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