From c2cc80d158c7b3618172de175859a089a7a39bb3 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Wed, 10 Sep 2025 10:04:37 +0800 Subject: [PATCH 01/11] Polished histograms naming --- .../Tasks/Strangeness/phik0shortanalysis.cxx | 108 ++++-------------- 1 file changed, 22 insertions(+), 86 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx index 076609b91b9..b7212c0be73 100644 --- a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx @@ -225,7 +225,6 @@ struct Phik0shortanalysis { Configurable applyEfficiency{"applyEfficiency", false, "Use efficiency for filling histograms"}; // Configurables for dN/deta with phi computation - Configurable furtherCheckonMcCollision{"furtherCheckonMcCollision", true, "Further check on MC collisions"}; Configurable filterOnGenPhi{"filterOnGenPhi", 1, "Filter on Gen Phi (0: K+K- pair like Phi, 1: proper Phi)"}; Configurable filterOnRecoPhi{"filterOnRecoPhi", 1, "Filter on Reco Phi (0: without PDG, 1: with PDG)"}; Configurable fillMcPartsForAllReco{"fillMcPartsForAllReco", false, "Fill MC particles for all associated reco collisions"}; @@ -399,16 +398,13 @@ struct Phik0shortanalysis { mcEventHist.add("hGenMCAssocRecoMultiplicityPercent", "GenMC AssocReco Multiplicity Percentile", kTH1F, {binnedmultAxis}); mcEventHist.add("h2GenMCAssocRecoVertexZvsMult", "GenMC AssocReco Vertex Z vs Multiplicity Percentile", kTH2F, {vertexZAxis, binnedmultAxis}); mcEventHist.add("hGenMCRecoMultiplicityPercent", "GenMCReco Multiplicity Percentile", kTH1F, {binnedmultAxis}); - mcEventHist.add("h2GenMCRecoVertexZvsMult", "GenMCReco Vertex Z vs Multiplicity Percentile", kTH2F, {vertexZAxis, binnedmultAxis}); // Eta distribution for dN/deta values estimation in MC mcEventHist.add("h6RecoMCEtaDistribution", "Eta vs multiplicity in MCReco", kTHnSparseF, {vertexZAxis, binnedmultAxis, etaAxis, phiAxis, {6, -0.5f, 5.5f}, {3, -0.5f, 2.5f}}); - mcEventHist.add("h6RecoCheckMCEtaDistribution", "Eta vs multiplicity in MCReco Check", kTHnSparseF, {vertexZAxis, binnedmultAxis, etaAxis, phiAxis, {6, -0.5f, 5.5f}, {3, -0.5f, 2.5f}}); mcEventHist.add("h5GenMCEtaDistribution", "Eta vs multiplicity in MCGen", kTHnSparseF, {binnedmultAxis, etaAxis, phiAxis, {6, -0.5f, 5.5f}, {3, -0.5f, 2.5f}}); - mcEventHist.add("h6GenMCEtaDistributionAssocReco", "Eta vs multiplicity in MCGen Assoc Reco", kTHnSparseF, {vertexZAxis, binnedmultAxis, etaAxis, phiAxis, {6, -0.5f, 5.5f}, {3, -0.5f, 2.5f}}); - mcEventHist.add("h6GenMCEtaDistributionReco", "Eta vs multiplicity in MCGen Reco", kTHnSparseF, {vertexZAxis, binnedmultAxis, etaAxis, phiAxis, {6, -0.5f, 5.5f}, {3, -0.5f, 2.5f}}); - mcEventHist.add("h6GenMCEtaDistributionRecoCheck", "Eta vs multiplicity in MCGen Reco Check", kTHnSparseF, {vertexZAxis, binnedmultAxis, etaAxis, phiAxis, {6, -0.5f, 5.5f}, {3, -0.5f, 2.5f}}); + mcEventHist.add("h6GenMCAssocRecoEtaDistribution", "Eta vs multiplicity in MCGen Assoc Reco", kTHnSparseF, {vertexZAxis, binnedmultAxis, etaAxis, phiAxis, {6, -0.5f, 5.5f}, {3, -0.5f, 2.5f}}); + mcEventHist.add("h6GenMCAllAssocRecoEtaDistribution", "Eta vs multiplicity in MCGen Reco", kTHnSparseF, {vertexZAxis, binnedmultAxis, etaAxis, phiAxis, {6, -0.5f, 5.5f}, {3, -0.5f, 2.5f}}); // Phi topological/PID cuts dataPhiHist.add("h2DauTracksPhiDCAxyPreCutData", "Dcaxy distribution vs pt before DCAxy cut", kTH2F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}, {2000, -0.05, 0.05, "DCA_{xy} (cm)"}}); @@ -2636,67 +2632,7 @@ struct Phik0shortanalysis { PROCESS_SWITCH(Phik0shortanalysis, processdNdetaWPhiData, "Process function for dN/deta values in Data", false); - void processdNdetaWPhiMCReco(SimCollisions::iterator const& collision, FilteredMCTracks const& filteredMCTracks, MCCollisions const&, aod::McParticles const& mcParticles) - { - if (!acceptEventQA(collision, true)) - return; - if (!collision.has_mcCollision()) - return; - - const auto& mcCollision = collision.mcCollision_as(); - auto mcParticlesThisColl = mcParticles.sliceBy(preslices.perMCColl, mcCollision.globalIndex()); - - if (furtherCheckonMcCollision && (std::abs(mcCollision.posZ()) > cutZVertex || !pwglf::isINELgtNmc(mcParticlesThisColl, 0, pdgDB))) - return; - if (filterOnGenPhi && !eventHasGenPhi(mcParticlesThisColl)) - return; - - mcEventHist.fill(HIST("hRecoMCMultiplicityPercent"), mcCollision.centFT0M()); - mcEventHist.fill(HIST("h2RecoMCVertexZvsMult"), collision.posZ(), mcCollision.centFT0M()); - - for (const auto& track : filteredMCTracks) { - if (trackConfigs.applyExtraPhiCuts && ((track.phi() > trackConfigs.extraPhiCuts->at(0) && track.phi() < trackConfigs.extraPhiCuts->at(1)) || - track.phi() <= trackConfigs.extraPhiCuts->at(2) || track.phi() >= trackConfigs.extraPhiCuts->at(3))) - continue; - if (!track.has_mcParticle()) - continue; - - auto mcTrack = track.mcParticle_as(); - if (!mcTrack.isPhysicalPrimary() || std::abs(mcTrack.eta()) > trackConfigs.etaMax) - continue; - - mcEventHist.fill(HIST("h6RecoMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kGlobalplusITSonly); - if (track.hasTPC()) { - mcEventHist.fill(HIST("h6RecoMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kGlobalonly); - } else { - mcEventHist.fill(HIST("h6RecoMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kITSonly); - } - - int pid = fromPDGToEnum(mcTrack.pdgCode()); - mcEventHist.fill(HIST("h6RecoMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), pid, kGlobalplusITSonly); - } - - for (const auto& mcParticle : mcParticlesThisColl) { - if (!isGenParticleCharged(mcParticle)) - continue; - - mcEventHist.fill(HIST("h6GenMCEtaDistributionReco"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kNoGenpTVar); - if (mcParticle.pt() < trackConfigs.cMinChargedParticlePtcut) { - mcEventHist.fill(HIST("h6GenMCEtaDistributionReco"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup, -10.0f * mcParticle.pt() + 2.0f); - mcEventHist.fill(HIST("h6GenMCEtaDistributionReco"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown, 5.0f * mcParticle.pt() + 0.5f); - } else { - mcEventHist.fill(HIST("h6GenMCEtaDistributionReco"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup); - mcEventHist.fill(HIST("h6GenMCEtaDistributionReco"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown); - } - - int pid = fromPDGToEnum(mcParticle.pdgCode()); - mcEventHist.fill(HIST("h6GenMCEtaDistributionReco"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), pid, kNoGenpTVar); - } - } - - PROCESS_SWITCH(Phik0shortanalysis, processdNdetaWPhiMCReco, "Process function for dN/deta values in MCReco", false); - - void processdNdetaWPhiMCGen(MCCollisions const& mcCollisions, SimCollisions const& collisions, FilteredMCTracks const& filteredMCTracks, aod::McParticles const& mcParticles) + void processdNdetaWPhiMC(MCCollisions const& mcCollisions, SimCollisions const& collisions, FilteredMCTracks const& filteredMCTracks, aod::McParticles const& mcParticles) { std::vector> collsGrouped(mcCollisions.size()); @@ -2752,8 +2688,8 @@ struct Phik0shortanalysis { break; } - mcEventHist.fill(HIST("hGenMCRecoMultiplicityPercent"), mcCollision.centFT0M()); - mcEventHist.fill(HIST("h2GenMCRecoVertexZvsMult"), collision.posZ(), mcCollision.centFT0M()); + mcEventHist.fill(HIST("hRecoMCMultiplicityPercent"), mcCollision.centFT0M()); + mcEventHist.fill(HIST("h2RecoMCVertexZvsMult"), collision.posZ(), mcCollision.centFT0M()); zVtxs.push_back(collision.posZ()); @@ -2768,15 +2704,15 @@ struct Phik0shortanalysis { if (!mcTrack.isPhysicalPrimary() || std::abs(mcTrack.eta()) > trackConfigs.etaMax) continue; - mcEventHist.fill(HIST("h6RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kGlobalplusITSonly); + mcEventHist.fill(HIST("h6RecoMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kGlobalplusITSonly); if (track.hasTPC()) { - mcEventHist.fill(HIST("h6RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kGlobalonly); + mcEventHist.fill(HIST("h6RecoMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kGlobalonly); } else { - mcEventHist.fill(HIST("h6RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kITSonly); + mcEventHist.fill(HIST("h6RecoMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kITSonly); } int pid = fromPDGToEnum(mcTrack.pdgCode()); - mcEventHist.fill(HIST("h6RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), pid, kGlobalplusITSonly); + mcEventHist.fill(HIST("h6RecoMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), pid, kGlobalplusITSonly); } if (fillMcPartsForAllReco) { @@ -2784,17 +2720,17 @@ struct Phik0shortanalysis { if (!isGenParticleCharged(mcParticle)) continue; - mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kNoGenpTVar); + mcEventHist.fill(HIST("h6GenMCAllAssocRecoEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kNoGenpTVar); if (mcParticle.pt() < trackConfigs.cMinChargedParticlePtcut) { - mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup, -10.0f * mcParticle.pt() + 2.0f); - mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown, 5.0f * mcParticle.pt() + 0.5f); + mcEventHist.fill(HIST("h6GenMCAllAssocRecoEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup, -10.0f * mcParticle.pt() + 2.0f); + mcEventHist.fill(HIST("h6GenMCAllAssocRecoEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown, 5.0f * mcParticle.pt() + 0.5f); } else { - mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup); - mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown); + mcEventHist.fill(HIST("h6GenMCAllAssocRecoEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup); + mcEventHist.fill(HIST("h6GenMCAllAssocRecoEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown); } int pid = fromPDGToEnum(mcParticle.pdgCode()); - mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), pid, kNoGenpTVar); + mcEventHist.fill(HIST("h6GenMCAllAssocRecoEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), pid, kNoGenpTVar); } } @@ -2835,21 +2771,21 @@ struct Phik0shortanalysis { if (numberAssocColl > 0) { float zVtxRef = zVtxs[0]; - mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kNoGenpTVar); + mcEventHist.fill(HIST("h6GenMCAssocRecoEtaDistribution"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kNoGenpTVar); if (mcParticle.pt() < trackConfigs.cMinChargedParticlePtcut) { - mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup, -10.0f * mcParticle.pt() + 2.0f); - mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown, 5.0f * mcParticle.pt() + 0.5f); + mcEventHist.fill(HIST("h6GenMCAssocRecoEtaDistribution"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup, -10.0f * mcParticle.pt() + 2.0f); + mcEventHist.fill(HIST("h6GenMCAssocRecoEtaDistribution"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown, 5.0f * mcParticle.pt() + 0.5f); } else { - mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup); - mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown); + mcEventHist.fill(HIST("h6GenMCAssocRecoEtaDistribution"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup); + mcEventHist.fill(HIST("h6GenMCAssocRecoEtaDistribution"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown); } - mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), pid, kNoGenpTVar); + mcEventHist.fill(HIST("h6GenMCAssocRecoEtaDistribution"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), pid, kNoGenpTVar); } } } } - PROCESS_SWITCH(Phik0shortanalysis, processdNdetaWPhiMCGen, "Process function for dN/deta values in MCGen", false); + PROCESS_SWITCH(Phik0shortanalysis, processdNdetaWPhiMC, "Process function for dN/deta values in MC", false); // New 2D analysis procedure void processPhiK0SPionData2D(SelCollisions::iterator const& collision, FullTracks const& fullTracks, FullV0s const& V0s, V0DauTracks const&) From de95729ead3e30c18dbd9884aed6a407b8d5e60c Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Thu, 11 Sep 2025 12:43:25 +0800 Subject: [PATCH 02/11] First commit to merge process function for particle efficiencies --- .../Tasks/Strangeness/phik0shortanalysis.cxx | 344 +++++++++--------- 1 file changed, 175 insertions(+), 169 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx index b7212c0be73..2bdb44c0954 100644 --- a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx @@ -3027,226 +3027,232 @@ struct Phik0shortanalysis { PROCESS_SWITCH(Phik0shortanalysis, processPhiK0SPionMCClosure2D, "Process function for Phi-K0S and Phi-Pion Correlations in MCClosure2D", false); - void processAllPartMCReco(SimCollisions::iterator const& collision, FullMCTracks const& fullMCTracks, FullMCV0s const& V0s, V0DauMCTracks const&, MCCollisions const&, aod::McParticles const& mcParticles) + void processAllPartMC(MCCollisions const& mcCollisions, SimCollisions const& collisions, FullMCTracks const& fullMCTracks, FullMCV0s const& V0s, V0DauMCTracks const&, aod::McParticles const& mcParticles) { - if (!acceptEventQA(collision, false)) - return; - - if (!collision.has_mcCollision()) - return; - - const auto& mcCollision = collision.mcCollision_as(); - float genmultiplicity = mcCollision.centFT0M(); - // Defining positive and negative tracks for phi reconstruction - auto posThisColl = posMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - auto negThisColl = negMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + std::vector> collsGrouped(mcCollisions.size()); - for (const auto& track1 : posThisColl) { // loop over all selected tracks - if (!selectionTrackResonance(track1, false) || !selectionPIDKaonpTdependent(track1)) - continue; // topological and PID selection + for (const auto& collision : collisions) { + if (!collision.has_mcCollision()) + continue; + const auto& mcCollision = collision.mcCollision_as(); + collsGrouped[mcCollision.globalIndex()].push_back(collision.globalIndex()); + } - auto track1ID = track1.globalIndex(); + for (const auto& mcCollision : mcCollisions) { + auto mcParticlesThisMcColl = mcParticles.sliceBy(preslices.perMCColl, mcCollision.globalIndex()); - if (!track1.has_mcParticle()) - continue; - auto mcTrack1 = track1.mcParticle_as(); - if (mcTrack1.pdgCode() != PDG_t::kKPlus || !mcTrack1.isPhysicalPrimary()) + if (!pwglf::isINELgtNmc(mcParticlesThisMcColl, 0, pdgDB)) continue; + switch (filterOnGenPhi) { + case 0: + if (!eventHasGenKPair(mcParticlesThisMcColl)) + continue; + break; + case 1: + if (!eventHasGenPhi(mcParticlesThisMcColl)) + continue; + break; + default: + break; + } - for (const auto& track2 : negThisColl) { - if (!selectionTrackResonance(track2, false) || !selectionPIDKaonpTdependent(track2)) - continue; // topological and PID selection + uint64_t numberAssocColl = 0; + std::vector zVtxs; - auto track2ID = track2.globalIndex(); - if (track2ID == track1ID) - continue; // condition to avoid double counting of pair + auto& collIndexesThisMcColl = collsGrouped[mcCollision.globalIndex()]; - if (!track2.has_mcParticle()) - continue; - auto mcTrack2 = track2.mcParticle_as(); - if (mcTrack2.pdgCode() != PDG_t::kKMinus || !mcTrack2.isPhysicalPrimary()) - continue; + for (const auto& collisionIndex : collIndexesThisMcColl) { + auto collision = collisions.rawIteratorAt(collisionIndex); - float pTMother = -1.0f; - float yMother = -1.0f; - bool isMCMotherPhi = false; - for (const auto& motherOfMcTrack1 : mcTrack1.mothers_as()) { - for (const auto& motherOfMcTrack2 : mcTrack2.mothers_as()) { - if (motherOfMcTrack1.pdgCode() != motherOfMcTrack2.pdgCode()) - continue; - if (motherOfMcTrack1.globalIndex() != motherOfMcTrack2.globalIndex()) - continue; - if (motherOfMcTrack1.pdgCode() != o2::constants::physics::Pdg::kPhi) - continue; + if (acceptEventQA(collision, false)) { + //// + auto filteredMCTracksThisColl = filteredMCTracks.sliceBy(preslices.perColl, collision.globalIndex()); - pTMother = motherOfMcTrack1.pt(); - yMother = motherOfMcTrack1.y(); - isMCMotherPhi = true; + posFiltMCTracks.bindTable(filteredMCTracksThisColl); + negFiltMCTracks.bindTable(filteredMCTracksThisColl); + //// + + switch (filterOnRecoPhi) { + case 0: + if (!eventHasRecoPhi(posFiltMCTracks, negFiltMCTracks)) + continue; + break; + case 1: + if (!eventHasRecoPhiWPDG(posFiltMCTracks, negFiltMCTracks, mcParticles)) + continue; + break; + default: + break; } - } - if (!isMCMotherPhi) - continue; - if (pTMother < phiConfigs.minPhiPt || std::abs(yMother) > deltaYConfigs.cfgYAcceptance) - continue; + mcEventHist.fill(HIST("hRecoMCMultiplicityPercent"), mcCollision.centFT0M()); + mcEventHist.fill(HIST("h2RecoMCVertexZvsMult"), collision.posZ(), mcCollision.centFT0M()); - mcPhiHist.fill(HIST("h3PhiMCRecoNewProc"), genmultiplicity, pTMother, yMother); - } - } + zVtxs.push_back(collision.posZ()); - for (const auto& v0 : V0s) { - if (!v0.has_mcParticle()) - continue; + //// + // Defining positive and negative tracks for phi reconstruction + auto posThisColl = posMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto negThisColl = negMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - auto v0mcparticle = v0.mcParticle(); - if (v0mcparticle.pdgCode() != PDG_t::kK0Short || !v0mcparticle.isPhysicalPrimary()) - continue; + for (const auto& track1 : posThisColl) { // loop over all selected tracks + if (!selectionTrackResonance(track1, false) || !selectionPIDKaonpTdependent(track1)) + continue; // topological and PID selection - const auto& posDaughterTrack = v0.posTrack_as(); - const auto& negDaughterTrack = v0.negTrack_as(); + auto track1ID = track1.globalIndex(); - if (!selectionV0(v0, posDaughterTrack, negDaughterTrack)) - continue; - if (v0Configs.cfgFurtherV0Selection && !furtherSelectionV0(v0, collision)) - continue; - if (std::abs(v0mcparticle.y()) > deltaYConfigs.cfgYAcceptance) - continue; + if (!track1.has_mcParticle()) + continue; + auto mcTrack1 = track1.mcParticle_as(); + if (mcTrack1.pdgCode() != PDG_t::kKPlus || !mcTrack1.isPhysicalPrimary()) + continue; - mcK0SHist.fill(HIST("h3K0SMCRecoNewProc"), genmultiplicity, v0mcparticle.pt(), v0mcparticle.y()); - } + for (const auto& track2 : negThisColl) { + if (!selectionTrackResonance(track2, false) || !selectionPIDKaonpTdependent(track2)) + continue; // topological and PID selection - for (const auto& track : fullMCTracks) { - // Pion selection - if (!selectionPion(track, false)) - continue; + auto track2ID = track2.globalIndex(); + if (track2ID == track1ID) + continue; // condition to avoid double counting of pair - if (!track.has_mcParticle()) - continue; + if (!track2.has_mcParticle()) + continue; + auto mcTrack2 = track2.mcParticle_as(); + if (mcTrack2.pdgCode() != PDG_t::kKMinus || !mcTrack2.isPhysicalPrimary()) + continue; - auto mcTrack = track.mcParticle_as(); - if (std::abs(mcTrack.pdgCode()) != PDG_t::kPiPlus) - continue; + float pTMother = -1.0f; + float yMother = -1.0f; + bool isMCMotherPhi = false; + for (const auto& motherOfMcTrack1 : mcTrack1.mothers_as()) { + for (const auto& motherOfMcTrack2 : mcTrack2.mothers_as()) { + if (motherOfMcTrack1.pdgCode() != motherOfMcTrack2.pdgCode()) + continue; + if (motherOfMcTrack1.globalIndex() != motherOfMcTrack2.globalIndex()) + continue; + if (motherOfMcTrack1.pdgCode() != o2::constants::physics::Pdg::kPhi) + continue; + + pTMother = motherOfMcTrack1.pt(); + yMother = motherOfMcTrack1.y(); + isMCMotherPhi = true; + } + } - if (std::abs(mcTrack.y()) > deltaYConfigs.cfgYAcceptance) - continue; + if (!isMCMotherPhi) + continue; + if (pTMother < phiConfigs.minPhiPt || std::abs(yMother) > deltaYConfigs.cfgYAcceptance) + continue; - // Primary pion selection - if (mcTrack.isPhysicalPrimary()) { - mcPionHist.fill(HIST("h3RecMCDCAxyPrimPi"), track.pt(), track.dcaXY()); - } else { - if (mcTrack.getProcess() == 4) { // Selection of secondary pions from weak decay - mcPionHist.fill(HIST("h3RecMCDCAxySecWeakDecayPi"), track.pt(), track.dcaXY()); - } else { // Selection of secondary pions from material interactions - mcPionHist.fill(HIST("h3RecMCDCAxySecMaterialPi"), track.pt(), track.dcaXY()); - } - continue; - } + mcPhiHist.fill(HIST("h3PhiMCRecoNewProc"), genmultiplicity, pTMother, yMother); + } + } - mcPionHist.fill(HIST("h3PiMCRecoNewProc"), genmultiplicity, mcTrack.pt(), mcTrack.y()); + for (const auto& v0 : V0s) { + if (!v0.has_mcParticle()) + continue; - if (track.pt() >= trackConfigs.pTToUseTOF && !track.hasTOF()) - continue; + auto v0mcparticle = v0.mcParticle(); + if (v0mcparticle.pdgCode() != PDG_t::kK0Short || !v0mcparticle.isPhysicalPrimary()) + continue; - mcPionHist.fill(HIST("h3PiMCReco2NewProc"), genmultiplicity, mcTrack.pt(), mcTrack.y()); - } + const auto& posDaughterTrack = v0.posTrack_as(); + const auto& negDaughterTrack = v0.negTrack_as(); - // Defining McParticles in the collision - auto mcParticlesThisColl = mcParticles.sliceByCached(aod::mcparticle::mcCollisionId, mcCollision.globalIndex(), cache); + if (!selectionV0(v0, posDaughterTrack, negDaughterTrack)) + continue; + if (v0Configs.cfgFurtherV0Selection && !furtherSelectionV0(v0, collision)) + continue; + if (std::abs(v0mcparticle.y()) > deltaYConfigs.cfgYAcceptance) + continue; - for (const auto& mcParticle : mcParticlesThisColl) { - if (std::abs(mcParticle.y()) > deltaYConfigs.cfgYAcceptance) - continue; + mcK0SHist.fill(HIST("h3K0SMCRecoNewProc"), genmultiplicity, v0mcparticle.pt(), v0mcparticle.y()); + } - // Phi selection - if (mcParticle.pdgCode() == o2::constants::physics::Pdg::kPhi && mcParticle.pt() >= phiConfigs.minPhiPt) - mcPhiHist.fill(HIST("h3PhiMCGenRecoCheckNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); + for (const auto& track : fullMCTracks) { + // Pion selection + if (!selectionPion(track, false)) + continue; - // K0S selection - if (mcParticle.pdgCode() == PDG_t::kK0Short && mcParticle.isPhysicalPrimary() && mcParticle.pt() >= v0Configs.v0SettingMinPt) - mcK0SHist.fill(HIST("h3K0SMCGenRecoCheckNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); + if (!track.has_mcParticle()) + continue; - // Pion selection - if (std::abs(mcParticle.pdgCode()) == PDG_t::kPiPlus && mcParticle.isPhysicalPrimary() && mcParticle.pt() >= trackConfigs.cMinPionPtcut) - mcPionHist.fill(HIST("h3PiMCGenRecoCheckNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); - } - } + auto mcTrack = track.mcParticle_as(); + if (std::abs(mcTrack.pdgCode()) != PDG_t::kPiPlus) + continue; - PROCESS_SWITCH(Phik0shortanalysis, processAllPartMCReco, "Process function for all particles in MCReco", false); + if (std::abs(mcTrack.y()) > deltaYConfigs.cfgYAcceptance) + continue; - void processAllPartMCGen(MCCollisions::iterator const& mcCollision, soa::SmallGroups const& collisions, aod::McParticles const& mcParticles) - { - if (std::abs(mcCollision.posZ()) > cutZVertex) - return; - if (!pwglf::isINELgtNmc(mcParticles, 0, pdgDB)) - return; + // Primary pion selection + if (mcTrack.isPhysicalPrimary()) { + mcPionHist.fill(HIST("h3RecMCDCAxyPrimPi"), track.pt(), track.dcaXY()); + } else { + if (mcTrack.getProcess() == 4) { // Selection of secondary pions from weak decay + mcPionHist.fill(HIST("h3RecMCDCAxySecWeakDecayPi"), track.pt(), track.dcaXY()); + } else { // Selection of secondary pions from material interactions + mcPionHist.fill(HIST("h3RecMCDCAxySecMaterialPi"), track.pt(), track.dcaXY()); + } + continue; + } - float genmultiplicity = mcCollision.centFT0M(); + mcPionHist.fill(HIST("h3PiMCRecoNewProc"), genmultiplicity, mcTrack.pt(), mcTrack.y()); - uint64_t numberAssocColl = 0; - for (const auto& collision : collisions) { - if (acceptEventQA(collision, false)) { - mcEventHist.fill(HIST("hGenMCRecoMultiplicityPercent"), genmultiplicity); // Event split numerator + if (track.pt() >= trackConfigs.pTToUseTOF && !track.hasTOF()) + continue; - for (const auto& mcParticle : mcParticles) { - // The inclusive number of particles is the signal loss denominator, - // while the number of associated particles is the signal loss numerator - if (std::abs(mcParticle.y()) > deltaYConfigs.cfgYAcceptance) - continue; + mcPionHist.fill(HIST("h3PiMCReco2NewProc"), genmultiplicity, mcTrack.pt(), mcTrack.y()); + } + //// - // Phi selection - if (mcParticle.pdgCode() == o2::constants::physics::Pdg::kPhi && mcParticle.pt() >= phiConfigs.minPhiPt) - mcPhiHist.fill(HIST("h3PhiMCGenRecoNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); + numberAssocColl++; + } + } - // K0S selection - if (mcParticle.pdgCode() == PDG_t::kK0Short && mcParticle.isPhysicalPrimary() && mcParticle.pt() >= v0Configs.v0SettingMinPt) - mcK0SHist.fill(HIST("h3K0SMCGenRecoNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); + mcEventHist.fill(HIST("hGenMCMultiplicityPercent"), mcCollision.centFT0M()); - // Pion selection - if (std::abs(mcParticle.pdgCode()) == PDG_t::kPiPlus && mcParticle.isPhysicalPrimary() && mcParticle.pt() >= trackConfigs.cMinPionPtcut) - mcPionHist.fill(HIST("h3PiMCGenRecoNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); + if (numberAssocColl > 0) { + float zVtxRef = zVtxs[0]; + if (zVtxs.size() > 1) { + for (size_t i = 1; i < zVtxs.size(); ++i) { + mcEventHist.fill(HIST("hSplitVertexZ"), zVtxs[i] - zVtxRef); + } } - numberAssocColl++; + mcEventHist.fill(HIST("hGenMCAssocRecoMultiplicityPercent"), mcCollision.centFT0M()); + mcEventHist.fill(HIST("h2GenMCAssocRecoVertexZvsMult"), zVtxRef, mcCollision.centFT0M()); } - } - // The inclusive number of events is the event loss denominator, - // while the number of associated events is the event loss numerator - mcEventHist.fill(HIST("hGenMCMultiplicityPercent"), genmultiplicity); - if (numberAssocColl > 0) - mcEventHist.fill(HIST("hGenMCAssocRecoMultiplicityPercent"), genmultiplicity); - - for (const auto& mcParticle : mcParticles) { - // The inclusive number of particles is the signal loss denominator, - // while the number of associated particles is the signal loss numerator - if (std::abs(mcParticle.y()) > deltaYConfigs.cfgYAcceptance) - continue; + for (const auto& mcParticle : mcParticlesThisMcColl) { + if (std::abs(mcParticle.y()) > deltaYConfigs.cfgYAcceptance) + continue; - // Phi selection - if (mcParticle.pdgCode() == o2::constants::physics::Pdg::kPhi && mcParticle.pt() >= phiConfigs.minPhiPt) { - mcPhiHist.fill(HIST("h3PhiMCGenNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); - if (numberAssocColl > 0) - mcPhiHist.fill(HIST("h3PhiMCGenAssocRecoNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); - } + // Phi selection + if (mcParticle.pdgCode() == o2::constants::physics::Pdg::kPhi && mcParticle.pt() >= phiConfigs.minPhiPt) { + mcPhiHist.fill(HIST("h3PhiMCGenNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); + if (numberAssocColl > 0) + mcPhiHist.fill(HIST("h3PhiMCGenAssocRecoNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); + } - // K0S selection - if (mcParticle.pdgCode() == PDG_t::kK0Short && mcParticle.isPhysicalPrimary() && mcParticle.pt() >= v0Configs.v0SettingMinPt) { - mcK0SHist.fill(HIST("h3K0SMCGenNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); - if (numberAssocColl > 0) - mcK0SHist.fill(HIST("h3K0SMCGenAssocRecoNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); - } + // K0S selection + if (mcParticle.pdgCode() == PDG_t::kK0Short && mcParticle.isPhysicalPrimary() && mcParticle.pt() >= v0Configs.v0SettingMinPt) { + mcK0SHist.fill(HIST("h3K0SMCGenNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); + if (numberAssocColl > 0) + mcK0SHist.fill(HIST("h3K0SMCGenAssocRecoNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); + } - // Pion selection - if (std::abs(mcParticle.pdgCode()) == PDG_t::kPiPlus && mcParticle.isPhysicalPrimary() && mcParticle.pt() >= trackConfigs.cMinPionPtcut) { - mcPionHist.fill(HIST("h3PiMCGenNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); - if (numberAssocColl > 0) - mcPionHist.fill(HIST("h3PiMCGenAssocRecoNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); + // Pion selection + if (std::abs(mcParticle.pdgCode()) == PDG_t::kPiPlus && mcParticle.isPhysicalPrimary() && mcParticle.pt() >= trackConfigs.cMinPionPtcut) { + mcPionHist.fill(HIST("h3PiMCGenNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); + if (numberAssocColl > 0) + mcPionHist.fill(HIST("h3PiMCGenAssocRecoNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); + } } } } - PROCESS_SWITCH(Phik0shortanalysis, processAllPartMCGen, "Process function for all particles in MCGen", false); + PROCESS_SWITCH(Phik0shortanalysis, processAllPartMC, "Process function for all particles in MC", false); void processPhiK0SMixingEvent(SelCollisions const& collisions, FullTracks const& fullTracks, FullV0s const& V0s, V0DauTracks const&) { From 81b6a8f49ee1b61640f333e058b573373a80d941 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Thu, 11 Sep 2025 16:19:23 +0800 Subject: [PATCH 03/11] Finalize merge process functions for particle efficiencies --- .../Tasks/Strangeness/phik0shortanalysis.cxx | 173 +++++++++--------- 1 file changed, 86 insertions(+), 87 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx index 2bdb44c0954..213512282a3 100644 --- a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx @@ -672,26 +672,18 @@ struct Phik0shortanalysis { } if (analysisModeConfigs.isMCNewProc) { - mcPhiHist.add("h3PhiMCRecoNewProc", "Phi in MCReco", kTH3F, {binnedmultAxis, pTPhiAxis, yAxis}); - mcK0SHist.add("h3K0SMCRecoNewProc", "K0S in MCReco", kTH3F, {binnedmultAxis, pTK0SAxis, yAxis}); - mcPionHist.add("h3PiMCRecoNewProc", "Pion in MCReco", kTH3F, {binnedmultAxis, pTPiAxis, yAxis}); - mcPionHist.add("h3PiMCReco2NewProc", "Pion in MCReco", kTH3F, {binnedmultAxis, pTPiAxis, yAxis}); + mcPhiHist.add("h4PhiMCRecoNewProc", "Phi in MCReco", kTHnSparseF, {vertexZAxis, binnedmultAxis, pTPhiAxis, yAxis}); + mcK0SHist.add("h4K0SMCRecoNewProc", "K0S in MCReco", kTHnSparseF, {vertexZAxis, binnedmultAxis, pTK0SAxis, yAxis}); + mcPionHist.add("h4PiMCRecoNewProc", "Pion in MCReco", kTHnSparseF, {vertexZAxis, binnedmultAxis, pTPiAxis, yAxis}); + mcPionHist.add("h4PiMCReco2NewProc", "Pion in MCReco", kTHnSparseF, {vertexZAxis, binnedmultAxis, pTPiAxis, yAxis}); mcPhiHist.add("h3PhiMCGenNewProc", "Phi in MCGen", kTH3F, {binnedmultAxis, pTPhiAxis, yAxis}); mcK0SHist.add("h3K0SMCGenNewProc", "K0S in MCGen", kTH3F, {binnedmultAxis, pTK0SAxis, yAxis}); mcPionHist.add("h3PiMCGenNewProc", "Pion in MCGen", kTH3F, {binnedmultAxis, pTPiAxis, yAxis}); - mcPhiHist.add("h3PhiMCGenAssocRecoNewProc", "Phi in MCGen Associated MCReco", kTH3F, {binnedmultAxis, pTPhiAxis, yAxis}); - mcK0SHist.add("h3K0SMCGenAssocRecoNewProc", "K0S in MCGen Associated MCReco", kTH3F, {binnedmultAxis, pTK0SAxis, yAxis}); - mcPionHist.add("h3PiMCGenAssocRecoNewProc", "Pion in MCGen Associated MCReco", kTH3F, {binnedmultAxis, pTPiAxis, yAxis}); - - mcPhiHist.add("h3PhiMCGenRecoNewProc", "Phi in MCGen MCReco", kTH3F, {binnedmultAxis, pTPhiAxis, yAxis}); - mcK0SHist.add("h3K0SMCGenRecoNewProc", "K0S in MCGen MCReco", kTH3F, {binnedmultAxis, pTK0SAxis, yAxis}); - mcPionHist.add("h3PiMCGenRecoNewProc", "Pion in MCGen MCReco", kTH3F, {binnedmultAxis, pTPiAxis, yAxis}); - - mcPhiHist.add("h3PhiMCGenRecoCheckNewProc", "Phi in MCGen MCReco Check", kTH3F, {binnedmultAxis, pTPhiAxis, yAxis}); - mcK0SHist.add("h3K0SMCGenRecoCheckNewProc", "K0S in MCGen MCReco Check", kTH3F, {binnedmultAxis, pTK0SAxis, yAxis}); - mcPionHist.add("h3PiMCGenRecoCheckNewProc", "Pion in MCGen MCReco Check", kTH3F, {binnedmultAxis, pTPiAxis, yAxis}); + mcPhiHist.add("h4PhiMCGenAssocRecoNewProc", "Phi in MCGen Associated MCReco", kTHnSparseF, {vertexZAxis, binnedmultAxis, pTPhiAxis, yAxis}); + mcK0SHist.add("h4K0SMCGenAssocRecoNewProc", "K0S in MCGen Associated MCReco", kTHnSparseF, {vertexZAxis, binnedmultAxis, pTK0SAxis, yAxis}); + mcPionHist.add("h4PiMCGenAssocRecoNewProc", "Pion in MCGen Associated MCReco", kTHnSparseF, {vertexZAxis, binnedmultAxis, pTPiAxis, yAxis}); } // Initialize CCDB only if purity or efficiencies are requested in the task @@ -3066,20 +3058,19 @@ struct Phik0shortanalysis { auto collision = collisions.rawIteratorAt(collisionIndex); if (acceptEventQA(collision, false)) { - //// - auto filteredMCTracksThisColl = filteredMCTracks.sliceBy(preslices.perColl, collision.globalIndex()); + auto fullMCTracksThisColl = fullMCTracks.sliceBy(preslices.perColl, collision.globalIndex()); + auto v0sThisColl = V0s.sliceBy(preslices.perColl, collision.globalIndex()); - posFiltMCTracks.bindTable(filteredMCTracksThisColl); - negFiltMCTracks.bindTable(filteredMCTracksThisColl); - //// + posMCTracks.bindTable(fullMCTracksThisColl); + negMCTracks.bindTable(fullMCTracksThisColl); switch (filterOnRecoPhi) { case 0: - if (!eventHasRecoPhi(posFiltMCTracks, negFiltMCTracks)) + if (!eventHasRecoPhi(posMCTracks, negMCTracks)) continue; break; case 1: - if (!eventHasRecoPhiWPDG(posFiltMCTracks, negFiltMCTracks, mcParticles)) + if (!eventHasRecoPhiWPDG(posMCTracks, negMCTracks, mcParticles)) continue; break; default: @@ -3091,69 +3082,70 @@ struct Phik0shortanalysis { zVtxs.push_back(collision.posZ()); - //// - // Defining positive and negative tracks for phi reconstruction - auto posThisColl = posMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - auto negThisColl = negMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + if ((filterOnGenPhi != 0 && filterOnGenPhi != 1) && (filterOnRecoPhi != 0 && filterOnRecoPhi != 1)) { + for (const auto& track1 : posMCTracks) { // loop over all selected tracks + if (!selectionTrackResonance(track1, false) || !selectionPIDKaonpTdependent(track1)) + continue; // topological and PID selection - for (const auto& track1 : posThisColl) { // loop over all selected tracks - if (!selectionTrackResonance(track1, false) || !selectionPIDKaonpTdependent(track1)) - continue; // topological and PID selection + auto track1ID = track1.globalIndex(); - auto track1ID = track1.globalIndex(); + if (!track1.has_mcParticle()) + continue; + auto mcTrack1 = mcParticles.rawIteratorAt(track1.mcParticleId()); + if (mcTrack1.pdgCode() != PDG_t::kKPlus || !mcTrack1.isPhysicalPrimary()) + continue; - if (!track1.has_mcParticle()) - continue; - auto mcTrack1 = track1.mcParticle_as(); - if (mcTrack1.pdgCode() != PDG_t::kKPlus || !mcTrack1.isPhysicalPrimary()) - continue; + for (const auto& track2 : negMCTracks) { + if (!selectionTrackResonance(track2, false) || !selectionPIDKaonpTdependent(track2)) + continue; // topological and PID selection - for (const auto& track2 : negThisColl) { - if (!selectionTrackResonance(track2, false) || !selectionPIDKaonpTdependent(track2)) - continue; // topological and PID selection + auto track2ID = track2.globalIndex(); + if (track2ID == track1ID) + continue; // condition to avoid double counting of pair - auto track2ID = track2.globalIndex(); - if (track2ID == track1ID) - continue; // condition to avoid double counting of pair + if (!track2.has_mcParticle()) + continue; + auto mcTrack2 = mcParticles.rawIteratorAt(track2.mcParticleId()); + if (mcTrack2.pdgCode() != PDG_t::kKMinus || !mcTrack2.isPhysicalPrimary()) + continue; - if (!track2.has_mcParticle()) - continue; - auto mcTrack2 = track2.mcParticle_as(); - if (mcTrack2.pdgCode() != PDG_t::kKMinus || !mcTrack2.isPhysicalPrimary()) - continue; + const auto mcTrack1MotherIndexes = mcTrack1.mothersIds(); + const auto mcTrack2MotherIndexes = mcTrack2.mothersIds(); + + float pTMother = -1.0f; + float yMother = -1.0f; + bool isMCMotherPhi = false; + + for (const auto& mcTrack1MotherIndex : mcTrack1MotherIndexes) { + for (const auto& mcTrack2MotherIndex : mcTrack2MotherIndexes) { + if (mcTrack1MotherIndex != mcTrack2MotherIndex) + continue; + + const auto mother = mcParticles.rawIteratorAt(mcTrack1MotherIndex); + if (mother.pdgCode() != o2::constants::physics::Pdg::kPhi) + continue; - float pTMother = -1.0f; - float yMother = -1.0f; - bool isMCMotherPhi = false; - for (const auto& motherOfMcTrack1 : mcTrack1.mothers_as()) { - for (const auto& motherOfMcTrack2 : mcTrack2.mothers_as()) { - if (motherOfMcTrack1.pdgCode() != motherOfMcTrack2.pdgCode()) - continue; - if (motherOfMcTrack1.globalIndex() != motherOfMcTrack2.globalIndex()) - continue; - if (motherOfMcTrack1.pdgCode() != o2::constants::physics::Pdg::kPhi) - continue; - - pTMother = motherOfMcTrack1.pt(); - yMother = motherOfMcTrack1.y(); - isMCMotherPhi = true; + pTMother = mother.pt(); + yMother = mother.y(); + isMCMotherPhi = true; + } } - } - if (!isMCMotherPhi) - continue; - if (pTMother < phiConfigs.minPhiPt || std::abs(yMother) > deltaYConfigs.cfgYAcceptance) - continue; + if (!isMCMotherPhi) + continue; + if (pTMother < phiConfigs.minPhiPt || std::abs(yMother) > deltaYConfigs.cfgYAcceptance) + continue; - mcPhiHist.fill(HIST("h3PhiMCRecoNewProc"), genmultiplicity, pTMother, yMother); + mcPhiHist.fill(HIST("h4PhiMCRecoNewProc"), collision.posZ(), mcCollision.centFT0M(), pTMother, yMother); + } } } - for (const auto& v0 : V0s) { + for (const auto& v0 : v0sThisColl) { if (!v0.has_mcParticle()) continue; - auto v0mcparticle = v0.mcParticle(); + auto v0mcparticle = mcParticles.rawIteratorAt(v0.mcParticleId()); if (v0mcparticle.pdgCode() != PDG_t::kK0Short || !v0mcparticle.isPhysicalPrimary()) continue; @@ -3167,10 +3159,10 @@ struct Phik0shortanalysis { if (std::abs(v0mcparticle.y()) > deltaYConfigs.cfgYAcceptance) continue; - mcK0SHist.fill(HIST("h3K0SMCRecoNewProc"), genmultiplicity, v0mcparticle.pt(), v0mcparticle.y()); + mcK0SHist.fill(HIST("h4K0SMCRecoNewProc"), collision.posZ(), mcCollision.centFT0M(), v0mcparticle.pt(), v0mcparticle.y()); } - for (const auto& track : fullMCTracks) { + for (const auto& track : fullMCTracksThisColl) { // Pion selection if (!selectionPion(track, false)) continue; @@ -3178,7 +3170,7 @@ struct Phik0shortanalysis { if (!track.has_mcParticle()) continue; - auto mcTrack = track.mcParticle_as(); + auto mcTrack = mcParticles.rawIteratorAt(track.mcParticleId()); if (std::abs(mcTrack.pdgCode()) != PDG_t::kPiPlus) continue; @@ -3197,14 +3189,13 @@ struct Phik0shortanalysis { continue; } - mcPionHist.fill(HIST("h3PiMCRecoNewProc"), genmultiplicity, mcTrack.pt(), mcTrack.y()); + mcPionHist.fill(HIST("h4PiMCRecoNewProc"), collision.posZ(), mcCollision.centFT0M(), mcTrack.pt(), mcTrack.y()); if (track.pt() >= trackConfigs.pTToUseTOF && !track.hasTOF()) continue; - mcPionHist.fill(HIST("h3PiMCReco2NewProc"), genmultiplicity, mcTrack.pt(), mcTrack.y()); + mcPionHist.fill(HIST("h4PiMCReco2NewProc"), collision.posZ(), mcCollision.centFT0M(), mcTrack.pt(), mcTrack.y()); } - //// numberAssocColl++; } @@ -3228,31 +3219,39 @@ struct Phik0shortanalysis { if (std::abs(mcParticle.y()) > deltaYConfigs.cfgYAcceptance) continue; - // Phi selection - if (mcParticle.pdgCode() == o2::constants::physics::Pdg::kPhi && mcParticle.pt() >= phiConfigs.minPhiPt) { - mcPhiHist.fill(HIST("h3PhiMCGenNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); - if (numberAssocColl > 0) - mcPhiHist.fill(HIST("h3PhiMCGenAssocRecoNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); + if (filterOnGenPhi != 0 && filterOnGenPhi != 1) { + // Phi selection + if (mcParticle.pdgCode() == o2::constants::physics::Pdg::kPhi && mcParticle.pt() >= phiConfigs.minPhiPt) { + mcPhiHist.fill(HIST("h3PhiMCGenNewProc"), mcCollision.centFT0M(), mcParticle.pt(), mcParticle.y()); + if (numberAssocColl > 0) { + float zVtxRef = zVtxs[0]; + mcPhiHist.fill(HIST("h4PhiMCGenAssocRecoNewProc"), zVtxRef, mcCollision.centFT0M(), mcParticle.pt(), mcParticle.y()); + } + } } // K0S selection if (mcParticle.pdgCode() == PDG_t::kK0Short && mcParticle.isPhysicalPrimary() && mcParticle.pt() >= v0Configs.v0SettingMinPt) { - mcK0SHist.fill(HIST("h3K0SMCGenNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); - if (numberAssocColl > 0) - mcK0SHist.fill(HIST("h3K0SMCGenAssocRecoNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); + mcK0SHist.fill(HIST("h3K0SMCGenNewProc"), mcCollision.centFT0M(), mcParticle.pt(), mcParticle.y()); + if (numberAssocColl > 0) { + float zVtxRef = zVtxs[0]; + mcK0SHist.fill(HIST("h4K0SMCGenAssocRecoNewProc"), zVtxRef, mcCollision.centFT0M(), mcParticle.pt(), mcParticle.y()); + } } // Pion selection if (std::abs(mcParticle.pdgCode()) == PDG_t::kPiPlus && mcParticle.isPhysicalPrimary() && mcParticle.pt() >= trackConfigs.cMinPionPtcut) { - mcPionHist.fill(HIST("h3PiMCGenNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); - if (numberAssocColl > 0) - mcPionHist.fill(HIST("h3PiMCGenAssocRecoNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); + mcPionHist.fill(HIST("h3PiMCGenNewProc"), mcCollision.centFT0M(), mcParticle.pt(), mcParticle.y()); + if (numberAssocColl > 0) { + float zVtxRef = zVtxs[0]; + mcPionHist.fill(HIST("h4PiMCGenAssocRecoNewProc"), zVtxRef, mcCollision.centFT0M(), mcParticle.pt(), mcParticle.y()); + } } } } } - PROCESS_SWITCH(Phik0shortanalysis, processAllPartMC, "Process function for all particles in MC", false); + PROCESS_SWITCH(Phik0shortanalysis, processAllPartMC, "Process function for all particles (not for phi if triggered on it) in MC", false); void processPhiK0SMixingEvent(SelCollisions const& collisions, FullTracks const& fullTracks, FullV0s const& V0s, V0DauTracks const&) { From c8c9734963908735a0007f8538236a745df4ff33 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Fri, 12 Sep 2025 17:59:15 +0800 Subject: [PATCH 04/11] First commit for deltay - deltaphi correlations --- .../Tasks/Strangeness/phik0shortanalysis.cxx | 286 +++++++++++++----- 1 file changed, 210 insertions(+), 76 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx index 213512282a3..36a1fe840c9 100644 --- a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx @@ -936,6 +936,20 @@ struct Phik0shortanalysis { return true; } + template + bool selectionPhi(const T& posTrack, const T& negTrack) + { + // To be possibly completed + return !posTrack.empty() && !negTrack.empty(); + } + + template + bool selectionPhiWPDG(const T1& posTrack, const T1& negTrack, const T2& mcParticles) + { + // To be possibly completed + return !posTrack.empty() && !negTrack.empty(); + } + template bool eventHasRecoPhi(const T1& posTracks, const T2& negTracks) { @@ -1108,7 +1122,7 @@ struct Phik0shortanalysis { } template - bool isGenParticleCharged(const T& mcParticle) + bool selectionChargedGenParticle(const T& mcParticle) { if (!mcParticle.isPhysicalPrimary() || std::abs(mcParticle.eta()) > trackConfigs.etaMax) return false; @@ -2709,7 +2723,7 @@ struct Phik0shortanalysis { if (fillMcPartsForAllReco) { for (const auto& mcParticle : mcParticlesThisMcColl) { - if (!isGenParticleCharged(mcParticle)) + if (!selectionChargedGenParticle(mcParticle)) continue; mcEventHist.fill(HIST("h6GenMCAllAssocRecoEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kNoGenpTVar); @@ -2745,7 +2759,7 @@ struct Phik0shortanalysis { } for (const auto& mcParticle : mcParticlesThisMcColl) { - if (!isGenParticleCharged(mcParticle)) + if (!selectionChargedGenParticle(mcParticle)) continue; int pid = fromPDGToEnum(mcParticle.pdgCode()); @@ -3019,6 +3033,105 @@ struct Phik0shortanalysis { PROCESS_SWITCH(Phik0shortanalysis, processPhiK0SPionMCClosure2D, "Process function for Phi-K0S and Phi-Pion Correlations in MCClosure2D", false); + void processPhiK0SMixingEvent2D(SelCollisions const& collisions, FullTracks const& fullTracks, FullV0s const& V0s, V0DauTracks const&) + { + auto tracksV0sTuple = std::make_tuple(fullTracks, V0s); + Pair pairPhiK0S{binningOnVertexAndCent, cfgNoMixedEvents, -1, collisions, tracksV0sTuple, &cache}; + + for (auto const& [collision1, tracks1, collision2, v0s2] : pairPhiK0S) { + float multiplicity = collision1.centFT0M(); + + Partition posMixTracks = aod::track::signed1Pt > trackConfigs.cfgCutCharge; + posMixTracks.bindTable(tracks1); + Partition negMixTracks = aod::track::signed1Pt < trackConfigs.cfgCutCharge; + negMixTracks.bindTable(tracks1); + + for (const auto& [posTrack1, negTrack1, v0] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(posMixTracks, negMixTracks, v0s2))) { + if (!selectionTrackResonance(posTrack1, true) || !selectionPIDKaonpTdependent(posTrack1)) + continue; + if (!selectionTrackResonance(negTrack1, true) || !selectionPIDKaonpTdependent(negTrack1)) + continue; + if (posTrack1.globalIndex() == negTrack1.globalIndex()) + continue; + + ROOT::Math::PxPyPzMVector recPhi = recMother(posTrack1, negTrack1, massKa, massKa); + if (recPhi.Pt() < phiConfigs.minPhiPt) + continue; + if (std::abs(recPhi.Rapidity()) > deltaYConfigs.cfgYAcceptance) + continue; + + const auto& posDaughterTrack = v0.posTrack_as(); + const auto& negDaughterTrack = v0.negTrack_as(); + + if (!selectionV0(v0, posDaughterTrack, negDaughterTrack)) + continue; + if (v0Configs.cfgFurtherV0Selection && !furtherSelectionV0(v0, collision2)) + continue; + if (std::abs(v0.yK0Short()) > deltaYConfigs.cfgYAcceptance) + continue; + + float efficiencyPhiK0S = 1.0f; + if (applyEfficiency) { + efficiencyPhiK0S = effMapPhi->Interpolate(multiplicity, recPhi.Pt(), recPhi.Rapidity()) * effMapK0S->Interpolate(multiplicity, v0.pt(), v0.yK0Short()); + if (efficiencyPhiK0S == 0) + efficiencyPhiK0S = 1.0f; + } + float weightPhiK0S = applyEfficiency ? 1.0f / efficiencyPhiK0S : 1.0f; + mePhiK0SHist.fill(HIST("h5PhiK0SMENewProc"), v0.yK0Short() - recPhi.Rapidity(), multiplicity, v0.pt(), v0.mK0Short(), recPhi.M(), weightPhiK0S); + } + } + } + + PROCESS_SWITCH(Phik0shortanalysis, processPhiK0SMixingEvent2D, "Process Mixed Event for Phi-K0S Analysis 2D", false); + + void processPhiPionMixingEvent2D(SelCollisions const& collisions, FullTracks const& fullTracks) + { + auto tracksTuple = std::make_tuple(fullTracks); + SameKindPair pairPhiPion{binningOnVertexAndCent, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; + + for (auto const& [collision1, tracks1, collision2, tracks2] : pairPhiPion) { + float multiplicity = collision1.centFT0M(); + + Partition posMixTracks = aod::track::signed1Pt > trackConfigs.cfgCutCharge; + posMixTracks.bindTable(tracks1); + Partition negMixTracks = aod::track::signed1Pt < trackConfigs.cfgCutCharge; + negMixTracks.bindTable(tracks1); + + for (const auto& [posTrack1, negTrack1, track] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(posMixTracks, negMixTracks, tracks2))) { + if (!selectionTrackResonance(posTrack1, true) || !selectionPIDKaonpTdependent(posTrack1)) + continue; + if (!selectionTrackResonance(negTrack1, true) || !selectionPIDKaonpTdependent(negTrack1)) + continue; + if (posTrack1.globalIndex() == negTrack1.globalIndex()) + continue; + + ROOT::Math::PxPyPzMVector recPhi = recMother(posTrack1, negTrack1, massKa, massKa); + if (recPhi.Pt() < phiConfigs.minPhiPt) + continue; + if (std::abs(recPhi.Rapidity()) > deltaYConfigs.cfgYAcceptance) + continue; + + if (!selectionPion(track, false)) + continue; + if (std::abs(track.rapidity(massPi)) > deltaYConfigs.cfgYAcceptance) + continue; + + float efficiencyPhiPion = 1.0f; + if (applyEfficiency) { + efficiencyPhiPion = track.pt() < trackConfigs.pTToUseTOF ? effMapPhi->Interpolate(multiplicity, recPhi.Pt(), recPhi.Rapidity()) * effMapPionTPC->Interpolate(multiplicity, track.pt(), track.rapidity(massPi)) : effMapPhi->Interpolate(multiplicity, recPhi.Pt(), recPhi.Rapidity()) * effMapPionTPCTOF->Interpolate(multiplicity, track.pt(), track.rapidity(massPi)); + if (efficiencyPhiPion == 0) + efficiencyPhiPion = 1.0f; + } + float weightPhiPion = applyEfficiency ? 1.0f / efficiencyPhiPion : 1.0f; + mePhiPionHist.fill(HIST("h5PhiPiTPCMENewProc"), track.rapidity(massPi) - recPhi.Rapidity(), multiplicity, track.pt(), track.tpcNSigmaPi(), recPhi.M(), weightPhiPion); + if (track.hasTOF()) + mePhiPionHist.fill(HIST("h5PhiPiTOFMENewProc"), track.rapidity(massPi) - recPhi.Rapidity(), multiplicity, track.pt(), track.tofNSigmaPi(), recPhi.M(), weightPhiPion); + } + } + } + + PROCESS_SWITCH(Phik0shortanalysis, processPhiPionMixingEvent2D, "Process Mixed Event for Phi-Pion Analysis 2D", false); + void processAllPartMC(MCCollisions const& mcCollisions, SimCollisions const& collisions, FullMCTracks const& fullMCTracks, FullMCV0s const& V0s, V0DauMCTracks const&, aod::McParticles const& mcParticles) { @@ -3253,104 +3366,125 @@ struct Phik0shortanalysis { PROCESS_SWITCH(Phik0shortanalysis, processAllPartMC, "Process function for all particles (not for phi if triggered on it) in MC", false); - void processPhiK0SMixingEvent(SelCollisions const& collisions, FullTracks const& fullTracks, FullV0s const& V0s, V0DauTracks const&) + // New 2D analysis procedure + void processPhiK0SPionDeltayDeltaphiData2D(SelCollisions::iterator const& collision, FullTracks const& fullTracks, FullV0s const& V0s, V0DauTracks const&) { - auto tracksV0sTuple = std::make_tuple(fullTracks, V0s); - Pair pairPhiK0S{binningOnVertexAndCent, cfgNoMixedEvents, -1, collisions, tracksV0sTuple, &cache}; + // Check if the event selection is passed + if (!acceptEventQA(collision, true)) + return; - for (auto const& [collision1, tracks1, collision2, v0s2] : pairPhiK0S) { - float multiplicity = collision1.centFT0M(); + float multiplicity = collision.centFT0M(); + dataEventHist.fill(HIST("hMultiplicityPercent"), multiplicity); - Partition posMixTracks = aod::track::signed1Pt > trackConfigs.cfgCutCharge; - posMixTracks.bindTable(tracks1); - Partition negMixTracks = aod::track::signed1Pt < trackConfigs.cfgCutCharge; - negMixTracks.bindTable(tracks1); + // Defining positive and negative tracks for phi reconstruction + auto posThisColl = posTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto negThisColl = negTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - for (const auto& [posTrack1, negTrack1, v0] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(posMixTracks, negMixTracks, v0s2))) { - if (!selectionTrackResonance(posTrack1, true) || !selectionPIDKaonpTdependent(posTrack1)) - continue; - if (!selectionTrackResonance(negTrack1, true) || !selectionPIDKaonpTdependent(negTrack1)) - continue; - if (posTrack1.globalIndex() == negTrack1.globalIndex()) - continue; + if (!eventHasRecoPhi(posThisColl, negThisColl)) + return; - ROOT::Math::PxPyPzMVector recPhi = recMother(posTrack1, negTrack1, massKa, massKa); - if (recPhi.Pt() < phiConfigs.minPhiPt) - continue; - if (std::abs(recPhi.Rapidity()) > deltaYConfigs.cfgYAcceptance) - continue; + dataEventHist.fill(HIST("hEventSelection"), 4); // at least a Phi candidate in the event - const auto& posDaughterTrack = v0.posTrack_as(); - const auto& negDaughterTrack = v0.negTrack_as(); + bool isCountedPhi = false; + bool isFilledhV0 = false; - if (!selectionV0(v0, posDaughterTrack, negDaughterTrack)) - continue; - if (v0Configs.cfgFurtherV0Selection && !furtherSelectionV0(v0, collision2)) + // Loop over all positive tracks + for (const auto& track1 : posThisColl) { + if (!selectionTrackResonance(track1, true) || !selectionPIDKaonpTdependent(track1)) + continue; // topological and PID selection + + dataPhiHist.fill(HIST("hEta"), track1.eta()); + dataPhiHist.fill(HIST("hNsigmaKaonTPC"), track1.tpcInnerParam(), track1.tpcNSigmaKa()); + dataPhiHist.fill(HIST("hNsigmaKaonTOF"), track1.tpcInnerParam(), track1.tofNSigmaKa()); + + auto track1ID = track1.globalIndex(); + + // Loop over all negative tracks + for (const auto& track2 : negThisColl) { + if (!selectionTrackResonance(track2, true) || !selectionPIDKaonpTdependent(track2)) + continue; // topological and PID selection + + auto track2ID = track2.globalIndex(); + if (track2ID == track1ID) + continue; // condition to avoid double counting of pair + + ROOT::Math::PxPyPzMVector recPhi = recMother(track1, track2, massKa, massKa); + if (recPhi.Pt() < phiConfigs.minPhiPt || recPhi.Pt() > phiConfigs.maxPhiPt) continue; - if (std::abs(v0.yK0Short()) > deltaYConfigs.cfgYAcceptance) + if (std::abs(recPhi.Rapidity()) > deltaYConfigs.cfgYAcceptance) continue; - float efficiencyPhiK0S = 1.0f; + if (!isCountedPhi) + isCountedPhi = true; + + float efficiencyPhi = 1.0f; if (applyEfficiency) { - efficiencyPhiK0S = effMapPhi->Interpolate(multiplicity, recPhi.Pt(), recPhi.Rapidity()) * effMapK0S->Interpolate(multiplicity, v0.pt(), v0.yK0Short()); - if (efficiencyPhiK0S == 0) - efficiencyPhiK0S = 1.0f; + efficiencyPhi = effMapPhi->Interpolate(multiplicity, recPhi.Pt(), recPhi.Rapidity()); + if (efficiencyPhi == 0) + efficiencyPhi = 1.0f; } - float weightPhiK0S = applyEfficiency ? 1.0f / efficiencyPhiK0S : 1.0f; - mePhiK0SHist.fill(HIST("h5PhiK0SMENewProc"), v0.yK0Short() - recPhi.Rapidity(), multiplicity, v0.pt(), v0.mK0Short(), recPhi.M(), weightPhiK0S); - } - } - } + float weightPhi = applyEfficiency ? 1.0f / efficiencyPhi : 1.0f; + dataPhiHist.fill(HIST("h3PhiDataNewProc"), multiplicity, recPhi.Pt(), recPhi.M(), weightPhi); - PROCESS_SWITCH(Phik0shortanalysis, processPhiK0SMixingEvent, "Process Mixed Event for Phi-K0S Analysis", false); + // V0 already reconstructed by the builder + for (const auto& v0 : V0s) { + const auto& posDaughterTrack = v0.posTrack_as(); + const auto& negDaughterTrack = v0.negTrack_as(); - void processPhiPionMixingEvent(SelCollisions const& collisions, FullTracks const& fullTracks) - { - auto tracksTuple = std::make_tuple(fullTracks); - SameKindPair pairPhiPion{binningOnVertexAndCent, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; + // Cut on V0 dynamic columns + if (!selectionV0(v0, posDaughterTrack, negDaughterTrack)) + continue; + if (v0Configs.cfgFurtherV0Selection && !furtherSelectionV0(v0, collision)) + continue; - for (auto const& [collision1, tracks1, collision2, tracks2] : pairPhiPion) { - float multiplicity = collision1.centFT0M(); + if (!isFilledhV0) { + dataK0SHist.fill(HIST("hDCAV0Daughters"), v0.dcaV0daughters()); + dataK0SHist.fill(HIST("hV0CosPA"), v0.v0cosPA()); - Partition posMixTracks = aod::track::signed1Pt > trackConfigs.cfgCutCharge; - posMixTracks.bindTable(tracks1); - Partition negMixTracks = aod::track::signed1Pt < trackConfigs.cfgCutCharge; - negMixTracks.bindTable(tracks1); + // Filling the PID of the V0 daughters in the region of the K0 peak + if (v0Configs.lowMK0S < v0.mK0Short() && v0.mK0Short() < v0Configs.upMK0S) { + dataK0SHist.fill(HIST("hNSigmaPosPionFromK0S"), posDaughterTrack.tpcInnerParam(), posDaughterTrack.tpcNSigmaPi()); + dataK0SHist.fill(HIST("hNSigmaNegPionFromK0S"), negDaughterTrack.tpcInnerParam(), negDaughterTrack.tpcNSigmaPi()); + } + } - for (const auto& [posTrack1, negTrack1, track] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(posMixTracks, negMixTracks, tracks2))) { - if (!selectionTrackResonance(posTrack1, true) || !selectionPIDKaonpTdependent(posTrack1)) - continue; - if (!selectionTrackResonance(negTrack1, true) || !selectionPIDKaonpTdependent(negTrack1)) - continue; - if (posTrack1.globalIndex() == negTrack1.globalIndex()) - continue; + if (std::abs(v0.yK0Short()) > deltaYConfigs.cfgYAcceptance) + continue; - ROOT::Math::PxPyPzMVector recPhi = recMother(posTrack1, negTrack1, massKa, massKa); - if (recPhi.Pt() < phiConfigs.minPhiPt) - continue; - if (std::abs(recPhi.Rapidity()) > deltaYConfigs.cfgYAcceptance) - continue; + float efficiencyPhiK0S = 1.0f; + if (applyEfficiency) { + efficiencyPhiK0S = effMapPhi->Interpolate(multiplicity, recPhi.Pt(), recPhi.Rapidity()) * effMapK0S->Interpolate(multiplicity, v0.pt(), v0.yK0Short()); + if (efficiencyPhiK0S == 0) + efficiencyPhiK0S = 1.0f; + } + float weightPhiK0S = applyEfficiency ? 1.0f / efficiencyPhiK0S : 1.0f; + dataPhiK0SHist.fill(HIST("h5PhiK0SData2PartCorr"), multiplicity, recPhi.Pt(), v0.pt(), recPhi.Rapidity() - v0.yK0Short(), recPhi.Phi() - v0.phi(), weightPhiK0S); + } - if (!selectionPion(track, false)) - continue; - if (std::abs(track.rapidity(massPi)) > deltaYConfigs.cfgYAcceptance) - continue; + isFilledhV0 = true; - float efficiencyPhiPion = 1.0f; - if (applyEfficiency) { - efficiencyPhiPion = track.pt() < trackConfigs.pTToUseTOF ? effMapPhi->Interpolate(multiplicity, recPhi.Pt(), recPhi.Rapidity()) * effMapPionTPC->Interpolate(multiplicity, track.pt(), track.rapidity(massPi)) : effMapPhi->Interpolate(multiplicity, recPhi.Pt(), recPhi.Rapidity()) * effMapPionTPCTOF->Interpolate(multiplicity, track.pt(), track.rapidity(massPi)); - if (efficiencyPhiPion == 0) - efficiencyPhiPion = 1.0f; + // Loop over all primary pion candidates + for (const auto& track : fullTracks) { + if (!selectionPion(track, false)) + continue; + + if (std::abs(track.rapidity(massPi)) > deltaYConfigs.cfgYAcceptance) + continue; + + float efficiencyPhiPion = 1.0f; + if (applyEfficiency) { + efficiencyPhiPion = track.pt() < trackConfigs.pTToUseTOF ? effMapPhi->Interpolate(multiplicity, recPhi.Pt(), recPhi.Rapidity()) * effMapPionTPC->Interpolate(multiplicity, track.pt(), track.rapidity(massPi)) : effMapPhi->Interpolate(multiplicity, recPhi.Pt(), recPhi.Rapidity()) * effMapPionTPCTOF->Interpolate(multiplicity, track.pt(), track.rapidity(massPi)); + if (efficiencyPhiPion == 0) + efficiencyPhiPion = 1.0f; + } + float weightPhiPion = applyEfficiency ? 1.0f / efficiencyPhiPion : 1.0f; + dataPhiPionHist.fill(HIST("h5PhiPiData2PartCorr"), multiplicity, recPhi.Pt(), track.pt(), recPhi.Rapidity() - track.rapidity(massPi), recPhi.Phi() - track.phi(), weightPhiPion); } - float weightPhiPion = applyEfficiency ? 1.0f / efficiencyPhiPion : 1.0f; - mePhiPionHist.fill(HIST("h5PhiPiTPCMENewProc"), track.rapidity(massPi) - recPhi.Rapidity(), multiplicity, track.pt(), track.tpcNSigmaPi(), recPhi.M(), weightPhiPion); - if (track.hasTOF()) - mePhiPionHist.fill(HIST("h5PhiPiTOFMENewProc"), track.rapidity(massPi) - recPhi.Rapidity(), multiplicity, track.pt(), track.tofNSigmaPi(), recPhi.M(), weightPhiPion); } } } - PROCESS_SWITCH(Phik0shortanalysis, processPhiPionMixingEvent, "Process Mixed Event for Phi-Pion Analysis", false); + PROCESS_SWITCH(Phik0shortanalysis, processPhiK0SPionDeltayDeltaphiData2D, "Process function for Phi-K0S and Phi-Pion Deltay and Deltaphi 2D Correlations in Data", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From 84d16cb389a527757fe883a9532cf52278397d90 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Fri, 12 Sep 2025 18:10:02 +0800 Subject: [PATCH 05/11] Fist commit for resonanceTreeCreator --- .../Resonances/resonanceTreeCreator.cxx | 334 ++++++++++++++++++ 1 file changed, 334 insertions(+) create mode 100644 PWGLF/TableProducer/Resonances/resonanceTreeCreator.cxx diff --git a/PWGLF/TableProducer/Resonances/resonanceTreeCreator.cxx b/PWGLF/TableProducer/Resonances/resonanceTreeCreator.cxx new file mode 100644 index 00000000000..2c4f8ccfa33 --- /dev/null +++ b/PWGLF/TableProducer/Resonances/resonanceTreeCreator.cxx @@ -0,0 +1,334 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +/// +/// \file resonanceTreeCreator.cxx +/// \brief Produces a TTree with machine learning variables for resonances in the LF group +/// \author Stefano Cannito (stefano.cannito@cern.ch) + +#include "Common/DataModel/EventSelection.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +// #include "PWGLF/DataModel/LFResonanceMLTables.h" +#include "PWGLF/DataModel/mcCentrality.h" +#include "PWGLF/Utils/inelGt.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "ReconstructionDataFormats/Track.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +namespace o2::aod +{ +namespace resomlcandidates +{ +// Multiplicity class +DECLARE_SOA_COLUMN(MultClass, multClass, float); //! Event multiplicity class +// Daughter 1 +DECLARE_SOA_COLUMN(PtDaughter1, ptdaughter1, float); //! Transverse momentum of daughter1 (GeV/c) +DECLARE_SOA_COLUMN(PDaughter1, pdaughter1, float); //! Momentum of daughter1 (GeV/c) +DECLARE_SOA_COLUMN(PhiDaughter1, phiDaughter1, float); //! Azimuthal angle of daughter1 (rad) +DECLARE_SOA_COLUMN(EtaDaughter1, etaDaughter1, float); //! Pseudorapidity of daughter1 +DECLARE_SOA_COLUMN(YDaughter1, yDaughter1, float); //! Rapidity of daughter1 +DECLARE_SOA_COLUMN(DCAxyDaughter1, dcaDaughter1, float); //! DCA of daughter1 to primary vertex (cm) +DECLARE_SOA_COLUMN(DCAzDaughter1, dcaZDaughter1, float); //! DCA of daughter1 to primary vertex in z (cm) +DECLARE_SOA_COLUMN(NSigTpcPi1, nSigTpcPi1, float); //! TPC Nsigma separation for daughter1 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcKa1, nSigTpcKa1, float); //! TPC Nsigma separation for daughter1 with kaon mass hypothesis +DECLARE_SOA_COLUMN(NSigTofPi1, nSigTofPi1, float); //! TOF Nsigma separation for daughter1 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTofKa1, nSigTofKa1, float); //! TOF Nsigma separation for daughter1 with kaon mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcTofPi1, nSigTpcTofPi1, float); //! TPC and TOF combined Nsigma separation for daughter1 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcTofKa1, nSigTpcTofKa1, float); //! TPC and TOF combined Nsigma separation for daughter1 with kaon mass hypothesis +// Daughter 2 +DECLARE_SOA_COLUMN(PtDaughter2, ptdaughter2, float); //! Transverse momentum of daughter2 (GeV/c) +DECLARE_SOA_COLUMN(PDaughter2, pdaughter2, float); //! Momentum of daughter2 (in GeV/c) +DECLARE_SOA_COLUMN(PhiDaughter2, phiDaughter2, float); //! Azimuthal angle of daughter2 (rad) +DECLARE_SOA_COLUMN(EtaDaughter2, etaDaughter2, float); //! Pseudorapidity of daughter2 +DECLARE_SOA_COLUMN(YDaughter2, yDaughter2, float); //! Rapidity of daughter2 +DECLARE_SOA_COLUMN(DCAxyDaughter2, dcaDaughter2, float); //! DCA of daughter2 to primary vertex (cm) +DECLARE_SOA_COLUMN(DCAzDaughter2, dcaZDaughter2, float); //! DCA of daughter2 to primary vertex in z (cm) +DECLARE_SOA_COLUMN(NSigTpcPi2, nSigTpcPi2, float); //! TPC Nsigma separation for daughter2 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcKa2, nSigTpcKa2, float); //! TPC Nsigma separation for daughter2 with kaon mass hypothesis +DECLARE_SOA_COLUMN(NSigTofPi2, nSigTofPi2, float); //! TOF Nsigma separation for daughter2 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTofKa2, nSigTofKa2, float); //! TOF Nsigma separation for daughter2 with kaon mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcTofPi2, nSigTpcTofPi2, float); //! TPC and TOF combined Nsigma separation for daughter2 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcTofKa2, nSigTpcTofKa2, float); //! TPC and TOF combined Nsigma separation for daughter2 with kaon mass hypothesis +// Candidate +DECLARE_SOA_COLUMN(M, m, float); //! Invariant mass of candidate (GeV/c2) +DECLARE_SOA_COLUMN(Pt, pt, float); //! Transverse momentum of candidate (GeV/c) +DECLARE_SOA_COLUMN(P, p, float); //! Momentum of candidate (GeV/c) +DECLARE_SOA_COLUMN(Phi, phi, float); //! Azimuth angle of candidate +DECLARE_SOA_COLUMN(Eta, eta, float); //! Pseudorapidity of candidate +DECLARE_SOA_COLUMN(Y, y, float); //! Rapidity of candidate +DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! Sign of the candidate +DECLARE_SOA_COLUMN(IsPhi, isPhi, bool); //! Flag to indicate if the candidate is a phi meson +} // namespace resomlcandidates + +DECLARE_SOA_TABLE(ResoMLCandidates, "AOD", "RESOMLCANDIDATES", + resomlcandidates::MultClass, + resomlcandidates::PtDaughter1, + resomlcandidates::PDaughter1, + resomlcandidates::PhiDaughter1, + resomlcandidates::EtaDaughter1, + resomlcandidates::YDaughter1, + resomlcandidates::DCAxyDaughter1, + resomlcandidates::DCAzDaughter1, + resomlcandidates::NSigTpcPi1, + resomlcandidates::NSigTpcKa1, + resomlcandidates::NSigTofPi1, + resomlcandidates::NSigTofKa1, + resomlcandidates::NSigTpcTofPi1, + resomlcandidates::NSigTpcTofKa1, + resomlcandidates::PtDaughter2, + resomlcandidates::PDaughter2, + resomlcandidates::PhiDaughter2, + resomlcandidates::EtaDaughter2, + resomlcandidates::YDaughter2, + resomlcandidates::DCAxyDaughter2, + resomlcandidates::DCAzDaughter2, + resomlcandidates::NSigTpcPi2, + resomlcandidates::NSigTpcKa2, + resomlcandidates::NSigTofPi2, + resomlcandidates::NSigTofKa2, + resomlcandidates::NSigTpcTofPi2, + resomlcandidates::NSigTpcTofKa2, + resomlcandidates::M, + resomlcandidates::Pt, + resomlcandidates::P, + resomlcandidates::Phi, + resomlcandidates::Eta, + resomlcandidates::Y, + resomlcandidates::Sign, + resomlcandidates::IsPhi); + +namespace resomlselection +{ +DECLARE_SOA_COLUMN(PhiBDTScore, gammaBDTScore, float); +} // namespace resomlselection + +DECLARE_SOA_TABLE(ResoPhiMLSelection, "AOD", "RESOPHIMLSELECTION", + resomlselection::PhiBDTScore); +} // namespace o2::aod + +struct resonanceTreeCreator { + // Production of the TTree + Produces resoMLCandidates; + + // Configurables for track selection + Configurable cfgCutCharge{"cfgCutCharge", 0.0f, "Cut on the signed transverse momentum to select positive or negative tracks"}; + + // Configurables for production of training samples + Configurable fillOnlySignal{"fillOnlySignal", false, "Flag to fill derived tables with signal for ML trainings"}; + Configurable fillOnlyBackground{"fillOnlyBackground", false, "Flag to fill derived tables with background for ML trainings"}; + Configurable downSampleBkgFactor{"downSampleBkgFactor", 0.5f, "Fraction of background candidates to keep for ML trainings"}; + Configurable ptMaxForDownSample{"ptMaxForDownSample", 10.0f, "Maximum pt for the application of the downsampling factor"}; + + // Defining the type of the collisions for data and MC + using SelCollisions = soa::Join; + using SimCollisions = soa::Join; + + // Defining the type of the tracks for data and MC + using FullTracks = soa::Join; + using FullMCTracks = soa::Join; + + Partition posTracks = aod::track::signed1Pt > cfgCutCharge; + Partition negTracks = aod::track::signed1Pt < cfgCutCharge; + + Partition posMCTracks = aod::track::signed1Pt > cfgCutCharge; + Partition negMCTracks = aod::track::signed1Pt < cfgCutCharge; + + // Cache for the tracks + SliceCache cache; + + // Necessary to flag INEL>0 events in GenMC + Service pdgDB; + + enum ParticleType { + Pi, + Ka, + Pr + }; + + // Constants + double massPi = o2::constants::physics::MassPiPlus; + double massKa = o2::constants::physics::MassKPlus; + + void init(InitContext&) + { + } + + // Combine Nsigma values from TPC and TOF + template + float combineNSigma(const T& track) + { + float nSigmaTPC, nSigmaTOF; + switch (massHypo) { + case Pi: + nSigmaTPC = track.tpcNSigmaPi(); + nSigmaTOF = track.tofNSigmaPi(); + break; + case Ka: + nSigmaTPC = track.tpcNSigmaKa(); + nSigmaTOF = track.tofNSigmaKa(); + break; + case Pr: + nSigmaTPC = track.tpcNSigmaPr(); + nSigmaTOF = track.tofNSigmaPr(); + break; + default: + break; + } + + static constexpr float defaultNSigmaTolerance = .1f; + static constexpr float defaultNSigma = -999.f + defaultNSigmaTolerance; + + if (nSigmaTPC > defaultNSigma && nSigmaTOF > defaultNSigma) + return std::sqrt(0.5f * std::pow(nSigmaTPC, 2) + std::pow(nSigmaTOF, 2)); + if (nSigmaTPC > defaultNSigma) + return std::abs(nSigmaTPC); + if (nSigmaTOF > defaultNSigma) + return std::abs(nSigmaTOF); + return nSigmaTPC; + } + + // Reconstruct the candidate 4-momentum from two daughter tracks + template + ROOT::Math::PxPyPzMVector recMother(const T& track1, const T& track2, float masstrack1, float masstrack2) + { + ROOT::Math::PxPyPzMVector daughter1(track1.px(), track1.py(), track1.pz(), masstrack1); // set the daughter1 4-momentum + ROOT::Math::PxPyPzMVector daughter2(track2.px(), track2.py(), track2.pz(), masstrack2); // set the daughter2 4-momentum + ROOT::Math::PxPyPzMVector mother = daughter1 + daughter2; // calculate the mother 4-momentum + + return mother; + } + + template + void fillCandidateTree(const T1& collision, const T2& track1, const T2& track2, float masstrack1, float masstrack2) + { + auto tpctofPi1 = combineNSigma(track1); + auto tpctofKa1 = combineNSigma(track1); + auto tpctofPi2 = combineNSigma(track2); + auto tpctofKa2 = combineNSigma(track2); + + ROOT::Math::PxPyPzMVector recCandidate = recMother(track1, track2, masstrack1, masstrack2); + + if (downSampleBkgFactor < 1.) { + float pseudoRndm = track1.pt() * 1000. - static_cast(track1.pt() * 1000); + if (recCandidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) + return; + } + + bool isPhi = false; + if constexpr (isMC) { + if (track1.has_mcParticle() && track2.has_mcParticle()) { + auto mcTrack1 = track1.template mcParticle_as(); + auto mcTrack2 = track2.template mcParticle_as(); + + auto mothersOfMcTrack1 = mcTrack1.template mothers_as(); + auto mothersOfMcTrack2 = mcTrack2.template mothers_as(); + + for (const auto& motherOfMcTrack1 : mothersOfMcTrack1) { + for (const auto& motherOfMcTrack2 : mothersOfMcTrack2) { + if (mcTrack1.pdgCode() == PDG_t::kKPlus && mcTrack2.pdgCode() == PDG_t::kKMinus && + motherOfMcTrack1.pdgCode() == motherOfMcTrack2.pdgCode() && motherOfMcTrack1.pdgCode() == o2::constants::physics::Pdg::kPhi) { + isPhi = true; + break; + } + } + } + } + + if (fillOnlySignal && !isPhi) + return; // Skip filling if only signal is requested and not a phi candidate + if (fillOnlyBackground && isPhi) + return; // Skip filling if only background is requested and a phi candidate + } + + /*isPhi = (mcTrack1.pdgCode() == PDG_t::kKPlus && mcTrack2.pdgCode() == PDG_t::kKMinus && + motherOfMcTrack1.pdgCode() == motherOfMcTrack2.pdgCode() && motherOfMcTrack1.pdgCode() == o2::constants::physics::Pdg::kPhi); + }*/ + + resoMLCandidates(collision.centFT0M(), + track1.pt(), track1.p(), track1.phi(), track1.eta(), track1.rapidity(masstrack1), track1.dcaXY(), track1.dcaZ(), + track1.tpcNSigmaPi(), track1.tpcNSigmaKa(), track1.tofNSigmaPi(), track1.tofNSigmaKa(), tpctofPi1, tpctofKa1, + track2.pt(), track2.p(), track2.phi(), track2.eta(), track2.rapidity(masstrack2), track2.dcaXY(), track2.dcaZ(), + track2.tpcNSigmaPi(), track2.tpcNSigmaKa(), track2.tofNSigmaPi(), track2.tofNSigmaKa(), tpctofPi2, tpctofKa2, + recCandidate.M(), recCandidate.Pt(), recCandidate.P(), recCandidate.Phi(), + recCandidate.Eta(), recCandidate.Rapidity(), track1.sign() + track2.sign(), isPhi); + } + + void processData(SelCollisions::iterator const& collision, FullTracks const&) + { + auto posThisColl = posTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto negThisColl = negTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + + for (const auto& track1 : posThisColl) { + for (const auto& track2 : negThisColl) { + if (track1.globalIndex() == track2.globalIndex()) + continue; // condition to avoid double counting of pair + + // Fill the ResoMLCandidates table with candidates in Data + fillCandidateTree(collision, track1, track2, massKa, massKa); + } + } + } + + PROCESS_SWITCH(resonanceTreeCreator, processData, "Fill ResoMLCandidates in Data", true); + + void processMC(SimCollisions::iterator const& collision, FullMCTracks const&, aod::McParticles const&) + { + auto posThisColl = posMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto negThisColl = negMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + + for (const auto& track1 : posThisColl) { + for (const auto& track2 : negThisColl) { + if (track1.globalIndex() == track2.globalIndex()) + continue; // condition to avoid double counting of pair + + // Fill the ResoMLCandidates table with candidates in MC + fillCandidateTree(collision, track1, track2, massKa, massKa); + } + } + } + + PROCESS_SWITCH(resonanceTreeCreator, processMC, "Fill ResoMLCandidates in MC", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} \ No newline at end of file From cf2d26179a8579149879a66720f18656ff3ee724 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Sun, 14 Sep 2025 10:17:34 +0200 Subject: [PATCH 06/11] Update CMakeLists for new task --- PWGLF/TableProducer/Resonances/CMakeLists.txt | 5 ++ .../Resonances/resonanceTreeCreator.cxx | 52 ++++++++++--------- .../Tasks/Strangeness/phik0shortanalysis.cxx | 4 +- 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/PWGLF/TableProducer/Resonances/CMakeLists.txt b/PWGLF/TableProducer/Resonances/CMakeLists.txt index a58387288a8..a3e59673293 100644 --- a/PWGLF/TableProducer/Resonances/CMakeLists.txt +++ b/PWGLF/TableProducer/Resonances/CMakeLists.txt @@ -54,3 +54,8 @@ o2physics_add_dpl_workflow(cksspinalignment SOURCES cksspinalignment.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(resonance-tree-creator + SOURCES resonanceTreeCreator.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGLF/TableProducer/Resonances/resonanceTreeCreator.cxx b/PWGLF/TableProducer/Resonances/resonanceTreeCreator.cxx index 2c4f8ccfa33..edf7cb558a8 100644 --- a/PWGLF/TableProducer/Resonances/resonanceTreeCreator.cxx +++ b/PWGLF/TableProducer/Resonances/resonanceTreeCreator.cxx @@ -13,23 +13,6 @@ /// \brief Produces a TTree with machine learning variables for resonances in the LF group /// \author Stefano Cannito (stefano.cannito@cern.ch) -#include "Common/DataModel/EventSelection.h" - -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -// #include "PWGLF/DataModel/LFResonanceMLTables.h" #include "PWGLF/DataModel/mcCentrality.h" #include "PWGLF/Utils/inelGt.h" @@ -37,6 +20,7 @@ #include "Common/Core/TrackSelection.h" #include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" @@ -44,10 +28,23 @@ #include "CommonConstants/PhysicsConstants.h" #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/Track.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include + using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; @@ -97,6 +94,16 @@ DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! Sign of the candidate DECLARE_SOA_COLUMN(IsPhi, isPhi, bool); //! Flag to indicate if the candidate is a phi meson } // namespace resomlcandidates +DECLARE_SOA_TABLE(ResoCandidates, "AOD", "RESOCANDIDATES", + resomlcandidates::M, + resomlcandidates::Pt, + resomlcandidates::P, + resomlcandidates::Phi, + resomlcandidates::Eta, + resomlcandidates::Y, + resomlcandidates::Sign, + resomlcandidates::IsPhi); + DECLARE_SOA_TABLE(ResoMLCandidates, "AOD", "RESOMLCANDIDATES", resomlcandidates::MultClass, resomlcandidates::PtDaughter1, @@ -145,6 +152,7 @@ DECLARE_SOA_TABLE(ResoPhiMLSelection, "AOD", "RESOPHIMLSELECTION", struct resonanceTreeCreator { // Production of the TTree + Produces resoCandidates; Produces resoMLCandidates; // Configurables for track selection @@ -171,8 +179,8 @@ struct resonanceTreeCreator { Partition posMCTracks = aod::track::signed1Pt > cfgCutCharge; Partition negMCTracks = aod::track::signed1Pt < cfgCutCharge; - // Cache for the tracks - SliceCache cache; + Preslice perColl = aod::track::collisionId; + Preslice perMCColl = aod::mcparticle::mcCollisionId; // Necessary to flag INEL>0 events in GenMC Service pdgDB; @@ -278,10 +286,6 @@ struct resonanceTreeCreator { return; // Skip filling if only background is requested and a phi candidate } - /*isPhi = (mcTrack1.pdgCode() == PDG_t::kKPlus && mcTrack2.pdgCode() == PDG_t::kKMinus && - motherOfMcTrack1.pdgCode() == motherOfMcTrack2.pdgCode() && motherOfMcTrack1.pdgCode() == o2::constants::physics::Pdg::kPhi); - }*/ - resoMLCandidates(collision.centFT0M(), track1.pt(), track1.p(), track1.phi(), track1.eta(), track1.rapidity(masstrack1), track1.dcaXY(), track1.dcaZ(), track1.tpcNSigmaPi(), track1.tpcNSigmaKa(), track1.tofNSigmaPi(), track1.tofNSigmaKa(), tpctofPi1, tpctofKa1, @@ -331,4 +335,4 @@ struct resonanceTreeCreator { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; -} \ No newline at end of file +} diff --git a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx index 36a1fe840c9..8fd0cabdd0d 100644 --- a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx @@ -3409,7 +3409,9 @@ struct Phik0shortanalysis { continue; // condition to avoid double counting of pair ROOT::Math::PxPyPzMVector recPhi = recMother(track1, track2, massKa, massKa); - if (recPhi.Pt() < phiConfigs.minPhiPt || recPhi.Pt() > phiConfigs.maxPhiPt) + if (recPhi.Pt() < phiConfigs.minPhiPt) + continue; + if (recPhi.M() < phiConfigs.lowMPhi || recPhi.M() > phiConfigs.upMPhi) continue; if (std::abs(recPhi.Rapidity()) > deltaYConfigs.cfgYAcceptance) continue; From 629327fbea4ae38422fa32c7a999b268c8a1a510 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Fri, 19 Sep 2025 09:34:47 +0200 Subject: [PATCH 07/11] Additional selection for phi signal-only candidates --- .../Resonances/resonanceTreeCreator.cxx | 84 ++++++++++--------- 1 file changed, 45 insertions(+), 39 deletions(-) diff --git a/PWGLF/TableProducer/Resonances/resonanceTreeCreator.cxx b/PWGLF/TableProducer/Resonances/resonanceTreeCreator.cxx index edf7cb558a8..9a4a9a28f43 100644 --- a/PWGLF/TableProducer/Resonances/resonanceTreeCreator.cxx +++ b/PWGLF/TableProducer/Resonances/resonanceTreeCreator.cxx @@ -138,8 +138,7 @@ DECLARE_SOA_TABLE(ResoMLCandidates, "AOD", "RESOMLCANDIDATES", resomlcandidates::Phi, resomlcandidates::Eta, resomlcandidates::Y, - resomlcandidates::Sign, - resomlcandidates::IsPhi); + resomlcandidates::Sign); namespace resomlselection { @@ -185,6 +184,9 @@ struct resonanceTreeCreator { // Necessary to flag INEL>0 events in GenMC Service pdgDB; + // Cache for manual slicing + SliceCache cache; + enum ParticleType { Pi, Ka, @@ -244,8 +246,9 @@ struct resonanceTreeCreator { return mother; } - template - void fillCandidateTree(const T1& collision, const T2& track1, const T2& track2, float masstrack1, float masstrack2) + template + void fillCandidateTree(const T1& collision, const T2& track1, const T2& track2, float masstrack1, float masstrack2 + /*std::optional> mcParticles = std::nullopt*/) { auto tpctofPi1 = combineNSigma(track1); auto tpctofKa1 = combineNSigma(track1); @@ -260,39 +263,43 @@ struct resonanceTreeCreator { return; } - bool isPhi = false; - if constexpr (isMC) { - if (track1.has_mcParticle() && track2.has_mcParticle()) { - auto mcTrack1 = track1.template mcParticle_as(); - auto mcTrack2 = track2.template mcParticle_as(); - - auto mothersOfMcTrack1 = mcTrack1.template mothers_as(); - auto mothersOfMcTrack2 = mcTrack2.template mothers_as(); - - for (const auto& motherOfMcTrack1 : mothersOfMcTrack1) { - for (const auto& motherOfMcTrack2 : mothersOfMcTrack2) { - if (mcTrack1.pdgCode() == PDG_t::kKPlus && mcTrack2.pdgCode() == PDG_t::kKMinus && - motherOfMcTrack1.pdgCode() == motherOfMcTrack2.pdgCode() && motherOfMcTrack1.pdgCode() == o2::constants::physics::Pdg::kPhi) { - isPhi = true; - break; - } - } - } - } - - if (fillOnlySignal && !isPhi) - return; // Skip filling if only signal is requested and not a phi candidate - if (fillOnlyBackground && isPhi) - return; // Skip filling if only background is requested and a phi candidate - } - resoMLCandidates(collision.centFT0M(), track1.pt(), track1.p(), track1.phi(), track1.eta(), track1.rapidity(masstrack1), track1.dcaXY(), track1.dcaZ(), track1.tpcNSigmaPi(), track1.tpcNSigmaKa(), track1.tofNSigmaPi(), track1.tofNSigmaKa(), tpctofPi1, tpctofKa1, track2.pt(), track2.p(), track2.phi(), track2.eta(), track2.rapidity(masstrack2), track2.dcaXY(), track2.dcaZ(), track2.tpcNSigmaPi(), track2.tpcNSigmaKa(), track2.tofNSigmaPi(), track2.tofNSigmaKa(), tpctofPi2, tpctofKa2, recCandidate.M(), recCandidate.Pt(), recCandidate.P(), recCandidate.Phi(), - recCandidate.Eta(), recCandidate.Rapidity(), track1.sign() + track2.sign(), isPhi); + recCandidate.Eta(), recCandidate.Rapidity(), track1.sign() + track2.sign()); + } + + template + bool isMCPhi(const T& track1, const T& track2, const aod::McParticles& mcParticles) + { + if (!track1.has_mcParticle() || !track2.has_mcParticle()) + return false; // Skip filling if no MC truth is available for both tracks + + auto mcTrack1 = mcParticles.rawIteratorAt(track1.mcParticleId()); + auto mcTrack2 = mcParticles.rawIteratorAt(track2.mcParticleId()); + + if (mcTrack1.pdgCode() != PDG_t::kKPlus || !mcTrack1.isPhysicalPrimary()) + return false; // Skip filling if the first track is not a primary K+ + if (mcTrack2.pdgCode() != PDG_t::kKMinus || !mcTrack2.isPhysicalPrimary()) + return false; // Skip filling if the second track is not a primary K- + + const auto mcTrack1MotherIndexes = mcTrack1.mothersIds(); + const auto mcTrack2MotherIndexes = mcTrack2.mothersIds(); + + for (const auto& mcTrack1MotherIndex : mcTrack1MotherIndexes) { + for (const auto& mcTrack2MotherIndex : mcTrack2MotherIndexes) { + if (mcTrack1MotherIndex != mcTrack2MotherIndex) + continue; + + const auto mother = mcParticles.rawIteratorAt(mcTrack1MotherIndex); + if (mother.pdgCode() == o2::constants::physics::Pdg::kPhi) + return true; + } + } + return false; } void processData(SelCollisions::iterator const& collision, FullTracks const&) @@ -302,29 +309,28 @@ struct resonanceTreeCreator { for (const auto& track1 : posThisColl) { for (const auto& track2 : negThisColl) { - if (track1.globalIndex() == track2.globalIndex()) - continue; // condition to avoid double counting of pair - // Fill the ResoMLCandidates table with candidates in Data - fillCandidateTree(collision, track1, track2, massKa, massKa); + fillCandidateTree(collision, track1, track2, massKa, massKa); } } } PROCESS_SWITCH(resonanceTreeCreator, processData, "Fill ResoMLCandidates in Data", true); - void processMC(SimCollisions::iterator const& collision, FullMCTracks const&, aod::McParticles const&) + void processMC(SimCollisions::iterator const& collision, FullMCTracks const&, aod::McParticles const& mcParticles) { auto posThisColl = posMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); auto negThisColl = negMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); for (const auto& track1 : posThisColl) { for (const auto& track2 : negThisColl) { - if (track1.globalIndex() == track2.globalIndex()) - continue; // condition to avoid double counting of pair + if (fillOnlySignal && !isMCPhi(track1, track2, mcParticles)) + return; // Skip filling if only signal is requested and not a phi in MC truth + if (fillOnlyBackground && isMCPhi(track1, track2, mcParticles)) + return; // Skip filling if only background is requested and a phi in MC truth // Fill the ResoMLCandidates table with candidates in MC - fillCandidateTree(collision, track1, track2, massKa, massKa); + fillCandidateTree(collision, track1, track2, massKa, massKa); } } } From a1ca222be81809331a39f0adff23938c3ec7dd66 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Fri, 19 Sep 2025 16:39:46 +0200 Subject: [PATCH 08/11] Changed function names --- .../Resonances/resonanceTreeCreator.cxx | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/PWGLF/TableProducer/Resonances/resonanceTreeCreator.cxx b/PWGLF/TableProducer/Resonances/resonanceTreeCreator.cxx index 9a4a9a28f43..3479f896595 100644 --- a/PWGLF/TableProducer/Resonances/resonanceTreeCreator.cxx +++ b/PWGLF/TableProducer/Resonances/resonanceTreeCreator.cxx @@ -84,14 +84,14 @@ DECLARE_SOA_COLUMN(NSigTofKa2, nSigTofKa2, float); //! TOF Nsigma separati DECLARE_SOA_COLUMN(NSigTpcTofPi2, nSigTpcTofPi2, float); //! TPC and TOF combined Nsigma separation for daughter2 with pion mass hypothesis DECLARE_SOA_COLUMN(NSigTpcTofKa2, nSigTpcTofKa2, float); //! TPC and TOF combined Nsigma separation for daughter2 with kaon mass hypothesis // Candidate -DECLARE_SOA_COLUMN(M, m, float); //! Invariant mass of candidate (GeV/c2) -DECLARE_SOA_COLUMN(Pt, pt, float); //! Transverse momentum of candidate (GeV/c) -DECLARE_SOA_COLUMN(P, p, float); //! Momentum of candidate (GeV/c) -DECLARE_SOA_COLUMN(Phi, phi, float); //! Azimuth angle of candidate -DECLARE_SOA_COLUMN(Eta, eta, float); //! Pseudorapidity of candidate -DECLARE_SOA_COLUMN(Y, y, float); //! Rapidity of candidate -DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! Sign of the candidate -DECLARE_SOA_COLUMN(IsPhi, isPhi, bool); //! Flag to indicate if the candidate is a phi meson +DECLARE_SOA_COLUMN(M, m, float); //! Invariant mass of candidate (GeV/c2) +DECLARE_SOA_COLUMN(Pt, pt, float); //! Transverse momentum of candidate (GeV/c) +DECLARE_SOA_COLUMN(P, p, float); //! Momentum of candidate (GeV/c) +DECLARE_SOA_COLUMN(Phi, phi, float); //! Azimuth angle of candidate +DECLARE_SOA_COLUMN(Eta, eta, float); //! Pseudorapidity of candidate +DECLARE_SOA_COLUMN(Y, y, float); //! Rapidity of candidate +DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! Sign of the candidate +DECLARE_SOA_COLUMN(IsTruePhi, isTruePhi, bool); //! Flag to indicate if the candidate is a phi meson } // namespace resomlcandidates DECLARE_SOA_TABLE(ResoCandidates, "AOD", "RESOCANDIDATES", @@ -102,7 +102,7 @@ DECLARE_SOA_TABLE(ResoCandidates, "AOD", "RESOCANDIDATES", resomlcandidates::Eta, resomlcandidates::Y, resomlcandidates::Sign, - resomlcandidates::IsPhi); + resomlcandidates::IsTruePhi); DECLARE_SOA_TABLE(ResoMLCandidates, "AOD", "RESOMLCANDIDATES", resomlcandidates::MultClass, @@ -247,8 +247,8 @@ struct resonanceTreeCreator { } template - void fillCandidateTree(const T1& collision, const T2& track1, const T2& track2, float masstrack1, float masstrack2 - /*std::optional> mcParticles = std::nullopt*/) + void fillCandidateTree4ML(const T1& collision, const T2& track1, const T2& track2, float masstrack1, float masstrack2 + /*std::optional> mcParticles = std::nullopt*/) { auto tpctofPi1 = combineNSigma(track1); auto tpctofKa1 = combineNSigma(track1); @@ -302,7 +302,7 @@ struct resonanceTreeCreator { return false; } - void processData(SelCollisions::iterator const& collision, FullTracks const&) + void processData4ML(SelCollisions::iterator const& collision, FullTracks const&) { auto posThisColl = posTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); auto negThisColl = negTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); @@ -310,14 +310,14 @@ struct resonanceTreeCreator { for (const auto& track1 : posThisColl) { for (const auto& track2 : negThisColl) { // Fill the ResoMLCandidates table with candidates in Data - fillCandidateTree(collision, track1, track2, massKa, massKa); + fillCandidateTree4ML(collision, track1, track2, massKa, massKa); } } } - PROCESS_SWITCH(resonanceTreeCreator, processData, "Fill ResoMLCandidates in Data", true); + PROCESS_SWITCH(resonanceTreeCreator, processData4ML, "Fill ResoMLCandidates in Data", true); - void processMC(SimCollisions::iterator const& collision, FullMCTracks const&, aod::McParticles const& mcParticles) + void processMC4ML(SimCollisions::iterator const& collision, FullMCTracks const&, aod::McParticles const& mcParticles) { auto posThisColl = posMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); auto negThisColl = negMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); @@ -330,12 +330,12 @@ struct resonanceTreeCreator { return; // Skip filling if only background is requested and a phi in MC truth // Fill the ResoMLCandidates table with candidates in MC - fillCandidateTree(collision, track1, track2, massKa, massKa); + fillCandidateTree4ML(collision, track1, track2, massKa, massKa); } } } - PROCESS_SWITCH(resonanceTreeCreator, processMC, "Fill ResoMLCandidates in MC", false); + PROCESS_SWITCH(resonanceTreeCreator, processMC4ML, "Fill ResoMLCandidates in MC", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From bb83f4e13e9786e363bbf00c2db4c30f85dfc4b3 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Sat, 20 Sep 2025 09:13:21 +0200 Subject: [PATCH 09/11] Added preslice --- PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx index 8fd0cabdd0d..945a769ff34 100644 --- a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx @@ -294,8 +294,9 @@ struct Phik0shortanalysis { // Preslice for manual slicing struct : PresliceGroup { - Preslice perColl = aod::track::collisionId; - Preslice perMCColl = aod::mcparticle::mcCollisionId; + Preslice trackPerCollision = aod::track::collisionId; + Preslice mcPartPerMCCollision = aod::mcparticle::mcCollisionId; + Preslice v0PerCollision = aod::v0::collisionId; } preslices; // Positive and negative tracks partitions @@ -2650,7 +2651,7 @@ struct Phik0shortanalysis { } for (const auto& mcCollision : mcCollisions) { - auto mcParticlesThisMcColl = mcParticles.sliceBy(preslices.perMCColl, mcCollision.globalIndex()); + auto mcParticlesThisMcColl = mcParticles.sliceBy(preslices.mcPartPerMCCollision, mcCollision.globalIndex()); if (!pwglf::isINELgtNmc(mcParticlesThisMcColl, 0, pdgDB)) continue; @@ -2676,7 +2677,7 @@ struct Phik0shortanalysis { auto collision = collisions.rawIteratorAt(collisionIndex); if (acceptEventQA(collision, false)) { - auto filteredMCTracksThisColl = filteredMCTracks.sliceBy(preslices.perColl, collision.globalIndex()); + auto filteredMCTracksThisColl = filteredMCTracks.sliceBy(preslices.trackPerCollision, collision.globalIndex()); posFiltMCTracks.bindTable(filteredMCTracksThisColl); negFiltMCTracks.bindTable(filteredMCTracksThisColl); @@ -3145,7 +3146,7 @@ struct Phik0shortanalysis { } for (const auto& mcCollision : mcCollisions) { - auto mcParticlesThisMcColl = mcParticles.sliceBy(preslices.perMCColl, mcCollision.globalIndex()); + auto mcParticlesThisMcColl = mcParticles.sliceBy(preslices.mcPartPerMCCollision, mcCollision.globalIndex()); if (!pwglf::isINELgtNmc(mcParticlesThisMcColl, 0, pdgDB)) continue; @@ -3171,8 +3172,8 @@ struct Phik0shortanalysis { auto collision = collisions.rawIteratorAt(collisionIndex); if (acceptEventQA(collision, false)) { - auto fullMCTracksThisColl = fullMCTracks.sliceBy(preslices.perColl, collision.globalIndex()); - auto v0sThisColl = V0s.sliceBy(preslices.perColl, collision.globalIndex()); + auto fullMCTracksThisColl = fullMCTracks.sliceBy(preslices.trackPerCollision, collision.globalIndex()); + auto v0sThisColl = V0s.sliceBy(preslices.v0PerCollision, collision.globalIndex()); posMCTracks.bindTable(fullMCTracksThisColl); negMCTracks.bindTable(fullMCTracksThisColl); From bdf4baa3440a7915edafbd7946cb2037719776c0 Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Sat, 20 Sep 2025 09:26:29 +0200 Subject: [PATCH 10/11] new axis --- PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx index 945a769ff34..eb60a0cb1af 100644 --- a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx @@ -338,6 +338,7 @@ struct Phik0shortanalysis { AxisSpec etaAxis = {16, -trackConfigs.etaMax, trackConfigs.etaMax, "#eta"}; AxisSpec yAxis = {deltaYConfigs.nBinsY, -deltaYConfigs.cfgYAcceptance, deltaYConfigs.cfgYAcceptance, "#it{y}"}; AxisSpec deltayAxis = {deltaYConfigs.nBinsDeltaY, -1.0f, 1.0f, "#Delta#it{y}"}; + AxisSpec deltaphiAxis = {72, -o2::constants::math::PIHalf, o2::constants::math::PIHalf * 3, "#Delta#varphi"}; AxisSpec phiAxis = {629, 0, o2::constants::math::TwoPI, "#phi"}; AxisSpec multAxis = {120, 0.0f, 120.0f, "centFT0M"}; AxisSpec binnedmultAxis{(std::vector)binsMult, "centFT0M"}; @@ -657,6 +658,9 @@ struct Phik0shortanalysis { dataPhiK0SHist.add("h5PhiK0SDataNewProc", "2D Invariant mass of Phi and K0Short in Data", kTHnSparseF, {deltayAxis, binnedmultAxis, binnedpTK0SAxis, massK0SAxis, massPhiAxis}); dataPhiPionHist.add("h5PhiPiTPCDataNewProc", "Phi Invariant mass vs Pion nSigma TPC in Data", kTHnSparseF, {deltayAxis, binnedmultAxis, binnedpTPiAxis, nSigmaPiAxis, massPhiAxis}); dataPhiPionHist.add("h5PhiPiTOFDataNewProc", "Phi Invariant mass vs Pion nSigma TOF in Data", kTHnSparseF, {deltayAxis, binnedmultAxis, binnedpTPiAxis, nSigmaPiAxis, massPhiAxis}); + + dataPhiK0SHist.add("h5PhiK0SData2PartCorr", "Deltay vs deltaphi for Phi and K0Short in Data", kTHnSparseF, {binnedmultAxis, binnedpTPhiAxis, binnedpTK0SAxis, deltayAxis, deltaphiAxis}); + dataPhiPionHist.add("h5PhiPiData2PartCorr", "Deltay vs deltaphi for Phi and Pion in Data", kTHnSparseF, {binnedmultAxis, binnedpTPhiAxis, binnedpTPiAxis, deltayAxis, deltaphiAxis}); } if (analysisModeConfigs.isClosureNewProc) { From a2d285a7ef9e296acc8d522c4c5e5cc00f37357f Mon Sep 17 00:00:00 2001 From: Stefano Cannito Date: Sat, 20 Sep 2025 11:56:52 +0200 Subject: [PATCH 11/11] Removed unused function --- PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx index eb60a0cb1af..047e32c8adc 100644 --- a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx @@ -941,20 +941,6 @@ struct Phik0shortanalysis { return true; } - template - bool selectionPhi(const T& posTrack, const T& negTrack) - { - // To be possibly completed - return !posTrack.empty() && !negTrack.empty(); - } - - template - bool selectionPhiWPDG(const T1& posTrack, const T1& negTrack, const T2& mcParticles) - { - // To be possibly completed - return !posTrack.empty() && !negTrack.empty(); - } - template bool eventHasRecoPhi(const T1& posTracks, const T2& negTracks) {