Skip to content

Commit

Permalink
Merge branch 'main' into mockup-builder
Browse files Browse the repository at this point in the history
  • Loading branch information
dimitra97 authored Apr 12, 2023
2 parents c083366 + 65807a1 commit ae91d76
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 6 deletions.
14 changes: 12 additions & 2 deletions Core/include/Acts/TrackFitting/GaussianSumFitter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ struct GaussianSumFitter {

// Initialize the backward propagation with the DirectNavigator
auto bwdPropInitializer = [&sSequence, this](const auto& opts) {
using Actors = ActionList<GsfActor, DirectNavigator::Initializer>;
using Actors = ActionList<GsfActor, Acts::detail::FinalStateCollector,
DirectNavigator::Initializer>;
using Aborters = AbortList<>;

std::vector<const Surface*> backwardSequence(
Expand Down Expand Up @@ -169,7 +170,7 @@ struct GaussianSumFitter {

// Initialize the backward propagation with the DirectNavigator
auto bwdPropInitializer = [this](const auto& opts) {
using Actors = ActionList<GsfActor>;
using Actors = ActionList<GsfActor, Acts::detail::FinalStateCollector>;
using Aborters = AbortList<EndOfWorldReached>;

PropagatorOptions<Actors, Aborters> propOptions(opts.geoContext,
Expand Down Expand Up @@ -441,6 +442,15 @@ struct GaussianSumFitter {
track.parameters() = params.parameters();
track.covariance() = params.covariance().value();
track.setReferenceSurface(params.referenceSurface().getSharedPtr());

if (trackContainer.hasColumn(
hashString(GsfConstants::kFinalMultiComponentStateColumn))) {
ACTS_DEBUG("Add final multi-component state to track")
const auto& fsr = bwdResult->template get<
Acts::detail::FinalStateCollector::result_type>();
track.template component<GsfConstants::FinalMultiComponentState>(
GsfConstants::kFinalMultiComponentStateColumn) = fsr.pars;
}
}

calculateTrackQuantities(track);
Expand Down
12 changes: 11 additions & 1 deletion Core/include/Acts/TrackFitting/GsfOptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,16 @@
#include "Acts/Utilities/Logger.hpp"

namespace Acts {

namespace Experimental {

namespace GsfConstants {
constexpr std::string_view kFinalMultiComponentStateColumn =
"gsf-final-multi-component-state";
using FinalMultiComponentState =
std::optional<Acts::MultiComponentBoundTrackParameters<SinglyCharged>>;
} // namespace GsfConstants

/// The extensions needed for the GSF
template <typename traj_t>
struct GsfExtensions {
Expand Down Expand Up @@ -70,10 +78,12 @@ struct GsfOptions {

double weightCutoff = 1.e-4;

bool abortOnError = true;
bool abortOnError = false;

bool disableAllMaterialHandling = false;

std::string_view finalMultiComponentStateColumn = "";

GsfOptions() = delete;
};

Expand Down
39 changes: 39 additions & 0 deletions Core/include/Acts/TrackFitting/detail/GsfActor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -794,5 +794,44 @@ struct GsfActor {
}
};

/// An actor that collects the final multi component state once the propagation
/// finished
struct FinalStateCollector {
using MultiPars = Acts::Experimental::GsfConstants::FinalMultiComponentState;

struct result_type {
MultiPars pars;
};

template <typename propagator_state_t, typename stepper_t,
typename navigator_t>
void operator()(propagator_state_t& state, const stepper_t& stepper,
const navigator_t& navigator, result_type& result,
const Logger& /*logger*/) const {
if (not(navigator.targetReached(state.navigation) and
navigator.currentSurface(state.navigation))) {
return;
}

const auto& surface = *navigator.currentSurface(state.navigation);
std::vector<std::tuple<double, BoundVector, std::optional<BoundSymMatrix>>>
states;

for (auto cmp : stepper.componentIterable(state.stepping)) {
auto singleState = cmp.singleState(state);
auto bs = cmp.singleStepper(stepper).boundState(singleState.stepping,
surface, true);

if (bs.ok()) {
const auto& btp = std::get<BoundTrackParameters>(*bs);
states.emplace_back(cmp.weight(), btp.parameters(), btp.covariance());
}
}

result.pars =
typename MultiPars::value_type(surface.getSharedPtr(), states);
}
};

} // namespace detail
} // namespace Acts
16 changes: 16 additions & 0 deletions Examples/Algorithms/TrackFitting/src/GsfFitterFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ struct GsfFitterFunctionImpl
const ActsExamples::TrackFittingAlgorithm::GeneralFitterOptions& options,
TrackContainer& tracks) const override {
const auto gsfOptions = makeGsfOptions(options);

using namespace Acts::Experimental::GsfConstants;
if (not tracks.hasColumn(
Acts::hashString(kFinalMultiComponentStateColumn))) {
std::string key(kFinalMultiComponentStateColumn);
tracks.template addColumn<FinalMultiComponentState>(key);
}

return fitter.fit(sourceLinks.begin(), sourceLinks.end(), initialParameters,
gsfOptions, tracks);
}
Expand All @@ -102,6 +110,14 @@ struct GsfFitterFunctionImpl
const std::vector<const Acts::Surface*>& surfaceSequence,
TrackContainer& tracks) const override {
const auto gsfOptions = makeGsfOptions(options);

using namespace Acts::Experimental::GsfConstants;
if (not tracks.hasColumn(
Acts::hashString(kFinalMultiComponentStateColumn))) {
std::string key(kFinalMultiComponentStateColumn);
tracks.template addColumn<FinalMultiComponentState>(key);
}

return directFitter.fit(sourceLinks.begin(), sourceLinks.end(),
initialParameters, gsfOptions, surfaceSequence,
tracks);
Expand Down
3 changes: 3 additions & 0 deletions Examples/Python/tests/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,9 @@ def test_full_chain_odd_example_pythia_geant4(tmp_path):
)


@pytest.mark.skip(
reason="as of https://github.com/acts-project/acts/issues/2023 disabling for now"
)
@pytest.mark.skipif(not dd4hepEnabled, reason="DD4hep not set up")
@pytest.mark.slow
def test_ML_Ambiguity_Solver(tmp_path, assert_root_hash):
Expand Down
33 changes: 31 additions & 2 deletions Tests/UnitTests/Core/TrackFitting/GsfTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ GsfExtensions<VectorMultiTrajectory> getExtensions() {

FitterTester tester;

const auto logger = getDefaultLogger("GSF", Logging::INFO);

using Stepper = Acts::MultiEigenStepperLoop<>;
using Propagator = Acts::Propagator<Stepper, Acts::Navigator>;
using BetheHeitlerApprox = AtlasBetheHeitlerApprox<6, 5>;
Expand Down Expand Up @@ -184,4 +182,35 @@ BOOST_AUTO_TEST_CASE(ZeroFieldWithOutliers) {
false, false);
}

BOOST_AUTO_TEST_CASE(WithFinalMultiComponentState) {
Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
Acts::VectorMultiTrajectory{}};
using namespace Acts::Experimental::GsfConstants;
std::string key(kFinalMultiComponentStateColumn);
tracks.template addColumn<FinalMultiComponentState>(key);

auto multi_pars = makeParameters();
auto measurements =
createMeasurements(tester.simPropagator, tester.geoCtx, tester.magCtx,
multi_pars, tester.resolutions, rng);
auto sourceLinks = tester.prepareSourceLinks(measurements.sourceLinks);
auto options = makeDefaultGsfOptions();

// create a boundless target surface near the tracker exit
Acts::Vector3 center(-3._m, 0., 0.);
Acts::Vector3 normal(1., 0., 0.);
auto targetSurface =
Acts::Surface::makeShared<Acts::PlaneSurface>(center, normal);

options.referenceSurface = targetSurface.get();

auto res = gsfZero.fit(sourceLinks.begin(), sourceLinks.end(), multi_pars,
options, tracks);

BOOST_REQUIRE(res.ok());
BOOST_CHECK(res->template component<FinalMultiComponentState>(
kFinalMultiComponentStateColumn)
.has_value());
}

BOOST_AUTO_TEST_SUITE_END()
4 changes: 3 additions & 1 deletion docs/core/track_fitting.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ 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`.

To simplify integration, the GSF returns a {class}`Acts::KalmanFitterResult` object, the same as the {class}`Acts::KalmanFitter`. This allows to use the same analysis tools for both fitters. Currently, the states of the individual components are not returned by the fitter.
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.

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).

Expand Down

0 comments on commit ae91d76

Please sign in to comment.