ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
spatial_grid.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/core/concepts.hpp"
13#include "detray/geometry/concepts.hpp"
14#include "detray/geometry/mask.hpp"
15#include "detray/geometry/shapes/concentric_cylinder2D.hpp"
16#include "detray/navigation/accelerators/concepts.hpp"
17#include "detray/navigation/accelerators/search_window.hpp"
18#include "detray/navigation/intersection/ray_intersector.hpp"
19#include "detray/tracks/ray.hpp"
20#include "detray/utils/grid/concepts.hpp"
21#include "detray/utils/grid/detail/axis_helpers.hpp"
22#include "detray/utils/grid/detail/bin_view.hpp"
23#include "detray/utils/grid/grid.hpp"
24#include "detray/utils/grid/grid_bins.hpp"
25#include "detray/utils/grid/grid_collection.hpp"
26
27// System include(s)
28#include <limits>
29
30namespace detray {
31
33template <concepts::grid grid_t>
34class spatial_grid_impl : public grid_t {
35 using base_grid = grid_t;
36 using frame_t = typename grid_t::local_frame_type;
37 using algebra_t = typename grid_t::algebra_type;
38
39 public:
41 using value_type = typename base_grid::value_type;
43 using query_type = typename base_grid::point_type;
44
46 template <bool is_owning>
48
50 using mask_type =
52
54 using base_grid::base_grid;
55
61 template <concepts::scalar... Args>
62 DETRAY_HOST_DEVICE explicit constexpr spatial_grid_impl(base_grid &&gr,
63 Args &&...mask_values)
64 : base_grid(std::move(gr)), m_mask{get_mask_from_axes(mask_values...)} {}
65
69 template <concepts::scalar... Args>
70 DETRAY_HOST_DEVICE explicit constexpr spatial_grid_impl(base_grid &gr,
71 Args &&...mask_values)
72 : base_grid(gr), m_mask{get_mask_from_axes(mask_values...)} {}
73
77 DETRAY_HOST_DEVICE constexpr spatial_grid_impl(base_grid &&gr,
78 const mask_type &mask)
79 : base_grid(std::move(gr)), m_mask{mask} {}
80
82 DETRAY_HOST_DEVICE constexpr const mask_type &mask() const { return m_mask; }
83
87 DETRAY_HOST_DEVICE constexpr void mask(const mask_type &m) { m_mask = m; }
88
94 DETRAY_HOST_DEVICE decltype(auto) search(const query_type &p) const {
95 DETRAY_DEBUG_HOST(" -> lookup pos: " << p);
96 return this->bin(p);
97 }
98
104 DETRAY_HOST_DEVICE decltype(auto) search(const query_type &p) {
105 DETRAY_DEBUG_HOST(" -> lookup pos: " << p);
106 return this->bin(p);
107 }
108
114 DETRAY_HOST_DEVICE query_type
116 const dtransform3D<algebra_t> &trf) const {
117 // Intersect the (virtual) reference surface of the grid to find
118 // the correct bin
119 using intersector_t =
121
122 constexpr intersector_t intersector{};
123 typename intersector_t::result_type result{};
124 constexpr auto overstep_tol{
125 -std::numeric_limits<dscalar<algebra_t>>::max()};
126
127 // The cylinder intersector requires the radius from the mask
128 if constexpr (concepts::cylindrical<frame_t>) {
129 result = intersector.point_of_intersection(tangential, trf, m_mask,
130 overstep_tol);
131 } else {
132 result = intersector.point_of_intersection(tangential, trf, overstep_tol);
133 }
134
135 // Retrieve the closest intersection point and check its valid
136 typename intersector_t::point_type intr_point;
137 bool is_inside{true};
138 if constexpr (intersector_t::n_solutions == 1) {
139 // Intersection with the grid was found
140 if (detray::detail::all_of(result.is_valid())) [[likely]] {
141 intr_point = result.point;
142 } else {
143 is_inside = false;
144 }
145 } else {
146 // Closest intersection with the grid was found
147 if (detray::detail::all_of(result[0].is_valid())) [[likely]] {
148 intr_point = result[0].point;
149 } else {
150 is_inside = false;
151 }
152 }
153 // Use ray origin as query position
154 if (!is_inside) [[unlikely]] {
155 // In case the intersection results come in local coordinates
156 if constexpr (std::same_as<decltype(intr_point), query_type>) {
157 intr_point =
158 frame_t::global_to_local(trf, tangential.pos(), tangential.dir());
159 } else {
160 intr_point = tangential.pos();
161 }
162 }
163
164 // Most intersectors return global positions -> project to grid axes
165 if constexpr (std::same_as<frame_t, concentric_cylindrical2D<algebra_t>>) {
166 // The concentric cylinder intersector only returns the z-pos
167 return {vector::phi(tangential.pos(result.path)), intr_point[1]};
168 } else if constexpr (std::same_as<decltype(intr_point), query_type>) {
169 return intr_point;
170 } else {
171 // Project the intersection point into the local grid frame
172 return this->project(trf, intr_point, tangential.dir());
173 }
174 }
175
185 template <concepts::arithmetic window_size_t>
186 DETRAY_HOST_DEVICE auto search(
187 const query_type &p,
188 const search_window<window_size_t, 2> &win_size) const {
189 DETRAY_DEBUG_HOST(" -> lookup pos: " << p);
190 DETRAY_DEBUG_HOST(" -> search window: [" << win_size[0] << ", "
191 << win_size[1] << "]");
192
193 // Return iterable over bins in the search window
194 auto bin_ranges = this->axes().bin_ranges(p, win_size);
195 auto search_area = axis::detail::bin_view(*this, bin_ranges);
196
197 // Join the respective bins to a single iteration
198 return detray::views::join(std::move(search_area));
199 }
200
208 template <concepts::detector detector_t, typename track_t,
209 concepts::arithmetic window_size_t>
210 DETRAY_HOST_DEVICE auto search(
211 const detector_t &det, const typename detector_t::volume_type &volume,
212 const track_t &track, const search_window<window_size_t, 2> &win_size,
213 const typename detector_t::geometry_context &ctx) const {
214 // Placement of the grid (same as volume)
215 const auto &trf = det.transform_store().at(volume.transform(), ctx);
216
217 query_type loc_pos{};
218 // For 2-dimensional grids, project the track position along the track
219 // direction to find the optimal grid bin
220 if constexpr (base_grid::dim == 2) {
221 if constexpr (concepts::cylindrical<frame_t>) {
222 DETRAY_DEBUG_HOST("2D spatial grid: " << m_mask);
223 } else {
224 DETRAY_DEBUG_HOST("2D spatial grid: " << DETRAY_TYPENAME(frame_t));
225 }
226
227 // Tangential to the current track parameters
228 const detray::detail::ray<algebra_t> tangential{track};
229
230 // Intersect the (virtual) reference surface of the grid to find
231 // the correct bin
232 loc_pos = local_point_of_intersection(tangential, trf);
233 } else {
234 loc_pos = this->project(trf, track.pos(), track.dir());
235 }
236
237 // Grid lookup
238 return search(loc_pos, win_size);
239 }
240
241 private:
243 template <typename... Args>
244 DETRAY_HOST_DEVICE mask_type get_mask_from_axes(Args &&...mask_values) {
245 constexpr auto inv_vol_link{detray::detail::invalid_value<std::uint8_t>()};
246
248 if constexpr (concepts::cylindrical<frame_t>) {
249 static_assert(sizeof...(Args) == 1,
250 "Spatial cylinder grid: Only the cylinder radius "
251 "needs to be provided externally");
252
253 constexpr auto inf{std::numeric_limits<dscalar<algebra_t>>::max()};
254 return mask_type{inv_vol_link, mask_values..., -inf, inf};
255 } else {
257 return {};
258 }
259 }
260
262 mask_type m_mask{};
263};
264
272template <concepts::algebra algebra_t, typename axes_t, typename bin_t,
273 template <std::size_t> class serializer_t = simple_serializer,
274 typename containers = host_container_types, bool ownership = true>
277 simple_serializer>>;
278
279namespace concepts {
280
281template <class SG>
284 requires(const SG &sgr) {
285 typename SG::mask_type;
286
287 { sgr.mask() } -> std::same_as<const typename SG::mask_type &>;
288 };
289
290} // namespace concepts
291
295template <concepts::grid grid_t>
298 : public grid_collection<grid_t> {
299 // Use a normal grid collection for the grid related data
300 using base_collection = grid_collection<grid_t>;
301 using const_base_collection = const base_collection;
302
303 using frame_t = typename grid_t::local_frame_type;
304 using mask_t = typename spatial_grid_impl<grid_t>::mask_type;
306
307 template <typename T>
308 using vector_t = typename base_collection::template vector_type<T>;
309
310 public:
312 using size_type = typename base_collection::size_type;
315
317 using view_type =
318 dmulti_view<detail::get_view_t<base_collection>, dvector_view<mask_t>>;
319
321 using const_view_type = dmulti_view<detail::get_view_t<const_base_collection>,
322 dvector_view<const mask_t>>;
323
325 using buffer_type = dmulti_buffer<detail::get_buffer_t<base_collection>,
326 dvector_buffer<mask_t>>;
327
329 grid_collection() = default;
330
334 DETRAY_HOST
335 explicit grid_collection(vecmem::memory_resource *resource)
336 : base_collection(resource), m_mask_values(resource) {}
337
341 DETRAY_HOST_DEVICE
342 grid_collection(base_collection &&grid_coll, vector_t<scalar_t> &&mask_values)
343 : base_collection(std::move(grid_coll)),
344 m_mask_values(std::move(mask_values)) {}
345
348 template <concepts::device_view coll_view_t>
349 DETRAY_HOST_DEVICE explicit grid_collection(coll_view_t &view)
350 : base_collection(detail::get<0>(view.m_view)),
351 m_mask_values(detail::get<1>(view.m_view)) {}
352
356 DETRAY_HOST_DEVICE grid_collection(grid_collection &&other) noexcept
357 : base_collection(std::move(other)),
358 m_mask_values(std::move(other.m_mask_values)) {}
359
363 DETRAY_HOST_DEVICE grid_collection &operator=(
364 grid_collection &&other) noexcept {
365 if (this != &other) {
366 m_mask_values = std::move(other.m_mask_values);
367 base_collection::operator=(std::move(other));
368 }
369 return *this;
370 }
371
375 DETRAY_HOST_DEVICE
376 constexpr auto operator[](const size_type i) const
378 if constexpr (concepts::cylindrical<frame_t>) {
379 assert(static_cast<dindex>(m_mask_values.size()) == this->size());
380 return spatial_grid_impl<grid_t>(const_base_collection::operator[](i),
381 m_mask_values[i]);
382 } else {
383 return spatial_grid_impl<grid_t>(const_base_collection::operator[](i));
384 }
385 }
386
390 DETRAY_HOST_DEVICE
391 constexpr auto at(const size_type i) const -> spatial_grid_impl<grid_t> {
392 if constexpr (concepts::cylindrical<frame_t>) {
393 assert(static_cast<dindex>(m_mask_values.size()) == this->size());
394 return spatial_grid_impl<grid_t>(const_base_collection::at(i),
395 m_mask_values[i]);
396 } else {
397 return spatial_grid_impl<grid_t>(const_base_collection::at(i));
398 }
399 }
400
402 DETRAY_HOST auto get_data() -> view_type {
403 return view_type{base_collection::get_data(),
404 detray::get_data(m_mask_values)};
405 }
406
408 DETRAY_HOST
409 auto get_data() const -> const_view_type {
410 return const_view_type{const_base_collection::get_data(),
411 detray::get_data(m_mask_values)};
412 }
413
416 template <concepts::spatial_grid other_grid_t>
417 requires std::constructible_from<
418 typename spatial_grid_impl<grid_t>::template type<true>, other_grid_t>
419 DETRAY_HOST constexpr auto push_back(const other_grid_t &gr) noexcept(false)
420 -> void {
421 // Copy over the base grid data
422 base_collection::push_back(gr);
423
424 // Add the additional mask values
425 m_mask_values.push_back(gr.mask());
426 }
427
428 private:
430 vector_t<mask_t> m_mask_values{};
431};
432
433} // namespace detray
describes a straight-line trajectory
Definition ray.hpp:22
const vector3_type & dir() const
Return the ray direction.
Definition ray.hpp:79
const point3_type & pos() const
Return the ray origin.
Definition ray.hpp:63
auto get_data() const -> const_view_type
Definition spatial_grid.hpp:409
spatial_grid_impl< grid_t > value_type
Accelerator view materialized from one collection entry.
Definition spatial_grid.hpp:314
dmulti_view< detail::get_view_t< base_collection >, dvector_view< mask_t > > view_type
Vecmem based grid collection view type.
Definition spatial_grid.hpp:317
typename base_collection::size_type size_type
Index type used to address grid entries.
Definition spatial_grid.hpp:312
grid_collection()=default
Make spatial grid collection default constructible: Empty.
dmulti_view< detail::get_view_t< const_base_collection >, dvector_view< const mask_t > > const_view_type
Vecmem based grid collection view type.
Definition spatial_grid.hpp:321
grid_collection(vecmem::memory_resource *resource)
Create empty spatial grid collection from specific vecmem memory resource.
Definition spatial_grid.hpp:335
auto get_data() -> view_type
Definition spatial_grid.hpp:402
grid_collection(base_collection &&grid_coll, vector_t< scalar_t > &&mask_values)
Create spatial grid collection from existing data - move.
Definition spatial_grid.hpp:342
grid_collection(coll_view_t &view)
Device-side construction from a vecmem based view type.
Definition spatial_grid.hpp:349
dmulti_buffer< detail::get_buffer_t< base_collection >, dvector_buffer< mask_t > > buffer_type
Vecmem based buffer type.
Definition spatial_grid.hpp:325
grid_collection & operator=(grid_collection &&other) noexcept
Move assignment.
Definition spatial_grid.hpp:363
constexpr auto at(const size_type i) const -> spatial_grid_impl< grid_t >
Create spatial grid acceleration structure from underlying grid data.
Definition spatial_grid.hpp:391
grid_collection(grid_collection &&other) noexcept
Move constructor.
Definition spatial_grid.hpp:356
constexpr auto push_back(const other_grid_t &gr) noexcept(false) -> void
Add a new grid.
Definition spatial_grid.hpp:419
constexpr auto operator[](const size_type i) const -> spatial_grid_impl< grid_t >
Create spatial grid acceleration structure from underlying grid data.
Definition spatial_grid.hpp:376
An N-dimensional grid for object storage.
Definition grid.hpp:38
Mask a region on a surface and link it to a volume.
Definition mask.hpp:46
An N-dimensional spatial grid for geometry object searches.
Definition spatial_grid.hpp:34
constexpr spatial_grid_impl(base_grid &&gr, Args &&...mask_values)
Construct from existing grid - move.
Definition spatial_grid.hpp:62
query_type local_point_of_intersection(const detray::detail::ray< algebra_t > &tangential, const dtransform3D< algebra_t > &trf) const
Straight line intersection with the grid.
Definition spatial_grid.hpp:115
decltype(auto) search(const query_type &p) const
Find the value of a single bin - const.
Definition spatial_grid.hpp:94
auto search(const query_type &p, const search_window< window_size_t, 2 > &win_size) const
Return a neighborhood of values from the grid.
Definition spatial_grid.hpp:186
constexpr void mask(const mask_type &m)
Replace the mask of the virtual reference surface.
Definition spatial_grid.hpp:87
typename base_grid::point_type query_type
Coordinate type used to query bins.
Definition spatial_grid.hpp:43
decltype(auto) search(const query_type &p)
Find the value of a single bin.
Definition spatial_grid.hpp:104
constexpr spatial_grid_impl(base_grid &gr, Args &&...mask_values)
Construct from existing base grid - copy.
Definition spatial_grid.hpp:70
constexpr spatial_grid_impl(base_grid &&gr, const mask_type &mask)
Construct from existing base grid and mask - copy.
Definition spatial_grid.hpp:77
spatial_grid_impl< typename grid_t::template type< is_owning > > type
Find the corresponding (non-)owning grid type.
Definition spatial_grid.hpp:47
typename base_grid::value_type value_type
Value type stored in the grid bins.
Definition spatial_grid.hpp:41
auto search(const detector_t &det, const typename detector_t::volume_type &volume, const track_t &track, const search_window< window_size_t, 2 > &win_size, const typename detector_t::geometry_context &ctx) const
Interface for the navigator.
Definition spatial_grid.hpp:210
constexpr const mask_type & mask() const
Definition spatial_grid.hpp:82
detray::mask< concentric_cylinder2D, algebra_t, std::uint8_t > mask_type
Definition spatial_grid.hpp:50
Algebra plugin concept.
Definition concepts.hpp:147
Arithmetic types.
Definition concepts.hpp:21
Definition concepts.hpp:214
Check if a type can be used as a detector.
Definition concepts.hpp:47
Definition concepts.hpp:64
Scalar concept: Elements of vectors/matrices (can be simd vectors).
Definition concepts.hpp:40
Definition spatial_grid.hpp:282
Acceleration structure that contains surfaces (surface descriptors) TODO: Add surface descriptor conc...
Definition concepts.hpp:63
Acceleration structure that contains volumes (volume indices).
Definition concepts.hpp:73
Type list concepts.
Definition concepts.hpp:17
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
unsigned int dindex
Default index type.
Definition indexing.hpp:18
spatial_grid_impl< grid_impl< coordinate_axes< axes_t, algebra_t, ownership, containers >, bin_t, simple_serializer > > spatial_grid
Spatial grid alias built from coordinate axes and a bin type.
Definition spatial_grid.hpp:275
darray< window_size_t, DIM > search_window
Size around a query point for which to do the search in an acceleration structure.
Definition search_window.hpp:24
const auto & get(const detray::tuple< Ts... > &t) noexcept
Get a tuple element by index from a const tuple.
Definition tuple.hpp:152
get_transform3D_t< A, T > dtransform3D
Three-dimensional transform type for algebra A and value type T.
Definition algebra.hpp:84
container_types<> host_container_types
Defining some common types Default host container policy based on vecmem vectors.
Definition containers.hpp:82
Intersection interface for detector surfaces.
Definition intersector.hpp:25
constexpr result_type point_of_intersection(const detail::ray< algebra_t > &ray, const transform3_type &trf, const scalar_type overstep_tol=0.f) const
Operator function to find intersections between ray and planar mask.
Definition intersector.hpp:64
interface type to construct a join_view with CTAD
Definition join.hpp:109
Intersection implementation for detector surfaces using a ray trajectory.
Definition ray_intersector.hpp:31