diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index 0b779485244..cac62250bbe 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -743,6 +743,8 @@ enum ParticleOriginMCTruth { kSecondaryDaughterXistar0, //! Daughter from a Xi*^0 decay kSecondaryDaughterXistarMinus, //! Daughter from a Xi*^- decay kElse, //! none of the above; (NOTE: used to catch bugs. will be removed once MC usage is properly validated) + kSecondaryFromHF, //! Kaon from a charm- or beauty-hadron decay chain + kSecondaryFromLF, //! Kaon from a light-flavour decay without a heavy-flavour ancestor kNOriginMCTruthTypes }; @@ -762,7 +764,9 @@ static constexpr std::string_view ParticleOriginMCTruthName[kNOriginMCTruthTypes "_SecondaryDaughterOmegaMinus", "_SecondaryDaughterXistar0", "_SecondaryDaughterXistarMinus", - "_Else"}; + "_Else", + "_SecondaryFromHF", + "_SecondaryFromLF"}; /// Distinguished between reconstructed and truth enum MCType { diff --git a/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h b/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h index 096b9bb7b28..410e79774a5 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h +++ b/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h @@ -233,6 +233,12 @@ class FemtoDreamParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterLambda").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterSigmaplus").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterOmegaMinus").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + if (std::abs(mPDG) == kKPlus) { + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryFromHF").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryFromLF").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryFromHF").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryFromLF").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + } mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Secondary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); @@ -245,6 +251,10 @@ class FemtoDreamParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); } else { mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + if (std::abs(mPDG) == kKPlus) { + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryFromHF").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryFromLF").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + } mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Secondary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Material").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_WrongCollision").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); @@ -597,6 +607,16 @@ class FemtoDreamParticleHisto mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_Secondary"), part.pt(), part.tempFitVar(), part.dcaZ(), mult); break; + case (o2::aod::femtodreamMCparticle::kSecondaryFromHF): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryFromHF"), part.fdExtMCParticle().motherPDG()); + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryFromHF"), + part.pt(), part.tempFitVar(), part.dcaZ(), mult); + break; + case (o2::aod::femtodreamMCparticle::kSecondaryFromLF): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryFromLF"), part.fdExtMCParticle().motherPDG()); + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryFromLF"), + part.pt(), part.tempFitVar(), part.dcaZ(), mult); + break; case (o2::aod::femtodreamMCparticle::kMaterial): mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_Material"), part.fdExtMCParticle().motherPDG()); mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_Material"), @@ -645,6 +665,14 @@ class FemtoDreamParticleHisto mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_Secondary"), part.pt(), part.tempFitVar()); break; + case (o2::aod::femtodreamMCparticle::kSecondaryFromHF): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryFromHF"), + part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtodreamMCparticle::kSecondaryFromLF): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryFromLF"), + part.pt(), part.tempFitVar()); + break; case (o2::aod::femtodreamMCparticle::kMaterial): mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_Material"), part.pt(), part.tempFitVar()); diff --git a/PWGCF/FemtoDream/Core/femtoDreamUtils.h b/PWGCF/FemtoDream/Core/femtoDreamUtils.h index fde124f5db4..16a7314c380 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamUtils.h +++ b/PWGCF/FemtoDream/Core/femtoDreamUtils.h @@ -18,9 +18,12 @@ #include "PWGCF/DataModel/FemtoDerived.h" +#include "Common/Core/RecoDecay.h" + #include #include +#include #include #include @@ -102,6 +105,28 @@ inline float getMass(int pdgCode) return mass; } +/// Classify true kaons from the correct collision for the DCA templates. +template +inline int getKaonOrigin(T const& particles, typename T::iterator const& particle) +{ + using namespace o2::aod::femtodreamMCparticle; + constexpr int GenFromTransport = -1; + if (particle.getProcess() == TMCProcess::kPHInhelastic && particle.getGenStatusCode() == GenFromTransport) { + return kMaterial; + } + // HF decay products can be physical primaries. Check their ancestry first. + if (RecoDecay::getParticleOrigin(particles, particle) != RecoDecay::OriginType::None) { + return kSecondaryFromHF; + } + if (particle.isPhysicalPrimary()) { + return kPrimary; + } + if (particle.getProcess() == TMCProcess::kPDecay && particle.getGenStatusCode() == GenFromTransport && particle.has_mothers()) { + return kSecondaryFromLF; + } + return kElse; +} + inline int checkDaughterType(o2::aod::femtodreamparticle::ParticleType partType, int motherPDG, int daughterPDG = 0) { int partOrigin = 0; diff --git a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx index dc7eeb02b03..74d01a83f01 100644 --- a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx @@ -466,7 +466,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { } template - void fillMcParticle(CollisionType const& col, ParticleType const& particle, o2::aod::femtodreamparticle::ParticleType fdparttype) + void fillMcParticle(CollisionType const& col, ParticleType const& particle, o2::aod::femtodreamparticle::ParticleType fdparttype, aod::McParticles const& mcParticles) { if (particle.has_mcParticle()) { // get corresponding MC particle and its info @@ -484,6 +484,11 @@ struct HfProducerCharmHadronsTrackFemtoDream { // check if the collision associated with the particle is the same as the analyzed collision by checking their Ids if ((col.has_mcCollision() && (particleMc.mcCollisionId() != col.mcCollisionId())) || !col.has_mcCollision()) { particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kWrongCollision; + } else if (std::abs(pdgCode) == kKPlus) { + particleOrigin = getKaonOrigin(mcParticles, particleMc); + if (!motherparticlesMc.empty()) { + pdgCodeMother = motherparticlesMc.front().pdgCode(); + } // check if particle is primary } else if (particleMc.isPhysicalPrimary()) { particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kPrimary; @@ -537,7 +542,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { } template - bool fillTracksForCharmHadron(CollisionType const& col, TrackType const& tracks) + bool fillTracksForCharmHadron(CollisionType const& col, TrackType const& tracks, aod::McParticles const* mcParticles = nullptr) { std::vector const childIDs = {0, 0}; // these IDs are necessary to keep track of the children @@ -590,14 +595,14 @@ struct HfProducerCharmHadronsTrackFemtoDream { } if constexpr (IsMc) { - fillMcParticle(col, track, o2::aod::femtodreamparticle::ParticleType::kTrack); + fillMcParticle(col, track, o2::aod::femtodreamparticle::ParticleType::kTrack, *mcParticles); } } return fIsTrackFilled; } template - void fillCharmHadronTable(CollisionType const& col, TrackType const& tracks, CandType const& candidates) + void fillCharmHadronTable(CollisionType const& col, TrackType const& tracks, CandType const& candidates, aod::McParticles const* mcParticles = nullptr) { const auto vtxZ = col.posZ(); const auto sizeCand = candidates.size(); @@ -884,7 +889,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { fillTable(2, candidate.isSelDstarToD0Pi(), outputMlDstar.at(0), outputMlDstar.at(1), outputMlDstar.at(2)); } } - isTrackFilled = fillTracksForCharmHadron(col, tracks); + isTrackFilled = fillTracksForCharmHadron(col, tracks, mcParticles); aod::femtodreamcollision::BitMaskType bitTrack = 0; if (isTrackFilled) { @@ -908,7 +913,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { } template - void fillXicHadronTable(CollisionType const& col, TrackType const& tracks, CandType const& candidates, DaughterTrackType const&) + void fillXicHadronTable(CollisionType const& col, TrackType const& tracks, CandType const& candidates, DaughterTrackType const&, aod::McParticles const* mcParticles = nullptr) { const auto vtxZ = col.posZ(); const auto sizeCand = candidates.size(); @@ -1030,7 +1035,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { } } - isTrackFilled = fillTracksForCharmHadron(col, tracks); + isTrackFilled = fillTracksForCharmHadron(col, tracks, mcParticles); aod::femtodreamcollision::BitMaskType bitTrack = 0; if (isTrackFilled) { @@ -1153,25 +1158,25 @@ struct HfProducerCharmHadronsTrackFemtoDream { void processMcD0ToPiK(FemtoFullCollisionMc const& col, aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, - aod::McParticles const&, + aod::McParticles const& mcParticles, CandidateD0Mc const& candidates) { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); - fillCharmHadronTable(col, tracks, candidates); + fillCharmHadronTable(col, tracks, candidates, &mcParticles); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcD0ToPiK, "Provide Mc for D0ToPiK", false); void processMcD0ToPiKWithML(FemtoFullCollisionMc const& col, aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, - aod::McParticles const&, + aod::McParticles const& mcParticles, soa::Join const& candidates) { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); - fillCharmHadronTable(col, tracks, candidates); + fillCharmHadronTable(col, tracks, candidates, &mcParticles); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcD0ToPiKWithML, "Provide Mc for D0ToPiK with ml", false); @@ -1208,25 +1213,25 @@ struct HfProducerCharmHadronsTrackFemtoDream { void processMcDstarToD0Pi(FemtoFullCollisionMc const& col, aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, - aod::McParticles const&, + aod::McParticles const& mcParticles, CandidateDstarMc const& candidates) { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); - fillCharmHadronTable(col, tracks, candidates); + fillCharmHadronTable(col, tracks, candidates, &mcParticles); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcDstarToD0Pi, "Provide Mc for DstarToD0Pi", false); void processMcDstarToD0PiWithML(FemtoFullCollisionMc const& col, aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, - aod::McParticles const&, + aod::McParticles const& mcParticles, soa::Join const& candidates) { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); - fillCharmHadronTable(col, tracks, candidates); + fillCharmHadronTable(col, tracks, candidates, &mcParticles); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcDstarToD0PiWithML, "Provide Mc for DstarToD0Pi with ml", false); @@ -1265,25 +1270,25 @@ struct HfProducerCharmHadronsTrackFemtoDream { void processMcDplusToPiKPi(FemtoFullCollisionMc const& col, aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, - aod::McParticles const&, + aod::McParticles const& mcParticles, CandidateDplusMc const& candidates) { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); - fillCharmHadronTable(col, tracks, candidates); + fillCharmHadronTable(col, tracks, candidates, &mcParticles); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcDplusToPiKPi, "Provide Mc for DplusToPiKPi", false); void processMcDplusToPiKPiWithML(FemtoFullCollisionMc const& col, aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, - aod::McParticles const&, + aod::McParticles const& mcParticles, soa::Join const& candidates) { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); - fillCharmHadronTable(col, tracks, candidates); + fillCharmHadronTable(col, tracks, candidates, &mcParticles); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcDplusToPiKPiWithML, "Provide Mc for DplusToPiKPi with ml", false); @@ -1322,25 +1327,25 @@ struct HfProducerCharmHadronsTrackFemtoDream { void processMcLcToPKPi(FemtoFullCollisionMc const& col, aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, - aod::McParticles const&, + aod::McParticles const& mcParticles, CandidateLcMc const& candidates) { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); - fillCharmHadronTable(col, tracks, candidates); + fillCharmHadronTable(col, tracks, candidates, &mcParticles); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcLcToPKPi, "Provide Mc for lctopkpi", false); void processMcLcToPKPiWithML(FemtoFullCollisionMc const& col, aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, - aod::McParticles const&, + aod::McParticles const& mcParticles, soa::Join const& candidates) { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); - fillCharmHadronTable(col, tracks, candidates); + fillCharmHadronTable(col, tracks, candidates, &mcParticles); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcLcToPKPiWithML, "Provide Mc for lctopkpi with ml", false); @@ -1400,11 +1405,11 @@ struct HfProducerCharmHadronsTrackFemtoDream { aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, aod::FullTracks const& daughterTracks, - aod::McParticles const&, + aod::McParticles const& mcParticles, soa::Filtered const& candidates) { getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates, daughterTracks); + fillXicHadronTable(col, tracks, candidates, daughterTracks, &mcParticles); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPi, "MC for XicToXiPiPi (DCAFitter)", false); @@ -1412,11 +1417,11 @@ struct HfProducerCharmHadronsTrackFemtoDream { aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, aod::FullTracks const& daughterTracks, - aod::McParticles const&, + aod::McParticles const& mcParticles, soa::Filtered const& candidates) { getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates, daughterTracks); + fillXicHadronTable(col, tracks, candidates, daughterTracks, &mcParticles); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPiKf, "MC for XicToXiPiPi (KFParticle)", false); @@ -1424,11 +1429,11 @@ struct HfProducerCharmHadronsTrackFemtoDream { aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, aod::FullTracks const& daughterTracks, - aod::McParticles const&, + aod::McParticles const& mcParticles, soa::Filtered> const& candidates) { getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates, daughterTracks); + fillXicHadronTable(col, tracks, candidates, daughterTracks, &mcParticles); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPiWithML, "MC for XicToXiPiPi with ML (DCAFitter)", false); @@ -1436,11 +1441,11 @@ struct HfProducerCharmHadronsTrackFemtoDream { aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, aod::FullTracks const& daughterTracks, - aod::McParticles const&, + aod::McParticles const& mcParticles, soa::Filtered> const& candidates) { getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates, daughterTracks); + fillXicHadronTable(col, tracks, candidates, daughterTracks, &mcParticles); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPiWithMLKf, "MC for XicToXiPiPi with ML (KFParticle)", false);