diff --git a/algo/detectors/sts/UnpackSts.cxx b/algo/detectors/sts/UnpackSts.cxx index a58a132c5594e96511ed2e4f0ba2727b91dbf00d..e1dd3dc806e695d898a71debcd8dde8e68aae02f 100644 --- a/algo/detectors/sts/UnpackSts.cxx +++ b/algo/detectors/sts/UnpackSts.cxx @@ -24,8 +24,8 @@ namespace cbm::algo { // --- Output data - vector<CbmStsDigi> digiVec = {}; - UnpackStsMonitorData moni = {}; + vector<CbmStsDigi> digiVec = {}; + UnpackStsMonitorData monitor = {}; // --- Current Timeslice time and TS_MSB epoch cycle fCurrentTsTime = tTimeslice; @@ -38,23 +38,23 @@ namespace cbm::algo // --- The first message in the MS is expected to be of type EPOCH and can be ignored if (message[0].GetMessType() != stsxyter::MessType::Epoch) { std::cout << "Error: UnpackSts: First message type is " << uint16_t(message[0].GetMessType()) << std::endl; - moni.fNumErrInvalidFirstMessage++; - return std::make_pair(digiVec, moni); + monitor.fNumErrInvalidFirstMessage++; + return std::make_pair(digiVec, monitor); } // --- The second message must be of type ts_msb if (message[1].GetMessType() != stsxyter::MessType::TsMsb) { std::cout << "Error: UnpackSts: Second message type is " << uint16_t(message[0].GetMessType()) << std::endl; - moni.fNumErrInvalidFirstMessage++; - return std::make_pair(digiVec, moni); + monitor.fNumErrInvalidFirstMessage++; + return std::make_pair(digiVec, monitor); } - ProcessTsmsbMessage(message[1]); + ProcessTsmsbMessage(message[1], monitor); // ---Â Number of messages in microslice auto msSize = msDescr.size; if (msSize % sizeof(stsxyter::Message) != 0) { - moni.fNumErrInvalidMsSize++; - return std::make_pair(digiVec, moni); + monitor.fNumErrInvalidMsSize++; + return std::make_pair(digiVec, monitor); } const uint32_t numMessages = msSize / sizeof(stsxyter::Message); @@ -65,15 +65,15 @@ namespace cbm::algo switch (message[messageNr].GetMessType()) { case stsxyter::MessType::Hit: { - ProcessHitMessage(message[messageNr], digiVec, moni); + ProcessHitMessage(message[messageNr], digiVec, monitor); break; } case stsxyter::MessType::TsMsb: { - ProcessTsmsbMessage(message[messageNr]); + ProcessTsmsbMessage(message[messageNr], monitor); break; } default: { - moni.fNumNonHitOrTsbMessage++; + monitor.fNumNonHitOrTsbMessage++; break; } @@ -81,20 +81,20 @@ namespace cbm::algo } //# Messages - return std::make_pair(digiVec, moni); + return std::make_pair(digiVec, monitor); } // -------------------------------------------------------------------------- // ----- Process hit message -------------------------------------------- void UnpackSts::ProcessHitMessage(const stsxyter::Message& message, vector<CbmStsDigi>& digiVec, - UnpackStsMonitorData& moni) const + UnpackStsMonitorData& monitor) const { // --- Check eLink and get parameters uint16_t elink = message.GetLinkIndexHitBinning(); if (elink >= fParams.fElinkParams.size()) { - moni.fNumErrElinkOutOfRange++; + monitor.fNumErrElinkOutOfRange++; return; } const UnpackStsElinkPar& elinkPar = fParams.fElinkParams.at(elink); @@ -111,32 +111,25 @@ namespace cbm::algo channel = numChansPerModule - message.GetHitChannel() + 1; } - // --- Time stamp - // --- Expand to full Unix time in clock cycles - uint64_t timeCc = message.GetHitTimeBinning() + fCurrentEpochTime; - if (timeCc >> 59 != 0) { // avoid overflow in 64 bit // TODO: Hard-coded number! - moni.fNumErrTimestampOverflow++; - return; - } - // --- Convert time into ns - uint64_t timeNs = (timeCc * fkClockCycleNom + fkClockCycleDen / 2) / fkClockCycleDen; + // --- Convert time stamp from clock cycles to ns + uint64_t messageTime = (message.GetHitTimeBinning() * fkClockCycleNom + fkClockCycleDen / 2) / fkClockCycleDen; + // --- Expand to time within timeslice + messageTime += fCurrentEpochTime; // --- Correct ASIC-wise offsets - timeNs -= elinkPar.fTimeOffset; - // --- Calculate time relative to timeslice - timeNs -= fCurrentTsTime; + messageTime -= elinkPar.fTimeOffset; // --- TODO: Add walk correction (depends on ADC) // --- Charge double charge = elinkPar.fAdcOffset + (message.GetHitAdc() - 1) * elinkPar.fAdcGain; // --- Create output digi - digiVec.emplace_back(address, channel, timeNs, charge); + digiVec.emplace_back(address, channel, messageTime, charge); } // -------------------------------------------------------------------------- // ----- Process an epoch (TS_MSB) message ------------------------------ - void UnpackSts::ProcessTsmsbMessage(const stsxyter::Message& message) + void UnpackSts::ProcessTsmsbMessage(const stsxyter::Message& message, UnpackStsMonitorData& monitor) { auto epoch = message.GetTsMsbValBinning(); @@ -145,8 +138,16 @@ namespace cbm::algo if (epoch < fCurrentEpoch) fCurrentCycle++; // --- Update current epoch - fCurrentEpoch = epoch; - fCurrentEpochTime = (fCurrentCycle * fkEpochsPerCycle + epoch) * fkEpochLength; + fCurrentEpoch = epoch; + uint64_t epochTimeInCc = (fCurrentCycle * fkEpochsPerCycle + epoch) * fkEpochLength; + if (epochTimeInCc >> 59 != 0) { // avoid overflow in 64 bit // TODO: Hard-coded number! + monitor.fNumErrTimestampOverflow++; + return; + } + + // --- Calculate epoch time in ns relative to timeslice start time + fCurrentEpochTime = (epochTimeInCc * fkClockCycleNom + fkClockCycleDen / 2) / fkClockCycleDen; + fCurrentEpochTime -= fCurrentTsTime; } // -------------------------------------------------------------------------- diff --git a/algo/detectors/sts/UnpackSts.h b/algo/detectors/sts/UnpackSts.h index c5e5aba6e2f11c4ebb28ab3254d73708c566e5ee..96e3dd483448b11d642a7926870c3977758171aa 100644 --- a/algo/detectors/sts/UnpackSts.h +++ b/algo/detectors/sts/UnpackSts.h @@ -108,15 +108,16 @@ namespace cbm::algo /** @brief Process a hit message ** @param message SMX message (32-bit word) ** @param digiVec Vector to append the created digi to + ** @param monitor Reference to monitor object **/ void ProcessHitMessage(const stsxyter::Message& message, std::vector<CbmStsDigi>& digiVec, - UnpackStsMonitorData& moni) const; + UnpackStsMonitorData& monitor) const; /** @brief Process an epoch message (TS_MSB) ** @param message SMX message (32-bit word) - ** @param digiVec Vector to append the created digi to + ** @param monitor Reference to monitor object **/ - void ProcessTsmsbMessage(const stsxyter::Message& message); + void ProcessTsmsbMessage(const stsxyter::Message& message, UnpackStsMonitorData& monitor); private: // members diff --git a/core/data/raw/StsXyterMessage.h b/core/data/raw/StsXyterMessage.h index 903e0436e68a1c70c7cddf9b0914a3c5c03a6d7a..9a9fff1c2a81c0f96838abef43c6e7f714ccf491 100644 --- a/core/data/raw/StsXyterMessage.h +++ b/core/data/raw/StsXyterMessage.h @@ -160,7 +160,8 @@ namespace stsxyter static constexpr uint32_t kulClockCycleDen = 8; ///< Clock cycle denominator, equivalent to 2*160 MHz clock static constexpr double kdClockCycleNs = static_cast<double>(kulClockCycleNom) / kulClockCycleDen; // ns, not rounded - static const uint32_t kuHitNbTsBinsBinning = 1 << 10; + // 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>(kuTsMsbNbTsBinsBinning) * static_cast<uint64_t>(kuHitNbTsBinsBinning); diff --git a/reco/tasks/CbmSourceTs.cxx b/reco/tasks/CbmSourceTs.cxx index ccc6ba59513589c53793923a477e9e6f28e1fe8f..f5c89275a6b561db982688c9e721f66b6cdc59aa 100644 --- a/reco/tasks/CbmSourceTs.cxx +++ b/reco/tasks/CbmSourceTs.cxx @@ -9,6 +9,8 @@ #include <FairSource.h> #include <Logger.h> +#include <iostream> + using fles::Timeslice; using std::string; @@ -52,12 +54,14 @@ Bool_t CbmSourceTs::Init() // ----- Read one time slice from archive --------------------------------- Int_t CbmSourceTs::ReadEvent(UInt_t) { + std::cout << std::endl; fFlesTs = fFlesSource->get(); if (!fFlesTs) { LOG(info) << "SourceTs: End of archive reached; stopping run."; return 1; } - LOG(info) << "SourceTs: Reading time slice " << fNumTs << " (index " << fFlesTs->index() << ")"; + LOG(info) << "SourceTs: Reading time slice " << fNumTs << " (index " << fFlesTs->index() + << ") at t = " << fFlesTs->start_time() << " ns"; fNumTs++; return 0; } diff --git a/reco/tasks/CbmTaskUnpack.cxx b/reco/tasks/CbmTaskUnpack.cxx index 32a6c7693bf0ea062be23602428e31267fd72a72..ecca0e5e8884e0354ca259ed18d1faab93ddb8e3 100644 --- a/reco/tasks/CbmTaskUnpack.cxx +++ b/reco/tasks/CbmTaskUnpack.cxx @@ -74,13 +74,14 @@ void CbmTaskUnpack::Exec(Option_t*) uint64_t numComp = timeslice->num_components(); uint64_t numCompUsed = 0; - LOG(info) << GetName() << ": TS " << tsIndex << " at t = " << tsTime << ", components " << numComp; - // --- Component loop for (uint64_t comp = 0; comp < numComp; comp++) { uint8_t systemId = timeslice->descriptor(comp, 0).sys_id; if (systemId == static_cast<uint8_t>(fles::SubsystemIdentifier::STS)) { + uint16_t equipmentId = timeslice->descriptor(comp, 0).eq_id; + auto algoIt = fAlgoSts.find(equipmentId); + assert(algoIt != fAlgoSts.end()); // --- Component log size_t numDigisInComp = 0; @@ -91,7 +92,7 @@ void CbmTaskUnpack::Exec(Option_t*) for (uint64_t mslice = 0; mslice < numMsInComp; mslice++) { auto msDescriptor = timeslice->descriptor(comp, mslice); auto msContent = timeslice->content(comp, mslice); - auto result = fAlgoSts[comp](msContent, msDescriptor, tsTime); + auto result = (algoIt->second)(msContent, msDescriptor, tsTime); LOG(debug1) << GetName() << ": Component " << comp << ", microslice " << mslice << ", digis " << result.first.size() << ", errors " << result.second.fNumNonHitOrTsbMessage << " | " << result.second.fNumErrElinkOutOfRange << " | " << result.second.fNumErrInvalidFirstMessage @@ -105,8 +106,8 @@ void CbmTaskUnpack::Exec(Option_t*) } //# microslice compTimer.Stop(); - LOG(info) << GetName() << ": Component " << comp << ", microslices " << numMsInComp << ", digis " - << numDigisInComp << ", CPU time " << compTimer.CpuTime() * 1000. << " ms"; + LOG(debug) << GetName() << ": Component " << comp << ", microslices " << numMsInComp << ", digis " + << numDigisInComp << ", CPU time " << compTimer.CpuTime() * 1000. << " ms"; numCompUsed++; numDigis += numDigisInComp; numMs += numMsInComp; @@ -204,16 +205,14 @@ InitStatus CbmTaskUnpack::Init() // TODO: Add parameters for time and ADC calibration par->fElinkParams.push_back(elinkPar); } - cbm::algo::UnpackSts algo; - algo.SetParams(std::move(par)); - fAlgoSts.push_back(algo); + fAlgoSts[equip].SetParams(std::move(par)); LOG(info) << GetName() << ": configured equipment " << equip << " with " << numElinks << " elinks"; } //# equipments LOG(info) << GetName() << ": configured " << fAlgoSts.size() << " unpacker algorithms for STS."; + LOG(debug) << "Readout map:" << fStsConfig.PrintReadoutMap(); LOG(info) << "=================================================="; std::cout << std::endl; - LOG(info) << "Readout map:" << fStsConfig.PrintReadoutMap(); return kSUCCESS; } diff --git a/reco/tasks/CbmTaskUnpack.h b/reco/tasks/CbmTaskUnpack.h index 12c9e2fa3121ab239fd92a64738044a36404b5d7..9d5dbbd924c502e162302460457ba6bf9ae0e3b6 100644 --- a/reco/tasks/CbmTaskUnpack.h +++ b/reco/tasks/CbmTaskUnpack.h @@ -67,8 +67,8 @@ private: // methods private: // members - CbmSourceTs* fSource = nullptr; - std::vector<cbm::algo::UnpackSts> fAlgoSts = {}; //! + CbmSourceTs* fSource = nullptr; + std::map<uint16_t, cbm::algo::UnpackSts> fAlgoSts = {}; cbm::algo::StsReadoutConfig fStsConfig {}; size_t fNumTs = 0; size_t fNumMs = 0;