99// granted to it by virtue of its status as an Intergovernmental Organization
1010// or submit itself to any jurisdiction.
1111
12- #ifndef ALICEO2_ITSMFT_TRACKING_DETECTORLAYOUT_H_
13- #define ALICEO2_ITSMFT_TRACKING_DETECTORLAYOUT_H_
12+ #ifndef ALICEO2_ITSMFT_TRACKING_DETECTORCONFIGURATION_H_
13+ #define ALICEO2_ITSMFT_TRACKING_DETECTORCONFIGURATION_H_
1414
1515#include < algorithm>
1616#include < cstdint>
17+ #include < utility>
1718#include < vector>
1819
1920#include < gsl/span>
2021
2122#include " ITSMFTTracking/SurfaceDescriptor.h"
2223#include " ITSMFTTracking/LayerMask.h"
24+ #include " ITSMFTTracking/IndexTableConfigurationSet.h"
2325
2426namespace o2 ::itsmft::tracking
2527{
2628
27- enum class DetectorLayoutError : uint8_t {
29+ enum class DetectorConfigurationError : uint8_t {
2830 None,
2931 EmptyCatalog,
3032 TooManySurfaces,
3133 InvalidComponentBoundary,
3234 HoleLayersOutsideLayout
3335};
3436
35- struct DetectorLayoutDefinition {
36- // First position of each component. Position zero is always required.
37- std::vector<uint16_t > componentOffsets{0 };
38- LayerMask holeLayers{};
39- };
40-
41- inline DetectorLayoutDefinition makeDetectorLayout (LayerMask holeLayers = {})
42- {
43- DetectorLayoutDefinition definition;
44- definition.holeLayers = holeLayers;
45- return definition;
46- }
47-
48- // Immutable detector layout. LayerId is exactly the dense position of a layer
49- // descriptor in this container. Iteration-expanded topology belongs to the
50- // Tracker's IterationConfiguration; this type intentionally owns no edges,
51- // paths, adjacency, schedules, or mutable pass state.
52- class DetectorLayout
37+ // TimeFrame-owned detector geometry and prepared settings, shared by every
38+ // iteration. LayerId is the dense descriptor position. SurfaceCatalogView
39+ // borrows only the geometry; iteration topology and event state live elsewhere.
40+ class DetectorConfiguration
5341{
5442 public:
55- DetectorLayout () = default ;
56- DetectorLayout (gsl::span<const SurfaceDescriptor> layers, DetectorLayoutDefinition definition = {})
57- : mLayers {layers.begin (), layers.end ()}, mComponentOffsets {std::move (definition. componentOffsets )}, mHoleLayers {definition. holeLayers }
43+ DetectorConfiguration () = default ;
44+ DetectorConfiguration (gsl::span<const SurfaceDescriptor> layers, std::vector< uint16_t > componentOffsets = { 0 }, LayerMask holeLayers = {})
45+ : mLayers {layers.begin (), layers.end ()}, mComponentOffsets {std::move (componentOffsets)}, mHoleLayers {holeLayers}
5846 {
5947 validate ();
6048 }
6149
62- bool valid () const noexcept { return mError == DetectorLayoutError ::None; }
63- DetectorLayoutError getError () const noexcept { return mError ; }
50+ bool valid () const noexcept { return mError == DetectorConfigurationError ::None; }
51+ DetectorConfigurationError getError () const noexcept { return mError ; }
6452 bool empty () const noexcept { return mLayers .empty (); }
6553 std::size_t size () const noexcept { return mLayers .size (); }
6654 gsl::span<const SurfaceDescriptor> getLayers () const noexcept { return mLayers ; }
@@ -69,6 +57,14 @@ class DetectorLayout
6957 LayerMask getHoleLayers () const noexcept { return mHoleLayers ; }
7058 SurfaceCatalogView getSurfaceCatalog () const noexcept { return {mLayers .data (), static_cast <uint32_t >(mLayers .size ())}; }
7159
60+ // Cylinders have one radius; disks use the midpoint of their radial chart.
61+ float getRepresentativeRadius (LayerId id) const
62+ {
63+ const auto & surface = (*this )[id];
64+ return surface.kind == SurfaceKind::Cylinder ? surface.referenceCoordinate
65+ : 0 .5f * (surface.chartRange .min + surface.chartRange .max );
66+ }
67+
7268 bool sameComponent (uint16_t first, uint16_t second) const noexcept
7369 {
7470 if (first >= mLayers .size () || second >= mLayers .size ()) {
@@ -80,34 +76,42 @@ class DetectorLayout
8076 return component (first) == component (second);
8177 }
8278
79+ // Prepared once by Tracker before the configuration is installed in a frame.
80+ IndexTableConfigurationSet indexTableConfigs;
81+ std::vector<float > positionResolutions;
82+ std::vector<uint32_t > addTimeError;
83+ std::vector<float > layerResolution;
84+ std::vector<float > systError2Row;
85+ std::vector<float > systError2Col;
86+
8387 private:
8488 void validate () noexcept
8589 {
8690 if (mLayers .empty ()) {
87- mError = DetectorLayoutError ::EmptyCatalog;
91+ mError = DetectorConfigurationError ::EmptyCatalog;
8892 return ;
8993 }
9094 if (mLayers .size () > MaxLayoutSurfaces) {
91- mError = DetectorLayoutError ::TooManySurfaces;
95+ mError = DetectorConfigurationError ::TooManySurfaces;
9296 return ;
9397 }
9498 if (mComponentOffsets .empty () || mComponentOffsets .front () != 0 || mComponentOffsets .back () >= mLayers .size () ||
9599 !std::is_sorted (mComponentOffsets .begin (), mComponentOffsets .end ()) ||
96100 std::adjacent_find (mComponentOffsets .begin (), mComponentOffsets .end ()) != mComponentOffsets .end ()) {
97- mError = DetectorLayoutError ::InvalidComponentBoundary;
101+ mError = DetectorConfigurationError ::InvalidComponentBoundary;
98102 return ;
99103 }
100104 if (!mHoleLayers .isSubsetOf (LayerMask::span (0 , static_cast <int >(mLayers .size ()) - 1 ))) {
101- mError = DetectorLayoutError ::HoleLayersOutsideLayout;
105+ mError = DetectorConfigurationError ::HoleLayersOutsideLayout;
102106 return ;
103107 }
104- mError = DetectorLayoutError ::None;
108+ mError = DetectorConfigurationError ::None;
105109 }
106110
107111 std::vector<SurfaceDescriptor> mLayers ;
108112 std::vector<uint16_t > mComponentOffsets ;
109113 LayerMask mHoleLayers {};
110- DetectorLayoutError mError {DetectorLayoutError ::EmptyCatalog};
114+ DetectorConfigurationError mError {DetectorConfigurationError ::EmptyCatalog};
111115};
112116
113117} // namespace o2::itsmft::tracking
0 commit comments