diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt index 59e4d431644146d57de67fd882d39bd328a301d5..fa94bdca04bc6461df3cd1655f82b67869a01330 100644 --- a/algo/CMakeLists.txt +++ b/algo/CMakeLists.txt @@ -109,6 +109,7 @@ set(SRCS detectors/tof/HitfinderChain.cxx detectors/tof/CalibratorChain.cxx detectors/tof/config/ReadoutPars_mCBM2022.cxx + detectors/tof/config/ReadoutPars_mCBM2024.cxx detectors/bmon/ReadoutConfig.cxx detectors/bmon/Unpack.cxx detectors/bmon/UnpackMS.cxx diff --git a/algo/base/Options.cxx b/algo/base/Options.cxx index fad88ed6193c9d1dd56278d8ac46c5283919e9a2..5c4f42813a387d5b658cbd0ada66a10cf3647e5c 100644 --- a/algo/base/Options.cxx +++ b/algo/base/Options.cxx @@ -82,6 +82,7 @@ Options::Options(int argc, char** argv) ("systems,s", po::value(&fDetectors)->multitoken()->default_value({Subsystem::STS, Subsystem::TOF, Subsystem::BMON, Subsystem::MUCH, Subsystem::RICH, Subsystem::TRD, Subsystem::TRD2D})->value_name("<detectors>"), "space seperated list of detectors to process (sts, mvd, ...)") ("child-id,c", po::value(&fChildId)->default_value("00")->value_name("<id>"), "online process id on node") + ("run-id,r", po::value(&fRunId)->default_value(2391)->value_name("<RunId>"), "Run ID, for now flesctl run index, later run start time") ("num-ts,n", po::value(&fNumTimeslices)->default_value(-1)->value_name("<num>"), "Stop after <num> timeslices (-1 = all)") ("skip-ts", po::value(&fSkipTimeslices)->default_value(0)->value_name("<num>"), diff --git a/algo/base/Options.h b/algo/base/Options.h index b4c0c7a39d9217bdaeda79dcf456e6cda9be7ea2..06eb0c2fac39f853a86b0ac4dc7a9a0c281e9926 100644 --- a/algo/base/Options.h +++ b/algo/base/Options.h @@ -43,6 +43,7 @@ namespace cbm::algo return fNumOMPThreads > 0 ? std::make_optional(fNumOMPThreads) : std::nullopt; } const std::string& ChildId() const { return fChildId; } + uint64_t RunId() const { return fRunId; } bool DumpArchive() const { return fDumpArchive; } const std::vector<Step>& Steps() const { return fRecoSteps; } @@ -78,6 +79,7 @@ namespace cbm::algo bool fCompressArchive = false; std::vector<fles::Subsystem> fDetectors; std::string fChildId = "00"; + uint64_t fRunId = 2391; }; } // namespace cbm::algo diff --git a/algo/detectors/tof/ReadoutConfig.cxx b/algo/detectors/tof/ReadoutConfig.cxx index 6234bbead9771ee2ccaf5cdcbc52f33d06bc28b1..c5b8a599887e94176e315dee1a5ffac897c457c3 100644 --- a/algo/detectors/tof/ReadoutConfig.cxx +++ b/algo/detectors/tof/ReadoutConfig.cxx @@ -75,7 +75,8 @@ namespace cbm::algo::tof for (uint16_t elink = 0; elink < pars.NElinksPerComponent(); elink++) { fReadoutMap[equipment][elink].resize(pars.nChannelsPerAsic); - const uint32_t asicId = ElinkIdxToGet4Idx(elink, pars); + const uint32_t asicId = + pars.CheckInnerComp(equipment) ? ElinkIdxToGet4IdxInner(elink, pars) : ElinkIdxToGet4Idx(elink, pars); for (uint16_t channel = 0; channel < pars.nChannelsPerAsic; channel++) { const uint32_t febId = (asicId / pars.nAsicsPerFeb); @@ -98,8 +99,26 @@ namespace cbm::algo::tof return pars.elink2Asic[elink % pars.NElinksPerCrob()] + pars.NElinksPerCrob() * (elink / pars.NElinksPerCrob()); } else { - throw FatalError("CbmMcbm2018TofPar::ElinkIdxToGet4Idx => Index out of bound, {} vs {}, returning crazy value!", - elink, static_cast<uint32_t>(pars.NElinksPerComponent())); + throw FatalError("tof::ReadoutConfig::ElinkIdxToGet4Idx => Index out of bound, {} vs {}, stop there!", elink, + static_cast<uint32_t>(pars.NElinksPerComponent())); + } + } + + int32_t ReadoutConfig::ElinkIdxToGet4IdxInner(uint32_t elink, const config::ReadoutPars& pars) + { + if (0 == pars.elink2AsicInner.size()) { + throw FatalError("tof::ReadoutConfig::ElinkIdxToGet4IdxInner => map is empty, stop there, check your Config!"); + } + else if (gdpbv100::kuChipIdMergedEpoch == elink) { + return elink; + } + else if (elink < pars.NElinksPerComponent()) { + return pars.elink2AsicInner[elink % pars.NElinksPerCrob()] + + pars.NElinksPerCrob() * (elink / pars.NElinksPerCrob()); + } + else { + throw FatalError("tof::ReadoutConfig::ElinkIdxToGet4IdxInner => Index out of bound, {} vs {}, stop there!", elink, + static_cast<uint32_t>(pars.NElinksPerComponent())); } } // ------------------------------------------------------------------------- @@ -125,9 +144,16 @@ namespace cbm::algo::tof uint32_t uNrOfChannels = uNrOfGet4 * pars.nChannelsPerAsic; fviRpcChUId.resize(uNrOfChannels); + uint32_t nbRobPerComp = 2; // number of Gbtx per Gdpb (flim) for the final channel count check + if (pars.mcbmTof2024) { + // Hack for 2024 TOF mapping + nbRobPerComp = 1; + } + uint32_t uCh = 0; for (uint32_t uGbtx = 0; uGbtx < pars.NCROBs(); ++uGbtx) { - uint32_t uCh0 = uCh; + uint32_t uCh0 = uCh; + uint32_t uGdpb = uCh0 / (pars.nFebsPerComponent * pars.nAsicsPerFeb * pars.nChannelsPerAsic); const auto& crob = pars.crobs.at(uGbtx); switch (crob.rpcType) { case 2: // intended fall-through @@ -156,12 +182,22 @@ namespace cbm::algo::tof case 7: [[fallthrough]]; case 9: // Star2 boxes { - BuildChannelsUidMapStar2(uCh, crob); + if ((pars.eqIds[uGdpb] & 0xF000) == 0xB000) { + BuildChannelsUidMapStar2Inner(uCh, crob); + } + else { + BuildChannelsUidMapStar2(uCh, crob); + } break; } case 6: // Buc box { - BuildChannelsUidMapBuc(uCh, crob); + if ((pars.eqIds[uGdpb] & 0xF000) == 0xB000) { + BuildChannelsUidMapStar2Inner(uCh, crob); + } + else { + BuildChannelsUidMapBuc(uCh, crob); + } break; } case 69: { @@ -182,7 +218,7 @@ namespace cbm::algo::tof L_(error) << "Invalid Tof Type specifier for GBTx " << std::setw(2) << uGbtx << ": " << crob.rpcType; } } // switch (crob.rpcType) - if (int32_t(uCh - uCh0) != pars.nFebsPerComponent * pars.nAsicsPerFeb * pars.nChannelsPerAsic / 2) { + if (int32_t(uCh - uCh0) != pars.nFebsPerComponent * pars.nAsicsPerFeb * pars.nChannelsPerAsic / nbRobPerComp) { throw FatalError("Tof mapping error for Gbtx {}, diff = {}, type {}", uGbtx, uCh - uCh0, crob.rpcType); } } // for (UInt_t uGbtx = 0; uGbtx < numCrob; ++uGbtx) @@ -339,6 +375,92 @@ namespace cbm::algo::tof } } + // ------------------------------------------------------------------------- + void ReadoutConfig::BuildChannelsUidMapStar2Inner(uint32_t& uCh, const config::CROB& crob) + { + if (crob.rpcSide < 3) { + int32_t NrFeet = 2; + if (crob.rpcSide < 2) NrFeet = 1; + int32_t iFeet = 0; + for (; iFeet < NrFeet; iFeet++) { + for (int32_t iStr = 0; iStr < 32; iStr++) { + int32_t iStrMap = iStr; + int32_t iRpcMap = crob.nRPC; + int32_t iSideMap = crob.rpcSide; + if (crob.rpcSide == 2) { + if (iFeet == 0) + iSideMap = 0; + else + iSideMap = 1; + } + else { + if (crob.rpcSide == 3) { + if (iFeet == 0) + iSideMap = 1; + else + iSideMap = 0; + } + } + if (crob.rpcType != 6) + if (iSideMap == 0) iStrMap = 31 - iStr; + + if (iSideMap > -1) + fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(crob.moduleId, iRpcMap, iStrMap, iSideMap, crob.rpcType); + else + fviRpcChUId[uCh] = 0; + + uCh++; + } + } + while (iFeet < 2) { + for (int32_t iStr = 0; iStr < 32; iStr++) { + fviRpcChUId[uCh] = 0; + uCh++; + } + iFeet++; + } + } + else { + if (crob.rpcSide == 3) { + int iSideMap = -1; + int iStrMap = -1; + int iRpcMap = -1; + for (int32_t iFeet = 0; iFeet < 5; iFeet++) { + for (int32_t iStr = 0; iStr < 32; iStr++) { + switch (iFeet) { + case 0: iSideMap = -1; break; + case 1: + iRpcMap = 0; + iStrMap = iStr; + iSideMap = 0; + break; + case 2: + iRpcMap = 0; + iStrMap = iStr; + iSideMap = 1; + break; + case 3: + iRpcMap = 1; + iStrMap = iStr; + iSideMap = 0; + break; + case 4: + iRpcMap = 1; + iStrMap = iStr; + iSideMap = 1; + break; + } + if (iSideMap > -1) + fviRpcChUId[uCh] = + CbmTofAddress::GetUniqueAddress(crob.moduleId, iRpcMap, iStrMap, iSideMap, crob.rpcType); + else + fviRpcChUId[uCh] = 0; + uCh++; + } + } + } + } + } // ------------------------------------------------------------------------- void ReadoutConfig::BuildChannelsUidMapBuc(uint32_t& uCh, const config::CROB& crob) diff --git a/algo/detectors/tof/ReadoutConfig.h b/algo/detectors/tof/ReadoutConfig.h index 0959c48b2646655d1ef0f2ce81c9d6d6261dc5fa..4b77c63789bbff4dd9959003d6b7a5043d0a52ec 100644 --- a/algo/detectors/tof/ReadoutConfig.h +++ b/algo/detectors/tof/ReadoutConfig.h @@ -56,6 +56,9 @@ namespace cbm::algo::tof /// Mapping to eLink to ASIC number within DPB. Mapping is the same for each DPB. int32_t ElinkIdxToGet4Idx(uint32_t elink, const config::ReadoutPars& pars); + /// Mapping to eLink to ASIC number within DPB for 2024 inner TOF FEBs. Mapping is the same for each DPB. + int32_t ElinkIdxToGet4IdxInner(uint32_t elink, const config::ReadoutPars& pars); + int32_t Get4ChanToPadiChan(uint32_t channelInFee, const config::ReadoutPars& pars); std::vector<int32_t> fviRpcChUId = {}; // UID/address for each channel, build from type, side and module @@ -66,6 +69,7 @@ namespace cbm::algo::tof void BuildChannelsUidMapCern(uint32_t& uCh, const config::CROB& crob); void BuildChannelsUidMapCera(uint32_t& uCh, const config::CROB& crob); void BuildChannelsUidMapStar2(uint32_t& uCh, const config::CROB& crob); + void BuildChannelsUidMapStar2Inner(uint32_t& uCh, const config::CROB& crob); void BuildChannelsUidMapBuc(uint32_t& uCh, const config::CROB& crob); }; diff --git a/algo/detectors/tof/config/ReadoutPars.h b/algo/detectors/tof/config/ReadoutPars.h index bac8282523255ebdb7e41d50b3dc1b03f091c40f..f40b53c326a0f9f76273ba2eeb814a1affb85fae 100644 --- a/algo/detectors/tof/config/ReadoutPars.h +++ b/algo/detectors/tof/config/ReadoutPars.h @@ -20,6 +20,9 @@ namespace cbm::algo::tof::config struct ReadoutPars { static ReadoutPars MakeMCBM2022(); + static ReadoutPars MakeMCBM2024(); + + bool mcbmTof2024 = false; i32 nFebsPerComponent; i32 nAsicsPerFeb; @@ -36,6 +39,7 @@ namespace cbm::algo::tof::config // Mapping to eLink to ASIC number within CROB. Mapping is the same for each CROB. (size: nElinksPerCrob) std::vector<i32> elink2Asic; + std::vector<i32> elink2AsicInner; // Mapping in Readout chain PCBs // Map from GET4 channel to PADI channel @@ -47,6 +51,9 @@ namespace cbm::algo::tof::config i32 NChansPerComponent() const { return nChannelsPerAsic * NElinksPerComponent(); } i32 NElinksPerCrob() const { return nAsicsPerFeb * NFebsPerCrob(); } i32 NElinksPerComponent() const { return NElinksPerCrob() * nCrobPerComponent; } + + bool CheckBmonComp(uint32_t uCompId) const { return ((uCompId & 0xFFF0) == 0xABF0); } + bool CheckInnerComp(uint32_t uCompId) const { return ((uCompId & 0xFFF0) == 0xBBC0); } }; } // namespace cbm::algo::tof::config diff --git a/algo/detectors/tof/config/ReadoutPars_mCBM2022.cxx b/algo/detectors/tof/config/ReadoutPars_mCBM2022.cxx index 34713a4207d2a010be0c688d24a5ff6da70d9c65..18b1ef6aac7474103ba55022d5e7dc82e1f0f734 100644 --- a/algo/detectors/tof/config/ReadoutPars_mCBM2022.cxx +++ b/algo/detectors/tof/config/ReadoutPars_mCBM2022.cxx @@ -1,6 +1,7 @@ /* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt SPDX-License-Identifier: GPL-3.0-only Authors: Felix Weiglhofer [committer], Dominik Smith */ +#include "Exceptions.h" #include "ReadoutPars.h" using namespace cbm::algo::tof::config; @@ -46,6 +47,14 @@ ReadoutPars ReadoutPars::MakeMCBM2022() 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12, 19, 18, 17, 16, 23, 22, 21, 20, 27, 26, 25, 24, 31, 30, 29, 28}; //! Map from GET4 channel to PADI channel + if (pars.NElinksPerCrob() != static_cast<i32>(pars.elink2Asic.size())) { + throw FatalError("tof::ReadoutPars::MakeMCBM2022 => size of elink2Asic not matching, {} vs {}, stop there!", + static_cast<uint32_t>(pars.elink2Asic.size()), static_cast<uint32_t>(pars.NElinksPerComponent())); + } + if (pars.NChansPerFeb() != static_cast<i32>(pars.asic2PadI.size())) { + throw FatalError("tof::ReadoutPars::MakeMCBM2022 => size of asic2PadI not matching, {} vs {}, stop there!", + static_cast<uint32_t>(pars.elink2Asic.size()), static_cast<uint32_t>(pars.NChansPerFeb())); + } return pars; } diff --git a/algo/detectors/tof/config/ReadoutPars_mCBM2024.cxx b/algo/detectors/tof/config/ReadoutPars_mCBM2024.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d1fe95adaec1ecddcc99a543930e47034b873198 --- /dev/null +++ b/algo/detectors/tof/config/ReadoutPars_mCBM2024.cxx @@ -0,0 +1,69 @@ +/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Felix Weiglhofer [committer], Dominik Smith */ +#include "Exceptions.h" +#include "ReadoutPars.h" + +using namespace cbm::algo::tof::config; + +ReadoutPars ReadoutPars::MakeMCBM2024() +{ + // This here refers to the mCBM 2022 and 2024 setups. + // Taken from CbmMcbm2018TofPar in combination with macro/beamtime/mcbm2022/mTofCriParNickel.par + // and mTofCriParNickel_withBmon.par (?) + + ReadoutPars pars; + + pars.mcbmTof2024 = true; + + pars.nFebsPerComponent = 5; + pars.nAsicsPerFeb = 8; + pars.nChannelsPerAsic = 4; + pars.nCrobPerComponent = 1; + + constexpr int NumCrob = 15; + + // Module Identifier connected to Gbtx link, has to match geometry + const int32_t moduleId[NumCrob] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 0, 0, 0, 1, 0}; + + // type of Rpcs connected to Gbtx link + const int32_t rpcType[NumCrob] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 9, 9, 6}; + + // side of Rpcs connected to Gbtx link, i.e. 0 or 1 + const int32_t rpcSide[NumCrob] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 2, 3}; + + // number of Rpcs connected to Gbtx link, i.e. 3 or 5 + const int32_t numRpc[NumCrob] = {5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5}; + + for (int i = 0; i < NumCrob; ++i) { + pars.crobs.push_back({moduleId[i], rpcType[i], rpcSide[i], numRpc[i]}); + } + + pars.eqIds = {0xabc0, 0xabc1, 0xabc2, 0xabc3, 0xabc4, 0xabc5, 0xabc6, 0xabc7, + 0xabc8, 0xabc9, 0xabca, 0xabcb, 0xabcc, 0xabcd, 0xbbc0}; + + pars.elink2Asic = {27, 2, 7, 3, 31, 26, 30, 1, 33, 37, 32, 13, 9, 14, 10, 15, 17, 21, 16, 35, + 34, 38, 25, 24, 0, 6, 20, 23, 18, 22, 28, 4, 29, 5, 19, 36, 39, 8, 12, 11}; + pars.elink2AsicInner = {0, 16, 8, 17, 1, 18, 9, 19, 2, 20, 10, 21, 3, 22, 11, 23, 4, 24, 12, 25, + 5, 26, 13, 27, 6, 28, 14, 29, 7, 30, 15, 31, 32, 33, 34, 35, 36, 37, 38, 39}; + + // Mapping in Readout chain PCBs + pars.asic2PadI = { + 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12, + 19, 18, 17, 16, 23, 22, 21, 20, 27, 26, 25, 24, 31, 30, 29, 28}; //! Map from GET4 channel to PADI channel + + if (pars.NElinksPerCrob() != static_cast<i32>(pars.elink2Asic.size())) { + throw FatalError("tof::ReadoutPars::MakeMCBM2024 => size of elink2Asic not matching, {} vs {}, stop there!", + static_cast<uint32_t>(pars.elink2Asic.size()), static_cast<uint32_t>(pars.NElinksPerCrob())); + } + if (pars.NElinksPerCrob() != static_cast<i32>(pars.elink2AsicInner.size())) { + throw FatalError("tof::ReadoutPars::MakeMCBM2024 => size of elink2AsicInner not matching, {} vs {}, stop there!", + static_cast<uint32_t>(pars.elink2Asic.size()), static_cast<uint32_t>(pars.NElinksPerCrob())); + } + if (pars.NChansPerFeb() != static_cast<i32>(pars.asic2PadI.size())) { + throw FatalError("tof::ReadoutPars::MakeMCBM2024 => size of asic2PadI not matching, {} vs {}, stop there!", + static_cast<uint32_t>(pars.elink2Asic.size()), static_cast<uint32_t>(pars.NChansPerFeb())); + } + + return pars; +} diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx index e308d7dc3ffe79bff64b9c4e218815c4ef0acc51..0da2d2f9b8c009ee29d3b6828224385edede13e2 100644 --- a/algo/global/Reco.cxx +++ b/algo/global/Reco.cxx @@ -125,7 +125,8 @@ void Reco::Init(const Options& opts) } if (Opts().Has(Subsystem::TOF) && Opts().Has(Step::Unpack)) { - tof::ReadoutConfig cfg{tof::config::ReadoutPars::MakeMCBM2022()}; + tof::ReadoutConfig cfg{2724 <= Opts().RunId() ? tof::config::ReadoutPars::MakeMCBM2024() + : tof::config::ReadoutPars::MakeMCBM2022()}; fTofUnpack = std::make_unique<tof::Unpack>(cfg); }