12#include "detray/builders/detector_builder.hpp"
13#include "detray/builders/surface_factory.hpp"
14#include "detray/builders/volume_builder.hpp"
15#include "detray/core/concepts.hpp"
16#include "detray/definitions/indexing.hpp"
17#include "detray/io/backend/detail/basic_converter.hpp"
18#include "detray/io/backend/detail/type_info.hpp"
19#include "detray/io/frontend/payloads.hpp"
34struct hash<detray::io::shape_id> {
36 return std::hash<std::size_t>()(
static_cast<std::size_t
>(
m));
54 static constexpr std::string_view
tag =
"geometry";
63 template <
class detector_t>
67 DETRAY_VERBOSE_HOST(
"Reading payload object...");
70 using sf_factory_ptr_t =
71 std::shared_ptr<surface_factory_interface<detector_t>>;
75 using shape_registry_t = io::detail::filtered_shape_registry<detector_t>;
77 (!types::contains<shape_registry_t, io::detail::unknown_type> &&
78 types::size<shape_registry_t> > 0) ||
79 (types::contains<shape_registry_t, io::detail::unknown_type> &&
80 types::size<shape_registry_t> > 1));
82 DETRAY_DEBUG_HOST(
"Have " << det_data.
volumes.size() <<
" input volumes");
85 for (
const auto& vol_data : det_data.
volumes) {
87 DETRAY_DEBUG_HOST(
"Configuring detector builder with new volume '"
88 << vol_data.name <<
"' of type " << vol_data.type);
89 auto vbuilder = det_builder.new_volume(vol_data.type);
92 vbuilder->set_name(vol_data.name);
94 DETRAY_DEBUG_HOST(
"Volume placement for " << vol_data.name <<
" is\n"
95 << vol_data.transform);
97 vbuilder->add_volume_placement(
101 std::map<io_shape_id, sf_factory_ptr_t> pt_factories;
102 std::map<io_shape_id, sf_factory_ptr_t> sf_factories;
105 DETRAY_DEBUG_HOST(
"Discovered " << vol_data.surfaces.size()
106 <<
" surfaces in volume payload");
107 for (
const auto& [sf_idx, sf_data] :
109 const std::vector<mask_payload>& mask_data = sf_data.masks;
112 auto& factories{sf_data.type == surface_id::e_portal ? pt_factories
116 auto shape_id{mask_data.front().shape == io_shape_id::cylinder2
117 ? io_shape_id::portal_cylinder2
118 : mask_data.front().shape};
120 if (
shape_id == io_shape_id::unknown) {
121 std::string err_str{
"Unknown mask shape id in geometry file!"};
122 DETRAY_FATAL_HOST(err_str);
123 throw std::invalid_argument(err_str);
129 if (
auto search = factories.find(key); search == factories.end()) {
131 "Creating new surface factory for shape id: " << key);
133 std::move(init_factory<shape_registry_t, detector_t>(
shape_id));
136 DETRAY_DEBUG_HOST(
"-> Surface #" << sf_idx <<
" is " << sf_data.type);
137 DETRAY_DEBUG_HOST(
"--> shape = " <<
shape_id);
138 for ([[maybe_unused]]
const auto& m_data : mask_data) {
139 DETRAY_DEBUG_HOST(
"--> boundaries = ["
140 << DETRAY_LOG_VECTOR(m_data.boundaries) <<
"]");
142 DETRAY_DEBUG_HOST(
"--> pos = ["
143 << DETRAY_LOG_VECTOR(sf_data.transform.tr) <<
"]");
150 typename detector_t::geometry_context geo_ctx{};
151 for (
const auto& [key, pt_factory] : pt_factories) {
152 DETRAY_DEBUG_HOST(
"Adding '" << key
153 <<
"' portal factory to volume builder");
154 vbuilder->add_surfaces(pt_factory, geo_ctx);
157 for (
const auto& [key, sf_factory] : sf_factories) {
158 DETRAY_DEBUG_HOST(
"Adding '" << key
159 <<
"' surface factory to volume builder");
160 vbuilder->add_surfaces(sf_factory, geo_ctx);
168 template <
class detector_t>
171 using algebra_t =
typename detector_t::algebra_type;
175 vector3_t t{
static_cast<scalar_t
>(trf_data.
tr[0]),
176 static_cast<scalar_t
>(trf_data.
tr[1]),
177 static_cast<scalar_t
>(trf_data.
tr[2])};
178 vector3_t x{
static_cast<scalar_t
>(trf_data.
rot[0]),
179 static_cast<scalar_t
>(trf_data.
rot[1]),
180 static_cast<scalar_t
>(trf_data.
rot[2])};
181 vector3_t y{
static_cast<scalar_t
>(trf_data.
rot[3]),
182 static_cast<scalar_t
>(trf_data.
rot[4]),
183 static_cast<scalar_t
>(trf_data.
rot[5])};
184 vector3_t z{
static_cast<scalar_t
>(trf_data.
rot[6]),
185 static_cast<scalar_t
>(trf_data.
rot[7]),
186 static_cast<scalar_t
>(trf_data.
rot[8])};
195 template <
class detector_t>
197 using nav_link_t =
typename detector_t::surface_type::navigation_link;
201 std::vector<std::vector<scalar_t>> mask_boundaries{};
202 for (
const auto& mask_data : sf_data.
masks) {
203 std::vector<scalar_t>& boundaries = mask_boundaries.emplace_back();
204 std::ranges::copy(mask_data.boundaries, std::back_inserter(boundaries));
213 if (sf_data.
masks.front().shape == io_shape_id::portal_cylinder2 ||
214 sf_data.
masks.front().shape == io_shape_id::cylinder2) {
215 const auto z_shift{
static_cast<scalar_t
>(trf.translation()[2])};
217 for (
auto& mask_boundary : mask_boundaries) {
218 mask_boundary[concentric_cylinder2D::e_lower_z] += z_shift;
219 mask_boundary[concentric_cylinder2D::e_upper_z] += z_shift;
223 trf =
decltype(trf){};
226 const std::size_t sf_idx{
229 : detray::detail::invalid_value<std::size_t>()};
231 std::vector<nav_link_t> vol_links{};
232 vol_links.reserve(sf_data.
masks.size());
233 for (
const auto& mask_pl : sf_data.
masks) {
234 vol_links.push_back(
static_cast<nav_link_t
>(
235 detail::basic_converter::from_payload(mask_pl.volume_link)));
238 assert(mask_boundaries.size() == vol_links.size());
240 return {sf_data.
type,
242 std::move(vol_links),
243 std::move(mask_boundaries),
244 static_cast<dindex>(sf_idx),
255 static std::shared_ptr<surface_factory_interface<detector_t>> init_factory(
258 using shape_t = types::at<shape_registry_t, I>;
261 if constexpr (!std::is_same_v<shape_t, io::detail::unknown_type>) {
263 if (
shape_id == types::id<io::shape_registry, shape_t>) {
264 return std::make_shared<surface_factory<detector_t, shape_t>>();
268 if constexpr (I < types::size<shape_registry_t> - 1u) {
269 return init_factory<shape_registry_t, detector_t, I + 1>(
shape_id);
272 "Given shape id could not be matched to a mask type: " +
273 std::to_string(
static_cast<std::int64_t
>(
shape_id))};
275 DETRAY_FATAL_HOST(err_str);
276 throw std::invalid_argument(err_str);
Provides functionality to build a detray detector volume by volume.
Definition detector_builder.hpp:40
Tracking geometry reader backend.
Definition geometry_reader.hpp:47
static void from_payload(detector_builder< typename detector_t::metadata, volume_builder > &det_builder, const payload_type &det_data)
Populate the detector builder from a serialized geometry payload.
Definition geometry_reader.hpp:64
detector_payload payload_type
Payload type that the reader processes.
Definition geometry_reader.hpp:57
static constexpr std::string_view tag
Tag the reader as "geometry".
Definition geometry_reader.hpp:54
static detector_t::transform3_type from_payload(const transform_payload &trf_data)
Definition geometry_reader.hpp:169
static surface_data< detector_t > from_payload(const surface_payload &sf_data)
Build surface-factory data from a serialized surface entry.
Definition geometry_reader.hpp:196
Bind transform and mask data together for surface building.
Definition surface_factory_interface.hpp:37
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
constexpr double m
Meter.
Definition Units.hpp:97
The following enums are global for all detectors.
Definition concepts.hpp:18
shape_id
Enumerate the shape primitives globally.
Definition definitions.hpp:33
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
get_vector3D_t< A, T > dvector3D
Three-dimensional vector type for algebra A and value type T.
Definition algebra.hpp:80
get_transform3D_t< A, T > dtransform3D
Three-dimensional transform type for algebra A and value type T.
Definition algebra.hpp:84
A payload for a detector geometry.
Definition payloads.hpp:355
std::vector< volume_payload > volumes
Material payloads grouped by detector volume.
Definition payloads.hpp:357
A payload for surfaces.
Definition payloads.hpp:153
detray::surface_id type
Either sensitive, passive or portal.
Definition payloads.hpp:169
transform_payload transform
Placement transform of the surface.
Definition payloads.hpp:158
std::optional< std::size_t > index_in_coll
Position of the surface in the volume surface container.
Definition payloads.hpp:156
std::vector< mask_payload > masks
Mask definitions attached to the surface.
Definition payloads.hpp:160
std::uint64_t source
Identifier of the source object (e.g. value of ACTS::GeometryIdentifier).
Definition payloads.hpp:164
Range adaptor that creates an enumerate view, optionally starting at a selected index.
Definition enumerate.hpp:266