diff --git a/Core/include/Acts/EventData/TrackProxy.hpp b/Core/include/Acts/EventData/TrackProxy.hpp index e5f1cf05d0f..6c1577d0788 100644 --- a/Core/include/Acts/EventData/TrackProxy.hpp +++ b/Core/include/Acts/EventData/TrackProxy.hpp @@ -605,6 +605,8 @@ class TrackProxy { /// 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**. /// @return Track state range to iterate over auto trackStates() const { return m_container->forwardTrackStateRange(m_index); @@ -616,6 +618,8 @@ class TrackProxy { /// 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**. /// @return Track state range to iterate over template > auto trackStates() { diff --git a/Core/include/Acts/EventData/TrackStateProxy.hpp b/Core/include/Acts/EventData/TrackStateProxy.hpp index 8b079483176..ce3069c670a 100644 --- a/Core/include/Acts/EventData/TrackStateProxy.hpp +++ b/Core/include/Acts/EventData/TrackStateProxy.hpp @@ -779,7 +779,7 @@ class TrackStateProxy { /// @tparam kMeasurementSize Size of the calibrated measurement /// @param meas The measurement object to set /// - /// @note This assumes this TrackState stores it's own calibrated + /// @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. diff --git a/docs/_extensions/lazy_autodoc.py b/docs/_extensions/lazy_autodoc.py index 3385b3c0b7a..4976c81e952 100644 --- a/docs/_extensions/lazy_autodoc.py +++ b/docs/_extensions/lazy_autodoc.py @@ -138,6 +138,7 @@ def run() -> None: "Acts::BoundIndices", "Acts::FreeIndices", "Acts::MagneticFieldError", + "Acts::TrackStatePropMask", } role_ex = re.compile(r"[{:](" + "|".join(roles) + r")[}:]`(.+?)`") diff --git a/docs/conf.py b/docs/conf.py index 82067353f2f..d0152469031 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -33,6 +33,7 @@ "breathe", "myst_parser", "sphinx.ext.mathjax", + "sphinx.ext.graphviz", "sphinx.ext.todo", "warnings_filter", ] diff --git a/docs/core/eventdata/figures/ckf_tree.svg b/docs/core/eventdata/figures/ckf_tree.svg index 45a7c14ce0d..baa927882b2 100644 --- a/docs/core/eventdata/figures/ckf_tree.svg +++ b/docs/core/eventdata/figures/ckf_tree.svg @@ -3,36 +3,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + @@ -50,66 +74,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - - - - - - + + + - + + + - - - - - + - + + + - + + + - - - - - + + + + + + + - + - - - - + + + + - + - - - - - - + + + + + + diff --git a/docs/core/eventdata/tracks.md b/docs/core/eventdata/tracks.md index d3cf5fcfed1..b8b72806d29 100644 --- a/docs/core/eventdata/tracks.md +++ b/docs/core/eventdata/tracks.md @@ -2,6 +2,9 @@ This section is **incomplete!** ::: +:::{contents} +::: + (edm_tracks)= # High-level Track Event Data Model @@ -125,14 +128,6 @@ incoming measurement. It then instructs the {term}`EDM` through the frontend layer to ensure enough memory is available, where the specifics are again left up to the backend layer. -(ckf_tree)= -:::{figure} figures/ckf_tree.svg -:width: 300px -:align: center -Illustration of a branching multi-trajectory that is created during -combinatorial track finding. -::: - 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 @@ -181,13 +176,76 @@ discussed below. (edm_track_iteration)= ### Track state iteration and forward linking -:::{todo} -Add picture of track state sequence and stem and tip index +By default, track states are connected as a one-directional linked list, where +each track state knows its *previous* track state. {numref}`ckf_tree` shows an +example of a track state tree, like it is constructed by the combinatorial +track finding. + +In {numref}`ckf_tree` states $S_7$ and $S_6$ are the two {term}`tip states` of the track state tree, whil $S_1$ is the single {term}`stem state`. +In the case of combinatorial track finding starting from e.g. a +{term}`seed`, it could be the location of the innermost {term}`space +point`. + +(ckf_tree)= +:::{figure} figures/ckf_tree.svg +:width: 300px +:align: center +Illustration of a branching multi-trajectory that is created during +combinatorial track finding. +::: + +Each track object points at a single {term}`tip state` to define its track state sequence. +The {class}`Acts::TrackProxy` class has various methods to access the track state sequence: + +```cpp +auto track = getTrackFromSomewhere(); +for(const auto trackState : track.trackStatesReversed()) { + // do something with track state +} + +``` + +Note that {func}`Acts::TrackProxy::trackStatesReversed` iterates from the {term}`tip state` to +the {term}`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 this: +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 +{term}`tip states B; +} +::: + ## Track State API @@ -210,3 +268,13 @@ You can manually add forward-linking to a track by calling ### Backends shipped with ACTS ### How to build a backend + +## Glossary + +:::{glossary} +tip state + The state at the *tip* of a trajectory, usually the *outermost* track state, on the opposite end of the {term}`stem state`. + +stem state + The state at the *stem* of a trajectory, meaning the *innermost* track state. The opposite end is the {term}`tip state`. +::: diff --git a/docs/glossary.md b/docs/glossary.md index d8a0afadc4c..1816414907a 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -21,4 +21,14 @@ SoA AoS Memory layout where a collection of objects are stored in a single array, where each object internally has a member for each property. + +Seed + A starting point for the track finding stage. E.g. a triplet of {term}`space + points` that are loosely compatible with a track hypothesis. + +Space point + A three dimensional (possibly approximated) location through which a particle + will have passed and created masurements. In some cases, like strip + detectors, space points are [formed from multiple + measurements](#tracking_sp_formation). ::: diff --git a/docs/tracking.md b/docs/tracking.md index afbafaf7fb4..cc61d96a7ca 100644 --- a/docs/tracking.md +++ b/docs/tracking.md @@ -115,7 +115,7 @@ $\sigma^2(X)$ are the regular variances. As the covariance matrix $C$ is symmetric, only the upper right half is shown in the matrix above. The uncertainties associated with the local position, as well as the momentum direction are indicated in {numref}`parameters` (a) as an ellipse and a cone -around the momentum vector $\vec p$, respectively. +around the momentum vector $\vec p$, respectively. (particle_propagation)= ## Particle propagation @@ -483,7 +483,7 @@ detectors, the readout can either be performed in a binary way, only recording which segments fired, or the amount of charges measured in the segment can be recorded, e.g. via *time-over-threshold* readout. In all cases, the readout is attached to an identifier uniquely locating the segment on the corresponding -sensor. +sensor. As a next step, these raw readouts need to be *clustered*, in order to extract an estimate of where particles intersect with the sensor. The general @@ -495,7 +495,7 @@ either consider all eight surrounding pixels as neighboring a central one, or only consider the four non-diagonal ones, as shown in {numref}`clustering_cca`. The figure only shows the simplest possible cluster starting from the central pixel. In reality, the CCA will iteratively -continue from the pixels on the cluster edges. +continue from the pixels on the cluster edges. (clustering_cca)= :::{figure} /figures/tracking/cca.svg @@ -519,7 +519,7 @@ $$ $$ Here, $\vec l_i$ is the local position of the $i$-th segment while -$q_i$ is its charge. +$q_i$ is its charge. An illustration of the clusterization can be found in {numref}`clustering_image`, where a pixel sensor is shown to be intersected by a charged particle, @@ -528,7 +528,7 @@ with a red frame receive energy from the particle, but the amount is under the readout threshold. Four other cells receive energy above the threshold and are read out. The clustering will then group these four cells into a cluster, and subsequently estimate the cluster position based on the energy -deposited in the cells. In case no charge information is not available +deposited in the cells. In case no charge information is not available for a given detector, the calculation is purely geometric. @@ -559,8 +559,9 @@ mitigated by allowing tracks to share clusters with other particles, which comes at the price of allowing duplicated tracks to some extent. Additionally, merged clusters typically feature worse position resolution, which manifests itself since it negatively affects the final fit of the -track. +track. +(tracking_sp_formation)= ## Spacepoint formation The basic input to most forms of pattern recognition algorithms for tracking @@ -651,7 +652,7 @@ $$ with the charge $q$ and the magnetic field $B$. An intersection between the straight line in the $rz$-plane with the $z$-axis gives an -estimate of the longitudinal impact parameter. +estimate of the longitudinal impact parameter. An illustration of seeds in the transverse plane is found in {numref}`seeding_figure`. Note that seeds can incorporate hits spread across all of the layers shown, although this can be a configuration parameter. @@ -876,7 +877,7 @@ $$ and a filtered residual $$ - \vec r_k = \vec m_k - \mathbf H_k \vec x_k + \vec r_k = \vec m_k - \mathbf H_k \vec x_k , $$ @@ -885,7 +886,7 @@ the measurement $\vec m_k$. Using the filtered residual, an effective $\chi^2$ increment $$ - \chi^2_+ = \vec r_k^\mathrm{T} + \chi^2_+ = \vec r_k^\mathrm{T} \left[ \left( \mathbb 1 - \mathbf H_k \mathbf K_k \right) \mathbf V_k \right]^{-1} \vec r_k $$