Skip to content

Commit

Permalink
feat(gx2f): Add new error DidNotConverge (#2898)
Browse files Browse the repository at this point in the history
Returns an error, if the fitter does not converge within the maximum number of updates.
  • Loading branch information
AJPfleger authored Jan 29, 2024
1 parent 7d596d1 commit 6aeeeda
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 0 deletions.
11 changes: 11 additions & 0 deletions Core/include/Acts/TrackFitting/GlobalChiSquareFitter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,17 @@ class Gx2Fitter {
ACTS_VERBOSE("final params:\n" << params);
/// Finish Fitting /////////////////////////////////////////////////////////

// Since currently most of our tracks converge in 4-5 updates, we want to
// set nUpdateMax higher than that to guarantee convergence for most tracks.
// In cases, where we set a smaller nUpdateMax, it's because we want to
// investigate the behaviour of the fitter before it converges, like in some
// unit-tests.
if (nUpdate == gx2fOptions.nUpdateMax && gx2fOptions.nUpdateMax > 5) {
ACTS_INFO("Did not converge in " << gx2fOptions.nUpdateMax
<< " updates.");
return Experimental::GlobalChiSquareFitterError::DidNotConverge;
}

// Calculate covariance of the fitted parameters with inverse of [a]
BoundMatrix fullCovariancePredicted = BoundMatrix::Identity();
bool aMatrixIsInvertible = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace Experimental {
enum class GlobalChiSquareFitterError {
// ensure all values are non-zero
AIsNotInvertible = 1,
DidNotConverge = 2,
};

std::error_code make_error_code(
Expand Down
2 changes: 2 additions & 0 deletions Core/src/TrackFitting/GlobalChiSquareFitterError.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class GlobalChiSquareFitterErrorCategory : public std::error_category {
switch (static_cast<GlobalChiSquareFitterError>(c)) {
case GlobalChiSquareFitterError::AIsNotInvertible:
return "Gx2f: aMatrix is not invertible.";
case GlobalChiSquareFitterError::DidNotConverge:
return "Gx2f: Did not converge in 'nUpdateMax' updates.";
default:
return "unknown";
}
Expand Down
72 changes: 72 additions & 0 deletions Tests/UnitTests/Core/TrackFitting/Gx2fTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,78 @@ BOOST_AUTO_TEST_CASE(relChi2changeCutOff) {

ACTS_INFO("*** Test: relChi2changeCutOff -- Finish");
}

BOOST_AUTO_TEST_CASE(DidNotConverge) {
ACTS_INFO("*** Test: DidNotConverge -- Start");

std::default_random_engine rng(42);

ACTS_DEBUG("Create the detector");
const std::size_t nSurfaces = 5;
Detector detector;
detector.geometry = makeToyDetector(geoCtx, nSurfaces);

ACTS_DEBUG("Set the start parameters for measurement creation and fit");
const auto parametersMeasurements = makeParameters();
const auto startParametersFit = makeParameters(
7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);

ACTS_DEBUG("Create the measurements");
// simulation propagator
using SimPropagator =
Acts::Propagator<Acts::StraightLineStepper, Acts::Navigator>;
const SimPropagator simPropagator = makeStraightPropagator(detector.geometry);
const auto measurements =
createMeasurements(simPropagator, geoCtx, magCtx, parametersMeasurements,
resMapAllPixel, rng);
const auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
ACTS_VERBOSE("sourceLinks.size() = " << sourceLinks.size());

BOOST_REQUIRE_EQUAL(sourceLinks.size(), nSurfaces);

ACTS_DEBUG("Set up the fitter");
const Surface* rSurface = &parametersMeasurements.referenceSurface();

using RecoStepper = EigenStepper<>;
const auto recoPropagator =
makeConstantFieldPropagator<RecoStepper>(detector.geometry, 0_T);

using RecoPropagator = decltype(recoPropagator);
using Gx2Fitter =
Experimental::Gx2Fitter<RecoPropagator, VectorMultiTrajectory>;
const Gx2Fitter fitter(recoPropagator, gx2fLogger->clone());

Experimental::Gx2FitterExtensions<VectorMultiTrajectory> extensions;
extensions.calibrator
.connect<&testSourceLinkCalibrator<VectorMultiTrajectory>>();
TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry};
extensions.surfaceAccessor
.connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);

// The relChi2changeCutOff = 0 prevents to stop the fitter after convergence,
// therefore all updates will be done (even if the result does not change).
// Since we didn't break due to convergence, we reach nUpdatesMax and
// therefore fail the fit.
const Experimental::Gx2FitterOptions gx2fOptions(
geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface,
false, false, FreeToBoundCorrection(false), 6, true, 0);

Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
Acts::VectorMultiTrajectory{}};

ACTS_DEBUG("Fit the track");
ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements);
ACTS_VERBOSE("startParameter fit:\n" << startParametersFit);
const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
startParametersFit, gx2fOptions, tracks);

BOOST_REQUIRE(!res.ok());
BOOST_CHECK_EQUAL(
res.error(),
Acts::Experimental::GlobalChiSquareFitterError::DidNotConverge);

ACTS_INFO("*** Test: DidNotConverge -- Finish");
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace Test
} // namespace Acts

0 comments on commit 6aeeeda

Please sign in to comment.