File indexing completed on 2026-05-27 07:24:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "detray/builders/volume_builder.hpp"
0011
0012 #include "detray/builders/cuboid_portal_generator.hpp"
0013 #include "detray/builders/detector_builder.hpp"
0014 #include "detray/builders/surface_factory.hpp"
0015 #include "detray/core/detector.hpp"
0016 #include "detray/definitions/indexing.hpp"
0017 #include "detray/geometry/mask.hpp"
0018 #include "detray/geometry/shapes.hpp"
0019
0020
0021 #include "detray/test/framework/types.hpp"
0022
0023
0024 #include <vecmem/memory/host_memory_resource.hpp>
0025
0026
0027 #include <gtest/gtest.h>
0028
0029 namespace {
0030
0031 using scalar = detray::test::scalar;
0032 using point3 = detray::test::point3;
0033
0034 constexpr scalar tol{1e-7f};
0035
0036 }
0037
0038
0039 GTEST_TEST(detray_builders, surface_factory) {
0040 using namespace detray;
0041
0042 using metadata_t = test::default_metadata;
0043 using detector_t = detector<metadata_t>;
0044 using transform3 = dtransform3D<typename detector_t::algebra_type>;
0045
0046
0047
0048
0049 using portal_cylinder_factory =
0050 surface_factory<detector_t, concentric_cylinder2D>;
0051
0052 auto pt_cyl_factory = std::make_shared<portal_cylinder_factory>();
0053
0054 typename portal_cylinder_factory::sf_data_collection cyl_sf_data;
0055 cyl_sf_data.emplace_back(surface_id::e_portal,
0056 transform3(point3{0.f, 0.f, -1000.f}), 0u,
0057 std::vector<scalar>{10.f, -1000.f, 1500.f});
0058 cyl_sf_data.emplace_back(surface_id::e_portal,
0059 transform3(point3{0.f, 0.f, 1000.f}), 2u,
0060 std::vector<scalar>{20.f, -1500.f, 1000.f});
0061
0062 EXPECT_EQ(pt_cyl_factory->size(), 0u);
0063 EXPECT_TRUE(pt_cyl_factory->types().empty());
0064 EXPECT_TRUE(pt_cyl_factory->bounds().empty());
0065 EXPECT_TRUE(pt_cyl_factory->transforms().empty());
0066 EXPECT_TRUE(pt_cyl_factory->volume_links().empty());
0067
0068 pt_cyl_factory->push_back(std::move(cyl_sf_data));
0069
0070 cyl_sf_data.clear();
0071
0072 EXPECT_EQ(pt_cyl_factory->size(), 2u);
0073 EXPECT_EQ(pt_cyl_factory->types().size(), 2u);
0074 EXPECT_EQ(pt_cyl_factory->bounds().size(), 2u);
0075 EXPECT_EQ(pt_cyl_factory->transforms().size(), 2u);
0076 EXPECT_EQ(pt_cyl_factory->volume_links().size(), 2u);
0077 const auto& portal_cyl_comps = pt_cyl_factory->bounds().front().front();
0078 EXPECT_NEAR(portal_cyl_comps[0], 10.f, tol);
0079 EXPECT_NEAR(portal_cyl_comps[1], -1000.f, tol);
0080 EXPECT_NEAR(portal_cyl_comps[2], 1500.f, tol);
0081 const auto& portal_cyl_vol_links = pt_cyl_factory->volume_links();
0082 EXPECT_EQ(portal_cyl_vol_links[0][0], 0u);
0083 EXPECT_EQ(portal_cyl_vol_links[1][0], 2u);
0084
0085
0086
0087
0088 using sensitive_cylinder_factory = surface_factory<detector_t, cylinder2D>;
0089
0090 auto cyl_factory = std::make_shared<sensitive_cylinder_factory>();
0091
0092 cyl_sf_data.emplace_back(surface_id::e_sensitive,
0093 transform3(point3{0.f, 0.f, -50.f}), 1u,
0094 std::vector<scalar>{5.f, -900.f, 900.f});
0095 cyl_sf_data.emplace_back(surface_id::e_sensitive,
0096 transform3(point3{0.f, 0.f, 50.f}), 1u,
0097 std::vector<scalar>{5.f, -900.f, 900.f});
0098
0099 cyl_sf_data.emplace_back(surface_id::e_passive,
0100 transform3(point3{0.f, 0.f, -20.f}), 1u,
0101 std::vector<scalar>{4.9f, -900.f, 900.f});
0102 cyl_sf_data.emplace_back(surface_id::e_passive,
0103 transform3(point3{0.f, 0.f, 20.f}), 1u,
0104 std::vector<scalar>{4.9f, -900.f, 900.f});
0105
0106 EXPECT_EQ(cyl_factory->size(), 0u);
0107 EXPECT_TRUE(cyl_factory->types().empty());
0108 EXPECT_TRUE(cyl_factory->bounds().empty());
0109 EXPECT_TRUE(cyl_factory->transforms().empty());
0110 EXPECT_TRUE(cyl_factory->volume_links().empty());
0111
0112 cyl_factory->push_back(std::move(cyl_sf_data));
0113 cyl_sf_data.clear();
0114
0115 EXPECT_EQ(cyl_factory->size(), 4u);
0116 EXPECT_EQ(cyl_factory->types().size(), 4u);
0117 EXPECT_EQ(cyl_factory->bounds().size(), 4u);
0118 EXPECT_EQ(cyl_factory->transforms().size(), 4u);
0119 EXPECT_EQ(cyl_factory->volume_links().size(), 4u);
0120 const auto& sens_cyl_comps = cyl_factory->bounds().front().front();
0121 EXPECT_NEAR(sens_cyl_comps[0], 5.f, tol);
0122 EXPECT_NEAR(sens_cyl_comps[1], -900.f, tol);
0123 EXPECT_NEAR(sens_cyl_comps[2], 900.f, tol);
0124 const auto& sens_cyl_vol_links = cyl_factory->volume_links().front();
0125 EXPECT_EQ(sens_cyl_vol_links[0], 1u);
0126
0127
0128
0129
0130
0131
0132 using annulus_factory = surface_factory<detector_t, annulus2D>;
0133
0134 auto ann_factory = std::make_shared<annulus_factory>();
0135
0136 typename annulus_factory::sf_data_collection ann_sf_data;
0137 ann_sf_data.emplace_back(
0138 surface_id::e_sensitive, transform3(point3{0.f, 0.f, 0.f}), 1u,
0139 std::vector<scalar>{300.f, 350.f, -0.1f, 0.1f, 0.5f, 0.6f, 1.4f});
0140 ann_factory->push_back(std::move(ann_sf_data));
0141 ann_sf_data.clear();
0142
0143 const auto& ann_comps = ann_factory->bounds().front().front();
0144 EXPECT_NEAR(ann_comps[0], 300.f, tol);
0145 EXPECT_NEAR(ann_comps[1], 350.f, tol);
0146 EXPECT_NEAR(ann_comps[2], -0.1f, tol);
0147 EXPECT_NEAR(ann_comps[3], 0.1f, tol);
0148 EXPECT_NEAR(ann_comps[4], 0.5f, tol);
0149 EXPECT_NEAR(ann_comps[5], 0.6f, tol);
0150 EXPECT_NEAR(ann_comps[6], 1.4f, tol);
0151
0152
0153 using rectangle_factory = surface_factory<detector_t, rectangle2D>;
0154
0155 auto rect_factory = std::make_shared<rectangle_factory>();
0156
0157 typename rectangle_factory::sf_data_collection rect_sf_data;
0158 rect_sf_data.emplace_back(surface_id::e_sensitive,
0159 transform3(point3{0.f, 0.f, 0.f}), 1u,
0160 std::vector<scalar>{10.f, 8.f});
0161 rect_factory->push_back(std::move(rect_sf_data));
0162 rect_sf_data.clear();
0163
0164 const auto& rectgl_comps = rect_factory->bounds().front().front();
0165 EXPECT_NEAR(rectgl_comps[0], 10.f, tol);
0166 EXPECT_NEAR(rectgl_comps[1], 8.f, tol);
0167
0168
0169 using disc_factory = surface_factory<detector_t, ring2D>;
0170
0171 auto sf_disc_factory = std::make_shared<disc_factory>();
0172
0173 typename disc_factory::sf_data_collection disc_sf_data;
0174 disc_sf_data.emplace_back(surface_id::e_passive,
0175 transform3(point3{0.f, 0.f, 0.f}), 1u,
0176 std::vector<scalar>{0.f, 5.f});
0177 sf_disc_factory->push_back(std::move(disc_sf_data));
0178 disc_sf_data.clear();
0179
0180 const auto& ring_comps = sf_disc_factory->bounds().front().front();
0181 EXPECT_NEAR(ring_comps[0], 0.f, tol);
0182 EXPECT_NEAR(ring_comps[1], 5.f, tol);
0183
0184
0185 using trapezoid_factory = surface_factory<detector_t, trapezoid2D>;
0186
0187 auto trpz_factory = std::make_shared<trapezoid_factory>();
0188
0189 typename trapezoid_factory::sf_data_collection trpz_sf_data;
0190 trpz_sf_data.emplace_back(surface_id::e_sensitive,
0191 transform3(point3{0.f, 0.f, 0.f}), 1u,
0192 std::vector<scalar>{1.f, 3.f, 2.f, 0.25f});
0193 trpz_factory->push_back(std::move(trpz_sf_data));
0194 trpz_sf_data.clear();
0195
0196 const auto& trpz_comps = trpz_factory->bounds().front().front();
0197 EXPECT_NEAR(trpz_comps[0], 1.f, tol);
0198 EXPECT_NEAR(trpz_comps[1], 3.f, tol);
0199 EXPECT_NEAR(trpz_comps[2], 2.f, tol);
0200 EXPECT_NEAR(trpz_comps[3], 0.25f, tol);
0201 }
0202
0203
0204 GTEST_TEST(detray_builders, volume_builder) {
0205 using namespace detray;
0206
0207 vecmem::host_memory_resource host_mr;
0208
0209 using metadata_t = test::default_metadata;
0210 using detector_t = detector<metadata_t>;
0211 using transform3 = typename detector_t::transform3_type;
0212
0213 detector_t d(host_mr);
0214
0215 EXPECT_TRUE(d.volumes().empty());
0216
0217 using rectangle_factory = surface_factory<detector_t, rectangle2D>;
0218 auto sf_factory = std::make_shared<rectangle_factory>();
0219 sf_factory->push_back({surface_id::e_sensitive,
0220 transform3(point3{0.f, 0.f, -1.f}), 1u,
0221 std::vector<scalar>{10.f, 8.f}});
0222
0223 volume_builder<detector_t> vbuilder{volume_id::e_cylinder};
0224 vbuilder.add_surfaces(sf_factory);
0225 vbuilder.build(d);
0226
0227 const auto& vol = d.volumes().back();
0228
0229 EXPECT_TRUE(d.volumes().size() == 1u);
0230 EXPECT_EQ(vol.index(), 0u);
0231 EXPECT_EQ(vol.index(), vbuilder.vol_index());
0232 EXPECT_EQ(vol.id(), volume_id::e_cylinder);
0233 }