diff --git a/Tracking/Acts/ActsEvent/ActsEvent/Decoration.h b/Tracking/Acts/ActsEvent/ActsEvent/Decoration.h index af49b9a0620c1ca29eb30adf4dfbae8c37979d44..953e72d6d312868a3a78646e9f135aa6b5de8654 100644 --- a/Tracking/Acts/ActsEvent/ActsEvent/Decoration.h +++ b/Tracking/Acts/ActsEvent/ActsEvent/Decoration.h @@ -3,36 +3,30 @@ */ #ifndef ActsEvent_Decoration_h #define ActsEvent_Decoration_h -#include "AthContainers/AuxElement.h" + +#include "AthContainersInterfaces/AuxTypes.h" +#include "AthContainersInterfaces/IAuxStore.h" +#include "AthContainersInterfaces/IConstAuxStore.h" +#include "xAODCore/AuxContainerBase.h" namespace ActsTrk { using IndexType = std::uint32_t; // TODO take from a common header namespace detail { +using SetterType = + std::function<std::any(SG::IAuxStore*, ActsTrk::IndexType, SG::auxid_t)>; +using GetterType = std::function<const std::any( + const SG::IConstAuxStore*, ActsTrk::IndexType, SG::auxid_t)>; +using CopierType = + std::function<void(SG::IAuxStore*, ActsTrk::IndexType, SG::auxid_t, + const SG::IConstAuxStore*, ActsTrk::IndexType)>; -template <typename STORE> struct Decoration { - using SetterType = - std::function<std::any(STORE*, ActsTrk::IndexType, const std::string&)>; - using GetterType = std::function<const std::any( - const STORE*, ActsTrk::IndexType, const std::string&)>; - using CopierType = - std::function<void(STORE*, ActsTrk::IndexType, const std::string&, - const STORE*, ActsTrk::IndexType)>; - - Decoration(const std::string& n, GetterType g, CopierType c, - SetterType s = static_cast<SetterType>(nullptr)) - : name(n), - hash(Acts::hashString(name)), - getter(g), - copier(c), - setter(s) {} - - std::string name; // xAOD API needs this - uint32_t hash; // Acts API comes with this - // TODO add here the aux ID to save on lookup - GetterType getter; // type aware accessors - CopierType copier; - SetterType setter; + std::string name; // for our info + uint32_t hash = 0; // Acts API comes with this + SG::auxid_t auxid = SG::null_auxid; // xAOD talks with this + GetterType getter = nullptr; // type aware accessors + CopierType copier = nullptr; + SetterType setter = nullptr; }; template <typename T> @@ -44,41 +38,65 @@ struct accepted_decoration_types { }; // getter that is good for non-mutable containers -template <typename STORE, typename T> -const std::any constDecorationGetter(const STORE* container, +template <typename T> +const std::any constDecorationGetter(const SG::IConstAuxStore* container, ActsTrk::IndexType idx, - const std::string& name) { - const SG::ConstAuxElement el(container, idx); - return &(el.auxdataConst<T>(name)); + SG::auxid_t decorationId) { + const void* data = container->getData(decorationId); + return &(static_cast<const T*>(data)[idx]); } - // getter that is good for mutable containers (returns const ptr wrapped in -// std::any but allow adding decorations to store) -template <typename STORE, typename T> -const std::any decorationGetter(const STORE* container, ActsTrk::IndexType idx, - const std::string& name) { - const SG::AuxElement* el = (*container)[idx]; - return const_cast<const T*>(&(el->auxdecor<T>(name))); +template <typename T> +const std::any decorationGetter(const SG::IAuxStore* container, + ActsTrk::IndexType idx, + SG::auxid_t decorationId) { + const void* data = container->getData(decorationId); + return &(static_cast<T*>(data)[idx]); } // setter for mutable containers (i.e. provides non const ptr wrapped in // std::any) -template <typename STORE, typename T> -std::any decorationSetter(STORE* container, ActsTrk::IndexType idx, - const std::string& name) { - const SG::AuxElement* el = (*container)[idx]; - return &(el->auxdecor<T>(name)); +template <typename T> +std::any decorationSetter(SG::IAuxStore* container, ActsTrk::IndexType idx, + SG::auxid_t decorationId) { + void* data = container->getData(decorationId, idx + 1, idx + 1); + return &(static_cast<T*>(data)[idx]); } -template <typename STORE, typename T> -void decorationCopier(STORE* dst, ActsTrk::IndexType dst_idx, - const std::string& name, const STORE* src, +template <typename T> +void decorationCopier(SG::IAuxStore* dst, ActsTrk::IndexType dst_idx, + SG::auxid_t decorationId, const SG::IConstAuxStore* src, ActsTrk::IndexType src_idx) { - *std::any_cast<T*>(decorationSetter<STORE, T>(dst, dst_idx, name)) = + *std::any_cast<T*>(decorationSetter<T>(dst, dst_idx, decorationId)) = *std::any_cast<const T*>( - constDecorationGetter<STORE, T>(src, src_idx, name)); + constDecorationGetter<T>(src, src_idx, decorationId)); +} + +template <typename T> +static Decoration decoration(const std::string& n, GetterType g, CopierType c, + SetterType s = static_cast<SetterType>(nullptr)) { + Decoration dec; + dec.name = n; + dec.hash = Acts::hashString(n); + dec.auxid = SG::AuxTypeRegistry::instance().getAuxID<T>(n); + if (dec.auxid == SG::null_auxid) + throw std::runtime_error("ActsTrk::Decoration Aux ID for " + n + + " could not be found"); + dec.getter = g; + dec.copier = c; + dec.setter = s; + return dec; } + +/** +* @arg container - source container to look for decorations +* @arg staticVaraibles - set of names of predefined variables for this container +*/ +std::vector<Decoration> restoreDecorations( + const SG::IConstAuxStore* container, + const std::set<std::string>& staticVariables); + } // namespace detail } // namespace ActsTrk diff --git a/Tracking/Acts/ActsEvent/ActsEvent/MultiTrajectory.h b/Tracking/Acts/ActsEvent/ActsEvent/MultiTrajectory.h index b1a19bdbb0f266713dd478adfab8e12163af4049..6265ea3330b42381f2b03a895358ae4745afb071 100644 --- a/Tracking/Acts/ActsEvent/ActsEvent/MultiTrajectory.h +++ b/Tracking/Acts/ActsEvent/ActsEvent/MultiTrajectory.h @@ -277,7 +277,6 @@ class MutableMultiTrajectory final */ inline size_t size_impl() const { - //return m_trackStatesAux->size(); return m_trackStatesSize; } @@ -364,15 +363,14 @@ class MutableMultiTrajectory final std::unique_ptr<xAOD::TrackSurfaceContainer> m_surfacesBackend; std::unique_ptr<xAOD::TrackSurfaceAuxContainer> m_surfacesBackendAux; - using DecorationAccess = ActsTrk::detail::Decoration<xAOD::TrackStateAuxContainer>; - std::vector<DecorationAccess> m_decorations; + std::vector<ActsTrk::detail::Decoration> m_decorations; std::vector<std::optional<Acts::SourceLink>> m_calibratedSourceLinks; std::vector<std::optional<Acts::SourceLink>> m_uncalibratedSourceLinks; std::vector<StoredSurface> m_surfaces; ActsGeometryContext m_geoContext; - + static const std::set<std::string> s_staticVariables; // addjust prealocated size to actualy used void trim(); }; @@ -451,8 +449,8 @@ class MultiTrajectory const DataLink<xAOD::TrackParametersAuxContainer> m_trackParametersAux; const DataLink<xAOD::TrackJacobianAuxContainer> m_trackJacobiansAux; const DataLink<xAOD::TrackMeasurementAuxContainer> m_trackMeasurementsAux; - using DecorationAccess = ActsTrk::detail::Decoration<xAOD::TrackStateContainer>; - std::vector<DecorationAccess> m_decorations; + std::vector<ActsTrk::detail::Decoration> m_decorations; + // TODO remove once tracking code switches to sourceLinks with EL std::vector<std::optional<Acts::SourceLink>> m_calibratedSourceLinks; std::vector<std::optional<Acts::SourceLink>> m_uncalibratedSourceLinks; diff --git a/Tracking/Acts/ActsEvent/ActsEvent/MultiTrajectory.icc b/Tracking/Acts/ActsEvent/ActsEvent/MultiTrajectory.icc index f46fe018383ddeb890d41f2147ab3c4338027112..557ddf4b0aec61f1daa95752e594dc26be1bf0c4 100644 --- a/Tracking/Acts/ActsEvent/ActsEvent/MultiTrajectory.icc +++ b/Tracking/Acts/ActsEvent/ActsEvent/MultiTrajectory.icc @@ -109,11 +109,12 @@ template <typename T> void ActsTrk::MutableMultiTrajectory::addColumn_impl(const std::string& name) { // It is actually not clear if we would allow decorating RO MTJ, maybe we do if constexpr (ActsTrk::detail::accepted_decoration_types<T>::value) { - m_decorations.emplace_back( + m_decorations.emplace_back( ActsTrk::detail::decoration<T>( name, - ActsTrk::detail::constDecorationGetter<xAOD::TrackStateContainer, T>, - ActsTrk::detail::decorationCopier<xAOD::TrackStateContainer, T>, - ActsTrk::detail::decorationSetter<xAOD::TrackStateContainer, T> + ActsTrk::detail::constDecorationGetter<T>, + ActsTrk::detail::decorationCopier<T>, + ActsTrk::detail::decorationSetter<T> + ) ); // it would be useful to force presence of decoration already here } else { diff --git a/Tracking/Acts/ActsEvent/ActsEvent/TrackStorageContainer.h b/Tracking/Acts/ActsEvent/ActsEvent/TrackStorageContainer.h index 56c6667801e9037f251ae9ca5e131ae2d0bd81db..a81ce141e1b023250c21b82e33c54b6649bc505c 100644 --- a/Tracking/Acts/ActsEvent/ActsEvent/TrackStorageContainer.h +++ b/Tracking/Acts/ActsEvent/ActsEvent/TrackStorageContainer.h @@ -14,6 +14,9 @@ #include "xAODTracking/TrackSurfaceAuxContainer.h" #include "xAODTracking/TrackSurfaceContainer.h" #include "ActsEvent/SurfaceEncoding.h" +// #include "xAODTracking/TrackStorageContainer.h" +// #include "xAODTracking/TrackStorageAuxContainer.h" + namespace ActsTrk { @@ -108,12 +111,11 @@ class TrackStorageContainer { } protected: - using DecorationAccess = ActsTrk::detail::Decoration<xAOD::TrackSummaryContainer>; - std::vector<DecorationAccess> m_decorations; DataLink<xAOD::TrackSummaryContainer> m_trackBackend = nullptr; DataLink<xAOD::TrackSurfaceAuxContainer> m_surfBackendAux = nullptr; + std::vector<ActsTrk::detail::Decoration> m_decorations; std::vector<std::shared_ptr<const Acts::Surface>> m_surfaces; std::vector<Acts::ParticleHypothesis> m_particleHypothesis; // TODO move the storage to the backend @@ -271,11 +273,11 @@ constexpr void MutableTrackStorageContainer::addColumn_impl( "TrackStorageContainer::addColumn_impl: " "unsupported decoration type"); } - m_decorations.push_back(DecorationAccess( + m_decorations.emplace_back(ActsTrk::detail::decoration<T>( name, - ActsTrk::detail::constDecorationGetter<xAOD::TrackSummaryContainer, T>, - ActsTrk::detail::decorationCopier<xAOD::TrackSummaryContainer, T>, - ActsTrk::detail::decorationSetter<xAOD::TrackSummaryContainer, T> + ActsTrk::detail::constDecorationGetter<T>, + ActsTrk::detail::decorationCopier<T>, + ActsTrk::detail::decorationSetter<T> )); } diff --git a/Tracking/Acts/ActsEvent/Root/Decoration.cxx b/Tracking/Acts/ActsEvent/Root/Decoration.cxx new file mode 100644 index 0000000000000000000000000000000000000000..602c2c3c5407e0e66c708fb74fbabf6aaf8f28c8 --- /dev/null +++ b/Tracking/Acts/ActsEvent/Root/Decoration.cxx @@ -0,0 +1,48 @@ +/* + Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration +*/ +#include "Acts/Utilities/HashedString.hpp" +#include "ActsEvent/Decoration.h" + + +namespace ActsTrk::detail { +std::vector<Decoration> restoreDecorations( + const SG::IConstAuxStore* container, + const std::set<std::string>& staticVariables) { + std::vector<Decoration> decorations; + for (auto id : container->getAuxIDs()) { + const std::string name = SG::AuxTypeRegistry::instance().getName(id); + const std::type_info* typeInfo = + SG::AuxTypeRegistry::instance().getType(id); + if (staticVariables.count(name) == 1) { + continue; + } + + // try making decoration accessor of matching type + // there is a fixed set of supported types (as there is a fixed set + // available in MutableMTJ) setters are not needed so replaced by a + // "nullptr" + if (*typeInfo == typeid(float)) { + decorations.emplace_back( + decoration<float>(name, ActsTrk::detail::constDecorationGetter<float>, + ActsTrk::detail::decorationCopier<float>)); + } else if (*typeInfo == typeid(double)) { + decorations.emplace_back(decoration<double>( + name, ActsTrk::detail::constDecorationGetter<double>, + ActsTrk::detail::decorationCopier<double>)); + } else if (*typeInfo == typeid(short)) { + decorations.emplace_back( + decoration<short>(name, ActsTrk::detail::constDecorationGetter<short>, + ActsTrk::detail::decorationCopier<short>)); + } else if (*typeInfo == typeid(uint32_t)) { + decorations.emplace_back(decoration<uint32_t>( + name, ActsTrk::detail::constDecorationGetter<uint32_t>, + ActsTrk::detail::decorationCopier<uint32_t>)); + } else { + throw std::runtime_error("Can't restore decoration of " + name + + " because it is of an unsupported type"); + } + } + return decorations; +} +} // namespace ActsTrk::detail \ No newline at end of file diff --git a/Tracking/Acts/ActsEvent/Root/MultiTrajectory.cxx b/Tracking/Acts/ActsEvent/Root/MultiTrajectory.cxx index 77475449e3027b7f2ae90e3702122e7d283414c6..656205e9788be7ca567b67b345ccb847e92db822 100644 --- a/Tracking/Acts/ActsEvent/Root/MultiTrajectory.cxx +++ b/Tracking/Acts/ActsEvent/Root/MultiTrajectory.cxx @@ -4,13 +4,20 @@ #include "ActsEvent/MultiTrajectory.h" #include "ActsEvent/SurfaceEncoding.h" #include "xAODTracking/TrackMeasurementAuxContainer.h" +#include "xAODCore/AuxContainerBase.h" #include "xAODTracking/TrackState.h" #include "xAODTracking/TrackParameters.h" #include "xAODTracking/TrackJacobian.h" -#include "xAODTracking/TrackMeasurement.h" + constexpr uint64_t InvalidGeoID = std::numeric_limits<uint64_t>::max(); +const std::set<std::string> ActsTrk::MutableMultiTrajectory::s_staticVariables = { + "chi2", "pathLength", "typeFlags", "previous", "next", "predicted", "filtered", "smoothed", "jacobian", "calibrated", "measDim", "uncalibratedMeasurementLink", "geometryId", "surfaceLink" + }; + + + template<typename T> const T* to_const_ptr(const std::unique_ptr<T>& ptr) { return ptr.get(); @@ -268,8 +275,7 @@ std::any ActsTrk::MutableMultiTrajectory::component_impl( default: { for (auto& d : m_decorations) { if (d.hash == key) { - // TODO VITAL - make decorations to work with a generic Aux - // return d.setter(m_trackStates.get(), istate, d.name); + return d.setter(m_trackStatesAux.get(), istate, d.auxid); } } throw std::runtime_error("MutableMultiTrajectory::component_impl no such component " + std::to_string(key)); @@ -318,8 +324,7 @@ const std::any ActsTrk::MutableMultiTrajectory::component_impl( for (auto& d : m_decorations) { if (d.hash == key) { INSPECTCALL("getting dymaic variable " << d.name << " " << istate); - // TODO restore after all implementation is moved to Aux backend - // return d.getter(m_trackStates.get(), istate, d.name); + return d.getter(m_trackStatesAux.get(), istate, d.auxid); } } throw std::runtime_error("MutableMultiTrajectory::component_impl const no such component " + std::to_string(key)); @@ -468,40 +473,7 @@ ActsTrk::MultiTrajectory::MultiTrajectory( m_trackJacobiansAux(trackJacobians), m_trackMeasurementsAux(trackMeasurements) { INSPECTCALL("ctor " << this << " " << m_trackStatesAux->size()); - - for ( auto id : m_trackStatesAux->getAuxIDs() ) { - - const std::string name = SG::AuxTypeRegistry::instance().getName(id); - if ( hasColumn_impl(Acts::hashString(name)) ) { // already known columns - continue; - } - // TODO restore in following MR - // const std::type_info* typeInfo = SG::AuxTypeRegistry::instance().getType(id); - - // // try making decoration accessor of matching type - // // there is a fixed set of supported types (as there is a fixed set available in MutableMTJ) - // // setters are not needed so replaced by a "nullptr" - // if ( *typeInfo == typeid(float) ) { - // m_decorations.emplace_back( name, - // ActsTrk::detail::constDecorationGetter<xAOD::TrackStateContainer, float>, - // ActsTrk::detail::decorationCopier<xAOD::TrackStateContainer, float>); - // } else if ( *typeInfo == typeid(double) ) { - // m_decorations.emplace_back( name, - // ActsTrk::detail::constDecorationGetter<xAOD::TrackStateContainer, double>, - // ActsTrk::detail::decorationCopier<xAOD::TrackStateContainer, double>); - - // } else if ( *typeInfo == typeid(short) ) { - // m_decorations.emplace_back( name, - // ActsTrk::detail::constDecorationGetter<xAOD::TrackStateContainer, short>, - // ActsTrk::detail::decorationCopier<xAOD::TrackStateContainer, short>); - - // } else if ( *typeInfo == typeid(uint32_t) ) { - // m_decorations.emplace_back( name, - // ActsTrk::detail::constDecorationGetter<xAOD::TrackStateContainer, uint32_t>, - // ActsTrk::detail::decorationCopier<xAOD::TrackStateContainer, uint32_t>); - // } - - } + m_decorations = ActsTrk::detail::restoreDecorations(m_trackStatesAux, ActsTrk::MutableMultiTrajectory::s_staticVariables); } bool ActsTrk::MultiTrajectory::has_impl(Acts::HashedString key, @@ -552,8 +524,8 @@ const std::any ActsTrk::MultiTrajectory::component_impl( default: { for (auto& d : m_decorations) { if (d.hash == key) { - // TODO - // return d.getter(m_trackStates.cptr(), istate, d.name); + // TODO the dynamic_cast will disappear + return d.getter(m_trackStatesAux.cptr(), istate, d.auxid); } } throw std::runtime_error("MultiTrajectory::component_impl no such component " + std::to_string(key)); @@ -564,6 +536,7 @@ const std::any ActsTrk::MultiTrajectory::component_impl( bool ActsTrk::MultiTrajectory::hasColumn_impl( Acts::HashedString key) const { using namespace Acts::HashedStringLiteral; + // TODO try using staticVariables set switch (key) { case "previous"_hash: case "chi2"_hash: @@ -636,7 +609,7 @@ void ActsTrk::MultiTrajectory::fillSurfaces(const Acts::TrackingGeometry* geo, c const Acts::Surface* ActsTrk::MultiTrajectory::referenceSurface_impl(IndexType istate) const { - INSPECTCALL( this << " " << istate << " " << m_trackStates->size() << " " << m_surfaces.size()); + INSPECTCALL( this << " " << istate << " " << m_trackStatesAux->size() << " " << m_surfaces.size()); if ( istate >= m_surfaces.size() ) throw std::out_of_range("MultiTrajectory index " + std::to_string(istate) + " out of range " + std::to_string(m_surfaces.size()) + " when accessing reference surface"); return toSurfacePtr(m_surfaces[istate]); } diff --git a/Tracking/Acts/ActsEvent/Root/TrackStorageContainer.cxx b/Tracking/Acts/ActsEvent/Root/TrackStorageContainer.cxx index 248a39ff6992c513f33de5bb4bae46b7e8bdf762..7c7130ecb4e22e7b1c31e0c67b29af787ad4df71 100644 --- a/Tracking/Acts/ActsEvent/Root/TrackStorageContainer.cxx +++ b/Tracking/Acts/ActsEvent/Root/TrackStorageContainer.cxx @@ -70,7 +70,8 @@ std::any ActsTrk::TrackStorageContainer::component_impl( } for (auto& d : m_decorations) { if (d.hash == key) { - return d.getter(m_trackBackend.cptr(), itrack, d.name); + // TODO the dynamic case will be eliminated once we switch to use Aux containers directly + return d.getter(m_trackBackend->getStore(), itrack, d.auxid); } } throw std::runtime_error("TrackStorageContainer no such component " + @@ -102,53 +103,7 @@ void ActsTrk::TrackStorageContainer::fillFrom( void ActsTrk::TrackStorageContainer::restoreDecorations() { - - for (auto id : m_trackBackend->getConstStore()->getAuxIDs()) { - const std::string name = SG::AuxTypeRegistry::instance().getName(id); - const std::type_info* typeInfo = - SG::AuxTypeRegistry::instance().getType(id); - if (staticVariables.count(name) == 1) { - continue; - } - - // try making decoration accessor of matching type - // there is a fixed set of supported types (as there is a fixed set - // available in MutableMTJ) setters are not needed so replaced by a - // "nullptr" - if (*typeInfo == typeid(float)) { - m_decorations.emplace_back( - name, - ActsTrk::detail::constDecorationGetter<xAOD::TrackSummaryContainer, - float>, - ActsTrk::detail::decorationCopier<xAOD::TrackSummaryContainer, - float>); - } else if (*typeInfo == typeid(double)) { - m_decorations.emplace_back( - name, - ActsTrk::detail::constDecorationGetter<xAOD::TrackSummaryContainer, - double>, - ActsTrk::detail::decorationCopier<xAOD::TrackSummaryContainer, - double>); - } else if (*typeInfo == typeid(short)) { - m_decorations.emplace_back( - name, - ActsTrk::detail::constDecorationGetter<xAOD::TrackSummaryContainer, - short>, - ActsTrk::detail::decorationCopier<xAOD::TrackSummaryContainer, - short>); - } else if (*typeInfo == typeid(uint32_t)) { - m_decorations.emplace_back( - name, - ActsTrk::detail::constDecorationGetter<xAOD::TrackSummaryContainer, - uint32_t>, - ActsTrk::detail::decorationCopier<xAOD::TrackSummaryContainer, - uint32_t>); - } else { - throw std::runtime_error( - "TrackStorageContainer Can't resore decoration of " + name + - " because it is of an unsupported type"); - } - } + m_decorations = ActsTrk::detail::restoreDecorations(m_trackBackend->getConstStore(), staticVariables); } @@ -232,8 +187,8 @@ void ActsTrk::MutableTrackStorageContainer::copyDynamicFrom_impl( std::set<std::string> usedDecorations; for ( const auto& other_decor: other.m_decorations) { if ( staticVariables.count(other_decor.name) == 1) { continue; } - - other_decor.copier(trackBackend(), itrack, other_decor.name, other.trackBackend(), + // TODO dynamic cast will disappear + other_decor.copier(m_mutableTrackBackendAux.get(), itrack, other_decor.auxid, other.trackBackend()->getStore(), other_itrack); } } @@ -250,7 +205,7 @@ std::any ActsTrk::MutableTrackStorageContainer::component_impl( } for (auto& d : m_decorations) { if (d.hash == key) { - return d.setter(m_mutableTrackBackend.get(), itrack, d.name); + return d.setter(m_mutableTrackBackendAux.get(), itrack, d.auxid); } } throw std::runtime_error("TrackStorageContainer no such component " + diff --git a/Tracking/Acts/ActsEvent/test/MultiTrajectoryBasic_test.cxx b/Tracking/Acts/ActsEvent/test/MultiTrajectoryBasic_test.cxx index 3aac6337b5f01e6fa62964928a670385639ec478..c486f707a14f38609d25c64bc17ca026279b1dd6 100644 --- a/Tracking/Acts/ActsEvent/test/MultiTrajectoryBasic_test.cxx +++ b/Tracking/Acts/ActsEvent/test/MultiTrajectoryBasic_test.cxx @@ -231,77 +231,70 @@ BOOST_FIXTURE_TEST_CASE(Dynamic_columns, EmptyMTJ) { BOOST_CHECK(mtj->has_backends()); BOOST_CHECK_EQUAL(mtj->hasColumn("jacobian"_hash), true); // not dynamic column - // TODO restore once decorations are reimplemented - // BOOST_CHECK_EQUAL(mtj->hasColumn("author"_hash), - // false); // dynamic column absent initially - // mtj->addColumn<short>("author"); // add dynamic column - - // BOOST_CHECK_EQUAL(mtj->hasColumn("author"_hash), - // true); // dynamic column present now - // mtj->addColumn<float>("mcprob"); - // BOOST_CHECK_EQUAL(mtj->hasColumn("mcprob"_hash), - // true); // dynamic column present now - - // constexpr auto kMask = Acts::TrackStatePropMask::Predicted; - // auto i0 = mtj->addTrackState(kMask); - // auto i1 = mtj->addTrackState(kMask, i0); - // auto i2 = mtj->addTrackState(kMask, i1); + BOOST_CHECK_EQUAL(mtj->hasColumn("author"_hash), + false); // dynamic column absent initially + mtj->addColumn<short>("author"); // add dynamic column + + BOOST_CHECK_EQUAL(mtj->hasColumn("author"_hash), + true); // dynamic column present now + mtj->addColumn<float>("mcprob"); + BOOST_CHECK_EQUAL(mtj->hasColumn("mcprob"_hash), + true); // dynamic column present now + + constexpr auto kMask = Acts::TrackStatePropMask::Predicted; + auto i0 = mtj->addTrackState(kMask); + auto i1 = mtj->addTrackState(kMask, i0); + auto i2 = mtj->addTrackState(kMask, i1); // dynamic column enabled late - // TODO to restore once decorations implementation is available for the new MTJ backend approach - // auto ts0 = mtj->getTrackState(i0); - // auto ts1 = mtj->getTrackState(i1); - // auto ts2 = mtj->getTrackState(i2); - // TODO tests of the decorations will be restored once we unify all implementations to talk to Aux stores - // ts0.component<short, "author"_hash>() = 5; - // ts1.component<short, "author"_hash>() = 6; - // ts2.component<short, "author"_hash>() = 4; - - // ts0.component<float, "mcprob"_hash>() = 0.5; - // ts1.component<float, "mcprob"_hash>() = 0.9; - - // // unset for ts2 - - // // read them back - // BOOST_CHECK_EQUAL((ts0.component<short, "author"_hash>()), 5); - // BOOST_CHECK_EQUAL((ts1.component<short, "author"_hash>()), 6); - // BOOST_CHECK_EQUAL((ts2.component<short, "author"_hash>()), 4); - - // BOOST_TEST((ts0.component<float, "mcprob"_hash>()) == 0.5, - // boost::test_tools::tolerance(0.01)); - // BOOST_TEST((ts1.component<float, "mcprob"_hash>()) == 0.9, - // boost::test_tools::tolerance(0.01)); - // BOOST_TEST((ts2.component<float, "mcprob"_hash>()) == 0.0, - // boost::test_tools::tolerance(0.01)); - - // BOOST_CHECK_THROW((ts2.component<float, "sth"_hash>()), std::runtime_error); + auto ts0 = mtj->getTrackState(i0); + auto ts1 = mtj->getTrackState(i1); + auto ts2 = mtj->getTrackState(i2); - // RO MTJ needs to be remade now because only at construction it can recognise - // the dynamic columns - // ro_mtj = std::make_unique<ActsTrk::MultiTrajectory>(&mtj->trackStates(), &mtj->trackParameters(), - // &mtj->trackJacobians(), &mtj->trackMeasurements()); + ts0.component<short, "author"_hash>() = 5; + ts1.component<short, "author"_hash>() = 6; + ts2.component<short, "author"_hash>() = 4; + + ts0.component<float, "mcprob"_hash>() = 0.5; + ts1.component<float, "mcprob"_hash>() = 0.9; + // unset for ts2 - // BOOST_CHECK_EQUAL(ro_mtj->hasColumn("author"_hash), - // true); // dynamic column present now in const version too - // BOOST_CHECK_EQUAL(ro_mtj->hasColumn("mcprob"_hash), - // true); // dynamic column present now in const version too + // read them back + BOOST_CHECK_EQUAL((ts0.component<short, "author"_hash>()), 5); + BOOST_CHECK_EQUAL((ts1.component<short, "author"_hash>()), 6); + BOOST_CHECK_EQUAL((ts2.component<short, "author"_hash>()), 4); - // auto ro_ts0 = ro_mtj->getTrackState(i0); - // auto ro_ts1 = ro_mtj->getTrackState(i1); - // auto ro_ts2 = ro_mtj->getTrackState(i2); + BOOST_TEST((ts0.component<float, "mcprob"_hash>()) == 0.5, + boost::test_tools::tolerance(0.01)); + BOOST_TEST((ts1.component<float, "mcprob"_hash>()) == 0.9, + boost::test_tools::tolerance(0.01)); + BOOST_TEST((ts2.component<float, "mcprob"_hash>()) == 0.0, + boost::test_tools::tolerance(0.01)); - // BOOST_CHECK_EQUAL((ro_ts0.component<double, "chi2"_hash>()), 0.0); + BOOST_CHECK_THROW((ts2.component<float, "sth"_hash>()), std::runtime_error); - // BOOST_CHECK_EQUAL((ro_ts0.component<short, "author"_hash>()), 5); - // BOOST_CHECK_EQUAL((ro_ts1.component<short, "author"_hash>()), 6); - // BOOST_CHECK_EQUAL((ro_ts2.component<short, "author"_hash>()), 4); + // RO MTJ needs to be remade now because only at construction it can recognise + // the dynamic columns - // BOOST_TEST((ro_ts0.component<float, "mcprob"_hash>()) == 0.5, - // boost::test_tools::tolerance(0.01)); - // BOOST_TEST((ro_ts1.component<float, "mcprob"_hash>()) == 0.9, - // boost::test_tools::tolerance(0.01)); - // BOOST_TEST((ro_ts2.component<float, "mcprob"_hash>()) == 0.0, - // boost::test_tools::tolerance(0.01)); + BOOST_CHECK_EQUAL(ro_mtj()->hasColumn("author"_hash), + true); // dynamic column present now in const version too + BOOST_CHECK_EQUAL(ro_mtj()->hasColumn("mcprob"_hash), + true); // dynamic column present now in const version too + + auto ro_ts0 = ro_mtj()->getTrackState(i0); + auto ro_ts1 = ro_mtj()->getTrackState(i1); + auto ro_ts2 = ro_mtj()->getTrackState(i2); + + BOOST_CHECK_EQUAL((ro_ts0.component<short, "author"_hash>()), 5); + BOOST_CHECK_EQUAL((ro_ts1.component<short, "author"_hash>()), 6); + BOOST_CHECK_EQUAL((ro_ts2.component<short, "author"_hash>()), 4); + + BOOST_TEST((ro_ts0.component<float, "mcprob"_hash>()) == 0.5, + boost::test_tools::tolerance(0.01)); + BOOST_TEST((ro_ts1.component<float, "mcprob"_hash>()) == 0.9, + boost::test_tools::tolerance(0.01)); + BOOST_TEST((ro_ts2.component<float, "mcprob"_hash>()) == 0.0, + boost::test_tools::tolerance(0.01)); } // FIXME - test below should use ACTS::MTJ api once available in needed shape