From 2fad2fff300efd9a728dccbec580aea2cd4deaa4 Mon Sep 17 00:00:00 2001 From: Jonathan Witte Date: Fri, 13 Nov 2026 16:18:18 +0100 Subject: [PATCH] Adding a configurable to mute histograms from ambiguous tracks --- PWGDQ/Tasks/dqEfficiency_withAssoc.cxx | 72 ++++++++++++++++---------- PWGDQ/Tasks/tableReader_withAssoc.h | 35 ++++++++----- 2 files changed, 67 insertions(+), 40 deletions(-) diff --git a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx index 9b759f453e9..3ff1faa887f 100644 --- a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx +++ b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx @@ -1714,6 +1714,8 @@ struct AnalysisSameEventPairing { } fConfigCuts; Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; + Configurable fConfigAmbiguousBarrelHistograms{"cfgAmbiguousBarrelHistograms", true, "If true, add the in/out-of-bunch ambiguity histogram classes for barrel pairs"}; + Configurable fConfigAmbiguousMuonHistograms{"cfgAmbiguousMuonHistograms", true, "If true, add the in/out-of-bunch ambiguity histogram classes for muon pairs"}; Configurable fConfigAddSEPHistogram{"cfgAddSEPHistogram", "", "Comma separated list of histograms"}; Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format"}; @@ -1913,7 +1915,7 @@ struct AnalysisSameEventPairing { Form("PairsBarrelSEPM_%s", objArray->At(icut)->GetName()), Form("PairsBarrelSEPP_%s", objArray->At(icut)->GetName()), Form("PairsBarrelSEMM_%s", objArray->At(icut)->GetName())}; - if (fConfigQA) { + if (fConfigQA && fConfigAmbiguousBarrelHistograms) { // assign separate hist directories for ambiguous tracks names.push_back(Form("PairsBarrelSEPM_ambiguousInBunch_%s", objArray->At(icut)->GetName())); names.push_back(Form("PairsBarrelSEPP_ambiguousInBunch_%s", objArray->At(icut)->GetName())); @@ -1956,12 +1958,14 @@ struct AnalysisSameEventPairing { if (fConfigQA) { names.push_back(Form("PairsBarrelSEPMCorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); names.push_back(Form("PairsBarrelSEPMIncorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); - names.push_back(Form("PairsBarrelSEPM_ambiguousInBunch_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); - names.push_back(Form("PairsBarrelSEPM_ambiguousInBunchCorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); - names.push_back(Form("PairsBarrelSEPM_ambiguousInBunchIncorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); - names.push_back(Form("PairsBarrelSEPM_ambiguousOutOfBunch_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); - names.push_back(Form("PairsBarrelSEPM_ambiguousOutOfBunchCorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); - names.push_back(Form("PairsBarrelSEPM_ambiguousOutOfBunchIncorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + if (fConfigAmbiguousBarrelHistograms) { + names.push_back(Form("PairsBarrelSEPM_ambiguousInBunch_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + names.push_back(Form("PairsBarrelSEPM_ambiguousInBunchCorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + names.push_back(Form("PairsBarrelSEPM_ambiguousInBunchIncorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + names.push_back(Form("PairsBarrelSEPM_ambiguousOutOfBunch_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + names.push_back(Form("PairsBarrelSEPM_ambiguousOutOfBunchCorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + names.push_back(Form("PairsBarrelSEPM_ambiguousOutOfBunchIncorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + } } for (auto const& n : names) { histNames += Form("%s;", n.Data()); @@ -2004,7 +2008,7 @@ struct AnalysisSameEventPairing { Form("PairsMuonSEPM_%s", objArray->At(icut)->GetName()), Form("PairsMuonSEPP_%s", objArray->At(icut)->GetName()), Form("PairsMuonSEMM_%s", objArray->At(icut)->GetName())}; - if (fConfigQA) { + if (fConfigQA && fConfigAmbiguousMuonHistograms) { // assign separate hist directories for ambiguous tracks names.push_back(Form("PairsMuonSEPM_ambiguousInBunch_%s", objArray->At(icut)->GetName())); names.push_back(Form("PairsMuonSEPP_ambiguousInBunch_%s", objArray->At(icut)->GetName())); @@ -2045,12 +2049,14 @@ struct AnalysisSameEventPairing { if (fConfigQA) { names.push_back(Form("PairsMuonSEPMCorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); names.push_back(Form("PairsMuonSEPMIncorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); - names.push_back(Form("PairsMuonSEPM_ambiguousInBunch_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); - names.push_back(Form("PairsMuonSEPM_ambiguousInBunchCorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); - names.push_back(Form("PairsMuonSEPM_ambiguousInBunchIncorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); - names.push_back(Form("PairsMuonSEPM_ambiguousOutOfBunch_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); - names.push_back(Form("PairsMuonSEPM_ambiguousOutOfBunchCorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); - names.push_back(Form("PairsMuonSEPM_ambiguousOutOfBunchIncorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + if (fConfigAmbiguousMuonHistograms) { + names.push_back(Form("PairsMuonSEPM_ambiguousInBunch_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + names.push_back(Form("PairsMuonSEPM_ambiguousInBunchCorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + names.push_back(Form("PairsMuonSEPM_ambiguousInBunchIncorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + names.push_back(Form("PairsMuonSEPM_ambiguousOutOfBunch_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + names.push_back(Form("PairsMuonSEPM_ambiguousOutOfBunchCorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + names.push_back(Form("PairsMuonSEPM_ambiguousOutOfBunchIncorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + } } for (auto const& n : names) { histNames += Form("%s;", n.Data()); @@ -2154,12 +2160,15 @@ struct AnalysisSameEventPairing { if (fConfigQA) { names.push_back(Form("PairsEleMuSEPMCorrectAssoc_%s_%s_%s", trackCutName.Data(), muonCutName.Data(), sig->GetName())); names.push_back(Form("PairsEleMuSEPMIncorrectAssoc_%s_%s_%s", trackCutName.Data(), muonCutName.Data(), sig->GetName())); - names.push_back(Form("PairsEleMuSEPM_ambiguousInBunch_%s_%s_%s", trackCutName.Data(), muonCutName.Data(), sig->GetName())); - names.push_back(Form("PairsEleMuSEPM_ambiguousInBunchCorrectAssoc_%s_%s_%s", trackCutName.Data(), muonCutName.Data(), sig->GetName())); - names.push_back(Form("PairsEleMuSEPM_ambiguousInBunchIncorrectAssoc_%s_%s_%s", trackCutName.Data(), muonCutName.Data(), sig->GetName())); - names.push_back(Form("PairsEleMuSEPM_ambiguousOutOfBunch_%s_%s_%s", trackCutName.Data(), muonCutName.Data(), sig->GetName())); - names.push_back(Form("PairsEleMuSEPM_ambiguousOutOfBunchCorrectAssoc_%s_%s_%s", trackCutName.Data(), muonCutName.Data(), sig->GetName())); - names.push_back(Form("PairsEleMuSEPM_ambiguousOutOfBunchIncorrectAssoc_%s_%s_%s", trackCutName.Data(), muonCutName.Data(), sig->GetName())); + // the e-mu ambiguity classes mix a barrel and a muon leg, so they need both switches + if (fConfigAmbiguousBarrelHistograms && fConfigAmbiguousMuonHistograms) { + names.push_back(Form("PairsEleMuSEPM_ambiguousInBunch_%s_%s_%s", trackCutName.Data(), muonCutName.Data(), sig->GetName())); + names.push_back(Form("PairsEleMuSEPM_ambiguousInBunchCorrectAssoc_%s_%s_%s", trackCutName.Data(), muonCutName.Data(), sig->GetName())); + names.push_back(Form("PairsEleMuSEPM_ambiguousInBunchIncorrectAssoc_%s_%s_%s", trackCutName.Data(), muonCutName.Data(), sig->GetName())); + names.push_back(Form("PairsEleMuSEPM_ambiguousOutOfBunch_%s_%s_%s", trackCutName.Data(), muonCutName.Data(), sig->GetName())); + names.push_back(Form("PairsEleMuSEPM_ambiguousOutOfBunchCorrectAssoc_%s_%s_%s", trackCutName.Data(), muonCutName.Data(), sig->GetName())); + names.push_back(Form("PairsEleMuSEPM_ambiguousOutOfBunchIncorrectAssoc_%s_%s_%s", trackCutName.Data(), muonCutName.Data(), sig->GetName())); + } } for (auto const& n : names) { histNames += Form("%s;", n.Data()); @@ -2309,6 +2318,12 @@ struct AnalysisSameEventPairing { histNamesMC = fMuonHistNamesMCmatched; ncuts = fNCutsMuon; } + // the in/out-of-bunch ambiguity hist classes are only booked (and therefore only fillable) when the + // corresponding switch is on; the indices below assume they are appended last in each name vector + bool fillAmbiguousHistos = fConfigAmbiguousBarrelHistograms; + if constexpr (TPairType == VarManager::kDecayToMuMu) { + fillAmbiguousHistos = fConfigAmbiguousMuonHistograms; + } auto twoTrackFilter = static_cast(0); int sign1 = 0; @@ -2629,7 +2644,7 @@ struct AnalysisSameEventPairing { } else { // incorrect track-collision association fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][4].Data(), dqefficiency_helpers::varValues()); } - if (isAmbiInBunch) { // ambiguous in bunch + if (fillAmbiguousHistos && isAmbiInBunch) { // ambiguous in bunch fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][5].Data(), dqefficiency_helpers::varValues()); if (isCorrectAssoc_leg1 && isCorrectAssoc_leg2) { fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][6].Data(), dqefficiency_helpers::varValues()); @@ -2637,7 +2652,7 @@ struct AnalysisSameEventPairing { fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][7].Data(), dqefficiency_helpers::varValues()); } } - if (isAmbiOutOfBunch) { // ambiguous out of bunch + if (fillAmbiguousHistos && isAmbiOutOfBunch) { // ambiguous out of bunch fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][8].Data(), dqefficiency_helpers::varValues()); if (isCorrectAssoc_leg1 && isCorrectAssoc_leg2) { fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][9].Data(), dqefficiency_helpers::varValues()); @@ -2647,7 +2662,7 @@ struct AnalysisSameEventPairing { } } } - if (fConfigQA) { + if (fConfigQA && fillAmbiguousHistos) { if (isAmbiInBunch) { fHistMan->FillHistClass(histNames[icut][3].Data(), dqefficiency_helpers::varValues()); } @@ -2664,7 +2679,7 @@ struct AnalysisSameEventPairing { fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][1].Data(), dqefficiency_helpers::varValues()); } } - if (fConfigQA) { + if (fConfigQA && fillAmbiguousHistos) { if (isAmbiInBunch) { fHistMan->FillHistClass(histNames[icut][4].Data(), dqefficiency_helpers::varValues()); } @@ -2679,7 +2694,7 @@ struct AnalysisSameEventPairing { fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][2].Data(), dqefficiency_helpers::varValues()); } } - if (fConfigQA) { + if (fConfigQA && fillAmbiguousHistos) { if (isAmbiInBunch) { fHistMan->FillHistClass(histNames[icut][5].Data(), dqefficiency_helpers::varValues()); } @@ -2859,6 +2874,8 @@ struct AnalysisSameEventPairing { const auto& histNames = fTrackMuonHistNames; const auto& histNamesMC = fTrackMuonHistNamesMCmatched; int nPairCuts = !fPairCuts.empty() ? static_cast(fPairCuts.size()) : 1; + // e-mu pairs have one barrel and one muon leg, so the ambiguity classes need both switches + bool fillAmbiguousHistos = fConfigAmbiguousBarrelHistograms && fConfigAmbiguousMuonHistograms; uint32_t twoTrackFilter = 0; uint32_t mcDecision = 0; @@ -3021,7 +3038,7 @@ struct AnalysisSameEventPairing { } else { fHistMan->FillHistClass(mcNames[2].Data(), dqefficiency_helpers::varValues()); } - if (!fConfigQA || mcNames.size() < 11) { + if (!fConfigQA || mcNames.size() < 5) { continue; } // QA fills (PM only, mirroring the dilepton MC layout: indices 3..10) @@ -3031,6 +3048,9 @@ struct AnalysisSameEventPairing { } else { fHistMan->FillHistClass(mcNames[4].Data(), dqefficiency_helpers::varValues()); } + if (!fillAmbiguousHistos || mcNames.size() < 11) { + continue; + } if (isAmbiInBunch) { fHistMan->FillHistClass(mcNames[5].Data(), dqefficiency_helpers::varValues()); if (isCorrectPair) { diff --git a/PWGDQ/Tasks/tableReader_withAssoc.h b/PWGDQ/Tasks/tableReader_withAssoc.h index 354e9fe815d..28482ed30c6 100644 --- a/PWGDQ/Tasks/tableReader_withAssoc.h +++ b/PWGDQ/Tasks/tableReader_withAssoc.h @@ -1485,6 +1485,7 @@ struct AnalysisSameEventPairing { o2::framework::Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format"}; o2::framework::Configurable fConfigQA{"cfgQA", true, "If true, fill output histograms"}; o2::framework::Configurable fConfigAmbiguousMuonHistograms{"cfgAmbiguousMuonHistograms", true, "If true, fill ambiguous histograms"}; + o2::framework::Configurable fConfigAmbiguousBarrelHistograms{"cfgAmbiguousBarrelHistograms", true, "If true, add the ambiguity histogram classes for barrel pairs"}; // option for TR pair fill o2::framework::Configurable fConfigTRPairs{"cfgFillTRPairs", false, "If true, fill Track rotation pairs"}; @@ -1708,21 +1709,27 @@ struct AnalysisSameEventPairing { Form("PairsBarrelSEPP_%s", objArray->At(icut)->GetName()), Form("PairsBarrelSEMM_%s", objArray->At(icut)->GetName())}; histNames += Form("%s;%s;%s;", names[0].Data(), names[1].Data(), names[2].Data()); - names.push_back(Form("PairsBarrelSEPM_ambiguousextra_%s", objArray->At(icut)->GetName())); - names.push_back(Form("PairsBarrelSEPP_ambiguousextra_%s", objArray->At(icut)->GetName())); - names.push_back(Form("PairsBarrelSEMM_ambiguousextra_%s", objArray->At(icut)->GetName())); - histNames += Form("%s;%s;%s;", names[3].Data(), names[4].Data(), names[5].Data()); + // append a hist class to both the name vector and the list of classes to be created + auto addName = [&names, &histNames](TString const& name) { + names.push_back(name); + histNames += Form("%s;", name.Data()); + }; + if (fConfigAmbiguousBarrelHistograms) { + addName(Form("PairsBarrelSEPM_ambiguousextra_%s", objArray->At(icut)->GetName())); + addName(Form("PairsBarrelSEPP_ambiguousextra_%s", objArray->At(icut)->GetName())); + addName(Form("PairsBarrelSEMM_ambiguousextra_%s", objArray->At(icut)->GetName())); + } if (fConfigTRPairs) { - names.push_back(Form("PairsBarrelTRPM_%s", objArray->At(icut)->GetName())); - names.push_back(Form("PairsBarrelTRPM_ambiguousextra_%s", objArray->At(icut)->GetName())); - names.push_back(Form("PairsBarrelTR_MEPM_%s", objArray->At(icut)->GetName())); - histNames += Form("%s;%s;%s;", names[6].Data(), names[7].Data(), names[8].Data()); + addName(Form("PairsBarrelTRPM_%s", objArray->At(icut)->GetName())); + if (fConfigAmbiguousBarrelHistograms) { + addName(Form("PairsBarrelTRPM_ambiguousextra_%s", objArray->At(icut)->GetName())); + } + addName(Form("PairsBarrelTR_MEPM_%s", objArray->At(icut)->GetName())); } if (fEnableBarrelMixingHistos) { - names.push_back(Form("PairsBarrelMEPM_%s", objArray->At(icut)->GetName())); - names.push_back(Form("PairsBarrelMEPP_%s", objArray->At(icut)->GetName())); - names.push_back(Form("PairsBarrelMEMM_%s", objArray->At(icut)->GetName())); - histNames += Form("%s;%s;%s;", names[(fConfigTRPairs ? 9 : 6)].Data(), names[(fConfigTRPairs ? 10 : 7)].Data(), names[(fConfigTRPairs ? 11 : 8)].Data()); + addName(Form("PairsBarrelMEPM_%s", objArray->At(icut)->GetName())); + addName(Form("PairsBarrelMEPP_%s", objArray->At(icut)->GetName())); + addName(Form("PairsBarrelMEMM_%s", objArray->At(icut)->GetName())); } fTrackHistNames[icut] = names; @@ -2412,7 +2419,7 @@ struct AnalysisSameEventPairing { isLeg1Ambi = (twoTrackFilter & (static_cast(1) << 28) || (twoTrackFilter & (static_cast(1) << 30))); isLeg2Ambi = (twoTrackFilter & (static_cast(1) << 29) || (twoTrackFilter & (static_cast(1) << 31))); if constexpr (TPairType == VarManager::kDecayToEE) { - if (isLeg1Ambi && isLeg2Ambi) { + if (fConfigAmbiguousBarrelHistograms && isLeg1Ambi && isLeg2Ambi) { std::pair iPair(a1.reducedtrackId(), a2.reducedtrackId()); if (fAmbiguousPairs.contains(iPair)) { if (fAmbiguousPairs[iPair] & (static_cast(1) << icut)) { // if this pair is already stored with this cut @@ -2569,7 +2576,7 @@ struct AnalysisSameEventPairing { isLeg1Ambi = (twoTrackFilter & (static_cast(1) << 28) || (twoTrackFilter & (static_cast(1) << 30))); isLeg2Ambi = (twoTrackFilter & (static_cast(1) << 29) || (twoTrackFilter & (static_cast(1) << 31))); if constexpr (TPairType == VarManager::kDecayToEE) { - if (isLeg1Ambi && isLeg2Ambi) { + if (fConfigAmbiguousBarrelHistograms && isLeg1Ambi && isLeg2Ambi) { std::pair iPair(a1.reducedtrackId(), a2.reducedtrackId()); if (fAmbiguousPairs.contains(iPair)) { if (fAmbiguousPairs[iPair] & (static_cast(1) << icut)) { // if this pair is already stored with this cut