12#include "detray/builders/surface_factory_interface.hpp"
13#include "detray/definitions/algebra.hpp"
14#include "detray/definitions/detail/qualifiers.hpp"
15#include "detray/definitions/indexing.hpp"
16#include "detray/geometry/detail/surface_kernels.hpp"
17#include "detray/geometry/shapes/cylinder2D.hpp"
18#include "detray/geometry/shapes/ring2D.hpp"
19#include "detray/material/material.hpp"
20#include "detray/material/material_rod.hpp"
21#include "detray/material/material_slab.hpp"
22#include "detray/material/predefined_materials.hpp"
23#include "detray/utils/grid/axis.hpp"
24#include "detray/utils/logging.hpp"
25#include "detray/utils/ranges.hpp"
38template <concepts::scalar scalar_t>
39inline std::vector<material_slab<scalar_t>> generate_cyl_mat(
41 material<scalar_t> mat,
const scalar_t t,
const scalar_t scalor) {
42 std::vector<material_slab<scalar_t>> ts;
46 scalar_t z_lower{detail::invalid_value<scalar_t>()};
47 scalar_t z_upper{-detail::invalid_value<scalar_t>()};
48 for (
const auto &bounds : bounds_vec) {
49 z_lower = math::min(z_lower, bounds.at(cylinder2D::e_lower_z));
50 z_upper = math::max(z_upper, bounds.at(cylinder2D::e_upper_z));
54 const scalar_t length{math::fabs(z_upper - z_lower)};
56 const scalar_t z_step{length /
static_cast<scalar_t
>(nbins - 1u)};
57 for (std::size_t n = 0u; n < nbins; ++n) {
58 ts.emplace_back(mat,
static_cast<scalar_t
>(scalor * z * z) + t);
66template <concepts::scalar scalar_t>
67inline std::vector<material_slab<scalar_t>> generate_disc_mat(
69 material<scalar_t> mat,
const scalar_t t,
const scalar_t scalor) {
70 std::vector<material_slab<scalar_t>> ts;
74 scalar_t r_inner{detail::invalid_value<scalar_t>()};
75 scalar_t r_outer{0.f};
76 for (
const auto &bounds : bounds_vec) {
77 r_inner = math::min(r_inner, bounds.at(ring2D::e_inner_r));
78 r_outer = math::max(r_outer, bounds.at(ring2D::e_outer_r));
82 const scalar_t r_step{(r_outer - r_inner) /
83 static_cast<scalar_t
>(nbins - 1u)};
84 for (std::size_t n = 0u; n < nbins; ++n) {
85 ts.emplace_back(mat,
static_cast<scalar_t
>(scalor * r) + t);
95template <concepts::scalar scalar_t>
112 std::function<std::vector<material_slab<scalar_t>>(
129 template <
typename mask_
id_t>
134 std::make_pair(
static_cast<unsigned int>(map_type), sf_type);
150 template <
typename mask_
id_t>
153 std::make_pair(
static_cast<unsigned int>(map_type), sf_type);
160 template <
typename mask_
id_t>
163 std::make_pair(
static_cast<unsigned int>(map_type), sf_type);
170 template <
typename mask_
id_t>
173 std::make_pair(
static_cast<unsigned int>(map_type), sf_type);
182template <concepts::detector detector_t>
207 typename detector_t::surface_lookup_container &surfaces,
208 typename detector_t::transform_container &transforms,
209 typename detector_t::mask_container &masks,
210 typename detector_t::geometry_context ctx = {})
213 (*this->
get_factory())(volume, surfaces, transforms, masks, ctx);
215 m_surface_range = idx_range;
231 template <
typename bin_data_t, std::
size_t N>
233 typename detector_t::surface_lookup_container &surfaces,
234 const typename detector_t::mask_container &masks,
237 DETRAY_DEBUG_HOST(
"Generate material maps...");
239 static_assert(N == 2u,
"This generator only supports 2D material maps");
241 using link_t =
typename detector_t::surface_type::material_link;
242 using mask_id =
typename detector_t::masks::id;
243 using material_id =
typename detector_t::material::id;
245 assert(surfaces.size() >= (m_surface_range[1] - m_surface_range[0]));
250 const auto sf_idx{m_surface_range[0] + i};
253 if constexpr (types::contains<
typename detector_t::material,
255 const mask_id sf_mask_id = sf.mask().id();
256 if (sf_mask_id == mask_id::e_straw_tube ||
257 sf_mask_id == mask_id::e_drift_cell) {
263 if (!m_cfg.has_config(sf.mask().id(), sf.id())) {
266 const auto &map_cfg = m_cfg.get_map_config(sf.mask().id(), sf.id());
269 assert(map_cfg.n_bins.size() == N);
271 std::ranges::copy_n(map_cfg.n_bins.begin(), N, n_bins.at(sf_idx).begin());
274 const std::size_t bins = map_cfg.n_bins.at(map_cfg.axis_index);
277 detail::surface_kernels<typename detector_t::algebra_type>;
279 const auto bounds_vec =
280 masks.template visit<typename sf_kernels::get_mask_values>(sf.mask());
284 map_cfg.mat_generator(bounds_vec, bins, map_cfg.mapped_material,
285 map_cfg.thickness, map_cfg.scalor)};
289 for (
dindex bin0 = 0u; bin0 < map_cfg.n_bins.at(0); ++bin0) {
290 for (
dindex bin1 = 0u; bin1 < map_cfg.n_bins.at(1); ++bin1) {
293 material.at((map_cfg.axis_index == 0u) ? bin0 : bin1)};
297 material_map.emplace(sf_idx, std::vector<bin_data_t>{data});
299 search->second.push_back(data);
const surface_factory_interface< detector_t > * get_factory() const
Definition surface_factory_interface.hpp:215
factory_decorator(std::unique_ptr< surface_factory_interface< detector_t > > factory)
Wrap a concrete surface factory and forward interface calls to it.
Definition surface_factory_interface.hpp:203
auto operator()(typename detector_t::volume_type &volume, typename detector_t::surface_lookup_container &surfaces, typename detector_t::transform_container &transforms, typename detector_t::mask_container &masks, typename detector_t::geometry_context ctx={}) -> dindex_range override
Call the underlying surface factory and record the surface range that was produced.
Definition material_map_generator.hpp:206
material_map_generator(std::unique_ptr< surface_factory_interface< detector_t > > factory, const material_map_config< scalar_t > &cfg)
Construct from configuration cfg.
Definition material_map_generator.hpp:191
auto operator()(typename detector_t::surface_lookup_container &surfaces, const typename detector_t::mask_container &masks, std::map< dindex, std::vector< bin_data_t > > &material_map, std::map< dindex, darray< std::size_t, N > > &n_bins)
Create material maps for all surfaces that the underlying surface factory builds.
Definition material_map_generator.hpp:232
How to generate surfaces with their corresponding masks and transforms.
Definition surface_factory_interface.hpp:120
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
detail::index_range< dindex > dindex_range
Index ranges and sequences.
Definition indexing.hpp:24
vecmem::vector< value_t > dvector
Vector container backed by vecmem.
Definition containers.hpp:34
grid< algebra_t, axes< shape_t >, bins::single< material_slab< dscalar< algebra_t > > >, simple_serializer, container_t, owning > material_map
Definition of binned material.
Definition material_map.hpp:29
unsigned int dindex
Default index type.
Definition indexing.hpp:18
constexpr dindex dindex_invalid
Global invalid index definition.
Definition indexing.hpp:21
surface_id
surface type, resolved during navigation.
Definition geometry.hpp:41
std::array< value_t, kDIM > darray
Fixed-size array container.
Definition containers.hpp:30
Multi-bin: contains bin indices from multiple axes.
Definition axis.hpp:36
How to configure the generation for a specific type of material map.
Definition material_map_generator.hpp:98
darray< std::size_t, 2 > n_bins
Number of bins for material maps.
Definition material_map_generator.hpp:102
scalar_t thickness
Minimal thickness of the material slabs in the material maps.
Definition material_map_generator.hpp:108
scalar_t scalor
Scale factor for the material thickness calculation.
Definition material_map_generator.hpp:110
std::function< std::vector< material_slab< scalar_t > >(const dvector< dvector< scalar_t > > &, const std::size_t, material< scalar_t >, const scalar_t, const scalar_t)> mat_generator
How to vary the material thickness along the bins.
Definition material_map_generator.hpp:115
dindex map_id
Type id value of the material map in a given detector.
Definition material_map_generator.hpp:100
std::size_t axis_index
Along which of the two axes to scale the material thickness.
Definition material_map_generator.hpp:104
material< scalar_t > mapped_material
Material to be filled into the maps.
Definition material_map_generator.hpp:106
Configuration for the material map generator.
Definition material_map_generator.hpp:96
std::map< std::pair< unsigned int, surface_id >, map_config > m_map_configs
Configuration for different types of material maps: The key consists of the mask type id and the surf...
Definition material_map_generator.hpp:120
constexpr material_map_config & set_map_config(mask_id_t map_type, surface_id sf_type, const map_config &cfg)
SettersStore the configuration for one mask and surface category.
Definition material_map_generator.hpp:130
const auto & get_map_config(mask_id_t map_type, surface_id sf_type) const
Get the configuration for a mask and surface category.
Definition material_map_generator.hpp:161
auto & get_map_config(mask_id_t map_type, surface_id sf_type)
Get the mutable configuration for a mask and surface category.
Definition material_map_generator.hpp:171
bool has_config(mask_id_t map_type, surface_id sf_type) const
GettersCheck whether a configuration exists for a mask and surface category.
Definition material_map_generator.hpp:151
Rod structure to be mapped on the line mask.
Definition material_rod.hpp:26
Material composition properties and density data used by interactions.
Definition material.hpp:36
interface type to construct a subrange_view with CTAD
Definition subrange.hpp:90
Predefined silicon material using TrackML bulk properties.
Definition predefined_materials.hpp:212
static constexpr scalar_t mm
Native length unit, the millimetre.
Definition units.hpp:27