Warning, file /acts/Core/include/Acts/TrackFitting/TrackletJoiner.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/EventData/TrackContainerFrontendConcept.hpp"
0013 #include "Acts/EventData/TrackProxyConcept.hpp"
0014 #include "Acts/EventData/TrackStateProxyConcept.hpp"
0015 #include "Acts/EventData/Types.hpp"
0016 #include "Acts/Geometry/GeometryContext.hpp"
0017 #include "Acts/TrackFitting/KalmanFitterError.hpp"
0018 #include "Acts/TrackFitting/MbfSmoother.hpp"
0019 #include "Acts/TrackFitting/detail/TrackletJoining.hpp"
0020 #include "Acts/Utilities/Logger.hpp"
0021 #include "Acts/Utilities/Result.hpp"
0022
0023 #include <algorithm>
0024 #include <iterator>
0025 #include <memory>
0026 #include <tuple>
0027 #include <utility>
0028
0029 namespace Acts {
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 class TrackletJoiner {
0054 public:
0055
0056 struct Config {
0057
0058 bool smoothSecond = true;
0059
0060 bool conditionFirst = true;
0061
0062 bool invertJacobians = true;
0063 };
0064
0065
0066 TrackletJoiner() : TrackletJoiner(Config{}) {}
0067
0068
0069
0070
0071 explicit TrackletJoiner(const Config& cfg,
0072 std::unique_ptr<const Logger> logger =
0073 getDefaultLogger("TrackletJoiner", Logging::INFO))
0074 : m_cfg(cfg), m_logger(std::move(logger)) {}
0075
0076
0077
0078 const Config& config() const { return m_cfg; }
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 template <typename smoother_t = MbfSmoother, TrackProxyConcept track_proxy_t>
0095 Result<void> joinInPlace(const GeometryContext& gctx, track_proxy_t& first,
0096 typename track_proxy_t::TrackStateProxy sharedState,
0097 track_proxy_t& second,
0098 const smoother_t& smoother = smoother_t{}) const {
0099 auto& trajectory = first.container().trackStateContainer();
0100
0101 if (first.stemIndex() == kTrackIndexInvalid) {
0102 first.linkForward();
0103 }
0104
0105 if (second.tipIndex() == kTrackIndexInvalid) {
0106
0107 const auto tipIndex = first.tipIndex();
0108 const auto stemIndex = first.stemIndex();
0109 first.copyFromWithoutStates(second);
0110 first.tipIndex() = tipIndex;
0111 first.stemIndex() = stemIndex;
0112 return Result<void>::success();
0113 }
0114 if (!sharedState.hasSmoothed()) {
0115 ACTS_DEBUG("Shared state " << sharedState.index()
0116 << " has no smoothed parameters");
0117 return KalmanFitterError::SmoothFailed;
0118 }
0119
0120 BoundVector sharedMean = sharedState.smoothed();
0121 BoundMatrix sharedCov = sharedState.smoothedCovariance();
0122
0123 if (m_cfg.smoothSecond) {
0124 auto res = smoother(gctx, trajectory, second.tipIndex(), logger());
0125 if (!res.ok()) {
0126 ACTS_DEBUG("Smoothing of the second tracklet failed: "
0127 << res.error().message());
0128 return res.error();
0129 }
0130
0131
0132 auto secondStart = second.outermostTrackState();
0133 for (auto ts : second.trackStatesReversed()) {
0134 secondStart = ts;
0135 }
0136 auto prior = detail::smoothPriorNode(AnyConstTrackStateProxy{secondStart},
0137 sharedMean, sharedCov, logger());
0138 if (!prior.ok()) {
0139 return prior.error();
0140 }
0141 std::tie(sharedMean, sharedCov) = *prior;
0142 }
0143
0144 if (m_cfg.conditionFirst) {
0145 auto res = detail::conditionSmoothedStatesOnSharedState(
0146 trajectory, sharedState.index(), first.tipIndex(), sharedMean,
0147 sharedCov, logger());
0148 if (!res.ok()) {
0149 ACTS_DEBUG("Conditioning of the first tracklet failed: "
0150 << res.error().message());
0151 return res.error();
0152 }
0153 } else {
0154 detail::setSmoothedWithoutSharing(AnyMutableTrackStateProxy{sharedState},
0155 sharedMean, sharedCov);
0156 }
0157
0158 const auto tipIndex = first.tipIndex();
0159 detail::linkTrackletBehind(sharedState, second, m_cfg.invertJacobians);
0160 first.copyFromWithoutStates(second);
0161 first.tipIndex() = tipIndex;
0162 first.stemIndex() = second.stemIndex();
0163
0164 return Result<void>::success();
0165 }
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 template <typename smoother_t = MbfSmoother,
0182 TrackContainerFrontend track_container_t,
0183 TrackProxyConcept track_proxy_t,
0184 TrackStateProxyConcept track_state_proxy_t>
0185 Result<typename track_container_t::TrackProxy> joinCopy(
0186 const GeometryContext& gctx, track_container_t& out,
0187 const track_proxy_t& first, const track_state_proxy_t& sharedState,
0188 const track_proxy_t& second,
0189 const smoother_t& smoother = smoother_t{}) const {
0190 using TrackProxy = typename track_container_t::TrackProxy;
0191 using TrackStateProxy = typename track_container_t::TrackStateProxy;
0192
0193
0194 auto firstStates = first.trackStatesReversed();
0195 auto sharedIt = std::ranges::find_if(firstStates, [&](const auto& ts) {
0196 return ts.index() == sharedState.index();
0197 });
0198 if (sharedIt == firstStates.end()) {
0199 ACTS_DEBUG("Shared state " << sharedState.index()
0200 << " is not on the first tracklet");
0201 return Result<TrackProxy>::failure(KalmanFitterError::SmoothFailed);
0202 }
0203
0204 TrackProxy firstCopy = out.makeTrack();
0205 firstCopy.copyFrom(first);
0206 TrackProxy secondCopy = out.makeTrack();
0207 secondCopy.copyFrom(second);
0208
0209 auto copyStates = firstCopy.trackStatesReversed();
0210 TrackStateProxy sharedCopy = *std::ranges::next(
0211 copyStates.begin(),
0212 std::ranges::distance(firstStates.begin(), sharedIt));
0213
0214 auto res = joinInPlace(gctx, firstCopy, sharedCopy, secondCopy, smoother);
0215
0216 out.removeTrack(secondCopy.index());
0217 if (!res.ok()) {
0218 out.removeTrack(firstCopy.index());
0219 return Result<TrackProxy>::failure(res.error());
0220 }
0221 return firstCopy;
0222 }
0223
0224 private:
0225 const Logger& logger() const { return *m_logger; }
0226
0227 Config m_cfg;
0228 std::unique_ptr<const Logger> m_logger;
0229 };
0230
0231
0232
0233 }