diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index a970dfb48c..678b1dd463 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -43,6 +43,12 @@ traccc_add_library( traccc_core core TYPE SHARED "include/traccc/edm/track_collection.hpp" "include/traccc/edm/impl/track_collection.ipp" "include/traccc/edm/track_container.hpp" + "include/traccc/edm/DeviceMultiTrajectory.hpp" + "include/traccc/edm/impl/DeviceMultiTrajectory.ipp" + "src/edm/DeviceMultiTrajectory.cpp" + "include/traccc/edm/DeviceTrackBackend.hpp" + "src/edm/DeviceTrackBackend.cpp" + "include/traccc/edm/DeviceTrackContainer.hpp" # Magnetic field description. "include/traccc/bfield/magnetic_field_types.hpp" "include/traccc/bfield/magnetic_field.hpp" diff --git a/core/include/traccc/edm/DeviceMultiTrajectory.hpp b/core/include/traccc/edm/DeviceMultiTrajectory.hpp new file mode 100644 index 0000000000..77f1dedc49 --- /dev/null +++ b/core/include/traccc/edm/DeviceMultiTrajectory.hpp @@ -0,0 +1,181 @@ +/** TRACCC library, part of the ACTS project (R&D line) + * + * (c) 2025 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +#pragma once + +// Local include(s). +#include "traccc/edm/track_container.hpp" +#include "traccc/geometry/host_detector.hpp" + +// Acts include(s). +#include +#include +#include + +// System include(s). +#include +#include + +namespace traccc::edm { + +/// @c Acts::MultiTrajectory specialisation for traccc produced tracks +class DeviceMultiTrajectory + : public Acts::MultiTrajectory { + + public: + /// Constructor from a track container and Acts/Detray tracking geometries + /// + /// @param tracks The track container holding the data + /// @param actsGeometry The Acts tracking geometry associated with the + /// trajectories + /// @param detrayGeometry The Detray tracking geometry associated with the + /// trajectories + /// + explicit DeviceMultiTrajectory( + const track_container::const_view& tracks, + const Acts::TrackingGeometry& actsGeometry, + const host_detector& detrayGeometry); + /// Copy constructor + DeviceMultiTrajectory(const DeviceMultiTrajectory&) = default; + + /// Copy assignment operator + DeviceMultiTrajectory& operator=(const DeviceMultiTrajectory&) = default; + + /// @name Functions required by @c Acts::MultiTrajectory + /// @{ + + /// Get the size of the object (number of track states) + /// + /// @return The total number of track states + /// + IndexType size_impl() const; + + /// Get the calibrated size of a given track state (measurement dimension) + /// + /// @param istate The index of the track state + /// @return The calibrated size (measurement dimension) + /// + IndexType calibratedSize_impl(IndexType istate) const; + + /// Check if a given component exists for a given track state + /// + /// @param key The key of the component to check + /// @param istate The index of the track state to check + /// @return @c true if the component exists, @c false otherwise + /// + bool has_impl(Acts::HashedString key, IndexType istate) const; + + /// Check if a given track state column exists + /// + /// @param key The key of the column to check + /// @return @c true if the column exists, @c false otherwise + /// + bool hasColumn_impl(Acts::HashedString key) const; + + /// Retrieve a given component of a track state + /// + /// @param key The key of the component to retrieve + /// @param istate The index of the track state to retrieve from + /// @return The component as an @c std::any object + /// + std::any component_impl(Acts::HashedString key, IndexType istate) const; + + /// Retrieve the parameters of a given track state + /// + /// @param index Index into the parameter column + /// @return The Eigen object representing the parameters + /// + ConstTrackStateProxy::ConstParameters parameters_impl( + IndexType index) const; + + /// Retrieve the covariance of a given track state + /// + /// @param index Index into the covariance column + /// @return The Eigen object representing the covariance + /// + ConstTrackStateProxy::ConstCovariance covariance_impl( + IndexType index) const; + + /// Retrieve the calibrated measurement (positions) of a given track state + /// + /// @tparam MEASDIM the measurement dimension + /// @param istate The track state index + /// @return The Eigen object representing the calibrated measurement + /// + template + ConstTrackStateProxy::Calibrated calibrated_impl( + IndexType istate) const; + + /// Retrieve the calibrated measurement covariance of a given track state + /// + /// @tparam MEASDIM the measurement dimension + /// @param index The track state index + /// @return The Eigen object representing the calibrated measurement + /// covariance + /// + template + ConstTrackStateProxy::CalibratedCovariance + calibratedCovariance_impl(IndexType index) const; + + /// Retrieve the jacobian of a given track state + /// + /// @param istate The track state + /// @return The Eigen object representing the jacobian + /// + ConstTrackStateProxy::ConstCovariance jacobian_impl(IndexType istate) const; + + /// Retrieve the reference surface of a given track state + /// + /// @param index Index into the track state container + /// @return A pointer to the reference surface + /// + const Acts::Surface* referenceSurface_impl(IndexType index) const; + + /// Dynamic keys available in this multi-trajectory + /// + /// By definition, it will always be empty for traccc multi-trajectories. + /// + /// @return The list of dynamic keys + /// + const std::vector& dynamicKeys_impl() const; + + /// Retrieve the uncalibrated source link of a given track state + /// + /// @param istate The index of the track state + /// @return The source link object + /// + Acts::SourceLink getUncalibratedSourceLink_impl(IndexType istate) const; + + /// @} + + private: + /// The track container holding the data + track_container::const_device m_tracks; + /// The tracking geometry associated with the trajectories + std::reference_wrapper m_actsGeometry; + /// The Detray tracking geometry associated with the trajectories + std::reference_wrapper m_detrayGeometry; + +}; // class DeviceMultiTrajectory + +/// Make sure that @c DeviceMultiTrajectory meets the concept requirements +static_assert(Acts::ConstMultiTrajectoryBackend); + +} // namespace traccc::edm + +namespace Acts { + +/// Declare that @c traccc::edm::DeviceMultiTrajectory is a read-only +/// multi-trajectory +template <> +struct IsReadOnlyMultiTrajectory + : std::true_type {}; + +} // namespace Acts + +// Include the template implementation. +#include "traccc/edm/impl/DeviceMultiTrajectory.ipp" diff --git a/core/include/traccc/edm/DeviceTrackBackend.hpp b/core/include/traccc/edm/DeviceTrackBackend.hpp new file mode 100644 index 0000000000..b3088e6f73 --- /dev/null +++ b/core/include/traccc/edm/DeviceTrackBackend.hpp @@ -0,0 +1,145 @@ +/** TRACCC library, part of the ACTS project (R&D line) + * + * (c) 2025 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +#pragma once + +// Local include(s). +#include "traccc/edm/track_container.hpp" +#include "traccc/geometry/host_detector.hpp" + +// Acts include(s). +#include +#include +#include +#include +#include + +// System include(s). +#include +#include + +namespace traccc::edm { + +/// Implementation of the @c Acts::ConstTrackContainerBackend concept for traccc +/// produced tracks +class DeviceTrackBackend { + + public: + /// Constructor from a track container and Acts/Detray tracking geometries + /// + /// @param tracks The track container holding the data + /// @param actsGeometry The Acts tracking geometry associated with the + /// trajectories + /// @param detrayGeometry The Detray tracking geometry associated with the + /// trajectories + /// + explicit DeviceTrackBackend( + const track_container::const_view& tracks, + const Acts::TrackingGeometry& actsGeometry, + const host_detector& detrayGeometry); + /// Copy constructor + DeviceTrackBackend(const DeviceTrackBackend&) = default; + + /// Copy assignment operator + DeviceTrackBackend& operator=(const DeviceTrackBackend&) = default; + + /// Track index type + using IndexType = Acts::MultiTrajectoryTraits::IndexType; + /// Track parameters type + using ConstParameters = + Acts::detail_lt::FixedSizeTypes::CoefficientsMap; + /// Track covariance type + using ConstCovariance = + Acts::detail_lt::FixedSizeTypes::CovarianceMap; + + /// @name Functions required by @c Acts::TrackContainer + /// @{ + + /// Get the size of the object (the number of tracks) + /// + /// @return The total number of tracks + /// + std::size_t size_impl() const; + + /// Retrieve the parameters of a given track + /// + /// @param index Index into the parameter column + /// @return The Eigen object representing the parameters + /// + ConstParameters parameters(IndexType index) const; + + /// Retrieve the covariance of a given track state + /// + /// @param index Index into the covariance column + /// @return The Eigen object representing the covariance + /// + ConstCovariance covariance(IndexType index) const; + + /// Check if a given track column exists + /// + /// @param key The key of the column to check + /// @return @c true if the column exists, @c false otherwise + /// + bool hasColumn_impl(Acts::HashedString key) const; + + /// Retrieve a given component of a track + /// + /// @param key The key of the component to retrieve + /// @param itrack The index of the track to retrieve from + /// @return The component as an @c std::any object + /// + std::any component_impl(Acts::HashedString key, IndexType itrack) const; + + /// Particle hypothesis of a given track + /// + /// @param itrack The index of the track + /// @return The particle hypothesis + /// + Acts::ParticleHypothesis particleHypothesis_impl(IndexType itrack) const; + + /// Retrieve the reference surface of a given track + /// + /// @param index Index into the track container + /// @return A pointer to the reference surface + /// + const Acts::Surface* referenceSurface_impl(IndexType index) const; + + /// Dynamic keys available in this track container + /// + /// By definition, it will always be empty for traccc tracks. + /// + /// @return The list of dynamic keys + /// + const std::vector& dynamicKeys_impl() const; + + /// @} + + private: + /// The track container holding the data + track_container::const_device m_tracks; + /// The tracking geometry associated with the trajectories + std::reference_wrapper m_actsGeometry; + /// The Detray tracking geometry associated with the trajectories + std::reference_wrapper m_detrayGeometry; + +}; // class DeviceTrackBackend + +/// Make sure that @c DeviceTrackBackend meets the concept requirements +static_assert(Acts::ConstTrackContainerBackend); + +} // namespace traccc::edm + +namespace Acts { + +/// Declare that @c traccc::edm::DeviceTrackBackend is a read-only track +/// container +template <> +struct IsReadOnlyTrackContainer + : std::true_type {}; + +} // namespace Acts diff --git a/core/include/traccc/edm/DeviceTrackContainer.hpp b/core/include/traccc/edm/DeviceTrackContainer.hpp new file mode 100644 index 0000000000..7919ce0608 --- /dev/null +++ b/core/include/traccc/edm/DeviceTrackContainer.hpp @@ -0,0 +1,24 @@ +/** TRACCC library, part of the ACTS project (R&D line) + * + * (c) 2025 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +#pragma once + +// Local include(s). +#include "traccc/edm/DeviceMultiTrajectory.hpp" +#include "traccc/edm/DeviceTrackBackend.hpp" + +// Acts include(s). +#include + +namespace traccc::edm { + +/// @c Acts::TrackContainer specialisation for traccc produced tracks +using DeviceTrackContainer = + Acts::TrackContainer; + +} // namespace traccc::edm diff --git a/core/include/traccc/edm/impl/DeviceMultiTrajectory.ipp b/core/include/traccc/edm/impl/DeviceMultiTrajectory.ipp new file mode 100644 index 0000000000..c5baf433d8 --- /dev/null +++ b/core/include/traccc/edm/impl/DeviceMultiTrajectory.ipp @@ -0,0 +1,32 @@ +/** TRACCC library, part of the ACTS project (R&D line) + * + * (c) 2025 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +#pragma once + +namespace traccc::edm { + +template +auto DeviceMultiTrajectory::calibrated_impl(IndexType istate) const + -> ConstTrackStateProxy::Calibrated { + + return ConstTrackStateProxy::Calibrated{ + m_tracks.measurements.at(m_tracks.states.measurement_index().at(istate)) + .local_position() + .data()}; +} + +template +auto DeviceMultiTrajectory::calibratedCovariance_impl(IndexType) const + -> ConstTrackStateProxy::CalibratedCovariance { + + // We don't provide this at the moment. + throw std::runtime_error( + "traccc::edm::DeviceMultiTrajectory::calibratedCovariance_impl is not " + "supported"); +} + +} // namespace traccc::edm diff --git a/core/src/edm/DeviceMultiTrajectory.cpp b/core/src/edm/DeviceMultiTrajectory.cpp new file mode 100644 index 0000000000..9d169ff385 --- /dev/null +++ b/core/src/edm/DeviceMultiTrajectory.cpp @@ -0,0 +1,165 @@ +/** TRACCC library, part of the ACTS project (R&D line) + * + * (c) 2025 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +// Local include(s). +#include "traccc/edm/DeviceMultiTrajectory.hpp" + +// System include(s). +#include +#include + +namespace traccc::edm { + +DeviceMultiTrajectory::DeviceMultiTrajectory( + const track_container::const_view& tracks, + const Acts::TrackingGeometry& actsGeometry, + const host_detector& detrayGeometry) + : m_tracks{tracks}, + m_actsGeometry{actsGeometry}, + m_detrayGeometry(detrayGeometry) {} + +auto DeviceMultiTrajectory::size_impl() const -> IndexType { + + return static_cast(m_tracks.states.size()); +} + +auto DeviceMultiTrajectory::calibratedSize_impl(IndexType istate) const + -> IndexType { + + // Access the measurement and return its dimensions. + return static_cast( + m_tracks.measurements.at(m_tracks.states.measurement_index().at(istate)) + .dimensions()); +} + +bool DeviceMultiTrajectory::has_impl(Acts::HashedString key, IndexType) const { + + return hasColumn_impl(key); +} + +bool DeviceMultiTrajectory::hasColumn_impl(Acts::HashedString key) const { + + // Use the hashing literal from Acts. + using namespace Acts::HashedStringLiteral; + + // Hard-code the available columns. + switch (key) { + case "chi2"_hash: + case "measdim"_hash: + return true; + default: + return false; + } +} + +std::any DeviceMultiTrajectory::component_impl(Acts::HashedString key, + IndexType istate) const { + + // Use the hashing literal from Acts. + using namespace Acts::HashedStringLiteral; + + // Extract the requested component. + switch (key) { + case "chi2"_hash: + return &(m_tracks.states.smoothed_chi2().at(istate)); + case "measdim"_hash: + return &(m_tracks.measurements + .at(m_tracks.states.measurement_index().at(istate)) + .dimensions()); + default: + throw std::runtime_error( + "traccc::edm::DeviceMultiTrajectory::component_impl no such " + "component: " + + std::to_string(key)); + } +} + +auto DeviceMultiTrajectory::parameters_impl(IndexType index) const + -> ConstTrackStateProxy::ConstParameters { + + // Access the track state's parameters. + const bound_track_parameters& deviceParams = + m_tracks.states.smoothed_params().at(index); + + // Construct the parameters on the fly. Since Acts always expects the + // parameters to be FP64, and the device code may use FP32. + Acts::BoundVector actsParams; + actsParams << deviceParams.bound_local()[0], deviceParams.bound_local()[1], + deviceParams.phi(), deviceParams.theta(), deviceParams.qop(), + deviceParams.time(); + + // Construct the parameters expected by Acts. + return ConstTrackStateProxy::ConstParameters{actsParams.data()}; +} + +auto DeviceMultiTrajectory::covariance_impl(IndexType index) const + -> ConstTrackStateProxy::ConstCovariance { + + // Access the track state's parameters. + const bound_track_parameters& params = + m_tracks.states.smoothed_params().at(index); + + // Construct the covariance on the fly. + Acts::BoundSquareMatrix covariance; + for (unsigned int i = 0; i < Acts::BoundSquareMatrix::RowsAtCompileTime; + ++i) { + for (unsigned int j = 0; j < Acts::BoundSquareMatrix::ColsAtCompileTime; + ++j) { + covariance(i, j) = params.covariance()[i][j]; + } + } + + // Construct the covariance expected by Acts. + return ConstTrackStateProxy::ConstCovariance{covariance.data()}; +} + +auto DeviceMultiTrajectory::jacobian_impl(IndexType) const + -> ConstTrackStateProxy::ConstCovariance { + + // Currently not supported in traccc. + throw std::runtime_error( + "traccc::edm::DeviceMultiTrajectory::jacobian_impl is not supported"); +} + +const Acts::Surface* DeviceMultiTrajectory::referenceSurface_impl( + IndexType index) const { + + // Get the Detray surface barcode belonging to the requested track state. + const detray::geometry::barcode& barcode = + m_tracks.measurements.surface_link().at( + m_tracks.states.measurement_index().at(index)); + + // With this barcode, look up the Acts surface using the Detray geometry. + const Acts::GeometryIdentifier acts_surface_id = + host_detector_visitor( + m_detrayGeometry.get(), + [&]( + const typename detector_traits_t::host& detector) { + return Acts::GeometryIdentifier{ + detector.surfaces().search(barcode).source}; + }); + + // And now that we have an Acts surface identifier, retrieve the surface + // from the Acts tracking geometry. + return m_actsGeometry.get().findSurface(acts_surface_id); +} + +const std::vector& DeviceMultiTrajectory::dynamicKeys_impl() + const { + + // There are no dynamic keys in traccc multi-trajectories. + static const std::vector empty_keys{}; + return empty_keys; +} + +Acts::SourceLink DeviceMultiTrajectory::getUncalibratedSourceLink_impl( + IndexType) const { + + return Acts::SourceLink{nullptr}; +} + +} // namespace traccc::edm diff --git a/core/src/edm/DeviceTrackBackend.cpp b/core/src/edm/DeviceTrackBackend.cpp new file mode 100644 index 0000000000..54a751dbba --- /dev/null +++ b/core/src/edm/DeviceTrackBackend.cpp @@ -0,0 +1,164 @@ +/** TRACCC library, part of the ACTS project (R&D line) + * + * (c) 2025 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +// Local include(s). +#include "traccc/edm/DeviceTrackBackend.hpp" + +// System include(s). +#include +#include + +namespace traccc::edm { + +DeviceTrackBackend::DeviceTrackBackend( + const track_container::const_view& tracks, + const Acts::TrackingGeometry& actsGeometry, + const host_detector& detrayGeometry) + : m_tracks{tracks}, + m_actsGeometry{actsGeometry}, + m_detrayGeometry(detrayGeometry) {} + +std::size_t DeviceTrackBackend::size_impl() const { + + return static_cast(m_tracks.tracks.size()); +} + +auto DeviceTrackBackend::parameters(IndexType index) const -> ConstParameters { + + // Access the track's parameters. + const bound_track_parameters& deviceParams = + m_tracks.tracks.params().at(index); + + // Construct the parameters on the fly. Since Acts always expects the + // parameters to be FP64, and the device code may use FP32. + Acts::BoundVector actsParams; + actsParams << deviceParams.bound_local()[0], deviceParams.bound_local()[1], + deviceParams.phi(), deviceParams.theta(), deviceParams.qop(), + deviceParams.time(); + + // Construct the parameters expected by Acts. + return ConstParameters{actsParams.data()}; +} + +auto DeviceTrackBackend::covariance(IndexType index) const -> ConstCovariance { + + // Access the track's parameters. + const bound_track_parameters& params = + m_tracks.tracks.params().at(index); + + // Construct the covariance on the fly. + Acts::BoundSquareMatrix covariance; + for (unsigned int i = 0; i < Acts::BoundSquareMatrix::RowsAtCompileTime; + ++i) { + for (unsigned int j = 0; j < Acts::BoundSquareMatrix::ColsAtCompileTime; + ++j) { + covariance(i, j) = params.covariance()[i][j]; + } + } + + // Construct the covariance expected by Acts. + return ConstCovariance{covariance.data()}; +} + +bool DeviceTrackBackend::hasColumn_impl(Acts::HashedString key) const { + + // Use the hashing literal from Acts. + using namespace Acts::HashedStringLiteral; + + // Hard-code the available columns. + switch (key) { + case "fitOutcome"_hash: + case "params"_hash: + case "ndf"_hash: + case "chi2"_hash: + case "pval"_hash: + case "nHoles"_hash: + return true; + default: + return false; + } +} + +std::any DeviceTrackBackend::component_impl(Acts::HashedString key, + IndexType itrack) const { + + // Use the hashing literal from Acts. + using namespace Acts::HashedStringLiteral; + + // Hard-code the available columns. + switch (key) { + case "fitOutcome"_hash: + return &(m_tracks.tracks.fit_outcome().at(itrack)); + case "params"_hash: + return &(m_tracks.tracks.params().at(itrack)); + case "ndf"_hash: + return &(m_tracks.tracks.ndf().at(itrack)); + case "chi2"_hash: + return &(m_tracks.tracks.chi2().at(itrack)); + case "pval"_hash: + return &(m_tracks.tracks.pval().at(itrack)); + case "nHoles"_hash: + return &(m_tracks.tracks.nholes().at(itrack)); + default: + throw std::runtime_error( + "traccc::edm::DeviceTrackBackend::component_impl: Requested " + "track component does not exist: " + + std::to_string(key)); + } +} + +Acts::ParticleHypothesis DeviceTrackBackend::particleHypothesis_impl( + IndexType) const { + + // traccc tracks do not have per-track particle hypotheses; return a default + return Acts::ParticleHypothesis::muon(); +} + +const Acts::Surface* DeviceTrackBackend::referenceSurface_impl( + IndexType index) const { + + // Get the Detray surface barcode belonging to the first track state of the + // requested track. + detray::geometry::barcode barcode; + if (m_tracks.tracks.at(index).constituent_links().at(0u).type == + track_constituent_link::track_state) { + barcode = m_tracks.measurements.surface_link().at( + m_tracks.states.measurement_index().at( + m_tracks.tracks.constituent_links().at(index).at(0u).index)); + } else if (m_tracks.tracks.at(index).constituent_links().at(0u).type == + track_constituent_link::measurement) { + barcode = m_tracks.measurements.surface_link().at( + m_tracks.tracks.constituent_links().at(index).at(0u).index); + } else { + throw std::runtime_error( + "traccc::edm::DeviceTrackBackend::referenceSurface_impl: Invalid " + "track constituent link type encountered"); + } + + // With this barcode, look up the Acts surface using the Detray geometry. + const Acts::GeometryIdentifier acts_surface_id = + host_detector_visitor( + m_detrayGeometry.get(), + [&]( + const typename detector_traits_t::host& detector) { + return Acts::GeometryIdentifier{ + detector.surfaces().search(barcode).source}; + }); + + // And now that we have an Acts surface identifier, retrieve the surface + // from the Acts tracking geometry. + return m_actsGeometry.get().findSurface(acts_surface_id); +} + +const std::vector& DeviceTrackBackend::dynamicKeys_impl() + const { + + static const std::vector emptyKeys{}; + return emptyKeys; +} + +} // namespace traccc::edm diff --git a/tests/core/CMakeLists.txt b/tests/core/CMakeLists.txt index 54460d4171..02e2a02243 100644 --- a/tests/core/CMakeLists.txt +++ b/tests/core/CMakeLists.txt @@ -7,6 +7,7 @@ # Declare the core library test(s). traccc_add_test(core "test_algorithm.cpp" + "test_edm.cpp" "test_module_map.cpp" "test_pvalue.cpp" "particle.cpp" diff --git a/tests/core/test_edm.cpp b/tests/core/test_edm.cpp new file mode 100644 index 0000000000..3ed2f2d7c5 --- /dev/null +++ b/tests/core/test_edm.cpp @@ -0,0 +1,37 @@ +/** + * TRACCC library, part of the ACTS project (R&D line) + * + * (c) 2025 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +// Project include(s). +#include "traccc/edm/DeviceTrackContainer.hpp" + +// VecMem include(s). +#include + +// GTest include(s). +#include + +TEST(edm, track_container_creation) { + + // Create an empty track container. + vecmem::host_memory_resource mr; + traccc::edm::track_container::host tracks{mr}; + traccc::edm::track_container::const_data + tracksData{tracks}; + Acts::TrackingGeometry* dummyActsGeometry = nullptr; + traccc::host_detector dummyDetrayGeometry; + + // Create the track container. + traccc::edm::DeviceTrackContainer trackContainer{ + traccc::edm::DeviceTrackBackend{tracksData, *dummyActsGeometry, + dummyDetrayGeometry}, + traccc::edm::DeviceMultiTrajectory{tracksData, *dummyActsGeometry, + dummyDetrayGeometry}}; + + // Check that the size is zero. + ASSERT_EQ(trackContainer.size(), 0u); +}