ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
surface_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/builders/detail/radius_getter.hpp"
13#include "detray/core/concepts.hpp"
14#include "detray/core/detector.hpp"
15#include "detray/definitions/grid_axis.hpp"
16#include "detray/definitions/units.hpp"
17#include "detray/navigation/concepts.hpp"
18#include "detray/utils/grid/concepts.hpp"
19#include "detray/utils/logging.hpp"
20
21// Plugin include(s)
22#include "detray/plugins/svgtools/conversion/grid.hpp"
23#include "detray/plugins/svgtools/styling/styling.hpp"
24
25// Actsvg include(s)
26#include "actsvg/proto/grid.hpp"
27
28// System include(s)
29#include <algorithm>
30#include <array>
31#include <optional>
32#include <string>
33#include <vector>
34
35namespace detray::svgtools::conversion {
36
37namespace detail {
38
50 template <typename group_t, typename index_t, typename volume_t>
51 DETRAY_HOST_DEVICE std::vector<std::vector<std::size_t>> operator()(
52 [[maybe_unused]] const group_t& group,
53 [[maybe_unused]] const index_t index,
54 [[maybe_unused]] const volume_t& vol_desc,
55 [[maybe_unused]] const std::array<dindex, 2>& search_window) const {
56 using accel_t = typename group_t::value_type;
57
58 if constexpr (concepts::surface_grid<accel_t>) {
59 using transform3_t = typename accel_t::local_frame_type::transform3_type;
60 using algebra_t = typename accel_t::local_frame_type::algebra_type;
61 using scalar_t = typename transform3_t::scalar_type;
62 using point2_t = typename transform3_t::point2;
63
64 // The actsvg display only works for 2-dimensional grids
65 if constexpr (accel_t::dim != 2u) {
66 DETRAY_ERROR_HOST("Only 2D grids can be displayed in actvg");
67 return {};
68 }
69
70 const accel_t grid = group.at(index);
71 const std::size_t n_bins{grid.nbins()};
72
73 std::vector<std::vector<std::size_t>> bin_assoc;
74 bin_assoc.reserve(n_bins);
75
76 // Create the bin associations
77 auto edges0 = grid.template get_axis<0>().bin_edges();
78 auto edges1 = grid.template get_axis<1>().bin_edges();
79
80 // In the svg convention the phi axis has to be the second axis to
81 // loop over
82 constexpr bool is_cyl{
83 std::is_same_v<typename accel_t::local_frame_type,
85 std::is_same_v<typename accel_t::local_frame_type,
87 if constexpr (is_cyl) {
88 edges0.swap(edges1);
89 }
90
91 for (std::size_t i = 1u; i < edges0.size(); ++i) {
92 scalar_t p0 = 0.5f * (edges0.at(i) + edges0.at(i - 1));
93
94 for (std::size_t j = 1u; j < edges1.size(); ++j) {
95 scalar_t p1 = 0.5f * (edges1.at(j) + edges1.at(j - 1));
96
97 // Create the bin center position estimates for detray
98 // (swap cylinder coordinates back)
99 point2_t bin_center{p0, p1};
100 if constexpr (is_cyl) {
101 bin_center = {p1, p0};
102 }
103
104 // Get all the bin entries and calculate the loc index
105 std::vector<std::size_t> entries;
106 for (const auto& sf_desc : grid.search(bin_center, search_window)) {
107 // actsvg expects the sensitive surfaces to be numbered
108 // starting from zero (per volume)
109 entries.push_back(vol_desc.to_local_sf_index(sf_desc.index()));
110 }
111
112 // Remove duplicates
113 std::ranges::sort(entries);
114 auto last = std::unique(entries.begin(), entries.end());
115 entries.erase(last, entries.end());
116
117 bin_assoc.push_back(std::move(entries));
118 }
119 }
120
121 return bin_assoc;
122 }
123
124 return {};
125 }
126};
127
128} // namespace detail
129
138template <concepts::detector detector_t, typename view_t>
139auto surface_grid(const detector_t& detector, const dindex index,
140 const view_t& view,
141 const styling::grid_style& style =
144 using geo_object_ids = typename detector_t::geo_obj_ids;
145
146 const auto vol_desc = detector.volume(index);
147 const auto link = vol_desc.template accel_link<geo_object_ids::e_sensitive>();
148
149 // Proactively calculate the reference radius for a cylinder grid
150 // (will only be used if the volume actually holds a barrel grid)
151
152 // Get the the radii of the volume portal surfaces
153 std::vector<scalar_t> radii{};
154 const auto vol = tracking_volume{detector, vol_desc};
155
156 // Passive surfaces could be in the brute force finder, but no
157 // sensitive surfaces, since the volume has a grid. Their radii are,
158 // however, always within the interval of the portal radii
159 for (const auto& pt_desc : vol.portals()) {
160 auto r = detector.mask_store()
161 .template visit<detray::detail::outer_radius_getter>(
162 pt_desc.mask());
163 if (r.has_value()) {
164 radii.push_back(*r);
165 }
166 }
167
168 scalar_t cyl_ref_radius{0.f};
169 if (!radii.empty()) {
170 scalar_t inner_r = *std::ranges::min_element(radii);
171 scalar_t outer_r = *std::ranges::max_element(radii);
172
173 cyl_ref_radius = 0.5f * static_cast<actsvg::scalar>(inner_r + outer_r);
174 }
175
176 return svgtools::conversion::grid(detector.accelerator_store(), link, view,
177 cyl_ref_radius, style);
178}
179
187template <concepts::detector detector_t>
188std::vector<std::vector<std::size_t>> get_bin_association(
189 const detector_t& det, const detray::tracking_volume<detector_t>& vol,
190 const std::array<dindex, 2>& search_window = {2u, 2u}) {
191 using geo_object_ids = typename detector_t::geo_obj_ids;
192
193 const auto& vol_desc = det.volume(vol.index());
194
195 if (const auto& link =
196 vol_desc.template accel_link<geo_object_ids::e_sensitive>();
197 !link.is_invalid()) {
198 return det.accelerator_store()
199 .template visit<detail::bin_association_getter>(link, vol_desc,
201 }
202
203 return {};
204}
205
206} // namespace detray::svgtools::conversion
auto mask_store() const -> const mask_container &
Definition detector.hpp:308
const auto & volume(dindex volume_index) const
Return a volume by its stored index.
Definition detector.hpp:242
Facade for a detray detector volume.
Definition tracking_volume.hpp:44
constexpr auto index() const -> dindex
Definition tracking_volume.hpp:96
Grid that contains surfaces (used e.g.
Definition concepts.hpp:115
const styling::grid_style grid_style
Grid style used by the Tableau detector and volumes.
Definition styling.hpp:305
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
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
Projection into a 2D concentric cylindrical frame (No rotation in coordinate transformation).
Definition concentric_cylindrical2D.hpp:21
Projection into a 2D cylindrical coordinate frame.
Definition cylindrical2D.hpp:20
A functor to access the bins and get the associated surface indices.
Definition surface_grid.hpp:40
std::vector< std::vector< std::size_t > > operator()(const group_t &group, const index_t index, const volume_t &vol_desc, const std::array< dindex, 2 > &search_window) const
Collect surface indices from neighboring bins around each grid bin.
Definition surface_grid.hpp:51
Style applied to an actsvg proto grid.
Definition styling.hpp:37