1313#include " detray/geometry/tracking_surface.hpp"
1414#include " detray/propagator/base_actor.hpp"
1515#include " detray/propagator/detail/jacobian_engine.hpp"
16+ #include " detray/utils/curvilinear_frame.hpp"
1617
1718namespace detray {
1819
@@ -24,19 +25,81 @@ struct parameter_transporter : actor {
2425 using scalar_type = dscalar<algebra_t >;
2526 // Transformation matching this struct
2627 using transform3_type = dtransform3D<algebra_t >;
28+ // The track parameters bound to the current sensitive/material surface
29+ using bound_track_parameters_type = bound_track_parameters<algebra_t >;
2730 // Matrix actor
2831 using matrix_operator = dmatrix_operator<algebra_t >;
2932 // bound matrix type
30- using bound_matrix_t = bound_matrix<algebra_t >;
33+ using bound_matrix_type = bound_matrix<algebra_t >;
3134 // Matrix type for bound to free jacobian
3235 using bound_to_free_matrix_t = bound_to_free_matrix<algebra_t >;
3336 // / @}
3437
38+ struct state {
39+
40+ friend parameter_transporter;
41+
42+ state () = default ;
43+
44+ // / Start from free track parameters
45+ DETRAY_HOST_DEVICE
46+ explicit state (const free_track_parameters<algebra_t >& free_params) {
47+
48+ curvilinear_frame<algebra_t > cf (free_params);
49+
50+ // Set bound track parameters
51+ m_bound_params.set_parameter_vector (cf.m_bound_vec );
52+
53+ // A dummy covariance - should not be used
54+ m_bound_params.set_covariance (
55+ matrix_operator ()
56+ .template identity <e_bound_size, e_bound_size>());
57+
58+ // An invalid barcode - should not be used
59+ m_bound_params.set_surface_link (geometry::barcode{});
60+ }
61+
62+ // / Start from bound track parameters
63+ DETRAY_HOST_DEVICE
64+ explicit state (const bound_track_parameters_type& bound_params)
65+ : m_bound_params{bound_params} {}
66+
67+ // / @returns bound track parameters - const access
68+ DETRAY_HOST_DEVICE
69+ bound_track_parameters_type& bound_params () { return m_bound_params; }
70+
71+ // / @returns bound track parameters.
72+ DETRAY_HOST_DEVICE
73+ const bound_track_parameters_type& bound_params () const {
74+ return m_bound_params;
75+ }
76+
77+ // / @returns the current full Jacbian.
78+ DETRAY_HOST_DEVICE
79+ inline const bound_matrix_type& full_jacobian () const {
80+ return m_full_jacobian;
81+ }
82+
83+ private:
84+ // / Set new full Jacbian.
85+ DETRAY_HOST_DEVICE
86+ inline void set_full_jacobian (const bound_matrix_type& jac) {
87+ m_full_jacobian = jac;
88+ }
89+
90+ // / Full jacobian
91+ bound_matrix_type m_full_jacobian =
92+ matrix_operator ().template identity<e_bound_size, e_bound_size>();
93+
94+ // / bound covariance
95+ bound_track_parameters_type m_bound_params;
96+ };
97+
3598 struct get_full_jacobian_kernel {
3699
37100 template <typename mask_group_t , typename index_t ,
38101 typename stepper_state_t >
39- DETRAY_HOST_DEVICE inline bound_matrix_t operator ()(
102+ DETRAY_HOST_DEVICE inline bound_matrix_type operator ()(
40103 const mask_group_t & /* mask_group*/ , const index_t & /* index*/ ,
41104 const transform3_type& trf3,
42105 const bound_to_free_matrix_t & bound_to_free_jacobian,
@@ -73,7 +136,8 @@ struct parameter_transporter : actor {
73136 };
74137
75138 template <typename propagator_state_t >
76- DETRAY_HOST_DEVICE void operator ()(propagator_state_t & propagation) const {
139+ DETRAY_HOST_DEVICE void operator ()(state& transporter_state,
140+ propagator_state_t & propagation) const {
77141 auto & stepping = propagation._stepping ;
78142 const auto & navigation = propagation._navigation ;
79143
@@ -89,7 +153,7 @@ struct parameter_transporter : actor {
89153 const auto sf = navigation.get_surface ();
90154
91155 // Bound track params of departure surface
92- auto & bound_params = stepping .bound_params ();
156+ auto & bound_params = transporter_state .bound_params ();
93157
94158 // Covariance is transported only when the previous surface is an
95159 // actual tracking surface. (i.e. This disables the covariance transport
@@ -107,17 +171,17 @@ struct parameter_transporter : actor {
107171 const auto vol_mat_ptr =
108172 vol.has_material () ? vol.material_parameters (stepping ().pos ())
109173 : nullptr ;
110- stepping .set_full_jacobian (
174+ transporter_state .set_full_jacobian (
111175 sf.template visit_mask <get_full_jacobian_kernel>(
112176 sf.transform (ctx), bound_to_free_jacobian, vol_mat_ptr,
113177 propagation._stepping ));
114178
115179 // Calculate surface-to-surface covariance transport
116- const bound_matrix_t new_cov =
117- stepping .full_jacobian () * bound_params.covariance () *
118- matrix_operator ().transpose (stepping .full_jacobian ());
180+ const bound_matrix_type new_cov =
181+ transporter_state .full_jacobian () * bound_params.covariance () *
182+ matrix_operator ().transpose (transporter_state .full_jacobian ());
119183
120- stepping. bound_params () .set_covariance (new_cov);
184+ bound_params.set_covariance (new_cov);
121185 }
122186
123187 // Convert free to bound vector
@@ -127,7 +191,43 @@ struct parameter_transporter : actor {
127191 // Set surface link
128192 bound_params.set_surface_link (sf.barcode ());
129193 }
194+ };
195+
196+ // / Update the stepper state after the bound track parameters were updated
197+ template <typename algebra_t >
198+ struct parameter_resetter : actor {
199+
200+ template <typename propagator_state_t >
201+ DETRAY_HOST_DEVICE void operator ()(
202+ const parameter_transporter<algebra_t >::state& transporter_state,
203+ propagator_state_t & propagation) const {
130204
131- }; // namespace detray
205+ const auto & navigation = propagation._navigation ;
206+ auto & stepping = propagation._stepping ;
207+
208+ // Do covariance transport when the track is on surface
209+ if (!(navigation.is_on_sensitive () ||
210+ navigation.encountered_sf_material ())) {
211+ return ;
212+ }
213+
214+ typename propagator_state_t ::detector_type::geometry_context ctx{};
215+
216+ // Update free params after bound params were changed by actors
217+ const auto sf = navigation.get_surface ();
218+ stepping () =
219+ sf.bound_to_free_vector (ctx, transporter_state.bound_params ());
220+
221+ // Reset jacobian transport to identity matrix
222+ stepping.reset_transport_jacobian ();
223+ }
224+ };
225+
226+ // / Call actors that depend on the bound track parameters safely together with
227+ // / the parameter transporter and parameter resetter
228+ template <typename algebra_t , typename ... transporter_observers>
229+ using parameter_updater =
230+ composite_actor<detray::tuple, parameter_transporter<algebra_t >,
231+ transporter_observers..., parameter_resetter<algebra_t >>;
132232
133233} // namespace detray
0 commit comments