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/detector_builder.hpp"
0011 
0012 #include "detray/builders/cuboid_portal_generator.hpp"
0013 #include "detray/builders/cylinder_portal_generator.hpp"
0014 #include "detray/builders/surface_factory.hpp"
0015 #include "detray/core/detector.hpp"
0016 #include "detray/definitions/indexing.hpp"
0017 
0018 // Detray test include(s)
0019 #include "detray/test/framework/types.hpp"
0020 
0021 // Vecmem include(s)
0022 #include <vecmem/memory/host_memory_resource.hpp>
0023 
0024 // GTest include(s)
0025 #include <gtest/gtest.h>
0026 
0027 namespace {
0028 
0029 using scalar = detray::test::scalar;
0030 using point3 = detray::test::point3;
0031 using vector3 = detray::test::vector3;
0032 using point2 = detray::test::point2;
0033 
0034 }  // anonymous namespace
0035 
0036 /// Integration test to build a cylinder volume with contained surfaces
0037 GTEST_TEST(detray_builders, detector_builder) {
0038   using namespace detray;
0039 
0040   using metadata_t = test::default_metadata;
0041   using detector_builder_t = detector_builder<metadata_t>;
0042   using detector_t = typename detector_builder_t::detector_type;
0043   using transform3 = dtransform3D<typename detector_t::algebra_type>;
0044   using mask_id = typename detector_t::masks::id;
0045 
0046   // Surface factories
0047   using trapezoid_factory = surface_factory<detector_t, trapezoid2D>;
0048 
0049   // detector builder
0050   auto geo_ctx = typename detector_t::geometry_context{};
0051 
0052   detector_builder_t det_builder{};
0053   det_builder.set_name("test_detector");
0054 
0055   //
0056   // first volume builder
0057   //
0058   auto vbuilder = det_builder.new_volume(volume_id::e_cylinder);
0059 
0060   typename detector_t::point3_type t{0.f, 0.f, 0.f};
0061   vbuilder->add_volume_placement(t);
0062 
0063   // initial checks
0064   EXPECT_EQ(vbuilder->vol_index(), 0u);
0065 
0066   const auto vol_idx{
0067       static_cast<typename detector_t::surface_type::navigation_link>(
0068           vbuilder->vol_index())};
0069 
0070   auto trpz_factory = std::make_shared<trapezoid_factory>();
0071   typename trapezoid_factory::sf_data_collection trpz_sf_data;
0072   trpz_sf_data.emplace_back(surface_id::e_sensitive,
0073                             transform3(point3{0.f, 0.f, 1000.f}), vol_idx,
0074                             std::vector<scalar>{1.f, 3.f, 2.f, 0.25f});
0075   trpz_sf_data.emplace_back(surface_id::e_sensitive,
0076                             transform3(point3{0.f, 0.f, 1100.f}), vol_idx,
0077                             std::vector<scalar>{1.f, 3.f, 2.f, 0.25f});
0078   trpz_sf_data.emplace_back(surface_id::e_sensitive,
0079                             transform3(point3{0.f, 0.f, 1200.f}), vol_idx,
0080                             std::vector<scalar>{1.f, 3.f, 2.f, 0.25f});
0081   trpz_factory->push_back(std::move(trpz_sf_data));
0082 
0083   // Add a portal cylinder around the volume
0084   cylinder_portal_config<scalar> cfg{};
0085   auto cyl_generator =
0086       std::make_shared<cylinder_portal_generator<detector_t>>(cfg);
0087 
0088   vbuilder->add_surfaces(trpz_factory, geo_ctx);
0089   vbuilder->add_surfaces(cyl_generator);
0090 
0091   //
0092   // second volume builder
0093   //
0094   auto vbuilder2 = det_builder.new_volume(volume_id::e_cuboid);
0095 
0096   // volume builder
0097   t = typename detector_t::point3_type{0.f, 0.f, 20.f};
0098   vbuilder2->add_volume_placement(t);
0099 
0100   // Add a portal box around the cuboid volume with a min distance of 'env'
0101   constexpr auto env{0.1f * unit<scalar>::mm};
0102   auto cuboid_generator =
0103       std::make_shared<cuboid_portal_generator<detector_t>>(env);
0104 
0105   vbuilder2->add_surfaces(trpz_factory, geo_ctx);
0106   vbuilder2->add_surfaces(cuboid_generator);
0107 
0108   // initial checks
0109   EXPECT_EQ(vbuilder2->vol_index(), 1u);
0110 
0111   //
0112   // build the detector
0113   //
0114   vecmem::host_memory_resource host_mr;
0115   const detector_t d = det_builder.build(host_mr);
0116   const auto& vol0 = tracking_volume{d, 0u};
0117   const auto& vol1 = tracking_volume{d, 1u};
0118 
0119   // check the results
0120   EXPECT_EQ(d.volumes().size(), 2u);
0121   EXPECT_EQ(vol0.id(), volume_id::e_cylinder);
0122   EXPECT_EQ(vol0.index(), 0u);
0123   EXPECT_EQ(vol1.id(), volume_id::e_cuboid);
0124   EXPECT_EQ(vol1.index(), 1u);
0125 
0126   // Check the volume placements for both volumes
0127   typename detector_t::transform3_type identity{};
0128   EXPECT_TRUE(vol0.transform() == identity);
0129   EXPECT_TRUE(d.transform_store().at(0u) == identity);
0130   typename detector_t::transform3_type trf{t};
0131   EXPECT_TRUE(vol1.transform() == trf);
0132   EXPECT_TRUE(d.transform_store().at(8u) == trf);
0133 
0134   EXPECT_EQ(d.surfaces().size(), 16u);
0135   EXPECT_EQ(d.mask_store().template size<mask_id::e_concentric_cylinder2D>(),
0136             2u);
0137   EXPECT_EQ(d.mask_store().template size<mask_id::e_ring2D>(), 2u);
0138   EXPECT_EQ(d.mask_store().template size<mask_id::e_annulus2D>(), 0u);
0139   EXPECT_EQ(d.mask_store().template size<mask_id::e_cylinder2D>(), 0u);
0140   // Portal rectangle masks are deduplicated
0141   EXPECT_EQ(d.mask_store().template size<mask_id::e_rectangle2D>(), 3u);
0142   EXPECT_EQ(d.mask_store().template size<mask_id::e_ring2D>(), 2u);
0143   EXPECT_EQ(d.mask_store().template size<mask_id::e_trapezoid2D>(), 6u);
0144 }