2323#include < utility> // std::move
2424#include < vector> // std::vector
2525
26+ #include " TMCProcess.h" // for VMC Particle Production Process
2627#include " CommonConstants/MathConstants.h"
2728
2829// / Base class for calculating properties of reconstructed decays
@@ -595,14 +596,15 @@ class RecoDecay
595596 }
596597
597598 // / Gets the complete list of indices of final-state daughters of an MC particle.
599+ // / \param checkProcess switch to accept only decay daughters by checking the production process of MC particles
598600 // / \param particle MC particle
599601 // / \param list vector where the indices of final-state daughters will be added
600602 // / \param arrPDGFinal array of PDG codes of particles to be considered final if found
601603 // / \param depthMax maximum decay tree level; Daughters at this level (or beyond) will be considered final. If -1, all levels are considered.
602604 // / \param stage decay tree level; If different from 0, the particle itself will be added in the list in case it has no daughters.
603605 // / \note Final state is defined as particles from arrPDGFinal plus final daughters of any other decay branch.
604606 // / \note Antiparticles of particles in arrPDGFinal are accepted as well.
605- template <std::size_t N, typename T>
607+ template <bool checkProcess = false , std::size_t N, typename T>
606608 static void getDaughters (const T& particle,
607609 std::vector<int >* list,
608610 const std::array<int , N>& arrPDGFinal,
@@ -613,6 +615,13 @@ class RecoDecay
613615 // Printf("getDaughters: Error: No list!");
614616 return ;
615617 }
618+ if constexpr (checkProcess) {
619+ // If the particle is neither the original particle nor coming from a decay, we do nothing and exit.
620+ if (stage != 0 && particle.getProcess () != TMCProcess::kPDecay && particle.getProcess () != TMCProcess::kPPrimary ) { // decay products of HF hadrons are labeled as kPPrimary
621+ return ;
622+ }
623+ }
624+
616625 bool isFinal = false ; // Flag to indicate the end of recursion
617626 if (depthMax > -1 && stage >= depthMax) { // Maximum depth has been reached (or exceeded).
618627 isFinal = true ;
@@ -655,11 +664,12 @@ class RecoDecay
655664 // Call itself to get daughters of daughters recursively.
656665 stage++;
657666 for (auto & dau : particle.template daughters_as <typename std::decay_t <T>::parent_t >()) {
658- getDaughters (dau, list, arrPDGFinal, depthMax, stage);
667+ getDaughters<checkProcess> (dau, list, arrPDGFinal, depthMax, stage);
659668 }
660669 }
661670
662671 // / Checks whether the reconstructed decay candidate is the expected decay.
672+ // / \param checkProcess switch to accept only decay daughters by checking the production process of MC particles
663673 // / \param particlesMC table with MC particles
664674 // / \param arrDaughters array of candidate daughters
665675 // / \param PDGMother expected mother PDG code
@@ -668,7 +678,7 @@ class RecoDecay
668678 // / \param sign antiparticle indicator of the found mother w.r.t. PDGMother; 1 if particle, -1 if antiparticle, 0 if mother not found
669679 // / \param depthMax maximum decay tree level to check; Daughters up to this level will be considered. If -1, all levels are considered.
670680 // / \return index of the mother particle if the mother and daughters are correct, -1 otherwise
671- template <bool acceptFlavourOscillation = false , std::size_t N, typename T, typename U>
681+ template <bool acceptFlavourOscillation = false , bool checkProcess = false , std::size_t N, typename T, typename U>
672682 static int getMatchedMCRec (const T& particlesMC,
673683 const std::array<U, N>& arrDaughters,
674684 int PDGMother,
@@ -724,12 +734,14 @@ class RecoDecay
724734 return -1 ;
725735 }
726736 // Check that the number of direct daughters is not larger than the number of expected final daughters.
727- if (particleMother.daughtersIds ().back () - particleMother.daughtersIds ().front () + 1 > static_cast <int >(N)) {
728- // Printf("MC Rec: Rejected: too many direct daughters: %d (expected %ld final)", particleMother.daughtersIds().back() - particleMother.daughtersIds().front() + 1, N);
729- return -1 ;
737+ if constexpr (!checkProcess) {
738+ if (particleMother.daughtersIds ().back () - particleMother.daughtersIds ().front () + 1 > static_cast <int >(N)) {
739+ // Printf("MC Rec: Rejected: too many direct daughters: %d (expected %ld final)", particleMother.daughtersIds().back() - particleMother.daughtersIds().front() + 1, N);
740+ return -1 ;
741+ }
730742 }
731743 // Get the list of actual final daughters.
732- getDaughters (particleMother, &arrAllDaughtersIndex, arrPDGDaughters, depthMax);
744+ getDaughters<checkProcess> (particleMother, &arrAllDaughtersIndex, arrPDGDaughters, depthMax);
733745 // printf("MC Rec: Mother %d has %d final daughters:", indexMother, arrAllDaughtersIndex.size());
734746 // for (auto i : arrAllDaughtersIndex) {
735747 // printf(" %d", i);
@@ -779,24 +791,26 @@ class RecoDecay
779791 }
780792
781793 // / Checks whether the MC particle is the expected one.
794+ // / \param checkProcess switch to accept only decay daughters by checking the production process of MC particles
782795 // / \param particlesMC table with MC particles
783796 // / \param candidate candidate MC particle
784797 // / \param PDGParticle expected particle PDG code
785798 // / \param acceptAntiParticles switch to accept the antiparticle
786799 // / \param sign antiparticle indicator of the candidate w.r.t. PDGParticle; 1 if particle, -1 if antiparticle, 0 if not matched
787800 // / \return true if PDG code of the particle is correct, false otherwise
788- template <bool acceptFlavourOscillation = false , typename T, typename U>
801+ template <bool acceptFlavourOscillation = false , bool checkProcess = false , typename T, typename U>
789802 static int isMatchedMCGen (const T& particlesMC,
790803 const U& candidate,
791804 int PDGParticle,
792805 bool acceptAntiParticles = false ,
793806 int8_t * sign = nullptr )
794807 {
795808 std::array<int , 0 > arrPDGDaughters;
796- return isMatchedMCGen<acceptFlavourOscillation>(particlesMC, candidate, PDGParticle, std::move (arrPDGDaughters), acceptAntiParticles, sign);
809+ return isMatchedMCGen<acceptFlavourOscillation, checkProcess >(particlesMC, candidate, PDGParticle, std::move (arrPDGDaughters), acceptAntiParticles, sign);
797810 }
798811
799812 // / Check whether the MC particle is the expected one and whether it decayed via the expected decay channel.
813+ // / \param checkProcess switch to accept only decay daughters by checking the production process of MC particles
800814 // / \param particlesMC table with MC particles
801815 // / \param candidate candidate MC particle
802816 // / \param PDGParticle expected particle PDG code
@@ -806,7 +820,7 @@ class RecoDecay
806820 // / \param depthMax maximum decay tree level to check; Daughters up to this level will be considered. If -1, all levels are considered.
807821 // / \param listIndexDaughters vector of indices of found daughter
808822 // / \return true if PDG codes of the particle and its daughters are correct, false otherwise
809- template <bool acceptFlavourOscillation = false , std::size_t N, typename T, typename U>
823+ template <bool acceptFlavourOscillation = false , bool checkProcess = false , std::size_t N, typename T, typename U>
810824 static bool isMatchedMCGen (const T& particlesMC,
811825 const U& candidate,
812826 int PDGParticle,
@@ -843,12 +857,14 @@ class RecoDecay
843857 return false ;
844858 }
845859 // Check that the number of direct daughters is not larger than the number of expected final daughters.
846- if (candidate.daughtersIds ().back () - candidate.daughtersIds ().front () + 1 > static_cast <int >(N)) {
847- // Printf("MC Gen: Rejected: too many direct daughters: %d (expected %ld final)", candidate.daughtersIds().back() - candidate.daughtersIds().front() + 1, N);
848- return false ;
860+ if constexpr (!checkProcess) {
861+ if (candidate.daughtersIds ().back () - candidate.daughtersIds ().front () + 1 > static_cast <int >(N)) {
862+ // Printf("MC Gen: Rejected: too many direct daughters: %d (expected %ld final)", candidate.daughtersIds().back() - candidate.daughtersIds().front() + 1, N);
863+ return false ;
864+ }
849865 }
850866 // Get the list of actual final daughters.
851- getDaughters (candidate, &arrAllDaughtersIndex, arrPDGDaughters, depthMax);
867+ getDaughters<checkProcess> (candidate, &arrAllDaughtersIndex, arrPDGDaughters, depthMax);
852868 // printf("MC Gen: Mother %ld has %ld final daughters:", candidate.globalIndex(), arrAllDaughtersIndex.size());
853869 // for (auto i : arrAllDaughtersIndex) {
854870 // printf(" %d", i);
0 commit comments