File indexing completed on 2026-09-20 08:23:11
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Utilities/Axis.hpp"
0012 #include "Acts/Utilities/AxisDefinitions.hpp"
0013 #include "Acts/Utilities/Grid.hpp"
0014 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0015
0016 #include <array>
0017 #include <cstddef>
0018 #include <sstream>
0019
0020 using namespace Acts;
0021
0022 namespace ActsTests {
0023
0024
0025
0026
0027
0028
0029
0030
0031 BOOST_AUTO_TEST_SUITE(UtilitiesSuite)
0032
0033 BOOST_AUTO_TEST_CASE(grid_test_1d_equidistant) {
0034 using Point = std::array<double, 1>;
0035 using indices = std::array<std::size_t, 1>;
0036
0037 const Axis a(0.0, 4.0, 4u);
0038 Grid g(Type<double>, a);
0039
0040 BOOST_CHECK_EQUAL(g.size(), 6u);
0041
0042
0043 for (std::size_t bin = 0; bin < g.size(); ++bin) {
0044 g.at(bin) = bin;
0045 }
0046
0047
0048 const Point point{0.7};
0049 const std::size_t globalBin = g.multiAxis().getGlobalBinFromPoint(point);
0050 const indices localBins = g.multiAxis().getLocalBinsFromGlobalBin(globalBin);
0051
0052 BOOST_CHECK_EQUAL(g.atPosition(point), g.at(globalBin));
0053 BOOST_CHECK_EQUAL(g.atPosition(point), g.atLocalBins(localBins));
0054 }
0055
0056 BOOST_AUTO_TEST_CASE(grid_test_2d_equidistant) {
0057 using Point = std::array<double, 2>;
0058 using indices = std::array<std::size_t, 2>;
0059
0060 const Axis a(0.0, 4.0, 4u);
0061 const Axis b(0.0, 3.0, 3u);
0062 Grid g(Type<double>, a, b);
0063
0064 BOOST_CHECK_EQUAL(g.size(), 30u);
0065
0066
0067 for (std::size_t bin = 0; bin < g.size(); ++bin) {
0068 g.at(bin) = bin;
0069 }
0070
0071
0072 const Point point{0.7, 1.3};
0073 const std::size_t globalBin = g.multiAxis().getGlobalBinFromPoint(point);
0074 const indices localBins = g.multiAxis().getLocalBinsFromGlobalBin(globalBin);
0075
0076 BOOST_CHECK_EQUAL(g.atPosition(point), g.at(globalBin));
0077 BOOST_CHECK_EQUAL(g.atPosition(point), g.atLocalBins(localBins));
0078 }
0079
0080 BOOST_AUTO_TEST_CASE(grid_test_3d_equidistant) {
0081 using Point = std::array<double, 3>;
0082 using indices = std::array<std::size_t, 3>;
0083
0084 const Axis a(0.0, 2.0, 2u);
0085 const Axis b(0.0, 3.0, 3u);
0086 const Axis c(0.0, 2.0, 2u);
0087 Grid g(Type<double>, a, b, c);
0088
0089 BOOST_CHECK_EQUAL(g.size(), 80u);
0090
0091
0092 for (std::size_t bin = 0; bin < g.size(); ++bin) {
0093 g.at(bin) = bin;
0094 }
0095
0096
0097 const Point point{0.7, 2.3, 1.3};
0098 const std::size_t globalBin = g.multiAxis().getGlobalBinFromPoint(point);
0099 const indices localBins = g.multiAxis().getLocalBinsFromGlobalBin(globalBin);
0100
0101 BOOST_CHECK_EQUAL(g.atPosition(point), g.at(globalBin));
0102 BOOST_CHECK_EQUAL(g.atPosition(point), g.atLocalBins(localBins));
0103 }
0104
0105 BOOST_AUTO_TEST_CASE(grid_test_1d_variable) {
0106 using Point = std::array<double, 1>;
0107 using indices = std::array<std::size_t, 1>;
0108
0109 const Axis a({0.0, 1.0, 4.0});
0110 Grid g(Type<double>, a);
0111
0112 BOOST_CHECK_EQUAL(g.size(), 4u);
0113
0114
0115 for (std::size_t bin = 0; bin < g.size(); ++bin) {
0116 g.at(bin) = bin;
0117 }
0118
0119
0120 const Point point{0.7};
0121 const std::size_t globalBin = g.multiAxis().getGlobalBinFromPoint(point);
0122 const indices localBins = g.multiAxis().getLocalBinsFromGlobalBin(globalBin);
0123
0124 BOOST_CHECK_EQUAL(g.atPosition(point), g.at(globalBin));
0125 BOOST_CHECK_EQUAL(g.atPosition(point), g.atLocalBins(localBins));
0126 }
0127
0128 BOOST_AUTO_TEST_CASE(grid_test_2d_variable) {
0129 using Point = std::array<double, 2>;
0130 using indices = std::array<std::size_t, 2>;
0131
0132 const Axis a({0.0, 0.5, 3.0});
0133 const Axis b({0.0, 1.0, 4.0});
0134 Grid g(Type<double>, a, b);
0135
0136 BOOST_CHECK_EQUAL(g.size(), 16u);
0137
0138
0139 for (std::size_t bin = 0; bin < g.size(); ++bin) {
0140 g.at(bin) = bin;
0141 }
0142
0143
0144 const Point point{0.7, 1.3};
0145 const std::size_t globalBin = g.multiAxis().getGlobalBinFromPoint(point);
0146 const indices localBins = g.multiAxis().getLocalBinsFromGlobalBin(globalBin);
0147
0148 BOOST_CHECK_EQUAL(g.atPosition(point), g.at(globalBin));
0149 BOOST_CHECK_EQUAL(g.atPosition(point), g.atLocalBins(localBins));
0150 }
0151
0152 BOOST_AUTO_TEST_CASE(grid_test_3d_variable) {
0153 using Point = std::array<double, 3>;
0154 using indices = std::array<std::size_t, 3>;
0155
0156 const Axis a({0.0, 1.0});
0157 const Axis b({0.0, 0.5, 3.0});
0158 const Axis c({0.0, 0.5, 3.0, 3.3});
0159 Grid g(Type<double>, a, b, c);
0160
0161 BOOST_CHECK_EQUAL(g.size(), 60u);
0162
0163
0164 for (std::size_t bin = 0; bin < g.size(); ++bin) {
0165 g.at(bin) = bin;
0166 }
0167
0168
0169 const Point point{0.7, 1.3, 3.7};
0170 const std::size_t globalBin = g.multiAxis().getGlobalBinFromPoint(point);
0171 const indices localBins = g.multiAxis().getLocalBinsFromGlobalBin(globalBin);
0172
0173 BOOST_CHECK_EQUAL(g.atPosition(point), g.at(globalBin));
0174 BOOST_CHECK_EQUAL(g.atPosition(point), g.atLocalBins(localBins));
0175 }
0176
0177 BOOST_AUTO_TEST_CASE(grid_test_2d_mixed) {
0178 using Point = std::array<double, 2>;
0179 using indices = std::array<std::size_t, 2>;
0180
0181 const Axis a(0.0, 1.0, 4u);
0182 const Axis b({0.0, 0.5, 3.0});
0183 Grid g(Type<double>, a, b);
0184
0185 BOOST_CHECK_EQUAL(g.size(), 24u);
0186
0187
0188 for (std::size_t bin = 0; bin < g.size(); ++bin) {
0189 g.at(bin) = bin;
0190 }
0191
0192
0193 const Point point{1.3, 3.7};
0194 const std::size_t globalBin = g.multiAxis().getGlobalBinFromPoint(point);
0195 const indices localBins = g.multiAxis().getLocalBinsFromGlobalBin(globalBin);
0196
0197 BOOST_CHECK_EQUAL(g.atPosition(point), g.at(globalBin));
0198 BOOST_CHECK_EQUAL(g.atPosition(point), g.atLocalBins(localBins));
0199 }
0200
0201 BOOST_AUTO_TEST_CASE(grid_test_2d_mixed_at) {
0202 using Point = std::array<double, 2>;
0203
0204 const Axis a(0.0, 6.0, 4u);
0205 const Axis b({0.0, 1.5, 3.0});
0206 Grid g(Type<double>, a, b);
0207
0208
0209 g.atPosition(Point({{0, 0}})) = 0.;
0210 g.atPosition(Point({{1.5, 0}})) = 1.;
0211 g.atPosition(Point({{3, 0}})) = 2.;
0212 g.atPosition(Point({{4.5, 0}})) = 3.;
0213 g.atPosition(Point({{6, 0}})) = 4.;
0214 g.atPosition(Point({{0, 1.5}})) = 5.;
0215 g.atPosition(Point({{1.5, 1.5}})) = 6.;
0216 g.atPosition(Point({{3, 1.5}})) = 7.;
0217 g.atPosition(Point({{4.5, 1.5}})) = 8.;
0218 g.atPosition(Point({{6, 1.5}})) = 9.;
0219 g.atPosition(Point({{0, 3}})) = 10.;
0220 g.atPosition(Point({{1.5, 3}})) = 11.;
0221 g.atPosition(Point({{3, 3}})) = 12.;
0222 g.atPosition(Point({{4.5, 3}})) = 13.;
0223 g.atPosition(Point({{6, 3}})) = 14.;
0224
0225
0226 BOOST_CHECK_EQUAL(g.size(), 24u);
0227
0228
0229 BOOST_CHECK_EQUAL(g.atPosition(Point({{1.2, 0.3}})), 0.);
0230 BOOST_CHECK_EQUAL(g.atPosition(Point({{2.2, 1.3}})), 1.);
0231 BOOST_CHECK_EQUAL(g.atPosition(Point({{4.9, 1.8}})), 8.);
0232 BOOST_CHECK_EQUAL(g.atPosition(Point({{3.7, 2.1}})), 7.);
0233 BOOST_CHECK_EQUAL(g.atPosition(Point({{0.4, 2.3}})), 5.);
0234 }
0235
0236 BOOST_AUTO_TEST_CASE(grid_interpolation) {
0237 using Point = std::array<double, 3>;
0238
0239 const Axis a(1.0, 3.0, 2u);
0240 const Axis b(1.0, 5.0, 2u);
0241 const Axis c(1.0, 7.0, 2u);
0242 Grid g(Type<double>, a, b, c);
0243
0244 g.atPosition(Point{1., 1., 1.}) = 10.;
0245 g.atPosition(Point{2., 1., 1.}) = 20.;
0246 g.atPosition(Point{1., 3., 1.}) = 30.;
0247 g.atPosition(Point{2., 3., 1.}) = 40.;
0248 g.atPosition(Point{1., 1., 4.}) = 50.;
0249 g.atPosition(Point{2., 1., 4.}) = 60.;
0250 g.atPosition(Point{1., 3., 4.}) = 70.;
0251 g.atPosition(Point{2., 3., 4.}) = 80.;
0252
0253 CHECK_CLOSE_REL(g.interpolate(Point{1., 1., 1.}), 10., 1e-6);
0254 CHECK_CLOSE_REL(g.interpolate(Point{2., 1., 1.}), 20., 1e-6);
0255 CHECK_CLOSE_REL(g.interpolate(Point{1., 3., 1.}), 30., 1e-6);
0256 CHECK_CLOSE_REL(g.interpolate(Point{2., 3., 1.}), 40., 1e-6);
0257 CHECK_CLOSE_REL(g.interpolate(Point{1., 1., 4.}), 50., 1e-6);
0258 CHECK_CLOSE_REL(g.interpolate(Point{2., 1., 4.}), 60., 1e-6);
0259 CHECK_CLOSE_REL(g.interpolate(Point{1., 3., 4.}), 70., 1e-6);
0260 CHECK_CLOSE_REL(g.interpolate(Point{2., 3., 4.}), 80., 1e-6);
0261 CHECK_CLOSE_REL(g.interpolate(Point{1.5, 1., 1.}), 15., 1e-6);
0262 CHECK_CLOSE_REL(g.interpolate(Point{1.5, 3., 1.}), 35., 1e-6);
0263 CHECK_CLOSE_REL(g.interpolate(Point{1., 2., 1.}), 20., 1e-6);
0264 CHECK_CLOSE_REL(g.interpolate(Point{2., 2., 1.}), 30., 1e-6);
0265 CHECK_CLOSE_REL(g.interpolate(Point{1.5, 1., 4.}), 55., 1e-6);
0266 CHECK_CLOSE_REL(g.interpolate(Point{1.5, 3., 4.}), 75., 1e-6);
0267 CHECK_CLOSE_REL(g.interpolate(Point{1., 2., 4.}), 60., 1e-6);
0268 CHECK_CLOSE_REL(g.interpolate(Point{2., 2., 4.}), 70., 1e-6);
0269 CHECK_CLOSE_REL(g.interpolate(Point{1., 1., 2.5}), 30., 1e-6);
0270 CHECK_CLOSE_REL(g.interpolate(Point{1., 3., 2.5}), 50., 1e-6);
0271 CHECK_CLOSE_REL(g.interpolate(Point{2., 1., 2.5}), 40., 1e-6);
0272 CHECK_CLOSE_REL(g.interpolate(Point{2., 3., 2.5}), 60., 1e-6);
0273 CHECK_CLOSE_REL(g.interpolate(Point{1.5, 2., 2.5}), 360. / 8, 1e-6);
0274 CHECK_CLOSE_REL(g.interpolate(Point{1.3, 2.1, 1.6}), 32., 1e-6);
0275 CHECK_CLOSE_REL(g.interpolate(Point{2., 3., 4.}), 80., 1e-6);
0276 }
0277
0278 BOOST_AUTO_TEST_CASE(grid_type_conversion) {
0279
0280 using Grid2Int =
0281 Grid<int, Axis<AxisType::Equidistant>, Axis<AxisType::Variable>>;
0282
0283 const Axis a(0.0, 1.0, 10u);
0284 const Axis b({0., 1.2, 2.3, 3.4, 4.5, 5.6});
0285 const Grid g2(Type<double>, a, b);
0286 const decltype(g2) g2Copy(g2.multiAxis().getAxesTuple());
0287
0288 static_assert(std::same_as<decltype(g2), decltype(g2Copy)>);
0289
0290 auto g2ConvertedInt = g2Copy.convertType<int>();
0291 static_assert(std::same_as<decltype(g2ConvertedInt), Grid2Int>);
0292 }
0293
0294 BOOST_AUTO_TEST_CASE(grid_full_conversion) {
0295
0296 struct DoubleToInt {
0297
0298 using value_type = int;
0299
0300 int operator()(double d) { return static_cast<int>(d); }
0301 };
0302
0303
0304 const Axis a(0.0, 1.0, 2u);
0305 Grid g1(Type<double>, a);
0306
0307 using Point = std::array<double, 1>;
0308 g1.atPosition(Point{0.3}) = 1.1;
0309 g1.atPosition(Point{0.6}) = 2.4;
0310
0311 DoubleToInt d2i;
0312
0313 auto g1ConvertedInt = g1.convertGrid(d2i);
0314 BOOST_CHECK_EQUAL(g1ConvertedInt.atPosition(Point{0.3}), 1);
0315 BOOST_CHECK_EQUAL(g1ConvertedInt.atPosition(Point{0.6}), 2);
0316 }
0317
0318 BOOST_AUTO_TEST_CASE(Output) {
0319 const Axis a{AxisOpen, 0.0, 1.0, 10u};
0320 const Axis b{AxisBound, {1, 2, 3}};
0321
0322 const Grid g(Type<double>, a, b);
0323
0324 std::stringstream ss;
0325 ss << g;
0326 BOOST_CHECK_EQUAL(ss.str(),
0327 "Axis<Equidistant, Open>(0, 1, 10, Undefined), "
0328 "Axis<Variable, Bound>({1, 2, 3}, Undefined)");
0329
0330 const IGrid& ig = g;
0331
0332 ss.str("");
0333
0334 ss << ig;
0335
0336 BOOST_CHECK_EQUAL(ss.str(),
0337 "Axis<Equidistant, Open>(0, 1, 10, Undefined), "
0338 "Axis<Variable, Bound>({1, 2, 3}, Undefined)");
0339 }
0340
0341 BOOST_AUTO_TEST_CASE(Equality) {
0342 const Axis a{AxisOpen, 0.0, 1.0, 10u};
0343 const Axis b{AxisBound, {1, 2, 3}};
0344 const Axis c{AxisClosed, {1, 2, 5}};
0345
0346 const Grid ab{Type<double>, a, b};
0347 const Grid ac{Type<double>, a, c};
0348
0349 BOOST_CHECK_EQUAL(ab, ab);
0350 BOOST_CHECK_EQUAL(ac, ac);
0351 BOOST_CHECK_NE(ab, ac);
0352
0353 const IGrid& iab = ab;
0354 const IGrid& iac = ac;
0355
0356 BOOST_CHECK_EQUAL(iab, iab);
0357 BOOST_CHECK_EQUAL(iac, iac);
0358 }
0359
0360 BOOST_AUTO_TEST_SUITE_END()
0361
0362 }