@@ -114,14 +114,92 @@ constexpr std::array<int, NChannels> PDGArrayParticle = {o2::constants::physics:
114114 o2::constants::physics::Pdg::kLambdaCPlus , o2::constants::physics::Pdg::kLambdaCPlus ,
115115 o2::constants::physics::Pdg::kXiCPlus , o2::constants::physics::Pdg::kXiCPlus , o2::constants::physics::Pdg::kXiC0 ,
116116 o2::constants::physics::Pdg::kOmegaC0 , o2::constants::physics::Pdg::kOmegaC0 };
117- constexpr std::array<unsigned int , NChannels> NDaughters = {2 , 3 , 3 , 3 , 3 , 3 , 5 , 5 , 4 , 4 , 4 , 3 , 4 , 3 , 3 , 3 , 5 , 4 , 4 , 4 };
118- constexpr std::array<int , NChannels> MaxDepthForSearch = {1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 2 , 3 , 2 , 3 , 2 , 4 , 3 , 3 , 3 };
117+ constexpr std::array<unsigned int , NChannels> NDaughters = {
118+ 2 , // DzeroToKPi
119+ 3 , // DstarToDzeroPi
120+ 3 , // DplusToPiKPi
121+ 3 , // DplusToPhiPiToKKPi
122+ 3 , // DsToPhiPiToKKPi
123+ 3 , // DsToK0starKToKKPi
124+ 5 , // Ds1ToDStarK0s
125+ 5 , // Ds2StarToDPlusK0s
126+ 4 , // D10ToDStarPi
127+ 4 , // D2Star0ToDPlusPi
128+ 4 , // B0ToDminusPi
129+ 3 , // BplusToD0Pi
130+ 4 , // BsToDsPi
131+ 3 , // LcToPKPi
132+ 3 , // LcToPiK0s
133+ 3 , // XiCplusToPKPi
134+ 5 , // XiCplusToXiPiPi
135+ 4 , // XiCzeroToXiPi
136+ 4 , // OmegaCToOmegaPi
137+ 4 // OmegaCToXiPi
138+ };
139+ constexpr std::array<int , NChannels> MaxDepthForSearch = {
140+ 1 , // DzeroToKPi
141+ 2 , // DstarToDzeroPi
142+ 2 , // DplusToPiKPi
143+ 2 , // DplusToPhiPiToKKPi
144+ 2 , // DsToPhiPiToKKPi
145+ 2 , // DsToK0starKToKKPi
146+ 3 , // Ds1ToDStarK0s
147+ 3 , // Ds2StarToDPlusK0s
148+ 3 , // D10ToDStarPi
149+ 3 , // D2Star0ToDPlusPi
150+ 3 , // B0ToDminusPi
151+ 2 , // BplusToD0Pi
152+ 3 , // BsToDsPi
153+ 2 , // LcToPKPi
154+ 3 , // LcToPiK0s
155+ 2 , // XiCplusToPKPi
156+ 4 , // XiCplusToXiPiPi
157+ 3 , // XiCzeroToXiPi
158+ 3 , // OmegaCToOmegaPi
159+ 3 // OmegaCToXiPi
160+ };
119161// keep coherent indexing with PDGArrayParticle
120162// FIXME: look for a better solution
121- constexpr std::array<std::array<int , 2 >, NChannels> ArrPdgFinal2Prong = {{{+kPiPlus , -kKPlus }, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}}};
122- constexpr std::array<std::array<int , 3 >, NChannels> ArrPdgFinal3Prong = {{{}, {+kPiPlus , -kKPlus , +kPiPlus }, {+kPiPlus , -kKPlus , +kPiPlus }, {+kKPlus , -kKPlus , +kPiPlus }, {+kKPlus , -kKPlus , +kPiPlus }, {+kKPlus , -kKPlus , +kPiPlus }, {}, {}, {}, {}, {}, {-kPiPlus , +kKPlus , +kPiPlus }, {}, {+kProton , -kKPlus , +kPiPlus }, {+kProton , -kPiPlus , +kPiPlus }, {+kProton , -kKPlus , +kPiPlus }, {}, {}, {}, {}}};
123- constexpr std::array<std::array<int , 4 >, NChannels> ArrPdgFinal4Prong = {{{}, {}, {}, {}, {}, {}, {}, {}, {+kPiPlus , -kKPlus , +kPiPlus , -kPiPlus }, {+kPiPlus , -kKPlus , +kPiPlus , -kPiPlus }, {-kPiPlus , +kKPlus , -kPiPlus , +kPiPlus }, {}, {-kKPlus , +kKPlus , -kPiPlus , +kPiPlus }, {}, {}, {}, {}, {+kPiPlus , -kPiPlus , -kPiPlus , +kProton }, {+kPiPlus , -kKPlus , -kPiPlus , +kProton }, {+kPiPlus , -kPiPlus , -kPiPlus , +kProton }}};
124- constexpr std::array<std::array<int , 5 >, NChannels> ArrPdgFinal5Prong = {{{}, {}, {}, {}, {}, {}, {+kPiPlus , -kKPlus , +kPiPlus , +kPiPlus , -kPiPlus }, {+kPiPlus , -kKPlus , +kPiPlus , +kPiPlus , -kPiPlus }, {}, {}, {}, {}, {}, {}, {}, {}, {+kPiPlus , +kPiPlus , -kPiPlus , -kPiPlus , +kProton }, {}, {}, {}}};
163+ constexpr auto ArrPdgFinal2Prong = []() {
164+ std::array<std::array<int , 2 >, NChannels> arr{};
165+ arr[DzeroToKPi] = {+kPiPlus , -kKPlus };
166+ return arr;
167+ }();
168+
169+ constexpr auto ArrPdgFinal3Prong = []() {
170+ std::array<std::array<int , 3 >, NChannels> arr{};
171+ arr[DstarToDzeroPi] = {+kPiPlus , -kKPlus , +kPiPlus };
172+ arr[DplusToPiKPi] = {+kPiPlus , -kKPlus , +kPiPlus };
173+ arr[DplusToPhiPiToKKPi] = {+kKPlus , -kKPlus , +kPiPlus };
174+ arr[DsToPhiPiToKKPi] = {+kKPlus , -kKPlus , +kPiPlus };
175+ arr[DsToK0starKToKKPi] = {+kKPlus , -kKPlus , +kPiPlus };
176+ arr[BplusToD0Pi] = {-kPiPlus , +kKPlus , +kPiPlus };
177+ arr[LcToPKPi] = {+kProton , -kKPlus , +kPiPlus };
178+ arr[LcToPiK0s] = {+kProton , -kPiPlus , +kPiPlus };
179+ arr[XiCplusToPKPi] = {+kProton , -kKPlus , +kPiPlus };
180+ return arr;
181+ }();
182+
183+ constexpr auto ArrPdgFinal4Prong = []() {
184+ std::array<std::array<int , 4 >, NChannels> arr{};
185+ arr[D10ToDStarPi] = {+kPiPlus , -kKPlus , +kPiPlus , -kPiPlus };
186+ arr[D2Star0ToDPlusPi] = {+kPiPlus , -kKPlus , +kPiPlus , -kPiPlus };
187+ arr[B0ToDminusPi] = {-kPiPlus , +kKPlus , -kPiPlus , +kPiPlus };
188+ arr[BsToDsPi] = {-kKPlus , +kKPlus , -kPiPlus , +kPiPlus };
189+ arr[XiCzeroToXiPi] = {+kPiPlus , -kPiPlus , -kPiPlus , +kProton };
190+ arr[OmegaCToOmegaPi] = {+kPiPlus , -kKPlus , -kPiPlus , +kProton };
191+ arr[OmegaCToXiPi] = {+kPiPlus , -kPiPlus , -kPiPlus , +kProton };
192+ return arr;
193+ }();
194+
195+ constexpr auto ArrPdgFinal5Prong = []() {
196+ std::array<std::array<int , 5 >, NChannels> arr{};
197+ arr[Ds1ToDStarK0s] = {+kPiPlus , -kKPlus , +kPiPlus , +kPiPlus , -kPiPlus };
198+ arr[Ds2StarToDPlusK0s] = {+kPiPlus , -kKPlus , +kPiPlus , +kPiPlus , -kPiPlus };
199+ arr[XiCplusToXiPiPi] = {+kPiPlus , +kPiPlus , -kPiPlus , -kPiPlus , +kProton };
200+ return arr;
201+ }();
202+
125203constexpr std::string_view Labels[NChannels] = {" D^{0} #rightarrow K#pi" , " D*^{+} #rightarrow D^{0}#pi" , " D^{+} #rightarrow K#pi#pi" , " D^{+} #rightarrow KK#pi" , " D_{s}^{+} #rightarrow #Phi#pi #rightarrow KK#pi" ,
126204 " D_{s}^{+} #rightarrow #bar{K}^{*0}K #rightarrow KK#pi" , " D_{s}1 #rightarrow D*^{+}K^{0}_{s}" , " D_{s}2* #rightarrow D^{+}K^{0}_{s}" , " D1^{0} #rightarrow D*^{+}#pi" ,
127205 " D2^{*} #rightarrow D^{+}#pi" ,
@@ -279,7 +357,9 @@ struct HfTaskMcValidationGen {
279357 }
280358
281359 template <o2::hf_centrality::CentralityEstimator CentEstimator, typename GenColl, typename Particles, typename RecoColls>
282- void runCheckGenParticles (GenColl const & mcCollision, Particles const & mcParticles, RecoColls const & recoCollisions, BCsInfo const &, std::array<int , NChannels>& counterPrompt, std::array<int , NChannels>& counterNonPrompt)
360+ void runCheckGenParticles (
361+ GenColl const & mcCollision, Particles const & mcParticles, RecoColls const & recoCollisions,
362+ BCsInfo const &, std::array<int , NChannels>& counterPrompt, std::array<int , NChannels>& counterNonPrompt, std::array<int , NChannels>& counterBeauty)
283363 {
284364 if (eventGeneratorType >= 0 && mcCollision.getSubGeneratorId () != eventGeneratorType) {
285365 return ;
@@ -478,6 +558,8 @@ struct HfTaskMcValidationGen {
478558 } else if (origin == RecoDecay::OriginType::NonPrompt) {
479559 counterNonPrompt[iD]++;
480560 }
561+ } else { // Beauty hadrons
562+ counterBeauty[iD]++; // Matched already, no need to check origin for beauty hadrons
481563 }
482564
483565 auto daughter0 = particle.template daughters_as <Particles>().begin ();
@@ -553,16 +635,16 @@ struct HfTaskMcValidationGen {
553635 for (const auto & mcCollision : mcCollisions) {
554636 const auto recoCollsPerMcColl = recoCollisions.sliceBy (colPerMcCollision, mcCollision.globalIndex ());
555637 const auto mcParticlesPerMcColl = mcParticles.sliceBy (mcParticlesPerMcCollision, mcCollision.globalIndex ());
556- std::array<int , NChannels> counterPrompt{0 }, counterNonPrompt{0 };
557- runCheckGenParticles<o2::hf_centrality::CentralityEstimator::None>(mcCollision, mcParticlesPerMcColl, recoCollsPerMcColl, bcInfo, counterPrompt, counterNonPrompt);
638+ std::array<int , NChannels> counterPrompt{0 }, counterNonPrompt{0 }, counterBeauty{ 0 } ;
639+ runCheckGenParticles<o2::hf_centrality::CentralityEstimator::None>(mcCollision, mcParticlesPerMcColl, recoCollsPerMcColl, bcInfo, counterPrompt, counterNonPrompt, counterBeauty );
558640 static_for<0 , NCharmMesonChannels - 1 >([&](auto i) { // Charm mesons
559641 constexpr int Index = i.value ;
560642 registry.fill (HIST (" PromptCharmMesons/hCountPrompt" ) + HIST (ParticleNames[Index]), counterPrompt[Index]);
561643 registry.fill (HIST (" NonPromptCharmMesons/hCountNonPrompt" ) + HIST (ParticleNames[Index]), counterNonPrompt[Index]);
562644 });
563645 static_for<NCharmMesonChannels, NCharmMesonChannels + NBeautyChannels - 1 >([&](auto i) { // Beauty hadrons
564646 constexpr int Index = i.value ;
565- registry.fill (HIST (" Beauty/hCount" ) + HIST (ParticleNames[Index]), counterPrompt [Index]);
647+ registry.fill (HIST (" Beauty/hCount" ) + HIST (ParticleNames[Index]), counterBeauty [Index]);
566648 });
567649 static_for<NCharmMesonChannels + NBeautyChannels, NChannels - 1 >([&](auto i) { // Charm baryons
568650 constexpr int Index = i.value ;
@@ -581,16 +663,16 @@ struct HfTaskMcValidationGen {
581663 for (const auto & mcCollision : mcCollisions) {
582664 const auto recoCollsPerMcColl = recoCollisions.sliceBy (colPerMcCollisionFT0C, mcCollision.globalIndex ());
583665 const auto mcParticlesPerMcColl = mcParticles.sliceBy (mcParticlesPerMcCollision, mcCollision.globalIndex ());
584- std::array<int , NChannels> counterPrompt{0 }, counterNonPrompt{0 };
585- runCheckGenParticles<o2::hf_centrality::CentralityEstimator::FT0C >(mcCollision, mcParticlesPerMcColl, recoCollsPerMcColl, bcInfo, counterPrompt, counterNonPrompt);
666+ std::array<int , NChannels> counterPrompt{0 }, counterNonPrompt{0 }, counterBeauty{ 0 } ;
667+ runCheckGenParticles<o2::hf_centrality::CentralityEstimator::FT0C >(mcCollision, mcParticlesPerMcColl, recoCollsPerMcColl, bcInfo, counterPrompt, counterNonPrompt, counterBeauty );
586668 static_for<0 , NCharmMesonChannels - 1 >([&](auto i) { // Charm mesons
587669 constexpr int Index = i.value ;
588670 registry.fill (HIST (" PromptCharmMesons/hCountPrompt" ) + HIST (ParticleNames[Index]), counterPrompt[Index]);
589671 registry.fill (HIST (" NonPromptCharmMesons/hCountNonPrompt" ) + HIST (ParticleNames[Index]), counterNonPrompt[Index]);
590672 });
591673 static_for<NCharmMesonChannels, NCharmMesonChannels + NBeautyChannels - 1 >([&](auto i) { // Beauty
592674 constexpr int Index = i.value ;
593- registry.fill (HIST (" Beauty/hCount" ) + HIST (ParticleNames[Index]), counterPrompt [Index]);
675+ registry.fill (HIST (" Beauty/hCount" ) + HIST (ParticleNames[Index]), counterBeauty [Index]);
594676 });
595677 static_for<NCharmMesonChannels + NBeautyChannels, NChannels - 1 >([&](auto i) { // Charm baryons
596678 constexpr int Index = i.value ;
@@ -609,16 +691,16 @@ struct HfTaskMcValidationGen {
609691 for (const auto & mcCollision : mcCollisions) {
610692 const auto recoCollsPerMcColl = recoCollisions.sliceBy (colPerMcCollisionFT0M, mcCollision.globalIndex ());
611693 const auto mcParticlesPerMcColl = mcParticles.sliceBy (mcParticlesPerMcCollision, mcCollision.globalIndex ());
612- std::array<int , NChannels> counterPrompt{0 }, counterNonPrompt{0 };
613- runCheckGenParticles<o2::hf_centrality::CentralityEstimator::FT0M >(mcCollision, mcParticlesPerMcColl, recoCollsPerMcColl, bcInfo, counterPrompt, counterNonPrompt);
694+ std::array<int , NChannels> counterPrompt{0 }, counterNonPrompt{0 }, counterBeauty{ 0 } ;
695+ runCheckGenParticles<o2::hf_centrality::CentralityEstimator::FT0M >(mcCollision, mcParticlesPerMcColl, recoCollsPerMcColl, bcInfo, counterPrompt, counterNonPrompt, counterBeauty );
614696 static_for<0 , NCharmMesonChannels - 1 >([&](auto i) { // Charm mesons
615697 constexpr int Index = i.value ;
616698 registry.fill (HIST (" PromptCharmMesons/hCountPrompt" ) + HIST (ParticleNames[Index]), counterPrompt[Index]);
617699 registry.fill (HIST (" NonPromptCharmMesons/hCountNonPrompt" ) + HIST (ParticleNames[Index]), counterNonPrompt[Index]);
618700 });
619701 static_for<NCharmMesonChannels, NCharmMesonChannels + NBeautyChannels - 1 >([&](auto i) { // Beauty mesons
620702 constexpr int Index = i.value ;
621- registry.fill (HIST (" Beauty/hCount" ) + HIST (ParticleNames[Index]), counterPrompt [Index]);
703+ registry.fill (HIST (" Beauty/hCount" ) + HIST (ParticleNames[Index]), counterBeauty [Index]);
622704 });
623705 static_for<NCharmMesonChannels + NBeautyChannels, NChannels - 1 >([&](auto i) { // Charm baryons
624706 constexpr int Index = i.value ;
@@ -639,6 +721,7 @@ struct HfTaskMcValidationRec {
639721 Preslice<aod::Tracks> perCol = aod::track::collisionId;
640722
641723 Configurable<int > eventGeneratorType{" eventGeneratorType" , -1 , " If positive, enable event selection using subGeneratorId information. The value indicates which events to keep (0 = MB, 4 = charm triggered, 5 = beauty triggered)" };
724+ Configurable<bool > searchUpToQuark{" searchUpToQuark" , true , " Search up to quark level when determining the origin of a particle (prompt vs non-prompt)" };
642725 Configurable<bool > storeOccupancy{" storeOccupancy" , false , " Store collision occupancy for dedicated studies" };
643726
644727 std::array<std::shared_ptr<TH1 >, NChannels> histDeltaPt, histDeltaPx, histDeltaPy, histDeltaPz, histDeltaSecondaryVertexX, histDeltaSecondaryVertexY, histDeltaSecondaryVertexZ, histDeltaDecayLength;
@@ -921,7 +1004,7 @@ struct HfTaskMcValidationRec {
9211004 for (const auto & trackColl1 : tracksColl1) {
9221005 if (trackColl1.has_mcParticle () && trackColl1.isPVContributor ()) {
9231006 auto particleColl1 = trackColl1.mcParticle ();
924- auto origin = RecoDecay::getCharmHadronOrigin (mcParticles, particleColl1, true );
1007+ auto origin = RecoDecay::getParticleOrigin (mcParticles, particleColl1, searchUpToQuark );
9251008 if (origin == RecoDecay::NonPrompt) {
9261009 nFromBeautyColl1++;
9271010 }
@@ -931,7 +1014,7 @@ struct HfTaskMcValidationRec {
9311014 for (const auto & trackColl2 : tracksColl2) {
9321015 if (trackColl2.has_mcParticle () && trackColl2.isPVContributor ()) {
9331016 auto particleColl2 = trackColl2.mcParticle ();
934- auto origin = RecoDecay::getCharmHadronOrigin (mcParticles, particleColl2, true );
1017+ auto origin = RecoDecay::getParticleOrigin (mcParticles, particleColl2, searchUpToQuark );
9351018 if (origin == RecoDecay::NonPrompt) {
9361019 nFromBeautyColl2++;
9371020 }
@@ -960,7 +1043,7 @@ struct HfTaskMcValidationRec {
9601043 if (eventGeneratorType >= 0 && mcCollision.getSubGeneratorId () != eventGeneratorType) {
9611044 continue ;
9621045 }
963- auto origin = RecoDecay::getCharmHadronOrigin (mcParticles, particle, true );
1046+ auto origin = RecoDecay::getParticleOrigin (mcParticles, particle, searchUpToQuark );
9641047 histTracks->Fill (origin, track.pt ());
9651048 bool const isAmbiguous = (track.compatibleCollIds ().size () != 1 );
9661049 if (isAmbiguous) {
0 commit comments