Back to home page

EIC code displayed by LXR

 
 

    


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

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/geometry/shapes/line.hpp"
0011 
0012 #include "detray/definitions/units.hpp"
0013 #include "detray/geometry/concepts.hpp"
0014 #include "detray/geometry/mask.hpp"
0015 
0016 // Detray test include(s)
0017 #include "detray/test/framework/types.hpp"
0018 #include "detray/test/utils/ratio_test.hpp"
0019 
0020 // GTest include
0021 #include <gtest/gtest.h>
0022 
0023 using namespace detray;
0024 
0025 using test_algebra = test::algebra;
0026 using scalar = test::scalar;
0027 using point3 = test::point3;
0028 
0029 namespace {
0030 
0031 constexpr scalar tol{1e-4f};
0032 
0033 // 50 mm wire with 1 mm radial cell size
0034 constexpr scalar cell_size{1.f * unit<scalar>::mm};
0035 constexpr scalar hz{50.f * unit<scalar>::mm};
0036 
0037 }  // anonymous namespace
0038 
0039 /// This tests the basic functionality of a line with a radial cross section
0040 GTEST_TEST(detray_masks, line_circular) {
0041   static_assert(concepts::shape<line_circular, test_algebra>);
0042   static_assert(concepts::line_shape<line_circular, test_algebra>);
0043 
0044   const point3 ln_in{0.09f, 0.5f, 0.f};
0045   const point3 ln_edge{1.f, 50.f, 0.f};
0046   const point3 ln_out1{1.2f, 0.f, 0.f};
0047   const point3 ln_out2{0.09f, -51.f, 0.f};
0048 
0049   const mask<line_circular, test_algebra> ln{0u, cell_size, hz};
0050 
0051   ASSERT_NEAR(ln[line_circular::e_cross_section], 1.f * unit<scalar>::mm, tol);
0052   ASSERT_NEAR(ln[line_circular::e_half_z], 50.f * unit<scalar>::mm, tol);
0053 
0054   ASSERT_TRUE(ln.is_inside(ln_in));
0055   ASSERT_TRUE(ln.is_inside(ln_edge));
0056   ASSERT_FALSE(ln.is_inside(ln_out1));
0057   ASSERT_FALSE(ln.is_inside(ln_out2));
0058 
0059   // Check area and measure
0060   EXPECT_NEAR(ln.area(), 628.318531f * unit<scalar>::mm2, tol);
0061   EXPECT_NEAR(ln.measure(), 314.159265359f * unit<scalar>::mm3, tol);
0062 
0063   // Check bounding box
0064   constexpr scalar envelope{0.01f};
0065   const auto loc_bounds = ln.local_min_bounds(envelope);
0066   ASSERT_NEAR(loc_bounds[cuboid3D::e_min_x], -(cell_size + envelope), tol);
0067   ASSERT_NEAR(loc_bounds[cuboid3D::e_min_y], -(cell_size + envelope), tol);
0068   ASSERT_NEAR(loc_bounds[cuboid3D::e_min_z], -(hz + envelope), tol);
0069   ASSERT_NEAR(loc_bounds[cuboid3D::e_max_x], (cell_size + envelope), tol);
0070   ASSERT_NEAR(loc_bounds[cuboid3D::e_max_y], (cell_size + envelope), tol);
0071   ASSERT_NEAR(loc_bounds[cuboid3D::e_max_z], (hz + envelope), tol);
0072 
0073   const auto centroid = ln.centroid();
0074   ASSERT_NEAR(centroid[0], 0.f, tol);
0075   ASSERT_NEAR(centroid[1], 0.f, tol);
0076   ASSERT_NEAR(centroid[2], 0.f, tol);
0077 }
0078 
0079 /// This tests the inside/outside method of the mask
0080 GTEST_TEST(detray_masks, line_circular_ratio_test) {
0081   struct mask_check {
0082     bool operator()(const point3 &p,
0083                     const mask<line_circular, test_algebra> &st,
0084                     const test::transform3 &trf, const test::vector3 & /*dir*/,
0085                     const scalar t) {
0086       return st.is_inside(trf, p, t);
0087     }
0088   };
0089 
0090   constexpr mask<line_circular, test_algebra> st{0u, 3.f, 5.f};
0091 
0092   constexpr scalar t{0.f};
0093   const test::transform3 trf{};
0094   // Track direction not parallel to the line, so that we always
0095   // have a valid local position (normally ensure by the intersector)
0096   test::vector3 dir{1.f, 0.f, 0.f};
0097   constexpr scalar size{10.f * unit<scalar>::mm};
0098   const auto n_points{static_cast<std::size_t>(std::pow(500, 3))};
0099 
0100   std::vector<point3> points =
0101       test::generate_regular_points<cuboid3D>(n_points, {size});
0102 
0103   scalar ratio = test::ratio_test<mask_check>(points, st, trf, dir, t);
0104 
0105   const scalar volume{st.measure()};
0106   const scalar world{size * size * size};
0107 
0108   ASSERT_NEAR(ratio, volume / world, 0.001f);
0109 }
0110 
0111 /// This tests the basic functionality of a line with a square cross section
0112 GTEST_TEST(detray_masks, line_square) {
0113   static_assert(concepts::shape<line_square, test_algebra>);
0114   static_assert(concepts::line_shape<line_circular, test_algebra>);
0115 
0116   const point3 ln_in{static_cast<scalar>(1.1f), static_cast<scalar>(0.9f),
0117                      constant<scalar>::pi_4};
0118   const point3 ln_edge{1.f, 1.f, 0.f};
0119   const point3 ln_out1{1.1f, 0.f, 0.f};
0120   const point3 ln_out2{0.09f, -51.f, 0.f};
0121 
0122   // 50 mm wire with 1 mm square cell sizes
0123   const mask<line_square, test_algebra> ln{0u, cell_size, hz};
0124 
0125   ASSERT_NEAR(ln[line_circular::e_cross_section], 1.f * unit<scalar>::mm, tol);
0126   ASSERT_NEAR(ln[line_circular::e_half_z], 50.f * unit<scalar>::mm, tol);
0127 
0128   ASSERT_TRUE(ln.is_inside(ln_in));
0129   ASSERT_TRUE(ln.is_inside(ln_edge, 1e-5f));
0130   ASSERT_FALSE(ln.is_inside(ln_edge, -1e-5f));
0131   ASSERT_FALSE(ln.is_inside(ln_out1));
0132   ASSERT_FALSE(ln.is_inside(ln_out2));
0133 
0134   // Check area and measure
0135   EXPECT_NEAR(ln.area(), 800.f * unit<scalar>::mm2, tol);
0136   EXPECT_NEAR(ln.measure(), 400.f * unit<scalar>::mm3, tol);
0137 
0138   // Check bounding box
0139   constexpr scalar envelope{0.01f};
0140   const auto loc_bounds = ln.local_min_bounds(envelope);
0141   ASSERT_NEAR(loc_bounds[cuboid3D::e_min_x], -(cell_size + envelope), tol);
0142   ASSERT_NEAR(loc_bounds[cuboid3D::e_min_y], -(cell_size + envelope), tol);
0143   ASSERT_NEAR(loc_bounds[cuboid3D::e_min_z], -(hz + envelope), tol);
0144   ASSERT_NEAR(loc_bounds[cuboid3D::e_max_x], (cell_size + envelope), tol);
0145   ASSERT_NEAR(loc_bounds[cuboid3D::e_max_y], (cell_size + envelope), tol);
0146   ASSERT_NEAR(loc_bounds[cuboid3D::e_max_z], (hz + envelope), tol);
0147 
0148   const auto centroid = ln.centroid();
0149   ASSERT_NEAR(centroid[0], 0.f, tol);
0150   ASSERT_NEAR(centroid[1], 0.f, tol);
0151   ASSERT_NEAR(centroid[2], 0.f, tol);
0152 }
0153 
0154 /// This tests the inside/outside method of the mask
0155 GTEST_TEST(detray_masks, line_square_ratio_test) {
0156   struct mask_check {
0157     bool operator()(const point3 &p, const mask<line_square, test_algebra> &dcl,
0158                     const test::transform3 &trf, const test::vector3 & /*dir*/,
0159                     const scalar t) {
0160       return dcl.is_inside(trf, p, t);
0161     }
0162   };
0163 
0164   constexpr mask<line_square, test_algebra> dcl{0u, 3.f, 5.f};
0165 
0166   constexpr scalar t{0.f};
0167   const test::transform3 trf{};
0168   // Track direction not parallel to the line, so that we always
0169   // have a valid local position (normally ensure by the intersector)
0170   test::vector3 dir{1.f, 0.f, 0.f};
0171   constexpr scalar size{10.f * unit<scalar>::mm};
0172   const auto n_points{static_cast<std::size_t>(std::pow(500, 3))};
0173 
0174   std::vector<point3> points =
0175       test::generate_regular_points<cuboid3D>(n_points, {size});
0176 
0177   scalar ratio = test::ratio_test<mask_check>(points, dcl, trf, dir, t);
0178 
0179   const scalar volume{dcl.measure()};
0180   const scalar world{size * size * size};
0181 
0182   ASSERT_NEAR(ratio, volume / world, 0.005f);
0183 }