Skip to content

Commit d9d115f

Browse files
[PWGCF] Add systematic variations on topological selections of V0s in flow analyses (#13548)
1 parent 5bcb710 commit d9d115f

File tree

2 files changed

+137
-47
lines changed

2 files changed

+137
-47
lines changed

PWGCF/DataModel/CorrelationsDerived.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,13 @@ enum ParticleDecay {
145145
PhiToKKPID3,
146146
K0stoPiPi,
147147
LambdatoPPi,
148-
AntiLambdatoPiP
148+
AntiLambdatoPiP,
149+
K0stoPiPiLoose,
150+
K0stoPiPiTight,
151+
LambdaToPPiLoose,
152+
LambdaToPPiTight,
153+
AntiLambdaToPiPLoose,
154+
AntiLambdaToPiPTight
149155
};
150156
} // namespace cf2prongtrack
151157
DECLARE_SOA_TABLE(CF2ProngTracks, "AOD", "CF2PRONGTRACK", //! Reduced track table

PWGCF/TableProducer/filter2Prong.cxx

Lines changed: 130 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -58,28 +58,68 @@ struct Filter2Prong {
5858
O2_DEFINE_CONFIGURABLE(cfgImSigmaFormula, std::string, "(([p] < 0.5 || [hasTOF] <= 0.0) && abs([sTPC]) < 3.0) || ([p] >= 0.5 && abs([sTPC]) < 2.5 && abs([sTOF]) < 3.0)", "pT dependent daughter track sigma pass condition. Parameters: [p] momentum, [sTPC] sigma TPC, [sTOF] sigma TOF, [hasTOF] has TOF.")
5959

6060
struct : ConfigurableGroup {
61+
O2_DEFINE_CONFIGURABLE(storeLooseTight, bool, false, "Store also loose and tight V0 candidates for systematics");
6162
O2_DEFINE_CONFIGURABLE(tpcNClsCrossedRowsTrackMin, float, 70, "Minimum number of crossed rows in TPC");
6263
O2_DEFINE_CONFIGURABLE(etaTrackMax, float, 0.8, "Maximum pseudorapidity");
63-
O2_DEFINE_CONFIGURABLE(ptTrackMin, float, 0.1, "Minimum transverse momentum");
64-
O2_DEFINE_CONFIGURABLE(minV0DCAPr, float, 0.1, "Min V0 proton DCA");
65-
O2_DEFINE_CONFIGURABLE(minV0DCAPiLambda, float, 0.1, "Min V0 pion DCA for lambda");
66-
O2_DEFINE_CONFIGURABLE(minV0DCAPiK0s, float, 0.1, "Min V0 pion DCA for K0s");
67-
O2_DEFINE_CONFIGURABLE(daughPIDCuts, float, 4.0, "PID nsigma for V0s");
68-
O2_DEFINE_CONFIGURABLE(massK0Min, float, 0.4, "Minimum mass for K0");
69-
O2_DEFINE_CONFIGURABLE(massK0Max, float, 0.6, "Maximum mass for K0");
70-
O2_DEFINE_CONFIGURABLE(massLambdaMin, float, 1.0, "Minimum mass for lambda");
71-
O2_DEFINE_CONFIGURABLE(massLambdaMax, float, 1.3, "Maximum mass for lambda");
72-
O2_DEFINE_CONFIGURABLE(radiusMaxLambda, float, 2.3, "Maximum decay radius (cm) for lambda");
73-
O2_DEFINE_CONFIGURABLE(radiusMinLambda, float, 0.0, "Minimum decay radius (cm) for lambda");
74-
O2_DEFINE_CONFIGURABLE(radiusMaxK0s, float, 2.3, "Maximum decay radius (cm) for K0s");
75-
O2_DEFINE_CONFIGURABLE(radiusMinK0s, float, 0.0, "Minimum decay radius (cm) for K0s");
76-
O2_DEFINE_CONFIGURABLE(cosPaMinLambda, float, 0.98, "Minimum cosine of pointing angle for lambda");
77-
O2_DEFINE_CONFIGURABLE(cosPaMinK0s, float, 0.98, "Minimum cosine of pointing angle for K0s");
78-
O2_DEFINE_CONFIGURABLE(dcaV0DaughtersMaxLambda, float, 0.2, "Maximum DCA among the V0 daughters (cm) for lambda");
79-
O2_DEFINE_CONFIGURABLE(dcaV0DaughtersMaxK0s, float, 0.2, "Maximum DCA among the V0 daughters (cm) for K0s");
80-
O2_DEFINE_CONFIGURABLE(qtArmenterosMinForK0s, float, 0.12, "Minimum Armenteros' qt for K0s");
81-
O2_DEFINE_CONFIGURABLE(maxLambdaLifeTime, float, 30, "Maximum lambda lifetime (in cm)");
82-
O2_DEFINE_CONFIGURABLE(maxK0sLifeTime, float, 30, "Maximum K0s lifetime (in cm)");
64+
O2_DEFINE_CONFIGURABLE(ptTrackMin, float, 0.15, "Minimum transverse momentum");
65+
O2_DEFINE_CONFIGURABLE(minV0DCAPr, std::vector<float>,
66+
(std::vector<float>{0.06f, 0.07f, 0.08f}),
67+
"Maximum DCAxy for daughter tracks (Loose, Default, Tight)");
68+
O2_DEFINE_CONFIGURABLE(minV0DCAPiLambda, std::vector<float>,
69+
(std::vector<float>{0.1f, 0.2f, 0.3f}),
70+
"Min V0 pion DCA for lambda (Loose, Default, Tight)");
71+
O2_DEFINE_CONFIGURABLE(minV0DCAPiK0s, std::vector<float>,
72+
(std::vector<float>{0.05f, 0.1f, 0.2f}),
73+
"Min V0 pion DCA for K0s (Loose, Default, Tight)");
74+
O2_DEFINE_CONFIGURABLE(daughPIDCuts, std::vector<float>,
75+
(std::vector<float>{3.0f, 4.0f, 5.0f}),
76+
"PID nsigma for V0s (Loose, Default, Tight)");
77+
O2_DEFINE_CONFIGURABLE(massK0Min, std::vector<float>,
78+
(std::vector<float>{0.4f, 0.4f, 0.4f}),
79+
"Minimum mass for K0 (Loose, Default, Tight)");
80+
O2_DEFINE_CONFIGURABLE(massK0Max, std::vector<float>,
81+
(std::vector<float>{0.6f, 0.6f, 0.6f}),
82+
"Maximum mass for K0 (Loose, Default, Tight)");
83+
O2_DEFINE_CONFIGURABLE(massLambdaMin, std::vector<float>,
84+
(std::vector<float>{1.07f, 1.07f, 1.07f}),
85+
"Minimum mass for lambda (Loose, Default, Tight)");
86+
O2_DEFINE_CONFIGURABLE(massLambdaMax, std::vector<float>,
87+
(std::vector<float>{1.17f, 1.17f, 1.17f}),
88+
"Maximum mass for lambda (Loose, Default, Tight)");
89+
O2_DEFINE_CONFIGURABLE(radiusMaxLambda, std::vector<float>,
90+
(std::vector<float>{20.f, 30.f, 40.f}),
91+
"Maximum decay radius (cm) for lambda (Loose, Default, Tight)");
92+
O2_DEFINE_CONFIGURABLE(radiusMinLambda, std::vector<float>,
93+
(std::vector<float>{1.0f, 1.2f, 1.4f}),
94+
"Minimum decay radius (cm) for lambda (Loose, Default, Tight)");
95+
O2_DEFINE_CONFIGURABLE(radiusMaxK0s, std::vector<float>,
96+
(std::vector<float>{1.0f, 1.2f, 1.4f}),
97+
"Maximum decay radius (cm) for K0s (Loose, Default, Tight)");
98+
O2_DEFINE_CONFIGURABLE(radiusMinK0s, std::vector<float>,
99+
(std::vector<float>{0.0f, 0.0f, 0.1f}),
100+
"Minimum decay radius (cm) for K0s (Loose, Default, Tight)");
101+
O2_DEFINE_CONFIGURABLE(cosPaMinLambda, std::vector<float>,
102+
(std::vector<float>{0.990f, 0.993f, 0.995f}),
103+
"Minimum cosine of pointing angle for lambda (Loose, Default, Tight)");
104+
O2_DEFINE_CONFIGURABLE(cosPaMinK0s, std::vector<float>,
105+
(std::vector<float>{0.990f, 0.993f, 0.995f}),
106+
"Minimum cosine of pointing angle for K0s (Loose, Default, Tight)");
107+
O2_DEFINE_CONFIGURABLE(dcaV0DaughtersMaxLambda, std::vector<float>,
108+
(std::vector<float>{0.7f, 0.8f, 0.9f}),
109+
"Maximum DCA among the V0 daughters (cm) for lambda (Loose, Default, Tight)");
110+
O2_DEFINE_CONFIGURABLE(dcaV0DaughtersMaxK0s, std::vector<float>,
111+
(std::vector<float>{0.7f, 0.8f, 0.9f}),
112+
"Maximum DCA among the V0 daughters (cm) for K0s (Loose, Default, Tight)");
113+
O2_DEFINE_CONFIGURABLE(qtArmenterosMinForK0s, std::vector<float>,
114+
(std::vector<float>{0.2f, 0.2f, 0.2f}),
115+
"Minimum Armenteros' qt for K0s (Loose, Default, Tight)");
116+
O2_DEFINE_CONFIGURABLE(maxLambdaLifeTime, std::vector<float>,
117+
(std::vector<float>{40.f, 30.f, 25.f}),
118+
"Maximum lambda lifetime (in cm) (Loose, Default, Tight)");
119+
O2_DEFINE_CONFIGURABLE(maxK0sLifeTime, std::vector<float>,
120+
(std::vector<float>{40.f, 30.f, 25.f}),
121+
"Maximum K0s lifetime (in cm) (Loose, Default, Tight)");
122+
83123
} grpV0;
84124

85125
struct : ConfigurableGroup {
@@ -313,74 +353,78 @@ struct Filter2Prong {
313353
}
314354

315355
template <typename Collision, typename V0Cand>
316-
bool isSelectedV0AsK0s(Collision const& collision, const V0Cand& v0)
356+
bool isSelectedV0AsK0s(Collision const& collision, const V0Cand& v0, bool isLoose, bool isTight)
317357
{
318358
const auto& posTrack = v0.template posTrack_as<PIDTrack>();
319359
const auto& negTrack = v0.template negTrack_as<PIDTrack>();
320360

361+
const int indexCut = isLoose ? 0 : (isTight ? 2 : 1);
362+
321363
float CtauK0s = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0;
322364

323-
if (v0.mK0Short() < grpV0.massK0Min || v0.mK0Short() > grpV0.massK0Max) {
365+
if (v0.mK0Short() < grpV0.massK0Min.value[indexCut] || v0.mK0Short() > grpV0.massK0Max.value[indexCut]) {
324366
return false;
325367
}
326-
if ((v0.qtarm() / std::abs(v0.alpha())) < grpV0.qtArmenterosMinForK0s) {
368+
if ((v0.qtarm() / std::abs(v0.alpha())) < grpV0.qtArmenterosMinForK0s.value[indexCut]) {
327369
return false;
328370
}
329-
if (v0.v0radius() > grpV0.radiusMaxK0s || v0.v0radius() < grpV0.radiusMinK0s) {
371+
if (v0.v0radius() > grpV0.radiusMaxK0s.value[indexCut] || v0.v0radius() < grpV0.radiusMinK0s.value[indexCut]) {
330372
return false;
331373
}
332-
if (v0.v0cosPA() < grpV0.cosPaMinK0s) {
374+
if (v0.v0cosPA() < grpV0.cosPaMinK0s.value[indexCut]) {
333375
return false;
334376
}
335-
if (v0.dcaV0daughters() > grpV0.dcaV0DaughtersMaxK0s) {
377+
if (v0.dcaV0daughters() > grpV0.dcaV0DaughtersMaxK0s.value[indexCut]) {
336378
return false;
337379
}
338-
if (std::abs(CtauK0s) > grpV0.maxK0sLifeTime) {
380+
if (std::abs(CtauK0s) > grpV0.maxK0sLifeTime.value[indexCut]) {
339381
return false;
340382
}
341-
if (((std::abs(posTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts))) {
383+
if (((std::abs(posTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts.value[indexCut]) || (std::abs(negTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts.value[indexCut]))) {
342384
return false;
343385
}
344-
if ((TMath::Abs(v0.dcapostopv()) < grpV0.minV0DCAPiK0s || TMath::Abs(v0.dcanegtopv()) < grpV0.minV0DCAPiK0s)) {
386+
if ((TMath::Abs(v0.dcapostopv()) < grpV0.minV0DCAPiK0s.value[indexCut]) || (TMath::Abs(v0.dcanegtopv()) < grpV0.minV0DCAPiK0s.value[indexCut])) {
345387
return false;
346388
}
347389
return true;
348390
}
349391

350392
template <LambdaPid pid, typename Collision, typename V0Cand>
351-
bool isSelectedV0AsLambda(Collision const& collision, const V0Cand& v0)
393+
bool isSelectedV0AsLambda(Collision const& collision, const V0Cand& v0, bool isLoose, bool isTight)
352394
{
353395
const auto& posTrack = v0.template posTrack_as<PIDTrack>();
354396
const auto& negTrack = v0.template negTrack_as<PIDTrack>();
355397

398+
const int indexCut = isLoose ? 0 : (isTight ? 2 : 1);
399+
356400
float CtauLambda = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda;
357401

358-
if ((v0.mLambda() < grpV0.massLambdaMin || v0.mLambda() > grpV0.massLambdaMax) &&
359-
(v0.mAntiLambda() < grpV0.massLambdaMin || v0.mAntiLambda() > grpV0.massLambdaMax)) {
402+
if ((v0.mLambda() < grpV0.massLambdaMin.value[indexCut] || v0.mLambda() > grpV0.massLambdaMax.value[indexCut]) &&
403+
(v0.mAntiLambda() < grpV0.massLambdaMin.value[indexCut] || v0.mAntiLambda() > grpV0.massLambdaMax.value[indexCut])) {
360404
return false;
361405
}
362-
if (v0.v0radius() > grpV0.radiusMaxLambda || v0.v0radius() < grpV0.radiusMinLambda) {
406+
if (v0.v0radius() > grpV0.radiusMaxLambda.value[indexCut] || v0.v0radius() < grpV0.radiusMinLambda.value[indexCut]) {
363407
return false;
364408
}
365-
if (v0.v0cosPA() < grpV0.cosPaMinLambda) {
409+
if (v0.v0cosPA() < grpV0.cosPaMinLambda.value[indexCut]) {
366410
return false;
367411
}
368-
if (v0.dcaV0daughters() > grpV0.dcaV0DaughtersMaxLambda) {
412+
if (v0.dcaV0daughters() > grpV0.dcaV0DaughtersMaxLambda.value[indexCut]) {
369413
return false;
370414
}
371-
if (pid == LambdaPid::kLambda && (TMath::Abs(v0.dcapostopv()) < grpV0.minV0DCAPr || TMath::Abs(v0.dcanegtopv()) < grpV0.minV0DCAPiLambda)) {
415+
if (pid == LambdaPid::kLambda && (TMath::Abs(v0.dcapostopv()) < grpV0.minV0DCAPr.value[indexCut] || TMath::Abs(v0.dcanegtopv()) < grpV0.minV0DCAPiLambda.value[indexCut])) {
372416
return false;
373417
}
374-
if (pid == LambdaPid::kAntiLambda && (TMath::Abs(v0.dcapostopv()) < grpV0.minV0DCAPiLambda || TMath::Abs(v0.dcanegtopv()) < grpV0.minV0DCAPr)) {
418+
if (pid == LambdaPid::kAntiLambda && (TMath::Abs(v0.dcapostopv()) < grpV0.minV0DCAPiLambda.value[indexCut] || TMath::Abs(v0.dcanegtopv()) < grpV0.minV0DCAPr.value[indexCut])) {
375419
return false;
376420
}
377-
if (pid == LambdaPid::kLambda && ((std::abs(posTrack.tpcNSigmaPr()) > grpV0.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts))) {
421+
if (pid == LambdaPid::kLambda && ((std::abs(posTrack.tpcNSigmaPr()) > grpV0.daughPIDCuts.value[indexCut]) || (std::abs(negTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts.value[indexCut]))) {
378422
return false;
379423
}
380-
if (pid == LambdaPid::kAntiLambda && ((std::abs(posTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPr()) > grpV0.daughPIDCuts))) {
424+
if (pid == LambdaPid::kAntiLambda && ((std::abs(posTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts.value[indexCut]) || (std::abs(negTrack.tpcNSigmaPr()) > grpV0.daughPIDCuts.value[indexCut]))) {
381425
return false;
382426
}
383-
if (std::abs(CtauLambda) > grpV0.maxLambdaLifeTime) {
427+
if (std::abs(CtauLambda) > grpV0.maxLambdaLifeTime.value[indexCut]) {
384428
return false;
385429
}
386430
return true;
@@ -564,15 +608,28 @@ struct Filter2Prong {
564608
double massV0 = 0.0;
565609

566610
// K0s
567-
if (isSelectedV0AsK0s(collision, v0)) { // candidate is K0s
611+
if (isSelectedV0AsK0s(collision, v0, false, false)) { // candidate is K0s
568612
output2ProngTracks(cfcollisions.begin().globalIndex(),
569613
posTrack.globalIndex(), negTrack.globalIndex(),
570614
v0.pt(), v0.eta(), v0.phi(), v0.mK0Short(), aod::cf2prongtrack::K0stoPiPi);
571615
}
616+
if (grpV0.storeLooseTight) // store also loose and tight K0s
617+
{
618+
if (isSelectedV0AsK0s(collision, v0, true, false)) { // candidate is loose K0s
619+
output2ProngTracks(cfcollisions.begin().globalIndex(),
620+
posTrack.globalIndex(), negTrack.globalIndex(),
621+
v0.pt(), v0.eta(), v0.phi(), v0.mK0Short(), aod::cf2prongtrack::K0stoPiPiLoose);
622+
}
623+
if (isSelectedV0AsK0s(collision, v0, false, true)) { // candidate is tight K0s
624+
output2ProngTracks(cfcollisions.begin().globalIndex(),
625+
posTrack.globalIndex(), negTrack.globalIndex(),
626+
v0.pt(), v0.eta(), v0.phi(), v0.mK0Short(), aod::cf2prongtrack::K0stoPiPiTight);
627+
}
628+
}
572629

573630
// Lambda and Anti-Lambda
574-
bool LambdaTag = isSelectedV0AsLambda<LambdaPid::kLambda>(collision, v0);
575-
bool aLambdaTag = isSelectedV0AsLambda<LambdaPid::kAntiLambda>(collision, v0);
631+
bool LambdaTag = isSelectedV0AsLambda<LambdaPid::kLambda>(collision, v0, false, false);
632+
bool aLambdaTag = isSelectedV0AsLambda<LambdaPid::kAntiLambda>(collision, v0, false, false);
576633

577634
// Note: candidate compatible with Lambda and Anti-Lambda hypothesis are counted twice (once for each hypothesis)
578635
if (LambdaTag) { // candidate is Lambda
@@ -584,6 +641,33 @@ struct Filter2Prong {
584641
massV0 = v0.mAntiLambda();
585642
output2ProngTracks(cfcollisions.begin().globalIndex(), posTrack.globalIndex(), negTrack.globalIndex(),
586643
v0.pt(), v0.eta(), v0.phi(), massV0, aod::cf2prongtrack::AntiLambdatoPiP);
644+
}
645+
if (grpV0.storeLooseTight) { // store also loose and tight Lambdas
646+
bool LambdaLooseTag = isSelectedV0AsLambda<LambdaPid::kLambda>(collision, v0, true, false);
647+
bool aLambdaLooseTag = isSelectedV0AsLambda<LambdaPid::kAntiLambda>(collision, v0, true, false);
648+
bool LambdaTightTag = isSelectedV0AsLambda<LambdaPid::kLambda>(collision, v0, false, true);
649+
bool aLambdaTightTag = isSelectedV0AsLambda<LambdaPid::kAntiLambda>(collision, v0, false, true);
650+
651+
if (LambdaLooseTag) { // candidate is loose Lambda
652+
massV0 = v0.mLambda();
653+
output2ProngTracks(cfcollisions.begin().globalIndex(), posTrack.globalIndex(), negTrack.globalIndex(),
654+
v0.pt(), v0.eta(), v0.phi(), massV0, aod::cf2prongtrack::LambdaToPPiLoose);
655+
}
656+
if (LambdaTightTag) { // candidate is tight Lambda
657+
massV0 = v0.mLambda();
658+
output2ProngTracks(cfcollisions.begin().globalIndex(), posTrack.globalIndex(), negTrack.globalIndex(),
659+
v0.pt(), v0.eta(), v0.phi(), massV0, aod::cf2prongtrack::LambdaToPPiTight);
660+
}
661+
if (aLambdaLooseTag) { // candidate is loose Anti-lambda
662+
massV0 = v0.mAntiLambda();
663+
output2ProngTracks(cfcollisions.begin().globalIndex(), posTrack.globalIndex(), negTrack.globalIndex(),
664+
v0.pt(), v0.eta(), v0.phi(), massV0, aod::cf2prongtrack::AntiLambdaToPiPLoose);
665+
}
666+
if (aLambdaTightTag) { // candidate is tight Anti-lambda
667+
massV0 = v0.mAntiLambda();
668+
output2ProngTracks(cfcollisions.begin().globalIndex(), posTrack.globalIndex(), negTrack.globalIndex(),
669+
v0.pt(), v0.eta(), v0.phi(), massV0, aod::cf2prongtrack::AntiLambdaToPiPTight);
670+
}
587671
} // end of Lambda and Anti-Lambda processing
588672
} // end of loop over V0 candidates
589673

@@ -675,15 +759,15 @@ struct Filter2Prong {
675759
double massV0 = 0.0;
676760

677761
// K0s
678-
if (isSelectedV0AsK0s(collision, v0)) { // candidate is K0s
762+
if (isSelectedV0AsK0s(collision, v0, false, false)) { // candidate is K0s
679763
output2ProngTracks(cfcollisions.begin().globalIndex(),
680764
posTrack.globalIndex(), negTrack.globalIndex(),
681765
v0.pt(), v0.eta(), v0.phi(), v0.mK0Short(), aod::cf2prongtrack::K0stoPiPi);
682766
}
683767

684768
// Lambda and Anti-Lambda
685-
bool LambdaTag = isSelectedV0AsLambda<LambdaPid::kLambda>(collision, v0);
686-
bool aLambdaTag = isSelectedV0AsLambda<LambdaPid::kAntiLambda>(collision, v0);
769+
bool LambdaTag = isSelectedV0AsLambda<LambdaPid::kLambda>(collision, v0, false, false);
770+
bool aLambdaTag = isSelectedV0AsLambda<LambdaPid::kAntiLambda>(collision, v0, false, false);
687771

688772
// Note: candidate compatible with Lambda and Anti-Lambda hypothesis are counted twice (once for each hypothesis)
689773
if (LambdaTag) { // candidate is Lambda

0 commit comments

Comments
 (0)