Skip to content

Commit e244e0c

Browse files
authored
MCGen analysis update removing reco collisions
1 parent 517402f commit e244e0c

File tree

1 file changed

+167
-74
lines changed

1 file changed

+167
-74
lines changed

PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx

Lines changed: 167 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,11 @@ struct HfCorrelatorDplusHadrons {
186186

187187
Configurable<int> selectionFlagDplus{"selectionFlagDplus", 7, "Selection Flag for Dplus"}; // 7 corresponds to topo+PID cuts
188188
Configurable<int> numberEventsMixed{"numberEventsMixed", 5, "Number of events mixed in ME process"};
189+
Configurable<bool> removeUnreconstructedGenCollisions{"removeUnreconstructedGenCollisions",true,"Remove generator-level collisions that were not reconstructed"};
190+
Configurable<bool> removeCollWSplitVtx{"removeCollWSplitVtx", true, "Flag for rejecting the splitted collisions"};
191+
Configurable<bool> useSel8{"useSel8", true, "Flag for applying sel8 for collision selection"};
192+
Configurable<bool> selNoSameBunchPileUpColl{"selNoSameBunchPileUpColl", true, "Flag for rejecting the collisions associated with the same bunch crossing"};
193+
Configurable<float> zVtxMax{"zVtxMax", 10., "max. position-z of the reconstructed collision"};
189194
Configurable<bool> applyEfficiency{"applyEfficiency", true, "Flag for applying D-meson efficiency weights"};
190195
Configurable<bool> removeDaughters{"removeDaughters", true, "Flag for removing D-meson daughters from correlations"};
191196
Configurable<float> yCandMax{"yCandMax", 0.8, "max. cand. rapidity"};
@@ -210,6 +215,7 @@ struct HfCorrelatorDplusHadrons {
210215
// Event Mixing for the Data Mode
211216
using SelCollisionsWithDplus = soa::Filtered<soa::Join<aod::Collisions, aod::Mults, aod::EvSels, aod::DmesonSelection>>;
212217
using SelCollisionsWithDplusMc = soa::Filtered<soa::Join<aod::McCollisions, aod::DmesonSelection, aod::MultsExtraMC>>; // collisionFilter applied
218+
using CollisionsMc = soa::Join<aod::McCollisions, aod::MultsExtraMC>;
213219
using CandidatesDplusData = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelDplusToPiKPi, aod::HfMlDplusToPiKPi>>;
214220
// Event Mixing for the MCRec Mode
215221
using CandidatesDplusMcRec = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelDplusToPiKPi, aod::HfMlDplusToPiKPi, aod::HfCand3ProngMcRec>>;
@@ -226,6 +232,8 @@ struct HfCorrelatorDplusHadrons {
226232
Filter dplusFilter = ((o2::aod::hf_track_index::hfflag & static_cast<uint8_t>(1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi)) != static_cast<uint8_t>(0)) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus;
227233
Filter trackFilter = (nabs(aod::track::eta) < etaTrackMax) && (nabs(aod::track::pt) > ptTrackMin) && (nabs(aod::track::dcaXY) < dcaXYTrackMax) && (nabs(aod::track::dcaZ) < dcaZTrackMax);
228234
Preslice<aod::McParticles> presliceMc{aod::mcparticle::mcCollisionId};
235+
Preslice<CandDplusMcGen> candMcGenPerMcCollision = o2::aod::mcparticle::mcCollisionId;
236+
PresliceUnsorted<soa::Join<aod::Collisions, aod::FT0Mults, aod::EvSels, aod::McCollisionLabels>> recoCollisionsPerMcCollision = o2::aod::mccollisionlabel::mcCollisionId;
229237
// Filter particlesFilter = nabs(aod::mcparticle::pdgCode) == 411 || ((aod::mcparticle::flags & (uint8_t)o2::aod::mcparticle::enums::PhysicalPrimary) == (uint8_t)o2::aod::mcparticle::enums::PhysicalPrimary);
230238
ConfigurableAxis binsMultiplicity{"binsMultiplicity", {VARIABLE_WIDTH, 0.0f, 2000.0f, 6000.0f, 100000.0f}, "Mixing bins - multiplicity"};
231239
ConfigurableAxis binsZVtx{"binsZVtx", {VARIABLE_WIDTH, -10.0f, -2.5f, 2.5f, 10.0f}, "Mixing bins - z-vertex"};
@@ -311,6 +319,126 @@ struct HfCorrelatorDplusHadrons {
311319
corrBinning = {{binsZVtx, binsMultiplicity}, true};
312320
}
313321

322+
template <typename ParticleContainer, typename AssocContainer>
323+
void runMcGenDplusHadronAnalysis(const ParticleContainer& particlesToLoop, const AssocContainer& groupedMcParticles, int poolBin, int& counterDplusHadron)
324+
{
325+
for (const auto& particle : particlesToLoop) {
326+
327+
if (std::abs(particle.pdgCode()) != Pdg::kDPlus) {
328+
continue;
329+
}
330+
331+
if (std::abs(particle.flagMcMatchGen()) != hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) {
332+
continue;
333+
}
334+
335+
double yD = RecoDecay::y(particle.pVector(), MassDPlus);
336+
337+
if (std::abs(yD) > yCandGenMax ||
338+
particle.pt() < ptCandMin ||
339+
particle.pt() > ptCandMax) {
340+
continue;
341+
}
342+
343+
std::vector<int> listDaughters{};
344+
std::array<int, NDaughters> const arrDaughDplusPDG = {+kPiPlus, -kKPlus, kPiPlus};
345+
std::array<int, NDaughters> prongsId{};
346+
347+
RecoDecay::getDaughters(particle, &listDaughters, arrDaughDplusPDG, 2);
348+
349+
if (listDaughters.size() != NDaughters) {
350+
continue;
351+
}
352+
353+
bool isDaughtersOk = true;
354+
int counterDaughters = 0;
355+
356+
for (const auto& dauIdx : listDaughters) {
357+
auto daughI = particlesToLoop.rawIteratorAt(dauIdx - particlesToLoop.offset());
358+
359+
if (std::abs(daughI.eta()) >= EtaDaughtersMax) {
360+
isDaughtersOk = false;
361+
break;
362+
}
363+
364+
prongsId[counterDaughters++] = daughI.globalIndex();
365+
}
366+
367+
if (!isDaughtersOk) { // Skip this D+ candidate if any daughter fails eta cut
368+
continue;
369+
}
370+
counterDplusHadron++;
371+
372+
registry.fill(HIST("hDplusBin"), poolBin);
373+
registry.fill(HIST("hPtCandMCGen"), particle.pt());
374+
registry.fill(HIST("hEtaMcGen"), particle.eta());
375+
registry.fill(HIST("hPhiMcGen"), RecoDecay::constrainAngle(particle.phi(), -PIHalf));
376+
registry.fill(HIST("hYMCGen"), yD);
377+
378+
// Prompt / Non-prompt separation
379+
bool isDplusPrompt = particle.originMcGen() == RecoDecay::OriginType::Prompt;
380+
bool isDplusNonPrompt = particle.originMcGen() == RecoDecay::OriginType::NonPrompt;
381+
382+
if (isDplusPrompt) {
383+
registry.fill(HIST("hPtCandMcGenPrompt"), particle.pt());
384+
} else if (isDplusNonPrompt) {
385+
registry.fill(HIST("hPtCandMcGenNonPrompt"), particle.pt());
386+
}
387+
388+
// Count triggers
389+
registry.fill(HIST("hcountDplustriggersMCGen"), 0, particle.pt());
390+
391+
for (const auto& particleAssoc : groupedMcParticles) {
392+
393+
if (std::abs(particleAssoc.eta()) > etaTrackMax ||
394+
particleAssoc.pt() < ptTrackMin ||
395+
particleAssoc.pt() > ptTrackMax) {
396+
continue;
397+
}
398+
399+
// Remove daughters if requested
400+
if (removeDaughters) {
401+
if (particleAssoc.globalIndex() == prongsId[0] ||
402+
particleAssoc.globalIndex() == prongsId[1] ||
403+
particleAssoc.globalIndex() == prongsId[2]) {
404+
continue;
405+
}
406+
}
407+
408+
// Particle species selection
409+
if ((std::abs(particleAssoc.pdgCode()) != kElectron) &&
410+
(std::abs(particleAssoc.pdgCode()) != kMuonMinus) &&
411+
(std::abs(particleAssoc.pdgCode()) != kPiPlus) &&
412+
(std::abs(particleAssoc.pdgCode()) != kKPlus) &&
413+
(std::abs(particleAssoc.pdgCode()) != kProton)) {
414+
continue;
415+
}
416+
417+
if (!particleAssoc.isPhysicalPrimary()) {
418+
continue;
419+
}
420+
421+
int trackOrigin = RecoDecay::getCharmHadronOrigin(groupedMcParticles,
422+
particleAssoc,
423+
true);
424+
425+
registry.fill(HIST("hPtParticleAssocMcGen"), particleAssoc.pt());
426+
entryDplusHadronPair(
427+
getDeltaPhi(particleAssoc.phi(), particle.phi()),
428+
particleAssoc.eta() - particle.eta(),
429+
particle.pt(),
430+
particleAssoc.pt(),
431+
poolBin
432+
);
433+
434+
entryDplusHadronRecoInfo(MassDPlus, true);
435+
entryDplusHadronGenInfo(isDplusPrompt,
436+
particleAssoc.isPhysicalPrimary(),
437+
trackOrigin);
438+
}
439+
}
440+
}
441+
314442
/// Dplus-hadron correlation pair builder - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth)
315443
void processData(SelCollisionsWithDplus::iterator const& collision,
316444
TracksData const& tracks,
@@ -535,103 +663,68 @@ struct HfCorrelatorDplusHadrons {
535663
}
536664
PROCESS_SWITCH(HfCorrelatorDplusHadrons, processMcRec, "Process MC Reco mode", true);
537665

538-
/// Dplus-Hadron correlation pair builder - for MC gen-level analysis (no filter/selection, only true signal)
539-
void processMcGen(SelCollisionsWithDplusMc::iterator const& mcCollision,
540-
CandDplusMcGen const& mcParticles)
541-
{
666+
/// Dplus-Hadron correlation pair builder - for MC gen-level analysis (no filter/selection, only true signal)
667+
void processMcGen(CollisionsMc const& mcCollisions,
668+
soa::Join<aod::Collisions, aod::FT0Mults, aod::EvSels, aod::McCollisionLabels> const& collisions,
669+
CandDplusMcGen const& mcParticles)
670+
{
671+
BinningTypeMcGen const corrBinningMcGen{{binsZVtx, binsMultiplicityMc}, true};
672+
673+
for (const auto& mcCollision : mcCollisions) {
674+
542675
int counterDplusHadron = 0;
543676
registry.fill(HIST("hMCEvtCount"), 0);
544677

545-
BinningTypeMcGen const corrBinningMcGen{{binsZVtx, binsMultiplicityMc}, true};
546678
int poolBin = corrBinningMcGen.getBin(std::make_tuple(mcCollision.posZ(), mcCollision.multMCFT0A()));
547679
registry.fill(HIST("hMultFT0AMcGen"), mcCollision.multMCFT0A());
548680

549-
// MC gen level
550-
for (const auto& particle1 : mcParticles) {
551-
// check if the particle is Dplus (for general plot filling and selection, so both cases are fine) - NOTE: decay channel is not probed!
552-
if (std::abs(particle1.pdgCode()) != Pdg::kDPlus) {
553-
continue;
554-
}
555-
if (std::abs(particle1.flagMcMatchGen()) != hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) {
556-
continue;
557-
}
558-
double const yD = RecoDecay::y(particle1.pVector(), MassDPlus);
559-
if (std::abs(yD) >= yCandMax || particle1.pt() <= ptCandMin) {
681+
const auto groupedMcParticles = mcParticles.sliceBy(candMcGenPerMcCollision, mcCollision.globalIndex());
682+
const auto groupedCollisions = collisions.sliceBy(recoCollisionsPerMcCollision, mcCollision.globalIndex());
683+
684+
if (removeUnreconstructedGenCollisions) {
685+
686+
if (groupedCollisions.size() < 1) {
560687
continue;
561688
}
562-
std::vector<int> listDaughters{};
563-
std::array<int, NDaughters> const arrDaughDplusPDG = {+kPiPlus, -kKPlus, kPiPlus};
564-
std::array<int, NDaughters> prongsId{};
565-
listDaughters.clear();
566-
RecoDecay::getDaughters(particle1, &listDaughters, arrDaughDplusPDG, 2);
567-
int counterDaughters = 0;
568-
if (listDaughters.size() != NDaughters) {
689+
690+
if (groupedCollisions.size() > 1 && removeCollWSplitVtx) {
569691
continue;
570692
}
571-
bool isDaughtersOk = true;
572-
for (const auto& dauIdx : listDaughters) {
573-
auto daughI = mcParticles.rawIteratorAt(dauIdx - mcParticles.offset());
574-
if (std::abs(daughI.eta()) >= EtaDaughtersMax) {
575-
isDaughtersOk = false;
576-
break;
577-
}
578-
counterDaughters += 1;
579-
prongsId[counterDaughters - 1] = daughI.globalIndex();
580-
}
581-
if (!isDaughtersOk) {
582-
continue; // Skip this D+ candidate if any daughter fails eta cut
583-
}
584-
counterDplusHadron++;
585-
586-
registry.fill(HIST("hDplusBin"), poolBin);
587-
registry.fill(HIST("hPtCandMCGen"), particle1.pt());
588-
registry.fill(HIST("hEtaMcGen"), particle1.eta());
589-
registry.fill(HIST("hPhiMcGen"), RecoDecay::constrainAngle(particle1.phi(), -PIHalf));
590-
registry.fill(HIST("hYMCGen"), yD);
591693

592-
// prompt and non-prompt division
593-
bool isDplusPrompt = particle1.originMcGen() == RecoDecay::OriginType::Prompt;
594-
bool isDplusNonPrompt = particle1.originMcGen() == RecoDecay::OriginType::NonPrompt;
595-
if (isDplusPrompt) {
596-
registry.fill(HIST("hPtCandMcGenPrompt"), particle1.pt());
597-
} else if (isDplusNonPrompt) {
598-
registry.fill(HIST("hPtCandMcGenNonPrompt"), particle1.pt());
599-
}
694+
for (const auto& collision : groupedCollisions) {
600695

601-
// Dplus Hadron correlation dedicated section
602-
// if it's a Dplus particle, search for Hadron and evaluate correlations
603-
registry.fill(HIST("hcountDplustriggersMCGen"), 0, particle1.pt()); // to count trigger Dplus for normalisation)
604-
for (const auto& particleAssoc : mcParticles) {
605-
if (std::abs(particleAssoc.eta()) > etaTrackMax || particleAssoc.pt() < ptTrackMin || particleAssoc.pt() > ptTrackMax) {
696+
if (useSel8 && !collision.sel8()) {
606697
continue;
607698
}
608-
if (removeDaughters) {
609-
if (particleAssoc.globalIndex() == prongsId[0] || particleAssoc.globalIndex() == prongsId[1] || particleAssoc.globalIndex() == prongsId[2]) {
610-
continue;
611-
}
699+
700+
if (std::abs(collision.posZ()) > zVtxMax) {
701+
continue;
612702
}
613-
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)) {
703+
704+
if (selNoSameBunchPileUpColl &&
705+
!(collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup))) {
614706
continue;
615707
}
616-
if (!particleAssoc.isPhysicalPrimary()) {
708+
709+
if (!collision.has_mcCollision()) {
710+
registry.fill(HIST("hFakeCollision"), 0.);
617711
continue;
618712
}
619713

620-
int trackOrigin = RecoDecay::getCharmHadronOrigin(mcParticles, particleAssoc, true);
621-
registry.fill(HIST("hPtParticleAssocMcGen"), particleAssoc.pt());
622-
entryDplusHadronPair(getDeltaPhi(particleAssoc.phi(), particle1.phi()),
623-
particleAssoc.eta() - particle1.eta(),
624-
particle1.pt(),
625-
particleAssoc.pt(),
626-
poolBin);
627-
entryDplusHadronRecoInfo(MassDPlus, true);
628-
entryDplusHadronGenInfo(isDplusPrompt, particleAssoc.isPhysicalPrimary(), trackOrigin);
629-
} // end associated loop
630-
} // end trigger
714+
// MC particles with reconstructed-collision selection
715+
runMcGenDplusHadronAnalysis(groupedMcParticles, groupedMcParticles, poolBin, counterDplusHadron);
716+
}
717+
718+
}
719+
else {
720+
// MC particles without reconstructed-collision selection (preliminay approval approach)
721+
runMcGenDplusHadronAnalysis(groupedMcParticles, groupedMcParticles, poolBin, counterDplusHadron);
722+
}
723+
631724
registry.fill(HIST("hcountDplusHadronPerEvent"), counterDplusHadron);
632725
registry.fill(HIST("hZvtx"), mcCollision.posZ());
633-
// registry.fill(HIST("hMultiplicity"), getTracksSize(mcCollision));
634726
}
727+
}
635728
PROCESS_SWITCH(HfCorrelatorDplusHadrons, processMcGen, "Process MC Gen mode", false);
636729

637730
void processDataMixedEvent(SelCollisionsWithDplus const& collisions,

0 commit comments

Comments
 (0)