Skip to content

Commit 6640c87

Browse files
[PWGCF] Add systematic variations on topological sel for V0s in flow analyses
1 parent 85d2fe5 commit 6640c87

File tree

2 files changed

+101
-50
lines changed

2 files changed

+101
-50
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: 94 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -58,28 +58,29 @@ 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(tpcNClsCrossedRowsTrackMin, float, 70, "Minimum number of crossed rows in TPC");
62-
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)");
61+
O2_DEFINE_CONFIGURABLE(storeLooseTight, bool, false, "Store also loose and tight V0 candidates for systematics")
62+
O2_DEFINE_CONFIGURABLE(tpcNClsCrossedRowsTrackMin, std::vector<int>, {60, 70, 80}, "Minimum number of TPC crossed rows for daughter tracks (Loose, Default, Tight)");
63+
O2_DEFINE_CONFIGURABLE(etaTrackMax, std::vector<float>, {0.8, 0.8, 0.8}, "Maximum eta for daughter tracks (Loose, Default, Tight)");
64+
O2_DEFINE_CONFIGURABLE(ptTrackMin, std::vector<float>, {0.1, 0.1, 0.1}, "Minimum pT for daughter tracks (Loose, Default, Tight)");
65+
O2_DEFINE_CONFIGURABLE(minV0DCAPr, std::vector<float>, {0.06, 0.07, 0.0.08}, "Maximum DCAxy for daughter tracks (Loose, Default, Tight)");
66+
O2_DEFINE_CONFIGURABLE(minV0DCAPiLambda, std::vector<float>, {0.1, 0.2, 0.3}, "Min V0 pion DCA for lambda (Loose, Default, Tight)");
67+
O2_DEFINE_CONFIGURABLE(minV0DCAPiK0s, std::vector<float>, {0.05, 0.1, 0.2}, "Min V0 pion DCA for K0s (Loose, Default, Tight)");
68+
O2_DEFINE_CONFIGURABLE(daughPIDCuts, std::vector<float>, {3.0, 4.0, 5.0}, "PID nsigma for V0s (Loose, Default, Tight)");
69+
O2_DEFINE_CONFIGURABLE(massK0Min, std::vector<float>, {0.4, 0.4, 0.4}, "Minimum mass for K0 (Loose, Default, Tight)");
70+
O2_DEFINE_CONFIGURABLE(massK0Max, std::vector<float>, {0.6, 0.6, 0.6}, "Maximum mass for K0 (Loose, Default, Tight)");
71+
O2_DEFINE_CONFIGURABLE(massLambdaMin, std::vector<float>, {1.07, 1.07, 1.07}, "Minimum mass for lambda (Loose, Default, Tight)");
72+
O2_DEFINE_CONFIGURABLE(massLambdaMax, std::vector<float>, {1.17, 1.17, 1.17}, "Maximum mass for lambda (Loose, Default, Tight)");
73+
O2_DEFINE_CONFIGURABLE(radiusMaxLambda, std::vector<float>, {20, 30, 40}, "Maximum decay radius (cm) for lambda (Loose, Default, Tight)");
74+
O2_DEFINE_CONFIGURABLE(radiusMinLambda, std::vector<float>, {1.0, 1.2, 1.4}, "Minimum decay radius (cm) for lambda (Loose, Default, Tight)");
75+
O2_DEFINE_CONFIGURABLE(radiusMaxK0s, std::vector<float>, {1.0, 1.2, 1.4}, "Maximum decay radius (cm) for K0s (Loose, Default, Tight)");
76+
O2_DEFINE_CONFIGURABLE(radiusMinK0s, std::vector<float>, {0.0, 0.0, 0.1}, "Minimum decay radius (cm) for K0s (Loose, Default, Tight)");
77+
O2_DEFINE_CONFIGURABLE(cosPaMinLambda, std::vector<float>, {0.990, 0.993, 0.995}, "Minimum cosine of pointing angle for lambda (Loose, Default, Tight)");
78+
O2_DEFINE_CONFIGURABLE(cosPaMinK0s, std::vector<float>, {0.990, 0.993, 0.995}, "Minimum cosine of pointing angle for K0s (Loose, Default, Tight)");
79+
O2_DEFINE_CONFIGURABLE(dcaV0DaughtersMaxLambda, std::vector<float>, {0.7, 0.8, 0.9}, "Maximum DCA among the V0 daughters (cm) for lambda (Loose, Default, Tight)");
80+
O2_DEFINE_CONFIGURABLE(dcaV0DaughtersMaxK0s, std::vector<float>, {0.7, 0.8, 0.9}, "Maximum DCA among the V0 daughters (cm) for K0s (Loose, Default, Tight)");
81+
O2_DEFINE_CONFIGURABLE(qtArmenterosMinForK0s, std::vector<float>, {0.2, 0.2, 0.2}, "Minimum Armenteros' qt for K0s (Loose, Default, Tight)");
82+
O2_DEFINE_CONFIGURABLE(maxLambdaLifeTime, std::vector<float>, {40, 30, 25}, "Maximum lambda lifetime (in cm) (Loose, Default, Tight)");
83+
O2_DEFINE_CONFIGURABLE(maxK0sLifeTime, std::vector<float>, {40, 30, 25}, "Maximum K0s lifetime (in cm) (Loose, Default, Tight)");
8384
} grpV0;
8485

8586
struct : ConfigurableGroup {
@@ -313,74 +314,78 @@ struct Filter2Prong {
313314
}
314315

315316
template <typename Collision, typename V0Cand>
316-
bool isSelectedV0AsK0s(Collision const& collision, const V0Cand& v0)
317+
bool isSelectedV0AsK0s(Collision const& collision, const V0Cand& v0, bool isLoose, bool isTight)
317318
{
318319
const auto& posTrack = v0.template posTrack_as<PIDTrack>();
319320
const auto& negTrack = v0.template negTrack_as<PIDTrack>();
320321

322+
const int indexCut = isLoose ? 0 : (isTight ? 2 : 1);
323+
321324
float CtauK0s = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0;
322325

323-
if (v0.mK0Short() < grpV0.massK0Min || v0.mK0Short() > grpV0.massK0Max) {
326+
if (v0.mK0Short() < massK0min[indexCut] || v0.mK0Short() > massK0max[indexCut]) {
324327
return false;
325328
}
326-
if ((v0.qtarm() / std::abs(v0.alpha())) < grpV0.qtArmenterosMinForK0s) {
329+
if ((v0.qtarm() / std::abs(v0.alpha())) < qtArmenterosMinForK0s[indexCut]) {
327330
return false;
328331
}
329-
if (v0.v0radius() > grpV0.radiusMaxK0s || v0.v0radius() < grpV0.radiusMinK0s) {
332+
if (v0.v0radius() > radiusMaxK0s[indexCut] || v0.v0radius() < radiusMinK0s[indexCut]) {
330333
return false;
331334
}
332-
if (v0.v0cosPA() < grpV0.cosPaMinK0s) {
335+
if (v0.v0cosPA() < cosPaMinK0s[indexCut]) {
333336
return false;
334337
}
335-
if (v0.dcaV0daughters() > grpV0.dcaV0DaughtersMaxK0s) {
338+
if (v0.dcaV0daughters() > dcaV0DaughtersMaxK0s[indexCut]) {
336339
return false;
337340
}
338-
if (std::abs(CtauK0s) > grpV0.maxK0sLifeTime) {
341+
if (std::abs(CtauK0s) > maxK0sLifeTime[indexCut]) {
339342
return false;
340343
}
341-
if (((std::abs(posTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts))) {
344+
if (((std::abs(posTrack.tpcNSigmaPi()) > dughPIDCuts[indexCut]) || (std::abs(negTrack.tpcNSigmaPi()) > dughPIDCuts[indexCut]))) {
342345
return false;
343346
}
344-
if ((TMath::Abs(v0.dcapostopv()) < grpV0.minV0DCAPiK0s || TMath::Abs(v0.dcanegtopv()) < grpV0.minV0DCAPiK0s)) {
347+
if ((TMath::Abs(v0.dcapostopv()) < minV0DCAPiK0s[indexCut]) || (TMath::Abs(v0.dcanegtopv()) < minV0DCAPiK0s[indexCut])) {
345348
return false;
346349
}
347350
return true;
348351
}
349352

350353
template <LambdaPid pid, typename Collision, typename V0Cand>
351-
bool isSelectedV0AsLambda(Collision const& collision, const V0Cand& v0)
354+
bool isSelectedV0AsLambda(Collision const& collision, const V0Cand& v0, bool isLoose, bool isTight)
352355
{
353356
const auto& posTrack = v0.template posTrack_as<PIDTrack>();
354357
const auto& negTrack = v0.template negTrack_as<PIDTrack>();
355358

359+
const int indexCut = isLoose ? 0 : (isTight ? 2 : 1);
360+
356361
float CtauLambda = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda;
357362

358-
if ((v0.mLambda() < grpV0.massLambdaMin || v0.mLambda() > grpV0.massLambdaMax) &&
359-
(v0.mAntiLambda() < grpV0.massLambdaMin || v0.mAntiLambda() > grpV0.massLambdaMax)) {
363+
if ((v0.mLambda() < massLambdaMin[indexCut] || v0.mLambda() > massLambdaMax[indexCut]) &&
364+
(v0.mAntiLambda() < massLambdaMin[indexCut] || v0.mAntiLambda() > massLambdaMax[indexCut])) {
360365
return false;
361366
}
362-
if (v0.v0radius() > grpV0.radiusMaxLambda || v0.v0radius() < grpV0.radiusMinLambda) {
367+
if (v0.v0radius() > radiusMaxLambda[indexCut] || v0.v0radius() < radiusMinLambda[indexCut]) {
363368
return false;
364369
}
365-
if (v0.v0cosPA() < grpV0.cosPaMinLambda) {
370+
if (v0.v0cosPA() < cosPaMinLambda[indexCut]) {
366371
return false;
367372
}
368-
if (v0.dcaV0daughters() > grpV0.dcaV0DaughtersMaxLambda) {
373+
if (v0.dcaV0daughters() > dcaV0DaughtersMaxLambda[indexCut]) {
369374
return false;
370375
}
371-
if (pid == LambdaPid::kLambda && (TMath::Abs(v0.dcapostopv()) < grpV0.minV0DCAPr || TMath::Abs(v0.dcanegtopv()) < grpV0.minV0DCAPiLambda)) {
376+
if (pid == LambdaPid::kLambda && (TMath::Abs(v0.dcapostopv()) < minV0DCAPr[indexCut] || TMath::Abs(v0.dcanegtopv()) < minV0DCAPiLambda[indexCut])) {
372377
return false;
373378
}
374-
if (pid == LambdaPid::kAntiLambda && (TMath::Abs(v0.dcapostopv()) < grpV0.minV0DCAPiLambda || TMath::Abs(v0.dcanegtopv()) < grpV0.minV0DCAPr)) {
379+
if (pid == LambdaPid::kAntiLambda && (TMath::Abs(v0.dcapostopv()) < minV0DCAPiLambda[indexCut] || TMath::Abs(v0.dcanegtopv()) < minV0DCAPr[indexCut])) {
375380
return false;
376381
}
377-
if (pid == LambdaPid::kLambda && ((std::abs(posTrack.tpcNSigmaPr()) > grpV0.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts))) {
382+
if (pid == LambdaPid::kLambda && ((std::abs(posTrack.tpcNSigmaPr()) > daughPIDCuts[indexCut]) || (std::abs(negTrack.tpcNSigmaPi()) > daughPIDCuts[indexCut]))) {
378383
return false;
379384
}
380-
if (pid == LambdaPid::kAntiLambda && ((std::abs(posTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPr()) > grpV0.daughPIDCuts))) {
385+
if (pid == LambdaPid::kAntiLambda && ((std::abs(posTrack.tpcNSigmaPi()) > daughPIDCuts[indexCut]) || (std::abs(negTrack.tpcNSigmaPr()) > daughPIDCuts[indexCut]))) {
381386
return false;
382387
}
383-
if (std::abs(CtauLambda) > grpV0.maxLambdaLifeTime) {
388+
if (std::abs(CtauLambda) > maxLambdaLifeTime[indexCut]) {
384389
return false;
385390
}
386391
return true;
@@ -395,16 +400,16 @@ struct Filter2Prong {
395400
if (!posTrack.hasTPC() || !negTrack.hasTPC()) {
396401
return false;
397402
}
398-
if (posTrack.tpcNClsCrossedRows() < grpV0.tpcNClsCrossedRowsTrackMin || negTrack.tpcNClsCrossedRows() < grpV0.tpcNClsCrossedRowsTrackMin) {
403+
if (posTrack.tpcNClsCrossedRows() < grpV0.tpcNClsCrossedRowsTrackMin[indexCut] || negTrack.tpcNClsCrossedRows() < grpV0.tpcNClsCrossedRowsTrackMin[indexCut]) {
399404
return false;
400405
}
401406
if (posTrack.tpcCrossedRowsOverFindableCls() < 0.8 || negTrack.tpcCrossedRowsOverFindableCls() < 0.8) {
402407
return false;
403408
}
404-
if (std::abs(v0.positiveeta()) > grpV0.etaTrackMax || std::abs(v0.negativeeta()) > grpV0.etaTrackMax) {
409+
if (std::abs(v0.positiveeta()) > grpV0.etaTrackMax[indexCut] || std::abs(v0.negativeeta()) > grpV0.etaTrackMax[indexCut]) {
405410
return false;
406411
}
407-
if (v0.positivept() < grpV0.ptTrackMin || v0.negativept() < grpV0.ptTrackMin) {
412+
if (v0.positivept() < grpV0.ptTrackMin[indexCut] || v0.negativept() < grpV0.ptTrackMin[indexCut]) {
408413
return false;
409414
}
410415
return true;
@@ -564,15 +569,28 @@ struct Filter2Prong {
564569
double massV0 = 0.0;
565570

566571
// K0s
567-
if (isSelectedV0AsK0s(collision, v0)) { // candidate is K0s
572+
if (isSelectedV0AsK0s(collision, v0, false, false)) { // candidate is K0s
568573
output2ProngTracks(cfcollisions.begin().globalIndex(),
569574
posTrack.globalIndex(), negTrack.globalIndex(),
570575
v0.pt(), v0.eta(), v0.phi(), v0.mK0Short(), aod::cf2prongtrack::K0stoPiPi);
571576
}
577+
if (storeLooseTight) // store also loose and tight K0s
578+
{
579+
if (isSelectedV0AsK0s(collision, v0, true, false)) { // candidate is loose K0s
580+
output2ProngTracks(cfcollisions.begin().globalIndex(),
581+
posTrack.globalIndex(), negTrack.globalIndex(),
582+
v0.pt(), v0.eta(), v0.phi(), v0.mK0Short(), aod::cf2prongtrack::K0stoPiPiLoose);
583+
}
584+
if (isSelectedV0AsK0s(collision, v0, false, true)) { // candidate is tight K0s
585+
output2ProngTracks(cfcollisions.begin().globalIndex(),
586+
posTrack.globalIndex(), negTrack.globalIndex(),
587+
v0.pt(), v0.eta(), v0.phi(), v0.mK0Short(), aod::cf2prongtrack::K0stoPiPiTight);
588+
}
589+
}
572590

573591
// Lambda and Anti-Lambda
574-
bool LambdaTag = isSelectedV0AsLambda<LambdaPid::kLambda>(collision, v0);
575-
bool aLambdaTag = isSelectedV0AsLambda<LambdaPid::kAntiLambda>(collision, v0);
592+
bool LambdaTag = isSelectedV0AsLambda<LambdaPid::kLambda>(collision, v0, false, false);
593+
bool aLambdaTag = isSelectedV0AsLambda<LambdaPid::kAntiLambda>(collision, v0, false, false);
576594

577595
// Note: candidate compatible with Lambda and Anti-Lambda hypothesis are counted twice (once for each hypothesis)
578596
if (LambdaTag) { // candidate is Lambda
@@ -584,7 +602,34 @@ struct Filter2Prong {
584602
massV0 = v0.mAntiLambda();
585603
output2ProngTracks(cfcollisions.begin().globalIndex(), posTrack.globalIndex(), negTrack.globalIndex(),
586604
v0.pt(), v0.eta(), v0.phi(), massV0, aod::cf2prongtrack::AntiLambdatoPiP);
587-
} // end of Lambda and Anti-Lambda processing
605+
}
606+
if (storeLooseTight) { // store also loose and tight Lambdas
607+
bool LambdaLooseTag = isSelectedV0AsLambda<LambdaPid::kLambda>(collision, v0, true, false);
608+
bool aLambdaLooseTag = isSelectedV0AsLambda<LambdaPid::kAntiLambda>(collision, v0, true, false);
609+
bool LambdaTightTag = isSelectedV0AsLambda<LambdaPid::kLambda>(collision, v0, false, true);
610+
bool aLambdaTightTag = isSelectedV0AsLambda<LambdaPid::kAntiLambda>(collision, v0, false, true);
611+
612+
if (LambdaLooseTag) { // candidate is loose Lambda
613+
massV0 = v0.mLambda();
614+
output2ProngTracks(cfcollisions.begin().globalIndex(), posTrack.globalIndex(), negTrack.globalIndex(),
615+
v0.pt(), v0.eta(), v0.phi(), massV0, aod::cf2prongtrack::LambdaToPPiLoose);
616+
}
617+
if (LambdaTightTag) { // candidate is tight Lambda
618+
massV0 = v0.mLambda();
619+
output2ProngTracks(cfcollisions.begin().globalIndex(), posTrack.globalIndex(), negTrack.globalIndex(),
620+
v0.pt(), v0.eta(), v0.phi(), massV0, aod::cf2prongtrack::LambdaToPPiTight);
621+
}
622+
if (aLambdaLooseTag) { // candidate is loose Anti-lambda
623+
massV0 = v0.mAntiLambda();
624+
output2ProngTracks(cfcollisions.begin().globalIndex(), posTrack.globalIndex(), negTrack.globalIndex(),
625+
v0.pt(), v0.eta(), v0.phi(), massV0, aod::cf2prongtrack::AntiLambdaToPiPLoose);
626+
}
627+
if (aLambdaTightTag) { // candidate is tight Anti-lambda
628+
massV0 = v0.mAntiLambda();
629+
output2ProngTracks(cfcollisions.begin().globalIndex(), posTrack.globalIndex(), negTrack.globalIndex(),
630+
v0.pt(), v0.eta(), v0.phi(), massV0, aod::cf2prongtrack::AntiLambdaToPiPTight);
631+
}
632+
} // end of Lambda and Anti-Lambda processing
588633
} // end of loop over V0 candidates
589634

590635
// Phi

0 commit comments

Comments
 (0)