File indexing completed on 2026-10-31 08:31:40
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/TrackFitting/RefittingAlgorithm.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/Definitions/Units.hpp"
0014 #include "Acts/EventData/BoundTrackParameters.hpp"
0015 #include "Acts/EventData/MultiTrajectory.hpp"
0016 #include "Acts/EventData/SourceLink.hpp"
0017 #include "Acts/EventData/TrackProxy.hpp"
0018 #include "Acts/EventData/VectorMultiTrajectory.hpp"
0019 #include "Acts/EventData/VectorTrackContainer.hpp"
0020 #include "Acts/Surfaces/PerigeeSurface.hpp"
0021 #include "Acts/Surfaces/Surface.hpp"
0022 #include "Acts/Utilities/Result.hpp"
0023 #include "ActsExamples/Framework/AlgorithmContext.hpp"
0024 #include "ActsExamples/TrackFitting/RefittingCalibrator.hpp"
0025 #include "ActsExamples/TrackFitting/TrackFitterFunction.hpp"
0026
0027 #include <algorithm>
0028 #include <array>
0029 #include <cstdint>
0030 #include <memory>
0031 #include <optional>
0032 #include <ostream>
0033 #include <stdexcept>
0034 #include <system_error>
0035 #include <utility>
0036 #include <vector>
0037
0038 namespace ActsExamples {
0039
0040 RefittingAlgorithm::RefittingAlgorithm(
0041 Config config, std::unique_ptr<const Acts::Logger> logger)
0042 : IAlgorithm("RefittingAlgorithm", std::move(logger)),
0043 m_cfg(std::move(config)) {
0044 if (m_cfg.inputTracks.empty()) {
0045 throw std::invalid_argument("Missing input tracks collection");
0046 }
0047 if (m_cfg.outputTracks.empty()) {
0048 throw std::invalid_argument("Missing output tracks collection");
0049 }
0050
0051 m_inputTracks.initialize(m_cfg.inputTracks);
0052 m_outputTracks.initialize(m_cfg.outputTracks);
0053 }
0054
0055 ProcessCode RefittingAlgorithm::execute(const AlgorithmContext& ctx) const {
0056 const auto& inputTracks = m_inputTracks(ctx);
0057
0058 auto trackContainer = std::make_shared<Acts::VectorTrackContainer>();
0059 auto trackStateContainer = std::make_shared<Acts::VectorMultiTrajectory>();
0060 TrackContainer tracks(trackContainer, trackStateContainer);
0061
0062 std::shared_ptr<const Acts::Surface> perigeeSurface =
0063 Acts::Surface::makeShared<Acts::PerigeeSurface>(
0064 Acts::Vector3{0., 0., 0.});
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 auto beamSpotVectorTrackStateContainer =
0076 std::make_shared<Acts::VectorMultiTrajectory>();
0077 auto beamSpotTrackState = beamSpotVectorTrackStateContainer->makeTrackState();
0078
0079 const Acts::Vector2 beamSpotMeasValue{0., 0.};
0080
0081 beamSpotTrackState.setReferenceSurface(perigeeSurface);
0082
0083 if (m_cfg.beamSpotConstraint.has_value()) {
0084 ACTS_DEBUG("Using provided beam spot constraint matrix");
0085 beamSpotTrackState.allocateCalibrated(beamSpotMeasValue,
0086 m_cfg.beamSpotConstraint.value());
0087 } else {
0088 ACTS_DEBUG("No beam spot constraint provided, using zero matrix");
0089 beamSpotTrackState.allocateCalibrated(beamSpotMeasValue,
0090 Acts::SquareMatrix2::Zero());
0091 }
0092
0093 beamSpotTrackState.setProjectorSubspaceIndices(
0094 std::array<std::uint8_t, 2>{Acts::eBoundLoc0, Acts::eBoundLoc1});
0095
0096 Acts::SourceLink testSL{42};
0097 beamSpotTrackState.setUncalibratedSourceLink(std::move(testSL));
0098
0099 auto beamSpotConstVectorTrackStateContainer =
0100 std::make_shared<Acts::ConstVectorMultiTrajectory>(
0101 std::move(*beamSpotVectorTrackStateContainer));
0102
0103 auto beamSpotConstTrackState =
0104 beamSpotConstVectorTrackStateContainer->getTrackState(
0105 beamSpotTrackState.index());
0106
0107
0108 std::vector<Acts::SourceLink> trackSourceLinks;
0109 std::vector<const Acts::Surface*> surfSequence;
0110 RefittingCalibrator calibrator;
0111
0112 auto itrack = 0ul;
0113 for (const auto& track : inputTracks) {
0114
0115 ++itrack;
0116 if (m_cfg.pickTrack > -1 &&
0117 static_cast<std::size_t>(m_cfg.pickTrack) != itrack - 1) {
0118 continue;
0119 }
0120
0121 if (!track.hasReferenceSurface()) {
0122 ACTS_VERBOSE("Skip track " << itrack << ": missing ref surface");
0123 continue;
0124 }
0125
0126
0127
0128 const auto& refSurface = track.referenceSurface();
0129 const bool useBeamSpotConstraint = m_cfg.beamSpotConstraint.has_value();
0130 if (useBeamSpotConstraint && *perigeeSurface != refSurface) {
0131 ACTS_ERROR("Track " << itrack
0132 << " is not parametrized on the beam spot perigee "
0133 "surface, cannot apply the beam spot constraint");
0134 return ProcessCode::ABORT;
0135 }
0136
0137
0138
0139 const std::shared_ptr<const Acts::Surface> initialSurface =
0140 useBeamSpotConstraint ? perigeeSurface : refSurface.getSharedPtr();
0141
0142 TrackFitterFunction::GeneralFitterOptions options{
0143 ctx.recoGeoContext,
0144 ctx.magFieldContext,
0145 ctx.calibContext,
0146 perigeeSurface.get(),
0147 Acts::PropagatorPlainOptions(ctx.recoGeoContext, ctx.magFieldContext),
0148 true};
0149
0150 Acts::BoundTrackParameters initialParams(initialSurface, track.parameters(),
0151 track.covariance(),
0152 track.particleHypothesis());
0153
0154 if (initialParams.covariance()) {
0155 for (auto i = 0ul; i < m_cfg.initialVarInflation.size(); ++i) {
0156 (*initialParams.covariance())(i, i) *= m_cfg.initialVarInflation.at(i);
0157 }
0158 }
0159
0160 trackSourceLinks.clear();
0161 surfSequence.clear();
0162
0163 for (auto state : track.trackStatesReversed()) {
0164 surfSequence.push_back(&state.referenceSurface());
0165
0166 if (!state.hasCalibrated()) {
0167 continue;
0168 }
0169
0170 auto sl = RefittingCalibrator::RefittingSourceLink{state};
0171 trackSourceLinks.push_back(Acts::SourceLink{sl});
0172 }
0173
0174 if (surfSequence.empty()) {
0175 ACTS_DEBUG("Empty track " << itrack << " found.");
0176 continue;
0177 }
0178
0179 if (useBeamSpotConstraint) {
0180 RefittingCalibrator::RefittingSourceLink beamSpotSL{
0181 beamSpotConstTrackState};
0182 trackSourceLinks.emplace_back(Acts::SourceLink{beamSpotSL});
0183 }
0184
0185 std::ranges::reverse(surfSequence);
0186
0187 ACTS_VERBOSE("Initial parameters: "
0188 << initialParams.fourPosition(ctx.recoGeoContext).transpose()
0189 << " -> " << initialParams.direction().transpose());
0190
0191 ACTS_DEBUG("Invoke direct fitter for track " << itrack);
0192 auto result = (*m_cfg.fit)(trackSourceLinks, initialParams, options,
0193 calibrator, surfSequence, tracks);
0194
0195 if (result.ok()) {
0196
0197 const auto& refittedTrack = result.value();
0198 if (refittedTrack.hasReferenceSurface()) {
0199 ACTS_VERBOSE("Refitted parameters for track " << itrack);
0200 ACTS_VERBOSE(" " << track.parameters().transpose());
0201 ACTS_VERBOSE("Measurements: " << refittedTrack.nMeasurements());
0202 ACTS_VERBOSE("Outliers: " << refittedTrack.nOutliers());
0203 } else {
0204 ACTS_DEBUG("No refitted parameters for track " << itrack);
0205 }
0206 } else {
0207 ACTS_DEBUG("Fit failed for event "
0208 << ctx.eventNumber << " track " << itrack << " with error: "
0209 << result.error() << ", " << result.error().message());
0210 }
0211 ++itrack;
0212 }
0213
0214 ACTS_DEBUG("Fitted tracks: " << trackContainer->size());
0215
0216 if (logger().doPrint(Acts::Logging::DEBUG)) {
0217 std::stringstream ss;
0218 trackStateContainer->statistics().toStream(ss);
0219 ACTS_DEBUG(ss.str());
0220 }
0221
0222 ConstTrackContainer constTracks{
0223 std::make_shared<Acts::ConstVectorTrackContainer>(
0224 std::move(*trackContainer)),
0225 std::make_shared<Acts::ConstVectorMultiTrajectory>(
0226 std::move(*trackStateContainer))};
0227
0228 m_outputTracks(ctx, std::move(constTracks));
0229 return ProcessCode::SUCCESS;
0230 }
0231
0232 }