File indexing completed on 2025-08-05 08:09:49
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/GenericBoundTrackParameters.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/Propagator/Propagator.hpp"
0018 #include "Acts/Surfaces/PerigeeSurface.hpp"
0019 #include "Acts/Surfaces/Surface.hpp"
0020 #include "Acts/Utilities/Result.hpp"
0021 #include "ActsExamples/EventData/MeasurementCalibration.hpp"
0022 #include "ActsExamples/EventData/ProtoTrack.hpp"
0023 #include "ActsExamples/Framework/AlgorithmContext.hpp"
0024 #include "ActsExamples/TrackFitting/TrackFitterFunction.hpp"
0025
0026 #include <cstddef>
0027 #include <functional>
0028 #include <ostream>
0029 #include <stdexcept>
0030 #include <system_error>
0031 #include <utility>
0032 #include <vector>
0033
0034 ActsExamples::TrackFittingAlgorithm::TrackFittingAlgorithm(
0035 Config config, Acts::Logging::Level level)
0036 : ActsExamples::IAlgorithm("TrackFittingAlgorithm", level),
0037 m_cfg(std::move(config)) {
0038 if (m_cfg.inputMeasurements.empty()) {
0039 throw std::invalid_argument("Missing input measurement collection");
0040 }
0041 if (m_cfg.inputSourceLinks.empty()) {
0042 throw std::invalid_argument("Missing input source links collection");
0043 }
0044 if (m_cfg.inputProtoTracks.empty()) {
0045 throw std::invalid_argument("Missing input proto tracks collection");
0046 }
0047 if (m_cfg.inputInitialTrackParameters.empty()) {
0048 throw std::invalid_argument(
0049 "Missing input initial track parameters collection");
0050 }
0051 if (m_cfg.outputTracks.empty()) {
0052 throw std::invalid_argument("Missing output tracks collection");
0053 }
0054 if (!m_cfg.calibrator) {
0055 throw std::invalid_argument("Missing calibrator");
0056 }
0057 if (m_cfg.inputClusters.empty() && m_cfg.calibrator->needsClusters()) {
0058 throw std::invalid_argument("The configured calibrator needs clusters");
0059 }
0060
0061 m_inputMeasurements.initialize(m_cfg.inputMeasurements);
0062 m_inputSourceLinks.initialize(m_cfg.inputSourceLinks);
0063 m_inputProtoTracks.initialize(m_cfg.inputProtoTracks);
0064 m_inputInitialTrackParameters.initialize(m_cfg.inputInitialTrackParameters);
0065 m_inputClusters.maybeInitialize(m_cfg.inputClusters);
0066 m_outputTracks.initialize(m_cfg.outputTracks);
0067 }
0068
0069 ActsExamples::ProcessCode ActsExamples::TrackFittingAlgorithm::execute(
0070 const ActsExamples::AlgorithmContext& ctx) const {
0071
0072 const auto& measurements = m_inputMeasurements(ctx);
0073 const auto& sourceLinks = m_inputSourceLinks(ctx);
0074 const auto& protoTracks = m_inputProtoTracks(ctx);
0075 const auto& initialParameters = m_inputInitialTrackParameters(ctx);
0076
0077 const ClusterContainer* clusters =
0078 m_inputClusters.isInitialized() ? &m_inputClusters(ctx) : nullptr;
0079
0080
0081 if (protoTracks.size() != initialParameters.size()) {
0082 ACTS_FATAL("Inconsistent number of proto tracks and parameters "
0083 << protoTracks.size() << " vs " << initialParameters.size());
0084 return ProcessCode::ABORT;
0085 }
0086
0087
0088 auto pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
0089 Acts::Vector3{0., 0., 0.});
0090
0091
0092
0093
0094 ActsExamples::MeasurementCalibratorAdapter calibrator(*(m_cfg.calibrator),
0095 measurements, clusters);
0096
0097 TrackFitterFunction::GeneralFitterOptions options{
0098 ctx.geoContext, ctx.magFieldContext, ctx.calibContext, pSurface.get(),
0099 Acts::PropagatorPlainOptions()};
0100
0101 auto trackContainer = std::make_shared<Acts::VectorTrackContainer>();
0102 auto trackStateContainer = std::make_shared<Acts::VectorMultiTrajectory>();
0103 TrackContainer tracks(trackContainer, trackStateContainer);
0104
0105
0106 std::vector<Acts::SourceLink> trackSourceLinks;
0107 for (std::size_t itrack = 0; itrack < protoTracks.size(); ++itrack) {
0108
0109 if (m_cfg.pickTrack > -1 && m_cfg.pickTrack != static_cast<int>(itrack)) {
0110 continue;
0111 }
0112
0113
0114 const auto& protoTrack = protoTracks[itrack];
0115 const auto& initialParams = initialParameters[itrack];
0116
0117
0118
0119 if (protoTrack.empty()) {
0120 ACTS_WARNING("Empty track " << itrack << " found.");
0121 continue;
0122 }
0123
0124 ACTS_VERBOSE("Initial parameters: "
0125 << initialParams.fourPosition(ctx.geoContext).transpose()
0126 << " -> " << initialParams.direction().transpose());
0127
0128
0129 trackSourceLinks.clear();
0130 trackSourceLinks.reserve(protoTrack.size());
0131
0132
0133 for (auto hitIndex : protoTrack) {
0134 if (auto it = sourceLinks.nth(hitIndex); it != sourceLinks.end()) {
0135 const IndexSourceLink& sourceLink = *it;
0136 trackSourceLinks.push_back(Acts::SourceLink{sourceLink});
0137 } else {
0138 ACTS_FATAL("Proto track " << itrack << " contains invalid hit index"
0139 << hitIndex);
0140 return ProcessCode::ABORT;
0141 }
0142 }
0143
0144 ACTS_DEBUG("Invoke direct fitter for track " << itrack);
0145 auto result = (*m_cfg.fit)(trackSourceLinks, initialParams, options,
0146 calibrator, tracks);
0147
0148 if (result.ok()) {
0149
0150 const auto& track = result.value();
0151 if (track.hasReferenceSurface()) {
0152 ACTS_VERBOSE("Fitted parameters for track " << itrack);
0153 ACTS_VERBOSE(" " << track.parameters().transpose());
0154 } else {
0155 ACTS_DEBUG("No fitted parameters for track " << itrack);
0156 }
0157 } else {
0158 ACTS_WARNING("Fit failed for track "
0159 << itrack << " with error: " << result.error() << ", "
0160 << result.error().message());
0161 }
0162 }
0163
0164 std::stringstream ss;
0165 trackStateContainer->statistics().toStream(ss);
0166 ACTS_DEBUG(ss.str());
0167
0168 ConstTrackContainer constTracks{
0169 std::make_shared<Acts::ConstVectorTrackContainer>(
0170 std::move(*trackContainer)),
0171 std::make_shared<Acts::ConstVectorMultiTrajectory>(
0172 std::move(*trackStateContainer))};
0173
0174 m_outputTracks(ctx, std::move(constTracks));
0175 return ActsExamples::ProcessCode::SUCCESS;
0176 }