File indexing completed on 2025-09-18 08:33:17
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/EventData/MultiTrajectory.hpp"
0012 #include "Acts/EventData/MultiTrajectoryBackendConcept.hpp"
0013 #include "Acts/EventData/TrackContainer.hpp"
0014 #include "Acts/EventData/TrackStatePropMask.hpp"
0015 #include "Acts/EventData/Types.hpp"
0016 #include "Acts/EventData/detail/DynamicKeyIterator.hpp"
0017 #include "Acts/Plugins/Podio/PodioDynamicColumns.hpp"
0018 #include "Acts/Plugins/Podio/PodioTrackContainer.hpp"
0019 #include "Acts/Plugins/Podio/PodioUtil.hpp"
0020 #include "Acts/Utilities/HashedString.hpp"
0021 #include "Acts/Utilities/Helpers.hpp"
0022
0023 #pragma GCC diagnostic push
0024 #pragma GCC diagnostic ignored "-Wold-style-cast"
0025 #include "ActsPodioEdm/BoundParametersCollection.h"
0026 #include "ActsPodioEdm/JacobianCollection.h"
0027 #include "ActsPodioEdm/TrackStateCollection.h"
0028 #include "ActsPodioEdm/TrackStateInfo.h"
0029 #pragma GCC diagnostic pop
0030
0031 #include <any>
0032 #include <memory>
0033 #include <stdexcept>
0034 #include <tuple>
0035 #include <type_traits>
0036
0037 #include <podio/CollectionBase.h>
0038 #include <podio/Frame.h>
0039
0040 namespace Acts {
0041
0042 class MutablePodioTrackStateContainer;
0043 class ConstPodioTrackStateContainer;
0044
0045 class PodioTrackStateContainerBase {
0046 public:
0047 using Parameters =
0048 typename detail_lt::FixedSizeTypes<eBoundSize, false>::CoefficientsMap;
0049 using Covariance =
0050 typename detail_lt::FixedSizeTypes<eBoundSize, false>::CovarianceMap;
0051
0052 using ConstParameters =
0053 typename detail_lt::FixedSizeTypes<eBoundSize, true>::CoefficientsMap;
0054 using ConstCovariance =
0055 typename detail_lt::FixedSizeTypes<eBoundSize, true>::CovarianceMap;
0056
0057 protected:
0058 template <typename T>
0059 static constexpr bool has_impl(T& instance, HashedString key,
0060 TrackIndexType istate) {
0061 constexpr auto kInvalid = MultiTrajectoryTraits::kInvalid;
0062 using namespace Acts::HashedStringLiteral;
0063 auto trackState = instance.m_collection->at(istate);
0064 const auto& data = trackState.getData();
0065 switch (key) {
0066 case "predicted"_hash:
0067 return data.ipredicted != kInvalid;
0068 case "filtered"_hash:
0069 return data.ifiltered != kInvalid;
0070 case "smoothed"_hash:
0071 return data.ismoothed != kInvalid;
0072 case "calibrated"_hash:
0073 return data.measdim != kInvalid;
0074 case "calibratedCov"_hash:
0075 return data.measdim != kInvalid;
0076 case "jacobian"_hash:
0077 return data.ijacobian != kInvalid;
0078 case "projector"_hash:
0079 return data.hasProjector;
0080 case "uncalibratedSourceLink"_hash:
0081 return data.uncalibratedIdentifier != PodioUtil::kNoIdentifier;
0082 case "previous"_hash:
0083 case "next"_hash:
0084 case "measdim"_hash:
0085 case "referenceSurface"_hash:
0086 case "chi2"_hash:
0087 case "pathLength"_hash:
0088 case "typeFlags"_hash:
0089 return true;
0090 default:
0091 return instance.m_dynamic.contains(key);
0092 }
0093
0094 return false;
0095 }
0096
0097 template <bool EnsureConst, typename T>
0098 static std::any component_impl(T& instance, HashedString key,
0099 TrackIndexType istate) {
0100 if constexpr (EnsureConst) {
0101 static_assert(std::is_const_v<std::remove_reference_t<T>>,
0102 "Is not const");
0103 }
0104 using namespace Acts::HashedStringLiteral;
0105 auto trackState = instance.m_collection->at(istate);
0106 std::conditional_t<EnsureConst, const ActsPodioEdm::TrackStateInfo*,
0107 ActsPodioEdm::TrackStateInfo*>
0108 dataPtr;
0109 if constexpr (EnsureConst) {
0110 dataPtr = &trackState.getData();
0111 } else {
0112 dataPtr = &PodioUtil::getDataMutable(trackState);
0113 }
0114 auto& data = *dataPtr;
0115 switch (key) {
0116 case "previous"_hash:
0117 return &data.previous;
0118 case "next"_hash:
0119 return &data.next;
0120 case "predicted"_hash:
0121 return &data.ipredicted;
0122 case "filtered"_hash:
0123 return &data.ifiltered;
0124 case "smoothed"_hash:
0125 return &data.ismoothed;
0126 case "projector"_hash:
0127 return &data.projector;
0128 case "measdim"_hash:
0129 return &data.measdim;
0130 case "chi2"_hash:
0131 return &data.chi2;
0132 case "pathLength"_hash:
0133 return &data.pathLength;
0134 case "typeFlags"_hash:
0135 return &data.typeFlags;
0136 default:
0137 auto it = instance.m_dynamic.find(key);
0138 if (it == instance.m_dynamic.end()) {
0139 throw std::runtime_error("Unable to handle this component");
0140 }
0141 std::conditional_t<EnsureConst,
0142 const podio_detail::ConstDynamicColumnBase*,
0143 podio_detail::DynamicColumnBase*>
0144 col = it->second.get();
0145 assert(col && "Dynamic column is null");
0146 return col->get(istate);
0147 }
0148 }
0149
0150 template <typename T>
0151 static constexpr bool hasColumn_impl(T& instance, HashedString key) {
0152 using namespace Acts::HashedStringLiteral;
0153 switch (key) {
0154 case "predicted"_hash:
0155 case "filtered"_hash:
0156 case "smoothed"_hash:
0157 case "jacobian"_hash:
0158 case "projector"_hash:
0159 case "previous"_hash:
0160 case "next"_hash:
0161 case "uncalibratedSourceLink"_hash:
0162 case "referenceSurface"_hash:
0163 case "measdim"_hash:
0164 case "chi2"_hash:
0165 case "pathLength"_hash:
0166 case "typeFlags"_hash:
0167 return true;
0168 default:
0169 return instance.m_dynamic.contains(key);
0170 }
0171 }
0172
0173 static void populateSurfaceBuffer(
0174 const PodioUtil::ConversionHelper& helper,
0175 const ActsPodioEdm::TrackStateCollection& collection,
0176 std::vector<std::shared_ptr<const Surface>>& surfaces) noexcept {
0177 surfaces.reserve(collection.size());
0178 for (ActsPodioEdm::TrackState trackState : collection) {
0179 surfaces.push_back(PodioUtil::convertSurfaceFromPodio(
0180 helper, trackState.getReferenceSurface()));
0181 }
0182 }
0183 };
0184
0185 template <>
0186 struct IsReadOnlyMultiTrajectory<ConstPodioTrackStateContainer>
0187 : std::true_type {};
0188
0189 class ConstPodioTrackStateContainer final
0190 : public PodioTrackStateContainerBase,
0191 public MultiTrajectory<ConstPodioTrackStateContainer> {
0192 public:
0193 ConstPodioTrackStateContainer(
0194 const PodioUtil::ConversionHelper& helper,
0195 const ActsPodioEdm::TrackStateCollection& trackStates,
0196 const ActsPodioEdm::BoundParametersCollection& params,
0197 const ActsPodioEdm::JacobianCollection& jacs)
0198 : m_helper{helper},
0199 m_collection{&trackStates},
0200 m_params{¶ms},
0201 m_jacs{&jacs} {
0202
0203 populateSurfaceBuffer(m_helper, *m_collection, m_surfaces);
0204 }
0205
0206
0207
0208
0209
0210 ConstPodioTrackStateContainer(const MutablePodioTrackStateContainer& other);
0211
0212 ConstPodioTrackStateContainer(const PodioUtil::ConversionHelper& helper,
0213 const podio::Frame& frame,
0214 const std::string& suffix = "")
0215 : m_helper{helper},
0216 m_collection{nullptr},
0217 m_params{nullptr},
0218 m_jacs{nullptr} {
0219 std::string s = suffix.empty() ? suffix : "_" + suffix;
0220
0221 std::vector<std::string> available = frame.getAvailableCollections();
0222
0223 std::string trackStatesKey = "trackStates" + s;
0224 std::string paramsKey = "trackStateParameters" + s;
0225 std::string jacsKey = "trackStateJacobians" + s;
0226
0227 if (!rangeContainsValue(available, trackStatesKey)) {
0228 throw std::runtime_error{"Track state collection '" + trackStatesKey +
0229 "' not found in frame"};
0230 }
0231
0232 if (!rangeContainsValue(available, paramsKey)) {
0233 throw std::runtime_error{"Track state parameters collection '" +
0234 paramsKey + "' not found in frame"};
0235 }
0236
0237 if (!rangeContainsValue(available, jacsKey)) {
0238 throw std::runtime_error{"Track state jacobian collection '" + jacsKey +
0239 "' not found in frame"};
0240 }
0241
0242 loadCollection<ActsPodioEdm::TrackStateCollection>(m_collection, frame,
0243 trackStatesKey);
0244 loadCollection<ActsPodioEdm::BoundParametersCollection>(m_params, frame,
0245 paramsKey);
0246 loadCollection<ActsPodioEdm::JacobianCollection>(m_jacs, frame, jacsKey);
0247
0248 populateSurfaceBuffer(m_helper, *m_collection, m_surfaces);
0249
0250 podio_detail::recoverDynamicColumns(frame, trackStatesKey, m_dynamic);
0251 }
0252
0253 detail::DynamicKeyRange<podio_detail::ConstDynamicColumnBase>
0254 dynamicKeys_impl() const {
0255 return {m_dynamic.begin(), m_dynamic.end()};
0256 }
0257
0258 private:
0259 template <typename collection_t>
0260 static void loadCollection(collection_t const*& dest,
0261 const podio::Frame& frame,
0262 const std::string& key) {
0263 const auto* collection = frame.get(key);
0264
0265 if (const auto* d = dynamic_cast<const collection_t*>(collection);
0266 d != nullptr) {
0267 dest = d;
0268 } else {
0269 throw std::runtime_error{"Unable to get collection " + key};
0270 }
0271 }
0272
0273 public:
0274 ConstParameters parameters_impl(IndexType istate) const {
0275 return ConstParameters{m_params->at(istate).getData().values.data()};
0276 }
0277
0278 ConstCovariance covariance_impl(IndexType istate) const {
0279 return ConstCovariance{m_params->at(istate).getData().covariance.data()};
0280 }
0281
0282 ConstCovariance jacobian_impl(IndexType istate) const {
0283 IndexType ijacobian = m_collection->at(istate).getData().ijacobian;
0284 return ConstCovariance{m_jacs->at(ijacobian).getData().values.data()};
0285 }
0286
0287 template <std::size_t measdim>
0288 ConstTrackStateProxy::Calibrated<measdim> calibrated_impl(
0289 IndexType index) const {
0290 return ConstTrackStateProxy::Calibrated<measdim>{
0291 m_collection->at(index).getData().measurement.data()};
0292 }
0293
0294 template <std::size_t measdim>
0295 ConstTrackStateProxy::CalibratedCovariance<measdim> calibratedCovariance_impl(
0296 IndexType index) const {
0297 return ConstTrackStateProxy::CalibratedCovariance<measdim>{
0298 m_collection->at(index).getData().measurementCovariance.data()};
0299 }
0300
0301 IndexType size_impl() const { return m_collection->size(); }
0302
0303 std::any component_impl(HashedString key, IndexType istate) const {
0304 return PodioTrackStateContainerBase::component_impl<true>(*this, key,
0305 istate);
0306 }
0307
0308 constexpr bool hasColumn_impl(HashedString key) const {
0309 return PodioTrackStateContainerBase::hasColumn_impl(*this, key);
0310 }
0311
0312 constexpr bool has_impl(HashedString key, IndexType istate) const {
0313 return PodioTrackStateContainerBase::has_impl(*this, key, istate);
0314 }
0315
0316 MultiTrajectoryTraits::IndexType calibratedSize_impl(IndexType istate) const {
0317 return m_collection->at(istate).getData().measdim;
0318 }
0319
0320 SourceLink getUncalibratedSourceLink_impl(IndexType istate) const {
0321 return m_helper.get().identifierToSourceLink(
0322 m_collection->at(istate).getData().uncalibratedIdentifier);
0323 }
0324
0325 const Surface* referenceSurface_impl(IndexType istate) const {
0326 return m_surfaces.at(istate).get();
0327 }
0328
0329 private:
0330 friend class PodioTrackStateContainerBase;
0331
0332 std::reference_wrapper<const PodioUtil::ConversionHelper> m_helper;
0333 const ActsPodioEdm::TrackStateCollection* m_collection;
0334 const ActsPodioEdm::BoundParametersCollection* m_params;
0335 const ActsPodioEdm::JacobianCollection* m_jacs;
0336 std::vector<std::shared_ptr<const Surface>> m_surfaces;
0337
0338 std::unordered_map<HashedString,
0339 std::unique_ptr<podio_detail::ConstDynamicColumnBase>>
0340 m_dynamic;
0341 std::vector<HashedString> m_dynamicKeys;
0342 };
0343
0344 static_assert(IsReadOnlyMultiTrajectory<ConstPodioTrackStateContainer>::value,
0345 "MutablePodioTrackStateContainer should not be read-only");
0346
0347 static_assert(
0348 ConstMultiTrajectoryBackend<ConstPodioTrackStateContainer>,
0349 "ConstPodioTrackStateContainer does not fulfill TrackContainerBackend");
0350
0351 template <>
0352 struct IsReadOnlyMultiTrajectory<MutablePodioTrackStateContainer>
0353 : std::false_type {};
0354
0355 class MutablePodioTrackStateContainer final
0356 : public PodioTrackStateContainerBase,
0357 public MultiTrajectory<MutablePodioTrackStateContainer> {
0358 public:
0359 MutablePodioTrackStateContainer(PodioUtil::ConversionHelper& helper)
0360 : m_helper{helper} {
0361 m_collection = std::make_unique<ActsPodioEdm::TrackStateCollection>();
0362 m_jacs = std::make_unique<ActsPodioEdm::JacobianCollection>();
0363 m_params = std::make_unique<ActsPodioEdm::BoundParametersCollection>();
0364
0365 populateSurfaceBuffer(m_helper, *m_collection, m_surfaces);
0366 }
0367
0368 ConstParameters parameters_impl(IndexType istate) const {
0369 return ConstParameters{m_params->at(istate).getData().values.data()};
0370 }
0371
0372 Parameters parameters_impl(IndexType istate) {
0373 return Parameters{
0374 PodioUtil::getDataMutable(m_params->at(istate)).values.data()};
0375 }
0376
0377 ConstCovariance covariance_impl(IndexType istate) const {
0378 return ConstCovariance{m_params->at(istate).getData().covariance.data()};
0379 }
0380
0381 Covariance covariance_impl(IndexType istate) {
0382 return Covariance{
0383 PodioUtil::getDataMutable(m_params->at(istate)).covariance.data()};
0384 }
0385
0386 ConstCovariance jacobian_impl(IndexType istate) const {
0387 IndexType ijacobian = m_collection->at(istate).getData().ijacobian;
0388 return ConstCovariance{m_jacs->at(ijacobian).getData().values.data()};
0389 }
0390
0391 Covariance jacobian_impl(IndexType istate) {
0392 IndexType ijacobian = m_collection->at(istate).getData().ijacobian;
0393 return Covariance{
0394 PodioUtil::getDataMutable(m_jacs->at(ijacobian)).values.data()};
0395 }
0396
0397 template <std::size_t measdim>
0398 ConstTrackStateProxy::Calibrated<measdim> calibrated_impl(
0399 IndexType index) const {
0400 return ConstTrackStateProxy::Calibrated<measdim>{
0401 m_collection->at(index).getData().measurement.data()};
0402 }
0403
0404 template <std::size_t measdim>
0405 TrackStateProxy::Calibrated<measdim> calibrated_impl(IndexType index) {
0406 return TrackStateProxy::Calibrated<measdim>{
0407 PodioUtil::getDataMutable(m_collection->at(index)).measurement.data()};
0408 }
0409
0410 template <std::size_t measdim>
0411 ConstTrackStateProxy::CalibratedCovariance<measdim> calibratedCovariance_impl(
0412 IndexType index) const {
0413 return ConstTrackStateProxy::CalibratedCovariance<measdim>{
0414 m_collection->at(index).getData().measurementCovariance.data()};
0415 }
0416
0417 template <std::size_t measdim>
0418 TrackStateProxy::CalibratedCovariance<measdim> calibratedCovariance_impl(
0419 IndexType index) {
0420 return TrackStateProxy::CalibratedCovariance<measdim>{
0421 PodioUtil::getDataMutable(m_collection->at(index))
0422 .measurementCovariance.data()};
0423 }
0424
0425 IndexType size_impl() const { return m_collection->size(); }
0426
0427 std::any component_impl(HashedString key, IndexType istate) const {
0428 return PodioTrackStateContainerBase::component_impl<true>(*this, key,
0429 istate);
0430 }
0431
0432 std::any component_impl(HashedString key, IndexType istate) {
0433 return PodioTrackStateContainerBase::component_impl<false>(*this, key,
0434 istate);
0435 }
0436
0437 constexpr bool hasColumn_impl(HashedString key) const {
0438 return PodioTrackStateContainerBase::hasColumn_impl(*this, key);
0439 }
0440
0441 constexpr bool has_impl(HashedString key, IndexType istate) const {
0442 return PodioTrackStateContainerBase::has_impl(*this, key, istate);
0443 }
0444
0445 IndexType addTrackState_impl(
0446 TrackStatePropMask mask = TrackStatePropMask::All,
0447 TrackIndexType iprevious = kTrackIndexInvalid) {
0448 auto trackState = m_collection->create();
0449 auto& data = PodioUtil::getDataMutable(trackState);
0450 data.previous = iprevious;
0451 data.ipredicted = kInvalid;
0452 data.ifiltered = kInvalid;
0453 data.ismoothed = kInvalid;
0454 data.ijacobian = kInvalid;
0455
0456 PodioUtil::getReferenceSurfaceMutable(trackState).surfaceType =
0457 PodioUtil::kNoSurface;
0458
0459 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Predicted)) {
0460 m_params->create();
0461 data.ipredicted = m_params->size() - 1;
0462 }
0463 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Filtered)) {
0464 m_params->create();
0465 data.ifiltered = m_params->size() - 1;
0466 }
0467 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Smoothed)) {
0468 m_params->create();
0469 data.ismoothed = m_params->size() - 1;
0470 }
0471 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Jacobian)) {
0472 m_jacs->create();
0473 data.ijacobian = m_jacs->size() - 1;
0474 }
0475 data.measdim = kInvalid;
0476 data.hasProjector = false;
0477 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Calibrated)) {
0478 data.hasProjector = true;
0479 }
0480 m_surfaces.emplace_back();
0481
0482 data.uncalibratedIdentifier = PodioUtil::kNoIdentifier;
0483 assert(m_collection->size() == m_surfaces.size() &&
0484 "Inconsistent surface buffer");
0485
0486 for (const auto& [key, vec] : m_dynamic) {
0487 vec->add();
0488 }
0489
0490 return m_collection->size() - 1;
0491 }
0492
0493 void addTrackStateComponents_impl(IndexType istate, TrackStatePropMask mask) {
0494 auto& data = PodioUtil::getDataMutable(m_collection->at(istate));
0495
0496 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Predicted) &&
0497 data.ipredicted == kInvalid) {
0498 m_params->create();
0499 data.ipredicted = m_params->size() - 1;
0500 }
0501
0502 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Filtered) &&
0503 data.ifiltered == kInvalid) {
0504 m_params->create();
0505 data.ifiltered = m_params->size() - 1;
0506 }
0507
0508 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Smoothed) &&
0509 data.ismoothed == kInvalid) {
0510 m_params->create();
0511 data.ismoothed = m_params->size() - 1;
0512 }
0513
0514 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Jacobian) &&
0515 data.ijacobian == kInvalid) {
0516 m_jacs->create();
0517 data.ijacobian = m_jacs->size() - 1;
0518 }
0519
0520 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Calibrated) &&
0521 !data.hasProjector) {
0522 data.hasProjector = true;
0523 }
0524 }
0525
0526 void shareFrom_impl(TrackIndexType iself, TrackIndexType iother,
0527 TrackStatePropMask shareSource,
0528 TrackStatePropMask shareTarget) {
0529 auto& self = PodioUtil::getDataMutable(m_collection->at(iself));
0530 auto& other = PodioUtil::getDataMutable(m_collection->at(iother));
0531
0532 assert(ACTS_CHECK_BIT(getTrackState(iother).getMask(), shareSource) &&
0533 "Source has incompatible allocation");
0534
0535 using PM = TrackStatePropMask;
0536
0537 IndexType sourceIndex{kInvalid};
0538 switch (shareSource) {
0539 case PM::Predicted:
0540 sourceIndex = other.ipredicted;
0541 break;
0542 case PM::Filtered:
0543 sourceIndex = other.ifiltered;
0544 break;
0545 case PM::Smoothed:
0546 sourceIndex = other.ismoothed;
0547 break;
0548 case PM::Jacobian:
0549 sourceIndex = other.ijacobian;
0550 break;
0551 default:
0552 throw std::domain_error{"Unable to share this component"};
0553 }
0554
0555 assert(sourceIndex != kInvalid);
0556
0557 switch (shareTarget) {
0558 case PM::Predicted:
0559 assert(shareSource != PM::Jacobian);
0560 self.ipredicted = sourceIndex;
0561 break;
0562 case PM::Filtered:
0563 assert(shareSource != PM::Jacobian);
0564 self.ifiltered = sourceIndex;
0565 break;
0566 case PM::Smoothed:
0567 assert(shareSource != PM::Jacobian);
0568 self.ismoothed = sourceIndex;
0569 break;
0570 case PM::Jacobian:
0571 assert(shareSource == PM::Jacobian);
0572 self.ijacobian = sourceIndex;
0573 break;
0574 default:
0575 throw std::domain_error{"Unable to share this component"};
0576 }
0577 }
0578
0579 void unset_impl(TrackStatePropMask target, TrackIndexType istate) {
0580 auto& data = PodioUtil::getDataMutable(m_collection->at(istate));
0581 switch (target) {
0582 case TrackStatePropMask::Predicted:
0583 data.ipredicted = kInvalid;
0584 break;
0585 case TrackStatePropMask::Filtered:
0586 data.ifiltered = kInvalid;
0587 break;
0588 case TrackStatePropMask::Smoothed:
0589 data.ismoothed = kInvalid;
0590 break;
0591 case TrackStatePropMask::Jacobian:
0592 data.ijacobian = kInvalid;
0593 break;
0594 case TrackStatePropMask::Calibrated:
0595 data.measdim = kInvalid;
0596 break;
0597 default:
0598 throw std::domain_error{"Unable to unset this component"};
0599 }
0600 }
0601
0602 void clear_impl() {
0603 m_collection->clear();
0604 m_params->clear();
0605 m_surfaces.clear();
0606 for (const auto& [key, vec] : m_dynamic) {
0607 vec->clear();
0608 }
0609 }
0610
0611 template <typename T>
0612 constexpr void addColumn_impl(std::string_view key) {
0613 HashedString hashedKey = hashStringDynamic(key);
0614 m_dynamic.insert(
0615 {hashedKey, std::make_unique<podio_detail::DynamicColumn<T>>(key)});
0616 }
0617
0618 template <typename val_t, typename cov_t>
0619 void allocateCalibrated_impl(IndexType istate,
0620 const Eigen::DenseBase<val_t>& val,
0621 const Eigen::DenseBase<cov_t>& cov)
0622 requires(Concepts::eigen_base_is_fixed_size<val_t> &&
0623 Eigen::PlainObjectBase<val_t>::RowsAtCompileTime <=
0624 toUnderlying(eBoundSize) &&
0625 Concepts::eigen_bases_have_same_num_rows<val_t, cov_t> &&
0626 Concepts::eigen_base_is_square<cov_t>)
0627 {
0628 constexpr std::size_t measdim = val_t::RowsAtCompileTime;
0629
0630 auto& data = PodioUtil::getDataMutable(m_collection->at(istate));
0631
0632 if (data.measdim != kInvalid && data.measdim != measdim) {
0633 throw std::invalid_argument{
0634 "Measurement dimension does not match the allocated dimension"};
0635 }
0636
0637 data.measdim = measdim;
0638
0639 Eigen::Map<ActsVector<measdim>> valMap(data.measurement.data());
0640 valMap = val;
0641
0642 Eigen::Map<ActsSquareMatrix<measdim>> covMap(
0643 data.measurementCovariance.data());
0644 covMap = cov;
0645 }
0646
0647 void setUncalibratedSourceLink_impl(IndexType istate,
0648 const SourceLink& sourceLink) {
0649 PodioUtil::Identifier id =
0650 m_helper.get().sourceLinkToIdentifier(sourceLink);
0651 auto& data = PodioUtil::getDataMutable(m_collection->at(istate));
0652 data.uncalibratedIdentifier = id;
0653 }
0654
0655 void setReferenceSurface_impl(IndexType istate,
0656 std::shared_ptr<const Surface> surface) {
0657 auto trackState = m_collection->at(istate);
0658 trackState.setReferenceSurface(
0659 PodioUtil::convertSurfaceToPodio(m_helper, *surface));
0660 m_surfaces.at(istate) = std::move(surface);
0661 }
0662
0663 MultiTrajectoryTraits::IndexType calibratedSize_impl(IndexType istate) const {
0664 return m_collection->at(istate).getData().measdim;
0665 }
0666
0667 SourceLink getUncalibratedSourceLink_impl(IndexType istate) const {
0668 return m_helper.get().identifierToSourceLink(
0669 m_collection->at(istate).getData().uncalibratedIdentifier);
0670 }
0671
0672 const Surface* referenceSurface_impl(IndexType istate) const {
0673 return m_surfaces.at(istate).get();
0674 }
0675
0676 void releaseInto(podio::Frame& frame, const std::string& suffix = "") {
0677 std::string s = suffix;
0678 if (!s.empty()) {
0679 s = "_" + s;
0680 }
0681 frame.put(std::move(m_collection), "trackStates" + s);
0682 frame.put(std::move(m_params), "trackStateParameters" + s);
0683 frame.put(std::move(m_jacs), "trackStateJacobians" + s);
0684 m_surfaces.clear();
0685
0686 for (const auto& [key, col] : m_dynamic) {
0687 col->releaseInto(frame, "trackStates" + s + "_extra__");
0688 }
0689
0690 m_dynamic.clear();
0691 }
0692
0693 detail::DynamicKeyRange<podio_detail::DynamicColumnBase> dynamicKeys_impl()
0694 const {
0695 return {m_dynamic.begin(), m_dynamic.end()};
0696 }
0697
0698 void copyDynamicFrom_impl(IndexType dstIdx, HashedString key,
0699 const std::any& srcPtr) {
0700 auto it = m_dynamic.find(key);
0701 if (it == m_dynamic.end()) {
0702 throw std::invalid_argument{
0703 "Destination container does not have matching dynamic column"};
0704 }
0705
0706 it->second->copyFrom(dstIdx, srcPtr);
0707 }
0708
0709 private:
0710 friend class PodioTrackStateContainerBase;
0711 friend class ConstPodioTrackStateContainer;
0712
0713 std::reference_wrapper<PodioUtil::ConversionHelper> m_helper;
0714 std::unique_ptr<ActsPodioEdm::TrackStateCollection> m_collection;
0715 std::unique_ptr<ActsPodioEdm::BoundParametersCollection> m_params;
0716 std::unique_ptr<ActsPodioEdm::JacobianCollection> m_jacs;
0717 std::vector<std::shared_ptr<const Surface>> m_surfaces;
0718
0719 std::unordered_map<HashedString,
0720 std::unique_ptr<podio_detail::DynamicColumnBase>>
0721 m_dynamic;
0722 std::vector<HashedString> m_dynamicKeys;
0723 };
0724
0725 static_assert(
0726 !IsReadOnlyMultiTrajectory<MutablePodioTrackStateContainer>::value,
0727 "MutablePodioTrackStateContainer should not be read-only");
0728
0729 static_assert(MutableMultiTrajectoryBackend<MutablePodioTrackStateContainer>,
0730 "MutablePodioTrackStateContainer does not fulfill "
0731 "TrackStateContainerBackend");
0732
0733 inline ConstPodioTrackStateContainer::ConstPodioTrackStateContainer(
0734 const MutablePodioTrackStateContainer& other)
0735 : m_helper{other.m_helper},
0736 m_collection{other.m_collection.get()},
0737 m_params{other.m_params.get()},
0738 m_jacs{other.m_jacs.get()},
0739 m_surfaces{other.m_surfaces} {
0740 for (const auto& [key, col] : other.m_dynamic) {
0741 m_dynamic.insert({key, col->asConst()});
0742 }
0743 }
0744
0745 }