2020#define HomogeneousField // o2-linter: disable=name/macro (required by KFParticle)
2121#endif
2222
23- #include < memory>
24- #include < string>
25- #include < vector>
26-
27- #include < KFParticleBase.h>
28- #include < KFParticle.h>
29- #include < KFPTrack.h>
30- #include < KFPVertex.h>
31- #include < KFVertex.h>
23+ #include " PWGHF/Core/CentralityEstimation.h"
24+ #include " PWGHF/Core/DecayChannels.h"
25+ #include " PWGHF/Core/SelectorCuts.h"
26+ #include " PWGHF/DataModel/CandidateReconstructionTables.h"
27+ #include " PWGHF/Utils/utilsBfieldCCDB.h"
28+ #include " PWGHF/Utils/utilsEvSelHf.h"
29+ #include " PWGHF/Utils/utilsMcGen.h"
30+ #include " PWGHF/Utils/utilsMcMatching.h"
31+ #include " PWGHF/Utils/utilsPid.h"
32+ #include " PWGHF/Utils/utilsTrkCandHf.h"
33+ #include " PWGLF/DataModel/mcCentrality.h"
3234
33- #include < TPDGCode.h>
35+ #include " Common/Core/trackUtilities.h"
36+ #include " Tools/KFparticle/KFUtilities.h"
3437
3538#include " CommonConstants/PhysicsConstants.h"
3639#include " DCAFitter/DCAFitterN.h"
3740#include " Framework/AnalysisTask.h"
3841#include " Framework/HistogramRegistry.h"
39- #include " Framework/runDataProcessing.h"
4042#include " Framework/RunningWorkflowInfo.h"
43+ #include " Framework/runDataProcessing.h"
4144#include " ReconstructionDataFormats/DCA.h"
4245
43- #include " Common/Core/trackUtilities.h"
44- #include " Tools/KFparticle/KFUtilities.h"
46+ #include < TPDGCode.h>
4547
46- #include " PWGLF/DataModel/mcCentrality.h"
48+ #include < KFPTrack.h>
49+ #include < KFPVertex.h>
50+ #include < KFParticle.h>
51+ #include < KFParticleBase.h>
52+ #include < KFVertex.h>
4753
48- #include " PWGHF/Core/CentralityEstimation.h"
49- #include " PWGHF/Core/SelectorCuts.h"
50- #include " PWGHF/DataModel/CandidateReconstructionTables.h"
51- #include " PWGHF/Utils/utilsBfieldCCDB.h"
52- #include " PWGHF/Utils/utilsEvSelHf.h"
53- #include " PWGHF/Utils/utilsMcGen.h"
54- #include " PWGHF/Utils/utilsPid.h"
55- #include " PWGHF/Utils/utilsTrkCandHf.h"
54+ #include < memory>
55+ #include < string>
56+ #include < vector>
5657
5758using namespace o2 ;
5859using namespace o2 ::analysis;
5960using namespace o2 ::hf_evsel;
6061using namespace o2 ::hf_trkcandsel;
6162using namespace o2 ::aod::hf_cand_2prong;
63+ using namespace o2 ::hf_decay;
64+ using namespace o2 ::hf_decay::hf_cand_2prong;
6265using namespace o2 ::hf_centrality;
6366using namespace o2 ::hf_occupancy;
6467using namespace o2 ::constants::physics;
@@ -691,6 +694,7 @@ struct HfCandidateCreator2ProngExpressions {
691694 Configurable<bool > rejectBackground{" rejectBackground" , true , " Reject particles from background events" };
692695 Configurable<bool > matchKinkedDecayTopology{" matchKinkedDecayTopology" , false , " Match also candidates with tracks that decay with kinked topology" };
693696 Configurable<bool > matchInteractionsWithMaterial{" matchInteractionsWithMaterial" , false , " Match also candidates with tracks that interact with material" };
697+ Configurable<bool > matchCorrelatedBackgrounds{" matchCorrelatedBackgrounds" , false , " Match correlated background candidates" };
694698
695699 HfEventSelectionMc hfEvSelMc; // mc event selection and monitoring
696700
@@ -738,15 +742,18 @@ struct HfCandidateCreator2ProngExpressions {
738742 int indexRec = -1 ;
739743 int8_t sign = 0 ;
740744 int8_t flag = 0 ;
745+ int8_t channel = 0 ;
741746 int8_t origin = 0 ;
742747 int8_t nKinkedTracks = 0 ;
743748 int8_t nInteractionsWithMaterial = 0 ;
749+ constexpr std::size_t NDaughtersResonant{2u };
744750
745751 // Match reconstructed candidates.
746752 // Spawned table can be used directly
747753 for (const auto & candidate : *rowCandidateProng2) {
748754 flag = 0 ;
749755 origin = 0 ;
756+ channel = 0 ;
750757 auto arrayDaughters = std::array{candidate.prong0_as <aod::TracksWMc>(), candidate.prong1_as <aod::TracksWMc>()};
751758
752759 // Check whether the particle is from background events. If so, reject it.
@@ -762,47 +769,107 @@ struct HfCandidateCreator2ProngExpressions {
762769 }
763770 }
764771 if (fromBkg) {
765- rowMcMatchRec (flag, origin, -1 .f , 0 , 0 , 0 );
772+ rowMcMatchRec (flag, origin, channel, -1 .f , 0 , 0 , 0 );
766773 continue ;
767774 }
768775 }
769776 std::vector<int > idxBhadMothers{};
770777
771- // D0(bar) → π± K∓
772- if (matchKinkedDecayTopology && matchInteractionsWithMaterial) {
773- indexRec = RecoDecay::getMatchedMCRec<false , false , false , true , true >(mcParticles, arrayDaughters, Pdg::kD0 , std::array{+kPiPlus , -kKPlus }, true , &sign, 1 , &nKinkedTracks, &nInteractionsWithMaterial);
774- } else if (matchKinkedDecayTopology && !matchInteractionsWithMaterial) {
775- indexRec = RecoDecay::getMatchedMCRec<false , false , false , true , false >(mcParticles, arrayDaughters, Pdg::kD0 , std::array{+kPiPlus , -kKPlus }, true , &sign, 1 , &nKinkedTracks);
776- } else if (!matchKinkedDecayTopology && matchInteractionsWithMaterial) {
777- indexRec = RecoDecay::getMatchedMCRec<false , false , false , false , true >(mcParticles, arrayDaughters, Pdg::kD0 , std::array{+kPiPlus , -kKPlus }, true , &sign, 1 , nullptr , &nInteractionsWithMaterial);
778- } else {
779- indexRec = RecoDecay::getMatchedMCRec (mcParticles, arrayDaughters, Pdg::kD0 , std::array{+kPiPlus , -kKPlus }, true , &sign);
780- }
781- if (indexRec > -1 ) {
782- flag = sign * (1 << DecayType::D0ToPiK);
783- }
778+ if (matchCorrelatedBackgrounds) {
779+ indexRec = -1 ; // Index of the matched reconstructed candidate
780+ constexpr int FinalStateDepth = 2 ;
781+ constexpr int ResoDepth = 1 ;
782+
783+ // D0(bar) → π+ K−, π+ K− π0, π+ π−, π+ π− π0, K+ K−
784+ for (const auto & [chn, finalState] : hf_cand_2prong::daughtersD0Main) {
785+ std::array<int , 2 > finalStateParts2Prong = std::array{finalState[0 ], finalState[1 ]};
786+ if (finalState.size () == 3 ) { // o2-linter: disable=magic-number (Partly Reco 3-prong decays)
787+ if (matchKinkedDecayTopology && matchInteractionsWithMaterial) {
788+ indexRec = RecoDecay::getMatchedMCRec<false , false , true , true , true >(mcParticles, arrayDaughters, Pdg::kD0 , finalStateParts2Prong, true , &sign, FinalStateDepth, &nKinkedTracks, &nInteractionsWithMaterial);
789+ } else if (matchKinkedDecayTopology && !matchInteractionsWithMaterial) {
790+ indexRec = RecoDecay::getMatchedMCRec<false , false , true , true , false >(mcParticles, arrayDaughters, Pdg::kD0 , finalStateParts2Prong, true , &sign, FinalStateDepth, &nKinkedTracks);
791+ } else if (!matchKinkedDecayTopology && matchInteractionsWithMaterial) {
792+ indexRec = RecoDecay::getMatchedMCRec<false , false , true , false , true >(mcParticles, arrayDaughters, Pdg::kD0 , finalStateParts2Prong, true , &sign, FinalStateDepth, nullptr , &nInteractionsWithMaterial);
793+ } else {
794+ indexRec = RecoDecay::getMatchedMCRec<false , false , true , false , false >(mcParticles, arrayDaughters, Pdg::kD0 , finalStateParts2Prong, true , &sign, FinalStateDepth);
795+ }
784796
785- // J/ψ → e+ e−
786- if (flag == 0 ) {
787- if (matchInteractionsWithMaterial) {
788- indexRec = RecoDecay::getMatchedMCRec<false , false , false , false , true >(mcParticles, arrayDaughters, Pdg::kJPsi , std::array{+kElectron , -kElectron }, true , &sign, 1 , nullptr , &nInteractionsWithMaterial);
797+ if (indexRec > -1 ) {
798+ auto motherParticle = mcParticles.rawIteratorAt (indexRec);
799+ std::array<int , 3 > finalStateParts2ProngAll = std::array{finalState[0 ], finalState[1 ], finalState[2 ]};
800+ changeFinalStatePdgSign (motherParticle.pdgCode (), +kPi0 , finalStateParts2ProngAll);
801+ if (!RecoDecay::isMatchedMCGen (mcParticles, motherParticle, Pdg::kD0 , finalStateParts2ProngAll, true , &sign, FinalStateDepth)) {
802+ indexRec = -1 ; // Reset indexRec if the generated decay does not match the reconstructed one does not match the reconstructed one
803+ }
804+ }
805+ } else if (finalState.size () == 2 ) { // o2-linter: disable=magic-number (Fully Reco 2-prong decays)
806+ if (matchKinkedDecayTopology && matchInteractionsWithMaterial) {
807+ indexRec = RecoDecay::getMatchedMCRec<false , false , false , true , true >(mcParticles, arrayDaughters, Pdg::kD0 , finalStateParts2Prong, true , &sign, FinalStateDepth, &nKinkedTracks, &nInteractionsWithMaterial);
808+ } else if (matchKinkedDecayTopology && !matchInteractionsWithMaterial) {
809+ indexRec = RecoDecay::getMatchedMCRec<false , false , false , true , false >(mcParticles, arrayDaughters, Pdg::kD0 , finalStateParts2Prong, true , &sign, FinalStateDepth, &nKinkedTracks);
810+ } else if (!matchKinkedDecayTopology && matchInteractionsWithMaterial) {
811+ indexRec = RecoDecay::getMatchedMCRec<false , false , false , false , true >(mcParticles, arrayDaughters, Pdg::kD0 , finalStateParts2Prong, true , &sign, FinalStateDepth, nullptr , &nInteractionsWithMaterial);
812+ } else {
813+ indexRec = RecoDecay::getMatchedMCRec<false , false , false , false , false >(mcParticles, arrayDaughters, Pdg::kD0 , finalStateParts2Prong, true , &sign, FinalStateDepth);
814+ }
815+ } else {
816+ LOG (fatal) << " Final state size not supported: " << finalState.size ();
817+ continue ;
818+ }
819+ if (indexRec > -1 ) {
820+ flag = sign * (1 << chn);
821+
822+ // Flag the resonant decay channel
823+ std::vector<int > arrResoDaughIndex = {};
824+ RecoDecay::getDaughters (mcParticles.rawIteratorAt (indexRec), &arrResoDaughIndex, std::array{0 }, ResoDepth);
825+ std::array<int , NDaughtersResonant> arrPDGDaugh = {};
826+ if (arrResoDaughIndex.size () == NDaughtersResonant) {
827+ for (auto iProng = 0u ; iProng < arrResoDaughIndex.size (); ++iProng) {
828+ auto daughI = mcParticles.rawIteratorAt (arrResoDaughIndex[iProng]);
829+ arrPDGDaugh[iProng] = daughI.pdgCode ();
830+ }
831+ channel = flagResonantDecay (Pdg::kD0 , arrPDGDaugh);
832+ }
833+ break ;
834+ }
835+ }
836+ } else {
837+ // D0(bar) → π± K∓
838+ if (matchKinkedDecayTopology && matchInteractionsWithMaterial) {
839+ indexRec = RecoDecay::getMatchedMCRec<false , false , false , true , true >(mcParticles, arrayDaughters, Pdg::kD0 , std::array{+kPiPlus , -kKPlus }, true , &sign, 1 , &nKinkedTracks, &nInteractionsWithMaterial);
840+ } else if (matchKinkedDecayTopology && !matchInteractionsWithMaterial) {
841+ indexRec = RecoDecay::getMatchedMCRec<false , false , false , true , false >(mcParticles, arrayDaughters, Pdg::kD0 , std::array{+kPiPlus , -kKPlus }, true , &sign, 1 , &nKinkedTracks);
842+ } else if (!matchKinkedDecayTopology && matchInteractionsWithMaterial) {
843+ indexRec = RecoDecay::getMatchedMCRec<false , false , false , false , true >(mcParticles, arrayDaughters, Pdg::kD0 , std::array{+kPiPlus , -kKPlus }, true , &sign, 1 , nullptr , &nInteractionsWithMaterial);
789844 } else {
790- indexRec = RecoDecay::getMatchedMCRec (mcParticles, arrayDaughters, Pdg::kJPsi , std::array{+kElectron , -kElectron }, true );
845+ indexRec = RecoDecay::getMatchedMCRec (mcParticles, arrayDaughters, Pdg::kD0 , std::array{+kPiPlus , -kKPlus }, true , &sign );
791846 }
792847 if (indexRec > -1 ) {
793- flag = 1 << DecayType::JpsiToEE ;
848+ flag = sign * ( 1 << DecayType::D0ToPiK) ;
794849 }
795- }
796850
797- // J/ψ → μ+ μ−
798- if (flag == 0 ) {
799- if (matchInteractionsWithMaterial) {
800- indexRec = RecoDecay::getMatchedMCRec<false , false , false , false , true >(mcParticles, arrayDaughters, Pdg::kJPsi , std::array{+kMuonPlus , -kMuonPlus }, true , &sign, 1 , nullptr , &nInteractionsWithMaterial);
801- } else {
802- indexRec = RecoDecay::getMatchedMCRec (mcParticles, arrayDaughters, Pdg::kJPsi , std::array{+kMuonPlus , -kMuonPlus }, true );
851+ // J/ψ → e+ e−
852+ if (flag == 0 ) {
853+ if (matchInteractionsWithMaterial) {
854+ indexRec = RecoDecay::getMatchedMCRec<false , false , false , false , true >(mcParticles, arrayDaughters, Pdg::kJPsi , std::array{+kElectron , -kElectron }, true , &sign, 1 , nullptr , &nInteractionsWithMaterial);
855+ } else {
856+ indexRec = RecoDecay::getMatchedMCRec (mcParticles, arrayDaughters, Pdg::kJPsi , std::array{+kElectron , -kElectron }, true );
857+ }
858+ if (indexRec > -1 ) {
859+ flag = 1 << DecayType::JpsiToEE;
860+ }
803861 }
804- if (indexRec > -1 ) {
805- flag = 1 << DecayType::JpsiToMuMu;
862+
863+ // J/ψ → μ+ μ−
864+ if (flag == 0 ) {
865+ if (matchInteractionsWithMaterial) {
866+ indexRec = RecoDecay::getMatchedMCRec<false , false , false , false , true >(mcParticles, arrayDaughters, Pdg::kJPsi , std::array{+kMuonPlus , -kMuonPlus }, true , &sign, 1 , nullptr , &nInteractionsWithMaterial);
867+ } else {
868+ indexRec = RecoDecay::getMatchedMCRec (mcParticles, arrayDaughters, Pdg::kJPsi , std::array{+kMuonPlus , -kMuonPlus }, true );
869+ }
870+ if (indexRec > -1 ) {
871+ flag = 1 << DecayType::JpsiToMuMu;
872+ }
806873 }
807874 }
808875
@@ -813,9 +880,9 @@ struct HfCandidateCreator2ProngExpressions {
813880 }
814881 if (origin == RecoDecay::OriginType::NonPrompt) {
815882 auto bHadMother = mcParticles.rawIteratorAt (idxBhadMothers[0 ]);
816- rowMcMatchRec (flag, origin, bHadMother.pt (), bHadMother.pdgCode (), nKinkedTracks, nInteractionsWithMaterial);
883+ rowMcMatchRec (flag, origin, channel, bHadMother.pt (), bHadMother.pdgCode (), nKinkedTracks, nInteractionsWithMaterial);
817884 } else {
818- rowMcMatchRec (flag, origin, -1 .f , 0 , nKinkedTracks, nInteractionsWithMaterial);
885+ rowMcMatchRec (flag, origin, channel, -1 .f , 0 , nKinkedTracks, nInteractionsWithMaterial);
819886 }
820887 }
821888
@@ -842,11 +909,11 @@ struct HfCandidateCreator2ProngExpressions {
842909 if (rejectionMask != 0 ) {
843910 // at least one event selection not satisfied --> reject all particles from this collision
844911 for (unsigned int i = 0 ; i < mcParticlesPerMcColl.size (); ++i) {
845- rowMcMatchGen (0 , 0 , -1 );
912+ rowMcMatchGen (0 , 0 , 0 , -1 );
846913 }
847914 continue ;
848915 }
849- hf_mc_gen::fillMcMatchGen2Prong (mcParticles, mcParticlesPerMcColl, rowMcMatchGen, rejectBackground);
916+ hf_mc_gen::fillMcMatchGen2Prong (mcParticles, mcParticlesPerMcColl, rowMcMatchGen, rejectBackground, matchCorrelatedBackgrounds );
850917 }
851918 }
852919
0 commit comments