ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
material_map_factory.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/homogeneous_material_factory.hpp"
13#include "detray/builders/surface_factory.hpp"
14#include "detray/definitions/indexing.hpp"
15#include "detray/geometry/shapes/unmasked.hpp"
16#include "detray/material/material.hpp"
17#include "detray/utils/logging.hpp"
18#include "detray/utils/ranges.hpp"
19
20// System include(s)
21#include <algorithm>
22#include <cassert>
23#include <map>
24#include <memory>
25#include <vector>
26
27namespace detray {
28
38template <concepts::detector detector_t, typename index_t = dindex>
39class material_map_factory final : public factory_decorator<detector_t> {
40 using mask_id = typename detector_t::masks::id;
41 using material_id = typename detector_t::material::id;
42 using index_type = index_t;
43
44 using base_factory = factory_decorator<detector_t>;
45 using placeholder_factory_t = surface_factory<detector_t, unmasked<>>;
46
47 public:
52
53 using base_factory::operator();
54
58 DETRAY_HOST
60 std::unique_ptr<surface_factory_interface<detector_t>> sf_factory =
61 std::make_unique<placeholder_factory_t>())
62 : base_factory(std::move(sf_factory)) {}
63
66 DETRAY_HOST
67 auto n_materials() const -> dindex {
68 const dindex n_surfaces{static_cast<dindex>(m_links.size())};
69
70 // Need exactly one material per surface
71 assert(m_n_bins.size() == n_surfaces);
72 assert(m_axis_spans.size() == n_surfaces);
73 assert(m_materials.size() == n_surfaces);
74 assert(m_thickness.size() == n_surfaces);
75
76 return n_surfaces;
77 }
78
80 DETRAY_HOST
81 auto links() const -> const
82 std::map<std::size_t, std::pair<material_id, std::vector<index_type>>> & {
83 return m_links;
84 }
85
87 DETRAY_HOST
88 auto materials() const
89 -> const std::map<std::size_t, std::vector<material<scalar_type>>> & {
90 return m_materials;
91 }
92
94 DETRAY_HOST
95 auto thickness() const
96 -> const std::map<std::size_t, std::vector<scalar_type>> & {
97 return m_thickness;
98 }
99
107 DETRAY_HOST
108 void add_material(material_id id, data_type &&mat_data,
109 std::vector<std::size_t> &&n_bins,
110 std::vector<std::vector<scalar_type>> &&axis_spans,
111 std::vector<index_type> &&indices) {
112 DETRAY_VERBOSE_HOST("Received material map data");
113
114 auto [sf_index, mat, thickness] = std::move(mat_data).get_data();
115
116 assert(!detail::is_invalid_value(sf_index));
117
118 m_links.emplace(sf_index, std::make_pair(id, std::move(indices)));
119 m_n_bins.emplace(sf_index, std::move(n_bins));
120 m_axis_spans.emplace(sf_index, std::move(axis_spans));
121 m_materials.emplace(sf_index, std::move(mat));
122 m_thickness.emplace(sf_index, std::move(thickness));
123 }
124
126 DETRAY_HOST
127 auto clear() -> void override {
128 m_links.clear();
129 m_n_bins.clear();
130 m_axis_spans.clear();
131 m_materials.clear();
132 m_thickness.clear();
133 }
134
151 template <typename bin_data_t, std::size_t N>
152 DETRAY_HOST auto operator()(
153 typename detector_t::surface_lookup_container &surfaces,
154 std::map<dindex, std::vector<bin_data_t>> &material_map,
155 std::map<dindex, darray<std::size_t, N>> &n_bins,
156 std::map<dindex, darray<std::vector<scalar_type>, N>> &axis_spans) {
157 DETRAY_VERBOSE_HOST("Add material maps...");
158
159 using link_t = typename detector_t::surface_type::material_link;
160
161 // Check data consistency
162 const std::size_t n_materials{this->n_materials()};
163 if (n_materials == 0) {
164 return;
165 }
166
167 assert(surfaces.size() >= n_materials);
168
169 DETRAY_VERBOSE_HOST("-> Have " << m_materials.size()
170 << " configured material map(s) to assign");
171
172 // Add the material only to those surfaces that the data links against
173 for (auto &[i, materials] : m_materials) {
174 const auto sf_idx{static_cast<dindex>(i)};
175
176 DETRAY_DEBUG_HOST("--> #" << sf_idx << " sf = " << surfaces.at(sf_idx));
177
178 // Copy the number of bins to the builder
179 assert(m_n_bins.at(sf_idx).size() == N);
180 n_bins.emplace(sf_idx, darray<std::size_t, N>{});
181 std::ranges::copy_n(m_n_bins.at(sf_idx).begin(), N,
182 n_bins.at(sf_idx).begin());
183
184 // Copy the axis spans to the builder (if present)
185 axis_spans.emplace(sf_idx, darray<std::vector<scalar_type>, N>{});
186 for (std::size_t in = 0; in < N; ++in) {
187 if (m_axis_spans.at(sf_idx).size() > in) {
188 axis_spans.at(sf_idx).at(in) = m_axis_spans.at(sf_idx).at(in);
189 }
190 }
191
192 // Combine the material slab with its local bin index
193 for (const auto [j, mat] : detray::views::enumerate(materials)) {
194 scalar_type t{m_thickness.at(sf_idx)[j]};
195 auto &loc_bin_idx{m_links.at(sf_idx).second.at(j)};
196
197 material_slab<scalar_type> mat_slab{mat, t};
198 bin_data_t data{loc_bin_idx, mat_slab};
199
200 auto search = material_map.find(sf_idx);
201 if (search == material_map.end()) {
202 material_map.emplace(sf_idx, std::vector<bin_data_t>{data});
203 } else {
204 search->second.push_back(data);
205 }
206 }
207
208 auto map_id{m_links.at(sf_idx).first};
209 DETRAY_DEBUG_HOST("--> Set surface material id: " << map_id);
210 surfaces.at(sf_idx).material() = link_t{map_id, dindex_invalid};
211 }
212
213 DETRAY_DEBUG_HOST("Finished");
214 }
215
216 private:
218 std::map<std::size_t, std::pair<material_id, std::vector<index_type>>>
219 m_links{};
221 std::map<std::size_t, std::vector<std::size_t>> m_n_bins{};
223 std::map<std::size_t, std::vector<std::vector<scalar_type>>> m_axis_spans{};
225 std::map<std::size_t, std::vector<scalar_type>> m_thickness{};
228 std::map<std::size_t, std::vector<material<scalar_type>>> m_materials{};
229};
230
231} // namespace detray
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
Bind components for material together.
Definition homogeneous_material_factory.hpp:35
auto operator()(typename detector_t::surface_lookup_container &surfaces, std::map< dindex, std::vector< bin_data_t > > &material_map, std::map< dindex, darray< std::size_t, N > > &n_bins, std::map< dindex, darray< std::vector< scalar_type >, N > > &axis_spans)
Add data for material maps to the containers of a volume builder.
Definition material_map_factory.hpp:152
auto links() const -> const std::map< std::size_t, std::pair< material_id, std::vector< index_type > > > &
Definition material_map_factory.hpp:81
auto n_materials() const -> dindex
Definition material_map_factory.hpp:67
auto materials() const -> const std::map< std::size_t, std::vector< material< scalar_type > > > &
Definition material_map_factory.hpp:88
dscalar< typename detector_t::algebra_type > scalar_type
Scalar type used by material map values.
Definition material_map_factory.hpp:49
material_map_factory(std::unique_ptr< surface_factory_interface< detector_t > > sf_factory=std::make_unique< placeholder_factory_t >())
Factory with surfaces potentially already filled or empty placeholder that will not be used.
Definition material_map_factory.hpp:59
material_data< scalar_type > data_type
Material data type consumed by this factory.
Definition material_map_factory.hpp:51
auto thickness() const -> const std::map< std::size_t, std::vector< scalar_type > > &
Definition material_map_factory.hpp:95
auto clear() -> void override
Clear old data.
Definition material_map_factory.hpp:127
void add_material(material_id id, data_type &&mat_data, std::vector< std::size_t > &&n_bins, std::vector< std::vector< scalar_type > > &&axis_spans, std::vector< index_type > &&indices)
Add all necessary components to the factory for a material map.
Definition material_map_factory.hpp:108
How to generate surfaces with their corresponding masks and transforms.
Definition surface_factory_interface.hpp:120
Generates a number of surfaces for a volume (can be portals, passives or sensitives) and fills them i...
Definition surface_factory.hpp:43
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
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
std::array< value_t, kDIM > darray
Fixed-size array container.
Definition containers.hpp:30
tuple< T1, T2 > pair
A two-element tuple alias.
Definition tuple.hpp:145
Slab structure to be mapped on the mask (plane, cylinder).
Definition material_slab.hpp:25
Material composition properties and density data used by interactions.
Definition material.hpp:36
Range adaptor that creates an enumerate view, optionally starting at a selected index.
Definition enumerate.hpp:266