From 5b16d30c711eb4ac7f6935cd68ae23d00f2592a6 Mon Sep 17 00:00:00 2001 From: Alexandru Bercuci <abercuci@niham.nipne.ro> Date: Fri, 19 Aug 2022 09:47:52 +0300 Subject: [PATCH] fix memory leak reported at https://redmine.cbm.gsi.de/issues/2570. Extend suggestions of PAL --- reco/base/CbmRecoUnpackAlgo.tmpl | 9 + .../trd/unpack/CbmTrdUnpackFaspAlgo.cxx | 203 +++++++++++------- .../trd/unpack/CbmTrdUnpackFaspAlgo.h | 54 +++-- .../trd/unpack/CbmTrdUnpackFaspConfig.cxx | 9 + .../trd/unpack/CbmTrdUnpackFaspConfig.h | 5 +- 5 files changed, 181 insertions(+), 99 deletions(-) diff --git a/reco/base/CbmRecoUnpackAlgo.tmpl b/reco/base/CbmRecoUnpackAlgo.tmpl index ad70ec00c8..595f80381d 100644 --- a/reco/base/CbmRecoUnpackAlgo.tmpl +++ b/reco/base/CbmRecoUnpackAlgo.tmpl @@ -253,6 +253,12 @@ protected: */ virtual bool unpack(const fles::Timeslice* ts, std::uint16_t icomp, UInt_t imslice) = 0; + /** + * @brief Use this function to implement additional actions to be called to finalize component if necessary. + (e.g. copy from temp buffers) + */ + virtual void FinalizeComponent() { return; }; + public: // Runtime functions @@ -433,6 +439,9 @@ public: } } + /// Give opportunity to finalize component (e.g. copy from temp buffers) if necessary + FinalizeComponent(); + auto ndigis = fOutputVec.size(); fNrCreatedDigis += ndigis; diff --git a/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.cxx b/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.cxx index e839fce3a9..19a3fdb0ca 100644 --- a/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.cxx +++ b/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.cxx @@ -47,23 +47,26 @@ CbmTrdUnpackFaspAlgo::~CbmTrdUnpackFaspAlgo() {} //_________________________________________________________________________________ Bool_t CbmTrdUnpackFaspAlgo::initParSet(FairParGenericSet* parset) { + printf("AB :: CbmTrdUnpackFaspAlgo::initParSet\n"); FairParamList parList; Int_t nModules(0); if (strcmp(parset->ClassName(), "CbmTrdParSetAsic") == 0) { CbmTrdParSetAsic* setPar = static_cast<CbmTrdParSetAsic*>(parset); for (auto did : fModuleId) { + printf("AB :: check did %d\n", did); const CbmTrdParSetAsic* setDet = static_cast<const CbmTrdParSetAsic*>(setPar->GetModuleSet(did)); if (!setDet) continue; if (setDet->GetAsicType() != Int_t(CbmTrdDigi::eCbmTrdAsicType::kFASP)) continue; if (fMonitor) fMonitor->addParam(did, setDet); nModules++; + printf("AB :: register ASIC params for module %d\n", did); std::vector<Int_t> a; setDet->GetAsicAddresses(&a); for (auto add : a) { CbmTrdParAsic* asic = (CbmTrdParAsic*) setDet->GetModulePar(add); if (asic->IsA() == CbmTrdParSpadic::Class()) continue; fAsicPar.addParam(asic); - if (VERBOSE) asic->Print(); + if (VERBOSE > 2) asic->Print(); } } // setPar->printParams(); @@ -213,7 +216,7 @@ void CbmTrdUnpackFaspAlgo::mess_prt(CbmTrdFaspContent* mess) } //_________________________________________________________________________________ -bool CbmTrdUnpackFaspAlgo::pushDigis(std::vector<CbmTrdUnpackFaspAlgo::CbmTrdFaspContent*> messes) +bool CbmTrdUnpackFaspAlgo::pushDigis(std::vector<CbmTrdUnpackFaspAlgo::CbmTrdFaspContent> messes) { UChar_t lFasp(0xff); UShort_t lchR, lchT; @@ -223,124 +226,155 @@ bool CbmTrdUnpackFaspAlgo::pushDigis(std::vector<CbmTrdUnpackFaspAlgo::CbmTrdFas CbmTrdParFasp* faspPar(nullptr); const CbmTrdParFaspChannel* chCalib(nullptr); CbmTrdParModDigi* digiPar(nullptr); + for (auto imess : messes) { if (lFasp == 0xff) { - lFasp = messes[0]->fasp; + lFasp = messes[0].fasp; // link data to the position on the padplane - if (!(faspPar = (CbmTrdParFasp*) fAsicPar.GetAsicPar(imess->mod * 1000 + lFasp))) { - LOG(error) << GetName() << "::pushDigis - Par for FASP " << (int) lFasp << " in module " << imess->mod + if (!(faspPar = (CbmTrdParFasp*) fAsicPar.GetAsicPar(fMod * 1000 + lFasp))) { + LOG(error) << GetName() << "::pushDigis - Par for FASP " << (int) lFasp << " in module " << fMod << " missing. Skip."; return false; } - if (!(digiPar = (CbmTrdParModDigi*) fDigiSet->GetModulePar(imess->mod))) { - LOG(error) << GetName() << "::pushDigis - DIGI par for module " << imess->mod << " missing. Skip."; + if (!(digiPar = (CbmTrdParModDigi*) fDigiSet->GetModulePar(fMod))) { + LOG(error) << GetName() << "::pushDigis - DIGI par for module " << fMod << " missing. Skip."; return false; } // TODO temporary add DAQ time calibration for FASPRO. // Should be absorbed in the ASIC parameter definition - if (digiPar->GetPadRow(faspPar->GetChannelAddress(imess->ch)) % 2) tdaqOffset = 3; + if (digiPar->GetPadRow(faspPar->GetChannelAddress(imess.ch)) % 2) tdaqOffset = 3; if (VERBOSE) faspPar->Print(); } - if (VERBOSE) mess_prt(imess); + if (VERBOSE) mess_prt(&imess); - pad = faspPar->GetChannelAddress(imess->ch); - chCalib = faspPar->GetChannel(imess->ch); + pad = faspPar->GetChannelAddress(imess.ch); + chCalib = faspPar->GetChannel(imess.ch); ch = 2 * pad + chCalib->HasPairingR(); - lTime = fTime + tdaqOffset + imess->tlab; + lTime = fTime + tdaqOffset + imess.tlab; lchR = 0; lchT = 0; - if (chCalib->HasPairingR()) lchR = imess->data; + if (chCalib->HasPairingR()) lchR = imess.data; else - lchT = imess->data; + lchT = imess.data; if (VERBOSE) - printf("fasp[%2d] ch[%4d / %2d] pad[%4d] row[%2d] col[%2d] %c[%4d]\n", lFasp, ch, imess->ch, pad, + printf("fasp[%2d] ch[%4d / %2d] pad[%4d] row[%2d] col[%2d] %c[%4d]\n", lFasp, ch, imess.ch, pad, digiPar->GetPadRow(pad), digiPar->GetPadColumn(pad), (chCalib->HasPairingT() ? 'T' : 'R'), lchT > 0 ? lchT : lchR); - if (fDigiBuffer.find(pad) != fDigiBuffer.end()) { + if (fDigiBuffer[fCrob][pad].size()) { // check if last digi has both R/T message components. Update if not and is within time window - auto id = fDigiBuffer[pad].rbegin(); - dtime = (*id)->GetTimeDAQ() - lTime; + auto id = fDigiBuffer[fCrob][pad].rbegin(); // Should always be valid here. + // No need to extra check + dtime = (*id).GetTimeDAQ() - lTime; bool use(false); if (TMath::Abs(dtime) < 5) { // test message part of (last) digi - r = (*id)->GetCharge(t, dt); + r = (*id).GetCharge(t, dt); if (lchR && r < 0.1) { // set R charge on an empty slot - (*id)->SetCharge(t, lchR, -dtime); + (*id).SetCharge(t, lchR, -dtime); use = true; } 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).SetCharge(lchT, r, +dtime); + (*id).SetTimeDAQ(ULong64_t((*id).GetTimeDAQ() - dtime)); use = true; } } // build digi for message when update failed if (!use) { - CbmTrdDigi* digi = new CbmTrdDigi(pad, lchT, lchR, lTime); - digi->SetAddressModule(imess->mod); - fDigiBuffer[pad].push_back(digi); - id = fDigiBuffer[pad].rbegin(); + CbmTrdDigi digi(pad, lchT, lchR, lTime); + digi.SetAddressModule(fMod); + fDigiBuffer[fCrob][pad].push_back(digi); + id = fDigiBuffer[fCrob][pad].rbegin(); } - if (id != fDigiBuffer[pad].rend()) id++; + if (id != fDigiBuffer[fCrob][pad].rend()) id++; - // update charge for previously allocated digis to account for FASPRO ADC buffering and read-out problem + // update charge for previously allocated digis to account for FASPRO ADC buffering and read-out feature use = false; - for (; id != fDigiBuffer[pad].rend(); ++id) { - r = (*id)->GetCharge(t, dt); + for (; id != fDigiBuffer[fCrob][pad].rend(); ++id) { + r = (*id).GetCharge(t, dt); if (lchR && int(r)) { // update R charge and mark on digi - (*id)->SetCharge(t, lchR, dt); - (*id)->SetFlag(1); + (*id).SetCharge(t, lchR, dt); + (*id).SetFlag(1); use = true; } else if (lchT && int(t)) { // update T charge and mark on digi - (*id)->SetCharge(lchT, r, dt); - (*id)->SetFlag(0); + (*id).SetCharge(lchT, r, dt); + (*id).SetFlag(0); use = true; } if (use) break; } } else { // init pad position in map and build digi for message - CbmTrdDigi* digi = new CbmTrdDigi(pad, lchT, lchR, lTime); - digi->SetAddressModule(imess->mod); - fDigiBuffer[pad].push_back(digi); + CbmTrdDigi digi(pad, lchT, lchR, lTime); + digi.SetAddressModule(fMod); + fDigiBuffer[fCrob][pad].push_back(digi); } - delete imess; } + messes.clear(); - // push finalized digits to the next level - for (int jd(0); jd < NFASPCH; jd += 2) { - int ipad(faspPar->GetChannelAddress(jd)); - if (fDigiBuffer.find(ipad) == fDigiBuffer.end()) continue; + return true; +} + +uint32_t CbmTrdUnpackFaspAlgo::ResetTimeslice() +{ + uint32_t uNbLostDigis = 0; + /// PAL 03/08/2022: clear internal buffer at latest between two timeslices (TS are self contained!) - for (auto id = fDigiBuffer[ipad].begin(); id != fDigiBuffer[ipad].end(); id++) { - r = (*id)->GetCharge(t, dt); + for (auto crobBuffer : fDigiBuffer) { + for (auto pad_id(0); pad_id < NFASPMOD * NFASPCH; pad_id++) { + if (!crobBuffer.second[pad_id].size()) continue; + + LOG(warn) << fName << "::ResetTimeslice - buffered digi @ CROB=" << crobBuffer.first << " / pad=" << pad_id + << " store " << crobBuffer.second[pad_id].size() << " unprocessed digi."; + uNbLostDigis += crobBuffer.second[pad_id].size(); + + crobBuffer.second[pad_id].clear(); + } + } + return uNbLostDigis; +} + +void CbmTrdUnpackFaspAlgo::FinalizeComponent() +{ + Double_t r, t; + Int_t dt; + // push finalized digits to the next level + for (uint16_t ipad(0); ipad < NFASPMOD * NFASPCH; ipad++) { + if (!fDigiBuffer[fCrob][ipad].size()) continue; + uint nIncomplete(0); + for (auto id = fDigiBuffer[fCrob][ipad].begin(); id != fDigiBuffer[fCrob][ipad].end(); id++) { + r = (*id).GetCharge(t, dt); // check if digi has all signals CORRECTED - if (((t > 0) != (*id)->IsFlagged(0)) || ((r > 0) != (*id)->IsFlagged(1))) continue; - if (fMonitor) fMonitor->FillHistos(((*id))); + if (((t > 0) != (*id).IsFlagged(0)) || ((r > 0) != (*id).IsFlagged(1))) { + nIncomplete++; + continue; + } + if (fMonitor) fMonitor->FillHistos((&(*id))); // reset flags as they were used only to mark the correctly setting of the charge/digi - (*id)->SetFlag(0, false); - (*id)->SetFlag(1, false); - fOutputVec.emplace_back(*std::move((*id))); - // clear digi buffer wrt the digi which was forwarded to higher structures - id = fDigiBuffer[ipad].erase(id); + (*id).SetFlag(0, false); + (*id).SetFlag(1, false); + fOutputVec.emplace_back(std::move((*id))); + } + // clear digi buffer wrt the digi which was forwarded to higher structures + fDigiBuffer[fCrob][ipad].clear(); + if (nIncomplete > 2) { + LOG(warn) << fName << "FinalizeComponent(" << fCrob << ") skip " << nIncomplete << " incomplete digi at pad " + << ipad << ".\n"; } } - messes.clear(); - - return true; + fCrob = 0xffff; // reset current crob id } // ---- unpack ---- bool CbmTrdUnpackFaspAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp, UInt_t imslice) { if (VERBOSE) printf("CbmTrdUnpackFaspAlgo::unpack 0x%04x %d\n", icomp, imslice); - //LOG(info) << "Component " << icomp << " connected to config CbmTrdUnpackConfig2D. Slice "<<imslice; + // LOG(info) << "Component " << icomp << " connected to config CbmTrdUnpackConfig2D. Slice "<<imslice; - uint32_t mod_id = 5; uint8_t crob_id = 0; uint16_t eq_id; bool unpackOk = true; @@ -351,14 +385,33 @@ bool CbmTrdUnpackFaspAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp if (VERBOSE) printf("time start %lu\n", static_cast<size_t>(msdesc.idx)); // define time wrt start of time slice in TRD/FASP clks [80 MHz] fTime = ULong64_t((msdesc.idx - fTsStartTime - fSystemTimeOffset) / 12.5); - eq_id = msdesc.eq_id; // read the CROB id - for (; crob_id < NCROBMOD; crob_id++) { - if (((*fCrobMap)[mod_id])[crob_id] == eq_id) break; + + // get MOD_id and CROB id from the equipment + bool mapped = false; + eq_id = msdesc.eq_id; + for (auto mod_id : fModuleId) { + for (crob_id = 0; crob_id < NCROBMOD; crob_id++) { + if (((*fCrobMap)[mod_id])[crob_id] == eq_id) break; + } + if (crob_id == NCROBMOD) continue; + + // found module-cri pair + // buffer module configuration + if (fMod == 0xffff || fMod != mod_id) { + fMod = mod_id; + if (!init()) { + LOG(error) << GetName() << "::unpack - init mod_id=" << mod_id << " failed."; + return false; + } + } + mapped = true; + break; } - if (crob_id == NCROBMOD) { + if (!mapped) { LOG(error) << GetName() << "::unpack - CROB eq_id=" << eq_id << " not registered in the unpacker."; return false; } + if (fCrob == 0xffff) fCrob = icomp; // Get the µslice size in bytes to calculate the number of completed words auto mssize = msdesc.size; @@ -375,8 +428,8 @@ bool CbmTrdUnpackFaspAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp UChar_t lFaspOld(0xff); - vector<CbmTrdFaspContent*> vDigi; - CbmTrdFaspContent* mess(nullptr); + vector<CbmTrdFaspContent> vMess; + CbmTrdFaspContent mess; for (uint64_t j = 0; j < nwords; j++, wd++) { // // Select the appropriate conversion type of the word according to the message type // switch(mess_type(*wd)){ @@ -398,8 +451,8 @@ bool CbmTrdUnpackFaspAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp if (isaux) { if (!ch_id) { // clear buffer - if (vDigi.size()) { pushDigis(vDigi); } - vDigi.clear(); + if (vMess.size()) { pushDigis(vMess); } + vMess.clear(); if (VERBOSE) cout << boost::format(" EE : fasp_id=%02d ch_id=%02d epoch=%03d\n") % static_cast<unsigned int>(fasp_id) @@ -413,12 +466,12 @@ bool CbmTrdUnpackFaspAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp } } else { - if (fFaspMap) fasp_id = ((*fFaspMap)[mod_id])[fasp_id]; + if (fFaspMap) fasp_id = ((*fFaspMap)[fMod])[fasp_id]; if (lFaspOld != fasp_id) { // push - if (vDigi.size()) { pushDigis(vDigi); } - vDigi.clear(); + if (vMess.size()) { pushDigis(vMess); } + vMess.clear(); lFaspOld = fasp_id; } if (data & 0x1) { @@ -433,15 +486,13 @@ bool CbmTrdUnpackFaspAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp LOG(debug) << GetName() << "::unpack - Self-triggered data."; data &= 0x1fff; } - mess = new CbmTrdFaspContent; - mess->ch = ch_id; - mess->type = kData; - mess->tlab = slice; - mess->data = data >> 1; - mess->fasp = lFaspOld; - mess->mod = mod_id; - mess->crob = crob_id; - vDigi.push_back(mess); + mess.ch = ch_id; + mess.type = kData; + mess.tlab = slice; + mess.data = data >> 1; + mess.fasp = lFaspOld; + mess.crob = crob_id; + vMess.push_back(mess); } //prt_wd(*wd); } diff --git a/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.h b/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.h index 530df41b59..65a91e04e8 100644 --- a/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.h +++ b/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.h @@ -9,14 +9,14 @@ * @brief Trd FASP unpacking algorithm * @version 0.1 * @date 2021-04-21 - * + * * @copyright Copyright (c) 2021 - * - * This is the base class for the algorithmic part of the tsa data unpacking + * + * This is the base class for the algorithmic part of the tsa data unpacking * processes of the CbmTrd. - * The actual translation from tsa to digi happens in the derived classes. - * - * + * The actual translation from tsa to digi happens in the derived classes. + * + * */ #ifndef CbmTrdUnpackFaspAlgo_H @@ -45,7 +45,7 @@ class CbmTrdParSetDigi; class CbmTrdUnpackFaspAlgo : public CbmRecoUnpackAlgo<CbmTrdDigi> { public: - /** @brief Bytes per FASP frame stored in the microslices (32 bits words) + /** @brief Bytes per FASP frame stored in the microslices (32 bits words) * - DATA WORD - * ffff.ffdd dddd.dddd dddd.tttt ttta.cccc * f - FASP id @@ -56,7 +56,7 @@ public: * - EPOCH WORD - * ffff.fftt tttt.tttt tttt.tttt ttta.cccc * f - FASP id - * t - epoch index + * t - epoch index * a - word type (0) * c - channel id */ @@ -102,7 +102,7 @@ public: /** * @brief Get the requested parameter containers. - * Return the required parameter containers together with the paths to the ascii + * Return the required parameter containers together with the paths to the ascii * files to. * * @param[in] std::string geoTag as used in CbmSetup @@ -121,6 +121,9 @@ public: * @param monitor predefined unpacking monitor */ void SetMonitor(std::shared_ptr<CbmTrdUnpackFaspMonitor> monitor) { fMonitor = monitor; } + /** @brief Check and assure there are no data left-overs */ + uint32_t ResetTimeslice(); + protected: /** @brief Get message type from the FASP word */ CbmTrdFaspMessageType mess_type(uint32_t wd); @@ -130,11 +133,11 @@ protected: void mess_readEW(uint32_t wd, CbmTrdFaspContent* mess); /** @brief Print FASP message */ void mess_prt(CbmTrdFaspContent* mess); - bool pushDigis(std::vector<CbmTrdUnpackFaspAlgo::CbmTrdFaspContent*> digis); + bool pushDigis(std::vector<CbmTrdUnpackFaspAlgo::CbmTrdFaspContent> messages); /** @brief Time offset for digi wrt the TS start, expressed in 80 MHz clks. It contains: * - relative offset of the MS wrt the TS * - FASP epoch offset for current CROB - * - TRD2D system offset wrt to experiment time (e.g. T0) + * - TRD2D system offset wrt to experiment time (e.g. T0) */ ULong64_t fTime; @@ -147,7 +150,7 @@ protected: /** * @brief Additional initialisation function for all BaseR derived algorithms. * - * @return Bool_t initOk + * @return Bool_t initOk */ virtual Bool_t init() { return kTRUE; } @@ -156,26 +159,30 @@ protected: /** * @brief Handles the distribution of the hidden derived classes to their explicit functions. * - * @param parset - * @return Bool_t initOk + * @param parset + * @return Bool_t initOk */ Bool_t initParSet(FairParGenericSet* parset); /** * @brief Unpack a given microslice. - * + * * @param ts timeslice pointer * @param icomp index to the component to be unpacked * @param imslice index of the microslice to be unpacked - * @return true - * @return false - * + * @return true if all is fine + * * @remark The content of the µslice can only be accessed via the timeslice. Hence, we need to pass the pointer to the full timeslice */ bool unpack(const fles::Timeslice* ts, std::uint16_t icomp, UInt_t imslice); + /** + * @brief Finalize component (e.g. copy from temp buffers) + */ + void FinalizeComponent(); + // Constants - /** @brief Bytes per FASP frame stored in the microslices (32 bits words) + /** @brief Bytes per FASP frame stored in the microslices (32 bits words) * - DATA WORD - * ffff.ffdd dddd.dddd dddd.tttt ttta.cccc * f - FASP id @@ -186,7 +193,7 @@ protected: * - EPOCH WORD - * ffff.fftt tttt.tttt tttt.tttt ttta.cccc * f - FASP id - * t - epoch index + * t - epoch index * a - word type (0) * c - channel id */ @@ -196,10 +203,13 @@ private: void prt_wd(uint32_t w); std::map<uint32_t, uint8_t[NFASPMOD]>* fFaspMap = nullptr; ///> FASP mapping update wrt the default setting std::map<uint32_t, uint16_t[NCROBMOD]>* fCrobMap = nullptr; ///> CRI mapping setting - std::map<uint32_t, std::vector<CbmTrdDigi*>> fDigiBuffer; ///> Map of buffered digi per pad + std::map<uint16_t, std::array<std::vector<CbmTrdDigi>, NFASPMOD* NFASPCH>> fDigiBuffer = { + {{}}}; ///> Buffered digi for each pad in CROB component /** @brief Potential (online) monitor for the unpacking process */ std::shared_ptr<CbmTrdUnpackFaspMonitor> fMonitor = nullptr; - std::vector<Int_t> fModuleId; + uint16_t fCrob = 0xffff; //! current crob being processed + uint16_t fMod = 0xffff; //! current module being processed + std::vector<uint16_t> fModuleId; ///> list of modules for which there is are calibration parameters CbmTrdParSetAsic fAsicPar; CbmTrdParSetDigi* fDigiSet = nullptr; diff --git a/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.cxx b/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.cxx index 683dde77bc..9220aeef74 100644 --- a/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.cxx +++ b/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.cxx @@ -30,6 +30,15 @@ std::shared_ptr<CbmTrdUnpackFaspAlgo> CbmTrdUnpackFaspConfig::chooseAlgo() return nullptr; } +// ---- reset ---- +void CbmTrdUnpackFaspConfig::reset() +{ + uint32_t uNbLostDigis = fAlgo->ResetTimeslice(); + if (uNbLostDigis /*&& fDoLog*/) { + LOG(info) << fName << "::reset - Lost digis after processing timeslice: " << uNbLostDigis; + } +} + //_____________________________________________________________________ void CbmTrdUnpackFaspConfig::InitAlgo() { diff --git a/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.h b/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.h index 54a377eca6..25540834f5 100644 --- a/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.h +++ b/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.h @@ -78,7 +78,7 @@ public: */ void SetCrobMapping(int modAddress, uint16_t crobMap[NFASPMOD]); - /** @brief Add a monitor to the unpacker. + /** @brief Add a monitor to the unpacker. * @param value CbmTrdUnpackFaspMonitor */ void SetMonitor(std::shared_ptr<CbmTrdUnpackFaspMonitor> value) { fMonitor = value; } @@ -90,6 +90,9 @@ protected: */ virtual std::shared_ptr<CbmTrdUnpackFaspAlgo> chooseAlgo(); + /** @brief Implement additional actions to be called once per TS, e.g. needed if more than the default output vector is used. */ + virtual void reset(); + private: std::map<uint32_t, uint8_t[NFASPMOD]> fFaspMap; ///> Module address to FASP id mapping std::map<uint32_t, uint16_t[NCROBMOD]> fCrobMap; ///> Module address to CROB id mapping -- GitLab