Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Refactor the measurement calibrator in the examples #2058

Merged
merged 12 commits into from
Apr 27, 2023
2 changes: 1 addition & 1 deletion Examples/Algorithms/Alignment/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ target_link_libraries(
ActsExamplesAlignment
PUBLIC
ActsCore ActsAlignment
ActsExamplesFramework ActsExamplesMagneticField)
ActsExamplesFramework ActsExamplesMagneticField)

install(
TARGETS ActsExamplesAlignment
Expand Down
7 changes: 5 additions & 2 deletions Examples/Algorithms/Alignment/src/AlignmentAlgorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "Acts/Surfaces/PerigeeSurface.hpp"
#include "Acts/TrackFitting/GainMatrixSmoother.hpp"
#include "Acts/TrackFitting/GainMatrixUpdater.hpp"
#include "ActsExamples/EventData/MeasurementCalibration.hpp"
#include "ActsExamples/EventData/ProtoTrack.hpp"
#include "ActsExamples/EventData/Trajectories.hpp"
#include "ActsExamples/Framework/WhiteBoard.hpp"
Expand Down Expand Up @@ -98,8 +99,10 @@ ActsExamples::ProcessCode ActsExamples::AlignmentAlgorithm::execute(
Acts::Vector3{0., 0., 0.});

Acts::KalmanFitterExtensions<Acts::VectorMultiTrajectory> extensions;
MeasurementCalibrator calibrator{measurements};
extensions.calibrator.connect<&MeasurementCalibrator::calibrate>(&calibrator);
PassThroughCalibrator pcalibrator;
MeasurementCalibratorAdapter calibrator(pcalibrator, measurements);
extensions.calibrator.connect<&MeasurementCalibratorAdapter::calibrate>(
&calibrator);
Acts::GainMatrixUpdater kfUpdater;
Acts::GainMatrixSmoother kfSmoother;
extensions.updater.connect<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "Acts/TrackFitting/GainMatrixSmoother.hpp"
#include "Acts/TrackFitting/GainMatrixUpdater.hpp"
#include "ActsExamples/EventData/Measurement.hpp"
#include "ActsExamples/EventData/MeasurementCalibration.hpp"
#include "ActsExamples/EventData/Track.hpp"
#include "ActsExamples/Framework/ProcessCode.hpp"
#include "ActsExamples/Framework/WhiteBoard.hpp"
Expand Down Expand Up @@ -63,14 +64,16 @@ ActsExamples::ProcessCode ActsExamples::TrackFindingAlgorithm::execute(
Acts::PropagatorPlainOptions pOptions;
pOptions.maxSteps = 100000;

MeasurementCalibrator calibrator{measurements};
PassThroughCalibrator pcalibrator;
MeasurementCalibratorAdapter calibrator(pcalibrator, measurements);
Acts::GainMatrixUpdater kfUpdater;
Acts::GainMatrixSmoother kfSmoother;
Acts::MeasurementSelector measSel{m_cfg.measurementSelectorCfg};

Acts::CombinatorialKalmanFilterExtensions<Acts::VectorMultiTrajectory>
extensions;
extensions.calibrator.connect<&MeasurementCalibrator::calibrate>(&calibrator);
extensions.calibrator.connect<&MeasurementCalibratorAdapter::calibrate>(
&calibrator);
extensions.updater.connect<
&Acts::GainMatrixUpdater::operator()<Acts::VectorMultiTrajectory>>(
&kfUpdater);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "Acts/TrackFitting/BetheHeitlerApprox.hpp"
#include "Acts/Utilities/CalibrationContext.hpp"
#include "ActsExamples/EventData/Measurement.hpp"
#include "ActsExamples/EventData/MeasurementCalibration.hpp"
#include "ActsExamples/EventData/Track.hpp"
#include "ActsExamples/TrackFitting/RefittingCalibrator.hpp"

Expand All @@ -46,7 +47,7 @@ class TrackFitterFunction {
virtual TrackFitterResult operator()(const std::vector<Acts::SourceLink>&,
const TrackParameters&,
const GeneralFitterOptions&,
const MeasurementCalibrator&,
const MeasurementCalibratorAdapter&,
TrackContainer&) const = 0;

virtual TrackFitterResult operator()(const std::vector<Acts::SourceLink>&,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ class TrackFittingAlgorithm final : public IAlgorithm {
std::string outputTracks;
/// Type erased fitter function.
std::shared_ptr<TrackFitterFunction> fit;
/// Tracking geometry for surface lookup
/// Pick a single track for debugging (-1 process all tracks)
int pickTrack = -1;
// Type erased calibrator for the measurements
std::shared_ptr<MeasurementCalibrator> calibrator;
};

/// Constructor of the fitting algorithm
Expand Down
2 changes: 1 addition & 1 deletion Examples/Algorithms/TrackFitting/src/GsfFitterFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ struct GsfFitterFunctionImpl final : public ActsExamples::TrackFitterFunction {
TrackFitterResult operator()(const std::vector<Acts::SourceLink>& sourceLinks,
const TrackParameters& initialParameters,
const GeneralFitterOptions& options,
const MeasurementCalibrator& calibrator,
const MeasurementCalibratorAdapter& calibrator,
TrackContainer& tracks) const override {
const auto gsfOptions = makeGsfOptions(options, calibrator);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ struct KalmanFitterFunctionImpl final : public TrackFitterFunction {
TrackFitterResult operator()(const std::vector<Acts::SourceLink>& sourceLinks,
const TrackParameters& initialParameters,
const GeneralFitterOptions& options,
const MeasurementCalibrator& calibrator,
const MeasurementCalibratorAdapter& calibrator,
TrackContainer& tracks) const override {
const auto kfOptions = makeKfOptions(options, calibrator);
return fitter.fit(sourceLinks.begin(), sourceLinks.end(), initialParameters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ ActsExamples::TrackFittingAlgorithm::TrackFittingAlgorithm(
if (m_cfg.outputTracks.empty()) {
throw std::invalid_argument("Missing output tracks collection");
}
if (!m_cfg.calibrator) {
throw std::invalid_argument("Missing calibrator");
}

m_inputMeasurements.initialize(m_cfg.inputMeasurements);
m_inputSourceLinks.initialize(m_cfg.inputSourceLinks);
Expand Down Expand Up @@ -68,7 +71,8 @@ ActsExamples::ProcessCode ActsExamples::TrackFittingAlgorithm::execute(
// Measurement calibrator must be instantiated here, because we need the
// measurements to construct it. The other extensions are hold by the
// fit-function-object
ActsExamples::MeasurementCalibrator calibrator(measurements);
ActsExamples::MeasurementCalibratorAdapter calibrator(*(m_cfg.calibrator),
measurements);

TrackFitterFunction::GeneralFitterOptions options{
ctx.geoContext, ctx.magFieldContext, ctx.calibContext, pSurface.get(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "Acts/EventData/TrackContainer.hpp"
#include "Acts/Surfaces/PerigeeSurface.hpp"
#include "ActsExamples/EventData/MeasurementCalibration.hpp"
#include "ActsExamples/EventData/ProtoTrack.hpp"
#include "ActsExamples/Framework/WhiteBoard.hpp"

Expand Down Expand Up @@ -64,8 +65,10 @@ ActsExamples::ProcessCode ActsExamples::TrackFittingChi2Algorithm::execute(
// Set Chi2 options
Acts::Experimental::Chi2FitterExtensions<Acts::VectorMultiTrajectory>
extensions;
MeasurementCalibrator calibrator{measurements};
extensions.calibrator.connect<&MeasurementCalibrator::calibrate>(&calibrator);
PassThroughCalibrator pcalibrator;
MeasurementCalibratorAdapter calibrator(pcalibrator, measurements);
extensions.calibrator.connect<&MeasurementCalibratorAdapter::calibrate>(
&calibrator);

Acts::Experimental::Chi2FitterOptions chi2Options(
ctx.geoContext, ctx.magFieldContext, ctx.calibContext, extensions,
Expand Down
3 changes: 2 additions & 1 deletion Examples/Framework/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ include(ActsTargetLinkLibrariesSystem)

add_library(
ActsExamplesFramework SHARED
src/EventData/MeasurementCalibration.cpp
src/Framework/IAlgorithm.cpp
src/Framework/SequenceElement.cpp
src/Framework/WhiteBoard.cpp
Expand Down Expand Up @@ -62,4 +63,4 @@ install(

install(
DIRECTORY include/ActsExamples
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
47 changes: 3 additions & 44 deletions Examples/Framework/include/ActsExamples/EventData/Measurement.hpp
Original file line number Diff line number Diff line change
@@ -1,68 +1,27 @@
// This file is part of the Acts project.
//
// Copyright (C) 2020 CERN for the benefit of the Acts project
// Copyright (C) 2020-2023 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/EventData/Measurement.hpp"
#include "Acts/EventData/MultiTrajectory.hpp"
#include "Acts/EventData/SourceLink.hpp"
#include "Acts/EventData/VectorMultiTrajectory.hpp"
#include "ActsExamples/EventData/IndexSourceLink.hpp"
#include <Acts/EventData/Measurement.hpp>

#include <cassert>
#include <vector>

namespace ActsExamples {

/// Variable measurement type that can contain all possible combinations.
using Measurement = ::Acts::BoundVariantMeasurement;

/// Container of measurements.
///
/// In contrast to the source links, the measurements themself must not be
/// orderable. The source links stored in the measurements are treated
/// as opaque here and no ordering is enforced on the stored measurements.
using MeasurementContainer = std::vector<Measurement>;

/// Calibrator to convert an index source link to a measurement.
class MeasurementCalibrator {
public:
/// Construct an invalid calibrator. Required to allow copying.
MeasurementCalibrator() = default;
/// Construct using a user-provided container to chose measurements from.
MeasurementCalibrator(const MeasurementContainer& measurements)
: m_measurements(&measurements) {}

/// Find the measurement corresponding to the source link.
///
/// @tparam parameters_t Track parameters type
/// @param gctx The geometry context (unused)
/// @param trackState The track state to calibrate
void calibrate(
const Acts::GeometryContext& /*gctx*/,
Acts::MultiTrajectory<Acts::VectorMultiTrajectory>::TrackStateProxy
trackState) const {
const IndexSourceLink& sourceLink =
trackState.getUncalibratedSourceLink().get<IndexSourceLink>();
assert(m_measurements and
"Undefined measurement container in DigitizedCalibrator");
assert((sourceLink.index() < m_measurements->size()) and
"Source link index is outside the container bounds");
std::visit(
[&](const auto& meas) {
trackState.allocateCalibrated(meas.size());
trackState.setCalibrated(meas);
},
(*m_measurements)[sourceLink.index()]);
}

private:
// use pointer so the calibrator is copyable and default constructible.
const MeasurementContainer* m_measurements = nullptr;
};

} // namespace ActsExamples
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// This file is part of the Acts project.
//
// Copyright (C) 2023 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/EventData/MultiTrajectory.hpp"
#include "Acts/EventData/SourceLink.hpp"
#include "Acts/EventData/VectorMultiTrajectory.hpp"
#include "ActsExamples/EventData/IndexSourceLink.hpp"
#include <ActsExamples/EventData/Measurement.hpp>

#include <cassert>

namespace ActsExamples {

/// Abstract base class for measurement-based calibration
class MeasurementCalibrator {
public:
virtual void calibrate(
const MeasurementContainer& measurements,
const Acts::GeometryContext& gctx,
Acts::MultiTrajectory<Acts::VectorMultiTrajectory>::TrackStateProxy&
trackState) const = 0;

virtual ~MeasurementCalibrator() = default;
};

// Calibrator to convert an index source link to a measurement as-is
class PassThroughCalibrator : public MeasurementCalibrator {
public:
/// Find the measurement corresponding to the source link.
///
/// @tparam parameters_t Track parameters type
/// @param gctx The geometry context (unused)
/// @param trackState The track state to calibrate
void calibrate(
const MeasurementContainer& measurements,
const Acts::GeometryContext& /*gctx*/,
Acts::MultiTrajectory<Acts::VectorMultiTrajectory>::TrackStateProxy&
trackState) const override;
};

// Adapter class that wraps a MeasurementCalibrator to conform to the
// core ACTS calibration interface
class MeasurementCalibratorAdapter {
public:
MeasurementCalibratorAdapter(const MeasurementCalibrator& calibrator,
const MeasurementContainer& measurements);

void calibrate(
const Acts::GeometryContext& gctx,
Acts::MultiTrajectory<Acts::VectorMultiTrajectory>::TrackStateProxy
trackState) const;

private:
const MeasurementCalibrator& m_calibrator;
const MeasurementContainer& m_measurements;
};

} // namespace ActsExamples
39 changes: 39 additions & 0 deletions Examples/Framework/src/EventData/MeasurementCalibration.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// This file is part of the Acts project.
//
// Copyright (C) 2023 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <ActsExamples/EventData/MeasurementCalibration.hpp>

void ActsExamples::PassThroughCalibrator::calibrate(
const MeasurementContainer& measurements,
const Acts::GeometryContext& /*gctx*/,
Acts::MultiTrajectory<Acts::VectorMultiTrajectory>::TrackStateProxy&
trackState) const {
const IndexSourceLink& sourceLink =
trackState.getUncalibratedSourceLink().get<IndexSourceLink>();
assert((sourceLink.index() < measurements.size()) and
"Source link index is outside the container bounds");

std::visit(
[&trackState](const auto& meas) {
trackState.allocateCalibrated(meas.size());
trackState.setCalibrated(meas);
},
(measurements)[sourceLink.index()]);
}

ActsExamples::MeasurementCalibratorAdapter::MeasurementCalibratorAdapter(
const MeasurementCalibrator& calibrator,
const MeasurementContainer& measurements)
: m_calibrator{calibrator}, m_measurements{measurements} {}

void ActsExamples::MeasurementCalibratorAdapter::calibrate(
const Acts::GeometryContext& gctx,
Acts::MultiTrajectory<Acts::VectorMultiTrajectory>::TrackStateProxy
trackState) const {
return m_calibrator.calibrate(m_measurements, gctx, trackState);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "Acts/Geometry/TrackingGeometry.hpp"
#include "Acts/Utilities/Logger.hpp"
#include "ActsExamples/EventData/Cluster.hpp"
#include "ActsExamples/EventData/Index.hpp"
#include "ActsExamples/EventData/IndexSourceLink.hpp"
#include "ActsExamples/EventData/Measurement.hpp"
#include "ActsExamples/Framework/DataHandle.hpp"
#include "ActsExamples/Framework/IReader.hpp"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "Acts/Utilities/Logger.hpp"
#include "ActsExamples/EventData/Cluster.hpp"
#include "ActsExamples/EventData/IndexSourceLink.hpp"
#include "ActsExamples/EventData/Measurement.hpp"
#include "ActsExamples/Framework/DataHandle.hpp"
#include "ActsExamples/Framework/IReader.hpp"
Expand Down
2 changes: 2 additions & 0 deletions Examples/Python/python/acts/examples/reconstruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,7 @@ def addKalmanTracks(
fit=acts.examples.makeKalmanFitterFunction(
trackingGeometry, field, **kalmanOptions
),
calibrator=acts.examples.makePassThroughCalibrator(),
)
s.addAlgorithm(fitAlg)

Expand Down Expand Up @@ -896,6 +897,7 @@ def addTruthTrackingGsf(
outputTracks="gsf_tracks",
pickTrack=-1,
fit=acts.examples.makeGsfFitterFunction(trackingGeometry, field, **gsfOptions),
calibrator=acts.examples.makePassThroughCalibrator(),
)
s.addAlgorithm(gsfAlg)

Expand Down
10 changes: 9 additions & 1 deletion Examples/Python/src/TrackFitting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void addTrackFitting(Context& ctx) {
ACTS_PYTHON_DECLARE_ALGORITHM(
ActsExamples::TrackFittingAlgorithm, mex, "TrackFittingAlgorithm",
inputMeasurements, inputSourceLinks, inputProtoTracks,
inputInitialTrackParameters, outputTracks, fit, pickTrack);
inputInitialTrackParameters, outputTracks, fit, pickTrack, calibrator);

ACTS_PYTHON_DECLARE_ALGORITHM(ActsExamples::RefittingAlgorithm, mex,
"RefittingAlgorithm", inputTracks, outputTracks,
Expand Down Expand Up @@ -66,6 +66,14 @@ void addTrackFitting(Context& ctx) {
py::arg("reverseFilteringMomThreshold"),
py::arg("freeToBoundCorrection"), py::arg("level"));

py::class_<MeasurementCalibrator, std::shared_ptr<MeasurementCalibrator>>(
mex, "MeasurementCalibrator");

mex.def("makePassThroughCalibrator",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is merged already, but I there a reason not to just expose the inheritance relationship and then have Python just construct the object directly instead of the factory?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No real reason I guess, I just don't know what I'm doing on the python side ;-) putting this on my list

[]() -> std::shared_ptr<MeasurementCalibrator> {
return std::make_shared<PassThroughCalibrator>();
});

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