ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
perigee_stopper.hpp
1// This file is part of the ACTS project.
2//
3// Copyright (C) 2016 CERN for the benefit of the ACTS project
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9#pragma once
10
11// Project include(s)
12#include "detray/definitions/algebra.hpp"
13#include "detray/definitions/detail/qualifiers.hpp"
14#include "detray/definitions/geometry.hpp"
15#include "detray/geometry/mask.hpp"
16#include "detray/geometry/shapes/line.hpp"
17#include "detray/geometry/tracking_volume.hpp"
18#include "detray/navigation/caching_navigator.hpp"
19#include "detray/navigation/intersection/ray_intersector.hpp"
20#include "detray/propagator/base_actor.hpp"
21#include "detray/propagator/constrained_step.hpp"
22#include "detray/tracks/ray.hpp"
23#include "detray/utils/curvilinear_frame.hpp"
24
25namespace detray {
26
30template <concepts::algebra algebra_t>
31struct perigee_stopper : public base_actor {
34
36 struct state {
42 // @TODO Make smaller once overstepping is solved
45 unsigned int m_inner_vol_idx{0u};
46 };
47
53 template <typename propagator_state_t>
54 DETRAY_HOST_DEVICE void operator()(state &actor_state,
55 propagator_state_t &prop_state) const {
56 using detector_t = typename propagator_state_t::detector_type;
57 using perigee_intersector_t = ray_intersector<line_circular, algebra_t>;
58
59 // Nothing left to do. Propagation will exit successfully on its own
60 auto &navigation = prop_state.navigation();
61 if (navigation.finished()) {
62 return;
63 }
64
65 // Only check this in the innermost volume and during backward nav.
66 if (navigation.volume() != actor_state.m_inner_vol_idx ||
67 navigation.direction() != navigation::direction::e_backward) {
68 return;
69 }
70
71 // Volume that contains the IP
72 const tracking_volume inner_vol{navigation.detector(),
73 actor_state.m_inner_vol_idx};
74
75 // Stop at the perigee (cylindrical detectors only)
76 if (inner_vol.id() != volume_id::e_cylinder) {
77 return;
78 }
79
80 // At least the exit portal should be reachable
81 if (navigation.cache_exhausted()) {
82 navigation.abort("Perigee stopper has no next candidate");
83 prop_state.heartbeat(false);
84 return;
85 }
86
87 auto &stepping = prop_state.stepping();
88 auto &track = stepping();
89
90 // Linear track approximation
91 const detail::ray<algebra_t> trk_approx{track.pos(), -1.f * track.dir()};
92
93 // Check the stopping radius (outside the track will not be stopped)
94 assert(actor_state.m_stopping_radius > 0.f);
95 constexpr scalar_t max_hz{detail::invalid_value<scalar_t>()};
96
97 using perigee_mask_t = mask<line_circular, algebra_t>;
98 const perigee_mask_t perigee_mask{
99 static_cast<typename perigee_mask_t::links_type>(
100 actor_state.m_inner_vol_idx),
101 actor_state.m_stopping_radius, max_hz};
102
103 // The perigee is not linked to any detector surface
104 constexpr typename detector_t::surface_type inv_sf{};
105 const dtransform3D<algebra_t> identity{};
106 constexpr scalar_t mask_tolerance{0.f};
107 constexpr scalar_t overstep_tolerance{-detail::invalid_value<scalar_t>()};
108
109 const auto perigee_intr =
110 perigee_intersector_t{}(trk_approx, inv_sf, perigee_mask, identity,
111 mask_tolerance, overstep_tolerance);
112
113 scalar_t dist_to_cand{std::as_const(navigation).target().path()};
114 if (perigee_intr.is_probably_inside() &&
115 math::fabs(perigee_intr.path()) < math::fabs(dist_to_cand)) {
116 assert(actor_state.m_on_perigee_tol > 0.f);
117
118 // The track has reached the perigee: "exit success"
119 if (math::fabs(perigee_intr.path()) <= actor_state.m_on_perigee_tol) {
120 navigation.exit();
121 prop_state.heartbeat(false);
122 } else {
123 // @TODO: Use a guided navigator for this in order to catch
124 // overstepping correctly
125 stepping.template set_constraint<step::constraint::e_actor>(
126 perigee_intr.path());
127 }
128 }
129 }
130};
131
132} // namespace detray
describes a straight-line trajectory
Definition ray.hpp:22
Mask a region on a surface and link it to a volume.
Definition mask.hpp:46
Facade for a detray detector volume.
Definition tracking_volume.hpp:44
constexpr auto id() const -> volume_id
Definition tracking_volume.hpp:92
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
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
get_transform3D_t< A, T > dtransform3D
Three-dimensional transform type for algebra A and value type T.
Definition algebra.hpp:84
Base class actor implementation.
Definition base_actor.hpp:20
Per-actor configuration for checking the perigee.
Definition perigee_stopper.hpp:36
scalar_t m_stopping_radius
Radius around the beamline, where to test against the perigee Outside this radius,...
Definition perigee_stopper.hpp:40
unsigned int m_inner_vol_idx
Index of the innermost volume for this detector: Convention is 0.
Definition perigee_stopper.hpp:45
scalar_t m_on_perigee_tol
Tolerance under which to consider the track at the perigee.
Definition perigee_stopper.hpp:43
Actor that exits from a navigation stream, if it has reached the perigee.
Definition perigee_stopper.hpp:31
dscalar< algebra_t > scalar_t
Scalar type used by the algebra.
Definition perigee_stopper.hpp:33
void operator()(state &actor_state, propagator_state_t &prop_state) const
Intersects a linear track approximation with the perigee and exits the navigation,...
Definition perigee_stopper.hpp:54
static constexpr scalar_t um
Length, native unit mm.
Definition units.hpp:25
static constexpr scalar_t mm
Native length unit, the millimetre.
Definition units.hpp:27