Skip to content

Commit

Permalink
refactor!: Consistent naming of GSF mixture reduction and component m…
Browse files Browse the repository at this point in the history
…erging (#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
  • Loading branch information
benjaminhuth authored Nov 14, 2023
1 parent cc29c08 commit 6e8cd68
Show file tree
Hide file tree
Showing 13 changed files with 100 additions and 75 deletions.
1 change: 0 additions & 1 deletion Core/include/Acts/Propagator/MultiEigenStepperLoop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
4 changes: 2 additions & 2 deletions Core/include/Acts/TrackFitting/GaussianSumFitter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
});

Expand Down
8 changes: 7 additions & 1 deletion Core/include/Acts/TrackFitting/GsfMixtureReduction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<GsfComponent> &cmpCache,
std::size_t maxCmpsAfterMerge,
const Surface &surface);

}
} // namespace Acts
11 changes: 9 additions & 2 deletions Core/include/Acts/TrackFitting/GsfOptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -99,8 +107,7 @@ struct GsfOptions {

std::string_view finalMultiComponentStateColumn = "";

MixtureReductionMethod stateReductionMethod =
MixtureReductionMethod::eMaxWeight;
ComponentMergeMethod componentMergeMethod = ComponentMergeMethod::eMaxWeight;

#if __cplusplus < 202002L
GsfOptions() = delete;
Expand Down
19 changes: 10 additions & 9 deletions Core/include/Acts/TrackFitting/detail/GsfActor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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};

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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();
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
#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"

#include <cmath>
#include <optional>
#include <tuple>

namespace Acts {
namespace detail {
namespace Acts::detail {

/// Angle descriptions for the combineBoundGaussianMixture function
template <BoundIndices Idx>
Expand Down Expand Up @@ -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
Expand All @@ -220,16 +213,16 @@ enum class MixtureReductionMethod { eMean, eMaxWeight };
///
/// @return parameters and covariance as std::tuple< BoundVector, BoundMatrix >
template <typename mixture_t, typename projector_t = Acts::Identity>
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<Acts::BoundVector, Acts::BoundSquareMatrix>;
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(
Expand All @@ -242,4 +235,4 @@ auto reduceGaussianMixture(const mixture_t &mixture, const Surface &surface,
}
}

} // namespace Acts
} // namespace Acts::detail
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -74,22 +74,27 @@ std::shared_ptr<TrackFitterFunction> 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<TrackFitterFunction> makeGsfFitterFunction(
std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry,
std::shared_ptr<const Acts::MagneticFieldProvider> 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)
Expand Down
28 changes: 16 additions & 12 deletions Examples/Algorithms/TrackFitting/src/GsfFitterFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -167,9 +172,9 @@ struct GsfFitterFunctionImpl final : public ActsExamples::TrackFitterFunction {
std::shared_ptr<TrackFitterFunction> ActsExamples::makeGsfFitterFunction(
std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry,
std::shared_ptr<const Acts::MagneticFieldProvider> 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"));
Expand Down Expand Up @@ -202,9 +207,8 @@ std::shared_ptr<TrackFitterFunction> 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;
}
5 changes: 2 additions & 3 deletions Examples/Python/python/acts/examples/reconstruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
}
Expand Down
30 changes: 16 additions & 14 deletions Examples/Python/src/TrackFitting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -97,36 +97,38 @@ void addTrackFitting(Context& ctx) {
},
py::arg("path"));

py::enum_<Acts::MixtureReductionMethod>(mex, "FinalReductionMethod")
.value("mean", Acts::MixtureReductionMethod::eMean)
.value("maxWeight", Acts::MixtureReductionMethod::eMaxWeight);
py::enum_<Acts::ComponentMergeMethod>(mex, "ComponentMergeMethod")
.value("mean", Acts::ComponentMergeMethod::eMean)
.value("maxWeight", Acts::ComponentMergeMethod::eMaxWeight);

py::enum_<ActsExamples::MixtureReductionAlgorithm>(
mex, "MixtureReductionAlgorithm")
.value("KLDistance", MixtureReductionAlgorithm::KLDistance);

py::class_<ActsExamples::BetheHeitlerApprox>(mex, "AtlasBetheHeitlerApprox")
.def_static("loadFromFiles",
&ActsExamples::BetheHeitlerApprox::loadFromFiles,
py::arg("lowParametersPath"), py::arg("lowParametersPath"))
.def_static("makeDefault",
[]() { return Acts::makeDefaultBetheHeitlerApprox(); });

mex.def(
"makeGsfFitterFunction",
[](std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry,
std::shared_ptr<const Acts::MagneticFieldProvider> 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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Loading

0 comments on commit 6e8cd68

Please sign in to comment.