Project
Loading...
Searching...
No Matches
AnalysisHelpers.h
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#ifndef o2_framework_AnalysisHelpers_H_DEFINED
12#define o2_framework_AnalysisHelpers_H_DEFINED
13
14#include "ConfigParamSpec.h"
15#include "Framework/ASoA.h"
18#include "Framework/InputSpec.h"
19#include "Framework/Output.h"
21#include "Framework/OutputRef.h"
23#include "Framework/Plugins.h"
26#include "Framework/Traits.h"
27
28#include <string>
29namespace o2::framework
30{
31std::string serializeProjectors(std::vector<framework::expressions::Projector>& projectors);
32std::string serializeSchema(std::shared_ptr<arrow::Schema>& schema);
33} // namespace o2::framework
34
35namespace o2::soa
36{
37template <TableRef R>
39{
41 std::string{"input:"} + o2::aod::label<R>(),
43 aod::sourceSpec<R>(),
44 {"\"\""}};
45}
46
47namespace
48{
49template <soa::with_sources T>
50inline constexpr auto getSources()
51{
52 return []<size_t N, std::array<soa::TableRef, N> refs>() {
53 return []<size_t... Is>(std::index_sequence<Is...>) {
54 return std::vector{soa::tableRef2ConfigParamSpec<refs[Is]>()...};
55 }(std::make_index_sequence<N>());
56 }.template operator()<T::sources.size(), T::sources>();
57}
58
59template <soa::with_ccdb_urls T>
60inline constexpr auto getCCDBUrls()
61{
62 std::vector<framework::ConfigParamSpec> result;
63 for (size_t i = 0; i < T::ccdb_urls.size(); ++i) {
64 result.push_back({std::string{"ccdb:"} + std::string{T::ccdb_bindings[i]},
66 T::ccdb_urls[i],
67 {"\"\""}});
68 }
69 return result;
70}
71
72template <soa::with_sources T>
73constexpr auto getInputMetadata() -> std::vector<framework::ConfigParamSpec>
74{
75 std::vector<framework::ConfigParamSpec> inputMetadata;
76 auto inputSources = getSources<T>();
77 std::sort(inputSources.begin(), inputSources.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name < b.name; });
78 auto last = std::unique(inputSources.begin(), inputSources.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name == b.name; });
79 inputSources.erase(last, inputSources.end());
80 inputMetadata.insert(inputMetadata.end(), inputSources.begin(), inputSources.end());
81 return inputMetadata;
82}
83
84template <typename T>
85 requires(!soa::with_sources<T>)
86constexpr auto getInputMetadata() -> std::vector<framework::ConfigParamSpec>
87{
88 return {};
89}
90
91template <soa::with_ccdb_urls T>
92constexpr auto getCCDBMetadata() -> std::vector<framework::ConfigParamSpec>
93{
94 std::vector<framework::ConfigParamSpec> results = getCCDBUrls<T>();
95 std::sort(results.begin(), results.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name < b.name; });
96 auto last = std::unique(results.begin(), results.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name == b.name; });
97 results.erase(last, results.end());
98 return results;
99}
100
101template <typename T>
102constexpr auto getCCDBMetadata() -> std::vector<framework::ConfigParamSpec>
103{
104 return {};
105}
106
107template <soa::with_expression_pack T>
108constexpr auto getExpressionMetadata() -> std::vector<framework::ConfigParamSpec>
109{
110 using expression_pack_t = T::expression_pack_t;
111
112 auto projectors = []<typename... C>(framework::pack<C...>) -> std::vector<framework::expressions::Projector> {
113 std::vector<framework::expressions::Projector> result;
114 (result.emplace_back(std::move(C::Projector())), ...);
115 return result;
116 }(expression_pack_t{});
117
118 auto schema = std::make_shared<arrow::Schema>(o2::soa::createFieldsFromColumns(expression_pack_t{}));
119
121 return {framework::ConfigParamSpec{"projectors", framework::VariantType::String, json, {"\"\""}},
122 framework::ConfigParamSpec{"schema", framework::VariantType::String, framework::serializeSchema(schema), {"\"\""}}};
123}
124
125template <typename T>
126 requires(!soa::with_expression_pack<T>)
127constexpr auto getExpressionMetadata() -> std::vector<framework::ConfigParamSpec>
128{
129 return {};
130}
131
132} // namespace
133
134template <TableRef R>
135constexpr auto tableRef2InputSpec()
136{
137 std::vector<framework::ConfigParamSpec> metadata;
138 auto m = getInputMetadata<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata>();
139 metadata.insert(metadata.end(), m.begin(), m.end());
140 auto ccdbMetadata = getCCDBMetadata<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata>();
141 metadata.insert(metadata.end(), ccdbMetadata.begin(), ccdbMetadata.end());
142 auto p = getExpressionMetadata<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata>();
143 metadata.insert(metadata.end(), p.begin(), p.end());
144
146 o2::aod::label<R>(),
147 o2::aod::origin<R>(),
148 o2::aod::description(o2::aod::signature<R>()),
149 R.version,
150 framework::Lifetime::Timeframe,
151 metadata};
152}
153
154template <TableRef R>
155constexpr auto tableRef2OutputSpec()
156{
158 framework::OutputLabel{o2::aod::label<R>()},
159 o2::aod::origin<R>(),
160 o2::aod::description(o2::aod::signature<R>()),
161 R.version};
162}
163
164template <TableRef R>
165constexpr auto tableRef2Output()
166{
167 return framework::Output{
168 o2::aod::origin<R>(),
169 o2::aod::description(o2::aod::signature<R>()),
170 R.version};
171}
172
173template <TableRef R>
174constexpr auto tableRef2OutputRef()
175{
177 o2::aod::label<R>(),
178 R.version};
179}
180} // namespace o2::soa
181
182namespace o2::framework
183{
184class TableConsumer;
185
189template <typename T>
191
192template <typename T>
193concept is_enumerated_iterator = requires(T t) { t.globalIndex(); };
194
195template <is_producable T>
197 public:
198 using persistent_table_t = decltype([]() { if constexpr (soa::is_iterator<T>) { return typename T::parent_t{nullptr}; } else { return T{nullptr}; } }());
199 using cursor_t = decltype(std::declval<TableBuilder>().cursor<persistent_table_t>());
200
201 template <typename... Ts>
202 void operator()(Ts&&... args)
203 requires(sizeof...(Ts) == framework::pack_size(typename persistent_table_t::persistent_columns_t{}))
204 {
205 ++mCount;
206 cursor(0, extract(args)...);
207 }
208
210 int64_t lastIndex()
211 {
212 return mCount;
213 }
214
216 {
217 mBuilder = std::move(builder);
218 cursor = std::move(FFL(mBuilder->cursor<persistent_table_t>()));
219 mCount = -1;
220 return true;
221 }
222
223 void setLabel(const char* label)
224 {
225 mBuilder->setLabel(label);
226 }
227
230 void reserve(int64_t size)
231 {
232 mBuilder->reserve(typename persistent_table_t::column_types{}, size);
233 }
234
235 void release()
236 {
237 mBuilder.release();
238 }
239
240 decltype(FFL(std::declval<cursor_t>())) cursor;
241
242 private:
243 static decltype(auto) extract(is_enumerated_iterator auto const& arg)
244 {
245 return arg.globalIndex();
246 }
247
248 template <typename A>
250 static decltype(auto) extract(A&& arg)
251 {
252 return arg;
253 }
254
258 LifetimeHolder<TableBuilder> mBuilder = nullptr;
259 int64_t mCount = -1;
260};
261
263template <soa::is_table T>
264consteval auto typeWithRef() -> T
265{
266}
267
268template <soa::is_iterator T>
269consteval auto typeWithRef() -> typename T::parent_t
270{
271}
272
273template <typename T>
274 requires soa::is_table<T> || soa::is_iterator<T>
276 using table_t = decltype(typeWithRef<T>());
277 using metadata = aod::MetadataTrait<o2::aod::Hash<table_t::ref.desc_hash>>::metadata;
278
279 static OutputSpec const spec()
280 {
281 return OutputSpec{OutputLabel{aod::label<table_t::ref>()}, o2::aod::origin<table_t::ref>(), o2::aod::description(o2::aod::signature<table_t::ref>()), table_t::ref.version};
282 }
283
284 static OutputRef ref()
285 {
286 return OutputRef{aod::label<table_t::ref>(), table_t::ref.version};
287 }
288};
289
294template <is_producable T>
296};
297
298template <typename T>
299concept is_produces = requires(T t) { typename T::cursor_t; typename T::persistent_table_t; &T::cursor; };
300
310};
311
312template <typename T>
313concept is_produces_group = std::derived_from<T, ProducesGroup>;
314
316template <soa::is_metadata M, soa::TableRef Ref>
318 using metadata = M;
319 constexpr static auto sources = M::sources;
320
321 template <soa::TableRef R>
322 static constexpr auto base_spec()
323 {
324 return soa::tableRef2InputSpec<R>();
325 }
326
327 static auto base_specs()
328 {
329 return []<size_t... Is>(std::index_sequence<Is...>) -> std::vector<InputSpec> {
330 return {base_spec<sources[Is]>()...};
331 }(std::make_index_sequence<sources.size()>{});
332 }
333
334 constexpr auto spec() const
335 {
336 return soa::tableRef2OutputSpec<Ref>();
337 }
338
339 constexpr auto output() const
340 {
341 return soa::tableRef2Output<Ref>();
342 }
343
344 constexpr auto ref() const
345 {
346 return soa::tableRef2OutputRef<Ref>();
347 }
348};
349
352template <typename T>
353concept is_spawnable = soa::has_metadata<aod::MetadataTrait<o2::aod::Hash<T::ref.desc_hash>>> && soa::has_extension<typename aod::MetadataTrait<o2::aod::Hash<T::ref.desc_hash>>::metadata>;
354
355template <typename T>
356concept is_dynamically_spawnable = soa::has_metadata<aod::MetadataTrait<o2::aod::Hash<T::ref.desc_hash>>> && soa::has_configurable_extension<typename aod::MetadataTrait<o2::aod::Hash<T::ref.desc_hash>>::metadata>;
357
358template <is_spawnable T>
359constexpr auto transformBase()
360{
361 using metadata = typename aod::MetadataTrait<o2::aod::Hash<T::ref.desc_hash>>::metadata;
363}
364
365template <is_spawnable T>
366struct Spawns : decltype(transformBase<T>()) {
367 using spawnable_t = T;
368 using metadata = decltype(transformBase<T>())::metadata;
369 using extension_t = typename metadata::extension_table_t;
370 using base_table_t = typename metadata::base_table_t;
371 using expression_pack_t = typename metadata::expression_pack_t;
372 static constexpr size_t N = framework::pack_size(expression_pack_t{});
373
374 constexpr auto pack()
375 {
376 return expression_pack_t{};
377 }
378
379 typename T::table_t* operator->()
380 {
381 return table.get();
382 }
383 typename T::table_t const& operator*() const
384 {
385 return *table;
386 }
387
389 {
390 return extension->asArrowTable();
391 }
392 std::shared_ptr<typename T::table_t> table = nullptr;
393 std::shared_ptr<extension_t> extension = nullptr;
394 std::array<o2::framework::expressions::Projector, N> projectors = []<typename... C>(framework::pack<C...>) -> std::array<expressions::Projector, sizeof...(C)>
395 {
396 return {{std::move(C::Projector())...}};
397 }
399 std::shared_ptr<gandiva::Projector> projector = nullptr;
400 std::shared_ptr<arrow::Schema> schema = std::make_shared<arrow::Schema>(o2::soa::createFieldsFromColumns(expression_pack_t{}));
401};
402
403template <typename T>
404concept is_spawns = requires(T t) {
405 typename T::metadata;
406 requires std::same_as<decltype(t.pack()), typename T::expression_pack_t>;
407 requires std::same_as<decltype(t.projector), std::shared_ptr<gandiva::Projector>>;
408};
409
414
415template <is_dynamically_spawnable T, bool DELAYED = false>
416struct Defines : decltype(transformBase<T>()) {
417 static constexpr bool delayed = DELAYED;
418 using spawnable_t = T;
419 using metadata = decltype(transformBase<T>())::metadata;
420 using extension_t = typename metadata::extension_table_t;
421 using base_table_t = typename metadata::base_table_t;
422 using placeholders_pack_t = typename metadata::placeholders_pack_t;
423 static constexpr size_t N = framework::pack_size(placeholders_pack_t{});
424
425 constexpr auto pack()
426 {
427 return placeholders_pack_t{};
428 }
429
430 typename T::table_t* operator->()
431 {
432 return table.get();
433 }
434 typename T::table_t const& operator*() const
435 {
436 return *table;
437 }
438
440 {
441 return extension->asArrowTable();
442 }
443 std::shared_ptr<typename T::table_t> table = nullptr;
444 std::shared_ptr<extension_t> extension = nullptr;
445
446 std::array<o2::framework::expressions::Projector, N> projectors;
447 std::shared_ptr<gandiva::Projector> projector = nullptr;
448 std::shared_ptr<arrow::Schema> schema = std::make_shared<arrow::Schema>(o2::soa::createFieldsFromColumns(placeholders_pack_t{}));
449 std::shared_ptr<arrow::Schema> inputSchema = nullptr;
450
451 bool needRecompilation = false;
452
457};
458
459template <is_dynamically_spawnable T>
461
462template <typename T>
463concept is_defines = requires(T t) {
464 typename T::metadata;
465 requires std::same_as<decltype(t.pack()), typename T::placeholders_pack_t>;
466 requires std::same_as<decltype(t.projector), std::shared_ptr<gandiva::Projector>>;
467 requires std::same_as<decltype(t.needRecompilation), bool>;
468 &T::recompile;
469};
470
475struct Exclusive {
476};
477struct Sparse {
478};
479
480namespace
481{
482template <typename T, typename Key>
483inline std::shared_ptr<arrow::ChunkedArray> getIndexToKey(arrow::Table* table)
484{
485 using IC = framework::pack_element_t<framework::has_type_at_conditional_v<soa::is_binding_compatible, Key>(typename T::external_index_columns_t{}), typename T::external_index_columns_t>;
486 return table->column(framework::has_type_at_v<IC>(typename T::persistent_columns_t{}));
487}
488
489template <soa::is_column C>
490struct ColumnTrait {
491 using column_t = C;
492
493 static consteval auto listSize()
494 {
495 if constexpr (std::same_as<typename C::type, std::vector<int>>) {
496 return -1;
497 } else if constexpr (std::same_as<int[2], typename C::type>) {
498 return 2;
499 } else {
500 return 1;
501 }
502 }
503
504 template <typename T, typename Key>
505 static std::shared_ptr<SelfIndexColumnBuilder> makeColumnBuilder(arrow::Table* table, arrow::MemoryPool* pool)
506 {
507 if constexpr (!std::same_as<T, Key>) {
508 return std::make_shared<IndexColumnBuilder>(getIndexToKey<T, Key>(table), C::columnLabel(), listSize(), pool);
509 } else {
510 return std::make_shared<SelfIndexColumnBuilder>(C::columnLabel(), pool);
511 }
512 }
513};
514
515template <typename Key, typename C>
516struct Reduction {
517 using type = typename std::conditional<soa::is_binding_compatible_v<Key, typename C::binding_t>(), SelfIndexColumnBuilder, IndexColumnBuilder>::type;
518};
519
520template <typename Key, typename C>
521using reduced_t = Reduction<Key, C>::type;
522} // namespace
523
524template <typename Kind>
526 template <typename Key, size_t N, std::array<soa::TableRef, N> refs, typename C1, typename... Cs>
527 static auto indexBuilder(const char* label, std::vector<std::shared_ptr<arrow::Table>>&& tables, framework::pack<C1, Cs...>)
528 {
529 auto pool = arrow::default_memory_pool();
530 SelfIndexColumnBuilder self{C1::columnLabel(), pool};
531 std::unique_ptr<ChunkedArrayIterator> keyIndex = nullptr;
532 if constexpr (!Key::template hasOriginal<refs[0]>()) {
533 keyIndex = std::make_unique<ChunkedArrayIterator>(tables[0]->column(o2::aod::MetadataTrait<o2::aod::Hash<refs[0].desc_hash>>::metadata::template getIndexPosToKey<Key>()));
534 }
535
536 auto sq = std::make_index_sequence<sizeof...(Cs)>();
537
538 auto columnBuilders = [&tables, &pool ]<size_t... Is>(std::index_sequence<Is...>) -> std::array<std::shared_ptr<framework::SelfIndexColumnBuilder>, sizeof...(Cs)>
539 {
540 return {[](arrow::Table* table, arrow::MemoryPool* pool) {
541 using T = framework::pack_element_t<Is, framework::pack<Cs...>>;
542 if constexpr (!Key::template hasOriginal<refs[Is + 1]>()) {
543 constexpr auto pos = o2::aod::MetadataTrait<o2::aod::Hash<refs[Is + 1].desc_hash>>::metadata::template getIndexPosToKey<Key>();
544 return std::make_shared<IndexColumnBuilder>(table->column(pos), T::columnLabel(), ColumnTrait<T>::listSize(), pool);
545 } else {
546 return std::make_shared<SelfIndexColumnBuilder>(T::columnLabel(), pool);
547 }
548 }(tables[Is + 1].get(), pool)...};
549 }
550 (sq);
551
552 std::array<bool, sizeof...(Cs)> finds;
553
554 for (int64_t counter = 0; counter < tables[0]->num_rows(); ++counter) {
555 int64_t idx = -1;
556 if constexpr (Key::template hasOriginal<refs[0]>()) {
557 idx = counter;
558 } else {
559 idx = keyIndex->valueAt(counter);
560 }
561 finds = [&idx, &columnBuilders]<size_t... Is>(std::index_sequence<Is...>) {
562 return std::array{
563 [&idx, &columnBuilders]() {
564 using T = typename framework::pack_element_t<Is, framework::pack<Cs...>>;
565 return std::static_pointer_cast<reduced_t<Key, T>>(columnBuilders[Is])->template find<T>(idx);
566 }()...};
567 }(sq);
568 if constexpr (std::same_as<Kind, Sparse>) {
569 [&idx, &columnBuilders]<size_t... Is>(std::index_sequence<Is...>) {
570 ([&idx, &columnBuilders]() {
571 using T = typename framework::pack_element_t<Is, framework::pack<Cs...>>;
572 return std::static_pointer_cast<reduced_t<Key, T>>(columnBuilders[Is])->template fill<T>(idx); }(), ...);
573 }(sq);
574 self.fill<C1>(counter);
575 } else if constexpr (std::same_as<Kind, Exclusive>) {
576 if (std::none_of(finds.begin(), finds.end(), [](bool const x) { return x == false; })) {
577 [&idx, &columnBuilders]<size_t... Is>(std::index_sequence<Is...>) {
578 ([&idx, &columnBuilders]() {
579 using T = typename framework::pack_element_t<Is, framework::pack<Cs...>>;
580 return std::static_pointer_cast<reduced_t<Key, T>>(columnBuilders[Is])->template fill<T>(idx);
581 }(),
582 ...);
583 }(sq);
584 self.fill<C1>(counter);
585 }
586 }
587 }
588
589 return [&label, &columnBuilders, &self]<size_t... Is>(std::index_sequence<Is...>) {
590 return makeArrowTable(label,
591 {self.template result<C1>(), [&columnBuilders]() {
592 using T = typename framework::pack_element_t<Is, framework::pack<Cs...>>;
593 return std::static_pointer_cast<reduced_t<Key, T>>(columnBuilders[Is])->template result<T>();
594 }()...},
595 {self.field(), [&columnBuilders]() {
596 using T = typename framework::pack_element_t<Is, framework::pack<Cs...>>;
597 return std::static_pointer_cast<reduced_t<Key, T>>(columnBuilders[Is])->field();
598 }()...});
599 }(sq);
600 }
601};
602
604
605template <soa::is_index_table T>
606constexpr auto transformBase()
607{
608 using metadata = typename aod::MetadataTrait<o2::aod::Hash<T::ref.desc_hash>>::metadata;
610}
611
612template <soa::is_index_table T>
613struct Builds : decltype(transformBase<T>()) {
614 using buildable_t = T;
615 using metadata = decltype(transformBase<T>())::metadata;
616 using IP = std::conditional_t<metadata::exclusive, IndexBuilder<Exclusive>, IndexBuilder<Sparse>>;
617 using Key = metadata::Key;
618 using H = typename T::first_t;
619 using Ts = typename T::rest_t;
620 using index_pack_t = metadata::index_pack_t;
621
623 {
624 return table.get();
625 }
626 T const& operator*() const
627 {
628 return *table;
629 }
630
632 {
633 return table->asArrowTable();
634 }
635 std::shared_ptr<T> table = nullptr;
636
637 constexpr auto pack()
638 {
639 return index_pack_t{};
640 }
641
642 template <typename Key, typename... Cs>
643 auto build(framework::pack<Cs...>, std::vector<std::shared_ptr<arrow::Table>>&& tables)
644 {
645 this->table = std::make_shared<T>(IP::template indexBuilder<Key, metadata::sources.size(), metadata::sources>(o2::aod::label<T::ref>(), std::forward<std::vector<std::shared_ptr<arrow::Table>>>(tables), framework::pack<Cs...>{}));
646 return (this->table != nullptr);
647 }
648};
649
650template <typename T>
651concept is_builds = requires(T t) {
652 typename T::metadata;
653 typename T::Key;
654 requires std::same_as<decltype(t.pack()), typename T::index_pack_t>;
655};
656
664template <typename T>
665struct OutputObj {
666 using obj_t = T;
667
669 : object(std::make_shared<T>(t)),
670 label(t.GetName()),
671 policy{policy_},
672 sourceType{sourceType_},
673 mTaskHash{0}
674 {
675 }
676
678 : object(nullptr),
679 label(label_),
680 policy{policy_},
681 sourceType{sourceType_},
682 mTaskHash{0}
683 {
684 }
685
686 void setObject(T const& t)
687 {
688 object = std::make_shared<T>(t);
689 object->SetName(label.c_str());
690 }
691
692 void setObject(T&& t)
693 {
694 object = std::make_shared<T>(t);
695 object->SetName(label.c_str());
696 }
697
698 void setObject(T* t)
699 {
700 object.reset(t);
701 object->SetName(label.c_str());
702 }
703
704 void setObject(std::shared_ptr<T> t)
705 {
706 object = t;
707 object->SetName(label.c_str());
708 }
709
710 void setHash(uint32_t hash)
711 {
712 mTaskHash = hash;
713 }
714
717 {
719 auto lhash = runtime_hash(label.c_str());
720 std::memset(desc.str, '_', 16);
721 std::stringstream s;
722 s << std::hex << lhash;
723 s << std::hex << mTaskHash;
724 s << std::hex << reinterpret_cast<uint64_t>(this);
725 std::memcpy(desc.str, s.str().c_str(), 12);
726 return OutputSpec{OutputLabel{label}, "ATSK", desc, 0, Lifetime::QA};
727 }
728
730 {
731 return object.get();
732 }
733
735 {
736 return *object.get();
737 }
738
739 OutputRef ref(uint16_t index, uint16_t max)
740 {
741 return OutputRef{std::string{label}, 0,
743 }
744
745 std::shared_ptr<T> object;
746 std::string label;
749 uint32_t mTaskHash;
750};
751
752template <typename T>
753concept is_outputobj = requires(T t) {
754 &T::setHash;
755 &T::spec;
756 &T::ref;
757 requires std::same_as<decltype(t.operator->()), typename T::obj_t*>;
758 requires std::same_as<decltype(t.object), std::shared_ptr<typename T::obj_t>>;
759};
760
764template <typename T>
765struct Service {
766 using service_t = T;
768
769 decltype(auto) operator->() const
770 {
772 return service->get();
773 } else {
774 return service;
775 }
776 }
777};
778
779template <typename T>
780concept is_service = requires(T t) {
781 requires std::same_as<decltype(t.service), typename T::service_t*>;
782 &T::operator->;
783};
784
786{
787 return std::make_unique<o2::soa::Filtered<std::decay_t<decltype(table)>>>(std::vector{table}, std::forward<soa::SelectionVector>(selection));
788}
789
791{
792 return std::make_unique<o2::soa::Filtered<std::decay_t<decltype(table)>>>(std::vector{table.asArrowTable()}, std::forward<soa::SelectionVector>(selection));
793}
794
795void initializePartitionCaches(std::set<uint32_t> const& hashes, std::shared_ptr<arrow::Schema> const& schema, expressions::Filter const& filter, gandiva::NodePtr& tree, gandiva::FilterPtr& gfilter);
796
797template <typename T>
798struct Partition {
799 using content_t = T;
800 Partition(expressions::Node&& filter_) : filter{std::forward<expressions::Node>(filter_)}
801 {
802 }
803
804 Partition(expressions::Node&& filter_, T const& table)
805 : filter{std::forward<expressions::Node>(filter_)}
806 {
807 setTable(table);
808 }
809
810 void intializeCaches(std::set<uint32_t> const& hashes, std::shared_ptr<arrow::Schema> const& schema)
811 {
813 }
814
815 void bindTable(T const& table)
816 {
817 intializeCaches(T::table_t::hashes(), table.asArrowTable()->schema());
818 if (dataframeChanged) {
820 dataframeChanged = false;
821 }
822 }
823
824 template <typename... Ts>
825 void bindExternalIndices(Ts*... tables)
826 {
827 if (mFiltered != nullptr) {
828 mFiltered->bindExternalIndices(tables...);
829 }
830 }
831
832 template <typename E>
834 {
835 if (mFiltered != nullptr) {
836 mFiltered->bindInternalIndicesTo(ptr);
837 }
838 }
839
841 {
843 }
844
845 [[nodiscard]] std::shared_ptr<arrow::Table> asArrowTable() const
846 {
847 return mFiltered->asArrowTable();
848 }
849
851 {
852 return mFiltered.get();
853 }
854
855 template <typename T1>
856 [[nodiscard]] auto rawSliceBy(o2::framework::Preslice<T1> const& container, int value) const
857 {
858 return mFiltered->rawSliceBy(container, value);
859 }
860
862 {
863 return mFiltered->sliceByCached(node, value, cache);
864 }
865
867 {
868 return mFiltered->sliceByCachedUnsorted(node, value, cache);
869 }
870
871 template <typename T1, typename Policy, bool OPT>
872 [[nodiscard]] auto sliceBy(o2::framework::PresliceBase<T1, Policy, OPT> const& container, int value) const
873 {
874 return mFiltered->sliceBy(container, value);
875 }
876
878 std::unique_ptr<o2::soa::Filtered<T>> mFiltered = nullptr;
879 gandiva::NodePtr tree = nullptr;
881 bool dataframeChanged = true;
882
888 {
889 return mFiltered->begin();
890 }
892 {
893 return mFiltered->end();
894 }
896 {
897 return mFiltered->begin();
898 }
900 {
901 return mFiltered->end();
902 }
903
904 int64_t size() const
905 {
906 return mFiltered->size();
907 }
908};
909
910template <typename T>
911concept is_partition = requires(T t) {
912 &T::updatePlaceholders;
913 requires std::same_as<decltype(t.filter), expressions::Filter>;
914 requires std::same_as<decltype(t.mFiltered), std::unique_ptr<o2::soa::Filtered<typename T::content_t>>>;
915};
916} // namespace o2::framework
917
918namespace o2::soa
919{
921template <soa::is_table T, soa::is_spawnable_column... Cs>
922auto Extend(T const& table)
923{
924 using output_t = Join<T, soa::Table<o2::aod::Hash<"JOIN"_h>, o2::aod::Hash<"JOIN/0"_h>, o2::aod::Hash<"JOIN"_h>, Cs...>>;
925 static std::array<framework::expressions::Projector, sizeof...(Cs)> projectors{{std::move(Cs::Projector())...}};
926 static std::shared_ptr<gandiva::Projector> projector = nullptr;
927 static auto schema = std::make_shared<arrow::Schema>(o2::soa::createFieldsFromColumns(framework::pack<Cs...>{}));
928 return output_t{{o2::framework::spawner(framework::pack<Cs...>{}, {table.asArrowTable()}, "dynamicExtension", projectors.data(), projector, schema), table.asArrowTable()}, 0};
929}
930
933template <soa::is_table T, soa::is_dynamic_column... Cs>
934auto Attach(T const& table)
935{
936 using output_t = Join<T, o2::soa::Table<o2::aod::Hash<"JOIN"_h>, o2::aod::Hash<"JOIN/0"_h>, o2::aod::Hash<"JOIN"_h>, Cs...>>;
937 return output_t{{table.asArrowTable()}, table.offset()};
938}
939} // namespace o2::soa
940
941#endif // o2_framework_AnalysisHelpers_H_DEFINED
std::shared_ptr< arrow::Schema > schema
std::vector< expressions::Projector > projectors
std::vector< std::shared_ptr< gandiva::Expression > > expressions
std::shared_ptr< gandiva::Projector > projector
uint32_t hash
std::unique_ptr< expressions::Node > node
int32_t i
uint16_t pos
Definition RawData.h:3
uint32_t gfilter
Definition RawData.h:6
constexpr uint32_t runtime_hash(char const *str)
nlohmann::json json
TBranch * ptr
Definition A.h:16
iterator const_iterator
Definition ASoA.h:3750
T::template iterator_template_o< FilteredIndexPolicy, self_t > iterator
Definition ASoA.h:3748
Helper to check if a type T is an iterator.
Definition ASoA.h:1279
GLint GLenum GLint x
Definition glcorearb.h:403
const GLfloat * m
Definition glcorearb.h:4066
GLuint64EXT * result
Definition glcorearb.h:5662
GLsizeiptr size
Definition glcorearb.h:659
GLuint index
Definition glcorearb.h:781
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition glcorearb.h:1308
GLuint object
Definition glcorearb.h:4041
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLsizei GLenum * sources
Definition glcorearb.h:2516
GLuint counter
Definition glcorearb.h:3987
std::shared_ptr< gandiva::Filter > FilterPtr
Definition Expressions.h:47
std::variant< OriginValueMatcher, DescriptionValueMatcher, SubSpecificationTypeValueMatcher, std::unique_ptr< DataDescriptorMatcher >, ConstantValueMatcher, StartTimeValueMatcher > Node
std::shared_ptr< gandiva::Projector > createProjectorHelper(size_t nColumns, expressions::Projector *projectors, std::shared_ptr< arrow::Schema > schema, std::vector< std::shared_ptr< arrow::Field > > const &fields)
gandiva::Selection createSelection(std::shared_ptr< arrow::Table > const &table, Filter const &expression)
Function for creating gandiva selection from our internal filter tree.
void updatePlaceholders(Filter &filter, InitContext &context)
Update placeholder nodes from context.
Defining PrimaryVertex explicitly as messageable.
auto spawner(std::shared_ptr< arrow::Table > const &fullTable, const char *name, o2::framework::expressions::Projector *projectors, std::shared_ptr< gandiva::Projector > &projector, std::shared_ptr< arrow::Schema > const &schema)
Expression-based column generator to materialize columns.
typename pack_element< I, T >::type pack_element_t
Definition Pack.h:56
std::string serializeProjectors(std::vector< framework::expressions::Projector > &projectors)
constexpr std::size_t pack_size(pack< Ts... > const &)
template function to determine number of types in a pack
Definition Pack.h:28
std::string serializeSchema(std::shared_ptr< arrow::Schema > &schema)
constexpr auto transformBase()
This helper struct allows you to declare index tables to be created in a task.
memfun_type< decltype(&F::operator())>::type FFL(F const &func)
auto getTableFromFilter(soa::is_filtered_table auto const &table, soa::SelectionVector &&selection)
consteval auto typeWithRef() -> T
Helper to define output for a Table.
OutputObjHandlingPolicy
Policy enum to determine OutputObj handling when writing.
void initializePartitionCaches(std::set< uint32_t > const &hashes, std::shared_ptr< arrow::Schema > const &schema, expressions::Filter const &filter, gandiva::NodePtr &tree, gandiva::FilterPtr &gfilter)
std::shared_ptr< arrow::Table > makeArrowTable(const char *label, std::vector< std::shared_ptr< arrow::ChunkedArray > > &&columns, std::vector< std::shared_ptr< arrow::Field > > &&fields)
auto createFieldsFromColumns(framework::pack< C... >)
Definition ASoA.h:410
SelectionVector selectionToVector(gandiva::Selection const &sel)
Definition ASoA.cxx:48
constexpr auto tableRef2InputSpec()
constexpr auto tableRef2Output()
std::vector< int64_t > SelectionVector
Definition ASoA.h:415
auto Attach(T const &table)
constexpr auto tableRef2ConfigParamSpec()
auto Extend(T const &table)
On-the-fly adding of expression columns.
constexpr auto tableRef2OutputSpec()
constexpr auto tableRef2OutputRef()
@ C
Definition Defs.h:36
Defining DataPointCompositeObject explicitly as copiable.
std::shared_ptr< T > table
constexpr auto pack()
typename T::first_t H
T const & operator*() const
auto build(framework::pack< Cs... >, std::vector< std::shared_ptr< arrow::Table > > &&tables)
metadata::index_pack_t index_pack_t
typename T::rest_t Ts
decltype(transformBase< T >())::metadata metadata
std::shared_ptr< typename T::table_t > table
T::table_t const & operator*() const
decltype(transformBase< T >())::metadata metadata
typename metadata::extension_table_t extension_t
std::array< o2::framework::expressions::Projector, N > projectors
std::shared_ptr< extension_t > extension
std::shared_ptr< arrow::Schema > inputSchema
std::shared_ptr< arrow::Schema > schema
typename metadata::base_table_t base_table_t
static constexpr bool delayed
static constexpr size_t N
typename metadata::placeholders_pack_t placeholders_pack_t
std::shared_ptr< gandiva::Projector > projector
static auto indexBuilder(const char *label, std::vector< std::shared_ptr< arrow::Table > > &&tables, framework::pack< C1, Cs... >)
static OutputSpec const spec()
aod::MetadataTrait< o2::aod::Hash< table_t::ref.desc_hash > >::metadata metadata
decltype(typeWithRef< T >()) table_t
O2 header for OutputObj metadata.
OutputObj(T &&t, OutputObjHandlingPolicy policy_=OutputObjHandlingPolicy::AnalysisObject, OutputObjSourceType sourceType_=OutputObjSourceType::OutputObjSource)
void setObject(std::shared_ptr< T > t)
OutputObjSourceType sourceType
OutputRef ref(uint16_t index, uint16_t max)
std::shared_ptr< T > object
OutputObj(std::string const &label_, OutputObjHandlingPolicy policy_=OutputObjHandlingPolicy::AnalysisObject, OutputObjSourceType sourceType_=OutputObjSourceType::OutputObjSource)
OutputSpec const spec()
OutputObjHandlingPolicy policy
void setHash(uint32_t hash)
Partition(expressions::Node &&filter_, T const &table)
typename o2::soa::Filtered< T >::const_iterator filtered_const_iterator
void bindTable(T const &table)
filtered_const_iterator begin() const
auto rawSliceBy(o2::framework::Preslice< T1 > const &container, int value) const
auto sliceByCached(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
void intializeCaches(std::set< uint32_t > const &hashes, std::shared_ptr< arrow::Schema > const &schema)
Partition(expressions::Node &&filter_)
typename o2::soa::Filtered< T >::iterator filtered_iterator
o2::soa::Filtered< T > * operator->()
typename o2::soa::Filtered< T >::iterator iterator
auto sliceBy(o2::framework::PresliceBase< T1, Policy, OPT > const &container, int value) const
std::shared_ptr< arrow::Table > asArrowTable() const
o2::soa::RowViewSentinel end() const
void updatePlaceholders(InitContext &context)
std::unique_ptr< o2::soa::Filtered< T > > mFiltered
expressions::Filter filter
o2::soa::RowViewSentinel end()
auto sliceByCachedUnsorted(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
typename o2::soa::Filtered< T >::const_iterator const_iterator
gandiva::FilterPtr gfilter
void bindExternalIndices(Ts *... tables)
filtered_iterator begin()
T::table_t * operator->()
std::shared_ptr< gandiva::Projector > projector
std::shared_ptr< extension_t > extension
T::table_t const & operator*() const
static constexpr size_t N
typename metadata::base_table_t base_table_t
std::shared_ptr< arrow::Schema > schema
typename metadata::expression_pack_t expression_pack_t
constexpr auto pack()
std::array< o2::framework::expressions::Projector, N > projectors
decltype(transformBase< T >())::metadata metadata
std::shared_ptr< typename T::table_t > table
typename metadata::extension_table_t extension_t
Helper template for table transformations.
constexpr auto spec() const
constexpr auto output() const
static constexpr auto base_spec()
constexpr auto ref() const
int64_t lastIndex()
Last index inserted in the table.
decltype(FFL(std::declval< cursor_t >())) cursor
bool resetCursor(LifetimeHolder< TableBuilder > builder)
void setLabel(const char *label)
void operator()(Ts &&... args)
decltype([]() { if constexpr(soa::is_iterator< T >) { return typename T::parent_t{nullptr} persistent_table_t
decltype(std::declval< TableBuilder >().cursor< persistent_table_t >()) cursor_t
An expression tree node corresponding to a column binding.
A struct, containing the root of the expression tree.
a move-only header stack with serialized headers This is the flat buffer where all the headers in a m...
Definition Stack.h:33
constexpr size_t max
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))