Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-13 08:13:31

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
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/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(Config config,
0037                                              Acts::Logging::Level level)
0038     : IAlgorithm("TrackFittingAlgorithm", level), m_cfg(std::move(config)) {
0039   if (m_cfg.inputMeasurements.empty()) {
0040     throw std::invalid_argument("Missing input measurement collection");
0041   }
0042   if (m_cfg.inputProtoTracks.empty()) {
0043     throw std::invalid_argument("Missing input proto tracks collection");
0044   }
0045   if (m_cfg.inputInitialTrackParameters.empty()) {
0046     throw std::invalid_argument(
0047         "Missing input initial track parameters collection");
0048   }
0049   if (m_cfg.outputTracks.empty()) {
0050     throw std::invalid_argument("Missing output tracks collection");
0051   }
0052   if (!m_cfg.calibrator) {
0053     throw std::invalid_argument("Missing calibrator");
0054   }
0055   if (m_cfg.inputClusters.empty() && m_cfg.calibrator->needsClusters()) {
0056     throw std::invalid_argument("The configured calibrator needs clusters");
0057   }
0058 
0059   m_inputMeasurements.initialize(m_cfg.inputMeasurements);
0060   m_inputProtoTracks.initialize(m_cfg.inputProtoTracks);
0061   m_inputInitialTrackParameters.initialize(m_cfg.inputInitialTrackParameters);
0062   m_inputClusters.maybeInitialize(m_cfg.inputClusters);
0063   m_outputTracks.initialize(m_cfg.outputTracks);
0064 }
0065 
0066 ProcessCode TrackFittingAlgorithm::execute(const AlgorithmContext& ctx) const {
0067   // Read input data
0068   const auto& measurements = m_inputMeasurements(ctx);
0069   const auto& protoTracks = m_inputProtoTracks(ctx);
0070   const auto& initialParameters = m_inputInitialTrackParameters(ctx);
0071 
0072   const ClusterContainer* clusters =
0073       m_inputClusters.isInitialized() ? &m_inputClusters(ctx) : nullptr;
0074 
0075   ACTS_DEBUG("Input measurements: " << measurements.size());
0076   ACTS_DEBUG("Input proto tracks: " << protoTracks.size());
0077   ACTS_DEBUG("Input initial parameters: " << initialParameters.size());
0078   ACTS_DEBUG("Input clusters: " << (clusters ? clusters->size() : 0));
0079 
0080   // Consistency cross checks
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   // Construct a perigee surface as the target surface
0088   auto pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
0089       Acts::Vector3{0., 0., 0.});
0090 
0091   // Measurement calibrator must be instantiated here, because we need the
0092   // measurements to construct it. The other extensions are hold by the
0093   // fit-function-object
0094   MeasurementCalibratorAdapter calibrator(*(m_cfg.calibrator), measurements,
0095                                           clusters);
0096 
0097   TrackFitterFunction::GeneralFitterOptions options{
0098       ctx.geoContext, ctx.magFieldContext, ctx.calibContext, pSurface.get(),
0099       Acts::PropagatorPlainOptions(ctx.geoContext, ctx.magFieldContext)};
0100 
0101   auto trackContainer = std::make_shared<Acts::VectorTrackContainer>();
0102   auto trackStateContainer = std::make_shared<Acts::VectorMultiTrajectory>();
0103   TrackContainer tracks(trackContainer, trackStateContainer);
0104 
0105   // reserve space for the track containers
0106   // simply assume 30 states per track for now
0107   trackContainer->reserve(protoTracks.size());
0108   trackStateContainer->reserve(protoTracks.size() * 30);
0109 
0110   // Perform the fit for each input track
0111   std::vector<Acts::SourceLink> trackSourceLinks;
0112   for (std::size_t itrack = 0; itrack < protoTracks.size(); ++itrack) {
0113     // Check if you are not in picking mode
0114     if (m_cfg.pickTrack > -1 &&
0115         static_cast<std::size_t>(m_cfg.pickTrack) != itrack) {
0116       continue;
0117     }
0118 
0119     // The list of hits and the initial start parameters
0120     const auto& protoTrack = protoTracks[itrack];
0121     const auto& initialParams = initialParameters[itrack];
0122 
0123     // We can have empty tracks which must give empty fit results so the number
0124     // of entries in input and output containers matches.
0125     if (protoTrack.empty()) {
0126       ACTS_WARNING("Empty track " << itrack << " found.");
0127       continue;
0128     }
0129 
0130     ACTS_VERBOSE("Initial 4 position: "
0131                  << initialParams.fourPosition(ctx.geoContext).transpose());
0132     ACTS_VERBOSE(
0133         "Initial direction: " << initialParams.direction().transpose());
0134     ACTS_VERBOSE("Initial momentum: " << initialParams.absoluteMomentum());
0135 
0136     // Clear & reserve the right size
0137     trackSourceLinks.clear();
0138     trackSourceLinks.reserve(protoTrack.size());
0139 
0140     // Fill the source links via their indices from the container
0141     for (auto measIndex : protoTrack) {
0142       ConstVariableBoundMeasurementProxy measurement =
0143           measurements.getMeasurement(measIndex);
0144       IndexSourceLink sourceLink(measurement.geometryId(), measIndex);
0145       trackSourceLinks.push_back(Acts::SourceLink(sourceLink));
0146     }
0147 
0148     ACTS_VERBOSE("Invoke fitter for track " << itrack);
0149     auto result = (*m_cfg.fit)(trackSourceLinks, initialParams, options,
0150                                calibrator, tracks);
0151 
0152     if (result.ok()) {
0153       // Get the fit output object
0154       const auto& track = result.value();
0155       if (track.hasReferenceSurface()) {
0156         ACTS_VERBOSE("Fitted parameters for track " << itrack);
0157         ACTS_VERBOSE("  " << track.parameters().transpose());
0158         ACTS_VERBOSE("Measurements: (prototrack->track): "
0159                      << protoTrack.size() << " -> " << track.nMeasurements());
0160       } else {
0161         ACTS_VERBOSE("No fitted parameters for track " << itrack);
0162       }
0163     } else {
0164       ACTS_WARNING("Fit failed for track "
0165                    << itrack << " with error: " << result.error() << ", "
0166                    << result.error().message());
0167     }
0168   }
0169 
0170   if (logger().doPrint(Acts::Logging::DEBUG)) {
0171     std::stringstream ss;
0172     trackStateContainer->statistics().toStream(ss);
0173     ACTS_DEBUG(ss.str());
0174   }
0175 
0176   ConstTrackContainer constTracks{
0177       std::make_shared<Acts::ConstVectorTrackContainer>(
0178           std::move(*trackContainer)),
0179       std::make_shared<Acts::ConstVectorMultiTrajectory>(
0180           std::move(*trackStateContainer))};
0181 
0182   m_outputTracks(ctx, std::move(constTracks));
0183   return ProcessCode::SUCCESS;
0184 }
0185 
0186 }  // namespace ActsExamples