88// In applying this license CERN does not waive the privileges and immunities
99// granted to it by virtue of its status as an Intergovernmental Organization
1010// or submit itself to any jurisdiction.
11-
1211// ========================
1312// / \file decay3bodybuilder.cxx
1413// / \brief Builder task for 3-body hypertriton decay reconstruction (proton + pion + deuteron)
1514// / \author Yuanzhe Wang <yuanzhe.wang@cern.ch>
1615// / \author Carolina Reetz <c.reetz@cern.ch>
1716// ========================
1817
19- #include < cmath>
20- #include < array>
21- #include < cstdlib>
22- #include < string>
23- #include < vector>
24- #include < unordered_map>
25- #include < algorithm>
26- #include < memory>
18+ #include " TableHelper.h"
2719
28- #include " Framework/runDataProcessing.h"
29- #include " Framework/AnalysisTask.h"
30- #include " Framework/AnalysisDataModel.h"
31- #include " Framework/ASoAHelpers.h"
32- #include " ReconstructionDataFormats/Track.h"
33- #include " Common/Core/RecoDecay.h"
34- #include " Common/Core/trackUtilities.h"
3520#include " PWGLF/DataModel/Reduced3BodyTables.h"
3621#include " PWGLF/DataModel/Vtx3BodyTables.h"
3722#include " PWGLF/DataModel/pidTOFGeneric.h"
3823#include " PWGLF/Utils/decay3bodyBuilderHelper.h"
24+
25+ #include " Common/Core/PID/PIDTOF.h"
26+ #include " Common/Core/RecoDecay.h"
27+ #include " Common/Core/trackUtilities.h"
3928#include " Common/DataModel/EventSelection.h"
4029#include " Common/DataModel/PIDResponse.h"
41- #include " Common/Core/PID/PIDTOF.h"
42- #include " TableHelper.h"
43- #include " Tools/KFparticle/KFUtilities.h"
44-
4530#include " EventFiltering/Zorro.h"
4631#include " EventFiltering/ZorroSummary.h"
32+ #include " Tools/KFparticle/KFUtilities.h"
4733
48- #include " DetectorsBase/Propagator.h"
49- #include " DetectorsBase/GeometryManager.h"
50- #include " DataFormatsParameters/GRPObject.h"
51- #include " DataFormatsParameters/GRPMagField.h"
5234#include " CCDB/BasicCCDBManager.h"
35+ #include " DataFormatsParameters/GRPMagField.h"
36+ #include " DataFormatsParameters/GRPObject.h"
37+ #include " DetectorsBase/GeometryManager.h"
38+ #include " DetectorsBase/Propagator.h"
39+ #include " Framework/ASoAHelpers.h"
40+ #include " Framework/AnalysisDataModel.h"
41+ #include " Framework/AnalysisTask.h"
42+ #include " Framework/runDataProcessing.h"
43+ #include " ReconstructionDataFormats/Track.h"
44+
45+ #include < algorithm>
46+ #include < array>
47+ #include < cmath>
48+ #include < cstdlib>
49+ #include < memory>
50+ #include < string>
51+ #include < unordered_map>
52+ #include < vector>
5353
5454#ifndef HomogeneousField
5555#define HomogeneousField
5656#endif
5757
5858// includes KFParticle
59- #include " KFParticle.h"
6059#include " KFPTrack.h"
6160#include " KFPVertex.h"
61+ #include " KFParticle.h"
6262#include " KFParticleBase.h"
6363#include " KFVertex.h"
6464
@@ -125,6 +125,7 @@ struct decay3bodyBuilder {
125125 Configurable<bool > doSkimmedProcessing{" doSkimmedProcessing" , false , " Apply Zoroo counting in case of skimmed data input" };
126126 Configurable<std::string> triggerList{"triggerList", "fTriggerEventF1Proton, fTrackedOmega, fTrackedXi, fOmegaLargeRadius, fDoubleOmega, fOmegaHighMult, fSingleXiYN, fQuadrupleXi, fDoubleXi, fhadronOmega, fOmegaXi, fTripleXi, fOmega, fGammaVeryLowPtEMCAL, fGammaVeryLowPtDCAL, fGammaHighPtEMCAL, fGammaLowPtEMCAL, fGammaVeryHighPtDCAL, fGammaVeryHighPtEMCAL, fGammaLowPtDCAL, fJetNeutralLowPt, fJetNeutralHighPt, fGammaHighPtDCAL, fJetFullLowPt, fJetFullHighPt, fEMCALReadout, fPCMandEE, fPHOSnbar, fPCMHighPtPhoton, fPHOSPhoton, fLD, fPPPHI, fPD, fLLL, fPLL, fPPL, fPPP, fLeadingPtTrack, fHighFt0cFv0Flat, fHighFt0cFv0Mult, fHighFt0Flat, fHighFt0Mult, fHighMultFv0, fHighTrackMult, fHfSingleNonPromptCharm3P, fHfSingleNonPromptCharm2P, fHfSingleCharm3P, fHfPhotonCharm3P, fHfHighPt2P, fHfSigmaC0K0, fHfDoubleCharm2P, fHfBeauty3P, fHfFemto3P, fHfFemto2P, fHfHighPt3P, fHfSigmaCPPK, fHfDoubleCharm3P, fHfDoubleCharmMix, fHfPhotonCharm2P, fHfV0Charm2P, fHfBeauty4P, fHfV0Charm3P, fHfSingleCharm2P, fHfCharmBarToXiBach, fSingleMuHigh, fSingleMuLow, fLMeeHMR, fDiMuon, fDiElectron, fLMeeIMR, fSingleE, fTrackHighPt, fTrackLowPt, fJetChHighPt, fJetChLowPt, fUDdiffLarge, fUDdiffSmall, fITSextremeIonisation, fITSmildIonisation, fH3L3Body, fHe, fH2", "List of triggers used to select events"};
127127 Configurable<bool > onlyKeepInterestedTrigger{" onlyKeepInterestedTrigger" , false , " Flag to keep only interested trigger" };
128+ Configurable<bool > doLikeSign{" doLikeSign" , false , " Flag to produce like-sign background. If true, require the sign of pion is as same as deuteron but not proton." };
128129
129130 // CCDB options
130131 struct : ConfigurableGroup {
@@ -145,6 +146,7 @@ struct decay3bodyBuilder {
145146 Configurable<bool > useSelections{" useSelections" , true , " Apply selections during decay3body building" };
146147 Configurable<bool > useTPCforPion{" useTPCforPion" , false , " Flag to ask for TPC info for pion track (PID, nClusters), false: pion track can be ITS only" };
147148 Configurable<bool > acceptTPCOnly{" acceptTPCOnly" , false , " Accept TPC only tracks as daughters" };
149+ Configurable<bool > askOnlyITSMatch{" askOnlyITSMatch" , true , " ask only ITS match to distinguish TPC only tracks" };
148150 Configurable<bool > calculateCovariance{" calculateCovariance" , true , " Calculate candidate and daughter covariance matrices" };
149151 // daughter track selections
150152 Configurable<float > maxEtaDaughters{" maxEtaDaughters" , 0.9 , " Max eta of daughters" };
@@ -182,7 +184,7 @@ struct decay3bodyBuilder {
182184 Configurable<int > n3bodyMixing{" n3bodyMixing" , 0 , " Number of decay3bodys to mix: 0 - value set to maximum bin entry in hDecay3BodyRadiusPhi, > 0 - manual setting" };
183185 Configurable<int > mixingType{" mixingType" , 0 , " 0: mix V0 from one event with bachelor from another, 1: mix pion and bachelor from one event with proton from another, 1: mix proton and bachelor from one event with pion from another " };
184186 ConfigurableAxis bins3BodyRadius{" mixingOpts.bins3BodyRadius" , {VARIABLE_WIDTH, 0 .0f , 2 .0f , 4 .0f , 7 .0f , 10 .0f , 14 .0f , 18 .0f , 22 .0f , 30 .0f , 40 .0f }, " Mixing bins - 3body radius" };
185- ConfigurableAxis bins3BodyPhi{" mixingOpts.bins3BodyPhi" , {VARIABLE_WIDTH, -180 * TMath::Pi () / 180 , -120 * TMath::Pi () / 180 , -60 * TMath::Pi () / 180 , 0 , 60 * TMath::Pi () / 180 , 120 * TMath::Pi () / 180 , 180 * TMath::Pi () / 180 }, " Mixing bins - 3body phi (rad)" };
187+ ConfigurableAxis bins3BodyPhi{" mixingOpts.bins3BodyPhi" , {VARIABLE_WIDTH, -180 * o2::constants::math::Deg2Rad , -120 * o2::constants::math::Deg2Rad , -60 * o2::constants::math::Deg2Rad , 0 , 60 * o2::constants::math::Deg2Rad , 120 * o2::constants::math::Deg2Rad , 180 * o2::constants::math::Deg2Rad }, " Mixing bins - 3body phi (rad)" };
186188 ConfigurableAxis bins3BodyPhiDegree{" mixingOpts.bins3BodyPhiDegree" , {VARIABLE_WIDTH, -180 , -120 , -60 , 0 , 60 , 120 , 180 }, " Mixing bins - 3body phi (degree)" };
187189 ConfigurableAxis bins3BodyPosZ{" mixingOpts.bins3BodyPosZ" , {VARIABLE_WIDTH, -500 .0f , -200 .0f , -100 .0f , -70 .0f , -60 .0f , -50 .0f , -40 .0f , -35 .0f , -30 .0f , -25 .0f , -20 .0f , -15 .0f , -13 .0f , -10 .0f , -8 .0f , -6 .0f , -4 .0f , -2 .0f , 0 .0f , 2 .0f , 4 .0f , 6 .0f , 8 .0f , 10 .0f , 13 .0f , 15 .0f , 20 .0f , 25 .0f , 30 .0f , 35 .0f , 40 .0f , 50 .0f , 60 .0f , 70 .0f , 100 .0f , 200 .0f , 500 .0f }, " 3body SV z position" };
188190 Configurable<bool > selectPVPosZ3bodyMixing{" selectPVPosZ3bodyMixing" , true , " Select same pvPosZ events in case of 3body mixing" };
@@ -264,6 +266,8 @@ struct decay3bodyBuilder {
264266 // tracked cluster size
265267 std::vector<int > fTrackedClSizeVector ;
266268
269+ // trigger info
270+ std::vector<bool > isTriggeredCollision;
267271 // MC info
268272 std::vector<bool > isGoodCollision;
269273
@@ -652,8 +656,14 @@ struct decay3bodyBuilder {
652656 // prepare MC container (not necessarily used)
653657 std::vector<bool > mcParticleIsReco;
654658
659+ if constexpr (soa::is_table<TBCs>) {
660+ isTriggeredCollision.clear ();
661+ isTriggeredCollision.resize (collisions.size (), false );
662+ }
655663 // clear and reserve size for MC info vectors
656664 if constexpr (soa::is_table<TMCParticles>) {
665+ isGoodCollision.clear ();
666+ mcParticleIsReco.clear ();
657667 isGoodCollision.resize (mcCollisions.size (), false );
658668 mcParticleIsReco.resize (mcParticles.size (), false );
659669 }
@@ -670,6 +680,7 @@ struct decay3bodyBuilder {
670680 }
671681 }
672682
683+ isTriggeredCollision[collision.globalIndex ()] = true ;
673684 // event counting
674685 registry.fill (HIST (" Counters/hEventCounter" ), 0.5 );
675686 if (doSel8selection && !collision.sel8 ()) {
@@ -711,7 +722,7 @@ struct decay3bodyBuilder {
711722 // skip decay3body without assigned collision
712723 // / TODO: do we want this??
713724 if (decay3body.collisionId () < 0 ) {
714- return ;
725+ continue ;
715726 }
716727
717728 // aquire collision
@@ -727,8 +738,11 @@ struct decay3bodyBuilder {
727738 }
728739
729740 // event selection
730- if constexpr (soa::is_table<TBCs>) {
731- if (doSel8selection && !collision.sel8 ()) { // only when NOT running over reduced data
741+ if constexpr (soa::is_table<TBCs>) { // only when NOT running over reduced data
742+ if (doSel8selection && !collision.sel8 ()) {
743+ continue ;
744+ }
745+ if (onlyKeepInterestedTrigger && !isTriggeredCollision[collision.globalIndex ()]) {
732746 continue ;
733747 }
734748 }
@@ -740,12 +754,12 @@ struct decay3bodyBuilder {
740754 auto trackPos = decay3body.template track0_as <TTracksTo>();
741755 auto trackNeg = decay3body.template track1_as <TTracksTo>();
742756 auto trackDeuteron = decay3body.template track2_as <TTracksTo>();
743- auto trackProton = trackPos;
744- auto trackPion = trackNeg;
745- if (trackDeuteron.sign () < 0 ) {
746- trackProton = trackNeg;
747- trackPion = trackPos;
757+ bool protonSign = trackDeuteron.sign () > 0 ;
758+ if (doLikeSign) {
759+ protonSign = -protonSign;
748760 }
761+ auto trackProton = protonSign ? trackPos : trackNeg;
762+ auto trackPion = protonSign ? trackNeg : trackPos;
749763
750764 // get deuteron TOF PID
751765 float tofNSigmaDeuteron;
@@ -772,6 +786,7 @@ struct decay3bodyBuilder {
772786 decay3bodyBuilderOpts.useSelections ,
773787 decay3bodyBuilderOpts.useTPCforPion ,
774788 decay3bodyBuilderOpts.acceptTPCOnly ,
789+ decay3bodyBuilderOpts.askOnlyITSMatch ,
775790 decay3bodyBuilderOpts.calculateCovariance ,
776791 false /* isEventMixing*/ )) {
777792 continue ;
@@ -863,7 +878,7 @@ struct decay3bodyBuilder {
863878 // MC handling part: generated information of non-reco candidates
864879 // ____________________________________________________________________
865880 if constexpr (soa::is_table<TMCParticles>) {
866- for (auto & mcparticle : mcParticles) {
881+ for (const auto & mcparticle : mcParticles) {
867882 // MC info
868883 resetMCInfo (this3BodyMCInfo);
869884 this3BodyMCInfo.isReco = false ;
@@ -877,14 +892,14 @@ struct decay3bodyBuilder {
877892 this3BodyMCInfo.survivedEventSel = isGoodCollision[mcparticle.mcCollisionId ()];
878893
879894 // check if MC particle is hypertriton
880- if (std::abs (mcparticle.pdgCode ()) != 1010010030 ) {
895+ if (std::abs (mcparticle.pdgCode ()) != o2::constants::physics::Pdg:: kHyperTriton ) {
881896 continue ;
882897 }
883898
884899 // check daughter identities
885900 bool haveProton = false , havePion = false , haveDeuteron = false ;
886901 bool haveAntiProton = false , haveAntiPion = false , haveAntiDeuteron = false ;
887- for (auto & mcparticleDaughter : mcparticle.template daughters_as <TMCParticles>()) {
902+ for (const auto & mcparticleDaughter : mcparticle.template daughters_as <TMCParticles>()) {
888903 if (mcparticleDaughter.pdgCode () == PDG_t::kProton )
889904 haveProton = true ;
890905 if (mcparticleDaughter.pdgCode () == PDG_t::kProtonBar )
@@ -893,9 +908,9 @@ struct decay3bodyBuilder {
893908 havePion = true ;
894909 if (mcparticleDaughter.pdgCode () == PDG_t::kPiMinus )
895910 haveAntiPion = true ;
896- if (mcparticleDaughter.pdgCode () == 1000010020 )
911+ if (mcparticleDaughter.pdgCode () == o2::constants::physics::Pdg:: kDeuteron )
897912 haveDeuteron = true ;
898- if (mcparticleDaughter.pdgCode () == -1000010020 )
913+ if (mcparticleDaughter.pdgCode () == -o2::constants::physics::Pdg:: kDeuteron )
899914 haveAntiDeuteron = true ;
900915 }
901916
@@ -907,7 +922,7 @@ struct decay3bodyBuilder {
907922 this3BodyMCInfo.isTrueAntiH3L = true ;
908923 }
909924 // get daughters
910- for (auto & mcparticleDaughter : mcparticle.template daughters_as <aod::McParticles>()) {
925+ for (const auto & mcparticleDaughter : mcparticle.template daughters_as <aod::McParticles>()) {
911926 if (std::abs (mcparticleDaughter.pdgCode ()) == PDG_t::kProton ) { // proton
912927 this3BodyMCInfo.genMomProton = mcparticleDaughter.p ();
913928 this3BodyMCInfo.genPtProton = mcparticleDaughter.pt ();
@@ -917,7 +932,7 @@ struct decay3bodyBuilder {
917932 this3BodyMCInfo.genMomPion = mcparticleDaughter.p ();
918933 this3BodyMCInfo.genPtPion = mcparticleDaughter.pt ();
919934 this3BodyMCInfo.daughterPiPdgCode = mcparticleDaughter.pdgCode ();
920- } else if (std::abs (mcparticleDaughter.pdgCode ()) == 1000010020 ) { // deuteron
935+ } else if (std::abs (mcparticleDaughter.pdgCode ()) == o2::constants::physics::Pdg:: kDeuteron ) { // deuteron
921936 this3BodyMCInfo.genMomDeuteron = mcparticleDaughter.p ();
922937 this3BodyMCInfo.genPtDeuteron = mcparticleDaughter.pt ();
923938 this3BodyMCInfo.daughterDePdgCode = mcparticleDaughter.pdgCode ();
@@ -1168,6 +1183,7 @@ struct decay3bodyBuilder {
11681183 decay3bodyBuilderOpts.useSelections ,
11691184 decay3bodyBuilderOpts.useTPCforPion ,
11701185 decay3bodyBuilderOpts.acceptTPCOnly ,
1186+ decay3bodyBuilderOpts.askOnlyITSMatch ,
11711187 decay3bodyBuilderOpts.calculateCovariance ,
11721188 true /* isEventMixing*/ )) {
11731189 // fill analysis tables with built candidate
@@ -1183,14 +1199,14 @@ struct decay3bodyBuilder {
11831199 template <typename MCTrack3B>
11841200 int checkH3LTruth (MCTrack3B const & mcParticlePr, MCTrack3B const & mcParticlePi, MCTrack3B const & mcParticleDe, bool & isMuonReco)
11851201 {
1186- if (std::abs (mcParticlePr.pdgCode ()) != 2212 || std::abs (mcParticleDe.pdgCode ()) != 1000010020 ) {
1202+ if (std::abs (mcParticlePr.pdgCode ()) != PDG_t:: kProton || std::abs (mcParticleDe.pdgCode ()) != o2::constants::physics::Pdg:: kDeuteron ) {
11871203 return -1 ;
11881204 }
11891205 // check proton and deuteron mother
11901206 int prDeMomID = -1 ;
11911207 for (const auto & motherPr : mcParticlePr.template mothers_as <aod::McParticles>()) {
11921208 for (const auto & motherDe : mcParticleDe.template mothers_as <aod::McParticles>()) {
1193- if (motherPr.globalIndex () == motherDe.globalIndex () && std::abs (motherPr.pdgCode ()) == 1010010030 ) {
1209+ if (motherPr.globalIndex () == motherDe.globalIndex () && std::abs (motherPr.pdgCode ()) == o2::constants::physics::Pdg:: kHyperTriton ) {
11941210 prDeMomID = motherPr.globalIndex ();
11951211 break ;
11961212 }
@@ -1199,14 +1215,14 @@ struct decay3bodyBuilder {
11991215 if (prDeMomID == -1 ) {
12001216 return -1 ;
12011217 }
1202- if (std::abs (mcParticlePi.pdgCode ()) != 211 && std::abs (mcParticlePi.pdgCode ()) != 13 ) {
1218+ if (std::abs (mcParticlePi.pdgCode ()) != PDG_t:: kPiPlus && std::abs (mcParticlePi.pdgCode ()) != PDG_t:: kMuonMinus ) {
12031219 return -1 ;
12041220 }
12051221 // check if the pion track is a muon coming from a pi -> mu + vu decay, if yes, take the mother pi
12061222 auto mcParticlePiTmp = mcParticlePi;
1207- if (std::abs (mcParticlePiTmp.pdgCode ()) == 13 ) {
1223+ if (std::abs (mcParticlePiTmp.pdgCode ()) == PDG_t:: kMuonMinus ) {
12081224 for (const auto & motherPi : mcParticlePiTmp.template mothers_as <aod::McParticles>()) {
1209- if (std::abs (motherPi.pdgCode ()) == 211 ) {
1225+ if (std::abs (motherPi.pdgCode ()) == PDG_t:: kPiPlus ) {
12101226 mcParticlePiTmp = motherPi;
12111227 isMuonReco = true ;
12121228 break ;
0 commit comments