2727#include " Common/Core/RecoDecay.h"
2828
2929#include < CommonConstants/MathConstants.h>
30+ #include < CommonConstants/PhysicsConstants.h>
3031#include < Framework/AnalysisHelpers.h>
3132#include < Framework/Configurable.h>
3233#include < Framework/HistogramRegistry.h>
@@ -60,34 +61,40 @@ struct ConfKinkFilters : o2::framework::ConfigurableGroup {
6061
6162// selections bits for all kinks
6263// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
63- #define KINK_DEFAULT_BITS \
64- o2::framework::Configurable<bool > passThrough{" passThrough" , false , " If true, all Kinks are passed through. Bits for all selections are stored." }; \
65- o2::framework::Configurable<std::vector<float >> kinkTopoDcaMax{" kinkTopoDcaMax" , {2 .0f }, " Maximum kink topological DCA" }; \
66- o2::framework::Configurable<std::vector<float >> transRadMin{" transRadMin" , {20 . f }, " Minimum transverse radius (cm)" }; \
67- o2::framework::Configurable<std::vector<float >> transRadMax{" transRadMax" , {100 .f }, " Maximum transverse radius (cm)" }; \
68- o2::framework::Configurable<std::vector<float >> dauAbsEtaMax{" dauAbsEtaMax" , {1 .0f }, " Maximum absolute pseudorapidity for daughter track" }; \
69- o2::framework::Configurable<std::vector<float >> dauDcaPvMin{" dauDcaPvMin" , {0 .1f }, " Minimum DCA of daughter from primary vertex (cm)" }; \
70- o2::framework::Configurable<std::vector<float >> mothDcaPvMax{" mothDcaPvMax" , {1 .0f }, " Maximum DCA of mother from primary vertex (cm)" }; \
71- o2::framework::Configurable<std::vector<float >> alphaAPMin{ " alphaAPMin " , {- 1 . 0f }, " Minimum Alpha_AP for Sigma candidates" }; \
72- o2::framework::Configurable<std::vector<float >> alphaAPMax{ " alphaAPMax " , {0 .0f }, " Maximum Alpha_AP for Sigma candidates" }; \
73- o2::framework::Configurable<std::vector<float >> qtAPMin{ " qtAPMin " , {0 .15f }, " Minimum qT_AP for Sigma candidates " }; \
74- o2::framework::Configurable<std::vector<float >> qtAPMax{ " qtAPMax " , {0 .2f }, " Maximum qT_AP for Sigma candidates " }; \
75- o2::framework::Configurable<std::vector<float >> cosPointingAngleMin{ " cosPointingAngleMin " , {0 . 0f }, " Minimum cosine of pointing angle " };
64+ #define KINK_DEFAULT_BITS \
65+ o2::framework::Configurable<bool > passThrough{" passThrough" , false , " If true, all Kinks are passed through. Bits for all selections are stored." }; \
66+ o2::framework::Configurable<std::vector<float >> kinkTopoDcaMax{" kinkTopoDcaMax" , {2 .0f }, " Maximum kink topological DCA" }; \
67+ o2::framework::Configurable<std::vector<float >> transRadMin{" transRadMin" , {19 . 6f }, " Minimum transverse radius (cm)" }; \
68+ o2::framework::Configurable<std::vector<float >> transRadMax{" transRadMax" , {100 .f }, " Maximum transverse radius (cm)" }; \
69+ o2::framework::Configurable<std::vector<float >> dauAbsEtaMax{" dauAbsEtaMax" , {1 .0f }, " Maximum absolute pseudorapidity for daughter track" }; \
70+ o2::framework::Configurable<std::vector<float >> dauDcaPvMin{" dauDcaPvMin" , {0 .1f }, " Minimum DCA of daughter from primary vertex (cm)" }; \
71+ o2::framework::Configurable<std::vector<float >> mothDcaPvMax{" mothDcaPvMax" , {1 .0f }, " Maximum DCA of mother from primary vertex (cm)" }; \
72+ o2::framework::Configurable<std::vector<float >> qtAPMin{ " qtAPMin " , {0 . 15f }, " Minimum qT_AP for Sigma candidates" }; \
73+ o2::framework::Configurable<std::vector<float >> qtAPMax{ " qtAPMax " , {0 .2f }, " Maximum qT_AP for Sigma candidates" }; \
74+ o2::framework::Configurable<std::vector<float >> cosPointingAngleMin{ " cosPointingAngleMin " , {0 .0f }, " Minimum cosine of pointing angle " }; \
75+ o2::framework::Configurable<std::vector<float >> ptOriginalMin{ " ptOriginalMin " , {1 .2f }, " Minimum original (not recalculated) pT of the mother (GeV/c) " }; \
76+ o2::framework::Configurable<std::vector<float >> ptOriginalMax{ " ptOriginalMax " , {10 . f }, " Maximum original (not recalculated) pT of the mother (GeV/c) " };
7677
7778// derived selection bits for sigma
7879struct ConfSigmaBits : o2::framework::ConfigurableGroup {
7980 std::string prefix = std::string(" SigmaBits" );
8081 KINK_DEFAULT_BITS
82+ o2::framework::Configurable<std::vector<float >> alphaAPMin{" alphaAPMin" , {-1 .0f }, " Minimum Alpha_AP for Sigma candidates" };
83+ o2::framework::Configurable<std::vector<float >> alphaAPMax{" alphaAPMax" , {0 .0f }, " Maximum Alpha_AP for Sigma candidates" };
8184 o2::framework::Configurable<std::vector<float >> chaDauTpcPion{" chaDauTpcPion" , {5 .f }, " Maximum |nsigma_Pion| TPC for charged daughter tracks" };
8285};
8386
8487// derived selection bits for sigma plus
8588struct ConfSigmaPlusBits : o2::framework::ConfigurableGroup {
8689 std::string prefix = std::string(" SigmaPlusBits" );
8790 KINK_DEFAULT_BITS
91+ o2::framework::Configurable<std::vector<float >> alphaAPMin{" alphaAPMin" , {0 .0f }, " Minimum Alpha_AP for SigmaPlus candidates" };
92+ o2::framework::Configurable<std::vector<float >> alphaAPMax{" alphaAPMax" , {1 .0f }, " Maximum Alpha_AP for SigmaPlus candidates" };
8893 o2::framework::Configurable<std::vector<float >> chaDauTpcProton{" chaDauTpcProton" , {5 .f }, " Maximum |nsigma_Proton| TPC for charged daughter tracks" };
89- o2::framework::Configurable<std::vector<float >> chaDauTofProton{" chaDauTofProton" , {5 .f }, " Maximum combined |nsigma_Proton| (TPC+TOF) for charged daughter tracks" };
90- o2::framework::Configurable<float > pidThres{" pidThres" , 0 .75f , " Momentum threshold for using TOF/combined pid for daughter tracks (GeV/c)" };
94+ o2::framework::Configurable<std::vector<float >> chaDauTofProton{" chaDauTofProton" , {}, " Maximum |nsigma_Proton| TOF for charged daughter tracks (only used above pidThres)" };
95+ o2::framework::Configurable<bool > requireTof{" requireTof" , false , " If true, TOF PID is a minimal selection above pidThres. If false, TOF PID only sets bits" };
96+ o2::framework::Configurable<bool > keepTracksWithoutTof{" keepTracksWithoutTof" , true , " If true, daughters above pidThres without TOF signal pass all TOF selections" };
97+ o2::framework::Configurable<float > pidThres{" pidThres" , 0 .75f , " Daughter momentum threshold (GeV/c). Below, only TPC PID is used and all TOF selections are passed" };
9198};
9299
93100#undef KINK_DEFAULT_BITS
@@ -153,6 +160,9 @@ enum KinkSeles {
153160 kQtAPMax ,
154161 kCosPointingAngleMin ,
155162
163+ kPtOriginalMin ,
164+ kPtOriginalMax ,
165+
156166 kKinkSelsMax
157167};
158168
@@ -173,7 +183,9 @@ const std::unordered_map<KinkSeles, std::string> kinkSelectionNames = {
173183 {kAlphaAPMax , " alphaAPMax" },
174184 {kQtAPMin , " qtAPMin" },
175185 {kQtAPMax , " qtAPMax" },
176- {kCosPointingAngleMin , " cosPointingAngleMin" }};
186+ {kCosPointingAngleMin , " cosPointingAngleMin" },
187+ {kPtOriginalMin , " ptOriginalMin" },
188+ {kPtOriginalMax , " ptOriginalMax" }};
177189
178190// / enum for all kink pre-filters (evaluated in checkFilters, before the selection bitmask)
179191enum KinkFilters {
@@ -232,8 +244,9 @@ class KinkSelection : public baseselection::BaseSelection<float, o2::analysis::f
232244 mMassSigmaPlusLowerLimit = filter.massMinSigmaPlus .value ;
233245 mMassSigmaPlusUpperLimit = filter.massMaxSigmaPlus .value ;
234246 mPidThreshold = config.pidThres .value ;
235- this ->addSelection (kChaDaughTpcProton , kinkSelectionNames.at (kChaDaughTpcProton ), config.chaDauTpcProton .value , limits::kAbsUpperLimit , false , false , true );
236- this ->addSelection (kChaDaughTofProton , kinkSelectionNames.at (kChaDaughTofProton ), config.chaDauTofProton .value , limits::kUpperLimit , false , false , true );
247+ mKeepTracksWithoutTof = config.keepTracksWithoutTof .value ;
248+ this ->addSelection (kChaDaughTpcProton , kinkSelectionNames.at (kChaDaughTpcProton ), config.chaDauTpcProton .value , limits::kAbsUpperLimit , true , true , false );
249+ this ->addSelection (kChaDaughTofProton , kinkSelectionNames.at (kChaDaughTofProton ), config.chaDauTofProton .value , limits::kAbsUpperLimit , true , config.requireTof .value , false );
237250 }
238251
239252 this ->addSelection (kKinkTopoDcaMax , kinkSelectionNames.at (kKinkTopoDcaMax ), config.kinkTopoDcaMax .value , limits::kUpperLimit , true , true , false );
@@ -247,6 +260,8 @@ class KinkSelection : public baseselection::BaseSelection<float, o2::analysis::f
247260 this ->addSelection (kQtAPMin , kinkSelectionNames.at (kQtAPMin ), config.qtAPMin .value , limits::kLowerLimit , true , true , false );
248261 this ->addSelection (kQtAPMax , kinkSelectionNames.at (kQtAPMax ), config.qtAPMax .value , limits::kUpperLimit , true , true , false );
249262 this ->addSelection (kCosPointingAngleMin , kinkSelectionNames.at (kCosPointingAngleMin ), config.cosPointingAngleMin .value , limits::kLowerLimit , true , true , false );
263+ this ->addSelection (kPtOriginalMin , kinkSelectionNames.at (kPtOriginalMin ), config.ptOriginalMin .value , limits::kLowerLimit , true , true , false );
264+ this ->addSelection (kPtOriginalMax , kinkSelectionNames.at (kPtOriginalMax ), config.ptOriginalMax .value , limits::kUpperLimit , true , true , false );
250265
251266 this ->setupSelectionHistogram <SelectionHistName>(registry);
252267
@@ -281,7 +296,7 @@ class KinkSelection : public baseselection::BaseSelection<float, o2::analysis::f
281296 };
282297
283298 template <typename T1 , typename T2 , typename T3 >
284- void computeKinkKinematics (T1 const & kinkCand, T2 const & /* tracks*/ , T3 const & col)
299+ void computeKinkKinematics (T1 const & kinkCand, T2 const & /* tracks*/ , T3 const & /* col*/ )
285300 {
286301 std::array<float , 3 > momMother = {kinkCand.pxMoth (), kinkCand.pyMoth (), kinkCand.pzMoth ()};
287302 float kinkMomP = RecoDecay::p (momMother);
@@ -300,7 +315,7 @@ class KinkSelection : public baseselection::BaseSelection<float, o2::analysis::f
300315 float p2A = kinkDauP * kinkDauP;
301316 mQtAp = (p2V0 > 0 .f ) ? std::sqrt (std::max (0 .f , p2A - dp * dp / p2V0)) : 0 .f ;
302317
303- std::array<float , 3 > vMother = {kinkCand.xDecVtx () - col. posX () , kinkCand.yDecVtx () - col. posY () , kinkCand.zDecVtx () - col. posZ ()};
318+ std::array<float , 3 > vMother = {kinkCand.xDecVtx (), kinkCand.yDecVtx (), kinkCand.zDecVtx ()};
304319 float vMotherNorm = std::sqrt (std::inner_product (vMother.begin (), vMother.end (), vMother.begin (), 0 .f ));
305320 mCosPointingAngle = (vMotherNorm > 0 .f && kinkMomP > 0 .f ) ? (std::inner_product (momMother.begin (), momMother.end (), vMother.begin (), 0 .f )) / (kinkMomP * vMotherNorm) : 0 .f ;
306321 mTransRadius = std::hypot (kinkCand.xDecVtx (), kinkCand.yDecVtx ());
@@ -327,6 +342,9 @@ class KinkSelection : public baseselection::BaseSelection<float, o2::analysis::f
327342 this ->evaluateObservable (kQtAPMin , mQtAp );
328343 this ->evaluateObservable (kQtAPMax , mQtAp );
329344 this ->evaluateObservable (kCosPointingAngleMin , mCosPointingAngle );
345+ // the stored pT is the recalculated one, the original pT is only available as selection bits
346+ this ->evaluateObservable (kPtOriginalMin , mKinkMotherPtOriginal );
347+ this ->evaluateObservable (kPtOriginalMax , mKinkMotherPtOriginal );
330348 this ->evaluateObservable (kKinkTopoDcaMax , kinkCand.dcaKinkTopo ());
331349
332350 // Compute transRadius
@@ -345,14 +363,13 @@ class KinkSelection : public baseselection::BaseSelection<float, o2::analysis::f
345363 this ->evaluateObservable (kChaDaughTpcPion , chaDaughter.tpcNSigmaPi ());
346364 }
347365 if constexpr (modes::isEqual (kinkType, modes::Kink::kSigmaPlus )) {
366+ this ->evaluateObservable (kChaDaughTpcProton , chaDaughter.tpcNSigmaPr ());
348367 if (mKinkDauP < mPidThreshold ) {
349- this ->evaluateObservable (kChaDaughTpcProton , chaDaughter.tpcNSigmaPr ());
368+ this ->evaluateObservable (kChaDaughTofProton , 0 .f );
369+ } else if (chaDaughter.hasTOF ()) {
370+ this ->evaluateObservable (kChaDaughTofProton , chaDaughter.tofNSigmaPr ());
350371 } else {
351- if (chaDaughter.hasTOF ()) {
352- this ->evaluateObservable (kChaDaughTofProton , std::abs (chaDaughter.tofNSigmaPr ()));
353- } else {
354- this ->evaluateObservable (kChaDaughTofProton , 999 .f );
355- }
372+ this ->evaluateObservable (kChaDaughTofProton , mKeepTracksWithoutTof ? 0 .f : 999 .f );
356373 }
357374 }
358375
@@ -368,9 +385,20 @@ class KinkSelection : public baseselection::BaseSelection<float, o2::analysis::f
368385 mKinkMotherEta = RecoDecay::eta (momMother);
369386 mKinkMotherPhi = RecoDecay::phi (momMother);
370387
371- // Recalculate pT using kinematic constraints
372- float ptRecalc = utils::calcPtnew (momMother[0 ], momMother[1 ], momMother[2 ], momDaughter[0 ], momDaughter[1 ], momDaughter[2 ]);
373- mKinkMotherPt = (ptRecalc > 0 .f ) ? ptRecalc : std::hypot (momMother[0 ], momMother[1 ]);
388+ // Recalculate pT using kinematic constraints of the decay channel
389+ float ptRecalc = -999 .f ;
390+ if constexpr (modes::isEqual (kinkType, modes::Kink::kSigma )) {
391+ // Sigma- -> pi- n
392+ ptRecalc = utils::calcPtnew (momMother[0 ], momMother[1 ], momMother[2 ], momDaughter[0 ], momDaughter[1 ], momDaughter[2 ],
393+ o2::constants::physics::MassSigmaMinus, o2::constants::physics::MassPionCharged, o2::constants::physics::MassNeutron);
394+ }
395+ if constexpr (modes::isEqual (kinkType, modes::Kink::kSigmaPlus )) {
396+ // Sigma+ -> p pi0
397+ ptRecalc = utils::calcPtnew (momMother[0 ], momMother[1 ], momMother[2 ], momDaughter[0 ], momDaughter[1 ], momDaughter[2 ],
398+ o2::constants::physics::MassSigmaPlus, o2::constants::physics::MassProton, o2::constants::physics::MassPionNeutral);
399+ }
400+ mKinkMotherPtOriginal = std::hypot (momMother[0 ], momMother[1 ]);
401+ mKinkMotherPt = (ptRecalc > 0 .f ) ? ptRecalc : mKinkMotherPtOriginal ;
374402 }
375403
376404 template <typename T>
@@ -444,6 +472,7 @@ class KinkSelection : public baseselection::BaseSelection<float, o2::analysis::f
444472 float mMassSigmaPlusLowerLimit = 1 .15f ;
445473 float mMassSigmaPlusUpperLimit = 1 .25f ;
446474 float mPidThreshold = 0 .75f ;
475+ bool mKeepTracksWithoutTof = true ;
447476
448477 // kinematic filters
449478 float mPtMin = 0 .f;
@@ -454,7 +483,8 @@ class KinkSelection : public baseselection::BaseSelection<float, o2::analysis::f
454483 float mPhiMax = o2::constants::math::TwoPI;
455484
456485 // mother kinematic
457- float mKinkMotherPt = 0 .f;
486+ float mKinkMotherPt = 0 .f; // recalculated pT (falls back to the original pT if the recalculation fails)
487+ float mKinkMotherPtOriginal = 0 .f; // pT of the mother track as reconstructed
458488 float mKinkMotherEta = 0 .f;
459489 float mKinkMotherPhi = 0 .f;
460490
@@ -549,7 +579,8 @@ class KinkBuilder
549579 }
550580 }
551581
552- if (mProduceSigmas || mProduceSigmaMasks || mProduceSigmaExtras || mProduceSigmaPlus || mProduceSigmaPlusMasks || mProduceSigmaPlusExtras ) {
582+ if (mProduceSigmas || mProduceLiteSigmas || mProduceSigmaMasks || mProduceSigmaExtras ||
583+ mProduceSigmaPlus || mProduceLiteSigmaPlus || mProduceSigmaPlusMasks || mProduceSigmaPlusExtras ) {
553584 mFillAnyTable = true ;
554585 } else {
555586 LOG (info) << " No tables configured, Selection object will not be configured..." ;
0 commit comments