Back to home page

EIC code displayed by LXR

 
 

    


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

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 // Detray include(s)
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 // Detray test include(s)
0020 #include "detray/test/framework/types.hpp"
0021 
0022 // Vecmem include(s)
0023 #include <vecmem/memory/host_memory_resource.hpp>
0024 
0025 // Gtest include(s)
0026 #include <gtest/gtest.h>
0027 
0028 // System include(s)
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 }  // anonymous namespace
0043 
0044 /// Integration test: grid builder as volume builder decorator
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   // cylinder grid type of the toy detector
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   // passive surfaces are added to the grid
0074   // gbuilder.set_add_surfaces();
0075 
0076   // The cylinder portals are at the end of the surface range by construction
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   // Build empty grid
0083   gbuilder.init_grid(cyl_mask, {n_phi_bins, n_z_bins});
0084 
0085   EXPECT_TRUE(d.volumes().empty());
0086 
0087   // Add some portals first
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   // Then some passive and sensitive surfaces
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   // senstivies should end up in the grid, portals in the volume
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   // check results
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   // only the portals are referenced through the volume
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   // toy detector makes no distinction between the surface types
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   // Only the portals should be in the detector's surface container now
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   // check the portals in the detector
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   // check the sensitive surfaces in the grid
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 }