From fbad808d52554891ca9f516983eb8433c25d8a79 Mon Sep 17 00:00:00 2001 From: scattaru Date: Tue, 3 Feb 2026 10:08:51 +0100 Subject: [PATCH 1/2] Added ULS and LS separation in MC Gen processes --- .../HFC/TableProducer/correlatorDsHadrons.cxx | 89 +++++++++++-------- PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx | 43 ++++++++- 2 files changed, 92 insertions(+), 40 deletions(-) diff --git a/PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx index 562df81322d..bc08c544ede 100644 --- a/PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx @@ -759,25 +759,23 @@ struct HfCorrelatorDsHadrons { listDaughters.clear(); RecoDecay::getDaughters(particle, &listDaughters, arrDaughDsPDG, 2); int counterDaughters = 0; + // Assign Ds charge sign int chargeDs = 0; + if (particle.pdgCode() == kDS) { + chargeDs = 1; + } else { + chargeDs = -1; + } + // Find Ds daughters if (listDaughters.size() == NDaughtersDs) { for (const auto& dauIdx : listDaughters) { // auto daughI = mcParticles.rawIteratorAt(dauIdx - mcParticles.offset()); auto daughI = groupedMcParticles.rawIteratorAt(dauIdx - groupedMcParticles.offset()); counterDaughters += 1; - if (counterDaughters == 1) { - if (daughI.pdgCode() == kKPlus) { - chargeDs = 1; - } else { - chargeDs = -1; - } - } prongsId[counterDaughters - 1] = daughI.globalIndex(); } } - int numberOfCorrKaons = 0; - // Ds Hadron correlation dedicated section for (const auto& particleAssoc : groupedMcParticles) { if (std::abs(particleAssoc.eta()) > etaTrackMax || particleAssoc.pt() < ptTrackMin || particleAssoc.pt() > ptTrackMax) { @@ -792,46 +790,37 @@ struct HfCorrelatorDsHadrons { if (!particleAssoc.isPhysicalPrimary()) { continue; } - - if (isDsPrompt) { - registry.fill(HIST("hCorrAllPrimaryParticles"), getDeltaPhi(particleAssoc.phi(), particle.phi()), particle.pt(), particleAssoc.pt()); - if (std::abs(particleAssoc.pdgCode()) == kPiPlus) { - registry.fill(HIST("hCorrAllPrimaryHadrons"), getDeltaPhi(particleAssoc.phi(), particle.phi()), particle.pt(), particleAssoc.pt()); - registry.fill(HIST("hCorrAllPrimaryPions"), getDeltaPhi(particleAssoc.phi(), particle.phi()), particle.pt(), particleAssoc.pt()); - } else if (std::abs(particleAssoc.pdgCode()) == kKPlus) { - registry.fill(HIST("hCorrAllPrimaryHadrons"), getDeltaPhi(particleAssoc.phi(), particle.phi()), particle.pt(), particleAssoc.pt()); - registry.fill(HIST("hCorrAllPrimaryKaons"), getDeltaPhi(particleAssoc.phi(), particle.phi()), particle.pt(), particleAssoc.pt()); - } else if (std::abs(particleAssoc.pdgCode()) == kProton) { - registry.fill(HIST("hCorrAllPrimaryHadrons"), getDeltaPhi(particleAssoc.phi(), particle.phi()), particle.pt(), particleAssoc.pt()); - registry.fill(HIST("hCorrAllPrimaryProtons"), getDeltaPhi(particleAssoc.phi(), particle.phi()), particle.pt(), particleAssoc.pt()); + if (pidTrkApplied) { + // MC truth match + if (trkPIDspecies->at(0) == o2::track::PID::Kaon && std::abs(particleAssoc.pdgCode()) != kKPlus) { + continue; + } + if (trkPIDspecies->at(0) == o2::track::PID::Pion && std::abs(particleAssoc.pdgCode()) != kPiPlus) { + continue; } - if (pidTrkApplied) { - if (((chargeDs == 1) && (particleAssoc.pdgCode() == kKPlus)) || ((chargeDs == -1) && (particleAssoc.pdgCode() == kKMinus))) { // LS pairs - registry.fill(HIST("hCorrKaonsLSPairs"), getDeltaPhi(particleAssoc.phi(), particle.phi()), particle.pt(), particleAssoc.pt()); - numberOfCorrKaons++; - } - if (((chargeDs == 1) && (particleAssoc.pdgCode() == kKMinus)) || ((chargeDs == -1) && (particleAssoc.pdgCode() == kKPlus))) { // ULS pairs - registry.fill(HIST("hCorrKaonsULSPairs"), getDeltaPhi(particleAssoc.phi(), particle.phi()), particle.pt(), particleAssoc.pt()); - numberOfCorrKaons++; - } + if (trkPIDspecies->at(0) == o2::track::PID::Proton && std::abs(particleAssoc.pdgCode()) != kProton) { + continue; } } + int chargeParticle = 0; + if ((particleAssoc.pdgCode() == kElectron) || (particleAssoc.pdgCode() == kMuonMinus) || (particleAssoc.pdgCode() == kPiMinus) || (particleAssoc.pdgCode()) == kKMinus || (particleAssoc.pdgCode() == kProtonBar)) { + chargeParticle = -1; + } else { + chargeParticle = 1; + } // trackOrigin = RecoDecay::getCharmHadronOrigin(mcParticles, particleAssoc, true); trackOrigin = RecoDecay::getCharmHadronOrigin(groupedMcParticles, particleAssoc, true); registry.fill(HIST("hPtParticleAssocMcGen"), particleAssoc.pt()); entryDsHadronPair(getDeltaPhi(particleAssoc.phi(), particle.phi()), particleAssoc.eta() - particle.eta(), - particle.pt(), - particleAssoc.pt(), + particle.pt() * chargeDs, + particleAssoc.pt() * chargeParticle, poolBin, 0); entryDsHadronRecoInfo(MassDS, true, isDecayChan); entryDsHadronGenInfo(isDsPrompt, particleAssoc.isPhysicalPrimary(), trackOrigin); } // end loop generated particles - if (numberOfCorrKaons == 0) { - registry.fill(HIST("hDsWoKaons"), numberOfCorrKaons); - } } // if statement for Ds selection } // end loop generated Ds } // end loop reconstructed collision @@ -1095,12 +1084,38 @@ struct HfCorrelatorDsHadrons { if (!particleAssoc.isPhysicalPrimary()) { continue; } + if (pidTrkApplied) { + // MC truth match + if (trkPIDspecies->at(0) == o2::track::PID::Kaon && std::abs(particleAssoc.pdgCode()) != kKPlus) { + continue; + } + if (trkPIDspecies->at(0) == o2::track::PID::Pion && std::abs(particleAssoc.pdgCode()) != kPiPlus) { + continue; + } + if (trkPIDspecies->at(0) == o2::track::PID::Proton && std::abs(particleAssoc.pdgCode()) != kProton) { + continue; + } + } + + int chargeDs = 0; + if (candidate.pdgCode() == kDS) { + chargeDs = 1; + } else { + chargeDs = -1; + } + + int chargeParticle = 0; + if ((particleAssoc.pdgCode() == kElectron) || (particleAssoc.pdgCode() == kMuonMinus) || (particleAssoc.pdgCode() == kPiMinus) || (particleAssoc.pdgCode()) == kKMinus || (particleAssoc.pdgCode() == kProtonBar)) { + chargeParticle = -1; + } else { + chargeParticle = 1; + } int trackOrigin = RecoDecay::getCharmHadronOrigin(mcParticles, particleAssoc, true); bool isDsPrompt = candidate.originMcGen() == RecoDecay::OriginType::Prompt; entryDsHadronPair(getDeltaPhi(particleAssoc.phi(), candidate.phi()), particleAssoc.eta() - candidate.eta(), - candidate.pt(), - particleAssoc.pt(), + candidate.pt() * chargeDs, + particleAssoc.pt() * chargeParticle, poolBin, 0); entryDsHadronRecoInfo(MassDS, true, true); diff --git a/PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx b/PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx index e257beec41e..86986ee9efc 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx @@ -254,7 +254,12 @@ struct HfTaskCorrelationDsHadrons { registry.add("hDeltaEtaPtIntSidebandRightMcRec", "Ds-h deltaEta sideband right region MC reco", {HistType::kTH1F, {axisDetlaEta}}); registry.add("hDeltaPhiPtIntSidebandRightMcRec", "Ds-h deltaPhi sideband right region MC reco", {HistType::kTH1F, {axisDetlaPhi}}); registry.add("hCorrel2DVsPtSidebandRightMcRec", "Ds-h correlations sideband right region MC reco", {HistType::kTHnSparseD, {{axisDetlaPhi}, {axisDetlaEta}, {axisPtD}, {axisPtHadron}, {axisPoolBin}}}); - + if (doLSpair) { + registry.add("hCorrel2DVsPtPhysicalPrimaryMcRecLS", "Ds-h correlations signal region (only true primary particles) MC reco", {HistType::kTHnSparseD, {{axisDetlaPhi}, {axisDetlaEta}, {axisPtD}, {axisPtHadron}, {axisDsPrompt}, {axisPoolBin}}}); + } + if (doULSpair) { + registry.add("hCorrel2DVsPtPhysicalPrimaryMcRecULS", "Ds-h correlations signal region (only true primary particles) MC reco", {HistType::kTHnSparseD, {{axisDetlaPhi}, {axisDetlaEta}, {axisPtD}, {axisPtHadron}, {axisDsPrompt}, {axisPoolBin}}}); + } registry.get(HIST("hCorrel2DVsPtSignalRegionMcRec"))->Sumw2(); registry.get(HIST("hCorrel2DVsPtPhysicalPrimaryMcRec"))->Sumw2(); registry.get(HIST("hCorrel2DVsPtSidebandLeftMcRec"))->Sumw2(); @@ -270,6 +275,14 @@ struct HfTaskCorrelationDsHadrons { registry.add("hCorrel2DVsPtMcGenNonPromptDsNonPromptHadron", "Ds-h correlations non prompt Ds non prompt h MC Gen", {HistType::kTHnSparseD, {{axisDetlaPhi}, {axisDetlaEta}, {axisPtD}, {axisPtHadron}, {axisPoolBin}}}); registry.add("hCorrel2DVsPtMcGenNonPrompt", "Ds-h correlations NonPrompt MC Gen", {HistType::kTHnSparseD, {{axisDetlaPhi}, {axisDetlaEta}, {axisPtD}, {axisPtHadron}, {axisPoolBin}}}); + if (doLSpair) { + registry.add("hCorrel2DVsPtMcGenPromptLS", "Ds-h correlations Prompt MC Gen", {HistType::kTHnSparseD, {{axisDetlaPhi}, {axisDetlaEta}, {axisPtD}, {axisPtHadron}, {axisPoolBin}}}); + registry.add("hCorrel2DVsPtMcGenNonPromptLS", "Ds-h correlations NonPrompt MC Gen", {HistType::kTHnSparseD, {{axisDetlaPhi}, {axisDetlaEta}, {axisPtD}, {axisPtHadron}, {axisPoolBin}}}); + } + if (doULSpair) { + registry.add("hCorrel2DVsPtMcGenPromptULS", "Ds-h correlations Prompt MC Gen", {HistType::kTHnSparseD, {{axisDetlaPhi}, {axisDetlaEta}, {axisPtD}, {axisPtHadron}, {axisPoolBin}}}); + registry.add("hCorrel2DVsPtMcGenNonPromptULS", "Ds-h correlations NonPrompt MC Gen", {HistType::kTHnSparseD, {{axisDetlaPhi}, {axisDetlaEta}, {axisPtD}, {axisPtHadron}, {axisPoolBin}}}); + } registry.get(HIST("hCorrel2DVsPtMcGen"))->Sumw2(); registry.get(HIST("hCorrel2DVsPtMcGenPrompt"))->Sumw2(); registry.get(HIST("hCorrel2DVsPtMcGenNonPrompt"))->Sumw2(); @@ -642,7 +655,13 @@ struct HfTaskCorrelationDsHadrons { registry.fill(HIST("hDeltaPhiPtIntSignalRegionMcRec"), deltaPhi, efficiencyWeight); registry.fill(HIST("hCorrel2DVsPtSignalRegionMcRec"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), statusDsPrompt, poolBin, efficiencyWeight); if (isPhysicalPrimary) { - registry.fill(HIST("hCorrel2DVsPtPhysicalPrimaryMcRec"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), statusDsPrompt, poolBin, efficiencyWeight); + if (doLSpair && ((ptD > 0. && ptHadron > 0.) || (ptD < 0. && ptHadron < 0.))) { // like-sign pairs + registry.fill(HIST("hCorrel2DVsPtPhysicalPrimaryMcRecLS"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), statusDsPrompt, poolBin, efficiencyWeight); + } else if (doULSpair && ((ptD > 0. && ptHadron < 0.) || (ptD < 0. && ptHadron > 0.))) { // unlike-sign pairs + registry.fill(HIST("hCorrel2DVsPtPhysicalPrimaryMcRecULS"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), statusDsPrompt, poolBin, efficiencyWeight); + } else { // default case + registry.fill(HIST("hCorrel2DVsPtPhysicalPrimaryMcRec"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), statusDsPrompt, poolBin, efficiencyWeight); + } if (statusDsPrompt == 1 && statusPromptHadron == RecoDecay::OriginType::Prompt) { registry.fill(HIST("hCorrel2DVsPtSignalRegionPromptDsPromptHadronMcRec"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin, efficiencyWeight); } else if (statusDsPrompt == 0 && statusPromptHadron == RecoDecay::OriginType::NonPrompt) { @@ -685,11 +704,23 @@ struct HfTaskCorrelationDsHadrons { registry.fill(HIST("hDeltaPhiPtIntMcGen"), deltaPhi); if (isDsPrompt) { registry.fill(HIST("hCorrel2DVsPtMcGenPrompt"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin); + if (doULSpair) { + registry.fill(HIST("hCorrel2DVsPtMcGenPromptULS"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin); + } + if (doLSpair && ((ptD > 0. && ptHadron > 0.) || (ptD < 0. && ptHadron < 0.))) { + registry.fill(HIST("hCorrel2DVsPtMcGenPromptLS"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin); + } if (statusPromptHadron == RecoDecay::OriginType::Prompt) { registry.fill(HIST("hCorrel2DVsPtMcGenPromptDsPromptHadron"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin); } } else { registry.fill(HIST("hCorrel2DVsPtMcGenNonPrompt"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin); + if (doULSpair) { + registry.fill(HIST("hCorrel2DVsPtMcGenNonPromptULS"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin); + } + if (doLSpair && ((ptD > 0. && ptHadron > 0.) || (ptD < 0. && ptHadron < 0.))) { + registry.fill(HIST("hCorrel2DVsPtMcGenNonPromptLS"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin); + } if (statusPromptHadron == RecoDecay::OriginType::NonPrompt) { registry.fill(HIST("hCorrel2DVsPtMcGenNonPromptDsNonPromptHadron"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin); } @@ -876,7 +907,13 @@ struct HfTaskCorrelationDsHadrons { registry.fill(HIST("hDeltaPhiPtIntSignalRegionMcRec"), deltaPhi, efficiencyWeight); registry.fill(HIST("hCorrel2DVsPtSignalRegionMcRec"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), statusDsPrompt, poolBin, efficiencyWeight); if (isPhysicalPrimary) { - registry.fill(HIST("hCorrel2DVsPtPhysicalPrimaryMcRec"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), statusDsPrompt, poolBin, efficiencyWeight); + if (doLSpair && ((ptD > 0. && ptHadron > 0.) || (ptD < 0. && ptHadron < 0.))) { // like-sign pairs + registry.fill(HIST("hCorrel2DVsPtPhysicalPrimaryMcRecLS"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), statusDsPrompt, poolBin, efficiencyWeight); + } else if (doULSpair && ((ptD > 0. && ptHadron < 0.) || (ptD < 0. && ptHadron > 0.))) { // unlike-sign pairs + registry.fill(HIST("hCorrel2DVsPtPhysicalPrimaryMcRecULS"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), statusDsPrompt, poolBin, efficiencyWeight); + } else { // default case + registry.fill(HIST("hCorrel2DVsPtPhysicalPrimaryMcRec"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), statusDsPrompt, poolBin, efficiencyWeight); + } if (statusDsPrompt == 1 && statusPromptHadron == RecoDecay::OriginType::Prompt) { registry.fill(HIST("hCorrel2DVsPtSignalRegionPromptDsPromptHadronMcRec"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin, efficiencyWeight); } else if (statusDsPrompt == 0 && statusPromptHadron == RecoDecay::OriginType::NonPrompt) { From aef6bed76ac299309c3fb4dd7b1a88b9ed90d864 Mon Sep 17 00:00:00 2001 From: scattaru Date: Tue, 3 Feb 2026 18:50:38 +0100 Subject: [PATCH 2/2] Fix bud in MC-ME process --- PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx index bc08c544ede..03949919708 100644 --- a/PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx @@ -1018,7 +1018,7 @@ struct HfCorrelatorDsHadrons { isDsPrompt = candidate.originMcRec() == RecoDecay::OriginType::Prompt; // Ds Signal isDsSignal = std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK; - isDecayChan = candidate.flagMcDecayChanRec() == decayChannel; + isDecayChan = candidate.flagMcDecayChanRec() == channelsResonant[decayChannel]; if (pAssoc.has_mcParticle()) { auto mcParticle = pAssoc.template mcParticle_as(); isPhysicalPrimary = mcParticle.isPhysicalPrimary();