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/annulus2D.hpp"
0011 
0012 #include "detray/definitions/math.hpp"
0013 #include "detray/definitions/units.hpp"
0014 #include "detray/geometry/concepts.hpp"
0015 #include "detray/geometry/mask.hpp"
0016 
0017 // Detray test include(s)
0018 #include "detray/test/framework/types.hpp"
0019 #include "detray/test/utils/ratio_test.hpp"
0020 
0021 // GTest include
0022 #include <gtest/gtest.h>
0023 
0024 using namespace detray;
0025 
0026 using test_algebra = test::algebra;
0027 using scalar = test::scalar;
0028 using point3 = test::point3;
0029 
0030 constexpr scalar tol{1e-5f};
0031 
0032 /// This tests the basic functionality of a stereo annulus
0033 GTEST_TEST(detray_masks, annulus2D) {
0034   static_assert(concepts::shape<annulus2D, test_algebra>);
0035   static_assert(concepts::planar_shape<annulus2D, test_algebra>);
0036 
0037   constexpr scalar minR{7.2f * unit<scalar>::mm};
0038   constexpr scalar maxR{12.0f * unit<scalar>::mm};
0039   constexpr scalar minPhi{0.74195f};
0040   constexpr scalar maxPhi{1.33970f};
0041   point3 offset = {-2.f, 2.f, 0.f};
0042 
0043   // points in cartesian module frame
0044   point3 p2_in = {7.f, 7.f, 0.f};
0045   point3 p2_out1 = {5.f, 5.f, 0.f};
0046   point3 p2_out2 = {10.f, 3.f, 0.f};
0047   point3 p2_out3 = {10.f, 10.f, 0.f};
0048   point3 p2_out4 = {4.f, 10.f, 0.f};
0049 
0050   auto toStripFrame = [&offset](const point3 &xy) -> point3 {
0051     auto shifted = xy + offset;
0052     scalar r{vector::perp(shifted)};
0053     scalar phi{vector::phi(shifted)};
0054     return point3{r, phi, static_cast<scalar>(0.f)};
0055   };
0056 
0057   mask<annulus2D, test_algebra> ann2{0u,     minR, maxR,      minPhi,
0058                                      maxPhi, 0.f,  offset[0], offset[1]};
0059 
0060   ASSERT_NEAR(ann2[annulus2D::e_min_r], 7.2f, tol);
0061   ASSERT_NEAR(ann2[annulus2D::e_max_r], 12.0f, tol);
0062   ASSERT_NEAR(ann2[annulus2D::e_min_phi_rel], 0.74195f, tol);
0063   ASSERT_NEAR(ann2[annulus2D::e_max_phi_rel], 1.33970f, tol);
0064   ASSERT_NEAR(ann2[annulus2D::e_shift_x], -2.0f, tol);
0065   ASSERT_NEAR(ann2[annulus2D::e_shift_y], 2.0f, tol);
0066   ASSERT_NEAR(ann2[annulus2D::e_average_phi], 0.f, tol);
0067 
0068   ASSERT_TRUE(ann2.is_inside(toStripFrame(p2_in)));
0069   ASSERT_FALSE(ann2.is_inside(toStripFrame(p2_out1)));
0070   ASSERT_FALSE(ann2.is_inside(toStripFrame(p2_out2)));
0071   ASSERT_FALSE(ann2.is_inside(toStripFrame(p2_out3)));
0072   ASSERT_FALSE(ann2.is_inside(toStripFrame(p2_out4)));
0073   // Move outside point inside using a tolerance
0074   ASSERT_TRUE(ann2.is_inside(toStripFrame(p2_out1), 1.3f));
0075   ASSERT_TRUE(ann2.is_inside(toStripFrame(p2_out4), 0.9f));
0076 
0077   ASSERT_NEAR(
0078       ann2.get_shape().min_dist_to_boundary(ann2.values(), toStripFrame(p2_in)),
0079       2.1005f, tol);
0080   ASSERT_NEAR(ann2.get_shape().min_dist_to_boundary(ann2.values(),
0081                                                     toStripFrame(p2_out1)),
0082               0.128932f, tol);
0083   ASSERT_NEAR(ann2.get_shape().min_dist_to_boundary(ann2.values(),
0084                                                     toStripFrame(p2_out2)),
0085               1.55969f, tol);
0086   ASSERT_NEAR(ann2.get_shape().min_dist_to_boundary(ann2.values(),
0087                                                     toStripFrame(p2_out3)),
0088               2.14214f, tol);
0089   ASSERT_NEAR(ann2.get_shape().min_dist_to_boundary(ann2.values(),
0090                                                     toStripFrame(p2_out4)),
0091               0.80214f, tol);
0092 
0093   // Check area: @TODO not implemented, yet
0094   scalar a = ann2.area();
0095   ASSERT_EQ(a, ann2.measure());
0096 
0097   // Check corner positions
0098   std::array<scalar, 8> c = ann2.get_shape().corners(ann2.values());
0099   for (unsigned int i{0u}; i < 8u; i += 2u) {
0100     // Transform to local cartesian beam system
0101     const scalar loc_x{c[i] * math::cos(c[i + 1]) -
0102                        ann2.values()[annulus2D::e_shift_x]};
0103     const scalar loc_y{c[i] * math::sin(c[i + 1]) -
0104                        ann2.values()[annulus2D::e_shift_y]};
0105 
0106     // Inner points
0107     if (i < 4u) {
0108       EXPECT_NEAR(std::hypot(loc_x, loc_y), minR, tol)
0109           << "point " << i << ": loc_x: " << loc_x << ", loc_y: " << loc_y
0110           << std::endl;
0111     }
0112     // Outer points
0113     else {
0114       EXPECT_NEAR(std::hypot(loc_x, loc_y), maxR, tol)
0115           << "point " << i << ": loc_x: " << loc_x << ", loc_y: " << loc_y
0116           << std::endl;
0117     }
0118   }
0119 
0120   // Check bounding box
0121   constexpr scalar envelope{0.01f};
0122   const auto loc_bounds = ann2.local_min_bounds(envelope);
0123   ASSERT_NEAR(loc_bounds[cuboid3D::e_min_x], 3.8954f - envelope, tol);
0124   ASSERT_NEAR(loc_bounds[cuboid3D::e_min_y], 2.39186f - envelope, tol);
0125   ASSERT_NEAR(loc_bounds[cuboid3D::e_min_z], -envelope, tol);
0126   ASSERT_NEAR(loc_bounds[cuboid3D::e_max_x], 10.50652f + envelope, tol);
0127   ASSERT_NEAR(loc_bounds[cuboid3D::e_max_y], 10.89317f + envelope, tol);
0128   ASSERT_NEAR(loc_bounds[cuboid3D::e_max_z], envelope, tol);
0129 
0130   // TODO: Check centroid against visualization
0131 }
0132 
0133 /// This tests the inside/outside method of the mask
0134 GTEST_TEST(detray_masks, annulus2D_ratio_test) {
0135   struct mask_check {
0136     bool operator()(const point3 &p, const mask<annulus2D, test_algebra> &ann,
0137                     const test::transform3 &trf, const scalar t) {
0138       return ann.is_inside(trf, p, t);
0139     }
0140   };
0141 
0142   constexpr scalar t{0.f};
0143 
0144   constexpr mask<annulus2D, test_algebra> ann{0u,       2.5f, 5.f,  -0.64299f,
0145                                               4.13173f, 1.f,  0.5f, 0.f};
0146   const test::transform3 trf{};
0147 
0148   constexpr scalar world{10.f * unit<scalar>::mm};
0149   const auto n_points{static_cast<std::size_t>(std::pow(500, 3))};
0150 
0151   // x- and y-coordinates yield a valid local position on the underlying plane
0152   std::vector<point3> points =
0153       test::generate_regular_points<cuboid3D>(n_points, {world});
0154 
0155   scalar ratio = test::ratio_test<mask_check>(points, ann, trf, t);
0156 
0157   ASSERT_FALSE(detail::is_invalid_value(ratio));
0158 }