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

beamtime/tof-tdctest/go4/MBSUNPACK/TMbsCrateProc.cxx (r4864/r4679)

Go to the documentation of this file.
00001 #include "TMbsCrateProc.h"
00002 
00003 #include <stdlib.h>
00004 
00005 #include "TTimeStamp.h"
00006 #include "TSystem.h"
00007 #include "TROOT.h"
00008 #include "TGo4Log.h"
00009 
00010 #include "TTriglogEvent.h"
00011 
00012 // still need this for subevent types:
00013 #include "roc/Message.h"
00014 #include "roc/Board.h"
00015 
00016 #if defined(VERSION_VFTX) || defined(VERSION_VFTX_28)  // For Heidelberg tests!
00017    #include "../mbs/cbmvme0.h"
00018 #else
00019    #include "../mbs/cbmvme.h"
00020 #endif
00021 
00022 // Needed for FPGA_TDC hits sorting
00023 #include <algorithm>
00024 
00025 const uint32_t vme_setup[MAX__N_MOD*6] = VME__MODULES;
00026 
00027 uint64_t vme_tags[MAX__N_MOD];
00028 
00029 #define CAEN1290_DEBUG 0
00030 #define L1182_DEBUG 0
00031 
00032 TMbsCrateProc::TMbsCrateProc() :
00033    TCBMBeamtimeProc(),
00034    fOutputEvent(0)
00035 {
00036 }
00037 
00038 TMbsCrateProc::TMbsCrateProc(const char* name) :
00039    TCBMBeamtimeProc(name),
00040    fOutputEvent(0)
00041 {
00042    TGo4Log::Info("TMbsCrateProc: Create instance %s", name);
00043 
00044    TString obname, obtitle;   
00045 
00046    fPar = (TMbsCrateParam*) MakeParameter("MbsCratePar", "TMbsCrateParam");
00047    
00048    // v1290 histograms
00049 
00050    iCaenEnabled = 0;
00051    for (int n=0;n<MAX_1290;n++)
00052       if( 1 == fPar->uCaenTdcHistosEnabled[n] )
00053       {
00054          if( kTRUE == fPar->bCaenDebug || kTRUE == fPar->bCaenTriggerTime )
00055             fTDC[n].MakeHistos(this, fPar->bCaenDebug, fPar->bCaenTriggerTime, Form("TDC%d",n));
00056          else {
00057             fTDC[n].MakeHistos(this, Form("TDC%d",n));
00058             if( CAEN1290_DEBUG )
00059                fTDC[n].MakeDebugHistos(this, Form("TDC%d",n));
00060          }
00061          iCaenEnabled++;
00062       }
00063 
00064    if( 1 < iCaenEnabled && 1 == fPar->uCaenCoincidenceMap)
00065    {
00066       /*
00067       fAllTDC_chanMapL = MakeTH2('I', "CAEN/chanMap_CaenTdcL", "Channel (L) during same event?",
00068             MAX_1290*T1290Data::NumChan, -0.5, MAX_1290*T1290Data::NumChan-0.5,
00069             MAX_1290*T1290Data::NumChan, -0.5, MAX_1290*T1290Data::NumChan-0.5,
00070            "Channel 1 []", "Channel 2[]", "Events []");
00071       */
00072       iMapIndex = 0;
00073       for( Int_t iModule1 = 0; iModule1 < MAX_1290; iModule1 ++)
00074          for( Int_t iModule2 = iModule1; iModule2 < MAX_1290; iModule2 ++)
00075          {
00076             if( MAX_1290*(MAX_1290+1)/2 < iMapIndex )
00077             {
00078                TGo4Log::Info("****Mbs unpacker: Error creating caen mapping histos: index out of boundary : %d / %d (tdc #%d VS tdc #%d)",
00079                      iMapIndex, MAX_1290*(MAX_1290+1)/2, iModule1, iModule2);
00080                break;
00081             }
00082             fTDC_chanMapL[ iMapIndex ] =
00083                      MakeTH2('I', Form("CAEN/Mapping/Mapp%d_%dCaen", iModule1, iModule2 ),
00084                                   Form("Channel during same event?, Tdc %d VS Tdc %d", iModule1, iModule2),
00085                                   T1290Data::NumChan, -0.5, T1290Data::NumChan - 0.5,
00086                                   T1290Data::NumChan, -0.5, T1290Data::NumChan - 0.5,
00087                                   Form("Channel Tdc #%d []", iModule1),
00088                                   Form("Channel Tdc #%d []", iModule2),"Events []");
00089             iMapIndex++;
00090          }
00091    }
00092 
00093    for (int n=0;n<MAX_965;n++)
00094       if( 1 == fPar->uCaenQdcHistosEnabled[n] )
00095          for (int ch=0;ch<MQDC_t::NumChan;ch++) {
00096             obname.Form("QDC%d/Charge%d_%d",n,n,ch);
00097             obtitle.Form("Charge of QDC %d channel %d",n,ch);
00098             fQdc_Charge[n][ch] = MakeTH1('I',obname.Data(),obtitle.Data(),4096,1,4096,"charge");
00099          }
00100 
00101    for (int n=0;n<MAX_FPGA_TDC;n++)
00102       if( 1 == fPar->uVftxHistosEnabled[n] )
00103          for (int ch=0;ch<FPGA_TDC_NBCHAN;ch++) {
00104             obname.Form("FPGA_TDC%d/FPGA_TDC%d_Ch%d", n, n, ch);
00105             obtitle.Form("Fine counter of TDC%d channel %d", n, ch);
00106             fFPGA_Ch[n][ch] = MakeTH1('I', obname.Data(), obtitle.Data(), 0x800, 0, 0x800, "cnt");
00107 
00108             iLastFpgaTdcCoarse[n][ch] = -1;
00109          }
00110 
00111    // 1182 histograms
00112    for (int n=0;n<MAX_1182;n++)
00113       if( 1 == fPar->uLecroyQdcHistosEnabled[n] )
00114          for (int ch=0;ch<NUM_1182_CH;ch++) {
00115             obname.Form("118%d/118%d_channel%d", n+2, n+2, ch);
00116             obtitle.Form("118%d Channel %d", n+2, ch);
00117             f1182h[n][ch] = MakeTH1('I', obname.Data(), obtitle.Data(), 1024, 0, 4096.);
00118          }
00119 
00120 
00121    // QFW histograms
00122    if( 1 == fPar->uQFWHistosEnabled )
00123    {
00124       fQFWcnt = MakeTH1('I', "QFW/QFWcnt", "Counts in QFW channels", 4, 0, 4, "cnt");
00125       fQFWerr = MakeTH1('I', "QFW/QFWerr", "Error counts in QFW channels", 4, 0, 4, "err");
00126 
00127       fQFWInfo = new TLatex(0.5,0.5,"-- demo text --");
00128       fQFWInfo->SetName("QFWInfo");
00129       fQFWInfo->SetNDC();
00130       AddObject(fQFWInfo);
00131    }
00132 
00133    for (int n=0;n<MAX__N_MOD;n++) {
00134       if (n != (int)vme_setup[n*6]) {
00135          TGo4Log::Error("Wrong setup in cbmvme.h file in row %d",n);
00136          exit(1);
00137       }
00138 
00139       vme_tags[n] = (((uint64_t) vme_setup[n*6+5]) << 32) | vme_setup[n*6+4];
00140 
00141       if ((n>0) && (vme_tags[n]==0)) {
00142          TGo4Log::Error("Wrong setup in cbmvme.h - zero tag in row %d", n);
00143          exit(1);
00144       }
00145    }
00146 
00147    // Initial value of event number
00148    iLastEventNumber = -1;
00149 
00150    TGo4Log::Info("TMbsCrateProc - Histograms created");
00151 }
00152 
00153 TMbsCrateProc::~TMbsCrateProc()
00154 {
00155    TGo4Log::Info("Last Event: %d", iLastEventNumber);
00156    cout << "**** TMbsCrateProc: Delete instance " << endl;
00157 }
00158 
00159 void TMbsCrateProc::InitEvent(TGo4EventElement* outevnt)
00160 {
00161    TCBMBeamtimeEvent* btevent=dynamic_cast<TCBMBeamtimeEvent*>(outevnt);
00162    if(btevent)
00163    {
00164       // since output event object is never discarded within processor lifetime,
00165       // we just search for subevent by name once to speed up processing
00166       if(fOutputEvent==0)
00167          fOutputEvent=dynamic_cast<TMbsCrateEvent*>(btevent->GetSubEvent("MBSCRATE"));
00168    }
00169    else
00170    {
00171 
00172       fOutputEvent= dynamic_cast<TMbsCrateEvent*>(outevnt);
00173    }
00174    if(fOutputEvent==0) {
00175       GO4_STOP_ANALYSIS_MESSAGE("**** TMbsCrateProc: Fatal error: output event is not a TMbsCrateEvent!!! STOP GO4");
00176    }
00177 }
00178 
00179 void TMbsCrateProc::ProcessSubevent(TGo4MbsSubEvent* subevt)
00180 {
00181 // uncomment this to test with previous beamtime lmds:
00182    if (subevt->GetProcid() == roc::proc_Triglog) {
00183       if( -1 == iLastEventNumber )
00184       {
00185          iLastEventNumber = GetEventNumber();
00186          TGo4Log::Info("First Event: %d", iLastEventNumber);
00187       }
00188          else iLastEventNumber =  GetEventNumber();
00189 
00190       UInt_t lwords = subevt->GetIntLen();
00191       Int_t  indx = 0;
00192       if(  4+ NUM_SCALERS*N_SCALERS_CH < lwords)
00193       {
00194          indx = 4+ NUM_SCALERS*N_SCALERS_CH;
00195          fOutputEvent->fTriglogInputPattern = subevt->Data(indx++);
00196 
00197          if( indx < subevt->GetIntLen() )
00198             fOutputEvent->fTriglogReferenceClock = subevt->Data(indx++) ;
00199       }
00200    }
00201    if (subevt->GetProcid() == roc::proc_COSY_Nov11) {
00202 // comment this to test with previous beamtime lmds:
00203 //   if (subevt->GetProcid() == roc::proc_GSI_Aug12) {
00204       // MBS data from GSI beamtime, August 11
00205       // subevt->GetControl() == 9 from Master MBS, subevt->GetControl() == 10 from Slave MBS
00206 
00207       Int_t *pdata = subevt->GetDataField();
00208       UInt_t lwords = subevt->GetIntLen();
00209 
00210       // printf("CERN subevent Control %u TOTALLEN = %u\n", subevt->GetControl(), lwords);
00211 
00212       Int_t* tagpos[MAX__N_MOD];
00213       Int_t taglen[MAX__N_MOD];
00214 
00215       for (int n=0;n<MAX__N_MOD;n++) {
00216          tagpos[n] = 0;
00217          taglen[n] = 0;
00218       }
00219 
00220       int lasttag = -1;
00221 
00222       for (UInt_t cur = 0; cur < lwords; ++cur) {
00223          uint64_t* ptag = (uint64_t*) pdata;
00224          bool find = false;
00225 
00226          for (int ntag=1;ntag<MAX__N_MOD;ntag++)
00227             if ((*ptag == vme_tags[ntag]) && (vme_tags[ntag]!=0)) {
00228                if (lasttag>=0) {
00229                   taglen[lasttag] = pdata - tagpos[lasttag];
00230                   lasttag = -1;
00231                }
00232 
00233                if (tagpos[ntag]==0) {
00234                   pdata+=2; cur+=1;
00235                   tagpos[ntag] = pdata;
00236                   lasttag = ntag;
00237                } else {
00238                   TGo4Log::Error("FORMAT ERROR found tag %lld twice\n", vme_tags[ntag]);
00239                   pdata+=2; cur+=1;
00240                }
00241 
00242                find = true;
00243                break;
00244             }
00245 
00246          if (!find) pdata++;
00247       }
00248 
00249       if (lasttag>=0)
00250          taglen[lasttag] = pdata - tagpos[lasttag];
00251 
00252       // for (int ntag=0;ntag<numtags;ntag++)
00253       //    if (tagpos[ntag])
00254       //       printf("TAG %d POS %lu LEN %d\n", ntag, tagpos[ntag] - p0, taglen[ntag]);
00255 
00256 
00257       // if (GetTriggerNumber()==8) {
00258       //   fOutputEvent->SetValid(kFALSE);
00259       //   return;
00260       // }
00261 
00262 
00263       // actually process data in subroutines:
00264 
00265       if (tagpos[VME__ID_1182] && taglen[VME__ID_1182])
00266          Process1182(0, tagpos[VME__ID_1182], taglen[VME__ID_1182]);  // 1182
00267       if (tagpos[VME__ID_1183] && taglen[VME__ID_1183])
00268          Process1182(1, tagpos[VME__ID_1183], taglen[VME__ID_1183]);  // 1183
00269 
00270       for (int tdc=VME__ID_TDC1;tdc<=VME__ID_TDC8;tdc++)
00271          if (tagpos[tdc] && taglen[tdc])
00272             Process1290(tdc-VME__ID_TDC1, tagpos[tdc], taglen[tdc]);  // all TDCs
00273 
00274       for (int qdc=VME__ID_QDC1;qdc<=VME__ID_QDC2;qdc++)
00275          if (tagpos[qdc] && taglen[qdc])
00276             Process965(qdc-VME__ID_QDC1, tagpos[qdc], taglen[qdc]);  // all QDCs
00277 
00278       for (int fpga=VME__ID_FPGA1;fpga<=VME__ID_FPGA11;fpga++)
00279          if (tagpos[fpga] && taglen[fpga])
00280             ProcessVFTX(fpga-VME__ID_FPGA1, (uint32_t*) tagpos[fpga], taglen[fpga]);  // all FPGAs
00281 
00282       if (tagpos[VME__ID_QFW] && taglen[VME__ID_QFW])
00283          ProcessQFW((uint32_t*)tagpos[VME__ID_QFW], taglen[VME__ID_QFW]);  // QFW
00284 
00285       if (tagpos[VME__ID_SCOM] && taglen[VME__ID_SCOM])
00286          ProcessScalOrMu((uint32_t*)tagpos[VME__ID_SCOM], taglen[VME__ID_SCOM]);  // Scaler Or Multiplicity
00287 
00288       if( 1 < iCaenEnabled && 1 == fPar->uCaenCoincidenceMap)
00289          for (Int_t iCaentdc1 = 0; iCaentdc1 < MAX_1290; iCaentdc1++)
00290             if( 1 == fPar->uCaenTdcHistosEnabled[iCaentdc1] )
00291                for (Int_t iChannel1 = 0; iChannel1 < T1290Data::NumChan; iChannel1++)
00292                {
00293                   // Go back to index for VFTX internal map
00294                   iMapIndex = MAX_1290*(MAX_1290+1)/2
00295                            - (MAX_1290-iCaentdc1)*((MAX_1290-iCaentdc1)+1)/2;
00296 
00297                   if( MAX_1290*(MAX_1290+1)/2 < iMapIndex )
00298                   {
00299                      TGo4Log::Info("****Vftx monitor: Error filling mapping histos: index out of boundary : %d / %d (tdc #%d VS tdc #%d)",
00300                            iMapIndex, MAX_1290*(MAX_1290+1)/2, iCaentdc1, iCaentdc1);
00301                      return;
00302                   } // if( MAX_1290*(MAX_1290+1)/2 < iMapIndex )
00303 
00304                   //if( 0 < fOutputEvent->fMtdc[iCaentdc1].hit_lead[iChannel1] &&
00305                   //    0 < fOutputEvent->fMtdc[iCaentdc1].hit_trail[iChannel1] )
00306                   if( 0 < fOutputEvent->fMtdc[iCaentdc1].hit_lead[iChannel1] )
00307                   {
00308                      for (Int_t iChannel2 = iChannel1+1; iChannel2 < T1290Data::NumChan; iChannel2++)
00309                         //if( 0 < fOutputEvent->fMtdc[iCaentdc1].hit_lead[iChannel2] &&
00310                         //    0 < fOutputEvent->fMtdc[iCaentdc1].hit_trail[iChannel2])
00311                         if( 0 < fOutputEvent->fMtdc[iCaentdc1].hit_lead[iChannel2] )
00312                            /*
00313                            fAllTDC_chanMapL->Fill( iCaentdc1*T1290Data::NumChan + iChannel1,
00314                                                   iCaentdc1*T1290Data::NumChan + iChannel2);
00315                                                   */
00316                            fTDC_chanMapL[iMapIndex] ->Fill( iChannel1, iChannel2);
00317 
00318                      for (Int_t iCaentdc2 = iCaentdc1+1; iCaentdc2 < MAX_1290; iCaentdc2++)
00319                      {
00320                         // Find index for corresponding VFTX against VFTX map
00321                         iMapIndex = MAX_1290*(MAX_1290+1)/2
00322                                  - (MAX_1290-iCaentdc1)*((MAX_FPGA_TDC-iCaentdc1)+1)/2
00323                                  + (iCaentdc2 - iCaentdc1);
00324                         if( MAX_1290*(MAX_1290+1)/2 < iMapIndex )
00325                         {
00326                            TGo4Log::Info("****Vftx monitor: Error filling mapping histos: index out of boundary : %d / %d (tdc #%d VS tdc #%d)",
00327                                  iMapIndex, MAX_1290*(MAX_1290+1)/2, iCaentdc1, iCaentdc2);
00328                            return;
00329                         } // if( MAX_1290*(MAX_1290+1)/2 < iMapIndex )
00330 
00331                         if( 1 == fPar->uCaenTdcHistosEnabled[iCaentdc2] )
00332                            for (Int_t iChannel2 = 0; iChannel2 < T1290Data::NumChan; iChannel2++)
00333                               //if( 0 < fOutputEvent->fMtdc[iCaentdc2].hit_lead[iChannel2] &&
00334                               //    0 < fOutputEvent->fMtdc[iCaentdc2].hit_trail[iChannel2] )
00335                               if( 0 < fOutputEvent->fMtdc[iCaentdc2].hit_lead[iChannel2]  )
00336                               /*
00337                                  fAllTDC_chanMapL->Fill( iCaentdc1*T1290Data::NumChan + iChannel1,
00338                                                         iCaentdc2*T1290Data::NumChan + iChannel2);
00339                               */
00340                                  fTDC_chanMapL[iMapIndex] ->Fill( iChannel1, iChannel2);
00341                      } // for (Int_t iCaentdc2 = iCaentdc1+1; iCaentdc2 < MAX_1290; iCaentdc2++)
00342                   } // if( 0 < fOutputEvent->fMtdc[iCaentdc1].hit_lead[iChannel1] && same for trail )
00343                } // for (Int_t iChannel1 = 0; iChannel1 < T1290Data::NumChan; iChannel1++)
00344 
00345       fOutputEvent->SetValid(kTRUE);
00346    }
00347 }
00348 
00349 
00350 
00351 
00352 void TMbsCrateProc::Process1182(int num, int* pdata, int len)
00353 {
00354    if (len < 2 + NUM_1182_CH ) {
00355       cout <<"TBeamMonitorProc:Process1182 data length"<< len << "not sufficient!" <<endl;
00356       return;
00357    }
00358 
00359    if (num>=MAX_1182) {
00360       cout << "Wrong ID=" << num << " of 1182 module" << endl;
00361       return;
00362    }
00363 
00364    // skip event header:
00365    int header = *pdata++;
00366    if (L1182_DEBUG)  printf("1182 header:0x%0x \n",header);
00367 
00368    // skip status
00369    int status = *pdata++;
00370    if (L1182_DEBUG)
00371       printf("1182 status:0x%0x :  \n"
00372             "        conversion complete    (bit0): 0x%x\n"
00373             "        conversion in progress (bit1): 0x%x\n"
00374             "        front(1)/rear(0) panel (bit2): 0x%x\n"
00375             "        Event buffer not full  (bit3): 0x%x\n"
00376             "        Event count       (bits 4..7): 0x%x\n"
00377             "        should be 0            (bit8): 0x%x\n"
00378             "        should be 0            (bit9): 0x%x\n",
00379             status, status & 1, (status >> 1) & 1 , (status >> 2) & 1, (status >> 3) & 1,
00380             (status >> 4) & 0xf,  (status >> 8) & 1, (status >> 9) & 1);
00381 
00382    for(int ch=0;ch<NUM_1182_CH;++ch) {
00383       int val = *pdata++;
00384       
00385       if( 1 == fPar->uLecroyQdcHistosEnabled[num] )
00386          f1182h[num][ch]->Fill(val);
00387 
00388       fOutputEvent->fData1182[num][ch] = val; // output event to root tree
00389    }
00390 
00391    fOutputEvent->SetValid(kTRUE);
00392 }
00393 
00394 void TMbsCrateProc::Process1290(int num, int* pdata, unsigned int len)
00395 {
00396    if (num >= MAX_1290) {
00397       cout << "Wrong 1290 index " << num << endl;
00398       return;
00399    }
00400 
00401    int expected_geo = 0;
00402 
00403    if (num<0) {
00404       // if number is not specified, try to identify it base on GEO value
00405       expected_geo = T1290Data::FindGeo(pdata, len);
00406       if (expected_geo<=0) {
00407          printf("ERROR: Did not found GEO in the data\n");
00408          return;
00409       }
00410 
00411       switch (expected_geo) {
00412          case 5: num = 8; break;
00413          case 6: num = 9; break;
00414          case 7: num = 10; break;
00415          case 8: num = 11; break;
00416          case 9: num = 12; break;
00417          case 10: num = 13; break;
00418          case 11: num = 14; break;
00419          default:
00420             printf("Unsupported GEO code %d\n", expected_geo);
00421             return;
00422       }
00423 
00424       // printf("Found GEO code %d defined num %d\n", expected_geo, num);
00425 
00426    } else {
00427       switch(num) {
00428          case 0: expected_geo = 8; break;
00429          case 1: expected_geo = 9; break;
00430          case 2: expected_geo = 10; break;
00431          case 3: expected_geo = 11; break;
00432          case 4: expected_geo = 12; break;
00433          case 5: expected_geo = 13; break;
00434          case 6: expected_geo = 14; break;
00435          case 7: expected_geo = 15; break;
00436        }
00437    }
00438    // printf("Process1290 num = %d expected GEO = %d len = %u\n", num, expected_geo, len);
00439 
00440    fOutputEvent->fMtdc[num].Unpack(pdata, len, expected_geo);
00441 
00442    if( 1 == fPar->uCaenTdcHistosEnabled[num] )
00443    {
00444       if( kTRUE == fPar->bCaenDebug || kTRUE == fPar->bCaenTriggerTime )
00445          fTDC[num].FillHistos(fOutputEvent->fMtdc[num], fPar->bCaenDebug, fPar->bCaenTriggerTime);
00446       else
00447       {
00448          fTDC[num].FillHistos(fOutputEvent->fMtdc[num]);
00449          if( CAEN1290_DEBUG )
00450             fTDC[num].FillDebugHistos(fOutputEvent->fMtdc[num]);
00451       }
00452    }
00453 
00454    fOutputEvent->SetValid(kTRUE);
00455 }
00456 
00457 void TMbsCrateProc::Process965(int num, int* pdata, unsigned int len)
00458 {
00459         int geo, crate, count;
00460         Int_t timeOffset;
00461         int data;
00462         
00463         if (num >= MAX_965) {
00464                 cout << "Wrong 965 index " << num << endl;
00465                 return;
00466         }
00467         geo = 0;
00468         timeOffset = 0;
00469         data = *pdata++;
00470         len--;
00471         count = 0;
00472         if (num<0) {
00473                 // if number is not specified, try to identify it base on GEO value
00474                 geo = MQDC_t::FindGeo(pdata, &count, &crate);
00475                 if (geo<=0) {
00476                         printf("ERROR: Did not found GEO in the data\n");
00477                         return;
00478                 }
00479                 switch (geo) {
00480                         case 0: num = 0; break;
00481                         case 1: num = 1; break;
00482                         case 2: num = 2; break;
00483                         default:
00484                                 printf("Unsupported GEO code %d\n", geo);
00485                                 return;
00486                 }
00487         }
00488         else
00489         {
00490                 if(((data>>24) & 0x7) == 0x2)
00491                 {
00492                         count = (data >> 8) & 0x3f;
00493                 }
00494                 switch(num) {
00495                         case 0: geo = 0; break;
00496                         case 1: geo = 1; break;
00497                         case 2: geo = 2; break;
00498                 }
00499         }
00500         fOutputEvent->fMqdc[num].Unpack(pdata, count, geo);
00501         
00502    if( 1 == fPar->uCaenQdcHistosEnabled[num] )
00503       for (int ch=0; ch<MQDC_t::NumChan; ch++) {
00504          if(fOutputEvent->fMqdc[num].charge[ch]>0)
00505             fQdc_Charge[num][ch]->Fill(fOutputEvent->fMqdc[num].charge[ch]);
00506        }
00507         
00508         fOutputEvent->SetValid(kTRUE);
00509 }
00510 
00511 void TMbsCrateProc::ProcessVFTX(int num, uint32_t* pdata, unsigned int len)
00512 {
00513    if ((num<0) || (num>=MAX_FPGA_TDC)) 
00514    {
00515       TGo4Log::Error("Error VFTX number %d out of bound (max %d) ", num, MAX_FPGA_TDC);
00516       return;
00517    }
00518 
00519    for (int ch=0;ch<FPGA_TDC_NBCHAN;ch++) {
00520       iLastFpgaTdcCoarse[num][ch] = -1;
00521    }
00522 
00523    uint32_t l_dat = *pdata++; // module header
00524    if ( (l_dat & TDC_EVT_HEADER_KEY_MASK)>>TDC_EVT_HEADER_KEY_SHIFT != TDC_EVT_HEADER_KEYWORD ) 
00525    {
00526       TGo4Log::Warn("this is not a vftx %d header, jumping this sub-event...", num);
00527       //return;
00528    }
00529    FPGA_TDC_header header;
00530    uint32_t l_nr_cha   = (l_dat & TDC_EVT_HEADER_NB_MASK);
00531    header.nr_data = l_nr_cha;
00532    header.mod_nr = ((l_dat & TDC_EVT_HEADER_MOD_MASK) >> TDC_EVT_HEADER_MOD_SHIFT); 
00533    if( header.mod_nr != num)
00534       TGo4Log::Warn("Wrong VFTX index in header of vftx %d: %d", num, header.mod_nr);
00535 
00536    if (l_nr_cha+2 != len && l_nr_cha+2 + 256 != len)
00537    {
00538      TGo4Log::Warn("wrong length in vftx %d header, jumping this sub-event... %d vs %d", num, l_nr_cha+2, len);
00539      // Return commented: MBS vftxlib.c for gsi aug 12 not compatible with too many data in event: 
00540      // only 8 bit where used to code event size => effective limitation to 256 hits then loop
00541       //return;
00542    }
00543    
00544    l_dat = *pdata++;  // vulom tdc fifo header
00545    if (l_dat & TDC_FIFO_MESSAGE_TYPE) 
00546    {
00547       header.fpga_fifo_tt = (l_dat & TDC_FIFO_HEADER_TRIG_TYPE) >> TDC_FIFO_HEADER_TRIG_TYPE_SHIFT;
00548       header.fpga_fifo_ct = (l_dat & TDC_FIFO_HEADER_TRIG_TIME) >> TDC_FIFO_HEADER_TRIG_TIME_SHIFT;
00549       header.fpga_fifo_nd = (l_dat & TDC_FIFO_HEADER_DATA_CNT);
00550    } // if (l_dat & TDC_FIFO_MESSAGE_TYPE) 
00551    else 
00552    {
00553       TGo4Log::Warn("vftx %d fifo header missing... ", num);
00554    }
00555    
00556       
00557    // cout << "mod: " << num << " ct: " << header.fpga_fifo_ct << endl;
00558    fOutputEvent->fFPGAHEAD[num].push_back(header);
00559    // cout << "TDC" << num << " , data items: " << header.nr_data << endl;
00560    // cout << "trigger ct: " << header.fpga_fifo_ct << "data nb: " << header.fpga_fifo_nd << endl;
00561    while (l_nr_cha-- > 0) 
00562    {
00563       uint32_t l_da0 = *pdata++;
00564 
00565       FPGA_TDC_hit hit;
00566       if ((l_da0 & TDC_FIFO_MESSAGE_TYPE) == TDC_FIFO_MESSAGE_TYPE) 
00567       {
00568          TGo4Log::Warn("wrong data item in vftx %d: type %d (message %08x, header %08x), jumping this sub-event...", 
00569                        num, (l_da0 & TDC_FIFO_MESSAGE_TYPE)>>TDC_FIFO_MESSAGE_TYPE_SHIFT, l_da0, l_dat);
00570          TGo4Log::Warn("Message: tt %01u ct %5u nd %3u", 
00571                       (l_da0 & TDC_FIFO_HEADER_TRIG_TYPE) >> TDC_FIFO_HEADER_TRIG_TYPE_SHIFT,
00572                       (l_da0 & TDC_FIFO_HEADER_TRIG_TIME) >> TDC_FIFO_HEADER_TRIG_TIME_SHIFT,
00573                       (l_da0 & TDC_FIFO_HEADER_DATA_CNT) );
00574          TGo4Log::Warn("Header : tt %01u ct %5u nd %3u", 
00575                       (l_dat & TDC_FIFO_HEADER_TRIG_TYPE) >> TDC_FIFO_HEADER_TRIG_TYPE_SHIFT,
00576                       (l_dat & TDC_FIFO_HEADER_TRIG_TIME) >> TDC_FIFO_HEADER_TRIG_TIME_SHIFT,
00577                       (l_dat & TDC_FIFO_HEADER_DATA_CNT) );
00578          return;
00579       }
00580       hit.ch_ix        = (l_da0 & TDC_FIFO_DATA_CHAN) >> TDC_FIFO_DATA_CHAN_SHIFT; //4-5 bit
00581       if (hit.ch_ix > FPGA_TDC_NBCHAN - 1)
00582          TGo4Log::Warn("channel number larger then %d found in vftx %d", FPGA_TDC_NBCHAN -1, num);
00583          
00584       hit.future_bit   = (l_da0 & TDC_FIFO_FUTURE_BIT) >> TDC_FIFO_FUTURE_BIT_SHIFT;  //  1 bit
00585       hit.coarse_ct    = (l_da0 & TDC_FIFO_COARSE_CT) >> TDC_FIFO_COARSE_CT_SHIFT;   // 15 bit
00586       hit.ch_tim       = (l_da0 & TDC_FIFO_FINE_CT);        // 10 bit, 11th bit empty
00587 
00588       if( 1 == fPar->uDebug )
00589       {
00590          if( (Int_t)hit.coarse_ct - iLastFpgaTdcCoarse[num][hit.ch_ix] < 6 &&
00591                -6 < (Int_t)hit.coarse_ct - iLastFpgaTdcCoarse[num][hit.ch_ix] &&
00592                -1 < iLastFpgaTdcCoarse[num][hit.ch_ix] )
00593             TGo4Log::Warn("Too close hits in vftx %d channel %d: old coarse %d new coarse %d diff %d ft %3x",
00594                   num, hit.ch_ix, iLastFpgaTdcCoarse[num][hit.ch_ix], hit.coarse_ct,
00595                   (Int_t)hit.coarse_ct - iLastFpgaTdcCoarse[num][hit.ch_ix],
00596                   hit.ch_tim);
00597 
00598          iLastFpgaTdcCoarse[num][hit.ch_ix] = hit.coarse_ct;
00599       }
00600 
00601       // cout << "data: "<< l_nr_cha << " ch: " << hit.ch_ix << " ct: " << hit.coarse_ct;
00602       // cout << " ft: " << hit.ch_tim << " fut: " << hit.future_bit << endl;
00603       fOutputEvent->fFPGA[num].push_back(hit);
00604       
00605       if( 1 == fPar->uVftxHistosEnabled[num] )
00606          if (hit.ch_ix<FPGA_TDC_NBCHAN)
00607             fFPGA_Ch[num][hit.ch_ix]->Fill(hit.ch_tim);
00608    } // while (l_nr_cha-- > 0)
00609 
00610    // Attempt at sorting hits according to their times
00611    stable_sort( fOutputEvent->fFPGA[num].begin(), fOutputEvent->fFPGA[num].end() );
00612 
00613    //cout<<" FPGA TDC num "<<num<<" finished"<<endl;
00614    fOutputEvent->SetValid(kTRUE);
00615 }
00616 
00617 void TMbsCrateProc::ProcessQFW(uint32_t* pdata, unsigned int len)
00618 {
00619    if (len!=9) {
00620       TGo4Log::Error("Wrong QFW format");
00621       return;
00622    }
00623 
00624    for (int n=0;n<4;n++) {
00625       fOutputEvent->fQFW.counters[n] = *pdata++;
00626       if( 1 == fPar->uQFWHistosEnabled )
00627          fQFWcnt->SetBinContent(n+1, fOutputEvent->fQFW.counters[n]);
00628    }
00629 
00630    TString txt = "#splitline";
00631 
00632    for (int n=0;n<4;n++) {
00633       fOutputEvent->fQFW.errcnt[n] = *pdata++;
00634       if( 1 == fPar->uQFWHistosEnabled )
00635          fQFWerr->SetBinContent(n+1, fOutputEvent->fQFW.errcnt[n]);
00636 
00637       txt+=Form("{#scale[2.0]{#color[2]{Ch%d cnt:%10u err:%10u}}}", n, fOutputEvent->fQFW.counters[n], fOutputEvent->fQFW.errcnt[n]);
00638    }
00639 
00640    fOutputEvent->fQFW.setup = *pdata;
00641 
00642    txt+=Form("{#scale[2.0]{#color[2]{Setup: %d}}}", fOutputEvent->fQFW.setup);
00643 
00644    if( 1 == fPar->uQFWHistosEnabled )
00645       fQFWInfo->SetText(0.2, 0.5, txt.Data());
00646 
00647    fOutputEvent->SetValid(kTRUE);
00648 }
00649 
00650 void TMbsCrateProc::ProcessScalOrMu(uint32_t* pdata, unsigned int len)
00651 {
00652    if( 16 == SCALORMU_NB_SCAL )
00653    {
00654       if (len != SCALORMU_NB_SCAL) {
00655          TGo4Log::Error("Wrong Scaler Or Multiplicity sub-event length: %u instead of %d",
00656                len, SCALORMU_NB_SCAL);
00657          return;
00658       }
00659       if( 1 == fPar->uDebug )
00660          TGo4Log::Info("Scaler Or Multiplicity sub-event found!");
00661       for( Int_t iScalerInd=0; iScalerInd < SCALORMU_NB_SCAL; iScalerInd++)
00662          fOutputEvent->fScalOrMu.uScaler[iScalerInd] = (UInt_t)*pdata++;
00663    }
00664       else
00665       {
00666          if (len != SCALORMU_NB_SCAL + 1) {
00667             TGo4Log::Error("Wrong Scaler Or Multiplicity sub-event length: %u instead of %d",
00668                   len, SCALORMU_NB_SCAL + 1);
00669             return;
00670          }
00671          if( 1 == fPar->uDebug )
00672             TGo4Log::Info("Scaler Or Multiplicity sub-event found!");
00673          for( Int_t iScalerInd=0; iScalerInd < SCALORMU_NB_SCAL; iScalerInd++)
00674             fOutputEvent->fScalOrMu.uScaler[iScalerInd] = (UInt_t)*pdata++;
00675          fOutputEvent->fScalOrMu.uReferenceClock = (UInt_t)*pdata++;
00676       }
00677 }
00678 

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