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
@@ -90,7 +154,7 @@ struct parameter_transporter : actor {
90154 const auto sf = navigation.get_surface ();
91155
92156 // Bound track params of departure surface
93- auto & bound_params = stepping .bound_params ();
157+ auto & bound_params = transporter_state .bound_params ();
94158
95159 // Covariance is transported only when the previous surface is an
96160 // actual tracking surface. (i.e. This disables the covariance transport
@@ -108,17 +172,17 @@ struct parameter_transporter : actor {
108172 const auto vol_mat_ptr =
109173 vol.has_material () ? vol.material_parameters (stepping ().pos ())
110174 : nullptr ;
111- stepping .set_full_jacobian (
175+ transporter_state .set_full_jacobian (
112176 sf.template visit_mask <get_full_jacobian_kernel>(
113177 sf.transform (gctx), bound_to_free_jacobian, vol_mat_ptr,
114178 propagation._stepping ));
115179
116180 // Calculate surface-to-surface covariance transport
117- const bound_matrix_t new_cov =
118- stepping .full_jacobian () * bound_params.covariance () *
119- matrix_operator ().transpose (stepping .full_jacobian ());
181+ const bound_matrix_type new_cov =
182+ transporter_state .full_jacobian () * bound_params.covariance () *
183+ matrix_operator ().transpose (transporter_state .full_jacobian ());
120184
121- stepping. bound_params () .set_covariance (new_cov);
185+ bound_params.set_covariance (new_cov);
122186 }
123187
124188 // Convert free to bound vector
@@ -128,7 +192,43 @@ struct parameter_transporter : actor {
128192 // Set surface link
129193 bound_params.set_surface_link (sf.barcode ());
130194 }
195+ };
196+
197+ // / Update the stepper state after the bound track parameters were updated
198+ template <typename algebra_t >
199+ struct parameter_resetter : actor {
200+
201+ template <typename propagator_state_t >
202+ DETRAY_HOST_DEVICE void operator ()(
203+ const parameter_transporter<algebra_t >::state& transporter_state,
204+ propagator_state_t & propagation) const {
131205
132- }; // namespace detray
206+ const auto & navigation = propagation._navigation ;
207+ auto & stepping = propagation._stepping ;
208+
209+ // Do covariance transport when the track is on surface
210+ if (!(navigation.is_on_sensitive () ||
211+ navigation.encountered_sf_material ())) {
212+ return ;
213+ }
214+
215+ typename propagator_state_t ::detector_type::geometry_context ctx{};
216+
217+ // Update free params after bound params were changed by actors
218+ const auto sf = navigation.get_surface ();
219+ stepping () =
220+ sf.bound_to_free_vector (ctx, transporter_state.bound_params ());
221+
222+ // Reset jacobian transport to identity matrix
223+ stepping.reset_transport_jacobian ();
224+ }
225+ };
226+
227+ // / Call actors that depend on the bound track parameters safely together with
228+ // / the parameter transporter and parameter resetter
229+ template <typename algebra_t , typename ... transporter_observers>
230+ using parameter_updater =
231+ composite_actor<detray::tuple, parameter_transporter<algebra_t >,
232+ transporter_observers..., parameter_resetter<algebra_t >>;
133233
134234} // namespace detray
0 commit comments