Project
Loading...
Searching...
No Matches
testROFLookupTables.cxx
Go to the documentation of this file.
1// Copyright 2019-2026 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#include <boost/test/tools/old/interface.hpp>
13#define BOOST_TEST_MODULE ITS ROFLookupTables
14#define BOOST_TEST_MAIN
15#define BOOST_TEST_DYN_LINK
16
17#include <boost/test/unit_test.hpp>
19
21// LayerTiming
22BOOST_AUTO_TEST_CASE(layertiming_basic)
23{
25 table.defineLayer(0, 10, 594, 100, 0, 50);
26 const auto& layer = table.getLayer(0);
27
28 // test ROF time calculations
29 auto start0 = layer.getROFStartInBC(0);
30 BOOST_CHECK_EQUAL(start0, 100); // delay only
31
32 auto end0 = layer.getROFEndInBC(0);
33 BOOST_CHECK_EQUAL(end0, 100 + 594);
34
35 // test second ROF
36 auto start1 = layer.getROFStartInBC(1);
37 BOOST_CHECK_EQUAL(start1, 100 + 594);
38}
39
40BOOST_AUTO_TEST_CASE(layertiming_base)
41{
43 table.defineLayer(0, 10, 500, 0, 0, 0);
44 table.defineLayer(1, 12, 600, 50, 0, 0);
45 table.defineLayer(2, 8, 400, 100, 0, 0);
46 const auto& layer1 = table.getLayer(1);
47 BOOST_CHECK_EQUAL(layer1.mNROFsTF, 12);
48 BOOST_CHECK_EQUAL(layer1.mROFLength, 600);
49}
50
51BOOST_AUTO_TEST_CASE(rofmask_construct_from_timing)
52{
54 timing.defineLayer(0, 3, 100, 0, 0, 0);
55 timing.defineLayer(1, 4, 50, 25, 0, 0);
56
58 const auto view = mask.getView();
59
60 BOOST_REQUIRE(view.mFlatMask != nullptr);
61 BOOST_REQUIRE(view.mLayerROFOffsets != nullptr);
62 BOOST_CHECK_EQUAL(view.mLayerROFOffsets[0], 0);
63 BOOST_CHECK_EQUAL(view.mLayerROFOffsets[1], 3);
64 BOOST_CHECK_EQUAL(view.mLayerROFOffsets[2], 7);
65
66 // by default all rofs are disabled
67 for (int rof{0}; rof < 3; ++rof) {
68 BOOST_CHECK(!view.isROFEnabled(0, rof));
69 }
70 for (int rof{0}; rof < 4; ++rof) {
71 BOOST_CHECK(!view.isROFEnabled(1, rof));
72 }
73
74 mask.selectROF({110, 20});
75
76 BOOST_CHECK(!view.isROFEnabled(0, 0));
77 BOOST_CHECK(view.isROFEnabled(0, 1));
78 BOOST_CHECK(!view.isROFEnabled(0, 2));
79
80 BOOST_CHECK(!view.isROFEnabled(1, 0));
81 BOOST_CHECK(view.isROFEnabled(1, 1));
82 BOOST_CHECK(view.isROFEnabled(1, 2));
83 BOOST_CHECK(!view.isROFEnabled(1, 3));
84}
85
86// ROFOverlapTable
87BOOST_AUTO_TEST_CASE(rofoverlap_basic)
88{
89 // define 2 layers with the same definitions (no staggering)
91 table.defineLayer(0, 12, 594, 0, 0, 0);
92 table.defineLayer(1, 12, 594, 0, 0, 0);
93 table.init();
94 const auto view = table.getView();
95 // each rof in layer 0 should be compatible with its layer 1 equivalent
96 for (int rof{0}; rof < 12; ++rof) {
97 BOOST_CHECK(view.doROFsOverlap(0, rof, 1, rof));
98 BOOST_CHECK(view.doROFsOverlap(1, rof, 0, rof));
99 BOOST_CHECK(view.getOverlap(0, 1, rof).getEntries() == 1);
100 }
101}
102
103BOOST_AUTO_TEST_CASE(rofoverlap_staggered)
104{
105 // test staggered layers with ROF delay
107 table.defineLayer(0, 10, 500, 0, 0, 0);
108 table.defineLayer(1, 10, 500, 250, 0, 0); // 250 BC delay
109 table.init();
110 const auto view = table.getView();
111
112 // verify overlap range
113 { // from 0 to 1
114 const auto& range = view.getOverlap(0, 1, 0);
115 BOOST_CHECK_EQUAL(range.getEntries(), 1);
116 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
117 }
118 { // from 1 to 0
119 const auto& range = view.getOverlap(1, 0, 0);
120 BOOST_CHECK_EQUAL(range.getEntries(), 2);
121 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
122 }
123}
124
125BOOST_AUTO_TEST_CASE(rofoverlap_staggered_pp)
126{
127 const uint32_t rofLen{198}, rofBins{6};
128 const uint32_t rofDelay{rofLen / rofBins};
130 for (uint32_t lay{0}; lay < 3; ++lay) {
131 table.defineLayer(lay, 6, rofLen, lay * rofDelay, 0, 0);
132 }
133 table.init();
134 const auto view = table.getView();
135 view.printAll();
136}
137
138BOOST_AUTO_TEST_CASE(rofoverlap_staggered_track_time_ignores_added_error)
139{
140 const uint32_t rofLen{198};
141 const uint32_t rofDelay{33};
142 const uint32_t addTimeErr{100};
143
144 o2::its::ROFOverlapTable<7> tableNoError;
145 o2::its::ROFOverlapTable<7> tableWithError;
146 for (uint32_t lay{0}; lay < 7; ++lay) {
147 const auto delay = (lay == 6) ? 0 : lay * rofDelay;
148 tableNoError.defineLayer(lay, 2, rofLen, delay, 0, 0);
149 tableWithError.defineLayer(lay, 2, rofLen, delay, 0, addTimeErr);
150 }
151
152 auto getCommonTrackTime = [](const auto& table) {
153 auto ts = table.getLayer(0).getROFTimeBounds(0);
154 for (uint32_t lay{1}; lay < 7; ++lay) {
155 ts += table.getLayer(lay).getROFTimeBounds(0);
156 }
157 return ts.makeSymmetrical();
158 };
159
160 const auto tsNoError = getCommonTrackTime(tableNoError);
161 BOOST_CHECK_EQUAL(tsNoError.getTimeStamp(), 181.5f);
162 BOOST_CHECK_EQUAL(tsNoError.getTimeStampError(), 16.5f);
163
164 const auto tsWithError = getCommonTrackTime(tableWithError);
165 BOOST_CHECK_EQUAL(tsWithError.getTimeStamp(), 181.5f);
166 BOOST_CHECK_EQUAL(tsWithError.getTimeStampError(), 16.5f);
167}
168
169BOOST_AUTO_TEST_CASE(rofoverlap_track_time_boundary_migration_fallback)
170{
171 const uint32_t rofLen{198};
172 const uint32_t addTimeErr{30};
173
175 for (uint32_t lay{0}; lay < 7; ++lay) {
176 table.defineLayer(lay, 4, rofLen, 0, 0, addTimeErr);
177 }
178
179 auto getCommonTrackTime = [](const auto& table) {
180 bool firstCls{true}, nominalCompatible{true};
181 o2::its::TimeEstBC nominalTS, expandedTS;
182 for (uint32_t lay{0}; lay < 7; ++lay) {
183 const auto rof = lay < 3 ? 0 : 1;
184 const auto nominalROFTS = table.getLayer(lay).getROFTimeBounds(rof);
185 const auto expandedROFTS = table.getLayer(lay).getROFTimeBounds(rof, true);
186 if (firstCls) {
187 firstCls = false;
188 nominalTS = nominalROFTS;
189 expandedTS = expandedROFTS;
190 } else {
191 if (nominalCompatible) {
192 if (nominalTS.isCompatible(nominalROFTS)) {
193 nominalTS += nominalROFTS;
194 } else {
195 nominalCompatible = false;
196 }
197 }
198 BOOST_REQUIRE(expandedTS.isCompatible(expandedROFTS));
199 expandedTS += expandedROFTS;
200 }
201 }
202 return (nominalCompatible ? nominalTS : expandedTS).makeSymmetrical();
203 };
204
205 const auto tsWithError = getCommonTrackTime(table);
206 BOOST_CHECK_EQUAL(tsWithError.getTimeStamp(), 198.f);
207 BOOST_CHECK_EQUAL(tsWithError.getTimeStampError(), 30.f);
208}
209
210BOOST_AUTO_TEST_CASE(rofoverlap_staggered_alllayers)
211{
212 // test staggered layers with ROF delay
214 table.defineLayer(0, 2, 3, 0, 0, 0);
215 table.defineLayer(1, 3, 2, 0, 0, 0);
216 table.defineLayer(2, 6, 1, 0, 0, 0);
217 table.init();
218 const auto view = table.getView();
219 // verify overlap range
220 { // from 0 to 1 rof=0
221 const auto& range = view.getOverlap(0, 1, 0);
222 BOOST_CHECK_EQUAL(range.getEntries(), 2);
223 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
224 }
225 { // from 0 to 2 rof=0
226 const auto& range = view.getOverlap(0, 2, 0);
227 BOOST_CHECK_EQUAL(range.getEntries(), 3);
228 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
229 }
230 { // from 0 to 1 rof=1
231 const auto& range = view.getOverlap(0, 1, 1);
232 BOOST_CHECK_EQUAL(range.getEntries(), 2);
233 BOOST_CHECK_EQUAL(range.getFirstEntry(), 1);
234 }
235 { // from 0 to 2 rof=1
236 const auto& range = view.getOverlap(0, 2, 1);
237 BOOST_CHECK_EQUAL(range.getEntries(), 3);
238 BOOST_CHECK_EQUAL(range.getFirstEntry(), 3);
239 }
240 { // from 1 to 2 rof=0
241 const auto& range = view.getOverlap(1, 2, 0);
242 BOOST_CHECK_EQUAL(range.getEntries(), 2);
243 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
244 }
245 { // from 1 to 0 rof=0
246 const auto& range = view.getOverlap(1, 0, 0);
247 BOOST_CHECK_EQUAL(range.getEntries(), 1);
248 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
249 }
250 { // from 1 to 2 rof=1
251 const auto& range = view.getOverlap(1, 2, 1);
252 BOOST_CHECK_EQUAL(range.getEntries(), 2);
253 BOOST_CHECK_EQUAL(range.getFirstEntry(), 2);
254 }
255 { // from 1 to 0 rof=1
256 const auto& range = view.getOverlap(1, 0, 1);
257 BOOST_CHECK_EQUAL(range.getEntries(), 2);
258 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
259 }
260 { // from 1 to 2 rof=2
261 const auto& range = view.getOverlap(1, 2, 2);
262 BOOST_CHECK_EQUAL(range.getEntries(), 2);
263 BOOST_CHECK_EQUAL(range.getFirstEntry(), 4);
264 }
265 { // from 1 to 0 rof=2
266 const auto& range = view.getOverlap(1, 0, 2);
267 BOOST_CHECK_EQUAL(range.getEntries(), 1);
268 BOOST_CHECK_EQUAL(range.getFirstEntry(), 1);
269 }
270 { // from 2 to 1 rof=0
271 const auto& range = view.getOverlap(2, 1, 0);
272 BOOST_CHECK_EQUAL(range.getEntries(), 1);
273 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
274 }
275 { // from 2 to 1 rof=1
276 const auto& range = view.getOverlap(2, 1, 1);
277 BOOST_CHECK_EQUAL(range.getEntries(), 1);
278 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
279 }
280 { // from 2 to 1 rof=2
281 const auto& range = view.getOverlap(2, 1, 2);
282 BOOST_CHECK_EQUAL(range.getEntries(), 1);
283 BOOST_CHECK_EQUAL(range.getFirstEntry(), 1);
284 }
285 { // from 2 to 1 rof=3
286 const auto& range = view.getOverlap(2, 1, 3);
287 BOOST_CHECK_EQUAL(range.getEntries(), 1);
288 BOOST_CHECK_EQUAL(range.getFirstEntry(), 1);
289 }
290 { // from 2 to 1 rof=4
291 const auto& range = view.getOverlap(2, 1, 4);
292 BOOST_CHECK_EQUAL(range.getEntries(), 1);
293 BOOST_CHECK_EQUAL(range.getFirstEntry(), 2);
294 }
295 { // from 2 to 1 rof=5
296 const auto& range = view.getOverlap(2, 1, 5);
297 BOOST_CHECK_EQUAL(range.getEntries(), 1);
298 BOOST_CHECK_EQUAL(range.getFirstEntry(), 2);
299 }
300 { // from 2 to 0 rof=0
301 const auto& range = view.getOverlap(2, 0, 0);
302 BOOST_CHECK_EQUAL(range.getEntries(), 1);
303 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
304 }
305 { // from 2 to 0 rof=1
306 const auto& range = view.getOverlap(2, 0, 1);
307 BOOST_CHECK_EQUAL(range.getEntries(), 1);
308 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
309 }
310 { // from 2 to 0 rof=2
311 const auto& range = view.getOverlap(2, 0, 2);
312 BOOST_CHECK_EQUAL(range.getEntries(), 1);
313 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
314 }
315 { // from 2 to 0 rof=3
316 const auto& range = view.getOverlap(2, 0, 3);
317 BOOST_CHECK_EQUAL(range.getEntries(), 1);
318 BOOST_CHECK_EQUAL(range.getFirstEntry(), 1);
319 }
320 { // from 2 to 0 rof=4
321 const auto& range = view.getOverlap(2, 0, 4);
322 BOOST_CHECK_EQUAL(range.getEntries(), 1);
323 BOOST_CHECK_EQUAL(range.getFirstEntry(), 1);
324 }
325 { // from 2 to 0 rof=5
326 const auto& range = view.getOverlap(2, 0, 5);
327 BOOST_CHECK_EQUAL(range.getEntries(), 1);
328 BOOST_CHECK_EQUAL(range.getFirstEntry(), 1);
329 }
330}
331
332BOOST_AUTO_TEST_CASE(rofoverlap_staggered_alllayers_delay_delta)
333{
334 // test staggered layers with ROF delay
336 table.defineLayer(0, 2, 3, 0, 0, 0);
337 table.defineLayer(1, 3, 2, 1, 0, 0);
338 table.defineLayer(2, 6, 1, 0, 0, 1);
339 table.init();
340 const auto view = table.getView();
341
342 // verify overlap range
343 { // from 0 to 1 rof=0
344 const auto& range = view.getOverlap(0, 1, 0);
345 BOOST_CHECK_EQUAL(range.getEntries(), 1);
346 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
347 }
348 { // from 0 to 2 rof=0
349 const auto& range = view.getOverlap(0, 2, 0);
350 BOOST_CHECK_EQUAL(range.getEntries(), 4);
351 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
352 }
353 { // from 0 to 1 rof=1
354 const auto& range = view.getOverlap(0, 1, 1);
355 BOOST_CHECK_EQUAL(range.getEntries(), 2);
356 BOOST_CHECK_EQUAL(range.getFirstEntry(), 1);
357 }
358 { // from 0 to 2 rof=1
359 const auto& range = view.getOverlap(0, 2, 1);
360 BOOST_CHECK_EQUAL(range.getEntries(), 4);
361 BOOST_CHECK_EQUAL(range.getFirstEntry(), 2);
362 }
363 { // from 1 to 2 rof=0
364 const auto& range = view.getOverlap(1, 2, 0);
365 BOOST_CHECK_EQUAL(range.getEntries(), 4);
366 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
367 }
368 { // from 1 to 0 rof=0
369 const auto& range = view.getOverlap(1, 0, 0);
370 BOOST_CHECK_EQUAL(range.getEntries(), 1);
371 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
372 }
373 { // from 1 to 2 rof=1
374 const auto& range = view.getOverlap(1, 2, 1);
375 BOOST_CHECK_EQUAL(range.getEntries(), 4);
376 BOOST_CHECK_EQUAL(range.getFirstEntry(), 2);
377 }
378 { // from 1 to 0 rof=1
379 const auto& range = view.getOverlap(1, 0, 1);
380 BOOST_CHECK_EQUAL(range.getEntries(), 1);
381 BOOST_CHECK_EQUAL(range.getFirstEntry(), 1);
382 }
383 { // from 1 to 2 rof=2
384 const auto& range = view.getOverlap(1, 2, 2);
385 BOOST_CHECK_EQUAL(range.getEntries(), 2);
386 BOOST_CHECK_EQUAL(range.getFirstEntry(), 4);
387 }
388 { // from 1 to 0 rof=2
389 const auto& range = view.getOverlap(1, 0, 2);
390 BOOST_CHECK_EQUAL(range.getEntries(), 1);
391 BOOST_CHECK_EQUAL(range.getFirstEntry(), 1);
392 }
393 { // from 2 to 1 rof=0
394 const auto& range = view.getOverlap(2, 1, 0);
395 BOOST_CHECK_EQUAL(range.getEntries(), 1);
396 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
397 }
398 { // from 2 to 1 rof=1
399 const auto& range = view.getOverlap(2, 1, 1);
400 BOOST_CHECK_EQUAL(range.getEntries(), 1);
401 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
402 }
403 { // from 2 to 1 rof=2
404 const auto& range = view.getOverlap(2, 1, 2);
405 BOOST_CHECK_EQUAL(range.getEntries(), 2);
406 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
407 }
408 { // from 2 to 1 rof=3
409 const auto& range = view.getOverlap(2, 1, 3);
410 BOOST_CHECK_EQUAL(range.getEntries(), 2);
411 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
412 }
413 { // from 2 to 1 rof=4
414 const auto& range = view.getOverlap(2, 1, 4);
415 BOOST_CHECK_EQUAL(range.getEntries(), 2);
416 BOOST_CHECK_EQUAL(range.getFirstEntry(), 1);
417 }
418 { // from 2 to 1 rof=5
419 const auto& range = view.getOverlap(2, 1, 5);
420 BOOST_CHECK_EQUAL(range.getEntries(), 2);
421 BOOST_CHECK_EQUAL(range.getFirstEntry(), 1);
422 }
423 { // from 2 to 0 rof=0
424 const auto& range = view.getOverlap(2, 0, 0);
425 BOOST_CHECK_EQUAL(range.getEntries(), 1);
426 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
427 }
428 { // from 2 to 0 rof=1
429 const auto& range = view.getOverlap(2, 0, 1);
430 BOOST_CHECK_EQUAL(range.getEntries(), 1);
431 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
432 }
433 { // from 2 to 0 rof=2
434 const auto& range = view.getOverlap(2, 0, 2);
435 BOOST_CHECK_EQUAL(range.getEntries(), 2);
436 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
437 }
438 { // from 2 to 0 rof=3
439 const auto& range = view.getOverlap(2, 0, 3);
440 BOOST_CHECK_EQUAL(range.getEntries(), 2);
441 BOOST_CHECK_EQUAL(range.getFirstEntry(), 0);
442 }
443 { // from 2 to 0 rof=4
444 const auto& range = view.getOverlap(2, 0, 4);
445 BOOST_CHECK_EQUAL(range.getEntries(), 1);
446 BOOST_CHECK_EQUAL(range.getFirstEntry(), 1);
447 }
448 { // from 2 to 0 rof=5
449 const auto& range = view.getOverlap(2, 0, 5);
450 BOOST_CHECK_EQUAL(range.getEntries(), 1);
451 BOOST_CHECK_EQUAL(range.getFirstEntry(), 1);
452 }
453}
454
455BOOST_AUTO_TEST_CASE(rofoverlap_with_delta)
456{
457 // test with ROF delta for compatibility window
459 table.defineLayer(0, 8, 600, 0, 0, 100); // +/- 100 BC delta
460 table.defineLayer(1, 8, 600, 0, 0, 100);
461 table.init();
462 const auto view = table.getView();
463
464 // with delta, ROFs should have wider compatibility
465 for (int rof{0}; rof < 8; ++rof) {
466 auto overlap = view.getOverlap(0, 1, rof);
467 if (rof == 0 || rof == 7) {
468 // edges should see only two
469 BOOST_CHECK_EQUAL(overlap.getEntries(), 2);
470 } else {
471 BOOST_CHECK_EQUAL(overlap.getEntries(), 3);
472 }
473 }
474}
475
476BOOST_AUTO_TEST_CASE(rofoverlap_same_layer)
477{
478 // test same layer compatibility
480 table.defineLayer(0, 10, 500, 0, 0, 0);
481 table.init();
482 const auto view = table.getView();
483
484 // same ROF in same layer should be compatible
485 BOOST_CHECK(view.doROFsOverlap(0, 5, 0, 5));
486 // different ROFs in same layer should not be compatible
487 BOOST_CHECK(!view.doROFsOverlap(0, 5, 0, 6));
488}
489
490BOOST_AUTO_TEST_CASE(rofoverlap_timestamp_basic)
491{
493 table.defineLayer(0, 4, 100, 0, 0, 0);
494 table.defineLayer(1, 4, 100, 0, 0, 0);
495 table.defineLayer(2, 8, 50, 0, 0, 0);
496 table.defineLayer(3, 7, 50, 50, 0, 0);
497 table.init();
498 const auto& view = table.getView();
499
500 const auto t01 = view.getTimeStamp(0, 3, 1, 3);
501 BOOST_CHECK_EQUAL(t01.getTimeStamp(), 300);
502 BOOST_CHECK_EQUAL(t01.getTimeStampError(), 100);
503
504 const auto t02 = view.getTimeStamp(0, 1, 2, 3);
505 BOOST_CHECK_EQUAL(t02.getTimeStamp(), 150);
506 BOOST_CHECK_EQUAL(t02.getTimeStampError(), 50);
507
508 const auto t03 = view.getTimeStamp(0, 0, 3, 0);
509 BOOST_CHECK_EQUAL(t03.getTimeStamp(), 50);
510 BOOST_CHECK_EQUAL(t03.getTimeStampError(), 50);
511
512 const auto t23 = view.getTimeStamp(2, 2, 3, 1);
513 BOOST_CHECK_EQUAL(t23.getTimeStamp(), 100);
514 BOOST_CHECK_EQUAL(t23.getTimeStampError(), 50);
515}
516
517BOOST_AUTO_TEST_CASE(rofoverlap_timestamp_complex)
518{
520 table.defineLayer(0, 4, 100, 0, 0, 0);
521 table.defineLayer(1, 4, 100, 0, 0, 10);
522 table.defineLayer(2, 8, 50, 0, 0, 0);
523 table.defineLayer(3, 7, 50, 50, 0, 10);
524 table.init();
525 const auto& view = table.getView();
526 view.printMapping(0, 1);
527
528 const auto t010 = view.getTimeStamp(0, 3, 1, 3);
529 BOOST_CHECK_EQUAL(t010.getTimeStamp(), 300);
530 BOOST_CHECK_EQUAL(t010.getTimeStampError(), 100);
531
532 const auto t011 = view.getTimeStamp(0, 2, 1, 3);
533 BOOST_CHECK_EQUAL(t011.getTimeStamp(), 290);
534 BOOST_CHECK_EQUAL(t011.getTimeStampError(), 10);
535
536 const auto t02 = view.getTimeStamp(0, 1, 2, 3);
537 BOOST_CHECK_EQUAL(t02.getTimeStamp(), 150);
538 BOOST_CHECK_EQUAL(t02.getTimeStampError(), 50);
539
540 const auto t03 = view.getTimeStamp(0, 0, 3, 0);
541 BOOST_CHECK_EQUAL(t03.getTimeStamp(), 40);
542 BOOST_CHECK_EQUAL(t03.getTimeStampError(), 60);
543}
544
545// ROFVertexLookupTable
546BOOST_AUTO_TEST_CASE(rofvertex_basic)
547{
549 table.defineLayer(0, 6, 594, 0, 0, 0);
550 table.init();
551 std::vector<o2::its::Vertex> vertices;
552 o2::its::Vertex vert0;
553 vert0.getTimeStamp().setTimeStamp(594);
554 vert0.getTimeStamp().setTimeStampError(594);
555 vertices.push_back(vert0);
556 o2::its::Vertex vert1;
557 vert1.getTimeStamp().setTimeStamp(2375);
558 vert1.getTimeStamp().setTimeStampError(594);
559 vertices.push_back(vert1);
560 table.update(vertices.data(), vertices.size());
561 const auto view = table.getView();
562 view.printAll();
563}
564
565BOOST_AUTO_TEST_CASE(rofvertex_init_with_vertices)
566{
568 table.defineLayer(0, 10, 500, 0, 0, 0);
569 table.defineLayer(1, 10, 500, 0, 0, 0);
570
571 // create vertices at different timestamps
572 std::vector<o2::its::Vertex> vertices;
573 for (int i = 0; i < 5; ++i) {
575 v.getTimeStamp().setTimeStamp(i * 1000);
576 v.getTimeStamp().setTimeStampError(500);
577 vertices.push_back(v);
578 }
579
580 table.init(vertices.data(), vertices.size());
581 const auto view = table.getView();
582
583 // verify vertices can be queried
584 const auto& vtxRange = view.getVertices(0, 0);
585 BOOST_CHECK_EQUAL(vtxRange.getEntries(), 1);
586}
587
588BOOST_AUTO_TEST_CASE(rofvertex_max_vertices)
589{
591 table.defineLayer(0, 3, 1000, 0, 0, 500);
592
593 std::vector<o2::its::Vertex> vertices;
594 for (int i = 0; i < 10; ++i) {
596 v.getTimeStamp().setTimeStamp(500 + i * 100);
597 v.getTimeStamp().setTimeStampError(50);
598 vertices.push_back(v);
599 }
600
601 table.init(vertices.data(), vertices.size());
602 const auto view = table.getView();
603
604 int32_t maxVtx = view.getMaxVerticesPerROF();
605 BOOST_CHECK(maxVtx >= 0);
606}
607
608BOOST_AUTO_TEST_CASE(rofvertex_vertex_more)
609{
611 table.defineLayer(0, 4, 100, 0, 0, 0);
612 table.defineLayer(1, 4, 100, 0, 0, 10);
613 table.defineLayer(2, 8, 50, 0, 0, 0);
614 table.defineLayer(3, 7, 50, 50, 0, 10);
615 table.init();
616
617 std::vector<o2::its::Vertex> vertices;
618 { // vertex 0 overlapping
619 auto& v = vertices.emplace_back();
620 v.getTimeStamp().setTimeStamp(100);
621 v.getTimeStamp().setTimeStampError(10);
622 }
623 { // vertex 1
624 auto& v = vertices.emplace_back();
625 v.getTimeStamp().setTimeStamp(100);
626 v.getTimeStamp().setTimeStampError(0);
627 }
628 { // vertex 2 spanning multiple rofs
629 auto& v = vertices.emplace_back();
630 v.getTimeStamp().setTimeStamp(100);
631 v.getTimeStamp().setTimeStampError(60);
632 }
633
634 // sorty vertices by lower bound
635 std::sort(vertices.begin(), vertices.end(), [](const auto& pvA, const auto& pvB) {
636 const auto& a = pvA.getTimeStamp();
637 const auto& b = pvB.getTimeStamp();
638 const auto aLower = a.getTimeStamp() - a.getTimeStampError();
639 const auto bLower = b.getTimeStamp() - b.getTimeStampError();
640 if (aLower != bLower) {
641 return aLower < bLower;
642 }
643 return pvA.getNContributors() > pvB.getNContributors();
644 });
645
646 table.update(vertices.data(), vertices.size());
647 const auto& view = table.getView();
648
649 const auto& v0 = vertices[0]; // 100+60
650 const auto& v1 = vertices[1]; // 100+10
651 const auto& v2 = vertices[2]; // 100+0
652
653 // check for v0
654 // layer 0
655 BOOST_CHECK(!view.isVertexCompatible(0, 0, v0));
656 BOOST_CHECK(view.isVertexCompatible(0, 1, v0));
657 BOOST_CHECK(!view.isVertexCompatible(0, 2, v0));
658 BOOST_CHECK(!view.isVertexCompatible(0, 3, v0));
659 // layer 1
660 BOOST_CHECK(view.isVertexCompatible(1, 0, v0));
661 BOOST_CHECK(view.isVertexCompatible(1, 1, v0));
662 BOOST_CHECK(!view.isVertexCompatible(1, 2, v0));
663 BOOST_CHECK(!view.isVertexCompatible(1, 3, v0));
664 // layer 2
665 BOOST_CHECK(!view.isVertexCompatible(2, 0, v0));
666 BOOST_CHECK(!view.isVertexCompatible(2, 1, v0));
667 BOOST_CHECK(view.isVertexCompatible(2, 2, v0));
668 BOOST_CHECK(view.isVertexCompatible(2, 3, v0));
669 BOOST_CHECK(!view.isVertexCompatible(2, 4, v0));
670 BOOST_CHECK(!view.isVertexCompatible(2, 5, v0));
671 BOOST_CHECK(!view.isVertexCompatible(2, 6, v0));
672 BOOST_CHECK(!view.isVertexCompatible(2, 7, v0));
673 // layer 3
674 BOOST_CHECK(view.isVertexCompatible(3, 0, v0));
675 BOOST_CHECK(view.isVertexCompatible(3, 1, v0));
676 BOOST_CHECK(view.isVertexCompatible(3, 2, v0));
677 BOOST_CHECK(!view.isVertexCompatible(3, 3, v0));
678 BOOST_CHECK(!view.isVertexCompatible(3, 4, v0));
679 BOOST_CHECK(!view.isVertexCompatible(3, 5, v0));
680 BOOST_CHECK(!view.isVertexCompatible(3, 6, v0));
681
682 // check for v1
683 // layer 0
684 BOOST_CHECK(!view.isVertexCompatible(0, 0, v1));
685 BOOST_CHECK(view.isVertexCompatible(0, 1, v1));
686 BOOST_CHECK(!view.isVertexCompatible(0, 2, v1));
687 BOOST_CHECK(!view.isVertexCompatible(0, 3, v1));
688 // layer 1
689 BOOST_CHECK(view.isVertexCompatible(1, 0, v1));
690 BOOST_CHECK(view.isVertexCompatible(1, 1, v1));
691 BOOST_CHECK(!view.isVertexCompatible(1, 2, v1));
692 BOOST_CHECK(!view.isVertexCompatible(1, 3, v1));
693 // layer 2
694 BOOST_CHECK(!view.isVertexCompatible(2, 0, v1));
695 BOOST_CHECK(!view.isVertexCompatible(2, 1, v1));
696 BOOST_CHECK(view.isVertexCompatible(2, 2, v1));
697 BOOST_CHECK(!view.isVertexCompatible(2, 3, v1));
698 BOOST_CHECK(!view.isVertexCompatible(2, 4, v1));
699 BOOST_CHECK(!view.isVertexCompatible(2, 5, v1));
700 BOOST_CHECK(!view.isVertexCompatible(2, 6, v1));
701 BOOST_CHECK(!view.isVertexCompatible(2, 7, v1));
702 // layer 3
703 BOOST_CHECK(view.isVertexCompatible(3, 0, v1));
704 BOOST_CHECK(view.isVertexCompatible(3, 1, v1));
705 BOOST_CHECK(!view.isVertexCompatible(3, 2, v1));
706 BOOST_CHECK(!view.isVertexCompatible(3, 3, v1));
707 BOOST_CHECK(!view.isVertexCompatible(3, 4, v1));
708 BOOST_CHECK(!view.isVertexCompatible(3, 5, v1));
709 BOOST_CHECK(!view.isVertexCompatible(3, 6, v1));
710
711 // check for v2
712 // layer 0
713 BOOST_CHECK(!view.isVertexCompatible(0, 0, v2));
714 BOOST_CHECK(view.isVertexCompatible(0, 1, v2));
715 BOOST_CHECK(!view.isVertexCompatible(0, 2, v2));
716 BOOST_CHECK(!view.isVertexCompatible(0, 3, v2));
717 // layer 1
718 BOOST_CHECK(view.isVertexCompatible(1, 0, v2));
719 BOOST_CHECK(view.isVertexCompatible(1, 1, v2));
720 BOOST_CHECK(!view.isVertexCompatible(1, 2, v2));
721 BOOST_CHECK(!view.isVertexCompatible(1, 3, v2));
722 // layer 2
723 BOOST_CHECK(!view.isVertexCompatible(2, 0, v2));
724 BOOST_CHECK(!view.isVertexCompatible(2, 1, v2));
725 BOOST_CHECK(view.isVertexCompatible(2, 2, v2));
726 BOOST_CHECK(!view.isVertexCompatible(2, 3, v2));
727 BOOST_CHECK(!view.isVertexCompatible(2, 4, v2));
728 BOOST_CHECK(!view.isVertexCompatible(2, 5, v2));
729 BOOST_CHECK(!view.isVertexCompatible(2, 6, v2));
730 BOOST_CHECK(!view.isVertexCompatible(2, 7, v2));
731 // layer 3
732 BOOST_CHECK(view.isVertexCompatible(3, 0, v2));
733 BOOST_CHECK(view.isVertexCompatible(3, 1, v2));
734 BOOST_CHECK(!view.isVertexCompatible(3, 2, v2));
735 BOOST_CHECK(!view.isVertexCompatible(3, 3, v2));
736 BOOST_CHECK(!view.isVertexCompatible(3, 4, v2));
737 BOOST_CHECK(!view.isVertexCompatible(3, 5, v2));
738 BOOST_CHECK(!view.isVertexCompatible(3, 6, v2));
739}
740
741BOOST_AUTO_TEST_CASE(rofvertex_exact_compatibility)
742{
744 table.defineLayer(0, 4, 100, 0, 0, 0);
745 table.defineLayer(1, 4, 100, 0, 0, 10);
746 table.defineLayer(2, 8, 50, 0, 0, 0);
747 table.defineLayer(3, 7, 50, 50, 0, 10);
748 table.init();
749
750 // sorted by lower bound timestamp
751 std::vector<o2::its::Vertex> vertices;
752 { // idx 0: [40, 160] - wide span
753 auto& v = vertices.emplace_back();
754 v.getTimeStamp().setTimeStamp(100);
755 v.getTimeStamp().setTimeStampError(60);
756 }
757 { // idx 1: [90, 110]
758 auto& v = vertices.emplace_back();
759 v.getTimeStamp().setTimeStamp(100);
760 v.getTimeStamp().setTimeStampError(10);
761 }
762 { // idx 2: [100, 100] - zero width, false-positive prone
763 auto& v = vertices.emplace_back();
764 v.getTimeStamp().setTimeStamp(100);
765 v.getTimeStamp().setTimeStampError(0);
766 }
767
768 table.update(vertices.data(), vertices.size());
769 const auto& view = table.getView();
770
771 // Layer 0 ROF 0: [0, 100)
772 BOOST_CHECK(!view.isVertexCompatible(0, 0, vertices[0]));
773 BOOST_CHECK(!view.isVertexCompatible(0, 0, vertices[1]));
774 BOOST_CHECK(!view.isVertexCompatible(0, 0, vertices[2]));
775
776 // Layer 0 ROF 1: [100, 200) - range includes idx 2 as false positive
777 {
778 const auto& range = view.getVertices(0, 1);
779 BOOST_CHECK_EQUAL(range.getEntries(), 3); // superset
780
781 size_t exactCount = 0;
782 for (size_t i = range.getFirstEntry(); i < range.getEntriesBound(); ++i) {
783 if (view.isVertexCompatible(0, 1, vertices[i])) {
784 ++exactCount;
785 }
786 }
787 // BOOST_CHECK_EQUAL(exactCount, 2); // idx 2 filtered out
788 }
789
790 // Layer 0 ROF 2: [200, 300) - nothing overlaps
791 BOOST_CHECK(!view.isVertexCompatible(0, 2, vertices[0]));
792 BOOST_CHECK(!view.isVertexCompatible(0, 2, vertices[1]));
793 BOOST_CHECK(!view.isVertexCompatible(0, 2, vertices[2]));
794
795 // Layer 2 ROF 0: [0, 50) - only idx 0
796 BOOST_CHECK(!view.isVertexCompatible(2, 0, vertices[0]));
797 BOOST_CHECK(!view.isVertexCompatible(2, 0, vertices[1]));
798
799 // Layer 2 ROF 1: [50, 100) - idx 0 and 1
800 BOOST_CHECK(!view.isVertexCompatible(2, 1, vertices[0]));
801 BOOST_CHECK(!view.isVertexCompatible(2, 1, vertices[1]));
802 BOOST_CHECK(!view.isVertexCompatible(2, 1, vertices[2]));
803
804 // Layer 2 ROF 3: [150, 200) - only idx 0
805 BOOST_CHECK(view.isVertexCompatible(2, 3, vertices[0]));
806 BOOST_CHECK(!view.isVertexCompatible(2, 3, vertices[1]));
807
808 // Layer 3 ROF 0: [40, 110) - all three genuine
809 BOOST_CHECK(view.isVertexCompatible(3, 0, vertices[0]));
810 BOOST_CHECK(view.isVertexCompatible(3, 0, vertices[1]));
811 BOOST_CHECK(view.isVertexCompatible(3, 0, vertices[2]));
812
813 // Layer 3 ROF 2: [140, 210) - only idx 0
814 BOOST_CHECK(view.isVertexCompatible(3, 2, vertices[0]));
815 BOOST_CHECK(!view.isVertexCompatible(3, 2, vertices[1]));
816 BOOST_CHECK(!view.isVertexCompatible(3, 2, vertices[2]));
817}
int32_t i
const GLdouble * v
Definition glcorearb.h:832
GLenum GLint * range
Definition glcorearb.h:1899
GLfloat v0
Definition glcorearb.h:811
GLfloat GLfloat v1
Definition glcorearb.h:812
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
GLint GLuint mask
Definition glcorearb.h:291
GLfloat GLfloat GLfloat v2
Definition glcorearb.h:813
BOOST_AUTO_TEST_CASE(layertiming_basic)
-----— Tests -----—
BOOST_CHECK(tree)
BOOST_CHECK_EQUAL(triggersD.size(), triggers.size())