ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
surface_kernels.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/builders/detail/radius_getter.hpp"
13#include "detray/core/concepts.hpp"
14#include "detray/definitions/algebra.hpp"
15#include "detray/definitions/units.hpp"
16#include "detray/geometry/mask.hpp"
17#include "detray/geometry/shapes.hpp"
18#include "detray/geometry/surface.hpp"
19#include "detray/geometry/tracking_volume.hpp"
20#include "detray/utils/concepts.hpp"
21
22// System include(s)
23#include <cassert>
24#include <optional>
25
26namespace detray::svgtools::utils {
27
31 public:
40 template <typename mask_group_t, concepts::index index_t,
41 concepts::transform3D transform3_t>
42 DETRAY_HOST inline auto operator()(const mask_group_t& mask_group,
43 const index_t& index,
44 const transform3_t& transform,
45 const std::size_t /*unused*/ = 0) const {
46 return link_start(mask_group.at(index), transform);
47 }
48
58 template <typename mask_group_t, concepts::interval idx_range_t,
59 concepts::transform3D transform3_t>
60 DETRAY_HOST inline auto operator()(const mask_group_t& mask_group,
61 const idx_range_t& idx_range,
62 const transform3_t& transform,
63 const std::size_t mask_idx) const {
64 assert(mask_idx < idx_range.size());
65 return link_start(mask_group.at(idx_range.lower() + mask_idx), transform);
66 }
67
68 private:
69 // Calculates the link starting location of the remaining shapes.
70 template <typename mask_t, concepts::transform3D transform3_t>
71 typename mask_t::point3_type inline link_start(
72 const mask_t& mask, const transform3_t& transform) const {
73 return transform.point_to_global(mask.centroid());
74 }
75
76 // Calculates the (optimal) link starting point for rings.
77 template <concepts::transform3D transform3_t, concepts::algebra algebra_t>
78 dpoint3D<algebra_t> inline link_start(
80 const transform3_t& transform) const {
81 using shape_t = detray::ring2D;
83 using point3_t = typename mask_t::point3_type;
84 using scalar_t = typename mask_t::scalar_type;
85
86 const scalar_t r{0.5f *
87 (mask[shape_t::e_inner_r] + mask[shape_t::e_outer_r])};
88 const scalar_t phi{detray::constant<scalar_t>::pi_2};
89
90 return mask_t::to_global_frame(transform, point3_t{r, phi, 0.f});
91 }
92
93 // Calculates the (optimal) link starting point for annuluses.
94 template <concepts::transform3D transform3_t, concepts::algebra algebra_t>
95 dpoint3D<algebra_t> inline link_start(
96 const detray::mask<detray::annulus2D, algebra_t>& mask,
97 const transform3_t& transform) const {
98 using shape_t = detray::annulus2D;
99 using mask_t = detray::mask<shape_t, algebra_t>;
100 using point3_t = typename mask_t::point3_type;
101 using scalar_t = typename mask_t::scalar_type;
102
103 const scalar_t r{(mask[shape_t::e_min_r] + mask[shape_t::e_max_r]) / 2.f};
104 const scalar_t phi{mask[shape_t::e_average_phi]};
105
106 return mask_t::to_global_frame(transform, point3_t{r, phi, 0.f});
107 }
108
109 // Calculates the (optimal) link starting point for concentric cylinders
110 template <concepts::transform3D transform3_t, concepts::algebra algebra_t>
111 dpoint3D<algebra_t> inline link_start(
112 const detray::mask<concentric_cylinder2D, algebra_t>& mask,
113 const transform3_t& transform) const {
114 using mask_t = detray::mask<concentric_cylinder2D, algebra_t>;
115 using point3_t = typename mask_t::point3_type;
116 using scalar_t = typename mask_t::scalar_type;
117
118 const scalar_t r{mask[concentric_cylinder2D::e_r]};
119 const scalar_t phi{detray::constant<scalar_t>::pi_2};
120 // Shift the center to the actual cylinder bounds
121 const scalar_t z{mask.centroid()[2]};
122
123 return mask_t::to_global_frame(transform, point3_t{phi, z, r});
124 }
125
126 // Calculates the (optimal) link starting point for cylinders (2D).
127 template <concepts::transform3D transform3_t, concepts::algebra algebra_t>
128 dpoint3D<algebra_t> inline link_start(
129 const detray::mask<cylinder2D, algebra_t>& mask,
130 const transform3_t& transform) const {
131 using mask_t = detray::mask<cylinder2D, algebra_t>;
132 using point3_t = typename mask_t::point3_type;
133 using scalar_t = typename mask_t::scalar_type;
134
135 const scalar_t r{mask[cylinder2D::e_r]};
136 const scalar_t phi{detray::constant<scalar_t>::pi_2};
137 // Shift the center to the actual cylinder bounds
138 const scalar_t z{mask.centroid()[2]};
139
140 return mask_t::to_global_frame(transform, point3_t{r * phi, z, r});
141 }
142
143 // Calculates the (optimal) link starting point for cylinders (3D).
144 template <concepts::transform3D transform3_t, concepts::algebra algebra_t>
145 dpoint3D<algebra_t> inline link_start(
146 const detray::mask<detray::cylinder3D, algebra_t>& mask,
147 const transform3_t& transform) const {
148 using shape_t = detray::cylinder3D;
149 using mask_t = detray::mask<shape_t, algebra_t>;
150 using point3_t = typename mask_t::point3_type;
151 using scalar_t = typename mask_t::scalar_type;
152
153 const scalar_t r{mask[shape_t::e_max_r]};
154 const scalar_t phi{0.5f *
155 (mask[shape_t::e_max_phi] + mask[shape_t::e_max_phi])};
156 const scalar_t z{mask.centroid()[2]};
157
158 return mask_t::to_global_frame(transform, point3_t{r, phi, z});
159 }
160};
161
165 public:
181 template <typename mask_group_t, concepts::index index_t,
182 concepts::detector detector_t, concepts::point3D point3_t,
183 concepts::vector3D vector3_t, concepts::scalar scalar_t>
184 DETRAY_HOST inline vector3_t operator()(
185 const mask_group_t& mask_group, const index_t& index,
186 const detector_t& detector,
188 const point3_t& surface_point, const vector3_t& surface_normal,
189 const scalar_t& link_length, const std::size_t /*unused*/ = 0) const {
190 return link_dir(mask_group.at(index), detector, volume, surface_point,
191 surface_normal) *
192 link_length +
193 surface_point;
194 }
195
212 template <typename mask_group_t, concepts::interval idx_range_t,
213 concepts::detector detector_t, concepts::point3D point3_t,
214 concepts::vector3D vector3_t, concepts::scalar scalar_t>
215 DETRAY_HOST inline vector3_t operator()(
216 const mask_group_t& mask_group, const idx_range_t& idx_range,
217 const detector_t& detector,
219 const point3_t& surface_point, const vector3_t& surface_normal,
220 const scalar_t& link_length, const std::size_t mask_idx) const {
221 assert(mask_idx < idx_range.size());
222 return link_dir(mask_group.at(idx_range.lower() + mask_idx), detector,
223 volume, surface_point, surface_normal) *
224 link_length +
225 surface_point;
226 }
227
228 private:
230 template <concepts::detector detector_t, typename mask_t,
231 concepts::point3D point3_t, concepts::vector3D vector3_t>
232 inline vector3_t link_dir(const mask_t& /*mask*/,
233 const detector_t& /*detector*/,
235 const point3_t& surface_point,
236 const vector3_t& surface_normal) const {
237 const auto dir = volume.center() - surface_point;
238 const auto dot_prod = vector::dot(dir, surface_normal);
239
240 // Should geometrically not happen with a local point 'surface_point'
241 assert(dot_prod != 0.f);
242
243 return math::copysign(1.f, dot_prod) * surface_normal;
244 }
245
247 template <concepts::detector detector_t, concepts::point3D point3_t,
248 concepts::vector3D vector3_t, typename shape_t>
249 requires std::is_same_v<shape_t, cylinder2D> ||
250 std::is_same_v<shape_t, concentric_cylinder2D>
251 inline vector3_t link_dir(
253 const detector_t& detector,
255 const point3_t& /*surface_point*/,
256 const vector3_t& surface_normal) const {
257 for (const auto& desc : volume.portals()) {
258 const detray::geometry::surface surface{detector, desc};
259
260 if (auto r =
261 surface
262 .template visit_mask<detray::detail::outer_radius_getter>()) {
263 if (*r > mask[shape_t::e_r]) {
264 return surface_normal;
265 }
266 }
267 }
268 return vector3_t{-1.f * surface_normal};
269 }
270};
271
272} // namespace detray::svgtools::utils
Facade for a detray detector surface.
Definition surface.hpp:36
Mask a region on a surface and link it to a volume.
Definition mask.hpp:46
auto centroid() const
Definition mask.hpp:282
Geometrical shape of a closed ring.
Definition ring2D.hpp:34
Facade for a detray detector volume.
Definition tracking_volume.hpp:44
Check if a type can be used as a detector.
Definition concepts.hpp:47
Index concept to access vector/matrix elements.
Definition concepts.hpp:54
Concept that checks if a type models an interval of some value that can be obtained with 'get'.
Definition concepts.hpp:41
Definition concepts.hpp:77
Scalar concept: Elements of vectors/matrices (can be simd vectors).
Definition concepts.hpp:40
Transform concept.
Definition concepts.hpp:126
Definition concepts.hpp:65
get_point3D_t< A, T > dpoint3D
Three-dimensional point type for algebra A and value type T.
Definition algebra.hpp:72
static constexpr scalar_t pi_2
π/2
Definition units.hpp:138