Skip to content

Commit

Permalink
fix: Use material before the first measurement in smoothing (#956)
Browse files Browse the repository at this point in the history
This PR allow material situated before the first measurement (eg : beampipe) to be properly accounted for in the KF and CKF.
  • Loading branch information
Corentin-Allaire committed Aug 25, 2021
1 parent 0123060 commit 72eecda
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 36 deletions.
48 changes: 29 additions & 19 deletions Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,7 @@ class CombinatorialKalmanFilter {

// The surface could be either sensitive or passive
bool isSensitive = (surface->associatedDetectorElement() != nullptr);
bool isMaterial = (surface->surfaceMaterial() != nullptr);
std::string type = isSensitive ? "sensitive" : "passive";
ACTS_VERBOSE("Detected " << type
<< " surface: " << surface->geometryId());
Expand All @@ -675,11 +676,17 @@ class CombinatorialKalmanFilter {
// Add state if there is already measurement detected on this branch
// For in-sensitive surface, only add state when smoothing is
// required
if (tipState.nMeasurements > 0 and
(isSensitive or (not isSensitive and smoothing))) {
bool createState = false;
if (smoothing) {
createState = (tipState.nMeasurements > 0 or isMaterial);
} else {
createState = (tipState.nMeasurements > 0 and isSensitive);
}
if (createState) {
// New state is to be added. Remove the last tip from active tips now
result.activeTips.erase(result.activeTips.end() - 1);

if (not result.activeTips.empty()) {
result.activeTips.erase(result.activeTips.end() - 1);
}
// No source links on surface, add either hole or passive material
// TrackState. No storage allocation for uncalibrated/calibrated
// measurement and filtered parameter
Expand Down Expand Up @@ -976,15 +983,17 @@ class CombinatorialKalmanFilter {
const auto& lastMeasurementIndex =
result.lastMeasurementIndices.at(result.iSmoothed);

// Get the indices of the first measurement states;
size_t firstMeasurementIndex = lastMeasurementIndex;
// Get the indices of the first states (can be either a measurement or
// material);
size_t firstStateIndex = lastMeasurementIndex;
// Count track states to be smoothed
size_t nStates = 0;
result.fittedStates.applyBackwards(lastMeasurementIndex, [&](auto st) {
bool isMeasurement =
st.typeFlags().test(TrackStateFlag::MeasurementFlag);
if (isMeasurement) {
firstMeasurementIndex = st.index();
bool isMaterial = st.typeFlags().test(TrackStateFlag::MaterialFlag);
if (isMeasurement || isMaterial) {
firstStateIndex = st.index();
}
nStates++;
});
Expand All @@ -1010,9 +1019,10 @@ class CombinatorialKalmanFilter {
return Result<void>::success();
}

// Obtain the smoothed parameters at first/last measurement state
auto firstCreatedMeasurement =
result.fittedStates.getTrackState(firstMeasurementIndex);
// Obtain the smoothed parameters at first/last measurement state.
// The first state can also be a material state
auto firstCreatedState =
result.fittedStates.getTrackState(firstStateIndex);
auto lastCreatedMeasurement =
result.fittedStates.getTrackState(lastMeasurementIndex);

Expand All @@ -1025,7 +1035,7 @@ class CombinatorialKalmanFilter {

// The smoothed free params at the first/last measurement state
auto firstParams = MultiTrajectoryHelpers::freeSmoothed(
state.options.geoContext, firstCreatedMeasurement);
state.options.geoContext, firstCreatedState);
auto lastParams = MultiTrajectoryHelpers::freeSmoothed(
state.options.geoContext, lastCreatedMeasurement);
// Get the intersections of the smoothed free parameters with the target
Expand All @@ -1042,14 +1052,14 @@ class CombinatorialKalmanFilter {
// smoothed measurement state. Also, whether the intersection is on
// surface is not checked here.
bool reverseDirection = false;
bool closerToFirstCreatedMeasurement =
bool closerTofirstCreatedState =
(std::abs(firstIntersection.intersection.pathLength) <=
std::abs(lastIntersection.intersection.pathLength));
if (closerToFirstCreatedMeasurement) {
if (closerTofirstCreatedState) {
stepper.update(state.stepping, firstParams,
firstCreatedMeasurement.smoothed(),
firstCreatedMeasurement.smoothedCovariance(),
firstCreatedMeasurement.referenceSurface());
firstCreatedState.smoothed(),
firstCreatedState.smoothedCovariance(),
firstCreatedState.referenceSurface());
reverseDirection = (firstIntersection.intersection.pathLength < 0);
} else {
stepper.update(state.stepping, lastParams,
Expand All @@ -1058,8 +1068,8 @@ class CombinatorialKalmanFilter {
lastCreatedMeasurement.referenceSurface());
reverseDirection = (lastIntersection.intersection.pathLength < 0);
}
const auto& surface = closerToFirstCreatedMeasurement
? firstCreatedMeasurement.referenceSurface()
const auto& surface = closerTofirstCreatedState
? firstCreatedState.referenceSurface()
: lastCreatedMeasurement.referenceSurface();
ACTS_VERBOSE(
"Smoothing successful, updating stepping state to smoothed "
Expand Down
39 changes: 22 additions & 17 deletions Core/include/Acts/TrackFitting/KalmanFitter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,8 +575,10 @@ class KalmanFitter {
} else if (surface->associatedDetectorElement() != nullptr ||
surface->surfaceMaterial() != nullptr) {
// We only create track states here if there is already measurement
// detected
if (result.measurementStates > 0) {
// detected or if the surface has material (no holes before the first
// measurement)
if (result.measurementStates > 0 ||
surface->surfaceMaterial() != nullptr) {
// No source links on surface, add either hole or passive material
// TrackState entry multi trajectory. No storage allocation for
// uncalibrated/calibrated measurement and filtered parameter
Expand Down Expand Up @@ -853,16 +855,18 @@ class KalmanFitter {
// Remember you smoothed the track states
result.smoothed = true;

// Get the indices of the first measurement states;
size_t firstMeasurementIndex = result.lastMeasurementIndex;
// Get the indices of the first states (can be either a measurement or
// material);
size_t firstStateIndex = result.lastMeasurementIndex;
// Count track states to be smoothed
size_t nStates = 0;
result.fittedStates.applyBackwards(
result.lastMeasurementIndex, [&](auto st) {
bool isMeasurement =
st.typeFlags().test(TrackStateFlag::MeasurementFlag);
if (isMeasurement) {
firstMeasurementIndex = st.index();
bool isMaterial = st.typeFlags().test(TrackStateFlag::MaterialFlag);
if (isMeasurement || isMaterial) {
firstStateIndex = st.index();
}
nStates++;
});
Expand Down Expand Up @@ -892,8 +896,8 @@ class KalmanFitter {
}

// Obtain the smoothed parameters at first/last measurement state
auto firstCreatedMeasurement =
result.fittedStates.getTrackState(firstMeasurementIndex);
auto firstCreatedState =
result.fittedStates.getTrackState(firstStateIndex);
auto lastCreatedMeasurement =
result.fittedStates.getTrackState(result.lastMeasurementIndex);

Expand All @@ -904,9 +908,10 @@ class KalmanFitter {
state.stepping.navDir * freeVector.segment<3>(eFreeDir0), true);
};

// The smoothed free params at the first/last measurement state
// The smoothed free params at the first/last measurement state.
// (the first state can also be a material state)
auto firstParams = MultiTrajectoryHelpers::freeSmoothed(
state.options.geoContext, firstCreatedMeasurement);
state.options.geoContext, firstCreatedState);
auto lastParams = MultiTrajectoryHelpers::freeSmoothed(
state.options.geoContext, lastCreatedMeasurement);
// Get the intersections of the smoothed free parameters with the target
Expand All @@ -923,14 +928,14 @@ class KalmanFitter {
// smoothed measurement state. Also, whether the intersection is on
// surface is not checked here.
bool reverseDirection = false;
bool closerToFirstCreatedMeasurement =
bool closerTofirstCreatedState =
(std::abs(firstIntersection.intersection.pathLength) <=
std::abs(lastIntersection.intersection.pathLength));
if (closerToFirstCreatedMeasurement) {
if (closerTofirstCreatedState) {
stepper.update(state.stepping, firstParams,
firstCreatedMeasurement.smoothed(),
firstCreatedMeasurement.smoothedCovariance(),
firstCreatedMeasurement.referenceSurface());
firstCreatedState.smoothed(),
firstCreatedState.smoothedCovariance(),
firstCreatedState.referenceSurface());
reverseDirection = (firstIntersection.intersection.pathLength < 0);
} else {
stepper.update(state.stepping, lastParams,
Expand All @@ -939,8 +944,8 @@ class KalmanFitter {
lastCreatedMeasurement.referenceSurface());
reverseDirection = (lastIntersection.intersection.pathLength < 0);
}
const auto& surface = closerToFirstCreatedMeasurement
? firstCreatedMeasurement.referenceSurface()
const auto& surface = closerTofirstCreatedState
? firstCreatedState.referenceSurface()
: lastCreatedMeasurement.referenceSurface();
ACTS_VERBOSE(
"Smoothing successful, updating stepping state to smoothed "
Expand Down

0 comments on commit 72eecda

Please sign in to comment.