Skip to content

Commit

Permalink
feat: Move GSF out of namespace Experimental (#2479)
Browse files Browse the repository at this point in the history
The GSF has proven to be reasonably stable the last months, so I think we can put it into the main `Acts` namespace.
  • Loading branch information
benjaminhuth authored Sep 26, 2023
1 parent 40e5cf9 commit 2b922b0
Show file tree
Hide file tree
Showing 15 changed files with 36 additions and 62 deletions.
3 changes: 0 additions & 3 deletions Core/include/Acts/TrackFitting/BetheHeitlerApprox.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ inline auto inverseTransformComponent(double transformed_weight,

} // namespace detail

namespace Experimental {

/// This class approximates the Bethe-Heitler with only one component. This is
/// mainly inside @ref AtlasBetheHeitlerApprox, but can also be used as the
/// only component approximation (then probably for debugging)
Expand Down Expand Up @@ -283,5 +281,4 @@ class AtlasBetheHeitlerApprox {
/// the GSF without the need to load files
AtlasBetheHeitlerApprox<6, 5> makeDefaultBetheHeitlerApprox();

} // namespace Experimental
} // namespace Acts
3 changes: 0 additions & 3 deletions Core/include/Acts/TrackFitting/GaussianSumFitter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ struct IsMultiComponentBoundParameters<MultiComponentBoundTrackParameters>

} // namespace detail

namespace Experimental {

/// Gaussian Sum Fitter implementation.
/// @tparam propagator_t The propagator type on which the algorithm is built on
/// @tparam bethe_heitler_approx_t The type of the Bethe-Heitler-Approximation
Expand Down Expand Up @@ -472,5 +470,4 @@ struct GaussianSumFitter {
}
};

} // namespace Experimental
} // namespace Acts
4 changes: 1 addition & 3 deletions Core/include/Acts/TrackFitting/GsfError.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include <type_traits>

namespace Acts {
namespace Experimental {

enum class GsfError {
StartParametersNotOnStartSurface = 1,
Expand All @@ -24,11 +23,10 @@ enum class GsfError {

std::error_code make_error_code(GsfError e);

} // namespace Experimental
} // namespace Acts

// register with STL
namespace std {
template <>
struct is_error_code_enum<Acts::Experimental::GsfError> : std::true_type {};
struct is_error_code_enum<Acts::GsfError> : std::true_type {};
} // namespace std
6 changes: 3 additions & 3 deletions Core/include/Acts/TrackFitting/GsfMixtureReduction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

namespace Acts {

void reduceMixtureWithKLDistance(
std::vector<Acts::Experimental::GsfComponent> &cmpCache,
std::size_t maxCmpsAfterMerge, const Surface &surface);
void reduceMixtureWithKLDistance(std::vector<GsfComponent> &cmpCache,
std::size_t maxCmpsAfterMerge,
const Surface &surface);

}
3 changes: 0 additions & 3 deletions Core/include/Acts/TrackFitting/GsfOptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@

namespace Acts {

namespace Experimental {

struct GsfComponent {
ActsScalar weight = 0;
BoundVector boundPars = BoundVector::Zero();
Expand Down Expand Up @@ -109,5 +107,4 @@ struct GsfOptions {
#endif
};

} // namespace Experimental
} // namespace Acts
10 changes: 5 additions & 5 deletions Core/include/Acts/TrackFitting/detail/GsfActor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ struct GsfResult {
Result<void> result{Result<void>::success()};

// Internal: component cache to avoid reallocation
std::vector<Acts::Experimental::GsfComponent> componentCache;
std::vector<GsfComponent> componentCache;
};

/// The actor carrying out the GSF algorithm
Expand All @@ -70,7 +70,7 @@ struct GsfActor {
/// Enforce default construction
GsfActor() = default;

using ComponentCache = Acts::Experimental::GsfComponent;
using ComponentCache = Acts::GsfComponent;

/// Broadcast the result_type
using result_type = GsfResult<traj_t>;
Expand Down Expand Up @@ -106,7 +106,7 @@ struct GsfActor {
std::optional<std::size_t> numberMeasurements;

/// The extensions
Experimental::GsfExtensions<traj_t> extensions;
GsfExtensions<traj_t> extensions;

/// Whether we are in the reverse pass or not. This is more reliable than
/// checking the navigation direction, because in principle the fitter can
Expand Down Expand Up @@ -760,7 +760,7 @@ struct GsfActor {

/// Set the relevant options that can be set from the Options struct all in
/// one place
void setOptions(const Acts::Experimental::GsfOptions<traj_t>& options) {
void setOptions(const Acts::GsfOptions<traj_t>& options) {
m_cfg.maxComponents = options.maxComponents;
m_cfg.extensions = options.extensions;
m_cfg.abortOnError = options.abortOnError;
Expand All @@ -774,7 +774,7 @@ struct GsfActor {
/// An actor that collects the final multi component state once the propagation
/// finished
struct FinalStateCollector {
using MultiPars = Acts::Experimental::GsfConstants::FinalMultiComponentState;
using MultiPars = Acts::GsfConstants::FinalMultiComponentState;

struct result_type {
MultiPars pars;
Expand Down
6 changes: 1 addition & 5 deletions Core/src/TrackFitting/BetheHeitlerApprox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@

#include "Acts/TrackFitting/BetheHeitlerApprox.hpp"

namespace Acts::Experimental {

AtlasBetheHeitlerApprox<6, 5> makeDefaultBetheHeitlerApprox() {
Acts::AtlasBetheHeitlerApprox<6, 5> Acts::makeDefaultBetheHeitlerApprox() {
// Tracking/TrkFitter/TrkGaussianSumFilterUtils/Data/BetheHeitler_cdf_nC6_O5.par
// clang-format off
constexpr static AtlasBetheHeitlerApprox<6, 5>::Data cdf_cmps6_order5_data = {{
Expand Down Expand Up @@ -56,5 +54,3 @@ AtlasBetheHeitlerApprox<6, 5> makeDefaultBetheHeitlerApprox() {
return AtlasBetheHeitlerApprox<6, 5>(cdf_cmps6_order5_data,
cdf_cmps6_order5_data, true, true);
}

} // namespace Acts::Experimental
5 changes: 2 additions & 3 deletions Core/src/TrackFitting/GsfError.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class GsfErrorCategory : public std::error_category {

// Return what each enum means in text.
std::string message(int c) const final {
using Acts::Experimental::GsfError;
using Acts::GsfError;

switch (static_cast<GsfError>(c)) {
case GsfError::StartParametersHaveNoCovariance:
Expand All @@ -40,8 +40,7 @@ class GsfErrorCategory : public std::error_category {

} // namespace

std::error_code Acts::Experimental::make_error_code(
Acts::Experimental::GsfError e) {
std::error_code Acts::make_error_code(Acts::GsfError e) {
static GsfErrorCategory c;
return {static_cast<int>(e), c};
}
13 changes: 6 additions & 7 deletions Core/src/TrackFitting/GsfMixtureReduction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@
#include "Acts/TrackFitting/detail/SymmetricKlDistanceMatrix.hpp"

template <typename proj_t, typename angle_desc_t>
void reduceWithKLDistanceImpl(
std::vector<Acts::Experimental::GsfComponent> &cmpCache,
std::size_t maxCmpsAfterMerge, const proj_t &proj,
const angle_desc_t &desc) {
void reduceWithKLDistanceImpl(std::vector<Acts::GsfComponent> &cmpCache,
std::size_t maxCmpsAfterMerge, const proj_t &proj,
const angle_desc_t &desc) {
Acts::detail::SymmetricKLDistanceMatrix distances(cmpCache, proj);

auto remainingComponents = cmpCache.size();
Expand Down Expand Up @@ -50,9 +49,9 @@ void reduceWithKLDistanceImpl(

namespace Acts {

void reduceMixtureWithKLDistance(
std::vector<Acts::Experimental::GsfComponent> &cmpCache,
std::size_t maxCmpsAfterMerge, const Surface &surface) {
void reduceMixtureWithKLDistance(std::vector<Acts::GsfComponent> &cmpCache,
std::size_t maxCmpsAfterMerge,
const Surface &surface) {
if (cmpCache.size() <= maxCmpsAfterMerge) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ std::shared_ptr<TrackFitterFunction> makeKalmanFitterFunction(

/// This type is used in the Examples framework for the Bethe-Heitler
/// approximation
using BetheHeitlerApprox = Acts::Experimental::AtlasBetheHeitlerApprox<6, 5>;
using BetheHeitlerApprox = Acts::AtlasBetheHeitlerApprox<6, 5>;

/// Makes a fitter function object for the GSF
///
Expand Down
17 changes: 8 additions & 9 deletions Examples/Algorithms/TrackFitting/src/GsfFitterFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,11 @@ using MultiStepper = Acts::MultiEigenStepperLoop<>;
using Propagator = Acts::Propagator<MultiStepper, Acts::Navigator>;
using DirectPropagator = Acts::Propagator<MultiStepper, Acts::DirectNavigator>;

using Fitter =
Acts::Experimental::GaussianSumFitter<Propagator, BetheHeitlerApprox,
Acts::VectorMultiTrajectory>;
using Fitter = Acts::GaussianSumFitter<Propagator, BetheHeitlerApprox,
Acts::VectorMultiTrajectory>;
using DirectFitter =
Acts::Experimental::GaussianSumFitter<DirectPropagator, BetheHeitlerApprox,
Acts::VectorMultiTrajectory>;
Acts::GaussianSumFitter<DirectPropagator, BetheHeitlerApprox,
Acts::VectorMultiTrajectory>;
using TrackContainer =
Acts::TrackContainer<Acts::VectorTrackContainer,
Acts::VectorMultiTrajectory, std::shared_ptr>;
Expand Down Expand Up @@ -96,12 +95,12 @@ struct GsfFitterFunctionImpl final : public ActsExamples::TrackFitterFunction {
template <typename calibrator_t>
auto makeGsfOptions(const GeneralFitterOptions& options,
const calibrator_t& calibrator) const {
Acts::Experimental::GsfExtensions<Acts::VectorMultiTrajectory> extensions;
Acts::GsfExtensions<Acts::VectorMultiTrajectory> extensions;
extensions.updater.connect<
&Acts::GainMatrixUpdater::operator()<Acts::VectorMultiTrajectory>>(
&updater);

Acts::Experimental::GsfOptions<Acts::VectorMultiTrajectory> gsfOptions{
Acts::GsfOptions<Acts::VectorMultiTrajectory> gsfOptions{
options.geoContext,
options.magFieldContext,
options.calibrationContext,
Expand Down Expand Up @@ -131,7 +130,7 @@ struct GsfFitterFunctionImpl final : public ActsExamples::TrackFitterFunction {
TrackContainer& tracks) const override {
const auto gsfOptions = makeGsfOptions(options, calibrator);

using namespace Acts::Experimental::GsfConstants;
using namespace Acts::GsfConstants;
if (not tracks.hasColumn(
Acts::hashString(kFinalMultiComponentStateColumn))) {
std::string key(kFinalMultiComponentStateColumn);
Expand All @@ -151,7 +150,7 @@ struct GsfFitterFunctionImpl final : public ActsExamples::TrackFitterFunction {
TrackContainer& tracks) const override {
const auto gsfOptions = makeGsfOptions(options, calibrator);

using namespace Acts::Experimental::GsfConstants;
using namespace Acts::GsfConstants;
if (not tracks.hasColumn(
Acts::hashString(kFinalMultiComponentStateColumn))) {
std::string key(kFinalMultiComponentStateColumn);
Expand Down
5 changes: 2 additions & 3 deletions Examples/Python/src/TrackFitting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,8 @@ void addTrackFitting(Context& ctx) {
.def_static("loadFromFiles",
&ActsExamples::BetheHeitlerApprox::loadFromFiles,
py::arg("lowParametersPath"), py::arg("lowParametersPath"))
.def_static("makeDefault", []() {
return Acts::Experimental::makeDefaultBetheHeitlerApprox();
});
.def_static("makeDefault",
[]() { return Acts::makeDefaultBetheHeitlerApprox(); });

mex.def(
"makeGsfFitterFunction",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
#include <vector>

using namespace Acts;
using namespace Acts::Experimental;
using namespace Acts::UnitLiterals;

BOOST_AUTO_TEST_CASE(test_distance_matrix_min_distance) {
std::vector<GsfComponent> cmps = {
Expand Down
3 changes: 1 addition & 2 deletions Tests/UnitTests/Core/TrackFitting/GsfTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ namespace {
using namespace Acts;
using namespace Acts::Test;
using namespace Acts::UnitLiterals;
using namespace Acts::Experimental;

static const auto electron = ParticleHypothesis::electron();

Expand Down Expand Up @@ -224,7 +223,7 @@ BOOST_AUTO_TEST_CASE(ZeroFieldWithOutliers) {
BOOST_AUTO_TEST_CASE(WithFinalMultiComponentState) {
Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
Acts::VectorMultiTrajectory{}};
using namespace Acts::Experimental::GsfConstants;
using namespace Acts::GsfConstants;
std::string key(kFinalMultiComponentStateColumn);
tracks.template addColumn<FinalMultiComponentState>(key);

Expand Down
16 changes: 6 additions & 10 deletions docs/core/track_fitting.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ This chapter will be extended in the future.
(gsf_core)=
## Gaussian Sum Filter (GSF)

:::{note}
The GSF is not considered as production ready yet, therefore it is located in the namespace `Acts::Experimental`.
:::

The GSF is an extension of the Kalman-Filter that allows to handle non-gaussian errors by modelling the track state as a gaussian mixture:

$$
Expand Down Expand Up @@ -82,9 +78,9 @@ Even though the multi-stepper interface exposes only one aggregate state and thu

### Using the GSF

The GSF is implemented in the class {class}`Acts::Experimental::GaussianSumFitter`. The interface of its `fit(...)`-functions is very similar to the one of the {class}`Acts::KalmanFitter` (one for the standard {class}`Acts::Navigator` and one for the {class}`Acts::DirectNavigator` that takes an additional `std::vector<const Acts::Surface *>` as an argument):
The GSF is implemented in the class {class}`Acts::GaussianSumFitter`. The interface of its `fit(...)`-functions is very similar to the one of the {class}`Acts::KalmanFitter` (one for the standard {class}`Acts::Navigator` and one for the {class}`Acts::DirectNavigator` that takes an additional `std::vector<const Acts::Surface *>` as an argument):

```{doxygenstruct} Acts::Experimental::GaussianSumFitter
```{doxygenstruct} Acts::GaussianSumFitter
---
members: fit
outline:
Expand All @@ -95,17 +91,17 @@ The fit can be customized with several options, e.g., the maximum number of comp

To simplify integration, the GSF returns an {class}`Acts::KalmanFitterResult` object, the same as the {class}`Acts::KalmanFitter`. This allows to use the same analysis tools for both fitters.

If the GSF finds the column with the string identifier *"gsf-final-multi-component-state"* (defined in `Acts::Experimental::GsfConstants::kFinalMultiComponentStateColumn`) in the track container, it adds the final multi-component state to the track as a `std::optional<Acts::MultiComponentBoundTrackParameters<SinglyCharged>>` object.
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<Acts::MultiComponentBoundTrackParameters<SinglyCharged>>` object.

A GSF example can be found in the Acts Examples Framework [here](https://github.com/acts-project/acts/blob/main/Examples/Scripts/Python/truth_tracking_gsf.py).

### Customising the Bethe-Heitler approximation

The GSF needs an approximation of the Bethe-Heitler distribution as a Gaussian mixture on each material interaction (see above). This task is delegated to a separate class, that can be provided by a template parameter to {class}`Acts::Experimental::GaussianSumFitter`, so in principle it can be implemented in different ways.
The GSF needs an approximation of the Bethe-Heitler distribution as a Gaussian mixture on each material interaction (see above). This task is delegated to a separate class, that can be provided by a template parameter to {class}`Acts::GaussianSumFitter`, so in principle it can be implemented in different ways.

However, ACTS ships with the class {class}`Acts::Experimental::AtlasBetheHeitlerApprox` that implements the ATLAS strategy for this task: To be able to evaluate the approximation of the Bethe-Heitler distribution for different materials and thicknesses, the individual Gaussian components (weight, mean, variance of the ratio $E_f/E_i$) are parametrised as polynomials in $x/x_0$. This class can load files in the ATLAS format that can be found [here](https://gitlab.cern.ch/atlas/athena/-/tree/master/Tracking/TrkFitter/TrkGaussianSumFilter/Data). A default parameterization can be created with {func}`Acts::Experimental::makeDefaultBetheHeitlerApprox`.
However, ACTS ships with the class {class}`Acts::AtlasBetheHeitlerApprox` that implements the ATLAS strategy for this task: To be able to evaluate the approximation of the Bethe-Heitler distribution for different materials and thicknesses, the individual Gaussian components (weight, mean, variance of the ratio $E_f/E_i$) are parametrised as polynomials in $x/x_0$. This class can load files in the ATLAS format that can be found [here](https://gitlab.cern.ch/atlas/athena/-/tree/master/Tracking/TrkFitter/TrkGaussianSumFilter/Data). A default parameterization can be created with {func}`Acts::makeDefaultBetheHeitlerApprox`.

The {class}`Acts::Experimental::AtlasBetheHeitlerApprox` is constructed with two parameterizations, allowing to use different parameterizations for different $x/x_0$. In particular, it has this behaviour:
The {class}`Acts::AtlasBetheHeitlerApprox` is constructed with two parameterizations, allowing to use different parameterizations for different $x/x_0$. In particular, it has this behaviour:
* $x/x_0 < 0.0001$: Return no change
* $x/x_0 < 0.002$: Return a single gaussian approximation
* $x/x_0 < 0.1$: Return the approximation for low $x/x_0$.
Expand Down

0 comments on commit 2b922b0

Please sign in to comment.