Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 16 additions & 15 deletions EventFiltering/PWGHF/HFFilter.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ struct HfFilter { // Main struct for HF triggers
// nsigma PID (except for V0 and cascades)
Configurable<LabeledArray<float>> 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<LabeledArray<float>> ptCuts{"ptCuts", {cutsPt[0], 2, 8, labelsRowsCutsPt, labelsColumnsCutsPt}, "minimum and maximum pT for bachelor tracks (except for V0 and cascades)"};
Configurable<LabeledArray<float>> 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<LabeledArray<float>> ptThresholds{"ptThresholds", {cutsHighPtThresholds[0], 1, 2, labelsEmpty, labelsColumnsHighPtThresholds}, "pT treshold for high pT charm hadron candidates for kHighPt triggers in GeV/c"};
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -549,7 +550,7 @@ struct HfFilter { // Main struct for HF triggers

// Beauty with D0
if (!keepEvent[kBeauty3P] && isD0BeautyTagged) {
auto isTrackSelected = helper.isSelectedTrackForSoftPionOrBeauty<kBeauty3P>(track, trackParThird, dcaThird);
int16_t isTrackSelected = helper.isSelectedTrackForSoftPionOrBeauty<kBeauty3P>(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);
Expand Down Expand Up @@ -857,7 +858,7 @@ struct HfFilter { // Main struct for HF triggers
getPxPyPz(trackParBachelor, pVecBachelor);
}

int isTrackSelected = helper.isSelectedTrackForSoftPionOrBeauty<kV0Charm2P>(trackBachelor, trackParBachelor, dcaBachelor);
auto isTrackSelected = helper.isSelectedTrackForSoftPionOrBeauty<kV0Charm2P>(trackBachelor, trackParBachelor, dcaBachelor);
if (TESTBIT(isTrackSelected, kSoftPion) && ((TESTBIT(selD0InMass, 0) && trackBachelor.sign() > 0) || (TESTBIT(selD0InMass, 1) && trackBachelor.sign() < 0))) {
std::array<float, 2> massDausD0{massPi, massKa};
auto massD0dau = massD0Cand;
Expand Down Expand Up @@ -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<float, 3> 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<float, 2> 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<float, 3> pVecProton = trackProton.pVector();
auto isSelProton = helper.isSelectedBachelorForCharmBaryon<kPrCharm2P>(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
Expand All @@ -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<kPrCharm2P>(trackBachelor, trackParBachelor, dcaBachelor);
auto isTrackSelected = helper.isSelectedTrackForSoftPionOrBeauty<kPrCharm2P>(trackBachelor, trackParBachelor, dcaBachelor);
if (TESTBIT(isTrackSelected, kSoftPion) && ((TESTBIT(selD0InMass, 0) && trackBachelor.sign() > 0) || (TESTBIT(selD0InMass, 1) && trackBachelor.sign() < 0))) {
std::array<float, 2> massDausD0{massPi, massKa};
auto massD0dau = massD0Cand;
Expand Down Expand Up @@ -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<kSigmaCPPK>(trackSoftPi, trackParSoftPi, dcaSoftPi);
int16_t isSoftPionSelected = helper.isSelectedTrackForSoftPionOrBeauty<kSigmaCPPK>(trackSoftPi, trackParSoftPi, dcaSoftPi);
if (TESTBIT(isSoftPionSelected, kSoftPionForSigmaC) /*&& (TESTBIT(is3Prong[2], 0) || TESTBIT(is3Prong[2], 1))*/) {

// check the mass of the SigmaC++ candidate
Expand Down Expand Up @@ -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<kSigmaC0K0>(trackSoftPi, trackParSoftPi, dcaSoftPi);
int16_t isSoftPionSelected = helper.isSelectedTrackForSoftPionOrBeauty<kSigmaC0K0>(trackSoftPi, trackParSoftPi, dcaSoftPi);
if (TESTBIT(isSoftPionSelected, kSoftPionForSigmaC) /*&& (TESTBIT(is3Prong[2], 0) || TESTBIT(is3Prong[2], 1))*/) {

// check the mass of the SigmaC0 candidate
Expand Down Expand Up @@ -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<kCharmBarToXiBach>(track, dcaInfoBach);
if (isSelBachelor == kRejected) {
continue;
}
Expand Down Expand Up @@ -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<kCharmBarToXiBach>(trackSecond, dcaInfoBachSecond);
if (!TESTBIT(isSelBachelorSecond, kPionForCharmBaryon)) {
continue;
}
Expand Down
49 changes: 35 additions & 14 deletions EventFiltering/PWGHF/HFFilterHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ enum bachelorTrackSelection {
kSoftPionForBeauty,
kPionForCharmBaryon,
kKaonForCharmBaryon,
kProtonForCharmBaryon,
kSoftPionForSigmaC
};

Expand Down Expand Up @@ -296,9 +297,9 @@ constexpr float cutsPtThresholdsForFemto[1][2] = {{8., 1.4}}; // proton, deutero
static const std::vector<std::string> 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<std::string> 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<std::string> labelsColumnsCutsPt = {"Beauty", "DstarPlus", "PrForFemto", "CharmBaryon", "SoftPiSigmaC", "SoftKaonXicResoToSigmaC", "DeForFemto", "BeautyToJPsi", "PrForLcReso"};
static const std::vector<std::string> labelsRowsCutsPt = {"Minimum", "Maximum"};

// PID cuts
Expand Down Expand Up @@ -472,6 +473,11 @@ class HfFilterHelper
mPtMinCharmBaryonBachelor = minPt;
mPtMaxCharmBaryonBachelor = maxPt;
}
void setPtLimitsLcResonanceBachelor(float minPt, float maxPt)
{
mPtMinLcResonanceBachelor = minPt;
mPtMaxLcResonanceBachelor = maxPt;
}

void setNsigmaProtonCutsForFemto(std::array<float, 4> nSigmaCuts) { mNSigmaPrCutsForFemto = nSigmaCuts; }
void setNsigmaDeuteronCutsForFemto(std::array<float, 4> nSigmaCuts) { mNSigmaDeCutsForFemto = nSigmaCuts; }
Expand Down Expand Up @@ -565,7 +571,7 @@ class HfFilterHelper
template <typename T>
bool isSelectedHighPt3Prong(const T& pt);
template <o2::aod::hffilters::HfTriggers whichTrigger, typename T, typename T1, typename T2>
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 <typename T1, typename T2, typename H2>
bool isSelectedTrack4Femto(const T1& track, const T2& trackPar, const int& activateQA, H2 hTPCPID, H2 hTOFPID, const int& trackSpecies);
template <typename T>
Expand Down Expand Up @@ -594,8 +600,8 @@ class HfFilterHelper
bool isSelectedPhoton(const Photon& photon, const std::array<T, 2>& dauTracks, const int& activateQA, H2 hV0Selected, std::array<H2, 4>& hArmPod);
template <typename Casc>
bool isSelectedCascade(const Casc& casc);
template <typename T, typename T2>
int8_t isSelectedBachelorForCharmBaryon(const T& track, const T2& dca);
template <o2::aod::hffilters::HfTriggers whichTrigger, typename T, typename T2>
int16_t isSelectedBachelorForCharmBaryon(const T& track, const T2& dca);
template <bool is4beauty = false, typename T>
bool isSelectedProton4CharmOrBeautyBaryons(const T& track);
template <typename T, typename U>
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 <o2::aod::hffilters::HfTriggers whichTrigger, typename T, typename T1, typename T2>
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;
Expand Down Expand Up @@ -939,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;
}
}
Expand Down Expand Up @@ -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 <typename T, typename T2>
inline int8_t HfFilterHelper::isSelectedBachelorForCharmBaryon(const T& track, const T2& dca)
template <o2::aod::hffilters::HfTriggers whichTrigger, typename T, typename T2>
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);
Expand Down Expand Up @@ -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)) {
Expand All @@ -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;
}
Expand Down