Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions Analysis/Core/include/AnalysisCore/RecoDecay.h
Original file line number Diff line number Diff line change
Expand Up @@ -562,12 +562,13 @@ class RecoDecay
/// \param depthMax maximum decay tree level; Daughters at this level (or beyond) will be considered final. If -1, all levels are considered.
/// \param stage decay tree level; If different from 0, the particle itself will be added in the list in case it has no daughters.
/// \note Final state is defined as particles from arrPDGFinal plus final daughters of any other decay branch.
/// \note Antiparticles of particles in arrPDGFinal are accepted as well.
template <std::size_t N, typename T>
static void getDaughters(const T& particlesMC,
int index,
std::vector<int>* list,
const array<int, N>& arrPDGFinal,
int depthMax = -1,
int8_t depthMax = -1,
int8_t stage = 0)
{
if (index <= -1) {
Expand Down Expand Up @@ -597,11 +598,12 @@ class RecoDecay
// If this is not the original particle, we are at the end of this branch and this particle is final.
isFinal = true;
}
// If the particle has daughters but is considered to be final, we label it as final.
auto PDGParticle = particle.pdgCode();
if (!isFinal) {
auto PDGParticle = std::abs(particle.pdgCode());
// If this is not the original particle, check its PDG code.
if (!isFinal && stage > 0) {
// If the particle has daughters but is considered to be final, we label it as final.
for (auto PDGi : arrPDGFinal) {
if (std::abs(PDGParticle) == std::abs(PDGi)) { // Accept antiparticles.
if (PDGParticle == std::abs(PDGi)) { // Accept antiparticles.
isFinal = true;
break;
}
Expand Down Expand Up @@ -744,12 +746,13 @@ class RecoDecay
/// \param candidate candidate MC particle
/// \param PDGParticle expected particle PDG code
/// \param acceptAntiParticles switch to accept the antiparticle
/// \param sign antiparticle indicator of the candidate w.r.t. PDGParticle; 1 if particle, -1 if antiparticle, 0 if not matched
/// \return true if PDG code of the particle is correct, false otherwise
template <typename T, typename U>
static int isMatchedMCGen(const T& particlesMC, const U& candidate, int PDGParticle, bool acceptAntiParticles = false)
static int isMatchedMCGen(const T& particlesMC, const U& candidate, int PDGParticle, bool acceptAntiParticles = false, int8_t* sign = nullptr)
{
array<int, 0> arrPDGDaughters;
return isMatchedMCGen(particlesMC, candidate, PDGParticle, std::move(arrPDGDaughters), acceptAntiParticles);
return isMatchedMCGen(particlesMC, candidate, PDGParticle, std::move(arrPDGDaughters), acceptAntiParticles, sign);
}

/// Check whether the MC particle is the expected one and whether it decayed via the expected decay channel.
Expand All @@ -776,8 +779,7 @@ class RecoDecay
sgn = 1;
} else if (acceptAntiParticles && PDGCandidate == -PDGParticle) { // antiparticle PDG match
sgn = -1;
}
if (sgn == 0) {
} else {
//Printf("MC Gen: Rejected: bad particle PDG: %s%d != %d", acceptAntiParticles ? "abs " : "", PDGCandidate, std::abs(PDGParticle));
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ DECLARE_SOA_DYNAMIC_COLUMN(MaxNormalisedDeltaIP, maxNormalisedDeltaIP, [](float
// - ±LcToPKPi: Λc± → p± K∓ π±
DECLARE_SOA_COLUMN(FlagMCMatchRec, flagMCMatchRec, int8_t); // reconstruction level
DECLARE_SOA_COLUMN(FlagMCMatchGen, flagMCMatchGen, int8_t); // generator level
DECLARE_SOA_COLUMN(FlagMCDecayChanRec, flagMCDecayChanRec, int8_t); // Resonant decay channel flag, reconstruction level
DECLARE_SOA_COLUMN(FlagMCDecayChanGen, flagMCDecayChanGen, int8_t); // Resonant decay channel flag, generator level

// mapping of decay types
enum DecayType { DPlusToPiKPi = 0,
Expand Down Expand Up @@ -428,11 +430,13 @@ using HfCandProng3 = HfCandProng3Ext;

// table with results of reconstruction level MC matching
DECLARE_SOA_TABLE(HfCandProng3MCRec, "AOD", "HFCANDP3MCREC",
hf_cand_prong3::FlagMCMatchRec);
hf_cand_prong3::FlagMCMatchRec,
hf_cand_prong3::FlagMCDecayChanRec);

// table with results of generator level MC matching
DECLARE_SOA_TABLE(HfCandProng3MCGen, "AOD", "HFCANDP3MCGEN",
hf_cand_prong3::FlagMCMatchGen);
hf_cand_prong3::FlagMCMatchGen,
hf_cand_prong3::FlagMCDecayChanGen);

} // namespace o2::aod

Expand Down
52 changes: 48 additions & 4 deletions Analysis/Tasks/PWGHF/HFCandidateCreator3Prong.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,19 @@ struct HFCandidateCreator3ProngMC {
{
int8_t sign = 0;
int8_t flag = 0;
int8_t DecayChannel = 0;
std::vector<int> arrDaughIndex;
std::array<int, 2> arrPDGDaugh;
std::array<int, 2> arrPDGResonant1 = {2212, 313}; // Λc± → p± K*
std::array<int, 2> arrPDGResonant2 = {2224, 321}; // Λc± → Δ(1232)±± K∓
std::array<int, 2> arrPDGResonant3 = {3124, 211}; // Λc± → Λ(1520) π±

// Match reconstructed candidates.
for (auto& candidate : candidates) {
//Printf("New rec. candidate");
flag = 0;
DecayChannel = 0;
arrDaughIndex.clear();
auto arrayDaughters = array{candidate.index0_as<aod::BigTracksMC>(), candidate.index1_as<aod::BigTracksMC>(), candidate.index2_as<aod::BigTracksMC>()};

// D± → π± K∓ π±
Expand All @@ -168,18 +176,37 @@ struct HFCandidateCreator3ProngMC {
// Λc± → p± K∓ π±
if (flag == 0) {
//Printf("Checking Λc± → p± K∓ π±");
if (RecoDecay::getMatchedMCRec(particlesMC, std::move(arrayDaughters), 4122, array{+kProton, -kKPlus, +kPiPlus}, true, &sign) > -1) {
auto indexRecLc = RecoDecay::getMatchedMCRec(particlesMC, std::move(arrayDaughters), 4122, array{+kProton, -kKPlus, +kPiPlus}, true, &sign, 2);
if (indexRecLc > -1) {
flag = sign * (1 << LcToPKPi);

//Printf("Flagging the different Λc± → p± K∓ π± decay channels");
RecoDecay::getDaughters(particlesMC, indexRecLc, &arrDaughIndex, array{0}, 1);
if (arrDaughIndex.size() == 2) {
for (auto iProng = 0; iProng < arrDaughIndex.size(); ++iProng) {
auto daughI = particlesMC.iteratorAt(arrDaughIndex[iProng]);
arrPDGDaugh[iProng] = std::abs(daughI.pdgCode());
}
if (arrPDGDaugh[0] == arrPDGResonant1[0] && arrPDGDaugh[1] == arrPDGResonant1[1]) {
DecayChannel = 1;
} else if (arrPDGDaugh[0] == arrPDGResonant2[0] && arrPDGDaugh[1] == arrPDGResonant2[1]) {
DecayChannel = 2;
} else if (arrPDGDaugh[0] == arrPDGResonant3[0] && arrPDGDaugh[1] == arrPDGResonant3[1]) {
DecayChannel = 3;
}
}
}
}

rowMCMatchRec(flag);
rowMCMatchRec(flag, DecayChannel);
}

// Match generated particles.
for (auto& particle : particlesMC) {
//Printf("New gen. candidate");
flag = 0;
DecayChannel = 0;
arrDaughIndex.clear();

// D± → π± K∓ π±
//Printf("Checking D± → π± K∓ π±");
Expand All @@ -190,12 +217,29 @@ struct HFCandidateCreator3ProngMC {
// Λc± → p± K∓ π±
if (flag == 0) {
//Printf("Checking Λc± → p± K∓ π±");
if (RecoDecay::isMatchedMCGen(particlesMC, particle, 4122, array{+kProton, -kKPlus, +kPiPlus}, true, &sign)) {
auto isMatchedGenLc = RecoDecay::isMatchedMCGen(particlesMC, particle, 4122, array{+kProton, -kKPlus, +kPiPlus}, true, &sign, 2);
if (isMatchedGenLc) {
flag = sign * (1 << LcToPKPi);

//Printf("Flagging the different Λc± → p± K∓ π± decay channels");
RecoDecay::getDaughters(particlesMC, particle.globalIndex(), &arrDaughIndex, array{0}, 1);
if (arrDaughIndex.size() == 2) {
for (auto jProng = 0; jProng < arrDaughIndex.size(); ++jProng) {
auto daughJ = particlesMC.iteratorAt(arrDaughIndex[jProng]);
arrPDGDaugh[jProng] = std::abs(daughJ.pdgCode());
}
if (arrPDGDaugh[0] == arrPDGResonant1[0] && arrPDGDaugh[1] == arrPDGResonant1[1]) {
DecayChannel = 1;
} else if (arrPDGDaugh[0] == arrPDGResonant2[0] && arrPDGDaugh[1] == arrPDGResonant2[1]) {
DecayChannel = 2;
} else if (arrPDGDaugh[0] == arrPDGResonant3[0] && arrPDGDaugh[1] == arrPDGResonant3[1]) {
DecayChannel = 3;
}
}
}
}

rowMCMatchGen(flag);
rowMCMatchGen(flag, DecayChannel);
}
}
};
Expand Down