Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-11-01 07:55:12

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(view.atLocalBins({1, 1}),
0128                     1.5 * doubleGrid.globalBinFromLocalBins({1, 1}), 1e-10);
0129 
0130   // Modify through view
0131   view.atLocalBins({1, 1}) = 42.0;
0132   BOOST_CHECK_CLOSE(doubleGrid.atLocalBins({1, 1}), 42.0, 1e-10);
0133 }
0134 
0135 // Test creation of any grid view from IGrid type
0136 BOOST_AUTO_TEST_CASE(CreateFromIGrid) {
0137   auto doubleGrid = createDoubleGrid2D();
0138   IGrid& iGrid = doubleGrid;
0139 
0140   // Create view from IGrid
0141   AnyGridView<double> view(iGrid);
0142 
0143   // Check dimensions
0144   BOOST_CHECK_EQUAL(view.dimensions(), 2u);
0145 
0146   // Check values
0147   BOOST_CHECK_CLOSE(view.atLocalBins({1, 1}),
0148                     1.5 * doubleGrid.globalBinFromLocalBins({1, 1}), 1e-10);
0149 }
0150 
0151 // Test creation of const grid view from const IGrid type
0152 BOOST_AUTO_TEST_CASE(CreateConstViewFromConstIGrid) {
0153   auto doubleGrid = createDoubleGrid2D();
0154   const IGrid& constIGrid = doubleGrid;
0155 
0156   // Create const view from const IGrid
0157   AnyGridConstView<double> constView(constIGrid);
0158 
0159   // Check dimensions
0160   BOOST_CHECK_EQUAL(constView.dimensions(), 2u);
0161 
0162   // Check values
0163   BOOST_CHECK_CLOSE(constView.atLocalBins({1, 1}),
0164                     1.5 * doubleGrid.globalBinFromLocalBins({1, 1}), 1e-10);
0165 }
0166 
0167 // Test type mismatch handling when creating from IGrid
0168 BOOST_AUTO_TEST_CASE(TypeMismatchFromIGrid) {
0169   auto doubleGrid = createDoubleGrid2D();
0170   IGrid& iGrid = doubleGrid;
0171 
0172   // Try to create int view from double grid
0173   BOOST_CHECK_THROW((AnyGridView<int>(iGrid)), std::invalid_argument);
0174 }
0175 
0176 // Test type mismatch handling when creating const view from const IGrid
0177 BOOST_AUTO_TEST_CASE(TypeMismatchFromConstIGrid) {
0178   auto doubleGrid = createDoubleGrid2D();
0179   const IGrid& constIGrid = doubleGrid;
0180 
0181   // Try to create int view from double grid
0182   BOOST_CHECK_THROW((AnyGridConstView<int>(constIGrid)), std::invalid_argument);
0183 }
0184 
0185 // Test creation of mutable view from mutable grid
0186 BOOST_AUTO_TEST_CASE(MutableViewFromMutableGrid) {
0187   auto stringGrid = createStringGrid2D();
0188 
0189   // Create mutable view
0190   AnyGridView<std::string> view(stringGrid);
0191 
0192   // Modify through view
0193   view.atLocalBins({2, 2}) = "Modified";
0194 
0195   // Check modification in original grid
0196   BOOST_CHECK_EQUAL(stringGrid.atLocalBins({2, 2}), "Modified");
0197 }
0198 
0199 // Test creation of const view from mutable grid
0200 BOOST_AUTO_TEST_CASE(ConstViewFromMutableGrid) {
0201   auto stringGrid = createStringGrid2D();
0202 
0203   // Create const view from mutable grid
0204   AnyGridConstView<std::string> constView(stringGrid);
0205 
0206   // Check read access
0207   BOOST_CHECK_EQUAL(constView.atLocalBins({2, 2}),
0208                     stringGrid.atLocalBins({2, 2}));
0209 
0210   // Verify that the following would not compile:
0211   // constView.atLocalBins({2, 2}) = "Modified"; // Should cause compilation
0212   // error
0213 }
0214 
0215 // Test creation of const view from const grid
0216 BOOST_AUTO_TEST_CASE(ConstViewFromConstGrid) {
0217   const auto stringGrid = createStringGrid2D();
0218 
0219   // Create const view from const grid
0220   AnyGridConstView<std::string> constView(stringGrid);
0221 
0222   // Check read access
0223   BOOST_CHECK_EQUAL(constView.atLocalBins({2, 2}),
0224                     stringGrid.atLocalBins({2, 2}));
0225 }
0226 
0227 // Test complex type (vector) with both IGrid and concrete grid type
0228 // construction
0229 BOOST_AUTO_TEST_CASE(VectorTypeWithBothConstructions) {
0230   auto vectorGrid = createVectorGrid3D();
0231 
0232   // Test with concrete grid type
0233   AnyGridView<std::vector<float>> concreteView(vectorGrid);
0234   BOOST_CHECK_EQUAL(concreteView.dimensions(), 3u);
0235   BOOST_CHECK_EQUAL(concreteView.atLocalBins({1, 1, 1}).size(), 2u);
0236   BOOST_CHECK_EQUAL(concreteView.atLocalBins({1, 1, 1})[0],
0237                     vectorGrid.atLocalBins({1, 1, 1})[0]);
0238 
0239   // Test with IGrid type
0240   IGrid& iGrid = vectorGrid;
0241   AnyGridView<std::vector<float>> iGridView(iGrid);
0242   BOOST_CHECK_EQUAL(iGridView.dimensions(), 3u);
0243   BOOST_CHECK_EQUAL(iGridView.atLocalBins({1, 1, 1}).size(), 2u);
0244   BOOST_CHECK_EQUAL(iGridView.atLocalBins({1, 1, 1})[0],
0245                     vectorGrid.atLocalBins({1, 1, 1})[0]);
0246 
0247   // Test with const IGrid type
0248   const IGrid& constIGrid = vectorGrid;
0249   AnyGridConstView<std::vector<float>> constIGridView(constIGrid);
0250   BOOST_CHECK_EQUAL(constIGridView.dimensions(), 3u);
0251   BOOST_CHECK_EQUAL(constIGridView.atLocalBins({1, 1, 1}).size(), 2u);
0252   BOOST_CHECK_EQUAL(constIGridView.atLocalBins({1, 1, 1})[0],
0253                     vectorGrid.atLocalBins({1, 1, 1})[0]);
0254 
0255   // Modify through view
0256   std::vector<float> newValue = {99.0f, 88.0f};
0257   concreteView.atLocalBins({1, 1, 1}) = newValue;
0258   BOOST_CHECK_EQUAL(vectorGrid.atLocalBins({1, 1, 1})[0], 99.0f);
0259   BOOST_CHECK_EQUAL(vectorGrid.atLocalBins({1, 1, 1})[1], 88.0f);
0260 }
0261 
0262 // Test grid properties access through view
0263 BOOST_AUTO_TEST_CASE(GridPropertiesAccess) {
0264   auto doubleGrid = createDoubleGrid2D();
0265   AnyGridView<double> view(doubleGrid);
0266 
0267   // Test dimensions
0268   BOOST_CHECK_EQUAL(view.dimensions(), 2u);
0269 
0270   // Test bin center
0271   auto center = view.binCenter({1, 1});
0272   auto expectedCenter = doubleGrid.binCenter({1, 1});
0273   BOOST_CHECK_CLOSE(center[0], expectedCenter[0], 1e-10);
0274   BOOST_CHECK_CLOSE(center[1], expectedCenter[1], 1e-10);
0275 
0276   // Test lower left bin edge
0277   auto lowerLeft = view.lowerLeftBinEdge({1, 1});
0278   auto expectedLowerLeft = doubleGrid.lowerLeftBinEdge({1, 1});
0279   BOOST_CHECK_CLOSE(lowerLeft[0], expectedLowerLeft[0], 1e-10);
0280   BOOST_CHECK_CLOSE(lowerLeft[1], expectedLowerLeft[1], 1e-10);
0281 
0282   // Test upper right bin edge
0283   auto upperRight = view.upperRightBinEdge({1, 1});
0284   auto expectedUpperRight = doubleGrid.upperRightBinEdge({1, 1});
0285   BOOST_CHECK_CLOSE(upperRight[0], expectedUpperRight[0], 1e-10);
0286   BOOST_CHECK_CLOSE(upperRight[1], expectedUpperRight[1], 1e-10);
0287 
0288   // Test number of local bins
0289   auto numBins = view.numLocalBins();
0290   auto expectedNumBins = doubleGrid.numLocalBins();
0291   BOOST_CHECK_EQUAL(numBins[0], expectedNumBins[0]);
0292   BOOST_CHECK_EQUAL(numBins[1], expectedNumBins[1]);
0293 }
0294 
0295 // Test grid properties access through const view from const IGrid
0296 BOOST_AUTO_TEST_CASE(GridPropertiesAccessConstView) {
0297   auto doubleGrid = createDoubleGrid2D();
0298   const IGrid& constIGrid = doubleGrid;
0299   AnyGridConstView<double> constView(constIGrid);
0300 
0301   // Test dimensions
0302   BOOST_CHECK_EQUAL(constView.dimensions(), 2u);
0303 
0304   // Test bin center
0305   auto center = constView.binCenter({1, 1});
0306   auto expectedCenter = doubleGrid.binCenter({1, 1});
0307   BOOST_CHECK_CLOSE(center[0], expectedCenter[0], 1e-10);
0308   BOOST_CHECK_CLOSE(center[1], expectedCenter[1], 1e-10);
0309 
0310   // Test lower left bin edge
0311   auto lowerLeft = constView.lowerLeftBinEdge({1, 1});
0312   auto expectedLowerLeft = doubleGrid.lowerLeftBinEdge({1, 1});
0313   BOOST_CHECK_CLOSE(lowerLeft[0], expectedLowerLeft[0], 1e-10);
0314   BOOST_CHECK_CLOSE(lowerLeft[1], expectedLowerLeft[1], 1e-10);
0315 
0316   // Test upper right bin edge
0317   auto upperRight = constView.upperRightBinEdge({1, 1});
0318   auto expectedUpperRight = doubleGrid.upperRightBinEdge({1, 1});
0319   BOOST_CHECK_CLOSE(upperRight[0], expectedUpperRight[0], 1e-10);
0320   BOOST_CHECK_CLOSE(upperRight[1], expectedUpperRight[1], 1e-10);
0321 
0322   // Test number of local bins
0323   auto numBins = constView.numLocalBins();
0324   auto expectedNumBins = doubleGrid.numLocalBins();
0325   BOOST_CHECK_EQUAL(numBins[0], expectedNumBins[0]);
0326   BOOST_CHECK_EQUAL(numBins[1], expectedNumBins[1]);
0327 }
0328 
0329 // Test error cases
0330 BOOST_AUTO_TEST_CASE(ErrorCases) {
0331   auto intGrid = createIntGrid1D();
0332   auto doubleGrid = createDoubleGrid2D();
0333 
0334   // Test accessing with wrong number of indices
0335   AnyGridView<int> intView(intGrid);
0336   BOOST_CHECK_THROW(intView.atLocalBins({1, 2}), std::invalid_argument);
0337 
0338   // Test accessing with out-of-bounds indices
0339   BOOST_CHECK_THROW(intView.atLocalBins({10}), std::out_of_range);
0340 
0341   // Test creating view with wrong value type
0342   IGrid& iGrid = doubleGrid;
0343   BOOST_CHECK_THROW(AnyGridView<std::string>{iGrid}, std::invalid_argument);
0344 
0345   // Test creating const view with wrong value type
0346   const IGrid& constIGrid = doubleGrid;
0347   BOOST_CHECK_THROW(AnyGridConstView<std::string>{constIGrid},
0348                     std::invalid_argument);
0349 }
0350 
0351 // Test copy operations
0352 BOOST_AUTO_TEST_CASE(CopyOperations) {
0353   // Create grids that will live for the duration of the test
0354   auto doubleGrid1 = createDoubleGrid2D();
0355   auto doubleGrid2 = createDoubleGrid2D();
0356   auto doubleGrid3 = createDoubleGrid2D();
0357 
0358   // Test copy constructor
0359   AnyGridView<double> view1(doubleGrid1);
0360   AnyGridView<double> view2(view1);
0361   BOOST_CHECK_CLOSE(view1.atLocalBins({1, 1}), view2.atLocalBins({1, 1}),
0362                     1e-10);
0363 
0364   // Test copy assignment
0365   AnyGridView<double> view3(doubleGrid2);
0366   view3 = view1;
0367   BOOST_CHECK_CLOSE(view1.atLocalBins({1, 1}), view3.atLocalBins({1, 1}),
0368                     1e-10);
0369 
0370   // Same for const views
0371   AnyGridConstView<double> constView1(doubleGrid1);
0372   AnyGridConstView<double> constView2(constView1);
0373   BOOST_CHECK_CLOSE(constView1.atLocalBins({1, 1}),
0374                     constView2.atLocalBins({1, 1}), 1e-10);
0375 
0376   auto doubleGrid4 = createDoubleGrid2D();
0377   AnyGridConstView<double> constView3(doubleGrid4);
0378   constView3 = constView1;
0379   BOOST_CHECK_CLOSE(constView1.atLocalBins({1, 1}),
0380                     constView3.atLocalBins({1, 1}), 1e-10);
0381 
0382   // Test const view from const IGrid
0383   const IGrid& constIGrid = doubleGrid1;
0384   AnyGridConstView<double> constView4(constIGrid);
0385   AnyGridConstView<double> constView5(constView4);
0386   BOOST_CHECK_CLOSE(constView4.atLocalBins({1, 1}),
0387                     constView5.atLocalBins({1, 1}), 1e-10);
0388 }
0389 
0390 BOOST_AUTO_TEST_CASE(TypeDeduction) {
0391   auto grid = createIntGrid1D();
0392   AnyGridView view(grid);
0393   static_assert(std::is_same_v<decltype(view), AnyGridView<int>>);
0394 
0395   const auto constGrid = createIntGrid1D();
0396   AnyGridConstView<int> constView(constGrid);
0397   static_assert(std::is_same_v<decltype(constView), AnyGridConstView<int>>);
0398 }
0399 
0400 BOOST_AUTO_TEST_SUITE_END()
0401 
0402 }  // namespace ActsTests