@@ -98,16 +98,9 @@ struct HfCorrelatorLcScHadronsSelection {
9898 Configurable<float > ptCandMin{" ptCandMin" , 1 ., " min. cand. pT" };
9999
100100 struct : ConfigurableGroup {
101- Configurable<float > cfgV0radiusMin{" cfgV0radiusMin" , 1.2 , " minimum decay radius" };
102- Configurable<float > cfgDCAPosToPVMin{" cfgDCAPosToPVMin" , 0.05 , " minimum DCA to PV for positive track" };
103- Configurable<float > cfgDCANegToPVMin{" cfgDCANegToPVMin" , 0.2 , " minimum DCA to PV for negative track" };
104- Configurable<float > cfgV0CosPA{" cfgV0CosPA" , 0.995 , " minimum v0 cosine" };
105- Configurable<float > cfgDCAV0Dau{" cfgDCAV0Dau" , 1.0 , " maximum DCA between daughters" };
106- Configurable<float > cfgV0PtMin{" cfgV0PtMin" , 0 , " minimum pT for lambda" };
107- Configurable<float > cfgV0LifeTime{" cfgV0LifeTime" , 30 ., " maximum lambda lifetime" };
108- Configurable<float > cfgPV{" cfgPV" , 10 ., " maximum z-vertex" };
109101 Configurable<int > cfgMaxOccupancy{" cfgMaxOccupancy" , 999999 , " maximum occupancy of tracks in neighbouring collisions in a given time range" };
110102 Configurable<int > cfgMinOccupancy{" cfgMinOccupancy" , 0 , " maximum occupancy of tracks in neighbouring collisions in a given time range" };
103+ Configurable<float > cfgPV{" cfgPV" , 10 ., " maximum z-vertex" };
111104 } cfgV0;
112105
113106 SliceCache cache;
@@ -188,37 +181,6 @@ struct HfCorrelatorLcScHadronsSelection {
188181 candSel (isCandFound);
189182 }
190183
191- template <typename TCollision, typename V0 >
192- bool selectionV0 (TCollision const & collision, V0 const & candidate)
193- {
194- if (candidate.v0radius () < cfgV0.cfgV0radiusMin ) {
195- return false ;
196- }
197- if (std::abs (candidate.dcapostopv ()) < cfgV0.cfgDCAPosToPVMin ) {
198- return false ;
199- }
200- if (std::abs (candidate.dcanegtopv ()) < cfgV0.cfgDCANegToPVMin ) {
201- return false ;
202- }
203- if (candidate.v0cosPA () < cfgV0.cfgV0CosPA ) {
204- return false ;
205- }
206- if (std::abs (candidate.dcaV0daughters ()) > cfgV0.cfgDCAV0Dau ) {
207- return false ;
208- }
209- if (candidate.pt () < cfgV0.cfgV0PtMin ) {
210- return false ;
211- }
212- if (std::abs (candidate.yLambda ()) > yCandMax) {
213- return false ;
214- }
215- if (candidate.distovertotmom (collision.posX (), collision.posY (), collision.posZ ()) * o2::constants::physics::MassLambda > cfgV0.cfgV0LifeTime ) {
216- return false ;
217- }
218-
219- return true ;
220- }
221-
222184 template <typename TCollision>
223185 bool eventSelV0 (TCollision collision)
224186 {
@@ -260,12 +222,7 @@ struct HfCorrelatorLcScHadronsSelection {
260222 candSel (isCandFound);
261223 return ;
262224 }
263- for (const auto & v0 : V0s) {
264- if (selectionV0 (collision, v0)) {
265- isCandFound = true ;
266- break ;
267- }
268- }
225+ isCandFound = true ;
269226 candSel (isCandFound);
270227 }
271228 PROCESS_SWITCH (HfCorrelatorLcScHadronsSelection, processV0Selection, " Process V0 Collision Selection for Data" , true );
@@ -376,17 +333,27 @@ struct HfCorrelatorLcScHadrons {
376333 } cfgCharmCand;
377334
378335 struct : ConfigurableGroup {
379- Configurable<float > cfgDaughPrPtMax{ " cfgDaughPrPtMax " , 5 ., " max. pT Daughter Proton" };
380- Configurable<float > cfgDaughPrPtMin{ " cfgDaughPrPtMin " , 0.3 , " min. pT Daughter Proton" };
381- Configurable<float > cfgDaughPiPtMax{ " cfgDaughPiPtMax " , 10 ., " max. pT Daughter Pion" };
382- Configurable<float > cfgDaughPiPtMin{ " cfgDaughPiPtMin " , 0.3 , " min. pT Daughter Pion" };
383- Configurable<float > cfgDaughPIDCutsTPCPr{ " cfgDaughPIDCutsTPCPr " , 2.5 , " max. TPCnSigma Proton" };
384- Configurable<float > cfgDaughPIDCutsTPCPi{ " cfgDaughPIDCutsTPCPi " , 2.5 , " max. TPCnSigma Pion" };
385- Configurable<float > cfgDaughPIDCutsTOFPi{ " cfgDaughPIDCutsTOFPi " , 2.5 , " max. TOFnSigma Pion" };
386- Configurable<float > cfgDaughPIDCutsTOFPr{ " cfgDaughPIDCutsTOFPr " , 2.5 , " max. TOFnSigma Pion" };
336+ Configurable<float > cfgV0DaughPrPtMax{ " cfgV0DaughPrPtMax " , 5 ., " max. pT Daughter Proton" };
337+ Configurable<float > cfgV0DaughPrPtMin{ " cfgV0DaughPrPtMin " , 0.3 , " min. pT Daughter Proton" };
338+ Configurable<float > cfgV0DaughPiPtMax{ " cfgV0DaughPiPtMax " , 10 ., " max. pT Daughter Pion" };
339+ Configurable<float > cfgV0DaughPiPtMin{ " cfgV0DaughPiPtMin " , 0.3 , " min. pT Daughter Pion" };
340+ Configurable<float > cfgV0DaughPIDCutsTPCPr{ " cfgV0DaughPIDCutsTPCPr " , 2.5 , " max. TPCnSigma Proton" };
341+ Configurable<float > cfgV0DaughPIDCutsTPCPi{ " cfgV0DaughPIDCutsTPCPi " , 2.5 , " max. TPCnSigma Pion" };
342+ Configurable<float > cfgV0DaughPIDCutsTOFPi{ " cfgV0DaughPIDCutsTOFPi " , 2.5 , " max. TOFnSigma Pion" };
343+ Configurable<float > cfgV0DaughPIDCutsTOFPr{ " cfgV0DaughPIDCutsTOFPr " , 2.5 , " max. TOFnSigma Pion" };
387344 Configurable<float > cfgHypMassWindow{" cfgHypMassWindow" , 0.1 , " single lambda mass selection" };
388345 Configurable<bool > cfgIsCorrCollMatchV0{" cfgIsCorrCollMatchV0" , true , " check if daughter and mother collision are same" };
389346 Configurable<bool > cfgCalDataDrivenEffPr{" cfgCalDataDrivenEffPr" , false , " calculate data driven efficiency of proton using Lambda" };
347+ Configurable<float > cfgV0radiusMin{" cfgV0radiusMin" , 1.2 , " minimum decay radius" };
348+ Configurable<float > cfgDCAPosToPVMin{" cfgDCAPosToPVMin" , 0.05 , " minimum DCA to PV for positive track" };
349+ Configurable<float > cfgDCANegToPVMin{" cfgDCANegToPVMin" , 0.2 , " minimum DCA to PV for negative track" };
350+ Configurable<float > cfgV0CosPA{" cfgV0CosPA" , 0.995 , " minimum v0 cosine" };
351+ Configurable<float > cfgDCAV0Dau{" cfgDCAV0Dau" , 1.0 , " maximum DCA between daughters" };
352+ Configurable<float > cfgV0PtMin{" cfgV0PtMin" , 0 , " minimum pT for lambda" };
353+ Configurable<float > cfgV0LifeTime{" cfgV0LifeTime" , 30 ., " maximum lambda lifetime" };
354+ Configurable<int > cfgMaxOccupancy{" cfgMaxOccupancy" , 999999 , " maximum occupancy of tracks in neighbouring collisions in a given time range" };
355+ Configurable<int > cfgMinOccupancy{" cfgMinOccupancy" , 0 , " maximum occupancy of tracks in neighbouring collisions in a given time range" };
356+ Configurable<float > cfgPV{" cfgPV" , 10 ., " maximum z-vertex" };
390357 Configurable<bool > calEffV0{" calEffV0" , false , " calculate lambda0 efficiency" };
391358 } cfgV0;
392359
@@ -551,6 +518,7 @@ struct HfCorrelatorLcScHadrons {
551518 registry.add (" hV0LambdaReflMcRec" , " McRec V0 Lambda reflected candidates;inv. mass (p #pi) (GeV/#it{c}^{2});GeV/#it{c};GeV/#it{c}" , {HistType::kTH3F , {{axisMassV0}, {axisPtV0}, {axisPtHadron}}});
552519 registry.add (" hV0LambdaPiKRejMcRec" , " McRec V0 Lambda candidates with #pi K rejection;inv. mass (p #pi) (GeV/#it{c}^{2});GeV/#it{c};GeV/#it{c}" , {HistType::kTH3F , {{axisMassV0}, {axisPtV0}, {axisPtHadron}}});
553520 registry.add (" hV0LambdaReflPiKRejMcRec" , " McRec V0 Lambda reflected candidates with #pi K rejection;inv. mass (p #pi) (GeV/#it{c}^{2});GeV/#it{c};GeV/#it{c}" , {HistType::kTH3F , {{axisMassV0}, {axisPtV0}, {axisPtHadron}}});
521+ registry.add (" hV0PtPrimLambdaMcGen" , " Mcgen V0 Lambda candidates;GeV/#it{c}" , {HistType::kTH1F , {{axisPtV0}}});
554522
555523 corrBinning = {{binsZVtx, binsMultiplicity}, true };
556524 }
@@ -582,6 +550,37 @@ struct HfCorrelatorLcScHadrons {
582550 return y;
583551 }
584552
553+ template <typename TCollision, typename V0 >
554+ bool selectionV0 (TCollision const & collision, V0 const & candidate)
555+ {
556+ if (candidate.v0radius () < cfgV0.cfgV0radiusMin ) {
557+ return false ;
558+ }
559+ if (std::abs (candidate.dcapostopv ()) < cfgV0.cfgDCAPosToPVMin ) {
560+ return false ;
561+ }
562+ if (std::abs (candidate.dcanegtopv ()) < cfgV0.cfgDCANegToPVMin ) {
563+ return false ;
564+ }
565+ if (candidate.v0cosPA () < cfgV0.cfgV0CosPA ) {
566+ return false ;
567+ }
568+ if (std::abs (candidate.dcaV0daughters ()) > cfgV0.cfgDCAV0Dau ) {
569+ return false ;
570+ }
571+ if (candidate.pt () < cfgV0.cfgV0PtMin ) {
572+ return false ;
573+ }
574+ if (std::abs (candidate.yLambda ()) > cfgCharmCand.yCandMax ) {
575+ return false ;
576+ }
577+ if (candidate.distovertotmom (collision.posX (), collision.posY (), collision.posZ ()) * o2::constants::physics::MassLambda > cfgV0.cfgV0LifeTime ) {
578+ return false ;
579+ }
580+
581+ return true ;
582+ }
583+
585584 template <typename Tracktype, typename V0Type>
586585 bool isSelectedV0Daughter (Tracktype const & track, V0Type v0, int pid)
587586 {
@@ -594,22 +593,22 @@ struct HfCorrelatorLcScHadrons {
594593 if (std::abs (pid) == kProton ) {
595594 bool passTOF = false ;
596595
597- if (track.pt () > cfgV0.cfgDaughPrPtMax || track.pt () < cfgV0.cfgDaughPrPtMin ) {
596+ if (track.pt () > cfgV0.cfgV0DaughPrPtMax || track.pt () < cfgV0.cfgV0DaughPrPtMin ) {
598597 return false ;
599598 }
600599 if (track.hasTOF ()) {
601600 if constexpr (std::experimental::is_detected<HasStrangeTOFinV0, V0Type>::value) {
602601 // pid > 0: Proton from Lambda (LaPr)
603602 // pid < 0: Antiproton from Anti-Lambda (ALaPr)
604603 double strangeTOF = (pid > 0 ) ? v0.tofNSigmaLaPr () : v0.tofNSigmaALaPr ();
605- passTOF = std::abs (strangeTOF) > cfgV0.cfgDaughPIDCutsTOFPr ;
604+ passTOF = std::abs (strangeTOF) > cfgV0.cfgV0DaughPIDCutsTOFPr ;
606605 } else {
607606 // if strange TOF is unavailable
608- passTOF = std::abs (track.tofNSigmaPr ()) > cfgV0.cfgDaughPIDCutsTOFPr ;
607+ passTOF = std::abs (track.tofNSigmaPr ()) > cfgV0.cfgV0DaughPIDCutsTOFPr ;
609608 }
610609 }
611610
612- if ((std::abs (track.tpcNSigmaPr ()) > cfgV0.cfgDaughPIDCutsTPCPr ) || passTOF) {
611+ if ((std::abs (track.tpcNSigmaPr ()) > cfgV0.cfgV0DaughPIDCutsTPCPr ) || passTOF) {
613612 return false ;
614613 }
615614 }
@@ -620,7 +619,7 @@ struct HfCorrelatorLcScHadrons {
620619 if (std::abs (pid) == kPiPlus ) {
621620 bool passTOF = false ;
622621
623- if (track.pt () > cfgV0.cfgDaughPiPtMax || track.pt () < cfgV0.cfgDaughPiPtMin ) {
622+ if (track.pt () > cfgV0.cfgV0DaughPiPtMax || track.pt () < cfgV0.cfgV0DaughPiPtMin ) {
624623 return false ;
625624 }
626625
@@ -630,14 +629,14 @@ struct HfCorrelatorLcScHadrons {
630629 // We evaluate both applicable hypotheses based on charge sign and pick the best match.
631630 double tofLa = (pid > 0 ) ? v0.tofNSigmaALaPi () : v0.tofNSigmaLaPi ();
632631
633- passTOF = tofLa > cfgV0.cfgDaughPIDCutsTOFPi ;
632+ passTOF = tofLa > cfgV0.cfgV0DaughPIDCutsTOFPi ;
634633 } else {
635634 // Fallback to standard track TOF
636- passTOF = std::abs (track.tofNSigmaPi ()) > cfgV0.cfgDaughPIDCutsTOFPi ;
635+ passTOF = std::abs (track.tofNSigmaPi ()) > cfgV0.cfgV0DaughPIDCutsTOFPi ;
637636 }
638637 }
639638
640- if ((std::abs (track.tpcNSigmaPi ()) > cfgV0.cfgDaughPIDCutsTPCPi ) || passTOF) {
639+ if ((std::abs (track.tpcNSigmaPi ()) > cfgV0.cfgV0DaughPIDCutsTPCPi ) || passTOF) {
641640 return false ;
642641 }
643642 }
@@ -811,10 +810,14 @@ struct HfCorrelatorLcScHadrons {
811810
812811 // Correlate Lc with all Lambda V0 in the same event
813812 for (const auto & v0 : v0s) {
814-
813+
815814 const int v0Lambda = 1 ;
816815 const int v0AntiLambda = -1 ;
817816
817+ if (!selectionV0 (collision, v0)){
818+ continue ;
819+ }
820+
818821 auto posTrackV0 = v0.template posTrack_as <TrackType>();
819822 auto negTrackV0 = v0.template negTrack_as <TrackType>();
820823
@@ -920,21 +923,25 @@ struct HfCorrelatorLcScHadrons {
920923 // ========================================
921924 // Efficiency calculation block
922925 // ========================================
923- template <bool IsMc, typename V0 , typename TrackType>
924- void fillEffV0 (V0 const & v0s,
926+ template <bool IsMc, typename CollType, typename V0 , typename TrackType, typename PartType>
927+ void fillEffV0 (CollType const & col,
928+ V0 const & v0s,
925929 TrackType const &,
926- aod::McParticles const & mcParticles)
930+ PartType const & mcParticles)
927931 {
932+ int countV0 = 1 ;
928933 // Data-driven efficiency calculation for protons using Lambda
929934 for (const auto & v0 : v0s) {
935+ bool passV0Sel = selectionV0 (col, v0);
936+
930937 auto const & trackV0Pos = v0.template posTrack_as <TrackType>();
931938 auto const & trackV0Neg = v0.template negTrack_as <TrackType>();
932939 if (cfgV0.cfgIsCorrCollMatchV0 && ((v0.collisionId () != trackV0Pos.collisionId ()) || (v0.collisionId () != trackV0Neg.collisionId ()))) {
933940 continue ;
934941 }
935942
936943 // Process Lambda (proton + pion)
937- if (std::abs (o2::constants::physics::MassLambda - v0.mLambda ()) < cfgV0.cfgHypMassWindow ) {
944+ if (passV0Sel && std::abs (o2::constants::physics::MassLambda - v0.mLambda ()) < cfgV0.cfgHypMassWindow ) {
938945 entryHadron (v0.mLambda (), trackV0Pos.eta (), trackV0Pos.pt () * trackV0Pos.sign (), 0 , 0 , v0.pt ());
939946 entryTrkPID (trackV0Pos.tpcNSigmaPr (), trackV0Pos.tpcNSigmaKa (), trackV0Pos.tpcNSigmaPi (), trackV0Pos.tofNSigmaPr (), trackV0Pos.tofNSigmaKa (), trackV0Pos.tofNSigmaPi ());
940947
@@ -958,7 +965,7 @@ struct HfCorrelatorLcScHadrons {
958965 }
959966 }
960967
961- if (std::abs (o2::constants::physics::MassLambda - v0.mAntiLambda ()) < cfgV0.cfgHypMassWindow ) {
968+ if (passV0Sel && std::abs (o2::constants::physics::MassLambda - v0.mAntiLambda ()) < cfgV0.cfgHypMassWindow ) {
962969 entryHadron (v0.mAntiLambda (), trackV0Neg.eta (), trackV0Neg.pt () * trackV0Neg.sign (), 0 , 0 , v0.pt ());
963970 entryTrkPID (trackV0Neg.tpcNSigmaPr (), trackV0Neg.tpcNSigmaKa (), trackV0Neg.tpcNSigmaPi (), trackV0Neg.tofNSigmaPr (), trackV0Neg.tofNSigmaKa (), trackV0Neg.tofNSigmaPi ());
964971
@@ -991,7 +998,8 @@ struct HfCorrelatorLcScHadrons {
991998 auto const & partV0Pos = trackV0Pos.mcParticle ();
992999 auto const & partV0Neg = trackV0Neg.mcParticle ();
9931000
994- if (v0Mc.pdgCode () == kLambda0 ) {
1001+ if (passV0Sel && v0Mc.pdgCode () == kLambda0 ) {
1002+ if (isSelectedV0Daughter (trackV0Pos, v0, kProton ) && isSelectedV0Daughter (trackV0Neg, v0, kPiMinus )) {
9951003 registry.fill (HIST (" hV0LambdaMcRec" ), v0.mLambda (), v0.pt (), partV0Pos.pt ());
9961004 registry.fill (HIST (" hV0LambdaReflMcRec" ), v0.mAntiLambda (), v0.pt (), partV0Neg.pt ());
9971005 if (cfgV0.calEffV0 && v0Mc.isPhysicalPrimary () && v0Mc.producedByGenerator ()) {
@@ -1004,7 +1012,9 @@ struct HfCorrelatorLcScHadrons {
10041012 registry.fill (HIST (" hV0LambdaReflPiKRejMcRec" ), v0.mAntiLambda (), v0.pt (), partV0Neg.pt ());
10051013 }
10061014 }
1007- if (v0Mc.pdgCode () == kLambda0Bar ) {
1015+ }
1016+ if (passV0Sel && v0Mc.pdgCode () == kLambda0Bar ) {
1017+ if (isSelectedV0Daughter (trackV0Neg, v0, kProtonBar ) && isSelectedV0Daughter (trackV0Pos, v0, kPiPlus )) {
10081018 registry.fill (HIST (" hV0LambdaMcRec" ), v0.mAntiLambda (), v0.pt (), partV0Neg.pt ());
10091019 registry.fill (HIST (" hV0LambdaReflMcRec" ), v0.mLambda (), v0.pt (), partV0Pos.pt ());
10101020
@@ -1018,12 +1028,10 @@ struct HfCorrelatorLcScHadrons {
10181028 }
10191029 }
10201030 }
1021- }
1031+ if (cfgV0.calEffV0 && countV0 == 1 ) {
1032+ auto genPart = mcParticles.sliceBy (perTrueCollision, v0Mc.mcCollisionId ());
10221033
1023- if constexpr (IsMc) {
1024- if (cfgV0.calEffV0 ) {
1025-
1026- for (const auto & particle : mcParticles) {
1034+ for (const auto & particle : genPart) {
10271035
10281036 if (std::abs (particle.pdgCode ()) != kLambda0 ) {
10291037 continue ;
@@ -1036,13 +1044,14 @@ struct HfCorrelatorLcScHadrons {
10361044 continue ;
10371045 }
10381046
1039- auto daughterParts = particle.daughters_as <aod::McParticles>();
1047+ auto daughterParts = particle.template daughters_as <aod::McParticles>();
10401048 const int8_t nDaughtersV0 = 2 ;
10411049
10421050 if (daughterParts.size () != nDaughtersV0) {
10431051 continue ;
10441052 }
10451053
1054+ int8_t countPassedDaughter = 0 ;
10461055 for (const auto & currentDaughter : daughterParts) {
10471056
10481057 if (std::abs (currentDaughter.eta ()) > cfgCharmCand.etaTrackMax ) {
@@ -1051,22 +1060,29 @@ struct HfCorrelatorLcScHadrons {
10511060
10521061 if (std::abs (currentDaughter.pdgCode ()) == kProton ) {
10531062
1054- if (currentDaughter.pt () > cfgV0.cfgDaughPrPtMax || currentDaughter.pt () < cfgV0.cfgDaughPrPtMin ) {
1063+ if (currentDaughter.pt () > cfgV0.cfgV0DaughPrPtMax || currentDaughter.pt () < cfgV0.cfgV0DaughPrPtMin ) {
10551064 continue ;
10561065 }
10571066
10581067 } else if (std::abs (currentDaughter.pdgCode ()) == kPiPlus ) {
1059- if (currentDaughter.pt () > cfgV0.cfgDaughPiPtMax || currentDaughter.pt () < cfgV0.cfgDaughPiPtMin ) {
1068+ if (currentDaughter.pt () > cfgV0.cfgV0DaughPiPtMax || currentDaughter.pt () < cfgV0.cfgV0DaughPiPtMin ) {
10601069 continue ;
10611070 }
10621071
10631072 } else {
10641073 continue ;
10651074 }
1075+ countPassedDaughter++;
1076+ }
1077+ if (countPassedDaughter == nDaughtersV0) {
1078+ registry.fill (HIST (" hV0PtPrimLambdaMcGen" ), particle.pt ());
10661079 }
1067- registry.fill (HIST (" hV0PtPrimLambdaMcGen" ), particle.pt ());
10681080 }
10691081 }
1082+ countV0++;
1083+
1084+ }
1085+
10701086 }
10711087 }
10721088
@@ -1866,12 +1882,12 @@ struct HfCorrelatorLcScHadrons {
18661882 }
18671883 PROCESS_SWITCH (HfCorrelatorLcScHadrons, processMcLambdaV0, " Mc process for v0 lambda with Lc" , false );
18681884
1869- void processLambda0EffCal (SelCollisions::iterator const &,
1885+ void processLambda0EffCal (SelCollisions::iterator const & collision ,
18701886 TracksWithMc const & tracks,
18711887 soa::Join<aod::V0Datas, aod::V0TOFNSigmas, aod::McV0Labels> const & v0s,
18721888 aod::McParticles const & mcParticles)
18731889 {
1874- fillEffV0<true >(v0s, tracks, mcParticles);
1890+ fillEffV0<true >(collision, v0s, tracks, mcParticles);
18751891 }
18761892 PROCESS_SWITCH (HfCorrelatorLcScHadrons, processLambda0EffCal, " Mc process for lambda0" , false );
18771893};
0 commit comments