Back to home page

EIC code displayed by LXR

 
 

    


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

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/utils/bounding_volume.hpp"
0011 
0012 #include "detray/definitions/units.hpp"
0013 #include "detray/geometry/mask.hpp"
0014 #include "detray/geometry/shapes.hpp"
0015 
0016 // Detray test include(s)
0017 #include "detray/test/framework/types.hpp"
0018 
0019 // Google test include(s).
0020 #include <gtest/gtest.h>
0021 
0022 using namespace detray;
0023 
0024 using test_algebra = test::algebra;
0025 using scalar = test::scalar;
0026 using point3 = test::point3;
0027 using vector3 = test::vector3;
0028 using transform3 = test::transform3;
0029 
0030 namespace {
0031 
0032 // envelope around wrapped object (scalor in percent)
0033 constexpr scalar envelope{0.01f};
0034 
0035 // test tolerance
0036 constexpr scalar tol{1e-5f};
0037 
0038 }  // anonymous namespace
0039 
0040 /// This tests the basic functionality cuboid axis aligned bounding box
0041 GTEST_TEST(detray_utils, bounding_cuboid3D) {
0042   // cuboid
0043   constexpr scalar hx{1.f * unit<scalar>::mm};
0044   constexpr scalar hy{9.3f * unit<scalar>::mm};
0045   constexpr scalar hz{0.5f * unit<scalar>::mm};
0046 
0047   point3 p2_in = {0.5f, 8.0f, -0.4f};
0048   point3 p2_edge = {1.f, 9.3f, 0.5f};
0049   point3 p2_out = {1.5f, -9.f, 0.55f};
0050 
0051   mask<cuboid3D, test_algebra> c3{0u, -hx, -hy, -hz, hx, hy, hz};
0052 
0053   axis_aligned_bounding_volume<cuboid3D, test_algebra> aabb{c3, 0u, envelope};
0054 
0055   // Id of this instance
0056   ASSERT_EQ(aabb.id(), 0u);
0057 
0058   // Test the bounds
0059   const auto bounds = aabb.bounds();
0060   ASSERT_NEAR(bounds[cuboid3D::e_min_x], -hx - envelope, tol);
0061   ASSERT_NEAR(bounds[cuboid3D::e_min_y], -hy - envelope, tol);
0062   ASSERT_NEAR(bounds[cuboid3D::e_min_z], -hz - envelope, tol);
0063   ASSERT_NEAR(bounds[cuboid3D::e_max_x], hx + envelope, tol);
0064   ASSERT_NEAR(bounds[cuboid3D::e_max_y], hy + envelope, tol);
0065   ASSERT_NEAR(bounds[cuboid3D::e_max_z], hz + envelope, tol);
0066 
0067   ASSERT_TRUE(aabb.is_inside(p2_in));
0068   ASSERT_TRUE(aabb.is_inside(p2_edge));
0069   ASSERT_FALSE(aabb.is_inside(p2_out));
0070   // Move outside point inside using a tolerance
0071   ASSERT_TRUE(aabb.is_inside(p2_out, 1.f));
0072 }
0073 
0074 /// This tests the basic functionality cylindrical axis aligned bounding box
0075 GTEST_TEST(detray_utils, bounding_cylinder3D) {
0076   // cylinder
0077   constexpr scalar r{3.f * unit<scalar>::mm};
0078   constexpr scalar hz{4.f * unit<scalar>::mm};
0079 
0080   point3 p3_in = {r, static_cast<scalar>(0.f), static_cast<scalar>(-1.f)};
0081   point3 p3_edge = {static_cast<scalar>(0.f), r, hz};
0082   point3 p3_out = {r * constant<scalar>::inv_sqrt2,
0083                    r * constant<scalar>::inv_sqrt2, static_cast<scalar>(4.5f)};
0084   point3 p3_off = {1.f, 1.f, -9.f};
0085 
0086   axis_aligned_bounding_volume<cylinder3D, test_algebra> aabc{
0087       0u, 0.f, -constant<scalar>::pi, -hz, r, constant<scalar>::pi, hz};
0088 
0089   // Id of this instance
0090   ASSERT_EQ(aabc.id(), 0u);
0091 
0092   // Test the bounds
0093   const auto bounds = aabc.bounds();
0094   ASSERT_NEAR(bounds[cylinder3D::e_min_r], 0.f, tol);
0095   ASSERT_NEAR(bounds[cylinder3D::e_max_r], r, tol);
0096   ASSERT_NEAR(bounds[cylinder3D::e_min_phi], -constant<scalar>::pi, tol);
0097   ASSERT_NEAR(bounds[cylinder3D::e_max_phi], constant<scalar>::pi, tol);
0098   ASSERT_NEAR(bounds[cylinder3D::e_min_z], -hz, tol);
0099   ASSERT_NEAR(bounds[cylinder3D::e_max_z], hz, tol);
0100 
0101   ASSERT_TRUE(aabc.is_inside(p3_in));
0102   ASSERT_TRUE(aabc.is_inside(p3_edge));
0103   ASSERT_FALSE(aabc.is_inside(p3_out));
0104   ASSERT_FALSE(aabc.is_inside(p3_off));
0105   // Move outside point inside using a tolerance
0106   ASSERT_TRUE(aabc.is_inside(p3_out, 0.6f));
0107 }
0108 
0109 /// This tests the basic functionality of an aabb around a stereo annulus
0110 GTEST_TEST(detray_utils, annulus2D_aabb) {
0111   constexpr scalar minR{7.2f * unit<scalar>::mm};
0112   constexpr scalar maxR{12.0f * unit<scalar>::mm};
0113   constexpr scalar minPhi{0.74195f};
0114   constexpr scalar maxPhi{1.33970f};
0115   typename transform3::point2 offset = {-2.f, 2.f};
0116 
0117   mask<annulus2D, test_algebra> ann2{0u,     minR, maxR,      minPhi,
0118                                      maxPhi, 0.f,  offset[0], offset[1]};
0119 
0120   // Construct local aabb around mask
0121   axis_aligned_bounding_volume<cuboid3D, test_algebra> aabb{ann2, 0u, envelope};
0122 
0123   // rotate around z-axis by 90deg and then translate by 1mm in each direction
0124   const vector3 new_x{0.f, -1.f, 0.f};
0125   const vector3 new_z{0.f, 0.f, 1.f};
0126   const vector3 t{1.f, 2.f, 3.f};
0127   const transform3 trf{t, new_z, new_x};
0128 
0129   const auto glob_aabb = aabb.transform(trf);
0130   ASSERT_NEAR(glob_aabb[cuboid3D::e_min_x], 2.39186f - envelope + t[0], tol);
0131   ASSERT_NEAR(glob_aabb[cuboid3D::e_min_y], -10.50652f - envelope + t[1], tol);
0132   ASSERT_NEAR(glob_aabb[cuboid3D::e_min_z], -envelope + t[2], tol);
0133   ASSERT_NEAR(glob_aabb[cuboid3D::e_max_x], 10.89317f + envelope + t[0], tol);
0134   ASSERT_NEAR(glob_aabb[cuboid3D::e_max_y], -3.8954f + envelope + t[1], tol);
0135   ASSERT_NEAR(glob_aabb[cuboid3D::e_max_z], envelope + t[2], tol);
0136 }
0137 
0138 /// This tests the basic functionality of an aabb around a cylinder
0139 GTEST_TEST(detray_utils, cylinder2D_aabb) {
0140   constexpr scalar r{3.f * unit<scalar>::mm};
0141   constexpr scalar hz{4.f * unit<scalar>::mm};
0142 
0143   mask<cylinder2D, test_algebra> c{0u, r, -hz, hz};
0144 
0145   // Construct local aabb around mask
0146   axis_aligned_bounding_volume<cuboid3D, test_algebra> aabb{c, 0u, envelope};
0147 
0148   // rotate around z-axis by 90deg and then translate by 1mm in each direction
0149   const vector3 new_x{0.f, -1.f, 0.f};
0150   const vector3 new_z{0.f, 0.f, 1.f};
0151   const vector3 t{1.f, 2.f, 3.f};
0152   const transform3 trf{t, new_z, new_x};
0153 
0154   const auto glob_aabb = aabb.transform(trf);
0155   ASSERT_NEAR(glob_aabb[cuboid3D::e_min_x], -(r + envelope) + t[0], tol);
0156   ASSERT_NEAR(glob_aabb[cuboid3D::e_min_y], -(r + envelope) + t[1], tol);
0157   ASSERT_NEAR(glob_aabb[cuboid3D::e_min_z], -(hz + envelope) + t[2], tol);
0158   ASSERT_NEAR(glob_aabb[cuboid3D::e_max_x], (r + envelope) + t[0], tol);
0159   ASSERT_NEAR(glob_aabb[cuboid3D::e_max_y], (r + envelope) + t[1], tol);
0160   ASSERT_NEAR(glob_aabb[cuboid3D::e_max_z], (hz + envelope) + t[2], tol);
0161 }
0162 
0163 /// This tests the basic functionality of an aabb around a line
0164 GTEST_TEST(detray_utils, line2D_aabb) {
0165   constexpr scalar cell_size{1.f * unit<scalar>::mm};
0166   constexpr scalar hz{50.f * unit<scalar>::mm};
0167 
0168   const mask<line_circular, test_algebra> ln_r{0u, cell_size, hz};
0169   const mask<line_square, test_algebra> ln_sq{0u, cell_size, hz};
0170 
0171   // Construct local aabb around mask
0172   axis_aligned_bounding_volume<cuboid3D, test_algebra> aabb_r{ln_r, 0u,
0173                                                               envelope};
0174   axis_aligned_bounding_volume<cuboid3D, test_algebra> aabb_sq{ln_sq, 0u,
0175                                                                envelope};
0176 
0177   // rotate around z-axis by 90deg and then translate by 1mm in each direction
0178   const vector3 new_x{0.f, -1.f, 0.f};
0179   const vector3 new_z{0.f, 0.f, 1.f};
0180   const vector3 t{1.f, 2.f, 3.f};
0181   const transform3 trf{t, new_z, new_x};
0182 
0183   // Radial crossection
0184   const auto glob_aabb_r = aabb_r.transform(trf);
0185   ASSERT_NEAR(glob_aabb_r[cuboid3D::e_min_x], -(cell_size + envelope) + t[0],
0186               tol);
0187   ASSERT_NEAR(glob_aabb_r[cuboid3D::e_min_y], -(cell_size + envelope) + t[1],
0188               tol);
0189   ASSERT_NEAR(glob_aabb_r[cuboid3D::e_min_z], -(hz + envelope) + t[2], tol);
0190   ASSERT_NEAR(glob_aabb_r[cuboid3D::e_max_x], (cell_size + envelope) + t[0],
0191               tol);
0192   ASSERT_NEAR(glob_aabb_r[cuboid3D::e_max_y], (cell_size + envelope) + t[1],
0193               tol);
0194   ASSERT_NEAR(glob_aabb_r[cuboid3D::e_max_z], (hz + envelope) + t[2], tol);
0195 
0196   // Square crossection
0197   const auto glob_aabb_sq = aabb_sq.transform(trf);
0198   ASSERT_NEAR(glob_aabb_sq[cuboid3D::e_min_x], -(cell_size + envelope) + t[0],
0199               tol);
0200   ASSERT_NEAR(glob_aabb_sq[cuboid3D::e_min_y], -(cell_size + envelope) + t[1],
0201               tol);
0202   ASSERT_NEAR(glob_aabb_sq[cuboid3D::e_min_z], -(hz + envelope) + t[2], tol);
0203   ASSERT_NEAR(glob_aabb_sq[cuboid3D::e_max_x], (cell_size + envelope) + t[0],
0204               tol);
0205   ASSERT_NEAR(glob_aabb_sq[cuboid3D::e_max_y], (cell_size + envelope) + t[1],
0206               tol);
0207   ASSERT_NEAR(glob_aabb_sq[cuboid3D::e_max_z], (hz + envelope) + t[2], tol);
0208 }
0209 
0210 /// This tests the basic functionality of an aabb around a rectangle
0211 GTEST_TEST(detray_utils, rectangle2D_aabb) {
0212   constexpr scalar hx{1.f * unit<scalar>::mm};
0213   constexpr scalar hy{9.3f * unit<scalar>::mm};
0214 
0215   mask<rectangle2D, test_algebra> r2{0u, hx, hy};
0216 
0217   // Construct local aabb around mask
0218   axis_aligned_bounding_volume<cuboid3D, test_algebra> aabb{r2, 0u, envelope};
0219 
0220   // rotate around z-axis by 90deg and then translate by 1mm in each direction
0221   const vector3 new_x{0.f, -1.f, 0.f};
0222   const vector3 new_z{0.f, 0.f, 1.f};
0223   const vector3 t{1.f, 2.f, 3.f};
0224   const transform3 trf{t, new_z, new_x};
0225 
0226   const auto glob_aabb = aabb.transform(trf);
0227   ASSERT_NEAR(glob_aabb[cuboid3D::e_min_x], -(hy + envelope) + t[0], tol);
0228   ASSERT_NEAR(glob_aabb[cuboid3D::e_min_y], -(hx + envelope) + t[1], tol);
0229   ASSERT_NEAR(glob_aabb[cuboid3D::e_min_z], -(envelope) + t[2], tol);
0230   ASSERT_NEAR(glob_aabb[cuboid3D::e_max_x], (hy + envelope) + t[0], tol);
0231   ASSERT_NEAR(glob_aabb[cuboid3D::e_max_y], (hx + envelope) + t[1], tol);
0232   ASSERT_NEAR(glob_aabb[cuboid3D::e_max_z], (envelope) + t[2], tol);
0233 }
0234 
0235 /// This tests the basic functionality of an aabb around a rectangle
0236 GTEST_TEST(detray_utils, ring2D_aabb) {
0237   constexpr scalar inner_r{0.f * unit<scalar>::mm};
0238   constexpr scalar outer_r{3.5f * unit<scalar>::mm};
0239 
0240   mask<ring2D, test_algebra> r2{0u, inner_r, outer_r};
0241 
0242   // Construct local aabb around mask
0243   axis_aligned_bounding_volume<cuboid3D, test_algebra> aabb{r2, 0u, envelope};
0244 
0245   // rotate around z-axis by 90deg and then translate by 1mm in each direction
0246   const vector3 new_x{0.f, -1.f, 0.f};
0247   const vector3 new_z{0.f, 0.f, 1.f};
0248   const vector3 t{1.f, 2.f, 3.f};
0249   const transform3 trf{t, new_z, new_x};
0250 
0251   const auto glob_aabb = aabb.transform(trf);
0252   ASSERT_NEAR(glob_aabb[cuboid3D::e_min_x], -(outer_r + envelope) + t[0], tol);
0253   ASSERT_NEAR(glob_aabb[cuboid3D::e_min_y], -(outer_r + envelope) + t[1], tol);
0254   ASSERT_NEAR(glob_aabb[cuboid3D::e_min_z], -(envelope) + t[2], tol);
0255   ASSERT_NEAR(glob_aabb[cuboid3D::e_max_x], (outer_r + envelope) + t[0], tol);
0256   ASSERT_NEAR(glob_aabb[cuboid3D::e_max_y], (outer_r + envelope) + t[1], tol);
0257   ASSERT_NEAR(glob_aabb[cuboid3D::e_max_z], (envelope) + t[2], tol);
0258 }
0259 
0260 /// This tests the basic functionality of an aabb around a rectangle
0261 GTEST_TEST(detray_utils, trapezoid2D_aabb) {
0262   constexpr scalar hx_miny{1.f * unit<scalar>::mm};
0263   constexpr scalar hx_maxy{3.f * unit<scalar>::mm};
0264   constexpr scalar hy{2.f * unit<scalar>::mm};
0265   constexpr scalar divisor{1.f / (2.f * hy)};
0266 
0267   mask<trapezoid2D, test_algebra> t2{0u, hx_miny, hx_maxy, hy, divisor};
0268 
0269   // Construct local aabb around mask
0270   axis_aligned_bounding_volume<cuboid3D, test_algebra> aabb{t2, 0u, envelope};
0271 
0272   // rotate around z-axis by 90deg and then translate by 1mm in each direction
0273   const vector3 new_x{0.f, -1.f, 0.f};
0274   const vector3 new_z{0.f, 0.f, 1.f};
0275   const vector3 t{1.f, 2.f, 3.f};
0276   const transform3 trf{t, new_z, new_x};
0277 
0278   const auto glob_aabb = aabb.transform(trf);
0279   ASSERT_NEAR(glob_aabb[cuboid3D::e_min_x], -(hy + envelope) + t[0], tol);
0280   ASSERT_NEAR(glob_aabb[cuboid3D::e_min_y], -(hx_maxy + envelope) + t[1], tol);
0281   ASSERT_NEAR(glob_aabb[cuboid3D::e_min_z], -envelope + t[2], tol);
0282   ASSERT_NEAR(glob_aabb[cuboid3D::e_max_x], (hy + envelope) + t[0], tol);
0283   ASSERT_NEAR(glob_aabb[cuboid3D::e_max_y], (hx_maxy + envelope) + t[1], tol);
0284   ASSERT_NEAR(glob_aabb[cuboid3D::e_max_z], envelope + t[2], tol);
0285 }
0286 
0287 /// This tests wrapping a collection of cuboid bounding volumes
0288 GTEST_TEST(detray_utils, wrap_bounding_cuboid3D) {
0289   using box_t = axis_aligned_bounding_volume<cuboid3D, test_algebra>;
0290 
0291   box_t b1{0u, -1.f, 0.f, -10.f, -0.5f, 1.f, 0.f};
0292   box_t b2{0u, -2.f, 3.f, 2.f, 2.f, 4.5f, 3.5f};
0293   box_t b3{0u, -1.5f, -0.1f, -2.f, 0.f, 0.1f, 2.f};
0294   box_t b4{0u, 0.f, 0.f, 0.f, 2.f, 2.f, 10.f};
0295 
0296   std::vector<box_t> boxes = {b1, b2, b3, b4};
0297 
0298   box_t aabb{boxes, 0u, envelope};
0299 
0300   // Id of this instance
0301   ASSERT_EQ(aabb.id(), 0u);
0302 
0303   // Test the bounds
0304   const auto bounds = aabb.bounds();
0305   ASSERT_NEAR(bounds[cuboid3D::e_min_x], -2.f - envelope, tol);
0306   ASSERT_NEAR(bounds[cuboid3D::e_min_y], -0.1f - envelope, tol);
0307   ASSERT_NEAR(bounds[cuboid3D::e_min_z], -10.f - envelope, tol);
0308   ASSERT_NEAR(bounds[cuboid3D::e_max_x], 2.f + envelope, tol);
0309   ASSERT_NEAR(bounds[cuboid3D::e_max_y], 4.5f + envelope, tol);
0310   ASSERT_NEAR(bounds[cuboid3D::e_max_z], 10.f + envelope, tol);
0311 }