ATLAS Offline Software
TrackTimeDefAndQualityAlg.cxx
Go to the documentation of this file.
1 
12 
14 #include "StoreGate/ReadHandle.h"
16 
17 namespace HGTD {
18 
20  ISvcLocator* pSvcLocator)
21  : AthReentrantAlgorithm(name, pSvcLocator) {}
22 
24 
26  ATH_CHECK(m_layerHasExtensionKey.initialize());
27  ATH_CHECK(m_layerClusterTimeKey.initialize());
33 
34  return StatusCode::SUCCESS;
35 }
36 
39 
40 StatusCode TrackTimeDefAndQualityAlg::execute(const EventContext& ctx) const {
41 
42  SG::ReadHandle<xAOD::TrackParticleContainer> trk_ptkl_container_handle(
44  const xAOD::TrackParticleContainer* track_particles =
45  trk_ptkl_container_handle.cptr();
46  if (not track_particles) {
48  "[TrackTimeDefAndQualityAlg] TrackParticleContainer not found, "
49  "aborting execute!");
50  return StatusCode::FAILURE;
51  }
52 
54  m_time_dec_key, ctx);
56  m_time_res_dec_key, ctx);
61 
62  for (const auto* track_ptkl : *track_particles) {
63 
64  // runs the time consistency checks
65  // if no hits are found in HGTD, returns a default time
67 
68  // check if the last hit on track was within the predefined area
69  if (lastHitIsOnLastSurface(*track_ptkl)) {
70  res.m_field |= (0b0000 << m_holes_ptrn_sft);
71  } else {
72  res.m_field |= (0b0001 << m_holes_ptrn_sft);
73  }
74 
75  // keep which of the hits associated in reco were primary hits (truth info!)
76  short prime_pattern = 0x0;
77  for (short i = 0; i < n_hgtd_layers; i++) {
78  if (res.m_hits.at(i).m_isprime) {
79  prime_pattern |= (1 << i);
80  }
81  }
82  res.m_field |= (prime_pattern << m_primes_ptrn_sft);
83 
84  // decorate the track again with this info
85  time_handle(*track_ptkl) = res.m_time;
86  timeres_handle(*track_ptkl) = res.m_resolution;
87  hasValidTime_handle(*track_ptkl) = res.m_hasValidTime;
88  summary_handle(*track_ptkl) = res.m_field;
89  }
90  return StatusCode::SUCCESS;
91 }
92 
95 
98  const xAOD::TrackParticle* track_particle) const {
99 
100  // get all available hits (see the struct Hit) in a first step
101  std::array<Hit, n_hgtd_layers> valid_hits = getValidHits(track_particle);
102 
104  result.m_hits = valid_hits;
105  result.m_field = 0x0;
106  result.m_time = m_default_time;
107  result.m_resolution = m_default_time_res;
108  result.m_hasValidTime = 0;
109 
110  short recoed_pattern = getValidPattern(valid_hits);
111  // stored the pattern of hits as retrieved from the iterative extension
112  result.m_field |= (recoed_pattern << m_recoed_ptrn_sft);
113 
114  short nhits = std::count_if(valid_hits.begin(), valid_hits.end(),
115  [](const Hit& hit) { return hit.m_isvalid; });
116  if (nhits < 2) {
117  // fill the patern with the 1 hit (or none) and return
118  result.m_field |= (recoed_pattern << m_comp_ptrn_sft);
119  result.m_time = meanTime(valid_hits);
120  result.m_resolution = trackTimeResolution(valid_hits);
121  result.m_hasValidTime = recoed_pattern ? 1 : 0;
122  return result;
123  } else if (nhits == 2) {
124  // if the deltaT cut is passed, the pattern stays the same, otherwise set
125  // to 0 as no hit passes
126  // TODO: find better way to treat this!
127  if (passesDeltaT(valid_hits)) {
128  result.m_field |= (recoed_pattern << m_comp_ptrn_sft); // stays the same
129  result.m_time = meanTime(valid_hits);
130  result.m_resolution = trackTimeResolution(valid_hits);
131  result.m_hasValidTime = 1;
132  return result;
133  } else {
134  result.m_field |= (0b0000 << m_comp_ptrn_sft); // no hit passes
135  result.m_time = m_default_time; // TODO should I just use the mean?
136  result.m_resolution = m_default_time_res;
137  return result;
138  }
139 
140  } else {
141  // for 3 or 4 hits, remove hit(s) with worst chi2 if needed
142  float chi2 = calculateChi2(valid_hits);
143  // if the chi2 is below the threshold, keep all hits
144  bool searching = chi2 > m_chi2_threshold;
145  while (searching) {
146  short remove_layer = findLayerWithBadChi2(valid_hits);
147  setLayerAsInvalid(valid_hits, remove_layer);
148  float new_chi2 = calculateChi2(valid_hits);
149  nhits = std::count_if(valid_hits.begin(), valid_hits.end(),
150  [](const Hit& hit) { return hit.m_isvalid; });
151  if (new_chi2 <= m_chi2_threshold or nhits < 3) {
152  searching = false;
153  }
154  } // while loop ended
155 
156  short chi2_rej_pattern = getValidPattern(valid_hits);
157 
158  if (nhits == 2) {
159  if (passesDeltaT(valid_hits)) {
160  result.m_field |= (chi2_rej_pattern << m_comp_ptrn_sft);
161  result.m_time = meanTime(valid_hits);
162  result.m_resolution = trackTimeResolution(valid_hits);
163  result.m_hasValidTime = 1;
164  return result;
165  } else {
166  result.m_field |= (0b0000 << m_comp_ptrn_sft); // no hit passes
167  result.m_time = m_default_time; // TODO should I just use the mean?
168  result.m_resolution = m_default_time_res;
169  return result;
170  }
171  } else {
172  // 3 or 4 hits, chi2 passed
173  result.m_field |= (chi2_rej_pattern << m_comp_ptrn_sft);
174  result.m_time = meanTime(valid_hits);
175  result.m_resolution = trackTimeResolution(valid_hits);
176  result.m_hasValidTime = 1;
177  return result;
178  }
179  }
180 }
181 
182 std::array<TrackTimeDefAndQualityAlg::Hit, n_hgtd_layers>
184  const xAOD::TrackParticle* track_particle) const {
185 
187  layerClusterTimeHandle(m_layerClusterTimeKey);
188  std::vector<float> times = layerClusterTimeHandle(*track_particle);
189 
191  layerHasExtensionHandle(m_layerHasExtensionKey);
192  std::vector<bool> has_clusters = layerHasExtensionHandle(*track_particle);
193 
195  layerClusterTruthClassHandle(m_layerClusterTruthClassKey);
196  std::vector<int> hit_classification =
197  layerClusterTruthClassHandle(*track_particle);
198 
199  std::array<Hit, n_hgtd_layers> valid_hits;
200 
201  for (size_t i = 0; i < n_hgtd_layers; i++) {
202  Hit newhit;
203  if (has_clusters.at(i)) {
204  newhit.m_time = times.at(i);
205  newhit.m_isprime = hit_classification.at(i) == 1;
206  newhit.m_isvalid = true;
207  }
208  newhit.m_layer = i;
209  valid_hits.at(i) = newhit;
210  }
211 
212  return valid_hits;
213 }
214 
216  const std::array<TrackTimeDefAndQualityAlg::Hit, n_hgtd_layers>& hits)
217  const {
218  short pattern = 0x0;
219  for (short i = 0; i < n_hgtd_layers; i++) {
220  if (hits.at(i).m_isvalid) {
221  pattern |= (1 << i);
222  }
223  }
224  return pattern;
225 }
226 
228  const std::array<Hit, n_hgtd_layers>& hits) const {
229 
230  float mean = meanTime(hits);
231 
232  float chi2 = 0.;
233  for (const auto& hit : hits) {
234  if (hit.m_isvalid) {
235  chi2 += (hit.m_time - mean) * (hit.m_time - mean) /
236  (hit.m_resolution * hit.m_resolution);
237  }
238  }
239  return chi2;
240 }
241 
243  const std::array<TrackTimeDefAndQualityAlg::Hit, n_hgtd_layers>& hits)
244  const {
245  // don't trust the user here.
246  short n_valid = std::count_if(hits.begin(), hits.end(),
247  [](const Hit& hit) { return hit.m_isvalid; });
248  if (n_valid != 2) {
249  return false;
250  }
251  // FIXME this should be doable in a simpler manner...
252  std::vector<float> times;
253  std::vector<float> res;
254  for (const auto& hit : hits) {
255  if (hit.m_isvalid) {
256  times.push_back(hit.m_time);
257  res.push_back(hit.m_resolution);
258  }
259  }
260  // pass if the distance in units of the resolution passes the cut
261  return std::abs(times.at(0) - times.at(1)) <
262  m_deltat_cut * hypot(res.at(0), res.at(1));
263 }
264 
266  const std::array<TrackTimeDefAndQualityAlg::Hit, n_hgtd_layers>& hits)
267  const {
268  float sum = 0.;
269  short n = 0;
270  for (const auto& hit : hits) {
271  if (hit.m_isvalid) {
272  sum += hit.m_time;
273  n++;
274  }
275  }
276  return n == 0 ? m_default_time.value() : sum / (float)n;
277 }
278 
280  const std::array<TrackTimeDefAndQualityAlg::Hit, n_hgtd_layers>& hits)
281  const {
282 
283  float sum = 0.;
284  for (const auto& hit : hits) {
285  if (hit.m_isvalid) {
286  sum += 1. / (hit.m_resolution * hit.m_resolution);
287  }
288  }
289  return sum == 0. ? m_default_time_res.value()
290  : static_cast<float>(std::sqrt(1. / sum));
291 }
292 
294  std::array<TrackTimeDefAndQualityAlg::Hit, n_hgtd_layers> hits) const {
295  short remove_layer = -1;
296  float local_min_chi2 = 999999;
297  for (auto& hit : hits) {
298  // "turn off" hits one after the other to test their impact on the chi2
299  bool validbuff = hit.m_isvalid;
300  hit.m_isvalid = false;
301  float local_chi2 = calculateChi2(hits);
302  hit.m_isvalid = validbuff;
303  if (local_chi2 < local_min_chi2) {
304  local_min_chi2 = local_chi2;
305  remove_layer = hit.m_layer;
306  }
307  }
308  return remove_layer;
309 }
310 
312  std::array<TrackTimeDefAndQualityAlg::Hit, n_hgtd_layers>& hits,
313  short layer) const {
314  for (auto& hit : hits) {
315  if (hit.m_layer == layer) {
316  hit.m_isvalid = false;
317  }
318  }
319 }
320 
323 
324  const Trk::TrackStates* tsos =
325  track.trackStateOnSurfaces();
326  if (not tsos) {
327  ATH_MSG_ERROR("Failed to retrieve track state on surfaces");
328  return nullptr;
329  }
330  // loop over the associated hits in ITk in reverse order, since we want to
331  // select the one closest to HGTD to start the extrapolation
332  for (auto i = tsos->rbegin(); i != tsos->rend(); ++i) {
333  const auto* curr_last_tsos = *i;
334  if (not curr_last_tsos) {
335  continue;
336  }
337  if (curr_last_tsos->type(Trk::TrackStateOnSurface::Measurement) and
338  curr_last_tsos->trackParameters() and
339  curr_last_tsos->measurementOnTrack()) {
340  return curr_last_tsos->trackParameters();
341  }
342  }
343  return nullptr;
344 }
345 
347  const xAOD::TrackParticle& track_particle) const {
348  const Trk::Track* track = track_particle.track();
349  const Trk::TrackParameters* last_hit_param = getLastHitOnTrack(*track);
350  float radius = std::hypot(last_hit_param->position().x(),
351  last_hit_param->position().y());
352  float abs_z = std::abs(last_hit_param->position().z());
353 
354  if (abs_z > 2700) {
355  return true;
356  }
357  if (radius < 350 and abs_z > 2400) {
358  return true;
359  }
360  // region 2
361  if (radius > 205 and radius < 350 and abs_z > 2100) {
362  return true;
363  }
364  // region 3
365  if (radius < 220 and abs_z > 2200) {
366  return true;
367  }
368 
369  if (radius < 140 and abs_z > 1890) {
370  return true;
371  }
372 
373  return false;
374 }
375 
376 } // namespace HGTD
mergePhysValFiles.pattern
pattern
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:26
HGTD::TrackTimeDefAndQualityAlg::execute
virtual StatusCode execute(const EventContext &ctx) const override final
Definition: TrackTimeDefAndQualityAlg.cxx:40
mean
void mean(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")
Definition: dependence.cxx:254
get_generator_info.result
result
Definition: get_generator_info.py:21
HGTD::TrackTimeDefAndQualityAlg::initialize
virtual StatusCode initialize() override final
Definition: TrackTimeDefAndQualityAlg.cxx:23
HGTD::TrackTimeDefAndQualityAlg::passesDeltaT
bool passesDeltaT(const std::array< Hit, n_hgtd_layers > &hits) const
Checks two hits for time compatibility.
Definition: TrackTimeDefAndQualityAlg.cxx:242
SG::ReadHandle::cptr
const_pointer_type cptr()
Dereference the pointer.
HGTD::TrackTimeDefAndQualityAlg::Hit::m_isvalid
bool m_isvalid
Definition: TrackTimeDefAndQualityAlg.h:108
Trk::Track
The ATLAS Track class.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/Track.h:73
HGTD::TrackTimeDefAndQualityAlg::setLayerAsInvalid
void setLayerAsInvalid(std::array< Hit, n_hgtd_layers > &hits, short layer) const
Given a layer number, the hit sitting on this layer is flagged as invalid.
Definition: TrackTimeDefAndQualityAlg.cxx:311
Trk::ParametersBase::position
const Amg::Vector3D & position() const
Access method for the position.
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
HGTD::TrackTimeDefAndQualityAlg::lastHitIsOnLastSurface
bool lastHitIsOnLastSurface(const xAOD::TrackParticle &track_particle) const
Checks if the last hit on track was found on a pre-specified set of Pixel and Strip layers close to t...
Definition: TrackTimeDefAndQualityAlg.cxx:346
HGTD::TrackTimeDefAndQualityAlg::findLayerWithBadChi2
short findLayerWithBadChi2(std::array< Hit, n_hgtd_layers > hits) const
Identifies time outliers by finding the layer within which a hit contributes negatively to the overal...
Definition: TrackTimeDefAndQualityAlg.cxx:293
HGTD::TrackTimeDefAndQualityAlg::m_layerClusterTruthClassKey
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_layerClusterTruthClassKey
Definition: TrackTimeDefAndQualityAlg.h:85
HGTD::TrackTimeDefAndQualityAlg::Hit::m_resolution
float m_resolution
Definition: TrackTimeDefAndQualityAlg.h:106
HGTD::TrackTimeDefAndQualityAlg::m_hasValidTime_dec_key
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_hasValidTime_dec_key
Definition: TrackTimeDefAndQualityAlg.h:95
TrackTimeDefAndQualityAlg.h
HGTD::TrackTimeDefAndQualityAlg::getLastHitOnTrack
const Trk::TrackParameters * getLastHitOnTrack(const Trk::Track &track) const
Definition: TrackTimeDefAndQualityAlg.cxx:322
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
SG::ReadDecorHandle
Handle class for reading a decoration on an object.
Definition: StoreGate/StoreGate/ReadDecorHandle.h:94
HGTD
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration.
Definition: Clustering.h:28
HGTD::TrackTimeDefAndQualityAlg::trackTimeResolution
float trackTimeResolution(const std::array< Hit, n_hgtd_layers > &hits) const
Calculates the combined resolution.
Definition: TrackTimeDefAndQualityAlg.cxx:279
lumiFormat.i
int i
Definition: lumiFormat.py:92
beamspotman.n
n
Definition: beamspotman.py:731
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
LArG4ShowerLibProcessing.hits
hits
Definition: LArG4ShowerLibProcessing.py:136
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
SG::WriteDecorHandle
Handle class for adding a decoration to an object.
Definition: StoreGate/StoreGate/WriteDecorHandle.h:99
HGTD::TrackTimeDefAndQualityAlg::m_summarypattern_dec_key
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_summarypattern_dec_key
Definition: TrackTimeDefAndQualityAlg.h:98
HGTD::TrackTimeDefAndQualityAlg::getValidPattern
short getValidPattern(const std::array< Hit, n_hgtd_layers > &hits) const
Returns the pattern of valid hits in HGTD as a 4-bit bitfield, where a 1 encodes that a valid hit was...
Definition: TrackTimeDefAndQualityAlg.cxx:215
res
std::pair< std::vector< unsigned int >, bool > res
Definition: JetGroupProductTest.cxx:14
WriteDecorHandle.h
Handle class for adding a decoration to an object.
chi2
double chi2(TH1 *h0, TH1 *h1)
Definition: comparitor.cxx:522
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
HGTD::TrackTimeDefAndQualityAlg::getValidHits
std::array< Hit, n_hgtd_layers > getValidHits(const xAOD::TrackParticle *track_particle) const
Definition: TrackTimeDefAndQualityAlg.cxx:183
Trk::ParametersBase
Definition: ParametersBase.h:55
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
DataVector< xAOD::TrackParticle_v1 >
HGTD::TrackTimeDefAndQualityAlg::Hit
Definition: TrackTimeDefAndQualityAlg.h:104
HGTD::TrackTimeDefAndQualityAlg::calculateChi2
float calculateChi2(const std::array< Hit, n_hgtd_layers > &hits) const
Calculates the chi2 of the hit times given their resolution.
Definition: TrackTimeDefAndQualityAlg.cxx:227
HGTD::TrackTimeDefAndQualityAlg::runTimeConsistencyCuts
CleaningResult runTimeConsistencyCuts(const xAOD::TrackParticle *track_particle) const
Definition: TrackTimeDefAndQualityAlg.cxx:97
HGTD::TrackTimeDefAndQualityAlg::meanTime
float meanTime(const std::array< Hit, n_hgtd_layers > &hits) const
Calculates the arithmetic mean of the valid hit times;.
Definition: TrackTimeDefAndQualityAlg.cxx:265
HGTD::TrackTimeDefAndQualityAlg::m_default_time_res
FloatProperty m_default_time_res
Definition: TrackTimeDefAndQualityAlg.h:131
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
HGTD::TrackTimeDefAndQualityAlg::m_deltat_cut
FloatProperty m_deltat_cut
Definition: TrackTimeDefAndQualityAlg.h:123
HGTD::TrackTimeDefAndQualityAlg::m_layerClusterTimeKey
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_layerClusterTimeKey
Definition: TrackTimeDefAndQualityAlg.h:81
HGTD::TrackTimeDefAndQualityAlg::m_comp_ptrn_sft
const short m_comp_ptrn_sft
Definition: TrackTimeDefAndQualityAlg.h:63
HGTD::TrackTimeDefAndQualityAlg::Hit::m_layer
short m_layer
Definition: TrackTimeDefAndQualityAlg.h:109
HGTD::TrackTimeDefAndQualityAlg::m_default_time
FloatProperty m_default_time
Definition: TrackTimeDefAndQualityAlg.h:126
ParticleGun_SamplingFraction.radius
radius
Definition: ParticleGun_SamplingFraction.py:96
HGTD::TrackTimeDefAndQualityAlg::Hit::m_isprime
bool m_isprime
Definition: TrackTimeDefAndQualityAlg.h:107
HGTD::TrackTimeDefAndQualityAlg::m_trackParticleContainerKey
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_trackParticleContainerKey
Definition: TrackTimeDefAndQualityAlg.h:74
HGTD::TrackTimeDefAndQualityAlg::m_time_dec_key
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_time_dec_key
Definition: TrackTimeDefAndQualityAlg.h:90
SG::WriteDecorHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
HGTD::TrackTimeDefAndQualityAlg::m_holes_ptrn_sft
const short m_holes_ptrn_sft
Definition: TrackTimeDefAndQualityAlg.h:64
HGTD::TrackTimeDefAndQualityAlg::TrackTimeDefAndQualityAlg
TrackTimeDefAndQualityAlg(const std::string &name, ISvcLocator *pSvcLocator)
Definition: TrackTimeDefAndQualityAlg.cxx:19
HGTD::TrackTimeDefAndQualityAlg::m_time_res_dec_key
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_time_res_dec_key
Definition: TrackTimeDefAndQualityAlg.h:92
HGTD::TrackTimeDefAndQualityAlg::m_primes_ptrn_sft
const short m_primes_ptrn_sft
Definition: TrackTimeDefAndQualityAlg.h:65
HGTD::TrackTimeDefAndQualityAlg::Hit::m_time
float m_time
Definition: TrackTimeDefAndQualityAlg.h:105
ReadDecorHandle.h
Handle class for reading a decoration on an object.
HGTD::TrackTimeDefAndQualityAlg::m_layerHasExtensionKey
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_layerHasExtensionKey
Definition: TrackTimeDefAndQualityAlg.h:78
HGTD::TrackTimeDefAndQualityAlg::m_recoed_ptrn_sft
const short m_recoed_ptrn_sft
Definition: TrackTimeDefAndQualityAlg.h:61
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
xAOD::TrackParticle_v1::track
const Trk::Track * track() const
Returns a pointer (which can be NULL) to the Trk::Track which was used to make this TrackParticle.
Definition: TrackParticle_v1.cxx:805
ReadHandle.h
Handle class for reading from StoreGate.
HGTD::TrackTimeDefAndQualityAlg::CleaningResult
Definition: TrackTimeDefAndQualityAlg.h:112
readCCLHist.float
float
Definition: readCCLHist.py:83
Trk::TrackStateOnSurface::Measurement
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
Definition: TrackStateOnSurface.h:101
HGTD::TrackTimeDefAndQualityAlg::m_chi2_threshold
FloatProperty m_chi2_threshold
Definition: TrackTimeDefAndQualityAlg.h:120
plot_times.times
def times(fn)
Definition: plot_times.py:11