Skip to content

Commit 992ab80

Browse files
[PWGHF,Common] Add Cd to deKpi candidates reconstruction workflow into the HF framework (#13453)
Co-authored-by: Vít Kučera <26327373+vkucera@users.noreply.github.com>
1 parent 5a81ac0 commit 992ab80

File tree

13 files changed

+922
-79
lines changed

13 files changed

+922
-79
lines changed

Common/Core/TrackSelectorPID.h

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#ifndef COMMON_CORE_TRACKSELECTORPID_H_
1818
#define COMMON_CORE_TRACKSELECTORPID_H_
1919

20+
#include <CommonConstants/PhysicsConstants.h>
2021
#include <Framework/Logger.h>
2122
#include <ReconstructionDataFormats/PID.h>
2223

@@ -43,6 +44,9 @@ class TrackSelectorPidBase
4344
/// Default constructor
4445
TrackSelectorPidBase() = default;
4546

47+
static constexpr float NSigmaMinDefault{-999.f};
48+
static constexpr float NSigmaMaxDefault{999.f};
49+
4650
/// Conversion operator
4751
template <uint64_t pdgNew>
4852
operator TrackSelectorPidBase<pdgNew>() const
@@ -108,10 +112,10 @@ class TrackSelectorPidBase
108112
/// \param tpcNSigmaCustom custom TPC nσ value to be used for the selection, in case the desired value cannot be taken from the track table
109113
/// \return true if track satisfies TPC PID hypothesis for given TPC nσ range
110114
template <typename T>
111-
bool isSelectedByTpc(const T& track, bool& conditionalTof, float tpcNSigmaCustom = -999.f)
115+
bool isSelectedByTpc(const T& track, bool& conditionalTof, float tpcNSigmaCustom = NSigmaMinDefault)
112116
{
113117
// Accept if selection is disabled via large values.
114-
if (mNSigmaTpcMin < -999. && mNSigmaTpcMax > 999.) {
118+
if (mNSigmaTpcMin < NSigmaMinDefault && mNSigmaTpcMax > NSigmaMaxDefault) {
115119
return true;
116120
}
117121

@@ -127,16 +131,18 @@ class TrackSelectorPidBase
127131
nSigma = track.tpcNSigmaKa();
128132
} else if constexpr (pdg == kProton) {
129133
nSigma = track.tpcNSigmaPr();
134+
} else if constexpr (pdg == o2::constants::physics::Pdg::kDeuteron) {
135+
nSigma = track.tpcNSigmaDe();
130136
} else {
131137
errorPdg();
132138
}
133139

134140
/// use custom TPC nσ, if a valid value is provided
135-
if (tpcNSigmaCustom > -999.f) {
141+
if (tpcNSigmaCustom > NSigmaMinDefault) {
136142
nSigma = tpcNSigmaCustom;
137143
}
138144

139-
if (mNSigmaTpcMinCondTof < -999. && mNSigmaTpcMaxCondTof > 999.) {
145+
if (mNSigmaTpcMinCondTof < NSigmaMinDefault && mNSigmaTpcMaxCondTof > NSigmaMaxDefault) {
140146
conditionalTof = true;
141147
} else {
142148
conditionalTof = mNSigmaTpcMinCondTof <= nSigma && nSigma <= mNSigmaTpcMaxCondTof;
@@ -148,7 +154,7 @@ class TrackSelectorPidBase
148154
/// \param track track
149155
/// \return TPC selection status (see TrackSelectorPID::Status)
150156
template <typename T>
151-
TrackSelectorPID::Status statusTpc(const T& track, float tpcNSigmaCustom = -999.f)
157+
TrackSelectorPID::Status statusTpc(const T& track, float tpcNSigmaCustom = NSigmaMinDefault)
152158
{
153159
if (!isValidForTpc(track)) {
154160
return TrackSelectorPID::NotApplicable;
@@ -202,10 +208,10 @@ class TrackSelectorPidBase
202208
/// \param tofNSigmaCustom custom TOF nσ value to be used for the selection, in case the desired value cannot be taken from the track table
203209
/// \return true if track satisfies TOF PID hypothesis for given TOF nσ range
204210
template <typename T>
205-
bool isSelectedByTof(const T& track, bool& conditionalTpc, float tofNSigmaCustom = -999.f)
211+
bool isSelectedByTof(const T& track, bool& conditionalTpc, float tofNSigmaCustom = NSigmaMinDefault)
206212
{
207213
// Accept if selection is disabled via large values.
208-
if (mNSigmaTofMin < -999. && mNSigmaTofMax > 999.) {
214+
if (mNSigmaTofMin < NSigmaMinDefault && mNSigmaTofMax > NSigmaMaxDefault) {
209215
return true;
210216
}
211217

@@ -221,16 +227,18 @@ class TrackSelectorPidBase
221227
nSigma = track.tofNSigmaKa();
222228
} else if constexpr (pdg == kProton) {
223229
nSigma = track.tofNSigmaPr();
230+
} else if constexpr (pdg == o2::constants::physics::Pdg::kDeuteron) {
231+
nSigma = track.tofNSigmaDe();
224232
} else {
225233
errorPdg();
226234
}
227235

228236
/// use custom TOF nσ, if a valid value is provided
229-
if (tofNSigmaCustom > -999.f) {
237+
if (tofNSigmaCustom > NSigmaMinDefault) {
230238
nSigma = tofNSigmaCustom;
231239
}
232240

233-
if (mNSigmaTofMinCondTpc < -999. && mNSigmaTofMaxCondTpc > 999.) {
241+
if (mNSigmaTofMinCondTpc < NSigmaMinDefault && mNSigmaTofMaxCondTpc > NSigmaMaxDefault) {
234242
conditionalTpc = true;
235243
} else {
236244
conditionalTpc = mNSigmaTofMinCondTpc <= nSigma && nSigma <= mNSigmaTofMaxCondTpc;
@@ -242,7 +250,7 @@ class TrackSelectorPidBase
242250
/// \param track track
243251
/// \return TOF selection status (see TrackSelectorPID::Status)
244252
template <typename T>
245-
TrackSelectorPID::Status statusTof(const T& track, float tofNSigmaCustom = -999.f)
253+
TrackSelectorPID::Status statusTof(const T& track, float tofNSigmaCustom = NSigmaMinDefault)
246254
{
247255
if (!isValidForTof(track)) {
248256
return TrackSelectorPID::NotApplicable;
@@ -301,7 +309,7 @@ class TrackSelectorPidBase
301309
bool isSelectedByRich(const T& track, bool& conditionalTof)
302310
{
303311
// Accept if selection is disabled via large values.
304-
if (mNSigmaRichMin < -999. && mNSigmaRichMax > 999.) {
312+
if (mNSigmaRichMin < NSigmaMinDefault && mNSigmaRichMax > NSigmaMaxDefault) {
305313
return true;
306314
}
307315

@@ -321,7 +329,7 @@ class TrackSelectorPidBase
321329
errorPdg();
322330
}
323331

324-
if (mNSigmaRichMinCondTof < -999. && mNSigmaRichMaxCondTof > 999.) {
332+
if (mNSigmaRichMinCondTof < NSigmaMinDefault && mNSigmaRichMaxCondTof > NSigmaMaxDefault) {
325333
conditionalTof = true;
326334
} else {
327335
conditionalTof = mNSigmaRichMinCondTof <= nSigma && nSigma <= mNSigmaRichMaxCondTof;
@@ -405,7 +413,7 @@ class TrackSelectorPidBase
405413
/// \param track track
406414
/// \return status of combined PID (TPC or TOF) (see TrackSelectorPID::Status)
407415
template <typename T>
408-
TrackSelectorPID::Status statusTpcOrTof(const T& track, float tpcNSigmaCustom = -999.f, float tofNSigmaCustom = -999.f)
416+
TrackSelectorPID::Status statusTpcOrTof(const T& track, float tpcNSigmaCustom = NSigmaMinDefault, float tofNSigmaCustom = NSigmaMinDefault)
409417
{
410418
int pidTpc = statusTpc(track, tpcNSigmaCustom);
411419
int pidTof = statusTof(track, tofNSigmaCustom);
@@ -426,7 +434,7 @@ class TrackSelectorPidBase
426434
/// \param track track
427435
/// \return status of combined PID (TPC and TOF) (see TrackSelectorPID::Status)
428436
template <typename T>
429-
TrackSelectorPID::Status statusTpcAndTof(const T& track, float tpcNSigmaCustom = -999.f, float tofNSigmaCustom = -999.f)
437+
TrackSelectorPID::Status statusTpcAndTof(const T& track, float tpcNSigmaCustom = NSigmaMinDefault, float tofNSigmaCustom = NSigmaMinDefault)
430438
{
431439
int pidTpc = TrackSelectorPID::NotApplicable;
432440
if (track.hasTPC()) {
@@ -464,23 +472,29 @@ class TrackSelectorPidBase
464472
template <typename T>
465473
bool isElectronAndNotPion(const T& track, bool useTof = true, bool useRich = true)
466474
{
475+
constexpr float NSigmaInvalid{-1000.f};
476+
constexpr float PTofRichTElectronMin{0.4f};
477+
constexpr float PTofRichTElectronMax{0.6f};
478+
constexpr float PRichPionBandMin{1.0f};
479+
constexpr float PRichPionBandMax{2.0f};
480+
467481
bool isSelTof = false;
468482
bool isSelRich = false;
469483
bool hasRich = track.richId() > -1;
470484
bool hasTof = isValidForTof(track);
471485
auto nSigmaTofEl = track.tofNSigmaEl();
472486
auto nSigmaTofPi = track.tofNSigmaPi();
473-
auto nSigmaRichEl = hasRich ? track.rich().richNsigmaEl() : -1000.;
474-
auto nSigmaRichPi = hasRich ? track.rich().richNsigmaPi() : -1000.;
487+
auto nSigmaRichEl = hasRich ? track.rich().richNsigmaEl() : NSigmaInvalid;
488+
auto nSigmaRichPi = hasRich ? track.rich().richNsigmaPi() : NSigmaInvalid;
475489
auto p = track.p();
476490

477491
// TOF
478-
if (useTof && hasTof && (p < 0.6)) {
479-
if (p > 0.4 && hasRich) {
492+
if (useTof && hasTof && (p < PTofRichTElectronMax)) {
493+
if (p > PTofRichTElectronMin && hasRich) {
480494
if ((std::abs(nSigmaTofEl) < mNSigmaTofMax) && (std::abs(nSigmaRichEl) < mNSigmaRichMax)) {
481495
isSelTof = true; // is selected as electron by TOF and RICH
482496
}
483-
} else if (p <= 0.4) {
497+
} else if (p <= PTofRichTElectronMin) {
484498
if (std::abs(nSigmaTofEl) < mNSigmaTofMax) {
485499
isSelTof = true; // is selected as electron by TOF
486500
}
@@ -499,7 +513,7 @@ class TrackSelectorPidBase
499513
if (std::abs(nSigmaRichEl) < mNSigmaRichMax) {
500514
isSelRich = true; // is selected as electron by RICH
501515
}
502-
if ((std::abs(nSigmaRichPi) < mNSigmaRichMax) && (p > 1.0) && (p < 2.0)) {
516+
if ((std::abs(nSigmaRichPi) < mNSigmaRichMax) && (p > PRichPionBandMin) && (p < PRichPionBandMax)) {
503517
isSelRich = false; // is selected as pion by RICH
504518
}
505519
} else {
@@ -551,6 +565,8 @@ class TrackSelectorPidBase
551565
return track.bayesID() == o2::track::PID::Kaon;
552566
} else if constexpr (pdg == kProton) {
553567
return track.bayesID() == o2::track::PID::Proton;
568+
} else if constexpr (pdg == o2::constants::physics::Pdg::kDeuteron) {
569+
return track.bayesID() == o2::track::PID::Deuteron;
554570
} else {
555571
errorPdg();
556572
return false;
@@ -579,6 +595,8 @@ class TrackSelectorPidBase
579595
prob = track.bayesKa();
580596
} else if constexpr (pdg == kProton) {
581597
prob = track.bayesPr();
598+
} else if constexpr (pdg == o2::constants::physics::Pdg::kDeuteron) {
599+
prob = track.bayesDe();
582600
} else {
583601
errorPdg();
584602
}
@@ -656,10 +674,11 @@ class TrackSelectorPidBase
656674
};
657675

658676
// Predefined types
659-
using TrackSelectorEl = TrackSelectorPidBase<kElectron>; // El
660-
using TrackSelectorMu = TrackSelectorPidBase<kMuonMinus>; // Mu
661-
using TrackSelectorPi = TrackSelectorPidBase<kPiPlus>; // Pi
662-
using TrackSelectorKa = TrackSelectorPidBase<kKPlus>; // Ka
663-
using TrackSelectorPr = TrackSelectorPidBase<kProton>; // Pr
677+
using TrackSelectorEl = TrackSelectorPidBase<kElectron>; // El
678+
using TrackSelectorMu = TrackSelectorPidBase<kMuonMinus>; // Mu
679+
using TrackSelectorPi = TrackSelectorPidBase<kPiPlus>; // Pi
680+
using TrackSelectorKa = TrackSelectorPidBase<kKPlus>; // Ka
681+
using TrackSelectorPr = TrackSelectorPidBase<kProton>; // Pr
682+
using TrackSelectorDe = TrackSelectorPidBase<o2::constants::physics::Pdg::kDeuteron>; // De
664683

665684
#endif // COMMON_CORE_TRACKSELECTORPID_H_

PWGHF/Core/HfHelper.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,20 @@ class HfHelper
410410
return RecoDecay::m(std::array{candidate.pVectorProng2(), candidate.pVectorProng0()}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPiPlus});
411411
}
412412

413+
// Cd± → De± K∓ π±
414+
415+
template <typename T>
416+
auto invMassCdToDeKPi(const T& candidate)
417+
{
418+
return candidate.m(std::array{o2::constants::physics::MassDeuteron, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus});
419+
}
420+
421+
template <typename T>
422+
auto invMassCdToPiKDe(const T& candidate)
423+
{
424+
return candidate.m(std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus, o2::constants::physics::MassDeuteron});
425+
}
426+
413427
// Ξc± → p± K∓ π±
414428

415429
template <typename T>

PWGHF/Core/SelectorCuts.h

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,13 @@ static const std::vector<std::string> labelsCutVarTrack = {"min_dcaxytoprimary",
6868
namespace hf_presel_pid
6969
{
7070
// default values for the PID cuts for protons in the track-index-skim-creator
71-
constexpr float CutsPid[4][6] = {{0.f, 1000.f, 5.f, 0.f, 1000.f, 5.f},
71+
constexpr float CutsPid[5][6] = {{0.f, 1000.f, 5.f, 0.f, 1000.f, 5.f},
72+
{0.f, 1000.f, 5.f, 0.f, 1000.f, 5.f},
7273
{0.f, 1000.f, 5.f, 0.f, 1000.f, 5.f},
7374
{0.f, 1000.f, 5.f, 0.f, 1000.f, 5.f},
7475
{0.f, 1000.f, 5.f, 0.f, 1000.f, 5.f}};
7576
static const std::vector<std::string> labelsCutsPid = {"minPtTpc", "maxPtTpc", "nSigmaMaxTpc", "minPtTof", "maxPtTof", "nSigmaMaxTof"};
76-
static const std::vector<std::string> labelsRowsPid = {"ProtonInLcToPKPi", "ProtonInXicToPKPi", "ProtonInLcToPK0S", "KaonIn3Prongs"};
77+
static const std::vector<std::string> labelsRowsPid = {"ProtonInLcToPKPi", "ProtonInXicToPKPi", "ProtonInLcToPK0S", "KaonIn3Prongs", "DeuteronInCdToDeKPi"};
7778
} // namespace hf_presel_pid
7879

7980
namespace hf_cuts_bdt_multiclass
@@ -1516,6 +1517,43 @@ static const std::vector<std::string> labelsPt = {
15161517
static const std::vector<std::string> labelsCutVar = {"max pKpi mass Lc", "max piKp mass Lc"};
15171518
} // namespace hf_cuts_sigmac_to_p_k_pi
15181519

1520+
namespace hf_cuts_cd_to_de_k_pi
1521+
{
1522+
static constexpr int NBinsPt = 6;
1523+
static constexpr int NCutVars = 10;
1524+
// default values for the pT bin edges (can be used to configure histogram axis)
1525+
// offset by 1 from the bin numbers in cuts array
1526+
constexpr double BinsPt[NBinsPt + 1] = {
1527+
0.,
1528+
2.,
1529+
4.,
1530+
6.,
1531+
8.,
1532+
12.,
1533+
24.};
1534+
const auto vecBinsPt = std::vector<double>{BinsPt, BinsPt + NBinsPt + 1};
1535+
1536+
// default values for the cuts m, ptP, ptK, ptPi, chi2PCA, dL, cosp, dLXY, NdLXY, ImpParXY, mass(Kpi)
1537+
constexpr double Cuts[NBinsPt][NCutVars] = {{0.4, 0.4, 0.4, 0.4, 0., 0.005, 0., 0., 0., 1e+10}, /* 0 < pT < 2 */
1538+
{0.4, 0.4, 0.4, 0.4, 0., 0.005, 0., 0., 0., 1e+10}, /* 2 < pT < 4 */
1539+
{0.4, 0.4, 0.4, 0.4, 0., 0.005, 0., 0., 0., 1e+10}, /* 4 < pT < 6 */
1540+
{0.4, 0.4, 0.4, 0.4, 0., 0.005, 0., 0., 0., 1e+10}, /* 6 < pT < 8 */
1541+
{0.4, 0.4, 0.4, 0.4, 0., 0.005, 0., 0., 0., 1e+10}, /* 8 < pT < 12 */
1542+
{0.4, 0.4, 0.4, 0.4, 0., 0.005, 0., 0., 0., 1e+10}}; /* 12 < pT < 24 */
1543+
1544+
// row labels
1545+
static const std::vector<std::string> labelsPt = {
1546+
"pT bin 0",
1547+
"pT bin 1",
1548+
"pT bin 2",
1549+
"pT bin 3",
1550+
"pT bin 4",
1551+
"pT bin 5"};
1552+
1553+
// column labels
1554+
static const std::vector<std::string> labelsCutVar = {"m", "pT De", "pT K", "pT Pi", "Chi2PCA", "decay length", "cos pointing angle", "decLengthXY", "normDecLXY", "impParXY"};
1555+
} // namespace hf_cuts_cd_to_de_k_pi
1556+
15191557
} // namespace o2::analysis
15201558

15211559
#endif // PWGHF_CORE_SELECTORCUTS_H_

PWGHF/D2H/Tasks/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ o2physics_add_dpl_workflow(task-bs
4949
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
5050
COMPONENT_NAME Analysis)
5151

52+
o2physics_add_dpl_workflow(task-cd
53+
SOURCES taskCd.cxx
54+
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::EventFilteringUtils
55+
COMPONENT_NAME Analysis)
56+
5257
o2physics_add_dpl_workflow(task-charm-polarisation
5358
SOURCES taskCharmPolarisation.cxx
5459
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore

0 commit comments

Comments
 (0)