Skip to content

Commit e5c01a0

Browse files
committed
Protect from invalid measurement covariances
1 parent f1e2189 commit e5c01a0

2 files changed

Lines changed: 31 additions & 0 deletions

File tree

‎Detectors/ITSMFT/common/tracking/src/Propagator.cxx‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,9 @@ bool commitBarrelPropagation(SurfaceTrackState& destination, SurfaceTrackState&
279279
bool residualInverse(const SurfaceTrackState& state, const SurfaceMeasurement& measurement,
280280
float& inverse00, float& inverse01, float& inverse11) noexcept
281281
{
282+
if (!(measurement.covariance.uu >= 0.f) || !(measurement.covariance.vv >= 0.f)) {
283+
return false;
284+
}
282285
const float s00 = state.covariance[packedCovarianceIndex(0, 0)] + measurement.covariance.uu;
283286
const float s01 = state.covariance[packedCovarianceIndex(1, 0)] + measurement.covariance.uv;
284287
const float s11 = state.covariance[packedCovarianceIndex(1, 1)] + measurement.covariance.vv;

‎Detectors/ITSMFT/common/tracking/test/testPropagator.cxx‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,6 +1124,34 @@ BOOST_AUTO_TEST_CASE(FullMFTRefitLegUsesNominalMaterialAtEverySurface)
11241124

11251125
// --- 10/11: chi2-gate failure and atomicity ----------------------------------
11261126

1127+
BOOST_AUTO_TEST_CASE(NegativeMeasurementVarianceFailsTransactionally)
1128+
{
1129+
for (const bool forward : {false, true}) {
1130+
for (const bool negativeU : {false, true}) {
1131+
// Cover both a negative residual variance and a small invalid measurement
1132+
// variance hidden by the positive track covariance.
1133+
for (const float variance : {-1.f, -1.e-6f}) {
1134+
BOOST_TEST_CONTEXT("forward=" << forward << ", negativeU=" << negativeU << ", variance=" << variance)
1135+
{
1136+
auto state = forward ? diskState() : barrelState();
1137+
const auto before = state;
1138+
auto measurement = forward ? diskMeasurement() : barrelMeasurement();
1139+
(negativeU ? measurement.covariance.uu : measurement.covariance.vv) = variance;
1140+
float chi2 = 123.f;
1141+
1142+
BOOST_CHECK(!(forward ? Propagator::predictedChi2Forward(state, measurement, chi2)
1143+
: Propagator::predictedChi2Barrel(state, measurement, chi2)));
1144+
BOOST_CHECK_EQUAL(chi2, 123.f);
1145+
BOOST_CHECK(!(forward ? Propagator::updateForward(state, measurement, chi2)
1146+
: Propagator::updateBarrel(state, measurement, chi2)));
1147+
BOOST_CHECK(bitEqual(state, before));
1148+
BOOST_CHECK_EQUAL(chi2, 123.f);
1149+
}
1150+
}
1151+
}
1152+
}
1153+
}
1154+
11271155
BOOST_AUTO_TEST_CASE(Chi2GateRejectsOversizedPredictedChi2Transactionally)
11281156
{
11291157
auto state = barrelState();

0 commit comments

Comments
 (0)