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

onlinemonitor/spadicV10monitor/TSpadicV10Proc.cxx (r4864/r3724)

Go to the documentation of this file.
00001 #include "TSpadicV10Proc.h"
00002 
00003 #include "TH1.h"
00004 #include "TH2.h"
00005 #include "TTimeStamp.h"
00006 #include "TROOT.h"
00007 #include "TSystem.h"
00008 #include "TLatex.h"
00009 
00010 #include "TSpadicV10Param.h"
00011 #include "TGo4MbsEvent.h"
00012 #include "TGo4WinCond.h"
00013 #include "TGo4Log.h"
00014 
00015 
00016 #include "base/commons.h"
00017 #include "sp605/Message.h"
00018 //#include "sp605/Iterator.h"
00019 #include "sp605/Board.h"
00020 
00021 #include <algorithm>
00022 
00023 // enable this define for "online" mode with only one aux trigger per input buffer analyzed
00024 // if disabled, may process up to TSpadicV10Param::maxBufferTriggers per buffer (only offline mode with no lost samples!)
00025 #define SPADICV10_SINGLETRIGGERMODE 1
00026 //#define SPADICV10_DEBUG 1
00027 
00028 
00029 TSpadicV10Proc::TSpadicV10Proc() :
00030    TCBMBeamtimeProc(),
00031    fIsTimeSorted(kFALSE),
00032    fOutputEvent(0),
00033    fHasNewGlobalTrigger(kFALSE)
00034 {
00035 }
00036 
00037 //***********************************************************
00038 TSpadicV10Proc::~TSpadicV10Proc()
00039 {
00040 
00041    TGo4Log::Info("TSpadicV10Proc: Delete instance ");
00042 //   if (fParam->baselineCalibr && (fParam->pedSaveToFile.Length()>0) && fPedestals) {
00043 //      fPedestals->Extract();
00044 //      fPedestals->SaveToFile(fParam->pedSaveToFile.Data());
00045 //   }
00046 //
00047 //   if (fPedestals) {
00048 //      delete fPedestals;
00049 //      fPedestals = 0;
00050 //   }
00051 }
00052 
00053 //***********************************************************
00054 // this one is used in standard factory
00055 TSpadicV10Proc::TSpadicV10Proc(const char* name) :
00056    TCBMBeamtimeProc(name),
00057    fIsTimeSorted(kFALSE),
00058    fOutputEvent(0),
00059    fHasNewGlobalTrigger(kFALSE)
00060 {
00061    TGo4Log::Info("TSpadicV10Proc: Create instance %s", GetName());
00062 
00063    // SL TODO: after next go4 release change uncomment usage of setup macro
00064    fParam = (TSpadicV10Param *) MakeParameter("SpadicV10Par", "TSpadicV10Param" , "set_SpadicV10Par.C");
00065 
00066    fLastRateTm = TTimeStamp().AsDouble();
00067    fTotaldatasize = 0;
00068    fRate = 0.;
00069 
00070    fEvntSize = MakeTH1('I', "EvntSizeSpadicV10", "Number of messages in spadic v10 event", 250, 1., 2000.);
00071 
00072    int hnumbrds = fParam->numBoards > 8 ? fParam->numBoards : 8;
00073 
00074    fMsgsPerBoard = MakeTH1('I', "MsgsPerSpadicV10", "Number of messages per SPADICV10 board", hnumbrds, 0., hnumbrds);
00075 
00076    fTriggersPerBoard = MakeTH1('I', "TriggersPerSpadicV10", "Number of Trigger messages per SPADICV10 board", hnumbrds, 0., hnumbrds);
00077 
00078    fSYNC1_R01 = MakeTH1('I', "Spadic_SYNC1_R01", "Time difference between SYNC1 on boards 0 and 1", 5000, -5000., 5000., "#Delta t");
00079    fAUX2_R01 = MakeTH1('I', "Spadic_AUX2_R01", "Time difference between AUX2 on boards 0 and 1", 5000, -5000., 5000., "#Delta t");
00080 
00081    fDeltaTriggerTime = MakeTH1('I', "TriggerDeltaTimeSpadicV10", "Corrected hits time difference of all SPADICV10s", 5000, -5000., 5000., "#Delta t");
00082    fGlobalTriggerWind = MakeWinCond("SP605_TriggerWindow", -100, 2000., fDeltaTriggerTime->GetName());
00083    fGlobalAUXWind = MakeWinCond("SP605_AUXWindow", -100, 100., fDeltaTriggerTime->GetName());
00084 
00085    for (int brd=0; brd<fParam->numBoards; brd++) {
00086       BRDS.push_back(TSpadicV10BoardRec());
00087       BRDS[brd].MakeSpadicsVector(fParam->activeBoards[brd]);
00088 
00089       if (!AssertBoard(brd)) continue;
00090 
00091       char folder[100];
00092       sprintf(folder,"SP605_%u/", brd);
00093 
00094       BRDS[brd].fMsgCnt = MakeTH1('I', Form("%sMsgCounts%u", folder, brd), Form("Distribution of messages counts on SP605 %u board", brd), 9, 0., 9.);
00095       if (IsObjMade()) {
00096          BRDS[brd].fMsgCnt->GetXaxis()->SetBinLabel(1, "Black-box");
00097          for (int n=0;n<8;n++)
00098             BRDS[brd].fMsgCnt->GetXaxis()->SetBinLabel(1 + n+1, Form("SPADIC%d",n));
00099       }
00100 
00101       BRDS[brd].fMsgTypes = MakeTH1('I', Form("%sBlackBox/SP605MsgTypes%u", folder, brd), Form("Distribution of messages types in SP605 %u board", brd), 8, 0., 8.);
00102 
00103       if (IsObjMade()) {
00104          BRDS[brd].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_EPOCH, "EPOCH");
00105          BRDS[brd].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_HIT, "HIT");
00106          BRDS[brd].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_SYNC, "SYNC");
00107          BRDS[brd].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_AUX, "AUX");
00108          BRDS[brd].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_EPOCH2, "EPOCH2");
00109          BRDS[brd].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_GET4, "GET4");
00110          BRDS[brd].fMsgTypes->GetXaxis()->SetBinLabel(1 + roc::MSG_SYS, "SYS");
00111       }
00112 
00113       BRDS[brd].fAUXch = MakeTH1('I', Form("%sBlackBox/SP605_%u_AuxCh", folder, brd), "Number events per aux channel", 4, 0., 4.);
00114 
00115       for (unsigned nsync=0; nsync<MAX_SPADICV10_SYNC; nsync++)
00116          BRDS[brd].fSYNCt[nsync] = MakeTH1('I', Form("%sBlackBox/SP605_%u_Sync%u_t", folder, brd, nsync), Form("Time distribution of SYNC%u signal on SP605%u", nsync, brd), 10000, 0., 1000.);
00117 
00118       for (unsigned naux=0; naux<MAX_SPADICV10_AUX; naux++)
00119          BRDS[brd].fAUXt[naux] = MakeTH1('I', Form("%sBlackBox/SP605_%u_Aux%u_t", folder, brd, naux), Form("Time distribution of AUX%u signal on SP605%u", naux, brd), 10000, 0., 1000.);
00120 
00121       BRDS[brd].fSysTypes = MakeTH1('I', Form("%sBlackBox/SP605_%u_SysTypes", folder, brd), Form("SP605%u Distribution of black-box system messages", brd), roc::SYSMSG_PACKETLOST+1, 0., roc::SYSMSG_PACKETLOST+1);
00122       if (IsObjMade()) {
00123          BRDS[brd].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_DAQ_START,  "DAQ_START");
00124          BRDS[brd].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_DAQ_FINISH, "DAQ_FINISH");
00125          BRDS[brd].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_NX_PARITY,  "NX_PARITY");
00126          BRDS[brd].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_SYNC_PARITY,"SYNC_PARITY");
00127          BRDS[brd].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_DAQ_RESUME, "DAQ_RESUME");
00128          BRDS[brd].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_FIFO_RESET, "FIFO_RESET");
00129          BRDS[brd].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_USER,       "USER_MSG");
00130          BRDS[brd].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_PCTIME,     "PCTIME");
00131          BRDS[brd].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_ADC,        "ADC");
00132          BRDS[brd].fSysTypes->GetXaxis()->SetBinLabel(1 + roc::SYSMSG_PACKETLOST, "PACKETLOST");
00133       }
00134 
00135       BRDS[brd].fTrigger = MakeTH1('I', Form("%sSP605_%u_Trigger", folder, brd), Form("Time difference between all hits and last trigger signal on SP605 %u", brd), 2500, -1000., 4000.);
00136       BRDS[brd].fTrigger_100 = MakeTH1('I', Form("%sSP605_%u_Trigger_100", folder, brd), Form("Time difference between all hits and last trigger signal on SP605 %u", brd), 50005, -100000., 1e6);
00137       BRDS[brd].fTriggerWind = MakeWinCond(Form("SP605_%u_EventWindow",brd), 485., 885., BRDS[brd].fTrigger->GetName());
00138       BRDS[brd].fEvntMultipl = MakeTH1('I', Form("%sSP605_%u_Event_Multiplicity", folder, brd), Form("Event multiplicity for SP605 %u in time window", brd), 100, 0., 100.);
00139 
00140       for (unsigned spid=0; spid<BRDS[brd].numSpadics(); spid++) {
00141          if (!AssertSpadic(brd, spid)) continue;
00142 
00143          char dfolder[100];
00144          sprintf(folder, "%sSPADIC_%u/", folder, spid);
00145 
00146          TSpadicV10Rec& rec = BRDS[brd].SPADICS[spid];
00147 
00148          rec.fMsgTypes = MakeTH1('I', Form("%sMsgTypes_%u_%u", dfolder, brd, spid), Form("Distribution of messages types in SP605 %u board", brd), 8, 0., 8.);
00149          if (IsObjMade()) {
00150             rec.fMsgTypes->GetXaxis()->SetBinLabel(1 + sp605::MSG_NOP, "NOP");
00151             rec.fMsgTypes->GetXaxis()->SetBinLabel(1 + sp605::MSG_HIT, "HIT");
00152             rec.fMsgTypes->GetXaxis()->SetBinLabel(1 + sp605::MSG_OVERFLOW, "OVFL");
00153             rec.fMsgTypes->GetXaxis()->SetBinLabel(1 + sp605::MSG_INFO, "INFO");
00154             rec.fMsgTypes->GetXaxis()->SetBinLabel(1 + sp605::MSG_EPOCH, "EPOCH");
00155          }
00156 
00157          rec.fTrigTypes = MakeTH1('I', Form("%sHitTypes_%u_%u", dfolder, brd, spid), Form("Distribution of hit types for board %u spadic %u", brd, spid), 4, 0., 4);
00158          if (IsObjMade()) {
00159             rec.fTrigTypes->GetXaxis()->SetBinLabel(1 + sp605::TRIG_GLOBAL,     "GLOB");
00160             rec.fTrigTypes->GetXaxis()->SetBinLabel(1 + sp605::TRIG_SELF,       "SELF");
00161             rec.fTrigTypes->GetXaxis()->SetBinLabel(1 + sp605::TRIG_NEIGHBOR,   "NEIGH");
00162             rec.fTrigTypes->GetXaxis()->SetBinLabel(1 + sp605::TRIG_BOTH,       "BOTH");
00163          }
00164 
00165          rec.fStopTypes = MakeTH1('I', Form("%sStopTypes_%u_%u", dfolder, brd, spid), Form("Distribution of stop types for board %u spadic %u", brd, spid), 8, 0., 8.);
00166          if (IsObjMade()) {
00167             rec.fStopTypes->GetXaxis()->SetBinLabel(1 + sp605::STOP_NORMAL,             "NORM");
00168             rec.fStopTypes->GetXaxis()->SetBinLabel(1 + sp605::STOP_OUTBUFFULL,         "FULBUF");
00169             rec.fStopTypes->GetXaxis()->SetBinLabel(1 + sp605::STOP_FIFOFULL,           "FULFIFO");
00170             rec.fStopTypes->GetXaxis()->SetBinLabel(1 + sp605::STOP_MULTIHIT,           "MULTI");
00171             rec.fStopTypes->GetXaxis()->SetBinLabel(1 + sp605::STOP_OUTBUFFULLMULTIHIT, "MULTIFULBUF");
00172             rec.fStopTypes->GetXaxis()->SetBinLabel(1 + sp605::STOP_FIFOFULLMULTIHIT,   "MULTIFULFIFO");      ;
00173          }
00174 
00175          rec.fInfoTypes = MakeTH1('I', Form("%sInfoTypes_%u_%u", dfolder, brd, spid), Form("Distribution of info types for board %u spadic %u", brd, spid), 8, 0., 8.);
00176          if (IsObjMade()) {
00177             rec.fInfoTypes->GetXaxis()->SetBinLabel(1 + sp605::INFO_DIS, "DIS");
00178             rec.fInfoTypes->GetXaxis()->SetBinLabel(1 + sp605::INFO_NGT, "NGT");
00179             rec.fInfoTypes->GetXaxis()->SetBinLabel(1 + sp605::INFO_NRT, "NRT");
00180             rec.fInfoTypes->GetXaxis()->SetBinLabel(1 + sp605::INFO_NBE, "NBE");
00181             rec.fInfoTypes->GetXaxis()->SetBinLabel(1 + sp605::INFO_MSB, "MSB");
00182             rec.fInfoTypes->GetXaxis()->SetBinLabel(1 + sp605::INFO_NOP, "NOP");
00183             rec.fInfoTypes->GetXaxis()->SetBinLabel(1 + sp605::INFO_SYN, "SYN");
00184          }
00185 
00186          rec.fSpadic_overflows = MakeTH2('I', Form("%sOverflowMap_%u_%u", dfolder, brd, spid), Form("Map of overflow counts SP605 %u SPADIC %u", brd, spid), MAX_SPADICV10_GROUPS, 0, MAX_SPADICV10_GROUPS, MAX_SPADICV10CHANNELS, -0.5, MAX_SPADICV10CHANNELS-0.5, "group","Channel ID");
00187 
00188          rec.fSpadic_trace2D = MakeTH2('I', Form("%sTrace2D_%u_%u", dfolder, brd, spid), Form("Trace2D from BOARD %u SPADIC %u", brd, spid), SPADICV10_TRACE_SIZE, 0, SPADICV10_TRACE_SIZE, MAX_SPADICV10CHANNELS, -0.5, MAX_SPADICV10CHANNELS-0.5, "time (50 ns)","Channel ID");
00189          rec.fSpadic_trace2D->SetContour(99);
00190 
00191          rec.fTrigger_Chs = MakeTH1('I', Form("%sChannels_trigg_%u_%u", dfolder, brd, spid), Form("Channels from BOARD %u SPADIC %u", brd, spid), MAX_SPADICV10CHANNELS, 0., MAX_SPADICV10CHANNELS);
00192 
00193          for (int ch = 0; ch < MAX_SPADICV10CHANNELS; ch++) {
00194             char d2name[100], d2info[100];
00195             sprintf(d2name, "%sChannel%u/Brd%u_Sp%u_Ch%u", dfolder, ch, brd, spid, ch);
00196             sprintf(d2info, "SP605 %u SPADIC %u Channel %u", brd, spid, ch);
00197             // printf("Create histograms for channel %s\n", d2name);
00198 
00199             rec.fSpadic_trace[ch] = MakeTH1('I', Form("%strace", d2name),  Form("Trace  from %s", d2info), SPADICV10_TRACE_SIZE, 0, SPADICV10_TRACE_SIZE, "time (40ns)");
00200             rec.fSpadic_trace_clean[ch] = MakeTH1('I', Form("%strace_clean", d2name),  Form("Trace clean  from %s", d2info), SPADICV10_TRACE_SIZE, 0, SPADICV10_TRACE_SIZE, "time (40ns)");
00201             rec.fSpadic_ADCdist[ch] = MakeTH1('I', Form("%sADCdist", d2name),  Form("ADC value distribution from %s", d2info), SPADICV10_TRACE_SIZE, 0, SPADICV10_TRACE_SIZE, "time (40ns)");
00202          } // for Channels
00203       }  // for SPADICS
00204    } // for boards
00205 
00206 /*
00207 
00208    for (unsigned n=0; n<fNumSpadicV10s;n++) {
00209       SPADICV10[n].fIsEventComplete = kFALSE;
00210       SPADICV10[n].fHasNewData = kFALSE;
00211 
00212       // do not build histograms for non-used SPADICV10
00213       if (!AssertSpadicV10(n)) continue;
00214 
00215 
00216       SPADICV10[n].fTrigger_AUX = MakeTH1('I', Form("%sSpadicV10_%u_Trigger_AUX", folder, n), Form("Time difference between all AUXs and last trigger signal on SPADICV10%u", n), 5000, -5000., 5000.);
00217 
00218       SPADICV10[n].fAUXWind = MakeWinCond(Form("SpadicV10_%u_AUXWindow",n), -100., 100., SPADICV10[n].fTrigger_AUX->GetName());
00219 
00220 
00221 
00222 
00223 
00224          SPADICV10[n].fTrigger_Fronts[nx] = MakeTH1('I', Form("%sTrigger", nxfolder), Form("Time difference between hit and last trigger signal on %s", nxinfo), 2500, -1000., 4000.);
00225 
00226       } // for nx
00227 
00228    } //
00229 
00230 */
00231 
00232    ExecuteScript("set_SpadicV10Cond.C");
00233    
00234    ResetEndOfBuffer();
00235 }
00236 
00237 void TSpadicV10Proc::ProcessTriggerMessage(TSpadicV10Data* theSpadic, int brd_id, uint64_t fulltm)
00238 {
00239    fTriggersPerBoard->Fill(brd_id);
00240 
00241    if (!BRDS[brd_id].fHasNewTrigger) {
00242 
00243       //printf("Find trigger for roc %d\n",sid); cout << endl;
00244 
00245       BRDS[brd_id].fLastTriggerTm = fulltm;
00246       BRDS[brd_id].fHasNewTrigger = kTRUE;
00247       BRDS[brd_id].fTriggersPerBuffer++;
00248       if(theSpadic)
00249          theSpadic->fLastTriggerTm = fulltm;
00250    }
00251 
00252 #ifndef   SPADICV10_SINGLETRIGGERMODE
00253    if (brd_id == fParam->masterBoard) {
00254       fOutputEvent->fLastGlobalTriggerTm = fulltm;
00255       if (fParam->globalTrigger && !fHasNewGlobalTrigger) {
00256          fHasNewGlobalTrigger = kTRUE;
00257          if (!fFirstSubEvent) {
00258             TGo4Log::Error("Master trigger defined not in the first subevent - change SPADICV10 readout !!!");
00259             exit(1);
00260          }
00261          // JAM put here distribution of master trigger to slaves:
00262          //cout <<"TTTTTTTTTTTTTTTTTTT ProcessTriggerMessage as master"<<sid << endl;
00263 
00264          // FIXME: SL: it is only for the case when many trigger in buffer are defined, not necessary in normal config
00265          for (unsigned n = 0; n < numBoards(); n++) {
00266             if (!AssertBoard(n) || (n==(unsigned) brd_id)) continue;
00267 
00268             TSpadicV10Data* reventn = dynamic_cast<TSpadicV10Data*> (fOutputEvent->getEventElement(n));
00269             uint64_t triggertm(0);
00270             // TODO: reintroduce calibration coefficients
00271             if (BRDS[brd_id].fLastTriggerTm > BRDS[brd_id].fStartSyncTm)
00272                triggertm = BRDS[n].fStartSyncTm + (BRDS[brd_id].fLastTriggerTm - BRDS[brd_id].fStartSyncTm);
00273             else
00274                triggertm = BRDS[n].fStartSyncTm - (BRDS[brd_id].fStartSyncTm - BRDS[brd_id].fLastTriggerTm);
00275             //cout <<"TTTTTTTTTTTTTTTTTTT ProcessTriggerMessage distributes triggertime "<< triggertm<<" to roc "<<n << endl;
00276             ProcessTriggerMessage(reventn, n, triggertm);
00277          }
00278       }
00279    }
00280 #endif
00281 
00282 
00283    if (BRDS[brd_id].fHasNewTrigger) {
00284       // reprocess unprocessed messages already here, do not let them go back to unprocessed
00285       
00286       for (unsigned i=0; i<BRDS[brd_id].fUnprocessedMsg.size(); i++)
00287          ProcessExtendedMessage(brd_id, theSpadic, BRDS[brd_id].fUnprocessedMsg[i], false);
00288       
00289       BRDS[brd_id].fUnprocessedMsg.clear(); // is filled again from current event below
00290    }
00291 }
00292 
00293 
00294 void TSpadicV10Proc::InitEvent(TGo4EventElement* outevnt)
00295 {
00296    // since output event object is never discarded within processor lifetime,
00297    // we just search for subevent by name once to speed up processing
00298    if(fOutputEvent==0)
00299    {
00300       // test if we are in beamtime or standalone mode:
00301       TCBMBeamtimeEvent* btevent=dynamic_cast<TCBMBeamtimeEvent*>(outevnt);
00302       if(btevent)
00303       {
00304 
00305          fOutputEvent=dynamic_cast<TSpadicV10Event*>(btevent->GetSubEvent("SPADICV10"));
00306       }
00307       else
00308       {
00309 
00310          fOutputEvent= dynamic_cast<TSpadicV10Event*>(outevnt);
00311       }
00312       if(fOutputEvent==0)
00313       {
00314          GO4_STOP_ANALYSIS_MESSAGE("**** TSpadicV10Proc: Fatal error: output event is not a TSpadicV10Event!!! STOP GO4");
00315       }
00316    } // IF OUTPUTEVENT
00317 
00318    fFirstSubEvent = true;
00319 
00320    for (unsigned n=0;n<numBoards();n++) {
00321       BRDS[n].fStartSyncTm = 0;
00322       BRDS[n].fStopSyncTm = 0;
00323    }
00324 
00325 //   printf("Start event\n");
00326 }
00327 
00328 
00329 
00330 //-----------------------------------------------------------
00331 // event function
00332 void TSpadicV10Proc::ProcessSubevent(TGo4MbsSubEvent* psubevt)
00333 {
00334 //   uint32_t nxch(0), auxid(0), syncid(0);
00335 //   uint64_t fulltm(0);
00336 //   uint32_t typ(0), lastevsid(0);
00337 //   uint8_t stop(0), info(0), trig(0), lost(0);
00338 //   uint8_t fid(0), chipid(0);
00339    static int cnt=0;
00340    unsigned msgcount=0;
00341 
00342    //cout << "#################### ProcessSubevent Start" << endl;
00343    bool is_dabc_evt = (psubevt->GetProcid() == roc::proc_SpadicV10Event);
00344    bool is_raw_evt = (psubevt->GetProcid() == roc::proc_SpadicV10Raw);
00345 
00346    // printf("RAW %d DABC %d fullid 0x%x \n", is_raw_evt, is_dabc_evt, psubevt->GetFullId());
00347 
00348    if (!is_dabc_evt && !is_raw_evt) return;
00349 
00350    // fIsTimeSorted = (psubevt->GetPsid() == roc::proc_MergedEvent);
00351 
00352 #ifdef   SPADICV10_SINGLETRIGGERMODE
00353        fIsTimeSorted = kFALSE; // SL to avoid any mismatches, should be implemented anyway differently
00354 #else
00355      fIsTimeSorted=kTRUE; // JAM used for TEST!
00356 #endif
00357    if(cnt==0) {
00358        cout << "TTTTTTT fIsTimeSorted is: "<< fIsTimeSorted<< endl;
00359        cnt=1;
00360    }
00361 
00362 
00363    unsigned brd_id = psubevt->GetSubcrate(); // this is sp605 board id
00364    int msg_fmt = psubevt->GetControl();
00365 
00366    if (fParam->debugLevel>0)
00367       printf("SPADICV1 %s data BRD_ID:%u fmt:%d \n", (is_dabc_evt ? "DABC" : "RAW"), brd_id, msg_fmt);
00368 
00369    // printf("BRDID %u FORMAT %d\n", brd_id, msg_fmt);
00370 
00371    if (!AssertBoard(brd_id)) {
00372       printf("Cannot analyze data from board %u - skip\n",brd_id);
00373       return;
00374    }
00375 
00376    //fIter = SPADICV10[brd_id].fIter; // use separate iterators for each roc subevent
00377    //printf ("IIIIIIII Set iterator 0x%x for sid %d\n", (unsigned) &(SPADICV10[brd_id].fIter),brd_id);
00378 
00379 //
00380 //
00381 //   //     cout << "SpadicV10ID = " << (int) psubevt->GetSubcrate() << "  data kind = " << (int) psubevt->GetPsid() << endl;
00382 //
00383 //   fIter.setSpadicV10Number(psubevt->GetSubcrate());
00384 
00385    
00386 // BEGIN INITIAL EVENT PART
00387    if(!IsKeepInputEvent())
00388    {
00389       //cout << "#################### ProcessSubevent has new input event" << endl;
00390       int datasize = (psubevt->GetDlen() - 2) * 2;
00391 //      int msg_fmt = psubevt->GetControl();
00392 //      SPADICV10[brd_id].fIter.setFormat(msg_fmt);
00393 //      SPADICV10[brd_id].fIter.setSpadicV10Number(brd_id);
00394 
00395 
00396       // we can exclude messages (SYNC and may be EPOCH) which are added by DABC at the end of subevent
00397 
00398 
00399       if (is_dabc_evt) {
00400       
00401          // ignore all irrelevant events
00402          if (GetTriggerNumber()>7) return;
00403 
00404          // extract SYNC time directly in the loop
00405 
00406       } // isdabcevent
00407 
00408       fTotaldatasize += datasize;
00409 
00410       BRDS[brd_id].fIter.setFormat(msg_fmt);
00411 
00412       if (!BRDS[brd_id].fIter.assign(psubevt->GetDataField(), datasize)) return;
00413 
00414       //     cout << "nummsgs = " << datasize << "  len = " << datasize*6 << endl;
00415 
00416       fEvntSize->Fill(datasize);
00417 
00418       //cout << "AnlProc: found subevent subcrate="<<(int) psubevt->GetSubcrate()<<", psid="<<(int)psubevt->GetPsid()<<", control="<<(int) psubevt->GetControl()<< endl;
00419 
00420       } // if !IsKeepInputEvent
00421 // END INITIAL EVENT PART
00422 
00423    BRDS[brd_id].fLoopsPerBuffer++;
00424 
00425    TSpadicV10Data* theSpadic = 0;
00426    unsigned last_brd_id = 0;
00427 
00428    sp605::Message* data = & BRDS[brd_id].fIter.msg();
00429    roc::Message* rocmsg = & BRDS[brd_id].fIter.rocmsg();
00430 
00431 #ifdef   SPADICV10_SINGLETRIGGERMODE
00432     while (BRDS[brd_id].fIter.next()) {
00433 #else
00434      while (!(BRDS[brd_id].fIsEventComplete) && BRDS[brd_id].fIter.next()) {
00435       // JAM: only process messages if current event for this roc is not yet complete.
00436       // otherwise, we keep input buffer until we look for next event.
00437 #endif
00438       msgcount++;
00439       // sid=brd_id;
00440       // data->setSpadicNumber(brd_id); //
00441       //sid = data->getSpadicNumber();
00442 
00443       if (fParam->debugLevel>1)
00444          BRDS[brd_id].fIter.printMessage();
00445 
00446       fMsgsPerBoard->Fill(brd_id);
00447 
00448       BRDS[brd_id].fHasNewData = kTRUE;
00449 
00450       // SL: extract TSpadicV10Data from composite event only when it necessary
00451       // in 99% of cases board_id is not changing and we do not search and dynamic_cast again
00452       if ((theSpadic==0) || (last_brd_id!=brd_id)) {
00453          theSpadic = dynamic_cast<TSpadicV10Data*> (fOutputEvent->getEventElement(brd_id));
00454          last_brd_id = brd_id;
00455          if (fParam->noTrigger && fParam->doSorting && theSpadic) {
00456             // reprocess unprocessed messages already here, do not let them go back to unprocessed
00457             // do it only when sorting was requested, otherwise unprocessed should not exists at all
00458             for (unsigned i=0; i<BRDS[brd_id].fUnprocessedMsg.size(); i++)
00459                ProcessExtendedMessage(brd_id, theSpadic, BRDS[brd_id].fUnprocessedMsg[i], false);
00460             BRDS[brd_id].fUnprocessedMsg.clear(); // is filled again from current event below
00461          }
00462       }
00463 
00464       /*************************************/
00465 
00466       uint64_t fulltm = BRDS[brd_id].fIter.getMsgFullTime();
00467 
00468 
00469       if (BRDS[brd_id].fIter.isRocMsg()) {
00470          unsigned typ = rocmsg->getMessageType();
00471 
00472          BRDS[brd_id].fMsgCnt->Fill(0); // account black-box messages
00473 
00474          BRDS[brd_id].fMsgTypes->Fill(typ);
00475 
00476          switch (typ) {
00477             case roc::MSG_EPOCH: break;
00478             case roc::MSG_SYNC: {
00479 
00480                // if iterator reached buffer end, it is second SYNC which should not be accounted
00481                if (msgcount>2 && is_dabc_evt && BRDS[brd_id].fIter.at_the_end()) {
00482                   BRDS[brd_id].fStopSyncTm = fulltm;
00483                   continue;
00484                }
00485 
00486 
00487                unsigned syncid = rocmsg->getSyncChNum();
00488                if (syncid < MAX_SPADICV10_SYNC)  {
00489                   BRDS[brd_id].fLastSyncTm[syncid] = fulltm;
00490                   BRDS[brd_id].fLastSyncId[syncid] = rocmsg->getSyncData();
00491                   if (theSpadic)
00492                      theSpadic->fLastSyncTm[syncid] = fulltm;
00493                   uint64_t synctm = fulltm / 100000000L;
00494                   BRDS[brd_id].fSYNCt[syncid]->Fill((synctm % 10000) * 0.1);
00495                }
00496 
00497                if((msgcount==2) && is_dabc_evt) {
00498                   BRDS[brd_id].fStartSyncTm = fulltm;
00499                   BRDS[brd_id].fDabcSeparator = rocmsg->getSyncChNum()+10;
00500 
00501    #ifdef SPADICV10_SINGLETRIGGERMODE
00502                   unsigned master_id = fParam->masterBoard;
00503                   // try to reintroduce trigger message in local time
00504                   if (AssertBoard(master_id) && (master_id!=brd_id) && BRDS[master_id].fHasNewTrigger) {
00505 
00506                      uint64_t triggertm(0);
00507 
00508                      // TODO: introduce time calibration coefficients
00509                      if (BRDS[master_id].fLastTriggerTm > BRDS[master_id].fStartSyncTm)
00510                         triggertm = BRDS[brd_id].fStartSyncTm + (BRDS[master_id].fLastTriggerTm - BRDS[master_id].fStartSyncTm);
00511                      else
00512                         triggertm = BRDS[brd_id].fStartSyncTm - (BRDS[master_id].fStartSyncTm - BRDS[master_id].fLastTriggerTm);
00513 
00514                      ProcessTriggerMessage(theSpadic, brd_id, triggertm);
00515                   }
00516    #endif
00517                }
00518 
00519                if (fParam->triggerSignal == (int) (syncid + 10))
00520                   ProcessTriggerMessage(theSpadic, brd_id, fulltm);
00521 
00522                // SL: SYNC/AUX messages are excluded , probably should be reintroduced again
00523                //ProcessExtendedMessage(brd_id, theSpadic, exmess);
00524                break;
00525             }
00526 
00527             case roc::MSG_AUX: {
00528                unsigned auxid = rocmsg->getAuxChNum();
00529                BRDS[brd_id].fAUXch->Fill(auxid);
00530 
00531                if (auxid < MAX_SPADICV10_AUX) {
00532                   BRDS[brd_id].fLastAuxTm[auxid] = fulltm;
00533                   uint64_t auxtm = fulltm / 100000000L;
00534                   BRDS[brd_id].fAUXt[auxid]->Fill((auxtm % 10000) * 0.1);
00535                }
00536 
00537                if (fParam->triggerSignal == (int) auxid) {
00538                   ProcessTriggerMessage(theSpadic, brd_id, fulltm);
00539                   //if (sid==0) printf("AUX msg = %lu\n", fulltm);
00540                }
00541 
00542                // SL: SYNC/AUX messages are excluded , probably should be reintroduced again
00543                //ProcessExtendedMessage(brd_id, theSpadic, exmess);
00544                break;
00545             }
00546 
00547             case roc::MSG_SYS: {
00548                BRDS[brd_id].fSysTypes->Fill(rocmsg->getSysMesType());
00549                break;
00550             }
00551 
00552             default:
00553                printf("Unsupported ROC message kind %u\n", typ);
00554                break;
00555          }
00556 
00557          continue;
00558       }
00559 
00560 
00561       unsigned typ = data->getMsgType();
00562       //cout << "MSG- SPADICV10:"<<sid << ", typ:" <<typ<<", cnt:"<<msgcount<< endl;
00563       //data->printData(sp605::msg_print_Human | sp605::msg_print_Prefix);
00564 
00565       // data->printData();
00566 
00567       BRDS[brd_id].fMsgTypes->Fill(typ);
00568 
00569       unsigned sp_id = BRDS[brd_id].fIter.getSpadicId();
00570 
00571       BRDS[brd_id].fMsgCnt->Fill(sp_id+1); // account SPADIC messages
00572 
00573       if (!AssertSpadic(brd_id, sp_id)) continue;
00574 
00575       unsigned gr_id = data->getGroup();
00576 
00577       TSpadicV10Rec& rec = BRDS[brd_id].SPADICS[sp_id];
00578 
00579       rec.fMsgTypes->Fill(typ);
00580 
00581       TSpadicV10MessageExtended exmess(*data,fulltm);
00582       exmess.SetSpadicId(sp_id);
00583 
00584 // TODO: add baseline calibration?
00585 //      if (fParam->baselineCalibr && fParam->dynamicPedestal ) {
00586 //         Bool_t extTrigHit = kFALSE;
00587 //         if (typ == sp605::MSG_HIT) {
00588 //            if (fParam->ttriMode[sid][data->getNxNumber()]) {
00589 //               extTrigHit = kTRUE;
00590 //            }
00591 //         }
00592 //         if (extTrigHit) {
00593 //            fPedestals->ExtractExttrigStream(*data, fulltm);
00594 //         } else {
00595 //            fPedestals->ExtractAutocalibrStream(*data, fulltm);
00596 //         }
00597 //      }
00598 
00599       switch (typ)
00600       {
00601          case sp605::MSG_NOP:
00602             break;
00603 
00604          case sp605::MSG_HIT: {
00605             unsigned stop = data->getStopType();
00606             unsigned trig = data->getHitType();
00607             rec.fTrigTypes->Fill(trig);
00608             rec.fStopTypes->Fill(stop);
00609 
00610             unsigned ch_id = data->getChNum();
00611 
00612 #ifdef SPADICV10_DEBUG
00613             cout << "*** Found MSG_HIT- SPADICV10:"<<sid <<", group:"<<fid<<", chan:"<<nxch<< ", stop type:0x"<<std::hex <<stop;
00614             cout << ", hit type:0x"<<std::hex <<trig<<std::dec<< endl;
00615 #endif
00616             if (ch_id < MAX_SPADICV10CHANNELS) {
00617                // TODO - implement raw histograms of trace data in message payload here
00618                for (UInt_t bin = 0; bin < data->getTraceSize(); bin++) {
00619                   int16_t val = data->getTrace(bin);
00620                   rec.fSpadic_trace[ch_id]->SetBinContent(bin + 1, (int) val); // // // copy of original sampels, this spectra will be corrected
00621                   rec.fSpadic_trace2D->SetBinContent((int) bin + 1, (int) ch_id + 1, (int) val);
00622                   rec.fSpadic_ADCdist[ch_id]->Fill(val);
00623                }
00624                // TODO: add other things to to with the traces like in spadicv03 processor!
00625                // may do this in separate function call
00626 
00627 
00628                //
00629                // TODO: <put more sophisticated code for trace display END
00630                ProcessExtendedMessage(brd_id, theSpadic, exmess); // this will do the message time cut
00631             } else {
00632                GO4_STOP_ANALYSIS_MESSAGE(
00633                      "Data index out of range error - brd:0x%x channel:0x%x !! Check your setup.",
00634                      brd_id, ch_id);
00635             }
00636             break;
00637          }
00638 
00639          case sp605::MSG_OVERFLOW: {
00640 
00641             unsigned lost = data->getOverflowHits();
00642             unsigned ch_id = data->getChNum();
00643 
00644             rec.fSpadic_overflows->Fill(gr_id, ch_id, lost);
00645 #ifdef SPADICV10_DEBUG
00646             cout << "*** Found MSG_OVERFLOW- SPADICV10:"<< brd_id <<", group:"<<gr_id<<", chan:"<<ch_id<< ", lost hits:0x"<<std::hex <<lost<<std::dec<< endl;
00647 #endif
00648 
00649             //ProcessExtendedMessage(sid, theSpadic, exmess);
00650             break;
00651          }
00652 
00653          case sp605::MSG_EPOCH: {
00654             rec.fCurrEpoch = data->getEpoch();
00655 #ifdef SPADICV10_DEBUG
00656             cout << "*** Found MSG_EPOCH- SPADICV10:"<<sid << ", epoch:0x"<<std::hex <<data->getEpochNumber()<<std::dec<< endl;
00657 #endif
00658             ProcessExtendedMessage(brd_id, theSpadic, exmess); // used for closing condition of event
00659 
00660             break;
00661          }
00662 
00663          case sp605::MSG_INFO: {
00664 
00665             unsigned info = data->getInfoType();
00666 
00667             rec.fInfoTypes->Fill(info);
00668 #ifdef SPADICV10_DEBUG
00669             cout << "*** Found INFO- SPADICV10:"<<sid << ", info:0x"<<std::hex <<typ<<std::dec<<", chan:"<<nxch<< endl;
00670 #endif
00671             if(info==sp605::INFO_SYN)
00672                {
00673                   uint8_t ep = data->getInfoEpoch();
00674                   std::cout << "  !!! Out of Sync at epoch:0x" << std::hex<< ep << std::dec << std::endl;
00675                }
00676 
00677             //ProcessExtendedMessage(sid, theSpadic, exmess); // no timestamp
00678             break;
00679          }
00680 
00681       /*************************************/      
00682       } // switch
00683 
00684       // in strict timesorting mode, we may find end of event before processing whole
00685       // input buffer:
00686       if(fIsTimeSorted)
00687       {
00688          if(BRDS[brd_id].fIsEventComplete)
00689             {
00690                //cout <<"STRICT Timesorting mode finds complete event for sid:"<< brd_id <<endl;//<<", keep mbs input!" << endl;
00691                break; // do not stop processing this buffer until we have next trigger!
00692             }
00693       }
00694    } // while
00695 
00696    if (fParam->debugLevel>0)
00697      printf("SPADICV10Proc process %d messages\n", msgcount);
00698 
00699    if(fIsTimeSorted) {
00700          // check after loop if we are already at the end of container:
00701       if(BRDS[brd_id].fIter.at_the_end()) {
00702                //cout <<"STRICT Timesorting mode is at the end of container for sid:"<< brd_id <<". Set EOB!" << endl;
00703              #if __GO4BUILDVERSION__ > 40500
00704                BRDS[brd_id].fHasEndOfBuffer=kTRUE;
00705              #endif
00706             }
00707       }
00708    //  cout << "Stop processing" << endl;
00709 
00710    fFirstSubEvent = kFALSE;
00711 }
00712 
00713 
00714 
00715 void TSpadicV10Proc::FinalizeEvent()
00716 {
00717 //   static unsigned count=0;
00718 //   static unsigned bcount=0;
00719    fOutputEvent->fMbsEventNumber = GetEventNumber();
00720    // now we should decide if event should be delivered to the output
00721    // either all used SPADICV10s are ready with their events or sync is used as trigger
00722 
00723    bool allEventComplete(true), isAnyData(false), isAllSyncSepar(true), allInputsComplete(true);
00724 
00725    if ((fAUX2_R01!=0) && AssertBoard(0) && AssertBoard(1) &&
00726        (BRDS[0].fLastAuxTm[2] > BRDS[0].fStartSyncTm) &&
00727        (BRDS[1].fLastAuxTm[2] > BRDS[1].fStartSyncTm)) {
00728       int diff0 = BRDS[0].fLastAuxTm[2] - BRDS[0].fStartSyncTm;
00729       int diff1 = BRDS[1].fLastAuxTm[2] - BRDS[0].fStartSyncTm;
00730 
00731       fAUX2_R01->Fill(diff0-diff1);
00732 
00733 //      printf ("%5d   %5d %5d\n", diff0-diff1, diff0, diff1);
00734    }
00735 
00736    if (fSYNC1_R01 && AssertBoard(0) && AssertBoard(1)) {
00737       double diff = BRDS[1].fLastSyncTm[1] - BRDS[0].fLastSyncTm[1];
00738       double iddiff = 0. + BRDS[1].fLastSyncId[1] - BRDS[0].fLastSyncId[1];
00739       if (iddiff != 0) printf("iddiff = %5.0f\n", iddiff);
00740       fSYNC1_R01->Fill(diff);
00741    }
00742 
00743    for (unsigned r=0; r<numBoards();r++) {
00744       if (!AssertBoard(r)) continue;
00745       TSpadicV10Data* theSpadicV10 = dynamic_cast<TSpadicV10Data*>(fOutputEvent->getEventElement(r));
00746       if(theSpadicV10==0) continue;
00747       
00748 #ifdef SPADICV10_SINGLETRIGGERMODE
00749       // protection against producing too large history in unprocessed messages in case when AUX used as trigger
00750       // WORKAROUND - should be done more correctly
00751        if ((fParam->triggerSignal>=0) && (fParam->triggerSignal<10))
00752           BRDS[r].fUnprocessedMsg.clear();
00753 #endif
00754 
00755      if( theSpadicV10->fExtMessages.size() > 0)
00756          isAnyData = true;
00757       /*************************************/
00758 
00759 
00760 #ifdef SPADICV10_SINGLETRIGGERMODE
00761       if (!BRDS[r].fIsEventComplete && BRDS[r].fHasNewTrigger && (BRDS[r].fStopSyncTm > BRDS[r].fStartSyncTm) &&
00762             (BRDS[r].fStopSyncTm > BRDS[r].fLastTriggerTm)) {
00763          double diff = BRDS[r].fStopSyncTm - BRDS[r].fLastTriggerTm;
00764 
00765          TGo4WinCond* cond = fParam->globalTrigger ? fGlobalTriggerWind : BRDS[r].fTriggerWind;
00766 
00767          double rightdist = diff - cond->GetXUp();
00768          
00769          //printf ("SPADICV10%d rightdist %5.1f\n", r, rightdist);
00770          // if hit far away on right side, event can be close for this SPADICV10
00771          if (rightdist > 5000.) BRDS[r].fIsEventComplete = kTRUE;
00772       }
00773 #endif
00774       // we only care about incomplete event if any data at all seen by the SPADICV10!
00775       if(!BRDS[r].fIsEventComplete && BRDS[r].fHasNewData) allEventComplete = false;
00776       if (BRDS[r].fDabcSeparator != fParam->triggerSignal) isAllSyncSepar = false;
00777 
00778       //printf("SPADICV10%d event complete = %d\n", r, SPADICV10[r].fIsEventComplete);
00779 
00780       if( (!BRDS[r].fHasEndOfBuffer)
00781             && (BRDS[r].fTriggersPerBuffer<=fParam->maxBufferTriggers)
00782             && (BRDS[r].fLoopsPerBuffer<=fParam->maxBufferLoops))
00783          {
00784             allInputsComplete = false;
00785          }
00786 
00787 
00788       //printf("SPADICV10%d buffer complete = %d\n", r, SPADICV10[r].fHasEndOfBuffer);
00789 
00790 //      if (SPADICV10[r].fTriggersPerBuffer > fParam->maxBufferTriggers) {
00791 //         printf("SPADICV10%d # of triggers %d per buffer exceeds %d \n", r,
00792 //               SPADICV10[r].fTriggersPerBuffer, (int) fParam->maxBufferTriggers);
00793 //         cout << endl;
00794 //      }
00795 //      if (SPADICV10[r].fLoopsPerBuffer > fParam->maxBufferLoops) {
00796 //         printf("SPADICV10%d # of loops %d per buffer exceeds %d\n", r,
00797 //               SPADICV10[r].fLoopsPerBuffer, (int) fParam->maxBufferLoops);
00798 //         cout << endl;
00799 //      }
00800 
00801    } // for r
00802 
00803    if (fParam->noTrigger && isAnyData) allEventComplete = true;
00804    if (isAllSyncSepar) allEventComplete = true;
00805 
00806 
00807 
00808    if (allEventComplete) {
00809      
00810       //printf("!!!!!!!!! Event %d is complete !!!!!!!!!\n",count++);
00811 
00812       for (unsigned r=0; r<numBoards(); r++) {
00813          TSpadicV10Data* theSpadicV10 = dynamic_cast<TSpadicV10Data*>(fOutputEvent->getEventElement(r));
00814          if(theSpadicV10==0) continue;
00815 
00816          if (fParam->doSorting)
00817          {
00818             std::sort(theSpadicV10->fExtMessages.begin(), theSpadicV10->fExtMessages.end());
00819          }
00820 
00821          BRDS[r].fEvntMultipl->Fill(theSpadicV10->fExtMessages.size());
00822 
00823          theSpadicV10->SetValid(kTRUE);
00824 
00825 /*
00826          unsigned sz = theSpadicV10->fExtMessages.size();
00827          printf("SPADICV10%d has %u messages\n", sid, sz);
00828          for (unsigned n=0;n<sz;n++) {
00829             printf("  Msg %3u fulltime:%10llu ", n, theSpadicV10->fExtMessages[n].GetFullTime());
00830             theSpadicV10->fExtMessages[n].GetSpadicV10Message().printData();
00831 
00832             static uint64_t lasttm = 0;
00833             if (lasttm > theSpadicV10->fExtMessages[n].GetFullTime()) {
00834                printf ("!!!!!!!!!!!! error with sorting !!!!!!!!!!!!");
00835                exit(5);
00836             }
00837             lasttm = theSpadicV10->fExtMessages[n].GetFullTime();
00838          }
00839 */
00840       }
00841 
00842       fOutputEvent->SetValid(kTRUE);
00843 
00844       ResetTrigger();
00845 
00846    } else {
00847       fOutputEvent->SetValid(kFALSE);
00848    }
00849 
00850 
00851 
00852    // was triggered by parameter update
00853 //   if(fParam->storePedestalFile && (fParam->pedSaveToFile.Length()>0))  {
00854 //      fParam->storePedestalFile = kFALSE;
00855 //      if(fPedestals) fPedestals->SaveToFile( fParam->pedSaveToFile.Data());
00856 //   }
00857 
00858    if(GetTriggerNumber()==8)
00859    {
00860           //ignore pulser events in spill pause for the moment
00861           fOutputEvent->SetValid(kFALSE);
00862    }
00863 
00864    // Decide if we need to keep input event or request next one when all buffers are done:
00865 
00866    if(fIsTimeSorted)
00867         {
00868             if(allInputsComplete)
00869             {
00870                    //cout <<"STRICT Timesorting mode finds all input buffers processed. Get new mbs input "<<bcount++ << endl;
00871 #if __GO4BUILDVERSION__ > 40500
00872                    SetKeepInputEvent(kFALSE); // request new mbs container
00873 #endif
00874                    ResetEndOfBuffer();
00875             }
00876 
00877 
00878 // JAM: this one will throw away almost everything...
00879 //            else if (anyInputComplete && !allEventComplete)
00880 //            {
00881 //               cout <<"STRICT Timesorting mode finds some input buffer at the end, but not all events complete. Discard rest of buffers and  get new mbs input "<< bcount++<< endl;
00882 //#if __GO4BUILDVERSION__ > 40500
00883 //               SetKeepInputEvent(kFALSE); // request new mbs container
00884 //#endif
00885 //               ResetEndOfBuffer();
00886 //            }
00887 
00888             else
00889             {
00890 #if __GO4BUILDVERSION__ > 40500
00891                    //cout <<"STRICT Timesorting mode sets KEEP mbs input!" << endl;
00892                    SetKeepInputEvent(kTRUE);  // unless we have processed buffers of all rocs completely, we keep input
00893 #endif
00894             }
00895 
00896         }
00897 
00898 
00899 
00900    // calculation of the rate:
00901      double tm = TTimeStamp().AsDouble();
00902      double diff = tm - fLastRateTm;
00903      if (diff>1.) {
00904         double rate = fTotaldatasize / diff;
00905         if (fRate==0.) fRate = rate;
00906         fRate = fRate * 0.9 + rate * 0.1;
00907         fEvntSize->SetTitle(Form("RATE %5.1f KB/s", fRate/1024.));
00908         fTotaldatasize = 0;
00909         fLastRateTm = tm;
00910      }
00911 
00912 
00913     //printf(" =============== TSpadicV10Proc::FinalizeEvent ===================\n ");
00914 }
00915 
00916 
00917 void TSpadicV10Proc::ProcessExtendedMessage(unsigned brd_id, TSpadicV10Data* theSpadic, TSpadicV10MessageExtended& exmsg, bool with_unprocessed)
00918 {
00919    bool isinside(false), add_to_unprocessed(false), add_to_event(false);
00920 
00921    double diff = 0;
00922 
00923    if (BRDS[brd_id].fLastTriggerTm!=0) {
00924       if(exmsg.GetFullTime() >= BRDS[brd_id].fLastTriggerTm)
00925          diff = exmsg.GetFullTime() - BRDS[brd_id].fLastTriggerTm;
00926       else
00927          diff = -1.0 * (BRDS[brd_id].fLastTriggerTm - exmsg.GetFullTime());
00928 
00929    //if(with_unprocessed) cout << "       dt="<<diff<< endl;
00930    }
00931 
00932    if (fParam->noTrigger) {
00933 
00934       // JAM: for the moment, we can only handle untriggered mode. Take all input messagesas is
00935       add_to_event = true;
00936 
00937       // to avoid situation when sorting over buffer boundary should be done,
00938       // only messages which are far away from last sync message, will be accepted into output event
00939 //      if (!fParam->doSorting || (SPADICV10[sid].fStopSyncTm==0)) {
00940 //         add_to_event = true;
00941 //      } else {
00942 //         if (exmsg.GetFullTime() + 16000 < SPADICV10[sid].fStopSyncTm)
00943 //            add_to_event = true;
00944 //         else
00945 //            add_to_unprocessed = true;
00946 //      }
00947    } else
00948    if (BRDS[brd_id].fHasNewTrigger) {
00949 
00950       TGo4WinCond* cond = fParam->globalTrigger ? fGlobalTriggerWind : BRDS[brd_id].fTriggerWind;
00951 
00952 //      if(exmsg.GetMessageType() == sp605::MSG_AUX)
00953 //         cond = fParam->globalTrigger ? fGlobalAUXWind : SPADICV10[sid].fAUXWind;
00954 
00955       exmsg.SetTriggerDeltaT(diff);
00956 
00957       if (cond->Test(diff)) {
00958          add_to_event = true;
00959          isinside = true;
00960       } else {
00961          double rightdist = diff - cond->GetXUp();
00962          if(fIsTimeSorted)
00963             {
00964                // we assume that message stream was strictly time sorted by dabc/ or go4 lmd user source JAM
00965                if (rightdist>0.) {
00966                   BRDS[brd_id].fIsEventComplete = kTRUE;
00967                   //SPADICV10[sid].fHasNewTrigger= kFALSE; // everything after us is buffered until next trigger is found
00968                   add_to_unprocessed = kTRUE; // keep this message for next event.
00969                   //cout <<"STRICT Timesorting mode marks complete event for roc:"<<sid<<" at dt="<<rightdist << endl;
00970                }
00971             }
00972          else
00973             {
00974          //BEGIN NOT STRICTLY SORTED, 1 EVENT PER MBS CONTAINER, for fast online monitoring  JAM
00975                   // if hit far away on right side, event can be close for this SPADICV10
00976                   if (rightdist > 5000.) BRDS[brd_id].fIsEventComplete = kTRUE;
00977                   if (rightdist>0.) {
00978                      if (BRDS[brd_id].fStopSyncTm==0) {
00979                         add_to_unprocessed = true;
00980                      } else {
00981                         double diff2 = 0;
00982                         if(exmsg.GetFullTime() >= BRDS[brd_id].fStopSyncTm)
00983                            diff2 = exmsg.GetFullTime() - BRDS[brd_id].fStopSyncTm;
00984                         else
00985                            diff2 = -1.0 * (BRDS[brd_id].fStopSyncTm - exmsg.GetFullTime());
00986 
00987                         // only keep message if it have chance to go into next event
00988                         add_to_unprocessed = diff2 >= cond->GetXLow();
00989 
00990                         // if (add_to_unprocessed && (sid==0)) printf("diff2 = %7.1f\n", diff2);
00991                      }
00992                   }
00993          // END NOT STRICTLY
00994             } //if(fIsTimeSorted)
00995       } // if (cond->Test(diff))
00996    } // if (SPADICV10[sid].fHasNewTrigger)
00997    else 
00998    {
00999      // if no new trigger was found up to now, we need to add message to unprocessed
01000      // at the end of the message we should check if unprocessed messages are still interesting
01001      add_to_unprocessed = true;
01002    }
01003 
01004    if(isinside && (exmsg.GetMessageType() == sp605::MSG_HIT)) { // but we put only nx hist to local histograms...
01005       unsigned sp_id = exmsg.GetSpadicId();
01006       unsigned ch_id = exmsg.GetFullChNum();
01007       BRDS[brd_id].SPADICS[sp_id].fTrigger_Chs->Fill(ch_id);
01008    }
01009 
01010     if((exmsg.GetMessageType() == sp605::MSG_HIT) && (diff!=0)) {
01011      // if (sid==0) printf("Diff = %9.1f\n", diff);
01012       fDeltaTriggerTime->Fill(diff);
01013       BRDS[brd_id].fTrigger->Fill(diff);
01014       BRDS[brd_id].fTrigger_100->Fill(diff);
01015    }
01016 
01017 //   if(exmsg.GetMessageType() == sp605::MSG_AUX) {
01018 //      SPADICV10[sid].fTrigger_AUX->Fill(diff);
01019 //   }
01020 
01021 
01022    if(exmsg.GetMessageType() == sp605::MSG_EPOCH)
01023    {
01024       // we use epoch messages to finish event time window, but do not want it stored.
01025       add_to_unprocessed=kFALSE;
01026       add_to_event=kFALSE;
01027    }
01028 
01029    if (theSpadic && add_to_event)
01030       theSpadic->fExtMessages.push_back(exmsg);
01031 
01032    if (add_to_unprocessed && with_unprocessed)
01033       BRDS[brd_id].fUnprocessedMsg.push_back(exmsg);
01034 }
01035 
01036 void TSpadicV10Proc::ResetTrigger()
01037 {
01038    //cout <<"RRRRRRRRRRRR ResetTrigger" << endl;
01039    fHasNewGlobalTrigger = kFALSE;
01040    for (unsigned n=0; n<numBoards();n++) {
01041       BRDS[n].fIsEventComplete = kFALSE;
01042       if (BRDS[n].fHasEndOfBuffer) BRDS[n].fHasNewData = kFALSE;
01043       BRDS[n].fHasNewTrigger = kFALSE;
01044 // SL: we keep last trigger time for histogramm filling
01045 //      SPADICV10[n].fLastTriggerTm = 0;
01046       BRDS[n].fDabcSeparator = -1;
01047    }
01048 }
01049 
01050 
01051 void TSpadicV10Proc::ResetEndOfBuffer()
01052 {
01053    //cout <<"RRRRRRRRRRRR ResetEndOfBuffer:" << endl;
01054    for (unsigned n=0; n<numBoards();n++) {
01055       //cout <<" SpadicV10"<<n<<" triggers:"<<  SPADICV10[n].fTriggersPerBuffer <<", loops:"<<SPADICV10[n].fLoopsPerBuffer<< endl;
01056       BRDS[n].fTriggersPerBuffer=0;
01057       BRDS[n].fLoopsPerBuffer=0;
01058       BRDS[n].fHasEndOfBuffer = kFALSE;
01059    }
01060 }
01061 
01062 

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