From bba75f957f5a6180cd71b50e418c2d6bbd55bdbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Mon, 4 Aug 2025 16:08:16 +0200 Subject: [PATCH 01/13] Remove Xi from Xic vertexing --- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 28 ++++++------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index ebe0713d03a..2c06280478c 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -3367,7 +3367,6 @@ struct HfTrackIndexSkimCreatorLfCascades { } config; o2::vertexing::DCAFitterN<2> df2; // 2-prong vertex fitter - o2::vertexing::DCAFitterN<3> df3; // 3-prong vertex fitter Service ccdb; o2::base::MatLayerCylSet* lut; o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; @@ -3428,14 +3427,6 @@ struct HfTrackIndexSkimCreatorLfCascades { df2.setUseAbsDCA(config.useAbsDCA); df2.setWeightedFinalPCA(config.useWeightedFinalPCA); - df3.setPropagateToPCA(config.propagateToPCA); - df3.setMaxR(config.maxR); - df3.setMaxDZIni(config.maxDZIni); - df3.setMinParamChange(config.minParamChange); - df3.setMinRelChi2Change(config.minRelChi2Change); - df3.setUseAbsDCA(config.useAbsDCA); - df3.setWeightedFinalPCA(config.useWeightedFinalPCA); - ccdb->setURL(config.ccdbUrl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); @@ -3564,9 +3555,6 @@ struct HfTrackIndexSkimCreatorLfCascades { df2.setBz(magneticField); df2.setRefitWithMatCorr(config.refitWithMatCorr); - df3.setBz(magneticField); - df3.setRefitWithMatCorr(config.refitWithMatCorr); - // cascade loop auto thisCollId = collision.globalIndex(); auto groupedCascades = cascades.sliceBy(cascadesPerCollision, thisCollId); @@ -3803,7 +3791,8 @@ struct HfTrackIndexSkimCreatorLfCascades { // reconstruct Xic with DCAFitter int nVtxFrom3ProngFitterXiHyp = 0; try { - nVtxFrom3ProngFitterXiHyp = df3.process(trackCascXi, trackParVarCharmBachelor1, trackParVarPion2); + // Use only bachelor tracks for vertex reconstruction because the Xi track has large uncertainties. + nVtxFrom3ProngFitterXiHyp = df2.process(trackParVarCharmBachelor1, trackParVarPion2); } catch (...) { if (config.fillHistograms) { registry.fill(HIST("hFitterStatusXi3Prong"), 1); @@ -3816,16 +3805,15 @@ struct HfTrackIndexSkimCreatorLfCascades { if (nVtxFrom3ProngFitterXiHyp > 0) { - df3.propagateTracksToVertex(); + df2.propagateTracksToVertex(); - if (df3.isPropagateTracksToVertexDone()) { + if (df2.isPropagateTracksToVertexDone()) { std::array pVec1 = {0.}; std::array pVec2 = {0.}; - std::array pVec3 = {0.}; - df3.getTrack(0).getPxPyPzGlo(pVec1); // take the momentum at the Xic vertex - df3.getTrack(1).getPxPyPzGlo(pVec2); - df3.getTrack(2).getPxPyPzGlo(pVec3); + std::array pVec3 = pVecCasc; + df2.getTrack(0).getPxPyPzGlo(pVec1); // take the momentum at the Xic vertex + df2.getTrack(1).getPxPyPzGlo(pVec2); float ptXic3Prong = RecoDecay::pt(pVec1, pVec2, pVec3); std::array, 3> arr3Mom = {pVec1, pVec2, pVec3}; @@ -3844,7 +3832,7 @@ struct HfTrackIndexSkimCreatorLfCascades { registry.fill(HIST("hMassXicPlusToXiPiPi"), mass3Prong); registry.fill(HIST("hPtCutsXicPlusToXiPiPi"), ptXic3Prong); } - } else if (df3.isPropagationFailure()) { + } else if (df2.isPropagationFailure()) { LOGF(info, "Exception caught: failed to propagate tracks (3prong) to charm baryon decay vtx"); } } From b7e0f923a2e943a782043f1af8cdc3592850ae5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Mon, 4 Aug 2025 16:32:40 +0200 Subject: [PATCH 02/13] Remove mass aliases --- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 106 ++++++------------ 1 file changed, 34 insertions(+), 72 deletions(-) diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index 2c06280478c..2a695d2872e 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -87,6 +87,7 @@ using namespace o2::aod; using namespace o2::hf_centrality; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::constants::physics; // enum for candidate type enum CandidateType { @@ -1267,14 +1268,6 @@ struct HfTrackIndexSkimCreator { o2::base::Propagator::MatCorrType noMatCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; int runNumber; - double massPi{0.}; - double massK{0.}; - double massProton{0.}; - double massElectron{0.}; - double massMuon{0.}; - double massDzero{0.}; - double massPhi{0.}; - // int nColls{0}; //can be added to run over limited collisions per file - for tesing purposes static constexpr int kN2ProngDecays = hf_cand_2prong::DecayType::N2ProngDecays; // number of 2-prong hadron types @@ -1328,34 +1321,26 @@ struct HfTrackIndexSkimCreator { return; } - massPi = o2::constants::physics::MassPiPlus; - massK = o2::constants::physics::MassKPlus; - massProton = o2::constants::physics::MassProton; - massElectron = o2::constants::physics::MassElectron; - massMuon = o2::constants::physics::MassMuonPlus; - massDzero = o2::constants::physics::MassD0; - massPhi = o2::constants::physics::MassPhi; - - arrMass2Prong[hf_cand_2prong::DecayType::D0ToPiK] = std::array{std::array{massPi, massK}, - std::array{massK, massPi}}; + arrMass2Prong[hf_cand_2prong::DecayType::D0ToPiK] = std::array{std::array{MassPiPlus, MassKPlus}, + std::array{MassKPlus, MassPiPlus}}; - arrMass2Prong[hf_cand_2prong::DecayType::JpsiToEE] = std::array{std::array{massElectron, massElectron}, - std::array{massElectron, massElectron}}; + arrMass2Prong[hf_cand_2prong::DecayType::JpsiToEE] = std::array{std::array{MassElectron, MassElectron}, + std::array{MassElectron, MassElectron}}; - arrMass2Prong[hf_cand_2prong::DecayType::JpsiToMuMu] = std::array{std::array{massMuon, massMuon}, - std::array{massMuon, massMuon}}; + arrMass2Prong[hf_cand_2prong::DecayType::JpsiToMuMu] = std::array{std::array{MassMuonPlus, MassMuonPlus}, + std::array{MassMuonPlus, MassMuonPlus}}; - arrMass3Prong[hf_cand_3prong::DecayType::DplusToPiKPi] = std::array{std::array{massPi, massK, massPi}, - std::array{massPi, massK, massPi}}; + arrMass3Prong[hf_cand_3prong::DecayType::DplusToPiKPi] = std::array{std::array{MassPiPlus, MassKPlus, MassPiPlus}, + std::array{MassPiPlus, MassKPlus, MassPiPlus}}; - arrMass3Prong[hf_cand_3prong::DecayType::LcToPKPi] = std::array{std::array{massProton, massK, massPi}, - std::array{massPi, massK, massProton}}; + arrMass3Prong[hf_cand_3prong::DecayType::LcToPKPi] = std::array{std::array{MassProton, MassKPlus, MassPiPlus}, + std::array{MassPiPlus, MassKPlus, MassProton}}; - arrMass3Prong[hf_cand_3prong::DecayType::DsToKKPi] = std::array{std::array{massK, massK, massPi}, - std::array{massPi, massK, massK}}; + arrMass3Prong[hf_cand_3prong::DecayType::DsToKKPi] = std::array{std::array{MassKPlus, MassKPlus, MassPiPlus}, + std::array{MassPiPlus, MassKPlus, MassKPlus}}; - arrMass3Prong[hf_cand_3prong::DecayType::XicToPKPi] = std::array{std::array{massProton, massK, massPi}, - std::array{massPi, massK, massProton}}; + arrMass3Prong[hf_cand_3prong::DecayType::XicToPKPi] = std::array{std::array{MassProton, MassKPlus, MassPiPlus}, + std::array{MassPiPlus, MassKPlus, MassProton}}; // cuts for 2-prong decays retrieved by json. the order must be then one in hf_cand_2prong::DecayType cut2Prong = {config.cutsD0ToPiK, config.cutsJpsiToEE, config.cutsJpsiToMuMu}; @@ -1572,10 +1557,10 @@ struct HfTrackIndexSkimCreator { whichHypo[kN2ProngDecays] = whichHypo[hf_cand_2prong::DecayType::D0ToPiK]; double deltaMass = config.cutsDstarToD0Pi->get(pTBinDstar, 1u); - if (TESTBIT(whichHypo[iDecay2P], 0) && (massHypos[0] > (massDzero + deltaMass) * (massDzero + deltaMass) || massHypos[0] < (massDzero - deltaMass) * (massDzero - deltaMass))) { + if (TESTBIT(whichHypo[iDecay2P], 0) && (massHypos[0] > (MassD0 + deltaMass) * (MassD0 + deltaMass) || massHypos[0] < (MassD0 - deltaMass) * (MassD0 - deltaMass))) { CLRBIT(whichHypo[kN2ProngDecays], 0); } - if (TESTBIT(whichHypo[iDecay2P], 1) && (massHypos[1] > (massDzero + deltaMass) * (massDzero + deltaMass) || massHypos[1] < (massDzero - deltaMass) * (massDzero - deltaMass))) { + if (TESTBIT(whichHypo[iDecay2P], 1) && (massHypos[1] > (MassD0 + deltaMass) * (MassD0 + deltaMass) || massHypos[1] < (MassD0 - deltaMass) * (MassD0 - deltaMass))) { CLRBIT(whichHypo[kN2ProngDecays], 1); } } @@ -1597,13 +1582,13 @@ struct HfTrackIndexSkimCreator { double deltaMassMax = cut3Prong[hf_cand_3prong::DecayType::DsToKKPi].get(pTBin, 4u); if (TESTBIT(whichHypo[hf_cand_3prong::DecayType::DsToKKPi], 0)) { double mass2PhiKKPi = RecoDecay::m2(std::array{pVecTrack0, pVecTrack1}, std::array{arrMass3Prong[hf_cand_3prong::DecayType::DsToKKPi][0][0], arrMass3Prong[hf_cand_3prong::DecayType::DsToKKPi][0][1]}); - if (mass2PhiKKPi > (massPhi + deltaMassMax) * (massPhi + deltaMassMax) || mass2PhiKKPi < (massPhi - deltaMassMax) * (massPhi - deltaMassMax)) { + if (mass2PhiKKPi > (MassPhi + deltaMassMax) * (MassPhi + deltaMassMax) || mass2PhiKKPi < (MassPhi - deltaMassMax) * (MassPhi - deltaMassMax)) { CLRBIT(whichHypo[hf_cand_3prong::DecayType::DsToKKPi], 0); } } if (TESTBIT(whichHypo[hf_cand_3prong::DecayType::DsToKKPi], 1)) { double mass2PhiPiKK = RecoDecay::m2(std::array{pVecTrack1, pVecTrack2}, std::array{arrMass3Prong[hf_cand_3prong::DecayType::DsToKKPi][1][1], arrMass3Prong[hf_cand_3prong::DecayType::DsToKKPi][1][2]}); - if (mass2PhiPiKK > (massPhi + deltaMassMax) * (massPhi + deltaMassMax) || mass2PhiPiKK < (massPhi - deltaMassMax) * (massPhi - deltaMassMax)) { + if (mass2PhiPiKK > (MassPhi + deltaMassMax) * (MassPhi + deltaMassMax) || mass2PhiPiKK < (MassPhi - deltaMassMax) * (MassPhi - deltaMassMax)) { CLRBIT(whichHypo[hf_cand_3prong::DecayType::DsToKKPi], 1); } } @@ -1912,8 +1897,8 @@ struct HfTrackIndexSkimCreator { // D0 mass double deltaMassD0 = config.cutsDstarToD0Pi->get(pTBin, 1u); // 1u == deltaMassD0Index - double invMassD0 = RecoDecay::m(arrMomD0, std::array{massPi, massK}); - if (std::abs(invMassD0 - massDzero) > deltaMassD0) { + double invMassD0 = RecoDecay::m(arrMomD0, std::array{MassPiPlus, MassKPlus}); + if (std::abs(invMassD0 - MassD0) > deltaMassD0) { isSelected = 0; if (config.debug) { CLRBIT(cutStatus, 1); @@ -1923,7 +1908,7 @@ struct HfTrackIndexSkimCreator { // D*+ mass double maxDeltaMass = config.cutsDstarToD0Pi->get(pTBin, 0u); // 0u == deltaMassIndex - double invMassDstar = RecoDecay::m(arrMom, std::array{massPi, massK, massPi}); + double invMassDstar = RecoDecay::m(arrMom, std::array{MassPiPlus, MassKPlus, MassPiPlus}); deltaMass = invMassDstar - invMassD0; if (deltaMass > maxDeltaMass) { isSelected = 0; @@ -3106,10 +3091,6 @@ struct HfTrackIndexSkimCreatorCascades { o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; int runNumber{0}; - double massP{0.}; - double massK0s{0.}; - double massLc{0.}; - using SelectedCollisions = soa::Filtered>; using FilteredTrackAssocSel = soa::Filtered>; @@ -3132,10 +3113,6 @@ struct HfTrackIndexSkimCreatorCascades { config.etaMinV0Daugh.value = -config.etaMaxV0Daugh; } - massP = o2::constants::physics::MassProton; - massK0s = o2::constants::physics::MassK0Short; - massLc = o2::constants::physics::MassLambdaCPlus; - if (config.useDCAFitter) { df2.setPropagateToPCA(config.propagateToPCA); df2.setMaxR(config.maxR); @@ -3225,7 +3202,7 @@ struct HfTrackIndexSkimCreatorCascades { } // V0 invariant mass selection - if (std::abs(v0.mK0Short() - massK0s) > config.cutInvMassV0) { + if (std::abs(v0.mK0Short() - MassK0Short) > config.cutInvMassV0) { continue; // should go to the filter, but since it is a dynamic column, I cannot use it there } @@ -3238,8 +3215,8 @@ struct HfTrackIndexSkimCreatorCascades { // invariant-mass cut: we do it here, before updating the momenta of bach and V0 during the fitting to save CPU // TODO: but one should better check that the value here and after the fitter do not change significantly!!! - double mass2K0sP = RecoDecay::m(std::array{pVecBach, pVecV0}, std::array{massP, massK0s}); - if ((config.cutInvMassCascLc >= 0.) && (std::abs(mass2K0sP - massLc) > config.cutInvMassCascLc)) { + double mass2K0sP = RecoDecay::m(std::array{pVecBach, pVecV0}, std::array{MassProton, MassK0Short}); + if ((config.cutInvMassCascLc >= 0.) && (std::abs(mass2K0sP - MassLambdaCPlus) > config.cutInvMassCascLc)) { continue; } @@ -3281,7 +3258,7 @@ struct HfTrackIndexSkimCreatorCascades { // invariant mass // re-calculate invariant masses with updated momenta, to fill the histogram - mass2K0sP = RecoDecay::m(std::array{pVecBach, pVecV0}, std::array{massP, massK0s}); + mass2K0sP = RecoDecay::m(std::array{pVecBach, pVecV0}, std::array{MassProton, MassK0Short}); std::array posCasc = {0., 0., 0.}; if (config.useDCAFitter) { const auto& cascVtx = df2.getPCACandidate(); @@ -3378,14 +3355,6 @@ struct HfTrackIndexSkimCreatorLfCascades { std::array, kN2ProngDecays> arrMass2Prong; std::array, kN3ProngDecays> arrMass3Prong; - // PDG masses - double massP{0.}; - double massPi{0.}; - double massKaon{0.}; - double massXi{0.}; - double massOmega{0.}; - double massLambda{0.}; - using SelectedCollisions = soa::Filtered>; using SelectedHfTrackAssoc = soa::Filtered>; using CascFull = soa::Join; @@ -3407,17 +3376,10 @@ struct HfTrackIndexSkimCreatorLfCascades { return; } - massP = o2::constants::physics::MassProton; - massPi = o2::constants::physics::MassPiPlus; - massKaon = o2::constants::physics::MassKPlus; - massXi = o2::constants::physics::MassXiMinus; - massOmega = o2::constants::physics::MassOmegaMinus; - massLambda = o2::constants::physics::MassLambda0; - - arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi] = std::array{massXi, massPi}; - arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi] = std::array{massOmega, massPi}; - arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK] = std::array{massOmega, massKaon}; - arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi] = std::array{massXi, massPi, massPi}; + arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi] = std::array{MassXiMinus, MassPiPlus}; + arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi] = std::array{MassOmegaMinus, MassPiPlus}; + arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK] = std::array{MassOmegaMinus, MassKPlus}; + arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi] = std::array{MassXiMinus, MassPiPlus, MassPiPlus}; df2.setPropagateToPCA(config.propagateToPCA); df2.setMaxR(config.maxR); @@ -3498,7 +3460,7 @@ struct HfTrackIndexSkimCreatorLfCascades { std::abs(casc.dcav0topv(pvx, pvy, pvz)) > config.dcaV0ToPv && casc.v0radius() > config.v0TransvRadius && casc.cascradius() > config.cascTransvRadius && - std::abs(casc.mLambda() - massLambda) < config.v0MassWindow) { + std::abs(casc.mLambda() - MassLambda0) < config.v0MassWindow) { registry.fill(HIST("hCandidateCounter"), 3.5); // pass cascade selections @@ -3668,7 +3630,7 @@ struct HfTrackIndexSkimCreatorLfCascades { std::array, 2> arrMomToXi = {pVecXi, pVecPion1XiHyp}; auto mass2ProngXiHyp = RecoDecay::m(arrMomToXi, arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi]); - if ((std::abs(casc.mXi() - massXi) < config.cascadeMassWindow) && (mass2ProngXiHyp >= config.massXiPiMin) && (mass2ProngXiHyp <= config.massXiPiMax)) { + if ((std::abs(casc.mXi() - MassXiMinus) < config.cascadeMassWindow) && (mass2ProngXiHyp >= config.massXiPiMin) && (mass2ProngXiHyp <= config.massXiPiMax)) { registry.fill(HIST("hRejpTStatusXicZeroOmegacZeroToXiPi"), 0); if (ptXic >= config.ptMinXicZeroOmegacZeroToXiPiLfCasc) { SETBIT(hfFlag, aod::hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi); @@ -3716,7 +3678,7 @@ struct HfTrackIndexSkimCreatorLfCascades { auto mass2ProngOmegaPiHyp = RecoDecay::m(arrMomToOmega, arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi]); auto mass2ProngOmegaKHyp = RecoDecay::m(arrMomToOmega, arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK]); - if (std::abs(casc.mOmega() - massOmega) < config.cascadeMassWindow) { + if (std::abs(casc.mOmega() - MassOmegaMinus) < config.cascadeMassWindow) { if ((mass2ProngOmegaPiHyp >= config.massOmegaCharmBachelorMin) && (mass2ProngOmegaPiHyp <= config.massOmegaCharmBachelorMax)) { registry.fill(HIST("hRejpTStatusOmegacZeroToOmegaPi"), 0); if (ptOmegac >= config.ptMinOmegacZeroToOmegaPiLfCasc) { @@ -3819,7 +3781,7 @@ struct HfTrackIndexSkimCreatorLfCascades { std::array, 3> arr3Mom = {pVec1, pVec2, pVec3}; auto mass3Prong = RecoDecay::m(arr3Mom, arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi]); - if ((std::abs(casc.mXi() - massXi) < config.cascadeMassWindow) && (mass3Prong >= config.massXiPiPiMin) && (mass3Prong <= config.massXiPiPiMax)) { + if ((std::abs(casc.mXi() - MassXiMinus) < config.cascadeMassWindow) && (mass3Prong >= config.massXiPiPiMin) && (mass3Prong <= config.massXiPiPiMax)) { registry.fill(HIST("hRejpTStatusXicPlusToXiPiPi"), 0); if (ptXic3Prong >= config.ptMinXicplusLfCasc) { SETBIT(hfFlag, aod::hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi); From 08db6d6054e308e125c2fd2a746b3eb09fe93058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Mon, 4 Aug 2025 18:25:59 +0200 Subject: [PATCH 03/13] Fix method name --- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index 2a695d2872e..c85ce5ca9f4 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -1686,7 +1686,7 @@ struct HfTrackIndexSkimCreator { /// \param cutStatus is a 2D array with outcome of each selection (filled only in debug mode) /// \param isSelected ia s bitmap with selection outcome template - void applySelections2Prong(const T1& pVecCand, const T2& secVtx, const T3& primVtx, T4& cutStatus, int& isSelected) + void applySelection2Prong(const T1& pVecCand, const T2& secVtx, const T3& primVtx, T4& cutStatus, int& isSelected) { if (config.debug || isSelected > 0) { @@ -2294,7 +2294,7 @@ struct HfTrackIndexSkimCreator { pvCoord2Prong[1] = pvRefitCoord2Prong[1]; pvCoord2Prong[2] = pvRefitCoord2Prong[2]; } - applySelections2Prong(pVecCandProng2, secondaryVertex2, pvCoord2Prong, cutStatus2Prong, isSelected2ProngCand); + applySelection2Prong(pVecCandProng2, secondaryVertex2, pvCoord2Prong, cutStatus2Prong, isSelected2ProngCand); if (is2ProngCandidateGoodFor3Prong && config.do3Prong == 1) { is2ProngCandidateGoodFor3Prong = isTwoTrackVertexSelectedFor3Prongs(secondaryVertex2, pvCoord2Prong, df2); } From ab79d5407d67b9c189dcb0af9ec682549650ceac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Wed, 6 Aug 2025 18:16:22 +0200 Subject: [PATCH 04/13] Add selection and preselection --- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 149 ++++++++++++------ 1 file changed, 103 insertions(+), 46 deletions(-) diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index c85ce5ca9f4..924a551f016 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -3293,6 +3293,7 @@ struct HfTrackIndexSkimCreatorLfCascades { Configurable do3Prong{"do3Prong", false, "do 3-prong cascade"}; Configurable rejDiffCollTrack{"rejDiffCollTrack", false, "Reject tracks coming from different collisions"}; + Configurable ptTolerance{"ptTolerance", 0.1, "pT tolerance in GeV/c for applying preselections before vertex reconstruction"}; // charm baryon invariant mass spectra limits Configurable massXiPiMin{"massXiPiMin", 2.1, "Invariant mass lower limit for xi pi decay channel"}; @@ -3324,10 +3325,12 @@ struct HfTrackIndexSkimCreatorLfCascades { Configurable ptMinXicplusLfCasc{"ptMinXicplusLfCasc", 0.f, "min. pT for Xicplus in Xi + Pi + Pi decays"}; Configurable v0TransvRadius{"v0TransvRadius", 1.0, "V0 radius in xy plane"}; // 1.2 (xi) and 1.1 (omega) in run2 Configurable cascTransvRadius{"cascTransvRadius", 0.4, "Cascade radius in xy plane"}; // 0.5 cm (xi) and 0.6 (omega) in run2 + Configurable decayLengthXicMin{"decayLengthXicMin", 0.4, "Min. decay length of Xic"}; // ... Configurable dcaBachToPv{"dcaBachToPv", 0.03, "DCA Bach To PV"}; // 0.04 in run2 Configurable dcaV0ToPv{"dcaV0ToPv", 0.02, "DCA V0 To PV"}; // 0.03 in run2 Configurable 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) Configurable 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) + Configurable 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) Configurable dcaV0Dau{"dcaV0Dau", 2.0, "DCA V0 Daughters"}; // conservative, a cut ar 1.0 should also be fine Configurable dcaCascDau{"dcaCascDau", 2.0, "DCA Casc Daughters"}; // conservative, a cut ar 1.0 should also be fine Configurable dcaNegToPv{"dcaNegToPv", 0.05, "DCA Neg To PV"}; // 0.06 in run2 @@ -3490,6 +3493,58 @@ struct HfTrackIndexSkimCreatorLfCascades { return false; } + /// Method to perform selections for 3-prong candidates before vertex reconstruction + /// \param pVecTrack0 is the momentum array of the first daughter track + /// \param pVecTrack1 is the momentum array of the second daughter track + /// \param pVecTrack2 is the momentum array of the third daughter track + template + bool isPreselectedCandidate(T1 const& pVecTrack0, T1 const& pVecTrack1, T1 const& pVecTrack2) + { + // pt + auto pt = RecoDecay::pt(pVecTrack0, pVecTrack1, pVecTrack2) + config.ptTolerance; // add tolerance because of no reco decay vertex + if (pt < config.ptMinXicplusLfCasc) { + return false; + } + + // invariant mass + double invMassMin = config.massXiPiPiMin; + double invMassMax = config.massXiPiPiMax; + if (invMassMin >= 0. && invMassMax > 0.) { + auto arrMom = std::array{pVecTrack0, pVecTrack1, pVecTrack2}; + auto invMass2 = RecoDecay::m2(arrMom, arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi]); + if (invMass2 < invMassMin * invMassMin || invMass2 >= invMassMax * invMassMax) { + return false; + } + } + } + + /// Method to perform selections for 3-prong candidates after vertex reconstruction + /// \param pVecCand is the array for the candidate momentum after reconstruction of secondary vertex + /// \param secVtx is the secondary vertex + /// \param primVtx is the primary vertex + /// \return selection outcome + template + bool isSelectedCandidate(const T1& pVecCand, const T2& secVtx, const T3& primVtx) + { + // pt + auto pt = RecoDecay::pt(pVecCand); + if (pt <= config.ptMinXicplusLfCasc) { + return false; + } + + // CPA + auto cpa = RecoDecay::cpa(primVtx, secVtx, pVecCand); + if (cpa < config.xicCosPA) { + return false; + } + + // decay length + auto decayLength = RecoDecay::distance(primVtx, secVtx); + if (decayLength < config.decayLengthXicMin) { + return false; + } + } + void processNoLfCascades(SelectedCollisions const&) { // dummy @@ -3560,20 +3615,20 @@ struct HfTrackIndexSkimCreatorLfCascades { covCasc[i] = casc.positionCovMat()[i]; } // create cascade track - o2::track::TrackParCov trackCascXi; + o2::track::TrackParCov trackParCovCascXi; if (trackCascDauCharged.sign() > 0) { - trackCascXi = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, 1, true); + trackParCovCascXi = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, 1, true); } else if (trackCascDauCharged.sign() < 0) { - trackCascXi = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, -1, true); + trackParCovCascXi = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, -1, true); } else { continue; } - trackCascXi.setAbsCharge(1); + trackParCovCascXi.setAbsCharge(1); - auto trackCascOmega = trackCascXi; + auto trackParCovCascOmega = trackParCovCascXi; - trackCascXi.setPID(o2::track::PID::XiMinus); - trackCascOmega.setPID(o2::track::PID::OmegaMinus); + trackParCovCascXi.setPID(o2::track::PID::XiMinus); + trackParCovCascOmega.setPID(o2::track::PID::OmegaMinus); //--------------combining cascade and pion tracks-------------- auto groupedBachTrackIndices = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); @@ -3600,12 +3655,12 @@ struct HfTrackIndexSkimCreatorLfCascades { } // primary pion track to be processed with DCAFitter - auto trackParVarCharmBachelor1 = getTrackParCov(trackCharmBachelor1); + auto trackParCovCharmBachelor1 = getTrackParCov(trackCharmBachelor1); // find charm baryon decay using xi PID hypothesis (xi pi channel) int nVtxFrom2ProngFitterXiHyp = 0; try { - nVtxFrom2ProngFitterXiHyp = df2.process(trackCascXi, trackParVarCharmBachelor1); + nVtxFrom2ProngFitterXiHyp = df2.process(trackParCovCascXi, trackParCovCharmBachelor1); } catch (...) { if (config.fillHistograms) { registry.fill(HIST("hFitterStatusXi2Prong"), 1); @@ -3651,7 +3706,7 @@ struct HfTrackIndexSkimCreatorLfCascades { // find charm baryon decay using omega PID hypothesis to be combined with the charm bachelor (either pion or kaon) int nVtxFrom2ProngFitterOmegaHyp = 0; try { - nVtxFrom2ProngFitterOmegaHyp = df2.process(trackCascOmega, trackParVarCharmBachelor1); + nVtxFrom2ProngFitterOmegaHyp = df2.process(trackParCovCascOmega, trackParCovCharmBachelor1); } catch (...) { if (config.fillHistograms) { registry.fill(HIST("hFitterStatusOmega2Prong"), 1); @@ -3719,14 +3774,16 @@ struct HfTrackIndexSkimCreatorLfCascades { hfFlag); } - // first loop over tracks + // Xic -> Xi pi pi if (config.do3Prong) { + // Xi mass cut + if (std::abs(casc.mXi() - MassXiMinus) > config.cascadeMassWindow) { + continue; + } - // second loop over positive tracks + // second loop over tracks for (auto trackIdCharmBachelor2 = trackIdCharmBachelor1 + 1; trackIdCharmBachelor2 != groupedBachTrackIndices.end(); ++trackIdCharmBachelor2) { - hfFlag = 0; - if (!TESTBIT(trackIdCharmBachelor2.isSelProng(), CandidateType::CandCascadeBachelor)) { continue; } @@ -3747,14 +3804,16 @@ struct HfTrackIndexSkimCreatorLfCascades { continue; } - // primary pion track to be processed with DCAFitter - auto trackParVarPion2 = getTrackParCov(trackCharmBachelor2); + if (!isPreselectedCandidate(pVecCasc, trackCharmBachelor1.pVector(), trackCharmBachelor2.pVector())) { + continue; + } // reconstruct Xic with DCAFitter + // Use only bachelor tracks for vertex reconstruction because the Xi track has large uncertainties. int nVtxFrom3ProngFitterXiHyp = 0; try { - // Use only bachelor tracks for vertex reconstruction because the Xi track has large uncertainties. - nVtxFrom3ProngFitterXiHyp = df2.process(trackParVarCharmBachelor1, trackParVarPion2); + auto trackParCovCharmBachelor2 = getTrackParCov(trackCharmBachelor2); + nVtxFrom3ProngFitterXiHyp = df2.process(trackParCovCharmBachelor1, trackParCovCharmBachelor2); } catch (...) { if (config.fillHistograms) { registry.fill(HIST("hFitterStatusXi3Prong"), 1); @@ -3766,47 +3825,45 @@ struct HfTrackIndexSkimCreatorLfCascades { } if (nVtxFrom3ProngFitterXiHyp > 0) { - df2.propagateTracksToVertex(); - if (df2.isPropagateTracksToVertexDone()) { - - std::array pVec1 = {0.}; - std::array pVec2 = {0.}; - std::array pVec3 = pVecCasc; - df2.getTrack(0).getPxPyPzGlo(pVec1); // take the momentum at the Xic vertex + std::array pVec1{0.}; + std::array pVec2{0.}; + std::array pVec3{pVecCasc}; // Use the Xi track for the 3-prong calculations. + // get bachelor momenta at the Xic vertex + df2.getTrack(0).getPxPyPzGlo(pVec1); df2.getTrack(1).getPxPyPzGlo(pVec2); - float ptXic3Prong = RecoDecay::pt(pVec1, pVec2, pVec3); - - std::array, 3> arr3Mom = {pVec1, pVec2, pVec3}; - auto mass3Prong = RecoDecay::m(arr3Mom, arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi]); + auto pVecCand = RecoDecay::pVec(pVec1, pVec2, pVec3); + auto ptCand = RecoDecay::pt(pVecCand); + std::array primaryVertex{collision.posX(), collision.posY(), collision.posZ()}; // primary vertex + const auto& secondaryVertex = df2.getPCACandidate(); // secondary vertex + + registry.fill(HIST("hRejpTStatusXicPlusToXiPiPi"), 0); + if (ptCand >= config.ptMinXicplusLfCasc) { + registry.fill(HIST("hRejpTStatusXicPlusToXiPiPi"), 1); + } - if ((std::abs(casc.mXi() - MassXiMinus) < config.cascadeMassWindow) && (mass3Prong >= config.massXiPiPiMin) && (mass3Prong <= config.massXiPiPiMax)) { - registry.fill(HIST("hRejpTStatusXicPlusToXiPiPi"), 0); - if (ptXic3Prong >= config.ptMinXicplusLfCasc) { - SETBIT(hfFlag, aod::hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi); - registry.fill(HIST("hRejpTStatusXicPlusToXiPiPi"), 1); - } + if (!isSelectedCandidate(pVecCand, secondaryVertex, primaryVertex)) { + continue; } // fill histograms - if (config.fillHistograms && (TESTBIT(hfFlag, aod::hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi))) { + if (config.fillHistograms) { + std::array, 3> arr3Mom = {pVec1, pVec2, pVec3}; + auto mass3Prong = RecoDecay::m(arr3Mom, arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi]); registry.fill(HIST("hMassXicPlusToXiPiPi"), mass3Prong); - registry.fill(HIST("hPtCutsXicPlusToXiPiPi"), ptXic3Prong); + registry.fill(HIST("hPtCutsXicPlusToXiPiPi"), ptCand); } + + // fill table row if a vertex was found + rowTrackIndexCasc3Prong(thisCollId, + casc.cascadeId(), + trackCharmBachelor1.globalIndex(), + trackCharmBachelor2.globalIndex()); } else if (df2.isPropagationFailure()) { LOGF(info, "Exception caught: failed to propagate tracks (3prong) to charm baryon decay vtx"); } } - - // fill table row only if a vertex was found - if (hfFlag != 0) { - rowTrackIndexCasc3Prong(thisCollId, - casc.cascadeId(), - trackCharmBachelor1.globalIndex(), - trackCharmBachelor2.globalIndex()); - } - } // end 3prong loop } // end 3prong condition From 9c4528c445cc127de6a87f654ed4c81ccadaec4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Wed, 6 Aug 2025 18:38:30 +0200 Subject: [PATCH 05/13] Renaming --- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index 924a551f016..00b1260f91c 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -3330,7 +3330,7 @@ struct HfTrackIndexSkimCreatorLfCascades { Configurable dcaV0ToPv{"dcaV0ToPv", 0.02, "DCA V0 To PV"}; // 0.03 in run2 Configurable 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) Configurable 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) - Configurable 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) + Configurable xicCosPA{"xicCosPA", 0.95, "Xic CosPA"}; // ... Configurable dcaV0Dau{"dcaV0Dau", 2.0, "DCA V0 Daughters"}; // conservative, a cut ar 1.0 should also be fine Configurable dcaCascDau{"dcaCascDau", 2.0, "DCA Casc Daughters"}; // conservative, a cut ar 1.0 should also be fine Configurable dcaNegToPv{"dcaNegToPv", 0.05, "DCA Neg To PV"}; // 0.06 in run2 @@ -3493,12 +3493,12 @@ struct HfTrackIndexSkimCreatorLfCascades { return false; } - /// Method to perform selections for 3-prong candidates before vertex reconstruction + /// Method to perform selections for Xic 3-prong candidates before vertex reconstruction /// \param pVecTrack0 is the momentum array of the first daughter track /// \param pVecTrack1 is the momentum array of the second daughter track /// \param pVecTrack2 is the momentum array of the third daughter track template - bool isPreselectedCandidate(T1 const& pVecTrack0, T1 const& pVecTrack1, T1 const& pVecTrack2) + bool isPreselectedCandidateXic(T1 const& pVecTrack0, T1 const& pVecTrack1, T1 const& pVecTrack2) { // pt auto pt = RecoDecay::pt(pVecTrack0, pVecTrack1, pVecTrack2) + config.ptTolerance; // add tolerance because of no reco decay vertex @@ -3518,13 +3518,13 @@ struct HfTrackIndexSkimCreatorLfCascades { } } - /// Method to perform selections for 3-prong candidates after vertex reconstruction + /// Method to perform selections for Xic 3-prong candidates after vertex reconstruction /// \param pVecCand is the array for the candidate momentum after reconstruction of secondary vertex /// \param secVtx is the secondary vertex /// \param primVtx is the primary vertex /// \return selection outcome template - bool isSelectedCandidate(const T1& pVecCand, const T2& secVtx, const T3& primVtx) + bool isSelectedCandidateXic(const T1& pVecCand, const T2& secVtx, const T3& primVtx) { // pt auto pt = RecoDecay::pt(pVecCand); @@ -3804,7 +3804,7 @@ struct HfTrackIndexSkimCreatorLfCascades { continue; } - if (!isPreselectedCandidate(pVecCasc, trackCharmBachelor1.pVector(), trackCharmBachelor2.pVector())) { + if (!isPreselectedCandidateXic(pVecCasc, trackCharmBachelor1.pVector(), trackCharmBachelor2.pVector())) { continue; } @@ -3843,7 +3843,7 @@ struct HfTrackIndexSkimCreatorLfCascades { registry.fill(HIST("hRejpTStatusXicPlusToXiPiPi"), 1); } - if (!isSelectedCandidate(pVecCand, secondaryVertex, primaryVertex)) { + if (!isSelectedCandidateXic(pVecCand, secondaryVertex, primaryVertex)) { continue; } From 1a0f6923cd3e4ed0c6f851e56e5467a7901bea75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Wed, 6 Aug 2025 19:13:14 +0200 Subject: [PATCH 06/13] Fix missing return true --- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index 00b1260f91c..7be9ca1f30d 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -3516,6 +3516,8 @@ struct HfTrackIndexSkimCreatorLfCascades { return false; } } + + return true; } /// Method to perform selections for Xic 3-prong candidates after vertex reconstruction @@ -3543,6 +3545,8 @@ struct HfTrackIndexSkimCreatorLfCascades { if (decayLength < config.decayLengthXicMin) { return false; } + + return true; } void processNoLfCascades(SelectedCollisions const&) From ceaefa7a6e312fd5d46fac3e488a22bb0439087a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Thu, 7 Aug 2025 13:01:10 +0200 Subject: [PATCH 07/13] Fix default config values. Apply cuts only with valid conifg. --- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 60 +++++++++++-------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index 7be9ca1f30d..e3a6b8672e9 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -3323,20 +3323,20 @@ struct HfTrackIndexSkimCreatorLfCascades { Configurable ptMinOmegaczeroToOmegaKaLfCasc{"ptMinOmegaczeroToOmegaKaLfCasc", 0.f, "min. pT for Omegaczero in Omega + Ka decays"}; Configurable ptMinXicZeroOmegacZeroToXiPiLfCasc{"ptMinXicZeroOmegacZeroToXiPiLfCasc", 0.f, "min. pT for XicZeroOmegacZero in Xi + Pi decays"}; Configurable ptMinXicplusLfCasc{"ptMinXicplusLfCasc", 0.f, "min. pT for Xicplus in Xi + Pi + Pi decays"}; - Configurable v0TransvRadius{"v0TransvRadius", 1.0, "V0 radius in xy plane"}; // 1.2 (xi) and 1.1 (omega) in run2 - Configurable cascTransvRadius{"cascTransvRadius", 0.4, "Cascade radius in xy plane"}; // 0.5 cm (xi) and 0.6 (omega) in run2 - Configurable decayLengthXicMin{"decayLengthXicMin", 0.4, "Min. decay length of Xic"}; // ... - Configurable dcaBachToPv{"dcaBachToPv", 0.03, "DCA Bach To PV"}; // 0.04 in run2 - Configurable dcaV0ToPv{"dcaV0ToPv", 0.02, "DCA V0 To PV"}; // 0.03 in run2 - Configurable 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) - Configurable 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) - Configurable xicCosPA{"xicCosPA", 0.95, "Xic CosPA"}; // ... - Configurable dcaV0Dau{"dcaV0Dau", 2.0, "DCA V0 Daughters"}; // conservative, a cut ar 1.0 should also be fine - Configurable dcaCascDau{"dcaCascDau", 2.0, "DCA Casc Daughters"}; // conservative, a cut ar 1.0 should also be fine - Configurable dcaNegToPv{"dcaNegToPv", 0.05, "DCA Neg To PV"}; // 0.06 in run2 - Configurable dcaPosToPv{"dcaPosToPv", 0.05, "DCA Pos To PV"}; // 0.06 in run2 - Configurable v0MassWindow{"v0MassWindow", 0.01, "V0 mass window"}; // 0.008 in run2 - Configurable cascadeMassWindow{"cascadeMassWindow", 0.01, "Cascade mass window"}; + Configurable v0TransvRadius{"v0TransvRadius", 1.f, "V0 radius in xy plane"}; // 1.2 (xi) and 1.1 (omega) in run2 + Configurable cascTransvRadius{"cascTransvRadius", 0.4f, "Cascade radius in xy plane"}; // 0.5 cm (xi) and 0.6 (omega) in run2 + Configurable decayLengthXicMin{"decayLengthXicMin", -1.f, "Min. decay length of Xic"}; // ... + Configurable dcaBachToPv{"dcaBachToPv", 0.03f, "DCA Bach To PV"}; // 0.04 in run2 + Configurable dcaV0ToPv{"dcaV0ToPv", 0.02f, "DCA V0 To PV"}; // 0.03 in run2 + Configurable 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) + Configurable 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) + Configurable xicCosPA{"xicCosPA", 0.95, "Xic CosPA"}; // ... + Configurable dcaV0Dau{"dcaV0Dau", 2.f, "DCA V0 Daughters"}; // conservative, a cut ar 1.0 should also be fine + Configurable dcaCascDau{"dcaCascDau", 2.f, "DCA Casc Daughters"}; // conservative, a cut ar 1.0 should also be fine + Configurable dcaNegToPv{"dcaNegToPv", 0.05f, "DCA Neg To PV"}; // 0.06 in run2 + Configurable dcaPosToPv{"dcaPosToPv", 0.05f, "DCA Pos To PV"}; // 0.06 in run2 + Configurable v0MassWindow{"v0MassWindow", 0.01f, "V0 mass window"}; // 0.008 in run2 + Configurable cascadeMassWindow{"cascadeMassWindow", 0.01f, "Cascade mass window"}; // magnetic field setting from CCDB Configurable isRun2{"isRun2", false, "enable Run 2 or Run 3 GRP objects for magnetic field"}; @@ -3501,9 +3501,11 @@ struct HfTrackIndexSkimCreatorLfCascades { bool isPreselectedCandidateXic(T1 const& pVecTrack0, T1 const& pVecTrack1, T1 const& pVecTrack2) { // pt - auto pt = RecoDecay::pt(pVecTrack0, pVecTrack1, pVecTrack2) + config.ptTolerance; // add tolerance because of no reco decay vertex - if (pt < config.ptMinXicplusLfCasc) { - return false; + if (config.ptMinXicplusLfCasc > 0.f) { + auto pt = RecoDecay::pt(pVecTrack0, pVecTrack1, pVecTrack2) + config.ptTolerance; // add tolerance because of no reco decay vertex + if (pt < config.ptMinXicplusLfCasc) { + return false; + } } // invariant mass @@ -3529,21 +3531,27 @@ struct HfTrackIndexSkimCreatorLfCascades { bool isSelectedCandidateXic(const T1& pVecCand, const T2& secVtx, const T3& primVtx) { // pt - auto pt = RecoDecay::pt(pVecCand); - if (pt <= config.ptMinXicplusLfCasc) { - return false; + if (config.ptMinXicplusLfCasc > 0.f) { + auto pt = RecoDecay::pt(pVecCand); + if (pt <= config.ptMinXicplusLfCasc) { + return false; + } } // CPA - auto cpa = RecoDecay::cpa(primVtx, secVtx, pVecCand); - if (cpa < config.xicCosPA) { - return false; + if (config.xicCosPA > -1.f) { + auto cpa = RecoDecay::cpa(primVtx, secVtx, pVecCand); + if (cpa < config.xicCosPA) { + return false; + } } // decay length - auto decayLength = RecoDecay::distance(primVtx, secVtx); - if (decayLength < config.decayLengthXicMin) { - return false; + if (config.decayLengthXicMin > 0.f) { + auto decayLength = RecoDecay::distance(primVtx, secVtx); + if (decayLength < config.decayLengthXicMin) { + return false; + } } return true; From 4f3e5f5f196d93cd06c9e61becdf12ebbd2c72b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Thu, 7 Aug 2025 13:09:25 +0200 Subject: [PATCH 08/13] Add const. Apply sharp pt cut --- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index e3a6b8672e9..b1cecaaeb5d 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -3533,7 +3533,7 @@ struct HfTrackIndexSkimCreatorLfCascades { // pt if (config.ptMinXicplusLfCasc > 0.f) { auto pt = RecoDecay::pt(pVecCand); - if (pt <= config.ptMinXicplusLfCasc) { + if (pt < config.ptMinXicplusLfCasc) { return false; } } @@ -3824,7 +3824,7 @@ struct HfTrackIndexSkimCreatorLfCascades { // Use only bachelor tracks for vertex reconstruction because the Xi track has large uncertainties. int nVtxFrom3ProngFitterXiHyp = 0; try { - auto trackParCovCharmBachelor2 = getTrackParCov(trackCharmBachelor2); + const auto trackParCovCharmBachelor2 = getTrackParCov(trackCharmBachelor2); nVtxFrom3ProngFitterXiHyp = df2.process(trackParCovCharmBachelor1, trackParCovCharmBachelor2); } catch (...) { if (config.fillHistograms) { @@ -3845,10 +3845,10 @@ struct HfTrackIndexSkimCreatorLfCascades { // get bachelor momenta at the Xic vertex df2.getTrack(0).getPxPyPzGlo(pVec1); df2.getTrack(1).getPxPyPzGlo(pVec2); - auto pVecCand = RecoDecay::pVec(pVec1, pVec2, pVec3); - auto ptCand = RecoDecay::pt(pVecCand); - std::array primaryVertex{collision.posX(), collision.posY(), collision.posZ()}; // primary vertex - const auto& secondaryVertex = df2.getPCACandidate(); // secondary vertex + const auto pVecCand = RecoDecay::pVec(pVec1, pVec2, pVec3); + const auto ptCand = RecoDecay::pt(pVecCand); + const std::array primaryVertex{collision.posX(), collision.posY(), collision.posZ()}; // primary vertex + const auto& secondaryVertex = df2.getPCACandidate(); // secondary vertex registry.fill(HIST("hRejpTStatusXicPlusToXiPiPi"), 0); if (ptCand >= config.ptMinXicplusLfCasc) { @@ -3861,8 +3861,8 @@ struct HfTrackIndexSkimCreatorLfCascades { // fill histograms if (config.fillHistograms) { - std::array, 3> arr3Mom = {pVec1, pVec2, pVec3}; - auto mass3Prong = RecoDecay::m(arr3Mom, arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi]); + const std::array, 3> arr3Mom = {pVec1, pVec2, pVec3}; + const auto mass3Prong = RecoDecay::m(arr3Mom, arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi]); registry.fill(HIST("hMassXicPlusToXiPiPi"), mass3Prong); registry.fill(HIST("hPtCutsXicPlusToXiPiPi"), ptCand); } From 54315ed651e1d7c3cc1826f11ff2c16d9f07b475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Thu, 7 Aug 2025 13:44:52 +0200 Subject: [PATCH 09/13] More const. Improve variable scope. --- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index b1cecaaeb5d..56e3eacafd8 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -3502,18 +3502,18 @@ struct HfTrackIndexSkimCreatorLfCascades { { // pt if (config.ptMinXicplusLfCasc > 0.f) { - auto pt = RecoDecay::pt(pVecTrack0, pVecTrack1, pVecTrack2) + config.ptTolerance; // add tolerance because of no reco decay vertex + const auto pt = RecoDecay::pt(pVecTrack0, pVecTrack1, pVecTrack2) + config.ptTolerance; // add tolerance because of no reco decay vertex if (pt < config.ptMinXicplusLfCasc) { return false; } } // invariant mass - double invMassMin = config.massXiPiPiMin; - double invMassMax = config.massXiPiPiMax; - if (invMassMin >= 0. && invMassMax > 0.) { - auto arrMom = std::array{pVecTrack0, pVecTrack1, pVecTrack2}; - auto invMass2 = RecoDecay::m2(arrMom, arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi]); + if (config.massXiPiPiMin >= 0. && config.massXiPiPiMax > 0.) { + const double invMassMin = config.massXiPiPiMin; + const double invMassMax = config.massXiPiPiMax; + const auto arrMom = std::array{pVecTrack0, pVecTrack1, pVecTrack2}; + const auto invMass2 = RecoDecay::m2(arrMom, arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi]); if (invMass2 < invMassMin * invMassMin || invMass2 >= invMassMax * invMassMax) { return false; } @@ -3532,7 +3532,7 @@ struct HfTrackIndexSkimCreatorLfCascades { { // pt if (config.ptMinXicplusLfCasc > 0.f) { - auto pt = RecoDecay::pt(pVecCand); + const auto pt = RecoDecay::pt(pVecCand); if (pt < config.ptMinXicplusLfCasc) { return false; } @@ -3540,7 +3540,7 @@ struct HfTrackIndexSkimCreatorLfCascades { // CPA if (config.xicCosPA > -1.f) { - auto cpa = RecoDecay::cpa(primVtx, secVtx, pVecCand); + const auto cpa = RecoDecay::cpa(primVtx, secVtx, pVecCand); if (cpa < config.xicCosPA) { return false; } @@ -3548,7 +3548,7 @@ struct HfTrackIndexSkimCreatorLfCascades { // decay length if (config.decayLengthXicMin > 0.f) { - auto decayLength = RecoDecay::distance(primVtx, secVtx); + const auto decayLength = RecoDecay::distance(primVtx, secVtx); if (decayLength < config.decayLengthXicMin) { return false; } @@ -3577,16 +3577,16 @@ struct HfTrackIndexSkimCreatorLfCascades { for (const auto& collision : collisions) { // set the magnetic field from CCDB - auto bc = collision.bc_as(); + const auto bc = collision.bc_as(); initCCDB(bc, runNumber, ccdb, config.isRun2 ? config.ccdbPathGrp : config.ccdbPathGrpMag, lut, config.isRun2); - auto magneticField = o2::base::Propagator::Instance()->getNominalBz(); // z component + const auto magneticField = o2::base::Propagator::Instance()->getNominalBz(); // z component df2.setBz(magneticField); df2.setRefitWithMatCorr(config.refitWithMatCorr); // cascade loop - auto thisCollId = collision.globalIndex(); - auto groupedCascades = cascades.sliceBy(cascadesPerCollision, thisCollId); + const auto thisCollId = collision.globalIndex(); + const auto groupedCascades = cascades.sliceBy(cascadesPerCollision, thisCollId); for (const auto& casc : groupedCascades) { @@ -3594,11 +3594,11 @@ struct HfTrackIndexSkimCreatorLfCascades { //----------------accessing particles in the decay chain------------- // cascade daughter - charged particle - auto trackCascDauCharged = casc.bachelor_as(); // meson <- xi track + const auto trackCascDauCharged = casc.bachelor_as(); // meson <- xi track // cascade daughter - V0 - auto trackV0PosDau = casc.posTrack_as(); // p <- V0 track (positive track) 0 + const auto trackV0PosDau = casc.posTrack_as(); // p <- V0 track (positive track) 0 // V0 negative daughter - auto trackV0NegDau = casc.negTrack_as(); // pion <- V0 track (negative track) 1 + const auto trackV0NegDau = casc.negTrack_as(); // pion <- V0 track (negative track) 1 // check that particles come from the same collision if (config.rejDiffCollTrack) { @@ -3618,8 +3618,8 @@ struct HfTrackIndexSkimCreatorLfCascades { continue; } - std::array vertexCasc = {casc.x(), casc.y(), casc.z()}; - std::array pVecCasc = {casc.px(), casc.py(), casc.pz()}; + const std::array vertexCasc = {casc.x(), casc.y(), casc.z()}; + const std::array pVecCasc = {casc.px(), casc.py(), casc.pz()}; std::array covCasc = {0.}; constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component for (int i = 0; i < 6; i++) { @@ -3643,14 +3643,14 @@ struct HfTrackIndexSkimCreatorLfCascades { trackParCovCascOmega.setPID(o2::track::PID::OmegaMinus); //--------------combining cascade and pion tracks-------------- - auto groupedBachTrackIndices = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + const auto groupedBachTrackIndices = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); for (auto trackIdCharmBachelor1 = groupedBachTrackIndices.begin(); trackIdCharmBachelor1 != groupedBachTrackIndices.end(); ++trackIdCharmBachelor1) { hfFlag = 0; isGoogForXi2Prong = true; isGoogForOmega2Prong = true; - auto trackCharmBachelor1 = trackIdCharmBachelor1.track_as(); + const auto trackCharmBachelor1 = trackIdCharmBachelor1.track_as(); if ((config.rejDiffCollTrack) && (trackCascDauCharged.collisionId() != trackCharmBachelor1.collisionId())) { continue; @@ -3667,7 +3667,7 @@ struct HfTrackIndexSkimCreatorLfCascades { } // primary pion track to be processed with DCAFitter - auto trackParCovCharmBachelor1 = getTrackParCov(trackCharmBachelor1); + const auto trackParCovCharmBachelor1 = getTrackParCov(trackCharmBachelor1); // find charm baryon decay using xi PID hypothesis (xi pi channel) int nVtxFrom2ProngFitterXiHyp = 0; @@ -3800,7 +3800,7 @@ struct HfTrackIndexSkimCreatorLfCascades { continue; } - auto trackCharmBachelor2 = trackIdCharmBachelor2.track_as(); + const auto trackCharmBachelor2 = trackIdCharmBachelor2.track_as(); if ((config.rejDiffCollTrack) && (trackCascDauCharged.collisionId() != trackCharmBachelor2.collisionId())) { continue; @@ -3841,7 +3841,7 @@ struct HfTrackIndexSkimCreatorLfCascades { if (df2.isPropagateTracksToVertexDone()) { std::array pVec1{0.}; std::array pVec2{0.}; - std::array pVec3{pVecCasc}; // Use the Xi track for the 3-prong calculations. + const std::array pVec3{pVecCasc}; // Use the Xi track for the 3-prong calculations. // get bachelor momenta at the Xic vertex df2.getTrack(0).getPxPyPzGlo(pVec1); df2.getTrack(1).getPxPyPzGlo(pVec2); From d452e8ada4ae8b1b2fa8835acff0ca118911bbdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Thu, 7 Aug 2025 14:11:53 +0200 Subject: [PATCH 10/13] Pass float by value --- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index 56e3eacafd8..869a3c548c2 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -511,7 +511,7 @@ struct HfTrackIndexSkimCreatorTagSelTracks { /// \param dca is a 2-element array with dca in transverse and longitudinal directions /// \param statusProng is the selection flag template - void isSelectedTrack(const T& hfTrack, const float& trackPt, const float& trackEta, const std::array& dca, int& statusProng) + void isSelectedTrack(const T& hfTrack, const float trackPt, const float trackEta, const std::array& dca, int& statusProng) { if (config.fillHistograms) { registry.fill(HIST("hPtNoCuts"), trackPt); @@ -3449,7 +3449,7 @@ struct HfTrackIndexSkimCreatorLfCascades { /// Single-cascade cuts template - bool isPreselectedCascade(const TCascade& casc, const float& pvx, const float& pvy, const float& pvz) + bool isPreselectedCascade(const TCascade& casc, const float pvx, const float pvy, const float pvz) { registry.fill(HIST("hCandidateCounter"), 2.5); From 148d5fd7e802a2f18fb4ccdc49e8f2a1fb8bf520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Thu, 7 Aug 2025 18:12:07 +0200 Subject: [PATCH 11/13] Fix momentum order in mass calculation --- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index 869a3c548c2..fdf3c0049d2 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -3494,15 +3494,15 @@ struct HfTrackIndexSkimCreatorLfCascades { } /// Method to perform selections for Xic 3-prong candidates before vertex reconstruction - /// \param pVecTrack0 is the momentum array of the first daughter track - /// \param pVecTrack1 is the momentum array of the second daughter track - /// \param pVecTrack2 is the momentum array of the third daughter track + /// \param pVecXi is the momentum array of the Xi daughter track + /// \param pVecPi1 is the momentum array of the first pion daughter track + /// \param pVecPi2 is the momentum array of the second pion daughter track template - bool isPreselectedCandidateXic(T1 const& pVecTrack0, T1 const& pVecTrack1, T1 const& pVecTrack2) + bool isPreselectedCandidateXic(T1 const& pVecXi, T1 const& pVecPi1, T1 const& pVecPi2) { // pt if (config.ptMinXicplusLfCasc > 0.f) { - const auto pt = RecoDecay::pt(pVecTrack0, pVecTrack1, pVecTrack2) + config.ptTolerance; // add tolerance because of no reco decay vertex + const auto pt = RecoDecay::pt(pVecXi, pVecPi1, pVecPi2) + config.ptTolerance; // add tolerance because of no reco decay vertex if (pt < config.ptMinXicplusLfCasc) { return false; } @@ -3512,7 +3512,7 @@ struct HfTrackIndexSkimCreatorLfCascades { if (config.massXiPiPiMin >= 0. && config.massXiPiPiMax > 0.) { const double invMassMin = config.massXiPiPiMin; const double invMassMax = config.massXiPiPiMax; - const auto arrMom = std::array{pVecTrack0, pVecTrack1, pVecTrack2}; + const auto arrMom = std::array{pVecXi, pVecPi1, pVecPi2}; const auto invMass2 = RecoDecay::m2(arrMom, arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi]); if (invMass2 < invMassMin * invMassMin || invMass2 >= invMassMax * invMassMax) { return false; @@ -3839,16 +3839,15 @@ struct HfTrackIndexSkimCreatorLfCascades { if (nVtxFrom3ProngFitterXiHyp > 0) { df2.propagateTracksToVertex(); if (df2.isPropagateTracksToVertexDone()) { - std::array pVec1{0.}; - std::array pVec2{0.}; - const std::array pVec3{pVecCasc}; // Use the Xi track for the 3-prong calculations. + std::array pVecPi1{}; + std::array pVecPi2{}; // get bachelor momenta at the Xic vertex - df2.getTrack(0).getPxPyPzGlo(pVec1); - df2.getTrack(1).getPxPyPzGlo(pVec2); - const auto pVecCand = RecoDecay::pVec(pVec1, pVec2, pVec3); + df2.getTrack(0).getPxPyPzGlo(pVecPi1); + df2.getTrack(1).getPxPyPzGlo(pVecPi2); + const auto pVecCand = RecoDecay::pVec(pVecCasc, pVecPi1, pVecPi2); const auto ptCand = RecoDecay::pt(pVecCand); - const std::array primaryVertex{collision.posX(), collision.posY(), collision.posZ()}; // primary vertex - const auto& secondaryVertex = df2.getPCACandidate(); // secondary vertex + const std::array primaryVertex{collision.posX(), collision.posY(), collision.posZ()}; // primary vertex + const auto& secondaryVertex = df2.getPCACandidate(); // secondary vertex registry.fill(HIST("hRejpTStatusXicPlusToXiPiPi"), 0); if (ptCand >= config.ptMinXicplusLfCasc) { @@ -3861,7 +3860,7 @@ struct HfTrackIndexSkimCreatorLfCascades { // fill histograms if (config.fillHistograms) { - const std::array, 3> arr3Mom = {pVec1, pVec2, pVec3}; + const std::array arr3Mom{pVecCasc, pVecPi1, pVecPi2}; const auto mass3Prong = RecoDecay::m(arr3Mom, arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi]); registry.fill(HIST("hMassXicPlusToXiPiPi"), mass3Prong); registry.fill(HIST("hPtCutsXicPlusToXiPiPi"), ptCand); From 3ed87fe5f1b78e70ab9d8b27d397d6580d57efaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Thu, 7 Aug 2025 18:29:18 +0200 Subject: [PATCH 12/13] Simpler array declaration --- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index fdf3c0049d2..7720007942b 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -3509,10 +3509,10 @@ struct HfTrackIndexSkimCreatorLfCascades { } // invariant mass - if (config.massXiPiPiMin >= 0. && config.massXiPiPiMax > 0.) { + if (config.massXiPiPiMin >= 0.f && config.massXiPiPiMax > 0.f) { const double invMassMin = config.massXiPiPiMin; const double invMassMax = config.massXiPiPiMax; - const auto arrMom = std::array{pVecXi, pVecPi1, pVecPi2}; + const std::array arrMom{pVecXi, pVecPi1, pVecPi2}; const auto invMass2 = RecoDecay::m2(arrMom, arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi]); if (invMass2 < invMassMin * invMassMin || invMass2 >= invMassMax * invMassMax) { return false; From ceb0a8f7adef45908a91cf88bc52b7c09ea32ff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Fri, 8 Aug 2025 14:01:21 +0200 Subject: [PATCH 13/13] Adjust comments --- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index 7720007942b..4b03533ce1f 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -3497,6 +3497,7 @@ struct HfTrackIndexSkimCreatorLfCascades { /// \param pVecXi is the momentum array of the Xi daughter track /// \param pVecPi1 is the momentum array of the first pion daughter track /// \param pVecPi2 is the momentum array of the second pion daughter track + /// \return selection outcome template bool isPreselectedCandidateXic(T1 const& pVecXi, T1 const& pVecPi1, T1 const& pVecPi2) { @@ -3523,7 +3524,7 @@ struct HfTrackIndexSkimCreatorLfCascades { } /// Method to perform selections for Xic 3-prong candidates after vertex reconstruction - /// \param pVecCand is the array for the candidate momentum after reconstruction of secondary vertex + /// \param pVecCand is the momentum array of the candidate after the reconstruction of the secondary vertex /// \param secVtx is the secondary vertex /// \param primVtx is the primary vertex /// \return selection outcome