From 6e8cd689a9de7f91e4cb8bcd9dfd436d1fbfa0d6 Mon Sep 17 00:00:00 2001 From: Benjamin Huth <37871400+benjaminhuth@users.noreply.github.com> Date: Tue, 14 Nov 2023 03:16:51 +0100 Subject: [PATCH] refactor!: Consistent naming of GSF mixture reduction and component merging (#2658) This PR applies consistent naming for two similar operations on Gaussian mixtures: * *component merging* is the procedure of merge Gaussian components to a single set of parameters+covariance * *mixture reduction* is reducing the number of components in a mixture --- .../Acts/Propagator/MultiEigenStepperLoop.hpp | 1 - .../Acts/TrackFitting/GaussianSumFitter.hpp | 4 +-- .../Acts/TrackFitting/GsfMixtureReduction.hpp | 8 ++++- Core/include/Acts/TrackFitting/GsfOptions.hpp | 11 +++++-- .../Acts/TrackFitting/detail/GsfActor.hpp | 19 ++++++------ .../detail/GsfComponentMerging.hpp} | 21 +++++-------- .../detail/SymmetricKlDistanceMatrix.hpp | 2 +- .../TrackFitting/TrackFitterFunction.hpp | 19 +++++++----- .../TrackFitting/src/GsfFitterFunction.cpp | 28 +++++++++-------- .../python/acts/examples/reconstruction.py | 5 ++-- Examples/Python/src/TrackFitting.cpp | 30 ++++++++++--------- .../TrackFitting/GsfComponentMergingTests.cpp | 2 +- docs/core/reconstruction/track_fitting.md | 25 +++++++++++----- 13 files changed, 100 insertions(+), 75 deletions(-) rename Core/include/Acts/{Utilities/GaussianMixtureReduction.hpp => TrackFitting/detail/GsfComponentMerging.hpp} (94%) diff --git a/Core/include/Acts/Propagator/MultiEigenStepperLoop.hpp b/Core/include/Acts/Propagator/MultiEigenStepperLoop.hpp index 50323b77fb9..7fd4eb4766e 100644 --- a/Core/include/Acts/Propagator/MultiEigenStepperLoop.hpp +++ b/Core/include/Acts/Propagator/MultiEigenStepperLoop.hpp @@ -25,7 +25,6 @@ #include "Acts/Propagator/Propagator.hpp" #include "Acts/Propagator/detail/LoopStepperUtils.hpp" #include "Acts/Surfaces/Surface.hpp" -#include "Acts/Utilities/GaussianMixtureReduction.hpp" #include "Acts/Utilities/Intersection.hpp" #include "Acts/Utilities/Result.hpp" diff --git a/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp b/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp index d2bdb76a49d..030331650f8 100644 --- a/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp +++ b/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp @@ -449,9 +449,9 @@ struct GaussianSumFitter { if (options.referenceSurface) { const auto& params = *bwdResult->endParameters; - const auto [finalPars, finalCov] = Acts::reduceGaussianMixture( + const auto [finalPars, finalCov] = detail::mergeGaussianMixture( params.components(), params.referenceSurface(), - options.stateReductionMethod, [](auto& t) { + options.componentMergeMethod, [](auto& t) { return std::tie(std::get<0>(t), std::get<1>(t), *std::get<2>(t)); }); diff --git a/Core/include/Acts/TrackFitting/GsfMixtureReduction.hpp b/Core/include/Acts/TrackFitting/GsfMixtureReduction.hpp index 3b0a3d9704f..0624c948776 100644 --- a/Core/include/Acts/TrackFitting/GsfMixtureReduction.hpp +++ b/Core/include/Acts/TrackFitting/GsfMixtureReduction.hpp @@ -13,8 +13,14 @@ namespace Acts { +/// Greedy component reduction algorithm. Reduces the components with the +/// minimal symmetric KL-distance (applied only to the q/p-dimension) until the +/// required number of components is reached. +/// @param cmpCache the component collection +/// @param maxCmpsAfterMerge the number of components we want to reach +/// @param surface the surface type on which the components are void reduceMixtureWithKLDistance(std::vector &cmpCache, std::size_t maxCmpsAfterMerge, const Surface &surface); -} +} // namespace Acts diff --git a/Core/include/Acts/TrackFitting/GsfOptions.hpp b/Core/include/Acts/TrackFitting/GsfOptions.hpp index 9930c534d0c..0cf35fb11e6 100644 --- a/Core/include/Acts/TrackFitting/GsfOptions.hpp +++ b/Core/include/Acts/TrackFitting/GsfOptions.hpp @@ -20,6 +20,14 @@ namespace Acts { +/// @enum ComponentMergeMethod +/// +/// Available reduction methods for the reduction of a Gaussian mixture +enum class ComponentMergeMethod { eMean, eMaxWeight }; + +/// @struct GsfComponent +/// +/// Encapsulates a component of a Gaussian mixture as used by the GSF struct GsfComponent { ActsScalar weight = 0; BoundVector boundPars = BoundVector::Zero(); @@ -99,8 +107,7 @@ struct GsfOptions { std::string_view finalMultiComponentStateColumn = ""; - MixtureReductionMethod stateReductionMethod = - MixtureReductionMethod::eMaxWeight; + ComponentMergeMethod componentMergeMethod = ComponentMergeMethod::eMaxWeight; #if __cplusplus < 202002L GsfOptions() = delete; diff --git a/Core/include/Acts/TrackFitting/detail/GsfActor.hpp b/Core/include/Acts/TrackFitting/detail/GsfActor.hpp index 0ec658a0ad6..3800d3d63be 100644 --- a/Core/include/Acts/TrackFitting/detail/GsfActor.hpp +++ b/Core/include/Acts/TrackFitting/detail/GsfActor.hpp @@ -20,6 +20,7 @@ #include "Acts/TrackFitting/GsfError.hpp" #include "Acts/TrackFitting/GsfOptions.hpp" #include "Acts/TrackFitting/KalmanFitter.hpp" +#include "Acts/TrackFitting/detail/GsfComponentMerging.hpp" #include "Acts/TrackFitting/detail/GsfUtils.hpp" #include "Acts/TrackFitting/detail/KalmanUpdateHelpers.hpp" #include "Acts/Utilities/Zip.hpp" @@ -114,7 +115,7 @@ struct GsfActor { bool inReversePass = false; /// How to reduce the states that are stored in the multi trajectory - MixtureReductionMethod reductionMethod = MixtureReductionMethod::eMaxWeight; + ComponentMergeMethod mergeMethod = ComponentMergeMethod::eMaxWeight; const Logger* logger{nullptr}; @@ -714,15 +715,15 @@ struct GsfActor { proxy.setReferenceSurface(surface.getSharedPtr()); proxy.copyFrom(firstCmpProxy, mask); - auto [prtMean, prtCov] = reduceGaussianMixture( - tmpStates.tips, surface, m_cfg.reductionMethod, - PrtProjector{tmpStates.traj, tmpStates.weights}); + auto [prtMean, prtCov] = + mergeGaussianMixture(tmpStates.tips, surface, m_cfg.mergeMethod, + PrtProjector{tmpStates.traj, tmpStates.weights}); proxy.predicted() = prtMean; proxy.predictedCovariance() = prtCov; if (isMeasurement) { - auto [fltMean, fltCov] = reduceGaussianMixture( - tmpStates.tips, surface, m_cfg.reductionMethod, + auto [fltMean, fltCov] = mergeGaussianMixture( + tmpStates.tips, surface, m_cfg.mergeMethod, FltProjector{tmpStates.traj, tmpStates.weights}); proxy.filtered() = fltMean; proxy.filteredCovariance() = fltCov; @@ -744,8 +745,8 @@ struct GsfActor { result.surfacesVisitedBwdAgain.push_back(&surface); if (trackState.hasSmoothed()) { - const auto [smtMean, smtCov] = reduceGaussianMixture( - tmpStates.tips, surface, m_cfg.reductionMethod, + const auto [smtMean, smtCov] = mergeGaussianMixture( + tmpStates.tips, surface, m_cfg.mergeMethod, FltProjector{tmpStates.traj, tmpStates.weights}); trackState.smoothed() = smtMean; @@ -766,7 +767,7 @@ struct GsfActor { m_cfg.abortOnError = options.abortOnError; m_cfg.disableAllMaterialHandling = options.disableAllMaterialHandling; m_cfg.weightCutoff = options.weightCutoff; - m_cfg.reductionMethod = options.stateReductionMethod; + m_cfg.mergeMethod = options.componentMergeMethod; m_cfg.calibrationContext = &options.calibrationContext.get(); } }; diff --git a/Core/include/Acts/Utilities/GaussianMixtureReduction.hpp b/Core/include/Acts/TrackFitting/detail/GsfComponentMerging.hpp similarity index 94% rename from Core/include/Acts/Utilities/GaussianMixtureReduction.hpp rename to Core/include/Acts/TrackFitting/detail/GsfComponentMerging.hpp index 6811ebcfb14..cf5bc4bf1b0 100644 --- a/Core/include/Acts/Utilities/GaussianMixtureReduction.hpp +++ b/Core/include/Acts/TrackFitting/detail/GsfComponentMerging.hpp @@ -11,6 +11,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/TrackParametrization.hpp" #include "Acts/Surfaces/CylinderSurface.hpp" +#include "Acts/TrackFitting/GsfOptions.hpp" #include "Acts/Utilities/Identity.hpp" #include "Acts/Utilities/detail/periodic.hpp" @@ -18,8 +19,7 @@ #include #include -namespace Acts { -namespace detail { +namespace Acts::detail { /// Angle descriptions for the combineBoundGaussianMixture function template @@ -203,13 +203,6 @@ auto gaussianMixtureMeanCov(const components_t components, return RetType{mean, cov}; } -} // namespace detail - -/// @enum MixtureReductionMethod -/// -/// Available reduction methods for the reduction of a Gaussian mixture -enum class MixtureReductionMethod { eMean, eMaxWeight }; - /// Reduce Gaussian mixture /// /// @param mixture The mixture iterable @@ -220,16 +213,16 @@ enum class MixtureReductionMethod { eMean, eMaxWeight }; /// /// @return parameters and covariance as std::tuple< BoundVector, BoundMatrix > template -auto reduceGaussianMixture(const mixture_t &mixture, const Surface &surface, - MixtureReductionMethod method, - projector_t &&projector = projector_t{}) { +auto mergeGaussianMixture(const mixture_t &mixture, const Surface &surface, + ComponentMergeMethod method, + projector_t &&projector = projector_t{}) { using R = std::tuple; const auto [mean, cov] = detail::angleDescriptionSwitch(surface, [&](const auto &desc) { return detail::gaussianMixtureMeanCov(mixture, projector, desc); }); - if (method == MixtureReductionMethod::eMean) { + if (method == ComponentMergeMethod::eMean) { return R{mean, cov}; } else { const auto maxWeightIt = std::max_element( @@ -242,4 +235,4 @@ auto reduceGaussianMixture(const mixture_t &mixture, const Surface &surface, } } -} // namespace Acts +} // namespace Acts::detail diff --git a/Core/include/Acts/TrackFitting/detail/SymmetricKlDistanceMatrix.hpp b/Core/include/Acts/TrackFitting/detail/SymmetricKlDistanceMatrix.hpp index 3c511091e95..a4ab04e4ffa 100644 --- a/Core/include/Acts/TrackFitting/detail/SymmetricKlDistanceMatrix.hpp +++ b/Core/include/Acts/TrackFitting/detail/SymmetricKlDistanceMatrix.hpp @@ -11,8 +11,8 @@ #include "Acts/EventData/MultiComponentTrackParameters.hpp" #include "Acts/EventData/MultiTrajectory.hpp" #include "Acts/EventData/TrackParameters.hpp" +#include "Acts/TrackFitting/detail/GsfComponentMerging.hpp" #include "Acts/TrackFitting/detail/GsfUtils.hpp" -#include "Acts/Utilities/GaussianMixtureReduction.hpp" namespace Acts::detail { diff --git a/Examples/Algorithms/TrackFitting/include/ActsExamples/TrackFitting/TrackFitterFunction.hpp b/Examples/Algorithms/TrackFitting/include/ActsExamples/TrackFitting/TrackFitterFunction.hpp index 0e8d4957695..f126c55a918 100644 --- a/Examples/Algorithms/TrackFitting/include/ActsExamples/TrackFitting/TrackFitterFunction.hpp +++ b/Examples/Algorithms/TrackFitting/include/ActsExamples/TrackFitting/TrackFitterFunction.hpp @@ -16,9 +16,9 @@ #include "Acts/Geometry/TrackingGeometry.hpp" #include "Acts/MagneticField/MagneticFieldContext.hpp" #include "Acts/MagneticField/MagneticFieldProvider.hpp" -#include "Acts/Propagator/MultiEigenStepperLoop.hpp" #include "Acts/Propagator/Propagator.hpp" #include "Acts/TrackFitting/BetheHeitlerApprox.hpp" +#include "Acts/TrackFitting/GsfOptions.hpp" #include "Acts/Utilities/CalibrationContext.hpp" #include "ActsExamples/EventData/Measurement.hpp" #include "ActsExamples/EventData/MeasurementCalibration.hpp" @@ -74,22 +74,27 @@ std::shared_ptr makeKalmanFitterFunction( /// approximation using BetheHeitlerApprox = Acts::AtlasBetheHeitlerApprox<6, 5>; +/// Available algorithms for the mixture reduction +enum class MixtureReductionAlgorithm { KLDistance }; + /// Makes a fitter function object for the GSF /// /// @param trackingGeometry the trackingGeometry for the propagator /// @param magneticField the magnetic field for the propagator /// @param betheHeitlerApprox The object that encapsulates the approximation. /// @param maxComponents number of maximum components in the track state -/// @param abortOnError whether to call std::abort on an error -/// @param disableAllMaterialHandling run the GSF like a KF (no energy loss, -/// always 1 component, ...) +/// @param weightCutoff when to drop components +/// @param componentMergeMethod How to merge a mixture to a single set of +/// parameters and covariance +/// @param mixtureReductionAlgorithm How to reduce the number of components +/// in a mixture /// @param logger a logger instance std::shared_ptr makeGsfFitterFunction( std::shared_ptr trackingGeometry, std::shared_ptr magneticField, - BetheHeitlerApprox betheHeitlerApprox, size_t maxComponents, - double weightCutoff, Acts::MixtureReductionMethod finalReductionMethod, - bool abortOnError, bool disableAllMaterialHandling, + BetheHeitlerApprox betheHeitlerApprox, std::size_t maxComponents, + double weightCutoff, Acts::ComponentMergeMethod componentMergeMethod, + MixtureReductionAlgorithm mixtureReductionAlgorithm, 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 d71d7baffb9..b90b2e2377d 100644 --- a/Examples/Algorithms/TrackFitting/src/GsfFitterFunction.cpp +++ b/Examples/Algorithms/TrackFitting/src/GsfFitterFunction.cpp @@ -24,7 +24,6 @@ #include "Acts/TrackFitting/GsfMixtureReduction.hpp" #include "Acts/TrackFitting/GsfOptions.hpp" #include "Acts/Utilities/Delegate.hpp" -#include "Acts/Utilities/GaussianMixtureReduction.hpp" #include "Acts/Utilities/HashedString.hpp" #include "Acts/Utilities/Intersection.hpp" #include "Acts/Utilities/Logger.hpp" @@ -81,8 +80,10 @@ struct GsfFitterFunctionImpl final : public ActsExamples::TrackFitterFunction { double weightCutoff = 0; bool abortOnError = false; bool disableAllMaterialHandling = false; - Acts::MixtureReductionMethod reductionMethod = - Acts::MixtureReductionMethod::eMaxWeight; + MixtureReductionAlgorithm reductionAlg = + MixtureReductionAlgorithm::KLDistance; + Acts::ComponentMergeMethod mergeMethod = + Acts::ComponentMergeMethod::eMaxWeight; IndexSourceLink::SurfaceAccessor m_slSurfaceAccessor; @@ -111,15 +112,19 @@ struct GsfFitterFunctionImpl final : public ActsExamples::TrackFitterFunction { weightCutoff, abortOnError, disableAllMaterialHandling}; - gsfOptions.stateReductionMethod = reductionMethod; + gsfOptions.componentMergeMethod = mergeMethod; gsfOptions.extensions.calibrator.connect<&calibrator_t::calibrate>( &calibrator); gsfOptions.extensions.surfaceAccessor .connect<&IndexSourceLink::SurfaceAccessor::operator()>( &m_slSurfaceAccessor); - gsfOptions.extensions.mixtureReducer - .connect<&Acts::reduceMixtureWithKLDistance>(); + switch (reductionAlg) { + case MixtureReductionAlgorithm::KLDistance: { + gsfOptions.extensions.mixtureReducer + .connect<&Acts::reduceMixtureWithKLDistance>(); + } break; + } return gsfOptions; } @@ -167,9 +172,9 @@ struct GsfFitterFunctionImpl final : public ActsExamples::TrackFitterFunction { std::shared_ptr ActsExamples::makeGsfFitterFunction( std::shared_ptr trackingGeometry, std::shared_ptr magneticField, - BetheHeitlerApprox betheHeitlerApprox, size_t maxComponents, - double weightCutoff, Acts::MixtureReductionMethod finalReductionMethod, - bool abortOnError, bool disableAllMaterialHandling, + BetheHeitlerApprox betheHeitlerApprox, std::size_t maxComponents, + double weightCutoff, Acts::ComponentMergeMethod componentMergeMethod, + MixtureReductionAlgorithm mixtureReductionAlgorithm, const Acts::Logger& logger) { // Standard fitter MultiStepper stepper(magneticField, logger.cloneWithSuffix("Step")); @@ -202,9 +207,8 @@ std::shared_ptr ActsExamples::makeGsfFitterFunction( std::move(trackFitter), std::move(directTrackFitter), geo); fitterFunction->maxComponents = maxComponents; fitterFunction->weightCutoff = weightCutoff; - fitterFunction->abortOnError = abortOnError; - fitterFunction->disableAllMaterialHandling = disableAllMaterialHandling; - fitterFunction->reductionMethod = finalReductionMethod; + fitterFunction->mergeMethod = componentMergeMethod; + fitterFunction->reductionAlg = mixtureReductionAlgorithm; return fitterFunction; } diff --git a/Examples/Python/python/acts/examples/reconstruction.py b/Examples/Python/python/acts/examples/reconstruction.py index 36b311a6781..8dbda185a9d 100644 --- a/Examples/Python/python/acts/examples/reconstruction.py +++ b/Examples/Python/python/acts/examples/reconstruction.py @@ -981,9 +981,8 @@ def addTruthTrackingGsf( gsfOptions = { "betheHeitlerApprox": acts.examples.AtlasBetheHeitlerApprox.makeDefault(), "maxComponents": 12, - "abortOnError": False, - "disableAllMaterialHandling": False, - "finalReductionMethod": acts.examples.FinalReductionMethod.maxWeight, + "componentMergeMethod": acts.examples.ComponentMergeMethod.maxWeight, + "mixtureReductionAlgorithm": acts.examples.MixtureReductionAlgorithm.KLDistance, "weightCutoff": 1.0e-4, "level": customLogLevel(), } diff --git a/Examples/Python/src/TrackFitting.cpp b/Examples/Python/src/TrackFitting.cpp index cdba4a4cb0c..4fc7ac46f44 100644 --- a/Examples/Python/src/TrackFitting.cpp +++ b/Examples/Python/src/TrackFitting.cpp @@ -10,7 +10,7 @@ #include "Acts/EventData/detail/CorrectedTransformationFreeToBound.hpp" #include "Acts/Plugins/Python/Utilities.hpp" #include "Acts/TrackFitting/BetheHeitlerApprox.hpp" -#include "Acts/Utilities/GaussianMixtureReduction.hpp" +#include "Acts/TrackFitting/GsfOptions.hpp" #include "Acts/Utilities/Logger.hpp" #include "ActsExamples/EventData/Cluster.hpp" #include "ActsExamples/EventData/MeasurementCalibration.hpp" @@ -97,9 +97,13 @@ void addTrackFitting(Context& ctx) { }, py::arg("path")); - py::enum_(mex, "FinalReductionMethod") - .value("mean", Acts::MixtureReductionMethod::eMean) - .value("maxWeight", Acts::MixtureReductionMethod::eMaxWeight); + py::enum_(mex, "ComponentMergeMethod") + .value("mean", Acts::ComponentMergeMethod::eMean) + .value("maxWeight", Acts::ComponentMergeMethod::eMaxWeight); + + py::enum_( + mex, "MixtureReductionAlgorithm") + .value("KLDistance", MixtureReductionAlgorithm::KLDistance); py::class_(mex, "AtlasBetheHeitlerApprox") .def_static("loadFromFiles", @@ -107,26 +111,24 @@ void addTrackFitting(Context& ctx) { py::arg("lowParametersPath"), py::arg("lowParametersPath")) .def_static("makeDefault", []() { return Acts::makeDefaultBetheHeitlerApprox(); }); - mex.def( "makeGsfFitterFunction", [](std::shared_ptr trackingGeometry, std::shared_ptr magneticField, - BetheHeitlerApprox betheHeitlerApprox, size_t maxComponents, - double weightCutoff, - Acts::MixtureReductionMethod finalReductionMethod, bool abortOnError, - bool disableAllMaterialHandling, Logging::Level level) { + BetheHeitlerApprox betheHeitlerApprox, std::size_t maxComponents, + double weightCutoff, Acts::ComponentMergeMethod componentMergeMethod, + ActsExamples::MixtureReductionAlgorithm mixtureReductionAlgorithm, + Logging::Level level) { return ActsExamples::makeGsfFitterFunction( trackingGeometry, magneticField, betheHeitlerApprox, - maxComponents, weightCutoff, finalReductionMethod, abortOnError, - disableAllMaterialHandling, + maxComponents, weightCutoff, componentMergeMethod, + mixtureReductionAlgorithm, *Acts::getDefaultLogger("GSFFunc", level)); }, py::arg("trackingGeometry"), py::arg("magneticField"), py::arg("betheHeitlerApprox"), py::arg("maxComponents"), - py::arg("weightCutoff"), py::arg("finalReductionMethod"), - py::arg("abortOnError"), py::arg("disableAllMaterialHandling"), - py::arg("level")); + py::arg("weightCutoff"), py::arg("componentMergeMethod"), + py::arg("mixtureReductionAlgorithm"), py::arg("level")); mex.def( "makeGlobalChiSquareFitterFunction", diff --git a/Tests/UnitTests/Core/TrackFitting/GsfComponentMergingTests.cpp b/Tests/UnitTests/Core/TrackFitting/GsfComponentMergingTests.cpp index 12b2c9cd746..ddac64213f4 100644 --- a/Tests/UnitTests/Core/TrackFitting/GsfComponentMergingTests.cpp +++ b/Tests/UnitTests/Core/TrackFitting/GsfComponentMergingTests.cpp @@ -21,7 +21,7 @@ #include "Acts/Surfaces/PlaneSurface.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Surfaces/SurfaceBounds.hpp" -#include "Acts/Utilities/GaussianMixtureReduction.hpp" +#include "Acts/TrackFitting/detail/GsfComponentMerging.hpp" #include "Acts/Utilities/Identity.hpp" #include "Acts/Utilities/Intersection.hpp" #include "Acts/Utilities/Result.hpp" diff --git a/docs/core/reconstruction/track_fitting.md b/docs/core/reconstruction/track_fitting.md index 9520d20297a..59a627c993f 100644 --- a/docs/core/reconstruction/track_fitting.md +++ b/docs/core/reconstruction/track_fitting.md @@ -67,12 +67,6 @@ Simplified overview of the GSF algorithm. ### The Multi-Stepper To implement the GSF, a special stepper is needed, that can handle a multi-component state internally: The {class}`Acts::MultiEigenStepperLoop`, which is based on the {class}`Acts::EigenStepper` and thus shares a lot of code with it. It interfaces to the navigation as one aggregate state to limit the navigation overhead, but internally processes a multi-component state. How this aggregation is performed can be configured via a template parameter, by default weighted average is used ({struct}`Acts::WeightedComponentReducerLoop`). -At the end of the fit the multi-component state must be reduced to a single set of parameters with a corresponding covariance matrix. This is supported by the {class}`Acts::MultiEigenStepperLoop` in two different ways currently: The *mean* method computes the mean and the covariance matrix of the multi-component state, whereas the *maximum weight* method just returns the component with the maximum weight. This can be configured in the constructor of the {class}`Acts::MultiEigenStepperLoop` with the {enum}`Acts::MixtureReductionMethod`. In the future there is planned to add a *mode* finding method as well. - -:::{note} -In practice it turned out that the *maximum weight* method leads to better results so far. -::: - Even though the multi-stepper interface exposes only one aggregate state and thus is compatible with most standard tools, there is a special aborter is required to stop the navigation when the surface is reached, the {struct}`Acts::MultiStepperSurfaceReached`. It checks if all components have reached the target surface already and updates their state accordingly. Optionally, it also can stop the propagation when the aggregate state reaches the surface. @@ -87,9 +81,24 @@ outline: --- ``` -The fit can be customized with several options, e.g., the maximum number of components. All options can be found in the {struct}`Acts::GsfOptions`. +The fit can be customized with several options. Important ones are: +* *maximum components*: How many components at maximum should be kept. +* *weight cut*: When to drop components. +* *component merging*: How a multi-component state is reduced to a single set of parameters and covariance. The method can be chosen with the enum {enum}`Acts::ComponentMergeMethod`. Two methods are supported currently: + * The *mean* computes the mean and the covariance of the mean. + * *max weight* takes the parameters of component with the maximum weight and computes the variance around these. This is a cheap approximation of the mode, which is not implemented currently. + +:::{note} +A good starting configuration is to use 12 components, the *max weight* merging and the *KL distance* reduction. +::: + +All options can be found in the {struct}`Acts::GsfOptions`: -To simplify integration, the GSF returns an {struct}`Acts::KalmanFitterResult` object, the same as the {class}`Acts::KalmanFitter`. This allows to use the same analysis tools for both fitters. +```{doxygenstruct} Acts::GsfOptions +--- +outline: +--- +``` If the GSF finds the column with the string identifier *"gsf-final-multi-component-state"* (defined in `Acts::GsfConstants::kFinalMultiComponentStateColumn`) in the track container, it adds the final multi-component state to the track as a `std::optional>` object.