File indexing completed on 2025-07-06 08:07:10
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/Definitions/Units.hpp"
0014 #include "Acts/EventData/MultiTrajectory.hpp"
0015 #include "Acts/EventData/MultiTrajectoryBackendConcept.hpp"
0016 #include "Acts/EventData/TrackContainerBackendConcept.hpp"
0017 #include "Acts/EventData/TrackProxy.hpp"
0018 #include "Acts/EventData/Types.hpp"
0019 #include "Acts/EventData/Utils.hpp"
0020 #include "Acts/Utilities/HashedString.hpp"
0021 #include "Acts/Utilities/Holders.hpp"
0022 #include "Acts/Utilities/UnitVectors.hpp"
0023
0024 #include <any>
0025 #include <cstddef>
0026 #include <iterator>
0027 #include <string_view>
0028
0029 namespace Acts {
0030
0031 template <typename T>
0032 struct IsReadOnlyTrackContainer;
0033
0034
0035
0036
0037
0038
0039
0040 template <TrackContainerBackend track_container_t,
0041 CommonMultiTrajectoryBackend traj_t,
0042 template <typename> class holder_t = detail::RefHolder>
0043 class TrackContainer {
0044 public:
0045
0046 static constexpr bool ReadOnly =
0047 IsReadOnlyTrackContainer<track_container_t>::value;
0048
0049
0050
0051 static constexpr bool TrackStateReadOnly =
0052 IsReadOnlyMultiTrajectory<traj_t>::value;
0053
0054 static_assert(ReadOnly == TrackStateReadOnly,
0055 "Either both track container and track state container need to "
0056 "be readonly or both have to be readwrite");
0057
0058
0059 using IndexType = TrackIndexType;
0060
0061
0062 static constexpr IndexType kInvalid = kTrackIndexInvalid;
0063
0064
0065
0066 using TrackProxy =
0067 Acts::TrackProxy<track_container_t, traj_t, holder_t, false>;
0068
0069
0070
0071 using ConstTrackProxy =
0072 Acts::TrackProxy<track_container_t, traj_t, holder_t, true>;
0073
0074 using TrackContainerBackend = track_container_t;
0075 using TrackStateContainerBackend = traj_t;
0076
0077 using TrackStateProxy = typename MultiTrajectory<traj_t>::TrackStateProxy;
0078 using ConstTrackStateProxy =
0079 typename MultiTrajectory<traj_t>::ConstTrackStateProxy;
0080
0081 #ifndef DOXYGEN
0082 friend TrackProxy;
0083 friend ConstTrackProxy;
0084 #endif
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101 TrackContainer(holder_t<track_container_t> container, holder_t<traj_t> traj)
0102 : m_container{std::move(container)}, m_traj{std::move(traj)} {}
0103
0104
0105
0106
0107
0108
0109
0110 TrackContainer(auto& container, auto& traj)
0111 requires(detail::is_same_template<holder_t, detail::RefHolder>::value)
0112 : m_container{&container}, m_traj{&traj} {}
0113
0114
0115
0116
0117
0118
0119
0120 TrackContainer(const auto& container, const auto& traj)
0121 requires(detail::is_same_template<holder_t,
0122 detail::ConstRefHolder>::value &&
0123 ReadOnly && TrackStateReadOnly)
0124 : m_container{&container}, m_traj{&traj} {}
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139 ConstTrackProxy getTrack(IndexType itrack) const { return {*this, itrack}; }
0140
0141
0142
0143
0144
0145 TrackProxy getTrack(IndexType itrack)
0146 requires(!ReadOnly)
0147 {
0148 return {*this, itrack};
0149 }
0150
0151
0152
0153
0154
0155 IndexType addTrack()
0156 requires(!ReadOnly)
0157 {
0158 auto track = getTrack(m_container->addTrack_impl());
0159 track.tipIndex() = kInvalid;
0160 return track.index();
0161 }
0162
0163
0164
0165
0166
0167 TrackProxy makeTrack()
0168 requires(!ReadOnly)
0169 {
0170 return getTrack(addTrack());
0171 }
0172
0173
0174
0175
0176
0177
0178 void removeTrack(IndexType itrack)
0179 requires(!ReadOnly)
0180 {
0181 m_container->removeTrack_impl(itrack);
0182 }
0183
0184
0185
0186
0187 auto begin()
0188 requires(!ReadOnly)
0189 {
0190 return detail_tc::TrackProxyIterator<std::decay_t<decltype(*this)>,
0191 TrackProxy, false>{*this, 0};
0192 }
0193
0194
0195
0196
0197 auto end()
0198 requires(!ReadOnly)
0199 {
0200 return detail_tc::TrackProxyIterator<std::decay_t<decltype(*this)>,
0201 TrackProxy, false>{*this, size()};
0202 }
0203
0204
0205
0206 auto begin() const {
0207 return detail_tc::TrackProxyIterator<std::decay_t<decltype(*this)>,
0208 ConstTrackProxy, true>{*this, 0};
0209 }
0210
0211
0212
0213 auto end() const {
0214 return detail_tc::TrackProxyIterator<std::decay_t<decltype(*this)>,
0215 ConstTrackProxy, true>{*this, size()};
0216 }
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230 template <typename T>
0231 constexpr void addColumn(std::string_view key)
0232 requires(!ReadOnly)
0233 {
0234 m_container->template addColumn_impl<T>(key);
0235 }
0236
0237
0238
0239 constexpr bool hasColumn(const std::string& key) const {
0240 return m_container->hasColumn_impl(hashString(key));
0241 }
0242
0243
0244
0245 constexpr bool hasColumn(HashedString key) const {
0246 return m_container->hasColumn_impl(key);
0247 }
0248
0249
0250
0251
0252
0253
0254
0255
0256 template <typename other_track_container_t>
0257 void ensureDynamicColumns(const other_track_container_t& other)
0258 requires(!ReadOnly)
0259 {
0260 container().ensureDynamicColumns_impl(other.container());
0261 }
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274 auto& container()
0275 requires(!ReadOnly)
0276 {
0277 return *m_container;
0278 }
0279
0280
0281
0282 const auto& container() const { return *m_container; }
0283
0284
0285
0286
0287 auto& trackStateContainer()
0288 requires(!ReadOnly)
0289 {
0290 return *m_traj;
0291 }
0292
0293
0294
0295
0296 auto& trackStateContainerHolder()
0297 requires(!ReadOnly)
0298 {
0299 return m_traj;
0300 }
0301
0302
0303
0304 const auto& trackStateContainer() const { return *m_traj; }
0305
0306
0307
0308 const auto& trackStateContainerHolder() const { return m_traj; }
0309
0310
0311
0312
0313
0314 constexpr IndexType size() const { return m_container->size_impl(); }
0315
0316
0317
0318 void clear()
0319 requires(!ReadOnly)
0320 {
0321 m_container->clear();
0322 m_traj->clear();
0323 }
0324
0325 protected:
0326 template <typename T, HashedString key>
0327 constexpr T& component(IndexType itrack)
0328 requires(!ReadOnly)
0329 {
0330 return *std::any_cast<T*>(container().component_impl(key, itrack));
0331 }
0332
0333 template <typename T>
0334 constexpr T& component(HashedString key, IndexType itrack)
0335 requires(!ReadOnly)
0336 {
0337 return *std::any_cast<T*>(container().component_impl(key, itrack));
0338 }
0339
0340 template <typename T, HashedString key>
0341 constexpr const T& component(IndexType itrack) const {
0342 return *std::any_cast<const T*>(container().component_impl(key, itrack));
0343 }
0344
0345 template <typename T>
0346 constexpr const T& component(HashedString key, IndexType itrack) const {
0347 return *std::any_cast<const T*>(container().component_impl(key, itrack));
0348 }
0349
0350 constexpr typename TrackProxy::Parameters parameters(IndexType itrack)
0351 requires(!ReadOnly)
0352 {
0353 return container().parameters(itrack);
0354 }
0355
0356 constexpr typename ConstTrackProxy::ConstParameters parameters(
0357 IndexType itrack) const {
0358 return container().parameters(itrack);
0359 }
0360
0361 constexpr typename TrackProxy::Covariance covariance(IndexType itrack)
0362 requires(!ReadOnly)
0363 {
0364 return container().covariance(itrack);
0365 }
0366
0367 constexpr typename ConstTrackProxy::ConstCovariance covariance(
0368 IndexType itrack) const {
0369 return container().covariance(itrack);
0370 }
0371
0372 auto reverseTrackStateRange(IndexType itrack)
0373 requires(!ReadOnly)
0374 {
0375 auto tip = component<IndexType, hashString("tipIndex")>(itrack);
0376 return m_traj->reverseTrackStateRange(tip);
0377 }
0378
0379 auto reverseTrackStateRange(IndexType itrack) const {
0380 auto tip = component<IndexType, hashString("tipIndex")>(itrack);
0381 return m_traj->reverseTrackStateRange(tip);
0382 }
0383
0384 auto forwardTrackStateRange(IndexType itrack)
0385 requires(!ReadOnly)
0386 {
0387 auto stem = component<IndexType, hashString("stemIndex")>(itrack);
0388 if (stem == kInvalid) {
0389 throw std::invalid_argument{"Track has no stem index"};
0390 }
0391 return m_traj->forwardTrackStateRange(stem);
0392 }
0393
0394 auto forwardTrackStateRange(IndexType itrack) const {
0395 auto stem = component<IndexType, hashString("stemIndex")>(itrack);
0396 if (stem == kInvalid) {
0397 throw std::invalid_argument{"Track has no stem index"};
0398 }
0399 return m_traj->forwardTrackStateRange(stem);
0400 }
0401
0402 private:
0403 template <typename T>
0404 void copyDynamicFrom(IndexType dstIdx, const T& src, IndexType srcIdx)
0405 requires(!ReadOnly)
0406 {
0407 const auto& dynamicKeys = src.dynamicKeys_impl();
0408 for (const auto key : dynamicKeys) {
0409 std::any srcPtr = src.component_impl(key, srcIdx);
0410 container().copyDynamicFrom_impl(dstIdx, key, srcPtr);
0411 }
0412 }
0413
0414 detail_tc::ConstIf<holder_t<track_container_t>, ReadOnly> m_container;
0415 detail_tc::ConstIf<holder_t<traj_t>, ReadOnly> m_traj;
0416 };
0417
0418 template <TrackContainerBackend track_container_t, typename traj_t>
0419 TrackContainer(track_container_t& container, traj_t& traj)
0420 -> TrackContainer<track_container_t, traj_t, detail::RefHolder>;
0421
0422 template <TrackContainerBackend track_container_t, typename traj_t>
0423 TrackContainer(const track_container_t& container, const traj_t& traj)
0424 -> TrackContainer<track_container_t, traj_t, detail::ConstRefHolder>;
0425
0426 template <TrackContainerBackend track_container_t, typename traj_t>
0427 TrackContainer(track_container_t&& container, traj_t&& traj)
0428 -> TrackContainer<track_container_t, traj_t, detail::ValueHolder>;
0429
0430 }