Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-27 07:24:01

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 // Project include(s)
0012 #include "detray/definitions/detail/qualifiers.hpp"
0013 #include "detray/definitions/indexing.hpp"
0014 #include "detray/definitions/navigation.hpp"
0015 #include "detray/definitions/units.hpp"
0016 #include "detray/geometry/surface.hpp"
0017 #include "detray/navigation/detail/intersection_kernel.hpp"
0018 #include "detray/navigation/detail/navigation_functions.hpp"
0019 #include "detray/navigation/intersection/intersection.hpp"
0020 #include "detray/navigation/intersection/ray_intersector.hpp"
0021 #include "detray/navigation/navigation_config.hpp"
0022 #include "detray/navigation/navigation_state.hpp"
0023 #include "detray/utils/logging.hpp"
0024 
0025 namespace detray {
0026 
0027 /// @brief Navigation base class - interface towards the propagator
0028 ///
0029 /// The navigator is initialized around a detector object, but is itself
0030 /// agnostic to the detectors's object/primitive types.
0031 /// Within a detector volume, the navigatior will perform a local navigation
0032 /// based on the geometry acceleration structure(s) that are provided by the
0033 /// volume. Once the local navigation is resolved, it moves to the next volume
0034 /// by a portal.
0035 /// To this end, it requires a link to the [next] navigation volume in every
0036 /// candidate that is computed by intersection from the detector objects:
0037 /// A module surface must link back to its mother volume, while a portal surface
0038 /// links to the next volume in the direction of the track.
0039 ///
0040 /// The navigation state is set up by an init() call and then runs an update()
0041 /// after the track state changed.
0042 ///
0043 /// @tparam navigator_impl_t implementation of the navigation update
0044 template <typename navigator_impl_t>
0045 class navigator_base {
0046  public:
0047   /// @brief Helper method to initialize a volume.
0048   ///
0049   /// @tparam track_t type of track, needs to provide pos() and dir() methods
0050   ///
0051   /// @param track access to the track parameters
0052   /// @param state the current navigation state
0053   /// @param cfg the navigation configuration
0054   /// @param ctx the geometry context
0055   /// @param resolve_overstepping whether to check for overstepping
0056   template <typename track_t, typename nav_state_t, typename context_t>
0057   DETRAY_HOST_DEVICE constexpr void init(
0058       const track_t &track, nav_state_t &navigation,
0059       const navigation::config &cfg, const context_t &ctx,
0060       const bool resolve_overstepping = false) const {
0061     // Run local navigation in the current volume
0062     navigation::local_navigation(track, navigation, cfg, ctx,
0063                                  resolve_overstepping);
0064 
0065     DETRAY_VERBOSE_HOST("Status: " << navigation.status() << " (next sf.: "
0066                                    << navigation.next_surface().index() << ")");
0067     if (navigation.is_on_surface()) {
0068       DETRAY_VERBOSE_HOST("-> Current surface: "
0069                           << navigation.current_surface().index()
0070                           << ", has material: " << std::boolalpha
0071                           << navigation.current_surface().has_material()
0072                           << std::noboolalpha);
0073     }
0074     DETRAY_VERBOSE_HOST_DEVICE("Update complete: dist to next %f mm",
0075                                navigation());
0076   }
0077 
0078   /// @brief Complete update of the navigation flow.
0079   ///
0080   /// Restores 'full trust' state to the candidates cache and checks whether
0081   /// the track stepped onto a portal and a volume switch is due. If so, or
0082   /// when the previous update according to the given trust level
0083   /// failed to restore trust, it performs a complete reinitialization of the
0084   /// navigation.
0085   ///
0086   /// @tparam track_t type of track, needs to provide pos() and dir() methods
0087   ///
0088   /// @param track access to the track parameters
0089   /// @param state the current navigation state
0090   /// @param cfg the navigation configuration
0091   /// @param ctx the geometry context
0092   ///
0093   /// @returns a heartbeat to indicate if the navigation is still alive
0094   template <typename track_t, typename nav_state_t, typename context_t>
0095   DETRAY_HOST_DEVICE DETRAY_INLINE constexpr bool update(
0096       const track_t &track, nav_state_t &navigation,
0097       const navigation::config &cfg, const context_t &ctx) const {
0098     assert(navigation.is_alive());
0099     assert(!track.is_invalid());
0100 
0101     // Update was completely successful (most likely case)
0102     if (navigation.trust_level() == navigation::trust_level::e_full) {
0103       DETRAY_VERBOSE_HOST_DEVICE(
0104           "-> Full trust, nothing left to do: dist to next %f mm",
0105           navigation());
0106       return false;
0107     }
0108 
0109     // Candidates are re-evaluated based on the current trust level.
0110     // Should result in 'full trust'
0111     constexpr const navigator_impl_t navigation_impl{};
0112     bool is_init = navigation_impl.update_impl(track, navigation, cfg, ctx);
0113 
0114     // Otherwise: if we encountered a portal, perform volume switch
0115     if (navigation.is_on_portal()) {
0116       navigation::volume_switch(track, navigation, cfg, ctx);
0117       is_init = true;
0118 
0119       // Reached end of detector
0120       if (!navigation.is_alive()) {
0121         return false;
0122       }
0123     }
0124     // If no trust could be restored during the update, try to rescue the
0125     // navigation stream by re-initializing with loose tolerances
0126     if (navigation.trust_level() != navigation::trust_level::e_full ||
0127         navigation.cache_exhausted()) {
0128       is_init = true;
0129       navigation::init_loose_cfg(track, navigation, cfg, ctx);
0130 
0131       navigation.run_inspector(cfg, track.pos(), track.dir(), "Re-init: ");
0132     }
0133 
0134     DETRAY_VERBOSE_HOST("Status: " << navigation.status() << " (vol.:"
0135                                    << navigation.volume() << ", next sf.: "
0136                                    << navigation.next_surface().index() << ")");
0137     if (navigation.is_on_surface()) {
0138       DETRAY_VERBOSE_HOST("-> Current surface: "
0139                           << navigation.current_surface().index()
0140                           << ", has material: " << std::boolalpha
0141                           << navigation.current_surface().has_material()
0142                           << std::noboolalpha);
0143     }
0144     DETRAY_VERBOSE_HOST_DEVICE("Update complete: dist to next %f mm",
0145                                navigation());
0146 
0147     return is_init;
0148   }
0149 };
0150 
0151 }  // namespace detray