diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt index 21d6134d74c4170143ca94354beb1761117a1098..9de6731fcd03d154c9fe2b33b246accd127cb65e 100644 --- a/algo/CMakeLists.txt +++ b/algo/CMakeLists.txt @@ -83,8 +83,6 @@ set(SRCS evselector/DigiEventSelector.cxx evselector/DigiEventSelectorConfig.cxx unpack/CommonUnpacker.cxx - unpack/Unpack.cxx - unpack/UnpackChain.cxx detectors/sts/ChannelMaskSet_mCBM2022.cxx detectors/sts/ReadoutConfig.cxx detectors/sts/ReadoutConfig_mCBM2022.cxx @@ -94,22 +92,28 @@ set(SRCS detectors/sts/WalkMap.cxx detectors/sts/WalkMap_mCBM2022.cxx detectors/much/ReadoutConfig.cxx + detectors/much/Unpack.cxx detectors/much/UnpackMS.cxx detectors/tof/HitFinder.cxx detectors/tof/Calibrate.cxx detectors/tof/Clusterizer.cxx detectors/tof/ReadoutConfig.cxx + detectors/tof/Unpack.cxx detectors/tof/UnpackMS.cxx detectors/tof/Hitfind.cxx detectors/tof/HitfinderChain.cxx detectors/tof/CalibratorChain.cxx detectors/bmon/ReadoutConfig.cxx + detectors/bmon/Unpack.cxx detectors/bmon/UnpackMS.cxx detectors/trd/ReadoutConfig.cxx + detectors/trd/Unpack.cxx detectors/trd/UnpackMS.cxx detectors/trd2d/ReadoutConfig.cxx + detectors/trd2d/Unpack.cxx detectors/trd2d/UnpackMS.cxx detectors/rich/ReadoutConfig.cxx + detectors/rich/Unpack.cxx detectors/rich/UnpackMS.cxx global/Reco.cxx qa/DigiEventQa.cxx diff --git a/algo/base/AlgoTraits.h b/algo/base/AlgoTraits.h new file mode 100644 index 0000000000000000000000000000000000000000..21954e3030ff6ec514ab9cad56530ecaddffee78 --- /dev/null +++ b/algo/base/AlgoTraits.h @@ -0,0 +1,60 @@ +/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main + SPDX-License-Identifier: GPL-3.0-only + Authors: Felix Weiglhofer [committer] */ + +#pragma once + +#include <type_traits> + +/** + * @file AlgoTraits.h + * @brief Type traits for online algorithms + */ + +namespace cbm::algo::algo_traits +{ + + namespace detail + { + template<typename...> + struct ResultOf { + }; + + template<typename R, typename Algo, typename... Args> + struct ResultOf<R (Algo::*)(Args...) const> { + using type = R; + }; + + template<typename R, typename Algo, typename... Args> + struct ResultOf<R (Algo::*)(Args...)> { + using type = R; + }; + + template<typename Algo> + struct ResultOf<Algo> : ResultOf<decltype(&Algo::operator())> { + }; + + } // namespace detail + + /** + * @brief Type alias for the return type produced by an algorithm when invoked via callable-operator + */ + template<typename Algo> + using ResultOf_t = typename detail::ResultOf<Algo>::type; + + // Currently assume algorithms return std::pair<R, M> + // where R is the output and M is the monitoring data + + /** + * @brief Type alias for the output type produced by an algorithm + */ + template<typename Algo> + using Output_t = typename ResultOf_t<Algo>::first_type; + + /** + * @brief Type alias for the monitoring type produced by an algorithm + */ + template<typename Algo> + using Monitor_t = typename ResultOf_t<Algo>::second_type; + +} // namespace cbm::algo::algo_traits diff --git a/algo/base/compat/Algorithm.h b/algo/base/compat/Algorithm.h index 2fee8a387dcd63c4a760d2a93c130e5f384f6533..94c03a7de8c96c0c397dcf896d1fe95d2ae4a1b5 100644 --- a/algo/base/compat/Algorithm.h +++ b/algo/base/compat/Algorithm.h @@ -19,7 +19,7 @@ #include <algorithm> -#ifdef __cpp_lib_execution +#if defined(__cpp_lib_execution) && defined(HAVE_PARALLEL_ALGORITHM) #define WITH_EXECUTION #include <execution> #endif @@ -27,18 +27,6 @@ namespace cbm::algo { - namespace detail - { -#ifdef WITH_EXECUTION - inline constexpr auto ExecPolicy = -#ifdef HAVE_PARALLEL_ALGORITHM - std::execution::par_unseq; -#else - std::execution::seq; -#endif // HAVE_PARALLEL_ALGORITHM -#endif // WITH_EXECUTION - } // namespace detail - /** * @brief Wrapper for std::sort * @@ -49,7 +37,7 @@ namespace cbm::algo void Sort(It first, It last, Compare comp) { #ifdef WITH_EXECUTION - std::sort(detail::ExecPolicy, first, last, comp); + std::sort(std::execution::par_unseq, first, last, comp); #else std::sort(first, last, comp); #endif diff --git a/algo/detectors/bmon/Unpack.cxx b/algo/detectors/bmon/Unpack.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ed0313d552860a6148666aa07be53c8801587420 --- /dev/null +++ b/algo/detectors/bmon/Unpack.cxx @@ -0,0 +1,37 @@ +/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main + SPDX-License-Identifier: GPL-3.0-only + Authors: Felix Weiglhofer [committer], Dominik Smith */ + +#include "Unpack.h" + +#include "log.hpp" + +using namespace cbm::algo::bmon; +using fles::Subsystem; + +Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout) +{ + constexpr i64 SystemTimeOffset = 0; + + // Create one algorithm per component for Bmon and configure it with parameters + auto equipIdsBmon = fReadout.GetEquipmentIds(); + for (auto& equip : equipIdsBmon) { + std::unique_ptr<bmon::UnpackPar> par(new bmon::UnpackPar()); + const size_t numElinks = fReadout.GetNumElinks(equip); + for (size_t elink = 0; elink < numElinks; elink++) { + bmon::UnpackElinkPar elinkPar; + elinkPar.fChannelUId = fReadout.Map(equip, elink); // Vector of Bmon addresses for this elink + elinkPar.fTimeOffset = SystemTimeOffset; + par->fElinkParams.push_back(elinkPar); + } + fAlgos[equip].SetParams(std::move(par)); + L_(debug) << "--- Configured equipment " << equip << " with " << numElinks << " elinks"; + } + L_(info) << "--- Configured " << fAlgos.size() << " unpacker algorithms for Bmon."; +} + +Unpack::Result_t Unpack::operator()(const fles::Timeslice& ts) const +{ + constexpr int SystemVersion = 0x00; + return DoUnpack(Subsystem::BMON, ts, SystemVersion); +} diff --git a/algo/detectors/bmon/Unpack.h b/algo/detectors/bmon/Unpack.h new file mode 100644 index 0000000000000000000000000000000000000000..aca19761f62113c3cc39ef3ac20c074b2581e696 --- /dev/null +++ b/algo/detectors/bmon/Unpack.h @@ -0,0 +1,32 @@ +/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main + SPDX-License-Identifier: GPL-3.0-only + Authors: Felix Weiglhofer [committer], Dominik Smith */ + +#pragma once + +#include "CommonUnpacker.h" +#include "ReadoutConfig.h" +#include "UnpackMS.h" + +namespace cbm::algo::bmon +{ + + namespace detail + { + using UnpackBase = CommonUnpacker<CbmBmonDigi, UnpackMS, UnpackMonitorData>; + } + + class Unpack : public detail::UnpackBase { + + public: + using Result_t = detail::UnpackBase::Result_t; + + Unpack(const ReadoutConfig& readout); + + Result_t operator()(const fles::Timeslice&) const; + + private: + ReadoutConfig fReadout; + }; + +} // namespace cbm::algo::bmon diff --git a/algo/detectors/much/Unpack.cxx b/algo/detectors/much/Unpack.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0e8797e1d6de6c6b8931d185f3d7d22ab8abfd60 --- /dev/null +++ b/algo/detectors/much/Unpack.cxx @@ -0,0 +1,38 @@ +/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main + SPDX-License-Identifier: GPL-3.0-only + Authors: Felix Weiglhofer [committer], Dominik Smith */ + +#include "Unpack.h" + +#include "log.hpp" + +using namespace cbm::algo::much; +using fles::Subsystem; + +Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout) +{ + constexpr i64 SystemTimeOffset = -980; + + // Create one algorithm per component for Bmon and configure it with parameters + auto equipIdsMuch = fReadout.GetEquipmentIds(); + for (auto& equip : equipIdsMuch) { + std::unique_ptr<much::UnpackPar> par(new much::UnpackPar()); + const size_t numElinks = fReadout.GetNumElinks(equip); + for (size_t elink = 0; elink < numElinks; elink++) { + much::UnpackElinkPar elinkPar; + elinkPar.fAddress = fReadout.Map(equip, elink); // Vector of MUCH addresses for this elink + elinkPar.fTimeOffset = SystemTimeOffset; + elinkPar.fChanMask = fReadout.MaskMap(equip, elink); + par->fElinkParams.push_back(elinkPar); + } + fAlgos[equip].SetParams(std::move(par)); + L_(debug) << "--- Configured equipment " << equip << " with " << numElinks << " elinks"; + } + L_(info) << "--- Configured " << fAlgos.size() << " unpacker algorithms for MUCH."; +} + +Unpack::Result_t Unpack::operator()(const fles::Timeslice& ts) const +{ + constexpr int SystemVersion = 0x20; + return DoUnpack(Subsystem::MUCH, ts, SystemVersion); +} diff --git a/algo/detectors/much/Unpack.h b/algo/detectors/much/Unpack.h new file mode 100644 index 0000000000000000000000000000000000000000..8721ea9b41d8d6f59f81d78769f95bf304ad4026 --- /dev/null +++ b/algo/detectors/much/Unpack.h @@ -0,0 +1,32 @@ +/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main + SPDX-License-Identifier: GPL-3.0-only + Authors: Felix Weiglhofer [committer], Dominik Smith */ + +#pragma once + +#include "CommonUnpacker.h" +#include "ReadoutConfig.h" +#include "UnpackMS.h" + +namespace cbm::algo::much +{ + + namespace detail + { + using UnpackBase = CommonUnpacker<CbmMuchDigi, UnpackMS, UnpackMonitorData>; + } + + class Unpack : public detail::UnpackBase { + + public: + using Result_t = detail::UnpackBase::Result_t; + + Unpack(const ReadoutConfig& readout); + + Result_t operator()(const fles::Timeslice&) const; + + private: + ReadoutConfig fReadout; + }; + +} // namespace cbm::algo::much diff --git a/algo/detectors/rich/Unpack.cxx b/algo/detectors/rich/Unpack.cxx new file mode 100644 index 0000000000000000000000000000000000000000..04fc255666c7c336e8dfdd64f72defb7c3a24dde --- /dev/null +++ b/algo/detectors/rich/Unpack.cxx @@ -0,0 +1,36 @@ +/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main + SPDX-License-Identifier: GPL-3.0-only + Authors: Felix Weiglhofer [committer], Dominik Smith */ + +#include "Unpack.h" + +#include "log.hpp" + +using namespace cbm::algo::rich; +using fles::Subsystem; + +Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout) +{ + constexpr i64 SystemTimeOffset = 100; + + // Create one algorithm per component for Bmon and configure it with parameters + auto equipIdsRich = fReadout.GetEquipmentIds(); + for (auto& equip : equipIdsRich) { + std::unique_ptr<rich::UnpackPar> par(new rich::UnpackPar()); + std::map<uint32_t, std::vector<double>> compMap = fReadout.Map(equip); + for (auto const& val : compMap) { + uint32_t address = val.first; + par->fElinkParams[address].fToTshift = val.second; + par->fElinkParams[address].fTimeOffset = SystemTimeOffset; + } + fAlgos[equip].SetParams(std::move(par)); + L_(info) << "--- Configured equipment " << equip << " with " << fReadout.GetNumElinks(equip) << " elinks"; + } + L_(info) << "--- Configured " << fAlgos.size() << " unpacker algorithms for RICH."; +} + +Unpack::Result_t Unpack::operator()(const fles::Timeslice& ts) const +{ + constexpr int SystemVersion = 0x03; + return DoUnpack(Subsystem::RICH, ts, SystemVersion); +} diff --git a/algo/detectors/rich/Unpack.h b/algo/detectors/rich/Unpack.h new file mode 100644 index 0000000000000000000000000000000000000000..dbb7bd6b904c0fa4a0417b50e2efac70d70aa468 --- /dev/null +++ b/algo/detectors/rich/Unpack.h @@ -0,0 +1,32 @@ +/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main + SPDX-License-Identifier: GPL-3.0-only + Authors: Felix Weiglhofer [committer], Dominik Smith */ + +#pragma once + +#include "CommonUnpacker.h" +#include "ReadoutConfig.h" +#include "UnpackMS.h" + +namespace cbm::algo::rich +{ + + namespace detail + { + using UnpackBase = CommonUnpacker<CbmRichDigi, UnpackMS, UnpackMonitorData>; + } + + class Unpack : public detail::UnpackBase { + + public: + using Result_t = detail::UnpackBase::Result_t; + + Unpack(const ReadoutConfig& readout); + + Result_t operator()(const fles::Timeslice&) const; + + private: + ReadoutConfig fReadout; + }; + +} // namespace cbm::algo::rich diff --git a/algo/detectors/sts/Unpack.cxx b/algo/detectors/sts/Unpack.cxx index 4097fb33f95465a65b85744a99eb59295b63cff4..c40e4e75c9b4dc990efb68efcd98ebb7c4da60f5 100644 --- a/algo/detectors/sts/Unpack.cxx +++ b/algo/detectors/sts/Unpack.cxx @@ -39,6 +39,8 @@ Unpack::Unpack(const Config& config) : fConfig(config) fAlgos[equip].SetParams(std::move(par)); L_(debug) << "--- Configured equipment " << equip << " with " << numElinks << " elinks"; } //# equipments + + L_(info) << "--- Configured " << fAlgos.size() << " unpacker algorithms for STS."; } Unpack::Result_t Unpack::operator()(const fles::Timeslice& ts) const diff --git a/algo/detectors/tof/Unpack.cxx b/algo/detectors/tof/Unpack.cxx new file mode 100644 index 0000000000000000000000000000000000000000..7764470e22284eb48d96e6b029fd6ee89581e637 --- /dev/null +++ b/algo/detectors/tof/Unpack.cxx @@ -0,0 +1,37 @@ +/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main + SPDX-License-Identifier: GPL-3.0-only + Authors: Felix Weiglhofer [committer], Dominik Smith */ + +#include "Unpack.h" + +#include "log.hpp" + +using namespace cbm::algo::tof; +using fles::Subsystem; + +Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout) +{ + constexpr i64 SystemTimeOffset = 40; + + auto equipIdsTof = fReadout.GetEquipmentIds(); + for (auto& equip : equipIdsTof) { + std::unique_ptr<tof::UnpackPar> par(new tof::UnpackPar()); + const size_t numElinks = fReadout.GetNumElinks(equip); + for (size_t elink = 0; elink < numElinks; elink++) { + tof::UnpackElinkPar elinkPar; + elinkPar.fChannelUId = fReadout.Map(equip, elink); // Vector of TOF addresses for this elink + elinkPar.fTimeOffset = SystemTimeOffset; + par->fElinkParams.push_back(elinkPar); + } + fAlgos[equip].SetParams(std::move(par)); + L_(debug) << "--- Configured equipment " << equip << " with " << numElinks << " elinks"; + } + + L_(info) << "--- Configured " << fAlgos.size() << " unpacker algorithms for TOF."; +} + +Unpack::Result_t Unpack::operator()(const fles::Timeslice& ts) const +{ + constexpr int SystemVersion = 0x00; + return DoUnpack(Subsystem::TOF, ts, SystemVersion); +} diff --git a/algo/detectors/tof/Unpack.h b/algo/detectors/tof/Unpack.h new file mode 100644 index 0000000000000000000000000000000000000000..d11e669f03d92c8c1be713efe223847954a00263 --- /dev/null +++ b/algo/detectors/tof/Unpack.h @@ -0,0 +1,31 @@ +/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main + SPDX-License-Identifier: GPL-3.0-only + Authors: Felix Weiglhofer [committer], Dominik Smith */ +#pragma once + +#include "CommonUnpacker.h" +#include "tof/ReadoutConfig.h" +#include "tof/UnpackMS.h" + +namespace cbm::algo::tof +{ + + namespace detail + { + using UnpackBase = CommonUnpacker<CbmTofDigi, UnpackMS, UnpackMonitorData>; + } + + class Unpack : public detail::UnpackBase { + + public: + using Result_t = detail::UnpackBase::Result_t; + + Unpack(const ReadoutConfig& readout); + + Result_t operator()(const fles::Timeslice&) const; + + private: + ReadoutConfig fReadout; + }; + +} // namespace cbm::algo::tof diff --git a/algo/detectors/trd/Unpack.cxx b/algo/detectors/trd/Unpack.cxx new file mode 100644 index 0000000000000000000000000000000000000000..9beddb8e7cc6db978a61f457d11fbc67d3521800 --- /dev/null +++ b/algo/detectors/trd/Unpack.cxx @@ -0,0 +1,47 @@ +/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main + SPDX-License-Identifier: GPL-3.0-only + Authors: Felix Weiglhofer [committer], Dominik Smith */ + +#include "Unpack.h" + +#include "log.hpp" + +using namespace cbm::algo::trd; +using fles::Subsystem; + +Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout) +{ + constexpr i64 SystemTimeOffset = 1300; + + // Create one algorithm per component for TRD and configure it with parameters + auto equipIdsTrd = fReadout.GetEquipmentIds(); + for (auto& equip : equipIdsTrd) { + + std::unique_ptr<trd::UnpackPar> par(new trd::UnpackPar()); + const size_t numCrobs = fReadout.GetNumCrobs(equip); + + for (size_t crob = 0; crob < numCrobs; crob++) { + trd::UnpackCrobPar crobPar; + const size_t numElinks = fReadout.GetNumElinks(equip, crob); + + for (size_t elink = 0; elink < numElinks; elink++) { + trd::UnpackElinkPar elinkPar; + auto addresses = fReadout.Map(equip, crob, elink); + elinkPar.fAddress = addresses.first; // Asic address for this elink + elinkPar.fChanAddress = addresses.second; // Channel addresses for this elink + elinkPar.fTimeOffset = SystemTimeOffset; + crobPar.fElinkParams.push_back(elinkPar); + } + par->fCrobParams.push_back(crobPar); + } + fAlgos[equip].SetParams(std::move(par)); + L_(debug) << "--- Configured equipment " << equip << " with " << numCrobs << " crobs"; + } + L_(info) << "--- Configured " << fAlgos.size() << " unpacker algorithms for TRD."; +} + +Unpack::Result_t Unpack::operator()(const fles::Timeslice& ts) const +{ + constexpr int SystemVersion = 0x01; + return DoUnpack(Subsystem::TRD, ts, SystemVersion); +} diff --git a/algo/detectors/trd/Unpack.h b/algo/detectors/trd/Unpack.h new file mode 100644 index 0000000000000000000000000000000000000000..b35c26b2304bfb7bde5ac65cc6a1f2303cce5fff --- /dev/null +++ b/algo/detectors/trd/Unpack.h @@ -0,0 +1,34 @@ +/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main + SPDX-License-Identifier: GPL-3.0-only + Authors: Felix Weiglhofer [committer], Dominik Smith */ + +#pragma once + +#include "CommonUnpacker.h" +#include "ReadoutConfig.h" +#include "UnpackMS.h" + +namespace cbm::algo::trd +{ + + namespace detail + { + using UnpackBase = CommonUnpacker<CbmTrdDigi, UnpackMS, UnpackMonitorData>; + } + + class Unpack : public detail::UnpackBase { + + public: + using Result_t = detail::UnpackBase::Result_t; + + Unpack(const ReadoutConfig& readout); + + Result_t operator()(const fles::Timeslice&) const; + + const ReadoutConfig& Readout() const { return fReadout; } + + private: + ReadoutConfig fReadout; + }; + +} // namespace cbm::algo::trd diff --git a/algo/detectors/trd2d/Unpack.cxx b/algo/detectors/trd2d/Unpack.cxx new file mode 100644 index 0000000000000000000000000000000000000000..16f82926fac58d225d5fefdcee4cc74370a45c85 --- /dev/null +++ b/algo/detectors/trd2d/Unpack.cxx @@ -0,0 +1,51 @@ +/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main + SPDX-License-Identifier: GPL-3.0-only + Authors: Felix Weiglhofer [committer], Dominik Smith */ + +#include "Unpack.h" + +#include "log.hpp" + +using namespace cbm::algo::trd2d; +using fles::Subsystem; + +Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout) +{ + constexpr i64 SystemTimeOffset = -510; + + // Create one algorithm per component for TRD and configure it with parameters + auto equipIdsTrd2d = fReadout.GetEquipmentIds(); + for (auto& equip : equipIdsTrd2d) { + + std::unique_ptr<trd2d::UnpackPar> par(new trd2d::UnpackPar()); + const size_t numAsics = fReadout.GetNumAsics(equip); + + for (size_t asic = 0; asic < numAsics; asic++) { + 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 + asicPar.fChanParams.push_back(chanPar); + } + auto comppars = fReadout.CompMap(equip); + par->fSystemTimeOffset = SystemTimeOffset; + par->fModId = comppars.moduleId; + par->fCrobId = comppars.crobId; + par->fAsicParams.push_back(asicPar); + } + fAlgos[equip].SetParams(std::move(par)); + L_(debug) << "--- Configured equipment " << equip << " with " << numAsics << " asics"; + } + L_(info) << "--- Configured " << fAlgos.size() << " unpacker algorithms for TRD2D."; +} + +Unpack::Result_t Unpack::operator()(const fles::Timeslice& ts) const +{ + constexpr int SystemVersion = 0x02; + return DoUnpack(Subsystem::TRD2D, ts, SystemVersion); +} diff --git a/algo/detectors/trd2d/Unpack.h b/algo/detectors/trd2d/Unpack.h new file mode 100644 index 0000000000000000000000000000000000000000..eac2415c06bef15862ac32599119d30e2798f5d8 --- /dev/null +++ b/algo/detectors/trd2d/Unpack.h @@ -0,0 +1,34 @@ +/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main + SPDX-License-Identifier: GPL-3.0-only + Authors: Felix Weiglhofer [committer], Dominik Smith */ + +#pragma once + +#include "CommonUnpacker.h" +#include "ReadoutConfig.h" +#include "UnpackMS.h" + +namespace cbm::algo::trd2d +{ + + namespace detail + { + using UnpackBase = CommonUnpacker<CbmTrdDigi, UnpackMS, UnpackMonitorData>; + } + + class Unpack : public detail::UnpackBase { + + public: + using Result_t = detail::UnpackBase::Result_t; + + Unpack(const ReadoutConfig& readout); + + Result_t operator()(const fles::Timeslice&) const; + + const ReadoutConfig& Readout() const { return fReadout; } + + private: + ReadoutConfig fReadout; + }; + +} // namespace cbm::algo::trd2d diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx index bd3cb4c656fa8f0e9a976ad3a85b41e6dcae4aec..785f6b936fef9da19ac79448fbb9cd637ac40fa1 100644 --- a/algo/global/Reco.cxx +++ b/algo/global/Reco.cxx @@ -20,6 +20,7 @@ #include <xpu/host.h> using namespace cbm::algo; +using fles::Subsystem; Reco::Reco() {} Reco::~Reco() {} @@ -60,7 +61,6 @@ void Reco::Init(const Options& opts) fContext.opts = opts; SetContext(&fContext); - fUnpack.SetContext(&fContext); fStsHitFinder.SetContext(&fContext); fTofCalibrator.SetContext(&fContext); fTofHitFinder.SetContext(&fContext); @@ -85,9 +85,22 @@ void Reco::Init(const Options& opts) fContext.recoParams = config::Read<RecoParams>(yaml); // Unpackers - fUnpack.Init(); + if (Opts().Has(Subsystem::BMON) && Opts().Has(Step::Unpack)) { + bmon::ReadoutConfig cfg{}; + fBmonUnpack = std::make_unique<bmon::Unpack>(cfg); + } + + if (Opts().Has(Subsystem::MUCH) && Opts().Has(Step::Unpack)) { + much::ReadoutConfig cfg{}; + fMuchUnpack = std::make_unique<much::Unpack>(cfg); + } + + if (Opts().Has(Subsystem::RICH) && Opts().Has(Step::Unpack)) { + rich::ReadoutConfig cfg{}; + fRichUnpack = std::make_unique<rich::Unpack>(cfg); + } - if (Opts().Has(fles::Subsystem::STS) && Opts().Has(Step::Unpack)) { + if (Opts().Has(Subsystem::STS) && Opts().Has(Step::Unpack)) { sts::ReadoutSetup readoutSetup = config::ReadFromFile<sts::ReadoutSetup>(Opts().ParamsDir() / "StsReadout.yaml"); auto chanMask = config::ReadFromFile<sts::ChannelMaskSet>(Opts().ParamsDir() / "StsChannelMaskSet.yaml"); sts::ReadoutConfig readout{readoutSetup, chanMask}; @@ -96,6 +109,23 @@ void Reco::Init(const Options& opts) fStsUnpack = std::make_unique<sts::Unpack>(cfg); } + if (Opts().Has(Subsystem::TOF) && Opts().Has(Step::Unpack)) { + tof::ReadoutConfig cfg{}; + fTofUnpack = std::make_unique<tof::Unpack>(cfg); + } + + if (Opts().Has(Subsystem::TRD) && Opts().Has(Step::Unpack)) { + yaml = YAML::LoadFile((Opts().ParamsDir() / "TrdReadoutSetup.yaml").string()); + auto cfg = config::Read<trd::ReadoutConfig>(yaml); + fTrdUnpack = std::make_unique<trd::Unpack>(cfg); + } + + if (Opts().Has(Subsystem::TRD2D) && Opts().Has(Step::Unpack)) { + yaml = YAML::LoadFile((Opts().ParamsDir() / "Trd2dReadoutSetup.yaml").string()); + auto cfg = config::Read<trd2d::ReadoutConfig>(yaml); + fTrd2dUnpack = std::make_unique<trd2d::Unpack>(cfg); + } + // --- Event building fs::path configFile = opts.ParamsDir() / "EventbuildConfig.yaml"; evbuild::Config config(YAML::LoadFile(configFile.string())); @@ -152,29 +182,22 @@ RecoResults Reco::Run(const fles::Timeslice& ts) xpu::scoped_timer timerU("Unpack", &procMon.timeUnpack); xpu::t_add_bytes(ts_utils::SizeBytes(ts)); - if (fStsUnpack) { - auto [stsDigis, stsMonitor] = (*fStsUnpack)(ts); - - digis.fSts = std::move(stsDigis); - QueueUnpackerMetricsDet(stsMonitor); - } - - auto [digisU, unpackMonitor] = fUnpack.Run(ts); + digis.fBmon = RunUnpacker(fBmonUnpack, ts); + digis.fMuch = RunUnpacker(fMuchUnpack, ts); + digis.fRich = RunUnpacker(fRichUnpack, ts); + digis.fSts = RunUnpacker(fStsUnpack, ts); + digis.fTof = RunUnpacker(fTofUnpack, ts); + digis.fTrd = RunUnpacker(fTrdUnpack, ts); + digis.fTrd2d = RunUnpacker(fTrd2dUnpack, ts); - digis.fMuch = std::move(digisU.fMuch); - digis.fTof = std::move(digisU.fTof); - digis.fBmon = std::move(digisU.fBmon); - digis.fTrd = std::move(digisU.fTrd); - digis.fTrd2d = std::move(digisU.fTrd2d); - digis.fRich = std::move(digisU.fRich); - digis.fPsd = std::move(digisU.fPsd); - digis.fFsd = std::move(digisU.fFsd); + // No unpackers for these yet + // digis.fPsd = RunUnpacker(fPsdUnpack, ts); + // digis.fFsd = RunUnpacker(fFsdUnpack, ts); L_(info) << "TS contains Digis: STS=" << digis.fSts.size() << " MUCH=" << digis.fMuch.size() << " TOF=" << digis.fTof.size() << " BMON=" << digis.fBmon.size() << " TRD=" << digis.fTrd.size() << " TRD2D=" << digis.fTrd2d.size() << " RICH=" << digis.fRich.size() << " PSD=" << digis.fPsd.size() << " FSD=" << digis.fFsd.size(); - QueueUnpackerMetrics(ts, unpackMonitor, digis); } // --- Digi event building @@ -232,6 +255,10 @@ RecoResults Reco::Run(const fles::Timeslice& ts) } } PrintTimings(procMon.time); + if (prevTsId) { + procMon.tsDelta = ts.index() - *prevTsId; + } + prevTsId = ts.index(); QueueProcessingMetrics(procMon); return results; @@ -263,59 +290,16 @@ void Reco::PrintTimings(xpu::timings& timings) } } -void Reco::QueueUnpackerMetrics(const fles::Timeslice& ts, const UnpackMonitorData& monitor, const DigiData& digis) +template<class Unpacker> +auto Reco::RunUnpacker(const std::unique_ptr<Unpacker>& unpacker, const fles::Timeslice& ts) + -> algo_traits::Output_t<Unpacker> { - if (!HasMonitor()) return; - - auto sizeBytes = [](const auto& d) { return d.size() * sizeof(d[0]); }; - auto expansionFactor = [&](size_t x, const auto& d) { - return d.size() > 0 ? static_cast<double>(sizeBytes(d)) / x : 0.0; - }; - - size_t tsDelta = ts.index() - prevTsId; - prevTsId = ts.index(); - - auto& stsDigis = digis.fSts; - auto& muchDigis = digis.fMuch; - auto& tofDigis = digis.fTof; - auto& bmonDigis = digis.fBmon; - auto& trdDigis = digis.fTrd; - auto& trd2dDigis = digis.fTrd2d; - auto& richDigis = digis.fRich; - - size_t nDigisTotal = sizeBytes(stsDigis) + sizeBytes(muchDigis) + sizeBytes(tofDigis) + sizeBytes(bmonDigis) - + sizeBytes(trdDigis) + sizeBytes(trd2dDigis) + sizeBytes(richDigis); - - double totalExpansionFactor = static_cast<double>(nDigisTotal) / monitor.fNumBytes; - - GetMonitor().QueueMetric("cbmreco", {{"hostname", fles::system::current_hostname()}, {"child", Opts().ChildId()}}, - { - {"tsIdDelta", tsDelta}, - {"unpackTimeTotal", monitor.fTime.wall()}, - {"unpackThroughput", monitor.fTime.throughput()}, - {"unpackBytesInMuch", monitor.fNumBytesInMuch}, - {"unpackBytesInTof", monitor.fNumBytesInTof}, - {"unpackBytesInBmon", monitor.fNumBytesInBmon}, - {"unpackBytesInTrd", monitor.fNumBytesInTrd}, - {"unpackBytesInTrd2d", monitor.fNumBytesInTrd2d}, - {"unpackBytesInRich", monitor.fNumBytesInRich}, - {"unpackBytesOutMuch", sizeBytes(muchDigis)}, - {"unpackBytesOutTof", sizeBytes(tofDigis)}, - {"unpackBytesOutBmon", sizeBytes(bmonDigis)}, - {"unpackBytesOutTrd", sizeBytes(trdDigis)}, - {"unpackBytesOutTrd2d", sizeBytes(trd2dDigis)}, - {"unpackBytesOutRich", sizeBytes(richDigis)}, - {"unpackExpansionFactorMuch", expansionFactor(monitor.fNumBytesInMuch, muchDigis)}, - {"unpackExpansionFactorTof", expansionFactor(monitor.fNumBytesInTof, tofDigis)}, - {"unpackExpansionFactorBmon", expansionFactor(monitor.fNumBytesInBmon, bmonDigis)}, - {"unpackExpansionFactorTrd", expansionFactor(monitor.fNumBytesInTrd, trdDigis)}, - {"unpackExpansionFactorTrd2d", expansionFactor(monitor.fNumBytesInTrd2d, trd2dDigis)}, - {"unpackExpansionFactorRich", expansionFactor(monitor.fNumBytesInRich, richDigis)}, - {"unpackExpansionFactorTotal", totalExpansionFactor}, - {"unpackNumCompUsed", monitor.fNumCompUsed}, - {"unpackNumErrInvalidEqId", monitor.fNumErrInvalidEqId}, - {"unpackNumErrInvalidSysVer", monitor.fNumErrInvalidSysVer}, - }); + if (!unpacker) { + return {}; + } + auto [digis, monitor] = (*unpacker)(ts); + QueueUnpackerMetricsDet(monitor); + return digis; } template<class MSMonitor> @@ -446,9 +430,15 @@ void Reco::QueueProcessingMetrics(const ProcessingMonitor& mon) return; } + MetricFieldSet fields = { + {"processingTimeTotal", mon.time.wall()}, + {"processingThroughput", mon.time.throughput()}, + }; + + if (mon.tsDelta) { + fields.emplace_back("tsDelta", *mon.tsDelta); + } + GetMonitor().QueueMetric("cbmreco", {{"hostname", fles::system::current_hostname()}, {"child", Opts().ChildId()}}, - { - {"processingTimeTotal", mon.time.wall()}, - {"processingThroughput", mon.time.throughput()}, - }); + std::move(fields)); } diff --git a/algo/global/Reco.h b/algo/global/Reco.h index 8649f997df76961fce165e40f62f118cce1c47bb..569c7bbe8e17d511a2c3ffcdfcf6b2a6727f3cc4 100644 --- a/algo/global/Reco.h +++ b/algo/global/Reco.h @@ -4,16 +4,22 @@ #ifndef CBM_ALGO_GLOBAL_RECO_H #define CBM_ALGO_GLOBAL_RECO_H +#include "AlgoTraits.h" #include "EventbuildChain.h" #include "HistogramSender.h" #include "SubChain.h" -#include "UnpackChain.h" +#include "bmon/Unpack.h" #include "ca/TrackingChain.h" #include "global/RecoResults.h" +#include "much/Unpack.h" +#include "rich/Unpack.h" #include "sts/HitfinderChain.h" #include "sts/Unpack.h" #include "tof/CalibratorChain.h" #include "tof/HitfinderChain.h" +#include "tof/Unpack.h" +#include "trd/Unpack.h" +#include "trd2d/Unpack.h" #include <xpu/host.h> @@ -27,8 +33,9 @@ namespace cbm::algo class Options; struct ProcessingMonitor { - xpu::timings time; //< total processing time - xpu::timings timeUnpack; //< time spent in unpacking + xpu::timings time; //< total processing time + xpu::timings timeUnpack; //< time spent in unpacking + std::optional<i64> tsDelta; //< id difference between current and previous timeslice }; class Reco : SubChain { @@ -52,17 +59,32 @@ namespace cbm::algo xpu::timings fTimesliceTimesAcc; std::shared_ptr<HistogramSender> fSender; - size_t prevTsId = 0; + std::optional<u64> prevTsId; + + // BMON + std::unique_ptr<bmon::Unpack> fBmonUnpack; + + // MUCH + std::unique_ptr<much::Unpack> fMuchUnpack; + + // RICH + std::unique_ptr<rich::Unpack> fRichUnpack; // STS - UnpackChain fUnpack; std::unique_ptr<sts::Unpack> fStsUnpack; sts::HitfinderChain fStsHitFinder; // TOF + std::unique_ptr<tof::Unpack> fTofUnpack; tof::HitfinderChain fTofHitFinder; tof::CalibratorChain fTofCalibrator; + // TRD + std::unique_ptr<trd::Unpack> fTrdUnpack; + + // TRD2D + std::unique_ptr<trd2d::Unpack> fTrd2dUnpack; + // Eventbuilding std::unique_ptr<evbuild::EventbuildChain> fEventBuild; @@ -71,7 +93,9 @@ namespace cbm::algo void Validate(const Options& opts); - void QueueUnpackerMetrics(const fles::Timeslice&, const UnpackMonitorData&, const DigiData&); + template<class Unpacker> + auto RunUnpacker(const std::unique_ptr<Unpacker>&, const fles::Timeslice&) -> algo_traits::Output_t<Unpacker>; + template<class MSMonitor> void QueueUnpackerMetricsDet(const UnpackMonitor<MSMonitor>&); void QueueStsRecoMetrics(const sts::HitfinderMonitor&); diff --git a/algo/unpack/CommonUnpacker.cxx b/algo/unpack/CommonUnpacker.cxx index ab4d188b29bd5563e39fec686c318d1c7940f583..b1c657bc7dceb78da23d1afe046e2f155aafc736 100644 --- a/algo/unpack/CommonUnpacker.cxx +++ b/algo/unpack/CommonUnpacker.cxx @@ -29,6 +29,7 @@ detail::MSData::MSData(const fles::Timeslice& ts, fles::Subsystem subsystem, gsl continue; } + monitor.numComponents++; monitor.sizeBytesIn += ts.size_component(comp); monitor.numMs += numMsInComp; for (u64 mslice = 0; mslice < numMsInComp; mslice++) { diff --git a/algo/unpack/CommonUnpacker.h b/algo/unpack/CommonUnpacker.h index 2db2791b2d7d100b45dd0f87d80ff70281e72c45..35bf7fe552feac2bd3208116a774ae8161ec6ee3 100644 --- a/algo/unpack/CommonUnpacker.h +++ b/algo/unpack/CommonUnpacker.h @@ -24,6 +24,7 @@ namespace cbm::algo struct UnpackMonitorBase { fles::Subsystem system; // subsystem + size_t numComponents = 0; // number of components used size_t numMs = 0; // number of microslices size_t sizeBytesIn = 0; // total size of microslice contents size_t sizeBytesOut = 0; // total size of unpacked digis diff --git a/algo/unpack/Unpack.cxx b/algo/unpack/Unpack.cxx deleted file mode 100644 index 76912437224e489d1a28e422827494c3500afdb4..0000000000000000000000000000000000000000 --- a/algo/unpack/Unpack.cxx +++ /dev/null @@ -1,440 +0,0 @@ -/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt - SPDX-License-Identifier: GPL-3.0-only - Authors: Volker Friese [committer], Sebastian Heinemann, Felix Weiglhofer */ - - -#include "Unpack.h" - -#include "compat/Algorithm.h" -#include "compat/OpenMP.h" -#include "log.hpp" -#include "util/TsUtils.h" - -#include <chrono> - -#include <xpu/host.h> - -using namespace std; -using fles::Subsystem; - -namespace cbm::algo -{ - // ----- Execution ------------------------------------------------------- - Unpack::resultType Unpack::operator()(const fles::Timeslice* timeslice) - { - xpu::push_timer("Unpack"); - xpu::t_add_bytes(ts_utils::SizeBytes(*timeslice)); - - // --- Output data - resultType result = {}; - DigiData& digiTs = result.first; - UnpackMonitorData& monitor = result.second; - - if (DetectorEnabled(Subsystem::TOF)) { - monitor.fNumBytesInTof += - ParallelMsLoop(Subsystem::TOF, monitor, digiTs.fTof, monitor.fTof, *timeslice, fAlgoTof, 0x00); - } - - if (DetectorEnabled(Subsystem::BMON)) { - monitor.fNumBytesInBmon += - ParallelMsLoop(Subsystem::BMON, monitor, digiTs.fBmon, monitor.fBmon, *timeslice, fAlgoBmon, 0x00); - } - - if (DetectorEnabled(Subsystem::MUCH)) { - monitor.fNumBytesInMuch += - ParallelMsLoop(Subsystem::MUCH, monitor, digiTs.fMuch, monitor.fMuch, *timeslice, fAlgoMuch, 0x20); - } - - if (DetectorEnabled(Subsystem::RICH)) { - monitor.fNumBytesInRich += - ParallelMsLoop(Subsystem::RICH, monitor, digiTs.fRich, monitor.fRich, *timeslice, fAlgoRich, 0x03); - } - - if (DetectorEnabled(Subsystem::TRD)) { - monitor.fNumBytesInTrd += - ParallelMsLoop(Subsystem::TRD, monitor, digiTs.fTrd, monitor.fTrd, *timeslice, fAlgoTrd, 0x01); - } - - if (DetectorEnabled(Subsystem::TRD2D)) { - monitor.fNumBytesInTrd2d += - ParallelMsLoop(Subsystem::TRD2D, monitor, digiTs.fTrd2d, monitor.fTrd2d, *timeslice, fAlgoTrd2d, 0x02); - } - - - // --- Component loop - for (uint64_t comp = 0; comp < timeslice->num_components(); comp++) { - - // System ID of current component - const auto subsystem = static_cast<Subsystem>(timeslice->descriptor(comp, 0).sys_id); - - if (!DetectorEnabled(subsystem)) continue; - - xpu::scoped_timer t1(fles::to_string(subsystem)); - xpu::t_add_bytes(timeslice->size_component(comp)); - - // Equipment ID of current component - // const uint16_t equipmentId = timeslice->descriptor(comp, 0).eq_id; - - // The current algorithms work for the format versions hard-coded as parameters to MsLoop() below. - // Other versions are not yet supported. - // In the future, different data formats will be supported by instantiating different - // algorithms depending on the version. - - // if (subsystem == Subsystem::STS) { - // MsLoop(timeslice, fAlgoSts, comp, equipmentId, &digiTs.fSts, monitor, &monitor.fSts, 0x20); - // } - // if (subsystem == Subsystem::MUCH) { - // MsLoop(timeslice, fAlgoMuch, comp, equipmentId, &digiTs.fMuch, monitor, &monitor.fMuch, 0x20); - // } - // if (subsystem == Subsystem::TOF) { - // MsLoop(timeslice, fAlgoTof, comp, equipmentId, &digiTs.fTof, monitor, &monitor.fTof, 0x00); - // } - // if (subsystem == Subsystem::BMON) { - // MsLoop(timeslice, fAlgoBmon, comp, equipmentId, &digiTs.fBmon, monitor, &monitor.fBmon, 0x00); - // } - // if (subsystem == Subsystem::TRD) { - // monitor.fNumBytesInTrd += - // MsLoop(timeslice, fAlgoTrd, comp, equipmentId, &digiTs.fTrd, monitor, &monitor.fTrd, 0x01); - // } - // if (subsystem == Subsystem::TRD2D) { - // monitor.fNumBytesInTrd2d += - // MsLoop(timeslice, fAlgoTrd2d, comp, equipmentId, &digiTs.fTrd2d, monitor, &monitor.fTrd2d, 0x02); - // } - // if (subsystem == Subsystem::RICH) { - // monitor.fNumBytesInRich += - // MsLoop(timeslice, fAlgoRich, comp, equipmentId, &digiTs.fRich, monitor, &monitor.fRich, 0x03); - // } - } //# component - - // --- Sorting of output digis. Is required by both digi trigger and event builder. - - xpu::push_timer("Sort"); - DoSort(digiTs.fSts); - DoSort(digiTs.fMuch); - DoSort(digiTs.fTof); - DoSort(digiTs.fBmon); - DoSort(digiTs.fTrd); - DoSort(digiTs.fTrd2d); - DoSort(digiTs.fRich); - xpu::pop_timer(); - - monitor.fTime = xpu::pop_timer(); - - return result; - } - // ---------------------------------------------------------------------------- - - - // ---------------------------------------------------------------------------- - std::pair<size_t, size_t> Unpack::ParallelInit(const fles::Timeslice& ts, Subsystem subsystem, - gsl::span<const uint16_t> legalEqIds, uint8_t sys_ver, - UnpackMonitorData& monitor, std::vector<u16>& msEqIds, - std::vector<fles::MicrosliceDescriptor>& msDesc, - std::vector<const u8*>& msContent) - { - size_t numMs = 0; - size_t sizeBytes = 0; - - for (uint64_t comp = 0; comp < ts.num_components(); comp++) { - auto this_subsystem = static_cast<Subsystem>(ts.descriptor(comp, 0).sys_id); - - if (this_subsystem == subsystem) { - const u64 numMsInComp = ts.num_microslices(comp); - const u16 componentId = ts.descriptor(comp, 0).eq_id; - - if (ts.descriptor(comp, 0).sys_ver != sys_ver) { - monitor.fNumErrInvalidSysVer++; - continue; - } - - if (std::find(legalEqIds.begin(), legalEqIds.end(), componentId) == legalEqIds.end()) { - monitor.fNumErrInvalidEqId++; - continue; - } - - sizeBytes += ts.size_component(comp); - numMs += numMsInComp; - for (u64 mslice = 0; mslice < numMsInComp; mslice++) { - msEqIds.push_back(componentId); - msDesc.push_back(ts.descriptor(comp, mslice)); - msContent.push_back(ts.content(comp, mslice)); - } - } - } - - return {numMs, sizeBytes}; - } - // ---------------------------------------------------------------------------- - - - // ---------------------------------------------------------------------------- - template<class Digi, class UnpackAlgo, class Monitor> - size_t Unpack::ParallelMsLoop(const Subsystem subsystem, UnpackMonitorData& genericMonitor, PODVector<Digi>& digisOut, - std::vector<Monitor>& monitorOut, const fles::Timeslice& ts, - const std::map<u16, UnpackAlgo>& algos, u8 sys_ver) - { - xpu::scoped_timer t_(fles::to_string(subsystem)); - - std::vector<u16> msEqIds; // equipment ids of microslices - std::vector<fles::MicrosliceDescriptor> msDesc; // microslice descriptors - std::vector<const u8*> msContent; // pointer to microslice content - auto legalEqIds = GetEqIds(algos); - - // Workaround a problem for some clang versions - // Capturing structured bindings either is avaialable with C++20 - // Obviously GCC supports it already and has no problems but clang or at - // least some clang versions fail during compilation - // auto [numMs, sizeBytes] = - // ParallelInit(ts, subsystem, gsl::make_span(legalEqIds), sys_ver, genericMonitor, msEqIds, msDesc, msContent); - std::pair<size_t, size_t> tmp = - ParallelInit(ts, subsystem, gsl::make_span(legalEqIds), sys_ver, genericMonitor, msEqIds, msDesc, msContent); - auto numMs = tmp.first; - auto sizeBytes = tmp.second; - std::vector<std::vector<Digi>> msDigis(numMs); // unpacked digis per microslice - std::vector<Monitor> monitor(numMs); // unpacking monitoring data per microslice - - xpu::t_add_bytes(sizeBytes); - genericMonitor.fNumBytes += sizeBytes; - - xpu::push_timer("Unpack"); - xpu::t_add_bytes(sizeBytes); - CBM_PARALLEL_FOR(schedule(dynamic)) - for (size_t i = 0; i < numMs; i++) { - auto result = algos.at(msEqIds[i])(msContent[i], msDesc[i], ts.start_time()); - msDigis[i] = std::move(result.first); - monitor[i] = std::move(result.second); - } - xpu::pop_timer(); - - xpu::push_timer("Resize"); - size_t nDigisTotal = 0; - for (const auto& digis : msDigis) { - nDigisTotal += digis.size(); - } - digisOut.resize(nDigisTotal); - xpu::pop_timer(); - - xpu::push_timer("Merge"); - xpu::t_add_bytes(nDigisTotal * sizeof(Digi)); - CBM_PARALLEL_FOR(schedule(dynamic)) - for (size_t i = 0; i < numMs; i++) { - size_t offset = 0; - for (size_t x = 0; x < i; x++) - offset += msDigis[x].size(); - std::copy(msDigis[i].begin(), msDigis[i].end(), digisOut.begin() + offset); - } - xpu::pop_timer(); - - monitorOut = std::move(monitor); - - return sizeBytes; - } - // ---------------------------------------------------------------------------- - - - // ----------------- Microslice loop ------------------------------------------ - template<class Digi, class UnpackAlgo, class MonitorData> - size_t Unpack::MsLoop(const fles::Timeslice* timeslice, std::map<uint16_t, UnpackAlgo>& algoMap, const uint64_t comp, - const uint16_t eqId, PODVector<Digi>* digis, UnpackMonitorData& monitor, - std::vector<MonitorData>* monitorMs, uint8_t sys_ver) - { - // --- Component log - size_t numBytesInComp = 0; - size_t numDigisInComp = 0; - - // For profiling - const auto starttime = std::chrono::high_resolution_clock::now(); - - // Get Unpacker - const auto algoIt = algoMap.find(eqId); - if (algoIt == algoMap.end()) { - monitor.fNumErrInvalidEqId++; - return 0; - } - UnpackAlgo& algo = algoIt->second; - - if (timeslice->descriptor(comp, 0).sys_ver != sys_ver) { - monitor.fNumErrInvalidSysVer++; - return 0; - } - - const uint64_t numMsInComp = timeslice->num_microslices(comp); - - for (uint64_t mslice = 0; mslice < numMsInComp; mslice++) { - const auto msDescriptor = timeslice->descriptor(comp, mslice); - const auto msContent = timeslice->content(comp, mslice); - auto result = algo(msContent, msDescriptor, timeslice->start_time()); - L_(debug) << "Unpack::MsLoop(): Component " << comp << ", microslice " << mslice << ", digis " - << result.first.size() << ", " << result.second.print(); - numBytesInComp += msDescriptor.size; - numDigisInComp += result.first.size(); - digis->insert(digis->end(), result.first.begin(), result.first.end()); - monitorMs->push_back(result.second); - } - // Get elapsed time - const auto endtime = std::chrono::high_resolution_clock::now(); - const auto duration = std::chrono::duration_cast<std::chrono::microseconds>(endtime - starttime); - - L_(debug) << "Unpack(): Component " << comp << ", subsystem " - << fles::to_string(static_cast<Subsystem>(timeslice->descriptor(comp, 0).sys_id)) << ", microslices " - << numMsInComp << " input size " << numBytesInComp << " bytes," - << " digis " << numDigisInComp << ", CPU time " << duration.count() / 1000. << " ms"; - - monitor.fNumMs += numMsInComp; - monitor.fNumBytes += numBytesInComp; - monitor.fNumDigis += numDigisInComp; - monitor.fNumCompUsed++; - - return numBytesInComp; - } - // ---------------------------------------------------------------------------- - - - // ----- Initialisation --------------------------------------------------- - void Unpack::Init(std::vector<Subsystem> subIds) - { - fSubsystems = subIds; - - // --- Common parameters for all components for STS - - // Create one algorithm per component for STS and configure it with parameters - - - // Create one algorithm per component for MUCH and configure it with parameters - auto equipIdsMuch = fMuchConfig.GetEquipmentIds(); - for (auto& equip : equipIdsMuch) { - std::unique_ptr<much::UnpackPar> par(new much::UnpackPar()); - const size_t numElinks = fMuchConfig.GetNumElinks(equip); - for (size_t elink = 0; elink < numElinks; elink++) { - much::UnpackElinkPar elinkPar; - elinkPar.fAddress = fMuchConfig.Map(equip, elink); // Vector of MUCH addresses for this elink - elinkPar.fTimeOffset = fSystemTimeOffset[Subsystem::MUCH]; - elinkPar.fChanMask = fMuchConfig.MaskMap(equip, elink); - par->fElinkParams.push_back(elinkPar); - } - fAlgoMuch[equip].SetParams(std::move(par)); - L_(debug) << "--- Configured equipment " << equip << " with " << numElinks << " elinks"; - } - - // Create one algorithm per component for TOF and configure it with parameters - auto equipIdsTof = fTofConfig.GetEquipmentIds(); - for (auto& equip : equipIdsTof) { - std::unique_ptr<tof::UnpackPar> par(new tof::UnpackPar()); - const size_t numElinks = fTofConfig.GetNumElinks(equip); - for (size_t elink = 0; elink < numElinks; elink++) { - tof::UnpackElinkPar elinkPar; - elinkPar.fChannelUId = fTofConfig.Map(equip, elink); // Vector of TOF addresses for this elink - elinkPar.fTimeOffset = fSystemTimeOffset[Subsystem::TOF]; - par->fElinkParams.push_back(elinkPar); - } - fAlgoTof[equip].SetParams(std::move(par)); - L_(debug) << "--- Configured equipment " << equip << " with " << numElinks << " elinks"; - } - - // Create one algorithm per component for Bmon and configure it with parameters - auto equipIdsBmon = fBmonConfig.GetEquipmentIds(); - for (auto& equip : equipIdsBmon) { - std::unique_ptr<bmon::UnpackPar> par(new bmon::UnpackPar()); - const size_t numElinks = fBmonConfig.GetNumElinks(equip); - for (size_t elink = 0; elink < numElinks; elink++) { - bmon::UnpackElinkPar elinkPar; - elinkPar.fChannelUId = fBmonConfig.Map(equip, elink); // Vector of Bmon addresses for this elink - elinkPar.fTimeOffset = fSystemTimeOffset[Subsystem::BMON]; - par->fElinkParams.push_back(elinkPar); - } - fAlgoBmon[equip].SetParams(std::move(par)); - L_(debug) << "--- Configured equipment " << equip << " with " << numElinks << " elinks"; - } - - // Create one algorithm per component and configure it with parameters - auto equipIdsRich = fRichConfig.GetEquipmentIds(); - for (auto& equip : equipIdsRich) { - std::unique_ptr<rich::UnpackPar> par(new rich::UnpackPar()); - std::map<uint32_t, std::vector<double>> compMap = fRichConfig.Map(equip); - for (auto const& val : compMap) { - uint32_t address = val.first; - par->fElinkParams[address].fToTshift = val.second; - par->fElinkParams[address].fTimeOffset = fSystemTimeOffset[Subsystem::RICH]; - } - fAlgoRich[equip].SetParams(std::move(par)); - L_(info) << "--- Configured equipment " << equip << " with " << fRichConfig.GetNumElinks(equip) << " elinks"; - } - - // Create one algorithm per component for TRD and configure it with parameters - auto equipIdsTrd = fTrdConfig.GetEquipmentIds(); - for (auto& equip : equipIdsTrd) { - - std::unique_ptr<trd::UnpackPar> par(new trd::UnpackPar()); - const size_t numCrobs = fTrdConfig.GetNumCrobs(equip); - - for (size_t crob = 0; crob < numCrobs; crob++) { - trd::UnpackCrobPar crobPar; - const size_t numElinks = fTrdConfig.GetNumElinks(equip, crob); - - for (size_t elink = 0; elink < numElinks; elink++) { - trd::UnpackElinkPar elinkPar; - auto addresses = fTrdConfig.Map(equip, crob, elink); - elinkPar.fAddress = addresses.first; // Asic address for this elink - elinkPar.fChanAddress = addresses.second; // Channel addresses for this elink - elinkPar.fTimeOffset = fSystemTimeOffset[Subsystem::TRD]; - crobPar.fElinkParams.push_back(elinkPar); - } - par->fCrobParams.push_back(crobPar); - } - fAlgoTrd[equip].SetParams(std::move(par)); - L_(debug) << "--- Configured equipment " << equip << " with " << numCrobs << " crobs"; - } - - // Create one algorithm per component for TRD2D and configure it with parameters - auto equipIdsTrd2d = fTrd2dConfig.GetEquipmentIds(); - for (auto& equip : equipIdsTrd2d) { - - std::unique_ptr<trd2d::UnpackPar> par(new trd2d::UnpackPar()); - const size_t numAsics = fTrd2dConfig.GetNumAsics(equip); - - for (size_t asic = 0; asic < numAsics; asic++) { - trd2d::UnpackAsicPar asicPar; - const size_t numChans = fTrd2dConfig.GetNumChans(equip, asic); - - for (size_t chan = 0; chan < numChans; chan++) { - trd2d::UnpackChannelPar chanPar; - auto pars = fTrd2dConfig.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 - asicPar.fChanParams.push_back(chanPar); - } - auto comppars = fTrd2dConfig.CompMap(equip); - par->fSystemTimeOffset = fSystemTimeOffset[Subsystem::TRD2D]; - par->fModId = comppars.moduleId; - par->fCrobId = comppars.crobId; - par->fAsicParams.push_back(asicPar); - } - fAlgoTrd2d[equip].SetParams(std::move(par)); - L_(debug) << "--- Configured equipment " << equip << " with " << numAsics << " asics"; - } - - // L_(debug) << "Readout map:" << fStsConfig.PrintReadoutMap(); - L_(info) << "--- Configured " << fAlgoMuch.size() << " unpacker algorithms for MUCH."; - L_(info) << "--- Configured " << fAlgoRich.size() << " unpacker algorithms for RICH."; - // L_(debug) << "Readout map:" << fRichConfig.PrintReadoutMap(); - L_(info) << "--- Configured " << fAlgoTof.size() << " unpacker algorithms for TOF."; - L_(info) << "--- Configured " << fAlgoTrd.size() << " unpacker algorithms for TRD."; - L_(info) << "--- Configured " << fAlgoTrd2d.size() << " unpacker algorithms for TRD2D."; - L_(info) << "--- Configured " << fAlgoBmon.size() << " unpacker algorithms for Bmon."; - L_(info) << "=================================================="; - } - // ---------------------------------------------------------------------------- - - - // ---------------------------------------------------------------------------- - template<class Digi> - void Unpack::DoSort(PODVector<Digi>& digis) - { - xpu::t_add_bytes(digis.size() * sizeof(Digi)); // Add bytes to timer, assumes xpu::timers are started in operator() - Sort(digis.begin(), digis.end(), - [](const Digi& digi1, const Digi& digi2) { return digi1.GetTime() < digi2.GetTime(); }); - } - - -} /* namespace cbm::algo */ diff --git a/algo/unpack/Unpack.h b/algo/unpack/Unpack.h deleted file mode 100644 index dc569130349502211ee9bd4bd179713bd320507f..0000000000000000000000000000000000000000 --- a/algo/unpack/Unpack.h +++ /dev/null @@ -1,195 +0,0 @@ -/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt - SPDX-License-Identifier: GPL-3.0-only - Authors: Volker Friese, Dominik Smith [committer], Sebastian Heinemann, Felix Weiglhofer */ - - -#ifndef UNPACK_H -#define UNPACK_H 1 - -#include "DigiData.h" -#include "PODVector.h" -#include "bmon/ReadoutConfig.h" -#include "bmon/UnpackMS.h" -#include "much/ReadoutConfig.h" -#include "much/UnpackMS.h" -#include "rich/ReadoutConfig.h" -#include "rich/UnpackMS.h" -#include "sts/Digi.h" -#include "tof/ReadoutConfig.h" -#include "tof/UnpackMS.h" -#include "trd/ReadoutConfig.h" -#include "trd/UnpackMS.h" -#include "trd2d/ReadoutConfig.h" -#include "trd2d/UnpackMS.h" - -#include <gsl/span> -#include <optional> -#include <sstream> -#include <vector> - -#include <xpu/host.h> - -namespace cbm::algo -{ - - /** @struct UnpackMonitorData - ** @author Dominik Smith <d.smith@gsi.de> - ** @since 2 Jun 2023 - ** @brief Monitoring data for unpacking - **/ - struct UnpackMonitorData { - std::vector<much::UnpackMonitorData> fMuch; ///< Monitoring data for MUCH - std::vector<tof::UnpackMonitorData> fTof; ///< Monitoring data for TOF - std::vector<bmon::UnpackMonitorData> fBmon; ///< Monitoring data for Bmon - std::vector<trd::UnpackMonitorData> fTrd; ///< Monitoring data for TRD - std::vector<trd2d::UnpackMonitorData> fTrd2d; ///< Monitoring data for TRD2D - std::vector<rich::UnpackMonitorData> fRich; ///< Monitoring data for RICH - xpu::timings fTime; - size_t fNumMs = 0; - size_t fNumBytes = 0; - size_t fNumBytesInMuch = 0; - size_t fNumBytesInTof = 0; - size_t fNumBytesInBmon = 0; - size_t fNumBytesInTrd = 0; - size_t fNumBytesInTrd2d = 0; - size_t fNumBytesInRich = 0; - size_t fNumDigis = 0; - size_t fNumCompUsed = 0; - size_t fNumErrInvalidEqId = 0; - size_t fNumErrInvalidSysVer = 0; - std::string print() const - { - std::stringstream ss; - ss << "TS stats: num MS " << fNumMs << ", bytes " << fNumBytes << ", digis " << fNumDigis << ", components " - << fNumCompUsed << ", invalidEqIds " << fNumErrInvalidEqId << ", invalidSysVersions " << fNumErrInvalidSysVer - << std::endl; - return ss.str(); - } - }; - - /** @class Unpack - ** @brief Algo class for unpacking digi timeslicess - ** @author Dominik Smith <d.smith@gsi.de> - ** @since 02.06.2023 - ** - **/ - class Unpack { - - public: - typedef std::pair<DigiData, UnpackMonitorData> resultType; - using Subsystem = fles::Subsystem; - - /** @brief Algorithm execution - ** @param fles timeslice to unpack - ** @return pair: digi timeslice, monitoring data - **/ - resultType operator()(const fles::Timeslice* timeslice); - - /** @brief Default constructor **/ - Unpack(){}; - - /** @brief Destructor **/ - ~Unpack(){}; - - /** @brief Parameters for MUCH unpackers **/ - much::ReadoutConfig fMuchConfig{}; - - /** @brief Parameters for TOF unpackers **/ - tof::ReadoutConfig fTofConfig{}; - - /** @brief Parameters for Bmon unpackers **/ - bmon::ReadoutConfig fBmonConfig{}; - - /** @brief Parameters for TRD unpackers **/ - trd::ReadoutConfig fTrdConfig{}; - - /** @brief Parameters for TRD2D unpackers **/ - trd2d::ReadoutConfig fTrd2dConfig{}; - - /** @brief Parameters for RICH unpackers **/ - rich::ReadoutConfig fRichConfig{}; - - /** @brief Initialize unpackers and fill parameters from config objects - * @param subIds: vector of subsystem identifiers to unpack, default: all - * @see Init() - **/ - void Init(std::vector<fles::Subsystem> subIds = { - Subsystem::STS, - Subsystem::MUCH, - Subsystem::TOF, - Subsystem::BMON, - Subsystem::TRD, - Subsystem::TRD2D, - Subsystem::RICH, - }); - - bool DetectorEnabled(Subsystem subsystem) - { - return std::find(fSubsystems.begin(), fSubsystems.end(), subsystem) != fSubsystems.end(); - } - - private: // methods - /** @brief Microslice loop **/ - template<class Digi, class UnpackAlgo, class MonitorData> - size_t MsLoop(const fles::Timeslice* timeslice, std::map<uint16_t, UnpackAlgo>& algoMap, const uint64_t comp, - const uint16_t eqId, PODVector<Digi>* digis, UnpackMonitorData& monitor, - std::vector<MonitorData>* monitorMs, uint8_t sys_ver); - - /** @brief Parallel microslice loop **/ - template<class Digi, class UnpackAlgo, class Monitor> - size_t ParallelMsLoop(const Subsystem subsystem, UnpackMonitorData& monitor, PODVector<Digi>& digisOut, - std::vector<Monitor>& monitorOut, const fles::Timeslice& ts, - const std::map<u16, UnpackAlgo>& algos, u8 sys_ver); - - std::pair<size_t, size_t> ParallelInit(const fles::Timeslice& ts, Subsystem subsystem, - gsl::span<const uint16_t> legalEqIds, uint8_t sys_ver, - UnpackMonitorData& monitor, std::vector<u16>& eqIds, - std::vector<fles::MicrosliceDescriptor>& msDesc, - std::vector<const u8*>& msContent); - - /** @brief Sort Digis and add bytes to timer for throughput */ - template<class Digi> - void DoSort(PODVector<Digi>& digis); - - - private: // members - std::vector<Subsystem> fSubsystems = {}; ///< Detector identifiers to unpack - - /** @brief MUCH unpackers **/ - std::map<uint16_t, much::UnpackMS> fAlgoMuch = {}; - - /** @brief TOF unpackers **/ - std::map<uint16_t, tof::UnpackMS> fAlgoTof = {}; - - /** @brief Bmon unpackers **/ - std::map<uint16_t, bmon::UnpackMS> fAlgoBmon = {}; - - /** @brief TRD unpackers **/ - std::map<uint16_t, trd::UnpackMS> fAlgoTrd = {}; - - /** @brief TRD2D unpackers **/ - std::map<uint16_t, trd2d::UnpackMS> fAlgoTrd2d = {}; - - /** @brief RICH unpackers **/ - std::map<uint16_t, rich::UnpackMS> fAlgoRich = {}; - - /** @brief System time offsets **/ - std::map<Subsystem, int32_t> fSystemTimeOffset = { - {Subsystem::STS, -970}, {Subsystem::MUCH, -980}, {Subsystem::RICH, 100}, {Subsystem::TOF, 40}, - {Subsystem::BMON, 0}, {Subsystem::TRD, 1300}, {Subsystem::TRD2D, -510}}; - - private: // methods - template<typename UnpackAlgo> - std::vector<uint16_t> GetEqIds(const std::map<uint16_t, UnpackAlgo>& algoMap) const - { - std::vector<uint16_t> eqIds; - eqIds.reserve(algoMap.size()); - for (const auto& [eqId, algo] : algoMap) { - eqIds.push_back(eqId); - } - return eqIds; - } - }; -} // namespace cbm::algo - -#endif /* UNPACK_H */ diff --git a/algo/unpack/UnpackChain.cxx b/algo/unpack/UnpackChain.cxx deleted file mode 100644 index 8dd57874cbb3b95fe49440fcfb34c8fab4c63f3c..0000000000000000000000000000000000000000 --- a/algo/unpack/UnpackChain.cxx +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main - SPDX-License-Identifier: GPL-3.0-only - Authors: Felix Weiglhofer [committer] */ -#include "UnpackChain.h" - -#include "config/Yaml.h" - -using namespace cbm::algo; -using fles::Subsystem; - -void UnpackChain::Init() -{ - if (Opts().Has(Subsystem::TRD)) { - auto yaml = YAML::LoadFile((Opts().ParamsDir() / "TrdReadoutSetup.yaml").string()); - fUnpack.fTrdConfig = config::Read<trd::ReadoutConfig>(yaml); - } - if (Opts().Has(Subsystem::TRD2D)) { - auto yaml = YAML::LoadFile((Opts().ParamsDir() / "Trd2dReadoutSetup.yaml").string()); - fUnpack.fTrd2dConfig = config::Read<trd2d::ReadoutConfig>(yaml); - } - fUnpack.Init(Opts().Detectors()); -} - -Unpack::resultType UnpackChain::Run(const fles::Timeslice& timeslice) -{ - auto result = fUnpack(×lice); - - return result; -} diff --git a/algo/unpack/UnpackChain.h b/algo/unpack/UnpackChain.h deleted file mode 100644 index fbab36a67fbfde10c74b28baaed1a67b005a0d85..0000000000000000000000000000000000000000 --- a/algo/unpack/UnpackChain.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main - SPDX-License-Identifier: GPL-3.0-only - Authors: Felix Weiglhofer [committer] */ -#ifndef CBM_ALGO_UNPACK_UNPACKCHAIN_H -#define CBM_ALGO_UNPACK_UNPACKCHAIN_H - -#include "SubChain.h" -#include "Unpack.h" - -namespace cbm::algo -{ - - class UnpackChain : public SubChain { - - public: - void Init(); - - Unpack::resultType Run(const fles::Timeslice&); - - private: - Unpack fUnpack; - }; - -} // namespace cbm::algo - - -#endif //CBM_ALGO_UNPACK_UNPACKCHAIN_H diff --git a/reco/tasks/CbmTaskUnpack.cxx b/reco/tasks/CbmTaskUnpack.cxx index aea57d1d8e71819c61d8f2459923ddbb37f08b7e..378a3935776860f161d6538e0a4bc60e9370fcf4 100644 --- a/reco/tasks/CbmTaskUnpack.cxx +++ b/reco/tasks/CbmTaskUnpack.cxx @@ -17,9 +17,9 @@ #include "CbmTrdParSetAsic.h" #include "CbmTrdParSetDigi.h" #include "CbmTrdParSpadic.h" - #include "MicrosliceDescriptor.hpp" #include "System.hpp" +#include "config/Yaml.h" #include <FairParAsciiFileIo.h> #include <FairParamList.h> @@ -36,8 +36,6 @@ #include <sstream> #include <vector> -#include "config/Yaml.h" - using namespace std; using namespace cbm::algo; @@ -71,8 +69,18 @@ void CbmTaskUnpack::Exec(Option_t*) timer.Start(); // --- Unpack the timeslice - auto result = fUnpack(timeslice); - fTimeslice->fData = result.first.ToStorable(); + DigiData digis; + Monitor monitor; + + digis.fBmon = RunUnpacker(fBmonUnpack, *timeslice, monitor); + digis.fMuch = RunUnpacker(fMuchUnpack, *timeslice, monitor); + digis.fRich = RunUnpacker(fRichUnpack, *timeslice, monitor); + digis.fSts = RunUnpacker(fStsUnpack, *timeslice, monitor); + digis.fTof = RunUnpacker(fTofUnpack, *timeslice, monitor); + digis.fTrd = RunUnpacker(fTrdUnpack, *timeslice, monitor); + digis.fTrd2d = RunUnpacker(fTrd2dUnpack, *timeslice, monitor); + + fTimeslice->fData = digis.ToStorable(); // --- Timeslice log timer.Stop(); @@ -80,10 +88,10 @@ void CbmTaskUnpack::Exec(Option_t*) logOut << setw(15) << left << GetName() << " ["; logOut << fixed << setw(8) << setprecision(1) << right << timer.RealTime() * 1000. << " ms] "; logOut << "TS " << fNumTs << " (index " << timeslice->index() << ")"; - logOut << ", components " << result.second.fNumCompUsed << " / " << timeslice->num_components(); - logOut << ", microslices " << result.second.fNumMs; - logOut << ", input rate " << double(result.second.fNumBytes) / timer.RealTime() / 1.e6 << " MB/s"; - logOut << ", digis " << result.second.fNumDigis; + logOut << ", components " << monitor.numCompUsed << " / " << timeslice->num_components(); + logOut << ", microslices " << monitor.numMs; + logOut << ", input rate " << double(monitor.numBytes) / timer.RealTime() / 1.e6 << " MB/s"; + logOut << ", digis " << monitor.numDigis; LOG(info) << logOut.str(); #if !defined(__CLING__) && !defined(__ROOTCLING__) @@ -91,17 +99,17 @@ void CbmTaskUnpack::Exec(Option_t*) fMonitor->QueueMetric(GetName(), {{"host", fHostname}}, {{"realtime", timer.RealTime()}, {"cputime", timer.CpuTime()}, - {"input_size", result.second.fNumBytes}, - {"input_rate", double(result.second.fNumBytes) / timer.RealTime()}, - {"digis", result.second.fNumDigis}}); + {"input_size", monitor.numBytes}, + {"input_rate", double(monitor.numBytes) / timer.RealTime()}, + {"digis", monitor.numDigis}}); } #endif // --- Run statistics fNumTs++; - fNumMs += result.second.fNumMs; - fNumBytes += result.second.fNumBytes; - fNumDigis += result.second.fNumDigis; + fNumMs += monitor.numMs; + fNumBytes += monitor.numBytes; + fNumDigis += monitor.numDigis; fTime += timer.RealTime(); } // ---------------------------------------------------------------------------- @@ -155,11 +163,21 @@ InitStatus CbmTaskUnpack::Init() LOG(info) << "--- Registered branch DigiTimeslice."; // ---- Initialize unpacker - fUnpack.fTrdConfig = InitTrdReadoutConfig(); - fUnpack.fTrd2dConfig = InitTrd2dReadoutConfig(); - if (fConfig.dumpSetup) { DumpUnpackSetup(); } - fUnpack.Init(); + fBmonUnpack = std::make_unique<bmon::Unpack>(bmon::ReadoutConfig{}); + fMuchUnpack = std::make_unique<much::Unpack>(much::ReadoutConfig{}); + fRichUnpack = std::make_unique<rich::Unpack>(rich::ReadoutConfig{}); + + auto stsReadout = sts::ReadoutConfig::MakeMCBM2022(); + auto stsWalkMap = sts::WalkMap::MakeMCBM2022(); + fStsUnpack = std::make_unique<sts::Unpack>(sts::Unpack::Config{stsReadout, stsWalkMap}); + fTofUnpack = std::make_unique<tof::Unpack>(tof::ReadoutConfig{}); + fTrdUnpack = std::make_unique<trd::Unpack>(InitTrdReadoutConfig()); + fTrd2dUnpack = std::make_unique<trd2d::Unpack>(InitTrd2dReadoutConfig()); + + if (fConfig.dumpSetup) { + DumpUnpackSetup(); + } return kSUCCESS; } @@ -178,12 +196,16 @@ cbm::algo::trd2d::ReadoutConfig CbmTaskUnpack::InitTrd2dReadoutConfig() // Read the .digi file and store result CbmTrdParSetDigi digiparset; - if (asciiInput.open(digiparfile.data())) { digiparset.init(&asciiInput); } + if (asciiInput.open(digiparfile.data())) { + digiparset.init(&asciiInput); + } asciiInput.close(); // Read the .asic file and store result CbmTrdParSetAsic asicparset; - if (asciiInput.open(asicparfile.data())) { asicparset.init(&asciiInput); } + if (asciiInput.open(asicparfile.data())) { + asicparset.init(&asciiInput); + } asciiInput.close(); // Map (moduleId) -> (array of crobId) @@ -247,7 +269,9 @@ cbm::algo::trd::ReadoutConfig CbmTaskUnpack::InitTrdReadoutConfig() CbmTrdParSetAsic trdpar; FairParAsciiFileIo asciiInput; - if (asciiInput.open(trdparfile.data())) { trdpar.init(&asciiInput); } + if (asciiInput.open(trdparfile.data())) { + trdpar.init(&asciiInput); + } FairParamList parlist; trdpar.putParams(&parlist); @@ -273,7 +297,9 @@ cbm::algo::trd::ReadoutConfig CbmTaskUnpack::InitTrdReadoutConfig() const uint16_t criId = asicPar->GetCriId(); const uint8_t crobId = asicPar->GetCrobId(); const uint8_t elinkId = asicPar->GetElinkId(0); - if (elinkId >= 98) { continue; } // Don't add not connected asics to the map + if (elinkId >= 98) { + continue; + } // Don't add not connected asics to the map addressMap[criId][crobId][elinkId] = address; addressMap[criId][crobId][elinkId + 1] = address; @@ -301,11 +327,23 @@ void CbmTaskUnpack::DumpUnpackSetup() { LOG(info) << "--- Dumping readout setup to yaml file ---"; - auto yaml = config::Dump {}(fUnpack.fTrdConfig); + auto yaml = config::Dump{}(fTrdUnpack->Readout()); std::ofstream("TrdReadoutSetup.yaml") << yaml; - yaml = config::Dump {}(fUnpack.fTrd2dConfig); + yaml = config::Dump{}(fTrd2dUnpack->Readout()); std::ofstream("Trd2dReadoutSetup.yaml") << yaml; } +template<class Unpacker> +auto CbmTaskUnpack::RunUnpacker(const std::unique_ptr<Unpacker>& unpacker, const fles::Timeslice& timeslice, + Monitor& monitor) -> cbm::algo::algo_traits::Output_t<Unpacker> +{ + auto [digis, detmon] = (*unpacker)(timeslice); + monitor.numCompUsed += detmon.numComponents; + monitor.numMs += detmon.numMs; + monitor.numBytes += detmon.sizeBytesIn; + monitor.numDigis += digis.size(); + return digis; +} + ClassImp(CbmTaskUnpack) diff --git a/reco/tasks/CbmTaskUnpack.h b/reco/tasks/CbmTaskUnpack.h index 2c5c3c78b714d623162db0531ab26e9590a3ea07..ccb50f7a87182a106201b2739937b97a628eae1b 100644 --- a/reco/tasks/CbmTaskUnpack.h +++ b/reco/tasks/CbmTaskUnpack.h @@ -19,14 +19,21 @@ namespace cbm } #endif +#include "AlgoTraits.h" +#include "EventBuilder.h" +#include "bmon/Unpack.h" +#include "much/Unpack.h" +#include "rich/Unpack.h" +#include "sts/Unpack.h" +#include "tof/Unpack.h" +#include "trd/Unpack.h" +#include "trd2d/Unpack.h" + #include <FairTask.h> #include <sstream> #include <vector> -#include "EventBuilder.h" -#include "Unpack.h" - class CbmDigiManager; class CbmSourceTs; @@ -50,6 +57,13 @@ public: bool dumpSetup = false; }; + struct Monitor { + size_t numCompUsed = 0; + size_t numMs = 0; + size_t numBytes = 0; + size_t numDigis = 0; + }; + /** @brief Constructor **/ CbmTaskUnpack(Config config); @@ -98,8 +112,14 @@ private: // members cbm::Monitor* fMonitor = nullptr; std::string fHostname; - /** @brief Unpacker algorithm **/ - cbm::algo::Unpack fUnpack; + /* Unpacker algorithms */ + std::unique_ptr<cbm::algo::bmon::Unpack> fBmonUnpack; + std::unique_ptr<cbm::algo::much::Unpack> fMuchUnpack; + std::unique_ptr<cbm::algo::rich::Unpack> fRichUnpack; + std::unique_ptr<cbm::algo::sts::Unpack> fStsUnpack; + std::unique_ptr<cbm::algo::tof::Unpack> fTofUnpack; + std::unique_ptr<cbm::algo::trd::Unpack> fTrdUnpack; + std::unique_ptr<cbm::algo::trd2d::Unpack> fTrd2dUnpack; size_t fNumTs = 0; size_t fNumMs = 0; @@ -108,6 +128,10 @@ private: // members double fTime = 0.; CbmDigiTimeslice* fTimeslice = nullptr; ///< Output data + template<class Unpacker> + auto RunUnpacker(const std::unique_ptr<Unpacker>& unpacker, const fles::Timeslice& ts, Monitor& monitor) + -> cbm::algo::algo_traits::Output_t<Unpacker>; + ClassDef(CbmTaskUnpack, 3); };