File indexing completed on 2025-09-17 08:02:43
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Definitions/TrackParametrization.hpp"
0010 #include "Acts/EventData/MultiTrajectory.hpp"
0011 #include "Acts/EventData/TrackContainer.hpp"
0012 #include "Acts/EventData/VectorMultiTrajectory.hpp"
0013 #include "Acts/EventData/VectorTrackContainer.hpp"
0014 #include "Acts/EventData/detail/CorrectedTransformationFreeToBound.hpp"
0015 #include "Acts/Geometry/GeometryIdentifier.hpp"
0016 #include "Acts/Propagator/DirectNavigator.hpp"
0017 #include "Acts/Propagator/Navigator.hpp"
0018 #include "Acts/Propagator/Propagator.hpp"
0019 #include "Acts/Propagator/SympyStepper.hpp"
0020 #include "Acts/TrackFitting/GainMatrixUpdater.hpp"
0021 #include "Acts/TrackFitting/KalmanFitter.hpp"
0022 #include "Acts/TrackFitting/MbfSmoother.hpp"
0023 #include "Acts/Utilities/Delegate.hpp"
0024 #include "Acts/Utilities/Logger.hpp"
0025 #include "ActsExamples/EventData/IndexSourceLink.hpp"
0026 #include "ActsExamples/EventData/MeasurementCalibration.hpp"
0027 #include "ActsExamples/EventData/Track.hpp"
0028 #include "ActsExamples/TrackFitting/RefittingCalibrator.hpp"
0029 #include "ActsExamples/TrackFitting/TrackFitterFunction.hpp"
0030
0031 #include <cmath>
0032 #include <functional>
0033 #include <memory>
0034 #include <utility>
0035 #include <vector>
0036
0037 namespace {
0038
0039 using Stepper = Acts::SympyStepper;
0040 using Propagator = Acts::Propagator<Stepper, Acts::Navigator>;
0041 using Fitter = Acts::KalmanFitter<Propagator, Acts::VectorMultiTrajectory>;
0042 using DirectPropagator = Acts::Propagator<Stepper, Acts::DirectNavigator>;
0043 using DirectFitter =
0044 Acts::KalmanFitter<DirectPropagator, Acts::VectorMultiTrajectory>;
0045
0046 using TrackContainer =
0047 Acts::TrackContainer<Acts::VectorTrackContainer,
0048 Acts::VectorMultiTrajectory, std::shared_ptr>;
0049
0050 struct SimpleReverseFilteringLogic {
0051 double momentumThreshold = 0;
0052
0053 bool doBackwardFiltering(
0054 Acts::VectorMultiTrajectory::ConstTrackStateProxy trackState) const {
0055 auto momentum = std::abs(1 / trackState.filtered()[Acts::eBoundQOverP]);
0056 return (momentum <= momentumThreshold);
0057 }
0058 };
0059
0060 struct SimpleOutlierFinder {
0061 double chi2Cut = std::numeric_limits<double>::infinity();
0062
0063 bool isOutlier(
0064 Acts::VectorMultiTrajectory::ConstTrackStateProxy trackState) const {
0065 double chi2 = Acts::calculatePredictedChi2(trackState);
0066 return chi2 > chi2Cut;
0067 }
0068 };
0069
0070 using namespace ActsExamples;
0071
0072 struct KalmanFitterFunctionImpl final : public TrackFitterFunction {
0073 Fitter fitter;
0074 DirectFitter directFitter;
0075
0076 Acts::GainMatrixUpdater kfUpdater;
0077 Acts::MbfSmoother kfSmoother;
0078 SimpleReverseFilteringLogic reverseFilteringLogic;
0079 double reverseFilteringCovarianceScaling = 1.0;
0080 SimpleOutlierFinder outlierFinder;
0081
0082 bool multipleScattering = false;
0083 bool energyLoss = false;
0084 Acts::FreeToBoundCorrection freeToBoundCorrection;
0085
0086 IndexSourceLink::SurfaceAccessor slSurfaceAccessor;
0087
0088 KalmanFitterFunctionImpl(Fitter&& f, DirectFitter&& df,
0089 const Acts::TrackingGeometry& trkGeo)
0090 : fitter(std::move(f)),
0091 directFitter(std::move(df)),
0092 slSurfaceAccessor{trkGeo} {}
0093
0094 template <typename calibrator_t>
0095 auto makeKfOptions(const GeneralFitterOptions& options,
0096 const calibrator_t& calibrator) const {
0097 Acts::KalmanFitterExtensions<Acts::VectorMultiTrajectory> extensions;
0098 extensions.updater.connect<
0099 &Acts::GainMatrixUpdater::operator()<Acts::VectorMultiTrajectory>>(
0100 &kfUpdater);
0101 extensions.smoother
0102 .connect<&Acts::MbfSmoother::operator()<Acts::VectorMultiTrajectory>>(
0103 &kfSmoother);
0104 extensions.reverseFilteringLogic
0105 .connect<&SimpleReverseFilteringLogic::doBackwardFiltering>(
0106 &reverseFilteringLogic);
0107 extensions.outlierFinder.connect<&SimpleOutlierFinder::isOutlier>(
0108 &outlierFinder);
0109
0110 Acts::KalmanFitterOptions<Acts::VectorMultiTrajectory> kfOptions(
0111 options.geoContext, options.magFieldContext, options.calibrationContext,
0112 extensions, options.propOptions, &(*options.referenceSurface));
0113
0114 kfOptions.referenceSurfaceStrategy =
0115 Acts::KalmanFitterTargetSurfaceStrategy::first;
0116 kfOptions.multipleScattering = multipleScattering;
0117 kfOptions.energyLoss = energyLoss;
0118 kfOptions.freeToBoundCorrection = freeToBoundCorrection;
0119 kfOptions.extensions.calibrator.connect<&calibrator_t::calibrate>(
0120 &calibrator);
0121 kfOptions.reversedFilteringCovarianceScaling =
0122 reverseFilteringCovarianceScaling;
0123
0124 if (options.doRefit) {
0125 kfOptions.extensions.surfaceAccessor
0126 .connect<&RefittingCalibrator::accessSurface>();
0127 } else {
0128 kfOptions.extensions.surfaceAccessor
0129 .connect<&IndexSourceLink::SurfaceAccessor::operator()>(
0130 &slSurfaceAccessor);
0131 }
0132
0133 return kfOptions;
0134 }
0135
0136 TrackFitterResult operator()(const std::vector<Acts::SourceLink>& sourceLinks,
0137 const TrackParameters& initialParameters,
0138 const GeneralFitterOptions& options,
0139 const MeasurementCalibratorAdapter& calibrator,
0140 TrackContainer& tracks) const override {
0141 const auto kfOptions = makeKfOptions(options, calibrator);
0142 return fitter.fit(sourceLinks.begin(), sourceLinks.end(), initialParameters,
0143 kfOptions, tracks);
0144 }
0145
0146 TrackFitterResult operator()(
0147 const std::vector<Acts::SourceLink>& sourceLinks,
0148 const TrackParameters& initialParameters,
0149 const GeneralFitterOptions& options,
0150 const RefittingCalibrator& calibrator,
0151 const std::vector<const Acts::Surface*>& surfaceSequence,
0152 TrackContainer& tracks) const override {
0153 const auto kfOptions = makeKfOptions(options, calibrator);
0154 return directFitter.fit(sourceLinks.begin(), sourceLinks.end(),
0155 initialParameters, kfOptions, surfaceSequence,
0156 tracks);
0157 }
0158 };
0159
0160 }
0161
0162 std::shared_ptr<ActsExamples::TrackFitterFunction>
0163 ActsExamples::makeKalmanFitterFunction(
0164 std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry,
0165 std::shared_ptr<const Acts::MagneticFieldProvider> magneticField,
0166 bool multipleScattering, bool energyLoss,
0167 double reverseFilteringMomThreshold,
0168 double reverseFilteringCovarianceScaling,
0169 Acts::FreeToBoundCorrection freeToBoundCorrection, double chi2Cut,
0170 const Acts::Logger& logger) {
0171
0172 const Stepper stepper(std::move(magneticField));
0173
0174
0175 const auto& geo = *trackingGeometry;
0176 Acts::Navigator::Config cfg{std::move(trackingGeometry)};
0177 cfg.resolvePassive = false;
0178 cfg.resolveMaterial = true;
0179 cfg.resolveSensitive = true;
0180 Acts::Navigator navigator(cfg, logger.cloneWithSuffix("Navigator"));
0181 Propagator propagator(stepper, std::move(navigator),
0182 logger.cloneWithSuffix("Propagator"));
0183 Fitter trackFitter(std::move(propagator), logger.cloneWithSuffix("Fitter"));
0184
0185
0186 Acts::DirectNavigator directNavigator{
0187 logger.cloneWithSuffix("DirectNavigator")};
0188 DirectPropagator directPropagator(stepper, std::move(directNavigator),
0189 logger.cloneWithSuffix("DirectPropagator"));
0190 DirectFitter directTrackFitter(std::move(directPropagator),
0191 logger.cloneWithSuffix("DirectFitter"));
0192
0193
0194 auto fitterFunction = std::make_shared<KalmanFitterFunctionImpl>(
0195 std::move(trackFitter), std::move(directTrackFitter), geo);
0196 fitterFunction->multipleScattering = multipleScattering;
0197 fitterFunction->energyLoss = energyLoss;
0198 fitterFunction->reverseFilteringLogic.momentumThreshold =
0199 reverseFilteringMomThreshold;
0200 fitterFunction->freeToBoundCorrection = freeToBoundCorrection;
0201 fitterFunction->reverseFilteringCovarianceScaling =
0202 reverseFilteringCovarianceScaling;
0203 fitterFunction->outlierFinder.chi2Cut = chi2Cut;
0204
0205 return fitterFunction;
0206 }