ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
intersector_base.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/indexing.hpp"
15#include "detray/definitions/math.hpp"
16#include "detray/definitions/units.hpp"
17#include "detray/geometry/concepts.hpp"
18#include "detray/geometry/detail/shape_utils.hpp"
19#include "detray/navigation/intersection/intersection.hpp"
20#include "detray/navigation/intersection/intersection_config.hpp"
21#include "detray/utils/invalid_values.hpp"
22
23// System include(s)
24#include <cstdint>
25#include <limits>
26#include <ostream>
27
28namespace detray {
29
32template <typename intersector_t>
33struct intersector_base : public intersector_t {
36 using algebra_type = typename intersector_t::algebra_type;
50
52 template <typename surface_descr_t>
54 typename intersector_t::template intersection_type<surface_descr_t>;
55
57 template <typename other_algebra_t>
59 typename intersector_t::template trajectory_type<other_algebra_t>;
60
62 static constexpr std::uint8_t n_solutions{intersector_t::n_solutions};
63
65 using result_type = typename intersector_t::result_type;
66
73
82 template <typename surface_descr_t, typename mask_t,
83 concepts::algebra other_algebra_t, std::uint8_t N = n_solutions>
84 requires(N == 1u)
85 DETRAY_HOST_DEVICE constexpr intersection_type<surface_descr_t> operator()(
86 const trajectory_type<other_algebra_t> &traj, const surface_descr_t &sf,
87 const mask_t &mask, const transform3_type &trf,
88 const intersection::config &cfg = {},
89 const scalar_type external_mask_tol = 0.f) const {
90 result_type result =
91 call_intersector(traj, mask, trf, cfg.overstep_tolerance);
92
94 resolve_mask(is, traj, result, sf, mask, trf, cfg, external_mask_tol);
95
96 return is;
97 }
98
107 template <typename surface_descr_t, typename mask_t,
108 concepts::algebra other_algebra_t, std::uint8_t N = n_solutions>
109 requires(N > 1u)
110 DETRAY_HOST_DEVICE constexpr darray<intersection_type<surface_descr_t>,
112 operator()(const trajectory_type<other_algebra_t> &traj,
113 const surface_descr_t &sf, const mask_t &mask,
114 const transform3_type &trf, const intersection::config &cfg = {},
115 const scalar_type external_mask_tol = 0.f) const {
116 // One or both of these solutions might be invalid
117 result_type result =
118 call_intersector(traj, mask, trf, cfg.overstep_tolerance);
119
121
122 for (std::size_t i = 0u; i < n_solutions; ++i) {
123 if (detray::detail::any_of(result[i].is_valid())) {
124 resolve_mask(ret[i], traj, result[i], sf, mask, trf, cfg,
125 external_mask_tol);
126 }
127 }
128
129 // Even if there are two geometrically valid solutions, the smaller one
130 // might not be passed on if it is below the overstepping tolerance
131 return ret;
132 }
133
134
143 template <typename surface_descr_t, typename mask_t,
144 concepts::algebra other_algebra_t>
145 DETRAY_HOST_DEVICE constexpr decltype(auto) operator()(
146 const trajectory_type<other_algebra_t> &traj, const surface_descr_t &sf,
147 const mask_t &mask, const transform3_type &trf,
148 const scalar_type mask_tolerance,
149 const scalar_type overstep_tol = 0.f) const {
150 const intersection::config intr_cfg{
151 .min_mask_tolerance = static_cast<float>(mask_tolerance),
152 .max_mask_tolerance = static_cast<float>(mask_tolerance),
153 .mask_tolerance_scalor = 0.f,
154 .overstep_tolerance = static_cast<float>(overstep_tol)};
155
156 return this->operator()(traj, sf, mask, trf, intr_cfg, 0.f);
157 }
158
159 private:
161 template <concepts::algebra other_algebra_t, typename mask_t>
162 constexpr result_type call_intersector(
164 [[maybe_unused]] const mask_t &mask, const transform3_type &trf,
165 const scalar_type overstep_tol = 0.f) const {
166 if constexpr (concepts::cylindrical<mask_t>) {
167 return intersector_t{}.point_of_intersection(traj, trf, mask,
168 overstep_tol);
169 } else {
170 return intersector_t{}.point_of_intersection(traj, trf, overstep_tol);
171 }
172 }
173};
174
185template <typename intersection_t, typename trajectory_t,
186 concepts::algebra algebra_t, concepts::point point_t,
187 typename surface_descr_t, typename mask_t,
188 concepts::transform3D transform3_t, concepts::scalar scalar_t>
189DETRAY_HOST_DEVICE constexpr void resolve_mask(
190 intersection_t &is, const trajectory_t &traj,
192 &ip,
193 const surface_descr_t sf_desc, const mask_t &mask, const transform3_t &trf,
194 const intersection::config &cfg = {},
195 const scalar_t external_mask_tolerance = 0.f) {
196 // Mask out solutions that don't meet the overstepping tolerance (SoA)
197 if constexpr (concepts::soa<algebra_t>) {
198 using status_t = typename intersection_t::status_type;
199
200 is.status()(is.path() < cfg.overstep_tolerance) =
201 static_cast<status_t>(intersection::status::e_outside);
202 } else {
203 is.set_status(intersection::status::e_outside);
204 }
205
206 // Build intersection struct from test trajectory, if the distance is valid
207 if (detray::detail::none_of(ip.path >= cfg.overstep_tolerance)) {
208 // Not a valid intersection
209 return;
210 }
211
212 // Save local position for debug evaluation
213 if constexpr (intersection_t::contains_pos()) {
214 // Global position on the surface
215 dpoint3D<algebra_t> glob_pos;
216 if constexpr (concepts::soa<algebra_t>) {
217 // The trajectory is given in AoS layout. Translate...
218 const auto &origin = traj.pos();
219 const auto &dir = traj.dir();
220
221 // Broadcast
222 const dvector3D<algebra_t> ro{origin[0], origin[1], origin[2]};
223 const dvector3D<algebra_t> rd{dir[0], dir[1], dir[2]};
224
225 glob_pos = ro + ip.path * rd;
226 } else {
227 // Works for any parameterized trajectory
228 glob_pos = traj.pos(ip.path);
229 }
230 is.set_local(mask_t::to_local_frame3D(trf, glob_pos, traj.dir(ip.path)));
231 }
232
233 scalar_t base_tol = 0.f;
234 scalar_t ext_tol = 0.f;
235
236 // Tol.: scale with distance of surface to account for track bending
237 if (!sf_desc.is_portal() ||
238 cfg.min_mask_tolerance == std::numeric_limits<float>::max()) {
239 ext_tol = external_mask_tolerance;
240 base_tol =
241 math::max(static_cast<scalar_t>(cfg.min_mask_tolerance),
242 math::min(static_cast<scalar_t>(cfg.max_mask_tolerance),
243 static_cast<scalar_t>(cfg.mask_tolerance_scalor) *
244 math::fabs(ip.path)));
245 }
246
247 // Mask check results with and without external tolerance
248 typename mask_t::result_type mask_check{};
249
250 // Intersector provides specialized local point
251 if constexpr (std::same_as<point_t, dpoint2D<algebra_t>>) {
252 mask_check = mask.resolve(ip.point, base_tol, ext_tol);
253 } else {
254 // Otherwise, let the shape transform the point to local
255 mask_check = mask.resolve(trf, ip.point, base_tol, ext_tol);
256 }
257
258 // Set the less strict status first, then overwrite with more strict
259 is.set_status_if(intersection::status::e_edge,
261 is.set_status_if(intersection::status::e_inside,
263
264 is.set_path(ip.path);
265 is.set_surface(sf_desc);
266 is.set_direction(!math::signbit(ip.path));
267 is.set_volume_link(mask.volume_link());
268}
269
270} // namespace detray
Mask a region on a surface and link it to a volume.
Definition mask.hpp:46
constexpr result_type resolve(const point_t &loc_p, const scalar_type tol=std::numeric_limits< scalar_type >::epsilon(), const scalar_type edge_tol=0.f) const
Mask this shape onto a surface.
Definition mask.hpp:200
auto volume_link() const -> const links_type &
Definition mask.hpp:255
Algebra plugin concept.
Definition concepts.hpp:147
Definition concepts.hpp:214
Point concepts.
Definition concepts.hpp:71
Scalar concept: Elements of vectors/matrices (can be simd vectors).
Definition concepts.hpp:40
Check if an algebra has soa layout.
Definition concepts.hpp:159
Transform concept.
Definition concepts.hpp:126
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
constexpr void resolve_mask(intersection_t &is, const trajectory_t &traj, const intersection_point< algebra_t, point_t, intersection::contains_pos > &ip, const surface_descr_t sf_desc, const mask_t &mask, const transform3_t &trf, const intersection::config &cfg={}, const scalar_t external_mask_tolerance=0.f)
Fill an intersection with the result of the intersection alg.
Definition intersector_base.hpp:189
std::array< value_t, kDIM > darray
Fixed-size array container.
Definition containers.hpp:30
const auto & get(const detray::tuple< Ts... > &t) noexcept
Get a tuple element by index from a const tuple.
Definition tuple.hpp:152
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_value_t< A > dvalue
Value scalar type of the algebra backend.
Definition algebra.hpp:48
get_point3D_t< A, T > dpoint3D
Three-dimensional point type for algebra A and value type T.
Definition algebra.hpp:72
get_point2D_t< A, T > dpoint2D
Two-dimensional point type for algebra A and value type T.
Definition algebra.hpp:68
Intersector configuration.
Definition intersection_config.hpp:21
Result of intersector: Point of intersection on a surface.
Definition intersection.hpp:43
Base class for an intersector: Provides mask based call interfaces for convenience.
Definition intersector_base.hpp:33
typename helix_intersector_impl< typename shape_t::template local_frame_type< algebra_t >, algebra_t >::template intersection_type< surface_descr_t > intersection_type
Definition intersector_base.hpp:53
typename helix_intersector_impl< typename shape_t::template local_frame_type< algebra_t >, algebra_t >::result_type result_type
Definition intersector_base.hpp:65
constexpr intersection_type< surface_descr_t > operator()(const trajectory_type< other_algebra_t > &traj, const surface_descr_t &sf, const mask_t &mask, const transform3_type &trf, const intersection::config &cfg={}, const scalar_type external_mask_tol=0.f) const
Operator function to find intersections between trajectory and a surface.
Definition intersector_base.hpp:85
typename helix_intersector_impl< typename shape_t::template local_frame_type< algebra_t >, algebra_t >::template trajectory_type< other_algebra_t > trajectory_type
Definition intersector_base.hpp:58
typename helix_intersector_impl< typename shape_t::template local_frame_type< algebra_t >, algebra_t >::algebra_type algebra_type
Definition intersector_base.hpp:36