Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-11-07 09:15:21

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 #pragma once
0010 
0011 // for definitions of Calibrator, MeasurementSelector
0012 #include "Acts/TrackFinding/CombinatorialKalmanFilterExtensions.hpp"
0013 #include "Acts/TrackFitting/KalmanFitter.hpp"
0014 
0015 namespace Acts {
0016 
0017 /// @brief Create track states for selected measurements associated to a surface.
0018 ///
0019 /// - First get a source link range covering relevant measurements associated to
0020 ///   the given surface. This task is delegated to a SourceLinkAccessor.
0021 /// - Then create temporary track states for all measurements defined
0022 ///   by a source link range, calibrate the measurements and fill the
0023 ///   the calibrated data of these track states using a dedicated calibrator
0024 /// - The measurement selection is delegated to a dedicated measurement
0025 ///   selector.
0026 /// - Finally add branches to the given trajectory for the selected, temporary
0027 ///   track states. The track states of these branches still lack the filtered
0028 ///    data which is to be filled by the next stage e.g. the
0029 ///    CombinatorialKalmanFilter.
0030 /// All track states, the temporary track states and track states for selected
0031 /// measurements, are created in the given trajectory. The resulting container
0032 /// may become big. Thus, it is advisable to copy selected tracks and their
0033 /// track states to a separate container after each track finding step.
0034 ///
0035 template <typename source_link_iterator_t, typename track_container_t>
0036 struct TrackStateCreator {
0037   /// Type alias for result of track states creation operation
0038   using TrackStatesResult =
0039       Acts::Result<CkfTypes::BranchVector<TrackIndexType>>;
0040   /// Type alias for track state container backend from track container
0041   using TrackStateContainerBackend =
0042       typename track_container_t::TrackStateContainerBackend;
0043   /// Type alias for track proxy from track container
0044   using TrackProxy = typename track_container_t::TrackProxy;
0045   /// Type alias for track state proxy from track container
0046   using TrackStateProxy = typename track_container_t::TrackStateProxy;
0047   /// Type alias for bound state tuple containing parameters, jacobian and path
0048   /// length
0049   using BoundState = std::tuple<BoundTrackParameters, BoundMatrix, double>;
0050   /// Type alias for container of candidate track state proxies
0051   using candidate_container_t =
0052       typename std::vector<typename track_container_t::TrackStateProxy>;
0053 
0054   // delegate definition to get source link ranges for a surface
0055   /// Type alias for delegate to access source link ranges for a surface
0056   using SourceLinkAccessor =
0057       Delegate<std::pair<source_link_iterator_t, source_link_iterator_t>(
0058           const Surface&)>;
0059 
0060   // delegate to get calibrted measurements from a source link iterator
0061   /// Type alias for calibrator delegate to process measurements from source
0062   /// links
0063   using Calibrator =
0064       typename KalmanFitterExtensions<TrackStateContainerBackend>::Calibrator;
0065 
0066   // delegate to select measurements from a track state range
0067   /// Type alias for delegate to select measurements from track state candidates
0068   using MeasurementSelector =
0069       Delegate<Result<std::pair<typename candidate_container_t::iterator,
0070                                 typename candidate_container_t::iterator>>(
0071           candidate_container_t& trackStates, bool&, const Logger&)>;
0072 
0073   /// The source link accessor will return an source link range for a surface
0074   /// which link to the associated measurements.
0075   SourceLinkAccessor sourceLinkAccessor;
0076 
0077   /// The Calibrator is a dedicated calibration algorithm that allows to
0078   /// calibrate measurements using track information, this could be e.g. sagging
0079   /// for wires, module deformations, etc.
0080   Calibrator calibrator{DelegateFuncTag<
0081       detail::voidFitterCalibrator<TrackStateContainerBackend>>{}};
0082 
0083   /// Delegate for measurement selection on surfaces
0084   MeasurementSelector measurementSelector{
0085       DelegateFuncTag<voidMeasurementSelector>{}};
0086 
0087  public:
0088   /// @brief extend the trajectory onto the given surface.
0089   ///
0090   /// @param gctx The geometry context to be used for this task
0091   /// @param calibrationContext The calibration context used to fill the calibrated data
0092   /// @param surface The surface onto which the trajectory is extended
0093   /// @param boundState the predicted bound state on the given surface
0094   /// @param prevTip the tip of the trajectory which is to be extended
0095   /// @param trackStateCandidates a temporary buffer which can be used to
0096   ///        to keep track of newly created temporary track states.
0097   /// @param trajectory the trajectory to be extended.
0098   /// @param logger a logger for messages.
0099   ///
0100   /// @return a list of indices of newly created track states which extend the
0101   ///    trajectory onto the given surface and match the bound state, or an
0102   ///    error.
0103   ///
0104   /// Extend or branch the trajectory onto the given surface. This may create
0105   /// new track states using measurements which match the predicted bound state.
0106   /// This may create multiple branches. The new track states still miss the
0107   /// "filtered" data.
0108   Result<CkfTypes::BranchVector<TrackIndexType>> createTrackStates(
0109       const GeometryContext& gctx, const CalibrationContext& calibrationContext,
0110       [[maybe_unused]] const Surface& surface, const BoundState& boundState,
0111       TrackIndexType prevTip,
0112       std::vector<TrackStateProxy>& trackStateCandidates,
0113       TrackStateContainerBackend& trajectory, const Logger& logger) const {
0114     TrackStatesResult tsRes = TrackStatesResult::success({});
0115     using SourceLinkRange = decltype(sourceLinkAccessor(surface));
0116     SourceLinkRange slRange = sourceLinkAccessor(surface);
0117     if (slRange.first != slRange.second) {
0118       auto [slBegin, slEnd] = slRange;
0119       tsRes = createSourceLinkTrackStates(
0120           gctx, calibrationContext, surface, boundState, slBegin, slEnd,
0121           prevTip, trackStateCandidates, trajectory, logger);
0122     }
0123     return tsRes;
0124   }
0125 
0126   /// Create track states for selected measurements given by the source links
0127   ///
0128   /// @param gctx The current geometry context
0129   /// @param calibrationContext pointer to the current calibration context
0130   /// @param surface the surface the sourceLinks are associated to
0131   /// @param boundState Bound state from the propagation on this surface
0132   /// @param slBegin Begin iterator for sourceLinks
0133   /// @param slEnd End iterator for sourceLinks
0134   /// @param prevTip Index pointing at previous trajectory state (i.e. tip)
0135   /// @param trackStateCandidates a temporary buffer which can be used to
0136   ///        to keep track of newly created temporary track states.
0137   /// @param trajectory the trajectory to which new track states for selected measurements will be added
0138   /// @param logger the logger for messages.
0139   /// @return Result containing vector of track state indices or error
0140   Result<CkfTypes::BranchVector<TrackIndexType>> createSourceLinkTrackStates(
0141       const GeometryContext& gctx, const CalibrationContext& calibrationContext,
0142       [[maybe_unused]] const Surface& surface, const BoundState& boundState,
0143       source_link_iterator_t slBegin, source_link_iterator_t slEnd,
0144       TrackIndexType prevTip,
0145       std::vector<TrackStateProxy>& trackStateCandidates,
0146       TrackStateContainerBackend& trajectory, const Logger& logger) const {
0147     using PM = TrackStatePropMask;
0148 
0149     using ResultTrackStateList =
0150         Acts::Result<CkfTypes::BranchVector<TrackIndexType>>;
0151     ResultTrackStateList resultTrackStateList{
0152         CkfTypes::BranchVector<TrackIndexType>()};
0153     const auto& [boundParams, jacobian, pathLength] = boundState;
0154 
0155     trackStateCandidates.clear();
0156     if constexpr (std::ranges::random_access_range<source_link_iterator_t>) {
0157       trackStateCandidates.reserve(std::distance(slBegin, slEnd));
0158     }
0159 
0160     // Calibrate all the source links on the surface since the selection has
0161     // to be done based on calibrated measurement
0162     for (auto it = slBegin; it != slEnd; ++it) {
0163       // get the source link
0164       const auto sourceLink = *it;
0165 
0166       // prepare the track state
0167       PM mask = PM::Predicted | PM::Jacobian | PM::Calibrated;
0168       if (it != slBegin) {
0169         // not the first TrackState, only need uncalibrated and calibrated
0170         mask = PM::Calibrated;
0171       }
0172 
0173       ACTS_VERBOSE("Create temp track state with mask: " << mask);
0174       // Temporary and final track states are created in the same
0175       // trajectory, which could lead to very large containers.
0176 
0177       // CAREFUL! This trackstate has a previous index that is not in this
0178       // MultiTrajectory Visiting backwards from this track state will
0179       // fail!
0180       auto ts = trajectory.makeTrackState(mask, prevTip);
0181 
0182       if (it == slBegin) {
0183         // only set these for first
0184         ts.predicted() = boundParams.parameters();
0185         if (boundParams.covariance()) {
0186           ts.predictedCovariance() = *boundParams.covariance();
0187         }
0188         ts.jacobian() = jacobian;
0189       } else {
0190         // subsequent track states can reuse
0191         auto& first = trackStateCandidates.front();
0192         ts.shareFrom(first, PM::Predicted);
0193         ts.shareFrom(first, PM::Jacobian);
0194       }
0195 
0196       ts.pathLength() = pathLength;
0197       ts.setReferenceSurface(boundParams.referenceSurface().getSharedPtr());
0198 
0199       // now calibrate the track state
0200       calibrator(gctx, calibrationContext, sourceLink, ts);
0201 
0202       trackStateCandidates.push_back(ts);
0203     }
0204 
0205     bool isOutlier = false;
0206     Result<std::pair<typename std::vector<TrackStateProxy>::iterator,
0207                      typename std::vector<TrackStateProxy>::iterator>>
0208         selectorResult =
0209             measurementSelector(trackStateCandidates, isOutlier, logger);
0210     if (!selectorResult.ok()) {
0211       ACTS_ERROR("Selection of calibrated measurements failed: "
0212                  << selectorResult.error().message());
0213       resultTrackStateList =
0214           ResultTrackStateList::failure(selectorResult.error());
0215     } else {
0216       auto selectedTrackStateRange = *selectorResult;
0217       resultTrackStateList = processSelectedTrackStates(
0218           selectedTrackStateRange.first, selectedTrackStateRange.second,
0219           trajectory, isOutlier, logger);
0220     }
0221 
0222     return resultTrackStateList;
0223   }
0224 
0225   /// Create track states for the given trajectory from candidate track states
0226   ///
0227   /// @param begin begin iterator of the list of candidate track states
0228   /// @param end end iterator of the list of candidate track states
0229   /// @param trackStates the trajectory to which the new track states are added
0230   /// @param isOutlier true if the candidate(s) is(are) an outlier(s).
0231   /// @param logger the logger for messages
0232   /// @return Result containing vector of track state indices or error
0233   Result<CkfTypes::BranchVector<TrackIndexType>> processSelectedTrackStates(
0234       typename std::vector<TrackStateProxy>::const_iterator begin,
0235       typename std::vector<TrackStateProxy>::const_iterator end,
0236       TrackStateContainerBackend& trackStates, bool isOutlier,
0237       const Logger& logger) const {
0238     using PM = TrackStatePropMask;
0239 
0240     using ResultTrackStateList =
0241         Acts::Result<CkfTypes::BranchVector<TrackIndexType>>;
0242     ResultTrackStateList resultTrackStateList{
0243         CkfTypes::BranchVector<TrackIndexType>()};
0244     CkfTypes::BranchVector<TrackIndexType>& trackStateList =
0245         *resultTrackStateList;
0246     trackStateList.reserve(end - begin);
0247 
0248     std::optional<TrackStateProxy> firstTrackState{std::nullopt};
0249     for (auto it = begin; it != end; ++it) {
0250       auto& candidateTrackState = *it;
0251 
0252       PM mask = PM::Predicted | PM::Filtered | PM::Jacobian | PM::Calibrated;
0253       if (it != begin) {
0254         // subsequent track states don't need storage for these as they will
0255         // be shared
0256         mask &= ~PM::Predicted & ~PM::Jacobian;
0257       }
0258       if (isOutlier) {
0259         // outlier won't have separate filtered parameters
0260         mask &= ~PM::Filtered;
0261       }
0262 
0263       // copy this trackstate into fitted states MultiTrajectory
0264       auto trackState =
0265           trackStates.makeTrackState(mask, candidateTrackState.previous());
0266       ACTS_VERBOSE("Create SourceLink output track state #"
0267                    << trackState.index() << " with mask: " << mask);
0268 
0269       if (it != begin) {
0270         // assign indices pointing to first track state
0271         trackState.shareFrom(*firstTrackState, PM::Predicted);
0272         trackState.shareFrom(*firstTrackState, PM::Jacobian);
0273       } else {
0274         firstTrackState = trackState;
0275       }
0276 
0277       // either copy ALL or everything except for predicted and jacobian
0278       trackState.copyFrom(candidateTrackState, mask, false);
0279 
0280       auto typeFlags = trackState.typeFlags();
0281       typeFlags.set(TrackStateFlag::ParameterFlag);
0282       typeFlags.set(TrackStateFlag::MeasurementFlag);
0283       if (trackState.referenceSurface().surfaceMaterial() != nullptr) {
0284         typeFlags.set(TrackStateFlag::MaterialFlag);
0285       }
0286       if (isOutlier) {
0287         // propagate information that this is an outlier state
0288         ACTS_VERBOSE(
0289             "Creating outlier track state with tip = " << trackState.index());
0290         typeFlags.set(TrackStateFlag::OutlierFlag);
0291       }
0292 
0293       trackStateList.push_back(trackState.index());
0294     }
0295     return resultTrackStateList;
0296   }
0297 
0298   /// Default measurement selector which will return all measurements
0299   /// @param candidates Measurement track state candidates
0300   /// @return Iterator pair representing the range of all candidates
0301   static Result<std::pair<typename std::vector<TrackStateProxy>::iterator,
0302                           typename std::vector<TrackStateProxy>::iterator>>
0303   voidMeasurementSelector(typename std::vector<TrackStateProxy>& candidates,
0304                           bool& /*isOutlier*/, const Logger& /*logger*/) {
0305     return std::pair{candidates.begin(), candidates.end()};
0306   };
0307 };
0308 
0309 }  // namespace Acts