Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 56 additions & 26 deletions Core/include/Acts/Propagator/MultiStepperLoop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "Acts/Propagator/detail/LoopStepperUtils.hpp"
#include "Acts/Propagator/detail/SteppingHelper.hpp"
#include "Acts/Surfaces/Surface.hpp"
#include "Acts/TrackFitting/GsfOptions.hpp"
#include "Acts/Utilities/Intersection.hpp"
#include "Acts/Utilities/Logger.hpp"
#include "Acts/Utilities/Result.hpp"
Expand All @@ -31,7 +32,6 @@
#include <cstddef>
#include <limits>
#include <sstream>
#include <vector>

#include <boost/container/small_vector.hpp>

Expand Down Expand Up @@ -132,7 +132,7 @@
/// component
template <Concepts::SingleStepper single_stepper_t,
typename component_reducer_t = MaxWeightReducerLoop>
class MultiStepperLoop final {

Check warning on line 135 in Core/include/Acts/Propagator/MultiStepperLoop.hpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Class has 36 methods, which is greater than the 35 authorized. Split it into smaller classes.

See more on https://sonarcloud.io/project/issues?id=acts-project_acts&issues=AZyfY0BkFxSSdjftZXY4&open=AZyfY0BkFxSSdjftZXY4&pullRequest=5139
/// Single stepper instance
single_stepper_t m_singleStepper;

Expand Down Expand Up @@ -165,8 +165,10 @@
using Jacobian = BoundMatrix;
/// Type alias for covariance matrix
using Covariance = BoundMatrix;
/// Bound state tuple containing parameters, Jacobian, and path length
using BoundState =
/// Single component bound state definition
using BoundState = std::tuple<BoundTrackParameters, Jacobian, double>;
/// Multi-component bound state definition
using MultiBoundState =
std::tuple<MultiComponentBoundTrackParameters, Jacobian, double>;

/// @brief The reducer type
Expand All @@ -184,6 +186,9 @@

struct Options : public SingleOptions {
using SingleOptions::SingleOptions;

ComponentMergeMethod componentMergeMethod =
ComponentMergeMethod::eMaxWeight;
};

/// State container for multi-component stepping.
Expand Down Expand Up @@ -269,33 +274,16 @@
return state;
}

/// Initialize the stepper state from bound track parameters
/// @param state Stepper state to initialize
/// @param par Bound track parameters to initialize from
void initialize(State& state, const BoundTrackParameters& par) const;

/// Initialize the stepper state from multi-component bound track parameters
/// @param state The stepper state to initialize
/// @param par The multi-component bound track parameters
void initialize(State& state,
const MultiComponentBoundTrackParameters& par) const {
if (par.components().empty()) {
throw std::invalid_argument(
"Cannot construct MultiEigenStepperLoop::State with empty "
"multi-component parameters");
}

state.particleHypothesis = par.particleHypothesis();

const auto surface = par.referenceSurface().getSharedPtr();

for (auto i = 0ul; i < par.components().size(); ++i) {
const auto& [weight, singlePars] = par[i];
auto& cmp = state.components.emplace_back(
m_singleStepper.makeState(state.options), weight,
IntersectionStatus::onSurface);
m_singleStepper.initialize(cmp.state, singlePars);
}

if (std::get<2>(par.components().front())) {
state.covTransport = true;
}
}
const MultiComponentBoundTrackParameters& par) const;

/// A proxy struct which allows access to a single component of the
/// multi-component state. It has the semantics of a const reference, i.e.
Expand Down Expand Up @@ -703,6 +691,31 @@
const FreeToBoundCorrection& freeToBoundCorrection =
FreeToBoundCorrection(false)) const;

/// Create and return the bound state at the current position
///
/// @brief This transports (if necessary) the covariance
/// to the surface and creates a bound state. It does not check
/// if the transported state is at the surface, this needs to
/// be guaranteed by the propagator.
/// @note This is done by combining the gaussian mixture on the specified
/// surface. If the conversion to bound states of some components
/// fails, these components are ignored unless all components fail. In this
/// case an error code is returned.
///
/// @param [in] state State that will be presented as @c BoundState
/// @param [in] surface The surface to which we bind the state
/// @param [in] transportCov Flag steering covariance transport
/// @param [in] freeToBoundCorrection Flag steering non-linear correction during global to local correction
///
/// @return A bound state:
/// - the parameters at the surface
/// - the stepwise jacobian towards it (from last bound)
/// - and the path length (from start - for ordering)
Result<MultiBoundState> multiBoundState(
State& state, const Surface& surface, bool transportCov = true,
const FreeToBoundCorrection& freeToBoundCorrection =
FreeToBoundCorrection(false)) const;

/// @brief If necessary fill additional members needed for curvilinearState
///
/// Compute path length derivatives in case they have not been computed
Expand Down Expand Up @@ -731,6 +744,23 @@
/// - and the path length (from start - for ordering)
BoundState curvilinearState(State& state, bool transportCov = true) const;

/// Create and return a curvilinear state at the current position
///
/// @brief This transports (if necessary) the covariance
/// to the current position and creates a curvilinear state.
/// @note This is done as a simple average over the free representation
/// and covariance of the components.
///
/// @param [in] state State that will be presented as @c CurvilinearState
/// @param [in] transportCov Flag steering covariance transport
///
/// @return A curvilinear state:
/// - the curvilinear parameters at given position
/// - the stepweise jacobian towards it (from last bound)
/// - and the path length (from start - for ordering)
MultiBoundState multiCurvilinearState(State& state,
bool transportCov = true) const;

/// Method for on-demand transport of the covariance
/// to a new curvilinear frame at current position,
/// or direction of the state
Expand Down
85 changes: 81 additions & 4 deletions Core/include/Acts/Propagator/MultiStepperLoop.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,79 @@

#include "Acts/Propagator/MultiStepperError.hpp"

#include <vector>

namespace Acts {

template <Concepts::SingleStepper S, typename R>
void MultiStepperLoop<S, R>::initialize(State& state,
const BoundTrackParameters& par) const {
state.particleHypothesis = par.particleHypothesis();

state.components.clear();
auto& cmp =
state.components.emplace_back(m_singleStepper.makeState(state.options),
1., IntersectionStatus::onSurface);
m_singleStepper.initialize(cmp.state, par);

state.covTransport = par.covariance().has_value();
state.pathAccumulated = 0;
state.steps = 0;

state.stepCounterAfterFirstComponentOnSurface.reset();

state.statistics = {};
}

template <Concepts::SingleStepper S, typename R>
void MultiStepperLoop<S, R>::initialize(
State& state, const MultiComponentBoundTrackParameters& par) const {
if (par.components().empty()) {
throw std::invalid_argument(
"Cannot construct MultiEigenStepperLoop::State with empty "
"multi-component parameters");
}

state.particleHypothesis = par.particleHypothesis();

state.components.clear();
for (auto i = 0ul; i < par.components().size(); ++i) {
const auto& [weight, singlePars] = par[i];
auto& cmp =
state.components.emplace_back(m_singleStepper.makeState(state.options),
weight, IntersectionStatus::onSurface);
m_singleStepper.initialize(cmp.state, singlePars);
}

state.covTransport = std::get<2>(par.components().front()).has_value();
state.pathAccumulated = 0;
state.steps = 0;

state.stepCounterAfterFirstComponentOnSurface.reset();

state.statistics = {};
}

template <Concepts::SingleStepper S, typename R>
auto MultiStepperLoop<S, R>::boundState(
State& state, const Surface& surface, bool transportCov,
const FreeToBoundCorrection& freeToBoundCorrection) const
-> Result<BoundState> {
Result<MultiBoundState> result =
multiBoundState(state, surface, transportCov, freeToBoundCorrection);
if (!result.ok()) {
return result.error();
}
const auto& [multiBoundParams, jacobian, pathLength] = *result;
return BoundState{multiBoundParams.merge(state.options.componentMergeMethod),
jacobian, pathLength};
}

template <Concepts::SingleStepper S, typename R>
auto MultiStepperLoop<S, R>::multiBoundState(
State& state, const Surface& surface, bool transportCov,
const FreeToBoundCorrection& freeToBoundCorrection) const
-> Result<MultiBoundState> {
assert(!state.components.empty());

std::vector<std::tuple<double, BoundVector, Covariance>> cmps;
Expand Down Expand Up @@ -59,15 +125,26 @@ auto MultiStepperLoop<S, R>::boundState(
return MultiStepperError::AllComponentsConversionToBoundFailed;
}

return BoundState{MultiComponentBoundTrackParameters(
surface.getSharedPtr(), cmps, state.particleHypothesis),
Jacobian::Zero(), accumulatedPathLength};
return MultiBoundState{
MultiComponentBoundTrackParameters(surface.getSharedPtr(), cmps,
state.particleHypothesis),
Jacobian::Zero(), accumulatedPathLength};
}

template <Concepts::SingleStepper S, typename R>
auto MultiStepperLoop<S, R>::curvilinearState(State& state,
bool transportCov) const
-> BoundState {
MultiBoundState result = multiCurvilinearState(state, transportCov);
const auto& [multiBoundParams, jacobian, pathLength] = result;
return BoundState{multiBoundParams.merge(state.options.componentMergeMethod),
jacobian, pathLength};
}

template <Concepts::SingleStepper S, typename R>
auto MultiStepperLoop<S, R>::multiCurvilinearState(State& state,
bool transportCov) const
-> MultiBoundState {
assert(!state.components.empty());

std::vector<std::tuple<double, Vector4, Vector3, double, BoundMatrix>> cmps;
Expand All @@ -85,7 +162,7 @@ auto MultiStepperLoop<S, R>::curvilinearState(State& state,
accumulatedPathLength += state.components[i].weight * pl;
}

return BoundState{
return MultiBoundState{
MultiComponentBoundTrackParameters::createCurvilinear(
state.options.geoContext, cmps, state.particleHypothesis),
Jacobian::Zero(), accumulatedPathLength};
Expand Down
44 changes: 6 additions & 38 deletions Core/include/Acts/Propagator/Propagator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include "Acts/Propagator/StandardAborters.hpp"
#include "Acts/Propagator/StepperConcept.hpp"
#include "Acts/Propagator/VoidNavigator.hpp"
#include "Acts/Propagator/detail/ParameterTraits.hpp"
#include "Acts/Utilities/Logger.hpp"
#include "Acts/Utilities/Result.hpp"

Expand Down Expand Up @@ -90,17 +89,7 @@ class Propagator final
SupportsBoundParameters_v<stepper_t>,
detail::BasePropagatorHelper<Propagator<stepper_t, navigator_t>>,
detail::PropagatorStub> {
/// Re-define bound track parameters dependent on the stepper
using StepperBoundTrackParameters =
detail::stepper_bound_parameters_type_t<stepper_t>;
static_assert(BoundTrackParametersConcept<StepperBoundTrackParameters>,
"Stepper bound track parameters do not fulfill bound "
"parameters concept.");
static_assert(std::copy_constructible<StepperBoundTrackParameters>,
"return track parameter type must be copy-constructible");

using Jacobian = BoundMatrix;
using BoundState = std::tuple<StepperBoundTrackParameters, Jacobian, double>;
static constexpr bool HasMultiStepper = Concepts::MultiStepper<stepper_t>;

static_assert(StepperStateConcept<typename stepper_t::State>,
"Stepper does not fulfill stepper concept.");
Expand Down Expand Up @@ -143,7 +132,6 @@ class Propagator final
///
template <typename propagator_options_t>
struct result_type_helper {
using parameters_t = StepperBoundTrackParameters;
using actor_list_t = typename propagator_options_t::actor_list_type;

/// @brief Propagation result type for an arbitrary list of additional
Expand All @@ -152,7 +140,7 @@ class Propagator final
/// @tparam args Parameter pack specifying additional propagation results
///
template <typename... args>
using this_result_type = PropagatorResult<parameters_t, args...>;
using this_result_type = PropagatorResult<args...>;

/// @brief Propagation result type derived from a given action list
using type = typename actor_list_t::template result_type<this_result_type>;
Expand Down Expand Up @@ -219,7 +207,6 @@ class Propagator final
/// fulfilled or the maximum number of steps/path length provided in the
/// propagation options is reached.
///
/// @tparam parameters_t Type of initial track parameters to propagate
/// @tparam propagator_options_t Type of the propagator options
/// @tparam path_aborter_t The path aborter type to be added
///
Expand All @@ -243,7 +230,6 @@ class Propagator final
/// is fulfilled, the destination surface is hit or the maximum number of
/// steps/path length as given in the propagation options is reached.
///
/// @tparam parameters_t Type of initial track parameters to propagate
/// @tparam propagator_options_t Type of the propagator options
/// @tparam target_aborter_t The target aborter type to be added
/// @tparam path_aborter_t The path aborter type to be added
Expand Down Expand Up @@ -343,33 +329,15 @@ class Propagator final
/// @param [in] result Result of the propagation
/// @param [in] options Propagation options
/// @param [in] createFinalParameters Whether to produce parameters at the end of the propagation
/// @param [in] target Surface to be used for the final parameters, if createFinalParameters is true
/// If nullptr, the current surface of the navigator will be used
///
/// @return Propagation result
template <typename propagator_state_t, typename propagator_options_t>
Result<ResultType<propagator_options_t>> makeResult(
propagator_state_t state, Result<void> result,
const propagator_options_t& options, bool createFinalParameters) const;

/// @brief Builds the propagator result object
///
/// This function creates the propagator result object from the propagator
/// state object. The `result` is passed to pipe a potential error from the
/// propagation call. The `options` are used to determine the type of the
/// result object.
///
/// @tparam propagator_state_t Type of the propagator state object
/// @tparam propagator_options_t Type of the propagator options
///
/// @param [in] state Propagator state object
/// @param [in] result Result of the propagation
/// @param [in] target Target surface of to propagate to
/// @param [in] options Propagation options
///
/// @return Propagation result
template <typename propagator_state_t, typename propagator_options_t>
Result<ResultType<propagator_options_t>> makeResult(
propagator_state_t state, Result<void> result, const Surface& target,
const propagator_options_t& options) const;
const propagator_options_t& options, bool createFinalParameters,
const Surface* target = nullptr) const;

private:
/// Implementation of propagation algorithm
Expand Down
Loading
Loading