ATLAS Offline Software
TrackStatePrinter.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #ifndef ACTSTRACKRECONSTRUCTION_TRACKSTATEPRINTER_ICC
6 #define ACTSTRACKRECONSTRUCTION_TRACKSTATEPRINTER_ICC 1
7 
8 // ATHENA
9 #include "xAODMeasurementBase/UncalibratedMeasurementContainer.h"
10 #include "ActsGeometry/ATLASSourceLink.h"
11 
12 // ACTS CORE
13 #include "Acts/Geometry/TrackingGeometry.hpp"
14 #include "Acts/EventData/TrackParameters.hpp"
15 
16 // Other
17 #include <iostream>
18 #include <sstream>
19 
20 namespace ActsTrk
21 {
22  /// format all arguments and return as a string.
23  /// Used here to apply std::setw() to the combination of values.
24  template <typename... Types>
25  static std::string to_string(Types &&...values)
26  {
27  std::ostringstream os;
28  (os << ... << values);
29  return os.str();
30  }
31 
32  template <typename track_container_t>
33  void
34  TrackStatePrinter::printTrack(const Acts::GeometryContext &tgContext,
35  const track_container_t &tracks,
36  const typename track_container_t::TrackProxy &track,
37  const std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, size_t>> &container_offset) const
38  {
39  const auto lastMeasurementIndex = track.tipIndex();
40  // to print track states from inside outward, we need to reverse the order of visitBackwards().
41  using PrintTrackStateContainer = std::decay_t<decltype(tracks.trackStateContainer())>;
42  std::vector<typename PrintTrackStateContainer::ConstTrackStateProxy> states;
43  states.reserve(lastMeasurementIndex + 1); // could be an overestimate
44  size_t npixel = 0, nstrip = 0;
45  tracks.trackStateContainer().visitBackwards(
46  lastMeasurementIndex,
47  [&states, &npixel, &nstrip](const PrintTrackStateContainer::ConstTrackStateProxy &state) -> void
48  {
49  if (state.hasCalibrated())
50  {
51  if (state.calibratedSize() == 1)
52  ++nstrip;
53  else if (state.calibratedSize() == 2)
54  ++npixel;
55  }
56  states.push_back(state);
57  });
58 
59  if (track.nMeasurements() + track.nOutliers() != npixel + nstrip)
60  {
61  ATH_MSG_WARNING("Track has " << track.nMeasurements() + track.nOutliers() << " measurements + outliers, but "
62  << npixel + nstrip << " pixel + strip hits");
63  }
64 
65  const Acts::BoundTrackParameters per(track.referenceSurface().getSharedPtr(),
66  track.parameters(),
67  track.covariance(),
68  track.particleHypothesis());
69  std::cout << std::setw(5) << lastMeasurementIndex << ' '
70  << std::left
71  << std::setw(4) << "parm" << ' '
72  << std::setw(21) << actsSurfaceName(per.referenceSurface()) << ' '
73  << std::setw(22) << to_string("#hit=", npixel, '/', nstrip, ", #hole=", track.nHoles()) << ' '
74  << std::right;
75  printParameters(per.referenceSurface(), tgContext, per.parameters());
76  std::cout << std::fixed << std::setw(8) << ' '
77  << std::setw(7) << std::setprecision(1) << track.chi2() << ' '
78  << std::left
79  << "#out=" << track.nOutliers()
80  << ", #sh=" << track.nSharedHits()
81  << std::right << std::defaultfloat << std::setprecision(-1) << '\n';
82 
83  for (auto i = states.size(); i > 0;)
84  {
85  printTrackState(tgContext, states[--i], container_offset);
86  }
87  }
88 
89  template <typename track_state_proxy_t>
90  void
91  TrackStatePrinter::printTrackState(const Acts::GeometryContext &tgContext,
92  const track_state_proxy_t &state,
93  const std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, size_t>> &container_offset,
94  bool useFiltered) const
95  {
96  if (!m_printFilteredStates && useFiltered)
97  return;
98 
99  ptrdiff_t index = -1;
100 
101  if (state.hasUncalibratedSourceLink())
102  {
103  ATLASUncalibSourceLink sl = state.getUncalibratedSourceLink().template get<ATLASUncalibSourceLink>();
104  const xAOD::UncalibratedMeasurement &umeas = getUncalibratedMeasurement(sl);
105  index = umeas.index();
106  for (const auto &[container, offset] : container_offset)
107  {
108  if (umeas.container() == container)
109  {
110  index += offset;
111  break;
112  }
113  }
114  }
115 
116  std::cout << std::setw(5) << state.index() << ' ';
117  char ptype = !m_printFilteredStates ? ' '
118  : useFiltered ? 'F'
119  : 'S';
120  if (state.hasCalibrated())
121  {
122  std::cout << ptype << std::setw(2) << state.calibratedSize() << 'D';
123  }
124  else if (state.typeFlags().test(Acts::TrackStateFlag::HoleFlag))
125  {
126  std::cout << std::setw(4) << "hole";
127  }
128  else
129  {
130  std::cout << ptype << std::setw(3) << " ";
131  }
132  std::cout << ' '
133  << std::left
134  << std::setw(21) << actsSurfaceName(state.referenceSurface()) << ' ';
135  if (index >= 0)
136  {
137  std::cout << std::setw(22) << index << ' ';
138  }
139  else
140  {
141  std::cout << std::setw(22) << to_string(state.referenceSurface().geometryId()) << ' ';
142  }
143  std::cout << std::right;
144  const auto &parameters = !useFiltered ? state.parameters()
145  : state.hasFiltered() ? state.filtered()
146  : state.predicted();
147  printParameters(state.referenceSurface(), tgContext, parameters);
148  std::cout << ' '
149  << std::fixed
150  << std::setw(6) << std::setprecision(1) << state.pathLength() << ' '
151  << std::setw(7) << std::setprecision(1) << state.chi2() << ' '
152  << std::defaultfloat << std::setprecision(-1)
153  << std::setw(Acts::TrackStateFlag::NumTrackStateFlags) << trackStateName(state.typeFlags()) << '\n';
154  }
155 
156 } // namespace ActsTrk
157 
158 #endif