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 pOptions(gctx_, mctx_);
64
65 pOptions.direction = intersection.intersections()[0].pathLength() >= 0
66 ? Acts::Direction::Forward
67 : Acts::Direction::Backward;
68
69 auto result = propagator_.propagate(pars, *target_surface, pOptions);
70
71 // CHECK THE EXTRAPOLATION COVARIANCE MATRIX
72
73 if (debug_) {
74 if (result.ok()) {
75 std::cout << "INITIAL COV MATRIX" << std::endl;
76 std::cout << (*(pars.covariance())) << std::endl;
77
78 std::cout << "FINAL COV MATRIX" << std::endl;
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 }
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 // get first and last track state on surface
104 auto outermost = *(track.trackStatesReversed().begin());
105 auto begin = track.trackStatesReversed().begin();
106 std::advance(begin, track.nTrackStates() - 1);
107 auto innermost = *begin;
108
109 // I'm checking which track state is closer to the origin of the target
110 // surface to decide from where to start the extrapolation to the surface. I
111 // use the coordinate along the beam axis.
112 double first_dis = std::abs(
113 innermost.referenceSurface().transform(gctx_).translation()(0) -
114 target_surface->transform(gctx_).translation()(0));
115
116 double last_dis = std::abs(
117 outermost.referenceSurface().transform(gctx_).translation()(0) -
118 target_surface->transform(gctx_).translation()(0));
119
120 // This is the track state to use for the extrapolation
121
122 const auto& ts = first_dis < last_dis ? innermost : outermost;
123
124 // Get the BoundTrackStateParameters
125
126 const auto& surface = ts.referenceSurface();
127 const auto& smoothed = ts.smoothed();
128 bool hasSmoothed = ts.hasSmoothed();
129 const auto& filtered = ts.filtered();
130 const auto& cov = ts.smoothedCovariance();
131
132 if (debug_) {
133 std::cout << "Surface::" << surface.transform(gctx_).translation()
134 << std::endl;
135 if (hasSmoothed)
136 std::cout << "Smoothed::" << smoothed.transpose() << std::endl;
137 std::cout << "HasSmoothed::" << hasSmoothed << std::endl;
138 std::cout << "Filtered::" << filtered.transpose() << std::endl;
139 }
140 // mg Aug 2024 ... v36 takes the particle...assume electron
141 auto partHypo{Acts::SinglyChargedParticleHypothesis::electron()};
142 Acts::BoundTrackParameters sp(surface.getSharedPtr(), smoothed, cov,
143 partHypo);
144 return extrapolate(sp, target_surface);
145 }
146
147 template <class track_t>
148 std::optional<Acts::BoundTrackParameters> extrapolateToEcal(
149 track_t track, const std::shared_ptr<Acts::Surface>& target_surface) {
150 // get last track state on the track.
151 // Now.. I'm taking whatever it is. I'm not checking here if it is a
152 // measurement.
153
154 auto& tsc = track.container().trackStateContainer();
155 auto begin = track.trackStates().begin();
156 auto ts_last = *begin;
157 const auto& surface = (ts_last).referenceSurface();
158 const auto& smoothed = (ts_last).smoothed();
159 const auto& cov = (ts_last).smoothedCovariance();
160
161 // Get the BoundTrackStateParameters
162 // assume electron for now
163 auto partHypo{Acts::SinglyChargedParticleHypothesis::electron()};
164
165 Acts::BoundTrackParameters state_parameters(surface.getSharedPtr(),
166 smoothed, cov, partHypo);
167
168 // One can also use directly the extrapolate method
169 PropagatorOptions pOptions(gctx_, mctx_);
170 auto result =
171 propagator_.propagate(state_parameters, *target_surface, pOptions);
172
173 if (result.ok())
174 return *result->endParameters;
175 else
176 return std::nullopt;
177 }
178
189 template <class track_t>
190 bool TrackStateAtSurface(track_t track,
191 const std::shared_ptr<Acts::Surface>& target_surface,
193 ldmx::TrackStateType type) {
194 auto opt_pars = extrapolate(track, target_surface);
195 if (opt_pars) {
196 // Reference point
197 Acts::Vector3 surf_loc = target_surface->transform(gctx_).translation();
198 ts.refX = surf_loc(0);
199 ts.refY = surf_loc(1);
200 ts.refZ = surf_loc(2);
201
202 // Parameters
203 ts.params =
204 tracking::sim::utils::convertActsToLdmxPars((*opt_pars).parameters());
205
206 // Covariance
207 const Acts::BoundMatrix& trk_cov = *((*opt_pars).covariance());
208 tracking::sim::utils::flatCov(trk_cov, ts.cov);
209
210 ts.ts_type = type;
211 return true;
212 } else {
213 return false;
214 }
215 }
216
217 private:
218 propagator_t propagator_;
219 Acts::GeometryContext gctx_;
220 Acts::MagneticFieldContext mctx_;
221 bool debug_{false};
222};
223
224} // namespace reco
225} // 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...
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...