diff --git a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoMuch.cxx b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoMuch.cxx index 6ef7a25d0f40cb5e1d0491e9e6efe86f207b443f..9c0b2bdf103e1494b23f6609a763dc42830fc5bc 100644 --- a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoMuch.cxx +++ b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoMuch.cxx @@ -42,9 +42,13 @@ CbmMcbm2018UnpackerAlgoMuch::CbmMcbm2018UnpackerAlgoMuch() : fDpbIdIndexMap(), fvbCrobActiveFlag(), fuNbFebs( 0 ), + //fviFebAddress(), fuNbStsXyters( 0 ), fdTimeOffsetNs( 0.0 ), fvdTimeOffsetNsAsics(), + fbUseChannelMask( kFALSE ), + fvvbMaskedChannels(), + fdAdcCut( 0 ), fulCurrentTsIdx( 0 ), fulCurrentMsIdx( 0 ), fdTsStartTime( -1.0 ), @@ -86,6 +90,11 @@ CbmMcbm2018UnpackerAlgoMuch::~CbmMcbm2018UnpackerAlgoMuch() fvmHitsInMs[ uDpb ].clear(); } // for( UInt_t uDpb = 0; uDpb < fuNrOfDpbs; ++uDpb ) */ + + if( nullptr != fParCList ) + delete fParCList; + if( nullptr != fUnpackPar ) + delete fUnpackPar; } // ------------------------------------------------------------------------- @@ -204,6 +213,11 @@ Bool_t CbmMcbm2018UnpackerAlgoMuch::InitParameters() } // for( UInt_t uCrobIdx = 0; uCrobIdx < fUnpackPar->GetNbCrobsPerDpb(); ++uCrobIdx ) } // for( UInt_t uDpb = 0; uDpb < fuNrOfDpbs; ++uDpb ) */ + + if( fbBinningFw ) + LOG(info) << "Unpacking data in bin sorter FW mode"; + else LOG(info) << "Unpacking data in full time sorter FW mode (legacy)"; + // Internal status initialization fvulCurrentTsMsb.resize( fuNrOfDpbs ); fvuCurrentTsMsbCycle.resize( fuNrOfDpbs ); @@ -553,6 +567,11 @@ Bool_t CbmMcbm2018UnpackerAlgoMuch::ProcessMs( const fles::Timeslice& ts, size_t UInt_t uTsMsbCycleHeader = std::floor( fulCurrentMsIdx / ( stsxyter::kulTsCycleNbBins * stsxyter::kdClockCycleNs ) ); + /// => Quick and dirty hack for binning FW!!! + if( kTRUE == fbBinningFw ) + uTsMsbCycleHeader = std::floor( fulCurrentMsIdx / + ( stsxyter::kulTsCycleNbBinsBinning * stsxyter::kdClockCycleNs ) ); + if( 0 == uMsIdx ) { if( uTsMsbCycleHeader != fvuCurrentTsMsbCycle[ fuCurrDpbIdx ] ) @@ -617,6 +636,9 @@ Bool_t CbmMcbm2018UnpackerAlgoMuch::ProcessMs( const fles::Timeslice& ts, size_t { // Extract the eLink and Asic indices => Should GO IN the fill method now that obly hits are link/asic specific! UShort_t usElinkIdx = pMess[uIdx].GetLinkIndex(); + /// => Quick and dirty hack for binning FW!!! + if( kTRUE == fbBinningFw ) + usElinkIdx = pMess[uIdx].GetLinkIndexHitBinning(); // fhStsMessTypePerElink->Fill( usElinkIdx, static_cast< uint16_t > (typeMess) ); // fhStsHitsElinkPerDpb->Fill( fuCurrDpbIdx, usElinkIdx ); @@ -686,6 +708,16 @@ Bool_t CbmMcbm2018UnpackerAlgoMuch::ProcessMs( const fles::Timeslice& ts, size_t // FillTsMsbInfo( pMess[uIdx] ); break; } // case stsxyter::MessType::Empty : + case stsxyter::MessType::EndOfMs : + { + if( pMess[uIdx].IsMsErrorFlagOn() ) + { + fErrVect.push_back( CbmErrorMessage( ECbmModuleId::kMuch, fulCurrentMsIdx, + fuCurrDpbIdx, 0x20, + pMess[uIdx].GetMsErrorType() ) ); + } // if( pMess[uIdx].IsMsErrorFlagOn() ) + break; + } // case stsxyter::MessType::EndOfMs : case stsxyter::MessType::Dummy : { // fhStsMessTypePerElink->Fill( fuCurrDpbIdx * fUnpackPar->GetNbElinkPerDpb(), static_cast< uint16_t > (typeMess) ); @@ -712,6 +744,10 @@ void CbmMcbm2018UnpackerAlgoMuch::ProcessHitInfo( const stsxyter::Message & mess // UShort_t usTsOver = mess.GetHitTimeOver(); UShort_t usRawTs = mess.GetHitTime(); + /// => Quick and dirty hack for binning FW!!! + if( kTRUE == fbBinningFw ) + usRawTs = mess.GetHitTimeBinning(); + /// Cheat needed only for modules with FEB at bottom of module or the Test module // usChan = 127 - usChan; @@ -763,10 +799,29 @@ void CbmMcbm2018UnpackerAlgoMuch::ProcessHitInfo( const stsxyter::Message & mess + static_cast<ULong64_t>( stsxyter::kulTsCycleNbBins ) * static_cast<ULong64_t>( fvuCurrentTsMsbCycle[fuCurrDpbIdx] ); + /// => Quick and dirty hack for binning FW!!! + if( kTRUE == fbBinningFw ) + ulHitTime = usRawTs + + static_cast<ULong64_t>( stsxyter::kuHitNbTsBinsBinning ) + * static_cast<ULong64_t>( fvulCurrentTsMsb[fuCurrDpbIdx]) + + static_cast<ULong64_t>( stsxyter::kulTsCycleNbBinsBinning ) + * static_cast<ULong64_t>( fvuCurrentTsMsbCycle[fuCurrDpbIdx] ) + ; + // Convert the Hit time in bins to Hit time in ns Double_t dHitTimeNs = ulHitTime * stsxyter::kdClockCycleNs; - fvmHitsInMs.push_back( stsxyter::FinalHit( ulHitTime, usRawAdc, uAsicIdx, usChan, fuCurrDpbIdx, uCrobIdx ) ); + /// Store hit for output only if it is mapped to a module!!! + //if( 0 != fviFebAddress[ uFebIdx ] && fdAdcCut < usRawAdc ) + if( fdAdcCut < usRawAdc ) + { + /// Store only if masking is disabled or if channeld is not masked + /// 2D vector is safe as always right size if masking enabled + if( kFALSE == fbUseChannelMask || false == fvvbMaskedChannels[ uAsicIdx ][ usChan ] ) + fvmHitsInMs.push_back( stsxyter::FinalHit( ulHitTime, usRawAdc, uAsicIdx, usChan, fuCurrDpbIdx, uCrobIdx ) ); + } // if( 0 != fviFebAddress[ uFebIdx ] ) + + // fvmHitsInMs.push_back( stsxyter::FinalHit( ulHitTime, usRawAdc, uAsicIdx, usChan, fuCurrDpbIdx, uCrobIdx ) ); /// If EM flag ON, store a corresponding error message with the next flag after all other possible status flags set if( mess.IsHitMissedEvts() ) @@ -812,6 +867,10 @@ void CbmMcbm2018UnpackerAlgoMuch::ProcessTsMsbInfo( const stsxyter::Message & me { UInt_t uVal = mess.GetTsMsbVal(); + /// => Quick and dirty hack for binning FW!!! + if( kTRUE == fbBinningFw ) + uVal = mess.GetTsMsbValBinning(); + /* if( (uVal != fvulCurrentTsMsb[fuCurrDpbIdx] + 1) && 0 < uVal && !( 1 == uMessIdx && usVal == fvulCurrentTsMsb[fuCurrDpbIdx] ) ) // 1st TS_MSB in MS is always a repeat of the last one in previous MS! @@ -846,7 +905,9 @@ void CbmMcbm2018UnpackerAlgoMuch::ProcessTsMsbInfo( const stsxyter::Message & me if( uVal != fvulCurrentTsMsb[fuCurrDpbIdx] + 1 && !( 0 == uVal && 4194303 == fvulCurrentTsMsb[fuCurrDpbIdx] ) && /// Case where we reach a normal cycle edge 1 != uMessIdx && /// First TS_MSB in MS may jump if TS dropped by DAQ - !( 0 == uVal && 0 == fvulCurrentTsMsb[fuCurrDpbIdx] && 2 == uMessIdx ) ) /// case with cycle et edge of 2 MS + !( 0 == uVal && 0 == fvulCurrentTsMsb[fuCurrDpbIdx] && 2 == uMessIdx ) && /// case with cycle et edge of 2 MS + uVal < fvulCurrentTsMsb[fuCurrDpbIdx] /// New FW introduced TS_MSB suppression + large TS_MSB => warning only if value not increasing + ) { LOG(info) << "TS MSb Jump in " << " TS " << std::setw( 12 ) << fulCurrentTsIdx @@ -914,6 +975,14 @@ void CbmMcbm2018UnpackerAlgoMuch::ProcessStatusInfo( const stsxyter::Message & m * static_cast<ULong64_t>( fvulCurrentTsMsb[fuCurrDpbIdx]) + static_cast<ULong64_t>( stsxyter::kulTsCycleNbBins ) * static_cast<ULong64_t>( fvuCurrentTsMsbCycle[fuCurrDpbIdx] ); + + /// => Quick and dirty hack for binning FW!!! + if( kTRUE == fbBinningFw ) + ulTime = static_cast<ULong64_t>( stsxyter::kuHitNbTsBinsBinning ) + * static_cast<ULong64_t>( fvulCurrentTsMsb[fuCurrDpbIdx]) + + static_cast<ULong64_t>( stsxyter::kulTsCycleNbBinsBinning ) + * static_cast<ULong64_t>( fvuCurrentTsMsbCycle[fuCurrDpbIdx] ); + /// Convert the time in bins to Hit time in ns Double_t dTimeNs = ulTime * stsxyter::kdClockCycleNs; @@ -1232,3 +1301,22 @@ void CbmMcbm2018UnpackerAlgoMuch::SetTimeOffsetNsAsic( UInt_t uAsicIdx, Double_t fvdTimeOffsetNsAsics[ uAsicIdx ] = dOffsetIn; } // ------------------------------------------------------------------------- +void CbmMcbm2018UnpackerAlgoMuch::MaskNoisyChannel( UInt_t uFeb, UInt_t uChan, Bool_t bMasked ) +{ + if( kFALSE == fbUseChannelMask ) + { + fbUseChannelMask = kTRUE; + fvvbMaskedChannels.resize( fuNbFebs ); + for( UInt_t uFebIdx = 0; uFebIdx < fuNbFebs; ++uFebIdx ) + { + fvvbMaskedChannels[ uFebIdx ].resize( fUnpackPar->GetNbChanPerFeb(), false ); + } // for( UInt_t uFeb = 0; uFeb < fuNbFebs; ++uFeb ) + } // if( kFALSE == fbUseChannelMask ) + if( uFeb < fuNbFebs && uChan < fUnpackPar->GetNbChanPerFeb() ) + fvvbMaskedChannels[ uFeb ][ uChan ] = bMasked; + else LOG( fatal ) << "CbmMcbm2018UnpackerAlgoMuch::MaskNoisyChannel => Invalid FEB and/or CHAN index:" + << Form( " %u vs %u and %u vs %u", uFeb, fuNbFebs, uChan, fUnpackPar->GetNbChanPerFeb() ); +} +// ------------------------------------------------------------------------- + + diff --git a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoMuch.h b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoMuch.h index 7d8fb74ee97404e15eecac4ce7129198ebb78135..3cc4e3ba414ac39191c297718980b4319a156fa4 100644 --- a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoMuch.h +++ b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoMuch.h @@ -62,10 +62,17 @@ class CbmMcbm2018UnpackerAlgoMuch : public CbmStar2019Algo<CbmMuchBeamTimeDigi> inline void SetMonitorMode( Bool_t bFlagIn = kTRUE ) { fbMonitorMode = bFlagIn; } inline void SetTimeOffsetNs( Double_t dOffsetIn = 0.0 ) { fdTimeOffsetNs = dOffsetIn; } void SetTimeOffsetNsAsic( UInt_t uAsicIdx, Double_t dOffsetIn = 0.0 ); - + void MaskNoisyChannel( UInt_t uFeb, UInt_t uChan, Bool_t bMasked = kTRUE ); void EnableAsicType( Int_t flag = 0 ) { fiFlag = flag; } + + /// => Quick and dirty hack for binning FW!!! + void SetBinningFwFlag( Bool_t bEnable = kTRUE ) { fbBinningFw = bEnable; } + inline void SetVectCapInc( Double_t dIncFact ) { fdCapacityIncFactor = dIncFact; } + void SetAdcCut( UInt_t uAdc ) { fdAdcCut = uAdc; } + + CbmMuchBeamTimeDigi * CreateMuchDigi(stsxyter::FinalHit *); @@ -74,6 +81,8 @@ class CbmMcbm2018UnpackerAlgoMuch : public CbmStar2019Algo<CbmMuchBeamTimeDigi> Bool_t fbMonitorMode; //! Switch ON the filling of a minimal set of histograms Bool_t fbDebugMonitorMode; //! Switch ON the filling of a additional set of histograms std::vector< Bool_t > fvbMaskedComponents; + /// => Quick and dirty hack for binning FW!!! + Bool_t fbBinningFw = kFALSE; Int_t fiFlag; //! Switch to smx2.0/smx2.1 data-> fiFlag = 0 for 2.0 and fiFlag = 1 for 2.1 @@ -89,7 +98,11 @@ class CbmMcbm2018UnpackerAlgoMuch : public CbmStar2019Algo<CbmMuchBeamTimeDigi> /// User settings: Data correction parameters Double_t fdTimeOffsetNs; std::vector< Double_t > fvdTimeOffsetNsAsics; + //std::vector< Int_t > fviFebAddress; //! Much address for each FEB, [ NbDpb * NbCrobPerDpb * NbFebsPerCrob ] + Bool_t fbUseChannelMask; + std::vector< std::vector< bool > > fvvbMaskedChannels; //! Vector of channel masks, [ NbFeb ][ NbCHanInFeb ], used only if fbUseChannelMask is true + UInt_t fdAdcCut; /// Constants static const Int_t kiMaxNbFlibLinks = 32; diff --git a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoTof.cxx b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoTof.cxx index 6825320382ef4a97633daea66b9335725b650cd0..d44b6a1966816a97438f79e5c53125c2e6845653 100644 --- a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoTof.cxx +++ b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoTof.cxx @@ -121,6 +121,10 @@ CbmMcbm2018UnpackerAlgoTof::~CbmMcbm2018UnpackerAlgoTof() { fvvmEpSupprBuffer[ uGdpb ].clear(); } // for( UInt_t uGdpb = 0; uGdpb < fuNrOfGdpbs; ++uGdpb ) + if( nullptr != fParCList ) + delete fParCList; + if( nullptr != fUnpackPar ) + delete fUnpackPar; } // ------------------------------------------------------------------------- @@ -474,6 +478,8 @@ Bool_t CbmMcbm2018UnpackerAlgoTof::InitParameters() { if( 0 == uCh % 8 ) sPrintout += "\n"; + if( 0 == uCh % fuNrOfChannelsPerGdpb ) + sPrintout += Form( "\n Gdpb %u\n", uCh / fuNrOfChannelsPerGdpb ); sPrintout += Form(" 0x%08x", fviRpcChUId[ uCh ] ); } // for( UInt_t i = 0; i < uNrOfChannels; ++i) LOG(info) << sPrintout; @@ -720,6 +726,8 @@ Bool_t CbmMcbm2018UnpackerAlgoTof::ProcessMs( const fles::Timeslice& ts, size_t messageType = pMess[ uIdx ].getMessageType(); fuGet4Id = fUnpackPar->ElinkIdxToGet4Idx( pMess[ uIdx ].getGdpbGenChipId() ); + if( fuDiamondDpbIdx == fuCurrDpbIdx || 0x90 == fuCurrentMsSysId ) + fuGet4Id = pMess[ uIdx ].getGdpbGenChipId(); fuGet4Nr = (fuCurrDpbIdx * fuNrOfGet4PerGdpb) + fuGet4Id; if( fuNrOfGet4PerGdpb <= fuGet4Id && diff --git a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskMuch.cxx b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskMuch.cxx index f5d7e82a74e3271b14fcbe78a74c73cf826a491f..248817824bc312734c67c2641027735d19765ea6 100644 --- a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskMuch.cxx +++ b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskMuch.cxx @@ -35,6 +35,7 @@ CbmMcbm2018UnpackerTaskMuch::CbmMcbm2018UnpackerTaskMuch( UInt_t /*uNbGdpb*/ ) : CbmMcbmUnpack(), fbMonitorMode( kFALSE ), fbWriteOutput( kTRUE ), + fvChanMasks(), fulTsCounter( 0 ), fUnpackerAlgo( nullptr ) { @@ -142,6 +143,11 @@ Bool_t CbmMcbm2018UnpackerTaskMuch::InitContainers() fUnpackerAlgo->SetMonitorMode( fbMonitorMode ); + for( std::vector< MuchFebChanMask >::iterator it = fvChanMasks.begin(); + it < fvChanMasks.end(); + ++it ) + fUnpackerAlgo->MaskNoisyChannel( (*it).uFeb, (*it).uChan, (*it).bMasked ); + return initOK; } @@ -254,4 +260,23 @@ void CbmMcbm2018UnpackerTaskMuch::EnableAsicType( Int_t fiFlag ) { fUnpackerAlgo->EnableAsicType( fiFlag ); } + +void CbmMcbm2018UnpackerTaskMuch::SetBinningFwFlag( Bool_t bEnable ) +{ + fUnpackerAlgo->SetBinningFwFlag( bEnable ); +} + +void CbmMcbm2018UnpackerTaskMuch::MaskNoisyChannel( UInt_t uFeb, UInt_t uChan, Bool_t bMasked ) +{ + + fvChanMasks.push_back( MuchFebChanMask{ uFeb, uChan, bMasked } ); + +} + +void CbmMcbm2018UnpackerTaskMuch::SetAdcCut( UInt_t uAdc ) +{ + fUnpackerAlgo->SetAdcCut( uAdc ); +} + + ClassImp(CbmMcbm2018UnpackerTaskMuch) diff --git a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskMuch.h b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskMuch.h index eb1a47dc164b09b68b464684e53ce0bd44b9a56f..967e3b9eaf17a7d66905e525829194816609ca78 100644 --- a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskMuch.h +++ b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskMuch.h @@ -17,6 +17,13 @@ class CbmMcbm2018UnpackerAlgoMuch; //class TClonesArray; +struct MuchFebChanMask +{ + UInt_t uFeb; + UInt_t uChan; + Bool_t bMasked; +}; + class CbmMcbm2018UnpackerTaskMuch : public CbmMcbmUnpack { public: @@ -51,8 +58,16 @@ class CbmMcbm2018UnpackerTaskMuch : public CbmMcbmUnpack void SetTimeOffsetNsAsic( UInt_t uAsicIdx, Double_t dOffsetIn = 0.0 ); void EnableAsicType( Int_t fiFlag = 0 ); + + /// => Quick and dirty hack for binning FW!!! + void SetBinningFwFlag( Bool_t bEnable = kTRUE ); + /// Task settings void SetWriteOutputFlag( Bool_t bFlagIn ) { fbWriteOutput = bFlagIn; } + //Masking Noisy Channels + void MaskNoisyChannel( UInt_t uFeb, UInt_t uChan, Bool_t bMasked = kTRUE ); + /// ADC cut + void SetAdcCut( UInt_t uAdc ); private: /// Control flags @@ -60,6 +75,9 @@ class CbmMcbm2018UnpackerTaskMuch : public CbmMcbmUnpack Bool_t fbDebugMonitorMode; //! Switch ON the filling of a additional set of histograms Bool_t fbWriteOutput; //! If ON the output TClonesArray of digi is written to disk + /// Temporary storage of user parameters + std::vector< MuchFebChanMask > fvChanMasks; + /// Statistics & first TS rejection uint64_t fulTsCounter; diff --git a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskTof.cxx b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskTof.cxx index 666b7b108df111653a826c2b6ba6d139ebe99a6f..fdd87455b83f741963c1da6e8cbcff61719dde88 100644 --- a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskTof.cxx +++ b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskTof.cxx @@ -222,7 +222,8 @@ Bool_t CbmMcbm2018UnpackerTaskTof::DoUnpack(const fles::Timeslice& ts, size_t /* vDigi.clear(); fUnpackerAlgo->ClearVector(); - + if( kTRUE == fbMonitorMode ) + { if( kTRUE == fbSeparateArrayT0 ) { fhArraySize->Fill( fulTsCounter, fpvDigiTof->size() + fpvDigiT0->size() ); @@ -233,6 +234,7 @@ Bool_t CbmMcbm2018UnpackerTaskTof::DoUnpack(const fles::Timeslice& ts, size_t /* fhArraySize->Fill( fulTsCounter, fpvDigiTof->size() ); fhArrayCapacity->Fill( fulTsCounter, fpvDigiTof->capacity() ); } // else of if( kTRUE == fbSeparateArrayT0 ) + } // if( kTRUE == fbMonitorMode ) if( 0 == fulTsCounter % 10000 ) LOG(info) << "Processed " << fulTsCounter << "TS";