Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 09:16:09

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