19#include <Acts/EventData/ParticleHypothesis.hpp>
20#include <Acts/EventData/TrackContainer.hpp>
21#include <Acts/EventData/VectorMultiTrajectory.hpp>
22#include <Acts/EventData/VectorTrackContainer.hpp>
23#include <Acts/Geometry/GeometryContext.hpp>
24#include <Acts/Geometry/GeometryIdentifier.hpp>
25#include <Acts/Geometry/TrackingGeometry.hpp>
26#include <Acts/MagneticField/MagneticFieldProvider.hpp>
27#include <Acts/Propagator/EigenStepper.hpp>
28#include <Acts/Propagator/Navigator.hpp>
29#include <Acts/Propagator/Propagator.hpp>
30#include <Acts/TrackFinding/CombinatorialKalmanFilter.hpp>
31#include <Acts/TrackFinding/TrackStateCreator.hpp>
32#include <Acts/TrackFitting/GainMatrixSmoother.hpp>
33#include <Acts/TrackFitting/GainMatrixUpdater.hpp>
34#include <Acts/TrackFitting/KalmanFitter.hpp>
35#include <Acts/Utilities/CalibrationContext.hpp>
36#include <Acts/Utilities/Logger.hpp>
37#include <Acts/Utilities/VectorHelpers.hpp>
39#include <SHiP/TrackFitResult.hpp>
45#include <spdlog/spdlog.h>
58 Acts::Vector3
const direction = (m1.
global - m0.
global).normalized();
59 if (!direction.allFinite())
62 Acts::BoundVector pars = Acts::BoundVector::Zero();
63 pars[Acts::eBoundLoc0] = m0.
local[0];
64 pars[Acts::eBoundLoc1] = m0.
local[1];
65 pars[Acts::eBoundTime] = 0.;
66 pars[Acts::eBoundPhi] = Acts::VectorHelpers::phi(direction);
67 pars[Acts::eBoundTheta] = Acts::VectorHelpers::theta(direction);
68 double const p0 = 10.0 * Acts::UnitConstants::GeV;
69 pars[Acts::eBoundQOverP] = 1.0 / p0;
79 Acts::BoundMatrix cov = Acts::BoundMatrix::Zero();
80 double const sLoc = 27.5 * Acts::UnitConstants::mm;
81 cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = sLoc * sLoc;
82 cov(Acts::eBoundLoc1, Acts::eBoundLoc1) = sLoc * sLoc;
83 double const sT = 1.0 * Acts::UnitConstants::ns;
84 cov(Acts::eBoundTime, Acts::eBoundTime) = sT * sT;
85 double const sAng = 0.275;
86 cov(Acts::eBoundPhi, Acts::eBoundPhi) = sAng * sAng;
87 cov(Acts::eBoundTheta, Acts::eBoundTheta) = sAng * sAng;
88 double const sQop = 2.75 / p0;
89 cov(Acts::eBoundQOverP, Acts::eBoundQOverP) = sQop * sQop;
91 return Acts::BoundTrackParameters(m0.
surface->getSharedPtr(), pars, cov,
92 Acts::ParticleHypothesis::pion());
103template <
typename TrackStateProxy>
104Acts::Result<std::pair<typename std::vector<TrackStateProxy>::iterator,
105 typename std::vector<TrackStateProxy>::iterator>>
107 const Acts::Logger&) {
109 if (candidates.empty())
110 return std::pair{candidates.begin(), candidates.end()};
112 auto best = candidates.begin();
113 double bestDist2 = std::numeric_limits<double>::max();
114 for (
auto it = candidates.begin(); it != candidates.end(); ++it) {
115 auto const pred = it->predicted();
116 auto const meas = it->template calibrated<2>();
117 double const dx = pred[Acts::eBoundLoc0] - meas[0];
118 double const dy = pred[Acts::eBoundLoc1] - meas[1];
119 double const dist2 = dx * dx + dy * dy;
120 if (dist2 < bestDist2) {
125 std::iter_swap(candidates.begin(), best);
126 return std::pair{candidates.begin(), std::next(candidates.begin())};
133 using BField = Acts::MagneticFieldProvider;
139 std::shared_ptr<Acts::MagneticFieldProvider> field)
140 : m_geometry{std::move(geometry)},
141 m_geoContext(Acts::GeometryContext::dangerouslyDefaultConstruct()),
142 m_field{std::move(field)} {
144 Navigator::Config navCfg;
145 navCfg.trackingGeometry = m_geometry;
146 Navigator navigator(navCfg, Acts::getDefaultLogger(
"Navigator", Acts::Logging::INFO));
148 Propagator propagator(std::move(stepper), std::move(navigator));
149 m_ckf = std::make_unique<Ckf>(std::move(propagator),
150 Acts::getDefaultLogger(
"CKF", Acts::Logging::INFO));
155 Navigator::Config fitNavCfg;
156 fitNavCfg.trackingGeometry = m_geometry;
158 Acts::getDefaultLogger(
"FitNavigator", Acts::Logging::INFO));
159 Propagator fitPropagator(std::move(fitStepper), std::move(fitNavigator));
160 m_fitter = std::make_unique<Fitter>(std::move(fitPropagator));
169 Acts::BoundTrackParameters
const& seed,
171 std::vector<std::vector<ActsExamples::Index>> out;
176 using TrackStateCreatorType =
177 Acts::TrackStateCreator<IndexSourceLinkAccessor::Iterator, TrackContainer>;
178 TrackStateCreatorType trackStateCreator;
179 trackStateCreator.sourceLinkAccessor.template connect<&IndexSourceLinkAccessor::range>(
180 &sourceLinkAccessor);
181 trackStateCreator.calibrator
182 .template connect<&SpectrometerMeasurements::calibrator<Trajectory>>(&measurements);
186 trackStateCreator.measurementSelector.template connect<
189 Acts::GainMatrixUpdater kfUpdater;
191 Acts::CombinatorialKalmanFilterExtensions<TrackContainer> extensions;
192 extensions.updater.template connect<&Acts::GainMatrixUpdater::operator()<
Trajectory>>(
194 extensions.createTrackStates.template connect<&TrackStateCreatorType::createTrackStates>(
197 Acts::PropagatorPlainOptions propOptions(m_geoContext, m_magContext);
200 propOptions.maxSteps = 500;
201 propOptions.pathLimit = 50000. * Acts::UnitConstants::mm;
203 Acts::CombinatorialKalmanFilterOptions<TrackContainer> options(
204 m_geoContext, m_magContext, std::cref(m_calibContext), extensions, propOptions);
208 TrackContainer tracks(trackStorage, trajStorage);
210 auto result = m_ckf->findTracks(seed, options, tracks);
212 spdlog::warn(
"CKF track finding failed: {}", result.error().message());
215 for (
auto const& trackProxy : *result) {
220 if (trackProxy.tipIndex() == Acts::kTrackIndexInvalid)
222 std::vector<ActsExamples::Index> hits;
223 tracks.trackStateContainer().visitBackwards(trackProxy.tipIndex(), [&](
auto ts) {
224 if (!ts.typeFlags().isMeasurement())
231 if (!ts.hasUncalibratedSourceLink())
236 auto const isl = ts.getUncalibratedSourceLink().template get<IndexSourceLink>();
237 hits.push_back(isl.index());
241 out.push_back(std::move(hits));
253 SHiP::TrackFitResult
refit(Acts::BoundTrackParameters
const& seed,
255 std::vector<ActsExamples::Index>
const& hitIndices)
const {
267 struct MeasurementSurfaceAccessor {
269 const Acts::Surface* operator()(Acts::SourceLink
const& sl)
const {
271 return measurements->
measurements()[isl.index()].surface;
275 Acts::GainMatrixUpdater kfUpdater;
276 Acts::GainMatrixSmoother kfSmoother;
277 MeasurementSurfaceAccessor surfaceAccessor{&measurements};
279 Acts::KalmanFitterExtensions<Trajectory> ext;
280 ext.surfaceAccessor.template connect<&MeasurementSurfaceAccessor::operator()>(
282 ext.calibrator.template connect<&SpectrometerMeasurements::calibrator<Trajectory>>(
284 ext.updater.template connect<&Acts::GainMatrixUpdater::operator()<
Trajectory>>(&kfUpdater);
285 ext.smoother.template connect<&Acts::GainMatrixSmoother::operator()<
Trajectory>>(
288 Acts::PropagatorPlainOptions propOptions(m_geoContext, m_magContext);
289 propOptions.maxSteps = 500;
290 propOptions.pathLimit = 50000. * Acts::UnitConstants::mm;
292 Acts::KalmanFitterOptions<Trajectory> options(m_geoContext, m_magContext,
293 std::cref(m_calibContext), ext, propOptions,
294 &seed.referenceSurface());
296 Acts::VectorTrackContainer trackStorage;
298 Acts::TrackContainer tracks(std::move(trackStorage), std::move(trajStorage));
300 std::vector<Acts::SourceLink> sourceLinks;
301 sourceLinks.reserve(hitIndices.size());
302 for (
auto const idx : hitIndices) {
304 sourceLinks.emplace_back(
IndexSourceLink{m.surface->geometryId(), idx});
307 auto result = m_fitter->fit(sourceLinks.begin(), sourceLinks.end(), seed, options, tracks);
312 using TrackContainer = Acts::TrackContainer<TrackContainerBackend, Trajectory>;
313 using Ckf = Acts::CombinatorialKalmanFilter<Propagator, TrackContainer>;
314 using Fitter = Acts::KalmanFitter<Propagator, Trajectory>;
316 std::shared_ptr<const Acts::TrackingGeometry> m_geometry;
317 Acts::GeometryContext m_geoContext;
318 Acts::MagneticFieldContext m_magContext;
319 Acts::CalibrationContext m_calibContext;
320 std::shared_ptr<BField> m_field;
321 std::unique_ptr<Ckf> m_ckf;
322 std::unique_ptr<Fitter> m_fitter;
A source link that stores just an index.
Definition IndexSourceLink.hpp:32
SHiP::TrackFitResult refit(Acts::BoundTrackParameters const &seed, SpectrometerMeasurements const &measurements, std::vector< ActsExamples::Index > const &hitIndices) const
Definition SpectrometerCkf.hpp:253
Acts::MagneticFieldProvider BField
Definition SpectrometerCkf.hpp:133
SpectrometerCkf(std::shared_ptr< const Acts::TrackingGeometry > geometry, std::shared_ptr< Acts::MagneticFieldProvider > field)
Definition SpectrometerCkf.hpp:138
Acts::VectorTrackContainer TrackContainerBackend
Definition SpectrometerCkf.hpp:132
std::vector< std::vector< ActsExamples::Index > > findCandidateHits(Acts::BoundTrackParameters const &seed, SpectrometerMeasurements const &measurements) const
Definition SpectrometerCkf.hpp:168
Acts::EigenStepper<> Stepper
Definition SpectrometerCkf.hpp:134
Acts::VectorMultiTrajectory Trajectory
Definition SpectrometerCkf.hpp:131
Acts::Navigator Navigator
Definition SpectrometerCkf.hpp:135
Acts::Propagator< Stepper, Navigator > Propagator
Definition SpectrometerCkf.hpp:136
Definition SpectrometerMeasurements.hpp:37
const ActsExamples::GeometryIdMultiset< IndexSourceLink > & sourceLinks() const
Definition SpectrometerMeasurements.hpp:91
const std::vector< Measurement > & measurements() const
Definition SpectrometerMeasurements.hpp:89
Definition fit_seed.cpp:16
Acts::Result< std::pair< typename std::vector< TrackStateProxy >::iterator, typename std::vector< TrackStateProxy >::iterator > > selectNearestMeasurement(std::vector< TrackStateProxy > &candidates, bool &isOutlier, const Acts::Logger &)
Definition SpectrometerCkf.hpp:106
TrackFitResult fromActsFitResult(const Acts::Result< Acts::TrackContainer< Acts::VectorTrackContainer, Acts::VectorMultiTrajectory, Acts::ValueHolder >::TrackProxy > &actsResult, Acts::TrackContainer< Acts::VectorTrackContainer, Acts::VectorMultiTrajectory, Acts::ValueHolder > &tracks, Acts::GeometryContext const &gctx)
Definition Utilities.hpp:20
std::optional< Acts::BoundTrackParameters > makeSeedFromHitPair(const SpectrometerMeasurements::Measurement &m0, const SpectrometerMeasurements::Measurement &m1)
Definition SpectrometerCkf.hpp:55
const Container * container
Definition GeometryContainers.hpp:149
Accessor for the above source link container.
Definition IndexSourceLink.hpp:75
Definition SpectrometerMeasurements.hpp:39
const Acts::Surface * surface
Definition SpectrometerMeasurements.hpp:42
Acts::Vector2 local
Definition SpectrometerMeasurements.hpp:44
Acts::Vector3 global
Definition SpectrometerMeasurements.hpp:43