Project
Loading...
Searching...
No Matches
test_GroupSlicer.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#include "Framework/ASoA.h"
17#include <arrow/util/config.h>
18
19#include <catch_amalgamated.hpp>
20
21using namespace o2;
22using namespace o2::framework;
23
24namespace o2::aod
25{
26namespace test
27{
30DECLARE_SOA_COLUMN(Bar, bar, float);
31DECLARE_SOA_COLUMN(EventProperty, eventProperty, float);
32} // namespace test
33DECLARE_SOA_TABLE(Events, "AOD", "EVTS",
35 test::ID,
36 test::EventProperty,
37 test::Foo,
38 test::Bar);
39
40using Event = Events::iterator;
41
42namespace test
43{
45DECLARE_SOA_COLUMN(X, x, float);
46DECLARE_SOA_COLUMN(Y, y, float);
47DECLARE_SOA_COLUMN(Z, z, float);
48} // namespace test
49
50namespace unsorted
51{
53}
54
55DECLARE_SOA_TABLE(TrksX, "AOD", "TRKSX",
56 test::EventId,
57 test::X);
58DECLARE_SOA_TABLE(TrksY, "AOD", "TRKSY",
59 test::EventId,
60 test::Y);
61DECLARE_SOA_TABLE(TrksZ, "AOD", "TRKSZ",
62 test::EventId,
63 test::Z);
64DECLARE_SOA_TABLE(TrksU, "AOD", "TRKSU",
65 test::X,
66 test::Y,
67 test::Z);
68
69DECLARE_SOA_TABLE(TrksXU, "AOD", "TRKSXU",
70 unsorted::EventId,
71 test::X);
72DECLARE_SOA_TABLE(TrksYU, "AOD", "TRKSYU",
73 unsorted::EventId,
74 test::Y);
75DECLARE_SOA_TABLE(TrksZU, "AOD", "TRKSZU",
76 unsorted::EventId,
77 test::Z);
78
79namespace test
80{
81DECLARE_SOA_COLUMN(Arr, arr, float[3]);
82DECLARE_SOA_COLUMN(Boo, boo, bool);
83DECLARE_SOA_COLUMN(Lst, lst, std::vector<double>);
84} // namespace test
85
86DECLARE_SOA_TABLE(EventExtra, "AOD", "EVTSXTRA", test::Arr, test::Boo, test::Lst);
87
88} // namespace o2::aod
89TEST_CASE("RelatedByIndex")
90{
92 CHECK(soa::relatedByIndex<aod::Collision, Trks>() == true);
93 CHECK(soa::relatedByIndex<aod::Collision, aod::Tracks>() == true);
94}
95
96TEST_CASE("GroupSlicerOneAssociated")
97{
98 TableBuilder builderE;
99 auto evtsWriter = builderE.cursor<aod::Events>();
100 for (auto i = 0; i < 20; ++i) {
101 evtsWriter(0, i, 0.5f * i, 2.f * i, 3.f * i);
102 }
103 auto evtTable = builderE.finalize();
104
105 TableBuilder builderT;
106 auto trksWriter = builderT.cursor<aod::TrksX>();
107 for (auto i = 0; i < 20; ++i) {
108 for (auto j = 0.f; j < 5; j += 0.5f) {
109 trksWriter(0, i, 0.5f * j);
110 }
111 }
112 auto trkTable = builderT.finalize();
113 aod::Events e{evtTable};
114 aod::TrksX t{trkTable};
115 REQUIRE(e.size() == 20);
116 REQUIRE(t.size() == 10 * 20);
117
118 auto tt = std::make_tuple(t);
119 std::string key = "fIndex" + o2::framework::cutString(soa::getLabelFromType<aod::Events>());
120 ArrowTableSlicingCache slices({{soa::getLabelFromType<aod::TrksX>(), soa::getMatcherFromTypeForKey<aod::TrksX>(key), key}});
121 auto s = slices.updateCacheEntry(0, trkTable);
122 o2::framework::GroupSlicer g(e, tt, slices);
123
124 auto count = 0;
125 for (auto& slice : g) {
126 auto as = slice.associatedTables();
127 auto gg = slice.groupingElement();
128 REQUIRE(gg.globalIndex() == count);
129 auto trks = std::get<aod::TrksX>(as);
130 REQUIRE(trks.size() == 10);
131 for (auto& trk : trks) {
132 REQUIRE(trk.eventId() == count);
133 }
134 ++count;
135 }
136}
137
138TEST_CASE("GroupSlicerSeveralAssociated")
139{
140 TableBuilder builderE;
141 auto evtsWriter = builderE.cursor<aod::Events>();
142 for (auto i = 0; i < 20; ++i) {
143 evtsWriter(0, i, 0.5f * i, 2.f * i, 3.f * i);
144 }
145 auto evtTable = builderE.finalize();
146
147 TableBuilder builderTX;
148 auto trksWriterX = builderTX.cursor<aod::TrksX>();
149 TableBuilder builderTY;
150 auto trksWriterY = builderTY.cursor<aod::TrksY>();
151 TableBuilder builderTZ;
152 auto trksWriterZ = builderTZ.cursor<aod::TrksZ>();
153
154 TableBuilder builderTXYZ;
155 auto trksWriterXYZ = builderTXYZ.cursor<aod::TrksU>();
156
157 for (auto i = 0; i < 20; ++i) {
158 for (auto j = 0.f; j < 5; j += 0.5f) {
159 trksWriterX(0, i, 0.5f * j);
160 }
161 for (auto j = 0.f; j < 10; j += 0.5f) {
162 trksWriterY(0, i, 0.5f * j);
163 }
164 for (auto j = 0.f; j < 15; j += 0.5f) {
165 trksWriterZ(0, i, 0.5f * j);
166 }
167
168 for (auto j = 0.f; j < 5; j += 0.5f) {
169 trksWriterXYZ(0, 0.5f * j, 2.f * j, 2.5f * j);
170 }
171 }
172 auto trkTableX = builderTX.finalize();
173 auto trkTableY = builderTY.finalize();
174 auto trkTableZ = builderTZ.finalize();
175
176 auto trkTableXYZ = builderTXYZ.finalize();
177
178 aod::Events e{evtTable};
179 aod::TrksX tx{trkTableX};
180 aod::TrksY ty{trkTableY};
181 aod::TrksZ tz{trkTableZ};
182
183 aod::TrksU tu{trkTableXYZ};
184
185 REQUIRE(e.size() == 20);
186 REQUIRE(tx.size() == 10 * 20);
187 REQUIRE(ty.size() == 20 * 20);
188 REQUIRE(tz.size() == 30 * 20);
189
190 REQUIRE(tu.size() == 10 * 20);
191
192 auto tt = std::make_tuple(tx, ty, tz, tu);
193 auto key = "fIndex" + o2::framework::cutString(soa::getLabelFromType<aod::Events>());
194 ArrowTableSlicingCache slices({{soa::getLabelFromType<aod::TrksX>(), soa::getMatcherFromTypeForKey<aod::TrksX>(key), key},
195 {soa::getLabelFromType<aod::TrksY>(), soa::getMatcherFromTypeForKey<aod::TrksY>(key), key},
196 {soa::getLabelFromType<aod::TrksZ>(), soa::getMatcherFromTypeForKey<aod::TrksZ>(key), key}});
197 auto s = slices.updateCacheEntry(0, {trkTableX});
198 s = slices.updateCacheEntry(1, {trkTableY});
199 s = slices.updateCacheEntry(2, {trkTableZ});
200 o2::framework::GroupSlicer g(e, tt, slices);
201
202 auto count = 0;
203 for (auto& slice : g) {
204 auto as = slice.associatedTables();
205 auto gg = slice.groupingElement();
206 REQUIRE(gg.globalIndex() == count);
207 auto trksx = std::get<aod::TrksX>(as);
208 auto trksy = std::get<aod::TrksY>(as);
209 auto trksz = std::get<aod::TrksZ>(as);
210
211 auto trksu = std::get<aod::TrksU>(as);
212
213 REQUIRE(trksx.size() == 10);
214 REQUIRE(trksy.size() == 20);
215 REQUIRE(trksz.size() == 30);
216
217 REQUIRE(trksu.size() == 10 * 20);
218
219 for (auto& trk : trksx) {
220 REQUIRE(trk.eventId() == count);
221 }
222 for (auto& trk : trksy) {
223 REQUIRE(trk.eventId() == count);
224 }
225 for (auto& trk : trksz) {
226 REQUIRE(trk.eventId() == count);
227 }
228
229 ++count;
230 }
231}
232
233TEST_CASE("GroupSlicerMismatchedGroups")
234{
235 TableBuilder builderE;
236 auto evtsWriter = builderE.cursor<aod::Events>();
237 for (auto i = 0; i < 20; ++i) {
238 evtsWriter(0, i, 0.5f * i, 2.f * i, 3.f * i);
239 }
240 auto evtTable = builderE.finalize();
241
242 TableBuilder builderT;
243 auto trksWriter = builderT.cursor<aod::TrksX>();
244 for (auto i = 0; i < 20; ++i) {
245 if (i == 3 || i == 10 || i == 12 || i == 16 || i == 19) {
246 continue;
247 }
248 for (auto j = 0; j < 10; ++j) {
249 trksWriter(0, i, 0.5f * (j / 2.));
250 }
251 }
252 auto trkTable = builderT.finalize();
253 aod::Events e{evtTable};
254 aod::TrksX t{trkTable};
255 REQUIRE(e.size() == 20);
256 REQUIRE(t.size() == 10 * (20 - 5));
257
258 auto tt = std::make_tuple(t);
259 std::string key = "fIndex" + o2::framework::cutString(soa::getLabelFromType<aod::Events>());
260 ArrowTableSlicingCache slices({{soa::getLabelFromType<aod::TrksX>(), soa::getMatcherFromTypeForKey<aod::TrksX>(key), key}});
261 auto s = slices.updateCacheEntry(0, trkTable);
262 o2::framework::GroupSlicer g(e, tt, slices);
263
264 for (auto& slice : g) {
265 auto as = slice.associatedTables();
266 auto gg = slice.groupingElement();
267 REQUIRE(gg.globalIndex() == (int64_t)slice.position);
268 auto trks = std::get<aod::TrksX>(as);
269 if (slice.position == 3 || slice.position == 10 || slice.position == 12 || slice.position == 16 || slice.position == 19) {
270 REQUIRE(trks.size() == 0);
271 } else {
272 REQUIRE(trks.size() == 10);
273 }
274 for (auto& trk : trks) {
275 REQUIRE(trk.eventId() == (int64_t)slice.position);
276 }
277 }
278}
279
280TEST_CASE("GroupSlicerMismatchedUnassignedGroups")
281{
282 TableBuilder builderE;
283 auto evtsWriter = builderE.cursor<aod::Events>();
284 for (auto i = 0; i < 20; ++i) {
285 evtsWriter(0, i, 0.5f * i, 2.f * i, 3.f * i);
286 }
287 auto evtTable = builderE.finalize();
288
289 int skip = 0;
290
291 TableBuilder builderT;
292 auto trksWriter = builderT.cursor<aod::TrksX>();
293 for (auto i = 0; i < 20; ++i) {
294 if (i == 3 || i == 10 || i == 12 || i == 16 || i == 19) {
295 for (auto iz = 0; iz < 5; ++iz) {
296 trksWriter(0, -1 - skip, 0.123f * iz + 1.654f);
297 }
298 ++skip;
299 continue;
300 }
301 for (auto j = 0; j < 10; ++j) {
302 trksWriter(0, i, 0.5f * (j / 2.));
303 }
304 }
305 for (auto i = 0; i < 5; ++i) {
306 trksWriter(0, -6, 0.123f * i + 1.654f);
307 }
308 auto trkTable = builderT.finalize();
309
310 aod::Events e{evtTable};
311 aod::TrksX t{trkTable};
312 REQUIRE(e.size() == 20);
313 REQUIRE(t.size() == (30 + 10 * (20 - 5)));
314
315 auto tt = std::make_tuple(t);
316 std::string key = "fIndex" + o2::framework::cutString(soa::getLabelFromType<aod::Events>());
317 ArrowTableSlicingCache slices({{soa::getLabelFromType<aod::TrksX>(), soa::getMatcherFromTypeForKey<aod::TrksX>(key), key}});
318 auto s = slices.updateCacheEntry(0, trkTable);
319 o2::framework::GroupSlicer g(e, tt, slices);
320
321 auto count = 0;
322 for (auto& slice : g) {
323 auto as = slice.associatedTables();
324 auto gg = slice.groupingElement();
325 REQUIRE(gg.globalIndex() == count);
326 auto trks = std::get<aod::TrksX>(as);
327 if (count == 3 || count == 10 || count == 12 || count == 16 || count == 19) {
328 REQUIRE(trks.size() == 0);
329 } else {
330 REQUIRE(trks.size() == 10);
331 }
332 for (auto& trk : trks) {
333 REQUIRE(trk.eventId() == count);
334 }
335 ++count;
336 }
337}
338
339TEST_CASE("GroupSlicerMismatchedFilteredGroups")
340{
341 TableBuilder builderE;
342 auto evtsWriter = builderE.cursor<aod::Events>();
343 for (auto i = 0; i < 20; ++i) {
344 evtsWriter(0, i, 0.5f * i, 2.f * i, 3.f * i);
345 }
346 auto evtTable = builderE.finalize();
347
348 TableBuilder builderT;
349 auto trksWriter = builderT.cursor<aod::TrksX>();
350 for (auto i = 0; i < 20; ++i) {
351 if (i == 3 || i == 10 || i == 12 || i == 16) {
352 continue;
353 }
354 for (auto j = 0.f; j < 5; j += 0.5f) {
355 trksWriter(0, i, 0.5f * j);
356 }
357 }
358 auto trkTable = builderT.finalize();
359 using FilteredEvents = soa::Filtered<aod::Events>;
360 soa::SelectionVector rows{2, 4, 10, 9, 15};
361 FilteredEvents e{{evtTable}, {2, 4, 10, 9, 15}};
362 aod::TrksX t{trkTable};
363 REQUIRE(e.size() == 5);
364 REQUIRE(t.size() == 10 * (20 - 4));
365
366 auto tt = std::make_tuple(t);
367 std::string key = "fIndex" + o2::framework::cutString(soa::getLabelFromType<aod::Events>());
368 ArrowTableSlicingCache slices({{soa::getLabelFromType<aod::TrksX>(), soa::getMatcherFromTypeForKey<aod::TrksX>(key), key}});
369 auto s = slices.updateCacheEntry(0, trkTable);
370 o2::framework::GroupSlicer g(e, tt, slices);
371
372 auto count = 0;
373
374 for (auto& slice : g) {
375 auto as = slice.associatedTables();
376 auto gg = slice.groupingElement();
377 REQUIRE(gg.globalIndex() == rows[count]);
378 auto trks = std::get<aod::TrksX>(as);
379 if (rows[count] == 3 || rows[count] == 10 || rows[count] == 12 || rows[count] == 16) {
380 REQUIRE(trks.size() == 0);
381 } else {
382 REQUIRE(trks.size() == 10);
383 }
384 for (auto& trk : trks) {
385 REQUIRE(trk.eventId() == rows[count]);
386 }
387 ++count;
388 }
389}
390
391TEST_CASE("GroupSlicerMismatchedUnsortedFilteredGroups")
392{
393 TableBuilder builderE;
394 auto evtsWriter = builderE.cursor<aod::Events>();
395 for (auto i = 0; i < 20; ++i) {
396 evtsWriter(0, i, 0.5f * i, 2.f * i, 3.f * i);
397 }
398 auto evtTable = builderE.finalize();
399
400 TableBuilder builderT;
401 auto trksWriter = builderT.cursor<aod::TrksXU>();
402 std::vector<int> randomized{10, 2, 1, 0, 15, 3, 6, 4, 14, 5, 7, 9, 8, 19, 11, 13, 17, 12, 18, 19};
403 std::vector<int64_t> sel;
404 sel.resize(10 * (20 - 4));
405 std::iota(sel.begin(), sel.end(), 0);
406 for (auto i : randomized) {
407 if (i == 3 || i == 10 || i == 12 || i == 16) {
408 continue;
409 }
410 for (auto j = 0.f; j < 5; j += 0.5f) {
411 trksWriter(0, i, 0.5f * j);
412 }
413 }
414 auto trkTable = builderT.finalize();
415
416 TableBuilder builderTE;
417 auto trksWriterE = builderTE.cursor<aod::TrksXU>();
418 auto trkTableE = builderTE.finalize();
419
420 using FilteredEvents = soa::Filtered<aod::Events>;
421 soa::SelectionVector rows{2, 4, 10, 9, 15};
422 FilteredEvents e{{evtTable}, {2, 4, 10, 9, 15}};
423 soa::SmallGroups<aod::TrksXU> t{{trkTable}, std::move(sel)};
424
425 REQUIRE(e.size() == 5);
426 REQUIRE(t.size() == 10 * (20 - 4));
427
428 auto tt = std::make_tuple(t);
429 std::string key = "fIndex" + o2::framework::cutString(soa::getLabelFromType<aod::Events>());
430 ArrowTableSlicingCache slices({}, {{soa::getLabelFromType<aod::TrksXU>(), soa::getMatcherFromTypeForKey<aod::TrksXU>(key), key}});
431 auto s = slices.updateCacheEntryUnsorted(0, trkTable);
432 o2::framework::GroupSlicer g(e, tt, slices);
433
434 unsigned int count = 0;
435
436 for (auto& slice : g) {
437 auto as = slice.associatedTables();
438 auto gg = slice.groupingElement();
439 REQUIRE(gg.globalIndex() == rows[count]);
440 auto trks = std::get<soa::SmallGroups<aod::TrksXU>>(as);
441 if (rows[count] == 3 || rows[count] == 10 || rows[count] == 12 || rows[count] == 16) {
442 REQUIRE(trks.size() == 0);
443 } else {
444 REQUIRE(trks.size() == 10);
445 }
446 for (auto& trk : trks) {
447 REQUIRE(trk.eventId() == rows[count]);
448 }
449 ++count;
450 }
451
452 std::vector<int64_t> sele;
453 soa::SmallGroups<aod::TrksXU> te{{trkTableE}, std::move(sele)};
454 auto tte = std::make_tuple(te);
455 o2::framework::GroupSlicer ge(e, tte, slices);
456
457 count = 0;
458 for (auto& slice : ge) {
459 auto as = slice.associatedTables();
460 auto gg = slice.groupingElement();
461 REQUIRE(gg.globalIndex() == rows[count]);
462 auto trks = std::get<soa::SmallGroups<aod::TrksXU>>(as);
463 REQUIRE(trks.size() == 0);
464 ++count;
465 }
466
467 soa::SmallGroupsUnfiltered<aod::TrksXU> tu{{trkTable}, std::vector<int64_t>{}};
468 auto ttu = std::make_tuple(tu);
469 o2::framework::GroupSlicer gu(e, ttu, slices);
470
471 count = 0;
472 for (auto& slice : gu) {
473 auto as = slice.associatedTables();
474 auto gg = slice.groupingElement();
475 REQUIRE(gg.globalIndex() == rows[count]);
476 auto trks = std::get<soa::SmallGroupsUnfiltered<aod::TrksXU>>(as);
477 if (rows[count] == 3 || rows[count] == 10 || rows[count] == 12 || rows[count] == 16) {
478 REQUIRE(trks.size() == 0);
479 } else {
480 REQUIRE(trks.size() == 10);
481 }
482 ++count;
483 }
484}
485
486namespace o2::aod
487{
488namespace parts
489{
491DECLARE_SOA_COLUMN(Property, property, int);
493} // namespace parts
494DECLARE_SOA_TABLE(Parts, "AOD", "PRTS", soa::Index<>, parts::EventId, parts::Property, parts::RelativesIdSlice);
495
496namespace things
497{
500} // namespace things
501DECLARE_SOA_TABLE(Things, "AOD", "THNGS", soa::Index<>, things::EventId, things::PartId);
502
503} // namespace o2::aod
504
505template <typename... As>
506static void overwriteInternalIndices(std::tuple<As...>& dest, std::tuple<As...> const& src)
507{
508 (std::get<As>(dest).bindInternalIndicesTo(&std::get<As>(src)), ...);
509}
510
511TEST_CASE("GroupSlicerMismatchedUnsortedFilteredGroupsWithSelfIndex")
512{
513 TableBuilder builderE;
514 auto evtsWriter = builderE.cursor<aod::Events>();
515 for (auto i = 0; i < 10; ++i) {
516 evtsWriter(0, i, 0.5f * i, 2.f * i, 3.f * i);
517 }
518 auto evtTable = builderE.finalize();
519
520 TableBuilder builderP;
521 auto partsWriter = builderP.cursor<aod::Parts>();
522 int filler[2];
523 std::random_device rd; // a seed source for the random number engine
524 std::mt19937 gen(rd()); // mersenne_twister_engine seeded with rd()
525 std::uniform_int_distribution<> distrib(0, 99);
526
527 for (auto i = 0; i < 100; ++i) {
528 filler[0] = distrib(gen);
529 filler[1] = distrib(gen);
530 if (filler[0] > filler[1]) {
531 std::swap(filler[0], filler[1]);
532 }
533 partsWriter(0, std::floor(i / 10.), i, filler);
534 }
535 auto partsTable = builderP.finalize();
536
537 TableBuilder builderT;
538 auto thingsWriter = builderT.cursor<aod::Things>();
539 for (auto i = 0; i < 10; ++i) {
540 thingsWriter(0, i, distrib(gen));
541 }
542 auto thingsTable = builderT.finalize();
543
544 aod::Events e{evtTable};
545 aod::Things t{thingsTable};
546 using FilteredParts = soa::Filtered<aod::Parts>;
547 auto size = distrib(gen);
549 for (auto i = 0; i < size; ++i) {
550 rows.push_back(distrib(gen));
551 }
552 FilteredParts fp{{partsTable}, rows};
553 auto associatedTuple = std::make_tuple(fp, t);
554 std::string key = "fIndex" + o2::framework::cutString(soa::getLabelFromType<aod::Events>());
555 ArrowTableSlicingCache slices({{soa::getLabelFromType<aod::Parts>(), soa::getMatcherFromTypeForKey<aod::Parts>(key), key},
556 {soa::getLabelFromType<aod::Things>(), soa::getMatcherFromTypeForKey<aod::Things>(key), key}});
557 auto s0 = slices.updateCacheEntry(0, partsTable);
558 auto s1 = slices.updateCacheEntry(1, thingsTable);
559 o2::framework::GroupSlicer g(e, associatedTuple, slices);
560
561 overwriteInternalIndices(associatedTuple, associatedTuple);
562
563 // For a grouped case, the recursive access of a slice-self index of a filtered table should have consistent types
564 for (auto& slice : g) {
565 auto as = slice.associatedTables();
566 auto gg = slice.groupingElement();
567 overwriteInternalIndices(as, associatedTuple);
568 auto& ts = std::get<1>(as);
569 ts.bindExternalIndices(&e, &std::get<0>(associatedTuple));
570 for (auto& thing : ts) {
571 if (thing.has_part()) {
572 auto part = thing.part_as<FilteredParts>();
573 REQUIRE(std::same_as<std::decay_t<decltype(part)>::parent_t, FilteredParts>);
574 auto rs = part.relatives_as<std::decay_t<decltype(part)::parent_t>>();
575 REQUIRE(std::same_as<std::decay_t<decltype(rs)>, FilteredParts>);
576 for (auto& r : rs) {
577 REQUIRE(std::same_as<std::decay_t<decltype(r)>::parent_t, FilteredParts>);
578 auto rss = r.relatives_as<std::decay_t<decltype(r)>::parent_t>();
579 REQUIRE(std::same_as<std::decay_t<decltype(rss)>, FilteredParts>);
580 for (auto& rr : rss) {
581 REQUIRE(std::same_as<std::decay_t<decltype(rr)>::parent_t, FilteredParts>);
582 auto rsss = rr.relatives_as<std::decay_t<decltype(rr)>::parent_t>();
583 REQUIRE(std::same_as<std::decay_t<decltype(rsss)>, FilteredParts>);
584 for (auto& rrr : rsss) {
585 REQUIRE(std::same_as<std::decay_t<decltype(rrr)>::parent_t, FilteredParts>);
586 auto rssss = rrr.relatives_as<std::decay_t<decltype(rrr)>::parent_t>();
587 REQUIRE(std::same_as<std::decay_t<decltype(rssss)>, FilteredParts>);
588 }
589 }
590 }
591 }
592 }
593 }
594}
595
596TEST_CASE("EmptySliceables")
597{
598 TableBuilder builderE;
599 auto evtsWriter = builderE.cursor<aod::Events>();
600 for (auto i = 0; i < 20; ++i) {
601 evtsWriter(0, i, 0.5f * i, 2.f * i, 3.f * i);
602 }
603 auto evtTable = builderE.finalize();
604
605 TableBuilder builderT;
606 auto trksWriter = builderT.cursor<aod::TrksX>();
607 auto trkTable = builderT.finalize();
608
609 aod::Events e{evtTable};
610 aod::TrksX t{trkTable};
611 REQUIRE(e.size() == 20);
612 REQUIRE(t.size() == 0);
613
614 auto tt = std::make_tuple(t);
615 std::string key = "fIndex" + o2::framework::cutString(soa::getLabelFromType<aod::Events>());
616 ArrowTableSlicingCache slices({{soa::getLabelFromType<aod::TrksX>(), soa::getMatcherFromTypeForKey<aod::TrksX>(key), key}});
617 auto s = slices.updateCacheEntry(0, trkTable);
618 o2::framework::GroupSlicer g(e, tt, slices);
619
620 unsigned int count = 0;
621 for (auto& slice : g) {
622 auto as = slice.associatedTables();
623 auto gg = slice.groupingElement();
624 auto trks = std::get<aod::TrksX>(as);
625 REQUIRE(gg.globalIndex() == count);
626 REQUIRE(trks.size() == 0);
627 ++count;
628 }
629}
630
631TEST_CASE("ArrowDirectSlicing")
632{
633 int counts[] = {5, 5, 5, 4, 1};
634 int offsets[] = {0, 5, 10, 15, 19, 20};
635 int ids[] = {0, 1, 2, 3, 4};
636 int sizes[] = {4, 1, 12, 5, 2};
637
639
640 TableBuilder builderE;
641 auto evtsWriter = builderE.cursor<aod::Events>();
642 auto step = 0;
643 for (auto i = 0; i < 20; ++i) {
644 if (i >= offsets[step + 1]) {
645 ++step;
646 }
647 evtsWriter(0, ids[step], 0.5f * i, 2.f * i, 3.f * i);
648 }
649 auto evtTable = builderE.finalize();
650
651 TableBuilder builderEE;
652 auto evtsEWriter = builderEE.cursor<aod::EventExtra>();
653 step = 0;
654
655 for (auto i = 0; i < 20; ++i) {
656 if (i >= offsets[step + 1]) {
657 ++step;
658 }
659 float arr[3] = {0.1f * i, 0.2f * i, 0.3f * i};
660 std::vector<double> d;
661 for (auto z = 0; z < sizes[step]; ++z) {
662 d.push_back((double)z * 0.5);
663 }
664 evtsEWriter(0, arr, i % 2 == 0, d);
665 }
666 auto evtETable = builderEE.finalize();
667
668 aod::Events e{evtTable};
669 aod::EventExtra ee{evtETable};
670 BigE b_e{{evtTable, evtETable}};
671
672 std::vector<std::shared_ptr<arrow::ChunkedArray>> slices_array;
673 std::vector<std::shared_ptr<arrow::ChunkedArray>> slices_bool;
674 std::vector<std::shared_ptr<arrow::ChunkedArray>> slices_vec;
675 auto offset = 0;
676 for (auto i = 0u; i < 5; ++i) {
677 slices_array.emplace_back(evtETable->column(0)->Slice(offset, counts[i]));
678 slices_bool.emplace_back(evtETable->column(1)->Slice(offset, counts[i]));
679 slices_vec.emplace_back(evtETable->column(2)->Slice(offset, counts[i]));
680 offset += counts[i];
681 REQUIRE(slices_array[i]->length() == counts[i]);
682 REQUIRE(slices_bool[i]->length() == counts[i]);
683 REQUIRE(slices_vec[i]->length() == counts[i]);
684 }
685
686 std::vector<arrow::Datum> slices;
687 std::vector<uint64_t> offsts;
688 auto bk = Entry(soa::getLabelFromType<aod::Events>(), soa::getMatcherFromTypeForKey<aod::Events>("fID"), "fID");
689 ArrowTableSlicingCache cache({bk});
690 auto s = cache.updateCacheEntry(0, {evtTable});
691 auto lcache = cache.getCacheFor(bk);
692 for (auto i = 0u; i < 5; ++i) {
693 auto [offset, count] = lcache.getSliceFor(i);
694 auto tbl = b_e.asArrowTable()->Slice(offset, count);
695 auto ca = tbl->GetColumnByName("fArr");
696 auto cb = tbl->GetColumnByName("fBoo");
697 auto cv = tbl->GetColumnByName("fLst");
698 REQUIRE(ca->length() == counts[i]);
699 REQUIRE(cb->length() == counts[i]);
700 REQUIRE(cv->length() == counts[i]);
701 REQUIRE(ca->Equals(slices_array[i]));
702 REQUIRE(cb->Equals(slices_bool[i]));
703 REQUIRE(cv->Equals(slices_vec[i]));
704 }
705
706 int j = 0u;
707 for (auto i = 0u; i < 5; ++i) {
708 auto [offset, count] = lcache.getSliceFor(i);
709 auto tbl = BigE{{b_e.asArrowTable()->Slice(offset, count)}, static_cast<uint64_t>(offset)};
710 REQUIRE(tbl.size() == counts[i]);
711 for (auto& row : tbl) {
712 REQUIRE(row.id() == ids[i]);
713 REQUIRE(row.boo() == (j % 2 == 0));
714 auto rid = row.globalIndex();
715 auto arr = row.arr();
716 REQUIRE(arr[0] == 0.1f * (float)rid);
717 REQUIRE(arr[1] == 0.2f * (float)rid);
718 REQUIRE(arr[2] == 0.3f * (float)rid);
719
720 auto d = row.lst();
721 REQUIRE(d.size() == (size_t)sizes[i]);
722 for (auto z = 0u; z < d.size(); ++z) {
723 REQUIRE(d[z] == 0.5 * (double)z);
724 }
725 ++j;
726 }
727 }
728}
729
730TEST_CASE("TestSlicingException")
731{
732 int offsets[] = {0, 5, 10, 15, 19, 20};
733 int ids[] = {0, 1, 2, 4, 3};
734
735 TableBuilder builderE;
736 auto evtsWriter = builderE.cursor<aod::Events>();
737 auto step = 0;
738 for (auto i = 0; i < 20; ++i) {
739 if (i >= offsets[step + 1]) {
740 ++step;
741 }
742 evtsWriter(0, ids[step], 0.5f * i, 2.f * i, 3.f * i);
743 }
744 auto evtTable = builderE.finalize();
745
746 auto bk = Entry(soa::getLabelFromType<aod::Events>(), soa::getMatcherFromTypeForKey<aod::Events>("fID"), "fID");
747 ArrowTableSlicingCache cache({bk});
748
749 try {
750 auto s = cache.updateCacheEntry(0, {evtTable});
751 } catch (RuntimeErrorRef re) {
752 REQUIRE(std::string{error_from_ref(re).what} == "Table Events index fID is not sorted: next value 3 < previous value 4!");
753 return;
754 } catch (...) {
755 FAIL("Slicing should have failed due to unsorted index");
756 }
757}
#define DECLARE_SOA_TABLE(_Name_, _Origin_, _Desc_,...)
Definition ASoA.h:3267
#define DECLARE_SOA_COLUMN(_Name_, _Getter_, _Type_)
Definition ASoA.h:2513
#define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN(_Name_, _Getter_)
Definition ASoA.h:3080
#define DECLARE_SOA_INDEX_COLUMN(_Name_, _Getter_)
Definition ASoA.h:2955
default_random_engine gen(dev())
int32_t i
uint32_t j
Definition RawData.h:0
StringRef key
std::shared_ptr< arrow::Table > finalize()
#define CHECK
struct _cl_event * event
Definition glcorearb.h:2982
GLint GLenum GLint x
Definition glcorearb.h:403
GLenum src
Definition glcorearb.h:1767
GLint GLsizei count
Definition glcorearb.h:399
GLsizeiptr size
Definition glcorearb.h:659
GLuint GLsizei const GLuint const GLintptr * offsets
Definition glcorearb.h:2595
GLuint * ids
Definition glcorearb.h:647
GLuint GLsizei const GLuint const GLintptr const GLsizeiptr * sizes
Definition glcorearb.h:2595
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
Definition glcorearb.h:5034
GLintptr offset
Definition glcorearb.h:660
GLuint GLsizei GLsizei * length
Definition glcorearb.h:790
GLboolean GLboolean g
Definition glcorearb.h:1233
GLboolean r
Definition glcorearb.h:1233
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s0
Definition glcorearb.h:5034
Events::iterator Event
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
TEST_CASE("test_prepareArguments")
RuntimeError & error_from_ref(RuntimeErrorRef)
std::string cutString(std::string &&str)
Definition ASoA.cxx:282
std::vector< int64_t > SelectionVector
Definition ASoA.h:443
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
FIXME: do not use data model tables.
arrow::Status updateCacheEntry(int pos, std::shared_ptr< arrow::Table > const &table)
char what[MAX_RUNTIME_ERROR_SIZE]
HistogramRegistry foo()
std::random_device rd
std::vector< int > row
std::vector< ReadoutWindowData > rows