File indexing completed on 2025-07-01 08:07:53
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 != 0;
0074 case "calibratedCov"_hash:
0075 return data.measdim != 0;
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.find(key) != instance.m_dynamic.end();
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.find(key) != instance.m_dynamic.end();
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 (std::find(available.begin(), available.end(), trackStatesKey) ==
0228 available.end()) {
0229 throw std::runtime_error{"Track state collection '" + trackStatesKey +
0230 "' not found in frame"};
0231 }
0232
0233 if (std::find(available.begin(), available.end(), paramsKey) ==
0234 available.end()) {
0235 throw std::runtime_error{"Track state parameters collection '" +
0236 paramsKey + "' not found in frame"};
0237 }
0238
0239 if (std::find(available.begin(), available.end(), jacsKey) ==
0240 available.end()) {
0241 throw std::runtime_error{"Track state jacobian collection '" + jacsKey +
0242 "' not found in frame"};
0243 }
0244
0245 loadCollection<ActsPodioEdm::TrackStateCollection>(m_collection, frame,
0246 trackStatesKey);
0247 loadCollection<ActsPodioEdm::BoundParametersCollection>(m_params, frame,
0248 paramsKey);
0249 loadCollection<ActsPodioEdm::JacobianCollection>(m_jacs, frame, jacsKey);
0250
0251 populateSurfaceBuffer(m_helper, *m_collection, m_surfaces);
0252
0253 podio_detail::recoverDynamicColumns(frame, trackStatesKey, m_dynamic);
0254 }
0255
0256 detail::DynamicKeyRange<podio_detail::ConstDynamicColumnBase>
0257 dynamicKeys_impl() const {
0258 return {m_dynamic.begin(), m_dynamic.end()};
0259 }
0260
0261 private:
0262 template <typename collection_t>
0263 static void loadCollection(collection_t const*& dest,
0264 const podio::Frame& frame,
0265 const std::string& key) {
0266 const auto* collection = frame.get(key);
0267
0268 if (const auto* d = dynamic_cast<const collection_t*>(collection);
0269 d != nullptr) {
0270 dest = d;
0271 } else {
0272 throw std::runtime_error{"Unable to get collection " + key};
0273 }
0274 }
0275
0276 public:
0277 ConstParameters parameters_impl(IndexType istate) const {
0278 return ConstParameters{m_params->at(istate).getData().values.data()};
0279 }
0280
0281 ConstCovariance covariance_impl(IndexType istate) const {
0282 return ConstCovariance{m_params->at(istate).getData().covariance.data()};
0283 }
0284
0285 ConstCovariance jacobian_impl(IndexType istate) const {
0286 IndexType ijacobian = m_collection->at(istate).getData().ijacobian;
0287 return ConstCovariance{m_jacs->at(ijacobian).getData().values.data()};
0288 }
0289
0290 template <std::size_t measdim>
0291 ConstTrackStateProxy::Calibrated<measdim> calibrated_impl(
0292 IndexType index) const {
0293 return ConstTrackStateProxy::Calibrated<measdim>{
0294 m_collection->at(index).getData().measurement.data()};
0295 }
0296
0297 template <std::size_t measdim>
0298 ConstTrackStateProxy::CalibratedCovariance<measdim> calibratedCovariance_impl(
0299 IndexType index) const {
0300 return ConstTrackStateProxy::CalibratedCovariance<measdim>{
0301 m_collection->at(index).getData().measurementCovariance.data()};
0302 }
0303
0304 IndexType size_impl() const { return m_collection->size(); }
0305
0306 std::any component_impl(HashedString key, IndexType istate) const {
0307 return PodioTrackStateContainerBase::component_impl<true>(*this, key,
0308 istate);
0309 }
0310
0311 constexpr bool hasColumn_impl(HashedString key) const {
0312 return PodioTrackStateContainerBase::hasColumn_impl(*this, key);
0313 }
0314
0315 constexpr bool has_impl(HashedString key, IndexType istate) const {
0316 return PodioTrackStateContainerBase::has_impl(*this, key, istate);
0317 }
0318
0319 MultiTrajectoryTraits::IndexType calibratedSize_impl(IndexType istate) const {
0320 return m_collection->at(istate).getData().measdim;
0321 }
0322
0323 SourceLink getUncalibratedSourceLink_impl(IndexType istate) const {
0324 return m_helper.get().identifierToSourceLink(
0325 m_collection->at(istate).getData().uncalibratedIdentifier);
0326 }
0327
0328 const Surface* referenceSurface_impl(IndexType istate) const {
0329 return m_surfaces.at(istate).get();
0330 }
0331
0332 private:
0333 friend class PodioTrackStateContainerBase;
0334
0335 std::reference_wrapper<const PodioUtil::ConversionHelper> m_helper;
0336 const ActsPodioEdm::TrackStateCollection* m_collection;
0337 const ActsPodioEdm::BoundParametersCollection* m_params;
0338 const ActsPodioEdm::JacobianCollection* m_jacs;
0339 std::vector<std::shared_ptr<const Surface>> m_surfaces;
0340
0341 std::unordered_map<HashedString,
0342 std::unique_ptr<podio_detail::ConstDynamicColumnBase>>
0343 m_dynamic;
0344 std::vector<HashedString> m_dynamicKeys;
0345 };
0346
0347 static_assert(IsReadOnlyMultiTrajectory<ConstPodioTrackStateContainer>::value,
0348 "MutablePodioTrackStateContainer should not be read-only");
0349
0350 static_assert(
0351 ConstMultiTrajectoryBackend<ConstPodioTrackStateContainer>,
0352 "ConstPodioTrackStateContainer does not fulfill TrackContainerBackend");
0353
0354 template <>
0355 struct IsReadOnlyMultiTrajectory<MutablePodioTrackStateContainer>
0356 : std::false_type {};
0357
0358 class MutablePodioTrackStateContainer final
0359 : public PodioTrackStateContainerBase,
0360 public MultiTrajectory<MutablePodioTrackStateContainer> {
0361 public:
0362 MutablePodioTrackStateContainer(PodioUtil::ConversionHelper& helper)
0363 : m_helper{helper} {
0364 m_collection = std::make_unique<ActsPodioEdm::TrackStateCollection>();
0365 m_jacs = std::make_unique<ActsPodioEdm::JacobianCollection>();
0366 m_params = std::make_unique<ActsPodioEdm::BoundParametersCollection>();
0367
0368 populateSurfaceBuffer(m_helper, *m_collection, m_surfaces);
0369 }
0370
0371 ConstParameters parameters_impl(IndexType istate) const {
0372 return ConstParameters{m_params->at(istate).getData().values.data()};
0373 }
0374
0375 Parameters parameters_impl(IndexType istate) {
0376 return Parameters{
0377 PodioUtil::getDataMutable(m_params->at(istate)).values.data()};
0378 }
0379
0380 ConstCovariance covariance_impl(IndexType istate) const {
0381 return ConstCovariance{m_params->at(istate).getData().covariance.data()};
0382 }
0383
0384 Covariance covariance_impl(IndexType istate) {
0385 return Covariance{
0386 PodioUtil::getDataMutable(m_params->at(istate)).covariance.data()};
0387 }
0388
0389 ConstCovariance jacobian_impl(IndexType istate) const {
0390 IndexType ijacobian = m_collection->at(istate).getData().ijacobian;
0391 return ConstCovariance{m_jacs->at(ijacobian).getData().values.data()};
0392 }
0393
0394 Covariance jacobian_impl(IndexType istate) {
0395 IndexType ijacobian = m_collection->at(istate).getData().ijacobian;
0396 return Covariance{
0397 PodioUtil::getDataMutable(m_jacs->at(ijacobian)).values.data()};
0398 }
0399
0400 template <std::size_t measdim>
0401 ConstTrackStateProxy::Calibrated<measdim> calibrated_impl(
0402 IndexType index) const {
0403 return ConstTrackStateProxy::Calibrated<measdim>{
0404 m_collection->at(index).getData().measurement.data()};
0405 }
0406
0407 template <std::size_t measdim>
0408 TrackStateProxy::Calibrated<measdim> calibrated_impl(IndexType index) {
0409 return TrackStateProxy::Calibrated<measdim>{
0410 PodioUtil::getDataMutable(m_collection->at(index)).measurement.data()};
0411 }
0412
0413 template <std::size_t measdim>
0414 ConstTrackStateProxy::CalibratedCovariance<measdim> calibratedCovariance_impl(
0415 IndexType index) const {
0416 return ConstTrackStateProxy::CalibratedCovariance<measdim>{
0417 m_collection->at(index).getData().measurementCovariance.data()};
0418 }
0419
0420 template <std::size_t measdim>
0421 TrackStateProxy::CalibratedCovariance<measdim> calibratedCovariance_impl(
0422 IndexType index) {
0423 return TrackStateProxy::CalibratedCovariance<measdim>{
0424 PodioUtil::getDataMutable(m_collection->at(index))
0425 .measurementCovariance.data()};
0426 }
0427
0428 IndexType size_impl() const { return m_collection->size(); }
0429
0430 std::any component_impl(HashedString key, IndexType istate) const {
0431 return PodioTrackStateContainerBase::component_impl<true>(*this, key,
0432 istate);
0433 }
0434
0435 std::any component_impl(HashedString key, IndexType istate) {
0436 return PodioTrackStateContainerBase::component_impl<false>(*this, key,
0437 istate);
0438 }
0439
0440 constexpr bool hasColumn_impl(HashedString key) const {
0441 return PodioTrackStateContainerBase::hasColumn_impl(*this, key);
0442 }
0443
0444 constexpr bool has_impl(HashedString key, IndexType istate) const {
0445 return PodioTrackStateContainerBase::has_impl(*this, key, istate);
0446 }
0447
0448 IndexType addTrackState_impl(
0449 TrackStatePropMask mask = TrackStatePropMask::All,
0450 TrackIndexType iprevious = kTrackIndexInvalid) {
0451 auto trackState = m_collection->create();
0452 auto& data = PodioUtil::getDataMutable(trackState);
0453 data.previous = iprevious;
0454 data.ipredicted = kInvalid;
0455 data.ifiltered = kInvalid;
0456 data.ismoothed = kInvalid;
0457 data.ijacobian = kInvalid;
0458
0459 PodioUtil::getReferenceSurfaceMutable(trackState).surfaceType =
0460 PodioUtil::kNoSurface;
0461
0462 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Predicted)) {
0463 m_params->create();
0464 data.ipredicted = m_params->size() - 1;
0465 }
0466 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Filtered)) {
0467 m_params->create();
0468 data.ifiltered = m_params->size() - 1;
0469 }
0470 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Smoothed)) {
0471 m_params->create();
0472 data.ismoothed = m_params->size() - 1;
0473 }
0474 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Jacobian)) {
0475 m_jacs->create();
0476 data.ijacobian = m_jacs->size() - 1;
0477 }
0478 data.measdim = 0;
0479 data.hasProjector = false;
0480 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Calibrated)) {
0481 data.hasProjector = true;
0482 }
0483 m_surfaces.emplace_back();
0484
0485 data.uncalibratedIdentifier = PodioUtil::kNoIdentifier;
0486 assert(m_collection->size() == m_surfaces.size() &&
0487 "Inconsistent surface buffer");
0488
0489 for (const auto& [key, vec] : m_dynamic) {
0490 vec->add();
0491 }
0492
0493 return m_collection->size() - 1;
0494 }
0495
0496 void addTrackStateComponents_impl(IndexType istate, TrackStatePropMask mask) {
0497 auto& data = PodioUtil::getDataMutable(m_collection->at(istate));
0498
0499 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Predicted) &&
0500 data.ipredicted == kInvalid) {
0501 m_params->create();
0502 data.ipredicted = m_params->size() - 1;
0503 }
0504
0505 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Filtered) &&
0506 data.ifiltered == kInvalid) {
0507 m_params->create();
0508 data.ifiltered = m_params->size() - 1;
0509 }
0510
0511 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Smoothed) &&
0512 data.ismoothed == kInvalid) {
0513 m_params->create();
0514 data.ismoothed = m_params->size() - 1;
0515 }
0516
0517 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Jacobian) &&
0518 data.ijacobian == kInvalid) {
0519 m_jacs->create();
0520 data.ijacobian = m_jacs->size() - 1;
0521 }
0522
0523 if (ACTS_CHECK_BIT(mask, TrackStatePropMask::Calibrated) &&
0524 !data.hasProjector) {
0525 data.hasProjector = true;
0526 }
0527 }
0528
0529 void shareFrom_impl(TrackIndexType iself, TrackIndexType iother,
0530 TrackStatePropMask shareSource,
0531 TrackStatePropMask shareTarget) {
0532 auto& self = PodioUtil::getDataMutable(m_collection->at(iself));
0533 auto& other = PodioUtil::getDataMutable(m_collection->at(iother));
0534
0535 assert(ACTS_CHECK_BIT(getTrackState(iother).getMask(), shareSource) &&
0536 "Source has incompatible allocation");
0537
0538 using PM = TrackStatePropMask;
0539
0540 IndexType sourceIndex{kInvalid};
0541 switch (shareSource) {
0542 case PM::Predicted:
0543 sourceIndex = other.ipredicted;
0544 break;
0545 case PM::Filtered:
0546 sourceIndex = other.ifiltered;
0547 break;
0548 case PM::Smoothed:
0549 sourceIndex = other.ismoothed;
0550 break;
0551 case PM::Jacobian:
0552 sourceIndex = other.ijacobian;
0553 break;
0554 default:
0555 throw std::domain_error{"Unable to share this component"};
0556 }
0557
0558 assert(sourceIndex != kInvalid);
0559
0560 switch (shareTarget) {
0561 case PM::Predicted:
0562 assert(shareSource != PM::Jacobian);
0563 self.ipredicted = sourceIndex;
0564 break;
0565 case PM::Filtered:
0566 assert(shareSource != PM::Jacobian);
0567 self.ifiltered = sourceIndex;
0568 break;
0569 case PM::Smoothed:
0570 assert(shareSource != PM::Jacobian);
0571 self.ismoothed = sourceIndex;
0572 break;
0573 case PM::Jacobian:
0574 assert(shareSource == PM::Jacobian);
0575 self.ijacobian = sourceIndex;
0576 break;
0577 default:
0578 throw std::domain_error{"Unable to share this component"};
0579 }
0580 }
0581
0582 void unset_impl(TrackStatePropMask target, TrackIndexType istate) {
0583 auto& data = PodioUtil::getDataMutable(m_collection->at(istate));
0584 switch (target) {
0585 case TrackStatePropMask::Predicted:
0586 data.ipredicted = kInvalid;
0587 break;
0588 case TrackStatePropMask::Filtered:
0589 data.ifiltered = kInvalid;
0590 break;
0591 case TrackStatePropMask::Smoothed:
0592 data.ismoothed = kInvalid;
0593 break;
0594 case TrackStatePropMask::Jacobian:
0595 data.ijacobian = kInvalid;
0596 break;
0597 case TrackStatePropMask::Calibrated:
0598 data.measdim = 0;
0599 break;
0600 default:
0601 throw std::domain_error{"Unable to unset this component"};
0602 }
0603 }
0604
0605 void clear_impl() {
0606 m_collection->clear();
0607 m_params->clear();
0608 m_surfaces.clear();
0609 for (const auto& [key, vec] : m_dynamic) {
0610 vec->clear();
0611 }
0612 }
0613
0614 template <typename T>
0615 constexpr void addColumn_impl(std::string_view key) {
0616 HashedString hashedKey = hashString(key);
0617 m_dynamic.insert(
0618 {hashedKey, std::make_unique<podio_detail::DynamicColumn<T>>(key)});
0619 }
0620
0621 void allocateCalibrated_impl(IndexType istate, std::size_t measdim) {
0622 assert(measdim > 0 && "Zero measdim not supported");
0623 auto& data = PodioUtil::getDataMutable(m_collection->at(istate));
0624 data.measdim = measdim;
0625 }
0626
0627 void setUncalibratedSourceLink_impl(IndexType istate,
0628 const SourceLink& sourceLink) {
0629 PodioUtil::Identifier id =
0630 m_helper.get().sourceLinkToIdentifier(sourceLink);
0631 auto& data = PodioUtil::getDataMutable(m_collection->at(istate));
0632 data.uncalibratedIdentifier = id;
0633 }
0634
0635 void setReferenceSurface_impl(IndexType istate,
0636 std::shared_ptr<const Surface> surface) {
0637 auto trackState = m_collection->at(istate);
0638 trackState.setReferenceSurface(
0639 PodioUtil::convertSurfaceToPodio(m_helper, *surface));
0640 m_surfaces.at(istate) = std::move(surface);
0641 }
0642
0643 MultiTrajectoryTraits::IndexType calibratedSize_impl(IndexType istate) const {
0644 return m_collection->at(istate).getData().measdim;
0645 }
0646
0647 SourceLink getUncalibratedSourceLink_impl(IndexType istate) const {
0648 return m_helper.get().identifierToSourceLink(
0649 m_collection->at(istate).getData().uncalibratedIdentifier);
0650 }
0651
0652 const Surface* referenceSurface_impl(IndexType istate) const {
0653 return m_surfaces.at(istate).get();
0654 }
0655
0656 void releaseInto(podio::Frame& frame, const std::string& suffix = "") {
0657 std::string s = suffix;
0658 if (!s.empty()) {
0659 s = "_" + s;
0660 }
0661 frame.put(std::move(m_collection), "trackStates" + s);
0662 frame.put(std::move(m_params), "trackStateParameters" + s);
0663 frame.put(std::move(m_jacs), "trackStateJacobians" + s);
0664 m_surfaces.clear();
0665
0666 for (const auto& [key, col] : m_dynamic) {
0667 col->releaseInto(frame, "trackStates" + s + "_extra__");
0668 }
0669
0670 m_dynamic.clear();
0671 }
0672
0673 detail::DynamicKeyRange<podio_detail::DynamicColumnBase> dynamicKeys_impl()
0674 const {
0675 return {m_dynamic.begin(), m_dynamic.end()};
0676 }
0677
0678 void copyDynamicFrom_impl(IndexType dstIdx, HashedString key,
0679 const std::any& srcPtr) {
0680 auto it = m_dynamic.find(key);
0681 if (it == m_dynamic.end()) {
0682 throw std::invalid_argument{
0683 "Destination container does not have matching dynamic column"};
0684 }
0685
0686 it->second->copyFrom(dstIdx, srcPtr);
0687 }
0688
0689 private:
0690 friend class PodioTrackStateContainerBase;
0691 friend class ConstPodioTrackStateContainer;
0692
0693 std::reference_wrapper<PodioUtil::ConversionHelper> m_helper;
0694 std::unique_ptr<ActsPodioEdm::TrackStateCollection> m_collection;
0695 std::unique_ptr<ActsPodioEdm::BoundParametersCollection> m_params;
0696 std::unique_ptr<ActsPodioEdm::JacobianCollection> m_jacs;
0697 std::vector<std::shared_ptr<const Surface>> m_surfaces;
0698
0699 std::unordered_map<HashedString,
0700 std::unique_ptr<podio_detail::DynamicColumnBase>>
0701 m_dynamic;
0702 std::vector<HashedString> m_dynamicKeys;
0703 };
0704
0705 static_assert(
0706 !IsReadOnlyMultiTrajectory<MutablePodioTrackStateContainer>::value,
0707 "MutablePodioTrackStateContainer should not be read-only");
0708
0709 static_assert(MutableMultiTrajectoryBackend<MutablePodioTrackStateContainer>,
0710 "MutablePodioTrackStateContainer does not fulfill "
0711 "TrackStateContainerBackend");
0712
0713 ConstPodioTrackStateContainer::ConstPodioTrackStateContainer(
0714 const MutablePodioTrackStateContainer& other)
0715 : m_helper{other.m_helper},
0716 m_collection{other.m_collection.get()},
0717 m_params{other.m_params.get()},
0718 m_jacs{other.m_jacs.get()},
0719 m_surfaces{other.m_surfaces} {
0720 for (const auto& [key, col] : other.m_dynamic) {
0721 m_dynamic.insert({key, col->asConst()});
0722 }
0723 }
0724
0725 }