|
|
|||
File indexing completed on 2026-06-02 07:56:05
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/Geometry/GeometryIdentifier.hpp" 0012 #include "Acts/Geometry/Layer.hpp" 0013 #include "Acts/Geometry/TrackingGeometry.hpp" 0014 #include "Acts/Geometry/TrackingVolume.hpp" 0015 #include "Acts/Navigation/INavigationPolicy.hpp" 0016 #include "Acts/Navigation/NavigationStream.hpp" 0017 #include "Acts/Propagator/NavigationTarget.hpp" 0018 #include "Acts/Propagator/NavigatorOptions.hpp" 0019 #include "Acts/Propagator/NavigatorStatistics.hpp" 0020 #include "Acts/Surfaces/BoundaryTolerance.hpp" 0021 #include "Acts/Surfaces/Surface.hpp" 0022 #include "Acts/Utilities/Logger.hpp" 0023 #include "Acts/Utilities/Result.hpp" 0024 0025 #include <optional> 0026 #include <string> 0027 0028 #include <boost/container/small_vector.hpp> 0029 0030 namespace Acts { 0031 0032 /// @brief The navigation options for the tracking geometry 0033 /// 0034 /// @tparam object_t Type of the object for navigation to check against 0035 template <typename object_t> 0036 struct NavigationOptions final { 0037 /// The boundary check directive 0038 BoundaryTolerance boundaryTolerance = BoundaryTolerance::None(); 0039 0040 // How to resolve the geometry 0041 /// Always look for sensitive 0042 bool resolveSensitive = true; 0043 /// Always look for material 0044 bool resolveMaterial = true; 0045 /// always look for passive 0046 bool resolvePassive = false; 0047 0048 /// Hint for start object 0049 const object_t* startObject = nullptr; 0050 /// Hint for end object 0051 const object_t* endObject = nullptr; 0052 0053 /// External surface identifier for which the boundary check is ignored 0054 std::vector<GeometryIdentifier> externalSurfaces = {}; 0055 0056 /// The minimum distance for a surface to be considered 0057 double nearLimit = 0; 0058 /// The maximum distance for a surface to be considered 0059 double farLimit = std::numeric_limits<double>::max(); 0060 }; 0061 0062 /// @brief Steers the propagation through the geometry by providing the next 0063 /// surface to be targeted. 0064 /// 0065 /// The Navigator is part of the propagation and responsible for steering 0066 /// the surface sequence to encounter all the relevant surfaces which are 0067 /// intersected by the trajectory. 0068 /// 0069 /// The current navigation stage is cached in the state struct and updated 0070 /// when necessary. If any surface in the extrapolation flow is hit, it is 0071 /// set to the navigation state, such that other actors can deal with it. 0072 /// 0073 /// The current target surface is referenced by an index which points into 0074 /// the navigation candidates. The navigation candidates are ordered by the 0075 /// path length to the surface. If a surface is hit, the 0076 /// `state.currentSurface` pointer is set. This actors to observe 0077 /// that we are on a surface. 0078 /// 0079 class Navigator final { 0080 public: 0081 /// Type alias for navigation surface candidates container 0082 using NavigationSurfaces = 0083 boost::container::small_vector<NavigationTarget, 10>; 0084 0085 /// Type alias for navigation layer candidates container 0086 using NavigationLayers = boost::container::small_vector<NavigationTarget, 10>; 0087 0088 /// Type alias for navigation boundary candidates container 0089 using NavigationBoundaries = 0090 boost::container::small_vector<NavigationTarget, 4>; 0091 0092 /// Type alias for generic navigation candidates container 0093 using NavigationCandidates = 0094 boost::container::small_vector<NavigationTarget, 10>; 0095 0096 /// Type alias for geometry version enumeration 0097 using GeometryVersion = TrackingGeometry::GeometryVersion; 0098 0099 /// The navigation stage 0100 enum struct Stage : int { 0101 initial = 0, 0102 surfaceTarget = 1, 0103 layerTarget = 2, 0104 boundaryTarget = 3, 0105 }; 0106 0107 /// The navigator configuration 0108 struct Config { 0109 /// Tracking Geometry for this Navigator 0110 std::shared_ptr<const TrackingGeometry> trackingGeometry{nullptr}; 0111 0112 /// stop at every sensitive surface (whether it has material or not) 0113 bool resolveSensitive = true; 0114 /// stop at every material surface (whether it is passive or not) 0115 bool resolveMaterial = true; 0116 /// stop at every surface regardless what it is 0117 bool resolvePassive = false; 0118 }; 0119 0120 /// The navigator options 0121 struct Options : public NavigatorPlainOptions { 0122 /// Constructor with geometry context 0123 /// @param gctx The geometry context for the navigation 0124 explicit Options(const GeometryContext& gctx) 0125 : NavigatorPlainOptions(gctx) {} 0126 0127 /// Set the plain navigation options 0128 /// @param options The plain navigator options to set 0129 void setPlainOptions(const NavigatorPlainOptions& options) { 0130 static_cast<NavigatorPlainOptions&>(*this) = options; 0131 } 0132 }; 0133 0134 /// @brief Nested State struct 0135 /// 0136 /// It acts as an internal state which is created for every propagation and 0137 /// meant to keep thread-local navigation information. 0138 struct State { 0139 /// Constructor with navigation options 0140 /// @param options_ The navigation options for this state 0141 explicit State(const Options& options_) : options(options_) {} 0142 0143 /// Navigation options configuration 0144 Options options; 0145 0146 /// Management of policy state allocation and deallocation 0147 NavigationPolicyStateManager policyStateManager; 0148 0149 // Navigation on surface level 0150 /// the vector of navigation surfaces to work through 0151 NavigationSurfaces navSurfaces = {}; 0152 /// the current surface index of the navigation state 0153 std::optional<std::size_t> navSurfaceIndex; 0154 0155 // Navigation on layer level 0156 /// the vector of navigation layers to work through 0157 NavigationLayers navLayers = {}; 0158 /// the current layer index of the navigation state 0159 std::optional<std::size_t> navLayerIndex; 0160 0161 // Navigation on volume level 0162 /// the vector of boundary surfaces to work through 0163 NavigationBoundaries navBoundaries = {}; 0164 /// the current boundary index of the navigation state 0165 std::optional<std::size_t> navBoundaryIndex; 0166 0167 // Navigation candidates(portals and surfaces together) 0168 /// the vector of navigation candidates to work through 0169 NavigationCandidates navCandidates = {}; 0170 /// the current candidate index of the navigation state 0171 std::optional<std::size_t> navCandidateIndex; 0172 0173 /// Free candidates not part of the tracking geometry. 0174 // They are stored as a pair of surface pointer 0175 /// and a boolean indicating whether the surface has already been 0176 /// reached during propagation 0177 std::vector<std::pair<const Surface*, bool>> freeCandidates{}; 0178 0179 /// Get reference to current navigation surface 0180 /// @return Reference to current navigation target 0181 NavigationTarget& navSurface() { 0182 return navSurfaces.at(navSurfaceIndex.value()); 0183 } 0184 0185 /// Get reference to current navigation layer 0186 /// @return Reference to current layer intersection 0187 NavigationTarget& navLayer() { return navLayers.at(navLayerIndex.value()); } 0188 0189 /// Get reference to current navigation boundary 0190 /// @return Reference to current boundary intersection 0191 NavigationTarget& navBoundary() { 0192 return navBoundaries.at(navBoundaryIndex.value()); 0193 } 0194 0195 /// Get reference to current navigation candidate 0196 /// @return Reference to current boundary intersection 0197 NavigationTarget& navCandidate() { 0198 return navCandidates.at(navCandidateIndex.value()); 0199 } 0200 0201 /// Volume where the navigation started 0202 const TrackingVolume* startVolume = nullptr; 0203 /// Layer where the navigation started 0204 const Layer* startLayer = nullptr; 0205 /// Surface where the navigation started 0206 const Surface* startSurface = nullptr; 0207 /// Current volume during navigation 0208 const TrackingVolume* currentVolume = nullptr; 0209 /// Current layer during navigation 0210 const Layer* currentLayer = nullptr; 0211 /// Current surface during navigation 0212 const Surface* currentSurface = nullptr; 0213 /// Target surface for navigation 0214 const Surface* targetSurface = nullptr; 0215 0216 /// Flag to break navigation loop 0217 bool navigationBreak = false; 0218 /// Current navigation stage in the state machine 0219 Stage navigationStage = Stage::initial; 0220 0221 /// Statistics collection for navigation performance 0222 NavigatorStatistics statistics; 0223 0224 /// Stream for navigation debugging and monitoring 0225 NavigationStream stream; 0226 0227 /// Surfaces that are not part of the tracking geometry 0228 std::vector<const Surface*> freeSurfaces; 0229 0230 /// Reset navigation state after switching layers 0231 void resetAfterLayerSwitch() { 0232 navSurfaces.clear(); 0233 navSurfaceIndex.reset(); 0234 } 0235 0236 /// Reset navigation state after switching volumes 0237 void resetAfterVolumeSwitch() { 0238 resetAfterLayerSwitch(); 0239 0240 navLayers.clear(); 0241 navLayerIndex.reset(); 0242 navBoundaries.clear(); 0243 navBoundaryIndex.reset(); 0244 navCandidates.clear(); 0245 navCandidateIndex.reset(); 0246 0247 currentLayer = nullptr; 0248 0249 policyStateManager.reset(); 0250 } 0251 0252 /// Completely reset navigation state to initial conditions 0253 void resetForRenavigation() { 0254 resetAfterVolumeSwitch(); 0255 0256 currentVolume = nullptr; 0257 currentSurface = nullptr; 0258 0259 navigationBreak = false; 0260 navigationStage = Stage::initial; 0261 0262 // Set the surface reached switches back to false 0263 std::ranges::for_each(freeCandidates, 0264 [](std::pair<const Surface*, bool>& freeSurface) { 0265 freeSurface.second = false; 0266 }); 0267 0268 stream.reset(); 0269 } 0270 }; 0271 0272 /// Constructor with configuration object 0273 /// 0274 /// @param cfg The navigator configuration 0275 /// @param _logger a logger instance 0276 explicit Navigator(Config cfg, 0277 std::shared_ptr<const Logger> _logger = 0278 getDefaultLogger("Navigator", Logging::Level::INFO)); 0279 0280 /// Create a navigation state from options 0281 /// @param options The navigation options 0282 /// @return A new navigation state 0283 State makeState(const Options& options) const; 0284 0285 /// Get the current surface from navigation state 0286 /// @param state The navigation state 0287 /// @return Pointer to current surface, or nullptr if none 0288 const Surface* currentSurface(const State& state) const; 0289 0290 /// Get the current volume from navigation state 0291 /// @param state The navigation state 0292 /// @return Pointer to current volume, or nullptr if none 0293 const TrackingVolume* currentVolume(const State& state) const; 0294 0295 /// Get material properties of the current volume 0296 /// @param state The navigation state 0297 /// @return Pointer to volume material, or nullptr if no volume or material 0298 const IVolumeMaterial* currentVolumeMaterial(const State& state) const; 0299 0300 /// Get the starting surface from navigation state 0301 /// @param state The navigation state 0302 /// @return Pointer to start surface, or nullptr if none 0303 const Surface* startSurface(const State& state) const; 0304 0305 /// Get the target surface from navigation state 0306 /// @param state The navigation state 0307 /// @return Pointer to target surface, or nullptr if none 0308 const Surface* targetSurface(const State& state) const; 0309 0310 /// Check if navigation has reached the end of the world (no current volume) 0311 /// @param state The navigation state 0312 /// @return True if end of world is reached 0313 bool endOfWorldReached(const State& state) const; 0314 0315 /// Check if navigation should be interrupted 0316 /// @param state The navigation state 0317 /// @return True if navigation break flag is set 0318 bool navigationBreak(const State& state) const; 0319 0320 /// @brief Initialize the navigator state 0321 /// 0322 /// This function initializes the navigator state for a new propagation. 0323 /// 0324 /// @param state The navigation state 0325 /// @param position The start position 0326 /// @param direction The start direction 0327 /// @param propagationDirection The propagation direction 0328 /// 0329 /// @return Indication if the initialization was successful 0330 [[nodiscard]] Result<void> initialize(State& state, const Vector3& position, 0331 const Vector3& direction, 0332 Direction propagationDirection) const; 0333 0334 /// @brief Get the next target surface 0335 /// 0336 /// This function gets the next target surface for the propagation. 0337 /// 0338 /// @param state The navigation state 0339 /// @param position The current position 0340 /// @param direction The current direction 0341 /// 0342 /// @return The next target surface 0343 NavigationTarget nextTarget(State& state, const Vector3& position, 0344 const Vector3& direction) const; 0345 0346 /// @brief Check if the current target is still valid 0347 /// 0348 /// This function checks if the target is valid. 0349 /// 0350 /// @param state The navigation state 0351 /// @param position The current position 0352 /// @param direction The current direction 0353 /// 0354 /// @return True if the target is valid 0355 bool checkTargetValid(State& state, const Vector3& position, 0356 const Vector3& direction) const; 0357 0358 /// @brief Handle the surface reached 0359 /// 0360 /// This function handles the surface reached. 0361 /// 0362 /// @param state The navigation state 0363 /// @param position The current position 0364 /// @param direction The current direction 0365 /// @param surface The surface reached 0366 void handleSurfaceReached(State& state, const Vector3& position, 0367 const Vector3& direction, 0368 const Surface& surface) const; 0369 0370 private: 0371 /// @brief NextTarget helper function for Gen1 geometry configuration 0372 /// 0373 /// @param state The navigation state 0374 /// @param position The current position 0375 /// @param direction The current direction 0376 NavigationTarget getNextTargetGen1(State& state, const Vector3& position, 0377 const Vector3& direction) const; 0378 0379 /// @brief NextTarget helper function for Gen3 geometry configuration 0380 /// 0381 /// @param state The navigation state 0382 /// @param position The current position 0383 /// @param direction The current direction 0384 NavigationTarget getNextTargetGen3(State& state, const Vector3& position, 0385 const Vector3& direction) const; 0386 0387 /// @brief NextTarget helper function 0388 /// This function is called for returning the next target 0389 /// and checks gen1/gen3 case in order to sub-call the proper functions 0390 /// 0391 /// @param state The navigation state 0392 /// @param position The current position 0393 /// @param direction The current direction 0394 NavigationTarget tryGetNextTarget(State& state, const Vector3& position, 0395 const Vector3& direction) const; 0396 0397 /// @brief Resolve compatible candidates (surfaces or portals) for gen3 0398 /// navigation 0399 /// 0400 /// This function is called when gen3 configuration is found and it resolves 0401 /// at the same time for portals and surfaces 0402 /// @param state The navigation state 0403 /// @param position The current position 0404 /// @param direction The current direction 0405 void resolveCandidates(State& state, const Vector3& position, 0406 const Vector3& direction) const; 0407 0408 /// @brief Resolve compatible surfaces 0409 /// 0410 /// This function resolves the compatible surfaces for the navigation. 0411 /// 0412 /// @param state The navigation state 0413 /// @param position The current position 0414 /// @param direction The current direction 0415 void resolveSurfaces(State& state, const Vector3& position, 0416 const Vector3& direction) const; 0417 0418 /// @brief Resolve compatible layers 0419 /// 0420 /// This function resolves the compatible layers for the navigation. 0421 /// 0422 /// @param state The navigation state 0423 /// @param position The current position 0424 /// @param direction The current direction 0425 void resolveLayers(State& state, const Vector3& position, 0426 const Vector3& direction) const; 0427 0428 /// @brief Resolve compatible boundaries 0429 /// 0430 /// This function resolves the compatible boundaries for the navigation. 0431 /// 0432 /// @param state The navigation state 0433 /// @param position The current position 0434 /// @param direction The current direction 0435 void resolveBoundaries(State& state, const Vector3& position, 0436 const Vector3& direction) const; 0437 0438 /// @brief Check if the navigator is inactive 0439 /// 0440 /// This function checks if the navigator is inactive. 0441 /// 0442 /// @param state The navigation state 0443 /// 0444 /// @return True if the navigator is inactive 0445 bool inactive(const State& state) const; 0446 0447 /// @brief Get volume info string for logging 0448 /// 0449 /// @tparam propagator_state_t The propagator state type 0450 /// @param state The state containing current volume info 0451 /// @return String with volume name for logging 0452 std::string volInfo(const State& state) const; 0453 0454 const Logger& logger() const { return *m_logger; } 0455 0456 Config m_cfg; 0457 0458 // Cached so we don't have to query the TrackingGeometry constantly. 0459 TrackingGeometry::GeometryVersion m_geometryVersion{}; 0460 0461 std::shared_ptr<const Logger> m_logger; 0462 }; 0463 0464 } // namespace Acts
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|