ATLAS Offline Software
TrackTruthMatchingBaseAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
5 
9 
10 // for pdg_id -> name
11 #include "HepPDT/ParticleDataTable.hh"
12 
13 #include <iomanip>
14 #include <cmath>
15 #include <type_traits>
16 #include <typeinfo>
17 #include <numeric>
18 
19 namespace {
20  template <typename T_EnumClass >
21  constexpr typename std::underlying_type<T_EnumClass>::type to_underlying(T_EnumClass an_enum) {
22  return static_cast<typename std::underlying_type<T_EnumClass>::type>(an_enum);
23  }
24 
25  template <typename T, std::size_t N>
26  void accumulateTo(typename std::vector<std::array<T,N> >::const_iterator src_begin,
27  typename std::vector<std::array<T,N> >::const_iterator src_end,
28  std::array<T,N> &dest) {
29  for (typename std::vector<std::array<T,N> >::const_iterator src_iter = src_begin;
30  src_iter != src_end;
31  ++src_iter) {
32  for (unsigned int elm_i=0; elm_i<dest.size(); ++elm_i) {
33  assert( elm_i < src_iter->size() );
34  dest[elm_i] += (*src_iter)[elm_i];
35  }
36  }
37  }
38 
39  template <typename T, bool LastRowOnly=false>
40  void accumulateToLastColumnRow(std::size_t n_rows, std::size_t n_cols, std::vector<T> &stat) {
41  assert(n_cols > 0);
42  assert(n_rows > 0);
43  auto stat_begin_iter = stat.begin();
44  if (n_rows>1) {
45  auto stat_total_row_begin_iter = stat.begin() + (n_rows-1) * n_cols;
46  assert( static_cast<std::size_t>(stat_total_row_begin_iter - stat_begin_iter) < stat.size());
47 
48  for (std::size_t row_i = 0; row_i < n_rows-1; ++row_i) {
49  auto stat_end_iter = stat_begin_iter + n_cols - 1 ;
50  assert(static_cast<std::size_t>(stat_end_iter - stat.begin()) < stat.size());
51  auto stat_total_row_iter = stat_total_row_begin_iter;
52  if constexpr(!LastRowOnly) {
53  accumulateTo(stat_begin_iter, stat_end_iter, *stat_end_iter );
54  }
55 
56  ++stat_end_iter; // now also consider the total eta bin.
57  for (; stat_begin_iter != stat_end_iter; ++stat_begin_iter, ++stat_total_row_iter) {
58  assert(static_cast<std::size_t>(stat_begin_iter - stat.begin()) < stat.size());
59  assert(static_cast<std::size_t>(stat_total_row_iter - stat.begin()) < stat.size());
60  for (unsigned int idx=0; idx < stat_total_row_iter->size(); ++idx) {
61  stat_total_row_iter->at(idx) += stat_begin_iter->at(idx);
62  }
63  }
64  }
65  }
66  else if constexpr(!LastRowOnly) {
67  auto stat_end_iter = stat_begin_iter + n_cols - 1 ;
68  accumulateTo(stat_begin_iter, stat_end_iter, *stat_end_iter );
69  }
70  }
71 
72  template <typename T>
73  void accumulateToLastRow(std::size_t n_rows, std::size_t n_cols, std::vector<T> &stat) {
74  accumulateToLastColumnRow<T,true>(n_rows, n_cols, stat);
75  }
76 
77  template <typename T, std::size_t N>
78  void addStat(const std::vector<std::array<T,N> > &src, std::vector<std::array<T,N> > &dest) {
79  assert( src.size() == dest.size());
80  unsigned int idx=0;
81  for (const std::array<T,N> &src_elm : src) {
82  assert( idx < dest.size());
83  std::array<T,N> &dest_elm = dest[idx];
84  unsigned val_i=0;
85  for (const T &val : src_elm) {
86  assert( val_i < dest_elm.size());
87  dest_elm[val_i] += val;
88  ++val_i;
89  }
90  ++idx;
91  }
92  }
93 
94  inline double sqr(double a) { return a*a; }
95  // computate ratio and its statistical uncertainty
96  inline std::array<float, 2> computeRatio(unsigned int numerator_counts, unsigned int denominator_counts) {
97  double inv_denominator_counts = denominator_counts > 0 ? 1./denominator_counts : 0.;
98  return std::array<float, 2> {
99  static_cast<float>(numerator_counts * inv_denominator_counts),
100  static_cast<float>(sqrt( numerator_counts * (denominator_counts-numerator_counts)
101  * inv_denominator_counts * sqr(inv_denominator_counts) ))
102  };
103  }
104 
105  std::string hfill(const std::string &head, const std::string &tail, std::size_t width) {
106  width=std::max(width, head.size() + tail.size()) - head.size() - tail.size();
107  std::stringstream out;
108  out << head << std::setw(width) << " " << tail;
109  return out.str();
110 
111  }
112 
113  std::string dumpCounts(const ActsTrk::HitCounterArray &counts) {
114  std::stringstream out;
115  for (uint8_t val : counts) {
116  out << " " << std::setw(2) << static_cast<int>(val);
117  }
118  return out.str();
119  }
120 }
121 namespace ActsTrk
122 {
123  // to dump
124  inline MsgStream &operator<<(MsgStream &out, const ActsUtils::Stat &stat) {
126  return out;
127  }
128 
130  ISvcLocator *pSvcLocator)
131  : AthReentrantAlgorithm(name, pSvcLocator)
132  {
133  }
134 
136  {
137  ATH_CHECK( m_truthSelectionTool.retrieve());
139  initStatTables();
140  return checkMatchWeights();
141  }
142 
143  template <bool IsDebug>
144  template <class T_OutStream>
146  if constexpr(IsDebug) {
147  out << "Weighted measurement sum per truth particle without associated counts :" << m_measPerTruthParticleWithoutCounts << std::endl
148  << m_measPerTruthParticleWithoutCounts.histogramToString() << std::endl
149  << "Match probability of best match :" << m_bestMatchProb << std::endl
150  << m_bestMatchProb.histogramToString() << std::endl
151  << "Match probability of next-to-best match :" << m_nextToBestMatchProb << std::endl
152  << m_nextToBestMatchProb.histogramToString() << std::endl;
153  }
154  }
155 
156  template <bool IsDebug>
158  if constexpr(IsDebug) {
159  std::lock_guard<std::mutex> lock(m_mutex);
160  m_measPerTruthParticleWithoutCounts.add(weighted_measurement_sum);
161  }
162  }
163  template <bool IsDebug>
164  inline void TrackTruthMatchingBaseAlg::DebugCounter<IsDebug>::fillTruthMatchProb(const std::array<float,2> &best_match_prob) const {
165  if constexpr(IsDebug) {
166  std::lock_guard<std::mutex> lock(m_mutex);
167  m_bestMatchProb.add(best_match_prob[0]);
168  m_nextToBestMatchProb.add(best_match_prob[1]);
169  }
170  }
171 
172 
174  {
175  if (msgLvl(MSG::INFO)) {
176  if constexpr(TrackFindingValidationDebugHists) {
178  }
179  msg(MSG::INFO) << "Truth selection cuts: " << std::endl;
180  unsigned int cut_i=0;
181  std::size_t total = std::accumulate ( m_detailedStat.m_truthSelectionCuts.m_histogram.begin(),
182  m_detailedStat.m_truthSelectionCuts.m_histogram.end(), 0u);
183  msg() << std::setw(3) << "" << " " << std::setw(20) << total << " total" << std::endl;
184  if (m_detailedStat.m_truthSelectionCuts.m_histogram.at(cut_i) > 0) {
185  msg() << std::setw(3) << "" << " "
186  << std::setw(20) << (total - m_detailedStat.m_truthSelectionCuts.m_histogram.at(cut_i))
187  << " underflow" << std::endl;
188  }
189  total -= m_detailedStat.m_truthSelectionCuts.m_histogram.at(cut_i++);
190  for (const std::string &name : m_truthSelectionTool->names()) {
191  total -= m_detailedStat.m_truthSelectionCuts.m_histogram.at(cut_i);
192  msg() << std::setw(3) << cut_i << " " << std::setw(20) << total << " " << name << std::endl;
193  ++cut_i;
194  }
195  total -= m_detailedStat.m_truthSelectionCuts.m_histogram.at(cut_i);
196  if (total>0) {
197  msg() << std::setw(3) << "" << " " << std::setw(20) << total << " overflow" << std::endl;
198  }
199  if (msgLvl(MSG::DEBUG)) {
200  msg() << m_detailedStat.m_truthSelectionCuts.histogramToString();
201  }
202  msg() << endmsg;
203  }
204  printStatTables();
205  return StatusCode::SUCCESS;
206  }
207 
210  const HitCountsPerTrack &track_hit_counts,
211  TrackTruthMatchingBaseAlg::EventStat &event_stat) const
212  {
213  TruthMatchResult ret{};
214  std::array<unsigned int,2> best_match_i{std::numeric_limits<unsigned int>::max(),std::numeric_limits<unsigned int>::max()};
215  std::array<float,2> best_match_prob {};
216 
217  std::array<unsigned int,2> best_match_i_nonoise{std::numeric_limits<unsigned int>::max(),std::numeric_limits<unsigned int>::max()};
218  std::array<float,2> best_match_prob_nonoise{};
219 
220  const HitCounterArray &total_counts = track_hit_counts.totalCounts();
221  const HitCounterArray &noise_counts = track_hit_counts.noiseCounts();
222 
223  double total_sum=weightedCountSum(total_counts, m_weights.value() );
224  double total_sum_for_prob=weightedCountSum(total_counts, m_weightsForProb.value() );
225  double noise_sum=noiseCorrection(noise_counts, m_weightsForProb.value() );
226  double total_sum_for_prob_nonoise=total_sum_for_prob;
227  total_sum_for_prob += noise_sum;
228 
229  if (total_sum_for_prob>0.) {
230  // compute total hit count per truth particle and remember the highest and second highest
231  // count per truth particle.
232  // The match probability is then max_counter / sum_{i in associated truth particles} counts_i
233  unsigned int truth_i=0;
234  --truth_i;
235  for (const std::pair<const xAOD::TruthParticle *, HitCounterArray > &
236  hit_counts_for_associated_truth_particle : track_hit_counts.countsPerTruthParticle() ) {
237  ++truth_i;
238  double truth_sum_for_prob=weightedCountSum(hit_counts_for_associated_truth_particle.second, m_weightsForProb.value() );
239  float match_prob_nonoise = truth_sum_for_prob /total_sum_for_prob_nonoise;
240  float match_prob = truth_sum_for_prob /total_sum_for_prob;
241  if (match_prob>1 || match_prob<0.) {
242  ATH_MSG_ERROR("Negative or too large truth match \"probability\". This should not happen."
243  << " Track hits: " << dumpCounts(total_counts)
244  << " noise hits of those: " << dumpCounts(noise_counts)
245  << " truth hits: " << dumpCounts(hit_counts_for_associated_truth_particle.second));
246  } // remember the highest and next-to-highest hit count per truth particle
247  if (match_prob>best_match_prob[1]) {
248  int dest_i=match_prob<best_match_prob[0];
249  best_match_i[1]=best_match_i[0];
250  best_match_prob[1]=best_match_prob[0];
251  best_match_prob[dest_i]=match_prob;
252  best_match_i[dest_i]=truth_i;
253  }
254  if (match_prob_nonoise>best_match_prob_nonoise[1]) {
255  int dest_i=match_prob_nonoise<best_match_prob_nonoise[0];
256  best_match_i_nonoise[1]=best_match_i_nonoise[0];
257  best_match_prob_nonoise[1]=best_match_prob_nonoise[0];
258  best_match_prob_nonoise[dest_i]=match_prob_nonoise;
259  best_match_i_nonoise[dest_i]=truth_i;
260  }
261 
262  }
263  }
264 
265  if (best_match_i_nonoise[0] != best_match_i[0]) {
267  }
268  if ( best_match_i[0] < track_hit_counts.countsPerTruthParticle().size()
269  && track_hit_counts.countsPerTruthParticle()[ best_match_i[0] ].first) {
270  ret.m_truthParticle = track_hit_counts.countsPerTruthParticle()[ best_match_i[0] ].first;
271  ret.m_matchProbability = best_match_prob[0];
272 
273  const xAOD::TruthParticle *best_match = track_hit_counts.countsPerTruthParticle()[ best_match_i[0] ].first;
274  const IAthSelectionTool::CutResult accept = m_truthSelectionTool->accept(best_match);
275  event_stat.m_truthSelectionCuts.add( event_stat.m_nTruthCuts - accept.missingCuts() );
276  if (accept) {
277 
278  double common_truth_sum=weightedCountSum(track_hit_counts.countsPerTruthParticle()[ best_match_i[0] ].second, m_weights.value() );
279 
280  float hit_efficiency = 0.;
281  std::unordered_map<const xAOD::TruthParticle *,HitCounterArray>::const_iterator
282  best_truth_particle_counts_iter = truth_particle_hit_counts.find( best_match );
283 
284  if (best_truth_particle_counts_iter != truth_particle_hit_counts.end()) {
285  double truth_sum=weightedCountSum(best_truth_particle_counts_iter->second, m_weights.value() );
286  // in principle truth_measuremnts should always be larger than 0
287  hit_efficiency = truth_sum > 0u ? (common_truth_sum/truth_sum) : 0.;
288  }
289  else {
290  // this can happen if the total number of hits are below threshold for
291  // accepting a truth particle
294  }
295 
296  // in principle a track matched to a truth particle should always have n_total > 0
297  // but the hits could be filtered out.
298  if (total_sum>0.) {
299  float hit_purity = common_truth_sum / total_sum;
300  ret.m_hitPurity = hit_purity;
301  ret.m_hitEfficiency = hit_efficiency;
302  m_debugCounter.fillTruthMatchProb(best_match_prob);
303 
304  if constexpr(TrackFindingValidationDetailedStat) {
305  float best_match_pt = best_match->pt();
306  std::size_t eta_category_i = getPtEtaStatCategory(best_match_pt, best_match->eta());
307  std::size_t pdg_id_category_i = getPtPdgIdStatCategory(best_match_pt, best_match->pdg_id());
308  event_stat.fill( eta_category_i, pdg_id_category_i, hit_efficiency, hit_purity, best_match_prob[0], best_match );
309  }
310  }
311  }
312  else {
314  }
315  }
316  else {
317  // no eta, pdg_id for tracks without associated truth particle
318  // could use eta of track but not available to the algorithm
319 
321  if (!track_hit_counts.countsPerTruthParticle().empty()) {
322  ATH_MSG_ERROR("Failed to select best matching truth particle out of " << track_hit_counts.countsPerTruthParticle().size()
323  << ". This should not happen." );
324  }
325  }
326  return ret;
327  }
328 
329 
330 
332  std::size_t n_tracks,
333  TrackTruthMatchingBaseAlg::EventStat &event_stat) const
334  {
335  if constexpr(EventStat::doDetail) {
336  if (m_computeTrackRecoEfficiency.value()) {
337  for(const std::pair<const xAOD::TruthParticle * const,ActsTrk::HitCounterArray> &truth_particle : truth_particle_hit_counts) {
338  const IAthSelectionTool::CutResult accept = m_truthSelectionTool->accept(truth_particle.first);
339  if (accept) {
340  double truth_sum=weightedCountSum(truth_particle.second, m_weights.value() );
341  if (truth_sum>0.) {
342  float truth_particle_pt = truth_particle.first->pt();
343  std::size_t eta_category_i = getPtEtaStatCategory(truth_particle_pt, truth_particle.first->eta());
344  std::size_t pdg_id_category_i = getPtPdgIdStatCategory(truth_particle_pt, truth_particle.first->pdg_id());
345  event_stat.incrementTotal(eta_category_i, pdg_id_category_i);
346  }
347  }
348  }
349  }
350  }
351 
352  // update total statistic counter
353  {
354  std::lock_guard<std::mutex> lock(m_statMutex);
359  m_counter[NTracksTotal]+=n_tracks;
360  m_counter[NTruthWithCountsTotal]+=truth_particle_hit_counts.size();
361 
362  if constexpr(EventStat::doDetail) {
363  m_detailedStat += event_stat;
364  }
365  }
366  }
367 
368  inline std::size_t TrackTruthMatchingBaseAlg::getPtEtaStatCategory(float pt, float eta) const
369  {
370  std::vector<float>::const_iterator pt_bin_iter = std::upper_bound(m_statPtBins.begin(),
371  m_statPtBins.end(),
372  pt);
373  std::vector<float>::const_iterator eta_bin_iter = std::upper_bound(m_statEtaBins.begin(),
374  m_statEtaBins.end(),
375  m_useAbsEtaForStat ? std::abs(eta) : eta);
376  return (m_statEtaBins.size()+2u) * static_cast<std::size_t>(pt_bin_iter - m_statPtBins.begin())
377  + static_cast<std::size_t>(eta_bin_iter - m_statEtaBins.begin());
378  }
379  std::size_t TrackTruthMatchingBaseAlg::getPtPdgIdStatCategory(float pt, int pdg_id) const {
380  std::vector<float>::const_iterator pt_bin_iter = std::upper_bound(m_statPtBins.begin(),
381  m_statPtBins.end(),
382  pt);
383  int abs_pdg_id = std::min(std::abs(pdg_id), s_pdgIdMax);
384  std::vector< int >::const_iterator iter = std::find(m_pdgId.begin(), m_pdgId.end(), abs_pdg_id);
385  if (iter == m_pdgId.end()){
386  if (m_pdgId.size() < m_pdgId.capacity()) {
387  std::lock_guard<std::mutex> lock(m_statMutex); // @TODO pdg id list specific mutex ?
388  // make sure that the pdg id still does not exist.
389  iter = std::find(m_pdgId.begin(), m_pdgId.end(), abs_pdg_id);
390  if (iter == m_pdgId.end()){
391  m_pdgId.push_back(abs_pdg_id);
392  iter = m_pdgId.end()-1;
393  }
394  }
395  else {
396  iter=m_pdgId.begin();
397  }
398  }
399  return (m_pdgId.capacity()) * static_cast<std::size_t>(pt_bin_iter - m_statPtBins.begin())
400  + (iter - m_pdgId.begin());
401  }
402 
403  void TrackTruthMatchingBaseAlg::checkBinOrder( const std::vector<float> &bin_edges, const std::string &bin_label) const {
404  if (!bin_edges.empty())
405  {
406  float last_eta = bin_edges[0];
407  for (float eta : bin_edges)
408  {
409  if (eta < last_eta)
410  {
411  ATH_MSG_FATAL(bin_label + " bins for statistics counter not in ascending order.");
412  }
413  last_eta = eta;
414  }
415  }
416  }
418  {
419  if (!m_statEtaBins.empty())
420  {
421  m_useAbsEtaForStat = (m_statEtaBins[0] > 0.);
422  checkBinOrder(m_statEtaBins.value(),"Eta");
423  }
424  checkBinOrder(m_statPtBins.value(),"Pt");
425 
426 
427  unsigned int max_pdg_id_slots=( m_pdgIdCategorisation.value() ? 20 : 1 );
428 
429  // last element in statPerEta and counterPerEta will be used accumulate statistics of all eta bins
430  m_detailedStat.reset( *m_truthSelectionTool,
431  (m_statPtBins.size() + 2) * (m_statEtaBins.size() + 2),
432  (m_statPtBins.size() + 2) * max_pdg_id_slots);
433 
434  m_pdgId.reserve(max_pdg_id_slots);
435  m_pdgId.push_back(1000000000);
436  }
437 
438  template <bool DetailEnabled>
441  if constexpr(DetailEnabled) {
442  addStat(event_stat.m_counterPerEta,m_counterPerEta);
443  addStat(event_stat.m_statPerEta, m_statPerEta);
444  addStat(event_stat.m_counterPerPdgId,m_counterPerPdgId);
445  addStat(event_stat.m_statPerPdgId, m_statPerPdgId);
446  }
447  m_truthSelectionCuts += event_stat.m_truthSelectionCuts;
448  return *this;
449  }
450 
451  template <bool DetailEnabled>
453  const std::vector<float> &statPtBins,
454  const std::vector<float> &statEtaBins,
455  std::vector< int > &pdgId,
456  bool printDetails,
457  bool pdgIdCategorisation,
458  bool useAbsEtaForStat) {
459  if constexpr(DetailEnabled) {
460  static constexpr bool rotate=true;// row : eta/PDG ID; column: pt
461  std::vector<std::string> counter_labels { std::string("Truth particles"),
462  std::string("with asso. track"),
463  std::string("with >1 asso. tracks"),
464  std::string("total tracks")};
465  std::vector<std::string> pt_labels;
466  pt_labels.reserve(statPtBins.size() + 2);
467  unsigned int pt_precision=0;
468  for (float pt : statPtBins) {
469  if (pt<1.) {
470  pt_precision=1;
471  break;
472  }
473  }
474  for (std::size_t bin_i = 0; bin_i < statPtBins.size() + 2; ++bin_i) {
475  pt_labels.push_back(TableUtils::makeBinLabel("pt",statPtBins, bin_i, true, pt_precision));
476  }
477  // statistics eta-bins
478  {
479  std::vector<std::string> eta_labels;
480  eta_labels.reserve(statEtaBins.size() + 2);
481  for (std::size_t eta_bin_i = 0; eta_bin_i < statEtaBins.size() + 2; ++eta_bin_i) {
482  eta_labels.push_back(TableUtils::makeEtaBinLabel(statEtaBins, eta_bin_i, useAbsEtaForStat));
483  }
484 
485  accumulateToLastColumnRow(statPtBins.size()+2,statEtaBins.size()+2, m_statPerEta);
486  accumulateToLastColumnRow(statPtBins.size()+2,statEtaBins.size()+2, m_counterPerEta);
487 
488  if (statPtBins.empty() || printDetails) {
489  parent.printCategories(pt_labels, eta_labels, counter_labels, m_statPerEta, m_counterPerEta,
490  (!statPtBins.empty()
491  ? hfill("pt ",
492  "eta",
493  TableUtils::maxLabelWidth(pt_labels)
494  +TableUtils::maxLabelWidth(eta_labels))
495  : std::string("eta") ),
496  !statPtBins.empty());
497  }
498  if (!statPtBins.empty()) {
499  parent.printData2D(pt_labels, eta_labels,
500  rotate
501  ? hfill("eta","\\ pt", TableUtils::maxLabelWidth(eta_labels))
502  : hfill("pt","\\ eta", TableUtils::maxLabelWidth(pt_labels)),
503  m_statPerEta,
504  m_counterPerEta,
505  rotate);
506  }
507  }
508 
509  // statistics in PDG ID bins.
510  if (pdgIdCategorisation) {
511  std::vector<std::string> pdg_id_labels;
512  pdg_id_labels.reserve( pdgId.size());
513  pdg_id_labels.push_back("Other");
514  for (unsigned int pdg_i=1; pdg_i < pdgId.size(); ++pdg_i) {
515  std::stringstream a_label;
516  a_label << HepPID::particleName(pdgId[pdg_i]) << " [" << pdgId[pdg_i] << "]";
517  pdg_id_labels.push_back( a_label.str() );
518  }
519  unsigned int max_pdg_id_slots=m_statPerPdgId.size()/(statPtBins.size()+2);
520  assert( m_statPerPdgId.size() % (statPtBins.size()+2) == 0 );
521  // also the unused columns are projected, but that does not harm :
522  accumulateToLastRow(statPtBins.size()+2,max_pdg_id_slots, m_statPerPdgId);
523  accumulateToLastRow(statPtBins.size()+2,max_pdg_id_slots, m_counterPerPdgId);
524 
525  if (statPtBins.empty() || printDetails) {
526  parent.printCategories(pt_labels, pdg_id_labels, counter_labels, m_statPerPdgId, m_counterPerPdgId,
527  (!statPtBins.empty()
528  ? hfill("pt ",
529  "PDG-id",
530  TableUtils::maxLabelWidth(pt_labels)
531  +TableUtils::maxLabelWidth(pdg_id_labels))
532  : std::string("eta")),
533  !statPtBins.empty());
534  }
535  if (!statPtBins.empty()) {
536  parent.printData2D(pt_labels, pdg_id_labels,
537  rotate
538  ? hfill("PDG ID","\\ pt", TableUtils::maxLabelWidth(pdg_id_labels))
539  : hfill("pt","\\ PDG ID", TableUtils::maxLabelWidth(pt_labels)),
540  m_statPerPdgId,
541  m_counterPerPdgId,
542  rotate);
543  }
544  }
545  }
546  }
547 
549  {
550  if (msgLvl(MSG::INFO))
551  {
552  msg() << MSG::INFO << std::endl;
553  m_detailedStat.printStatTables( *this, m_statPtBins, m_statEtaBins, m_pdgId, m_printDetails.value(), m_pdgIdCategorisation.value(), m_useAbsEtaForStat );
554  {
555  std::array<std::string, kNCounter> counter_labels { std::string("Number of tracks"),
556  std::string("Number of truth particles with hit counts"),
557  std::string("Associated truth particles without hit counts"),
558  std::string("Tracks without associated truth particle"),
559  std::string("Tracks without selected, associated truth particle"),
560  std::string("Best truth particle without noise correction mismatch")
561  };
562  msg() << makeTable( m_counter, counter_labels) << std::endl;
563  }
564  msg() << endmsg;
565  }
566  }
567 
568 
569 
570  void TrackTruthMatchingBaseAlg::printCategories(const std::vector<std::string> &row_category_labels,
571  const std::vector<std::string> &col_category_labels,
572  std::vector<std::string> &counter_labels,
573  std::vector< std::array< ActsUtils::Stat, kNCategorisedStat> > &stat_per_category,
574  std::vector< std::array< std::size_t, kNCategorisedCounter> > &counts_per_category,
575  const std::string &top_left,
576  bool print_sub_categories) const {
577  if (!row_category_labels.empty() && !col_category_labels.empty()) {
578  if (row_category_labels.size() * col_category_labels.size() > counts_per_category.size() ) {
579  ATH_MSG_ERROR( "Mismatch between category labels and number of counters (logic error -> fix needed):"
580  << row_category_labels.size() << " * " << col_category_labels.size()
581  << " > " << counts_per_category.size() );
582  }
583  constexpr std::size_t stat_column_width=14*4 + 3*3+4 + 9; // floats + seperators + integer of Stat output
584  assert( stat_per_category.size() == counts_per_category.size());
585  const unsigned int n_rows = row_category_labels.size();
586  const unsigned int n_cols = stat_per_category.size() / n_rows; // some columns at the end of a row might not have labels
587  // and are to be ignored
588 
589  assert( stat_per_category.size() % n_rows == 0 );
590  for(unsigned int row_i=(print_sub_categories ? 0 : n_rows-1); row_i<n_rows; ++row_i) {
591  {
592  std::vector<std::string> stat_labels { std::string("Hit Efficiency") };
593  msg() << makeTable( stat_per_category, row_i*n_cols, kNCategorisedStat, kHitEfficiency, 1u, col_category_labels, stat_labels, top_left)
594  .columnWidth(stat_column_width)
595  .labelPrefix(row_category_labels.at(row_i)+" ")
596  .precision(std::vector<unsigned int>{3})
597  << std::endl;
598  }
599  {
600  std::vector<std::string> stat_labels { std::string("Hit Purity") };
601  msg() << makeTable( stat_per_category, row_i*n_cols, kNCategorisedStat, kHitPurity, 1u, col_category_labels, stat_labels, top_left)
602  .columnWidth(stat_column_width)
603  .labelPrefix(row_category_labels.at(row_i)+" ")
604  .precision(std::vector<unsigned int>{3})
605  << std::endl;
606  }
607  {
608  std::vector<std::string> stat_labels { std::string("Match probability") };
609  msg() << makeTable( stat_per_category, row_i*n_cols, kNCategorisedStat, kMatchProbability, 1u, col_category_labels, stat_labels, top_left)
610  .columnWidth(stat_column_width)
611  .labelPrefix(row_category_labels.at(row_i)+" ")
612  .precision(std::vector<unsigned int>{3})
613  << std::endl;
614  }
615  if (m_showRawCounts.value()) {
616  msg() << makeTable( counts_per_category, row_i*n_cols, kNCategorisedCounter, 0u, 1u, col_category_labels, counter_labels, top_left)
617  .labelPrefix(row_category_labels.at(row_i)+" ")
618  << std::endl;
619  }
620 
621  if (m_computeTrackRecoEfficiency.value()) {
622  std::vector< std::array< float, 2> > eff;
623  eff.reserve(m_pdgId.size());
624  for (unsigned int category_i=0; category_i< col_category_labels.size(); ++category_i) {
625  eff.push_back( computeRatio( counts_per_category[category_i+row_i*n_cols][kNParticleWithAssociatedTrack],
626  counts_per_category[category_i+row_i*n_cols][kNTotalParticles] ) );
627  }
628  std::vector<std::string> eff_labels { std::string("reco efficiency"),
629  std::string("stat. uncertainty") };
630  msg() << makeTable( eff, 0u, eff.begin()->size(),0u,1u, col_category_labels, eff_labels, top_left)
631  .labelPrefix(row_category_labels.at(row_i)+" ")
632  .precision(std::vector<unsigned int>{3,3})
633  << std::endl;
634  }
635  }
636  }
637  }
638 
639  namespace {
640  // helper to prevent temporary table data from beeing destructed too early
641  template <typename T>
642  struct TablePlusData {
643  TablePlusData(std::vector<T> &&values,
644  const std::vector<std::string> &row_labels,
645  const std::vector<std::string> &col_labels,
646  const std::string &top_left_label)
647  : m_data(std::move(values)),
648  m_assocTable({
650  row_labels.size(), // n-rows
651  col_labels.size(), // n-columns
652  col_labels.size(), // offset between rows
653  0u, // first column index
654  1u}, // offset between columns
655  TableUtils::Range<std::string> {row_labels.data(), row_labels.size()},
656  TableUtils::Range<std::string> {col_labels.data(), col_labels.size()},
657  top_left_label
658  })
659  {}
660  std::vector<T> m_data;
662  TablePlusData &columnWidth(std::size_t value) { m_assocTable.columnWidth(value); return *this;}
663  TablePlusData &minLabelWidth(std::size_t value) { m_assocTable.minLabelWidth(value); return *this;}
664  TablePlusData &dumpHeader(bool value=true) { m_assocTable.dumpHeader(value); return *this;}
665  TablePlusData &dumpFooter(bool value=true) { m_assocTable.dumpFooter(value); return *this;}
666  TablePlusData &separateLastRow(bool value=true) { m_assocTable.separateLastRow(value); return *this;}
667  TablePlusData &labelPrefix(const std::string& value) { m_assocTable.labelPrefix(value); return *this;}
668  TablePlusData &precision(std::vector<unsigned int> &&precision) { m_assocTable.precision(std::move(precision)); return *this;}
669  };
670 
671  template <typename T>
672  inline MsgStream &operator<<(MsgStream &out, const TablePlusData<T> &table) {
673  out << table.m_assocTable;
674  return out;
675  }
676 
677  template <typename T>
678  inline std::ostream &operator<<(std::ostream &out, const TablePlusData<T> &table) {
679  out << table.m_assocTable;
680  return out;
681  }
682 
683  template <class T_Container, class T_Function, typename T=double>
684  TablePlusData<T>
685  create2DTable(const std::vector<std::string> &row_category_labels,
686  const std::vector<std::string> &col_category_labels,
687  const std::string &top_left_label,
688  T_Container container,
689  T_Function function,
690  bool rotate) {
691  const unsigned int n_rows = row_category_labels.size();
692  const unsigned int n_cols = col_category_labels.size();
693  const unsigned int n_cols_total = container.size() / n_rows; // some columns at the end of a row might not have labels
694  std::vector< T > values;
695  values.reserve( n_rows * n_cols );
696  if (rotate) {
697  for (unsigned int col_i=0; col_i< n_cols; ++col_i) {
698  for (unsigned int row_i=0; row_i< n_rows; ++row_i) {
699  values.push_back( function(container.at( row_i * n_cols_total + col_i )) );
700  }
701  }
702  }
703  else {
704  for (unsigned int row_i=0; row_i< n_rows; ++row_i) {
705  for (unsigned int col_i=0; col_i< n_cols; ++col_i) {
706  values.push_back( function(container.at( row_i * n_cols_total + col_i )) );
707  }
708  }
709  }
710  return TablePlusData<T>(std::move(values),
711  rotate ? col_category_labels : row_category_labels, // rows
712  rotate ? row_category_labels : col_category_labels, // columns
713  top_left_label);
714  }
715  }
716 
717  void TrackTruthMatchingBaseAlg::printData2D(const std::vector<std::string> &row_category_labels,
718  const std::vector<std::string> &col_category_labels,
719  const std::string &top_left_label,
720  std::vector< std::array< ActsUtils::Stat, kNCategorisedStat> > &stat_per_category,
721  std::vector< std::array< std::size_t, kNCategorisedCounter> > &counts_per_category,
722  bool rotate) const
723  {
724  if (!row_category_labels.empty() && !col_category_labels.empty()) {
725  if (row_category_labels.size() * col_category_labels.size() > counts_per_category.size() ) {
726  ATH_MSG_ERROR( "Mismatch between category labels and number of counters (logic error -> fix needed):"
727  << row_category_labels.size() << " * " << col_category_labels.size()
728  << " > " << counts_per_category.size() );
729  }
730  std::vector<unsigned int> column_precision;
731  column_precision.resize( rotate ? row_category_labels.size() : col_category_labels.size(), 3u);
732  assert( stat_per_category.size() == counts_per_category.size());
733  msg() << "Hit efficiency : contributing hits over all hits of best matching truth particle" << std::endl
734  << create2DTable( row_category_labels, col_category_labels, top_left_label, stat_per_category,
735  [](const std::array< ActsUtils::Stat, kNCategorisedStat> &stat) {
736  return stat.at(kHitEfficiency).mean();
737  },
738  rotate)
739  .columnWidth(10)
740  .precision(std::vector<unsigned int>(column_precision))
741  << std::endl;
742  msg() << "Hit purity : contributing hits of best matching truth particle over all hits on track" << std::endl
743  << create2DTable( row_category_labels, col_category_labels, top_left_label, stat_per_category,
744  [](const std::array< ActsUtils::Stat, kNCategorisedStat> &stat) {
745  return stat.at(kHitPurity).mean();
746  },
747  rotate)
748  .columnWidth(10)
749  .precision(std::vector<unsigned int>(column_precision))
750  << std::endl;
751  msg() << "Match probability : weighted common hit sum of best matching truth particle over total track weighted hit sum" << std::endl
752  << create2DTable( row_category_labels, col_category_labels, top_left_label, stat_per_category,
753  [](const std::array< ActsUtils::Stat, kNCategorisedStat> &stat) {
754  return stat.at(kMatchProbability).mean();
755  },
756  rotate)
757  .columnWidth(10)
758  .precision(std::vector<unsigned int>(column_precision))
759  << std::endl;
760 
761  if (m_computeTrackRecoEfficiency.value()) {
762  msg() << "Reco efficiency : tracks with assoc. truth particle over all selected truth particles with assoc. measurements."
763  << std::endl
764  << create2DTable( row_category_labels, col_category_labels, top_left_label, counts_per_category,
765  [](const std::array< std::size_t, kNCategorisedCounter> &counter) {
768  },
769  rotate)
770  .columnWidth(10)
771  .precision(std::move(column_precision))
772  << std::endl;
773  }
774  }
775  }
776 
778  if (m_weights.size() != s_NMeasurementTypes) {
779  ATH_MSG_FATAL( "There must be exactly one weight per measurement type. But got "
780  << m_weights.size() << " != " << s_NMeasurementTypes);
781  return StatusCode::FAILURE;
782  }
783  if (m_weightsForProb.size() != s_NMeasurementTypes) {
784  ATH_MSG_FATAL( "There must be exactly one weight for computing the matching probability per measurement type. But got "
785  << m_weightsForProb.size() << " != " << s_NMeasurementTypes);
786  return StatusCode::FAILURE;
787  }
788  for (unsigned int type_i=0; type_i<s_NMeasurementTypes; ++type_i) {
789  if (m_weightsForProb[type_i]<0. || m_weights[type_i]<0. || (m_weights[type_i]>0) != (m_weightsForProb[type_i]>0.)) {
790  ATH_MSG_FATAL( "Invalid weights (should be positive) or inconsistency of weights which are zero (match prob. weights, weights):"
791  << m_weightsForProb[type_i] << " vs " << m_weights[type_i]);
792  return StatusCode::FAILURE;
793  }
794  }
795  return StatusCode::SUCCESS;
796  }
797 
799  const std::vector<float> &weights) {
800  assert( weights.size() == counts.size());
801  double sum=0.;
802  for (unsigned int count_i=0; count_i < counts.size(); ++count_i) {
803  sum += counts[count_i] * weights[count_i];
804  }
805  return sum;
806  }
807 
809  const std::vector<float> &weights) {
810  assert( weights.size() == noise_counts.size());
811  double sum=0.;
812  for (unsigned int count_i=0; count_i < noise_counts.size(); ++count_i) {
813  sum -= weights[count_i] * noise_counts[count_i] - noise_counts[count_i];
814  }
815  return sum;
816  }
817 }
ActsTrk::TrackTruthMatchingBaseAlg::postProcessEventStat
void postProcessEventStat(const TruthParticleHitCounts &truth_particle_hit_counts, std::size_t n_tracks, EventStat &event_stat) const
Definition: TrackTruthMatchingBaseAlg.cxx:331
m_assocTable
TableUtils::MultiColumnTable< T > m_assocTable
Definition: TrackTruthMatchingBaseAlg.cxx:661
ActsTrk::TrackTruthMatchingBaseAlg::EventStatBase::m_nTruthCuts
unsigned int m_nTruthCuts
Definition: TrackTruthMatchingBaseAlg.h:127
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
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
ActsTrk::TrackTruthMatchingBaseAlg::TruthMatchResult
Match result returned by analyseTrackTruth.
Definition: TrackTruthMatchingBaseAlg.h:133
rotate
void rotate(double angler, GeoTrf::Vector2D &vector)
Definition: TRTDetectorFactory_Full.cxx:63
createSimpleDistributions.IsDebug
bool IsDebug
Definition: createSimpleDistributions.py:12
TableUtils::Range2D
Definition: TableUtils.h:60
max
#define max(a, b)
Definition: cfImp.cxx:41
TableUtils::MultiColumnTable
Definition: TableUtils.h:250
ActsTrk::TrackTruthMatchingBaseAlg::m_weightsForProb
Gaudi::Property< std::vector< float > > m_weightsForProb
Definition: TrackTruthMatchingBaseAlg.h:156
ActsTrk::TrackTruthMatchingBaseAlg::NTracksTotal
@ NTracksTotal
Definition: TrackTruthMatchingBaseAlg.h:235
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:557
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
ActsTrk::HitCountsPerTrack
Container for hit counts per track Contains hit counts per associated truth particle and the total hi...
Definition: TrackToTruthParticleAssociation.h:37
ActsTrk::detail::to_underlying
constexpr std::underlying_type< T_EnumClass >::type to_underlying(T_EnumClass an_enum)
Helper to convert class enum into an integer.
Definition: HitSummaryDataUtils.h:25
tail
std::string tail(std::string s, const std::string &pattern)
tail of a string
Definition: computils.cxx:300
ActsTrk::TrackTruthMatchingBaseAlg::BaseStat::operator+=
BaseStat< DetailEnabled > & operator+=(const BaseStat< DetailEnabled > &event_stat)
Definition: TrackTruthMatchingBaseAlg.cxx:440
WriteCellNoiseToCool.src
src
Definition: WriteCellNoiseToCool.py:513
IAthSelectionTool::CutResult
Definition: IAthSelectionTool.h:30
ActsTrk::TrackTruthMatchingBaseAlg::EventStatBase::m_nTracksWithoutAssociatedTruthParticle
unsigned int m_nTracksWithoutAssociatedTruthParticle
Definition: TrackTruthMatchingBaseAlg.h:123
ActsTrk::TrackTruthMatchingBaseAlg::printData2D
void printData2D(const std::vector< std::string > &row_category_labels, const std::vector< std::string > &col_category_labels, const std::string &top_left_label, std::vector< std::array< ActsUtils::Stat, kNCategorisedStat > > &stat_per_category, std::vector< std::array< std::size_t, kNCategorisedCounter > > &counts_per_category, bool rotate) const
Definition: TrackTruthMatchingBaseAlg.cxx:717
m_data
std::vector< T > m_data
Definition: TrackTruthMatchingBaseAlg.cxx:660
ActsTrk::TrackTruthMatchingBaseAlg::initialize
virtual StatusCode initialize() override
Definition: TrackTruthMatchingBaseAlg.cxx:135
CutsMETMaker::accept
StatusCode accept(const xAOD::Muon *mu)
Definition: CutsMETMaker.cxx:18
ActsTrk::TrackTruthMatchingBaseAlg::kHitEfficiency
@ kHitEfficiency
Definition: TrackTruthMatchingBaseAlg.h:252
accumulate
bool accumulate(AccumulateMap &map, std::vector< module_t > const &modules, FPGATrackSimMatrixAccumulator const &acc)
Accumulates an accumulator (e.g.
Definition: FPGATrackSimMatrixAccumulator.cxx:22
ActsTrk::TrackTruthMatchingBaseAlg::m_printDetails
Property< bool > m_printDetails
Definition: TrackTruthMatchingBaseAlg.h:195
test_pyathena.pt
pt
Definition: test_pyathena.py:11
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
AthCommonMsg< Gaudi::Algorithm >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
athena.value
value
Definition: athena.py:124
ActsTrk::TrackTruthMatchingBaseAlg::kMatchProbability
@ kMatchProbability
Definition: TrackTruthMatchingBaseAlg.h:254
perfmonmt-printer.dest
dest
Definition: perfmonmt-printer.py:189
xAOD::TruthParticle_v1::pdg_id
int pdg_id() const
PDG ID code.
Definition: TruthParticle_v1.h:52
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
python.Bindings.values
values
Definition: Control/AthenaPython/python/Bindings.py:805
ActsTrk::TrackTruthMatchingBaseAlg::BaseStat::m_truthSelectionCuts
ActsUtils::StatHist m_truthSelectionCuts
Definition: TrackTruthMatchingBaseAlg.h:342
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
ActsTrk::HitCounterArray
Definition: TrackToTruthParticleAssociation.h:25
yodamerge_tmp.val_i
float val_i
Definition: yodamerge_tmp.py:252
ActsTrk::TrackTruthMatchingBaseAlg::weightedCountSum
static double weightedCountSum(const ActsTrk::HitCounterArray &counts, const std::vector< float > &weights)
Definition: TrackTruthMatchingBaseAlg.cxx:798
ActsTrk::TrackTruthMatchingBaseAlg::getPtPdgIdStatCategory
std::size_t getPtPdgIdStatCategory(float pt, int pdg_id) const
Return the category based on the PDG ID.
Definition: TrackTruthMatchingBaseAlg.cxx:379
ActsUtils::Stat
Simple class to gather statistics : min, max, mean, rms.
Definition: StatUtils.h:16
ActsTrk::TrackTruthMatchingBaseAlg::DebugCounter::fillTruthMatchProb
void fillTruthMatchProb(const std::array< float, 2 > &best_match_prob) const
Definition: TrackTruthMatchingBaseAlg.cxx:164
ActsTrk::TrackTruthMatchingBaseAlg::NoAssociatedTruthParticle
@ NoAssociatedTruthParticle
Definition: TrackTruthMatchingBaseAlg.h:238
ActsTrk::TrackTruthMatchingBaseAlg::EventStatBase::fill
void fill([[maybe_unused]] unsigned int eta_category_i, [[maybe_unused]] unsigned int pdg_id_category_i, [[maybe_unused]] float hit_efficiency, [[maybe_unused]] float hit_purity, [[maybe_unused]] float match_prob, [[maybe_unused]] const xAOD::TruthParticle *best_match)
Definition: TrackTruthMatchingBaseAlg.h:94
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
ActsTrk::TrackTruthMatchingBaseAlg::EventStatBase::m_nTruthParticleWithoutAssociatedCounts
unsigned int m_nTruthParticleWithoutAssociatedCounts
Definition: TrackTruthMatchingBaseAlg.h:122
ActsTrk::TrackTruthMatchingBaseAlg::m_statEtaBins
Property< std::vector< float > > m_statEtaBins
Definition: TrackTruthMatchingBaseAlg.h:187
ActsTrk::TrackTruthMatchingBaseAlg::printStatTables
void printStatTables() const
Definition: TrackTruthMatchingBaseAlg.cxx:548
ActsTrk::TrackTruthMatchingBaseAlg::s_NMeasurementTypes
constexpr static unsigned int s_NMeasurementTypes
Definition: TrackTruthMatchingBaseAlg.h:231
G4StepHelper::particleName
std::string particleName(const G4Step *theStep)
TODO.
Definition: StepHelper.cxx:24
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
makeTable
TableUtils::StatTable< T > makeTable(const std::array< T, N > &counter, const std::array< std::string, N > &label)
Definition: TableUtils.h:521
ActsUtils::dumpStat
void dumpStat(T_Stream &out, const Stat &stat)
Dump the given statistics object to the given output stream.
Definition: StatUtils.h:62
TableUtils::maxLabelWidth
std::size_t maxLabelWidth(const T_Collection &col)
Definition: TableUtils.h:288
sqr
#define sqr(t)
Definition: PolygonTriangulator.cxx:110
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
TableUtils::makeBinLabel
std::string makeBinLabel(const std::string &variable_name, const std::vector< float > &bins, std::size_t bin_i, bool abs_value=false, int precision=1)
Definition: TableUtils.h:483
xAOD::TruthParticle_v1
Class describing a truth particle in the MC record.
Definition: TruthParticle_v1.h:37
ActsTrk::TrackTruthMatchingBaseAlg::NTruthWithCountsTotal
@ NTruthWithCountsTotal
Definition: TrackTruthMatchingBaseAlg.h:236
ActsTrk::TrackTruthMatchingBaseAlg::getPtEtaStatCategory
std::size_t getPtEtaStatCategory(float pt, float eta) const
Return the category based on the provided eta value.
Definition: TrackTruthMatchingBaseAlg.cxx:368
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ActsTrk::TrackTruthMatchingBaseAlg::TruthParticleNoNoiseMismatch
@ TruthParticleNoNoiseMismatch
Definition: TrackTruthMatchingBaseAlg.h:240
ActsTrk::TrackTruthMatchingBaseAlg::checkBinOrder
void checkBinOrder(const std::vector< float > &bin_edges, const std::string &bin_label) const
check that bins are in increasing order.
Definition: TrackTruthMatchingBaseAlg.cxx:403
TableUtils::Range< std::string >
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
ActsTrk::operator<<
MsgStream & operator<<(MsgStream &out, const ActsUtils::Stat &stat)
Definition: TrackToTruthAssociationAlg.cxx:25
ActsTrk::TrackTruthMatchingBaseAlg::BaseStat::m_counterPerPdgId
CounterArrayVec m_counterPerPdgId
Definition: TrackTruthMatchingBaseAlg.h:352
ActsTrk::TrackTruthMatchingBaseAlg::m_statPtBins
Property< std::vector< float > > m_statPtBins
Definition: TrackTruthMatchingBaseAlg.h:189
ActsTrk::TrackTruthMatchingBaseAlg::EventStatBase::m_nTruthParticleNonoiseMismatches
unsigned int m_nTruthParticleNonoiseMismatches
Definition: TrackTruthMatchingBaseAlg.h:125
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
ActsTrk::TrackTruthMatchingBaseAlg::EventStatBase
Definition: TrackTruthMatchingBaseAlg.h:79
ActsTrk::TrackTruthMatchingBaseAlg::DebugCounter::fillMeasForTruthParticleWithoutCount
void fillMeasForTruthParticleWithoutCount(double weighted_measurement_sum) const
Definition: TrackTruthMatchingBaseAlg.cxx:157
beamspotman.stat
stat
Definition: beamspotman.py:266
ActsTrk::TrackTruthMatchingBaseAlg::kHitPurity
@ kHitPurity
Definition: TrackTruthMatchingBaseAlg.h:253
min
#define min(a, b)
Definition: cfImp.cxx:40
ActsTrk::HitCountsPerTrack::noiseCounts
HitCounterArray & noiseCounts()
Noise hit counts per track.
Definition: TrackToTruthParticleAssociation.h:59
TruthVertex.h
head
std::string head(std::string s, const std::string &pattern)
head of a string
Definition: computils.cxx:310
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
ActsTrk::TrackTruthMatchingBaseAlg::m_computeTrackRecoEfficiency
Property< bool > m_computeTrackRecoEfficiency
Definition: TrackTruthMatchingBaseAlg.h:197
ActsTrk::TrackFindingValidationDebugHists
constexpr bool TrackFindingValidationDebugHists
Definition: TrackTruthMatchingBaseAlg.h:41
python.ext.table_printer.table
list table
Definition: table_printer.py:81
ActsTrk::HitCountsPerTrack::totalCounts
HitCounterArray & totalCounts()
Total hit counts per track.
Definition: TrackToTruthParticleAssociation.h:51
weights
Definition: herwig7_interface.h:44
ActsTrk::TrackTruthMatchingBaseAlg::kNCategorisedCounter
@ kNCategorisedCounter
Definition: TrackTruthMatchingBaseAlg.h:249
xAOD::TruthParticle_v1::eta
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
Definition: TruthParticle_v1.cxx:174
ActsTrk::TrackTruthMatchingBaseAlg::EventStatBase::m_nTracksWithoutSelectedTruthParticle
unsigned int m_nTracksWithoutSelectedTruthParticle
Definition: TrackTruthMatchingBaseAlg.h:124
TrackTruthMatchingBaseAlg.h
ActsTrk::TrackTruthMatchingBaseAlg::checkMatchWeights
StatusCode checkMatchWeights()
Definition: TrackTruthMatchingBaseAlg.cxx:777
python.Dumpers.typename
def typename(t)
Definition: Dumpers.py:194
ActsTrk::TrackTruthMatchingBaseAlg::initStatTables
void initStatTables()
Definition: TrackTruthMatchingBaseAlg.cxx:417
ActsTrk::TruthParticleHitCounts
std::unordered_map< const xAOD::TruthParticle *, HitCounterArray > TruthParticleHitCounts
Definition: TruthParticleHitCounts.h:19
ActsTrk::HitCountsPerTrack::countsPerTruthParticle
const container & countsPerTruthParticle() const
vector with counts per associated truth particle
Definition: TrackToTruthParticleAssociation.h:43
TableUtils::makeEtaBinLabel
std::string makeEtaBinLabel(const std::vector< float > &eta_bins, std::size_t eta_bin_i, bool abs_eta=false)
Definition: TableUtils.h:512
ActsTrk::TrackTruthMatchingBaseAlg::BaseStat::printStatTables
void printStatTables(const TrackTruthMatchingBaseAlg &parent, const std::vector< float > &statPtBins, const std::vector< float > &statEtaBins, std::vector< int > &pdgId, bool printDetails, bool pdgIdCategorisation, bool useAbsEtaForStat)
Definition: TrackTruthMatchingBaseAlg.cxx:452
ActsTrk::TrackTruthMatchingBaseAlg::kNParticleWithAssociatedTrack
@ kNParticleWithAssociatedTrack
Definition: TrackTruthMatchingBaseAlg.h:246
ActsTrk::TrackFindingValidationDetailedStat
constexpr bool TrackFindingValidationDetailedStat
Definition: TrackTruthMatchingBaseAlg.h:42
ActsTrk::TrackTruthMatchingBaseAlg::s_pdgIdMax
constexpr static int s_pdgIdMax
Definition: TrackTruthMatchingBaseAlg.h:258
ActsTrk::TrackTruthMatchingBaseAlg::BaseStat::m_statPerPdgId
StatArrayVec m_statPerPdgId
Definition: TrackTruthMatchingBaseAlg.h:354
a
TList * a
Definition: liststreamerinfos.cxx:10
ActsTrk::TrackTruthMatchingBaseAlg::m_truthSelectionTool
ToolHandle< IAthSelectionTool > m_truthSelectionTool
Definition: TrackTruthMatchingBaseAlg.h:199
Base_Fragment.width
width
Definition: Sherpa_i/share/common/Base_Fragment.py:59
ActsTrk::TrackTruthMatchingBaseAlg::m_showRawCounts
Property< bool > m_showRawCounts
Definition: TrackTruthMatchingBaseAlg.h:193
ActsTrk::TrackTruthMatchingBaseAlg::MissingTruthParticleHitCounts
@ MissingTruthParticleHitCounts
Definition: TrackTruthMatchingBaseAlg.h:237
ActsTrk::TrackTruthMatchingBaseAlg::kNTotalParticles
@ kNTotalParticles
Definition: TrackTruthMatchingBaseAlg.h:245
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
ActsTrk::TrackTruthMatchingBaseAlg::EventStatBase::doDetail
static constexpr bool doDetail
Definition: TrackTruthMatchingBaseAlg.h:80
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
ActsTrk::TrackTruthMatchingBaseAlg::TrackTruthMatchingBaseAlg
TrackTruthMatchingBaseAlg(const std::string &name, ISvcLocator *pSvcLocator)
Definition: TrackTruthMatchingBaseAlg.cxx:129
DEBUG
#define DEBUG
Definition: page_access.h:11
AthCommonMsg< Gaudi::Algorithm >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
ActsTrk::TrackTruthMatchingBaseAlg::BaseStat
Definition: TrackTruthMatchingBaseAlg.h:47
ActsUtils::StatHist::add
void add(double val)
Gather statistics and fill the histogram if not disabled.
Definition: StatUtils.h:116
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
ActsTrk::TrackTruthMatchingBaseAlg::kNCategorisedStat
@ kNCategorisedStat
Definition: TrackTruthMatchingBaseAlg.h:255
ActsTrk::TrackTruthMatchingBaseAlg::printCategories
void printCategories(const std::vector< std::string > &pt_category_labels, const std::vector< std::string > &eta_category_labels, std::vector< std::string > &counter_labels, std::vector< std::array< ActsUtils::Stat, kNCategorisedStat > > &stat_per_category, std::vector< std::array< std::size_t, kNCategorisedCounter > > &counts_per_category, const std::string &top_left_label, bool print_sub_categories) const
Definition: TrackTruthMatchingBaseAlg.cxx:570
xAOD::TruthParticle_v1::pt
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Definition: TruthParticle_v1.cxx:166
ActsTrk
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
Definition: MuonDetectorBuilderTool.cxx:49
dqt_zlumi_alleff_HIST.eff
int eff
Definition: dqt_zlumi_alleff_HIST.py:113
ActsTrk::TrackTruthMatchingBaseAlg::m_truthHitCounts
SG::ReadHandleKey< TruthParticleHitCounts > m_truthHitCounts
Definition: TrackTruthMatchingBaseAlg.h:153
ActsTrk::TrackTruthMatchingBaseAlg::m_weights
Gaudi::Property< std::vector< float > > m_weights
Definition: TrackTruthMatchingBaseAlg.h:159
ActsTrk::TrackTruthMatchingBaseAlg::m_debugCounter
DebugCounter< TrackFindingValidationDebugHists > m_debugCounter
Definition: TrackTruthMatchingBaseAlg.h:227
ActsTrk::TrackTruthMatchingBaseAlg::analyseTrackTruth
TruthMatchResult analyseTrackTruth(const TruthParticleHitCounts &truth_particle_hit_counts, const HitCountsPerTrack &track_hit_counts, EventStat &event_stat) const
Definition: TrackTruthMatchingBaseAlg.cxx:209
ActsTrk::TrackTruthMatchingBaseAlg::noiseCorrection
static double noiseCorrection(const ActsTrk::HitCounterArray &noise_counts, const std::vector< float > &weights)
Definition: TrackTruthMatchingBaseAlg.cxx:808
ActsTrk::TrackTruthMatchingBaseAlg::BaseStat::m_counterPerEta
CounterArrayVec m_counterPerEta
Definition: TrackTruthMatchingBaseAlg.h:351
ActsTrk::TrackTruthMatchingBaseAlg::DebugCounter::dumpStatistics
void dumpStatistics(T_OutStream &out) const
Definition: TrackTruthMatchingBaseAlg.cxx:145
ActsTrk::TrackTruthMatchingBaseAlg::BaseStat::m_statPerEta
StatArrayVec m_statPerEta
Definition: TrackTruthMatchingBaseAlg.h:353
ActsTrk::TrackTruthMatchingBaseAlg
Definition: TrackTruthMatchingBaseAlg.h:45
TruthParticle.h
test_pyathena.counter
counter
Definition: test_pyathena.py:15
ActsTrk::TrackTruthMatchingBaseAlg::NoSelectedTruthParticle
@ NoSelectedTruthParticle
Definition: TrackTruthMatchingBaseAlg.h:239
ActsTrk::TrackTruthMatchingBaseAlg::m_useAbsEtaForStat
bool m_useAbsEtaForStat
Definition: TrackTruthMatchingBaseAlg.h:261
ActsTrk::TrackTruthMatchingBaseAlg::BaseStat::incrementTotal
void incrementTotal([[maybe_unused]] unsigned int eta_category_i, [[maybe_unused]] unsigned int pdg_id_category_i)
Definition: TrackTruthMatchingBaseAlg.h:315
TSU::T
unsigned long long T
Definition: L1TopoDataTypes.h:35
ActsTrk::TrackTruthMatchingBaseAlg::m_pdgIdCategorisation
Property< bool > m_pdgIdCategorisation
Definition: TrackTruthMatchingBaseAlg.h:191
TableUtils::computeRatio
float computeRatio(std::size_t numerator, std::size_t denominator)
Definition: TableUtils.h:412
ActsTrk::TrackTruthMatchingBaseAlg::finalize
virtual StatusCode finalize() override
Definition: TrackTruthMatchingBaseAlg.cxx:173