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