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,9 @@ 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;
748- }
757+ int protonSign = doLikeSign ? -trackDeuteron.sign () : trackDeuteron.sign ();
758+ auto trackProton = protonSign > 0 ? trackPos : trackNeg;
759+ auto trackPion = protonSign > 0 ? trackNeg : trackPos;
749760
750761 // get deuteron TOF PID
751762 float tofNSigmaDeuteron;
@@ -772,6 +783,7 @@ struct decay3bodyBuilder {
772783 decay3bodyBuilderOpts.useSelections ,
773784 decay3bodyBuilderOpts.useTPCforPion ,
774785 decay3bodyBuilderOpts.acceptTPCOnly ,
786+ decay3bodyBuilderOpts.askOnlyITSMatch ,
775787 decay3bodyBuilderOpts.calculateCovariance ,
776788 false /* isEventMixing*/ )) {
777789 continue ;
@@ -863,7 +875,7 @@ struct decay3bodyBuilder {
863875 // MC handling part: generated information of non-reco candidates
864876 // ____________________________________________________________________
865877 if constexpr (soa::is_table<TMCParticles>) {
866- for (auto & mcparticle : mcParticles) {
878+ for (const auto & mcparticle : mcParticles) {
867879 // MC info
868880 resetMCInfo (this3BodyMCInfo);
869881 this3BodyMCInfo.isReco = false ;
@@ -877,14 +889,14 @@ struct decay3bodyBuilder {
877889 this3BodyMCInfo.survivedEventSel = isGoodCollision[mcparticle.mcCollisionId ()];
878890
879891 // check if MC particle is hypertriton
880- if (std::abs (mcparticle.pdgCode ()) != 1010010030 ) {
892+ if (std::abs (mcparticle.pdgCode ()) != o2::constants::physics::Pdg:: kHyperTriton ) {
881893 continue ;
882894 }
883895
884896 // check daughter identities
885897 bool haveProton = false , havePion = false , haveDeuteron = false ;
886898 bool haveAntiProton = false , haveAntiPion = false , haveAntiDeuteron = false ;
887- for (auto & mcparticleDaughter : mcparticle.template daughters_as <TMCParticles>()) {
899+ for (const auto & mcparticleDaughter : mcparticle.template daughters_as <TMCParticles>()) {
888900 if (mcparticleDaughter.pdgCode () == PDG_t::kProton )
889901 haveProton = true ;
890902 if (mcparticleDaughter.pdgCode () == PDG_t::kProtonBar )
@@ -893,9 +905,9 @@ struct decay3bodyBuilder {
893905 havePion = true ;
894906 if (mcparticleDaughter.pdgCode () == PDG_t::kPiMinus )
895907 haveAntiPion = true ;
896- if (mcparticleDaughter.pdgCode () == 1000010020 )
908+ if (mcparticleDaughter.pdgCode () == o2::constants::physics::Pdg:: kDeuteron )
897909 haveDeuteron = true ;
898- if (mcparticleDaughter.pdgCode () == -1000010020 )
910+ if (mcparticleDaughter.pdgCode () == -o2::constants::physics::Pdg:: kDeuteron )
899911 haveAntiDeuteron = true ;
900912 }
901913
@@ -907,7 +919,7 @@ struct decay3bodyBuilder {
907919 this3BodyMCInfo.isTrueAntiH3L = true ;
908920 }
909921 // get daughters
910- for (auto & mcparticleDaughter : mcparticle.template daughters_as <aod::McParticles>()) {
922+ for (const auto & mcparticleDaughter : mcparticle.template daughters_as <aod::McParticles>()) {
911923 if (std::abs (mcparticleDaughter.pdgCode ()) == PDG_t::kProton ) { // proton
912924 this3BodyMCInfo.genMomProton = mcparticleDaughter.p ();
913925 this3BodyMCInfo.genPtProton = mcparticleDaughter.pt ();
@@ -917,7 +929,7 @@ struct decay3bodyBuilder {
917929 this3BodyMCInfo.genMomPion = mcparticleDaughter.p ();
918930 this3BodyMCInfo.genPtPion = mcparticleDaughter.pt ();
919931 this3BodyMCInfo.daughterPiPdgCode = mcparticleDaughter.pdgCode ();
920- } else if (std::abs (mcparticleDaughter.pdgCode ()) == 1000010020 ) { // deuteron
932+ } else if (std::abs (mcparticleDaughter.pdgCode ()) == o2::constants::physics::Pdg:: kDeuteron ) { // deuteron
921933 this3BodyMCInfo.genMomDeuteron = mcparticleDaughter.p ();
922934 this3BodyMCInfo.genPtDeuteron = mcparticleDaughter.pt ();
923935 this3BodyMCInfo.daughterDePdgCode = mcparticleDaughter.pdgCode ();
@@ -1168,6 +1180,7 @@ struct decay3bodyBuilder {
11681180 decay3bodyBuilderOpts.useSelections ,
11691181 decay3bodyBuilderOpts.useTPCforPion ,
11701182 decay3bodyBuilderOpts.acceptTPCOnly ,
1183+ decay3bodyBuilderOpts.askOnlyITSMatch ,
11711184 decay3bodyBuilderOpts.calculateCovariance ,
11721185 true /* isEventMixing*/ )) {
11731186 // fill analysis tables with built candidate
@@ -1183,14 +1196,14 @@ struct decay3bodyBuilder {
11831196 template <typename MCTrack3B>
11841197 int checkH3LTruth (MCTrack3B const & mcParticlePr, MCTrack3B const & mcParticlePi, MCTrack3B const & mcParticleDe, bool & isMuonReco)
11851198 {
1186- if (std::abs (mcParticlePr.pdgCode ()) != 2212 || std::abs (mcParticleDe.pdgCode ()) != 1000010020 ) {
1199+ if (std::abs (mcParticlePr.pdgCode ()) != PDG_t:: kProton || std::abs (mcParticleDe.pdgCode ()) != o2::constants::physics::Pdg:: kDeuteron ) {
11871200 return -1 ;
11881201 }
11891202 // check proton and deuteron mother
11901203 int prDeMomID = -1 ;
11911204 for (const auto & motherPr : mcParticlePr.template mothers_as <aod::McParticles>()) {
11921205 for (const auto & motherDe : mcParticleDe.template mothers_as <aod::McParticles>()) {
1193- if (motherPr.globalIndex () == motherDe.globalIndex () && std::abs (motherPr.pdgCode ()) == 1010010030 ) {
1206+ if (motherPr.globalIndex () == motherDe.globalIndex () && std::abs (motherPr.pdgCode ()) == o2::constants::physics::Pdg:: kHyperTriton ) {
11941207 prDeMomID = motherPr.globalIndex ();
11951208 break ;
11961209 }
@@ -1199,14 +1212,14 @@ struct decay3bodyBuilder {
11991212 if (prDeMomID == -1 ) {
12001213 return -1 ;
12011214 }
1202- if (std::abs (mcParticlePi.pdgCode ()) != 211 && std::abs (mcParticlePi.pdgCode ()) != 13 ) {
1215+ if (std::abs (mcParticlePi.pdgCode ()) != PDG_t:: kPiPlus && std::abs (mcParticlePi.pdgCode ()) != PDG_t:: kMuonMinus ) {
12031216 return -1 ;
12041217 }
12051218 // check if the pion track is a muon coming from a pi -> mu + vu decay, if yes, take the mother pi
12061219 auto mcParticlePiTmp = mcParticlePi;
1207- if (std::abs (mcParticlePiTmp.pdgCode ()) == 13 ) {
1220+ if (std::abs (mcParticlePiTmp.pdgCode ()) == PDG_t:: kMuonMinus ) {
12081221 for (const auto & motherPi : mcParticlePiTmp.template mothers_as <aod::McParticles>()) {
1209- if (std::abs (motherPi.pdgCode ()) == 211 ) {
1222+ if (std::abs (motherPi.pdgCode ()) == PDG_t:: kPiPlus ) {
12101223 mcParticlePiTmp = motherPi;
12111224 isMuonReco = true ;
12121225 break ;
0 commit comments