Back to home page

sPhenix code displayed by LXR

 
 

    


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

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2023 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/Definitions/Algebra.hpp"
0012 #include "Acts/Detector/detail/IndexedGridFiller.hpp"
0013 #include "Acts/Detector/detail/ReferenceGenerators.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/Navigation/NavigationStateUpdaters.hpp"
0016 #include "Acts/Navigation/SurfaceCandidatesUpdaters.hpp"
0017 #include "Acts/Surfaces/CylinderBounds.hpp"
0018 #include "Acts/Surfaces/CylinderSurface.hpp"
0019 #include "Acts/Surfaces/PlaneSurface.hpp"
0020 #include "Acts/Surfaces/RectangleBounds.hpp"
0021 #include "Acts/Surfaces/Surface.hpp"
0022 #include "Acts/Utilities/BinningType.hpp"
0023 #include "Acts/Utilities/Enumerate.hpp"
0024 #include "Acts/Utilities/Grid.hpp"
0025 #include "Acts/Utilities/Logger.hpp"
0026 #include "Acts/Utilities/TypeTraits.hpp"
0027 #include "Acts/Utilities/detail/Axis.hpp"
0028 #include "Acts/Utilities/detail/AxisFwd.hpp"
0029 
0030 #include <array>
0031 #include <cmath>
0032 #include <cstddef>
0033 #include <memory>
0034 #include <ostream>
0035 #include <set>
0036 #include <utility>
0037 #include <vector>
0038 
0039 using namespace Acts;
0040 using namespace Acts::detail;
0041 using namespace Acts::Experimental;
0042 using namespace Acts::Experimental::detail;
0043 
0044 GeometryContext tContext;
0045 Logging::Level logLevel = Logging::VERBOSE;
0046 
0047 namespace {
0048 
0049 /// Helper method to count how many bins are not empty
0050 template <typename indexed_surface_grid>
0051 std::size_t countBins(const indexed_surface_grid& isGrid) {
0052   std::size_t nonEmptyBins = 0u;
0053   for (std::size_t igb = 0u; igb < isGrid.grid.size(); ++igb) {
0054     const auto& gb = isGrid.grid.at(igb);
0055     if (!gb.empty()) {
0056       ++nonEmptyBins;
0057     }
0058   }
0059   return nonEmptyBins;
0060 }
0061 
0062 }  // namespace
0063 
0064 BOOST_AUTO_TEST_SUITE(Detector)
0065 
0066 BOOST_AUTO_TEST_CASE(BinSequence) {
0067   ACTS_LOCAL_LOGGER(getDefaultLogger("*** Pre-Test", logLevel));
0068   ACTS_INFO("Testing bin sequence generators.");
0069 
0070   // Test standard bound local bin sequence
0071   auto seq48e0b10B = binSequence({4u, 8u}, 0u, 10u, AxisBoundaryType::Bound);
0072   std::vector<std::size_t> reference = {4u, 5u, 6u, 7u, 8u};
0073   BOOST_CHECK(seq48e0b10B == reference);
0074 
0075   // Test bound local bin sequence with expansion 1u
0076   auto seq48e1b10B = binSequence({4u, 8u}, 1u, 10u, AxisBoundaryType::Bound);
0077   reference = {3u, 4u, 5u, 6u, 7u, 8u, 9u};
0078   BOOST_CHECK(seq48e1b10B == reference);
0079 
0080   // Test bound local bin sequence with expansion 3u - clipped to max bin 10u
0081   auto seq48e3b10B = binSequence({4u, 8u}, 3u, 10u, AxisBoundaryType::Bound);
0082   reference = {1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u};
0083   BOOST_CHECK(seq48e3b10B == reference);
0084 
0085   // Test open bin sequence with overflow filling
0086   auto seq48e3b10O = binSequence({4u, 8u}, 3u, 10u, AxisBoundaryType::Open);
0087   reference = {1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u};
0088   BOOST_CHECK(seq48e3b10O == reference);
0089 
0090   // Test standard closed local bins
0091   auto seq48e0b10C = binSequence({4u, 8u}, 0u, 20u, AxisBoundaryType::Closed);
0092   reference = {4u, 5u, 6u, 7u, 8u};
0093   BOOST_CHECK(seq48e0b10C == reference);
0094 
0095   // Test closed local bins with expansion
0096   auto seq48e1b10C = binSequence({4u, 8u}, 1u, 20u, AxisBoundaryType::Closed);
0097   reference = {3u, 4u, 5u, 6u, 7u, 8u, 9u};
0098   BOOST_CHECK(seq48e1b10C == reference);
0099 
0100   // Test closed local bins with expansion over bin boundary
0101   auto seq1029e1b20C =
0102       binSequence({19u, 20u}, 1u, 20u, AxisBoundaryType::Closed);
0103   reference = {1u, 18u, 19u, 20u};
0104   BOOST_CHECK(seq1029e1b20C == reference);
0105 
0106   // Test closed local bins with bin boundary jump
0107   auto seq218e0b20C = binSequence({2u, 18u}, 0u, 20u, AxisBoundaryType::Closed);
0108   reference = {1u, 2u, 18u, 19u, 20u};
0109   BOOST_CHECK(seq218e0b20C == reference);
0110 
0111   // Test closed local bins with bin boundary jump with extension
0112   auto seq218e2b20C = binSequence({2u, 18u}, 2u, 20u, AxisBoundaryType::Closed);
0113   reference = {1u, 2u, 3u, 4u, 16u, 17u, 18u, 19u, 20u};
0114   BOOST_CHECK(seq218e2b20C == reference);
0115 }
0116 
0117 BOOST_AUTO_TEST_CASE(IndexGridXYOneSurfaceCenter) {
0118   ACTS_LOCAL_LOGGER(getDefaultLogger("*** Test 0", logLevel));
0119   ACTS_INFO("Testing X-Y grid.");
0120   ACTS_INFO("Testing one surface with center generator, should lead to 1 bin.");
0121 
0122   // x-y Axes & Grid
0123   Axis<AxisType::Equidistant, AxisBoundaryType::Bound> axisX(-5., 5., 5);
0124   Axis<AxisType::Equidistant, AxisBoundaryType::Bound> axisY(-5., 5., 5);
0125   Grid<std::vector<unsigned int>, decltype(axisX), decltype(axisY)> gridXY(
0126       {axisX, axisY});
0127 
0128   // Indexed Surface grid
0129   IndexedSurfacesImpl<decltype(gridXY)> indexedGridXY(std::move(gridXY),
0130                                                       {binX, binY});
0131 
0132   // Create a single surface in the center
0133   auto rBounds = std::make_shared<RectangleBounds>(4., 4.);
0134   auto pSurface = Surface::makeShared<PlaneSurface>(Transform3::Identity(),
0135                                                     std::move(rBounds));
0136 
0137   // The Filler instance and a center based generator
0138   IndexedGridFiller filler{{}};
0139   filler.oLogger = getDefaultLogger("IndexGridFiller", Logging::VERBOSE);
0140   CenterReferenceGenerator generator;
0141   std::vector<std::shared_ptr<Surface>> surfaces = {pSurface};
0142 
0143   // Fill the surface
0144   filler.fill(tContext, indexedGridXY, surfaces, generator);
0145 
0146   std::size_t nonEmptyBins = countBins<decltype(indexedGridXY)>(indexedGridXY);
0147   // Check the correct number of filled bins
0148   ACTS_INFO("- filled " << nonEmptyBins << " bins of the grid.");
0149   BOOST_CHECK_EQUAL(nonEmptyBins, 1u);
0150 }
0151 
0152 BOOST_AUTO_TEST_CASE(IndexGridXYOneSurfaceBinValue) {
0153   ACTS_LOCAL_LOGGER(getDefaultLogger("*** Test 1", logLevel));
0154   ACTS_INFO("Testing X-Y grid.");
0155   ACTS_INFO(
0156       "Testing one surface with bin value generator, should lead to 1 bin.");
0157 
0158   // x-y Axes & Grid
0159   Axis<AxisType::Equidistant, AxisBoundaryType::Bound> axisX(-5., 5., 5);
0160   Axis<AxisType::Equidistant, AxisBoundaryType::Bound> axisY(-5., 5., 5);
0161   Grid<std::vector<unsigned int>, decltype(axisX), decltype(axisY)> gridXY(
0162       {axisX, axisY});
0163 
0164   // Indexed Surface grid
0165   IndexedSurfacesImpl<decltype(gridXY)> indexedGridXY(std::move(gridXY),
0166                                                       {binX, binY});
0167 
0168   // Create a single surface in the center
0169   auto rBounds = std::make_shared<RectangleBounds>(4., 4.);
0170   auto pSurface = Surface::makeShared<PlaneSurface>(Transform3::Identity(),
0171                                                     std::move(rBounds));
0172 
0173   // The Filler instance and a center based generator
0174   IndexedGridFiller filler{{}};
0175   filler.oLogger = getDefaultLogger("IndexGridFiller", Logging::VERBOSE);
0176 
0177   BinningValueReferenceGenerator<binX> generator;
0178   std::vector<std::shared_ptr<Surface>> surfaces = {pSurface};
0179 
0180   // Fill the surface
0181   filler.fill(tContext, indexedGridXY, surfaces, generator);
0182 
0183   std::size_t nonEmptyBins = countBins<decltype(indexedGridXY)>(indexedGridXY);
0184   ACTS_INFO("- filled " << nonEmptyBins << " bins of the grid.");
0185   BOOST_CHECK_EQUAL(nonEmptyBins, 1u);
0186 }
0187 
0188 BOOST_AUTO_TEST_CASE(IndexGridXYOneSurfacePolyhedron) {
0189   ACTS_LOCAL_LOGGER(getDefaultLogger("*** Test 2", logLevel));
0190   ACTS_INFO("Testing X-Y grid.");
0191   ACTS_INFO(
0192       "Testing one surface with polyhedron generator without expansion, should "
0193       "lead to 5 unique bins, 25 total bins filled");
0194 
0195   // x-y Axes & Grid
0196   Axis<AxisType::Equidistant, AxisBoundaryType::Bound> axisX(-5., 5., 5);
0197   Axis<AxisType::Equidistant, AxisBoundaryType::Bound> axisY(-5., 5., 5);
0198   Grid<std::vector<unsigned int>, decltype(axisX), decltype(axisY)> gridXY(
0199       {axisX, axisY});
0200 
0201   // Indexed Surface grid
0202   IndexedSurfacesImpl<decltype(gridXY)> indexedGridXY(std::move(gridXY),
0203                                                       {binX, binY});
0204 
0205   // Create a single surface in the center
0206   auto rBounds = std::make_shared<RectangleBounds>(4., 4.);
0207   auto pSurface = Surface::makeShared<PlaneSurface>(Transform3::Identity(),
0208                                                     std::move(rBounds));
0209 
0210   // The Filler instance and a center based generator
0211   IndexedGridFiller filler{{0u, 0u}};
0212   filler.oLogger = getDefaultLogger("IndexGridFiller", Logging::DEBUG);
0213 
0214   PolyhedronReferenceGenerator<1u, true> generator;
0215   std::vector<std::shared_ptr<Surface>> surfaces = {pSurface};
0216 
0217   // Fill the surface
0218   filler.fill(tContext, indexedGridXY, surfaces, generator);
0219 
0220   std::size_t nonEmptyBins = countBins<decltype(indexedGridXY)>(indexedGridXY);
0221   ACTS_INFO("- filled " << nonEmptyBins << " bins of the grid.");
0222   BOOST_CHECK_EQUAL(nonEmptyBins, 25u);
0223 }
0224 
0225 BOOST_AUTO_TEST_CASE(IndexGridXYOneSurfacePolyhedronBinExpansion) {
0226   ACTS_LOCAL_LOGGER(getDefaultLogger("*** Test 3", logLevel));
0227   ACTS_INFO("Testing X-Y grid.");
0228   ACTS_INFO(
0229       "Testing one surface with polyhedron generator and expansion, should "
0230       "lead to 5 unique bins, 49 total bins filled");
0231 
0232   // x-y Axes & Grid
0233   Axis<AxisType::Equidistant, AxisBoundaryType::Bound> axisX(-9., 9., 9);
0234   Axis<AxisType::Equidistant, AxisBoundaryType::Bound> axisY(-9., 9., 9);
0235   Grid<std::vector<unsigned int>, decltype(axisX), decltype(axisY)> gridXY(
0236       {axisX, axisY});
0237 
0238   // Indexed Surface grid
0239   IndexedSurfacesImpl<decltype(gridXY)> indexedGridXY(std::move(gridXY),
0240                                                       {binX, binY});
0241 
0242   // Create a single surface in the center
0243   auto rBounds = std::make_shared<RectangleBounds>(4., 4.);
0244   auto pSurface = Surface::makeShared<PlaneSurface>(Transform3::Identity(),
0245                                                     std::move(rBounds));
0246 
0247   // The Filler instance and a center based generator
0248   IndexedGridFiller filler{{1u, 1u}};
0249   filler.oLogger = getDefaultLogger("IndexGridFiller", Logging::DEBUG);
0250 
0251   PolyhedronReferenceGenerator<1u, true> generator;
0252   std::vector<std::shared_ptr<Surface>> surfaces = {pSurface};
0253 
0254   // Fill the surface
0255   filler.fill(tContext, indexedGridXY, surfaces, generator);
0256 
0257   std::size_t nonEmptyBins = countBins<decltype(indexedGridXY)>(indexedGridXY);
0258   ACTS_INFO("- filled " << nonEmptyBins << " bins of the grid.");
0259   BOOST_CHECK_EQUAL(nonEmptyBins, 49u);
0260 }
0261 
0262 BOOST_AUTO_TEST_CASE(IndexGridZPhiYOneSurfacePolyhedronBinExpansion) {
0263   ACTS_LOCAL_LOGGER(getDefaultLogger("*** Test 4", logLevel));
0264   ACTS_INFO("Testing Phi-Z grid.");
0265   ACTS_INFO(
0266       "Testing one surface with polyhedron generator without expansion, should "
0267       "lead to 5 unique bins, 6 total bins filled");
0268 
0269   // z-phi Axes & Grid
0270   Axis<AxisType::Equidistant, AxisBoundaryType::Bound> axisZ(-9., 9., 9);
0271   Axis<AxisType::Equidistant, AxisBoundaryType::Closed> axisPhi(-M_PI, M_PI,
0272                                                                 36);
0273   Grid<std::vector<unsigned int>, decltype(axisZ), decltype(axisPhi)> gridZPhi(
0274       {axisZ, axisPhi});
0275 
0276   // Indexed Surface grid
0277   IndexedSurfacesImpl<decltype(gridZPhi)> indexedGridZPhi(std::move(gridZPhi),
0278                                                           {binZ, binPhi});
0279 
0280   auto cBounds = std::make_shared<CylinderBounds>(10, 2., M_PI / 30, 0.);
0281   auto cSurface = Surface::makeShared<CylinderSurface>(Transform3::Identity(),
0282                                                        std::move(cBounds));
0283 
0284   // The Filler instance and a center based generator
0285   IndexedGridFiller filler{{0u, 0u}};
0286   filler.oLogger = getDefaultLogger("IndexGridFiller", Logging::DEBUG);
0287 
0288   PolyhedronReferenceGenerator<1u, true> generator;
0289   std::vector<std::shared_ptr<Surface>> surfaces = {cSurface};
0290 
0291   // Fill the surface
0292   filler.fill(tContext, indexedGridZPhi, surfaces, generator);
0293 
0294   std::size_t nonEmptyBins =
0295       countBins<decltype(indexedGridZPhi)>(indexedGridZPhi);
0296   ACTS_INFO("- filled " << nonEmptyBins << " bins of the grid.");
0297   BOOST_CHECK_EQUAL(nonEmptyBins, 6u);
0298 }
0299 
0300 BOOST_AUTO_TEST_CASE(IndexGridZPhiYOneSurfaceMPIPolyhedronBinExpansion) {
0301   ACTS_LOCAL_LOGGER(getDefaultLogger("*** Test 4", logLevel));
0302   ACTS_INFO("Testing Phi-Z grid.");
0303   ACTS_INFO("Testing one surface at M_PI jump, with polyhedron generator");
0304 
0305   // z-phi Axes & Grid
0306   Axis<AxisType::Equidistant, AxisBoundaryType::Bound> axisZ(-9., 9., 9);
0307   Axis<AxisType::Equidistant, AxisBoundaryType::Closed> axisPhi(-M_PI, M_PI,
0308                                                                 36);
0309   Grid<std::vector<unsigned int>, decltype(axisZ), decltype(axisPhi)> gridZPhi(
0310       {axisZ, axisPhi});
0311 
0312   // Indexed Surface grid
0313   IndexedSurfacesImpl<decltype(gridZPhi)> indexedGridZPhi(std::move(gridZPhi),
0314                                                           {binZ, binPhi});
0315 
0316   auto cBounds = std::make_shared<CylinderBounds>(10, 2., M_PI / 10, 0.);
0317   auto tf = AngleAxis3(M_PI, Vector3::UnitZ()) * Transform3::Identity();
0318   auto cSurface = Surface::makeShared<CylinderSurface>(tf, std::move(cBounds));
0319 
0320   // The Filler instance and a center based generator
0321   IndexedGridFiller filler{{0u, 0u}};
0322   filler.oLogger = getDefaultLogger("IndexGridFiller", Logging::DEBUG);
0323 
0324   PolyhedronReferenceGenerator<1u, true> generator;
0325   std::vector<std::shared_ptr<Surface>> surfaces = {cSurface};
0326 
0327   // Fill the surface
0328   filler.fill(tContext, indexedGridZPhi, surfaces, generator);
0329 
0330   std::size_t nonEmptyBins =
0331       countBins<decltype(indexedGridZPhi)>(indexedGridZPhi);
0332   ACTS_INFO("- filled " << nonEmptyBins << " bins of the grid.");
0333   BOOST_CHECK_EQUAL(nonEmptyBins, 9u);
0334 }
0335 
0336 BOOST_AUTO_TEST_SUITE_END()