Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-11 08:09:31

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/AnyGridView.hpp"
0012 #include "Acts/Utilities/Axis.hpp"
0013 #include "Acts/Utilities/AxisDefinitions.hpp"
0014 #include "Acts/Utilities/Grid.hpp"
0015 #include "Acts/Utilities/TypeTraits.hpp"
0016 
0017 #include <stdexcept>
0018 #include <string>
0019 #include <utility>
0020 #include <vector>
0021 
0022 using namespace Acts;
0023 
0024 namespace ActsTests {
0025 
0026 BOOST_AUTO_TEST_SUITE(UtilitiesSuite)
0027 
0028 // Helper function to create a 1D grid with int values
0029 auto createIntGrid1D() {
0030   Axis a(0.0, 4.0, 4u);
0031   Grid g(Type<int>, a);
0032 
0033   // Fill with values
0034   for (std::size_t i = 0; i < g.size(); i++) {
0035     g.at(i) = static_cast<int>(i * 10);
0036   }
0037 
0038   return g;
0039 }
0040 
0041 // Helper function to create a 2D grid with double values
0042 auto createDoubleGrid2D() {
0043   Axis a(0.0, 4.0, 4u);
0044   Axis b(0.0, 6.0, 3u);
0045   Grid g(Type<double>, std::move(a), std::move(b));
0046 
0047   // Fill with values
0048   for (std::size_t i = 0; i < g.size(); i++) {
0049     g.at(i) = static_cast<double>(i) * 1.5;
0050   }
0051 
0052   return g;
0053 }
0054 
0055 // Helper function to create a 2D grid with string values
0056 auto createStringGrid2D() {
0057   Axis a(0.0, 4.0, 4u);
0058   Axis b(0.0, 6.0, 3u);
0059   Grid g(Type<std::string>, std::move(a), std::move(b));
0060 
0061   // Fill with values
0062   for (std::size_t i = 0; i < g.size(); i++) {
0063     g.at(i) = "Value_" + std::to_string(i);
0064   }
0065 
0066   return g;
0067 }
0068 
0069 // Helper function to create a 3D grid with vector values
0070 auto createVectorGrid3D() {
0071   Axis a(0.0, 4.0, 2u);
0072   Axis b(0.0, 6.0, 2u);
0073   Axis c(0.0, 8.0, 2u);
0074   Grid g(Type<std::vector<float>>, std::move(a), std::move(b), std::move(c));
0075 
0076   // Fill with values
0077   for (std::size_t i = 0; i < g.size(); i++) {
0078     g.at(i) = {static_cast<float>(i), static_cast<float>(i * 2)};
0079   }
0080 
0081   return g;
0082 }
0083 
0084 // Test read and write access to int grid using type safe interface
0085 BOOST_AUTO_TEST_CASE(IntGridReadWriteAccess) {
0086   auto grid = createIntGrid1D();
0087 
0088   // Create mutable view
0089   AnyGridView<int> view(grid);
0090 
0091   // Test read access
0092   BOOST_CHECK_EQUAL(view.atLocalBins({1}), 10);
0093   BOOST_CHECK_EQUAL(view.atLocalBins({2}), 20);
0094 
0095   // Test write access
0096   view.atLocalBins({1}) = 100;
0097   BOOST_CHECK_EQUAL(view.atLocalBins({1}), 100);
0098   BOOST_CHECK_EQUAL(grid.atLocalBins({1}), 100);
0099 }
0100 
0101 // Test read-only access to int grid using type safe interface
0102 BOOST_AUTO_TEST_CASE(IntGridReadOnlyAccess) {
0103   auto grid = createIntGrid1D();
0104 
0105   // Create const view
0106   AnyGridConstView<int> constView(grid);
0107 
0108   // Test read access
0109   BOOST_CHECK_EQUAL(constView.atLocalBins({1}), 10);
0110   BOOST_CHECK_EQUAL(constView.atLocalBins({2}), 20);
0111 
0112   // Verify that the following would not compile:
0113   // constView.atLocalBins({1}) = 100; // Should cause compilation error
0114 }
0115 
0116 // Test creation of any grid view from concrete grid type
0117 BOOST_AUTO_TEST_CASE(CreateFromConcreteGrid) {
0118   auto doubleGrid = createDoubleGrid2D();
0119 
0120   // Create view from concrete grid
0121   AnyGridView<double> view(doubleGrid);
0122 
0123   // Check dimensions
0124   BOOST_CHECK_EQUAL(view.dimensions(), 2u);
0125 
0126   // Check values
0127   BOOST_CHECK_CLOSE(
0128       view.atLocalBins({1, 1}),
0129       1.5 * doubleGrid.multiAxis().getGlobalBinFromLocalBins({1, 1}), 1e-10);
0130 
0131   // Modify through view
0132   view.atLocalBins({1, 1}) = 42.0;
0133   BOOST_CHECK_CLOSE(doubleGrid.atLocalBins({1, 1}), 42.0, 1e-10);
0134 }
0135 
0136 // Test creation of any grid view from IGrid type
0137 BOOST_AUTO_TEST_CASE(CreateFromIGrid) {
0138   auto doubleGrid = createDoubleGrid2D();
0139   IGrid& iGrid = doubleGrid;
0140 
0141   // Create view from IGrid
0142   AnyGridView<double> view(iGrid);
0143 
0144   // Check dimensions
0145   BOOST_CHECK_EQUAL(view.dimensions(), 2u);
0146 
0147   // Check values
0148   BOOST_CHECK_CLOSE(
0149       view.atLocalBins({1, 1}),
0150       1.5 * doubleGrid.multiAxis().getGlobalBinFromLocalBins({1, 1}), 1e-10);
0151 }
0152 
0153 // Test creation of const grid view from const IGrid type
0154 BOOST_AUTO_TEST_CASE(CreateConstViewFromConstIGrid) {
0155   auto doubleGrid = createDoubleGrid2D();
0156   const IGrid& constIGrid = doubleGrid;
0157 
0158   // Create const view from const IGrid
0159   AnyGridConstView<double> constView(constIGrid);
0160 
0161   // Check dimensions
0162   BOOST_CHECK_EQUAL(constView.dimensions(), 2u);
0163 
0164   // Check values
0165   BOOST_CHECK_CLOSE(
0166       constView.atLocalBins({1, 1}),
0167       1.5 * doubleGrid.multiAxis().getGlobalBinFromLocalBins({1, 1}), 1e-10);
0168 }
0169 
0170 // Test type mismatch handling when creating from IGrid
0171 BOOST_AUTO_TEST_CASE(TypeMismatchFromIGrid) {
0172   auto doubleGrid = createDoubleGrid2D();
0173   IGrid& iGrid = doubleGrid;
0174 
0175   // Try to create int view from double grid
0176   BOOST_CHECK_THROW((AnyGridView<int>(iGrid)), std::invalid_argument);
0177 }
0178 
0179 // Test type mismatch handling when creating const view from const IGrid
0180 BOOST_AUTO_TEST_CASE(TypeMismatchFromConstIGrid) {
0181   auto doubleGrid = createDoubleGrid2D();
0182   const IGrid& constIGrid = doubleGrid;
0183 
0184   // Try to create int view from double grid
0185   BOOST_CHECK_THROW((AnyGridConstView<int>(constIGrid)), std::invalid_argument);
0186 }
0187 
0188 // Test creation of mutable view from mutable grid
0189 BOOST_AUTO_TEST_CASE(MutableViewFromMutableGrid) {
0190   auto stringGrid = createStringGrid2D();
0191 
0192   // Create mutable view
0193   AnyGridView<std::string> view(stringGrid);
0194 
0195   // Modify through view
0196   view.atLocalBins({2, 2}) = "Modified";
0197 
0198   // Check modification in original grid
0199   BOOST_CHECK_EQUAL(stringGrid.atLocalBins({2, 2}), "Modified");
0200 }
0201 
0202 // Test creation of const view from mutable grid
0203 BOOST_AUTO_TEST_CASE(ConstViewFromMutableGrid) {
0204   auto stringGrid = createStringGrid2D();
0205 
0206   // Create const view from mutable grid
0207   AnyGridConstView<std::string> constView(stringGrid);
0208 
0209   // Check read access
0210   BOOST_CHECK_EQUAL(constView.atLocalBins({2, 2}),
0211                     stringGrid.atLocalBins({2, 2}));
0212 
0213   // Verify that the following would not compile:
0214   // constView.atLocalBins({2, 2}) = "Modified"; // Should cause compilation
0215   // error
0216 }
0217 
0218 // Test creation of const view from const grid
0219 BOOST_AUTO_TEST_CASE(ConstViewFromConstGrid) {
0220   const auto stringGrid = createStringGrid2D();
0221 
0222   // Create const view from const grid
0223   AnyGridConstView<std::string> constView(stringGrid);
0224 
0225   // Check read access
0226   BOOST_CHECK_EQUAL(constView.atLocalBins({2, 2}),
0227                     stringGrid.atLocalBins({2, 2}));
0228 }
0229 
0230 // Test complex type (vector) with both IGrid and concrete grid type
0231 // construction
0232 BOOST_AUTO_TEST_CASE(VectorTypeWithBothConstructions) {
0233   auto vectorGrid = createVectorGrid3D();
0234 
0235   // Test with concrete grid type
0236   AnyGridView<std::vector<float>> concreteView(vectorGrid);
0237   BOOST_CHECK_EQUAL(concreteView.dimensions(), 3u);
0238   BOOST_CHECK_EQUAL(concreteView.atLocalBins({1, 1, 1}).size(), 2u);
0239   BOOST_CHECK_EQUAL(concreteView.atLocalBins({1, 1, 1})[0],
0240                     vectorGrid.atLocalBins({1, 1, 1})[0]);
0241 
0242   // Test with IGrid type
0243   IGrid& iGrid = vectorGrid;
0244   AnyGridView<std::vector<float>> iGridView(iGrid);
0245   BOOST_CHECK_EQUAL(iGridView.dimensions(), 3u);
0246   BOOST_CHECK_EQUAL(iGridView.atLocalBins({1, 1, 1}).size(), 2u);
0247   BOOST_CHECK_EQUAL(iGridView.atLocalBins({1, 1, 1})[0],
0248                     vectorGrid.atLocalBins({1, 1, 1})[0]);
0249 
0250   // Test with const IGrid type
0251   const IGrid& constIGrid = vectorGrid;
0252   AnyGridConstView<std::vector<float>> constIGridView(constIGrid);
0253   BOOST_CHECK_EQUAL(constIGridView.dimensions(), 3u);
0254   BOOST_CHECK_EQUAL(constIGridView.atLocalBins({1, 1, 1}).size(), 2u);
0255   BOOST_CHECK_EQUAL(constIGridView.atLocalBins({1, 1, 1})[0],
0256                     vectorGrid.atLocalBins({1, 1, 1})[0]);
0257 
0258   // Modify through view
0259   std::vector<float> newValue = {99.0f, 88.0f};
0260   concreteView.atLocalBins({1, 1, 1}) = newValue;
0261   BOOST_CHECK_EQUAL(vectorGrid.atLocalBins({1, 1, 1})[0], 99.0f);
0262   BOOST_CHECK_EQUAL(vectorGrid.atLocalBins({1, 1, 1})[1], 88.0f);
0263 }
0264 
0265 // Test grid properties access through view
0266 BOOST_AUTO_TEST_CASE(GridPropertiesAccess) {
0267   auto doubleGrid = createDoubleGrid2D();
0268   AnyGridView<double> view(doubleGrid);
0269 
0270   // Test dimensions
0271   BOOST_CHECK_EQUAL(view.dimensions(), 2u);
0272 
0273   // Test bin center
0274   auto center = view.multiAxisAny().getBinCenterAny({1, 1});
0275   auto expectedCenter = doubleGrid.multiAxis().getBinCenter({1, 1});
0276   BOOST_CHECK_CLOSE(center[0], expectedCenter[0], 1e-10);
0277   BOOST_CHECK_CLOSE(center[1], expectedCenter[1], 1e-10);
0278 
0279   // Test lower left bin edge
0280   auto lowerLeft = view.multiAxisAny().getLowerLeftBinEdgeAny({1, 1});
0281   auto expectedLowerLeft = doubleGrid.multiAxis().getLowerLeftBinEdge({1, 1});
0282   BOOST_CHECK_CLOSE(lowerLeft[0], expectedLowerLeft[0], 1e-10);
0283   BOOST_CHECK_CLOSE(lowerLeft[1], expectedLowerLeft[1], 1e-10);
0284 
0285   // Test upper right bin edge
0286   auto upperRight = view.multiAxisAny().getUpperRightBinEdgeAny({1, 1});
0287   auto expectedUpperRight = doubleGrid.multiAxis().getUpperRightBinEdge({1, 1});
0288   BOOST_CHECK_CLOSE(upperRight[0], expectedUpperRight[0], 1e-10);
0289   BOOST_CHECK_CLOSE(upperRight[1], expectedUpperRight[1], 1e-10);
0290 
0291   // Test number of local bins
0292   auto numBins = view.multiAxisAny().getNBinsAny();
0293   auto expectedNumBins = doubleGrid.multiAxis().getNBins();
0294   BOOST_CHECK_EQUAL(numBins[0], expectedNumBins[0]);
0295   BOOST_CHECK_EQUAL(numBins[1], expectedNumBins[1]);
0296 }
0297 
0298 // Test grid properties access through const view from const IGrid
0299 BOOST_AUTO_TEST_CASE(GridPropertiesAccessConstView) {
0300   auto doubleGrid = createDoubleGrid2D();
0301   const IGrid& constIGrid = doubleGrid;
0302   AnyGridConstView<double> constView(constIGrid);
0303 
0304   // Test dimensions
0305   BOOST_CHECK_EQUAL(constView.dimensions(), 2u);
0306 
0307   // Test bin center
0308   auto center = constView.multiAxisAny().getBinCenterAny({1, 1});
0309   auto expectedCenter = doubleGrid.multiAxis().getBinCenter({1, 1});
0310   BOOST_CHECK_CLOSE(center[0], expectedCenter[0], 1e-10);
0311   BOOST_CHECK_CLOSE(center[1], expectedCenter[1], 1e-10);
0312 
0313   // Test lower left bin edge
0314   auto lowerLeft = constView.multiAxisAny().getLowerLeftBinEdgeAny({1, 1});
0315   auto expectedLowerLeft = doubleGrid.multiAxis().getLowerLeftBinEdge({1, 1});
0316   BOOST_CHECK_CLOSE(lowerLeft[0], expectedLowerLeft[0], 1e-10);
0317   BOOST_CHECK_CLOSE(lowerLeft[1], expectedLowerLeft[1], 1e-10);
0318 
0319   // Test upper right bin edge
0320   auto upperRight = constView.multiAxisAny().getUpperRightBinEdgeAny({1, 1});
0321   auto expectedUpperRight = doubleGrid.multiAxis().getUpperRightBinEdge({1, 1});
0322   BOOST_CHECK_CLOSE(upperRight[0], expectedUpperRight[0], 1e-10);
0323   BOOST_CHECK_CLOSE(upperRight[1], expectedUpperRight[1], 1e-10);
0324 
0325   // Test number of local bins
0326   auto numBins = constView.multiAxisAny().getNBinsAny();
0327   auto expectedNumBins = doubleGrid.multiAxis().getNBins();
0328   BOOST_CHECK_EQUAL(numBins[0], expectedNumBins[0]);
0329   BOOST_CHECK_EQUAL(numBins[1], expectedNumBins[1]);
0330 }
0331 
0332 // Test error cases
0333 BOOST_AUTO_TEST_CASE(ErrorCases) {
0334   auto intGrid = createIntGrid1D();
0335   auto doubleGrid = createDoubleGrid2D();
0336 
0337   // Test accessing with wrong number of indices
0338   AnyGridView<int> intView(intGrid);
0339   BOOST_CHECK_THROW(intView.atLocalBins({1, 2}), std::invalid_argument);
0340 
0341   // Test accessing with out-of-bounds indices
0342   BOOST_CHECK_THROW(intView.atLocalBins({10}), std::out_of_range);
0343 
0344   // Test creating view with wrong value type
0345   IGrid& iGrid = doubleGrid;
0346   BOOST_CHECK_THROW(AnyGridView<std::string>{iGrid}, std::invalid_argument);
0347 
0348   // Test creating const view with wrong value type
0349   const IGrid& constIGrid = doubleGrid;
0350   BOOST_CHECK_THROW(AnyGridConstView<std::string>{constIGrid},
0351                     std::invalid_argument);
0352 }
0353 
0354 // Test copy operations
0355 BOOST_AUTO_TEST_CASE(CopyOperations) {
0356   // Create grids that will live for the duration of the test
0357   auto doubleGrid1 = createDoubleGrid2D();
0358   auto doubleGrid2 = createDoubleGrid2D();
0359   auto doubleGrid3 = createDoubleGrid2D();
0360 
0361   // Test copy constructor
0362   AnyGridView<double> view1(doubleGrid1);
0363   AnyGridView<double> view2(view1);
0364   BOOST_CHECK_CLOSE(view1.atLocalBins({1, 1}), view2.atLocalBins({1, 1}),
0365                     1e-10);
0366 
0367   // Test copy assignment
0368   AnyGridView<double> view3(doubleGrid2);
0369   view3 = view1;
0370   BOOST_CHECK_CLOSE(view1.atLocalBins({1, 1}), view3.atLocalBins({1, 1}),
0371                     1e-10);
0372 
0373   // Same for const views
0374   AnyGridConstView<double> constView1(doubleGrid1);
0375   AnyGridConstView<double> constView2(constView1);
0376   BOOST_CHECK_CLOSE(constView1.atLocalBins({1, 1}),
0377                     constView2.atLocalBins({1, 1}), 1e-10);
0378 
0379   auto doubleGrid4 = createDoubleGrid2D();
0380   AnyGridConstView<double> constView3(doubleGrid4);
0381   constView3 = constView1;
0382   BOOST_CHECK_CLOSE(constView1.atLocalBins({1, 1}),
0383                     constView3.atLocalBins({1, 1}), 1e-10);
0384 
0385   // Test const view from const IGrid
0386   const IGrid& constIGrid = doubleGrid1;
0387   AnyGridConstView<double> constView4(constIGrid);
0388   AnyGridConstView<double> constView5(constView4);
0389   BOOST_CHECK_CLOSE(constView4.atLocalBins({1, 1}),
0390                     constView5.atLocalBins({1, 1}), 1e-10);
0391 }
0392 
0393 BOOST_AUTO_TEST_CASE(TypeDeduction) {
0394   auto grid = createIntGrid1D();
0395   AnyGridView view(grid);
0396   static_assert(std::is_same_v<decltype(view), AnyGridView<int>>);
0397 
0398   const auto constGrid = createIntGrid1D();
0399   AnyGridConstView<int> constView(constGrid);
0400   static_assert(std::is_same_v<decltype(constView), AnyGridConstView<int>>);
0401 }
0402 
0403 BOOST_AUTO_TEST_SUITE_END()
0404 
0405 }  // namespace ActsTests