// ----------------------------------------------------------------------------- // ----- TTrbUnpackTof source file ----- // ----- ----- // ----- created by C. Simon on 2014-03-08 ----- // ----- ----- // ----- based on TMbsUnpackTof by P.-A. Loizeau ----- // ----- https://subversion.gsi.de/fairroot/cbmroot/development/ploizeau/ ----- // ----- main/unpack/tof/TMbsUnpackTof.cxx ----- // ----- revision 21787, 2013-09-20 ----- // ----------------------------------------------------------------------------- #include "TTrbUnpackTof.h" // Parameter header #include "TMbsUnpackTofPar.h" #include "TofDef.h" #include "TofTrbTdcDef.h" #include "TTrbHeader.h" // Iterator #include "HadaqTrbIterator.h" // Subunpacker header #include "TTofTrbTdcUnpacker.h" // Output object #include "TTofTrbTdcBoard.h" // ROOT headers #include "TClonesArray.h" #include "TROOT.h" #include "TH1.h" #include "TH2.h" #include "TMath.h" // FairRoot headers #include "FairRunOnline.h" #include "FairLogger.h" #include "FairRuntimeDb.h" ClassImp(TTrbUnpackTof) TTrbUnpackTof::TTrbUnpackTof( Short_t type, Short_t subType, Short_t procId, Short_t subCrate, Short_t control) : FairUnpack( type, subType, procId, subCrate, control), fMbsUnpackPar(0), fMbsCalibPar(0), fiNbEvents(0), fiCurrentEventNumber(0), fiPreviousEventNumber(0), fbFineSpillTiming(kTRUE), fbInspection(kFALSE), fTrbIterator(NULL), fTrbTdcUnpacker(NULL), fTrbTdcBoardCollection(NULL), fbSaveRawTdcBoards(kFALSE), fTdcUnpackMap(), fuInDataTrbSebNb(0), fuActiveTrbTdcNb(0), fTrbTriggerPattern(NULL), fTrbTriggerType(NULL), fCtsBusyTime(NULL), fCtsIdleTime(NULL), fCtsIdleTimeSpill(NULL), fCtsSpillLength(NULL), fCtsTriggerDistance(NULL), fItcAssertions(NULL), fItcEvents(NULL), fHadaqEventTime(NULL), fTrbEventNumberJump(NULL), fCtsTriggerCycles(NULL), fCtsTriggerAccepted(NULL), fHadaqEventsRecorded(NULL), fHadaqTimeInSpill(NULL), fCtsTimeInSpill(NULL), fEventSkipsInSpill(NULL), fTrbHeader(NULL), fTrbSubeventSize(), fTrbSubeventStatus(), fTrbTdcWords(), fTrbTdcProcessStatus(), fuTrigChanEdgeCounter(new UInt_t[16]), fuTrigChanClockCounter(new UInt_t[16]), fuTrigInputEdgeCounter(new UInt_t[16]), fuTrigInputClockCounter(new UInt_t[16]), fiAllPossibleTriggers(0), fiAcceptedTriggers(0), fliAllPossibleTriggersOverflows(0), fliAcceptedTriggersOverflows(0), fiHadaqLastEventTime(0), fiHadaqFirstEventTime(0), fiHadaqSpillStartTime(0), fiHadaqCoarseSpillStartTime(0), fiCtsLastEventTime(0), fiCtsFirstEventTime(0), fbNextSpillToStart(kFALSE), fbHadaqBufferDelay(kFALSE) { LOG(INFO)<<"**** TTrbUnpackTof: Call TTrbUnpackTof()..."<nextEvent(); LOG(DEBUG2)<<"First word in memory: "<tuSize)<tuDecoding)<tuId)<evtSeqNr)<evtDate)<evtTime)<evtRunNr)<evtPad)<GetSeqNr()<GetDataError() ) { LOG(WARNING)<<"Error bit set in at least one HADAQ raw subevent!"<GetTrigType(); if( !fTrbTdcUnpacker ) { LOG(ERROR)<<"TTrbUnpackTof not properly initialized! Cannot unpack any events."<SetCalibTrigger(uTriggerType); LOG(DEBUG)<GetSize()<<" B"<GetDecoding())<GetId())<GetSeqNr()<GetDate()>>16), 1+((tCurrentEvent->GetDate()&0xff00)>>8), ((tCurrentEvent->GetDate()&0xff)) )<GetTime()>>16), ((tCurrentEvent->GetTime()&0xff00)>>8), ((tCurrentEvent->GetTime()&0xff)) )<GetRunNr()<GetPaddedSize()-tCurrentEvent->GetSize() <<" B"<GetPaddedSize() ) { // LOG(WARNING)<GetPaddedSize(), uNb1ByteWords, (Float_t)(tCurrentEvent->GetPaddedSize())/(Float_t)uNb1ByteWords, size ) <nextSubevent() ) { LOG(DEBUG)<<"Getting HADAQ raw subevent in HADAQ raw event..."<currSubevent(); UInt_t uSubeventId = tCurrentSubevent->GetId() & 0xffff; uNbSubevents++; Bool_t bKnownSubevent = ( -1 < fMbsUnpackPar->GetTrbSebIndex( uSubeventId ) ); UInt_t uNbRegisteredFpgas = 0; UInt_t uNbActiveFpgas = 0; if( bKnownSubevent ) { uNbRegisteredFpgas = fMbsUnpackPar->GetInDataFpgaNbPerTrbSeb( uSubeventId ); uNbActiveFpgas = fMbsUnpackPar->GetActiveTdcNbPerTrbSep( uSubeventId ); fTrbSubeventSize[ fMbsUnpackPar->GetTrbSebIndex( uSubeventId ) ]->Fill( tCurrentSubevent->GetSize()/1000 ); } DataErrorHandling(uSubeventId, tCurrentSubevent->GetErrBits()); if( tCurrentSubevent->GetDataError() || (tCurrentSubevent->GetErrBits() != 0x00000001) ) { LOG(ERROR)<GetSize()<<" B"<GetDecoding())<GetTrigNr()>>8)<GetTrigType())<GetTrigNr()&0xff)<GetPaddedSize()-tCurrentSubevent->GetSize() <<" B"<GetNrOfDataWords(); if( 0 == uNbSubsubeventDataWords ) { LOG(WARNING)<Data(uSubsubeventDataIndex); uSubsubeventSource = uSubsubeventData & 0xffff; UInt_t uSubsubeventLength = (uSubsubeventData >> 16) & 0xffff; Bool_t bKnownSubsubevent = fMbsUnpackPar->IsTrbFpgaInData(uSubsubeventSource); UInt_t uMotherBoardId = 0xffff; Bool_t bUnpack = kFALSE; if( bKnownSubsubevent ) { uMotherBoardId = fMbsUnpackPar->GetTrbSebAddrForFpga(uSubsubeventSource); bUnpack = ( -1 < fMbsUnpackPar->GetActiveTrbTdcIndex(uSubsubeventSource) ); } LOG(DEBUG)<>12) ) { uNbSubsubevents++; LOG(DEBUG)<<"====================================="<Data(uSubsubeventDataIndex+1)>>16)&0xff)<IsLogNeeded(DEBUG2)) { for(UInt_t uWord = uSubsubeventDataIndex; uWord <= uSubsubeventDataIndex+uSubsubeventLength; uWord++) { LOG(DEBUG2)<Data(uWord))<GetActiveTrbTdcIndex( uSubsubeventSource ); fTdcUnpackMap[iActiveTdcIndex] = std::pair(tCurrentSubevent, uSubsubeventDataIndex); fTrbTdcWords[iActiveTdcIndex]->Fill(uSubsubeventLength); // fTrbTdcProcessStatus[ iActiveTdcIndex ]->Fill( fTrbTdcUnpacker->ProcessData( tCurrentSubevent, uSubsubeventDataIndex ) ); } } else { LOG(DEBUG)<IsLogNeeded(DEBUG2)) { for(UInt_t uWord = uSubsubeventDataIndex; uWord <= uSubsubeventDataIndex+uSubsubeventLength; uWord++) { LOG(DEBUG2)<Data(uWord))<>12) ) { uNbSubsubevents++; LOG(DEBUG)<<"====================================="<Data(uSubsubeventDataIndex))<Data(uHubSubeventDataIndex); UInt_t uHubSubeventSource = uHubSubeventData & 0xffff; UInt_t uHubSubeventLength = (uHubSubeventData >> 16) & 0xffff; Bool_t bKnownHubSubevent = fMbsUnpackPar->IsTrbFpgaInData(uHubSubeventSource); if( bKnownHubSubevent && bKnownSubsubevent ) { uMotherBoardId = fMbsUnpackPar->GetTrbSebAddrForFpga(uHubSubeventSource); bUnpack = ( -1 < fMbsUnpackPar->GetActiveTrbTdcIndex(uHubSubeventSource) ); } LOG(DEBUG)<>12) ) { uNbSubsubevents++; LOG(DEBUG)<<"====================================="<Data(uHubSubeventDataIndex+1)>>16)&0xff)<IsLogNeeded(DEBUG2)) { for(UInt_t uWord = uHubSubeventDataIndex; uWord <= uHubSubeventDataIndex+uHubSubeventLength; uWord++) { LOG(DEBUG2)<Data(uWord))<GetActiveTrbTdcIndex( uHubSubeventSource ); fTdcUnpackMap[iActiveTdcIndex] = std::pair(tCurrentSubevent, uHubSubeventDataIndex); fTrbTdcWords[iActiveTdcIndex]->Fill(uHubSubeventLength); // fTrbTdcProcessStatus[ iActiveTdcIndex ]->Fill( fTrbTdcUnpacker->ProcessData( tCurrentSubevent, uHubSubeventDataIndex ) ); } } else { LOG(DEBUG)<IsLogNeeded(DEBUG2)) { for(UInt_t uWord = uHubSubeventDataIndex; uWord <= uHubSubeventDataIndex+uHubSubeventLength; uWord++) { LOG(DEBUG2)<Data(uWord))<>12) ) { uNbSubsubevents++; LOG(DEBUG)<<"====================================="<IsLogNeeded(DEBUG2)) { for(UInt_t uWord = uHubSubeventDataIndex; uWord <= uHubSubeventDataIndex+uHubSubeventLength; uWord++) { LOG(DEBUG2)<Data(uWord))<IsLogNeeded(DEBUG2)) { for(UInt_t uWord = uHubSubeventDataIndex; uWord <= uHubSubeventDataIndex+uHubSubeventLength; uWord++) { LOG(DEBUG2)<Data(uWord))<IsLogNeeded(DEBUG2)) { for(UInt_t uWord = uHubSubeventDataIndex; uWord <= uHubSubeventDataIndex+uHubSubeventLength; uWord++) { LOG(DEBUG2)<Data(uWord))<>12) ) { uNbSubsubevents++; // Moving all the HADAQ time calculations here to make sure that only // good events with a CTS subsubevent are considered. Int_t iHadaqCurrentEventTime = (tCurrentEvent->GetTime()&0xff) +60*((tCurrentEvent->GetTime()&0xff00)>>8) +3600*(tCurrentEvent->GetTime()>>16); // time offset of the first valid event in a run if( 0 == fiNbEvents ) { fiHadaqFirstEventTime = iHadaqCurrentEventTime; } // allow for unambiguous, consecutive time stamping of events for between 24h and 48h of data taking per run // (1 overflow from 23:59:59 to 00:00:00 can be taken into account without duplicating time stamps when // not keeping track of the number of overflows) if( 0 > (iHadaqCurrentEventTime - fiHadaqLastEventTime) ) { iHadaqCurrentEventTime += 86400; } fHadaqEventTime->Fill(iHadaqCurrentEventTime - fiHadaqFirstEventTime); // start of a new HADAQ spill: at least 2 seconds time difference to the preceding event if( 1 < (iHadaqCurrentEventTime - fiHadaqLastEventTime) ) { fiHadaqCoarseSpillStartTime = iHadaqCurrentEventTime; fHadaqTimeInSpill->Reset("ICE"); } fTrbHeader->SetTimeInSpill(static_cast(iHadaqCurrentEventTime-fiHadaqCoarseSpillStartTime)); fHadaqTimeInSpill->Fill(fTrbHeader->GetTimeInSpill()); fiCurrentEventNumber = static_cast((tCurrentSubevent->GetTrigNr()) >> 8); if( 0 < fiNbEvents ) { fTrbEventNumberJump->Fill(fiCurrentEventNumber - fiPreviousEventNumber); } UInt_t uTrigStatus = tCurrentSubevent->Data(uSubsubeventDataIndex+1) & 0xffff; uTriggerPattern = uTrigStatus; for(UInt_t uChannel = 0; uChannel < 16; uChannel++) { if( uTriggerPattern & (0x1 << uChannel) ) { fTrbTriggerPattern->Fill(TMath::Log2( uTriggerPattern & (0x1 << uChannel) )); } } fTrbTriggerType->Fill(uTriggerType); fTrbHeader->SetTriggerPattern(uTriggerPattern); fTrbHeader->SetTriggerType(uTriggerType); UInt_t uNbInputCh = (tCurrentSubevent->Data(uSubsubeventDataIndex+1) >> 16) & 0xf; UInt_t uNbTrigCh = (tCurrentSubevent->Data(uSubsubeventDataIndex+1) >> 20) & 0x1f; Bool_t bIncludeLastIdle = (tCurrentSubevent->Data(uSubsubeventDataIndex+1) >> 25) & 0x1; Bool_t bIncludeCounters = (tCurrentSubevent->Data(uSubsubeventDataIndex+1) >> 26) & 0x1; Bool_t bIncludeTimestamp = (tCurrentSubevent->Data(uSubsubeventDataIndex+1) >> 27) & 0x1; UInt_t uExtTrigFlag = (tCurrentSubevent->Data(uSubsubeventDataIndex+1) >> 28) & 0x3; Bool_t bIncludeMbsSync = kFALSE; UInt_t uMbsSync = 0xffffff; Bool_t bMbsSyncError = kFALSE; UInt_t uNbCtsWords = uNbInputCh*2 +uNbTrigCh*2 +bIncludeLastIdle*2 +bIncludeCounters*3 +bIncludeTimestamp*1; UInt_t uBusyIdleOffset = uSubsubeventDataIndex + 2 + uNbInputCh*2 + uNbTrigCh*2; UInt_t uStatsOffset = uBusyIdleOffset + bIncludeLastIdle*2; UInt_t uTimeStampOffset = uStatsOffset + bIncludeCounters*3; if( bIncludeLastIdle ) { UInt_t uBusyTime = tCurrentSubevent->Data(uBusyIdleOffset+1); // time [us] to complete the TrbNet trigger process in the last event fCtsBusyTime->Fill( uBusyTime/100. ); UInt_t uIdleTime = tCurrentSubevent->Data(uBusyIdleOffset); // time [us] passed since the last trigger procession fCtsIdleTime->Fill( uIdleTime/100. ); // CTS idle for less than 1 second if( 1. > uIdleTime/100000000. ) { fCtsTriggerDistance->Fill( (uBusyTime+uIdleTime)/100.); } } Long64_t iAllTriggersDiff(0); Long64_t iAllEventsDiff(0); if( bIncludeCounters ) { Long64_t iAllTriggersCounter = (Long64_t)tCurrentSubevent->Data(uStatsOffset+1) + fliAllPossibleTriggersOverflows*4294967296; Long64_t iAllEventsCounter = (Long64_t)tCurrentSubevent->Data(uStatsOffset+2) + fliAcceptedTriggersOverflows*4294967296; iAllTriggersDiff = iAllTriggersCounter - fiAllPossibleTriggers; if( 0 > iAllTriggersDiff ) { iAllTriggersDiff += 4294967296; fliAllPossibleTriggersOverflows++; } iAllEventsDiff = iAllEventsCounter - fiAcceptedTriggers; if( 0 > iAllEventsDiff ) { iAllEventsDiff += 4294967296; fliAcceptedTriggersOverflows++; } LOG(DEBUG)<Fill(iAllTriggersDiff); fItcEvents->Fill(iAllEventsDiff); } fiAllPossibleTriggers = (Long64_t)tCurrentSubevent->Data(uStatsOffset+1) + fliAllPossibleTriggersOverflows*4294967296; fiAcceptedTriggers = (Long64_t)tCurrentSubevent->Data(uStatsOffset+2) + fliAcceptedTriggersOverflows*4294967296; } if( bIncludeTimestamp ) { Long64_t iCurrentTimeStamp = (Long64_t)tCurrentSubevent->Data(uTimeStampOffset); /* ############################################################################# // works reliably only for nov15 data // more robust than the version covering both feb15 and nov15 if( fbNextSpillToStart || (0 == fiNbEvents) ) { fiCtsFirstEventTime = iCurrentTimeStamp; fiCtsLastEventTime = 0; fiHadaqSpillStartTime = iHadaqCurrentEventTime - fiHadaqFirstEventTime; iAllTriggersDiff = 0; iAllEventsDiff = 0; fbNextSpillToStart = kFALSE; } if( 10 < (iHadaqCurrentEventTime - fiHadaqLastEventTime) ) { fbNextSpillToStart = kTRUE; } ########################################################################### */ // seems to work for both feb15 and nov15 data // more assumptions necessary, less robust if( 0 == fiNbEvents ) { fiCtsFirstEventTime = iCurrentTimeStamp; fiCtsLastEventTime = 0; fiHadaqSpillStartTime = iHadaqCurrentEventTime - fiHadaqFirstEventTime; iAllTriggersDiff = 0; iAllEventsDiff = 0; // seemingly a HADAQ buffer delay can already exist at the beginning of a run! fbHadaqBufferDelay = kTRUE; } else { // start of a new HADAQ spill: at least 2 seconds time difference to the preceding one if( 1 < (iHadaqCurrentEventTime - fiHadaqLastEventTime) ) { // no HADAQ buffer delay has been observed if( !fbHadaqBufferDelay ) { // compare the current CTS time to the value in the previous event Long64_t iTimeInSpill = iCurrentTimeStamp - fiCtsFirstEventTime; if( 0 > iTimeInSpill ) { iTimeInSpill += 4294967296; } // event most probably belongs to the preceding spill if( 1000*100000 > (iTimeInSpill-fiCtsLastEventTime) ) { fbHadaqBufferDelay = kTRUE; } // event most probably starts a new spill else { fiCtsFirstEventTime = iCurrentTimeStamp; fiCtsLastEventTime = 0; fiHadaqSpillStartTime = iHadaqCurrentEventTime - fiHadaqFirstEventTime; iAllTriggersDiff = 0; iAllEventsDiff = 0; fCtsTimeInSpill->Reset("ICE"); } } // a HADAQ buffer delay is propagating else { fiCtsFirstEventTime = iCurrentTimeStamp; fiCtsLastEventTime = 0; fiHadaqSpillStartTime = fiHadaqLastEventTime - fiHadaqFirstEventTime; iAllTriggersDiff = 0; iAllEventsDiff = 0; fCtsTimeInSpill->Reset("ICE"); } } // somewhere inside a HADAQ spill else { // first event following a series of delayed HADAQ buffers if( fbHadaqBufferDelay ) { fiCtsFirstEventTime = iCurrentTimeStamp; fiCtsLastEventTime = 0; // correct spill start time w.r.t. the HADAQ buffer delay fiHadaqSpillStartTime = fiHadaqLastEventTime - fiHadaqFirstEventTime; iAllTriggersDiff = 0; iAllEventsDiff = 0; fCtsTimeInSpill->Reset("ICE"); // HADAQ buffer delay propagation should stop here fbHadaqBufferDelay = kFALSE; } } } // ############################################################################# Long64_t iTimeInSpill = iCurrentTimeStamp - fiCtsFirstEventTime; if( 0 > iTimeInSpill ) { iTimeInSpill += 4294967296; } if( bIncludeCounters ) { if( 0 == fiCtsLastEventTime ) { LOG(DEBUG)<Data(uBusyIdleOffset))<Fill(fiHadaqSpillStartTime*1. + (Double_t)(fiCtsLastEventTime + iTimeInSpill)/2./100000000., iAllTriggersDiff); fCtsTriggerAccepted->Fill(fiHadaqSpillStartTime*1. + (Double_t)(fiCtsLastEventTime + iTimeInSpill)/2./100000000., iAllEventsDiff); fHadaqEventsRecorded->Fill(fiHadaqSpillStartTime*1. + (Double_t)(fiCtsLastEventTime + iTimeInSpill)/2./100000000., 1); } if(fbFineSpillTiming) { fTrbHeader->SetTimeInSpill(static_cast(iTimeInSpill)/100000000.); } fCtsTimeInSpill->Fill((Double_t)iTimeInSpill/100000.); fEventSkipsInSpill->Fill((Double_t)iTimeInSpill/100000000., fiCurrentEventNumber - fiPreviousEventNumber - 1); fiCtsLastEventTime = iTimeInSpill; } /* Uncomment the following block of code to display [DEBUG2] the difference of assertion cycle and rising edge counters of the trigger input modules (IM) and the iternal trigger channels (ITC) compared to the previous event. As of 2016-01-22, most counter values written into the CTS subsubevent are not meaningful due to a firmware bug. In the CTS GUI, the counter values are correct (polled via the slow-control channel of TrbNet). */ /* UInt_t uTrigInpOffset = uSubsubeventDataIndex + 2; UInt_t uTrigCntOffset = uTrigInpOffset + uNbInputCh*2; UInt_t uTrigInpEdgeDiffsSum(0); UInt_t uTrigInpClockDiffsSum(0); for( UInt_t uInput = 0; uInput < uNbInputCh; uInput++ ) { UInt_t uTrigInpClockDiff = tCurrentSubevent->Data( uTrigInpOffset + 2*uInput ) - fuTrigInputClockCounter[uInput]; uTrigInpClockDiffsSum += uTrigInpClockDiff; fuTrigInputClockCounter[uInput] = tCurrentSubevent->Data( uTrigInpOffset + 2*uInput ); LOG(DEBUG2)<Data( uTrigInpOffset + 1 + 2*uInput ) - fuTrigInputEdgeCounter[uInput]; uTrigInpEdgeDiffsSum += uTrigInpEdgeDiff; fuTrigInputEdgeCounter[uInput] = tCurrentSubevent->Data( uTrigInpOffset + 1 + 2*uInput ); LOG(DEBUG2)<Data( uTrigCntOffset + 2*uChannel ) - fuTrigChanClockCounter[uChannel]; uTrigChanClockDiffsSum += uTrigChanClockDiff; fuTrigChanClockCounter[uChannel] = tCurrentSubevent->Data( uTrigCntOffset + 2*uChannel ); LOG(DEBUG2)<Data( uTrigCntOffset + 1 + 2*uChannel ) - fuTrigChanEdgeCounter[uChannel]; uTrigChanEdgeDiffsSum += uTrigChanEdgeDiff; fuTrigChanEdgeCounter[uChannel] = tCurrentSubevent->Data( uTrigCntOffset + 1 + 2*uChannel ); LOG(DEBUG2)<Data(uSubsubeventDataIndex+2+uNbCtsWords) & 0xffffff; bMbsSyncError = tCurrentSubevent->Data(uSubsubeventDataIndex+2+uNbCtsWords) & 0x80000000; } LOG(DEBUG)<<"====================================="<IsLogNeeded(DEBUG2)) { for(UInt_t uWord = uSubsubeventDataIndex; uWord <= uSubsubeventDataIndex+uSubsubeventLength; uWord++) { LOG(DEBUG2)<Data(uWord))<IsLogNeeded(DEBUG2)) { for(UInt_t uWord = uSubsubeventDataIndex; uWord <= uSubsubeventDataIndex+uSubsubeventLength; uWord++) { LOG(DEBUG2)<Data(uWord))<IsTrbEventUnpacked(uTriggerPattern) ) { LOG(INFO)<<"HADAQ raw event does not meet the trigger selection criteria. Skip it."<IsLogNeeded(DEBUG2)) { for(UInt_t uWord = uSubsubeventDataIndex; uWord <= uSubsubeventDataIndex+uSubsubeventLength; uWord++) { LOG(DEBUG2)<Data(uWord))< >::iterator it = fTdcUnpackMap.begin(); it != fTdcUnpackMap.end(); ++it) { Int_t iTdcUnpackStatus = fTrbTdcUnpacker->ProcessData( (it->second).first, (it->second).second ); fTrbTdcProcessStatus[ it->first ]->Fill( iTdcUnpackStatus ); if( (trbtdc::process_Success != iTdcUnpackStatus) && (trbtdc::process_BadFineTime != iTdcUnpackStatus) ) { bSkipHadaqEvent = kTRUE; } } if( bSkipHadaqEvent ) { LOG(INFO)<<"TDC raw data integrity not guaranteed. Skip the full HADAQ raw event."<GetActiveTrbSebNb())<GetRuntimeDb(); fMbsUnpackPar = (TMbsUnpackTofPar *) (rtdb->getContainer("TMbsUnpackTofPar")); if( fbInspection ) { fMbsCalibPar = (TMbsCalibTofPar *) (rtdb->getContainer("TMbsCalibTofPar")); } if( 0 == fMbsUnpackPar || ( fbInspection && !fMbsCalibPar ) ) return kFALSE; fMbsUnpackPar->printParams(); fuInDataTrbSebNb = fMbsUnpackPar->GetActiveTrbSebNb(); fuActiveTrbTdcNb = fMbsUnpackPar->GetNbActiveBoards( tofMbs::trbtdc ); return kTRUE; } Bool_t TTrbUnpackTof::CreateSubunpackers() { LOG(INFO)<<"**** TTrbUnpackTof: Call CreateSubunpackers()..."<SetInspection(fbInspection); } return kTRUE; } Bool_t TTrbUnpackTof::RegisterOutput() { LOG(INFO)<<"**** TTrbUnpackTof: Call RegisterOutput()..."<Register( "TofTrbTdc","TofUnpack", fTrbTdcBoardCollection, fMbsUnpackPar->WriteDataInCbmOut() || fbSaveRawTdcBoards ); fTrbHeader = new TTrbHeader(); manager->Register( "TofTrbHeader.","TofUnpack", fTrbHeader, kTRUE ); return kTRUE; } void TTrbUnpackTof::SetSaveRawData( Bool_t bSaveRaw ) { fbSaveRawTdcBoards = bSaveRaw; LOG(INFO)<<"TTrbUnpackTof => Enable the saving of raw trb data in analysis output file" <Clear("C"); fTdcUnpackMap.clear(); return kTRUE; } void TTrbUnpackTof::CreateHistograms() { LOG(DEBUG)<<"**** TTrbUnpackTof: Call CreateHistograms()..."<cd(); fTrbTriggerPattern = new TH1I("tof_trb_trigger_pattern", "CTS trigger pattern", 16, 0, 16); fTrbTriggerPattern->GetXaxis()->SetTitle("trigger pattern []"); fTrbTriggerType = new TH1I("tof_trb_trigger_types", "CTS trigger types", 16, 0, 16); fTrbTriggerType->GetXaxis()->SetTitle("trigger type []"); fTrbEventNumberJump = new TH1I("tof_trb_event_jump", "CTS event number jumps", 100, 0, 100); fTrbEventNumberJump->GetXaxis()->SetTitle("event counter increment []"); fCtsBusyTime = new TH1I("tof_trb_cts_busy", "CTS busy time", 100, 0, 100); fCtsBusyTime->GetXaxis()->SetTitle("busy time [#mus]"); fCtsIdleTime = new TH1I("tof_trb_cts_idle", "CTS idle time", 200, 0, 200); fCtsIdleTime->GetXaxis()->SetTitle("idle time [#mus]"); fCtsIdleTimeSpill = new TH1I("tof_trb_cts_idle_spill", "TDC spill-break length", 100, 0, 100); fCtsIdleTimeSpill->GetXaxis()->SetTitle("spill break [s]"); fCtsSpillLength = new TH1I("tof_trb_cts_spill_length", "TDC spill length", 20, 0, 20); fCtsSpillLength->GetXaxis()->SetTitle("spill length [s]"); fCtsTriggerDistance = new TH1I("tof_trb_cts_cycle", "CTS trigger distance", 500, 0, 500); fCtsTriggerDistance->GetXaxis()->SetTitle("trigger distance [#mus]"); fItcAssertions = new TH1I("tof_trb_itc_assert", "All trigger cycles since last event", 200, 0, 200); fItcAssertions->GetXaxis()->SetTitle("detected triggers []"); fItcEvents = new TH1I("tof_trb_cts_events", "Accepted cycles since last event", 100, 0, 100); fItcEvents->GetXaxis()->SetTitle("accepted triggers []"); // binning and range increased to cover run times of up to 6 hours fHadaqEventTime = new TH1I("tof_trb_hadaq_time", "HADAQ event time", 20000, 0, 20000); fHadaqEventTime->GetXaxis()->SetTitle("HADAQ event time [s]"); fCtsTriggerCycles = new TH1I("tof_trb_trigger_rate", "CTS trigger/event rate", 20000, 0, 20000); fCtsTriggerCycles->GetXaxis()->SetTitle("CTS event time [s]"); fCtsTriggerCycles->SetMarkerStyle(34); fCtsTriggerCycles->SetMarkerColor(kRed); fCtsTriggerCycles->SetLineColor(kRed); fCtsTriggerAccepted = new TH1I("tof_trb_event_rate", "CTS trigger/event rate", 20000, 0, 20000); fCtsTriggerAccepted->GetXaxis()->SetTitle("CTS event time [s]"); fCtsTriggerAccepted->SetMarkerStyle(34); fCtsTriggerAccepted->SetMarkerColor(kGreen); fCtsTriggerAccepted->SetLineColor(kGreen); fHadaqEventsRecorded = new TH1I("tof_trb_hadaq_rate", "CTS/HADAQ event rate", 20000, 0, 20000); fHadaqEventsRecorded->GetXaxis()->SetTitle("CTS event time [s]"); fHadaqEventsRecorded->SetMarkerStyle(34); fHadaqEventsRecorded->SetMarkerColor(kBlue); fHadaqEventsRecorded->SetLineColor(kBlue); fHadaqTimeInSpill = new TH1I("tof_hadaq_time_spill", "HADAQ coarse time in spill", 20, 0, 20); fHadaqTimeInSpill->GetXaxis()->SetTitle("HADAQ time in spill [s]"); fCtsTimeInSpill = new TH1I("tof_cts_time_spill", "CTS fine time in spill", 20000, 0, 20000); fCtsTimeInSpill->GetXaxis()->SetTitle("CTS time in spill [ms]"); fEventSkipsInSpill = new TH2I("tof_trb_skips_spill", "CTS events skipped in spill", 20, 0, 20, 100, 0, 100); fEventSkipsInSpill->GetXaxis()->SetTitle("CTS event time in spill [s]"); fEventSkipsInSpill->GetYaxis()->SetTitle("CTS events skipped"); TH1* hTemp = 0; for( UInt_t uTrbSeb = 0; uTrbSeb < fuInDataTrbSebNb; uTrbSeb++ ) { UInt_t uTrbNetAddress = fMbsUnpackPar->GetTrbSebAddr(uTrbSeb); hTemp = new TH1I( Form("tof_trb_size_subevent_%03u", uTrbSeb), Form("data sent by TRB-SEB 0x%04x", uTrbNetAddress), 65, 0, 65); hTemp->GetXaxis()->SetTitle("subevent size [kB]"); fTrbSubeventSize.push_back( hTemp ); hTemp = new TH1I( Form("tof_trb_status_subevent_%03u", uTrbSeb), Form("status bits of TRB-SEB 0x%04x", uTrbNetAddress), 32, 0, 32); hTemp->GetXaxis()->SetTitle("TrbNet status bits []"); fTrbSubeventStatus.push_back( hTemp ); } for( UInt_t uTrbTdc = 0; uTrbTdc < fuActiveTrbTdcNb; uTrbTdc++) { UInt_t uTrbNetAddress = fMbsUnpackPar->GetActiveTrbTdcAddr(uTrbTdc); hTemp = new TH1I( Form("tof_trb_words_tdc_%03u", uTrbTdc), Form("words sent by TRB-TDC 0x%04x", uTrbNetAddress), 800, 0, 800); hTemp->GetXaxis()->SetTitle("subsubevent words [4B]"); fTrbTdcWords.push_back( hTemp ); hTemp = new TH1I( Form("tof_trb_process_status_tdc_%03u", uTrbTdc), Form("data processing status of TRB-TDC 0x%04x", uTrbNetAddress), trbtdc::process_StatusMessages, 0, trbtdc::process_StatusMessages); hTemp->GetXaxis()->SetTitle("TDC unpacking status []"); fTrbTdcProcessStatus.push_back( hTemp ); } gDirectory->cd( oldir->GetPath() ); } void TTrbUnpackTof::WriteHistograms() { LOG(DEBUG)<<"**** TTrbUnpackTof: Call WriteHistograms()..."<Write(); fTrbTriggerType->Write(); fTrbEventNumberJump->Write(); fCtsBusyTime->Write(); fCtsIdleTime->Write(); fCtsIdleTimeSpill->Write(); fCtsSpillLength->Write(); fCtsTriggerDistance->Write(); fItcAssertions->Write(); fItcEvents->Write(); fHadaqEventTime->Write(); fCtsTriggerCycles->Write(); fCtsTriggerAccepted->Write(); fHadaqEventsRecorded->Write(); fHadaqTimeInSpill->Write(); fCtsTimeInSpill->Write(); fEventSkipsInSpill->Write(); for( UInt_t uTrbSeb = 0; uTrbSeb < fuInDataTrbSebNb; uTrbSeb++ ) { fTrbSubeventSize[uTrbSeb]->Write(); fTrbSubeventStatus[uTrbSeb]->Write(); } for( UInt_t uTrbTdc = 0; uTrbTdc < fuActiveTrbTdcNb; uTrbTdc++) { fTrbTdcWords[uTrbTdc]->Write(); fTrbTdcProcessStatus[uTrbTdc]->Write(); } gDirectory->cd( oldir->GetPath() ); tHist->Close(); delete tHist; } void TTrbUnpackTof::DataErrorHandling(UInt_t uSubeventId, UInt_t uErrorPattern) { // TrbNet network error and status bits if (tofTrb::status_network_0 & uErrorPattern) { LOG(DEBUG)<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_network_0)); } if (tofTrb::status_network_1 & uErrorPattern) { LOG(ERROR)<<"TrbNet network status: endpoint data collision"<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_network_1)); } if (tofTrb::status_network_2 & uErrorPattern) { LOG(ERROR)<<"TrbNet network status: incomplete data transfer between nodes"<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_network_2)); } if (tofTrb::status_network_3 & uErrorPattern) { LOG(ERROR)<<"TrbNet network status: check-sum mismatch on point-to-point link"<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_network_3)); } if (tofTrb::status_network_4 & uErrorPattern) { LOG(ERROR)<<"TrbNet network status: network request not understood by node"<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_network_4)); } if (tofTrb::status_network_5 & uErrorPattern) { LOG(ERROR)<<"TrbNet network status: I/O buffer packet count mismatch"<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_network_5)); } if (tofTrb::status_network_6 & uErrorPattern) { LOG(ERROR)<<"TrbNet network status: network transaction timeout"<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_network_6)); } // TrbNet readout error and status bits if (tofTrb::status_readout_16 & uErrorPattern) { LOG(ERROR)<<"TrbNet readout status: trigger number mismatch"<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_readout_16)); } if (tofTrb::status_readout_17 & uErrorPattern) { LOG(ERROR)<<"TrbNet readout status: trigger code mismatch"<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_readout_17)); } if (tofTrb::status_readout_18 & uErrorPattern) { LOG(ERROR)<<"TrbNet readout status: wrong data stream length"<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_readout_18)); } if (tofTrb::status_readout_19 & uErrorPattern) { LOG(ERROR)<<"TrbNet readout status: front-end failed to deliver any data"<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_readout_19)); } if (tofTrb::status_readout_20 & uErrorPattern) { LOG(ERROR)<<"TrbNet readout status: requested CTS trigger number not in front-end event data buffer"<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_readout_20)); } if (tofTrb::status_readout_21 & uErrorPattern) { LOG(ERROR)<<"TrbNet readout status: front-end data only partially sent"<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_readout_21)); } if (tofTrb::status_readout_22 & uErrorPattern) { LOG(ERROR)<<"TrbNet readout status: severe readout problem (TrbNet reset required)"<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_readout_22)); } if (tofTrb::status_readout_23 & uErrorPattern) { LOG(ERROR)<<"TrbNet readout status: single broken event"<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_readout_23)); } if (tofTrb::status_readout_24 & uErrorPattern) { LOG(ERROR)<<"TrbNet readout status: GbE link down"<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_readout_24)); } if (tofTrb::status_readout_25 & uErrorPattern) { LOG(ERROR)<<"TrbNet readout status: subevent buffer almost full"<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_readout_25)); } if (tofTrb::status_readout_26 & uErrorPattern) { LOG(ERROR)<<"TrbNet readout status: corrupted data detected by the subevent builder"<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_readout_26)); } if (tofTrb::status_readout_27 & uErrorPattern) { LOG(ERROR)<<"TrbNet readout status: reference time problem"<GetTrbSebIndex( uSubeventId ) ]->Fill(TMath::Log2(tofTrb::status_readout_27)); } return; }