Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-31 08:18: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/Seeding/SphericalSpacePointGrid.hpp"
0012 #include "Acts/Utilities/GridBinFinder.hpp"
0013 
0014 #include <cmath>
0015 #include <numbers>
0016 
0017 namespace Acts::Test {
0018 
0019 namespace {
0020 
0021 // Minimal valid configuration for the (phi, eta, r) grid. bFieldInZ = 0 makes
0022 // the constructor use maxPhiBins directly, so we do not need a physical helix
0023 // sizing for the phi axis in this unit test. Four eta bins: [-3,-1], [-1,0],
0024 // [0,1], [1,3]; two r bins: [0,100], [100,200].
0025 Acts::Experimental::SphericalSpacePointGrid::Config makeConfig() {
0026   Acts::Experimental::SphericalSpacePointGrid::Config cfg;
0027   cfg.bFieldInZ = 0;
0028   cfg.maxPhiBins = 20;
0029   cfg.phiMin = -std::numbers::pi_v<float>;
0030   cfg.phiMax = std::numbers::pi_v<float>;
0031   cfg.rMin = 0.f;
0032   cfg.rMax = 200.f;
0033   cfg.etaMin = -3.f;
0034   cfg.etaMax = 3.f;
0035   cfg.etaBinEdges = {-3.f, -1.f, 0.f, 1.f, 3.f};
0036   cfg.rBinEdges = {0.f, 100.f, 200.f};
0037   cfg.bottomBinFinder.emplace(1, 1, 0);
0038   cfg.topBinFinder.emplace(1, 1, 0);
0039   return cfg;
0040 }
0041 
0042 }  // namespace
0043 
0044 BOOST_AUTO_TEST_SUITE(SphericalSpacePointGridTests)
0045 
0046 // The grid bins on cot(theta) = z / r = sinh(eta) and stores sinh(etaBinEdges)
0047 // on the axis, so a space point falls into exactly the eta bin it belongs to.
0048 // We exercise that by looking up by cot(theta) = sinh(eta).
0049 BOOST_AUTO_TEST_CASE(BinsByCotThetaMatchEta) {
0050   Acts::Experimental::SphericalSpacePointGrid grid(makeConfig());
0051 
0052   BOOST_CHECK_GT(grid.numberOfBins(), 0u);
0053 
0054   const float phi = 0.f;
0055   const float r = 150.f;
0056   auto binAtEta = [&](float eta) {
0057     return grid.binIndex(phi, std::sinh(eta), r);
0058   };
0059 
0060   BOOST_REQUIRE(binAtEta(0.5f).has_value());
0061 
0062   // Two points in the same eta bin ([0,1]) map to the same global bin.
0063   BOOST_CHECK(binAtEta(0.5f) == binAtEta(0.7f));
0064   // Points in different eta bins map to different global bins.
0065   BOOST_CHECK(binAtEta(0.5f) != binAtEta(1.5f));   // [0,1] vs [1,3]
0066   BOOST_CHECK(binAtEta(0.5f) != binAtEta(-0.5f));  // [0,1] vs [-1,0]
0067   // The sinh mapping places the bin boundary exactly at the eta edge (eta = 1).
0068   BOOST_CHECK(binAtEta(0.99f) != binAtEta(1.01f));
0069   BOOST_CHECK(binAtEta(1.01f) == binAtEta(2.0f));  // both in [1,3]
0070 
0071   // The r axis separates points at the same (phi, eta) but different r.
0072   BOOST_CHECK(grid.binIndex(phi, std::sinh(0.5f), 50.f) !=
0073               grid.binIndex(phi, std::sinh(0.5f), 150.f));
0074 }
0075 
0076 // Points outside the eta acceptance (|eta| > etaMax) fall outside the grid and
0077 // yield no bin; inserting such a point is a no-op for the counter.
0078 BOOST_AUTO_TEST_CASE(OutOfAcceptanceHasNoBin) {
0079   Acts::Experimental::SphericalSpacePointGrid grid(makeConfig());
0080 
0081   const float phi = 0.f;
0082   const float r = 150.f;
0083   // eta = 5 is beyond etaMax = 3.
0084   BOOST_CHECK(!grid.binIndex(phi, std::sinh(5.f), r).has_value());
0085 
0086   const std::size_t before = grid.numberOfSpacePoints();
0087   const auto inserted = grid.insert(99, phi, std::sinh(5.f), r);
0088   BOOST_CHECK(!inserted.has_value());
0089   BOOST_CHECK_EQUAL(grid.numberOfSpacePoints(), before);
0090 }
0091 
0092 // When etaBinEdges is empty the grid builds equidistant eta bins from
0093 // etaMin/etaMax with deltaEtaMax width (the default production path). It must
0094 // still bin in eta.
0095 BOOST_AUTO_TEST_CASE(UniformEtaFallback) {
0096   auto cfg = makeConfig();
0097   cfg.etaBinEdges.clear();
0098   cfg.deltaEtaMax = 0.5f;  // etaMin=-3 .. etaMax=3 -> 12 bins
0099   Acts::Experimental::SphericalSpacePointGrid grid(cfg);
0100 
0101   BOOST_CHECK_GT(grid.numberOfBins(), 0u);
0102   const float phi = 0.f;
0103   const float r = 150.f;
0104   BOOST_CHECK(grid.binIndex(phi, std::sinh(-2.f), r) !=
0105               grid.binIndex(phi, std::sinh(2.f), r));
0106 }
0107 
0108 // Inserted space points land in the expected bins: two points in the same eta
0109 // bin share a bin, a third in a different eta bin is separate.
0110 BOOST_AUTO_TEST_CASE(InsertPlacesInExpectedBins) {
0111   Acts::Experimental::SphericalSpacePointGrid grid(makeConfig());
0112 
0113   const float phi = 0.f;
0114   const float r = 150.f;
0115   grid.insert(0, phi, std::sinh(0.5f), r);  // eta bin [0,1]
0116   grid.insert(1, phi, std::sinh(0.7f), r);  // same bin
0117   grid.insert(2, phi, std::sinh(1.5f), r);  // eta bin [1,3]
0118 
0119   BOOST_CHECK_EQUAL(grid.numberOfSpacePoints(), 3u);
0120 
0121   const auto binLow = grid.binIndex(phi, std::sinh(0.5f), r);
0122   const auto binHigh = grid.binIndex(phi, std::sinh(1.5f), r);
0123   BOOST_REQUIRE(binLow.has_value());
0124   BOOST_REQUIRE(binHigh.has_value());
0125   BOOST_CHECK(binLow != binHigh);
0126   BOOST_CHECK_EQUAL(grid.at(*binLow).size(), 2u);   // indices 0 and 1
0127   BOOST_CHECK_EQUAL(grid.at(*binHigh).size(), 1u);  // index 2
0128 }
0129 
0130 BOOST_AUTO_TEST_SUITE_END()
0131 
0132 }  // namespace Acts::Test