Skip to content

Commit ab79d54

Browse files
committed
Add selection and preselection
1 parent 08db6d6 commit ab79d54

File tree

1 file changed

+103
-46
lines changed

1 file changed

+103
-46
lines changed

PWGHF/TableProducer/trackIndexSkimCreator.cxx

Lines changed: 103 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3293,6 +3293,7 @@ struct HfTrackIndexSkimCreatorLfCascades {
32933293

32943294
Configurable<bool> do3Prong{"do3Prong", false, "do 3-prong cascade"};
32953295
Configurable<bool> rejDiffCollTrack{"rejDiffCollTrack", false, "Reject tracks coming from different collisions"};
3296+
Configurable<double> ptTolerance{"ptTolerance", 0.1, "pT tolerance in GeV/c for applying preselections before vertex reconstruction"};
32963297

32973298
// charm baryon invariant mass spectra limits
32983299
Configurable<double> massXiPiMin{"massXiPiMin", 2.1, "Invariant mass lower limit for xi pi decay channel"};
@@ -3324,10 +3325,12 @@ struct HfTrackIndexSkimCreatorLfCascades {
33243325
Configurable<float> ptMinXicplusLfCasc{"ptMinXicplusLfCasc", 0.f, "min. pT for Xicplus in Xi + Pi + Pi decays"};
33253326
Configurable<float> v0TransvRadius{"v0TransvRadius", 1.0, "V0 radius in xy plane"}; // 1.2 (xi) and 1.1 (omega) in run2
33263327
Configurable<float> cascTransvRadius{"cascTransvRadius", 0.4, "Cascade radius in xy plane"}; // 0.5 cm (xi) and 0.6 (omega) in run2
3328+
Configurable<float> decayLengthXicMin{"decayLengthXicMin", 0.4, "Min. decay length of Xic"}; // ...
33273329
Configurable<float> dcaBachToPv{"dcaBachToPv", 0.03, "DCA Bach To PV"}; // 0.04 in run2
33283330
Configurable<float> dcaV0ToPv{"dcaV0ToPv", 0.02, "DCA V0 To PV"}; // 0.03 in run2
33293331
Configurable<double> v0CosPA{"v0CosPA", 0.95, "V0 CosPA"}; // 0.97 in run2 - KEEP LOSE to re-cut after PVRefit! - double -> N.B. dcos(x)/dx = 0 at x=0)
33303332
Configurable<double> cascCosPA{"cascCosPA", 0.95, "Casc CosPA"}; // 0.97 in run2 - KEEP LOSE to re-cut after PVRefit! - double -> N.B. dcos(x)/dx = 0 at x=0)
3333+
Configurable<double> xicCosPA{"xicCosPA", 0.95, "Xic CosPA"}; // 0.97 in run2 - KEEP LOSE to re-cut after PVRefit! - double -> N.B. dcos(x)/dx = 0 at x=0)
33313334
Configurable<float> dcaV0Dau{"dcaV0Dau", 2.0, "DCA V0 Daughters"}; // conservative, a cut ar 1.0 should also be fine
33323335
Configurable<float> dcaCascDau{"dcaCascDau", 2.0, "DCA Casc Daughters"}; // conservative, a cut ar 1.0 should also be fine
33333336
Configurable<float> dcaNegToPv{"dcaNegToPv", 0.05, "DCA Neg To PV"}; // 0.06 in run2
@@ -3490,6 +3493,58 @@ struct HfTrackIndexSkimCreatorLfCascades {
34903493
return false;
34913494
}
34923495

3496+
/// Method to perform selections for 3-prong candidates before vertex reconstruction
3497+
/// \param pVecTrack0 is the momentum array of the first daughter track
3498+
/// \param pVecTrack1 is the momentum array of the second daughter track
3499+
/// \param pVecTrack2 is the momentum array of the third daughter track
3500+
template <typename T1>
3501+
bool isPreselectedCandidate(T1 const& pVecTrack0, T1 const& pVecTrack1, T1 const& pVecTrack2)
3502+
{
3503+
// pt
3504+
auto pt = RecoDecay::pt(pVecTrack0, pVecTrack1, pVecTrack2) + config.ptTolerance; // add tolerance because of no reco decay vertex
3505+
if (pt < config.ptMinXicplusLfCasc) {
3506+
return false;
3507+
}
3508+
3509+
// invariant mass
3510+
double invMassMin = config.massXiPiPiMin;
3511+
double invMassMax = config.massXiPiPiMax;
3512+
if (invMassMin >= 0. && invMassMax > 0.) {
3513+
auto arrMom = std::array{pVecTrack0, pVecTrack1, pVecTrack2};
3514+
auto invMass2 = RecoDecay::m2(arrMom, arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi]);
3515+
if (invMass2 < invMassMin * invMassMin || invMass2 >= invMassMax * invMassMax) {
3516+
return false;
3517+
}
3518+
}
3519+
}
3520+
3521+
/// Method to perform selections for 3-prong candidates after vertex reconstruction
3522+
/// \param pVecCand is the array for the candidate momentum after reconstruction of secondary vertex
3523+
/// \param secVtx is the secondary vertex
3524+
/// \param primVtx is the primary vertex
3525+
/// \return selection outcome
3526+
template <typename T1, typename T2, typename T3>
3527+
bool isSelectedCandidate(const T1& pVecCand, const T2& secVtx, const T3& primVtx)
3528+
{
3529+
// pt
3530+
auto pt = RecoDecay::pt(pVecCand);
3531+
if (pt <= config.ptMinXicplusLfCasc) {
3532+
return false;
3533+
}
3534+
3535+
// CPA
3536+
auto cpa = RecoDecay::cpa(primVtx, secVtx, pVecCand);
3537+
if (cpa < config.xicCosPA) {
3538+
return false;
3539+
}
3540+
3541+
// decay length
3542+
auto decayLength = RecoDecay::distance(primVtx, secVtx);
3543+
if (decayLength < config.decayLengthXicMin) {
3544+
return false;
3545+
}
3546+
}
3547+
34933548
void processNoLfCascades(SelectedCollisions const&)
34943549
{
34953550
// dummy
@@ -3560,20 +3615,20 @@ struct HfTrackIndexSkimCreatorLfCascades {
35603615
covCasc[i] = casc.positionCovMat()[i];
35613616
}
35623617
// create cascade track
3563-
o2::track::TrackParCov trackCascXi;
3618+
o2::track::TrackParCov trackParCovCascXi;
35643619
if (trackCascDauCharged.sign() > 0) {
3565-
trackCascXi = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, 1, true);
3620+
trackParCovCascXi = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, 1, true);
35663621
} else if (trackCascDauCharged.sign() < 0) {
3567-
trackCascXi = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, -1, true);
3622+
trackParCovCascXi = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, -1, true);
35683623
} else {
35693624
continue;
35703625
}
3571-
trackCascXi.setAbsCharge(1);
3626+
trackParCovCascXi.setAbsCharge(1);
35723627

3573-
auto trackCascOmega = trackCascXi;
3628+
auto trackParCovCascOmega = trackParCovCascXi;
35743629

3575-
trackCascXi.setPID(o2::track::PID::XiMinus);
3576-
trackCascOmega.setPID(o2::track::PID::OmegaMinus);
3630+
trackParCovCascXi.setPID(o2::track::PID::XiMinus);
3631+
trackParCovCascOmega.setPID(o2::track::PID::OmegaMinus);
35773632

35783633
//--------------combining cascade and pion tracks--------------
35793634
auto groupedBachTrackIndices = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId);
@@ -3600,12 +3655,12 @@ struct HfTrackIndexSkimCreatorLfCascades {
36003655
}
36013656

36023657
// primary pion track to be processed with DCAFitter
3603-
auto trackParVarCharmBachelor1 = getTrackParCov(trackCharmBachelor1);
3658+
auto trackParCovCharmBachelor1 = getTrackParCov(trackCharmBachelor1);
36043659

36053660
// find charm baryon decay using xi PID hypothesis (xi pi channel)
36063661
int nVtxFrom2ProngFitterXiHyp = 0;
36073662
try {
3608-
nVtxFrom2ProngFitterXiHyp = df2.process(trackCascXi, trackParVarCharmBachelor1);
3663+
nVtxFrom2ProngFitterXiHyp = df2.process(trackParCovCascXi, trackParCovCharmBachelor1);
36093664
} catch (...) {
36103665
if (config.fillHistograms) {
36113666
registry.fill(HIST("hFitterStatusXi2Prong"), 1);
@@ -3651,7 +3706,7 @@ struct HfTrackIndexSkimCreatorLfCascades {
36513706
// find charm baryon decay using omega PID hypothesis to be combined with the charm bachelor (either pion or kaon)
36523707
int nVtxFrom2ProngFitterOmegaHyp = 0;
36533708
try {
3654-
nVtxFrom2ProngFitterOmegaHyp = df2.process(trackCascOmega, trackParVarCharmBachelor1);
3709+
nVtxFrom2ProngFitterOmegaHyp = df2.process(trackParCovCascOmega, trackParCovCharmBachelor1);
36553710
} catch (...) {
36563711
if (config.fillHistograms) {
36573712
registry.fill(HIST("hFitterStatusOmega2Prong"), 1);
@@ -3719,14 +3774,16 @@ struct HfTrackIndexSkimCreatorLfCascades {
37193774
hfFlag);
37203775
}
37213776

3722-
// first loop over tracks
3777+
// Xic -> Xi pi pi
37233778
if (config.do3Prong) {
3779+
// Xi mass cut
3780+
if (std::abs(casc.mXi() - MassXiMinus) > config.cascadeMassWindow) {
3781+
continue;
3782+
}
37243783

3725-
// second loop over positive tracks
3784+
// second loop over tracks
37263785
for (auto trackIdCharmBachelor2 = trackIdCharmBachelor1 + 1; trackIdCharmBachelor2 != groupedBachTrackIndices.end(); ++trackIdCharmBachelor2) {
37273786

3728-
hfFlag = 0;
3729-
37303787
if (!TESTBIT(trackIdCharmBachelor2.isSelProng(), CandidateType::CandCascadeBachelor)) {
37313788
continue;
37323789
}
@@ -3747,14 +3804,16 @@ struct HfTrackIndexSkimCreatorLfCascades {
37473804
continue;
37483805
}
37493806

3750-
// primary pion track to be processed with DCAFitter
3751-
auto trackParVarPion2 = getTrackParCov(trackCharmBachelor2);
3807+
if (!isPreselectedCandidate(pVecCasc, trackCharmBachelor1.pVector(), trackCharmBachelor2.pVector())) {
3808+
continue;
3809+
}
37523810

37533811
// reconstruct Xic with DCAFitter
3812+
// Use only bachelor tracks for vertex reconstruction because the Xi track has large uncertainties.
37543813
int nVtxFrom3ProngFitterXiHyp = 0;
37553814
try {
3756-
// Use only bachelor tracks for vertex reconstruction because the Xi track has large uncertainties.
3757-
nVtxFrom3ProngFitterXiHyp = df2.process(trackParVarCharmBachelor1, trackParVarPion2);
3815+
auto trackParCovCharmBachelor2 = getTrackParCov(trackCharmBachelor2);
3816+
nVtxFrom3ProngFitterXiHyp = df2.process(trackParCovCharmBachelor1, trackParCovCharmBachelor2);
37583817
} catch (...) {
37593818
if (config.fillHistograms) {
37603819
registry.fill(HIST("hFitterStatusXi3Prong"), 1);
@@ -3766,47 +3825,45 @@ struct HfTrackIndexSkimCreatorLfCascades {
37663825
}
37673826

37683827
if (nVtxFrom3ProngFitterXiHyp > 0) {
3769-
37703828
df2.propagateTracksToVertex();
3771-
37723829
if (df2.isPropagateTracksToVertexDone()) {
3773-
3774-
std::array<float, 3> pVec1 = {0.};
3775-
std::array<float, 3> pVec2 = {0.};
3776-
std::array<float, 3> pVec3 = pVecCasc;
3777-
df2.getTrack(0).getPxPyPzGlo(pVec1); // take the momentum at the Xic vertex
3830+
std::array<float, 3> pVec1{0.};
3831+
std::array<float, 3> pVec2{0.};
3832+
std::array<float, 3> pVec3{pVecCasc}; // Use the Xi track for the 3-prong calculations.
3833+
// get bachelor momenta at the Xic vertex
3834+
df2.getTrack(0).getPxPyPzGlo(pVec1);
37783835
df2.getTrack(1).getPxPyPzGlo(pVec2);
3779-
float ptXic3Prong = RecoDecay::pt(pVec1, pVec2, pVec3);
3780-
3781-
std::array<std::array<float, 3>, 3> arr3Mom = {pVec1, pVec2, pVec3};
3782-
auto mass3Prong = RecoDecay::m(arr3Mom, arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi]);
3836+
auto pVecCand = RecoDecay::pVec(pVec1, pVec2, pVec3);
3837+
auto ptCand = RecoDecay::pt(pVecCand);
3838+
std::array<float, 3> primaryVertex{collision.posX(), collision.posY(), collision.posZ()}; // primary vertex
3839+
const auto& secondaryVertex = df2.getPCACandidate(); // secondary vertex
3840+
3841+
registry.fill(HIST("hRejpTStatusXicPlusToXiPiPi"), 0);
3842+
if (ptCand >= config.ptMinXicplusLfCasc) {
3843+
registry.fill(HIST("hRejpTStatusXicPlusToXiPiPi"), 1);
3844+
}
37833845

3784-
if ((std::abs(casc.mXi() - MassXiMinus) < config.cascadeMassWindow) && (mass3Prong >= config.massXiPiPiMin) && (mass3Prong <= config.massXiPiPiMax)) {
3785-
registry.fill(HIST("hRejpTStatusXicPlusToXiPiPi"), 0);
3786-
if (ptXic3Prong >= config.ptMinXicplusLfCasc) {
3787-
SETBIT(hfFlag, aod::hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi);
3788-
registry.fill(HIST("hRejpTStatusXicPlusToXiPiPi"), 1);
3789-
}
3846+
if (!isSelectedCandidate(pVecCand, secondaryVertex, primaryVertex)) {
3847+
continue;
37903848
}
37913849

37923850
// fill histograms
3793-
if (config.fillHistograms && (TESTBIT(hfFlag, aod::hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi))) {
3851+
if (config.fillHistograms) {
3852+
std::array<std::array<float, 3>, 3> arr3Mom = {pVec1, pVec2, pVec3};
3853+
auto mass3Prong = RecoDecay::m(arr3Mom, arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi]);
37943854
registry.fill(HIST("hMassXicPlusToXiPiPi"), mass3Prong);
3795-
registry.fill(HIST("hPtCutsXicPlusToXiPiPi"), ptXic3Prong);
3855+
registry.fill(HIST("hPtCutsXicPlusToXiPiPi"), ptCand);
37963856
}
3857+
3858+
// fill table row if a vertex was found
3859+
rowTrackIndexCasc3Prong(thisCollId,
3860+
casc.cascadeId(),
3861+
trackCharmBachelor1.globalIndex(),
3862+
trackCharmBachelor2.globalIndex());
37973863
} else if (df2.isPropagationFailure()) {
37983864
LOGF(info, "Exception caught: failed to propagate tracks (3prong) to charm baryon decay vtx");
37993865
}
38003866
}
3801-
3802-
// fill table row only if a vertex was found
3803-
if (hfFlag != 0) {
3804-
rowTrackIndexCasc3Prong(thisCollId,
3805-
casc.cascadeId(),
3806-
trackCharmBachelor1.globalIndex(),
3807-
trackCharmBachelor2.globalIndex());
3808-
}
3809-
38103867
} // end 3prong loop
38113868
} // end 3prong condition
38123869

0 commit comments

Comments
 (0)