diff --git a/algo/detectors/trd2d/UnpackMS.cxx b/algo/detectors/trd2d/UnpackMS.cxx index 24fb88e6656fb77fdd65823a4d8a2edfe362eb66..9851cd5d1235ea3eba74fbfe5f52e75d4542fb0f 100644 --- a/algo/detectors/trd2d/UnpackMS.cxx +++ b/algo/detectors/trd2d/UnpackMS.cxx @@ -187,14 +187,9 @@ namespace cbm::algo::trd2d MsContext ctx = {}; - // define time wrt start of time slice in TRD/FASP clks [80 MHz]. Contains: - // - relative offset of the MS wrt the TS - // - FASP epoch offset for current CROB - // - TRD2D system offset wrt to experiment time (e.g. Bmon) - uint64_t time = uint64_t((msDescr.idx - tTimeslice - fParams.fSystemTimeOffset) / 12.5); - - // Get parameters for current eq id. - //const uint8_t crob_id = fParams.fEqId; + // define time wrt start of time slice in TRD/FASP clks [80 MHz]. + uint64_t time = uint64_t((msDescr.idx - tTimeslice) / 25); // guaranteed by CBM-DAQ + time <<= 1; // time expressed in 12.5 ns clks // Get the number of complete words in the input MS buffer. const uint32_t nwords = msDescr.size / 4; @@ -280,7 +275,7 @@ namespace cbm::algo::trd2d // No need to extra check double r, t; int32_t dt; - const int32_t dtime = (*id).GetTimeDAQ() - lTime; + const int32_t dtime = (*id).GetTime() - lTime; bool use(false); if (abs(dtime) < 5) { // test message part of (last) digi @@ -291,7 +286,7 @@ namespace cbm::algo::trd2d } else if (lchT && t < 0.1) { // set T charge on an empty slot (*id).SetCharge(lchT, r, +dtime); - (*id).SetTimeDAQ(uint64_t((*id).GetTimeDAQ() - dtime)); + (*id).SetTime(lTime); use = true; } } @@ -343,6 +338,12 @@ namespace cbm::algo::trd2d // reset flags as they were used only to mark the correctly setting of the charge/digi (*id).SetFlag(0, false); (*id).SetFlag(1, false); + /** Convert global time from clk temporary representation to the finale version in [ns] + * Correct the time with the system time offset which is derived in calibration.*/ + uint64_t gtime = (*id).GetTime() * fAsicClockPeriod; + gtime >>= 1; + if (gtime >= uint64_t(fParams.fSystemTimeOffset)) gtime -= fParams.fSystemTimeOffset; + (*id).SetTime(gtime); outputDigis.emplace_back(std::move((*id))); } // clear digi buffer wrt the digi which was forwarded to higher structures @@ -369,11 +370,16 @@ namespace cbm::algo::trd2d Result_t result = {}; MsContext ctx = {}; - // define time wrt start of time slice in TRD/FASP clks [80 MHz]. Contains: - // - relative offset of the MS wrt the TS - // - FASP epoch offset for current CROB - // - TRD2D system offset wrt to experiment time - uint64_t time = uint64_t((msDescr.idx - tTimeslice - fParams.fSystemTimeOffset) * fAsicClockFreq); + // // define time wrt start of time slice in TRD/FASP clks [80 MHz]. Contains: + // // - relative offset of the MS wrt the TS + // // - FASP epoch offset for current CROB + // // - TRD2D system offset wrt to experiment time + // uint64_t time = uint64_t((msDescr.idx - tTimeslice - fParams.fSystemTimeOffset) * fAsicClockFreq); + + //define the time in run as function of CBM 40MHz clk + uint64_t timeClk = (msDescr.idx - tTimeslice) / 25; + //convert to TRD2D 80MHz clk + timeClk <<= 1; // Get the number of complete words in the input MS buffer. const uint32_t nwords = msDescr.size / 4; @@ -399,12 +405,12 @@ namespace cbm::algo::trd2d if (ctx.fMess.ch == 0) { // check word integrity // clear buffer if (vMess.size()) { - pushDigis(vMess, time, ctx); + pushDigis(vMess, timeClk, ctx); } vMess.clear(); lFaspOld = 0xff; - time += FASP_EPOCH_LENGTH; + timeClk += FASP_EPOCH_LENGTH; } else { L_(error) << "FASP message[Epoch] with wrong signature."; @@ -416,7 +422,7 @@ namespace cbm::algo::trd2d // PROCESS DATA MESSAGES // clear buffer when switching to other FASP if (ctx.fMess.fasp != lFaspOld) { - if (vMess.size()) pushDigis(vMess, time, ctx); + if (vMess.size()) pushDigis(vMess, timeClk, ctx); vMess.clear(); lFaspOld = ctx.fMess.fasp; } @@ -432,6 +438,12 @@ namespace cbm::algo::trd2d for (uint16_t ipad(0); ipad < NFASPMOD * NFASPPAD; ipad++) { if (!ctx.fRobDigi[ipad].size()) continue; for (auto id : ctx.fRobDigi[ipad]) { + /** Convert global time from clk temporary representation to the finale version in [ns] + * Correct the time with the system time offset which is derived in calibration.*/ + uint64_t gtime = id.GetTime() * fAsicClockPeriod; + gtime >>= 1; + if (gtime >= uint64_t(fParams.fSystemTimeOffset)) gtime -= fParams.fSystemTimeOffset; + id.SetTime(gtime); outputDigis.emplace_back(std::move(id)); } } @@ -462,7 +474,7 @@ namespace cbm::algo::trd2d if (calPar.noise.fSignalThres && imess.data <= calPar.noise.fSignalThres) continue; const uint32_t pad = mch / 2; const bool hasPairingR = bool(chPar.fPadAddress > 0); - const uint64_t lTime = time + calPar.fDaqOffset + imess.tlab; + const uint64_t lTime = time + imess.tlab + calPar.fDaqOffset; const uint16_t sgn = uint16_t((imess.data - fParams.fRefSignal) * calPar.fGainFee - calPar.fBaseline + fParams.fRefSignal); const uint16_t lchR = hasPairingR ? sgn : 0; @@ -482,7 +494,7 @@ namespace cbm::algo::trd2d // No need to extra check double r, t; int32_t dt; - const int32_t dtime = id.GetTimeDAQ() - lTime; + const int32_t dtime = id.GetTime() - lTime; bool use(false); if (abs(dtime) < 5) { // test message part of (last) digi r = id.GetCharge(t, dt); @@ -492,7 +504,7 @@ namespace cbm::algo::trd2d } else if (lchT && t < 0.1) { // set T charge on an empty slot id.SetCharge(lchT, r, +dtime); - id.SetTimeDAQ(uint64_t(id.GetTimeDAQ() - dtime)); + id.SetTime(lTime); use = true; } } diff --git a/algo/detectors/trd2d/UnpackMS.h b/algo/detectors/trd2d/UnpackMS.h index 8bf64c43c166b543774f1c821029b01db7511a42..b09536dfde21d098ca73e1cc24046f6441193f81 100644 --- a/algo/detectors/trd2d/UnpackMS.h +++ b/algo/detectors/trd2d/UnpackMS.h @@ -44,6 +44,9 @@ namespace cbm::algo::trd2d kNone }; + /** @brief Clock period of FASP 12.5ns. Use 25ns follow by division by 2*/ + static constexpr uint fAsicClockPeriod = 25; + /** @brief Data structure for unpacking the FASP word */ // Constants /** @brief Bytes per FASP frame stored in the microslices (32 bits words) @@ -308,9 +311,6 @@ namespace cbm::algo::trd2d bool pushDigis(std::vector<FaspMessage> messages, const uint64_t time, MsContext& ctx) const; UnpackPar fParams = {}; ///< Parameter container - - /** @brief Clock frequency of FASP in 0.08 GHz. HW also supports 0.04 GHz*/ - static constexpr float fAsicClockFreq = 0.08; }; } // namespace cbm::algo::trd2d diff --git a/core/data/trd/CbmTrdDigi.cxx b/core/data/trd/CbmTrdDigi.cxx index 88f5b183d591d1889f75af62f00f5c0b096f3793..67196924971083fe371b38931d4eaffe6fb68c34 100644 --- a/core/data/trd/CbmTrdDigi.cxx +++ b/core/data/trd/CbmTrdDigi.cxx @@ -251,22 +251,6 @@ void CbmTrdDigi::SetFlag(const int32_t iflag, bool set) CLRBIT(fInfo, fgkFlgOffset + iflag); } -//_________________________________________________________________________________ -void CbmTrdDigi::SetTime(double t) -{ - switch (GetType()) { - case eCbmTrdAsicType::kFASP: { - fTime = uint64_t(ceil(t / Clk(GetType()))); - break; - } - case eCbmTrdAsicType::kSPADIC: { - fTime = static_cast<uint64_t>(t); - break; - } - case eCbmTrdAsicType::kNTypes: return; - } -} - //_________________________________________________________________________________ void CbmTrdDigi::SetTimeOffset(int8_t t) { diff --git a/core/data/trd/CbmTrdDigi.h b/core/data/trd/CbmTrdDigi.h index 664e0cfcb3c9588d01c89a3374a1f68a3bbd19dd..0e50f16088d836843d677d44c36412dbd3e850de 100644 --- a/core/data/trd/CbmTrdDigi.h +++ b/core/data/trd/CbmTrdDigi.h @@ -54,6 +54,7 @@ public: * \param[in] chargeT Charge for tilt pad parring. * \param[in] chargeR Charge for rectangle pad parring. * \param[in] time Absolute time [ASIC clocks]. + * \sa CbmTrdModuleSim2D::AddDigi(), cbm::algo::trd2d::UnpackMS::pushDigis(), [legacy] CbmTrdUnpackFaspAlgo::pushDigis() */ CbmTrdDigi(int32_t padChNr, float chargeT, float chargeR, uint64_t time); /** @@ -137,7 +138,6 @@ public: **/ static ECbmModuleId GetSystem() { return ECbmModuleId::kTrd; } - /** @brief Class name (static) ** @return CbmTrdDigi **/ @@ -149,16 +149,13 @@ public: static const char* GetBranchName() { return "TrdDigi"; } - /** \brief Getter for physical time [ns]. Accounts for clock representation of each ASIC. In SPADIC case physical time is already stored in fTime. */ - double GetTime() const - { - return (GetType() == eCbmTrdAsicType::kFASP) ? fTime * fgClk[static_cast<size_t>(GetType())] : fTime; - } - /** \brief Getter for global DAQ time [clk]. Differs for each ASIC. In FASP case DAQ time is already stored in fTime.*/ - uint64_t GetTimeDAQ() const - { - return (GetType() == eCbmTrdAsicType::kFASP) ? fTime : fTime / fgClk[static_cast<size_t>(GetType())]; - } + /** \brief Getter for physical time [ns]. Accounts for clock representation of each ASIC. In SPADIC case physical time is already stored in fTime. + * Applies also to FASP starting with mCBM2025/02 (\sa FinalizeTime()) + */ + double GetTime() const { return fTime; } + /** \brief Getter for global DAQ time [clk]. Differs for each ASIC. [In FASP case DAQ time is already stored in fTime. - to be removed] + */ + uint64_t GetTimeDAQ() const { return fTime / fgClk[static_cast<size_t>(GetType())]; } /** \brief Channel trigger type. SPADIC specific see CbmTrdTriggerType*/ int32_t GetTriggerType() const { return (fInfo >> fgkTrgOffset) & 0x3; } @@ -217,10 +214,17 @@ public: { if (GetType() == eCbmTrdAsicType::kFASP) SetFlag(kFlag2, set); } - /** \brief Set global digi time (ns)*/ - void SetTime(double t); - /** \brief Set global digi time (clk)*/ - void SetTimeDAQ(uint64_t t) { fTime = t; } + /** \brief Set global digi time (ns) + * !! Use this function if you know what you are doing ! + * \sa CbmTrdFasp::WriteDigi(), + * \sa cbm::algo::trd2d::UnpackMS::operator(), + * \sa cbm::algo::trd2d::UnpackMS::pushDigis(), + * \sa cbm::algo::trd2d::UnpackMS::FinalizeComponent() + * \sa CbmTrdUnpackFaspAlgo::unpack(), + * \sa CbmTrdUnpackFaspAlgo::pushDigis(), + * \sa CbmTrdUnpackFaspAlgo::FinalizeComponent() + */ + void SetTime(double t) { fTime = static_cast<uint64_t>(t); } /** \brief Set time offset of rectangular to tilt pads for FASP (clk)*/ void SetTimeOffset(int8_t t); /** \brief Set digi trigger type */ @@ -267,7 +271,7 @@ protected: uint32_t fInfo = 0; //< pad address and extra information uint32_t fCharge = 0; //< measured charge. For SPADIC is int32_t(charge*1eN) where N is the precission while //< for FASP it contains the R and T charges each on 12bits and the time difference between R and T pads in CLK (8 bits). - uint64_t fTime = 0; //< global time of the digi: For SPADIC in ns, for FASP in ASIC clock + uint64_t fTime = 0; //< global time of the digi: For SPADIC & FASP in ns /** * @brief clock length in ns for acquisition diff --git a/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.cxx b/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.cxx index 17ab8334de8ed1dafdc927efa274f74a7eab1c90..9885486b6cb55126bd53a1ad8f4e8a201101dea6 100644 --- a/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.cxx +++ b/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.cxx @@ -171,7 +171,7 @@ bool CbmTrdUnpackFaspAlgo::pushDigis(std::vector<CbmTrdUnpackFaspAlgo::CbmTrdFas // No need to extra check Double_t r, t; Int_t dt; - const Int_t dtime = (*id).GetTimeDAQ() - lTime; + const Int_t dtime = (*id).GetTime() - lTime; bool use(false); if (TMath::Abs(dtime) < 5) { // test message part of (last) digi @@ -182,7 +182,7 @@ bool CbmTrdUnpackFaspAlgo::pushDigis(std::vector<CbmTrdUnpackFaspAlgo::CbmTrdFas } else if (lchT && t < 0.1) { // set T charge on an empty slot (*id).SetCharge(lchT, r, +dtime); - (*id).SetTimeDAQ(ULong64_t((*id).GetTimeDAQ() - dtime)); + (*id).SetTime(lTime); use = true; } } @@ -259,6 +259,11 @@ void CbmTrdUnpackFaspAlgo::FinalizeComponent() // reset flags as they were used only to mark the correctly setting of the charge/digi (*id).SetFlag(0, false); (*id).SetFlag(1, false); + /** Convert global time from clk temporary representation to the finale version in [ns] + * Correct the time with the system time offset which is derived in calibration.*/ + uint64_t gtime = (*id).GetTime() * 12.5; // fAsicClockPeriod; + if (gtime >= uint64_t(fSystemTimeOffset)) gtime -= fSystemTimeOffset; + (*id).SetTime(gtime); fOutputVec.emplace_back(std::move((*id))); } // clear digi buffer wrt the digi which was forwarded to higher structures @@ -300,7 +305,8 @@ bool CbmTrdUnpackFaspAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp } } // define time wrt start of time slice in TRD/FASP clks [80 MHz] - fTime = ULong64_t((msdesc.idx - fTsStartTime - fSystemTimeOffset) / 12.5); + fTime = uint64_t((msdesc.idx - fTsStartTime) / 25); + fTime <<= 1; // get MOD_id and ROB id from the equipment, using the comp map: eq_id -> (mod_id, rob_id) fMess->mod = fAsicSet.FindModuleByEqId(msdesc.eq_id, fMess->rob, fMess->elink);