Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-20 08:23:11

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 #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 // The binning geometry of the underlying multi-axis (bin lookups, bin edges,
0025 // neighborhoods, closest points, ...) is exercised in `MultiAxisTests.cpp`.
0026 // These tests focus on the behaviour that `Grid` adds on top of its
0027 // multi-axis: value storage and access (`at`, `atPosition`, `atLocalBins`),
0028 // interpolation, type conversion and the `IGrid` interface. Consistency of the
0029 // different value accessors is cross-checked through `grid.multiAxis()`.
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   // initialize grid
0043   for (std::size_t bin = 0; bin < g.size(); ++bin) {
0044     g.at(bin) = bin;
0045   }
0046 
0047   // consistency of access
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   // initialize grid
0067   for (std::size_t bin = 0; bin < g.size(); ++bin) {
0068     g.at(bin) = bin;
0069   }
0070 
0071   // consistency of access
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   // initialize grid
0092   for (std::size_t bin = 0; bin < g.size(); ++bin) {
0093     g.at(bin) = bin;
0094   }
0095 
0096   // consistency of access
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   // initialize grid
0115   for (std::size_t bin = 0; bin < g.size(); ++bin) {
0116     g.at(bin) = bin;
0117   }
0118 
0119   // consistency of access
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   // initialize grid
0139   for (std::size_t bin = 0; bin < g.size(); ++bin) {
0140     g.at(bin) = bin;
0141   }
0142 
0143   // consistency of access
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   // initialize grid
0164   for (std::size_t bin = 0; bin < g.size(); ++bin) {
0165     g.at(bin) = bin;
0166   }
0167 
0168   // consistency of access
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   // initialize grid
0188   for (std::size_t bin = 0; bin < g.size(); ++bin) {
0189     g.at(bin) = bin;
0190   }
0191 
0192   // consistency of access
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   // initialize the grid
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   // test general properties
0226   BOOST_CHECK_EQUAL(g.size(), 24u);
0227 
0228   // test some arbitrary points
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   // Type conversion test
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   // The converter class
0296   struct DoubleToInt {
0297     // Declare a value type
0298     using value_type = int;
0299     // the conversion operator
0300     int operator()(double d) { return static_cast<int>(d); }
0301   };
0302 
0303   // Grid conversion test
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 }  // namespace ActsTests