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/navigation/detail/navigation_functions.hpp"
0017 #include "detray/navigation/intersection/intersection.hpp"
0018 #include "detray/navigation/intersection/ray_intersector.hpp"
0019 #include "detray/navigation/navigation_config.hpp"
0020 #include "detray/navigation/navigation_state.hpp"
0021 #include "detray/navigation/navigator_base.hpp"
0022 #include "detray/utils/logging.hpp"
0023 
0024 namespace detray {
0025 
0026 /// @brief The geometry navigation class.
0027 ///
0028 /// @tparam detector_t the detector to navigate
0029 /// @tparam inspector_t is a validation inspector that can record information
0030 ///         about the navigation state at different points of the nav. flow.
0031 /// @tparam intersection_t candidate type
0032 template <
0033     typename detector_t, typename inspector_t = navigation::void_inspector,
0034     typename intersection_t = intersection2D<typename detector_t::surface_type,
0035                                              typename detector_t::algebra_type,
0036                                              !intersection::contains_pos>>
0037 class navigator : public navigator_base<
0038                       navigator<detector_t, inspector_t, intersection_t>> {
0039   friend class navigator_base<navigator>;
0040 
0041   using scalar_t = dscalar<typename detector_t::algebra_type>;
0042 
0043  public:
0044   using detector_type = detector_t;
0045   using context_type = typename detector_type::geometry_context;
0046   using intersection_type = intersection_t;
0047   using inspector_type = inspector_t;
0048 
0049   /// @brief Navigation state that contains a the current and the next
0050   /// candidates
0051   class state
0052       : public navigation::base_state<state, detector_type, 2u, inspector_type,
0053                                       intersection_type> {
0054     // Allow the navigator classes to access methods that update the state
0055     friend class navigator;
0056     friend class navigator_base<navigator>;
0057 
0058     // Allow the filling/updating of candidates
0059     friend struct detail::intersection_initialize<ray_intersector>;
0060     friend struct detail::intersection_update<ray_intersector>;
0061 
0062     // Navigation utility functions that need to modify the state
0063     friend struct navigation::candidate_search;
0064 
0065     template <typename state_t>
0066     friend constexpr void navigation::update_status(state_t &,
0067                                                     const navigation::config &);
0068 
0069     template <typename track_t, typename state_t, typename ctx_t>
0070     friend constexpr void navigation::local_navigation(
0071         const track_t &, state_t &, const navigation::config &, const ctx_t &,
0072         const bool);
0073 
0074     template <typename track_t, typename state_t, typename ctx_t>
0075     friend constexpr void navigation::volume_switch(const track_t &, state_t &,
0076                                                     const navigation::config &,
0077                                                     const ctx_t &);
0078 
0079     template <typename track_t, typename state_t, typename ctx_t>
0080     friend constexpr void navigation::init_loose_cfg(const track_t &, state_t &,
0081                                                      navigation::config,
0082                                                      const ctx_t &);
0083     using base_type = navigation::base_state<state, detector_type, 2u,
0084                                              inspector_type, intersection_type>;
0085 
0086     using candidate_const_itr_t = typename base_type::candidate_const_itr_t;
0087 
0088    public:
0089     using value_type = typename base_type::candidate_t;
0090     using view_type = detail::get_view_t<inspector_t>;
0091     using const_view_type = detail::get_view_t<const inspector_t>;
0092 
0093     /// Use common methods of constructing a nvaigation state
0094     using base_type::base_type;
0095 
0096     /// @returns the navigator always has only one candidate
0097     DETRAY_HOST_DEVICE
0098     constexpr auto n_candidates() const -> dindex { return 1u; }
0099 
0100     /// Update navigation trust level to high trust
0101     /// @{
0102     DETRAY_HOST_DEVICE
0103     constexpr void set_high_trust() {
0104       this->trust_level(this->trust_level() < navigation::trust_level::e_high
0105                             ? this->trust_level()
0106                             : navigation::trust_level::e_high);
0107     }
0108     DETRAY_HOST_DEVICE
0109     constexpr void set_fair_trust() { this->set_high_trust(); }
0110     /// @}
0111 
0112    private:
0113     /// Insert a new element @param new_cadidate before position @param pos
0114     DETRAY_HOST_DEVICE
0115     constexpr void insert(candidate_const_itr_t /*pos*/,
0116                           const intersection_type &new_cadidate) {
0117       // Insert the first candidate
0118       if (math::fabs(new_cadidate) < math::fabs(this->candidates()[1].path)) {
0119         this->candidates()[1] = new_cadidate;
0120       }
0121 
0122       assert(this->next_index() == 1u);
0123       assert(detail::is_invalid_value(new_cadidate.volume_link()) ||
0124              new_cadidate.volume_link() < this->detector().volumes().size());
0125     }
0126 
0127     /// If the current target is reached, move it to the first position in
0128     /// the cache and reset the target slot
0129     DETRAY_HOST_DEVICE
0130     constexpr void reset_candidate() {
0131       // Move the current candidate to the first cache position
0132       this->candidates()[0] = this->candidates()[1];
0133 
0134       // Flag the old candidate as invalid
0135       this->candidates()[1].set_path(std::numeric_limits<scalar_t>::max());
0136     }
0137   };
0138 
0139  private:
0140   /// Helper method to update the candidate (surface intersections)
0141   /// based on an externally provided trust level. Will (re-)initialize the
0142   /// navigation if there is no trust.
0143   ///
0144   /// @tparam track_t type of track, needs to provide pos() and dir() methods
0145   ///
0146   /// @param track access to the track parameters
0147   /// @param state the current navigation state
0148   /// @param cfg the navigation configuration
0149   /// @param ctx the geometry context
0150   template <typename track_t>
0151   DETRAY_HOST_DEVICE constexpr bool update_impl(const track_t &track,
0152                                                 state &navigation,
0153                                                 const navigation::config &cfg,
0154                                                 const context_type &ctx) const {
0155     const auto &det = navigation.detector();
0156     constexpr bool is_init{true};
0157 
0158     assert(navigation.trust_level() != navigation::trust_level::e_full);
0159 
0160     // Update only the current candidate and the corresponding
0161     // - do this only when the navigation state is still coherent
0162     if (navigation.trust_level() == navigation::trust_level::e_high) {
0163       DETRAY_VERBOSE_HOST_DEVICE("Called 'update()' - high trust");
0164 
0165       // Update next candidate: If not reachable, 'high trust' is broken
0166       if (!navigation::update_candidate(
0167               navigation.direction(), navigation.target(), track, det,
0168               cfg.intersection, navigation.external_tol(), ctx)) {
0169         navigation.status(navigation::status::e_unknown);
0170         // This will run into the fair trust case below.
0171         navigation.set_fair_trust();
0172       } else {
0173         // Update navigation flow on the new candidate information
0174         navigation::update_status(navigation, cfg);
0175 
0176         navigation.run_inspector(cfg, track.pos(), track.dir(),
0177                                  "Update complete: high trust: ");
0178 
0179         // The work is done if: the track has not reached a surface yet
0180         // or trust is gone (portal was reached or the cache is broken).
0181         if (navigation.status() == navigation::status::e_towards_object ||
0182             navigation.is_on_portal()) {
0183           return !is_init;
0184         }
0185         // Else (if full trust): Track is on non-portal surface and
0186         // cache is not exhausted. Move the current surface back in the
0187         // cache and re-initialize the volume to find the next target
0188         if (navigation.trust_level() == navigation::trust_level::e_full) {
0189           navigation.reset_candidate();
0190         }
0191 
0192         // Find the next/different candidate
0193         navigation.set_no_trust();
0194       }
0195     }
0196     // If [next] target is not reachable or actor flagged 'no trust',
0197     // re-initialize the volume.
0198     assert(navigation.trust_level() == navigation::trust_level::e_no_trust);
0199     DETRAY_VERBOSE_HOST_DEVICE("Called 'update()' - no trust");
0200 
0201     constexpr bool resolve_overstepping{true};
0202     navigation::local_navigation(track, navigation, cfg, ctx,
0203                                  resolve_overstepping);
0204     return is_init;
0205   }
0206 };
0207 
0208 }  // namespace detray