Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2026-07-16 08:07:52

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.isSensitive()) {
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     const GeometryContext& gctx, const NavigationArguments& args,
0039     AppendOnlyNavigationStream& stream, const Logger& logger) const {
0040   ACTS_VERBOSE("MultiLayerNavigationPolicy Candidates initialization for volume"
0041                << m_volume.volumeName());
0042   const Transform3& itransform = m_volume.globalToLocalTransform(gctx);
0043   const Vector3 locPosition = itransform * args.position;
0044   const Vector3 locDirection = itransform.linear() * args.direction;
0045 
0046   std::vector<Vector2> path = generatePath(locPosition, locDirection);
0047 
0048   const auto& surfaces = m_volume.surfaces();
0049   std::vector<const Surface*> surfCandidates = {};
0050   surfCandidates.reserve(surfaces.size());
0051 
0052   for (const auto& pos : path) {
0053     // Local access
0054     std::vector<std::size_t> fAccessor = {0u, 1u};
0055     const auto& indices = m_indexedGrid.grid.atPosition(
0056         GridAccessHelpers::accessLocal<GridType>(pos, fAccessor));
0057     std::ranges::transform(indices, std::back_inserter(surfCandidates),
0058                            [&](const auto& i) { return &surfaces[i]; });
0059   }
0060 
0061   ACTS_VERBOSE("MultiLayerNavigationPolicy Candidates reported "
0062                << surfCandidates.size() << " candidates");
0063 
0064   // fill the navigation stream with the container
0065   for (const auto* surf : surfCandidates) {
0066     stream.addSurfaceCandidate(*surf, args.tolerance);
0067   }
0068 }
0069 
0070 std::vector<Vector2> MultiLayerNavigationPolicy::generatePath(
0071     const Vector3& startPosition, const Vector3& direction) const {
0072   std::vector<Vector2> path;
0073 
0074   auto maxXIndex = m_indexedGrid.grid.numLocalBins()[0];
0075   auto maxYIndex = m_indexedGrid.grid.numLocalBins()[1];
0076   Vector3 unitDir = direction.normalized();
0077 
0078   // cast the starting position and direction to the correct axis
0079   Vector2 startPoint{
0080       VectorHelpers::cast(startPosition, m_indexedGrid.casts[0]),
0081       VectorHelpers::cast(startPosition, m_indexedGrid.casts[1])};
0082   Vector2 startDir{VectorHelpers::cast(unitDir, m_indexedGrid.casts[0]),
0083                    VectorHelpers::cast(unitDir, m_indexedGrid.casts[1])};
0084 
0085   for (std::size_t i = 0; i < maxYIndex; i++) {
0086     auto v1 = m_indexedGrid.grid.lowerLeftBinEdge({1, i + 1});
0087     auto v2 = m_indexedGrid.grid.upperRightBinEdge({maxXIndex, i + 1});
0088 
0089     auto intersection = Acts::detail::IntersectionHelper2D::intersectSegment(
0090         Vector2(v1[0], v1[1]), Vector2(v2[0], v2[1]), startPoint, startDir);
0091     if (!intersection.isValid()) {
0092       continue;
0093     }
0094 
0095     path.push_back(intersection.position());
0096   }
0097   return path;
0098 }
0099 
0100 }  // namespace Acts::Experimental