ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
helix_plane_intersector.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// Project include(s)
12#include "detray/definitions/algebra.hpp"
13#include "detray/definitions/detail/qualifiers.hpp"
14#include "detray/definitions/math.hpp"
15#include "detray/definitions/units.hpp"
16#include "detray/geometry/coordinates/cartesian2D.hpp"
17#include "detray/geometry/coordinates/polar2D.hpp"
18#include "detray/navigation/intersection/intersection.hpp"
19#include "detray/tracks/helix.hpp"
20#include "detray/utils/root_finding.hpp"
21
22// System include(s)
23#include <cmath>
24#include <limits>
25#include <type_traits>
26
27namespace detray {
28
29template <typename frame_t, concepts::algebra algebra_t>
31
37template <detray::concepts::aos algebra_t>
38struct helix_intersector_impl<cartesian2D<algebra_t>, algebra_t> {
39 private:
40 using scalar_t = dscalar<algebra_t>;
41
42 public:
44 using algebra_type = algebra_t;
45
47 template <typename surface_descr_t>
50
52 template <typename other_algebra_t>
54
55 // Maximum number of solutions this intersector can produce
57 static constexpr std::uint8_t n_solutions{1u};
58
61
69 DETRAY_HOST_DEVICE constexpr result_type point_of_intersection(
71 const scalar_t /*unused*/ = 0.f) const {
72 using point3_t = dpoint3D<algebra_t>;
73 using vector3_t = dvector3D<algebra_t>;
74
75 // Surface normal
76 const vector3_t sn = trf.z();
77 // Surface translation
78 const point3_t st = trf.translation();
79
80 // For a plane parallel to the magnetic field, the projected helix is
81 // a circle. Reject planes outside that circle before attempting to find
82 // a root: bracket expansion cannot succeed when no intersection exists.
83 const vector3_t field = h.b_field();
84 const scalar_t curvature = -h.qop() * h.B();
85 if (vector::dot(sn, field) == 0.f && curvature != 0.f &&
86 h.radius() * h.B() >= 1e-6f) {
87 const vector3_t field_axis = vector::normalize(field);
88 // The transverse circle centre is offset from the initial position.
89 const vector3_t center_offset =
90 (1.f / curvature) * vector::cross(field_axis, h.dir());
91 const scalar_t center_distance = math::fabs(
92 vector::dot(sn, h.pos() - st) + vector::dot(sn, center_offset));
93 const scalar_t radius = h.radius();
94 // Keep near-tangent cases within the solver's tolerance, with an
95 // additional allowance for floating-point roundoff.
96 const scalar_t margin = convergence_tolerance +
97 64.f * std::numeric_limits<scalar_t>::epsilon() *
98 (center_distance + radius);
99 if (std::isfinite(center_distance) && std::isfinite(radius) &&
100 center_distance - radius > margin) {
101 constexpr scalar_t inv = detail::invalid_value<scalar_t>();
102 return {inv, point3_t{inv, inv, inv}, inv};
103 }
104 }
105
106 // Starting point on the helix for the Newton iteration
107 const vector3_t dist{st - h.pos(0.f)};
108 scalar_t denom{vector::dot(sn, h.dir(0.5f * vector::norm(dist)))};
109 scalar_t s_ini;
110 if (denom == 0.f) {
111 s_ini = vector::norm(dist);
112 } else {
113 s_ini = vector::dot(sn, dist) / denom;
114 }
115
117 auto plane_inters_func = [&h, &st, &sn](const scalar_t x) {
118 // f(s) = sn * (h.pos(s) - st) == 0
119 const scalar_t f_s{vector::dot(sn, (h.pos(x) - st))};
120 // f'(s) = sn * h.dir(s)
121 const scalar_t df_s{vector::dot(sn, h.dir(x))};
122
123 return std::make_tuple(f_s, df_s);
124 };
125
126 // Run the root finding algorithm
127 scalar_t s;
128 scalar_t ds;
129 if (run_rtsafe) {
130 std::tie(s, ds) =
131 newton_raphson_safe(plane_inters_func, s_ini, convergence_tolerance,
133 } else {
134 std::tie(s, ds) =
135 newton_raphson(plane_inters_func, s_ini, convergence_tolerance,
137 }
138
139 return {s, h.pos(s), ds};
140 }
141
145 std::size_t max_n_tries{1000u};
149 bool run_rtsafe{true};
150};
151
152template <detray::concepts::aos algebra_t>
153struct helix_intersector_impl<polar2D<algebra_t>, algebra_t>
154 : public helix_intersector_impl<cartesian2D<algebra_t>, algebra_t> {};
155
156} // namespace detray
describes a helical trajectory in a given B-field.
Definition helix.hpp:33
This class holds the intersection information.
Definition intersection.hpp:212
Detray include(s).
Definition array_operators.hpp:18
get_scalar_t< A, T > dscalar
Scalar type for algebra A and value type T.
Definition algebra.hpp:64
std::pair< scalar_t, scalar_t > newton_raphson_safe(function_t &evaluate_func, scalar_t s, const scalar_t convergence_tolerance=1.f *unit< scalar_t >::um, const std::size_t max_n_tries=1000u, const scalar_t max_path=5.f *unit< scalar_t >::m)
Find a root using the Newton-Raphson and Bisection algorithms.
Definition root_finding.hpp:193
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
std::pair< scalar_t, scalar_t > newton_raphson(function_t &evaluate_func, scalar_t s, const scalar_t convergence_tolerance=1.f *unit< scalar_t >::um, const std::size_t max_n_tries=1000u, const scalar_t max_path=5.f *unit< scalar_t >::m)
Find a root using the Newton-Raphson algorithm.
Definition root_finding.hpp:121
get_point3D_t< A, T > dpoint3D
Three-dimensional point type for algebra A and value type T.
Definition algebra.hpp:72
Projection into a 2D cartesian coordinate frame.
Definition cartesian2D.hpp:19
scalar_t max_path
Early exit, if the intersection is too far away.
Definition helix_plane_intersector.hpp:147
intersection_point_err< algebra_t > result_type
Result type returned by the geometric intersection calculation.
Definition helix_plane_intersector.hpp:60
intersection2D< surface_descr_t, algebra_t, intersection::contains_pos > intersection_type
Intersection result type associated with a surface descriptor.
Definition helix_plane_intersector.hpp:48
scalar_t convergence_tolerance
Tolerance for convergence.
Definition helix_plane_intersector.hpp:143
std::size_t max_n_tries
Guard against infinite loops.
Definition helix_plane_intersector.hpp:145
static constexpr std::uint8_t n_solutions
Maximum number of solutions produced by this intersector.
Definition helix_plane_intersector.hpp:57
constexpr result_type point_of_intersection(const trajectory_type< algebra_t > &h, const dtransform3D< algebra_t > &trf, const scalar_t=0.f) const
Operator function to find intersections between a helix and a planar surface.
Definition helix_plane_intersector.hpp:69
algebra_t algebra_type
Algebra policy used by this intersector.
Definition helix_plane_intersector.hpp:44
detail::helix< other_algebra_t > trajectory_type
Trajectory representation accepted by this intersector.
Definition helix_plane_intersector.hpp:53
bool run_rtsafe
Complement the Newton algorithm with Bisection steps.
Definition helix_plane_intersector.hpp:149
Intersection implementation for detector surfaces using a helix trajectory.
Definition helix_intersector.hpp:29
Result of intersector: Distance, intersection point (2D or 3D, local/global) and error estimate on di...
Definition intersection.hpp:150
Projection into a polar coordinate frame.
Definition polar2D.hpp:20
static constexpr scalar_t um
Length, native unit mm.
Definition units.hpp:25
static constexpr scalar_t m
Metre expressed in millimetres.
Definition units.hpp:31