ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
line.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/containers.hpp"
14#include "detray/definitions/detail/qualifiers.hpp"
15#include "detray/definitions/indexing.hpp"
16#include "detray/definitions/math.hpp"
17#include "detray/definitions/units.hpp"
18#include "detray/geometry/coordinates/cartesian3D.hpp"
19#include "detray/geometry/coordinates/line2D.hpp"
20#include "detray/geometry/detail/shape_utils.hpp"
21
22// System include(s)
23#include <limits>
24#include <ostream>
25#include <string_view>
26#include <type_traits>
27
28namespace detray {
29
39template <bool kSquareCrossSect = false>
40class line {
41 public:
43 static constexpr std::string_view name = "line";
44
46 static constexpr bool square_cross_sect = kSquareCrossSect;
47
49 enum boundaries : unsigned int {
50 e_cross_section = 0u,
51 e_half_z = 1u,
52 e_size = 2u
53 };
54
56 template <concepts::scalar scalar_t>
58
60 template <concepts::algebra algebra_t>
62
64 template <typename bool_t>
65 using result_type = detail::boundary_check_result<bool_t>;
66
68 static constexpr std::size_t dim{2u};
69
79 template <concepts::scalar scalar_t, concepts::point point_t>
80 DETRAY_HOST_DEVICE inline scalar_t min_dist_to_boundary(
81 const bounds_type<scalar_t> &bounds, const point_t &loc_p) const {
82 if constexpr (square_cross_sect) {
83 const scalar_t dist_x = math::fabs(
84 math::fabs(loc_p[0] * math::cos(loc_p[2])) - bounds[e_cross_section]);
85 const scalar_t dist_y = math::fabs(
86 math::fabs(loc_p[0] * math::sin(loc_p[2])) - bounds[e_cross_section]);
87 const scalar_t dist_z =
88 math::fabs(math::fabs(loc_p[1]) - bounds[e_half_z]);
89
90 return math::min(math::min(dist_x, dist_y), dist_z);
91
92 } else {
93 return math::min(
94 math::fabs(math::fabs(loc_p[0]) - bounds[e_cross_section]),
95 math::fabs(math::fabs(loc_p[1]) - bounds[e_half_z]));
96 }
97 }
98
108 template <concepts::algebra algebra_t>
109 DETRAY_HOST_DEVICE constexpr result_type<dbool<algebra_t>> check_boundaries(
110 const bounds_type<dscalar<algebra_t>> &bounds,
111 const dtransform3D<algebra_t> &trf, const dpoint3D<algebra_t> &glob_p,
112 const dscalar<algebra_t> tol =
113 std::numeric_limits<dscalar<algebra_t>>::epsilon(),
114 const dscalar<algebra_t> edge_tol = 0.f) const {
115 const auto loc_3D{cartesian3D<algebra_t>::global_to_local(trf, glob_p, {})};
116
117 if constexpr (square_cross_sect) {
118 using scalar_t = dscalar<algebra_t>;
119
120 const scalar_t loc_0{math::fabs(loc_3D[0])};
121 const scalar_t loc_1{math::fabs(loc_3D[1])};
122 const scalar_t loc_2{math::fabs(loc_3D[2])};
123
124 // Check in local cartesian coordinates instead of line coordinates
125 auto inside_mask{(loc_0 <= (bounds[e_cross_section] + tol) &&
126 loc_1 <= (bounds[e_cross_section] + tol) &&
127 loc_2 <= (bounds[e_half_z] + tol))};
128
129 decltype(inside_mask) inside_edge{false};
130 if (detail::any_of(edge_tol > 0.f)) {
131 const scalar_t full_tol{tol + edge_tol};
132
133 inside_edge = (loc_0 <= (bounds[e_cross_section] + full_tol) &&
134 loc_1 <= (bounds[e_cross_section] + full_tol) &&
135 loc_2 <= (bounds[e_half_z] + full_tol));
136 }
137
138 return result_type<dbool<algebra_t>>{inside_mask, inside_edge};
139 } else {
140 // Check in local 2D line coordinates (sign not needed)
141 return check_boundaries(
142 bounds, dpoint2D<algebra_t>{vector::perp(loc_3D), loc_3D[2]}, tol,
143 edge_tol);
144 }
145 }
146
159 template <concepts::scalar scalar_t, concepts::point point_t>
160 DETRAY_HOST_DEVICE constexpr auto check_boundaries(
161 const bounds_type<scalar_t> &bounds, const point_t &loc_p,
162 const scalar_t tol = std::numeric_limits<scalar_t>::epsilon(),
163 const scalar_t edge_tol = 0.f) const {
164 // For a square cross section (e.g. a cell of drift chamber), we check
165 // if (1) x and y of the local cart. point is less than the half cell
166 // size and (2) the distance to the point of closest approach on the
167 // line from the line center is less than the half line length
168 if constexpr (square_cross_sect) {
169 const scalar_t loc_0{math::fabs(loc_p[0] * math::cos(loc_p[2]))};
170 const scalar_t loc_1{math::fabs(loc_p[0] * math::sin(loc_p[2]))};
171 const scalar_t loc_2{math::fabs(loc_p[1])};
172
173 auto inside_mask{(loc_0 <= (bounds[e_cross_section] + tol) &&
174 loc_1 <= (bounds[e_cross_section] + tol) &&
175 loc_2 <= bounds[e_half_z] + tol)};
176
177 decltype(inside_mask) inside_edge{false};
178 if (detail::any_of(edge_tol > 0.f)) {
179 const scalar_t full_tol{tol + edge_tol};
180
181 inside_edge = (loc_0 <= (bounds[e_cross_section] + full_tol) &&
182 loc_1 <= (bounds[e_cross_section] + full_tol) &&
183 loc_2 <= bounds[e_half_z] + full_tol);
184 }
185
186 return result_type<decltype(inside_mask)>{inside_mask, inside_edge};
187 }
188 // For a circular cross section (e.g. straw tube), we check if (1) the
189 // radial distance is within the scope and (2) the distance to the point
190 // of closest approach on the line from the line center is less than the
191 // line half length
192 else {
193 const scalar_t loc_0{math::fabs(loc_p[0])};
194 const scalar_t loc_1{math::fabs(loc_p[1])};
195
196 auto inside_mask{(loc_0 <= (bounds[e_cross_section] + tol) &&
197 loc_1 <= (bounds[e_half_z] + tol))};
198
199 decltype(inside_mask) inside_edge{false};
200 if (detail::any_of(edge_tol > 0.f)) {
201 const scalar_t full_tol{tol + edge_tol};
202
203 inside_edge = (loc_0 <= (bounds[e_cross_section] + full_tol) &&
204 loc_1 <= (bounds[e_half_z] + full_tol));
205 }
206
207 return result_type<decltype(inside_mask)>{inside_mask, inside_edge};
208 }
209 }
210
211
217 template <concepts::scalar scalar_t>
218 DETRAY_HOST_DEVICE constexpr scalar_t measure(
219 const bounds_type<scalar_t> &bounds) const {
220 if constexpr (square_cross_sect) {
221 return 8.f * bounds[e_half_z] * bounds[e_cross_section] *
222 bounds[e_cross_section];
223 } else {
224 return constant<scalar_t>::pi * 2.f * bounds[e_half_z] *
225 bounds[e_cross_section] * bounds[e_cross_section];
226 }
227 }
228
234 template <concepts::scalar scalar_t>
235 DETRAY_HOST_DEVICE constexpr scalar_t area(
236 const bounds_type<scalar_t> &bounds) const {
237 if constexpr (square_cross_sect) {
238 return 16.f * bounds[e_half_z] * bounds[e_cross_section];
239 } else {
240 return 4.f * constant<scalar_t>::pi * bounds[e_cross_section] *
241 bounds[e_half_z];
242 }
243 }
244
251 template <concepts::scalar scalar_t>
252 DETRAY_HOST_DEVICE constexpr bounds_type<scalar_t> merge(
253 const bounds_type<scalar_t> &bounds,
254 const bounds_type<scalar_t> &o_bounds) const {
255 bounds_type<scalar_t> new_bounds{};
256
257 new_bounds[e_cross_section] =
258 math::max(bounds[e_cross_section], o_bounds[e_cross_section]);
259 new_bounds[e_half_z] = math::max(bounds[e_half_z], o_bounds[e_half_z]);
260
261 return new_bounds;
262 }
263
273 template <concepts::algebra algebra_t>
274 DETRAY_HOST_DEVICE inline darray<dscalar<algebra_t>, 6> local_min_bounds(
275 const bounds_type<dscalar<algebra_t>> &bounds,
276 const dscalar<algebra_t> env =
277 std::numeric_limits<dscalar<algebra_t>>::epsilon()) const {
278 using scalar_t = dscalar<algebra_t>;
279
280 assert(env > 0.f);
281 const scalar_t xy_bound{bounds[e_cross_section] + env};
282 const scalar_t z_bound{bounds[e_half_z] + env};
283
284 return {-xy_bound, -xy_bound, -z_bound, xy_bound, xy_bound, z_bound};
285 }
286
288 template <concepts::algebra algebra_t>
289 DETRAY_HOST_DEVICE dpoint3D<algebra_t> centroid(
290 const bounds_type<dscalar<algebra_t>> & /*unused*/) const {
291 return {0.f, 0.f, 0.f};
292 }
293
300 template <concepts::algebra algebra_t>
302 const bounds_type<dscalar<algebra_t>> &bounds, dindex /*ignored*/) const {
303 using point3_t = dpoint3D<algebra_t>;
304
305 point3_t lc = {0.f, 0.f, -bounds[e_half_z]};
306 point3_t rc = {0.f, 0.f, bounds[e_half_z]};
307
308 return {lc, rc};
309 }
310
317 template <concepts::scalar scalar_t>
318 DETRAY_HOST constexpr bool check_consistency(
319 const bounds_type<scalar_t> &bounds, std::ostream &os) const {
320 constexpr auto tol{10.f * std::numeric_limits<scalar_t>::epsilon()};
321
322 if (bounds[e_cross_section] < tol) {
323 os << "DETRAY ERROR (HOST): Radius/sides must be in the range (0, "
324 "numeric_max)"
325 << std::endl;
326 return false;
327 }
328 if (bounds[e_half_z] < tol) {
329 os << "DETRAY ERROR (HOST): Half length z must be in the range (0, "
330 "numeric_max)"
331 << std::endl;
332 return false;
333 }
334
335 return true;
336 }
337};
338
343
344} // namespace detray
Geometrical shape of a line surface.
Definition line.hpp:40
darray< dscalar< algebra_t >, 6 > local_min_bounds(const bounds_type< dscalar< algebra_t > > &bounds, const dscalar< algebra_t > env=std::numeric_limits< dscalar< algebra_t > >::epsilon()) const
Lower and upper point for minimal axis aligned bounding box.
Definition line.hpp:274
darray< scalar_t, boundaries::e_size > bounds_type
Container definition for the shape boundary values.
Definition line.hpp:57
scalar_t min_dist_to_boundary(const bounds_type< scalar_t > &bounds, const point_t &loc_p) const
Find the minimum distance to any boundary.
Definition line.hpp:80
dvector< dpoint3D< algebra_t > > vertices(const bounds_type< dscalar< algebra_t > > &bounds, dindex) const
Generate vertices in local cartesian frame.
Definition line.hpp:301
constexpr bounds_type< scalar_t > merge(const bounds_type< scalar_t > &bounds, const bounds_type< scalar_t > &o_bounds) const
Merge two line shapes.
Definition line.hpp:252
static constexpr std::string_view name
Definition line.hpp:43
constexpr scalar_t measure(const bounds_type< scalar_t > &bounds) const
Measure of the shape: Volume.
Definition line.hpp:218
constexpr result_type< dbool< algebra_t > > check_boundaries(const bounds_type< dscalar< algebra_t > > &bounds, const dtransform3D< algebra_t > &trf, const dpoint3D< algebra_t > &glob_p, const dscalar< algebra_t > tol=std::numeric_limits< dscalar< algebra_t > >::epsilon(), const dscalar< algebra_t > edge_tol=0.f) const
Check boundary values for a local point.
Definition line.hpp:109
constexpr auto check_boundaries(const bounds_type< scalar_t > &bounds, const point_t &loc_p, const scalar_t tol=std::numeric_limits< scalar_t >::epsilon(), const scalar_t edge_tol=0.f) const
Definition line.hpp:160
dpoint3D< algebra_t > centroid(const bounds_type< dscalar< algebra_t > > &) const
Definition line.hpp:289
constexpr scalar_t area(const bounds_type< scalar_t > &bounds) const
The area of a the shape.
Definition line.hpp:235
static constexpr bool square_cross_sect
Definition line.hpp:46
boundaries
Indices for the line cross-section and half-length boundary values.
Definition line.hpp:49
static constexpr std::size_t dim
Definition line.hpp:68
constexpr bool check_consistency(const bounds_type< scalar_t > &bounds, std::ostream &os) const
Check consistency of boundary values.
Definition line.hpp:318
detail::boundary_check_result< bool_t > result_type
Result type of a boundary check.
Definition line.hpp:65
line2D< algebra_t > local_frame_type
Local coordinate frame for boundary checks.
Definition line.hpp:61
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
line< false > line_circular
Radial crossection, boundary check in polar coordinates.
Definition line.hpp:340
vecmem::vector< value_t > dvector
Vector container backed by vecmem.
Definition containers.hpp:34
unsigned int dindex
Default index type.
Definition indexing.hpp:18
line< true > line_square
Square crossection, boundary check in cartesian coordinates.
Definition line.hpp:342
std::array< value_t, kDIM > darray
Fixed-size array container.
Definition containers.hpp:30
get_transform3D_t< A, T > dtransform3D
Three-dimensional transform type for algebra A and value type T.
Definition algebra.hpp:84
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
static loc_point global_to_local(const transform3_type &trf, const point3_type &p, const vector3_type &)
This method transforms a point from a global cartesian 3D frame to a local 3D cartesian point Convert...
Definition cartesian3D.hpp:57
static constexpr scalar_t pi
π
Definition units.hpp:136
Projection into a line coordinate frame.
Definition line2D.hpp:20