Skip to content

Commit ced0979

Browse files
committed
Improve kalman fitter error handling
1 parent b719deb commit ced0979

14 files changed

Lines changed: 314 additions & 111 deletions

core/include/traccc/edm/impl/track_state_helpers.ipp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ TRACCC_HOST_DEVICE
1919
// Create the result object.
2020
typename track_state_collection<algebra_t>::device::object_type state;
2121

22-
// Set it to be a hole by default, with the appropriate (measurement) index.
23-
state.set_hole();
22+
// Set it not to be a hole by default, with the appropriate (measurement)
23+
// index.
24+
state.set_hole(false);
2425
state.measurement_index() = mindex;
2526

2627
// Set the correct surface link for the track parameters.

core/include/traccc/edm/track_fit_outcome.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ enum class track_fit_outcome : std::uint16_t {
1717
UNKNOWN,
1818
SUCCESS,
1919
FAILURE_NON_POSITIVE_NDF,
20+
FAILURE_NOT_ALL_FITTED,
2021
FAILURE_NOT_ALL_SMOOTHED,
22+
FAILURE_FITTER,
23+
FAILURE_SMOOTHER,
24+
FAILURE_FORWARD_PROPAGATION,
25+
FAILURE_BACKWARD_PROPAGATION,
2126
MAX_OUTCOME
2227
};
2328

core/include/traccc/finding/actors/ckf_aborter.hpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,10 @@ struct ckf_aborter : detray::actor {
5151
abrt_state.path_from_surface > abrt_state.min_step_length) {
5252
prop_state._heartbeat &= navigation.pause();
5353
abrt_state.success = true;
54-
}
55-
56-
TRACCC_VERBOSE_HOST_DEVICE("-> Found sensitive surface: %d",
57-
navigation.barcode().index());
58-
59-
// Reset path from surface
60-
if (navigation.is_on_sensitive()) {
6154
abrt_state.path_from_surface = 0.f;
55+
56+
TRACCC_VERBOSE_HOST_DEVICE("-> Found sensitive surface: %d",
57+
navigation.barcode().index());
6258
}
6359

6460
if (abrt_state.count > abrt_state.max_count) {

core/include/traccc/finding/details/combinatorial_kalman_filter.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -522,15 +522,16 @@ combinatorial_kalman_filter(
522522
TRACCC_DEBUG_HOST("Propagating... ");
523523
propagator.propagate(propagation,
524524
detray::tie(s0, s1, s2, s3, s4, s5));
525-
TRACCC_DEBUG_HOST("Finished propagation: On surface "
526-
<< propagation._navigation.barcode());
525+
TRACCC_DEBUG_HOST("Finished propagation");
527526

528527
// If a surface found, add the parameter for the next
529528
// step
530529
bool valid_track{s5.success};
531530
if (valid_track) {
532531
assert(propagation._navigation.is_on_sensitive());
533532
assert(!propagation._stepping.bound_params().is_invalid());
533+
TRACCC_DEBUG_HOST(
534+
"On surface: " << propagation._navigation.barcode());
534535

535536
const auto& out_param = propagation._stepping.bound_params();
536537

core/include/traccc/finding/details/combinatorial_kalman_filter_types.hpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,7 @@
1414
#include "traccc/finding/actors/interaction_register.hpp"
1515

1616
// Detray include(s).
17-
#include <detray/navigation/navigator.hpp>
18-
#include <detray/propagator/actor_chain.hpp>
19-
#include <detray/propagator/actors/aborters.hpp>
20-
#include <detray/propagator/actors/parameter_resetter.hpp>
21-
#include <detray/propagator/actors/parameter_transporter.hpp>
22-
#include <detray/propagator/actors/pointwise_material_interactor.hpp>
23-
#include <detray/propagator/constrained_step.hpp>
24-
#include <detray/propagator/propagator.hpp>
25-
#include <detray/propagator/rk_stepper.hpp>
17+
#include "traccc/utils/propagation.hpp"
2618

2719
// System include(s).
2820
#include <type_traits>

core/include/traccc/fitting/kalman_filter/gain_matrix_updater.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,7 @@ struct gain_matrix_updater {
209209

210210
const scalar theta = trk_state.filtered_params().theta();
211211
if (theta <= 0.f || theta >= 2.f * constant<traccc::scalar>::pi) {
212-
TRACCC_ERROR_HOST_DEVICE("Hit theta pole after filtering : %f",
213-
theta);
212+
TRACCC_ERROR_HOST_DEVICE("Hit theta pole in filtering : %f", theta);
214213
return kalman_fitter_status::ERROR_THETA_POLE;
215214
}
216215

core/include/traccc/fitting/kalman_filter/kalman_actor.hpp

Lines changed: 108 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)