diff --git a/PWGLF/TableProducer/Resonances/resonanceModuleInitializer.cxx b/PWGLF/TableProducer/Resonances/resonanceModuleInitializer.cxx index d5a43cf1028..8a07e7365b3 100644 --- a/PWGLF/TableProducer/Resonances/resonanceModuleInitializer.cxx +++ b/PWGLF/TableProducer/Resonances/resonanceModuleInitializer.cxx @@ -110,9 +110,9 @@ struct ResonanceModuleInitializer { static constexpr int PdgLambda1520 = o2::constants::physics::Pdg::kLambda1520_Py; static constexpr int Xi1530Code = 3324; static constexpr int PdgK1Plus1270 = o2::constants::physics::Pdg::kK1_1270Plus; - static constexpr int Xi1820NeutralCode = 123314; - static constexpr int Xi1820MinusCode = 123324; - static constexpr int Omega2012MinusCode = 123334; + static constexpr int Xi1820MinusCode = o2::constants::physics::Pdg::kXi1820Minus; + static constexpr int Xi1820ZeroCode = o2::constants::physics::Pdg::kXi1820Zero; + static constexpr int Omega2012MinusCode = o2::constants::physics::Pdg::kOmega2012Minus; static constexpr int PdgProton = PDG_t::kProton; static constexpr int PdgLambda0 = PDG_t::kLambda0; static constexpr int PdgXiMinus = PDG_t::kXiMinus; @@ -232,7 +232,7 @@ struct ResonanceModuleInitializer { || (nabs(aod::mcparticle::pdgCode) == PdgLambda1520) // Lambda(1520) || (nabs(aod::mcparticle::pdgCode) == Xi1530Code) // Xi(1530)0 || (nabs(aod::mcparticle::pdgCode) == PdgK1Plus1270) // K1(1270)+ - || (nabs(aod::mcparticle::pdgCode) == Xi1820NeutralCode) // Xi(1820)0 + || (nabs(aod::mcparticle::pdgCode) == Xi1820ZeroCode) // Xi(1820)0 || (nabs(aod::mcparticle::pdgCode) == Xi1820MinusCode) // Xi(1820)- || (nabs(aod::mcparticle::pdgCode) == Omega2012MinusCode) // Omega(2012)- || (nabs(aod::mcparticle::pdgCode) == PdgProton) // proton diff --git a/PWGLF/Tasks/Resonances/omega2012Analysis.cxx b/PWGLF/Tasks/Resonances/omega2012Analysis.cxx index 2f9db446f51..831ac6e89e8 100644 --- a/PWGLF/Tasks/Resonances/omega2012Analysis.cxx +++ b/PWGLF/Tasks/Resonances/omega2012Analysis.cxx @@ -50,7 +50,6 @@ struct Omega2012Analysis { static constexpr float kSmallNumber = 1e-10f; // Small number to avoid division by zero static constexpr float kMaxDCAV0ToPV = 1.0f; // Maximum DCA of V0 to PV static constexpr int kNumExpectedDaughters = 2; // Expected number of daughters for 2-body decay - static constexpr int kPlaceholderPdgCode = 3335; SliceCache cache; Preslice perResoCollisionCasc = aod::resodaughter::resoCollisionId; Preslice perResoCollisionV0 = aod::resodaughter::resoCollisionId; @@ -73,6 +72,8 @@ struct Omega2012Analysis { Configurable cMaxEtaCut{"cMaxEtaCut", 0.8, "Maximum |eta|"}; Configurable cfgRapidityCut{"cfgRapidityCut", 0.5, "Rapidity cut"}; Configurable cRecoINELgt0{"cRecoINELgt0", false, "Apply Reco INEL>0 event selection"}; + Configurable cMCINELgt0{"cMCINELgt0", false, "Require generator INEL>0 in MC processes"}; + Configurable cMCVtxIn10{"cMCVtxIn10", false, "Require generator |vertex z| < 10 cm in MC processes"}; Configurable cKinCuts{"cKinCuts", false, "Kinematic cuts for Xi-K0s opening angle"}; Configurable> cKinCutsPt{"cKinCutsPt", {0.0, 0.4, 0.6, 0.8, 1.0, 1.4, 1.8, 2.2, 2.6, 3.0, 4.0, 5.0, 6.0, 1e10}, "Omega(2012) pT bins for kinematic cuts"}; Configurable> cKinLowerCutsAlpha{"cKinLowerCutsAlpha", {1.5, 1.0, 0.5, 0.3, 0.2, 0.15, 0.1, 0.08, 0.07, 0.06, 0.04, 0.02, 0.02}, "Lower cut on Xi-K0s opening angle"}; @@ -157,6 +158,10 @@ struct Omega2012Analysis { // PDG masses double massK0 = MassK0Short; + // Module-initializer collision tables (matches the resonance-module-initializer producer) + using ResoCollisions = aod::ResoCollisions_001; + using ResoMCCollisions = soa::Join; + using BinningTypeVertexContributor = ColumnBinningPolicy; BinningTypeVertexContributor colBinning{{cfgVtxBins, cfgMultBins}, true}; @@ -888,7 +893,7 @@ struct Omega2012Analysis { } PROCESS_SWITCH(Omega2012Analysis, processDummy, "Process Dummy", true); - void processData(const aod::ResoCollision& collision, + void processData(ResoCollisions::iterator const& collision, aod::ResoCascades const& resocasc, aod::ResoV0s const& resov0s) { @@ -899,13 +904,13 @@ struct Omega2012Analysis { } PROCESS_SWITCH(Omega2012Analysis, processData, "Process Event for data", false); - void processMixedEvent(const aod::ResoCollisions& collisions, + void processMixedEvent(ResoCollisions const& collisions, aod::ResoCascades const& resocasc, aod::ResoV0s const& resov0s) { auto cascV0sTuple = std::make_tuple(resocasc, resov0s); - Pair pairs{colBinning, nEvtMixing, -1, collisions, cascV0sTuple, &cache}; + Pair pairs{colBinning, nEvtMixing, -1, collisions, cascV0sTuple, &cache}; for (const auto& [collision1, casc1, collision2, v0s2] : pairs) { if (cRecoINELgt0 && (!collision1.isRecINELgt0() || !collision2.isRecINELgt0())) @@ -947,20 +952,56 @@ struct Omega2012Analysis { } PROCESS_SWITCH(Omega2012Analysis, processMixedEvent, "Process Mixed Event", false); - // MC processes - placeholder for future implementation - void processMC(const aod::ResoCollision& /*collision*/, - aod::ResoCascades const& /*resocasc*/, - aod::ResoV0s const& /*resov0s*/, - aod::McParticles const& /*mcParticles*/) + // MC reconstructed processing: match reconstructed Xi + K0s pairs to a common Omega(2012) mother + void processMC(ResoMCCollisions::iterator const& collision, + soa::Join const& resocasc, + soa::Join const& resov0s) { - // TODO: Implement MC truth matching for Xi + K0s - // - Match reconstructed Xi to MC Xi - // - Match reconstructed K0s to MC K0s - // - Fill MC truth histograms - // - Fill reconstruction efficiency histograms - // - Check if the Xi and K0s come from same Omega(2012) mother + if (cRecoINELgt0 && !collision.isRecINELgt0()) + return; + if (cMCINELgt0 && !collision.isINELgt0()) + return; + if (cMCVtxIn10 && !collision.isVtxIn10()) + return; + + int nCascAfterCuts = 0; + int nV0sAfterCuts = 0; + auto selectedXis = selectXiCandidates(resocasc, nCascAfterCuts); + auto selectedK0s = selectK0sCandidates(collision, resov0s, nV0sAfterCuts); + + for (const auto& selectedXi : selectedXis) { + const auto& xi = selectedXi.candidate; + if (std::abs(xi.pdgCode()) != kXiMinus) + continue; + + for (const auto& selectedK0 : selectedK0s) { + const auto& v0 = selectedK0.candidate; + + if (sharesAnyDaughterId(selectedXi.daughterIds, selectedK0.daughterIds)) + continue; + if (std::abs(v0.pdgCode()) != kK0Short) + continue; + if (xi.motherId() < 0 || xi.motherId() != v0.motherId()) + continue; + if (std::abs(xi.motherPDG()) != kOmega2012Minus || xi.motherPDG() != v0.motherPDG()) + continue; + + ROOT::Math::PxPyPzEVector pXi, pK0s, pRes; + pXi = ROOT::Math::PxPyPzEVector(ROOT::Math::PtEtaPhiMVector(xi.pt(), xi.eta(), xi.phi(), xi.mXi())); + pK0s = ROOT::Math::PxPyPzEVector(ROOT::Math::PtEtaPhiMVector(v0.pt(), v0.eta(), v0.phi(), massK0)); + pRes = pXi + pK0s; + + if (std::abs(pRes.Rapidity()) >= cfgRapidityCut) + continue; + + histos.fill(HIST("MC/hMCRecOmega2012Pt"), pRes.Pt()); + histos.fill(HIST("MC/hMCRecOmega2012PtEta"), pRes.Pt(), pRes.Eta()); + histos.fill(HIST("MC/hMCRecXiPt"), xi.pt()); + histos.fill(HIST("MC/hMCRecK0sPt"), v0.pt()); + } + } } - PROCESS_SWITCH(Omega2012Analysis, processMC, "Process MC with truth matching (placeholder)", false); + PROCESS_SWITCH(Omega2012Analysis, processMC, "Process MC with truth matching", false); void processMCGenerated(aod::McParticles const& mcParticles) { @@ -968,11 +1009,10 @@ struct Omega2012Analysis { // This resonance decays to Xi + K0s for (const auto& mcParticle : mcParticles) { - // Look for Omega(2012) - PDG code may vary by generator + // Look for Omega(2012) int pdg = mcParticle.pdgCode(); - // TODO: Update the PDG code library to include Omega(2012) codes - if (std::abs(pdg) != kPlaceholderPdgCode) + if (std::abs(pdg) != kOmega2012Minus) continue; // Fill generated level histograms @@ -1015,10 +1055,16 @@ struct Omega2012Analysis { (std::abs(daughter2PDG) == kXiMinus && daughter1PDG == kK0Short)) { histos.fill(HIST("MC/hMCTruthInvMassXiK0s"), motherM); histos.fill(HIST("MC/hMCTruthMassPtXiK0s"), motherM, motherPt); + + const bool isDaughter1Xi = std::abs(daughter1PDG) == kXiMinus; + const auto& pXiTruth = isDaughter1Xi ? p1 : p2; + const auto& pK0sTruth = isDaughter1Xi ? p2 : p1; + histos.fill(HIST("MC/hMCTrueXiPt"), pXiTruth.Pt()); + histos.fill(HIST("MC/hMCTrueK0sPt"), pK0sTruth.Pt()); } } } - PROCESS_SWITCH(Omega2012Analysis, processMCGenerated, "Process MC generated particles (placeholder)", false); + PROCESS_SWITCH(Omega2012Analysis, processMCGenerated, "Process MC generated particles", false); // Fill function for 3-body decay analysis template @@ -1122,7 +1168,7 @@ struct Omega2012Analysis { } // 3-body decay analysis: Xi + pi + K0s with ResoTracks - void processThreeBodyWithTracks(const aod::ResoCollision& collision, + void processThreeBodyWithTracks(ResoCollisions::iterator const& collision, aod::ResoCascades const& resocasc, aod::ResoV0s const& resov0s, aod::ResoTracks const& resotracks, @@ -1136,7 +1182,7 @@ struct Omega2012Analysis { PROCESS_SWITCH(Omega2012Analysis, processThreeBodyWithTracks, "Process 3-body decay with ResoTracks", false); // 3-body decay analysis: Xi + pi + K0s with ResoMicroTracks - void processThreeBodyWithMicroTracks(const aod::ResoCollision& collision, + void processThreeBodyWithMicroTracks(ResoCollisions::iterator const& collision, aod::ResoCascades const& resocasc, aod::ResoV0s const& resov0s, aod::ResoMicroTracks const& resomicrotracks, diff --git a/PWGLF/Tasks/Resonances/xi1820Analysis.cxx b/PWGLF/Tasks/Resonances/xi1820Analysis.cxx index 12b89e89024..576d6e232b7 100644 --- a/PWGLF/Tasks/Resonances/xi1820Analysis.cxx +++ b/PWGLF/Tasks/Resonances/xi1820Analysis.cxx @@ -103,8 +103,8 @@ struct Xi1820Analysis { // Constants static constexpr float SmallMomentumDenominator = 1e-10f; // Small value to avoid division by zero - static constexpr int PdgChargedXi1820 = 123314; // o2-linter: disable=pdg/explicit-code (Xi(1820) PDG code not available in PDG_t or o2::constants::physics::Pdg) - static constexpr int PdgXi1820Zero = 123324; // o2-linter: disable=pdg/explicit-code (Xi(1820) PDG code not available in PDG_t or o2::constants::physics::Pdg) + static constexpr int PdgChargedXi1820 = Pdg::kXi1820Minus; + static constexpr int PdgXi1820Zero = Pdg::kXi1820Zero; static constexpr int ExpectedDaughters = 2; // Expected number of daughters for two-body decay // Axes