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

onlinemonitor/rocmonitor/TRocProc.cxx (r4864/r3871)

Go to the documentation of this file.
00001 #include "TRocProc.h"
00002 
00003 #include "TH1.h"
00004 #include "TH2.h"
00005 #include "TTimeStamp.h"
00006 #include "TROOT.h"
00007 #include "TSystem.h"
00008 #include "TLatex.h"
00009 
00010 #include "TRocAnalysis.h"
00011 #include "TRocParam.h"
00012 #include "TPedestalExtractor.h"
00013 #include "TGo4MbsEvent.h"
00014 #include "TGo4WinCond.h"
00015 #include "TGo4Log.h"
00016 #include "TGo4Version.h"
00017 
00018 #include "roc/Message.h"
00019 //#include "roc/Iterator.h"
00020 #include "roc/Board.h"
00021 
00022 #include <algorithm>
00023 
00024 // enable this define for "online" mode with only one aux trigger per input buffer analyzed
00025 // if disabled, may process up to TRocParam::maxBufferTriggers per buffer (only offline mode with no lost samples!)
00026 #define ROC_SINGLETRIGGERMODE 1
00027 
00028 //#define DUMPMODE 1
00029 
00030 //#define DUMPALLMESSAGES 1
00031 
00032 #define GET4_BUFFERS_SIZE_LIMIT 100000
00033 
00034 TRocProc::TRocProc() :
00035    TCBMBeamtimeProc(),
00036    //fIter(fDefaultIter),
00037    fPedestals(0),
00038    fIsTimeSorted(kFALSE),
00039    fOutputEvent(0),
00040    fHasNewGlobalTrigger(kFALSE)
00041 {
00042 }
00043 
00044 //***********************************************************
00045 TRocProc::~TRocProc()
00046 {
00047    // Control over Automatic reset
00048    if ((fParam->uNbFeets>0) || (fParam->uNbRocsGet4>0))
00049       TGo4Log::Info("Total Nb GET4 resets: %d", uIndexResetGet4);
00050 
00051    TGo4Log::Info("TRocProc: Delete instance ");
00052    if (fParam->baselineCalibr && (fParam->pedSaveToFile.Length()>0) && fPedestals) {
00053       fPedestals->Extract();
00054       fPedestals->SaveToFile(fParam->pedSaveToFile.Data());
00055    }
00056 
00057    if (fPedestals) {
00058       delete fPedestals;
00059       fPedestals = 0;
00060    }
00061 }
00062 
00063 //***********************************************************
00064 // this one is used in standard factory
00065 TRocProc::TRocProc(const char* name) :
00066    TCBMBeamtimeProc(name),//fIter(fDefaultIter),
00067    fIsTimeSorted(kFALSE),
00068    fOutputEvent(0),
00069    fHasNewGlobalTrigger(kFALSE)
00070 {
00071    TGo4Log::Info("TRocProc: Create instance %s", name);
00072 
00073    // here we optionally override parameter values with setup macro, if existing:
00074    TString setupmacro = "set_RocPar.C";
00075    if(TString(TGo4Analysis::Instance()->ClassName())=="TRocAnalysis") {
00076       // in standalone roc analysis, take name of parameter setter macro from commandline arguments "-args -p mymacro.C"
00077       //JAM note that dynamic_cast would lead to linker problems here when working in full beamtime analysis
00078       TString usermacro = ((TRocAnalysis*)TGo4Analysis::Instance())->getUserPars();
00079       if (!usermacro.IsNull()) setupmacro = usermacro;
00080    }
00081 
00082    fParam = (TRocParam *) MakeParameter("RocPar", "TRocParam", setupmacro.Data());
00083 
00084         //ExecuteScript(setupmacro.Data());
00085 
00086    if (fParam)
00087       fParam->SetConfigRocs();
00088 
00089    //   fParam->triggerSignal = 10;
00090    //   fNumRocs = 3;
00091 
00092    fLastRateTm = TTimeStamp().AsDouble();
00093    fTotaldatasize = 0;
00094    fRate = 0.;
00095 
00096 
00097 
00098    if( kFALSE == fParam->noTrigger && 1 == fParam->uUseLocalEpochs )
00099    {
00100       fParam->uUseLocalEpochs = 0;
00101       cout<<"Disabling usage of local epochs for the Get4s, as incompatible with trigger window!"<<endl;
00102    }
00103    if (fParam->uNbRocsGet4>0)
00104       fParam->PrintGet4Options();
00105    if (fParam->numRocs > 0) fNumRocs = (unsigned) fParam->numRocs;
00106    if (fNumRocs > MAX_ROC) fNumRocs = MAX_ROC;
00107 
00108    for (int nx=0;nx<MAX_NX;nx++)
00109       nx_use_mask[nx] = false;
00110 
00111    switch (fParam->numNX) {
00112       case 0: break;
00113       case 1: nx_use_mask[0] = true; break; // show only even numbers
00114       case 2: nx_use_mask[0] = true; nx_use_mask[2] = true; break;
00115       default:
00116          for (int nx=0;nx<MAX_NX;nx++) nx_use_mask[nx] = true;
00117          break;
00118    }
00119 
00120    for (int n=0;n<MAX_GET4;n++)
00121       get4_use_mask[n] = false;
00122 
00123    int nget4 = fParam->uNbFeets*2;
00124    if (nget4>MAX_GET4) nget4 = MAX_GET4;
00125    for (int n=0;n<nget4;n++)
00126       get4_use_mask[n] = true;
00127 
00128    for (unsigned n=0; n<fNumRocs;n++) {
00129       ROC.push_back(TRocRec());
00130       ROC[n].fRocId = n;
00131    }
00132 
00133    fEvntSize = MakeTH1('I', "EvntSize", "Number of messages in event", 250, 1., 2000.);
00134 
00135    int hnumroc = fNumRocs > 8 ? fNumRocs : 8;
00136 
00137    fMsgsPerRoc = MakeTH1('I', "MsgsPerRoc", "Number of messages per ROC", hnumroc, 0., hnumroc);
00138 
00139    fTriggerPerRoc = MakeTH1('I', "TriggersPerRoc", "Number of Trigger messages per ROC", hnumroc, 0., hnumroc);
00140 
00141    fDeltaTriggerTime = MakeTH1('I', "TriggerDeltaTime", "Corrected hits time difference of all ROCs", 5000, -5000., 5000., "#Delta t");
00142    
00143    fGlobalTriggerWind = MakeWinCond("TriggerWindow", -100, 2000., fDeltaTriggerTime->GetName());
00144    fGlobalAUXWind = MakeWinCond("AUXWindow", -100, 100., fDeltaTriggerTime->GetName());
00145 
00146    fAUX2_R01 = 0;
00147    fSYNC_R0_R10 = 0;
00148 
00149 //   if (fNumRocs>1)
00150 //      fAUX2_R01 = MakeTH1('I', "AUX2_R01", "Time difference between AUX2 messages on ROC0 and ROC1", 200, -200., +200);
00151 
00152 //   if (fNumRocs>9)
00153 //      fSYNC_R0_R10 = MakeTH1('I', "SYNC_R0_R10", "Time difference between SYNC0/R10 and SYNC1/R0", 20000, -100000., +100000);
00154 
00155    fPedestals = 0;
00156 
00157    if (fParam->baselineCalibr) {
00158       fPedestals = new TPedestalExtractor(fNumRocs, MAX_NX, fParam->pedInitState );
00159       fPedestals->SetExttrigCalibrPeriod( fParam->pedTtriCalibrPeriod );
00160       fPedestals->SetVerbose( fParam->pedVerbose );
00161       if (fParam->pedestalFile.Length()>0) {
00162          fPedestals->LoadFromFile(fParam->pedestalFile.Data());
00163       }
00164    }
00165 
00166    for (unsigned n=0; n<fNumRocs;n++) {
00167       ROC[n].fIsEventComplete = kFALSE;
00168       ROC[n].fHasNewData = kFALSE;
00169 
00170       // do not build histograms for non-used ROC
00171       if (!AssertRoc(n)) continue;
00172 
00173       char folder[30];
00174       sprintf(folder,"ROC%u/",n);
00175 
00176       ROC[n].fMsgTypes = MakeTH1('I', Form("%sMsgTypes%u", folder, n), Form("ROC%u Distribution of messages types", n), 8, 0., 8.);
00177 
00178       if (IsObjMade()) {
00179          ROC[n].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_NOP, "NOP");
00180          ROC[n].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_HIT, "HIT");
00181          ROC[n].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_EPOCH, "EPOCH");
00182          ROC[n].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_SYNC, "SYNC");
00183          ROC[n].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_AUX, "AUX");
00184          ROC[n].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_EPOCH2, "EPOCH2");
00185          ROC[n].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_GET4, "GET4");
00186          ROC[n].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_SYS, "SYS");
00187       }
00188 
00189       ROC[n].fSysTypes = MakeTH1('I', Form("%sSysTypes%u", folder, n), Form("ROC%u Distribution of system messages", n), roc::SYSMSG_GET4_EVENT+1, 0., roc::SYSMSG_GET4_EVENT+1);
00190 
00191       if (IsObjMade()) {
00192          ROC[n].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_DAQ_START,  "DAQ_START");
00193          ROC[n].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_DAQ_FINISH, "DAQ_FINISH");
00194          ROC[n].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_NX_PARITY,  "NX_PARITY");
00195          ROC[n].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_SYNC_PARITY,"SYNC_PARITY");
00196          ROC[n].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_DAQ_RESUME, "DAQ_RESUME");
00197          ROC[n].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_FIFO_RESET, "FIFO_RESET");
00198          ROC[n].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_USER,       "USER_MSG");
00199          ROC[n].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_PCTIME,     "PCTIME");
00200          ROC[n].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_ADC,        "ADC");
00201          ROC[n].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_PACKETLOST, "PACKETLOST");
00202          ROC[n].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_GET4_EVENT, "GET4_EVENT");
00203       }
00204 
00205       ROC[n].fSysUserTypes = MakeTH1('I', Form("%sSysUserTypes%u", folder, n), Form("ROC%u Distribution of user messages", n), 8, 7., 15.);
00206       if (IsObjMade()) {
00207          ROC[n].fSysUserTypes->GetXaxis()->SetBinLabel(roc::SYSMSG_USER_CALIBR_ON - 6, "CALIBR_ON");
00208          ROC[n].fSysUserTypes->GetXaxis()->SetBinLabel(roc::SYSMSG_USER_CALIBR_OFF - 6, "CALIBR_OFF");
00209          ROC[n].fSysUserTypes->GetXaxis()->SetBinLabel(roc::SYSMSG_USER_RECONFIGURE - 6, "RECONFIGURE");
00210       }
00211 
00212       ROC[n].fAUXch = MakeTH1('I', Form("%sRoc%u_aux_chs", folder, n), "Number events per aux channel", 8, 0., 8.);
00213 
00214       ROC[n].fTrigger_AllNX = MakeTH1('I', Form("%sRoc%u_Trigger", folder, n), Form("Time difference between all hits and last trigger signal on ROC%u", n), 2500, -1000., 4000.);
00215       ROC[n].fTrigger_AllNX_100 = MakeTH1('I', Form("%sRoc%u_Trigger_100", folder, n), Form("Time difference between all hits and last trigger signal on ROC%u", n), 50005, -100000., 1e6);
00216 
00217       ROC[n].fTrigger_AUX = MakeTH1('I', Form("%sRoc%u_Trigger_AUX", folder, n), Form("Time difference between all AUXs and last trigger signal on ROC%u", n), 5000, -5000., 5000.);
00218 
00219       ROC[n].fTriggerWind = MakeWinCond(Form("Roc%u_EventWindow",n), 485., 885., ROC[n].fTrigger_AllNX->GetName());
00220 
00221       ROC[n].fAUXWind = MakeWinCond(Form("Roc%u_AUXWindow",n), -100., 100., ROC[n].fTrigger_AUX->GetName());
00222 
00223       ROC[n].fEvntMultipl = MakeTH1('I', Form("%sRoc%u_Multiplicity", folder, n), Form("Event multiplicity for ROC%u in time window", n), 16, 0., 16.);
00224 
00225       ROC[n].fALLt = MakeTH1('I', Form("%sRoc%u_ALL_t", folder,n), Form("Time distribution of ALL hits on ROC%u", n), 10000, 0., 1000.,"s");
00226 
00227 
00228 
00229       for (unsigned nsync=0; nsync<MAX_SYNC; nsync++)
00230          ROC[n].fSYNCt[nsync] = MakeTH1('I', Form("%sRoc%u_Sync%u_t", folder, n, nsync), Form("Time distribution of SYNC%u signal on ROC%u", nsync, n), 10000, 0., 1000.,"s");
00231 
00232       for (unsigned naux=0; naux<MAX_AUX; naux++)
00233          ROC[n].fAUXt[naux] = MakeTH1('I', Form("%sRoc%u_Aux%u_t", folder, n, naux), Form("Time distribution of AUX%u signal on ROC%u", naux, n), 10000, 0., 1000.,"s");
00234 
00235       for (int k=0;k<2;k++)
00236          ROC[n].fFebADC[k] = MakeTH1('I', Form("%sRoc%u_Feb%d_adcs", folder, n, k), Form("ADC values on ROC%u FEB%d", n, k), 4, 0., 4., "channel", "ADC");
00237 
00238       for(unsigned nx=0;nx<MAX_NX;nx++) {
00239 
00240          if (!AssertNX(nx)) continue;
00241 
00242          char nxfolder[30], nxinfo[30];
00243          sprintf(nxfolder,"%sNX%u/Roc%u_nx%u_", folder, nx, n, nx);
00244          sprintf(nxinfo,"ROC = %u NXYTER = %u", n, nx);
00245 
00246          ROC[n].fChs[nx] = MakeTH1('I', Form("%schannels", nxfolder), Form("Channels from %s", nxinfo), 128, 0., 128.);
00247          ROC[n].fTrigger_Chs[nx] = MakeTH1('I', Form("%schs_trigg", nxfolder), Form("Channels from %s under trigger cut", nxinfo), 128, 0., 128.);
00248          ROC[n].fADCs[nx] = MakeTH2('I', Form("%sadc", nxfolder), Form("ADC distribution for %s", nxinfo), 128, 0., 128., 1024, 0., 4096., "Channel number", "ADC values");
00249                  ROC[n].fTrigADCs[nx] = MakeTH2('I', Form("%sadctrig", nxfolder), Form("ADC distribution for %s for the Trigger condition", nxinfo), 128, 0., 128., 1024, 0., 4096., "Channel number", "ADC values");
00250          ROC[n].fBaseline[nx] = MakeTH2('I', Form("%sBaseline", nxfolder), Form("Baseline for %s", nxinfo), 128, 0., 128., 4096, 0., 4096., "Channel number", "Baseline, ADC counts");
00251          if (fParam->baselineCalibr)
00252             ROC[n].fADCs_wo_baseline[nx] = MakeTH2('I', Form("%sadc_wo_baseline", nxfolder), Form("ADC - Baseline   for %s", nxinfo), 128, 0., 128., 1024, -200., 824., "Channel number", "ADC values (baseline subtracted)");
00253          ROC[n].fTrigger_NX[nx] = MakeTH1('I', Form("%sTrigger", nxfolder), Form("Time difference between hit and last trigger signal on %s", nxinfo), 2500, -1000., 4000.);
00254 
00255          ROC[n].fHITt[nx] = MakeTH1('I', Form("%sHIT_t", nxfolder), Form("Time distribution of HIT signal on %s", nxinfo), 10000, 0., 1000.,"s");
00256 
00257 
00258          if (fParam->nxDiffCh>=0)
00259             for (int ndiff=0;ndiff<NUM_DIFFS; ndiff++) {
00260                int nch = ndiff * (MOD_DIFFS + 1) + MOD_DIFFS;
00261                ROC[n].fTmDiff[nx][ndiff] = MakeTH1('I', Form("%sDiff_%d_%d", nxfolder, fParam->nxDiffCh, nch), Form("Time difference between channels %d and %d from %s", fParam->nxDiffCh, nch, nxinfo), 2000, -1000., 1000.);
00262             }
00263 
00264       } // for nx
00265 
00266 
00268       if (fParam->uNbFeets>0) {
00269 
00270          ROC[n].fGet4SysTypes = MakeTH1('I', Form("%sGet4SysTypes%u", folder, n), Form("ROC%u Distribution of GET4 system messages", n), 2, 0., 2.);
00271          if (IsObjMade()) {
00272             ROC[n].fGet4SysTypes->GetXaxis()->SetBinLabel(1, "ERROR");
00273             ROC[n].fGet4SysTypes->GetXaxis()->SetBinLabel(2, "EXT_SYNC");
00274          }
00275          
00276          ROC[n].fGet4Chips = MakeTH1('I', Form("%sGet4Chips%u", folder, n), Form("ROC%u distribution of GET4 messages", n), MAX_GET4, 0, MAX_GET4);
00277       }
00278 
00279       for (unsigned g4=0;g4<MAX_GET4;g4++) {
00280          if (!AssertGET4(g4)) continue;
00281 
00282          char g4folder[30], g4info[30];
00283          sprintf(g4folder,"%sG4%u/Roc%u_g4%u_", folder, g4, n, g4);
00284          sprintf(g4info,"ROC = %u GET4 = %u", n, g4);
00285 
00286          ROC[n].fGet4Channels[g4] = MakeTH1('I', Form("%sChannels", g4folder), Form("Channels distribution on %s", g4info), MAX_GET4_CH*2, 0, MAX_GET4_CH*2, "chip");
00287          ROC[n].fGet4Tm[g4] = MakeTH1('I', Form("%sStamp", g4folder), Form("Time stamp distribution on %s", g4info), 26215, 0., 26215., "ns");
00288          ROC[n].fGet4DiffSync[g4] = MakeTH1('I', Form("%sDiffSync", g4folder), Form("Difference to last epoch2 with sync on %s", g4info), 65536, 0., 655360., "ns");
00289 
00290          ROC[n].fGet4Trigger[g4] = MakeTH1('I', Form("%sTrigger", g4folder), Form("Time difference between Get4 hits and last trigger on %s", g4info), 2500, -1000., 4000.);
00291          ROC[n].fGet4Trigger100[g4] = MakeTH1('I', Form("%sTrigger100", g4folder), Form("Time difference between Get4 hits and last trigger signal on %s", g4info), 5005, -1000., 1e6);
00292 
00293          for(int k=0;k<MAX_GET4_CH;k++)
00294             for (int fl=0;fl<2;fl++) {
00295                ROC[n].fGet4TmCh[g4][k][fl] = MakeTH1('I', Form("%sStamp_ch%d_%s", g4folder, k, (fl ? "fall" : "rise")), Form("Time stamps distribution on %s channel %d edge %s", g4info, k, (fl ? "rise" : "fall")), 26215, 0., 26215., "ns");
00296                
00297                ROC[n].fGet4Channels[g4]->GetXaxis()->SetBinLabel(1+k*2+fl,Form("Ch%d %s",k,(fl ? "fall" : "rise")));
00298             }
00299 
00300          ROC[n].fGet4Info[g4] = new TLatex(0.2, 0.2, "--- sample text ---");
00301          ROC[n].fGet4Info[g4]->SetName(Form("ROC%u_get4%u_info", n, g4));
00302          ROC[n].fGet4Info[g4]->SetNDC();
00303          AddObject(ROC[n].fGet4Info[g4]); // will replace old one of same name
00304       }
00305    }
00306    
00308    if( kFALSE == fParam->NoGet4Cleaning )
00309    { // Remove all Cleaning related histograms
00310       for( UInt_t uChip = 0; uChip < 2*fParam->uNbFeets; uChip++ )
00311          FECHIP.push_back(TGet4Rec());
00312 
00313       // GET4 chip specific initialization
00314       for( UInt_t uChip = 0; uChip < 2*fParam->uNbFeets; uChip++ )
00315       { // Loop on chips, 2 chip per board
00316          //~ FECHIP[uChip].fIsEventComplete=kFALSE;
00317          
00318          // Multiple buffers solution
00319          FECHIP[uChip].uLastEpoch2                     = 0;
00320          FECHIP[uChip].uRocEpochCycle                  = 0;
00321          FECHIP[uChip].uLocalEpochNb                   = 0;
00322          FECHIP[uChip].uLocalEpochCycle                = 0;
00323          (FECHIP[uChip].bValidEpochFlag).resize(  fParam->uNbBuffers );
00324          (FECHIP[uChip].fCurrentEventMsg).resize( fParam->uNbBuffers );
00325          (FECHIP[uChip].uEpochStart).resize(      fParam->uNbBuffers );
00326          (FECHIP[uChip].uCycleStart).resize(      fParam->uNbBuffers );
00327          (FECHIP[uChip].bMessageInterBufferOk).resize(fParam->uNbBuffers );
00328          (FECHIP[uChip].fCurrentUnprocessedMsg).resize( fParam->uNbBuffers );
00329          for( UInt_t uBuffer = 0; uBuffer < fParam->uNbBuffers; uBuffer ++)
00330          {  // Same number of buffers for chip and epoch buffers
00331             (FECHIP[uChip].bValidEpochFlag)[uBuffer] = kFALSE;
00332             (FECHIP[uChip].fCurrentEventMsg)[uBuffer].clear();
00333             (FECHIP[uChip].uEpochStart)[uBuffer]     = 0;
00334             (FECHIP[uChip].uCycleStart)[uBuffer]     = 0;
00335             (FECHIP[uChip].bMessageInterBufferOk)[uBuffer] = kFALSE;
00336             (FECHIP[uChip].fCurrentUnprocessedMsg)[uBuffer].clear();
00337          }
00338 
00339          TString sChipFolder = Form("Feet/Get4/Chip%u/",uChip);
00340          TString sChanFolder[NB_CHAN_GET4];
00341          for(Int_t iChan = 0; iChan < NB_CHAN_GET4; iChan++)
00342             sChanFolder[iChan] = Form("Channel%d/",NB_CHAN_GET4*uChip + iChan);
00343 
00344          // Chip Related histograms
00345          FECHIP[uChip].fGet4SyncSpacing = MakeTH1('I',
00346             sChipFolder + Form( "SyncSpacing%d", uChip),
00347             Form( "Non synced Epochs between synced Epochs on Chip %d", uChip ),
00348             2*fParam->uSyncCycleSize, 0, 2*fParam->uSyncCycleSize, "No of Epochs [1]", "Entries [1]" );
00349          FECHIP[uChip].fGet4SyncSpacingComp = MakeTH2('I',
00350             sChipFolder + Form( "SyncSpacing%dComp", uChip),
00351             Form( "Non synced Epochs between synced Epochs, corrected for sync losses versus uncorrected on Chip %d", uChip ),
00352             2*fParam->uSyncCycleSize, 0, 2*fParam->uSyncCycleSize, 2*fParam->uSyncCycleSize, 0, 2*fParam->uSyncCycleSize,
00353             "No of Epochs [1]", "No of Epochs [1]", "Entries [1]" );
00354 
00355          FECHIP[uChip].fGet4ValidSpacing = MakeTH1('I',
00356             sChipFolder + Form( "ValidSpacing%d", uChip),
00357             Form( "Non synced Epochs between synced valid Epochs on Chip %d", uChip ),
00358             30, 0, 30, "No of Epochs [1]", "Entries [1]" );
00359 
00360          FECHIP[uChip].fGet4InvalidSpacing = MakeTH1('I',
00361             sChipFolder + Form( "InvalidSpacing%d", uChip),
00362             Form( "Non synced Epochs between synced invalid Epochs on Chip %d", uChip ),
00363             3*fParam->uSyncCycleSize, 0, 3*fParam->uSyncCycleSize, "No of Epochs [1]", "Entries [1]" );
00364 
00365          FECHIP[uChip].fGet4ValidEpochs = MakeTH1( 'I',
00366             sChipFolder + Form( "ValidEpochs%d", uChip),
00367             Form( "Valid epochs (chips %d synched)", uChip ),
00368             2, -0.5, 1.5, "Valid? [0 = False, 1= True]", "Entries [1]" );
00369          FECHIP[uChip].fGet4MessValidEpochs = MakeTH1( 'I',
00370             sChipFolder + Form( "Raw/RawMessValidEpochs%d", uChip),
00371             Form( "Messages in Valid epochs (chips %d synched)", uChip ),
00372             501, -0.5, 500.5, "Mess Nb [1]", "Entries [1]" );
00373          FECHIP[uChip].fGet4AccMessNotValidated = MakeTH1( 'I',
00374             sChipFolder + Form( "Raw/RawAccMessNotValidEpochs%d", uChip),
00375             Form( "Nb of messages matching the trigger accepted without epoch validation bec. event (chips %d not synched)", uChip ),
00376             501, -0.5, 500.5, "Mess Nb [1]", "Entries [1]" );
00377 
00378          FECHIP[uChip].fModuloSyncRoc= MakeTH2( 'I',
00379             sChipFolder + Form( "ModuloSyncRoc%d", uChip),
00380             "Evolution of the modulo for the ROC epoch with sync",
00381             501, -0.5, 500.5, 2*fParam->uSyncCycleSize, 0, 2*fParam->uSyncCycleSize,
00382             "Cycle (~27s) [1]", "; Modulo [1]" );
00383          FECHIP[uChip].fModuloSyncLocal= MakeTH2( 'I',
00384             sChipFolder + Form( "ModuloSyncLocal%d", uChip),
00385             "Evolution of the modulo for the local epoch with sync",
00386             501, -0.5, 500.5, 2*fParam->uSyncCycleSize, 0, 2*fParam->uSyncCycleSize,
00387             "Cycle (~27s) [1]", "; Modulo [1]" );
00388          FECHIP[uChip].fModuloSyncMainClock= MakeTH2( 'I',
00389             sChipFolder + Form( "ModuloSyncMain%d", uChip),
00390             "Evolution of the modulo for the 250MHz epoch in 150MHz epoch with sync",
00391             501, -0.5, 500.5, 2*fParam->uMainSyncCycleSize, 0, 2*fParam->uMainSyncCycleSize,
00392             "Cycle (~27s) [1]", "; Modulo [1]" );
00393 
00394          FECHIP[uChip].fInterChipSyncEpochShiftEvol= MakeTH2( 'I',
00395             sChipFolder + Form( "InterChipSyncEpochShiftEvol%d", uChip),
00396             "Evolution of the Inter chip epoch shift check",
00397             501, -0.5, 500.5, 10, -5.5, 4.5,
00398             "Cycle (~27s) [1]", "; Shift [1]" );
00399 
00400          // Channels related Histograms
00401          for(Int_t iChan = 0; iChan < NB_CHAN_GET4; iChan++)
00402          { // Loop on channels per chips
00403             Int_t iFullChan = NB_CHAN_GET4*uChip + iChan;
00404 
00405             // Just to be sure, hopefully useless
00406             FECHIP[uChip].fGet4FineTimeLE[iChan]       = 0; // Finetime of Leading Edge
00407             FECHIP[uChip].fGet4FineTimeTE[iChan]       = 0; // Finetime of Trailing Edge
00408             FECHIP[uChip].fGet4LeDnl[iChan]            = 0; // DNL value for each bin
00409             FECHIP[uChip].fGet4LeDnlSum[iChan]         = 0; // Integral of DNL value up to each bin
00410             FECHIP[uChip].fGet4TeDnl[iChan]            = 0; // DNL value for each bin
00411             FECHIP[uChip].fGet4TeDnlSum[iChan]         = 0; // Integral of DNL value up to each bin
00412             FECHIP[uChip].fNbConsecutiveLE[iChan]      = 0; // Nb of consecutive Leading edges (should stay at 1 or max 2 when multi hits)
00413             FECHIP[uChip].fNbConsecutiveTE[iChan]      = 0; // Nb of consecutive Trailing edges (should stay at 1 or max 2 when multi hits)
00414 
00415             // Histos
00416             FECHIP[uChip].fGet4RisEdgesNbEvol[iChan] = MakeTH1( 'I',
00417                "Feet/debug/"+ sChanFolder[iChan] + Form("Raw/RawRisingNbEvo%d", iFullChan),
00418                Form( "Nb of rising  edges per cycle, channel %d ", iFullChan ),
00419                500, 0, 499, "Cycle []", "Edges [1]" );
00420             FECHIP[uChip].fGet4FalEdgesNbEvol[iChan] = MakeTH1( 'I',
00421                "Feet/debug/"+ sChanFolder[iChan] + Form("Raw/RawFallingNbEvo%d", iFullChan),
00422                Form( "Nb of falling edges per cycle, channel %d ", iFullChan ),
00423                500, 0, 499, "Cycle []", "Edges [1]" );
00424 
00425             if( 1 == fParam->uDebugHistoOn )
00426             {
00427                   FECHIP[uChip].fGet4FineTimeLE[iChan] = MakeTH1('I',
00428                      "Feet/Channels/"+ sChanFolder[iChan] + Form("LeadingEdge/RawFineTimeL%d", iFullChan),
00429                      Form( "Nonlinearity Histogram of Channel %d Leading Edge",iFullChan),
00430                      NB_BIN_GET4_FTS,-0.5, NB_BIN_GET4_FTS- 0.5, "Bin [1]","Entries [1]" );
00431 
00432                   FECHIP[uChip].fGet4FineTimeTE[iChan] = MakeTH1('I',
00433                      "Feet/Channels/"+ sChanFolder[iChan] + Form("TrailingEdge/RawFineTimeT%d", iFullChan),
00434                      Form( "Nonlinearity Histogram of Channel %d Trailing Edge",iFullChan),
00435                      NB_BIN_GET4_FTS,-0.5, NB_BIN_GET4_FTS - 0.5, "Bin [1]","Entries [1]" );
00436 
00437                   FECHIP[uChip].fGet4LeDnl[iChan] = MakeTH1('I',
00438                      "Feet/Channels/"+ sChanFolder[iChan] + Form("LeadingEdge/RawDnlL%d", iFullChan),
00439                      Form( "DNL of Channel %d Leading Edge",iFullChan),
00440                      NB_BIN_GET4_FTS,-0.5,NB_BIN_GET4_FTS - 0.5, "Bin [1]","DNL offset [Bin]" );
00441                   FECHIP[uChip].fGet4LeDnlSum[iChan] = MakeTH1('I',
00442                      "Feet/Channels/"+ sChanFolder[iChan] + Form("LeadingEdge/RawDnlIntL%d", iFullChan),
00443                      Form( "Dnl Sum of Channel %d Leading Edge",iFullChan),
00444                      NB_BIN_GET4_FTS,-0.5,NB_BIN_GET4_FTS - 0.5, "Bin [1]","DNL Sum [Bin]" );
00445 
00446                   FECHIP[uChip].fGet4TeDnl[iChan] = MakeTH1('I',
00447                      "Feet/Channels/"+ sChanFolder[iChan] + Form("TrailingEdge/RawDnlT%d", iFullChan),
00448                      Form( "DNL of Channel %d Trailing Edge",iFullChan),
00449                      NB_BIN_GET4_FTS,-0.5,NB_BIN_GET4_FTS - 0.5, "Bin [1]","DNL offset [Bin]" );
00450                   FECHIP[uChip].fGet4TeDnlSum[iChan] = MakeTH1('I',
00451                      "Feet/Channels/"+ sChanFolder[iChan] + Form("TrailingEdge/RawDnlIntT%d", iFullChan),
00452                      Form( "DNL Sum of Channel %d Trailing Edge",iFullChan),
00453                      NB_BIN_GET4_FTS,-0.5,NB_BIN_GET4_FTS - 0.5, "Bin [1]","DNL Sum [Bin]" );
00454 
00455                   FECHIP[uChip].fNbConsecutiveLE[iChan] = MakeTH1( 'I',
00456                      "Feet/debug/"+ sChanFolder[iChan] + Form("RawConsLE%d", iFullChan),
00457                      Form( "Nb of consecutive Leading edges in Valid epochs (chips %d synched)", uChip ),
00458                      15, 0.5, 15.5, "LE Nb [1]", "Entries [1]" );
00459                   FECHIP[uChip].fNbConsecutiveTE[iChan] = MakeTH1( 'I',
00460                      "Feet/debug/"+ sChanFolder[iChan] + Form("RawConsTE%d", iFullChan),
00461                      Form( "Nb of consecutive Leading edges in Valid epochs (chips %d synched)", uChip ),
00462                      15, 0.5, 15.5, "TE Nb [1]", "Entries [1]" );
00463             } // if( 1 == fParam->uDebugHistoOn )
00464          } // for(Int_t iChan = 0; iChan < NB_CHAN_GET4; iChan++)
00465       } // for( UInt_t uChip = 0; uChip < fParam->uNbFeets; uChip++ )
00466 
00467       // General variables
00468       for(UInt_t uTempFeetRoc = 0; uTempFeetRoc < fParam->uNbRocsGet4;uTempFeetRoc++)
00469          uNbEvents[uTempFeetRoc] = 0;
00470       // GET4 general variables
00471       uCurrentEpoch2 = 0;
00472       uCurrentCycle2 = 0;
00473 
00474       uLastEpochMainClock = 0;
00475       uMainEpochCycle     = 0;
00476    
00477       uRocEpochFirstSyncedChip = 0;
00478       uRocCycleFirstSyncedChip = 0;
00479    
00480       uEpochFirstSyncAfterReset = 0;
00481       uCycleFirstSyncAfterReset = 0;
00482    
00483       bTransferMessageNext = kFALSE;
00484 
00485       uEpochBufferStart = 0 ;
00486       uCycleBufferStart = 0 ;
00487 
00488       vMessageInterBuffer.resize( fParam->uNbBuffers );
00489       vMessageInterBufferUnprocessed.resize( fParam->uNbBuffers );
00490       for( UInt_t uBuffer = 0; uBuffer < fParam->uNbBuffers; uBuffer ++)
00491       {
00492          vMessageInterBuffer[uBuffer].clear();
00493          vMessageInterBufferUnprocessed[uBuffer].clear();
00494       }
00495       vMessageEventBuffer.clear();
00496 
00497       vUnprocessedMessages.resize( fNumRocs );
00498       for( UInt_t uRoc = 0; uRoc < fNumRocs; uRoc ++)
00499          vUnprocessedMessages[uRoc].clear();
00500    } // if( kFALSE == fParam->NoGet4Cleaning )
00501 
00502    // GET4 general histograms
00503 
00504    fDistribEpochsMain = 0;
00505 
00506    if ((fParam->uNbFeets>0) || (fParam->uNbRocsGet4>0)) {
00507 
00508       fGet4SynchChip = MakeTH1('I', "Feet/Messages/Get4ExternalSynchChip",
00509                               "Get4 chip sending External Synch message",
00510                               fParam->uNbFeets*2, -0.5, fParam->uNbFeets*2 -0.5, "Ext Sync chip","Entries [1]");
00511       fGet4SynchPatt = MakeTH2('I', "Feet/Messages/Get4ExternalSynchPatt",
00512                               "Pattern of Get4 External Synch message",
00513                               fParam->uNbFeets*2, -0.5, fParam->uNbFeets*2 -0.5, 64, 0., 64.,
00514                               "Ext Sync chip", "Sync Pattern","Entries [1]");
00515       fGet4ErrorChip = MakeTH1('I', "Feet/Messages/Get4ErrorChip",
00516                               "Get4 chip sending Error message",
00517                               fParam->uNbFeets*2, -0.5, fParam->uNbFeets*2 -0.5, "Error Chip","Entries [1]");
00518       fGet4ErrorPatt = MakeTH2('I', "Feet/Messages/Get4ErrorPatt",
00519                               "Pattern of Get4 Error message",
00520                               fParam->uNbFeets*2, -0.5, fParam->uNbFeets*2 -0.5, 64, 0., 64.,
00521                               "Error chip","Error Pattern","Entries [1]");
00522       fGet4DataLoss = MakeTH1('I', "Feet/GET4/Dataloss", "Epochs with data Loss",
00523                               fParam->uNbFeets*2, -0.5, fParam->uNbFeets*2 -0.5,
00524                               "Get 4 Chip","Nb epochs with Loss [1]");
00525       fGet4EdgeMessagePerRawEvent = MakeTH2('I', "Feet/GET4/EdgePerRawEvt", "Nb of accepted edge message per event",
00526                               2000, -0.5, 2000 -0.5, fParam->uNbRocsGet4, 0, fParam->uNbRocsGet4,
00527                               "Nb accepted edge message [1]","Feet ROC ID [1]");
00528    if( kFALSE == fParam->NoGet4Cleaning )
00529    { // Remove all Cleaning related histograms
00530       fGet4NotValidMessRawEvent   = MakeTH2('I', "Feet/GET4/NotValidMessRawEvt",
00531                               "Nb of not validated accepted edge message per event",
00532                               2000, -0.5, 2000 -0.5, fParam->uNbRocsGet4, 0, fParam->uNbRocsGet4,
00533                               "Nb of not validated accepted edge message [1]","Feet ROC ID [1]");
00534 
00535       fMapEpochsRoc= MakeTH2( 'I', "Feet/Epochs/MapEpochsRoc",
00536             Form("Modulo %u of epoch counter value for Roc sync epoch messages",fParam->uSyncCycleSize),
00537             fParam->uNbFeets*2, -0.5, fParam->uNbFeets*2 -0.5, 30, -0.5, 29.5,
00538             "chip []", Form("Modulo %u of Epoch counter[]", fParam->uSyncCycleSize), "Counts []" );
00539       fMapEpochsLocal= MakeTH2( 'I', "Feet/Epochs/MapEpochsLocal",
00540             Form("Modulo %u of epoch counter value for local sync epoch messages", fParam->uSyncCycleSize),
00541             fParam->uNbFeets*2, -0.5, fParam->uNbFeets*2 -0.5, fParam->uSyncCycleSize, -0.5, fParam->uSyncCycleSize-0.5,
00542             "chip []", Form("Modulo %u of Epoch counter[]", fParam->uSyncCycleSize), "Counts []" );
00543       fMapEpochsMain= MakeTH2( 'I', "Feet/Epochs/MapEpochsMain",
00544             Form("Modulo %u of epoch counter value for 250MHz epoch messages", fParam->uMainSyncCycleSize),
00545             fParam->uNbFeets*2, -0.5, fParam->uNbFeets*2 -0.5,
00546             2*(fParam->uMainSyncCycleSize), -0.5, 2*(fParam->uMainSyncCycleSize)-0.5,
00547             "chip []", Form("Modulo %u of Epoch counter[]", fParam->uSyncCycleSize), "Counts []" );
00548       fDistribEpochsRoc= MakeTH2( 'I', "Feet/Epochs/DistribEpochsRoc",
00549             "Distribution of epoch counter value for Roc epoch messages",
00550             fParam->uNbFeets*2, -0.5, fParam->uNbFeets*2 -0.5, 1050, 0, 1050000,
00551             "chip []", "Value of Roc Epoch Cnt []", "Counts []" );
00552       fDistribEpochsLocal= MakeTH2( 'I', "Feet/Epochs/DistribEpochsLocal",
00553             "Distribution of epoch counter value for 250MHz epoch messages",
00554             fParam->uNbFeets*2, -0.5, fParam->uNbFeets*2 -0.5, 1050, 0, 1050000,
00555             "chip []", "Value of Local Epoch Cnt []", "Counts []" );
00556       fDistribEpochsMain= MakeTH1( 'I', "Feet/Epochs/DistribEpochsMain",
00557             "Distribution of epoch counter value for Local epoch messages",
00558             4100, 0, 4100,
00559             "Value of Local Epoch Cnt []", "Counts []" );
00560       fNbMissedSync= MakeTH2( 'I', "Feet/Epochs/NbMissedSync",
00561             "Distribution of missed sync nb per chip",
00562             fParam->uNbFeets*2, -0.5, fParam->uNbFeets*2 -0.5, 30, 0, 30,
00563             "chip []", "Nb of Missed Sync []", "Counts []" );
00564 
00565       fInterChipSyncEpochShift= MakeTH2( 'I', "Feet/Epochs/InterChipSyncEpochShift",
00566             "Inter chip epoch shift check",
00567             fParam->uNbFeets*2, -0.5, fParam->uNbFeets*2,
00568             10, -5.5, 4.5,
00569             "Chip [1]", "; Shift [1]" );
00570       fGet4RisEdgesNb = MakeTH1('I', "Feet/Get4EdgesCount/Raw/RawRisingEdgesNb",
00571                       "Number of Rising edges per channel",
00572                       fParam->uNbFeets * 8, -0.5, fParam->uNbFeets * 8 - 0.5,
00573                       "Channel [1]", "Entries [1]" );
00574       fGet4FalEdgesNb = MakeTH1('I', "Feet/Get4EdgesCount/Raw/RawFallingEdgesNb",
00575                       "Number of Falling edges per channel",
00576                       fParam->uNbFeets * 8, -0.5, fParam->uNbFeets * 8 - 0.5,
00577                       "Channel [1]", "Entries [1]" );
00578       fGet4EdgesDiffEvol= MakeTH2('I', "Feet/Get4EdgesCount/Raw/RawEdgesDiffEvol",
00579                       "diff ( nb falling - nb rising ) for each cycle/channel",
00580                       500, 0, 500, fParam->uNbFeets * 8, -0.5, fParam->uNbFeets * 8 - 0.5,
00581                       "Cycle []", "Chan []", "(Falling - Rising[1]" );
00582       fGet4RisEdgesEvol = MakeTH1('I', "Feet/Get4EdgesCount/Raw/RawRisingEdgesEvol",
00583                       "Number of Rising edges per cycle",
00584                       500, 0, 500, "Cycle []", "Edges [1]" );
00585       fGet4FalEdgesEvol = MakeTH1('I', "Feet/Get4EdgesCount/Raw/RawFallingEdgesEvol",
00586                       "Number of Falling edges per cycle",
00587                       500, 0, 500, "Cycle []", "Edges [1]" );
00588 
00589       } // if( kFALSE == fParam->NoGet4Cleaning)
00590    } // if ((fParam->uNbFeets>0) || (fParam->uNbRocsGet4>0))
00591 
00592    // Control over Automatic reset
00593    uIndexResetGet4 = 0; // AUTO reset
00594    /*************************************/
00595 
00596    setupmacro = "set_RocCond.C";
00597    // in standalone roc analysis, take name of condition setter macro from commandline arguments "-args -c mymacro.C"
00598    //JAM note that dynamic_cast would lead to linker problems here when working in full beamtime analysis
00599    if(TString(TGo4Analysis::Instance()->ClassName())=="TRocAnalysis") {
00600       TString usermacro = ((TRocAnalysis*)TGo4Analysis::Instance())->getUserConds();
00601       if (!usermacro.IsNull()) setupmacro = usermacro;
00602    }
00603 
00604    ExecuteScript(setupmacro.Data());
00605    
00606    ResetEndOfBuffer();
00607 }
00608 
00609 
00610 
00611 
00612 
00613 
00614 
00615 void TRocProc::ProcessTriggerMessage(TRocData* rocevent, int rocid, uint64_t fulltm)
00616 {
00617 //   if (fParam->noTrigger) return;
00618 
00619    // JAM: for multiaux mode: better only count the applied triggers, not all trigger messages
00620    // fTriggerPerRoc->Fill(rocid);
00621 
00622    if (!ROC[rocid].fHasNewTrigger) {
00623          // JAM avoid that trigger message on slave roc will override real master trigger!
00624          if((!fParam->globalTrigger) // local triggers are always taken
00625                ||
00626                (fParam->globalTrigger
00627                       &&  !fHasNewGlobalTrigger // any following trigger inside delta time window is ignored
00628                      && (((unsigned) rocid==fParam->masterRoc) || ROC[fParam->masterRoc].fHasNewTrigger)))
00629                      // only accept new trigger if we are the master, or if the master had a new trigger that is distributed to us
00630             {
00631 #ifdef DUMPMODE
00632          printf("Find trigger for roc %d\n", rocid); cout << endl;
00633 #endif
00634          fTriggerPerRoc->Fill(rocid);
00635          ROC[rocid].fLastTriggerTm = fulltm;
00636 #ifndef  ROC_SINGLETRIGGERMODE         
00637          if(!fParam->globalTrigger || (unsigned) rocid==fParam->masterRoc) // JAM only set trigger flag for master, slaves must be corrected by sync first!
00638 #endif
00639             ROC[rocid].fHasNewTrigger = kTRUE;
00640          ROC[rocid].fTriggersPerBuffer++;
00641          if (rocevent)
00642             rocevent->fLastTriggerTm = fulltm;
00643       }
00644  //  }
00645 #ifndef  ROC_SINGLETRIGGERMODE
00646 
00647    if ((unsigned) rocid==fParam->masterRoc) {
00648       fOutputEvent->fLastGlobalTriggerTm = fulltm;
00649       if (fParam->globalTrigger && !fHasNewGlobalTrigger) {
00650          if (!fFirstSubEvent) {
00651             TGo4Log::Error("Master trigger defined not in the first subevent - change ROC readout !!!");
00652             exit(1);
00653          }
00654          // JAM put here distribution of master trigger to slaves:
00655 #ifdef DUMPMODE
00656          cout <<"TTTTTTTTTTTTTTTTTTT ProcessTriggerMessage as master"<<rocid << endl;
00657 #endif
00658          // FIXME: SL: it is only for the case when many trigger in buffer are defined, not necessary in normal config
00659 
00660 
00661 
00662          // this alone will not work, because start sync time of slaves is not available here! is corrected at next slave sync.
00663          for (unsigned n = 0; n < fNumRocs; n++) {
00664             if (!AssertRoc(n))
00665                continue;
00666             if(n== (unsigned) rocid) continue;
00667             TRocData* reventn = dynamic_cast<TRocData*> (fOutputEvent->getEventElement(n));
00668             uint64_t triggertm(0);
00669             // TODO: reintroduce calibration coefficients
00670             if (ROC[rocid].fLastTriggerTm > ROC[rocid].fStartSyncTm)
00671                triggertm = ROC[n].fStartSyncTm
00672                      + (ROC[rocid].fLastTriggerTm - ROC[rocid].fStartSyncTm);
00673             else
00674                triggertm = ROC[n].fStartSyncTm
00675                      - (ROC[rocid].fStartSyncTm - ROC[rocid].fLastTriggerTm);
00676 #ifdef DUMPMODE
00677             cout <<"TTTTTTTTTTTTTTTTTTT ProcessTriggerMessage distributes triggertime "<< triggertm<<" to roc "<<n << endl;
00678             cout <<"      Master trigger: "<< ROC[rocid].fLastTriggerTm <<", Master Sync: "<< ROC[rocid].fStartSyncTm <<", Our Sync:"<<ROC[n].fStartSyncTm<< endl;
00679 #endif
00680             ProcessTriggerMessage(reventn, n, triggertm);
00681             if(ROC[rocid].fTriggersPerBuffer==1)
00682                ROC[n].fHasNewTrigger = kFALSE; // first trigger: mark slave trigger as not ready until we correct sync shifts
00683             else
00684                ROC[n].fHasNewTrigger = kTRUE; // for subsequent triggers, sync correction has already been done
00685          }
00686          fHasNewGlobalTrigger = kTRUE; // need to set this flag after slaves are set
00687       }
00688    }
00689 
00690 #endif
00691 
00692    if (ROC[rocid].fHasNewTrigger) {
00693       // reprocess unprocessed messages already here, do not let them go back to unprocessed
00694       HandleUnprocessedMessages(rocevent, rocid);
00695       } // if (ROC[rocid].fHasNewTrigger)
00696    } // if (!ROC[rocid].fHasNewTrigger)
00697 }
00698 
00699 
00700 void TRocProc::HandleUnprocessedMessages(TRocData* rocevent, int rocid)
00701 {
00702    for (unsigned i=0; i<ROC[rocid].fUnprocessedMsg.size(); i++) {
00703       ProcessExtendedMessage(rocid, rocevent, ROC[rocid].fUnprocessedMsg[i], false);
00704 //         if (rocid==0) {
00705 //            printf("Unproc ExMsg = %lu\n",ROC[rocid].fUnprocessedMsg[i].GetFullTime());
00706 //            ROC[rocid].fUnprocessedMsg[i].GetRocMessage().printData();
00707 //         }
00708    }
00709    ROC[rocid].fUnprocessedMsg.clear(); // is filled again from current event below
00710 
00711    // TEST: attempt to make get4 cleaning compatible with trigger selection
00712    if( kFALSE == fParam->NoGet4Cleaning && -1 != fParam->FindFeetRocId(rocid) )
00713    {
00714       for( unsigned int uChipCheck = 0; uChipCheck < fParam->uNbFeets*2; uChipCheck++)
00715       {
00716          if( fParam->uGet4Active[ uChipCheck ] )
00717             for( UInt_t uBuffer = 0; uBuffer < fParam->uNbBuffers; uBuffer ++ )
00718             {
00719                for (unsigned i=0; i<(FECHIP[uChipCheck].fCurrentUnprocessedMsg[uBuffer]).size(); i++)
00720                {
00721                   TRocMessageExtended mTemp = (FECHIP[uChipCheck].fCurrentUnprocessedMsg[uBuffer]).at(i);
00722                   if (fParam->noTrigger)
00723                   {
00724                      (FECHIP[uChipCheck].fCurrentEventMsg[ uBuffer ]).push_back(mTemp);
00725                   } // if (fParam->noTrigger)
00726                   else
00727                   {
00728                      Bool_t bAdd_to_event(kFALSE);
00729 
00730                      Double_t dDiff = 0.;
00731                      Bool_t bIsdiff = kFALSE;
00732 
00733                      if(mTemp.GetFullTime() >= ROC[rocid].fLastTriggerTm)
00734                         dDiff = mTemp.GetFullTime() - ROC[rocid].fLastTriggerTm;
00735                      else
00736                         dDiff = -1.0 * (ROC[rocid].fLastTriggerTm - mTemp.GetFullTime());
00737 
00738                      mTemp.SetTriggerDeltaT(dDiff);
00739 
00740                      bIsdiff = kTRUE;
00741 
00742                      TGo4WinCond* cond = fParam->globalTrigger ? fGlobalTriggerWind : ROC[rocid].fTriggerWind;
00743 
00744                      if (cond->Test(dDiff))
00745                      {
00746                         bAdd_to_event = kTRUE;
00747                      }
00748 
00749                      if (bIsdiff) {
00750                            fDeltaTriggerTime->Fill(dDiff);
00751                            ROC[rocid].fTrigger_AllNX->Fill(dDiff);
00752                            ROC[rocid].fTrigger_AllNX_100->Fill(dDiff);
00753 
00754                            unsigned g4 = mTemp.GetGet4Number();
00755                            if (ROC[rocid].fGet4Trigger[g4])
00756                               ROC[rocid].fGet4Trigger[g4]->Fill(dDiff);
00757                            if (ROC[rocid].fGet4Trigger100[g4])
00758                               ROC[rocid].fGet4Trigger100[g4]->Fill(dDiff);
00759                      }
00760 
00761                      if ( bAdd_to_event )
00762                      {
00763                         (FECHIP[uChipCheck].fCurrentEventMsg[ uBuffer ]).push_back(mTemp);
00764                      } // if ( bAdd_to_event )
00765                   } // else of if (fParam->noTrigger)
00766                } // for (unsigned i=0; i<(FECHIP[uChipCheck].fCurrentUnprocessedMsg[uBuffer]).size(); i++)
00767                (FECHIP[uChipCheck].fCurrentUnprocessedMsg[uBuffer]).clear();
00768             } // for( UInt_t uBuffer = 0; uBuffer < fParam->uNbBuffers; uBuffer ++ )
00769       } // for( unsigned int uChipCheck = 0; uChipCheck < fParam->uNbFeets*2; uChipCheck++)
00770       for( UInt_t uBuffer = 0; uBuffer < fParam->uNbBuffers; uBuffer ++ )
00771       {
00772          for (unsigned i=0; i<(vMessageInterBufferUnprocessed[uBuffer]).size(); i++)
00773          {
00774             TRocMessageExtended mTemp = (vMessageInterBufferUnprocessed[uBuffer]).at(i);
00775             if (fParam->noTrigger)
00776             {
00777                (vMessageInterBuffer[uBuffer]).push_back(mTemp);
00778             } // if (fParam->noTrigger)
00779             else
00780             {
00781                Bool_t bAdd_to_event(kFALSE);
00782 
00783                Double_t dDiff = 0.;
00784                Bool_t bIsdiff = kFALSE;
00785 
00786                if(mTemp.GetFullTime() >= ROC[rocid].fLastTriggerTm)
00787                   dDiff = mTemp.GetFullTime() - ROC[rocid].fLastTriggerTm;
00788                else
00789                   dDiff = -1.0 * (ROC[rocid].fLastTriggerTm - mTemp.GetFullTime());
00790 
00791                mTemp.SetTriggerDeltaT(dDiff);
00792 
00793                bIsdiff = kTRUE;
00794 
00795                TGo4WinCond* cond = fParam->globalTrigger ? fGlobalTriggerWind : ROC[rocid].fTriggerWind;
00796 
00797                if (cond->Test(dDiff))
00798                {
00799                   bAdd_to_event = kTRUE;
00800                }
00801 
00802                if (bIsdiff) {
00803                   fDeltaTriggerTime->Fill(dDiff);
00804                   ROC[rocid].fTrigger_AllNX->Fill(dDiff);
00805                   ROC[rocid].fTrigger_AllNX_100->Fill(dDiff);
00806 
00807                   unsigned g4 = mTemp.GetGet4Number();
00808                   if (ROC[rocid].fGet4Trigger[g4])
00809                      ROC[rocid].fGet4Trigger[g4]->Fill(dDiff);
00810                   if (ROC[rocid].fGet4Trigger100[g4])
00811                      ROC[rocid].fGet4Trigger100[g4]->Fill(dDiff);
00812                }
00813 
00814                if ( bAdd_to_event )
00815                {
00816                   (vMessageInterBuffer[uBuffer]).push_back(mTemp);
00817                }
00818             } // else of if (fParam->noTrigger)
00819          } // for (unsigned i=0; i<(vMessageInterBufferUnprocessed[uBuffer]).size(); i++)
00820          (vMessageInterBufferUnprocessed[uBuffer]).clear();
00821       } // for( UInt_t uBuffer = 0; uBuffer < fParam->uNbBuffers; uBuffer ++ )
00822       for (unsigned i=0; i<vUnprocessedMessages[rocid].size(); i++)
00823       {
00824          TRocMessageExtended mTemp = (vUnprocessedMessages[rocid]).at(i);
00825          if (fParam->noTrigger)
00826          {
00827             rocevent->fExtMessages.push_back(mTemp);
00828          } // if (fParam->noTrigger)
00829          else
00830          {
00831             Bool_t bAdd_to_event(kFALSE);
00832 
00833             Double_t dDiff = 0.;
00834             Bool_t bIsdiff = kFALSE;
00835 
00836             if(mTemp.GetFullTime() >= ROC[rocid].fLastTriggerTm)
00837                dDiff = mTemp.GetFullTime() - ROC[rocid].fLastTriggerTm;
00838             else
00839                dDiff = -1.0 * (ROC[rocid].fLastTriggerTm - mTemp.GetFullTime());
00840 
00841             mTemp.SetTriggerDeltaT(dDiff);
00842 
00843             bIsdiff = kTRUE;
00844 
00845             TGo4WinCond* cond = fParam->globalTrigger ? fGlobalTriggerWind : ROC[rocid].fTriggerWind;
00846 
00847             if (cond->Test(dDiff))
00848             {
00849                bAdd_to_event = kTRUE;
00850             }
00851 
00852             if (bIsdiff) {
00853                fDeltaTriggerTime->Fill(dDiff);
00854                ROC[rocid].fTrigger_AllNX->Fill(dDiff);
00855                ROC[rocid].fTrigger_AllNX_100->Fill(dDiff);
00856 
00857                unsigned g4 = mTemp.GetGet4Number();
00858                if (ROC[rocid].fGet4Trigger[g4])
00859                   ROC[rocid].fGet4Trigger[g4]->Fill(dDiff);
00860                if (ROC[rocid].fGet4Trigger100[g4])
00861                   ROC[rocid].fGet4Trigger100[g4]->Fill(dDiff);
00862             }
00863 
00864             if ( bAdd_to_event )
00865             {
00866                rocevent->fExtMessages.push_back(mTemp);
00867             }
00868          } // else of if (fParam->noTrigger)
00869       } // for (unsigned i=0; i<(vUnprocessedMessages[rocid]).size(); i++)
00870       (vUnprocessedMessages[rocid]).clear();
00871    } // if( kFALSE == fParam->NoGet4Cleaning )
00872 
00873 
00874 }
00875 
00876 
00877 
00878 
00879 void TRocProc::InitEvent(TGo4EventElement* outevnt)
00880 {
00881    // since output event object is never discarded within processor lifetime,
00882    // we just search for subevent by name once to speed up processing
00883    if(fOutputEvent==0)
00884    {
00885       // test if we are in beamtime or standalone mode:
00886       TCBMBeamtimeEvent* btevent=dynamic_cast<TCBMBeamtimeEvent*>(outevnt);
00887       if(btevent)
00888       {
00889 
00890          fOutputEvent=dynamic_cast<TRocEvent*>(btevent->GetSubEvent("ROC"));
00891       }
00892       else
00893       {
00894 
00895          fOutputEvent= dynamic_cast<TRocEvent*>(outevnt);
00896       }
00897       if(fOutputEvent==0)
00898       {
00899          GO4_STOP_ANALYSIS_MESSAGE("**** TRocProc: Fatal error: output event is not a TRocEvent!!! STOP GO4");
00900       }
00901    } // IF OUTPUTEVENT
00902 
00903    fFirstSubEvent = true;
00904 
00905 //   printf("Start event\n");
00906 }
00907 
00908 
00909 
00910 //-----------------------------------------------------------
00911 // event function
00912 void TRocProc::ProcessSubevent(TGo4MbsSubEvent* psubevt)
00913 {
00914    uint32_t nxid(0), g4id(0), g4ch(0), g4fl(0), nxch(0), nxadc(0), auxid(0), syncid(0);
00915    uint64_t fulltm(0);
00916    uint32_t typ(0), rocid(0);
00917    Double_t nxadc_corr = 0.;
00918    static int cnt=0;
00919    unsigned msgcount=0;
00920 #ifdef DUMPMODE
00921    static unsigned count=0;
00922    static unsigned bcount=0;
00923 #endif
00924 
00925    //cout << "#################### ProcessSubevent Start" << endl;
00926    bool is_dabc_evt = (psubevt->GetProcid() == roc::proc_RocEvent) ||
00927                       (psubevt->GetProcid() == roc::proc_ErrEvent) ||
00928                       (psubevt->GetProcid() == roc::proc_MergedEvent);
00929    bool is_raw_evt = (psubevt->GetProcid() == roc::proc_RawData);
00930 
00931    if (!is_dabc_evt && !is_raw_evt) return;
00932 
00933    // fIsTimeSorted = (psubevt->GetProcid() == roc::proc_MergedEvent);
00934 
00935 #ifdef   ROC_SINGLETRIGGERMODE
00936      fIsTimeSorted = kFALSE; // SL to avoid any mismatches, should be implemented anyway differently
00937 #else
00938      fIsTimeSorted = kTRUE; // JAM used for TEST!
00939 #endif
00940 
00941    if(cnt==0) {
00942       TGo4Log::Info("Multitriggermode: %s", fIsTimeSorted ? "true" : "false");
00943       cnt=1;
00944    }
00945 
00946 
00947    unsigned rid = psubevt->GetSubcrate();
00948 //   //     cout << "RocID = " << (int) psubevt->GetSubcrate() << "  data kind = " << (int) psubevt->GetProcid() << endl;
00949 //
00950    
00951    if (!AssertRoc(rid)) {
00952      // to see that messages are comming from the ROC
00953      fMsgsPerRoc->Fill(rid, (psubevt->GetDlen() - 2)/4);
00954      return;
00955    }
00956 
00957 
00958    
00959 //   printf("Process ROC event\n");
00960 
00961 // BEGIN INITIAL EVENT PART
00962    if(ROC[rid].fLoopsPerBuffer==0)
00963    {
00964 
00965 #ifdef DUMPMODE
00966       cout << "#################### ProcessSubevent rid:"<<rid<<" has new input event #"<< GetEventNumber() << endl;
00967 #endif
00968       int datasize = (psubevt->GetDlen() - 2) * 2;
00969       int msg_fmt = psubevt->GetControl();
00970       ROC[rid].fIter.setFormat(msg_fmt);
00971       ROC[rid].fIter.setRocNumber(rid);
00972 
00973 //      printf("ROCID %d datasize %d trigger %d\n", rid, datasize, GetTriggerNumber());
00974 
00975       // we can exclude messages (SYNC and may be EPOCH) which are added by DABC at the end of subevent
00976 
00978       if( kFALSE == fParam->NoGet4Cleaning )
00979       { // Remove all Cleaning related histograms
00980          if( -1 != fParam->FindFeetRocId( psubevt->GetSubcrate() ) )
00981          {
00982             Int_t iFeetRocIndex = fParam->FindFeetRocId( psubevt->GetSubcrate() );
00983             if(uNbEvents[iFeetRocIndex] == 0) {
00984                uFirstEventIndex[iFeetRocIndex] = GetEventNumber();
00985                // not needed but for safety, happen only once per run!
00986                for ( UInt_t uChip = 0; uChip < fParam->uNbFeets * 2; uChip++ )
00987                   FECHIP[uChip].bFirstEpochBlock = kTRUE;
00988                cout<<"***** First event on Get4 roc "<<iFeetRocIndex<<": "<<uFirstEventIndex[iFeetRocIndex]<<endl;
00989             } // if(uNbEvents[iFeetRocIndex] == 0)
00990             else {
00991                if( 0 < fParam->iEventNbGap &&
00992                    (Int_t)uPrevEventIndex[iFeetRocIndex] + fParam->iEventNbGap != GetEventNumber() ) {
00993                   Message(0, "***** Missing event in file for Get4 roc %d: Event %d, Previous event index %d, Current event Index %d, expected %d",
00994                         iFeetRocIndex, uNbEvents[iFeetRocIndex], uPrevEventIndex[iFeetRocIndex], GetEventNumber(),
00995                         (Int_t)uPrevEventIndex[iFeetRocIndex] + fParam->iEventNbGap);
00996                    for ( UInt_t uChip = 0; uChip < fParam->uNbFeets * 2; uChip++ )
00997                       FECHIP[uChip].bFirstSyncAfterEventJump = kTRUE;
00998                } // if not matching expected event gap
00999             } // else of if(uNbEvents[iFeetRocIndex] == 0)
01000             uPrevEventIndex[iFeetRocIndex]  = GetEventNumber();
01001             uNbEvents[iFeetRocIndex]++;
01002          } // if( -1 != fParam->FindFeetRocId( psubevt->GetSubcrate() ) )
01003       } // if( kFALSE == fParam->NoGet4Cleaning)
01004       /*************************************/
01005    
01006       if (is_dabc_evt) {
01007       
01008          // ignore all irrelevant events
01009          if (GetTriggerNumber()>8) return;
01010 
01011          roc::Message msg1, msg2;
01012 
01013          char* ptr = (char*) psubevt->GetDataField();
01014          int msglen = roc::Message::RawSize(msg_fmt);
01015 
01016          if (ROC[rid].fIter.assign(ptr + datasize - msglen, msglen)) {
01017             if (ROC[rid].fIter.next()) msg1.assign(ROC[rid].fIter.msg());
01018          }
01019 
01020          if (!msg1.isSyncMsg()) {
01021             TGo4Log::Error("Non-SYNC message at the end of DABC-produced subevent");
01022          } else {
01023             datasize -= msglen;
01024             int shift = msglen;
01025             while (shift<=datasize) {
01026 
01027                if (ROC[rid].fIter.assign(ptr + datasize - shift, msglen)) {
01028                   if (ROC[rid].fIter.next())
01029                      msg2.assign(ROC[rid].fIter.msg());
01030                   else
01031                      break;
01032 
01033                   if (msg2.isEpochMsg()) break;
01034                }
01035                shift+=msglen;
01036             }
01037             // exclude special epoch message for sync only
01038             if ((shift==msglen) && msg2.isEpochMsg()) datasize -= msglen;
01039          }
01040 
01041          // In special case when same sync message is used as trigger, we also can extend
01042          // our trigger analysis and exclude most messages from the consideration
01043 
01044          if (msg1.isSyncMsg() && msg2.isEpochMsg() && (msg1.getRocNumber()==msg2.getRocNumber())) {
01045             unsigned rocid = msg1.getRocNumber();
01046             if (rocid<fNumRocs) ROC[rocid].fStopSyncTm = msg1.getMsgFullTime(msg2.getEpochNumber());
01047          }
01048       }
01049 
01050       fTotaldatasize += datasize;
01051 
01052       if (!ROC[rid].fIter.assign(psubevt->GetDataField(), datasize)) return;
01053 
01054 
01055       //     cout << "nummsgs = " << datasize << "  len = " << datasize*6 << endl;
01056 
01057       fEvntSize->Fill(datasize);
01058 
01059       //cout << "AnlProc: found subevent subcrate="<<(int) psubevt->GetSubcrate()<<", procid="<<(int)psubevt->GetProcid()<<", control="<<(int) psubevt->GetControl()<< endl;
01060 
01061 #ifdef   ROC_SINGLETRIGGERMODE
01062       // first take over incomplete event messages from previous buffer:
01063       if (ROC[rid].fHasNewTrigger && !ROC[rid].fIsEventComplete &&
01064                (ROC[rid].fTmpMessages.size() > 0)) {
01065 
01066             //printf("Reassign messages to output event %u\n", ROC[rid].fTmpMessages.size());
01067             TRocData* devt = dynamic_cast<TRocData*> (fOutputEvent->getEventElement(rid));
01068 
01069             if (devt)
01070                devt->fExtMessages = ROC[rid].fTmpMessages;
01071 
01072             ROC[rid].fTmpMessages.clear();
01073          }
01074 #endif
01075 
01076 
01077       } // if !IsKeepInputEvent
01078 // END INITIAL EVENT PART
01079 
01080    ROC[rid].fLoopsPerBuffer++;
01081 
01082    uint32_t lastevrocid(0);
01083    TRocData* rocevent(0);
01084 
01085    roc::Message* data = & ROC[rid].fIter.msg();
01086 //   printf("Start loop for ROCID %d use nx0 %d use nx2 %d\n", rid, nx_use_mask[0], nx_use_mask[2]);
01087 
01088 
01089 
01090 
01091 
01092 
01093 
01094 
01095 #ifdef   ROC_SINGLETRIGGERMODE
01096     while (ROC[rid].fIter.next()) {
01097 #else
01098      bool hasmoredata=false;
01099      while (!ROC[rid].fIsEventComplete && (hasmoredata=ROC[rid].fIter.next())==true) {
01100       // JAM: only process messages if current event for this roc is not yet complete.
01101       // otherwise, we keep input buffer until we look for next event.
01102 #endif
01103       msgcount++;
01104       rocid = data->getRocNumber();
01105 
01106       fMsgsPerRoc->Fill(rocid);
01107       if ((rocid>=fNumRocs) || (ROC[rocid].fMsgTypes==0)) continue;
01108 
01109 
01110 
01111 
01112       ROC[rocid].fHasNewData = kTRUE;
01113 
01114       // SL: extract TRocData from composite event only when it necessary
01115       // in 99% of cases rocid is not changing and we do not search and dynamic_cast again
01116       if ((rocevent==0) || (lastevrocid!=rocid)) {
01117          rocevent = dynamic_cast<TRocData*> (fOutputEvent->getEventElement(rocid));
01118          lastevrocid = rocid;
01119          if (fParam->noTrigger && fParam->doSorting) {
01120             // reprocess unprocessed messages already here, do not let them go back to unprocessed
01121             // do it only when sorting was requested, otherwise unprocessed should not exists at all
01122             for (unsigned i=0; i<ROC[rocid].fUnprocessedMsg.size(); i++)
01123                ProcessExtendedMessage(rocid, rocevent, ROC[rocid].fUnprocessedMsg[i], false);
01124             ROC[rocid].fUnprocessedMsg.clear(); // is filled again from current event below
01125          }
01126       }
01127 
01128 
01129 #ifndef   ROC_SINGLETRIGGERMODE
01130       // JAM special case: last event was closed by aux trigger itself, needs to be assigned:
01131       if (!fParam->globalTrigger || rocid == fParam->masterRoc) {
01132          if (msgcount > 2 && !ROC[rocid].fHasNewTrigger
01133                && ROC[rocid].fUnprocessedMsg.size() > 0) {
01134 //            cout << "uuuuuuuuuuuuuu Unprocessed roc:" << rocid
01135 //                  << " with entries" << ROC[rocid].fUnprocessedMsg.size()
01136 //                  << endl;
01137             if (ROC[rocid].fUnprocessedMsg[0].GetMessageType()
01138                   == roc::MSG_AUX) {
01139                int auxid =
01140                      ROC[rocid].fUnprocessedMsg[0].GetRocMessage().getAuxChNum();
01141                if (fParam->triggerSignal == (int) auxid) {
01142                   uint64_t trigtm = ROC[rocid].fUnprocessedMsg[0].GetFullTime();
01143 #ifdef DUMPMODE
01144                   cout << "Found previous trig MSG- ROC:" << rocid << ", auxid:"
01145                         << auxid << ", cnt:" << msgcount << endl;
01146 #endif
01147                   ProcessTriggerMessage(rocevent, rocid, trigtm); // will invoke processextended msg of unprocessed
01148                }
01149             }
01150 
01151          }
01152       }
01153 #endif
01154 
01155       /*************************************/
01156 
01157       typ = data->getMessageType();
01158       //cout << "MSG- ROC:"<<rocid << ", typ:" <<typ<<", cnt:"<<msgcount<< endl;
01159 #ifdef DUMPALLMESSAGES
01160       data->printData(roc::msg_print_Human | roc::msg_print_Prefix);
01161 #endif
01162 
01163       double msgtm = 0.;
01164 
01165       if(typ==roc::MSG_GET4) {
01166          fulltm = data->getMsgFullTime(ROC[rocid].fLastEpoch2[data->getGet4Number()]);
01167          msgtm = (fulltm % 20000000000000LLU)*1e-9;
01168       } else {
01169          fulltm = data->getMsgFullTime(ROC[rocid].fCurrEpoch);
01170          msgtm = (fulltm % 1000000000000LLU)*1e-9;
01171       }
01172 
01173       ROC[rocid].fMsgTypes->Fill(typ);
01174       ROC[rocid].fALLt->Fill(msgtm);
01175 
01176       TRocMessageExtended exmess(*data,fulltm);
01177 
01178       if (fParam->baselineCalibr && fParam->dynamicPedestal ) {
01179          Bool_t extTrigHit = kFALSE;
01180          if (typ == roc::MSG_HIT) {
01181             if (fParam->ttriMode[rocid][data->getNxNumber()]) {
01182                extTrigHit = kTRUE;
01183             }
01184          }
01185          if (extTrigHit) {
01186             fPedestals->ExtractExttrigStream(*data, fulltm);
01187          } else {
01188             fPedestals->ExtractAutocalibrStream(*data, fulltm);
01189          }
01190       }
01191 
01192       switch (typ)
01193       {
01194          case roc::MSG_NOP:
01195             break;
01196 
01197          case roc::MSG_HIT: {
01198             nxid = data->getNxNumber();
01199             nxch = data->getNxChNum();
01200             nxadc = data->getNxAdcValue();
01201 
01202             if ((nxid >= MAX_NX) || !nx_use_mask[nxid])
01203                continue;
01204 
01205 
01206             Bool_t data_hit(kTRUE), ped_hit(kFALSE);
01207 
01208             if( fParam->baselineCalibr && fParam->dynamicPedestal ) {
01209                 if( fParam->ttriMode[rocid][nxid] ) {
01210                     if( fParam->dynamicPedestal ) {
01211                         data_hit = kTRUE;
01212                         ped_hit = kTRUE;
01213                     } else {
01214                         data_hit = kTRUE;
01215                         ped_hit = kFALSE;
01216                     }
01217                 } else {
01218                     switch (fPedestals->GetState(rocid)) {
01219                         case roc::SYSMSG_USER_CALIBR_OFF:
01220                             data_hit = kTRUE;
01221                             ped_hit = kFALSE;
01222                             break;
01223                         case roc::SYSMSG_USER_CALIBR_ON:
01224                             data_hit = kFALSE;
01225                             ped_hit = kTRUE;
01226                             break;
01227                         default: // roc::SYSMSG_USER_RECONFIGURE:
01228                             data_hit = kFALSE;
01229                             ped_hit = kFALSE;
01230                             break;
01231                     }
01232                 }
01233             }
01234 
01235 //            if (!data_hit && !ped_hit) printf("Undefined hit\n");
01236 //                                 else printf("--------------- Usual hit --------------\n");
01237 
01238             if( data_hit ) {
01239                ROC[rocid].fNxTm[nxid][nxch] = fulltm;
01240 
01241                ROC[rocid].fHITt[nxid]->Fill(msgtm);
01242 
01243                if (fParam->nxDiffCh >= 0)
01244                {
01245                   if (nxch == (unsigned) fParam->nxDiffCh)
01246                   {
01247                      for (int ndiff = 0; ndiff < NUM_DIFFS; ndiff++)
01248                      {
01249                         int ch2 = ndiff * (MOD_DIFFS + 1) + MOD_DIFFS;
01250                         double diff = 0.
01251                               + ROC[rocid].fNxTm[nxid][fParam->nxDiffCh]
01252                                                        - ROC[rocid].fNxTm[nxid][ch2];
01253                         if (TMath::Abs(diff) < 1e4)
01254                            ROC[rocid].fTmDiff[nxid][ndiff]->Fill(diff);
01255                      }
01256                   }
01257 
01258                   if (nxch % (MOD_DIFFS + 1) == MOD_DIFFS)
01259                   {
01260                      int ndiff = nxch / (MOD_DIFFS + 1);
01261                      double diff = 0. + ROC[rocid].fNxTm[nxid][fParam->nxDiffCh]
01262                                                             - ROC[rocid].fNxTm[nxid][nxch];
01263                      if (TMath::Abs(diff) < 1e4)
01264                         ROC[rocid].fTmDiff[nxid][ndiff]->Fill(diff);
01265                   }
01266                }
01267 
01268                ROC[rocid].fChs[nxid]->Fill(nxch);
01269                ROC[rocid].fADCs[nxid]->Fill(nxch, nxadc);
01270                if (fParam->baselineCalibr) {
01271                   nxadc_corr = fPedestals->GetPedestal(rocid, nxid, nxch) - nxadc;
01272                   ROC[rocid].fADCs_wo_baseline[nxid]->Fill(nxch, nxadc_corr);
01273                }
01274                else {
01275                   nxadc_corr = 4095 - nxadc;
01276                }
01277                ProcessNxHit(data, nxadc_corr);
01278                // pass message data over to output event
01279                exmess.SetCorrectedNxADC(nxadc_corr);
01280                ProcessExtendedMessage(rocid, rocevent, exmess);
01281             }
01282 
01283             if( ped_hit ) {
01284                 ROC[rocid].fBaseline[nxid]->Fill(nxch, nxadc);
01285             }
01286 
01287             break;
01288          }
01289 
01290          case roc::MSG_GET4:
01291              if (ROC[rocid].bIgnoreData) continue;
01292 
01293              g4id = data->getGet4Number();
01294              g4ch = data->getGet4ChNum();
01295              g4fl = data->getGet4Edge();
01296              
01297              ROC[rocid].fLastGet4Tm[g4id][g4ch][g4fl] = fulltm;
01298 
01299              if (ROC[rocid].fGet4Chips)
01300                 ROC[rocid].fGet4Chips->Fill(g4id);
01301 
01302              if (ROC[rocid].fGet4Tm[g4id])
01303                 ROC[rocid].fGet4Tm[g4id]->Fill(data->getGet4Ts()/20.);
01304              
01305              if (ROC[rocid].fGet4Channels[g4id])
01306                 ROC[rocid].fGet4Channels[g4id]->Fill(g4ch*2 + g4fl);
01307 
01308              if (ROC[rocid].fGet4TmCh[g4id][g4ch][g4fl])
01309                 ROC[rocid].fGet4TmCh[g4id][g4ch][g4fl]->Fill(data->getGet4Ts()/20.);
01310 
01311              ROC[rocid].fGet4ChCnt[g4id][g4ch][g4fl]++;
01312 
01313                 // reset counter when changing sign
01314                 if ((ROC[rocid].fGet4EdgeCnt[g4id][g4ch]>0) ^ g4fl) {
01315 
01316                    // calculate difference to last time of different edge
01317                    uint64_t diff2 = fulltm - ROC[rocid].fLastGet4Tm[g4id][g4ch][1-g4fl];
01318 
01319                    // printf("diff2 = %llu\n", diff2);
01320 
01321                    // lets define interval of +-500 ns around full epoch and test three epochs
01322                    bool suspicios = false;
01323                    for (unsigned k=1;k<4;k++)
01324                       if ((diff2 > (k*26214 - 500)) && (diff2 < (k*26214 + 500))) suspicios = true;
01325 
01326                    ROC[rocid].fGet4ChangeCnt[g4id][g4ch]++;
01327                    if (suspicios) ROC[rocid].fGet4SuspiciousCnt[g4id][g4ch]++;
01328 
01329                    ROC[rocid].fGet4EdgeCnt[g4id][g4ch] = 0;
01330                 }
01331 
01332               ROC[rocid].fGet4EdgeCnt[g4id][g4ch] += (g4fl ? +1 : -1);
01333 
01334               if (abs(ROC[rocid].fGet4EdgeCnt[g4id][g4ch])>3) {
01335                  // printout only several first errors
01336                  if (++ROC[rocid].fGet4ErrCnt[g4id][g4ch]<4)
01337                     if (fParam->bGet4Debug)
01338                        printf("**** GET4 EDGE error on roc:%u Get4:%u ch:%u epoch2:%u edgecnt:%d ****\n", rocid, g4id, g4ch, ROC[rocid].fLastEpoch2[g4id], ROC[rocid].fGet4EdgeCnt[g4id][g4ch]);
01339               }
01340 
01341              if (ROC[rocid].fGet4DiffSync[g4id]) {
01342                 uint64_t ff = roc::Message::FullTimeStamp2(ROC[rocid].fLastEpoch2[g4id] - ROC[rocid].fLastEpoch2Sync[g4id],  data->getGet4Ts());
01343 
01344                 ROC[rocid].fGet4DiffSync[g4id]->Fill(ff/20.);
01345              }
01346 
01347              // a GET4 Data event
01348              if( kTRUE == fParam->NoGet4Cleaning) {
01349                 exmess.SetRocEpoch(ROC[rocid].fLastEpoch2[data->getGet4Number()]);
01350                 ProcessExtendedMessage(rocid, rocevent, exmess);
01351              } else
01352                 ProcessGet4DataMessage(rocid, fParam->DefineGet4IndexOffset(rocid), data);
01353 
01354              break;
01355 
01356          case roc::MSG_EPOCH:
01357             ROC[rocid].fCurrEpoch = data->getEpochNumber();
01358             //ProcessExtendedMessage(rocid, rocevent, exmess); // NOT anymore used for closing condition of event JAM
01359             
01361             if( kFALSE == fParam->NoGet4Cleaning )
01362             { // Remove all Cleaning related histograms
01363                if( uLastEpochMainClock > data->getEpochNumber() )
01364                   uMainEpochCycle++;
01365                uLastEpochMainClock = data->getEpochNumber();
01366                if (fDistribEpochsMain) fDistribEpochsMain->Fill(uLastEpochMainClock);
01367                for ( unsigned int uChip = 0; uChip < fParam->uNbFeets * 2; uChip++ )
01368                   (FECHIP[uChip].uEpochMainClockSinceLastSync)++; // Main 250MHz clock epoch counter
01369             } // if( kFALSE == fParam->NoGet4Cleaning)
01370       /************************************/
01371             break;
01372 
01373          case roc::MSG_EPOCH2:
01374             g4id = data->getEpoch2ChipNumber();
01375 
01376             ROC[rocid].ProcessEpoch2(g4id, data->getEpoch2Number(), data->getEpoch2Sync(), fParam->bGet4Debug);
01377 
01378             // disable ignore of input data after two epoch2 with sync
01379             if (ROC[rocid].bIgnoreData) {
01380                if (data->getEpoch2Sync() && (++ROC[rocid].fIgnoreCnt > 1)) {
01381                   ROC[rocid].bIgnoreData = false;
01382                   if (fParam->bGet4Debug)
01383                      printf("Enable analysis for roc %d again after two epoch2 with sync epoch2:%u fulltm = %10.6f\n", rocid, data->getEpoch2Number(), fulltm*1e-9);
01384                }
01385             }
01386 
01388             // MSG_EPOCH2 describes a GET4 epoch events caused by a 4096 clock
01389             // cycle epoch of the 156.25 MHz clock.
01390             if( kFALSE == fParam->NoGet4Cleaning )
01391                ProcessGet4EpochMessage(rocid, rocevent, fParam->DefineGet4IndexOffset(rocid), data);
01392             /************************************/
01393             break;
01394 
01395          case roc::MSG_SYNC:
01396             syncid = data->getSyncChNum();
01397             if (syncid < MAX_SYNC)  {
01398                ROC[rocid].fLastSyncTm[syncid] = fulltm;
01399                ROC[rocid].fLastSyncId[syncid] = data->getSyncData();
01400                if (rocevent)
01401                   rocevent->fLastSyncTm[syncid] = fulltm;
01402                ROC[rocid].fSYNCt[syncid]->Fill(msgtm);
01403 
01404 
01405             if((msgcount<3) && !is_raw_evt) {
01406                //cout << "Sync message for roc "<<rocid << ", msgcount:" <<msgcount<<", time:"<<fulltm<< endl;
01407 #ifndef ROC_SINGLETRIGGERMODE
01408                uint64_t oldstartsynctm=ROC[rocid].fStartSyncTm;
01409 //               if(rocid==0)
01410 //               {
01412 //
01413 //                  //cout << "Sync: fulltm:"<<fulltm << ", synctm:" <<synctm<<", oldfulltime:"<<oldstartsynctm<< endl;
01419 //               }
01420 #endif
01421                ROC[rocid].fStartSyncTm = fulltm;
01422                ROC[rocid].fDabcSeparator = data->getSyncChNum()+10;
01423 
01424 
01425                unsigned mrocid = fParam->masterRoc;
01426                // try to reintroduce trigger message in local time
01427                if (AssertRoc(mrocid) && (rocid!=mrocid) && ROC[mrocid].fHasNewTrigger) {
01428 #ifdef ROC_SINGLETRIGGERMODE
01429                   uint64_t triggertm(0);
01430 
01431                   // TODO: reintroduce calibration coefficients
01432                   if (ROC[mrocid].fLastTriggerTm > ROC[mrocid].fStartSyncTm)
01433                      triggertm = ROC[rocid].fStartSyncTm + (ROC[mrocid].fLastTriggerTm - ROC[mrocid].fStartSyncTm);
01434                   else
01435                      triggertm = ROC[rocid].fStartSyncTm - (ROC[mrocid].fStartSyncTm - ROC[mrocid].fLastTriggerTm);
01436 
01437                   ProcessTriggerMessage(rocevent, rocid, triggertm);
01438 #else
01439                   // JAM in multiple trigger mode, we still have to correct the trigger times as distributed from master,
01440                   // because for first trigger they were related to previous start sync time:
01441 
01442                   if(fParam->globalTrigger && fHasNewGlobalTrigger &&  !ROC[rocid].fHasNewTrigger)
01443                   {
01444                       //JAM FIXME: this will fail if we have intermediate buffers without any events on slave stream!
01445                      ROC[rocid].fLastTriggerTm=ROC[rocid].fLastTriggerTm + ROC[rocid].fStartSyncTm - oldstartsynctm;
01446                      ROC[rocid].fHasNewTrigger=kTRUE; // JAM this flag avoids that we destroy correct trigger time when time window overlaps with end of buffer
01447                      HandleUnprocessedMessages(rocevent, rocid); // need to care for unprocessed that were ignored in ProcessTriggerMessage before our correction JAM
01448 #ifdef DUMPMODE
01449                      cout <<"TTTTTTTTTTTTTTTTTTT Process Subevent corrects slave trigger time"<< ROC[rocid].fLastTriggerTm<<" for roc "<<rocid<<", SHIFT="<< ROC[rocid].fStartSyncTm - oldstartsynctm << endl;
01450 #endif
01451                   }
01452 #endif
01453                } // AssertRoc
01454 
01455 
01456 
01457 
01458 
01459 
01460             }
01461 
01462             if (fParam->triggerSignal == (int) (syncid + 10)) // then may use it for new trigger
01463                ProcessTriggerMessage(rocevent, rocid, fulltm);
01464 
01465             ProcessExtendedMessage(rocid, rocevent, exmess);
01466 
01467             } // if < MAXSYNC
01468             break;
01469 
01470          case roc::MSG_AUX:
01471             auxid = data->getAuxChNum();
01472             ROC[rocid].fAUXch->Fill(auxid);
01473 
01474             //printf ("ROC%d get AUX%d\n", rocid, auxid);
01475 
01476             if (auxid < MAX_AUX) {
01477                ROC[rocid].fLastAuxTm[auxid] = fulltm;
01478                ROC[rocid].fAUXt[auxid]->Fill(msgtm);
01479             }
01480 
01481             if (fParam->triggerSignal == (int) auxid) {
01482                 ProcessTriggerMessage(rocevent, rocid, fulltm);
01483 #ifdef DUMPMODE
01484                 if (rocid==0) printf("AUX msg = %lu\n", fulltm);
01485 #endif
01486             }
01487             ProcessExtendedMessage(rocid, rocevent, exmess);
01488             break;
01489 
01490          case roc::MSG_SYS:
01491             ROC[rocid].fSysTypes->Fill(data->getSysMesType());
01492 
01493             if (data->getSysMesType() == roc::SYSMSG_USER)
01494             {
01495                ROC[rocid].fSysUserTypes->Fill(data->getSysMesData());
01496 
01497                switch (data->getSysMesData())
01498                {
01499                   case roc::SYSMSG_USER_CALIBR_ON:
01500                      ROC[rocid].bIgnoreData = kFALSE;
01501 
01502                      break;
01503                   case roc::SYSMSG_USER_CALIBR_OFF:
01504                      ROC[rocid].bIgnoreData = kFALSE;
01505 
01506                      break;
01507                   case roc::SYSMSG_USER_RECONFIGURE:
01508                      ROC[rocid].bIgnoreData = kTRUE;
01509                      ROC[rocid].fIgnoreCnt = 0;
01510                      ROC[rocid].fIgnoreTime = fulltm;
01512                      if( kFALSE == fParam->NoGet4Cleaning && 0< fParam->uNbBlockJumpedReset)
01513                      { // Remove all Cleaning related histograms
01514                         for ( UInt_t uChip = 0; uChip < fParam->uNbFeets * 2; uChip++ )
01515                         {
01516                            FECHIP[uChip].bJumpEpochBlockAfterReset = kTRUE;
01517                            FECHIP[uChip].uNbEpochBlockAfterReset = 0;
01518                         }
01519                         uEpochFirstSyncAfterReset = 0;
01520                         uCycleFirstSyncAfterReset = 0;
01521                      } // if( kFALSE == fParam->NoGet4Cleaning)
01522 
01523                      uIndexResetGet4 ++; // AUTO reset
01524                      /*************************************/
01525                      break;
01526 
01527                   default:
01528                      // forward all other kinds to next step
01529                      ProcessExtendedMessage(rocid, rocevent, exmess);
01530                      break;
01531                } // switch (data->getSysMesData())
01532             } // if (data->getSysMesType() == roc::SYSMSG_USER)
01533             else if (data->getSysMesType() == roc::SYSMSG_ADC)
01534             {
01535                int febid = (data->getSysMesData() >> 31) & 1;
01536                int nch = (data->getSysMesData() >> 24) & 0x7f;
01537                int val = data->getSysMesData() & 0xffff;
01538                ROC[rocid].fFebADC[febid]->SetBinContent(nch + 1, val);
01539 
01540                ProcessExtendedMessage(rocid, rocevent, exmess);
01541             }
01543             else if( data->getSysMesType() == roc::SYSMSG_GET4_EVENT )
01544             {
01545                UInt_t uGet4SysMessType = (data->getSysMesData()>>6) & 0x1;
01546                // Get4 system message types histogram
01547                if (ROC[rocid].fGet4SysTypes)
01548                   ROC[rocid].fGet4SysTypes->Fill(uGet4SysMessType);
01549 
01550                UInt_t uGet4IndexOffset = fParam->DefineGet4IndexOffset(rocid);
01551 
01552                if(uGet4SysMessType)
01553                {
01554                   // Get4 system message type = Sync
01555                   if( kFALSE == fParam->NoGet4Cleaning)
01556                      if( kFALSE == ProcessGet4ExtSyncMessage( uGet4IndexOffset, data) )
01557                         continue;
01558                } // if(uGet4SysMessType)
01559                else
01560                {
01561                   // Get4 system message type = Error
01562                   UInt_t uChip = data->getField(40, 8) + uGet4IndexOffset;
01563 
01564                   // Remap the Get4 chip index
01565                   uChip = fParam->RemapGet4Chip(uChip);
01566 
01567                   if (!fParam->IsValidGet4Chip(uChip)) {
01568                       cout << "Error: Bad chip nb in Epoch message = " << uChip << endl;
01569                       cout << " => This message will be skipped!!!! "<<endl;
01570                       continue;
01571                   }
01572 
01573                   // SL: FIXME: is it required, message has different format here??
01574                   data->setGet4Number(uChip);
01575 
01576                   fGet4ErrorChip->Fill( uChip );
01577                   fGet4ErrorPatt->Fill(uChip, (data->getSysMesData()) & 0x3f);
01578                } // else of if(uGet4SysMessType)
01579             } // if( data->getSysMesType() == roc::SYSMSG_GET4_EVENT )
01580             break;
01581       /*************************************/      
01582       } // switch
01583 
01584       // in strict timesorting mode, we may find end of event before processing whole
01585       // input buffer:
01586       if(fIsTimeSorted)
01587       {
01588          if(ROC[rid].fIsEventComplete)
01589             {
01590                //cout <<"STRICT Timesorting mode finds complete event for rocid:"<< rid <<endl;//<<", keep mbs input!" << endl;
01591                break; // do not stop processing this buffer until we have next trigger!
01592             }
01593       }
01594 
01595 
01596     } // while
01597 
01598 
01599 // JAM FIXME: rule single/multitriggermode with parameter, not compiler flags!
01600    if(fIsTimeSorted)
01601       {
01602 #ifndef ROC_SINGLETRIGGERMODE
01603 #if __GO4BUILDVERSION__ > 40500
01604       ROC[rid].fHasEndOfBuffer=!hasmoredata;
01605 #endif
01606 #endif
01607       }
01608    //  cout << "Stop processing" << endl;
01609 
01610    fFirstSubEvent = kFALSE;
01611 }
01612 
01613 
01614 
01615 void TRocProc::FinalizeEvent()
01616 {
01617 
01618 #ifdef DUMPMODE
01619     static unsigned count=0;
01620     static unsigned bcount=0;
01621 #endif
01622 
01623    fOutputEvent->fMbsEventNumber = GetEventNumber();
01624    // now we should decide if event should be delivered to the output
01625    // either all used ROCs are ready with their events or sync is used as trigger
01626 
01627    bool allEventComplete(true), isAnyData(false), isAllSyncSepar(true), allInputsComplete(true);
01628 
01629    if ((fAUX2_R01!=0) && AssertRoc(0) && AssertRoc(1) &&
01630        (ROC[0].fLastAuxTm[2] > ROC[0].fStartSyncTm) &&
01631        (ROC[1].fLastAuxTm[2] > ROC[1].fStartSyncTm)) {
01632       int diff0 = ROC[0].fLastAuxTm[2] - ROC[0].fStartSyncTm;
01633       int diff1 = ROC[1].fLastAuxTm[2] - ROC[1].fStartSyncTm;
01634 
01635       fAUX2_R01->Fill(diff0-diff1);
01636 
01637 //      printf ("%5d   %5d %5d\n", diff0-diff1, diff0, diff1);
01638    }
01639 
01640    if (fSYNC_R0_R10 && AssertRoc(0) && AssertRoc(10)) {
01641       double diff = ROC[0].fLastSyncTm[1] - ROC[10].fLastSyncTm[0];
01642       double iddiff = 0. + ROC[0].fLastSyncId[1] - ROC[10].fLastSyncId[0];
01643       
01644       if (iddiff != 0) printf("iddiff = %5.0f\n", iddiff);
01645       
01646       fSYNC_R0_R10->Fill(diff);
01647    }
01648 
01649    for (unsigned r=0; r<fNumRocs;r++) {
01650       if (!AssertRoc(r)) continue;
01651       TRocData* theRoc = dynamic_cast<TRocData*>(fOutputEvent->getEventElement(r));
01652       if(theRoc==0) continue;
01653       
01654 #ifdef ROC_SINGLETRIGGERMODE
01655       // protection against producing too large history in unprocessed messages in case when AUX used as trigger
01656       // WORKAROUND - should be done more correctly
01657        if ((fParam->triggerSignal>=0) && (fParam->triggerSignal<10))
01658           ROC[r].fUnprocessedMsg.clear(); 
01659 #endif
01660 
01661       if( (theRoc->fExtMessages.size() > 0) || (theRoc->vMessageEventBuffer.size() > 0))
01662          isAnyData = true;
01663       /*************************************/
01664 
01665 
01666 #ifdef ROC_SINGLETRIGGERMODE
01667       if (!ROC[r].fIsEventComplete && ROC[r].fHasNewTrigger && (ROC[r].fStopSyncTm > ROC[r].fStartSyncTm) && 
01668             (ROC[r].fStopSyncTm > ROC[r].fLastTriggerTm)) {
01669          double diff = ROC[r].fStopSyncTm - ROC[r].fLastTriggerTm;
01670 
01671          TGo4WinCond* cond = fParam->globalTrigger ? fGlobalTriggerWind : ROC[r].fTriggerWind;
01672 
01673          double rightdist = diff - cond->GetXUp();
01674          
01675          //printf ("ROC%d rightdist %5.1f\n", r, rightdist);
01676          // if hit far away on right side, event can be close for this ROC
01677          if (rightdist > 5000.) ROC[r].fIsEventComplete = kTRUE;
01678       }
01679 #endif
01680       // we only care about incomplete event if any data at all seen by the ROC!
01681       if(!ROC[r].fIsEventComplete && ROC[r].fHasNewData) allEventComplete = false;
01682       if (ROC[r].fDabcSeparator != fParam->triggerSignal) isAllSyncSepar = false;
01683 
01684 #ifdef DUMPMODE
01685       printf("ROC%d event complete = %d\n", r, ROC[r].fIsEventComplete);
01686 #endif
01687 
01688       // multi trigger mode: we only keep current input buffer
01689       // if we have any data, we are not at the end of buffer and below the break counter conditions
01690       if( (ROC[r].fHasNewData) && (!ROC[r].fHasEndOfBuffer)
01691             && (ROC[r].fTriggersPerBuffer<=fParam->maxBufferTriggers)
01692             && (ROC[r].fLoopsPerBuffer<=fParam->maxBufferLoops))
01693          {
01694             allInputsComplete = false;
01695          }
01696 
01697 #ifdef DUMPMODE
01698       printf("ROC%d buffer complete = %d, has new data: %d\n", r, ROC[r].fHasEndOfBuffer, ROC[r].fHasNewData);
01699 #endif
01700 //
01701 //      if (ROC[r].fTriggersPerBuffer > fParam->maxBufferTriggers) {
01702 //         printf("ROC%d # of triggers %d per buffer exceeds %d \n", r,
01703 //               ROC[r].fTriggersPerBuffer, (int) fParam->maxBufferTriggers);
01704 //         cout << endl;
01705 //      }
01706 //      if (ROC[r].fLoopsPerBuffer > fParam->maxBufferLoops) {
01707 //         printf("ROC%d # of loops %d per buffer exceeds %d\n", r,
01708 //               ROC[r].fLoopsPerBuffer, (int) fParam->maxBufferLoops);
01709 //         cout << endl;
01710 //      }
01711 
01712    } // for r
01713 
01714    if (fParam->noTrigger && isAnyData) allEventComplete = true;
01715    if (isAllSyncSepar) allEventComplete = true;
01716 
01717 
01718 
01719    if (allEventComplete) {
01720 #ifdef DUMPMODE
01721       printf("!!!!!!!!! Event %d is complete !!!!!!!!!\n",count++);
01722 #endif
01723       for (unsigned rocid=0; rocid<fNumRocs;rocid++) {
01724          TRocData* theRoc = dynamic_cast<TRocData*>(fOutputEvent->getEventElement(rocid));
01725          if(theRoc==0) continue;
01726 
01727 //#ifndef   ROC_SINGLETRIGGERMODE
01728       // take over incomplete event messages from previous buffe no sooner than we have completed eventr:
01729       // this is important if between trigger and closing message are several mbs buffers JAM
01730       if (ROC[rocid].fTmpMessages.size() > 0) {
01731 #ifdef DUMPMODE
01732             printf("Event is complete- Insert leftover messages of roc %d to output event %u\n", rocid, ROC[rocid].fTmpMessages.size());
01733 #endif
01734             theRoc->fExtMessages.insert (theRoc->fExtMessages.end(),ROC[rocid].fTmpMessages.begin(),ROC[rocid].fTmpMessages.end());
01735             ROC[rocid].fTmpMessages.clear();
01736          }
01737 //#endif
01738 
01739 
01740 
01742          Int_t iFeetRocId = fParam->FindFeetRocId(rocid);
01743          if( -1 != iFeetRocId)
01744          {
01745             // Histogram of edge messages/event
01746             if( kTRUE == fParam->noTrigger )
01747                fGet4EdgeMessagePerRawEvent->Fill( (theRoc->vMessageEventBuffer).size(), iFeetRocId );
01748                else if( kFALSE == fParam->NoGet4Cleaning )
01749                {
01750                   UInt_t uTotalUnvalidatedMessAccepted = 0;
01751                   // UInt_t uInitialOutputSize = theRoc->fExtMessages.size();
01752                   for( UInt_t uBuffer = 0; uBuffer < fParam->uNbBuffers; uBuffer ++ )
01753                   {
01754                      uTotalUnvalidatedMessAccepted += vMessageInterBuffer[ uBuffer ].size();
01755                      theRoc->fExtMessages.insert( theRoc->fExtMessages.end(),
01756                                        vMessageInterBuffer[ uBuffer ].begin(),
01757                                        vMessageInterBuffer[ uBuffer ].end() );
01758                      vMessageInterBuffer[ uBuffer ].clear();
01759                   } // for( UInt_t uBuffer = 0; uBuffer < fParam->uNbBuffers; uBuffer ++ )
01760 
01761                   for( unsigned int uChipCheck = 0; uChipCheck < fParam->uNbFeets*2; uChipCheck++)
01762                   {
01763                      FECHIP[uChipCheck].uNotValidatedMessagesAccepted = 0;
01764                      for( UInt_t uBuffer = 0; uBuffer < fParam->uNbBuffers; uBuffer ++ )
01765                      {
01766                         FECHIP[uChipCheck].uNotValidatedMessagesAccepted += (FECHIP[uChipCheck].fCurrentEventMsg[ uBuffer ]).size();
01767                         theRoc->fExtMessages.insert( theRoc->fExtMessages.end(),
01768                                  (FECHIP[uChipCheck].fCurrentEventMsg[ uBuffer ]).begin(),
01769                                  (FECHIP[uChipCheck].fCurrentEventMsg[ uBuffer ]).end());
01770                         (FECHIP[uChipCheck].fCurrentEventMsg[uBuffer]).clear();
01771                      } // for( UInt_t uBuffer = 0; uBuffer < fParam->uNbBuffers; uBuffer ++ )
01772                      uTotalUnvalidatedMessAccepted += FECHIP[uChipCheck].uNotValidatedMessagesAccepted;
01773 
01774                      (FECHIP[uChipCheck].fGet4AccMessNotValidated)->Fill( FECHIP[uChipCheck].uNotValidatedMessagesAccepted );
01775                   } // for( unsigned int uChipCheck = 0; uChipCheck < fParam->uNbFeets*2; uChipCheck++)
01776                   fGet4NotValidMessRawEvent->Fill( uTotalUnvalidatedMessAccepted, iFeetRocId);
01777                   fGet4EdgeMessagePerRawEvent->Fill( (theRoc->fExtMessages).size(), iFeetRocId );
01778                } // else if( kFALSE == fParam->NoGet4Cleaning )
01779                else fGet4EdgeMessagePerRawEvent->Fill( (theRoc->fExtMessages).size(), iFeetRocId );
01780          } // if( -1 != iFeetRocId)
01781       /*************************************/
01782 
01783          if (fParam->doSorting)
01784          {
01785 
01786 /*
01787             printf("======== Before %u ========== \n", theRoc->fExtMessages.size());
01788             for (unsigned n=0; n<theRoc->fExtMessages.size();n++)
01789                theRoc->fExtMessages[n].GetRocMessage().printData();
01790             printf("======================================================= \n");
01791 */
01792 
01793             std::sort(theRoc->fExtMessages.begin(), theRoc->fExtMessages.end());
01794             
01796             // Only if not trigger window us applied
01797             if( kTRUE == fParam->noTrigger )
01798             {
01799                if( -1 != iFeetRocId)
01800                   // Time ordering valid get4 data messages
01801                   if( kFALSE == TimeOrderMessageBuffer( theRoc ) )
01802                   {
01803                      // Do something? means it's empty!
01804                      // => Case should never popup with previous checks...
01805                   }
01806             }
01807       /*************************************/
01808          }
01809 
01810          ROC[rocid].fEvntMultipl->Fill(theRoc->fExtMessages.size());
01811 
01812 
01813 //         if (theRoc->fExtMessages.size() == 0) {
01814 //            printf("======== ZERO messages for ROC %d, count %d \n", rocid,
01815 //                  bcount++);
01816 //
01817 //         }
01818 
01819          theRoc->SetValid(kTRUE);
01820 
01821 /*
01822          printf("======== SetValid TRUE %u ========== \n", theRoc->fExtMessages.size());
01823          for (unsigned n=0; n<theRoc->fExtMessages.size();n++) {
01824             printf ("Tm: %10llu", theRoc->fExtMessages[n].GetFullTime());
01825             theRoc->fExtMessages[n].GetRocMessage().printData();
01826          }
01827          printf("======================================================= \n");
01828 */
01829 
01830 
01831 /*
01832          unsigned sz = theRoc->fExtMessages.size();
01833          printf("ROC%d has %u messages\n", rocid, sz);
01834          for (unsigned n=0;n<sz;n++) {
01835             printf("  Msg %3u fulltime:%10llu ", n, theRoc->fExtMessages[n].GetFullTime());
01836             theRoc->fExtMessages[n].GetRocMessage().printData();
01837 
01838             static uint64_t lasttm = 0;
01839             if (lasttm > theRoc->fExtMessages[n].GetFullTime()) {
01840                printf ("!!!!!!!!!!!! error with sorting !!!!!!!!!!!!");
01841                exit(5);
01842             }
01843             lasttm = theRoc->fExtMessages[n].GetFullTime();
01844          }
01845 */
01846       }
01847 
01848       fOutputEvent->SetValid(kTRUE);
01849 
01850       ResetTrigger();
01851 
01852 
01853 
01854    } else {
01855       fOutputEvent->SetValid(kFALSE);
01856 
01857       // another workaround - try to keep data which could be discarded
01858       // this is a case when MBS event ends, but we were not able to complete event
01859 
01860       for (unsigned rocid=0; rocid<fNumRocs;rocid++) {
01861          TRocData* theRoc = dynamic_cast<TRocData*>(fOutputEvent->getEventElement(rocid));
01862          if(theRoc==0) continue;
01863 #ifdef ROC_SINGLETRIGGERMODE
01864                         if (ROC[rocid].fHasNewTrigger && !ROC[rocid].fIsEventComplete && theRoc->fExtMessages.size()>0 ){    
01865 #else         
01866          if (ROC[rocid].fHasNewTrigger && theRoc->fExtMessages.size()>0 ){
01867 #endif
01868          // do not check if this subevent is not complete, since we have to save anyway if full event is incomplete
01869          //if (ROC[rocid].fHasNewTrigger && !ROC[rocid].fIsEventComplete && theRoc->fExtMessages.size()>0 ){
01870                //&& (ROC[rocid].fLastTriggerTm > ROC[rocid].fStartSyncTm)) { // JAM this one will lead to missed events between start and end buffer
01871 #ifdef DUMPMODE
01872             printf("Very special case - not closed event in ROC %u, saving %d messages\n", rocid,theRoc->fExtMessages.size());
01873 #endif
01874             //ROC[rocid].fTmpMessages = theRoc->fExtMessages; // JAM this will lead to trouble with complete empty buffers between trigger and closing msg
01875             ROC[rocid].fTmpMessages.insert(ROC[rocid].fTmpMessages.end(),theRoc->fExtMessages.begin(),theRoc->fExtMessages.end());
01876             theRoc->fExtMessages.clear();
01877          }
01878       }
01879    }
01880 
01881 
01882 
01883    // was triggered by parameter update
01884    if(fParam->storePedestalFile && (fParam->pedSaveToFile.Length()>0))  {
01885       fParam->storePedestalFile = kFALSE;
01886       if(fPedestals) fPedestals->SaveToFile( fParam->pedSaveToFile.Data());
01887    }
01888 
01889    if(GetTriggerNumber()>8)
01890    {
01891           //ignore pulser events in spill pause for the moment
01892           fOutputEvent->SetValid(kFALSE);
01893    }
01894 
01895    // Decide if we need to keep input event or request next one when all buffers are done:
01896 
01897    if(fIsTimeSorted)
01898         {
01899             if(allInputsComplete)
01900             {
01901 
01902 #ifdef DUMPMODE
01903                    cout <<"STRICT Timesorting mode finds all input buffers processed. Get new mbs input "<<bcount++ << endl;
01904 #endif
01905 
01906 #if __GO4BUILDVERSION__ > 40500
01907                    SetKeepInputEvent(kFALSE); // request new mbs container
01908 #endif
01909                    ResetEndOfBuffer();
01910             }
01911             else
01912             {
01913 #ifdef DUMPMODE
01914              cout <<"STRICT Timesorting mode sets KEEP mbs input!" << endl;
01915 #endif
01916 #if __GO4BUILDVERSION__ > 40500
01917 
01918                    SetKeepInputEvent(kTRUE);  // unless we have processed buffers of all rocs completely, we keep input
01919 #endif
01920             }
01921 
01922         }
01923 
01924 
01925 #ifdef ROC_SINGLETRIGGERMODE
01926       ResetEndOfBuffer(); // necessary to enter initialization part for each roc
01927 #endif
01928 
01929 
01930    // calculation of the rate:
01931      double tm = TTimeStamp().AsDouble();
01932      double diff = tm - fLastRateTm;
01933      if (diff>1.) {
01934         double rate = fTotaldatasize / diff;
01935         if (fRate==0.) fRate = rate;
01936         fRate = fRate * 0.9 + rate * 0.1;
01937         fEvntSize->SetTitle(Form("RATE %5.1f KB/s", fRate/1024.));
01938         fTotaldatasize = 0;
01939         fLastRateTm = tm;
01940      }
01941 
01942 
01943     //printf(" =============== TRocProc::FinalizeEvent ===================\n ");
01944 }
01945 
01946 
01947 void TRocProc::ProcessExtendedMessage(unsigned rocid, TRocData* rocevent, TRocMessageExtended& exmsg, bool with_unprocessed)
01948 {
01949    bool isinside(false), add_to_unprocessed(false), add_to_event(false);
01950 
01951    double diff = 0;
01952 
01953    if (ROC[rocid].fLastTriggerTm!=0) {
01954       if(exmsg.GetFullTime() >= ROC[rocid].fLastTriggerTm)
01955          diff = exmsg.GetFullTime() - ROC[rocid].fLastTriggerTm;
01956       else
01957          diff = -1.0 * (ROC[rocid].fLastTriggerTm - exmsg.GetFullTime());
01958 
01959    //if(with_unprocessed) cout << "       dt="<<diff<< endl;
01960    }
01961 
01962    if (fParam->noTrigger) {
01963 
01964       // to avoid situation when sorting over buffer boundary should be done,
01965       // only messages which are far away from last sync message, will be accepted into output event
01966 
01967       if (!fParam->doSorting || (ROC[rocid].fStopSyncTm==0)) {
01968          add_to_event = true;
01969       } else {
01970          if (exmsg.GetFullTime() + 16000 < ROC[rocid].fStopSyncTm)
01971             add_to_event = true;
01972          else
01973             add_to_unprocessed = true;
01974       }
01975    } else
01976    if (ROC[rocid].fHasNewTrigger) {
01977 
01978       TGo4WinCond* cond = fParam->globalTrigger ? fGlobalTriggerWind : ROC[rocid].fTriggerWind;
01979       TGo4WinCond* eventcond=cond; // only use this window for event building! JAM
01980       if(exmsg.GetMessageType() == roc::MSG_AUX)
01981          cond = fParam->globalTrigger ? fGlobalAUXWind : ROC[rocid].fAUXWind;
01982 
01983       exmsg.SetTriggerDeltaT(diff);
01984 
01985       if (cond->Test(diff)) {
01986          add_to_event = true;
01987          isinside = true;
01988       } else {
01989          double rightdist = diff - eventcond->GetXUp();
01990          if(fIsTimeSorted)
01991             {
01992                // we assume that message stream was strictly time sorted by dabc/ or go4 lmd user source JAM
01993                //if (rightdist>0.){
01994                // test: only real hits may close
01995                if (rightdist>0. && (exmsg.GetMessageType() != roc::MSG_SYNC || fParam->triggerSignal>9 )) {
01996                   // JAM in aux trigger mode, we do not allow sync messages to close event window
01997                   ROC[rocid].fIsEventComplete = kTRUE;
01998 //                  ROC[rocid].fHasNewTrigger= kFALSE; // everything after us is buffered until next trigger is found
01999 //                  if(fParam->globalTrigger && rocid==fParam->masterRoc)
02000 //                     fHasNewGlobalTrigger=kFALSE; // in master mode, enable accepting new trigger immediately!
02001                   add_to_unprocessed = kTRUE; // keep this message for next event.
02002 #ifdef DUMPMODE
02003                   cout <<"STRICT Timesorting mode marks complete event with msgtype:"<< (int) exmsg.GetMessageType() <<" for roc:"<<rocid<<" at dt="<<rightdist << endl;
02004 #endif
02005                }
02006             }
02007          else
02008             {
02009          //BEGIN NOT STRICTLY SORTED, 1 EVENT PER MBS CONTAINER, for fast online monitoring  JAM
02010                   // if hit far away on right side, event can be close for this ROC
02011                   if (rightdist > 5000.) ROC[rocid].fIsEventComplete = kTRUE;
02012                   if (rightdist>0.) {
02013                      if (ROC[rocid].fStopSyncTm==0) {
02014                         add_to_unprocessed = true;
02015                      } else {
02016                         double diff2 = 0;
02017                         if(exmsg.GetFullTime() >= ROC[rocid].fStopSyncTm)
02018                            diff2 = exmsg.GetFullTime() - ROC[rocid].fStopSyncTm;
02019                         else
02020                            diff2 = -1.0 * (ROC[rocid].fStopSyncTm - exmsg.GetFullTime());
02021 
02022                         // only keep message if it have chance to go into next event
02023                         add_to_unprocessed = diff2 >= cond->GetXLow();
02024 
02025                         // if (add_to_unprocessed && (rocid==0)) printf("diff2 = %7.1f\n", diff2);
02026                      }
02027                   }
02028          // END NOT STRICTLY
02029             } //if(fIsTimeSorted)
02030       } // if (cond->Test(diff))
02031    } // if (ROC[rocid].fHasNewTrigger)
02032    else 
02033    {
02034      // if no new trigger was found up to now, we need to add message to unprocessed
02035      // at the end of the message we should check if unprocessed messages are still interesting
02036      add_to_unprocessed = true;
02037    }
02038 
02039    //cout <<"....... isinside="<<isinside<<", add2event="<<add_to_event<<", add2unprocessed="<< add_to_unprocessed<< endl;
02040 
02041    if(isinside && (exmsg.GetMessageType() == roc::MSG_HIT)) { // but we put only nx hist to local histograms...
02042       unsigned nxid = exmsg.GetNxNumber();
02043       unsigned nxch = exmsg.GetNxChNum();
02044           unsigned nxadc = exmsg.GetNxADC();
02045       if (ROC[rocid].fTrigger_Chs[nxid])
02046          ROC[rocid].fTrigger_Chs[nxid]->Fill(nxch);
02047       if (ROC[rocid].fTrigADCs[nxid])
02048          ROC[rocid].fTrigADCs[nxid]->Fill(nxch, nxadc);
02049    }
02050 
02051     if((exmsg.GetMessageType() == roc::MSG_HIT || exmsg.GetMessageType() == roc::MSG_GET4) && (diff!=0)) {
02052      // if (rocid==0) printf("Diff = %9.1f\n", diff);
02053       fDeltaTriggerTime->Fill(diff);
02054       ROC[rocid].fTrigger_AllNX->Fill(diff);
02055       ROC[rocid].fTrigger_AllNX_100->Fill(diff);
02056       if(exmsg.GetMessageType() == roc::MSG_HIT) {
02057          unsigned nxid = exmsg.GetNxNumber();
02058          if (ROC[rocid].fTrigger_NX[nxid])
02059             ROC[rocid].fTrigger_NX[nxid]->Fill(diff);
02060       }
02061 
02062       if(exmsg.GetMessageType() == roc::MSG_GET4) {
02063          unsigned g4 = exmsg.GetGet4Number();
02064          if (ROC[rocid].fGet4Trigger[g4])
02065             ROC[rocid].fGet4Trigger[g4]->Fill(diff);
02066          if (ROC[rocid].fGet4Trigger100[g4])
02067             ROC[rocid].fGet4Trigger100[g4]->Fill(diff);
02068       }
02069    }
02070 
02071    if(exmsg.GetMessageType() == roc::MSG_AUX) {
02072       ROC[rocid].fTrigger_AUX->Fill(diff);
02073    }
02074 
02075 
02076    if(exmsg.GetMessageType() == roc::MSG_EPOCH)
02077    {
02078       // we use epoch messages to finish event time window, but do not want it stored.
02079       add_to_unprocessed=kFALSE;
02080       add_to_event=kFALSE;
02081 
02082    }
02083 
02084    if (rocevent && add_to_event)
02085       rocevent->fExtMessages.push_back(exmsg);
02086 
02087    if (add_to_unprocessed && with_unprocessed)
02088       ROC[rocid].fUnprocessedMsg.push_back(exmsg);
02089 }
02090 
02091 void TRocProc::ResetTrigger()
02092 {
02093 #ifdef DUMPMODE
02094    cout <<"RRRRRRRRRRRR ResetTrigger" << endl;
02095 #endif
02096    fHasNewGlobalTrigger = kFALSE;
02097    for (unsigned n=0; n<fNumRocs;n++)
02098    {
02099       ROC[n].fIsEventComplete = kFALSE;
02100 
02101       // why this JAM?V
02102 //#ifdef ROC_SINGLETRIGGERMODE
02103  //     if (ROC[n].fHasEndOfBuffer) ROC[n].fHasNewData = kFALSE;
02104 //#endif
02105       ROC[n].fHasNewTrigger = kFALSE;
02106 // SL: we keep last trigger time for histogramm filling
02107 //      ROC[n].fLastTriggerTm = 0;
02108       ROC[n].fDabcSeparator = -1;
02109 
02110    }
02111 }
02112 
02113 
02114 void TRocProc::ResetEndOfBuffer()
02115 {
02116 #ifdef DUMPMODE
02117    cout <<"RRRRRRRRRRRR ResetEndOfBuffer:" << endl;
02118 #endif
02119 
02120    for (unsigned n=0; n<fNumRocs;n++)
02121    {
02122 #ifdef DUMPMODE
02123       cout <<" Roc"<<n<<" triggers:"<<  ROC[n].fTriggersPerBuffer <<", loops:"<<ROC[n].fLoopsPerBuffer<< endl;
02124 #endif
02125       ROC[n].fTriggersPerBuffer=0;
02126       ROC[n].fLoopsPerBuffer=0;
02127       ROC[n].fHasEndOfBuffer = kFALSE;
02128       ROC[n].fHasNewData = kFALSE;
02129    }
02130 
02131    ;
02132 }
02133 
02134 /**********************************************************************/
02135 /*
02136  * This function process the data message when it is a GET4 epoch message
02137  */
02138 Bool_t TRocProc::ProcessGet4EpochMessage(UInt_t uRocId, TRocData* rocEvent, UInt_t uGet4IndexOffset, roc::Message* mesData)
02139 {
02140    // each GET4 chip generates epoch events
02141    UInt_t uChip = mesData->getEpoch2ChipNumber() + uGet4IndexOffset;
02142    
02143    // Remap the Get4 chip index
02144    uChip = fParam->RemapGet4Chip(uChip);
02145 
02146    // SL: test if chip ID is inside valid range
02147    if (!fParam->IsValidGet4Chip(uChip)) {
02148       TGo4Log::Error("Wrong chip id %u",uChip);
02149       return kFALSE;
02150    }
02151 
02152    mesData->setEpoch2ChipNumber(uChip);
02153 
02154   
02155    // Print debug data in the analysis log window for the
02156    // "fParam->uGet4Print" first messages
02157    if(printData<fParam->uGet4Print  )
02158    {
02159       // Print the informations of this epoch message
02160       Message(0,"Epoch chip %2d, ROC epoch %7d cycle %6d, local epoch %7d cycle %6d, Synched? %d, Loss? %d, Event %u, Un %d, Un Tot %d",
02161                uChip, mesData->getEpoch2Number(), FECHIP[uChip].uRocEpochCycle, FECHIP[uChip].uLocalEpochNb,
02162                FECHIP[uChip].uLocalEpochCycle,( mesData->getEpoch2Sync() != 0 ), ( mesData->getEpoch2DataLost() != 0 ),
02163                uNbEvents[0], FECHIP[uChip].uUnsyncedEpochs, FECHIP[uChip].uUnsyncedEpochsSinceLastSync);
02164       Message(0,"First synced epoc %7d, First Synced cycle %6d, shift last %3d, Status shift: %1d %1d %1d %1d %1d %1d",
02165                 uRocEpochFirstSyncedChip, uRocCycleFirstSyncedChip, FECHIP[uChip].iInterChipEpochShiftLast,
02166                 FECHIP[0].bChipGotASync, FECHIP[1].bChipGotASync, FECHIP[2].bChipGotASync, FECHIP[3].bChipGotASync, 
02167                 FECHIP[4].bChipGotASync, FECHIP[5].bChipGotASync);
02168       PrintLocalEpochIndexes( 0 );
02169       PrintRocEpochIndexes( 0 );
02170       Message(0, "Current Buffer: %2d", FECHIP[uChip].uCurrentMessagesBuffer);
02171       printData++;
02172    }
02173     
02174    // Test if chip is software disabled
02175    if( !fParam->uGet4Active[uChip] )
02176       return kTRUE;
02177 
02178    if( GET4_BUFFERS_SIZE_LIMIT < (FECHIP[uChip].fCurrentEventMsg[ FECHIP[uChip].uCurrentMessagesBuffer ]).size() ||
02179        GET4_BUFFERS_SIZE_LIMIT < (FECHIP[uChip].fCurrentUnprocessedMsg[ FECHIP[uChip].uCurrentMessagesBuffer ]).size()  )
02180    {
02181       Message(1,"Get4 warning: buffer on chip %2u reached the limit size of %uk messages: current size %6d",
02182             uChip, GET4_BUFFERS_SIZE_LIMIT/1000, (FECHIP[uChip].fCurrentEventMsg[ FECHIP[uChip].uCurrentMessagesBuffer ]).size());
02183       Message(1," => Check the active chips parameters, if OK there is probably oscillations!");
02184       Message(1," => Buffer will be cleared");
02185       (FECHIP[uChip].fCurrentEventMsg[       FECHIP[uChip].uCurrentMessagesBuffer ]).clear();
02186       (FECHIP[uChip].fCurrentUnprocessedMsg[ FECHIP[uChip].uCurrentMessagesBuffer ]).clear();
02187    }
02188 
02189    for( UInt_t uBufferTemp = 0; uBufferTemp < fParam->uNbBuffers; uBufferTemp ++)
02190       if( GET4_BUFFERS_SIZE_LIMIT <  vMessageInterBuffer[ uBufferTemp ].size() ||
02191           GET4_BUFFERS_SIZE_LIMIT <  vMessageInterBufferUnprocessed[ uBufferTemp ].size()  )
02192       {
02193          Message(1,"Get4 warning: inter buffer #%2u reached the limit size of %uk messages: current size %6d",
02194                uBufferTemp, GET4_BUFFERS_SIZE_LIMIT/1000, vMessageInterBuffer[ uBufferTemp ].size());
02195          Message(1," => Check the active chips parameters, if OK there is probably oscillations!");
02196          Message(1," => Buffer will be cleared");
02197          vMessageInterBuffer[uBufferTemp].clear();
02198          vMessageInterBufferUnprocessed[uBufferTemp].clear();
02199       }
02200 
02201    // bLossFlag indicates whether some data were lost for this
02202    // get4 in ROC buffer during this epoch
02203    Bool_t bLossFlag = ( mesData->getEpoch2DataLost() != 0 );
02204    
02205    // bSyncFlag indicates whether the GET4 asic was synchronised
02206    // in this epoch
02207    Bool_t bSyncFlag = ( mesData->getEpoch2Sync() != 0 );
02208    
02209    if( bLossFlag )
02210    {
02211       fGet4DataLoss->Fill( uChip );
02212       if ( uChip >= 0 && uChip < fParam->uNbFeets * 2 )
02213          FECHIP[uChip].uLastEpoch2 = mesData->getEpoch2Number();
02214       
02215       if( 0 == fParam->uSilentMode )
02216       {
02217          Message(3,"****** Data Loss on chip %2d in epoch %7d cycle %6d (local epoch %7d cycle %6d) Synched? %d, Event %u, Un %d, Un Tot %d",
02218                      uChip, mesData->getEpoch2Number(), FECHIP[uChip].uRocEpochCycle, FECHIP[uChip].uLocalEpochNb,
02219                      FECHIP[uChip].uLocalEpochCycle,bSyncFlag, uNbEvents[0],
02220                      FECHIP[uChip].uUnsyncedEpochs, FECHIP[uChip].uUnsyncedEpochsSinceLastSync);
02221          PrintMessageBufferIndexes( 0 );
02222          PrintMessageBufferSizes( 0 );
02223       }
02224       FECHIP[uChip].bDataLossSinceLastSync = kTRUE;
02225       return kFALSE;
02226    }
02227 
02228    // Analyses works now with a variable number of FEET boards
02229    // e.g. fParam->uNbFeets * 2 GET4 ASICs
02230    if ( uChip >= 0 && uChip < fParam->uNbFeets * 2 )
02231    {         
02232       fDistribEpochsRoc->Fill(uChip, (UInt_t)(mesData->getEpoch2Number()) );
02233       fDistribEpochsLocal->Fill(uChip, FECHIP[uChip].uLocalEpochNb );
02234       (FECHIP[uChip].uLocalEpochNb)++;
02235       
02236       // uLastEpoch contains the current epoch number
02237       if( mesData->getEpoch2Number() < (FECHIP[uChip].uLastEpoch2) )
02238       {
02239          (FECHIP[uChip].uRocEpochCycle)++;
02240       }             
02241          
02242       // uLastEpoch contains the current epoch number
02243       if( FECHIP[uChip].uLocalEpochNb == fParam->uRocCycleSize)
02244       {
02245          (FECHIP[uChip].uLocalEpochCycle)++;
02246          FECHIP[uChip].uLocalEpochNb = 0;
02247          if( 1 == fParam->uDebugHistoOn )
02248          {
02249             //Update DNL histograms
02250             for (UInt_t uChan = 0; uChan < NB_CHAN_GET4; uChan++) 
02251             {
02252                Double_t dDnlLeading = 0;
02253                Double_t dSumLeading = 0;
02254                Double_t dDnlTrailing = 0;
02255                Double_t dSumTrailing = 0;
02256                
02257                // First Resets everything
02258                (FECHIP[uChip].fGet4LeDnl)[uChan]->Reset();
02259                (FECHIP[uChip].fGet4LeDnlSum)[uChan]->Reset();
02260                (FECHIP[uChip].fGet4TeDnl)[uChan]->Reset();
02261                (FECHIP[uChip].fGet4TeDnlSum)[uChan]->Reset();
02262          
02263                // First bin
02264                dDnlLeading = ((FECHIP[uChip].fGet4FineTimeLE)[uChan]->GetBinContent(1)- 
02265                                     ((FECHIP[uChip].fGet4FineTimeLE)[uChan]->GetEntries()/(Double_t)NB_BIN_GET4_FTS) ) /
02266                                  ((FECHIP[uChip].fGet4FineTimeLE)[uChan]->GetEntries()/(Double_t)NB_BIN_GET4_FTS);
02267                (FECHIP[uChip].fGet4LeDnl)[uChan]->Fill( 0.0, dDnlLeading);
02268                dSumLeading += dDnlLeading;
02269                (FECHIP[uChip].fGet4LeDnlSum)[uChan]->Fill( 0.0, dSumLeading );
02270                
02271                dDnlTrailing = ((FECHIP[uChip].fGet4FineTimeTE)[uChan]->GetBinContent(1)- 
02272                                     ((FECHIP[uChip].fGet4FineTimeTE)[uChan]->GetEntries()/(Double_t)NB_BIN_GET4_FTS) ) /
02273                                  ((FECHIP[uChip].fGet4FineTimeTE)[uChan]->GetEntries()/(Double_t)NB_BIN_GET4_FTS);
02274                (FECHIP[uChip].fGet4TeDnl)[uChan]->Fill( 0.0, dDnlTrailing );
02275                dSumTrailing += dDnlTrailing;
02276                (FECHIP[uChip].fGet4TeDnlSum)[uChan]->Fill( 0.0, dSumTrailing );
02277                
02278                for( Int_t iBin = 2; iBin <= NB_BIN_GET4_FTS; iBin++)
02279                {
02280                   dDnlLeading = ((FECHIP[uChip].fGet4FineTimeLE)[uChan]->GetBinContent(iBin)- 
02281                                        ((FECHIP[uChip].fGet4FineTimeLE)[uChan]->GetEntries()/(Double_t)NB_BIN_GET4_FTS) ) /
02282                                  ((FECHIP[uChip].fGet4FineTimeLE)[uChan]->GetEntries()/(Double_t)NB_BIN_GET4_FTS);
02283                   (FECHIP[uChip].fGet4LeDnl)[uChan]->Fill( (Double_t)(iBin-1), dDnlLeading );
02284                   dSumLeading += dDnlLeading;
02285                   (FECHIP[uChip].fGet4LeDnlSum)[uChan]->Fill( (Double_t)(iBin-1), dSumLeading );
02286                   
02287                   dDnlTrailing = ((FECHIP[uChip].fGet4FineTimeTE)[uChan]->GetBinContent(iBin)- 
02288                                        ((FECHIP[uChip].fGet4FineTimeTE)[uChan]->GetEntries()/(Double_t)NB_BIN_GET4_FTS) ) /
02289                                  ((FECHIP[uChip].fGet4FineTimeTE)[uChan]->GetEntries()/(Double_t)NB_BIN_GET4_FTS);
02290                   (FECHIP[uChip].fGet4TeDnl)[uChan]->Fill( (Double_t)(iBin-1), dDnlTrailing );
02291                   dSumTrailing += dDnlTrailing;
02292                   (FECHIP[uChip].fGet4TeDnlSum)[uChan]->Fill( (Double_t)(iBin-1), dSumTrailing );
02293                } // for( Int_t iBin = 2; iBin <= NB_BIN_GET4_FTS; iBin++)
02294             } // for (Int_t uChan = uChip*4; uChan < (uChip+1)*4; uChan++) 
02295          } // if( 1 == uDebugHistoOn )
02296       } // if( FECHIP[uChip].uLocalEpochNb == fParam->uRocCycleSize)
02297       
02298       FECHIP[uChip].uLastEpoch2 = mesData->getEpoch2Number();
02299 
02300       if( 1 == fParam->uUseLocalEpochs)
02301       {
02302          uCurrentEpoch2 = FECHIP[uChip].uLocalEpochNb;
02303          uCurrentCycle2 = FECHIP[uChip].uLocalEpochCycle;
02304       }
02305       else
02306       {
02307          uCurrentEpoch2 = mesData->getEpoch2Number();
02308          uCurrentCycle2 = FECHIP[uChip].uRocEpochCycle;
02309       }
02310       
02311       if ( bSyncFlag )
02312       {
02313          // Reject everything before the first synchronization!
02314          if( FECHIP[uChip].bFirstEpochBlock == kTRUE)
02315          {
02316             for(UInt_t uChipTemp = 0; uChipTemp < 2*fParam->uNbFeets; uChipTemp++ )
02317                   if( kTRUE == FECHIP[uChipTemp].bFirstEpochBlock && 1 == FECHIP[uChipTemp].uNbEpochBlockAfterReset
02318                         && 0 == FECHIP[uChip].uNbEpochBlockAfterReset
02319                         && 15 < FECHIP[uChipTemp].uUnsyncedEpochsSinceLastSync)
02320                   {
02321                      Message(0,"Jump chip %2d which started earlier than others: %7d epoch since first sync!",
02322                                uChipTemp, FECHIP[uChipTemp].uUnsyncedEpochsSinceLastSync);
02323                      FECHIP[uChipTemp].uNbEpochBlockAfterReset = 0;
02324                      FECHIP[uChipTemp].uUnsyncedEpochsSinceLastSync = 0;
02325                   }
02326 
02327             if( 1 == FECHIP[uChip].uNbEpochBlockAfterReset )
02328                FECHIP[uChip].bFirstEpochBlock = kFALSE;
02329             
02330             FECHIP[uChip].uLocalEpochCycle = 0;
02331             FECHIP[uChip].uLocalEpochNb    = 0;
02332             
02333             // clear the "fParam->uSyncCycleSize" epochs data message & epochs number buffers
02334             for( UInt_t uBuffer = 0; uBuffer < fParam->uNbBuffers; uBuffer ++)
02335             {
02336                (FECHIP[uChip].fCurrentEventMsg)[uBuffer].clear();
02337                (FECHIP[uChip].fCurrentUnprocessedMsg)[uBuffer].clear();
02338             }
02339             FECHIP[uChip].uCurrentMessagesBuffer = 0;
02340             
02341             if( 1 == fParam->uUseLocalEpochs)
02342             {
02343                FECHIP[uChip].uEpochStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uLocalEpochNb;
02344                FECHIP[uChip].uCycleStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uLocalEpochCycle;
02345             }
02346             else
02347             {
02348                FECHIP[uChip].uEpochStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uLastEpoch2;
02349                FECHIP[uChip].uCycleStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uRocEpochCycle;
02350             }
02351 
02352             // Reset the variable storing the total nb of messages
02353             // buffered at the end of last epoch
02354             // (Overkill, but safer)
02355             FECHIP[uChip].u_messageCountLastEpoch = 0;
02356             
02357             // the number of unsynced epochs is reseted here
02358             FECHIP[uChip].uUnsyncedEpochs = 0;
02359             FECHIP[uChip].uUnsyncedEpochsSinceLastSync = 0;
02360             FECHIP[uChip].bDataLossSinceLastSync = kFALSE;
02361             FECHIP[uChip].cAutomaticFakeSyncSinceLastSync = 0;
02362                      
02363             FECHIP[uChip].uEpochMainClockSinceLastSync = 0;
02364             
02365             
02366             FECHIP[uChip].bFirstSyncAfterEventJump = kFALSE;
02367             
02368             FECHIP[uChip].bChipGotASync = kTRUE;
02369             uRocEpochFirstSyncedChip = 0;
02370             uRocCycleFirstSyncedChip = 0;
02371             FECHIP[uChip].iInterChipEpochShiftLast = 0;
02372 
02373             // Preparing modulo debug variables
02374             FECHIP[uChip].uModuloLastSynch = mesData->getEpoch2Number()%(fParam->uSyncCycleSize);
02375             FECHIP[uChip].uCycleLastSynch = FECHIP[uChip].uRocEpochCycle;
02376             if( 1 == FECHIP[uChip].uNbEpochBlockAfterReset )
02377             {
02378                Message(1,"Here we start for chip %2d (1st sync just passed, Roc epoch %10d, cycle %6d)",
02379                      uChip, FECHIP[uChip].uLastEpoch2, FECHIP[uChip].uRocEpochCycle);
02380                PrintMessageBufferIndexes( 0 );
02381                PrintLocalEpochIndexes( 0 );
02382                PrintLocalEpochCycles( 0 );
02383             }
02384 
02385             FECHIP[uChip].bJumpEpochBlockAfterReset = kFALSE;
02386             if( 1 == FECHIP[uChip].uNbEpochBlockAfterReset )
02387                FECHIP[uChip].uNbEpochBlockAfterReset = 0;
02388                else FECHIP[uChip].uNbEpochBlockAfterReset ++;
02389             
02390             // Goes on without doing anything else
02391             return kTRUE;
02392          } // if( FECHIP[uChip].bFirstEpochBlock == kTRUE)
02393             
02394          // Reject everything in fParam->uNbBlockJumpedReset epoch blocks
02395          // after a GET4 reset message has been received
02396          // 2*27µs + 37µs = ~100µs data thronw out
02397          if( FECHIP[uChip].bJumpEpochBlockAfterReset == kTRUE)
02398          {
02399             if( 0 == uEpochFirstSyncAfterReset && 0 == uCycleFirstSyncAfterReset)
02400             {
02401                if( 1 == fParam->uUseLocalEpochs)
02402                {
02403                   uEpochFirstSyncAfterReset = FECHIP[uChip].uLocalEpochNb;
02404                   uCycleFirstSyncAfterReset = FECHIP[uChip].uLocalEpochCycle;
02405                }
02406                else
02407                {
02408                   uEpochFirstSyncAfterReset = FECHIP[uChip].uLastEpoch2;
02409                   uCycleFirstSyncAfterReset = FECHIP[uChip].uRocEpochCycle;
02410                }
02411             }
02412             /*
02413              * For now no check on Epoch cycle, should not matter with new version of
02414              * ROC firmware!!!
02415              */
02416             ULong64_t ulHighestStartEpoch = 0;
02417             ULong64_t ulLocalEpochHighestStart = 0;
02418             UInt_t    uBufferWithHighestStart = 0;
02419             UInt_t    uInterBufferWithHighestStart = 0;
02420             Bool_t    bTestFirstAfterReset = kTRUE;
02421             for ( UInt_t uChipTemp = 0; uChipTemp < fParam->uNbFeets * 2; uChipTemp++ )
02422             {
02423                if( !fParam->uGet4Active[uChipTemp] )
02424                   continue;
02425                if( 0 < FECHIP[uChipTemp].uNbEpochBlockAfterReset )
02426                {
02427                   bTestFirstAfterReset = kFALSE;
02428                   break;
02429                }
02430                for( UInt_t uBufferTemp = 0; uBufferTemp < fParam->uNbBuffers; uBufferTemp ++)
02431                   if( ulHighestStartEpoch < FECHIP[uChipTemp].uEpochStart[uBufferTemp] )
02432                   {
02433                      ulHighestStartEpoch = FECHIP[uChipTemp].uEpochStart[uBufferTemp];
02434                      ulLocalEpochHighestStart = FECHIP[uChipTemp].uLocalEpochNb;
02435                      uBufferWithHighestStart = uBufferTemp;
02436                      uInterBufferWithHighestStart = FECHIP[uChipTemp].uCurrentMessageInterBuffer;
02437                   }
02438             }
02439             if( kTRUE == bTestFirstAfterReset )
02440             {
02441                for ( UInt_t uChipTemp = 0; uChipTemp < fParam->uNbFeets * 2; uChipTemp++ )
02442                {
02443                   if( !fParam->uGet4Active[uChipTemp] )
02444                      continue;
02445                   for( UInt_t uBufferTemp = 0; uBufferTemp < fParam->uNbBuffers; uBufferTemp ++)
02446                   {
02447                      if( FECHIP[uChipTemp].uEpochStart[uBufferTemp] < ulHighestStartEpoch )
02448                      {
02449                         (FECHIP[uChipTemp].fCurrentEventMsg)[uBufferTemp].clear();
02450                         (FECHIP[uChipTemp].fCurrentUnprocessedMsg)[uBufferTemp].clear();
02451                      }
02452                   }
02453 
02454                   FECHIP[uChipTemp].uCurrentMessagesBuffer = uBufferWithHighestStart;
02455                   FECHIP[uChipTemp].uCurrentMessageInterBuffer = uInterBufferWithHighestStart;
02456                   FECHIP[uChipTemp].uEpochStart[FECHIP[uChipTemp].uCurrentMessagesBuffer] = 0;
02457                   FECHIP[uChipTemp].uCycleStart[FECHIP[uChipTemp].uCurrentMessagesBuffer] = 0;
02458 
02459                   FECHIP[uChipTemp].uLocalEpochNb = ulLocalEpochHighestStart;
02460                }
02461             }
02462 
02463             (FECHIP[uChip].uNbEpochBlockAfterReset)++;
02464             
02465             Message(0,"Throwing Epoch block for chip %2d because of GET4 reset: block %2d (Epoch %11d, local %11d, %11d %7d, %d)",
02466                       uChip,FECHIP[uChip].uNbEpochBlockAfterReset,  FECHIP[uChip].uLastEpoch2, FECHIP[uChip].uLocalEpochNb,
02467                       uEpochFirstSyncAfterReset, uCycleFirstSyncAfterReset, FECHIP[uChip].uCurrentMessagesBuffer);
02468             
02469             if( 1 == fParam->uUseLocalEpochs)
02470             {
02471                if( fParam->uNbBlockJumpedReset == FECHIP[uChip].uNbEpochBlockAfterReset)
02472                {
02473                   FECHIP[uChip].bJumpEpochBlockAfterReset = kFALSE;
02474                   FECHIP[uChip].uNbEpochBlockAfterReset = 0;
02475                }
02476             }
02477                else if( ( uEpochFirstSyncAfterReset + (fParam->uNbBlockJumpedReset -1) * fParam->uSyncCycleSize
02478                            <= FECHIP[uChip].uLastEpoch2 ) ||
02479                    uCycleFirstSyncAfterReset < FECHIP[uChip].uRocEpochCycle )
02480                {
02481                   FECHIP[uChip].bJumpEpochBlockAfterReset = kFALSE;
02482                   FECHIP[uChip].uNbEpochBlockAfterReset = 0;
02483                }
02484             
02485             // clear the "fParam->uSyncCycleSize" epochs data message & epochs number buffers
02486             (FECHIP[uChip].fCurrentEventMsg[FECHIP[uChip].uCurrentMessagesBuffer]).clear();
02487             (FECHIP[uChip].fCurrentUnprocessedMsg[FECHIP[uChip].uCurrentMessagesBuffer]).clear();
02488             
02489             Int_t iNbEpochToIgnore = FECHIP[uChip].uUnsyncedEpochs + 1;
02490 
02491             if( (Int_t)(FECHIP[uChip].uLocalEpochNb) < iNbEpochToIgnore )
02492             {
02493                (FECHIP[uChip].uLocalEpochCycle)--;
02494                FECHIP[uChip].uLocalEpochNb = fParam->uRocCycleSize
02495                                               + FECHIP[uChip].uLocalEpochNb
02496                                               - iNbEpochToIgnore ;
02497             }
02498             else if( fParam->uRocCycleSize < (FECHIP[uChip].uLocalEpochNb - iNbEpochToIgnore ) )
02499             {
02500                (FECHIP[uChip].uLocalEpochCycle)++;
02501                FECHIP[uChip].uLocalEpochNb = FECHIP[uChip].uLocalEpochNb - iNbEpochToIgnore
02502                                                            - fParam->uRocCycleSize;
02503             }
02504             else
02505                FECHIP[uChip].uLocalEpochNb -= iNbEpochToIgnore;
02506             if( 1 == fParam->uUseLocalEpochs)
02507             {
02508                FECHIP[uChip].uEpochStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uLocalEpochNb;
02509                FECHIP[uChip].uCycleStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uLocalEpochCycle;
02510             }
02511             else
02512             {
02513                FECHIP[uChip].uEpochStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uLastEpoch2;
02514                FECHIP[uChip].uCycleStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uRocEpochCycle;
02515             }
02516 
02517             // Reset the variable storing the total nb of messages
02518             // buffered at the end of last epoch
02519             // (Overkill, but safer)
02520             FECHIP[uChip].u_messageCountLastEpoch = 0;
02521             
02522             // the number of unsynced epochs is reseted here
02523             FECHIP[uChip].uUnsyncedEpochs = 0;
02524             FECHIP[uChip].uUnsyncedEpochsSinceLastSync = 0;
02525             FECHIP[uChip].bDataLossSinceLastSync = kFALSE;
02526             FECHIP[uChip].cAutomaticFakeSyncSinceLastSync = 0;
02527                      
02528             FECHIP[uChip].uEpochMainClockSinceLastSync = 0;
02529 
02530             // Preparing modulo debug variables
02531             FECHIP[uChip].uModuloLastSynch = mesData->getEpoch2Number()%(fParam->uSyncCycleSize);
02532             FECHIP[uChip].uCycleLastSynch = FECHIP[uChip].uRocEpochCycle;
02533             
02534             // Goes on without doing anything else
02535             return kTRUE;
02536          } // if( FECHIP[uChip].bJumpEpochBlockAfterReset == kTRUE)
02537          
02538          // To survive missing events with a stream server
02539          if( FECHIP[uChip].bFirstSyncAfterEventJump == kTRUE)
02540          {
02541             FECHIP[uChip].bFirstSyncAfterEventJump = kFALSE;
02542             
02543             // clear the "fParam->uSyncCycleSize" epochs data message & epochs number buffers
02544             (FECHIP[uChip].fCurrentEventMsg[FECHIP[uChip].uCurrentMessagesBuffer]).clear();
02545             (FECHIP[uChip].fCurrentUnprocessedMsg[FECHIP[uChip].uCurrentMessagesBuffer]).clear();
02546             
02547             Int_t iNbEpochToIgnore = FECHIP[uChip].uUnsyncedEpochs + 1;
02548                
02549             if( (Int_t)(FECHIP[uChip].uLocalEpochNb) < iNbEpochToIgnore )
02550             {
02551                (FECHIP[uChip].uLocalEpochCycle)--;
02552                FECHIP[uChip].uLocalEpochNb = fParam->uRocCycleSize
02553                                               + FECHIP[uChip].uLocalEpochNb
02554                                               - iNbEpochToIgnore ;
02555             }
02556             else if( fParam->uRocCycleSize < (FECHIP[uChip].uLocalEpochNb - iNbEpochToIgnore ) )
02557             {
02558                (FECHIP[uChip].uLocalEpochCycle)++;
02559                FECHIP[uChip].uLocalEpochNb = FECHIP[uChip].uLocalEpochNb - iNbEpochToIgnore
02560                                                            - fParam->uRocCycleSize;
02561             }
02562             else
02563                FECHIP[uChip].uLocalEpochNb -= iNbEpochToIgnore;
02564             if( 1 == fParam->uUseLocalEpochs)
02565             {
02566                FECHIP[uChip].uEpochStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uLocalEpochNb;
02567                FECHIP[uChip].uCycleStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uLocalEpochCycle;
02568             }
02569             else
02570             {
02571                FECHIP[uChip].uEpochStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uLastEpoch2;
02572                FECHIP[uChip].uCycleStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uRocEpochCycle;
02573             }
02574 
02575             // Reset the variable storing the total nb of messages
02576             // buffered at the end of last epoch
02577             // (Overkill, but safer)
02578             FECHIP[uChip].u_messageCountLastEpoch = 0;
02579             
02580             // the number of unsynced epochs is reseted here
02581             FECHIP[uChip].uUnsyncedEpochs = 0;
02582             FECHIP[uChip].uUnsyncedEpochsSinceLastSync = 0;
02583             FECHIP[uChip].bDataLossSinceLastSync = kFALSE;
02584             FECHIP[uChip].cAutomaticFakeSyncSinceLastSync = 0;
02585                      
02586             FECHIP[uChip].uEpochMainClockSinceLastSync = 0;
02587 
02588             // Preparing modulo debug variables
02589             FECHIP[uChip].uModuloLastSynch = mesData->getEpoch2Number()%(fParam->uSyncCycleSize);
02590             FECHIP[uChip].uCycleLastSynch = FECHIP[uChip].uRocEpochCycle;
02591             
02592             Message(0,"Here we re-start for chip %2d (1st sync after missing event just passed)", uChip);
02593             
02594             // Goes on without doing anything else
02595             return kTRUE;
02596          }
02597           
02598          if( FECHIP[0].uRocEpochCycle==0)
02599          {
02600             fMapEpochsRoc->Fill(uChip, mesData->getEpoch2Number()%(fParam->uSyncCycleSize) );
02601          }
02602          (FECHIP[uChip].fModuloSyncRoc)->Fill(FECHIP[uChip].uRocEpochCycle, mesData->getEpoch2Number()%(fParam->uSyncCycleSize));
02603          
02604          fMapEpochsMain->Fill(uChip, uLastEpochMainClock%(fParam->uMainSyncCycleSize) );
02605          (FECHIP[uChip].fModuloSyncMainClock)->Fill(uMainEpochCycle, uLastEpochMainClock%(fParam->uMainSyncCycleSize));
02606          
02607          // if the sync flag is set the number of unsynced epoch
02608          // since the
02609          // last epoch flag was set is filled into a histogram
02610          (FECHIP[uChip].fGet4SyncSpacing)->Fill( FECHIP[uChip].uUnsyncedEpochsSinceLastSync );
02611          (FECHIP[uChip].fGet4SyncSpacingComp)->Fill( FECHIP[uChip].uUnsyncedEpochsSinceLastSync, FECHIP[uChip].uUnsyncedEpochs );
02612          fNbMissedSync->Fill( uChip, FECHIP[uChip].cAutomaticFakeSyncSinceLastSync);
02613          
02614          UInt_t uMeanEpochNb = 0;
02615          UInt_t uNbActiveChips = 0;
02616          for( UInt_t uChipLoop = 0; uChipLoop < fParam->uNbFeets * 2; uChipLoop++)
02617             if( uChipLoop != uChip && fParam->uGet4Active[ uChipLoop ] )
02618             {
02619                uMeanEpochNb += FECHIP[uChipLoop].uLocalEpochNb;
02620                uNbActiveChips++;
02621             }
02622          if( 0 < uNbActiveChips )
02623             uMeanEpochNb /= uNbActiveChips;
02624                
02625          // Only if we will not ignore this fake "epoch block" in later analysis
02626          // aka if more than half of number of unsynchronized epochs
02627          // Do it also if there was some data loss since last sync, because then we
02628          // don't know how much was lost! => Wrong?!?
02629          if( ( FECHIP[uChip].uUnsyncedEpochs > ( (fParam->uSyncCycleSize - 1)/2 + 1) ||
02630               ( FECHIP[uChip].uUnsyncedEpochs == ( (fParam->uSyncCycleSize - 1)/2 + 1) && 
02631                 FECHIP[uChip].uLocalEpochNb <= uMeanEpochNb) )||
02632              ( kTRUE == FECHIP[uChip].bDataLossSinceLastSync && 3 < FECHIP[uChip].uUnsyncedEpochs ) || 
02633              ( 0 < FECHIP[uChip].cAutomaticFakeSyncSinceLastSync && 3 < FECHIP[uChip].uUnsyncedEpochs ) )
02634          {
02635             if( 0 == fParam->uSilentSyncMode )
02636             {
02637                if(kTRUE == FECHIP[uChip].bDataLossSinceLastSync )
02638                {
02639                   Message(0,"After Loss: chip %2d Local epoch %7d, cycle %6d, Unsynched Counts: %3d, Total Unsync %3d",
02640                               uChip, FECHIP[uChip].uLocalEpochNb, FECHIP[uChip].uLocalEpochCycle, FECHIP[uChip].uUnsyncedEpochs,
02641                               FECHIP[uChip].uUnsyncedEpochsSinceLastSync);
02642                   PrintLocalEpochIndexes( 0 );
02643                   PrintLocalEpochCycles( 0 );
02644                }
02645                if(0 < FECHIP[uChip].cAutomaticFakeSyncSinceLastSync )
02646                {
02647                   Message(0,"After Auto: chip %2d Local epoch %7d, cycle %6d, Unsynched Counts: %3d, Total Unsync %3d",
02648                               uChip, FECHIP[uChip].uLocalEpochNb, FECHIP[uChip].uLocalEpochCycle, FECHIP[uChip].uUnsyncedEpochs,
02649                               FECHIP[uChip].uUnsyncedEpochsSinceLastSync);
02650                   PrintLocalEpochIndexes( 0 );
02651                   PrintLocalEpochCycles( 0 );
02652                }
02653                if( FECHIP[uChip].uUnsyncedEpochs == ( (fParam->uSyncCycleSize - 1)/2 + 1) )
02654                {
02655                   Message(0,"After Eq +: chip %2d Local epoch %7d, cycle %6d, Unsynched Counts: %3d, Total Unsync %3d Mean %7d",
02656                               uChip, FECHIP[uChip].uLocalEpochNb, FECHIP[uChip].uLocalEpochCycle, FECHIP[uChip].uUnsyncedEpochs,
02657                               FECHIP[uChip].uUnsyncedEpochsSinceLastSync, uMeanEpochNb);
02658                   PrintLocalEpochIndexes( 0 );
02659                   PrintLocalEpochCycles( 0 );
02660                }
02661             }
02662                
02663             // Analyse data from next buffer
02664             Bool_t bNextEpochValid = kFALSE;
02665             if( fParam->uNbBuffers - 1 == FECHIP[uChip].uCurrentMessagesBuffer) // index made a loop => next is 1st buffer
02666                bNextEpochValid = FECHIP[uChip].bValidEpochFlag[ 0 ];
02667                else bNextEpochValid = FECHIP[uChip].bValidEpochFlag[FECHIP[uChip].uCurrentMessagesBuffer + 1];
02668             
02669             FECHIP[uChip].bMessageInterBufferOk[ FECHIP[uChip].uCurrentMessageInterBuffer ] = kTRUE;
02670             
02671             if(bNextEpochValid == kTRUE)
02672             {
02673                (vMessageInterBuffer[ FECHIP[uChip].uCurrentMessageInterBuffer ]).insert(
02674                         (vMessageInterBuffer[ FECHIP[uChip].uCurrentMessageInterBuffer ]).end(),
02675                         (FECHIP[uChip].fCurrentEventMsg[ FECHIP[uChip].uCurrentMessageInterBuffer ]).begin(),
02676                         (FECHIP[uChip].fCurrentEventMsg[ FECHIP[uChip].uCurrentMessageInterBuffer ]).end());
02677                (vMessageInterBufferUnprocessed[ FECHIP[uChip].uCurrentMessageInterBuffer ]).insert(
02678                         (vMessageInterBufferUnprocessed[ FECHIP[uChip].uCurrentMessageInterBuffer ]).end(),
02679                         (FECHIP[uChip].fCurrentUnprocessedMsg[ FECHIP[uChip].uCurrentMessageInterBuffer ]).begin(),
02680                         (FECHIP[uChip].fCurrentUnprocessedMsg[ FECHIP[uChip].uCurrentMessageInterBuffer ]).end());
02681                FECHIP[uChip].fGet4MessValidEpochs->Fill( 
02682                      (FECHIP[uChip].fCurrentEventMsg[ FECHIP[uChip].uCurrentMessageInterBuffer ]).size() );
02683                (FECHIP[uChip].fCurrentEventMsg[ FECHIP[uChip].uCurrentMessageInterBuffer ]).clear();
02684                (FECHIP[uChip].fCurrentUnprocessedMsg[ FECHIP[uChip].uCurrentMessageInterBuffer ]).clear();
02685             }
02686 
02687             bTransferMessageNext = kTRUE;
02688             for( unsigned int uChipCheck = 0; uChipCheck < fParam->uNbFeets*2; uChipCheck++)
02689             {
02690                // two buffers solution
02691                if( FECHIP[uChipCheck].bMessageInterBufferOk[ FECHIP[uChip].uCurrentMessageInterBuffer ] == kFALSE 
02692                      && fParam->uGet4Active[ uChipCheck ])
02693                {
02694                   bTransferMessageNext = kFALSE;
02695                   break;
02696                }
02697             }
02698             if( bTransferMessageNext == kTRUE )
02699             {
02700                // Multiple buffers solution
02701                UInt_t uIndexNextInterMessBuff = 0;
02702                if( fParam->uNbBuffers - 1 == FECHIP[uChip].uCurrentMessageInterBuffer )
02703                   uIndexNextInterMessBuff = 0;
02704                   else uIndexNextInterMessBuff = FECHIP[uChip].uCurrentMessageInterBuffer + 1;
02705 
02706                if( kTRUE == fParam->noTrigger )
02707                   rocEvent->vMessageEventBuffer.insert( rocEvent->vMessageEventBuffer.end(),
02708                                     vMessageInterBuffer[ uIndexNextInterMessBuff ].begin(),
02709                                     vMessageInterBuffer[ uIndexNextInterMessBuff ].end() );
02710                   else
02711                   {
02712                      // TEST: attempt to make get4 processing compatible with trigger selection
02713                      rocEvent->fExtMessages.insert( rocEvent->fExtMessages.end(),
02714                                        vMessageInterBuffer[ uIndexNextInterMessBuff ].begin(),
02715                                        vMessageInterBuffer[ uIndexNextInterMessBuff ].end() );
02716                      (vUnprocessedMessages[uRocId]).insert((vUnprocessedMessages[uRocId]).end(),
02717                                     vMessageInterBufferUnprocessed[ uIndexNextInterMessBuff ].begin(),
02718                                     vMessageInterBufferUnprocessed[ uIndexNextInterMessBuff ].end() );
02719                   }
02720                
02721                for( unsigned int uChipCheck = 0; uChipCheck < fParam->uNbFeets*2; uChipCheck++)
02722                {
02723                   FECHIP[uChipCheck].bStoredHitUnp = kFALSE;
02724                   FECHIP[uChipCheck].bMessageInterBufferOk[ FECHIP[uChip].uCurrentMessageInterBuffer ] = kFALSE;
02725                }
02726                (vMessageInterBuffer[ uIndexNextInterMessBuff ]).clear();
02727                (vMessageInterBufferUnprocessed[ uIndexNextInterMessBuff ]).clear();
02728             }
02729             // Multiples buffers solution
02730             FECHIP[uChip].uCurrentMessageInterBuffer = (FECHIP[uChip].uCurrentMessageInterBuffer + 1)%fParam->uNbBuffers;
02731          } // if we will not ignore this fake "epoch block" in later analysis
02732             
02733          // If there was exactly "fParam->uSyncCycleSize - 1) epochs since last synched one,
02734          // all those "fParam->uSyncCycleSize" are valid, else they are all to be rejected
02735          if( FECHIP[uChip].uUnsyncedEpochs == (fParam->uSyncCycleSize - 1) && 
02736              FECHIP[uChip].uUnsyncedEpochsSinceLastSync == FECHIP[uChip].uUnsyncedEpochs 
02737              && kFALSE == FECHIP[uChip].bDataLossSinceLastSync)
02738             FECHIP[uChip].bValidEpochFlag[FECHIP[uChip].uCurrentMessagesBuffer] = kTRUE;
02739             else FECHIP[uChip].bValidEpochFlag[FECHIP[uChip].uCurrentMessagesBuffer] = kFALSE;
02740 
02741          FECHIP[uChip].bStoredHitUnp = kTRUE;
02742          if( FECHIP[0].uLocalEpochCycle == 0 )
02743          {
02744             fMapEpochsLocal->Fill(uChip, (FECHIP[uChip].uLocalEpochNb)%(fParam->uSyncCycleSize) );
02745          }
02746          (FECHIP[uChip].fModuloSyncLocal)->Fill(FECHIP[uChip].uLocalEpochCycle, (FECHIP[uChip].uLocalEpochNb)%(fParam->uSyncCycleSize));
02747          
02748          // Analyse data only from valid epochs
02749          if(FECHIP[uChip].bValidEpochFlag[FECHIP[uChip].uCurrentMessagesBuffer])
02750          {
02751             // Don't work straight because I need to take into account the cycles!
02752             //~ if( 0 != (FECHIP[uChip].uLocalEpochNb)%(fParam->uSyncCycleSize) )
02753                //~ GO4_STOP_ANALYSIS_MESSAGE("Et bimmmmmmm! %d %d", uChip, FECHIP[uChip].uLocalEpochNb );
02754             // Accepted epochs bunch
02755             (FECHIP[uChip].fGet4ValidSpacing)->Fill( FECHIP[uChip].uUnsyncedEpochs );
02756             
02757             if( mesData->getEpoch2Number()%(fParam->uSyncCycleSize) != FECHIP[uChip].uModuloLastSynch 
02758                 && (FECHIP[uChip].uRocEpochCycle) == FECHIP[uChip].uCycleLastSynch
02759                 && 0 == fParam->uSilentSyncMode)
02760                Message(2,"Synch ROC Epoch shift chip: %2d in Roc Epoch: %7d, cycle %6d (Local epoch %7d, cycle %6d) Unsynched Counts: %3d, last modulo %u/ modulo %u",
02761                            uChip, FECHIP[uChip].uLastEpoch2, FECHIP[uChip].uRocEpochCycle, FECHIP[uChip].uLocalEpochNb, 
02762                            FECHIP[uChip].uLocalEpochCycle, FECHIP[uChip].uUnsyncedEpochs,
02763                            FECHIP[uChip].uModuloLastSynch, mesData->getEpoch2Number()%(fParam->uSyncCycleSize));
02764             FECHIP[uChip].uModuloLastSynch = mesData->getEpoch2Number()%(fParam->uSyncCycleSize);
02765             FECHIP[uChip].uCycleLastSynch = FECHIP[uChip].uRocEpochCycle;
02766             
02767             // Inter chip epoch shift check
02768             Bool_t bFirstToSyncCheck = kTRUE;
02769             for( UInt_t uTempChip = 0; uTempChip < 2*fParam->uNbFeets; uTempChip++)
02770                if( kFALSE == FECHIP[uTempChip].bChipGotASync )
02771                   bFirstToSyncCheck = kFALSE;
02772             if( kTRUE == bFirstToSyncCheck )
02773             {
02774                uRocEpochFirstSyncedChip = FECHIP[uChip].uLastEpoch2;
02775                uRocCycleFirstSyncedChip = FECHIP[uChip].uRocEpochCycle;
02776                for( UInt_t uTempChip = 0; uTempChip < 2*fParam->uNbFeets; uTempChip++)
02777                   FECHIP[uTempChip].bChipGotASync = kFALSE;
02778                FECHIP[uChip].bChipGotASync = kTRUE;
02779             }
02780             else
02781             {
02782                FECHIP[uChip].bChipGotASync = kTRUE;
02783                Int_t iEpochShift = (Int_t)(FECHIP[uChip].uLastEpoch2) - (Int_t)uRocEpochFirstSyncedChip 
02784                                  + CYCLE_IN_EPOCHS*( (Int_t)(FECHIP[uChip].uRocEpochCycle) - (Int_t)uRocCycleFirstSyncedChip);
02785                if( iEpochShift != FECHIP[uChip].iInterChipEpochShiftLast )
02786                {
02787                   // Add option in Parameter!!!!!
02788                   //~ Message(0,"%2d epoch %7d cycle %6d Shift %3d", 
02789                             //~ uChip, FECHIP[uChip].uLastEpoch2, FECHIP[uChip].uRocEpochCycle,iEpochShift);
02790                       
02791                   FECHIP[uChip].iInterChipEpochShiftLast = iEpochShift;
02792                }
02793             }
02794             
02795             fInterChipSyncEpochShift->Fill(uChip, FECHIP[uChip].iInterChipEpochShiftLast); 
02796             (FECHIP[uChip].fInterChipSyncEpochShiftEvol)->Fill(FECHIP[uChip].uRocEpochCycle, FECHIP[uChip].iInterChipEpochShiftLast); 
02797          } // if(FECHIP[uChip].bValidEpochFlag[FECHIP[uChip].uCurrentMessagesBuffer])
02798          else
02799          {       
02800             // Inter chip epoch shift check
02801             FECHIP[uChip].bChipGotASync = kTRUE;     
02802             
02803             // When rejection enabled, some epochs bunch are invalid
02804             (FECHIP[uChip].fGet4InvalidSpacing)->Fill( FECHIP[uChip].uUnsyncedEpochsSinceLastSync ); 
02805             
02806             if( 0 == fParam->uSilentSyncMode )
02807             {
02808                Message(2,"Invalid Block chip: %2d in Roc Epoch: %7d Cycle %6d (Local ep %7d Cy %6d) Unsynched Counts: %3d Unsynch Total: %3d M Buffer %1d B Buffer %1d",
02809                            uChip, FECHIP[uChip].uLastEpoch2, FECHIP[uChip].uRocEpochCycle, FECHIP[uChip].uLocalEpochNb, 
02810                            FECHIP[uChip].uLocalEpochCycle, FECHIP[uChip].uUnsyncedEpochs, FECHIP[uChip].uUnsyncedEpochsSinceLastSync,
02811                            FECHIP[uChip].uCurrentMessagesBuffer, FECHIP[uChip].uCurrentMessageInterBuffer);
02812                Message(1,"Current 250MHz epoch count since last sync: %3d", FECHIP[uChip].uEpochMainClockSinceLastSync);
02813                PrintLocalEpochIndexes( 1 );
02814                PrintLocalEpochCycles( 1 );
02815             }
02816 
02817             // clear the "fParam->uSyncCycleSize" epochs data message & epochs number buffers
02818             (FECHIP[uChip].fCurrentEventMsg[FECHIP[uChip].uCurrentMessagesBuffer]).clear();
02819             (FECHIP[uChip].fCurrentUnprocessedMsg[FECHIP[uChip].uCurrentMessagesBuffer]).clear();
02820             
02821             // If less than half of a normal sync period => no real sync
02822             // Go back as if last epochs did not exist!
02823             // Except if there was some data loss since last sync, because then we
02824             // don't know how much was lost!
02825             if( ( FECHIP[uChip].uUnsyncedEpochs < ( (fParam->uSyncCycleSize - 1)/2 + 1) ||
02826                   ( FECHIP[uChip].uUnsyncedEpochs == ( (fParam->uSyncCycleSize - 1)/2 + 1) && 
02827                     FECHIP[uChip].uLocalEpochNb > uMeanEpochNb)  ) && 
02828                 ( kFALSE == FECHIP[uChip].bDataLossSinceLastSync || 3 >= FECHIP[uChip].uUnsyncedEpochs ) && 
02829                 ( 0 == FECHIP[uChip].cAutomaticFakeSyncSinceLastSync || 3 >= FECHIP[uChip].uUnsyncedEpochs ) )
02830             {
02831                if( 0 == fParam->uSilentSyncMode )
02832                {
02833                   if( FECHIP[uChip].uUnsyncedEpochs == ( (fParam->uSyncCycleSize - 1)/2 + 1) )
02834                   {
02835                      Message(0,"After Eq -: chip %2d Local epoch %7d, cycle %6d, Unsynched Counts: %3d, Total Unsync %3d Mean %7d",
02836                                  uChip, FECHIP[uChip].uLocalEpochNb, FECHIP[uChip].uLocalEpochCycle, FECHIP[uChip].uUnsyncedEpochs,
02837                                  FECHIP[uChip].uUnsyncedEpochsSinceLastSync, uMeanEpochNb);
02838                      PrintLocalEpochIndexes( 0 );
02839                      PrintLocalEpochCycles( 0 );
02840                   }
02841                   else
02842                   {
02843                      Message(0,"Ignore block: chip %2d Local epoch %7d, cycle %6d, Unsynched Counts: %3d, Total Unsync %3d Nb auto %2d Test %2d Mean %2d",
02844                                  uChip, FECHIP[uChip].uLocalEpochNb, FECHIP[uChip].uLocalEpochCycle, FECHIP[uChip].uUnsyncedEpochs,
02845                                  FECHIP[uChip].uUnsyncedEpochsSinceLastSync, FECHIP[uChip].cAutomaticFakeSyncSinceLastSync,
02846                                  (Int_t)uMeanEpochNb - (Int_t)FECHIP[uChip].uLocalEpochNb, uMeanEpochNb);
02847                      PrintLocalEpochIndexes( 0 );
02848                      PrintLocalEpochCycles( 0 );
02849                   }
02850                }
02851                
02852                // Case where the invalid block is the 
02853                // first block after a cycle change
02854                Int_t iNbEpochToIgnore = 0;
02855                if( FECHIP[uChip].uUnsyncedEpochsSinceLastSync == FECHIP[uChip].uUnsyncedEpochs )
02856                   iNbEpochToIgnore = FECHIP[uChip].uUnsyncedEpochs + 1;
02857                   else if( 17 < (Int_t)uMeanEpochNb - (Int_t)FECHIP[uChip].uLocalEpochNb )
02858                      iNbEpochToIgnore = (Int_t)FECHIP[uChip].uLocalEpochNb - (Int_t)uMeanEpochNb;
02859                   else iNbEpochToIgnore = FECHIP[uChip].uUnsyncedEpochs + 1;
02860                   
02861                if( (Int_t)(FECHIP[uChip].uLocalEpochNb) < iNbEpochToIgnore )
02862                {
02863                   (FECHIP[uChip].uLocalEpochCycle)--;
02864                   FECHIP[uChip].uLocalEpochNb = fParam->uRocCycleSize
02865                                                  + FECHIP[uChip].uLocalEpochNb
02866                                                  - iNbEpochToIgnore ;
02867                }
02868                else if( fParam->uRocCycleSize < (FECHIP[uChip].uLocalEpochNb - iNbEpochToIgnore ) )
02869                {
02870                   (FECHIP[uChip].uLocalEpochCycle)++;
02871                   FECHIP[uChip].uLocalEpochNb = FECHIP[uChip].uLocalEpochNb - iNbEpochToIgnore
02872                                                               - fParam->uRocCycleSize;
02873                }
02874                else
02875                   FECHIP[uChip].uLocalEpochNb -= iNbEpochToIgnore;
02876                
02877                FECHIP[uChip].uUnsyncedEpochs = 0;
02878                FECHIP[uChip].uUnsyncedEpochsSinceLastSync = 0;
02879                FECHIP[uChip].bDataLossSinceLastSync = kFALSE;
02880                FECHIP[uChip].cAutomaticFakeSyncSinceLastSync = 0;
02881                
02882                FECHIP[uChip].uEpochMainClockSinceLastSync = 0;
02883                
02884                if( 0 == fParam->uSilentSyncMode )
02885                {
02886                   PrintLocalEpochIndexes( 1 );
02887                   PrintLocalEpochCycles( 1 );
02888                }
02889                   
02890                return kFALSE;
02891             } // if( FECHIP[uChip].uUnsyncedEpochs < ( (fParam->uSyncCycleSize - 1)/2 + 1) && kFALSE == FECHIP[uChip].bDataLossSinceLastSync )
02892             else
02893             {
02894                // Case where the invalid block is the 
02895                // first block after a cycle change
02896                if( (Int_t)(FECHIP[uChip].uLocalEpochNb) < ( (Int_t)FECHIP[uChip].uUnsyncedEpochs - (Int_t)(fParam->uSyncCycleSize - 1)))
02897                {
02898                   (FECHIP[uChip].uLocalEpochCycle)--;
02899                   FECHIP[uChip].uLocalEpochNb = fParam->uRocCycleSize + FECHIP[uChip].uLocalEpochNb
02900                                                  - ((Int_t)FECHIP[uChip].uUnsyncedEpochs - (Int_t)(fParam->uSyncCycleSize - 1)) ;
02901                }
02902                else if( fParam->uRocCycleSize <
02903                         (FECHIP[uChip].uLocalEpochNb - ( (Int_t)FECHIP[uChip].uUnsyncedEpochs - (Int_t)(fParam->uSyncCycleSize - 1) ) ) )
02904                {
02905                   (FECHIP[uChip].uLocalEpochCycle)++;
02906                   FECHIP[uChip].uLocalEpochNb = FECHIP[uChip].uLocalEpochNb 
02907                                                 - ((Int_t)FECHIP[uChip].uUnsyncedEpochs - (Int_t)(fParam->uSyncCycleSize - 1))
02908                                                 - fParam->uRocCycleSize;
02909                }
02910                else
02911                   FECHIP[uChip].uLocalEpochNb -= (Int_t)FECHIP[uChip].uUnsyncedEpochs - (Int_t)(fParam->uSyncCycleSize - 1);
02912                   
02913                if( 0 == fParam->uSilentSyncMode )
02914                {
02915                   PrintLocalEpochIndexes( 1 );
02916                   PrintLocalEpochCycles( 1 );
02917                }
02918             } // else of // if( FECHIP[uChip].uUnsyncedEpochs < ( (fParam->uSyncCycleSize - 1)/2 + 1) && kFALSE == FECHIP[uChip].bDataLossSinceLastSync )
02919          } // else of if(FECHIP[uChip].bValidEpochFlag[FECHIP[uChip].uCurrentMessagesBuffer])
02920          
02921          // Go to next buffers
02922          FECHIP[uChip].uCurrentMessagesBuffer = ( FECHIP[uChip].uCurrentMessagesBuffer + 1)%fParam->uNbBuffers;
02923          // clear buffer of previous "fParam->uSyncCycleSize" epochs (keep the last "fParam->uSyncCycleSize")
02924          (FECHIP[uChip].fCurrentEventMsg[FECHIP[uChip].uCurrentMessagesBuffer]).clear();
02925          (FECHIP[uChip].fCurrentUnprocessedMsg[FECHIP[uChip].uCurrentMessagesBuffer]).clear();
02926          // Save "fParam->uSyncCycleSize" Epoch block start
02927          if( 1 == fParam->uUseLocalEpochs)
02928          {
02929             FECHIP[uChip].uEpochStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uLocalEpochNb;
02930             FECHIP[uChip].uCycleStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uLocalEpochCycle;
02931          }
02932          else
02933          {
02934             FECHIP[uChip].uEpochStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uLastEpoch2;
02935             FECHIP[uChip].uCycleStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uRocEpochCycle;
02936          } // if( 1 == fParam->uUseLocalEpochs)
02937 
02938          // Reset the variable storing the total nb of messages
02939          // buffered at the end of last epoch
02940          // (Overkill, but safer)
02941          FECHIP[uChip].u_messageCountLastEpoch = 0;
02942          
02943          // the number of unsynced epochs is reseted here
02944          FECHIP[uChip].uUnsyncedEpochs = 0;
02945          FECHIP[uChip].uUnsyncedEpochsSinceLastSync = 0;
02946          FECHIP[uChip].bDataLossSinceLastSync = kFALSE;
02947          FECHIP[uChip].cAutomaticFakeSyncSinceLastSync = 0;
02948          
02949          FECHIP[uChip].uEpochMainClockSinceLastSync = 0;
02950       } // if ( bSyncFlag )
02951       else // of if ( bSyncFlag )
02952       {
02953          // If = CycleSize - 1 => should be a sync!
02954          // => will make it a bad epoch block without waiting for sync
02955          // => act immediatly as if a sync message was just lost
02956          if( (fParam->uSyncCycleSize - 1) == FECHIP[uChip].uUnsyncedEpochs )
02957          {
02958             // 1 more fake sync automatically generated
02959             if( kTRUE == FECHIP[uChip].bDataLossSinceLastSync )
02960                (FECHIP[uChip].cAutomaticFakeSyncSinceLastSync) ++;
02961             
02962                
02963             UInt_t uMeanEpoch = 0;
02964             UInt_t uNbActiveChips = 0;
02965             for( UInt_t uChipTemp = 0; uChipTemp < fParam->uNbFeets*2; uChipTemp++)
02966                if( uChipTemp != uChip && fParam->uGet4Active[ uChipTemp ])
02967                {
02968                   uMeanEpoch += FECHIP[uChipTemp].uLocalEpochCycle;
02969                   uNbActiveChips++;
02970                }
02971             if( 0 < uNbActiveChips )
02972                uMeanEpoch /= uNbActiveChips;
02973             if( 15 <  (Int_t)FECHIP[uChip].uLocalEpochCycle - (Int_t)uMeanEpoch )
02974             {
02975                Message(1, "Auto Sync with high epoch diff on chip %d", uChip);
02976                PrintLocalEpochIndexes( 1 );
02977                PrintLocalEpochCycles( 1 );
02978             }
02979                
02980             // Reject everything in fParam->uNbBlockJumpedReset epoch blocks
02981             // after a GET4 reset message has been received
02982             // 2*27µs + 37µs = ~100µs data thronw out
02983             if( FECHIP[uChip].bJumpEpochBlockAfterReset == kTRUE)
02984             {
02985                if( 0 == uEpochFirstSyncAfterReset && 0 == uCycleFirstSyncAfterReset)
02986                {
02987                   if( 1 == fParam->uUseLocalEpochs)
02988                   {
02989                      uEpochFirstSyncAfterReset = FECHIP[uChip].uLocalEpochNb;
02990                      uCycleFirstSyncAfterReset = FECHIP[uChip].uLocalEpochCycle;
02991                   }
02992                   else
02993                   {
02994                      uEpochFirstSyncAfterReset = FECHIP[uChip].uLastEpoch2;
02995                      uCycleFirstSyncAfterReset = FECHIP[uChip].uRocEpochCycle;
02996                   }
02997                }
02998                /*
02999                 * For now no check on Epoch cycle, should not matter with new version of
03000                 * ROC firmware!!!
03001                 */
03002                ULong64_t ulHighestStartEpoch = 0;
03003                ULong64_t ulLocalEpochHighestStart = 0;
03004                UInt_t    uBufferWithHighestStart = 0;
03005                UInt_t    uInterBufferWithHighestStart = 0;
03006                Bool_t    bTestFirstAfterReset = kTRUE;
03007                for ( UInt_t uChipTemp = 0; uChipTemp < fParam->uNbFeets * 2; uChipTemp++ )
03008                {
03009                   if( !fParam->uGet4Active[uChipTemp] )
03010                      continue;
03011                   if( 0 < FECHIP[uChipTemp].uNbEpochBlockAfterReset )
03012                   {
03013                      bTestFirstAfterReset = kFALSE;
03014                      break;
03015                   }
03016                   for( UInt_t uBufferTemp = 0; uBufferTemp < fParam->uNbBuffers; uBufferTemp ++)
03017                      if( ulHighestStartEpoch < FECHIP[uChipTemp].uEpochStart[uBufferTemp] )
03018                      {
03019                         ulHighestStartEpoch = FECHIP[uChipTemp].uEpochStart[uBufferTemp];
03020                         ulLocalEpochHighestStart = FECHIP[uChipTemp].uLocalEpochNb;
03021                         uBufferWithHighestStart = uBufferTemp;
03022                         uInterBufferWithHighestStart = FECHIP[uChipTemp].uCurrentMessageInterBuffer;
03023                      }
03024                }
03025                if( kTRUE == bTestFirstAfterReset )
03026                {
03027                   for ( UInt_t uChipTemp = 0; uChipTemp < fParam->uNbFeets * 2; uChipTemp++ )
03028                   {
03029                      if( !fParam->uGet4Active[uChipTemp] )
03030                         continue;
03031                      for( UInt_t uBufferTemp = 0; uBufferTemp < fParam->uNbBuffers; uBufferTemp ++)
03032                      {
03033                         if( FECHIP[uChipTemp].uEpochStart[uBufferTemp] < ulHighestStartEpoch )
03034                         {
03035                            (FECHIP[uChipTemp].fCurrentEventMsg)[uBufferTemp].clear();
03036                            (FECHIP[uChipTemp].fCurrentUnprocessedMsg[uBufferTemp]).clear();
03037                         }
03038                      }
03039 
03040                      FECHIP[uChipTemp].uCurrentMessagesBuffer = uBufferWithHighestStart;
03041                      FECHIP[uChipTemp].uCurrentMessageInterBuffer = uInterBufferWithHighestStart;
03042                      FECHIP[uChipTemp].uEpochStart[FECHIP[uChipTemp].uCurrentMessagesBuffer] = 0;
03043                      FECHIP[uChipTemp].uCycleStart[FECHIP[uChipTemp].uCurrentMessagesBuffer] = 0;
03044 
03045                      FECHIP[uChipTemp].uLocalEpochNb = ulLocalEpochHighestStart;
03046                   }
03047                }
03048 
03049                (FECHIP[uChip].uNbEpochBlockAfterReset)++;
03050                
03051                Message(0,"Throwing Epoch block for chip %2d because of GET4 reset: block %2d (Epoch %11d, local %11d, %11d %7d)",
03052                          uChip,FECHIP[uChip].uNbEpochBlockAfterReset,  FECHIP[uChip].uLastEpoch2, FECHIP[uChip].uLocalEpochNb,
03053                          uEpochFirstSyncAfterReset, uCycleFirstSyncAfterReset);
03054                
03055                if( 1 == fParam->uUseLocalEpochs)
03056                {
03057                   if( fParam->uNbBlockJumpedReset == FECHIP[uChip].uNbEpochBlockAfterReset)
03058                   {
03059                      FECHIP[uChip].bJumpEpochBlockAfterReset = kFALSE;
03060                      FECHIP[uChip].uNbEpochBlockAfterReset = 0;
03061                   }
03062                }
03063                   else if( ( uEpochFirstSyncAfterReset + (fParam->uNbBlockJumpedReset -1) * fParam->uSyncCycleSize
03064                               <= FECHIP[uChip].uLastEpoch2 ) ||
03065                       uCycleFirstSyncAfterReset < FECHIP[uChip].uRocEpochCycle )
03066                   {
03067                      FECHIP[uChip].bJumpEpochBlockAfterReset = kFALSE;
03068                      FECHIP[uChip].uNbEpochBlockAfterReset = 0;
03069                   }
03070                
03071                // clear the "fParam->uSyncCycleSize" epochs data message & epochs number buffers
03072                (FECHIP[uChip].fCurrentEventMsg[FECHIP[uChip].uCurrentMessagesBuffer]).clear();
03073                (FECHIP[uChip].fCurrentUnprocessedMsg[FECHIP[uChip].uCurrentMessagesBuffer]).clear();
03074                
03075                Int_t iNbEpochToIgnore = FECHIP[uChip].uUnsyncedEpochs + 1;
03076                   
03077                if( (Int_t)(FECHIP[uChip].uLocalEpochNb) < iNbEpochToIgnore )
03078                {
03079                   (FECHIP[uChip].uLocalEpochCycle)--;
03080                   FECHIP[uChip].uLocalEpochNb = fParam->uRocCycleSize
03081                                                  + FECHIP[uChip].uLocalEpochNb
03082                                                  - iNbEpochToIgnore ;
03083                }
03084                else if( fParam->uRocCycleSize < (FECHIP[uChip].uLocalEpochNb - iNbEpochToIgnore ) )
03085                {
03086                   (FECHIP[uChip].uLocalEpochCycle)++;
03087                   FECHIP[uChip].uLocalEpochNb = FECHIP[uChip].uLocalEpochNb - iNbEpochToIgnore
03088                                                               - fParam->uRocCycleSize;
03089                }
03090                else
03091                   FECHIP[uChip].uLocalEpochNb -= iNbEpochToIgnore;
03092                if( 1 == fParam->uUseLocalEpochs)
03093                {
03094                   FECHIP[uChip].uEpochStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uLocalEpochNb;
03095                   FECHIP[uChip].uCycleStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uLocalEpochCycle;
03096                }
03097                else
03098                {
03099                   FECHIP[uChip].uEpochStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uLastEpoch2;
03100                   FECHIP[uChip].uCycleStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uRocEpochCycle;
03101                }
03102 
03103                // Reset the variable storing the total nb of messages
03104                // buffered at the end of last epoch
03105                // (Overkill, but safer)
03106                FECHIP[uChip].u_messageCountLastEpoch = 0;
03107                
03108                // the number of unsynced epochs is reseted here
03109                FECHIP[uChip].uUnsyncedEpochs = 0;
03110                FECHIP[uChip].uUnsyncedEpochsSinceLastSync = 0;
03111                FECHIP[uChip].bDataLossSinceLastSync = kFALSE;
03112                FECHIP[uChip].cAutomaticFakeSyncSinceLastSync = 0;
03113                         
03114                FECHIP[uChip].uEpochMainClockSinceLastSync = 0;
03115 
03116                // Preparing modulo debug variables
03117                FECHIP[uChip].uModuloLastSynch = mesData->getEpoch2Number()%(fParam->uSyncCycleSize);
03118                FECHIP[uChip].uCycleLastSynch = FECHIP[uChip].uRocEpochCycle;
03119                
03120                // Goes on without doing anything else
03121                return kTRUE;
03122             } // if( FECHIP[uChip].bJumpEpochBlockAfterReset == kTRUE)
03123             
03124             if( 0 == fParam->uSilentSyncMode )
03125             {
03126                Message(2,"Automat Block chip: %2d in Roc Epoch: %7d Cycle %6d (Local ep %7d Cy %6d) Unsynched Counts: %3d Unsynch Total: %3d M Buffer %1d B Buffer %1d Loss %1d",
03127                            uChip, FECHIP[uChip].uLastEpoch2, FECHIP[uChip].uRocEpochCycle, FECHIP[uChip].uLocalEpochNb, 
03128                            FECHIP[uChip].uLocalEpochCycle, FECHIP[uChip].uUnsyncedEpochs, FECHIP[uChip].uUnsyncedEpochsSinceLastSync,
03129                            FECHIP[uChip].uCurrentMessagesBuffer, FECHIP[uChip].uCurrentMessageInterBuffer, FECHIP[uChip].bDataLossSinceLastSync);
03130                if(kTRUE == FECHIP[uChip].bDataLossSinceLastSync )
03131                {
03132                   Message(0,"After Loss: chip %2d Local epoch %7d, cycle %6d, Unsynched Counts: %3d, Total Unsync %3d Automat!!",
03133                               uChip, FECHIP[uChip].uLocalEpochNb, FECHIP[uChip].uLocalEpochCycle, FECHIP[uChip].uUnsyncedEpochs,
03134                               FECHIP[uChip].uUnsyncedEpochsSinceLastSync);
03135                   PrintLocalEpochIndexes( 0 );
03136                   PrintLocalEpochCycles( 0 );
03137                }
03138             }
03139                            
03140             // Add 1 to epoch index for the missing synched epoch
03141             (FECHIP[uChip].uLocalEpochNb)++;      
03142             // uLocalEpochNb contains the current epoch number
03143             if( FECHIP[uChip].uLocalEpochNb == fParam->uRocCycleSize)
03144             {
03145                (FECHIP[uChip].uLocalEpochCycle)++;
03146                FECHIP[uChip].uLocalEpochNb = 0;
03147             }
03148             else if( FECHIP[uChip].uLocalEpochNb > fParam->uRocCycleSize)
03149                cout<<"Problem!"<<endl;
03150             
03151             // This Epoch block is of course not valid!
03152             FECHIP[uChip].bValidEpochFlag[FECHIP[uChip].uCurrentMessagesBuffer] = kFALSE;
03153             
03154             // Analyse data from next buffer
03155             Bool_t bNextEpochValid = kFALSE;
03156             if( fParam->uNbBuffers - 1 == FECHIP[uChip].uCurrentMessagesBuffer) // index made a loop => next is 1st buffer
03157                bNextEpochValid = FECHIP[uChip].bValidEpochFlag[ 0 ];
03158                else bNextEpochValid = FECHIP[uChip].bValidEpochFlag[FECHIP[uChip].uCurrentMessagesBuffer + 1];
03159             
03160             FECHIP[uChip].bMessageInterBufferOk[ FECHIP[uChip].uCurrentMessageInterBuffer ] = kTRUE;
03161             
03162             if(bNextEpochValid == kTRUE)
03163             {
03164                (vMessageInterBuffer[ FECHIP[uChip].uCurrentMessageInterBuffer ]).insert(
03165                         (vMessageInterBuffer[ FECHIP[uChip].uCurrentMessageInterBuffer ]).end(),
03166                         (FECHIP[uChip].fCurrentEventMsg[ FECHIP[uChip].uCurrentMessageInterBuffer ]).begin(),
03167                         (FECHIP[uChip].fCurrentEventMsg[ FECHIP[uChip].uCurrentMessageInterBuffer ]).end());
03168                (vMessageInterBufferUnprocessed[ FECHIP[uChip].uCurrentMessageInterBuffer ]).insert(
03169                         (vMessageInterBufferUnprocessed[ FECHIP[uChip].uCurrentMessageInterBuffer ]).end(),
03170                         (FECHIP[uChip].fCurrentUnprocessedMsg[ FECHIP[uChip].uCurrentMessageInterBuffer ]).begin(),
03171                         (FECHIP[uChip].fCurrentUnprocessedMsg[ FECHIP[uChip].uCurrentMessageInterBuffer ]).end());
03172                FECHIP[uChip].fGet4MessValidEpochs->Fill( 
03173                      (FECHIP[uChip].fCurrentEventMsg[ FECHIP[uChip].uCurrentMessageInterBuffer ]).size() );
03174                (FECHIP[uChip].fCurrentEventMsg[ FECHIP[uChip].uCurrentMessageInterBuffer ]).clear();
03175                (FECHIP[uChip].fCurrentUnprocessedMsg[ FECHIP[uChip].uCurrentMessageInterBuffer ]).clear();
03176             }
03177 
03178             bTransferMessageNext = kTRUE;
03179             for( unsigned int uChipCheck = 0; uChipCheck < fParam->uNbFeets*2; uChipCheck++)
03180             {
03181                // two buffers solution
03182                if( FECHIP[uChipCheck].bMessageInterBufferOk[ FECHIP[uChip].uCurrentMessageInterBuffer ] == kFALSE 
03183                      && fParam->uGet4Active[ uChipCheck ])
03184                {
03185                   bTransferMessageNext = kFALSE;
03186                   break;
03187                }
03188             }
03189             if( bTransferMessageNext == kTRUE )
03190             {
03191                // Multiple buffers solution
03192                UInt_t uIndexNextInterMessBuff = 0;
03193                if( fParam->uNbBuffers - 1 == FECHIP[uChip].uCurrentMessageInterBuffer )
03194                   uIndexNextInterMessBuff = 0;
03195                   else uIndexNextInterMessBuff = FECHIP[uChip].uCurrentMessageInterBuffer + 1;
03196 
03197                if( kTRUE == fParam->noTrigger )
03198                   rocEvent->vMessageEventBuffer.insert( rocEvent->vMessageEventBuffer.end(),
03199                                     vMessageInterBuffer[ uIndexNextInterMessBuff ].begin(),
03200                                     vMessageInterBuffer[ uIndexNextInterMessBuff ].end() );
03201                else
03202                {
03203                   // TEST: attempt to make get4 processing compatible with trigger selection
03204                   rocEvent->fExtMessages.insert( rocEvent->fExtMessages.end(),
03205                                     vMessageInterBuffer[ uIndexNextInterMessBuff ].begin(),
03206                                     vMessageInterBuffer[ uIndexNextInterMessBuff ].end() );
03207                   (vUnprocessedMessages[uRocId]).insert((vUnprocessedMessages[uRocId]).end(),
03208                                  vMessageInterBufferUnprocessed[ uIndexNextInterMessBuff ].begin(),
03209                                  vMessageInterBufferUnprocessed[ uIndexNextInterMessBuff ].end() );
03210                }
03211                
03212                for( unsigned int uChipCheck = 0; uChipCheck < fParam->uNbFeets*2; uChipCheck++)
03213                {
03214                   FECHIP[uChipCheck].bStoredHitUnp = kFALSE;
03215                   FECHIP[uChipCheck].bMessageInterBufferOk[ FECHIP[uChip].uCurrentMessageInterBuffer ] = kFALSE;
03216                }
03217                (vMessageInterBuffer[ uIndexNextInterMessBuff ]).clear();
03218                (vMessageInterBufferUnprocessed[ uIndexNextInterMessBuff ]).clear();
03219             } // if( bTransferMessageNext == kTRUE )
03220             // Multiples buffers solution
03221             FECHIP[uChip].uCurrentMessageInterBuffer = (FECHIP[uChip].uCurrentMessageInterBuffer + 1)%fParam->uNbBuffers;
03222             
03223             // Go to next buffers
03224             FECHIP[uChip].uCurrentMessagesBuffer = ( FECHIP[uChip].uCurrentMessagesBuffer + 1)%fParam->uNbBuffers;
03225             // clear the "fParam->uSyncCycleSize" epochs data message & epochs number buffers (Should be already cleared but ...)
03226             (FECHIP[uChip].fCurrentEventMsg[FECHIP[uChip].uCurrentMessagesBuffer]).clear();
03227             (FECHIP[uChip].fCurrentUnprocessedMsg[FECHIP[uChip].uCurrentMessagesBuffer]).clear();
03228             
03229             // Save "fParam->uSyncCycleSize" Epoch block start
03230             if( 1 == fParam->uUseLocalEpochs)
03231             {
03232                FECHIP[uChip].uEpochStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uLocalEpochNb;
03233                FECHIP[uChip].uCycleStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uLocalEpochCycle;
03234             }
03235             else
03236             {
03237                FECHIP[uChip].uEpochStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uLastEpoch2;
03238                FECHIP[uChip].uCycleStart[FECHIP[uChip].uCurrentMessagesBuffer] = FECHIP[uChip].uRocEpochCycle;
03239             }
03240 
03241             // Reset the variable storing the total nb of messages
03242             // buffered at the end of last epoch
03243             // (Overkill, but safer)
03244             FECHIP[uChip].u_messageCountLastEpoch = 0;
03245             
03246             // the number of unsynced epochs is reseted here:
03247             // Goes to one in next lines because we have already one
03248             // epoch more on top of the missing synch
03249             FECHIP[uChip].uUnsyncedEpochs = 0;
03250             FECHIP[uChip].bDataLossSinceLastSync = kFALSE;
03251             
03252             FECHIP[uChip].uEpochMainClockSinceLastSync = 0;
03253          } // if( (fParam->uSyncCycleSize - 1) == FECHIP[uChip].uUnsyncedEpochs )
03254          
03255          (FECHIP[uChip].uUnsyncedEpochs)++;
03256          (FECHIP[uChip].uUnsyncedEpochsSinceLastSync)++;
03257       } // else of if ( bSyncFlag )
03258       
03259       // Update the variable storing the total nb of messages
03260       // buffered at the end of last epoch
03261       FECHIP[uChip].u_messageCountLastEpoch = (FECHIP[uChip].fCurrentEventMsg[FECHIP[uChip].uCurrentMessagesBuffer]).size();
03262          
03263    } // if ( uChip >= 0 && uChip < fParam->uNbFeets * 2 )
03264    else
03265    {  
03266          Message(3, "Error: Bad chip nb in Epoch message = %u", uChip);
03267          Message(3, " => This message will be skipped!!!! ");
03268          return kFALSE;
03269    }
03270 
03271    // Fill Histograms of valid epochs flags
03272    (FECHIP[uChip].fGet4ValidEpochs)->Fill(FECHIP[uChip].bValidEpochFlag[FECHIP[uChip].uCurrentMessagesBuffer]);
03273       
03274    return kTRUE;
03275 }
03276 /**********************************************************************/
03277 /*
03278  * This function process the data message when it is a GET4 data message
03279  */
03280 Bool_t TRocProc::ProcessGet4DataMessage(UInt_t uRocId, UInt_t uGet4IndexOffset, roc::Message* mesData)
03281 {
03282    // store it in the "fParam->uSyncCycleSize" epochs buffer
03283    // store also the corresponding epoch number
03284    // (for spacing & ToT measure)
03285    UInt_t uChip = mesData->getGet4Number() + uGet4IndexOffset;
03286       
03287    // Remap the Get4 chip index
03288    uChip = fParam->RemapGet4Chip(uChip);
03289 
03290    // SL: test if chip ID is inside valid range
03291    if (!fParam->IsValidGet4Chip(uChip)) {
03292       return kFALSE;
03293    }
03294 
03295    mesData->setGet4Number(uChip);
03296 
03297    // Test if chip is software disabled
03298    if( !fParam->uGet4Active[uChip] )
03299       return kFALSE;
03300 
03301    if ( !(uChip >= 0 && uChip < fParam->uNbFeets * 2) )
03302    {  
03303          cout << "Error: Bad chip nb in Epoch message = " << uChip << endl;
03304          cout << " => This message will be skipped!!!! "<<endl;
03305          return kFALSE;
03306    }
03307 
03308    TRocMessageExtended mTemp;
03309    UInt_t uTempRocEp = 0;
03310    UInt_t uTempRocCy = 0;
03311    UInt_t uTempLocEp = 0;
03312    UInt_t uTempLocCy = 0;
03313 
03314    if( fParam->uGet4EdgeInversion[uChip] == 1 )
03315       mesData->setGet4Edge( !( mesData->getGet4Edge() ) );
03316 
03317    uTempRocEp = FECHIP[uChip].uLastEpoch2;
03318 //   uTempRocEp = ROC[uRocId].fLastEpoch2[mesData->getGet4Number()];
03319    uTempRocCy = FECHIP[uChip].uRocEpochCycle;
03320    uTempLocEp = FECHIP[uChip].uLocalEpochNb;
03321    uTempLocCy = FECHIP[uChip].uLocalEpochCycle;
03322    mTemp.SetGet4MessageFull(*mesData, uTempRocEp, uTempRocCy, uTempLocEp, uTempLocCy, 1 == fParam->uUseLocalEpochs);
03323 
03324    // TEST: Modifications to adapt trigger selection to the GET4 processing
03325    if (fParam->noTrigger)
03326    {
03327       (FECHIP[uChip].fCurrentEventMsg[FECHIP[uChip].uCurrentMessagesBuffer]).push_back(mTemp);
03328 
03329       Int_t iIndexVector = (FECHIP[uChip].fCurrentEventMsg[FECHIP[uChip].uCurrentMessagesBuffer]).size() -1;
03330       if( (((FECHIP[uChip].fCurrentEventMsg[FECHIP[uChip].uCurrentMessagesBuffer]).at(iIndexVector)).GetRocMessage()).getMessageType()
03331           != roc::MSG_GET4 )
03332          Message(3, "Error 1 on %2u: this message is not a GET4 data: type %2u VS %2u VS %2u VS %2u",
03333            uChip, mesData->getMessageType(), (mTemp.GetRocMessage()).getMessageType(),
03334            (((FECHIP[uChip].fCurrentEventMsg[FECHIP[uChip].uCurrentMessagesBuffer]).back()).GetRocMessage()).getMessageType(),
03335            (((FECHIP[uChip].fCurrentEventMsg[FECHIP[uChip].uCurrentMessagesBuffer]).at(iIndexVector)).GetRocMessage()).getMessageType());
03336    } // if (fParam->noTrigger)
03337       else
03338       {
03339          Double_t dDiff = 0.;
03340          Bool_t bIsdiff = kFALSE;
03341 
03342          if(mTemp.GetFullTime() >= ROC[uRocId].fLastTriggerTm)
03343            dDiff = mTemp.GetFullTime() - ROC[uRocId].fLastTriggerTm;
03344          else
03345            dDiff = -1.0 * (ROC[uRocId].fLastTriggerTm - mTemp.GetFullTime());
03346 
03347          bIsdiff = kTRUE;
03348 
03349          if (ROC[uRocId].fHasNewTrigger)
03350          {
03351             Bool_t bIsInside(kFALSE), bAdd_to_unprocessed(kFALSE), bAdd_to_event(kFALSE);
03352 
03353             TGo4WinCond* cond = fParam->globalTrigger ? fGlobalTriggerWind : ROC[uRocId].fTriggerWind;
03354 
03355             mTemp.SetTriggerDeltaT(dDiff);
03356 
03357             if (cond->Test(dDiff))
03358             {
03359               bAdd_to_event = kTRUE;
03360               bIsInside = kTRUE;
03361             }
03362               else
03363               {
03364                  Double_t dRightdist = dDiff - cond->GetXUp();
03365                  //BEGIN NOT STRICTLY SORTED, 1 EVENT PER MBS CONTAINER, for fast online monitoring  JAM
03366                  // if hit far away on right side, event can be close for this ROC
03367                  if (dRightdist > 5000.) ROC[uRocId].fIsEventComplete = kTRUE;
03368                  if (dRightdist>0.)
03369                  {
03370                     if (ROC[uRocId].fStopSyncTm==0)
03371                        bAdd_to_unprocessed = kTRUE;
03372                        else
03373                        {
03374                           Double_t dDiff2 = 0;
03375                           if(mTemp.GetFullTime() >= ROC[uRocId].fStopSyncTm)
03376                              dDiff2 = mTemp.GetFullTime() - ROC[uRocId].fStopSyncTm;
03377                           else
03378                              dDiff2 = -1.0 * (ROC[uRocId].fStopSyncTm - mTemp.GetFullTime());
03379 
03380                           // only keep message if it have change to go into next event
03381                           bAdd_to_unprocessed = dDiff2 >= cond->GetXLow();
03382                        }
03383                  }
03384               } // else of if (cond->Test(diff))
03385 
03386             if ( bAdd_to_event )
03387             {
03388               (FECHIP[uChip].fCurrentEventMsg[ FECHIP[uChip].uCurrentMessagesBuffer ]).push_back(mTemp);
03389             }
03390 
03391             if (bAdd_to_unprocessed )
03392             {
03393               (FECHIP[uChip].fCurrentUnprocessedMsg[ FECHIP[uChip].uCurrentMessagesBuffer ]).push_back(mTemp);
03394             }
03395          } // if (ROC[uRocId].fHasNewTrigger)
03396             else
03397             {
03398                // if no new trigger was found up to now, we need to add message to unprocessed
03399                // at the end of the message we should check if unprocessed messages are still interesting
03400                (FECHIP[uChip].fCurrentUnprocessedMsg[ FECHIP[uChip].uCurrentMessagesBuffer ]).push_back(mTemp);
03401             } // else of if (ROC[uRocId].fHasNewTrigger)
03402 
03403          if (bIsdiff) {
03404                fDeltaTriggerTime->Fill(dDiff);
03405                ROC[uRocId].fTrigger_AllNX->Fill(dDiff);
03406                ROC[uRocId].fTrigger_AllNX_100->Fill(dDiff);
03407 
03408                unsigned g4 = mTemp.GetGet4Number();
03409                if (ROC[uRocId].fGet4Trigger[g4])
03410                   ROC[uRocId].fGet4Trigger[g4]->Fill(dDiff);
03411                if (ROC[uRocId].fGet4Trigger100[g4])
03412                   ROC[uRocId].fGet4Trigger100[g4]->Fill(dDiff);
03413          }
03414       }// else of if (fParam->noTrigger)
03415       
03416    // Control Histograms filling
03417    UInt_t uEdge        = mesData->getGet4Edge();
03418    UInt_t uChannel     = mesData->getGet4ChNum();
03419    UInt_t uFullChannel = uChip*4 + mesData->getGet4ChNum();
03420 
03421    if ( uEdge == 0 )
03422    {        
03423       fGet4RisEdgesNb->Fill( uFullChannel );
03424       if( 1 == fParam->uUseLocalEpochs)
03425       {
03426          fGet4EdgesDiffEvol->Fill( mTemp.GetLocalCycle(), uFullChannel, -1);
03427          fGet4RisEdgesEvol->Fill( mTemp.GetLocalCycle() );
03428       }
03429          else
03430          { 
03431             fGet4EdgesDiffEvol->Fill( mTemp.GetRocCycle(), uFullChannel, -1);
03432             fGet4RisEdgesEvol->Fill( mTemp.GetRocCycle() );
03433          }
03434       if( 1 == fParam->uDebugHistoOn )
03435       {
03436          (FECHIP[uChip].fGet4FineTimeLE)[uChannel]->Fill( mesData->getGet4Ts() % NB_BIN_GET4_FTS);
03437          if( 1 == fParam->uUseLocalEpochs)
03438             (FECHIP[uChip].fGet4RisEdgesNbEvol[uChannel])->Fill( mTemp.GetLocalCycle());
03439             else (FECHIP[uChip].fGet4RisEdgesNbEvol[uChannel])->Fill(mTemp.GetLocalCycle());
03440          (FECHIP[uChip].u_nbConsLE[uChannel])++;
03441          if( (FECHIP[uChip].u_nbConsTE[uChannel]) )
03442          {
03443             (FECHIP[uChip].fNbConsecutiveTE[uChannel])->Fill((FECHIP[uChip].u_nbConsTE[uChannel]));
03444             (FECHIP[uChip].u_nbConsTE[uChannel]) = 0;
03445          }
03446       }
03447    }
03448       else
03449       {
03450          fGet4FalEdgesNb->Fill( uFullChannel );
03451          if( 1 == fParam->uUseLocalEpochs)
03452          {
03453             fGet4EdgesDiffEvol->Fill( mTemp.GetLocalCycle(), uFullChannel, 1);
03454             fGet4FalEdgesEvol->Fill( mTemp.GetLocalCycle() );
03455          }
03456             else
03457             { 
03458                fGet4EdgesDiffEvol->Fill( mTemp.GetRocCycle(), uFullChannel, 1);
03459                fGet4FalEdgesEvol->Fill( mTemp.GetRocCycle() );
03460             }
03461             
03462          if( 1 == fParam->uDebugHistoOn )
03463          {
03464             (FECHIP[uChip].fGet4FineTimeTE[uChannel])->Fill( mesData->getGet4Ts() % NB_BIN_GET4_FTS);
03465             if( 1 == fParam->uUseLocalEpochs)
03466                (FECHIP[uChip].fGet4FalEdgesNbEvol[uChannel])->Fill(mTemp.GetLocalCycle());
03467                else (FECHIP[uChip].fGet4FalEdgesNbEvol[uChannel])->Fill(mTemp.GetRocCycle());
03468             (FECHIP[uChip].u_nbConsTE[uChannel])++;
03469             if( (FECHIP[uChip].u_nbConsLE[uChannel]) )
03470             {
03471             (FECHIP[uChip].fNbConsecutiveLE[uChannel])->Fill((FECHIP[uChip].u_nbConsLE[uChannel]));
03472             (FECHIP[uChip].u_nbConsLE[uChannel]) = 0;
03473             }
03474          } // if( 1 == fParam->uDebugHistoOn )
03475       }
03476       
03477    return kTRUE;
03478 }
03479 /**********************************************************************/
03480 /*
03481  * This function process the data message when it is a GET4 External Synch
03482  */
03483 Bool_t TRocProc::ProcessGet4ExtSyncMessage(UInt_t uGet4IndexOffset, roc::Message* mesData)
03484 {
03485    UChar_t uChip = mesData->getField(40, 8) + uGet4IndexOffset;
03486    // Remap the Get4 chip index
03487 
03488    uChip = fParam->RemapGet4Chip(uChip);
03489 
03490    // SL: test if chip ID is inside valid range
03491    if (!fParam->IsValidGet4Chip(uChip)) {
03492          cout << "Error: Bad chip nb in Epoch message = " << uChip << endl;
03493          cout << " => This message will be skipped!!!! "<<endl;
03494          return kFALSE;
03495    }
03496 
03497    // SL: FIXME: is it required??? message has different format here!!!
03498    mesData->setGet4Number(uChip);
03499 
03500    fGet4SynchChip->Fill( uChip );
03501    fGet4SynchPatt->Fill(uChip, (mesData->getSysMesData()) & 0x3f);
03502 
03503    // Store Ext sync messages from expected Get4 chips
03504    // as a "fake" last extra channel, which will always have
03505    // only a leading edge
03506    //~ if( uChip == 2 || uChip == 3)
03507    {
03508       TRocMessageExtended mTemp;
03509       mTemp.SetGet4MessageFull(*mesData, FECHIP[uChip].uLastEpoch2, FECHIP[uChip].uRocEpochCycle,
03510                                      FECHIP[uChip].uLocalEpochNb, FECHIP[uChip].uLocalEpochCycle,
03511                                      1 == fParam->uUseLocalEpochs);
03512       (FECHIP[uChip].fCurrentEventMsg[FECHIP[uChip].uCurrentMessagesBuffer]).push_back(mTemp);
03513       
03514       if( (((FECHIP[uChip].fCurrentEventMsg[FECHIP[uChip].uCurrentMessagesBuffer]).back()).GetRocMessage()).getMessageType() != roc::MSG_SYS )
03515          Message(3, "Error 1 on %2u: this message is not a SYNC data: type %2u VS %2uVS %2u", 
03516                  uChip, mesData->getMessageType(), (mTemp.GetRocMessage()).getMessageType(),
03517                  (((FECHIP[uChip].fCurrentEventMsg[FECHIP[uChip].uCurrentMessagesBuffer]).back()).GetRocMessage()).getMessageType());
03518    }
03519    
03520       
03521    return kTRUE;
03522 }
03523 /**********************************************************************/
03524 /*
03525  * This function order all data messages in the current message buffer
03526  * by time, using ths standard C++ vector/list functions 
03527  */
03528 Bool_t TRocProc::TimeOrderMessageBuffer( TRocData* rocToSort )
03529 {       
03530    if(0 == rocToSort->vMessageEventBuffer.size())
03531    {
03532       rocToSort->vMessageEventBuffer.clear();
03533       return kFALSE;
03534    }
03535 
03536    list<TRocMessageExtended> lSortingList;
03537    lSortingList.clear();
03538 
03539    // Insert all event from this Epoch in the list
03540    lSortingList.insert( lSortingList.begin(), rocToSort->vMessageEventBuffer.begin(),
03541                            rocToSort->vMessageEventBuffer.end() );
03542 
03543    // Sort the messages in the list
03544    lSortingList.sort( );
03545 
03546    rocToSort->vMessageEventBuffer.clear();
03547    rocToSort->vMessageEventBuffer.insert(rocToSort->vMessageEventBuffer.begin(),
03548                                  lSortingList.begin(),
03549                                  lSortingList.end() );
03550    
03551    // No check needed, we trust std C++ ?!?
03552    
03553    return kTRUE;
03554 }
03555 /**********************************************************************/
03556 
03557 Bool_t TRocProc::PrintRocEpochIndexes(Int_t uMessagePriority )
03558 {
03559    switch( fParam->uNbFeets )
03560    {
03561       case 1:
03562          Message(uMessagePriority,"Current ROC epoch indexes: %7d %7d ",
03563                   FECHIP[0].uLastEpoch2,  FECHIP[1].uLastEpoch2);
03564          break;
03565       case 2:
03566          Message(uMessagePriority,"Current ROC epoch indexes: %7d %7d %7d %7d ",
03567                   FECHIP[0].uLastEpoch2,  FECHIP[1].uLastEpoch2,  FECHIP[2].uLastEpoch2,  FECHIP[3].uLastEpoch2);
03568          break;
03569       case 3:
03570          Message(uMessagePriority,"Current ROC epoch indexes: %7d %7d %7d %7d %7d %7d ",
03571                   FECHIP[0].uLastEpoch2,  FECHIP[1].uLastEpoch2,  FECHIP[2].uLastEpoch2,  FECHIP[3].uLastEpoch2, FECHIP[4].uLastEpoch2,
03572                   FECHIP[5].uLastEpoch2);
03573          break;
03574       case 4:
03575          Message(uMessagePriority,"Current ROC epoch indexes: %7d %7d %7d %7d %7d %7d %7d %7d ",
03576                   FECHIP[0].uLastEpoch2,  FECHIP[1].uLastEpoch2,  FECHIP[2].uLastEpoch2,  FECHIP[3].uLastEpoch2, FECHIP[4].uLastEpoch2,
03577                   FECHIP[5].uLastEpoch2,  FECHIP[6].uLastEpoch2,  FECHIP[7].uLastEpoch2);
03578          break;
03579       case 5:
03580          Message(uMessagePriority,"Current ROC epoch indexes: %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d ",
03581                   FECHIP[0].uLastEpoch2,  FECHIP[1].uLastEpoch2,  FECHIP[2].uLastEpoch2,  FECHIP[3].uLastEpoch2, FECHIP[4].uLastEpoch2,
03582                   FECHIP[5].uLastEpoch2,  FECHIP[6].uLastEpoch2,  FECHIP[7].uLastEpoch2,  FECHIP[8].uLastEpoch2, FECHIP[9].uLastEpoch2);
03583          break;
03584       case 6:
03585          Message(uMessagePriority,"Current ROC epoch indexes: %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d ",
03586                   FECHIP[0].uLastEpoch2,  FECHIP[1].uLastEpoch2,  FECHIP[2].uLastEpoch2,  FECHIP[3].uLastEpoch2, FECHIP[4].uLastEpoch2,
03587                   FECHIP[5].uLastEpoch2,  FECHIP[6].uLastEpoch2,  FECHIP[7].uLastEpoch2,  FECHIP[8].uLastEpoch2, FECHIP[9].uLastEpoch2,
03588                   FECHIP[10].uLastEpoch2, FECHIP[11].uLastEpoch2);
03589          break;
03590       case 7:
03591          Message(uMessagePriority,"Current ROC epoch indexes: %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d ",
03592                   FECHIP[0].uLastEpoch2,  FECHIP[1].uLastEpoch2,  FECHIP[2].uLastEpoch2,  FECHIP[3].uLastEpoch2, FECHIP[4].uLastEpoch2,
03593                   FECHIP[5].uLastEpoch2,  FECHIP[6].uLastEpoch2,  FECHIP[7].uLastEpoch2,  FECHIP[8].uLastEpoch2, FECHIP[9].uLastEpoch2,
03594                   FECHIP[10].uLastEpoch2, FECHIP[11].uLastEpoch2, FECHIP[12].uLastEpoch2, FECHIP[13].uLastEpoch2);
03595          break;
03596       default:
03597          Message(uMessagePriority,"Current ROC epoch indexes: %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d (Limited to 7 first chips)",
03598                   FECHIP[0].uLastEpoch2,  FECHIP[1].uLastEpoch2,  FECHIP[2].uLastEpoch2,  FECHIP[3].uLastEpoch2, FECHIP[4].uLastEpoch2,
03599                   FECHIP[5].uLastEpoch2,  FECHIP[6].uLastEpoch2,  FECHIP[7].uLastEpoch2,  FECHIP[8].uLastEpoch2, FECHIP[9].uLastEpoch2,
03600                   FECHIP[10].uLastEpoch2, FECHIP[11].uLastEpoch2, FECHIP[12].uLastEpoch2, FECHIP[13].uLastEpoch2);
03601          break;
03602    }
03603    return kTRUE;
03604 }
03605 Bool_t TRocProc::PrintRocEpochCycles(Int_t uMessagePriority )
03606 {
03607    switch( fParam->uNbFeets )
03608    {
03609       case 1:
03610          Message(uMessagePriority,"Current ROC cycle indexes: %6d %6d ",
03611                   FECHIP[0].uRocEpochCycle,  FECHIP[1].uRocEpochCycle);
03612          break;
03613       case 2:
03614          Message(uMessagePriority,"Current ROC cycle indexes: %6d %6d %6d %6d ",
03615                   FECHIP[0].uRocEpochCycle,  FECHIP[1].uRocEpochCycle,  FECHIP[2].uRocEpochCycle,  FECHIP[3].uRocEpochCycle);
03616          break;
03617       case 3:
03618          Message(uMessagePriority,"Current ROC cycle indexes: %6d %6d %6d %6d %6d %6d ",
03619                   FECHIP[0].uRocEpochCycle,  FECHIP[1].uRocEpochCycle,  FECHIP[2].uRocEpochCycle,  FECHIP[3].uRocEpochCycle, 
03620                   FECHIP[4].uRocEpochCycle,  FECHIP[5].uRocEpochCycle);
03621          break;
03622       case 4:
03623          Message(uMessagePriority,"Current ROC cycle indexes: %6d %6d %6d %6d %6d %6d %6d %6d ",
03624                   FECHIP[0].uRocEpochCycle,  FECHIP[1].uRocEpochCycle,  FECHIP[2].uRocEpochCycle,  FECHIP[3].uRocEpochCycle,
03625                   FECHIP[4].uRocEpochCycle,  FECHIP[5].uRocEpochCycle,  FECHIP[6].uRocEpochCycle,  FECHIP[7].uRocEpochCycle);
03626          break;
03627       case 5:
03628          Message(uMessagePriority,"Current ROC cycle indexes: %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d ",
03629                   FECHIP[0].uRocEpochCycle,  FECHIP[1].uRocEpochCycle,  FECHIP[2].uRocEpochCycle,  FECHIP[3].uRocEpochCycle,
03630                   FECHIP[4].uRocEpochCycle,  FECHIP[5].uRocEpochCycle,  FECHIP[6].uRocEpochCycle,  FECHIP[7].uRocEpochCycle,
03631                   FECHIP[8].uRocEpochCycle, FECHIP[9].uRocEpochCycle);
03632          break;
03633       case 6:
03634          Message(uMessagePriority,"Current ROC cycle indexes: %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d ",
03635                   FECHIP[0].uRocEpochCycle,  FECHIP[1].uRocEpochCycle,  FECHIP[2].uRocEpochCycle,  FECHIP[3].uRocEpochCycle,
03636                   FECHIP[4].uRocEpochCycle,  FECHIP[5].uRocEpochCycle,  FECHIP[6].uRocEpochCycle,  FECHIP[7].uRocEpochCycle,  
03637                   FECHIP[8].uRocEpochCycle,  FECHIP[9].uRocEpochCycle,  FECHIP[10].uRocEpochCycle, FECHIP[11].uRocEpochCycle);
03638          break;
03639       case 7:
03640          Message(uMessagePriority,"Current ROC cycle indexes: %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d ",
03641                   FECHIP[0].uRocEpochCycle,  FECHIP[1].uRocEpochCycle,  FECHIP[2].uRocEpochCycle,  FECHIP[3].uRocEpochCycle, 
03642                   FECHIP[4].uRocEpochCycle,  FECHIP[5].uRocEpochCycle,  FECHIP[6].uRocEpochCycle,  FECHIP[7].uRocEpochCycle,
03643                   FECHIP[8].uRocEpochCycle,  FECHIP[9].uRocEpochCycle,  FECHIP[10].uRocEpochCycle, FECHIP[11].uRocEpochCycle, 
03644                   FECHIP[12].uRocEpochCycle, FECHIP[13].uRocEpochCycle);
03645          break;
03646       default:
03647          Message(uMessagePriority,"Current ROC cycle indexes: %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d (Limited to 7 first chips)",
03648                   FECHIP[0].uRocEpochCycle,  FECHIP[1].uRocEpochCycle,  FECHIP[2].uRocEpochCycle,  FECHIP[3].uRocEpochCycle, 
03649                   FECHIP[4].uRocEpochCycle,  FECHIP[5].uRocEpochCycle,  FECHIP[6].uRocEpochCycle,  FECHIP[7].uRocEpochCycle,
03650                   FECHIP[8].uRocEpochCycle,  FECHIP[9].uRocEpochCycle,  FECHIP[10].uRocEpochCycle, FECHIP[11].uRocEpochCycle, 
03651                   FECHIP[12].uRocEpochCycle, FECHIP[13].uRocEpochCycle);
03652          break;
03653    }
03654    return kTRUE;
03655 }
03656 Bool_t TRocProc::PrintLocalEpochIndexes(Int_t uMessagePriority )
03657 {
03658    switch( fParam->uNbFeets )
03659    {
03660       case 1:
03661          Message(uMessagePriority,"Current epoch indexes: %7d %7d ",
03662                   FECHIP[0].uLocalEpochNb,  FECHIP[1].uLocalEpochNb);
03663          break;
03664       case 2:
03665          Message(uMessagePriority,"Current epoch indexes: %7d %7d %7d %7d ",
03666                   FECHIP[0].uLocalEpochNb,  FECHIP[1].uLocalEpochNb,  FECHIP[2].uLocalEpochNb,  FECHIP[3].uLocalEpochNb);
03667          break;
03668       case 3:
03669          Message(uMessagePriority,"Current epoch indexes: %7d %7d %7d %7d %7d %7d ",
03670                   FECHIP[0].uLocalEpochNb,  FECHIP[1].uLocalEpochNb,  FECHIP[2].uLocalEpochNb,  FECHIP[3].uLocalEpochNb,
03671                   FECHIP[4].uLocalEpochNb,  FECHIP[5].uLocalEpochNb);
03672          break;
03673       case 4:
03674          Message(uMessagePriority,"Current epoch indexes: %7d %7d %7d %7d %7d %7d %7d %7d ",
03675                   FECHIP[0].uLocalEpochNb,  FECHIP[1].uLocalEpochNb,  FECHIP[2].uLocalEpochNb,  FECHIP[3].uLocalEpochNb, 
03676                   FECHIP[4].uLocalEpochNb,  FECHIP[5].uLocalEpochNb,  FECHIP[6].uLocalEpochNb,  FECHIP[7].uLocalEpochNb);
03677          break;
03678       case 5:
03679          Message(uMessagePriority,"Current epoch indexes: %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d ",
03680                   FECHIP[0].uLocalEpochNb,  FECHIP[1].uLocalEpochNb,  FECHIP[2].uLocalEpochNb,  FECHIP[3].uLocalEpochNb,
03681                   FECHIP[4].uLocalEpochNb,  FECHIP[5].uLocalEpochNb,  FECHIP[6].uLocalEpochNb,  FECHIP[7].uLocalEpochNb,
03682                   FECHIP[8].uLocalEpochNb,  FECHIP[9].uLocalEpochNb);
03683          break;
03684       case 6:
03685          Message(uMessagePriority,"Current epoch indexes: %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d ",
03686                   FECHIP[0].uLocalEpochNb,  FECHIP[1].uLocalEpochNb,  FECHIP[2].uLocalEpochNb,  FECHIP[3].uLocalEpochNb, 
03687                   FECHIP[4].uLocalEpochNb,  FECHIP[5].uLocalEpochNb,  FECHIP[6].uLocalEpochNb,  FECHIP[7].uLocalEpochNb, 
03688                   FECHIP[8].uLocalEpochNb,  FECHIP[9].uLocalEpochNb,  FECHIP[10].uLocalEpochNb, FECHIP[11].uLocalEpochNb);
03689          break;
03690       case 7:
03691          Message(uMessagePriority,"Current epoch indexes: %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d ",
03692                   FECHIP[0].uLocalEpochNb,  FECHIP[1].uLocalEpochNb,  FECHIP[2].uLocalEpochNb,  FECHIP[3].uLocalEpochNb,
03693                   FECHIP[4].uLocalEpochNb,  FECHIP[5].uLocalEpochNb,  FECHIP[6].uLocalEpochNb,  FECHIP[7].uLocalEpochNb,
03694                   FECHIP[8].uLocalEpochNb,  FECHIP[9].uLocalEpochNb,  FECHIP[10].uLocalEpochNb, FECHIP[11].uLocalEpochNb,
03695                   FECHIP[12].uLocalEpochNb, FECHIP[13].uLocalEpochNb);
03696          break;
03697       default:
03698          Message(uMessagePriority,"Current epoch indexes: %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d (Limited to 7 first chips)",
03699                   FECHIP[0].uLocalEpochNb,  FECHIP[1].uLocalEpochNb,  FECHIP[2].uLocalEpochNb,  FECHIP[3].uLocalEpochNb,
03700                   FECHIP[4].uLocalEpochNb,  FECHIP[5].uLocalEpochNb,  FECHIP[6].uLocalEpochNb,  FECHIP[7].uLocalEpochNb,
03701                   FECHIP[8].uLocalEpochNb,  FECHIP[9].uLocalEpochNb,  FECHIP[10].uLocalEpochNb, FECHIP[11].uLocalEpochNb,
03702                   FECHIP[12].uLocalEpochNb, FECHIP[13].uLocalEpochNb);
03703          break;
03704    }
03705    return kTRUE;
03706 }
03707 Bool_t TRocProc::PrintLocalEpochCycles(Int_t uMessagePriority )
03708 {
03709    switch( fParam->uNbFeets )
03710    {
03711       case 1:
03712          Message(uMessagePriority,"Current cycle indexes: %6d %6d ",
03713                   FECHIP[0].uLocalEpochCycle,  FECHIP[1].uLocalEpochCycle);
03714          break;
03715       case 2:
03716          Message(uMessagePriority,"Current cycle indexes: %6d %6d %6d %6d ",
03717                   FECHIP[0].uLocalEpochCycle,  FECHIP[1].uLocalEpochCycle,  FECHIP[2].uLocalEpochCycle,  FECHIP[3].uLocalEpochCycle);
03718          break;
03719       case 3:
03720          Message(uMessagePriority,"Current cycle indexes: %6d %6d %6d %6d %6d %6d ",
03721                   FECHIP[0].uLocalEpochCycle,  FECHIP[1].uLocalEpochCycle,  FECHIP[2].uLocalEpochCycle,  FECHIP[3].uLocalEpochCycle,
03722                   FECHIP[4].uLocalEpochCycle,  FECHIP[5].uLocalEpochCycle);
03723          break;
03724       case 4:
03725          Message(uMessagePriority,"Current cycle indexes: %6d %6d %6d %6d %6d %6d %6d %6d ",
03726                   FECHIP[0].uLocalEpochCycle,  FECHIP[1].uLocalEpochCycle,  FECHIP[2].uLocalEpochCycle,  FECHIP[3].uLocalEpochCycle,
03727                   FECHIP[4].uLocalEpochCycle,  FECHIP[5].uLocalEpochCycle,  FECHIP[6].uLocalEpochCycle,  FECHIP[7].uLocalEpochCycle);
03728          break;
03729       case 5:
03730          Message(uMessagePriority,"Current cycle indexes: %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d ",
03731                   FECHIP[0].uLocalEpochCycle,  FECHIP[1].uLocalEpochCycle,  FECHIP[2].uLocalEpochCycle,  FECHIP[3].uLocalEpochCycle,
03732                   FECHIP[4].uLocalEpochCycle,  FECHIP[5].uLocalEpochCycle,  FECHIP[6].uLocalEpochCycle,  FECHIP[7].uLocalEpochCycle,
03733                   FECHIP[8].uLocalEpochCycle,  FECHIP[9].uLocalEpochCycle);
03734          break;
03735       case 6:
03736          Message(uMessagePriority,"Current cycle indexes: %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d ",
03737                   FECHIP[0].uLocalEpochCycle,  FECHIP[1].uLocalEpochCycle,  FECHIP[2].uLocalEpochCycle,  FECHIP[3].uLocalEpochCycle,
03738                   FECHIP[4].uLocalEpochCycle,  FECHIP[5].uLocalEpochCycle,  FECHIP[6].uLocalEpochCycle,  FECHIP[7].uLocalEpochCycle,
03739                   FECHIP[8].uLocalEpochCycle,  FECHIP[9].uLocalEpochCycle,  FECHIP[10].uLocalEpochCycle, FECHIP[11].uLocalEpochCycle);
03740          break;
03741       case 7:
03742          Message(uMessagePriority,"Current cycle indexes: %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d ",
03743                   FECHIP[0].uLocalEpochCycle,  FECHIP[1].uLocalEpochCycle,  FECHIP[2].uLocalEpochCycle,  FECHIP[3].uLocalEpochCycle,
03744                   FECHIP[4].uLocalEpochCycle,  FECHIP[5].uLocalEpochCycle,  FECHIP[6].uLocalEpochCycle,  FECHIP[7].uLocalEpochCycle,
03745                   FECHIP[8].uLocalEpochCycle,  FECHIP[9].uLocalEpochCycle,  FECHIP[10].uLocalEpochCycle, FECHIP[11].uLocalEpochCycle,
03746                   FECHIP[12].uLocalEpochCycle, FECHIP[13].uLocalEpochCycle);
03747          break;
03748       default:
03749          Message(uMessagePriority,"Current cycle indexes: %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d (Limited to 7 first chips)",
03750                   FECHIP[0].uLocalEpochCycle,  FECHIP[1].uLocalEpochCycle,  FECHIP[2].uLocalEpochCycle,  FECHIP[3].uLocalEpochCycle,
03751                   FECHIP[4].uLocalEpochCycle,  FECHIP[5].uLocalEpochCycle,  FECHIP[6].uLocalEpochCycle,  FECHIP[7].uLocalEpochCycle,
03752                   FECHIP[8].uLocalEpochCycle,  FECHIP[9].uLocalEpochCycle,  FECHIP[10].uLocalEpochCycle, FECHIP[11].uLocalEpochCycle,
03753                   FECHIP[12].uLocalEpochCycle, FECHIP[13].uLocalEpochCycle);
03754          break;
03755    }
03756    return kTRUE;
03757 }
03758 Bool_t TRocProc::PrintUnsynchronizedEpochCount(Int_t uMessagePriority)
03759 {
03760    switch( fParam->uNbFeets )
03761    {
03762       case 1:
03763          Message(uMessagePriority,"Current unsynchronized count: %3d %3d ",
03764                   FECHIP[0].uUnsyncedEpochs,  FECHIP[1].uUnsyncedEpochs);
03765          break;
03766       case 2:
03767          Message(uMessagePriority,"Current unsynchronized count: %3d %3d %3d %3d ",
03768                   FECHIP[0].uUnsyncedEpochs,  FECHIP[1].uUnsyncedEpochs,  FECHIP[2].uUnsyncedEpochs,  FECHIP[3].uUnsyncedEpochs);
03769          break;
03770       case 3:
03771          Message(uMessagePriority,"Current unsynchronized count: %3d %3d %3d %3d %3d %3d ",
03772                   FECHIP[0].uUnsyncedEpochs,  FECHIP[1].uUnsyncedEpochs,  FECHIP[2].uUnsyncedEpochs,  FECHIP[3].uUnsyncedEpochs,
03773                   FECHIP[4].uUnsyncedEpochs,  FECHIP[5].uUnsyncedEpochs);
03774          break;
03775       case 4:
03776          Message(uMessagePriority,"Current unsynchronized count: %3d %3d %3d %3d %3d %3d %3d %3d ",
03777                   FECHIP[0].uUnsyncedEpochs,  FECHIP[1].uUnsyncedEpochs,  FECHIP[2].uUnsyncedEpochs,  FECHIP[3].uUnsyncedEpochs,
03778                   FECHIP[4].uUnsyncedEpochs,  FECHIP[5].uUnsyncedEpochs,  FECHIP[6].uUnsyncedEpochs,  FECHIP[7].uUnsyncedEpochs);
03779          break;
03780       case 5:
03781          Message(uMessagePriority,"Current unsynchronized count: %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d ",
03782                   FECHIP[0].uUnsyncedEpochs,  FECHIP[1].uUnsyncedEpochs,  FECHIP[2].uUnsyncedEpochs,  FECHIP[3].uUnsyncedEpochs,
03783                   FECHIP[4].uUnsyncedEpochs,  FECHIP[5].uUnsyncedEpochs,  FECHIP[6].uUnsyncedEpochs,  FECHIP[7].uUnsyncedEpochs,
03784                   FECHIP[8].uUnsyncedEpochs,  FECHIP[9].uUnsyncedEpochs);
03785          break;
03786       case 6:
03787          Message(uMessagePriority,"Current unsynchronized count: %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d ",
03788                   FECHIP[0].uUnsyncedEpochs,  FECHIP[1].uUnsyncedEpochs,  FECHIP[2].uUnsyncedEpochs,  FECHIP[3].uUnsyncedEpochs,
03789                   FECHIP[4].uUnsyncedEpochs,  FECHIP[5].uUnsyncedEpochs,  FECHIP[6].uUnsyncedEpochs,  FECHIP[7].uUnsyncedEpochs,
03790                   FECHIP[8].uUnsyncedEpochs,  FECHIP[9].uUnsyncedEpochs,  FECHIP[10].uUnsyncedEpochs, FECHIP[11].uUnsyncedEpochs);
03791          break;
03792       case 7:
03793          Message(uMessagePriority,"Current unsynchronized count: %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d ",
03794                   FECHIP[0].uUnsyncedEpochs,  FECHIP[1].uUnsyncedEpochs,  FECHIP[2].uUnsyncedEpochs,  FECHIP[3].uUnsyncedEpochs,
03795                   FECHIP[4].uUnsyncedEpochs,  FECHIP[5].uUnsyncedEpochs,  FECHIP[6].uUnsyncedEpochs,  FECHIP[7].uUnsyncedEpochs,
03796                   FECHIP[8].uUnsyncedEpochs,  FECHIP[9].uUnsyncedEpochs,  FECHIP[10].uUnsyncedEpochs, FECHIP[11].uUnsyncedEpochs,
03797                   FECHIP[12].uUnsyncedEpochs, FECHIP[13].uUnsyncedEpochs);
03798          break;
03799       default:
03800          Message(uMessagePriority,"Current unsynchronized count: %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d (Limited to 7 first chips)",
03801                   FECHIP[0].uUnsyncedEpochs,  FECHIP[1].uUnsyncedEpochs,  FECHIP[2].uUnsyncedEpochs,  FECHIP[3].uUnsyncedEpochs,
03802                   FECHIP[4].uUnsyncedEpochs,  FECHIP[5].uUnsyncedEpochs,  FECHIP[6].uUnsyncedEpochs,  FECHIP[7].uUnsyncedEpochs,
03803                   FECHIP[8].uUnsyncedEpochs,  FECHIP[9].uUnsyncedEpochs,  FECHIP[10].uUnsyncedEpochs, FECHIP[11].uUnsyncedEpochs,
03804                   FECHIP[12].uUnsyncedEpochs, FECHIP[13].uUnsyncedEpochs);
03805          break;
03806    }
03807    return kTRUE;
03808 }
03809 Bool_t TRocProc::PrintTotalUnsynchronizedEpochCount(Int_t uMessagePriority)
03810 {
03811    switch( fParam->uNbFeets )
03812    {
03813       case 1:
03814          Message(uMessagePriority,"Current total unsynchronized count: %3d %3d ",
03815                   FECHIP[0].uUnsyncedEpochsSinceLastSync,  FECHIP[1].uUnsyncedEpochsSinceLastSync);
03816          break;
03817       case 2:
03818          Message(uMessagePriority,"Current total unsynchronized count: %3d %3d %3d %3d ",
03819                   FECHIP[0].uUnsyncedEpochsSinceLastSync,  FECHIP[1].uUnsyncedEpochsSinceLastSync,  FECHIP[2].uUnsyncedEpochsSinceLastSync,
03820                   FECHIP[3].uUnsyncedEpochsSinceLastSync);
03821          break;
03822       case 3:
03823          Message(uMessagePriority,"Current total unsynchronized count: %3d %3d %3d %3d %3d %3d ",
03824                   FECHIP[0].uUnsyncedEpochsSinceLastSync,  FECHIP[1].uUnsyncedEpochsSinceLastSync,  FECHIP[2].uUnsyncedEpochsSinceLastSync,
03825                   FECHIP[3].uUnsyncedEpochsSinceLastSync,  FECHIP[4].uUnsyncedEpochsSinceLastSync,  FECHIP[5].uUnsyncedEpochsSinceLastSync);
03826          break;
03827       case 4:
03828          Message(uMessagePriority,"Current total unsynchronized count: %3d %3d %3d %3d %3d %3d %3d %3d ",
03829                   FECHIP[0].uUnsyncedEpochsSinceLastSync,  FECHIP[1].uUnsyncedEpochsSinceLastSync,  FECHIP[2].uUnsyncedEpochsSinceLastSync,
03830                   FECHIP[3].uUnsyncedEpochsSinceLastSync,  FECHIP[4].uUnsyncedEpochsSinceLastSync,  FECHIP[5].uUnsyncedEpochsSinceLastSync,
03831                   FECHIP[6].uUnsyncedEpochsSinceLastSync,  FECHIP[7].uUnsyncedEpochsSinceLastSync);
03832          break;
03833       case 5:
03834          Message(uMessagePriority,"Current total unsynchronized count: %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d ",
03835                   FECHIP[0].uUnsyncedEpochsSinceLastSync,  FECHIP[1].uUnsyncedEpochsSinceLastSync,  FECHIP[2].uUnsyncedEpochsSinceLastSync,
03836                   FECHIP[3].uUnsyncedEpochsSinceLastSync,  FECHIP[4].uUnsyncedEpochsSinceLastSync,  FECHIP[5].uUnsyncedEpochsSinceLastSync,
03837                   FECHIP[6].uUnsyncedEpochsSinceLastSync,  FECHIP[7].uUnsyncedEpochsSinceLastSync,  FECHIP[8].uUnsyncedEpochsSinceLastSync, 
03838                   FECHIP[9].uUnsyncedEpochsSinceLastSync);
03839          break;
03840       case 6:
03841          Message(uMessagePriority,"Current total unsynchronized count: %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d ",
03842                   FECHIP[0].uUnsyncedEpochsSinceLastSync,  FECHIP[1].uUnsyncedEpochsSinceLastSync,  FECHIP[2].uUnsyncedEpochsSinceLastSync,
03843                   FECHIP[3].uUnsyncedEpochsSinceLastSync,  FECHIP[4].uUnsyncedEpochsSinceLastSync,  FECHIP[5].uUnsyncedEpochsSinceLastSync,
03844                   FECHIP[6].uUnsyncedEpochsSinceLastSync,  FECHIP[7].uUnsyncedEpochsSinceLastSync,  FECHIP[8].uUnsyncedEpochsSinceLastSync,
03845                   FECHIP[9].uUnsyncedEpochsSinceLastSync,  FECHIP[10].uUnsyncedEpochsSinceLastSync, FECHIP[11].uUnsyncedEpochsSinceLastSync);
03846          break;
03847       case 7:
03848          Message(uMessagePriority,"Current total unsynchronized count: %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d ",
03849                   FECHIP[0].uUnsyncedEpochsSinceLastSync,  FECHIP[1].uUnsyncedEpochsSinceLastSync,  FECHIP[2].uUnsyncedEpochsSinceLastSync,
03850                   FECHIP[3].uUnsyncedEpochsSinceLastSync,  FECHIP[4].uUnsyncedEpochsSinceLastSync,  FECHIP[5].uUnsyncedEpochsSinceLastSync,
03851                   FECHIP[6].uUnsyncedEpochsSinceLastSync,  FECHIP[7].uUnsyncedEpochsSinceLastSync,  FECHIP[8].uUnsyncedEpochsSinceLastSync,
03852                   FECHIP[9].uUnsyncedEpochsSinceLastSync,  FECHIP[10].uUnsyncedEpochsSinceLastSync, FECHIP[11].uUnsyncedEpochsSinceLastSync,
03853                   FECHIP[12].uUnsyncedEpochsSinceLastSync, FECHIP[13].uUnsyncedEpochsSinceLastSync);
03854          break;
03855       default:
03856          Message(uMessagePriority,"Current total unsynchronized count: %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d (Limited to 7 first chips)",
03857                   FECHIP[0].uUnsyncedEpochsSinceLastSync,  FECHIP[1].uUnsyncedEpochsSinceLastSync,  FECHIP[2].uUnsyncedEpochsSinceLastSync,
03858                   FECHIP[3].uUnsyncedEpochsSinceLastSync,  FECHIP[4].uUnsyncedEpochsSinceLastSync,  FECHIP[5].uUnsyncedEpochsSinceLastSync,
03859                   FECHIP[6].uUnsyncedEpochsSinceLastSync,  FECHIP[7].uUnsyncedEpochsSinceLastSync,  FECHIP[8].uUnsyncedEpochsSinceLastSync,
03860                   FECHIP[9].uUnsyncedEpochsSinceLastSync,  FECHIP[10].uUnsyncedEpochsSinceLastSync, FECHIP[11].uUnsyncedEpochsSinceLastSync,
03861                   FECHIP[12].uUnsyncedEpochsSinceLastSync, FECHIP[13].uUnsyncedEpochsSinceLastSync);
03862          break;
03863    }
03864    return kTRUE;
03865 }
03866 Bool_t TRocProc::PrintMessageBufferIndexes(Int_t uMessagePriority )
03867 {
03868    switch( fParam->uNbFeets )
03869    {
03870       case 1:
03871          Message(uMessagePriority,"Current Mess Buff : %1d %1d ",
03872                   FECHIP[0].uCurrentMessagesBuffer,  FECHIP[1].uCurrentMessagesBuffer);
03873          break;
03874       case 2:
03875          Message(uMessagePriority,"Current Mess Buff : %1d %1d %1d %1d ",
03876                   FECHIP[0].uCurrentMessagesBuffer,  FECHIP[1].uCurrentMessagesBuffer,  FECHIP[2].uCurrentMessagesBuffer,
03877                   FECHIP[3].uCurrentMessagesBuffer);
03878          break;
03879       case 3:
03880          Message(uMessagePriority,"Current Mess Buff : %1d %1d %1d %1d %1d %1d ",
03881                   FECHIP[0].uCurrentMessagesBuffer,  FECHIP[1].uCurrentMessagesBuffer,  FECHIP[2].uCurrentMessagesBuffer,
03882                   FECHIP[3].uCurrentMessagesBuffer,  FECHIP[4].uCurrentMessagesBuffer,  FECHIP[5].uCurrentMessagesBuffer);
03883          break;
03884       case 4:
03885          Message(uMessagePriority,"Current Mess Buff : %1d %1d %1d %1d %1d %1d %1d %1d ",
03886                   FECHIP[0].uCurrentMessagesBuffer,  FECHIP[1].uCurrentMessagesBuffer,  FECHIP[2].uCurrentMessagesBuffer,
03887                   FECHIP[3].uCurrentMessagesBuffer,  FECHIP[4].uCurrentMessagesBuffer,  FECHIP[5].uCurrentMessagesBuffer,
03888                   FECHIP[6].uCurrentMessagesBuffer,  FECHIP[7].uCurrentMessagesBuffer);
03889          break;
03890       case 5:
03891          Message(uMessagePriority,"Current Mess Buff : %1d %1d %1d %1d %1d %1d %1d %1d %1d %1d ",
03892                   FECHIP[0].uCurrentMessagesBuffer,  FECHIP[1].uCurrentMessagesBuffer,  FECHIP[2].uCurrentMessagesBuffer,
03893                   FECHIP[3].uCurrentMessagesBuffer,  FECHIP[4].uCurrentMessagesBuffer,  FECHIP[5].uCurrentMessagesBuffer,
03894                   FECHIP[6].uCurrentMessagesBuffer,  FECHIP[7].uCurrentMessagesBuffer,  FECHIP[8].uCurrentMessagesBuffer,
03895                   FECHIP[9].uCurrentMessagesBuffer);
03896          break;
03897       case 6:
03898          Message(uMessagePriority,"Current Mess Buff : %1d %1d %1d %1d %1d %1d %1d %1d %1d %1d %1d %1d ",
03899                   FECHIP[0].uCurrentMessagesBuffer,  FECHIP[1].uCurrentMessagesBuffer,  FECHIP[2].uCurrentMessagesBuffer,
03900                   FECHIP[3].uCurrentMessagesBuffer,  FECHIP[4].uCurrentMessagesBuffer,  FECHIP[5].uCurrentMessagesBuffer,
03901                   FECHIP[6].uCurrentMessagesBuffer,  FECHIP[7].uCurrentMessagesBuffer,  FECHIP[8].uCurrentMessagesBuffer,
03902                   FECHIP[9].uCurrentMessagesBuffer,  FECHIP[10].uCurrentMessagesBuffer, FECHIP[11].uCurrentMessagesBuffer);
03903          break;
03904       case 7:
03905          Message(uMessagePriority,"Current Mess Buff : %1d %1d %1d %1d %1d %1d %1d %1d %1d %1d %1d %1d %1d %1d ",
03906                   FECHIP[0].uCurrentMessagesBuffer,  FECHIP[1].uCurrentMessagesBuffer,  FECHIP[2].uCurrentMessagesBuffer,
03907                   FECHIP[3].uCurrentMessagesBuffer,  FECHIP[4].uCurrentMessagesBuffer,  FECHIP[5].uCurrentMessagesBuffer,
03908                   FECHIP[6].uCurrentMessagesBuffer,  FECHIP[7].uCurrentMessagesBuffer,  FECHIP[8].uCurrentMessagesBuffer,
03909                   FECHIP[9].uCurrentMessagesBuffer,  FECHIP[10].uCurrentMessagesBuffer, FECHIP[11].uCurrentMessagesBuffer,
03910                   FECHIP[12].uCurrentMessagesBuffer, FECHIP[13].uCurrentMessagesBuffer);
03911          break;
03912       default:
03913          Message(uMessagePriority,"Current Mess Buff : %1d %1d %1d %1d %1d %1d %1d %1d %1d %1d %1d %1d %1d %1d (Limited to 7 first chips)",
03914                   FECHIP[0].uCurrentMessagesBuffer,  FECHIP[1].uCurrentMessagesBuffer,  FECHIP[2].uCurrentMessagesBuffer,
03915                   FECHIP[3].uCurrentMessagesBuffer,  FECHIP[4].uCurrentMessagesBuffer,  FECHIP[5].uCurrentMessagesBuffer,
03916                   FECHIP[6].uCurrentMessagesBuffer,  FECHIP[7].uCurrentMessagesBuffer,  FECHIP[8].uCurrentMessagesBuffer,
03917                   FECHIP[9].uCurrentMessagesBuffer,  FECHIP[10].uCurrentMessagesBuffer, FECHIP[11].uCurrentMessagesBuffer,
03918                   FECHIP[12].uCurrentMessagesBuffer, FECHIP[13].uCurrentMessagesBuffer);
03919          break;
03920    }
03921    return kTRUE;
03922 }
03923 Bool_t TRocProc::PrintMessageBufferSizes(Int_t uMessagePriority )
03924 {
03925    for(UInt_t uBufferTestIndex = 0; uBufferTestIndex < fParam->uNbBuffers ; uBufferTestIndex++)
03926       {
03927       switch( fParam->uNbFeets )
03928       {
03929          case 1:
03930             Message(uMessagePriority,"Mess Buff %1d Size  : %4d %4d ", uBufferTestIndex,
03931                      FECHIP[0].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[1].fCurrentEventMsg[uBufferTestIndex].size());
03932             break;
03933          case 2:
03934             Message(uMessagePriority,"Mess Buff %1d Size  : %4d %4d %4d %4d ", uBufferTestIndex,
03935                      FECHIP[0].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[1].fCurrentEventMsg[uBufferTestIndex].size(),  
03936                      FECHIP[2].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[3].fCurrentEventMsg[uBufferTestIndex].size());
03937             break;
03938          case 3:
03939             Message(uMessagePriority,"Mess Buff %1d Size  : %4d %4d %4d %4d %4d %4d ", uBufferTestIndex,
03940                      FECHIP[0].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[1].fCurrentEventMsg[uBufferTestIndex].size(),
03941                      FECHIP[2].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[3].fCurrentEventMsg[uBufferTestIndex].size(),
03942                      FECHIP[4].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[5].fCurrentEventMsg[uBufferTestIndex].size());
03943             break;
03944          case 4:
03945             Message(uMessagePriority,"Mess Buff %1d Size  : %4d %4d %4d %4d %4d %4d %4d %4d ", uBufferTestIndex,
03946                      FECHIP[0].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[1].fCurrentEventMsg[uBufferTestIndex].size(),
03947                      FECHIP[2].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[3].fCurrentEventMsg[uBufferTestIndex].size(),
03948                      FECHIP[4].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[5].fCurrentEventMsg[uBufferTestIndex].size(),
03949                      FECHIP[6].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[7].fCurrentEventMsg[uBufferTestIndex].size());
03950             break;
03951          case 5:
03952             Message(uMessagePriority,"Mess Buff %1d Size  : %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d ", uBufferTestIndex,
03953                      FECHIP[0].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[1].fCurrentEventMsg[uBufferTestIndex].size(),
03954                      FECHIP[2].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[3].fCurrentEventMsg[uBufferTestIndex].size(),
03955                      FECHIP[4].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[5].fCurrentEventMsg[uBufferTestIndex].size(),
03956                      FECHIP[6].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[7].fCurrentEventMsg[uBufferTestIndex].size(),
03957                      FECHIP[8].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[9].fCurrentEventMsg[uBufferTestIndex].size());
03958             break;
03959          case 6:
03960             Message(uMessagePriority,"Mess Buff %1d Size  : %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d ", uBufferTestIndex,
03961                      FECHIP[0].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[1].fCurrentEventMsg[uBufferTestIndex].size(),
03962                      FECHIP[2].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[3].fCurrentEventMsg[uBufferTestIndex].size(),
03963                      FECHIP[4].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[5].fCurrentEventMsg[uBufferTestIndex].size(),
03964                      FECHIP[6].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[7].fCurrentEventMsg[uBufferTestIndex].size(),
03965                      FECHIP[8].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[9].fCurrentEventMsg[uBufferTestIndex].size(),
03966                      FECHIP[10].fCurrentEventMsg[uBufferTestIndex].size(), FECHIP[11].fCurrentEventMsg[uBufferTestIndex].size());
03967             break;
03968          case 7:
03969             Message(uMessagePriority,"Mess Buff %1d Size  : %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d ", uBufferTestIndex,
03970                      FECHIP[0].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[1].fCurrentEventMsg[uBufferTestIndex].size(),
03971                      FECHIP[2].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[3].fCurrentEventMsg[uBufferTestIndex].size(),
03972                      FECHIP[4].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[5].fCurrentEventMsg[uBufferTestIndex].size(),
03973                      FECHIP[6].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[7].fCurrentEventMsg[uBufferTestIndex].size(),
03974                      FECHIP[8].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[9].fCurrentEventMsg[uBufferTestIndex].size(),
03975                      FECHIP[10].fCurrentEventMsg[uBufferTestIndex].size(), FECHIP[11].fCurrentEventMsg[uBufferTestIndex].size(),
03976                      FECHIP[12].fCurrentEventMsg[uBufferTestIndex].size(), FECHIP[13].fCurrentEventMsg[uBufferTestIndex].size());
03977             break;
03978          default:
03979             Message(uMessagePriority,"Mess Buff %1d Size  : %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d (Limited to 7 first chips)",
03980                      uBufferTestIndex,
03981                      FECHIP[0].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[1].fCurrentEventMsg[uBufferTestIndex].size(),
03982                      FECHIP[2].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[3].fCurrentEventMsg[uBufferTestIndex].size(),
03983                      FECHIP[4].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[5].fCurrentEventMsg[uBufferTestIndex].size(),
03984                      FECHIP[6].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[7].fCurrentEventMsg[uBufferTestIndex].size(),
03985                      FECHIP[8].fCurrentEventMsg[uBufferTestIndex].size(),  FECHIP[9].fCurrentEventMsg[uBufferTestIndex].size(),
03986                      FECHIP[10].fCurrentEventMsg[uBufferTestIndex].size(), FECHIP[11].fCurrentEventMsg[uBufferTestIndex].size(),
03987                      FECHIP[12].fCurrentEventMsg[uBufferTestIndex].size(), FECHIP[13].fCurrentEventMsg[uBufferTestIndex].size());
03988             break;
03989       }
03990    }
03991    return kTRUE;
03992 }

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