LDMX Software
TrackExtrapolatorTool.h
1#pragma once
2
3#include <iostream>
4#include <iterator>
5#include <optional>
6
7#include "Acts/Definitions/TrackParametrization.hpp"
8#include "Acts/EventData/TrackContainer.hpp"
9#include "Acts/EventData/TrackProxy.hpp"
10#include "Acts/Geometry/GeometryContext.hpp"
11#include "Acts/MagneticField/MagneticFieldContext.hpp"
12#include "Acts/Propagator/AbortList.hpp"
13#include "Acts/Propagator/ActionList.hpp"
14#include "Acts/Propagator/MaterialInteractor.hpp"
15#include "Acts/Propagator/Propagator.hpp"
16#include "Acts/Propagator/detail/SteppingLogger.hpp"
17#include "Tracking/Event/Track.h"
18#include "Tracking/Sim/TrackingUtils.h"
19
20using ActionList =
21 Acts::ActionList<Acts::detail::SteppingLogger, Acts::MaterialInteractor>;
22using AbortList = Acts::AbortList<Acts::EndOfWorldReached>;
23
24namespace tracking {
25namespace reco {
26
27template <class propagator_t>
29 public:
30 // The geometry context should be already in the propagator options...
31 TrackExtrapolatorTool(propagator_t propagator,
32 const Acts::GeometryContext& gctx,
33 const Acts::MagneticFieldContext& mctx)
34 : propagator_(std::move(propagator)) {
35 gctx_ = gctx;
36 mctx_ = mctx;
37 }
38
44 void setDebug(bool debug) { debug_ = debug; }
45
55 typename propagator_t::template Options<ActionList, AbortList>;
56
57 std::optional<Acts::BoundTrackParameters> extrapolate(
58 const Acts::BoundTrackParameters pars,
59 const std::shared_ptr<Acts::Surface>& target_surface) {
60 auto intersection = target_surface->intersect(gctx_, pars.position(gctx_),
61 pars.direction());
62
63 PropagatorOptions p_options(gctx_, mctx_);
64
65 p_options.direction = intersection.intersections()[0].pathLength() >= 0
66 ? Acts::Direction::Forward
67 : Acts::Direction::Backward;
68
69 auto result = propagator_.propagate(pars, *target_surface, p_options);
70
71 // CHECK THE EXTRAPOLATION COVARIANCE MATRIX
72
73 if (debug_) {
74 if (result.ok()) {
75 std::cout << "INITIAL COV MATRIX\n";
76 std::cout << (*(pars.covariance())) << std::endl;
77
78 std::cout << "FINAL COV MATRIX\n";
79 auto opt_pars = *result->endParameters;
80 std::cout << *(opt_pars.covariance()) << std::endl;
81 }
82 }
83
84 if (result.ok())
85 return *result->endParameters;
86 else
87 return std::nullopt;
88 } // end of extrapolate()
89
100 template <class track_t>
101 std::optional<Acts::BoundTrackParameters> extrapolate(
102 track_t track, const std::shared_ptr<Acts::Surface>& target_surface) {
103 if (debug_) {
104 std::cout << "[TrackExtrapolatorTool] extrapolate START\n";
105 std::cout << "[TrackExtrapolatorTool] track.nTrackStates() = "
106 << track.nTrackStates() << std::endl;
107 std::cout << "[TrackExtrapolatorTool] target_surface = "
108 << target_surface.get() << std::endl;
109 }
110
111 // get first and last track state on surface
112 if (debug_)
113 std::cout
114 << "[TrackExtrapolatorTool] Getting outermost track state...\n";
115 auto outermost = *(track.trackStatesReversed().begin());
116 if (debug_)
117 std::cout
118 << "[TrackExtrapolatorTool] Getting innermost track state...\n";
119 auto begin = track.trackStatesReversed().begin();
120 std::advance(begin, track.nTrackStates() - 1);
121 auto innermost = *begin;
122 if (debug_)
123 std::cout << "[TrackExtrapolatorTool] Got innermost and outermost "
124 "track states\n";
125
126 // I'm checking which track state is closer to the origin of the target
127 // surface to decide from where to start the extrapolation to the surface. I
128 // use the coordinate along the beam axis.
129 if (debug_)
130 std::cout << "[TrackExtrapolatorTool] Calculating distances...\n";
131 double first_dis = std::abs(
132 innermost.referenceSurface().transform(gctx_).translation()(0) -
133 target_surface->transform(gctx_).translation()(0));
134
135 double last_dis = std::abs(
136 outermost.referenceSurface().transform(gctx_).translation()(0) -
137 target_surface->transform(gctx_).translation()(0));
138 if (debug_)
139 std::cout << "[TrackExtrapolatorTool] first_dis = " << first_dis
140 << ", last_dis = " << last_dis << std::endl;
141
142 // This is the track state to use for the extrapolation
143
144 const auto& ts = first_dis < last_dis ? innermost : outermost;
145 if (debug_) std::cout << "[TrackExtrapolatorTool] Selected track state\n";
146
147 // Get the BoundTrackStateParameters
148
149 if (debug_)
150 std::cout << "[TrackExtrapolatorTool] Getting reference surface...\n";
151 const auto& surface = ts.referenceSurface();
152 if (debug_)
153 std::cout << "[TrackExtrapolatorTool] Checking hasSmoothed...\n";
154 bool has_smoothed = ts.hasSmoothed();
155 if (debug_)
156 std::cout << "[TrackExtrapolatorTool] has_smoothed = " << has_smoothed
157 << std::endl;
158
159 // Use smoothed parameters if available, otherwise use filtered
160 Acts::BoundVector params;
161 Acts::BoundMatrix cov;
162
163 if (has_smoothed) {
164 if (debug_)
165 std::cout << "[TrackExtrapolatorTool] Using smoothed parameters...\n";
166 params = ts.smoothed();
167 cov = ts.smoothedCovariance();
168 } else {
169 if (debug_)
170 std::cout << "[TrackExtrapolatorTool] Using filtered parameters...\n";
171 params = ts.filtered();
172 cov = ts.filteredCovariance();
173 }
174 if (debug_)
175 std::cout << "[TrackExtrapolatorTool] Got all track state components\n";
176
177 if (debug_) {
178 std::cout << "Surface::" << surface.transform(gctx_).translation()
179 << std::endl;
180 std::cout << "HasSmoothed::" << has_smoothed << std::endl;
181 std::cout << "Parameters::" << params.transpose() << std::endl;
182 }
183 // mg Aug 2024 ... v36 takes the particle...assume electron
184 if (debug_)
185 std::cout
186 << "[TrackExtrapolatorTool] Creating BoundTrackParameters...\n";
187 auto part_hypo{Acts::SinglyChargedParticleHypothesis::electron()};
188 Acts::BoundTrackParameters sp(surface.getSharedPtr(), params, cov,
189 part_hypo);
190 if (debug_)
191 std::cout << "[TrackExtrapolatorTool] BoundTrackParameters created, "
192 "calling extrapolate(BTP)...\n";
193 auto result = extrapolate(sp, target_surface);
194 if (debug_) std::cout << "[TrackExtrapolatorTool] extrapolate DONE\n";
195 return result;
196 }
197
207 template <class track_t>
208 std::optional<Acts::BoundTrackParameters> extrapolateToEcal(
209 track_t track, const std::shared_ptr<Acts::Surface>& target_surface) {
210 // get last track state on the track.
211 // Now.. I'm taking whatever it is. I'm not checking here if it is a
212 // measurement.
213
214 auto& tsc = track.container().trackStateContainer();
215 auto begin = track.trackStates().begin();
216 auto ts_last = *begin;
217 const auto& surface = (ts_last).referenceSurface();
218 const auto& smoothed = (ts_last).smoothed();
219 const auto& cov = (ts_last).smoothedCovariance();
220
221 // Get the BoundTrackStateParameters
222 // assume electron for now
223 auto part_hypo{Acts::SinglyChargedParticleHypothesis::electron()};
224
225 Acts::BoundTrackParameters state_parameters(surface.getSharedPtr(),
226 smoothed, cov, part_hypo);
227
228 // One can also use directly the extrapolate method
229 PropagatorOptions p_options(gctx_, mctx_);
230 auto result =
231 propagator_.propagate(state_parameters, *target_surface, p_options);
232
233 if (result.ok())
234 return *result->endParameters;
235 else
236 return std::nullopt;
237 }
238
249 template <class track_t>
250 bool trackStateAtSurface(track_t track,
251 const std::shared_ptr<Acts::Surface>& target_surface,
253 ldmx::TrackStateType type) {
254 if (debug_) {
255 std::cout << "[TrackExtrapolatorTool] trackStateAtSurface START\n";
256 std::cout << "[TrackExtrapolatorTool] target_surface = "
257 << target_surface.get() << std::endl;
258 std::cout << "[TrackExtrapolatorTool] track.nTrackStates() = "
259 << track.nTrackStates() << std::endl;
260 std::cout << "[TrackExtrapolatorTool] TrackStateType = "
261 << static_cast<int>(type) << std::endl;
262 std::cout << "[TrackExtrapolatorTool] About to call extrapolate...\n";
263 }
264
265 auto opt_pars = extrapolate(track, target_surface);
266
267 if (debug_) {
268 std::cout << "[TrackExtrapolatorTool] extrapolate returned, "
269 "opt_pars.has_value() = "
270 << opt_pars.has_value() << std::endl;
271 }
272
273 if (opt_pars) {
274 if (debug_)
275 std::cout << "[TrackExtrapolatorTool] Getting surface location...\n";
276 // Reference point
277 Acts::Vector3 surf_loc = target_surface->transform(gctx_).translation();
278 ts.ref_x_ = surf_loc(0);
279 ts.ref_y_ = surf_loc(1);
280 ts.ref_z_ = surf_loc(2);
281 if (debug_) {
282 std::cout << "[TrackExtrapolatorTool] Surface location: ("
283 << surf_loc(0) << ", " << surf_loc(1) << ", " << surf_loc(2)
284 << ")\n";
285 }
286
287 if (debug_)
288 std::cout << "[TrackExtrapolatorTool] Getting parameters...\n";
289 // Parameters
290 ts.params_ =
291 tracking::sim::utils::convertActsToLdmxPars((*opt_pars).parameters());
292 if (debug_) std::cout << "[TrackExtrapolatorTool] Parameters set\n";
293
294 if (debug_)
295 std::cout << "[TrackExtrapolatorTool] Getting covariance...\n";
296 // Covariance
297 const Acts::BoundMatrix& trk_cov = *((*opt_pars).covariance());
298 if (debug_)
299 std::cout << "[TrackExtrapolatorTool] Covariance matrix obtained\n";
300 tracking::sim::utils::flatCov(trk_cov, ts.cov_);
301 if (debug_)
302 std::cout << "[TrackExtrapolatorTool] Covariance flattened\n";
303
304 ts.ts_type_ = type;
305 if (debug_)
306 std::cout << "[TrackExtrapolatorTool] trackStateAtSurface SUCCESS\n";
307 return true;
308 } else {
309 if (debug_)
310 std::cout << "[TrackExtrapolatorTool] trackStateAtSurface FAILED - "
311 "opt_pars is empty\n";
312 return false;
313 }
314 }
315
316 private:
317 propagator_t propagator_;
318 Acts::GeometryContext gctx_;
319 Acts::MagneticFieldContext mctx_;
320 bool debug_{false};
321};
322
323} // namespace reco
324} // namespace tracking
typename propagator_t::template Options< ActionList, AbortList > PropagatorOptions
Method to extrapolate to a target surface given a set of BoundTrackParameters.
std::optional< Acts::BoundTrackParameters > extrapolate(track_t track, const std::shared_ptr< Acts::Surface > &target_surface)
Method to extrapolate to a target surface given a track The method computes which track state is clos...
std::optional< Acts::BoundTrackParameters > extrapolateToEcal(track_t track, const std::shared_ptr< Acts::Surface > &target_surface)
Create an ldmx::TrackState to the extrapolated position.
bool trackStateAtSurface(track_t track, const std::shared_ptr< Acts::Surface > &target_surface, ldmx::Track::TrackState &ts, ldmx::TrackStateType type)
Create an ldmx::TrackState to the extrapolated position.
void setDebug(bool debug)
Turn on/off internal debug flag.
The measurement calibrator can be a function or a class/struct able to retrieve the sim hits containe...