Project
Loading...
Searching...
No Matches
testTraversalTopology.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
12#define BOOST_TEST_MODULE ITSMFT TraversalTopology
13#define BOOST_TEST_MAIN
14#define BOOST_TEST_DYN_LINK
15#include <boost/test/unit_test.hpp>
16
17#include <algorithm>
18#include <type_traits>
19#include <vector>
20
23
24namespace
25{
26using namespace o2::itsmft::tracking;
28
29std::vector<SurfaceDescriptor> catalog(uint16_t count)
30{
31 std::vector<SurfaceDescriptor> result;
32 result.reserve(count);
33 for (uint16_t id = 0; id < count; ++id) {
34 result.push_back(SurfaceDescriptor{id, 0, SurfaceKind::Cylinder});
35 }
36 return result;
37}
38
39DetectorConfiguration makeLayout(uint16_t layerCount,
40 std::vector<uint16_t> componentOffsets = {0},
41 LayerMask holeLayers = {})
42{
43 const auto surfaces = catalog(layerCount);
44 return DetectorConfiguration{surfaces, std::move(componentOffsets), holeLayers};
45}
46
47LayerMask mask(std::initializer_list<uint16_t> ids)
48{
50 for (const auto id : ids) {
51 result.set(id);
52 }
53 return result;
54}
55
56LayerMask layerMask(std::initializer_list<uint16_t> positions)
57{
59 for (const auto position : positions) {
60 result.set(position);
61 }
62 return result;
63}
64
65TrackingParameters parametersFor(const DetectorConfiguration& layout)
66{
68 result.NLayers = static_cast<int>(layout.size());
69 result.StartLayerMask = LayerMask::span(0, result.NLayers - 1);
70 return result;
71}
72
73const Edge* findEdge(const TraversalTopology& topology, LayerId from, LayerId to)
74{
75 const auto edge = std::find_if(topology.edges.begin(), topology.edges.end(), [&](const auto& candidate) {
76 return candidate.from == from && candidate.to == to;
77 });
78 return edge == topology.edges.end() ? nullptr : &*edge;
79}
80} // namespace
81
82BOOST_AUTO_TEST_CASE(CellPathContainsOnlyTwoEdgeIds)
83{
84 static_assert(std::is_standard_layout_v<CellPath>);
85 static_assert(std::is_trivially_copyable_v<CellPath>);
86 static_assert(std::is_same_v<decltype(CellPath::first), EdgeId>);
87 static_assert(std::is_same_v<decltype(CellPath::second), EdgeId>);
88 static_assert(sizeof(CellPath) == sizeof(EdgeId) + sizeof(EdgeId));
89 BOOST_CHECK_EQUAL(sizeof(CellPath), 4u);
90}
91
92BOOST_AUTO_TEST_CASE(EdgeContainsOnlySurfaceEndpoints)
93{
94 static_assert(std::is_standard_layout_v<Edge>);
95 static_assert(std::is_trivially_copyable_v<Edge>);
96 static_assert(std::is_same_v<decltype(Edge::from), LayerId>);
97 static_assert(std::is_same_v<decltype(Edge::to), LayerId>);
98 static_assert(sizeof(Edge) == sizeof(LayerId) + sizeof(LayerId));
99 BOOST_CHECK_EQUAL(sizeof(Edge), 4u);
100}
101
102BOOST_AUTO_TEST_CASE(ComponentBoundariesRejectCrossComponentEdges)
103{
104 const auto layout = makeLayout(4, {0, 2});
105 const auto result = deriveTraversalTopology(layout, parametersFor(layout));
106 BOOST_REQUIRE(result.ok());
107 BOOST_CHECK_EQUAL(result.topology->edges.size(), 2u);
108 BOOST_CHECK(findEdge(*result.topology, LayerId{1}, LayerId{2}) == nullptr);
109}
110
111BOOST_AUTO_TEST_CASE(AllActiveChainDerivesEdgesAndCellPaths)
112{
113 const auto layout = makeLayout(4);
114 const auto result = deriveTraversalTopology(layout, parametersFor(layout));
115 BOOST_REQUIRE(result.ok());
116 const auto& topology = *result.topology;
117 BOOST_CHECK_EQUAL(topology.nLayers, 4u);
118 BOOST_CHECK_EQUAL(topology.activeSurfaceList.size(), 4u);
119 BOOST_CHECK_EQUAL(topology.edges.size(), 3u);
120 BOOST_CHECK_EQUAL(topology.paths.size(), 2u);
121 BOOST_CHECK(topology.edges[0].from == LayerId{0});
122 BOOST_CHECK(topology.edges[0].to == LayerId{1});
123 BOOST_CHECK(topology.edges[1].from == LayerId{1});
124 BOOST_CHECK(topology.edges[1].to == LayerId{2});
125 BOOST_CHECK(topology.edges[2].from == LayerId{2});
126 BOOST_CHECK(topology.edges[2].to == LayerId{3});
127 BOOST_CHECK(topology.paths[0].first == EdgeId{0});
128 BOOST_CHECK(topology.paths[0].second == EdgeId{1});
129 BOOST_CHECK(topology.paths[1].first == EdgeId{1});
130 BOOST_CHECK(topology.paths[1].second == EdgeId{2});
131}
132
133BOOST_AUTO_TEST_CASE(SeedingLayersBuildTheGraphWhileStartLayersOnlySelectRoadStarts)
134{
135 const auto layout = makeLayout(5);
136 const auto seeding = mask({0, 2, 4});
137 auto outerStartParameters = parametersFor(layout);
138 outerStartParameters.SeedingLayers = layerMask({0, 2, 4});
139 outerStartParameters.StartLayerMask = layerMask({4});
140 const auto startsAtOuterSurface = deriveTraversalTopology(
141 layout, outerStartParameters);
142 BOOST_REQUIRE(startsAtOuterSurface.ok());
143 const auto& topology = *startsAtOuterSurface.topology;
144 BOOST_CHECK(topology.seedingLayers == seeding);
145 BOOST_CHECK_EQUAL(topology.activeSurfaceList.size(), 5u);
146 BOOST_REQUIRE_EQUAL(topology.edges.size(), 2u);
147 BOOST_CHECK(findEdge(topology, LayerId{0}, LayerId{2}) != nullptr);
148 BOOST_CHECK(findEdge(topology, LayerId{2}, LayerId{4}) != nullptr);
149 BOOST_REQUIRE_EQUAL(topology.paths.size(), 1u);
150 BOOST_REQUIRE_EQUAL(topology.roadStartPaths.size(), 1u);
151
152 auto middleStartParameters = outerStartParameters;
153 middleStartParameters.StartLayerMask = layerMask({2});
154 const auto startsAtMiddleSurface = deriveTraversalTopology(
155 layout, middleStartParameters);
156 BOOST_REQUIRE(startsAtMiddleSurface.ok());
157 BOOST_REQUIRE_EQUAL(startsAtMiddleSurface.topology->edges.size(), topology.edges.size());
158 BOOST_REQUIRE_EQUAL(startsAtMiddleSurface.topology->paths.size(), topology.paths.size());
159 for (std::size_t i = 0; i < topology.edges.size(); ++i) {
160 BOOST_CHECK(startsAtMiddleSurface.topology->edges[i].from == topology.edges[i].from);
161 BOOST_CHECK(startsAtMiddleSurface.topology->edges[i].to == topology.edges[i].to);
162 }
163 for (std::size_t i = 0; i < topology.paths.size(); ++i) {
164 BOOST_CHECK(startsAtMiddleSurface.topology->paths[i].first == topology.paths[i].first);
165 BOOST_CHECK(startsAtMiddleSurface.topology->paths[i].second == topology.paths[i].second);
166 }
167 BOOST_CHECK(startsAtMiddleSurface.topology->roadStartPaths.empty());
168}
169
170BOOST_AUTO_TEST_CASE(DisabledMiddleSurfaceRetainsAdmittedBridge)
171{
172 const auto layout = makeLayout(4, {0}, mask({1}));
173 auto parameters = parametersFor(layout);
174 parameters.MaxHoles = 1;
175 parameters.InactiveLayerMask = layerMask({1});
176 const auto result = deriveTraversalTopology(layout, parameters);
177 BOOST_REQUIRE(result.ok());
178 const auto& topology = *result.topology;
179 BOOST_CHECK_EQUAL(topology.activeSurfaceList.size(), 3u);
180 BOOST_CHECK_EQUAL(topology.edges.size(), 2u);
181 BOOST_CHECK_EQUAL(topology.paths.size(), 1u);
182 const auto* bridge = findEdge(topology, LayerId{0}, LayerId{2});
183 BOOST_REQUIRE(bridge != nullptr);
184 BOOST_CHECK(bridge->from == LayerId{0});
185 BOOST_CHECK(bridge->to == LayerId{2});
186 BOOST_CHECK(topology.activeSurfaceList[1] == LayerId{2});
187 BOOST_CHECK(topology.paths[0].first == EdgeId{0});
188 BOOST_CHECK(topology.paths[0].second == EdgeId{1});
189}
190
191BOOST_AUTO_TEST_CASE(DisabledEndpointOmitsItsEdges)
192{
193 const auto layout = makeLayout(4, {0}, mask({1}));
194 auto parameters = parametersFor(layout);
195 parameters.MaxHoles = 1;
196 parameters.InactiveLayerMask = layerMask({0});
197 const auto result = deriveTraversalTopology(layout, parameters);
198 BOOST_REQUIRE(result.ok());
199 for (const auto& edge : result.topology->edges) {
200 BOOST_CHECK(edge.from != LayerId{0});
201 BOOST_CHECK(edge.to != LayerId{0});
202 }
203 BOOST_CHECK(findEdge(*result.topology, LayerId{1}, LayerId{2}) != nullptr);
204}
205
206BOOST_AUTO_TEST_CASE(InvalidDerivationIsTransactional)
207{
208 const auto layout = makeLayout(4);
209 auto parameters = parametersFor(layout);
210 parameters.NLayers = 7;
211 const auto result = deriveTraversalTopology(layout, parameters);
212 BOOST_CHECK(!result.ok());
213 BOOST_CHECK(!result.topology.has_value());
214 BOOST_CHECK(result.error == TraversalTopologyError::LayerCountMismatch);
215
216 DetectorConfiguration invalid;
217 const auto invalidResult = deriveTraversalTopology(invalid, TrackingParameters{});
218 BOOST_CHECK(!invalidResult.ok());
219 BOOST_CHECK(!invalidResult.topology.has_value());
220 BOOST_CHECK(invalidResult.error == TraversalTopologyError::InvalidLayout);
221}
Shared CA tracking configuration for ITS and MFT.
int32_t i
GLint GLsizei count
Definition glcorearb.h:399
GLuint64EXT * result
Definition glcorearb.h:5662
GLuint * ids
Definition glcorearb.h:647
GLint GLuint mask
Definition glcorearb.h:291
GLuint id
Definition glcorearb.h:650
detail::Identifier< EdgeIdTag, uint16_t > EdgeId
Definition IdTypes.h:61
detail::Identifier< LayerIdTag, uint16_t > LayerId
Definition IdTypes.h:60
TraversalTopologyBuildResult deriveTraversalTopology(const DetectorConfiguration &layout, const o2::itsmft::IterationParameters &parameters)
BOOST_AUTO_TEST_CASE(CellPathContainsOnlyTwoEdgeIds)
BOOST_CHECK(tree)
BOOST_CHECK_EQUAL(triggersD.size(), triggers.size())