Skip to content

Commit eab29c9

Browse files
fgrosaalibuild
andauthored
[Common] Generalise navigation of mother indices for MC truth matching (#18222)
Co-authored-by: ALICE Action Bot <alibuild@cern.ch>
1 parent 1223729 commit eab29c9

1 file changed

Lines changed: 59 additions & 29 deletions

File tree

‎Common/Core/RecoDecay.h‎

Lines changed: 59 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <cmath> // std::abs, std::sqrt
2828
#include <cstddef> // std::size_t
2929
#include <cstdint> // intX_t
30+
#include <numeric> // std::iota
3031
#include <tuple> // std::apply
3132
#include <type_traits> // std::decay_t
3233
#include <utility> // std::move
@@ -49,6 +50,10 @@ struct RecoDecay {
4950
};
5051

5152
static constexpr int8_t StatusCodeAfterFlavourOscillation{92}; // decay products after B0(s) flavour oscillation
53+
static constexpr int8_t StatusCodePrimaryMin{81}; // primary particles (after hadronization) have status code >= 81
54+
static constexpr int8_t StatusCodePrimaryMax{89}; // primary particles (after hadronization) have status code <= 89
55+
static constexpr int8_t StatusCodeRhadronMin{101}; // R-hadrons (after hadronization) have status code >= 101
56+
static constexpr int8_t StatusCodeRhadronMax{109}; // R-hadrons (after hadronization) have status code <= 109
5257
static constexpr int PdgQuarkMax{8}; // largest quark PDG code; o2-linter: disable=pdg/explicit-code (t' does not have a named constant.)
5358
static constexpr int PdgBosonMin{PDG_t::kGluon}; // smallest boson (gauge or H) PDG code
5459
static constexpr int PdgBosonMax{37}; // largest boson (gauge or H) PDG code; o2-linter: disable=pdg/explicit-code (H+ does not have a named constant.)
@@ -561,6 +566,46 @@ struct RecoDecay {
561566
return maxNormDeltaIP;
562567
}
563568

569+
template <typename PPart>
570+
static void getOrderedMotherIds(const PPart& particle,
571+
std::vector<int64_t>& motherIdsOrdered,
572+
const bool searchUpToQuark = false)
573+
{
574+
if (!particle.has_mothers()) {
575+
return;
576+
}
577+
578+
if (particle.mothersIds().front() == particle.globalIndex()) {
579+
return;
580+
}
581+
582+
if (!searchUpToQuark) {
583+
motherIdsOrdered.push_back(particle.mothersIds().front());
584+
} else {
585+
if (particle.mothersIds().size() == 2) {
586+
if (particle.mothersIds().front() == particle.mothersIds().back()) {
587+
motherIdsOrdered.push_back(particle.mothersIds().front());
588+
} else if (particle.mothersIds().front() < particle.mothersIds().back()) {
589+
auto absStatusCode = std::abs(particle.getGenStatusCode());
590+
if ((absStatusCode >= StatusCodePrimaryMin && absStatusCode <= StatusCodePrimaryMax) || (absStatusCode >= StatusCodeRhadronMin && absStatusCode <= StatusCodeRhadronMax)) {
591+
motherIdsOrdered.resize(particle.mothersIds().back() - particle.mothersIds().front() + 1);
592+
std::iota(motherIdsOrdered.begin(), motherIdsOrdered.end(), particle.mothersIds().front());
593+
} else {
594+
motherIdsOrdered.push_back(particle.mothersIds().front());
595+
motherIdsOrdered.push_back(particle.mothersIds().back());
596+
}
597+
} else if (particle.mothersIds().front() > particle.mothersIds().back()) {
598+
if (particle.mothersIds().back() != 0) {
599+
motherIdsOrdered.push_back(particle.mothersIds().back());
600+
}
601+
motherIdsOrdered.push_back(particle.mothersIds().front());
602+
}
603+
} else if (particle.mothersIds().size() == 1) {
604+
motherIdsOrdered.push_back(particle.mothersIds().front());
605+
}
606+
}
607+
}
608+
564609
/// Finds the mother of an MC particle by looking for the expected PDG code in the mother chain.
565610
/// \tparam acceptFlavourOscillation switch to accept decays where the mother oscillated (e.g. B0 -> B0bar)
566611
/// \param particlesMC table with MC particles
@@ -599,10 +644,12 @@ struct RecoDecay {
599644
for (auto iPart : arrayIds[-stage]) { // check all the particles that were the mothers at the previous stage, o2-linter: disable=const-ref-in-for-loop (int elements)
600645
auto particleMother = particlesMC.rawIteratorAt(iPart - particlesMC.offset());
601646
if (particleMother.has_mothers()) {
602-
// If searchUpToQuark is false we only take the first mother (since decay products only have one mother)
603-
auto lastMotherIdxToCheck = searchUpToQuark ? particleMother.mothersIds().back() : particleMother.mothersIds().front();
604-
for (auto iMother = particleMother.mothersIds().front(); iMother <= lastMotherIdxToCheck; ++iMother) { // loop over the mother particles of the analysed particle
605-
if (std::find(arrayIdsStage.begin(), arrayIdsStage.end(), iMother) != arrayIdsStage.end()) { // if a mother is still present in the vector, do not check it again
647+
648+
std::vector<int64_t> motherIdsOrdered{};
649+
getOrderedMotherIds(particleMother, motherIdsOrdered, searchUpToQuark);
650+
651+
for (auto const& iMother : motherIdsOrdered) { // loop over the mother particles of the analysed particle
652+
if (std::find(arrayIdsStage.begin(), arrayIdsStage.end(), iMother) != arrayIdsStage.end()) { // if a mother is still present in the vector, do not check it again
606653
continue;
607654
}
608655
auto mother = particlesMC.rawIteratorAt(iMother - particlesMC.offset());
@@ -1059,6 +1106,7 @@ struct RecoDecay {
10591106
while (arrayIds[-stage].size() > 0) {
10601107
// vector of mother indices for the current stage
10611108
std::vector<int64_t> arrayIdsStage{};
1109+
std::vector<int64_t> motherIdsOrdered{};
10621110
for (auto iPart : arrayIds[-stage]) { // check all the particles that were the mothers at the previous stage, o2-linter: disable=const-ref-in-for-loop (int elements)
10631111
auto particleMother = particlesMC.rawIteratorAt(iPart - particlesMC.offset());
10641112
if (particleMother.has_mothers()) {
@@ -1072,8 +1120,9 @@ struct RecoDecay {
10721120
}
10731121
}
10741122

1075-
for (auto iMother = particleMother.mothersIds().front(); iMother <= particleMother.mothersIds().back(); ++iMother) { // loop over the mother particles of the analysed particle
1076-
if (std::find(arrayIdsStage.begin(), arrayIdsStage.end(), iMother) != arrayIdsStage.end()) { // if a mother is still present in the vector, do not check it again
1123+
getOrderedMotherIds(particleMother, motherIdsOrdered, searchUpToQuark);
1124+
for (auto const& iMother : motherIdsOrdered) { // loop over the mother particles of the analysed particle
1125+
if (std::find(arrayIdsStage.begin(), arrayIdsStage.end(), iMother) != arrayIdsStage.end()) { // if a mother is still present in the vector, do not check it again
10771126
continue;
10781127
}
10791128
auto mother = particlesMC.rawIteratorAt(iMother - particlesMC.offset());
@@ -1161,30 +1210,11 @@ struct RecoDecay {
11611210
auto particleMother = particlesMC.rawIteratorAt(iPart - particlesMC.offset());
11621211
if (particleMother.has_mothers()) {
11631212

1164-
// we break immediately if searchUpToQuark is false and the first mother is a quark or a boson (a hadron should never be the mother of a parton)
1165-
if (!searchUpToQuark) {
1166-
auto mother = particlesMC.rawIteratorAt(particleMother.mothersIds().front() - particlesMC.offset());
1167-
auto pdgParticleIMother = std::abs(mother.pdgCode()); // PDG code of the mother
1168-
if (pdgParticleIMother <= PdgQuarkMax || (pdgParticleIMother >= PdgBosonMin && pdgParticleIMother <= PdgBosonMax)) {
1169-
// auto PDGPaticle = std::abs(particleMother.pdgCode());
1170-
if (
1171-
(pdgParticle / PdgDivisorMeson == PDG_t::kBottom || // b mesons
1172-
pdgParticle / PdgDivisorBaryon == PDG_t::kBottom) // b baryons
1173-
) {
1174-
return OriginType::NonPrompt; // beauty
1175-
}
1176-
if (
1177-
(pdgParticle / PdgDivisorMeson == PDG_t::kCharm || // c mesons
1178-
pdgParticle / PdgDivisorBaryon == PDG_t::kCharm) // c baryons
1179-
) {
1180-
return OriginType::Prompt; // charm
1181-
}
1182-
break;
1183-
}
1184-
}
1213+
std::vector<int64_t> motherIdsOrdered{};
1214+
getOrderedMotherIds(particleMother, motherIdsOrdered, searchUpToQuark);
11851215

1186-
for (auto iMother = particleMother.mothersIds().front(); iMother <= particleMother.mothersIds().back(); ++iMother) { // loop over the mother particles of the analysed particle
1187-
if (std::find(arrayIdsStage.begin(), arrayIdsStage.end(), iMother) != arrayIdsStage.end()) { // if a mother is still present in the vector, do not check it again
1216+
for (auto const& iMother : motherIdsOrdered) { // loop over the mother particles of the analysed particle
1217+
if (std::find(arrayIdsStage.begin(), arrayIdsStage.end(), iMother) != arrayIdsStage.end()) { // if a mother is still present in the vector, do not check it again
11881218
continue;
11891219
}
11901220
auto mother = particlesMC.rawIteratorAt(iMother - particlesMC.offset());

0 commit comments

Comments
 (0)