12#include "detray/builders/bin_fillers.hpp"
13#include "detray/builders/detail/radius_getter.hpp"
14#include "detray/builders/grid_factory.hpp"
15#include "detray/builders/surface_factory_interface.hpp"
16#include "detray/builders/volume_builder.hpp"
17#include "detray/builders/volume_builder_interface.hpp"
18#include "detray/core/concepts.hpp"
19#include "detray/geometry/tracking_volume.hpp"
20#include "detray/navigation/accelerators/concepts.hpp"
21#include "detray/navigation/accelerators/spatial_grid.hpp"
22#include "detray/utils/grid/concepts.hpp"
23#include "detray/utils/logging.hpp"
42 using link_id_t =
typename detector_t::volume_type::object_id;
45 using spatial_grid_t =
46 std::conditional_t<concepts::surface_accelerator<grid_t>, grid_t,
48 using spatial_grid_owning_t =
typename spatial_grid_t::template type<true>;
66 DETRAY_VERBOSE_HOST(
"Add grid builder to volume: " << this->
name());
78 m_add_passives = is_add_passive;
80 DETRAY_VERBOSE_HOST(
"Add passive surfaces to grid: " << std::boolalpha
95 assert(
static_cast<int>(sf_id) > 0);
97 assert(sf_id < link_id_t::e_size);
107 template <
typename gr
id_shape_t>
111 const std::vector<std::pair<typename grid_t::loc_bin_index, dindex>>
112 &bin_capacities = {},
115 DETRAY_VERBOSE_HOST(
"Initialize surface grid...");
118 std::is_same_v<
typename grid_shape_t::template local_frame_type<
119 typename detector_t::algebra_type>,
120 typename grid_t::local_frame_type>,
121 "Mask has incorrect shape");
124 m_grid = spatial_grid_owning_t{m_factory.template new_grid<grid_t>(
125 m, n_bins, bin_capacities, ax_bin_edges),
126 typename spatial_grid_t::mask_type{}};
128 DETRAY_VERBOSE_HOST(
"Created empty grid:\n"
129 << DETRAY_TYPENAME(grid_t) <<
"\n"
139 const std::vector<scalar_type> &spans,
140 const std::vector<std::size_t> &n_bins,
141 const std::vector<std::pair<typename grid_t::loc_bin_index, dindex>>
142 &bin_capacities = {},
143 const std::vector<std::vector<scalar_type>> &ax_bin_edges =
144 std::vector<std::vector<scalar_type>>()) {
145 DETRAY_VERBOSE_HOST(
"Initialize surface grid...");
149 spatial_grid_owning_t{m_factory.template new_grid<grid_t>(
150 spans, n_bins, bin_capacities, ax_bin_edges),
151 typename spatial_grid_t::mask_type{}};
153 DETRAY_VERBOSE_HOST(
"Created empty grid:\n"
154 << DETRAY_TYPENAME(grid_t) <<
"\n"
165 template <
typename volume_type,
typename... Args>
167 const detector_t &det,
const volume_type &vol,
168 const typename detector_t::geometry_context ctx = {},
169 const bin_filler_t bin_filler = {}, Args &&...args) {
170 bin_filler(m_grid, det, vol, ctx, args...);
182 template <
typename volume_type,
typename surface_container_t,
183 typename transform_container_t,
typename mask_container_t,
186 const volume_type &vol,
const surface_container_t &
surfaces,
187 const transform_container_t &
transforms,
const mask_container_t &
masks,
188 const typename detector_t::geometry_context ctx = {},
189 const bin_filler_t bin_filler = {}, Args &&...args) {
200 typename detector_t::geometry_context ctx = {}) ->
201 typename detector_t::volume_type *
override {
202 DETRAY_VERBOSE_HOST(
"Build surface grid...");
205 DETRAY_WARN_HOST(this->
name()
206 <<
": Surface grid deduplication not yet implemented");
210 " -> Defer to other builders to get complete surface descriptors "
213 using surface_desc_t =
typename detector_t::surface_type;
216 typename detector_t::volume_type *vol_ptr =
219 DETRAY_VERBOSE_HOST(
"Resume building with updated surface descriptors");
222 const auto vol = tracking_volume{det, vol_ptr->index()};
225 if (m_grid.size() == 0u) {
226 DETRAY_DEBUG_HOST(
"-> Filling grid automatically...");
228 std::vector<surface_desc_t>
surfaces{};
229 for (
auto &sf_desc : vol.surfaces()) {
230 if (sf_desc.is_sensitive() ||
231 (m_add_passives && sf_desc.is_passive())) {
238 surfaces, det.transform_store(), det.mask_store(), ctx);
240 DETRAY_DEBUG_HOST(
"-> Grid is prefilled...");
246 for (surface_desc_t &sf_desc : m_grid.all()) {
247 assert(!detail::is_invalid_value(sf_desc.index()));
249 dindex glob_idx{vol_ptr->to_global_sf_index(sf_desc.index())};
250 const auto &new_sf_desc = det.surface(glob_idx);
252 assert(new_sf_desc.index() == glob_idx);
253 assert(!new_sf_desc.identifier().is_invalid());
255 sf_desc = new_sf_desc;
260 if constexpr (concepts::cylindrical<typename grid_t::local_frame_type>) {
261 assert(vol_ptr->id() == volume_id::e_cylinder);
263 constexpr auto inv_vol_link{
264 detray::detail::invalid_value<std::uint8_t>()};
265 constexpr auto inf{std::numeric_limits<scalar_type>::max()};
267 DETRAY_DEBUG_HOST(
"Find radius for cylinder grid...");
272 std::vector<scalar_type> radii{};
273 for (
auto pt_desc : vol.portals()) {
274 auto r = det.mask_store().template visit<detail::outer_radius_getter>(
278 DETRAY_DEBUG_HOST(
"Found radius " << *r
279 <<
" mm of portal: " << pt_desc);
285 if (!radii.empty()) {
286 const scalar_type inner_r{*std::ranges::min_element(radii)};
287 const scalar_type outer_r{*std::ranges::max_element(radii)};
289 grid_r = 0.5f * (inner_r + outer_r);
292 typename spatial_grid_t::mask_type cyl_mask{inv_vol_link, grid_r, -inf,
295 DETRAY_DEBUG_HOST(
"Setting mask for cylinder grid: " << cyl_mask);
297 m_grid.mask(cyl_mask);
300 constexpr auto gid{types::id<typename detector_t::accel, spatial_grid_t>};
301 const dindex grid_idx{det.accelerator_store().template size<gid>()};
303 DETRAY_DEBUG_HOST(
"Adding grid to volume in detector. Surface type: "
304 << m_id <<
", grid: " << gid
305 <<
", grid idx: " << grid_idx);
308 vol_ptr->set_accel_link(m_id, gid, grid_idx);
311 det._accelerators.template push_back<gid>(m_grid);
313 DETRAY_DEBUG_HOST(
"Accelerator link: " << vol_ptr->accel_link());
314 DETRAY_VERBOSE_HOST(
"Successfully built "
315 << gid <<
" for volume: " << this->
name());
317 DETRAY_DEBUG_HOST(
"Finished grid: " << m_grid);
324 auto &
get() {
return m_grid; }
327 link_id_t m_id{link_id_t::e_sensitive};
328 grid_factory_t m_factory{};
330 spatial_grid_owning_t m_grid{};
331 bin_filler_t m_bin_filler{};
332 bool m_add_passives{
false};
337 template <
class,
template <std::
size_t>
class,
338 typename>
class grid_factory_t,
339 typename grid_shape_t, typename bin_t,
340 template <std::size_t> class serializer_t,
341 axis::bounds e_bounds = axis::bounds::e_closed,
342 template <typename, typename> class... binning_ts>
345 typename grid_factory_t<bin_t, serializer_t,
346 typename detector_t::algebra_type>::
347 template grid_type<axes<grid_shape_t, e_bounds, binning_ts...>>,
348 grid_factory_t<bin_t, serializer_t, typename detector_t::algebra_type>>;
Build a grid of a certain shape.
Definition grid_builder.hpp:41
void set_add_passives(bool is_add_passive=false)
Should the passive surfaces be added to the grid ?
Definition grid_builder.hpp:77
auto build(detector_t &det, const volume_builder_options &opt, typename detector_t::geometry_context ctx={}) -> typename detector_t::volume_type *override
Add the volume and the grid to the detector det.
Definition grid_builder.hpp:199
void set_type(std::size_t sf_id)
Set the surface category this grid should contain (type id in the accelerator link in the volume desc...
Definition grid_builder.hpp:88
void fill_grid(const volume_type &vol, const surface_container_t &surfaces, const transform_container_t &transforms, const mask_container_t &masks, const typename detector_t::geometry_context ctx={}, const bin_filler_t bin_filler={}, Args &&...args)
Fill grid from externally provided surfaces - temporary solution until the volume builders can be dep...
Definition grid_builder.hpp:185
dscalar< algebra_type > scalar_type
Scalar type used for grid axes and coordinates.
Definition grid_builder.hpp:58
detector_t detector_type
Detector type whose volume and accelerator data this builder updates.
Definition grid_builder.hpp:52
grid_builder(std::unique_ptr< volume_builder_interface< detector_t > > vol_builder)
Decorate a volume with a surface accelerator grid.
Definition grid_builder.hpp:63
void set_type(link_id_t sf_id)
Set the surface category this grid should contain (type id in the accelerator link in the volume desc...
Definition grid_builder.hpp:93
auto & get()
Definition grid_builder.hpp:324
void init_grid(const mask< grid_shape_t, algebra_type > &m, const darray< std::size_t, grid_t::dim > &n_bins, const std::vector< std::pair< typename grid_t::loc_bin_index, dindex > > &bin_capacities={}, const darray< std::vector< scalar_type >, grid_t::dim > &ax_bin_edges=darray< std::vector< scalar_type >, grid_t::dim >())
Initialize a grid from a shape mask and explicit binning parameters.
Definition grid_builder.hpp:108
typename detector_type::surface_type value_type
Surface type stored as a grid value.
Definition grid_builder.hpp:56
void init_grid(const std::vector< scalar_type > &spans, const std::vector< std::size_t > &n_bins, const std::vector< std::pair< typename grid_t::loc_bin_index, dindex > > &bin_capacities={}, const std::vector< std::vector< scalar_type > > &ax_bin_edges=std::vector< std::vector< scalar_type > >())
Build the empty grid from axis parameters.
Definition grid_builder.hpp:138
typename detector_t::algebra_type algebra_type
Algebra backend used by the grid and detector.
Definition grid_builder.hpp:54
void fill_grid(const detector_t &det, const volume_type &vol, const typename detector_t::geometry_context ctx={}, const bin_filler_t bin_filler={}, Args &&...args)
Fill grid from existing volume using a bin filling strategy This can also be called without a volume ...
Definition grid_builder.hpp:166
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
Interface for volume builders (and volume builder decorators).
Definition volume_builder_interface.hpp:66
virtual detector_t::surface_lookup_container & surfaces()=0
Access to builder data.
detector_t::transform_container & transforms() override
Returns mutable access to the wrapped builder's transforms.
Definition volume_builder_interface.hpp:288
std::string_view name() override
Returns the wrapped volume's name.
Definition volume_builder_interface.hpp:222
volume_decorator(std::unique_ptr< volume_builder_interface< detector_t > > vol_builder)
Wraps a volume builder.
Definition volume_builder_interface.hpp:178
volume_builder_interface< detector_t > * get_builder()
Access to underlying builderReturns a pointer to the wrapped builder.
Definition volume_builder_interface.hpp:278
detector_t::surface_lookup_container & surfaces() override
Returns mutable access to the wrapped builder's surface lookup container.
Definition volume_builder_interface.hpp:283
detector_t::mask_container & masks() override
Returns mutable access to the wrapped builder's masks.
Definition volume_builder_interface.hpp:293
auto operator()() -> typename detector_t::volume_type &override
Returns the mutable volume being built.
Definition volume_builder_interface.hpp:187
auto build(detector_t &det, const volume_builder_options &opt, typename detector_t::geometry_context={}) -> typename detector_t::volume_type *override
Builds the wrapped volume in the detector.
Definition volume_builder_interface.hpp:229
bool has_accel() const override
Returns whether sensitive surfaces are added to brute force lookup.
Definition volume_builder_interface.hpp:211
Check if a type can be used as a detector.
Definition concepts.hpp:47
Definition concepts.hpp:64
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
std::array< value_t, kDIM > darray
Fixed-size array container.
Definition containers.hpp:30
grid_builder< detector_t, typename grid_factory_t< bin_t, serializer_t, typename detector_t::algebra_type >:: template grid_type< axes< grid_shape_t, e_bounds, binning_ts... > >, grid_factory_t< bin_t, serializer_t, typename detector_t::algebra_type > > grid_builder_type
Grid builder from single components.
Definition grid_builder.hpp:343
grid_factory< typename grid_t::bin_type, simple_serializer, typename grid_t::algebra_type > grid_factory_type
Infer a grid factory type from an already completely assembled grid type.
Definition grid_factory.hpp:751
Fill a surface grid using the surface translation.
Definition bin_fillers.hpp:69
Options for the volume builder classes.
Definition volume_builder_interface.hpp:29
constexpr bool deduplicate() const
Getters.
Definition volume_builder_interface.hpp:40