Skip to content

Commit 869f22b

Browse files
committed
Refined hole counting in KF
1 parent 891c9bb commit 869f22b

File tree

1 file changed

+125
-26
lines changed

1 file changed

+125
-26
lines changed

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

Lines changed: 125 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,16 @@
1717
#include "traccc/utils/particle.hpp"
1818

1919
// detray include(s).
20+
#include <detray/navigation/direct_navigator.hpp>
21+
#include <detray/navigation/navigator.hpp>
2022
#include <detray/propagator/base_actor.hpp>
2123

2224
// vecmem include(s)
2325
#include <vecmem/containers/device_vector.hpp>
2426

27+
// System include(s)
28+
#include <cstdlib>
29+
2530
namespace traccc {
2631

2732
enum class kalman_actor_direction {
@@ -57,6 +62,7 @@ struct kalman_actor_state {
5762
void reset() {
5863
m_it = m_track_states.begin();
5964
m_it_rev = m_track_states.rbegin();
65+
n_holes = 0u;
6066
}
6167

6268
/// Advance the iterator
@@ -71,12 +77,107 @@ struct kalman_actor_state {
7177

7278
/// @return true if the iterator reaches the end of vector
7379
TRACCC_HOST_DEVICE
74-
bool is_complete() {
75-
if (!backward_mode && m_it == m_track_states.end()) {
76-
return true;
77-
} else if (backward_mode && m_it_rev == m_track_states.rend()) {
78-
return true;
80+
bool is_complete() const {
81+
return ((!backward_mode && m_it == m_track_states.end()) ||
82+
(backward_mode && m_it_rev == m_track_states.rend()));
83+
}
84+
85+
/// @returns the current number of holes in this state
86+
TRACCC_HOST_DEVICE
87+
unsigned int count_missed() const {
88+
unsigned int n_missed{0u};
89+
90+
if (backward_mode) {
91+
for (const auto& trk_state : m_track_states) {
92+
if (trk_state.smoothed().is_invalid()) {
93+
++n_missed;
94+
}
95+
}
96+
} else {
97+
for (const auto& trk_state : m_track_states) {
98+
if (trk_state.filtered().is_invalid()) {
99+
++n_missed;
100+
}
101+
}
79102
}
103+
104+
return n_missed;
105+
}
106+
107+
template <typename nav_state_t>
108+
void evaluate_hole(const nav_state_t& navigation) {
109+
if (navigation.is_good_candidate()) {
110+
++n_holes;
111+
}
112+
}
113+
114+
/// @return true if the iterator reaches the end of vector
115+
/// @TODO: Remove once direct navigator is used in forward pass
116+
template <typename propagation_state_t>
117+
TRACCC_HOST_DEVICE bool check_matching_surface(
118+
propagation_state_t& propagation) {
119+
120+
auto& navigation = propagation._navigation;
121+
auto& trk_state = (*this)();
122+
123+
// Surface was found, continue with KF algorithm
124+
if (navigation.barcode() == trk_state.surface_link()) {
125+
// Count a hole, if track finding did not find a measurement
126+
if (trk_state.is_hole) {
127+
evaluate_hole(navigation);
128+
}
129+
// If track finding did not find measurement on this surface: skip
130+
return !trk_state.is_hole;
131+
}
132+
133+
// Skipped surfaces: adjust iterator and remove counted hole
134+
// (only relevant if using non-direct navigation, e.g. forward truth
135+
// fitting or different prop. config between CKF asnd KF)
136+
// TODO: Remove again
137+
using detector_t = typename propagation_state_t::detector_type;
138+
using nav_state_t = typename propagation_state_t::navigator_state_type;
139+
if constexpr (!std::same_as<nav_state_t,
140+
typename detray::direct_navigator<
141+
detector_t>::state>) {
142+
int i{1};
143+
if (backward_mode) {
144+
// If we are on the last state and the navigation surface does
145+
// not match, it must be an additional surface
146+
// -> continue navigation until matched
147+
if (m_it_rev + 1 == m_track_states.rend()) {
148+
evaluate_hole(navigation);
149+
return false;
150+
}
151+
// Check if the current navigation surfaces can be found on a
152+
// later track state. That means the current track state was
153+
// skipped by the navigator: Advance the internal iterator
154+
for (auto itr = m_it_rev + 1; itr != m_track_states.rend();
155+
++itr) {
156+
if (itr->surface_link() == navigation.barcode()) {
157+
m_it_rev += i;
158+
return true;
159+
}
160+
++i;
161+
}
162+
} else {
163+
if (m_it + 1 == m_track_states.end()) {
164+
evaluate_hole(navigation);
165+
return false;
166+
}
167+
for (auto itr = m_it + 1; itr != m_track_states.end(); ++itr) {
168+
if (itr->surface_link() == navigation.barcode()) {
169+
m_it += i;
170+
return true;
171+
}
172+
++i;
173+
}
174+
}
175+
}
176+
177+
// Mismatch was not from missed state: Is a hole
178+
++n_holes;
179+
180+
// After additional surface, keep navigating until match is found
80181
return false;
81182
}
82183

@@ -89,8 +190,7 @@ struct kalman_actor_state {
89190
// iterator for backward filtering
90191
typename track_state_coll::reverse_iterator m_it_rev;
91192

92-
// The number of holes (The number of sensitive surfaces which do not
93-
// have a measurement for the track pattern)
193+
// Count the number of encountered surfaces without measurement
94194
unsigned int n_holes{0u};
95195

96196
// Run back filtering for smoothing, if true
@@ -118,7 +218,6 @@ struct kalman_actor : detray::actor {
118218
auto& stepping = propagation._stepping;
119219
auto& navigation = propagation._navigation;
120220

121-
// If the iterator reaches the end, terminate the propagation
122221
if (actor_state.is_complete()) {
123222
propagation._heartbeat &= navigation.exit();
124223
return;
@@ -127,21 +226,19 @@ struct kalman_actor : detray::actor {
127226
// triggered only for sensitive surfaces
128227
if (navigation.is_on_sensitive()) {
129228

130-
auto& trk_state = actor_state();
229+
// Did the navigation switch direction?
230+
actor_state.backward_mode =
231+
navigation.direction() ==
232+
detray::navigation::direction::e_backward;
131233

132-
// Increase the hole counts if the propagator fails to find the next
133-
// measurement
134-
if (navigation.barcode() != trk_state.surface_link()) {
135-
if (!actor_state.backward_mode) {
136-
actor_state.n_holes++;
137-
}
234+
// Increase the hole count if the propagator stops at an additional
235+
// surface and wait for the next sensitive surface to match
236+
if (!actor_state.check_matching_surface(propagation)) {
138237
return;
139238
}
140239

141-
// This track state is not a hole
142-
if (!actor_state.backward_mode) {
143-
trk_state.is_hole = false;
144-
}
240+
auto& trk_state = actor_state();
241+
auto& bound_param = stepping.bound_params();
145242

146243
// Run Kalman Gain Updater
147244
const auto sf = navigation.get_surface();
@@ -157,11 +254,10 @@ struct kalman_actor : detray::actor {
157254
kalman_actor_direction::BIDIRECTIONAL) {
158255
// Forward filter
159256
res = gain_matrix_updater<algebra_t>{}(
160-
trk_state, propagation._stepping.bound_params(),
161-
is_line);
257+
trk_state, bound_param, is_line);
162258

163259
// Update the propagation flow
164-
stepping.bound_params() = trk_state.filtered();
260+
bound_param = trk_state.filtered();
165261
} else {
166262
assert(false);
167263
}
@@ -170,10 +266,14 @@ struct kalman_actor : detray::actor {
170266
kalman_actor_direction::BACKWARD_ONLY ||
171267
direction_e ==
172268
kalman_actor_direction::BIDIRECTIONAL) {
269+
// Forward filter did not find this state: skip
270+
if (trk_state.filtered().is_invalid()) {
271+
actor_state.next();
272+
return;
273+
}
173274
// Backward filter for smoothing
174275
res = two_filters_smoother<algebra_t>{}(
175-
trk_state, propagation._stepping.bound_params(),
176-
is_line);
276+
trk_state, bound_param, is_line);
177277
} else {
178278
assert(false);
179279
}
@@ -190,8 +290,7 @@ struct kalman_actor : detray::actor {
190290
// is changed (This rarely happens when qop is set with a poor seed
191291
// resolution)
192292
propagation.set_particle(detail::correct_particle_hypothesis(
193-
stepping.particle_hypothesis(),
194-
propagation._stepping.bound_params()));
293+
stepping.particle_hypothesis(), bound_param));
195294

196295
// Update iterator
197296
actor_state.next();

0 commit comments

Comments
 (0)