Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-29 07:55:41

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