@@ -437,6 +437,108 @@ struct Filter2Prong {
437437 }
438438 PROCESS_SWITCH (Filter2Prong, processDataInvMass, " Process data generic 2-prong candidates with invariant mass method" , false );
439439
440+ // Phi and V0s invariant mass method candidate finder. Only works for non-identical daughters of opposite charge for now.
441+ void processDataPhiV0 (aod::Collisions::iterator const & collision, aod::BCsWithTimestamps const &, aod::CFCollRefs const & cfcollisions, aod::CFTrackRefs const & cftracks, Filter2Prong::PIDTrack const & tracks, aod::V0Datas const & V0s)
442+ {
443+ if (cfcollisions.size () <= 0 )
444+ return ; // rejected collision
445+
446+ // V0
447+ for (const auto & v0 : V0s) { // Loop over V0 candidates
448+ if (!isV0TrackSelected (v0)) { // Quality selection for V0 prongs
449+ continue ;
450+ }
451+
452+ const auto & posTrack = v0.template posTrack_as <PIDTrack>();
453+ const auto & negTrack = v0.template negTrack_as <PIDTrack>();
454+ double massV0 = 0.0 ;
455+
456+ // K0s
457+ if (isSelectedV0AsK0s (collision, v0)) { // candidate is K0s
458+ output2ProngTracks (cfcollisions.begin ().globalIndex (),
459+ posTrack.globalIndex (), negTrack.globalIndex (),
460+ v0.pt (), v0.eta (), v0.phi (), v0.mK0Short (), aod::cf2prongtrack::K0stoPiPi);
461+ }
462+
463+ // Lambda and Anti-Lambda
464+ bool LambdaTag = isSelectedV0AsLambda<LambdaPid::kLambda >(collision, v0);
465+ bool aLambdaTag = isSelectedV0AsLambda<LambdaPid::kAntiLambda >(collision, v0);
466+
467+ // Note: candidate compatible with Lambda and Anti-Lambda hypothesis are counted twice (once for each hypothesis)
468+ if (LambdaTag) { // candidate is Lambda
469+ massV0 = v0.mLambda ();
470+ output2ProngTracks (cfcollisions.begin ().globalIndex (), posTrack.globalIndex (), negTrack.globalIndex (),
471+ v0.pt (), v0.eta (), v0.phi (), massV0, aod::cf2prongtrack::LambdatoPPi);
472+ }
473+ if (aLambdaTag) { // candidate is Anti-lambda
474+ massV0 = v0.mAntiLambda ();
475+ output2ProngTracks (cfcollisions.begin ().globalIndex (), posTrack.globalIndex (), negTrack.globalIndex (),
476+ v0.pt (), v0.eta (), v0.phi (), massV0, aod::cf2prongtrack::AntiLambdatoPiP);
477+ } // end of Lambda and Anti-Lambda processing
478+ } // end of loop over V0 candidates
479+
480+ // Phi
481+ if (cftracks.size () <= 0 )
482+ return ; // rejected collision
483+
484+ o2::aod::ITSResponse itsResponse;
485+
486+ for (const auto & cftrack1 : cftracks) { // Loop over first track
487+ const auto & p1 = tracks.iteratorAt (cftrack1.trackId () - tracks.begin ().globalIndex ());
488+ if (p1.sign () != 1 ) {
489+ continue ;
490+ }
491+ if (!selectionTrack (p1)) {
492+ continue ;
493+ }
494+ if (grpPhi.ITSPIDSelection && p1.p () < grpPhi.ITSPIDPthreshold .value && !(itsResponse.nSigmaITS <o2::track::PID::Kaon>(p1) > grpPhi.lowITSPIDNsigma .value && itsResponse.nSigmaITS <o2::track::PID::Kaon>(p1) < grpPhi.highITSPIDNsigma .value )) { // Check ITS PID condition
495+ continue ;
496+ }
497+ if (!selectionPID (p1)) {
498+ continue ;
499+ }
500+ if (grpPhi.removefaketrack && isFakeTrack (p1)) { // Check if the track is a fake kaon
501+ continue ;
502+ }
503+
504+ for (const auto & cftrack2 : cftracks) { // Loop over second track
505+ if (cftrack2.globalIndex () == cftrack1.globalIndex ()) // Skip if it's the same track as the first one
506+ continue ;
507+
508+ const auto & p2 = tracks.iteratorAt (cftrack2.trackId () - tracks.begin ().globalIndex ());
509+ if (p2.sign () != -1 ) {
510+ continue ;
511+ }
512+ if (!selectionTrack (p2)) {
513+ continue ;
514+ }
515+ if (!selectionPID (p2)) {
516+ continue ;
517+ }
518+ if (grpPhi.ITSPIDSelection && p2.p () < grpPhi.ITSPIDPthreshold .value && !(itsResponse.nSigmaITS <o2::track::PID::Kaon>(p2) > grpPhi.lowITSPIDNsigma .value && itsResponse.nSigmaITS <o2::track::PID::Kaon>(p2) < grpPhi.highITSPIDNsigma .value )) { // Check ITS PID condition
519+ continue ;
520+ }
521+ if (grpPhi.removefaketrack && isFakeTrack (p2)) { // Check if the track is a fake kaon
522+ continue ;
523+ }
524+ if (!selectionPair (p1, p2)) {
525+ continue ;
526+ }
527+
528+ ROOT::Math::PtEtaPhiMVector vec1 (p1.pt (), p1.eta (), p1.phi (), cfgImPart1Mass);
529+ ROOT::Math::PtEtaPhiMVector vec2 (p2.pt (), p2.eta (), p2.phi (), cfgImPart2Mass);
530+ ROOT::Math::PtEtaPhiMVector s = vec1 + vec2;
531+ if (s.M () < grpPhi.ImMinInvMassPhiMeson || s.M () > grpPhi.ImMaxInvMassPhiMeson ) {
532+ continue ;
533+ }
534+ float phi = RecoDecay::constrainAngle (s.Phi (), 0 .0f );
535+ output2ProngTracks (cfcollisions.begin ().globalIndex (),
536+ cftrack1.globalIndex (), cftrack2.globalIndex (), s.pt (), s.eta (), phi, s.M (), aod::cf2prongtrack::PhiToKK);
537+ } // end of loop over second track
538+ } // end of loop over first track
539+ }
540+ PROCESS_SWITCH (Filter2Prong, processDataPhiV0, " Process data Phi and V0 candidates with invariant mass method" , false );
541+
440542 // Phi and V0s invariant mass method candidate finder. Only works for non-identical daughters of opposite charge for now.
441543 void processDataV0 (aod::Collisions::iterator const & collision, aod::BCsWithTimestamps const &, aod::CFCollRefs const & cfcollisions, aod::CFTrackRefs const & cftracks, Filter2Prong::PIDTrack const &, aod::V0Datas const & V0s)
442544 {
0 commit comments