From eb1b545541b576b803c8d4a7d072e07000faad80 Mon Sep 17 00:00:00 2001 From: apalasciano Date: Thu, 20 Mar 2025 13:37:10 +0100 Subject: [PATCH 1/3] [PWGHF,Trigger] Add bachelor ptcuts in Lc resonances --- EventFiltering/PWGHF/HFFilter.cxx | 31 +++++++++-------- EventFiltering/PWGHF/HFFilterHelpers.h | 47 +++++++++++++++++++------- 2 files changed, 50 insertions(+), 28 deletions(-) diff --git a/EventFiltering/PWGHF/HFFilter.cxx b/EventFiltering/PWGHF/HFFilter.cxx index 21d5fa643b9..034109b0efb 100644 --- a/EventFiltering/PWGHF/HFFilter.cxx +++ b/EventFiltering/PWGHF/HFFilter.cxx @@ -75,7 +75,7 @@ struct HfFilter { // Main struct for HF triggers // nsigma PID (except for V0 and cascades) Configurable> nSigmaPidCuts{"nSigmaPidCuts", {cutsNsigma[0], 4, 8, labelsRowsNsigma, labelsColumnsNsigma}, "Nsigma cuts for ITS/TPC/TOF PID (except for V0 and cascades)"}; // min and max pts for tracks and bachelors (except for V0 and cascades) - Configurable> ptCuts{"ptCuts", {cutsPt[0], 2, 8, labelsRowsCutsPt, labelsColumnsCutsPt}, "minimum and maximum pT for bachelor tracks (except for V0 and cascades)"}; + Configurable> ptCuts{"ptCuts", {cutsPt[0], 2, 9, labelsRowsCutsPt, labelsColumnsCutsPt}, "minimum and maximum pT for bachelor tracks (except for V0 and cascades)"}; // parameters for high-pT triggers Configurable> ptThresholds{"ptThresholds", {cutsHighPtThresholds[0], 1, 2, labelsEmpty, labelsColumnsHighPtThresholds}, "pT treshold for high pT charm hadron candidates for kHighPt triggers in GeV/c"}; @@ -204,6 +204,7 @@ struct HfFilter { // Main struct for HF triggers helper.setPtLimitsProtonForFemto(ptCuts->get(0u, 2u), ptCuts->get(1u, 2u)); helper.setPtLimitsDeuteronForFemto(ptCuts->get(0u, 6u), ptCuts->get(1u, 6u)); helper.setPtLimitsCharmBaryonBachelor(ptCuts->get(0u, 3u), ptCuts->get(1u, 3u)); + helper.setPtLimitsLcResonanceBachelor(ptCuts->get(0u, 8u), ptCuts->get(1u, 8u)); helper.setCutsSingleTrackBeauty(cutsTrackBeauty3Prong, cutsTrackBeauty4Prong, cutsTrackBeauty4Prong); helper.setCutsSingleTrackCharmBaryonBachelor(cutsTrackCharmBaryonBachelor); helper.setCutsBhadrons(cutsBplus, cutsBzeroToDstar, cutsBzero, cutsBs, cutsLb, cutsXib); @@ -549,7 +550,7 @@ struct HfFilter { // Main struct for HF triggers // Beauty with D0 if (!keepEvent[kBeauty3P] && isD0BeautyTagged) { - auto isTrackSelected = helper.isSelectedTrackForSoftPionOrBeauty(track, trackParThird, dcaThird); + int16_t isTrackSelected = helper.isSelectedTrackForSoftPionOrBeauty(track, trackParThird, dcaThird); if (TESTBIT(isTrackSelected, kForBeauty) && ((TESTBIT(selD0InMass, 0) && track.sign() < 0) || (TESTBIT(selD0InMass, 1) && track.sign() > 0))) { // D0 pi- and D0bar pi+ auto massCand = RecoDecay::m(std::array{pVec2Prong, pVecThird}, std::array{massD0, massPi}); auto pVecBeauty3Prong = RecoDecay::pVec(pVec2Prong, pVecThird); @@ -857,7 +858,7 @@ struct HfFilter { // Main struct for HF triggers getPxPyPz(trackParBachelor, pVecBachelor); } - int isTrackSelected = helper.isSelectedTrackForSoftPionOrBeauty(trackBachelor, trackParBachelor, dcaBachelor); + auto isTrackSelected = helper.isSelectedTrackForSoftPionOrBeauty(trackBachelor, trackParBachelor, dcaBachelor); if (TESTBIT(isTrackSelected, kSoftPion) && ((TESTBIT(selD0InMass, 0) && trackBachelor.sign() > 0) || (TESTBIT(selD0InMass, 1) && trackBachelor.sign() < 0))) { std::array massDausD0{massPi, massKa}; auto massD0dau = massD0Cand; @@ -943,17 +944,17 @@ struct HfFilter { // Main struct for HF triggers if (!keepEvent[kPrCharm2P] && isD0SignalTagged && (TESTBIT(selD0InMass, 0) || TESTBIT(selD0InMass, 1))) { for (const auto& trackProtonId : trackIdsThisCollision) { // start loop over tracks selecting only protons auto trackProton = tracks.rawIteratorAt(trackProtonId.trackId()); - std::array pVecProton = trackProton.pVector(); + auto trackParBachelorProton = getTrackPar(trackProton); if (trackProton.globalIndex() == trackPos.globalIndex() || trackProton.globalIndex() == trackNeg.globalIndex()) { continue; } - // minimal track selections - if (!trackProton.isGlobalTrackWoDCA() || std::fabs(trackProton.pt()) < 0.3f) { - continue; + gpu::gpustd::array dcaInfoBachProton; + if (trackProton.collisionId() != thisCollId) { + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParBachelorProton, 2.f, noMatCorr, &dcaInfoBachProton); } - // PID selection - bool isProton = helper.isSelectedProton4CharmOrBeautyBaryons(trackProton); - if (isProton) { + std::array pVecProton = trackProton.pVector(); + auto isSelProton = helper.isSelectedBachelorForCharmBaryon(trackProton, dcaInfoBachProton); + if (isSelProton == kProtonForCharmBaryon) { if (!keepEvent[kPrCharm2P]) { // we first look for a D*+ for (const auto& trackBachelorId : trackIdsThisCollision) { // start loop over tracks to find bachelor pion @@ -968,7 +969,7 @@ struct HfFilter { // Main struct for HF triggers o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParBachelor, 2.f, noMatCorr, &dcaBachelor); getPxPyPz(trackParBachelor, pVecBachelor); } - int isTrackSelected = helper.isSelectedTrackForSoftPionOrBeauty(trackBachelor, trackParBachelor, dcaBachelor); + auto isTrackSelected = helper.isSelectedTrackForSoftPionOrBeauty(trackBachelor, trackParBachelor, dcaBachelor); if (TESTBIT(isTrackSelected, kSoftPion) && ((TESTBIT(selD0InMass, 0) && trackBachelor.sign() > 0) || (TESTBIT(selD0InMass, 1) && trackBachelor.sign() < 0))) { std::array massDausD0{massPi, massKa}; auto massD0dau = massD0Cand; @@ -1390,7 +1391,7 @@ struct HfFilter { // Main struct for HF triggers o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParSoftPi, 2.f, noMatCorr, &dcaSoftPi); getPxPyPz(trackParSoftPi, pVecSoftPi); } - int8_t isSoftPionSelected = helper.isSelectedTrackForSoftPionOrBeauty(trackSoftPi, trackParSoftPi, dcaSoftPi); + int16_t isSoftPionSelected = helper.isSelectedTrackForSoftPionOrBeauty(trackSoftPi, trackParSoftPi, dcaSoftPi); if (TESTBIT(isSoftPionSelected, kSoftPionForSigmaC) /*&& (TESTBIT(is3Prong[2], 0) || TESTBIT(is3Prong[2], 1))*/) { // check the mass of the SigmaC++ candidate @@ -1596,7 +1597,7 @@ struct HfFilter { // Main struct for HF triggers o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParSoftPi, 2.f, noMatCorr, &dcaSoftPi); getPxPyPz(trackParSoftPi, pVecSoftPi); } - int8_t isSoftPionSelected = helper.isSelectedTrackForSoftPionOrBeauty(trackSoftPi, trackParSoftPi, dcaSoftPi); + int16_t isSoftPionSelected = helper.isSelectedTrackForSoftPionOrBeauty(trackSoftPi, trackParSoftPi, dcaSoftPi); if (TESTBIT(isSoftPionSelected, kSoftPionForSigmaC) /*&& (TESTBIT(is3Prong[2], 0) || TESTBIT(is3Prong[2], 1))*/) { // check the mass of the SigmaC0 candidate @@ -1725,7 +1726,7 @@ struct HfFilter { // Main struct for HF triggers o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParBachelor, 2.f, noMatCorr, &dcaInfoBach); } - auto isSelBachelor = helper.isSelectedBachelorForCharmBaryon(track, dcaInfoBach); + auto isSelBachelor = helper.isSelectedBachelorForCharmBaryon(track, dcaInfoBach); if (isSelBachelor == kRejected) { continue; } @@ -1769,7 +1770,7 @@ struct HfFilter { // Main struct for HF triggers o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParBachelorSecond, 2.f, noMatCorr, &dcaInfoBachSecond); } - auto isSelBachelorSecond = helper.isSelectedBachelorForCharmBaryon(trackSecond, dcaInfoBachSecond); + auto isSelBachelorSecond = helper.isSelectedBachelorForCharmBaryon(trackSecond, dcaInfoBachSecond); if (!TESTBIT(isSelBachelorSecond, kPionForCharmBaryon)) { continue; } diff --git a/EventFiltering/PWGHF/HFFilterHelpers.h b/EventFiltering/PWGHF/HFFilterHelpers.h index f3fbe237f7a..fe194da51ee 100644 --- a/EventFiltering/PWGHF/HFFilterHelpers.h +++ b/EventFiltering/PWGHF/HFFilterHelpers.h @@ -127,6 +127,7 @@ enum bachelorTrackSelection { kSoftPionForBeauty, kPionForCharmBaryon, kKaonForCharmBaryon, + kProtonForCharmBaryon, kSoftPionForSigmaC }; @@ -296,9 +297,9 @@ constexpr float cutsPtThresholdsForFemto[1][2] = {{8., 1.4}}; // proton, deutero static const std::vector labelsColumnsPtThresholdsForFemto = {"Proton", "Deuteron"}; // min and max pT for all tracks combined (except for V0 and cascades) -constexpr float cutsPt[2][8] = {{1., 0.1, 0.8, 0.5, 0.1, 0.2, 0.4, 0.5}, - {100000., 100000., 5., 100000., 100000., 100000., 100000., 100000.}}; // beauty, D*, femto, SigmaC, Xic*+ -> SigmaC++K-, beauty to JPsi -static const std::vector labelsColumnsCutsPt = {"Beauty", "DstarPlus", "PrForFemto", "CharmBaryon", "SoftPiSigmaC", "SoftKaonXicResoToSigmaC", "DeForFemto", "BeautyToJPsi"}; +constexpr float cutsPt[2][9] = {{1., 0.1, 0.8, 0.5, 0.1, 0.2, 0.4, 0.5, 0.3}, + {100000., 100000., 5., 100000., 100000., 100000., 100000., 100000., 100000.}}; // beauty, D*, femto, SigmaC, Xic*+ -> SigmaC++K-, beauty to JPsi, Lc*->D0p +static const std::vector labelsColumnsCutsPt = {"Beauty", "DstarPlus", "PrForFemto", "CharmBaryon", "SoftPiSigmaC", "SoftKaonXicResoToSigmaC", "DeForFemto", "BeautyToJPsi", "PrForLcReso"}; static const std::vector labelsRowsCutsPt = {"Minimum", "Maximum"}; // PID cuts @@ -472,6 +473,11 @@ class HfFilterHelper mPtMinCharmBaryonBachelor = minPt; mPtMaxCharmBaryonBachelor = maxPt; } + void setPtLimitsLcResonanceBachelor(float minPt, float maxPt) + { + mPtMinLcResonanceBachelor = minPt; + mPtMaxLcResonanceBachelor = maxPt; + } void setNsigmaProtonCutsForFemto(std::array nSigmaCuts) { mNSigmaPrCutsForFemto = nSigmaCuts; } void setNsigmaDeuteronCutsForFemto(std::array nSigmaCuts) { mNSigmaDeCutsForFemto = nSigmaCuts; } @@ -565,7 +571,7 @@ class HfFilterHelper template bool isSelectedHighPt3Prong(const T& pt); template - int8_t isSelectedTrackForSoftPionOrBeauty(const T& track, const T1& trackPar, const T2& dca); + int16_t isSelectedTrackForSoftPionOrBeauty(const T& track, const T1& trackPar, const T2& dca); template bool isSelectedTrack4Femto(const T1& track, const T2& trackPar, const int& activateQA, H2 hTPCPID, H2 hTOFPID, const int& trackSpecies); template @@ -594,8 +600,8 @@ class HfFilterHelper bool isSelectedPhoton(const Photon& photon, const std::array& dauTracks, const int& activateQA, H2 hV0Selected, std::array& hArmPod); template bool isSelectedCascade(const Casc& casc); - template - int8_t isSelectedBachelorForCharmBaryon(const T& track, const T2& dca); + template + int16_t isSelectedBachelorForCharmBaryon(const T& track, const T2& dca); template bool isSelectedProton4CharmOrBeautyBaryons(const T& track); template @@ -668,12 +674,14 @@ class HfFilterHelper float mPtMinProtonForFemto{0.8}; // minimum pt for the proton for femto float mPtMinDeuteronForFemto{0.8}; // minimum pt for the deuteron for femto float mPtMinCharmBaryonBachelor{0.5}; // minimum pt for the bachelor pion from Xic/Omegac decays + float mPtMinLcResonanceBachelor{0.3}; // minimum pt for the bachelor proton from Lc resonance decays float mPtMaxSoftPionForDstar{2.}; // maximum pt for the D*+ soft pion float mPtMaxBeautyBachelor{100000.}; // maximum pt for the b-hadron pion daughter float mPtMaxBeautyToJPsiBachelor{100000.}; // maximum pt for the b-hadron -> JPsi X daughters (not the muons) float mPtMaxProtonForFemto{5.0}; // maximum pt for the proton for femto float mPtMaxDeuteronForFemto{5.0}; // maximum pt for the deuteron for femto float mPtMaxCharmBaryonBachelor{100000.}; // maximum pt for the bachelor pion from Xic/Omegac decays + float mPtMaxLcResonanceBachelor{100000.}; // maximum pt for the bachelor proton from Lc resonance decays float mPtThresholdProtonForFemto{8.}; // pt threshold to change strategy for proton PID for femto float mPtThresholdDeuteronForFemto{1.4}; // pt threshold to change strategy for deuteron PID for femto float mPtMinSigmaCZero{0.f}; // pt min SigmaC0 candidate @@ -766,10 +774,10 @@ inline bool HfFilterHelper::isSelectedHighPt3Prong(const T& pt) /// \param dca is the 2d array with dcaXY and dcaZ of the track /// \return a flag that encodes the selection for soft pions BIT(kSoftPion), tracks for beauty BIT(kForBeauty), or soft pions for beauty BIT(kSoftPionForBeauty) template -inline int8_t HfFilterHelper::isSelectedTrackForSoftPionOrBeauty(const T& track, const T1& trackPar, const T2& dca) +inline int16_t HfFilterHelper::isSelectedTrackForSoftPionOrBeauty(const T& track, const T1& trackPar, const T2& dca) { - int8_t retValue{BIT(kSoftPion) | BIT(kForBeauty) | BIT(kSoftPionForBeauty) | BIT(kSoftPionForSigmaC)}; + int16_t retValue{BIT(kSoftPion) | BIT(kForBeauty) | BIT(kSoftPionForBeauty) | BIT(kSoftPionForSigmaC)}; if (!track.isGlobalTrackWoDCA()) { return kRejected; @@ -1625,18 +1633,24 @@ inline bool HfFilterHelper::isSelectedCascade(const Casc& casc) /// \param track is a track /// \param dca is the 2d array with dcaXY and dcaZ of the track /// \return 0 if rejected, or a bitmap that contains the information whether it is selected as pion and/or kaon -template -inline int8_t HfFilterHelper::isSelectedBachelorForCharmBaryon(const T& track, const T2& dca) +template +inline int16_t HfFilterHelper::isSelectedBachelorForCharmBaryon(const T& track, const T2& dca) { - int8_t retValue{BIT(kPionForCharmBaryon) | BIT(kKaonForCharmBaryon)}; + int16_t retValue{BIT(kPionForCharmBaryon) | BIT(kKaonForCharmBaryon) | BIT(kProtonForCharmBaryon)}; if (!track.isGlobalTrackWoDCA()) { return kRejected; } float pt = track.pt(); - if (pt < mPtMinCharmBaryonBachelor || pt > mPtMaxCharmBaryonBachelor) { - return kRejected; + if constexpr (whichTrigger == kCharmBarToXiBach){ + if (pt < mPtMinCharmBaryonBachelor || pt > mPtMaxCharmBaryonBachelor) { + return kRejected; + } + } else if constexpr (whichTrigger == kPrCharm2P){ + if (pt < mPtMinLcResonanceBachelor || pt > mPtMaxLcResonanceBachelor) { + return kRejected; + } } auto pTBinTrack = findBin(mPtBinsTracks, pt); @@ -1665,14 +1679,18 @@ inline int8_t HfFilterHelper::isSelectedBachelorForCharmBaryon(const T& track, c float nSigmaPiTpc = track.tpcNSigmaPi(); float nSigmaKaTpc = track.tpcNSigmaKa(); + float nSigmaPrTpc = track.tpcNSigmaPr(); float nSigmaPiTof = track.tofNSigmaPi(); float nSigmaKaTof = track.tofNSigmaKa(); + float nSigmaPrTof = track.tofNSigmaPr(); if (mTpcPidCalibrationOption == 1) { nSigmaPiTpc = getTPCPostCalib(track, kPi); nSigmaKaTpc = getTPCPostCalib(track, kKa); + nSigmaPrTpc = getTPCPostCalib(track, kPr); } else if (mTpcPidCalibrationOption == 2) { nSigmaPiTpc = getTPCSplineCalib(track, (track.sign() > 0) ? kPi : kAntiPi); nSigmaKaTpc = getTPCSplineCalib(track, (track.sign() > 0) ? kKa : kAntiKa); + nSigmaPrTpc = getTPCSplineCalib(track, (track.sign() > 0) ? kPr : kAntiPr); } if ((track.hasTPC() && std::fabs(nSigmaPiTpc) > mNSigmaTpcPiCharmBaryonBachelor) && (track.hasTOF() && std::fabs(nSigmaPiTof) > mNSigmaTofPiCharmBaryonBachelor)) { @@ -1681,6 +1699,9 @@ inline int8_t HfFilterHelper::isSelectedBachelorForCharmBaryon(const T& track, c if ((track.hasTPC() && std::fabs(nSigmaKaTpc) > mNSigmaTpcPiCharmBaryonBachelor) && (track.hasTOF() && std::fabs(nSigmaKaTof) > mNSigmaTofPiCharmBaryonBachelor)) { CLRBIT(retValue, kKaonForCharmBaryon); } + if ((track.hasTPC() && std::fabs(nSigmaPrTpc) > mNSigmaTpcPiCharmBaryonBachelor) && (track.hasTOF() && std::fabs(nSigmaPrTof) > mNSigmaTpcPiCharmBaryonBachelor)) { + CLRBIT(retValue, kProtonForCharmBaryon); + } return retValue; } From 5f0919d536f3dc345eebb9177685103bbf9df769 Mon Sep 17 00:00:00 2001 From: apalasciano Date: Thu, 20 Mar 2025 16:27:38 +0100 Subject: [PATCH 2/3] Fabrizio's additional fix --- EventFiltering/PWGHF/HFFilterHelpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EventFiltering/PWGHF/HFFilterHelpers.h b/EventFiltering/PWGHF/HFFilterHelpers.h index fe194da51ee..9f0c30fbc97 100644 --- a/EventFiltering/PWGHF/HFFilterHelpers.h +++ b/EventFiltering/PWGHF/HFFilterHelpers.h @@ -947,7 +947,7 @@ inline bool HfFilterHelper::isSelectedTrack4Femto(const T1& track, const T2& tra return false; } } else { - if (NSigmaTOF > nSigmaCuts[2] || NSigmaTPC < -nSigmaCuts[0]) { // Use combined TPC and TOF above the threshold + if (NSigmaTOF < -nSigmaCuts[1] || NSigmaTPC < -nSigmaCuts[0]) { // Use combined TPC and TOF above the threshold return false; } } From 02124adbdf8e19f858e40bbbc95e4afab7ad20b7 Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Thu, 20 Mar 2025 15:28:31 +0000 Subject: [PATCH 3/3] Please consider the following formatting changes --- EventFiltering/PWGHF/HFFilterHelpers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EventFiltering/PWGHF/HFFilterHelpers.h b/EventFiltering/PWGHF/HFFilterHelpers.h index 9f0c30fbc97..c5d35286ac0 100644 --- a/EventFiltering/PWGHF/HFFilterHelpers.h +++ b/EventFiltering/PWGHF/HFFilterHelpers.h @@ -1643,11 +1643,11 @@ inline int16_t HfFilterHelper::isSelectedBachelorForCharmBaryon(const T& track, } float pt = track.pt(); - if constexpr (whichTrigger == kCharmBarToXiBach){ + if constexpr (whichTrigger == kCharmBarToXiBach) { if (pt < mPtMinCharmBaryonBachelor || pt > mPtMaxCharmBaryonBachelor) { return kRejected; } - } else if constexpr (whichTrigger == kPrCharm2P){ + } else if constexpr (whichTrigger == kPrCharm2P) { if (pt < mPtMinLcResonanceBachelor || pt > mPtMaxLcResonanceBachelor) { return kRejected; }