From 15c78e786e43f577ac410913ba7c3b148ad815d3 Mon Sep 17 00:00:00 2001 From: P-A Loizeau <p.-a.loizeau@gsi.de> Date: Fri, 3 Dec 2021 19:08:44 +0100 Subject: [PATCH] In STS unpacker, fix bug in handling of TS_MSB cycles happening at edge of MS + cleanup - Replace all legacy hard-coded numerical values for the TS_MSB cycle size by a constant derived in StsXyterMessage from the data format - Remove deprecated special cases in the handling of the TS_MSB messages which are not present anymore in the current CRI data format - Do not update TS_MSB and TS_MSB cycle from the MS header when the cycle happened exactly at the end of last MS - Recompute the TS+MSB in TS offset from the MS heder only when changing the Cycle or the TS_MSB from the same header - Add static method to convert Message Type into human readable string - Slight improve/cleanup of debug printouts and debug levels Was leading to errors and a crash in mCBM 2021 run 1588 files node8_3_0123 and node8_5_0002 --- core/data/raw/StsXyterMessage.cxx | 15 +++++- core/data/raw/StsXyterMessage.h | 6 ++- .../detectors/sts/unpack/CbmStsUnpackAlgo.cxx | 53 +++++++++---------- 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/core/data/raw/StsXyterMessage.cxx b/core/data/raw/StsXyterMessage.cxx index ca0c66cd13..1d63ec3aa2 100644 --- a/core/data/raw/StsXyterMessage.cxx +++ b/core/data/raw/StsXyterMessage.cxx @@ -17,7 +17,6 @@ using namespace stsxyter; // Class own namespace // Namespaces alias //namespace sxm = stsxyter::Message; - //************************* Messages OP ************************************// //---------------------------------------------------------------------------- MessSubType Message::GetSubType() const @@ -149,6 +148,20 @@ bool Message::PrintMess(std::ostream& os, MessagePrintMask ctrl, bool bBinning) return true; } //---------------------------------------------------------------------------- +std::string Message::PrintMessType(MessType type) +{ + switch (type) { + case MessType::Dummy: return "Dummy"; + case MessType::Hit: return "Hit"; + case MessType::TsMsb: return "TsMsb"; + case MessType::Epoch: return "Epoch"; + case MessType::Status: return "Status"; + case MessType::Empty: return "Empty"; + case MessType::EndOfMs: return "EndOfMs"; + default: return "Unknown"; + } +} +//---------------------------------------------------------------------------- //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //**************************************************************************// diff --git a/core/data/raw/StsXyterMessage.h b/core/data/raw/StsXyterMessage.h index 1333545f41..05c0f9a1f4 100644 --- a/core/data/raw/StsXyterMessage.h +++ b/core/data/raw/StsXyterMessage.h @@ -40,6 +40,7 @@ namespace stsxyter Empty, EndOfMs }; + /// Non-hit Message sub-types enum class MessSubType : uint16_t { @@ -160,8 +161,9 @@ namespace stsxyter /// Binning FW adds 1 bit to TS in HIT message /// => Quick and dirty hack is a factor 2!!! static const uint32_t kuHitNbTsBinsBinning = 1 << 10; + static const uint32_t kuTsMsbNbTsBinsBinning = 1 << kusLenTsMsbValBinning; static const uint64_t kulTsCycleNbBinsBinning = - static_cast<uint64_t>(1 << kusLenTsMsbValBinning) * static_cast<uint64_t>(kuHitNbTsBinsBinning); + static_cast<uint64_t>(kuTsMsbNbTsBinsBinning) * static_cast<uint64_t>(kuHitNbTsBinsBinning); class Message { private: @@ -377,6 +379,8 @@ namespace stsxyter // ------------------------ General OP --------------------------------------- bool PrintMess(std::ostream& os, MessagePrintMask ctrl = MessagePrintMask::msg_print_Human, bool bBinning = true) const; + + static std::string PrintMessType(MessType type); }; } // namespace stsxyter #endif // STSXYTERMESSAGE_H diff --git a/reco/detectors/sts/unpack/CbmStsUnpackAlgo.cxx b/reco/detectors/sts/unpack/CbmStsUnpackAlgo.cxx index 0756228412..27f212776a 100644 --- a/reco/detectors/sts/unpack/CbmStsUnpackAlgo.cxx +++ b/reco/detectors/sts/unpack/CbmStsUnpackAlgo.cxx @@ -314,6 +314,9 @@ void CbmStsUnpackAlgo::loopMsMessages(const uint8_t* msContent, const uint32_t u for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx++) { /// Get message type const stsxyter::MessType typeMess = pMess[uIdx].GetMessType(); + + LOG(debug2) << " Msg Idx " << std::setw(6) << uIdx << " Type " << stsxyter::Message::PrintMessType(typeMess); + if (fMonitor) if (fMonitor->GetDebugMode()) { fMonitor->ProcessDebugInfo(pMess[uIdx], fuCurrDpbIdx); } switch (typeMess) { @@ -473,9 +476,9 @@ void CbmStsUnpackAlgo::processHitInfo(const stsxyter::Message& mess) && (fbDupliWithoutAdc || usRawAdc == fvvusLastAdcChan[uAsicIdx][usChan]) && fulTsMsbIndexInTs[fuCurrDpbIdx] == fvvulLastTsMsbChan[uAsicIdx][usChan]) { /// FIXME: add plots to check what is done in this rejection - LOG(debug) << "CbmStsUnpackAlgo::processHitInfo => " - << Form("Rejecting duplicate on Asic %3u channel %3u, TS %3u, ADC %2u", uAsicIdx, usChan, usRawTs, - usRawAdc); + LOG(debug1) << "CbmStsUnpackAlgo::processHitInfo => " + << Form("Rejecting duplicate on Asic %3u channel %3u, TS %3u, ADC %2u", uAsicIdx, usChan, usRawTs, + usRawAdc); if (fMonitor) fMonitor->FillDuplicateHitsAdc(uFebIdx, uChanInFeb, usRawAdc); return; @@ -601,11 +604,9 @@ void CbmStsUnpackAlgo::processTsMsbInfo(const stsxyter::Message& mess, uint32_t } if (uVal != fvulCurrentTsMsb[fuCurrDpbIdx] + 1 /// Case where we reach a normal cycle edge - && !(0 == uVal && 4194303 == fvulCurrentTsMsb[fuCurrDpbIdx]) + && !(0 == uVal && stsxyter::kuTsMsbNbTsBinsBinning == fvulCurrentTsMsb[fuCurrDpbIdx]) /// First TS_MSB in MS may jump if TS dropped by DAQ - && 1 != uMessIdx - /// case with cycle et edge of 2 MS - && !(0 == uVal && 0 == fvulCurrentTsMsb[fuCurrDpbIdx] && 2 == uMessIdx) + && !(1 == uMessIdx && 0 == uMsIdx) /// Msg 1 and 2 will be same TS_MSB if data in 1st bin && !(uVal == fvulCurrentTsMsb[fuCurrDpbIdx] && 2 == uMessIdx) /// New FW introduced TS_MSB suppression + large TS_MSB => warning only if value not increasing @@ -616,11 +617,7 @@ void CbmStsUnpackAlgo::processTsMsbInfo(const stsxyter::Message& mess, uint32_t << std::setw(5) << fvulCurrentTsMsb[fuCurrDpbIdx] << " new TsMsb " << std::setw(5) << uVal; } - /// Catch case where previous MS ended up on a TS MSB cycle as it is then - /// already updated from the MS index - if (4194303 == uVal && 1 == uMessIdx) fvulCurrentTsMsb[fuCurrDpbIdx] = 0; - else - fvulCurrentTsMsb[fuCurrDpbIdx] = uVal; + fvulCurrentTsMsb[fuCurrDpbIdx] = uVal; LOG(debug1) << " TS " << std::setw(12) << fTsIndex << " MS Idx " << std::setw(4) << uMsIdx << " Msg Idx " << std::setw(5) << uMessIdx << " DPB " << std::setw(2) << fuCurrDpbIdx << " TsMsb " << std::setw(5) @@ -672,9 +669,24 @@ void CbmStsUnpackAlgo::refreshTsMsbFields(const uint32_t imslice, const size_t m << uTsMsbCycleHeader; fvuCurrentTsMsbCycle[fuCurrDpbIdx] = uTsMsbCycleHeader; fvulCurrentTsMsb[fuCurrDpbIdx] = uTsMsbHeader; + + fulTsMsbIndexInTs[fuCurrDpbIdx] = + fvulCurrentTsMsb[fuCurrDpbIdx] + + (fvuCurrentTsMsbCycle[fuCurrDpbIdx] * static_cast<uint64_t>(1 << stsxyter::kusLenTsMsbValBinning)); + if (fulTsMsbIndexInTs[fuCurrDpbIdx] < fulTsStartInTsMsb) { + LOG(fatal) << "CbmStsUnpackAlgo::refreshTsMsbFields => " + << "Value computed from TS_MSB and TS_MSB cycle smaller than Timeslice start in TS_MSB, " + << "would lead to a negative value so it cannot be recovered!!!!" + << std::endl + /// Values Printout + << "TS_MSB: " << fvulCurrentTsMsb[fuCurrDpbIdx] << " Cycle: " << fvuCurrentTsMsbCycle[fuCurrDpbIdx] + << " Full TS_MSB: " << fulTsMsbIndexInTs[fuCurrDpbIdx] << " TS Start offset: " << fulTsStartInTsMsb; + } + fulTsMsbIndexInTs[fuCurrDpbIdx] -= fulTsStartInTsMsb; } else if (uTsMsbCycleHeader != fvuCurrentTsMsbCycle[fuCurrDpbIdx]) { - if (4194303 == fvulCurrentTsMsb[fuCurrDpbIdx]) { + if ((stsxyter::kuTsMsbNbTsBinsBinning - 1) == fvulCurrentTsMsb[fuCurrDpbIdx]) { + /// Transition at the edge of two MS, the first TS_MSB message (idx 1) will make the cycle LOG(debug) << " TS " << std::setw(12) << fTsIndex << " MS " << std::setw(12) << mstime << " MS Idx " << std::setw(4) << imslice << " Msg Idx " << std::setw(5) << 0 << " DPB " << std::setw(2) << fuCurrDpbIdx << " Old TsMsb " << std::setw(5) << fvulCurrentTsMsb[fuCurrDpbIdx] << " Old MsbCy " @@ -685,22 +697,9 @@ void CbmStsUnpackAlgo::refreshTsMsbFields(const uint32_t imslice, const size_t m << "for TS " << std::setw(12) << fTsIndex << " MS " << std::setw(12) << mstime << " MsInTs " << std::setw(3) << imslice << " ====> " << fvuCurrentTsMsbCycle[fuCurrDpbIdx] << " (cnt) VS " << uTsMsbCycleHeader << " (header)"; + fvuCurrentTsMsbCycle[fuCurrDpbIdx] = uTsMsbCycleHeader; } - fvuCurrentTsMsbCycle[fuCurrDpbIdx] = uTsMsbCycleHeader; - } - fulTsMsbIndexInTs[fuCurrDpbIdx] = - fvulCurrentTsMsb[fuCurrDpbIdx] - + (fvuCurrentTsMsbCycle[fuCurrDpbIdx] * static_cast<uint64_t>(1 << stsxyter::kusLenTsMsbValBinning)); - if (fulTsMsbIndexInTs[fuCurrDpbIdx] < fulTsStartInTsMsb) { - LOG(fatal) << "CbmStsUnpackAlgo::refreshTsMsbFields => " - << "Value computed from TS_MSB and TS_MSB cycle smaller than Timeslice start in TS_MSB, " - << "would lead to a negative value so it cannot be recovered!!!!" - << std::endl - /// Values Printout - << "TS_MSB: " << fvulCurrentTsMsb[fuCurrDpbIdx] << " Cycle: " << fvuCurrentTsMsbCycle[fuCurrDpbIdx] - << " Full TS_MSB: " << fulTsMsbIndexInTs[fuCurrDpbIdx] << " TS Start offset: " << fulTsStartInTsMsb; } - fulTsMsbIndexInTs[fuCurrDpbIdx] -= fulTsStartInTsMsb; } // ---- unpack ---- -- GitLab