ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
material_map_reader.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/detector_builder.hpp"
13#include "detray/builders/material_map_builder.hpp"
14#include "detray/core/concepts.hpp"
15#include "detray/geometry/concepts.hpp"
16#include "detray/io/backend/detail/basic_converter.hpp"
17#include "detray/io/backend/detail/type_info.hpp"
18#include "detray/io/backend/homogeneous_material_reader.hpp"
19#include "detray/io/frontend/payloads.hpp"
20#include "detray/material/material_slab.hpp"
21#include "detray/utils/type_list.hpp"
22
23// System include(s)
24#include <memory>
25#include <stdexcept>
26#include <string_view>
27#include <vector>
28
29namespace detray::io {
30
34template <typename DIM = std::integral_constant<std::size_t, 2u>>
36 using material_reader_t = homogeneous_material_reader;
37
38 public:
40 static constexpr std::size_t dim{DIM()};
41
45
48
50 static constexpr std::string_view tag = "material_maps";
51
57 template <concepts::detector detector_t>
58 static void from_payload(detector_builder<typename detector_t::metadata,
59 volume_builder> &det_builder,
60 payload_type &&grids_data) {
61 DETRAY_VERBOSE_HOST("Reading payload object...");
62
65 using mat_data_t = typename mat_factory_t::data_type;
66 using mat_id = typename detector_t::material::id;
67
68 // Map the io::shape_id in the payload to the shape types known by
69 // the detector under construction
70 using mat_registry_t =
71 io::detail::filtered_material_map_registry<detector_t>;
72 static_assert((!types::contains<mat_registry_t, io::detail::unknown_type> &&
73 types::size<mat_registry_t> > 0) ||
74 (types::contains<mat_registry_t, io::detail::unknown_type> &&
75 types::size<mat_registry_t> > 1));
76
77 DETRAY_VERBOSE_HOST("Converting material grids for "
78 << grids_data.grids.size() << " volumes");
79 // Convert the material volume by volume
80 for (const auto &[vol_idx, mat_grids] : grids_data.grids) {
81 if (!det_builder.has_volume(vol_idx)) {
82 std::stringstream err_stream;
83 err_stream << "Volume " << vol_idx << ": "
84 << "Cannot build material map for volume "
85 << "(volume not registered in detector builder)";
86 DETRAY_FATAL_HOST(err_stream.str());
87 throw std::invalid_argument(err_stream.str());
88 }
89
90 DETRAY_VERBOSE_HOST("Reading material maps in volume: "
91 << det_builder[static_cast<dindex>(vol_idx)]->name());
92
93 // Decorate the current volume builder with material maps
94 auto vm_builder =
95 det_builder.template decorate<material_map_builder<detector_t, dim>>(
96 static_cast<dindex>(vol_idx));
97
98 DETRAY_VERBOSE_HOST("-> Found " << mat_grids.size()
99 << " material grids:");
100
101 // Add the material data to the factory
102 auto mat_factory =
103 std::make_shared<material_map_factory<detector_t, bin_index_type>>();
104
105 // Convert the material grid of each surface
106 for (const auto &[idx, grid_data] : detray::views::enumerate(mat_grids)) {
107 DETRAY_VERBOSE_HOST("Reading material map payload #" << idx << "...");
108 // Get the number of bins per axis
109 std::vector<std::size_t> n_bins{};
110 for (const auto &axis_data : grid_data.axes) {
111 n_bins.push_back(axis_data.bins);
112 }
113
114 DETRAY_VERBOSE_HOST("-> Belongs to "
115 << (dim == 2 ? "surface" : "volume") << " = "
116 << grid_data.owner_link.link);
117
118 mat_id map_id =
119 from_payload<mat_registry_t, detector_t>(grid_data.grid_link.type);
120 DETRAY_VERBOSE_HOST("-> Type id: " << map_id);
121
122 DETRAY_VERBOSE_HOST("-> Reading axis bins: Dims = " << dim);
123 for ([[maybe_unused]] const auto &[i, count] :
124 detray::views::enumerate(n_bins)) {
125 DETRAY_VERBOSE_HOST("--> Axis " << i << ": " << count << " bins");
126 }
127 // Get the axis spans
128 DETRAY_VERBOSE_HOST("-> Reading axis spans:");
129 std::vector<std::vector<scalar_t>> axis_spans = {};
130 for (const auto &[i, axis_data] :
131 detray::views::enumerate(grid_data.axes)) {
132 axis_spans.push_back({static_cast<scalar_t>(axis_data.edges.front()),
133 static_cast<scalar_t>(axis_data.edges.back())});
134 DETRAY_VERBOSE_HOST("--> Axis " << i << " ["
135 << axis_spans.back().at(0) << ", "
136 << axis_spans.back().at(1) << "]");
137 }
138
139 // Get the local bin indices and the material parametrization
140 DETRAY_VERBOSE_HOST("-> Reading bin content...");
141
142 std::vector<bin_index_type> loc_bins{};
143 mat_data_t mat_data{
144 detail::basic_converter::from_payload(grid_data.owner_link)};
145 DETRAY_VERBOSE_HOST("--> Found " << grid_data.bins.size() << " bins");
146 for (const auto &bin_data : grid_data.bins) {
147 assert(dim == bin_data.loc_index.size() &&
148 "Dimension of local bin indices in input file does "
149 "not match material grid dimension");
150
151 // The local bin indices for the bin to be filled
152 bin_index_type mbin;
153 for (const auto &[i, bin_idx] :
154 detray::views::enumerate(bin_data.loc_index)) {
155 mbin[i] = bin_idx;
156 }
157 loc_bins.push_back(std::move(mbin));
158
159 // Add the material slab per bin
160 for (const auto &slab_data : bin_data.content) {
161 mat_data.append(
162 material_reader_t::template from_payload<scalar_t>(slab_data));
163 }
164 }
165
166 DETRAY_VERBOSE_HOST("Finished reading data for material map #" << idx);
167 DETRAY_DEBUG_HOST(mat_data);
168
169 DETRAY_VERBOSE_HOST("Add material data to factory...");
170 mat_factory->add_material(map_id, std::move(mat_data),
171 std::move(n_bins), std::move(axis_spans),
172 std::move(loc_bins));
173 }
174
175 // Add the material maps to the volume
176 DETRAY_VERBOSE_HOST("Add the material maps to the volume:");
177 vm_builder->add_surfaces(mat_factory);
178 }
179 }
180
181 private:
183 template <typename mat_registry_t, concepts::detector detector_t,
184 std::size_t I = 0u>
185 static typename detector_t::material::id from_payload(
186 io::material_id type_id) {
187 // Get the next mask shape type
188 using frame_t = types::at<mat_registry_t, I>;
189 using algebra_t = typename detector_t::algebra_type;
190
191 // Material id of map data found
192 if constexpr (!std::is_same_v<frame_t, io::detail::unknown_type> &&
193 ::detray::concepts::coordinate_frame<frame_t>) {
194 // Get the corresponding material id for this detector
195 constexpr auto mat_id{
196 types::id<io::material_registry<algebra_t>, frame_t>};
197 if (type_id == mat_id) {
198 using mat_frame_registry_t = io::detail::mat_frame_registry<detector_t>;
199
200 constexpr std::size_t mapped_idx{
201 types::position<mat_frame_registry_t, frame_t>};
202
203 return types::id_cast<typename detector_t::material,
204 mat_frame_registry_t::original_index(mapped_idx)>;
205 }
206 }
207 // Test next material type id
208 if constexpr (I < types::size<mat_registry_t> - 1u) {
210 } else {
211 return detector_t::material::id::e_none;
212 }
213 }
214};
215
216} // namespace detray::io
Provides functionality to build a detray detector volume by volume.
Definition detector_builder.hpp:40
Homogeneous material reader backend.
Definition homogeneous_material_reader.hpp:34
Material map reader backend.
Definition material_map_reader.hpp:35
static constexpr std::size_t dim
Dimension of the material-grid bin index.
Definition material_map_reader.hpp:40
static constexpr std::string_view tag
Tag the reader as "material_maps".
Definition material_map_reader.hpp:50
static void from_payload(detector_builder< typename detector_t::metadata, volume_builder > &det_builder, payload_type &&grids_data)
Convert the material grids grids_data from their IO payload.
Definition material_map_reader.hpp:58
detector_grids_payload< surface_material_payload, io::material_id > payload_type
Payload type that the reader processes.
Definition material_map_reader.hpp:43
axis::multi_bin< dim > bin_index_type
Multi-axis bin index type used by material grids.
Definition material_map_reader.hpp:47
Factory class for material maps.
Definition material_map_factory.hpp:39
Provides basic functionality to build detector volumes.
Definition volume_builder.hpp:36
Check if a type can be used as a detector.
Definition concepts.hpp:47
The following enums are global for all detectors.
Definition concepts.hpp:18
material_id
Enumerate the different material types.
Definition definitions.hpp:59
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
Multi-bin: contains bin indices from multiple axes.
Definition axis.hpp:36
A payload for the grid collections of a detector.
Definition payloads.hpp:344
Range adaptor that creates an enumerate view, optionally starting at a selected index.
Definition enumerate.hpp:266