ATLAS Offline Software
Loading...
Searching...
No Matches
VertexTimeAlg.cxx
Go to the documentation of this file.
1
10
11#include "VertexTimeAlg.h"
12
13// Athena includes
19
20// Standard library includes
21#include <cmath>
22#include <stdexcept>
23
24namespace HGTD {
25
26VertexTimeAlg::VertexTimeAlg(const std::string& name, ISvcLocator* pSvcLocator)
27 : AthReentrantAlgorithm(name, pSvcLocator) {}
28
30
31 // Initialize keys for event data access
32 ATH_CHECK(m_primVxCont_key.initialize());
33 ATH_CHECK(m_trackCont_key.initialize());
34 ATH_CHECK(m_vxHasTime_key.initialize());
35 ATH_CHECK(m_vxTime_key.initialize());
36 ATH_CHECK(m_vxTimeRes_key.initialize());
37 ATH_CHECK(m_trackValidTime_key.initialize());
38 ATH_CHECK(m_trackTime_key.initialize());
39 ATH_CHECK(m_trackTimeRes_key.initialize());
40 const std::string weightFile {
41 PathResolver::find_file("TMVA.VBFinv.mu200.Step3p1.8var.weights.xml", "DATAPATH")
42 };
43 // Initialize the BDT
44 for (auto& bdt : m_BDT) {
45
46 bdt.reader = std::make_unique<TMVA::Reader>("!Color:!Silent");
47
48 bdt.reader->AddVariable("m_delta_z", &bdt.delta_z);
49 bdt.reader->AddVariable("m_z_sigma", &bdt.z_sigma);
50 bdt.reader->AddVariable("m_q_over_p", &bdt.q_over_p);
51 bdt.reader->AddVariable("m_q_over_p_sigma", &bdt.q_over_p_sigma);
52 bdt.reader->AddVariable("m_delta_z_resunits", &bdt.delta_z_resunits);
53 bdt.reader->AddVariable("m_cluster_sumpt2", &bdt.cluster_sumpt2);
54 bdt.reader->AddVariable("m_d0", &bdt.d0);
55 bdt.reader->AddVariable("m_d0_sigma", &bdt.d0_sigma);
56 bdt.reader->BookMVA("BDT", weightFile);
57 }
58
59 return StatusCode::SUCCESS;
60}
61
62StatusCode VertexTimeAlg::execute(const EventContext& ctx) const {
63
66
68 m_vxHasTime_key, ctx);
70 m_vxTime_key, ctx);
72 m_vxTimeRes_key, ctx);
73
74
75 for (const auto vx : *primVxCont) {
76
77 if (vx->vertexType() == xAOD::VxType::VertexType::PriVtx) {
78
79 std::vector<const xAOD::TrackParticle*> hgtdTracks {
80 vertexAssociatedHGTDTracks(vx, trackCont.cptr(), 1.0 * Gaudi::Units::GeV)
81 };
82
83 std::vector<HGTD::Cluster<const xAOD::TrackParticle*>> trackClusters {
84 clusterTracksInTime(ctx, hgtdTracks, 3.0)
85 };
86
87 // Get the cluster that was determined as HS by the BDT
89 getHScluster(ctx, trackClusters, vx)
90 };
91
92 if (HS_cluster.getEntries().size() > 0) {
93 // HS cluster was found
94
95 vxHasTime(*vx) = 1;
96 vxTime(*vx) = HS_cluster.getValues().at(0);
97 vxTimeRes(*vx) = HS_cluster.getSigmas().at(0);
98
99 } else {
100 // No cluster was chosen as HS
101
102 vxHasTime(*vx) = 0;
103 vxTime(*vx) = m_default_vxTime;
104 vxTimeRes(*vx) = m_default_vxTimeRes;
105 }
106
107 } else {
108 // Pileup vertices do not have a time
109
110 vxHasTime(*vx) = 0;
111 vxTime(*vx) = m_default_vxTime;
112 vxTimeRes(*vx) = m_default_vxTimeRes;
113 }
114 }
115
116 return StatusCode::SUCCESS;
117}
118
119std::vector<const xAOD::TrackParticle*>
121 const xAOD::Vertex* vertex, const xAOD::TrackParticleContainer* tracks,
122 double min_trk_pt) const {
123
124 std::vector<const xAOD::TrackParticle*> good_tracks { };
125
126 for (const auto trk : *tracks) {
127 if (std::abs(trk->eta()) < 2.4 || std::abs(trk->eta()) > 4.0) {
128 // Track is not within HGTD acceptance
129 continue;
130 }
131 if (trk->pt() < 1.0 * Gaudi::Units::GeV) {
132 continue;
133 }
134 if (passTrackVertexAssociation(trk, vertex, min_trk_pt)) {
135 good_tracks.push_back(trk);
136 }
137 }
138
139 return good_tracks;
140}
141
143 const xAOD::TrackParticle* track, const xAOD::Vertex* vertex,
144 double min_trk_pt, const double significance_cut) const {
145
146 if (track->pt() < min_trk_pt || std::abs(track->eta()) > 4.0) {
147 return false;
148 }
149
150 const double vx_z { vertex->z() };
151 const double vx_z_variance { vertex->covariancePosition()(2, 2) };
152
153 const double trk_z { track->vz() + track->z0() };
154 const double trk_z_variance { track->definingParametersCovMatrix()(1, 1) };
155
156 if (std::abs(trk_z - vx_z) / std::sqrt(trk_z_variance + vx_z_variance)
157 < significance_cut) {
158 return true;
159 } else {
160 return false;
161 }
162}
163
164std::vector<HGTD::Cluster<const xAOD::TrackParticle*>>
166 const EventContext& ctx,
167 const std::vector<const xAOD::TrackParticle*>& tracks,
168 double cluster_distance) const {
169
172
174 m_trackTime_key, ctx);
175
177 m_trackTimeRes_key, ctx);
178
179
181
182 for (const auto& track : tracks) {
183
184 if (trackValidTime(*track)) {
185 double time { trackTime(*track) };
186 double timeResolution { trackTimeResolution(*track) };
187
189 {time}, {timeResolution}, track);
190
191 collection.addCluster(cluster);
192 }
193 }
194
195 collection.updateDistanceCut(cluster_distance);
197
198 return collection.getClusters();
199}
200
202 const EventContext& ctx,
203 const std::vector<HGTD::Cluster<const xAOD::TrackParticle*>>& clusters,
204 const xAOD::Vertex* vertex) const {
205
207 float max_BDT_score { -1.0f };
208
209 for (const auto& cluster : clusters) {
210
211 // HS cluster has an additional requirement to have at least 3 tracks
212 if (cluster.getEntries().size() < 3) {
213 continue;
214 }
215
216 const float cluster_score { scoreCluster(ctx, cluster, vertex) };
217
218 if (cluster_score > m_bdt_cutvalue && cluster_score > max_BDT_score) {
219
220 max_BDT_score = cluster_score;
221 HS_cluster = cluster;
222 }
223 }
224
225 // If no cluster passes the HS criteria, the return value will be an empty
226 // cluster
227 return HS_cluster;
228}
229
231 const EventContext& ctx,
233 const xAOD::Vertex* vertex) const {
234
235 std::pair<float, float> cluster_z { getZOfCluster(cluster) };
236 std::pair<float, float> cluster_oneover_p { getOneOverPOfCluster(cluster) };
237 std::pair<float, float> cluster_d0 { getDOfCluster(cluster) };
238 double vertex_z_variance { vertex->covariancePosition()(2, 2) };
239
240 auto& bdt { *m_BDT.get(ctx) };
241
242 bdt.delta_z = cluster_z.first - vertex->z();
243 bdt.z_sigma = cluster_z.second;
244 bdt.q_over_p = cluster_oneover_p.first;
245 bdt.q_over_p_sigma = cluster_oneover_p.second;
246 bdt.d0 = cluster_d0.first;
247 bdt.d0_sigma = cluster_d0.second;
248 bdt.cluster_sumpt2 = getSumPt2OfCluster(cluster);
249 bdt.delta_z_resunits = (cluster_z.first - vertex->z()) /
250 std::sqrt(std::pow(cluster_z.second, 2.0) + vertex_z_variance);
251
252 return bdt.reader->EvaluateMVA("BDT");
253}
254
255std::pair<float, float> VertexTimeAlg::getZOfCluster(
256 const HGTD::Cluster<const xAOD::TrackParticle*>& cluster) const {
257
258 std::vector<const xAOD::TrackParticle*> tracks { cluster.getEntries() };
259
260 float num { 0.0f };
261 float denom { 0.0f };
262
263 for (const auto& track : tracks) {
264
265 float z0 { track->z0() };
266 float z0_variance {
267 static_cast<float>(track->definingParametersCovMatrix()(1, 1))
268 };
269
270 num += z0 / z0_variance;
271 denom += 1.0f / z0_variance;
272 }
273 if (denom == 0.)[[unlikely]]{
274 throw std::runtime_error("VertexTimeAlg::getZOfCluster: denominator is zero");
275 }
276 float avg_z0 = num / denom;
277 float avg_z0_sigma = std::sqrt(1.0f / denom);
278
279 return {avg_z0, avg_z0_sigma};
280}
281
283 const HGTD::Cluster<const xAOD::TrackParticle*>& cluster) const {
284
285 std::vector<const xAOD::TrackParticle*> tracks { cluster.getEntries() };
286
287 float num { 0.0f };
288 float denom { 0.0f };
289
290 for (const auto& track : tracks) {
291
292 float one_over_p { std::abs(track->qOverP()) };
293 float one_over_p_variance {
294 static_cast<float>(track->definingParametersCovMatrix()(4, 4))
295 };
296
297 num += one_over_p / one_over_p_variance;
298 denom += 1.0f / one_over_p_variance;
299 }
300 if (denom == 0.)[[unlikely]]{
301 throw std::runtime_error("VertexTimeAlg::getOneOverPOfCluster: denominator is zero");
302 }
303 float avg_oneover_p = num / denom;
304 float avg_oneover_p_sigma = std::sqrt(1.0f / denom);
305
306 return {avg_oneover_p, avg_oneover_p_sigma};
307}
308
309std::pair<float, float> VertexTimeAlg::getDOfCluster(
310 const HGTD::Cluster<const xAOD::TrackParticle*>& cluster) const {
311
312 std::vector<const xAOD::TrackParticle*> tracks { cluster.getEntries() };
313
314 float num { 0.0f };
315 float denom { 0.0f };
316
317 for (const auto& track : tracks) {
318
319 float d0 { track->d0() };
320 float d0_variance {
321 static_cast<float>(track->definingParametersCovMatrix()(0, 0))
322 };
323
324 num += d0 / d0_variance;
325 denom += 1.0f / d0_variance;
326 }
327 if (denom == 0.)[[unlikely]]{
328 throw std::runtime_error("VertexTimeAlg::getDOfCluster: denominator is zero");
329 }
330 float avg_z0 = num / denom;
331 float avg_z0_sigma = std::sqrt(1.0f / denom);
332
333 return {avg_z0, avg_z0_sigma};
334}
335
337 const HGTD::Cluster<const xAOD::TrackParticle*>& cluster) const {
338
339 std::vector<const xAOD::TrackParticle*> tracks { cluster.getEntries() };
340
341 float sumpt2 { 0.0f };
342
343 for (const auto& track : tracks) {
344 sumpt2 += std::pow(track->pt(), 2.0);
345 }
346
347 return sumpt2;
348}
349
350} // namespace HGTD
#define ATH_CHECK
Evaluate an expression and check for errors.
Handle class for reading a decoration on an object.
Handle class for reading from StoreGate.
Handle class for adding a decoration to an object.
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration.
An algorithm that can be simultaneously executed in multiple threads.
void doClustering(ClusterAlgo algo)
Definition Clustering.h:357
void updateDistanceCut(double cut_value)
Set the distance cut.
Definition Clustering.h:259
void addCluster(const Cluster< T > &vx)
Definition Clustering.h:263
const std::vector< Cluster< T > > & getClusters() const
Definition Clustering.h:495
std::vector< double > getValues() const
Return the N-dimensional value of the Cluster.
Definition Clustering.h:217
const std::vector< double > & getSigmas() const
Return the N-dimensional resolution of the Cluster.
Definition Clustering.h:229
const std::vector< T > & getEntries() const
Return the objects that are part of the Cluster.
Definition Clustering.h:199
std::pair< float, float > getDOfCluster(const HGTD::Cluster< const xAOD::TrackParticle * > &cluster) const
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_trackCont_key
Gaudi::Property< float > m_default_vxTime
std::vector< const xAOD::TrackParticle * > vertexAssociatedHGTDTracks(const xAOD::Vertex *vertex, const xAOD::TrackParticleContainer *tracks, double min_trk_pt) const
std::pair< float, float > getOneOverPOfCluster(const HGTD::Cluster< const xAOD::TrackParticle * > &cluster) const
SG::ReadHandleKey< xAOD::VertexContainer > m_primVxCont_key
Gaudi::Property< float > m_bdt_cutvalue
std::pair< float, float > getZOfCluster(const HGTD::Cluster< const xAOD::TrackParticle * > &cluster) const
HGTD::Cluster< const xAOD::TrackParticle * > getHScluster(const EventContext &ctx, const std::vector< HGTD::Cluster< const xAOD::TrackParticle * > > &clusters, const xAOD::Vertex *vertex) const
bool passTrackVertexAssociation(const xAOD::TrackParticle *track, const xAOD::Vertex *vertex, double min_trk_pt, const double significance_cut=2.5) const
std::vector< HGTD::Cluster< const xAOD::TrackParticle * > > clusterTracksInTime(const EventContext &ctx, const std::vector< const xAOD::TrackParticle * > &tracks, double cluster_distance) const
SG::WriteDecorHandleKey< xAOD::VertexContainer > m_vxTimeRes_key
VertexTimeAlg(const std::string &name, ISvcLocator *pSvcLocator)
Gaudi::Property< float > m_default_vxTimeRes
float scoreCluster(const EventContext &ctx, const HGTD::Cluster< const xAOD::TrackParticle * > &cluster, const xAOD::Vertex *vertex) const
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_trackValidTime_key
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_trackTime_key
SG::WriteDecorHandleKey< xAOD::VertexContainer > m_vxHasTime_key
StatusCode initialize() override final
float getSumPt2OfCluster(const HGTD::Cluster< const xAOD::TrackParticle * > &cluster) const
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_trackTimeRes_key
SG::WriteDecorHandleKey< xAOD::VertexContainer > m_vxTime_key
StatusCode execute(const EventContext &ctx) const override final
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
Handle class for reading a decoration on an object.
const_pointer_type cptr()
Dereference the pointer.
Handle class for adding a decoration to an object.
Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration.
@ PriVtx
Primary vertex.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
#define unlikely(x)