• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

onlinemonitor/rocmonitor/TFiberHodProc.cxx (r4864/r3723)

Go to the documentation of this file.
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 //#include "roc/Board.h"
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    // dummy for tree streamer
00035 }
00036 
00037 
00038 
00039 //***********************************************************
00040 // this one is used in standard factory
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    // Booking histograms
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    // Booking histograms for single event display
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    // SL TODO: after next go4 release change uncomment usage of setup macro
00076    fParam = (TFiberHodParam *) MakeParameter(parname, "TFiberHodParam"/*, setupmacro.Data() */);
00077 
00078    // here we optionally override parameter values with setup macro, if existing:
00079    ExecuteScript(setupmacro.Data());
00080 
00081    // initialize and fill decoding table
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    // preserve some memory, should be enough for most applications
00098    fHitbank.reserve(100);
00099    fClusterbank.reserve(100);
00100 }
00101 
00102 TFiberHodProc::~TFiberHodProc()
00103 {
00104    //cout << "**** TFiberHodProc: Delete instance " << endl;
00105 }
00106 
00107 void TFiberHodProc::InitializeDecoding(Int_t altflag)
00108 {
00109    // Initialze decoding table : vector fDecoding,
00110    // array index is the readout channel [0..127]
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       // Calculate febch [0..63] for given fiber number [1..64]
00122       // lcn: linearconnectornumber, is the wire number on one of the
00123       // flat cables. [1..16]
00124       // each 16 fibers go to one connector.
00125       // fibersubnr[0..15] linear fiber counter in groups of 16
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       // new code to resolve cabling problem during cern-oct12
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          // and swap at the end
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    // first assign input event:
00195    // since input event object is never discarded within processor lifetime,
00196    // we just search for subevent by name once to speed up processing
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    // then assign output event
00209    // since output event object is never discarded within processor lifetime,
00210    // we just search for subevent by name once to speed up processing
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    //variables for finding maximum fiber and max cluster in each layer,
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    // loop over all messages for Fiberhodoscope to fill hitbank
00257    // apply cut on ADCrange and TIMErange
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;  // only interested in HIT messages
00263       if (msg.GetRocNumber() != fParam->RocID || msg.GetNxNumber() != fParam->NxID) continue; // only hodoscope hits
00264 
00265       // apply cuts on hit selection
00266       if (!fADC_cond->Test(msg.GetCorrectedNxADC())) continue;
00267 
00268       // extract message information
00269       hitbankentry_t newhit;
00270 
00271       newhit.FEBchannel = msg.GetNxChNum();   // 0..127
00272       newhit.fiber = fDecoding[msg.GetNxChNum()].fiber; // 1-64
00273       newhit.plane = fDecoding[msg.GetNxChNum()].plane; // 1,2
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       // store ADC, ADCraw, maxCh, for maximum hit per each hodoscope plane.
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       // Do cluster finding in all hits:
00300       // First sort hitbank according to ADC value
00301       // Then look for first not-yet-clustered ADC hit and start new cluster
00302       // Loop over rest of hitbank, and look for neighboring hits within +-fMaxClusterDist
00303       // add all hits within range to the cluster, and finally calculate mean position, ADCsum
00304       // store cluster in clusterbank, and restart with next not-yet-clustered hit
00305 
00306       sort(fHitbank.begin(), fHitbank.end(), adccompare());
00307 
00308       // Find first not-yet-clustered hit with highest ADC
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) {  //Found a hit, start new cluster
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;      // Mark hit in hitbank as already used
00332 
00333             // look for additional hits for cluster, starting at position of
00334             // first hit in hitbank(ADC sorted)
00335             for (unsigned inext=ifirst+1; inext<fHitbank.size(); inext++) {
00336                if (fHitbank[inext].status!=0) continue;                      // hit already clustered or marked as crosstalk
00337                if (fHitbank[inext].plane!=fHitbank[ifirst].plane) continue;  // hit in different hodoscope plane
00338                // spatial distance to large
00339                if (abs(fHitbank[inext].fiber-fHitbank[ifirst].fiber)>fParam->MaxClusterDist) continue;
00340                // time difference to large
00341                if (fabs(fHitbank[inext].time-fHitbank[ifirst].time)>fParam->MaxTimeDiff) continue;
00342 
00343                // hit qualified to join the cluster
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             // Calculate cluster position as weighted mean, TDC as mean (ADC is already summed)
00356             newcluster.meanposition /= newcluster.sumADC;  // divide by ADC sum to get weighted mean
00357             newcluster.meanfiber /= newcluster.sumADC;
00358             newcluster.meantime /= newcluster.NrHits;    // divide by NrHits to get mean
00359 #ifdef HODOSCOPE_FULLTIMESTAMP
00360             newcluster.meanfulltime /= newcluster.NrHits;    // divide by NrHits to get mean
00361 #endif
00362             // keep pointers to maximum adc cluster per plane updated
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    // Fill eventvise histograms
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    // TODO: for the moment only single hit is detected based on maximum ADC
00392    // later one could try to extract several positions
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    // Single Event Display:
00429    // Fill cumulative single event hit- and cluster histograms only if activated
00430    if (fParam->SingleEventMode) {
00431       fSingleEventSlice++;
00432       if (fSingleEventSlice>100) fSingleEventSlice=1;
00433 
00434       if (hSingleEventCluster2D!=0) {
00435          // Fill cumulative single hit histogram
00436          for (Int_t i=0; i<=129; i++)  // include under- and overflow bin
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       // Fill cumulative single cluster histograms
00444       for (unsigned icluster=1; icluster<=5; icluster++) { // up to 5 clusters are displayed
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 /*            for (unsigned ihit=0; ihit<fClusterbank[icluster-1].hitlist.size(); ihit++) {
00453                hSingleEventCluster2D[icluster-1]->SetBinContent(fSingleEventSlice,
00454                      fClusterbank[icluster-1].hitlist[ihit]->fiber+
00455                      64*(fClusterbank[icluster-1].plane-1),
00456                      fClusterbank[icluster-1].hitlist[ihit]->ADC);
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 

Generated on Tue Dec 10 2013 04:52:23 for ROCsoft by  doxygen 1.7.1