Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:11:33

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2016-2024 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 http://mozilla.org/MPL/2.0/.
0008 
0009 #include <boost/test/unit_test.hpp>
0010 
0011 #include "Acts/Utilities/Grid.hpp"
0012 #include "Acts/Utilities/GridIterator.hpp"
0013 
0014 #include <array>
0015 #include <unordered_set>
0016 
0017 namespace Acts::Test {
0018 
0019 BOOST_AUTO_TEST_CASE(grid_iteration_test_1d_global_operators) {
0020   const std::size_t nBins = 10ul;
0021   Acts::detail::EquidistantAxis xAxis(0, 100, nBins);
0022   Acts::Grid<double, Acts::detail::EquidistantAxis> grid(
0023       std::make_tuple(std::move(xAxis)));
0024 
0025   BOOST_CHECK_EQUAL(grid.size(true), nBins + 2ul);
0026 
0027   Acts::GridGlobalIterator<double, Acts::detail::EquidistantAxis> gridStart =
0028       grid.begin();
0029   Acts::GridGlobalIterator<double, Acts::detail::EquidistantAxis> gridStop =
0030       grid.end();
0031 
0032   BOOST_CHECK_EQUAL(gridStart == gridStop, false);
0033   BOOST_CHECK_EQUAL(gridStart != gridStop, true);
0034   BOOST_CHECK_EQUAL(gridStart < gridStop, true);
0035   BOOST_CHECK_EQUAL(gridStart <= gridStop, true);
0036   BOOST_CHECK_EQUAL(gridStart > gridStop, false);
0037   BOOST_CHECK_EQUAL(gridStart >= gridStop, false);
0038 
0039   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), nBins + 2ul);
0040   auto itr = gridStart++;
0041   BOOST_CHECK_EQUAL(std::distance(itr, gridStart), 1ul);
0042   BOOST_CHECK_EQUAL(std::distance(itr, gridStop), nBins + 2ul);
0043   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), nBins + 1ul);
0044 
0045   itr = ++gridStart;
0046   BOOST_CHECK_EQUAL(std::distance(itr, gridStart), 0ul);
0047   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), nBins);
0048 
0049   itr = gridStart + std::distance(gridStart, gridStop);
0050   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), nBins);
0051   BOOST_CHECK_EQUAL(std::distance(itr, gridStop), 0ul);
0052   BOOST_CHECK_EQUAL(itr == gridStop, true);
0053 
0054   itr = gridStart - 1ul;
0055   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), nBins);
0056   BOOST_CHECK_EQUAL(std::distance(itr, gridStop), nBins + 1ul);
0057 
0058   gridStart += std::distance(gridStart, gridStop);
0059   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), 0ul);
0060   BOOST_CHECK_EQUAL(gridStart == gridStop, true);
0061 
0062   gridStart -= 3ul;
0063   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), 3ul);
0064   BOOST_CHECK_EQUAL(gridStart != gridStop, true);
0065 
0066   [[maybe_unused]] double value = *gridStart;
0067 
0068   Acts::GridGlobalIterator<double, Acts::detail::EquidistantAxis> gridDefault;
0069   Acts::GridGlobalIterator<double, Acts::detail::EquidistantAxis> gridDummy(
0070       grid, 0ul);
0071 
0072   BOOST_CHECK_EQUAL(gridDefault == gridDummy, false);
0073 }
0074 
0075 BOOST_AUTO_TEST_CASE(grid_iteration_test_2d_global_operators) {
0076   const std::size_t nBinsX = 10ul;
0077   const std::size_t nBinsY = 5ul;
0078   Acts::detail::EquidistantAxis xAxis(0, 100, nBinsX);
0079   Acts::detail::EquidistantAxis yAxis(0, 100, nBinsY);
0080   Acts::Grid<double, Acts::detail::EquidistantAxis,
0081              Acts::detail::EquidistantAxis>
0082       grid(std::make_tuple(std::move(xAxis), std::move(yAxis)));
0083 
0084   BOOST_CHECK_EQUAL(grid.size(true), (nBinsX + 2ul) * (nBinsY + 2ul));
0085 
0086   Acts::GridGlobalIterator<double, Acts::detail::EquidistantAxis,
0087                            Acts::detail::EquidistantAxis>
0088       gridStart = grid.begin();
0089   Acts::GridGlobalIterator<double, Acts::detail::EquidistantAxis,
0090                            Acts::detail::EquidistantAxis>
0091       gridStop = grid.end();
0092 
0093   BOOST_CHECK_EQUAL(gridStart == gridStop, false);
0094   BOOST_CHECK_EQUAL(gridStart != gridStop, true);
0095   BOOST_CHECK_EQUAL(gridStart < gridStop, true);
0096   BOOST_CHECK_EQUAL(gridStart <= gridStop, true);
0097   BOOST_CHECK_EQUAL(gridStart > gridStop, false);
0098   BOOST_CHECK_EQUAL(gridStart >= gridStop, false);
0099 
0100   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), grid.size(true));
0101   auto itr = gridStart++;
0102   BOOST_CHECK_EQUAL(std::distance(itr, gridStart), 1ul);
0103   BOOST_CHECK_EQUAL(std::distance(itr, gridStop), grid.size(true));
0104   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), grid.size(true) - 1ul);
0105 
0106   itr = ++gridStart;
0107   BOOST_CHECK_EQUAL(std::distance(itr, gridStart), 0ul);
0108   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), grid.size(true) - 2ul);
0109 
0110   itr = gridStart + std::distance(gridStart, gridStop);
0111   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), grid.size(true) - 2ul);
0112   BOOST_CHECK_EQUAL(std::distance(itr, gridStop), 0ul);
0113   BOOST_CHECK_EQUAL(itr == gridStop, true);
0114 
0115   itr = gridStart - 1ul;
0116   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), grid.size(true) - 2ul);
0117   BOOST_CHECK_EQUAL(std::distance(itr, gridStop), grid.size(true) - 1ul);
0118 
0119   gridStart += std::distance(gridStart, gridStop);
0120   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), 0ul);
0121   BOOST_CHECK_EQUAL(gridStart == gridStop, true);
0122 
0123   gridStart -= 3ul;
0124   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), 3ul);
0125   BOOST_CHECK_EQUAL(gridStart != gridStop, true);
0126 
0127   [[maybe_unused]] double value = *gridStart;
0128 
0129   Acts::GridGlobalIterator<double, Acts::detail::EquidistantAxis,
0130                            Acts::detail::EquidistantAxis>
0131       gridDefault;
0132   Acts::GridGlobalIterator<double, Acts::detail::EquidistantAxis,
0133                            Acts::detail::EquidistantAxis>
0134       gridDummy(grid, 0ul);
0135 
0136   BOOST_CHECK_EQUAL(gridDefault == gridDummy, false);
0137 }
0138 
0139 BOOST_AUTO_TEST_CASE(grid_iteration_test_1d_global) {
0140   const std::size_t nBins = 10ul;
0141   Acts::detail::EquidistantAxis xAxis(0, 100, nBins);
0142   Acts::Grid<double, Acts::detail::EquidistantAxis> grid(
0143       std::make_tuple(std::move(xAxis)));
0144 
0145   // test general properties
0146   BOOST_CHECK_EQUAL(grid.size(false), nBins);
0147   BOOST_CHECK_EQUAL(grid.size(true), nBins + 2ul);
0148 
0149   const std::array<std::size_t, 1ul> numLocalBins = grid.numLocalBins();
0150   BOOST_CHECK_EQUAL(numLocalBins[0ul], nBins);
0151 
0152   Acts::GridGlobalIterator<double, Acts::detail::EquidistantAxis> gridStart =
0153       grid.begin();
0154   Acts::GridGlobalIterator<double, Acts::detail::EquidistantAxis> gridStop =
0155       grid.end();
0156   std::size_t numIterations = 0ul;
0157   for (; gridStart != gridStop; gridStart++) {
0158     BOOST_CHECK_EQUAL(gridStart.globalBinIndex(), numIterations);
0159     const std::array<std::size_t, 1ul> locPosition =
0160         gridStart.localBinsIndices();
0161     BOOST_CHECK_EQUAL(numIterations, locPosition[0ul]);
0162     ++numIterations;
0163   }
0164   BOOST_CHECK_EQUAL(numIterations, grid.size(true));
0165 }
0166 
0167 BOOST_AUTO_TEST_CASE(grid_iteration_test_2d_global) {
0168   const std::size_t nBins = 10ul;
0169   Acts::detail::EquidistantAxis xAxis(0, 100, nBins);
0170   Acts::detail::EquidistantAxis yAxis(0, 100, nBins);
0171   Acts::Grid<double, Acts::detail::EquidistantAxis,
0172              Acts::detail::EquidistantAxis>
0173       grid(std::make_tuple(std::move(xAxis), std::move(yAxis)));
0174 
0175   // test general properties
0176   BOOST_CHECK_EQUAL(grid.size(false), nBins * nBins);
0177   BOOST_CHECK_EQUAL(grid.size(true), (nBins + 2ul) * (nBins + 2ul));
0178 
0179   const std::array<std::size_t, 2ul> numLocalBins = grid.numLocalBins();
0180   BOOST_CHECK_EQUAL(numLocalBins[0ul], nBins);
0181   BOOST_CHECK_EQUAL(numLocalBins[1ul], nBins);
0182 
0183   Acts::GridGlobalIterator<double, Acts::detail::EquidistantAxis,
0184                            Acts::detail::EquidistantAxis>
0185       gridStart = grid.begin();
0186   Acts::GridGlobalIterator<double, Acts::detail::EquidistantAxis,
0187                            Acts::detail::EquidistantAxis>
0188       gridStop = grid.end();
0189   std::size_t numIterations = 0ul;
0190   for (; gridStart != gridStop; ++gridStart) {
0191     BOOST_CHECK_EQUAL(gridStart.globalBinIndex(), numIterations);
0192     ++numIterations;
0193   }
0194   BOOST_CHECK_EQUAL(numIterations, grid.size(true));
0195 }
0196 
0197 BOOST_AUTO_TEST_CASE(grid_iteration_test_3d_global) {
0198   const std::size_t nBins = 10ul;
0199   const std::size_t nBinsZ = 20ul;
0200   Acts::detail::EquidistantAxis xAxis(0, 100, nBins);
0201   Acts::detail::EquidistantAxis yAxis(0, 100, nBins);
0202   Acts::detail::EquidistantAxis zAxis(0, 100, nBinsZ);
0203   Acts::Grid<double, Acts::detail::EquidistantAxis,
0204              Acts::detail::EquidistantAxis, Acts::detail::EquidistantAxis>
0205       grid(std::make_tuple(std::move(xAxis), std::move(yAxis),
0206                            std::move(zAxis)));
0207 
0208   // test general properties
0209   BOOST_CHECK_EQUAL(grid.size(false), nBins * nBins * nBinsZ);
0210   BOOST_CHECK_EQUAL(grid.size(true),
0211                     (nBins + 2ul) * (nBins + 2ul) * (nBinsZ + 2ul));
0212 
0213   const std::array<std::size_t, 3ul> numLocalBins = grid.numLocalBins();
0214   BOOST_CHECK_EQUAL(numLocalBins[0ul], nBins);
0215   BOOST_CHECK_EQUAL(numLocalBins[1ul], nBins);
0216   BOOST_CHECK_EQUAL(numLocalBins[2ul], nBinsZ);
0217 
0218   Acts::GridGlobalIterator<double, Acts::detail::EquidistantAxis,
0219                            Acts::detail::EquidistantAxis,
0220                            Acts::detail::EquidistantAxis>
0221       gridStart = grid.begin();
0222   Acts::GridGlobalIterator<double, Acts::detail::EquidistantAxis,
0223                            Acts::detail::EquidistantAxis,
0224                            Acts::detail::EquidistantAxis>
0225       gridStop = grid.end();
0226   std::size_t numIterations = 0ul;
0227   for (; gridStart != gridStop; ++gridStart) {
0228     BOOST_CHECK_EQUAL(gridStart.globalBinIndex(), numIterations);
0229     ++numIterations;
0230   }
0231   BOOST_CHECK_EQUAL(numIterations, grid.size(true));
0232 }
0233 
0234 BOOST_AUTO_TEST_CASE(grid_iteration_test_1d_local_operators) {
0235   const std::size_t nBins = 10ul;
0236   Acts::detail::EquidistantAxis xAxis(0, 100, nBins);
0237   Acts::Grid<double, Acts::detail::EquidistantAxis> grid(
0238       std::make_tuple(std::move(xAxis)));
0239 
0240   std::array<std::vector<std::size_t>, 1ul> navigation;
0241   navigation[0ul].resize(nBins);
0242   std::iota(navigation[0ul].begin(), navigation[0ul].end(), 1ul);
0243 
0244   // Constructor without navigation
0245   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis> gridIterNoNav(
0246       grid, {0ul});
0247   // Constructor(s) with navigation
0248   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis> gridStart(
0249       grid, {0ul}, navigation);
0250 
0251   BOOST_CHECK_EQUAL(std::distance(gridIterNoNav, gridStart), 0ul);
0252   BOOST_CHECK_EQUAL(gridIterNoNav == gridStart, true);
0253 
0254   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis> gridStop(
0255       grid, {nBins}, std::move(navigation));
0256 
0257   BOOST_CHECK_EQUAL(gridStart == gridStop, false);
0258   BOOST_CHECK_EQUAL(gridStart != gridStop, true);
0259 
0260   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), grid.size(false));
0261   BOOST_CHECK_EQUAL(gridStart != gridStop, true);
0262 
0263   auto itr = gridStart++;
0264   BOOST_CHECK_EQUAL(std::distance(itr, gridStart), 1ul);
0265   BOOST_CHECK_EQUAL(std::distance(itr, gridStop), nBins);
0266   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), nBins - 1ul);
0267 
0268   itr = ++gridStart;
0269   BOOST_CHECK_EQUAL(std::distance(itr, gridStart), 0ul);
0270   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), nBins - 2ul);
0271 
0272   [[maybe_unused]] double value = *gridStart;
0273   std::array<std::size_t, 1ul> locPos = gridStart.localBinsIndices();
0274   BOOST_CHECK_EQUAL(locPos[0ul], 3ul);
0275 
0276   std::size_t globPos = gridStart.globalBinIndex();
0277   BOOST_CHECK_EQUAL(globPos, 3ul);
0278 
0279   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis> gridDefault;
0280   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis> gridDummy(
0281       grid, {0ul});
0282 
0283   BOOST_CHECK_EQUAL(gridDefault == gridDummy, false);
0284 
0285   // move operation will invalidate gridStart since the grid gets moved and
0286   // replaced with a nullptr
0287   itr = std::move(gridStart);
0288   BOOST_CHECK_EQUAL(itr == gridStart, false);
0289   BOOST_CHECK_EQUAL(itr != gridStart, true);
0290   BOOST_CHECK_EQUAL(std::distance(itr, gridStop), nBins - 2ul);
0291 }
0292 
0293 BOOST_AUTO_TEST_CASE(grid_iteration_test_2d_local_operators) {
0294   const std::size_t nBinsX = 10ul;
0295   const std::size_t nBinsY = 5ul;
0296   Acts::detail::EquidistantAxis xAxis(0, 100, nBinsX);
0297   Acts::detail::EquidistantAxis yAxis(0, 100, nBinsY);
0298   Acts::Grid<double, Acts::detail::EquidistantAxis,
0299              Acts::detail::EquidistantAxis>
0300       grid(std::make_tuple(std::move(xAxis), std::move(yAxis)));
0301 
0302   std::array<std::vector<std::size_t>, 2ul> navigation;
0303   navigation[0ul].resize(nBinsX);
0304   navigation[1ul].resize(nBinsY);
0305   std::iota(navigation[0ul].begin(), navigation[0ul].end(), 1ul);
0306   std::iota(navigation[1ul].begin(), navigation[1ul].end(), 1ul);
0307 
0308   // Constructor without navigation
0309   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis,
0310                           Acts::detail::EquidistantAxis>
0311       gridIterNoNav(grid, {0ul, 0ul});
0312   // Constructor(s) with navigation
0313   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis,
0314                           Acts::detail::EquidistantAxis>
0315       gridStart(grid, {0ul, 0ul}, navigation);
0316 
0317   BOOST_CHECK_EQUAL(std::distance(gridIterNoNav, gridStart), 0ul);
0318   BOOST_CHECK_EQUAL(gridIterNoNav == gridStart, true);
0319 
0320   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis,
0321                           Acts::detail::EquidistantAxis>
0322       gridStop(grid, {nBinsX, nBinsY}, std::move(navigation));
0323 
0324   BOOST_CHECK_EQUAL(gridStart == gridStop, false);
0325   BOOST_CHECK_EQUAL(gridStart != gridStop, true);
0326 
0327   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), grid.size(false));
0328   BOOST_CHECK_EQUAL(gridStart != gridStop, true);
0329 
0330   auto itr = gridStart++;
0331   BOOST_CHECK_EQUAL(std::distance(itr, gridStart), 1ul);
0332   BOOST_CHECK_EQUAL(std::distance(itr, gridStop), nBinsX * nBinsY);
0333   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), nBinsX * nBinsY - 1ul);
0334 
0335   itr = ++gridStart;
0336   BOOST_CHECK_EQUAL(std::distance(itr, gridStart), 0ul);
0337   BOOST_CHECK_EQUAL(std::distance(gridStart, gridStop), nBinsX * nBinsY - 2ul);
0338 
0339   [[maybe_unused]] double value = *gridStart;
0340   std::array<std::size_t, 2ul> locPos = gridStart.localBinsIndices();
0341   BOOST_CHECK_EQUAL(locPos[0ul], 1ul);
0342   BOOST_CHECK_EQUAL(locPos[1ul], 3ul);
0343 
0344   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis,
0345                           Acts::detail::EquidistantAxis>
0346       gridDefault;
0347   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis,
0348                           Acts::detail::EquidistantAxis>
0349       gridDummy(grid, {0ul, 0ul});
0350 
0351   BOOST_CHECK_EQUAL(gridDefault == gridDummy, false);
0352 
0353   // move operation will invalidate gridStart since the grid gets moved and
0354   // replaced with a nullptr
0355   itr = std::move(gridStart);
0356   BOOST_CHECK_EQUAL(itr == gridStart, false);
0357   BOOST_CHECK_EQUAL(itr != gridStart, true);
0358   BOOST_CHECK_EQUAL(std::distance(itr, gridStop), nBinsX * nBinsY - 2ul);
0359 }
0360 
0361 BOOST_AUTO_TEST_CASE(grid_iteration_test_1d_local_notvalid) {
0362   const std::size_t nBins = 10ul;
0363   Acts::detail::EquidistantAxis xAxis(0, 100, nBins);
0364   Acts::Grid<double, Acts::detail::EquidistantAxis> grid(
0365       std::make_tuple(std::move(xAxis)));
0366 
0367   // no navigation bins
0368   std::array<std::vector<std::size_t>, 1ul> noNavigation;
0369   BOOST_CHECK_THROW(
0370       (Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis>(
0371           grid, {0ul}, std::move(noNavigation))),
0372       std::invalid_argument);
0373 
0374   // too many steps in the navigation, there are not enough bins in the axis
0375   std::array<std::vector<std::size_t>, 1ul> tooMuchNavigation;
0376   tooMuchNavigation[0ul].resize(2 * nBins);
0377   std::iota(tooMuchNavigation[0ul].begin(), tooMuchNavigation[0ul].end(), 1ul);
0378   BOOST_CHECK_THROW(
0379       (Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis>(
0380           grid, {0ul}, std::move(tooMuchNavigation))),
0381       std::invalid_argument);
0382 }
0383 
0384 BOOST_AUTO_TEST_CASE(grid_iteration_test_1d_local) {
0385   const std::size_t nBins = 10ul;
0386   Acts::detail::EquidistantAxis xAxis(0, 100, nBins);
0387   Acts::Grid<double, Acts::detail::EquidistantAxis> grid(
0388       std::make_tuple(std::move(xAxis)));
0389 
0390   // test general properties
0391   BOOST_CHECK_EQUAL(grid.size(false), nBins);
0392   BOOST_CHECK_EQUAL(grid.size(true), nBins + 2ul);
0393 
0394   const std::array<std::size_t, 1ul> numLocalBins = grid.numLocalBins();
0395   BOOST_CHECK_EQUAL(numLocalBins[0ul], nBins);
0396 
0397   std::array<std::vector<std::size_t>, 1ul> navigation;
0398   navigation[0ul].resize(nBins);
0399   std::iota(navigation[0ul].begin(), navigation[0ul].end(), 1ul);
0400 
0401   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis> gridStart =
0402       grid.begin(navigation);
0403   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis> gridStop =
0404       grid.end(navigation);
0405   std::size_t numIterations = 0ul;
0406   for (; gridStart != gridStop; ++gridStart) {
0407     ++numIterations;
0408   }
0409   BOOST_CHECK_EQUAL(numIterations, grid.size(false));
0410 }
0411 
0412 BOOST_AUTO_TEST_CASE(grid_iteration_test_2d_local) {
0413   const std::size_t nBins = 10ul;
0414   Acts::detail::EquidistantAxis xAxis(0, 100, nBins);
0415   Acts::detail::EquidistantAxis yAxis(0, 100, nBins);
0416   Acts::Grid<double, Acts::detail::EquidistantAxis,
0417              Acts::detail::EquidistantAxis>
0418       grid(std::make_tuple(std::move(xAxis), std::move(yAxis)));
0419 
0420   // test general properties
0421   BOOST_CHECK_EQUAL(grid.size(false), nBins * nBins);
0422   BOOST_CHECK_EQUAL(grid.size(true), (nBins + 2ul) * (nBins + 2ul));
0423 
0424   const std::array<std::size_t, 2ul> numLocalBins = grid.numLocalBins();
0425   BOOST_CHECK_EQUAL(numLocalBins[0ul], nBins);
0426   BOOST_CHECK_EQUAL(numLocalBins[1ul], nBins);
0427 
0428   std::array<std::vector<std::size_t>, 2ul> navigation;
0429   navigation[0ul].resize(nBins);
0430   navigation[1ul].resize(nBins);
0431   for (std::size_t i(0ul); i < 2ul; ++i) {
0432     std::iota(navigation[i].begin(), navigation[i].end(), 1ul);
0433   }
0434 
0435   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis,
0436                           Acts::detail::EquidistantAxis>
0437       gridStart = grid.begin(navigation);
0438   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis,
0439                           Acts::detail::EquidistantAxis>
0440       gridStop = grid.end(navigation);
0441   std::size_t numIterations = 0ul;
0442   for (; gridStart != gridStop; gridStart++) {
0443     ++numIterations;
0444   }
0445   BOOST_CHECK_EQUAL(numIterations, grid.size(false));
0446 }
0447 
0448 BOOST_AUTO_TEST_CASE(grid_iteration_test_3d_local) {
0449   const std::size_t nBins = 10ul;
0450   const std::size_t nBinsZ = 20ul;
0451   Acts::detail::EquidistantAxis xAxis(0, 100, nBins);
0452   Acts::detail::EquidistantAxis yAxis(0, 100, nBins);
0453   Acts::detail::EquidistantAxis zAxis(0, 100, nBinsZ);
0454   Acts::Grid<double, Acts::detail::EquidistantAxis,
0455              Acts::detail::EquidistantAxis, Acts::detail::EquidistantAxis>
0456       grid(std::make_tuple(std::move(xAxis), std::move(yAxis),
0457                            std::move(zAxis)));
0458 
0459   // test general properties
0460   BOOST_CHECK_EQUAL(grid.size(false), nBins * nBins * nBinsZ);
0461   BOOST_CHECK_EQUAL(grid.size(true),
0462                     (nBins + 2ul) * (nBins + 2ul) * (nBinsZ + 2ul));
0463 
0464   const std::array<std::size_t, 3ul> numLocalBins = grid.numLocalBins();
0465   BOOST_CHECK_EQUAL(numLocalBins[0ul], nBins);
0466   BOOST_CHECK_EQUAL(numLocalBins[1ul], nBins);
0467   BOOST_CHECK_EQUAL(numLocalBins[2ul], nBinsZ);
0468 
0469   std::array<std::vector<std::size_t>, 3ul> navigation;
0470   navigation[0ul].resize(nBins);
0471   navigation[1ul].resize(nBins);
0472   navigation[2ul].resize(nBinsZ);
0473   for (std::size_t i(0ul); i < 3ul; ++i) {
0474     std::iota(navigation[i].begin(), navigation[i].end(), 1ul);
0475   }
0476 
0477   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis,
0478                           Acts::detail::EquidistantAxis,
0479                           Acts::detail::EquidistantAxis>
0480       gridStart = grid.begin(navigation);
0481   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis,
0482                           Acts::detail::EquidistantAxis,
0483                           Acts::detail::EquidistantAxis>
0484       gridStop = grid.end(navigation);
0485   std::size_t numIterations = 0ul;
0486   for (; gridStart != gridStop; ++gridStart) {
0487     ++numIterations;
0488   }
0489   BOOST_CHECK_EQUAL(numIterations, grid.size(false));
0490 }
0491 
0492 BOOST_AUTO_TEST_CASE(grid_iteration_test_3d_local_custom_navigation) {
0493   const std::size_t nBins = 10ul;
0494   const std::size_t nBinsZ = 20ul;
0495   Acts::detail::EquidistantAxis xAxis(0, 100, nBins);
0496   Acts::detail::EquidistantAxis yAxis(0, 100, nBins);
0497   Acts::detail::EquidistantAxis zAxis(0, 100, nBinsZ);
0498   Acts::Grid<double, Acts::detail::EquidistantAxis,
0499              Acts::detail::EquidistantAxis, Acts::detail::EquidistantAxis>
0500       grid(std::make_tuple(std::move(xAxis), std::move(yAxis),
0501                            std::move(zAxis)));
0502 
0503   // test general properties
0504   BOOST_CHECK_EQUAL(grid.size(false), nBins * nBins * nBinsZ);
0505   BOOST_CHECK_EQUAL(grid.size(true),
0506                     (nBins + 2ul) * (nBins + 2ul) * (nBinsZ + 2ul));
0507 
0508   const std::array<std::size_t, 3ul> numLocalBins = grid.numLocalBins();
0509   BOOST_CHECK_EQUAL(numLocalBins[0ul], nBins);
0510   BOOST_CHECK_EQUAL(numLocalBins[1ul], nBins);
0511   BOOST_CHECK_EQUAL(numLocalBins[2ul], nBinsZ);
0512 
0513   std::array<std::vector<std::size_t>, 3ul> navigation;
0514   navigation[0ul] = {1ul, 5ul, 3ul, 2ul, 9ul, 10ul, 4ul, 6ul, 8ul, 7ul};
0515   navigation[1ul] = {6ul, 8ul, 7ul, 1ul, 5ul, 3ul, 2ul, 9ul, 10ul, 4ul};
0516   navigation[2ul] = {1ul,  5ul,  3ul,  2ul,  9ul,  10ul, 4ul,
0517                      6ul,  8ul,  7ul,  11ul, 15ul, 13ul, 12ul,
0518                      19ul, 20ul, 14ul, 16ul, 18ul, 17ul};
0519 
0520   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis,
0521                           Acts::detail::EquidistantAxis,
0522                           Acts::detail::EquidistantAxis>
0523       gridStart = grid.begin(navigation);
0524   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis,
0525                           Acts::detail::EquidistantAxis,
0526                           Acts::detail::EquidistantAxis>
0527       gridStop = grid.end(navigation);
0528   std::size_t numIterations = 0ul;
0529   for (; gridStart != gridStop; ++gridStart) {
0530     ++numIterations;
0531   }
0532   BOOST_CHECK_EQUAL(numIterations, grid.size(false));
0533 }
0534 
0535 BOOST_AUTO_TEST_CASE(grid_iteration_test_5d_local_custom_subnavigation) {
0536   const std::size_t nBins = 10ul;
0537   const std::size_t nBinsZ = 20ul;
0538   const std::size_t nBinsJK = 5ul;
0539   Acts::detail::EquidistantAxis xAxis(0, 100, nBins);
0540   Acts::detail::EquidistantAxis yAxis(0, 100, nBins);
0541   Acts::detail::EquidistantAxis zAxis(0, 100, nBinsZ);
0542   Acts::detail::EquidistantAxis jAxis(0, 100, nBinsJK);
0543   Acts::detail::EquidistantAxis kAxis(0, 100, nBinsJK);
0544   Acts::Grid<double, Acts::detail::EquidistantAxis,
0545              Acts::detail::EquidistantAxis, Acts::detail::EquidistantAxis,
0546              Acts::detail::EquidistantAxis, Acts::detail::EquidistantAxis>
0547       grid(std::make_tuple(std::move(xAxis), std::move(yAxis), std::move(zAxis),
0548                            std::move(jAxis), std::move(kAxis)));
0549 
0550   // test general properties
0551   BOOST_CHECK_EQUAL(grid.size(false),
0552                     nBins * nBins * nBinsZ * nBinsJK * nBinsJK);
0553   BOOST_CHECK_EQUAL(grid.size(true), (nBins + 2ul) * (nBins + 2ul) *
0554                                          (nBinsZ + 2ul) * (nBinsJK + 2ul) *
0555                                          (nBinsJK + 2ul));
0556 
0557   const std::array<std::size_t, 5ul> numLocalBins = grid.numLocalBins();
0558   BOOST_CHECK_EQUAL(numLocalBins[0ul], nBins);
0559   BOOST_CHECK_EQUAL(numLocalBins[1ul], nBins);
0560   BOOST_CHECK_EQUAL(numLocalBins[2ul], nBinsZ);
0561   BOOST_CHECK_EQUAL(numLocalBins[3ul], nBinsJK);
0562   BOOST_CHECK_EQUAL(numLocalBins[4ul], nBinsJK);
0563 
0564   // Iterate only on a few bins
0565   std::array<std::vector<std::size_t>, 5ul> navigation;
0566   navigation[0ul] = {1ul, 5ul, 3ul, 2ul, 9ul, 10ul, 4ul, 6ul, 8ul, 7ul};
0567   navigation[1ul] = {6ul, 8ul, 7ul, 1ul};
0568   navigation[2ul] = {1ul, 5ul};
0569   navigation[3ul] = {5ul, 3ul, 2ul};
0570   navigation[4ul] = {2ul};
0571 
0572   Acts::GridLocalIterator<
0573       double, Acts::detail::EquidistantAxis, Acts::detail::EquidistantAxis,
0574       Acts::detail::EquidistantAxis, Acts::detail::EquidistantAxis,
0575       Acts::detail::EquidistantAxis>
0576       gridStart = grid.begin(navigation);
0577   Acts::GridLocalIterator<
0578       double, Acts::detail::EquidistantAxis, Acts::detail::EquidistantAxis,
0579       Acts::detail::EquidistantAxis, Acts::detail::EquidistantAxis,
0580       Acts::detail::EquidistantAxis>
0581       gridStop = grid.end(navigation);
0582   std::size_t numIterations = 0ul;
0583   for (; gridStart != gridStop; ++gridStart) {
0584     ++numIterations;
0585   }
0586 
0587   std::size_t expectedIterations = 1ul;
0588   for (std::size_t i(0ul); i < 5ul; ++i) {
0589     expectedIterations *= navigation[i].size();
0590   }
0591 
0592   BOOST_CHECK_EQUAL(numIterations, expectedIterations);
0593 }
0594 
0595 BOOST_AUTO_TEST_CASE(grid_iteration_test_3d_local_norepetitions) {
0596   const std::size_t nBinsX = 5ul;
0597   const std::size_t nBinsY = 5ul;
0598   const std::size_t nBinsZ = 2ul;
0599   Acts::detail::EquidistantAxis xAxis(0, 100, nBinsX);
0600   Acts::detail::EquidistantAxis yAxis(0, 100, nBinsY);
0601   Acts::detail::EquidistantAxis zAxis(0, 100, nBinsZ);
0602   Acts::Grid<double, Acts::detail::EquidistantAxis,
0603              Acts::detail::EquidistantAxis, Acts::detail::EquidistantAxis>
0604       grid(std::make_tuple(std::move(xAxis), std::move(yAxis),
0605                            std::move(zAxis)));
0606 
0607   std::array<std::vector<std::size_t>, 3ul> navigation;
0608   navigation[0ul] = {1ul, 5ul, 3ul, 2ul, 4ul};
0609   navigation[1ul] = {4ul, 2ul, 3ul, 5ul, 1ul};
0610   navigation[2ul] = {2ul, 1ul};
0611 
0612   std::size_t expectedIterations =
0613       navigation[0ul].size() * navigation[1ul].size() * navigation[2ul].size();
0614 
0615   // Set the allowed values
0616   std::unordered_set<std::size_t> allowed_global_bins;
0617   for (std::size_t x : navigation[0ul]) {
0618     for (std::size_t y : navigation[1ul]) {
0619       for (std::size_t z : navigation[2ul]) {
0620         std::array<std::size_t, 3ul> locPos({x, y, z});
0621         std::size_t globPos = grid.globalBinFromLocalBins(locPos);
0622         BOOST_CHECK_EQUAL(
0623             allowed_global_bins.find(globPos) != allowed_global_bins.end(),
0624             false);
0625         allowed_global_bins.insert(globPos);
0626       }
0627     }
0628   }
0629 
0630   BOOST_CHECK_EQUAL(expectedIterations, allowed_global_bins.size());
0631 
0632   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis,
0633                           Acts::detail::EquidistantAxis,
0634                           Acts::detail::EquidistantAxis>
0635       gridStart = grid.begin(navigation);
0636   Acts::GridLocalIterator<double, Acts::detail::EquidistantAxis,
0637                           Acts::detail::EquidistantAxis,
0638                           Acts::detail::EquidistantAxis>
0639       gridStop = grid.end(navigation);
0640 
0641   // Prepare visited values
0642   std::unordered_set<std::size_t> visited_global_bins;
0643 
0644   std::size_t numIterations = 0ul;
0645   for (; gridStart != gridStop; ++gridStart) {
0646     ++numIterations;
0647     std::array<std::size_t, 3ul> locPos = gridStart.localBinsIndices();
0648     std::size_t globPos = grid.globalBinFromLocalBins(locPos);
0649     BOOST_CHECK_EQUAL(
0650         visited_global_bins.find(globPos) != visited_global_bins.end(), false);
0651     BOOST_CHECK_EQUAL(
0652         allowed_global_bins.find(globPos) != allowed_global_bins.end(), true);
0653     visited_global_bins.insert(globPos);
0654   }
0655 
0656   BOOST_CHECK_EQUAL(expectedIterations, numIterations);
0657   BOOST_CHECK_EQUAL(visited_global_bins.size(), allowed_global_bins.size());
0658 }
0659 
0660 }  // namespace Acts::Test