File indexing completed on 2026-05-27 07:24:14
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012 #include "detray/geometry/shapes/cuboid3D.hpp"
0013 #include "detray/geometry/shapes/cylinder2D.hpp"
0014
0015
0016 #include "detray/test/framework/types.hpp"
0017
0018
0019 #include <atomic>
0020 #include <random>
0021 #include <vector>
0022
0023 namespace detray::test {
0024
0025 template <typename shape_t>
0026 inline std::vector<point3> generate_regular_points(
0027 const std::size_t , const std::vector<scalar> & );
0028
0029
0030
0031 template <>
0032 inline std::vector<point3> generate_regular_points<cuboid3D>(
0033 const std::size_t n_points, const std::vector<scalar> &world) {
0034 const std::size_t n_steps{static_cast<std::size_t>(std::cbrt(n_points))};
0035
0036 const scalar world_x{world.at(0)};
0037 const scalar world_y{(world.size() > 1 ? world[1] : world[0])};
0038 const scalar world_z{(world.size() > 2 ? world[2] : world[0])};
0039 const scalar dx{world_x / static_cast<scalar>(n_steps)};
0040 const scalar dy{world_y / static_cast<scalar>(n_steps)};
0041 const scalar dz{world_z / static_cast<scalar>(n_steps)};
0042
0043 std::vector<point3> points{};
0044 points.reserve(n_points);
0045
0046 for (std::size_t ix = 0u; ix < n_steps; ++ix) {
0047 scalar x{-0.5f * world_x + static_cast<scalar>(ix) * dx};
0048
0049 for (std::size_t iy = 0u; iy < n_steps; ++iy) {
0050 scalar y{-0.5f * world_y + static_cast<scalar>(iy) * dy};
0051
0052 for (std::size_t iz = 0u; iz < n_steps; ++iz) {
0053 scalar z{-0.5f * world_z + static_cast<scalar>(iz) * dz};
0054
0055 points.push_back({x, y, z});
0056 }
0057 }
0058 }
0059
0060 return points;
0061 }
0062
0063
0064
0065 template <>
0066 inline std::vector<point3> generate_regular_points<cylinder2D>(
0067 const std::size_t n_points, const std::vector<scalar> &world) {
0068 const std::size_t n_steps{static_cast<std::size_t>(std::sqrt(n_points))};
0069
0070 const scalar world_r{world.at(0)};
0071 const scalar world_z{world.at(1)};
0072 const scalar dphi{2.f * constant<scalar>::pi / static_cast<scalar>(n_steps)};
0073 const scalar dz{world_z / static_cast<scalar>(n_steps)};
0074
0075 std::vector<point3> points{};
0076 points.reserve(n_points);
0077
0078 for (std::size_t iphi = 0u; iphi < n_steps; ++iphi) {
0079 scalar phi{-constant<scalar>::pi + static_cast<scalar>(iphi) * dphi};
0080
0081 for (std::size_t iz = 0u; iz < n_steps; ++iz) {
0082 scalar z{-0.5f * world_z + static_cast<scalar>(iz) * dz};
0083
0084 points.push_back({world_r * std::cos(phi), world_r * std::sin(phi), z});
0085 }
0086 }
0087
0088 return points;
0089 }
0090
0091
0092 inline std::vector<point3> generate_random_points(
0093 const scalar world, const std::size_t n_points,
0094 const std::uint32_t seed = std::mt19937::default_seed) {
0095 std::vector<point3> points{};
0096 points.reserve(n_points);
0097
0098 std::random_device rd;
0099 std::mt19937 mt(rd());
0100 mt.seed(seed);
0101 std::uniform_real_distribution<scalar> dist(-0.5f * world, 0.5f * world);
0102
0103 for (std::size_t i = 0u; i < n_points; ++i) {
0104 points.push_back({dist(mt), dist(mt), dist(mt)});
0105 }
0106
0107 return points;
0108 }
0109
0110
0111 template <typename predicate_t, typename... Args>
0112 inline scalar ratio_test(const std::vector<point3> &points, Args... args) {
0113 std::atomic_ulong yes = 0u;
0114
0115 for (const auto &p : points) {
0116 if (predicate_t{}(p, std::forward<Args>(args)...)) {
0117 ++yes;
0118 }
0119 }
0120
0121 return static_cast<scalar>(yes) / static_cast<scalar>(points.size());
0122 }
0123
0124 }