@@ -52,13 +52,28 @@ struct kalman_actor_state {
5252 reset ();
5353 }
5454
55+ // / Get the track state at a given position along the track
56+ TRACCC_HOST_DEVICE
57+ typename edm::track_state_collection<algebra_t >::device::proxy_type at (
58+ unsigned int i) {
59+ assert (m_track.constituent_links ().at (m_idx).type ==
60+ edm::track_constituent_link::track_state);
61+ return m_track_states.at (m_track.constituent_links ().at (i).index );
62+ }
63+
64+ // / Get the track state at a given position along the track
65+ TRACCC_HOST_DEVICE
66+ auto at (unsigned int i) const {
67+ assert (m_track.constituent_links ().at (m_idx).type ==
68+ edm::track_constituent_link::track_state);
69+ return m_track_states.at (m_track.constituent_links ().at (i).index );
70+ }
71+
5572 // / @return the reference of track state pointed by the iterator
5673 TRACCC_HOST_DEVICE
5774 typename edm::track_state_collection<algebra_t >::device::proxy_type
5875 operator ()() {
59- assert (m_track.constituent_links ().at (m_idx).type ==
60- edm::track_constituent_link::track_state);
61- return m_track_states.at (m_track.constituent_links ().at (m_idx).index );
76+ return at (m_idx);
6277 }
6378
6479 // / Reset the iterator
@@ -67,8 +82,9 @@ struct kalman_actor_state {
6782 if (!backward_mode) {
6883 m_idx = 0 ;
6984 } else {
70- m_idx = m_track. constituent_links (). size () - 1 ;
85+ m_idx = size () - 1 ;
7186 }
87+ n_holes = 0u ;
7288 }
7389
7490 // / Advance the iterator
@@ -81,24 +97,61 @@ struct kalman_actor_state {
8197 }
8298 }
8399
100+ // / @returns the number of track states
101+ TRACCC_HOST_DEVICE
102+ unsigned int size () /* const*/ { return m_track.constituent_links ().size (); }
103+
84104 // / @return true if the iterator reaches the end of vector
85105 TRACCC_HOST_DEVICE
86- bool is_complete () {
87- if (!backward_mode && m_idx == m_track.constituent_links ().size ()) {
88- return true ;
89- } else if (backward_mode &&
90- m_idx > m_track.constituent_links ().size ()) {
91- return true ;
92- }
93- return false ;
106+ bool is_complete () /* const*/ {
107+ return (!backward_mode && m_idx == size ()) ||
108+ (backward_mode && m_idx > size ());
94109 }
95110
96111 TRACCC_HOST_DEVICE
97- bool is_state () {
112+ bool is_state () /* const */ {
98113 return (m_track.constituent_links ().at (m_idx).type ==
99114 edm::track_constituent_link::track_state);
100115 }
101116
117+ // / @returns the current number of missed states during forward fit
118+ TRACCC_HOST_DEVICE
119+ unsigned int count_missed_fit () /* const*/ {
120+ unsigned int n_missed{0u };
121+
122+ for (unsigned int i = 0u ; i < size (); ++i) {
123+ const auto trk_state = at (i);
124+ if (!trk_state.is_hole () &&
125+ trk_state.filtered_params ().is_invalid ()) {
126+ TRACCC_DEBUG_HOST_DEVICE (
127+ " Missed track state %d/%d on surface %d during forward fit" ,
128+ i, size (), at (i).filtered_params ().surface_link ().index ());
129+ ++n_missed;
130+ }
131+ }
132+
133+ return n_missed;
134+ }
135+
136+ // / @returns the current number of missed states during smoothing
137+ TRACCC_HOST_DEVICE
138+ unsigned int count_missed_smoother () /* const*/ {
139+ unsigned int n_missed{0u };
140+
141+ for (unsigned int i = 0u ; i < size (); ++i) {
142+ const auto trk_state = at (i);
143+ if (!trk_state.is_hole () &&
144+ trk_state.smoothed_params ().is_invalid ()) {
145+ TRACCC_DEBUG_HOST_DEVICE (
146+ " Missed track state %d/%d on surface %d during smoothing" ,
147+ i, size (), at (i).smoothed_params ().surface_link ().index ());
148+ ++n_missed;
149+ }
150+ }
151+
152+ return n_missed;
153+ }
154+
102155 // / Object describing the track fit
103156 typename edm::track_collection<algebra_t >::device::proxy_type m_track;
104157 // / All track states in the event
@@ -110,12 +163,15 @@ struct kalman_actor_state {
110163 // / Index of the current track state
111164 unsigned int m_idx;
112165
113- // The number of holes (The number of sensitive surfaces which do not
114- // have a measurement for the track pattern)
166+ // / The number of holes (The number of sensitive surfaces which do not
167+ // / have a measurement for the track pattern)
115168 unsigned int n_holes{0u };
116169
117- // Run back filtering for smoothing, if true
170+ // / Run back filtering for smoothing, if true
118171 bool backward_mode = false ;
172+
173+ // / Result of the fitter pass
174+ kalman_fitter_status fit_result = kalman_fitter_status::SUCCESS;
119175};
120176
121177// / Detray actor for Kalman filtering
@@ -142,20 +198,18 @@ struct kalman_actor : detray::actor {
142198 return ;
143199 }
144200
201+ TRACCC_VERBOSE_HOST_DEVICE (" In Kalman actor..." );
202+ TRACCC_VERBOSE_HOST (
203+ " Expected: " << actor_state ().filtered_params ().surface_link ());
204+
145205 // triggered only for sensitive surfaces
146206 if (navigation.is_on_sensitive ()) {
147207
148- TRACCC_VERBOSE_HOST_DEVICE (" In Kalman actor..." );
149208 TRACCC_DEBUG_HOST (" -> on surface: " << navigation.get_surface ());
150209
151210 typename edm::track_state_collection<algebra_t >::device::proxy_type
152211 trk_state = actor_state ();
153212
154- TRACCC_DEBUG_HOST (
155- " -> expecting: " << actor_state.m_measurements
156- .at (trk_state.measurement_index ())
157- .surface_link );
158-
159213 // Increase the hole counts if the propagator fails to find the next
160214 // measurement
161215 if (navigation.barcode () !=
@@ -167,36 +221,28 @@ struct kalman_actor : detray::actor {
167221 return ;
168222 }
169223
170- TRACCC_VERBOSE_HOST_DEVICE (" Found next track state to fit" );
171-
172- // This track state is not a hole
173- if (!actor_state.backward_mode ) {
174- trk_state.set_hole (false );
175- }
224+ auto & bound_param = stepping.bound_params ();
176225
177226 // Run Kalman Gain Updater
178227 const auto sf = navigation.get_surface ();
179-
180228 const bool is_line = detail::is_line (sf);
181229
182- kalman_fitter_status res = kalman_fitter_status::SUCCESS;
183-
184230 if (!actor_state.backward_mode ) {
185231 if constexpr (direction_e ==
186232 kalman_actor_direction::FORWARD_ONLY ||
187233 direction_e ==
188234 kalman_actor_direction::BIDIRECTIONAL) {
189235 // Wrap the phi and theta angles in their valid ranges
190- normalize_angles (propagation. _stepping . bound_params () );
236+ normalize_angles (bound_param );
191237
192238 // Forward filter
193- TRACCC_DEBUG_HOST_DEVICE (" Run filtering" );
194- res = gain_matrix_updater<algebra_t >{}(
195- trk_state, actor_state.m_measurements ,
196- propagation. _stepping . bound_params (), is_line);
239+ TRACCC_DEBUG_HOST_DEVICE (" Run filtering... " );
240+ actor_state. fit_result = gain_matrix_updater<algebra_t >{}(
241+ trk_state, actor_state.m_measurements , bound_param,
242+ is_line);
197243
198244 // Update the propagation flow
199- stepping. bound_params () = trk_state.filtered_params ();
245+ bound_param = trk_state.filtered_params ();
200246 } else {
201247 assert (false );
202248 }
@@ -205,39 +251,50 @@ struct kalman_actor : detray::actor {
205251 kalman_actor_direction::BACKWARD_ONLY ||
206252 direction_e ==
207253 kalman_actor_direction::BIDIRECTIONAL) {
208- // Backward filter for smoothing
209- TRACCC_DEBUG_HOST_DEVICE (" Run smoothing" );
210- res = two_filters_smoother<algebra_t >{}(
211- trk_state, actor_state.m_measurements ,
212- propagation._stepping .bound_params (), is_line);
254+ TRACCC_DEBUG_HOST_DEVICE (" Run smoothing..." );
255+
256+ // Forward filter did not find this state: cannot smoothe
257+ if (trk_state.filtered_params ().is_invalid ()) {
258+ TRACCC_ERROR_HOST_DEVICE (
259+ " Track state not filtered by forward fit. "
260+ " Skipping" );
261+ actor_state.fit_result =
262+ kalman_fitter_status::ERROR_UPDATER_SKIPPED_STATE;
263+ } else {
264+ actor_state.fit_result =
265+ two_filters_smoother<algebra_t >{}(
266+ trk_state, actor_state.m_measurements ,
267+ bound_param, is_line);
268+ }
213269 } else {
214270 assert (false );
215271 }
216272 }
217273
218274 // Abort if the Kalman update fails
219- if (res != kalman_fitter_status::SUCCESS) {
275+ if (actor_state. fit_result != kalman_fitter_status::SUCCESS) {
220276 if (actor_state.backward_mode ) {
221277 TRACCC_ERROR_DEVICE (" Abort backward fit: KF status %d" ,
222- res );
278+ actor_state. fit_result );
223279 TRACCC_ERROR_HOST (
224- " Abort backward fit: " << fitter_debug_msg{res}());
280+ " Abort backward fit: "
281+ << fitter_debug_msg{actor_state.fit_result }());
225282 } else {
226- TRACCC_ERROR_DEVICE (" Abort forward fit: KF status %d" , res);
227- TRACCC_ERROR_HOST (
228- " Abort forward fit: " << fitter_debug_msg{res}());
283+ TRACCC_ERROR_DEVICE (" Abort forward fit: KF status %d" ,
284+ actor_state.fit_result );
285+ TRACCC_ERROR_HOST (" Abort forward fit: " << fitter_debug_msg{
286+ actor_state.fit_result }());
229287 }
230288 propagation._heartbeat &=
231- navigation.abort (fitter_debug_msg{res });
289+ navigation.abort (fitter_debug_msg{actor_state. fit_result });
232290 return ;
233291 }
234292
235293 // Change the charge of hypothesized particles when the sign of qop
236294 // is changed (This rarely happens when qop is set with a poor seed
237295 // resolution)
238296 propagation.set_particle (detail::correct_particle_hypothesis (
239- stepping.particle_hypothesis (),
240- propagation._stepping .bound_params ()));
297+ stepping.particle_hypothesis (), bound_param));
241298
242299 // Update iterator
243300 actor_state.next ();
0 commit comments