From 37d21a54640ed7c025ba9aeb304347146f82a00d Mon Sep 17 00:00:00 2001 From: "s.zharko@gsi.de" <s.zharko@gsi.de> Date: Tue, 11 Jun 2024 00:28:20 +0200 Subject: [PATCH] online: - The auxiliary data objects from unpackers are stored in a temporary data structure AuxDigiUnpack (TODO: Dummy classes for DigiQa, execute the QA inside the Reco::RunUnpacker function) - The option "--aux-data" is added to force saving the auxiliary data in unpackers (now is used only by std::Unpack) - STS digi QA: histograms for channel vs. e-link are added for different modules --- algo/base/AuxDigiData.h | 36 +++++++++++++++++++ algo/base/DigiData.h | 1 - algo/base/Options.cxx | 1 + algo/base/Options.h | 2 ++ algo/detectors/sts/Unpack.cxx | 1 + algo/detectors/sts/Unpack.h | 1 + algo/global/Reco.cxx | 39 +++++++++++---------- algo/global/Reco.h | 4 ++- algo/qa/unpack/QaBase.h | 24 ++++++++++--- algo/qa/unpack/StsDigiQa.cxx | 65 +++++++++++++++++++++++++++++------ algo/qa/unpack/StsDigiQa.h | 5 +-- algo/unpack/CommonUnpacker.h | 1 - 12 files changed, 141 insertions(+), 39 deletions(-) create mode 100644 algo/base/AuxDigiData.h diff --git a/algo/base/AuxDigiData.h b/algo/base/AuxDigiData.h new file mode 100644 index 0000000000..e464da7e28 --- /dev/null +++ b/algo/base/AuxDigiData.h @@ -0,0 +1,36 @@ +/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergei Zharko [committer] */ + +/// \file AuxDigiData.h +/// \date 10.06.2024 +/// \brief Collection of auxiliary data from unpackers (header) +/// \author Sergei Zharko <s.zharko@gsi.de> + +#pragma once + +#include "CommonUnpacker.h" +#include "bmon/UnpackMS.h" +#include "much/UnpackMS.h" +#include "rich/UnpackMS.h" +#include "sts/UnpackMS.h" +#include "tof/UnpackMS.h" +#include "trd/UnpackMS.h" +#include "trd2d/UnpackMS.h" + +#include <vector> + +namespace cbm::algo +{ + /// \struct AuxDigiData + /// \brief Collection of auxiliary digi objects from different module unpackers + struct AuxDigiData { + UnpackAux<bmon::UnpackAuxData> fBmon; + UnpackAux<much::UnpackAuxData> fMuch; + UnpackAux<rich::UnpackAuxData> fRich; + UnpackAux<sts::UnpackAuxData> fSts; + UnpackAux<tof::UnpackAuxData> fTof; + UnpackAux<trd::UnpackAuxData> fTrd; + UnpackAux<trd2d::UnpackAuxData> fTrd2d; + }; +} // namespace cbm::algo diff --git a/algo/base/DigiData.h b/algo/base/DigiData.h index 54a34f0830..c19b685d99 100644 --- a/algo/base/DigiData.h +++ b/algo/base/DigiData.h @@ -18,7 +18,6 @@ namespace cbm::algo { - /** * @brief Collection of digis from all detector systems * diff --git a/algo/base/Options.cxx b/algo/base/Options.cxx index 448a074e7d..d289178361 100644 --- a/algo/base/Options.cxx +++ b/algo/base/Options.cxx @@ -76,6 +76,7 @@ Options::Options(int argc, char** argv) "High-Water Mark for ZMQ socket to histogram server in messages:\n" " 0 = no buffering, num = nb updates kept in buffer if not pulled by server \n" " Tune to avoid too high memory usage but also adapt to server load!") + ("aux-data", po::value(&fCollectAuxData)->implicit_value(true), "Enables collecting of auxiliary data from algorithms") ("log-file,L", po::value(&fLogFile)->value_name("<file>"), "write log messages to file") ("output-types,O", po::value(&fOutputTypes)->multitoken()->value_name("<types>"), diff --git a/algo/base/Options.h b/algo/base/Options.h index 2d580a9e28..bb67de3def 100644 --- a/algo/base/Options.h +++ b/algo/base/Options.h @@ -31,6 +31,7 @@ namespace cbm::algo const std::string& MonitorUri() const { return fMonitorUri; } const std::string& HistogramUri() const { return fHistogramUri; } const int32_t& HistogramHwm() const { return fHistogramHwm; } + bool CollectAuxData() const { return fCollectAuxData; } bool CollectKernelTimes() const { return fProfilingLevel != ProfilingNone; } ProfilingLevel Profiling() const { return fProfilingLevel; } fs::path TimingsFile() const { return fTimingsFile; } @@ -84,6 +85,7 @@ namespace cbm::algo std::vector<fles::Subsystem> fDetectors; std::string fChildId = "00"; uint64_t fRunId = 2391; + bool fCollectAuxData = false; }; } // namespace cbm::algo diff --git a/algo/detectors/sts/Unpack.cxx b/algo/detectors/sts/Unpack.cxx index e5f7003fe2..8b11338c5c 100644 --- a/algo/detectors/sts/Unpack.cxx +++ b/algo/detectors/sts/Unpack.cxx @@ -19,6 +19,7 @@ Unpack::Unpack(const Config& config) : fConfig(config) auto equipIdsSts = fConfig.readout.GetEquipmentIds(); for (auto& equip : equipIdsSts) { sts::UnpackPar par{}; + par.fWriteAux = fConfig.bCollectAuxData; par.fNumChansPerAsic = numChansPerAsicSts; par.fNumAsicsPerModule = numAsicsPerModuleSts; const size_t numElinks = fConfig.readout.GetNumElinks(equip); diff --git a/algo/detectors/sts/Unpack.h b/algo/detectors/sts/Unpack.h index 50e8720861..f8c09d6686 100644 --- a/algo/detectors/sts/Unpack.h +++ b/algo/detectors/sts/Unpack.h @@ -23,6 +23,7 @@ namespace cbm::algo::sts struct Config { ReadoutConfig readout; WalkMap walkMap; + bool bCollectAuxData = false; }; using Result_t = detail::UnpackBase::Result_t; diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx index 4288d6df1b..faa3a29d46 100644 --- a/algo/global/Reco.cxx +++ b/algo/global/Reco.cxx @@ -3,6 +3,7 @@ Authors: Felix Weiglhofer [committer], P.-A. Loizeau */ #include "Reco.h" +#include "AuxDigiData.h" #include "BuildInfo.h" #include "CbmDigiEvent.h" #include "EventbuildChain.h" @@ -123,12 +124,13 @@ void Reco::Init(const Options& opts) sts::ReadoutSetup readoutSetup = yaml::ReadFromFile<sts::ReadoutSetup>(Opts().ParamsDir() / parFiles.sts.readout); auto chanMask = yaml::ReadFromFile<sts::ChannelMaskSet>(Opts().ParamsDir() / parFiles.sts.chanMask); auto walkMap = yaml::ReadFromFile<sts::WalkMap>(Opts().ParamsDir() / parFiles.sts.walkMap); - + bool bCollectAux = (fSender != nullptr && Opts().CollectAuxData()); sts::ReadoutConfig readout{readoutSetup, chanMask}; - sts::Unpack::Config cfg{.readout = readout, .walkMap = walkMap}; + sts::Unpack::Config cfg{.readout = readout, .walkMap = walkMap, .bCollectAuxData = bCollectAux}; fStsUnpack = std::make_unique<sts::Unpack>(cfg); if (fSender != nullptr) { fStsDigiQa = std::make_unique<sts::DigiQa>(fSender); + fStsDigiQa->SetUseAuxData(bCollectAux); fStsDigiQa->RegisterReadoutSetup(readoutSetup); fStsDigiQa->Init(); } @@ -227,18 +229,19 @@ RecoResults Reco::Run(const fles::Timeslice& ts) xpu::set<cbm::algo::Params>(Params()); DigiData digis; + AuxDigiData auxDigis; if (Opts().Has(Step::Unpack)) { xpu::scoped_timer timerU("Unpack", &procMon.timeUnpack); xpu::t_add_bytes(ts_utils::SizeBytes(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); + std::tie(digis.fBmon, auxDigis.fBmon) = RunUnpacker(fBmonUnpack, ts); + std::tie(digis.fMuch, auxDigis.fMuch) = RunUnpacker(fMuchUnpack, ts); + std::tie(digis.fRich, auxDigis.fRich) = RunUnpacker(fRichUnpack, ts); + std::tie(digis.fSts, auxDigis.fSts) = RunUnpacker(fStsUnpack, ts); + std::tie(digis.fTof, auxDigis.fTof) = RunUnpacker(fTofUnpack, ts); + std::tie(digis.fTrd, auxDigis.fTrd) = RunUnpacker(fTrdUnpack, ts); + std::tie(digis.fTrd2d, auxDigis.fTrd2d) = RunUnpacker(fTrd2dUnpack, ts); // No unpackers for these yet // digis.fPsd = RunUnpacker(fPsdUnpack, ts); @@ -248,15 +251,15 @@ RecoResults Reco::Run(const fles::Timeslice& ts) << " 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(); + // --- Raw digi QAs + if (fSender != nullptr && Opts().Has(Subsystem::STS)) { + fStsDigiQa->RegisterDigiData(&digis.fSts); + fStsDigiQa->RegisterAuxDigiData(&auxDigis.fSts); + fStsDigiQa->Exec(); + } } - // --- Raw digi QAs - if (fSender != nullptr && Opts().Has(Subsystem::STS) && Opts().Has(Step::Unpack)) { - fStsDigiQa->RegisterDigiData(&digis.fSts); - fStsDigiQa->Exec(); - } - sts::HitfinderMon stsHitfinderMonitor; if (fStsHitFinder) { xpu::scoped_timer timerSTS("STS Reco", &procMon.timeSTS); @@ -403,16 +406,14 @@ void Reco::PrintTimings(xpu::timings& timings) } template<class Unpacker> -auto Reco::RunUnpacker(const std::unique_ptr<Unpacker>& unpacker, const fles::Timeslice& ts) - -> algo_traits::Output_t<Unpacker> +auto Reco::RunUnpacker(const std::unique_ptr<Unpacker>& unpacker, const fles::Timeslice& ts) -> UnpackResult_t<Unpacker> { if (!unpacker) { return {}; } auto [digis, monitor, aux] = (*unpacker)(ts); QueueUnpackerMetricsDet(monitor); - //// TO DO: Send aux somewhere!! - return digis; + return std::make_tuple(digis, aux); } template<class MSMonitor> diff --git a/algo/global/Reco.h b/algo/global/Reco.h index 803d770759..b2b559651a 100644 --- a/algo/global/Reco.h +++ b/algo/global/Reco.h @@ -83,6 +83,8 @@ namespace cbm::algo using TrackingMonitorData = MonitorData<ECounter, ETimer>; } // namespace ca + template<class Unpacker> + using UnpackResult_t = std::tuple<algo_traits::Output_t<Unpacker>, algo_traits::Aux_t<Unpacker>>; } // namespace cbm::algo namespace cbm::algo @@ -167,7 +169,7 @@ namespace cbm::algo void Validate(const Options& opts); template<class Unpacker> - auto RunUnpacker(const std::unique_ptr<Unpacker>&, const fles::Timeslice&) -> algo_traits::Output_t<Unpacker>; + auto RunUnpacker(const std::unique_ptr<Unpacker>&, const fles::Timeslice&) -> UnpackResult_t<Unpacker>; template<class MSMonitor> void QueueUnpackerMetricsDet(const UnpackMonitor<MSMonitor>&); diff --git a/algo/qa/unpack/QaBase.h b/algo/qa/unpack/QaBase.h index c8b2e1a05b..f63d652f2f 100644 --- a/algo/qa/unpack/QaBase.h +++ b/algo/qa/unpack/QaBase.h @@ -21,7 +21,8 @@ namespace cbm::algo::sts /// \brief QA module for STS raw digis /// \tparam Digi A digi class for a given detector subsystem /// \tparam ReadoutSetup A read-out config for a given detector subsystem - template<class Digi, class ReadoutSetup> + /// \tparam AuxData Auxilary information on digis, stored for each micro timeslice + template<class Digi, class AuxData, class ReadoutSetup> class QaBase { public: /// \brief Constructor @@ -52,14 +53,29 @@ namespace cbm::algo::sts /// \brief Register digi-qa data void RegisterDigiData(const PODVector<Digi>* pvDigis) { fpvDigis = pvDigis; } + /// \brief Register auxiliary digi data + void RegisterAuxDigiData(const AuxData* pAuxDigis) + { + if (fbAux) { + fpAuxDigis = pAuxDigis; + } + else { + fpAuxDigis = nullptr; + } + } + + /// \brief Sets usage of auxiliary data + void SetUseAuxData(bool bAux = true) { fbAux = bAux; } + /// \brief Register read-out setup config void RegisterReadoutSetup(const ReadoutSetup& setup) { fpReadoutSetup = std::make_shared<ReadoutSetup>(setup); } protected: - qa::Data fQaData; ///< QA data - std::shared_ptr<HistogramSender> fpSender = nullptr; ///< Histogram sender - + qa::Data fQaData; ///< QA data + std::shared_ptr<HistogramSender> fpSender = nullptr; ///< Histogram sender std::shared_ptr<ReadoutSetup> fpReadoutSetup = nullptr; ///< Readout config instance const PODVector<Digi>* fpvDigis = nullptr; ///< Digis input + const AuxData* fpAuxDigis = nullptr; ///< Aux information on digis + bool fbAux = false; ///< Extra distributions (if the auxiliary data should be used) }; } // namespace cbm::algo::sts diff --git a/algo/qa/unpack/StsDigiQa.cxx b/algo/qa/unpack/StsDigiQa.cxx index db9a8b0472..cb07284244 100644 --- a/algo/qa/unpack/StsDigiQa.cxx +++ b/algo/qa/unpack/StsDigiQa.cxx @@ -32,42 +32,69 @@ void DigiQa::Init() int nModules = fpReadoutSetup->modules.size(); + auto GetAddressName = [&](int32_t address) -> std::string { + uint32_t u = CbmStsAddress::GetElementId(address, kStsUnit); + uint32_t l = CbmStsAddress::GetElementId(address, kStsLadder); + uint32_t m = CbmStsAddress::GetElementId(address, kStsModule); + return format("u{}_l{}_m{}", u, l, m); + }; + + auto GetAddressTitle = [&](int32_t address) -> std::string { + uint32_t u = CbmStsAddress::GetElementId(address, kStsUnit); + uint32_t l = CbmStsAddress::GetElementId(address, kStsLadder); + uint32_t m = CbmStsAddress::GetElementId(address, kStsModule); + return format("U{} L{} M{}", u, l, m); + }; + // Histograms per address { fvphAddressChannel.resize(nModules); fvphAddressCharge.resize(nModules); fvphAddressChannelCharge.resize(nModules); + if (fbAux) { + fvphAddressChannelElink.resize(nModules); + } for (int iM = 0; iM < nModules; ++iM) { int32_t address = fpReadoutSetup->modules.at(iM).address; fmAddressMap[address] = iM; - - auto cName = format("sts_digi/sts_digi_vs_channel_charge_addr{:#10x}", address); - auto cTitl = format("STS digis per channel and charge for module {:#10x}", address); + auto aName = GetAddressName(address); + auto aTitl = GetAddressTitle(address); + auto cName = format("sts_digi/sts_digi_vs_channel_charge_{}", aName); + auto cTitl = format("STS digis per channel and charge for module {}", aTitl); auto canv = CanvasConfig(cName, cTitl, 3, 1); { auto pad = PadConfig(); - auto name = format("sts_digi_addr{}_channel", iM); - auto titl = format("Number of digis per channel for address {:#10x};channel;N_{{digis}}", address); + auto name = format("sts_digi_{}_channel", aName); + auto titl = format("Number of digis per channel for module {};channel;N_{{digis}}", aTitl); fvphAddressChannel[iM] = fQaData.MakeObj<H1D>(name, titl, 2048, -0.5, 2047.5); pad.RegisterHistogram(fvphAddressChannel[iM], "hist"); canv.AddPadConfig(pad); } { auto pad = PadConfig(); - auto name = format("sts_digi_addr{}_charge", iM); - auto titl = format("STS digi charge for address {:#10x};charge [ADS units];N_{{digis}}", address); + auto name = format("sts_digi_{}_charge", aName); + auto titl = format("STS digi charge for mudule {};charge [ADS units];N_{{digis}}", aTitl); fvphAddressCharge[iM] = fQaData.MakeObj<H1D>(name, titl, 32, -0.5, 31.5); pad.RegisterHistogram(fvphAddressCharge[iM], "hist"); canv.AddPadConfig(pad); } { auto pad = PadConfig(); - auto name = format("sts_digi_addr{}_channel_charge", iM); - auto titl = format("STS digi charge for address {:#10x};charge [ADS units];channel", address); + auto name = format("sts_digi_{}_channel_charge", aName); + auto titl = format("STS digi charge for module {};charge [ADS units];channel", aTitl); fvphAddressChannelCharge[iM] = fQaData.MakeObj<H2D>(name, titl, 32, -0.5, 31.5, 2048, -0.5, 2047.5); pad.RegisterHistogram(fvphAddressChannelCharge[iM], "colz"); canv.AddPadConfig(pad); } + if (fbAux) { + auto pad = PadConfig(); + auto name = format("sts_digi_{}_channel_elink", aName); + auto titl = format("STS digi charge for module {};E-link;channel", aTitl); + fvphAddressChannelElink[iM] = fQaData.MakeObj<H2D>(name, titl, 40, -0.5, 39.5, 2048, -0.5, 2047.5); + pad.RegisterHistogram(fvphAddressChannelElink[iM], "colz"); + canv.AddPadConfig(pad); + } + fQaData.AddCanvasConfig(canv); } } @@ -83,7 +110,7 @@ void DigiQa::Exec() return; } - // Loop over STS digis and fill histograms + // --- Loop over STS digis and fill histograms for (const auto& digi : (*fpvDigis)) { int32_t address = digi.GetAddress(); double channel = digi.GetChannel(); @@ -92,7 +119,7 @@ void DigiQa::Exec() // Ensure, that the address is defined auto itHistID = fmAddressMap.find(address); if (itHistID == fmAddressMap.end()) { - L_(error) << format("std::DigiQa: found address {:x}, which is not defined in the ReadoutSetup config", address); + L_(error) << format("sts::DigiQa: found address {:x}, which is not defined in the ReadoutSetup config", address); continue; } @@ -102,6 +129,22 @@ void DigiQa::Exec() fvphAddressChannelCharge[iM]->Fill(charge, channel); } + // --- Loop over aux QA digis + if (fbAux) { + for (const auto& ms : fpAuxDigis->msAux) { + for (const auto& auxDigi : ms.fQaDigis) { + int32_t address = auxDigi.address; + auto itHistID = fmAddressMap.find(address); + if (itHistID == fmAddressMap.end()) { + L_(error) << format("sts::DigiQa: found address {:x}, which is not defined in the ReadoutSetup config", + address); + continue; + } + int iM = itHistID->second; + fvphAddressChannelElink[iM]->Fill(static_cast<double>(auxDigi.elink), static_cast<double>(auxDigi.channel)); + } + } + } fQaData.Send(fpSender); } diff --git a/algo/qa/unpack/StsDigiQa.h b/algo/qa/unpack/StsDigiQa.h index 49780f8d81..0a89c649af 100644 --- a/algo/qa/unpack/StsDigiQa.h +++ b/algo/qa/unpack/StsDigiQa.h @@ -12,14 +12,14 @@ #include "CbmStsDigi.h" #include "Definitions.h" #include "QaBase.h" -#include "sts/ReadoutConfig.h" +#include "sts/Unpack.h" #include <unordered_map> #include <vector> namespace cbm::algo::sts { - using DigiQaBase = QaBase<CbmStsDigi, ReadoutSetup>; + using DigiQaBase = QaBase<CbmStsDigi, UnpackAux<sts::UnpackAuxData>, ReadoutSetup>; /// \class cbm::algo::sts::DigiQa /// \brief QA module for STS raw digis @@ -56,6 +56,7 @@ namespace cbm::algo::sts std::vector<qa::H1D*> fvphAddressChannel; ///< hist: digi channel in different sensors std::vector<qa::H1D*> fvphAddressCharge; ///< hist: digi charge in different sensors std::vector<qa::H2D*> fvphAddressChannelCharge; ///< hist: digi channel vs. charge in different sensors + std::vector<qa::H2D*> fvphAddressChannelElink; ///< hist: digi channel vs. eling (AUX) qa::H2D* fvphFebAsic = nullptr; ///< hist: digi FEB vs ASIC }; diff --git a/algo/unpack/CommonUnpacker.h b/algo/unpack/CommonUnpacker.h index 1834c47729..e9a3652248 100644 --- a/algo/unpack/CommonUnpacker.h +++ b/algo/unpack/CommonUnpacker.h @@ -79,7 +79,6 @@ namespace cbm::algo template<class Digi, class MSMonitor, class MSAux> class CommonUnpacker { - protected: using Monitor_t = UnpackMonitor<MSMonitor>; using Aux_t = UnpackAux<MSAux>; -- GitLab