Skip to content

Commit

Permalink
refactor!: (gx2f) remove zeroField option and make implicit (acts-p…
Browse files Browse the repository at this point in the history
…roject#3276)

Instead of telling the fitter to fit some components like qop or T, we let it figure out, if there is enough information.
  • Loading branch information
AJPfleger authored and Tim Adye committed Jun 27, 2024
1 parent be89142 commit c6de57a
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 43 deletions.
26 changes: 15 additions & 11 deletions Core/include/Acts/TrackFitting/GlobalChiSquareFitter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ struct Gx2FitterOptions {
/// @param eLoss Whether to include energy loss
/// @param freeToBoundCorrection_ Correction for non-linearity effect during transform from free to bound
/// @param nUpdateMax_ Max number of iterations for updating the parameters
/// @param zeroField_ Disables the QoP fit in case of missing B-field
/// @param relChi2changeCutOff_ Check for convergence (abort condition). Set to 0 to skip.
Gx2FitterOptions(const GeometryContext& gctx,
const MagneticFieldContext& mctx,
Expand All @@ -120,7 +119,6 @@ struct Gx2FitterOptions {
const FreeToBoundCorrection& freeToBoundCorrection_ =
FreeToBoundCorrection(false),
const std::size_t nUpdateMax_ = 5,
const bool zeroField_ = false,
double relChi2changeCutOff_ = 1e-5)
: geoContext(gctx),
magFieldContext(mctx),
Expand All @@ -132,7 +130,6 @@ struct Gx2FitterOptions {
energyLoss(eLoss),
freeToBoundCorrection(freeToBoundCorrection_),
nUpdateMax(nUpdateMax_),
zeroField(zeroField_),
relChi2changeCutOff(relChi2changeCutOff_) {}

/// Contexts are required and the options must not be default-constructible.
Expand Down Expand Up @@ -166,9 +163,6 @@ struct Gx2FitterOptions {
/// Max number of iterations during the fit (abort condition)
std::size_t nUpdateMax = 5;

/// Disables the QoP fit in case of missing B-field
bool zeroField = false;

/// Check for convergence (abort condition). Set to 0 to skip.
double relChi2changeCutOff = 1e-7;
};
Expand Down Expand Up @@ -298,7 +292,7 @@ void addToGx2fSums(BoundMatrix& aMatrix, BoundVector& bVector, double& chi2sum,
}
}

BoundVector calculateDeltaParams(bool zeroField, const BoundMatrix& aMatrix,
BoundVector calculateDeltaParams(const BoundMatrix& aMatrix,
const BoundVector& bVector);

/// Global Chi Square fitter (GX2F) implementation.
Expand Down Expand Up @@ -864,8 +858,7 @@ class Gx2Fitter {
}

// calculate delta params [a] * delta = b
deltaParams =
calculateDeltaParams(gx2fOptions.zeroField, aMatrix, bVector);
deltaParams = calculateDeltaParams(aMatrix, bVector);

ACTS_VERBOSE("aMatrix:\n"
<< aMatrix << "\n"
Expand Down Expand Up @@ -910,7 +903,7 @@ class Gx2Fitter {
// Calculate covariance of the fitted parameters with inverse of [a]
BoundMatrix fullCovariancePredicted = BoundMatrix::Identity();
bool aMatrixIsInvertible = false;
if (gx2fOptions.zeroField) {
if (aMatrix(4, 4) == 0) {
constexpr std::size_t reducedMatrixSize = 4;

auto safeReducedCovariance = safeInverse(
Expand All @@ -921,9 +914,20 @@ class Gx2Fitter {
.topLeftCorner<reducedMatrixSize, reducedMatrixSize>() =
*safeReducedCovariance;
}
} else {
} else if (aMatrix(5, 5) == 0) {
constexpr std::size_t reducedMatrixSize = 5;

auto safeReducedCovariance = safeInverse(
aMatrix.topLeftCorner<reducedMatrixSize, reducedMatrixSize>().eval());
if (safeReducedCovariance) {
aMatrixIsInvertible = true;
fullCovariancePredicted
.topLeftCorner<reducedMatrixSize, reducedMatrixSize>() =
*safeReducedCovariance;
}
} else {
constexpr std::size_t reducedMatrixSize = 6;

auto safeReducedCovariance = safeInverse(
aMatrix.topLeftCorner<reducedMatrixSize, reducedMatrixSize>().eval());
if (safeReducedCovariance) {
Expand Down
13 changes: 10 additions & 3 deletions Core/src/TrackFitting/GlobalChiSquareFitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,30 @@

namespace Acts::Experimental {

BoundVector calculateDeltaParams(bool zeroField, const BoundMatrix& aMatrix,
BoundVector calculateDeltaParams(const BoundMatrix& aMatrix,
const BoundVector& bVector) {
BoundVector deltaParams = BoundVector::Zero();
if (zeroField) {
if (aMatrix(4, 4) == 0) {
constexpr std::size_t reducedMatrixSize = 4;
deltaParams.topLeftCorner<reducedMatrixSize, 1>() =
aMatrix.topLeftCorner<reducedMatrixSize, reducedMatrixSize>()
.colPivHouseholderQr()
.solve(bVector.topLeftCorner<reducedMatrixSize, 1>());
} else {
} else if (aMatrix(5, 5) == 0) {
constexpr std::size_t reducedMatrixSize = 5;
deltaParams.topLeftCorner<reducedMatrixSize, 1>() =
aMatrix.topLeftCorner<reducedMatrixSize, reducedMatrixSize>()
.colPivHouseholderQr()
.solve(bVector.topLeftCorner<reducedMatrixSize, 1>());
} else {
constexpr std::size_t reducedMatrixSize = 6;
deltaParams.topLeftCorner<reducedMatrixSize, 1>() =
aMatrix.topLeftCorner<reducedMatrixSize, reducedMatrixSize>()
.colPivHouseholderQr()
.solve(bVector.topLeftCorner<reducedMatrixSize, 1>());
}

return deltaParams;
}

} // namespace Acts::Experimental
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ std::shared_ptr<TrackFitterFunction> makeGsfFitterFunction(
/// @param energyLoss bool
/// @param freeToBoundCorrection bool
/// @param nUpdateMax max number of iterations during the fit
/// @param zerofield Disables the QoP fit in case of missing B-field.
/// @param relChi2changeCutOff Check for convergence (abort condition). Set to 0 to skip.
/// @param logger a logger instance
std::shared_ptr<TrackFitterFunction> makeGlobalChiSquareFitterFunction(
Expand All @@ -114,8 +113,7 @@ std::shared_ptr<TrackFitterFunction> makeGlobalChiSquareFitterFunction(
bool multipleScattering = true, bool energyLoss = true,
Acts::FreeToBoundCorrection freeToBoundCorrection =
Acts::FreeToBoundCorrection(),
std::size_t nUpdateMax = 5, bool zeroField = false,
double relChi2changeCutOff = 1e-7,
std::size_t nUpdateMax = 5, double relChi2changeCutOff = 1e-7,
const Acts::Logger& logger = *Acts::getDefaultLogger("Gx2f",
Acts::Logging::INFO));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ struct GlobalChiSquareFitterFunctionImpl final : public TrackFitterFunction {
bool energyLoss = false;
Acts::FreeToBoundCorrection freeToBoundCorrection;
std::size_t nUpdateMax = 5;
bool zeroField = false;
double relChi2changeCutOff = 1e-7;

IndexSourceLink::SurfaceAccessor m_slSurfaceAccessor;
Expand All @@ -95,7 +94,7 @@ struct GlobalChiSquareFitterFunctionImpl final : public TrackFitterFunction {
options.geoContext, options.magFieldContext, options.calibrationContext,
extensions, options.propOptions, &(*options.referenceSurface),
multipleScattering, energyLoss, freeToBoundCorrection, nUpdateMax,
zeroField, relChi2changeCutOff);
relChi2changeCutOff);

return gx2fOptions;
}
Expand Down Expand Up @@ -132,7 +131,7 @@ ActsExamples::makeGlobalChiSquareFitterFunction(
std::shared_ptr<const Acts::MagneticFieldProvider> magneticField,
bool multipleScattering, bool energyLoss,
Acts::FreeToBoundCorrection freeToBoundCorrection, std::size_t nUpdateMax,
bool zeroField, double relChi2changeCutOff, const Acts::Logger& logger) {
double relChi2changeCutOff, const Acts::Logger& logger) {
// Stepper should be copied into the fitters
const Stepper stepper(std::move(magneticField));

Expand Down Expand Up @@ -162,7 +161,6 @@ ActsExamples::makeGlobalChiSquareFitterFunction(
fitterFunction->energyLoss = energyLoss;
fitterFunction->freeToBoundCorrection = freeToBoundCorrection;
fitterFunction->nUpdateMax = nUpdateMax;
fitterFunction->zeroField = zeroField;
fitterFunction->relChi2changeCutOff = relChi2changeCutOff;

return fitterFunction;
Expand Down
2 changes: 0 additions & 2 deletions Examples/Python/python/acts/examples/reconstruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -1367,7 +1367,6 @@ def addGx2fTracks(
multipleScattering: bool = False,
energyLoss: bool = False,
nUpdateMax: int = 5,
zeroField: bool = False,
relChi2changeCutOff: float = 1e-7,
clusters: str = None,
calibrator: acts.examples.MeasurementCalibrator = acts.examples.makePassThroughCalibrator(),
Expand All @@ -1380,7 +1379,6 @@ def addGx2fTracks(
"energyLoss": energyLoss,
"freeToBoundCorrection": acts.examples.FreeToBoundCorrection(False),
"nUpdateMax": nUpdateMax,
"zeroField": zeroField,
"relChi2changeCutOff": relChi2changeCutOff,
"level": customLogLevel(),
}
Expand Down
6 changes: 3 additions & 3 deletions Examples/Python/src/TrackFitting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,17 +138,17 @@ void addTrackFitting(Context& ctx) {
std::shared_ptr<const Acts::MagneticFieldProvider> magneticField,
bool multipleScattering, bool energyLoss,
Acts::FreeToBoundCorrection freeToBoundCorrection,
std::size_t nUpdateMax, bool zeroField, double relChi2changeCutOff,
std::size_t nUpdateMax, double relChi2changeCutOff,
Logging::Level level) {
return ActsExamples::makeGlobalChiSquareFitterFunction(
trackingGeometry, magneticField, multipleScattering, energyLoss,
freeToBoundCorrection, nUpdateMax, zeroField, relChi2changeCutOff,
freeToBoundCorrection, nUpdateMax, relChi2changeCutOff,
*Acts::getDefaultLogger("Gx2f", level));
},
py::arg("trackingGeometry"), py::arg("magneticField"),
py::arg("multipleScattering"), py::arg("energyLoss"),
py::arg("freeToBoundCorrection"), py::arg("nUpdateMax"),
py::arg("zeroField"), py::arg("relChi2changeCutOff"), py::arg("level"));
py::arg("relChi2changeCutOff"), py::arg("level"));
}

{
Expand Down
18 changes: 9 additions & 9 deletions Tests/UnitTests/Core/TrackFitting/Gx2fTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ BOOST_AUTO_TEST_CASE(NoFit) {

Experimental::Gx2FitterOptions gx2fOptions(
geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface,
false, false, FreeToBoundCorrection(false), 0, true, 0);
false, false, FreeToBoundCorrection(false), 0, 0);

Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
Acts::VectorMultiTrajectory{}};
Expand Down Expand Up @@ -327,7 +327,7 @@ BOOST_AUTO_TEST_CASE(Fit5Iterations) {

const Experimental::Gx2FitterOptions gx2fOptions(
geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface,
false, false, FreeToBoundCorrection(false), 5, true, 0);
false, false, FreeToBoundCorrection(false), 5, 0);

Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
Acts::VectorMultiTrajectory{}};
Expand Down Expand Up @@ -432,7 +432,7 @@ BOOST_AUTO_TEST_CASE(MixedDetector) {

const Experimental::Gx2FitterOptions gx2fOptions(
geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface,
false, false, FreeToBoundCorrection(false), 5, true, 0);
false, false, FreeToBoundCorrection(false), 5, 0);

Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
Acts::VectorMultiTrajectory{}};
Expand Down Expand Up @@ -527,7 +527,7 @@ BOOST_AUTO_TEST_CASE(FitWithBfield) {

const Experimental::Gx2FitterOptions gx2fOptions(
geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface,
false, false, FreeToBoundCorrection(false), 5, false, 0);
false, false, FreeToBoundCorrection(false), 5, 0);

Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
Acts::VectorMultiTrajectory{}};
Expand Down Expand Up @@ -624,7 +624,7 @@ BOOST_AUTO_TEST_CASE(relChi2changeCutOff) {

const Experimental::Gx2FitterOptions gx2fOptions(
geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface,
false, false, FreeToBoundCorrection(false), 500, true, 1e-5);
false, false, FreeToBoundCorrection(false), 500, 1e-5);

Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
Acts::VectorMultiTrajectory{}};
Expand Down Expand Up @@ -724,7 +724,7 @@ BOOST_AUTO_TEST_CASE(DidNotConverge) {
// therefore fail the fit.
const Experimental::Gx2FitterOptions gx2fOptions(
geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface,
false, false, FreeToBoundCorrection(false), 6, true, 0);
false, false, FreeToBoundCorrection(false), 6, 0);

Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
Acts::VectorMultiTrajectory{}};
Expand Down Expand Up @@ -792,7 +792,7 @@ BOOST_AUTO_TEST_CASE(NotEnoughMeasurements) {

const Experimental::Gx2FitterOptions gx2fOptions(
geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface,
false, false, FreeToBoundCorrection(false), 6, true, 0);
false, false, FreeToBoundCorrection(false), 6, 0);

Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
Acts::VectorMultiTrajectory{}};
Expand Down Expand Up @@ -880,7 +880,7 @@ BOOST_AUTO_TEST_CASE(FindHoles) {

const Experimental::Gx2FitterOptions gx2fOptions(
geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface,
false, false, FreeToBoundCorrection(false), 20, true, 1e-5);
false, false, FreeToBoundCorrection(false), 20, 1e-5);

Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
Acts::VectorMultiTrajectory{}};
Expand Down Expand Up @@ -985,7 +985,7 @@ BOOST_AUTO_TEST_CASE(Material) {

const Experimental::Gx2FitterOptions gx2fOptions(
geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface,
false, false, FreeToBoundCorrection(false), 5, true, 0);
false, false, FreeToBoundCorrection(false), 5, 0);

Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
Acts::VectorMultiTrajectory{}};
Expand Down
9 changes: 1 addition & 8 deletions docs/core/reconstruction/track_fitting.md
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,6 @@ Gx2FitterOptions() = delete;
/// Max number of iterations during the fit (abort condition)
size_t nUpdateMax = 5;

/// Disables the QoP fit in case of missing B-field
bool zeroField = false;

/// Check for convergence (abort condition). Set to 0 to skip.
double relChi2changeCutOff = 1e-7;
};
Expand All @@ -356,11 +353,7 @@ Common options like the geometry context or toggling of the energy loss are simi
For now there are three *GX2F* specific options:
1. `nUpdateMax` sets an abort condition for the parameter update as a maximum number of iterations allowed.
We do not really want to use this condition, but it stops the fit in case of poor convergence.
2. `zeroField` toggles the q/p-fit.
If there is no magnetic field, we get no q/p-information.
This would crash the fitter when needing matrix inverses.
When this option is set to `true`, most of the matrices will omit the q/p-rows and -columns.
3. `relChi2changeCutOff` is the desired convergence criterion.
2. `relChi2changeCutOff` is the desired convergence criterion.
We compare at each step of the iteration the current to the previous $\chi^2$.
If the relative change is small enough, we finish the fit.
Expand Down

0 comments on commit c6de57a

Please sign in to comment.