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