Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:33

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/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/InternalNavigation.hpp"
0016 #include "Acts/Navigation/NavigationStateUpdaters.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/Axis.hpp"
0023 #include "Acts/Utilities/AxisDefinitions.hpp"
0024 #include "Acts/Utilities/BinningType.hpp"
0025 #include "Acts/Utilities/Enumerate.hpp"
0026 #include "Acts/Utilities/Grid.hpp"
0027 #include "Acts/Utilities/Logger.hpp"
0028 
0029 #include <array>
0030 #include <cmath>
0031 #include <cstddef>
0032 #include <memory>
0033 #include <numbers>
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 axisX(AxisBound, -5., 5., 5);
0124   Axis axisY(AxisBound, -5., 5., 5);
0125   Grid gridXY(Type<std::vector<unsigned int>>, std::move(axisX),
0126               std::move(axisY));
0127 
0128   // Indexed Surface grid
0129   IndexedSurfacesNavigation<decltype(gridXY)> indexedGridXY(
0130       std::move(gridXY), {AxisDirection::AxisX, AxisDirection::AxisY});
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 axisX(AxisBound, -5., 5., 5);
0160   Axis axisY(AxisBound, -5., 5., 5);
0161   Grid gridXY(Type<std::vector<unsigned int>>, std::move(axisX),
0162               std::move(axisY));
0163 
0164   // Indexed Surface grid
0165   IndexedSurfacesNavigation<decltype(gridXY)> indexedGridXY(
0166       std::move(gridXY), {AxisDirection::AxisX, AxisDirection::AxisY});
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   AxisDirectionReferenceGenerator<AxisDirection::AxisX> 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 axisX(AxisBound, -5., 5., 5);
0197   Axis axisY(AxisBound, -5., 5., 5);
0198   Grid gridXY(Type<std::vector<unsigned int>>, std::move(axisX),
0199               std::move(axisY));
0200 
0201   // Indexed Surface grid
0202   IndexedSurfacesNavigation<decltype(gridXY)> indexedGridXY(
0203       std::move(gridXY), {AxisDirection::AxisX, AxisDirection::AxisY});
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 axisX(AxisBound, -9., 9., 9);
0234   Axis axisY(AxisBound, -9., 9., 9);
0235   Grid gridXY(Type<std::vector<unsigned int>>, std::move(axisX),
0236               std::move(axisY));
0237 
0238   // Indexed Surface grid
0239   IndexedSurfacesNavigation<decltype(gridXY)> indexedGridXY(
0240       std::move(gridXY), {AxisDirection::AxisX, AxisDirection::AxisY});
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 axisZ(AxisBound, -9., 9., 9);
0271   Axis axisPhi(AxisClosed, -std::numbers::pi, std::numbers::pi, 36);
0272   Grid gridZPhi(Type<std::vector<unsigned int>>, std::move(axisZ),
0273                 std::move(axisPhi));
0274 
0275   // Indexed Surface grid
0276   IndexedSurfacesNavigation<decltype(gridZPhi)> indexedGridZPhi(
0277       std::move(gridZPhi), {AxisDirection::AxisZ, AxisDirection::AxisPhi});
0278 
0279   auto cBounds =
0280       std::make_shared<CylinderBounds>(10, 2., std::numbers::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(
0304       "Testing one surface at std::numbers::pi jump, with polyhedron "
0305       "generator");
0306 
0307   // z-phi Axes & Grid
0308   Axis axisZ(AxisBound, -9., 9., 9);
0309   Axis axisPhi(AxisClosed, -std::numbers::pi, std::numbers::pi, 36);
0310   Grid gridZPhi(Type<std::vector<unsigned int>>, std::move(axisZ),
0311                 std::move(axisPhi));
0312 
0313   // Indexed Surface grid
0314   IndexedSurfacesNavigation<decltype(gridZPhi)> indexedGridZPhi(
0315       std::move(gridZPhi), {AxisDirection::AxisZ, AxisDirection::AxisPhi});
0316 
0317   auto cBounds =
0318       std::make_shared<CylinderBounds>(10, 2., std::numbers::pi / 10, 0.);
0319   auto tf =
0320       AngleAxis3(std::numbers::pi, Vector3::UnitZ()) * Transform3::Identity();
0321   auto cSurface = Surface::makeShared<CylinderSurface>(tf, std::move(cBounds));
0322 
0323   // The Filler instance and a center based generator
0324   IndexedGridFiller filler{{0u, 0u}};
0325   filler.oLogger = getDefaultLogger("IndexGridFiller", Logging::DEBUG);
0326 
0327   PolyhedronReferenceGenerator<1u, true> generator;
0328   std::vector<std::shared_ptr<Surface>> surfaces = {cSurface};
0329 
0330   // Fill the surface
0331   filler.fill(tContext, indexedGridZPhi, surfaces, generator);
0332 
0333   std::size_t nonEmptyBins =
0334       countBins<decltype(indexedGridZPhi)>(indexedGridZPhi);
0335   ACTS_INFO("- filled " << nonEmptyBins << " bins of the grid.");
0336   BOOST_CHECK_EQUAL(nonEmptyBins, 9u);
0337 }
0338 
0339 BOOST_AUTO_TEST_SUITE_END()