High-level Track Event Data Model

Track information in ACTS can be divided into two parts: track-level information and track state-level information.

Track-level information are properties that relate to the full track. This includes the fitted track parameters with respect to some reference point, often the origin of the detector or the beamspot. It can also include summary information from the track finding stage, like the overall number of clusters that were used in the creation of the track, or the fit quality from the track fit.

Tracks are built-up from track states, where each track state corresponds to a discrete state determining the track properties. This mainly includes measurements states, expected intersections with sensors where no measurement was found (holes), and intersections with known passive material. The EDM allows building up a track from these track states iteratively. For example, the Kalman Filter will append track states to the sequence whenever it encounters a sensitive detector layer. The content of the track states is defined such that the fitter can store all relevant information, with as little need for extra information as possible. It is also designed to be flexible enough to support different fitters, which might require different information to be stored, as well as the Combinatorial Kalman Filter, which produces a tree of track states, instead of a fully linear sequence.

Ultimately, each output track is associated with a well-defined sequence of track states, allowing downstream consumers of the EDM to access the fully detailed information produced during track reconstruction.


This section will first discuss the architecture and general implementation of the Track EDM in Conceptual, and then report on the API of the involved classes in Track API.

Conceptual

Architecture

The Track EDM is structured such that the memory-layout can be SoA, while presenting an object-oriented interface for convenient usage.

Fig. 19 shows this object-oriented access model for the example of the track container and track proxy object. The track container holds vectors of the various pieces of information, and has methods to add a track, and to allow iteration over all tracks. This iteration, or index based access, yields a track proxy object, which exposes the properties as methods returning references, while internally only holding a pointer to and an index into the track container. The types are built in a way that preserves const-correctness, i.e. even though a track proxy is a value type which can be copied, it will not allow modification of the underlying track container if it is immutable:

auto mutableTrackContainer = /*...*/;
auto trackProxy = mutableTrackContainer.getTrack(5); // is mutable
const auto& constTrackProxy = trackProxy; // is const
// ...
auto constTrackContainer = /*...*/;
auto trackProxy = trackContainer.getTrack(5); // is const, even as an lvalue
../../_images/proxy.svg

Fig. 19 Illustration of the proxy pattern used in the track EDM. The track proxy logically represents a single track, and points to the data stored in the track container.

The track EDM is fully agnostic to the concrete persistency framework of an experiment. This avoids having to convert the data between different representations, if implemented correctly.

Implementation

To make the EDM implementation independent of an experiment persistency framework, it is separated into a frontend layer and a backend layer. The frontend layer contains user-facing getters and setters, as well as convenience methods that can be helpful. These methods are located either in the proxy objects or in the containers, depending on whether they operate on a single element or the entire container.

Overall, there are four main classes that make up the frontend layer: Acts::TrackProxy, Acts::TrackContainer, Acts::TrackStateProxy and Acts::MultiTrajectory. The latter serves as the track state container, where the name indicates that it is able to handle a branching tree structure of track states. TrackProxy and TrackStateProxy expose methods to get the local track parameters and covariance, corresponding reference surface, and also includes global statistics like the total number of measurements, outliers or holes in case of TrackProxy. TrackProxy also has a method to conveniently iterate over the associated track states from the last track state to the first one yielding TrackStateProxy objects from the track state container. In the common case of a track from the center of a cylindrical detector going outward, the default iteration order is from the outside inwards.

In case of TrackStateProxy, functionality is exposed in the frontend layer to allocate optional components, with the goal of reduced memory footprint. There are two main use cases of this: track parameters and measurements. The track-state EDM supports storing up to three sets of local track parameters and covariance matrices, modeled after the information the Kalman Filter formalism needs to store:

  1. predicted parameter vector and covariance matrix

  2. filtered parameter vector and covariance matrix

  3. smoothed parameter vector and covariance matrix

In case of combinatorial track finding (see Track Finding, specifically Fig. 16), track hypothesis can start out with a common sequence of track states, and then branch out when multiple compatible measurements are encountered, as seen in Fig. 21.

The track state EDM allows allocating only the track parameters that are needed, and also allows sharing the same track parameters between multiple track states, so that branching track states can share for example the same predicted parameters. How this is achieved exactly is left to the backend layer. Measurements are handled in a similar way, where the track finding decides how much storage is needed based on the number of dimensions of an incoming measurement. It then instructs the EDM through the frontend layer to ensure enough memory is available, where the specifics are again left up to the backend layer.

The backend layer exposes an interface that is used by the frontend layer to store and retrieve information. It uses dedicated methods where needed, such as for storing reference surfaces or source-link objects, which are lightweight container objects for experiment-specific measurements. For the majority of components, the frontend communicates with the backend through a single method to obtain references to the underlying data. Components are accessed via hashes of the component name, where the hashes are calculated at compile-time wherever possible. The backend can then use the hashed component name to retrieve the relevant memory. To allow directly manipulating the backing memory, the frontend expects the backend to return references into the backing storage.

TrackProxy provides a method to copy a track between different track containers, and only uses the frontend layer to accomplish this. This means that copying tracks between different backend implementations is trivial.

../../_images/edm_diagram.svg

Fig. 20 Diagram of the EDM architecture. The frontend layer is used by other ACTS components, and downstream clients. It is separated from the backend layer by an interface. Conversion to and from EDM4hep is possible. Examples of direct backend implementations are shown.

Fig. 20 shows a diagram of the EDM architecture. At the center are the TrackProxy and TrackContainer. These classes are produced by the track finding and track fitting components, and are the main interface point with the clients of tracking. In ACTS itself, all of the performance monitoring and downstream reconstruction is either directly built on top of these objects, or converts them into an internal EDM on the use case. Behind the backend interface, the track container coordinates with both a track state and a track backend, where a few examples are shown, and will be discussed below.

Track API

template<typename track_container_t, typename trajectory_t, template<typename> class holder_t, bool read_only = true>
class TrackProxy

Proxy class representing a single track.

This class provides a view into an associated TrackContainer, and has reference semantics. You can think of it as a pointer to a vector of tracks, which exposes an object-oriented interface for accessing the track properties.

Template Parameters:
  • track_container_t – the container backend

  • trajectory_t – the track state container backend

  • holder_t – ownership management class for the backend

  • read_only – true if this track container is not mutable

Constructors and assignment operator

Public constructors and assignment operators for TrackProxy only allow construction from another TrackProxy. You should generally not have to construct TrackProxy manually.

inline TrackProxy(const MutableTrackProxy &other)

Copy constructor from a mutable track proxy.

This is always valid, either mutable to mutable or mutable to const

Parameters:

other – the other track state proxy

inline TrackProxy &operator=(const MutableTrackProxy &other)

Copy assignment operator from mutable track proxy.

This is always valid, either mutable to mutable or mutable to const

Parameters:

other – the other track state proxy

TrackProxy properties

Methods that give access to the properties of a track represented by TrackProxy.

Many of these methods come in a const and a non-const version. The non-const version is only available if you have an instance of TrackProxy that does not have the read_only template parameter set to true, even if you hold it as an lvalue.

inline IndexType tipIndex() const

Get the tip index, i.e.

the entry point into the track state container

Returns:

the tip index by value

inline IndexType stemIndex() const

Index of the stem, i.e.

the innermost track state of the track. This might be invalid, signifying that the track state is not forward-linked.

Returns:

the stem index

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline IndexType &tipIndex()

Get a mutable reference to the tip index, i.e.

the entry point into the track container

Note

Only available if the track proxy is not read-only

Returns:

mutable reference to the tip index

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline IndexType &stemIndex()

Index of the stem, i.e.

the innermost track state of the track. This might be invalid, signifying that the track state is not forward-linked.

Note

Only available if the track proxy is not read-only

Returns:

mutable reference to the stem index

inline const Surface &referenceSurface() const

Get the reference surface of the track (e.g.

the perigee)

Returns:

the reference surface

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void setReferenceSurface(std::shared_ptr<const Surface> srf)

Set a new reference surface for this track.

Parameters:

srf – The surface to set

inline bool hasReferenceSurface() const

Returns whether the track has a reference surface or not.

Returns:

whether a surface exists or not

inline ConstParameters parameters() const

Get the parameters of the track at the reference surface (e.g.

perigee). Const version

Returns:

Proxy vector for the parameters

inline ConstCovariance covariance() const

Get the covariance of the track at the reference surface (e.g.

perigee). Const version

Returns:

Proxy matrix for the covariance

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline Parameters parameters()

Get the parameters of the track at the reference surface (e.g.

perigee). Mutable version

Note

Only available if the track proxy is not read-only

Returns:

Proxy vector for the parameters

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline Covariance covariance()

Get the covariance of the track at the reference surface (e.g.

perigee). Mutable version

Note

Only available if the track proxy is not read-only

Returns:

Proxy matrix for the covariance

inline ActsScalar theta() const

Access the theta parameter of the track at the reference surface.

Returns:

The theta parameter

inline ActsScalar phi() const

Access the phi parameter of the track at the reference surface.

Returns:

The phi parameter

inline ActsScalar loc0() const

Access the loc0 parameter of the track at the reference surface.

Returns:

The loc0 parameter

inline ActsScalar loc1() const

Access the loc1 parameter of the track at the reference surface.

Returns:

The loc1 parameter

inline ActsScalar time() const

Access the time parameter of the track at the reference surface.

Returns:

The time parameter

inline ActsScalar qOverP() const

Access the q/p (curvature) parameter of the track at the reference surface.

Returns:

The q/p parameter

inline ParticleHypothesis particleHypothesis() const

Get the particle hypothesis.

Returns:

the particle hypothesis

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void setParticleHypothesis(const ParticleHypothesis &particleHypothesis)

Set a new particle hypothesis for this track.

Note

Only available if the track proxy is not read-only

Parameters:

particleHypothesis – The particle hypothesis to set

inline ActsScalar charge() const

Get the charge of the tack.

Note

this depends on the charge hypothesis

Returns:

The absolute track momentum

inline ActsScalar absoluteMomentum() const

Get the absolute momentum of the tack.

Returns:

The absolute track momentum

inline ActsScalar transverseMomentum() const

Get the transverse momentum of the track.

Returns:

The track transverse momentum value

inline Vector3 direction() const

Get a unit vector along the track direction at the reference surface.

Returns:

The direction unit vector

inline Vector3 momentum() const

Get the global momentum vector.

Returns:

the global momentum vector

inline unsigned int nTrackStates() const

Return the number of track states associated to this track.

Note

This is calculated by iterating over the track states which is somewhat expensive. Consider caching this value if you need It more than once.

Returns:

The number of track states

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline unsigned int &nMeasurements()

Return the number of measurements for the track.

Const version

Note

Only available if the track proxy is not read-only

Returns:

The number of measurements

inline unsigned int nMeasurements() const

Return a mutable reference to the number of measurements for the track.

Mutable version

Returns:

The number of measurements

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline unsigned int &nHoles()

Return a mutable reference to the number of holes for the track.

Mutable version

Note

Only available if the track proxy is not read-only

Returns:

The number of holes

inline unsigned int nHoles() const

Return the number of measurements for the track.

Const version

Returns:

The number of measurements

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline unsigned int &nOutliers()

Return a mutable reference to the number of outliers for the track.

Mutable version

Note

Only available if the track proxy is not read-only

Returns:

The number of outliers

inline unsigned int nOutliers() const

Return the number of outliers for the track.

Const version

Returns:

The number of outliers

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline unsigned int &nSharedHits()

Return a mutable reference to the number of shared hits for the track.

Mutable version

Note

Only available if the track proxy is not read-only

Returns:

The number of shared hits

inline unsigned int nSharedHits() const

Return the number of shared hits for the track.

Const version

Returns:

The number of shared hits

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline float &chi2()

Return a mutable reference to the chi squared Mutable version.

Note

Only available if the track proxy is not read-only

Returns:

The chi squared

inline float chi2() const

Return the chi squared for the track.

Const version

Returns:

The chi squared

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline unsigned int &nDoF()

Return a mutable reference to the number of degrees of freedom for the track.

Mutable version

Note

Only available if the track proxy is not read-only

Returns:

The number of degrees of freedom

inline unsigned int nDoF() const

Return the number of degrees of freedom for the track.

Const version

Returns:

The number of degrees of freedom

inline IndexType index() const

Return the index of this track in the track container.

Note

This is separate from the tip index

Returns:

the track index

TrackProxy track state access

Methods that give access to the track states of a track represented by TrackProxy.

inline auto innermostTrackState() const

Return a const track state proxy to the innermost track state.

Note

This is only available, if the track is forward linked

Returns:

The innermost track state proxy

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline auto innermostTrackState()

Return a mutable track state proxy to the innermost track state.

Note

This is only available, if the track is forward linked

Note

Only available if the track proxy is not read-only

Returns:

The innermost track state proxy

inline auto trackStatesReversed() const

Get a range over the track states of this track.

Return value is compatible with range based for loop. Const version

Note

This range is from the outside inwards!

Returns:

Track state range to iterate over

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline auto trackStatesReversed()

Get a range over the track states of this track.

Return value is compatible with range based for loop. Mutable version

Note

Only available if the track proxy is not read-only

Note

This range is from the outside inwards!

Returns:

Track state range to iterate over

inline auto trackStates() const

Get a range over the track states of this track.

Return value is compatible with range based for loop. This overload returns a const-only track state range, which means you cannot modify the track states obtained in the iteration.

Note

This range is from the inside out!

Warning

This access direction is only possible if the track states are forward-linked.

Returns:

Track state range to iterate over

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline auto trackStates()

Get a range over the track states of this track.

Return value is compatible with range based for loop. This overload returns a mutable track state range, which means you can modify the track states obtained in the iteration.

Note

Only available if the track proxy is not read-only

Note

This range is from the inside out!

Warning

This access direction is only possible if the track states are forward-linked.

Returns:

Track state range to iterate over

TrackProxy track state manipulation

Methods that manipulate the track states of a track represented by TrackProxy.

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void linkForward()

Forward connect a track.

This means setting indices from the inside out on all track states.

Note

Only available if the track proxy is not read-only

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline auto appendTrackState(TrackStatePropMask mask = TrackStatePropMask::All)

Append a track state to this track.

This will modify the tip index to point at the newly created track state, which will be directly after the previous track state at tip index.

Note

Only available if the track proxy is not read-only

Parameters:

mask – The allocation prop mask for the new track state

Returns:

The newly added track state

template<typename track_proxy_t, bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void copyFrom(const track_proxy_t &other, bool copyTrackStates = true)

Copy the content of another track proxy into this one.

Note

Only available if the track proxy is not read-only

Template Parameters:

track_proxy_t – the other track proxy’s type

Parameters:
  • other – The track proxy

  • copyTrackStates – Copy the track state sequence from other

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void reverseTrackStates(bool invertJacobians = false)

Reverse the ordering of track states for this track Afterwards, the previous endpoint of the track state sequence will be the “innermost” track state.

Note

Only available if the track proxy is not read-only

Note

This is dangerous with branching track state sequences, as it will break them

Note

This also automatically forward-links the track!

Parameters:

invertJacobians – Whether to invert the Jacobians of the track states

TrackProxy generic component access

Methods that give access to generic components of a track represented by TrackProxy.

Internally, a compile-time hash of the component name is used to identify which component is being requested. Most of the named methods in TrackProxy properties use these methods to retrieve the actual data.

A number of overloads exist, where you can either supply the HashedString key as a template parameter or a runtime argument. The former has the advantage of being guaranteed to be evaluated at compile-time.

template<typename T, HashedString key, bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline constexpr T &component()

Retrieve a mutable reference to a component.

Template Parameters:
  • T – The type of the component to access

  • key – String key for the component to access

Returns:

Mutable reference to the component given by key

template<typename T, bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline constexpr T &component(HashedString key)

Retrieve a mutable reference to a component.

Template Parameters:

T – The type of the component to access

Parameters:

key – String key for the component to access

Returns:

Mutable reference to the component given by key

template<typename T, bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline constexpr T &component(std::string_view key)

Retrieve a mutable reference to a component.

Note

This might hash the key at runtime instead of compile-time

Template Parameters:

T – The type of the component to access

Parameters:

key – String key for the component to access

Returns:

Mutable reference to the component given by key

template<typename T, HashedString key>
inline constexpr const T &component() const

Retrieve a const reference to a component.

Template Parameters:
  • T – The type of the component to access

  • key – String key for the component to access

Returns:

Const reference to the component given by key

template<typename T>
inline constexpr const T &component(HashedString key) const

Retrieve a const reference to a component.

Template Parameters:

T – The type of the component to access

Parameters:

key – String key for the component to access

Returns:

Const reference to the component given by key

template<typename T>
inline constexpr const T &component(std::string_view key) const

Retrieve a const reference to a component.

Note

This might hash the key at runtime instead of compile-time

Template Parameters:

T – The type of the component to access

Parameters:

key – String key for the component to access

Returns:

Const reference to the component given by key

Public Types

using ConstCovariance = typename detail_lt::Types<eBoundSize, true>::CovarianceMap

Same as Covariance, but with const semantics.

using ConstParameters = typename detail_lt::Types<eBoundSize, true>::CoefficientsMap

Same as Parameters, but with const semantics.

using ConstProxyType = ConstTrackProxy

Alias for an associated const track proxy, with the same backends.

using ConstTrackProxy = TrackProxy<track_container_t, trajectory_t, holder_t, true>

Alias for the const version of this track proxy, with the same backends.

using ConstTrackStateProxy = typename Trajectory::ConstTrackStateProxy

Alias for an associated const track state proxy, with the same backends.

using Container = track_container_t

The track container backend given as a template parameter.

using Covariance = typename detail_lt::Types<eBoundSize, false>::CovarianceMap

Map-type for a bound covariance.

This has reference semantics, i.e. points at a matrix by an internal pointer.

using IndexType = typename Container::IndexType

The index type of the track container.

using MutableTrackProxy = TrackProxy<track_container_t, trajectory_t, holder_t, false>

Alias for the mutable version of this track proxy, with the same backends.

using Parameters = typename detail_lt::Types<eBoundSize, false>::CoefficientsMap

Map-type for a bound parameter vector.

This has reference semantics, i.e. points at a matrix by an internal pointer.

using TrackStateProxy = typename Trajectory::TrackStateProxy

Alias for an associated mutable track state proxy, with the same backends.

using Trajectory = trajectory_t

The track state container backend given as a template parameter.

Public Functions

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline auto &container()

Return a reference to the track container backend, mutable version.

Note

Only available if the track proxy is not read-only

Returns:

reference to the track container backend

inline const auto &container() const

Return a reference to the track container backend, const version.

Returns:

reference to the track container backend

inline BoundTrackParameters createParametersAtReference() const

Return the track parameters at the reference surface.

Note

The parameters are created on the fly

Returns:

the track parameters

inline BoundTrackParameters createParametersFromState(const ConstTrackStateProxy &trackState) const

Convert a track state into track parameters.

Note

The parameters are created on the fly

Returns:

the track parameters

inline bool operator==(const TrackProxy &other) const

Equality operator with another track proxy Checks the container identity and the track index.

Returns:

True if the track proxies refer to the same track

Public Static Attributes

static constexpr IndexType kInvalid = Container::kInvalid

Sentinel value that indicates an invalid index.

static constexpr bool ReadOnly = read_only

Indicates whether this track proxy is read-only or if it can be modified.

template<ACTS_CONCEPT track_container_t(TrackContainerBackend), typename traj_t, template<typename> class holder_t = detail::RefHolder>
class TrackContainer

Track container interface class.

This type represents a collections of tracks. It uses a backend to store both the actual tracks and the associated track states.

Template Parameters:
  • track_container_t – the track container backend

  • traj_t – the track state container backend

  • holder_t – ownership management class for the backend

TrackContainer construction

Constructors for the track container by using a set of backends (track + track state). The container can either take ownership of the backends or just hold references to them. This is driven by the holder_t template parameter, where you can also supply a custom holder type. Template deduction is used to try to guess the correct holder type.

inline TrackContainer(holder_t<track_container_t> container, holder_t<traj_t> traj)

Constructor from a track container backend and a track state container backend.

Parameters:
  • container – the track container backend

  • traj – the track state container backend

template<template<typename> class H = holder_t, typename = std::enable_if_t<detail::is_same_template<H, detail::RefHolder>::value>>
inline TrackContainer(track_container_t &container, traj_t &traj)

Constructor from references to a track container backend and to a track state container backend.

Note

The track container will not assume ownership over the backends in this case. You need to ensure suitable lifetime

Parameters:
  • container – the track container backend

  • traj – the track state container backend

template<template<typename> class H = holder_t, bool RO = (IsReadOnlyTrackContainer<track_container_t>::value && IsReadOnlyMultiTrajectory<traj_t>::value), typename = std::enable_if_t<detail::is_same_template<H, detail::ConstRefHolder>::value && RO>>
inline TrackContainer(const track_container_t &container, const traj_t &traj)

Constructor from const references to a track container backend and to a track state container backend.

Note

The track container will not assume ownership over the backends in this case. You need to ensure suitable lifetime

Parameters:
  • container – the track container backend

  • traj – the track state container backend

TrackContainer track (proxy) access and manipulation

These methods allow accessing tracks, i.e. adding or retrieving a track proxy that points at a specific track in the container.

inline ConstTrackProxy getTrack(IndexType itrack) const

Get a const track proxy for a track index.

Parameters:

itrack – the track index in the container

Returns:

A const track proxy for the index

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline TrackProxy getTrack(IndexType itrack)

Get a mutable track proxy for a track index.

Note

Only available if the track container is not read-only

Parameters:

itrack – the track index in the container

Returns:

A mutable track proxy for the index

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline IndexType addTrack()

Add a track to the container.

Note this only creates the logical track and allocates memory. You can combine this with getTrack to obtain a track proxy

Note

Only available if the track container is not read-only

Returns:

the index to the newly added track

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline TrackProxy makeTrack()

Add a track to the container and return a track proxy to it This effectively calls addTrack and getTrack.

Note

Only available if the track container is not read-only

Returns:

a track proxy to the newly added track

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void removeTrack(IndexType itrack)

Remove a track at index itrack from the container.

Note

Only available if the track container is not read-only

Note

This invalidates track proxies that point to tracks with larger indices than itrack!

Parameters:

itrack – The index of the track to remove

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline auto begin()

Get a mutable iterator to the first track in the container.

Note

Only available if the track container is not read-only

Returns:

a mutable iterator to the first track

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline auto end()

Get a past-the-end iterator for this container.

Note

Only available if the track container is not read-only

Returns:

a past-the-end iterator

inline auto begin() const

Get an const iterator to the first track in the container.

Returns:

a const iterator to the first track

inline auto end() const

Get a past-the-end iterator for this container.

Returns:

a past-the-end iterator

TrackContainer column management

TrackContainer can manage a set of common static columns, and dynamic columns that can be added at runtime.

This set of methods allows you to manage the dynamic columns.

template<typename T, bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline constexpr void addColumn(const std::string &key)

Add a dymanic column to the track container.

Note

Only available if the track container is not read-only

Parameters:

key – the name of the column to be added

inline constexpr bool hasColumn(const std::string &key) const

Check if this track container has a specific dynamic column.

Parameters:

key – the key to check for

inline constexpr bool hasColumn(HashedString key) const

Check if a this track container has a specific dynamic column.

Parameters:

key – the key to check for

template<typename other_track_container_t, bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void ensureDynamicColumns(const other_track_container_t &other)

Helper function to make this track container match the dynamic columns of another one.

This will only work if the track container supports this source, and depends on the implementation details of the dynamic columns of the container

Note

Only available if the track container is not read-only

Template Parameters:

other_track_container_t – Type of the other track container

Parameters:

other – The other track container

TrackContainer backend access

These methods allow accessing the backend of the track container.

In most cases, this is not necessary for interacting with the container.

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline auto &container()

Get a mutable reference to the track container backend.

Note

Only available if the track container is not read-only

Returns:

a mutable reference to the backend

inline const auto &container() const

Get a const reference to the track container backend.

Returns:

a const reference to the backend

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline auto &trackStateContainer()

Get a mutable reference to the track state container backend.

Note

Only available if the track container is not read-only

Returns:

a mutable reference to the backend

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline auto &trackStateContainerHolder()

Retrieve the holder of the track state container.

Note

Only available if the track container is not read-only

Returns:

The track state container including it’s holder

inline const auto &trackStateContainer() const

Get a const reference to the track state container backend.

Returns:

a const reference to the backend

inline const auto &trackStateContainerHolder() const

Retrieve the holder of the track state container.

Returns:

The track state container including it’s holder

Public Types

using ConstTrackProxy = Acts::TrackProxy<track_container_t, traj_t, holder_t, true>

Alias for the const version of a track proxy, with the same backends as this container.

using IndexType = TrackIndexType

The index type of the track container, taken from the container backend.

using TrackProxy = Acts::TrackProxy<track_container_t, traj_t, holder_t, false>

Alias for the mutable version of a track proxy, with the same backends as this container.

Public Functions

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void clear()

Clear the content of the track container.

Note

Only available if the track container is not read-only

inline constexpr IndexType size() const

Get the size (number of tracks) of the track container.

Returns:

the sixe

Public Static Attributes

static constexpr IndexType kInvalid = kTrackIndexInvalid

Sentinel value that indicates an invalid index.

static constexpr bool ReadOnly = IsReadOnlyTrackContainer<track_container_t>::value

Indicates if this track container is read-only, or if it can be modified.

static constexpr bool TrackStateReadOnly = IsReadOnlyMultiTrajectory<traj_t>::value

Indicates if the track state container is read-only, or if it can be modified.

Track state iteration and forward linking

By default, track states are connected as a one-directional linked list, where each track state knows its previous track state. Fig. 21 shows an example of a track state tree, like it is constructed by the combinatorial track finding.

In Fig. 21 states \(S_7\) and \(S_6\) are the two tip states of the track state tree, while \(S_1\) is the single stem state. In the case of combinatorial track finding starting from e.g. a seed, it could be the location of the innermost space point.

../../_images/ckf_tree.svg

Fig. 21 Illustration of a branching multi-trajectory that is created during combinatorial track finding.

Each track object points at a single tip state to define its track state sequence. The Acts::TrackProxy class has various methods to access the track state sequence:

auto track = getTrackFromSomewhere();
for(const auto trackState : track.trackStatesReversed()) {
  // do something with track state
}

Note that Acts::TrackProxy::trackStatesReversed() iterates from the tip state to the stem state, i.e. from the outside in.

Attention

By-default, it is not possible to iterate forward through the track states on a track! The track’s track states need to be forward-linked for this to be possible.

The reason for this is: As the trajectory branches at the second sensor into \(S_2\)/\(S_3\), it is not possible to connect the states forward, i.e. store in \(S_1\) what the next state is going to be: it is ambiguous!

However, when track finding has concluded, and the trajectories identified by tip states \(S_7\) and \(S_8\) have been discarded or are being copied into an output container, it is possible to forward link the track state sequences. This is possible if the trajectory does not branch anymore! Acts::TrackProxy::copyFrom() will implicitly forward link the track states, as it is guaranteed to not branch after copying.

You can manually add forward-linking to a track by calling Acts::TrackProxy::linkForward() or Acts::TrackProxy::reverseTrackStates().

Warning

Calling either Acts::TrackProxy::linkForward() or Acts::TrackProxy::reverseTrackStates() on a track state sequence which has branching will break the branching! If you have other tracks pointing at a tip state that branches from the sequence you’re trying to forward-link, it will be corrupted!

In this example, before any forward linking, the sequence looks like this:

digraph { rankdir="LR"; S2 -> S1; S3 -> S1; S7 -> S5 -> S4 -> S2; S6 -> S3; }

After a copy operation of \(S_6\) and \(S_7\) the resultig track state sequences will look like this:

digraph { rankdir="LR"; S11[label="S1 (copy)"]; S12[label="S1 (copy)"]; S7 -> S5 -> S4 -> S11; S11 -> S4 -> S5 -> S7; S6 -> S3 -> S12; S12 -> S3 -> S6; }

This now includes both forward and backward links, which allows iteration from \(S_1\)/\(S_2\) to \(S_6\)/\(S_7\) and the other way around.

Forward iteration can then be achieved like this:

auto track = getTrackFromSomewhere();
for(const auto trackState : track.trackStates()) {
  // iterate forward
  // do something with track state
}

and the innermost track state becomes directly accessible via Acts::TrackProxy::innermostTrackState().

Attention

If the track container has branching track state sequences, running a smoothing step in-place on branching tracks is problematic: if tracks are smoothed one by one, the last track of each shared track state (i.e. the track state where branching occurs) will overwrite the smoothing result of all previous tracks.

Consider again the track states in Fig. 21. \(S_1\) is the common ancestor for \(S_2\) and \(S_3\), and has a single slot to store smoothed parameters. If smoothing happens for the track ending in \(S_6\), then smoothing the track ending in \(S_7\) only the values written by the final smoothing of \(S_37 will survive in \)S_1$’s storage. This can be unexpected!

Track State API

template<typename trajectory_t, std::size_t M, bool read_only = true>
class TrackStateProxy

Proxy object to access a single point on the trajectory.

Template Parameters:
  • SourceLink – Type to link back to an original measurement

  • M – Maximum number of measurement dimensions

  • read_only – true for read-only access to underlying storage

Constructors and assignment operator

Public constructors and assignment operators for TrackStateProxy only allow construction from another TrackStateProxy. You should generally not have to construct TrackStateProxy manually.

inline TrackStateProxy(const TrackStateProxy<Trajectory, M, false> &other)

Constructor and assignment operator to construct TrackStateProxy from mutable.

Parameters:

other – The other TrackStateProxy to construct from

inline TrackStateProxy &operator=(const TrackStateProxy<Trajectory, M, false> &other)

Assignment operator to from mutable TrackStateProxy.

Parameters:

other – The other TrackStateProxy to construct from

Returns:

Reference to this TrackStateProxy

Track state properties

Properties of the track state represented by TrackStateProxy.

Many of these methods come in a const and a non-const version. The non-const version is only available if you have an instance of TrackStateProxy that does not have the read_only template parameter set to true, even if you hold it as an lvalue.

The track states each have an index in the track state container. The sequence of track states is implemented as a one or two-way linked list, which uses indices into the same container.

Each track state has a previous index, which points at the track state immediately preceding. A track state with a previous index of kInvalid is the first (innermost) track state in a track or track candidate. This is also referred to as a stem at the track level.

During track finding and fitting, track states are usually appended to the sequence, populating the previous index of the new track state. Combinatorial track finding can produce track states which fork in this way, by having more than one track state with the same previous index.

The track states have static, optional and dynamic properties. Static properties are always present, and can always be retrieved. Optional components use an extra indirection mechanism that coordinates with the backend to allow both not having the component set, or sharing it with other track states. An example is a branching trajectory from track finding which shares the same predicted parameter vector and associated covariance.

Optional components are

  • predicted parameters and covariance

  • filtered parameters and covariance

  • smoothed parameters and covariance

  • jacobian

  • calibrated measurement info including projector

They can be unset via unset, getMask can be used to check which components are present. The first four are shareable between track states via shareFrom.

inline IndexType index() const

Index within the trajectory.

Returns:

the index

inline IndexType previous() const

Return the index of the track state previous in the track sequence.

Returns:

The index of the previous track state.

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline IndexType &previous()

Return a mutable reference to the index of the track state ‘previous’ in the track sequence.

Note

Only available if the track state proxy is not read-only

Returns:

The index of the previous track state.

inline bool hasPrevious() const

Return whether this track state has a previous (parent) track state.

Returns:

Boolean indicating whether a previous track state exists

TrackStatePropMask getMask() const

Build a mask that represents all the allocated components of this track state proxy.

Returns:

The generated mask

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void unset(TrackStatePropMask target)

Unset an optional track state component.

Note

Only available if the track state proxy is not read-only

Parameters:

target – The component to unset

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void addComponents(TrackStatePropMask mask)

Add additional components to the track state.

Note

Only available if the track state proxy is not read-only

Parameters:

mask – The bitmask that instructs which components to allocate

inline const Surface &referenceSurface() const

Reference surface.

Returns:

the reference surface

inline bool hasReferenceSurface() const

Returns if the track state has a non nullptr surface associated.

Returns:

whether a surface exists or not

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void setReferenceSurface(std::shared_ptr<const Surface> srf)

Set the reference surface to a given value.

Note

This overload is only present in case ReadOnly is false.

Parameters:

srf – Shared pointer to the surface to set

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline float &chi2()

Getter/setter for chi2 value associated with the track state This overload returns a mutable reference, which allows setting a new value directly into the backing store.

Note

this overload is only enabled in case the proxy is not read-only

Returns:

Mutable reference to the chi2 value

inline float chi2() const

Getter for the chi2 value associated with the track state.

This overload returns a copy of the chi2 value, and thus does not allow modification of the value in the backing storage.

Returns:

the chi2 value of the track state

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline double &pathLength()

Getter for the path length associated with the track state.

This overloaded is only enabled if not read-only, and returns a mutable reference.

Returns:

Mutable reference to the pathlength.

inline double pathLength() const

Getter for the path length.

Returns a copy of the path length value.

Returns:

The path length of this track state

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline TrackStateType typeFlags()

Getter for the type flags associated with the track state.

This overloaded is only enabled if not read-only, and returns a mutable reference.

Returns:

reference to the type flags.

inline ConstTrackStateType typeFlags() const

Getter for the type flags.

Returns a copy of the type flags value.

Returns:

The type flags of this track state

Track state parameters

ConstParameters parameters() const

Track parameters vector.

This tries to be somewhat smart and return the first parameters that are set in this order: predicted -> filtered -> smoothed

Returns:

one of predicted, filtered or smoothed parameters

ConstCovariance covariance() const

Track parameters covariance matrix.

This tries to be somewhat smart and return the first parameters that are set in this order: predicted -> filtered -> smoothed

Returns:

one of predicted, filtered or smoothed covariances

inline ConstParameters predicted() const

Predicted track parameters vector.

Returns:

The predicted parameters

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline Parameters predicted()
inline ConstCovariance predictedCovariance() const

Predicted track parameters covariance matrix.

Returns:

The predicted track parameter covariance

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline Covariance predictedCovariance()
inline bool hasPredicted() const

Check whether the predicted parameters+covariance is set.

Returns:

Whether it is set or not

inline ConstParameters filtered() const

Filtered track parameters vector.

Note

Const version

Returns:

The filtered parameters

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline Parameters filtered()

Filtered track parameters vector.

Note

Mutable version

Returns:

The filtered parameters

inline ConstCovariance filteredCovariance() const

Filtered track parameters covariance matrix.

Note

Const version

Returns:

The filtered parameters covariance

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline Covariance filteredCovariance()

Filtered track parameters covariance matrix.

Note

Mutable version

Returns:

The filtered parameters covariance

inline bool hasFiltered() const

Return whether filtered parameters+covariance is set.

Returns:

Whether it is set

inline ConstParameters smoothed() const

Smoothed track parameters vector.

Note

Const version

Returns:

The smoothed parameters

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline Parameters smoothed()

Smoothed track parameters vector.

Note

Mutable version

Returns:

The smoothed parameters

inline ConstCovariance smoothedCovariance() const

Smoothed track parameters covariance matrix.

Note

Const version

Returns:

the parameter covariance matrix

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline Covariance smoothedCovariance()

Smoothed track parameters covariance matrix.

Note

Mutable version

Returns:

the parameter covariance matrix

inline bool hasSmoothed() const

Return whether smoothed parameters+covariance is set.

Returns:

Whether it is set

inline ConstCovariance jacobian() const

Returns the jacobian from the previous trackstate to this one.

Note

Const version

Returns:

The jacobian matrix

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline Covariance jacobian()

Returns the jacobian from the previous trackstate to this one.

Note

Mutable version

Returns:

The jacobian matrix

inline bool hasJacobian() const

Returns whether a jacobian is set for this trackstate.

Returns:

Whether it is set

Track state measurement properties

Properties of the measurement associated with the track state represented. This consists of a vector and an associated square matrix of a measurement dimension which is between one and the size of the track parametrization. The measurement coordinate frame is required to be a strict subset of the bound track parametrization on the local geometry coordinate frame, i.e. using a pure projector matrix to convert from the bound parametrization to the measurement frame is possible.

The track state stores the parameter vector and covariance, and the backend is given the possibility to do so in a jagged way, i.e. only storing the number of values needed. This requires calling allocateCalibrated before storing the measurements (even if it might be a no-op).

The projector matrix is packed as a bitset, which is converted to a matrix on-demand (and therefore returned by value).

A convenience function to assign this from the Measurement class is provided, although it’s use is discouraged.

The track state also includes a SourceLink which acts as a proxy to the original uncalibrated measurement that the calibrated measurement was derived from. It is set and returned by value, to allow unpacking / repacking by the backend, if needed.

Projector projector() const

Returns the projector (measurement mapping function) for this track state.

It is derived from the uncalibrated measurement

Note

This function returns the overallocated projector. This means it is of dimension MxM, where M is the maximum number of measurement dimensions. The NxM submatrix, where N is the actual dimension of the measurement, is located in the top left corner, everything else is zero.

Returns:

The overallocated projector

inline bool hasProjector() const

Returns whether a projector is set.

Returns:

Whether it is set

inline EffectiveProjector effectiveProjector() const

Returns the projector (measurement mapping function) for this track state.

It is derived from the uncalibrated measurement

Warning

This function returns the effective projector. This means it is of dimension \(N\times M\), where \(N\) is the actual dimension of the measurement.

Returns:

The effective projector

template<typename Derived, bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void setProjector(const Eigen::MatrixBase<Derived> &projector)

Set the projector on this track state This will convert the projector to a more compact bitset representation and store it.

Note

projector is assumed to only have 0s or 1s as components.

Parameters:

projector – The projector in the form of a dense matrix

inline ProjectorBitset projectorBitset() const

Directly get the projector bitset, a compressed form of a projection matrix.

Note

This is mainly to copy explicitly a projector from one state to another. Use the projector or effectiveProjector method if you want to access the matrix.

Returns:

The projector bitset

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void setProjectorBitset(ProjectorBitset proj)

Set the projector bitset, a compressed form of a projection matrix.

Note

This is mainly to copy explicitly a projector from one state to another. If you have a projection matrix, set it with setProjector.

Parameters:

proj – The projector bitset

SourceLink getUncalibratedSourceLink() const

Uncalibrated measurement in the form of a source link.

Const version

Returns:

The uncalibrated measurement source link

Set an uncalibrated source link.

Parameters:

sourceLink – The uncalibrated source link to set

inline bool hasUncalibratedSourceLink() const

Check if the point has an associated uncalibrated measurement.

Returns:

Whether it is set

inline bool hasCalibrated() const

Check if the point has an associated calibrated measurement.

Returns:

Whether it is set

template<std::size_t measdim>
inline ConstMeasurement<measdim> calibrated() const

Full calibrated measurement vector.

Might contain additional zeroed dimensions.

Note

Const version

Returns:

The measurement vector

template<std::size_t measdim, bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline Measurement<measdim> calibrated()

Full calibrated measurement vector.

Might contain additional zeroed dimensions.

Note

Mutable version

Returns:

The measurement vector

template<std::size_t measdim>
inline ConstMeasurementCovariance<measdim> calibratedCovariance() const

Const full calibrated measurement covariance matrix.

The effective covariance is located in the top left corner, everything else is zeroed.

Returns:

The measurement covariance matrix

template<std::size_t measdim, bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline MeasurementCovariance<measdim> calibratedCovariance()

Mutable full calibrated measurement covariance matrix.

The effective covariance is located in the top left corner, everything else is zeroed.

Returns:

The measurement covariance matrix

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline auto effectiveCalibrated()

Mutable dynamic measurement vector with only the valid dimensions.

Warning

The dynamic vector has a runtime overhead!

Returns:

The effective calibrated measurement vector

inline auto effectiveCalibrated() const

Const dynamic measurement vector with only the valid dimensions.

Warning

The dynamic matrix has a runtime overhead!

Returns:

The effective calibrated measurement vector

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline auto effectiveCalibratedCovariance()

Mutable dynamic measurement covariance matrix with only the valid dimensions.

Warning

The dynamic matrix has a runtime overhead!

Returns:

The effective calibrated covariance matrix

inline auto effectiveCalibratedCovariance() const

Const dynamic measurement covariance matrix with only the valid dimensions.

Warning

The dynamic matrix has a runtime overhead!

Returns:

The effective calibrated covariance matrix

inline IndexType calibratedSize() const

Return the (dynamic) number of dimensions stored for this measurement.

Note

Depending on the backend, this size is used to determine the memory range of the measurement vector and covariance.

Returns:

The number of dimensions

template<std::size_t kMeasurementSize, bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void setCalibrated(const Acts::Measurement<BoundIndices, kMeasurementSize> &meas)

Set the calibrated measurement of this track state from a measurement object.

This is a convenience function to set the calibrated measurement from the Acts::Measurement object. In general, you should implement this functionality specifically for an (experiment-specific) uncalibrated measurement EDM.

Note

This does not set the reference surface.

Warning

This assumes this TrackState stores it’s own calibrated measurement. If storage is shared with another TrackState, both will be overwritten!. Also assumes none of the calibrated components is invalid (i.e. unset) for this TrackState.

Template Parameters:

kMeasurementSize – Size of the calibrated measurement

Parameters:

meas – The measurement object to set

inline void allocateCalibrated(std::size_t measdim)

Allocate storage to be able to store a measurement of size measdim.

This must be called before setting the measurement content.

Sharing and copying

Methods to share and copy track state components. Sharing means setting up more than one track state to point to the same component.

Shareable components are

  • predicted parameters and covariance

  • filtered parameters and covariance

  • smoothed parameters and covariance

  • jacobian

See TrackStatePropMask.

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void shareFrom(TrackStatePropMask shareSource, TrackStatePropMask shareTarget)

Share a shareable component within this track state.

Parameters:
  • shareSource – Which component to share from

  • shareTarget – Which component to share as. This should be different from as shareSource, e.g. predicted can be shared as filtered.

template<bool RO = ReadOnly, bool ReadOnlyOther, typename = std::enable_if_t<!RO>>
inline void shareFrom(const TrackStateProxy<Trajectory, M, ReadOnlyOther> &other, TrackStatePropMask component)

Share a shareable component from another track state.

Note

The track states both need to be stored in the same MultiTrajectory instance

Parameters:
  • other – Track state proxy to share component from

  • component – Which component to share.

template<bool RO = ReadOnly, bool ReadOnlyOther, typename = std::enable_if_t<!RO>>
inline void shareFrom(const TrackStateProxy<Trajectory, M, ReadOnlyOther> &other, TrackStatePropMask shareSource, TrackStatePropMask shareTarget)

Share a shareable component from another track state.

Note

Shareable components are predicted, filtered, smoothed, calibrated, jacobian, or projector. See TrackStatePropMask.

Parameters:
  • other – Track state proxy to share component(s) from

  • shareSource – Which component to share from

  • shareTarget – Which component to share as. This can be be different from as shareSource, e.g. predicted can be shared as filtered.

template<ACTS_CONCEPT track_state_proxy_t(TrackStateProxyConcept), bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void copyFrom(const track_state_proxy_t &other, TrackStatePropMask mask = TrackStatePropMask::All, bool onlyAllocated = true)

Copy the contents of another track state proxy into this one.

Note

If the this track state proxy does not have compatible allocations with the source track state proxy, and onlyAllocated is false, an exception is thrown.

Note

The mask parameter will not cause a copy of components that are not allocated in the source track state proxy.

Parameters:
  • other – The other track state to copy from

  • mask – An optional mask to determine what to copy from

  • onlyAllocated – Whether to only copy allocated components

Track state proxy Generic component access

template<HashedString key>
inline constexpr bool has() const

Check if a component is set.

Template Parameters:

key – Hashed string key to check for

Returns:

true if the component exists, false if not

inline constexpr bool has(HashedString key) const

Check if a component is set.

Parameters:

key – Hashed string key to check for

Returns:

true if the component exists, false if not

inline constexpr bool has(std::string_view key) const

Check if a component is set.

Note

This might hash the key at runtime instead of compile-time

Parameters:

key – String key to check for

Returns:

true if the component exists, false if not

template<typename T, HashedString key, bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline constexpr T &component()

Retrieve a mutable reference to a component.

Template Parameters:
  • T – The type of the component to access

  • key – String key for the component to access

Returns:

Mutable reference to the component given by key

template<typename T, bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline constexpr T &component(HashedString key)

Retrieve a mutable reference to a component.

Template Parameters:

T – The type of the component to access

Parameters:

key – String key for the component to access

Returns:

Mutable reference to the component given by key

template<typename T, bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline constexpr T &component(std::string_view key)

Retrieve a mutable reference to a component.

Note

This might hash the key at runtime instead of compile-time

Template Parameters:

T – The type of the component to access

Parameters:

key – String key for the component to access

Returns:

Mutable reference to the component given by key

template<typename T, HashedString key>
inline constexpr const T &component() const

Retrieve a const reference to a component.

Template Parameters:
  • T – The type of the component to access

  • key – String key for the component to access

Returns:

Const reference to the component given by key

template<typename T>
inline constexpr const T &component(HashedString key) const

Retrieve a const reference to a component.

Template Parameters:

T – The type of the component to access

Parameters:

key – String key for the component to access

Returns:

Const reference to the component given by key

template<typename T>
inline constexpr const T &component(std::string_view key) const

Retrieve a const reference to a component.

Note

This might hash the key at runtime instead of compile-time

Template Parameters:

T – The type of the component to access

Parameters:

key – String key for the component to access

Returns:

Const reference to the component given by key

Public Types

using ConstCovariance = typename TrackStateTraits<M, true>::Covariance

Same as Covariance, but with const semantics.

template<std::size_t N>
using ConstMeasurement = typename TrackStateTraits<N, true>::Measurement

Same as Measurement, but with const semantics.

template<std::size_t N>
using ConstMeasurementCovariance = typename TrackStateTraits<N, true>::MeasurementCovariance

Same as MeasurementCovariance, but with const semantics.

using ConstParameters = typename TrackStateTraits<M, true>::Parameters

Same as Parameters, but with const semantics.

using ConstProxyType = TrackStateProxy<trajectory_t, M, true>

Alias for an associated const track state proxy, with the same backends.

using Covariance = typename TrackStateTraits<M, ReadOnly>::Covariance

Map-type for a bound covariance.

This has reference semantics, i.e. points at a matrix by an internal pointer.

using EffectiveProjector = Eigen::Matrix<typename Projector::Scalar, Eigen::Dynamic, Eigen::Dynamic, TrackStateTraits<M, ReadOnly>::ProjectorFlags, M, eBoundSize>

Dynamic variant of the projector matrix.

Warning

Using this type is discouraged, as it has a runtime overhead

using IndexType = TrackIndexType

The index type of the track state container.

template<std::size_t N>
using Measurement = typename TrackStateTraits<N, ReadOnly>::Measurement

Map-type for a measurement vector, where the local measurement dimension is variable.

template<std::size_t N>
using MeasurementCovariance = typename TrackStateTraits<N, ReadOnly>::MeasurementCovariance

Map-type for a measurement covariance matrix, where the local measurement dimension is variable.

using Parameters = typename TrackStateTraits<M, ReadOnly>::Parameters

Map-type for a bound parameter vector.

This has reference semantics, i.e. points at a matrix by an internal pointer.

using Projector = typename TrackStateTraits<M, ReadOnly>::Projector

Matrix representing the projector (measurement mapping function) for a measurement.

This is not a map type, but an actual matrix. This matrix is always \(M \times M\), even if the local measurement dimension is lower. The actual \(N\times M\) projector is given by the top \(N\) rows.

using Trajectory = trajectory_t

The track state container backend given as a template parameter.

Public Functions

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline auto &container()

Get a mutable reference to the track state container backend.

Returns:

a mutable reference to the backend

inline const auto &container() const

Get a const reference to the track state container backend.

Returns:

a const reference to the backend

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline MultiTrajectory<Trajectory> &trajectory()

Return a mutable reference to the underlying backend container.

Returns:

A reference to the backend container

inline const MultiTrajectory<Trajectory> &trajectory() const

Return a const reference to the underlying backend container.

Returns:

A const reference to the backend container

Public Static Attributes

static constexpr IndexType kInvalid = kTrackIndexInvalid

Sentinel value that indicates an invalid index.

static constexpr bool ReadOnly = read_only

Indicates whether this track state proxy is read-only or if it can be modified.

Friends

friend class Acts::MultiTrajectory< Trajectory >
template<typename derived_t>
class MultiTrajectory

Store a trajectory of track states with multiple components.

This container supports both simple, sequential trajectories as well as combinatorial or multi-component trajectories. Each point can store a parent point such that the trajectory forms a directed, acyclic graph of sub-trajectories. From a set of endpoints, all possible sub-components can be easily identified. Some functionality is provided to simplify iterating over specific sub-components.

MultiTrajectory track state (proxy) access and manipulation

These methods allow accessing track states, i.e. adding or retrieving a track state proxy that points at a specific track state in the container.

inline ConstTrackStateProxy getTrackState(IndexType istate) const

Access a read-only point on the trajectory by index.

Note

Only available if the MultiTrajectory is not read-only

Parameters:

istate – The index to access

Returns:

Read only proxy to the stored track state

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline TrackStateProxy getTrackState(IndexType istate)

Access a writable point on the trajectory by index.

Note

Only available if the MultiTrajectory is not read-only

Parameters:

istate – The index to access

Returns:

Read-write proxy to the stored track state

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline IndexType addTrackState(TrackStatePropMask mask = TrackStatePropMask::All, IndexType iprevious = kInvalid)

Add a track state without providing explicit information.

Which components of the track state are initialized/allocated can be controlled via mask

Note

Only available if the MultiTrajectory is not read-only

Parameters:
  • mask – The bitmask that instructs which components to allocate and which to leave invalid

  • iprevious – index of the previous state, kInvalid if first

Returns:

Index of the newly added track state

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline TrackStateProxy makeTrackState(TrackStatePropMask mask = TrackStatePropMask::All, IndexType iprevious = kInvalid)

Add a track state to the container and return a track state proxy to it This effectively calls addTrackState and getTrackState.

Note

Only available if the track state container is not read-only

Returns:

a track state proxy to the newly added track state

MultiTrajectory track state iteration

template<typename F>
void visitBackwards(IndexType iendpoint, F &&callable) const

Visit all previous states starting at a given endpoint.

Parameters:
  • iendpoint – index of the last state

  • callable – non-modifying functor to be called with each point

template<typename F, bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void applyBackwards(IndexType iendpoint, F &&callable)

Apply a function to all previous states starting at a given endpoint.

Note

Only available if the MultiTrajectory is not read-only

Warning

If the trajectory contains multiple components with common points, this can have an impact on the other components.

Parameters:
  • iendpoint – index of the last state

  • callable – modifying functor to be called with each point

inline auto reverseTrackStateRange(IndexType iendpoint) const

Range for the track states from iendpoint to the trajectory start.

Note

Const version

Parameters:

iendpoint – Trajectory entry point to start from

Returns:

Iterator pair to iterate over

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline auto reverseTrackStateRange(IndexType iendpoint)

Range for the track states from iendpoint to the trajectory start, i.e from the outside in.

Note

Only available if the MultiTrajectory is not read-only

Note

Mutable version

Parameters:

iendpoint – Trajectory entry point to start from

Returns:

Iterator pair to iterate over

inline auto forwardTrackStateRange(IndexType istartpoint) const

Range for the track states from istartpoint to the trajectory end, i.e from inside out.

Note

Const version

Parameters:

istartpoint – Trajectory state index for the innermost track state to start from

Returns:

Iterator pair to iterate over

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline auto forwardTrackStateRange(IndexType istartpoint)

Range for the track states from istartpoint to the trajectory end, i.e from inside out.

Note

Only available if the MultiTrajectory is not read-only

Parameters:

istartpoint – Trajectory state index for the innermost track state to start from

Returns:

Iterator pair to iterate over

MultiTrajectory column management

MultiTrajectory can manage a set of common static columns, and dynamic columns that can be added at runtime.

This set of methods allows you to manage the dynamic columns.

template<typename T, bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void addColumn(const std::string &key)

Add a column to the MultiTrajectory.

Note

This takes a string argument rather than a hashed string to maintain compatibility with backends.

Note

Only available if the MultiTrajectory is not read-only

Template Parameters:

T – Type of the column values to add

inline bool hasColumn(HashedString key) const

Check if a column with a key key exists.

Parameters:

key – Key to check for a column with

Returns:

True if the column exists, false if not.

Public Types

using ConstTrackStateProxy = Acts::TrackStateProxy<Derived, MeasurementSizeMax, true>

Alias for the const version of a track state proxy, with the same backends as this container.

using IndexType = typename TrackStateProxy::IndexType

The index type of the track state container.

using TrackStateProxy = Acts::TrackStateProxy<Derived, MeasurementSizeMax, false>

Alias for the mutable version of a track state proxy, with the same backends as this container.

Public Functions

template<bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
inline void clear()

Clear the MultiTrajectory.

Leaves the underlying storage untouched

Note

Only available if the MultiTrajectory is not read-only

inline IndexType size() const

Returns the number of track states contained.

Returns:

The number of track states

Public Static Attributes

static constexpr IndexType kInvalid = TrackStateProxy::kInvalid

Sentinel value that indicates an invalid index.

Component sharing

Acts::MultiTrajectory is designed so that components can be shared between track states. This can be achieved using the Acts::TrackStateProxy::shareFrom() can be used to set this up.

Shareable components are

  • predicted parameters and covariance

  • filtered parameters and covariance

  • smoothed parameters and covariance

  • jacobian

To illustrate why this can be useful, consider again Fig. 21, where \(S_2\) and \(S_3\) branch out from a shared \(S_1\). In this case, the predicted parameter vector and covariance, as well as the jacobian from \(S_1\to S_2\) and \(S_1 \to S_3\) will be identical. In this case, the combinatorial track finding will use the sharing functionality to share these components.

Attention

Sharing these components introduces cross-talk between track states, and this is intentional. If e.g. the predicted covariance is modified through either of the track states, the changes will be visible when accessed from the other track state as well.

Dynamic columns

Aside from the static properties that both the track states and the track have, the EDM supports adding almost arbitrary additional information as dynamic columns. The implementation of the dynamic column mechanism is given by the backend, where the interface layer classes Acts::MultiTrajectory and Acts::TrackContainer and associated proxies only coordinate the creation, access and copying of dynamic columns.

The following illustrates the usage of dynamic columns for Acts::TrackContainer, but usage on Acts::MultiTrajectory is identical.

Assume you create a track container using some combination of backends (see Backends shipped with ACTS for information on the backends shipped with ACTS).

Acts::TrackContainer tc{/*...*/};

// add dynamic columns programmatically

tc.addColumn<float>("col_a");
tc.addColumn<uint8_t>("col_b");

Adding columns is only supported on mutable track containers, const track containers should contain the original dynamic columns from when they were created. It is up to the backend to implement recovering dynamic columns from e.g. input files.

Note

Which types are supported depends on the backend being used. See Backends shipped with ACTS for information on the backends shipped with ACTS, and which types they support.

With these dynamic columns registered, it is now possible to set and get values for these columns on tracks.

using namespace Acts::HashedStringLiterals;
auto track = tc.makeTrack();

// these two are equivalent
track.component<float, "col_a"_hash>() = 42.42;
track.component<float>("col_a"_hash) = 52.52;
std::cout << track.component<float, "col_a"_hash>() << std::endl; // prints: 52.52

Tip

The expression "col_a"_hash is a user-defined literal that internally calls

Acts::hashedString("col_a");

This literal is only available after

using namespace Acts::HashedStringLiterals;

The components are accessed by a hash of the name of the component. This hash can be calculated from a string at compile-time, if the string is known at compile time. The difference between the two component access signatures is that in the first case, the hash of the component is guaranteed to be evaluated at compile-time, since it is given to the component function as a template argument. A third option is available to access components: see Accessors.

Accessors

It can be inconvenient to have to write the full component access signature, especially if you want to access the same components repeatedly. An alternative are accessors. They encapsulate the type of the component, and the component name hash into an object:

// definition of the accessor with a type and the name of the component
Acts::ProxyAccessor<float> extra("extra");
// component access by calling it on a proxy
extra(track) = 42.2;
std::cout << extra(track) << std::endl; // prints 42.2

Tip

The same accessor also works for Acts::TrackStateProxy objects, as it shares the same component access mechanism with Acts::TrackProxy.

The above accessor is a mutable accessor, meaning it can only be used with mutable proxy objects!

ConstTrackProxy<...> constTrack = /*...*/;
extra(constTrack); // this will give a compile error!

To access properties on const proxy objects, you need to use a dedicated accessor type:

Acts::ConstProxyAccessor<float> extraConst("extra");
std::cout << extraConst(constTrack) << std::endl; // prints 42.2
// using the const accessor on a mutable proxy also works
std::cout << extraConst(track) << std::endl; // prints 42.2

For both const and mutable proxy accessors you do not actually need a mutable reference, as the internal accessor state is not mutated after construction. You can safely use a static instance of these accessors to avoid constructing them over and over again:

template<typename track_proxy_t>
void doSomething(track_proxy_t track, float value) {
    // only created once, never changed
    static const Acts::ProxyAccessor<float> extra("extra");
    extra(track) = value;
}

Holders

The Acts::TrackContainer implements a mechanism to optionally own the backends that it is constructed with. This is implemented using a holder type, which is passed either as a template parameter, or deduced automatically.

Available default holders are:

  • Acts::detail::RefHolder which does not own the backends

  • Acts::detail::ConstRefHolder which does not own the backends and does not permit mutations.

  • Acts::detail::ValueHolder which owns the backends by value. This is auto-deduced if the backends are given as values or rvalue-references.

Other user-specified holders can also be used, for example, it is possible to use std::shared_ptr as a holder directly, like:

std::shared_ptr<Acts::VectorTrackContainer> vtc{
    std::make_shared<Acts::VectorTrackContainer>()};
std::shared_ptr<Acts::VectorMultiTrajectory> mtj{
    std::make_shared<Acts::VectorMultiTrajectory>()};

Acts::TrackContainer<Acts::VectorTrackContainer, Acts::VectorMultiTrajectory, std::shared_ptr>
tc{vtc, mtj};

How to create a track from scratch

Tracks can be created directly from the EDM interface. You start by creating or obtaining a mutable track container:

Acts::TrackContainer tc{Acts::VectorTrackContainer{}, Acts::VectorMutiTrajectory{}};

A single track can be added like this:

auto track = tc.makeTrack();
// set some properties
track.parameters() << 0.1_mm, 3_mm, 1/20_GeV, 0.2, 0.4, 25_mm;
track.setReferenceSurface(
    Acts::Surface::makeSurface<Acts::PerigeeSurface>(Acts::Vector3::Zero()));

The track is still lacking track states. You can append track states to the track, which means that a track state is attached behind the outermost track state currently assigned.

auto ts1 = track.appendTrackState();
ts1.smoothed() << 0.4_um, 1_mm, 1/19_GeV, 0.21, 0.37, 40_ns;
//...
auto ts2 = track.appendTrackState();
ts2.smoothed() << 0.4_um, 1_mm, 1/19_GeV, 0.21, 0.37, 40_ns;

Note that this means that you have to create track state from the inside out! If you have to add track states from the outside in, you can still append them and reverse the track at the very end.

track.reverseTrackStates();

Track EDM backends

Backends shipped with ACTS

Transient vector backend

The transient vector backend implements the reference backend for the track EDM. It does not implement any persistency directly. The implementation of this backend for both track and track state containers uses separate classes for the mutable and const versions, in order to fully comply with const correctness. It also uses a common base class internally, which is however an implementation detail.

To build a track container with this backend, you can write

Acts::VectorMultiTrajectory mtj{};
Acts::VectorTrackContainer vtc{};
Acts::TrackContainer tc{vtc, mtj};

or

Acts::ConstVectorTrackContainer vtc{/* ... */};
Acts::ConstVectorMultiTrajectory mtj{/* ... */};
Acts::TrackContainer ctc{vtc, mtj};

Note

There are currently no restrictions on types that can be used as dynamic columns. Any type can be stored and retrieved back from the backend.

Keep in mind that the transient vector backend does not support persistency, meaning that there is no mechanism to serialize dynamic columns (or static columns for that matter) to disk and read them back in.

PODIO backend

The PODIO track EDM backend shipped with the library uses a custom PODIO-EDM defined in edm.yml in the ACTS core repository.

The working model is this:

  1. Mutable PODIO track and track state backends are created with a helper

    Acts::MutablePodioTrackStateContainer tsc{helper};
    Acts::MutablePodioTrackContainer ptc{helper};
    
  2. A track container is built using these PODIO backend instances

    Acts::TrackContainer tc{ptc, tsc};
    
  3. The track container is used by some algorithm

    tc.makeTrack();
    // ...
    
  4. The mutable backends released into a podio::Frame for writing.

    ptc.releaseInto(frame);
    tsc.releaseInto(frame);
    // write frame
    
  5. When reading, const track state and track PODIO backends are created from a podio::Frame

    auto frame = /* read frame */;
    Acts::ConstPodioTrackStateContainer tsc{helper, frame};
    Acts::ConstPodioTrackContainer ptc{helper, frame};
    

Note

The PODIO backend currently supports all types that can be written to a podio::UserDataCollection for dynamic columns. At the time of writing these are: float, double, int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t, uint32_t, uint64_t.

In particular, it is not possible to write bool values directly. A workaround is using uint8_t and making boolean expressions explicit.

How to build a backend

Both track and track state backends need to conform to respective concepts. Effectively, the backend has to allow for collection functionality, like getting the current size etc.

Further, the backend needs to respond to queries for properties of the elements, where the element is identified by an index.

The backend needs to flag itself as mutable or const, by specializing

template <typename T>
struct IsReadOnlyMultiTrajectory;
// or
template <typename T>
struct IsReadOnlyTrackContainer;

This informs the interface layer to permit or prevent mutable access.

Common between both track and track state backends is the component access. Here, the component is identified by a compile-time string hash of the component name, which the backend responds to by a type-erased mutable or const pointer. There is a hard requirement for the backend to return stable pointers here, as the interface layer expects this and exposes this in the API.

This can be accomplished like in the transient backend with a switch-statements like:

switch (key) {
  case "previous"_hash:
    return &m_previous[istate];
  case "next"_hash:
    return &m_next[istate];
  case "predicted"_hash:
    return &m_index[istate].ipredicted;
  case "filtered"_hash:
    return &m_index[istate].ifiltered;
  case "smoothed"_hash:
    return &m_index[istate].ismoothed;
  case "projector"_hash:
    return &m_projectors[instance.m_index[istate].iprojector];
  case "measdim"_hash:
    return &m_index[istate].measdim;
  case "chi2"_hash:
    return &m_index[istate].chi2;
  case "pathLength"_hash:
    return &m_index[istate].pathLength;
  case "typeFlags"_hash:
    return &m_index[istate].typeFlags;
  default:
    // handle dynamic columns
}

The default statement deals with Dynamic columns. For support of dynamic columns, the backend needs to implement hasColumn_impl to return if a column exists, mutable backends need to implement addColumn_impl which adds a column with a type and a string name. copyDynamicFrom_impl and ensureDynamicColumn_impl on mutable backends allows copying dynamic content between container backends. dynamicKeys_impl returns an iterator pair that informs the caller of which dynamic keys are registered. This is also used in dynamic column copies.

Both backend types return parameter vectors and covariance matrices. This is always done as Eigen maps, which have reference semantics into the backing storage.

TrackContainer backend

  • Mutable & const

    • Get size

    • Reference parameter vector and covariance matrix access

    • Get if column exists

    • Get reference surface (returns const Surface*)

    • Get particle hypothesis (returns by-value, so allows on-the-fly creation)

    • Get dynamic keys

    • Type-erased component access

  • Mutable

    • Add and remove a track

    • Add column

    • Ensure dynamic columns, copy dynamic columns

    • Reserve number of entries

    • Set reference surface

    • Set particle hypothesis

    • Clear the container

MultiTrajectory (track state) backend

The track state container can share components. This is implemented for the shareable components by the interface layer looking up a component that stores an index into a separate shareable-component-container. Then, functions exists which return Eigen maps into the relevant backend storage based on the index looked up as a component before.

The track state container also handles calibrated measurement in a packed way. This is to say, that for \(N\) dimensional measurement, the backend can store only the dimension \(N\) and then \(N\) numbers representing the measurement vector and \(N\times N\) numbers for the associated covariance matrix. To enable this, a mutable backend exposes allocateCalibrated_impl which accepts a track state index and the measurement size, and ensures storage is available to hand out a reference into associated backing storage. An example is the transient vector backend, which stores the offset into measurement and covariance matrix vector, and ensures its size is consistent.

In both cases above, the absence of the value can be indicated by setting the indices to the sentinel value kInvalid. The backend also has query methods that test if the index is invalid and return a boolean.

The track state container also stores SourceLinks, which are assigned by value and returned by value, which allows the backend to unpack assigned source links and repackage uncalibrated measurement references back into a source link when returning.

  • Mutable & const

    • Get the calibrated measurement dimension (size)

    • Get uncalibrated source link

    • Get reference surface

    • Get parameter from parameter index

    • Get covariance from covariance index

    • Get jacobian from jacobian index

    • Get measurement vector given compile-time measurement dimension

    • Get measurement covariance matrix given compile-time measurement dimension

    • Check if an optional component is set

    • Get the container size

    • Type-erased component access

    • Get if column exists

    • Get dynamic keys

  • Mutable

    • Add a track state

    • Share track state components from another track state of the same container (otherwise no sharing is supported)

    • Unset an optional component

    • Clear the container

    • Add column

    • Ensure dynamic columns, copy dynamic columns

    • Set an uncalibrated source link that is passed by value

    • Set the reference surface

Glossary

tip state

The state at the tip of a trajectory, usually the outermost track state, on the opposite end of the stem state.

stem state

The state at the stem of a trajectory, meaning the innermost track state. The opposite end is the tip state.