Skip to content

Commit 1a681cd

Browse files
[FDD] New histograms and checkers for FDD (#1749)
* [FDD] (1) Histogram to check the Charge saturation and checker implemaentation (2) Checkers for the SW and HW triggers (3) Add DeadChannelMap to GenericCheck (4) Add EventsInGateTime2ch histogram * Protection against empty reasons in beautify function * correct path for the deadChannel map * Avoid having null pointer for dead channel map --------- Co-authored-by: Arvind Khuntia <arvind.khuntia@cern.ch>
1 parent 942af11 commit 1a681cd

12 files changed

Lines changed: 380 additions & 23 deletions

Modules/FIT/FDD/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ target_sources(O2QcFDD PRIVATE
1010
src/PostProcTask.cxx
1111
src/CFDEffCheck.cxx
1212
src/OutOfBunchCollCheck.cxx
13+
src/TriggersSwVsTcmCheck.cxx
1314
)
1415

1516
target_include_directories(
@@ -35,6 +36,7 @@ add_root_dictionary(O2QcFDD
3536
include/FDD/PostProcTask.h
3637
include/FDD/CFDEffCheck.h
3738
include/FDD/OutOfBunchCollCheck.h
39+
include/FDD/TriggersSwVsTcmCheck.h
3840
LINKDEF include/FDD/LinkDef.h)
3941

4042
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/FDD

Modules/FIT/FDD/include/FDD/CFDEffCheck.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
///
1313
/// \file CFDEffCheck.h
1414
/// \author Sebastian Bysiak sbysiak@cern.ch
15-
///
15+
/// LATEST modification for FDD on 25.04.2023 (akhuntia@cern.ch)
1616

1717
#ifndef QC_MODULE_FDD_FDDCFDEFFCHECK_H
1818
#define QC_MODULE_FDD_FDDCFDEFFCHECK_H

Modules/FIT/FDD/include/FDD/DigitQcTask.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
///
1313
/// \file DigitQcTask.h
1414
/// \author Artur Furs afurs@cern.ch
15-
/// LATEST modification for FDD on 24.05.2022 (akhuntia@cern.ch)
15+
/// LATEST modification for FDD on 25.04.2023 (akhuntia@cern.ch)
1616

1717
#ifndef QC_MODULE_FDD_FDDDIGITQCTASK_H
1818
#define QC_MODULE_FDD_FDDDIGITQCTASK_H
@@ -70,7 +70,6 @@ class DigitQcTask final : public TaskInterface
7070
constexpr static std::size_t sNCHANNELS_C = 8;
7171
constexpr static std::size_t sOrbitsPerTF = 256;
7272
constexpr static std::size_t sBCperOrbit = o2::constants::lhc::LHCMaxBunches;
73-
7473
constexpr static float sCFDChannel2NS = o2::fdd::timePerTDC; // CFD channel width in ns
7574

7675
private:
@@ -84,8 +83,9 @@ class DigitQcTask final : public TaskInterface
8483
double mTimeCurNS = 0.;
8584
int mTfCounter = 0;
8685
double mTimeSum = 0.;
87-
8886
long mTFcreationTime = 0;
87+
int mMinTimeGate = -192;
88+
int mMaxTimeGate = 192;
8989

9090
template <typename Param_t,
9191
typename = typename std::enable_if<std::is_floating_point<Param_t>::value ||
@@ -154,6 +154,8 @@ class DigitQcTask final : public TaskInterface
154154
int mTrgChargeLevelLow;
155155
int mTrgChargeLevelHigh;
156156
int mTrgOrGate;
157+
int mBinMinADCSaturationCheck;
158+
int mBinMaxADCSaturationCheck;
157159

158160
// Object which will be published
159161
std::unique_ptr<TH2F> mHist2CorrTCMchAndPMch;
@@ -173,6 +175,8 @@ class DigitQcTask final : public TaskInterface
173175
std::unique_ptr<TH1F> mHistAverageTimeC;
174176
std::unique_ptr<TH1F> mHistChannelID;
175177
std::unique_ptr<TH1F> mHistCFDEff;
178+
std::unique_ptr<TH1F> mHistGateTimeRatio2Ch;
179+
std::unique_ptr<TH1F> mHistSaturationFraction;
176180
std::unique_ptr<TH2F> mHistTimeSum2Diff;
177181
std::unique_ptr<TH2F> mHistTriggersCorrelation;
178182
std::unique_ptr<TH1D> mHistCycleDuration;

Modules/FIT/FDD/include/FDD/GenericCheck.h

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,18 @@
1212
///
1313
/// \file GenericCheck.h
1414
/// \author Sebastian Bysiak
15-
///
15+
/// LATEST modification for FDD on 25.04.2023 (akhuntia@cern.ch)
1616

1717
#ifndef QC_MODULE_FDD_FDDGENERICCHECK_H
1818
#define QC_MODULE_FDD_FDDGENERICCHECK_H
1919

2020
#include "QualityControl/CheckInterface.h"
2121
#include <DataFormatsQualityControl/FlagReasons.h>
22+
#include "DataFormatsFIT/DeadChannelMap.h"
23+
#include <DataFormatsQualityControl/FlagReasons.h>
2224

2325
namespace o2::quality_control_modules::fdd
2426
{
25-
2627
/// \brief helper class to store acceptable limits for given quantity
2728
/// \author Sebastian Bysiak
2829
class SingleCheck
@@ -38,6 +39,7 @@ class SingleCheck
3839
mThresholdError = thresholdError;
3940
mShouldBeLower = shouldBeLower;
4041
mIsActive = isActive;
42+
mBinNumberX = 0;
4143
};
4244
bool isActive() { return mIsActive; };
4345

@@ -47,16 +49,17 @@ class SingleCheck
4749
return;
4850

4951
std::string log = Form("%s : comparing value = %f with thresholds = %f, %f", mCheckName.c_str(), checkedValue, mThresholdWarning, mThresholdError);
52+
std::string reason;
5053
if (mShouldBeLower) {
5154
if (checkedValue > mThresholdError) {
5255
if (result.isBetterThan(Quality::Bad))
5356
result.set(Quality::Bad);
54-
result.addReason(o2::quality_control::FlagReasonFactory::Unknown(), Form("%.3f > %.3f (%s error limit)", checkedValue, mThresholdError, mCheckName.c_str()));
57+
reason = Form("%.3f > %.3f (%s error limit)", checkedValue, mThresholdError, mCheckName.c_str());
5558
log += "-> Bad";
5659
} else if (checkedValue > mThresholdWarning) {
5760
if (result.isBetterThan(Quality::Medium))
5861
result.set(Quality::Medium);
59-
result.addReason(o2::quality_control::FlagReasonFactory::Unknown(), Form("%.3f > %.3f (%s warning limit)", checkedValue, mThresholdWarning, mCheckName.c_str()));
62+
reason = Form("%.3f > %.3f (%s warning limit)", checkedValue, mThresholdWarning, mCheckName.c_str());
6063
log += "-> Medium";
6164
} else {
6265
log += "-> OK";
@@ -65,19 +68,37 @@ class SingleCheck
6568
if (checkedValue < mThresholdError) {
6669
if (result.isBetterThan(Quality::Bad))
6770
result.set(Quality::Bad);
68-
result.addReason(o2::quality_control::FlagReasonFactory::Unknown(), Form("%.3f < %.3f (%s error limit)", checkedValue, mThresholdError, mCheckName.c_str()));
71+
reason = Form("%.3f < %.3f (%s error limit)", checkedValue, mThresholdError, mCheckName.c_str());
6972
log += "-> Bad";
7073
} else if (checkedValue < mThresholdWarning) {
7174
if (result.isBetterThan(Quality::Medium))
7275
result.set(Quality::Medium);
73-
result.addReason(o2::quality_control::FlagReasonFactory::Unknown(), Form("%.3f < %.3f (%s warning limit)", checkedValue, mThresholdWarning, mCheckName.c_str()));
76+
reason = Form("%.3f < %.3f (%s warning limit)", checkedValue, mThresholdWarning, mCheckName.c_str());
7477
log += "-> Medium";
7578
} else {
7679
log += "-> OK";
7780
}
7881
}
82+
if (reason.length()) {
83+
if (mBinNumberX) {
84+
reason += Form(" for channel %d", mBinNumberX);
85+
}
86+
result.addReason(o2::quality_control::FlagReasonFactory::Unknown(), reason);
87+
}
88+
7989
ILOG(Debug, Support) << log << ENDM;
8090
}
91+
float getThresholdWarning()
92+
{
93+
return mThresholdWarning;
94+
}
95+
float getThresholdError()
96+
{
97+
return mThresholdError;
98+
}
99+
100+
public:
101+
int mBinNumberX;
81102

82103
private:
83104
std::string mCheckName;
@@ -107,7 +128,8 @@ class GenericCheck : public o2::quality_control::checker::CheckInterface
107128

108129
private:
109130
SingleCheck getCheckFromConfig(std::string);
110-
131+
SingleCheck mCheckMinThresholdY;
132+
SingleCheck mCheckMaxThresholdY;
111133
SingleCheck mCheckMaxOverflowIntegralRatio;
112134

113135
SingleCheck mCheckMinMeanX;
@@ -123,6 +145,11 @@ class GenericCheck : public o2::quality_control::checker::CheckInterface
123145

124146
std::array<double, 4> mPositionMsgBox;
125147
std::string mNameObjOnCanvas;
148+
149+
constexpr static std::size_t sNCHANNELSPhy = 16;
150+
o2::fit::DeadChannelMap* mDeadChannelMap;
151+
std::string mDeadChannelMapStr;
152+
std::string mPathDeadChannelMap;
126153
};
127154

128155
} // namespace o2::quality_control_modules::fdd

Modules/FIT/FDD/include/FDD/LinkDef.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@
1010
#pragma link C++ class o2::quality_control_modules::fdd::PostProcTask + ;
1111
#pragma link C++ class o2::quality_control_modules::fdd::CFDEffCheck + ;
1212
#pragma link C++ class o2::quality_control_modules::fdd::OutOfBunchCollCheck + ;
13+
#pragma link C++ class o2::quality_control_modules::fdd::TriggersSwVsTcmCheck + ;
1314
#endif
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2023 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
///
13+
/// \file TriggersSwVsTcmCheck.h
14+
/// \author Dawid Skora dawid.mateusz.skora@cern.ch
15+
/// \Modification for FDD by arvind.khuntia@cern.ch (25.04.2023)
16+
17+
#ifndef QC_MODULE_FDD_TRIGGERSSWVSTCMCHECK_H
18+
#define QC_MODULE_FDD_TRIGGERSSWVSTCMCHECK_H
19+
20+
#include "QualityControl/CheckInterface.h"
21+
#include "FV0Base/Constants.h"
22+
23+
namespace o2::quality_control_modules::fdd
24+
{
25+
class TriggersSwVsTcmCheck : public o2::quality_control::checker::CheckInterface
26+
{
27+
public:
28+
TriggersSwVsTcmCheck() = default;
29+
~TriggersSwVsTcmCheck() override = default;
30+
31+
void configure() override;
32+
Quality check(std::map<std::string, std::shared_ptr<MonitorObject>>* moMap) override;
33+
void beautify(std::shared_ptr<MonitorObject> mo, Quality checkResult = Quality::Null) override;
34+
std::string getAcceptedType() override;
35+
36+
ClassDefOverride(TriggersSwVsTcmCheck, 2);
37+
38+
private:
39+
std::array<double, 4> mPositionMsgBox;
40+
};
41+
42+
} // namespace o2::quality_control_modules::fdd
43+
44+
#endif // QC_MODULE_FDD_TRIGGERSSWVSTCMCHECK_H

Modules/FIT/FDD/src/CFDEffCheck.cxx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ void CFDEffCheck::configure()
8484
// supply deadChannelMap by hand when running offline
8585
std::map<std::string, std::string> metadata;
8686
mDeadChannelMap = retrieveConditionAny<o2::fit::DeadChannelMap>(mPathDeadChannelMap, metadata, (long)-1);
87-
if (!mDeadChannelMap->map.size()) {
87+
if (!mDeadChannelMap || !mDeadChannelMap->map.size()) {
8888
ILOG(Error, Support) << "object \"" << mPathDeadChannelMap << "\" NOT retrieved (or empty). All channels assumed to be alive!" << ENDM;
8989
mDeadChannelMap = new o2::fit::DeadChannelMap();
9090
for (uint8_t chId = 0; chId < sNCHANNELS; ++chId) {
@@ -98,9 +98,10 @@ void CFDEffCheck::configure()
9898
mDeadChannelMapStr += (mDeadChannelMapStr.empty() ? "" : ",") + std::to_string(chId);
9999
}
100100
}
101-
if (mDeadChannelMapStr.empty())
101+
if (mDeadChannelMapStr.empty()) {
102102
mDeadChannelMapStr = "EMPTY";
103-
ILOG(Info, Support) << "Loaded dead channel map: " << mDeadChannelMapStr << ENDM;
103+
}
104+
ILOG(Debug, Support) << "Loaded dead channel map: " << mDeadChannelMapStr << ENDM;
104105
}
105106

106107
Quality CFDEffCheck::check(std::map<std::string, std::shared_ptr<MonitorObject>>* moMap)
@@ -189,7 +190,7 @@ void CFDEffCheck::beautify(std::shared_ptr<MonitorObject> mo, Quality checkResul
189190
lineWarning->SetLineColor(kOrange);
190191
h->GetListOfFunctions()->Add(lineError);
191192
h->GetListOfFunctions()->Add(lineWarning);
192-
h->SetStats(0);
193+
h->SetStats(1);
193194
}
194195
}
195196

Modules/FIT/FDD/src/DigitQcTask.cxx

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
///
1313
/// \file DigitQcTask.cxx
1414
/// \author Artur Furs afurs@cern.ch
15-
/// LATEST modification for FDD on 24.08.2022 (sbysiak@cern.ch)
15+
/// LATEST modification for FDD on 25.04.2023 (akhuntia@cern.ch)
1616

1717
#include "FDD/DigitQcTask.h"
1818
#include "TCanvas.h"
@@ -129,7 +129,8 @@ bool DigitQcTask::chIsVertexEvent(const o2::fdd::ChannelData chd)
129129
return (chd.getFlag(o2::fdd::ChannelData::kIsCFDinADCgate) &&
130130
!(chd.getFlag(o2::fdd::ChannelData::kIsTimeInfoNOTvalid) || chd.getFlag(o2::fdd::ChannelData::kIsTimeInfoLate) || chd.getFlag(o2::fdd::ChannelData::kIsTimeInfoLost)) &&
131131
std::abs(static_cast<Int_t>(chd.mTime)) < mTrgOrGate &&
132-
!chd.getFlag(o2::fdd::ChannelData::kIsAmpHigh));
132+
static_cast<Int_t>(chd.mChargeADC) > mTrgChargeLevelLow &&
133+
static_cast<Int_t>(chd.mChargeADC) < mTrgChargeLevelHigh);
133134
}
134135

135136
void DigitQcTask::initialize(o2::framework::InitContext& /*ctx*/)
@@ -175,6 +176,10 @@ void DigitQcTask::initialize(o2::framework::InitContext& /*ctx*/)
175176
mTrgChargeLevelHigh = getNumericalParameter("trgChargeLevelHigh", 4095);
176177
mTrgThresholdTimeLow = getNumericalParameter("trgThresholdTimeLow", -192);
177178
mTrgThresholdTimeHigh = getNumericalParameter("trgThresholdTimeHigh", 192);
179+
mBinMinADCSaturationCheck = getNumericalParameter("BinMinADCSaturationCheck", 1);
180+
mBinMaxADCSaturationCheck = getNumericalParameter("BinMaxADCSaturationCheck", 3600);
181+
mMinTimeGate = getNumericalParameter("minGateTimeForRatioHistogram", -192);
182+
mMaxTimeGate = getNumericalParameter("maxGateTimeForRatioHistogram", 192);
178183
if (mTrgModeSide == TrgModeSide::kAplusC) {
179184
mTrgThresholdCenA = getNumericalParameter("trgThresholdCenA", 20);
180185
mTrgThresholdSCenA = getNumericalParameter("trgThresholdSCenA", 10);
@@ -286,7 +291,10 @@ void DigitQcTask::initialize(o2::framework::InitContext& /*ctx*/)
286291
mHistTimeSum2Diff->GetYaxis()->SetRangeUser(-5, 5);
287292
mHistNumADC = std::make_unique<TH1F>("HistNumADC", "HistNumADC", sNCHANNELS_PM, 0, sNCHANNELS_PM);
288293
mHistNumCFD = std::make_unique<TH1F>("HistNumCFD", "HistNumCFD", sNCHANNELS_PM, 0, sNCHANNELS_PM);
289-
mHistCFDEff = std::make_unique<TH1F>("CFD_efficiency", "CFD efficiency;ChannelID;efficiency", sNCHANNELS_PM, 0, sNCHANNELS_PM);
294+
mHistCFDEff = std::make_unique<TH1F>("CFD_efficiency", "Fraction of events with CFD in ADC gate vs ChannelID;ChannelID;Event fraction with CFD in ADC gate", sNCHANNELS_PM, 0, sNCHANNELS_PM);
295+
mHistSaturationFraction = std::make_unique<TH1F>("ADCChargeFractionInRange", Form("Fraction of charge in [%d, %d] ADC;Channel ID;Event fraction in [%d, %d] ADC", mBinMinADCSaturationCheck, mBinMaxADCSaturationCheck, mBinMinADCSaturationCheck, mBinMaxADCSaturationCheck), sNCHANNELS_PM, 0, sNCHANNELS_PM);
296+
std::string gateTimeRatioTitle = "Ratio of events between time " + std::to_string(mMinTimeGate) + " and " + std::to_string(mMaxTimeGate);
297+
mHistGateTimeRatio2Ch = std::make_unique<TH1F>("EventsInGateTime", gateTimeRatioTitle.c_str(), sNCHANNELS_PM, 0, sNCHANNELS_PM);
290298
mHistNchA = std::make_unique<TH1F>("NumChannelsA", "Number of channels(TCM), side A;Nch", sNCHANNELS_A, 0, sNCHANNELS_A);
291299
mHistNchC = std::make_unique<TH1F>("NumChannelsC", "Number of channels(TCM), side C;Nch", sNCHANNELS_C, 0, sNCHANNELS_C);
292300
mHistSumAmpA = std::make_unique<TH1F>("SumAmpA", "Sum of amplitudes(TCM), side A;", 5e3, 0, 5e3);
@@ -353,6 +361,8 @@ void DigitQcTask::initialize(o2::framework::InitContext& /*ctx*/)
353361
rebinFromConfig(); // after all histos are created
354362
// 1-dim hists
355363
getObjectsManager()->startPublishing(mHistCFDEff.get());
364+
getObjectsManager()->startPublishing(mHistSaturationFraction.get());
365+
getObjectsManager()->startPublishing(mHistGateTimeRatio2Ch.get());
356366
getObjectsManager()->startPublishing(mHistBC.get());
357367
getObjectsManager()->startPublishing(mHistNchA.get());
358368
getObjectsManager()->startPublishing(mHistNchC.get());
@@ -420,6 +430,8 @@ void DigitQcTask::startOfActivity(Activity& activity)
420430
mHistBC->Reset();
421431
mHistChDataBits->Reset();
422432
mHistCFDEff->Reset();
433+
mHistSaturationFraction->Reset();
434+
mHistGateTimeRatio2Ch->Reset();
423435
mHistNumADC->Reset();
424436
mHistNumCFD->Reset();
425437
mHistTimeSum2Diff->Reset();
@@ -823,6 +835,29 @@ void DigitQcTask::endOfCycle()
823835
// one has to set num. of entries manually because
824836
// default TH1Reductor gets only mean,stddev and entries (no integral)
825837
mHistCFDEff->Divide(mHistNumADC.get(), mHistNumCFD.get());
838+
for (int iPM = 0; iPM < sNCHANNELS_PM; iPM++) {
839+
double intNumerator = mHistAmp2Ch->ProjectionY("yNum", iPM + 1, iPM + 1)->Integral(mBinMinADCSaturationCheck, mBinMaxADCSaturationCheck);
840+
double intDenominator = mHistAmp2Ch->ProjectionY("yDen", iPM + 1, iPM + 1)->Integral(mBinMinADCSaturationCheck, mHistAmp2Ch->GetNbinsY());
841+
if (intDenominator)
842+
mHistSaturationFraction->SetBinContent(iPM, intNumerator / intDenominator);
843+
}
844+
845+
for (int channel = 0; channel <= sNCHANNELS_PM; channel++) {
846+
float events_in_range = 0;
847+
float events_per_channel = 0;
848+
for (int bin_on_y_axis = 1; bin_on_y_axis <= mHistTime2Ch->GetNbinsY(); bin_on_y_axis++) {
849+
if (mHistTime2Ch->GetYaxis()->GetBinLowEdge(bin_on_y_axis) > mMinTimeGate && mHistTime2Ch->GetYaxis()->GetBinLowEdge(bin_on_y_axis) < mMaxTimeGate) {
850+
events_in_range += mHistTime2Ch->GetBinContent(channel + 1, bin_on_y_axis);
851+
}
852+
events_per_channel += mHistTime2Ch->GetBinContent(channel + 1, bin_on_y_axis);
853+
}
854+
if (events_per_channel) {
855+
mHistGateTimeRatio2Ch->SetBinContent(channel + 1, events_in_range / events_per_channel);
856+
} else {
857+
mHistGateTimeRatio2Ch->SetBinContent(channel + 1, 0);
858+
}
859+
}
860+
mHistSaturationFraction->GetYaxis()->SetRangeUser(0, 1.1);
826861
mHistCycleDurationRange->SetBinContent(1., mTimeMaxNS - mTimeMinNS);
827862
mHistCycleDurationRange->SetEntries(mTimeMaxNS - mTimeMinNS);
828863
mHistCycleDurationNTF->SetBinContent(1., mTfCounter);
@@ -847,6 +882,8 @@ void DigitQcTask::reset()
847882
mHistBC->Reset();
848883
mHistChDataBits->Reset();
849884
mHistCFDEff->Reset();
885+
mHistSaturationFraction->Reset();
886+
mHistGateTimeRatio2Ch->Reset();
850887
mHistNumADC->Reset();
851888
mHistNumCFD->Reset();
852889
mHistTimeSum2Diff->Reset();

0 commit comments

Comments
 (0)