From 3ee9c5556bc143cb674ae713bb96d77c371173b9 Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Fri, 4 Jul 2025 11:30:47 +0200 Subject: [PATCH 1/2] [Common] allow access to the reference comparator plots in derived classes The changes allow to use the ReferenceComparatorTask as a base class, providing access to the reference comparison plots for the derived classes. A typical use case would be a post-processing task that produces some derived plots, which also need to compared with some reference. With the current production code, this involves adding a dedicated ReferenceComparatorTask in the workflow, that fetches the plots from the post-processing task from the QCDB. This commit allows to solve the above problem by deriving the post-processing task from the ReferenceComparatorTask, such that the reference comparison plots can be filled directly by the derived task, without going through the QCDB. This is achieved with the following two changes: * addition of a function that exposes the reference comparison plots in the ReferenceComparatorTask interface * storage of the pointer to the reference histogram in the ReferenceComparatorPlot object, such that it does not need to be passed to the `update()` method --- .../include/Common/ReferenceComparatorPlot.h | 2 +- .../include/Common/ReferenceComparatorTask.h | 3 +++ .../Common/src/ReferenceComparatorPlot.cxx | 27 ++++++++++--------- .../Common/src/ReferenceComparatorTask.cxx | 17 +++++++++--- 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/Modules/Common/include/Common/ReferenceComparatorPlot.h b/Modules/Common/include/Common/ReferenceComparatorPlot.h index 2d684f9134..55786cab2c 100644 --- a/Modules/Common/include/Common/ReferenceComparatorPlot.h +++ b/Modules/Common/include/Common/ReferenceComparatorPlot.h @@ -48,7 +48,7 @@ class ReferenceComparatorPlot virtual ~ReferenceComparatorPlot() = default; TObject* getMainCanvas(); - void update(TH1* histogram, TH1* referenceHistogram); + void update(TH1* histogram); private: std::shared_ptr mImplementation; diff --git a/Modules/Common/include/Common/ReferenceComparatorTask.h b/Modules/Common/include/Common/ReferenceComparatorTask.h index 62900049d0..67a3994492 100644 --- a/Modules/Common/include/Common/ReferenceComparatorTask.h +++ b/Modules/Common/include/Common/ReferenceComparatorTask.h @@ -50,6 +50,9 @@ class ReferenceComparatorTask : public quality_control::postprocessing::PostProc void update(quality_control::postprocessing::Trigger, framework::ServiceRegistryRef) override; void finalize(quality_control::postprocessing::Trigger, framework::ServiceRegistryRef) override; + std::map>& getComparatorPlots() { return mHistograms; } + std::shared_ptr getComparatorPlot(std::string plotName); + struct HistoWithRef { std::shared_ptr mPlot; std::shared_ptr mRefPlot; diff --git a/Modules/Common/src/ReferenceComparatorPlot.cxx b/Modules/Common/src/ReferenceComparatorPlot.cxx index 8ef659900c..42d05e5d53 100644 --- a/Modules/Common/src/ReferenceComparatorPlot.cxx +++ b/Modules/Common/src/ReferenceComparatorPlot.cxx @@ -159,21 +159,21 @@ static std::shared_ptr createHisto2D(const char* name, const char* title, class ReferenceComparatorPlotImpl { public: - ReferenceComparatorPlotImpl(bool scaleReference) - : mScaleReference(scaleReference) + ReferenceComparatorPlotImpl(TH1* referenceHistogram, bool scaleReference) + : mReferenceHistogram(referenceHistogram), mScaleReference(scaleReference) { } virtual ~ReferenceComparatorPlotImpl() = default; - virtual TObject* init(TH1* referenceHistogram, std::string outputPath, bool scaleReference, bool drawRatioOnly, std::string drawOption) + virtual TObject* getMainCanvas() { return nullptr; } - virtual TObject* getMainCanvas() + TH1* getReferenceHistogram() { - return nullptr; + return mReferenceHistogram; } void setScaleRef(bool scaleReference) @@ -183,9 +183,10 @@ class ReferenceComparatorPlotImpl bool getScaleReference() { return mScaleReference; } - virtual void update(TH1* histogram, TH1* referenceHistogram) = 0; + virtual void update(TH1* histogram) = 0; private: + TH1* mReferenceHistogram{ nullptr }; bool mScaleReference{ true }; }; @@ -200,7 +201,7 @@ class ReferenceComparatorPlotImpl1D : public ReferenceComparatorPlotImpl bool drawRatioOnly, double legendHeight, const std::string& drawOption) - : ReferenceComparatorPlotImpl(scaleReference), mLegendHeight(legendHeight) + : ReferenceComparatorPlotImpl(referenceHistogram, scaleReference), mLegendHeight(legendHeight) { float labelSize = 0.04; @@ -343,8 +344,9 @@ class ReferenceComparatorPlotImpl1D : public ReferenceComparatorPlotImpl return mCanvas.get(); } - void update(TH1* hist, TH1* referenceHistogram) + void update(TH1* hist) { + TH1* referenceHistogram = getReferenceHistogram(); if (!hist || !referenceHistogram) { return; } @@ -389,7 +391,7 @@ class ReferenceComparatorPlotImpl2D : public ReferenceComparatorPlotImpl bool scaleReference, bool drawRatioOnly, const std::string& drawOption) - : ReferenceComparatorPlotImpl(scaleReference) + : ReferenceComparatorPlotImpl(referenceHistogram, scaleReference) { if (!referenceHistogram) { return; @@ -498,8 +500,9 @@ class ReferenceComparatorPlotImpl2D : public ReferenceComparatorPlotImpl return mCanvas.get(); } - void update(TH1* histogram, TH1* referenceHistogram) + void update(TH1* histogram) { + TH1* referenceHistogram = getReferenceHistogram(); if (!histogram || !referenceHistogram) { return; } @@ -559,10 +562,10 @@ TObject* ReferenceComparatorPlot::getMainCanvas() return (mImplementation.get() ? mImplementation->getMainCanvas() : nullptr); } -void ReferenceComparatorPlot::update(TH1* histogram, TH1* referenceHistogram) +void ReferenceComparatorPlot::update(TH1* histogram) { if (mImplementation) { - mImplementation->update(histogram, referenceHistogram); + mImplementation->update(histogram); } } diff --git a/Modules/Common/src/ReferenceComparatorTask.cxx b/Modules/Common/src/ReferenceComparatorTask.cxx index 682429c236..4471f7be42 100644 --- a/Modules/Common/src/ReferenceComparatorTask.cxx +++ b/Modules/Common/src/ReferenceComparatorTask.cxx @@ -167,6 +167,18 @@ void ReferenceComparatorTask::initialize(quality_control::postprocessing::Trigge //_________________________________________________________________________________________ +std::shared_ptr ReferenceComparatorTask::getComparatorPlot(std::string plotName) +{ + // check if a corresponding output plot was initialized + auto iter = mHistograms.find(plotName); + if (iter == mHistograms.end()) { + return {}; + } + return iter->second; +} + +//_________________________________________________________________________________________ + void ReferenceComparatorTask::update(quality_control::postprocessing::Trigger trigger, framework::ServiceRegistryRef services) { auto& qcdb = services.get(); @@ -194,10 +206,7 @@ void ReferenceComparatorTask::update(quality_control::postprocessing::Trigger tr } // update the plot ratios and the histograms with superimposed reference - auto referenceMO = mReferencePlots[plotName]; - TH1* referenceHistogram = dynamic_cast(referenceMO->getObject()); - - iter->second->update(histogram, referenceHistogram); + iter->second->update(histogram); } } } From e40c600a92df2d754c63dfafe531c297620419e3 Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Fri, 4 Jul 2025 11:33:18 +0200 Subject: [PATCH 2/2] [Common] add reference comparator plots accessor functions Add to the ReferenceUtils.h header file the functions that allow to access the current, reference and ratio plots from the TCanvas created by the ReferenceComparartorPlot class. This will allow for example custom checkers to access the plots. --- .../include/QualityControl/ReferenceUtils.h | 67 ++++++++++++++++++ .../Common/src/ReferenceComparatorCheck.cxx | 68 +------------------ 2 files changed, 70 insertions(+), 65 deletions(-) diff --git a/Framework/include/QualityControl/ReferenceUtils.h b/Framework/include/QualityControl/ReferenceUtils.h index 5b8f6d7b6f..27b20fce19 100644 --- a/Framework/include/QualityControl/ReferenceUtils.h +++ b/Framework/include/QualityControl/ReferenceUtils.h @@ -25,6 +25,9 @@ #include "QualityControl/QcInfoLogger.h" #include "QualityControl/RepoPathUtils.h" +#include +#include + namespace o2::quality_control::checker { @@ -42,6 +45,70 @@ static std::shared_ptr getReferencePlot(qu return qcdb->retrieveMO(path, name, repository::DatabaseInterface::Timestamp::Latest, referenceActivity); } +//_________________________________________________________________________________________ +// +// Get the current and reference histograms from the container canvas. +// The two histograms are returned as a std::pair + +static std::pair getPlotsFromCanvas(TCanvas* canvas, std::string& message) +{ + // Get the pad containing the current histogram, as well as the reference one in the case of 1-D plots + TPad* padHist = dynamic_cast(canvas->GetPrimitive(TString::Format("%s_PadHist", canvas->GetName()))); + if (!padHist) { + message = "missing PadHist"; + return { nullptr, nullptr }; + } + // Get the pad containing the reference histogram. + // This pad is only present for 2-D histograms. + // 1-D histograms are drawn superimposed in the same pad + TPad* padHistRef = (TPad*)canvas->GetPrimitive(TString::Format("%s_PadHistRef", canvas->GetName())); + + // Get the current histogram + TH1* hist = dynamic_cast(padHist->GetPrimitive(TString::Format("%s_hist", canvas->GetName()))); + if (!hist) { + message = "missing histogram"; + return { nullptr, nullptr }; + } + + // Get the reference histogram, trying both pads + TH1* histRef = nullptr; + if (padHistRef) { + histRef = dynamic_cast(padHistRef->GetPrimitive(TString::Format("%s_hist_ref", canvas->GetName()))); + } else { + histRef = dynamic_cast(padHist->GetPrimitive(TString::Format("%s_hist_ref", canvas->GetName()))); + } + + if (!histRef) { + message = "missing reference histogram"; + return { nullptr, nullptr }; + } + + // return a pair with the two histograms + return { hist, histRef }; +} + +//_________________________________________________________________________________________ +// +// Get the ratio histogram from the container canvas + +static TH1* getRatioPlotFromCanvas(TCanvas* canvas) +{ + // Get the pad containing the current histogram, as well as the reference one in the case of 1-D plots + TPad* padHistRatio = dynamic_cast(canvas->GetPrimitive(TString::Format("%s_PadHistRatio", canvas->GetName()))); + if (!padHistRatio) { + return nullptr; + } + + // Get the current histogram + TH1* histRatio = dynamic_cast(padHistRatio->GetPrimitive(TString::Format("%s_hist_ratio", canvas->GetName()))); + if (!histRatio) { + return nullptr; + } + + // return a pair with the two histograms + return histRatio; +} + } // namespace o2::quality_control::checker #endif // QUALITYCONTROL_ReferenceUtils_H diff --git a/Modules/Common/src/ReferenceComparatorCheck.cxx b/Modules/Common/src/ReferenceComparatorCheck.cxx index 1c890e8c9a..c3eea7b6a4 100644 --- a/Modules/Common/src/ReferenceComparatorCheck.cxx +++ b/Modules/Common/src/ReferenceComparatorCheck.cxx @@ -75,72 +75,10 @@ void ReferenceComparatorCheck::endOfActivity(const Activity& activity) { } -//_________________________________________________________________________________________ -// -// Get the current and reference histograms from the canvas. -// The two histograms are returned as a std::pair -static std::pair getPlotsFromCanvas(TCanvas* canvas, std::string& message) -{ - // Get the pad containing the current histogram, as well as the reference one in the case of 1-D plots - TPad* padHist = (TPad*)canvas->GetPrimitive(TString::Format("%s_PadHist", canvas->GetName())); - if (!padHist) { - message = "missing PadHist"; - return { nullptr, nullptr }; - } - // Get the pad containing the reference histogram. - // This pad is only present for 2-D histograms. - // 1-D histograms are drawn superimposed in the same pad - TPad* padHistRef = (TPad*)canvas->GetPrimitive(TString::Format("%s_PadHistRef", canvas->GetName())); - - // Get the current histogram - TH1* hist = dynamic_cast(padHist->GetPrimitive(TString::Format("%s_hist", canvas->GetName()))); - if (!hist) { - message = "missing histogram"; - return { nullptr, nullptr }; - } - - // Get the reference histogram, trying both pads - TH1* histRef = nullptr; - if (padHistRef) { - histRef = dynamic_cast(padHistRef->GetPrimitive(TString::Format("%s_hist_ref", canvas->GetName()))); - } else { - histRef = dynamic_cast(padHist->GetPrimitive(TString::Format("%s_hist_ref", canvas->GetName()))); - } - - if (!histRef) { - message = "missing reference histogram"; - return { nullptr, nullptr }; - } - - // return a pair with the two histograms - return { hist, histRef }; -} - static std::pair getPlotsFromCanvas(TCanvas* canvas) { std::string dummyMessage; - return getPlotsFromCanvas(canvas, dummyMessage); -} - -//_________________________________________________________________________________________ -// -// Get the ratio histograms from the canvas -static TH1* getRatioPlotFromCanvas(TCanvas* canvas) -{ - // Get the pad containing the current histogram, as well as the reference one in the case of 1-D plots - TPad* padHistRatio = (TPad*)canvas->GetPrimitive(TString::Format("%s_PadHistRatio", canvas->GetName())); - if (!padHistRatio) { - return nullptr; - } - - // Get the current histogram - TH1* histRatio = dynamic_cast(padHistRatio->GetPrimitive(TString::Format("%s_hist_ratio", canvas->GetName()))); - if (!histRatio) { - return nullptr; - } - - // return a pair with the two histograms - return histRatio; + return o2::quality_control::checker::getPlotsFromCanvas(canvas, dummyMessage); } // Get the current and reference histograms from the canvas, and compare them using the comparator object passed as parameter @@ -156,7 +94,7 @@ static Quality compare(TCanvas* canvas, ObjectComparatorInterface* comparator, s } // extract the histograms from the canvas - auto plots = getPlotsFromCanvas(canvas, message); + auto plots = o2::quality_control::checker::getPlotsFromCanvas(canvas, message); if (!plots.first || !plots.second) { return Quality::Null; } @@ -389,7 +327,7 @@ void ReferenceComparatorCheck::beautify(std::shared_ptr mo, Quali setQualityLabel(canvas, quality); // draw a double-arrow indicating the horizontal range for the check, if it is set - beautifyRatioPlot(moName, getRatioPlotFromCanvas(canvas), quality); + beautifyRatioPlot(moName, o2::quality_control::checker::getRatioPlotFromCanvas(canvas), quality); } else { // draw the quality label directly on the plot if the MO is an histogram auto* th1 = dynamic_cast(mo->getObject());