00001 #include "TFiberHodProc.h"
00002
00003 #include "Riostream.h"
00004
00005 #include "TH1.h"
00006 #include "TH2.h"
00007 #include "TROOT.h"
00008 #include "TSystem.h"
00009 #include "TPedestalExtractor.h"
00010
00011 #include "TGo4MbsEvent.h"
00012 #include "TGo4WinCond.h"
00013 #include "TGo4Log.h"
00014
00015 #include "roc/Message.h"
00016
00017 #include <algorithm>
00018
00019 #include "roc/Message.h"
00020
00021 #include "TRocEvent.h"
00022 #include "TFiberHodParam.h"
00023
00024
00025
00026 TFiberHodProc::TFiberHodProc() :
00027 TCBMBeamtimeProc(),
00028 fParam(0),
00029 fRocEvent(0),
00030 fHodEvent(0),
00031 fHitbank(),
00032 fClusterbank()
00033 {
00034
00035 }
00036
00037
00038
00039
00040
00041
00042 TFiberHodProc::TFiberHodProc(const char* name) :
00043 TCBMBeamtimeProc(name),
00044 fParam(0),
00045 fRocEvent(0),
00046 fHodEvent(0)
00047 {
00048 TGo4Log::Info("TFiberHodProc: Create instance %s", name);
00049
00050 TString path = GetName();
00051 path += "/";
00052 path += GetName();
00053
00054
00055 hNrHits = MakeTH1('I', path+"_NrHits","Hit number", 64,-0.5,63.5);
00056 hMaxCh = MakeTH1('I', path+"_MaxChannel","maxChannel", 128,-0.5,127.5);
00057 hMaxFiberall = MakeTH1('I', path+"_MaxFiberall","maxFiber", 128,0.5,128.5);
00058 hMaxFiberpl1 = MakeTH1('I', path+"_MaxFiber1","maxFiber_pl1", 64,0.5,64.5);
00059 hMaxFiberpl2 = MakeTH1('I', path+"_MaxFiber2","maxFiber_pl2", 64,0.5,64.5);
00060 hADC = MakeTH1('I', path+"_ADC","ADC value", 100, 0., 4000.);
00061 hMaxADC = MakeTH2('I', path+"_MaxADC","maxADC", 128,-0.5,127.5,100,0.,4000);
00062 hMaxADCraw = MakeTH2('I', path+"_MaxADCraw","maxADCraw", 128,-0.5,127.5,100,0.,4000);
00063 hMaxFiber2D = MakeTH2('I', path+"_Hits2D","Hits2D", 64,0.5,64.5,64,0.5,64.5);
00064 hNrClusters2D = MakeTH2('I', path+"_NrClusters2d","NrClusters2D",10,-0.5,9.5,10,-0.5,9.5);
00065 hNrClusters = MakeTH1('I', path+"_NrClusters","NrClusters", 10,-0.5,9.5);
00066 hPosition2D = MakeTH2('I', path+"_Position2D","Position2D", 64,-32*1.01,32*1.01, 64,-32*1.01,32*1.01);
00067 hMaxClusterTimediff = MakeTH1('I', path+"_MaxClusterTimediff", "MaxClusterTimediff", 100,-50,50);
00068
00069
00070 fADC_cond = MakeWinCond(path+"_ADCcut", 200., 9999., hADC->GetName());
00071
00072 TString parname = GetName(); parname += "Par";
00073 TString setupmacro = "set_"; setupmacro+=parname; setupmacro+=".C";
00074
00075
00076 fParam = (TFiberHodParam *) MakeParameter(parname, "TFiberHodParam");
00077
00078
00079 ExecuteScript(setupmacro.Data());
00080
00081
00082 InitializeDecoding();
00083
00084 fSingleEventSlice=0;
00085 hSingleEventHit2D = 0;
00086 for (Int_t icluster=1; icluster<=5; icluster++) hSingleEventCluster2D[icluster-1]=0;
00087
00088 if (fParam->SingleEventMode) {
00089 hSingleEventHit2D = MakeTH2('F', path+"_SingleEventHit2D","SingleEventHit2D",100,0.5,100.5,128,0.5,128.5);
00090 for (Int_t icluster=1; icluster<=5; icluster++)
00091 hSingleEventCluster2D[icluster-1] =
00092 MakeTH2('F',Form(path+"_SingleEventCluster2D%i",icluster),
00093 Form("SingleEventCluster_%i",icluster),
00094 100,0.5,100.5,128,0.5,128.5);
00095 }
00096
00097
00098 fHitbank.reserve(100);
00099 fClusterbank.reserve(100);
00100 }
00101
00102 TFiberHodProc::~TFiberHodProc()
00103 {
00104
00105 }
00106
00107 void TFiberHodProc::InitializeDecoding(Int_t altflag)
00108 {
00109
00110
00111 for (Int_t i=0; i<127; i++) {
00112 fDecoding[i].FEBchannel=i;
00113 fDecoding[i].fiber=-1;
00114 fDecoding[i].plane=-1;
00115 fDecoding[i].pixel=-1;
00116 fDecoding[i].lcn=-1;
00117 fDecoding[i].cable=-1;
00118 }
00119
00120 for (Int_t ifiber=1; ifiber<=64; ifiber++) {
00121
00122
00123
00124
00125
00126
00127 Int_t fibersubnr=(ifiber-1)%16;
00128
00129 Int_t lcn=15-fibersubnr*2;
00130 if (fibersubnr>=8) lcn=(fibersubnr-7)*2;
00131
00132 Int_t channel=-1;
00133 Int_t cable=(ifiber-1)/16+1;
00134 Int_t pixel= ((lcn-1)/2)*8 +((lcn-1)%2);
00135 if (cable==1) {
00136 channel=(lcn-1)*4+0;
00137 pixel=pixel+1;
00138 }
00139 if (cable==2) {
00140 channel=(lcn-1)*4+2;
00141 pixel=pixel+3;
00142 }
00143 if (cable==3) {
00144 channel=(lcn-1)*4+1;
00145 pixel=pixel+5;
00146 }
00147 if (cable==4) {
00148 channel=(lcn-1)*4+3;
00149 pixel=pixel+7;
00150 }
00151
00152
00153 int ifiber_bis = ifiber;
00154 if (fParam->WrongCabling) {
00155 if (ifiber <= 8 ) ifiber_bis = ifiber + 56; else
00156 if (ifiber <= 16 ) ifiber_bis = ifiber + 40; else
00157 if (ifiber <= 24 ) ifiber_bis = ifiber + 24; else
00158 if (ifiber <= 32 ) ifiber_bis = ifiber + 8; else
00159 if (ifiber <= 40 ) ifiber_bis = ifiber - 8; else
00160 if (ifiber <= 48 ) ifiber_bis = ifiber - 24; else
00161 if (ifiber <= 56 ) ifiber_bis = ifiber - 40; else
00162 if (ifiber <= 64 ) ifiber_bis = ifiber - 56;
00163
00164
00165 ifiber_bis = 65 - ifiber_bis;
00166 }
00167
00168 fDecoding[channel].fiber = ifiber_bis;
00169 fDecoding[channel].plane=1;
00170 fDecoding[channel].pixel=pixel;
00171 fDecoding[channel].lcn=lcn;
00172 fDecoding[channel].cable=cable;
00173 fDecoding[channel].position=(ifiber_bis-32.5)*1.01;
00174
00175 fDecoding[channel+64].fiber = ifiber_bis;
00176 fDecoding[channel+64].plane=2;
00177 fDecoding[channel+64].pixel=pixel;
00178 fDecoding[channel+64].lcn=lcn;
00179 fDecoding[channel+64].cable=cable+4;
00180 fDecoding[channel+64].position=(ifiber_bis-32.5)*1.01;
00181 }
00182
00183 TGo4Log::Info("Decoding table for Fiber hodoscope %s (rocid %i, NXid %i) initialized:",
00184 GetName(), fParam->RocID, fParam->NxID);
00185 for (Int_t i=0; i<127; i++) {
00186 TGo4Log::Debug("Channel %3i: FiberNr /plane: %2i /%1i, PMT PixelNr: %2i, position: %4.1f",
00187 fDecoding[i].FEBchannel, fDecoding[i].fiber, fDecoding[i].plane,
00188 fDecoding[i].pixel, fDecoding[i].position);
00189 }
00190 }
00191
00192 void TFiberHodProc::InitEvent(TGo4EventElement* outevnt)
00193 {
00194
00195
00196
00197 if(fRocEvent==0) {
00198 TCBMBeamtimeEvent* btevent=dynamic_cast<TCBMBeamtimeEvent*>(GetInputEvent());
00199 if(btevent)
00200 fRocEvent = dynamic_cast<TRocEvent*>(btevent->GetSubEvent("ROC"));
00201 else
00202 fRocEvent = dynamic_cast<TRocEvent*>(GetInputEvent());
00203
00204 if(fRocEvent==0) {
00205 GO4_STOP_ANALYSIS_MESSAGE("**** TFiberHodProc: Fatal error: no input event TRocEvent!!! STOP GO4");
00206 }
00207 }
00208
00209
00210
00211 if(fHodEvent==0) {
00212 TCBMBeamtimeEvent* btevent = dynamic_cast<TCBMBeamtimeEvent*>(outevnt);
00213 if(btevent)
00214 fHodEvent = dynamic_cast<TFiberHodEvent*>(btevent->GetSubEvent(GetName()));
00215 else
00216 fHodEvent = dynamic_cast<TFiberHodEvent*>(outevnt);
00217
00218 if(fHodEvent==0) {
00219 GO4_STOP_ANALYSIS_MESSAGE("**** TFiberHodProc: Fatal error: output event is not a TFiberHodEvent!!! STOP GO4");
00220 }
00221 }
00222
00223 }
00224
00225 void TFiberHodProc::FinalizeEvent()
00226 {
00227 if (fParam->RocID<0) return;
00228
00229 if ((fRocEvent==0) || (fHodEvent==0)) {
00230 TGo4Log::Error("TFiberHodProc: %s ERROR: no input/output event specified", GetName());
00231 return;
00232 }
00233
00234 TRocData* RocData = dynamic_cast<TRocData*>(fRocEvent->getEventElement(fParam->RocID));
00235 if(RocData==0) {
00236 TGo4Log::Error("TFiberHodProc: %s ERROR: can not find roc of id %d in input, please check configuration!!!", GetName(), fParam->RocID);
00237 return;
00238 }
00239
00240 fHitbank.clear();
00241 fClusterbank.clear();
00242
00243
00244 Double_t maxADC[2]={-1000,-1000};
00245 Double_t maxADCraw[2]={-1000,-1000};
00246 Int_t maxCh[2]={-1,-1};
00247 Int_t maxFiber[2]={-1,-1};
00248
00249 Int_t MaxCluster[2] = {-1, -1};
00250 Int_t NrClustersPerPlane[2] = { 0, 0 };
00251
00252 unsigned NrMsgs = RocData->fExtMessages.size();
00253
00254 hNrHits->Fill(NrMsgs);
00255
00256
00257
00258
00259 for (unsigned MessageNr=0; MessageNr<NrMsgs; MessageNr++) {
00260 TRocMessageExtended& msg = RocData->fExtMessages.at(MessageNr);
00261
00262 if (msg.GetMessageType() != roc::MSG_HIT) continue;
00263 if (msg.GetRocNumber() != fParam->RocID || msg.GetNxNumber() != fParam->NxID) continue;
00264
00265
00266 if (!fADC_cond->Test(msg.GetCorrectedNxADC())) continue;
00267
00268
00269 hitbankentry_t newhit;
00270
00271 newhit.FEBchannel = msg.GetNxChNum();
00272 newhit.fiber = fDecoding[msg.GetNxChNum()].fiber;
00273 newhit.plane = fDecoding[msg.GetNxChNum()].plane;
00274 newhit.ADC = msg.GetCorrectedNxADC();
00275 newhit.ADCraw = msg.GetNxADC();
00276 newhit.time = msg.GetTriggerDeltaT();
00277 #ifdef HODOSCOPE_FULLTIMESTAMP
00278 newhit.fulltime = msg.GetFullTime();
00279 #endif
00280 newhit.position = fDecoding[msg.GetNxChNum()].position;
00281 newhit.status = 0;
00282
00283 fHitbank.push_back(newhit);
00284
00285
00286 if (newhit.ADC > maxADC[newhit.plane-1]) {
00287 maxADC[newhit.plane-1] = newhit.ADC;
00288 maxADCraw[newhit.plane-1] = newhit.ADCraw;
00289 maxFiber[newhit.plane-1] = newhit.fiber;
00290 maxCh[newhit.plane-1] = newhit.FEBchannel;
00291 }
00292 }
00293
00294 if (fParam->Debug) PrintAllHits();
00295
00296
00297 if (fHitbank.size()!=0) {
00298
00299
00300
00301
00302
00303
00304
00305
00306 sort(fHitbank.begin(), fHitbank.end(), adccompare());
00307
00308
00309 unsigned ifirst;
00310 Bool_t done;
00311 do {
00312 done=kTRUE;
00313 for (ifirst=0; ifirst<fHitbank.size(); ifirst++) {
00314 if (fHitbank[ifirst].status==0) {
00315 done=kFALSE;
00316 break;
00317 }
00318 }
00319
00320 if (!done) {
00321 clusterbankentry_t newcluster;
00322 newcluster.NrHits=1;
00323 newcluster.plane = fHitbank[ifirst].plane;
00324 newcluster.meanposition = fHitbank[ifirst].ADC*fHitbank[ifirst].position;
00325 newcluster.meanfiber = fHitbank[ifirst].ADC*fHitbank[ifirst].fiber;
00326 newcluster.sumADC = fHitbank[ifirst].ADC;
00327 newcluster.meantime = fHitbank[ifirst].time;
00328 #ifdef HODOSCOPE_FULLTIMESTAMP
00329 newcluster.meanfulltime = fHitbank[ifirst].fulltime;
00330 #endif
00331 fHitbank[ifirst].status=1;
00332
00333
00334
00335 for (unsigned inext=ifirst+1; inext<fHitbank.size(); inext++) {
00336 if (fHitbank[inext].status!=0) continue;
00337 if (fHitbank[inext].plane!=fHitbank[ifirst].plane) continue;
00338
00339 if (abs(fHitbank[inext].fiber-fHitbank[ifirst].fiber)>fParam->MaxClusterDist) continue;
00340
00341 if (fabs(fHitbank[inext].time-fHitbank[ifirst].time)>fParam->MaxTimeDiff) continue;
00342
00343
00344 newcluster.NrHits++;
00345 fHitbank[inext].status=1;
00346 newcluster.sumADC += fHitbank[inext].ADC;
00347 newcluster.meantime += fHitbank[inext].time;
00348 #ifdef HODOSCOPE_FULLTIMESTAMP
00349 newcluster.meanfulltime += fHitbank[inext].fulltime;
00350 #endif
00351 newcluster.meanposition += fHitbank[inext].ADC*fHitbank[inext].position;
00352 newcluster.meanfiber += fHitbank[inext].ADC*fHitbank[inext].fiber;
00353 }
00354
00355
00356 newcluster.meanposition /= newcluster.sumADC;
00357 newcluster.meanfiber /= newcluster.sumADC;
00358 newcluster.meantime /= newcluster.NrHits;
00359 #ifdef HODOSCOPE_FULLTIMESTAMP
00360 newcluster.meanfulltime /= newcluster.NrHits;
00361 #endif
00362
00363 if (MaxCluster[newcluster.plane-1] == -1 ||
00364 fClusterbank[MaxCluster[newcluster.plane-1]].sumADC<newcluster.sumADC)
00365 MaxCluster[newcluster.plane-1] = fClusterbank.size();
00366
00367 fClusterbank.push_back(newcluster);
00368 NrClustersPerPlane[newcluster.plane-1]++;
00369 }
00370 } while (!done);
00371 }
00372
00373 if (fParam->Debug) PrintAllClusters();
00374
00375
00376 if (maxFiber[0]>0 && maxFiber[1]>0) {
00377 hMaxCh->Fill(maxCh[0]); hMaxCh->Fill(maxCh[1]);
00378 hMaxFiberall->Fill(maxFiber[0]); hMaxFiberall->Fill(maxFiber[1]+64);
00379 hMaxFiberpl1->Fill(maxFiber[0]);
00380 hMaxFiberpl2->Fill(maxFiber[1]);
00381 hADC->Fill(maxADC[0]); hADC->Fill(maxADC[1]);
00382 hMaxADC->Fill(maxCh[0],maxADC[0]); hMaxADC->Fill(maxCh[1],maxADC[1]);
00383 hMaxADCraw->Fill(maxCh[0],maxADCraw[0]); hMaxADCraw->Fill(maxCh[1],maxADCraw[1]);
00384 hMaxFiber2D->Fill(maxFiber[0],maxFiber[1]);
00385 }
00386
00387 hNrClusters->Fill(fClusterbank.size());
00388
00389 hNrClusters2D->Fill(NrClustersPerPlane[0], NrClustersPerPlane[1]);
00390
00391
00392
00393
00394 if (MaxCluster[0]>=0 && MaxCluster[1]>=0) {
00395
00396 hMaxClusterTimediff->Fill(fClusterbank[MaxCluster[0]].meantime-
00397 fClusterbank[MaxCluster[1]].meantime);
00398
00399 if (TMath::Abs(fClusterbank[MaxCluster[0]].meantime-
00400 fClusterbank[MaxCluster[1]].meantime) < fParam->MaxTimeDiff) {
00401
00402 TFiberHodEvent::hit_t hh;
00403
00404 hh.X = fClusterbank[MaxCluster[0]].meanposition;
00405 hh.Y = fClusterbank[MaxCluster[1]].meanposition;
00406
00407 hh.time = (fClusterbank[MaxCluster[0]].meantime +
00408 fClusterbank[MaxCluster[1]].meantime) / 2;
00409
00410 #ifdef HODOSCOPE_FULLTIMESTAMP
00411 hh.fulltime = (fClusterbank[MaxCluster[0]].meanfulltime +
00412 fClusterbank[MaxCluster[1]].meanfulltime) / 2;
00413 #endif
00414 hh.NumHits = fClusterbank[MaxCluster[0]].NrHits +
00415 fClusterbank[MaxCluster[1]].NrHits;
00416
00417 hh.ADC = fClusterbank[MaxCluster[0]].sumADC +
00418 fClusterbank[MaxCluster[1]].sumADC;
00419
00420
00421
00422 hPosition2D->Fill(hh.X, hh.Y);
00423
00424 fHodEvent->fHits.push_back(hh);
00425 }
00426 }
00427
00428
00429
00430 if (fParam->SingleEventMode) {
00431 fSingleEventSlice++;
00432 if (fSingleEventSlice>100) fSingleEventSlice=1;
00433
00434 if (hSingleEventCluster2D!=0) {
00435
00436 for (Int_t i=0; i<=129; i++)
00437 hSingleEventHit2D->SetBinContent(fSingleEventSlice,i,0);
00438 for (unsigned ihit=0; ihit<fHitbank.size(); ihit++)
00439 hSingleEventHit2D->SetBinContent(fSingleEventSlice,
00440 fHitbank[ihit].fiber+64*(fHitbank[ihit].plane-1),fHitbank[ihit].ADC);
00441 }
00442
00443
00444 for (unsigned icluster=1; icluster<=5; icluster++) {
00445
00446 if (hSingleEventCluster2D[icluster-1]==0) continue;
00447
00448 for (Int_t i=0; i<=129; i++)
00449 hSingleEventCluster2D[icluster-1]->SetBinContent(fSingleEventSlice,i,0);
00450
00451 if ((icluster-1) < fClusterbank.size()) {
00452
00453
00454
00455
00456
00457
00458
00459 hSingleEventCluster2D[icluster-1]->SetBinContent(fSingleEventSlice,0,
00460 fClusterbank[icluster-1].meanfiber+
00461 64*(fClusterbank[icluster-1].plane-1));
00462 }
00463 }
00464 }
00465 }
00466
00467
00468 void TFiberHodProc::PrintAllHits()
00469 {
00470 printf("\nDump of Hitbank with %d hits \n", (int) fHitbank.size());
00471 for (unsigned ihit=0; ihit<fHitbank.size(); ihit++)
00472 printf("hit %u: fiber %d, plane %d, ADC %f, position:%f, Status %d \n",ihit+1,
00473 fHitbank[ihit].fiber, fHitbank[ihit].plane, fHitbank[ihit].ADC, fHitbank[ihit].position, fHitbank[ihit].status);
00474 }
00475
00476 void TFiberHodProc::PrintAllClusters()
00477 {
00478 printf("\nDump of clusterbank with %d clusters\n", (int) fClusterbank.size());
00479 for (unsigned icluster=0; icluster<fClusterbank.size(); icluster++) {
00480 printf("Cluster %d: ADCsum:%6.1f, TDCmean %6.1f, Position %6.1f, NrHits: %d \n",
00481 icluster,fClusterbank[icluster].sumADC, fClusterbank[icluster].meantime, fClusterbank[icluster].meanposition, fClusterbank[icluster].NrHits);
00482 }
00483 }
00484