File indexing completed on 2026-05-27 07:24:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "detray/utils/grid/grid_collection.hpp"
0011
0012 #include "detray/definitions/indexing.hpp"
0013 #include "detray/geometry/shapes/cylinder3D.hpp"
0014 #include "detray/utils/grid/grid.hpp"
0015 #include "detray/utils/grid/populators.hpp"
0016 #include "detray/utils/grid/serializers.hpp"
0017
0018
0019 #include "detray/test/framework/types.hpp"
0020
0021
0022 #include <algorithm>
0023 #include <limits>
0024
0025
0026 #include <gtest/gtest.h>
0027
0028 using namespace detray;
0029 using namespace detray::axis;
0030
0031 using test_algebra = test::algebra;
0032 using scalar = test::scalar;
0033
0034 namespace {
0035
0036
0037 bool constexpr is_n_owning = false;
0038
0039 constexpr dindex inf{std::numeric_limits<dindex>::max()};
0040
0041
0042 template <typename populator_t, typename bin_t>
0043 struct bin_content_sequence {
0044 using entry_t = typename bin_t::entry_type;
0045 entry_t entry{0};
0046
0047 auto operator()() {
0048 entry += entry_t{1};
0049 bin_t bin{};
0050 populator_t{}(bin, entry);
0051 return bin;
0052 }
0053 };
0054
0055 }
0056
0057
0058 GTEST_TEST(detray_grid, grid_collection) {
0059
0060 using grid_t =
0061 grid<test_algebra, axes<cylinder3D>, bins::static_array<dindex, 3>,
0062 simple_serializer, host_container_types, is_n_owning>;
0063
0064
0065 grid_t::bin_container_type bin_data{};
0066 bin_data.resize(197u);
0067 std::ranges::generate_n(
0068 bin_data.begin(), 197u,
0069 bin_content_sequence<attach<>, typename grid_t::bin_type>());
0070 dvector<dindex> grid_offsets = {0u, 48u, 72u};
0071
0072
0073 dvector<dsized_index_range> edge_ranges = {{0u, 2u}, {2u, 4u}, {4u, 6u},
0074 {6u, 1u}, {8u, 3u}, {10u, 8u},
0075 {12u, 5u}, {14u, 5u}, {16u, 5u}};
0076
0077
0078 dvector<scalar> bin_edges = {-10.f, 10.f, -20.f, 20.f, 0.f, 120.f,
0079 -5.f, 5.f, -15.f, 15.f, 0.f, 50.f,
0080 -15.f, 15.f, -35.f, 35.f, 0.f, 550.f};
0081
0082
0083 auto grid_coll =
0084 grid_collection<grid_t>(std::move(grid_offsets), std::move(bin_data),
0085 std::move(edge_ranges), std::move(bin_edges));
0086
0087
0088
0089
0090 EXPECT_EQ(grid_coll.size(), 3u);
0091 EXPECT_EQ(grid_coll.bin_storage().size(), 197u);
0092 EXPECT_EQ(grid_coll.axes_storage().size(), 9u);
0093 EXPECT_EQ(grid_coll.bin_edges_storage().size(), 18u);
0094
0095
0096 auto single_grid = grid_coll[1];
0097
0098 static_assert(std::is_same_v<decltype(single_grid), grid_t>,
0099 "Grid from collection has wrong type");
0100
0101 EXPECT_EQ(single_grid.dim, 3);
0102 EXPECT_EQ(single_grid.nbins(), 24u);
0103 auto r_axis = single_grid.get_axis<label::e_r>();
0104 EXPECT_EQ(r_axis.nbins(), 1u);
0105 auto phi_axis = single_grid.get_axis<label::e_phi>();
0106 EXPECT_EQ(phi_axis.nbins(), 3u);
0107 using z_axis_t = single_axis<closed<label::e_z>, regular<scalar>>;
0108 auto z_axis = single_grid.get_axis<z_axis_t>();
0109 EXPECT_EQ(z_axis.nbins(), 8u);
0110
0111
0112 EXPECT_EQ(single_grid.bin(0u, 0u, 0u)[0u], 49u);
0113 EXPECT_EQ(single_grid.bin(0u, 0u, 0u)[1u], inf);
0114 EXPECT_EQ(single_grid.bin(0u, 0u, 0u)[2u], inf);
0115
0116
0117 auto& bin_view = grid_coll[2].bin(101u);
0118 grid_coll[2].template populate<attach<>>(101u, 42u);
0119 EXPECT_EQ(bin_view[0u], 102u + 72u);
0120 EXPECT_EQ(bin_view[1u], 42u);
0121 EXPECT_EQ(bin_view[2u], inf);
0122
0123
0124 auto seq = detray::views::iota(49, 73);
0125 auto flat_bin_view = single_grid.all();
0126 EXPECT_EQ(seq.size(), 24u);
0127 EXPECT_EQ(flat_bin_view.size(), 24u);
0128 EXPECT_TRUE(
0129 std::equal(flat_bin_view.begin(), flat_bin_view.end(), seq.begin()));
0130
0131 auto grid_coll_view = get_data(grid_coll);
0132 static_assert(std::is_same_v<decltype(grid_coll_view),
0133 typename grid_collection<grid_t>::view_type>,
0134 "Grid collection view incorrectly assembled");
0135
0136 const grid_collection<grid_t>& const_coll = grid_coll;
0137 auto const_coll_view = get_data(const_coll);
0138 static_assert(
0139 std::is_same_v<decltype(const_coll_view),
0140 typename grid_collection<grid_t>::const_view_type>,
0141 "Grid collection const view incorrectly assembled");
0142 }
0143
0144
0145
0146 GTEST_TEST(detray_grid, grid_collection_dynamic_bin) {
0147
0148 using grid_t =
0149 grid<test_algebra, axes<cylinder3D>, bins::dynamic_array<dindex>,
0150 simple_serializer, host_container_types, is_n_owning>;
0151
0152
0153 grid_t::bin_container_type bin_data{};
0154 bin_data.bins.resize(197u);
0155 bin_data.entries.resize(4u * 197u);
0156
0157 int i{0};
0158 dindex entry{0u};
0159 dindex offset{0u};
0160 attach<> attacher{};
0161 for (auto& data : bin_data.bins) {
0162 data.offset = offset;
0163
0164 data.capacity = (i % 2) != 0u ? 1u : 3u;
0165
0166 detray::bins::dynamic_array bin{bin_data.entries.data(), data};
0167
0168 ASSERT_TRUE(bin.capacity() == (i % 2 != 0u ? 1u : 3u));
0169 ASSERT_TRUE(bin.size() == 0);
0170
0171 offset += bin.capacity();
0172
0173
0174 attacher(bin, entry);
0175
0176 ASSERT_TRUE(bin.size() == 1);
0177
0178 std::size_t idx{0u};
0179 for (auto e : bin) {
0180 if (idx == 0u) {
0181 ASSERT_TRUE(e == entry);
0182 } else {
0183 ASSERT_TRUE(e == inf);
0184 }
0185 ++idx;
0186 }
0187 ++entry;
0188 ++i;
0189 }
0190
0191 dvector<dindex> grid_offsets = {0u, 48u, 72u};
0192
0193
0194 dvector<dsized_index_range> edge_ranges = {{0u, 2u}, {2u, 4u}, {4u, 6u},
0195 {6u, 1u}, {8u, 3u}, {10u, 8u},
0196 {12u, 5u}, {14u, 5u}, {16u, 5u}};
0197
0198
0199 dvector<scalar> bin_edges = {-10.f, 10.f, -20.f, 20.f, 0.f, 120.f,
0200 -5.f, 5.f, -15.f, 15.f, 0.f, 50.f,
0201 -15.f, 15.f, -35.f, 35.f, 0.f, 550.f};
0202
0203
0204 auto grid_coll =
0205 grid_collection<grid_t>(std::move(grid_offsets), std::move(bin_data),
0206 std::move(edge_ranges), std::move(bin_edges));
0207
0208
0209
0210
0211 EXPECT_EQ(grid_coll.size(), 3u);
0212 EXPECT_EQ(grid_coll.bin_storage().bins.size(), 197u);
0213 EXPECT_EQ(grid_coll.bin_storage().entries.size(), 4u * 197u);
0214 EXPECT_EQ(grid_coll.axes_storage().size(), 9u);
0215 EXPECT_EQ(grid_coll.bin_edges_storage().size(), 18u);
0216
0217
0218 auto single_grid = grid_coll[1];
0219
0220 static_assert(std::is_same_v<decltype(single_grid), grid_t>,
0221 "Grid from collection has wrong type");
0222
0223 EXPECT_EQ(single_grid.dim, 3);
0224 EXPECT_EQ(single_grid.nbins(), 24u);
0225 auto r_axis = single_grid.get_axis<label::e_r>();
0226 EXPECT_EQ(r_axis.nbins(), 1u);
0227 auto phi_axis = single_grid.get_axis<label::e_phi>();
0228 EXPECT_EQ(phi_axis.nbins(), 3u);
0229 using z_axis_t = single_axis<closed<label::e_z>, regular<scalar>>;
0230 auto z_axis = single_grid.get_axis<z_axis_t>();
0231 EXPECT_EQ(z_axis.nbins(), 8u);
0232
0233 auto bin = single_grid.bin(0u, 0u, 0u);
0234 EXPECT_EQ(bin.capacity(), 3u);
0235 EXPECT_EQ(bin.size(), 1u);
0236 EXPECT_EQ(bin[0u], 48u);
0237
0238
0239 EXPECT_EQ(grid_coll[2].nbins(), 125u);
0240 grid_coll[2].template populate<attach<>>(102u, 42u);
0241 auto bin_view = grid_coll[2].bin(102u);
0242 EXPECT_EQ(bin_view.capacity(), 3u);
0243 EXPECT_EQ(bin_view.size(), 2u);
0244 EXPECT_EQ(bin_view[0u], 102u + 72u);
0245 EXPECT_EQ(bin_view[1u], 42u);
0246
0247
0248 auto seq = detray::views::iota(48, 72);
0249 auto flat_bin_view = single_grid.all();
0250 EXPECT_EQ(seq.size(), 24u);
0251 EXPECT_EQ(flat_bin_view.size(), 24u);
0252 EXPECT_TRUE(
0253 std::equal(flat_bin_view.begin(), flat_bin_view.end(), seq.begin()));
0254
0255 auto grid_coll_view = get_data(grid_coll);
0256 static_assert(std::is_same_v<decltype(grid_coll_view),
0257 typename grid_collection<grid_t>::view_type>,
0258 "Grid collection view incorrectly assembled");
0259
0260 const grid_collection<grid_t>& const_coll = grid_coll;
0261 auto const_coll_view = get_data(const_coll);
0262 static_assert(
0263 std::is_same_v<decltype(const_coll_view),
0264 typename grid_collection<grid_t>::const_view_type>,
0265 "Grid collection const view incorrectly assembled");
0266 }