Skip to content

Commit d208861

Browse files
authored
[PWGHF,Trigger] Add the possibility to use TPC PID in BDT for HFfilters + minor changes to selections (#10572)
1 parent 7445830 commit d208861

File tree

3 files changed

+106
-16
lines changed

3 files changed

+106
-16
lines changed

EventFiltering/PWGHF/HFFilter.cxx

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ struct HfFilter { // Main struct for HF triggers
104104
Configurable<bool> forceTofDeuteronForFemto{"forceTofDeuteronForFemto", false, "flag to force TOF PID for deuterons"};
105105

106106
// double charm
107-
Configurable<LabeledArray<int>> enableDoubleCharmChannels{"enableDoubleCharmChannels", {activeDoubleCharmChannels[0], 1, 3, labelsEmpty, labelsColumnsDoubleCharmChannels}, "Flags to enable/disable double charm channels"};
107+
Configurable<LabeledArray<int>> enableDoubleCharmChannels{"enableDoubleCharmChannels", {activeDoubleCharmChannels[0], 2, 3, labelsRowsDoubleCharmChannels, labelsColumnsDoubleCharmChannels}, "Flags to enable/disable double charm channels"};
108108
Configurable<bool> keepOnlyDplusForDouble3Prongs{"keepOnlyDplusForDouble3Prongs", false, "Flag to enable/disable to keep only D+ in double charm 3-prongs trigger"};
109109

110110
// parameters for resonance triggers
@@ -425,7 +425,7 @@ struct HfFilter { // Main struct for HF triggers
425425

426426
hProcessedEvents->Fill(0);
427427

428-
std::vector<std::vector<int64_t>> indicesDau2Prong{};
428+
std::vector<std::vector<int64_t>> indicesDau2Prong{}, indicesDau2ProngPrompt{};
429429

430430
auto cand2ProngsThisColl = cand2Prongs.sliceBy(hf2ProngPerCollision, thisCollId);
431431
for (const auto& cand2Prong : cand2ProngsThisColl) { // start loop over 2 prongs
@@ -516,8 +516,9 @@ struct HfFilter { // Main struct for HF triggers
516516
}
517517
}
518518
// multi-charm selection
519+
indicesDau2Prong.push_back(std::vector<int64_t>{trackPos.globalIndex(), trackNeg.globalIndex()});
519520
if (isD0CharmTagged) {
520-
indicesDau2Prong.push_back(std::vector<int64_t>{trackPos.globalIndex(), trackNeg.globalIndex()});
521+
indicesDau2ProngPrompt.push_back(std::vector<int64_t>{trackPos.globalIndex(), trackNeg.globalIndex()});
521522
}
522523

523524
if (applyOptimisation) {
@@ -946,6 +947,11 @@ struct HfFilter { // Main struct for HF triggers
946947
if (trackProton.globalIndex() == trackPos.globalIndex() || trackProton.globalIndex() == trackNeg.globalIndex()) {
947948
continue;
948949
}
950+
// minimal track selections
951+
if (!trackProton.isGlobalTrackWoDCA() || std::fabs(trackProton.pt()) < 0.3f) {
952+
continue;
953+
}
954+
// PID selection
949955
bool isProton = helper.isSelectedProton4CharmOrBeautyBaryons(trackProton);
950956
if (isProton) {
951957
if (!keepEvent[kPrCharm2P]) {
@@ -1074,7 +1080,7 @@ struct HfFilter { // Main struct for HF triggers
10741080

10751081
} // end loop over 2-prong candidates
10761082

1077-
std::vector<std::vector<int64_t>> indicesDau3Prong{};
1083+
std::vector<std::vector<int64_t>> indicesDau3Prong{}, indicesDau3ProngPrompt{};
10781084
auto cand3ProngsThisColl = cand3Prongs.sliceBy(hf3ProngPerCollision, thisCollId);
10791085
for (const auto& cand3Prong : cand3ProngsThisColl) { // start loop over 3 prongs
10801086
std::array<int8_t, kNCharmParticles - 1> is3Prong = {
@@ -1171,8 +1177,18 @@ struct HfFilter { // Main struct for HF triggers
11711177
keepEvent[kSingleNonPromptCharm3P] = true;
11721178
}
11731179

1174-
if ((!keepOnlyDplusForDouble3Prongs && std::accumulate(isCharmTagged.begin(), isCharmTagged.end(), 0)) || (keepOnlyDplusForDouble3Prongs && isCharmTagged[kDplus - 1])) {
1180+
if (!keepOnlyDplusForDouble3Prongs) {
11751181
indicesDau3Prong.push_back(std::vector<int64_t>{trackFirst.globalIndex(), trackSecond.globalIndex(), trackThird.globalIndex()});
1182+
if (std::accumulate(isCharmTagged.begin(), isCharmTagged.end(), 0)) {
1183+
indicesDau3ProngPrompt.push_back(std::vector<int64_t>{trackFirst.globalIndex(), trackSecond.globalIndex(), trackThird.globalIndex()});
1184+
}
1185+
} else {
1186+
if (isSignalTagged[kDplus - 1]) {
1187+
indicesDau3Prong.push_back(std::vector<int64_t>{trackFirst.globalIndex(), trackSecond.globalIndex(), trackThird.globalIndex()});
1188+
if (isCharmTagged[kDplus - 1]) {
1189+
indicesDau3ProngPrompt.push_back(std::vector<int64_t>{trackFirst.globalIndex(), trackSecond.globalIndex(), trackThird.globalIndex()});
1190+
}
1191+
}
11761192
} // end multiple 3-prong selection
11771193

11781194
auto pVec3Prong = RecoDecay::pVec(pVecFirst, pVecSecond, pVecThird);
@@ -1778,23 +1794,45 @@ struct HfFilter { // Main struct for HF triggers
17781794
}
17791795

17801796
auto n2Prongs = helper.computeNumberOfCandidates(indicesDau2Prong);
1797+
auto n2ProngsPrompt = helper.computeNumberOfCandidates(indicesDau2ProngPrompt);
17811798
auto n3Prongs = helper.computeNumberOfCandidates(indicesDau3Prong);
1799+
auto n3ProngsPrompt = helper.computeNumberOfCandidates(indicesDau3ProngPrompt);
17821800
indicesDau2Prong.insert(indicesDau2Prong.end(), indicesDau3Prong.begin(), indicesDau3Prong.end());
17831801
auto n23Prongs = helper.computeNumberOfCandidates(indicesDau2Prong);
1802+
indicesDau2ProngPrompt.insert(indicesDau2ProngPrompt.end(), indicesDau3ProngPrompt.begin(), indicesDau3ProngPrompt.end());
1803+
auto n23ProngsPrompt = helper.computeNumberOfCandidates(indicesDau2ProngPrompt);
17841804

17851805
if (activateQA) {
17861806
hN2ProngCharmCand->Fill(n2Prongs);
17871807
hN3ProngCharmCand->Fill(n3Prongs);
17881808
}
17891809

17901810
if (n2Prongs > 1 && enableDoubleCharmChannels->get(0u, 0u)) {
1791-
keepEvent[kDoubleCharm2P] = true;
1811+
if (enableDoubleCharmChannels->get(1u, 0u)) {
1812+
keepEvent[kDoubleCharm2P] = true;
1813+
} else {
1814+
if (n2ProngsPrompt > 1) {
1815+
keepEvent[kDoubleCharm2P] = true;
1816+
}
1817+
}
17921818
}
17931819
if (n3Prongs > 1 && enableDoubleCharmChannels->get(0u, 1u)) {
1794-
keepEvent[kDoubleCharm3P] = true;
1820+
if (enableDoubleCharmChannels->get(1u, 1u)) {
1821+
keepEvent[kDoubleCharm3P] = true;
1822+
} else {
1823+
if (n3ProngsPrompt > 1) {
1824+
keepEvent[kDoubleCharm3P] = true;
1825+
}
1826+
}
17951827
}
17961828
if (n23Prongs > 1 && enableDoubleCharmChannels->get(0u, 2u)) {
1797-
keepEvent[kDoubleCharmMix] = true;
1829+
if (enableDoubleCharmChannels->get(1u, 2u)) {
1830+
keepEvent[kDoubleCharmMix] = true;
1831+
} else {
1832+
if (n23ProngsPrompt > 1) {
1833+
keepEvent[kDoubleCharmMix] = true;
1834+
}
1835+
}
17981836
}
17991837

18001838
// apply downscale factors, if required

EventFiltering/PWGHF/HFFilterHelpers.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -343,8 +343,9 @@ static const std::vector<std::string> labelsColumnsCutsBeautyToJPsi = {"minPtMuo
343343
} // namespace hf_trigger_cuts_presel_beauty
344344

345345
// double charm
346-
constexpr int activeDoubleCharmChannels[1][3] = {{1, 1, 1}}; // kDoubleCharm2P, kDoubleCharm3P, kDoubleCharmMix
346+
constexpr int activeDoubleCharmChannels[2][3] = {{1, 1, 1}, {1, 1, 0}}; // kDoubleCharm2P, kDoubleCharm3P, kDoubleCharmMix (second column to keep non-prompt)
347347
static const std::vector<std::string> labelsColumnsDoubleCharmChannels = {"DoubleCharm2Prong", "DoubleCharm3Prong", "DoubleCharmMix"};
348+
static const std::vector<std::string> labelsRowsDoubleCharmChannels = {"", "KeepNonprompt"};
348349

349350
// charm resonances
350351
constexpr float cutsCharmReso[3][13] = {{0.0, 0.0, 0.0, 0.0, 0.4, 0., 0.0, 0.00, 0.21, 0.21, 0.0, 0.7, 0.7},
@@ -932,12 +933,13 @@ inline bool HfFilterHelper::isSelectedTrack4Femto(const T1& track, const T2& tra
932933
// For deuterons: Determine whether to apply TOF based on pt threshold
933934
if (trackSpecies == kDeuteronForFemto) {
934935
// Apply different PID strategy in different pt range
936+
// one side selection only
935937
if (pt <= ptThresholdPidStrategy) {
936-
if (std::fabs(NSigmaTPC) > nSigmaCuts[0] || NSigmaITS < nSigmaCuts[3]) { // Use TPC and ITS below the threshold, NSigmaITS for deuteron with a lower limit
938+
if (NSigmaTPC < -nSigmaCuts[0] || NSigmaITS < -nSigmaCuts[3]) { // Use TPC and ITS below the threshold, NSigmaITS for deuteron with a lower limit
937939
return false;
938940
}
939941
} else {
940-
if (NSigma > nSigmaCuts[2]) { // Use combined TPC and TOF above the threshold
942+
if (NSigmaTOF > nSigmaCuts[2] || NSigmaTPC < -nSigmaCuts[0]) { // Use combined TPC and TOF above the threshold
941943
return false;
942944
}
943945
}

PWGHF/TableProducer/trackIndexSkimCreator.cxx

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,9 +1766,12 @@ struct HfTrackIndexSkimCreator {
17661766

17671767
/// Method to perform ML selections for 2-prong candidates after the rectangular selections
17681768
/// \param featuresCand is the vector with the candidate features
1769+
/// \param featuresCandPid is the vector with the candidate PID features
17691770
/// \param outputScores is the array of vectors with the output scores to be filled
17701771
/// \param isSelected ia s bitmap with selection outcome
1771-
void applyMlSelectionForHfFilters3Prong(std::vector<float> featuresCand, std::array<std::vector<float>, kN3ProngDecays>& outputScores, int& isSelected)
1772+
/// \param usePidForHfFiltersBdt is the flag to determine whether to use also the PID features for the Lc BDT
1773+
template <bool usePidForHfFiltersBdt = false>
1774+
void applyMlSelectionForHfFilters3Prong(std::vector<float> featuresCand, std::vector<float> featuresCandPid, std::array<std::vector<float>, kN3ProngDecays>& outputScores, int& isSelected)
17721775
{
17731776
if (isSelected == 0) {
17741777
return;
@@ -1777,7 +1780,18 @@ struct HfTrackIndexSkimCreator {
17771780
const float ptDummy = 1.; // dummy pT value (only one pT bin)
17781781
for (int iDecay3P{0}; iDecay3P < kN3ProngDecays; ++iDecay3P) {
17791782
if (TESTBIT(isSelected, iDecay3P) && hasMlModel3Prong[iDecay3P]) {
1780-
bool isMlSel = hfMlResponse3Prongs[iDecay3P].isSelectedMl(featuresCand, ptDummy, outputScores[iDecay3P]);
1783+
bool isMlSel = false;
1784+
if constexpr (usePidForHfFiltersBdt) {
1785+
if (iDecay3P != hf_cand_3prong::DecayType::LcToPKPi && iDecay3P != hf_cand_3prong::DecayType::XicToPKPi) {
1786+
hfMlResponse3Prongs[iDecay3P].isSelectedMl(featuresCand, ptDummy, outputScores[iDecay3P]);
1787+
} else {
1788+
std::vector<float> featuresCandWithPid = featuresCand;
1789+
featuresCandWithPid.insert(featuresCandWithPid.end(), featuresCandPid.begin(), featuresCandPid.end());
1790+
hfMlResponse3Prongs[iDecay3P].isSelectedMl(featuresCandWithPid, ptDummy, outputScores[iDecay3P]);
1791+
}
1792+
} else {
1793+
isMlSel = hfMlResponse3Prongs[iDecay3P].isSelectedMl(featuresCand, ptDummy, outputScores[iDecay3P]);
1794+
}
17811795
if (config.fillHistograms) {
17821796
switch (iDecay3P) {
17831797
case hf_cand_3prong::DecayType::DplusToPiKPi: {
@@ -2002,7 +2016,7 @@ struct HfTrackIndexSkimCreator {
20022016
return;
20032017
} /// end of performPvRefitCandProngs function
20042018

2005-
template <bool doPvRefit = false, typename TTracks>
2019+
template <bool doPvRefit = false, bool usePidForHfFiltersBdt = false, typename TTracks>
20062020
void run2And3Prongs(SelectedCollisions const& collisions,
20072021
aod::BCsWithTimestamps const& bcWithTimeStamps,
20082022
FilteredTrackAssocSel const&,
@@ -2506,7 +2520,15 @@ struct HfTrackIndexSkimCreator {
25062520
std::array<std::vector<float>, kN3ProngDecays> mlScores3Prongs;
25072521
if (config.applyMlForHfFilters) {
25082522
std::vector<float> inputFeatures{trackParVarPcaPos1.getPt(), dcaInfoPos1[0], dcaInfoPos1[1], trackParVarPcaNeg1.getPt(), dcaInfoNeg1[0], dcaInfoNeg1[1], trackParVarPcaPos2.getPt(), dcaInfoPos2[0], dcaInfoPos2[1]};
2509-
applyMlSelectionForHfFilters3Prong(inputFeatures, mlScores3Prongs, isSelected3ProngCand);
2523+
std::vector<float> inputFeaturesLcPid{};
2524+
if constexpr (usePidForHfFiltersBdt) {
2525+
inputFeaturesLcPid.push_back(trackPos1.tpcNSigmaPr());
2526+
inputFeaturesLcPid.push_back(trackPos2.tpcNSigmaPr());
2527+
inputFeaturesLcPid.push_back(trackPos1.tpcNSigmaPi());
2528+
inputFeaturesLcPid.push_back(trackPos2.tpcNSigmaPi());
2529+
inputFeaturesLcPid.push_back(trackNeg1.tpcNSigmaKa());
2530+
}
2531+
applyMlSelectionForHfFilters3Prong<usePidForHfFiltersBdt>(inputFeatures, inputFeaturesLcPid, mlScores3Prongs, isSelected3ProngCand);
25102532
}
25112533

25122534
if (!config.debug && isSelected3ProngCand == 0) {
@@ -2751,7 +2773,15 @@ struct HfTrackIndexSkimCreator {
27512773
std::array<std::vector<float>, kN3ProngDecays> mlScores3Prongs;
27522774
if (config.applyMlForHfFilters) {
27532775
std::vector<float> inputFeatures{trackParVarPcaNeg1.getPt(), dcaInfoNeg1[0], dcaInfoNeg1[1], trackParVarPcaPos1.getPt(), dcaInfoPos1[0], dcaInfoPos1[1], trackParVarPcaNeg2.getPt(), dcaInfoNeg2[0], dcaInfoNeg2[1]};
2754-
applyMlSelectionForHfFilters3Prong(inputFeatures, mlScores3Prongs, isSelected3ProngCand);
2776+
std::vector<float> inputFeaturesLcPid{};
2777+
if constexpr (usePidForHfFiltersBdt) {
2778+
inputFeaturesLcPid.push_back(trackNeg1.tpcNSigmaPr());
2779+
inputFeaturesLcPid.push_back(trackNeg2.tpcNSigmaPr());
2780+
inputFeaturesLcPid.push_back(trackNeg1.tpcNSigmaPi());
2781+
inputFeaturesLcPid.push_back(trackNeg2.tpcNSigmaPi());
2782+
inputFeaturesLcPid.push_back(trackPos1.tpcNSigmaKa());
2783+
}
2784+
applyMlSelectionForHfFilters3Prong<usePidForHfFiltersBdt>(inputFeatures, inputFeaturesLcPid, mlScores3Prongs, isSelected3ProngCand);
27552785
}
27562786

27572787
if (!config.debug && isSelected3ProngCand == 0) {
@@ -2945,6 +2975,26 @@ struct HfTrackIndexSkimCreator {
29452975
run2And3Prongs(collisions, bcWithTimeStamps, trackIndices, tracks);
29462976
}
29472977
PROCESS_SWITCH(HfTrackIndexSkimCreator, process2And3ProngsNoPvRefit, "Process 2-prong and 3-prong skim without PV refit", true);
2978+
2979+
void process2And3ProngsWithPvRefitWithPidForHfFiltersBdt( // soa::Join<aod::Collisions, aod::CentV0Ms>::iterator const& collision, //FIXME add centrality when option for variations to the process function appears
2980+
SelectedCollisions const& collisions,
2981+
aod::BCsWithTimestamps const& bcWithTimeStamps,
2982+
FilteredTrackAssocSel const& trackIndices,
2983+
soa::Join<TracksWithPVRefitAndDCA, aod::pidTPCFullPi, aod::pidTPCFullKa, aod::pidTPCFullPr> const& tracks)
2984+
{
2985+
run2And3Prongs<true, true>(collisions, bcWithTimeStamps, trackIndices, tracks);
2986+
}
2987+
PROCESS_SWITCH(HfTrackIndexSkimCreator, process2And3ProngsWithPvRefitWithPidForHfFiltersBdt, "Process 2-prong and 3-prong skim with PV refit and PID for software trigger BDTs (Lc and Xic only)", false);
2988+
2989+
void process2And3ProngsNoPvRefitWithPidForHfFiltersBdt( // soa::Join<aod::Collisions, aod::CentV0Ms>::iterator const& collision, //FIXME add centrality when option for variations to the process function appears
2990+
SelectedCollisions const& collisions,
2991+
aod::BCsWithTimestamps const& bcWithTimeStamps,
2992+
FilteredTrackAssocSel const& trackIndices,
2993+
soa::Join<aod::TracksWCovDcaExtra, aod::pidTPCFullPi, aod::pidTPCFullKa, aod::pidTPCFullPr> const& tracks)
2994+
{
2995+
run2And3Prongs<false, true>(collisions, bcWithTimeStamps, trackIndices, tracks);
2996+
}
2997+
PROCESS_SWITCH(HfTrackIndexSkimCreator, process2And3ProngsNoPvRefitWithPidForHfFiltersBdt, "Process 2-prong and 3-prong skim without PV refit and PID for software trigger BDTs (Lc and Xic only)", false);
29482998
};
29492999

29503000
//________________________________________________________________________________________________________________________

0 commit comments

Comments
 (0)