File indexing completed on 2025-01-31 09:16:09
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 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
0048 using SourceLinkAccessor =
0049 Delegate<std::pair<source_link_iterator_t, source_link_iterator_t>(
0050 const Surface&)>;
0051
0052
0053 using Calibrator =
0054 typename KalmanFitterExtensions<TrackStateContainerBackend>::Calibrator;
0055
0056
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
0063
0064 SourceLinkAccessor sourceLinkAccessor;
0065
0066
0067
0068
0069 Calibrator calibrator{DelegateFuncTag<
0070 detail::voidFitterCalibrator<TrackStateContainerBackend>>{}};
0071
0072 MeasurementSelector measurementSelector{
0073 DelegateFuncTag<voidMeasurementSelector>{}};
0074
0075 public:
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
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
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
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
0148
0149 for (auto it = slBegin; it != slEnd; ++it) {
0150
0151 const auto sourceLink = *it;
0152
0153
0154 PM mask = PM::Predicted | PM::Jacobian | PM::Calibrated;
0155 if (it != slBegin) {
0156
0157 mask = PM::Calibrated;
0158 }
0159
0160 ACTS_VERBOSE("Create temp track state with mask: " << mask);
0161
0162
0163
0164
0165
0166
0167 auto ts = trajectory.makeTrackState(mask, prevTip);
0168
0169 if (it == slBegin) {
0170
0171 ts.predicted() = boundParams.parameters();
0172 if (boundParams.covariance()) {
0173 ts.predictedCovariance() = *boundParams.covariance();
0174 }
0175 ts.jacobian() = jacobian;
0176 } else {
0177
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
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
0213
0214
0215
0216
0217
0218
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
0241
0242 mask &= ~PM::Predicted & ~PM::Jacobian;
0243 }
0244 if (isOutlier) {
0245
0246 mask &= ~PM::Filtered;
0247 }
0248
0249
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
0257 trackState.shareFrom(*firstTrackState, PM::Predicted);
0258 trackState.shareFrom(*firstTrackState, PM::Jacobian);
0259 } else {
0260 firstTrackState = trackState;
0261 }
0262
0263
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
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
0285
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& , const Logger& ) {
0290 return std::pair{candidates.begin(), candidates.end()};
0291 };
0292 };
0293
0294 }