File indexing completed on 2026-05-27 07:24:15
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "detray/builders/grid_builder.hpp"
0011
0012 #include "detray/builders/surface_factory.hpp"
0013 #include "detray/builders/volume_builder.hpp"
0014 #include "detray/core/detector.hpp"
0015 #include "detray/definitions/indexing.hpp"
0016 #include "detray/geometry/mask.hpp"
0017 #include "detray/utils/type_list.hpp"
0018
0019
0020 #include "detray/test/framework/types.hpp"
0021
0022
0023 #include <vecmem/memory/host_memory_resource.hpp>
0024
0025
0026 #include <gtest/gtest.h>
0027
0028
0029 #include <limits>
0030
0031 using namespace detray;
0032 using namespace detray::axis;
0033
0034 namespace {
0035
0036 using scalar = test::scalar;
0037 using point3 = test::point3;
0038 using vector3 = test::vector3;
0039
0040 using detector_t = detector<test::toy_metadata>;
0041
0042 }
0043
0044
0045 GTEST_TEST(detray_builders, decorator_grid_builder) {
0046 using algebra_t = typename detector_t::algebra_type;
0047 using transform3 = dtransform3D<algebra_t>;
0048 using geo_obj_id = typename detector_t::geo_obj_ids;
0049 using acc_ids = typename detector_t::accel::id;
0050 using mask_id = typename detector_t::masks::id;
0051
0052
0053 using cyl_grid_t = grid<algebra_t, axes<concentric_cylinder2D>,
0054 bins::static_array<detector_t::surface_type, 1>,
0055 simple_serializer, host_container_types, false>;
0056
0057 using pt_cylinder_t = concentric_cylinder2D;
0058 using pt_cylinder_factory_t = surface_factory<detector_t, pt_cylinder_t>;
0059 using rectangle_factory = surface_factory<detector_t, rectangle2D>;
0060 using trapezoid_factory = surface_factory<detector_t, trapezoid2D>;
0061 using cylinder_factory = surface_factory<detector_t, pt_cylinder_t>;
0062
0063 vecmem::host_memory_resource host_mr;
0064 detector_t d(host_mr);
0065 auto geo_ctx = typename detector_t::geometry_context{};
0066 const auto vol_idx{
0067 static_cast<typename detector_t::surface_type::navigation_link>(
0068 d.volumes().size())};
0069
0070 auto vbuilder = std::make_unique<volume_builder<detector_t>>(
0071 volume_id::e_cylinder, vol_idx);
0072 auto gbuilder = grid_builder<detector_t, cyl_grid_t>{std::move(vbuilder)};
0073
0074
0075
0076
0077 const auto cyl_mask =
0078 mask<concentric_cylinder2D, algebra_t>{0u, 10.f, -500.f, 500.f};
0079 std::size_t n_phi_bins{5u};
0080 std::size_t n_z_bins{4u};
0081
0082
0083 gbuilder.init_grid(cyl_mask, {n_phi_bins, n_z_bins});
0084
0085 EXPECT_TRUE(d.volumes().empty());
0086
0087
0088 auto pt_cyl_factory = std::make_shared<pt_cylinder_factory_t>();
0089
0090 typename pt_cylinder_factory_t::sf_data_collection cyl_sf_data;
0091 cyl_sf_data.emplace_back(surface_id::e_portal,
0092 transform3(point3{0.f, 0.f, 0.f}), 0u,
0093 std::vector<scalar>{10.f, -1500.f, 1500.f});
0094 cyl_sf_data.emplace_back(surface_id::e_portal,
0095 transform3(point3{0.f, 0.f, 0.f}), 2u,
0096 std::vector<scalar>{20.f, -1500.f, 1500.f});
0097 pt_cyl_factory->push_back(std::move(cyl_sf_data));
0098
0099
0100 auto rect_factory = std::make_shared<rectangle_factory>();
0101
0102 typename rectangle_factory::sf_data_collection rect_sf_data;
0103 rect_sf_data.emplace_back(surface_id::e_sensitive,
0104 transform3(point3{7.07f, 7.07f, -500.f}), vol_idx,
0105 std::vector<scalar>{10.f, 8.f});
0106 rect_sf_data.emplace_back(surface_id::e_sensitive,
0107 transform3(point3{7.07f, 7.07f, -250.f}), vol_idx,
0108 std::vector<scalar>{10.f, 8.f});
0109 rect_sf_data.emplace_back(surface_id::e_sensitive,
0110 transform3(point3{7.07f, 7.07f, 100.f}), vol_idx,
0111 std::vector<scalar>{10.f, 8.f});
0112 rect_factory->push_back(std::move(rect_sf_data));
0113
0114 auto trpz_factory = std::make_shared<trapezoid_factory>();
0115
0116 typename trapezoid_factory::sf_data_collection trpz_sf_data;
0117 trpz_sf_data.emplace_back(surface_id::e_sensitive,
0118 transform3(point3{7.07f, 7.07f, 600.f}), vol_idx,
0119 std::vector<scalar>{1.f, 3.f, 2.f, 0.25f});
0120 trpz_factory->push_back(std::move(trpz_sf_data));
0121
0122 auto cyl_factory = std::make_shared<cylinder_factory>();
0123
0124 cyl_sf_data.clear();
0125 cyl_sf_data.emplace_back(surface_id::e_passive,
0126 transform3(point3{0.f, 0.f, 0.f}), vol_idx,
0127 std::vector<scalar>{5.f, -1300.f, 1300.f});
0128 cyl_factory->push_back(std::move(cyl_sf_data));
0129
0130
0131 gbuilder.add_surfaces(pt_cyl_factory, geo_ctx);
0132 gbuilder.add_surfaces(rect_factory, geo_ctx);
0133 gbuilder.add_surfaces(trpz_factory, geo_ctx);
0134 gbuilder.add_surfaces(cyl_factory, geo_ctx);
0135
0136 const auto& cyl_axis_z = gbuilder.get().template get_axis<label::e_cyl_z>();
0137 EXPECT_EQ(cyl_axis_z.label(), label::e_cyl_z);
0138 EXPECT_EQ(cyl_axis_z.nbins(), 4u);
0139
0140 gbuilder.build(d);
0141
0142
0143
0144
0145 const auto& vol = d.volumes().back();
0146 EXPECT_TRUE(d.volumes().size() == 1u);
0147 EXPECT_EQ(vol.index(), 0u);
0148 EXPECT_EQ(vol.id(), volume_id::e_cylinder);
0149
0150
0151 test::toy_metadata::object_link_type sf_range{};
0152 sf_range[0] = {acc_ids::e_surface_default, 0u};
0153 sf_range[1] = {acc_ids::e_surface_concentric_cylinder2D_grid, 0u};
0154
0155
0156 EXPECT_EQ(vol.template accel_link<geo_obj_id::e_portal>(),
0157 sf_range[geo_obj_id::e_portal]);
0158 EXPECT_EQ(vol.template accel_link<geo_obj_id::e_sensitive>(),
0159 sf_range[geo_obj_id::e_sensitive]);
0160 EXPECT_EQ(vol.template accel_link<geo_obj_id::e_passive>(),
0161 sf_range[geo_obj_id::e_passive]);
0162
0163
0164 EXPECT_EQ(d.surfaces().size(), 7u);
0165 EXPECT_EQ(d.mask_store().template size<mask_id::e_concentric_cylinder2D>(),
0166 3u);
0167 EXPECT_EQ(d.mask_store().template size<mask_id::e_ring2D>(), 0u);
0168 EXPECT_EQ(d.mask_store().template size<mask_id::e_rectangle2D>(), 3u);
0169 EXPECT_EQ(d.mask_store().template size<mask_id::e_trapezoid2D>(), 1u);
0170
0171
0172 const auto& bf_finder =
0173 d.accelerator_store()
0174 .template get<detector_t::accel::id::e_surface_brute_force>()[0];
0175 for (const auto& sf : bf_finder.all()) {
0176 EXPECT_TRUE((sf.id() == surface_id::e_portal) ||
0177 (sf.id() == surface_id::e_passive));
0178 EXPECT_EQ(sf.volume(), 0u);
0179 }
0180
0181
0182 const auto& cyl_grid =
0183 d.accelerator_store()
0184 .template get<
0185 detector_t::accel::id::e_surface_concentric_cylinder2D_grid>()[0];
0186 dindex trf_idx{3u};
0187 for (const auto& sf : cyl_grid.all()) {
0188 EXPECT_TRUE(sf.is_sensitive());
0189 EXPECT_EQ(sf.volume(), 0u);
0190 EXPECT_EQ(sf.transform(), trf_idx++);
0191 }
0192 }