Skip to content

Commit

Permalink
refactor: Add concepts for Track(State) backends (#2093)
Browse files Browse the repository at this point in the history
This PR adds concepts for the `MultiTrajectory` and `TrackContainer` backends. It also centralizes the index typedef and `kInvalid` sentinel value definition.

Blocked by:
- #2091
  • Loading branch information
paulgessinger committed May 24, 2023
1 parent f7ccfee commit 20a45ed
Show file tree
Hide file tree
Showing 9 changed files with 277 additions and 16 deletions.
13 changes: 5 additions & 8 deletions Core/include/Acts/EventData/MultiTrajectory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "Acts/EventData/MeasurementHelpers.hpp"
#include "Acts/EventData/SourceLink.hpp"
#include "Acts/EventData/TrackStatePropMask.hpp"
#include "Acts/EventData/Types.hpp"
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Utilities/HashedString.hpp"
#include "Acts/Utilities/Helpers.hpp"
Expand Down Expand Up @@ -210,9 +211,6 @@ struct TrackStateTraits {
using MeasurementCovariance =
typename detail_lt::Types<M, ReadOnly>::CovarianceMap;

using IndexType = std::uint32_t;
static constexpr IndexType kInvalid = std::numeric_limits<IndexType>::max();

constexpr static auto ProjectorFlags = Eigen::RowMajor | Eigen::AutoAlign;
using Projector =
Eigen::Matrix<typename Covariance::Scalar, M, eBoundSize, ProjectorFlags>;
Expand Down Expand Up @@ -244,8 +242,8 @@ class TrackStateProxy {
using ConstMeasurementCovariance =
typename TrackStateTraits<N, true>::MeasurementCovariance;

using IndexType = typename TrackStateTraits<M, ReadOnly>::IndexType;
static constexpr IndexType kInvalid = TrackStateTraits<M, ReadOnly>::kInvalid;
using IndexType = TrackIndexType;
static constexpr IndexType kInvalid = kTrackIndexInvalid;

// as opposed to the types above, this is an actual Matrix (rather than a
// map)
Expand Down Expand Up @@ -1126,9 +1124,8 @@ constexpr bool VisitorConcept = Concepts ::require<
/// from @c TrackStateTraits using the default maximum measurement dimension.
namespace MultiTrajectoryTraits {
constexpr unsigned int MeasurementSizeMax = eBoundSize;
using IndexType = TrackStateTraits<MeasurementSizeMax, true>::IndexType;
constexpr IndexType kInvalid =
TrackStateTraits<MeasurementSizeMax, true>::kInvalid;
using IndexType = TrackIndexType;
constexpr IndexType kInvalid = kTrackIndexInvalid;
} // namespace MultiTrajectoryTraits

template <typename T>
Expand Down
132 changes: 132 additions & 0 deletions Core/include/Acts/EventData/MultiTrajectoryBackendConcept.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// This file is part of the Acts project.
//
// Copyright (C) 2023 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/Definitions/Algebra.hpp"
#include "Acts/Definitions/TrackParametrization.hpp"
#include "Acts/EventData/SourceLink.hpp"
#include "Acts/EventData/TrackStatePropMask.hpp"
#include "Acts/EventData/Types.hpp"
#include "Acts/Surfaces/Surface.hpp"
#include "Acts/Utilities/HashedString.hpp"

#include <any>
#include <type_traits>

#if defined(ACTS_CONCEPTS_SUPPORTED)
#include <concepts>

namespace Acts {

namespace detail {
using Parameters = Eigen::Map<BoundVector>;
using Covariance = Eigen::Map<BoundMatrix>;

using ConstParameters = Eigen::Map<const BoundVector>;
using ConstCovariance = Eigen::Map<const BoundMatrix>;

} // namespace detail

template <typename T>
concept CommonMultiTrajectoryBackend = requires(const T& cv, HashedString key,
TrackIndexType istate) {
{ cv.calibratedSize_impl(istate) } -> std::same_as<TrackIndexType>;

{ cv.getUncalibratedSourceLink_impl(istate) } -> std::same_as<SourceLink>;

{ cv.referenceSurface_impl(istate) } -> std::same_as<const Surface*>;

{ cv.parameters_impl(istate) } -> std::same_as<detail::ConstParameters>;

{ cv.covariance_impl(istate) } -> std::same_as<detail::ConstCovariance>;

{ cv.jacobian_impl(istate) } -> std::same_as<detail::ConstCovariance>;

{
cv.template measurement_impl<2>(istate)
} -> std::same_as<Eigen::Map<const ActsVector<2>>>;

{
cv.template measurementCovariance_impl<2>(istate)
} -> std::same_as<Eigen::Map<const ActsSymMatrix<2>>>;

{ cv.has_impl(key, istate) } -> std::same_as<bool>;

{ cv.size_impl() } -> std::same_as<TrackIndexType>;

{ cv.component_impl(key, istate) } -> std::same_as<std::any>;

{ cv.hasColumn_impl(key) } -> std::same_as<bool>;
};

template <typename T>
concept ConstMultiTrajectoryBackend = CommonMultiTrajectoryBackend<T> &&
requires(T v, HashedString key, TrackIndexType istate) {
{ v.parameters_impl(istate) } -> std::same_as<detail::ConstParameters>;

{ v.covariance_impl(istate) } -> std::same_as<detail::ConstCovariance>;

{ v.jacobian_impl(istate) } -> std::same_as<detail::ConstCovariance>;

{
v.template measurement_impl<2>(istate)
} -> std::same_as<Eigen::Map<const ActsVector<2>>>;

{
v.template measurementCovariance_impl<2>(istate)
} -> std::same_as<Eigen::Map<const ActsSymMatrix<2>>>;
};

template <typename T>
concept MutableMultiTrajectoryBackend = CommonMultiTrajectoryBackend<T> &&
requires(T v, HashedString key, TrackIndexType istate,
TrackStatePropMask mask, std::string col, size_t dim,
SourceLink sl, std::shared_ptr<const Surface> surface) {
{ v.parameters_impl(istate) } -> std::same_as<detail::Parameters>;

{ v.covariance_impl(istate) } -> std::same_as<detail::Covariance>;

{ v.jacobian_impl(istate) } -> std::same_as<detail::Covariance>;

{
v.template measurement_impl<2>(istate)
} -> std::same_as<Eigen::Map<ActsVector<2>>>;

{
v.template measurementCovariance_impl<2>(istate)
} -> std::same_as<Eigen::Map<ActsSymMatrix<2>>>;

{ v.addTrackState_impl() } -> std::same_as<TrackIndexType>;

{v.shareFrom_impl(istate, istate, mask, mask)};

{v.unset_impl(mask, istate)};

{v.clear_impl()};

// As far as I know there's no good way to assert that there's a generic
// template function
{v.template addColumn_impl<uint32_t>(col)};
{v.template addColumn_impl<uint64_t>(col)};
{v.template addColumn_impl<int32_t>(col)};
{v.template addColumn_impl<int64_t>(col)};
{v.template addColumn_impl<float>(col)};
{v.template addColumn_impl<double>(col)};

{v.allocateCalibrated_impl(istate, dim)};

{v.setUncalibratedSourceLink_impl(istate, sl)};

{v.setReferenceSurface_impl(istate, surface)};

// @TODO: Add copyDynamicFrom + ensureDynamicColumns for MTJ like in TrackContainer
};

} // namespace Acts
#endif
18 changes: 12 additions & 6 deletions Core/include/Acts/EventData/TrackContainer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
#include "Acts/Definitions/Units.hpp"
#include "Acts/EventData/Charge.hpp"
#include "Acts/EventData/MultiTrajectory.hpp"
#include "Acts/EventData/TrackContainerBackendConcept.hpp"
#include "Acts/EventData/TrackProxy.hpp"
#include "Acts/EventData/Types.hpp"
#include "Acts/EventData/Utils.hpp"
#include "Acts/Utilities/HashedString.hpp"
#include "Acts/Utilities/Holders.hpp"
Expand All @@ -34,7 +36,8 @@ struct IsReadOnlyTrackContainer;
/// @tparam track_container_t the track container backend
/// @tparam traj_t the track state container backend
/// @tparam holder_t ownership management class for the backend
template <typename track_container_t, typename traj_t,
template <ACTS_CONCEPT(TrackContainerBackend) track_container_t,
typename traj_t,
template <typename> class holder_t = detail::RefHolder>
class TrackContainer {
public:
Expand All @@ -47,8 +50,8 @@ class TrackContainer {
"Either both track container and track state container need to "
"be readonly or both have to be readwrite");

using IndexType = MultiTrajectoryTraits::IndexType;
static constexpr IndexType kInvalid = MultiTrajectoryTraits::kInvalid;
using IndexType = TrackIndexType;
static constexpr IndexType kInvalid = kTrackIndexInvalid;

using TrackProxy =
Acts::TrackProxy<track_container_t, traj_t, holder_t, false>;
Expand Down Expand Up @@ -296,15 +299,18 @@ class TrackContainer {
detail_tc::ConstIf<holder_t<traj_t>, ReadOnly> m_traj;
};

template <typename track_container_t, typename traj_t>
template <ACTS_CONCEPT(TrackContainerBackend) track_container_t,
typename traj_t>
TrackContainer(track_container_t& container, traj_t& traj)
-> TrackContainer<track_container_t, traj_t, detail::RefHolder>;

template <typename track_container_t, typename traj_t>
template <ACTS_CONCEPT(TrackContainerBackend) track_container_t,
typename traj_t>
TrackContainer(const track_container_t& container, const traj_t& traj)
-> TrackContainer<track_container_t, traj_t, detail::ConstRefHolder>;

template <typename track_container_t, typename traj_t>
template <ACTS_CONCEPT(TrackContainerBackend) track_container_t,
typename traj_t>
TrackContainer(track_container_t&& container, traj_t&& traj)
-> TrackContainer<track_container_t, traj_t, detail::ValueHolder>;

Expand Down
87 changes: 87 additions & 0 deletions Core/include/Acts/EventData/TrackContainerBackendConcept.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// This file is part of the Acts project.
//
// Copyright (C) 2023 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/Definitions/TrackParametrization.hpp"
#include "Acts/EventData/Types.hpp"
#include "Acts/Surfaces/Surface.hpp"
#include "Acts/Utilities/HashedString.hpp"

#include <any>
#include <type_traits>

#if defined(ACTS_CONCEPTS_SUPPORTED)
#include <concepts>

namespace Acts {

namespace detail {
using Parameters = Eigen::Map<BoundVector>;
using Covariance = Eigen::Map<BoundMatrix>;

using ConstParameters = Eigen::Map<const BoundVector>;
using ConstCovariance = Eigen::Map<const BoundMatrix>;
} // namespace detail

template <typename T>
concept ConstTrackContainerBackend = requires(const T& cv, HashedString key,
TrackIndexType itrack) {
{ cv.size_impl() } -> std::same_as<std::size_t>;

{ cv.component_impl(key, itrack) } -> std::same_as<std::any>;

{ cv.parameters(itrack) } -> std::same_as<detail::ConstParameters>;

{ cv.covariance(itrack) } -> std::same_as<detail::ConstCovariance>;

{ cv.hasColumn_impl(key) } -> std::same_as<bool>;

{ cv.referenceSurface_impl(itrack) } -> std::same_as<const Surface*>;
};

template <typename T>
concept MutableTrackContainerBackend = ConstTrackContainerBackend<T> &&
requires(T v, HashedString key, TrackIndexType itrack, std::string col,
const T& other, std::shared_ptr<const Surface> sharedSurface) {
{ v.parameters(itrack) } -> std::same_as<detail::Parameters>;

{ v.covariance(itrack) } -> std::same_as<detail::Covariance>;

{ v.addTrack_impl() } -> std::same_as<TrackIndexType>;

{v.removeTrack_impl(itrack)};

// As far as I know there's no good way to assert that there's a generic
// template function
{v.template addColumn_impl<uint32_t>(col)};
{v.template addColumn_impl<uint64_t>(col)};
{v.template addColumn_impl<int32_t>(col)};
{v.template addColumn_impl<int64_t>(col)};
{v.template addColumn_impl<float>(col)};
{v.template addColumn_impl<double>(col)};

{v.copyDynamicFrom_impl(itrack, other, itrack)};

{v.ensureDynamicColumns_impl(other)};

{v.reserve(itrack)};

{v.setReferenceSurface_impl(itrack, sharedSurface)};
};

template <typename T>
struct IsReadOnlyTrackContainer;

template <typename T>
concept TrackContainerBackend = ConstTrackContainerBackend<T> &&
(IsReadOnlyTrackContainer<T>::value || MutableTrackContainerBackend<T>);

} // namespace Acts

#endif
5 changes: 3 additions & 2 deletions Core/include/Acts/EventData/TrackProxy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@
#include "Acts/EventData/Charge.hpp"
#include "Acts/EventData/MultiTrajectory.hpp"
#include "Acts/EventData/TrackStatePropMask.hpp"
#include "Acts/Utilities/Concepts.hpp"
#include "Acts/Utilities/UnitVectors.hpp"

#include <iterator>
#include <type_traits>

namespace Acts {

template <typename track_container_t, typename traj_t,
template <typename> class holder_t>
template <ACTS_CONCEPT(Acts::TrackContainerBackend) track_container_t,
typename traj_t, template <typename> class holder_t>
class TrackContainer;

namespace detail_tc {
Expand Down
19 changes: 19 additions & 0 deletions Core/include/Acts/EventData/Types.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// This file is part of the Acts project.
//
// Copyright (C) 2023 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#include <cstdint>
#include <limits>

namespace Acts {
using TrackIndexType = std::uint32_t;
static constexpr TrackIndexType kTrackIndexInvalid =
std::numeric_limits<TrackIndexType>::max();

} // namespace Acts
7 changes: 7 additions & 0 deletions Core/include/Acts/EventData/VectorMultiTrajectory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@

#include "Acts/Definitions/TrackParametrization.hpp"
#include "Acts/EventData/MultiTrajectory.hpp"
#include "Acts/EventData/MultiTrajectoryBackendConcept.hpp"
#include "Acts/EventData/TrackStatePropMask.hpp"
#include "Acts/EventData/detail/DynamicColumn.hpp"
#include "Acts/Utilities/Concepts.hpp"

#include <unordered_map>

Expand Down Expand Up @@ -452,6 +454,8 @@ class VectorMultiTrajectory final
// END INTERFACE
};

ACTS_STATIC_CHECK_CONCEPT(MutableMultiTrajectoryBackend, VectorMultiTrajectory);

class ConstVectorMultiTrajectory;
template <>
struct IsReadOnlyMultiTrajectory<ConstVectorMultiTrajectory> : std::true_type {
Expand Down Expand Up @@ -532,4 +536,7 @@ class ConstVectorMultiTrajectory final
// END INTERFACE
};

ACTS_STATIC_CHECK_CONCEPT(ConstMultiTrajectoryBackend,
ConstVectorMultiTrajectory);

} // namespace Acts

0 comments on commit 20a45ed

Please sign in to comment.