diff --git a/algo/ca/TrackingChain.cxx b/algo/ca/TrackingChain.cxx index 73b3d47f008991eedb614585c2ba53d5f50f168a..3810670e9f5fa6910491a97d4d2a17067cd3564c 100644 --- a/algo/ca/TrackingChain.cxx +++ b/algo/ca/TrackingChain.cxx @@ -1,4 +1,4 @@ -/* Copyright (C) 2023-2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt +/* Copyright (C) 2023-2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt SPDX-License-Identifier: GPL-3.0-only Authors: Sergei Zharko [committer] */ @@ -39,7 +39,10 @@ using cbm::algo::ca::constants::clrs::GNb; // grin bald text // --------------------------------------------------------------------------------------------------------------------- // -TrackingChain::TrackingChain(std::shared_ptr<cbm::algo::HistogramSender> histoSender) : fQa(Qa(histoSender)) {} +TrackingChain::TrackingChain(const std::unique_ptr<cbm::algo::qa::Manager>& qaManager, std::string_view name) + : fQa(Qa(qaManager, name)) +{ +} // --------------------------------------------------------------------------------------------------------------------- // @@ -90,7 +93,7 @@ void TrackingChain::Init() fCaFramework.Init(ca::TrackingMode::kMcbm); // ------ Initialize QA modules - if (fQa.IsSenderDefined()) { + if (fQa.IsActive()) { fQa.RegisterParameters(&fCaFramework.GetParameters()); fQa.Init(); } @@ -199,7 +202,7 @@ TrackingChain::Output_t TrackingChain::PrepareOutput() // QA - if (fQa.IsSenderDefined()) { + if (fQa.IsActive()) { fCaMonitorData.StartTimer(ca::ETimer::Qa); fQa.RegisterInputData(&fCaFramework.GetInputData()); fQa.RegisterTracks(&output.tracks); diff --git a/algo/ca/TrackingChain.h b/algo/ca/TrackingChain.h index e96735b5be03a5cb8b41520366a8f24b0f6577e9..3f949d3605e87e1f58b5404886a63ffd44c636d1 100644 --- a/algo/ca/TrackingChain.h +++ b/algo/ca/TrackingChain.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt +/* Copyright (C) 2023-2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt SPDX-License-Identifier: GPL-3.0-only Authors: Sergei Zharko [committer] */ @@ -15,7 +15,6 @@ #include "CaTrack.h" #include "CaTrackingMonitor.h" #include "CaVector.h" -#include "HistogramSender.h" #include "PartitionedSpan.h" #include "RecoResults.h" #include "SubChain.h" @@ -28,6 +27,11 @@ #include <memory> #include <vector> +namespace cbm::algo::qa +{ + class Manager; +} + namespace cbm::algo { /// \class cbm::algo::TrackingChain @@ -37,8 +41,9 @@ namespace cbm::algo class TrackingChain : public SubChain { public: /// \brief Constructor from parameters - /// \param histoSender A shared pointer to a histogram sender - TrackingChain(std::shared_ptr<HistogramSender> histoSender = nullptr); + /// \param pManager a QA-manager + /// \param name A name of the task (histograms directory) + TrackingChain(const std::unique_ptr<cbm::algo::qa::Manager>& qaManager = nullptr, std::string_view name = ""); /// \struct Input_t /// \brief Input to the TrackingChain diff --git a/algo/ca/qa/CaQa.cxx b/algo/ca/qa/CaQa.cxx index 2184256e92c7195368c07a6ea3d5572f5525534e..05815198dd6e6a228f9db995496470a830d18b2c 100644 --- a/algo/ca/qa/CaQa.cxx +++ b/algo/ca/qa/CaQa.cxx @@ -1,4 +1,4 @@ -/* Copyright (C) 2023-2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt +/* Copyright (C) 2023-2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt SPDX-License-Identifier: GPL-3.0-only Authors: Sergei Zharko [committer] */ @@ -61,7 +61,7 @@ void Qa::Init() using cbm::algo::qa::Prof2D; using fmt::format; - if (!fpSender.get()) { + if (!IsActive()) { return; } @@ -122,26 +122,26 @@ void Qa::Init() auto titl = format("{} hit occupancy in XY plane for station {} ({}{});x [cm];y [cm]", setTl, iSt, kDetName[detID], iStLoc); fvphHitOccupXY[iSt][hitSet] = - fQaData.MakeObj<H2D>(name, titl, nBinsXY, vMinX[iSt], vMaxX[iSt], nBinsXY, vMinY[iSt], vMaxY[iSt]); + MakeObj<H2D>(name, titl, nBinsXY, vMinX[iSt], vMaxX[iSt], nBinsXY, vMinY[iSt], vMaxY[iSt]); } { auto name = format("hit_{}_occup_zx_sta_{}", setNm, iSt); auto titl = format("{} hit occupancy in ZX plane for station {} ({}{});z [cm];x [cm]", setTl, iSt, kDetName[detID], iStLoc); - fvphHitOccupZX[iSt][hitSet] = fQaData.MakeObj<H2D>(name, titl, nBinsZ, zMinA, zMaxA, nBinsXY, xMinA, xMaxA); + fvphHitOccupZX[iSt][hitSet] = MakeObj<H2D>(name, titl, nBinsZ, zMinA, zMaxA, nBinsXY, xMinA, xMaxA); } if (kDebug) { auto name = format("hit_{}_occup_zy_sta_{}", setNm, iSt); auto titl = format("{} hit occupancy in ZY plane for station {} ({}{});z [cm];y [cm]", setTl, iSt, kDetName[detID], iStLoc); - fvphHitOccupZY[iSt][hitSet] = fQaData.MakeObj<H2D>(name, titl, nBinsZ, zMinA, zMaxA, nBinsXY, yMinA, yMaxA); + fvphHitOccupZY[iSt][hitSet] = MakeObj<H2D>(name, titl, nBinsZ, zMinA, zMaxA, nBinsXY, yMinA, yMaxA); } } if (kDebug) { auto name = format("hit_usage_xy_sta_{}", iSt); auto titl = format("Hit usage in XY plane for station {} ({}{});x [cm];y [cm]", iSt, kDetName[detID], iStLoc); fvphHitUsageXY[iSt] = - fQaData.MakeObj<Prof2D>(name, titl, nBinsXY, vMinX[iSt], vMaxX[iSt], nBinsXY, vMinY[iSt], vMaxY[iSt], 0., 1.); + MakeObj<Prof2D>(name, titl, nBinsXY, vMinX[iSt], vMaxX[iSt], nBinsXY, vMinY[iSt], vMaxY[iSt], 0., 1.); } } if (kDebug) { @@ -152,12 +152,12 @@ void Qa::Init() { auto name = format("hit_{}_front_key_index", setNm); auto titl = format("{} hit front key index;ID_{{key}}/N_{{keys}};Count", setTl); - fvphHitFrontKeyIndex[hitSet] = fQaData.MakeObj<H1D>(name, titl, NBins, 0., 1.); + fvphHitFrontKeyIndex[hitSet] = MakeObj<H1D>(name, titl, NBins, 0., 1.); } { auto name = format("hit_{}_back_key_index", setNm); auto titl = format("{} hit back key index;ID_{{key}}/N_{{keys}};Count", setTl); - fvphHitBackKeyIndex[hitSet] = fQaData.MakeObj<H1D>(name, titl, NBins, 0., 1.); + fvphHitBackKeyIndex[hitSet] = MakeObj<H1D>(name, titl, NBins, 0., 1.); } } } @@ -173,7 +173,7 @@ void Qa::Init() auto setTl = EHitSet::Input == hitSet ? "Input" : "Used"; auto name = format("hit_{}_rel_time{}", setNm, staNm); auto titl = format("{} hit relative time{}; #delta t_{{hit}};Count", setTl, staTl); - fvphHitTime[iSt][hitSet] = fQaData.MakeObj<H1D>(name, titl, 10000, -0.1, 1.1); + fvphHitTime[iSt][hitSet] = MakeObj<H1D>(name, titl, 10000, -0.1, 1.1); } } } @@ -189,22 +189,22 @@ void Qa::Init() { auto sName = format("track_{}_theta", vsPointName[i]); auto sTitl = format("#theta at {} hit; #theta", vsPointName[i]); - fvphTrkTheta[i] = fQaData.MakeObj<H1D>(sName, sTitl, 62, 0., 90.); + fvphTrkTheta[i] = MakeObj<H1D>(sName, sTitl, 62, 0., 90.); } { auto sName = format("track_{}_phi", vsPointName[i]); auto sTitl = format("#phi at {} hit; #phi", vsPointName[i]); - fvphTrkPhi[i] = fQaData.MakeObj<H1D>(sName, sTitl, 62, -180., 180.); + fvphTrkPhi[i] = MakeObj<H1D>(sName, sTitl, 62, -180., 180.); } { auto sName = format("track_{}_thata_phi", vsPointName[i]); auto sTitl = format("#theta vs #phi at {} hit; #phi; #theta", vsPointName[i]); - fvphTrkPhiTheta[i] = fQaData.MakeObj<H2D>(sName, sTitl, 62, -180., 180., 62, 0., 90.); + fvphTrkPhiTheta[i] = MakeObj<H2D>(sName, sTitl, 62, -180., 180., 62, 0., 90.); } { auto sName = format("track_{}_chi2_ndf", vsPointName[i]); auto sTitl = format("#chi^{{2}}/NDF at {} hit; #chi^{{2}}/NDF", vsPointName[i]); - fvphTrkChi2Ndf[i] = fQaData.MakeObj<H1D>(sName, sTitl, 100, 0., 20.); + fvphTrkChi2Ndf[i] = MakeObj<H1D>(sName, sTitl, 100, 0., 20.); } } { @@ -214,9 +214,9 @@ void Qa::Init() { auto sName = "track_fst_lst_sta"; auto sTitl = "First vs. last station index;ID^{last}_{station};ID^{first}_{station}"; - fphTrkFstLstSta = fQaData.MakeObj<H2D>(sName, sTitl, nBins, xMin, xMax, nBins, xMin, xMax); + fphTrkFstLstSta = MakeObj<H2D>(sName, sTitl, nBins, xMin, xMax, nBins, xMin, xMax); } - fphTrkNofHits = fQaData.MakeObj<H1D>("n_hits", "Number of hits;N_{hit}", nBins, xMin, xMax); + fphTrkNofHits = MakeObj<H1D>("n_hits", "Number of hits;N_{hit}", nBins, xMin, xMax); } // ---- Init canvases @@ -235,7 +235,7 @@ void Qa::Init() pad.RegisterHistogram(fvphHitOccupXY[iSt][hitSet], "colz"); canv.AddPadConfig(pad); } - fQaData.AddCanvasConfig(canv); + AddCanvasConfig(canv); } { // ZX and ZY auto name = format("ca_hit_{}_occupancy_zx_zy", setNm); @@ -255,7 +255,7 @@ void Qa::Init() } canv.AddPadConfig(pad); } - fQaData.AddCanvasConfig(canv); + AddCanvasConfig(canv); } } if (kDebug) { @@ -267,7 +267,7 @@ void Qa::Init() pad.RegisterHistogram(fvphHitUsageXY[iSt], "colz"); canv.AddPadConfig(pad); } - fQaData.AddCanvasConfig(canv); + AddCanvasConfig(canv); } } @@ -294,9 +294,8 @@ void Qa::Init() pad.RegisterHistogram(fphTrkFstLstSta, "colz"); canv.AddPadConfig(pad); } - fQaData.AddCanvasConfig(canv); + AddCanvasConfig(canv); } - fQaData.Init(fpSender); } } @@ -304,7 +303,7 @@ void Qa::Init() // void Qa::Exec() { - if (!fpSender.get()) { + if (!IsActive()) { return; } @@ -375,8 +374,6 @@ void Qa::Exec() trkFirstHit += nHits; } } - - fQaData.Send(fpSender); } // --------------------------------------------------------------------------------------------------------------------- diff --git a/algo/ca/qa/CaQa.h b/algo/ca/qa/CaQa.h index f0c0175a3bd4635d6dd5e449231d35365b915bf5..655d6fa50b16a9dac1133223ebafb56abeef08e7 100644 --- a/algo/ca/qa/CaQa.h +++ b/algo/ca/qa/CaQa.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt +/* Copyright (C) 2023-2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt SPDX-License-Identifier: GPL-3.0-only Authors: Sergei Zharko [committer] */ @@ -13,7 +13,7 @@ #include "CaHit.h" // for HitIndex_t #include "CaTimesliceHeader.h" #include "CaVector.h" -#include "QaData.h" // QA data +#include "qa/QaTaskHeader.h" namespace cbm::algo { @@ -21,6 +21,7 @@ namespace cbm::algo { class H1D; class H2D; + class Manager; } // namespace qa namespace ca { @@ -36,7 +37,7 @@ namespace cbm::algo::ca /// \class cbm::algo::ca::qa::Qa /// \brief Qa class for the CA tracking QA (header) /// - class Qa { + class Qa : public qa::TaskHeader { /// \brief Hit set entries enum class EHitSet { @@ -54,8 +55,9 @@ namespace cbm::algo::ca public: /// \brief Default destructor - /// \param pSender Pointer to the histogram sender - Qa(std::shared_ptr<HistogramSender> pSender) : fQaData("CA"), fpSender(pSender) {} + /// \param pManager Pointer to the QA manager + /// \param name Name of the QA (directory) + Qa(const std::unique_ptr<qa::Manager>& pManager, std::string_view name) : qa::TaskHeader(pManager, name) {} /// \brief Constructor from the configuration object /// \param config QA configuration object @@ -87,9 +89,6 @@ namespace cbm::algo::ca /// \return false Some of are not initialized bool CheckInit() const; - /// \brief Checks, if the histogram sender is defined - bool IsSenderDefined() const { return static_cast<bool>(fpSender.get()); } - /// \brief Registers tracking input data object /// \note Call per TS void RegisterInputData(const InputData* pInputData) { fpInputData = pInputData; } @@ -122,10 +121,6 @@ namespace cbm::algo::ca double fMinHitTime = std::numeric_limits<double>::max(); double fMaxHitTime = std::numeric_limits<double>::lowest(); - // utility - qa::Data fQaData; ///< QA data - - std::shared_ptr<HistogramSender> fpSender = nullptr; ///< Histogram sender const Parameters<fvec>* fpParameters = nullptr; ///< Pointer to tracking parameters const InputData* fpInputData = nullptr; ///< Pointer to input data const Vector<Track>* fpvTracks = nullptr; ///< Pointer to tracks vector diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx index 28acffb8b3e1901149a6160e170cd58c9a85e968..e9a0a7a9a0e0ff8e1cdb27b051c52f149ebc702b 100644 --- a/algo/global/Reco.cxx +++ b/algo/global/Reco.cxx @@ -1,6 +1,6 @@ -/* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main +/* Copyright (C) 2023-2025 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main SPDX-License-Identifier: GPL-3.0-only - Authors: Felix Weiglhofer [committer], P.-A. Loizeau */ + Authors: Felix Weiglhofer [committer], P.-A. Loizeau, Sergei Zharko */ #include "Reco.h" #include "AlgoFairloggerCompat.h" @@ -222,7 +222,12 @@ void Reco::Init(const Options& opts) // Tracking if (Opts().Has(Step::Tracking)) { - fTracking = std::make_unique<TrackingChain>(Opts().Has(QaStep::Tracking) ? fSender : nullptr); + if (Opts().Has(QaStep::Tracking)) { + fTracking = std::make_unique<TrackingChain>(fQaManager, "CaTimeslice"); + } + else { + fTracking = std::make_unique<TrackingChain>(); + } fTracking->RegisterSetup(pTrackingSetup); fTracking->SetContext(&fContext); fTracking->Init(); diff --git a/algo/qa/QaTaskHeader.h b/algo/qa/QaTaskHeader.h index 4038cd0d3e26a45f00394271502eea32574e4144..ca41383152a066fd98b79293f874428cd53fb350 100644 --- a/algo/qa/QaTaskHeader.h +++ b/algo/qa/QaTaskHeader.h @@ -22,7 +22,14 @@ namespace cbm::algo::qa public: /// \brief Constructor /// \param pManager a QA-manager - TaskHeader(const std::unique_ptr<Manager>& pManager) : fpData(pManager->GetData()) {} + /// \param name A name of the task (histograms directory) + TaskHeader(const std::unique_ptr<Manager>& pManager, std::string_view name) + : fpData(pManager != nullptr ? pManager->GetData() : nullptr) + { + if (fpData != nullptr) { + fpData->RegisterNewTask(name); + } + } /// \brief Copy constructor TaskHeader(const TaskHeader&) = delete; @@ -39,6 +46,12 @@ namespace cbm::algo::qa /// \brief Move assignment operator TaskHeader& operator=(TaskHeader&&) = delete; + /// \brief Checks, if the task is active + /// + /// The task can be inactive, if a nullptr qa::Manager was passed to the constructor. If it is the case, + /// the fpData instance is not defined, and no actions on the task should be performed + bool IsActive() const { return static_cast<bool>(fpData != nullptr); } + protected: /// \brief Adds a canvas configuration /// \param canvas A CanvasConfig object @@ -51,7 +64,7 @@ namespace cbm::algo::qa template<class Obj, typename... Args> Obj* MakeObj(Args... args) { - fpData->MakeObj<Obj>(args...); + return fpData->MakeObj<Obj>(args...); } private: