Skip to content

Commit

Permalink
refactor!: Refactor CKF branch stopper to allow stop and keep tracks (#…
Browse files Browse the repository at this point in the history
…3102)

Changes the CKF branch stopper to allow keeping the tracks after the branch is stopped. This is useful if a track already collected enough measurements but then starts to accumulate holes.

This change should allow us to stop branches more aggressively because we don't have to be worried anymore to throw out valid track candidates.

closes
- #2967

blocked by
- #3164
- #3163
  • Loading branch information
andiwand authored May 3, 2024
1 parent 8130574 commit bed53b2
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 38 deletions.
Binary file modified CI/physmon/reference/performance_amvf_gridseeder_ttbar_hist.root
Binary file not shown.
Binary file modified CI/physmon/reference/performance_amvf_orthogonal_hist.root
Binary file not shown.
Binary file modified CI/physmon/reference/performance_amvf_seeded_hist.root
Binary file not shown.
Binary file modified CI/physmon/reference/performance_amvf_ttbar_hist.root
Binary file not shown.
Binary file modified CI/physmon/reference/tracksummary_ckf_ttbar_hist.root
Binary file not shown.
40 changes: 27 additions & 13 deletions Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,28 @@ struct CombinatorialKalmanFilterTipState {
std::size_t nHoles = 0;
};

enum class CombinatorialKalmanFilterBranchStopperResult {
Continue,
StopAndDrop,
StopAndKeep,
};

/// Extension struct which holds the delegates to customize the CKF behavior
template <typename traj_t>
struct CombinatorialKalmanFilterExtensions {
using candidate_container_t =
typename std::vector<typename traj_t::TrackStateProxy>;
using BranchStopperResult = CombinatorialKalmanFilterBranchStopperResult;

using Calibrator = typename KalmanFitterExtensions<traj_t>::Calibrator;
using Updater = typename KalmanFitterExtensions<traj_t>::Updater;
using MeasurementSelector =
Delegate<Result<std::pair<typename candidate_container_t::iterator,
typename candidate_container_t::iterator>>(
candidate_container_t& trackStates, bool&, const Logger&)>;
using BranchStopper = Delegate<bool(const CombinatorialKalmanFilterTipState&,
typename traj_t::TrackStateProxy&)>;
using BranchStopper =
Delegate<BranchStopperResult(const CombinatorialKalmanFilterTipState&,
typename traj_t::TrackStateProxy&)>;

/// The Calibrator is a dedicated calibration algorithm that allows to
/// calibrate measurements using track information, this could be e.g. sagging
Expand Down Expand Up @@ -112,10 +120,10 @@ struct CombinatorialKalmanFilterExtensions {

/// Default branch stopper which will never stop
/// @return false
static bool voidBranchStopper(
static BranchStopperResult voidBranchStopper(
const CombinatorialKalmanFilterTipState& /*tipState*/,
typename traj_t::TrackStateProxy& /*trackState*/) {
return false;
return BranchStopperResult::Continue;
}
};

Expand Down Expand Up @@ -660,14 +668,23 @@ class CombinatorialKalmanFilter {
auto nonSourcelinkState =
result.fittedStates->getTrackState(currentTip);

using BranchStopperResult =
CombinatorialKalmanFilterBranchStopperResult;
BranchStopperResult branchStopperResult =
m_extensions.branchStopper(tipState, nonSourcelinkState);

// Check the branch
if (!m_extensions.branchStopper(tipState, nonSourcelinkState)) {
if (branchStopperResult == BranchStopperResult::Continue) {
// Remembered the active tip and its state
} else {
// No branch on this surface
nBranchesOnSurface = 0;

// Remove the last tip from active tips
if (branchStopperResult == BranchStopperResult::StopAndKeep) {
storeLastActiveTip(result);
}

// Remove the tip from list of active tips
result.activeTips.erase(result.activeTips.end() - 1);
}

Expand Down Expand Up @@ -872,13 +889,10 @@ class CombinatorialKalmanFilter {
tipState.nMeasurements++;
}

// Check if need to stop this branch
if (!m_extensions.branchStopper(tipState, trackState)) {
// Put tipstate back into active tips to continue with it
result.activeTips.emplace_back(currentTip, tipState);
// Record the number of branches on surface
nBranchesOnSurface++;
}
// Put tipstate back into active tips to continue with it
result.activeTips.emplace_back(currentTip, tipState);
// Record the number of branches on surface
nBranchesOnSurface++;
}
return Result<void>::success();
}
Expand Down
38 changes: 13 additions & 25 deletions Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,16 +179,18 @@ class BranchStopper {
using Config =
std::optional<std::variant<Acts::TrackSelector::Config,
Acts::TrackSelector::EtaBinnedConfig>>;
using BranchStopperResult =
Acts::CombinatorialKalmanFilterBranchStopperResult;

mutable std::atomic<std::size_t> m_nStoppedBranches{0};

explicit BranchStopper(const Config& config) : m_config(config) {}

bool operator()(
BranchStopperResult operator()(
const Acts::CombinatorialKalmanFilterTipState& tipState,
Acts::VectorMultiTrajectory::TrackStateProxy& trackState) const {
if (!m_config.has_value()) {
return false;
return BranchStopperResult::Continue;
}

const Acts::TrackSelector::Config* singleConfig = std::visit(
Expand All @@ -207,35 +209,21 @@ class BranchStopper {

if (singleConfig == nullptr) {
++m_nStoppedBranches;
return true;
return BranchStopperResult::StopAndDrop;
}

// Continue if the number of holes is below the maximum
if (tipState.nHoles <= singleConfig->maxHoles) {
return false;
}

// Continue if the number of outliers is below the maximum
if (tipState.nOutliers <= singleConfig->maxOutliers) {
return false;
}
bool enoughMeasurements =
tipState.nMeasurements >= singleConfig->minMeasurements;
bool tooManyHoles = tipState.nHoles > singleConfig->maxHoles;
bool tooManyOutliers = tipState.nOutliers > singleConfig->maxOutliers;

// If there are not enough measurements but more holes than allowed we stop
if (tipState.nMeasurements < singleConfig->minMeasurements) {
if (tooManyHoles || tooManyOutliers) {
++m_nStoppedBranches;
return true;
return enoughMeasurements ? BranchStopperResult::StopAndKeep
: BranchStopperResult::StopAndDrop;
}

// Getting another measurement guarantees that the holes are in the middle
// of the track
if (trackState.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag)) {
++m_nStoppedBranches;
return true;
}

// We cannot be sure if the holes are just at the end of the track so we
// have to keep going
return false;
return BranchStopperResult::Continue;
}

private:
Expand Down

0 comments on commit bed53b2

Please sign in to comment.