@@ -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