Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MFT: new checker for empty ladders #2379

Merged
merged 3 commits into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions Modules/MFT/include/MFT/QcMFTClusterCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,22 @@ class QcMFTClusterCheck : public o2::quality_control::checker::CheckInterface
std::string getAcceptedType() override;

private:
int mZoneThresholdMedium;
int mZoneThresholdBad;
int mLadderThresholdMedium;
int mLadderThresholdBad;

// ladder checker
bool mIsEmpty;
bool mAdjacentLadders;
int mEmptyCount;
int mAdjacentCount;

// masked chips part
bool mFirstCall;
std::vector<int> mMaskedChips;
std::vector<string> mChipMapName;
std::vector<string> mOutsideAccName;

void readMaskedChips(std::shared_ptr<MonitorObject> mo);
void createMaskedChipsNames();
void createOutsideAccNames();

// to form the name of the masked chips histograms
int mHalf[936] = { 0 };
Expand Down
12 changes: 8 additions & 4 deletions Modules/MFT/include/MFT/QcMFTDigitCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,22 @@ class QcMFTDigitCheck : public o2::quality_control::checker::CheckInterface
std::string getAcceptedType() override;

private:
int mZoneThresholdMedium;
int mZoneThresholdBad;
int mLadderThresholdMedium;
int mLadderThresholdBad;

// ladder checker
bool mIsEmpty;
bool mAdjacentLadders;
int mEmptyCount;
int mAdjacentCount;

// masked chips part
bool mFirstCall;
std::vector<int> mMaskedChips;
std::vector<string> mChipMapName;
std::vector<string> mOutsideAccName;

void readMaskedChips(std::shared_ptr<MonitorObject> mo);
void createMaskedChipsNames();
void createOutsideAccNames();

// noise scan check

Expand Down
46 changes: 46 additions & 0 deletions Modules/MFT/include/MFT/QcMFTUtilTables.h
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,52 @@ class QcMFTUtilTables
{ 17, -14, 14, 5, 0, 15 },
};

// names for occupancy maps (for outside acceptance and ladder checker)
string mDigitChipMapNames[20] = {
"ChipOccupancyMaps/Half_0/Disk_0/Face_0/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_0/Disk_0/Face_1/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_0/Disk_1/Face_0/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_0/Disk_1/Face_1/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_0/Disk_2/Face_0/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_0/Disk_2/Face_1/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_0/Disk_3/Face_0/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_0/Disk_3/Face_1/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_0/Disk_4/Face_0/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_0/Disk_4/Face_1/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_0/Face_0/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_0/Face_1/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_1/Face_0/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_1/Face_1/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_2/Face_0/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_2/Face_1/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_3/Face_0/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_3/Face_1/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_4/Face_0/mDigitChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_4/Face_1/mDigitChipOccupancyMap"
};

string mClusterChipMapNames[20] = {
"ChipOccupancyMaps/Half_0/Disk_0/Face_0/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_0/Disk_0/Face_1/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_0/Disk_1/Face_0/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_0/Disk_1/Face_1/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_0/Disk_2/Face_0/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_0/Disk_2/Face_1/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_0/Disk_3/Face_0/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_0/Disk_3/Face_1/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_0/Disk_4/Face_0/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_0/Disk_4/Face_1/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_0/Face_0/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_0/Face_1/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_1/Face_0/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_1/Face_1/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_2/Face_0/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_2/Face_1/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_3/Face_0/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_3/Face_1/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_4/Face_0/mClusterChipOccupancyMap",
"ChipOccupancyMaps/Half_1/Disk_4/Face_1/mClusterChipOccupancyMap"
};
// binX for outside acceptance (-1 due to uneven number of empty bins different parts of the detector)
int mBinX[20][21] = {
// half0
Expand Down
4 changes: 2 additions & 2 deletions Modules/MFT/mft-clusters.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@
]
} ],
"checkParameters" : {
"ZoneThresholdMedium" : "2",
"ZoneThresholdBad" : "5"
"LadderThresholdMedium" : "1",
"LadderThresholdBad" : "2"
},
"className" : "o2::quality_control_modules::mft::QcMFTClusterCheck",
"moduleName" : "QcMFT",
Expand Down
4 changes: 2 additions & 2 deletions Modules/MFT/mft-digits.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@
"detectorName" : "MFT",
"policy" : "OnEachSeparately",
"checkParameters" : {
"ZoneThresholdMedium" : "2",
"ZoneThresholdBad" : "5",
"LadderThresholdMedium" : "1",
"LadderThresholdBad" : "2",
"NoiseScan" : "1",
"NCyclesNoiseMap" : "3"
},
Expand Down
109 changes: 69 additions & 40 deletions Modules/MFT/src/QcMFTClusterCheck.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,21 @@ void QcMFTClusterCheck::configure()
{

// this is how to get access to custom parameters defined in the config file at qc.tasks.<task_name>.taskParameters
if (auto param = mCustomParameters.find("ZoneThresholdMedium"); param != mCustomParameters.end()) {
ILOG(Info, Support) << "Custom parameter - ZoneThresholdMedium: " << param->second << ENDM;
mZoneThresholdMedium = stoi(param->second);
if (auto param = mCustomParameters.find("LadderThresholdMedium"); param != mCustomParameters.end()) {
ILOG(Info, Support) << "Custom parameter - LadderThresholdMedium: " << param->second << ENDM;
mLadderThresholdMedium = stoi(param->second);
}
if (auto param = mCustomParameters.find("ZoneThresholdBad"); param != mCustomParameters.end()) {
ILOG(Info, Support) << "Custom parameter - ZoneThresholdBad: " << param->second << ENDM;
mZoneThresholdBad = stoi(param->second);
if (auto param = mCustomParameters.find("LadderThresholdBad"); param != mCustomParameters.end()) {
ILOG(Info, Support) << "Custom parameter - LadderThresholdBad: " << param->second << ENDM;
mLadderThresholdBad = stoi(param->second);
}

// no call to beautifier yet
mFirstCall = true;
mIsEmpty = true;
mAdjacentLadders = false;

mEmptyCount = 0;
}

Quality QcMFTClusterCheck::check(std::map<std::string, std::shared_ptr<MonitorObject>>* moMap)
Expand All @@ -74,6 +78,13 @@ Quality QcMFTClusterCheck::check(std::map<std::string, std::shared_ptr<MonitorOb

(void)moName;

if (mFirstCall) {
mFirstCall = false;
readMaskedChips(mo);
getChipMapData();
createMaskedChipsNames();
}

if (mo->getName() == "mClusterOccupancy") {
auto* hClusterOccupancy = dynamic_cast<TH1F*>(mo->getObject());
if (hClusterOccupancy == nullptr) {
Expand Down Expand Up @@ -112,30 +123,67 @@ Quality QcMFTClusterCheck::check(std::map<std::string, std::shared_ptr<MonitorOb
}
}

// checker for empty ladders
QcMFTUtilTables MFTTable;
for (int i = 0; i < 20; i++) {
if (mo->getName() == MFTTable.mClusterChipMapNames[i]) {
mAdjacentCount = 0;
auto* hClusterChipOccupancyMap = dynamic_cast<TH2F*>(mo->getObject());
if (hClusterChipOccupancyMap == nullptr) {
ILOG(Error, Support) << "Could not cast mClusterChipMap to TH2F." << ENDM;
return Quality::Null;
}
// loop over bins in each chip map
for (int iBinX = 0; iBinX < hClusterChipOccupancyMap->GetNbinsX(); iBinX++) {
mIsEmpty = true;
for (int iBinY = 0; iBinY < hClusterChipOccupancyMap->GetNbinsY(); iBinY++) {
if (hClusterChipOccupancyMap->GetBinContent(iBinX + 1, iBinY + 1) != 0) {
mIsEmpty = false; // if there is an unempty bin, the ladder is not empty
break;
} else {
// check if empty ladders are masked
for (int i = 0; i < mMaskedChips.size(); i++) {
if (mo->getName().find(mChipMapName[i]) != std::string::npos) {
if (iBinX + 1 == hClusterChipOccupancyMap->GetXaxis()->FindBin(mX[mMaskedChips[i]]) && iBinY + 1 == hClusterChipOccupancyMap->GetYaxis()->FindBin(mY[mMaskedChips[i]])) {
mIsEmpty = false;
} else {
mIsEmpty = true;
}
}
}
}
}
// count empty ladders
if (mIsEmpty) {
mEmptyCount++;
mAdjacentCount++;
} else {
mAdjacentCount = 0;
}
// set bool for adjacent ladders
if (mAdjacentCount >= mLadderThresholdBad) {
if (!mAdjacentLadders) {
mAdjacentLadders = true;
}
}
}
}
}

if (mo->getName() == "mClusterOccupancySummary") {
auto* hClusterOccupancySummary = dynamic_cast<TH2F*>(mo->getObject());
if (hClusterOccupancySummary == nullptr) {
ILOG(Error, Support) << "Could not cast hClusterOccupancySummary to TH2F." << ENDM;
return Quality::Null;
}

float nEmptyBins = 0; // number of empty zones

for (int iBinX = 0; iBinX < hClusterOccupancySummary->GetNbinsX(); iBinX++) {
for (int iBinY = 0; iBinY < hClusterOccupancySummary->GetNbinsY(); iBinY++) {
if ((hClusterOccupancySummary->GetBinContent(iBinX + 1, iBinY + 1)) == 0) {
nEmptyBins = nEmptyBins + 1;
}
}
}

if (nEmptyBins <= mZoneThresholdMedium) {
if (!mAdjacentLadders && mEmptyCount < mLadderThresholdMedium) {
result = Quality::Good;
}
if (nEmptyBins > mZoneThresholdMedium && nEmptyBins <= mZoneThresholdBad) {
if (!mAdjacentLadders && mEmptyCount >= mLadderThresholdMedium) {
result = Quality::Medium;
}
if (nEmptyBins > mZoneThresholdBad) {
if (mAdjacentLadders) {
result = Quality::Bad;
}
}
Expand Down Expand Up @@ -190,28 +238,9 @@ void QcMFTClusterCheck::createMaskedChipsNames()
}
}

void QcMFTClusterCheck::createOutsideAccNames()
{
for (int iHalf = 0; iHalf < 2; iHalf++) {
for (int iDisk = 0; iDisk < 5; iDisk++) {
for (int iFace = 0; iFace < 2; iFace++) {
mOutsideAccName.push_back(Form("ChipOccupancyMaps/Half_%d/Disk_%d/Face_%d/mClusterChipOccupancyMap",
iHalf, iDisk, iFace));
}
}
}
}

void QcMFTClusterCheck::beautify(std::shared_ptr<MonitorObject> mo, Quality checkResult)
{
// set up masking of dead chips once
if (mFirstCall) {
mFirstCall = false;
readMaskedChips(mo);
getChipMapData();
createMaskedChipsNames();
createOutsideAccNames();
}

// print skull in maps to display dead chips
int nMaskedChips = mMaskedChips.size();
for (int i = 0; i < nMaskedChips; i++) {
Expand All @@ -233,7 +262,7 @@ void QcMFTClusterCheck::beautify(std::shared_ptr<MonitorObject> mo, Quality chec
for (int iDisk = 0; iDisk < 5; iDisk++) {
for (int iFace = 0; iFace < 2; iFace++) {
int idx = (iDisk * 2 + iFace) + (10 * iHalf);
if (mo->getName().find(mOutsideAccName[idx]) != std::string::npos) {
if (mo->getName().find(MFTTable.mClusterChipMapNames[idx]) != std::string::npos) {
auto* h = dynamic_cast<TH2F*>(mo->getObject());
for (int i = 0; i < 21; i++) {
int binX = MFTTable.mBinX[idx][i];
Expand Down
Loading
Loading