diff --git a/algo/detectors/trd2d/ReadoutConfig.cxx b/algo/detectors/trd2d/ReadoutConfig.cxx index 3258171b02f4cf7e758adc311548a52ea4afd5d6..692988991454bed4ae6193b430d0a3707c45d94d 100644 --- a/algo/detectors/trd2d/ReadoutConfig.cxx +++ b/algo/detectors/trd2d/ReadoutConfig.cxx @@ -5,6 +5,7 @@ #include "ReadoutConfig.h" //#include "CbmTrdAddress.h" +#include "AlgoFairloggerCompat.h" #include <cassert> #include <iomanip> @@ -51,6 +52,16 @@ namespace cbm::algo::trd2d } // ------------------------------------------------------------------------------------ + // --- List of ASICs registered to the ROB --------------------- + std::vector<uint8_t> ReadoutConfig::GetAsicList(uint16_t equipmentId) + { + std::vector<uint8_t> result; + for (auto& entry : fChannelMap[equipmentId]) + result.push_back(entry.first); + return result; + } + // ------------------------------------------------------------------------------------ + // --- Number of Channels for a component / equipment, asic pair --------------------- size_t ReadoutConfig::GetNumChans(uint16_t equipmentId, uint16_t asicId) @@ -58,8 +69,10 @@ namespace cbm::algo::trd2d size_t result = 0; auto it = fChannelMap.find(equipmentId); if (it != fChannelMap.end()) { - if (asicId < fChannelMap[equipmentId].size()) { - result = fChannelMap[equipmentId][asicId].size(); + auto fiberMap = fChannelMap[equipmentId]; + auto jt = fiberMap.find(asicId); + if (jt != fiberMap.end()) { + result = fiberMap[asicId].size(); } } return result; @@ -67,16 +80,17 @@ namespace cbm::algo::trd2d // ------------------------------------------------------------------------------------ // --- Initialise the component mapping structure ---------------------------------- - void ReadoutConfig::InitComponentMap(const std::map<uint32_t, uint16_t[NCROBMOD]>& map) + void ReadoutConfig::InitComponentMap(const std::map<uint32_t, std::vector<uint16_t>>& map) { // Receive map (moduleId, crobId) -> (equipId) // Invert to obtain component map (equipId) -> (module iq, crob id) for (auto& entry : map) { uint16_t mod_id = entry.first; - for (uint8_t rob_id = 0; rob_id < NCROBMOD; rob_id++) { - uint16_t eq_id = entry.second[rob_id]; - if (!eq_id) continue; - fReadoutMap[eq_id] = {mod_id, rob_id}; + //for (uint8_t eq_id = 0; eq_id < NROBMOD * NELINKROB; eq_id++) { + uint8_t eq_id = 0; + for (const auto& eq_add : entry.second) { + //uint16_t eq_id = entry.second[elink_id]; + fReadoutMap[eq_add] = {mod_id, eq_id++}; } } } @@ -90,12 +104,10 @@ namespace cbm::algo::trd2d for (auto compMap : channelMap) { uint16_t equipmentId = compMap.first; uint16_t numAsics = compMap.second.size(); - fChannelMap[equipmentId].resize(numAsics); - for (auto asicMap : compMap.second) { uint16_t asicId = asicMap.first; uint16_t numChans = asicMap.second.size(); - fChannelMap[equipmentId][asicId].resize(numChans); + fChannelMap[equipmentId][asicId].resize(16); for (auto chanMap : asicMap.second) { uint16_t chanId = chanMap.first; std::tuple<int32_t, bool, uint64_t> chanPars = chanMap.second; @@ -109,14 +121,17 @@ namespace cbm::algo::trd2d // --- Mapping (equimentId, asicId, channel) -> (pad address, mask flag, daq offset) ----- - ReadoutConfig::ChanMapping ReadoutConfig::ChanMap(uint16_t equipId, uint16_t asic, uint16_t chan) + ReadoutConfig::ChanMapping ReadoutConfig::ChanMap(uint16_t equipId, uint16_t asicId, uint16_t chanId) { ChanMapping result = {-1, false, 0}; auto it = fChannelMap.find(equipId); if (it != fChannelMap.end()) { - if (asic < fChannelMap[equipId].size()) { - if (chan < fChannelMap[equipId][asic].size()) { - result = fChannelMap[equipId][asic][chan]; + auto fiberMap = fChannelMap[equipId]; + auto jt = fiberMap.find(asicId); + if (jt != fiberMap.end()) { + auto asic = fiberMap[asicId]; + if (chanId < asic.size()) { + result = asic[chanId]; } } } @@ -146,27 +161,33 @@ namespace cbm::algo::trd2d uint16_t equipmentId = comp.first; auto value = comp.second; uint16_t moduleId = value.moduleId; - uint16_t robId = value.robId; - ss << "Equipment " << equipmentId << " Module " << moduleId << " Rob " << robId << "\n"; + uint16_t fiberId = value.fiberId; + ss << "Equipment 0x" << std::hex << (int) equipmentId << " Module " << moduleId << " fiberId " << fiberId << "\n"; } ss << "\n"; for (auto asicMap : fChannelMap) { uint16_t equipmentId = asicMap.first; uint16_t numAsics = asicMap.second.size(); - ss << "\n Equipment " << equipmentId << " nAsics " << numAsics; - for (size_t asicId = 0; asicId < numAsics; asicId++) { - - uint16_t numChans = asicMap.second.at(asicId).size(); - ss << "\n Equipment " << equipmentId << " AsicId " << asicId << " nChans " << numChans; + ss << "\n Equipment 0x" << std::hex << (int) equipmentId << " nAsics " << numAsics; + + int asicCnt(0); + auto asics = asicMap.second; + for (auto asic : asics) { + int asicId = asic.first; + auto asicChs = asic.second; + uint16_t numChans = asicChs.size(); + ss << "\n " << asicCnt << " AsicId " << asicId << " nChans " << numChans; for (size_t chanId = 0; chanId < numChans; chanId++) { - auto entry = asicMap.second.at(asicId).at(chanId); - int32_t address = entry.padAddress; - bool isMasked = entry.rPairingFlag; - uint64_t daqOffset = entry.daqOffset; - ss << "\n Equipment " << equipmentId << " AsicId " << asicId << " chanID " << chanId << " pad address " - << address << " mask " << isMasked << " daq offset " << daqOffset; + auto entry = asicChs.at(chanId); + int32_t address = entry.padAddress; + bool isMasked = entry.maskFlag; + uint8_t tOffset = entry.tOffset; + uint16_t thres = entry.lThreshold; + ss << "\n chanID " << chanId << " {pad " << address << " mask " << isMasked << " time offset[clk] " + << (int) tOffset << " threshold[" << (thres > 0 ? "on" : "off") << "]}"; } + asicCnt++; } } ss << "\n"; diff --git a/algo/detectors/trd2d/ReadoutConfig.h b/algo/detectors/trd2d/ReadoutConfig.h index 4631e1c0a5b0f499df7223dd2aa15c683780b19d..a4b189c8f9d35a6f12ea07b3737e02bad9f102c6 100644 --- a/algo/detectors/trd2d/ReadoutConfig.h +++ b/algo/detectors/trd2d/ReadoutConfig.h @@ -34,22 +34,25 @@ namespace cbm::algo::trd2d public: struct CompMapping { uint16_t moduleId; - uint8_t robId; + uint8_t fiberId; CBM_YAML_FORMAT(YAML::Flow); CBM_YAML_PROPERTIES(yaml::Property(&CompMapping::moduleId, "moduleId", "Module ID"), - yaml::Property(&CompMapping::robId, "crobId", "CROB ID")); + yaml::Property(&CompMapping::fiberId, "fiberId", "Optical Fibre ID")); }; struct ChanMapping { - int32_t padAddress; - bool rPairingFlag; - uint64_t daqOffset; + int32_t padAddress; /// map pad and pairing to FASP channel + bool maskFlag; /// HW mask flag for channel + uint8_t tOffset; /// time correction in clk + uint16_t lThreshold; /// SW threshold for ringing channels CBM_YAML_FORMAT(YAML::Flow); - CBM_YAML_PROPERTIES(yaml::Property(&ChanMapping::padAddress, "padAddress", "Pad address"), - yaml::Property(&ChanMapping::rPairingFlag, "rPairingFlag", "R pairing flag"), - yaml::Property(&ChanMapping::daqOffset, "daqOffset", "DAQ offset")); + CBM_YAML_PROPERTIES( + yaml::Property(&ChanMapping::padAddress, "address", "Pad address"), + yaml::Property(&ChanMapping::maskFlag, "mask", "Channel masking flag"), + yaml::Property(&ChanMapping::tOffset, "toff", "Channel wise time offset"), + yaml::Property(&ChanMapping::lThreshold, "thres", "SW masking by threshold")); }; /** @brief Constructor **/ @@ -73,6 +76,13 @@ namespace cbm::algo::trd2d size_t GetNumAsics(uint16_t equipmentId); + /** @brief Number of ASICS of a component + ** @param Equipment ID + ** @return List of ASICS linked to the curent ROB + **/ + std::vector<uint8_t> GetAsicList(uint16_t equipmentId); + + /** @brief Number of channels of a component - ASIC pair ** @param Equipment ID ** @param ASIC ID @@ -102,7 +112,7 @@ namespace cbm::algo::trd2d std::string PrintReadoutMap(); /** @brief Initialisation of readout map **/ - void InitComponentMap(const std::map<uint32_t, uint16_t[NCROBMOD]>& crob_map); + void InitComponentMap(const std::map<uint32_t, std::vector<uint16_t>>& map); /** @brief Initialisation of channel map **/ void InitChannelMap( @@ -124,14 +134,14 @@ namespace cbm::algo::trd2d // --- TRD2D channel map // --- Map index: (equipment, asic, chan), map value: (pad address, mask flag, daq offset) - std::map<uint16_t, std::vector<std::vector<ChanMapping>>> fChannelMap = {}; //! - - CBM_YAML_PROPERTIES(yaml::Property(&ReadoutConfig::fSystemTimeOffset, "timeOffset", "System time offset for TRD2D"), - yaml::Property(&ReadoutConfig::fReadoutMap, "readoutMap", "Maps equipment to module and CROB ID", - YAML::Hex), - yaml::Property(&ReadoutConfig::fChannelMap, "channelMap", - "Maps equipment, ASIC and channel to pad address, R pairing flag and DAQ offset", - {}, YAML::Hex)); + std::map<uint16_t, std::map<uint8_t, std::vector<ChanMapping>>> fChannelMap = {}; //! + + CBM_YAML_PROPERTIES( + yaml::Property(&ReadoutConfig::fSystemTimeOffset, "timeOffset", "System time offset for TRD2D"), + yaml::Property(&ReadoutConfig::fReadoutMap, "readoutMap", "Maps equipment to module and Optical fibre Id", YAML::Hex), + yaml::Property(&ReadoutConfig::fChannelMap, "channelMap", + "Maps equipment, ASIC and channel to pad address, mask flag and DAQ offset", + YAML::Hex)); }; } // namespace cbm::algo::trd2d diff --git a/algo/detectors/trd2d/Unpack.cxx b/algo/detectors/trd2d/Unpack.cxx index c8a1ee803427197cb628b478b6e965ce7a2a51bd..f42c1851484cf6ce8822d42d2ab7ed72dcb7aaba 100644 --- a/algo/detectors/trd2d/Unpack.cxx +++ b/algo/detectors/trd2d/Unpack.cxx @@ -17,8 +17,7 @@ Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout) * eMessageVersion::kMessLegacy - refers to the version WITH digi buffering * eMessageVersion::kMess24 - refers to the version WITHOUT digi buffering */ - constexpr std::array<u8, int(eMessageVersion::kMessNoDef)> AlgoVersion = {(u8) eMessageVersion::kMessLegacy, - (u8) eMessageVersion::kMess24}; + constexpr std::array<u8, 2> AlgoVersion = {(u8) eMessageVersion::kMessLegacy, (u8) eMessageVersion::kMess24}; // Create one algorithm per component for TRD and configure it with parameters auto equipIdsTrd2d = fReadout.GetEquipmentIds(); @@ -27,42 +26,53 @@ Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout) trd2d::UnpackPar par{}; const size_t numAsics = fReadout.GetNumAsics(equip); - for (size_t asic = 0; asic < numAsics; asic++) { + auto asics = fReadout.GetAsicList(equip); + for (auto asic : asics) { trd2d::UnpackAsicPar asicPar; const size_t numChans = fReadout.GetNumChans(equip, asic); for (size_t chan = 0; chan < numChans; chan++) { trd2d::UnpackChannelPar chanPar; - auto pars = fReadout.ChanMap(equip, asic, chan); - chanPar.fPadAddress = pars.padAddress; // Pad address for channel - chanPar.fMask = pars.rPairingFlag; // Flag channel mask - chanPar.fDaqOffset = pars.daqOffset; // Time calibration parameter + auto pars = fReadout.ChanMap(equip, asic, chan); + chanPar.fPadAddress = pars.padAddress; // Pad address for channel + chanPar.fMask = pars.maskFlag; // Flag channel mask + chanPar.fDaqOffset = pars.tOffset; // Time calibration parameter + chanPar.fSignalThres = pars.lThreshold; // Threshold cut asicPar.fChanParams.push_back(chanPar); } + L_(debug) << "--- Configured asic " << (int) asic << " with " << numChans << " channels"; auto comppars = fReadout.CompMap(equip); par.fSystemTimeOffset = fReadout.GetSystemTimeOffset(); par.fModId = comppars.moduleId; - par.fRobId = comppars.robId; - par.fAsicParams.push_back(asicPar); + par.fEqAdd = equip; + par.fEqId = comppars.fiberId; + par.fAsicParams[asic] = asicPar; } + L_(debug) << "--- Configured equipment 0x" << std::hex << (int) equip << " with " << std::dec << numAsics + << " asics"; + // build all algorithms defined for data unpacking ! Why ?? (AB 25.01.15) std::unique_ptr<UnpackMSBase<CbmTrdDigi, UnpackMonitorData, UnpackAuxData>> algo; for (auto ver : AlgoVersion) { switch (ver) { case (int) eMessageVersion::kMessLegacy: - algo = std::make_unique<UnpackMS<(u8) eMessageVersion::kMessLegacy>>(par); + algo = std::make_unique<UnpackMS<(u8) eMessageVersion::kMessLegacy>>(std::move(par)); break; case (int) eMessageVersion::kMess24: - algo = std::make_unique<UnpackMS<(u8) eMessageVersion::kMess24>>(par); + algo = std::make_unique<UnpackMS<(u8) eMessageVersion::kMess24>>(std::move(par)); break; } // register algorithm + L_(debug) << "Register algo for ver=" << (int) ver << " eqId=0x" << std::hex << (int) equip; fAlgos[{equip, ver}] = std::move(algo); } - - L_(debug) << "--- Configured equipment " << equip << " with " << numAsics << " asics"; } L_(info) << "--- Configured " << fAlgos.size() << " unpacker algorithms for TRD2D."; + // for (const auto& [key, algo] : fAlgos) { + // L_(info) << "eq=0x" << std::hex << key.eqId << " ver=" << int(key.sysVer); + // if (key.sysVer ==2 ) continue; + // (dynamic_cast<const UnpackMS<3>&>(*algo)).DumpParameters(); + // } } Unpack::Result_t Unpack::operator()(const fles::Timeslice& ts) const { return DoUnpack(Subsystem::TRD2D, ts); } diff --git a/algo/detectors/trd2d/UnpackMS.cxx b/algo/detectors/trd2d/UnpackMS.cxx index 9bdf5b40d394b0e801152652af6b3fdfe51900db..1c0e77249c18b94780513a75dcadaa21e16318a6 100644 --- a/algo/detectors/trd2d/UnpackMS.cxx +++ b/algo/detectors/trd2d/UnpackMS.cxx @@ -8,6 +8,8 @@ #include <algorithm> #include <cassert> +#include <iomanip> +#include <iostream> #include <sstream> #include <vector> @@ -16,13 +18,11 @@ using std::unique_ptr; namespace cbm::algo::trd2d { // ---- Fasp message constructor ---------------------------------------- - FaspMessage::FaspMessage(uint8_t c, uint8_t typ, uint8_t t, uint16_t d, uint8_t r, uint8_t asic, uint8_t e) + FaspMessage::FaspMessage(uint8_t c, uint8_t typ, uint8_t t, uint16_t d, uint8_t asic) : ch(c) , type(eMessageType::kNone) , tlab(t) , data(d) - , rob(r) - , elink(e) , fasp(asic) { if (typ == uint8_t(eMessageType::kData)) @@ -36,12 +36,10 @@ namespace cbm::algo::trd2d std::stringstream ss; switch (type) { case eMessageType::kData: - ss << " DATA : rob=" << rob << (elink ? 'u' : 'd') << " fasp_id=" << fasp << " [" << getFaspIdMod() - << "] ch_id=" << ch << " tclk=" << tlab << " data=" << data << std::endl; - break; - case eMessageType::kEpoch: - ss << " EPOCH: eq_id=" << rob << (elink ? 'u' : 'd') << " ch_id=" << ch << " epoch=" << epoch << std::endl; + ss << " DATA : fasp=" << std::setw(2) << (int) fasp << " ch=" << std::setw(2) << (int) ch + << " t=" << std::setw(3) << (int) tlab << " data=" << std::setw(4) << (int) data << std::endl; break; + case eMessageType::kEpoch: ss << " EPOCH: ch=" << (int) ch << " epoch=" << (int) epoch << std::endl; break; default: ss << " MTYPE: unknown" << std::endl; break; } @@ -135,6 +133,40 @@ namespace cbm::algo::trd2d return; } + void UnpackPar::dump() const + { + L_(debug) << "UnpackPar::dump()"; + L_(debug) << "mod=" << fModId << " elink[" << (int) fEqId << "]=0x" << std::hex << (int) fEqAdd + << " nAsics=" << std::dec << fAsicParams.size(); + for (const auto& [fasp, par] : fAsicParams) { + L_(debug) << " fasp=" << int(fasp) << " par=" << std::hex << ∥ + } + L_(debug) << "UnpackPar::dump(-----------------------)"; + } + + template<> + uint8_t UnpackPar::mapFaspId2Mod<uint8_t(eMessageVersion::kMessLegacy)>(uint8_t fasp_id) const + { + /** Use the mapping 36 fasp -> 1 optical fiber (equipment id) + * Applies to FASPRO/FW v1 (e.g. mCBM22) + */ + L_(debug) << "<vLegacy> Eq[" << (int) fEqId << "] = 0x" << std::hex << fEqAdd; + return fEqId * NFASPROB + fasp_id; + } + + template<> + uint8_t UnpackPar::mapFaspId2Mod<uint8_t(eMessageVersion::kMess24)>(uint8_t fasp_id) const + { + /** Use the mapping 36 fasp -> 2 optical fiber (equipment id) + * Applies to FASPRO/FW v2 (e.g. mCBM25) + */ + + int rob = fEqId / 2; // ROB on the current chamber + //L_(debug) << "<v24> ROB=" << rob << " Eq[" << (int)fEqId << "] = 0x" << std::hex << fEqAdd; + + return rob * NFASPROB + fasp_id; + } + // ---- Algorithm execution --------------------------------------------- template<> typename UnpackMS<uint8_t(eMessageVersion::kMessLegacy)>::Result_t @@ -157,7 +189,7 @@ namespace cbm::algo::trd2d uint64_t time = uint64_t((msDescr.idx - tTimeslice - fParams.fSystemTimeOffset) / 12.5); // Get parameters for current eq id. - const uint8_t crob_id = fParams.fRobId; + //const uint8_t crob_id = fParams.fEqId; // Get the number of complete words in the input MS buffer. const uint32_t nwords = msDescr.size / 4; @@ -203,7 +235,7 @@ namespace cbm::algo::trd2d ctx.fMonitor.fNumSelfTriggeredData++; data &= 0x1fff; } - vMess.emplace_back(ch_id, (uint8_t) eMessageType::kData, slice, data >> 1, crob_id, lFaspOld); + vMess.emplace_back(ch_id, (uint8_t) eMessageType::kData, slice, data >> 1, lFaspOld); } std::get<0>(result) = FinalizeComponent(ctx); //TO DO: Original (non-algo) version calls this after MS loop!! std::get<1>(result) = ctx.fMonitor; @@ -214,8 +246,11 @@ namespace cbm::algo::trd2d template<uint8_t sys_ver> bool UnpackMS<sys_ver>::pushDigis(std::vector<FaspMessage> messes, const uint64_t time, MsContext& ctx) const { + constexpr uint8_t mLegacy = + uint8_t(eMessageVersion::kMessLegacy); // message versions compatible with the current algo specialization const uint16_t mod_id = fParams.fModId; - const UnpackAsicPar& asicPar = fParams.fAsicParams[messes[0].fasp]; + const uint8_t fasp_mod_id = fParams.mapFaspId2Mod<mLegacy>(messes[0].fasp); + const UnpackAsicPar& asicPar = fParams.fAsicParams.at(fasp_mod_id); const uint64_t tdaqOffset = asicPar.fChanParams[messes[0].ch].fDaqOffset; for (auto imess : messes) { @@ -334,6 +369,8 @@ namespace cbm::algo::trd2d // Get the number of complete words in the input MS buffer. const uint32_t nwords = msDescr.size / 4; + L_(debug) << "UnpackMS<kMess24>::op() param.elink[" << (int) fParams.fEqId << "]=0x" << std::hex + << (int) fParams.fEqAdd << " data.rob=0x" << int(msDescr.eq_id) << " words=" << std::dec << nwords; // We have 32 bit FASP frames in this readout version const uint32_t* wd = reinterpret_cast<const uint32_t*>(msContent); @@ -349,7 +386,6 @@ namespace cbm::algo::trd2d case eMessageType::kEpoch: ctx.fMess.readEW<m24>(w); break; default: break; // no way to reach this line } - ctx.fMess.rob = fParams.fRobId; // PROCESS EPOCH MESSAGES if (ctx.fMess.type == eMessageType::kEpoch) { @@ -377,10 +413,6 @@ namespace cbm::algo::trd2d vMess.clear(); lFaspOld = ctx.fMess.fasp; } - if (ctx.fMess.data & 0x1) { // kept for backward compatibility TODO - ctx.fMonitor.fNumErrEndBitSet++; - continue; - } if (ctx.fMess.data & 0x2000) { // kept for backward compatibility TODO ctx.fMonitor.fNumSelfTriggeredData++; ctx.fMess.data &= 0x1fff; @@ -390,10 +422,12 @@ namespace cbm::algo::trd2d // combine all digis from this ROB std::vector<CbmTrdDigi> outputDigis; - for (uint16_t ipad(0); ipad < NFASPMOD * NFASPCH; ipad++) { + for (uint16_t ipad(0); ipad < NFASPMOD * NFASPPAD; ipad++) { if (!ctx.fRobDigi[ipad].size()) continue; - for (auto id : ctx.fRobDigi[ipad]) + for (auto id : ctx.fRobDigi[ipad]) { + L_(debug) << id.ToString(); outputDigis.emplace_back(std::move(id)); + } } std::get<0>(result) = outputDigis; std::get<1>(result) = ctx.fMonitor; @@ -403,14 +437,18 @@ namespace cbm::algo::trd2d bool UnpackMS<uint8_t(eMessageVersion::kMess24)>::pushDigis(std::vector<FaspMessage> messes, const uint64_t time, MsContext& ctx) const { - const uint16_t mod_id = fParams.fModId; - const UnpackAsicPar& asicPar = fParams.fAsicParams[messes[0].fasp]; - const uint64_t tdaqOffset = asicPar.fChanParams[messes[0].ch].fDaqOffset; + constexpr uint8_t m24 = + uint8_t(eMessageVersion::kMess24); // message versions compatible with the current algo specialization + const uint8_t fasp_mod_id = fParams.mapFaspId2Mod<m24>(messes[0].fasp); + const UnpackAsicPar& asicPar = fParams.fAsicParams.at(fasp_mod_id); for (auto imess : messes) { - const int32_t pad = std::abs(asicPar.fChanParams[imess.ch].fPadAddress); - const bool hasPairingR = bool(asicPar.fChanParams[imess.ch].fPadAddress > 0); - const uint64_t lTime = time + tdaqOffset + imess.tlab; + const UnpackChannelPar& chPar = asicPar.fChanParams[imess.ch]; + // skip message if threshold set and signal under + if (chPar.fSignalThres && imess.data <= chPar.fSignalThres) continue; + const int32_t pad = std::abs(chPar.fPadAddress) / 2; + const bool hasPairingR = bool(chPar.fPadAddress > 0); + const uint64_t lTime = time + chPar.fDaqOffset + imess.tlab; const uint16_t lchR = hasPairingR ? imess.data : 0; const uint16_t lchT = hasPairingR ? 0 : imess.data; std::vector<CbmTrdDigi>& digiBuffer = ctx.fRobDigi[pad]; @@ -418,14 +456,14 @@ namespace cbm::algo::trd2d // init pad position in array and build digi for message if (digiBuffer.size() == 0) { digiBuffer.emplace_back(pad, lchT, lchR, lTime); - digiBuffer.back().SetAddressModule(mod_id); + digiBuffer.back().SetAddressModule(fParams.fModId); continue; } // check if last digi has both R/T message components. // Update if not and is within time window - auto id = digiBuffer.back(); // Should always be valid here. - // No need to extra check + auto& id = digiBuffer.back(); // Should always be valid here. + // No need to extra check double r, t; int32_t dt; const int32_t dtime = id.GetTimeDAQ() - lTime; @@ -446,7 +484,7 @@ namespace cbm::algo::trd2d // build digi for message when update failed if (!use) { digiBuffer.emplace_back(pad, lchT, lchR, lTime); - digiBuffer.back().SetAddressModule(mod_id); + digiBuffer.back().SetAddressModule(fParams.fModId); } } messes.clear(); diff --git a/algo/detectors/trd2d/UnpackMS.h b/algo/detectors/trd2d/UnpackMS.h index 6491945e0e1590f582058ae043ab777ca85c0d45..1babd7e8535aa955c768ef02deea1a6dc8b08c0a 100644 --- a/algo/detectors/trd2d/UnpackMS.h +++ b/algo/detectors/trd2d/UnpackMS.h @@ -12,11 +12,12 @@ #include <sstream> #define NFASPMOD 180 -#define NCROBMOD 5 -#define NFASPCROB NFASPMOD / NCROBMOD +#define NROBMOD 5 +#define NFASPROB NFASPMOD / NROBMOD #define NFASPCH 16 +#define NFASPPAD 8 -#define FASP_EPOCH_LENGTH 128 +#define FASP_EPOCH_LENGTH 128 // the length in clks of FASP epoch [1600ns @ 40MHz] namespace cbm::algo::trd2d { @@ -34,7 +35,6 @@ namespace cbm::algo::trd2d { kMessLegacy = 2, /// unpacker version for 2-board FASPRO+GETS HW kMess24 = 3, /// unpacker version for 1-board FASPRO HW first used 18.06.24 (mCBM) - kMessNoDef /// default unpacker version }; enum class eMessageType : int @@ -78,8 +78,7 @@ namespace cbm::algo::trd2d struct FaspMessage { FaspMessage() = default; FaspMessage(const FaspMessage&) = default; - FaspMessage(uint8_t c, uint8_t typ, uint8_t t, uint16_t d, uint8_t rob, uint8_t asic, uint8_t e = 0); - int getFaspIdMod() const { return fasp + rob * NFASPCROB; } + FaspMessage(uint8_t c, uint8_t typ, uint8_t t, uint16_t d, uint8_t asic); /** \brief Implementation of message type descriptor according to message version * \param w the message word @@ -106,9 +105,6 @@ namespace cbm::algo::trd2d uint8_t tlab = 0; ///< time of the digi inside the epoch uint16_t data = 0; ///< ADC value uint32_t epoch = 0; ///< epoch id (not used for the moment) - uint32_t mod = 0; ///< full module address according to CbmTrdAddress - uint8_t rob = 0; ///< ROB id in the module - uint8_t elink = 0; ///< optical link for read-out unit (up or down, starting with kMess24) uint8_t fasp = 0; ///< FASP id in the module }; @@ -120,7 +116,8 @@ namespace cbm::algo::trd2d struct UnpackChannelPar { int32_t fPadAddress; ///< Pad address for channel bool fMask; ///< Flag for channel masking - uint64_t fDaqOffset = 0; ///< Time calibration parameter + uint8_t fDaqOffset = 0; ///< Time calibration parameter + uint16_t fSignalThres = 0; ///< Signal threshold to remove ringing channels }; /** @struct UnpackAsicPar @@ -138,10 +135,22 @@ namespace cbm::algo::trd2d ** @brief Parameters required for the TRD2D unpacking (specific to one component) **/ struct UnpackPar { - int32_t fSystemTimeOffset = 0; ///< Time calibration parameter - uint16_t fModId = 0; ///< Module ID of component - uint8_t fRobId = 0; ///< ROB ID of component - std::vector<UnpackAsicPar> fAsicParams = {}; ///< Parameters for each ASIC + int32_t fSystemTimeOffset = 0; ///< Time calibration parameter + uint16_t fModId = 0; ///< Module ID of component + uint16_t fEqAdd = 0; ///< Equipment (optical fiber) address [HEX] + uint8_t fEqId = 0xff; ///< Equipment (optical fiber) ID of component + std::map<uint8_t, UnpackAsicPar> fAsicParams = {}; ///< Parameters for each ASIC + + /** \brief Write to the debug stream the content of the current param object*/ + void dump() const; + + /** \brief Calculate the module wise FASP id from the FASP id provided at the level + * of equipment Id (optical fibre in TRD2D case). + * \param fasp_id index of fasp as written on the message + * \return fasp id on the module as it is used in the parameter file + */ + template<uint8_t ver> + uint8_t mapFaspId2Mod(uint8_t fasp_id) const; }; @@ -183,12 +192,12 @@ namespace cbm::algo::trd2d ** @since 31 January 2023 ** @brief Unpack algorithm for TRD2D **/ - template<std::uint8_t sys_ve> + template<std::uint8_t sys_ver> class UnpackMS : public UnpackMSBase<CbmTrdDigi, UnpackMonitorData, UnpackAuxData> { public: /** @brief Construct from parameters **/ - UnpackMS(const UnpackPar& /*pars*/) {} + UnpackMS(const UnpackPar& pars) : fParams(pars) {} /** @brief Destructor **/ ~UnpackMS() override = default; @@ -239,7 +248,7 @@ namespace cbm::algo::trd2d public: /** @brief Construct from parameters **/ - UnpackMS(const UnpackPar& /*pars*/) {} + UnpackMS(const UnpackPar& pars) : fParams(pars) {} /** @brief Destructor **/ ~UnpackMS() override = default; @@ -262,7 +271,7 @@ namespace cbm::algo::trd2d private: // Types struct MsContext { UnpackMonitorData fMonitor; ///< Container for monitoring data - std::array<std::vector<CbmTrdDigi>, NFASPMOD* NFASPCH> fRobDigi = { + std::array<std::vector<CbmTrdDigi>, NFASPMOD* NFASPPAD> fRobDigi = { {}}; ///> Buffered digi for each pad in one Epoch-ROB component FaspMessage fMess; ///< encapsulation of the FASP message. }; diff --git a/reco/tasks/CbmTaskTrdUnpackParWrite.cxx b/reco/tasks/CbmTaskTrdUnpackParWrite.cxx index c7c3667f31426582748a8ec18bdf0a6f7c9447ea..6a19ff16bf719e0b89908d6efdb28eb89535fd6d 100644 --- a/reco/tasks/CbmTaskTrdUnpackParWrite.cxx +++ b/reco/tasks/CbmTaskTrdUnpackParWrite.cxx @@ -37,7 +37,7 @@ InitStatus CbmTaskTrdUnpackParWrite::Init() cbm::algo::trd2d::ReadoutConfig trd2dConfig; // Map (moduleId) -> (array of crobId) - std::map<uint32_t, uint16_t[NCROBMOD]> crobMap; + std::map<uint32_t, std::vector<uint16_t>> crobMap; // Map (equipId, asicId, chanId) -> (pad address, mask flag, daq offset [FASP clk]) std::map<size_t, std::map<size_t, std::map<size_t, std::tuple<int32_t, bool, uint64_t>>>> channelMap; @@ -53,9 +53,12 @@ InitStatus CbmTaskTrdUnpackParWrite::Init() auto digipar = entry.second; const int* crobs = setDet->GetCrobAddresses(); - for (int icrob(0); icrob < NCROBMOD; icrob++) - crobMap[moduleId][icrob] = crobs[icrob]; - + for (int icrob(0); icrob < NCROBMOD; icrob++) { + crobMap[moduleId].emplace_back(crobs[icrob] & 0xffff); + // check if there is an extra fiber defined on this ROB (version 2025 -) + uint16_t eq_id = (crobs[icrob] >> 16) & 0xffff; + if (eq_id) crobMap[moduleId].emplace_back(eq_id); + } // Loop through ASICs for this module std::vector<int32_t> addresses; setDet->GetAsicAddresses(&addresses);