File indexing completed on 2025-08-06 08:18:10
0001 #include "ActsTrackFittingAlgorithm.h"
0002
0003 #include <Acts/Definitions/TrackParametrization.hpp>
0004
0005 #include <Acts/Geometry/GeometryIdentifier.hpp>
0006 #include <Acts/Geometry/TrackingGeometry.hpp>
0007
0008 #include <Acts/Propagator/EigenStepper.hpp>
0009 #include <Acts/Propagator/Navigator.hpp>
0010 #include <Acts/Propagator/Propagator.hpp>
0011
0012 #include <Acts/Surfaces/Surface.hpp>
0013
0014 #include <Acts/TrackFitting/GainMatrixSmoother.hpp>
0015 #include <Acts/TrackFitting/GainMatrixUpdater.hpp>
0016
0017 #include <Acts/Utilities/Helpers.hpp>
0018
0019
0020 namespace
0021 {
0022 using Updater = Acts::GainMatrixUpdater;
0023 using Smoother = Acts::GainMatrixSmoother;
0024 using Stepper = Acts::EigenStepper<>;
0025 using Propagator = Acts::Propagator<Stepper, Acts::Navigator>;
0026 using Fitter = Acts::KalmanFitter<Propagator, Acts::VectorMultiTrajectory>;
0027 using DirectPropagator = Acts::Propagator<Stepper, Acts::DirectNavigator>;
0028 using DirectFitter = Acts::KalmanFitter<DirectPropagator, Acts::VectorMultiTrajectory>;
0029
0030 struct SimpleReverseFilteringLogic
0031 {
0032 SimpleReverseFilteringLogic() = default;
0033 double momentumThreshold = 0.0;
0034
0035 bool doBackwardFiltering(
0036 Acts::MultiTrajectory<Acts::VectorMultiTrajectory>::ConstTrackStateProxy trackState) const
0037 {
0038 auto momentum = fabs(1 / trackState.filtered()[Acts::eBoundQOverP]);
0039 return (momentum <= momentumThreshold);
0040 }
0041 };
0042
0043 template <typename TrackFitterFunction>
0044 auto makeKfOptions(const TrackFitterFunction& f,
0045 ActsTrackFittingAlgorithm::GeneralFitterOptions options)
0046 {
0047 Acts::KalmanFitterExtensions<Acts::VectorMultiTrajectory> extensions;
0048
0049 extensions.updater.connect<&Acts::GainMatrixUpdater::operator()<Acts::VectorMultiTrajectory>>(&f.kfUpdater);
0050
0051 extensions.smoother.connect<&Acts::GainMatrixSmoother::operator()<Acts::VectorMultiTrajectory>>(&f.kfSmoother);
0052 extensions.reverseFilteringLogic
0053 .connect<&SimpleReverseFilteringLogic::doBackwardFiltering>(
0054 &f.reverseFilteringLogic);
0055
0056 Acts::KalmanFitterOptions<Acts::VectorMultiTrajectory> kfOptions(
0057 options.geoContext, options.magFieldContext, options.calibrationContext,
0058 extensions, options.propOptions,
0059 &(*options.referenceSurface));
0060
0061 kfOptions.multipleScattering = f.multipleScattering;
0062 kfOptions.energyLoss = f.energyLoss;
0063 kfOptions.freeToBoundCorrection = f.freeToBoundCorrection;
0064
0065 return kfOptions;
0066 }
0067
0068 struct TrackFitterFunctionImpl
0069 : public ActsTrackFittingAlgorithm::TrackFitterFunction
0070 {
0071 Fitter trackFitter;
0072 ActsSourceLink::SurfaceAccessor m_slSurfaceAccessor;
0073
0074 Acts::GainMatrixUpdater kfUpdater;
0075 Acts::GainMatrixSmoother kfSmoother;
0076 SimpleReverseFilteringLogic reverseFilteringLogic;
0077
0078 bool multipleScattering;
0079 bool energyLoss;
0080 Acts::FreeToBoundCorrection freeToBoundCorrection;
0081
0082 TrackFitterFunctionImpl(Fitter&& f,
0083 const Acts::TrackingGeometry& trkGeo)
0084 : trackFitter(std::move(f))
0085 , m_slSurfaceAccessor{trkGeo}
0086 , multipleScattering(true)
0087 , energyLoss(true)
0088 , freeToBoundCorrection(Acts::FreeToBoundCorrection())
0089 {
0090 }
0091
0092 ActsTrackFittingAlgorithm::TrackFitterResult operator()(
0093 const std::vector<Acts::SourceLink>& sourceLinks,
0094 const ActsTrackFittingAlgorithm::TrackParameters& initialParameters,
0095 const ActsTrackFittingAlgorithm::GeneralFitterOptions& options,
0096 const CalibratorAdapter& calibrator,
0097 ActsTrackFittingAlgorithm::TrackContainer& tracks) const override
0098 {
0099 auto kfOptions = makeKfOptions(*this, options);
0100 kfOptions.extensions.surfaceAccessor
0101 .connect<&ActsSourceLink::SurfaceAccessor::operator()>(
0102 &m_slSurfaceAccessor);
0103 kfOptions.extensions.calibrator
0104 .connect<&CalibratorAdapter::calibrate>(
0105 &calibrator);
0106 return trackFitter.fit(sourceLinks.begin(), sourceLinks.end(),
0107 initialParameters, kfOptions, tracks);
0108 }
0109 };
0110
0111 struct DirectedFitterFunctionImpl
0112 : public ActsTrackFittingAlgorithm::DirectedTrackFitterFunction
0113 {
0114 DirectFitter fitter;
0115 ActsSourceLink::SurfaceAccessor m_slSurfaceAccessor;
0116
0117 Acts::GainMatrixUpdater kfUpdater;
0118 Acts::GainMatrixSmoother kfSmoother;
0119 SimpleReverseFilteringLogic reverseFilteringLogic;
0120
0121 bool multipleScattering;
0122 bool energyLoss;
0123 Acts::FreeToBoundCorrection freeToBoundCorrection;
0124
0125 DirectedFitterFunctionImpl(DirectFitter&& f,
0126 const Acts::TrackingGeometry& trkGeo)
0127 : fitter(std::move(f))
0128 , m_slSurfaceAccessor{trkGeo}
0129 , multipleScattering(true)
0130 , energyLoss(true)
0131 , freeToBoundCorrection(Acts::FreeToBoundCorrection())
0132 {
0133 }
0134
0135 ActsTrackFittingAlgorithm::TrackFitterResult operator()(
0136 const std::vector<Acts::SourceLink>& sourceLinks,
0137 const ActsTrackFittingAlgorithm::TrackParameters& initialParameters,
0138 const ActsTrackFittingAlgorithm::GeneralFitterOptions& options,
0139 const std::vector<const Acts::Surface*>& sSequence,
0140 const CalibratorAdapter& calibrator,
0141 ActsTrackFittingAlgorithm::TrackContainer& tracks) const override
0142 {
0143 auto kfOptions = makeKfOptions(*this, options);
0144 kfOptions.extensions.calibrator
0145 .connect<&CalibratorAdapter::calibrate>(
0146 &calibrator);
0147 kfOptions.extensions.surfaceAccessor
0148 .connect<&ActsSourceLink::SurfaceAccessor::operator()>(
0149 &m_slSurfaceAccessor);
0150 return fitter.fit(sourceLinks.begin(), sourceLinks.end(), initialParameters,
0151 kfOptions, sSequence, tracks);
0152 };
0153 };
0154
0155 }
0156
0157 struct sPHENIXTrackFitterFunctionImpl : public TrackFitterFunctionImpl
0158 {
0159 ResidualOutlierFinder m_oFinder;
0160
0161 bool use_OF = false;
0162
0163 void outlierFinder(const ResidualOutlierFinder& finder) override
0164 {
0165 m_oFinder = finder;
0166 use_OF = true;
0167 }
0168
0169 sPHENIXTrackFitterFunctionImpl(Fitter&& f,
0170 const Acts::TrackingGeometry& trkGeo)
0171 : TrackFitterFunctionImpl(std::move(f), trkGeo)
0172 {
0173 }
0174
0175 ActsTrackFittingAlgorithm::TrackFitterResult operator()(
0176 const std::vector<Acts::SourceLink>& sourceLinks,
0177 const ActsTrackFittingAlgorithm::TrackParameters& initialParameters,
0178 const ActsTrackFittingAlgorithm::GeneralFitterOptions& options,
0179 const CalibratorAdapter& calibrator,
0180 ActsTrackFittingAlgorithm::TrackContainer& tracks)
0181 const override
0182 {
0183 auto kfOptions = makeKfOptions(*this, options);
0184 kfOptions.extensions.calibrator.connect<&CalibratorAdapter::calibrate>(
0185 &calibrator);
0186 kfOptions.extensions.surfaceAccessor
0187 .connect<&ActsSourceLink::SurfaceAccessor::operator()>(
0188 &m_slSurfaceAccessor);
0189 if (use_OF)
0190 {
0191 kfOptions.extensions.outlierFinder.connect<&ResidualOutlierFinder::operator()>(&m_oFinder);
0192 }
0193
0194 return trackFitter.fit(sourceLinks.begin(), sourceLinks.end(),
0195 initialParameters, kfOptions, tracks);
0196 };
0197 };
0198
0199 std::shared_ptr<ActsTrackFittingAlgorithm::TrackFitterFunction>
0200 ActsTrackFittingAlgorithm::makeKalmanFitterFunction(
0201 const std::shared_ptr<const Acts::TrackingGeometry>& trackingGeometry,
0202 std::shared_ptr<const Acts::MagneticFieldProvider> magneticField,
0203 bool multipleScattering, bool energyLoss,
0204 double reverseFilteringMomThreshold,
0205 Acts::FreeToBoundCorrection freeToBoundCorrection,
0206 const Acts::Logger& logger)
0207 {
0208 Stepper stepper(std::move(magneticField));
0209 const auto& geo = *trackingGeometry;
0210
0211 Acts::Navigator::Config cfg{trackingGeometry};
0212 cfg.resolvePassive = false;
0213 cfg.resolveMaterial = true;
0214 cfg.resolveSensitive = true;
0215 Acts::Navigator navigator(cfg, logger.cloneWithSuffix("Navigator"));
0216 Propagator propagator(std::move(stepper), std::move(navigator),
0217 logger.cloneWithSuffix("Propagator"));
0218 Fitter trackFitter(std::move(propagator), logger.cloneWithSuffix("Fitter"));
0219
0220
0221 auto fitterFunction =
0222 std::make_shared<sPHENIXTrackFitterFunctionImpl>(std::move(trackFitter), geo);
0223 fitterFunction->multipleScattering = multipleScattering;
0224 fitterFunction->energyLoss = energyLoss;
0225 fitterFunction->reverseFilteringLogic.momentumThreshold =
0226 reverseFilteringMomThreshold;
0227 fitterFunction->freeToBoundCorrection = freeToBoundCorrection;
0228
0229 return fitterFunction;
0230 }
0231
0232 std::shared_ptr<
0233 ActsTrackFittingAlgorithm::DirectedTrackFitterFunction>
0234 ActsTrackFittingAlgorithm::makeDirectedKalmanFitterFunction(
0235 const std::shared_ptr<const Acts::TrackingGeometry>& trackingGeometry,
0236 std::shared_ptr<const Acts::MagneticFieldProvider> magneticField,
0237 bool multipleScattering, bool energyLoss,
0238 double reverseFilteringMomThreshold,
0239 Acts::FreeToBoundCorrection freeToBoundCorrection,
0240 const Acts::Logger& logger)
0241 {
0242
0243 const Stepper stepper(std::move(magneticField));
0244 const auto& geo = *trackingGeometry;
0245
0246 Acts::DirectNavigator navigator{
0247 logger.cloneWithSuffix("DirectNavigator")};
0248 DirectPropagator propagator(stepper, std::move(navigator),
0249 logger.cloneWithSuffix("DirectPropagator"));
0250 DirectFitter fitter(std::move(propagator),
0251 logger.cloneWithSuffix("DirectFitter"));
0252
0253
0254 auto fitterFunction =
0255 std::make_shared<DirectedFitterFunctionImpl>(std::move(fitter), geo);
0256 fitterFunction->multipleScattering = multipleScattering;
0257 fitterFunction->energyLoss = energyLoss;
0258 fitterFunction->reverseFilteringLogic.momentumThreshold =
0259 reverseFilteringMomThreshold;
0260 fitterFunction->freeToBoundCorrection = freeToBoundCorrection;
0261
0262 return fitterFunction;
0263 }