12#include "detray/core/concepts.hpp"
13#include "detray/core/detector.hpp"
14#include "detray/definitions/algorithms.hpp"
15#include "detray/definitions/containers.hpp"
16#include "detray/definitions/detail/qualifiers.hpp"
17#include "detray/definitions/indexing.hpp"
18#include "detray/definitions/navigation.hpp"
19#include "detray/definitions/units.hpp"
20#include "detray/navigation/detail/intersection_kernel.hpp"
21#include "detray/navigation/detail/navigation_functions.hpp"
22#include "detray/navigation/intersection/intersection.hpp"
23#include "detray/navigation/intersection/intersection_config.hpp"
24#include "detray/navigation/intersection/ray_intersector.hpp"
25#include "detray/navigation/navigation_config.hpp"
26#include "detray/navigation/navigation_state.hpp"
27#include "detray/tracks/ray.hpp"
37template <concepts::detector detector_t,
typename surface_sequence_t =
void>
39 using algebra_t =
typename detector_t::algebra_type;
53 std::same_as<surface_sequence_t, void>,
54 vecmem::device_vector<typename detector_t::surface_type>,
58 "Surface sequence must be iterable");
61 using surface_type = detray::ranges::range_value_t<surface_sequence_type>;
72 friend class direct_navigator;
74 template <
typename state_t>
75 friend constexpr void navigation::update_status(state_t &,
82 using dist_t = std::int_least16_t;
92 std::conditional_t<std::same_as<surface_sequence_t, void>,
93 detail::get_view_t<surface_sequence_type>,
97 std::conditional_t<std::same_as<surface_sequence_t, void>,
98 detail::get_view_t<const surface_sequence_type>,
105 DETRAY_HOST_DEVICE
constexpr state(
const detector_t &det,
107 : base_type(det), m_sequence(sequence) {
108 assert(!m_sequence.empty());
119 m_next_external = is_forward()
121 :
static_cast<dist_t
>(m_sequence.size() - 1u);
138 return std::numeric_limits<scalar_t>::max();
151 return (is_forward() &&
152 m_next_external !=
static_cast<dist_t
>(m_sequence.size())) ||
153 (!is_forward() && m_next_external != -1);
161 return m_sequence[
static_cast<unsigned int>(m_next_external)];
181 this->
target().set_surface(
182 m_sequence[
static_cast<unsigned int>(m_next_external)]);
188 this->
target().surface().has_material())));
208 m_next_external ==
static_cast<dist_t
>(m_sequence.size())) ||
209 (!is_forward() && m_next_external == -1));
217 constexpr bool is_forward()
const {
218 return this->
direction() == navigation::direction::e_forward;
225 dist_t m_next_external{0};
233 template <
typename track_t>
234 DETRAY_HOST_DEVICE
inline void init(
const track_t &track, state &navigation,
237 DETRAY_VERBOSE_HOST_DEVICE(
"Called 'init()':");
238 assert(navigation.has_next_external());
241 navigation.clear_cache();
244 update(track, navigation, cfg, ctx);
246 DETRAY_VERBOSE_HOST_DEVICE(
"Init complete!");
256 template <
typename track_t>
257 DETRAY_HOST_DEVICE
inline bool update(
const track_t &track, state &navigation,
260 DETRAY_VERBOSE_HOST_DEVICE(
"Called 'update()'");
261 DETRAY_DEBUG_HOST(
" -> Trust level: " << navigation.trust_level());
264 assert(navigation.is_alive() ||
265 navigation.status() == navigation::status::e_unknown);
266 assert(!track.is_invalid());
269 constexpr bool is_init{
true};
270 if (!navigation.has_next_external()) {
271 DETRAY_VERBOSE_HOST_DEVICE(
"No next target in surface sequence: Exit");
279 if (navigation.trust_level() != navigation::trust_level::e_full) {
281 constexpr auto inf{std::numeric_limits<float>::max()};
282 const intersection::config intr_cfg{
286 const detray::detail::ray<algebra_t> tangential{
288 static_cast<scalar_t
>(navigation.direction()) * track.dir()};
292 if (!update_candidate(tangential, det, navigation, intr_cfg, ctx)) {
295 if (target_reached_within_tolerance(track, navigation, cfg)) {
296 navigation.target().set_path(
static_cast<scalar_t
>(0.f));
297 navigation.target().set_status(intersection::status::e_inside);
299 navigation.abort(
"Could not reach current target");
306 navigation::update_status(navigation, cfg);
308 navigation.trust_level(navigation::trust_level::e_full);
311 if (navigation.status() == navigation::status::e_towards_object) {
312 DETRAY_VERBOSE_HOST_DEVICE(
"Update complete (towards object):");
313 DETRAY_DEBUG_HOST(
"\n"
314 << detray::navigation::print_state(navigation)
315 << detray::navigation::print_candidates(
316 navigation, cfg, track.pos(), track.dir()));
322 if (navigation.has_next_external() &&
323 !update_candidate(tangential, det, navigation, intr_cfg, ctx)) {
324 navigation.abort(
"Could not find new target after surface was reached");
330 navigation.set_volume(navigation.current().surface().volume());
333 navigation.trust_level(navigation::trust_level::e_full);
335 DETRAY_VERBOSE_HOST_DEVICE(
"Update complete (on surface):");
336 DETRAY_DEBUG_HOST(
"\n"
337 << detray::navigation::print_state(navigation)
338 << detray::navigation::print_candidates(
339 navigation, cfg, track.pos(), track.dir()));
345 DETRAY_VERBOSE_HOST_DEVICE(
" -> Full trust: Nothing left to do");
353 DETRAY_HOST_DEVICE DETRAY_INLINE
constexpr bool update_candidate(
354 const detray::detail::ray<algebra_t> &tangential,
const detector_t &det,
355 state &navigation,
const intersection::config &intr_cfg,
357 if constexpr (std::same_as<surface_sequence_t, void>) {
359 return navigation::update_candidate(navigation.target(), tangential, det,
360 intr_cfg, navigation.external_tol(),
364 return update_external_candidate(navigation.target(), tangential,
365 navigation.next_external(), intr_cfg,
366 navigation.external_tol());
371 DETRAY_HOST_DEVICE DETRAY_INLINE
constexpr bool update_external_candidate(
373 const detray::detail::ray<algebra_t> &tangential,
const surface_type &sf,
374 const intersection::config &cfg,
375 const scalar_t external_mask_tolerance)
const {
377 algebra_t, !intersection::contains_pos>
381 typename decltype(intersector)::result_type result{};
382 if constexpr (concepts::cylindrical<typename surface_type::mask_type>) {
383 result = intersector.point_of_intersection(
384 tangential, sf.transform(), sf.mask(), cfg.overstep_tolerance);
386 result = intersector.point_of_intersection(tangential, sf.transform(),
387 cfg.overstep_tolerance);
391 if constexpr (
decltype(intersector)::n_solutions > 1) {
392 resolve_mask(candidate, tangential, result[0], candidate.surface(),
393 sf.mask(), sf.transform(), cfg, external_mask_tolerance);
395 resolve_mask(candidate, tangential, result, candidate.surface(),
396 sf.mask(), sf.transform(), cfg, external_mask_tolerance);
399 return candidate.is_probably_inside();
403 template <
typename track_t>
404 DETRAY_HOST_DEVICE DETRAY_INLINE
constexpr bool
405 target_reached_within_tolerance(
const track_t &track,
const state &navigation,
406 const navigation::config &cfg)
const {
407 if constexpr (std::same_as<surface_sequence_t, void>) {
410 const surface_type target_sf = navigation.target().surface();
411 const auto inside = target_sf.mask().is_inside(
412 target_sf.transform(), track.pos(),
413 static_cast<scalar_t
>(cfg.intersection.path_tolerance));
415 if constexpr (std::is_scalar_v<
decltype(inside)>) {
418 return detray::detail::any_of(inside);
Mutable state for traversing the external surface sequence.
Definition direct_navigator.hpp:71
constexpr bool finished() const
Definition direct_navigator.hpp:200
surface_sequence_type sequence_type
Range type retained by the navigation state.
Definition direct_navigator.hpp:88
void reset()
Reset the navigation state.
Definition direct_navigator.hpp:113
std::conditional_t< std::same_as< surface_sequence_t, void >, detail::get_view_t< const surface_sequence_type >, surface_sequence_type > const_view_type
Const view type corresponding to the configured sequence type.
Definition direct_navigator.hpp:96
constexpr void set_direction(const navigation::direction dir)
Set direction in which the navigator should search for candidates.
Definition direct_navigator.hpp:144
intersection_type value_type
Candidate value type stored in the base navigation state.
Definition direct_navigator.hpp:86
std::conditional_t< std::same_as< surface_sequence_t, void >, detail::get_view_t< surface_sequence_type >, surface_sequence_type > view_type
View used to access the sequence during navigation.
Definition direct_navigator.hpp:91
constexpr scalar_t external_tol() const
Definition direct_navigator.hpp:137
constexpr void advance()
Advance the iterator (navigation status needs to be up to date!).
Definition direct_navigator.hpp:166
constexpr auto n_candidates() const -> dindex
Definition direct_navigator.hpp:133
constexpr state(const detector_t &det, const view_type &sequence)
Constructor using the detector and an externally provided sequence of detector surfaces.
Definition direct_navigator.hpp:105
constexpr surface_type next_external()
Advance the iterator.
Definition direct_navigator.hpp:159
constexpr bool has_next_external() const
Definition direct_navigator.hpp:150
constexpr void clear_cache()
Clear the state.
Definition direct_navigator.hpp:192
Navigator that visits an externally supplied sequence of surfaces in order.
Definition direct_navigator.hpp:38
void init(const track_t &track, state &navigation, const navigation::config &cfg, const context_type &ctx) const
Initialize the direct navigation flow on the first/last external surface.
Definition direct_navigator.hpp:234
detector_t detector_type
Detector whose surfaces are navigated.
Definition direct_navigator.hpp:44
navigation::void_inspector inspector_type
Inspector policy used by the direct navigation flow.
Definition direct_navigator.hpp:66
detray::ranges::range_value_t< surface_sequence_type > surface_type
Descriptor type stored in the surface sequence.
Definition direct_navigator.hpp:61
intersection2D< surface_type, algebra_t, !intersection::contains_pos > intersection_type
Intersection record stored in the navigation state.
Definition direct_navigator.hpp:63
bool update(const track_t &track, state &navigation, const navigation::config &cfg, const context_type &ctx={}) const
Update the navigation status on the current next external and switch to the following external surfac...
Definition direct_navigator.hpp:257
std::conditional_t< std::same_as< surface_sequence_t, void >, vecmem::device_vector< typename detector_t::surface_type >, surface_sequence_t > surface_sequence_type
Range containing the surfaces visited by this navigator.
Definition direct_navigator.hpp:52
detector_type::geometry_context context_type
Geometry context expected by the detector.
Definition direct_navigator.hpp:46
This class holds the intersection information.
Definition intersection.hpp:212
A navigation state object used to cache the information of the current navigation stream.
Definition navigation_state.hpp:81
dscalar< algebra_t > scalar_t
Definition navigation_state.hpp:103
constexpr void clear_cache()
Definition navigation_state.hpp:600
constexpr auto candidates() const -> const candidate_cache_t &
Definition navigation_state.hpp:317
constexpr void set_direction(const navigation::direction dir)
Definition navigation_state.hpp:207
constexpr auto target() const -> const candidate_t &
Definition navigation_state.hpp:344
constexpr auto direction() const -> navigation::direction
Definition navigation_state.hpp:200
constexpr dist_t last_index() const
Definition navigation_state.hpp:537
constexpr bool finished() const
Definition navigation_state.hpp:293
constexpr dist_t next_index() const
Definition navigation_state.hpp:533
std::int_least8_t dist_t
Definition navigation_state.hpp:119
detector_t detector_type
Definition navigation_state.hpp:127
Range concept.
Definition ranges.hpp:97
Detray include(s).
Definition array_operators.hpp:18
get_scalar_t< A, T > dscalar
Scalar type for algebra A and value type T.
Definition algebra.hpp:64
constexpr void resolve_mask(intersection_t &is, const trajectory_t &traj, const intersection_point< algebra_t, point_t, intersection::contains_pos > &ip, const surface_descr_t sf_desc, const mask_t &mask, const transform3_t &trf, const intersection::config &cfg={}, const scalar_t external_mask_tolerance=0.f)
Fill an intersection with the result of the intersection alg.
Definition intersector_base.hpp:189
unsigned int dindex
Default index type.
Definition indexing.hpp:18
intersector_base< ray_intersector_impl< typename shape_t::template local_frame_type< algebra_t >, algebra_t, resolve_pos > > ray_intersector
Select the ray intersector specialization for a shape's local frame.
Definition ray_intersector.hpp:36
float path_tolerance
Maximal absolute path distance for a track to be considered 'on surface'.
Definition intersection_config.hpp:32
Navigation configuration.
Definition navigation_config.hpp:24
intersection::config intersection
Tolerance on the mask 'is_inside' check:
Definition navigation_config.hpp:26
A void inpector that does nothing.
Definition navigation_state.hpp:38