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#include <iostream>
19
20#include <catch_amalgamated.hpp>
21
22using namespace o2;
23using namespace o2::framework;
24
25namespace o2::aod
26{
27namespace test
28{
31DECLARE_SOA_COLUMN(Bar, bar, float);
32DECLARE_SOA_COLUMN(EventProperty, eventProperty, float);
33} // namespace test
34DECLARE_SOA_TABLE(Events, "AOD", "EVTS",
36 test::ID,
37 test::EventProperty,
38 test::Foo,
39 test::Bar);
40
41using Event = Events::iterator;
42
43namespace test
44{
46DECLARE_SOA_COLUMN(X, x, float);
47DECLARE_SOA_COLUMN(Y, y, float);
48DECLARE_SOA_COLUMN(Z, z, float);
49} // namespace test
50
51namespace unsorted
52{
54}
55
56DECLARE_SOA_TABLE(TrksX, "AOD", "TRKSX",
57 test::EventId,
58 test::X);
59DECLARE_SOA_TABLE(TrksY, "AOD", "TRKSY",
60 test::EventId,
61 test::Y);
62DECLARE_SOA_TABLE(TrksZ, "AOD", "TRKSZ",
63 test::EventId,
64 test::Z);
65DECLARE_SOA_TABLE(TrksU, "AOD", "TRKSU",
66 test::X,
67 test::Y,
68 test::Z);
69
70DECLARE_SOA_TABLE(TrksXU, "AOD", "TRKSXU",
71 unsorted::EventId,
72 test::X);
73DECLARE_SOA_TABLE(TrksYU, "AOD", "TRKSYU",
74 unsorted::EventId,
75 test::Y);
76DECLARE_SOA_TABLE(TrksZU, "AOD", "TRKSZU",
77 unsorted::EventId,
78 test::Z);
79
80namespace test
81{
82DECLARE_SOA_COLUMN(Arr, arr, float[3]);
83DECLARE_SOA_COLUMN(Boo, boo, bool);
84DECLARE_SOA_COLUMN(Lst, lst, std::vector<double>);
85} // namespace test
86
87DECLARE_SOA_TABLE(EventExtra, "AOD", "EVTSXTRA", test::Arr, test::Boo, test::Lst);
88
89} // namespace o2::aod
90TEST_CASE("RelatedByIndex")
91{
93 CHECK(soa::relatedByIndex<aod::Collision, Trks>() == true);
94 CHECK(soa::relatedByIndex<aod::Collision, aod::Tracks>() == true);
95}
96
97TEST_CASE("GroupSlicerOneAssociated")
98{
99 TableBuilder builderE;
100 auto evtsWriter = builderE.cursor<aod::Events>();
101 for (auto i = 0; i < 20; ++i) {
102 evtsWriter(0, i, 0.5f * i, 2.f * i, 3.f * i);
103 }
104 auto evtTable = builderE.finalize();
105
106 TableBuilder builderT;
107 auto trksWriter = builderT.cursor<aod::TrksX>();
108 for (auto i = 0; i < 20; ++i) {
109 for (auto j = 0.f; j < 5; j += 0.5f) {
110 trksWriter(0, i, 0.5f * j);
111 }
112 }
113 auto trkTable = builderT.finalize();
114 aod::Events e{evtTable};
115 aod::TrksX t{trkTable};
116 REQUIRE(e.size() == 20);
117 REQUIRE(t.size() == 10 * 20);
118
119 auto tt = std::make_tuple(t);
120 ArrowTableSlicingCache slices({{soa::getLabelFromType<aod::TrksX>(), "fIndex" + o2::framework::cutString(soa::getLabelFromType<aod::Events>())}});
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>(), key},
195 {soa::getLabelFromType<aod::TrksY>(), key},
196 {soa::getLabelFromType<aod::TrksZ>(), 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 ArrowTableSlicingCache slices({{soa::getLabelFromType<aod::TrksX>(), "fIndex" + o2::framework::cutString(soa::getLabelFromType<aod::Events>())}});
260 auto s = slices.updateCacheEntry(0, trkTable);
261 o2::framework::GroupSlicer g(e, tt, slices);
262
263 for (auto& slice : g) {
264 auto as = slice.associatedTables();
265 auto gg = slice.groupingElement();
266 REQUIRE(gg.globalIndex() == (int64_t)slice.position);
267 auto trks = std::get<aod::TrksX>(as);
268 if (slice.position == 3 || slice.position == 10 || slice.position == 12 || slice.position == 16 || slice.position == 19) {
269 REQUIRE(trks.size() == 0);
270 } else {
271 REQUIRE(trks.size() == 10);
272 }
273 for (auto& trk : trks) {
274 REQUIRE(trk.eventId() == (int64_t)slice.position);
275 }
276 }
277}
278
279TEST_CASE("GroupSlicerMismatchedUnassignedGroups")
280{
281 TableBuilder builderE;
282 auto evtsWriter = builderE.cursor<aod::Events>();
283 for (auto i = 0; i < 20; ++i) {
284 evtsWriter(0, i, 0.5f * i, 2.f * i, 3.f * i);
285 }
286 auto evtTable = builderE.finalize();
287
288 int skip = 0;
289
290 TableBuilder builderT;
291 auto trksWriter = builderT.cursor<aod::TrksX>();
292 for (auto i = 0; i < 20; ++i) {
293 if (i == 3 || i == 10 || i == 12 || i == 16 || i == 19) {
294 for (auto iz = 0; iz < 5; ++iz) {
295 trksWriter(0, -1 - skip, 0.123f * iz + 1.654f);
296 }
297 ++skip;
298 continue;
299 }
300 for (auto j = 0; j < 10; ++j) {
301 trksWriter(0, i, 0.5f * (j / 2.));
302 }
303 }
304 for (auto i = 0; i < 5; ++i) {
305 trksWriter(0, -6, 0.123f * i + 1.654f);
306 }
307 auto trkTable = builderT.finalize();
308
309 aod::Events e{evtTable};
310 aod::TrksX t{trkTable};
311 REQUIRE(e.size() == 20);
312 REQUIRE(t.size() == (30 + 10 * (20 - 5)));
313
314 auto tt = std::make_tuple(t);
315 ArrowTableSlicingCache slices({{soa::getLabelFromType<aod::TrksX>(), "fIndex" + o2::framework::cutString(soa::getLabelFromType<aod::Events>())}});
316 auto s = slices.updateCacheEntry(0, trkTable);
317 o2::framework::GroupSlicer g(e, tt, slices);
318
319 auto count = 0;
320 for (auto& slice : g) {
321 auto as = slice.associatedTables();
322 auto gg = slice.groupingElement();
323 REQUIRE(gg.globalIndex() == count);
324 auto trks = std::get<aod::TrksX>(as);
325 if (count == 3 || count == 10 || count == 12 || count == 16 || count == 19) {
326 REQUIRE(trks.size() == 0);
327 } else {
328 REQUIRE(trks.size() == 10);
329 }
330 for (auto& trk : trks) {
331 REQUIRE(trk.eventId() == count);
332 }
333 ++count;
334 }
335}
336
337TEST_CASE("GroupSlicerMismatchedFilteredGroups")
338{
339 TableBuilder builderE;
340 auto evtsWriter = builderE.cursor<aod::Events>();
341 for (auto i = 0; i < 20; ++i) {
342 evtsWriter(0, i, 0.5f * i, 2.f * i, 3.f * i);
343 }
344 auto evtTable = builderE.finalize();
345
346 TableBuilder builderT;
347 auto trksWriter = builderT.cursor<aod::TrksX>();
348 for (auto i = 0; i < 20; ++i) {
349 if (i == 3 || i == 10 || i == 12 || i == 16) {
350 continue;
351 }
352 for (auto j = 0.f; j < 5; j += 0.5f) {
353 trksWriter(0, i, 0.5f * j);
354 }
355 }
356 auto trkTable = builderT.finalize();
357 using FilteredEvents = soa::Filtered<aod::Events>;
358 soa::SelectionVector rows{2, 4, 10, 9, 15};
359 FilteredEvents e{{evtTable}, {2, 4, 10, 9, 15}};
360 aod::TrksX t{trkTable};
361 REQUIRE(e.size() == 5);
362 REQUIRE(t.size() == 10 * (20 - 4));
363
364 auto tt = std::make_tuple(t);
365 ArrowTableSlicingCache slices({{soa::getLabelFromType<aod::TrksX>(), "fIndex" + o2::framework::cutString(soa::getLabelFromType<aod::Events>())}});
366 auto s = slices.updateCacheEntry(0, trkTable);
367 o2::framework::GroupSlicer g(e, tt, slices);
368
369 auto count = 0;
370
371 for (auto& slice : g) {
372 auto as = slice.associatedTables();
373 auto gg = slice.groupingElement();
374 REQUIRE(gg.globalIndex() == rows[count]);
375 auto trks = std::get<aod::TrksX>(as);
376 if (rows[count] == 3 || rows[count] == 10 || rows[count] == 12 || rows[count] == 16) {
377 REQUIRE(trks.size() == 0);
378 } else {
379 REQUIRE(trks.size() == 10);
380 }
381 for (auto& trk : trks) {
382 REQUIRE(trk.eventId() == rows[count]);
383 }
384 ++count;
385 }
386}
387
388TEST_CASE("GroupSlicerMismatchedUnsortedFilteredGroups")
389{
390 TableBuilder builderE;
391 auto evtsWriter = builderE.cursor<aod::Events>();
392 for (auto i = 0; i < 20; ++i) {
393 evtsWriter(0, i, 0.5f * i, 2.f * i, 3.f * i);
394 }
395 auto evtTable = builderE.finalize();
396
397 TableBuilder builderT;
398 auto trksWriter = builderT.cursor<aod::TrksXU>();
399 std::vector<int> randomized{10, 2, 1, 0, 15, 3, 6, 4, 14, 5, 7, 9, 8, 19, 11, 13, 17, 12, 18, 19};
400 std::vector<int64_t> sel;
401 sel.resize(10 * (20 - 4));
402 std::iota(sel.begin(), sel.end(), 0);
403 for (auto i : randomized) {
404 if (i == 3 || i == 10 || i == 12 || i == 16) {
405 continue;
406 }
407 for (auto j = 0.f; j < 5; j += 0.5f) {
408 trksWriter(0, i, 0.5f * j);
409 }
410 }
411 auto trkTable = builderT.finalize();
412
413 TableBuilder builderTE;
414 auto trksWriterE = builderTE.cursor<aod::TrksXU>();
415 auto trkTableE = builderTE.finalize();
416
417 using FilteredEvents = soa::Filtered<aod::Events>;
418 soa::SelectionVector rows{2, 4, 10, 9, 15};
419 FilteredEvents e{{evtTable}, {2, 4, 10, 9, 15}};
420 soa::SmallGroups<aod::TrksXU> t{{trkTable}, std::move(sel)};
421
422 REQUIRE(e.size() == 5);
423 REQUIRE(t.size() == 10 * (20 - 4));
424
425 auto tt = std::make_tuple(t);
426 ArrowTableSlicingCache slices({}, {{soa::getLabelFromType<aod::TrksXU>(), "fIndex" + o2::framework::cutString(soa::getLabelFromType<aod::Events>())}});
427 auto s = slices.updateCacheEntryUnsorted(0, trkTable);
428 o2::framework::GroupSlicer g(e, tt, slices);
429
430 unsigned int count = 0;
431
432 for (auto& slice : g) {
433 auto as = slice.associatedTables();
434 auto gg = slice.groupingElement();
435 REQUIRE(gg.globalIndex() == rows[count]);
436 auto trks = std::get<soa::SmallGroups<aod::TrksXU>>(as);
437 if (rows[count] == 3 || rows[count] == 10 || rows[count] == 12 || rows[count] == 16) {
438 REQUIRE(trks.size() == 0);
439 } else {
440 REQUIRE(trks.size() == 10);
441 }
442 for (auto& trk : trks) {
443 REQUIRE(trk.eventId() == rows[count]);
444 }
445 ++count;
446 }
447
448 std::vector<int64_t> sele;
449 soa::SmallGroups<aod::TrksXU> te{{trkTableE}, std::move(sele)};
450 auto tte = std::make_tuple(te);
451 o2::framework::GroupSlicer ge(e, tte, slices);
452
453 count = 0;
454 for (auto& slice : ge) {
455 auto as = slice.associatedTables();
456 auto gg = slice.groupingElement();
457 REQUIRE(gg.globalIndex() == rows[count]);
458 auto trks = std::get<soa::SmallGroups<aod::TrksXU>>(as);
459 REQUIRE(trks.size() == 0);
460 ++count;
461 }
462
463 soa::SmallGroupsUnfiltered<aod::TrksXU> tu{{trkTable}, std::vector<int64_t>{}};
464 auto ttu = std::make_tuple(tu);
465 o2::framework::GroupSlicer gu(e, ttu, slices);
466
467 count = 0;
468 for (auto& slice : gu) {
469 auto as = slice.associatedTables();
470 auto gg = slice.groupingElement();
471 REQUIRE(gg.globalIndex() == rows[count]);
472 auto trks = std::get<soa::SmallGroupsUnfiltered<aod::TrksXU>>(as);
473 if (rows[count] == 3 || rows[count] == 10 || rows[count] == 12 || rows[count] == 16) {
474 REQUIRE(trks.size() == 0);
475 } else {
476 REQUIRE(trks.size() == 10);
477 }
478 ++count;
479 }
480}
481
482namespace o2::aod
483{
484namespace parts
485{
487DECLARE_SOA_COLUMN(Property, property, int);
489} // namespace parts
490DECLARE_SOA_TABLE(Parts, "AOD", "PRTS", soa::Index<>, parts::EventId, parts::Property, parts::RelativesIdSlice);
491
492namespace things
493{
496} // namespace things
497DECLARE_SOA_TABLE(Things, "AOD", "THNGS", soa::Index<>, things::EventId, things::PartId);
498
499} // namespace o2::aod
500
501template <typename... As>
502static void overwriteInternalIndices(std::tuple<As...>& dest, std::tuple<As...> const& src)
503{
504 (std::get<As>(dest).bindInternalIndicesTo(&std::get<As>(src)), ...);
505}
506
507TEST_CASE("GroupSlicerMismatchedUnsortedFilteredGroupsWithSelfIndex")
508{
509 TableBuilder builderE;
510 auto evtsWriter = builderE.cursor<aod::Events>();
511 for (auto i = 0; i < 10; ++i) {
512 evtsWriter(0, i, 0.5f * i, 2.f * i, 3.f * i);
513 }
514 auto evtTable = builderE.finalize();
515
516 TableBuilder builderP;
517 auto partsWriter = builderP.cursor<aod::Parts>();
518 int filler[2];
519 std::random_device rd; // a seed source for the random number engine
520 std::mt19937 gen(rd()); // mersenne_twister_engine seeded with rd()
521 std::uniform_int_distribution<> distrib(0, 99);
522
523 for (auto i = 0; i < 100; ++i) {
524 filler[0] = distrib(gen);
525 filler[1] = distrib(gen);
526 if (filler[0] > filler[1]) {
527 std::swap(filler[0], filler[1]);
528 }
529 partsWriter(0, std::floor(i / 10.), i, filler);
530 }
531 auto partsTable = builderP.finalize();
532
533 TableBuilder builderT;
534 auto thingsWriter = builderT.cursor<aod::Things>();
535 for (auto i = 0; i < 10; ++i) {
536 thingsWriter(0, i, distrib(gen));
537 }
538 auto thingsTable = builderT.finalize();
539
540 aod::Events e{evtTable};
541 aod::Things t{thingsTable};
542 using FilteredParts = soa::Filtered<aod::Parts>;
543 auto size = distrib(gen);
545 for (auto i = 0; i < size; ++i) {
546 rows.push_back(distrib(gen));
547 }
548 FilteredParts fp{{partsTable}, rows};
549 auto associatedTuple = std::make_tuple(fp, t);
550 ArrowTableSlicingCache slices({{soa::getLabelFromType<aod::Parts>(), "fIndex" + o2::framework::cutString(soa::getLabelFromType<aod::Events>())},
551 {soa::getLabelFromType<aod::Things>(), "fIndex" + o2::framework::cutString(soa::getLabelFromType<aod::Events>())}});
552 auto s0 = slices.updateCacheEntry(0, partsTable);
553 auto s1 = slices.updateCacheEntry(1, thingsTable);
554 o2::framework::GroupSlicer g(e, associatedTuple, slices);
555
556 overwriteInternalIndices(associatedTuple, associatedTuple);
557
558 // For a grouped case, the recursive access of a slice-self index of a filtered table should have consistent types
559 for (auto& slice : g) {
560 auto as = slice.associatedTables();
561 auto gg = slice.groupingElement();
562 overwriteInternalIndices(as, associatedTuple);
563 auto& ts = std::get<1>(as);
564 ts.bindExternalIndices(&e, &std::get<0>(associatedTuple));
565 for (auto& thing : ts) {
566 if (thing.has_part()) {
567 auto part = thing.part_as<FilteredParts>();
568 REQUIRE(std::same_as<std::decay_t<decltype(part)>::parent_t, FilteredParts>);
569 auto rs = part.relatives_as<std::decay_t<decltype(part)::parent_t>>();
570 REQUIRE(std::same_as<std::decay_t<decltype(rs)>, FilteredParts>);
571 for (auto& r : rs) {
572 REQUIRE(std::same_as<std::decay_t<decltype(r)>::parent_t, FilteredParts>);
573 auto rss = r.relatives_as<std::decay_t<decltype(r)>::parent_t>();
574 REQUIRE(std::same_as<std::decay_t<decltype(rss)>, FilteredParts>);
575 for (auto& rr : rss) {
576 REQUIRE(std::same_as<std::decay_t<decltype(rr)>::parent_t, FilteredParts>);
577 auto rsss = rr.relatives_as<std::decay_t<decltype(rr)>::parent_t>();
578 REQUIRE(std::same_as<std::decay_t<decltype(rsss)>, FilteredParts>);
579 for (auto& rrr : rsss) {
580 REQUIRE(std::same_as<std::decay_t<decltype(rrr)>::parent_t, FilteredParts>);
581 auto rssss = rrr.relatives_as<std::decay_t<decltype(rrr)>::parent_t>();
582 REQUIRE(std::same_as<std::decay_t<decltype(rssss)>, FilteredParts>);
583 }
584 }
585 }
586 }
587 }
588 }
589}
590
591TEST_CASE("EmptySliceables")
592{
593 TableBuilder builderE;
594 auto evtsWriter = builderE.cursor<aod::Events>();
595 for (auto i = 0; i < 20; ++i) {
596 evtsWriter(0, i, 0.5f * i, 2.f * i, 3.f * i);
597 }
598 auto evtTable = builderE.finalize();
599
600 TableBuilder builderT;
601 auto trksWriter = builderT.cursor<aod::TrksX>();
602 auto trkTable = builderT.finalize();
603
604 aod::Events e{evtTable};
605 aod::TrksX t{trkTable};
606 REQUIRE(e.size() == 20);
607 REQUIRE(t.size() == 0);
608
609 auto tt = std::make_tuple(t);
610 ArrowTableSlicingCache slices({{soa::getLabelFromType<aod::TrksX>(), "fIndex" + o2::framework::cutString(soa::getLabelFromType<aod::Events>())}});
611 auto s = slices.updateCacheEntry(0, trkTable);
612 o2::framework::GroupSlicer g(e, tt, slices);
613
614 unsigned int count = 0;
615 for (auto& slice : g) {
616 auto as = slice.associatedTables();
617 auto gg = slice.groupingElement();
618 auto trks = std::get<aod::TrksX>(as);
619 REQUIRE(gg.globalIndex() == count);
620 REQUIRE(trks.size() == 0);
621 ++count;
622 }
623}
624
625TEST_CASE("ArrowDirectSlicing")
626{
627 int counts[] = {5, 5, 5, 4, 1};
628 int offsets[] = {0, 5, 10, 15, 19, 20};
629 int ids[] = {0, 1, 2, 3, 4};
630 int sizes[] = {4, 1, 12, 5, 2};
631
633
634 TableBuilder builderE;
635 auto evtsWriter = builderE.cursor<aod::Events>();
636 auto step = 0;
637 for (auto i = 0; i < 20; ++i) {
638 if (i >= offsets[step + 1]) {
639 ++step;
640 }
641 evtsWriter(0, ids[step], 0.5f * i, 2.f * i, 3.f * i);
642 }
643 auto evtTable = builderE.finalize();
644
645 TableBuilder builderEE;
646 auto evtsEWriter = builderEE.cursor<aod::EventExtra>();
647 step = 0;
648
649 for (auto i = 0; i < 20; ++i) {
650 if (i >= offsets[step + 1]) {
651 ++step;
652 }
653 float arr[3] = {0.1f * i, 0.2f * i, 0.3f * i};
654 std::vector<double> d;
655 for (auto z = 0; z < sizes[step]; ++z) {
656 d.push_back((double)z * 0.5);
657 }
658 evtsEWriter(0, arr, i % 2 == 0, d);
659 }
660 auto evtETable = builderEE.finalize();
661
662 aod::Events e{evtTable};
663 aod::EventExtra ee{evtETable};
664 BigE b_e{{evtTable, evtETable}};
665
666 std::vector<std::shared_ptr<arrow::ChunkedArray>> slices_array;
667 std::vector<std::shared_ptr<arrow::ChunkedArray>> slices_bool;
668 std::vector<std::shared_ptr<arrow::ChunkedArray>> slices_vec;
669 auto offset = 0;
670 for (auto i = 0u; i < 5; ++i) {
671 slices_array.emplace_back(evtETable->column(0)->Slice(offset, counts[i]));
672 slices_bool.emplace_back(evtETable->column(1)->Slice(offset, counts[i]));
673 slices_vec.emplace_back(evtETable->column(2)->Slice(offset, counts[i]));
674 offset += counts[i];
675 REQUIRE(slices_array[i]->length() == counts[i]);
676 REQUIRE(slices_bool[i]->length() == counts[i]);
677 REQUIRE(slices_vec[i]->length() == counts[i]);
678 }
679
680 std::vector<arrow::Datum> slices;
681 std::vector<uint64_t> offsts;
682 auto bk = Entry(soa::getLabelFromType<aod::Events>(), "fID");
683 ArrowTableSlicingCache cache({bk});
684 auto s = cache.updateCacheEntry(0, {evtTable});
685 auto lcache = cache.getCacheFor(bk);
686 for (auto i = 0u; i < 5; ++i) {
687 auto [offset, count] = lcache.getSliceFor(i);
688 auto tbl = b_e.asArrowTable()->Slice(offset, count);
689 auto ca = tbl->GetColumnByName("fArr");
690 auto cb = tbl->GetColumnByName("fBoo");
691 auto cv = tbl->GetColumnByName("fLst");
692 REQUIRE(ca->length() == counts[i]);
693 REQUIRE(cb->length() == counts[i]);
694 REQUIRE(cv->length() == counts[i]);
695 REQUIRE(ca->Equals(slices_array[i]));
696 REQUIRE(cb->Equals(slices_bool[i]));
697 REQUIRE(cv->Equals(slices_vec[i]));
698 }
699
700 int j = 0u;
701 for (auto i = 0u; i < 5; ++i) {
702 auto [offset, count] = lcache.getSliceFor(i);
703 auto tbl = BigE{{b_e.asArrowTable()->Slice(offset, count)}, static_cast<uint64_t>(offset)};
704 REQUIRE(tbl.size() == counts[i]);
705 for (auto& row : tbl) {
706 REQUIRE(row.id() == ids[i]);
707 REQUIRE(row.boo() == (j % 2 == 0));
708 auto rid = row.globalIndex();
709 auto arr = row.arr();
710 REQUIRE(arr[0] == 0.1f * (float)rid);
711 REQUIRE(arr[1] == 0.2f * (float)rid);
712 REQUIRE(arr[2] == 0.3f * (float)rid);
713
714 auto d = row.lst();
715 REQUIRE(d.size() == (size_t)sizes[i]);
716 for (auto z = 0u; z < d.size(); ++z) {
717 REQUIRE(d[z] == 0.5 * (double)z);
718 }
719 ++j;
720 }
721 }
722}
723
724TEST_CASE("TestSlicingException")
725{
726 int offsets[] = {0, 5, 10, 15, 19, 20};
727 int ids[] = {0, 1, 2, 4, 3};
728
729 TableBuilder builderE;
730 auto evtsWriter = builderE.cursor<aod::Events>();
731 auto step = 0;
732 for (auto i = 0; i < 20; ++i) {
733 if (i >= offsets[step + 1]) {
734 ++step;
735 }
736 evtsWriter(0, ids[step], 0.5f * i, 2.f * i, 3.f * i);
737 }
738 auto evtTable = builderE.finalize();
739
740 auto bk = Entry(soa::getLabelFromType<aod::Events>(), "fID");
741 ArrowTableSlicingCache cache({bk});
742
743 try {
744 auto s = cache.updateCacheEntry(0, {evtTable});
745 } catch (RuntimeErrorRef re) {
746 REQUIRE(std::string{error_from_ref(re).what} == "Table Events index fID is not sorted: next value 3 < previous value 4!");
747 return;
748 } catch (...) {
749 FAIL("Slicing should have failed due to unsorted index");
750 }
751}
#define DECLARE_SOA_TABLE(_Name_, _Origin_, _Desc_,...)
Definition ASoA.h:3170
#define DECLARE_SOA_COLUMN(_Name_, _Getter_, _Type_)
Definition ASoA.h:2395
#define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN(_Name_, _Getter_)
Definition ASoA.h:2977
#define DECLARE_SOA_INDEX_COLUMN(_Name_, _Getter_)
Definition ASoA.h:2852
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 PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
TEST_CASE("test_prepareArguments")
RuntimeError & error_from_ref(RuntimeErrorRef)
std::string cutString(std::string &&str)
Definition ASoA.cxx:238
std::vector< int64_t > SelectionVector
Definition ASoA.h:415
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