diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt index 72869ece1142b2f3d30fa91edfe661db094f115d..4dd79e72e3ddc13d0b463252f11a3374ef8e3a72 100644 --- a/algo/CMakeLists.txt +++ b/algo/CMakeLists.txt @@ -128,7 +128,9 @@ set(SRCS qa/PadConfig.cxx qa/QaData.cxx ca/TrackingChain.cxx - ca/qa/CaQaBuilder.cxx + ca/qa/CaInputQa.cxx + ca/qa/CaOutputQa.cxx + ca/qa/CaQaBase.cxx ) set(BUILD_INFO_CXX ${CMAKE_CURRENT_BINARY_DIR}/base/BuildInfo.cxx) @@ -246,7 +248,9 @@ install( ca/TrackingChainConfig.h # NOTE: SZh 20.11.2023: # The ca/qa directory depends on the online qa classes, so for now it has to be a part of the Algo library. - ca/qa/CaQaBuilder.h + ca/qa/CaInputQa.h + ca/qa/CaOutputQa.h + ca/qa/CaQaBase.h DESTINATION include/ ) diff --git a/algo/ca/TrackingChain.cxx b/algo/ca/TrackingChain.cxx index b54a1dfc0ae9edaaee40de06157299343579a324..ea1acc6fcf6f64d993f19b6662c76667890909f1 100644 --- a/algo/ca/TrackingChain.cxx +++ b/algo/ca/TrackingChain.cxx @@ -29,15 +29,20 @@ using cbm::algo::ca::EDetectorID; using cbm::algo::ca::Framework; using cbm::algo::ca::HitTypes_t; using cbm::algo::ca::InitManager; +using cbm::algo::ca::InputQa; +using cbm::algo::ca::OutputQa; using cbm::algo::ca::Parameters; -using cbm::algo::ca::QaBuilder; using cbm::algo::ca::Track; using cbm::algo::ca::constants::clrs::CL; // clear text using cbm::algo::ca::constants::clrs::GNb; // grin bald text // --------------------------------------------------------------------------------------------------------------------- // -TrackingChain::TrackingChain(std::shared_ptr<HistogramSender> histoSender) : fQaBuilder(QaBuilder(histoSender)) {} +TrackingChain::TrackingChain(std::shared_ptr<HistogramSender> histoSender) + : fInputQa(InputQa(histoSender)) + , fOutputQa(OutputQa(histoSender)) +{ +} // --------------------------------------------------------------------------------------------------------------------- // @@ -60,10 +65,13 @@ void TrackingChain::Init() fCaFramework.Init(ca::Framework::TrackingMode::kMcbm); fCaFramework.ReceiveParameters(std::move(parameters)); - // ------ Initialize QA builder - if (fQaBuilder.IsSenderDefined()) { - fQaBuilder.RegisterParameters(&fCaFramework.GetParameters()); - fQaBuilder.Init(); + // ------ Initialize QA modules + if (fOutputQa.IsSenderDefined()) { + fInputQa.RegisterParameters(&fCaFramework.GetParameters()); + fInputQa.Init(); + + fOutputQa.RegisterParameters(&fCaFramework.GetParameters()); + fOutputQa.Init(); } } @@ -149,11 +157,16 @@ TrackingChain::Output_t TrackingChain::PrepareOutput() output.monitorData = fCaMonitorData; // QA - if (fQaBuilder.IsSenderDefined()) { - fQaBuilder.RegisterInputData(&fCaFramework.GetInputData()); - fQaBuilder.RegisterTracks(&output.tracks); - fQaBuilder.RegisterRecoHitIndices(&fCaFramework.fRecoHits); - fQaBuilder.Build(); + if (fOutputQa.IsSenderDefined()) { + fInputQa.RegisterInputData(&fCaFramework.GetInputData()); + fInputQa.RegisterTracks(&output.tracks); + fInputQa.RegisterRecoHitIndices(&fCaFramework.fRecoHits); + fInputQa.Exec(); + + fOutputQa.RegisterInputData(&fCaFramework.GetInputData()); + fOutputQa.RegisterTracks(&output.tracks); + fOutputQa.RegisterRecoHitIndices(&fCaFramework.fRecoHits); + fOutputQa.Exec(); } @@ -170,6 +183,8 @@ void TrackingChain::ReadHits(PartitionedSpan<const ca::HitTypes_t::at<DetID>> hi out.open(std::string("./Debug_hits_") + ca::kDetName[DetID] + ".txt"); } + int nSt = fCaFramework.GetParameters().GetNstationsActive(); + using Hit_t = ca::HitTypes_t::at<DetID>; constexpr bool IsMvd = (DetID == EDetectorID::Mvd); constexpr bool IsSts = (DetID == EDetectorID::Sts); @@ -201,6 +216,11 @@ void TrackingChain::ReadHits(PartitionedSpan<const ca::HitTypes_t::at<DetID>> hi int iStActive = (iStLocal != -1) ? fCaFramework.GetParameters().GetStationIndexActive(iStLocal, DetID) : -1; size_t iOffset = hits.Offsets()[iPartition]; if (iStActive < 0) { + continue; // legit + } + if (iStActive >= nSt) { + L_(error) << "TrackingChain: found hit with wrong active station index above the upper limit: " << iStActive + << ", detector: " << ca::kDetName[DetID]; continue; } double lastTime = -1e9; diff --git a/algo/ca/TrackingChain.h b/algo/ca/TrackingChain.h index 43cd2b4ec95c2d282dc3e845404eb6920021f6c8..ec6bf2644dec09827e7bf408e90ba3b803e6a521 100644 --- a/algo/ca/TrackingChain.h +++ b/algo/ca/TrackingChain.h @@ -11,7 +11,8 @@ #include "CaDataManager.h" #include "CaFramework.h" -#include "CaQaBuilder.h" +#include "CaInputQa.h" +#include "CaOutputQa.h" #include "CaTrack.h" #include "CaTrackingMonitor.h" #include "CaVector.h" @@ -22,6 +23,7 @@ #include "TrackingDefs.h" #include "sts/Hit.h" #include "tof/Hit.h" + #include <memory> #include <vector> @@ -100,7 +102,9 @@ namespace cbm::algo ca::TrackingMonitorData fCaMonitorData{}; ///< CA monitor data object ca::Framework fCaFramework{}; ///< CA framework instance ca::DataManager fCaDataManager{}; ///< CA data manager - ca::QaBuilder fQaBuilder; ///< CA QA builder + + ca::InputQa fInputQa; ///< CA input QA builder + ca::OutputQa fOutputQa; ///< CA output QA builder // ************************ // ** Auxilary variables diff --git a/algo/ca/qa/CaInputQa.cxx b/algo/ca/qa/CaInputQa.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ec3eba9e6c7f821c721d3ea26226bbbfcf87dba7 --- /dev/null +++ b/algo/ca/qa/CaInputQa.cxx @@ -0,0 +1,200 @@ +/* Copyright (C) 2023-2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergei Zharko [committer] */ + +/// \file CaInputQa.cxx +/// \date 01.03.2024 +/// \brief An input QA module for CA tracking (source) +/// \author Sergei Zharko <s.zharko@gsi.de> + +#include "CaInputQa.h" + +#include "../TrackingDefs.h" +#include "CaConstants.h" +#include "CaInputData.h" +#include "CaParameters.h" + +#include <algorithm> +#include <limits> + +#include <fmt/format.h> + +using cbm::algo::ca::Hit; +using cbm::algo::ca::InputQa; +using cbm::algo::ca::constants::math::Pi; + + +// --------------------------------------------------------------------------------------------------------------------- +// +void InputQa::Init() +{ + using cbm::algo::qa::CanvasConfig; + using cbm::algo::qa::Data; + using cbm::algo::qa::H1D; + using cbm::algo::qa::H2D; + using cbm::algo::qa::PadConfig; + using fmt::format; + + if (!fpSender.get()) { + return; + } + + if (!fpParameters) { + L_(error) << "ca::InputQa::Init(): parameters object is not initialized"; + assert(false); + } + + int nSt = fpParameters->GetNstationsActive(); // Number of active tracking stations + + // ------ Init histograms + + // Occupancy distributions + { + fvphHitOccupXY.resize(nSt); + fvphHitOccupZX.resize(nSt); + fvphHitOccupZY.resize(nSt); + + // Station sizes in transverse plane + std::vector<double> vMinX(nSt); + std::vector<double> vMaxX(nSt); + std::vector<double> vMinY(nSt); + std::vector<double> vMaxY(nSt); + + int nBinsXY = 200; + int nBinsZ = 400; + + for (int iSt = 0; iSt < nSt; ++iSt) { + const auto& station = fpParameters->GetStation(iSt); + vMaxX[iSt] = station.GetXmax<double>(); + vMinX[iSt] = station.GetXmin<double>(); + vMaxY[iSt] = station.GetYmax<double>(); + vMinY[iSt] = station.GetYmin<double>(); + double dy = (vMaxY[iSt] - vMinY[iSt]) * kXYZMargin; + double dx = (vMaxX[iSt] - vMinX[iSt]) * kXYZMargin; + vMaxX[iSt] += dx; + vMinX[iSt] -= dx; + vMaxY[iSt] += dy; + vMinY[iSt] -= dy; + } + // Station max + double xMinA = *std::min_element(vMinX.begin(), vMinX.end()); + double xMaxA = *std::max_element(vMaxX.begin(), vMaxX.end()); + double yMinA = *std::min_element(vMinY.begin(), vMinY.end()); + double yMaxA = *std::max_element(vMaxY.begin(), vMaxY.end()); + double zMinA = fpParameters->GetStation(0).GetZ<double>(); + double zMaxA = fpParameters->GetStation(nSt - 1).GetZ<double>(); + { + double dz = (zMaxA - zMinA) * kXYZMargin; + zMinA -= dz; + zMaxA += dz; + } + for (int iSt = 0; iSt < nSt; ++iSt) { + int iStGeo = fpParameters->GetActiveToGeoMap()[iSt]; + auto [detID, iStLoc] = fpParameters->GetGeoToLocalIdMap()[iStGeo]; + for (auto hitSet : kHitSets) { + auto setNm = EHitSet::Input == hitSet ? "input" : "used"; + auto setTl = EHitSet::Input == hitSet ? "Input" : "Used"; + { + auto name = format("hit_{}_occup_xy_sta_{}", setNm, iSt); + 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]); + } + { + 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); + } + { + 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); + } + } + } + } + + // ----- Init canvases + { + // Hit occupancies + for (auto hitSet : kHitSets) { + auto setNm = EHitSet::Input == hitSet ? "input" : "used"; + auto setTl = EHitSet::Input == hitSet ? "Input" : "Used"; + { // XY + auto name = format("ca_hit_{}_occupancy_xy", setNm); + auto titl = format("{} hit occupancy in different stations in XY plane", setNm); + auto canv = CanvasConfig(name, titl); + for (int iSt = 0; iSt < nSt; ++iSt) { + auto pad = PadConfig(); + pad.RegisterHistogram(fvphHitOccupXY[iSt][hitSet], "colz"); + canv.AddPadConfig(pad); + } + fQaData.AddCanvasConfig(canv); + } + { // ZX and ZY + auto name = format("ca_hit_{}_occupancy_zx_zy", setNm); + auto titl = format("{} hit occupancy in different stations in ZX and ZY planes", setTl); + auto canv = CanvasConfig(name, titl); + { // ZX + auto pad = PadConfig(); + for (int iSt = 0; iSt < nSt; ++iSt) { + pad.RegisterHistogram(fvphHitOccupZX[iSt][hitSet], (iSt == 0 ? "colz" : "cols same")); + } + canv.AddPadConfig(pad); + } + { // ZY + auto pad = PadConfig(); + for (int iSt = 0; iSt < nSt; ++iSt) { + pad.RegisterHistogram(fvphHitOccupZY[iSt][hitSet], (iSt == 0 ? "colz" : "cols same")); + } + canv.AddPadConfig(pad); + } + fQaData.AddCanvasConfig(canv); + } + } + } + fQaData.Init(fpSender); +} + +// --------------------------------------------------------------------------------------------------------------------- +// +void InputQa::Exec() +{ + if (!fpSender.get()) { + return; + } + + if (!CheckInit()) { + L_(fatal) << "ca::OutputQa: instance is not initialized"; + assert(false); + } + + // Fill input hit histograms + { + for (const auto& hit : fpInputData->GetHits()) { + FillHitDistributionsForHitSet(EHitSet::Input, hit); + } + + for (int iH : (*fpvRecoHits)) { + FillHitDistributionsForHitSet(EHitSet::Used, fpInputData->GetHit(iH)); + } + } + + fQaData.Send(fpSender); +} + +// --------------------------------------------------------------------------------------------------------------------- +// +void InputQa::FillHitDistributionsForHitSet(InputQa::EHitSet hitSet, const Hit& hit) +{ + int iSt = hit.Station(); + double x = hit.X(); + double y = hit.Y(); + double z = hit.Z(); + fvphHitOccupXY[iSt][hitSet]->Fill(x, y); + fvphHitOccupZX[iSt][hitSet]->Fill(z, x); + fvphHitOccupZY[iSt][hitSet]->Fill(z, y); +} diff --git a/algo/ca/qa/CaInputQa.h b/algo/ca/qa/CaInputQa.h new file mode 100644 index 0000000000000000000000000000000000000000..baeedcb9761e688c582eee678074d3449a72a2b0 --- /dev/null +++ b/algo/ca/qa/CaInputQa.h @@ -0,0 +1,82 @@ +/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergei Zharko [committer] */ + +/// \file CaInputQa.h +/// \date 01.03.2024 +/// \brief A QA module for CA tracking input data (header) +/// \author Sergei Zharko <s.zharko@gsi.de> + +#pragma once + +#include "CaEnumArray.h" +#include "CaQaBase.h" + +namespace cbm::algo::ca +{ + /// \class cbm::algo::ca::qa::InputQa + /// \brief InputQa class for the CA tracking QA (header) + /// + class InputQa : public QaBase { + /// \brief Hit set entries + enum class EHitSet + { + Input, ///< Input hits + Used, ///< Hits used in tracks + kEND + }; + + /// \brief Definition of enum array over EHitSet entries + template<typename T> + using HitSetArray_t = EnumArray<EHitSet, T>; + + /// \brief Array of EHitSet entries for iteration + static constexpr HitSetArray_t<EHitSet> kHitSets = {EHitSet::Input, EHitSet::Used}; + + public: + /// \brief Default destructor + /// \param pSender Pointer to the histogram sender + InputQa(std::shared_ptr<HistogramSender> pSender) : QaBase(pSender, "CA/Input"){}; + + /// \brief Constructor from the configuration object + /// \param config QA configuration object + InputQa() = default; + + /// \brief Copy constructor + InputQa(const InputQa&) = delete; + + /// \brief Move constructor + InputQa(InputQa&&) = delete; + + /// \brief Destructor + ~InputQa() = default; + + /// \brief Copy assignment operator + InputQa& operator=(const InputQa&) = delete; + + /// \brief Move assignment operator + InputQa& operator=(InputQa&&) = delete; + + /// \brief QA execution function + void Exec(); + + /// \brief Initializes the QA + void Init(); + + private: + /// \brief Fills hit distributions + /// \param hitSet Hit set enum entry + /// \param hit Reference to hit + void FillHitDistributionsForHitSet(EHitSet hitSet, const ca::Hit& hit); + + + static constexpr double kXYZMargin = 0.05; ///< Margin for occupancy distributions in XY plane + static constexpr int knHitSets = 2; ///< Number of hit sets: input/used + + // Hit distributions vs. station + using OccupHistContainer_t = std::vector<HitSetArray_t<qa::H2D*>>; + OccupHistContainer_t fvphHitOccupXY; ///< hist: Hit occupancy in different stations in XY plane + OccupHistContainer_t fvphHitOccupZX; ///< hist: Hit occupancy in different stations in ZX plane + OccupHistContainer_t fvphHitOccupZY; ///< hist: Hit occupancy in different stations in ZY plane + }; +} // namespace cbm::algo::ca diff --git a/algo/ca/qa/CaQaBuilder.cxx b/algo/ca/qa/CaOutputQa.cxx similarity index 85% rename from algo/ca/qa/CaQaBuilder.cxx rename to algo/ca/qa/CaOutputQa.cxx index 87e224ef1801db69be7bfb5828e8feb54a1ea0d5..d9c8fd0cc349ecae784b9c0754cf68bad855ffa7 100644 --- a/algo/ca/qa/CaQaBuilder.cxx +++ b/algo/ca/qa/CaOutputQa.cxx @@ -2,12 +2,12 @@ SPDX-License-Identifier: GPL-3.0-only Authors: Sergei Zharko [committer] */ -/// \file CaQaQaBuilder.cxx +/// \file CaQaOutputQa.cxx /// \date 20.11.2023 /// \brief A QA module for CA tracking (implementation) /// \author S.Zharko <s.zharko@gsi.de> -#include "CaQaBuilder.h" +#include "CaOutputQa.h" #include "CaConstants.h" #include "CaInputData.h" @@ -16,27 +16,26 @@ #include <fmt/format.h> -using cbm::algo::ca::QaBuilder; +using cbm::algo::ca::OutputQa; using cbm::algo::ca::constants::math::Pi; -using cbm::algo::qa::CanvasConfig; -using cbm::algo::qa::Data; -using cbm::algo::qa::H1D; -using cbm::algo::qa::H2D; -using cbm::algo::qa::PadConfig; - // --------------------------------------------------------------------------------------------------------------------- // -void QaBuilder::Init() +void OutputQa::Init() { + using cbm::algo::qa::CanvasConfig; + using cbm::algo::qa::Data; + using cbm::algo::qa::H1D; + using cbm::algo::qa::H2D; + using cbm::algo::qa::PadConfig; using fmt::format; if (!fpSender.get()) { return; } - // ---- Init histograms - // TODO: Provide definition from config + + // ----- Histograms initialization constexpr int nParPads = 4; std::array<std::string, knTrkParPoints> vsPointName = {"first", "last"}; for (int i = 0; i < knTrkParPoints; ++i) { @@ -70,6 +69,7 @@ void QaBuilder::Init() // ---- Init canvases { + // Track parameters at first/last track hit for (int i = 0; i < knTrkParPoints; ++i) { @@ -124,27 +124,15 @@ void QaBuilder::Init() // --------------------------------------------------------------------------------------------------------------------- // -void QaBuilder::Build() +void OutputQa::Exec() { if (!fpSender.get()) { return; } - if (!fpParameters) { - LOG(error) << "cbm::algo::ca::QaBuilder::Build(): parameters object is undefined"; - return; - } - if (!fpInputData) { - LOG(error) << "cbm::algo::ca::QaBuilder::Build(): input data object is undefined"; - return; - } - if (!fpvTracks) { - LOG(error) << "cbm::algo::ca::QaBuilder::Build(): tracks vector is undefined"; - return; - } - if (!fpvRecoHits) { - LOG(error) << "cbm::algo::ca::QaBuilder::Build(): reco hit indices vector is undefined"; - return; + if (!CheckInit()) { + L_(fatal) << "ca::OutputQa: instance is not initialized"; + assert(false); } // Fill track histograms diff --git a/algo/ca/qa/CaOutputQa.h b/algo/ca/qa/CaOutputQa.h new file mode 100644 index 0000000000000000000000000000000000000000..2da5c4fd047430922ee0119f4a9e0e17fa243cac --- /dev/null +++ b/algo/ca/qa/CaOutputQa.h @@ -0,0 +1,61 @@ +/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergei Zharko [committer] */ + +/// \file CaOutputQa.h +/// \date 20.11.2023 +/// \brief A QA module for CA tracking (header) +/// \author S.Zharko <s.zharko@gsi.de> + +#pragma once + +#include "CaQaBase.h" + +namespace cbm::algo::ca +{ + /// \class cbm::algo::ca::qa::OutputQa + /// \brief OutputQa class for the CA tracking QA (header) + /// + class OutputQa : public QaBase { + public: + /// \brief Default destructor + /// \param pSender Pointer to the histogram sender + OutputQa(std::shared_ptr<HistogramSender> pSender) : QaBase(pSender, "CA/Output"){}; + + /// \brief Constructor from the configuration object + /// \param config QA configuration object + OutputQa() = default; + + /// \brief Copy constructor + OutputQa(const OutputQa&) = delete; + + /// \brief Move constructor + OutputQa(OutputQa&&) = delete; + + /// \brief Destructor + ~OutputQa() = default; + + /// \brief Copy assignment operator + OutputQa& operator=(const OutputQa&) = delete; + + /// \brief Move assignment operator + OutputQa& operator=(OutputQa&&) = delete; + + /// \brief QA execution function + void Exec(); + + /// \brief Initializes the QA + void Init(); + + private: + static constexpr int knTrkParPoints = 2; ///< Number of track points to build par distributions + + // Track distributions + std::array<qa::H1D*, knTrkParPoints> fvphTrkTheta = {{0}}; ///< hist: theta at first/last hit + std::array<qa::H1D*, knTrkParPoints> fvphTrkPhi = {{0}}; ///< hist: phi at first/last hit + std::array<qa::H1D*, knTrkParPoints> fvphTrkChi2Ndf = {{0}}; ///< hist: chi2/NDF at first/last hit + std::array<qa::H1D*, knTrkParPoints> fvphHitSta = {{0}}; ///< hist: station of first/last hit + std::array<qa::H2D*, knTrkParPoints> fvphTrkPhiTheta = {{0}}; ///< hist: theta vs. phi at first/last hit + qa::H1D* fphTrkNofHits = nullptr; ///< hist: number of hits in track + }; +} // namespace cbm::algo::ca diff --git a/algo/ca/qa/CaQaBase.cxx b/algo/ca/qa/CaQaBase.cxx new file mode 100644 index 0000000000000000000000000000000000000000..da2810670e09ca26f360443956bf6f9181264138 --- /dev/null +++ b/algo/ca/qa/CaQaBase.cxx @@ -0,0 +1,36 @@ +/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergei Zharko [committer] */ + +/// \file CaQaBase.h +/// \date 01.03.2024 +/// \brief Base class for tracking QA (source) +/// \author Sergei Zharko <s.zharko@gsi.de> + +#include "CaQaBase.h" + +using cbm::algo::ca::QaBase; + +// --------------------------------------------------------------------------------------------------------------------- +// +bool QaBase::CheckInit() const +{ + bool res = true; + if (!fpParameters) { + L_(error) << "cbm::algo::ca::OutputQa::Build(): parameters object is undefined"; + res = false; + } + if (!fpInputData) { + L_(error) << "cbm::algo::ca::OutputQa::Build(): input data object is undefined"; + res = false; + } + if (!fpvTracks) { + L_(error) << "cbm::algo::ca::OutputQa::Build(): track vector is undefined"; + res = false; + } + if (!fpvRecoHits) { + L_(error) << "cbm::algo::ca::OutputQa::Build(): used hit index vector is undefined"; + res = false; + } + return res; +} diff --git a/algo/ca/qa/CaQaBase.h b/algo/ca/qa/CaQaBase.h new file mode 100644 index 0000000000000000000000000000000000000000..3a85a06f6a3523f56ba9b9dd1a97ac66bc3c1a74 --- /dev/null +++ b/algo/ca/qa/CaQaBase.h @@ -0,0 +1,100 @@ +/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergei Zharko [committer] */ + +/// \file QaBase.h +/// \date 29.02.2024 +/// \brief Base class for tracking QA (header) +/// \author Sergei Zharko <s.zharko@gsi.de> + +#pragma once + +#include "CaHit.h" // for HitIndex_t +#include "CaTimesliceHeader.h" +#include "CaVector.h" +#include "QaData.h" // QA data + +namespace cbm::algo +{ + namespace qa + { + class H1D; + class H2D; + } // namespace qa + namespace ca + { + template<typename DataT> + class Parameters; + class InputData; + class Track; + } // namespace ca +} // namespace cbm::algo + +namespace cbm::algo::ca +{ + /// \class cbm::algo::ca::qa::QaBase + /// \brief Base class for CA tracking QA + /// + /// The class contains set of pointers to data structures, which are needed to build the histograms. + class QaBase { + public: + /// \brief Default destructor + /// \param pSender Pointer to the histogram sender + /// \param dirname Directory name in the output file + QaBase(std::shared_ptr<HistogramSender> pSender, const std::string& dirname) : fQaData(dirname), fpSender(pSender) + { + } + + /// \brief Constructor from the configuration object + /// \param config QA configuration object + QaBase() = default; + + /// \brief Copy constructor + QaBase(const QaBase&) = delete; + + /// \brief Move constructor + QaBase(QaBase&&) = delete; + + /// \brief Destructor + ~QaBase() = default; + + /// \brief Copy assignment operator + QaBase& operator=(const QaBase&) = delete; + + /// \brief Move assignment operator + QaBase& operator=(QaBase&&) = delete; + + /// \brief Check initialization + /// \return true All variables are initialized + /// \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; } + + /// \brief Registers track vector + /// \note Call per TS + void RegisterTracks(const Vector<Track>* pvTracks) { fpvTracks = pvTracks; } + + /// \brief Registers reco hits indices vector + /// \note Call per TS + void RegisterRecoHitIndices(const Vector<HitIndex_t>* pvRecoHits) { fpvRecoHits = pvRecoHits; } + + /// \brief Registers tracking parameters object + /// \note Call per run + void RegisterParameters(const Parameters<fvec>* pParameters) { fpParameters = pParameters; } + + protected: + 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 + const Vector<HitIndex_t>* fpvRecoHits = nullptr; ///< Pointer to reco hit indices + }; +} // namespace cbm::algo::ca diff --git a/algo/ca/qa/CaQaBuilder.h b/algo/ca/qa/CaQaBuilder.h deleted file mode 100644 index 5fa1f2321ec7a1e4a3809f1d2f022d879deed173..0000000000000000000000000000000000000000 --- a/algo/ca/qa/CaQaBuilder.h +++ /dev/null @@ -1,108 +0,0 @@ -/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt - SPDX-License-Identifier: GPL-3.0-only - Authors: Sergei Zharko [committer] */ - -/// \file CaQaQaBuilder.h -/// \date 20.11.2023 -/// \brief A QA module for CA tracking (header) -/// \author S.Zharko <s.zharko@gsi.de> - -#pragma once - -#include "CaHit.h" // for HitIndex_t -#include "CaTimesliceHeader.h" -#include "CaVector.h" -#include "QaData.h" // QA data - -namespace cbm::algo -{ - namespace qa - { - class H1D; - class H2D; - } // namespace qa -} // namespace cbm::algo - -namespace cbm::algo::ca -{ - template<typename DataT> - class Parameters; - class InputData; - class Track; - - /// \class cbm::algo::ca::qa::QaBuilder - /// \brief QaBuilder class for the CA tracking QA (header) - /// - class QaBuilder { - public: - using TrackV_t = ca::Vector<ca::Track>; - using HitIndexV_t = ca::Vector<std::vector<std::pair<uint32_t, uint32_t>>>; - - /// \brief Default destructor - /// \param pSender Pointer to the histogram sender - QaBuilder(std::shared_ptr<HistogramSender> pSender) : fpSender(pSender){}; - - /// \brief Constructor from the configuration object - /// \param config QA configuration object - QaBuilder() = default; - - /// \brief Copy constructor - QaBuilder(const QaBuilder&) = delete; - - /// \brief Move constructor - QaBuilder(QaBuilder&&) = delete; - - /// \brief Destructor - ~QaBuilder() = default; - - /// \brief Copy assignment operator - QaBuilder& operator=(const QaBuilder&) = delete; - - /// \brief Move assignment operator - QaBuilder& operator=(QaBuilder&&) = delete; - - /// \brief QA execution function - void Build(); - - /// \brief Initializes the QA - void Init(); - - /// \brief Checks, if the histogram sender is defined - bool IsSenderDefined() const { return static_cast<bool>(fpSender.get()); } - - /// \brief Registers tracking input data - /// \note Call per TS - void RegisterInputData(const InputData* pInputData) { fpInputData = pInputData; } - - /// \brief Registers track vector - /// \note Call per TS - void RegisterTracks(const Vector<Track>* pvTracks) { fpvTracks = pvTracks; } - - /// \brief Registers reco hits indices - /// \note Call per TS - void RegisterRecoHitIndices(const Vector<HitIndex_t>* pvRecoHits) { fpvRecoHits = pvRecoHits; } - - /// \brief Registers tracking parameters object - /// \note Call per run - void RegisterParameters(const Parameters<fvec>* pParameters) { fpParameters = pParameters; } - - private: - qa::Data fQaData{"CaQa"}; ///< 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 - const Vector<HitIndex_t>* fpvRecoHits = nullptr; ///< Pointer to reco hit indices - - // ----- List of the histograms ------------------------------------------------------------------------------------ - static constexpr int knTrkParPoints = 2; ///< Number of track points to build par distributions - - std::array<qa::H1D*, knTrkParPoints> fvphTrkTheta = {{0}}; ///< hist: theta at first/last hit - std::array<qa::H1D*, knTrkParPoints> fvphTrkPhi = {{0}}; ///< hist: phi at first/last hit - std::array<qa::H1D*, knTrkParPoints> fvphTrkChi2Ndf = {{0}}; ///< hist: chi2/NDF at first/last hit - std::array<qa::H1D*, knTrkParPoints> fvphHitSta = {{0}}; ///< hist: station of first/last hit - std::array<qa::H2D*, knTrkParPoints> fvphTrkPhiTheta = {{0}}; ///< hist: theta vs. phi at first/last hit - qa::H1D* fphTrkNofHits = nullptr; ///< hist: number of hits in track - }; -} // namespace cbm::algo::ca::qa diff --git a/services/histserv/tester/Application.cxx b/services/histserv/tester/Application.cxx index f6a675dc7261ad4600ae289241c857ef15d1c25a..99e9c3deeaf311d40817dcca719ffa7d88ad8b4d 100644 --- a/services/histserv/tester/Application.cxx +++ b/services/histserv/tester/Application.cxx @@ -45,7 +45,7 @@ namespace cbm::services::histserv_tester /// FIXME: Initialize communication channels of SOMETHING_To_Replace_FairMQ /// FIXME: Link channel to method in order to process received messages // fZmqSocket.set(zmq::sockopt::rcvhwm, int(hwm)); // FIXME: need for HWM? (NOTE: SZh 29.02.2024: if needed, move it - // do it in the HistogramSender) + // in the HistogramSender) } // -------------------------------------------------------------------------------------------------------------------