Skip to content

Commit 9166d9f

Browse files
committed
Fix overlaps handling in the CKF
1 parent b97c82c commit 9166d9f

File tree

13 files changed

+132
-87
lines changed

13 files changed

+132
-87
lines changed

core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ traccc_add_library( traccc_core core TYPE SHARED
8080
# Finding algorithmic code
8181
"include/traccc/finding/candidate_link.hpp"
8282
"include/traccc/finding/finding_config.hpp"
83+
"include/traccc/finding/propagation_data.hpp"
8384
"include/traccc/finding/actors/ckf_aborter.hpp"
8485
"include/traccc/finding/actors/interaction_register.hpp"
8586
"include/traccc/finding/details/combinatorial_kalman_filter_types.hpp"

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

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
// Project include(s)
1111
#include "traccc/definitions/primitives.hpp"
1212
#include "traccc/definitions/qualifiers.hpp"
13+
#include "traccc/utils/logging.hpp"
1314

1415
// detray include(s)
16+
#include <detray/definitions/indexing.hpp>
1517
#include <detray/propagator/base_actor.hpp>
1618

1719
// System include(s)
@@ -24,36 +26,45 @@ struct ckf_aborter : detray::actor {
2426
struct state {
2527
// minimal step length to prevent from staying on the same surface
2628
scalar min_step_length = 0.5f;
29+
2730
/// Maximum step counts that track can make to reach the next surface
28-
unsigned int max_count = 100;
31+
unsigned int max_count = 100u;
32+
unsigned int count = 0u;
2933

30-
bool success = false;
31-
unsigned int count = 0;
34+
/// Previous sensitive surface index
35+
detray::dindex prev_surface_index{detray::dindex_invalid};
36+
/// Current sensitive surface index
37+
detray::dindex surface_index{detray::dindex_invalid};
3238

33-
scalar path_from_surface{0.f};
39+
/// Whether a surface was found
40+
bool success = false;
3441
};
3542

3643
template <typename propagator_state_t>
3744
TRACCC_HOST_DEVICE void operator()(state &abrt_state,
3845
propagator_state_t &prop_state) const {
3946

4047
auto &navigation = prop_state._navigation;
41-
const auto &stepping = prop_state._stepping;
4248

4349
abrt_state.count++;
44-
abrt_state.path_from_surface += stepping.step_size();
4550

46-
// Stop at the next sensitive surface
47-
if (navigation.is_on_sensitive() &&
48-
abrt_state.path_from_surface > abrt_state.min_step_length) {
49-
prop_state._heartbeat &= navigation.pause();
50-
abrt_state.success = navigation.is_alive();
51+
// Is this a valid sensitive surface to run the CKF on?
52+
const detray::dindex sf_idx{navigation.barcode().index()};
53+
if (!navigation.is_on_sensitive() ||
54+
(abrt_state.surface_index == sf_idx) ||
55+
(abrt_state.prev_surface_index == sf_idx)) {
56+
return;
5157
}
5258

53-
// Reset path from surface
54-
if (navigation.is_on_sensitive()) {
55-
abrt_state.path_from_surface = 0.f;
56-
}
59+
// Update the visited sensitive surfaces and pause the propagation
60+
abrt_state.prev_surface_index = abrt_state.surface_index;
61+
abrt_state.surface_index = sf_idx;
62+
63+
prop_state._heartbeat &= navigation.pause();
64+
abrt_state.success = true;
65+
66+
assert(abrt_state.surface_index <
67+
navigation.detector().surfaces().size());
5768

5869
if (abrt_state.count > abrt_state.max_count) {
5970
prop_state._heartbeat &= navigation.abort(

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

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
#pragma once
88

99
// Project include(s).
10-
#include <detray/utils/log.hpp>
11-
1210
#include "traccc/edm/measurement.hpp"
1311
#include "traccc/edm/track_candidate_collection.hpp"
1412
#include "traccc/edm/track_state_helpers.hpp"
@@ -17,6 +15,7 @@
1715
#include "traccc/finding/candidate_link.hpp"
1816
#include "traccc/finding/details/combinatorial_kalman_filter_types.hpp"
1917
#include "traccc/finding/finding_config.hpp"
18+
#include "traccc/finding/propagation_data.hpp"
2019
#include "traccc/fitting/kalman_filter/gain_matrix_updater.hpp"
2120
#include "traccc/fitting/kalman_filter/is_line_visitor.hpp"
2221
#include "traccc/fitting/status_codes.hpp"
@@ -81,6 +80,10 @@ combinatorial_kalman_filter(
8180
// Create a logger.
8281
auto logger = [&log]() -> const Logger& { return log; };
8382

83+
// Minimum chi2 cut to use for measurements on surfaces that are edge hits
84+
// (don't accumulate pileup measurements)
85+
const float chi2_min{math::max(10.f, 0.1f * config.chi2_max)};
86+
8487
/*****************************************************************
8588
* Measurement Operations
8689
*****************************************************************/
@@ -144,20 +147,18 @@ combinatorial_kalman_filter(
144147

145148
std::vector<bound_track_parameters<algebra_type>> out_params;
146149

147-
std::vector<std::uint8_t> in_is_edge(seeds.size(), false);
148-
std::vector<std::uint8_t> out_is_edge;
150+
std::vector<propagation_data> in_prop_data(seeds.size());
151+
std::vector<propagation_data> out_prop_data;
149152

150153
for (unsigned int step = 0u; step < config.max_track_candidates_per_track;
151154
step++) {
152155

153-
DETRAY_DEBUG_HOST("PRPGAGATION STEP: " << step);
154156
TRACCC_VERBOSE("Starting step "
155157
<< step + 1 << " / "
156158
<< config.max_track_candidates_per_track);
157159

158160
// Iterate over input parameters
159161
const std::size_t n_in_params = in_params.size();
160-
DETRAY_DEBUG_HOST("# PARAMS: " << n_in_params);
161162

162163
// Terminate if there is no parameter to proceed
163164
if (n_in_params == 0) {
@@ -166,23 +167,22 @@ combinatorial_kalman_filter(
166167

167168
// Rough estimation on out parameters size
168169
out_params.reserve(n_in_params);
169-
out_is_edge.reserve(n_in_params);
170+
out_prop_data.reserve(n_in_params);
170171

171172
// Previous step ID
172173
std::fill(n_trks_per_seed.begin(), n_trks_per_seed.end(), 0u);
173174

174175
// Parameters updated by Kalman fitter
175176
std::vector<bound_track_parameters<algebra_type>> updated_params;
177+
std::vector<propagation_data> updated_prop_data;
176178

177179
for (unsigned int in_param_id = 0; in_param_id < n_in_params;
178180
in_param_id++) {
179181

180182
bound_track_parameters<algebra_type>& in_param =
181183
in_params[in_param_id];
182184

183-
DETRAY_DEBUG_HOST("PARAMS: " << in_param);
184-
185-
const bool is_edge{in_is_edge[in_param_id] > 0u};
185+
const propagation_data& prop_data = in_prop_data[in_param_id];
186186

187187
assert(!in_param.is_invalid());
188188

@@ -259,9 +259,7 @@ combinatorial_kalman_filter(
259259
best_links;
260260

261261
// Iterate over the measurements
262-
DETRAY_DEBUG_HOST("# MEAS: " << (up - lo));
263262
for (unsigned int meas_id = lo; meas_id < up; meas_id++) {
264-
DETRAY_DEBUG_HOST("TESTING MEAS: " << meas_id);
265263

266264
// The measurement on surface to handle.
267265
const measurement& meas = measurements.at(meas_id);
@@ -279,13 +277,10 @@ combinatorial_kalman_filter(
279277

280278
const traccc::scalar chi2 = trk_state.filtered_chi2();
281279

282-
DETRAY_DEBUG_HOST("KF STATUS: " << fitter_debug_msg{res}());
283-
284280
// The chi2 from Kalman update should be less than chi2_max
285281
if (res == kalman_fitter_status::SUCCESS &&
286-
chi2 < config.chi2_max) {
287-
288-
DETRAY_DEBUG_HOST("FOUND MEAS: " << meas_id);
282+
((!prop_data.is_edge && chi2 <= config.chi2_max) ||
283+
(chi2 <= chi2_min))) {
289284

290285
best_links.push_back(
291286
{{.step = step,
@@ -322,6 +317,7 @@ combinatorial_kalman_filter(
322317

323318
// Add the updated parameter to the updated parameters
324319
updated_params.push_back(filtered_params);
320+
updated_prop_data.push_back(prop_data);
325321
TRACCC_VERBOSE("updated_params["
326322
<< updated_params.size() - 1
327323
<< "] = " << updated_params.back());
@@ -340,15 +336,15 @@ combinatorial_kalman_filter(
340336
.meas_idx = std::numeric_limits<unsigned int>::max(),
341337
.seed_idx = orig_param_id,
342338
.n_cand = n_cand,
343-
.n_skipped = is_edge ? skip_counter : skip_counter + 1,
339+
.n_skipped =
340+
prop_data.is_edge ? skip_counter : skip_counter + 1,
344341
.n_consecutive_skipped = consecutive_skipped + 1,
345342
.chi2 = std::numeric_limits<traccc::scalar>::max(),
346343
.chi2_sum = prev_chi2_sum,
347344
.ndf_sum = prev_ndf_sum});
348345

349-
DETRAY_DEBUG_HOST("HOLE: " << std::boolalpha << !is_edge);
350-
351346
updated_params.push_back(in_param);
347+
updated_prop_data.push_back(prop_data);
352348
TRACCC_VERBOSE("updated_params["
353349
<< updated_params.size() - 1
354350
<< "] = " << updated_params.back());
@@ -468,7 +464,6 @@ combinatorial_kalman_filter(
468464
}
469465

470466
if (this_is_dominated) {
471-
DETRAY_DEBUG_HOST("Track is DEAD!");
472467
param_liveness.at(tracks.at(i)) = 0u;
473468
break;
474469
}
@@ -497,12 +492,14 @@ combinatorial_kalman_filter(
497492
if (links.at(step).at(link_id).n_skipped >
498493
config.max_num_skipping_per_cand) {
499494

500-
DETRAY_DEBUG_HOST("MAKE TIP: MAX NO. HOLES");
501495
tips.push_back({step, link_id});
502496
continue;
503497
}
504498

499+
assert(updated_params.size() == updated_prop_data.size());
505500
const auto& param = updated_params[link_id];
501+
const propagation_data& prop_data = updated_prop_data[link_id];
502+
506503
// Create propagator state
507504
typename traccc::details::ckf_propagator_t<
508505
detector_t, bfield_t>::state propagation(param, field, det);
@@ -524,50 +521,46 @@ combinatorial_kalman_filter(
524521
// Update the actor config
525522
s4.min_pT(static_cast<scalar_type>(config.min_pT));
526523
s4.min_p(static_cast<scalar_type>(config.min_p));
524+
s5.prev_surface_index = prop_data.prev_surface;
525+
s5.surface_index = param.surface_link().index();
527526
s5.min_step_length = config.min_step_length_for_next_surface;
528527
s5.max_count = config.max_step_counts_for_next_surface;
529528

530-
DETRAY_DEBUG_HOST("PROPAGATING... ");
531529
// Propagate to the next surface
532530
propagator.propagate(propagation,
533531
detray::tie(s0, s1, s2, s3, s4, s5));
534532

535-
DETRAY_DEBUG_HOST(
536-
"FINISHED PROPAGATING. PATH: " << s5.path_from_surface);
537-
538533
// If a surface found, add the parameter for the next
539534
// step
540535
if (s5.success) {
541536
assert(propagation._navigation.is_on_sensitive());
542537
assert(!propagation._stepping.bound_params().is_invalid());
543538

544539
out_params.push_back(propagation._stepping.bound_params());
545-
out_is_edge.push_back(
540+
out_prop_data.emplace_back(
541+
s5.prev_surface_index,
546542
propagation._navigation.is_edge_candidate());
547543
param_to_link[step].push_back(link_id);
548544
}
549545
// Unless the track found a surface, it is considered a
550546
// tip
551547
else if (!s5.success &&
552548
(step >= (config.min_track_candidates_per_track - 1u))) {
553-
554-
DETRAY_DEBUG_HOST("MAKE TIP: NO SENSITIVE");
555549
tips.push_back({step, link_id});
556550
}
557551

558552
// If no more CKF step is expected, current candidate is
559553
// kept as a tip
560554
if (s5.success &&
561555
(step == (config.max_track_candidates_per_track - 1u))) {
562-
DETRAY_DEBUG_HOST("MAKE TIP: MAX CANDIDATES");
563556
tips.push_back({step, link_id});
564557
}
565558
}
566559

567560
in_params = std::move(out_params);
568-
in_is_edge = std::move(out_is_edge);
561+
in_prop_data = std::move(out_prop_data);
569562
out_params.clear();
570-
out_is_edge.clear();
563+
out_prop_data.clear();
571564
}
572565

573566
/**********************
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
/** TRACCC library, part of the ACTS project (R&D line)
3+
*
4+
* (c) 2025 CERN for the benefit of the ACTS project
5+
*
6+
* Mozilla Public License Version 2.0
7+
*/
8+
9+
#pragma once
10+
11+
// Detray include(s).
12+
#include <detray/definitions/indexing.hpp>
13+
14+
namespace traccc {
15+
16+
/// Data from the propagation loop that has to be kept between CKF steps
17+
struct propagation_data {
18+
/// The surface that was visited before the current one (overlaps
19+
/// resolution)
20+
detray::dindex prev_surface{detray::dindex_invalid};
21+
22+
/// Is the current surface hit in the extended tolerance band?
23+
bool is_edge{false};
24+
};
25+
26+
} // namespace traccc

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,9 @@ struct kalman_actor : detray::actor {
212212
actor_state.next();
213213

214214
// Flag renavigation of the current candidate
215-
// if (math::fabs(navigation()) > 1.f * unit<float>::um) {
216-
navigation.set_high_trust();
217-
//}
215+
if (math::fabs(navigation()) > 1.f * unit<float>::um) {
216+
navigation.set_high_trust();
217+
}
218218
}
219219
}
220220
};

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ struct two_filters_smoother {
185185

186186
// Calculate backward chi2
187187
const matrix_type<D, D> R = (I_m - H * K) * V;
188-
assert(matrix::determinant(R) != 0.f);
188+
// assert(matrix::determinant(R) != 0.f);
189189
assert(std::isfinite(matrix::determinant(R)));
190190
const matrix_type<1, 1> chi2 =
191191
algebra::matrix::transposed_product<true, false>(

device/alpaka/src/finding/combinatorial_kalman_filter.hpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,9 @@ combinatorial_kalman_filter(
237237
copy.memset(param_liveness_buffer, 1)->wait();
238238

239239
// On the first measurement, no parameter can be a hole
240-
vecmem::data::vector_buffer<std::uint8_t> is_edges_buffer(n_seeds, mr.main);
241-
copy.setup(is_edges_buffer)->wait();
242-
copy.memset(is_edges_buffer, 0)->wait();
240+
vecmem::data::vector_buffer<propagation_data> prop_data_buffer(n_seeds,
241+
mr.main);
242+
copy.setup(prop_data_buffer)->wait();
243243

244244
// Number of tracks per seed
245245
vecmem::data::vector_buffer<unsigned int> n_tracks_per_seed_buffer(n_seeds,
@@ -306,9 +306,9 @@ combinatorial_kalman_filter(
306306
copy.setup(updated_liveness_buffer)->wait();
307307

308308
// Updated edges buffer after branching
309-
vecmem::data::vector_buffer<std::uint8_t> is_edges_updated_buffer(
309+
vecmem::data::vector_buffer<propagation_data> prop_data_updated_buffer(
310310
n_max_candidates, mr.main);
311-
copy.setup(is_edges_updated_buffer)->wait();
311+
copy.setup(prop_data_updated_buffer)->wait();
312312

313313
// Reset the number of tracks per seed
314314
copy.memset(n_tracks_per_seed_buffer, 0)->wait();
@@ -353,7 +353,7 @@ combinatorial_kalman_filter(
353353
.in_params_view = in_params_buffer,
354354
.in_params_liveness_view = param_liveness_buffer,
355355
.n_in_params = n_in_params,
356-
.is_edges_view = is_edges_buffer,
356+
.prop_data_view = prop_data_buffer,
357357
.measurement_ranges_view = meas_ranges_buffer,
358358
.links_view = links_buffer,
359359
.prev_links_idx =
@@ -517,7 +517,7 @@ combinatorial_kalman_filter(
517517
.params_view = in_params_buffer,
518518
.params_liveness_view = param_liveness_buffer,
519519
.param_ids_view = param_ids_buffer,
520-
.is_edges_view = is_edges_updated_buffer,
520+
.prop_data_view = prop_data_updated_buffer,
521521
.links_view = links_buffer,
522522
.prev_links_idx = step_to_link_idx_map[step],
523523
.step = step,
@@ -549,7 +549,7 @@ combinatorial_kalman_filter(
549549
config, device_payload.ptr());
550550
::alpaka::wait(queue);
551551

552-
std::swap(is_edges_buffer, is_edges_updated_buffer);
552+
std::swap(prop_data_buffer, prop_data_updated_buffer);
553553
}
554554
}
555555

0 commit comments

Comments
 (0)