Skip to content

Commit

Permalink
[Common] implement review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
aferrero2707 committed Jun 16, 2024
1 parent 1cca51e commit 916d1ce
Show file tree
Hide file tree
Showing 14 changed files with 248 additions and 241 deletions.
1 change: 1 addition & 0 deletions Modules/Common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ target_sources(O2QcCommon
src/CcdbInspectorTask.cxx
src/CcdbInspectorTaskConfig.cxx
src/CcdbInspectorCheck.cxx
src/ObjectComparatorInterface.cxx
src/ObjectComparatorDeviation.cxx
src/ObjectComparatorChi2.cxx
src/ObjectComparatorKolmogorov.cxx
Expand Down
2 changes: 1 addition & 1 deletion Modules/Common/include/Common/ObjectComparatorChi2.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class ObjectComparatorChi2 : public ObjectComparatorInterface

/// \brief objects comparison function
/// \return the quality resulting from the object comparison
o2::quality_control::core::Quality compare(TObject* obj, TObject* objRef, std::string& message) override;
o2::quality_control::core::Quality compare(TObject* object, TObject* referenceObject, std::string& message) override;
};

} // namespace o2::quality_control_modules::common
Expand Down
2 changes: 1 addition & 1 deletion Modules/Common/include/Common/ObjectComparatorDeviation.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class ObjectComparatorDeviation : public ObjectComparatorInterface

/// \brief objects comparison function
/// \return the quality resulting from the object comparison
o2::quality_control::core::Quality compare(TObject* obj, TObject* objRef, std::string& message) override;
o2::quality_control::core::Quality compare(TObject* object, TObject* referenceObject, std::string& message) override;
};

} // namespace o2::quality_control_modules::common
Expand Down
10 changes: 9 additions & 1 deletion Modules/Common/include/Common/ObjectComparatorInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@
#include "QualityControl/Quality.h"
#include "QualityControl/CustomParameters.h"
#include "QualityControl/Activity.h"

#include <tuple>

class TObject;
class TH1;

namespace o2::quality_control_modules::common
{
Expand All @@ -42,9 +46,13 @@ class ObjectComparatorInterface
void setThreshold(double threshold) { mThreshold = threshold; }
double getThreshold() { return mThreshold; }

/// perform a number of sanity checks on the input objects
/// \return a tuple containing pointers to the histogram, the reference histogram, and a boolean indicating the success of the checks
std::tuple<TH1*, TH1*, bool> checkInputObjects(TObject* object, TObject* referenceObject, std::string& message);

/// \brief objects comparison function
/// \return the quality resulting from the object comparison
virtual o2::quality_control::core::Quality compare(TObject* obj, TObject* objRef, std::string& message) = 0;
virtual o2::quality_control::core::Quality compare(TObject* object, TObject* referenceObject, std::string& message) = 0;

private:
/// the threshold to define the goodness of the comparison
Expand Down
2 changes: 1 addition & 1 deletion Modules/Common/include/Common/ObjectComparatorKolmogorov.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class ObjectComparatorKolmogorov : public ObjectComparatorInterface

/// \brief objects comparison function
/// \return the quality resulting from the object comparison
o2::quality_control::core::Quality compare(TObject* obj, TObject* objRef, std::string& message) override;
o2::quality_control::core::Quality compare(TObject* object, TObject* referenceObject, std::string& message) override;
};

} // namespace o2::quality_control_modules::common
Expand Down
13 changes: 10 additions & 3 deletions Modules/Common/include/Common/ReferenceComparatorPlot.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,18 @@ class ReferenceComparatorPlotImpl;
class ReferenceComparatorPlot
{
public:
ReferenceComparatorPlot(TH1* refHist, std::string outputPath, bool scaleRef, bool drawRatioOnly, std::string drawOption1D, std::string drawOption2D);
/// ReferenceComparatorPlot constructor
/// \param referenceHistogram pointer to the reference histogram object, used to initialize the internal plots
/// \param outputPath QCDB path were the output canvas is stored
/// \param scaleReference if true the reference plot is sclaled such that its integral matches the one of the current histogram
/// \param drawRatioOnly if true only the ratio between current and reference plot is draw, otherwise also the individual plots are drawn in addition
/// \param drawOption1D ROOT draw option to be used for 1-D plots
/// \param drawOption2D ROOT draw option to be used for 2-D plots
ReferenceComparatorPlot(TH1* referenceHistogram, const std::string& outputPath, bool scaleReference, bool drawRatioOnly, const std::string& drawOption1D, const std::string& drawOption2D);
virtual ~ReferenceComparatorPlot() = default;

TObject* getObject();
void update(TH1* hist, TH1* histRef);
TObject* getMainCanvas();
void update(TH1* histogram, TH1* referenceHistogram);

private:
std::shared_ptr<ReferenceComparatorPlotImpl> mImplementation;
Expand Down
7 changes: 3 additions & 4 deletions Modules/Common/include/Common/ReferenceComparatorTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,17 @@ class ReferenceComparatorTask : public quality_control::postprocessing::PostProc
};

private:
std::shared_ptr<o2::quality_control::core::MonitorObject> getRefPlot(o2::quality_control::repository::DatabaseInterface& qcdb, std::string fullPath, o2::quality_control::core::Activity activity);
void updatePlot(std::string plotName, TObject* object);
std::shared_ptr<o2::quality_control::core::MonitorObject> getReferencePlot(o2::quality_control::repository::DatabaseInterface& qcdb, std::string fullPath, o2::quality_control::core::Activity activity);

int mRefRun{ 0 };
int mReferenceRun{ 0 };
int mNotOlderThan{ 120 };

/// \brief configuration parameters
ReferenceComparatorTaskConfig mConfig;
/// \brief list of plot names, separately for each group
std::map<std::string, std::vector<std::string>> mPlotNames;
/// \brief reference MOs
std::map<std::string, std::shared_ptr<o2::quality_control::core::MonitorObject>> mRefPlots;
std::map<std::string, std::shared_ptr<o2::quality_control::core::MonitorObject>> mReferencePlots;
/// \brief histograms with comparison to reference
std::map<std::string, std::shared_ptr<ReferenceComparatorPlot>> mHistograms;
};
Expand Down
34 changes: 6 additions & 28 deletions Modules/Common/src/ObjectComparatorChi2.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -27,42 +27,20 @@ using namespace o2::quality_control::core;
namespace o2::quality_control_modules::common
{

Quality ObjectComparatorChi2::compare(TObject* obj, TObject* objRef, std::string& message)
Quality ObjectComparatorChi2::compare(TObject* object, TObject* referenceObject, std::string& message)
{
if (!obj || !objRef) {
message = "missing objects";
auto checkResult = checkInputObjects(object, referenceObject, message);
if (!std::get<2>(checkResult)) {
return Quality::Null;
}

// only consider objects that inherit from TH1
auto* hist = dynamic_cast<TH1*>(obj);
auto* histRef = dynamic_cast<TH1*>(objRef);

if (!hist || !histRef) {
message = "objects are not TH1";
return Quality::Null;
}

// the object and the reference must correspond to the same ROOT class
if (hist->IsA() != histRef->IsA()) {
message = "incompatible objects";
return Quality::Null;
}

if (histRef->GetEntries() < 1) {
message = "empty reference plot";
return Quality::Null;
}

if (hist->GetNcells() < 3 || hist->GetNcells() != histRef->GetNcells()) {
message = "incompatible number of bins";
return Quality::Null;
}
auto* histogram = std::get<0>(checkResult);
auto* referenceHistogram = std::get<1>(checkResult);

// perform a chi2 compatibility test between the two histograms
// it assumes that both histigrams represent counts, but the reference might
// have been rescaled to match the integral of the current histogram
double testProbability = hist->Chi2Test(histRef, "UU NORM");
double testProbability = histogram->Chi2Test(referenceHistogram, "UU NORM");

// compare the chi2 probability with the minimum allowed value
if (testProbability < getThreshold()) {
Expand Down
38 changes: 8 additions & 30 deletions Modules/Common/src/ObjectComparatorDeviation.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -27,44 +27,22 @@ using namespace o2::quality_control::core;
namespace o2::quality_control_modules::common
{

Quality ObjectComparatorDeviation::compare(TObject* obj, TObject* objRef, std::string& message)
Quality ObjectComparatorDeviation::compare(TObject* object, TObject* referenceObject, std::string& message)
{
if (!obj || !objRef) {
message = "missing objects";
auto checkResult = checkInputObjects(object, referenceObject, message);
if (!std::get<2>(checkResult)) {
return Quality::Null;
}

// only consider objects that inherit from TH1
auto* hist = dynamic_cast<TH1*>(obj);
auto* histRef = dynamic_cast<TH1*>(objRef);

if (!hist || !histRef) {
message = "objects are not TH1";
return Quality::Null;
}

// the object and the reference must correspond to the same ROOT class
if (hist->IsA() != histRef->IsA()) {
message = "incompatible objects";
return Quality::Null;
}

if (histRef->GetEntries() < 1) {
message = "empty reference plot";
return Quality::Null;
}

if (hist->GetNcells() < 3 || hist->GetNcells() != histRef->GetNcells()) {
message = "incompatible number of bins";
return Quality::Null;
}
auto* histogram = std::get<0>(checkResult);
auto* referenceHistogram = std::get<1>(checkResult);

// compute the average relative deviation between the bins
double averageDeviation = 0;
int numberOfBins = hist->GetNcells() - 2;
int numberOfBins = histogram->GetNcells() - 2;
for (int bin = 1; bin <= numberOfBins; bin++) {
double val = hist->GetBinContent(bin);
double refVal = histRef->GetBinContent(bin);
double val = histogram->GetBinContent(bin);
double refVal = referenceHistogram->GetBinContent(bin);
averageDeviation += (refVal == 0) ? 0 : std::abs((val - refVal) / refVal);
}
averageDeviation /= numberOfBins;
Expand Down
68 changes: 68 additions & 0 deletions Modules/Common/src/ObjectComparatorInterface.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// 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 ObjectComparatorInterface.cxx
/// \author Andrea Ferrero
/// \brief An interface for comparing two TObject
///

#include "Common/ObjectComparatorInterface.h"
// ROOT
#include <TH1.h>

#include <fmt/core.h>

using namespace o2::quality_control;
using namespace o2::quality_control::core;

namespace o2::quality_control_modules::common
{

std::tuple<TH1*, TH1*, bool> ObjectComparatorInterface::checkInputObjects(TObject* object, TObject* referenceObject, std::string& message)
{
TH1* histogram = nullptr;
TH1* referenceHistogram = nullptr;

if (!object || !referenceObject) {
message = "missing objects";
return std::make_tuple(histogram, referenceHistogram, false);
}

// only consider objects that inherit from TH1
histogram = dynamic_cast<TH1*>(object);
referenceHistogram = dynamic_cast<TH1*>(referenceObject);

if (!histogram || !referenceHistogram) {
message = "objects are not TH1";
return std::make_tuple(histogram, referenceHistogram, false);
}

// the object and the reference must correspond to the same ROOT class
if (histogram->IsA() != referenceHistogram->IsA()) {
message = "incompatible objects";
return std::make_tuple(histogram, referenceHistogram, false);
}

if (referenceHistogram->GetEntries() < 1) {
message = "empty reference plot";
return std::make_tuple(histogram, referenceHistogram, false);
}

if (histogram->GetNcells() < 3 || histogram->GetNcells() != referenceHistogram->GetNcells()) {
message = "incompatible number of bins";
return std::make_tuple(histogram, referenceHistogram, false);
}

return std::make_tuple(histogram, referenceHistogram, true);
}

} // namespace o2::quality_control_modules::common
34 changes: 6 additions & 28 deletions Modules/Common/src/ObjectComparatorKolmogorov.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -27,42 +27,20 @@ using namespace o2::quality_control::core;
namespace o2::quality_control_modules::common
{

Quality ObjectComparatorKolmogorov::compare(TObject* obj, TObject* objRef, std::string& message)
Quality ObjectComparatorKolmogorov::compare(TObject* object, TObject* referenceObject, std::string& message)
{
if (!obj || !objRef) {
message = "missing objects";
auto checkResult = checkInputObjects(object, referenceObject, message);
if (!std::get<2>(checkResult)) {
return Quality::Null;
}

// only consider objects that inherit from TH1
auto* hist = dynamic_cast<TH1*>(obj);
auto* histRef = dynamic_cast<TH1*>(objRef);

if (!hist || !histRef) {
message = "objects are not TH1";
return Quality::Null;
}

// the object and the reference must correspond to the same ROOT class
if (hist->IsA() != histRef->IsA()) {
message = "incompatible objects";
return Quality::Null;
}

if (histRef->GetEntries() < 1) {
message = "empty reference plot";
return Quality::Null;
}

if (hist->GetNcells() < 3 || hist->GetNcells() != histRef->GetNcells()) {
message = "incompatible number of bins";
return Quality::Null;
}
auto* histogram = std::get<0>(checkResult);
auto* referenceHistogram = std::get<1>(checkResult);

// perform a Kolmogorov compatibility test between the two histograms
// it assumes that both histigrams represent counts, but the reference might
// have been rescaled to match the integral of the current histogram
double testProbability = hist->KolmogorovTest(histRef, "UU NORM");
double testProbability = histogram->KolmogorovTest(referenceHistogram, "UU NORM");

// compare the Kolmogorov probability with the minimum allowed value
if (testProbability < getThreshold()) {
Expand Down
Loading

0 comments on commit 916d1ce

Please sign in to comment.