diff --git a/PWGHF/Tasks/taskMcEfficiency.cxx b/PWGHF/Tasks/taskMcEfficiency.cxx index 44b93d1a179..eb6e9ecfb7b 100644 --- a/PWGHF/Tasks/taskMcEfficiency.cxx +++ b/PWGHF/Tasks/taskMcEfficiency.cxx @@ -35,7 +35,7 @@ struct HfTaskMcEfficiency { ConfigurableAxis axisPt{"axisPt", {10, 0, 10}, "pT axis"}; ConfigurableAxis axisMass{"axisMass", {120, 1.5848, 2.1848}, "m_inv axis"}; - ConfigurableAxis axisPdg{"axisPdg", {VARIABLE_WIDTH, -4122.5, -421.5, 0, 421.5, 4122.5}, "PDG code axis"}; + ConfigurableAxis axisPdg{"axisPdg", {VARIABLE_WIDTH, -4122.5, -431.5, -421.5, -411.5, 0, 411.5, 421.5, 431.5, 4122.5}, "PDG code axis"}; ConfigurableAxis axisCPA{"axisCPA", {102, -1.02, 1.02}, "Cosine of pointing angle axis"}; Configurable mcAcceptancePt{"mcAcceptancePt", 0.1, "MC Acceptance: lower pt limit"}; @@ -94,7 +94,7 @@ struct HfTaskMcEfficiency { return track.isGlobalTrackWoDCA(); } - template + template void candidate3ProngLoop(T1& candidates, T2& tracks, T3& mcParticles, std::vector pdgCodes) { using TracksType = std::decay_t; @@ -108,7 +108,17 @@ struct HfTaskMcEfficiency { auto decayType = -1; std::array pdgDaughters; - if (pdgCode == pdg::kLambdaCPlus) { + if (pdgCode == pdg::kDPlus) { + decayType = 1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi; + pdgDaughters[0] = +kPiPlus; + pdgDaughters[1] = -kKPlus; + pdgDaughters[2] = +kPiPlus; + } else if (pdgCode == pdg::kDS) { + decayType = 1 << aod::hf_cand_3prong::DecayType::DsToKKPi; + pdgDaughters[0] = +kKPlus; + pdgDaughters[1] = -kKPlus; + pdgDaughters[2] = +kPiPlus; + } else if (pdgCode == pdg::kLambdaCPlus) { decayType = 1 << aod::hf_cand_3prong::DecayType::LcToPKPi; pdgDaughters[0] = +kProton; pdgDaughters[1] = -kKPlus; @@ -129,18 +139,30 @@ struct HfTaskMcEfficiency { bool isHypoMass2TrackStep = true; bool isHypoMass1SelStep = false; bool isHypoMass2SelStep = false; - if (pdgCode == pdg::kLambdaCPlus) { - isHypoMass1SelStep = candidate.isSelLcToPKPi(); /// from candidate selector! - isHypoMass2SelStep = candidate.isSelLcToPiKP(); /// from candidate selector! + /// selections from candidate selectors + if constexpr (hasDplus) { + if (pdgCode == pdg::kDPlus) { + isHypoMass1SelStep = candidate.isSelDplusToPiKPi(); // only one mass hypo for D+ + } + } + if constexpr (hasDs) { + if (pdgCode == pdg::kDS) { + isHypoMass1SelStep = candidate.isSelDsToKKPi(); + isHypoMass2SelStep = candidate.isSelDsToPiKK(); + } } + if constexpr (hasLc) { + if (pdgCode == pdg::kLambdaCPlus) { + isHypoMass1SelStep = candidate.isSelLcToPKPi(); + isHypoMass2SelStep = candidate.isSelLcToPiKP(); + } + } + bool collisionMatched = false; int origin = RecoDecay::OriginType::None; if constexpr (mc) { /// info MC used int8_t sign = 0; - int indexRec = -999; - if (pdgCode == pdg::kLambdaCPlus) { - indexRec = RecoDecay::getMatchedMCRec(mcParticles, std::array{trackPos, trackNeg, trackThird}, pdg::Code::kLambdaCPlus, array{+kProton, -kKPlus, +kPiPlus}, true, &sign, 2); - } + int indexRec = RecoDecay::getMatchedMCRec(mcParticles, std::array{trackPos, trackNeg, trackThird}, pdgCode, pdgDaughters, true, &sign, 2); if (indexRec < 0) { continue; @@ -178,12 +200,18 @@ struct HfTaskMcEfficiency { if (isHypoMass1TrackStep) { if (pdgCode == pdg::kLambdaCPlus) { massHypo1 = invMassLcToPKPi(candidate); + } else if (pdgCode == pdg::kDPlus) { + massHypo1 = invMassDplusToPiKPi(candidate); + } else if (pdgCode == pdg::kDS) { + massHypo1 = invMassDsToKKPi(candidate); } hCandidates->Fill(kHFStepTracked, pt, massHypo1, pdgCode, cpa, collisionMatched, origin); } if (isHypoMass2TrackStep) { if (pdgCode == pdg::kLambdaCPlus) { massHypo2 = invMassLcToPiKP(candidate); + } else if (pdgCode == pdg::kDS) { + massHypo2 = invMassDsToPiKK(candidate); } hCandidates->Fill(kHFStepTracked, pt, massHypo2, pdgCode, cpa, collisionMatched, origin); } @@ -370,7 +398,7 @@ struct HfTaskMcEfficiency { } /// check if we end-up with the correct final state using MC info int8_t sign = 0; - if (std::abs(mcParticle.pdgCode()) == pdg::kD0 && !RecoDecay::isMatchedMCGen(mcParticles, mcParticle, pdg::Code::kD0, array{+kPiPlus, -kKPlus}, true, &sign)) { + if (std::abs(mcParticle.pdgCode()) == pdg::kD0 && !RecoDecay::isMatchedMCGen(mcParticles, mcParticle, pdg::kD0, array{+kPiPlus, -kKPlus}, true, &sign)) { /// check if we have D0(bar) → π± K∓ continue; } @@ -446,10 +474,10 @@ struct HfTaskMcEfficiency { /// 3-prong analyses - template + template void candidate3ProngMcLoop(C& candidates, TracksWithSelectionMC& tracks, aod::McParticles& mcParticles, aod::McCollisionLabels& colls, std::vector pdgCodes) { - candidate3ProngLoop(candidates, tracks, mcParticles, pdgCodes); + candidate3ProngLoop(candidates, tracks, mcParticles, pdgCodes); auto hCandidates = registry.get(HIST("hCandidates")); auto hTrackablePtEta = registry.get(HIST("hTrackablePtEta")); @@ -482,14 +510,33 @@ struct HfTaskMcEfficiency { ////////////////////////// /// Step kHFStepMC /// ////////////////////////// - if (std::abs(mcParticle.pdgCode()) != pdgCode) { /// abs. value because only "kLambdaCPlus" is defined, not "kAntiLambdaCPlus" + auto absPdg = std::abs(mcParticle.pdgCode()); + if (absPdg != pdgCode) { /// abs. value because only "kLambdaCPlus" is defined, not "kAntiLambdaCPlus" continue; } + + std::array pdgDaughters; + if (pdgCode == pdg::kDPlus) { + pdgDaughters[0] = +kPiPlus; + pdgDaughters[1] = -kKPlus; + pdgDaughters[2] = +kPiPlus; + } else if (pdgCode == pdg::kDS) { + pdgDaughters[0] = +kKPlus; + pdgDaughters[1] = -kKPlus; + pdgDaughters[2] = +kPiPlus; + } else if (pdgCode == pdg::kLambdaCPlus) { + pdgDaughters[0] = +kProton; + pdgDaughters[1] = -kKPlus; + pdgDaughters[2] = +kPiPlus; + } else { + LOGP(fatal, "Not implemented for PDG {}", pdgCode); + } + /// check if we end-up with the correct final state using MC info int8_t sign = 0; std::unique_ptr> listIndexDaughters(new std::vector{}); - if (std::abs(mcParticle.pdgCode()) == pdg::kLambdaCPlus && !RecoDecay::isMatchedMCGen(mcParticles, mcParticle, pdg::Code::kLambdaCPlus, array{+kProton, -kKPlus, +kPiPlus}, true, &sign, 2, listIndexDaughters.get())) { - /// check if we have Λc± → p± K∓ π± (either direct or resonant) + if (!RecoDecay::isMatchedMCGen(mcParticles, mcParticle, pdgCode, pdgDaughters, true, &sign, 2, listIndexDaughters.get())) { + /// check if we have Λc± → p± K∓ π± (either direct or resonant), or D± → π± K∓ π± (either direct or resonant) or Ds± → K± K∓ π± (either direct or resonant) continue; } @@ -602,13 +649,55 @@ struct HfTaskMcEfficiency { } PROCESS_SWITCH(HfTaskMcEfficiency, processDataD0, "Process D0 data (no MC information needed)", false); + void processDataDplus(soa::Join& candidates, TracksWithSelection& tracks) + { + std::vector pdgCodes{pdg::kDPlus}; + candidate3ProngLoop(candidates, tracks, tracks, pdgCodes); + } + PROCESS_SWITCH(HfTaskMcEfficiency, processDataDplus, "Process D+ data (no MC information needed)", false); + + void processDataDs(soa::Join& candidates, TracksWithSelection& tracks) + { + std::vector pdgCodes{pdg::kDS}; + candidate3ProngLoop(candidates, tracks, tracks, pdgCodes); + } + PROCESS_SWITCH(HfTaskMcEfficiency, processDataDs, "Process Ds+ data (no MC information needed)", false); + void processDataLc(soa::Join& candidates, TracksWithSelection& tracks) { std::vector pdgCodes{pdg::kLambdaCPlus}; - candidate3ProngLoop(candidates, tracks, tracks, pdgCodes); + candidate3ProngLoop(candidates, tracks, tracks, pdgCodes); } PROCESS_SWITCH(HfTaskMcEfficiency, processDataLc, "Process Lc data (no MC information needed)", false); + void processDataDplusDs(soa::Join& candidates, TracksWithSelection& tracks) + { + std::vector pdgCodes{pdg::kDPlus, pdg::kDS}; + candidate3ProngLoop(candidates, tracks, tracks, pdgCodes); + } + PROCESS_SWITCH(HfTaskMcEfficiency, processDataDplusDs, "Process D+ and Ds+ data (no MC information needed)", false); + + void processDataDplusDsLc(soa::Join& candidates, TracksWithSelection& tracks) + { + std::vector pdgCodes{pdg::kDPlus, pdg::kDS, pdg::kLambdaCPlus}; + candidate3ProngLoop(candidates, tracks, tracks, pdgCodes); + } + PROCESS_SWITCH(HfTaskMcEfficiency, processDataDplusDsLc, "Process D+, Ds+, and Lc data (no MC information needed)", false); + + void processDataDplusLc(soa::Join& candidates, TracksWithSelection& tracks) + { + std::vector pdgCodes{pdg::kDPlus, pdg::kLambdaCPlus}; + candidate3ProngLoop(candidates, tracks, tracks, pdgCodes); + } + PROCESS_SWITCH(HfTaskMcEfficiency, processDataDplusLc, "Process D+ and Lc data (no MC information needed)", false); + + void processDataDsLc(soa::Join& candidates, TracksWithSelection& tracks) + { + std::vector pdgCodes{pdg::kDPlus, pdg::kDS, pdg::kLambdaCPlus}; + candidate3ProngLoop(candidates, tracks, tracks, pdgCodes); + } + PROCESS_SWITCH(HfTaskMcEfficiency, processDataDsLc, "Process Ds+ and Lc data (no MC information needed)", false); + // process functions for MC void processMcD0(soa::Join& candidates, TracksWithSelectionMC& tracks, aod::McParticles& mcParticles, aod::McCollisionLabels& colls) { @@ -617,12 +706,54 @@ struct HfTaskMcEfficiency { } PROCESS_SWITCH(HfTaskMcEfficiency, processMcD0, "Process MC for D0 signal", true); + void processMcDplus(soa::Join& candidates, TracksWithSelectionMC& tracks, aod::McParticles& mcParticles, aod::McCollisionLabels& colls) + { + std::vector pdgCodes{pdg::kDPlus}; + candidate3ProngMcLoop(candidates, tracks, mcParticles, colls, pdgCodes); + } + PROCESS_SWITCH(HfTaskMcEfficiency, processMcDplus, "Process MC for D+ signal", false); + + void processMcDs(soa::Join& candidates, TracksWithSelectionMC& tracks, aod::McParticles& mcParticles, aod::McCollisionLabels& colls) + { + std::vector pdgCodes{pdg::kDS}; + candidate3ProngMcLoop(candidates, tracks, mcParticles, colls, pdgCodes); + } + PROCESS_SWITCH(HfTaskMcEfficiency, processMcDs, "Process MC for Ds+ signal", false); + void processMcLc(soa::Join& candidates, TracksWithSelectionMC& tracks, aod::McParticles& mcParticles, aod::McCollisionLabels& colls) { std::vector pdgCodes{pdg::kLambdaCPlus}; - candidate3ProngMcLoop(candidates, tracks, mcParticles, colls, pdgCodes); + candidate3ProngMcLoop(candidates, tracks, mcParticles, colls, pdgCodes); } PROCESS_SWITCH(HfTaskMcEfficiency, processMcLc, "Process MC for Lc signal", false); + + void processMcDplusDs(soa::Join& candidates, TracksWithSelectionMC& tracks, aod::McParticles& mcParticles, aod::McCollisionLabels& colls) + { + std::vector pdgCodes{pdg::kDPlus, pdg::kDS}; + candidate3ProngMcLoop(candidates, tracks, mcParticles, colls, pdgCodes); + } + PROCESS_SWITCH(HfTaskMcEfficiency, processMcDplusDs, "Process MC for D+ and Ds+ signals", false); + + void processMcDplusDsLc(soa::Join& candidates, TracksWithSelectionMC& tracks, aod::McParticles& mcParticles, aod::McCollisionLabels& colls) + { + std::vector pdgCodes{pdg::kDPlus, pdg::kDS, pdg::kLambdaCPlus}; + candidate3ProngMcLoop(candidates, tracks, mcParticles, colls, pdgCodes); + } + PROCESS_SWITCH(HfTaskMcEfficiency, processMcDplusDsLc, "Process MC for D+, Ds+, and Lc signals", false); + + void processMcDplusLc(soa::Join& candidates, TracksWithSelectionMC& tracks, aod::McParticles& mcParticles, aod::McCollisionLabels& colls) + { + std::vector pdgCodes{pdg::kDPlus, pdg::kLambdaCPlus}; + candidate3ProngMcLoop(candidates, tracks, mcParticles, colls, pdgCodes); + } + PROCESS_SWITCH(HfTaskMcEfficiency, processMcDplusLc, "Process MC for D+ and Lc signals", false); + + void processMcDsLc(soa::Join& candidates, TracksWithSelectionMC& tracks, aod::McParticles& mcParticles, aod::McCollisionLabels& colls) + { + std::vector pdgCodes{pdg::kDS, pdg::kLambdaCPlus}; + candidate3ProngMcLoop(candidates, tracks, mcParticles, colls, pdgCodes); + } + PROCESS_SWITCH(HfTaskMcEfficiency, processMcDsLc, "Process MC for Ds+ and Lc signals", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)