Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:23:14

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 "Acts/Navigation/MultiLayerNavigationPolicy.hpp"
0010 
0011 #include "Acts/Geometry/ReferenceGenerators.hpp"
0012 #include "Acts/Utilities/GridAccessHelpers.hpp"
0013 
0014 namespace Acts::Experimental {
0015 
0016 MultiLayerNavigationPolicy::MultiLayerNavigationPolicy(
0017     const GeometryContext& gctx, const TrackingVolume& volume,
0018     const Logger& logger, const Config& config, IndexedUpdatorType grid)
0019     : m_volume(volume), m_indexedGrid(std::move(grid)) {
0020   ACTS_VERBOSE("Constructing MultiLayerNavigationPolicy for volume "
0021                << m_volume.volumeName());
0022 
0023   // Fill the grid with surfaces
0024   std::vector<std::shared_ptr<const Surface>> surfaces = {};
0025   for (const auto& surface : m_volume.surfaces()) {
0026     if (surface.associatedDetectorElement() == nullptr) {
0027       continue;
0028     }
0029     surfaces.push_back(surface.getSharedPtr());
0030   }
0031 
0032   CenterReferenceGenerator rGenerator;
0033   IndexGridFiller filler{config.binExpansion};
0034   filler.fill(gctx, m_indexedGrid, surfaces, rGenerator, {});
0035 }
0036 
0037 void MultiLayerNavigationPolicy::initializeCandidates(
0038     [[maybe_unused]] const GeometryContext& gctx,
0039     const NavigationArguments& args, AppendOnlyNavigationStream& stream,
0040     const Logger& logger) const {
0041   ACTS_VERBOSE("MultiLayerNavigationPolicy Candidates initialization for volume"
0042                << m_volume.volumeName());
0043   const Transform3& itransform = m_volume.itransform();
0044   const Vector3 locPosition = itransform * args.position;
0045   const Vector3 locDirection = itransform.linear() * args.direction;
0046 
0047   std::vector<Vector2> path = generatePath(locPosition, locDirection);
0048 
0049   const auto& surfaces = m_volume.surfaces();
0050   std::vector<const Surface*> surfCandidates = {};
0051   surfCandidates.reserve(surfaces.size());
0052 
0053   for (const auto& pos : path) {
0054     // Local access
0055     std::vector<std::size_t> fAccessor = {0u, 1u};
0056     const auto& indices = m_indexedGrid.grid.atPosition(
0057         GridAccessHelpers::accessLocal<GridType>(pos, fAccessor));
0058     std::ranges::transform(indices, std::back_inserter(surfCandidates),
0059                            [&](const auto& i) { return &surfaces[i]; });
0060   }
0061 
0062   ACTS_VERBOSE("MultiLayerNavigationPolicy Candidates reported "
0063                << surfCandidates.size() << " candidates");
0064 
0065   // fill the navigation stream with the container
0066   for (const auto* surf : surfCandidates) {
0067     stream.addSurfaceCandidate(*surf, args.tolerance);
0068   }
0069 }
0070 
0071 std::vector<Vector2> MultiLayerNavigationPolicy::generatePath(
0072     const Vector3& startPosition, const Vector3& direction) const {
0073   std::vector<Vector2> path;
0074 
0075   auto maxXIndex = m_indexedGrid.grid.numLocalBins()[0];
0076   auto maxYIndex = m_indexedGrid.grid.numLocalBins()[1];
0077   Vector3 unitDir = direction.normalized();
0078 
0079   // cast the starting position and direction to the correct axis
0080   Vector2 startPoint{
0081       VectorHelpers::cast(startPosition, m_indexedGrid.casts[0]),
0082       VectorHelpers::cast(startPosition, m_indexedGrid.casts[1])};
0083   Vector2 startDir{VectorHelpers::cast(unitDir, m_indexedGrid.casts[0]),
0084                    VectorHelpers::cast(unitDir, m_indexedGrid.casts[1])};
0085 
0086   for (std::size_t i = 0; i < maxYIndex; i++) {
0087     auto v1 = m_indexedGrid.grid.lowerLeftBinEdge({1, i + 1});
0088     auto v2 = m_indexedGrid.grid.upperRightBinEdge({maxXIndex, i + 1});
0089 
0090     auto intersection = Acts::detail::IntersectionHelper2D::intersectSegment(
0091         Vector2(v1[0], v1[1]), Vector2(v2[0], v2[1]), startPoint, startDir);
0092     if (!intersection.isValid()) {
0093       continue;
0094     }
0095 
0096     path.push_back(intersection.position());
0097   }
0098   return path;
0099 }
0100 
0101 }  // namespace Acts::Experimental