From c1e6e6898ec2b6bfc41b4dd509f42b7fc50f13be Mon Sep 17 00:00:00 2001 From: sigurd Date: Wed, 22 Jan 2025 16:43:53 +0100 Subject: [PATCH 1/2] Implement charge checks and improve candidate selection --- PWGDQ/Tasks/dqEfficiency_withAssoc.cxx | 57 +++++++++++++++++++++----- PWGDQ/Tasks/tableReader_withAssoc.cxx | 48 +++++++++++++++++----- 2 files changed, 85 insertions(+), 20 deletions(-) diff --git a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx index 2cda1a7d417..f4fb288df8f 100644 --- a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx +++ b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx @@ -1940,8 +1940,10 @@ struct AnalysisAsymmetricPairing { uint32_t fLegAFilterMask; uint32_t fLegBFilterMask; uint32_t fLegCFilterMask; - // Map tracking which pair of leg cuts the track cuts participate in - std::map fTrackCutFilterMasks; + // Maps tracking which combination of leg cuts the track cuts participate in + std::map fConstructedLegAFilterMasksMap; + std::map fConstructedLegBFilterMasksMap; + std::map fConstructedLegCFilterMasksMap; // Filter map for common track cuts uint32_t fCommonTrackCutMask; // Map tracking which common track cut the track cuts correspond to @@ -2053,7 +2055,7 @@ struct AnalysisAsymmetricPairing { legAIdx = objArray->IndexOf(legs->At(0)); if (legAIdx >= 0) { fConstructedLegAFilterMask |= static_cast(1) << legAIdx; - fTrackCutFilterMasks[icut] |= static_cast(1) << legAIdx; + fConstructedLegAFilterMasksMap[icut] |= static_cast(1) << legAIdx; } else { LOGF(fatal, "Leg A cut %s was not calculated upstream. Check the config!", legs->At(0)->GetName()); continue; @@ -2061,7 +2063,7 @@ struct AnalysisAsymmetricPairing { legBIdx = objArray->IndexOf(legs->At(1)); if (legBIdx >= 0) { fConstructedLegBFilterMask |= static_cast(1) << legBIdx; - fTrackCutFilterMasks[icut] |= static_cast(1) << legBIdx; + fConstructedLegBFilterMasksMap[icut] |= static_cast(1) << legBIdx; } else { LOGF(fatal, "Leg B cut %s was not calculated upstream. Check the config!", legs->At(1)->GetName()); continue; @@ -2070,7 +2072,7 @@ struct AnalysisAsymmetricPairing { legCIdx = objArray->IndexOf(legs->At(2)); if (legCIdx >= 0) { fConstructedLegCFilterMask |= static_cast(1) << legCIdx; - fTrackCutFilterMasks[icut] |= static_cast(1) << legCIdx; + fConstructedLegCFilterMasksMap[icut] |= static_cast(1) << legCIdx; } else { LOGF(fatal, "Leg C cut %s was not calculated upstream. Check the config!", legs->At(2)->GetName()); continue; @@ -2379,7 +2381,7 @@ struct AnalysisAsymmetricPairing { bool isPairIdWrong = false; for (int icut = 0; icut < fNLegCuts; ++icut) { // Find leg pair definitions both candidates participate in - if ((((a1.isBarrelSelected_raw() & fLegAFilterMask) | (a2.isBarrelSelected_raw() & fLegBFilterMask)) & fTrackCutFilterMasks[icut]) == fTrackCutFilterMasks[icut]) { + if ((a1.isBarrelSelected_raw() & fConstructedLegAFilterMasksMap[icut]) && (a2.isBarrelSelected_raw() & fConstructedLegBFilterMasksMap[icut])) { twoTrackFilter |= static_cast(1) << icut; // If the supposed pion passes a kaon cut, this is a K+K-. Skip it. if (TPairType == VarManager::kDecayToKPi && fConfigSkipAmbiguousIdCombinations.value) { @@ -2626,8 +2628,8 @@ struct AnalysisAsymmetricPairing { uint32_t threeTrackFilter = 0; uint32_t threeTrackCommonFilter = 0; for (int icut = 0; icut < fNLegCuts; ++icut) { - // Find out which leg cut combination the triplet passes - if ((((a1.isBarrelSelected_raw() & fLegAFilterMask) | (a2.isBarrelSelected_raw() & fLegBFilterMask) | (a3.isBarrelSelected_raw() & fLegCFilterMask)) & fTrackCutFilterMasks[icut]) == fTrackCutFilterMasks[icut]) { + // Find out which leg cut combinations the triplet passes + if ((a1.isBarrelSelected_raw() & fConstructedLegAFilterMasksMap[icut]) && (a2.isBarrelSelected_raw() & fConstructedLegBFilterMasksMap[icut]) && (a3.isBarrelSelected_raw() & fConstructedLegCFilterMasksMap[icut])) { threeTrackFilter |= (static_cast(1) << icut); if (tripletType == VarManager::kTripleCandidateToPKPi && fConfigSkipAmbiguousIdCombinations.value) { // Check if the supposed pion passes as a proton or kaon, if so, skip this triplet. It is pKp or pKK. @@ -2662,6 +2664,17 @@ struct AnalysisAsymmetricPairing { if (t1 == t2 || t1 == t3 || t2 == t3) { return; } + // Check charge + if (tripletType == VarManager::kTripleCandidateToKPiPi) { + if (!((t1.sign() == -1 && t2.sign() == 1 && t3.sign() == 1) || (t1.sign() == 1 && t2.sign() == -1 && t3.sign() == -1))) { + return; + } + } + if (tripletType == VarManager::kTripleCandidateToPKPi) { + if (!((t1.sign() == 1 && t2.sign() == -1 && t3.sign() == 1) || (t1.sign() == -1 && t2.sign() == 1 && t3.sign() == -1))) { + return; + } + } // store the ambiguity of the three legs in the last 3 digits of the two-track filter if (t1.barrelAmbiguityInBunch() > 1 || t1.barrelAmbiguityOutOfBunch() > 1) { @@ -2840,7 +2853,7 @@ struct AnalysisDileptonTrack { // TODO: The filter expressions seem to always use the default value of configurables, not the values from the actual configuration file Filter eventFilter = aod::dqanalysisflags::isEventSelected > static_cast(0); - Filter dileptonFilter = aod::reducedpair::pt > fConfigDileptonpTCut&& aod::reducedpair::mass > fConfigDileptonLowMass&& aod::reducedpair::mass fConfigDileptonLxyCut; + Filter dileptonFilter = aod::reducedpair::pt > fConfigDileptonpTCut && aod::reducedpair::mass > fConfigDileptonLowMass && aod::reducedpair::mass < fConfigDileptonHighMass && aod::reducedpair::sign == 0 && aod::reducedpair::lxy > fConfigDileptonLxyCut; Filter filterBarrel = aod::dqanalysisflags::isBarrelSelected > static_cast(0); Filter filterMuon = aod::dqanalysisflags::isMuonSelected > static_cast(0); @@ -3118,7 +3131,7 @@ struct AnalysisDileptonTrack { // loop over hadrons for (auto& assoc : assocs) { - if constexpr (TCandidateType == VarManager::kBtoJpsiEEK || TCandidateType == VarManager::kDstarToD0KPiPi) { + if constexpr (TCandidateType == VarManager::kBtoJpsiEEK) { if (!assoc.isBarrelSelected_bit(fTrackCutBit)) { continue; } @@ -3138,6 +3151,30 @@ struct AnalysisDileptonTrack { } } } + if constexpr (TCandidateType == VarManager::kDstarToD0KPiPi) { + if (!assoc.isBarrelSelected_bit(fTrackCutBit)) { + continue; + } + auto track = assoc.template reducedtrack_as(); + if (track.globalIndex() == dilepton.index0Id() || track.globalIndex() == dilepton.index1Id()) { + continue; + } + // Check that the charge combination makes sense for D*+ -> D0 pi+ or D*- -> D0bar pi- + if (!((track.sign() == 1 && lepton1.sign() == -1 && lepton2.sign() == 1) || (track.sign() == -1 && lepton1.sign() == 1 && lepton2.sign() == -1))) { + continue; + } + VarManager::FillDileptonHadron(dilepton, track, fValuesHadron); + VarManager::FillDileptonTrackVertexing(event, lepton1, lepton2, track, fValuesHadron); + + auto trackMC = track.reducedMCTrack(); + mcDecision = 0; + isig = 0; + for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { + if ((*sig).CheckSignal(true, lepton1MC, lepton2MC, trackMC)) { + mcDecision |= (static_cast(1) << isig); + } + } + } if constexpr (TCandidateType == VarManager::kBcToThreeMuons) { if (!assoc.isMuonSelected_bit(fTrackCutBit)) { continue; diff --git a/PWGDQ/Tasks/tableReader_withAssoc.cxx b/PWGDQ/Tasks/tableReader_withAssoc.cxx index 2e41976f236..25176b98127 100644 --- a/PWGDQ/Tasks/tableReader_withAssoc.cxx +++ b/PWGDQ/Tasks/tableReader_withAssoc.cxx @@ -1926,8 +1926,10 @@ struct AnalysisAsymmetricPairing { uint32_t fLegAFilterMask; uint32_t fLegBFilterMask; uint32_t fLegCFilterMask; - // Map tracking which pair of leg cuts the track cuts participate in - std::map fTrackCutFilterMasks; + // Maps tracking which combination of leg cuts the track cuts participate in + std::map fConstructedLegAFilterMasksMap; + std::map fConstructedLegBFilterMasksMap; + std::map fConstructedLegCFilterMasksMap; // Filter map for common track cuts uint32_t fCommonTrackCutMask; // Map tracking which common track cut the track cuts correspond to @@ -2027,7 +2029,7 @@ struct AnalysisAsymmetricPairing { legAIdx = objArray->IndexOf(legs->At(0)); if (legAIdx >= 0) { fConstructedLegAFilterMask |= (static_cast(1) << legAIdx); - fTrackCutFilterMasks[icut] |= static_cast(1) << legAIdx; + fConstructedLegAFilterMasksMap[icut] |= static_cast(1) << legAIdx; } else { LOGF(fatal, "Leg A cut %s was not calculated upstream. Check the config!", legs->At(0)->GetName()); continue; @@ -2035,7 +2037,7 @@ struct AnalysisAsymmetricPairing { legBIdx = objArray->IndexOf(legs->At(1)); if (legBIdx >= 0) { fConstructedLegBFilterMask |= (static_cast(1) << legBIdx); - fTrackCutFilterMasks[icut] |= static_cast(1) << legBIdx; + fConstructedLegBFilterMasksMap[icut] |= static_cast(1) << legBIdx; } else { LOGF(fatal, "Leg B cut %s was not calculated upstream. Check the config!", legs->At(1)->GetName()); continue; @@ -2044,7 +2046,7 @@ struct AnalysisAsymmetricPairing { legCIdx = objArray->IndexOf(legs->At(2)); if (legCIdx >= 0) { fConstructedLegCFilterMask |= (static_cast(1) << legCIdx); - fTrackCutFilterMasks[icut] |= static_cast(1) << legCIdx; + fConstructedLegCFilterMasksMap[icut] |= static_cast(1) << legCIdx; } else { LOGF(fatal, "Leg C cut %s was not calculated upstream. Check the config!", legs->At(2)->GetName()); continue; @@ -2258,7 +2260,7 @@ struct AnalysisAsymmetricPairing { bool isPairIdWrong = false; for (int icut = 0; icut < fNLegCuts; ++icut) { // Find leg pair definitions both candidates participate in - if ((((a1.isBarrelSelected_raw() & fLegAFilterMask) | (a2.isBarrelSelected_raw() & fLegBFilterMask)) & fTrackCutFilterMasks[icut]) == fTrackCutFilterMasks[icut]) { + if ((a1.isBarrelSelected_raw() & fConstructedLegAFilterMasksMap[icut]) && (a2.isBarrelSelected_raw() & fConstructedLegBFilterMasksMap[icut])) { twoTrackFilter |= (static_cast(1) << icut); // If the supposed pion passes a kaon cut, this is a K+K-. Skip it. if (TPairType == VarManager::kDecayToKPi && fConfigSkipAmbiguousIdCombinations.value) { @@ -2435,8 +2437,8 @@ struct AnalysisAsymmetricPairing { uint32_t threeTrackFilter = static_cast(0); uint32_t threeTrackCommonFilter = static_cast(0); for (int icut = 0; icut < fNLegCuts; ++icut) { - // Find out which leg cut combination the triplet passes - if ((((a1.isBarrelSelected_raw() & fLegAFilterMask) | (a2.isBarrelSelected_raw() & fLegBFilterMask) | (a3.isBarrelSelected_raw() & fLegCFilterMask)) & fTrackCutFilterMasks[icut]) == fTrackCutFilterMasks[icut]) { + // Find out which leg cut combinations the triplet passes + if ((a1.isBarrelSelected_raw() & fConstructedLegAFilterMasksMap[icut]) && (a2.isBarrelSelected_raw() & fConstructedLegBFilterMasksMap[icut]) && (a3.isBarrelSelected_raw() & fConstructedLegCFilterMasksMap[icut])) { threeTrackFilter |= (static_cast(1) << icut); if (tripletType == VarManager::kTripleCandidateToPKPi && fConfigSkipAmbiguousIdCombinations.value) { // Check if the supposed pion passes as a proton or kaon, if so, skip this triplet. It is pKp or pKK. @@ -2471,6 +2473,17 @@ struct AnalysisAsymmetricPairing { if (t1 == t2 || t1 == t3 || t2 == t3) { return; } + // Check charge + if (tripletType == VarManager::kTripleCandidateToKPiPi) { + if (!((t1.sign() == -1 && t2.sign() == 1 && t3.sign() == 1) || (t1.sign() == 1 && t2.sign() == -1 && t3.sign() == -1))) { + return; + } + } + if (tripletType == VarManager::kTripleCandidateToPKPi) { + if (!((t1.sign() == 1 && t2.sign() == -1 && t3.sign() == 1) || (t1.sign() == -1 && t2.sign() == 1 && t3.sign() == -1))) { + return; + } + } // store the ambiguity of the three legs in the last 3 digits of the two-track filter if (t1.barrelAmbiguityInBunch() > 1 || t1.barrelAmbiguityOutOfBunch() > 1) { @@ -2585,7 +2598,7 @@ struct AnalysisDileptonTrack { // TODO: The filter expressions seem to always use the default value of configurables, not the values from the actual configuration file Filter eventFilter = aod::dqanalysisflags::isEventSelected > static_cast(0); - Filter dileptonFilter = aod::reducedpair::pt > fConfigDileptonpTCut&& aod::reducedpair::mass > fConfigDileptonLowMass&& aod::reducedpair::mass fConfigDileptonLxyCut; + Filter dileptonFilter = aod::reducedpair::pt > fConfigDileptonpTCut && aod::reducedpair::mass > fConfigDileptonLowMass && aod::reducedpair::mass < fConfigDileptonHighMass && aod::reducedpair::sign == 0 && aod::reducedpair::lxy > fConfigDileptonLxyCut; Filter filterBarrel = aod::dqanalysisflags::isBarrelSelected > static_cast(0); Filter filterMuon = aod::dqanalysisflags::isMuonSelected > static_cast(0); @@ -2823,7 +2836,18 @@ struct AnalysisDileptonTrack { // loop over hadrons for (auto& assoc : assocs) { - if constexpr (TCandidateType == VarManager::kBtoJpsiEEK || TCandidateType == VarManager::kDstarToD0KPiPi) { + if constexpr (TCandidateType == VarManager::kBtoJpsiEEK) { + if (!assoc.isBarrelSelected_bit(fTrackCutBit)) { + continue; + } + auto track = assoc.template reducedtrack_as(); + if (track.globalIndex() == dilepton.index0Id() || track.globalIndex() == dilepton.index1Id()) { + continue; + } + VarManager::FillDileptonHadron(dilepton, track, fValuesHadron); + VarManager::FillDileptonTrackVertexing(event, lepton1, lepton2, track, fValuesHadron); + } + if constexpr (TCandidateType == VarManager::kDstarToD0KPiPi) { if (!assoc.isBarrelSelected_bit(fTrackCutBit)) { continue; } @@ -2831,6 +2855,10 @@ struct AnalysisDileptonTrack { if (track.globalIndex() == dilepton.index0Id() || track.globalIndex() == dilepton.index1Id()) { continue; } + // Check that the charge combination makes sense for D*+ -> D0 pi+ or D*- -> D0bar pi- + if (!((track.sign() == 1 && lepton1.sign() == -1 && lepton2.sign() == 1) || (track.sign() == -1 && lepton1.sign() == 1 && lepton2.sign() == -1))) { + continue; + } VarManager::FillDileptonHadron(dilepton, track, fValuesHadron); VarManager::FillDileptonTrackVertexing(event, lepton1, lepton2, track, fValuesHadron); } From f4f8edd51a4a7bd1e91bcaf5bc17e138ead80989 Mon Sep 17 00:00:00 2001 From: ALICE Builder Date: Wed, 22 Jan 2025 16:55:03 +0100 Subject: [PATCH 2/2] Please consider the following formatting changes (#10) --- PWGDQ/Tasks/dqEfficiency_withAssoc.cxx | 2 +- PWGDQ/Tasks/tableReader_withAssoc.cxx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx index f4fb288df8f..b6e01c4e974 100644 --- a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx +++ b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx @@ -2853,7 +2853,7 @@ struct AnalysisDileptonTrack { // TODO: The filter expressions seem to always use the default value of configurables, not the values from the actual configuration file Filter eventFilter = aod::dqanalysisflags::isEventSelected > static_cast(0); - Filter dileptonFilter = aod::reducedpair::pt > fConfigDileptonpTCut && aod::reducedpair::mass > fConfigDileptonLowMass && aod::reducedpair::mass < fConfigDileptonHighMass && aod::reducedpair::sign == 0 && aod::reducedpair::lxy > fConfigDileptonLxyCut; + Filter dileptonFilter = aod::reducedpair::pt > fConfigDileptonpTCut&& aod::reducedpair::mass > fConfigDileptonLowMass&& aod::reducedpair::mass fConfigDileptonLxyCut; Filter filterBarrel = aod::dqanalysisflags::isBarrelSelected > static_cast(0); Filter filterMuon = aod::dqanalysisflags::isMuonSelected > static_cast(0); diff --git a/PWGDQ/Tasks/tableReader_withAssoc.cxx b/PWGDQ/Tasks/tableReader_withAssoc.cxx index 25176b98127..87cfa7f32b2 100644 --- a/PWGDQ/Tasks/tableReader_withAssoc.cxx +++ b/PWGDQ/Tasks/tableReader_withAssoc.cxx @@ -2598,7 +2598,7 @@ struct AnalysisDileptonTrack { // TODO: The filter expressions seem to always use the default value of configurables, not the values from the actual configuration file Filter eventFilter = aod::dqanalysisflags::isEventSelected > static_cast(0); - Filter dileptonFilter = aod::reducedpair::pt > fConfigDileptonpTCut && aod::reducedpair::mass > fConfigDileptonLowMass && aod::reducedpair::mass < fConfigDileptonHighMass && aod::reducedpair::sign == 0 && aod::reducedpair::lxy > fConfigDileptonLxyCut; + Filter dileptonFilter = aod::reducedpair::pt > fConfigDileptonpTCut&& aod::reducedpair::mass > fConfigDileptonLowMass&& aod::reducedpair::mass fConfigDileptonLxyCut; Filter filterBarrel = aod::dqanalysisflags::isBarrelSelected > static_cast(0); Filter filterMuon = aod::dqanalysisflags::isMuonSelected > static_cast(0);