Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-27 07:24:20

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 // Project include(s)
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 // Detray test include(s)
0021 #include "detray/test/framework/types.hpp"
0022 
0023 // Vecmem include(s)
0024 #include <vecmem/memory/host_memory_resource.hpp>
0025 
0026 // GTest include(s)
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 }  // anonymous namespace
0037 
0038 /// This tests the functionality of a surface factory
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   // check portal cylinder
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   // data should be safely added to the factory by now
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   // check sensitive cylinder
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   // check the other mask types for this detector
0129   //
0130 
0131   // annulus
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   // rectangles
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   // ring
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   // trapezoid
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 /// This tests the initialization of a detector volume using a volume builder
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 }