File indexing completed on 2026-04-07 07:46:23
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/TrackFitting/TrackFittingAlgorithm.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/EventData/BoundTrackParameters.hpp"
0013 #include "Acts/EventData/SourceLink.hpp"
0014 #include "Acts/EventData/TrackProxy.hpp"
0015 #include "Acts/EventData/VectorMultiTrajectory.hpp"
0016 #include "Acts/EventData/VectorTrackContainer.hpp"
0017 #include "Acts/Surfaces/PerigeeSurface.hpp"
0018 #include "Acts/Surfaces/Surface.hpp"
0019 #include "Acts/Utilities/Logger.hpp"
0020 #include "Acts/Utilities/Result.hpp"
0021 #include "ActsExamples/EventData/IndexSourceLink.hpp"
0022 #include "ActsExamples/EventData/Measurement.hpp"
0023 #include "ActsExamples/EventData/MeasurementCalibration.hpp"
0024 #include "ActsExamples/Framework/AlgorithmContext.hpp"
0025 #include "ActsExamples/TrackFitting/TrackFitterFunction.hpp"
0026
0027 #include <cstddef>
0028 #include <ostream>
0029 #include <stdexcept>
0030 #include <system_error>
0031 #include <utility>
0032 #include <vector>
0033
0034 namespace ActsExamples {
0035
0036 TrackFittingAlgorithm::TrackFittingAlgorithm(
0037 Config config, std::unique_ptr<const Acts::Logger> logger)
0038 : IAlgorithm("TrackFittingAlgorithm", std::move(logger)),
0039 m_cfg(std::move(config)) {
0040 if (m_cfg.inputMeasurements.empty()) {
0041 throw std::invalid_argument("Missing input measurement collection");
0042 }
0043 if (m_cfg.inputProtoTracks.empty()) {
0044 throw std::invalid_argument("Missing input proto tracks collection");
0045 }
0046 if (m_cfg.inputInitialTrackParameters.empty()) {
0047 throw std::invalid_argument(
0048 "Missing input initial track parameters collection");
0049 }
0050 if (m_cfg.outputTracks.empty()) {
0051 throw std::invalid_argument("Missing output tracks collection");
0052 }
0053 if (!m_cfg.calibrator) {
0054 throw std::invalid_argument("Missing calibrator");
0055 }
0056 if (m_cfg.inputClusters.empty() && m_cfg.calibrator->needsClusters()) {
0057 throw std::invalid_argument("The configured calibrator needs clusters");
0058 }
0059
0060 m_inputMeasurements.initialize(m_cfg.inputMeasurements);
0061 m_inputProtoTracks.initialize(m_cfg.inputProtoTracks);
0062 m_inputInitialTrackParameters.initialize(m_cfg.inputInitialTrackParameters);
0063 m_inputClusters.maybeInitialize(m_cfg.inputClusters);
0064 m_outputTracks.initialize(m_cfg.outputTracks);
0065 }
0066
0067 ProcessCode TrackFittingAlgorithm::execute(const AlgorithmContext& ctx) const {
0068
0069 const auto& measurements = m_inputMeasurements(ctx);
0070 const auto& protoTracks = m_inputProtoTracks(ctx);
0071 const auto& initialParameters = m_inputInitialTrackParameters(ctx);
0072
0073 const ClusterContainer* clusters =
0074 m_inputClusters.isInitialized() ? &m_inputClusters(ctx) : nullptr;
0075
0076 ACTS_DEBUG("Input measurements: " << measurements.size());
0077 ACTS_DEBUG("Input proto tracks: " << protoTracks.size());
0078 ACTS_DEBUG("Input initial parameters: " << initialParameters.size());
0079 ACTS_DEBUG("Input clusters: " << (clusters ? clusters->size() : 0));
0080
0081
0082 if (protoTracks.size() != initialParameters.size()) {
0083 ACTS_FATAL("Inconsistent number of proto tracks and parameters "
0084 << protoTracks.size() << " vs " << initialParameters.size());
0085 return ProcessCode::ABORT;
0086 }
0087
0088
0089 auto pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
0090 Acts::Vector3{0., 0., 0.});
0091
0092
0093
0094
0095 MeasurementCalibratorAdapter calibrator(*(m_cfg.calibrator), measurements,
0096 clusters);
0097
0098 TrackFitterFunction::GeneralFitterOptions options{
0099 ctx.geoContext,
0100 ctx.magFieldContext,
0101 ctx.calibContext,
0102 pSurface.get(),
0103 Acts::PropagatorPlainOptions(ctx.geoContext, ctx.magFieldContext),
0104 false};
0105
0106 auto trackContainer = std::make_shared<Acts::VectorTrackContainer>();
0107 auto trackStateContainer = std::make_shared<Acts::VectorMultiTrajectory>();
0108 TrackContainer tracks(trackContainer, trackStateContainer);
0109
0110
0111
0112 trackContainer->reserve(protoTracks.size());
0113 trackStateContainer->reserve(protoTracks.size() * 30);
0114
0115
0116 std::vector<Acts::SourceLink> trackSourceLinks;
0117 for (std::size_t itrack = 0; itrack < protoTracks.size(); ++itrack) {
0118
0119 if (m_cfg.pickTrack > -1 &&
0120 static_cast<std::size_t>(m_cfg.pickTrack) != itrack) {
0121 continue;
0122 }
0123
0124
0125 const auto& protoTrack = protoTracks[itrack];
0126 const auto& initialParams = initialParameters[itrack];
0127
0128
0129
0130 if (protoTrack.empty()) {
0131 ACTS_WARNING("Empty proto track " << itrack << " found.");
0132 continue;
0133 }
0134
0135 ACTS_VERBOSE("Initial 4 position: "
0136 << initialParams.fourPosition(ctx.geoContext).transpose());
0137 ACTS_VERBOSE(
0138 "Initial direction: " << initialParams.direction().transpose());
0139 ACTS_VERBOSE("Initial momentum: " << initialParams.absoluteMomentum());
0140
0141
0142 trackSourceLinks.clear();
0143 trackSourceLinks.reserve(protoTrack.size());
0144
0145
0146 for (auto measIndex : protoTrack) {
0147 ConstVariableBoundMeasurementProxy measurement =
0148 measurements.getMeasurement(measIndex);
0149 IndexSourceLink sourceLink(measurement.geometryId(), measIndex);
0150 trackSourceLinks.push_back(Acts::SourceLink(sourceLink));
0151 }
0152
0153 ACTS_VERBOSE("Invoke fitter for track " << itrack);
0154 auto result = (*m_cfg.fit)(trackSourceLinks, initialParams, options,
0155 calibrator, tracks);
0156
0157 if (result.ok()) {
0158
0159 const auto& track = result.value();
0160 if (track.hasReferenceSurface()) {
0161 ACTS_VERBOSE("Fitted parameters for track " << itrack);
0162 ACTS_VERBOSE(" " << track.parameters().transpose());
0163 ACTS_VERBOSE("Measurements: (proto track->track): "
0164 << protoTrack.size() << " -> " << track.nMeasurements());
0165 } else {
0166 ACTS_VERBOSE("No fitted parameters for track " << itrack);
0167 }
0168 } else {
0169 ACTS_WARNING("Fit failed for track "
0170 << itrack << " with error: " << result.error() << ", "
0171 << result.error().message());
0172 }
0173 }
0174
0175 ACTS_DEBUG("Fitted tracks: " << trackContainer->size());
0176
0177 if (m_cfg.linkForward) {
0178 for (auto track : tracks) {
0179 track.linkForward();
0180 }
0181 }
0182
0183 if (logger().doPrint(Acts::Logging::DEBUG)) {
0184 std::stringstream ss;
0185 trackStateContainer->statistics().toStream(ss);
0186 ACTS_DEBUG(ss.str());
0187 }
0188
0189 ConstTrackContainer constTracks{
0190 std::make_shared<Acts::ConstVectorTrackContainer>(
0191 std::move(*trackContainer)),
0192 std::make_shared<Acts::ConstVectorMultiTrajectory>(
0193 std::move(*trackStateContainer))};
0194
0195 m_outputTracks(ctx, std::move(constTracks));
0196 return ProcessCode::SUCCESS;
0197 }
0198
0199 }