diff --git a/CI/physmon/workflows/physmon_trackfitting_kf.py b/CI/physmon/workflows/physmon_trackfitting_kf.py index 767c2ff5d69..b7aadfb6da1 100755 --- a/CI/physmon/workflows/physmon_trackfitting_kf.py +++ b/CI/physmon/workflows/physmon_trackfitting_kf.py @@ -24,6 +24,8 @@ field=setup.field, digiConfigFile=setup.digiConfig, outputDir=tp, + reverseFilteringMomThreshold=float("inf"), + reverseFilteringCovarianceScaling=100.0, s=s, ) diff --git a/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp b/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp index fcada49abc2..65ed2deac47 100644 --- a/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp +++ b/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp @@ -321,11 +321,23 @@ struct GaussianSumFitter { : sParameters.referenceSurface(); const auto& params = *fwdGsfResult.lastMeasurementState; + std::vector< + std::tuple>> + inflatedParamVector; + for (auto& [w, p, cov] : params.components()) { + inflatedParamVector.emplace_back( + w, p, cov.value() * options.reverseFilteringCovarianceScaling); + } + + MultiComponentBoundTrackParameters inflatedParams( + params.referenceSurface().getSharedPtr(), + std::move(inflatedParamVector), params.particleHypothesis()); + auto state = m_propagator.template makeState( - params, target, bwdPropOptions); + inflatedParams, target, bwdPropOptions); assert( (fwdGsfResult.lastMeasurementTip != MultiTrajectoryTraits::kInvalid && diff --git a/Core/include/Acts/TrackFitting/GsfOptions.hpp b/Core/include/Acts/TrackFitting/GsfOptions.hpp index 88fb902daff..c2d9e6e8e94 100644 --- a/Core/include/Acts/TrackFitting/GsfOptions.hpp +++ b/Core/include/Acts/TrackFitting/GsfOptions.hpp @@ -112,6 +112,8 @@ struct GsfOptions { bool disableAllMaterialHandling = false; + double reverseFilteringCovarianceScaling = 1.0; + std::string_view finalMultiComponentStateColumn = ""; ComponentMergeMethod componentMergeMethod = ComponentMergeMethod::eMaxWeight; diff --git a/Examples/Algorithms/TrackFitting/include/ActsExamples/TrackFitting/TrackFitterFunction.hpp b/Examples/Algorithms/TrackFitting/include/ActsExamples/TrackFitting/TrackFitterFunction.hpp index a58d0a90afb..99d149619e7 100644 --- a/Examples/Algorithms/TrackFitting/include/ActsExamples/TrackFitting/TrackFitterFunction.hpp +++ b/Examples/Algorithms/TrackFitting/include/ActsExamples/TrackFitting/TrackFitterFunction.hpp @@ -66,6 +66,7 @@ std::shared_ptr makeKalmanFitterFunction( std::shared_ptr magneticField, bool multipleScattering = true, bool energyLoss = true, double reverseFilteringMomThreshold = 0.0, + double reverseFilteringCovarianceScaling = 1.0, Acts::FreeToBoundCorrection freeToBoundCorrection = Acts::FreeToBoundCorrection(), const Acts::Logger& logger = *Acts::getDefaultLogger("Kalman", @@ -89,6 +90,8 @@ enum class MixtureReductionAlgorithm { weightCut, KLDistance }; /// parameters and covariance /// @param mixtureReductionAlgorithm How to reduce the number of components /// in a mixture +/// @param reverseFilteringCovarianceScaling How the covariance matrices are +/// inflated before the reverse filtering pass /// @param logger a logger instance std::shared_ptr makeGsfFitterFunction( std::shared_ptr trackingGeometry, @@ -96,7 +99,7 @@ std::shared_ptr makeGsfFitterFunction( BetheHeitlerApprox betheHeitlerApprox, std::size_t maxComponents, double weightCutoff, Acts::ComponentMergeMethod componentMergeMethod, MixtureReductionAlgorithm mixtureReductionAlgorithm, - const Acts::Logger& logger); + double reverseFilteringCovarianceScaling, const Acts::Logger& logger); /// Makes a fitter function object for the Global Chi Square Fitter (GX2F) /// diff --git a/Examples/Algorithms/TrackFitting/src/GsfFitterFunction.cpp b/Examples/Algorithms/TrackFitting/src/GsfFitterFunction.cpp index 7e893fff468..51203e50910 100644 --- a/Examples/Algorithms/TrackFitting/src/GsfFitterFunction.cpp +++ b/Examples/Algorithms/TrackFitting/src/GsfFitterFunction.cpp @@ -87,6 +87,7 @@ struct GsfFitterFunctionImpl final : public ActsExamples::TrackFitterFunction { MixtureReductionAlgorithm::KLDistance; Acts::ComponentMergeMethod mergeMethod = Acts::ComponentMergeMethod::eMaxWeight; + double reverseFilteringCovarianceScaling = 0.0; IndexSourceLink::SurfaceAccessor m_slSurfaceAccessor; @@ -115,6 +116,8 @@ struct GsfFitterFunctionImpl final : public ActsExamples::TrackFitterFunction { gsfOptions.abortOnError = abortOnError; gsfOptions.disableAllMaterialHandling = disableAllMaterialHandling; gsfOptions.componentMergeMethod = mergeMethod; + gsfOptions.reverseFilteringCovarianceScaling = + reverseFilteringCovarianceScaling; gsfOptions.extensions.calibrator.connect<&calibrator_t::calibrate>( &calibrator); @@ -195,7 +198,7 @@ std::shared_ptr ActsExamples::makeGsfFitterFunction( BetheHeitlerApprox betheHeitlerApprox, std::size_t maxComponents, double weightCutoff, Acts::ComponentMergeMethod componentMergeMethod, MixtureReductionAlgorithm mixtureReductionAlgorithm, - const Acts::Logger& logger) { + double reverseFilteringCovarianceScaling, const Acts::Logger& logger) { // Standard fitter MultiStepper stepper(magneticField, logger.cloneWithSuffix("Step")); const auto& geo = *trackingGeometry; @@ -229,6 +232,8 @@ std::shared_ptr ActsExamples::makeGsfFitterFunction( fitterFunction->weightCutoff = weightCutoff; fitterFunction->mergeMethod = componentMergeMethod; fitterFunction->reductionAlg = mixtureReductionAlgorithm; + fitterFunction->reverseFilteringCovarianceScaling = + reverseFilteringCovarianceScaling; return fitterFunction; } diff --git a/Examples/Algorithms/TrackFitting/src/KalmanFitterFunction.cpp b/Examples/Algorithms/TrackFitting/src/KalmanFitterFunction.cpp index 6f835c5c967..5b5417e73fc 100644 --- a/Examples/Algorithms/TrackFitting/src/KalmanFitterFunction.cpp +++ b/Examples/Algorithms/TrackFitting/src/KalmanFitterFunction.cpp @@ -76,7 +76,7 @@ struct KalmanFitterFunctionImpl final : public TrackFitterFunction { Acts::GainMatrixUpdater kfUpdater; Acts::GainMatrixSmoother kfSmoother; SimpleReverseFilteringLogic reverseFilteringLogic; - + double reverseFilteringCovarianceScaling; bool multipleScattering = false; bool energyLoss = false; Acts::FreeToBoundCorrection freeToBoundCorrection; @@ -114,6 +114,8 @@ struct KalmanFitterFunctionImpl final : public TrackFitterFunction { kfOptions.freeToBoundCorrection = freeToBoundCorrection; kfOptions.extensions.calibrator.connect<&calibrator_t::calibrate>( &calibrator); + kfOptions.reversedFilteringCovarianceScaling = + reverseFilteringCovarianceScaling; if (options.doRefit) { kfOptions.extensions.surfaceAccessor @@ -159,6 +161,7 @@ ActsExamples::makeKalmanFitterFunction( std::shared_ptr magneticField, bool multipleScattering, bool energyLoss, double reverseFilteringMomThreshold, + double reverseFilteringCovarianceScaling, Acts::FreeToBoundCorrection freeToBoundCorrection, const Acts::Logger& logger) { // Stepper should be copied into the fitters @@ -191,6 +194,8 @@ ActsExamples::makeKalmanFitterFunction( fitterFunction->reverseFilteringLogic.momentumThreshold = reverseFilteringMomThreshold; fitterFunction->freeToBoundCorrection = freeToBoundCorrection; + fitterFunction->reverseFilteringCovarianceScaling = + reverseFilteringCovarianceScaling; return fitterFunction; } diff --git a/Examples/Python/python/acts/examples/reconstruction.py b/Examples/Python/python/acts/examples/reconstruction.py index 0e30961fe39..727f3e9dba6 100644 --- a/Examples/Python/python/acts/examples/reconstruction.py +++ b/Examples/Python/python/acts/examples/reconstruction.py @@ -1289,6 +1289,7 @@ def addKalmanTracks( trackingGeometry: acts.TrackingGeometry, field: acts.MagneticFieldProvider, reverseFilteringMomThreshold: float = 0 * u.GeV, + reverseFilteringCovarianceScaling: float = 1.0, inputProtoTracks: str = "truth_particle_tracks", multipleScattering: bool = True, energyLoss: bool = True, @@ -1302,6 +1303,7 @@ def addKalmanTracks( "multipleScattering": multipleScattering, "energyLoss": energyLoss, "reverseFilteringMomThreshold": reverseFilteringMomThreshold, + "reverseFilteringCovarianceScaling": reverseFilteringCovarianceScaling, "freeToBoundCorrection": acts.examples.FreeToBoundCorrection(False), "level": customLogLevel(), } @@ -1362,6 +1364,7 @@ def addTruthTrackingGsf( "componentMergeMethod": acts.examples.ComponentMergeMethod.maxWeight, "mixtureReductionAlgorithm": acts.examples.MixtureReductionAlgorithm.KLDistance, "weightCutoff": 1.0e-4, + "reverseFilteringCovarianceScaling": 100.0, "level": customLogLevel(), } diff --git a/Examples/Python/src/TrackFitting.cpp b/Examples/Python/src/TrackFitting.cpp index 6d1b9818e51..4a02c9bb83c 100644 --- a/Examples/Python/src/TrackFitting.cpp +++ b/Examples/Python/src/TrackFitting.cpp @@ -53,17 +53,18 @@ void addTrackFitting(Context& ctx) { std::shared_ptr magneticField, bool multipleScattering, bool energyLoss, double reverseFilteringMomThreshold, + double reverseFilteringCovarianceScaling, Acts::FreeToBoundCorrection freeToBoundCorrection, Logging::Level level) { return ActsExamples::makeKalmanFitterFunction( trackingGeometry, magneticField, multipleScattering, energyLoss, - reverseFilteringMomThreshold, freeToBoundCorrection, - *Acts::getDefaultLogger("Kalman", level)); + reverseFilteringMomThreshold, reverseFilteringCovarianceScaling, + freeToBoundCorrection, *Acts::getDefaultLogger("Kalman", level)); }, - py::arg("trackingGeometry"), py::arg("magneticField"), - py::arg("multipleScattering"), py::arg("energyLoss"), - py::arg("reverseFilteringMomThreshold"), - py::arg("freeToBoundCorrection"), py::arg("level")); + "trackingGeometry"_a, "magneticField"_a, "multipleScattering"_a, + "energyLoss"_a, "reverseFilteringMomThreshold"_a, + "reverseFilteringCovarianceScaling"_a, "freeToBoundCorrection"_a, + "level"_a); py::class_>( mex, "MeasurementCalibrator"); @@ -108,17 +109,17 @@ void addTrackFitting(Context& ctx) { BetheHeitlerApprox betheHeitlerApprox, std::size_t maxComponents, double weightCutoff, Acts::ComponentMergeMethod componentMergeMethod, ActsExamples::MixtureReductionAlgorithm mixtureReductionAlgorithm, - Logging::Level level) { + double reverseFilteringCovarianceScaling, Logging::Level level) { return ActsExamples::makeGsfFitterFunction( trackingGeometry, magneticField, betheHeitlerApprox, maxComponents, weightCutoff, componentMergeMethod, - mixtureReductionAlgorithm, + mixtureReductionAlgorithm, reverseFilteringCovarianceScaling, *Acts::getDefaultLogger("GSFFunc", level)); }, - py::arg("trackingGeometry"), py::arg("magneticField"), - py::arg("betheHeitlerApprox"), py::arg("maxComponents"), - py::arg("weightCutoff"), py::arg("componentMergeMethod"), - py::arg("mixtureReductionAlgorithm"), py::arg("level")); + "trackingGeometry"_a, "magneticField"_a, "betheHeitlerApprox"_a, + "maxComponents"_a, "weightCutoff"_a, "componentMergeMethod"_a, + "mixtureReductionAlgorithm"_a, "reverseFilteringCovarianceScaling"_a, + "level"_a); mex.def( "makeGlobalChiSquareFitterFunction", diff --git a/Examples/Scripts/Python/truth_tracking_kalman.py b/Examples/Scripts/Python/truth_tracking_kalman.py index 0102f1db8ee..a6ae1f6786c 100755 --- a/Examples/Scripts/Python/truth_tracking_kalman.py +++ b/Examples/Scripts/Python/truth_tracking_kalman.py @@ -18,6 +18,7 @@ def runTruthTrackingKalman( inputHitsPath: Optional[Path] = None, decorators=[], reverseFilteringMomThreshold=0 * u.GeV, + reverseFilteringCovarianceScaling=1, s: acts.examples.Sequencer = None, ): from acts.examples.simulation import ( @@ -122,6 +123,7 @@ def runTruthTrackingKalman( trackingGeometry, field, reverseFilteringMomThreshold, + reverseFilteringCovarianceScaling, ) s.addAlgorithm(