Skip to content

Commit c794b66

Browse files
authored
Improve kalman fitter error handling (#1191)
Expand on the number of Kalman fit status codes and track fit outcomes to make a more fine-grained distinction between different error types in the Kalman fitter possible. Takes up the improvements in #1177. Edit: The wire chamber Kalman fitter test had to be adapted, because more error states are recognized Edit2: Also fixed the condition of is_complete for the backward fit to point one position below the first state
1 parent d8261ad commit c794b66

File tree

14 files changed

+317
-112
lines changed

14 files changed

+317
-112
lines changed

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
@@ -210,8 +210,7 @@ struct gain_matrix_updater {
210210

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

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

Lines changed: 117 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,29 @@ 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(i).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(i).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+
assert(m_idx >= 0);
77+
return at(static_cast<unsigned int>(m_idx));
6278
}
6379

6480
/// Reset the iterator
@@ -67,8 +83,9 @@ struct kalman_actor_state {
6783
if (!backward_mode) {
6884
m_idx = 0;
6985
} else {
70-
m_idx = m_track.constituent_links().size() - 1;
86+
m_idx = static_cast<int>(size()) - 1;
7187
}
88+
n_holes = 0u;
7289
}
7390

7491
/// Advance the iterator
@@ -81,22 +98,65 @@ struct kalman_actor_state {
8198
}
8299
}
83100

101+
/// @TODO: Const-correctness broken due to a vecmem bug
102+
/// @returns the number of track states
103+
TRACCC_HOST_DEVICE
104+
unsigned int size() /*const*/ { return m_track.constituent_links().size(); }
105+
84106
/// @return true if the iterator reaches the end of vector
85107
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;
108+
bool is_complete() /*const*/ {
109+
return (!backward_mode && m_idx == static_cast<int>(size())) ||
110+
(backward_mode && m_idx == -1);
111+
}
112+
113+
/// @TODO: Const-correctness broken due to a vecmem bug
114+
TRACCC_HOST_DEVICE
115+
bool is_state() /* const*/ {
116+
assert(m_idx >= 0);
117+
return (m_track.constituent_links()
118+
.at(static_cast<unsigned int>(m_idx))
119+
.type == edm::track_constituent_link::track_state);
120+
}
121+
122+
/// @TODO: Const-correctness broken due to a vecmem bug
123+
/// @returns the current number of missed states during forward fit
124+
TRACCC_HOST_DEVICE
125+
unsigned int count_missed_fit() /*const*/ {
126+
unsigned int n_missed{0u};
127+
128+
for (unsigned int i = 0u; i < size(); ++i) {
129+
const auto trk_state = at(i);
130+
if (!trk_state.is_hole() &&
131+
trk_state.filtered_params().is_invalid()) {
132+
TRACCC_DEBUG_HOST_DEVICE(
133+
"Missed track state %d/%d on surface %d during forward fit",
134+
i, size(), at(i).filtered_params().surface_link().index());
135+
++n_missed;
136+
}
92137
}
93-
return false;
138+
139+
return n_missed;
94140
}
95141

142+
/// @TODO: Const-correctness broken due to a vecmem bug
143+
/// @returns the current number of missed states during smoothing
96144
TRACCC_HOST_DEVICE
97-
bool is_state() {
98-
return (m_track.constituent_links().at(m_idx).type ==
99-
edm::track_constituent_link::track_state);
145+
unsigned int count_missed_smoother() /*const*/ {
146+
unsigned int n_missed{0u};
147+
148+
for (unsigned int i = 0u; i < size(); ++i) {
149+
const auto trk_state = at(i);
150+
if (!trk_state.is_hole() &&
151+
trk_state.smoothed_params().is_invalid()) {
152+
TRACCC_DEBUG_HOST_DEVICE(
153+
"Missed track state %d/%d on surface %d during smoothing",
154+
i, size(), at(i).smoothed_params().surface_link().index());
155+
++n_missed;
156+
}
157+
}
158+
159+
return n_missed;
100160
}
101161

102162
/// Object describing the track fit
@@ -108,14 +168,17 @@ struct kalman_actor_state {
108168
m_measurements;
109169

110170
/// Index of the current track state
111-
unsigned int m_idx;
171+
int m_idx;
112172

113-
// The number of holes (The number of sensitive surfaces which do not
114-
// have a measurement for the track pattern)
173+
/// The number of holes (The number of sensitive surfaces which do not
174+
/// have a measurement for the track pattern)
115175
unsigned int n_holes{0u};
116176

117-
// Run back filtering for smoothing, if true
177+
/// Run back filtering for smoothing, if true
118178
bool backward_mode = false;
179+
180+
/// Result of the fitter pass
181+
kalman_fitter_status fit_result = kalman_fitter_status::SUCCESS;
119182
};
120183

121184
/// Detray actor for Kalman filtering
@@ -142,20 +205,18 @@ struct kalman_actor : detray::actor {
142205
return;
143206
}
144207

208+
TRACCC_VERBOSE_HOST_DEVICE("In Kalman actor...");
209+
TRACCC_VERBOSE_HOST(
210+
"Expected: " << actor_state().filtered_params().surface_link());
211+
145212
// triggered only for sensitive surfaces
146213
if (navigation.is_on_sensitive()) {
147214

148-
TRACCC_VERBOSE_HOST_DEVICE("In Kalman actor...");
149215
TRACCC_DEBUG_HOST("-> on surface: " << navigation.get_surface());
150216

151217
typename edm::track_state_collection<algebra_t>::device::proxy_type
152218
trk_state = actor_state();
153219

154-
TRACCC_DEBUG_HOST(
155-
"-> expecting: " << actor_state.m_measurements
156-
.at(trk_state.measurement_index())
157-
.surface_link);
158-
159220
// Increase the hole counts if the propagator fails to find the next
160221
// measurement
161222
if (navigation.barcode() !=
@@ -167,36 +228,28 @@ struct kalman_actor : detray::actor {
167228
return;
168229
}
169230

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-
}
231+
auto& bound_param = stepping.bound_params();
176232

177233
// Run Kalman Gain Updater
178234
const auto sf = navigation.get_surface();
179-
180235
const bool is_line = detail::is_line(sf);
181236

182-
kalman_fitter_status res = kalman_fitter_status::SUCCESS;
183-
184237
if (!actor_state.backward_mode) {
185238
if constexpr (direction_e ==
186239
kalman_actor_direction::FORWARD_ONLY ||
187240
direction_e ==
188241
kalman_actor_direction::BIDIRECTIONAL) {
189242
// Wrap the phi and theta angles in their valid ranges
190-
normalize_angles(propagation._stepping.bound_params());
243+
normalize_angles(bound_param);
191244

192245
// 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);
246+
TRACCC_DEBUG_HOST_DEVICE("Run filtering...");
247+
actor_state.fit_result = gain_matrix_updater<algebra_t>{}(
248+
trk_state, actor_state.m_measurements, bound_param,
249+
is_line);
197250

198251
// Update the propagation flow
199-
stepping.bound_params() = trk_state.filtered_params();
252+
bound_param = trk_state.filtered_params();
200253
} else {
201254
assert(false);
202255
}
@@ -205,39 +258,50 @@ struct kalman_actor : detray::actor {
205258
kalman_actor_direction::BACKWARD_ONLY ||
206259
direction_e ==
207260
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);
261+
TRACCC_DEBUG_HOST_DEVICE("Run smoothing...");
262+
263+
// Forward filter did not find this state: cannot smoothe
264+
if (trk_state.filtered_params().is_invalid()) {
265+
TRACCC_ERROR_HOST_DEVICE(
266+
"Track state not filtered by forward fit. "
267+
"Skipping");
268+
actor_state.fit_result =
269+
kalman_fitter_status::ERROR_UPDATER_SKIPPED_STATE;
270+
} else {
271+
actor_state.fit_result =
272+
two_filters_smoother<algebra_t>{}(
273+
trk_state, actor_state.m_measurements,
274+
bound_param, is_line);
275+
}
213276
} else {
214277
assert(false);
215278
}
216279
}
217280

218281
// Abort if the Kalman update fails
219-
if (res != kalman_fitter_status::SUCCESS) {
282+
if (actor_state.fit_result != kalman_fitter_status::SUCCESS) {
220283
if (actor_state.backward_mode) {
221284
TRACCC_ERROR_DEVICE("Abort backward fit: KF status %d",
222-
res);
285+
actor_state.fit_result);
223286
TRACCC_ERROR_HOST(
224-
"Abort backward fit: " << fitter_debug_msg{res}());
287+
"Abort backward fit: "
288+
<< fitter_debug_msg{actor_state.fit_result}());
225289
} else {
226-
TRACCC_ERROR_DEVICE("Abort forward fit: KF status %d", res);
227-
TRACCC_ERROR_HOST(
228-
"Abort forward fit: " << fitter_debug_msg{res}());
290+
TRACCC_ERROR_DEVICE("Abort forward fit: KF status %d",
291+
actor_state.fit_result);
292+
TRACCC_ERROR_HOST("Abort forward fit: " << fitter_debug_msg{
293+
actor_state.fit_result}());
229294
}
230295
propagation._heartbeat &=
231-
navigation.abort(fitter_debug_msg{res});
296+
navigation.abort(fitter_debug_msg{actor_state.fit_result});
232297
return;
233298
}
234299

235300
// Change the charge of hypothesized particles when the sign of qop
236301
// is changed (This rarely happens when qop is set with a poor seed
237302
// resolution)
238303
propagation.set_particle(detail::correct_particle_hypothesis(
239-
stepping.particle_hypothesis(),
240-
propagation._stepping.bound_params()));
304+
stepping.particle_hypothesis(), bound_param));
241305

242306
// Update iterator
243307
actor_state.next();

0 commit comments

Comments
 (0)