Skip to content

Commit 34c6450

Browse files
committed
PWGHF: add offline event mixing tables for MC reco
1 parent 4133d27 commit 34c6450

1 file changed

Lines changed: 120 additions & 4 deletions

File tree

PWGHF/HFC/TableProducer/correlatorD0Hadrons.cxx

Lines changed: 120 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,9 @@ struct HfCorrelatorD0Hadrons {
266266
ConfigurableAxis binsPosZ{"binsPosZ", {100, -10., 10.}, "primary vertex z coordinate"};
267267
ConfigurableAxis binsPoolBin{"binsPoolBin", {9, 0., 9.}, "PoolBin"};
268268
ConfigurableAxis binsCentFt0m{"binsCentFt0m", {100, 0., 100.}, "Centrality percentile (FT0M)"};
269+
ConfigurableAxis binsBdtScoreBkg{"binsBdtScoreBkg", {500, 0., 1.}, "Bdt score background"};
270+
ConfigurableAxis binsBdtScorePrompt{"binsBdtScorePrompt", {200, 0., 1.}, "Bdt score prompt"};
271+
ConfigurableAxis binsBdtScoreNonPrompt{"binsBdtScoreNonPrompt", {200, 0., 1.}, "Bdt score non-prompt"};
269272

270273
HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject};
271274

@@ -285,9 +288,9 @@ struct HfCorrelatorD0Hadrons {
285288
AxisSpec const axisSignalStatus = {200, 0., 200., "Signal status"};
286289
AxisSpec axisEvtCount = {1, -0.5, 0.5};
287290
AxisSpec const axisTrkCount = {5, 0., 5.};
288-
AxisSpec axisBdtScoreBkg = {500, 0., 1., "Bdt score background"};
289-
AxisSpec axisBdtScorePrompt = {200, 0., 1., "Bdt score prompt"};
290-
AxisSpec axisBdtScoreNonPrompt = {200, 0., 1., "Bdt score Nonprompt"};
291+
AxisSpec axisBdtScoreBkg = {binsBdtScoreBkg, "Bdt score background"};
292+
AxisSpec axisBdtScorePrompt = {binsBdtScorePrompt, "Bdt score prompt"};
293+
AxisSpec axisBdtScoreNonPrompt = {binsBdtScoreNonPrompt, "Bdt score Nonprompt"};
291294
AxisSpec axisOrigin = {10, 0., 10., "Candidate origin"};
292295
AxisSpec axisCent = {binsCentFt0m, "Centrality"};
293296

@@ -322,9 +325,11 @@ struct HfCorrelatorD0Hadrons {
322325
registry.add("hYRec", "D0,D0bar candidates - MC reco", {HistType::kTH1F, {axisRapidity}});
323326
registry.add("hMassD0RecSig", "D0 signal candidates massVsPt - MC reco", {HistType::kTH2F, {{axisMassD}, {axisPtD}}});
324327
registry.add("hMassD0RecRef", "D0 reflection candidates massVsPt - MC reco", {HistType::kTH2F, {{axisMassD}, {axisPtD}}});
328+
registry.add("hMassD0RecRefAfterRejectBoth", "D0 reflection candidates after rejecting D0 and D0bar candidates massVsPt - MC reco", {HistType::kTH2F, {{axisMassD}, {axisPtD}}});
325329
registry.add("hMassD0RecBg", "D0 background candidates massVsPt - MC reco", {HistType::kTH2F, {{axisMassD}, {axisPtD}}});
326330
registry.add("hMassD0barRecSig", "D0bar signal candidates massVsPt - MC reco", {HistType::kTH2F, {{axisMassD}, {axisPtD}}});
327331
registry.add("hMassD0barRecRef", "D0bar reflection candidates massVsPt - MC reco", {HistType::kTH2F, {{axisMassD}, {axisPtD}}});
332+
registry.add("hMassD0barRecRefAfterRejectBoth", "D0bar reflection candidates after rejecting D0 and D0bar candidates massVsPt - MC reco", {HistType::kTH2F, {{axisMassD}, {axisPtD}}});
328333
registry.add("hMassD0barRecBg", "D0bar background candidates massVsPt - MC reco", {HistType::kTH2F, {{axisMassD}, {axisPtD}}});
329334
registry.add("hPtCandRecSigPrompt", "D0,Hadron candidates Prompt - MC Reco", {HistType::kTH1F, {axisPtD}});
330335
registry.add("hPtVsMLScoresVsEtaRecSigPrompt", "Prompt D0-D0bar signal candidates MLVsPtVsEta - MC reco", {HistType::kTHnSparseD, {{axisBdtScoreBkg}, {axisBdtScorePrompt}, {axisBdtScoreNonPrompt}, {axisPtD}, {axisEta}}});
@@ -583,9 +588,15 @@ struct HfCorrelatorD0Hadrons {
583588
void processMcRec(SelectedCollisions::iterator const& collision,
584589
SelectedTracksMcRec const& tracks,
585590
SelectedCandidatesMcRecMl const& candidates,
586-
aod::McParticles const& mcParticles)
591+
aod::McParticles const& mcParticles,
592+
aod::BCsWithTimestamps const&)
587593
{
588594
BinningType const corrBinning{{zPoolBins, multPoolBins}, true};
595+
596+
auto bc = collision.bc_as<aod::BCsWithTimestamps>();
597+
int gCollisionId = collision.globalIndex();
598+
int64_t timeStamp = bc.timestamp();
599+
589600
// find leading particle
590601
if (correlateD0WithLeadingParticle) {
591602
leadingIndex = findLeadingParticle(tracks, etaTrackMax.value);
@@ -625,6 +636,30 @@ struct HfCorrelatorD0Hadrons {
625636
std::vector<float> outputMlD0 = {-1., -1., -1.};
626637
std::vector<float> outputMlD0bar = {-1., -1., -1.};
627638

639+
std::vector<int64_t> softPionTrackIdsForOfflineMixing;
640+
std::vector<int> softPionStatusesForOfflineMixing;
641+
bool hasAcceptedD0ForOfflineMixing = false;
642+
643+
auto addSoftPionTrackForOfflineMixing = [&softPionTrackIdsForOfflineMixing, &softPionStatusesForOfflineMixing](int64_t trackId, int softPiStatus) {
644+
for (auto iTrack = 0u; iTrack < softPionTrackIdsForOfflineMixing.size(); ++iTrack) {
645+
if (softPionTrackIdsForOfflineMixing[iTrack] == trackId) {
646+
softPionStatusesForOfflineMixing[iTrack] |= softPiStatus;
647+
return;
648+
}
649+
}
650+
softPionTrackIdsForOfflineMixing.push_back(trackId);
651+
softPionStatusesForOfflineMixing.push_back(softPiStatus);
652+
};
653+
654+
auto getSoftPionStatusForOfflineMixing = [&softPionTrackIdsForOfflineMixing, &softPionStatusesForOfflineMixing](int64_t trackId) {
655+
for (auto iTrack = 0u; iTrack < softPionTrackIdsForOfflineMixing.size(); ++iTrack) {
656+
if (softPionTrackIdsForOfflineMixing[iTrack] == trackId) {
657+
return softPionStatusesForOfflineMixing[iTrack];
658+
}
659+
}
660+
return static_cast<int>(aod::hf_d0_assoc_tracks::NotSoftPi);
661+
};
662+
628663
for (const auto& candidate : candidates) {
629664
bool isD0Prompt = candidate.originMcRec() == RecoDecay::OriginType::Prompt;
630665
bool isD0NonPrompt = candidate.originMcRec() == RecoDecay::OriginType::NonPrompt;
@@ -646,6 +681,10 @@ struct HfCorrelatorD0Hadrons {
646681
const auto invMassD0 = HfHelper::invMassD0ToPiK(candidate);
647682
const auto invMassD0bar = HfHelper::invMassD0barToKPi(candidate);
648683

684+
if (candidate.isSelD0() >= selectionFlagD0 || candidate.isSelD0bar() >= selectionFlagD0bar) {
685+
hasAcceptedD0ForOfflineMixing = true;
686+
}
687+
649688
if (std::abs(candidate.flagMcMatchRec()) == o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) {
650689
// fill per-candidate distributions from D0/D0bar true candidates
651690
registry.fill(HIST("hPtCandRec"), candidate.pt());
@@ -671,13 +710,17 @@ struct HfCorrelatorD0Hadrons {
671710
}
672711
} else if (candidate.flagMcMatchRec() == -o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) {
673712
registry.fill(HIST("hMassD0RecRef"), invMassD0, candidate.pt(), efficiencyWeight);
713+
if (candidate.isSelD0bar() < selectionFlagD0bar) {
714+
registry.fill(HIST("hMassD0RecRefAfterRejectBoth"), invMassD0, candidate.pt(), efficiencyWeight);
715+
}
674716
} else {
675717
registry.fill(HIST("hMassD0RecBg"), invMassD0, candidate.pt(), efficiencyWeight);
676718
}
677719
for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) {
678720
outputMlD0[iclass] = candidate.mlProbD0()[classMl->at(iclass)];
679721
}
680722
registry.fill(HIST("hMLScoresVsMassVsPtVsEtaVsOriginVsCent"), outputMlD0[0], outputMlD0[1], outputMlD0[2], invMassD0, candidate.pt(), candidate.eta(), isD0Prompt, cent, efficiencyWeight);
723+
entryD0(candidate.phi(), candidate.eta(), candidate.pt(), invMassD0, poolBin, gCollisionId, timeStamp, (candidate.isSelD0bar() != 0) ? o2::aod::hf_correlation_d0_hadron::D0D0barBoth : o2::aod::hf_correlation_d0_hadron::D0Only);
681724
}
682725
if (candidate.isSelD0bar() >= selectionFlagD0bar) { // only reco as D0bar
683726
if (candidate.flagMcMatchRec() == -o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) { // also matched as D0bar
@@ -693,13 +736,17 @@ struct HfCorrelatorD0Hadrons {
693736
}
694737
} else if (candidate.flagMcMatchRec() == o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) {
695738
registry.fill(HIST("hMassD0barRecRef"), invMassD0bar, candidate.pt(), efficiencyWeight);
739+
if (candidate.isSelD0() < selectionFlagD0) {
740+
registry.fill(HIST("hMassD0barRecRefAfterRejectBoth"), invMassD0bar, candidate.pt(), efficiencyWeight);
741+
}
696742
} else {
697743
registry.fill(HIST("hMassD0barRecBg"), invMassD0bar, candidate.pt(), efficiencyWeight);
698744
}
699745
for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) {
700746
outputMlD0bar[iclass] = candidate.mlProbD0bar()[classMl->at(iclass)];
701747
}
702748
registry.fill(HIST("hMLScoresVsMassVsPtVsEtaVsOriginVsCent"), outputMlD0bar[0], outputMlD0bar[1], outputMlD0bar[2], invMassD0bar, candidate.pt(), candidate.eta(), isD0Prompt, cent, efficiencyWeight);
749+
entryD0(candidate.phi(), candidate.eta(), candidate.pt(), invMassD0bar, poolBin, gCollisionId, timeStamp, (candidate.isSelD0() != 0) ? o2::aod::hf_correlation_d0_hadron::D0D0barBoth : o2::aod::hf_correlation_d0_hadron::D0barOnly);
703750
}
704751
entryD0CandRecoInfo(invMassD0, invMassD0bar, candidate.pt(), outputMlD0[0], outputMlD0[2], outputMlD0bar[0], outputMlD0bar[2]);
705752
entryD0CandGenInfo(isD0Prompt);
@@ -740,12 +787,14 @@ struct HfCorrelatorD0Hadrons {
740787

741788
if (candidate.isSelD0() >= selectionFlagD0) {
742789
if ((std::abs(invMassDstar1 - invMassD0) - softPiMass) < ptSoftPionMax) {
790+
addSoftPionTrackForOfflineMixing(track.globalIndex(), aod::hf_d0_assoc_tracks::SoftPiD0);
743791
continue;
744792
}
745793
}
746794

747795
if (candidate.isSelD0bar() >= selectionFlagD0bar) {
748796
if ((std::abs(invMassDstar2 - invMassD0bar) - softPiMass) < ptSoftPionMax) {
797+
addSoftPionTrackForOfflineMixing(track.globalIndex(), aod::hf_d0_assoc_tracks::SoftPiD0bar);
749798
continue;
750799
}
751800
}
@@ -806,6 +855,20 @@ struct HfCorrelatorD0Hadrons {
806855
entryTrackRecoInfo(track.dcaXY(), track.dcaZ(), track.tpcNClsCrossedRows());
807856
} // end inner loop (Tracks)
808857
} // end of outer loop (D0)
858+
859+
// loop to save tables for offline event mixing
860+
if (hasAcceptedD0ForOfflineMixing) {
861+
for (const auto& track : tracks) {
862+
const auto softPiStatus = getSoftPionStatusForOfflineMixing(track.globalIndex());
863+
864+
registry.fill(HIST("hTracksBeforeSoftMix"), track.pt());
865+
if (softPiStatus == aod::hf_d0_assoc_tracks::NotSoftPi) {
866+
registry.fill(HIST("hTracksAfterSoftMix"), track.pt());
867+
}
868+
869+
entryD0Hadron(track.phi(), track.eta(), track.pt(), poolBin, gCollisionId, timeStamp, softPiStatus);
870+
}
871+
}
809872
}
810873

811874
PROCESS_SWITCH(HfCorrelatorD0Hadrons, processMcRec, "Process MC Reco mode", true);
@@ -817,6 +880,8 @@ struct HfCorrelatorD0Hadrons {
817880
{
818881
BinningTypeMcGen const corrBinningMcGen{{zPoolBins, multPoolBinsMcGen}, true};
819882
int poolBin = corrBinningMcGen.getBin(std::make_tuple(mcCollision.posZ(), mcCollision.multMCFT0A()));
883+
int gCollisionId = mcCollision.globalIndex();
884+
int64_t timeStamp = 0;
820885
registry.fill(HIST("hCollisionPoolBin"), poolBin);
821886
registry.fill(HIST("hEvtCountGen"), 0);
822887
// MC gen level
@@ -828,6 +893,29 @@ struct HfCorrelatorD0Hadrons {
828893
bool isD0NonPrompt = false;
829894
int trackOrigin = -1;
830895
float cent = 100.; // Centrality Placeholder: will be updated later
896+
std::vector<int64_t> softPionTrackIdsForOfflineMixing;
897+
std::vector<int> softPionStatusesForOfflineMixing;
898+
bool hasAcceptedD0ForOfflineMixing = false;
899+
900+
auto addSoftPionTrackForOfflineMixing = [&softPionTrackIdsForOfflineMixing, &softPionStatusesForOfflineMixing](int64_t trackId, int softPiStatus) {
901+
for (auto iTrack = 0u; iTrack < softPionTrackIdsForOfflineMixing.size(); ++iTrack) {
902+
if (softPionTrackIdsForOfflineMixing[iTrack] == trackId) {
903+
softPionStatusesForOfflineMixing[iTrack] |= softPiStatus;
904+
return;
905+
}
906+
}
907+
softPionTrackIdsForOfflineMixing.push_back(trackId);
908+
softPionStatusesForOfflineMixing.push_back(softPiStatus);
909+
};
910+
911+
auto getSoftPionStatusForOfflineMixing = [&softPionTrackIdsForOfflineMixing, &softPionStatusesForOfflineMixing](int64_t trackId) {
912+
for (auto iTrack = 0u; iTrack < softPionTrackIdsForOfflineMixing.size(); ++iTrack) {
913+
if (softPionTrackIdsForOfflineMixing[iTrack] == trackId) {
914+
return softPionStatusesForOfflineMixing[iTrack];
915+
}
916+
}
917+
return static_cast<int>(aod::hf_d0_assoc_tracks::NotSoftPi);
918+
};
831919

832920
for (const auto& particleTrigg : mcParticles) {
833921
if (std::abs(particleTrigg.pdgCode()) != Pdg::kD0) {
@@ -841,6 +929,7 @@ struct HfCorrelatorD0Hadrons {
841929
if (ptCandMin >= 0. && particleTrigg.pt() < ptCandMin) {
842930
continue;
843931
}
932+
hasAcceptedD0ForOfflineMixing = true;
844933

845934
registry.fill(HIST("hD0PoolBin"), poolBin);
846935
registry.fill(HIST("hPtCandGen"), particleTrigg.pt());
@@ -860,6 +949,7 @@ struct HfCorrelatorD0Hadrons {
860949
registry.fill(HIST("hPtCandGenNonPrompt"), particleTrigg.pt());
861950
registry.fill(HIST("hPtVsEtaCandGenSigNonPrompt"), particleTrigg.pt(), particleTrigg.eta());
862951
}
952+
entryD0(particleTrigg.phi(), particleTrigg.eta(), particleTrigg.pt(), MassD0, poolBin, gCollisionId, timeStamp, (particleTrigg.pdgCode() == Pdg::kD0) ? o2::aod::hf_correlation_d0_hadron::D0Only : o2::aod::hf_correlation_d0_hadron::D0barOnly);
863953

864954
// =============== D-h correlation dedicated section =====================
865955
for (const auto& particleAssoc : mcParticles) {
@@ -884,6 +974,7 @@ struct HfCorrelatorD0Hadrons {
884974
auto indexMotherD0 = RecoDecay::getMother(mcParticles, particleTrigg, Pdg::kDStar, true, nullptr, 1);
885975
bool correlationStatus = false;
886976
if (std::abs(particleAssoc.pdgCode()) == kPiPlus && indexMotherPi >= 0 && indexMotherD0 >= 0 && indexMotherPi == indexMotherD0) {
977+
addSoftPionTrackForOfflineMixing(particleAssoc.globalIndex(), (particleTrigg.pdgCode() == Pdg::kD0) ? aod::hf_d0_assoc_tracks::SoftPiD0 : aod::hf_d0_assoc_tracks::SoftPiD0bar);
887978
if (!storeAutoCorrelationFlag) {
888979
continue;
889980
}
@@ -911,6 +1002,31 @@ struct HfCorrelatorD0Hadrons {
9111002
} // end inner loop (Tracks)
9121003
}
9131004
} // end outer loop (D0)
1005+
1006+
if (hasAcceptedD0ForOfflineMixing) {
1007+
for (const auto& particleAssoc : mcParticles) {
1008+
if (std::abs(particleAssoc.eta()) > etaTrackMax) {
1009+
continue;
1010+
}
1011+
if (particleAssoc.pt() < ptTrackMin) {
1012+
continue;
1013+
}
1014+
if ((std::abs(particleAssoc.pdgCode()) != kElectron) && (std::abs(particleAssoc.pdgCode()) != kMuonMinus) && (std::abs(particleAssoc.pdgCode()) != kPiPlus) && (std::abs(particleAssoc.pdgCode()) != kKPlus) && (std::abs(particleAssoc.pdgCode()) != kProton)) {
1015+
continue;
1016+
}
1017+
if (!particleAssoc.isPhysicalPrimary()) {
1018+
continue;
1019+
}
1020+
const auto softPiStatus = getSoftPionStatusForOfflineMixing(particleAssoc.globalIndex());
1021+
1022+
registry.fill(HIST("hTracksBeforeSoftMix"), particleAssoc.pt());
1023+
if (softPiStatus == aod::hf_d0_assoc_tracks::NotSoftPi) {
1024+
registry.fill(HIST("hTracksAfterSoftMix"), particleAssoc.pt());
1025+
}
1026+
1027+
entryD0Hadron(particleAssoc.phi(), particleAssoc.eta(), particleAssoc.pt(), poolBin, gCollisionId, timeStamp, softPiStatus);
1028+
}
1029+
}
9141030
}
9151031

9161032
PROCESS_SWITCH(HfCorrelatorD0Hadrons, processMcGen, "Process MC Gen mode", false);

0 commit comments

Comments
 (0)