From 94040dab8fdf9b4d9faa3448a1a2727d0fafa01e Mon Sep 17 00:00:00 2001 From: "s.zharko@gsi.de" <s.zharko@gsi.de> Date: Fri, 14 Jun 2024 18:24:45 +0200 Subject: [PATCH] online STS digi QA: - missed event profile vs. time and TS index --- algo/qa/Histogram.h | 10 ++++++++++ algo/qa/PadConfig.h | 15 +++++++++++++-- algo/qa/QaData.cxx | 16 ++++++++++++++-- algo/qa/unpack/StsDigiQa.cxx | 16 ++++++++++++++++ algo/qa/unpack/StsDigiQa.h | 1 + services/histserv/app/Application.cxx | 10 +++++++--- services/histserv/app/Application.h | 1 - 7 files changed, 61 insertions(+), 8 deletions(-) diff --git a/algo/qa/Histogram.h b/algo/qa/Histogram.h index 852d9cf91b..1b70f3b058 100644 --- a/algo/qa/Histogram.h +++ b/algo/qa/Histogram.h @@ -65,6 +65,8 @@ namespace cbm::algo::qa public: using Flags_t = std::underlying_type_t<EHistFlag>; + static constexpr std::string_view ksTsIdSuffix = "_ts_id"; ///< Suffix of additional histograms vs. TS index + /// \brief Default constructor HistogramMetadata() = default; @@ -80,6 +82,14 @@ namespace cbm::algo::qa /// \brief Destructor ~HistogramMetadata() = default; + /// \brief Checks if the histogram flags configuration is valid + /// \return Is valid + bool CheckFlags() const + { + // The histogram must be plotted either vs TS, or over all TS + return (GetFlag(EHistFlag::StoreVsTsId) || !GetFlag(EHistFlag::OmitIntegrated)); + } + /// \brief Get flag /// \param key Flag key from the EHistFlag enumeration bool GetFlag(EHistFlag key) const { return static_cast<bool>(fFlags & static_cast<Flags_t>(key)); } diff --git a/algo/qa/PadConfig.h b/algo/qa/PadConfig.h index a7dc7469d4..4d6ac5376c 100644 --- a/algo/qa/PadConfig.h +++ b/algo/qa/PadConfig.h @@ -82,11 +82,22 @@ namespace cbm::algo::qa /// \tparam Hist Histogram class /// \param hist Histogram object /// \param opt Draw options for the histogram - // TODO: implement a single function + /// + /// If the histogram has EHistFlag::StoreVsTsId, then the TS dependendent histogram + /// will be plotted only. If both integrated and vs. TS histograms are needed, please + /// explicitly provide the histogram names to two separate pads using the RegisterObject + /// function. template<class Hist> void RegisterHistogram(const Hist* hist, std::string_view opt) { - RegisterObject(hist->GetName(), opt); + // NOTE: SZh 21.06.2024: + const auto& metadata = hist->GetMetadata(); + if (metadata.GetFlag(EHistFlag::StoreVsTsId)) { + RegisterObject(hist->GetName() + std::string(HistogramMetadata::ksTsIdSuffix), opt); + } + else if (!metadata.GetFlag(EHistFlag::OmitIntegrated)) { + RegisterObject(hist->GetName(), opt); + } } /// \brief Returns message config diff --git a/algo/qa/QaData.cxx b/algo/qa/QaData.cxx index ea184f35c1..1ead168f18 100644 --- a/algo/qa/QaData.cxx +++ b/algo/qa/QaData.cxx @@ -16,7 +16,7 @@ using cbm::algo::qa::Data; // --------------------------------------------------------------------------------------------------------------------- // void Data::Init(std::shared_ptr<HistogramSender> histSender) -{ +try { if (histSender.get()) { // Forming a histogram config message std::vector<std::pair<std::string, std::string>> vHistCfgs; @@ -28,7 +28,15 @@ void Data::Init(std::shared_ptr<HistogramSender> histSender) nHistograms += std::distance(fHistograms.fvP2.begin(), fHistograms.fvP2.end()); vHistCfgs.reserve(nHistograms); - auto RegHist = [&](const auto& h) { vHistCfgs.emplace_back(h.GetName() + "!" + h.GetMetadataString(), fsName); }; + auto RegHist = [&](const auto& h) { + if (!h.GetMetadata().CheckFlags()) { + std::stringstream msg; + msg << "attempt to pass a histogram " << h.GetName() + << " with inconsistent flags (see HistogramMetadata::CheckFlags for detailes)"; + throw std::runtime_error(msg.str()); + } + vHistCfgs.emplace_back(h.GetName() + "!" + h.GetMetadataString(), fsName); + }; std::for_each(fHistograms.fvH1.begin(), fHistograms.fvH1.end(), RegHist); std::for_each(fHistograms.fvH2.begin(), fHistograms.fvH2.end(), RegHist); @@ -54,6 +62,10 @@ void Data::Init(std::shared_ptr<HistogramSender> histSender) histSender->PrepareAndSendMsg(qa::HistogramContainer{}, zmq::send_flags::none); } } +catch (const std::exception& err) { + L_(fatal) << "cbm::algo::qa::Data for " << fsName << " fatally aborted. Reason " << err.what(); + assert(false); +} // --------------------------------------------------------------------------------------------------------------------- // diff --git a/algo/qa/unpack/StsDigiQa.cxx b/algo/qa/unpack/StsDigiQa.cxx index 8cb7a9ce0b..7c502536c4 100644 --- a/algo/qa/unpack/StsDigiQa.cxx +++ b/algo/qa/unpack/StsDigiQa.cxx @@ -56,6 +56,7 @@ void DigiQa::Init() if (fbAux) { fvphAddressChannelElink.resize(nModules); fvppAddressChannelMissedEvt.resize(nModules); + fvppAddressTimeMissedEvt.resize(nModules); } for (int iM = 0; iM < nModules; ++iM) { int32_t address = fpReadoutSetup->modules.at(iM).address; @@ -110,6 +111,20 @@ void DigiQa::Init() pad.RegisterHistogram(fvppAddressChannelMissedEvt[iM], ""); canv.AddPadConfig(pad); } + { + auto pad = PadConfig(); + auto name = format("sts_digi_{}_time_missed_evt", aName); + auto titl = + format("STS digi missed event ratio for module {};time [ms]; N_{{w/ missed events}} / N_{{tot.}}", aTitl); + constexpr double timeMin = 0.; // [ms] + constexpr double timeMax = 150.; // [ms] + int timeBins = std::ceil(timeMax - timeMin); + fvppAddressTimeMissedEvt[iM] = fQaData.MakeObj<Prof1D>(name, titl, timeBins, timeMin, timeMax, 0., 1.); + fvppAddressTimeMissedEvt[iM]->SetFlag(EHistFlag::StoreVsTsId); + fvppAddressTimeMissedEvt[iM]->SetFlag(EHistFlag::OmitIntegrated); + pad.RegisterHistogram(fvppAddressTimeMissedEvt[iM], ""); + canv.AddPadConfig(pad); + } } fQaData.AddCanvasConfig(canv); @@ -161,6 +176,7 @@ void DigiQa::Exec() fvphAddressChannelElink[iM]->Fill(static_cast<double>(auxDigi.elink), static_cast<double>(auxDigi.channel)); fvppAddressChannelMissedEvt[iM]->Fill(static_cast<double>(auxDigi.channel), static_cast<double>(auxDigi.missedEvent)); + fvppAddressTimeMissedEvt[iM]->Fill(auxDigi.time * 1.e-6, static_cast<double>(auxDigi.missedEvent)); } } } diff --git a/algo/qa/unpack/StsDigiQa.h b/algo/qa/unpack/StsDigiQa.h index 9b3787b6de..1e70c3d026 100644 --- a/algo/qa/unpack/StsDigiQa.h +++ b/algo/qa/unpack/StsDigiQa.h @@ -59,6 +59,7 @@ namespace cbm::algo::sts std::vector<qa::H2D*> fvphAddressChannelElink; ///< hist: digi channel (vs. eling (AUX) std::vector<qa::Prof1D*> fvppAddressChannelMissedEvt; ///< prof: missed event ratio vs. channel (AUX) + std::vector<qa::Prof1D*> fvppAddressTimeMissedEvt; ///< prof: missed event ratio vs. time (AUX) qa::H2D* fvphFebAsic = nullptr; ///< hist: digi FEB vs ASIC }; diff --git a/services/histserv/app/Application.cxx b/services/histserv/app/Application.cxx index 2e698f8b9b..5eb5362f05 100644 --- a/services/histserv/app/Application.cxx +++ b/services/histserv/app/Application.cxx @@ -46,6 +46,7 @@ using cbm::services::histserv::Application; using cbm::algo::qa::H1D; using cbm::algo::qa::H2D; +using cbm::algo::qa::HistogramMetadata; using cbm::algo::qa::Prof1D; using cbm::algo::qa::Prof2D; @@ -395,7 +396,7 @@ bool Application::ReceiveHistoConfig(zmq::message_t& msg) } if (metadata.GetFlag(EHistFlag::StoreVsTsId)) { // Histogram vs. TS id - this->RegisterHistoConfig(std::make_pair(name + std::string(ksTsIdSuffix), tempObject.second)); + this->RegisterHistoConfig(std::make_pair(name + std::string(HistogramMetadata::ksTsIdSuffix), tempObject.second)); } return true; @@ -620,7 +621,7 @@ bool Application::ReadHistogramExtendedTsId(const HistoSrc& rHist, uint64_t tsIn using HistoDst_t = typename std::conditional<IsSrcH1D, TH2D, TProfile2D>::type; /* clang-format on */ - std::string sHistoName = rHist.GetName() + std::string(ksTsIdSuffix); + std::string sHistoName = rHist.GetName() + std::string(HistogramMetadata::ksTsIdSuffix); int index1 = FindHistogram(sHistoName.c_str()); if (-1 == index1) { // ----- Creating new histogram @@ -642,6 +643,7 @@ bool Application::ReadHistogramExtendedTsId(const HistoSrc& rHist, uint64_t tsIn double maxZ = rHist.GetMaxY(); histogram_new = new TProfile2D(sHistoName.c_str(), title.c_str(), nBinsX, minX, maxX, nBinsY, minY, maxY, minZ, maxZ); + histogram_new->Sumw2(); } } cbm::qa::OnlineInterface::AddSlice(rHist, double(tsIndex), histogram_new); @@ -748,8 +750,8 @@ int Application::FindHistogram(const std::string& name) // bool Application::PrepareCanvas(uint32_t uCanvIdx) { - LOG(info) << " Extracting configuration for canvas index " << uCanvIdx; CanvasConfig conf(ExtractCanvasConfigFromString(fvpsCanvasConfig[uCanvIdx].second)); + LOG(info) << " Extracting configuration for canvas index " << uCanvIdx << "(name: " << conf.GetName().data() << ")"; /// First check if all objects to be drawn are present uint32_t uNbPads(conf.GetNbPads()); @@ -760,6 +762,8 @@ bool Application::PrepareCanvas(uint32_t uCanvIdx) /// Check for empty pads! if ("nullptr" != sName) { if (FindHistogram(sName) < 0) { + LOG(warn) << "Histogram \"" << sName << "\" requested by canvas \"" << conf.GetName().data() + << "\" was not found"; return false; } // if( FindHistogram( conf.GetObjName( uPadIdx, uObjIdx ) ) < 0 ) } // if( "nullptr" != sName ) diff --git a/services/histserv/app/Application.h b/services/histserv/app/Application.h index 53cbdc8483..580e0dba47 100644 --- a/services/histserv/app/Application.h +++ b/services/histserv/app/Application.h @@ -31,7 +31,6 @@ namespace cbm::services::histserv }; class Application { - static constexpr std::string_view ksTsIdSuffix = "_ts_id"; ///< Suffix of additional histograms vs. TS index public: /** @brief Standard constructor, initialises the application -- GitLab