File indexing completed on 2025-01-18 09:11:41
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/IndexSourceLink.hpp"
0022 #include "ActsExamples/EventData/Measurement.hpp"
0023 #include "ActsExamples/EventData/MeasurementCalibration.hpp"
0024 #include "ActsExamples/EventData/ProtoTrack.hpp"
0025 #include "ActsExamples/Framework/AlgorithmContext.hpp"
0026 #include "ActsExamples/TrackFitting/TrackFitterFunction.hpp"
0027
0028 #include <cstddef>
0029 #include <functional>
0030 #include <ostream>
0031 #include <stdexcept>
0032 #include <system_error>
0033 #include <utility>
0034 #include <vector>
0035
0036 ActsExamples::TrackFittingAlgorithm::TrackFittingAlgorithm(
0037 Config config, Acts::Logging::Level level)
0038 : ActsExamples::IAlgorithm("TrackFittingAlgorithm", level),
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 ActsExamples::ProcessCode ActsExamples::TrackFittingAlgorithm::execute(
0068 const ActsExamples::AlgorithmContext& ctx) const {
0069
0070 const auto& measurements = m_inputMeasurements(ctx);
0071 const auto& protoTracks = m_inputProtoTracks(ctx);
0072 const auto& initialParameters = m_inputInitialTrackParameters(ctx);
0073
0074 const ClusterContainer* clusters =
0075 m_inputClusters.isInitialized() ? &m_inputClusters(ctx) : nullptr;
0076
0077
0078 if (protoTracks.size() != initialParameters.size()) {
0079 ACTS_FATAL("Inconsistent number of proto tracks and parameters "
0080 << protoTracks.size() << " vs " << initialParameters.size());
0081 return ProcessCode::ABORT;
0082 }
0083
0084
0085 auto pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
0086 Acts::Vector3{0., 0., 0.});
0087
0088
0089
0090
0091 ActsExamples::MeasurementCalibratorAdapter calibrator(*(m_cfg.calibrator),
0092 measurements, clusters);
0093
0094 TrackFitterFunction::GeneralFitterOptions options{
0095 ctx.geoContext, ctx.magFieldContext, ctx.calibContext, pSurface.get(),
0096 Acts::PropagatorPlainOptions(ctx.geoContext, ctx.magFieldContext)};
0097
0098 auto trackContainer = std::make_shared<Acts::VectorTrackContainer>();
0099 auto trackStateContainer = std::make_shared<Acts::VectorMultiTrajectory>();
0100 TrackContainer tracks(trackContainer, trackStateContainer);
0101
0102
0103 std::vector<Acts::SourceLink> trackSourceLinks;
0104 for (std::size_t itrack = 0; itrack < protoTracks.size(); ++itrack) {
0105
0106 if (m_cfg.pickTrack > -1 &&
0107 static_cast<std::size_t>(m_cfg.pickTrack) != itrack) {
0108 continue;
0109 }
0110
0111
0112 const auto& protoTrack = protoTracks[itrack];
0113 const auto& initialParams = initialParameters[itrack];
0114
0115
0116
0117 if (protoTrack.empty()) {
0118 ACTS_WARNING("Empty track " << itrack << " found.");
0119 continue;
0120 }
0121
0122 ACTS_VERBOSE("Initial parameters: "
0123 << initialParams.fourPosition(ctx.geoContext).transpose()
0124 << " -> " << initialParams.direction().transpose());
0125
0126
0127 trackSourceLinks.clear();
0128 trackSourceLinks.reserve(protoTrack.size());
0129
0130
0131 for (auto measIndex : protoTrack) {
0132 ConstVariableBoundMeasurementProxy measurement =
0133 measurements.getMeasurement(measIndex);
0134 IndexSourceLink sourceLink(measurement.geometryId(), measIndex);
0135 trackSourceLinks.push_back(Acts::SourceLink(sourceLink));
0136 }
0137
0138 ACTS_DEBUG("Invoke direct fitter for track " << itrack);
0139 auto result = (*m_cfg.fit)(trackSourceLinks, initialParams, options,
0140 calibrator, tracks);
0141
0142 if (result.ok()) {
0143
0144 const auto& track = result.value();
0145 if (track.hasReferenceSurface()) {
0146 ACTS_VERBOSE("Fitted parameters for track " << itrack);
0147 ACTS_VERBOSE(" " << track.parameters().transpose());
0148 } else {
0149 ACTS_DEBUG("No fitted parameters for track " << itrack);
0150 }
0151 } else {
0152 ACTS_WARNING("Fit failed for track "
0153 << itrack << " with error: " << result.error() << ", "
0154 << result.error().message());
0155 }
0156 }
0157
0158 std::stringstream ss;
0159 trackStateContainer->statistics().toStream(ss);
0160 ACTS_DEBUG(ss.str());
0161
0162 ConstTrackContainer constTracks{
0163 std::make_shared<Acts::ConstVectorTrackContainer>(
0164 std::move(*trackContainer)),
0165 std::make_shared<Acts::ConstVectorMultiTrajectory>(
0166 std::move(*trackStateContainer))};
0167
0168 m_outputTracks(ctx, std::move(constTracks));
0169 return ActsExamples::ProcessCode::SUCCESS;
0170 }