Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-20 08:41:44

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/Units.hpp"
0012 #include "Acts/EventData/SpacePointContainer.hpp"
0013 #include "Acts/Seeding/DoubletSeedFinder.hpp"
0014 
0015 #include <array>
0016 #include <cmath>
0017 #include <optional>
0018 
0019 using namespace Acts::UnitLiterals;
0020 
0021 namespace Acts::Test {
0022 
0023 namespace {
0024 
0025 // Track direction from the origin, slightly off the stereo strips
0026 constexpr std::array<float, 3> kDirection{1.f, 4e-4f, 0.5f};
0027 constexpr float kStripHalfLength = 12_mm;
0028 constexpr float kStereoAngle = 0.02f;
0029 constexpr float kModuleGap = 2_mm;
0030 
0031 // Adds a strip space point of a barrel stereo module at radius `r`, crossed
0032 // by `kDirection`, at its nominal position shifted by `offset`.
0033 void addStripSpacePoint(SpacePointContainer& container, float r,
0034                         const std::array<float, 3>& offset) {
0035   const std::array<float, 3> innerHalf{
0036       0, -kStripHalfLength * std::sin(kStereoAngle),
0037       kStripHalfLength * std::cos(kStereoAngle)};
0038   const std::array<float, 3> outerHalf{
0039       0, kStripHalfLength * std::sin(kStereoAngle),
0040       kStripHalfLength * std::cos(kStereoAngle)};
0041 
0042   // strip center such that the track hit at `x` lies on the strip
0043   const auto center = [&](float x, const std::array<float, 3>& half) {
0044     const float s = kDirection[1] * x / half[1];
0045     return std::array<float, 3>{x, kDirection[1] * x - s * half[1],
0046                                 kDirection[2] * x - s * half[2]};
0047   };
0048   const std::array<float, 3> innerCenter = center(r, innerHalf);
0049   const std::array<float, 3> outerCenter = center(r + kModuleGap, outerHalf);
0050 
0051   auto sp = container.createSpacePoint();
0052   const float x = r + offset[0];
0053   const float y = kDirection[1] * r + offset[1];
0054   sp.xy() = {x, y};
0055   sp.zr() = {kDirection[2] * r + offset[2], std::hypot(x, y)};
0056   sp.varianceZ() = 1_mm;
0057   sp.varianceR() = 0;
0058   sp.outerStripCalibrationDetails() = {
0059       outerCenter,
0060       {outerCenter[0] - innerCenter[0], outerCenter[1] - innerCenter[1],
0061        outerCenter[2] - innerCenter[2]},
0062       outerHalf,
0063       innerHalf};
0064 }
0065 
0066 // Finds the top doublets of the first space point among the others
0067 DoubletsForMiddleSp findDoublets(const SpacePointContainer& container,
0068                                  std::optional<float> tolerance) {
0069   DoubletSeedFinder::Config config;
0070   config.candidateDirection = Direction::Forward();
0071   config.deltaRMin = 10_mm;
0072   config.deltaRMax = 200_mm;
0073   config.collisionRegionMin = -50_mm;
0074   config.collisionRegionMax = 50_mm;
0075   config.stripCalibrationTolerance = tolerance;
0076   const auto finder =
0077       DoubletSeedFinder::create(DoubletSeedFinder::DerivedConfig(config, 2_T));
0078 
0079   const ConstSpacePointProxy middle = container[0];
0080   DoubletsForMiddleSp doublets;
0081   finder->createDoublets(middle, DoubletSeedFinder::computeMiddleSpInfo(middle),
0082                          container.range({1, container.size()}), doublets);
0083   return doublets;
0084 }
0085 
0086 SpacePointContainer makeContainer() {
0087   return SpacePointContainer(
0088       SpacePointColumns::PackedXY | SpacePointColumns::PackedZR |
0089       SpacePointColumns::VarianceZ | SpacePointColumns::VarianceR |
0090       SpacePointColumns::StripCalibrationDetails);
0091 }
0092 
0093 }  // namespace
0094 
0095 BOOST_AUTO_TEST_SUITE(SeedingSuite)
0096 
0097 BOOST_AUTO_TEST_CASE(DoubletStripCalibrationUsesCalibratedPositions) {
0098   // nominal positions off along z, as from a wrong formation direction
0099   SpacePointContainer container = makeContainer();
0100   addStripSpacePoint(container, 300_mm, {0, 0, 3_mm});
0101   addStripSpacePoint(container, 400_mm, {0, 0, -3_mm});
0102 
0103   const DoubletsForMiddleSp nominal = findDoublets(container, std::nullopt);
0104   BOOST_REQUIRE_EQUAL(nominal.size(), 1u);
0105   BOOST_CHECK_CLOSE(nominal.cotTheta()[0], kDirection[2] - 0.06f, 0.1);
0106 
0107   const DoubletsForMiddleSp calibrated = findDoublets(container, 1.1f);
0108   BOOST_REQUIRE_EQUAL(calibrated.size(), 1u);
0109   BOOST_CHECK_SMALL(calibrated.cotTheta()[0] - kDirection[2], 5e-3f);
0110 }
0111 
0112 BOOST_AUTO_TEST_CASE(DoubletStripCalibrationRejectsMissedStrips) {
0113   // the chord points far off in phi and misses the strips
0114   SpacePointContainer container = makeContainer();
0115   addStripSpacePoint(container, 300_mm, {0, 0, 0});
0116   addStripSpacePoint(container, 400_mm, {0, 20_mm, 0});
0117 
0118   BOOST_CHECK_EQUAL(findDoublets(container, std::nullopt).size(), 1u);
0119   BOOST_CHECK_EQUAL(findDoublets(container, 1.1f).size(), 0u);
0120 }
0121 
0122 BOOST_AUTO_TEST_SUITE_END()
0123 
0124 }  // namespace Acts::Test