Skip to content

Commit 23ad41b

Browse files
committed
Add 3-prong combinatorics with ML-based single-track selection
1 parent def7bbd commit 23ad41b

3 files changed

Lines changed: 1579 additions & 0 deletions

File tree

PWGHF/Core/HfMlResponseHfTracks.h

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
// Copyright 2019-2026 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
/// \file HfMlResponseHfTracks.h
13+
/// \brief Class to compute the ML response for single-track selection of HF daughters
14+
/// \author Fabrizio Chinu <fabrizio.chinu@cern.ch>, Universita and INFN Torino
15+
16+
#ifndef PWGHF_CORE_HFMLRESPONSEHFTRACKS_H_
17+
#define PWGHF_CORE_HFMLRESPONSEHFTRACKS_H_
18+
19+
#include "PWGHF/Core/HfMlResponse.h"
20+
21+
#include "Tools/ML/MlResponse.h"
22+
23+
#include <algorithm>
24+
#include <cstdint>
25+
#include <iterator>
26+
#include <vector>
27+
28+
// Fill the map of available input features
29+
// the key is the feature's name (std::string)
30+
// the value is the corresponding value in EnumInputFeatures
31+
#define FILL_MAP_HF_TRACK(FEATURE) \
32+
{ \
33+
#FEATURE, static_cast<uint8_t>(InputFeaturesTracks::FEATURE)}
34+
35+
// Check if the index of mCachedIndices (index associated to a FEATURE)
36+
// matches the entry in EnumInputFeatures associated to this FEATURE
37+
// if so, the inputFeatures vector is filled with the FEATURE's value
38+
#define CHECK_AND_FILL_VEC_HF_TRACK(FEATURE) \
39+
case static_cast<uint8_t>(InputFeaturesTracks::FEATURE): \
40+
inputFeatures.emplace_back(track.FEATURE); \
41+
break;
42+
43+
namespace o2::analysis
44+
{
45+
46+
/// Output classes of the track-level HF model.
47+
/// The ordering must match the one used at training time.
48+
enum class HfTrackMlClass : uint8_t {
49+
Background = 0, ///< track is not a daughter of a D+ → πKπ / Ds → φπ → KKπ decay
50+
Pion, ///< track is the π± of a D+ → πKπ / Ds → φπ → KKπ decay
51+
Kaon, ///< track is the K∓ of a D+ → πKπ / Ds → φπ → KKπ decay
52+
NClasses
53+
};
54+
55+
enum class InputFeaturesTracks : uint8_t {
56+
// kinematics
57+
pt = 0,
58+
eta,
59+
// impact parameter and its resolution
60+
dcaXY,
61+
dcaZ,
62+
sigmaDcaXY,
63+
sigmaDcaZ,
64+
normDcaXY,
65+
normDcaZ,
66+
// track parameters
67+
signed1Pt,
68+
tgl,
69+
sign,
70+
isPvContributor,
71+
// ITS quality
72+
itsNCls,
73+
itsNClsInnerBarrel,
74+
itsChi2NCl,
75+
// TPC quality
76+
tpcNClsFound,
77+
tpcCrossedRowsOverFindableCls,
78+
tpcChi2NCl,
79+
tpcFractionSharedCls,
80+
// TPC PID
81+
tpcNSigmaPi,
82+
tpcNSigmaKa,
83+
// event
84+
centrality
85+
};
86+
87+
/// Plain container with every quantity the model can be fed.
88+
/// It is filled once per (track, collision) association by the task and then reduced to the
89+
/// configured subset of features by getInputFeatures().
90+
/// Everything is a float so that the training tree and the inference input are bit-identical.
91+
struct HfTrackMlFeatures {
92+
// kinematics
93+
float pt{0.f};
94+
float eta{0.f};
95+
// impact parameter and its resolution
96+
float dcaXY{0.f};
97+
float dcaZ{0.f};
98+
float sigmaDcaXY{0.f};
99+
float sigmaDcaZ{0.f};
100+
float normDcaXY{0.f};
101+
float normDcaZ{0.f};
102+
// track parameters
103+
float signed1Pt{0.f};
104+
float tgl{0.f};
105+
float sign{0.f};
106+
float isPvContributor{0.f};
107+
// ITS quality
108+
float itsNCls{0.f};
109+
float itsNClsInnerBarrel{0.f};
110+
float itsChi2NCl{0.f};
111+
// TPC quality
112+
float tpcNClsFound{0.f};
113+
float tpcCrossedRowsOverFindableCls{0.f};
114+
float tpcChi2NCl{0.f};
115+
float tpcFractionSharedCls{0.f};
116+
// TPC PID
117+
float tpcNSigmaPi{0.f};
118+
float tpcNSigmaKa{0.f};
119+
// event
120+
float centrality{0.f};
121+
};
122+
123+
template <typename TypeOutputScore = float>
124+
class HfMlResponseHfTracks : public HfMlResponse<TypeOutputScore>
125+
{
126+
public:
127+
/// Default constructor
128+
HfMlResponseHfTracks() = default;
129+
/// Default destructor
130+
virtual ~HfMlResponseHfTracks() = default;
131+
132+
/// Index of the model to be used for a given value of the binning variable (the track pT).
133+
/// Needed because the task applies its own per-class thresholds instead of the single-decision
134+
/// logic of MlResponse::isSelectedMl, whose private findBin is not reachable from here.
135+
/// Follows the same convention as the base class: mBinsLimits stores the bin edges.
136+
/// \param value is the value of the binning variable
137+
/// \return index of the model to be used, -1 if the value is outside the configured range
138+
int getModelBin(float value) const
139+
{
140+
const auto& binsLimits = MlResponse<TypeOutputScore>::mBinsLimits;
141+
const auto valueDouble = static_cast<double>(value);
142+
if (binsLimits.empty() || valueDouble < binsLimits.front() || valueDouble >= binsLimits.back()) {
143+
return -1;
144+
}
145+
return std::distance(binsLimits.begin(), std::upper_bound(binsLimits.begin(), binsLimits.end(), valueDouble)) - 1;
146+
}
147+
148+
/// Method to get the input features vector needed for ML inference
149+
/// \param track is the container with all the candidate track quantities
150+
/// \return inputFeatures vector, in the order configured via cacheInputFeaturesIndices
151+
std::vector<float> getInputFeatures(HfTrackMlFeatures const& track)
152+
{
153+
std::vector<float> inputFeatures;
154+
inputFeatures.reserve(MlResponse<TypeOutputScore>::mCachedIndices.size());
155+
156+
for (const auto& idx : MlResponse<TypeOutputScore>::mCachedIndices) {
157+
switch (idx) {
158+
CHECK_AND_FILL_VEC_HF_TRACK(pt);
159+
CHECK_AND_FILL_VEC_HF_TRACK(eta);
160+
CHECK_AND_FILL_VEC_HF_TRACK(dcaXY);
161+
CHECK_AND_FILL_VEC_HF_TRACK(dcaZ);
162+
CHECK_AND_FILL_VEC_HF_TRACK(sigmaDcaXY);
163+
CHECK_AND_FILL_VEC_HF_TRACK(sigmaDcaZ);
164+
CHECK_AND_FILL_VEC_HF_TRACK(normDcaXY);
165+
CHECK_AND_FILL_VEC_HF_TRACK(normDcaZ);
166+
CHECK_AND_FILL_VEC_HF_TRACK(signed1Pt);
167+
CHECK_AND_FILL_VEC_HF_TRACK(tgl);
168+
CHECK_AND_FILL_VEC_HF_TRACK(sign);
169+
CHECK_AND_FILL_VEC_HF_TRACK(isPvContributor);
170+
CHECK_AND_FILL_VEC_HF_TRACK(itsNCls);
171+
CHECK_AND_FILL_VEC_HF_TRACK(itsNClsInnerBarrel);
172+
CHECK_AND_FILL_VEC_HF_TRACK(itsChi2NCl);
173+
CHECK_AND_FILL_VEC_HF_TRACK(tpcNClsFound);
174+
CHECK_AND_FILL_VEC_HF_TRACK(tpcCrossedRowsOverFindableCls);
175+
CHECK_AND_FILL_VEC_HF_TRACK(tpcChi2NCl);
176+
CHECK_AND_FILL_VEC_HF_TRACK(tpcFractionSharedCls);
177+
CHECK_AND_FILL_VEC_HF_TRACK(tpcNSigmaPi);
178+
CHECK_AND_FILL_VEC_HF_TRACK(tpcNSigmaKa);
179+
CHECK_AND_FILL_VEC_HF_TRACK(centrality);
180+
}
181+
}
182+
183+
return inputFeatures;
184+
}
185+
186+
protected:
187+
/// Method to fill the map of available input features
188+
void setAvailableInputFeatures()
189+
{
190+
MlResponse<TypeOutputScore>::mAvailableInputFeatures = {
191+
FILL_MAP_HF_TRACK(pt),
192+
FILL_MAP_HF_TRACK(eta),
193+
FILL_MAP_HF_TRACK(dcaXY),
194+
FILL_MAP_HF_TRACK(dcaZ),
195+
FILL_MAP_HF_TRACK(sigmaDcaXY),
196+
FILL_MAP_HF_TRACK(sigmaDcaZ),
197+
FILL_MAP_HF_TRACK(normDcaXY),
198+
FILL_MAP_HF_TRACK(normDcaZ),
199+
FILL_MAP_HF_TRACK(signed1Pt),
200+
FILL_MAP_HF_TRACK(tgl),
201+
FILL_MAP_HF_TRACK(sign),
202+
FILL_MAP_HF_TRACK(isPvContributor),
203+
FILL_MAP_HF_TRACK(itsNCls),
204+
FILL_MAP_HF_TRACK(itsNClsInnerBarrel),
205+
FILL_MAP_HF_TRACK(itsChi2NCl),
206+
FILL_MAP_HF_TRACK(tpcNClsFound),
207+
FILL_MAP_HF_TRACK(tpcCrossedRowsOverFindableCls),
208+
FILL_MAP_HF_TRACK(tpcChi2NCl),
209+
FILL_MAP_HF_TRACK(tpcFractionSharedCls),
210+
FILL_MAP_HF_TRACK(tpcNSigmaPi),
211+
FILL_MAP_HF_TRACK(tpcNSigmaKa),
212+
FILL_MAP_HF_TRACK(centrality)};
213+
}
214+
};
215+
216+
} // namespace o2::analysis
217+
218+
#undef FILL_MAP_HF_TRACK
219+
#undef CHECK_AND_FILL_VEC_HF_TRACK
220+
221+
#endif // PWGHF_CORE_HFMLRESPONSEHFTRACKS_H_

PWGHF/D2H/TableProducer/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ o2physics_add_dpl_workflow(candidate-selector-lb-to-lc-pi-reduced
6363
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore
6464
COMPONENT_NAME Analysis)
6565

66+
# Track selectors
67+
68+
o2physics_add_dpl_workflow(ml-based-track-selector
69+
SOURCES mlBasedTrackSelector.cxx
70+
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DetectorsVertexing O2::DCAFitter O2Physics::AnalysisCCDB O2Physics::MLCore O2Physics::SGCutParHolder O2Physics::EventFilteringUtils
71+
COMPONENT_NAME Analysis)
72+
6673
# Data creators
6774

6875
o2physics_add_dpl_workflow(data-creator-charm-had-pi-reduced

0 commit comments

Comments
 (0)