Project
Loading...
Searching...
No Matches
TraversalTopology.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14
15#include <algorithm>
16#include <limits>
17
18#include <gsl/span>
19
21{
22
23namespace
24{
25uint16_t componentForPosition(gsl::span<const uint16_t> componentOffsets, uint16_t position) noexcept
26{
27 const auto upper = std::upper_bound(componentOffsets.begin(), componentOffsets.end(), position);
28 return static_cast<uint16_t>(std::distance(componentOffsets.begin(), upper) - 1);
29}
30
31LayerMask skippedBetween(uint16_t fromPosition, uint16_t toPosition) noexcept
32{
33 return LayerMask::skipped(fromPosition, toPosition);
34}
35} // namespace
36
38 const o2::itsmft::IterationParameters& parameters)
39{
41 if (!layout.valid()) {
43 return result;
44 }
45
46 if (parameters.NLayers != 0 && parameters.NLayers != layout.size()) {
48 return result;
49 }
50 if (parameters.MaxHoles < 0) {
52 return result;
53 }
54 const auto seedingLayers = parameters.SeedingLayers;
55 const auto roadStartLayers = parameters.StartLayerMask;
56 const auto disabledLayers = parameters.InactiveLayerMask;
57
58 TraversalTopology topology;
59 topology.nLayers = static_cast<uint16_t>(layout.size());
60 for (uint16_t position = 0; position < layout.size(); ++position) {
61 if (!disabledLayers.has(position)) {
62 topology.activeLayers.set(position);
63 topology.activeSurfaceList.push_back(LayerId{position});
64 }
65 }
66 if (topology.activeSurfaceList.empty()) {
68 return result;
69 }
70 topology.seedingLayers = seedingLayers.empty() ? topology.activeLayers : (seedingLayers & topology.activeLayers);
71
72 const auto componentOffsets = layout.getComponentOffsets();
73 const auto holeLayers = layout.getHoleLayers();
74 const auto componentOf = [componentOffsets](uint16_t position) {
75 return componentForPosition(componentOffsets, position);
76 };
77
78 for (uint16_t fromPosition = 0; fromPosition + 1 < layout.size(); ++fromPosition) {
79 if (!topology.seedingLayers.has(fromPosition)) {
80 continue;
81 }
82 for (uint16_t toPosition = fromPosition + 1; toPosition < layout.size(); ++toPosition) {
83 if (!topology.seedingLayers.has(toPosition) ||
84 componentOf(fromPosition) != componentOf(toPosition)) {
85 continue;
86 }
87 const auto skipped = skippedBetween(fromPosition, toPosition) & topology.seedingLayers;
88 if (skipped.count() > parameters.MaxHoles || !skipped.isSubsetOf(holeLayers)) {
89 continue;
90 }
91 if (topology.edges.size() >= MaxLayoutEdges) {
93 return result;
94 }
95 topology.edges.push_back(Edge{LayerId{fromPosition}, LayerId{toPosition}});
96 }
97 }
98
99 for (uint32_t first = 0; first < topology.edges.size(); ++first) {
100 for (uint32_t second = 0; second < topology.edges.size(); ++second) {
101 const auto& firstEdge = topology.edges[first];
102 const auto& secondEdge = topology.edges[second];
103 if (firstEdge.to != secondEdge.from || firstEdge.from == secondEdge.to) {
104 continue;
105 }
106 const auto skipped = (skippedBetween(firstEdge.from.value(), firstEdge.to.value()) |
107 skippedBetween(secondEdge.from.value(), secondEdge.to.value())) &
108 topology.seedingLayers;
109 if (skipped.count() > parameters.MaxHoles || !skipped.isSubsetOf(holeLayers)) {
110 continue;
111 }
112 if (topology.paths.size() >= MaxLayoutPaths) {
114 return result;
115 }
116 topology.paths.push_back(CellPath{EdgeId{static_cast<uint16_t>(first)}, EdgeId{static_cast<uint16_t>(second)}});
117 }
118 }
119
120 topology.pathsByFirstEdgeOffsets.assign(topology.edges.size() + 1, 0);
121 for (const auto& path : topology.paths) {
122 ++topology.pathsByFirstEdgeOffsets[path.first.value() + 1];
123 }
124 for (size_t offset = 1; offset < topology.pathsByFirstEdgeOffsets.size(); ++offset) {
126 }
127 topology.pathsByFirstEdge.resize(topology.paths.size());
128 auto cursor = topology.pathsByFirstEdgeOffsets;
129 for (uint32_t path = 0; path < topology.paths.size(); ++path) {
130 topology.pathsByFirstEdge[cursor[topology.paths[path].first.value()]++] = CellPathId{static_cast<uint16_t>(path)};
131 }
132
133 topology.scheduledPaths.reserve(topology.paths.size());
134 for (uint32_t path = 0; path < topology.paths.size(); ++path) {
135 topology.scheduledPaths.push_back(CellPathId{static_cast<uint16_t>(path)});
136 }
137 const auto pathOrder = [&](CellPathId lhs, CellPathId rhs) {
138 const auto lhsTarget = topology.edges[topology.paths[lhs.value()].second.value()].to;
139 const auto rhsTarget = topology.edges[topology.paths[rhs.value()].second.value()].to;
140 return lhsTarget != rhsTarget ? lhsTarget < rhsTarget : lhs < rhs;
141 };
142 std::sort(topology.scheduledPaths.begin(), topology.scheduledPaths.end(), pathOrder);
143
144 topology.roadStartPaths.reserve(topology.paths.size());
145 for (const auto path : topology.scheduledPaths) {
146 const auto target = topology.edges[topology.paths[path.value()].second.value()].to;
147 if (roadStartLayers.has(target.value())) {
148 topology.roadStartPaths.push_back(path);
149 }
150 }
151 topology.roadStartComponentOffsets.push_back(0);
152 uint16_t previousComponent = std::numeric_limits<uint16_t>::max();
153 for (uint32_t index = 0; index < topology.roadStartPaths.size(); ++index) {
154 const auto path = topology.roadStartPaths[index];
155 const auto target = topology.edges[topology.paths[path.value()].second.value()].to;
156 const auto component = componentOf(target.value());
157 if (component != previousComponent && index != 0) {
158 topology.roadStartComponentOffsets.push_back(index);
159 }
160 previousComponent = component;
161 }
162 topology.roadStartComponentOffsets.push_back(static_cast<uint32_t>(topology.roadStartPaths.size()));
163
164 result.topology.emplace(std::move(topology));
165 return result;
166}
167
168} // namespace o2::itsmft::tracking
Shared CA tracking configuration for ITS and MFT.
double upper[3]
gsl::span< const uint16_t > getComponentOffsets() const noexcept
GLuint64EXT * result
Definition glcorearb.h:5662
GLuint index
Definition glcorearb.h:781
GLint first
Definition glcorearb.h:399
GLenum target
Definition glcorearb.h:1641
GLintptr offset
Definition glcorearb.h:660
GLsizei const GLchar *const * path
Definition glcorearb.h:3591
constexpr uint32_t MaxLayoutPaths
Definition IdTypes.h:72
constexpr uint32_t MaxLayoutEdges
Definition IdTypes.h:71
TraversalTopologyBuildResult deriveTraversalTopology(const DetectorConfiguration &layout, const o2::itsmft::IterationParameters &parameters)
tracking::LayerMask SeedingLayers
tracking::LayerMask StartLayerMask
tracking::LayerMask InactiveLayerMask
std::vector< uint32_t > pathsByFirstEdgeOffsets
std::vector< uint32_t > roadStartComponentOffsets
std::vector< CellPathId > pathsByFirstEdge