diff --git a/algo/detectors/much/UnpackMuch.cxx b/algo/detectors/much/UnpackMuch.cxx index cd6a23445d492c2776c96eb6b465c2f3bcc6854f..ccd98924fe4c61ecef1bf883a41faa1ff111ede2 100644 --- a/algo/detectors/much/UnpackMuch.cxx +++ b/algo/detectors/much/UnpackMuch.cxx @@ -20,22 +20,25 @@ namespace cbm::algo // ---- Algorithm execution --------------------------------------------- UnpackMuch::resultType UnpackMuch::operator()(const uint8_t* msContent, const fles::MicrosliceDescriptor& msDescr, - const uint64_t tTimeslice) + const uint64_t tTimeslice) const { // --- Output data resultType result = {}; + TimeSpec time; + // --- Current Timeslice start time in epoch units. Note that it is always a multiple of epochs // --- and the epoch is a multiple of ns. const uint64_t epochLengthInNs = fkEpochLength * fkClockCycleNom / fkClockCycleDen; - fCurrentTsTime = tTimeslice / epochLengthInNs; + time.currentTsTime = tTimeslice / epochLengthInNs; // --- Current TS_MSB epoch cycle auto const msTime = msDescr.idx; // Unix time of MS in ns - fCurrentCycle = std::ldiv(msTime, fkCycleLength).quot; - fCurrentEpoch = 0; // Needed to make each MS independent of the previous! Will be updated in message 1 if MS OK - fCurrentEpochTime = 0; // Needed to make each MS independent of the previous! Will be updated in message 1 if MS OK + time.currentCycle = std::ldiv(msTime, fkCycleLength).quot; + time.currentEpoch = 0; // Needed to make each MS independent of the previous! Will be updated in message 1 if MS OK + time.currentEpochTime = + 0; // Needed to make each MS independent of the previous! Will be updated in message 1 if MS OK // ---Â Number of messages in microslice auto msSize = msDescr.size; @@ -66,7 +69,7 @@ namespace cbm::algo result.second.fNumErrInvalidFirstMessage++; return result; } - ProcessTsmsbMessage(message[1]); + ProcessTsmsbMessage(message[1], time); // --- Message loop for (uint32_t messageNr = 2; messageNr < numMessages; messageNr++) { @@ -75,11 +78,11 @@ namespace cbm::algo switch (message[messageNr].GetMessType()) { case stsxyter::MessType::Hit: { - ProcessHitMessage(message[messageNr], result.first, result.second); + ProcessHitMessage(message[messageNr], time, result.first, result.second); break; } case stsxyter::MessType::TsMsb: { - ProcessTsmsbMessage(message[messageNr]); + ProcessTsmsbMessage(message[messageNr], time); break; } default: { @@ -97,8 +100,8 @@ namespace cbm::algo // ----- Process hit message -------------------------------------------- - inline void UnpackMuch::ProcessHitMessage(const stsxyter::Message& message, vector<CbmMuchDigi>& digiVec, - UnpackMuchMonitorData& monitor) const + inline void UnpackMuch::ProcessHitMessage(const stsxyter::Message& message, const TimeSpec& time, + vector<CbmMuchDigi>& digiVec, UnpackMuchMonitorData& monitor) const { // --- Check eLink and get parameters uint16_t elink = message.GetLinkIndexHitBinning(); @@ -115,7 +118,7 @@ namespace cbm::algo uint32_t address = (elinkPar.fAddress)[channel]; // --- Expand time stamp to time within timeslice (in clock cycle) - uint64_t messageTime = message.GetHitTimeBinning() + fCurrentEpochTime; + uint64_t messageTime = message.GetHitTimeBinning() + time.currentEpochTime; // --- Convert time stamp from clock cycles to ns. Round to nearest full ns. messageTime = (messageTime * fkClockCycleNom + fkClockCycleDen / 2) / fkClockCycleDen; @@ -133,7 +136,7 @@ namespace cbm::algo // ----- Process an epoch (TS_MSB) message ------------------------------ - inline void UnpackMuch::ProcessTsmsbMessage(const stsxyter::Message& message) + inline void UnpackMuch::ProcessTsmsbMessage(const stsxyter::Message& message, TimeSpec& time) const { // The compression of time is based on the hierarchy epoch cycle - epoch - message time. // Cycles are counted from the start of Unix time and are multiples of an epoch (ts_msb). @@ -146,13 +149,13 @@ namespace cbm::algo auto epoch = message.GetTsMsbValBinning(); // --- Cycle wrap - if (epoch < fCurrentEpoch) fCurrentCycle++; + if (epoch < time.currentEpoch) time.currentCycle++; // --- Update current epoch counter - fCurrentEpoch = epoch; + time.currentEpoch = epoch; // --- Calculate epoch time in clocks cycles relative to timeslice start time - fCurrentEpochTime = (fCurrentCycle * fkEpochsPerCycle + epoch - fCurrentTsTime) * fkEpochLength; + time.currentEpochTime = (time.currentCycle * fkEpochsPerCycle + epoch - time.currentTsTime) * fkEpochLength; } // -------------------------------------------------------------------------- diff --git a/algo/detectors/much/UnpackMuch.h b/algo/detectors/much/UnpackMuch.h index 6cf45df4dac73075e3e84993c9d30b9a6327457e..477396b691d263b63c7c7447bb494bc93299f41b 100644 --- a/algo/detectors/much/UnpackMuch.h +++ b/algo/detectors/much/UnpackMuch.h @@ -100,13 +100,21 @@ namespace cbm::algo ** @return STS digi data **/ resultType operator()(const uint8_t* msContent, const fles::MicrosliceDescriptor& msDescr, - const uint64_t tTimeslice); + const uint64_t tTimeslice) const; /** @brief Set the parameter container ** @param params Pointer to parameter container **/ void SetParams(std::unique_ptr<UnpackMuchPar> params) { fParams = *(std::move(params)); } + private: // datatypes + struct TimeSpec { + uint64_t currentTsTime = 0; ///< Unix time of timeslice in units of epoch length + uint64_t currentCycle = 0; ///< Current epoch cycle + uint32_t currentEpoch = 0; ///< Current epoch number within epoch cycle + uint64_t currentEpochTime = 0; ///< Current epoch time relative to timeslice in clock cycles + }; + private: // methods /** @brief Process a hit message @@ -114,20 +122,16 @@ namespace cbm::algo ** @param digiVec Vector to append the created digi to ** @param monitor Reference to monitor object **/ - void ProcessHitMessage(const stsxyter::Message& message, std::vector<CbmMuchDigi>& digiVec, + void ProcessHitMessage(const stsxyter::Message& message, const TimeSpec& time, std::vector<CbmMuchDigi>& digiVec, UnpackMuchMonitorData& monitor) const; /** @brief Process an epoch message (TS_MSB) ** @param message SMX message (32-bit word) **/ - void ProcessTsmsbMessage(const stsxyter::Message& message); + void ProcessTsmsbMessage(const stsxyter::Message& message, TimeSpec& time) const; private: // members - uint64_t fCurrentTsTime = 0; ///< Unix time of timeslice in units of epoch length - uint64_t fCurrentCycle = 0; ///< Current epoch cycle - uint32_t fCurrentEpoch = 0; ///< Current epoch number within epoch cycle - uint64_t fCurrentEpochTime = 0; ///< Current epoch time relative to timeslice in clock cycles UnpackMuchPar fParams = {}; ///< Parameter container /** Number of TS_MSB epochs per cycle **/