From ef724c30694ad69060e9ade2beaee063e0e7dc3f Mon Sep 17 00:00:00 2001 From: Anton Riedel Date: Wed, 31 Dec 2025 02:23:55 +0100 Subject: [PATCH 1/4] Feat: finish MC for tracks and V0s --- PWGCF/Femto/Core/cascadeHistManager.h | 36 +- PWGCF/Femto/Core/collisionBuilder.h | 8 +- PWGCF/Femto/Core/femtoUtils.h | 2 +- PWGCF/Femto/Core/histManager.h | 7 + PWGCF/Femto/Core/kinkHistManager.h | 28 +- PWGCF/Femto/Core/mcBuilder.h | 252 ++++++++++-- PWGCF/Femto/Core/trackBuilder.h | 20 +- PWGCF/Femto/Core/trackHistManager.h | 121 +++--- .../Femto/Core/twoTrackResonanceHistManager.h | 24 +- PWGCF/Femto/Core/v0Builder.h | 79 +++- PWGCF/Femto/Core/v0HistManager.h | 368 +++++++++++++++--- PWGCF/Femto/DataModel/FemtoTables.h | 10 + PWGCF/Femto/TableProducer/femtoProducer.cxx | 96 +++-- PWGCF/Femto/Tasks/femtoKinkQa.cxx | 9 +- PWGCF/Femto/Tasks/femtoTrackQa.cxx | 10 +- PWGCF/Femto/Tasks/femtoV0Qa.cxx | 93 ++++- 16 files changed, 907 insertions(+), 256 deletions(-) diff --git a/PWGCF/Femto/Core/cascadeHistManager.h b/PWGCF/Femto/Core/cascadeHistManager.h index 9861a15cfd9..05de039359f 100644 --- a/PWGCF/Femto/Core/cascadeHistManager.h +++ b/PWGCF/Femto/Core/cascadeHistManager.h @@ -157,6 +157,8 @@ constexpr char PrefixLambdaCascade[] = "LambdaCascadeQa/"; constexpr std::string_view AnalysisDir = "Kinematics/"; constexpr std::string_view QaDir = "QA/"; +constexpr int AbsChargeDaughters = 1; + /// \class FemtoDreamEventHisto /// \brief Class for histogramming event properties // template @@ -179,9 +181,9 @@ class CascadeHistManager std::map> const& NegDauSpecs) { mHistogramRegistry = registry; - mBachelorManager.template init(registry, BachelorSpecs); - mPosDauManager.template init(registry, PosDauSpecs); - mNegDauManager.template init(registry, NegDauSpecs); + mBachelorManager.template init(registry, BachelorSpecs, AbsChargeDaughters); + mPosDauManager.template init(registry, PosDauSpecs, AbsChargeDaughters); + mNegDauManager.template init(registry, NegDauSpecs, AbsChargeDaughters); if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { initAnalysis(cascadeSpecs); } @@ -190,15 +192,6 @@ class CascadeHistManager } } - template - void enableOptionalHistograms(T1 const& CascadeConfBinningQa, T2 const& BachelorConfBinningQa, T3 const& PosDauConfBinningQa, T4 const& NegDauConfBinningQa) - { - mBachelorManager.enableOptionalHistograms(BachelorConfBinningQa); - mPosDauManager.enableOptionalHistograms(PosDauConfBinningQa); - mNegDauManager.enableOptionalHistograms(NegDauConfBinningQa); - mPlot2d = CascadeConfBinningQa.plot2d.value; - } - template void init(o2::framework::HistogramRegistry* registry, std::map> const& cascadeSpecs, @@ -210,8 +203,17 @@ class CascadeHistManager std::map> const& NegDauSpecs, T4 const& NegDauConfBinningQa) { - enableOptionalHistograms(CascadeConfBinningQa, BachelorConfBinningQa, PosDauConfBinningQa, NegDauConfBinningQa); - this->template init(registry, cascadeSpecs, BachelorSpecs, PosDauSpecs, NegDauSpecs); + mHistogramRegistry = registry; + mBachelorManager.template init(registry, BachelorSpecs, BachelorConfBinningQa, AbsChargeDaughters); + mPosDauManager.template init(registry, PosDauSpecs, PosDauConfBinningQa, AbsChargeDaughters); + mNegDauManager.template init(registry, NegDauSpecs, NegDauConfBinningQa, AbsChargeDaughters); + this->enableOptionalHistograms(CascadeConfBinningQa); + if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { + initAnalysis(cascadeSpecs); + } + if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { + initQa(cascadeSpecs); + } } template @@ -237,6 +239,12 @@ class CascadeHistManager } private: + template + void enableOptionalHistograms(T const& CascadeConfBinningQa) + { + mPlot2d = CascadeConfBinningQa.plot2d.value; + } + void initAnalysis(std::map> const& cascadeSpecs) { std::string analysisDir = std::string(cascadePrefix) + std::string(AnalysisDir); diff --git a/PWGCF/Femto/Core/collisionBuilder.h b/PWGCF/Femto/Core/collisionBuilder.h index 60d47f14e5f..aef859c5163 100644 --- a/PWGCF/Femto/Core/collisionBuilder.h +++ b/PWGCF/Femto/Core/collisionBuilder.h @@ -87,7 +87,7 @@ struct ConfCollisionBits : o2::framework::ConfigurableGroup { struct ConfCcdb : o2::framework::ConfigurableGroup { std::string prefix = std::string("ConfCcdb"); o2::framework::Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "URL to ccdb"}; - o2::framework::Configurable grpPath{"grpPath", "GLO/Config/GRPMagField", "Path to GRP object (Run3 -> GLO/Config/GRPMagField/Run2 -> GLO/GRP/GRP"}; + o2::framework::Configurable grpPath{"grpPath", "GLO/Config/GRPMagField", "Path to GRP object (Run3 -> GLO/Config/GRPMagField, Run2 -> GLO/GRP/GRP"}; o2::framework::Configurable triggerPath{"triggerPath", "EventFiltering/Zorro/", "CCDB path for trigger information"}; }; @@ -525,11 +525,7 @@ class CollisionBuilder mcBuilder.template fillMcCollisionWithLabel(mcProducts, col, mcCols); } - void - reset() - { - mCollisionAlreadyFilled = false; - } + void reset() { mCollisionAlreadyFilled = false; } private: CollisionSelection mCollisionSelection; diff --git a/PWGCF/Femto/Core/femtoUtils.h b/PWGCF/Femto/Core/femtoUtils.h index a9d4d5b2b25..abd53f2bc75 100644 --- a/PWGCF/Femto/Core/femtoUtils.h +++ b/PWGCF/Femto/Core/femtoUtils.h @@ -210,7 +210,7 @@ using HasSign = decltype(std::declval().sign()); template inline int signum(T x) { - return (T(0) < x) - (x < T(0)); // works for floats too + return (T(0) < x) - (x < T(0)); } }; // namespace utils diff --git a/PWGCF/Femto/Core/histManager.h b/PWGCF/Femto/Core/histManager.h index 55630d1bb75..19b1b0ce502 100644 --- a/PWGCF/Femto/Core/histManager.h +++ b/PWGCF/Femto/Core/histManager.h @@ -26,6 +26,13 @@ namespace o2::analysis::femto namespace histmanager { +// plot level for secondaries during mc processing +enum SecondaryPlotLevel { + kSecondaryPlotLevel1 = 1, + kSecondaryPlotLevel2 = 2, + kSecondaryPlotLevel3 = 3 +}; + template struct HistInfo { Hist hist; diff --git a/PWGCF/Femto/Core/kinkHistManager.h b/PWGCF/Femto/Core/kinkHistManager.h index 6d777ed6a9a..efec80ffaac 100644 --- a/PWGCF/Femto/Core/kinkHistManager.h +++ b/PWGCF/Femto/Core/kinkHistManager.h @@ -171,6 +171,8 @@ constexpr char PrefixSigmaPlus2[] = "SigmaPlus2/"; constexpr std::string_view AnalysisDir = "Kinematics/"; constexpr std::string_view QaDir = "QA/"; +constexpr int AbsChargeDaughters = 1; + /// \class KinkHistManager /// \brief Class for histogramming event properties // template @@ -189,7 +191,7 @@ class KinkHistManager std::map> const& ChaDauSpecs) { mHistogramRegistry = registry; - mChaDauManager.template init(registry, ChaDauSpecs); + mChaDauManager.template init(registry, ChaDauSpecs, AbsChargeDaughters); if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { initAnalysis(KinkSpecs); } @@ -198,13 +200,6 @@ class KinkHistManager } } - template - void enableOptionalHistograms(T1 const& KinkConfBinningQa, T2 const& ChaDauConfBinningQa) - { - mChaDauManager.enableOptionalHistograms(ChaDauConfBinningQa); - mPlot2d = KinkConfBinningQa.plot2d.value; - } - template void init(o2::framework::HistogramRegistry* registry, std::map> const& KinkSpecs, @@ -212,8 +207,15 @@ class KinkHistManager std::map> const& ChaDauSpecs, T2 const& ChaDauConfBinningQa) { - enableOptionalHistograms(KinkConfBinningQa, ChaDauConfBinningQa); - this->template init(registry, KinkSpecs, ChaDauSpecs); + mHistogramRegistry = registry; + mChaDauManager.template init(registry, ChaDauSpecs, ChaDauConfBinningQa, AbsChargeDaughters); + this->enableOptionalHistograms(KinkConfBinningQa); + if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { + initAnalysis(KinkSpecs); + } + if constexpr (isFlagSet(mode, modes::Mode::kQa)) { + initQa(KinkSpecs); + } } template @@ -232,6 +234,12 @@ class KinkHistManager } private: + template + void enableOptionalHistograms(T1 const& KinkConfBinningQa) + { + mPlot2d = KinkConfBinningQa.plot2d.value; + } + void initAnalysis(std::map> const& KinkSpecs) { std::string analysisDir = std::string(kinkPrefix) + std::string(AnalysisDir); diff --git a/PWGCF/Femto/Core/mcBuilder.h b/PWGCF/Femto/Core/mcBuilder.h index 2a687ef3943..a872f45de00 100644 --- a/PWGCF/Femto/Core/mcBuilder.h +++ b/PWGCF/Femto/Core/mcBuilder.h @@ -21,7 +21,6 @@ #include "PWGCF/Femto/Core/modes.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "CommonConstants/MathConstants.h" #include "Framework/AnalysisHelpers.h" #include "Framework/Configurable.h" @@ -51,6 +50,8 @@ struct McBuilderProducts : o2::framework::ProducesGroup { o2::framework::Produces producedCollisionLabels; o2::framework::Produces producedTrackLabels; + o2::framework::Produces producedLambdaLabels; + o2::framework::Produces producedK0shortLabels; }; struct ConfMcTables : o2::framework::ConfigurableGroup { @@ -61,7 +62,9 @@ struct ConfMcTables : o2::framework::ConfigurableGroup { o2::framework::Configurable produceMcPartonicMothers{"produceMcPartonicMothers", -1, "Produce MC partonic mother particles (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable producedCollisionLabels{"producedCollisionLabels", -1, "Produce MC partonic mother particles (-1: auto; 0 off; 1 on)"}; - o2::framework::Configurable producedTrackLabels{"producedTrackLabels", -1, "Produce MC partonic mother particles (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable producedTrackLabels{"producedTrackLabels", -1, "Produce track labels (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable producedLambdaLabels{"producedLambdaLabels", -1, "Produce lambda labels (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable producedK0shortLabels{"producedK0shortLabels", -1, "Produce k0short labels (-1: auto; 0 off; 1 on)"}; }; class McBuilder @@ -82,8 +85,10 @@ class McBuilder mProduceCollisionLabels = utils::enableTable("FColLabels", table.producedCollisionLabels.value, initContext); mProduceTrackLabels = utils::enableTable("FTrackLabels", table.producedTrackLabels.value, initContext); + mProduceLambdaLabels = utils::enableTable("FLambdaLabels", table.producedTrackLabels.value, initContext); + mProduceK0shortLabels = utils::enableTable("FK0shortLabels", table.producedTrackLabels.value, initContext); - if (mProduceMcCollisions || mProduceMcParticles || mProduceMcMothers || mProduceMcPartonicMothers || mProduceCollisionLabels || mProduceTrackLabels) { + if (mProduceMcCollisions || mProduceMcParticles || mProduceMcMothers || mProduceMcPartonicMothers || mProduceCollisionLabels || mProduceTrackLabels || mProduceLambdaLabels || mProduceK0shortLabels) { mFillAnyTable = true; } else { LOG(info) << "No tables configured..."; @@ -106,7 +111,7 @@ class McBuilder template void fillMcCollisionWithLabel(T1& mcProducts, T2 const& col, T3 const& /*mcCols*/) { - if (!mFillAnyTable) { + if (!mProduceCollisionLabels) { return; } // Case: This reconstructed collision has an MC collision @@ -132,25 +137,20 @@ class McBuilder modes::McOrigin getOrigin(T1 const& col, T2 const& /*mcCols*/, T3 const& mcParticle) { // constants - // const int producedDuringTransport = -1; - // const int producedByDecay = 4; - // const int producedByInelaticHadronicScattering = 4; + const int producedByDecay = 4; // check if reconstructed collision has a generated collision if (col.has_mcCollision()) { - // now check collision ids, if they not match, then the track does belong to the wrong collision + // now check collision ids, if they do not match, then the track belongs to another collision if (col.mcCollisionId() != mcParticle.mcCollisionId()) { return modes::McOrigin::kFromWrongCollision; } if (mcParticle.isPhysicalPrimary()) { return modes::McOrigin::kPhysicalPrimary; - // } else if ((mcParticle.getProcess() == producedByDecay) && (mcParticle.getGenStatusCode() == producedDuringTransport) && mcParticle.has_mothers()) { - } else if (mcParticle.has_mothers()) { + } else if (mcParticle.has_mothers() && mcParticle.getProcess() == producedByDecay) { return modes::McOrigin::kFromSecondaryDecay; - // } else if ((mcParticle.getProcess() == producedByInelaticHadronicScattering) && (mcParticle.getGenStatusCode() == producedDuringTransport) && mcParticle.has_mothers()) { } else { + // not a primary and not from a decay, we label as material return modes::McOrigin::kFromMaterial; - // } else { - // return modes::McOrigin::kFromUnkown; } } return modes::McOrigin::kFromWrongCollision; @@ -170,10 +170,10 @@ class McBuilder return it->second; } - template + template void fillMcTrackWithLabel(T1 const& col, T2 const& mcCols, T3 const& track, T4 const& mcParticles, T5& mcProducts) { - if (!mFillAnyTable) { + if (!mProduceTrackLabels) { return; } @@ -191,8 +191,8 @@ class McBuilder int64_t mcParticleRow = -1; // MC PARTICLE - auto itP = mMcTrackToMcParticleMap.find(particleIndex); - if (itP != mMcTrackToMcParticleMap.end()) { + auto itP = mTrackToMcParticleMap.find(particleIndex); + if (itP != mTrackToMcParticleMap.end()) { mcParticleRow = itP->second; } else { auto origin = this->getOrigin(col, mcCols, mcParticle); @@ -207,14 +207,14 @@ class McBuilder mcParticle.phi()); mcParticleRow = mcProducts.producedMcParticles.lastIndex(); - mMcTrackToMcParticleMap[particleIndex] = mcParticleRow; + mTrackToMcParticleMap[particleIndex] = mcParticleRow; } - // MOTHERS (fill only if exists) + // mothers (fill only if exists) int64_t mothersRow = -1; - auto itM = mMcTrackToMcMotherMap.find(trackIndex); + auto itM = mTrackToMcMotherMap.find(trackIndex); - if (itM != mMcTrackToMcMotherMap.end()) { + if (itM != mTrackToMcMotherMap.end()) { mothersRow = itM->second; } else { @@ -226,15 +226,15 @@ class McBuilder mcProducts.producedMothers(motherPdg); mothersRow = mcProducts.producedMothers.lastIndex(); - mMcTrackToMcMotherMap[trackIndex] = mothersRow; + mTrackToMcMotherMap[trackIndex] = mothersRow; } } - // PARTONIC MOTHER (fill only if exists) + // partonic mother (fill only if exists) int64_t partonicRow = -1; - auto itPM = mMcTrackToMcPartonicMap.find(trackIndex); + auto itPM = mTrackToMcPartonicMap.find(trackIndex); - if (itPM != mMcTrackToMcPartonicMap.end()) { + if (itPM != mTrackToMcPartonicMap.end()) { partonicRow = itPM->second; } else { int partIdx = -1; @@ -249,11 +249,179 @@ class McBuilder mcProducts.producedPartonicMothers(partonicPdg); partonicRow = mcProducts.producedPartonicMothers.lastIndex(); - mMcTrackToMcPartonicMap[trackIndex] = partonicRow; + mTrackToMcPartonicMap[trackIndex] = partonicRow; } } + mcProducts.producedTrackLabels(mcParticleRow, mothersRow, partonicRow); + } + + template + void fillMcLambdaWithLabel(T1 const& col, T2 const& mcCols, T3 const& lambda, T4 const& mcParticles, T5& mcProducts) + { + if (!mProduceLambdaLabels) { + return; + } + + if (!lambda.has_mcParticle()) { + mcProducts.producedLambdaLabels(-1, -1, -1); + return; + } + + auto mcParticle = lambda.template mcParticle_as(); + auto mcCol = mcParticle.template mcCollision_as(); + + int64_t particleIndex = mcParticle.globalIndex(); + int64_t lambdaIndex = lambda.globalIndex(); + + int64_t mcParticleRow = -1; + + // MC PARTICLE + auto itP = mLambdaToMcParticleMap.find(particleIndex); + if (itP != mLambdaToMcParticleMap.end()) { + mcParticleRow = itP->second; + } else { + auto origin = this->getOrigin(col, mcCols, mcParticle); + int64_t mcColId = this->getMcColId(mcCol, mcProducts); + + mcProducts.producedMcParticles( + mcColId, + static_cast(origin), + mcParticle.pdgCode(), + mcParticle.pt() * utils::signum(mcParticle.pdgCode()), + mcParticle.eta(), + mcParticle.phi()); + + mcParticleRow = mcProducts.producedMcParticles.lastIndex(); + mLambdaToMcParticleMap[particleIndex] = mcParticleRow; + } + + // mothers (fill only if exists) + int64_t mothersRow = -1; + auto itM = mLambdaToMcMotherMap.find(lambdaIndex); - // FINAL LABELS + if (itM != mLambdaToMcMotherMap.end()) { + mothersRow = itM->second; + } else { + + auto mothers = mcParticle.template mothers_as(); + bool motherExists = mcParticle.has_mothers() && !mothers.empty(); + + if (motherExists) { + int motherPdg = mothers.front().pdgCode(); // PDG code is ALWAYS valid if the mother exists + + mcProducts.producedMothers(motherPdg); + mothersRow = mcProducts.producedMothers.lastIndex(); + mLambdaToMcMotherMap[lambdaIndex] = mothersRow; + } + } + + // partonic mother (fill only if exists) + int64_t partonicRow = -1; + auto itPM = mLambdaToMcPartonicMap.find(lambdaIndex); + + if (itPM != mLambdaToMcPartonicMap.end()) { + partonicRow = itPM->second; + } else { + int partIdx = -1; + if (mcParticle.has_mothers()) { + partIdx = this->findFirstPartonicMother(mcParticle, mcParticles); + } + + bool partonicExists = (partIdx >= 0); + + if (partonicExists) { + int partonicPdg = mcParticles.iteratorAt(partIdx).pdgCode(); + + mcProducts.producedPartonicMothers(partonicPdg); + partonicRow = mcProducts.producedPartonicMothers.lastIndex(); + mLambdaToMcPartonicMap[lambdaIndex] = partonicRow; + } + } + mcProducts.producedLambdaLabels(mcParticleRow, mothersRow, partonicRow); + } + + template + void fillMcK0shortWithLabel(T1 const& col, T2 const& mcCols, T3 const& k0short, T4 const& mcParticles, T5& mcProducts) + { + if (!mProduceK0shortLabels) { + return; + } + + if (!k0short.has_mcParticle()) { + mcProducts.producedK0shortLabels(-1, -1, -1); + return; + } + + auto mcParticle = k0short.template mcParticle_as(); + auto mcCol = mcParticle.template mcCollision_as(); + + int64_t particleIndex = mcParticle.globalIndex(); + int64_t k0shortIndex = k0short.globalIndex(); + + int64_t mcParticleRow = -1; + + // MC PARTICLE + auto itP = mK0shortToMcParticleMap.find(particleIndex); + if (itP != mK0shortToMcParticleMap.end()) { + mcParticleRow = itP->second; + } else { + auto origin = this->getOrigin(col, mcCols, mcParticle); + int64_t mcColId = this->getMcColId(mcCol, mcProducts); + + mcProducts.producedMcParticles( + mcColId, + static_cast(origin), + mcParticle.pdgCode(), + mcParticle.pt(), + mcParticle.eta(), + mcParticle.phi()); + + mcParticleRow = mcProducts.producedMcParticles.lastIndex(); + mK0shortToMcParticleMap[particleIndex] = mcParticleRow; + } + + // mothers (fill only if exists) + int64_t mothersRow = -1; + auto itM = mK0shortToMcMotherMap.find(k0shortIndex); + + if (itM != mK0shortToMcMotherMap.end()) { + mothersRow = itM->second; + } else { + + auto mothers = mcParticle.template mothers_as(); + bool motherExists = mcParticle.has_mothers() && !mothers.empty(); + + if (motherExists) { + int motherPdg = mothers.front().pdgCode(); // PDG code is ALWAYS valid if the mother exists + + mcProducts.producedMothers(motherPdg); + mothersRow = mcProducts.producedMothers.lastIndex(); + mK0shortToMcMotherMap[k0shortIndex] = mothersRow; + } + } + + // partonic mother (fill only if exists) + int64_t partonicRow = -1; + auto itPM = mK0shortToMcPartonicMap.find(k0shortIndex); + + if (itPM != mK0shortToMcPartonicMap.end()) { + partonicRow = itPM->second; + } else { + int partIdx = -1; + if (mcParticle.has_mothers()) { + partIdx = this->findFirstPartonicMother(mcParticle, mcParticles); + } + + bool partonicExists = (partIdx >= 0); + + if (partonicExists) { + int partonicPdg = mcParticles.iteratorAt(partIdx).pdgCode(); + + mcProducts.producedPartonicMothers(partonicPdg); + partonicRow = mcProducts.producedPartonicMothers.lastIndex(); + mK0shortToMcPartonicMap[k0shortIndex] = partonicRow; + } + } mcProducts.producedTrackLabels(mcParticleRow, mothersRow, partonicRow); } @@ -309,11 +477,17 @@ class McBuilder { mCollisionMap.clear(); - mMcTrackToMcParticleMap.clear(); - mMcTrackToMcMotherMap.clear(); - mMcTrackToMcPartonicMap.clear(); + mTrackToMcParticleMap.clear(); + mTrackToMcMotherMap.clear(); + mTrackToMcPartonicMap.clear(); - mV0Map.clear(); + mLambdaToMcParticleMap.clear(); + mLambdaToMcMotherMap.clear(); + mLambdaToMcPartonicMap.clear(); + + mK0shortToMcParticleMap.clear(); + mK0shortToMcMotherMap.clear(); + mK0shortToMcPartonicMap.clear(); } private: @@ -326,14 +500,22 @@ class McBuilder bool mProduceCollisionLabels = false; bool mProduceTrackLabels = false; + bool mProduceLambdaLabels = false; + bool mProduceK0shortLabels = false; std::unordered_map mCollisionMap; - std::unordered_map mMcTrackToMcParticleMap; - std::unordered_map mMcTrackToMcMotherMap; - std::unordered_map mMcTrackToMcPartonicMap; + std::unordered_map mTrackToMcParticleMap; + std::unordered_map mTrackToMcMotherMap; + std::unordered_map mTrackToMcPartonicMap; + + std::unordered_map mLambdaToMcParticleMap; + std::unordered_map mLambdaToMcMotherMap; + std::unordered_map mLambdaToMcPartonicMap; - std::unordered_map mV0Map; + std::unordered_map mK0shortToMcParticleMap; + std::unordered_map mK0shortToMcMotherMap; + std::unordered_map mK0shortToMcPartonicMap; }; } // namespace mcbuilder diff --git a/PWGCF/Femto/Core/trackBuilder.h b/PWGCF/Femto/Core/trackBuilder.h index b1c04aaf172..4316a993bcd 100644 --- a/PWGCF/Femto/Core/trackBuilder.h +++ b/PWGCF/Femto/Core/trackBuilder.h @@ -685,6 +685,7 @@ class TrackBuilder } collisionBuilder.template fillMcCollision(collisionProducts, col, mcCols, mcProducts, mcBuilder); + // get track from the track table so we can dereference mc particle properly auto track = tracks.iteratorAt(trackWithItsPid.index()); this->template fillMcTrack(col, collisionProducts, mcCols, track, trackWithItsPid, trackProducts, mcParticles, mcBuilder, mcProducts); } @@ -693,11 +694,11 @@ class TrackBuilder template void fillMcTrack(T1 const& col, T2& collisionProducts, T3 const& mcCols, T4 const& track, T5 const& trackWithItsPid, T6& trackProducts, T7 const& mcParticles, T8& mcBuilder, T9& mcProducts) { - if (!mFillAnyTable) { + if (!mProduceTracks) { return; } this->template fillTrack(trackWithItsPid, trackProducts, collisionProducts); - mcBuilder.template fillMcTrackWithLabel(col, mcCols, track, mcParticles, mcProducts); + mcBuilder.template fillMcTrackWithLabel(col, mcCols, track, mcParticles, mcProducts); } template @@ -709,11 +710,24 @@ class TrackBuilder } else { this->fillTrack(daughter, trackProducts, collisionProducts); int64_t idx = trackProducts.producedTracks.lastIndex(); - indexMap.emplace(daughter.globalIndex(), idx); return idx; } } + template + int64_t getDaughterIndex(const T1& col, T2& collisionProducts, T3 const& mcCols, const T4& daughter, T5& daughterWithItsPid, T6& trackProducts, T7 const& mcParticles, T8& mcBuilder, T9& mcProducts) + { + auto result = utils::getIndex(daughter.globalIndex(), indexMap); + if (result) { + // daugher already in track table + return result.value(); + } else { + this->fillMcTrack(col, collisionProducts, mcCols, daughter, daughterWithItsPid, trackProducts, mcParticles, mcBuilder, mcProducts); + // daughter is last track which was added added + return trackProducts.producedTracks.lastIndex(); + } + } + private: TrackSelection mTrackSelection; bool mFillAnyTable = false; diff --git a/PWGCF/Femto/Core/trackHistManager.h b/PWGCF/Femto/Core/trackHistManager.h index 80f6f431cb3..27352a15689 100644 --- a/PWGCF/Femto/Core/trackHistManager.h +++ b/PWGCF/Femto/Core/trackHistManager.h @@ -123,6 +123,7 @@ enum TrackHist { kTrueEta, kTruePhi, // histograms for fraction estimation of tracks + kNoMcParticle, kPrimary, kFromWrongCollision, kFromMaterial, @@ -134,12 +135,6 @@ enum TrackHist { kTrackHistLast }; -enum SecondaryPlotLevel { - kSecondaryPlotLevel1 = 1, - kSecondaryPlotLevel2 = 2, - kSecondaryPlotLevel3 = 3 -}; - constexpr std::size_t MaxSecondary = 3; template @@ -272,8 +267,12 @@ struct ConfTrackMcBinning : o2::framework::ConfigurableGroup { }; constexpr const char PrefixTrackMcBinning1[] = "TrackMcBinning1"; +constexpr const char PrefixV0PosDauMcBinning[] = "V0PosDauMcBinning"; +constexpr const char PrefixV0NegDauMcBinning[] = "V0NegDauMcBinning"; using ConfTrackMcBinning1 = ConfTrackMcBinning; +using ConfV0PosDauMcBinning = ConfTrackMcBinning; +using ConfV0NegDauMcBinning = ConfTrackMcBinning; // must be in sync with enum TrackVariables // the enum gives the correct index in the array @@ -353,7 +352,7 @@ constexpr std::array, kTrackHistLast> {kTruePt, o2::framework::kTH1F, "hTruePt", "True transverse momentum; p_{T} (GeV/#it{c}); Entries"}, {kTrueEta, o2::framework::kTH1F, "hTrueEta", "True pseudorapdity; #eta; Entries"}, {kTruePhi, o2::framework::kTH1F, "hTruePhi", "True azimuthal angle; #varphi; Entries"}, - + {kNoMcParticle, o2::framework::kTHnSparseF, "hNoMcParticle", "Wrongly reconstructed particles; p_{T} (GeV/#it{c}); DCA_{xy} (cm); DCA_{z} (cm)"}, {kPrimary, o2::framework::kTHnSparseF, "hPrimary", "Primary particles; p_{T} (GeV/#it{c}); DCA_{xy} (cm); DCA_{z} (cm)"}, {kFromWrongCollision, o2::framework::kTHnSparseF, "hFromWrongCollision", "Particles associated to wrong collision; p_{T} (GeV/#it{c}); DCA_{xy} (cm); DCA_{z} (cm)"}, {kFromMaterial, o2::framework::kTHnSparseF, "hFromMaterial", "Particles from material; p_{T} (GeV/#it{c}); DCA_{xy} (cm); DCA_{z} (cm)"}, @@ -441,6 +440,7 @@ constexpr std::array, kTrackHistLast> {kPdg, {confMc.pdgCodes}}, \ {kPdgMother, {confMc.pdgCodes}}, \ {kPdgPartonicMother, {confMc.pdgCodes}}, \ + {kNoMcParticle, {confMc.pt, confMc.dcaXy, confMc.dcaZ}}, \ {kPrimary, {confMc.pt, confMc.dcaXy, confMc.dcaZ}}, \ {kFromWrongCollision, {confMc.pt, confMc.dcaXy, confMc.dcaZ}}, \ {kFromMaterial, {confMc.pt, confMc.dcaXy, confMc.dcaZ}}, \ @@ -516,8 +516,9 @@ class TrackHistManager TrackHistManager() = default; ~TrackHistManager() = default; + // init for analysis template - void init(o2::framework::HistogramRegistry* registry, std::map> const& Specs, int AbsCharge = 1) + void init(o2::framework::HistogramRegistry* registry, std::map> const& Specs, int AbsCharge) { mHistogramRegistry = registry; mAbsCharge = std::abs(AbsCharge); @@ -532,49 +533,7 @@ class TrackHistManager } } - // for qa alone - template - void enableOptionalHistograms(T const& ConfBinningQa) - { - mPlot2d = ConfBinningQa.plot2d.value; - mPlotElectronPid = ConfBinningQa.plotElectronPid.value; - mPlotPionPid = ConfBinningQa.plotPionPid.value; - mPlotKaonPid = ConfBinningQa.plotKaonPid.value; - mPlotProtonPid = ConfBinningQa.plotProtonPid.value; - mPlotDeuteronPid = ConfBinningQa.plotDeuteronPid.value; - mPlotTritonPid = ConfBinningQa.plotTritonPid.value; - mPlotHeliumPid = ConfBinningQa.plotHeliumPid.value; - mMomentumType = static_cast(ConfBinningQa.momentumType.value); - } - - // for qa + mc - template - void enableOptionalHistograms(T1 const& ConfBinningQa, T2 const& ConfBinningMc) - { - mPlot2d = ConfBinningQa.plot2d.value; - mPlotElectronPid = ConfBinningQa.plotElectronPid.value; - mPlotPionPid = ConfBinningQa.plotPionPid.value; - mPlotKaonPid = ConfBinningQa.plotKaonPid.value; - mPlotProtonPid = ConfBinningQa.plotProtonPid.value; - mPlotDeuteronPid = ConfBinningQa.plotDeuteronPid.value; - mPlotTritonPid = ConfBinningQa.plotTritonPid.value; - mPlotHeliumPid = ConfBinningQa.plotHeliumPid.value; - mMomentumType = static_cast(ConfBinningQa.momentumType.value); - - mPlotOrigins = ConfBinningMc.plotOrigins.value; - mPlotNSecondaries = ConfBinningMc.pdgCodesForMothersOfSecondary.value.size(); - - for (std::size_t i = 0; i < MaxSecondary; i++) { - if (i < ConfBinningMc.pdgCodesForMothersOfSecondary.value.size()) { - mPdgCodesSecondaryMother.at(i) = std::abs(ConfBinningMc.pdgCodesForMothersOfSecondary.value.at(i)); - } else { - mPdgCodesSecondaryMother.at(i) = 0; - } - } - } - - // special init function for Qa - // passing config group for qa so we can optionally enable histograms via flags + // init for analysis and qa template void init(o2::framework::HistogramRegistry* registry, std::map> const& Specs, T const& ConfBinningQa, int AbsCharge) { @@ -582,8 +541,7 @@ class TrackHistManager this->template init(registry, Specs, AbsCharge); } - // special init function for Qa + Mc - // passing config group for qa + mc so we can optionally enable histograms via flags + // init for analysis and mc and qa template void init(o2::framework::HistogramRegistry* registry, std::map> const& Specs, T1 const& ConfBinningQa, T2 const& ConfBinningMc, int AbsCharge) { @@ -617,6 +575,39 @@ class TrackHistManager } private: + // enable additional qa histograms + template + void enableOptionalHistograms(T const& ConfBinningQa) + { + mPlot2d = ConfBinningQa.plot2d.value; + mPlotElectronPid = ConfBinningQa.plotElectronPid.value; + mPlotPionPid = ConfBinningQa.plotPionPid.value; + mPlotKaonPid = ConfBinningQa.plotKaonPid.value; + mPlotProtonPid = ConfBinningQa.plotProtonPid.value; + mPlotDeuteronPid = ConfBinningQa.plotDeuteronPid.value; + mPlotTritonPid = ConfBinningQa.plotTritonPid.value; + mPlotHeliumPid = ConfBinningQa.plotHeliumPid.value; + mMomentumType = static_cast(ConfBinningQa.momentumType.value); + } + + // enable additional qa and mc histograms + template + void enableOptionalHistograms(T1 const& ConfBinningQa, T2 const& ConfBinningMc) + { + this->template enableOptionalHistograms(ConfBinningQa); + + mPlotOrigins = ConfBinningMc.plotOrigins.value; + mPlotNSecondaries = ConfBinningMc.pdgCodesForMothersOfSecondary.value.size(); + + for (std::size_t i = 0; i < MaxSecondary; i++) { + if (i < ConfBinningMc.pdgCodesForMothersOfSecondary.value.size()) { + mPdgCodesSecondaryMother.at(i) = std::abs(ConfBinningMc.pdgCodesForMothersOfSecondary.value.at(i)); + } else { + mPdgCodesSecondaryMother.at(i) = 0; + } + } + } + void initAnalysis(std::map> const& Specs) { std::string analysisDir = std::string(prefix) + std::string(AnalysisDir); @@ -735,17 +726,18 @@ class TrackHistManager mHistogramRegistry->add(mcDir + getHistNameV2(kPdgPartonicMother, HistTable), getHistDesc(kPdgPartonicMother, HistTable), getHistType(kPdgPartonicMother, HistTable), {Specs.at(kPdgPartonicMother)}); if (mPlotOrigins) { + mHistogramRegistry->add(mcDir + getHistNameV2(kNoMcParticle, HistTable), getHistDesc(kNoMcParticle, HistTable), getHistType(kNoMcParticle, HistTable), {Specs.at(kNoMcParticle)}); mHistogramRegistry->add(mcDir + getHistNameV2(kPrimary, HistTable), getHistDesc(kPrimary, HistTable), getHistType(kPrimary, HistTable), {Specs.at(kPrimary)}); mHistogramRegistry->add(mcDir + getHistNameV2(kFromWrongCollision, HistTable), getHistDesc(kFromWrongCollision, HistTable), getHistType(kFromWrongCollision, HistTable), {Specs.at(kFromWrongCollision)}); mHistogramRegistry->add(mcDir + getHistNameV2(kFromMaterial, HistTable), getHistDesc(kFromMaterial, HistTable), getHistType(kFromMaterial, HistTable), {Specs.at(kFromMaterial)}); - if (mPlotNSecondaries >= kSecondaryPlotLevel1) { + if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel1) { mHistogramRegistry->add(mcDir + getHistNameV2(kSecondary1, HistTable), getHistDesc(kSecondary1, HistTable), getHistType(kSecondary1, HistTable), {Specs.at(kSecondary1)}); } - if (mPlotNSecondaries >= kSecondaryPlotLevel2) { + if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel2) { mHistogramRegistry->add(mcDir + getHistNameV2(kSecondary2, HistTable), getHistDesc(kSecondary2, HistTable), getHistType(kSecondary2, HistTable), {Specs.at(kSecondary2)}); } - if (mPlotNSecondaries >= kSecondaryPlotLevel3) { + if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel3) { mHistogramRegistry->add(mcDir + getHistNameV2(kSecondary3, HistTable), getHistDesc(kSecondary3, HistTable), getHistType(kSecondary3, HistTable), {Specs.at(kSecondary3)}); } mHistogramRegistry->add(mcDir + getHistNameV2(kSecondaryOther, HistTable), getHistDesc(kSecondaryOther, HistTable), getHistType(kSecondaryOther, HistTable), {Specs.at(kSecondaryOther)}); @@ -869,12 +861,11 @@ class TrackHistManager { // No MC Particle if (!track.has_fMcParticle()) { - mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + - HIST(getHistName(kPdg, HistTable)), - 0); - mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + - HIST(getHistName(kOrigin, HistTable)), - static_cast(modes::McOrigin::kNoMcParticle)); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kPdg, HistTable)), 0); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kOrigin, HistTable)), static_cast(modes::McOrigin::kNoMcParticle)); + if (mPlotOrigins) { + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kNoMcParticle, HistTable)), track.pt(), track.dcaXY(), track.dcaZ()); + } return; } @@ -919,11 +910,11 @@ class TrackHistManager auto mother = track.template fMcMother_as(); int motherPdgCode = std::abs(mother.pdgCode()); // Switch on PDG of the mother - if (mPlotNSecondaries >= kSecondaryPlotLevel1 && motherPdgCode == mPdgCodesSecondaryMother[0]) { + if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel1 && motherPdgCode == mPdgCodesSecondaryMother[0]) { mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kSecondary1, HistTable)), track.pt(), track.dcaXY(), track.dcaZ()); - } else if (mPlotNSecondaries >= kSecondaryPlotLevel2 && motherPdgCode == mPdgCodesSecondaryMother[1]) { + } else if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel2 && motherPdgCode == mPdgCodesSecondaryMother[1]) { mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kSecondary2, HistTable)), track.pt(), track.dcaXY(), track.dcaZ()); - } else if (mPlotNSecondaries >= kSecondaryPlotLevel3 && motherPdgCode == mPdgCodesSecondaryMother[2]) { + } else if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel3 && motherPdgCode == mPdgCodesSecondaryMother[2]) { mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kSecondary3, HistTable)), track.pt(), track.dcaXY(), track.dcaZ()); } else { mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kSecondaryOther, HistTable)), track.pt(), track.dcaXY(), track.dcaZ()); diff --git a/PWGCF/Femto/Core/twoTrackResonanceHistManager.h b/PWGCF/Femto/Core/twoTrackResonanceHistManager.h index c7ed38b6b37..e9275f15adf 100644 --- a/PWGCF/Femto/Core/twoTrackResonanceHistManager.h +++ b/PWGCF/Femto/Core/twoTrackResonanceHistManager.h @@ -118,6 +118,8 @@ constexpr char PrefixKstar[] = "Kstar0/"; constexpr std::string_view AnalysisDir = "Kinematics/"; constexpr std::string_view QaDir = "QA/"; +constexpr int AbsChargeDaughers = 1; + template > const& NegDauSpecs) { mHistogramRegistry = registry; - mPosDauManager.template init(registry, PosDauSpecs); - mNegDauManager.template init(registry, NegDauSpecs); + mPosDauManager.template init(registry, PosDauSpecs, AbsChargeDaughers); + mNegDauManager.template init(registry, NegDauSpecs, AbsChargeDaughers); if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { initAnalysis(ResoSpecs); } @@ -145,13 +147,6 @@ class TwoTrackResonanceHistManager } } - template - void enableOptionalHistograms(T1 const& PosDauConfBinningQa, T2 const& NegDauConfBinningQa) - { - mPosDauManager.enableOptionalHistograms(PosDauConfBinningQa); - mNegDauManager.enableOptionalHistograms(NegDauConfBinningQa); - } - template void init(o2::framework::HistogramRegistry* registry, std::map> ResoSpecs, @@ -160,8 +155,15 @@ class TwoTrackResonanceHistManager std::map> NegDauSpecs, T2 const& NegDauConfBinningQa) { - enableOptionalHistograms(PosDauConfBinningQa, NegDauConfBinningQa); - this->template init(registry, ResoSpecs, PosDauSpecs, NegDauSpecs); + mHistogramRegistry = registry; + mPosDauManager.template init(registry, PosDauSpecs, PosDauConfBinningQa, AbsChargeDaughers); + mNegDauManager.template init(registry, NegDauSpecs, NegDauConfBinningQa, AbsChargeDaughers); + if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { + initAnalysis(ResoSpecs); + } + if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { + initQa(ResoSpecs); + } } template diff --git a/PWGCF/Femto/Core/v0Builder.h b/PWGCF/Femto/Core/v0Builder.h index e1d4b59120b..8f4b6ff78bc 100644 --- a/PWGCF/Femto/Core/v0Builder.h +++ b/PWGCF/Femto/Core/v0Builder.h @@ -372,7 +372,7 @@ class V0Builder } template - void fillV0s(T1 const& col, T2& collisionBuilder, T3& collisionProducts, T4& trackProducts, T5& v0products, T6 const& v0s, T7 const& tracks, T8 const& tracksWithItsPid, T9& trackBuilder) + void fillV0s(T1 const& col, T2& collisionBuilder, T3& collisionProducts, T4& trackProducts, T5& v0Products, T6 const& v0s, T7 const& tracks, T8 const& tracksWithItsPid, T9& trackBuilder) { if (!mFillAnyTable) { return; @@ -398,19 +398,62 @@ class V0Builder negDaughterIndex = trackBuilder.template getDaughterIndex(negDaughter, trackProducts, collisionProducts); if constexpr (modes::isEqual(v0Type, modes::V0::kLambda)) { - fillLambda(collisionProducts, v0products, v0, 1.f, posDaughterIndex, negDaughterIndex); + fillLambda(collisionProducts, v0Products, v0, 1.f, posDaughterIndex, negDaughterIndex); } if constexpr (modes::isEqual(v0Type, modes::V0::kAntiLambda)) { - fillLambda(collisionProducts, v0products, v0, -1.f, posDaughterIndex, negDaughterIndex); + fillLambda(collisionProducts, v0Products, v0, -1.f, posDaughterIndex, negDaughterIndex); } if constexpr (modes::isEqual(v0Type, modes::V0::kK0short)) { - fillK0short(collisionProducts, v0products, v0, posDaughterIndex, negDaughterIndex); + fillK0short(collisionProducts, v0Products, v0, posDaughterIndex, negDaughterIndex); + } + } + } + + template + void fillMcV0s(T1 const& col, T2& collisionBuilder, T3& collisionProducts, T4 const& mcCols, T5& trackProducts, T6& v0Products, T7 const& v0s, T8 const& tracks, T9 const& tracksWithItsPid, T10& trackBuilder, T11 const& mcParticles, T12& mcBuilder, T13& mcProducts) + { + + if (!mFillAnyTable) { + return; + } + int64_t posDaughterIndex = 0; + int64_t negDaughterIndex = 0; + for (const auto& v0 : v0s) { + if (!mV0Selection.checkFilters(v0)) { + continue; + } + mV0Selection.applySelections(v0, tracks); + if (!mV0Selection.passesAllRequiredSelections()) { + continue; + } + + collisionBuilder.template fillMcCollision(collisionProducts, col, mcCols, mcProducts, mcBuilder); + + auto posDaughter = tracks.iteratorAt(v0.posTrackId() - tracksWithItsPid.offset()); + auto posDaughterWithItsPid = tracksWithItsPid.iteratorAt(v0.posTrackId() - tracksWithItsPid.offset()); + posDaughterIndex = trackBuilder.template getDaughterIndex(col, collisionProducts, mcCols, posDaughter, posDaughterWithItsPid, trackProducts, mcParticles, mcBuilder, mcProducts); + + auto negDaughter = tracks.iteratorAt(v0.negTrackId() - tracksWithItsPid.offset()); + auto negDaughterWithItsPid = tracksWithItsPid.iteratorAt(v0.negTrackId() - tracksWithItsPid.offset()); + negDaughterIndex = trackBuilder.template getDaughterIndex(col, collisionProducts, mcCols, negDaughter, negDaughterWithItsPid, trackProducts, mcParticles, mcBuilder, mcProducts); + + if constexpr (modes::isEqual(v0Type, modes::V0::kLambda)) { + fillLambda(collisionProducts, v0Products, v0, 1.f, posDaughterIndex, negDaughterIndex); + mcBuilder.template fillMcLambdaWithLabel(col, mcCols, v0, mcParticles, mcProducts); + } + if constexpr (modes::isEqual(v0Type, modes::V0::kAntiLambda)) { + fillLambda(collisionProducts, v0Products, v0, -1.f, posDaughterIndex, negDaughterIndex); + mcBuilder.template fillMcLambdaWithLabel(col, mcCols, v0, mcParticles, mcProducts); + } + if constexpr (modes::isEqual(v0Type, modes::V0::kK0short)) { + fillK0short(collisionProducts, v0Products, v0, posDaughterIndex, negDaughterIndex); + mcBuilder.template fillMcK0shortWithLabel(col, mcCols, v0, mcParticles, mcProducts); } } } template - void fillLambda(T1& collisionProducts, T2& v0products, T3 const& v0, float sign, int64_t posDaughterIndex, int64_t negDaughterIndex) + void fillLambda(T1& collisionProducts, T2& v0Products, T3 const& v0, float sign, int64_t posDaughterIndex, int64_t negDaughterIndex) { float mass, massAnti; if (sign > 0.f) { @@ -421,7 +464,7 @@ class V0Builder massAnti = v0.mLambda(); } if (mProduceLambdas) { - v0products.producedLambdas(collisionProducts.producedCollision.lastIndex(), + v0Products.producedLambdas(collisionProducts.producedCollision.lastIndex(), sign * v0.pt(), v0.eta(), v0.phi(), @@ -430,10 +473,10 @@ class V0Builder negDaughterIndex); } if (mProduceLambdaMasks) { - v0products.producedLambdaMasks(mV0Selection.getBitmask()); + v0Products.producedLambdaMasks(mV0Selection.getBitmask()); } if (mProduceLambdaExtras) { - v0products.producedLambdaExtras( + v0Products.producedLambdaExtras( massAnti, v0.mK0Short(), v0.v0cosPA(), @@ -446,10 +489,10 @@ class V0Builder } template - void fillK0short(T1& collisionProducts, T2& v0products, T3 const& v0, int64_t posDaughterIndex, int64_t negDaughterIndex) + void fillK0short(T1& collisionProducts, T2& v0Products, T3 const& v0, int64_t posDaughterIndex, int64_t negDaughterIndex) { if (mProduceK0shorts) { - v0products.producedK0shorts(collisionProducts.producedCollision.lastIndex(), + v0Products.producedK0shorts(collisionProducts.producedCollision.lastIndex(), v0.pt(), v0.eta(), v0.phi(), @@ -458,10 +501,10 @@ class V0Builder negDaughterIndex); } if (mProduceK0shortMasks) { - v0products.producedK0shortMasks(mV0Selection.getBitmask()); + v0Products.producedK0shortMasks(mV0Selection.getBitmask()); } if (mProduceK0shortExtras) { - v0products.producedK0shortExtras( + v0Products.producedK0shortExtras( v0.mLambda(), v0.mAntiLambda(), v0.v0cosPA(), @@ -473,7 +516,17 @@ class V0Builder } } - bool fillAnyTable() { return mFillAnyTable; } + template + void fillMcV0(T1 const& col, T2& collisionProducts, T3 const& mcCols, T4 const& track, T5 const&, T6& v0Products, T7 const& mcParticles, T8& mcBuilder, T9& mcProducts) + { + if (!mFillAnyTable) { + return; + } + this->template fillLambda(); + mcBuilder.template fillMcV0WithLabel(); + } + + bool fillAnyTable() const { return mFillAnyTable; } private: V0Selection mV0Selection; diff --git a/PWGCF/Femto/Core/v0HistManager.h b/PWGCF/Femto/Core/v0HistManager.h index 8cede634209..ca59e6f1f4b 100644 --- a/PWGCF/Femto/Core/v0HistManager.h +++ b/PWGCF/Femto/Core/v0HistManager.h @@ -1,4 +1,4 @@ -// Copyright 2019-2025 CERN and copyright holders of ALICE O2. +// Copyright 2019-2025 CERN andphniticopyright 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. // @@ -65,9 +65,29 @@ enum V0Hist { kLambdaMassVsAntiLambdaMass, kK0shortMassVsLambdaMass, kK0shortMassVsAntiLambdaMass, + // mc + kOrigin, + kPdg, + kPdgMother, + kPdgPartonicMother, + kTruePt, + kTrueEta, + kTruePhi, + // histograms for fraction estimation of v0s + kNoMcParticle, + kPrimary, + kFromWrongCollision, + kFromMaterial, + kSecondary1, + kSecondary2, + kSecondary3, + kSecondaryOther, + kV0HistLast }; +constexpr std::size_t MaxSecondary = 3; + #define V0_DEFAULT_BINNING(defaultMassMin, defaultMassMax) \ o2::framework::ConfigurableAxis pt{"pt", {{600, 0, 6}}, "Pt"}; \ o2::framework::ConfigurableAxis eta{"eta", {{300, -1.5, 1.5}}, "Eta"}; \ @@ -111,6 +131,23 @@ using ConfLambdaQaBinning1 = ConfV0QaBinning; constexpr const char PrefixK0shortQaBinning1[] = "K0shortQaBinning1"; using ConfK0shortQaBinning1 = ConfV0QaBinning; +template +struct ConfV0McBinning : o2::framework::ConfigurableGroup { + std::string prefix = std::string(Prefix); + o2::framework::ConfigurableAxis pdgCodes{"pdgCodes", {{8001, -4000.5, 4000.5}}, "PDG codes of selected V0s"}; + o2::framework::ConfigurableAxis statusCode{"statusCode", {{21, -0.5, 20.5}}, "Status codes (i.e. Origin)"}; + o2::framework::Configurable plotOrigins{"plotOrigins", true, "Plot pt vs cosPa for different particle origins"}; + o2::framework::Configurable> pdgCodesForMothersOfSecondary{"pdgCodesForMothersOfSecondary", {3312, 3334}, "PDG codes of mothers of secondaries (Max 3 will be considered)"}; + o2::framework::ConfigurableAxis pt{"pt", {{150, 0, 3}}, "Pt"}; + o2::framework::ConfigurableAxis cosPa{"cosPa", {{100, 0.8, 1}}, "Cosine pointing angle"}; +}; + +constexpr const char PrefixLambdaMcBinning1[] = "LambdaMcBinning1"; +using ConfLambdaMcBinning1 = ConfV0McBinning; + +constexpr const char PrefixK0shortMcBinning1[] = "K0shortMcBinning1"; +using ConfK0shortMcBinning1 = ConfV0McBinning; + // must be in sync with enum TrackVariables // the enum gives the correct index in the array constexpr std::array, kV0HistLast> HistTable = { @@ -122,7 +159,7 @@ constexpr std::array, kV0HistLast> HistTable = { {kMassLambda, o2::framework::kTH1F, "hMassLambda", "#Lambda mass; m_{p#pi^{-}} (GeV/#it{c}^{2}); Entries"}, {kMassAntiLambda, o2::framework::kTH1F, "hMassAntiLambda", "#bar{#Lambda} mass; m_{#bar{p}#pi^{+}} (GeV/#it{c}^{2}); Entries"}, {kMassK0short, o2::framework::kTH1F, "hMassK0short", "K^{0}_{s} mass; m_{#pi^{+}#pi^{-}} (GeV/#it{c}^{2}); Entries"}, - {kCosPa, o2::framework::kTH1F, "hCosPa", "Cosine of pointing angle; coa(#alpha); Entries"}, + {kCosPa, o2::framework::kTH1F, "hCosPa", "Cosine of pointing angle; cos(#alpha); Entries"}, {kDecayDauDca, o2::framework::kTH1F, "hDauDca", "Daughter DCA at decay vertex ; DCA_{Decay vertex} (cm); Entries"}, {kDecayVtxX, o2::framework::kTH1F, "hDecayVtxX", "X coordinate of decay vertex ; DV_{X} (cm); Entries"}, {kDecayVtxY, o2::framework::kTH1F, "hDecayVtxY", "Y coordinate of decay vertex ; DV_{Y} (cm); Entries"}, @@ -138,49 +175,97 @@ constexpr std::array, kV0HistLast> HistTable = { {kPtVsK0shortMass, o2::framework::kTH2F, "hPtVsK0shortMass", "p_{T} vs K^{0}_{S} mass; p_{T} (GeV/#it{c}); m_{#pi^{+}#pi^{-}} (GeV/#it{c}^{2})"}, {kK0shortMassVsLambdaMass, o2::framework::kTH2F, "hK0shortMassVsLambdaMass", " K^{0}_{S} mass vs #Lambda mass; m_{#pi^{+}#pi^{-}} (GeV/#it{c}^{2}); m_{p#pi^{-}} (GeV/#it{c}^{2})"}, {kK0shortMassVsAntiLambdaMass, o2::framework::kTH2F, "hK0shortMassVsAntiLambdaMass", "K^{0}_{S} mass vs #bar{#Lambda} mass; m_{#pi^{+}#pi^{-}} (GeV/#it{c}^{2}); m_{#bar{p}#pi^{+}} (GeV/#it{c}^{2})"}, - {kLambdaMassVsAntiLambdaMass, o2::framework::kTH2F, "hLambdaMassVsAntiLambdaMass", "#Lambda mass vs #bar{#Lambda}; m_{p#pi^{-}} (GeV/#it{c}^{2}); m_{#bar{p}#pi^{+}} (GeV/#it{c}^{2})"}}}; + {kLambdaMassVsAntiLambdaMass, o2::framework::kTH2F, "hLambdaMassVsAntiLambdaMass", "#Lambda mass vs #bar{#Lambda}; m_{p#pi^{-}} (GeV/#it{c}^{2}); m_{#bar{p}#pi^{+}} (GeV/#it{c}^{2})"}, + {kOrigin, o2::framework::kTH1F, "hOrigin", "Status Codes (=Origin); Status Code; Entries"}, + {kPdg, o2::framework::kTH1F, "hPdg", "PDG Codes of selected tracks; PDG Code; Entries"}, + {kPdgMother, o2::framework::kTH1F, "hPdgMother", "PDG Codes of mother of selected tracks; PDG Code; Entries"}, + {kPdgPartonicMother, o2::framework::kTH1F, "hPdgPartonicMother", "PDG Codes of partonic mother selected tracks; PDG Code; Entries"}, + {kTruePt, o2::framework::kTH1F, "hTruePt", "True transverse momentum; p_{T} (GeV/#it{c}); Entries"}, + {kTrueEta, o2::framework::kTH1F, "hTrueEta", "True pseudorapdity; #eta; Entries"}, + {kTruePhi, o2::framework::kTH1F, "hTruePhi", "True azimuthal angle; #varphi; Entries"}, + {kNoMcParticle, o2::framework::kTH2F, "hNoMcParticle", "Wrongly reconstructed particles; p_{T} (GeV/#it{c}); cos(#alpha)"}, + {kPrimary, o2::framework::kTH2F, "hPrimary", "Primary particles; p_{T} (GeV/#it{c}); cos(#alpha)"}, + {kFromWrongCollision, o2::framework::kTH2F, "hFromWrongCollision", "Particles associated to wrong collision; p_{T} (GeV/#it{c}); cos(#alpha)"}, + {kFromMaterial, o2::framework::kTH2F, "hFromMaterial", "Particles from material; p_{T} (GeV/#it{c}); cos(#alpha)"}, + {kSecondary1, o2::framework::kTH2F, "hFromSecondary1", "Particles from secondary decay; p_{T} (GeV/#it{c}); cos(#alpha)"}, + {kSecondary2, o2::framework::kTH2F, "hFromSecondary2", "Particles from seconary decay; p_{T} (GeV/#it{c}); cos(#alpha)"}, + {kSecondary3, o2::framework::kTH2F, "hFromSecondary3", "Particles from seconary decay; p_{T} (GeV/#it{c}); cos(#alpha)"}, + {kSecondaryOther, o2::framework::kTH2F, "hFromSecondaryOther", "Particles from every other seconary decay; p_{T} (GeV/#it{c}); cos(#alpha)"}}, +}; + +#define V0_HIST_ANALYSIS_MAP(conf) \ + {kPt, {conf.pt}}, \ + {kEta, {conf.eta}}, \ + {kPhi, {conf.phi}}, \ + {kMass, {conf.mass}}, \ + {kSign, {conf.sign}}, + +#define V0_HIST_QA_MAP(confAnalysis, confQa) \ + {kCosPa, {confQa.cosPa}}, \ + {kDecayDauDca, {confQa.dauDcaAtDecay}}, \ + {kDecayVtxX, {confQa.decayVertex}}, \ + {kDecayVtxY, {confQa.decayVertex}}, \ + {kDecayVtxZ, {confQa.decayVertex}}, \ + {kDecayVtx, {confQa.decayVertex}}, \ + {kTransRadius, {confQa.transRadius}}, \ + {kPtVsEta, {confAnalysis.pt, confAnalysis.eta}}, \ + {kPtVsPhi, {confAnalysis.pt, confAnalysis.phi}}, \ + {kPhiVsEta, {confAnalysis.phi, confAnalysis.eta}}, \ + {kPtVsCosPa, {confAnalysis.pt, confQa.cosPa}}, \ + {kMassLambda, {confQa.massLambda}}, \ + {kMassAntiLambda, {confQa.massAntiLambda}}, \ + {kMassK0short, {confQa.massK0short}}, \ + {kPtVsLambdaMass, {confAnalysis.pt, confQa.massLambda}}, \ + {kPtVsAntiLambdaMass, {confAnalysis.pt, confQa.massAntiLambda}}, \ + {kPtVsK0shortMass, {confAnalysis.pt, confQa.massK0short}}, \ + {kLambdaMassVsAntiLambdaMass, {confQa.massLambda, confQa.massAntiLambda}}, \ + {kK0shortMassVsLambdaMass, {confQa.massK0short, confQa.massLambda}}, \ + {kK0shortMassVsAntiLambdaMass, {confQa.massK0short, confQa.massAntiLambda}}, + +#define V0_HIST_MC_MAP(confAnalysis, confMc) \ + {kTruePt, {confAnalysis.pt}}, \ + {kTrueEta, {confAnalysis.eta}}, \ + {kTruePhi, {confAnalysis.phi}}, \ + {kOrigin, {confMc.statusCode}}, \ + {kPdg, {confMc.pdgCodes}}, \ + {kPdgMother, {confMc.pdgCodes}}, \ + {kPdgPartonicMother, {confMc.pdgCodes}}, \ + {kNoMcParticle, {confMc.pt, confMc.cosPa}}, \ + {kPrimary, {confMc.pt, confMc.cosPa}}, \ + {kFromWrongCollision, {confMc.pt, confMc.cosPa}}, \ + {kFromMaterial, {confMc.pt, confMc.cosPa}}, \ + {kSecondary1, {confMc.pt, confMc.cosPa}}, \ + {kSecondary2, {confMc.pt, confMc.cosPa}}, \ + {kSecondary3, {confMc.pt, confMc.cosPa}}, \ + {kSecondaryOther, {confMc.pt, confMc.cosPa}}, template auto makeV0HistSpecMap(const T& confBinningAnalysis) { return std::map>{ - {kPt, {confBinningAnalysis.pt}}, - {kEta, {confBinningAnalysis.eta}}, - {kPhi, {confBinningAnalysis.phi}}, - {kMass, {confBinningAnalysis.mass}}, - {kSign, {confBinningAnalysis.sign}}}; + V0_HIST_ANALYSIS_MAP(confBinningAnalysis)}; } template std::map> makeV0QaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa) { return std::map>{ - {kPt, {confBinningAnalysis.pt}}, - {kEta, {confBinningAnalysis.eta}}, - {kPhi, {confBinningAnalysis.phi}}, - {kMass, {confBinningAnalysis.mass}}, - {kSign, {confBinningAnalysis.sign}}, - {kCosPa, {confBinningQa.cosPa}}, - {kDecayDauDca, {confBinningQa.dauDcaAtDecay}}, - {kDecayVtxX, {confBinningQa.decayVertex}}, - {kDecayVtxY, {confBinningQa.decayVertex}}, - {kDecayVtxZ, {confBinningQa.decayVertex}}, - {kDecayVtx, {confBinningQa.decayVertex}}, - {kTransRadius, {confBinningQa.transRadius}}, - {kPtVsEta, {confBinningAnalysis.pt, confBinningAnalysis.eta}}, - {kPtVsPhi, {confBinningAnalysis.pt, confBinningAnalysis.phi}}, - {kPhiVsEta, {confBinningAnalysis.phi, confBinningAnalysis.eta}}, - {kPtVsCosPa, {confBinningAnalysis.pt, confBinningQa.cosPa}}, - {kMassLambda, {confBinningQa.massLambda}}, - {kMassAntiLambda, {confBinningQa.massAntiLambda}}, - {kMassK0short, {confBinningQa.massK0short}}, - {kPtVsLambdaMass, {confBinningAnalysis.pt, confBinningQa.massLambda}}, - {kPtVsAntiLambdaMass, {confBinningAnalysis.pt, confBinningQa.massAntiLambda}}, - {kPtVsK0shortMass, {confBinningAnalysis.pt, confBinningQa.massK0short}}, - {kLambdaMassVsAntiLambdaMass, {confBinningQa.massLambda, confBinningQa.massAntiLambda}}, - {kK0shortMassVsLambdaMass, {confBinningQa.massK0short, confBinningQa.massLambda}}, - {kK0shortMassVsAntiLambdaMass, {confBinningQa.massK0short, confBinningQa.massAntiLambda}}}; -}; + V0_HIST_ANALYSIS_MAP(confBinningAnalysis) + V0_HIST_QA_MAP(confBinningAnalysis, confBinningQa)}; +} + +template +std::map> makeV0McQaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa, T3 const& confBinningMc) +{ + return std::map>{ + V0_HIST_ANALYSIS_MAP(confBinningAnalysis) + V0_HIST_QA_MAP(confBinningAnalysis, confBinningQa) + V0_HIST_MC_MAP(confBinningAnalysis, confBinningMc)}; +} + +#undef V0_HIST_ANALYSIS_MAP +#undef V0_HIST_QA_MAP +#undef V0_HIST_MC_MAP constexpr char PrefixLambdaQa[] = "LambdaQA/"; constexpr char PrefixLambda1[] = "Lambda1/"; @@ -193,6 +278,9 @@ constexpr char PrefixLambdaCascade[] = "LambdaCascadeQa/"; constexpr std::string_view AnalysisDir = "Kinematics/"; constexpr std::string_view QaDir = "QA/"; +constexpr std::string_view McDir = "MC/"; + +constexpr int AbsChargeDaughters = 1; /// \class FemtoDreamEventHisto /// \brief Class for histogramming event properties @@ -207,6 +295,7 @@ class V0HistManager V0HistManager() = default; ~V0HistManager() = default; + // init for analysis template void init(o2::framework::HistogramRegistry* registry, std::map> const& V0Specs, @@ -214,8 +303,8 @@ class V0HistManager std::map> const& NegDauSpecs) { mHistogramRegistry = registry; - mPosDauManager.template init(registry, PosDauSpecs); - mNegDauManager.template init(registry, NegDauSpecs); + mPosDauManager.template init(registry, PosDauSpecs, AbsChargeDaughters); + mNegDauManager.template init(registry, NegDauSpecs, AbsChargeDaughters); if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { initAnalysis(V0Specs); @@ -223,16 +312,12 @@ class V0HistManager if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { initQa(V0Specs); } + if constexpr (modes::isFlagSet(mode, modes::Mode::kMc)) { + initMc(V0Specs); + } } - template - void enableOptionalHistograms(T1 const& V0ConfBinningQa, T2 const& PosDauConfBinningQa, T3 const& NegDauConfBinningQa) - { - mPosDauManager.enableOptionalHistograms(PosDauConfBinningQa); - mNegDauManager.enableOptionalHistograms(NegDauConfBinningQa); - mPlot2d = V0ConfBinningQa.plot2d.value; - } - + // init for qa template void init(o2::framework::HistogramRegistry* registry, std::map> const& V0Specs, @@ -242,8 +327,49 @@ class V0HistManager std::map> const& NegDauSpecs, T3 const& NegDauConfBinningQa) { - enableOptionalHistograms(V0ConfBinningQa, PosDauConfBinningQa, NegDauConfBinningQa); - this->template init(registry, V0Specs, PosDauSpecs, NegDauSpecs); + mHistogramRegistry = registry; + mPosDauManager.template init(registry, PosDauSpecs, PosDauConfBinningQa, AbsChargeDaughters); + mNegDauManager.template init(registry, NegDauSpecs, NegDauConfBinningQa, AbsChargeDaughters); + this->enableOptionalHistograms(V0ConfBinningQa); + + if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { + initAnalysis(V0Specs); + } + if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { + initQa(V0Specs); + } + if constexpr (modes::isFlagSet(mode, modes::Mode::kMc)) { + initMc(V0Specs); + } + } + + // init for qa + mc + template + void init(o2::framework::HistogramRegistry* registry, + std::map> const& V0Specs, + T1 const& V0ConfBinningQa, + T2 const& V0ConfBinningMc, + std::map> const& PosDauSpecs, + T3 const& PosDauConfBinningQa, + T4 const& PosDauConfBinningMc, + std::map> const& NegDauSpecs, + T5 const& NegDauConfBinningQa, + T6 const& NegDauConfBinningMc) + { + mHistogramRegistry = registry; + mPosDauManager.template init(registry, PosDauSpecs, PosDauConfBinningQa, PosDauConfBinningMc, AbsChargeDaughters); + mNegDauManager.template init(registry, NegDauSpecs, NegDauConfBinningQa, NegDauConfBinningMc, AbsChargeDaughters); + this->enableOptionalHistograms(V0ConfBinningQa, V0ConfBinningMc); + + if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { + initAnalysis(V0Specs); + } + if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { + initQa(V0Specs); + } + if constexpr (modes::isFlagSet(mode, modes::Mode::kMc)) { + initMc(V0Specs); + } } template @@ -262,7 +388,50 @@ class V0HistManager } } + template + void fill(T1 const& v0candidate, T2 const& tracks, T3 const& mcParticles, T4 const& mcMothers, T5 const& mcPartonicMothers) + { + auto posDaughter = tracks.rawIteratorAt(v0candidate.posDauId() - tracks.offset()); + mPosDauManager.template fill(posDaughter, tracks, mcParticles, mcMothers, mcPartonicMothers); + auto negDaughter = tracks.rawIteratorAt(v0candidate.negDauId() - tracks.offset()); + mNegDauManager.template fill(negDaughter, tracks, mcParticles, mcMothers, mcPartonicMothers); + if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { + fillAnalysis(v0candidate); + } + if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { + fillQa(v0candidate); + } + if constexpr (modes::isFlagSet(mode, modes::Mode::kMc)) { + fillMc(v0candidate, mcParticles, mcMothers, mcPartonicMothers); + } + } + private: + // for qa + template + void enableOptionalHistograms(T1 const& V0ConfBinningQa) + { + mPlot2d = V0ConfBinningQa.plot2d.value; + } + + // for qa and mc + template + void enableOptionalHistograms(T1 const& V0ConfBinningQa, T2 const& V0ConfBinningMc) + { + mPlot2d = V0ConfBinningQa.plot2d.value; + + mPlotOrigins = V0ConfBinningMc.plotOrigins.value; + mPlotNSecondaries = V0ConfBinningMc.pdgCodesForMothersOfSecondary.value.size(); + + for (std::size_t i = 0; i < MaxSecondary; i++) { + if (i < V0ConfBinningMc.pdgCodesForMothersOfSecondary.value.size()) { + mPdgCodesSecondaryMother.at(i) = std::abs(V0ConfBinningMc.pdgCodesForMothersOfSecondary.value.at(i)); + } else { + mPdgCodesSecondaryMother.at(i) = 0; + } + } + } + void initAnalysis(std::map> const& V0Specs) { std::string analysisDir = std::string(v0Prefix) + std::string(AnalysisDir); @@ -303,6 +472,36 @@ class V0HistManager } } + void initMc(std::map> const& V0Specs) + { + std::string mcDir = std::string(v0Prefix) + std::string(McDir); + mHistogramRegistry->add(mcDir + getHistNameV2(kTruePt, HistTable), getHistDesc(kTruePt, HistTable), getHistType(kTruePt, HistTable), {V0Specs.at(kTruePt)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueEta, HistTable), getHistDesc(kTrueEta, HistTable), getHistType(kTrueEta, HistTable), {V0Specs.at(kTrueEta)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTruePhi, HistTable), getHistDesc(kTruePhi, HistTable), getHistType(kTruePhi, HistTable), {V0Specs.at(kTruePhi)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kOrigin, HistTable), getHistDesc(kOrigin, HistTable), getHistType(kOrigin, HistTable), {V0Specs.at(kOrigin)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kPdg, HistTable), getHistDesc(kPdg, HistTable), getHistType(kPdg, HistTable), {V0Specs.at(kPdg)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kPdgMother, HistTable), getHistDesc(kPdgMother, HistTable), getHistType(kPdgMother, HistTable), {V0Specs.at(kPdgMother)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kPdgPartonicMother, HistTable), getHistDesc(kPdgPartonicMother, HistTable), getHistType(kPdgPartonicMother, HistTable), {V0Specs.at(kPdgPartonicMother)}); + + if (mPlotOrigins) { + mHistogramRegistry->add(mcDir + getHistNameV2(kNoMcParticle, HistTable), getHistDesc(kNoMcParticle, HistTable), getHistType(kNoMcParticle, HistTable), {V0Specs.at(kNoMcParticle)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kPrimary, HistTable), getHistDesc(kPrimary, HistTable), getHistType(kPrimary, HistTable), {V0Specs.at(kPrimary)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kFromWrongCollision, HistTable), getHistDesc(kFromWrongCollision, HistTable), getHistType(kFromWrongCollision, HistTable), {V0Specs.at(kFromWrongCollision)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kFromMaterial, HistTable), getHistDesc(kFromMaterial, HistTable), getHistType(kFromMaterial, HistTable), {V0Specs.at(kFromMaterial)}); + + if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel1) { + mHistogramRegistry->add(mcDir + getHistNameV2(kSecondary1, HistTable), getHistDesc(kSecondary1, HistTable), getHistType(kSecondary1, HistTable), {V0Specs.at(kSecondary1)}); + } + if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel2) { + mHistogramRegistry->add(mcDir + getHistNameV2(kSecondary2, HistTable), getHistDesc(kSecondary2, HistTable), getHistType(kSecondary2, HistTable), {V0Specs.at(kSecondary2)}); + } + if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel3) { + mHistogramRegistry->add(mcDir + getHistNameV2(kSecondary3, HistTable), getHistDesc(kSecondary3, HistTable), getHistType(kSecondary3, HistTable), {V0Specs.at(kSecondary3)}); + } + mHistogramRegistry->add(mcDir + getHistNameV2(kSecondaryOther, HistTable), getHistDesc(kSecondaryOther, HistTable), getHistType(kSecondaryOther, HistTable), {V0Specs.at(kSecondaryOther)}); + } + } + template void fillAnalysis(T const& v0candidate) { @@ -370,8 +569,83 @@ class V0HistManager } } + template + void fillMc(T1 const& v0candidate, T2 const& /*mcParticles*/, T3 const& /*mcMothers*/, T4 const& /*mcPartonicMothers*/) + { + // No MC Particle + if (!v0candidate.has_fMcParticle()) { + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kPdg, HistTable)), 0); + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kOrigin, HistTable)), static_cast(modes::McOrigin::kNoMcParticle)); + if (mPlotOrigins) { + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kNoMcParticle, HistTable)), v0candidate.pt(), v0candidate.cosPa()); + } + return; + } + + // Retrieve MC particle + auto mcParticle = v0candidate.template fMcParticle_as(); + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kTruePt, HistTable)), mcParticle.pt()); + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kTrueEta, HistTable)), mcParticle.eta()); + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kTruePhi, HistTable)), mcParticle.phi()); + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kOrigin, HistTable)), mcParticle.origin()); + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kPdg, HistTable)), mcParticle.pdgCode()); + + // Mother PDG + if (v0candidate.has_fMcMother()) { + auto mother = v0candidate.template fMcMother_as(); + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kPdgMother, HistTable)), mother.pdgCode()); + } else { + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kPdgMother, HistTable)), 0); + } + + // Partonic Mother PDG + if (v0candidate.has_fMcPartMoth()) { + auto partonicMother = v0candidate.template fMcPartMoth_as(); + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kPdgPartonicMother, HistTable)), partonicMother.pdgCode()); + } else { + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kPdgPartonicMother, HistTable)), 0); + } + + // Plot origins + if (mPlotOrigins) { + switch (static_cast(mcParticle.origin())) { + case modes::McOrigin::kPhysicalPrimary: + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kPrimary, HistTable)), v0candidate.pt(), v0candidate.cosPa()); + break; + case modes::McOrigin::kFromWrongCollision: + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kFromWrongCollision, HistTable)), v0candidate.pt(), v0candidate.cosPa()); + break; + case modes::McOrigin::kFromMaterial: + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kFromMaterial, HistTable)), v0candidate.pt(), v0candidate.cosPa()); + break; + case modes::McOrigin::kFromSecondaryDecay: + if (v0candidate.has_fMcMother()) { + auto mother = v0candidate.template fMcMother_as(); + int motherPdgCode = std::abs(mother.pdgCode()); + // Switch on PDG of the mother + if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel1 && motherPdgCode == mPdgCodesSecondaryMother[0]) { + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kSecondary1, HistTable)), v0candidate.pt(), v0candidate.cosPa()); + } else if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel2 && motherPdgCode == mPdgCodesSecondaryMother[1]) { + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kSecondary2, HistTable)), v0candidate.pt(), v0candidate.cosPa()); + } else if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel3 && motherPdgCode == mPdgCodesSecondaryMother[2]) { + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kSecondary3, HistTable)), v0candidate.pt(), v0candidate.cosPa()); + } else { + mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kSecondaryOther, HistTable)), v0candidate.pt(), v0candidate.cosPa()); + } + } + break; + default: + // Unknown origin → safely ignore + break; + } + } + } + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; - bool mPlot2d = true; + bool mPlot2d = false; + bool mPlotOrigins = false; + int mPlotNSecondaries = 0; + std::array mPdgCodesSecondaryMother = {0}; trackhistmanager::TrackHistManager mPosDauManager; trackhistmanager::TrackHistManager mNegDauManager; }; diff --git a/PWGCF/Femto/DataModel/FemtoTables.h b/PWGCF/Femto/DataModel/FemtoTables.h index 787e8a3f381..87ead7ec293 100644 --- a/PWGCF/Femto/DataModel/FemtoTables.h +++ b/PWGCF/Femto/DataModel/FemtoTables.h @@ -740,5 +740,15 @@ DECLARE_SOA_TABLE(FTrackLabels, "AOD", "FTRACKLABEL", femtolabels::FMcMotherId, femtolabels::FMcPartMothId); +DECLARE_SOA_TABLE(FLambdaLabels, "AOD", "FLAMBDALABEL", + femtolabels::FMcParticleId, + femtolabels::FMcMotherId, + femtolabels::FMcPartMothId); + +DECLARE_SOA_TABLE(FK0shortLabels, "AOD", "FK0SHORTLABEL", + femtolabels::FMcParticleId, + femtolabels::FMcMotherId, + femtolabels::FMcPartMothId); + } // namespace o2::aod #endif // PWGCF_FEMTO_DATAMODEL_FEMTOTABLES_H_ diff --git a/PWGCF/Femto/TableProducer/femtoProducer.cxx b/PWGCF/Femto/TableProducer/femtoProducer.cxx index 3b964598335..8fb571f151d 100644 --- a/PWGCF/Femto/TableProducer/femtoProducer.cxx +++ b/PWGCF/Femto/TableProducer/femtoProducer.cxx @@ -71,14 +71,13 @@ using Run3FullPidTracks = pidTOFbeta, pidTOFmass>; using Run3McRecoTracks = soa::Join; -using Run3PpVzeros = aod::V0Datas; -using Run3PpRecoVzeros = soa::Join; +using Run3Vzeros = aod::V0Datas; +using Run3RecoVzeros = soa::Join; -using Run3PpCascades = CascDatas; -using Run3PpRecoCascades = soa::Join; +using Run3Cascades = CascDatas; +using Run3RecoCascades = soa::Join; -using Run3PpKinks = KinkCands; -// using Run3PpRecoKinks = soa::Join; +using Run3Kinks = KinkCands; using Run3McGenParticles = aod::McParticles; @@ -178,6 +177,16 @@ struct FemtoProducer { void init(InitContext& context) { + if ((xiBuilder.fillAnyTable() || omegaBuilder.fillAnyTable()) && (!doprocessTracksV0sCascadesRun3pp && !doprocessTracksV0sCascadesKinksRun3pp)) { + LOG(fatal) << "At least one cascade table is enabled, but wrong process function is enabled. Breaking..."; + } + if ((lambdaBuilder.fillAnyTable() || antilambdaBuilder.fillAnyTable() || k0shortBuilder.fillAnyTable()) && (!doprocessTracksV0sCascadesRun3pp && !doprocessTracksV0sRun3pp && !doprocessTracksV0sCascadesKinksRun3pp)) { + LOG(fatal) << "At least one v0 table is enabled, but wrong process function is enabled. Breaking..."; + } + if ((sigmaBuilder.fillAnyTable() || sigmaPlusBuilder.fillAnyTable()) && (!doprocessTracksKinksRun3pp && !doprocessTracksV0sCascadesKinksRun3pp)) { + LOG(fatal) << "At least one kink table is enabled, but wrong process function is enabled. Breaking..."; + } + // init ccdb ccdb->setURL(confCcdb.ccdbUrl.value); ccdb->setCaching(true); @@ -212,16 +221,6 @@ struct FemtoProducer { // configure mcBuilder mcBuilder.init(confMc, confMcTables, context); - - if ((xiBuilder.fillAnyTable() || omegaBuilder.fillAnyTable()) && (!doprocessTracksV0sCascadesRun3pp && !doprocessTracksV0sCascadesKinksRun3pp)) { - LOG(fatal) << "At least one cascade table is enabled, but wrong process function is enabled. Breaking..."; - } - if ((lambdaBuilder.fillAnyTable() || antilambdaBuilder.fillAnyTable() || k0shortBuilder.fillAnyTable()) && (!doprocessTracksV0sCascadesRun3pp && !doprocessTracksV0sRun3pp && !doprocessTracksV0sCascadesKinksRun3pp)) { - LOG(fatal) << "At least one v0 table is enabled, but wrong process function is enabled. Breaking..."; - } - if ((sigmaBuilder.fillAnyTable() || sigmaPlusBuilder.fillAnyTable()) && (!doprocessTracksKinksRun3pp && !doprocessTracksV0sCascadesKinksRun3pp)) { - LOG(fatal) << "At least one kink table is enabled, but wrong process function is enabled. Breaking..."; - } } // Core implementations @@ -260,9 +259,9 @@ struct FemtoProducer { } template - void processMcTracks(T1 const& col, T2 const& mcCol, T3 const& tracks, T4 const& tracksWithItsPid, T5 const& mcParticles) + void processMcTracks(T1 const& col, T2 const& mcCols, T3 const& tracks, T4 const& tracksWithItsPid, T5 const& mcParticles) { - trackBuilder.fillMcTracks(col, collisionBuilder, collisionBuilderProducts, mcCol, tracks, tracksWithItsPid, trackBuilderProducts, mcParticles, mcBuilder, mcProducts); + trackBuilder.fillMcTracks(col, collisionBuilder, collisionBuilderProducts, mcCols, tracks, tracksWithItsPid, trackBuilderProducts, mcParticles, mcBuilder, mcProducts); } template @@ -285,6 +284,16 @@ struct FemtoProducer { k0shortBuilder.fillV0s(col, collisionBuilder, collisionBuilderProducts, trackBuilderProducts, v0builderProducts, v0s, tracks, tracksWithItsPid, trackBuilder); } + template + void processMcV0s(T1 const& col, T2 const& mcCols, T3 const& tracks, T4 const& tracksWithItsPid, T5 const& v0s, T6 const& mcParticles) + { + lambdaBuilder.fillMcV0s(col, collisionBuilder, collisionBuilderProducts, mcCols, trackBuilderProducts, v0builderProducts, v0s, tracks, tracksWithItsPid, trackBuilder, mcParticles, mcBuilder, mcProducts); + antilambdaBuilder.fillMcV0s(col, collisionBuilder, collisionBuilderProducts, mcCols, trackBuilderProducts, v0builderProducts, v0s, tracks, tracksWithItsPid, trackBuilder, mcParticles, mcBuilder, mcProducts); + k0shortBuilder.fillMcV0s(col, collisionBuilder, collisionBuilderProducts, mcCols, trackBuilderProducts, v0builderProducts, v0s, tracks, tracksWithItsPid, trackBuilder, mcParticles, mcBuilder, mcProducts); + } + + // processMcV0s(col, mcCols, tracks, tracksWithItsPid, v0s, mcParticles); + // add kinks template void processKinks(T1 const& col, T2 const& tracks, T3 const& tracksWithItsPid, T4 const& kinks) @@ -331,7 +340,7 @@ struct FemtoProducer { void processTracksV0sRun3pp(consumeddata::Run3PpCollisions::iterator const& col, BCsWithTimestamps const& bcs, consumeddata::Run3FullPidTracks const& tracks, - consumeddata::Run3PpVzeros const& v0s) + consumeddata::Run3Vzeros const& v0s) { if (!processCollisions(col, bcs, tracks)) { return; @@ -348,7 +357,7 @@ struct FemtoProducer { void processTracksKinksRun3pp(consumeddata::Run3PpCollisions::iterator const& col, BCsWithTimestamps const& bcs, consumeddata::Run3FullPidTracks const& tracks, - consumeddata::Run3PpKinks const& kinks) + consumeddata::Run3Kinks const& kinks) { if (!processCollisions(col, bcs, tracks)) { return; @@ -365,8 +374,8 @@ struct FemtoProducer { void processTracksV0sCascadesRun3pp(consumeddata::Run3PpCollisions::iterator const& col, BCsWithTimestamps const& bcs, consumeddata::Run3FullPidTracks const& tracks, - consumeddata::Run3PpVzeros const& v0s, - consumeddata::Run3PpCascades const& cascades) + consumeddata::Run3Vzeros const& v0s, + consumeddata::Run3Cascades const& cascades) { if (!processCollisions(col, bcs, tracks)) { return; @@ -384,9 +393,9 @@ struct FemtoProducer { void processTracksV0sCascadesKinksRun3pp(consumeddata::Run3PpCollisions::iterator const& col, BCsWithTimestamps const& bcs, consumeddata::Run3FullPidTracks const& tracks, - consumeddata::Run3PpVzeros const& v0s, - consumeddata::Run3PpCascades const& cascades, - consumeddata::Run3PpKinks const& kinks) + consumeddata::Run3Vzeros const& v0s, + consumeddata::Run3Cascades const& cascades, + consumeddata::Run3Kinks const& kinks) { if (!processCollisions(col, bcs, tracks)) { return; @@ -417,6 +426,43 @@ struct FemtoProducer { processMcTracks(col, mcCols, tracks, tracksWithItsPid, mcParticles); } PROCESS_SWITCH(FemtoProducer, processTracksRun3ppMc, "Provide reconstructed and generated Tracks", false); + + // process monte carlo tracks and v0s + void processTracksV0sRun3ppMc(consumeddata::Run3PpMcRecoCollisions::iterator const& col, + consumeddata::Run3PpMcGenCollisions const& mcCols, + BCsWithTimestamps const& bcs, + consumeddata::Run3McRecoTracks const& tracks, + consumeddata::Run3RecoVzeros const& v0s, + consumeddata::Run3McGenParticles const& mcParticles) + { + if (!processMcCollisions(col, mcCols, bcs, tracks)) { + return; + } + auto tracksWithItsPid = o2::soa::Attach(tracks); + mcBuilder.reset(); + processMcTracks(col, mcCols, tracks, tracksWithItsPid, mcParticles); + processMcV0s(col, mcCols, tracks, tracksWithItsPid, v0s, mcParticles); + } + PROCESS_SWITCH(FemtoProducer, processTracksV0sRun3ppMc, "Provide reconstructed and generated Tracks and v0s", false); + + // process monte carlo tracks and v0s + void processTracksKinksRun3ppMc(consumeddata::Run3PpMcRecoCollisions::iterator const& col, + consumeddata::Run3PpMcGenCollisions const& mcCols, + BCsWithTimestamps const& bcs, + consumeddata::Run3McRecoTracks const& tracks, + consumeddata::Run3McGenParticles const& mcParticles) + { + if (!processMcCollisions(col, mcCols, bcs, tracks)) { + return; + } + auto tracksWithItsPid = o2::soa::Attach(tracks); + mcBuilder.reset(); + processMcTracks(col, mcCols, tracks, tracksWithItsPid, mcParticles); + processMcV0s(col, mcCols, tracks, tracksWithItsPid, v0s, mcParticles); + } + PROCESS_SWITCH(FemtoProducer, processTracksV0sRun3ppMc, "Provide reconstructed and generated Tracks and v0s", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/Femto/Tasks/femtoKinkQa.cxx b/PWGCF/Femto/Tasks/femtoKinkQa.cxx index 2c72edd1889..b2d84d2ba04 100644 --- a/PWGCF/Femto/Tasks/femtoKinkQa.cxx +++ b/PWGCF/Femto/Tasks/femtoKinkQa.cxx @@ -102,16 +102,16 @@ struct FemtoKinkQa { void init(InitContext&) { + if ((doprocessSigma + doprocessSigmaPlus > 1)) { + LOG(fatal) << "Only one process can be activated"; + } + // create a map for histogram specs auto colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); auto chaDauHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confKinkChaDaughterBinning, confKinkChaDaughterQaBinning); - if ((doprocessSigma + doprocessSigmaPlus > 1)) { - LOG(fatal) << "Only one process can be activated"; - } - if (doprocessSigma) { auto sigmaHistSpec = kinkhistmanager::makeKinkQaHistSpecMap(confSigmaBinning, confSigmaQaBinning); sigmaHistManager.init(&hRegistry, sigmaHistSpec, confSigmaQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); @@ -121,6 +121,7 @@ struct FemtoKinkQa { auto sigmaPlusHistSpec = kinkhistmanager::makeKinkQaHistSpecMap(confSigmaPlusBinning, confSigmaPlusQaBinning); sigmaPlusHistManager.init(&hRegistry, sigmaPlusHistSpec, confSigmaPlusQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); } + hRegistry.print(); }; void processSigma(FilteredFemtoCollision const& col, FemtoSigmas const& /*sigmas*/, FemtoTracks const& tracks) diff --git a/PWGCF/Femto/Tasks/femtoTrackQa.cxx b/PWGCF/Femto/Tasks/femtoTrackQa.cxx index 42e5eec9199..349296b7cd2 100644 --- a/PWGCF/Femto/Tasks/femtoTrackQa.cxx +++ b/PWGCF/Femto/Tasks/femtoTrackQa.cxx @@ -42,7 +42,6 @@ struct FemtoTrackQa { // setup tables using FemtoCollisions = o2::soa::Join; - using FilteredFemtoCollisions = o2::soa::Filtered; using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; @@ -85,21 +84,22 @@ struct FemtoTrackQa { LOG(fatal) << "More than 1 process function is activated. Breaking..."; } - if (doprocessData) { + bool processData = doprocessData; + + if (processData) { // create a map for histogram specs auto colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); auto trackHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confTrackBinning, confTrackQaBinning); trackHistManager.init(&hRegistry, trackHistSpec, confTrackQaBinning, trackSelections.chargeAbs.value); - } - - if (doprocessMc) { + } else { // create a map for histogram specs auto colHistSpec = colhistmanager::makeColMcQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); auto trackHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confTrackBinning, confTrackQaBinning, confTrackMcBinning); trackHistManager.init(&hRegistry, trackHistSpec, confTrackQaBinning, confTrackMcBinning, trackSelections.chargeAbs.value); } + hRegistry.print(); }; void processData(FilteredFemtoCollision const& col, FemtoTracks const& tracks) diff --git a/PWGCF/Femto/Tasks/femtoV0Qa.cxx b/PWGCF/Femto/Tasks/femtoV0Qa.cxx index 610516bf2ab..daeb05964de 100644 --- a/PWGCF/Femto/Tasks/femtoV0Qa.cxx +++ b/PWGCF/Femto/Tasks/femtoV0Qa.cxx @@ -42,15 +42,23 @@ using namespace o2::analysis::femto; struct FemtoV0Qa { + // setup tables using FemtoCollisions = o2::soa::Join; - using FilteredFemtoCollisions = o2::soa::Filtered; using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; + using FemtoCollisionsWithLabel = o2::soa::Join; + using FilteredFemtoCollisionsWithLabel = o2::soa::Filtered; + using FilteredFemtoCollisionWithLabel = FilteredFemtoCollisionsWithLabel::iterator; + using FemtoLambdas = o2::soa::Join; using FemtoK0shorts = o2::soa::Join; using FemtoTracks = o2::soa::Join; + using FemtoLambdasWithLabel = o2::soa::Join; + using FemtoK0shortsWithLabel = o2::soa::Join; + using FemtoTracksWithLabel = o2::soa::Join; + SliceCache cache; // setup for collisions @@ -66,8 +74,12 @@ struct FemtoV0Qa { Partition lambdaPartition = MAKE_LAMBDA_PARTITION(confLambdaSelection); Preslice perColLambdas = femtobase::stored::fColId; + Partition lambdaWithLabelPartition = MAKE_LAMBDA_PARTITION(confLambdaSelection); + Preslice perColLambdasWithLabel = femtobase::stored::fColId; + v0histmanager::ConfLambdaBinning1 confLambdaBinning; v0histmanager::ConfLambdaQaBinning1 confLambdaQaBinning; + v0histmanager::ConfLambdaMcBinning1 confLambdaMcBinning; v0histmanager::V0HistManager< v0histmanager::PrefixLambdaQa, trackhistmanager::PrefixV0PosDaughterQa, @@ -81,8 +93,12 @@ struct FemtoV0Qa { Partition k0shortPartition = MAKE_K0SHORT_PARTITION(confK0shortSelection); Preslice perColK0shorts = femtobase::stored::fColId; + Partition k0shortWithLabelPartition = MAKE_K0SHORT_PARTITION(confK0shortSelection); + Preslice perColK0shortsWithLabel = femtobase::stored::fColId; + v0histmanager::ConfK0shortBinning1 confK0shortBinning; v0histmanager::ConfK0shortQaBinning1 confK0shortQaBinning; + v0histmanager::ConfK0shortMcBinning1 confK0shortMcBinning; v0histmanager::V0HistManager< v0histmanager::PrefixK0shortQa, trackhistmanager::PrefixV0PosDaughterQa, @@ -93,34 +109,57 @@ struct FemtoV0Qa { // setup for daughters trackhistmanager::ConfV0PosDauBinning confV0PosDaughterBinning; trackhistmanager::ConfV0PosDauQaBinning confV0PosDaughterQaBinning; + trackhistmanager::ConfV0PosDauMcBinning confV0PosDaughterMcBinning; trackhistmanager::ConfV0NegDauBinning confV0NegDaughterBinning; trackhistmanager::ConfV0NegDauQaBinning confV0NegDaughterQaBinning; + trackhistmanager::ConfV0NegDauMcBinning confV0NegDaughterMcBinning; HistogramRegistry hRegistry{"FemtoV0Qa", {}, OutputObjHandlingPolicy::AnalysisObject}; void init(InitContext&) { - // create a map for histogram specs - auto colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); - colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); - - auto posDaughterHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confV0PosDaughterBinning, confV0PosDaughterQaBinning); - auto negDaughterHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confV0NegDaughterBinning, confV0NegDaughterQaBinning); - - if ((doprocessK0short + doprocessLambda) > 1) { + if ((doprocessLambda + doprocessLambdaMc + doprocessK0short + doprocessK0shortMc) > 1) { LOG(fatal) << "Only one process can be activated"; } - if (doprocessLambda) { - auto lambdaHistSpec = v0histmanager::makeV0QaHistSpecMap(confLambdaBinning, confLambdaQaBinning); - lambdaHistManager.init(&hRegistry, lambdaHistSpec, confLambdaQaBinning, posDaughterHistSpec, confV0PosDaughterQaBinning, negDaughterHistSpec, confV0NegDaughterQaBinning); - } - - if (doprocessK0short) { - auto k0shortHistSpec = v0histmanager::makeV0QaHistSpecMap(confK0shortBinning, confK0shortQaBinning); - k0shortHistManager.init(&hRegistry, k0shortHistSpec, confK0shortQaBinning, posDaughterHistSpec, confV0PosDaughterQaBinning, negDaughterHistSpec, confV0NegDaughterQaBinning); + bool processData = doprocessLambda || doprocessK0short; + + if (processData) { + auto colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); + colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); + + auto posDaughterHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confV0PosDaughterBinning, confV0PosDaughterQaBinning); + auto negDaughterHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confV0NegDaughterBinning, confV0NegDaughterQaBinning); + + if (doprocessLambda) { + auto lambdaHistSpec = v0histmanager::makeV0QaHistSpecMap(confLambdaBinning, confLambdaQaBinning); + lambdaHistManager.init(&hRegistry, lambdaHistSpec, confLambdaQaBinning, posDaughterHistSpec, confV0PosDaughterQaBinning, negDaughterHistSpec, confV0NegDaughterQaBinning); + } + + if (doprocessK0short) { + auto k0shortHistSpec = v0histmanager::makeV0QaHistSpecMap(confK0shortBinning, confK0shortQaBinning); + k0shortHistManager.init(&hRegistry, k0shortHistSpec, confK0shortQaBinning, posDaughterHistSpec, confV0PosDaughterQaBinning, negDaughterHistSpec, confV0NegDaughterQaBinning); + } + } else { + // process mc + auto colHistSpec = colhistmanager::makeColMcQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); + colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); + + auto posDaughterHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confV0PosDaughterBinning, confV0PosDaughterQaBinning, confV0PosDaughterMcBinning); + auto negDaughterHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confV0NegDaughterBinning, confV0NegDaughterQaBinning, confV0NegDaughterMcBinning); + + if (doprocessLambdaMc) { + auto lambdaHistSpec = v0histmanager::makeV0McQaHistSpecMap(confLambdaBinning, confLambdaQaBinning, confLambdaMcBinning); + lambdaHistManager.init(&hRegistry, lambdaHistSpec, confLambdaQaBinning, confLambdaMcBinning, posDaughterHistSpec, confV0PosDaughterQaBinning, confV0PosDaughterMcBinning, negDaughterHistSpec, confV0NegDaughterQaBinning, confV0NegDaughterMcBinning); + } + + if (doprocessK0shortMc) { + auto k0shortHistSpec = v0histmanager::makeV0McQaHistSpecMap(confK0shortBinning, confK0shortQaBinning, confK0shortMcBinning); + k0shortHistManager.init(&hRegistry, k0shortHistSpec, confK0shortQaBinning, confK0shortMcBinning, posDaughterHistSpec, confV0PosDaughterQaBinning, confV0PosDaughterMcBinning, negDaughterHistSpec, confV0NegDaughterQaBinning, confV0NegDaughterMcBinning); + } } + hRegistry.print(); }; void processK0short(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoK0shorts const& /*k0shorts*/) @@ -133,6 +172,16 @@ struct FemtoV0Qa { } PROCESS_SWITCH(FemtoV0Qa, processK0short, "Process k0shorts", false); + void processK0shortMc(FilteredFemtoCollisionWithLabel const& col, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& /*k0shorts*/, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + { + colHistManager.fill(col, mcCols); + auto k0shortSlice = k0shortWithLabelPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + for (auto const& k0short : k0shortSlice) { + k0shortHistManager.fill(k0short, tracks, mcParticles, mcMothers, mcPartonicMothers); + } + } + PROCESS_SWITCH(FemtoV0Qa, processK0shortMc, "Process k0shorts", false); + void processLambda(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoLambdas const& /*lambdas*/) { colHistManager.fill(col); @@ -142,6 +191,16 @@ struct FemtoV0Qa { } } PROCESS_SWITCH(FemtoV0Qa, processLambda, "Process lambdas", true); + + void processLambdaMc(FilteredFemtoCollisionWithLabel const& col, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& /*lambdas*/, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + { + colHistManager.fill(col, mcCols); + auto lambdaSlice = lambdaWithLabelPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + for (auto const& lambda : lambdaSlice) { + lambdaHistManager.fill(lambda, tracks, mcParticles, mcMothers, mcPartonicMothers); + } + } + PROCESS_SWITCH(FemtoV0Qa, processLambdaMc, "Process lambdas", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From ab3c8c5c7a8c27516e420d50cb9cd121993b9de9 Mon Sep 17 00:00:00 2001 From: Anton Riedel Date: Wed, 31 Dec 2025 13:50:41 +0100 Subject: [PATCH 2/4] Feat: finish mc processing for kinks --- PWGCF/Femto/Core/kinkBuilder.h | 49 ++- PWGCF/Femto/Core/kinkHistManager.h | 315 ++++++++++++++++++-- PWGCF/Femto/Core/mcBuilder.h | 220 +++++++++++++- PWGCF/Femto/Core/trackHistManager.h | 2 + PWGCF/Femto/Core/v0HistManager.h | 9 +- PWGCF/Femto/DataModel/FemtoTables.h | 10 + PWGCF/Femto/TableProducer/femtoProducer.cxx | 36 +-- PWGCF/Femto/Tasks/femtoKinkQa.cxx | 98 ++++-- 8 files changed, 654 insertions(+), 85 deletions(-) diff --git a/PWGCF/Femto/Core/kinkBuilder.h b/PWGCF/Femto/Core/kinkBuilder.h index be925771691..e4897d88dcd 100644 --- a/PWGCF/Femto/Core/kinkBuilder.h +++ b/PWGCF/Femto/Core/kinkBuilder.h @@ -27,7 +27,6 @@ #include "Common/Core/RecoDecay.h" #include "CommonConstants/MathConstants.h" -#include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisHelpers.h" #include "Framework/Configurable.h" @@ -435,7 +434,6 @@ class KinkBuilder int64_t daughterIndex = 0; for (const auto& kink : kinks) { - // compute mother kinematics before checking filters mKinkSelection.computeKinkMotherKinematics(kink); if (!mKinkSelection.checkFilters(kink)) { @@ -444,7 +442,6 @@ class KinkBuilder // compute qa variables before applying selections mKinkSelection.computeQaVariables(kink, tracks); mKinkSelection.applySelections(kink, tracks); - if (!mKinkSelection.passesAllRequiredSelections()) { continue; } @@ -452,7 +449,8 @@ class KinkBuilder collisionBuilder.template fillCollision(collisionProducts, col); // cleaner, but without ITS pid: auto daughter = kink.template trackDaug_as(); int64_t idx = kink.trackDaugId() - tracksWithItsPid.offset(); - if (idx < 0 || idx > static_cast(tracksWithItsPid.size())) { + // check for valid index + if (idx < 0 || idx >= static_cast(tracksWithItsPid.size())) { return; } auto daughter = tracksWithItsPid.iteratorAt(idx); @@ -466,6 +464,49 @@ class KinkBuilder } } + template + void fillMcKinks(T1 const& col, T2& collisionBuilder, T3& collisionProducts, T4 const& mcCols, T5& trackProducts, T6& kinkProducts, T7 const& kinks, T8 const& tracks, T9 const& tracksWithItsPid, T10& trackBuilder, T11 const& mcParticles, T12& mcBuilder, T13& mcProducts) + { + + if (!mFillAnyTable) { + return; + } + int64_t daughterIndex = 0; + for (const auto& kink : kinks) { + // compute mother kinematics before checking filters + mKinkSelection.computeKinkMotherKinematics(kink); + if (!mKinkSelection.checkFilters(kink)) { + continue; + } + // compute qa variables before applying selections + mKinkSelection.computeQaVariables(kink, tracks); + mKinkSelection.applySelections(kink, tracks); + if (!mKinkSelection.passesAllRequiredSelections()) { + continue; + } + + collisionBuilder.template fillMcCollision(collisionProducts, col, mcCols, mcProducts, mcBuilder); + + int64_t idx = kink.trackDaugId() - tracks.offset(); + // check for valid index + if (idx < 0 || idx >= static_cast(tracks.size())) { + return; + } + auto daughter = tracks.iteratorAt(idx); + auto daughterWithItsPid = tracksWithItsPid.iteratorAt(idx); + daughterIndex = trackBuilder.template getDaughterIndex(col, collisionProducts, mcCols, daughter, daughterWithItsPid, trackProducts, mcParticles, mcBuilder, mcProducts); + + if constexpr (modes::isEqual(kinkType, modes::Kink::kSigma)) { + fillSigma(collisionProducts, kinkProducts, kink, daughterIndex); + mcBuilder.template fillMcSigmaWithLabel(col, mcCols, kink, daughter, mcParticles, mcProducts); + } + if constexpr (modes::isEqual(kinkType, modes::Kink::kSigmaPlus)) { + fillSigmaPlus(collisionProducts, kinkProducts, kink, daughterIndex); + mcBuilder.template fillMcSigmaPlusWithLabel(col, mcCols, kink, daughter, mcParticles, mcProducts); + } + } + } + template void fillSigma(T1& collisionProducts, T2& kinkProducts, T3 const& kink, int64_t daughterIndex) { diff --git a/PWGCF/Femto/Core/kinkHistManager.h b/PWGCF/Femto/Core/kinkHistManager.h index efec80ffaac..e6621f01491 100644 --- a/PWGCF/Femto/Core/kinkHistManager.h +++ b/PWGCF/Femto/Core/kinkHistManager.h @@ -59,9 +59,29 @@ enum KinkHist { kPhiVsEta, kPtVsKinkAngle, kPtVsDecayRadius, + // mc + kOrigin, + kPdg, + kPdgMother, + kPdgPartonicMother, + kTruePt, + kTrueEta, + kTruePhi, + // histograms for fraction estimation of kinks + kNoMcParticle, + kPrimary, + kFromWrongCollision, + kFromMaterial, + kSecondary1, + kSecondary2, + kSecondary3, + kSecondaryOther, + kKinkHistLast }; +constexpr std::size_t MaxSecondary = 3; + #define KINK_DEFAULT_BINNING(defaultMassMin, defaultMassMax) \ o2::framework::ConfigurableAxis pt{"pt", {{600, 0, 6}}, "Pt"}; \ o2::framework::ConfigurableAxis eta{"eta", {{300, -1.5, 1.5}}, "Eta"}; \ @@ -104,6 +124,23 @@ using ConfSigmaQaBinning1 = ConfKinkQaBinning; constexpr const char PrefixSigmaPlusQaBinning1[] = "SigmaPlusQaBinning1"; using ConfSigmaPlusQaBinning1 = ConfKinkQaBinning; +template +struct ConfKinkMcBinning : o2::framework::ConfigurableGroup { + std::string prefix = std::string(Prefix); + o2::framework::ConfigurableAxis pdgCodes{"pdgCodes", {{8001, -4000.5, 4000.5}}, "PDG codes of selected V0s"}; + o2::framework::ConfigurableAxis statusCode{"statusCode", {{21, -0.5, 20.5}}, "Status codes (i.e. Origin)"}; + o2::framework::Configurable plotOrigins{"plotOrigins", true, "Plot pt vs cosPa for different particle origins"}; + o2::framework::Configurable> pdgCodesForMothersOfSecondary{"pdgCodesForMothersOfSecondary", {3312, 3334}, "PDG codes of mothers of secondaries (Max 3 will be considered)"}; + o2::framework::ConfigurableAxis pt{"pt", {{150, 0, 3}}, "Pt"}; + o2::framework::ConfigurableAxis kinkAngle{"kinkAngle", {{315, 0, 3.15}}, "Kink angle"}; +}; + +constexpr const char PrefixSigmaMcBinning1[] = "SigmaMcBinning1"; +using ConfSigmaMcBinning = ConfKinkMcBinning; + +constexpr const char PrefixSigmaPlusMcBinning1[] = "SigmaPlusMcBinning1"; +using ConfSigmaPlusMcBinning = ConfKinkMcBinning; + // must be in sync with enum KinkHist // the enum gives the correct index in the array constexpr std::array, kKinkHistLast> HistTable = { @@ -124,43 +161,90 @@ constexpr std::array, kKinkHistLast> HistTable = {kPtVsPhi, o2::framework::kTH2F, "hPtVsPhi", "p_{T} vs #varphi; p_{T} (GeV/#it{c}); #varphi"}, {kPhiVsEta, o2::framework::kTH2F, "hPhiVsEta", "#varphi vs #eta; #varphi; #eta"}, {kPtVsKinkAngle, o2::framework::kTH2F, "hPtVsKinkAngle", "p_{T} vs kink angle; p_{T} (GeV/#it{c}); kink angle (rad)"}, - {kPtVsDecayRadius, o2::framework::kTH2F, "hPtVsDecayRadius", "p_{T} vs transverse decay radius; p_{T} (GeV/#it{c}); r_{xy} (cm)"}}}; + {kPtVsDecayRadius, o2::framework::kTH2F, "hPtVsDecayRadius", "p_{T} vs transverse decay radius; p_{T} (GeV/#it{c}); r_{xy} (cm)"}, + {kOrigin, o2::framework::kTH1F, "hOrigin", "Status Codes (=Origin); Status Code; Entries"}, + {kPdg, o2::framework::kTH1F, "hPdg", "PDG Codes of reconstructed kinks; PDG Code; Entries"}, + {kPdgMother, o2::framework::kTH1F, "hPdgMother", "PDG Codes of mother of reconstructed kink; PDG Code; Entries"}, + {kPdgPartonicMother, o2::framework::kTH1F, "hPdgPartonicMother", "PDG Codes of partonic mother reconstructed knik; PDG Code; Entries"}, + {kTruePt, o2::framework::kTH1F, "hTruePt", "True transverse momentum; p_{T} (GeV/#it{c}); Entries"}, + {kTrueEta, o2::framework::kTH1F, "hTrueEta", "True pseudorapdity; #eta; Entries"}, + {kTruePhi, o2::framework::kTH1F, "hTruePhi", "True azimuthal angle; #varphi; Entries"}, + {kNoMcParticle, o2::framework::kTH2F, "hNoMcParticle", "Wrongly reconstructed particles; p_{T} (GeV/#it{c}); cos(#alpha)"}, + {kPrimary, o2::framework::kTH2F, "hPrimary", "Primary particles; p_{T} (GeV/#it{c}); cos(#alpha)"}, + {kFromWrongCollision, o2::framework::kTH2F, "hFromWrongCollision", "Particles associated to wrong collision; p_{T} (GeV/#it{c}); cos(#alpha)"}, + {kFromMaterial, o2::framework::kTH2F, "hFromMaterial", "Particles from material; p_{T} (GeV/#it{c}); cos(#alpha)"}, + {kSecondary1, o2::framework::kTH2F, "hFromSecondary1", "Particles from secondary decay; p_{T} (GeV/#it{c}); cos(#alpha)"}, + {kSecondary2, o2::framework::kTH2F, "hFromSecondary2", "Particles from seconary decay; p_{T} (GeV/#it{c}); cos(#alpha)"}, + {kSecondary3, o2::framework::kTH2F, "hFromSecondary3", "Particles from seconary decay; p_{T} (GeV/#it{c}); cos(#alpha)"}, + {kSecondaryOther, o2::framework::kTH2F, "hFromSecondaryOther", "Particles from every other seconary decay; p_{T} (GeV/#it{c}); cos(#alpha)"}}}; + +#define KINK_HIST_ANALYSIS_MAP(conf) \ + {kPt, {conf.pt}}, \ + {kEta, {conf.eta}}, \ + {kPhi, {conf.phi}}, \ + {kMass, {conf.mass}}, \ + {kSign, {conf.sign}}, + +#define KINK_HIST_QA_MAP(confAnalysis, confQa) \ + {kKinkAngle, {confQa.kinkAngle}}, \ + {kDcaMothToPV, {confQa.dcaMothToPV}}, \ + {kDcaDaugToPV, {confQa.dcaDaugToPV}}, \ + {kDecayVtxX, {confQa.decayVertex}}, \ + {kDecayVtxY, {confQa.decayVertex}}, \ + {kDecayVtxZ, {confQa.decayVertex}}, \ + {kDecayVtx, {confQa.decayVertex}}, \ + {kTransRadius, {confQa.transRadius}}, \ + {kPtVsEta, {confAnalysis.pt, confAnalysis.eta}}, \ + {kPtVsPhi, {confAnalysis.pt, confAnalysis.phi}}, \ + {kPhiVsEta, {confAnalysis.phi, confAnalysis.eta}}, \ + {kPtVsKinkAngle, {confAnalysis.pt, confQa.kinkAngle}}, \ + {kPtVsDecayRadius, {confAnalysis.pt, confQa.transRadius}}, + +#define KINK_HIST_MC_MAP(confAnalysis, confMc) \ + {kTruePt, {confAnalysis.pt}}, \ + {kTrueEta, {confAnalysis.eta}}, \ + {kTruePhi, {confAnalysis.phi}}, \ + {kOrigin, {confMc.statusCode}}, \ + {kPdg, {confMc.pdgCodes}}, \ + {kPdgMother, {confMc.pdgCodes}}, \ + {kPdgPartonicMother, {confMc.pdgCodes}}, \ + {kNoMcParticle, {confMc.pt, confMc.kinkAngle}}, \ + {kPrimary, {confMc.pt, confMc.kinkAngle}}, \ + {kFromWrongCollision, {confMc.pt, confMc.kinkAngle}}, \ + {kFromMaterial, {confMc.pt, confMc.kinkAngle}}, \ + {kSecondary1, {confMc.pt, confMc.kinkAngle}}, \ + {kSecondary2, {confMc.pt, confMc.kinkAngle}}, \ + {kSecondary3, {confMc.pt, confMc.kinkAngle}}, \ + {kSecondaryOther, {confMc.pt, confMc.kinkAngle}}, template auto makeKinkHistSpecMap(const T& confBinningAnalysis) { return std::map>{ - {kPt, {confBinningAnalysis.pt}}, - {kEta, {confBinningAnalysis.eta}}, - {kPhi, {confBinningAnalysis.phi}}, - {kMass, {confBinningAnalysis.mass}}, - {kSign, {confBinningAnalysis.sign}}}; + KINK_HIST_ANALYSIS_MAP(confBinningAnalysis)}; } template std::map> makeKinkQaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa) { return std::map>{ - {kPt, {confBinningAnalysis.pt}}, - {kEta, {confBinningAnalysis.eta}}, - {kPhi, {confBinningAnalysis.phi}}, - {kMass, {confBinningAnalysis.mass}}, - {kSign, {confBinningAnalysis.sign}}, - {kKinkAngle, {confBinningQa.kinkAngle}}, - {kDcaMothToPV, {confBinningQa.dcaMothToPV}}, - {kDcaDaugToPV, {confBinningQa.dcaDaugToPV}}, - {kDecayVtxX, {confBinningQa.decayVertex}}, - {kDecayVtxY, {confBinningQa.decayVertex}}, - {kDecayVtxZ, {confBinningQa.decayVertex}}, - {kDecayVtx, {confBinningQa.decayVertex}}, - {kTransRadius, {confBinningQa.transRadius}}, - {kPtVsEta, {confBinningAnalysis.pt, confBinningAnalysis.eta}}, - {kPtVsPhi, {confBinningAnalysis.pt, confBinningAnalysis.phi}}, - {kPhiVsEta, {confBinningAnalysis.phi, confBinningAnalysis.eta}}, - {kPtVsKinkAngle, {confBinningAnalysis.pt, confBinningQa.kinkAngle}}, - {kPtVsDecayRadius, {confBinningAnalysis.pt, confBinningQa.transRadius}}}; + KINK_HIST_ANALYSIS_MAP(confBinningAnalysis) + KINK_HIST_QA_MAP(confBinningAnalysis, confBinningQa)}; +} + +template +std::map> makeKinkMcQaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa, T3 const& confBinningMc) +{ + return std::map>{ + KINK_HIST_ANALYSIS_MAP(confBinningAnalysis) + KINK_HIST_QA_MAP(confBinningAnalysis, confBinningQa) + KINK_HIST_MC_MAP(confBinningAnalysis, confBinningMc)}; } +#undef KINK_HIST_ANALYSIS_MAP +#undef KINK_HIST_QA_MAP +#undef KINK_HIST_MC_MAP + constexpr char PrefixSigmaQa[] = "SigmaQA/"; constexpr char PrefixSigma1[] = "Sigma1/"; constexpr char PrefixSigma2[] = "Sigma2/"; @@ -170,12 +254,10 @@ constexpr char PrefixSigmaPlus2[] = "SigmaPlus2/"; constexpr std::string_view AnalysisDir = "Kinematics/"; constexpr std::string_view QaDir = "QA/"; +constexpr std::string_view McDir = "MC/"; constexpr int AbsChargeDaughters = 1; -/// \class KinkHistManager -/// \brief Class for histogramming event properties -// template template @@ -185,6 +267,7 @@ class KinkHistManager KinkHistManager() = default; ~KinkHistManager() = default; + // init for analysis template void init(o2::framework::HistogramRegistry* registry, std::map> const& KinkSpecs, @@ -198,8 +281,12 @@ class KinkHistManager if constexpr (isFlagSet(mode, modes::Mode::kQa)) { initQa(KinkSpecs); } + if constexpr (isFlagSet(mode, modes::Mode::kMc)) { + initMc(KinkSpecs); + } } + // init for qa template void init(o2::framework::HistogramRegistry* registry, std::map> const& KinkSpecs, @@ -216,20 +303,63 @@ class KinkHistManager if constexpr (isFlagSet(mode, modes::Mode::kQa)) { initQa(KinkSpecs); } + if constexpr (isFlagSet(mode, modes::Mode::kMc)) { + initMc(KinkSpecs); + } + } + + // init for qa + mc + template + void init(o2::framework::HistogramRegistry* registry, + std::map> const& KinkSpecs, + T1 const& KinkConfBinningQa, + T2 const& KinkConfBinningMc, + std::map> const& ChaDauSpecs, + T3 const& ChaDauConfBinningQa, + T4 const& ChaDauConfBinningMc) + { + mHistogramRegistry = registry; + mChaDauManager.template init(registry, ChaDauSpecs, ChaDauConfBinningQa, ChaDauConfBinningMc, AbsChargeDaughters); + this->enableOptionalHistograms(KinkConfBinningQa, KinkConfBinningMc); + if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { + initAnalysis(KinkSpecs); + } + if constexpr (isFlagSet(mode, modes::Mode::kQa)) { + initQa(KinkSpecs); + } + if constexpr (isFlagSet(mode, modes::Mode::kMc)) { + initMc(KinkSpecs); + } } template - void fill(T1 const& kinkcandidate, T2 const& tracks) + void fill(T1 const& kinkCandidate, T2 const& tracks) { // this used to work, still under investigation // auto chaDaughter = kinkcandidate.template chaDau_as(); - auto chaDaughter = tracks.rawIteratorAt(kinkcandidate.chaDauId() - tracks.offset()); + auto chaDaughter = tracks.rawIteratorAt(kinkCandidate.chaDauId() - tracks.offset()); mChaDauManager.template fill(chaDaughter, tracks); if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { - fillAnalysis(kinkcandidate); + fillAnalysis(kinkCandidate); } if constexpr (isFlagSet(mode, modes::Mode::kQa)) { - fillQa(kinkcandidate); + fillQa(kinkCandidate); + } + } + + template + void fill(T1 const& kinkCandidate, T2 const& tracks, T3 const& mcParticles, T4 const& mcMothers, T5 const& mcPartonicMothers) + { + auto chaDaughter = tracks.rawIteratorAt(kinkCandidate.chaDauId() - tracks.offset()); + mChaDauManager.template fill(chaDaughter, tracks, mcParticles, mcMothers, mcPartonicMothers); + if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { + fillAnalysis(kinkCandidate); + } + if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { + fillQa(kinkCandidate); + } + if constexpr (modes::isFlagSet(mode, modes::Mode::kMc)) { + fillMc(kinkCandidate, mcParticles, mcMothers, mcPartonicMothers); } } @@ -240,6 +370,24 @@ class KinkHistManager mPlot2d = KinkConfBinningQa.plot2d.value; } + // for qa and mc + template + void enableOptionalHistograms(T1 const& V0ConfBinningQa, T2 const& V0ConfBinningMc) + { + this->enableOptionalHistograms(V0ConfBinningQa); + + mPlotOrigins = V0ConfBinningMc.plotOrigins.value; + mPlotNSecondaries = V0ConfBinningMc.pdgCodesForMothersOfSecondary.value.size(); + + for (std::size_t i = 0; i < MaxSecondary; i++) { + if (i < V0ConfBinningMc.pdgCodesForMothersOfSecondary.value.size()) { + mPdgCodesSecondaryMother.at(i) = std::abs(V0ConfBinningMc.pdgCodesForMothersOfSecondary.value.at(i)); + } else { + mPdgCodesSecondaryMother.at(i) = 0; + } + } + } + void initAnalysis(std::map> const& KinkSpecs) { std::string analysisDir = std::string(kinkPrefix) + std::string(AnalysisDir); @@ -271,6 +419,36 @@ class KinkHistManager } } + void initMc(std::map> const& KinkSpecs) + { + std::string mcDir = std::string(kinkPrefix) + std::string(McDir); + mHistogramRegistry->add(mcDir + getHistNameV2(kTruePt, HistTable), getHistDesc(kTruePt, HistTable), getHistType(kTruePt, HistTable), {KinkSpecs.at(kTruePt)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueEta, HistTable), getHistDesc(kTrueEta, HistTable), getHistType(kTrueEta, HistTable), {KinkSpecs.at(kTrueEta)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTruePhi, HistTable), getHistDesc(kTruePhi, HistTable), getHistType(kTruePhi, HistTable), {KinkSpecs.at(kTruePhi)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kOrigin, HistTable), getHistDesc(kOrigin, HistTable), getHistType(kOrigin, HistTable), {KinkSpecs.at(kOrigin)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kPdg, HistTable), getHistDesc(kPdg, HistTable), getHistType(kPdg, HistTable), {KinkSpecs.at(kPdg)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kPdgMother, HistTable), getHistDesc(kPdgMother, HistTable), getHistType(kPdgMother, HistTable), {KinkSpecs.at(kPdgMother)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kPdgPartonicMother, HistTable), getHistDesc(kPdgPartonicMother, HistTable), getHistType(kPdgPartonicMother, HistTable), {KinkSpecs.at(kPdgPartonicMother)}); + + if (mPlotOrigins) { + mHistogramRegistry->add(mcDir + getHistNameV2(kNoMcParticle, HistTable), getHistDesc(kNoMcParticle, HistTable), getHistType(kNoMcParticle, HistTable), {KinkSpecs.at(kNoMcParticle)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kPrimary, HistTable), getHistDesc(kPrimary, HistTable), getHistType(kPrimary, HistTable), {KinkSpecs.at(kPrimary)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kFromWrongCollision, HistTable), getHistDesc(kFromWrongCollision, HistTable), getHistType(kFromWrongCollision, HistTable), {KinkSpecs.at(kFromWrongCollision)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kFromMaterial, HistTable), getHistDesc(kFromMaterial, HistTable), getHistType(kFromMaterial, HistTable), {KinkSpecs.at(kFromMaterial)}); + + if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel1) { + mHistogramRegistry->add(mcDir + getHistNameV2(kSecondary1, HistTable), getHistDesc(kSecondary1, HistTable), getHistType(kSecondary1, HistTable), {KinkSpecs.at(kSecondary1)}); + } + if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel2) { + mHistogramRegistry->add(mcDir + getHistNameV2(kSecondary2, HistTable), getHistDesc(kSecondary2, HistTable), getHistType(kSecondary2, HistTable), {KinkSpecs.at(kSecondary2)}); + } + if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel3) { + mHistogramRegistry->add(mcDir + getHistNameV2(kSecondary3, HistTable), getHistDesc(kSecondary3, HistTable), getHistType(kSecondary3, HistTable), {KinkSpecs.at(kSecondary3)}); + } + mHistogramRegistry->add(mcDir + getHistNameV2(kSecondaryOther, HistTable), getHistDesc(kSecondaryOther, HistTable), getHistType(kSecondaryOther, HistTable), {KinkSpecs.at(kSecondaryOther)}); + } + } + /// Fill histograms for kink candidates /// \param kinkcandidate Kink candidate to fill histograms for template @@ -309,9 +487,84 @@ class KinkHistManager } } + template + void fillMc(T1 const& kinkCandidate, T2 const& /*mcParticles*/, T3 const& /*mcMothers*/, T4 const& /*mcPartonicMothers*/) + { + // No MC Particle + if (!kinkCandidate.has_fMcParticle()) { + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kPdg, HistTable)), 0); + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kOrigin, HistTable)), static_cast(modes::McOrigin::kNoMcParticle)); + if (mPlotOrigins) { + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kNoMcParticle, HistTable)), kinkCandidate.pt(), kinkCandidate.kinkAngle()); + } + return; + } + + // Retrieve MC particle + auto mcParticle = kinkCandidate.template fMcParticle_as(); + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kTruePt, HistTable)), mcParticle.pt()); + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kTrueEta, HistTable)), mcParticle.eta()); + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kTruePhi, HistTable)), mcParticle.phi()); + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kOrigin, HistTable)), mcParticle.origin()); + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kPdg, HistTable)), mcParticle.pdgCode()); + + // Mother PDG + if (kinkCandidate.has_fMcMother()) { + auto mother = kinkCandidate.template fMcMother_as(); + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kPdgMother, HistTable)), mother.pdgCode()); + } else { + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kPdgMother, HistTable)), 0); + } + + // Partonic Mother PDG + if (kinkCandidate.has_fMcPartMoth()) { + auto partonicMother = kinkCandidate.template fMcPartMoth_as(); + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kPdgPartonicMother, HistTable)), partonicMother.pdgCode()); + } else { + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kPdgPartonicMother, HistTable)), 0); + } + + // Plot origins + if (mPlotOrigins) { + switch (static_cast(mcParticle.origin())) { + case modes::McOrigin::kPhysicalPrimary: + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kPrimary, HistTable)), kinkCandidate.pt(), kinkCandidate.kinkAngle()); + break; + case modes::McOrigin::kFromWrongCollision: + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kFromWrongCollision, HistTable)), kinkCandidate.pt(), kinkCandidate.kinkAngle()); + break; + case modes::McOrigin::kFromMaterial: + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kFromMaterial, HistTable)), kinkCandidate.pt(), kinkCandidate.kinkAngle()); + break; + case modes::McOrigin::kFromSecondaryDecay: + if (kinkCandidate.has_fMcMother()) { + auto mother = kinkCandidate.template fMcMother_as(); + int motherPdgCode = std::abs(mother.pdgCode()); + // Switch on PDG of the mother + if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel1 && motherPdgCode == mPdgCodesSecondaryMother[0]) { + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kSecondary1, HistTable)), kinkCandidate.pt(), kinkCandidate.kinkAngle()); + } else if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel2 && motherPdgCode == mPdgCodesSecondaryMother[1]) { + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kSecondary2, HistTable)), kinkCandidate.pt(), kinkCandidate.kinkAngle()); + } else if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel3 && motherPdgCode == mPdgCodesSecondaryMother[2]) { + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kSecondary3, HistTable)), kinkCandidate.pt(), kinkCandidate.kinkAngle()); + } else { + mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kSecondaryOther, HistTable)), kinkCandidate.pt(), kinkCandidate.kinkAngle()); + } + } + break; + default: + // Unknown origin → safely ignore + break; + } + } + } + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; trackhistmanager::TrackHistManager mChaDauManager; bool mPlot2d = true; + bool mPlotOrigins = false; + int mPlotNSecondaries = 0; + std::array mPdgCodesSecondaryMother = {0}; }; }; // namespace kinkhistmanager }; // namespace o2::analysis::femto diff --git a/PWGCF/Femto/Core/mcBuilder.h b/PWGCF/Femto/Core/mcBuilder.h index a872f45de00..1a59e35f65b 100644 --- a/PWGCF/Femto/Core/mcBuilder.h +++ b/PWGCF/Femto/Core/mcBuilder.h @@ -52,6 +52,8 @@ struct McBuilderProducts : o2::framework::ProducesGroup { o2::framework::Produces producedTrackLabels; o2::framework::Produces producedLambdaLabels; o2::framework::Produces producedK0shortLabels; + o2::framework::Produces producedSigmaLabels; + o2::framework::Produces producedSigmaPlusLabels; }; struct ConfMcTables : o2::framework::ConfigurableGroup { @@ -65,6 +67,8 @@ struct ConfMcTables : o2::framework::ConfigurableGroup { o2::framework::Configurable producedTrackLabels{"producedTrackLabels", -1, "Produce track labels (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable producedLambdaLabels{"producedLambdaLabels", -1, "Produce lambda labels (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable producedK0shortLabels{"producedK0shortLabels", -1, "Produce k0short labels (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable producedSigmaLabels{"producedSigmaLabels", -1, "Produce k0short labels (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable producedSigmaPlusLabels{"producedSigmaPlusLabels", -1, "Produce k0short labels (-1: auto; 0 off; 1 on)"}; }; class McBuilder @@ -85,8 +89,10 @@ class McBuilder mProduceCollisionLabels = utils::enableTable("FColLabels", table.producedCollisionLabels.value, initContext); mProduceTrackLabels = utils::enableTable("FTrackLabels", table.producedTrackLabels.value, initContext); - mProduceLambdaLabels = utils::enableTable("FLambdaLabels", table.producedTrackLabels.value, initContext); - mProduceK0shortLabels = utils::enableTable("FK0shortLabels", table.producedTrackLabels.value, initContext); + mProduceLambdaLabels = utils::enableTable("FLambdaLabels", table.producedLambdaLabels.value, initContext); + mProduceK0shortLabels = utils::enableTable("FK0shortLabels", table.producedK0shortLabels.value, initContext); + mProduceSigmaLabels = utils::enableTable("FSigmaLabels", table.producedSigmaLabels.value, initContext); + mProduceSigmaPlusLabels = utils::enableTable("FSigmaPlusLabels", table.producedSigmaPlusLabels.value, initContext); if (mProduceMcCollisions || mProduceMcParticles || mProduceMcMothers || mProduceMcPartonicMothers || mProduceCollisionLabels || mProduceTrackLabels || mProduceLambdaLabels || mProduceK0shortLabels) { mFillAnyTable = true; @@ -422,7 +428,195 @@ class McBuilder mK0shortToMcPartonicMap[k0shortIndex] = partonicRow; } } - mcProducts.producedTrackLabels(mcParticleRow, mothersRow, partonicRow); + mcProducts.producedK0shortLabels(mcParticleRow, mothersRow, partonicRow); + } + + template + void fillMcSigmaWithLabel(T1 const& col, T2 const& mcCols, T3 const& sigma, T4 const& sigmaDaughter, T5 const& mcParticles, T6& mcProducts) + { + if (!mProduceSigmaLabels) { + return; + } + + if (!sigmaDaughter.has_mcParticle()) { + mcProducts.producedSigmaLabels(-1, -1, -1); + return; + } + + auto mcKinkDaughter = sigmaDaughter.template mcParticle_as(); + auto mcKinkDaughterMothers = mcKinkDaughter.template mothers_as(); + + if (!mcKinkDaughter.has_mothers() && !mcKinkDaughterMothers.empty()) { + mcProducts.producedSigmaLabels(-1, -1, -1); + return; + } + + // we get the mc kink partilce via the mother of the kink daughter + auto mcParticle = mcKinkDaughterMothers.front(); + auto mcCol = mcParticle.template mcCollision_as(); + + int64_t particleIndex = mcParticle.globalIndex(); + int64_t sigmaIndex = sigma.globalIndex(); + + int64_t mcParticleRow = -1; + + // MC PARTICLE + auto itP = mSigmaToMcParticleMap.find(particleIndex); + if (itP != mSigmaToMcParticleMap.end()) { + mcParticleRow = itP->second; + } else { + auto origin = this->getOrigin(col, mcCols, mcParticle); + int64_t mcColId = this->getMcColId(mcCol, mcProducts); + + mcProducts.producedMcParticles( + mcColId, + static_cast(origin), + mcParticle.pdgCode(), + mcParticle.pt() * utils::signum(mcParticle.pdgCode()), + mcParticle.eta(), + mcParticle.phi()); + + mcParticleRow = mcProducts.producedMcParticles.lastIndex(); + mSigmaToMcParticleMap[particleIndex] = mcParticleRow; + } + + // mothers (fill only if exists) + int64_t mothersRow = -1; + auto itM = mSigmaToMcMotherMap.find(sigmaIndex); + + if (itM != mSigmaToMcMotherMap.end()) { + mothersRow = itM->second; + } else { + + auto mothers = mcParticle.template mothers_as(); + bool motherExists = mcParticle.has_mothers() && !mothers.empty(); + + if (motherExists) { + int motherPdg = mothers.front().pdgCode(); // PDG code is ALWAYS valid if the mother exists + + mcProducts.producedMothers(motherPdg); + mothersRow = mcProducts.producedMothers.lastIndex(); + mSigmaToMcMotherMap[sigmaIndex] = mothersRow; + } + } + + // partonic mother (fill only if exists) + int64_t partonicRow = -1; + auto itPM = mSigmaToMcPartonicMap.find(sigmaIndex); + + if (itPM != mSigmaToMcPartonicMap.end()) { + partonicRow = itPM->second; + } else { + int partIdx = -1; + if (mcParticle.has_mothers()) { + partIdx = this->findFirstPartonicMother(mcParticle, mcParticles); + } + + bool partonicExists = (partIdx >= 0); + + if (partonicExists) { + int partonicPdg = mcParticles.iteratorAt(partIdx).pdgCode(); + + mcProducts.producedPartonicMothers(partonicPdg); + partonicRow = mcProducts.producedPartonicMothers.lastIndex(); + mSigmaToMcPartonicMap[sigmaIndex] = partonicRow; + } + } + mcProducts.producedSigmaLabels(mcParticleRow, mothersRow, partonicRow); + } + + template + void fillMcSigmaPlusWithLabel(T1 const& col, T2 const& mcCols, T3 const& sigmaPlus, T4 const& sigmaPlusDaughter, T5 const& mcParticles, T6& mcProducts) + { + if (!mProduceSigmaPlusLabels) { + return; + } + + if (!sigmaPlusDaughter.has_mcParticle()) { + mcProducts.producedSigmaPlusLabels(-1, -1, -1); + return; + } + + auto mcKinkDaughter = sigmaPlusDaughter.template mcParticle_as(); + auto mcKinkDaughterMothers = mcKinkDaughter.template mothers_as(); + + if (!mcKinkDaughter.has_mothers() && !mcKinkDaughterMothers.empty()) { + mcProducts.producedSigmaPlusLabels(-1, -1, -1); + return; + } + + // we get the mc kink partilce via the mother of the kink daughter + auto mcParticle = mcKinkDaughterMothers.front(); + auto mcCol = mcParticle.template mcCollision_as(); + + int64_t particleIndex = mcParticle.globalIndex(); + int64_t sigmaIndex = sigmaPlus.globalIndex(); + + int64_t mcParticleRow = -1; + + // MC PARTICLE + auto itP = mSigmaPlusToMcParticleMap.find(particleIndex); + if (itP != mSigmaPlusToMcParticleMap.end()) { + mcParticleRow = itP->second; + } else { + auto origin = this->getOrigin(col, mcCols, mcParticle); + int64_t mcColId = this->getMcColId(mcCol, mcProducts); + + mcProducts.producedMcParticles( + mcColId, + static_cast(origin), + mcParticle.pdgCode(), + mcParticle.pt() * utils::signum(mcParticle.pdgCode()), + mcParticle.eta(), + mcParticle.phi()); + + mcParticleRow = mcProducts.producedMcParticles.lastIndex(); + mSigmaPlusToMcParticleMap[particleIndex] = mcParticleRow; + } + + // mothers (fill only if exists) + int64_t mothersRow = -1; + auto itM = mSigmaPlusToMcMotherMap.find(sigmaIndex); + + if (itM != mSigmaPlusToMcMotherMap.end()) { + mothersRow = itM->second; + } else { + + auto mothers = mcParticle.template mothers_as(); + bool motherExists = mcParticle.has_mothers() && !mothers.empty(); + + if (motherExists) { + int motherPdg = mothers.front().pdgCode(); // PDG code is ALWAYS valid if the mother exists + + mcProducts.producedMothers(motherPdg); + mothersRow = mcProducts.producedMothers.lastIndex(); + mSigmaPlusToMcMotherMap[sigmaIndex] = mothersRow; + } + } + + // partonic mother (fill only if exists) + int64_t partonicRow = -1; + auto itPM = mSigmaPlusToMcPartonicMap.find(sigmaIndex); + + if (itPM != mSigmaPlusToMcPartonicMap.end()) { + partonicRow = itPM->second; + } else { + int partIdx = -1; + if (mcParticle.has_mothers()) { + partIdx = this->findFirstPartonicMother(mcParticle, mcParticles); + } + + bool partonicExists = (partIdx >= 0); + + if (partonicExists) { + int partonicPdg = mcParticles.iteratorAt(partIdx).pdgCode(); + + mcProducts.producedPartonicMothers(partonicPdg); + partonicRow = mcProducts.producedPartonicMothers.lastIndex(); + mSigmaPlusToMcPartonicMap[sigmaIndex] = partonicRow; + } + } + mcProducts.producedSigmaPlusLabels(mcParticleRow, mothersRow, partonicRow); } template @@ -488,8 +682,18 @@ class McBuilder mK0shortToMcParticleMap.clear(); mK0shortToMcMotherMap.clear(); mK0shortToMcPartonicMap.clear(); + + mSigmaToMcParticleMap.clear(); + mSigmaToMcMotherMap.clear(); + mSigmaToMcPartonicMap.clear(); + + mSigmaPlusToMcParticleMap.clear(); + mSigmaPlusToMcMotherMap.clear(); + mSigmaPlusToMcPartonicMap.clear(); } + bool fillAnyTable() const { return mFillAnyTable; } + private: bool mPassThrough = false; bool mFillAnyTable = false; @@ -502,6 +706,8 @@ class McBuilder bool mProduceTrackLabels = false; bool mProduceLambdaLabels = false; bool mProduceK0shortLabels = false; + bool mProduceSigmaLabels = false; + bool mProduceSigmaPlusLabels = false; std::unordered_map mCollisionMap; @@ -516,6 +722,14 @@ class McBuilder std::unordered_map mK0shortToMcParticleMap; std::unordered_map mK0shortToMcMotherMap; std::unordered_map mK0shortToMcPartonicMap; + + std::unordered_map mSigmaToMcParticleMap; + std::unordered_map mSigmaToMcMotherMap; + std::unordered_map mSigmaToMcPartonicMap; + + std::unordered_map mSigmaPlusToMcParticleMap; + std::unordered_map mSigmaPlusToMcMotherMap; + std::unordered_map mSigmaPlusToMcPartonicMap; }; } // namespace mcbuilder diff --git a/PWGCF/Femto/Core/trackHistManager.h b/PWGCF/Femto/Core/trackHistManager.h index 27352a15689..d8d68abac2a 100644 --- a/PWGCF/Femto/Core/trackHistManager.h +++ b/PWGCF/Femto/Core/trackHistManager.h @@ -269,10 +269,12 @@ struct ConfTrackMcBinning : o2::framework::ConfigurableGroup { constexpr const char PrefixTrackMcBinning1[] = "TrackMcBinning1"; constexpr const char PrefixV0PosDauMcBinning[] = "V0PosDauMcBinning"; constexpr const char PrefixV0NegDauMcBinning[] = "V0NegDauMcBinning"; +constexpr const char PrefixKinkChaDauMcBinning[] = "KinkChaDauMcBinning"; using ConfTrackMcBinning1 = ConfTrackMcBinning; using ConfV0PosDauMcBinning = ConfTrackMcBinning; using ConfV0NegDauMcBinning = ConfTrackMcBinning; +using ConfKinkChaDauMcBinning = ConfTrackMcBinning; // must be in sync with enum TrackVariables // the enum gives the correct index in the array diff --git a/PWGCF/Femto/Core/v0HistManager.h b/PWGCF/Femto/Core/v0HistManager.h index ca59e6f1f4b..d57c3e9e9e8 100644 --- a/PWGCF/Femto/Core/v0HistManager.h +++ b/PWGCF/Femto/Core/v0HistManager.h @@ -177,9 +177,9 @@ constexpr std::array, kV0HistLast> HistTable = { {kK0shortMassVsAntiLambdaMass, o2::framework::kTH2F, "hK0shortMassVsAntiLambdaMass", "K^{0}_{S} mass vs #bar{#Lambda} mass; m_{#pi^{+}#pi^{-}} (GeV/#it{c}^{2}); m_{#bar{p}#pi^{+}} (GeV/#it{c}^{2})"}, {kLambdaMassVsAntiLambdaMass, o2::framework::kTH2F, "hLambdaMassVsAntiLambdaMass", "#Lambda mass vs #bar{#Lambda}; m_{p#pi^{-}} (GeV/#it{c}^{2}); m_{#bar{p}#pi^{+}} (GeV/#it{c}^{2})"}, {kOrigin, o2::framework::kTH1F, "hOrigin", "Status Codes (=Origin); Status Code; Entries"}, - {kPdg, o2::framework::kTH1F, "hPdg", "PDG Codes of selected tracks; PDG Code; Entries"}, - {kPdgMother, o2::framework::kTH1F, "hPdgMother", "PDG Codes of mother of selected tracks; PDG Code; Entries"}, - {kPdgPartonicMother, o2::framework::kTH1F, "hPdgPartonicMother", "PDG Codes of partonic mother selected tracks; PDG Code; Entries"}, + {kPdg, o2::framework::kTH1F, "hPdg", "PDG Codes of reconstructed v0; PDG Code; Entries"}, + {kPdgMother, o2::framework::kTH1F, "hPdgMother", "PDG Codes of mother of reconstructed v0; PDG Code; Entries"}, + {kPdgPartonicMother, o2::framework::kTH1F, "hPdgPartonicMother", "PDG Codes of partonic mother of reconstructed v0; PDG Code; Entries"}, {kTruePt, o2::framework::kTH1F, "hTruePt", "True transverse momentum; p_{T} (GeV/#it{c}); Entries"}, {kTrueEta, o2::framework::kTH1F, "hTrueEta", "True pseudorapdity; #eta; Entries"}, {kTruePhi, o2::framework::kTH1F, "hTruePhi", "True azimuthal angle; #varphi; Entries"}, @@ -407,6 +407,7 @@ class V0HistManager } private: + // for qa template void enableOptionalHistograms(T1 const& V0ConfBinningQa) @@ -418,7 +419,7 @@ class V0HistManager template void enableOptionalHistograms(T1 const& V0ConfBinningQa, T2 const& V0ConfBinningMc) { - mPlot2d = V0ConfBinningQa.plot2d.value; + this->enableOptionalHistograms(V0ConfBinningQa); mPlotOrigins = V0ConfBinningMc.plotOrigins.value; mPlotNSecondaries = V0ConfBinningMc.pdgCodesForMothersOfSecondary.value.size(); diff --git a/PWGCF/Femto/DataModel/FemtoTables.h b/PWGCF/Femto/DataModel/FemtoTables.h index 87ead7ec293..81d2e4c7d24 100644 --- a/PWGCF/Femto/DataModel/FemtoTables.h +++ b/PWGCF/Femto/DataModel/FemtoTables.h @@ -750,5 +750,15 @@ DECLARE_SOA_TABLE(FK0shortLabels, "AOD", "FK0SHORTLABEL", femtolabels::FMcMotherId, femtolabels::FMcPartMothId); +DECLARE_SOA_TABLE(FSigmaLabels, "AOD", "FSIGMALABEL", + femtolabels::FMcParticleId, + femtolabels::FMcMotherId, + femtolabels::FMcPartMothId); + +DECLARE_SOA_TABLE(FSigmaPlusLabels, "AOD", "FSIGMAPLUSLABEL", + femtolabels::FMcParticleId, + femtolabels::FMcMotherId, + femtolabels::FMcPartMothId); + } // namespace o2::aod #endif // PWGCF_FEMTO_DATAMODEL_FEMTOTABLES_H_ diff --git a/PWGCF/Femto/TableProducer/femtoProducer.cxx b/PWGCF/Femto/TableProducer/femtoProducer.cxx index 8fb571f151d..f72870f2d28 100644 --- a/PWGCF/Femto/TableProducer/femtoProducer.cxx +++ b/PWGCF/Femto/TableProducer/femtoProducer.cxx @@ -180,12 +180,15 @@ struct FemtoProducer { if ((xiBuilder.fillAnyTable() || omegaBuilder.fillAnyTable()) && (!doprocessTracksV0sCascadesRun3pp && !doprocessTracksV0sCascadesKinksRun3pp)) { LOG(fatal) << "At least one cascade table is enabled, but wrong process function is enabled. Breaking..."; } - if ((lambdaBuilder.fillAnyTable() || antilambdaBuilder.fillAnyTable() || k0shortBuilder.fillAnyTable()) && (!doprocessTracksV0sCascadesRun3pp && !doprocessTracksV0sRun3pp && !doprocessTracksV0sCascadesKinksRun3pp)) { + if ((lambdaBuilder.fillAnyTable() || antilambdaBuilder.fillAnyTable() || k0shortBuilder.fillAnyTable()) && (!doprocessTracksV0sCascadesRun3pp && !doprocessTracksV0sRun3pp && !doprocessTracksV0sCascadesKinksRun3pp && !doprocessTracksV0sRun3ppMc)) { LOG(fatal) << "At least one v0 table is enabled, but wrong process function is enabled. Breaking..."; } - if ((sigmaBuilder.fillAnyTable() || sigmaPlusBuilder.fillAnyTable()) && (!doprocessTracksKinksRun3pp && !doprocessTracksV0sCascadesKinksRun3pp)) { + if ((sigmaBuilder.fillAnyTable() || sigmaPlusBuilder.fillAnyTable()) && (!doprocessTracksKinksRun3pp && !doprocessTracksV0sCascadesKinksRun3pp && !doprocessTracksKinksRun3ppMc)) { LOG(fatal) << "At least one kink table is enabled, but wrong process function is enabled. Breaking..."; } + if (mcBuilder.fillAnyTable() && (!doprocessTracksV0sRun3ppMc && !doprocessTracksKinksRun3ppMc)) { + LOG(fatal) << "At least one mc table is enabled, but wrong process function is enabled. Breaking..."; + } // init ccdb ccdb->setURL(confCcdb.ccdbUrl.value); @@ -221,6 +224,8 @@ struct FemtoProducer { // configure mcBuilder mcBuilder.init(confMc, confMcTables, context); + + hRegistry.print(); } // Core implementations @@ -241,6 +246,7 @@ struct FemtoProducer { template bool processMcCollisions(T1 const& col, T2 const& mcCols, T3 const& /* bcs*/, T4 const& tracks) { + mcBuilder.reset(); collisionBuilder.reset(); auto bc = col.template bc_as(); collisionBuilder.initCollision(bc, col, tracks, ccdb, hRegistry); @@ -292,8 +298,6 @@ struct FemtoProducer { k0shortBuilder.fillMcV0s(col, collisionBuilder, collisionBuilderProducts, mcCols, trackBuilderProducts, v0builderProducts, v0s, tracks, tracksWithItsPid, trackBuilder, mcParticles, mcBuilder, mcProducts); } - // processMcV0s(col, mcCols, tracks, tracksWithItsPid, v0s, mcParticles); - // add kinks template void processKinks(T1 const& col, T2 const& tracks, T3 const& tracksWithItsPid, T4 const& kinks) @@ -302,14 +306,12 @@ struct FemtoProducer { sigmaPlusBuilder.fillKinks(col, collisionBuilder, collisionBuilderProducts, trackBuilderProducts, kinkBuilderProducts, kinks, tracks, tracksWithItsPid, trackBuilder); } - // TODO - // prepare to add kinks in MC - // template - // void processMcKinks(T1 const& col, T2 const& mcCols, T3 const& tracks, T4 const& tracksWithItsPid, T5 const& kinks, T6 const& mcParticles) - // { - // sigmaBuilder.fillMcKinks(col, collisionBuilder, collisionBuilderProducts, trackBuilderProducts, kinkBuilderProducts, kinks, tracks, tracksWithItsPid, trackBuilder); - // sigmaPlusBuilder.fillMcKinks(col, collisionBuilder, collisionBuilderProducts, trackBuilderProducts, kinkBuilderProducts, kinks, tracks, tracksWithItsPid, trackBuilder); - // } + template + void processMcKinks(T1 const& col, T2 const& mcCols, T3 const& tracks, T4 const& tracksWithItsPid, T5 const& kinks, T6 const& mcParticles) + { + sigmaBuilder.fillMcKinks(col, collisionBuilder, collisionBuilderProducts, mcCols, trackBuilderProducts, kinkBuilderProducts, kinks, tracks, tracksWithItsPid, trackBuilder, mcParticles, mcBuilder, mcProducts); + sigmaPlusBuilder.fillMcKinks(col, collisionBuilder, collisionBuilderProducts, mcCols, trackBuilderProducts, kinkBuilderProducts, kinks, tracks, tracksWithItsPid, trackBuilder, mcParticles, mcBuilder, mcProducts); + } // add cascades template @@ -422,7 +424,6 @@ struct FemtoProducer { } auto tracksWithItsPid = o2::soa::Attach(tracks); - mcBuilder.reset(); processMcTracks(col, mcCols, tracks, tracksWithItsPid, mcParticles); } PROCESS_SWITCH(FemtoProducer, processTracksRun3ppMc, "Provide reconstructed and generated Tracks", false); @@ -440,17 +441,17 @@ struct FemtoProducer { } auto tracksWithItsPid = o2::soa::Attach(tracks); - mcBuilder.reset(); processMcTracks(col, mcCols, tracks, tracksWithItsPid, mcParticles); processMcV0s(col, mcCols, tracks, tracksWithItsPid, v0s, mcParticles); } - PROCESS_SWITCH(FemtoProducer, processTracksV0sRun3ppMc, "Provide reconstructed and generated Tracks and v0s", false); + PROCESS_SWITCH(FemtoProducer, processTracksV0sRun3ppMc, "Provide reconstructed and generated tracks and v0s", false); // process monte carlo tracks and v0s void processTracksKinksRun3ppMc(consumeddata::Run3PpMcRecoCollisions::iterator const& col, consumeddata::Run3PpMcGenCollisions const& mcCols, BCsWithTimestamps const& bcs, consumeddata::Run3McRecoTracks const& tracks, + consumeddata::Run3Kinks const& kinks, consumeddata::Run3McGenParticles const& mcParticles) { if (!processMcCollisions(col, mcCols, bcs, tracks)) { @@ -458,11 +459,10 @@ struct FemtoProducer { } auto tracksWithItsPid = o2::soa::Attach(tracks); - mcBuilder.reset(); processMcTracks(col, mcCols, tracks, tracksWithItsPid, mcParticles); - processMcV0s(col, mcCols, tracks, tracksWithItsPid, v0s, mcParticles); + processMcKinks(col, mcCols, tracks, tracksWithItsPid, kinks, mcParticles); } - PROCESS_SWITCH(FemtoProducer, processTracksV0sRun3ppMc, "Provide reconstructed and generated Tracks and v0s", false); + PROCESS_SWITCH(FemtoProducer, processTracksKinksRun3ppMc, "Provide reconstructed and generated tracks and kinks", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/Femto/Tasks/femtoKinkQa.cxx b/PWGCF/Femto/Tasks/femtoKinkQa.cxx index b2d84d2ba04..2dd445adf5a 100644 --- a/PWGCF/Femto/Tasks/femtoKinkQa.cxx +++ b/PWGCF/Femto/Tasks/femtoKinkQa.cxx @@ -45,35 +45,46 @@ using namespace o2::analysis::femto; struct FemtoKinkQa { - // setup for collisions - collisionbuilder::ConfCollisionSelection collisionSelection; - Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); - - colhistmanager::CollisionHistManager colHistManager; - colhistmanager::ConfCollisionBinning confCollisionBinning; - colhistmanager::ConfCollisionQaBinning confCollisionQaBinning; - + // setup tables using FemtoCollisions = o2::soa::Join; - using FemtoCollision = FemtoCollisions::iterator; - using FilteredFemtoCollisions = o2::soa::Filtered; using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; + using FemtoCollisionsWithLabel = o2::soa::Join; + using FilteredFemtoCollisionsWithLabel = o2::soa::Filtered; + using FilteredFemtoCollisionWithLabel = FilteredFemtoCollisionsWithLabel::iterator; + // Define kink/sigma tables (joining tables for comprehensive information) using FemtoSigmas = o2::soa::Join; using FemtoSigmaPlus = o2::soa::Join; using FemtoTracks = o2::soa::Join; + using FemtoSigmasWithLabel = o2::soa::Join; + using FemtoSigmaPlusWithLabel = o2::soa::Join; + using FemtoTracksWithLabel = o2::soa::Join; + SliceCache cache; + // setup for collisions + collisionbuilder::ConfCollisionSelection collisionSelection; + Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + + colhistmanager::CollisionHistManager colHistManager; + colhistmanager::ConfCollisionBinning confCollisionBinning; + colhistmanager::ConfCollisionQaBinning confCollisionQaBinning; + // setup for sigmas kinkbuilder::ConfSigmaSelection1 confSigmaSelection; Partition sigmaPartition = MAKE_SIGMA_PARTITION(confSigmaSelection); Preslice perColSigmas = femtobase::stored::fColId; + Partition sigmaWithLabelPartition = MAKE_SIGMA_PARTITION(confSigmaSelection); + Preslice perColSigmasWithLabel = femtobase::stored::fColId; + kinkhistmanager::ConfSigmaBinning1 confSigmaBinning; kinkhistmanager::ConfSigmaQaBinning1 confSigmaQaBinning; + kinkhistmanager::ConfSigmaMcBinning confSigmaMcBinning; kinkhistmanager::KinkHistManager< kinkhistmanager::PrefixSigmaQa, trackhistmanager::PrefixKinkChaDaughterQa, @@ -86,8 +97,12 @@ struct FemtoKinkQa { Partition sigmaPlusPartition = MAKE_SIGMAPLUS_PARTITION(confSigmaPlusSelection); Preslice perColSigmaPlus = femtobase::stored::fColId; + Partition sigmaPlusWithLabelPartition = MAKE_SIGMAPLUS_PARTITION(confSigmaSelection); + Preslice perColSigmaPlussWithLabel = femtobase::stored::fColId; + kinkhistmanager::ConfSigmaPlusBinning1 confSigmaPlusBinning; kinkhistmanager::ConfSigmaPlusQaBinning1 confSigmaPlusQaBinning; + kinkhistmanager::ConfSigmaPlusMcBinning confSigmaPlusMcBinning; kinkhistmanager::KinkHistManager< kinkhistmanager::PrefixSigmaPlusQa, trackhistmanager::PrefixKinkChaDaughterQa, @@ -97,29 +112,42 @@ struct FemtoKinkQa { // setup for daughters trackhistmanager::ConfKinkChaDauBinning confKinkChaDaughterBinning; trackhistmanager::ConfKinkChaDauQaBinning confKinkChaDaughterQaBinning; + trackhistmanager::ConfKinkChaDauMcBinning confKinkChaDaughterMcBinning; HistogramRegistry hRegistry{"FemtoKinkQa", {}, OutputObjHandlingPolicy::AnalysisObject}; void init(InitContext&) { - if ((doprocessSigma + doprocessSigmaPlus > 1)) { + if ((doprocessSigma + doprocessSigmaMc + doprocessSigmaPlus + doprocessSigmaPlusMc) > 1) { LOG(fatal) << "Only one process can be activated"; } - // create a map for histogram specs - auto colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); - colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); - - auto chaDauHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confKinkChaDaughterBinning, confKinkChaDaughterQaBinning); - - if (doprocessSigma) { - auto sigmaHistSpec = kinkhistmanager::makeKinkQaHistSpecMap(confSigmaBinning, confSigmaQaBinning); - sigmaHistManager.init(&hRegistry, sigmaHistSpec, confSigmaQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); - } - - if (doprocessSigmaPlus) { - auto sigmaPlusHistSpec = kinkhistmanager::makeKinkQaHistSpecMap(confSigmaPlusBinning, confSigmaPlusQaBinning); - sigmaPlusHistManager.init(&hRegistry, sigmaPlusHistSpec, confSigmaPlusQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); + bool processData = doprocessSigma || doprocessSigmaPlus; + + if (processData) { + auto colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); + colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); + auto chaDauHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confKinkChaDaughterBinning, confKinkChaDaughterQaBinning); + if (doprocessSigma) { + auto sigmaHistSpec = kinkhistmanager::makeKinkQaHistSpecMap(confSigmaBinning, confSigmaQaBinning); + sigmaHistManager.init(&hRegistry, sigmaHistSpec, confSigmaQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); + } + if (doprocessSigmaPlus) { + auto sigmaPlusHistSpec = kinkhistmanager::makeKinkQaHistSpecMap(confSigmaPlusBinning, confSigmaPlusQaBinning); + sigmaPlusHistManager.init(&hRegistry, sigmaPlusHistSpec, confSigmaPlusQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); + } + } else { + auto colHistSpec = colhistmanager::makeColMcQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); + colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); + auto chaDauHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confKinkChaDaughterBinning, confKinkChaDaughterQaBinning, confKinkChaDaughterMcBinning); + if (doprocessSigmaMc) { + auto sigmaHistSpec = kinkhistmanager::makeKinkMcQaHistSpecMap(confSigmaBinning, confSigmaQaBinning, confSigmaMcBinning); + sigmaHistManager.init(&hRegistry, sigmaHistSpec, confSigmaQaBinning, confSigmaMcBinning, chaDauHistSpec, confKinkChaDaughterQaBinning, confKinkChaDaughterMcBinning); + } + if (doprocessSigmaPlusMc) { + auto sigmaPlusHistSpec = kinkhistmanager::makeKinkMcQaHistSpecMap(confSigmaPlusBinning, confSigmaPlusQaBinning, confSigmaPlusMcBinning); + sigmaPlusHistManager.init(&hRegistry, sigmaPlusHistSpec, confSigmaPlusQaBinning, confSigmaPlusMcBinning, chaDauHistSpec, confKinkChaDaughterQaBinning, confKinkChaDaughterMcBinning); + } } hRegistry.print(); }; @@ -134,6 +162,16 @@ struct FemtoKinkQa { } PROCESS_SWITCH(FemtoKinkQa, processSigma, "Process sigmas", true); + void processSigmaMc(FilteredFemtoCollisionWithLabel const& col, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmasWithLabel const& /*sigmas*/, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + { + colHistManager.fill(col, mcCols); + auto sigmaSlice = sigmaWithLabelPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + for (auto const& sigma : sigmaSlice) { + sigmaHistManager.fill(sigma, tracks, mcParticles, mcMothers, mcPartonicMothers); + } + } + PROCESS_SWITCH(FemtoKinkQa, processSigmaMc, "Process sigmas", false); + void processSigmaPlus(FilteredFemtoCollision const& col, FemtoSigmaPlus const& /*sigmaplus*/, FemtoTracks const& tracks) { colHistManager.fill(col); @@ -145,6 +183,16 @@ struct FemtoKinkQa { } } PROCESS_SWITCH(FemtoKinkQa, processSigmaPlus, "Process sigma plus", false); + + void processSigmaPlusMc(FilteredFemtoCollisionWithLabel const& col, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmaPlusWithLabel const& /*sigmaPlus*/, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + { + colHistManager.fill(col, mcCols); + auto sigmaPlusSlice = sigmaPlusWithLabelPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + for (auto const& sigmaPlus : sigmaPlusSlice) { + sigmaPlusHistManager.fill(sigmaPlus, tracks, mcParticles, mcMothers, mcPartonicMothers); + } + } + PROCESS_SWITCH(FemtoKinkQa, processSigmaPlusMc, "Process sigmas", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From 0217aa1b82cf9db4163b08bdedf5bffabe7f9f31 Mon Sep 17 00:00:00 2001 From: Anton Riedel Date: Wed, 31 Dec 2025 14:24:02 +0100 Subject: [PATCH 3/4] Feat: fix formatting --- PWGCF/Femto/Core/v0HistManager.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/PWGCF/Femto/Core/v0HistManager.h b/PWGCF/Femto/Core/v0HistManager.h index d57c3e9e9e8..6e2512da15a 100644 --- a/PWGCF/Femto/Core/v0HistManager.h +++ b/PWGCF/Femto/Core/v0HistManager.h @@ -1,4 +1,4 @@ -// Copyright 2019-2025 CERN andphniticopyright holders of ALICE O2. +// Copyright 2019-2025 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. // @@ -407,7 +407,6 @@ class V0HistManager } private: - // for qa template void enableOptionalHistograms(T1 const& V0ConfBinningQa) From 5832b7073dccb7ad5be514585ef8b399b3d3f8f2 Mon Sep 17 00:00:00 2001 From: Anton Riedel Date: Wed, 31 Dec 2025 14:50:19 +0100 Subject: [PATCH 4/4] Fix: remove unused function --- PWGCF/Femto/Core/v0Builder.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/PWGCF/Femto/Core/v0Builder.h b/PWGCF/Femto/Core/v0Builder.h index 8f4b6ff78bc..b70182cac04 100644 --- a/PWGCF/Femto/Core/v0Builder.h +++ b/PWGCF/Femto/Core/v0Builder.h @@ -516,16 +516,6 @@ class V0Builder } } - template - void fillMcV0(T1 const& col, T2& collisionProducts, T3 const& mcCols, T4 const& track, T5 const&, T6& v0Products, T7 const& mcParticles, T8& mcBuilder, T9& mcProducts) - { - if (!mFillAnyTable) { - return; - } - this->template fillLambda(); - mcBuilder.template fillMcV0WithLabel(); - } - bool fillAnyTable() const { return mFillAnyTable; } private: