From d257ae6ba475ee9044cecccec57e4e7830a3ba22 Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Fri, 4 Oct 2024 10:47:45 +0200 Subject: [PATCH] [MCH] introduce station deendent checker thresholds (#2445) Checker thresholds are extended to allow setting different values for specific stations, overriding the global default value. The code is also simplified by removing check of the ratio plots, that are now superseded by the common reference comparator output. --- Modules/MUON/MCH/include/MCH/DecodingCheck.h | 2 + Modules/MUON/MCH/include/MCH/DigitsCheck.h | 8 +- Modules/MUON/MCH/include/MCH/Helpers.h | 10 + .../MUON/MCH/include/MCH/PreclustersCheck.h | 4 +- Modules/MUON/MCH/src/DecodingCheck.cxx | 125 +++++----- Modules/MUON/MCH/src/DigitsCheck.cxx | 225 +++++------------- Modules/MUON/MCH/src/Helpers.cxx | 59 +++++ Modules/MUON/MCH/src/PreclustersCheck.cxx | 138 +++-------- 8 files changed, 231 insertions(+), 340 deletions(-) diff --git a/Modules/MUON/MCH/include/MCH/DecodingCheck.h b/Modules/MUON/MCH/include/MCH/DecodingCheck.h index c45209ae4a..d4ebf7e508 100644 --- a/Modules/MUON/MCH/include/MCH/DecodingCheck.h +++ b/Modules/MUON/MCH/include/MCH/DecodingCheck.h @@ -52,7 +52,9 @@ class DecodingCheck : public o2::quality_control::checker::CheckInterface int mMaxBadST12{ 2 }; int mMaxBadST345{ 3 }; double mMinGoodErrorFrac{ 0.9 }; + std::array, 5> mMinGoodErrorFracPerStation; double mMinGoodSyncFrac{ 0.9 }; + std::array, 5> mMinGoodSyncFracPerStation; QualityChecker mQualityChecker; diff --git a/Modules/MUON/MCH/include/MCH/DigitsCheck.h b/Modules/MUON/MCH/include/MCH/DigitsCheck.h index a354af811b..be229c5e4e 100644 --- a/Modules/MUON/MCH/include/MCH/DigitsCheck.h +++ b/Modules/MUON/MCH/include/MCH/DigitsCheck.h @@ -21,6 +21,7 @@ #include "QualityControl/CheckInterface.h" #include "QualityControl/Quality.h" #include +#include namespace o2::quality_control::core { @@ -55,16 +56,15 @@ class DigitsCheck : public o2::quality_control::checker::CheckInterface std::array checkBadChannelsRatio(TH1F* h); std::string mMeanRateHistName{ "RatesSignal/LastCycle/MeanRate" }; - std::string mMeanRateRatioHistName{ "RatesSignal/LastCycle/MeanRateRefRatio" }; std::string mGoodChanFracHistName{ "RatesSignal/LastCycle/GoodChannelsFraction" }; - std::string mGoodChanFracRatioHistName{ "RatesSignal/LastCycle/GoodChannelsFractionRefRatio" }; int mMaxBadST12{ 2 }; int mMaxBadST345{ 3 }; double mMinRate{ 0.001 }; + std::array, 5> mMinRatePerStation; double mMaxRate{ 10 }; - double mMaxRateDelta{ 0.2 }; + std::array, 5> mMaxRatePerStation; double mMinGoodFraction{ 0.9 }; - double mMaxGoodFractionDelta{ 0.2 }; + std::array, 5> mMinGoodFractionPerStation; double mRatePlotScaleMin{ 0 }; double mRatePlotScaleMax{ 10 }; diff --git a/Modules/MUON/MCH/include/MCH/Helpers.h b/Modules/MUON/MCH/include/MCH/Helpers.h index a7ccfef89b..e44d340c4d 100644 --- a/Modules/MUON/MCH/include/MCH/Helpers.h +++ b/Modules/MUON/MCH/include/MCH/Helpers.h @@ -19,6 +19,7 @@ #include "QualityControl/DatabaseInterface.h" #include "QualityControl/Quality.h" +#include "QualityControl/CustomParameters.h" #include "MCHConstants/DetectionElements.h" #include #include @@ -28,6 +29,7 @@ #include #include #include +#include #include namespace o2::quality_control::core @@ -52,10 +54,18 @@ constexpr int getNumDE() { return (4 * 4 + 18 * 2 + 26 * 4); } int getNumDEinChamber(int chIndex); std::pair getDEindexInChamber(int deId); +void getThresholdsPerStation(o2::quality_control::core::CustomParameters customParameters, + const o2::quality_control::core::Activity& activity, + std::string parKey, + std::array, 5>& thresholds, + double& defaultThreshold); + o2::quality_control::core::Quality checkDetectorQuality(gsl::span& deQuality); void addChamberDelimiters(TH1F* h, float xmin = 0, float xmax = 0); void addChamberDelimiters(TH2F* h); +void drawThresholdsPerStation(TH1* histogram, const std::array, 5>& thresholdsPerStation, double defaultThreshold); +void addDEBinLabels(TH1* histogram); std::string getHistoPath(int deId); bool matchHistName(std::string hist, std::string name); diff --git a/Modules/MUON/MCH/include/MCH/PreclustersCheck.h b/Modules/MUON/MCH/include/MCH/PreclustersCheck.h index 9b2f3b773e..907c796ed5 100644 --- a/Modules/MUON/MCH/include/MCH/PreclustersCheck.h +++ b/Modules/MUON/MCH/include/MCH/PreclustersCheck.h @@ -53,12 +53,10 @@ class PreclustersCheck : public o2::quality_control::checker::CheckInterface std::string mMeanEffHistNameB{ "Efficiency/LastCycle/MeanEfficiencyB" }; std::string mMeanEffHistNameNB{ "Efficiency/LastCycle/MeanEfficiencyNB" }; - std::string mMeanEffRatioHistNameB{ "Efficiency/LastCycle/MeanEfficiencyRefRatioB" }; - std::string mMeanEffRatioHistNameNB{ "Efficiency/LastCycle/MeanEfficiencyRefRatioNB" }; int mMaxBadST12{ 2 }; int mMaxBadST345{ 3 }; double mMinEfficiency{ 0.8 }; - double mMaxEffDelta{ 0.2 }; + std::array, 5> mMinEfficiencyPerStation; double mPseudoeffPlotScaleMin{ 0.0 }; double mPseudoeffPlotScaleMax{ 1.0 }; diff --git a/Modules/MUON/MCH/src/DecodingCheck.cxx b/Modules/MUON/MCH/src/DecodingCheck.cxx index 65df7b8bb9..e7a7f46918 100644 --- a/Modules/MUON/MCH/src/DecodingCheck.cxx +++ b/Modules/MUON/MCH/src/DecodingCheck.cxx @@ -42,8 +42,8 @@ void DecodingCheck::startOfActivity(const Activity& activity) mGoodFracHistName = getConfigurationParameter(mCustomParameters, "GoodFracHistName", mGoodFracHistName, activity); mSyncFracHistName = getConfigurationParameter(mCustomParameters, "SyncFracHistName", mSyncFracHistName, activity); - mMinGoodErrorFrac = getConfigurationParameter(mCustomParameters, "MinGoodErrorFrac", mMinGoodErrorFrac, activity); - mMinGoodSyncFrac = getConfigurationParameter(mCustomParameters, "MinGoodSyncFrac", mMinGoodSyncFrac, activity); + getThresholdsPerStation(mCustomParameters, activity, "MinGoodErrorFrac", mMinGoodErrorFracPerStation, mMinGoodErrorFrac); + getThresholdsPerStation(mCustomParameters, activity, "MinGoodSyncFrac", mMinGoodSyncFracPerStation, mMinGoodSyncFrac); mMaxBadST12 = getConfigurationParameter(mCustomParameters, "MaxBadDE_ST12", mMaxBadST12, activity); mMaxBadST345 = getConfigurationParameter(mCustomParameters, "MaxBadDE_ST345", mMaxBadST345, activity); @@ -70,9 +70,24 @@ Quality DecodingCheck::check(std::map= 0 && stationId < 5) { + if (mMinGoodErrorFracPerStation[stationId]) { + minGoodErrorFrac = mMinGoodErrorFracPerStation[stationId].value(); + } + } + double val = h->GetBinContent(deId + 1); - if (val < mMinGoodErrorFrac) { + if (val < minGoodErrorFrac) { errorsQuality[deId] = Quality::Bad; } else { errorsQuality[deId] = Quality::Good; @@ -87,9 +102,24 @@ Quality DecodingCheck::check(std::map= 0 && stationId < 5) { + if (mMinGoodSyncFracPerStation[stationId]) { + minGoodSyncFrac = mMinGoodSyncFracPerStation[stationId].value(); + } + } + double val = h->GetBinContent(deId + 1); - if (val < mMinGoodSyncFrac) { + if (val < minGoodSyncFrac) { syncQuality[deId] = Quality::Bad; } else { syncQuality[deId] = Quality::Good; @@ -103,37 +133,8 @@ Quality DecodingCheck::check(std::mapGetTitle(); - title.Append(" "); - title.Append(suffix.c_str()); - hist->SetTitle(title); -} - -static std::string getCurrentTime() -{ - time_t t; - time(&t); - - struct tm* tmp; - tmp = localtime(&t); - - char timestr[500]; - strftime(timestr, sizeof(timestr), "(%d/%m/%Y - %R)", tmp); - - std::string result = timestr; - return result; -} - void DecodingCheck::beautify(std::shared_ptr mo, Quality checkResult) { - auto currentTime = getCurrentTime(); - updateTitle(dynamic_cast(mo->getObject()), currentTime); - if (mo->getName().find("DecodingErrorsPerDE") != std::string::npos) { auto* h = dynamic_cast(mo->getObject()); if (!h) { @@ -193,21 +194,22 @@ void DecodingCheck::beautify(std::shared_ptr mo, Quality checkRes h->GetYaxis()->SetTitle("good boards fraction"); addChamberDelimiters(h, scaleMin, scaleMax); + addDEBinLabels(h); - // draw horizontal limits - TLine* l = new TLine(0, mMinGoodErrorFrac, h->GetXaxis()->GetXmax(), mMinGoodErrorFrac); - l->SetLineColor(kBlue); - l->SetLineStyle(kDashed); - h->GetListOfFunctions()->Add(l); - - if (checkResult == Quality::Good) { - h->SetFillColor(kGreen); - } else if (checkResult == Quality::Bad) { - h->SetFillColor(kRed); - } else if (checkResult == Quality::Medium) { - h->SetFillColor(kOrange); + // only the plot used for the check is beautified by changing the color + // and adding the horizontal lines corresponding to the thresholds + if (matchHistName(mo->getName(), mGoodFracHistName)) { + if (checkResult == Quality::Good) { + h->SetFillColor(kGreen); + } else if (checkResult == Quality::Bad) { + h->SetFillColor(kRed); + } else if (checkResult == Quality::Medium) { + h->SetFillColor(kOrange); + } + h->SetLineColor(kBlack); + + drawThresholdsPerStation(h, mMinGoodErrorFracPerStation, mMinGoodErrorFrac); } - h->SetLineColor(kBlack); } if (mo->getName().find("SyncedBoardsFractionPerDE") != std::string::npos) { @@ -222,21 +224,22 @@ void DecodingCheck::beautify(std::shared_ptr mo, Quality checkRes h->SetMaximum(scaleMax); addChamberDelimiters(h, scaleMin, scaleMax); + addDEBinLabels(h); + + // only the plot used for the check is beautified by changing the color + // and adding the horizontal lines corresponding to the thresholds + if (matchHistName(mo->getName(), mSyncFracHistName)) { + if (checkResult == Quality::Good) { + h->SetFillColor(kGreen); + } else if (checkResult == Quality::Bad) { + h->SetFillColor(kRed); + } else if (checkResult == Quality::Medium) { + h->SetFillColor(kOrange); + } + h->SetLineColor(kBlack); - // draw horizontal limits - TLine* l = new TLine(0, mMinGoodSyncFrac, h->GetXaxis()->GetXmax(), mMinGoodSyncFrac); - l->SetLineColor(kBlue); - l->SetLineStyle(kDashed); - h->GetListOfFunctions()->Add(l); - - if (checkResult == Quality::Good) { - h->SetFillColor(kGreen); - } else if (checkResult == Quality::Bad) { - h->SetFillColor(kRed); - } else if (checkResult == Quality::Medium) { - h->SetFillColor(kOrange); + drawThresholdsPerStation(h, mMinGoodSyncFracPerStation, mMinGoodSyncFrac); } - h->SetLineColor(kBlack); } } diff --git a/Modules/MUON/MCH/src/DigitsCheck.cxx b/Modules/MUON/MCH/src/DigitsCheck.cxx index 1ce6de82c2..4ee43ffb5a 100644 --- a/Modules/MUON/MCH/src/DigitsCheck.cxx +++ b/Modules/MUON/MCH/src/DigitsCheck.cxx @@ -17,6 +17,7 @@ #include "MCH/DigitsCheck.h" #include "MUONCommon/Helpers.h" #include "QualityControl/MonitorObject.h" +#include "QualityControl/QcInfoLogger.h" // ROOT #include @@ -40,21 +41,18 @@ void DigitsCheck::configure() void DigitsCheck::startOfActivity(const Activity& activity) { mMeanRateHistName = getConfigurationParameter(mCustomParameters, "MeanRateHistName", mMeanRateHistName, activity); - mMeanRateRatioHistName = getConfigurationParameter(mCustomParameters, "MeanRateRatioHistName", mMeanRateRatioHistName, activity); mGoodChanFracHistName = getConfigurationParameter(mCustomParameters, "GoodChanFracHistName", mGoodChanFracHistName, activity); - mGoodChanFracRatioHistName = getConfigurationParameter(mCustomParameters, "GoodChanFracRatioHistName", mGoodChanFracRatioHistName, activity); - mMinRate = getConfigurationParameter(mCustomParameters, "MinRate", mMinRate, activity); - mMaxRate = getConfigurationParameter(mCustomParameters, "MaxRate", mMaxRate, activity); - mMaxRateDelta = getConfigurationParameter(mCustomParameters, "MaxRateDelta", mMaxRateDelta, activity); - mMinGoodFraction = getConfigurationParameter(mCustomParameters, "MinGoodFraction", mMinGoodFraction, activity); - mMaxGoodFractionDelta = getConfigurationParameter(mCustomParameters, "MaxGoodFractionDelta", mMaxGoodFractionDelta, activity); - mRatePlotScaleMin = getConfigurationParameter(mCustomParameters, "RatePlotScaleMin", mRatePlotScaleMin, activity); - mRatePlotScaleMax = getConfigurationParameter(mCustomParameters, "RatePlotScaleMax", mRatePlotScaleMax, activity); + getThresholdsPerStation(mCustomParameters, activity, "MinRate", mMinRatePerStation, mMinRate); + getThresholdsPerStation(mCustomParameters, activity, "MaxRate", mMaxRatePerStation, mMaxRate); + getThresholdsPerStation(mCustomParameters, activity, "MinGoodFraction", mMinGoodFractionPerStation, mMinGoodFraction); mMaxBadST12 = getConfigurationParameter(mCustomParameters, "MaxBadDE_ST12", mMaxBadST12, activity); mMaxBadST345 = getConfigurationParameter(mCustomParameters, "MaxBadDE_ST345", mMaxBadST345, activity); + mRatePlotScaleMin = getConfigurationParameter(mCustomParameters, "RatePlotScaleMin", mRatePlotScaleMin, activity); + mRatePlotScaleMax = getConfigurationParameter(mCustomParameters, "RatePlotScaleMax", mRatePlotScaleMax, activity); + mQualityChecker.mMaxBadST12 = mMaxBadST12; mQualityChecker.mMaxBadST345 = mMaxBadST345; } @@ -68,7 +66,6 @@ std::array checkPlot(TH1F* h, Lambda check) for (auto de : o2::mch::constants::deIdsForAllMCH) { int chamberId = (de - 100) / 100; int stationId = chamberId / 2; - int chamberIdInStation = chamberId % 2; int deId = getDEindex(de); if (deId < 0) { @@ -77,7 +74,7 @@ std::array checkPlot(TH1F* h, Lambda check) int bin = deId + 1; double val = h->GetBinContent(bin); - if (check(val)) { + if (check(val, stationId)) { result[deId] = Quality::Good; } else { result[deId] = Quality::Bad; @@ -89,22 +86,34 @@ std::array checkPlot(TH1F* h, Lambda check) std::array DigitsCheck::checkMeanRates(TH1F* h) { - return checkPlot(h, [&](double val) -> bool { return (val >= mMinRate && val <= mMaxRate); }); -} - -std::array DigitsCheck::checkMeanRatesRatio(TH1F* h) -{ - return checkPlot(h, [&](double val) -> bool { return (std::abs(val - 1) <= mMaxRateDelta); }); + auto checkFunction = [&](double val, int station) -> bool { + auto minRate = mMinRate; + auto maxRate = mMaxRate; + if (station >= 0 && station < 5) { + if (mMinRatePerStation[station]) { + minRate = mMinRatePerStation[station].value(); + } + if (mMaxRatePerStation[station]) { + maxRate = mMaxRatePerStation[station].value(); + } + } + return (val >= minRate && val <= maxRate); + }; + return checkPlot(h, checkFunction); } std::array DigitsCheck::checkBadChannels(TH1F* h) { - return checkPlot(h, [&](double val) -> bool { return (val >= mMinGoodFraction); }); -} - -std::array DigitsCheck::checkBadChannelsRatio(TH1F* h) -{ - return checkPlot(h, [&](double val) -> bool { return (std::abs(val - 1) <= mMaxGoodFractionDelta); }); + auto checkFunction = [&](double val, int station) -> bool { + auto minGoodFraction = mMinGoodFraction; + if (station >= 0 && station < 5) { + if (mMinGoodFractionPerStation[station]) { + minGoodFraction = mMinGoodFractionPerStation[station].value(); + } + } + return (val >= minGoodFraction); + }; + return checkPlot(h, checkFunction); } template @@ -153,14 +162,6 @@ Quality DigitsCheck::check(std::map> } } - if (matchHistName(mo->getName(), mMeanRateRatioHistName)) { - TH1F* h = getHisto(mo); - if (h && h->GetEntries() > 0) { - auto q = checkMeanRatesRatio(h); - mQualityChecker.addCheckResult(q); - } - } - if (matchHistName(mo->getName(), mGoodChanFracHistName)) { TH1F* h = getHisto(mo); if (h) { @@ -168,14 +169,6 @@ Quality DigitsCheck::check(std::map> mQualityChecker.addCheckResult(q); } } - - if (matchHistName(mo->getName(), mGoodChanFracRatioHistName)) { - TH1F* h = getHisto(mo); - if (h && h->GetEntries() > 0) { - auto q = checkBadChannelsRatio(h); - mQualityChecker.addCheckResult(q); - } - } } return mQualityChecker.getQuality(); @@ -194,43 +187,8 @@ static void updateTitle(TH1* hist, std::string suffix) hist->SetTitle(title); } -static void updateTitle(TCanvas* c, std::string suffix) -{ - if (!c) { - return; - } - - TObject* obj; - TIter next(c->GetListOfPrimitives()); - while ((obj = next())) { - if (obj->InheritsFrom("TH1")) { - TH1* hist = dynamic_cast(obj); - updateTitle(hist, suffix); - } - } -} - -static std::string getCurrentTime() -{ - time_t t; - time(&t); - - struct tm* tmp; - tmp = localtime(&t); - - char timestr[500]; - strftime(timestr, sizeof(timestr), "(%d/%m/%Y - %R)", tmp); - - std::string result = timestr; - return result; -} - void DigitsCheck::beautify(std::shared_ptr mo, Quality checkResult) { - auto currentTime = getCurrentTime(); - updateTitle(dynamic_cast(mo->getObject()), currentTime); - updateTitle(dynamic_cast(mo->getObject()), currentTime); - if (mo->getName().find("Occupancy_Elec") != std::string::npos || mo->getName().find("OccupancySignal_Elec") != std::string::npos) { auto* h = dynamic_cast(mo->getObject()); @@ -268,61 +226,30 @@ void DigitsCheck::beautify(std::shared_ptr mo, Quality checkResul return; } - float scaleMin{ 0 }; - float scaleMax{ 0 }; - if (mo->getName().find("MeanRateRefRatio") != std::string::npos) { - scaleMin = 1.0 - mMaxRateDelta * 2.0; - scaleMax = 1.0 + mMaxRateDelta * 2.0; - h->GetYaxis()->SetTitle("rate / reference"); - } else { - scaleMin = mRatePlotScaleMin; - scaleMax = mRatePlotScaleMax; - h->GetYaxis()->SetTitle("rate (kHz)"); - } + double scaleMin{ mRatePlotScaleMin }; + double scaleMax{ mRatePlotScaleMax }; h->SetMinimum(scaleMin); h->SetMaximum(scaleMax); + h->GetYaxis()->SetTitle("rate (kHz)"); addChamberDelimiters(h, scaleMin, scaleMax); + addDEBinLabels(h); - if (mo->getName().find("MeanRateRefRatio") != std::string::npos) { - // draw horizontal limits - TLine* l = new TLine(0, 1, h->GetXaxis()->GetXmax(), 1); - l->SetLineColor(kBlack); - l->SetLineStyle(kDotted); - h->GetListOfFunctions()->Add(l); - - if (h->GetEntries() > 0) { - l = new TLine(0, 1.0 - mMaxRateDelta, h->GetXaxis()->GetXmax(), 1.0 - mMaxRateDelta); - l->SetLineColor(kBlue); - l->SetLineStyle(kDashed); - h->GetListOfFunctions()->Add(l); - - l = new TLine(0, 1.0 + mMaxRateDelta, h->GetXaxis()->GetXmax(), 1.0 + mMaxRateDelta); - l->SetLineColor(kBlue); - l->SetLineStyle(kDashed); - h->GetListOfFunctions()->Add(l); + // only the plot used for the check is beautified by changing the color + // and adding the horizontal lines corresponding to the thresholds + if (matchHistName(mo->getName(), mMeanRateHistName)) { + if (checkResult == Quality::Good) { + h->SetFillColor(kGreen); + } else if (checkResult == Quality::Bad) { + h->SetFillColor(kRed); + } else if (checkResult == Quality::Medium) { + h->SetFillColor(kOrange); } - } else { - // draw horizontal limits - TLine* l = new TLine(0, mMinRate, h->GetXaxis()->GetXmax(), mMinRate); - l->SetLineColor(kBlue); - l->SetLineStyle(kDashed); - h->GetListOfFunctions()->Add(l); - - l = new TLine(0, mMaxRate, h->GetXaxis()->GetXmax(), mMaxRate); - l->SetLineColor(kBlue); - l->SetLineStyle(kDashed); - h->GetListOfFunctions()->Add(l); - } + h->SetLineColor(kBlack); - if (checkResult == Quality::Good) { - h->SetFillColor(kGreen); - } else if (checkResult == Quality::Bad) { - h->SetFillColor(kRed); - } else if (checkResult == Quality::Medium) { - h->SetFillColor(kOrange); + drawThresholdsPerStation(h, mMinRatePerStation, mMinRate); + drawThresholdsPerStation(h, mMaxRatePerStation, mMaxRate); } - h->SetLineColor(kBlack); } if (mo->getName().find("GoodChannelsFraction") != std::string::npos) { @@ -332,55 +259,28 @@ void DigitsCheck::beautify(std::shared_ptr mo, Quality checkResul } float scaleMin{ 0 }; - float scaleMax{ 0 }; - if (mo->getName().find("GoodChannelsFractionRefRatio") != std::string::npos) { - scaleMin = 1.0 - mMaxGoodFractionDelta * 2.0; - scaleMax = 1.0 + mMaxGoodFractionDelta * 2.0; - h->GetYaxis()->SetTitle("fraction / reference"); - } else { - scaleMin = 0; - scaleMax = 1.05; - h->GetYaxis()->SetTitle("fraction"); - } + float scaleMax{ 1.05 }; h->SetMinimum(scaleMin); h->SetMaximum(scaleMax); + h->GetYaxis()->SetTitle("fraction"); addChamberDelimiters(h, scaleMin, scaleMax); + addDEBinLabels(h); - if (mo->getName().find("GoodChannelsFractionRefRatio") != std::string::npos) { - // draw horizontal limits - TLine* l = new TLine(0, 1, h->GetXaxis()->GetXmax(), 1); - l->SetLineColor(kBlack); - l->SetLineStyle(kDotted); - h->GetListOfFunctions()->Add(l); - - if (h->GetEntries() > 0) { - l = new TLine(0, 1.0 - mMaxGoodFractionDelta, h->GetXaxis()->GetXmax(), 1.0 - mMaxGoodFractionDelta); - l->SetLineColor(kBlue); - l->SetLineStyle(kDashed); - h->GetListOfFunctions()->Add(l); - - l = new TLine(0, 1.0 + mMaxGoodFractionDelta, h->GetXaxis()->GetXmax(), 1.0 + mMaxGoodFractionDelta); - l->SetLineColor(kBlue); - l->SetLineStyle(kDashed); - h->GetListOfFunctions()->Add(l); + // only the plot used for the check is beautified by changing the color + // and adding the horizontal lines corresponding to the thresholds + if (matchHistName(mo->getName(), mGoodChanFracHistName)) { + if (checkResult == Quality::Good) { + h->SetFillColor(kGreen); + } else if (checkResult == Quality::Bad) { + h->SetFillColor(kRed); + } else if (checkResult == Quality::Medium) { + h->SetFillColor(kOrange); } - } else { - // draw horizontal limits - TLine* l = new TLine(0, mMinGoodFraction, h->GetXaxis()->GetXmax(), mMinGoodFraction); - l->SetLineColor(kBlue); - l->SetLineStyle(kDashed); - h->GetListOfFunctions()->Add(l); - } + h->SetLineColor(kBlack); - if (checkResult == Quality::Good) { - h->SetFillColor(kGreen); - } else if (checkResult == Quality::Bad) { - h->SetFillColor(kRed); - } else if (checkResult == Quality::Medium) { - h->SetFillColor(kOrange); + drawThresholdsPerStation(h, mMinGoodFractionPerStation, mMinGoodFraction); } - h->SetLineColor(kBlack); } // update quality flags for each DE @@ -391,6 +291,7 @@ void DigitsCheck::beautify(std::shared_ptr mo, Quality checkResul } addChamberDelimiters(h); + addDEBinLabels(h); for (int deId = 0; deId < mQualityChecker.mQuality.size(); deId++) { float ybin = 0; diff --git a/Modules/MUON/MCH/src/Helpers.cxx b/Modules/MUON/MCH/src/Helpers.cxx index 34f1fded51..9334a6d1a3 100644 --- a/Modules/MUON/MCH/src/Helpers.cxx +++ b/Modules/MUON/MCH/src/Helpers.cxx @@ -18,6 +18,8 @@ #include "QualityControl/MonitorObject.h" #include "QualityControl/QualityObject.h" #include "QualityControl/ObjectMetadataKeys.h" +#include "QualityControl/QcInfoLogger.h" +#include "Common/Utils.h" #include "MCHRawElecMap/Mapper.h" #include #include @@ -149,6 +151,29 @@ int getDEindex(int deId) //_________________________________________________________________________________________ +void getThresholdsPerStation(o2::quality_control::core::CustomParameters customParameters, + const o2::quality_control::core::Activity& activity, + std::string parKey, + std::array, 5>& thresholds, + double& defaultThreshold) +{ + defaultThreshold = common::getFromExtendedConfig(activity, customParameters, parKey, defaultThreshold); + + for (int stationIndex = 0; stationIndex < 5; stationIndex++) { + auto parKeyForStation = parKey + ":ST" + std::to_string(stationIndex + 1); + auto parValue = common::getFromExtendedConfig(activity, customParameters, parKeyForStation, ""); + if (!parValue.empty()) { + try { + thresholds[stationIndex] = std::stod(parValue); + } catch (std::exception& exception) { + ILOG(Error, Support) << "Cannot convert value for key \"" << parKey << "\" to double, string is " << parValue << ENDM; + } + } + } +} + +//_________________________________________________________________________________________ + QualityChecker::QualityChecker() { for (auto de : o2::mch::constants::deIdsForAllMCH) { @@ -383,6 +408,40 @@ void addChamberDelimiters(TH2F* h) //_________________________________________________________________________________________ +void drawThresholdsPerStation(TH1* histogram, const std::array, 5>& thresholdsPerStation, double defaultThreshold) +{ + double xmin = 0; + double xmax = 0; + for (int stationIndex = 0; stationIndex < 5; stationIndex++) { + // draw threshold line for this station + double threshold = defaultThreshold; + if (thresholdsPerStation[stationIndex]) { + threshold = thresholdsPerStation[stationIndex].value(); + } + xmax = static_cast(getChamberOffset((stationIndex + 1) * 2)); + + TLine* l = new TLine(xmin, threshold, xmax, threshold); + l->SetLineColor(kBlue); + l->SetLineStyle(kDashed); + histogram->GetListOfFunctions()->Add(l); + + xmin = xmax; + } +} + +//_________________________________________________________________________________________ + +void addDEBinLabels(TH1* histogram) +{ + for (auto de : o2::mch::constants::deIdsForAllMCH) { + int bin = getDEindex(de) + 1; + auto binLabel = std::string("DE") + std::to_string(de); + histogram->GetXaxis()->SetBinLabel(bin, binLabel.c_str()); + } +} + +//_________________________________________________________________________________________ + void splitDataSourceName(std::string s, std::string& type, std::string& name) { std::string delimiter = ":"; diff --git a/Modules/MUON/MCH/src/PreclustersCheck.cxx b/Modules/MUON/MCH/src/PreclustersCheck.cxx index 3265179cfc..29a5c259c7 100644 --- a/Modules/MUON/MCH/src/PreclustersCheck.cxx +++ b/Modules/MUON/MCH/src/PreclustersCheck.cxx @@ -40,15 +40,13 @@ void PreclustersCheck::configure() void PreclustersCheck::startOfActivity(const Activity& activity) { - mMinEfficiency = getConfigurationParameter(mCustomParameters, "MinEfficiency", mMinEfficiency, activity); - mMaxEffDelta = getConfigurationParameter(mCustomParameters, "MaxEfficiencyDelta", mMaxEffDelta, activity); + getThresholdsPerStation(mCustomParameters, activity, "MinEfficiency", mMinEfficiencyPerStation, mMinEfficiency); + mPseudoeffPlotScaleMin = getConfigurationParameter(mCustomParameters, "PseudoeffPlotScaleMin", mPseudoeffPlotScaleMin, activity); mPseudoeffPlotScaleMax = getConfigurationParameter(mCustomParameters, "PseudoeffPlotScaleMax", mPseudoeffPlotScaleMax, activity); mMeanEffHistNameB = getConfigurationParameter(mCustomParameters, "MeanEffHistNameB", mMeanEffHistNameB, activity); mMeanEffHistNameNB = getConfigurationParameter(mCustomParameters, "MeanEffHistNameNB", mMeanEffHistNameNB, activity); - mMeanEffRatioHistNameB = getConfigurationParameter(mCustomParameters, "MeanEffRatioHistNameB", mMeanEffRatioHistNameB, activity); - mMeanEffRatioHistNameNB = getConfigurationParameter(mCustomParameters, "MeanEffRatioHistNameNB", mMeanEffRatioHistNameNB, activity); mMaxBadST12 = getConfigurationParameter(mCustomParameters, "MaxBadDE_ST12", mMaxBadST12, activity); mMaxBadST345 = getConfigurationParameter(mCustomParameters, "MaxBadDE_ST345", mMaxBadST345, activity); @@ -98,7 +96,6 @@ std::array checkPlot(TH1F* h, Lambda check) for (auto de : o2::mch::constants::deIdsForAllMCH) { int chamberId = (de - 100) / 100; int stationId = chamberId / 2; - int chamberIdInStation = chamberId % 2; int deId = getDEindex(de); if (deId < 0) { @@ -107,7 +104,7 @@ std::array checkPlot(TH1F* h, Lambda check) int bin = deId + 1; double val = h->GetBinContent(bin); - if (check(val)) { + if (check(val, stationId)) { result[deId] = Quality::Good; } else { result[deId] = Quality::Bad; @@ -119,12 +116,16 @@ std::array checkPlot(TH1F* h, Lambda check) std::array PreclustersCheck::checkMeanEfficiencies(TH1F* h) { - return checkPlot(h, [&](double val) -> bool { return (val >= mMinEfficiency); }); -} - -std::array PreclustersCheck::checkMeanEfficienciesRatio(TH1F* h) -{ - return checkPlot(h, [&](double val) -> bool { return (std::abs(val - 1) <= mMaxEffDelta); }); + auto checkFunction = [&](double val, int station) -> bool { + auto minEfficiency = mMinEfficiency; + if (station >= 0 && station < 5) { + if (mMinEfficiencyPerStation[station]) { + minEfficiency = mMinEfficiencyPerStation[station].value(); + } + } + return (val >= minEfficiency); + }; + return checkPlot(h, checkFunction); } Quality PreclustersCheck::check(std::map>* moMap) @@ -146,14 +147,6 @@ Quality PreclustersCheck::check(std::mapgetName(), mMeanEffRatioHistNameB) || matchHistName(mo->getName(), mMeanEffRatioHistNameNB)) { - TH1F* h = getHisto(mo); - if (h && h->GetEntries() > 0) { - auto q = checkMeanEfficienciesRatio(h); - mQualityChecker.addCheckResult(q); - } - } } return mQualityChecker.getQuality(); @@ -161,67 +154,18 @@ Quality PreclustersCheck::check(std::mapGetTitle(); - title.Append(" "); - title.Append(suffix.c_str()); - hist->SetTitle(title); -} - -static void updateTitle(TCanvas* c, std::string suffix) -{ - if (!c) { - return; - } - - TObject* obj; - TIter next(c->GetListOfPrimitives()); - while ((obj = next())) { - if (obj->InheritsFrom("TH1")) { - TH1* hist = dynamic_cast(obj); - updateTitle(hist, suffix); - } - } -} - -static std::string getCurrentTime() -{ - time_t t; - time(&t); - - struct tm* tmp; - tmp = localtime(&t); - - char timestr[500]; - strftime(timestr, sizeof(timestr), "(%d/%m/%Y - %R)", tmp); - - std::string result = timestr; - return result; -} - void PreclustersCheck::beautify(std::shared_ptr mo, Quality checkResult) { - auto currentTime = getCurrentTime(); - updateTitle(dynamic_cast(mo->getObject()), currentTime); - updateTitle(dynamic_cast(mo->getObject()), currentTime); - if ((mo->getName().find("ChargeMPV") != std::string::npos)) { TH1F* h = getHisto(mo); if (!h) { return; } - if ((mo->getName().find("ChargeMPVRefRatio") != std::string::npos)) { - h->SetMinimum(0.5); - h->SetMaximum(1.5); - } else { - h->SetMinimum(0); - h->SetMaximum(2000); - } + + h->SetMinimum(0); + h->SetMaximum(2000); addChamberDelimiters(h, h->GetMinimum(), h->GetMaximum()); + addDEBinLabels(h); } if ((mo->getName().find("MeanClusterSize") != std::string::npos)) { @@ -229,14 +173,11 @@ void PreclustersCheck::beautify(std::shared_ptr mo, Quality check if (!h) { return; } - if ((mo->getName().find("MeanClusterSizeRefRatio") != std::string::npos)) { - h->SetMinimum(0.8); - h->SetMaximum(1.2); - } else { - h->SetMinimum(0); - h->SetMaximum(20); - } + + h->SetMinimum(0); + h->SetMaximum(20); addChamberDelimiters(h, h->GetMinimum(), h->GetMaximum()); + addDEBinLabels(h); } if ((mo->getName().find("MeanEfficiency") != std::string::npos) || @@ -251,42 +192,17 @@ void PreclustersCheck::beautify(std::shared_ptr mo, Quality check (mo->getName().find("MeanEfficiencyNB") != std::string::npos)) { h->SetMinimum(mPseudoeffPlotScaleMin); h->SetMaximum(1.2); - - // draw horizontal limits - TLine* l = new TLine(0, mMinEfficiency, h->GetXaxis()->GetXmax(), mMinEfficiency); - l->SetLineColor(kBlue); - l->SetLineStyle(kDashed); - h->GetListOfFunctions()->Add(l); - } else if ((mo->getName().find("MeanEfficiencyRefRatio") != std::string::npos)) { - h->SetMinimum(1.0 - mMaxEffDelta * 2.0); - h->SetMaximum(1.0 + mMaxEffDelta * 2.0); - - // draw horizontal limits - TLine* l = new TLine(0, 1, h->GetXaxis()->GetXmax(), 1); - l->SetLineColor(kBlack); - l->SetLineStyle(kDotted); - h->GetListOfFunctions()->Add(l); - - if (h->GetEntries() > 0) { - l = new TLine(0, 1.0 - mMaxEffDelta, h->GetXaxis()->GetXmax(), 1.0 - mMaxEffDelta); - l->SetLineColor(kBlue); - l->SetLineStyle(kDashed); - h->GetListOfFunctions()->Add(l); - - l = new TLine(0, 1.0 + mMaxEffDelta, h->GetXaxis()->GetXmax(), 1.0 + mMaxEffDelta); - l->SetLineColor(kBlue); - l->SetLineStyle(kDashed); - h->GetListOfFunctions()->Add(l); - } } else { h->SetMinimum(0); h->SetMaximum(1.05 * h->GetMaximum()); } + addChamberDelimiters(h, h->GetMinimum(), h->GetMaximum()); + addDEBinLabels(h); - if ((mo->getName().find("MeanEfficiencyB") != std::string::npos) || - (mo->getName().find("MeanEfficiencyNB") != std::string::npos) || - (mo->getName().find("MeanEfficiencyRefRatio") != std::string::npos)) { + // only the plot used for the check is beautified by changing the color + // and adding the horizontal lines corresponding to the thresholds + if (matchHistName(mo->getName(), mMeanEffHistNameB) || matchHistName(mo->getName(), mMeanEffHistNameNB)) { if (checkResult == Quality::Good) { h->SetFillColor(kGreen); } else if (checkResult == Quality::Bad) { @@ -295,6 +211,8 @@ void PreclustersCheck::beautify(std::shared_ptr mo, Quality check h->SetFillColor(kOrange); } h->SetLineColor(kBlack); + + drawThresholdsPerStation(h, mMinEfficiencyPerStation, mMinEfficiency); } }