ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
annulus2D.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/polar2D.hpp"
20#include "detray/geometry/detail/shape_utils.hpp"
21#include "detray/geometry/detail/vertexer.hpp"
22
23// System include(s)
24#include <limits>
25#include <ostream>
26#include <string_view>
27
28namespace detray {
29
48class annulus2D {
49 public:
51 static constexpr std::string_view name = "(stereo) annulus2D";
52
54 enum boundaries : unsigned int {
55 e_min_r = 0u,
56 e_max_r = 1u,
57 e_min_phi_rel = 2u,
58 e_max_phi_rel = 3u,
59 e_average_phi = 4u,
60 e_shift_x = 5u,
61 e_shift_y = 6u,
62 e_size = 7u,
63 };
64
66 template <concepts::scalar scalar_t>
68
70 template <concepts::algebra algebra_t>
72
74 template <typename bool_t>
75 using result_type = detail::boundary_check_result<bool_t>;
76
78 static constexpr std::size_t dim{2u};
79
81 template <concepts::scalar scalar_t>
83 const bounds_type<scalar_t> &bounds) const {
84 // Half stereo angle (phi_s / 2) (y points in the long strip direction)
85 return 2.f * math::atan(bounds[e_shift_y] / bounds[e_shift_x]);
86 }
87
91 template <concepts::scalar scalar_t, concepts::point point_t>
92 DETRAY_HOST_DEVICE inline scalar_t get_phi_rel(
93 const bounds_type<scalar_t> &bounds, const point_t &loc_p) const {
94 // Rotate by avr phi in the focal system (this is usually zero)
95 return loc_p[1] - bounds[e_average_phi];
96 }
97
101 template <concepts::scalar scalar_t, concepts::point point_t>
102 DETRAY_HOST_DEVICE inline scalar_t get_r2_beam_frame(
103 const bounds_type<scalar_t> &bounds, const point_t &loc_p) const {
104 // Go to beam frame to check r boundaries. Use the origin
105 // shift in polar coordinates for that
106 // TODO: Put shift in r-phi into the bounds?
107 point_t shift_xy{};
108 shift_xy[0u] = -bounds[e_shift_x];
109 shift_xy[1u] = -bounds[e_shift_y];
110 const scalar_t shift_r = vector::perp(shift_xy);
111 const scalar_t shift_phi = vector::phi(shift_xy);
112
113 return shift_r * shift_r + loc_p[0] * loc_p[0] +
114 2.f * shift_r * loc_p[0] *
115 math::cos(get_phi_rel(bounds, loc_p) - shift_phi);
116 }
117
128 template <concepts::scalar scalar_t, concepts::point point_t>
129 DETRAY_HOST_DEVICE inline scalar_t min_dist_to_boundary(
130 const bounds_type<scalar_t> &bounds, const point_t &loc_p) const {
131 // The two quantities to check: r^2 in beam system, phi in focal system:
132
133 // Rotate by avr phi in the focal system (this is usually zero)
134 const scalar_t phi_rel_focal = get_phi_rel(bounds, loc_p);
135
136 // Check phi boundaries, which are well def. in focal frame
137 const scalar_t min_phi_dist =
138 math::min(math::fabs(phi_rel_focal - bounds[e_min_phi_rel]),
139 math::fabs(bounds[e_max_phi_rel] - phi_rel_focal));
140
141 const auto r_beam = math::sqrt(get_r2_beam_frame(bounds, loc_p));
142
143 const scalar_t min_r_dist = math::min(math::fabs(r_beam - bounds[e_min_r]),
144 math::fabs(bounds[e_max_r] - r_beam));
145
146 // Compare the radius with the chord
147 return math::min(min_r_dist,
148 2.f * loc_p[0] * math::sin(0.5f * min_phi_dist));
149 }
150
160 template <concepts::algebra algebra_t>
161 DETRAY_HOST_DEVICE constexpr result_type<dbool<algebra_t>> check_boundaries(
162 const bounds_type<dscalar<algebra_t>> &bounds,
163 const dtransform3D<algebra_t> &trf, const dpoint3D<algebra_t> &glob_p,
164 const dscalar<algebra_t> tol =
165 std::numeric_limits<dscalar<algebra_t>>::epsilon(),
166 const dscalar<algebra_t> edge_tol = 0.f) const {
167 using scalar_t = dscalar<algebra_t>;
168
169 // Move point to local plane: Focal frame in cartesian coordinates
170 const auto loc_3D{cartesian3D<algebra_t>::global_to_local(trf, glob_p, {})};
171
172 // Shift local 3D position into beam frame to check the radius
173 const scalar_t new_x{loc_3D[0] + bounds[e_shift_x]};
174 const scalar_t new_y{loc_3D[1] + bounds[e_shift_y]};
175
176 const scalar_t r_beam{math::sqrt(math::fma(new_x, new_x, new_y * new_y))};
177
178 auto inside_mask = ((r_beam + tol) >= bounds[e_min_r]) &&
179 (r_beam <= (bounds[e_max_r] + tol));
180
181 // Try to avoid the costly phi calculation
182 auto phi_focal{detail::invalid_value<scalar_t>()};
183 if (detail::any_of(inside_mask)) {
184 // Get phi for phi-bounds check and rotate by average phi
185 phi_focal = vector::phi(loc_3D) - bounds[e_average_phi];
186 // Estimate angular tolerance along r
187 const scalar_t phi_tol{detail::phi_tolerance(tol, r_beam)};
188
189 inside_mask = (phi_focal >= (bounds[e_min_phi_rel] - phi_tol)) &&
190 (phi_focal <= (bounds[e_max_phi_rel] + phi_tol)) &&
191 inside_mask;
192 }
193
194 decltype(inside_mask) inside_edge{false};
195 if (detail::any_of(edge_tol > 0.f)) {
196 // Edge tolerance
197 const scalar_t full_tol{tol + edge_tol};
198
199 inside_edge = ((r_beam + full_tol) >= bounds[e_min_r]) &&
200 (r_beam <= (bounds[e_max_r] + full_tol));
201
202 if (detail::any_of(inside_edge)) {
203 // If phi had not been calculated before, do it now
204 if (detail::is_invalid_value(phi_focal)) {
205 phi_focal = vector::phi(loc_3D) - bounds[e_average_phi];
206 }
207
208 const scalar_t phi_tol_full{detail::phi_tolerance(full_tol, r_beam)};
209
210 inside_edge = (phi_focal >= (bounds[e_min_phi_rel] - phi_tol_full)) &&
211 (phi_focal <= (bounds[e_max_phi_rel] + phi_tol_full)) &&
212 inside_edge;
213 }
214 }
215
216 return result_type<decltype(inside_mask)>{inside_mask, inside_edge};
217 }
218
229 template <concepts::scalar scalar_t, concepts::point point_t>
230 DETRAY_HOST_DEVICE constexpr auto check_boundaries(
231 const bounds_type<scalar_t> &bounds, const point_t &loc_p,
232 const scalar_t tol = std::numeric_limits<scalar_t>::epsilon(),
233 const scalar_t edge_tol = 0.f) const {
234 // The two quantities to check: r^2 in beam system, phi in focal system:
235
236 // Rotate by avr phi in the focal system (this is usually zero)
237 const scalar_t phi_focal = get_phi_rel(bounds, loc_p);
238
239 // Check phi boundaries, which are well def. in focal frame
240 const scalar_t phi_tol = detail::phi_tolerance(tol, loc_p[0]);
241 auto inside_mask = !((phi_focal < (bounds[e_min_phi_rel] - phi_tol)) ||
242 (phi_focal > (bounds[e_max_phi_rel] + phi_tol)));
243
244 // Try to avoid the costly r_beam calculation
245 auto r_beam2{detail::invalid_value<scalar_t>()};
246 if (detail::any_of(inside_mask)) {
247 r_beam2 = get_r2_beam_frame(bounds, loc_p);
248
249 // Apply tolerances as squares: 0 <= a, 0 <= b: a^2 <= b^2 <=> a <=
250 // b
251 const scalar_t minR_tol =
252 math::max(bounds[e_min_r] - tol, static_cast<scalar_t>(0.f));
253 const scalar_t maxR_tol = bounds[e_max_r] + tol;
254
255 assert(detail::all_of(minR_tol >= static_cast<scalar_t>(0.f)));
256
257 inside_mask = (r_beam2 >= (minR_tol * minR_tol)) &&
258 (r_beam2 <= (maxR_tol * maxR_tol)) && inside_mask;
259 }
260
261 decltype(inside_mask) inside_edge{false};
262 if (detail::any_of(edge_tol > 0.f)) {
263 // Edge tolerance
264 const scalar_t full_tol{tol + edge_tol};
265 const scalar_t phi_tol_full = detail::phi_tolerance(full_tol, loc_p[0]);
266
267 const auto phi_check_edge =
268 (phi_focal >= (bounds[e_min_phi_rel] - phi_tol_full)) &&
269 (phi_focal <= (bounds[e_max_phi_rel] + phi_tol_full));
270
271 if (detail::any_of(inside_edge)) {
272 // If phi had not been calculated before, do it now
273 if (detail::is_invalid_value(r_beam2)) {
274 r_beam2 = get_r2_beam_frame(bounds, loc_p);
275 }
276
277 const scalar_t minR_tol_edge =
278 math::max(bounds[e_min_r] - full_tol, static_cast<scalar_t>(0.f));
279 const scalar_t maxR_tol_edge = bounds[e_max_r] + full_tol;
280
281 assert(detail::all_of(minR_tol_edge >= static_cast<scalar_t>(0.f)));
282
283 inside_edge = (r_beam2 >= (minR_tol_edge * minR_tol_edge)) &&
284 (r_beam2 <= (maxR_tol_edge * maxR_tol_edge)) &&
285 phi_check_edge;
286 }
287 }
288
289 return result_type<decltype(inside_mask)>{inside_mask, inside_edge};
290 }
291
292
300 template <concepts::scalar scalar_t>
301 DETRAY_HOST_DEVICE constexpr scalar_t measure(
302 const bounds_type<scalar_t> &bounds) const {
303 return area(bounds);
304 }
305
312 template <concepts::scalar scalar_t>
313 DETRAY_HOST_DEVICE constexpr scalar_t area(
314 const bounds_type<scalar_t> & /*bounds*/) const {
315 return detail::invalid_value<scalar_t>();
316 }
317
324 template <concepts::scalar scalar_t>
325 DETRAY_HOST_DEVICE constexpr bounds_type<scalar_t> merge(
326 const bounds_type<scalar_t> &bounds,
327 const bounds_type<scalar_t> &o_bounds) const {
328 assert(bounds[e_average_phi] == o_bounds[e_average_phi]);
329 assert(bounds[e_shift_x] == o_bounds[e_shift_x]);
330 assert(bounds[e_shift_y] == o_bounds[e_shift_y]);
331
332 bounds_type<scalar_t> new_bounds{};
333
334 new_bounds[e_min_r] = math::min(bounds[e_min_r], o_bounds[e_min_r]);
335 new_bounds[e_max_r] = math::max(bounds[e_max_r], o_bounds[e_max_r]);
336 new_bounds[e_min_phi_rel] =
337 math::min(bounds[e_min_phi_rel], o_bounds[e_min_phi_rel]);
338 new_bounds[e_max_phi_rel] =
339 math::max(bounds[e_max_phi_rel], o_bounds[e_max_phi_rel]);
340 new_bounds[e_average_phi] = bounds[e_average_phi];
341 new_bounds[e_shift_x] = bounds[e_shift_x];
342 new_bounds[e_shift_y] = bounds[e_shift_y];
343
344 return new_bounds;
345 }
346
356 // @TODO: this is a terrible approximation: restrict to annulus corners
357 template <concepts::algebra algebra_t>
359 const bounds_type<dscalar<algebra_t>> &bounds,
360 const dscalar<algebra_t> env =
361 std::numeric_limits<dscalar<algebra_t>>::epsilon()) const {
362 using scalar_t = dscalar<algebra_t>;
363 using point_t = dpoint2D<algebra_t>;
364
365 assert(env > 0.f);
366
367 const auto c_pos = corners(bounds);
368
369 const scalar_t o_x{bounds[e_shift_x]};
370 const scalar_t o_y{bounds[e_shift_y]};
371
372 // Corner points 'b' and 'c' in local cartesian beam system
373 const point_t b{c_pos[4] * math::cos(c_pos[5]) - o_x,
374 c_pos[4] * math::sin(c_pos[5]) - o_y};
375 const point_t c{c_pos[6] * math::cos(c_pos[7]) - o_x,
376 c_pos[6] * math::sin(c_pos[7]) - o_y};
377
378 // bisector = 0.5 * (c + b). Scale to the length of the full circle to
379 // get the outermost point
380 const point_t t = bounds[e_max_r] * vector::normalize(c + b);
381
382 // Find the min/max positions in x and y
383 darray<scalar_t, 5> x_pos{c_pos[2] * math::cos(c_pos[3]) - o_x, b[0], c[0],
384 c_pos[0] * math::cos(c_pos[1]) - o_x, t[0]};
385 darray<scalar_t, 5> y_pos{c_pos[2] * math::sin(c_pos[3]) - o_y, b[1], c[1],
386 c_pos[0] * math::sin(c_pos[1]) - o_y, t[1]};
387
388 constexpr scalar_t inv{detail::invalid_value<scalar_t>()};
389 scalar_t min_x{inv};
390 scalar_t min_y{inv};
391 scalar_t max_x{-inv};
392 scalar_t max_y{-inv};
393 for (unsigned int i{0u}; i < 5u; ++i) {
394 min_x = x_pos[i] < min_x ? x_pos[i] : min_x;
395 max_x = x_pos[i] > max_x ? x_pos[i] : max_x;
396 min_y = y_pos[i] < min_y ? y_pos[i] : min_y;
397 max_y = y_pos[i] > max_y ? y_pos[i] : max_y;
398 }
399
400 return {min_x - env, min_y - env, -env, max_x + env, max_y + env, env};
401 }
402
412 template <concepts::scalar scalar_t>
413 DETRAY_HOST_DEVICE darray<scalar_t, 8> corners(
414 const bounds_type<scalar_t> &bounds) const {
415 // Calculate the r-coordinate of a point in the strip system from the
416 // circle arc radius (e.g. min_r) and the phi position in the strip
417 // system (e.g. for the corners these are average_phi + min_phi_rel and
418 // average_phi + max_phi_rel).
419 auto get_strips_pc_r = [&bounds](const scalar_t R,
420 const scalar_t phi) -> scalar_t {
421 // f: Shift distance between beamline and focal system origin
422 const scalar_t f2{bounds[e_shift_x] * bounds[e_shift_x] +
423 bounds[e_shift_y] * bounds[e_shift_y]};
424
425 // f * sin(phi_s / 2 + phi) using: f_y / f = sin(phi_s / 2) and
426 // sin(a + b) = sin(a)*cos(b) + cos(a)*sin(b)
427 const scalar_t f_sin_phi{bounds[e_shift_x] * math::cos(phi) +
428 bounds[e_shift_y] * math::sin(phi)};
429
430 return f_sin_phi + math::sqrt(f_sin_phi * f_sin_phi - f2 + R * R);
431 };
432
433 // Calculate the polar coordinates for the corners
434 const scalar_t min_phi{bounds[e_average_phi] + bounds[e_min_phi_rel]};
435 const scalar_t max_phi{bounds[e_average_phi] + bounds[e_max_phi_rel]};
436 darray<scalar_t, 8> corner_pos;
437 // bottom left: min_r, min_phi_rel
438 corner_pos[0] = get_strips_pc_r(bounds[e_min_r], min_phi);
439 corner_pos[1] = min_phi;
440 // bottom right: min_r, max_phi_rel
441 corner_pos[2] = get_strips_pc_r(bounds[e_min_r], max_phi);
442 corner_pos[3] = max_phi;
443 // top right: max_r, max_phi_rel
444 corner_pos[4] = get_strips_pc_r(bounds[e_max_r], max_phi);
445 corner_pos[5] = max_phi;
446 // top left: max_r, min_phi_rel
447 corner_pos[6] = get_strips_pc_r(bounds[e_max_r], min_phi);
448 corner_pos[7] = min_phi;
449
450 return corner_pos;
451 }
452
457 template <concepts::algebra algebra_t>
458 DETRAY_HOST_DEVICE dpoint3D<algebra_t> centroid(
459 const bounds_type<dscalar<algebra_t>> &bounds) const {
460 using scalar_t = dscalar<algebra_t>;
461
462 // Strip polar system
463 const auto crns = corners(bounds);
464
465 // Coordinates of the centroid position in strip system
466 const scalar_t r{0.25f * (crns[0] + crns[2] + crns[4] + crns[6])};
467 const scalar_t phi{bounds[e_average_phi]};
468
469 return r * dpoint3D<algebra_t>{math::cos(phi), math::sin(phi),
470 static_cast<scalar_t>(0)};
471 }
472
479 template <concepts::algebra algebra_t>
481 const bounds_type<dscalar<algebra_t>> &bounds, dindex n_seg) const {
482 using scalar_t = dscalar<algebra_t>;
483 using point2_t = dpoint2D<algebra_t>;
484 using point3_t = dpoint3D<algebra_t>;
485
486 scalar_t min_r = bounds[e_min_r];
487 scalar_t max_r = bounds[e_max_r];
488 scalar_t min_phi = bounds[e_average_phi] + bounds[e_min_phi_rel];
489 scalar_t max_phi = bounds[e_average_phi] + bounds[e_max_phi_rel];
490 scalar_t origin_x = bounds[e_shift_x];
491 scalar_t origin_y = bounds[e_shift_y];
492
493 point2_t origin_m = {origin_x, origin_y};
494
496 auto circIx = [](scalar_t O_x, scalar_t O_y, scalar_t r,
497 scalar_t phi) -> point2_t {
498 // ____________________________________________
499 // / 2 2 2 2 2 2
500 // O_x + O_y*m - \/ - O_x *m + 2*O_x*O_y*m - O_y + m *r + r
501 // x =
502 // --------------------------------------------------------------
503 // 2
504 // m + 1
505 //
506 // y = m*x
507 //
508 scalar_t m = math::tan(phi);
509 point2_t dir = {math::cos(phi), math::sin(phi)};
510 scalar_t x1 = (O_x + O_y * m -
511 math::sqrt(-math::pow(O_x, 2.f) * math::pow(m, 2.f) +
512 2.f * O_x * O_y * m - math::pow(O_y, 2.f) +
513 math::pow(m, 2.f) * math::pow(r, 2.f) +
514 math::pow(r, 2.f))) /
515 (math::pow(m, 2.f) + 1.f);
516 scalar_t x2 = (O_x + O_y * m +
517 math::sqrt(-math::pow(O_x, 2.f) * math::pow(m, 2.f) +
518 2.f * O_x * O_y * m - math::pow(O_y, 2.f) +
519 math::pow(m, 2.f) * math::pow(r, 2.f) +
520 math::pow(r, 2.f))) /
521 (math::pow(m, 2.f) + 1.f);
522
523 if (point2_t v1 = {x1, m * x1}; vector::dot(v1, dir) > 0.f) {
524 return v1;
525 }
526 return {x2, m * x2};
527 };
528
529 // calculate corners in STRIP XY
530 point2_t ul_xy = circIx(origin_x, origin_y, max_r, max_phi);
531 point2_t ll_xy = circIx(origin_x, origin_y, min_r, max_phi);
532 point2_t ur_xy = circIx(origin_x, origin_y, max_r, min_phi);
533 point2_t lr_xy = circIx(origin_x, origin_y, min_r, min_phi);
534
535 auto inner_phi = detail::phi_values(vector::phi(lr_xy - origin_m),
536 vector::phi(ll_xy - origin_m), n_seg);
537 auto outer_phi = detail::phi_values(vector::phi(ul_xy - origin_m),
538 vector::phi(ur_xy - origin_m), n_seg);
539
540 dvector<point3_t> annulus_vertices;
541 annulus_vertices.reserve(inner_phi.size() + outer_phi.size());
542 for (scalar_t iphi : inner_phi) {
543 annulus_vertices.push_back(point3_t{min_r * math::cos(iphi) + origin_x,
544 min_r * math::sin(iphi) + origin_y,
545 0.f});
546 }
547
548 for (scalar_t ophi : outer_phi) {
549 annulus_vertices.push_back(point3_t{max_r * math::cos(ophi) + origin_x,
550 max_r * math::sin(ophi) + origin_y,
551 0.f});
552 }
553
554 return annulus_vertices;
555 }
556
563 template <concepts::scalar scalar_t>
564 DETRAY_HOST constexpr bool check_consistency(
565 const bounds_type<scalar_t> &bounds, std::ostream &os) const {
566 constexpr auto tol{10.f * std::numeric_limits<scalar_t>::epsilon()};
567
568 if (math::signbit(bounds[e_min_r]) || bounds[e_max_r] < tol) {
569 os << "DETRAY ERROR (HOST): Radial bounds must be in the range [0, "
570 "numeric_max)";
571 return false;
572 }
573 if (bounds[e_min_r] >= bounds[e_max_r] ||
574 math::fabs(bounds[e_min_r] - bounds[e_max_r]) < tol) {
575 os << "DETRAY ERROR (HOST): Min radius must be smaller than max "
576 "radius.";
577 return false;
578 }
579 if ((bounds[e_min_phi_rel] < -constant<scalar_t>::pi ||
580 bounds[e_min_phi_rel] > constant<scalar_t>::pi) ||
581 (bounds[e_max_phi_rel] < -constant<scalar_t>::pi ||
582 bounds[e_max_phi_rel] > constant<scalar_t>::pi) ||
583 (bounds[e_average_phi] < -constant<scalar_t>::pi ||
584 bounds[e_average_phi] > constant<scalar_t>::pi)) {
585 os << "DETRAY ERROR (HOST): Angles must map onto [-pi, pi] range.";
586 return false;
587 }
588 if (bounds[e_min_phi_rel] >= bounds[e_max_phi_rel] ||
589 math::fabs(bounds[e_min_phi_rel] - bounds[e_max_phi_rel]) < tol) {
590 os << "DETRAY ERROR (HOST): Min relative angle must be smaller "
591 "than max relative "
592 "angle.";
593 return false;
594 }
595
596 return true;
597 }
598};
599
600} // namespace detray
Geometrical shape of a stereo annulus that is used for the ITk strip endcaps.
Definition annulus2D.hpp:48
constexpr bounds_type< scalar_t > merge(const bounds_type< scalar_t > &bounds, const bounds_type< scalar_t > &o_bounds) const
Merge two annulus shapes.
Definition annulus2D.hpp:325
constexpr bool check_consistency(const bounds_type< scalar_t > &bounds, std::ostream &os) const
Check consistency of boundary values.
Definition annulus2D.hpp:564
constexpr scalar_t area(const bounds_type< scalar_t > &) const
The area of a the shape.
Definition annulus2D.hpp:313
scalar_t get_phi_rel(const bounds_type< scalar_t > &bounds, const point_t &loc_p) const
Definition annulus2D.hpp:92
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 annulus2D.hpp:358
constexpr scalar_t measure(const bounds_type< scalar_t > &bounds) const
Measure of the shape: Area.
Definition annulus2D.hpp:301
dpoint3D< algebra_t > centroid(const bounds_type< dscalar< algebra_t > > &bounds) const
Definition annulus2D.hpp:458
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 annulus2D.hpp:129
darray< scalar_t, 8 > corners(const bounds_type< scalar_t > &bounds) const
Stereo annulus corners in polar strip system.
Definition annulus2D.hpp:413
dvector< dpoint3D< algebra_t > > vertices(const bounds_type< dscalar< algebra_t > > &bounds, dindex n_seg) const
Generate vertices in local cartesian frame.
Definition annulus2D.hpp:480
static constexpr std::string_view name
The name for this shape.
Definition annulus2D.hpp:51
polar2D< algebra_t > local_frame_type
Local coordinate frame ( focal system ).
Definition annulus2D.hpp:71
darray< scalar_t, 8 > stereo_angle(const bounds_type< scalar_t > &bounds) const
Definition annulus2D.hpp:82
detail::boundary_check_result< bool_t > result_type
Result type of a boundary check.
Definition annulus2D.hpp:75
darray< scalar_t, boundaries::e_size > bounds_type
Container definition for the shape boundary values.
Definition annulus2D.hpp:67
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 annulus2D.hpp:230
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 annulus2D.hpp:161
static constexpr std::size_t dim
Dimension of the local coordinate system.
Definition annulus2D.hpp:78
scalar_t get_r2_beam_frame(const bounds_type< scalar_t > &bounds, const point_t &loc_p) const
Definition annulus2D.hpp:102
boundaries
Names for the mask boundary values.
Definition annulus2D.hpp:54
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
vecmem::vector< value_t > dvector
Vector container backed by vecmem.
Definition containers.hpp:34
unsigned int dindex
Default index type.
Definition indexing.hpp:18
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 polar coordinate frame.
Definition polar2D.hpp:20