Skip to content

Commit 400e948

Browse files
authored
Refactor V0 selection logic and update parameters
1 parent 8c0e826 commit 400e948

1 file changed

Lines changed: 96 additions & 80 deletions

File tree

PWGHF/HFC/TableProducer/correlatorLcScHadrons.cxx

Lines changed: 96 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)