ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
cylinder3D.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/cylindrical3D.hpp"
19#include "detray/geometry/detail/shape_utils.hpp"
20
21// System include(s)
22#include <limits>
23#include <ostream>
24#include <stdexcept>
25#include <string_view>
26
27namespace detray {
28
33 public:
35 static constexpr std::string_view name = "cylinder3D";
36
38 enum boundaries : unsigned int {
39 e_min_r = 0u,
40 e_min_phi = 1u,
41 e_min_z = 2u,
42 e_max_r = 3u,
43 e_max_phi = 4u,
44 e_max_z = 5u,
45 e_size = 6u,
46 };
47
49 template <concepts::scalar scalar_t>
51
53 template <concepts::algebra algebra_t>
55
57 template <typename bool_t>
58 using result_type = bool_t;
59
61 static constexpr std::size_t dim{3u};
62
72 template <concepts::scalar scalar_t, concepts::point point_t>
73 DETRAY_HOST_DEVICE inline scalar_t min_dist_to_boundary(
74 const bounds_type<scalar_t> &bounds, const point_t &loc_p) const {
75 const scalar_t min_r_dist =
76 math::min(math::fabs(loc_p[0] - bounds[e_min_r]),
77 math::fabs(bounds[e_max_r] - loc_p[0]));
78 const scalar_t min_phi_dist =
79 math::min(math::fabs(loc_p[1] - bounds[e_min_phi]),
80 math::fabs(bounds[e_max_phi] - loc_p[1]));
81 const scalar_t min_z_dist =
82 math::min(math::fabs(loc_p[2] - bounds[e_min_z]),
83 math::fabs(bounds[e_max_z] - loc_p[2]));
84
85 // Use the chord for the phi distance
86 return math::min(
87 math::min(min_r_dist, 2.f * loc_p[0] * math::sin(0.5f * min_phi_dist)),
88 min_z_dist);
89 }
90
99 template <concepts::algebra algebra_t>
100 DETRAY_HOST_DEVICE constexpr result_type<dbool<algebra_t>> check_boundaries(
101 const bounds_type<dscalar<algebra_t>> &bounds,
102 const dtransform3D<algebra_t> &trf, const dpoint3D<algebra_t> &glob_p,
103 const dscalar<algebra_t> tol =
104 std::numeric_limits<dscalar<algebra_t>>::epsilon(),
105 const dscalar<algebra_t> /*edge_tol*/ = 0.f) const {
106 // Get the full local position
107 const auto loc_p =
109
110 return check_boundaries(bounds, loc_p, tol);
111 }
112
123 template <concepts::scalar scalar_t, concepts::point point_t>
124 DETRAY_HOST_DEVICE constexpr auto check_boundaries(
125 const bounds_type<scalar_t> &bounds, const point_t &loc_p,
126 const scalar_t tol = std::numeric_limits<scalar_t>::epsilon(),
127 const scalar_t /*edge_tol*/ = 0.f) const {
128 const scalar_t phi_tol = detail::phi_tolerance(tol, loc_p[0]);
129
130 return ((bounds[e_min_r] - tol) <= loc_p[0] &&
131 (bounds[e_min_phi] - phi_tol) <= loc_p[1] &&
132 (bounds[e_min_z] - tol) <= loc_p[2] &&
133 loc_p[0] <= (bounds[e_max_r] + tol) &&
134 loc_p[1] <= (bounds[e_max_phi] + phi_tol) &&
135 loc_p[2] <= (bounds[e_max_z] + tol));
136 }
137
138
144 template <concepts::scalar scalar_t>
145 DETRAY_HOST_DEVICE constexpr scalar_t measure(
146 const bounds_type<scalar_t> &bounds) const {
147 return volume(bounds);
148 }
149
155 template <concepts::scalar scalar_t>
156 DETRAY_HOST_DEVICE constexpr scalar_t volume(
157 const bounds_type<scalar_t> &bounds) const {
158 return constant<scalar_t>::pi * (bounds[e_max_z] - bounds[e_min_z]) *
159 (bounds[e_max_r] * bounds[e_max_r] -
160 bounds[e_min_r] * bounds[e_min_r]);
161 }
162
169 template <concepts::scalar scalar_t>
170 DETRAY_HOST_DEVICE constexpr bounds_type<scalar_t> merge(
171 const bounds_type<scalar_t> &bounds,
172 const bounds_type<scalar_t> &o_bounds) const {
173 bounds_type<scalar_t> new_bounds{};
174
175 new_bounds[e_min_r] = math::min(bounds[e_min_r], o_bounds[e_min_r]);
176 new_bounds[e_min_phi] = math::min(bounds[e_min_phi], o_bounds[e_min_phi]);
177 new_bounds[e_min_z] = math::min(bounds[e_min_z], o_bounds[e_min_z]);
178 new_bounds[e_max_r] = math::max(bounds[e_max_r], o_bounds[e_max_r]);
179 new_bounds[e_max_phi] = math::max(bounds[e_max_phi], o_bounds[e_max_phi]);
180 new_bounds[e_max_z] = math::max(bounds[e_max_z], o_bounds[e_max_z]);
181
182 return new_bounds;
183 }
184
194 // @todo: Look at phi - range for a better fit
195 template <concepts::algebra algebra_t>
196 DETRAY_HOST_DEVICE inline darray<dscalar<algebra_t>, 6> local_min_bounds(
197 const bounds_type<dscalar<algebra_t>> &bounds,
198 const dscalar<algebra_t> env =
199 std::numeric_limits<dscalar<algebra_t>>::epsilon()) const {
200 assert(env > 0.f);
201 const dscalar<algebra_t> r_bound{bounds[e_max_r] + env};
202 return {-r_bound, -r_bound, bounds[e_min_z] - env,
203 r_bound, r_bound, bounds[e_max_z] + env};
204 }
205
208 template <concepts::algebra algebra_t>
209 DETRAY_HOST_DEVICE dpoint3D<algebra_t> centroid(
210 const bounds_type<dscalar<algebra_t>> &bounds) const {
211 return 0.5f * dpoint3D<algebra_t>{static_cast<dscalar<algebra_t>>(0.f),
212 (bounds[e_min_phi] + bounds[e_max_phi]),
213 (bounds[e_min_z] + bounds[e_max_z])};
214 }
215
222 template <concepts::algebra algebra_t>
224 const bounds_type<dscalar<algebra_t>> & /*unused*/,
225 dindex /*unused*/) const {
226 throw std::runtime_error(
227 "Vertex generation for 3D cylinders is not implemented");
228 return {};
229 }
230
237 template <concepts::scalar scalar_t>
238 DETRAY_HOST constexpr bool check_consistency(
239 const bounds_type<scalar_t> &bounds, std::ostream &os) const {
240 constexpr auto tol{10.f * std::numeric_limits<scalar_t>::epsilon()};
241
242 if (bounds[e_min_r] < tol) {
243 os << "DETRAY ERROR (HOST): Radii must be in the range (0, "
244 "numeric_max)"
245 << std::endl;
246 return false;
247 }
248 if (bounds[e_min_r] >= bounds[e_max_r] ||
249 math::fabs(bounds[e_min_r] - bounds[e_max_r]) < tol) {
250 os << "DETRAY ERROR (HOST): Min Radius must be smaller than max "
251 "Radius.";
252 return false;
253 }
254 if (bounds[e_min_z] >= bounds[e_max_z] ||
255 math::fabs(bounds[e_min_z] - bounds[e_max_z]) < tol) {
256 os << "DETRAY ERROR (HOST): Min z must be smaller than max z.";
257 return false;
258 }
259
260 return true;
261 }
262};
263
264} // namespace detray
Geometrical shape of a full 3D cylinder.
Definition cylinder3D.hpp:32
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=0.f) const
Definition cylinder3D.hpp:124
dvector< dpoint3D< algebra_t > > vertices(const bounds_type< dscalar< algebra_t > > &, dindex) const
Generate vertices in local cartesian frame.
Definition cylinder3D.hpp:223
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 cylinder3D.hpp:196
constexpr scalar_t volume(const bounds_type< scalar_t > &bounds) const
The volume of a the shape.
Definition cylinder3D.hpp:156
static constexpr std::size_t dim
Dimension of the local coordinate system.
Definition cylinder3D.hpp:61
cylindrical3D< algebra_t > local_frame_type
Local coordinate frame for boundary checks.
Definition cylinder3D.hpp:54
darray< scalar_t, boundaries::e_size > bounds_type
Container definition for the shape boundary values.
Definition cylinder3D.hpp:50
bool_t result_type
Result type of a boundary check.
Definition cylinder3D.hpp:58
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 cylinder3D.hpp:73
constexpr bounds_type< scalar_t > merge(const bounds_type< scalar_t > &bounds, const bounds_type< scalar_t > &o_bounds) const
Merge two 3D cylinder shapes.
Definition cylinder3D.hpp:170
dpoint3D< algebra_t > centroid(const bounds_type< dscalar< algebra_t > > &bounds) const
Definition cylinder3D.hpp:209
constexpr bool check_consistency(const bounds_type< scalar_t > &bounds, std::ostream &os) const
Check consistency of boundary values.
Definition cylinder3D.hpp:238
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 >=0.f) const
Check boundary values for a local point.
Definition cylinder3D.hpp:100
static constexpr std::string_view name
The name for this shape.
Definition cylinder3D.hpp:35
constexpr scalar_t measure(const bounds_type< scalar_t > &bounds) const
Measure of the shape: Volume.
Definition cylinder3D.hpp:145
boundaries
Indices describing the entries in the shape boundary array.
Definition cylinder3D.hpp:38
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
static constexpr scalar_t pi
π
Definition units.hpp:136
Projection into a 3D cylindrical coordinate frame.
Definition cylindrical3D.hpp:20
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 cylindrical point.
Definition cylindrical3D.hpp:58