Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor!: Remove smoothing and extrapolation from core CKF #2722

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
62a54f2
remove smoothing and extrapolation from CKF
andiwand Nov 23, 2023
3d78904
fix
andiwand Nov 23, 2023
120dd79
fix
andiwand Nov 24, 2023
5192ec3
todo; typedefs
andiwand Nov 24, 2023
68a65bc
Merge branch 'main' into remove-ckf-smoothing-and-extrapolation
andiwand Nov 24, 2023
4021d6d
improve delegate initialization
andiwand Nov 24, 2023
2f07adc
Merge branch 'remove-ckf-smoothing-and-extrapolation' of github.com:a…
andiwand Nov 24, 2023
22778d9
put source link accessor into extensions
andiwand Nov 24, 2023
a729c1d
Merge branch 'main' into remove-ckf-smoothing-and-extrapolation
andiwand Nov 25, 2023
9721411
Merge branch 'main' into remove-ckf-smoothing-and-extrapolation
andiwand Nov 27, 2023
9f2e7d4
Merge branch 'main' into remove-ckf-smoothing-and-extrapolation
andiwand Dec 12, 2023
790e75e
Merge branch 'main' into remove-ckf-smoothing-and-extrapolation
andiwand Dec 16, 2023
ad3d4ad
Merge branch 'main' into remove-ckf-smoothing-and-extrapolation
andiwand Dec 21, 2023
6ec0298
Merge branch 'main' into remove-ckf-smoothing-and-extrapolation
andiwand Jan 11, 2024
312a5a0
Merge branch 'main' of https://github.com/acts-project/acts into remo…
andiwand Jan 23, 2024
9818689
introduce TrackHelpers
andiwand Jan 25, 2024
7ba2841
rename helper; fix
andiwand Jan 25, 2024
c712b45
Merge branch 'main' of github.com:acts-project/acts into remove-ckf-s…
andiwand Jan 25, 2024
768fb29
formatting
andiwand Jan 25, 2024
9477355
Merge branch 'main' into remove-ckf-smoothing-and-extrapolation
andiwand Feb 6, 2024
ebe7a3c
Merge branch 'main' of github.com:acts-project/acts into remove-ckf-s…
andiwand Feb 13, 2024
9f06c4b
fix merge
andiwand Feb 13, 2024
8e1967d
pr feedback part 1
andiwand Feb 13, 2024
2f57209
fix
andiwand Feb 13, 2024
ad5f096
Merge branch 'main' of github.com:acts-project/acts into remove-ckf-s…
andiwand Feb 14, 2024
008775c
pr feedback part 1
andiwand Feb 14, 2024
8cd2e8a
remove propagator helpers
andiwand Feb 14, 2024
ac9a940
pr feedback part 2
andiwand Feb 14, 2024
dda663d
fix formatting
andiwand Feb 14, 2024
f34e64d
fix silly
andiwand Feb 14, 2024
211c71a
fix smoothing: start from last measurement
andiwand Feb 15, 2024
821e832
use switch case
andiwand Feb 15, 2024
d11a007
only keep the first error
andiwand Feb 15, 2024
40a76ba
fix compilation
andiwand Feb 15, 2024
aee06cc
Merge branch 'main' into remove-ckf-smoothing-and-extrapolation
andiwand Feb 29, 2024
0742d56
Merge branch 'main' into remove-ckf-smoothing-and-extrapolation
andiwand Mar 13, 2024
653c169
Merge branch 'main' into remove-ckf-smoothing-and-extrapolation
andiwand Mar 27, 2024
48c4643
fix doc
andiwand Mar 27, 2024
eb5d298
update refs
andiwand Mar 27, 2024
c1e658a
fix exatrkx
andiwand Mar 27, 2024
8e11c91
Merge branch 'main' into remove-ckf-smoothing-and-extrapolation
kodiakhq[bot] Mar 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified CI/physmon/reference/performance_amvf_gridseeder_seeded_hist.root
Binary file not shown.
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_truth_estimated_hist.root
Binary file not shown.
Binary file modified CI/physmon/reference/performance_amvf_truth_smeared_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/performance_ivf_orthogonal_hist.root
Binary file not shown.
Binary file modified CI/physmon/reference/performance_ivf_seeded_hist.root
Binary file not shown.
Binary file modified CI/physmon/reference/performance_ivf_truth_estimated_hist.root
Binary file not shown.
Binary file modified CI/physmon/reference/performance_ivf_truth_smeared_hist.root
Binary file not shown.
Binary file modified CI/physmon/reference/tracksummary_ckf_orthogonal_hist.root
Binary file not shown.
Binary file modified CI/physmon/reference/tracksummary_ckf_seeded_hist.root
Binary file not shown.
Binary file modified CI/physmon/reference/tracksummary_ckf_truth_estimated_hist.root
Binary file not shown.
Binary file modified CI/physmon/reference/tracksummary_ckf_truth_smeared_hist.root
Binary file not shown.
Binary file modified CI/physmon/reference/tracksummary_ckf_ttbar_hist.root
Binary file not shown.
10 changes: 10 additions & 0 deletions Core/include/Acts/EventData/TrackProxy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,16 @@ class TrackProxy {
covariance(), particleHypothesis());
}

/// Convert a track state into track parameters
/// @note The parameters are created on the fly
/// @return the track parameters
BoundTrackParameters createParametersFromState(
const ConstTrackStateProxy& trackState) const {
return BoundTrackParameters(trackState.referenceSurface().getSharedPtr(),
trackState.parameters(),
trackState.covariance(), particleHypothesis());
}

/// Return a reference to the track container backend, mutable version.
/// @note Only available if the track proxy is not read-only
/// @return reference to the track container backend
Expand Down
436 changes: 68 additions & 368 deletions Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp

Large diffs are not rendered by default.

358 changes: 358 additions & 0 deletions Core/include/Acts/Utilities/TrackHelpers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,358 @@
// This file is part of the Acts project.
//
// Copyright (C) 2024 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/Definitions/Tolerance.hpp"
#include "Acts/EventData/MultiTrajectoryHelpers.hpp"
#include "Acts/EventData/TrackStateType.hpp"
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Propagator/StandardAborters.hpp"
#include "Acts/Surfaces/Surface.hpp"
#include "Acts/TrackFitting/GainMatrixSmoother.hpp"
#include "Acts/Utilities/Logger.hpp"
#include "Acts/Utilities/Result.hpp"

#include <utility>

namespace Acts {

enum class TrackExtrapolationStrategy {
/// Use the first track state to reach target surface
first,
/// Use the last track state to reach target surface
last,
/// Use the first or last track state to reach target surface depending on the
/// distance
firstOrLast,
};

enum class TrackExtrapolationError {
CompatibleTrackStateNotFound = 1,
ReferenceSurfaceUnreachable = 2,
};

std::error_code make_error_code(TrackExtrapolationError e);

template <typename track_proxy_t>
Result<typename track_proxy_t::ConstTrackStateProxy> findFirstMeasurementState(
const track_proxy_t &track) {
using TrackStateProxy = typename track_proxy_t::ConstTrackStateProxy;

// TODO specialize if track is forward linked

auto result = Result<TrackStateProxy>::failure(
TrackExtrapolationError::CompatibleTrackStateNotFound);

for (const auto &trackState : track.trackStatesReversed()) {
bool isMeasurement =
trackState.typeFlags().test(TrackStateFlag::MeasurementFlag);
bool isOutlier = trackState.typeFlags().test(TrackStateFlag::OutlierFlag);

if (isMeasurement && !isOutlier) {
result = trackState;
}
}

return result;
}

template <typename track_proxy_t>
Result<typename track_proxy_t::ConstTrackStateProxy> findLastMeasurementState(
const track_proxy_t &track) {
using TrackStateProxy = typename track_proxy_t::ConstTrackStateProxy;

for (const auto &trackState : track.trackStatesReversed()) {
bool isMeasurement =
trackState.typeFlags().test(TrackStateFlag::MeasurementFlag);
bool isOutlier = trackState.typeFlags().test(TrackStateFlag::OutlierFlag);

if (isMeasurement && !isOutlier) {
return trackState;
}
}

return Result<TrackStateProxy>::failure(
TrackExtrapolationError::CompatibleTrackStateNotFound);
}

/// @brief Smooth a track using the gain matrix smoother
///
/// @tparam track_proxy_t The track proxy type
///
/// @param geoContext The geometry context
/// @param track The track to smooth
/// @param logger The logger
///
/// @return The result of the smoothing
template <typename track_proxy_t>
Result<void> smoothTrack(
const GeometryContext &geoContext, track_proxy_t &track,
const Logger &logger = *getDefaultLogger("TrackSmoother", Logging::INFO)) {
Acts::GainMatrixSmoother smoother;

auto &trackContainer = track.container();
auto &trackStateContainer = trackContainer.trackStateContainer();

auto last = findLastMeasurementState(track);
if (!last.ok()) {
ACTS_ERROR("no last track state found");
return last.error();
}

auto smoothingResult =
smoother(geoContext, trackStateContainer, last->index(), logger);

if (!smoothingResult.ok()) {
ACTS_ERROR("Smoothing track " << track.index() << " failed with error "
<< smoothingResult.error());
return smoothingResult.error();
}

return Result<void>::success();
}

/// @brief Smooth tracks using the gain matrix smoother
///
/// @tparam track_container_t The track container type
///
/// @param geoContext The geometry context
/// @param trackContainer The track container
/// @param logger The logger
///
/// @return The result of the smoothing
template <typename track_container_t>
Result<void> smoothTracks(
const GeometryContext &geoContext, const track_container_t &trackContainer,
const Logger &logger = *getDefaultLogger("TrackSmoother", Logging::INFO)) {
Result<void> result = Result<void>::success();

for (const auto &track : trackContainer) {
auto smoothingResult = smoothTrack(geoContext, track, logger);

// Only keep the first error
if (!smoothingResult.ok() && result.ok()) {
result = smoothingResult.error();
andiwand marked this conversation as resolved.
Show resolved Hide resolved
}
}

return result;
}

/// @brief Find a track state for extrapolation
///
/// @tparam track_proxy_t The track proxy type
///
/// @param geoContext The geometry context
/// @param track The track
/// @param referenceSurface The reference surface
/// @param strategy The extrapolation strategy
/// @param logger The logger
///
/// @return The result of the search containing the track state
/// and the distance to the reference surface
template <typename track_proxy_t>
Result<std::pair<typename track_proxy_t::ConstTrackStateProxy, double>>
findTrackStateForExtrapolation(
const GeometryContext &geoContext, track_proxy_t &track,
const Surface &referenceSurface, TrackExtrapolationStrategy strategy,
const Logger &logger = *getDefaultLogger("TrackExtrapolation",
Logging::INFO)) {
using TrackStateProxy = typename track_proxy_t::ConstTrackStateProxy;

auto intersect = [&](const TrackStateProxy &state) -> SurfaceIntersection {
auto freeVector = MultiTrajectoryHelpers::freeSmoothed(geoContext, state);

return referenceSurface
.intersect(geoContext, freeVector.template segment<3>(eFreePos0),
freeVector.template segment<3>(eFreeDir0),
BoundaryCheck(true), s_onSurfaceTolerance)
.closest();
};

switch (strategy) {
case TrackExtrapolationStrategy::first: {
ACTS_VERBOSE("looking for first track state");

auto first = findFirstMeasurementState(track);
if (!first.ok()) {
ACTS_ERROR("no first track state found");
return first.error();
}

SurfaceIntersection intersection = intersect(*first);
if (!intersection) {
ACTS_ERROR("no intersection found");
return Result<std::pair<TrackStateProxy, double>>::failure(
TrackExtrapolationError::ReferenceSurfaceUnreachable);
}

ACTS_VERBOSE("found intersection at " << intersection.pathLength());
return std::make_pair(*first, intersection.pathLength());
}

case TrackExtrapolationStrategy::last: {
ACTS_VERBOSE("looking for last track state");

auto last = findLastMeasurementState(track);
if (!last.ok()) {
ACTS_ERROR("no last track state found");
return last.error();
}

SurfaceIntersection intersection = intersect(*last);
if (!intersection) {
ACTS_ERROR("no intersection found");
return Result<std::pair<TrackStateProxy, double>>::failure(
TrackExtrapolationError::ReferenceSurfaceUnreachable);
}

ACTS_VERBOSE("found intersection at " << intersection.pathLength());
return std::make_pair(*last, intersection.pathLength());
}

case TrackExtrapolationStrategy::firstOrLast: {
ACTS_VERBOSE("looking for first or last track state");

auto first = findFirstMeasurementState(track);
if (!first.ok()) {
ACTS_ERROR("no first track state found");
return first.error();
}

auto last = findLastMeasurementState(track);
if (!last.ok()) {
ACTS_ERROR("no last track state found");
return last.error();
}

SurfaceIntersection intersectionFirst = intersect(*first);
SurfaceIntersection intersectionLast = intersect(*last);

double absDistanceFirst = std::abs(intersectionFirst.pathLength());
double absDistanceLast = std::abs(intersectionLast.pathLength());

if (intersectionFirst && absDistanceFirst <= absDistanceLast) {
ACTS_VERBOSE("using first track state with intersection at "
<< intersectionFirst.pathLength());
return std::make_pair(*first, intersectionFirst.pathLength());
}

if (intersectionLast && absDistanceLast <= absDistanceFirst) {
ACTS_VERBOSE("using last track state with intersection at "
<< intersectionLast.pathLength());
return std::make_pair(*last, intersectionLast.pathLength());
}

ACTS_ERROR("no intersection found");
return Result<std::pair<TrackStateProxy, double>>::failure(
TrackExtrapolationError::ReferenceSurfaceUnreachable);
}
}

// unreachable
return Result<std::pair<TrackStateProxy, double>>::failure(
TrackExtrapolationError::CompatibleTrackStateNotFound);
}

/// @brief Extrapolate a track to a reference surface
///
/// @tparam track_proxy_t The track proxy type
/// @tparam propagator_t The propagator type
/// @tparam propagator_options_t The propagator options type
///
/// @param track The track which is modified in-place
/// @param referenceSurface The reference surface
/// @param propagator The propagator
/// @param options The propagator options
/// @param strategy The extrapolation strategy
/// @param logger The logger
///
/// @return The result of the extrapolation
template <typename track_proxy_t, typename propagator_t,
typename propagator_options_t>
Result<void> extrapolateTrackToReferenceSurface(
track_proxy_t &track, const Surface &referenceSurface,
const propagator_t &propagator, propagator_options_t options,
TrackExtrapolationStrategy strategy,
const Logger &logger = *getDefaultLogger("TrackExtrapolation",
Logging::INFO)) {
auto findResult = findTrackStateForExtrapolation(
options.geoContext, track, referenceSurface, strategy, logger);

if (!findResult.ok()) {
ACTS_ERROR("failed to find track state for extrapolation");
return findResult.error();
}

auto &[trackState, distance] = *findResult;

options.direction = Direction::fromScalarZeroAsPositive(distance);
auto propagateResult =
propagator.template propagate<BoundTrackParameters, propagator_options_t,
ForcedSurfaceReached>(
track.createParametersFromState(trackState), referenceSurface,
options);

if (!propagateResult.ok()) {
ACTS_ERROR("failed to extrapolate track: " << propagateResult.error());
return propagateResult.error();
}

track.setReferenceSurface(referenceSurface.getSharedPtr());
track.parameters() = propagateResult->endParameters.value().parameters();
track.covariance() =
propagateResult->endParameters.value().covariance().value();

return Result<void>::success();
}

/// @brief Extrapolate tracks to a reference surface
///
/// @tparam track_container_t The track container type
/// @tparam propagator_t The propagator type
/// @tparam propagator_options_t The propagator options type
///
/// @param trackContainer The track container which is modified in-place
/// @param referenceSurface The reference surface
/// @param propagator The propagator
/// @param options The propagator options
/// @param strategy The extrapolation strategy
/// @param logger The logger
///
/// @return The result of the extrapolation
template <typename track_container_t, typename propagator_t,
typename propagator_options_t>
Result<void> extrapolateTracksToReferenceSurface(
const track_container_t &trackContainer, const Surface &referenceSurface,
const propagator_t &propagator, propagator_options_t options,
TrackExtrapolationStrategy strategy,
const Logger &logger = *getDefaultLogger("TrackExtrapolation",
Logging::INFO)) {
Result<void> result = Result<void>::success();

for (const auto &track : trackContainer) {
auto extrapolateResult = extrapolateTrackToReferenceSurface(
track, referenceSurface, propagator, options, strategy, logger);

// Only keep the first error
if (!extrapolateResult.ok() && result.ok()) {
result = extrapolateResult.error();
}
}

return result;
}

} // namespace Acts

namespace std {
// register with STL
template <>
struct is_error_code_enum<Acts::TrackExtrapolationError> : std::true_type {};
} // namespace std
1 change: 1 addition & 0 deletions Core/src/Utilities/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ target_sources(
BinUtility.cpp
Logger.cpp
SpacePointUtility.cpp
TrackHelpers.cpp
)
Loading
Loading