/* 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 "CbmDigiTimeslice.h" #include "tof/TofReadoutConfig.h" #include "tof/UnpackTof.h" #include "trd/TrdReadoutConfig.h" #include "trd/UnpackTrd.h" #include "trd2d/Trd2dReadoutConfig.h" #include "trd2d/UnpackTrd2d.h" #include <optional> #include <sstream> #include <vector> #include "bmon/BmonReadoutConfig.h" #include "bmon/UnpackBmon.h" #include "much/MuchReadoutConfig.h" #include "much/UnpackMuch.h" #include "rich/RichReadoutConfig.h" #include "rich/UnpackRich.h" #include "sts/Digi.h" #include "sts/StsReadoutConfigLegacy.h" #include "sts/UnpackSts.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<UnpackStsMonitorData> fSts; ///< Monitoring data for STS std::vector<UnpackMuchMonitorData> fMuch; ///< Monitoring data for MUCH std::vector<UnpackTofMonitorData> fTof; ///< Monitoring data for TOF std::vector<UnpackBmonMonitorData> fBmon; ///< Monitoring data for T0 std::vector<UnpackTrdMonitorData> fTrd; ///< Monitoring data for TRD std::vector<UnpackTrd2dMonitorData> fTrd2d; ///< Monitoring data for TRD2D std::vector<UnpackRichMonitorData> fRich; ///< Monitoring data for RICH size_t fNumMs = 0; size_t fNumBytes = 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<CbmDigiTimeslice, 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 STS unpackers **/ StsReadoutConfigLegacy fStsConfig {}; /** @brief Parameters for MUCH unpackers **/ MuchReadoutConfig fMuchConfig {}; /** @brief Parameters for TOF unpackers **/ TofReadoutConfig fTofConfig {}; /** @brief Parameters for T0 unpackers **/ BmonReadoutConfig fBmonConfig {}; /** @brief Parameters for TRD unpackers **/ TrdReadoutConfig fTrdConfig {}; /** @brief Parameters for TRD2D unpackers **/ Trd2dReadoutConfig fTrd2dConfig {}; /** @brief Parameters for RICH unpackers **/ RichReadoutConfig fRichConfig {}; /** * @brief Set whether to apply walk correction. Must be set before Init(). (default: true) **/ void SetApplyWalkCorrection(bool applyWalkCorrection) { fApplyWalkCorrection = applyWalkCorrection; } /** @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::T0, 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> void MsLoop(const fles::Timeslice* timeslice, std::map<uint16_t, UnpackAlgo>& algoMap, const uint64_t comp, const uint16_t eqId, std::vector<Digi>* digis, UnpackMonitorData& monitor, std::vector<MonitorData>* monitorMs, uint8_t sys_ver); /** @brief Parallel microslice loop **/ template<class Digi, class UnpackAlgo, class Monitor> void ParallelMsLoop(const Subsystem subsystem, std::vector<Digi>& digisOut, std::vector<Monitor>& monitor, 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, 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(std::vector<Digi>& digis); private: // members bool fApplyWalkCorrection = true; ///< Apply walk correction std::vector<Subsystem> fSubsystems = {}; ///< Detector identifiers to unpack /** @brief STS unpackers **/ std::map<uint16_t, UnpackSts> fAlgoSts = {}; /** @brief MUCH unpackers **/ std::map<uint16_t, UnpackMuch> fAlgoMuch = {}; /** @brief TOF unpackers **/ std::map<uint16_t, UnpackTof> fAlgoTof = {}; /** @brief T0 unpackers **/ std::map<uint16_t, UnpackBmon> fAlgoBmon = {}; /** @brief TRD unpackers **/ std::map<uint16_t, UnpackTrd> fAlgoTrd = {}; /** @brief TRD2D unpackers **/ std::map<uint16_t, UnpackTrd2d> fAlgoTrd2d = {}; /** @brief RICH unpackers **/ std::map<uint16_t, UnpackRich> fAlgoRich = {}; /** @brief System time offsets **/ std::map<Subsystem, int32_t> fSystemTimeOffset = { {Subsystem::STS, -970}, {Subsystem::MUCH, -980}, {Subsystem::RICH, 100}, {Subsystem::TOF, 40}, {Subsystem::T0, 0}, {Subsystem::TRD, 1300}, {Subsystem::TRD2D, -510}}; }; } // namespace cbm::algo #endif /* UNPACK_H */