From 1a6b31d2f0e0ca74038373908614112f6170221e Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Wed, 26 Jun 2024 11:25:03 +0200 Subject: [PATCH 01/25] [QC-885] Modify ReferenceComparatorCheck to also accept a TH1 instead of a Canvas - also pass the database object from CheckRunner to CheckInterface and use it to implement a new method `retrieveReference`. --- Framework/include/QualityControl/Check.h | 6 ++ .../include/QualityControl/CheckInterface.h | 12 +++ .../include/QualityControl/ReferenceUtils.h | 61 +++++++++++++++ .../include/QualityControl/RepoPathUtils.h | 13 ++++ Framework/src/CheckInterface.cxx | 6 ++ Framework/src/CheckRunner.cxx | 1 + .../include/Common/ReferenceComparatorCheck.h | 3 + .../include/Common/ReferenceComparatorTask.h | 4 - .../Common/src/ReferenceComparatorCheck.cxx | 75 ++++++++++++++----- .../Common/src/ReferenceComparatorTask.cxx | 59 +-------------- doc/Advanced.md | 6 ++ 11 files changed, 166 insertions(+), 80 deletions(-) create mode 100644 Framework/include/QualityControl/ReferenceUtils.h diff --git a/Framework/include/QualityControl/Check.h b/Framework/include/QualityControl/Check.h index 879808b2cb..a1376e94fc 100644 --- a/Framework/include/QualityControl/Check.h +++ b/Framework/include/QualityControl/Check.h @@ -19,8 +19,10 @@ // O2 #include // QC +#include "QualityControl/DatabaseInterface.h" #include "QualityControl/QualityObject.h" #include "QualityControl/CheckConfig.h" +#include "QualityControl/CheckInterface.h" namespace o2::quality_control::core { @@ -92,6 +94,10 @@ class Check static CheckConfig extractConfig(const core::CommonSpec&, const CheckSpec&); static framework::OutputSpec createOutputSpec(const std::string& detector, const std::string& checkName); + void setDatabase(std::shared_ptr database) { + mCheckInterface->setDatabase(database); + } + private: void beautify(std::map>& moMap, const core::Quality& quality); diff --git a/Framework/include/QualityControl/CheckInterface.h b/Framework/include/QualityControl/CheckInterface.h index efe63cf29b..e3f8a47657 100644 --- a/Framework/include/QualityControl/CheckInterface.h +++ b/Framework/include/QualityControl/CheckInterface.h @@ -17,6 +17,7 @@ #ifndef QC_CHECKER_CHECKINTERFACE_H #define QC_CHECKER_CHECKINTERFACE_H +#include "QualityControl/DatabaseInterface.h" #include "QualityControl/Quality.h" #include "QualityControl/UserCodeInterface.h" #include "QualityControl/Activity.h" @@ -82,10 +83,21 @@ class CheckInterface : public core::UserCodeInterface virtual void startOfActivity(const core::Activity& activity); // not fully abstract because we don't want to change all the existing subclasses virtual void endOfActivity(const core::Activity& activity); // not fully abstract because we don't want to change all the existing subclasses + void setDatabase(std::shared_ptr database) { + mDatabase = database; + } + protected: /// \brief Called each time mCustomParameters is updated. virtual void configure() override; + /// \brief Retrieve a reference plot at the provided path, matching the give activity and for the provided run. + /// the activity is the current one, while the run number is the reference run. + std::shared_ptr retrieveReference(std::string path, int referenceRun, Activity activity); + + private: + std::shared_ptr mDatabase; + ClassDef(CheckInterface, 6) }; diff --git a/Framework/include/QualityControl/ReferenceUtils.h b/Framework/include/QualityControl/ReferenceUtils.h new file mode 100644 index 0000000000..304d8edcde --- /dev/null +++ b/Framework/include/QualityControl/ReferenceUtils.h @@ -0,0 +1,61 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// \file ReferenceComparatorUtils.h +/// \author Andrea Ferrero and Barthelemy von Haller +/// + +#ifndef QUALITYCONTROL_ReferenceComparatorUtils_H +#define QUALITYCONTROL_ReferenceComparatorUtils_H + +#include +#include "QualityControl/MonitorObject.h" +#include "QualityControl/DatabaseInterface.h" +#include "QualityControl/Activity.h" +#include "QualityControl/ActivityHelpers.h" +#include "QualityControl/QcInfoLogger.h" +#include "QualityControl/RepoPathUtils.h" + +namespace o2::quality_control_modules::common +{ + +//_________________________________________________________________________________________ +// +// Get the reference plot for a given MonitorObject path + +static std::shared_ptr getReferencePlot(quality_control::repository::DatabaseInterface* qcdb, std::string& fullPath, uint32_t referenceRun, quality_control::core::Activity activity) +{ + uint64_t timeStamp = 0; + activity.mId = referenceRun; + const auto filterMetadata = quality_control::core::activity_helpers::asDatabaseMetadata(activity, false); + const auto objectValidity = qcdb->getLatestObjectValidity(activity.mProvenance + "/" + fullPath, filterMetadata); + if (objectValidity.isValid()) { + timeStamp = objectValidity.getMax() - 1; + } else { + ILOG(Warning, Devel) << "Could not find the object '" << fullPath << "' for run " << activity.mId << ENDM; + return nullptr; + } + + std::string path; + std::string name; + if (!o2::quality_control::core::RepoPathUtils::splitObjectPath(fullPath, path, name)) { + return nullptr; + } + // retrieve MO from CCDB + auto mo = qcdb->retrieveMO(path, name, timeStamp, activity); + + return mo; +} + +} // namespace o2::quality_control_modules::common + +#endif // QUALITYCONTROL_ReferenceComparatorUtils_H diff --git a/Framework/include/QualityControl/RepoPathUtils.h b/Framework/include/QualityControl/RepoPathUtils.h index ac03cfeeb8..af3a627577 100644 --- a/Framework/include/QualityControl/RepoPathUtils.h +++ b/Framework/include/QualityControl/RepoPathUtils.h @@ -128,6 +128,19 @@ class RepoPathUtils static constexpr auto allowedProvenancesMessage = R"(Allowed provenances are "qc" (real data processed synchronously), "qc_async" (real data processed asynchronously) and "qc_mc" (simulated data).)"; static bool isProvenanceAllowed(const std::string& provenance); + + static bool splitObjectPath(const std::string& fullPath, std::string& path, std::string& name) + { + std::string delimiter = "/"; + std::string det; + size_t pos = fullPath.rfind(delimiter); + if (pos == std::string::npos) { + return false; + } + path = fullPath.substr(0, pos); + name = fullPath.substr(pos + 1); + return true; + } }; } // namespace o2::quality_control::core diff --git a/Framework/src/CheckInterface.cxx b/Framework/src/CheckInterface.cxx index 6d07cb3cda..bdc7c0cf5f 100644 --- a/Framework/src/CheckInterface.cxx +++ b/Framework/src/CheckInterface.cxx @@ -15,6 +15,7 @@ /// #include "QualityControl/CheckInterface.h" +#include "QualityControl/ReferenceUtils.h" #include "QualityControl/MonitorObject.h" #include @@ -59,4 +60,9 @@ void CheckInterface::endOfActivity(const Activity& activity) // noop, override it if you want. } +shared_ptr CheckInterface::retrieveReference(std::string path, int referenceRun, Activity activity) +{ + return quality_control_modules::common::getReferencePlot(mDatabase.get(), path, referenceRun, activity); +} + } // namespace o2::quality_control::checker diff --git a/Framework/src/CheckRunner.cxx b/Framework/src/CheckRunner.cxx index 62cad609c5..e231e9131e 100644 --- a/Framework/src/CheckRunner.cxx +++ b/Framework/src/CheckRunner.cxx @@ -231,6 +231,7 @@ void CheckRunner::init(framework::InitContext& iCtx) updatePolicyManager.reset(); for (auto& [checkName, check] : mChecks) { check.init(); + check.setDatabase(mDatabase); updatePolicyManager.addPolicy(check.getName(), check.getUpdatePolicyType(), check.getObjectsNames(), check.getAllObjectsOption(), false); } } catch (...) { diff --git a/Modules/Common/include/Common/ReferenceComparatorCheck.h b/Modules/Common/include/Common/ReferenceComparatorCheck.h index 1f7f070b25..200a358d1d 100644 --- a/Modules/Common/include/Common/ReferenceComparatorCheck.h +++ b/Modules/Common/include/Common/ReferenceComparatorCheck.h @@ -49,9 +49,12 @@ class ReferenceComparatorCheck : public o2::quality_control::checker::CheckInter void endOfActivity(const Activity& activity) override; private: + Quality getSinglePlotQuality(std::shared_ptr mo, std::string& message); + std::unique_ptr mComparator; std::map mQualityFlags; std::map> mQualityLabels; + quality_control::core::Activity mActivity; }; } // namespace o2::quality_control_modules::common diff --git a/Modules/Common/include/Common/ReferenceComparatorTask.h b/Modules/Common/include/Common/ReferenceComparatorTask.h index 195f9f27a5..57f582c458 100644 --- a/Modules/Common/include/Common/ReferenceComparatorTask.h +++ b/Modules/Common/include/Common/ReferenceComparatorTask.h @@ -19,10 +19,8 @@ #define QUALITYCONTROL_REFERENCECOMPARATORTASK_H #include "Common/ReferenceComparatorTaskConfig.h" -#include "Common/BigScreenCanvas.h" #include "QualityControl/PostProcessingInterface.h" #include "QualityControl/DatabaseInterface.h" -#include "QualityControl/Quality.h" #include #include #include @@ -63,8 +61,6 @@ class ReferenceComparatorTask : public quality_control::postprocessing::PostProc }; private: - std::shared_ptr getReferencePlot(o2::quality_control::repository::DatabaseInterface& qcdb, std::string fullPath, o2::quality_control::core::Activity activity); - int mReferenceRun{ 0 }; int mNotOlderThan{ 120 }; diff --git a/Modules/Common/src/ReferenceComparatorCheck.cxx b/Modules/Common/src/ReferenceComparatorCheck.cxx index bde10cf1a3..60c2388a37 100644 --- a/Modules/Common/src/ReferenceComparatorCheck.cxx +++ b/Modules/Common/src/ReferenceComparatorCheck.cxx @@ -15,8 +15,8 @@ /// #include "Common/ReferenceComparatorCheck.h" +#include "QualityControl/ReferenceUtils.h" #include "Common/TH1Ratio.h" -#include "Common/TH2Ratio.h" #include "QualityControl/MonitorObject.h" #include "QualityControl/Quality.h" #include "QualityControl/QcInfoLogger.h" @@ -25,6 +25,8 @@ #include #include +#include + // ROOT #include #include @@ -54,6 +56,8 @@ void ReferenceComparatorCheck::startOfActivity(const Activity& activity) if (mComparator) { mComparator->setThreshold(threshold); } + + mActivity = activity; } void ReferenceComparatorCheck::endOfActivity(const Activity& activity) @@ -129,6 +133,33 @@ static Quality compare(TCanvas* canvas, ObjectComparatorInterface* comparator, s return comparator->compare(plots.first, plots.second, message); } + +Quality ReferenceComparatorCheck::getSinglePlotQuality(std::shared_ptr mo, std::string& message) +{ + // retrieve the reference plot and compare + auto* th1 = dynamic_cast(mo->getObject()); + auto referenceRun = std::stoi(mCustomParameters.atOptional("referenceRun").value_or("0")); + + // get path of mo and ref (we have to remove the provenance) + string path = mo->getPath(); + size_t pos = path.find('/'); + if (pos != std::string::npos) { + path = path.substr(pos + 1); + } + + auto referencePlot = retrieveReference(path, referenceRun, mActivity); + if (!referencePlot) { + ILOG(Warning, Ops) << "The reference plot is empty" << ENDM; + return Quality::Null; + } + auto* ref = dynamic_cast(referencePlot->getObject()); + if (!ref) { + ILOG(Warning, Ops) << "The reference plot is not a TH1" << ENDM; + return Quality::Null; + } + return mComparator.get()->compare(th1, ref, message); +} + //_________________________________________________________________________________________ // // Loop over all the input MOs and compare each of them with the corresponding MO from the reference run @@ -139,17 +170,22 @@ Quality ReferenceComparatorCheck::check(std::mapgetName(); + Quality quality; + std::string message; - auto* canvas = dynamic_cast(mo->getObject()); - if (!canvas) { + // run the comparison algorithm + if (mo->getObject()->IsA() == TClass::GetClass()) { + // We got a canvas. It contains the plot and its reference. + auto* canvas = dynamic_cast(mo->getObject()); + quality = compare(canvas, mComparator.get(), message); + } else if (mo->getObject()->InheritsFrom(TH1::Class())) { + // We got a plot, we have to find the reference before calling the comparator + quality = getSinglePlotQuality(mo, message); + } else { + ILOG(Warning, Ops) << "mo is not a TCanvas or a TH1" << ENDM; continue; } - // run the comparison algorithm - Quality quality; - std::string message; - quality = compare(canvas, mComparator.get(), message); - // update the overall quality if (quality.isWorseThan(result)) { result.set(quality); @@ -229,23 +265,22 @@ static void setQualityLabel(TCanvas* canvas, const Quality& quality) void ReferenceComparatorCheck::beautify(std::shared_ptr mo, Quality checkResult) { - auto* canvas = dynamic_cast(mo->getObject()); - if (!canvas) { - return; - } - // get the quality associated to the current MO auto moName = mo->getName(); auto quality = mQualityFlags[moName]; - // retrieve the reference plot from the canvas and set the line color according to the quality - auto plots = getPlotsFromCanvas(canvas); - if (plots.second) { - plots.second->SetLineColor(getQualityColor(quality)); - } + auto* canvas = dynamic_cast(mo->getObject()); + if (canvas) { + // retrieve the reference plot from the canvas and set the line color according to the quality + auto plots = getPlotsFromCanvas(canvas); + if (plots.second) { + plots.second->SetLineColor(getQualityColor(quality)); + } - // draw the quality label on the plot - setQualityLabel(canvas, quality); + // draw the quality label on the plot + setQualityLabel(canvas, quality); + } + // TODO handle the case of simple MO } } // namespace o2::quality_control_modules::common diff --git a/Modules/Common/src/ReferenceComparatorTask.cxx b/Modules/Common/src/ReferenceComparatorTask.cxx index 0e21d2866c..0e937e9b84 100644 --- a/Modules/Common/src/ReferenceComparatorTask.cxx +++ b/Modules/Common/src/ReferenceComparatorTask.cxx @@ -17,8 +17,7 @@ #include "Common/ReferenceComparatorTask.h" #include "Common/ReferenceComparatorPlot.h" -#include "Common/TH1Ratio.h" -#include "Common/TH2Ratio.h" +#include "QualityControl/ReferenceUtils.h" #include "QualityControl/QcInfoLogger.h" #include "QualityControl/MonitorObject.h" #include "QualityControl/DatabaseInterface.h" @@ -26,8 +25,6 @@ // ROOT #include #include -#include -#include using namespace o2::quality_control::postprocessing; using namespace o2::quality_control::core; @@ -36,47 +33,6 @@ using namespace o2::quality_control; namespace o2::quality_control_modules::common { -static bool splitObjectPath(const std::string& fullPath, std::string& path, std::string& name) -{ - std::string delimiter = "/"; - std::string det; - size_t pos = fullPath.rfind(delimiter); - if (pos == std::string::npos) { - return false; - } - path = fullPath.substr(0, pos); - name = fullPath.substr(pos + 1); - return true; -} - -//_________________________________________________________________________________________ -// -// Helper function for retrieving the last MonitorObject for a give run number - -static std::shared_ptr getMOFromRun(repository::DatabaseInterface* qcdb, const std::string& fullPath, uint32_t run, Activity activity) -{ - uint64_t timeStamp = 0; - activity.mId = run; - const auto filterMetadata = activity_helpers::asDatabaseMetadata(activity, false); - const auto objectValidity = qcdb->getLatestObjectValidity(activity.mProvenance + "/" + fullPath, filterMetadata); - if (objectValidity.isValid()) { - timeStamp = objectValidity.getMax() - 1; - } else { - ILOG(Warning, Devel) << "Could not find the object '" << fullPath << "' for run " << activity.mId << ENDM; - return nullptr; - } - - std::string path; - std::string name; - if (!splitObjectPath(fullPath, path, name)) { - return nullptr; - } - // retrieve MO from CCDB - auto mo = qcdb->retrieveMO(path, name, timeStamp, activity); - - return mo; -} - //_________________________________________________________________________________________ // Helper function for retrieving a MonitorObject from the QCDB, in the form of a std::pair, bool> // A non-null MO is returned in the first element of the pair if the MO is found in the QCDB @@ -98,7 +54,7 @@ static std::pair, bool> getMO(repository::Databas std::string path; std::string name; - if (!splitObjectPath(fullPath, path, name)) { + if (!o2::quality_control::core::RepoPathUtils::splitObjectPath(fullPath, path, name)) { return { nullptr, false }; } // retrieve QO from CCDB - do not associate to trigger activity if ignoreActivity is true @@ -117,15 +73,6 @@ static std::pair, bool> getMO(repository::Databas return { qo, true }; } -//_________________________________________________________________________________________ -// -// Get the reference plot for a given MonitorObject path - -std::shared_ptr ReferenceComparatorTask::getReferencePlot(repository::DatabaseInterface& qcdb, std::string fullPath, Activity activity) -{ - return getMOFromRun(&qcdb, fullPath, mReferenceRun, activity); -} - //_________________________________________________________________________________________ void ReferenceComparatorTask::configure(const boost::property_tree::ptree& config) @@ -156,7 +103,7 @@ void ReferenceComparatorTask::initialize(quality_control::postprocessing::Trigge auto fullOutPath = group.outputPath + "/" + path; // retrieve the reference MO - auto referencePlot = getReferencePlot(qcdb, fullRefPath, t.activity); + auto referencePlot = getReferencePlot(&qcdb, fullRefPath, mReferenceRun, t.activity); if (!referencePlot) { continue; } diff --git a/doc/Advanced.md b/doc/Advanced.md index c9db65140d..2d396d147a 100644 --- a/doc/Advanced.md +++ b/doc/Advanced.md @@ -1308,6 +1308,12 @@ void customize(std::vector& workflowOptions) } ``` +## Reference data +TODO +- PP task -> pointer +- Checker -> if PP -> pointer +- Checker on TH1 -> describe here + ## Configuration files details The QC requires a number of configuration items. An example config file is From 603a00c1c07c11b1e81baacb1f3a4878ecd0c8c8 Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Wed, 26 Jun 2024 11:26:19 +0200 Subject: [PATCH 02/25] format --- Framework/include/QualityControl/Check.h | 3 ++- Framework/include/QualityControl/CheckInterface.h | 3 ++- Modules/Common/src/ReferenceComparatorCheck.cxx | 1 - doc/DevelopersTips.md | 4 ++++ 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Framework/include/QualityControl/Check.h b/Framework/include/QualityControl/Check.h index a1376e94fc..2d9b969c29 100644 --- a/Framework/include/QualityControl/Check.h +++ b/Framework/include/QualityControl/Check.h @@ -94,7 +94,8 @@ class Check static CheckConfig extractConfig(const core::CommonSpec&, const CheckSpec&); static framework::OutputSpec createOutputSpec(const std::string& detector, const std::string& checkName); - void setDatabase(std::shared_ptr database) { + void setDatabase(std::shared_ptr database) + { mCheckInterface->setDatabase(database); } diff --git a/Framework/include/QualityControl/CheckInterface.h b/Framework/include/QualityControl/CheckInterface.h index e3f8a47657..394d9488c9 100644 --- a/Framework/include/QualityControl/CheckInterface.h +++ b/Framework/include/QualityControl/CheckInterface.h @@ -83,7 +83,8 @@ class CheckInterface : public core::UserCodeInterface virtual void startOfActivity(const core::Activity& activity); // not fully abstract because we don't want to change all the existing subclasses virtual void endOfActivity(const core::Activity& activity); // not fully abstract because we don't want to change all the existing subclasses - void setDatabase(std::shared_ptr database) { + void setDatabase(std::shared_ptr database) + { mDatabase = database; } diff --git a/Modules/Common/src/ReferenceComparatorCheck.cxx b/Modules/Common/src/ReferenceComparatorCheck.cxx index 60c2388a37..038aef6ca6 100644 --- a/Modules/Common/src/ReferenceComparatorCheck.cxx +++ b/Modules/Common/src/ReferenceComparatorCheck.cxx @@ -133,7 +133,6 @@ static Quality compare(TCanvas* canvas, ObjectComparatorInterface* comparator, s return comparator->compare(plots.first, plots.second, message); } - Quality ReferenceComparatorCheck::getSinglePlotQuality(std::shared_ptr mo, std::string& message) { // retrieve the reference plot and compare diff --git a/doc/DevelopersTips.md b/doc/DevelopersTips.md index 6fd8b8f4f0..9bbc281887 100644 --- a/doc/DevelopersTips.md +++ b/doc/DevelopersTips.md @@ -143,6 +143,10 @@ firewall-cmd --reload 10. Set the monitoring url to `"url": "stdout://?qc,influxdb-udp://flptest1.cern.ch:8089"` 11. Once the dashboard is ready, tell Adam. +ALTERNATIVELY + +use http://alio2-bld4-mx-dev01-gpn:3000/?orgId=1 (admin and pwd like above) + ### Monitoring setup for building the grafana dashboard with prod data 1. Go to http://pcald24.cern.ch:3000/?orgId=1 From 626e7c400441cc0187832df11d89ea5d1c5e2b87 Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Wed, 26 Jun 2024 12:22:01 +0200 Subject: [PATCH 03/25] add beautify and doc --- .../include/QualityControl/ReferenceUtils.h | 5 +- .../include/Common/ReferenceComparatorTask.h | 1 - doc/Advanced.md | 71 +++++++++++++++++-- 3 files changed, 68 insertions(+), 9 deletions(-) diff --git a/Framework/include/QualityControl/ReferenceUtils.h b/Framework/include/QualityControl/ReferenceUtils.h index 304d8edcde..2f096ac9b3 100644 --- a/Framework/include/QualityControl/ReferenceUtils.h +++ b/Framework/include/QualityControl/ReferenceUtils.h @@ -50,10 +50,7 @@ static std::shared_ptr getReferencePlot(qu if (!o2::quality_control::core::RepoPathUtils::splitObjectPath(fullPath, path, name)) { return nullptr; } - // retrieve MO from CCDB - auto mo = qcdb->retrieveMO(path, name, timeStamp, activity); - - return mo; + return qcdb->retrieveMO(path, name, timeStamp, activity); } } // namespace o2::quality_control_modules::common diff --git a/Modules/Common/include/Common/ReferenceComparatorTask.h b/Modules/Common/include/Common/ReferenceComparatorTask.h index 57f582c458..5990f50fec 100644 --- a/Modules/Common/include/Common/ReferenceComparatorTask.h +++ b/Modules/Common/include/Common/ReferenceComparatorTask.h @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/doc/Advanced.md b/doc/Advanced.md index 2d396d147a..d0f0ef9add 100644 --- a/doc/Advanced.md +++ b/doc/Advanced.md @@ -1309,10 +1309,73 @@ void customize(std::vector& workflowOptions) ``` ## Reference data -TODO -- PP task -> pointer -- Checker -> if PP -> pointer -- Checker on TH1 -> describe here + +A reference object is an object from a previous run. It is usually used as a point of comparison. + +### Get a reference plot + +To retrieve a reference plot in your Check, use +``` + std::shared_ptr retrieveReference(std::string path, int referenceRun, Activity activity); +``` +- `path` : the path of the object _without the provenance (e.g. `qc`) +- `referenceRun` : the run of reference +- `activity` : the current activity + +If the reference is not found it will return a `nullptr` and issue a warning. + +### Compare to a reference plot + +The check `ReferenceComparatorCheck` in `Common` compares objects to their reference. + +TODO beautify + +The configuration looks like +``` + "QcCheck": { + "active": "true", + "className": "o2::quality_control_modules::common::ReferenceComparatorCheck", + "moduleName": "QcCommon", + "policy": "OnAny", + "detectorName": "TST", + "dataSource": [{ + "type": "Task", + "name": "QcTask", + "MOs": ["example"] + }], + "extendedCheckParameters": { + "default": { + "default": { + "referenceRun" : "500", + "moduleName" : "QualityControl", + "comparatorName" : "o2::quality_control_modules::common::ObjectComparatorChi2", + "threshold" : "0.5" + } + }, + "PHYSICS": { + "PROTON-PROTON": { + "referenceRun" : "551890" + } + } + } + } +``` +The check needs the following parameters +- `referenceRun` to specify what is the run of reference and retrieve the reference data. +- `comparatorName` to decide how to compare, see below for their descriptions. +- `threshold` to specifie the value used to discriminate between good and bad matches between the histograms. + +Three comparator are provided: +1. `o2::quality_control_modules::common::ObjectComparatorDeviation`: comparison based on the average relative deviation between the bins of the current and reference histograms; the `threshold` parameter represent in this case the maximum allowed deviation +2. `o2::quality_control_modules::common::ObjectComparatorChi2`: comparison based on a standard chi2 test between the current and reference histograms; the `threshold` parameter represent in this case the minimum allowed chi2 probability +3. `o2::quality_control_modules::common::ObjectComparatorKolmogorov`: comparison based on a standard Kolmogorov test between the current and reference histograms; the `threshold` parameter represent in this case the minimum allowed Kolmogorov probability + +Note that you can easily specify different reference runs for different run types and beam types. + +### Generate a canvas combining both the current and reference ratio histogram + +The postprocessing task ReferenceComparatorTask draws a given set of plots in comparison with their corresponding references, both as superimposed histograms and as current/reference ratio histograms. +See the details [here](https://github.com/AliceO2Group/QualityControl/blob/master/doc/PostProcessing.md#the-referencecomparatortask-class). ## Configuration files details From d23cfcd9e58feb4836d72f61b10896bd9826ad4e Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Wed, 26 Jun 2024 12:22:25 +0200 Subject: [PATCH 04/25] Format --- .../Common/src/ReferenceComparatorCheck.cxx | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/Modules/Common/src/ReferenceComparatorCheck.cxx b/Modules/Common/src/ReferenceComparatorCheck.cxx index 038aef6ca6..4b5edda813 100644 --- a/Modules/Common/src/ReferenceComparatorCheck.cxx +++ b/Modules/Common/src/ReferenceComparatorCheck.cxx @@ -148,12 +148,12 @@ Quality ReferenceComparatorCheck::getSinglePlotQuality(std::shared_ptr(referencePlot->getObject()); if (!ref) { - ILOG(Warning, Ops) << "The reference plot is not a TH1" << ENDM; + message = "The reference plot is not a TH1"; return Quality::Null; } return mComparator.get()->compare(th1, ref, message); @@ -226,6 +226,23 @@ static int getQualityColor(const Quality& q) return 0; } +static void updateQualityLabel(TPaveText* label, const Quality& quality) +{ + // draw the quality label with the text color corresponding to the quality level + label->SetTextColor(getQualityColor(quality)); + label->AddText(quality.getName().c_str()); + + // add the first flag below the quality label, or an empty line if no flags are set + auto flags = quality.getFlags(); + std::string message = flags.empty() ? "" : flags.front().second; + auto pos = message.find(" "); + if (pos != std::string::npos) { + message.erase(0, pos + 1); + } + auto* text = label->AddText(message.c_str()); + text->SetTextColor(kGray + 1); +} + // Write the quality level and flags in the existing PaveText inside the canvas static void setQualityLabel(TCanvas* canvas, const Quality& quality) { @@ -244,26 +261,14 @@ static void setQualityLabel(TCanvas* canvas, const Quality& quality) continue; } - // draw the quality label with the text color corresponding to the quality level - label->SetTextColor(getQualityColor(quality)); - label->AddText(quality.getName().c_str()); - - // add the first flag below the quality label, or an empty line if no flags are set - auto flags = quality.getFlags(); - std::string message = flags.empty() ? "" : flags.front().second; - auto pos = message.find(" "); - if (pos != std::string::npos) { - message.erase(0, pos + 1); - } - auto* text = label->AddText(message.c_str()); - text->SetTextColor(kGray + 1); - + updateQualityLabel(label, quality); break; } } void ReferenceComparatorCheck::beautify(std::shared_ptr mo, Quality checkResult) { + std::cout << "beautify" << std::endl; // get the quality associated to the current MO auto moName = mo->getName(); auto quality = mQualityFlags[moName]; @@ -279,7 +284,13 @@ void ReferenceComparatorCheck::beautify(std::shared_ptr mo, Quali // draw the quality label on the plot setQualityLabel(canvas, quality); } - // TODO handle the case of simple MO + auto* th1 = dynamic_cast(mo->getObject()); + std::cout << "th1 : " << th1 << std::endl; + if(th1) { + auto* qualityLabel = new TPaveText(0.75, 0.65, 0.98, 0.75, "brNDC"); + updateQualityLabel(qualityLabel, quality); + th1->GetListOfFunctions()->Add(qualityLabel); + } } } // namespace o2::quality_control_modules::common From 714a48620e4e7fbd65e39b7076878046ad175024 Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Wed, 26 Jun 2024 15:16:18 +0200 Subject: [PATCH 05/25] Format --- Modules/Common/src/ReferenceComparatorCheck.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Common/src/ReferenceComparatorCheck.cxx b/Modules/Common/src/ReferenceComparatorCheck.cxx index 4b5edda813..9609d59481 100644 --- a/Modules/Common/src/ReferenceComparatorCheck.cxx +++ b/Modules/Common/src/ReferenceComparatorCheck.cxx @@ -286,7 +286,7 @@ void ReferenceComparatorCheck::beautify(std::shared_ptr mo, Quali } auto* th1 = dynamic_cast(mo->getObject()); std::cout << "th1 : " << th1 << std::endl; - if(th1) { + if (th1) { auto* qualityLabel = new TPaveText(0.75, 0.65, 0.98, 0.75, "brNDC"); updateQualityLabel(qualityLabel, quality); th1->GetListOfFunctions()->Add(qualityLabel); From 466a984790dbc5c66d8eb7813fc277be83d2965e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9l=C3=A9my=20von=20Haller?= Date: Wed, 26 Jun 2024 15:45:36 +0200 Subject: [PATCH 06/25] cout --- Modules/Common/src/ReferenceComparatorCheck.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/Common/src/ReferenceComparatorCheck.cxx b/Modules/Common/src/ReferenceComparatorCheck.cxx index 9609d59481..7c8403598b 100644 --- a/Modules/Common/src/ReferenceComparatorCheck.cxx +++ b/Modules/Common/src/ReferenceComparatorCheck.cxx @@ -268,7 +268,6 @@ static void setQualityLabel(TCanvas* canvas, const Quality& quality) void ReferenceComparatorCheck::beautify(std::shared_ptr mo, Quality checkResult) { - std::cout << "beautify" << std::endl; // get the quality associated to the current MO auto moName = mo->getName(); auto quality = mQualityFlags[moName]; From a1ad04444617e0c92e1473e4be901763e6afd8ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9l=C3=A9my=20von=20Haller?= Date: Wed, 26 Jun 2024 15:46:07 +0200 Subject: [PATCH 07/25] Update ReferenceComparatorCheck.cxx --- Modules/Common/src/ReferenceComparatorCheck.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/Common/src/ReferenceComparatorCheck.cxx b/Modules/Common/src/ReferenceComparatorCheck.cxx index 7c8403598b..c1ab102789 100644 --- a/Modules/Common/src/ReferenceComparatorCheck.cxx +++ b/Modules/Common/src/ReferenceComparatorCheck.cxx @@ -284,7 +284,6 @@ void ReferenceComparatorCheck::beautify(std::shared_ptr mo, Quali setQualityLabel(canvas, quality); } auto* th1 = dynamic_cast(mo->getObject()); - std::cout << "th1 : " << th1 << std::endl; if (th1) { auto* qualityLabel = new TPaveText(0.75, 0.65, 0.98, 0.75, "brNDC"); updateQualityLabel(qualityLabel, quality); From 4755f09a329a575aafe3129c4e7c12e9c30b1121 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9l=C3=A9my=20von=20Haller?= Date: Wed, 26 Jun 2024 15:46:59 +0200 Subject: [PATCH 08/25] Update Advanced.md --- doc/Advanced.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/Advanced.md b/doc/Advanced.md index d0f0ef9add..9ae8282b35 100644 --- a/doc/Advanced.md +++ b/doc/Advanced.md @@ -1312,13 +1312,13 @@ void customize(std::vector& workflowOptions) A reference object is an object from a previous run. It is usually used as a point of comparison. -### Get a reference plot +### Get a reference plot in a check To retrieve a reference plot in your Check, use ``` std::shared_ptr retrieveReference(std::string path, int referenceRun, Activity activity); ``` -- `path` : the path of the object _without the provenance (e.g. `qc`) +- `path` : the path of the object _without the provenance (e.g. `qc`)_ - `referenceRun` : the run of reference - `activity` : the current activity From d6cb6e1f4b7e8fa805c8819770de0b696c656145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9l=C3=A9my=20von=20Haller?= Date: Wed, 26 Jun 2024 15:48:29 +0200 Subject: [PATCH 09/25] Update Advanced.md --- doc/Advanced.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/Advanced.md b/doc/Advanced.md index 9ae8282b35..ae39a88e7f 100644 --- a/doc/Advanced.md +++ b/doc/Advanced.md @@ -1322,14 +1322,12 @@ To retrieve a reference plot in your Check, use - `referenceRun` : the run of reference - `activity` : the current activity -If the reference is not found it will return a `nullptr` and issue a warning. +If the reference is not found it will return a `nullptr` and the quality is `Null`. ### Compare to a reference plot The check `ReferenceComparatorCheck` in `Common` compares objects to their reference. -TODO beautify - The configuration looks like ``` "QcCheck": { @@ -1372,6 +1370,8 @@ Three comparator are provided: Note that you can easily specify different reference runs for different run types and beam types. +The plot is beautified by the addition of a `TPaveText` containing the quality and the reason for the quality. + ### Generate a canvas combining both the current and reference ratio histogram The postprocessing task ReferenceComparatorTask draws a given set of plots in comparison with their corresponding references, both as superimposed histograms and as current/reference ratio histograms. From 6f9e9ef4217e726ded84e7bafe31cdac313abe2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9l=C3=A9my=20von=20Haller?= Date: Wed, 26 Jun 2024 15:50:40 +0200 Subject: [PATCH 10/25] Update DevelopersTips.md --- doc/DevelopersTips.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/doc/DevelopersTips.md b/doc/DevelopersTips.md index 9bbc281887..6fd8b8f4f0 100644 --- a/doc/DevelopersTips.md +++ b/doc/DevelopersTips.md @@ -143,10 +143,6 @@ firewall-cmd --reload 10. Set the monitoring url to `"url": "stdout://?qc,influxdb-udp://flptest1.cern.ch:8089"` 11. Once the dashboard is ready, tell Adam. -ALTERNATIVELY - -use http://alio2-bld4-mx-dev01-gpn:3000/?orgId=1 (admin and pwd like above) - ### Monitoring setup for building the grafana dashboard with prod data 1. Go to http://pcald24.cern.ch:3000/?orgId=1 From 142565fd75fcb873905039220d6b5dd8e6052e93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9l=C3=A9my=20von=20Haller?= Date: Mon, 1 Jul 2024 13:27:35 +0200 Subject: [PATCH 11/25] Update Framework/include/QualityControl/ReferenceUtils.h Co-authored-by: Piotr Konopka --- Framework/include/QualityControl/ReferenceUtils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/include/QualityControl/ReferenceUtils.h b/Framework/include/QualityControl/ReferenceUtils.h index 2f096ac9b3..67b476124a 100644 --- a/Framework/include/QualityControl/ReferenceUtils.h +++ b/Framework/include/QualityControl/ReferenceUtils.h @@ -25,7 +25,7 @@ #include "QualityControl/QcInfoLogger.h" #include "QualityControl/RepoPathUtils.h" -namespace o2::quality_control_modules::common +namespace o2::quality_control::checker { //_________________________________________________________________________________________ From 71e7460315d43b189fbf689a6028a2b4464e05d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9l=C3=A9my=20von=20Haller?= Date: Mon, 1 Jul 2024 13:28:29 +0200 Subject: [PATCH 12/25] Update Modules/Common/src/ReferenceComparatorCheck.cxx Co-authored-by: Piotr Konopka --- Modules/Common/src/ReferenceComparatorCheck.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Common/src/ReferenceComparatorCheck.cxx b/Modules/Common/src/ReferenceComparatorCheck.cxx index c1ab102789..de6496b72a 100644 --- a/Modules/Common/src/ReferenceComparatorCheck.cxx +++ b/Modules/Common/src/ReferenceComparatorCheck.cxx @@ -181,7 +181,7 @@ Quality ReferenceComparatorCheck::check(std::mapgetName() << "' is not a TCanvas or a TH1, the detector QC responsible should review the configuration" << ENDM; continue; } From 591aa8651c97670e7288ae43ce8b79ca93d8aac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9l=C3=A9my=20von=20Haller?= Date: Mon, 1 Jul 2024 13:28:44 +0200 Subject: [PATCH 13/25] Update doc/Advanced.md Co-authored-by: Piotr Konopka --- doc/Advanced.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Advanced.md b/doc/Advanced.md index 1f2a773f45..65545bc6c4 100644 --- a/doc/Advanced.md +++ b/doc/Advanced.md @@ -1453,7 +1453,7 @@ The check needs the following parameters - `comparatorName` to decide how to compare, see below for their descriptions. - `threshold` to specifie the value used to discriminate between good and bad matches between the histograms. -Three comparator are provided: +Three comparators are provided: 1. `o2::quality_control_modules::common::ObjectComparatorDeviation`: comparison based on the average relative deviation between the bins of the current and reference histograms; the `threshold` parameter represent in this case the maximum allowed deviation 2. `o2::quality_control_modules::common::ObjectComparatorChi2`: comparison based on a standard chi2 test between the current and reference histograms; the `threshold` parameter represent in this case the minimum allowed chi2 probability 3. `o2::quality_control_modules::common::ObjectComparatorKolmogorov`: comparison based on a standard Kolmogorov test between the current and reference histograms; the `threshold` parameter represent in this case the minimum allowed Kolmogorov probability From 55237985286affd9044669fdf2677861f2b5bb06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9l=C3=A9my=20von=20Haller?= Date: Mon, 1 Jul 2024 13:29:28 +0200 Subject: [PATCH 14/25] Update doc/Advanced.md Co-authored-by: Piotr Konopka --- doc/Advanced.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Advanced.md b/doc/Advanced.md index 65545bc6c4..7009f5ee07 100644 --- a/doc/Advanced.md +++ b/doc/Advanced.md @@ -1406,7 +1406,7 @@ A reference object is an object from a previous run. It is usually used as a poi To retrieve a reference plot in your Check, use ``` - std::shared_ptr retrieveReference(std::string path, int referenceRun, Activity activity); + std::shared_ptr CheckInterface::retrieveReference(std::string path, int referenceRun, Activity activity); ``` - `path` : the path of the object _without the provenance (e.g. `qc`)_ - `referenceRun` : the run of reference From 81a00d1380945acbe92b8146363ac1b033bce75e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9l=C3=A9my=20von=20Haller?= Date: Mon, 1 Jul 2024 13:38:58 +0200 Subject: [PATCH 15/25] Update ReferenceComparatorCheck.cxx --- Modules/Common/src/ReferenceComparatorCheck.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Modules/Common/src/ReferenceComparatorCheck.cxx b/Modules/Common/src/ReferenceComparatorCheck.cxx index de6496b72a..47c757474b 100644 --- a/Modules/Common/src/ReferenceComparatorCheck.cxx +++ b/Modules/Common/src/ReferenceComparatorCheck.cxx @@ -137,6 +137,10 @@ Quality ReferenceComparatorCheck::getSinglePlotQuality(std::shared_ptr(mo->getObject()); + if (th1 == nullptr) { + message = "The MonitorObject is not a TH1"; + return Quality::Null; + } auto referenceRun = std::stoi(mCustomParameters.atOptional("referenceRun").value_or("0")); // get path of mo and ref (we have to remove the provenance) From 5262cce5043e2308114ad4a34446597eba557af3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9l=C3=A9my=20von=20Haller?= Date: Mon, 1 Jul 2024 13:40:45 +0200 Subject: [PATCH 16/25] Update ReferenceComparatorCheck.cxx --- Modules/Common/src/ReferenceComparatorCheck.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/Common/src/ReferenceComparatorCheck.cxx b/Modules/Common/src/ReferenceComparatorCheck.cxx index 47c757474b..990ea46b9c 100644 --- a/Modules/Common/src/ReferenceComparatorCheck.cxx +++ b/Modules/Common/src/ReferenceComparatorCheck.cxx @@ -27,6 +27,8 @@ #include +#include + // ROOT #include #include From ee3757177a087b3f374626244d01babb8ea90547 Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Mon, 1 Jul 2024 13:50:48 +0200 Subject: [PATCH 17/25] - use int for the run - update the namespaces --- Framework/include/QualityControl/ReferenceUtils.h | 2 +- Framework/src/CheckInterface.cxx | 2 +- Modules/Common/src/ReferenceComparatorTask.cxx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Framework/include/QualityControl/ReferenceUtils.h b/Framework/include/QualityControl/ReferenceUtils.h index 67b476124a..9e580b1528 100644 --- a/Framework/include/QualityControl/ReferenceUtils.h +++ b/Framework/include/QualityControl/ReferenceUtils.h @@ -32,7 +32,7 @@ namespace o2::quality_control::checker // // Get the reference plot for a given MonitorObject path -static std::shared_ptr getReferencePlot(quality_control::repository::DatabaseInterface* qcdb, std::string& fullPath, uint32_t referenceRun, quality_control::core::Activity activity) +static std::shared_ptr getReferencePlot(quality_control::repository::DatabaseInterface* qcdb, std::string& fullPath, int referenceRun, quality_control::core::Activity activity) { uint64_t timeStamp = 0; activity.mId = referenceRun; diff --git a/Framework/src/CheckInterface.cxx b/Framework/src/CheckInterface.cxx index bdc7c0cf5f..aa6b11eba7 100644 --- a/Framework/src/CheckInterface.cxx +++ b/Framework/src/CheckInterface.cxx @@ -62,7 +62,7 @@ void CheckInterface::endOfActivity(const Activity& activity) shared_ptr CheckInterface::retrieveReference(std::string path, int referenceRun, Activity activity) { - return quality_control_modules::common::getReferencePlot(mDatabase.get(), path, referenceRun, activity); + return o2::quality_control::checker::getReferencePlot(mDatabase.get(), path, referenceRun, activity); } } // namespace o2::quality_control::checker diff --git a/Modules/Common/src/ReferenceComparatorTask.cxx b/Modules/Common/src/ReferenceComparatorTask.cxx index 537bca0500..527070c503 100644 --- a/Modules/Common/src/ReferenceComparatorTask.cxx +++ b/Modules/Common/src/ReferenceComparatorTask.cxx @@ -120,7 +120,7 @@ void ReferenceComparatorTask::initialize(quality_control::postprocessing::Trigge auto fullOutPath = group.outputPath + "/" + path; // retrieve the reference MO - auto referencePlot = getReferencePlot(&qcdb, fullRefPath, mReferenceRun, trigger.activity); + auto referencePlot = o2::quality_control::checker::getReferencePlot(&qcdb, fullRefPath, mReferenceRun, trigger.activity); if (!referencePlot) { continue; } From 3c62749822a7a0c60dc6c2312c2e82d32c0a900c Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Mon, 1 Jul 2024 13:53:26 +0200 Subject: [PATCH 18/25] format --- Framework/include/QualityControl/ReferenceUtils.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Framework/include/QualityControl/ReferenceUtils.h b/Framework/include/QualityControl/ReferenceUtils.h index 9e580b1528..19697ce650 100644 --- a/Framework/include/QualityControl/ReferenceUtils.h +++ b/Framework/include/QualityControl/ReferenceUtils.h @@ -14,8 +14,8 @@ /// \author Andrea Ferrero and Barthelemy von Haller /// -#ifndef QUALITYCONTROL_ReferenceComparatorUtils_H -#define QUALITYCONTROL_ReferenceComparatorUtils_H +#ifndef QUALITYCONTROL_ReferenceUtils_H +#define QUALITYCONTROL_ReferenceUtils_H #include #include "QualityControl/MonitorObject.h" @@ -53,6 +53,6 @@ static std::shared_ptr getReferencePlot(qu return qcdb->retrieveMO(path, name, timeStamp, activity); } -} // namespace o2::quality_control_modules::common +} // namespace o2::quality_control::checker -#endif // QUALITYCONTROL_ReferenceComparatorUtils_H +#endif // QUALITYCONTROL_ReferenceUtils_H From da08db6a3053d6f9f73099c1d699c55825b20705 Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Mon, 1 Jul 2024 14:38:45 +0200 Subject: [PATCH 19/25] return a tuple --- .../include/QualityControl/ReferenceUtils.h | 8 ++++---- .../include/QualityControl/RepoPathUtils.h | 17 ++++++++++++----- Modules/Common/src/ReferenceComparatorTask.cxx | 5 ++--- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/Framework/include/QualityControl/ReferenceUtils.h b/Framework/include/QualityControl/ReferenceUtils.h index 19697ce650..97fc86f0bd 100644 --- a/Framework/include/QualityControl/ReferenceUtils.h +++ b/Framework/include/QualityControl/ReferenceUtils.h @@ -32,7 +32,8 @@ namespace o2::quality_control::checker // // Get the reference plot for a given MonitorObject path -static std::shared_ptr getReferencePlot(quality_control::repository::DatabaseInterface* qcdb, std::string& fullPath, int referenceRun, quality_control::core::Activity activity) +static std::shared_ptr getReferencePlot(quality_control::repository::DatabaseInterface* qcdb, std::string& fullPath, + int referenceRun, quality_control::core::Activity activity) { uint64_t timeStamp = 0; activity.mId = referenceRun; @@ -45,9 +46,8 @@ static std::shared_ptr getReferencePlot(qu return nullptr; } - std::string path; - std::string name; - if (!o2::quality_control::core::RepoPathUtils::splitObjectPath(fullPath, path, name)) { + auto [success, path, name] = o2::quality_control::core::RepoPathUtils::splitObjectPath(fullPath); + if (!success) { return nullptr; } return qcdb->retrieveMO(path, name, timeStamp, activity); diff --git a/Framework/include/QualityControl/RepoPathUtils.h b/Framework/include/QualityControl/RepoPathUtils.h index af3a627577..389ea0da75 100644 --- a/Framework/include/QualityControl/RepoPathUtils.h +++ b/Framework/include/QualityControl/RepoPathUtils.h @@ -129,17 +129,24 @@ class RepoPathUtils static constexpr auto allowedProvenancesMessage = R"(Allowed provenances are "qc" (real data processed synchronously), "qc_async" (real data processed asynchronously) and "qc_mc" (simulated data).)"; static bool isProvenanceAllowed(const std::string& provenance); - static bool splitObjectPath(const std::string& fullPath, std::string& path, std::string& name) + /** + * Splits the provided path and returns both the base path and the object name. + * @param fullPath + * @return A tuple with 1. a boolean to specify if we succeeded (i.e. whether we found a `/`) + * 2. the path + * 3. the object name + */ + static std::tuple splitObjectPath(const std::string& fullPath) { std::string delimiter = "/"; std::string det; size_t pos = fullPath.rfind(delimiter); if (pos == std::string::npos) { - return false; + return {false, "", ""}; } - path = fullPath.substr(0, pos); - name = fullPath.substr(pos + 1); - return true; + std::string path = fullPath.substr(0, pos); + std::string name = fullPath.substr(pos + 1); + return {true, path, name}; } }; } // namespace o2::quality_control::core diff --git a/Modules/Common/src/ReferenceComparatorTask.cxx b/Modules/Common/src/ReferenceComparatorTask.cxx index 527070c503..9f63668240 100644 --- a/Modules/Common/src/ReferenceComparatorTask.cxx +++ b/Modules/Common/src/ReferenceComparatorTask.cxx @@ -52,9 +52,8 @@ static std::pair, bool> getMO(repository::Databas return { nullptr, false }; } - std::string path; - std::string name; - if (!o2::quality_control::core::RepoPathUtils::splitObjectPath(fullPath, path, name)) { + auto [success, path, name] = o2::quality_control::core::RepoPathUtils::splitObjectPath(fullPath); + if (!success) { return { nullptr, false }; } // retrieve QO from CCDB - do not associate to trigger activity if ignoreActivity is true From 1ffb5edb85068fd813f58910699deb38723e717b Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Tue, 2 Jul 2024 08:31:36 +0200 Subject: [PATCH 20/25] format --- Framework/include/QualityControl/RepoPathUtils.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Framework/include/QualityControl/RepoPathUtils.h b/Framework/include/QualityControl/RepoPathUtils.h index 389ea0da75..0dce4ce014 100644 --- a/Framework/include/QualityControl/RepoPathUtils.h +++ b/Framework/include/QualityControl/RepoPathUtils.h @@ -142,11 +142,11 @@ class RepoPathUtils std::string det; size_t pos = fullPath.rfind(delimiter); if (pos == std::string::npos) { - return {false, "", ""}; + return { false, "", "" }; } std::string path = fullPath.substr(0, pos); std::string name = fullPath.substr(pos + 1); - return {true, path, name}; + return { true, path, name }; } }; } // namespace o2::quality_control::core From f84803a8c8c0bd65ee39c82985e73bad944ef5d6 Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Wed, 3 Jul 2024 09:10:56 +0200 Subject: [PATCH 21/25] return null quality if no reference run number is provided. --- Modules/Common/src/ReferenceComparatorCheck.cxx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Modules/Common/src/ReferenceComparatorCheck.cxx b/Modules/Common/src/ReferenceComparatorCheck.cxx index 990ea46b9c..d08af0ce8e 100644 --- a/Modules/Common/src/ReferenceComparatorCheck.cxx +++ b/Modules/Common/src/ReferenceComparatorCheck.cxx @@ -143,7 +143,11 @@ Quality ReferenceComparatorCheck::getSinglePlotQuality(std::shared_ptrgetPath(); @@ -154,7 +158,7 @@ Quality ReferenceComparatorCheck::getSinglePlotQuality(std::shared_ptr(referencePlot->getObject()); From 3da59955c6e9bbc1e271cb1dd93bf68fcd3bdbc1 Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Wed, 3 Jul 2024 10:49:56 +0200 Subject: [PATCH 22/25] extraction --- Framework/include/QualityControl/RepoPathUtils.h | 10 ++++++++++ Modules/Common/src/ReferenceComparatorCheck.cxx | 6 +----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Framework/include/QualityControl/RepoPathUtils.h b/Framework/include/QualityControl/RepoPathUtils.h index 0dce4ce014..bc3445bd8c 100644 --- a/Framework/include/QualityControl/RepoPathUtils.h +++ b/Framework/include/QualityControl/RepoPathUtils.h @@ -148,6 +148,16 @@ class RepoPathUtils std::string name = fullPath.substr(pos + 1); return { true, path, name }; } + + static std::string getPathNoProvenance(std::shared_ptr mo) + { + std::string path = mo->getPath(); + size_t pos = path.find('/'); + if (pos != std::string::npos) { + path = path.substr(pos + 1); + } + return path; + } }; } // namespace o2::quality_control::core diff --git a/Modules/Common/src/ReferenceComparatorCheck.cxx b/Modules/Common/src/ReferenceComparatorCheck.cxx index d08af0ce8e..4f651fa890 100644 --- a/Modules/Common/src/ReferenceComparatorCheck.cxx +++ b/Modules/Common/src/ReferenceComparatorCheck.cxx @@ -150,11 +150,7 @@ Quality ReferenceComparatorCheck::getSinglePlotQuality(std::shared_ptrgetPath(); - size_t pos = path.find('/'); - if (pos != std::string::npos) { - path = path.substr(pos + 1); - } + std::string path = RepoPathUtils::getPathNoProvenance(mo); auto referencePlot = retrieveReference(path, referenceRun, mActivity); if (!referencePlot) { From da17738a23eee6ddedf882ddfc236226673b4826 Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Fri, 5 Jul 2024 09:02:13 +0200 Subject: [PATCH 23/25] - Keep the activity parameter but document it - use size_t for the run number - use Timestamp::Latest --- Framework/include/QualityControl/CheckInterface.h | 7 ++++++- Framework/include/QualityControl/ReferenceUtils.h | 15 ++------------- Framework/src/CheckInterface.cxx | 2 +- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/Framework/include/QualityControl/CheckInterface.h b/Framework/include/QualityControl/CheckInterface.h index 394d9488c9..45d2884336 100644 --- a/Framework/include/QualityControl/CheckInterface.h +++ b/Framework/include/QualityControl/CheckInterface.h @@ -94,7 +94,12 @@ class CheckInterface : public core::UserCodeInterface /// \brief Retrieve a reference plot at the provided path, matching the give activity and for the provided run. /// the activity is the current one, while the run number is the reference run. - std::shared_ptr retrieveReference(std::string path, int referenceRun, Activity activity); + /// + /// \param path path to the object (no provenance) + /// \param referenceRun Run number of the reference data + /// \param activity Current activity (necessary for the provenance and the pass) + /// \return + std::shared_ptr retrieveReference(std::string path, size_t referenceRun, Activity activity); private: std::shared_ptr mDatabase; diff --git a/Framework/include/QualityControl/ReferenceUtils.h b/Framework/include/QualityControl/ReferenceUtils.h index 97fc86f0bd..155b077841 100644 --- a/Framework/include/QualityControl/ReferenceUtils.h +++ b/Framework/include/QualityControl/ReferenceUtils.h @@ -33,24 +33,13 @@ namespace o2::quality_control::checker // Get the reference plot for a given MonitorObject path static std::shared_ptr getReferencePlot(quality_control::repository::DatabaseInterface* qcdb, std::string& fullPath, - int referenceRun, quality_control::core::Activity activity) + size_t referenceRun, core::Activity activity) { - uint64_t timeStamp = 0; - activity.mId = referenceRun; - const auto filterMetadata = quality_control::core::activity_helpers::asDatabaseMetadata(activity, false); - const auto objectValidity = qcdb->getLatestObjectValidity(activity.mProvenance + "/" + fullPath, filterMetadata); - if (objectValidity.isValid()) { - timeStamp = objectValidity.getMax() - 1; - } else { - ILOG(Warning, Devel) << "Could not find the object '" << fullPath << "' for run " << activity.mId << ENDM; - return nullptr; - } - auto [success, path, name] = o2::quality_control::core::RepoPathUtils::splitObjectPath(fullPath); if (!success) { return nullptr; } - return qcdb->retrieveMO(path, name, timeStamp, activity); + return qcdb->retrieveMO(path, name, repository::DatabaseInterface::Timestamp::Latest, activity); } } // namespace o2::quality_control::checker diff --git a/Framework/src/CheckInterface.cxx b/Framework/src/CheckInterface.cxx index aa6b11eba7..a3b5d62e98 100644 --- a/Framework/src/CheckInterface.cxx +++ b/Framework/src/CheckInterface.cxx @@ -60,7 +60,7 @@ void CheckInterface::endOfActivity(const Activity& activity) // noop, override it if you want. } -shared_ptr CheckInterface::retrieveReference(std::string path, int referenceRun, Activity activity) +shared_ptr CheckInterface::retrieveReference(std::string path, size_t referenceRun, Activity activity) { return o2::quality_control::checker::getReferencePlot(mDatabase.get(), path, referenceRun, activity); } From 371a1a6341924c444989eba4941ce8000b93cf9c Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Fri, 5 Jul 2024 09:16:34 +0200 Subject: [PATCH 24/25] Use extended parameters. --- .../include/Common/ReferenceComparatorCheck.h | 1 + .../Common/src/ReferenceComparatorCheck.cxx | 22 ++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Modules/Common/include/Common/ReferenceComparatorCheck.h b/Modules/Common/include/Common/ReferenceComparatorCheck.h index 200a358d1d..78c6f953b6 100644 --- a/Modules/Common/include/Common/ReferenceComparatorCheck.h +++ b/Modules/Common/include/Common/ReferenceComparatorCheck.h @@ -55,6 +55,7 @@ class ReferenceComparatorCheck : public o2::quality_control::checker::CheckInter std::map mQualityFlags; std::map> mQualityLabels; quality_control::core::Activity mActivity; + size_t mReferenceRun; }; } // namespace o2::quality_control_modules::common diff --git a/Modules/Common/src/ReferenceComparatorCheck.cxx b/Modules/Common/src/ReferenceComparatorCheck.cxx index 4f651fa890..c239855ef4 100644 --- a/Modules/Common/src/ReferenceComparatorCheck.cxx +++ b/Modules/Common/src/ReferenceComparatorCheck.cxx @@ -46,9 +46,10 @@ void ReferenceComparatorCheck::configure() void ReferenceComparatorCheck::startOfActivity(const Activity& activity) { - auto moduleName = mCustomParameters.atOptional("moduleName").value_or(""); - auto comparatorName = mCustomParameters.atOptional("comparatorName").value_or(""); - double threshold = std::stof(mCustomParameters.atOptional("threshold").value_or("0")); + auto moduleName = mCustomParameters.atOptional("moduleName", activity).value_or(""); + auto comparatorName = mCustomParameters.atOptional("comparatorName", activity).value_or(""); + double threshold = std::stof(mCustomParameters.atOptional("threshold", activity).value_or("0")); + mReferenceRun = std::stoi(mCustomParameters.atOptional("referenceRun", activity).value_or("0")); mComparator.reset(); if (!moduleName.empty() && !comparatorName.empty()) { @@ -143,16 +144,11 @@ Quality ReferenceComparatorCheck::getSinglePlotQuality(std::shared_ptr>* moMap) { - Quality result = Quality::Good; + Quality result = Quality::Null; + + if (mReferenceRun == 0) { + result.addFlag(FlagTypeFactory::Unknown(), "No reference run provided"); + return result; + } + for (auto& [key, mo] : *moMap) { auto moName = mo->getName(); Quality quality; From fd93cdf8acaa4e1585e69c01154d61c164bc1cd9 Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Fri, 5 Jul 2024 15:30:38 +0200 Subject: [PATCH 25/25] pass only 1 activity for reference and not the reference run + the current activity --- Framework/include/QualityControl/CheckInterface.h | 5 ++--- Framework/include/QualityControl/ReferenceUtils.h | 4 ++-- Framework/src/CheckInterface.cxx | 4 ++-- Modules/Common/include/Common/ReferenceComparatorCheck.h | 2 +- Modules/Common/src/ReferenceComparatorCheck.cxx | 6 ++++-- Modules/Common/src/ReferenceComparatorTask.cxx | 4 +++- doc/Advanced.md | 5 ++--- 7 files changed, 16 insertions(+), 14 deletions(-) diff --git a/Framework/include/QualityControl/CheckInterface.h b/Framework/include/QualityControl/CheckInterface.h index 45d2884336..b1bb206167 100644 --- a/Framework/include/QualityControl/CheckInterface.h +++ b/Framework/include/QualityControl/CheckInterface.h @@ -96,10 +96,9 @@ class CheckInterface : public core::UserCodeInterface /// the activity is the current one, while the run number is the reference run. /// /// \param path path to the object (no provenance) - /// \param referenceRun Run number of the reference data - /// \param activity Current activity (necessary for the provenance and the pass) + /// \param referenceActivity Reference activity (usually a copy of the current activity with a different run number) /// \return - std::shared_ptr retrieveReference(std::string path, size_t referenceRun, Activity activity); + std::shared_ptr retrieveReference(std::string path, Activity referenceActivity); private: std::shared_ptr mDatabase; diff --git a/Framework/include/QualityControl/ReferenceUtils.h b/Framework/include/QualityControl/ReferenceUtils.h index 155b077841..5b8f6d7b6f 100644 --- a/Framework/include/QualityControl/ReferenceUtils.h +++ b/Framework/include/QualityControl/ReferenceUtils.h @@ -33,13 +33,13 @@ namespace o2::quality_control::checker // Get the reference plot for a given MonitorObject path static std::shared_ptr getReferencePlot(quality_control::repository::DatabaseInterface* qcdb, std::string& fullPath, - size_t referenceRun, core::Activity activity) + core::Activity referenceActivity) { auto [success, path, name] = o2::quality_control::core::RepoPathUtils::splitObjectPath(fullPath); if (!success) { return nullptr; } - return qcdb->retrieveMO(path, name, repository::DatabaseInterface::Timestamp::Latest, activity); + return qcdb->retrieveMO(path, name, repository::DatabaseInterface::Timestamp::Latest, referenceActivity); } } // namespace o2::quality_control::checker diff --git a/Framework/src/CheckInterface.cxx b/Framework/src/CheckInterface.cxx index a3b5d62e98..445d51e609 100644 --- a/Framework/src/CheckInterface.cxx +++ b/Framework/src/CheckInterface.cxx @@ -60,9 +60,9 @@ void CheckInterface::endOfActivity(const Activity& activity) // noop, override it if you want. } -shared_ptr CheckInterface::retrieveReference(std::string path, size_t referenceRun, Activity activity) +shared_ptr CheckInterface::retrieveReference(std::string path, Activity referenceActivity) { - return o2::quality_control::checker::getReferencePlot(mDatabase.get(), path, referenceRun, activity); + return o2::quality_control::checker::getReferencePlot(mDatabase.get(), path, referenceActivity); } } // namespace o2::quality_control::checker diff --git a/Modules/Common/include/Common/ReferenceComparatorCheck.h b/Modules/Common/include/Common/ReferenceComparatorCheck.h index 78c6f953b6..9e163f9bd2 100644 --- a/Modules/Common/include/Common/ReferenceComparatorCheck.h +++ b/Modules/Common/include/Common/ReferenceComparatorCheck.h @@ -54,7 +54,7 @@ class ReferenceComparatorCheck : public o2::quality_control::checker::CheckInter std::unique_ptr mComparator; std::map mQualityFlags; std::map> mQualityLabels; - quality_control::core::Activity mActivity; + quality_control::core::Activity mActivity /*current*/, mReferenceActivity; size_t mReferenceRun; }; diff --git a/Modules/Common/src/ReferenceComparatorCheck.cxx b/Modules/Common/src/ReferenceComparatorCheck.cxx index c239855ef4..3800570252 100644 --- a/Modules/Common/src/ReferenceComparatorCheck.cxx +++ b/Modules/Common/src/ReferenceComparatorCheck.cxx @@ -61,6 +61,8 @@ void ReferenceComparatorCheck::startOfActivity(const Activity& activity) } mActivity = activity; + mReferenceActivity = activity; + mReferenceActivity.mId = mReferenceRun; } void ReferenceComparatorCheck::endOfActivity(const Activity& activity) @@ -147,8 +149,8 @@ Quality ReferenceComparatorCheck::getSinglePlotQuality(std::shared_ptr CheckInterface::retrieveReference(std::string path, int referenceRun, Activity activity); + std::shared_ptr CheckInterface::retrieveReference(std::string path, Activity referenceActivity); ``` - `path` : the path of the object _without the provenance (e.g. `qc`)_ -- `referenceRun` : the run of reference -- `activity` : the current activity +- `referenceActivity` : the activity of reference (usually the current activity with a different run number) If the reference is not found it will return a `nullptr` and the quality is `Null`.