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

beamtime/tof-tdctest/go4/GET4V10/TGet4v1Proc.cxx (r4864/r4862)

Go to the documentation of this file.
00001 #include "TGet4v1Proc.h"
00002 
00003 #include "TGo4Version.h"
00004 #if __GO4BUILDVERSION__ > 40502
00005 #include "go4iostream.h"
00006 #else
00007 #include "Riostream.h"
00008 #endif
00009 
00010 #include "TH1.h"
00011 #include "TH2.h"
00012 #include "TTimeStamp.h"
00013 #include "TROOT.h"
00014 #include "TSystem.h"
00015 #include "TLatex.h"
00016 
00017 #include "TGet4v1Param.h"
00018 #include "TGo4MbsEvent.h"
00019 #include "TGo4WinCond.h"
00020 #include "TGo4Log.h"
00021 #include "TGo4Version.h"
00022 
00023 #include "roc/Message.h"
00024 #include "roc/Board.h"
00025 
00026 #include <algorithm>
00027 
00028 // enable this define for "online" mode with only one aux trigger per input buffer analyzed
00029 // if disabled, may process up to TGet4v1Param::maxBufferTriggers per buffer (only offline mode with no lost samples!)
00030 #define ROC_SINGLETRIGGERMODE 1
00031 
00032 TGet4v1Proc::TGet4v1Proc() :
00033    TCBMBeamtimeProc(),
00034    fOutputEvent(0),
00035    fIsTimeSorted(kFALSE),
00036    fHasNewGlobalTrigger(kFALSE)
00037 {
00038 }
00039 
00040 //***********************************************************
00041 TGet4v1Proc::~TGet4v1Proc()
00042 {
00043    TGo4Log::Info("TGet4v1Proc: Test ");
00044    ROC.clear();
00045    TGo4Log::Info("TGet4v1Proc: Delete instance ");
00046 }
00047 
00048 //***********************************************************
00049 // this one is used in standard factory
00050 TGet4v1Proc::TGet4v1Proc(const char* name) :
00051    TCBMBeamtimeProc(name),
00052    fOutputEvent(0),
00053    fIsTimeSorted(kFALSE),
00054    fHasNewGlobalTrigger(kFALSE)
00055 {
00056    TGo4Log::Info("TGet4v1Proc: Create instance %s", name);
00057 
00058    // SL TODO: after next go4 release change uncomment usage of setup macro
00059    fParam = (TGet4v1Param *) MakeParameter("Get4v1Par", "TGet4v1Param" /*, "set_RocPar.C" */);
00060 
00061    fLastRateTm = TTimeStamp().AsDouble();
00062    fTotaldatasize = 0;
00063    fRate = 0.;
00064 
00065    // here we optionally override parameter values with setup macro, if existing:
00066    TString setupmacro = "set_Get4v1Par.C";
00067    if (!gSystem->AccessPathName(setupmacro.Data())) {
00068       TGo4Log::Info("Executing ROC parameter setup script %s", setupmacro.Data());
00069       gROOT->ProcessLine(Form(".x %s", setupmacro.Data()));
00070       // need to copy parameter setup to static event array,
00071       // when restored from Autosave file, executed in UpdateFrom method
00072       fParam->SetConfigRocs();
00073    } else {
00074       TGo4Log::Info("NO ROC parameter setup script %s. Use previous values!", setupmacro.Data());
00075    }
00076 
00077    fParam->PrintGet4Options();
00078    if (fParam->numRocs > MAX_ROC) fParam->numRocs = MAX_ROC;
00079    if (fParam->uNbGet4 > MAX_GET4) fParam->uNbGet4 = MAX_GET4;
00080 
00081    for (unsigned n=0; n < fParam->numRocs;n++) {
00082       ROC.push_back(TGet4v1Rec());
00083       ROC[n].fRocId = n;
00084    }
00085    fEvntSize = MakeTH1('I', "ROCs/EvntSize", "Number of messages in event",
00086          250, 1., 2000.);
00087 
00088    fEvtPerProc= MakeTH1('I', "SubEventsPerProc", "Number of subevents per Proc index",
00089          64, 0., 64);
00090 
00091    fMsgsPerRoc = MakeTH1('I', "ROCs/MsgsPerRoc", "Number of messages per ROC",
00092          fParam->numRocs, 0., fParam->numRocs);
00093 
00094    fTriggerPerRoc = MakeTH1('I', "ROCs/TriggersPerRoc", "Number of Trigger messages per ROC",
00095          fParam->numRocs, 0., fParam->numRocs);
00096 
00097    fDeltaTriggerTime = MakeTH1('I', "ROCs/TriggerDeltaTime", "Corrected hits time difference of all ROCs",
00098          5000, -5000., 5000., "Delta t");
00099 
00100    for( UInt_t  uRoc =0; uRoc<fParam->numRocs; uRoc++ )
00101    {
00102       // do not build histograms for non-used ROC
00103       if (!fParam->IsActiveRoc(uRoc)) continue;
00104 
00105       char folder[30];
00106       sprintf(folder,"ROC%u/",uRoc);
00107 
00108       ROC[uRoc].fMsgTypes = MakeTH1('I', Form("%sMsgTypes%u", folder, uRoc),
00109             Form("ROC%u Distribution of messages types", uRoc),
00110             8, 0., 8.);
00111 
00112       if (IsObjMade()) {
00113          ROC[uRoc].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_NOP, "NOP");
00114          ROC[uRoc].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_HIT, "HIT");
00115          ROC[uRoc].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_EPOCH, "EPOCH");
00116          ROC[uRoc].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_SYNC, "SYNC");
00117          ROC[uRoc].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_AUX, "AUX");
00118          ROC[uRoc].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_EPOCH2, "EPOCH2");
00119          ROC[uRoc].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_GET4, "GET4");
00120          ROC[uRoc].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_SYS, "SYS");
00121       }
00122 
00123       ROC[uRoc].fSysTypes = MakeTH1('I', Form("%sSysTypes%u", folder, uRoc),
00124             Form("ROC%u Distribution of system messages", uRoc),
00125             roc::SYSMSG_GET4_EVENT+1, 0., roc::SYSMSG_GET4_EVENT+1);
00126 
00127       if (IsObjMade()) {
00128          ROC[uRoc].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_DAQ_START,  "DAQ_START");
00129          ROC[uRoc].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_DAQ_FINISH, "DAQ_FINISH");
00130          ROC[uRoc].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_NX_PARITY,  "NX_PARITY");
00131          ROC[uRoc].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_SYNC_PARITY,"SYNC_PARITY");
00132          ROC[uRoc].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_DAQ_RESUME, "DAQ_RESUME");
00133          ROC[uRoc].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_FIFO_RESET, "FIFO_RESET");
00134          ROC[uRoc].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_USER,       "USER_MSG");
00135          ROC[uRoc].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_PCTIME,     "PCTIME");
00136          ROC[uRoc].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_ADC,        "ADC");
00137          ROC[uRoc].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_PACKETLOST, "PACKETLOST");
00138          ROC[uRoc].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_GET4_EVENT, "GET4_EVENT");
00139       }
00140 
00141       ROC[uRoc].fSysUserTypes = MakeTH1('I', Form("%sSysUserTypes%u", folder, uRoc),
00142             Form("ROC%u Distribution of user messages", uRoc),
00143             8, 7., 15.);
00144       if (IsObjMade()) {
00145          ROC[uRoc].fSysUserTypes->GetXaxis()->SetBinLabel(roc::SYSMSG_USER_CALIBR_ON - 6, "CALIBR_ON");
00146          ROC[uRoc].fSysUserTypes->GetXaxis()->SetBinLabel(roc::SYSMSG_USER_CALIBR_OFF - 6, "CALIBR_OFF");
00147          ROC[uRoc].fSysUserTypes->GetXaxis()->SetBinLabel(roc::SYSMSG_USER_RECONFIGURE - 6, "RECONFIGURE");
00148       }
00149 
00150       ROC[uRoc].fAUXch = MakeTH1('I', Form("%sRoc%u_aux_chs", folder, uRoc),
00151             "Number events per aux channel",
00152             8, 0., 8.);
00153 
00154       ROC[uRoc].fTrigger_All = MakeTH1('I', Form("%sRoc%u_Trigger", folder, uRoc),
00155             Form("Time difference between all hits and last trigger signal on ROC%u", uRoc),
00156             5000, -1000., 4000.);
00157       ROC[uRoc].fTrigger_All_100 = MakeTH1('I', Form("%sRoc%u_Trigger_100", folder, uRoc),
00158             Form("Time difference between all hits and last trigger signal on ROC%u", uRoc),
00159             50005, -100000., 1e6);
00160       ROC[uRoc].fTrigger_All_us = MakeTH1('I', Form("%sRoc%u_Trigger_us", folder, uRoc),
00161             Form("Time difference between all hits and last trigger signal on ROC%u", uRoc),
00162             1000, -1000., 999.*1e3);
00163       ROC[uRoc].fTrigger_All_ms = MakeTH1('I', Form("%sRoc%u_Trigger_ms", folder, uRoc),
00164             Form("Time difference between all hits and last trigger signal on ROC%u", uRoc),
00165             1000, -1e6, 999*1e6);
00166       ROC[uRoc].fTrigger_All_s = MakeTH1('I', Form("%sRoc%u_Trigger_s", folder, uRoc),
00167             Form("Time difference between all hits and last trigger signal on ROC%u", uRoc),
00168             1000, -1e9, 999*1e9);
00169 
00170       ROC[uRoc].fTrigger_AUX = MakeTH1('I', Form("%sRoc%u_Trigger_AUX", folder, uRoc),
00171             Form("Time difference between all AUXs and last trigger signal on ROC%u", uRoc),
00172             5000, -5000., 5000.);
00173 
00174       ROC[uRoc].fEvntMultipl = MakeTH1('I', Form("%sRoc%u_Multiplicity", folder, uRoc),
00175             Form("Event multiplicity for ROC%u in time window", uRoc),
00176             16, 0., 16.);
00177 
00178       ROC[uRoc].fALLt = MakeTH1('I', Form("%sRoc%u_ALL_t", folder,uRoc), Form("Time distribution of ALL signals on ROC%u", uRoc),
00179             36000, 0., 3600.,"s");
00180 
00181       ROC[uRoc].fDATAt = MakeTH1('I', Form("%sRoc%u_DATA_t", folder,uRoc), Form("Time distribution of DATA hits on ROC%u", uRoc),
00182             36000, 0., 3600.,"s");
00183 
00184       ROC[uRoc].fERRORt = MakeTH1('I', Form("%sRoc%u_ERROR_t", folder,uRoc), Form("Time distribution of ERROR signals on ROC%u", uRoc),
00185             36000, 0., 3600.,"s");
00186 
00187       ROC[uRoc].fSLOWCt = MakeTH1('I', Form("%sRoc%u_SLOWC_t", folder,uRoc), Form("Time distribution of SLOW CONTROL signals on ROC%u", uRoc),
00188             36000, 0., 3600.,"s");
00189 
00190       ROC[uRoc].fSelfTriggT = MakeTH1('I', Form("%sRoc%u_SelfTrigg_t", folder,uRoc), Form("Time distribution of self triggers on ROC%u", uRoc),
00191             36000, 0., 3600.,"s");
00192 
00193       ROC[uRoc].fEPOCHt = MakeTH1('I', Form("%sRoc%u_EPOCH_t", folder,uRoc), Form("Time distribution of Epochs on ROC%u", uRoc),
00194             36000, 0., 3600.,"s");
00195 
00196       ROC[uRoc].fAllSelectedT = MakeTH1('I', Form("%sRoc%u_AllSel_t", folder,uRoc), Form("Time distribution of all selected hits on ROC%u", uRoc),
00197             36000, 0., 3600.,"s");
00198 
00199       for (unsigned nsync=0; nsync<MAX_SYNC; nsync++)
00200          ROC[uRoc].fSYNCt[nsync] = MakeTH1('I', Form("%sRoc%u_Sync%u_t", folder, uRoc, nsync),
00201                Form("Time distribution of SYNC%u signal on ROC%u", nsync, uRoc),
00202                36000, 0., 3600.,"s");
00203 
00204       for (unsigned naux=0; naux<MAX_AUX; naux++)
00205          ROC[uRoc].fAUXt[naux] = MakeTH1('I', Form("%sRoc%u_Aux%u_t", folder, uRoc, naux),
00206                Form("Time distribution of AUX%u signal on ROC%u", naux, uRoc),
00207                36000, 0., 3600.,"s");
00208 
00209       // Long duration time distribution (1 min. bin, 10 days length)
00210       if( kTRUE == fParam->bLongTimeHistos )
00211       {
00212          ROC[uRoc].fAllLongT = MakeTH1('I', Form("%sLong/Roc%u_All_lt", folder,uRoc), Form("Time distribution of ALL signals on ROC%u", uRoc),
00213                14400, 0., 240.,"t [h]");
00214 
00215          ROC[uRoc].fDataLongT = MakeTH1('I', Form("%sLong/Roc%u_Data_lt", folder,uRoc), Form("Time distribution of DATA hits on ROC%u", uRoc),
00216                14400, 0., 240.,"t [h]");
00217 
00218          ROC[uRoc].fErrorLongT = MakeTH1('I', Form("%sLong/Roc%u_Error_lt", folder,uRoc), Form("Time distribution of ERROR signals on ROC%u", uRoc),
00219                14400, 0., 240.,"t [h]");
00220 
00221          ROC[uRoc].fSlowCLongT = MakeTH1('I', Form("%sLong/Roc%u_Slowc_lt", folder,uRoc), Form("Time distribution of SLOW CONTROL signals on ROC%u", uRoc),
00222                14400, 0., 240.,"t [h]");
00223 
00224          ROC[uRoc].fSelfTriggLongT = MakeTH1('I', Form("%sLong/Roc%u_SelfTrigg_lt", folder,uRoc), Form("Time distribution of self triggers on ROC%u", uRoc),
00225                14400, 0., 240.,"t [h]");
00226 
00227          ROC[uRoc].fEpochLongT = MakeTH1('I', Form("%sLong/Roc%u_Epoch_lt", folder,uRoc), Form("Time distribution of Epochs on ROC%u", uRoc),
00228                14400, 0., 240.,"t [h]");
00229 
00230          ROC[uRoc].fAllEpoch2LongT = MakeTH1('I', Form("%sLong/Roc%u_AllEp2_lt", folder,uRoc), Form("Time distribution of all epoch2 on ROC%u", uRoc),
00231                14400, 0., 240.,"t [h]");
00232 
00233          ROC[uRoc].fAllSelLongT = MakeTH1('I', Form("%sLong/Roc%u_AllSel_lt", folder,uRoc), Form("Time distribution of all selected hits on ROC%u", uRoc),
00234                14400, 0., 240.,"t [h]");
00235 
00236          for (unsigned nsync=0; nsync<MAX_SYNC; nsync++)
00237             ROC[uRoc].fSyncLongT[nsync] = MakeTH1('I', Form("%sLong/Roc%u_Sync%u_lt", folder, uRoc, nsync),
00238                   Form("Time distribution of SYNC%u signal on ROC%u", nsync, uRoc),
00239                   14400, 0., 240.,"t [h]");
00240       } // if( kTRUE == fParam->bLongTimeHistos )
00241 
00243       uNbEvents[uRoc]        = 0;
00244       uFirstEventIndex[uRoc] = 0;
00245       uPrevEventIndex[uRoc]  = 0;
00246 
00247       // Real events counters
00248       uEventInsideMbsEvtCount[uRoc] = 0;
00249       uRealEventsCount[uRoc] = 0;
00250       uNotEmptyEventInsideMbsEvtCount[uRoc] = 0;
00251       uNotEmptyRealEventsCount[uRoc] = 0;
00252 
00253       ROC[uRoc].fTriggerWind = MakeWinCond(Form("Roc%u_EventWindow",uRoc),
00254             485., 885., ROC[uRoc].fTrigger_All->GetName());
00255 
00256       ROC[uRoc].fAUXWind = MakeWinCond(Form("Roc%u_AUXWindow",uRoc),
00257             -100., 100., ROC[uRoc].fTrigger_AUX->GetName());
00258 
00259       for( Int_t iGet4 = 0; iGet4 < MAX_GET4_PER_ROC; iGet4++)
00260       {
00261          char folderGet4[30];
00262          sprintf(folderGet4,"%sGet4_%u/",folder, iGet4);
00263          UInt_t uRemappedGet4Index = fParam->RemapGet4Chip(uRoc, iGet4);
00264          if( kTRUE == fParam->IsValidGet4Chip(uRemappedGet4Index) &&
00265              kTRUE == fParam->IsActiveGet4Chip(uRemappedGet4Index) )
00266          {
00267             ROC[uRoc].fEPOCH2t[iGet4] = MakeTH1('I', Form("%sRoc%u_EPOCH2_t_%d", folder,uRoc, iGet4),
00268                   Form("Time distribution of GET4 Epochs on ROC%u Get4 %d", uRoc, iGet4),
00269                   36000, 0., 3600.,"s");
00270             for( Int_t iGet4Chan = 0; iGet4Chan < NB_CHAN_GET4; iGet4Chan++)
00271             {
00272                ROC[uRoc].fSelectedT[iGet4][iGet4Chan] = MakeTH1('I', Form("%sRoc%u_Selected_t_%d_Ch%d", folderGet4,uRoc, iGet4, iGet4Chan),
00273                      Form("Time distribution of selected hits on ROC%u Get4 %d Channel %d", uRoc, iGet4, iGet4Chan),
00274                      36000, 0., 3600.,"s");
00275             
00276                ROC[uRoc].fTrigger_Get4Channel[iGet4][iGet4Chan] =
00277                      MakeTH1('I', Form("%sRoc%u_Get%d_Ch%d_Trigger",
00278                                     folderGet4, uRoc, iGet4, iGet4Chan),
00279                               Form("Time difference between all hits on GET4 %d Channel %d and last trigger signal on ROC%u; [ns]",
00280                                     iGet4, iGet4Chan, uRoc),
00281                               10000, -5000., 5000.);
00282                ROC[uRoc].fTriggerMs_Get4Channel[iGet4][iGet4Chan] =
00283                      MakeTH1('I', Form("%sRoc%u_Get%d_Ch%d_TriggerMs",
00284                                     folderGet4, uRoc, iGet4, iGet4Chan),
00285                               Form("Time difference between all hits on GET4 %d Channel %d and last trigger signal on ROC%u; [ns]",
00286                                     iGet4, iGet4Chan, uRoc),
00287                               20000, -100*1e3, 100*1e3);
00288                ROC[uRoc].fTriggerS_Get4Channel[iGet4][iGet4Chan] =
00289                      MakeTH1('I', Form("%sRoc%u_Get%d_Ch%d_TriggerS",
00290                                     folderGet4, uRoc, iGet4, iGet4Chan),
00291                               Form("Time difference between all hits on GET4 %d Channel %d and last trigger signal on ROC%u; [ns]",
00292                                     iGet4, iGet4Chan, uRoc),
00293                               20000, -100*1e9, 1900*1e9);
00294 
00295                /*
00296                 * Debug Histograms for GET4 v1.x
00297                 */
00298                if( 1 == fParam->bTotHistoEnable )
00299                   ROC[uRoc].fTot[iGet4][iGet4Chan] =
00300                         MakeTH1('I', Form("%sTot/Roc%u_Get%d_Ch%d_Tot",
00301                               folderGet4, uRoc, iGet4, iGet4Chan),
00302                         Form("Tot for channel %d in chip %d on ROC %d", iGet4Chan, iGet4, uRoc),
00303                         1200, -25, 59975, "Tot [ps]", "Counts [1]" );
00304                if( 1 == fParam->bDebugHistoEnable )
00305                {
00306                   ROC[uRoc].fLeadingFTS[iGet4][iGet4Chan] =
00307                         MakeTH1('I',
00308                               Form("%sFTS_L/Roc%u_Get%d_Ch%d_FTS_Leading",
00309                                     folderGet4, uRoc, iGet4, iGet4Chan),
00310                               Form("FTS of Leading edge of channel %d in chip %d on ROC %d",
00311                                     iGet4Chan, iGet4, uRoc),
00312                               NB_BIN_GET4_FTS, 0., NB_BIN_GET4_FTS);
00313                   ROC[uRoc].fTrailingFTS[iGet4][iGet4Chan] =
00314                         MakeTH1('I',
00315                               Form("%sFTS_T/Roc%u_Get%d_Ch%d_FTS_Trailing",
00316                                     folderGet4, uRoc, iGet4, iGet4Chan),
00317                               Form("FTS of Trailing edge of channel %d in chip %d on ROC %d",
00318                                     iGet4Chan, iGet4, uRoc),
00319                               NB_BIN_GET4_FTS, 0., NB_BIN_GET4_FTS);
00320                   ROC[uRoc].fLeadingDnl[iGet4][iGet4Chan] =
00321                         MakeTH1('D',
00322                               Form("%sDnl_L/Roc%u_Get%d_Ch%d_Dnl_Leading",
00323                                     folderGet4, uRoc, iGet4, iGet4Chan),
00324                               Form("DNL of Leading edge of channel %d in chip %d on ROC %d",
00325                                     iGet4Chan, iGet4, uRoc),
00326                               NB_BIN_GET4_FTS, -0.5, NB_BIN_GET4_FTS-0.5);
00327                   ROC[uRoc].fLeadingDnlSum[iGet4][iGet4Chan] =
00328                         MakeTH1('D',
00329                               Form("%sDnlInt_L/Roc%u_Get%d_Ch%d_DnlSum_Leading",
00330                                     folderGet4, uRoc, iGet4, iGet4Chan),
00331                               Form("DNL Integral of Leading edge of channel %d in chip %d on ROC %d",
00332                                     iGet4Chan, iGet4, uRoc),
00333                               NB_BIN_GET4_FTS, -0.5, NB_BIN_GET4_FTS-0.5);
00334                   ROC[uRoc].fTrailingDnl[iGet4][iGet4Chan] =
00335                         MakeTH1('D',
00336                               Form("%sDnl_T/Roc%u_Get%d_Ch%d_Dnl_Trailing",
00337                                     folderGet4, uRoc, iGet4, iGet4Chan),
00338                               Form("DNL of Trailing edge of channel %d in chip %d on ROC %d",
00339                                     iGet4Chan, iGet4, uRoc),
00340                               NB_BIN_GET4_FTS, -0.5, NB_BIN_GET4_FTS-0.5);
00341                   ROC[uRoc].fTrailingDnlSum[iGet4][iGet4Chan] =
00342                         MakeTH1('D',
00343                               Form("%sDnlInt_T/Roc%u_Get%d_Ch%d_DnlSum_Trailing",
00344                                     folderGet4, uRoc, iGet4, iGet4Chan),
00345                               Form("DNL Integral of Trailing edge of channel %d in chip %d on ROC %d",
00346                                     iGet4Chan, iGet4, uRoc),
00347                               NB_BIN_GET4_FTS, -0.5, NB_BIN_GET4_FTS-0.5);
00348                } // if( 1 == fParam->bDebugHistoEnable )
00349 
00350                // Event statistics
00351                if( kTRUE == fParam->bChannelRateHistoEnable )
00352                   ROC[uRoc].fChannelRateEvolution[iGet4][iGet4Chan] = MakeTH1('I',
00353                         Form("%sRateCh/Roc%u_Get%d_Ch%d_RateEvolution",
00354                               folderGet4, uRoc, iGet4, iGet4Chan),
00355                         Form("Time distribution of hits of channel %d in chip %d on ROC %d",
00356                               iGet4Chan, iGet4, uRoc),
00357                         36000, 0., 7200.,"Time [s]", "(Nb hits)/(bin size in s) []");
00358 
00359             } // for( Int_t iGet4Chan = 0; iGet4Chan < NB_CHAN_GET4; iGet4Chan++)
00360 
00361             // Event statistics
00362             if( kTRUE == fParam->bChipRateHistoEnable )
00363             {
00364                ROC[uRoc].fChipRateEvolution[iGet4] = MakeTH1('I',
00365                      Form("%sRoc%u_Get%d_RateEvolution",
00366                            folderGet4, uRoc, iGet4 ),
00367                      Form("Time distribution of hits for all channels of chip %d on ROC %d",
00368                            iGet4, uRoc),
00369                      36000, 0., 7200.,"Time [s]", "(Nb hits)/(bin size in s) []");
00370                ROC[uRoc].fdRateEvolutionBinSize = ROC[uRoc].fChipRateEvolution[iGet4]->GetBinWidth( 1 );
00371             } // if( kTRUE == fParam->bChipRateHistoEnable )
00372             ROC[uRoc].fuNbHitsChipEpoch[iGet4] = 0;
00373 
00374             // Epochs
00375             ROC[uRoc].fEpochShiftsDuration[iGet4] = MakeTH2('I',
00376                   Form("%sRoc%u_Get%d_EpochShiftsDuration",
00377                         folderGet4, uRoc, iGet4 ),
00378                   Form("Time distribution of hits for all channels of chip %d on ROC %d",
00379                         iGet4, uRoc),
00380                   52, -26., 26.,
00381                   5000, 0., 5000.,
00382                   "Shift [GET4 epochs]", "Duration [GET4 epochs]");
00383          } // if remapped chip is valid and active
00384       } // for( Int_t iGet4 = 0; iGet4 < MAX_GET4_PER_ROC; iGet4++)
00385       ROC[uRoc].fDistribEpochs = MakeTH1( 'I', Form("%sRoc%u_DistribEpochs", folder, uRoc),
00386             "Distribution of epoch counter value for 250MHz epoch messages",
00387             MAIN_EPOCH_CYCLE_SIZE/100000, 0, MAIN_EPOCH_CYCLE_SIZE,
00388             "Value of Local Epoch Cnt []", "Counts []" );
00389       ROC[uRoc].fDistribEpochs2 = MakeTH2( 'I', Form("%sRoc%u_DistribEpochs2", folder, uRoc),
00390             "Distribution of epoch counter value for Roc epoch messages",
00391             MAX_GET4_PER_ROC, -0.5, MAX_GET4_PER_ROC -0.5,
00392             GET4_EPOCH_CYCLE_SIZE/100000, 0, GET4_EPOCH_CYCLE_SIZE,
00393             "chip []", "Value of Roc Epoch Cnt []", "Counts []" );
00394       ROC[uRoc].fEpochShiftsPerChip = MakeTH2( 'I', Form("%sRoc%u_EpochShiftsPerChip", folder, uRoc),
00395             "Value of shift in Epochs when non consecutive epoch index are detected, per chip",
00396             MAX_GET4_PER_ROC, -0.5, MAX_GET4_PER_ROC -0.5,
00397             512, -256, 256,
00398             "chip []", "Epoch indec Shift in GET4 epochs []", "Counts []" );
00399       ROC[uRoc].fEpochShiftsDurationPerChip = MakeTH2('I',
00400             Form("%sRoc%u_EpochShiftsDurationPerChip", folder, uRoc ),
00401             Form("Duration of epoch shifts for all chips on ROC %d", uRoc),
00402             MAX_GET4_PER_ROC, -0.5, MAX_GET4_PER_ROC -0.5,
00403             5000, 0., 5000.,
00404             "chip []", "Duration [GET4 epochs]");
00405 
00406       ROC[uRoc].fNbEventsPerMbsEvent = MakeTH1( 'I', Form("%sRoc%u_EventsCount", folder, uRoc),
00407             "Nb of detected events per Mbs event",
00408             50, 0, 50 ,
00409             "# Events []", "Counts []" );
00410       ROC[uRoc].fNbNotEmptyEventsPerMbsEvent = MakeTH1( 'I', Form("%sRoc%u_NotEmptyEvtCount", folder, uRoc),
00411             "Nb of detected events per Mbs event",
00412             50, 0, 50 ,
00413             "# Events []", "Counts []" );
00414       ROC[uRoc].fChannelsMapping = MakeTH2( 'I', Form("%sRoc%u_ChanMap", folder, uRoc),
00415             "Events with both channels present",
00416             NB_CHAN_GET4*MAX_GET4_PER_ROC, 0, MAX_GET4_PER_ROC ,
00417             NB_CHAN_GET4*MAX_GET4_PER_ROC, 0, MAX_GET4_PER_ROC ,
00418             "1st channel []", "2nd channel []", "Counts []" );
00419       ROC[uRoc].fChannelMultiplicity = MakeTH2( 'I', Form("%sRoc%u_ChanMul", folder, uRoc),
00420             "Channel multiplicity per event",
00421             NB_CHAN_GET4*MAX_GET4_PER_ROC, 0, MAX_GET4_PER_ROC ,
00422             20, 0, 20,
00423             "Channel []", "# Hits []", "events []" );
00424 
00425       if( kTRUE ==  fParam->bFreeStreaming && 0 < fParam->uNbTriggers )
00426       {
00427          ROC[uRoc].fDataSelfTriggerPerEvent = MakeTH2( 'I', Form("%sRoc%u_DataSelfTrigg", folder, uRoc),
00428                "Channel multiplicity per event",
00429                50, 0, 50 ,
00430                fParam->uNbTriggers, 0, fParam->uNbTriggers,
00431                "# Triggers/event []", "Trigger index[]", "events []" );
00432 
00433          ROC[uRoc].fDataSelfTrigDistanceNs  = MakeTH2('I', Form("%sRoc%u_DataTrigDistanceNs", folder, uRoc),
00434                "Time difference since last trigger from data ROC",
00435                1002, -2., 1000.,
00436                fParam->uNbTriggers, 0, fParam->uNbTriggers,
00437                " [ns]", "Trigger index[]", "events []" );
00438          ROC[uRoc].fDataSelfTrigDistanceUs   = MakeTH2('I', Form("%sRoc%u_DataTrigDistanceUs", folder, uRoc),
00439                "Time difference since last trigger from data ROC",
00440                999, 1., 1000.,
00441                fParam->uNbTriggers, 0, fParam->uNbTriggers,
00442                " [us]", "Trigger index[]", "events []" );
00443          ROC[uRoc].fDataSelfTrigDistanceMs   = MakeTH2('I', Form("%sRoc%u_DataTrigDistanceMs", folder, uRoc),
00444                "Time difference since last trigger from data ROC",
00445                999, 1., 1000.,
00446                fParam->uNbTriggers, 0, fParam->uNbTriggers,
00447                " [ms]", "Trigger index[]", "events []" );
00448          ROC[uRoc].fDataSelfTrigDistanceS    = MakeTH2('I', Form("%sRoc%u_DataTrigDistanceS", folder, uRoc),
00449                "Time difference since last trigger from data ROC",
00450                999, 1., 1000.,
00451                fParam->uNbTriggers, 0, fParam->uNbTriggers,
00452                " [s]", "Trigger index[]", "events []" );
00453       }
00454 
00455       // Error messages
00456       ROC[uRoc].fGet4ErrorChip = MakeTH1('I', Form("%sRoc%u_Get4ErrorChip", folder, uRoc),
00457                               "Get4 chip sending Error message",
00458                               fParam->uNbGet4, -0.5, fParam->uNbGet4 -0.5, "Error Chip","Entries [1]");
00459       ROC[uRoc].fGet4ErrorChan = MakeTH2('I', Form("%sRoc%u_Get4ErrorChan", folder, uRoc),
00460                               "Get4 channel/edge sending Error message",
00461                               2*(fParam->uNbGet4)*NB_CHAN_GET4, 0., (fParam->uNbGet4)*NB_CHAN_GET4, 6, 0, 6,
00462                               "Error chan","","Entries [1]");
00463 
00464       ROC[uRoc].fGet4ErrorChan->GetYaxis()->SetBinLabel(1, "0x04: FIFO Write      ");
00465       ROC[uRoc].fGet4ErrorChan->GetYaxis()->SetBinLabel(2, "0x05: Lost event      ");
00466       ROC[uRoc].fGet4ErrorChan->GetYaxis()->SetBinLabel(3, "0x06: Channel state   ");
00467       ROC[uRoc].fGet4ErrorChan->GetYaxis()->SetBinLabel(4, "0x11: Overwrite       ");
00468       ROC[uRoc].fGet4ErrorChan->GetYaxis()->SetBinLabel(5, "0x12: ToT out of range");
00469 
00470       ROC[uRoc].fGet4ErrorPatt = MakeTH2('I', Form("%sRoc%u_Get4ErrorPatt", folder, uRoc),
00471                               "Pattern of Get4 Error message",
00472                               fParam->uNbGet4, -0.5, fParam->uNbGet4 -0.5, 128, 0., 128,
00473                               "Error chip","","Entries [1]");
00474       ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(1,  "0x00: Readout Init    ");
00475       ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(2,  "0x01: Sync            ");
00476       ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(3,  "0x02: Epoch count sync");
00477       ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(4,  "0x03: Epoch           ");
00478       ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(5,  "0x04: FIFO Write      ");
00479       ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(6,  "0x05: Lost event      ");
00480       ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(7,  "0x06: Channel state   ");
00481       ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(8,  "0x07: Token Ring state");
00482       ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(9,  "0x08: Token           ");
00483       ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(10, "0x09: Error Readout   ");
00484       ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(11, "0x0a: SPI             ");
00485       ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(12, "0x0b: DLL Lock error  "); // <- From GET4 v1.2
00486       ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(13, "0x0c: DLL Reset invok."); // <- From GET4 v1.2
00487 //      ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(14, "0x0d:                 ");
00488 //      ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(15, "0x0e:                 ");
00489 //      ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(16, "0x0f:                 ");
00490 //      ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(17, "0x10:                 ");
00491       ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(18, "0x11: Overwrite       ");
00492       ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(19, "0x12: ToT out of range");
00493       ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(20, "0x13: Event Discarded ");
00494       ROC[uRoc].fGet4ErrorPatt->GetYaxis()->SetBinLabel(128, "0x7f: Unknown         ");
00495 
00496       /*
00497        * Debug Histograms for GET4 v1.x
00498        */
00499       if( 1 == fParam->bDebugHistoEnable )
00500       {
00501          UInt_t uHistosIndexSingleChip = 0;
00502          UInt_t uHistosIndexChipVsChip = 0;
00503          for(UInt_t uFirstGet4Channel = 0; uFirstGet4Channel < NB_CHAN_GET4; uFirstGet4Channel++)
00504          {
00505             for(UInt_t uSecondGet4Channel = 0; uSecondGet4Channel < NB_CHAN_GET4; uSecondGet4Channel++)
00506             {
00507                if( uFirstGet4Channel < uSecondGet4Channel )
00508                {
00509                   ROC[uRoc].fTimeDiffInsideChip[0][uHistosIndexSingleChip] =
00510                         MakeTH1('I',
00511                               Form("%sDebug/Chip1/Roc%d_TimeDiff1_%d_%d",
00512                                     folder, uRoc, uFirstGet4Channel, uSecondGet4Channel),
00513                               Form("Time difference between channel %d and %d in chip %d ROC %d",
00514                                     uFirstGet4Channel, uSecondGet4Channel, fParam->uGet4TimeDiffChip1, uRoc),
00515                               601, -15025, 15025, "dT [ps]", "Counts [1]" );
00516                   ROC[uRoc].fTimeDiffInsideChip[1][uHistosIndexSingleChip] =
00517                         MakeTH1('I', Form("%sDebug/Chip2/Roc%d_TimeDiff2_%d_%d",
00518                               folder, uRoc, uFirstGet4Channel, uSecondGet4Channel),
00519                         Form("Time difference between channel %d and %d in chip %d ROC %d",
00520                               uFirstGet4Channel, uSecondGet4Channel, fParam->uGet4TimeDiffChip2, uRoc),
00521                         601, -15025, 15025, "dT [ps]", "Counts [1]" );
00522 
00523                   // 1D FineTime correlation
00524                   ROC[uRoc].fFTCorrel[0][uHistosIndexSingleChip] =
00525                         MakeTH1('I',
00526                               Form("%sDebug/Chip1/Roc%d_FTCorrel1_%d_%d",
00527                                     folder, uRoc, uFirstGet4Channel, uSecondGet4Channel),
00528                               Form("FTS Correlation between channels %d and %d in chip %d ROC %d",
00529                                     uFirstGet4Channel, uSecondGet4Channel, fParam->uGet4TimeDiffChip1, uRoc),
00530                               2*NB_BIN_GET4_FTS + 1, -NB_BIN_GET4_FTS-0.5, NB_BIN_GET4_FTS+0.5);
00531                   ROC[uRoc].fFTCorrel[1][uHistosIndexSingleChip] =
00532                         MakeTH1('I',
00533                               Form("%sDebug/Chip2/Roc%d_FTCorrel2_%d_%d",
00534                                     folder, uRoc, uFirstGet4Channel, uSecondGet4Channel),
00535                               Form("FTS Correlation between channels %d and %d in chip %d ROC %d",
00536                                     uFirstGet4Channel, uSecondGet4Channel, fParam->uGet4TimeDiffChip2, uRoc),
00537                               2*NB_BIN_GET4_FTS + 1, -NB_BIN_GET4_FTS-0.5, NB_BIN_GET4_FTS+0.5);
00538 
00539                   // 2D FineTime correlation
00540                   ROC[uRoc].fFTCorrel2D[0][uHistosIndexSingleChip] =
00541                         MakeTH2('I',
00542                               Form("%sDebug/Chip1/Roc%d_2dFTCorr1_%d_%d",
00543                                     folder, uRoc, uFirstGet4Channel, uSecondGet4Channel),
00544                               Form("FTS Correlation between channels %d and %d in chip %d ROC %d",
00545                                     uFirstGet4Channel, uSecondGet4Channel, fParam->uGet4TimeDiffChip1, uRoc),
00546                               NB_BIN_GET4_FTS, -0.5, NB_BIN_GET4_FTS-0.5,
00547                               NB_BIN_GET4_FTS, -0.5, NB_BIN_GET4_FTS-0.5);
00548                   ROC[uRoc].fFTCorrel2D[1][uHistosIndexSingleChip] =
00549                         MakeTH2('I',
00550                               Form("%sDebug/Chip2/Roc%d_2dFTCorr2_%d_%d",
00551                                     folder, uRoc, uFirstGet4Channel, uSecondGet4Channel),
00552                               Form("FTS Correlation between channels %d and %d in chip %d ROC %d",
00553                                     uFirstGet4Channel, uSecondGet4Channel, fParam->uGet4TimeDiffChip2, uRoc),
00554                               NB_BIN_GET4_FTS, -0.5, NB_BIN_GET4_FTS-0.5,
00555                               NB_BIN_GET4_FTS, -0.5, NB_BIN_GET4_FTS-0.5);
00556 
00557                   uHistosIndexSingleChip++;
00558                } // if( uFirstGet4Channel < uSecondGet4Channel )
00559                ROC[uRoc].fTimeDiffBetweenChips[uHistosIndexChipVsChip] =
00560                      MakeTH1('I',
00561                            Form("%sDebug/ChipVsChip/Roc%d_dT_%d_%d_Vs_%d_%d",
00562                                  folder, uRoc,
00563                                  fParam->uGet4TimeDiffChip1, uFirstGet4Channel,
00564                                  fParam->uGet4TimeDiffChip2, uSecondGet4Channel),
00565                            Form("Time difference between channel %d in chip %d and channel %d in chip %d",
00566                                  uFirstGet4Channel, fParam->uGet4TimeDiffChip1, uSecondGet4Channel, fParam->uGet4TimeDiffChip2),
00567                            961, -24025, 24025, "dT [ps]", "Counts [1]" );
00568                ROC[uRoc].fFTCorrelChipToChip[uHistosIndexChipVsChip] =
00569                      MakeTH1('I',
00570                            Form("%sDebug/ChipVsChip/Roc%d_FTCorrel_%d_%d_Vs_%d_%d",
00571                                  folder, uRoc,
00572                                  fParam->uGet4TimeDiffChip1, uFirstGet4Channel,
00573                                  fParam->uGet4TimeDiffChip2, uSecondGet4Channel),
00574                            Form("FTS Correlation between channel %d in chip %d and channel %d in chip %d",
00575                                  uFirstGet4Channel, fParam->uGet4TimeDiffChip1, uSecondGet4Channel, fParam->uGet4TimeDiffChip2),
00576                            2*NB_BIN_GET4_FTS + 1, -NB_BIN_GET4_FTS-0.5, NB_BIN_GET4_FTS+0.5);
00577                uHistosIndexChipVsChip++;
00578             } // for(UInt_t uSecondGet4Channel = 0; uSecondGet4Channel < MAX_GET4_CH; uSecondGet4Channel++)
00579          } // for(UInt_t uFirstGet4Channel = 0; uFirstGet4Channel < MAX_GET4_CH; uFirstGet4Channel++)
00580       } // if( 1 == fParam->bDebugHistoEnable )
00581    } // for( UInt_t  uRoc =0; uRoc<fParam->numRocs; uRoc++ )
00582    printData = 0;
00583    fCurrentGet4Event.Clear();
00584 
00585    /* TODO FILL ME
00586     * Histos and inner variables initialization for Get4 monitoring
00587     */
00588 
00589    fGlobalTriggerWind = MakeWinCond("TriggerWindow", -100, 2000., fDeltaTriggerTime->GetName());
00590    fGlobalAUXWind     = MakeWinCond("AUXWindow",     -100, 100.,  fDeltaTriggerTime->GetName());
00591 
00592    setupmacro = "set_Get4v1Cond.C";
00593    if (!gSystem->AccessPathName(setupmacro.Data())) {
00594       TGo4Log::Info("Executing ROC condition setup script %s", setupmacro.Data());
00595       gROOT->ProcessLine(Form(".x %s", setupmacro.Data()));
00596    } else {
00597       TGo4Log::Info("NO ROC condition setup script %s. Use previous values!", setupmacro.Data());
00598    }
00599 
00600    ResetEndOfBuffer();
00601 
00602 /*
00603    fEvtIndexRoc = MakeTH2('I', "EvtIndexRoc", "Event count vs Event index - Initial event inedx for ROC",
00604          600, 0., 600, 600, 0., 600 );
00605    fEvtIndexTrig= MakeTH2('I', "EvtIndexTrig", "Event count vs Event index - Initial event inedx for VME",
00606          600, 0., 600, 600, 0., 600 );
00607          */
00608    uInitialEvent = 0;
00609    uEventCountsRoc = 0;
00610    uEventCountsTrig = 0;
00611    uEventCountsVme = 0;
00612 }
00613 
00614 
00615 void TGet4v1Proc::InitEvent(TGo4EventElement* outevnt)
00616 {
00617    // since output event object is never discarded within processor lifetime,
00618    // we just search for subevent by name once to speed up processing
00619    if(fOutputEvent==0)
00620    {
00621       // test if we are in beamtime or standalone mode:
00622       TCBMBeamtimeEvent* btevent=dynamic_cast<TCBMBeamtimeEvent*>(outevnt);
00623       if(btevent)
00624       {
00625 
00626          fOutputEvent = dynamic_cast<TGet4v1Event*>(btevent->GetSubEvent("ROCGET4V10"));
00627       }
00628       else
00629       {
00630 
00631          fOutputEvent= dynamic_cast<TGet4v1Event*>(outevnt);
00632       }
00633       if(fOutputEvent==0)
00634       {
00635          GO4_STOP_ANALYSIS_MESSAGE("**** TGet4v1Proc: Fatal error: output event is not a TGet4v1Event!!! STOP GO4");
00636       }
00637    } // IF OUTPUTEVENT
00638 
00639    fFirstSubEvent = true;
00640 
00641 //   printf("Start event\n");
00642 }
00643 
00644 
00645 
00646 //-----------------------------------------------------------
00647 // event function
00648 void TGet4v1Proc::ProcessSubevent(TGo4MbsSubEvent* psubevt)
00649 {
00650    uint32_t g4id(0), auxid(0), syncid(0);
00651    uint64_t fulltm(0);
00652    uint32_t typ(0), rocid(0), lastevrocid(0);
00653    static int cnt=0;
00654    unsigned msgcount=0;
00655 
00656    //cout << "#################### ProcessSubevent Start" << endl;
00657    bool is_dabc_evt = (psubevt->GetProcid() == roc::proc_RocEvent) ||
00658                       (psubevt->GetProcid() == roc::proc_ErrEvent) ||
00659                       (psubevt->GetProcid() == roc::proc_MergedEvent);
00660    bool is_raw_evt = (psubevt->GetProcid() == roc::proc_RawData);
00661    bool is_vme_evt = (psubevt->GetProcid() == roc::proc_Triglog) ||
00662                       (psubevt->GetProcid() == roc::proc_COSY_Nov11);
00663 
00664    fEvtPerProc->Fill( psubevt->GetProcid() );
00665    if( 0 == uEventCountsRoc && 0 == uEventCountsTrig)
00666       uInitialEvent = GetEventNumber();
00667 
00668    if( is_vme_evt && psubevt->GetProcid() == roc::proc_Triglog )
00669    {
00670       if( 0 == uEventCountsTrig )
00671          fEvtIndexTrig= MakeTH1('I', "EvtIndexTrig", "Event count vs Event index - Initial event index for VME",
00672                600, 0., 600 );
00673 //      fEvtIndexTrig->Fill( uEventCountsTrig, GetEventNumber() - uInitialEvent);
00674       fEvtIndexTrig->Fill( GetEventNumber() - uInitialEvent, uEventCountsTrig);
00675       uEventCountsTrig++;
00676    }
00677       else if( is_vme_evt && psubevt->GetProcid() == roc::proc_COSY_Nov11 )
00678       {
00679          if( 0 == uEventCountsVme )
00680             fEvtIndexVme= MakeTH1('I', "EvtIndexVme", "Event count vs Event index - Initial event index for VME",
00681                   600, 0., 600 );
00682          fEvtIndexVme->Fill( GetEventNumber() - uInitialEvent, uEventCountsVme );
00683          uEventCountsVme++;
00684       }
00685          else
00686          {
00687             if( 0 == uEventCountsRoc )
00688             {
00689                fEvtIndexRoc = MakeTH1('I', "EvtIndexRoc", "Event count vs Event index - Initial event index for ROC",
00690                      600, 0., 600 );
00691                fTriggerNumber = MakeTH1('I', "TriggerNumber", "Event count per trigger for ROC",
00692                      16, 0., 16 );
00693             }
00694             fEvtIndexRoc->Fill( GetEventNumber() - uInitialEvent, uEventCountsRoc );
00695             uEventCountsRoc++;
00696             fTriggerNumber->Fill( GetTriggerNumber() );
00697          }
00698 
00699    if (!is_dabc_evt && !is_raw_evt)
00700    {
00701       // No printout when VME part of merged data
00702       if( !is_vme_evt )
00703          cout << "Oups: Not DABC or RAW event"<< endl;
00704       return;
00705    }
00706 
00707    if( 1 == is_raw_evt && kFALSE == fParam->bRawDataMode )
00708    {
00709       fParam->bRawDataMode = kTRUE;
00710       cout<<" Found a RAW DATA event => switch RAW DATA mode ON"<<endl;
00711    }
00712 
00713    unsigned rid = psubevt->GetSubcrate();
00714 
00715 // BEGIN INITIAL EVENT PART
00716    int datasize = (psubevt->GetDlen() - 2) * 2;
00717    int msg_fmt = psubevt->GetControl();
00718    ROC[rid].fIter.setFormat(msg_fmt);
00719    ROC[rid].fIter.setRocNumber(rid);
00720 
00722    if( -1 != fParam->FindGet4RocId( psubevt->GetSubcrate() ) )
00723    {
00724       Int_t iFeetRocIndex = fParam->FindGet4RocId( psubevt->GetSubcrate() );
00725       if(uNbEvents[iFeetRocIndex] == 0) {
00726          uFirstEventIndex[iFeetRocIndex] = GetEventNumber();
00727          TGo4Log::Info("***** First event on Get4 roc %d: %d ", iFeetRocIndex, uFirstEventIndex[iFeetRocIndex]);
00728       } // if(uNbEvents[iFeetRocIndex] == 0)
00729       else {
00730          if( 0 < fParam->iEventNbGap &&
00731              (Int_t)uPrevEventIndex[iFeetRocIndex] + fParam->iEventNbGap != GetEventNumber() &&
00732              ( uPrevEventIndex[iFeetRocIndex] !=  fParam->uEventNbCycle || 0 != GetEventNumber() ) ) {
00733             TGo4Log::Error("***** Missing event in file for Get4 roc %d: Event %d, Previous event index %d, Current event Index %d, expected %d",
00734                   iFeetRocIndex, uNbEvents[iFeetRocIndex], uPrevEventIndex[iFeetRocIndex], GetEventNumber(),
00735                   (Int_t)uPrevEventIndex[iFeetRocIndex] + fParam->iEventNbGap);
00736          } // if not matching expected event gap
00737       } // else of if(uNbEvents[iFeetRocIndex] == 0)
00738       uPrevEventIndex[iFeetRocIndex]  = GetEventNumber();
00739       uNbEvents[iFeetRocIndex]++;
00740    } // if( -1 != fParam->FindGet4RocId( psubevt->GetSubcrate() ) )
00741    /*************************************/
00742 
00743    // we can exclude messages (SYNC and may be EPOCH) which are added by DABC at the end of subevent
00744    if (is_dabc_evt)
00745    {
00746       // ignore all irrelevant events
00747       if (GetTriggerNumber()>11)
00748       {
00749          cout<<"OUPS, trigger too high: "<<GetTriggerNumber()<<endl;
00750          return;
00751       }
00752 
00753       roc::Message msg1, msg2;
00754       roc::Message msgA, msgB;
00755 
00756       char* ptr = (char*) psubevt->GetDataField();
00757       int msglen = roc::Message::RawSize(msg_fmt);
00758 
00759       if (ROC[rid].fIter.assign(ptr + datasize - msglen, msglen)) {
00760          if (ROC[rid].fIter.next()) msg1.assign(ROC[rid].fIter.msg());
00761       }
00762 
00763       if (!msg1.isSyncMsg()) {
00764          TGo4Log::Error("Non-SYNC message at the end of DABC-produced subevent");
00765       } else {
00766          rocid = msg1.getRocNumber();
00767          /*
00768           * TODO: Option to choose between removing final epoch+SYNC or initial epoch+SYNC
00769           */
00770          UInt_t uSyncId    = msg1.getSyncChNum();
00771          UInt_t uSyncTs    = msg1.getSyncTs();
00772          UInt_t uSyncEpLsb = msg1.getSyncEpochLSB();
00773          UInt_t uSyncData  = msg1.getSyncData();
00774          UInt_t uSyncFlag  = msg1.getSyncStFlag();
00775          ULong64_t ulFulltime = msg1.getMsgFullTime( ROC[rocid].GetFullEpochNumber( ) );
00776          ulFulltime += ROC[rocid].GetSuperCycleEpOffset();
00777 /*
00778          cout<<"End Event "<<GetEventNumber()<<" Sync Id "<<uSyncId<<" Ts "<<uSyncTs;
00779          cout<<" EpLsb "<<uSyncEpLsb<<" Data "<<uSyncData<<" Flag "<<uSyncFlag;
00780          cout<<" FullT "<<ulFulltime<<endl;
00781          */
00782          /*
00783           *
00784           */
00785 
00786          // kFALSE = SYNC arriving before the event data, kTRUE = after
00787          // => if kTRUE, keep last 2 message and throw 2 first!
00788          if( kFALSE == fParam->bTriggerAfterData )
00789             datasize -= msglen;
00790          int shift = msglen;
00791          while (shift<=datasize) {
00792 
00793             if (ROC[rid].fIter.assign(ptr + datasize - shift, msglen)) {
00794                if (ROC[rid].fIter.next())
00795                   msg2.assign(ROC[rid].fIter.msg());
00796                else
00797                   break;
00798 
00799                if (msg2.isEpochMsg())
00800                {
00801                   /*
00802                   cout<<"End Event "<<GetEventNumber()<<" Epoch "<<msg2.getEpochNumber()<<endl;
00803                   */
00804                   break;
00805                }
00806             }
00807             shift+=msglen;
00808          }
00809          // exclude special epoch message for sync only
00810          // kFALSE = SYNC arriving before the event data, kTRUE = after
00811          // => if kTRUE, keep last 2 message and throw 2 first!
00812          if( kFALSE == fParam->bTriggerAfterData )
00813             if ((shift==msglen) && msg2.isEpochMsg()) datasize -= msglen;
00814       } // else of if (!msg1.isSyncMsg())
00815    } // if (is_dabc_evt)
00816 
00817    fTotaldatasize += datasize;
00818 
00819    if (!ROC[rid].fIter.assign(psubevt->GetDataField(), datasize))
00820    {
00821       cout<<"OUPS, probblem: "<<psubevt->GetDataField()<<" "<<datasize<<endl;
00822       return;
00823    } // if (!ROC[rid].fIter.assign(psubevt->GetDataField(), datasize))
00824 
00825    fEvntSize->Fill(datasize);
00826 
00827    //cout << "AnlProc: found subevent subcrate="<<(int) psubevt->GetSubcrate()<<", procid=";
00828    //cout<<(int)psubevt->GetProcid()<<", control="<<(int) psubevt->GetControl()<< endl;
00829 // END INITIAL EVENT PART
00830 
00831    /* TODO FILL ME
00832     * Buffer processing
00833     */
00834 
00835    roc::Message* data = & ROC[rid].fIter.msg();
00836    while (ROC[rid].fIter.next()) {
00837       msgcount++;
00838 
00839       rocid = data->getRocNumber();
00840       fMsgsPerRoc->Fill(rocid);
00841 
00842       // Process data only from active ROCs
00843       if( kFALSE == fParam->IsActiveRoc(rocid) )
00844          continue;
00845 
00846       typ = data->getMessageType();
00847       if(typ==roc::MSG_GET4)
00848       {
00849          fulltm = data->getMsgFullTime(
00850                ROC[rocid].GetFullEpoch2Number(
00851                      fParam->RemapGet4Chip( data->getGet4Number() ) ));
00852          fulltm +=  ROC[rocid].GetSuperCycleEp2Offset(
00853                      fParam->RemapGet4Chip( data->getGet4Number() ) );
00854       }
00855       else
00856       {
00857          fulltm = data->getMsgFullTime(
00858                ROC[rocid].GetFullEpochNumber() );
00859          fulltm +=  ROC[rocid].GetSuperCycleEpOffset( );
00860 
00861       }
00862 
00863       ROC[rocid].fMsgTypes->Fill(typ);
00864 
00865       ULong64_t  ulMsgTm = fulltm / 100000000L;
00866       ROC[rocid].fALLt->Fill( (ulMsgTm % 36000) * 0.1 );
00867 
00868       // Long duration time distribution (1 min. bin, 10 days length)
00869       if( kTRUE == fParam->bLongTimeHistos )
00870          ROC[rocid].fAllLongT->Fill( ( ulMsgTm * 0.1 ) /3600);
00871 
00872       TGet4v1MessageExtended exmess(*data,fulltm);
00873 
00874       switch (typ)
00875       {
00876          case roc::MSG_NOP:
00877          {
00878             break;
00879          } // case roc::MSG_NOP:
00880          case roc::MSG_HIT:
00881          {
00882             break;
00883          } // case roc::MSG_HIT:
00884          case roc::MSG_GET4:
00885          {
00886             Double_t dFullTimeD = data->getMsgFullTimeD(
00887                                     ROC[rocid].GetFullEpoch2Number(
00888                                              fParam->RemapGet4Chip( data->getGet4Number() ) ) );
00889             dFullTimeD += ROC[rocid].GetSuperCycleEp2OffsetD( fParam->RemapGet4Chip( data->getGet4Number() ) );
00890             exmess.SetFullTimeD( dFullTimeD );
00891             // In case of suppressed epochs, we will have no epoch2 message for all empty epochs
00892             // However, when a chip has data, its next epoch message should be present!!!
00893             // => Specific function to wait for next epoch2
00894             if( kTRUE == fParam->bSuppressedEpochs)
00895                ProcessGet4SuppDataMessage(rocid, exmess);
00896             else if( kTRUE == ProcessGet4DataMessage(rocid, exmess) )
00897                ProcessExtendedMessage(rocid, exmess);
00898             break;
00899          } // case roc::MSG_GET4:
00900          case roc::MSG_EPOCH:
00901          {
00902             /*
00903             if((msgcount<3) && !is_raw_evt)
00904             {
00905                cout<<"Beg Event "<<GetEventNumber()<<" Epoch "<<data->getEpochNumber()<<endl;
00906             }
00907             */
00908             if( !is_dabc_evt || kFALSE == fParam->bTriggerAfterData ||
00909                  2 < msgcount)
00910                ProcessRocEpochMessage(rocid, exmess);
00911             break;
00912          } // case roc::MSG_EPOCH:
00913          case roc::MSG_EPOCH2:
00914          {
00915             if( kTRUE == fParam->bSuppressedEpochs)
00916                ProcessGet4SuppEpochMessage(rocid, exmess);
00917                else ProcessGet4EpochMessage(rocid, exmess);
00918             break;
00919          } // case roc::MSG_EPOCH2:
00920          case roc::MSG_SYNC:
00921          {
00922             UInt_t uSyncId    = data->getSyncChNum();
00923             UInt_t uSyncTs    = data->getSyncTs();
00924             UInt_t uSyncEpLsb = data->getSyncEpochLSB();
00925             UInt_t uSyncData  = data->getSyncData();
00926             UInt_t uSyncFlag  = data->getSyncStFlag();
00927             ULong64_t ulFulltime = data->getMsgFullTime( ROC[rocid].GetFullEpochNumber( ) );
00928             ulFulltime += ROC[rocid].GetSuperCycleEpOffset();
00929 
00930             if( kFALSE == fParam->bTriggerAfterData )
00931             {
00932                if((msgcount<3) && !is_raw_evt)
00933                {
00934                   ROC[rocid].fDabcSeparator = data->getSyncChNum()+10;
00935                }
00936                ProcessRocSyncMessage(rocid, exmess);
00937             } // if( kFALSE == fParam->bTriggerAfterData )
00938                else if( (2 < msgcount ) || !is_dabc_evt)
00939                {
00940                   if( ( (datasize - 3 ) < (Int_t)msgcount) && !is_raw_evt)
00941                   {
00942                      ROC[rocid].fDabcSeparator = data->getSyncChNum()+10;
00943                   }
00944                   ProcessRocSyncMessage(rocid, exmess);
00945                } // else if( (2 < msgcount ) || !is_dabc_evt) of if( kFALSE == fParam->bTriggerAfterData )
00946             break;
00947          } // case roc::MSG_SYNC:
00948          case roc::MSG_AUX:
00949          {
00950             auxid = data->getAuxChNum();
00951             ROC[rocid].fAUXch->Fill(auxid);
00952             if (auxid < MAX_AUX)
00953             {
00954                ROC[rocid].fLastAuxTm[auxid] = fulltm;
00955 
00956                // Recalculate the full Time to take into account also the epoch cycles
00957                ULong64_t ulFulltime ;
00958                ulFulltime  = (exmess.GetRocMessage()).getMsgFullTime(
00959                                    ROC[rocid].GetFullEpochNumber( ));
00960                ulFulltime += ROC[rocid].GetSuperCycleEpOffset();
00961                exmess.SetFullTime(ulFulltime);
00962 
00963                ULong64_t auxtm = fulltm / 100000000L;
00964                ROC[rocid].fAUXt[auxid]->Fill((auxtm % 10000) * 0.1);
00965 
00966                if( kFALSE ==  fParam->bFreeStreaming || 0 == fParam->uNbTriggers )
00967                   if (fParam->triggerSignal == (Int_t) auxid)
00968                   {
00969                      ProcessTriggerMessage(rocid, exmess);
00970                   }
00971             } // if (auxid < MAX_AUX)
00972 
00973             break;
00974          } // case roc::MSG_AUX:
00975          case roc::MSG_SYS:
00976          {
00977             ROC[rocid].fSysTypes->Fill(data->getSysMesType());
00978 
00979             if (data->getSysMesType() == roc::SYSMSG_USER)
00980             {
00981                ROC[rocid].fSysUserTypes->Fill(data->getSysMesData());
00982 
00983                switch (data->getSysMesData())
00984                {
00985                   case roc::SYSMSG_USER_CALIBR_ON:
00986                      ROC[rocid].bIgnoreData = kFALSE;
00987                      break;
00988                   case roc::SYSMSG_USER_CALIBR_OFF:
00989                      ROC[rocid].bIgnoreData = kFALSE;
00990                      break;
00991                   case roc::SYSMSG_USER_RECONFIGURE:
00992                      ROC[rocid].bIgnoreData = kTRUE;
00993                      ROC[rocid].fIgnoreCnt = 0;
00994                      ROC[rocid].fIgnoreTime = fulltm;
00995                      break;
00996                   default:
00997                      break;
00998                } // switch (data->getSysMesData())
00999             } // if (data->getSysMesType() == roc::SYSMSG_USER)
01000             else if( data->getSysMesType() == roc::SYSMSG_GET4_EVENT )
01001             {
01002                UInt_t uGet4SysMessType = (data->getSysMesData()>>6) & 0x1;
01003 
01004                // Get4 system message types histogram
01005                /*
01006                if (ROC[rocid].fGet4SysTypes)
01007                   ROC[rocid].fGet4SysTypes->Fill(uGet4SysMessType);
01008                   */
01009 
01010                UInt_t uGet4IndexOffset = fParam->DefineGet4IndexOffset(rocid);
01011                // Remap the Get4 chip index
01012                UInt_t uChip = data->getField(40, 8) + uGet4IndexOffset;
01013                uChip = fParam->RemapGet4Chip(uChip);
01014                // Set Remapped Get4 index
01015                data->setField(40, 8, uChip);
01016 
01017                // Get4 system message type = Error
01018                if (!fParam->IsValidGet4Chip(uChip)) {
01019                    cout << "Error: Bad chip nb in Error message = " << uChip << endl;
01020                    cout << " => This message will be skipped!!!! "<<endl;
01021                    continue;
01022                }
01023 /*
01024                fGet4ErrorChip->Fill( uChip );
01025                fGet4ErrorPatt->Fill( uChip, (data->getSysMesData()) & 0x7f);
01026                if( 3 < ( (data->getSysMesData()) & 0x7f ) && ( (data->getSysMesData()) & 0x7f ) < 7 )
01027                   fGet4ErrorChan->Fill( (((data->getSysMesData()) & 0x300)>>16) + 0.5*(((data->getSysMesData()) & 0x80)>>15),
01028                        ((data->getSysMesData()) & 0x7f )>>2 );
01029 */
01030                UInt_t get4_24b_er_code = exmess.getGet4V10R32ErrorData();
01031                UInt_t get4_24b_er_chan = exmess.getGet4V10R32ErrorChan();
01032                UInt_t get4_24b_er_edge = exmess.getGet4V10R32ErrorEdge();
01033 
01034                ROC[rocid].fGet4ErrorChip->Fill( uChip );
01035                ROC[rocid].fGet4ErrorPatt->Fill( uChip, get4_24b_er_code);
01036                if( (0x03 < get4_24b_er_code && get4_24b_er_code < 0x07) )
01037                   ROC[rocid].fGet4ErrorChan->Fill(
01038                         NB_CHAN_GET4*uChip + get4_24b_er_chan + 0.5*get4_24b_er_edge,
01039                         get4_24b_er_code - 0x04 );
01040 
01041                ULong64_t uFullTimeBins = ((ULong64_t)  ROC[rocid].GetFullEpoch2Number( uChip )) << 19;
01042                uFullTimeBins /= 20; // now in ns
01043                uFullTimeBins += 512; // 250MHz offset
01044                uFullTimeBins /= 100000000L;
01045                ROC[rocid].fERRORt->Fill( (uFullTimeBins % 36000) * 0.1 );
01046 
01047                // Long duration time distribution (1 min. bin, 10 days length)
01048                if( kTRUE == fParam->bLongTimeHistos )
01049                   ROC[rocid].fErrorLongT->Fill( (uFullTimeBins * 0.1 ) / 3600 );
01050 
01051             } // if( data->getSysMesType() == roc::SYSMSG_GET4_EVENT )
01052             else if( get4v10::SYSMSG_GET4V1_32BIT_0 <= data->getSysMesType()   &&
01053                       data->getSysMesType() <= get4v10::SYSMSG_GET4V1_32BIT_15 )
01054             {
01055                if( 3 == Process32BitGet4Message(rocid, exmess) )
01056                   ProcessExtendedMessage(rocid, exmess);
01057             } // if GET4 32 bits message
01058             break;
01059          } //  case roc::MSG_SYS:
01060          default:
01061             break;
01062       } // switch (typ)
01063      
01064       if(printData<fParam->uGet4Print  )
01065       {
01066          exmess.Print(roc::msg_print_Human);
01067          printData++;
01068       }
01069    } // while (ROC[rid].fIter.next()) {
01070    /*
01071     * Buffer processing End
01072     */
01073 
01074    fFirstSubEvent = kFALSE;
01075 }
01076 
01077 
01078 
01079 void TGet4v1Proc::FinalizeEvent()
01080 {
01081    fOutputEvent->fMbsEventNumber = GetEventNumber();
01082    /* TODO FILL ME
01083     * Final histo filling
01084     * Event validation
01085     */
01086 
01087    // For now stop current event there: no event spread over MBS event in future
01088    /*
01089    if( kFALSE == fCurrentGet4Event.IsEmpty() )
01090       (fOutputEvent->fEvents).push_back( fCurrentGet4Event );
01091    fCurrentGet4Event.Clear();
01092    */
01093 
01094    for( UInt_t  uRocTempId =0; uRocTempId < fParam->numRocs; uRocTempId++ )
01095    {
01096       ROC[uRocTempId].fNbEventsPerMbsEvent->Fill(uEventInsideMbsEvtCount[uRocTempId]);
01097       ROC[uRocTempId].fNbNotEmptyEventsPerMbsEvent->Fill(uNotEmptyEventInsideMbsEvtCount[uRocTempId]);
01098       uEventInsideMbsEvtCount[uRocTempId] = 0;
01099       uNotEmptyEventInsideMbsEvtCount[uRocTempId] = 0;
01100 
01101       if( kTRUE ==  fParam->bFreeStreaming && 0 < fParam->uNbTriggers )
01102          for( UInt_t uTrigger = 0; uTrigger < fParam->uNbTriggers; uTrigger++)
01103          {
01104             ROC[uRocTempId].fDataSelfTriggerPerEvent->Fill( ROC[uRocTempId].fuDataSelfTriggerCount[uTrigger],
01105                   uTrigger );
01106             ROC[uRocTempId].fuDataSelfTriggerCount[uTrigger] = 0;
01107          }
01108    }
01109    //printf(" =============== TGet4v1Proc::FinalizeEvent ===================\n ");
01110 }
01111 
01112 
01113 void TGet4v1Proc::ProcessTriggerMessage(UInt_t uRocId, TGet4v1MessageExtended& extMess,
01114                                             Int_t iTriggerIndex)
01115 {
01116    /* TODO FILL ME
01117     * Trigger processing
01118     */
01119 
01120    /*
01121     * Check if current event already got a trigger
01122     */
01123    if( kTRUE == fCurrentGet4Event.HasTrigger() )
01124    {
01125       Double_t dLastTriggerDistance =
01126               extMess.GetFullTimeD()
01127             - fCurrentGet4Event.fdTriggerFullTime[uRocId] ;
01128 
01129       /*
01130        * If incoming trigger has lower priority than current trigger or if
01131        * current trigger was a SYNC trigger and a data trigger comes
01132        * And it is inside the deatime window
01133        * => Ignore incoming trigger
01134        */
01135       if( dLastTriggerDistance <= fParam->dDeadTime  &&
01136           iTriggerIndex < (Int_t)(fCurrentGet4Event.fuTriggerIndex)  )
01137          return;
01138       /*
01139        * If incoming trigger has higher priority than current trigger or if
01140        * current trigger was a SYNC trigger and a data trigger comes
01141        * And it is inside the deatime window
01142        * => erase current event, start new event using incoming trigger
01143        */
01144       else if( dLastTriggerDistance <= fParam->dDeadTime  &&
01145                 iTriggerIndex > (Int_t)(fCurrentGet4Event.fuTriggerIndex) )
01146       {
01147          fCurrentGet4Event.Clear();
01148 
01149       } // else if( iTriggerIndex > (Int_t)(fCurrentGet4Event.fuTriggerIndex) )
01150       /*
01151        * If incoming trigger has same priority than current trigger or if
01152        * current trigger was a SYNC trigger and a SYNC trigger comes
01153        * => depend on bAllowEventMixing flag and distance
01154        * kTRUE  = save the partially filled old one, start the new one => TODO MIXING!!!
01155        * kFALSE = ignore incoming trigger
01156        * Distance between them bigger than trigger window size => save the partially filled old one, start the new one
01157        */
01158       else
01159       {
01160          if( fParam->dDeadTime < dLastTriggerDistance || kTRUE == fParam->bAllowEventMixing)
01161          {
01162             /*
01163              * TODO real event mixing or parallel buffers
01164              */
01165             
01166             // Check flag indicating the extra epoch after trigger is passed
01167             for( UInt_t  uRocTempId =0; uRocTempId<fParam->numRocs; uRocTempId++ )
01168             {
01169                // do not check for non-used ROC
01170                if (!fParam->IsActiveRoc(uRocTempId)) continue;
01171                
01172                for( UInt_t uGet4 = 0; uGet4 < MAX_GET4_PER_ROC; uGet4++)
01173                {
01174                   UInt_t uRemappedGet4Index = fParam->RemapGet4Chip(uRocTempId, uGet4);
01175                   if( kFALSE == fParam->IsValidGet4Chip(uRemappedGet4Index) ||
01176                       kFALSE == fParam->IsActiveGet4Chip(uRemappedGet4Index) )
01177                       continue;
01178                       
01179                   // Finish previous event
01180 //                  BuildHitsAfterTrigg( uRocTempId,  uRemappedGet4Index);
01181 
01182                   // If chip not finished to process this event, build hits from current
01183                   // buffer (safe as we anyway build hits on epoch end when necessary)
01184                   if( kFALSE == ROC[uRocTempId].fbSelectionDone[uRemappedGet4Index]  )
01185                   {
01186                      // If This is the first epoch after the trigger and 
01187                      // we did not process the epoch before the one where the 
01188                      // trigger came, we need to initialize the 24 bit temp hits
01189                      if( kFALSE == ROC[uRocId].fbEpoch2SinceTrigger[uRemappedGet4Index] && 
01190                          kFALSE == ROC[uRocId].bLookInPreviousEpoch[uRemappedGet4Index] )
01191                         for( UInt_t uChan = 0; uChan < NB_CHAN_GET4; uChan++)
01192                               (ROC[uRocId].fHitTemp24[uRemappedGet4Index][uChan]).Clear();
01193                                  
01194                      BuildHits(uRocTempId, uRemappedGet4Index, ROC[uRocTempId].fbBufferWithLastFullEpoch2[uRemappedGet4Index]);
01195                      ROC[uRocTempId].fbSelectionDone[uRemappedGet4Index] = kTRUE;
01196                   }
01197                } // for( UInt_t uGet4 = 0; uGet4 < MAX_GET4_PER_ROC; uGet4++)
01198             } // for( UInt_t  uRocId =0; uRocId<fParam->numRocs; uRocId++ )
01199 
01200             // Save previous event if not empty
01201             if( kFALSE == fCurrentGet4Event.IsEmpty() )
01202             {
01203                AnalyzeAllGet4Channels( fCurrentGet4Event );
01204                (fOutputEvent->fEvents).push_back( fCurrentGet4Event );
01205                
01206                for( UInt_t  uRocTempId =0; uRocTempId<fParam->numRocs; uRocTempId++ )
01207                {
01208                   // do not check for non-used ROC
01209                   if (!fParam->IsActiveRoc(uRocTempId)) continue;
01210                   
01211                   uNotEmptyEventInsideMbsEvtCount[uRocTempId]++;
01212                   uNotEmptyRealEventsCount[uRocTempId]++;
01213                } // for( UInt_t  uRocTempId =0; uRocTempId<fParam->numRocs; uRocTempId++ )
01214             } // if( kFALSE == fCurrentGet4Event.IsEmpty() )
01215          } // if( kTRUE == fParam->bAllowEventMixing)
01216             else return;
01217       } // else of else if( trigger > currentTrig) of if( trigger < currentTrig)
01218    } // if( kTRUE == fCurrentGet4Event.HasTrigger() )
01219 
01220    // anyway clear again for safety
01221    fCurrentGet4Event.Clear();
01222 
01223    // Assign new trigger time to current event holder
01224    fCurrentGet4Event.fdTriggerFullTime[uRocId] = extMess.GetFullTimeD();
01225    if( fCurrentGet4Event.fdTriggerFullTime[uRocId] <= 0.0)
01226       TGo4Log::Error("Assigning 0 time as trigger time? event %d time %d", GetEventNumber(), extMess.GetFullTimeD());
01227 
01228    // Event number of the corresponding MBS event
01229    fCurrentGet4Event.fuMbsEventNumber      = GetEventNumber();
01230    // Index of the real event inside MBS event
01231    fCurrentGet4Event.fuEventNbInsideMbsEvt = uEventInsideMbsEvtCount[uRocId];
01232    // Total event number
01233    fCurrentGet4Event.fuGlobalEventNumber   = uRealEventsCount[uRocId];
01234    if( roc::MSG_SYNC == extMess.GetMessageType() )
01235    {
01236       // Flag indicating that this real event is the one synchronized to MBS
01237       fCurrentGet4Event.fbMbsSyncedEvent = kTRUE;
01238       // Event Nmber from the sync message
01239       fCurrentGet4Event.fuSyncEventNumber = (extMess.GetRocMessage()).getSyncData();
01240    } // if( roc::MSG_SYNC == extMess.GetMessageType() )
01241       else if( -1 < iTriggerIndex )
01242       {
01243          // Flag indicating that this real event was made after finding coincidence in data
01244          fCurrentGet4Event.fbDataTriggered = kTRUE;
01245          // Index of the Data trigger making this event
01246          fCurrentGet4Event.fuTriggerIndex = (UInt_t)iTriggerIndex;
01247       } // else if( -1 < iTriggerIndex ) of if( roc::MSG_SYNC == extMess.GetMessageType() )
01248    uEventInsideMbsEvtCount[uRocId]++;
01249    uRealEventsCount[uRocId]++;
01250 
01251    /*
01252     * TODO: ROC self (NX/SYNC/AUX) messages bulding/checking
01253     */
01254    ROC[uRocId].fbSelectionRocDone = kFALSE;
01255    ROC[uRocId].fbEpochSinceTrigger = kFALSE;
01256     
01257    // Good solution is following:
01258    // When trigger: Process PrevBuffer Epoch -1 and remove older data if no event mixing
01259    // When current epoch finishes or when new trigger out of deadtime => process current epoch and remove older data if no event mixing
01260    // When future epoch finishes or when new trigger out of deadtime => process future epoch (which is stored in current buffer)
01261    for( UInt_t uGet4Index = 0; uGet4Index < fParam->uNbGet4; uGet4Index++)
01262       if( fParam->IsActiveGet4Chip( uGet4Index ) )
01263       {
01264          // Check if necessary to build hits from buffer of previous epoch
01265          // Is the case if the trigger window begins before beginning of current epoch
01266          Double_t dFullTimeCurrentEpoch = (((ULong64_t)ROC[uRocId].GetFullEpoch2Number(uGet4Index)) << 19);
01267          dFullTimeCurrentEpoch = dFullTimeCurrentEpoch / 20. + 512.;
01268 
01269          if( extMess.GetFullTimeD() + fParam->dCoincidenceWindowStart[iTriggerIndex] < dFullTimeCurrentEpoch)
01270          {
01271             ROC[uRocId].bLookInPreviousEpoch[uGet4Index] = kTRUE;
01272             for( UInt_t uChan = 0; uChan < NB_CHAN_GET4; uChan++)
01273                   (ROC[uRocId].fHitTemp24[uGet4Index][uChan]).Clear();
01274             Bool_t bOlderBuffer = ( kTRUE == ROC[uRocId].fbBufferWithLastFullEpoch2[uGet4Index] ? 0 : 1 );
01275             BuildHits(uRocId, uGet4Index, bOlderBuffer);
01276          } // if( extMess.GetFullTimeD() + fParam->dCoincidenceWindowStart[iTriggerIndex] < dFullTimeCurrentEpoch)
01277             else ROC[uRocId].bLookInPreviousEpoch[uGet4Index] = kFALSE;
01278             
01279          // Check if necessary to build hits from buffer of epoch after current one
01280          // Is the case if the trigger window ends after the end of current epoch
01281 //         Double_t dFullTimeNextEpoch    = (Double_t)GET4_EPOCH_IN_PS*(Double_t)( 1.0 + ROC[uRocId].GetFullEpoch2Number(uGet4Index) )/ 1000.0;
01282          Double_t dFullTimeNextEpoch = 1.0 + (((ULong64_t)ROC[uRocId].GetFullEpoch2Number(uGet4Index)) << 19);
01283          dFullTimeNextEpoch = dFullTimeCurrentEpoch / 20. + 512.;
01284          if( dFullTimeNextEpoch < extMess.GetFullTimeD() + fParam->dCoincidenceWindowStop[iTriggerIndex] )
01285             ROC[uRocId].bLookInNextEpoch[uGet4Index] = kTRUE;
01286             else ROC[uRocId].bLookInNextEpoch[uGet4Index] = kFALSE;
01287             
01288          // Initialize the flag indicating how many epoch2 finished since this trigger came
01289          ROC[uRocId].fbEpoch2SinceTrigger[uGet4Index] = kFALSE;
01290          ROC[uRocId].fbSelectionDone[uGet4Index]   = kFALSE;
01291             
01292          for(UInt_t uChanTest = 0; uChanTest < NB_CHAN_GET4; uChanTest ++)
01293          {
01294             ROC[uRocId].fbDataTimeOut[uGet4Index][uChanTest] = kFALSE;
01295             ROC[uRocId].fbDataFallingOut[uGet4Index][uChanTest] = kFALSE;
01296          }
01297       }
01298    return;
01299 }
01300 
01301 void TGet4v1Proc::ProcessExtendedMessage(UInt_t uRocId, TGet4v1MessageExtended& extMess)
01302 {
01303    /* TODO FILL ME
01304     * Generic Extended message processing
01305     * If Previous trigger done => just put in buffer
01306     * If not done => put in buffer, build hit if possible and
01307     * check if it does not match current trigger
01308     */
01309    UInt_t uType = extMess.GetMessageType();
01310 
01311    // 24 Bits data message => need to be built
01312    if( roc::MSG_GET4 == uType )
01313    {
01314       UInt_t uGet4Id =  extMess.GetGet4Number() ;
01315 
01316       // Check if chip is activated
01317       if( fParam->IsActiveGet4Chip(uGet4Id) )
01318       {
01319          // Save message anyway in previous epochs buffer in case two triggers come close
01320          ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][
01321              ROC[uRocId].fbBufferWithLastFullEpoch2[uGet4Id]].push_back(extMess);
01322       } // if( fParam->IsActiveGet4Chip(uChip) )
01323    }
01324    // 32 Bits data message => already contains a full hit!
01325    else if( roc::MSG_SYS == uType &&
01326        get4v10::SYSMSG_GET4V1_32BIT_0 <= extMess.GetSysMesType()   &&
01327        extMess.GetSysMesType() <= get4v10::SYSMSG_GET4V1_32BIT_15 )
01328    {
01329       UInt_t uGet4Id =  extMess.getGet4V10R32ChipId() ;
01330       uGet4Id = fParam->RemapGet4Chip( uRocId, uGet4Id);
01331 
01332       // Check if chip is activated
01333       if( fParam->IsActiveGet4Chip(uGet4Id) )
01334       {
01335          // Save message anyway in previous epochs buffer in case two triggers come close
01336          ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][
01337              ROC[uRocId].fbBufferWithLastFullEpoch2[uGet4Id]].push_back(extMess);
01338       } // if( fParam->IsActiveGet4Chip(uChip) )
01339    } // else if( Get4 32 bits) of if( Get4 24 bits )
01340    // Other ROC data messages => Saved in their own vector for each event if needed
01341    else
01342    {
01343       cout<<"Rejected message because type not recognised in ProcessExtendedMessage"<<endl;
01344    }// else of else if( Get4 32 bits) of if( Get4 24 bits )
01345 }
01346 /**********************************************************************/
01347 Bool_t TGet4v1Proc::BuildHits(UInt_t uRocId, UInt_t uGet4Id, Bool_t bBufferToBuild)
01348 {
01349    /*
01350     * 32 bit hit building from all raw message => easy => done
01351     * 24bit hit building from all raw edges messages
01352     * -> Check edges order? => ordering messages should solve
01353     * -> Check multiple rising edges case  => Histos?
01354     * -> Check multiple falling edges case => Histos?
01355     */
01356    UInt_t uLastAcceptedMessageIndex = 0;
01357 
01358    std::sort( ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][bBufferToBuild].begin(),
01359               ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][bBufferToBuild].end() );
01360    for( UInt_t uMessageIndex = 0;
01361          uMessageIndex < ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][bBufferToBuild].size();
01362          uMessageIndex ++)
01363    {
01364       if( kTRUE == (ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][bBufferToBuild])[uMessageIndex].Is32Bit() )
01365       {
01366          // 32 Bits data message => already contains a full hit!
01367          fHitTemp.Clear();
01368          fHitTemp.SetFullHit32Bits( (ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][bBufferToBuild])[uMessageIndex] );
01369          if( kTRUE == CheckHit( uRocId, uGet4Id, fHitTemp ) )
01370             uLastAcceptedMessageIndex = uMessageIndex;
01371 
01372       } // if( kTRUE == (ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][bBufferToBuild])[uMessageIndex].Is32Bit() )
01373          else
01374          {
01375             UChar_t ucChan = (ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][bBufferToBuild])[uMessageIndex].GetGet4ChNum();
01376 
01377             // 24 Bits data message => Rising and falling edge need to be associated to get a hit
01378             if( 1 == (ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][bBufferToBuild])[uMessageIndex].IsRisingGet4Edge() )
01379             {
01380                // Trailing Edge
01381                // If no leading edge there, as messages are time ordered, means that
01382                // the leading edge of this hit is missing => no need to save it
01383                if( kTRUE == (ROC[uRocId].fHitTemp24[uGet4Id][ucChan]).IsTimeSet() )
01384                {
01385                   (ROC[uRocId].fHitTemp24[uGet4Id][ucChan]).SetTot24Bits(
01386                         (ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][bBufferToBuild])[uMessageIndex] );
01387 
01388                   // Check if hit is not too big
01389                   // If it is we can clear this one as anyway messages are time ordered!
01390                   if( (ROC[uRocId].fHitTemp24[uGet4Id][ucChan]).GetTot() < 0)
01391                   {
01392                      cout<<"Negative 24b ToT in Build Older: Mess "<<uMessageIndex;
01393                      cout<<" Tot "<<(ROC[uRocId].fHitTemp24[uGet4Id][ucChan]).GetTot();
01394                      cout<<" Test "<<( ((ROC[uRocId].fHitTemp24[uGet4Id][ucChan]).GetTimeMessage()) < ((ROC[uRocId].fHitTemp24[uGet4Id][ucChan]).GetTotMessage()) )<<endl;
01395                      ((ROC[uRocId].fHitTemp24[uGet4Id][ucChan]).GetTimeMessage()).Print(roc::msg_print_Human);
01396                      ((ROC[uRocId].fHitTemp24[uGet4Id][ucChan]).GetTotMessage()).Print(roc::msg_print_Human);
01397                      cout<<endl;
01398                      if( kTRUE == CheckHit( uRocId, uGet4Id, (ROC[uRocId].fHitTemp24[uGet4Id][ucChan]) ) )
01399                         uLastAcceptedMessageIndex = uMessageIndex;
01400                   }
01401                      else if( (ROC[uRocId].fHitTemp24[uGet4Id][ucChan]).GetTot() < fParam->dMaxTot )
01402                      {
01403                         if( kTRUE == CheckHit( uRocId, uGet4Id, (ROC[uRocId].fHitTemp24[uGet4Id][ucChan]) ) )
01404                            uLastAcceptedMessageIndex = uMessageIndex;
01405                      }
01406                      else (ROC[uRocId].fHitTemp24[uGet4Id][ucChan]).Clear();
01407                } // if( kTRUE == fHitTemp.IsTimeSet() )
01408             }
01409                else
01410                {
01411                   // Leading edge
01412                   // clear anyway as time ordered, worst case there was another leading edge
01413                   // whose trailing edge is missing
01414                   (ROC[uRocId].fHitTemp24[uGet4Id][ucChan]).Clear();
01415                   (ROC[uRocId].fHitTemp24[uGet4Id][ucChan]).SetTime24Bits(
01416                         (ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][bBufferToBuild])[uMessageIndex] );
01417                }
01418          } // else of if( kTRUE == (ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][bOlderBuffer])[uMessageIndex].Is32Bit() )
01419    } // for loop over older buffer = full epoch one
01420    
01421    // Erase all messages until last accepted one
01422    // This can be done only if we don't mix event (always strictly consecutive events)
01423    
01424    if( kFALSE == fParam->bAllowEventMixing)
01425       (ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][bBufferToBuild]).erase(
01426          (ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][bBufferToBuild]).begin(),
01427          (ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][bBufferToBuild]).begin() + uLastAcceptedMessageIndex );
01428          
01429    /*
01430    cout<<"Building hits, size old = "<<(ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][bBufferToBuild]).size()<<" (buffer "<<bBufferToBuild<<" )";
01431    cout<<" size new = "<<(ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][bCurrentBuffer]).size()<<" (buffer "<<bCurrentBuffer<<" )"<<endl;
01432    */
01433 
01434    return kTRUE;
01435 }
01436 
01437 
01438 Bool_t TGet4v1Proc::CheckHit(UInt_t uRocId, UInt_t uGet4Id, Get4v1Hit& hit)
01439 {
01440    /* TODO FILL ME
01441     * Check if Get4 Hit matches the current trigger and
01442     * if yes save it in output event
01443     */
01444    Double_t dTimeToTrigger = 0.0;
01445    Bool_t bSelectedHit = kFALSE;
01446 
01447    if ( 0.0 < fCurrentGet4Event.fdTriggerFullTime[uRocId] )
01448    {
01449       dTimeToTrigger = hit.GetHitFullTimeD() - fCurrentGet4Event.fdTriggerFullTime[uRocId];
01450 
01451       fDeltaTriggerTime->Fill( dTimeToTrigger );
01452       ROC[uRocId].fTrigger_All->Fill( dTimeToTrigger );
01453       ROC[uRocId].fTrigger_All_100->Fill( dTimeToTrigger );
01454       ROC[uRocId].fTrigger_All_us->Fill( dTimeToTrigger );
01455       ROC[uRocId].fTrigger_All_ms->Fill( dTimeToTrigger );
01456       ROC[uRocId].fTrigger_All_s->Fill( dTimeToTrigger );
01457 
01458       UChar_t uGet4Chan = hit.GetChan();
01459       ROC[uRocId].fTrigger_Get4Channel[uGet4Id][uGet4Chan]->Fill( dTimeToTrigger );
01460       ROC[uRocId].fTriggerMs_Get4Channel[uGet4Id][uGet4Chan]->Fill( dTimeToTrigger );
01461       ROC[uRocId].fTriggerS_Get4Channel[uGet4Id][uGet4Chan]->Fill( dTimeToTrigger );
01462          
01463 
01464       if( kTRUE == ROC[uRocId].fTriggerWind->Test( dTimeToTrigger) )
01465       {
01466          bSelectedHit =kTRUE;
01467          // Hit is in trigger selection window => add it to the event
01468          ( ( fCurrentGet4Event.fGet4Boards[uGet4Id] ).fHits[ hit.GetChan() ]).push_back( hit );
01469 
01470          // Count per global time unit in s
01471          Double_t dSyncTm = hit.GetHitFullTimeD() / 100000000.0;
01472          ROC[uRocId].fSelectedT[uGet4Id][uGet4Chan]->Fill(( dSyncTm ) * 0.1);
01473 
01474          ROC[uRocId].fAllSelectedT->Fill(( dSyncTm ) * 0.1 );
01475          // Long duration time distribution (1 min. bin, 10 days length)
01476          if( kTRUE == fParam->bLongTimeHistos )
01477             ROC[uRocId].fAllSelLongT->Fill( (dSyncTm * 0.1 ) / 3600 );
01478 
01479          // Filling histos:
01480          if( 1 == fParam->bTotHistoEnable )
01481          {
01482             ROC[uRocId].fTot[uGet4Id][hit.GetChan()]->Fill( hit.GetTot() );
01483             if( hit.GetTot() < 0)
01484             {
01485                cout<<"Negative 24b ToT in Check: "<<hit.GetTot()<<endl;
01486                (hit.GetTimeMessage()).Print(roc::msg_print_Human);
01487                (hit.GetTotMessage()).Print(roc::msg_print_Human);
01488                cout<<endl;
01489             }
01490          }
01491          if( 1 == fParam->bDebugHistoEnable )
01492          {
01493             ROC[uRocId].fLeadingFTS[uGet4Id][hit.GetChan()]->Fill( hit.GetHitLeadingFTS() );
01494             if( kFALSE == hit.Is32Bit() )
01495                ROC[uRocId].fTrailingFTS[uGet4Id][hit.GetChan()]->Fill( hit.GetHitTrailingFTS() );
01496          } // if( 1 == fParam->bDebugHistoEnable )
01497       }
01498    } // if ( 0.0 < fCurrentGet4Event.fdTriggerFullTime[uRocId])
01499       else TGo4Log::Error("Trying to check a hit validity while no trigger found for current event");
01500       
01501    return bSelectedHit;
01502 }
01503 void TGet4v1Proc::CheckEventClosure()
01504 {
01505    /* TODO FILL ME
01506     * Checking if event finiched for all ROCs/GET4s
01507     * saving it
01508     */
01509 
01510    // If not trigger yet => no need to check!
01511    if( kFALSE == fCurrentGet4Event.HasTrigger() )
01512       return;
01513 
01514    Bool_t bAllFutureEpochsFinished = kTRUE;
01515    // Check flag indicating the extra epoch after trigger is passed
01516    for( UInt_t  uRocId =0; uRocId<fParam->numRocs; uRocId++ )
01517    {
01518       // do not check for non-used ROC
01519       if (!fParam->IsActiveRoc(uRocId)) continue;
01520 
01521       if( kFALSE == ROC[uRocId].fbSelectionRocDone )
01522          bAllFutureEpochsFinished = kFALSE;
01523 
01524       for( UInt_t uGet4 = 0; uGet4 < MAX_GET4_PER_ROC; uGet4++)
01525       {
01526          UInt_t uRemappedGet4Index = fParam->RemapGet4Chip(uRocId, uGet4);
01527          if( kTRUE == fParam->IsValidGet4Chip(uRemappedGet4Index) &&
01528              kTRUE == fParam->IsActiveGet4Chip(uRemappedGet4Index) )
01529             if( kFALSE == ROC[uRocId].fbSelectionDone[uGet4] )
01530                bAllFutureEpochsFinished = kFALSE;
01531       }
01532    }
01533 
01534    // extra epoch passed for all => save event
01535    if( kTRUE == bAllFutureEpochsFinished )
01536    {
01537       if( kFALSE == fCurrentGet4Event.IsEmpty() )
01538       {
01539          AnalyzeAllGet4Channels( fCurrentGet4Event );
01540          (fOutputEvent->fEvents).push_back( fCurrentGet4Event );
01541          for( UInt_t  uRocId =0; uRocId<fParam->numRocs; uRocId++ )
01542          {
01543             uNotEmptyEventInsideMbsEvtCount[uRocId]++;
01544             uNotEmptyRealEventsCount[uRocId]++;
01545          }
01546       } // if( kFALSE == fCurrentGet4Event.IsEmpty() )
01547 
01548       fCurrentGet4Event.Clear();
01549    } // if( kTRUE == bAllFutureEpochsFinished )
01550 }
01551 
01552 void TGet4v1Proc::ResetTrigger()
01553 {
01554    /* TODO FILL ME
01555     * Trigger resetting => Needed?
01556     */
01557 }
01558 
01559 
01560 void TGet4v1Proc::ResetEndOfBuffer()
01561 {
01562    /* TODO FILL ME
01563     * Buffer resetting => Needed?
01564     */
01565 }
01566 
01567 /**********************************************************************/
01568 /*
01569  * This function process the data message when it is a ROC Sync message
01570  */
01571 Bool_t TGet4v1Proc::ProcessRocSyncMessage( UInt_t uRocId, TGet4v1MessageExtended& extMess )
01572 {
01573    /*
01574     * ROC Sync message specific processing
01575     * TODO: Check on Sync number from current event to avoid
01576     * multiple events created for same sync when using more than 1 ROC
01577     */
01578    UInt_t uSyncId = (extMess.GetRocMessage()).getSyncChNum();
01579    ULong64_t ulFulltime = extMess.GetFullTime();
01580 
01581    // Recalculate the full Time to take into account also the epoch cycles
01582    ulFulltime  = (extMess.GetRocMessage()).getMsgFullTime(
01583                        ROC[uRocId].GetFullEpochNumber( ));
01584    ulFulltime += ROC[uRocId].GetSuperCycleEpOffset();
01585    extMess.SetFullTime(ulFulltime);
01586 
01587    if( uSyncId < MAX_SYNC )
01588    {
01589       ROC[uRocId].fLastSyncTm[uSyncId] = ulFulltime;
01590       ROC[uRocId].fLastSyncId[uSyncId] = (extMess.GetRocMessage()).getSyncData();
01591       /* TODO ?
01592       if (rocevent)
01593          rocevent->fLastSyncTm[uSyncId] = ulFulltime;
01594          */
01595 
01596       // Count per global time unit in s
01597       ULong64_t ulSyncTm = ulFulltime / 100000000L;
01598       ROC[uRocId].fSYNCt[uSyncId]->Fill((ulSyncTm % 36000) * 0.1);
01599 
01600       // Long duration time distribution (1 min. bin, 10 days length)
01601       if( kTRUE == fParam->bLongTimeHistos )
01602          ROC[uRocId].fSyncLongT[uSyncId]->Fill( (ulSyncTm * 0.1 ) / 3600 );
01603 
01604       if( kFALSE ==  fParam->bFreeStreaming || 0 == fParam->uNbTriggers )
01605          if( fParam->triggerSignal == (Int_t) (uSyncId + 10) ) // then may use it for new trigger
01606             ProcessTriggerMessage( uRocId, extMess );
01607    } // if( uSyncId < MAX_SYNC )
01608    return kTRUE;
01609 }
01610 /**********************************************************************/
01611 /*
01612  * This function process the data message when it is a ROC epoch message
01613  */
01614 Bool_t TGet4v1Proc::ProcessRocEpochMessage( UInt_t uRocId, TGet4v1MessageExtended& extMess )
01615 {
01616    /*
01617     * Roc epoch message specific processing
01618     */
01619    if( ROC[uRocId].fuCurrEpoch > (extMess.GetRocMessage()).getEpochNumber() )
01620    {
01621       ROC[uRocId].fuEpochCycle++;
01622       TGo4Log::Info("Roc Epoch cycle change: %u", ROC[uRocId].fuEpochCycle);
01623    }
01624    ROC[uRocId].fuCurrEpoch = (extMess.GetRocMessage()).getEpochNumber();
01625 
01626    // Recalculate the full Time to take into account also the epoch cycles
01627    ULong64_t ulFulltime = ((ULong64_t)  ROC[uRocId].GetFullEpochNumber() ) << 14;
01628    extMess.SetFullTime(ulFulltime);
01629 
01630    // Count per global time unit in s
01631    ULong64_t ulEpochTm = ulFulltime / 100000000L;
01632    ROC[uRocId].fEPOCHt->Fill((ulEpochTm % 36000) * 0.1);
01633 
01634    // Long duration time distribution (1 min. bin, 10 days length)
01635    if( kTRUE == fParam->bLongTimeHistos )
01636       ROC[uRocId].fEpochLongT->Fill( (ulEpochTm * 0.1 ) / 3600 );
01637 
01638    ROC[uRocId].fDistribEpochs->Fill( ROC[uRocId].fuCurrEpoch );
01639 
01640    if(  kTRUE == fCurrentGet4Event.HasTrigger() && 
01641        kFALSE == ROC[uRocId].fbSelectionRocDone  )
01642    {
01643       Double_t dTimeToTrigger = 0.0;
01644       dTimeToTrigger = extMess.GetFullTimeD() - fCurrentGet4Event.fdTriggerFullTime[uRocId];
01645       // If flag is kTRUE: we are at the second epoch since trigger
01646       // => rest of trigger epoch + 1 full epoch elapsed, enough for ordering issues
01647       // => close hit selection checks for ROC self message
01648       // If Epoch is out of the trigger window started on trigger
01649       // => all hits always contained inside epoch even if not time ordered
01650       // => No need to look at the next epoch!!!
01651       if( kTRUE == ROC[uRocId].fbEpochSinceTrigger ||
01652           kFALSE == ROC[uRocId].fTriggerWind->Test( dTimeToTrigger)  )
01653       {
01654          ROC[uRocId].fbSelectionRocDone  = kTRUE;
01655          ROC[uRocId].fbEpochSinceTrigger = kFALSE;
01656          CheckEventClosure();
01657       }
01658       else ROC[uRocId].fbEpochSinceTrigger = kTRUE;
01659    } // If selection of hits after trigger detection not over
01660 /*
01661    // TODO: Maybe necessary?
01662    // As no empty epoch there after data anymore, try to use ROC epoch as
01663    // empty epochs... unsafe because of ordering, but epochs with data
01664    // should anyway have the flag ON and an epoch2 message coming after,
01665    // thus keeping the ordering containment
01666    if( kTRUE == fParam->bSuppressedEpochs && kTRUE == fCurrentGet4Event.HasTrigger())
01667       for( UInt_t uGet4Id = 0; uGet4Id < MAX_GET4_PER_ROC; uGet4Id ++)
01668          if( kTRUE == fParam->IsActiveGet4Chip(uGet4Id) &&
01669               0 == ROC[uRocId].fuEpochWithData[uGet4Id] &&
01670               kFALSE == ROC[uRocId].fbSelectionDone[uGet4Id]  )
01671          {
01672             // A trigger is ongoing on this chip!
01673             if( kFALSE == ROC[uRocId].fbEpoch2SinceTrigger[uGet4Id] )
01674             {
01675                // This is the first epoch after the trigger
01676                // => time to look for the data in the epoch which was
01677                // ongoing when the trigger was found
01678 
01679                // If we did not process the epoch before the one where the
01680                // trigger came, we need to initialize the 24 bit temp hits
01681                if( kFALSE == ROC[uRocId].bLookInPreviousEpoch[uGet4Id] )
01682                   for( UInt_t uChan = 0; uChan < NB_CHAN_GET4; uChan++)
01683                         (ROC[uRocId].fHitTemp24[uGet4Id][uChan]).Clear();
01684 
01685                BuildHits(uRocId, uGet4Id, ROC[uRocId].fbBufferWithLastFullEpoch2[uGet4Id]);
01686                if( kFALSE == ROC[uRocId].bLookInNextEpoch[uGet4Id] )
01687                {
01688                   ROC[uRocId].fbSelectionDone[uGet4Id] = kTRUE;
01689                   CheckEventClosure();
01690                }
01691                ROC[uRocId].fbEpoch2SinceTrigger[uGet4Id] = kTRUE;
01692             } // if( kFALSE == ROC[uRocId].fbEpoch2SinceTrigger[uGet4Id] )
01693             else if( kTRUE == ROC[uRocId].fbEpoch2SinceTrigger[uGet4Id] &&
01694                       kTRUE == ROC[uRocId].bLookInNextEpoch[uGet4Id])
01695             {
01696                // This is the second epoch after the trigger and we detected on trigger
01697                // that the trigger window extend in epoch after the one where trigger
01698                // was found => time to look for the data in the epoch which just finished
01699                // and was the one just after the trigger epoch
01700                BuildHits(uRocId, uGet4Id, ROC[uRocId].fbBufferWithLastFullEpoch2[uGet4Id]);
01701                ROC[uRocId].fbSelectionDone[uGet4Id] = kTRUE;
01702                CheckEventClosure();
01703             } // else if( kTRUE == ROC[uRocId].fbEpoch2SinceTrigger[uGet4Id] && kFALSE == ROC[uRocId].bLookInNextEpoch[uGet4Id])
01704          } // if chip active and not over
01705 */
01706    // Swap the flag indicating which buffer contains currently happening epoch
01707    ROC[uRocId].fbBufferWithLastFullEpoch = ( kTRUE == ROC[uRocId].fbBufferWithLastFullEpoch ? kFALSE: kTRUE );
01708    // Clear this buffer (Data more than 1 full epoch old => either already selected or junk)
01709    ROC[uRocId].fPrevEpochsBuffer[ ROC[uRocId].fbBufferWithLastFullEpoch ].clear();
01710 
01711    return kTRUE;
01712 }
01713 /**********************************************************************/
01714 /*
01715  * This function process the data message when it is a GET4 epoch message
01716  */
01717 Bool_t TGet4v1Proc::ProcessGet4EpochMessage( UInt_t uRocId, TGet4v1MessageExtended& extMess )
01718 {
01719    /*
01720     * 24bit Get4 epoch message specific processing
01721     */
01722 
01723    UInt_t uGet4Id(0);
01724 
01725    // Remap the Get4 chip index => Go in Get4 indexing common to all ROCs
01726    uGet4Id = (extMess.GetRocMessage()).getEpoch2ChipNumber();
01727    uGet4Id = fParam->RemapGet4Chip( fParam->DefineGet4IndexOffset(uRocId) +  uGet4Id);
01728    extMess.SetEpoch2ChipNumber(uGet4Id);
01729 
01730    // Check if active chip
01731    if( kFALSE == fParam->IsValidGet4Chip(uGet4Id) )
01732    {
01733        cout << "Error: Bad chip nb in Epoch message = " << uGet4Id << endl;
01734        cout << " => This message will be skipped!!!! "<<endl;
01735        return kFALSE;
01736    }
01737    if( kFALSE == fParam->IsActiveGet4Chip(uGet4Id) )
01738    {
01739       // Masked chip, hopefully on purpose, don't complain & return
01740       return kFALSE;
01741    }
01742    
01743    if( kTRUE == fCurrentGet4Event.HasTrigger() && kFALSE == ROC[uRocId].fbSelectionDone[uGet4Id]  )
01744    {
01745       // A trigger is ongoing on this chip!
01746       if( kFALSE == ROC[uRocId].fbEpoch2SinceTrigger[uGet4Id] )
01747       {
01748          // This is the first epoch after the trigger
01749          // => time to look for the data in the epoch which was
01750          // ongoing when the trigger was found
01751          
01752          // If we did not process the epoch before the one where the 
01753          // trigger came, we need to initialize the 24 bit temp hits
01754          if( kFALSE == ROC[uRocId].bLookInPreviousEpoch[uGet4Id] )
01755             for( UInt_t uChan = 0; uChan < NB_CHAN_GET4; uChan++)
01756                   (ROC[uRocId].fHitTemp24[uGet4Id][uChan]).Clear();
01757                   
01758          BuildHits(uRocId, uGet4Id, ROC[uRocId].fbBufferWithLastFullEpoch2[uGet4Id]);
01759          if( kFALSE == ROC[uRocId].bLookInNextEpoch[uGet4Id] )
01760          {
01761             ROC[uRocId].fbSelectionDone[uGet4Id] = kTRUE;
01762             CheckEventClosure();
01763          }
01764          ROC[uRocId].fbEpoch2SinceTrigger[uGet4Id] = kTRUE;
01765       } // if( kFALSE == ROC[uRocId].fbEpoch2SinceTrigger[uGet4Id] )
01766       else if( kTRUE == ROC[uRocId].fbEpoch2SinceTrigger[uGet4Id] && 
01767                 kTRUE == ROC[uRocId].bLookInNextEpoch[uGet4Id])
01768       {
01769          // This is the second epoch after the trigger and we detected on trigger
01770          // that the trigger window extend in epoch after the one where trigger
01771          // was found => time to look for the data in the epoch which just finished
01772          // and was the one just after the trigger epoch
01773          BuildHits(uRocId, uGet4Id, ROC[uRocId].fbBufferWithLastFullEpoch2[uGet4Id]);
01774          ROC[uRocId].fbSelectionDone[uGet4Id] = kTRUE;
01775          CheckEventClosure();
01776       } // else if( kTRUE == ROC[uRocId].fbEpoch2SinceTrigger[uGet4Id] && kFALSE == ROC[uRocId].bLookInNextEpoch[uGet4Id])
01777    } // if( kTRUE == fCurrentGet4Event.HasTrigger() && kFALSE == ROC[uRocId].fbSelectionDone[uGet4Id]  )
01778 
01779    UInt_t get4_24b_ep_epoch = (extMess.GetRocMessage()).getEpoch2Number();
01780    if( ROC[uRocId].fuCurrEpoch2[uGet4Id] + 1 != get4_24b_ep_epoch &&
01781        ( 0 < ROC[uRocId].fuCurrEpoch2[uGet4Id] || 0 < ROC[uRocId].fuEpoch2Cycle[uGet4Id] ) &&
01782        !( GET4_EPOCH_CYCLE_SIZE == ROC[uRocId].fuCurrEpoch2[uGet4Id]  && 0 == get4_24b_ep_epoch ) )
01783    {
01784       TGo4Log::Info("Roc Get4 Epoch2 error in 24b mode");
01785       ROC[uRocId].fEpochShiftsPerChip->Fill( uGet4Id, (Int_t)get4_24b_ep_epoch - (Int_t)(ROC[uRocId].fuCurrEpoch2[uGet4Id]+1) );
01786 
01787       // Correction attempt: just calculating, not using it
01788       if( (Int_t)get4_24b_ep_epoch - (Int_t)(ROC[uRocId].fuCurrEpoch2[uGet4Id]+1) < 10 )
01789       {
01790          // close epochs ( < 250us) => probable not a full event missing
01791          if( 0 != ROC[uRocId].fiEpochShift[uGet4Id])
01792             ROC[uRocId].fEpochShiftsDuration[uGet4Id]->Fill(ROC[uRocId].fiEpochShift[uGet4Id],
01793                   ROC[uRocId].fuNbShiftedEpochs[uGet4Id] );
01794          ROC[uRocId].fiEpochShift[uGet4Id] += (Int_t)get4_24b_ep_epoch - (Int_t)(ROC[uRocId].fuCurrEpoch2[uGet4Id]+1) ;
01795          ROC[uRocId].fuNbShiftedEpochs[uGet4Id] = 0;
01796       }
01797          else
01798          {
01799             // far epochs ( > 250us) => probable a full event is missing
01800             if( 0 != ROC[uRocId].fiEpochShift[uGet4Id])
01801                ROC[uRocId].fEpochShiftsDuration[uGet4Id]->Fill(ROC[uRocId].fiEpochShift[uGet4Id],
01802                      ROC[uRocId].fuNbShiftedEpochs[uGet4Id] );
01803             ROC[uRocId].fiEpochShift[uGet4Id]      = 0 ;
01804             ROC[uRocId].fuNbShiftedEpochs[uGet4Id] = 0;
01805          }
01806    } // if non consecutive epoch indexes
01807       else
01808       {
01809          if( 0 != ROC[uRocId].fiEpochShift[uGet4Id] )
01810             ROC[uRocId].fuNbShiftedEpochs[uGet4Id]++;
01811       } // else of if non consecutive epoch indexes
01812 
01813    // Event statistics
01814    ROC[uRocId].fuNbHitsChipEpoch[uGet4Id] = 0;
01815 
01816    if( ROC[uRocId].fuCurrEpoch2[uGet4Id] > get4_24b_ep_epoch )
01817    {
01818       TGo4Log::Info("Roc Epoch2 cycle (24b mode) change: %u", ROC[uRocId].fuEpoch2Cycle);
01819       ROC[uRocId].fuEpoch2Cycle[uGet4Id]++;
01820    }
01821    ROC[uRocId].fuCurrEpoch2[uGet4Id] = get4_24b_ep_epoch;
01822 
01823    // In case of suppressed epochs, we will have only chip 0 epochs for all empty epochs
01824    // We then use these epochs for all other active chips
01825    // However, when a chip has data, its next epoch message should be present!!!
01826    if( kTRUE == fParam->bSuppressedEpochs )
01827    {
01828       // Assume Chip 0 are always there, even if disabled
01829       // TODO: test this and at some other behavior if needed
01830       if( 0 == uGet4Id )
01831          for( UInt_t uGet4IdBis = uGet4Id + 1; uGet4IdBis < MAX_GET4_PER_ROC; uGet4IdBis ++)
01832             if( kTRUE == fParam->IsActiveGet4Chip(uGet4IdBis) )
01833             {
01834                // In case no data was found in previous epoch for this chip, we use the epoch info
01835                // from chip 0
01836                if( 0 == ROC[uRocId].fuEpochWithData[uGet4IdBis])
01837                {
01838                   if( ROC[uRocId].fuCurrEpoch2[uGet4IdBis] + 1 != get4_24b_ep_epoch &&
01839                       ( 0 < ROC[uRocId].fuCurrEpoch2[uGet4IdBis] || 0 < ROC[uRocId].fuEpoch2Cycle[uGet4IdBis] ) &&
01840                       !( GET4_EPOCH_CYCLE_SIZE == ROC[uRocId].fuCurrEpoch2[uGet4IdBis]  && 0 == get4_24b_ep_epoch ) )
01841                   {
01842                      TGo4Log::Info("Roc Get4 Epoch2 error in 24b mode");
01843                      ROC[uRocId].fEpochShiftsPerChip->Fill( uGet4IdBis, (Int_t)get4_24b_ep_epoch - (Int_t)(ROC[uRocId].fuCurrEpoch2[uGet4IdBis]+1) );
01844 
01845                      // Correction attempt: just calculating, not using it
01846                      if( (Int_t)get4_24b_ep_epoch - (Int_t)(ROC[uRocId].fuCurrEpoch2[uGet4IdBis]+1) < 10 )
01847                      {
01848                         // close epochs ( < 250us) => probable not a full event missing
01849                         if( 0 != ROC[uRocId].fiEpochShift[uGet4IdBis])
01850                            ROC[uRocId].fEpochShiftsDuration[uGet4IdBis]->Fill(ROC[uRocId].fiEpochShift[uGet4IdBis],
01851                                  ROC[uRocId].fuNbShiftedEpochs[uGet4IdBis] );
01852                         ROC[uRocId].fiEpochShift[uGet4IdBis] += (Int_t)get4_24b_ep_epoch - (Int_t)(ROC[uRocId].fuCurrEpoch2[uGet4IdBis]+1) ;
01853                         ROC[uRocId].fuNbShiftedEpochs[uGet4IdBis] = 0;
01854                      }
01855                         else
01856                         {
01857                            // far epochs ( > 250us) => probable a full event is missing
01858                            if( 0 != ROC[uRocId].fiEpochShift[uGet4IdBis])
01859                               ROC[uRocId].fEpochShiftsDuration[uGet4IdBis]->Fill(ROC[uRocId].fiEpochShift[uGet4IdBis],
01860                                     ROC[uRocId].fuNbShiftedEpochs[uGet4IdBis] );
01861                            ROC[uRocId].fiEpochShift[uGet4IdBis]      = 0 ;
01862                            ROC[uRocId].fuNbShiftedEpochs[uGet4IdBis] = 0;
01863                         }
01864                   } // if non consecutive epoch indexes
01865                      else
01866                      {
01867                         if( 0 != ROC[uRocId].fiEpochShift[uGet4IdBis] )
01868                            ROC[uRocId].fuNbShiftedEpochs[uGet4IdBis]++;
01869                      } // else of if non consecutive epoch indexes
01870 
01871                   // Event statistics
01872                   ROC[uRocId].fuNbHitsChipEpoch[uGet4IdBis] = 0;
01873 
01874                   if( ROC[uRocId].fuCurrEpoch2[uGet4IdBis] > get4_24b_ep_epoch )
01875                   {
01876                      TGo4Log::Info("Roc Epoch2 cycle (24b mode) change: %u", ROC[uRocId].fuEpoch2Cycle);
01877                      ROC[uRocId].fuEpoch2Cycle[uGet4IdBis]++;
01878                   }
01879                   ROC[uRocId].fuCurrEpoch2[uGet4IdBis] = get4_24b_ep_epoch;
01880                } // if( 0 == ROC[uRocId].fuEpochWithData[uGet4IdBis])
01881                   // If data just increase the flag, should not hurt,
01882                   // just in case the epoch messages are not always coming ordered the way I expect
01883                   else ROC[uRocId].fuEpochWithData[uGet4IdBis]++;
01884             } // if( kTRUE == fParam->IsActiveGet4Chip(uGet4IdBis) )
01885 
01886       ROC[uRocId].fuEpochWithData[uGet4Id] = 0;
01887    } // if( kTRUE == fParam->bSuppressedEpochs)
01888 
01889    // Recalculate the full Time to take into account also the epoch2 cycles
01890    ULong64_t uFullTimeBins = ((ULong64_t)  ROC[uRocId].GetFullEpoch2Number( uGet4Id )) << 19;
01891    ULong64_t uFullTime = uFullTimeBins/ 20 + 512;
01892    Double_t  dFullTime = uFullTimeBins / 20. + 512.;
01893    extMess.SetFullTime(  uFullTime );
01894    extMess.SetFullTimeD( dFullTime );
01895    
01896    // Set The ROC epoch2 counter and cycle counter
01897    extMess.SetRocEpoch( ROC[uRocId].fuCurrEpoch2[uGet4Id] );
01898    extMess.SetRocCycle( ROC[uRocId].fuEpoch2Cycle[uGet4Id] );
01899 
01900    // Count per global time unit in s
01901    ULong64_t ulEpochTm = uFullTime / 100000000L;
01902    ROC[uRocId].fEPOCH2t[uGet4Id]->Fill((ulEpochTm % 36000) * 0.1);
01903 
01904    // Long duration time distribution (1 min. bin, 10 days length)
01905    if( kTRUE == fParam->bLongTimeHistos )
01906       ROC[uRocId].fAllEpoch2LongT->Fill( (ulEpochTm * 0.1 ) / 3600 );
01907 
01908    ROC[uRocId].fDistribEpochs2->Fill(uGet4Id, ROC[uRocId].fuCurrEpoch2[uGet4Id]);
01909    
01910    // Swap the flag indicating which buffer contains currently happening epoch
01911    ROC[uRocId].fbBufferWithLastFullEpoch2[uGet4Id] = ( kTRUE == ROC[uRocId].fbBufferWithLastFullEpoch2[uGet4Id] ? kFALSE: kTRUE );
01912    // Clear this buffer (Data more than 1 full epoch old => either already selected or junk)
01913    ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][ ROC[uRocId].fbBufferWithLastFullEpoch2[uGet4Id] ].clear();
01914 
01915    return kTRUE;
01916 }
01917 /**********************************************************************/
01918 /*
01919  * This function process the data message when it is a GET4 data message
01920  */
01921 Bool_t TGet4v1Proc::ProcessGet4DataMessage( UInt_t uRocId, TGet4v1MessageExtended& extMess )
01922 {
01923    /*
01924     * 24bit Get4 hit message specific processing
01925     *
01926     * TODO
01927     * Make the get4_index consistent everywhere between global get4 index and inside roc get4 index
01928     */
01929 
01930    if (ROC[uRocId].bIgnoreData) return kFALSE;
01931 
01932    if( kFALSE == ROC[uRocId].fb24bitsReadoutDetected )
01933    {
01934       ROC[uRocId].fb24bitsReadoutDetected = kTRUE;
01935       fb24bitsReadoutDetected = kTRUE;
01936       // As it is first 24bit message, let's create
01937       // 24bit specific histograms
01938       char folder[30];
01939       sprintf(folder,"ROC%u/",uRocId);
01940 
01941       /*
01942        * 24 bits specific histograms
01943        */
01944       ROC[uRocId].fChannelInputMessCount = MakeTH1( 'I', Form("%sRoc%u_ChanCounts", folder, uRocId),
01945             "Channel multiplicity per event",
01946             2*NB_CHAN_GET4*MAX_GET4_PER_ROC, 0, MAX_GET4_PER_ROC ,
01947             "Channel []", "# Mess []" );
01948       ROC[uRocId].fb24bitsReadoutDetected = kTRUE;
01949    } // if( kFALSE == ROC[uRocId].fb24bitsReadoutDetected )
01950 
01951    UInt_t    uGet4Id(0), uGet4Ch(0), uGet4Edge(0);
01952    uGet4Id   = (extMess.GetRocMessage()).getGet4Number();
01953    uGet4Ch   = (extMess.GetRocMessage()).getGet4ChNum();
01954    uGet4Edge = (extMess.GetRocMessage()).getGet4Edge();
01955 
01956    // Remap the Get4 chip index
01957    uGet4Id = (extMess.GetRocMessage()).getGet4Number();
01958    uGet4Id = fParam->RemapGet4Chip( fParam->DefineGet4IndexOffset(uRocId) + uGet4Id);
01959    extMess.SetGet4Number(uGet4Id);
01960 
01961    // Check if valid chip
01962    if( kFALSE == fParam->IsValidGet4Chip(uGet4Id) )
01963    {
01964        cout << "Error: Bad chip nb in Data message = " << uGet4Id << endl;
01965        cout << " => This message will be skipped!!!! "<<endl;
01966        return kFALSE;
01967    }
01968    if( kFALSE == fParam->IsActiveGet4Chip(uGet4Id) )
01969    {
01970       // Masked chip, hopefully on purpose, don't complain & return
01971       return kFALSE;
01972    }
01973 
01974    // Recalculate the full Time to take into account also the epoch2 cycles
01975    ULong64_t uFullTimeBins = ((ULong64_t)  ROC[uRocId].GetFullEpoch2Number( uGet4Id ) << 19) |
01976                               (ULong64_t)extMess.GetGet4Ts();
01977    ULong64_t uFullTime = uFullTimeBins/ 20 + 512;
01978    Double_t  dFullTime = ((Double_t)uFullTimeBins)*0.05 + 512.;
01979    extMess.SetFullTime(  uFullTime );
01980    extMess.SetFullTimeD( dFullTime );
01981    
01982    // Set The ROC epoch2 counter and cycle counter
01983    extMess.SetRocEpoch( ROC[uRocId].fuCurrEpoch2[uGet4Id] );
01984    extMess.SetRocCycle( ROC[uRocId].fuEpoch2Cycle[uGet4Id] );
01985    
01986 
01987    // Count per global time unit in s
01988    ULong64_t ulDataTm = uFullTime / 100000000L;
01989    ROC[uRocId].fDATAt->Fill((ulDataTm % 36000) * 0.1);
01990 
01991    // Long duration time distribution (1 min. bin, 10 days length)
01992    if( kTRUE == fParam->bLongTimeHistos )
01993       ROC[uRocId].fDataLongT->Fill( (ulDataTm * 0.1 ) / 3600 );
01994 
01995    // Event statistics
01996    ROC[uRocId].fChannelInputMessCount->Fill( uGet4Id + (Double_t)uGet4Ch/(Double_t)NB_CHAN_GET4
01997                                                      + (Double_t)uGet4Edge/(Double_t)(2*NB_CHAN_GET4)  );
01998    if( kTRUE == fParam->bChipRateHistoEnable )
01999       ROC[uRocId].fChipRateEvolution[uGet4Id]->Fill(
02000             (uFullTimeBins ) * 0.1, 1.0/ROC[uRocId].fdRateEvolutionBinSize );
02001    if( kTRUE == fParam->bChannelRateHistoEnable )
02002       ROC[uRocId].fChannelRateEvolution[uGet4Id][uGet4Ch]->Fill(
02003             (uFullTimeBins ) * 0.1, 1.0/ROC[uRocId].fdRateEvolutionBinSize );
02004    ROC[uRocId].fuNbHitsChipEpoch[uGet4Id] ++;
02005 
02006    // Early event closure check
02007    if( kTRUE == fCurrentGet4Event.HasTrigger() &&
02008        kFALSE == ROC[uRocId].fbSelectionDone[uGet4Id]  )
02009    {
02010       Double_t dTimeToTrigger = 0.0;
02011       dTimeToTrigger = extMess.GetFullTimeD() - fCurrentGet4Event.fdTriggerFullTime[uRocId];
02012       if( kFALSE == ROC[uRocId].fTriggerWind->Test( dTimeToTrigger) )
02013       {
02014          // Message after the end of trigger window!!
02015          Bool_t bAllChanInChipOver = kTRUE;
02016 
02017          // If there was already a message from the same channel & edge out of the trigger
02018          //  window, then the token ring made at least one full turn => ok for all
02019          // Otherwise: need to check other channels/edge status
02020          if( (kFALSE == ROC[uRocId].fbDataTimeOut[uGet4Id][uGet4Ch] && 0 == uGet4Edge ) ||
02021              (kFALSE == ROC[uRocId].fbDataFallingOut[uGet4Id][uGet4Ch] && 1 == uGet4Edge ) )
02022          {
02023             // 24b = always a edge not a hit => need to check both !
02024             if( 0 == uGet4Edge )
02025                ROC[uRocId].fbDataTimeOut[uGet4Id][uGet4Ch] = kTRUE;
02026                else ROC[uRocId].fbDataFallingOut[uGet4Id][uGet4Ch] = kTRUE;
02027             // Check if chip fully finished
02028             for(UInt_t uChanTest = 0; uChanTest < NB_CHAN_GET4; uChanTest ++)
02029             {
02030                if( kFALSE ==  ROC[uRocId].fbDataTimeOut[uGet4Id][uChanTest] )
02031                   bAllChanInChipOver = kFALSE;
02032                if( kFALSE ==  ROC[uRocId].fbDataFallingOut[uGet4Id][uChanTest] )
02033                   bAllChanInChipOver = kFALSE;
02034             }
02035          } // if same edge not already out of trigger once
02036 
02037          // If chip fully finished: don't wait for the next epoch to close future buffer
02038          // of current event for this chip
02039          if( kTRUE == bAllChanInChipOver)
02040          {
02041             // If This is the first epoch after the trigger and 
02042             // we did not process the epoch before the one where the 
02043             // trigger came, we need to initialize the 24 bit temp hits
02044             if( kFALSE == ROC[uRocId].fbEpoch2SinceTrigger[uGet4Id] && 
02045                 kFALSE == ROC[uRocId].bLookInPreviousEpoch[uGet4Id] )
02046                for( UInt_t uChan = 0; uChan < NB_CHAN_GET4; uChan++)
02047                      (ROC[uRocId].fHitTemp24[uGet4Id][uChan]).Clear();
02048                      
02049             BuildHits(uRocId, uGet4Id, ROC[uRocId].fbBufferWithLastFullEpoch2[uGet4Id]);
02050             ROC[uRocId].fbSelectionDone[uGet4Id] = kTRUE;
02051             CheckEventClosure();
02052             
02053             for(UInt_t uChanTest = 0; uChanTest < NB_CHAN_GET4; uChanTest ++)
02054             {
02055                ROC[uRocId].fbDataTimeOut[uGet4Id][uChanTest] = kFALSE;
02056                ROC[uRocId].fbDataFallingOut[uGet4Id][uChanTest] = kFALSE;
02057             }
02058          } // if( kTRUE == bAllChanInChipOver)
02059       } // if( kFALSE == ROC[uRocId].fTriggerWind->Test( dTimeToTrigger) )
02060    } // Event ongoing with a detected trigger and chip did not finished all its buffers
02061 
02063    if( kTRUE ==  fParam->bFreeStreaming && 0 < fParam->uNbTriggers )
02064    {
02066       if( 0 == uGet4Edge )
02067       {
02068          for( Int_t iMainTriggerIndex = 0; iMainTriggerIndex < (Int_t)(fParam->uNbTriggers); iMainTriggerIndex++ )
02069             if( kTRUE == fParam->IsMainOfThisTrigger( iMainTriggerIndex, uGet4Id, uGet4Ch ) )
02070          {
02071             ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex] = extMess;
02072             /*
02073              * TODO: call to ProcessTrigger
02074              * TEMP: histo Filling + counting
02075              */
02076             Bool_t bAllInCoinc = kTRUE;
02077             for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iMainTriggerIndex]; uSecChannel++)
02078             {
02079                Double_t dDistanceToMain = ROC[uRocId].fdLastFullTimeSecChannel[iMainTriggerIndex][uSecChannel]
02080                                         - extMess.GetFullTimeD();
02081                if( dDistanceToMain < fParam->dCoincidenceWindowStart[iMainTriggerIndex] ||
02082                      fParam->dCoincidenceWindowStop[iMainTriggerIndex] < dDistanceToMain      )
02083                {
02084                   bAllInCoinc = kFALSE;
02085                   break;
02086                } // if out of coincidence window
02087                Double_t dTotDistanceToMain = ROC[uRocId].fdLastFullTimeSecChannelTot[iMainTriggerIndex][uSecChannel]
02088                                         - extMess.GetFullTimeD();
02089                if( dTotDistanceToMain < fParam->dCoincidenceWindowStart[iMainTriggerIndex] ||
02090                      fParam->dCoincidenceWindowStop[iMainTriggerIndex] < dTotDistanceToMain      )
02091                {
02092                   bAllInCoinc = kFALSE;
02093                   break;
02094                } // if out of coincidence window
02095             } // for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iMainTriggerIndex]; uSecChannel++)
02096             
02097             // Check if tot edge of the main channel is in trigger window
02098             Double_t dTotMainDistanceToMain = ROC[uRocId].fdLastFullTimeMainChannelTot[iMainTriggerIndex]
02099                               - ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTimeD();
02100             if( dTotMainDistanceToMain < fParam->dCoincidenceWindowStart[iMainTriggerIndex] ||
02101                   fParam->dCoincidenceWindowStop[iMainTriggerIndex] < dTotMainDistanceToMain      )
02102             {
02103                bAllInCoinc = kFALSE;
02104             } // if out of coincidence window
02105             
02106             if( kTRUE == bAllInCoinc )
02107             {
02108                Double_t dSameTriggerDistance =
02109                        ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTimeD()
02110                      - ROC[uRocId].fdLastFullTimeSelfTrigger[iMainTriggerIndex] ;
02111 
02112                ROC[uRocId].fDataSelfTrigDistanceNs->Fill( dSameTriggerDistance,     iMainTriggerIndex );
02113                ROC[uRocId].fDataSelfTrigDistanceUs->Fill( dSameTriggerDistance/1e3, iMainTriggerIndex );
02114                ROC[uRocId].fDataSelfTrigDistanceMs->Fill( dSameTriggerDistance/1e6, iMainTriggerIndex );
02115                ROC[uRocId].fDataSelfTrigDistanceS->Fill(  dSameTriggerDistance/1e9, iMainTriggerIndex );
02116 
02117                if( fParam->dDeadTime <= dSameTriggerDistance )
02118                {
02119                   // Here we have a DATA self-trigger!!!!!!
02120                   ROC[uRocId].fuDataSelfTriggerCount[iMainTriggerIndex] ++;
02121 
02122                   ROC[uRocId].fdLastFullTimeSelfTrigger[iMainTriggerIndex] =
02123                         ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTimeD();
02124 
02125                   ULong64_t uFullTimeSelfTrigBins = ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTime();
02126                   uFullTimeSelfTrigBins /= 100000000L;
02127                   ROC[uRocId].fSelfTriggT->Fill( (uFullTimeSelfTrigBins % 36000) * 0.1 );
02128                   
02129                   // Long duration time distribution (1 min. bin, 10 days length)
02130                   if( kTRUE == fParam->bLongTimeHistos )
02131                      ROC[uRocId].fSelfTriggLongT->Fill( (uFullTimeSelfTrigBins * 0.1 ) / 3600 );
02132 
02133                   ProcessTriggerMessage(uRocId, ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex], iMainTriggerIndex);
02134                } // if( fParam->dDeadTime <= dSameTriggerDistance )
02135             } // if( kTRUE == bAllInCoinc )
02136          } // if( -1 < iMainTriggerIndex )
02137 
02138          for( Int_t iSecTriggerIndex = 0; iSecTriggerIndex < (Int_t)(fParam->uNbTriggers); iSecTriggerIndex++ )
02139          {
02140             if( kTRUE == fParam->IsSecOfThisTrigger( iSecTriggerIndex, uGet4Id, uGet4Ch ) )
02141             {
02142                Int_t iSecondaryIndex = fParam->GetSecChannelIndex(iSecTriggerIndex, uGet4Id, uGet4Ch);
02143                if( -1 < iSecondaryIndex )
02144                {
02145                   ROC[uRocId].fdLastFullTimeSecChannel[iSecTriggerIndex][iSecondaryIndex] = extMess.GetFullTimeD();
02146 
02147                   /*
02148                    * TODO: call to ProcessTrigger
02149                    * TEMP: histo Filling + counting
02150                    */
02151                   Bool_t bAllInCoinc = kTRUE;
02152                   for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iSecTriggerIndex]; uSecChannel++)
02153                   {
02154                      Double_t dDistanceToMain = ROC[uRocId].fdLastFullTimeSecChannel[iSecTriggerIndex][uSecChannel]
02155                                        - ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD();
02156                      if( dDistanceToMain < fParam->dCoincidenceWindowStart[iSecTriggerIndex] ||
02157                            fParam->dCoincidenceWindowStop[iSecTriggerIndex] < dDistanceToMain      )
02158                      {
02159                         bAllInCoinc = kFALSE;
02160                         break;
02161                      } // if out of coincidence window
02162                         
02163                      // Check if tot edge is in trigger window, only needed in 24b mode
02164                      Double_t dTotDistanceToMain = ROC[uRocId].fdLastFullTimeSecChannelTot[iSecTriggerIndex][uSecChannel]
02165                                        - ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD();
02166                      if( dTotDistanceToMain < fParam->dCoincidenceWindowStart[iSecTriggerIndex] ||
02167                            fParam->dCoincidenceWindowStop[iSecTriggerIndex] < dTotDistanceToMain      )
02168                      {
02169                         bAllInCoinc = kFALSE;
02170                         break;
02171                      } // if out of coincidence window
02172                   } // for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iSecTriggerIndex]; uSecChannel++)
02173                      
02174                   // Check if tot edge of the main channel is in trigger window, only needed in 24b mode
02175                   Double_t dTotMainDistanceToMain = ROC[uRocId].fdLastFullTimeMainChannelTot[iSecTriggerIndex]
02176                                     - ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD();
02177                   if( dTotMainDistanceToMain < fParam->dCoincidenceWindowStart[iSecTriggerIndex] ||
02178                         fParam->dCoincidenceWindowStop[iSecTriggerIndex] < dTotMainDistanceToMain      )
02179                   {
02180                      bAllInCoinc = kFALSE;
02181                   } // if out of coincidence window
02182                      
02183                   if( kTRUE == bAllInCoinc  )
02184                   {
02185                      Double_t dSameTriggerDistance =
02186                              ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD()
02187                            - ROC[uRocId].fdLastFullTimeSelfTrigger[iSecTriggerIndex] ;
02188 
02189                      ROC[uRocId].fDataSelfTrigDistanceNs->Fill( dSameTriggerDistance,     iSecTriggerIndex );
02190                      ROC[uRocId].fDataSelfTrigDistanceUs->Fill( dSameTriggerDistance/1e3, iSecTriggerIndex );
02191                      ROC[uRocId].fDataSelfTrigDistanceMs->Fill( dSameTriggerDistance/1e6, iSecTriggerIndex );
02192                      ROC[uRocId].fDataSelfTrigDistanceS->Fill(  dSameTriggerDistance/1e9, iSecTriggerIndex );
02193 
02194                      if( fParam->dDeadTime <= dSameTriggerDistance )
02195                      {
02196                         // Here we have a DATA self-trigger!!!!!!
02197                         ROC[uRocId].fuDataSelfTriggerCount[iSecTriggerIndex] ++;
02198 
02199                         ROC[uRocId].fdLastFullTimeSelfTrigger[iSecTriggerIndex] =
02200                               ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD();
02201 
02202                         ULong64_t uFullTimeSelfTrigBins = ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTime();
02203                         uFullTimeSelfTrigBins /= 100000000L;
02204                         ROC[uRocId].fSelfTriggT->Fill( (uFullTimeSelfTrigBins % 36000) * 0.1 );
02205 
02206                         // Long duration time distribution (1 min. bin, 10 days length)
02207                         if( kTRUE == fParam->bLongTimeHistos )
02208                            ROC[uRocId].fSelfTriggLongT->Fill( (uFullTimeSelfTrigBins * 0.1 ) / 3600 );
02209 
02210                         ProcessTriggerMessage(uRocId, ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex], iSecTriggerIndex);
02211                      } // if( fParam->dDeadTime <= dSameTriggerDistance )
02212                   } // if( kTRUE == bAllInCoinc  )
02213                } // if( -1 < iSecondaryIndex )
02214             } //  if( -1 < iSecTriggerIndex )
02215          } // for( Int_t iSecTriggerIndex = 0; iSecTriggerIndex < (Int_t)(fParam->uNbTriggers); iSecTriggerIndex++ )
02216       }// if( 0 == uGet4Edge )
02218          else
02219          {
02220             // Falling edge
02221             for( Int_t iMainTriggerIndex = 0; iMainTriggerIndex < (Int_t)(fParam->uNbTriggers); iMainTriggerIndex++ )
02222                if( kTRUE == fParam->IsMainOfThisTrigger( iMainTriggerIndex, uGet4Id, uGet4Ch ) )
02223             {
02224                ROC[uRocId].fdLastFullTimeMainChannelTot[iMainTriggerIndex] = extMess.GetFullTimeD();
02225                      
02226                Bool_t bAllInCoinc = kTRUE;
02227                for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iMainTriggerIndex]; uSecChannel++)
02228                {
02229                   // Check if time edge is in trigger window
02230                   Double_t dDistanceToMain = ROC[uRocId].fdLastFullTimeSecChannel[iMainTriggerIndex][uSecChannel]
02231                                     - ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTimeD();
02232                   if( dDistanceToMain < fParam->dCoincidenceWindowStart[iMainTriggerIndex] ||
02233                         fParam->dCoincidenceWindowStop[iMainTriggerIndex] < dDistanceToMain      )
02234                   {
02235                      bAllInCoinc = kFALSE;
02236                      break;
02237                   } // if out of coincidence window
02238                   
02239                   // Check if tot edge is in trigger window, only needed in 24b mode
02240                   Double_t dTotDistanceToMain = ROC[uRocId].fdLastFullTimeSecChannelTot[iMainTriggerIndex][uSecChannel]
02241                                     - ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTimeD();
02242                   if( dTotDistanceToMain < fParam->dCoincidenceWindowStart[iMainTriggerIndex] ||
02243                         fParam->dCoincidenceWindowStop[iMainTriggerIndex] < dTotDistanceToMain      )
02244                   {
02245                      bAllInCoinc = kFALSE;
02246                      break;
02247                   } // if out of coincidence window
02248                } // for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iMainTriggerIndex]; uSecChannel++)
02249                
02250                // Check if tot edge of the main channel is in trigger window, only needed in 24b mode
02251                Double_t dTotMainDistanceToMain = ROC[uRocId].fdLastFullTimeMainChannelTot[iMainTriggerIndex]
02252                                  - ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTimeD();
02253                if( dTotMainDistanceToMain < fParam->dCoincidenceWindowStart[iMainTriggerIndex] ||
02254                      fParam->dCoincidenceWindowStop[iMainTriggerIndex] < dTotMainDistanceToMain      )
02255                {
02256                   bAllInCoinc = kFALSE;
02257                } // if out of coincidence window
02258                
02259                if( kTRUE == bAllInCoinc  )
02260                {
02261                   Double_t dSameTriggerDistance =
02262                           ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTimeD()
02263                         - ROC[uRocId].fdLastFullTimeSelfTrigger[iMainTriggerIndex] ;
02264 
02265                   ROC[uRocId].fDataSelfTrigDistanceNs->Fill( dSameTriggerDistance,     iMainTriggerIndex );
02266                   ROC[uRocId].fDataSelfTrigDistanceUs->Fill( dSameTriggerDistance/1e3, iMainTriggerIndex );
02267                   ROC[uRocId].fDataSelfTrigDistanceMs->Fill( dSameTriggerDistance/1e6, iMainTriggerIndex );
02268                   ROC[uRocId].fDataSelfTrigDistanceS->Fill(  dSameTriggerDistance/1e9, iMainTriggerIndex );
02269 
02270                   if( fParam->dDeadTime <= dSameTriggerDistance )
02271                   {
02272                      // Here we have a DATA self-trigger!!!!!!
02273                      ROC[uRocId].fuDataSelfTriggerCount[iMainTriggerIndex] ++;
02274 
02275                      ROC[uRocId].fdLastFullTimeSelfTrigger[iMainTriggerIndex] =
02276                            ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTimeD();
02277 
02278                      ULong64_t uFullTimeSelfTrigBins = ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTime();
02279                      uFullTimeSelfTrigBins /= 100000000L;
02280                      ROC[uRocId].fSelfTriggT->Fill( (uFullTimeSelfTrigBins % 36000) * 0.1 );
02281 
02282                      // Long duration time distribution (1 min. bin, 10 days length)
02283                      if( kTRUE == fParam->bLongTimeHistos )
02284                         ROC[uRocId].fSelfTriggLongT->Fill( (uFullTimeSelfTrigBins * 0.1 ) / 3600 );
02285 
02286                      ProcessTriggerMessage(uRocId, ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex], iMainTriggerIndex);
02287                   } // if( fParam->dDeadTime <= dSameTriggerDistance )
02288                } // if( kTRUE == bAllInCoinc  )
02289             } // if( kTRUE == fParam->IsMainOfThisTrigger( iMainTriggerIndex, uGet4Id, uGet4Ch ) )
02290             
02291             for( Int_t iSecTriggerIndex = 0; iSecTriggerIndex < (Int_t)(fParam->uNbTriggers); iSecTriggerIndex++ )
02292             {
02293                if( kTRUE == fParam->IsSecOfThisTrigger( iSecTriggerIndex, uGet4Id, uGet4Ch ) )
02294                {
02295                   Int_t iSecondaryIndex = fParam->GetSecChannelIndex(iSecTriggerIndex, uGet4Id, uGet4Ch);
02296                   if( -1 < iSecondaryIndex )
02297                   {
02298                      ROC[uRocId].fdLastFullTimeSecChannelTot[iSecTriggerIndex][iSecondaryIndex] = extMess.GetFullTimeD();
02299                      
02300                      Bool_t bAllInCoinc = kTRUE;
02301                      for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iSecTriggerIndex]; uSecChannel++)
02302                      {
02303                         // Check if time edge is in trigger window
02304                         Double_t dDistanceToMain = ROC[uRocId].fdLastFullTimeSecChannel[iSecTriggerIndex][uSecChannel]
02305                                           - ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD();
02306                         if( dDistanceToMain < fParam->dCoincidenceWindowStart[iSecTriggerIndex] ||
02307                               fParam->dCoincidenceWindowStop[iSecTriggerIndex] < dDistanceToMain      )
02308                         {
02309                            bAllInCoinc = kFALSE;
02310                            break;
02311                         } // if out of coincidence window
02312                         
02313                         // Check if tot edge is in trigger window
02314                         Double_t dTotDistanceToMain = ROC[uRocId].fdLastFullTimeSecChannelTot[iSecTriggerIndex][uSecChannel]
02315                                           - ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD();
02316                         if( dTotDistanceToMain < fParam->dCoincidenceWindowStart[iSecTriggerIndex] ||
02317                               fParam->dCoincidenceWindowStop[iSecTriggerIndex] < dTotDistanceToMain      )
02318                         {
02319                            bAllInCoinc = kFALSE;
02320                            break;
02321                         } // if out of coincidence window
02322                      } // for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iSecTriggerIndex]; uSecChannel++)
02323                      
02324                      // Check if tot edge of the main channel is in trigger window
02325                      Double_t dTotMainDistanceToMain = ROC[uRocId].fdLastFullTimeMainChannelTot[iSecTriggerIndex]
02326                                        - ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD();
02327                      if( dTotMainDistanceToMain < fParam->dCoincidenceWindowStart[iSecTriggerIndex] ||
02328                            fParam->dCoincidenceWindowStop[iSecTriggerIndex] < dTotMainDistanceToMain      )
02329                      {
02330                         bAllInCoinc = kFALSE;
02331                      } // if out of coincidence window
02332                      
02333                      if( kTRUE == bAllInCoinc  )
02334                      {
02335                         Double_t dSameTriggerDistance =
02336                                 ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD()
02337                               - ROC[uRocId].fdLastFullTimeSelfTrigger[iSecTriggerIndex] ;
02338 
02339                         ROC[uRocId].fDataSelfTrigDistanceNs->Fill( dSameTriggerDistance,     iSecTriggerIndex );
02340                         ROC[uRocId].fDataSelfTrigDistanceUs->Fill( dSameTriggerDistance/1e3, iSecTriggerIndex );
02341                         ROC[uRocId].fDataSelfTrigDistanceMs->Fill( dSameTriggerDistance/1e6, iSecTriggerIndex );
02342                         ROC[uRocId].fDataSelfTrigDistanceS->Fill(  dSameTriggerDistance/1e9, iSecTriggerIndex );
02343 
02344                         if( fParam->dDeadTime <= dSameTriggerDistance )
02345                         {
02346                            // Here we have a DATA self-trigger!!!!!!
02347                            ROC[uRocId].fuDataSelfTriggerCount[iSecTriggerIndex] ++;
02348 
02349                            ROC[uRocId].fdLastFullTimeSelfTrigger[iSecTriggerIndex] =
02350                                  ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD();
02351 
02352                            ULong64_t uFullTimeSelfTrigBins = ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTime();
02353                            uFullTimeSelfTrigBins /= 100000000L;
02354                            ROC[uRocId].fSelfTriggT->Fill( (uFullTimeSelfTrigBins % 36000) * 0.1 );
02355 
02356                            // Long duration time distribution (1 min. bin, 10 days length)
02357                            if( kTRUE == fParam->bLongTimeHistos )
02358                               ROC[uRocId].fSelfTriggLongT->Fill( (uFullTimeSelfTrigBins * 0.1 ) / 3600 );
02359 
02360                            ProcessTriggerMessage(uRocId, ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex], iSecTriggerIndex);
02361                         } // if( fParam->dDeadTime <= dSameTriggerDistance )
02362                      } // if( kTRUE == bAllInCoinc  )
02363                   } // if( -1 < iSecondaryIndex )
02364                } // if( kTRUE == fParam->IsSecOfThisTrigger( iSecTriggerIndex, uGet4Id, uGet4Ch ) )
02365             } // for( Int_t iSecTriggerIndex = 0; iSecTriggerIndex < (Int_t)(fParam->uNbTriggers); iSecTriggerIndex++ )
02366          } // else if( 0 == uGet4Edge )
02367    } // if( kTRUE ==  fParam->bFreeStreaming && 0 < fParam->uNbTriggers && 0 == uGet4Edge )
02368 
02369    return kTRUE;
02370 }
02371 /**********************************************************************/
02372 /*
02373  * This function process the data message when it is a GET4 External Synch
02374  */
02375 Bool_t TGet4v1Proc::ProcessGet4ExtSyncMessage( UInt_t uRocId, TGet4v1MessageExtended& extMess )
02376 {
02377    /* TODO FILL ME
02378     * 24bit Get4 external sync message specific processing
02379     */
02380    return kTRUE;
02381 }
02382 /**********************************************************************/
02383 /*
02384  * This function process the data message when it is a GET4 epoch message
02385  * In suppressed empty epochs 2 mode
02386  */
02387 Bool_t TGet4v1Proc::ProcessGet4SuppEpochMessage( UInt_t uRocId, TGet4v1MessageExtended& extMess )
02388 {
02389    /*
02390     * 24bit Get4 epoch message specific processing
02391     */
02392 
02393    UInt_t uGet4Id(0);
02394 
02395    // Remap the Get4 chip index => Go in Get4 indexing common to all ROCs
02396    uGet4Id = (extMess.GetRocMessage()).getEpoch2ChipNumber();
02397    uGet4Id = fParam->RemapGet4Chip( fParam->DefineGet4IndexOffset(uRocId) +  uGet4Id);
02398    extMess.SetEpoch2ChipNumber(uGet4Id);
02399 
02400    // Check if active chip
02401    if( kFALSE == fParam->IsValidGet4Chip(uGet4Id) )
02402    {
02403        cout << "Error: Bad chip nb in Epoch message = " << uGet4Id << endl;
02404        cout << " => This message will be skipped!!!! "<<endl;
02405        return kFALSE;
02406    }
02407    if( kFALSE == fParam->IsActiveGet4Chip(uGet4Id) )
02408    {
02409       // Masked chip, hopefully on purpose, don't complain & return
02410       return kFALSE;
02411    }
02412 
02413    UInt_t get4_24b_ep_epoch = (extMess.GetRocMessage()).getEpoch2Number();
02414    // No "non-consecutive epoch check" as in this mode they are by definition non consecutive
02415 
02416    // Event statistics
02417    ROC[uRocId].fuNbHitsChipEpoch[uGet4Id] = 0;
02418 
02419    if( ROC[uRocId].fuCurrEpoch2[uGet4Id] > get4_24b_ep_epoch )
02420    {
02421       TGo4Log::Info("Roc Epoch2 cycle (24b mode) change: %u", ROC[uRocId].fuEpoch2Cycle);
02422       ROC[uRocId].fuEpoch2Cycle[uGet4Id]++;
02423    }
02424    ROC[uRocId].fuCurrEpoch2[uGet4Id] = get4_24b_ep_epoch;
02425 
02426    // Reprocess all data messages which where waiting for their epoch
02427    if( 1 == ROC[uRocId].fuEpochWithData[uGet4Id] )
02428    {
02429       ProcessGet4ReprocessSuppData( uRocId, uGet4Id );
02430       ROC[uRocId].fuEpochWithData[uGet4Id] = 0;
02431    }
02432 
02433    // Self triggering
02434    if( kTRUE == fCurrentGet4Event.HasTrigger() && kFALSE == ROC[uRocId].fbSelectionDone[uGet4Id]  )
02435    {
02436       // A trigger is ongoing on this chip!
02437       if( kFALSE == ROC[uRocId].fbEpoch2SinceTrigger[uGet4Id] )
02438       {
02439          // This is the first epoch after the trigger
02440          // => time to look for the data in the epoch which was
02441          // ongoing when the trigger was found
02442 
02443          // If we did not process the epoch before the one where the
02444          // trigger came, we need to initialize the 24 bit temp hits
02445          if( kFALSE == ROC[uRocId].bLookInPreviousEpoch[uGet4Id] )
02446             for( UInt_t uChan = 0; uChan < NB_CHAN_GET4; uChan++)
02447                   (ROC[uRocId].fHitTemp24[uGet4Id][uChan]).Clear();
02448 
02449          BuildHits(uRocId, uGet4Id, ROC[uRocId].fbBufferWithLastFullEpoch2[uGet4Id]);
02450          if( kFALSE == ROC[uRocId].bLookInNextEpoch[uGet4Id] )
02451          {
02452             ROC[uRocId].fbSelectionDone[uGet4Id] = kTRUE;
02453             CheckEventClosure();
02454          }
02455          ROC[uRocId].fbEpoch2SinceTrigger[uGet4Id] = kTRUE;
02456       } // if( kFALSE == ROC[uRocId].fbEpoch2SinceTrigger[uGet4Id] )
02457       else if( kTRUE == ROC[uRocId].fbEpoch2SinceTrigger[uGet4Id] &&
02458                 kTRUE == ROC[uRocId].bLookInNextEpoch[uGet4Id])
02459       {
02460          // This is the second epoch after the trigger and we detected on trigger
02461          // that the trigger window extend in epoch after the one where trigger
02462          // was found => time to look for the data in the epoch which just finished
02463          // and was the one just after the trigger epoch
02464          BuildHits(uRocId, uGet4Id, ROC[uRocId].fbBufferWithLastFullEpoch2[uGet4Id]);
02465          ROC[uRocId].fbSelectionDone[uGet4Id] = kTRUE;
02466          CheckEventClosure();
02467       } // else if( kTRUE == ROC[uRocId].fbEpoch2SinceTrigger[uGet4Id] && kFALSE == ROC[uRocId].bLookInNextEpoch[uGet4Id])
02468    } // if( kTRUE == fCurrentGet4Event.HasTrigger() && kFALSE == ROC[uRocId].fbSelectionDone[uGet4Id]  )
02469 
02470    // Recalculate the full Time to take into account also the epoch2 cycles
02471    ULong64_t uFullTimeBins = ((ULong64_t)  ROC[uRocId].GetFullEpoch2Number( uGet4Id )) << 19;
02472    ULong64_t uFullTime = uFullTimeBins/ 20 + 512;
02473    Double_t  dFullTime = uFullTimeBins / 20. + 512.;
02474    extMess.SetFullTime(  uFullTime );
02475    extMess.SetFullTimeD( dFullTime );
02476 
02477    // Set The ROC epoch2 counter and cycle counter
02478    extMess.SetRocEpoch( ROC[uRocId].fuCurrEpoch2[uGet4Id] );
02479    extMess.SetRocCycle( ROC[uRocId].fuEpoch2Cycle[uGet4Id] );
02480 
02481    // Count per global time unit in s
02482    ULong64_t ulEpochTm = uFullTime / 100000000L;
02483    ROC[uRocId].fEPOCH2t[uGet4Id]->Fill((ulEpochTm % 36000) * 0.1);
02484 
02485    // Long duration time distribution (1 min. bin, 10 days length)
02486    if( kTRUE == fParam->bLongTimeHistos )
02487       ROC[uRocId].fAllEpoch2LongT->Fill( (ulEpochTm * 0.1 ) / 3600 );
02488 
02489    ROC[uRocId].fDistribEpochs2->Fill(uGet4Id, ROC[uRocId].fuCurrEpoch2[uGet4Id]);
02490 
02491    // Swap the flag indicating which buffer contains currently happening epoch
02492    ROC[uRocId].fbBufferWithLastFullEpoch2[uGet4Id] = ( kTRUE == ROC[uRocId].fbBufferWithLastFullEpoch2[uGet4Id] ? kFALSE: kTRUE );
02493    // Clear this buffer (Data more than 1 full epoch old => either already selected or junk)
02494    ROC[uRocId].fPrevEpochs2Buffer[uGet4Id][ ROC[uRocId].fbBufferWithLastFullEpoch2[uGet4Id] ].clear();
02495 
02496    return kTRUE;
02497 }
02498 /**********************************************************************/
02499 /*
02500  * This function process the data message when it is a GET4 data message
02501  */
02502 Bool_t TGet4v1Proc::ProcessGet4SuppDataMessage( UInt_t uRocId, TGet4v1MessageExtended& extMess )
02503 {
02504    /*
02505     * 24bit Get4 hit message specific processing
02506     * In case of suppressed epochs, we will have no epoch2 message for all empty epochs
02507     * However, when a chip has data, its next epoch message should be present!!!
02508     * => need a flag to use the proper epoch message when its the case
02509     *
02510     * TODO
02511     * Make the get4_index consistent everywhere between global get4 index and inside roc get4 index
02512     */
02513 
02514    if (ROC[uRocId].bIgnoreData) return kFALSE;
02515 
02516    if( kFALSE == ROC[uRocId].fb24bitsReadoutDetected )
02517    {
02518       ROC[uRocId].fb24bitsReadoutDetected = kTRUE;
02519       fb24bitsReadoutDetected = kTRUE;
02520       // As it is first 24bit message, let's create
02521       // 24bit specific histograms
02522       char folder[30];
02523       sprintf(folder,"ROC%u/",uRocId);
02524 
02525       /*
02526        * 24 bits specific histograms
02527        */
02528       ROC[uRocId].fChannelInputMessCount = MakeTH1( 'I', Form("%sRoc%u_ChanCounts", folder, uRocId),
02529             "Channel multiplicity per event",
02530             2*NB_CHAN_GET4*MAX_GET4_PER_ROC, 0, MAX_GET4_PER_ROC ,
02531             "Channel []", "# Mess []" );
02532       ROC[uRocId].fb24bitsReadoutDetected = kTRUE;
02533    } // if( kFALSE == ROC[uRocId].fb24bitsReadoutDetected )
02534 
02535    UInt_t    uGet4Id(0), uGet4Ch(0), uGet4Edge(0);
02536    uGet4Id   = (extMess.GetRocMessage()).getGet4Number();
02537    uGet4Ch   = (extMess.GetRocMessage()).getGet4ChNum();
02538    uGet4Edge = (extMess.GetRocMessage()).getGet4Edge();
02539 
02540    // Remap the Get4 chip index
02541    uGet4Id = (extMess.GetRocMessage()).getGet4Number();
02542    uGet4Id = fParam->RemapGet4Chip( fParam->DefineGet4IndexOffset(uRocId) + uGet4Id);
02543    extMess.SetGet4Number(uGet4Id);
02544 
02545    // Check if valid chip
02546    if( kFALSE == fParam->IsValidGet4Chip(uGet4Id) )
02547    {
02548        cout << "Error: Bad chip nb in Data message = " << uGet4Id << endl;
02549        cout << " => This message will be skipped!!!! "<<endl;
02550        return kFALSE;
02551    }
02552    if( kFALSE == fParam->IsActiveGet4Chip(uGet4Id) )
02553    {
02554       // Masked chip, hopefully on purpose, don't complain & return
02555       return kFALSE;
02556    }
02557 
02558    // => need a flag to use the proper epoch message when its the case
02559    ROC[uRocId].fuEpochWithData[uGet4Id] = 1;
02560 
02561    // Store data message in temporary buffer to wait for the next epoch message
02562    ROC[uRocId].fEpSuppBuffer[uGet4Id].push_back( extMess );
02563 
02564    return kTRUE;
02565 }
02566 
02567 /**********************************************************************/
02568 /*
02569  * This function reprocess the data message from a GET4 in empty epoch suppression
02570  * mode once its next epoch message is found
02571  */
02572 Bool_t TGet4v1Proc::ProcessGet4ReprocessSuppData( UInt_t uRocId, UInt_t uGet4Id )
02573 {
02574    /*
02575     * 24bit Get4 hit message specific processing
02576     * In case of suppressed epochs, we will have no epoch2 message for all empty epochs
02577     * However, when a chip has data, its next epoch message should be present just after all data!!!
02578     * => there should not be more than 1 epoch waiting time before reprocessing
02579     *
02580     * TODO
02581     * Make the get4_index consistent everywhere between global get4 index and inside roc get4 index
02582     */
02583    // Loop over the temporary buffer
02584    for( Int_t iDataIndex = 0; iDataIndex < ROC[uRocId].fEpSuppBuffer[uGet4Id].size(); iDataIndex++ )
02585    {
02586       TGet4v1MessageExtended extMess = ROC[uRocId].fEpSuppBuffer[uGet4Id][iDataIndex];
02587       UInt_t   uGet4Ch(0), uGet4Edge(0);
02588       uGet4Ch   = (extMess.GetRocMessage()).getGet4ChNum();
02589       uGet4Edge = (extMess.GetRocMessage()).getGet4Edge();
02590 
02591       // Recalculate the full Time to take into account also the epoch2 cycles
02592       ULong64_t uFullTimeBins = ((ULong64_t)  ( ROC[uRocId].GetFullEpoch2Number( uGet4Id ) - 1 ) << 19) |
02593                                  (ULong64_t)extMess.GetGet4Ts();
02594       ULong64_t uFullTime = uFullTimeBins/ 20 + 512;
02595       Double_t  dFullTime = ((Double_t)uFullTimeBins)*0.05 + 512.;
02596       extMess.SetFullTime(  uFullTime );
02597       extMess.SetFullTimeD( dFullTime );
02598 
02599       // Set The ROC epoch2 counter and cycle counter
02600       extMess.SetRocEpoch( ROC[uRocId].fuCurrEpoch2[uGet4Id] );
02601       extMess.SetRocCycle( ROC[uRocId].fuEpoch2Cycle[uGet4Id] );
02602 
02603 
02604       // Count per global time unit in s
02605       ULong64_t ulDataTm = uFullTime / 100000000L;
02606       ROC[uRocId].fDATAt->Fill((ulDataTm % 36000) * 0.1);
02607 
02608       // Long duration time distribution (1 min. bin, 10 days length)
02609       if( kTRUE == fParam->bLongTimeHistos )
02610          ROC[uRocId].fDataLongT->Fill( (ulDataTm * 0.1 ) / 3600 );
02611 
02612       // Event statistics
02613       ROC[uRocId].fChannelInputMessCount->Fill( uGet4Id + (Double_t)uGet4Ch/(Double_t)NB_CHAN_GET4
02614                                                         + (Double_t)uGet4Edge/(Double_t)(2*NB_CHAN_GET4)  );
02615       if( kTRUE == fParam->bChipRateHistoEnable )
02616          ROC[uRocId].fChipRateEvolution[uGet4Id]->Fill(
02617                (uFullTimeBins ) * 0.1, 1.0/ROC[uRocId].fdRateEvolutionBinSize );
02618       if( kTRUE == fParam->bChannelRateHistoEnable )
02619          ROC[uRocId].fChannelRateEvolution[uGet4Id][uGet4Ch]->Fill(
02620                (uFullTimeBins ) * 0.1, 1.0/ROC[uRocId].fdRateEvolutionBinSize );
02621       ROC[uRocId].fuNbHitsChipEpoch[uGet4Id] ++;
02622 
02623       // Early event closure check
02624       if( kTRUE == fCurrentGet4Event.HasTrigger() &&
02625           kFALSE == ROC[uRocId].fbSelectionDone[uGet4Id]  )
02626       {
02627          Double_t dTimeToTrigger = 0.0;
02628          dTimeToTrigger = extMess.GetFullTimeD() - fCurrentGet4Event.fdTriggerFullTime[uRocId];
02629          if( kFALSE == ROC[uRocId].fTriggerWind->Test( dTimeToTrigger) )
02630          {
02631             // Message after the end of trigger window!!
02632             Bool_t bAllChanInChipOver = kTRUE;
02633 
02634             // If there was already a message from the same channel & edge out of the trigger
02635             //  window, then the token ring made at least one full turn => ok for all
02636             // Otherwise: need to check other channels/edge status
02637             if( (kFALSE == ROC[uRocId].fbDataTimeOut[uGet4Id][uGet4Ch] && 0 == uGet4Edge ) ||
02638                 (kFALSE == ROC[uRocId].fbDataFallingOut[uGet4Id][uGet4Ch] && 1 == uGet4Edge ) )
02639             {
02640                // 24b = always a edge not a hit => need to check both !
02641                if( 0 == uGet4Edge )
02642                   ROC[uRocId].fbDataTimeOut[uGet4Id][uGet4Ch] = kTRUE;
02643                   else ROC[uRocId].fbDataFallingOut[uGet4Id][uGet4Ch] = kTRUE;
02644                // Check if chip fully finished
02645                for(UInt_t uChanTest = 0; uChanTest < NB_CHAN_GET4; uChanTest ++)
02646                {
02647                   if( kFALSE ==  ROC[uRocId].fbDataTimeOut[uGet4Id][uChanTest] )
02648                      bAllChanInChipOver = kFALSE;
02649                   if( kFALSE ==  ROC[uRocId].fbDataFallingOut[uGet4Id][uChanTest] )
02650                      bAllChanInChipOver = kFALSE;
02651                }
02652             } // if same edge not already out of trigger once
02653 
02654             // If chip fully finished: don't wait for the next epoch to close future buffer
02655             // of current event for this chip
02656             if( kTRUE == bAllChanInChipOver)
02657             {
02658                // If This is the first epoch after the trigger and
02659                // we did not process the epoch before the one where the
02660                // trigger came, we need to initialize the 24 bit temp hits
02661                if( kFALSE == ROC[uRocId].fbEpoch2SinceTrigger[uGet4Id] &&
02662                    kFALSE == ROC[uRocId].bLookInPreviousEpoch[uGet4Id] )
02663                   for( UInt_t uChan = 0; uChan < NB_CHAN_GET4; uChan++)
02664                         (ROC[uRocId].fHitTemp24[uGet4Id][uChan]).Clear();
02665 
02666                BuildHits(uRocId, uGet4Id, ROC[uRocId].fbBufferWithLastFullEpoch2[uGet4Id]);
02667                ROC[uRocId].fbSelectionDone[uGet4Id] = kTRUE;
02668                CheckEventClosure();
02669 
02670                for(UInt_t uChanTest = 0; uChanTest < NB_CHAN_GET4; uChanTest ++)
02671                {
02672                   ROC[uRocId].fbDataTimeOut[uGet4Id][uChanTest] = kFALSE;
02673                   ROC[uRocId].fbDataFallingOut[uGet4Id][uChanTest] = kFALSE;
02674                }
02675             } // if( kTRUE == bAllChanInChipOver)
02676          } // if( kFALSE == ROC[uRocId].fTriggerWind->Test( dTimeToTrigger) )
02677       } // Event ongoing with a detected trigger and chip did not finished all its buffers
02678 
02680       if( kTRUE ==  fParam->bFreeStreaming && 0 < fParam->uNbTriggers )
02681       {
02683          if( 0 == uGet4Edge )
02684          {
02685             for( Int_t iMainTriggerIndex = 0; iMainTriggerIndex < (Int_t)(fParam->uNbTriggers); iMainTriggerIndex++ )
02686                if( kTRUE == fParam->IsMainOfThisTrigger( iMainTriggerIndex, uGet4Id, uGet4Ch ) )
02687             {
02688                ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex] = extMess;
02689                /*
02690                 * TODO: call to ProcessTrigger
02691                 * TEMP: histo Filling + counting
02692                 */
02693                Bool_t bAllInCoinc = kTRUE;
02694                for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iMainTriggerIndex]; uSecChannel++)
02695                {
02696                   Double_t dDistanceToMain = ROC[uRocId].fdLastFullTimeSecChannel[iMainTriggerIndex][uSecChannel]
02697                                            - extMess.GetFullTimeD();
02698                   if( dDistanceToMain < fParam->dCoincidenceWindowStart[iMainTriggerIndex] ||
02699                         fParam->dCoincidenceWindowStop[iMainTriggerIndex] < dDistanceToMain      )
02700                   {
02701                      bAllInCoinc = kFALSE;
02702                      break;
02703                   } // if out of coincidence window
02704                   Double_t dTotDistanceToMain = ROC[uRocId].fdLastFullTimeSecChannelTot[iMainTriggerIndex][uSecChannel]
02705                                            - extMess.GetFullTimeD();
02706                   if( dTotDistanceToMain < fParam->dCoincidenceWindowStart[iMainTriggerIndex] ||
02707                         fParam->dCoincidenceWindowStop[iMainTriggerIndex] < dTotDistanceToMain      )
02708                   {
02709                      bAllInCoinc = kFALSE;
02710                      break;
02711                   } // if out of coincidence window
02712                } // for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iMainTriggerIndex]; uSecChannel++)
02713 
02714                // Check if tot edge of the main channel is in trigger window
02715                Double_t dTotMainDistanceToMain = ROC[uRocId].fdLastFullTimeMainChannelTot[iMainTriggerIndex]
02716                                  - ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTimeD();
02717                if( dTotMainDistanceToMain < fParam->dCoincidenceWindowStart[iMainTriggerIndex] ||
02718                      fParam->dCoincidenceWindowStop[iMainTriggerIndex] < dTotMainDistanceToMain      )
02719                {
02720                   bAllInCoinc = kFALSE;
02721                } // if out of coincidence window
02722 
02723                if( kTRUE == bAllInCoinc )
02724                {
02725                   Double_t dSameTriggerDistance =
02726                           ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTimeD()
02727                         - ROC[uRocId].fdLastFullTimeSelfTrigger[iMainTriggerIndex] ;
02728 
02729                   ROC[uRocId].fDataSelfTrigDistanceNs->Fill( dSameTriggerDistance,     iMainTriggerIndex );
02730                   ROC[uRocId].fDataSelfTrigDistanceUs->Fill( dSameTriggerDistance/1e3, iMainTriggerIndex );
02731                   ROC[uRocId].fDataSelfTrigDistanceMs->Fill( dSameTriggerDistance/1e6, iMainTriggerIndex );
02732                   ROC[uRocId].fDataSelfTrigDistanceS->Fill(  dSameTriggerDistance/1e9, iMainTriggerIndex );
02733 
02734                   if( fParam->dDeadTime <= dSameTriggerDistance )
02735                   {
02736                      // Here we have a DATA self-trigger!!!!!!
02737                      ROC[uRocId].fuDataSelfTriggerCount[iMainTriggerIndex] ++;
02738 
02739                      ROC[uRocId].fdLastFullTimeSelfTrigger[iMainTriggerIndex] =
02740                            ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTimeD();
02741 
02742                      ULong64_t uFullTimeSelfTrigBins = ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTime();
02743                      uFullTimeSelfTrigBins /= 100000000L;
02744                      ROC[uRocId].fSelfTriggT->Fill( (uFullTimeSelfTrigBins % 36000) * 0.1 );
02745 
02746                      // Long duration time distribution (1 min. bin, 10 days length)
02747                      if( kTRUE == fParam->bLongTimeHistos )
02748                         ROC[uRocId].fSelfTriggLongT->Fill( (uFullTimeSelfTrigBins * 0.1 ) / 3600 );
02749 
02750                      ProcessTriggerMessage(uRocId, ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex], iMainTriggerIndex);
02751                   } // if( fParam->dDeadTime <= dSameTriggerDistance )
02752                } // if( kTRUE == bAllInCoinc )
02753             } // if( -1 < iMainTriggerIndex )
02754 
02755             for( Int_t iSecTriggerIndex = 0; iSecTriggerIndex < (Int_t)(fParam->uNbTriggers); iSecTriggerIndex++ )
02756             {
02757                if( kTRUE == fParam->IsSecOfThisTrigger( iSecTriggerIndex, uGet4Id, uGet4Ch ) )
02758                {
02759                   Int_t iSecondaryIndex = fParam->GetSecChannelIndex(iSecTriggerIndex, uGet4Id, uGet4Ch);
02760                   if( -1 < iSecondaryIndex )
02761                   {
02762                      ROC[uRocId].fdLastFullTimeSecChannel[iSecTriggerIndex][iSecondaryIndex] = extMess.GetFullTimeD();
02763 
02764                      /*
02765                       * TODO: call to ProcessTrigger
02766                       * TEMP: histo Filling + counting
02767                       */
02768                      Bool_t bAllInCoinc = kTRUE;
02769                      for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iSecTriggerIndex]; uSecChannel++)
02770                      {
02771                         Double_t dDistanceToMain = ROC[uRocId].fdLastFullTimeSecChannel[iSecTriggerIndex][uSecChannel]
02772                                           - ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD();
02773                         if( dDistanceToMain < fParam->dCoincidenceWindowStart[iSecTriggerIndex] ||
02774                               fParam->dCoincidenceWindowStop[iSecTriggerIndex] < dDistanceToMain      )
02775                         {
02776                            bAllInCoinc = kFALSE;
02777                            break;
02778                         } // if out of coincidence window
02779 
02780                         // Check if tot edge is in trigger window, only needed in 24b mode
02781                         Double_t dTotDistanceToMain = ROC[uRocId].fdLastFullTimeSecChannelTot[iSecTriggerIndex][uSecChannel]
02782                                           - ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD();
02783                         if( dTotDistanceToMain < fParam->dCoincidenceWindowStart[iSecTriggerIndex] ||
02784                               fParam->dCoincidenceWindowStop[iSecTriggerIndex] < dTotDistanceToMain      )
02785                         {
02786                            bAllInCoinc = kFALSE;
02787                            break;
02788                         } // if out of coincidence window
02789                      } // for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iSecTriggerIndex]; uSecChannel++)
02790 
02791                      // Check if tot edge of the main channel is in trigger window, only needed in 24b mode
02792                      Double_t dTotMainDistanceToMain = ROC[uRocId].fdLastFullTimeMainChannelTot[iSecTriggerIndex]
02793                                        - ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD();
02794                      if( dTotMainDistanceToMain < fParam->dCoincidenceWindowStart[iSecTriggerIndex] ||
02795                            fParam->dCoincidenceWindowStop[iSecTriggerIndex] < dTotMainDistanceToMain      )
02796                      {
02797                         bAllInCoinc = kFALSE;
02798                      } // if out of coincidence window
02799 
02800                      if( kTRUE == bAllInCoinc  )
02801                      {
02802                         Double_t dSameTriggerDistance =
02803                                 ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD()
02804                               - ROC[uRocId].fdLastFullTimeSelfTrigger[iSecTriggerIndex] ;
02805 
02806                         ROC[uRocId].fDataSelfTrigDistanceNs->Fill( dSameTriggerDistance,     iSecTriggerIndex );
02807                         ROC[uRocId].fDataSelfTrigDistanceUs->Fill( dSameTriggerDistance/1e3, iSecTriggerIndex );
02808                         ROC[uRocId].fDataSelfTrigDistanceMs->Fill( dSameTriggerDistance/1e6, iSecTriggerIndex );
02809                         ROC[uRocId].fDataSelfTrigDistanceS->Fill(  dSameTriggerDistance/1e9, iSecTriggerIndex );
02810 
02811                         if( fParam->dDeadTime <= dSameTriggerDistance )
02812                         {
02813                            // Here we have a DATA self-trigger!!!!!!
02814                            ROC[uRocId].fuDataSelfTriggerCount[iSecTriggerIndex] ++;
02815 
02816                            ROC[uRocId].fdLastFullTimeSelfTrigger[iSecTriggerIndex] =
02817                                  ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD();
02818 
02819                            ULong64_t uFullTimeSelfTrigBins = ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTime();
02820                            uFullTimeSelfTrigBins /= 100000000L;
02821                            ROC[uRocId].fSelfTriggT->Fill( (uFullTimeSelfTrigBins % 36000) * 0.1 );
02822 
02823                            // Long duration time distribution (1 min. bin, 10 days length)
02824                            if( kTRUE == fParam->bLongTimeHistos )
02825                               ROC[uRocId].fSelfTriggLongT->Fill( (uFullTimeSelfTrigBins * 0.1 ) / 3600 );
02826 
02827                            ProcessTriggerMessage(uRocId, ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex], iSecTriggerIndex);
02828                         } // if( fParam->dDeadTime <= dSameTriggerDistance )
02829                      } // if( kTRUE == bAllInCoinc  )
02830                   } // if( -1 < iSecondaryIndex )
02831                } //  if( -1 < iSecTriggerIndex )
02832             } // for( Int_t iSecTriggerIndex = 0; iSecTriggerIndex < (Int_t)(fParam->uNbTriggers); iSecTriggerIndex++ )
02833          }// if( 0 == uGet4Edge )
02835             else
02836             {
02837                // Falling edge
02838                for( Int_t iMainTriggerIndex = 0; iMainTriggerIndex < (Int_t)(fParam->uNbTriggers); iMainTriggerIndex++ )
02839                   if( kTRUE == fParam->IsMainOfThisTrigger( iMainTriggerIndex, uGet4Id, uGet4Ch ) )
02840                {
02841                   ROC[uRocId].fdLastFullTimeMainChannelTot[iMainTriggerIndex] = extMess.GetFullTimeD();
02842 
02843                   Bool_t bAllInCoinc = kTRUE;
02844                   for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iMainTriggerIndex]; uSecChannel++)
02845                   {
02846                      // Check if time edge is in trigger window
02847                      Double_t dDistanceToMain = ROC[uRocId].fdLastFullTimeSecChannel[iMainTriggerIndex][uSecChannel]
02848                                        - ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTimeD();
02849                      if( dDistanceToMain < fParam->dCoincidenceWindowStart[iMainTriggerIndex] ||
02850                            fParam->dCoincidenceWindowStop[iMainTriggerIndex] < dDistanceToMain      )
02851                      {
02852                         bAllInCoinc = kFALSE;
02853                         break;
02854                      } // if out of coincidence window
02855 
02856                      // Check if tot edge is in trigger window, only needed in 24b mode
02857                      Double_t dTotDistanceToMain = ROC[uRocId].fdLastFullTimeSecChannelTot[iMainTriggerIndex][uSecChannel]
02858                                        - ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTimeD();
02859                      if( dTotDistanceToMain < fParam->dCoincidenceWindowStart[iMainTriggerIndex] ||
02860                            fParam->dCoincidenceWindowStop[iMainTriggerIndex] < dTotDistanceToMain      )
02861                      {
02862                         bAllInCoinc = kFALSE;
02863                         break;
02864                      } // if out of coincidence window
02865                   } // for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iMainTriggerIndex]; uSecChannel++)
02866 
02867                   // Check if tot edge of the main channel is in trigger window, only needed in 24b mode
02868                   Double_t dTotMainDistanceToMain = ROC[uRocId].fdLastFullTimeMainChannelTot[iMainTriggerIndex]
02869                                     - ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTimeD();
02870                   if( dTotMainDistanceToMain < fParam->dCoincidenceWindowStart[iMainTriggerIndex] ||
02871                         fParam->dCoincidenceWindowStop[iMainTriggerIndex] < dTotMainDistanceToMain      )
02872                   {
02873                      bAllInCoinc = kFALSE;
02874                   } // if out of coincidence window
02875 
02876                   if( kTRUE == bAllInCoinc  )
02877                   {
02878                      Double_t dSameTriggerDistance =
02879                              ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTimeD()
02880                            - ROC[uRocId].fdLastFullTimeSelfTrigger[iMainTriggerIndex] ;
02881 
02882                      ROC[uRocId].fDataSelfTrigDistanceNs->Fill( dSameTriggerDistance,     iMainTriggerIndex );
02883                      ROC[uRocId].fDataSelfTrigDistanceUs->Fill( dSameTriggerDistance/1e3, iMainTriggerIndex );
02884                      ROC[uRocId].fDataSelfTrigDistanceMs->Fill( dSameTriggerDistance/1e6, iMainTriggerIndex );
02885                      ROC[uRocId].fDataSelfTrigDistanceS->Fill(  dSameTriggerDistance/1e9, iMainTriggerIndex );
02886 
02887                      if( fParam->dDeadTime <= dSameTriggerDistance )
02888                      {
02889                         // Here we have a DATA self-trigger!!!!!!
02890                         ROC[uRocId].fuDataSelfTriggerCount[iMainTriggerIndex] ++;
02891 
02892                         ROC[uRocId].fdLastFullTimeSelfTrigger[iMainTriggerIndex] =
02893                               ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTimeD();
02894 
02895                         ULong64_t uFullTimeSelfTrigBins = ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTime();
02896                         uFullTimeSelfTrigBins /= 100000000L;
02897                         ROC[uRocId].fSelfTriggT->Fill( (uFullTimeSelfTrigBins % 36000) * 0.1 );
02898 
02899                         // Long duration time distribution (1 min. bin, 10 days length)
02900                         if( kTRUE == fParam->bLongTimeHistos )
02901                            ROC[uRocId].fSelfTriggLongT->Fill( (uFullTimeSelfTrigBins * 0.1 ) / 3600 );
02902 
02903                         ProcessTriggerMessage(uRocId, ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex], iMainTriggerIndex);
02904                      } // if( fParam->dDeadTime <= dSameTriggerDistance )
02905                   } // if( kTRUE == bAllInCoinc  )
02906                } // if( kTRUE == fParam->IsMainOfThisTrigger( iMainTriggerIndex, uGet4Id, uGet4Ch ) )
02907 
02908                for( Int_t iSecTriggerIndex = 0; iSecTriggerIndex < (Int_t)(fParam->uNbTriggers); iSecTriggerIndex++ )
02909                {
02910                   if( kTRUE == fParam->IsSecOfThisTrigger( iSecTriggerIndex, uGet4Id, uGet4Ch ) )
02911                   {
02912                      Int_t iSecondaryIndex = fParam->GetSecChannelIndex(iSecTriggerIndex, uGet4Id, uGet4Ch);
02913                      if( -1 < iSecondaryIndex )
02914                      {
02915                         ROC[uRocId].fdLastFullTimeSecChannelTot[iSecTriggerIndex][iSecondaryIndex] = extMess.GetFullTimeD();
02916 
02917                         Bool_t bAllInCoinc = kTRUE;
02918                         for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iSecTriggerIndex]; uSecChannel++)
02919                         {
02920                            // Check if time edge is in trigger window
02921                            Double_t dDistanceToMain = ROC[uRocId].fdLastFullTimeSecChannel[iSecTriggerIndex][uSecChannel]
02922                                              - ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD();
02923                            if( dDistanceToMain < fParam->dCoincidenceWindowStart[iSecTriggerIndex] ||
02924                                  fParam->dCoincidenceWindowStop[iSecTriggerIndex] < dDistanceToMain      )
02925                            {
02926                               bAllInCoinc = kFALSE;
02927                               break;
02928                            } // if out of coincidence window
02929 
02930                            // Check if tot edge is in trigger window
02931                            Double_t dTotDistanceToMain = ROC[uRocId].fdLastFullTimeSecChannelTot[iSecTriggerIndex][uSecChannel]
02932                                              - ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD();
02933                            if( dTotDistanceToMain < fParam->dCoincidenceWindowStart[iSecTriggerIndex] ||
02934                                  fParam->dCoincidenceWindowStop[iSecTriggerIndex] < dTotDistanceToMain      )
02935                            {
02936                               bAllInCoinc = kFALSE;
02937                               break;
02938                            } // if out of coincidence window
02939                         } // for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iSecTriggerIndex]; uSecChannel++)
02940 
02941                         // Check if tot edge of the main channel is in trigger window
02942                         Double_t dTotMainDistanceToMain = ROC[uRocId].fdLastFullTimeMainChannelTot[iSecTriggerIndex]
02943                                           - ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD();
02944                         if( dTotMainDistanceToMain < fParam->dCoincidenceWindowStart[iSecTriggerIndex] ||
02945                               fParam->dCoincidenceWindowStop[iSecTriggerIndex] < dTotMainDistanceToMain      )
02946                         {
02947                            bAllInCoinc = kFALSE;
02948                         } // if out of coincidence window
02949 
02950                         if( kTRUE == bAllInCoinc  )
02951                         {
02952                            Double_t dSameTriggerDistance =
02953                                    ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD()
02954                                  - ROC[uRocId].fdLastFullTimeSelfTrigger[iSecTriggerIndex] ;
02955 
02956                            ROC[uRocId].fDataSelfTrigDistanceNs->Fill( dSameTriggerDistance,     iSecTriggerIndex );
02957                            ROC[uRocId].fDataSelfTrigDistanceUs->Fill( dSameTriggerDistance/1e3, iSecTriggerIndex );
02958                            ROC[uRocId].fDataSelfTrigDistanceMs->Fill( dSameTriggerDistance/1e6, iSecTriggerIndex );
02959                            ROC[uRocId].fDataSelfTrigDistanceS->Fill(  dSameTriggerDistance/1e9, iSecTriggerIndex );
02960 
02961                            if( fParam->dDeadTime <= dSameTriggerDistance )
02962                            {
02963                               // Here we have a DATA self-trigger!!!!!!
02964                               ROC[uRocId].fuDataSelfTriggerCount[iSecTriggerIndex] ++;
02965 
02966                               ROC[uRocId].fdLastFullTimeSelfTrigger[iSecTriggerIndex] =
02967                                     ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD();
02968 
02969                               ULong64_t uFullTimeSelfTrigBins = ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTime();
02970                               uFullTimeSelfTrigBins /= 100000000L;
02971                               ROC[uRocId].fSelfTriggT->Fill( (uFullTimeSelfTrigBins % 36000) * 0.1 );
02972 
02973                               // Long duration time distribution (1 min. bin, 10 days length)
02974                               if( kTRUE == fParam->bLongTimeHistos )
02975                                  ROC[uRocId].fSelfTriggLongT->Fill( (uFullTimeSelfTrigBins * 0.1 ) / 3600 );
02976 
02977                               ProcessTriggerMessage(uRocId, ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex], iSecTriggerIndex);
02978                            } // if( fParam->dDeadTime <= dSameTriggerDistance )
02979                         } // if( kTRUE == bAllInCoinc  )
02980                      } // if( -1 < iSecondaryIndex )
02981                   } // if( kTRUE == fParam->IsSecOfThisTrigger( iSecTriggerIndex, uGet4Id, uGet4Ch ) )
02982                } // for( Int_t iSecTriggerIndex = 0; iSecTriggerIndex < (Int_t)(fParam->uNbTriggers); iSecTriggerIndex++ )
02983             } // else if( 0 == uGet4Edge )
02984       } // if( kTRUE ==  fParam->bFreeStreaming && 0 < fParam->uNbTriggers && 0 == uGet4Edge )
02985 
02986       ProcessExtendedMessage(uRocId, extMess);
02987    } // for( Int_t iDataIndex = 0; iDataIndex < ROC[uRocId].fEpSuppBuffer[uGet4Id].size(); iDataIndex++ )
02988    ROC[uRocId].fEpSuppBuffer[uGet4Id].clear();
02989 
02990    return kTRUE;
02991 }
02992 /**********************************************************************/
02993 Int_t TGet4v1Proc::Process32BitGet4Message( UInt_t uRocId, TGet4v1MessageExtended& extMess )
02994 {
02995    /*
02996     * 32bit Get4 hit message specific processing
02997     * TODO FILL ME
02998     * Make the get4_index consistent everywhere between global get4 index and inside roc get4 index
02999     */
03000 
03001    UInt_t get4_index = extMess.getGet4V10R32ChipId() ;
03002    get4_index = fParam->RemapGet4Chip(get4_index);
03003 
03004    // Check if valid chip
03005    if( kFALSE == fParam->IsValidGet4Chip(get4_index) )
03006    {
03007        cout << "Error: Bad chip nb in 32b Data message = " << get4_index <<" < "<<fParam->uNbGet4<< endl;
03008        cout << " => This message will be skipped!!!! "<<endl;
03009        return -1;
03010    }
03011    if( kFALSE == fParam->IsActiveGet4Chip(get4_index) )
03012    {
03013       // Masked chip, hopefully on purpose, don't complain & return
03014       return -1;
03015    }
03016 
03017    // If 1 message is 32bits, all are!
03018    if( kFALSE == ROC[uRocId].fb32bitsReadoutDetected )
03019    {
03020       ROC[uRocId].fb32bitsReadoutDetected = kTRUE;
03021       fb32bitsReadoutDetected = kTRUE;
03022       // As it is first 32bit message, let's create
03023       // 32bit specific histograms
03024       char folder[30];
03025       sprintf(folder,"ROC%u/",uRocId);
03026 
03027       /*
03028        * 32 bits specific histograms
03029        */
03030       ROC[uRocId].fChannelInputMessCount = MakeTH1( 'I', Form("%sRoc%u_ChanCounts", folder, uRocId),
03031             "Channel multiplicity per event",
03032             NB_CHAN_GET4*MAX_GET4_PER_ROC, 0, MAX_GET4_PER_ROC ,
03033             "Channel []", "# Mess []" );
03034 
03035          // Slow control messages
03036       ROC[uRocId].fGet4V1SlowControlType = MakeTH2('I', Form("%sRoc%u_Get4SlowControl", folder, uRocId),
03037             "SlowControl message type per Get4",
03038             fParam->uNbGet4, -0.5, fParam->uNbGet4 -0.5, 5, 0., 5,
03039             "Chip","","Entries [1]");
03040       ROC[uRocId].fGet4V1SlowControlType->GetYaxis()->SetBinLabel(1, "Scaler");
03041       ROC[uRocId].fGet4V1SlowControlType->GetYaxis()->SetBinLabel(2, "Dead time");
03042       ROC[uRocId].fGet4V1SlowControlType->GetYaxis()->SetBinLabel(3, "SPI");
03043       ROC[uRocId].fGet4V1SlowControlType->GetYaxis()->SetBinLabel(4, "Start");
03044       ROC[uRocId].fGet4V1SlowControlType->GetYaxis()->SetBinLabel(5, "Hamming");
03045       ROC[uRocId].fGet4V1SlowControlScaler = MakeTH2('I', Form("%sRoc%u_Get4SlScaler", folder, uRocId),
03046                               "Scaler in Get4 slow control message",
03047                               2*(fParam->uNbGet4)*NB_CHAN_GET4, 0., (fParam->uNbGet4)*NB_CHAN_GET4, 820, 0, 8200,
03048                               "Channel","Scaler [hits]","Entries [1]");
03049       ROC[uRocId].fGet4V1SlowControlDeadTime = MakeTH2('I', Form("%sRoc%u_Get4SlDeadTime", folder, uRocId),
03050                               "Dead time in Get4 slow control message",
03051                               2*(fParam->uNbGet4)*NB_CHAN_GET4, 0., (fParam->uNbGet4)*NB_CHAN_GET4, 410, 0, 4100,
03052                               "Channel","Dead Time [Clk cycle]","Entries [1]");
03053       ROC[uRocId].fGet4V1SlowControlHamming = MakeTH2('I', Form("%sRoc%u_Get4SlSeu", folder, uRocId),
03054             "Hamming error counter for SEU in Get4 slow control message",
03055             fParam->uNbGet4, 0., fParam->uNbGet4, 512, 0, 512,
03056             "Chip","Scaler [hits]","Entries [1]");
03057       ROC[uRocId].fGet4V1SlowControlSeuEvo = MakeTH2('I', Form("%sRoc%u_Get4SlSeuEvo", folder, uRocId),
03058             "Hamming error counter for SEU in Get4 slow control message",
03059             3600, 0, 3600, fParam->uNbGet4, 0., fParam->uNbGet4,
03060             "Time [s]", "Chip","Scaler [hits]");
03061          // Data messages
03062       ROC[uRocId].fGet4V1DllLockBit =
03063             MakeTH2('I', Form("%sRoc%u_Get4V1DllLockBit", folder, uRocId),
03064             "Dll lock bit status per channel",
03065             fParam->uNbGet4*NB_CHAN_GET4, -0.5 , fParam->uNbGet4*NB_CHAN_GET4 -0.5,
03066             2, -0.5, 1.5,
03067             "Channel []", "Dll lock bit []", "Counts [1]" );
03068 
03069       for( Int_t iGet4 = 0; iGet4 < MAX_GET4_PER_ROC; iGet4++)
03070       {
03071          char folderGet4[30];
03072          sprintf(folderGet4,"%sGet4_%u/",folder, iGet4);
03073          UInt_t uRemappedGet4Index = fParam->RemapGet4Chip(uRocId, iGet4);
03074          if( kTRUE == fParam->IsValidGet4Chip(uRemappedGet4Index) &&
03075              kTRUE == fParam->IsActiveGet4Chip(uRemappedGet4Index) )
03076          {
03077             ROC[uRocId].fGet4V1HitsDistanceNs[iGet4] =
03078                   MakeTH2('I', Form("%sRoc%u_Get%d_HitDistNs",
03079                                  folderGet4, uRocId, iGet4),
03080                            Form("Time difference since last hit on same channel in GET4 %d Channels on ROC%u; [ns]",
03081                                  iGet4, uRocId),
03082                            1002, -2., 1000.,
03083                            NB_CHAN_GET4, 0, NB_CHAN_GET4 );
03084             ROC[uRocId].fGet4V1HitsDistanceUs[iGet4] =
03085                   MakeTH2('I', Form("%sRoc%u_Get%d_HitDistUs",
03086                                  folderGet4, uRocId, iGet4),
03087                            Form("Time difference since last hit on same channel in GET4 %d Channels on ROC%u; [us]",
03088                                  iGet4, uRocId),
03089                            999, 1., 1000.,
03090                            NB_CHAN_GET4, 0, NB_CHAN_GET4 );
03091             ROC[uRocId].fGet4V1HitsDistanceMs[iGet4] =
03092                   MakeTH2('I', Form("%sRoc%u_Get%d_HitDistMs",
03093                                  folderGet4, uRocId, iGet4),
03094                            Form("Time difference since last hit on same channel in GET4 %d Channels on ROC%u; [ms]",
03095                                  iGet4, uRocId),
03096                            999, 1., 1000.,
03097                            NB_CHAN_GET4, 0, NB_CHAN_GET4 );
03098             ROC[uRocId].fGet4V1HitsDistanceS[iGet4]  =
03099                   MakeTH2('I', Form("%sRoc%u_Get%d_HitDistS",
03100                                  folderGet4, uRocId, iGet4),
03101                            Form("Time difference since last hit on same channel in GET4 %d Channels on ROC%u; [s]",
03102                                  iGet4, uRocId),
03103                            999, 1., 1000.,
03104                            NB_CHAN_GET4, 0, NB_CHAN_GET4 );
03105 
03106             if( 1 == fParam->bTotHistoEnable )
03107                for( Int_t iGet4Chan = 0; iGet4Chan < NB_CHAN_GET4; iGet4Chan++)
03108                   ROC[uRocId].fRawTot[iGet4][iGet4Chan] =
03109                         MakeTH1('I', Form("%sTot/RawTot_Ch%d_Get%d_Roc%u",
03110                               folderGet4, iGet4Chan, iGet4, uRocId ),
03111                         Form("Tot for channel %d in chip %d on ROC %d", iGet4Chan, iGet4, uRocId),
03112                         1200, -25, 59975, "Tot [ps]", "Counts [1]" );
03113          }
03114       } // for( Int_t iGet4 = 0; iGet4 < MAX_GET4_PER_ROC; iGet4++)
03115    } // if( kFALSE == fb32bitsReadoutDetected )
03116    extMess.Set32BitFlag();
03117 
03118    UInt_t get4_32b_type  = extMess.getGet4V10R32MessageType();
03119    switch(get4_32b_type)
03120    {
03121       case 0: // epoch message
03122       {
03123          UInt_t get4_32b_ep_epoch = extMess.getGet4V10R32EpochNumber();
03124          UInt_t get4_32b_ep_sync  = extMess.getGet4V10R32SyncFlag();
03125 
03126          if( kTRUE == fCurrentGet4Event.HasTrigger() && kFALSE == ROC[uRocId].fbSelectionDone[get4_index]  )
03127          {
03128             // A trigger is ongoing on this chip!
03129             if( kFALSE == ROC[uRocId].fbEpoch2SinceTrigger[get4_index] )
03130             {
03131                // This is the first epoch after the trigger
03132                // => time to look for the data in the epoch which was
03133                // ongoing when the trigger was found
03134                
03135                // If we did not process the epoch before the one where the 
03136                // trigger came, we need to initialize the 24 bit temp hits
03137                if( kFALSE == ROC[uRocId].bLookInPreviousEpoch[get4_index] )
03138                   for( UInt_t uChan = 0; uChan < NB_CHAN_GET4; uChan++)
03139                         (ROC[uRocId].fHitTemp24[get4_index][uChan]).Clear();
03140                         
03141                BuildHits(uRocId, get4_index, ROC[uRocId].fbBufferWithLastFullEpoch2[get4_index]);
03142                if( kFALSE == ROC[uRocId].bLookInNextEpoch[get4_index] )
03143                {
03144                   ROC[uRocId].fbSelectionDone[get4_index] = kTRUE;
03145                   CheckEventClosure();
03146                }
03147             } // if( kFALSE == ROC[uRocId].fbEpoch2SinceTrigger[get4_index] )
03148             else if( kTRUE == ROC[uRocId].fbEpoch2SinceTrigger[get4_index] && 
03149                       kTRUE == ROC[uRocId].bLookInNextEpoch[get4_index])
03150             {
03151                // This is the second epoch after the trigger and we detected on trigger
03152                // that the trigger window extend in epoch after the one where trigger
03153                // was found => time to look for the data in the epoch which just finished
03154                // and was the one just after the trigger epoch
03155                BuildHits(uRocId, get4_index, ROC[uRocId].fbBufferWithLastFullEpoch2[get4_index]);
03156                ROC[uRocId].fbSelectionDone[get4_index] = kTRUE;
03157                CheckEventClosure();
03158             } // else if( kTRUE == ROC[uRocId].fbEpoch2SinceTrigger[get4_index] && kFALSE == ROC[uRocId].bLookInNextEpoch[get4_index])
03159          } // if( kTRUE == fCurrentGet4Event.HasTrigger() && kFALSE == ROC[uRocId].fbSelectionDone[get4_index]  )
03160 
03161          if( ROC[uRocId].fuCurrEpoch2[get4_index] + 1 != get4_32b_ep_epoch &&
03162                ( 0 < ROC[uRocId].fuCurrEpoch2[get4_index] || 0 < ROC[uRocId].fuEpoch2Cycle[get4_index] ) &&
03163                !( GET4_EPOCH_CYCLE_SIZE == ROC[uRocId].fuCurrEpoch2[get4_index]  && 0 == get4_32b_ep_epoch ) )
03164          {
03165 
03166             // Count per global time unit in s for previous epoch as should not be too far away
03167             // anyway this is just for selection, not actual display
03168             ULong64_t ulPrevEpochTm = ((ULong64_t)  ROC[uRocId].GetFullEpoch2Number( get4_index )) << 19;
03169             ulPrevEpochTm = ulPrevEpochTm/ 20 + 512;
03170             ulPrevEpochTm = ulPrevEpochTm / 100000000L;
03171          
03172             if( 311 < (ulPrevEpochTm % 36000) * 0.1 &&
03173               (ulPrevEpochTm % 36000) * 0.1 < 312 )
03174             {
03175                cout<<(ulPrevEpochTm % 36000) * 0.1<<" Non consecutive epoch message for chip "<<get4_index<<" Roc Epoch "<<ROC[uRocId].fuCurrEpoch<<" : ";
03176                cout<<ROC[uRocId].fuCurrEpoch2[get4_index]<<" "<<get4_32b_ep_epoch<<" ";
03177                cout<<(Int_t)get4_32b_ep_epoch - (Int_t)(ROC[uRocId].fuCurrEpoch2[get4_index]+1) <<" ";
03178                cout<<ROC[uRocId].fiEpochShift[get4_index]<<" ";
03179                cout<<ROC[uRocId].fuNbShiftedEpochs[get4_index]<<endl;
03180             }
03181                        
03182             ROC[uRocId].fEpochShiftsPerChip->Fill( get4_index, (Int_t)get4_32b_ep_epoch - (Int_t)(ROC[uRocId].fuCurrEpoch2[get4_index]+1) );
03183 
03184             if( ROC[uRocId].fuCurrEpoch2[get4_index] > get4_32b_ep_epoch &&
03185                 GET4_EPOCH_CYCLE_SIZE < ROC[uRocId].fuCurrEpoch2[get4_index] + 100 &&
03186                 100 < get4_32b_ep_epoch )
03187                // Epoch close to a cycle change on both sides
03188                ROC[uRocId].fuEpoch2Cycle[get4_index]++;
03189 
03190             // Correction attempt:
03191             if( (Int_t)get4_32b_ep_epoch - (Int_t)(ROC[uRocId].fuCurrEpoch2[get4_index]+1) < 10 )
03192             {
03193                // close epochs ( < 250us) => probable not a full event missing
03194                if( 0 != ROC[uRocId].fiEpochShift[get4_index])
03195                {
03196                   ROC[uRocId].fEpochShiftsDuration[get4_index]->Fill(ROC[uRocId].fiEpochShift[get4_index],
03197                         ROC[uRocId].fuNbShiftedEpochs[get4_index] );
03198                   ROC[uRocId].fEpochShiftsDurationPerChip->Fill( get4_index,
03199                         ROC[uRocId].fuNbShiftedEpochs[get4_index] );
03200                }
03201                ROC[uRocId].fiEpochShift[get4_index] += (Int_t)get4_32b_ep_epoch - (Int_t)(ROC[uRocId].fuCurrEpoch2[get4_index]+1) ;
03202                ROC[uRocId].fuNbShiftedEpochs[get4_index] = 0;
03203             }
03204                else
03205                {
03206                   // far epochs ( > 250us) => probable a full event is missing
03207                   if( 0 != ROC[uRocId].fiEpochShift[get4_index])
03208                   {
03209                      ROC[uRocId].fEpochShiftsDuration[get4_index]->Fill(ROC[uRocId].fiEpochShift[get4_index],
03210                            ROC[uRocId].fuNbShiftedEpochs[get4_index] );
03211                      ROC[uRocId].fEpochShiftsDurationPerChip->Fill( get4_index,
03212                            ROC[uRocId].fuNbShiftedEpochs[get4_index] );
03213                   }
03214                   ROC[uRocId].fiEpochShift[get4_index]      = 0 ;
03215                   ROC[uRocId].fuNbShiftedEpochs[get4_index] = 0;
03216                }
03217 
03218             ROC[uRocId].fuCurrEpoch2[get4_index] = get4_32b_ep_epoch;
03219          } // if non consecutive epoch indexes
03220             else
03221             {
03222                if( ROC[uRocId].fuCurrEpoch2[get4_index] > get4_32b_ep_epoch )
03223                   ROC[uRocId].fuEpoch2Cycle[get4_index]++;
03224                ROC[uRocId].fuCurrEpoch2[get4_index] = get4_32b_ep_epoch;
03225 
03226                if( 0 != ROC[uRocId].fiEpochShift[get4_index] )
03227                   ROC[uRocId].fuNbShiftedEpochs[get4_index]++;
03228             } // else of if non consecutive epoch indexes
03229 
03230          // Event statistics
03231          ROC[uRocId].fuNbHitsChipEpoch[get4_index] = 0;
03232 
03233          /*
03234           * Temp fix for nov 2012 epoch problem
03235           */
03236 /*
03237          if( 0 == get4_index)
03238          {
03239             if( ROC[uRocId].fuCurrEpoch2[get4_index] > get4_32b_ep_epoch )
03240             {
03241                ROC[uRocId].fuEpoch2Cycle[1]++;
03242                ROC[uRocId].fuEpoch2Cycle[5]++;
03243             }
03244             ROC[uRocId].fuCurrEpoch2[1] = get4_32b_ep_epoch;
03245             ROC[uRocId].fuCurrEpoch2[5] = get4_32b_ep_epoch;
03246          }
03247          if( 1 != get4_index && 5 != get4_index)
03248          {
03249             if( ROC[uRocId].fuCurrEpoch2[get4_index] > get4_32b_ep_epoch )
03250                ROC[uRocId].fuEpoch2Cycle[get4_index]++;
03251             ROC[uRocId].fuCurrEpoch2[get4_index] = get4_32b_ep_epoch;
03252          }
03253 */
03254 
03255          ROC[uRocId].fDistribEpochs2->Fill(get4_index, ROC[uRocId].fuCurrEpoch2[get4_index]);
03256 
03257          ULong64_t uFullTimeBins = ((ULong64_t)  ROC[uRocId].GetFullEpoch2Number( get4_index )) << 19;
03258          ULong64_t uFullTime = uFullTimeBins/ 20 + 512;
03259          Double_t  dFullTime = uFullTimeBins / 20. + 512.;
03260          extMess.SetFullTime(  uFullTime );
03261          extMess.SetFullTimeD( dFullTime );
03262 
03263          // Count per global time unit in s
03264          ULong64_t ulEpochTm = uFullTime / 100000000L;
03265          ROC[uRocId].fEPOCH2t[get4_index]->Fill((ulEpochTm % 36000) * 0.1);
03266 
03267          // Long duration time distribution (1 min. bin, 10 days length)
03268          if( kTRUE == fParam->bLongTimeHistos )
03269             ROC[uRocId].fAllEpoch2LongT->Fill( (ulEpochTm * 0.1 ) / 3600 );
03270 
03271          // Swap the flag indicating which buffer contains currently happening epoch
03272          ROC[uRocId].fbBufferWithLastFullEpoch2[get4_index] = ( kTRUE == ROC[uRocId].fbBufferWithLastFullEpoch2[get4_index] ? kFALSE: kTRUE );
03273          // Clear this buffer (Data more than 1 full epoch old => either already selected or junk)
03274          ROC[uRocId].fPrevEpochs2Buffer[get4_index][ ROC[uRocId].fbBufferWithLastFullEpoch2[get4_index] ].clear();
03275 
03276          break;
03277       }
03278       case 1: // slow control message
03279       {
03280          UInt_t get4_32b_sl_data = extMess.getGet4V10R32SlData();
03281          UInt_t get4_32b_sl_type = extMess.getGet4V10R32SlType();
03282          UInt_t get4_32b_sl_edge = extMess.getGet4V10R32SlEdge();
03283          UInt_t get4_32b_sl_chan = extMess.getGet4V10R32SlChan();
03284 
03285          if( get4_32b_sl_type < 3)
03286             ROC[uRocId].fGet4V1SlowControlType->Fill(get4_index, get4_32b_sl_type);
03287 
03288          ULong64_t uFullTimeBins = ((ULong64_t)  ROC[uRocId].GetFullEpoch2Number( get4_index )) << 19;
03289          ULong64_t uFullTime = uFullTimeBins/ 20 + 512;
03290          Double_t  dFullTime = uFullTimeBins / 20. + 512.;
03291          extMess.SetFullTime(  uFullTime );
03292          extMess.SetFullTimeD( dFullTime );
03293 
03294          uFullTimeBins /= 20;
03295          uFullTimeBins += 512;
03296          uFullTimeBins /= 100000000L;
03297          ROC[uRocId].fSLOWCt->Fill( (uFullTimeBins % 36000) * 0.1 );
03298 
03299          // Long duration time distribution (1 min. bin, 10 days length)
03300          if( kTRUE == fParam->bLongTimeHistos )
03301             ROC[uRocId].fSlowCLongT->Fill( (uFullTimeBins * 0.1 ) / 3600 );
03302 
03303          switch(get4_32b_sl_type)
03304          {
03305             case 0:
03306                ROC[uRocId].fGet4V1SlowControlScaler->Fill(
03307                      NB_CHAN_GET4*get4_index + get4_32b_sl_chan + 0.5*get4_32b_sl_edge, get4_32b_sl_data );
03308                break;
03309             case 1:
03310                ROC[uRocId].fGet4V1SlowControlDeadTime->Fill(
03311                      NB_CHAN_GET4*get4_index + get4_32b_sl_chan + 0.5*get4_32b_sl_edge, get4_32b_sl_data );
03312                break;
03313             case 2:
03314                TGo4Log::Info("Get4 V1.0 32bit, chip %02d, SPI message: %06x", get4_index, get4_32b_sl_data);
03315                break;
03316             case 3:
03317                if( 0 == get4_32b_sl_chan && 1 == get4_32b_sl_edge )
03318                {
03319                   ROC[uRocId].fGet4V1SlowControlType->Fill(get4_index, 4);
03320                   ROC[uRocId].fGet4V1SlowControlHamming->Fill( get4_index, get4_32b_sl_data );
03321                   ROC[uRocId].fGet4V1SlowControlSeuEvo->Fill( 
03322                                 ( ROC[uRocId].GetFullEpoch2Number(get4_index) * GET4_EPOCH_IN_PS ) / 1e12, 
03323                                 get4_index, get4_32b_sl_data );
03324                }
03325                   else
03326                   {
03327                      ROC[uRocId].fGet4V1SlowControlType->Fill(get4_index, get4_32b_sl_type);
03328                      TGo4Log::Info("Get4 V1.0 32bit, chip %02d, Start message: %c%c%c (%6X)",
03329                            get4_index,
03330                            (get4_32b_sl_data>>16)&0xFF, (get4_32b_sl_data>>8)&0xFF,
03331                            get4_32b_sl_data&0xFF, get4_32b_sl_data);
03332                   }
03333 
03334                break;
03335             default:
03336                break;
03337          }
03338 
03339          break;
03340       }
03341       case 2: // error event
03342       {
03343          UInt_t get4_32b_er_code = extMess.getGet4V10R32ErrorData();
03344          UInt_t get4_32b_er_chan = extMess.getGet4V10R32ErrorChan();
03345          UInt_t get4_32b_er_edge = extMess.getGet4V10R32ErrorEdge();
03346 
03347          ULong64_t uFullTimeBins = ((ULong64_t)  ROC[uRocId].GetFullEpoch2Number( get4_index )) << 19;
03348          ULong64_t uFullTime = uFullTimeBins/ 20 + 512;
03349          Double_t  dFullTime = uFullTimeBins / 20. + 512.;
03350          extMess.SetFullTime(  uFullTime );
03351          extMess.SetFullTimeD( dFullTime );
03352 
03353          uFullTimeBins /= 20;
03354          uFullTimeBins += 512;
03355          uFullTimeBins /= 100000000L;
03356          ROC[uRocId].fERRORt->Fill( (uFullTimeBins % 36000) * 0.1 );
03357 
03358          // Long duration time distribution (1 min. bin, 10 days length)
03359          if( kTRUE == fParam->bLongTimeHistos )
03360             ROC[uRocId].fErrorLongT->Fill( (uFullTimeBins * 0.1 ) / 3600 );
03361 
03362          ROC[uRocId].fGet4ErrorChip->Fill( get4_index );
03363          ROC[uRocId].fGet4ErrorPatt->Fill( get4_index, get4_32b_er_code);
03364          if( (0x03 < get4_32b_er_code && get4_32b_er_code < 0x07) )
03365             ROC[uRocId].fGet4ErrorChan->Fill(
03366                   NB_CHAN_GET4*get4_index + get4_32b_er_chan + 0.5*get4_32b_er_edge,
03367                   get4_32b_er_code - 0x04 );
03368          else if( 0x11 == get4_32b_er_code ||
03369                    0x12 == get4_32b_er_code )
03370             ROC[uRocId].fGet4ErrorChan->Fill(
03371                   NB_CHAN_GET4*get4_index + get4_32b_er_chan + 0.5*get4_32b_er_edge,
03372                   get4_32b_er_code - 0x0e );
03373 
03374          break;
03375       }
03376       case 3: // data event
03377       {
03378          UInt_t get4_32b_dat_tot  = extMess.getGet4V10R32HitTot();
03379          UInt_t get4_32b_dat_ft   = extMess.getGet4V10R32HitFt();
03380          UInt_t get4_32b_dat_ts   = extMess.getGet4V10R32HitTs();
03381          UInt_t get4_32b_dat_chan = extMess.getGet4V10R32HitChan();
03382          UInt_t get4_32b_dat_dll  = extMess.getGet4V10R32HitDllFlag();
03383          if( NB_CHAN_GET4 <= get4_32b_dat_chan )
03384             return -1;
03385 
03386          ULong64_t uFullTimeBins = ((ULong64_t)  ROC[uRocId].GetFullEpoch2Number( get4_index ) << 19) |
03387                                     (ULong64_t)extMess.getGet4V10R32HitTimeBin();
03388          ULong64_t uFullTime = uFullTimeBins/ 20 + 512;
03389          Double_t  dFullTime = ((Double_t)uFullTimeBins)*0.05 + 512.;
03390          extMess.SetFullTime(  uFullTime );
03391          extMess.SetFullTimeD( dFullTime );
03392 
03393          uFullTimeBins /= 20;
03394          uFullTimeBins += 512;
03395          uFullTimeBins /= 100000000L;
03396          ROC[uRocId].fDATAt->Fill( (uFullTimeBins % 36000) * 0.1 );
03397 
03398          // Long duration time distribution (1 min. bin, 10 days length)
03399          if( kTRUE == fParam->bLongTimeHistos )
03400             ROC[uRocId].fDataLongT->Fill( (uFullTimeBins * 0.1 ) / 3600 );
03401 
03402          if( 0 < ROC[uRocId].fLastExtMess[get4_index][get4_32b_dat_chan].GetFullTimeD() )
03403          {
03404             ROC[uRocId].fGet4V1HitsDistanceNs[get4_index]->Fill( extMess.GetFullTimeD()
03405                   - ROC[uRocId].fLastExtMess[get4_index][get4_32b_dat_chan].GetFullTimeD(),
03406                   get4_32b_dat_chan);
03407             ROC[uRocId].fGet4V1HitsDistanceUs[get4_index]->Fill( ( extMess.GetFullTimeD()
03408                   - ROC[uRocId].fLastExtMess[get4_index][get4_32b_dat_chan].GetFullTimeD() )/1e3,
03409                   get4_32b_dat_chan);
03410             ROC[uRocId].fGet4V1HitsDistanceMs[get4_index]->Fill( ( extMess.GetFullTimeD()
03411                   - ROC[uRocId].fLastExtMess[get4_index][get4_32b_dat_chan].GetFullTimeD() )/1e6,
03412                   get4_32b_dat_chan);
03413             ROC[uRocId].fGet4V1HitsDistanceS[get4_index]->Fill( ( extMess.GetFullTimeD()
03414                   - ROC[uRocId].fLastExtMess[get4_index][get4_32b_dat_chan].GetFullTimeD() )/1e9,
03415                   get4_32b_dat_chan);
03416          }
03417 
03418          // Event statistics
03419          ROC[uRocId].fLastExtMess[get4_index][get4_32b_dat_chan] = extMess;
03420          ROC[uRocId].fChannelInputMessCount->Fill( get4_index + (Double_t)get4_32b_dat_chan/(Double_t)NB_CHAN_GET4  );
03421          if( kTRUE == fParam->bChipRateHistoEnable )
03422             ROC[uRocId].fChipRateEvolution[get4_index]->Fill(
03423                   (uFullTimeBins ) * 0.1, 1.0/ROC[uRocId].fdRateEvolutionBinSize );
03424          if( kTRUE == fParam->bChannelRateHistoEnable )
03425             ROC[uRocId].fChannelRateEvolution[get4_index][get4_32b_dat_chan]->Fill(
03426                   (uFullTimeBins ) * 0.1, 1.0/ROC[uRocId].fdRateEvolutionBinSize );
03427          ROC[uRocId].fuNbHitsChipEpoch[get4_index] ++;
03428 
03429          // TODO: bin size for Tot as option!!!
03430          if( 1 == fParam->bTotHistoEnable )
03431             ROC[uRocId].fRawTot[get4_index][get4_32b_dat_chan]->Fill( get4_32b_dat_tot*25500.0/255.0 );
03432 
03433          ROC[uRocId].fGet4V1DllLockBit->Fill( NB_CHAN_GET4*get4_index + get4_32b_dat_chan,
03434                                   get4_32b_dat_dll);
03435          if( kTRUE == ROC[uRocId].fbDllFlag[get4_index][get4_32b_dat_chan] && 1 == get4_32b_dat_dll)
03436          {
03437             ROC[uRocId].fbDllFlag[get4_index][get4_32b_dat_chan] = kFALSE;
03438             cout<<"DLL lock recovery, chip "<<get4_index<<" chan "<<get4_32b_dat_chan<<" at "<<(Double_t)uFullTimeBins*0.1<<" s"<<endl;
03439          }
03440          if( kFALSE == ROC[uRocId].fbDllFlag[get4_index][get4_32b_dat_chan] && 0 == get4_32b_dat_dll)
03441          {
03442             ROC[uRocId].fbDllFlag[get4_index][get4_32b_dat_chan] = kTRUE;
03443             cout<<"DLL lock loss, chip "<<get4_index<<" chan "<<get4_32b_dat_chan<<" at "<<(Double_t)uFullTimeBins*0.1<<" s"<<endl;
03444          }
03445 
03446          // Early event closure check
03447          if( kTRUE == fCurrentGet4Event.HasTrigger() &&
03448              kFALSE == ROC[uRocId].fbSelectionDone[get4_index]  )
03449          {
03450             Double_t dTimeToTrigger = 0.0;
03451             dTimeToTrigger = extMess.GetFullTimeD() - fCurrentGet4Event.fdTriggerFullTime[uRocId];
03452             if( kFALSE == ROC[uRocId].fTriggerWind->Test( dTimeToTrigger) )
03453             {
03454                // Message after the end of trigger window!!
03455                Bool_t bAllChanInChipOver = kTRUE;
03456 
03457                // If there was already a message from the same channel out of the trigger
03458                //  window, then the token ring made at least one full turn => ok for all
03459                // Otherwise: need to check other channels status
03460                if( kFALSE == ROC[uRocId].fbDataTimeOut[get4_index][get4_32b_dat_chan] )
03461                {
03462                   // 32b = always a hit, not just edge !
03463                   ROC[uRocId].fbDataTimeOut[get4_index][get4_32b_dat_chan] = kTRUE;
03464                   // Check if chip fully finished
03465                   for(UInt_t uChanTest = 0; uChanTest < NB_CHAN_GET4; uChanTest ++)
03466                      if( kFALSE ==  ROC[uRocId].fbDataTimeOut[get4_index][uChanTest] )
03467                         bAllChanInChipOver = kFALSE;
03468                }
03469                // If chip fully finished: don't wait for the next epoch to close future buffer
03470                // of current event for this chip
03471                if( kTRUE == bAllChanInChipOver)
03472                {
03473                   // If This is the first epoch after the trigger and 
03474                   // we did not process the epoch before the one where the 
03475                   // trigger came, we need to initialize the 24 bit temp hits
03476                   if( kFALSE == ROC[uRocId].fbEpoch2SinceTrigger[get4_index] && 
03477                       kFALSE == ROC[uRocId].bLookInPreviousEpoch[get4_index] )
03478                      for( UInt_t uChan = 0; uChan < NB_CHAN_GET4; uChan++)
03479                            (ROC[uRocId].fHitTemp24[get4_index][uChan]).Clear();
03480                            
03481                   BuildHits(uRocId, get4_index, ROC[uRocId].fbBufferWithLastFullEpoch2[get4_index]);
03482                   ROC[uRocId].fbSelectionDone[get4_index] = kTRUE;
03483                   CheckEventClosure();
03484             
03485                   for(UInt_t uChanTest = 0; uChanTest < NB_CHAN_GET4; uChanTest ++)
03486                      ROC[uRocId].fbDataTimeOut[get4_index][uChanTest] = kFALSE;
03487                } // if( kTRUE == bAllChanInChipOver)
03488             } // if( kFALSE == ROC[uRocId].fTriggerWind->Test( dTimeToTrigger) )
03489          } // Event ongoing with a detected trigger and future buffer not closed
03490 
03492          if( kTRUE ==  fParam->bFreeStreaming && 0 < fParam->uNbTriggers )
03493          {
03494             for( Int_t iMainTriggerIndex = 0; iMainTriggerIndex < (Int_t)(fParam->uNbTriggers); iMainTriggerIndex++ )
03495                if( kTRUE == fParam->IsMainOfThisTrigger( iMainTriggerIndex, get4_index, get4_32b_dat_chan ) )
03496             {
03497                ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex] = extMess;
03498                /*
03499                 * TODO: call to ProcessTrigger
03500                 * TEMP: histo Filling + counting
03501                 */
03502                Bool_t bAllInCoinc = kTRUE;
03503                for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iMainTriggerIndex]; uSecChannel++)
03504                {
03505                   Double_t dDistanceToMain = ROC[uRocId].fdLastFullTimeSecChannel[iMainTriggerIndex][uSecChannel]
03506                                            - extMess.GetFullTimeD();
03507                   if( dDistanceToMain < fParam->dCoincidenceWindowStart[iMainTriggerIndex] ||
03508                         fParam->dCoincidenceWindowStop[iMainTriggerIndex] < dDistanceToMain      )
03509                   {
03510                      bAllInCoinc = kFALSE;
03511                      break;
03512                   } // if out of coincidence window
03513                } // for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iMainTriggerIndex]; uSecChannel++)
03514                if( kTRUE == bAllInCoinc )
03515                {
03516                   Double_t dSameTriggerDistance =
03517                           ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTimeD()
03518                         - ROC[uRocId].fdLastFullTimeSelfTrigger[iMainTriggerIndex] ;
03519 
03520                   ROC[uRocId].fDataSelfTrigDistanceNs->Fill( dSameTriggerDistance,     iMainTriggerIndex );
03521                   ROC[uRocId].fDataSelfTrigDistanceUs->Fill( dSameTriggerDistance/1e3, iMainTriggerIndex );
03522                   ROC[uRocId].fDataSelfTrigDistanceMs->Fill( dSameTriggerDistance/1e6, iMainTriggerIndex );
03523                   ROC[uRocId].fDataSelfTrigDistanceS->Fill(  dSameTriggerDistance/1e9, iMainTriggerIndex );
03524 
03525                   if( fParam->dDeadTime <= dSameTriggerDistance )
03526                   {
03527                      // Here we have a DATA self-trigger!!!!!!
03528                      ROC[uRocId].fuDataSelfTriggerCount[iMainTriggerIndex] ++;
03529 
03530                      ROC[uRocId].fdLastFullTimeSelfTrigger[iMainTriggerIndex] =
03531                            ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTimeD();
03532 
03533                      ULong64_t uFullTimeSelfTrigBins = ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex].GetFullTime();
03534                      uFullTimeSelfTrigBins /= 100000000L;
03535                      ROC[uRocId].fSelfTriggT->Fill( (uFullTimeSelfTrigBins % 36000) * 0.1 );
03536 
03537                      // Long duration time distribution (1 min. bin, 10 days length)
03538                      if( kTRUE == fParam->bLongTimeHistos )
03539                         ROC[uRocId].fSelfTriggLongT->Fill( (uFullTimeSelfTrigBins * 0.1 ) / 3600 );
03540 
03541                      ProcessTriggerMessage(uRocId, ROC[uRocId].fextMessLastMainChannel[iMainTriggerIndex], iMainTriggerIndex);
03542                   } // if( fParam->dDeadTime <= dSameTriggerDistance )
03543                } // if( kTRUE == bAllInCoinc )
03544             } // if( -1 < iMainTriggerIndex )
03545             for( Int_t iSecTriggerIndex = 0; iSecTriggerIndex < (Int_t)(fParam->uNbTriggers); iSecTriggerIndex++ )
03546             {
03547                if( kTRUE == fParam->IsSecOfThisTrigger( iSecTriggerIndex, get4_index, get4_32b_dat_chan ) )
03548                   {
03549                      Int_t iSecondaryIndex = fParam->GetSecChannelIndex(iSecTriggerIndex, get4_index, get4_32b_dat_chan);
03550                      if( -1 < iSecondaryIndex )
03551                      {
03552                         ROC[uRocId].fdLastFullTimeSecChannel[iSecTriggerIndex][iSecondaryIndex] = extMess.GetFullTimeD();
03553 
03554                         /*
03555                          * TODO: call to ProcessTrigger
03556                          * TEMP: histo Filling + counting
03557                          */
03558                         Bool_t bAllInCoinc = kTRUE;
03559                         for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iSecTriggerIndex]; uSecChannel++)
03560                         {
03561                            Double_t dDistanceToMain = ROC[uRocId].fdLastFullTimeSecChannel[iSecTriggerIndex][uSecChannel]
03562                                              - ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD();
03563                            if( dDistanceToMain < fParam->dCoincidenceWindowStart[iSecTriggerIndex] ||
03564                                  fParam->dCoincidenceWindowStop[iSecTriggerIndex] < dDistanceToMain      )
03565                            {
03566                               bAllInCoinc = kFALSE;
03567                               break;
03568                            } // if out of coincidence window
03569                         } // for( UInt_t uSecChannel = 0; uSecChannel < fParam->uNbSecondarySelectionCh[iSecTriggerIndex]; uSecChannel++)
03570                         if( kTRUE == bAllInCoinc  )
03571                         {
03572                            Double_t dSameTriggerDistance =
03573                                    ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD()
03574                                  - ROC[uRocId].fdLastFullTimeSelfTrigger[iSecTriggerIndex] ;
03575 
03576                            ROC[uRocId].fDataSelfTrigDistanceNs->Fill( dSameTriggerDistance,     iSecTriggerIndex );
03577                            ROC[uRocId].fDataSelfTrigDistanceUs->Fill( dSameTriggerDistance/1e3, iSecTriggerIndex );
03578                            ROC[uRocId].fDataSelfTrigDistanceMs->Fill( dSameTriggerDistance/1e6, iSecTriggerIndex );
03579                            ROC[uRocId].fDataSelfTrigDistanceS->Fill(  dSameTriggerDistance/1e9, iSecTriggerIndex );
03580 
03581                            if( fParam->dDeadTime <= dSameTriggerDistance )
03582                            {
03583                               // Here we have a DATA self-trigger!!!!!!
03584                               ROC[uRocId].fuDataSelfTriggerCount[iSecTriggerIndex] ++;
03585 
03586                               ROC[uRocId].fdLastFullTimeSelfTrigger[iSecTriggerIndex] =
03587                                     ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTimeD();
03588 
03589                               ULong64_t uFullTimeSelfTrigBins = ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex].GetFullTime();
03590                               uFullTimeSelfTrigBins /= 100000000L;
03591                               ROC[uRocId].fSelfTriggT->Fill( (uFullTimeSelfTrigBins % 36000) * 0.1 );
03592 
03593                               // Long duration time distribution (1 min. bin, 10 days length)
03594                               if( kTRUE == fParam->bLongTimeHistos )
03595                                  ROC[uRocId].fSelfTriggLongT->Fill( (uFullTimeSelfTrigBins * 0.1 ) / 3600 );
03596 
03597                               ProcessTriggerMessage(uRocId, ROC[uRocId].fextMessLastMainChannel[iSecTriggerIndex], iSecTriggerIndex);
03598                            } // if( fParam->dDeadTime <= dSameTriggerDistance )
03599                         } // if( kTRUE == bAllInCoinc  )
03600                      } // if( -1 < iSecondaryIndex )
03601                   } //  if( -1 < iSecTriggerIndex )
03602                } // else of if( -1 < iMainTriggerIndex )
03603          } // if( kTRUE ==  fParam->bFreeStreaming && 0 < fParam->uNbTriggers )
03604 
03605          break;
03606       }
03607       default:
03608          break;
03609    } // switch(get4_32b_type)
03610 
03611    return get4_32b_type;
03612 }
03613 /**********************************************************************/
03614 
03615 Bool_t TGet4v1Proc::AnalyzeAllGet4Channels( Get4v1Event &eventFull )
03616 {
03617 
03618    /* TODO FILL ME
03619     * both readout mode histo filling
03620     */
03621    for( UInt_t  uRocId =0; uRocId<fParam->numRocs; uRocId++ )
03622    {
03623       if( !fParam->IsActiveRoc(uRocId) ) continue;
03624 
03625       for( Int_t iGet4 = 0; iGet4 < MAX_GET4_PER_ROC; iGet4++)
03626          for( Int_t iGet4Chan = 0; iGet4Chan < NB_CHAN_GET4; iGet4Chan++)
03627          {
03628             if( 0 < ( (eventFull.fGet4Boards[iGet4]).fHits[iGet4Chan]).size() )
03629             {
03630                for( Int_t iGet4Chan_2 = iGet4Chan+1; iGet4Chan_2 < NB_CHAN_GET4; iGet4Chan_2++)
03631                   if( 0 < ( (eventFull.fGet4Boards[iGet4]).fHits[iGet4Chan_2]).size() )
03632                      ROC[uRocId].fChannelsMapping->Fill( iGet4 + (Double_t)iGet4Chan/(Double_t)NB_CHAN_GET4,
03633                                              iGet4 + (Double_t)iGet4Chan_2/(Double_t)NB_CHAN_GET4 );
03634 
03635                for( Int_t iGet4_2 = iGet4+1; iGet4_2 < MAX_GET4_PER_ROC; iGet4_2++)
03636                   for( Int_t iGet4Chan_2 = 0; iGet4Chan_2 < NB_CHAN_GET4; iGet4Chan_2++)
03637                      if( 0 < ( (eventFull.fGet4Boards[iGet4_2]).fHits[iGet4Chan_2]).size() )
03638                         ROC[uRocId].fChannelsMapping->Fill( iGet4 + (Double_t)iGet4Chan/(Double_t)NB_CHAN_GET4,
03639                                                 iGet4_2 + (Double_t)iGet4Chan_2/(Double_t)NB_CHAN_GET4 );
03640             }
03641 
03642             ROC[uRocId].fChannelMultiplicity->Fill( iGet4 + (Double_t)iGet4Chan/(Double_t)NB_CHAN_GET4,
03643                   ( (eventFull.fGet4Boards[iGet4]).fHits[iGet4Chan]).size());
03644          }
03645 
03646       if( 1 == fParam->bDebugHistoEnable )
03647       {
03648          UInt_t uHistosIndexSingleChip = 0;
03649          UInt_t uHistosIndexChipVsChip = 0;
03650          for(UInt_t uFirstGet4Channel = 0; uFirstGet4Channel < NB_CHAN_GET4; uFirstGet4Channel++)
03651          {
03652             for(UInt_t uSecondGet4Channel = 0; uSecondGet4Channel < NB_CHAN_GET4; uSecondGet4Channel++)
03653             {
03654                if( uFirstGet4Channel < uSecondGet4Channel )
03655                {
03656                   if( 1 == ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip1]).fHits[uFirstGet4Channel]).size() &&
03657                       1 == ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip1]).fHits[uSecondGet4Channel]).size() )
03658                   {
03659                      ROC[uRocId].fTimeDiffInsideChip[0][uHistosIndexSingleChip]->Fill(
03660                            ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip1]).fHits[uFirstGet4Channel])[0].GetTimeDiff(
03661                            ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip1]).fHits[uSecondGet4Channel])[0]) );
03662                      // 1D FineTime correlation
03663                      ROC[uRocId].fFTCorrel[0][uHistosIndexSingleChip]->Fill(
03664                            ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip1]).fHits[uSecondGet4Channel])[0].GetHitLeadingFTS()
03665                           -( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip1]).fHits[uFirstGet4Channel])[0].GetHitLeadingFTS() );
03666                      // 2D FineTime correlation
03667                      ROC[uRocId].fFTCorrel2D[0][uHistosIndexSingleChip]->Fill(
03668                            ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip1]).fHits[uFirstGet4Channel])[0].GetHitLeadingFTS(),
03669                            ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip1]).fHits[uSecondGet4Channel])[0].GetHitLeadingFTS() );
03670                   }
03671                   if( 1 == ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip2]).fHits[uFirstGet4Channel]).size() &&
03672                       1 == ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip2]).fHits[uSecondGet4Channel]).size() )
03673                   {
03674                      ROC[uRocId].fTimeDiffInsideChip[1][uHistosIndexSingleChip]->Fill(
03675                            ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip2]).fHits[uFirstGet4Channel])[0].GetTimeDiff(
03676                            ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip2]).fHits[uSecondGet4Channel])[0]) );
03677                      // 1D FineTime correlation
03678                      ROC[uRocId].fFTCorrel[1][uHistosIndexSingleChip]->Fill(
03679                            ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip2]).fHits[uSecondGet4Channel])[0].GetHitLeadingFTS()
03680                           -( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip2]).fHits[uFirstGet4Channel])[0].GetHitLeadingFTS() );
03681                      // 2D FineTime correlation
03682                      ROC[uRocId].fFTCorrel2D[1][uHistosIndexSingleChip]->Fill(
03683                            ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip2]).fHits[uFirstGet4Channel])[0].GetHitLeadingFTS(),
03684                            ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip2]).fHits[uSecondGet4Channel])[0].GetHitLeadingFTS() );
03685                   }
03686                   uHistosIndexSingleChip++;
03687                } // if( uFirstGet4Channel < uSecondGet4Channel )
03688                if( 1 == ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip1]).fHits[uFirstGet4Channel]).size() &&
03689                    1 == ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip2]).fHits[uSecondGet4Channel]).size() )
03690                {
03691                   ROC[uRocId].fTimeDiffBetweenChips[uHistosIndexChipVsChip]->Fill(
03692                         ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip1]).fHits[uFirstGet4Channel])[0].GetTimeDiff(
03693                         ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip2]).fHits[uSecondGet4Channel])[0]) );
03694                   ROC[uRocId].fFTCorrelChipToChip[uHistosIndexChipVsChip]->Fill(
03695                         ( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip2]).fHits[uSecondGet4Channel])[0].GetHitLeadingFTS()
03696                        -( (eventFull.fGet4Boards[fParam->uGet4TimeDiffChip1]).fHits[uFirstGet4Channel])[0].GetHitLeadingFTS() );
03697                }
03698                uHistosIndexChipVsChip++;
03699             } // for(UInt_t uSecondGet4Channel = 0; uSecondGet4Channel < MAX_GET4_CH; uSecondGet4Channel++)
03700          } // for(UInt_t uFirstGet4Channel = 0; uFirstGet4Channel < MAX_GET4_CH; uFirstGet4Channel++)
03701       } // if( 1 == fParam->bDebugHistoEnable )
03702    } // for( UInt_t  uRocId =0; uRocId<fParam->numRocs; uRocId++ )
03703 
03704    if( kTRUE == fb32bitsReadoutDetected )
03705       AnalyzeAllGet4Channels32Bits( fCurrentGet4Event );
03706       else AnalyzeAllGet4Channels24Bits( fCurrentGet4Event );
03707 
03708    return kTRUE;
03709 }
03710 Bool_t TGet4v1Proc::AnalyzeAllGet4Channels24Bits( Get4v1Event &eventFull )
03711 {
03712 
03713    /* TODO FILL ME
03714     * 24 bit mode histo filling
03715     */
03716 
03717    if( 1 == fParam->bDebugHistoEnable )
03718       for( UInt_t  uRoc =0; uRoc<fParam->numRocs; uRoc++ )
03719          if( fParam->IsActiveRoc(uRoc) )
03720             if( 0 == uNbEvents[uRoc]%fParam->uNbEventsDnlUpdate )
03721             {
03722                UpdateLeadingDnlHistograms( eventFull, uRoc );
03723                UpdateTrailingDnlHistograms( eventFull, uRoc );
03724             }
03725 
03726    return kTRUE;
03727 }
03728 Bool_t TGet4v1Proc::AnalyzeAllGet4Channels32Bits( Get4v1Event &eventFull )
03729 {
03730 
03731    /* TODO FILL ME
03732     * 32 bit mode histo filling
03733     */
03734 
03735    if( 1 == fParam->bDebugHistoEnable )
03736       for( UInt_t  uRoc =0; uRoc<fParam->numRocs; uRoc++ )
03737          if( fParam->IsActiveRoc(uRoc) )
03738             if( 0 == uNbEvents[uRoc]%fParam->uNbEventsDnlUpdate )
03739                UpdateLeadingDnlHistograms( eventFull, uRoc );
03740 
03741    return kTRUE;
03742 }
03743 /**********************************************************************/
03744 
03745 Bool_t TGet4v1Proc::PrintRocEpochIndexes(UInt_t uRocId, Int_t uMessagePriority )
03746 {
03747    TString sOutput = "";
03748 
03749    for( UInt_t uGet4 = 0; uGet4 < fParam->uNbGet4; uGet4++)
03750    {
03751       sOutput += Form(" %7d", ROC[uRocId].fuCurrEpoch2[uGet4]);
03752    }
03753    Message(uMessagePriority,"Current ROC epoch indexes: %s ", sOutput.Data() );
03754 
03755    return kTRUE;
03756 }
03757 Bool_t TGet4v1Proc::PrintRocEpochCycles(UInt_t uRocId, Int_t uMessagePriority )
03758 {
03759    TString sOutput = "";
03760 
03761    for( UInt_t uGet4 = 0; uGet4 < fParam->uNbGet4; uGet4++)
03762    {
03763       sOutput += Form(" %6d", ROC[uRocId].fuEpoch2Cycle[uGet4]);
03764    }
03765    Message(uMessagePriority,"Current ROC cycle indexes: %s ", sOutput.Data() );
03766 
03767    return kTRUE;
03768 }
03769 /**********************************************************************/
03770 void TGet4v1Proc::UpdateLeadingDnlHistograms( Get4v1Event &eventFull, UInt_t uRocId )
03771 {
03772    for( Int_t iGet4 = 0; iGet4 < MAX_GET4_PER_ROC; iGet4++)
03773       for( Int_t iGet4Chan = 0; iGet4Chan < NB_CHAN_GET4; iGet4Chan++)
03774       {
03775          UInt_t uRemappedGet4Index = fParam->RemapGet4Chip(uRocId, iGet4);
03776          if( kTRUE == fParam->IsValidGet4Chip(uRemappedGet4Index) &&
03777              kTRUE == fParam->IsActiveGet4Chip(uRemappedGet4Index) )
03778          {
03779             Double_t dDnlLeading = 0;
03780             Double_t dSumLeading = 0;
03781 
03782             // First Resets everything
03783             ROC[uRocId].fLeadingDnl[iGet4][iGet4Chan]->Reset();
03784             ROC[uRocId].fLeadingDnlSum[iGet4][iGet4Chan]->Reset();
03785 
03786             // First bin
03787             dDnlLeading = ( ROC[uRocId].fLeadingFTS[iGet4][iGet4Chan]->GetBinContent(1)
03788                            - (ROC[uRocId].fLeadingFTS[iGet4][iGet4Chan]->GetEntries()/(Double_t)NB_BIN_GET4_FTS) ) /
03789                             (ROC[uRocId].fLeadingFTS[iGet4][iGet4Chan]->GetEntries()/(Double_t)NB_BIN_GET4_FTS);
03790             ROC[uRocId].fLeadingDnl[iGet4][iGet4Chan]->Fill( 0.0, dDnlLeading);
03791             dSumLeading += dDnlLeading;
03792             ROC[uRocId].fLeadingDnlSum[iGet4][iGet4Chan]->Fill( 0.0, dSumLeading );
03793 
03794             for( int j = 2; j <= NB_BIN_GET4_FTS; j++)
03795             {
03796              dDnlLeading = ( ROC[uRocId].fLeadingFTS[iGet4][iGet4Chan]->GetBinContent(j)
03797                              - (ROC[uRocId].fLeadingFTS[iGet4][iGet4Chan]->GetEntries()/(Double_t)NB_BIN_GET4_FTS) ) /
03798                             (ROC[uRocId].fLeadingFTS[iGet4][iGet4Chan]->GetEntries()/(Double_t)NB_BIN_GET4_FTS);
03799              ROC[uRocId].fLeadingDnl[iGet4][iGet4Chan]->Fill( (Double_t)(j-1), dDnlLeading );
03800              dSumLeading += dDnlLeading;
03801              ROC[uRocId].fLeadingDnlSum[iGet4][iGet4Chan]->Fill( (Double_t)j-1, dSumLeading );
03802             }
03803          }
03804       } // For get4 in ROC, for channel in GET4
03805 }
03806 void TGet4v1Proc::UpdateTrailingDnlHistograms( Get4v1Event &eventFull, UInt_t uRocId )
03807 {
03808    for( Int_t iGet4 = 0; iGet4 < MAX_GET4_PER_ROC; iGet4++)
03809       for( Int_t iGet4Chan = 0; iGet4Chan < NB_CHAN_GET4; iGet4Chan++)
03810       {
03811          UInt_t uRemappedGet4Index = fParam->RemapGet4Chip(uRocId, iGet4);
03812          if( kTRUE == fParam->IsValidGet4Chip(uRemappedGet4Index) &&
03813              kTRUE == fParam->IsActiveGet4Chip(uRemappedGet4Index) )
03814          {
03815             Double_t dDnlTrailing = 0;
03816             Double_t dSumTrailing = 0;
03817 
03818             // First Resets everything
03819             ROC[uRocId].fTrailingDnl[iGet4][iGet4Chan]->Reset();
03820             ROC[uRocId].fTrailingDnlSum[iGet4][iGet4Chan]->Reset();
03821 
03822             // First bin
03823             dDnlTrailing = ( ROC[uRocId].fTrailingFTS[iGet4][iGet4Chan]->GetBinContent(1)
03824                             - (ROC[uRocId].fTrailingFTS[iGet4][iGet4Chan]->GetEntries()/(Double_t)NB_BIN_GET4_FTS) ) /
03825                             (ROC[uRocId].fTrailingFTS[iGet4][iGet4Chan]->GetEntries()/(Double_t)NB_BIN_GET4_FTS);
03826             ROC[uRocId].fTrailingDnl[iGet4][iGet4Chan]->Fill( 0.0, dDnlTrailing );
03827             dSumTrailing += dDnlTrailing;
03828             ROC[uRocId].fTrailingDnlSum[iGet4][iGet4Chan]->Fill( 0.0, dSumTrailing );
03829 
03830             for( int j = 2; j <= NB_BIN_GET4_FTS; j++)
03831             {
03832              dDnlTrailing = ( ROC[uRocId].fTrailingFTS[iGet4][iGet4Chan]->GetBinContent(j)
03833                              - (ROC[uRocId].fTrailingFTS[iGet4][iGet4Chan]->GetEntries()/(Double_t)NB_BIN_GET4_FTS) ) /
03834                             (ROC[uRocId].fTrailingFTS[iGet4][iGet4Chan]->GetEntries()/(Double_t)NB_BIN_GET4_FTS);
03835              ROC[uRocId].fTrailingDnl[iGet4][iGet4Chan]->Fill( (Double_t)(j-1), dDnlTrailing );
03836              dSumTrailing += dDnlTrailing;
03837              ROC[uRocId].fTrailingDnlSum[iGet4][iGet4Chan]->Fill( (Double_t)(j-1), dSumTrailing );
03838             }
03839          }
03840       } // For get4 in ROC, for channel in GET4
03841 }

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