@@ -32,6 +32,8 @@ enum class EM_HFeeType : int {
3232 kBCe_BCe = 2 , // ULS
3333 kBCe_Be_SameB = 3 , // ULS
3434 kBCe_Be_DiffB = 4 , // LS
35+ kBCCe_BCe = 5 , // ULS
36+ kBCCe_BCCe = 6 , // ULS
3537};
3638
3739// _______________________________________________________________________
@@ -461,6 +463,55 @@ int IsFromCharm(TMCParticle const& p, TMCParticles const& mcparticles)
461463 return -999 ;
462464}
463465// _______________________________________________________________________
466+ template <typename T, typename U>
467+ int hasNCharmHadronsInBeautyDecay (T const & mcParticle, U const & mcParticles)
468+ {
469+ // require that the direct mother is beauty hadron via semileptonice decay. e.g. hb->e, not hb->X->pi0->eegamma
470+ if (!mcParticle.has_mothers ()) {
471+ return -999 ;
472+ }
473+ if (!IsFromBeauty (mcParticle, mcParticles)) {
474+ return -999 ;
475+ }
476+
477+ auto mp = mcParticles.iteratorAt (mcParticle.mothersIds ()[0 ]);
478+ if (!isCharmMeson (mp) && !isCharmBaryon (mp)) {
479+ return -999 ;
480+ }
481+
482+ int motherid = mcParticle.mothersIds ()[0 ]; // first mother index
483+ while (motherid > -1 ) {
484+ if (motherid < mcParticles.size ()) { // protect against bad mother indices. why is this needed?
485+ mp = mcParticles.iteratorAt (motherid);
486+ if (std::abs (mp.pdgCode ()) < 1e+9 && (std::to_string (std::abs (mp.pdgCode ()))[std::to_string (std::abs (mp.pdgCode ())).length () - 3 ] == ' 5' || std::to_string (std::abs (mp.pdgCode ()))[std::to_string (std::abs (mp.pdgCode ())).length () - 4 ] == ' 5' )) {
487+ // check if mp has two charm hadrons as daughters
488+ if (mp.has_daughters ()) {
489+ const auto & daughtersIds = mp.daughtersIds ();
490+ int count_charm_hadron = 0 ;
491+ for (const auto & daughterId : daughtersIds) {
492+ if (daughterId >= 0 && daughterId < mcParticles.size ()) {
493+ auto daughter = mcParticles.iteratorAt (daughterId);
494+ if (isCharmMeson (daughter) || isCharmBaryon (daughter)) {
495+ count_charm_hadron++;
496+ }
497+ }
498+ }
499+ return count_charm_hadron;
500+ } else {
501+ LOGF (debug, " Something went wrong: Did not find any daughter for the current mother! Can't be a mother if there are no daughters\n " );
502+ }
503+ }
504+ if (mp.has_mothers ()) {
505+ motherid = mp.mothersIds ()[0 ];
506+ } else {
507+ return -999 ;
508+ }
509+ } else {
510+ LOGF (info, " Mother label(%d) exceeds the McParticles size(%d)" , motherid, mcParticles.size ());
511+ }
512+ }
513+ }
514+ // _______________________________________________________________________
464515template <typename TMCParticle>
465516bool isFlavorOscillationB (TMCParticle const & mcParticle)
466517{
@@ -661,7 +712,18 @@ int IsHF(TMCParticle1 const& p1, TMCParticle2 const& p2, TMCParticles const& mcp
661712 mothers_pdg1.shrink_to_fit ();
662713 mothers_id2.shrink_to_fit ();
663714 mothers_pdg2.shrink_to_fit ();
664- return static_cast <int >(EM_HFeeType::kBCe_BCe ); // b->c->e and b->c->e, decay type = 1
715+ int n_c_from_b1 = hasNCharmHadronsInBeautyDecay (p1, mcparticles);
716+ int n_c_from_b2 = hasNCharmHadronsInBeautyDecay (p2, mcparticles);
717+ if (n_c_from_b1 == 1 && n_c_from_b2 == 1 ) {
718+ return static_cast <int >(EM_HFeeType::kBCe_BCe ); // b->c->e and b->c->e, decay type = 1
719+ } else if (n_c_from_b1 == 2 && n_c_from_b2 == 2 ) {
720+ return static_cast <int >(EM_HFeeType::kBCCe_BCCe ); // b->cc->e and b->cc->e, decay type = 6
721+ } else if ((n_c_from_b1 == 1 && n_c_from_b2 == 2 ) || (n_c_from_b1 == 2 && n_c_from_b2 == 1 )) {
722+ return static_cast <int >(EM_HFeeType::kBCCe_BCe ); // b->cc->e and b->c->e, decay type = 5
723+ } else {
724+ LOGF (debug, " Unexpected number of charm hadrons from beauty decay: n_c_from_b1 = %d, n_c_from_b2 = %d. Return kBCe_BCe as default." , n_c_from_b1, n_c_from_b2);
725+ return static_cast <int >(EM_HFeeType::kBCe_BCe ); // default to b->c->e and b->c->e, decay type = 1
726+ }
665727 }
666728
667729 if ((is_direct_from_b1 && is_c_from_b2) || (is_direct_from_b2 && is_c_from_b1)) {
0 commit comments