ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
helix.hpp
1// This file is part of the ACTS project.
2//
3// Copyright (C) 2016 CERN for the benefit of the ACTS project
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9#pragma once
10
11// TODO: Remove this when gcc fixes their false positives.
12#if defined(__GNUC__) && !defined(__clang__)
13#pragma GCC diagnostic warning "-Wmaybe-uninitialized"
14#endif
15
16// Project include(s).
17#include "detray/definitions/algebra.hpp"
18#include "detray/definitions/math.hpp"
19#include "detray/tracks/free_track_parameters.hpp"
20#include "detray/utils/invalid_values.hpp"
21
22// System include(s).
23#include <ostream>
24
25namespace detray::detail {
26
32template <concepts::algebra algebra_t>
33class helix {
34 public:
36 using algebra_type = algebra_t;
45
48
50 template <std::size_t ROWS, std::size_t COLS>
54
55 DETRAY_HOST_DEVICE
56 helix() = delete;
57
65 DETRAY_HOST_DEVICE
67 const scalar_type qop, const vector3_type &mag_field)
68 : _pos(pos),
69 _time(time),
70 _qop(qop),
71 _B{vector::norm(mag_field)},
72 _h0{vector::normalize(mag_field)},
73 _t0{dir} {
74 assert((math::fabs(vector::norm(_t0) - 1.f) < 1e-5f) &&
75 "The helix direction must be normalized");
76
77 // Momentum
78 const vector3_type mom =
79 (1.f / static_cast<scalar_type>(math::fabs(qop))) * _t0;
80
81 // Normalized _h0 X _t0
82 _n0 = vector::normalize(vector::cross(_h0, _t0));
83
84 // Magnitude of _h0 X _t0
85 _alpha = vector::norm(vector::cross(_h0, _t0));
86
87 // Dot product of _h0 X _t0
88 _delta = vector::dot(_h0, _t0);
89
90 // Path length scaler
91 _K = -_qop * _B;
92
93 // Get longitudinal momentum parallel to B field
94 scalar_type pz = vector::dot(mom, _h0);
95
96 // Get transverse momentum perpendicular to B field
97 vector3_type pT = mom - pz * _h0;
98
99 // R [mm] = pT [GeV] / B [T] in natural unit
100 _R = vector::norm(pT) / _B;
101
102 // Handle the case of pT ~ 0
103 if (vector::norm(pT) < 1e-6f) {
104 _vz_over_vt = detail::invalid_value<scalar_type>();
105 } else {
106 // Get vz over vt in new coordinate
107 _vz_over_vt = pz / vector::norm(pT);
108 }
109 }
110
114 DETRAY_HOST_DEVICE
115 helix(const free_track_parameters_type &track, const vector3_type &mag_field)
116 : helix(track.pos(), track.time(), track.dir(), track.qop(), mag_field) {
117 assert(!track.is_invalid());
118 }
119
124 template <typename field_view_t>
126 DETRAY_HOST_DEVICE helix(const free_track_parameters_type &track,
127 const field_view_t mag_field)
128 : helix(track.pos(), track.time(), track.dir(), track.qop(),
129 sample_field(mag_field, track.pos())) {}
130
132 DETRAY_HOST_DEVICE
133 scalar_type radius() const { return _R; }
134
138 DETRAY_HOST_DEVICE
139 point3_type operator()(const scalar_type s) const { return this->pos(s); }
140
144 DETRAY_HOST_DEVICE
145 point3_type pos(const scalar_type s) const {
146 // Handle the case of pT ~ 0
147 if (_vz_over_vt == detail::invalid_value<scalar_type>()) {
148 return _pos + s * _h0;
149 }
150
151 point3_type ret = _pos;
152 ret = ret + _delta / _K * (_K * s - math::sin(_K * s)) * _h0;
153 ret = ret + math::sin(_K * s) / _K * _t0;
154 ret = ret + _alpha / _K * (1.f - math::cos(_K * s)) * _n0;
155
156 return ret;
157 }
158
161 DETRAY_HOST_DEVICE
162 point3_type pos() const { return _pos; }
163
167 DETRAY_HOST_DEVICE
168 vector3_type dir(const scalar_type s) const {
169 // Handle the case of pT ~ 0
170 if (_vz_over_vt == detail::invalid_value<scalar_type>()) {
171 return _t0;
172 }
173
174 vector3_type ret{0.f, 0.f, 0.f};
175
176 ret = ret + _delta * (1 - math::cos(_K * s)) * _h0;
177 ret = ret + math::cos(_K * s) * _t0;
178 ret = ret + _alpha * math::sin(_K * s) * _n0;
179
180 return vector::normalize(ret);
181 }
182
185 DETRAY_HOST_DEVICE
186 point3_type dir() const { return _t0; }
187
190 DETRAY_HOST_DEVICE
191 scalar_type time() const { return _time; }
192
195 DETRAY_HOST_DEVICE
196 scalar_type qop() const { return _qop; }
197
200 DETRAY_HOST_DEVICE
201 scalar_type B() const { return _B; }
202
205 DETRAY_HOST_DEVICE
206 vector3_type b_field() const { return _B * _h0; }
207
211 DETRAY_HOST_DEVICE
213 free_matrix_t ret = matrix::zero<free_matrix_t>();
214
215 const matrix_type<3, 3> I33 = matrix::identity<matrix_type<3, 3>>();
216 const matrix_type<3, 3> Z33 = matrix::zero<matrix_type<3, 3>>();
217
218 // Notations
219 // r = position
220 // t = direction
221 // l = qoverp
222
223 // Get drdr
224 auto drdr = I33;
225 getter::set_block(ret, drdr, e_free_pos0, e_free_pos0);
226
227 // Get dtdr
228 auto dtdr = Z33;
229 getter::set_block(ret, dtdr, e_free_dir0, e_free_pos0);
230
231 // Get drdt
232 auto drdt = Z33;
233
234 const scalar_type sin_ks = math::sin(_K * s);
235 const scalar_type cos_ks = math::cos(_K * s);
236 drdt = drdt + sin_ks / _K * I33;
237
238 matrix_type<3, 1> H0 = matrix::zero<matrix_type<3, 1>>();
239 getter::element(H0, 0u, 0u) = _h0[0u];
240 getter::element(H0, 1u, 0u) = _h0[1u];
241 getter::element(H0, 2u, 0u) = _h0[2u];
242 const matrix_type<1, 3> H0_T = matrix::transpose(H0);
243 const matrix_type<3, 3> H0H0_T = H0 * H0_T;
244
245 drdt = drdt + (_K * s - sin_ks) / _K * H0H0_T;
246
247 drdt = drdt + (cos_ks - 1.f) / _K * matrix::column_wise_cross(I33, _h0);
248
249 getter::set_block(ret, drdt, e_free_pos0, e_free_dir0);
250
251 // Get dtdt
252 auto dtdt = Z33;
253 dtdt = dtdt + cos_ks * I33;
254 dtdt = dtdt + (1 - cos_ks) * H0H0_T;
255 dtdt = dtdt - sin_ks * matrix::column_wise_cross(I33, _h0);
256
257 getter::set_block(ret, dtdt, e_free_dir0, e_free_dir0);
258
259 // Get drdl
260 vector3_type drdl = 1.f / _qop * (s * this->dir(s) + _pos - this->pos(s));
261
262 getter::set_block(ret, drdl, e_free_pos0, e_free_qoverp);
263
264 // Get dtdl
265 vector3_type dtdl =
266 -_B * s *
267 (sin_ks * ((H0H0_T - I33) * _t0) + cos_ks * vector::cross(_h0, _t0));
268
269 getter::set_block(ret, dtdl, e_free_dir0, e_free_qoverp);
270
271 // 3x3 and 7x7 element is 1 (Maybe?)
272 getter::element(ret, e_free_time, e_free_time) = 1.f;
273 getter::element(ret, e_free_qoverp, e_free_qoverp) = 1.f;
274
275 return ret;
276 }
277
278 private:
280 DETRAY_HOST
281 friend std::ostream &operator<<(std::ostream &os, const helix &h) {
282 os << "helix: ";
283 os << "ori = " << h._pos;
284 os << ", dir = " << h._t0 << std::endl;
285
286 return os;
287 }
288
290 template <typename field_view_t>
291 constexpr vector3_type sample_field(const field_view_t field,
292 const point3_type &pos) const {
293 const auto bvec = field.at(pos[0], pos[1], pos[2]);
294
295 return {bvec[0], bvec[1], bvec[2]};
296 }
297
299 point3_type _pos;
300
302 scalar_type _time;
303
305 scalar_type _qop;
306
308 scalar_type _B;
309
311 vector3_type _h0;
312
314 vector3_type _t0;
315
317 vector3_type _n0;
318
320 scalar_type _alpha;
321
323 scalar_type _delta;
324
326 scalar_type _K;
327
329 scalar_type _R;
330
332 scalar_type _vz_over_vt;
333};
334
335template <concepts::algebra algebra_t, typename field_view_t>
336 requires(!concepts::vector3D<field_view_t>)
337DETRAY_HOST_DEVICE_DEDUCTION_GUIDE helix(
338 const free_track_parameters<algebra_t> &, const field_view_t)
340
341} // namespace detray::detail
describes a helical trajectory in a given B-field.
Definition helix.hpp:33
scalar_type time() const
Definition helix.hpp:191
vector3_type b_field() const
Return the uniform magnetic field vector.
Definition helix.hpp:206
free_matrix< algebra_t > free_matrix_t
Definition helix.hpp:53
point3_type dir() const
Return the initial unit tangent direction.
Definition helix.hpp:186
point3_type operator()(const scalar_type s) const
Evaluate the helix at a path length.
Definition helix.hpp:139
dvector3D< algebra_t > vector3_type
Definition helix.hpp:42
dmatrix< algebra_t, ROWS, COLS > matrix_type
Definition helix.hpp:51
helix(const free_track_parameters_type &track, const field_view_t mag_field)
Build a helix using a field view sampled at the track position.
Definition helix.hpp:126
free_matrix_t jacobian(const scalar_type s) const
Compute the free-parameter transport Jacobian at a path length.
Definition helix.hpp:212
dpoint3D< algebra_t > point3_type
Definition helix.hpp:40
scalar_type radius() const
Definition helix.hpp:133
algebra_t algebra_type
Definition helix.hpp:36
vector3_type dir(const scalar_type s) const
Definition helix.hpp:168
helix(const point3_type &pos, const scalar_type time, const vector3_type &dir, const scalar_type qop, const vector3_type &mag_field)
Parametrized constructor.
Definition helix.hpp:66
friend std::ostream & operator<<(std::ostream &os, const helix &h)
Print.
Definition helix.hpp:281
free_track_parameters< algebra_t > free_track_parameters_type
Definition helix.hpp:47
scalar_type qop() const
Definition helix.hpp:196
scalar_type B() const
Return the magnitude of the uniform magnetic field.
Definition helix.hpp:201
dtransform3D< algebra_t > transform3_type
Definition helix.hpp:44
point3_type pos() const
Return the initial position of the helix.
Definition helix.hpp:162
dscalar< algebra_t > scalar_type
Definition helix.hpp:38
point3_type pos(const scalar_type s) const
Definition helix.hpp:145
helix(const free_track_parameters_type &track, const vector3_type &mag_field)
Build a helix from a free track state and a uniform field vector.
Definition helix.hpp:115
Definition concepts.hpp:65
get_scalar_t< A, T > dscalar
Scalar type for algebra A and value type T.
Definition algebra.hpp:64
dmatrix< algebra_t, e_free_size, e_free_size > free_matrix
Covariance matrix type for free track parametrization.
Definition track_parametrization.hpp:73
get_vector3D_t< A, T > dvector3D
Three-dimensional vector type for algebra A and value type T.
Definition algebra.hpp:80
get_transform3D_t< A, T > dtransform3D
Three-dimensional transform type for algebra A and value type T.
Definition algebra.hpp:84
get_matrix_t< A, R, C, T > dmatrix
R by C matrix type for algebra A and value type T.
Definition algebra.hpp:88
get_point3D_t< A, T > dpoint3D
Three-dimensional point type for algebra A and value type T.
Definition algebra.hpp:72
free_parameters_vector< algebra_t > free_track_parameters
The free track parameters consist only of the parameter vector.
Definition free_track_parameters.hpp:249
constexpr bool is_invalid() const
Definition free_track_parameters.hpp:225
vector3_type dir() const
Definition free_track_parameters.hpp:128
scalar_type time() const
Definition free_track_parameters.hpp:149
point3_type pos() const
Definition free_track_parameters.hpp:110
scalar_type qop() const
Definition free_track_parameters.hpp:163