Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
KalmanFitterFunction.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file KalmanFitterFunction.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2019-2021 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
32 
33 #include <algorithm>
34 #include <cmath>
35 #include <functional>
36 #include <memory>
37 #include <utility>
38 #include <vector>
39 
40 namespace Acts {
41 class MagneticFieldProvider;
42 class SourceLink;
43 class Surface;
44 class TrackingGeometry;
45 } // namespace Acts
46 
47 namespace {
48 
53 using DirectFitter =
55 
56 using TrackContainer =
58  Acts::VectorMultiTrajectory, std::shared_ptr>;
59 
60 struct SimpleReverseFilteringLogic {
61  double momentumThreshold = 0;
62 
63  bool doBackwardFiltering(
65  auto momentum = fabs(1 / trackState.filtered()[Acts::eBoundQOverP]);
66  return (momentum <= momentumThreshold);
67  }
68 };
69 
70 using namespace ActsExamples;
71 
72 struct KalmanFitterFunctionImpl final : public TrackFitterFunction {
73  Fitter fitter;
74  DirectFitter directFitter;
75 
76  Acts::GainMatrixUpdater kfUpdater;
77  Acts::GainMatrixSmoother kfSmoother;
78  SimpleReverseFilteringLogic reverseFilteringLogic;
79 
80  bool multipleScattering = false;
81  bool energyLoss = false;
82  Acts::FreeToBoundCorrection freeToBoundCorrection;
83 
84  IndexSourceLink::SurfaceAccessor slSurfaceAccessor;
85 
86  KalmanFitterFunctionImpl(Fitter&& f, DirectFitter&& df,
87  const Acts::TrackingGeometry& trkGeo)
88  : fitter(std::move(f)),
89  directFitter(std::move(df)),
90  slSurfaceAccessor{trkGeo} {}
91 
92  template <typename calibrator_t>
93  auto makeKfOptions(const GeneralFitterOptions& options,
94  const calibrator_t& calibrator) const {
96  extensions.updater.connect<
97  &Acts::GainMatrixUpdater::operator()<Acts::VectorMultiTrajectory>>(
98  &kfUpdater);
99  extensions.smoother.connect<
100  &Acts::GainMatrixSmoother::operator()<Acts::VectorMultiTrajectory>>(
101  &kfSmoother);
102  extensions.reverseFilteringLogic
103  .connect<&SimpleReverseFilteringLogic::doBackwardFiltering>(
104  &reverseFilteringLogic);
105 
107  options.geoContext, options.magFieldContext, options.calibrationContext,
108  extensions, options.propOptions, &(*options.referenceSurface));
109 
110  kfOptions.referenceSurfaceStrategy =
111  Acts::KalmanFitterTargetSurfaceStrategy::first;
112  kfOptions.multipleScattering = multipleScattering;
113  kfOptions.energyLoss = energyLoss;
114  kfOptions.freeToBoundCorrection = freeToBoundCorrection;
115  kfOptions.extensions.calibrator.connect<&calibrator_t::calibrate>(
116  &calibrator);
117  kfOptions.extensions.surfaceAccessor
118  .connect<&IndexSourceLink::SurfaceAccessor::operator()>(
119  &slSurfaceAccessor);
120 
121  return kfOptions;
122  }
123 
124  TrackFitterResult operator()(const std::vector<Acts::SourceLink>& sourceLinks,
125  const TrackParameters& initialParameters,
126  const GeneralFitterOptions& options,
127  const MeasurementCalibratorAdapter& calibrator,
128  TrackContainer& tracks) const override {
129  const auto kfOptions = makeKfOptions(options, calibrator);
130  return fitter.fit(sourceLinks.begin(), sourceLinks.end(), initialParameters,
131  kfOptions, tracks);
132  }
133 
134  TrackFitterResult operator()(
135  const std::vector<Acts::SourceLink>& sourceLinks,
136  const TrackParameters& initialParameters,
137  const GeneralFitterOptions& options,
138  const RefittingCalibrator& calibrator,
139  const std::vector<const Acts::Surface*>& surfaceSequence,
140  TrackContainer& tracks) const override {
141  const auto kfOptions = makeKfOptions(options, calibrator);
142  return directFitter.fit(sourceLinks.begin(), sourceLinks.end(),
143  initialParameters, kfOptions, surfaceSequence,
144  tracks);
145  }
146 };
147 
148 } // namespace
149 
150 std::shared_ptr<ActsExamples::TrackFitterFunction>
152  std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry,
153  std::shared_ptr<const Acts::MagneticFieldProvider> magneticField,
154  bool multipleScattering, bool energyLoss,
155  double reverseFilteringMomThreshold,
156  Acts::FreeToBoundCorrection freeToBoundCorrection,
157  const Acts::Logger& logger) {
158  // Stepper should be copied into the fitters
159  const Stepper stepper(std::move(magneticField));
160 
161  // Standard fitter
162  const auto& geo = *trackingGeometry;
163  Acts::Navigator::Config cfg{std::move(trackingGeometry)};
164  cfg.resolvePassive = false;
165  cfg.resolveMaterial = true;
166  cfg.resolveSensitive = true;
167  Acts::Navigator navigator(cfg, logger.cloneWithSuffix("Navigator"));
168  Propagator propagator(stepper, std::move(navigator),
169  logger.cloneWithSuffix("Propagator"));
170  Fitter trackFitter(std::move(propagator), logger.cloneWithSuffix("Fitter"));
171 
172  // Direct fitter
173  Acts::DirectNavigator directNavigator{
174  logger.cloneWithSuffix("DirectNavigator")};
175  DirectPropagator directPropagator(stepper, std::move(directNavigator),
176  logger.cloneWithSuffix("DirectPropagator"));
177  DirectFitter directTrackFitter(std::move(directPropagator),
178  logger.cloneWithSuffix("DirectFitter"));
179 
180  // build the fitter function. owns the fitter object.
181  auto fitterFunction = std::make_shared<KalmanFitterFunctionImpl>(
182  std::move(trackFitter), std::move(directTrackFitter), geo);
183  fitterFunction->multipleScattering = multipleScattering;
184  fitterFunction->energyLoss = energyLoss;
185  fitterFunction->reverseFilteringLogic.momentumThreshold =
186  reverseFilteringMomThreshold;
187  fitterFunction->freeToBoundCorrection = freeToBoundCorrection;
188 
189  return fitterFunction;
190 }