File indexing completed on 2026-05-27 07:24:21
0001
0002
0003
0004
0005
0006
0007
0008
0009
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
0017 #include "detray/test/framework/types.hpp"
0018 #include "detray/test/utils/ratio_test.hpp"
0019
0020
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
0034 constexpr scalar cell_size{1.f * unit<scalar>::mm};
0035 constexpr scalar hz{50.f * unit<scalar>::mm};
0036
0037 }
0038
0039
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
0060 EXPECT_NEAR(ln.area(), 628.318531f * unit<scalar>::mm2, tol);
0061 EXPECT_NEAR(ln.measure(), 314.159265359f * unit<scalar>::mm3, tol);
0062
0063
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
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 & ,
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
0095
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
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
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
0135 EXPECT_NEAR(ln.area(), 800.f * unit<scalar>::mm2, tol);
0136 EXPECT_NEAR(ln.measure(), 400.f * unit<scalar>::mm3, tol);
0137
0138
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
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 & ,
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
0169
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 }