Skip to content

Commit 1ced46d

Browse files
committed
Fix bugs in the Kalman fitter
1 parent 4bc8979 commit 1ced46d

File tree

14 files changed

+281
-86
lines changed

14 files changed

+281
-86
lines changed

core/include/traccc/edm/track_parameters.hpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "traccc/definitions/qualifiers.hpp"
1515
#include "traccc/definitions/track_parametrization.hpp"
1616
#include "traccc/edm/container.hpp"
17+
#include "traccc/utils/trigonometric_helpers.hpp"
1718

1819
// detray include(s).
1920
#include <detray/tracks/tracks.hpp>
@@ -48,19 +49,15 @@ using bound_track_parameters_collection_types =
4849

4950
// Wrap the phi of track parameters to [-pi,pi]
5051
template <detray::concepts::algebra algebra_t>
51-
TRACCC_HOST_DEVICE inline void wrap_phi(
52+
TRACCC_HOST_DEVICE constexpr void normalize_angles(
5253
bound_track_parameters<algebra_t>& param) {
54+
traccc::scalar phi;
55+
traccc::scalar theta;
56+
57+
std::tie(phi, theta) = detail::wrap_phi_theta(param.phi(), param.theta());
5358

54-
traccc::scalar phi = param.phi();
55-
static constexpr traccc::scalar TWOPI =
56-
2.f * traccc::constant<traccc::scalar>::pi;
57-
phi = math::fmod(phi, TWOPI);
58-
if (phi > traccc::constant<traccc::scalar>::pi) {
59-
phi -= TWOPI;
60-
} else if (phi < -traccc::constant<traccc::scalar>::pi) {
61-
phi += TWOPI;
62-
}
6359
param.set_phi(phi);
60+
param.set_theta(theta);
6461
}
6562

6663
/// Covariance inflation used for track fitting

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

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ combinatorial_kalman_filter(
143143

144144
for (unsigned int step = 0u; step < config.max_track_candidates_per_track;
145145
step++) {
146-
146+
147147
TRACCC_VERBOSE("Starting step "
148148
<< step + 1 << " / "
149149
<< config.max_track_candidates_per_track);
@@ -242,7 +242,6 @@ combinatorial_kalman_filter(
242242

243243
// Iterate over the measurements
244244
for (unsigned int meas_id = lo; meas_id < up; meas_id++) {
245-
246245
// The measurement on surface to handle.
247246
const measurement& meas = measurements.at(meas_id);
248247

@@ -502,17 +501,36 @@ combinatorial_kalman_filter(
502501

503502
// If a surface found, add the parameter for the next
504503
// step
505-
if (s5.success) {
504+
bool valid_track{s5.success};
505+
if (valid_track) {
506506
assert(propagation._navigation.is_on_sensitive());
507507
assert(!propagation._stepping.bound_params().is_invalid());
508508

509-
out_params.push_back(propagation._stepping.bound_params());
510-
param_to_link[step].push_back(link_id);
509+
const auto& out_param = propagation._stepping.bound_params();
510+
511+
const scalar theta = out_param.theta();
512+
if (theta <= 0.f ||
513+
theta >= 2.f * constant<traccc::scalar>::pi) {
514+
valid_track = false;
515+
}
516+
517+
if (!std::isfinite(out_param.phi())) {
518+
valid_track = false;
519+
}
520+
521+
if (math::fabs(out_param.qop()) == 0.f) {
522+
valid_track = false;
523+
}
524+
525+
if (valid_track) {
526+
out_params.push_back(out_param);
527+
param_to_link[step].push_back(link_id);
528+
}
511529
}
512530
// Unless the track found a surface, it is considered a
513531
// tip
514-
else if (!s5.success &&
515-
(step >= (config.min_track_candidates_per_track - 1u))) {
532+
if (!valid_track &&
533+
(step >= (config.min_track_candidates_per_track - 1u))) {
516534
tips.push_back({step, link_id});
517535
}
518536

core/include/traccc/fitting/fitting_config.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ struct fitting_config {
3434
std::size_t barcode_sequence_size_factor = 5;
3535
std::size_t min_barcode_sequence_capacity = 100;
3636
traccc::scalar backward_filter_mask_tolerance =
37-
5.f * traccc::unit<scalar>::mm;
37+
10.f * traccc::unit<scalar>::m;
3838
};
3939

4040
} // namespace traccc

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

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,30 @@ struct gain_matrix_updater {
123123
predicted_vec + K * (meas_local - H * predicted_vec);
124124
const matrix_type<6, 6> filtered_cov = (I66 - K * H) * predicted_cov;
125125

126+
// Check the covariance for consistency
127+
if (getter::element(filtered_cov, 0, 0) <= 0.f ||
128+
getter::element(filtered_cov, 1, 1) <= 0.f ||
129+
getter::element(filtered_cov, 2, 2) <= 0.f ||
130+
getter::element(filtered_cov, 3, 3) <= 0.f ||
131+
getter::element(filtered_cov, 4, 4) <= 0.f ||
132+
getter::element(filtered_cov, 5, 5) <= 0.f) {
133+
return kalman_fitter_status::ERROR_UPDATER_INVALID_COVARIANCE;
134+
}
135+
136+
// Return false if track is parallel to z-axis or phi is not finite
137+
if (!std::isfinite(getter::element(filtered_vec, e_bound_theta, 0))) {
138+
return kalman_fitter_status::ERROR_INVERSION;
139+
}
140+
141+
if (!std::isfinite(getter::element(filtered_vec, e_bound_phi, 0))) {
142+
return kalman_fitter_status::ERROR_INVERSION;
143+
}
144+
145+
if (math::fabs(getter::element(filtered_vec, e_bound_qoverp, 0)) ==
146+
0.f) {
147+
return kalman_fitter_status::ERROR_QOP_ZERO;
148+
}
149+
126150
// Residual between measurement and (projected) filtered vector
127151
const matrix_type<D, 1> residual = meas_local - H * filtered_vec;
128152

@@ -133,36 +157,28 @@ struct gain_matrix_updater {
133157
residual, matrix::inverse(R)) *
134158
residual;
135159

136-
// Return false if track is parallel to z-axis or phi is not finite
137-
const scalar theta = bound_params.theta();
138-
139-
if (theta <= 0.f || theta >= constant<traccc::scalar>::pi) {
140-
return kalman_fitter_status::ERROR_THETA_ZERO;
141-
}
142-
143-
if (!std::isfinite(bound_params.phi())) {
144-
return kalman_fitter_status::ERROR_INVERSION;
145-
}
160+
const scalar chi2_val{getter::element(chi2, 0, 0)};
146161

147-
if (std::abs(bound_params.qop()) == 0.f) {
148-
return kalman_fitter_status::ERROR_QOP_ZERO;
149-
}
150-
151-
if (getter::element(chi2, 0, 0) < 0.f) {
162+
if (chi2_val < 0.f) {
152163
return kalman_fitter_status::ERROR_UPDATER_CHI2_NEGATIVE;
153164
}
154165

155-
if (!std::isfinite(getter::element(chi2, 0, 0))) {
166+
if (!std::isfinite(chi2_val)) {
156167
return kalman_fitter_status::ERROR_UPDATER_CHI2_NOT_FINITE;
157168
}
158169

159-
// Set the track state parameters
170+
// Set the chi2 for this track and measurement
160171
trk_state.filtered_params().set_vector(filtered_vec);
161172
trk_state.filtered_params().set_covariance(filtered_cov);
162-
trk_state.filtered_chi2() = getter::element(chi2, 0, 0);
173+
trk_state.filtered_chi2() = chi2_val;
163174

164-
// Wrap the phi in the range of [-pi, pi]
165-
wrap_phi(trk_state.filtered_params());
175+
// Wrap the phi and theta angles in their valid ranges
176+
normalize_angles(trk_state.filtered_params());
177+
178+
const scalar theta = trk_state.filtered_params().theta();
179+
if (theta <= 0.f || theta >= 2.f * constant<traccc::scalar>::pi) {
180+
return kalman_fitter_status::ERROR_THETA_POLE;
181+
}
166182

167183
assert(!trk_state.filtered_params().is_invalid());
168184

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ struct kalman_actor : detray::actor {
173173
kalman_actor_direction::FORWARD_ONLY ||
174174
direction_e ==
175175
kalman_actor_direction::BIDIRECTIONAL) {
176+
// Wrap the phi and theta angles in their valid ranges
177+
normalize_angles(propagation._stepping.bound_params());
178+
176179
// Forward filter
177180
res = gain_matrix_updater<algebra_t>{}(
178181
trk_state, actor_state.m_measurements,

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

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class kalman_fitter {
5555

5656
// Actor types
5757
using aborter = detray::pathlimit_aborter<scalar_type>;
58+
using momentum_aborter = detray::momentum_aborter<scalar_type>;
5859
using transporter = detray::parameter_transporter<algebra_type>;
5960
using interactor = detray::pointwise_material_interactor<algebra_type>;
6061
using forward_fit_actor =
@@ -71,11 +72,13 @@ class kalman_fitter {
7172

7273
using forward_actor_chain_type =
7374
detray::actor_chain<aborter, transporter, interactor, forward_fit_actor,
74-
resetter, barcode_sequencer, kalman_step_aborter>;
75+
resetter, momentum_aborter, barcode_sequencer,
76+
kalman_step_aborter>;
7577

7678
using backward_actor_chain_type =
7779
detray::actor_chain<aborter, transporter, backward_fit_actor,
78-
interactor, resetter, kalman_step_aborter>;
80+
interactor, resetter, momentum_aborter,
81+
kalman_step_aborter>;
7982

8083
// Navigator type for backward propagator
8184
using direct_navigator_type = detray::direct_navigator<detector_type>;
@@ -125,7 +128,8 @@ class kalman_fitter {
125128
typename forward_actor_chain_type::state_ref_tuple operator()() {
126129
return detray::tie(m_aborter_state, m_interactor_state,
127130
m_fit_actor_state, m_parameter_resetter,
128-
m_sequencer_state, m_step_aborter_state);
131+
m_montum_aborter_state, m_sequencer_state,
132+
m_step_aborter_state);
129133
}
130134

131135
/// @return the actor chain state
@@ -134,7 +138,7 @@ class kalman_fitter {
134138
backward_actor_state() {
135139
return detray::tie(m_aborter_state, m_fit_actor_state,
136140
m_interactor_state, m_parameter_resetter,
137-
m_step_aborter_state);
141+
m_montum_aborter_state, m_step_aborter_state);
138142
}
139143

140144
/// Individual actor states
@@ -144,6 +148,7 @@ class kalman_fitter {
144148
typename barcode_sequencer::state m_sequencer_state;
145149
kalman_step_aborter::state m_step_aborter_state{};
146150
typename resetter::state m_parameter_resetter{};
151+
typename momentum_aborter::state m_montum_aborter_state{};
147152

148153
/// Fitting result per track
149154
typename edm::track_collection<algebra_type>::device::proxy_type
@@ -281,16 +286,20 @@ class kalman_fitter {
281286
}
282287

283288
auto last = fitter_state.m_fit_actor_state();
284-
285289
const scalar theta = last.filtered_params().theta();
286-
if (theta <= 0.f || theta >= constant<traccc::scalar>::pi) {
287-
return kalman_fitter_status::ERROR_THETA_ZERO;
290+
291+
if (!std::isfinite(last.filtered_params().theta())) {
292+
return kalman_fitter_status::ERROR_INVERSION;
288293
}
289294

290295
if (!std::isfinite(last.filtered_params().phi())) {
291296
return kalman_fitter_status::ERROR_INVERSION;
292297
}
293298

299+
if (theta <= 0.f || theta >= 2.f * constant<traccc::scalar>::pi) {
300+
return kalman_fitter_status::ERROR_THETA_POLE;
301+
}
302+
294303
last.smoothed_params().set_parameter_vector(last.filtered_params());
295304
last.smoothed_params().set_covariance(
296305
last.filtered_params().covariance());
@@ -328,6 +337,8 @@ class kalman_fitter {
328337

329338
propagation._navigation.set_direction(
330339
detray::navigation::direction::e_backward);
340+
propagation._navigation.safe_step_size =
341+
0.1f * traccc::unit<scalar>::mm;
331342

332343
// Synchronize the current barcode with the input track parameter
333344
while (propagation._navigation.get_target_barcode() !=

0 commit comments

Comments
 (0)