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
00019 #include "sp605/Board.h"
00020
00021 #include <algorithm>
00022
00023
00024
00025 #define SPADICV10_SINGLETRIGGERMODE 1
00026
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
00043
00044
00045
00046
00047
00048
00049
00050
00051 }
00052
00053
00054
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
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
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 }
00203 }
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
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
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
00262
00263
00264
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
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
00276 ProcessTriggerMessage(reventn, n, triggertm);
00277 }
00278 }
00279 }
00280 #endif
00281
00282
00283 if (BRDS[brd_id].fHasNewTrigger) {
00284
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();
00290 }
00291 }
00292
00293
00294 void TSpadicV10Proc::InitEvent(TGo4EventElement* outevnt)
00295 {
00296
00297
00298 if(fOutputEvent==0)
00299 {
00300
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 }
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
00326 }
00327
00328
00329
00330
00331
00332 void TSpadicV10Proc::ProcessSubevent(TGo4MbsSubEvent* psubevt)
00333 {
00334
00335
00336
00337
00338
00339 static int cnt=0;
00340 unsigned msgcount=0;
00341
00342
00343 bool is_dabc_evt = (psubevt->GetProcid() == roc::proc_SpadicV10Event);
00344 bool is_raw_evt = (psubevt->GetProcid() == roc::proc_SpadicV10Raw);
00345
00346
00347
00348 if (!is_dabc_evt && !is_raw_evt) return;
00349
00350
00351
00352 #ifdef SPADICV10_SINGLETRIGGERMODE
00353 fIsTimeSorted = kFALSE;
00354 #else
00355 fIsTimeSorted=kTRUE;
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();
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
00370
00371 if (!AssertBoard(brd_id)) {
00372 printf("Cannot analyze data from board %u - skip\n",brd_id);
00373 return;
00374 }
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 if(!IsKeepInputEvent())
00388 {
00389
00390 int datasize = (psubevt->GetDlen() - 2) * 2;
00391
00392
00393
00394
00395
00396
00397
00398
00399 if (is_dabc_evt) {
00400
00401
00402 if (GetTriggerNumber()>7) return;
00403
00404
00405
00406 }
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
00415
00416 fEvntSize->Fill(datasize);
00417
00418
00419
00420 }
00421
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
00436
00437 #endif
00438 msgcount++;
00439
00440
00441
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
00451
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
00457
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();
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);
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
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
00504 if (AssertBoard(master_id) && (master_id!=brd_id) && BRDS[master_id].fHasNewTrigger) {
00505
00506 uint64_t triggertm(0);
00507
00508
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
00523
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
00540 }
00541
00542
00543
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
00563
00564
00565
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);
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
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
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
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);
00621 rec.fSpadic_trace2D->SetBinContent((int) bin + 1, (int) ch_id + 1, (int) val);
00622 rec.fSpadic_ADCdist[ch_id]->Fill(val);
00623 }
00624
00625
00626
00627
00628
00629
00630 ProcessExtendedMessage(brd_id, theSpadic, exmess);
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
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);
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
00678 break;
00679 }
00680
00681
00682 }
00683
00684
00685
00686 if(fIsTimeSorted)
00687 {
00688 if(BRDS[brd_id].fIsEventComplete)
00689 {
00690
00691 break;
00692 }
00693 }
00694 }
00695
00696 if (fParam->debugLevel>0)
00697 printf("SPADICV10Proc process %d messages\n", msgcount);
00698
00699 if(fIsTimeSorted) {
00700
00701 if(BRDS[brd_id].fIter.at_the_end()) {
00702
00703 #if __GO4BUILDVERSION__ > 40500
00704 BRDS[brd_id].fHasEndOfBuffer=kTRUE;
00705 #endif
00706 }
00707 }
00708
00709
00710 fFirstSubEvent = kFALSE;
00711 }
00712
00713
00714
00715 void TSpadicV10Proc::FinalizeEvent()
00716 {
00717
00718
00719 fOutputEvent->fMbsEventNumber = GetEventNumber();
00720
00721
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
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
00750
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
00770
00771 if (rightdist > 5000.) BRDS[r].fIsEventComplete = kTRUE;
00772 }
00773 #endif
00774
00775 if(!BRDS[r].fIsEventComplete && BRDS[r].fHasNewData) allEventComplete = false;
00776 if (BRDS[r].fDabcSeparator != fParam->triggerSignal) isAllSyncSepar = false;
00777
00778
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
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801 }
00802
00803 if (fParam->noTrigger && isAnyData) allEventComplete = true;
00804 if (isAllSyncSepar) allEventComplete = true;
00805
00806
00807
00808 if (allEventComplete) {
00809
00810
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
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 }
00841
00842 fOutputEvent->SetValid(kTRUE);
00843
00844 ResetTrigger();
00845
00846 } else {
00847 fOutputEvent->SetValid(kFALSE);
00848 }
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858 if(GetTriggerNumber()==8)
00859 {
00860
00861 fOutputEvent->SetValid(kFALSE);
00862 }
00863
00864
00865
00866 if(fIsTimeSorted)
00867 {
00868 if(allInputsComplete)
00869 {
00870
00871 #if __GO4BUILDVERSION__ > 40500
00872 SetKeepInputEvent(kFALSE);
00873 #endif
00874 ResetEndOfBuffer();
00875 }
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888 else
00889 {
00890 #if __GO4BUILDVERSION__ > 40500
00891
00892 SetKeepInputEvent(kTRUE);
00893 #endif
00894 }
00895
00896 }
00897
00898
00899
00900
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
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
00930 }
00931
00932 if (fParam->noTrigger) {
00933
00934
00935 add_to_event = true;
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947 } else
00948 if (BRDS[brd_id].fHasNewTrigger) {
00949
00950 TGo4WinCond* cond = fParam->globalTrigger ? fGlobalTriggerWind : BRDS[brd_id].fTriggerWind;
00951
00952
00953
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
00965 if (rightdist>0.) {
00966 BRDS[brd_id].fIsEventComplete = kTRUE;
00967
00968 add_to_unprocessed = kTRUE;
00969
00970 }
00971 }
00972 else
00973 {
00974
00975
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
00988 add_to_unprocessed = diff2 >= cond->GetXLow();
00989
00990
00991 }
00992 }
00993
00994 }
00995 }
00996 }
00997 else
00998 {
00999
01000
01001 add_to_unprocessed = true;
01002 }
01003
01004 if(isinside && (exmsg.GetMessageType() == sp605::MSG_HIT)) {
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
01012 fDeltaTriggerTime->Fill(diff);
01013 BRDS[brd_id].fTrigger->Fill(diff);
01014 BRDS[brd_id].fTrigger_100->Fill(diff);
01015 }
01016
01017
01018
01019
01020
01021
01022 if(exmsg.GetMessageType() == sp605::MSG_EPOCH)
01023 {
01024
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
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
01045
01046 BRDS[n].fDabcSeparator = -1;
01047 }
01048 }
01049
01050
01051 void TSpadicV10Proc::ResetEndOfBuffer()
01052 {
01053
01054 for (unsigned n=0; n<numBoards();n++) {
01055
01056 BRDS[n].fTriggersPerBuffer=0;
01057 BRDS[n].fLoopsPerBuffer=0;
01058 BRDS[n].fHasEndOfBuffer = kFALSE;
01059 }
01060 }
01061
01062