Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /acts/Core/include/Acts/Navigation/MultiLayerNavigationPolicy.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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 #pragma once
0010 
0011 #include "Acts/Detector/detail/IndexedGridFiller.hpp"
0012 #include "Acts/Detector/detail/ReferenceGenerators.hpp"
0013 #include "Acts/Geometry/TrackingVolume.hpp"
0014 #include "Acts/Navigation/INavigationPolicy.hpp"
0015 #include "Acts/Navigation/InternalNavigation.hpp"
0016 #include "Acts/Navigation/NavigationStream.hpp"
0017 #include "Acts/Surfaces/detail/IntersectionHelper2D.hpp"
0018 #include "Acts/Utilities/Grid.hpp"
0019 #include "Acts/Utilities/VectorHelpers.hpp"
0020 
0021 namespace Acts::Experimental {
0022 
0023 /// A navigation policy that uses grid based navigation for indexed surfaces
0024 /// Navigate through a multilayer structure by creating an artificial path on
0025 /// the grid.
0026 class MultiLayerNavigationPolicy : public INavigationPolicy {
0027  public:
0028   using gridType =
0029       Grid<std::vector<std::size_t>,
0030            Axis<AxisType::Equidistant, Acts::AxisBoundaryType::Bound>,
0031            Axis<AxisType::Equidistant, Acts::AxisBoundaryType::Bound>>;
0032   using indexedUpdatorType = IndexedSurfacesNavigation<gridType>;
0033 
0034   struct Config {
0035     // The binning expansion for grid neighbor lookups
0036     std::vector<std::size_t> binExpansion = {0u, 0u};
0037   };
0038 
0039   /// Main constructor, which expects the grid and will fill it with the
0040   /// surfaces from the volume passed
0041   /// @note Expects that the grid is defined but not filled - it will be filled here with the surfaces assigned to the @p volume
0042   /// @param gctx The geometrycontext object
0043   /// @param volume The tracking volume holding the surfaces that will be the indexed objects
0044   /// @param config The configuration of the Navigation Policy
0045   /// @param logger A logging instance
0046   /// @param grid The grid that will be filled with the surfaces
0047   explicit MultiLayerNavigationPolicy(const GeometryContext& gctx,
0048                                       const TrackingVolume& volume,
0049                                       const Logger& logger,
0050                                       const Config& config,
0051                                       indexedUpdatorType grid)
0052       : m_volume(volume), m_indexedGrid(std::move(grid)) {
0053     ACTS_VERBOSE("Constructing MultiLayerNavigationPolicy for volume "
0054                  << m_volume.volumeName());
0055 
0056     // Fill the grid with surfaces
0057     std::vector<std::shared_ptr<const Surface>> surfaces = {};
0058     for (const auto& surface : m_volume.surfaces()) {
0059       if (surface.associatedDetectorElement() == nullptr) {
0060         continue;
0061       }
0062       surfaces.push_back(surface.getSharedPtr());
0063     }
0064 
0065     Experimental::detail::CenterReferenceGenerator rGenerator;
0066     Experimental::detail::IndexedGridFiller filler{config.binExpansion};
0067     filler.fill(gctx, m_indexedGrid, surfaces, rGenerator, {});
0068   }
0069 
0070   /// Update the navigation state from the surface array
0071   /// @param args The navigation arguments
0072   /// @param stream The navigation stream to update
0073   /// @param logger The logger
0074   void initializeCandidates(const NavigationArguments& args,
0075                             AppendOnlyNavigationStream& stream,
0076                             const Logger& logger) const {
0077     ACTS_VERBOSE(
0078         "MultiLayerNavigationPolicy Candidates initialization for volume"
0079         << m_volume.volumeName());
0080     const Transform3& itransform = m_volume.itransform();
0081     const Vector3 locPosition = itransform * args.position;
0082     const Vector3 locDirection = itransform * args.direction;
0083 
0084     std::vector<Vector2> path = generatePath(locPosition, locDirection);
0085 
0086     const auto& surfaces = m_volume.surfaces();
0087     std::vector<const Surface*> surfCandidates = {};
0088     surfCandidates.reserve(surfaces.size());
0089 
0090     for (const auto& pos : path) {
0091       std::vector<std::size_t> indices = m_indexedGrid.grid.atPosition(pos);
0092 
0093       std::ranges::transform(indices, std::back_inserter(surfCandidates),
0094                              [&](const auto& i) { return &surfaces[i]; });
0095     }
0096 
0097     ACTS_VERBOSE("MultiLayerNavigationPolicy Candidates reported"
0098                  << surfCandidates.size() << " candidates");
0099 
0100     // fill the navigation stream with the container
0101     for (const auto* surf : surfCandidates) {
0102       stream.addSurfaceCandidate(*surf, args.tolerance);
0103     }
0104   }
0105 
0106   /// Connect this policy with a navigation delegate
0107   /// @param delegate The navigation delegate to connect to
0108   void connect(NavigationDelegate& delegate) const override {
0109     connectDefault<MultiLayerNavigationPolicy>(delegate);
0110   }
0111 
0112   /// Generate a path in the multilayer
0113   /// @param startPosition The starting position of the path (in local frame)
0114   /// @param direction The direction of the path (in local frame)
0115   /// @return A vector of positions along the path
0116   std::vector<Vector2> generatePath(const Vector3& startPosition,
0117                                     const Vector3& direction) const {
0118     std::vector<Vector2> path;
0119 
0120     auto maxXIndex = m_indexedGrid.grid.numLocalBins()[0];
0121     auto maxYIndex = m_indexedGrid.grid.numLocalBins()[1];
0122     Vector3 unitDir = direction.normalized();
0123 
0124     for (std::size_t i = 0; i < maxYIndex; i++) {
0125       auto v1 = m_indexedGrid.grid.lowerLeftBinEdge({1, i + 1});
0126       auto v2 = m_indexedGrid.grid.upperRightBinEdge({maxXIndex, i + 1});
0127 
0128       auto intersection = Acts::detail::IntersectionHelper2D::intersectSegment(
0129           Vector2(v1[0], v1[1]), Vector2(v2[0], v2[1]),
0130           startPosition.template block<2, 1>(0, 0),
0131           unitDir.template block<2, 1>(0, 0));
0132       if (!intersection.isValid()) {
0133         continue;
0134       }
0135 
0136       path.push_back(intersection.position());
0137     }
0138     return path;
0139   }
0140 
0141  private:
0142   // The tracking volume
0143   const TrackingVolume& m_volume;
0144 
0145   // The grid that holds the indexed surfaces
0146   indexedUpdatorType m_indexedGrid;
0147 };
0148 
0149 static_assert(NavigationPolicyConcept<MultiLayerNavigationPolicy>);
0150 
0151 }  // namespace Acts::Experimental