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::Collisions, Trks>() == true);
93 CHECK(soa::relatedByIndex<aod::Collisions, 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);
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 REQUIRE(s.ok());
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);
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);
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}}, soa::SelectionVector{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);
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}, soa::SelectionVector{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);
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);
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 const offsets[] = {0, 5, 10, 15, 19, 20};
636 int ids[] = {0, 1, 2, 3, 4};
637 int const 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 auto bk = Entry(soa::getLabelFromType<aod::Events>(), soa::getMatcherFromTypeForKey<aod::Events>("fID"), "fID");
688 ArrowTableSlicingCache cache({bk});
689 auto s = cache.updateCacheEntry(0, {evtTable});
690 REQUIRE(s.ok());
691 auto lcache = cache.getCacheFor(bk);
692 for (auto i = 0u; i < 5; ++i) {
693 auto [loffset, count] = lcache.getSliceFor(i);
694 auto tbl = b_e.asArrowTableRef().slice({static_cast<uint64_t>(loffset), count});
695 REQUIRE(tbl.range.size == counts[i]);
696 }
697
698 int j = 0u;
699 for (auto i = 0u; i < 5; ++i) {
700 auto [loffset, count] = lcache.getSliceFor(i);
701 auto tbl = BigE{{b_e.asArrowTableRef().slice({static_cast<uint64_t>(loffset), count})}};
702 REQUIRE(tbl.size() == counts[i]);
703 for (auto& row : tbl) {
704 REQUIRE(row.id() == ids[i]);
705 CHECK(row.boo() == (j % 2 == 0));
706 auto rid = row.globalIndex();
707 auto arr = row.arr();
708 REQUIRE(arr[0] == 0.1f * (float)rid);
709 REQUIRE(arr[1] == 0.2f * (float)rid);
710 REQUIRE(arr[2] == 0.3f * (float)rid);
711
712 auto d = row.lst();
713 REQUIRE(d.size() == (size_t)sizes[i]);
714 for (auto z = 0u; z < d.size(); ++z) {
715 REQUIRE(d[z] == 0.5 * (double)z);
716 }
717 ++j;
718 }
719 }
720}
721
722TEST_CASE("TestSlicingException")
723{
724 int const offsets[] = {0, 5, 10, 15, 19, 20};
725 int ids[] = {0, 1, 2, 4, 3};
726
727 TableBuilder builderE;
728 auto evtsWriter = builderE.cursor<aod::Events>();
729 auto step = 0;
730 for (auto i = 0; i < 20; ++i) {
731 if (i >= offsets[step + 1]) {
732 ++step;
733 }
734 evtsWriter(0, ids[step], 0.5f * i, 2.f * i, 3.f * i);
735 }
736 auto evtTable = builderE.finalize();
737
738 auto bk = Entry(soa::getLabelFromType<aod::Events>(), soa::getMatcherFromTypeForKey<aod::Events>("fID"), "fID");
739 ArrowTableSlicingCache cache({bk});
740
741 try {
742 auto s = cache.updateCacheEntry(0, {evtTable});
743 } catch (RuntimeErrorRef re) {
744 REQUIRE(std::string{error_from_ref(re).what} == "Table Events index fID is not sorted: next value 3 < previous value 4!");
745 return;
746 } catch (...) {
747 FAIL("Slicing should have failed due to unsorted index");
748 }
749}
#define DECLARE_SOA_TABLE(_Name_, _Origin_, _Desc_,...)
Definition ASoA.h:3196
#define DECLARE_SOA_COLUMN(_Name_, _Getter_, _Type_)
Definition ASoA.h:2440
#define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN(_Name_, _Getter_)
Definition ASoA.h:3007
#define DECLARE_SOA_INDEX_COLUMN(_Name_, _Getter_)
Definition ASoA.h:2882
default_random_engine gen(dev())
int32_t i
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error s
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events Show standalone event Run event generator maximum time bin of continuous for triggered for automatic continuous for automatic continuous triggered uint64_t
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char e
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events d
uint32_t j
Definition RawData.h:0
StringRef key
std::shared_ptr< arrow::Table > finalize()
#define CHECK
GLboolean GLboolean g
Definition glcorearb.h:1233
struct _cl_event * event
Definition glcorearb.h:2982
GLint GLenum GLint x
Definition glcorearb.h:403
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 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
GLint y
Definition glcorearb.h:270
GLintptr offset
Definition glcorearb.h:660
GLuint GLsizei GLsizei * length
Definition glcorearb.h:790
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:322
std::vector< int64_t > SelectionVector
Definition ASoA.h:444
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