From 91c706af8ea8dc51290ed377c26fe1c89a26f9be Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Tue, 31 May 2022 16:56:33 +0200 Subject: [PATCH 1/5] [QC-798] Add a check to ensure entries increase every cycle --- Modules/Common/CMakeLists.txt | 4 +- .../Common/include/Common/IncreasingEntries.h | 51 +++++++++++++ Modules/Common/include/Common/LinkDef.h | 4 +- Modules/Common/src/IncreasingEntries.cxx | 75 +++++++++++++++++++ 4 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 Modules/Common/include/Common/IncreasingEntries.h create mode 100644 Modules/Common/src/IncreasingEntries.cxx diff --git a/Modules/Common/CMakeLists.txt b/Modules/Common/CMakeLists.txt index fb96df7dfa..2c913544f0 100644 --- a/Modules/Common/CMakeLists.txt +++ b/Modules/Common/CMakeLists.txt @@ -10,7 +10,8 @@ configure_file("include/Common/Version.h.in" add_library(O2QcCommon) target_sources(O2QcCommon - PRIVATE src/WorstOfAllAggregator.cxx + PRIVATE src/IncreasingEntries.cxx + src/WorstOfAllAggregator.cxx src/TRFCollectionTask.cxx src/TRFCollectionTaskConfig.cxx src/NonEmpty.cxx @@ -44,6 +45,7 @@ add_root_dictionary(O2QcCommon include/Common/THnSparse5Reductor.h include/Common/QualityReductor.h include/Common/EverIncreasingGraph.h + include/Common/IncreasingEntries.h LINKDEF include/Common/LinkDef.h BASENAME O2QcCommon) diff --git a/Modules/Common/include/Common/IncreasingEntries.h b/Modules/Common/include/Common/IncreasingEntries.h new file mode 100644 index 0000000000..c5a0aee605 --- /dev/null +++ b/Modules/Common/include/Common/IncreasingEntries.h @@ -0,0 +1,51 @@ +// 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 IncreasingEntries.h +/// \author My Name +/// + +#ifndef QC_MODULE_COMMON_COMMONINCREASINGENTRIES_H +#define QC_MODULE_COMMON_COMMONINCREASINGENTRIES_H + +#include "QualityControl/CheckInterface.h" +#include + +namespace o2::quality_control_modules::common +{ + +/// \brief Example QC Check +/// \author My Name +class IncreasingEntries : public o2::quality_control::checker::CheckInterface +{ + public: + /// Default constructor + IncreasingEntries() = default; + /// Destructor + ~IncreasingEntries() override = default; + + // Override interface + void configure() override; + Quality check(std::map>* moMap) override; + void beautify(std::shared_ptr mo, Quality checkResult = Quality::Null) override; + std::string getAcceptedType() override; + + private: + std::map mLastEntries; + std::shared_ptr mPaveText; + + ClassDefOverride(IncreasingEntries, 2); +}; + +} // namespace o2::quality_control_modules::common + +#endif // QC_MODULE_COMMON_COMMONINCREASINGENTRIES_H diff --git a/Modules/Common/include/Common/LinkDef.h b/Modules/Common/include/Common/LinkDef.h index c70f1a489a..86bb2a722f 100644 --- a/Modules/Common/include/Common/LinkDef.h +++ b/Modules/Common/include/Common/LinkDef.h @@ -12,4 +12,6 @@ #pragma link C++ class o2::quality_control_modules::common::EverIncreasingGraph + ; #pragma link C++ class o2::quality_control_modules::common::TRFCollectionTask + ; #pragma link C++ class o2::quality_control_modules::common::WorstOfAllAggregator + ; -#endif + #pragma link C++ class o2::quality_control_modules::common::IncreasingEntries+; + + #endif diff --git a/Modules/Common/src/IncreasingEntries.cxx b/Modules/Common/src/IncreasingEntries.cxx new file mode 100644 index 0000000000..475351fe26 --- /dev/null +++ b/Modules/Common/src/IncreasingEntries.cxx @@ -0,0 +1,75 @@ +// 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 IncreasingEntries.cxx +/// \author My Name +/// + +#include "Common/IncreasingEntries.h" +#include "QualityControl/MonitorObject.h" +#include "QualityControl/Quality.h" +#include "QualityControl/QcInfoLogger.h" +// ROOT +#include +#include + +#include + +using namespace std; +using namespace o2::quality_control; + +namespace o2::quality_control_modules::common +{ + +void IncreasingEntries::configure() +{ + mPaveText = make_shared(1, 0.125, 0.6, 0, "NDC"); + mPaveText->AddText("Number of Entries has not changed"); + mPaveText->AddText("in the past cycle"); + mPaveText->SetFillColor(kRed); + mPaveText->SetMargin(0); +} + +Quality IncreasingEntries::check(std::map>* moMap) +{ + Quality result = Quality::Good; + + for (auto& [moName, mo] : *moMap) { + + TH1* histo = dynamic_cast(mo->getObject()); + if(histo == nullptr) { + continue; + } + + double previousNumberEntries = mLastEntries.count(moName) > 0 ? mLastEntries.at(moName) : 0; + double currentNumberEntries = histo->GetEntries(); + + if(previousNumberEntries == currentNumberEntries) { + result = Quality::Bad; + result.addReason(FlagReasonFactory::Unknown(), + "Number of entries stopped increasing."); + histo->GetListOfFunctions()->Add(mPaveText->Clone()); + } + + mLastEntries[moName] = currentNumberEntries; + } + return result; +} + +std::string IncreasingEntries::getAcceptedType() { return "TH1"; } + +void IncreasingEntries::beautify(std::shared_ptr mo, Quality checkResult) +{ + // as we want to add the text on the faulty histo we cannot do it here. +} + +} // namespace o2::quality_control_modules::common From a6b0499075ad9ff4aa623c2c04edf7c7a426962e Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Tue, 31 May 2022 16:59:34 +0200 Subject: [PATCH 2/5] format --- Framework/basic.json | 6 ++-- Modules/CMakeLists.txt | 34 +++++++++---------- .../Common/include/Common/IncreasingEntries.h | 4 +-- Modules/Common/include/Common/LinkDef.h | 6 ++-- Modules/Common/src/IncreasingEntries.cxx | 4 +-- .../Skeleton/include/Skeleton/SkeletonTask.h | 2 ++ Modules/Skeleton/src/SkeletonTask.cxx | 8 ++++- doc/DevelopersTips.md | 18 +++++++++- 8 files changed, 53 insertions(+), 29 deletions(-) diff --git a/Framework/basic.json b/Framework/basic.json index 846395c0c3..de4fc4578b 100644 --- a/Framework/basic.json +++ b/Framework/basic.json @@ -53,14 +53,14 @@ "checks": { "QcCheck": { "active": "true", - "className": "o2::quality_control_modules::skeleton::SkeletonCheck", - "moduleName": "QcSkeleton", + "className": "o2::quality_control_modules::common::IncreasingEntries", + "moduleName": "QcCommon", "policy": "OnAny", "detectorName": "TST", "dataSource": [{ "type": "Task", "name": "QcTask", - "MOs": ["example"] + "MOs": ["example", "example2", "asdf"] }] } } diff --git a/Modules/CMakeLists.txt b/Modules/CMakeLists.txt index 57ded9c726..39ef471ce8 100644 --- a/Modules/CMakeLists.txt +++ b/Modules/CMakeLists.txt @@ -5,20 +5,20 @@ add_subdirectory(Daq) add_subdirectory(Example) add_subdirectory(Benchmark) add_subdirectory(Skeleton) -add_subdirectory(TOF) -add_subdirectory(EMCAL) -add_subdirectory(MUON) -add_subdirectory(TPC) -add_subdirectory(ITS) -add_subdirectory(MFT) -add_subdirectory(PHOS) -add_subdirectory(FT0) -add_subdirectory(TRD) -add_subdirectory(HMPID) -add_subdirectory(CPV) -add_subdirectory(GLO) -add_subdirectory(FV0) -add_subdirectory(FDD) -add_subdirectory(ZDC) -add_subdirectory(CTP) -add_subdirectory(PID) +#add_subdirectory(TOF) +#add_subdirectory(EMCAL) +#add_subdirectory(MUON) +#add_subdirectory(TPC) +#add_subdirectory(ITS) +#add_subdirectory(MFT) +#add_subdirectory(PHOS) +#add_subdirectory(FT0) +#add_subdirectory(TRD) +#add_subdirectory(HMPID) +#add_subdirectory(CPV) +#add_subdirectory(GLO) +#add_subdirectory(FV0) +#add_subdirectory(FDD) +#add_subdirectory(ZDC) +#add_subdirectory(CTP) +#add_subdirectory(PID) diff --git a/Modules/Common/include/Common/IncreasingEntries.h b/Modules/Common/include/Common/IncreasingEntries.h index c5a0aee605..30511361c1 100644 --- a/Modules/Common/include/Common/IncreasingEntries.h +++ b/Modules/Common/include/Common/IncreasingEntries.h @@ -40,8 +40,8 @@ class IncreasingEntries : public o2::quality_control::checker::CheckInterface std::string getAcceptedType() override; private: - std::map mLastEntries; - std::shared_ptr mPaveText; + std::map mLastEntries; + std::shared_ptr mPaveText; ClassDefOverride(IncreasingEntries, 2); }; diff --git a/Modules/Common/include/Common/LinkDef.h b/Modules/Common/include/Common/LinkDef.h index 86bb2a722f..64be4d49ae 100644 --- a/Modules/Common/include/Common/LinkDef.h +++ b/Modules/Common/include/Common/LinkDef.h @@ -12,6 +12,6 @@ #pragma link C++ class o2::quality_control_modules::common::EverIncreasingGraph + ; #pragma link C++ class o2::quality_control_modules::common::TRFCollectionTask + ; #pragma link C++ class o2::quality_control_modules::common::WorstOfAllAggregator + ; - #pragma link C++ class o2::quality_control_modules::common::IncreasingEntries+; - - #endif +#pragma link C++ class o2::quality_control_modules::common::IncreasingEntries + ; + +#endif diff --git a/Modules/Common/src/IncreasingEntries.cxx b/Modules/Common/src/IncreasingEntries.cxx index 475351fe26..3e6647f1ce 100644 --- a/Modules/Common/src/IncreasingEntries.cxx +++ b/Modules/Common/src/IncreasingEntries.cxx @@ -46,14 +46,14 @@ Quality IncreasingEntries::check(std::map(mo->getObject()); - if(histo == nullptr) { + if (histo == nullptr) { continue; } double previousNumberEntries = mLastEntries.count(moName) > 0 ? mLastEntries.at(moName) : 0; double currentNumberEntries = histo->GetEntries(); - if(previousNumberEntries == currentNumberEntries) { + if (previousNumberEntries == currentNumberEntries) { result = Quality::Bad; result.addReason(FlagReasonFactory::Unknown(), "Number of entries stopped increasing."); diff --git a/Modules/Skeleton/include/Skeleton/SkeletonTask.h b/Modules/Skeleton/include/Skeleton/SkeletonTask.h index 385b19ebeb..edb130f46f 100644 --- a/Modules/Skeleton/include/Skeleton/SkeletonTask.h +++ b/Modules/Skeleton/include/Skeleton/SkeletonTask.h @@ -20,6 +20,7 @@ #include "QualityControl/TaskInterface.h" class TH1F; +class TGraph; using namespace o2::quality_control::core; @@ -47,6 +48,7 @@ class SkeletonTask final : public TaskInterface private: TH1F* mHistogram = nullptr; + TGraph* asdf = nullptr; }; } // namespace o2::quality_control_modules::skeleton diff --git a/Modules/Skeleton/src/SkeletonTask.cxx b/Modules/Skeleton/src/SkeletonTask.cxx index 4e9b7e0938..1f8e09cc22 100644 --- a/Modules/Skeleton/src/SkeletonTask.cxx +++ b/Modules/Skeleton/src/SkeletonTask.cxx @@ -16,6 +16,7 @@ #include #include +#include #include "QualityControl/QcInfoLogger.h" #include "Skeleton/SkeletonTask.h" @@ -44,6 +45,9 @@ void SkeletonTask::initialize(o2::framework::InitContext& /*ctx*/) mHistogram = new TH1F("example", "example", 20, 0, 30000); getObjectsManager()->startPublishing(mHistogram); getObjectsManager()->startPublishing(new TH1F("example2", "example2", 20, 0, 30000)); + asdf = new TGraph(10); + asdf->SetName("asdf"); + getObjectsManager()->startPublishing(asdf); try { getObjectsManager()->addMetadata(mHistogram->GetName(), "custom", "34"); } catch (...) { @@ -91,7 +95,9 @@ void SkeletonTask::monitorData(o2::framework::ProcessingContext& ctx) // const char* payload = input.payload; // for the sake of an example, let's fill the histogram with payload sizes - mHistogram->Fill(payloadSize); + if (mHistogram->GetEntries() < 20 || mHistogram->GetEntries() > 50) { + mHistogram->Fill(payloadSize); + } } // 2. Using get("") diff --git a/doc/DevelopersTips.md b/doc/DevelopersTips.md index d0fe6f3f22..b4fbe0f1f1 100644 --- a/doc/DevelopersTips.md +++ b/doc/DevelopersTips.md @@ -327,4 +327,20 @@ The config files on EPNs are merged to build a humongous config file used for th The common part is stored here: https://github.com/AliceO2Group/O2DPG/blob/master/DATA/production/qc-sync/qc-global.json The config file to use for each detector are defined here: https://github.com/AliceO2Group/O2DPG/blob/3dacaf525309b6e8cb4b4e2b7ea357ed65a95094/DATA/production/qc-workflow.sh - +## run locally multi-node +Terminal 1 +```bash +cd sw/BUILD/QualityControl-latest/QualityControl +export JSON_DIR=${PWD}/tests +export UNIQUE_PORT_1=12345 +export UNIQUE_PORT_2=12346 +o2-qc-run-producer --producers 2 --message-amount 1500 --message-rate 10 -b | o2-qc --config json://${JSON_DIR}/multinode-test.json -b --local --host localhost --run +``` +Terminal 2 +```bash +cd sw/BUILD/QualityControl-latest/QualityControl +export JSON_DIR=${PWD}/tests +export UNIQUE_PORT_1=12345 +export UNIQUE_PORT_2=12346 +o2-qc --config json://${JSON_DIR}/multinode-test.json -b --remote --run +``` \ No newline at end of file From fd781681901968fc4959990185a43cc735d67165 Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Wed, 1 Jun 2022 10:05:30 +0200 Subject: [PATCH 3/5] reenable detectors --- Modules/CMakeLists.txt | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Modules/CMakeLists.txt b/Modules/CMakeLists.txt index 39ef471ce8..57ded9c726 100644 --- a/Modules/CMakeLists.txt +++ b/Modules/CMakeLists.txt @@ -5,20 +5,20 @@ add_subdirectory(Daq) add_subdirectory(Example) add_subdirectory(Benchmark) add_subdirectory(Skeleton) -#add_subdirectory(TOF) -#add_subdirectory(EMCAL) -#add_subdirectory(MUON) -#add_subdirectory(TPC) -#add_subdirectory(ITS) -#add_subdirectory(MFT) -#add_subdirectory(PHOS) -#add_subdirectory(FT0) -#add_subdirectory(TRD) -#add_subdirectory(HMPID) -#add_subdirectory(CPV) -#add_subdirectory(GLO) -#add_subdirectory(FV0) -#add_subdirectory(FDD) -#add_subdirectory(ZDC) -#add_subdirectory(CTP) -#add_subdirectory(PID) +add_subdirectory(TOF) +add_subdirectory(EMCAL) +add_subdirectory(MUON) +add_subdirectory(TPC) +add_subdirectory(ITS) +add_subdirectory(MFT) +add_subdirectory(PHOS) +add_subdirectory(FT0) +add_subdirectory(TRD) +add_subdirectory(HMPID) +add_subdirectory(CPV) +add_subdirectory(GLO) +add_subdirectory(FV0) +add_subdirectory(FDD) +add_subdirectory(ZDC) +add_subdirectory(CTP) +add_subdirectory(PID) From 4621c0c57e1130eace4e4537e5c432b1cff65a45 Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Wed, 1 Jun 2022 11:09:39 +0200 Subject: [PATCH 4/5] restore basic.json --- Framework/basic.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Framework/basic.json b/Framework/basic.json index de4fc4578b..846395c0c3 100644 --- a/Framework/basic.json +++ b/Framework/basic.json @@ -53,14 +53,14 @@ "checks": { "QcCheck": { "active": "true", - "className": "o2::quality_control_modules::common::IncreasingEntries", - "moduleName": "QcCommon", + "className": "o2::quality_control_modules::skeleton::SkeletonCheck", + "moduleName": "QcSkeleton", "policy": "OnAny", "detectorName": "TST", "dataSource": [{ "type": "Task", "name": "QcTask", - "MOs": ["example", "example2", "asdf"] + "MOs": ["example"] }] } } From 5e190d5eb39ac3cb3fcf4cc75f978e3d27958729 Mon Sep 17 00:00:00 2001 From: Barthelemy Date: Wed, 1 Jun 2022 13:37:32 +0200 Subject: [PATCH 5/5] some fixes --- Framework/script/o2-qc-batch-test.sh | 10 +++++----- Modules/Skeleton/include/Skeleton/SkeletonTask.h | 2 -- Modules/Skeleton/src/SkeletonTask.cxx | 8 +------- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/Framework/script/o2-qc-batch-test.sh b/Framework/script/o2-qc-batch-test.sh index cd38ea41fb..fd0f2724f9 100755 --- a/Framework/script/o2-qc-batch-test.sh +++ b/Framework/script/o2-qc-batch-test.sh @@ -38,7 +38,7 @@ fi if [ -z "$JSON_DIR" ] then echo "JSON_DIR must be set when calling o2-qc-batch-test.sh" - exit 1 + exit 2 fi # make sure the CCDB is available otherwise we bail (no failure) @@ -64,14 +64,14 @@ code=$(curl -L ccdb-test.cern.ch:8080/qc/TST/MO/BatchTestTask${UNIQUE_ID}/exampl if (( $code != 200 )); then echo "Error, monitor object of the QC Task could not be found." delete_data - exit 2 + exit 3 fi # try to check that we got a valid root object root -b -l -q -e 'TFile f("/tmp/batch_test_obj${UNIQUE_ID}.root"); f.Print();' if (( $? != 0 )); then echo "Error, monitor object of the QC Task is invalid." delete_data - exit 2 + exit 4 fi # try if it is a non empty histogram entries=`root -b -l -q -e 'TFile f("/tmp/batch_test_obj${UNIQUE_ID}.root"); TH1F *h = (TH1F*)f.Get("ccdb_object"); cout << h->GetEntries() << endl;' | tail -n 1` @@ -79,7 +79,7 @@ if [ $entries -lt 150 ] 2>/dev/null then echo "The histogram of the QC Task has less than 150 (75%) of expected samples." delete_data - exit 2 + exit 5 fi # check QualityObject @@ -88,7 +88,7 @@ code=$(curl -L ccdb-test.cern.ch:8080/qc/TST/QO/BatchTestCheck${UNIQUE_ID}/`date if (( $code != 200 )); then echo "Error, quality object of the QC Task could not be found." delete_data - exit 2 + exit 6 fi echo "Batch test was passed." diff --git a/Modules/Skeleton/include/Skeleton/SkeletonTask.h b/Modules/Skeleton/include/Skeleton/SkeletonTask.h index edb130f46f..385b19ebeb 100644 --- a/Modules/Skeleton/include/Skeleton/SkeletonTask.h +++ b/Modules/Skeleton/include/Skeleton/SkeletonTask.h @@ -20,7 +20,6 @@ #include "QualityControl/TaskInterface.h" class TH1F; -class TGraph; using namespace o2::quality_control::core; @@ -48,7 +47,6 @@ class SkeletonTask final : public TaskInterface private: TH1F* mHistogram = nullptr; - TGraph* asdf = nullptr; }; } // namespace o2::quality_control_modules::skeleton diff --git a/Modules/Skeleton/src/SkeletonTask.cxx b/Modules/Skeleton/src/SkeletonTask.cxx index 1f8e09cc22..4e9b7e0938 100644 --- a/Modules/Skeleton/src/SkeletonTask.cxx +++ b/Modules/Skeleton/src/SkeletonTask.cxx @@ -16,7 +16,6 @@ #include #include -#include #include "QualityControl/QcInfoLogger.h" #include "Skeleton/SkeletonTask.h" @@ -45,9 +44,6 @@ void SkeletonTask::initialize(o2::framework::InitContext& /*ctx*/) mHistogram = new TH1F("example", "example", 20, 0, 30000); getObjectsManager()->startPublishing(mHistogram); getObjectsManager()->startPublishing(new TH1F("example2", "example2", 20, 0, 30000)); - asdf = new TGraph(10); - asdf->SetName("asdf"); - getObjectsManager()->startPublishing(asdf); try { getObjectsManager()->addMetadata(mHistogram->GetName(), "custom", "34"); } catch (...) { @@ -95,9 +91,7 @@ void SkeletonTask::monitorData(o2::framework::ProcessingContext& ctx) // const char* payload = input.payload; // for the sake of an example, let's fill the histogram with payload sizes - if (mHistogram->GetEntries() < 20 || mHistogram->GetEntries() > 50) { - mHistogram->Fill(payloadSize); - } + mHistogram->Fill(payloadSize); } // 2. Using get("")