From 167ddd3cd9fea06f0f05b73c5d9594997aa3d78f Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Fri, 13 Nov 2026 00:34:46 +0100 Subject: [PATCH 1/6] implement retrieveMatchedGenParticle() and pass it to fillCandidateTable() --- .../TableProducer/treeCreatorXicToXiPiPi.cxx | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx b/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx index 338fe6ca1fd..c0f63cf51b5 100644 --- a/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx +++ b/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx @@ -17,6 +17,7 @@ /// \author Jaeyoon Cho , Inha University #include "PWGHF/Core/DecayChannelsLegacy.h" +#include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" @@ -37,6 +38,7 @@ #include #include +#include #include using namespace o2; @@ -418,10 +420,9 @@ struct HfTreeCreatorXicToXiPiPi { using SelectedCandidatesMc = soa::Filtered>; using SelectedCandidatesKfMc = soa::Filtered>; using SelectedCandidatesMcML = soa::Filtered>; - using MatchedGenXicToXiPiPi = soa::Filtered>; + using MatchedGenXicToXiPiPi = soa::Join; Filter filterSelectCandidates = aod::hf_sel_candidate_xic::isSelXicToXiPiPi >= selectionFlagXic; - Filter filterGenXicToXiPiPi = (nabs(aod::hf_cand_mc_flag::flagMcMatchGen) == static_cast(BIT(aod::hf_cand_xic_to_xi_pi_pi::DecayType::XicToXiPiPi)) || nabs(aod::hf_cand_mc_flag::flagMcMatchGen) == static_cast(BIT(aod::hf_cand_xic_to_xi_pi_pi::DecayType::XicToXiResPiToXiPiPi)) || fillGenInfoForAcceptance == true); Partition recSig = nabs(aod::hf_cand_mc_flag::flagMcMatchRec) != static_cast(0); Partition recBg = nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(0); @@ -437,7 +438,7 @@ struct HfTreeCreatorXicToXiPiPi { } template - void fillCandidateTable(const T& candidate) + void fillCandidateTable(const T& candidate, const std::optional& particle = std::nullopt) { int8_t particleFlag = candidate.sign(); int8_t originMc = 0; @@ -792,6 +793,18 @@ struct HfTreeCreatorXicToXiPiPi { } } + template + std::optional retrieveMatchedGenParticle(CandType const& candidate, MatchedGenXicToXiPiPi const& particles) + { + const auto mcParticlePi0 = candidate.template pi0_as().template mcParticle_as(); + const auto indexMother = RecoDecay::getMother(particles, mcParticlePi0, o2::constants::physics::Pdg::kXiCPlus, true); + if (indexMother < 0) { + return std::nullopt; + } + const auto particleMother = particles.rawIteratorAt(indexMother); + return particleMother; + } + void processData(SelectedCandidates const& candidates) { // Filling candidate properties @@ -854,7 +867,8 @@ struct HfTreeCreatorXicToXiPiPi { rowCandidateFull.reserve(recSig.size()); } for (const auto& candidate : recSig) { - fillCandidateTable(candidate); + const auto matchedGenParticle = retrieveMatchedGenParticle(candidate, particles); + fillCandidateTable(candidate, matchedGenParticle); } } else if (fillOnlyBackground) { if (fillCandidateLiteTable) { @@ -876,7 +890,8 @@ struct HfTreeCreatorXicToXiPiPi { rowCandidateFull.reserve(candidates.size()); } for (const auto& candidate : candidates) { - fillCandidateTable(candidate); + const auto matchedGenParticle = retrieveMatchedGenParticle(candidate, particles); + fillCandidateTable(candidate, matchedGenParticle); } } @@ -917,7 +932,8 @@ struct HfTreeCreatorXicToXiPiPi { PROCESS_SWITCH(HfTreeCreatorXicToXiPiPi, processMc, "Process MC with DCAFitter reconstruction", false); void processMcKf(SelectedCandidatesKfMc const& candidates, - MatchedGenXicToXiPiPi const& particles) + MatchedGenXicToXiPiPi const& particles, + o2::aod::TracksWMc const&) { // Filling candidate properties if (fillOnlySignal) { @@ -927,7 +943,8 @@ struct HfTreeCreatorXicToXiPiPi { rowCandidateFull.reserve(recSigKf.size()); } for (const auto& candidate : recSigKf) { - fillCandidateTable(candidate); + const auto matchedGenParticle = retrieveMatchedGenParticle(candidate, particles); + fillCandidateTable(candidate, matchedGenParticle); } } else if (fillOnlyBackground) { if (fillCandidateLiteTable) { @@ -949,7 +966,8 @@ struct HfTreeCreatorXicToXiPiPi { rowCandidateFull.reserve(candidates.size()); } for (const auto& candidate : candidates) { - fillCandidateTable(candidate); + const auto matchedGenParticle = retrieveMatchedGenParticle(candidate, particles); + fillCandidateTable(candidate, matchedGenParticle); } } From 9b9af193a2b1f9a82f11fecdffd958baf911883f Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Fri, 13 Nov 2026 19:47:02 +0100 Subject: [PATCH 2/6] implement evaluateDecayLengthGenerated(), add namespace mc_match --- .../TableProducer/treeCreatorXicToXiPiPi.cxx | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx b/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx index c0f63cf51b5..fab7c6610bb 100644 --- a/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx +++ b/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx @@ -96,6 +96,12 @@ DECLARE_SOA_COLUMN(MlScorePrompt, mlScorePrompt, float); DECLARE_SOA_COLUMN(MlScoreNonPrompt, mlScoreNonPrompt, float); //! ML score for non-prompt signal class (3-class model only, -1 otherwise) } // namespace full +namespace mc_match +{ +DECLARE_SOA_COLUMN(PGen, pGen, float); //! momentum of matched generated particle +DECLARE_SOA_COLUMN(DecayLengthGen, decayLengthGen, float); //! decay length of matched generated particle +} // namespace mc_match + DECLARE_SOA_TABLE(HfCandXicToXiPiPiLites, "AOD", "HFXICXI2PILITE", full::ParticleFlag, hf_cand_mc_flag::OriginMcRec, @@ -805,6 +811,23 @@ struct HfTreeCreatorXicToXiPiPi { return particleMother; } + template + float evaluateDecayLengthGenerated(CandType const& candidate, MatchedGenXicToXiPiPi::iterator const& particle) + { + const auto mcParticlePi0 = candidate.template pi0_as().template mcParticle_as(); + const auto decayVertexX = mcParticlePi0.vx(); + const auto decayVertexY = mcParticlePi0.vy(); + const auto decayVertexZ = mcParticlePi0.vz(); + + const auto mcCollision = particle.template mcCollision_as(); + const auto primaryVertexX = mcCollision.posX(); + const auto primaryVertexY = mcCollision.posY(); + const auto primaryVertexZ = mcCollision.posZ(); + + const auto decayLendth = RecoDecay::distance(std::array{primaryVertexX, primaryVertexY, primaryVertexZ}, std::array{decayVertexX, decayVertexY, decayVertexZ}); + return decayLendth; + } + void processData(SelectedCandidates const& candidates) { // Filling candidate properties From 8d8b0a90fe69659e74db11d40ea24f30783f8034 Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Fri, 13 Nov 2026 23:26:02 +0100 Subject: [PATCH 3/6] rm evaluateDecayLengthGenerated(), save mc_match::[pGen, lGen] --- .../TableProducer/treeCreatorXicToXiPiPi.cxx | 74 ++++++++++++------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx b/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx index fab7c6610bb..8ad4b9b96b7 100644 --- a/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx +++ b/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx @@ -137,7 +137,10 @@ DECLARE_SOA_TABLE(HfCandXicToXiPiPiLites, "AOD", "HFXICXI2PILITE", full::ImpactParameterNormalisedPi0, full::ImpactParameterPi1, full::ImpactParameterNormalisedPi1, - full::MaxNormalisedDeltaIP); + full::MaxNormalisedDeltaIP, + // parameters of matched MC particle + mc_match::PGen, + mc_match::DecayLengthGen); DECLARE_SOA_TABLE(HfCandXicToXiPiPiLiteKfs, "AOD", "HFXICXI2PILITKF", full::ParticleFlag, @@ -207,7 +210,10 @@ DECLARE_SOA_TABLE(HfCandXicToXiPiPiLiteKfs, "AOD", "HFXICXI2PILITKF", hf_cand_xic_to_xi_pi_pi::DcaPi1Xi, hf_cand_xic_to_xi_pi_pi::DcaXYPi0Pi1, hf_cand_xic_to_xi_pi_pi::DcaXYPi0Xi, - hf_cand_xic_to_xi_pi_pi::DcaXYPi1Xi); + hf_cand_xic_to_xi_pi_pi::DcaXYPi1Xi, + // parameters of matched MC particle + mc_match::PGen, + mc_match::DecayLengthGen); DECLARE_SOA_TABLE(HfCandXicToXiPiPiLiteMLs, "AOD", "HFXICXI2PIMLITE", full::ParticleFlag, @@ -231,7 +237,10 @@ DECLARE_SOA_TABLE(HfCandXicToXiPiPiLiteMLs, "AOD", "HFXICXI2PIMLITE", hf_cand_xic_to_xi_pi_pi::NSigTpcPrFromLambda, full::MlScoreBkg, full::MlScorePrompt, - full::MlScoreNonPrompt); + full::MlScoreNonPrompt, + // parameters of matched MC particle + mc_match::PGen, + mc_match::DecayLengthGen); DECLARE_SOA_TABLE(HfCandXicToXiPiPiFulls, "AOD", "HFXICXI2PIFULL", full::ParticleFlag, @@ -293,7 +302,10 @@ DECLARE_SOA_TABLE(HfCandXicToXiPiPiFulls, "AOD", "HFXICXI2PIFULL", hf_cand_xic_to_xi_pi_pi::NSigTofPiFromXicPlus1, hf_cand_xic_to_xi_pi_pi::NSigTofBachelorPi, hf_cand_xic_to_xi_pi_pi::NSigTofPiFromLambda, - hf_cand_xic_to_xi_pi_pi::NSigTofPrFromLambda); + hf_cand_xic_to_xi_pi_pi::NSigTofPrFromLambda, + // parameters of matched MC particle + mc_match::PGen, + mc_match::DecayLengthGen); DECLARE_SOA_TABLE(HfCandXicToXiPiPiFullKfs, "AOD", "HFXICXI2PIFULKF", full::ParticleFlag, @@ -375,7 +387,10 @@ DECLARE_SOA_TABLE(HfCandXicToXiPiPiFullKfs, "AOD", "HFXICXI2PIFULKF", hf_cand_xic_to_xi_pi_pi::DcaPi1Xi, hf_cand_xic_to_xi_pi_pi::DcaXYPi0Pi1, hf_cand_xic_to_xi_pi_pi::DcaXYPi0Xi, - hf_cand_xic_to_xi_pi_pi::DcaXYPi1Xi); + hf_cand_xic_to_xi_pi_pi::DcaXYPi1Xi, + // parameters of matched MC particle + mc_match::PGen, + mc_match::DecayLengthGen); DECLARE_SOA_TABLE(HfCandXicToXiPiPiFullPs, "AOD", "HFXICXI2PIFULLP", hf_cand_mc_flag::FlagMcMatchGen, @@ -419,6 +434,7 @@ struct HfTreeCreatorXicToXiPiPi { Configurable ptMaxForDownSample{"ptMaxForDownSample", 10., "Maximum pt for the application of the downsampling factor"}; static constexpr int kNumBinaryClasses = 2; + static constexpr float UndefValueFloat = -999.f; using SelectedCandidates = soa::Filtered>; using SelectedCandidatesKf = soa::Filtered>; @@ -448,9 +464,15 @@ struct HfTreeCreatorXicToXiPiPi { { int8_t particleFlag = candidate.sign(); int8_t originMc = 0; + float pGen{UndefValueFloat}; + float decayLengthGen{UndefValueFloat}; if constexpr (DoMc) { particleFlag = candidate.flagMcMatchRec(); originMc = candidate.originMcRec(); + if (particle.has_value()) { + pGen = particle->p(); + decayLengthGen = particle->decayLengthMcGen(); + } } if constexpr (!DoKf && !DoMl) { if (fillCandidateLiteTable) { @@ -489,7 +511,10 @@ struct HfTreeCreatorXicToXiPiPi { candidate.impactParameterNormalised1(), candidate.impactParameter2(), candidate.impactParameterNormalised2(), - candidate.maxNormalisedDeltaIP()); + candidate.maxNormalisedDeltaIP(), + // parameters of matched MC particle + pGen, + decayLengthGen); } else { rowCandidateFull( particleFlag, @@ -551,7 +576,10 @@ struct HfTreeCreatorXicToXiPiPi { candidate.nSigTofPiFromXicPlus1(), candidate.nSigTofBachelorPi(), candidate.nSigTofPiFromLambda(), - candidate.nSigTofPrFromLambda()); + candidate.nSigTofPrFromLambda(), + // parameters of matched MC particle + pGen, + decayLengthGen); } } else if constexpr (DoKf) { if (fillCandidateLiteTable) { @@ -623,7 +651,10 @@ struct HfTreeCreatorXicToXiPiPi { candidate.dcaPi1Xi(), candidate.dcaXYPi0Pi1(), candidate.dcaXYPi0Xi(), - candidate.dcaXYPi1Xi()); + candidate.dcaXYPi1Xi(), + // parameters of matched MC particle + pGen, + decayLengthGen); } else { rowCandidateFullKf( particleFlag, @@ -705,7 +736,10 @@ struct HfTreeCreatorXicToXiPiPi { candidate.dcaPi1Xi(), candidate.dcaXYPi0Pi1(), candidate.dcaXYPi0Xi(), - candidate.dcaXYPi1Xi()); + candidate.dcaXYPi1Xi(), + // parameters of matched MC particle + pGen, + decayLengthGen); } } if constexpr (DoMl) { @@ -740,7 +774,10 @@ struct HfTreeCreatorXicToXiPiPi { candidate.nSigTpcPrFromLambda(), mlScoreBkg, mlScorePrompt, - mlScoreNonPrompt); + mlScoreNonPrompt, + // parameters of matched MC particle + pGen, + decayLengthGen); } } @@ -811,23 +848,6 @@ struct HfTreeCreatorXicToXiPiPi { return particleMother; } - template - float evaluateDecayLengthGenerated(CandType const& candidate, MatchedGenXicToXiPiPi::iterator const& particle) - { - const auto mcParticlePi0 = candidate.template pi0_as().template mcParticle_as(); - const auto decayVertexX = mcParticlePi0.vx(); - const auto decayVertexY = mcParticlePi0.vy(); - const auto decayVertexZ = mcParticlePi0.vz(); - - const auto mcCollision = particle.template mcCollision_as(); - const auto primaryVertexX = mcCollision.posX(); - const auto primaryVertexY = mcCollision.posY(); - const auto primaryVertexZ = mcCollision.posZ(); - - const auto decayLendth = RecoDecay::distance(std::array{primaryVertexX, primaryVertexY, primaryVertexZ}, std::array{decayVertexX, decayVertexY, decayVertexZ}); - return decayLendth; - } - void processData(SelectedCandidates const& candidates) { // Filling candidate properties From 5875777429d05f1874cd05b130bcd1f68b1e352a Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Fri, 13 Nov 2026 23:34:12 +0100 Subject: [PATCH 4/6] do not write mc_match to ml-tree --- PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx b/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx index 8ad4b9b96b7..62771a6082c 100644 --- a/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx +++ b/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx @@ -237,10 +237,7 @@ DECLARE_SOA_TABLE(HfCandXicToXiPiPiLiteMLs, "AOD", "HFXICXI2PIMLITE", hf_cand_xic_to_xi_pi_pi::NSigTpcPrFromLambda, full::MlScoreBkg, full::MlScorePrompt, - full::MlScoreNonPrompt, - // parameters of matched MC particle - mc_match::PGen, - mc_match::DecayLengthGen); + full::MlScoreNonPrompt); DECLARE_SOA_TABLE(HfCandXicToXiPiPiFulls, "AOD", "HFXICXI2PIFULL", full::ParticleFlag, @@ -774,10 +771,7 @@ struct HfTreeCreatorXicToXiPiPi { candidate.nSigTpcPrFromLambda(), mlScoreBkg, mlScorePrompt, - mlScoreNonPrompt, - // parameters of matched MC particle - pGen, - decayLengthGen); + mlScoreNonPrompt); } } From 24f3a07980cf17b44a8e9fcbad609969c6fe6bff Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Sat, 14 Nov 2026 00:09:51 +0100 Subject: [PATCH 5/6] fix clang-tidy errors --- PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx b/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx index 62771a6082c..cfa42b79085 100644 --- a/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx +++ b/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx @@ -838,7 +838,7 @@ struct HfTreeCreatorXicToXiPiPi { if (indexMother < 0) { return std::nullopt; } - const auto particleMother = particles.rawIteratorAt(indexMother); + auto particleMother = particles.rawIteratorAt(indexMother); return particleMother; } @@ -1111,7 +1111,7 @@ struct HfTreeCreatorXicToXiPiPi { PROCESS_SWITCH(HfTreeCreatorXicToXiPiPi, processMcWithML, "Process MC with DCAFitter reconstruction and ML", false); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +WorkflowSpec defineDataProcessing(ConfigContext const& context) { - return WorkflowSpec{adaptAnalysisTask(cfgc)}; + return WorkflowSpec{adaptAnalysisTask(context)}; } From 3d5edfa16e125e041646701f5d2a50a5dd20d03c Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Sat, 14 Nov 2026 00:49:38 +0100 Subject: [PATCH 6/6] subscribe processMc for o2::aod::TracksWMc --- PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx b/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx index cfa42b79085..40fd5d3eca0 100644 --- a/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx +++ b/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx @@ -894,7 +894,8 @@ struct HfTreeCreatorXicToXiPiPi { PROCESS_SWITCH(HfTreeCreatorXicToXiPiPi, processDataWithML, "Process data with DCAFitter reconstruction and ML", false); void processMc(SelectedCandidatesMc const& candidates, - MatchedGenXicToXiPiPi const& particles) + MatchedGenXicToXiPiPi const& particles, + o2::aod::TracksWMc const&) { // Filling candidate properties if (fillOnlySignal) {