// ----------------------------------------------------------------------------- // ----- 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" // 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 "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), fiNbEvents(0), fiCurrentEventNumber(0), fiPreviousEventNumber(0), fTrbIterator(NULL), fTrbTdcUnpacker(NULL), fTrbTdcBoardCollection(NULL), fbSaveRawTdcBoards(kFALSE), fTdcUnpackMap(), fuInDataTrbSebNb(0), fuActiveTrbTdcNb(0), fTrbTriggerPattern(NULL), fTrbTriggerType(NULL), fTrbEventNumberJump(NULL), fTrbSubeventSize(), fTrbSubeventStatus(), fTrbTdcWords(), fTrbTdcProcessStatus() { LOG(INFO)<<"**** TTrbUnpackTof: Call TTrbUnpackTof()..."<nextEvent(); LOG(DEBUG2)<<"First word in HADAQ event: "<tuSize)<tuDecoding)<tuId)<evtSeqNr)<evtDate)<evtTime)<evtRunNr)<evtPad)<GetDataError() ) { LOG(WARNING)<<"Error bit set in at least one HADAQ raw subevent!"<GetTrigType(); fTrbTdcUnpacker->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)<GetTrigNr()) >> 8; if( 0 < fiNbEvents ) { fTrbEventNumberJump->Fill(fiCurrentEventNumber - fiPreviousEventNumber); } } UInt_t uSubsubeventDataIndex = 0; UInt_t uSubsubeventData = 0; UInt_t uSubsubeventSource = 0xffff; while ( uSubsubeventSource != 0x5555 ) { uSubsubeventData = tCurrentSubevent->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++; 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); 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; if( 0x1 == uExtTrigFlag ) { bIncludeMbsSync = kTRUE; uMbsSync = tCurrentSubevent->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))<IsLogNeeded(DEBUG2)) { for(UInt_t uWord = uSubsubeventDataIndex; uWord <= uSubsubeventDataIndex+uSubsubeventLength; uWord++) { LOG(DEBUG2)<Data(uWord))<IsTrbEventUnpacked(uTriggerPattern) ) { for ( std::map >::iterator it = fTdcUnpackMap.begin(); it != fTdcUnpackMap.end(); ++it) { fTrbTdcProcessStatus[ it->first ]->Fill( fTrbTdcUnpacker->ProcessData( (it->second).first, (it->second).second ) ); } } LOG(DEBUG)<GetActiveTrbSebNb())<GetRuntimeDb(); fMbsUnpackPar = (TMbsUnpackTofPar *) (rtdb->getContainer("TMbsUnpackTofPar")); if( 0 == fMbsUnpackPar ) return kFALSE; fMbsUnpackPar->printParams(); fuInDataTrbSebNb = fMbsUnpackPar->GetActiveTrbSebNb(); fuActiveTrbTdcNb = fMbsUnpackPar->GetNbActiveBoards( tofMbs::trbtdc ); return kTRUE; } Bool_t TTrbUnpackTof::CreateSubunpackers() { LOG(INFO)<<"**** TTrbUnpackTof: Call CreateSubunpackers()..."<Register( "TofTrbTdc","TofUnpack", fTrbTdcBoardCollection, fMbsUnpackPar->WriteDataInCbmOut() || fbSaveRawTdcBoards ); 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); fTrbTriggerType = new TH1I("tof_trb_trigger_types", "CTS trigger types", 16, 0, 16); fTrbEventNumberJump = new TH1I("tof_trb_event_jump", "CTS event number jumps", 2500, 0, 2500); 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); 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); 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); 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); fTrbTdcProcessStatus.push_back( hTemp ); } gDirectory->cd( oldir->GetPath() ); } void TTrbUnpackTof::WriteHistograms() { LOG(DEBUG)<<"**** TTrbUnpackTof: Call WriteHistograms()..."<Write(); fTrbTriggerType->Write(); fTrbEventNumberJump->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)<<"TrbNet network status: node replied to network request"<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; }