From 737b76153e2cd8a845b48ef15455d5dff6c2c02e Mon Sep 17 00:00:00 2001 From: akyadav1963 Date: Fri, 5 Jun 2026 17:24:13 +0530 Subject: [PATCH 1/3] PWGLF: ptmultCorr.cxx: added DCA_xy axis in MC reco for secondary contamination estimation --- .../GlobalEventProperties/ptmultCorr.cxx | 215 +++++++++++++----- 1 file changed, 156 insertions(+), 59 deletions(-) diff --git a/PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx b/PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx index 4e8abe41a4c..712c70e1625 100644 --- a/PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx +++ b/PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -60,9 +61,7 @@ using ColMCRecTablePbPb = soa::SmallGroups>; using ColMCTrueTable = soa::Join; using TrackDataTable = soa::Join; -using FilTrackDataTable = soa::Filtered; using TrackMCRecTable = soa::Join; -using FilTrackMCRecTable = soa::Filtered; using TrackMCTrueTable = aod::McParticles; enum { @@ -81,6 +80,13 @@ enum { kGenpTend }; +// ── CHANGE 1 ──────────────────────────────────────────────────────────────── +// Added kGenAllCharged as the new last bin before kGenTrkTypeend. +// Numerator : kGenAll → MC truth physical primaries +// Denominator: kGenAllCharged → MC truth all charged (primaries + secondaries) +// Primary fraction from MC = kGenAll / kGenAllCharged per pT bin. +// axisGenTrkType (built from kGenTrkTypeend) auto-expands from 5 → 6 bins. +// ──────────────────────────────────────────────────────────────────────────── enum { kGenTrkTypebegin = 0, kGenAll = 1, @@ -88,6 +94,7 @@ enum { kGenKaon, kGenProton, kGenOther, + kGenAllCharged, // all charged particles (primaries + secondaries) — denominator for primary fraction kGenTrkTypeend }; @@ -122,7 +129,9 @@ AxisSpec axisPhi{{0, o2::constants::math::PIQuarter, o2::constants::math::PIHalf AxisSpec axisPhi2{629, 0, o2::constants::math::TwoPI, "#phi"}; AxisSpec axisCent{100, 0, 100, "#Cent"}; AxisSpec axisDeltaPt{50, -1.0, +1.0, "#Delta(pT)"}; +AxisSpec axisDCAxy{100, -3.0, 3.0, "DCA_{xy} (cm)", "DCAxyAxis"}; // range ±3 cm for TPC-only case AxisSpec axisGenPtVary = {kGenpTend - 1, +kGenpTbegin + 0.5, +kGenpTend - 0.5, "", "GenpTVaryAxis"}; +// axisGenTrkType auto-expands: kGenTrkTypeend is now 8, giving 6 bins (kGenAll … kGenAllCharged) AxisSpec axisGenTrkType = {kGenTrkTypeend - 1, +kGenTrkTypebegin + 0.5, +kGenTrkTypeend - 0.5, "", "GenTrackTypeAxis"}; AxisSpec axisRecTrkType = {kRecTrkTypeend - 1, +kRecTrkTypebegin + 0.5, +kRecTrkTypeend - 0.5, "", "RecTrackTypeAxis"}; AxisSpec axisTrackType = {kTrackTypeend - 1, +kTrackTypebegin + 0.5, +kTrackTypeend - 0.5, "", "TrackTypeAxis"}; @@ -166,7 +175,7 @@ struct PtmultCorr { ConfigurableAxis centralityBinning{"centralityBinning", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, ""}; ConfigurableAxis binsImpactPar{"binsImpactPar", {VARIABLE_WIDTH, 0.0, 3.00065, 4.28798, 6.14552, 7.6196, 8.90942, 10.0897, 11.2002, 12.2709, 13.3167, 14.4173, 23.2518}, "Binning of the impact parameter axis"}; - // DCA cache (loaded from CCDB) + // DCA cache (loaded from CCDB) struct ConfigDCA { TH1F* hDCAxy = nullptr; TH1F* hDCAz = nullptr; @@ -183,9 +192,14 @@ struct PtmultCorr { Configurable isApplyInelgt0{"isApplyInelgt0", false, "Enable INEL > 0 condition"}; Configurable isApplyOccuCut{"isApplyOccuCut", false, "Enable occupancy selection"}; + // Secondary estimation related configurables + Configurable isApplyDCACuts{"isApplyDCACuts", false, "Enable DCA cuts (set to false for secondary estimation)"}; + Configurable isApplyITSCuts{"isApplyITSCuts", false, "Enable ITS cuts (set to false for secondary estimation)"}; + Configurable isApplyChi2Cuts{"isApplyChi2Cuts", false, "Enable χ² cuts (set to false for secondary estimation)"}; + void init(InitContext const&) { - // Load DCA parametrisations from CCDB (matching piKpRAA) + // Load DCA parametrisations from CCDB (matching piKpRAA) if (!pathDCAxy.value.empty()) { cfgDCA.hDCAxy = ccdb->getForTimeStamp(pathDCAxy, ccdbNoLaterThan); if (cfgDCA.hDCAxy == nullptr) @@ -211,11 +225,11 @@ struct PtmultCorr { if (doprocessDataPbPb) { histos.add("hdatazvtxcent", "hdatazvtxcent", kTH2D, {axisVtxZ, centAxis}, false); - histos.add("hdatahistPbPb", "hdatahistPbPb", kTHnSparseD, {axisVtxZ, centAxis, axisPt, axisPhi, axisTrackType}, false); + histos.add("hdatahistPbPb", "hdatahistPbPb", kTHnSparseD, {axisVtxZ, centAxis, axisPt, axisPhi, axisTrackType, axisDCAxy}, false); } if (doprocessDatapp) { - histos.add("hdatahistpp", "hdatahistpp", kTHnSparseD, {axisVtxZ, axisPt, axisPhi, axisTrackType}, false); + histos.add("hdatahistpp", "hdatahistpp", kTHnSparseD, {axisVtxZ, axisPt, axisPhi, axisTrackType, axisDCAxy}, false); } if (doprocessMCeffPbPb) { @@ -224,12 +238,13 @@ struct PtmultCorr { histos.add("hPbPbGenMCAssoRecvtxz", "hPbPbGenMCAssoRecvtxz", kTH1D, {axisVtxZ}, false); histos.add("hPbPbGenMCAssoRecvtxzcent", "hPbPbGenMCAssoRecvtxzcent", kTH2D, {axisVtxZ, centAxis}, false); histos.add("hPbPbGenMCdndpt", "hPbPbGenMCdndpt", kTHnSparseD, {axisVtxZ, centAxis, axisPt, axisPhi}, false); + // axisGenTrkType now has 6 bins: kGenAll(1)…kGenOther(5), kGenAllCharged(6) histos.add("hPbPbGenMCAssoRecdndpt", "hPbPbGenMCAssoRecdndpt", kTHnSparseD, {axisVtxZ, centAxis, axisPt, axisPhi, axisGenTrkType, axisGenPtVary}, false); histos.add("hPbPbRecMCvtxz", "hPbPbRecMCvtxz", kTH1D, {axisVtxZ}, false); histos.add("hPbPbRecMCvtxzcent", "hPbPbRecMCvtxzcent", kTH2D, {axisVtxZ, centAxis}, false); histos.add("hPbPbRecMCcent", "hPbPbRecMCcent", kTH1D, {axisCent}, false); - histos.add("hPbPbRecMCdndpt", "hPbPbRecMCdndpt", kTHnSparseD, {axisVtxZ, centAxis, axisPt, axisPhi, axisRecTrkType, axisTrackType}, false); + histos.add("hPbPbRecMCdndpt", "hPbPbRecMCdndpt", kTHnSparseD, {axisVtxZ, centAxis, axisPt, axisPhi, axisRecTrkType, axisTrackType, axisDCAxy}, false); histos.add("hPbPbEtaReso", "hPbPbEtaReso", kTH2D, {axisPt, axisDeltaPt}); } @@ -237,10 +252,11 @@ struct PtmultCorr { histos.add("hppGenMCvtxz", "hppGenMCvtxz", kTH1D, {axisVtxZ}, false); histos.add("hppGenMCAssoRecvtxz", "hppGenMCAssoRecvtxz", kTH1D, {axisVtxZ}, false); histos.add("hppGenMCdndpt", "hppGenMCdndpt", kTHnSparseD, {axisVtxZ, axisPt, axisPhi}, false); + // axisGenTrkType now has 6 bins: kGenAll(1)…kGenOther(5), kGenAllCharged(6) histos.add("hppGenMCAssoRecdndpt", "hppGenMCAssoRecdndpt", kTHnSparseD, {axisVtxZ, axisPt, axisPhi, axisGenTrkType, axisGenPtVary}, false); histos.add("hppRecMCvtxz", "hppRecMCvtxz", kTH1D, {axisVtxZ}, false); - histos.add("hppRecMCdndpt", "hppRecMCdndpt", kTHnSparseD, {axisVtxZ, axisPt, axisPhi, axisRecTrkType, axisTrackType}, false); + histos.add("hppRecMCdndpt", "hppRecMCdndpt", kTHnSparseD, {axisVtxZ, axisPt, axisPhi, axisRecTrkType, axisTrackType, axisDCAxy}, false); histos.add("hppEtaReso", "hppEtaReso", kTH2D, {axisPt, axisDeltaPt}); } @@ -342,13 +358,22 @@ struct PtmultCorr { if (track.hasTPC()) { // ---- Global (ITS+TPC) tracks: - // ITS inner-barrel hit: must fire layer 0 or layer 1 - if (!(track.itsClusterMap() & 0x01) && !(track.itsClusterMap() & 0x02)) { - return false; - } - if (track.itsNCls() < cfgMinNClusITS) { - return false; + // ITS cuts: can be disabled for secondary estimation + if (isApplyITSCuts) { + // ITS inner-barrel hit: must fire layer 0 or layer 1 + if (!(track.itsClusterMap() & 0x01) && !(track.itsClusterMap() & 0x02)) { + return false; + } + if (track.itsNCls() < cfgMinNClusITS) { + return false; + } + // ITS chi2 cut (also part of ITS cuts) + if (track.itsChi2NCl() > cfgMaxChi2ClsITS) { + return false; + } } + + // TPC quality cuts (always applied) if (track.tpcNClsCrossedRows() < cfgMinNCrossedRows) { return false; } @@ -359,14 +384,16 @@ struct PtmultCorr { return false; } } - if (track.tpcChi2NCl() < cfgMinChi2ClsTPC || track.tpcChi2NCl() > cfgMaxChi2ClsTPC) { - return false; - } - if (track.itsChi2NCl() > cfgMaxChi2ClsITS) { - return false; + + // --- χ² cuts (can be disabled for secondary estimation) --- + if (isApplyChi2Cuts) { + if (track.tpcChi2NCl() < cfgMinChi2ClsTPC || track.tpcChi2NCl() > cfgMaxChi2ClsTPC) { + return false; + } } - // pT-dependent DCA cuts from CCDB - if (cfgDCA.loaded) { + + // pT-dependent DCA cuts (can be disabled for secondary estimation) + if (isApplyDCACuts && cfgDCA.loaded) { const float pt = track.pt(); const double dcaXYcut = cfgNSigmaDCAxy * (cfgDCA.hDCAxy->GetBinContent(1) + cfgDCA.hDCAxy->GetBinContent(2) / @@ -387,9 +414,12 @@ struct PtmultCorr { return false; } histos.fill(HIST("PhiVsEtaHistWithCut"), track.phi(), track.eta()); + return true; } + // Selects MC truth physical primaries (numerator for primary fraction). + // Requires: isPhysicalPrimary + producedByGenerator + charged + |eta| < etaRange template bool isGenTrackSelected(CheckGenTrack const& track) { @@ -415,14 +445,35 @@ struct PtmultCorr { return true; } - Filter fTrackSelectionITS = ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) && - ncheckbit(aod::track::trackCutFlag, TrackSelectionIts); - Filter fTrackSelectionTPC = ifnode(ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::TPC), - ncheckbit(aod::track::trackCutFlag, TrackSelectionTpc), true); - // DCA is now applied manually inside isTrackSelected() using pT-dependent CCDB parametrisation - Filter fTracksPt = aod::track::pt > cfgPtCutMin; + // ── CHANGE 2 ────────────────────────────────────────────────────────────── + // New helper: selects ALL charged particles in acceptance (denominator). + // Identical to isGenTrackSelected but WITHOUT the isPhysicalPrimary() check, + // so secondaries (weak-decay daughters, material interactions) also pass. + // Used to fill kGenAllCharged → primary fraction = kGenAll / kGenAllCharged. + // ────────────────────────────────────────────────────────────────────────── + template + bool isGenChargedTrackSelected(CheckGenTrack const& track) + { + if (!track.producedByGenerator()) { + return false; + } + auto pdgTrack = pdg->GetParticle(track.pdgCode()); + if (pdgTrack == nullptr) { + return false; + } + if (std::abs(pdgTrack->Charge()) < KminCharge) { + return false; + } + if (std::abs(track.eta()) >= etaRange) { + return false; + } + if (isApplyExtraPhiCut && ((track.phi() > extraphicut1 && track.phi() < extraphicut2) || track.phi() <= extraphicut3 || track.phi() >= extraphicut4)) { + return false; + } + return true; + } - void processDataPbPb(ColDataTablePbPb::iterator const& cols, FilTrackDataTable const& tracks) + void processDataPbPb(ColDataTablePbPb::iterator const& cols, TrackDataTable const& tracks) { if (!isEventSelected(cols)) { return; @@ -435,16 +486,16 @@ struct PtmultCorr { if (!isTrackSelected(track)) { continue; } - histos.fill(HIST("hdatahistPbPb"), cols.posZ(), cols.centFT0C(), track.pt(), track.phi(), kGlobalplusITS); + histos.fill(HIST("hdatahistPbPb"), cols.posZ(), cols.centFT0C(), track.pt(), track.phi(), kGlobalplusITS, track.dcaXY()); if (track.hasTPC()) { - histos.fill(HIST("hdatahistPbPb"), cols.posZ(), cols.centFT0C(), track.pt(), track.phi(), kGlobalonly); + histos.fill(HIST("hdatahistPbPb"), cols.posZ(), cols.centFT0C(), track.pt(), track.phi(), kGlobalonly, track.dcaXY()); } else { - histos.fill(HIST("hdatahistPbPb"), cols.posZ(), cols.centFT0C(), track.pt(), track.phi(), kITSonly); + histos.fill(HIST("hdatahistPbPb"), cols.posZ(), cols.centFT0C(), track.pt(), track.phi(), kITSonly, track.dcaXY()); } } } - void processDatapp(ColDataTablepp::iterator const& cols, FilTrackDataTable const& tracks) + void processDatapp(ColDataTablepp::iterator const& cols, TrackDataTable const& tracks) { if (!isEventSelected(cols)) { return; @@ -455,16 +506,16 @@ struct PtmultCorr { if (!isTrackSelected(track)) { continue; } - histos.fill(HIST("hdatahistpp"), cols.posZ(), track.pt(), track.phi(), kGlobalplusITS); + histos.fill(HIST("hdatahistpp"), cols.posZ(), track.pt(), track.phi(), kGlobalplusITS, track.dcaXY()); if (track.hasTPC()) { - histos.fill(HIST("hdatahistpp"), cols.posZ(), track.pt(), track.phi(), kGlobalonly); + histos.fill(HIST("hdatahistpp"), cols.posZ(), track.pt(), track.phi(), kGlobalonly, track.dcaXY()); } else { - histos.fill(HIST("hdatahistpp"), cols.posZ(), track.pt(), track.phi(), kITSonly); + histos.fill(HIST("hdatahistpp"), cols.posZ(), track.pt(), track.phi(), kITSonly, track.dcaXY()); } } } - void processMCeffPbPb(ColMCTrueTable::iterator const& mcCollision, ColMCRecTablePbPb const& RecCols, TrackMCTrueTable const& GenParticles, FilTrackMCRecTable const& RecTracks) + void processMCeffPbPb(ColMCTrueTable::iterator const& mcCollision, ColMCRecTablePbPb const& RecCols, TrackMCTrueTable const& GenParticles, TrackMCRecTable const& RecTracks) { auto gencent = -999; bool atLeastOne = false; @@ -484,10 +535,33 @@ struct PtmultCorr { histos.fill(HIST("hPbPbGenMCAssoRecvtxz"), mcCollision.posZ()); histos.fill(HIST("hPbPbGenMCAssoRecvtxzcent"), mcCollision.posZ(), gencent); } + + // ── CHANGE 3 ──────────────────────────────────────────────────────────── + // Restructured PbPb gen particle loop for primary fraction from MC truth. + // + // Pass 1 (loose): isGenChargedTrackSelected — all charged in acceptance. + // → fills kGenAllCharged (denominator) when associated with a reco event. + // + // Pass 2 (tight): additionally require isPhysicalPrimary (via continue). + // → fills kGenAll and species bins (numerator) — identical to before. + // + // Primary fraction (PbPb) = hPbPbGenMCAssoRecdndpt[kGenAll] + // / hPbPbGenMCAssoRecdndpt[kGenAllCharged] per pT bin + // ──────────────────────────────────────────────────────────────────────── for (const auto& particle : GenParticles) { - if (!isGenTrackSelected(particle)) { + // Loose check: charged + |eta| + phi (no isPhysicalPrimary requirement) + if (!isGenChargedTrackSelected(particle)) { + continue; + } + // Fill denominator: all charged particles (primaries + secondaries) + if (atLeastOne) { + histos.fill(HIST("hPbPbGenMCAssoRecdndpt"), mcCollision.posZ(), gencent, particle.pt(), particle.phi(), static_cast(kGenAllCharged), kNoGenpTVar); + } + // Tight check: physical primaries only — skip secondaries from this point on + if (!particle.isPhysicalPrimary()) { continue; } + // Fill primary-only histograms (numerator + species breakdown) histos.fill(HIST("hPbPbGenMCdndpt"), mcCollision.posZ(), gencent, particle.pt(), particle.phi()); if (atLeastOne) { histos.fill(HIST("hPbPbGenMCAssoRecdndpt"), mcCollision.posZ(), gencent, particle.pt(), particle.phi(), static_cast(kGenAll), kNoGenpTVar); @@ -535,18 +609,18 @@ struct PtmultCorr { } auto trkType = Rectrack.hasTPC() ? kGlobalonly : kITSonly; - histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), Rectrack.pt(), Rectrack.phi(), static_cast(kRecoAll), kGlobalplusITS); - histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), Rectrack.pt(), Rectrack.phi(), static_cast(kRecoAll), trkType); + histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), Rectrack.pt(), Rectrack.phi(), static_cast(kRecoAll), kGlobalplusITS, Rectrack.dcaXY()); + histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), Rectrack.pt(), Rectrack.phi(), static_cast(kRecoAll), trkType, Rectrack.dcaXY()); if (Rectrack.has_mcParticle()) { int pid = 0; auto mcpart = Rectrack.mcParticle(); histos.fill(HIST("hPbPbEtaReso"), Rectrack.pt(), Rectrack.pt() - mcpart.pt()); - histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), mcpart.pt(), mcpart.phi(), static_cast(kRecoHasmc), kGlobalplusITS); - histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), mcpart.pt(), mcpart.phi(), static_cast(kRecoHasmc), trkType); + histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), mcpart.pt(), mcpart.phi(), static_cast(kRecoHasmc), kGlobalplusITS, Rectrack.dcaXY()); + histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), mcpart.pt(), mcpart.phi(), static_cast(kRecoHasmc), trkType, Rectrack.dcaXY()); if (mcpart.isPhysicalPrimary()) { - histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), mcpart.pt(), mcpart.phi(), static_cast(kRecoPrimary), kGlobalplusITS); - histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), mcpart.pt(), mcpart.phi(), static_cast(kRecoPrimary), trkType); + histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), mcpart.pt(), mcpart.phi(), static_cast(kRecoPrimary), kGlobalplusITS, Rectrack.dcaXY()); + histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), mcpart.pt(), mcpart.phi(), static_cast(kRecoPrimary), trkType, Rectrack.dcaXY()); switch (std::abs(mcpart.pdgCode())) { case PDG_t::kPiPlus: pid = kRecoPion; @@ -574,17 +648,17 @@ struct PtmultCorr { pid = kRecoFake; } mclabels.push_back(Rectrack.mcParticleId()); - histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), mcpart.pt(), mcpart.phi(), static_cast(pid), kGlobalplusITS); - histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), mcpart.pt(), mcpart.phi(), static_cast(pid), trkType); + histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), mcpart.pt(), mcpart.phi(), static_cast(pid), kGlobalplusITS, Rectrack.dcaXY()); + histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), mcpart.pt(), mcpart.phi(), static_cast(pid), trkType, Rectrack.dcaXY()); } else { - histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), Rectrack.pt(), Rectrack.phi(), static_cast(kRecoBkg), kGlobalplusITS); - histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), Rectrack.pt(), Rectrack.phi(), static_cast(kRecoBkg), trkType); + histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), Rectrack.pt(), Rectrack.phi(), static_cast(kRecoBkg), kGlobalplusITS, Rectrack.dcaXY()); + histos.fill(HIST("hPbPbRecMCdndpt"), RecCol.posZ(), RecCol.centFT0C(), Rectrack.pt(), Rectrack.phi(), static_cast(kRecoBkg), trkType, Rectrack.dcaXY()); } } // track (mcrec) loop } // collision loop } - void processMCeffpp(ColMCTrueTable::iterator const& mcCollision, ColMCRecTablepp const& RecCols, TrackMCTrueTable const& GenParticles, FilTrackMCRecTable const& RecTracks) + void processMCeffpp(ColMCTrueTable::iterator const& mcCollision, ColMCRecTablepp const& RecCols, TrackMCTrueTable const& GenParticles, TrackMCRecTable const& RecTracks) { bool atLeastOne = false; for (const auto& RecCol : RecCols) { @@ -600,10 +674,33 @@ struct PtmultCorr { if (atLeastOne) { histos.fill(HIST("hppGenMCAssoRecvtxz"), mcCollision.posZ()); } + + // ── CHANGE 4 ──────────────────────────────────────────────────────────── + // Restructured pp gen particle loop for primary fraction from MC truth. + // + // Pass 1 (loose): isGenChargedTrackSelected — all charged in acceptance. + // → fills kGenAllCharged (denominator) when associated with a reco event. + // + // Pass 2 (tight): additionally require isPhysicalPrimary (via continue). + // → fills kGenAll and species bins (numerator) — identical to before. + // + // Primary fraction (pp) = hppGenMCAssoRecdndpt[kGenAll] + // / hppGenMCAssoRecdndpt[kGenAllCharged] per pT bin + // ──────────────────────────────────────────────────────────────────────── for (const auto& particle : GenParticles) { - if (!isGenTrackSelected(particle)) { + // Loose check: charged + |eta| + phi (no isPhysicalPrimary requirement) + if (!isGenChargedTrackSelected(particle)) { + continue; + } + // Fill denominator: all charged particles (primaries + secondaries) + if (atLeastOne) { + histos.fill(HIST("hppGenMCAssoRecdndpt"), mcCollision.posZ(), particle.pt(), particle.phi(), static_cast(kGenAllCharged), kNoGenpTVar); + } + // Tight check: physical primaries only — skip secondaries from this point on + if (!particle.isPhysicalPrimary()) { continue; } + // Fill primary-only histograms (numerator + species breakdown) histos.fill(HIST("hppGenMCdndpt"), mcCollision.posZ(), particle.pt(), particle.phi()); if (atLeastOne) { histos.fill(HIST("hppGenMCAssoRecdndpt"), mcCollision.posZ(), particle.pt(), particle.phi(), static_cast(kGenAll), kNoGenpTVar); @@ -648,17 +745,17 @@ struct PtmultCorr { continue; } auto trkType = Rectrack.hasTPC() ? kGlobalonly : kITSonly; - histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), Rectrack.pt(), Rectrack.phi(), static_cast(kRecoAll), kGlobalplusITS); - histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), Rectrack.pt(), Rectrack.phi(), static_cast(kRecoAll), trkType); + histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), Rectrack.pt(), Rectrack.phi(), static_cast(kRecoAll), kGlobalplusITS, Rectrack.dcaXY()); + histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), Rectrack.pt(), Rectrack.phi(), static_cast(kRecoAll), trkType, Rectrack.dcaXY()); if (Rectrack.has_mcParticle()) { int pid = 0; auto mcpart = Rectrack.mcParticle(); histos.fill(HIST("hppEtaReso"), Rectrack.pt(), Rectrack.pt() - mcpart.pt()); - histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), mcpart.pt(), mcpart.phi(), static_cast(kRecoHasmc), kGlobalplusITS); - histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), mcpart.pt(), mcpart.phi(), static_cast(kRecoHasmc), trkType); + histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), mcpart.pt(), mcpart.phi(), static_cast(kRecoHasmc), kGlobalplusITS, Rectrack.dcaXY()); + histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), mcpart.pt(), mcpart.phi(), static_cast(kRecoHasmc), trkType, Rectrack.dcaXY()); if (mcpart.isPhysicalPrimary()) { - histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), mcpart.pt(), mcpart.phi(), static_cast(kRecoPrimary), kGlobalplusITS); - histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), mcpart.pt(), mcpart.phi(), static_cast(kRecoPrimary), trkType); + histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), mcpart.pt(), mcpart.phi(), static_cast(kRecoPrimary), kGlobalplusITS, Rectrack.dcaXY()); + histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), mcpart.pt(), mcpart.phi(), static_cast(kRecoPrimary), trkType, Rectrack.dcaXY()); switch (std::abs(mcpart.pdgCode())) { case PDG_t::kPiPlus: pid = kRecoPion; @@ -686,11 +783,11 @@ struct PtmultCorr { pid = kRecoFake; } mclabels.push_back(Rectrack.mcParticleId()); - histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), mcpart.pt(), mcpart.phi(), static_cast(pid), kGlobalplusITS); - histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), mcpart.pt(), mcpart.phi(), static_cast(pid), trkType); + histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), mcpart.pt(), mcpart.phi(), static_cast(pid), kGlobalplusITS, Rectrack.dcaXY()); + histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), mcpart.pt(), mcpart.phi(), static_cast(pid), trkType, Rectrack.dcaXY()); } else { - histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), Rectrack.pt(), Rectrack.phi(), static_cast(kRecoBkg), kGlobalplusITS); - histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), Rectrack.pt(), Rectrack.phi(), static_cast(kRecoBkg), trkType); + histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), Rectrack.pt(), Rectrack.phi(), static_cast(kRecoBkg), kGlobalplusITS, Rectrack.dcaXY()); + histos.fill(HIST("hppRecMCdndpt"), RecCol.posZ(), Rectrack.pt(), Rectrack.phi(), static_cast(kRecoBkg), trkType, Rectrack.dcaXY()); } } // track (mcrec) loop } // collision loop From 2723547950408e175305c3a9f2bf3eb2628ef3f9 Mon Sep 17 00:00:00 2001 From: akyadav1963 <84583181+akyadav1963@users.noreply.github.com> Date: Fri, 5 Jun 2026 20:24:22 +0530 Subject: [PATCH 2/3] Update PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Vít Kučera <26327373+vkucera@users.noreply.github.com> --- PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx b/PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx index 712c70e1625..a84ce2ef875 100644 --- a/PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx +++ b/PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx @@ -193,9 +193,9 @@ struct PtmultCorr { Configurable isApplyOccuCut{"isApplyOccuCut", false, "Enable occupancy selection"}; // Secondary estimation related configurables - Configurable isApplyDCACuts{"isApplyDCACuts", false, "Enable DCA cuts (set to false for secondary estimation)"}; - Configurable isApplyITSCuts{"isApplyITSCuts", false, "Enable ITS cuts (set to false for secondary estimation)"}; - Configurable isApplyChi2Cuts{"isApplyChi2Cuts", false, "Enable χ² cuts (set to false for secondary estimation)"}; + Configurable applyDCACuts{"isApplyDCACuts", false, "Enable DCA cuts (set to false for secondary estimation)"}; + Configurable applyITSCuts{"isApplyITSCuts", false, "Enable ITS cuts (set to false for secondary estimation)"}; + Configurable applyChi2Cuts{"isApplyChi2Cuts", false, "Enable χ² cuts (set to false for secondary estimation)"}; void init(InitContext const&) { From dd9b0b4b8f007c83c2fcc21913b58a1273168507 Mon Sep 17 00:00:00 2001 From: akyadav1963 Date: Fri, 5 Jun 2026 21:54:52 +0530 Subject: [PATCH 3/3] Revert configurable renaming --- PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx b/PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx index a84ce2ef875..712c70e1625 100644 --- a/PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx +++ b/PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx @@ -193,9 +193,9 @@ struct PtmultCorr { Configurable isApplyOccuCut{"isApplyOccuCut", false, "Enable occupancy selection"}; // Secondary estimation related configurables - Configurable applyDCACuts{"isApplyDCACuts", false, "Enable DCA cuts (set to false for secondary estimation)"}; - Configurable applyITSCuts{"isApplyITSCuts", false, "Enable ITS cuts (set to false for secondary estimation)"}; - Configurable applyChi2Cuts{"isApplyChi2Cuts", false, "Enable χ² cuts (set to false for secondary estimation)"}; + Configurable isApplyDCACuts{"isApplyDCACuts", false, "Enable DCA cuts (set to false for secondary estimation)"}; + Configurable isApplyITSCuts{"isApplyITSCuts", false, "Enable ITS cuts (set to false for secondary estimation)"}; + Configurable isApplyChi2Cuts{"isApplyChi2Cuts", false, "Enable χ² cuts (set to false for secondary estimation)"}; void init(InitContext const&) {