File indexing completed on 2025-11-07 09:15:21
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012 #include "Acts/TrackFinding/CombinatorialKalmanFilterExtensions.hpp"
0013 #include "Acts/TrackFitting/KalmanFitter.hpp"
0014
0015 namespace Acts {
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 template <typename source_link_iterator_t, typename track_container_t>
0036 struct TrackStateCreator {
0037
0038 using TrackStatesResult =
0039 Acts::Result<CkfTypes::BranchVector<TrackIndexType>>;
0040
0041 using TrackStateContainerBackend =
0042 typename track_container_t::TrackStateContainerBackend;
0043
0044 using TrackProxy = typename track_container_t::TrackProxy;
0045
0046 using TrackStateProxy = typename track_container_t::TrackStateProxy;
0047
0048
0049 using BoundState = std::tuple<BoundTrackParameters, BoundMatrix, double>;
0050
0051 using candidate_container_t =
0052 typename std::vector<typename track_container_t::TrackStateProxy>;
0053
0054
0055
0056 using SourceLinkAccessor =
0057 Delegate<std::pair<source_link_iterator_t, source_link_iterator_t>(
0058 const Surface&)>;
0059
0060
0061
0062
0063 using Calibrator =
0064 typename KalmanFitterExtensions<TrackStateContainerBackend>::Calibrator;
0065
0066
0067
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
0074
0075 SourceLinkAccessor sourceLinkAccessor;
0076
0077
0078
0079
0080 Calibrator calibrator{DelegateFuncTag<
0081 detail::voidFitterCalibrator<TrackStateContainerBackend>>{}};
0082
0083
0084 MeasurementSelector measurementSelector{
0085 DelegateFuncTag<voidMeasurementSelector>{}};
0086
0087 public:
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
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
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
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
0161
0162 for (auto it = slBegin; it != slEnd; ++it) {
0163
0164 const auto sourceLink = *it;
0165
0166
0167 PM mask = PM::Predicted | PM::Jacobian | PM::Calibrated;
0168 if (it != slBegin) {
0169
0170 mask = PM::Calibrated;
0171 }
0172
0173 ACTS_VERBOSE("Create temp track state with mask: " << mask);
0174
0175
0176
0177
0178
0179
0180 auto ts = trajectory.makeTrackState(mask, prevTip);
0181
0182 if (it == slBegin) {
0183
0184 ts.predicted() = boundParams.parameters();
0185 if (boundParams.covariance()) {
0186 ts.predictedCovariance() = *boundParams.covariance();
0187 }
0188 ts.jacobian() = jacobian;
0189 } else {
0190
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
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
0226
0227
0228
0229
0230
0231
0232
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
0255
0256 mask &= ~PM::Predicted & ~PM::Jacobian;
0257 }
0258 if (isOutlier) {
0259
0260 mask &= ~PM::Filtered;
0261 }
0262
0263
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
0271 trackState.shareFrom(*firstTrackState, PM::Predicted);
0272 trackState.shareFrom(*firstTrackState, PM::Jacobian);
0273 } else {
0274 firstTrackState = trackState;
0275 }
0276
0277
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
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
0299
0300
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& , const Logger& ) {
0305 return std::pair{candidates.begin(), candidates.end()};
0306 };
0307 };
0308
0309 }