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::soa
30{
32 std::string label;
34 std::string columnLabel;
36 int pos;
37 std::shared_ptr<arrow::DataType> type = [](IndexKind kind) -> std::shared_ptr<arrow::DataType> {
38 switch (kind) {
41 return arrow::int32();
43 return arrow::fixed_size_list(arrow::int32(), 2);
45 return arrow::list(arrow::int32());
46 default:
47 return {nullptr};
48 }
49 }(kind);
50
51 auto operator==(IndexRecord const& other) const
52 {
53 return (this->label == other.label) && (this->columnLabel == other.columnLabel) && (this->kind == other.kind) && (this->pos == other.pos);
54 }
55
56 std::shared_ptr<arrow::Field> field() const
57 {
58 return std::make_shared<arrow::Field>(columnLabel, type);
59 }
60};
61
63 static std::vector<framework::IndexColumnBuilder> makeBuilders(std::vector<std::shared_ptr<arrow::Table>>&& tables, std::vector<soa::IndexRecord> const& records);
64 static void resetBuilders(std::vector<framework::IndexColumnBuilder>& builders, std::vector<std::shared_ptr<arrow::Table>>&& tables);
65
66 static std::shared_ptr<arrow::Table> materialize(std::vector<framework::IndexColumnBuilder>& builders, std::vector<std::shared_ptr<arrow::Table>>&& tables, std::vector<soa::IndexRecord> const& records, std::shared_ptr<arrow::Schema> const& schema, bool exclusive);
67};
68} // namespace o2::soa
69
70namespace o2::framework
71{
72std::shared_ptr<arrow::Table> makeEmptyTableImpl(const char* name, std::shared_ptr<arrow::Schema>& schema);
73
74template <soa::is_table T>
75auto makeEmptyTable(const char* name)
76{
77 auto schema = std::make_shared<arrow::Schema>(soa::createFieldsFromColumns(typename T::table_t::persistent_columns_t{}));
79}
80
81template <soa::TableRef R>
82 requires(soa::not_void<typename aod::MetadataTrait<aod::Hash<R.desc_hash>>::metadata>)
84{
85 auto schema = std::make_shared<arrow::Schema>(soa::createFieldsFromColumns(typename aod::MetadataTrait<aod::Hash<R.desc_hash>>::metadata::persistent_columns_t{}));
86 return makeEmptyTableImpl(o2::aod::label<R>(), schema);
87}
88
89template <typename... Cs>
91{
92 auto schema = std::make_shared<arrow::Schema>(soa::createFieldsFromColumns(p));
94}
95
96template <aod::is_aod_hash D>
98auto makeEmptyTable(const char* name)
99{
100 auto schema = std::make_shared<arrow::Schema>(soa::createFieldsFromColumns(typename aod::MetadataTrait<D>::metadata::persistent_columns_t{}));
102}
103
104std::shared_ptr<arrow::Table> spawnerHelper(std::shared_ptr<arrow::Table> const& fullTable, std::shared_ptr<arrow::Schema> newSchema, size_t nColumns,
105 expressions::Projector* projectors, const char* name, std::shared_ptr<gandiva::Projector>& projector);
106
107std::shared_ptr<arrow::Table> spawnerHelper(std::shared_ptr<arrow::Table> const& fullTable, std::shared_ptr<arrow::Schema> newSchema,
108 const char* name, size_t nColumns,
109 const std::shared_ptr<gandiva::Projector>& projector);
110
112template <aod::is_aod_hash D>
114auto 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)
115{
116 if (fullTable->num_rows() == 0) {
117 return makeEmptyTable<D>(name);
118 }
119 constexpr auto Ncol = []<typename M>() {
121 return framework::pack_size(typename M::placeholders_pack_t{});
122 } else {
123 return framework::pack_size(typename M::expression_pack_t{});
124 }
125 }.template operator()<typename o2::aod::MetadataTrait<D>::metadata>();
126 return spawnerHelper(fullTable, schema, Ncol, projectors, name, projector);
127}
128
129template <typename... C>
130auto spawner(framework::pack<C...>, std::vector<std::shared_ptr<arrow::Table>>&& tables, const char* name, expressions::Projector* projectors, std::shared_ptr<gandiva::Projector>& projector, std::shared_ptr<arrow::Schema> const& schema)
131{
132 std::array<const char*, 1> labels{"original"};
133 auto fullTable = soa::ArrowHelpers::joinTables(std::move(tables), std::span<const char* const>{labels});
134 if (fullTable->num_rows() == 0) {
136 }
137 return spawnerHelper(fullTable, schema, sizeof...(C), projectors, name, projector);
138}
139
140std::string serializeProjectors(std::vector<framework::expressions::Projector>& projectors);
141std::string serializeSchema(std::shared_ptr<arrow::Schema> schema);
142std::string serializeIndexRecords(std::vector<o2::soa::IndexRecord>& irs);
143std::vector<std::shared_ptr<arrow::Table>> extractSources(ProcessingContext& pc, std::vector<std::string> const& labels);
144
145struct Spawner {
146 std::string binding;
147 std::vector<std::string> labels;
148 std::vector<framework::ConcreteDataMatcher> matchers;
149 std::vector<std::shared_ptr<gandiva::Expression>> expressions;
150 std::shared_ptr<gandiva::Projector> projector = nullptr;
151 std::shared_ptr<arrow::Schema> schema = nullptr;
152 std::shared_ptr<arrow::Schema> inputSchema = nullptr;
153
157
158 std::shared_ptr<arrow::Table> materialize(ProcessingContext& pc) const;
159};
160
161struct Builder {
163 std::vector<std::string> labels;
164 std::vector<framework::ConcreteDataMatcher> matchers;
165 std::vector<o2::soa::IndexRecord> records;
166 std::shared_ptr<arrow::Schema> outputSchema;
170
171 std::shared_ptr<std::vector<framework::IndexColumnBuilder>> builders = nullptr;
172
173 std::shared_ptr<arrow::Table> materialize(ProcessingContext& pc);
174};
175} // namespace o2::framework
176
177namespace o2::soa
178{
179template <TableRef R>
181{
183 std::string{"input:"} + o2::aod::label<R>(),
185 aod::sourceSpec<R>(),
186 {"\"\""}};
187}
188
189template <TableRef R>
190constexpr auto tableRef2Schema()
191{
193 std::string{"input-schema:"} + o2::aod::label<R>(),
196 {"\"\""}};
197}
198
199namespace
200{
201template <soa::with_sources T>
202inline constexpr auto getSources()
203{
204 return []<size_t N, std::array<soa::TableRef, N> refs>() {
205 return []<size_t... Is>(std::index_sequence<Is...>) {
206 return std::vector{soa::tableRef2ConfigParamSpec<refs[Is]>()...};
207 }(std::make_index_sequence<N>());
208 }.template operator()<T::sources.size(), T::sources>();
209}
210
211template <soa::with_sources T>
212inline constexpr auto getSourceSchemas()
213{
214 return []<size_t N, std::array<soa::TableRef, N> refs>() {
215 return []<size_t... Is>(std::index_sequence<Is...>) {
216 return std::vector{soa::tableRef2Schema<refs[Is]>()...};
217 }(std::make_index_sequence<N>());
218 }.template operator()<T::sources.size(), T::sources>();
219}
220
221template <soa::with_sources_generator T, aod::is_origin_hash O = o2::aod::Hash<"AOD"_h>>
222inline constexpr auto getSources()
223{
224 return []<size_t N, std::array<soa::TableRef, N> refs>() {
225 return []<size_t... Is>(std::index_sequence<Is...>) {
226 return std::vector{soa::tableRef2ConfigParamSpec<refs[Is]>()...};
227 }(std::make_index_sequence<N>());
228 }.template operator()<T::N, T::template generateSources<O>()>();
229}
230
231template <soa::with_sources_generator T, aod::is_origin_hash O = o2::aod::Hash<"AOD"_h>>
232inline constexpr auto getSourceSchemas()
233{
234 return []<size_t N, std::array<soa::TableRef, N> refs>() {
235 return []<size_t... Is>(std::index_sequence<Is...>) {
236 return std::vector{soa::tableRef2Schema<refs[Is]>()...};
237 }(std::make_index_sequence<N>());
238 }.template operator()<T::N, T::template generateSources<O>()>();
239}
240
241template <soa::with_ccdb_urls T>
242inline constexpr auto getCCDBUrls()
243{
244 std::vector<framework::ConfigParamSpec> result;
245 for (size_t i = 0; i < T::ccdb_urls.size(); ++i) {
246 result.push_back({std::string{"ccdb:"} + std::string{T::ccdb_bindings[i]},
248 T::ccdb_urls[i],
249 {"\"\""}});
250 }
251 return result;
252}
253
254template <typename T>
255 requires(std::same_as<T, int>)
256consteval IndexKind getIndexKind()
257{
259}
260
261template <typename T>
262 requires(std::is_bounded_array_v<T>)
263consteval IndexKind getIndexKind()
264{
265 return IndexKind::IdxSlice;
266}
267
268template <typename T>
269 requires(framework::is_specialization_v<T, std::vector>)
270consteval IndexKind getIndexKind()
271{
272 return IndexKind::IdxArray;
273}
274
275template <soa::with_index_pack T>
276inline constexpr auto getIndexMapping()
277{
278 std::vector<IndexRecord> idx;
279 using indices = T::index_pack_t;
280 using Key = T::Key;
281 [&idx]<size_t... Is>(std::index_sequence<Is...>) mutable {
282 constexpr auto refs = T::generateSources();
283 ([&idx]<TableRef ref, typename C>() mutable {
284 constexpr auto pos = o2::aod::MetadataTrait<o2::aod::Hash<ref.desc_hash>>::metadata::template getIndexPosToKey<Key>();
285 if constexpr (pos == -1) {
286 idx.emplace_back(o2::aod::label<ref>(), o2::aod::matcher<ref>(), C::columnLabel(), IndexKind::IdxSelf, pos);
287 } else {
288 idx.emplace_back(o2::aod::label<ref>(), o2::aod::matcher<ref>(), C::columnLabel(), getIndexKind<typename C::type>(), pos);
289 }
290 }.template operator()<refs[Is], typename framework::pack_element_t<Is, indices>>(),
291 ...);
292 }(std::make_index_sequence<framework::pack_size(indices{})>());
293 ;
294 return idx;
295}
296
297template <soa::with_sources_generator T, aod::is_origin_hash O = o2::aod::Hash<"AOD"_h>>
298constexpr auto getInputMetadata() -> std::vector<framework::ConfigParamSpec>
299{
300 std::vector<framework::ConfigParamSpec> inputMetadata;
301
302 auto inputSources = getSources<T, O>();
303 std::sort(inputSources.begin(), inputSources.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name < b.name; });
304 auto last = std::unique(inputSources.begin(), inputSources.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name == b.name; });
305 inputSources.erase(last, inputSources.end());
306 inputMetadata.insert(inputMetadata.end(), inputSources.begin(), inputSources.end());
307
308 auto inputSchemas = getSourceSchemas<T, O>();
309 std::sort(inputSchemas.begin(), inputSchemas.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name < b.name; });
310 last = std::unique(inputSchemas.begin(), inputSchemas.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name == b.name; });
311 inputSchemas.erase(last, inputSchemas.end());
312 inputMetadata.insert(inputMetadata.end(), inputSchemas.begin(), inputSchemas.end());
313
314 return inputMetadata;
315}
316
317template <soa::with_sources T>
318constexpr auto getInputMetadata() -> std::vector<framework::ConfigParamSpec>
319{
320 std::vector<framework::ConfigParamSpec> inputMetadata;
321
322 auto inputSources = getSources<T>();
323 std::sort(inputSources.begin(), inputSources.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name < b.name; });
324 auto last = std::unique(inputSources.begin(), inputSources.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name == b.name; });
325 inputSources.erase(last, inputSources.end());
326 inputMetadata.insert(inputMetadata.end(), inputSources.begin(), inputSources.end());
327
328 auto inputSchemas = getSourceSchemas<T>();
329 std::sort(inputSchemas.begin(), inputSchemas.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name < b.name; });
330 last = std::unique(inputSchemas.begin(), inputSchemas.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name == b.name; });
331 inputSchemas.erase(last, inputSchemas.end());
332 inputMetadata.insert(inputMetadata.end(), inputSchemas.begin(), inputSchemas.end());
333
334 return inputMetadata;
335}
336
337template <typename T>
338 requires(!(soa::with_sources<T> || soa::with_sources_generator<T>))
339constexpr auto getInputMetadata() -> std::vector<framework::ConfigParamSpec>
340{
341 return {};
342}
343
344template <soa::with_ccdb_urls T>
345constexpr auto getCCDBMetadata() -> std::vector<framework::ConfigParamSpec>
346{
347 std::vector<framework::ConfigParamSpec> results = getCCDBUrls<T>();
348 std::sort(results.begin(), results.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name < b.name; });
349 auto last = std::unique(results.begin(), results.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name == b.name; });
350 results.erase(last, results.end());
351 return results;
352}
353
354template <typename T>
355constexpr auto getCCDBMetadata() -> std::vector<framework::ConfigParamSpec>
356{
357 return {};
358}
359
360template <soa::with_expression_pack T>
361constexpr auto getExpressionMetadata() -> std::vector<framework::ConfigParamSpec>
362{
363 using expression_pack_t = T::expression_pack_t;
364
365 auto projectors = []<typename... C>(framework::pack<C...>) -> std::vector<framework::expressions::Projector> {
366 std::vector<framework::expressions::Projector> result;
367 (result.emplace_back(std::move(C::Projector())), ...);
368 return result;
369 }(expression_pack_t{});
370
372 return {framework::ConfigParamSpec{"projectors", framework::VariantType::String, json, {"\"\""}}};
373}
374
375template <typename T>
376 requires(!soa::with_expression_pack<T>)
377constexpr auto getExpressionMetadata() -> std::vector<framework::ConfigParamSpec>
378{
379 return {};
380}
381
382template <soa::with_index_pack T>
383constexpr auto getIndexMetadata() -> std::vector<framework::ConfigParamSpec>
384{
385 auto map = getIndexMapping<T>();
386 return {framework::ConfigParamSpec{"index-records", framework::VariantType::String, framework::serializeIndexRecords(map), {"\"\""}},
387 {framework::ConfigParamSpec{"index-exclusive", framework::VariantType::Bool, T::exclusive, {"\"\""}}}};
388}
389
390template <typename T>
391 requires(!soa::with_index_pack<T>)
392constexpr auto getIndexMetadata() -> std::vector<framework::ConfigParamSpec>
393{
394 return {};
395}
396
397} // namespace
398
399template <TableRef R>
400constexpr auto tableRef2InputSpec()
401{
402 std::vector<framework::ConfigParamSpec> metadata;
403 std::vector<framework::ConfigParamSpec> sources;
404 if constexpr (soa::with_sources<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata>) {
405 sources = getInputMetadata<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata>();
406 } else if constexpr (soa::with_sources_generator<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata>) {
407 sources = getInputMetadata<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata, o2::aod::Hash<R.origin_hash>>();
408 }
409 metadata.insert(metadata.end(), sources.begin(), sources.end());
410 auto ccdbURLs = getCCDBMetadata<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata>();
411 metadata.insert(metadata.end(), ccdbURLs.begin(), ccdbURLs.end());
412 auto expressions = getExpressionMetadata<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata>();
413 metadata.insert(metadata.end(), expressions.begin(), expressions.end());
414 auto indices = getIndexMetadata<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata>();
415 metadata.insert(metadata.end(), indices.begin(), indices.end());
416 if constexpr (!soa::with_ccdb_urls<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata>) {
418 }
419
421 o2::aod::label<R>(),
422 o2::aod::origin<R>(),
423 o2::aod::description(o2::aod::signature<R>()),
424 R.version,
425 framework::Lifetime::Timeframe,
426 metadata};
427}
428
429template <TableRef R>
430constexpr auto tableRef2OutputSpec()
431{
432 std::vector<framework::ConfigParamSpec> metadata;
433 using md = typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata;
434 if constexpr (soa::with_ccdb_urls<md>) {
435 metadata.emplace_back("ccdb:", framework::VariantType::Bool, true, framework::ConfigParamSpec::HelpString{"\"\""});
436 } else if constexpr (soa::with_expression_pack<md>) {
437 metadata.emplace_back("projectors", framework::VariantType::Bool, true, framework::ConfigParamSpec::HelpString{"\"\""});
438 } else if constexpr (soa::with_index_pack<md>) {
439 metadata.emplace_back("index-records", framework::VariantType::Bool, true, framework::ConfigParamSpec::HelpString{"\"\""});
440 }
442 framework::OutputLabel{o2::aod::label<R>()},
443 o2::aod::origin<R>(),
444 o2::aod::description(o2::aod::signature<R>()),
445 R.version,
446 framework::Lifetime::Timeframe,
447 metadata};
448}
449
450template <TableRef R>
451constexpr auto tableRef2Output()
452{
453 return framework::Output{
454 o2::aod::origin<R>(),
455 o2::aod::description(o2::aod::signature<R>()),
456 R.version};
457}
458
459template <TableRef R>
460constexpr auto tableRef2OutputRef()
461{
463 o2::aod::label<R>(),
464 R.version};
465}
466} // namespace o2::soa
467
468namespace o2::framework
469{
470class TableConsumer;
471
475template <typename T>
477
478template <typename T>
479concept is_enumerated_iterator = requires(T t) { t.globalIndex(); };
480
481template <is_producable T>
483 public:
484 using persistent_table_t = decltype([]() { if constexpr (soa::is_iterator<T>) { return typename T::parent_t{nullptr}; } else { return T{nullptr}; } }());
485 using cursor_t = decltype(std::declval<TableBuilder>().cursor<persistent_table_t>());
486
487 template <typename... Ts>
488 void operator()(Ts&&... args)
489 requires(sizeof...(Ts) == framework::pack_size(typename persistent_table_t::persistent_columns_t{}))
490 {
491 ++mCount;
492 cursor(0, extract(args)...);
493 }
494
496 int64_t lastIndex()
497 {
498 return mCount;
499 }
500
502 {
503 mBuilder = std::move(builder);
504 cursor = std::move(FFL(mBuilder->cursor<persistent_table_t>()));
505 mCount = -1;
506 return true;
507 }
508
509 void setLabel(const char* label)
510 {
511 mBuilder->setLabel(label);
512 }
513
516 void reserve(int64_t size)
517 {
518 mBuilder->reserve(typename persistent_table_t::column_types{}, size);
519 }
520
521 void release()
522 {
523 mBuilder.release();
524 }
525
526 decltype(FFL(std::declval<cursor_t>())) cursor;
527
528 private:
529 static decltype(auto) extract(is_enumerated_iterator auto const& arg)
530 {
531 return arg.globalIndex();
532 }
533
534 template <typename A>
536 static decltype(auto) extract(A&& arg)
537 {
538 return arg;
539 }
540
544 LifetimeHolder<TableBuilder> mBuilder = nullptr;
545 int64_t mCount = -1;
546};
547
549template <soa::is_table T>
550consteval auto typeWithRef() -> T
551{
552}
553
554template <soa::is_iterator T>
555consteval auto typeWithRef() -> typename T::parent_t
556{
557}
558
559template <typename T>
560 requires soa::is_table<T> || soa::is_iterator<T>
562 using table_t = decltype(typeWithRef<T>());
563 using metadata = aod::MetadataTrait<o2::aod::Hash<table_t::ref.desc_hash>>::metadata;
564
565 static constexpr auto spec()
566 {
567 return soa::tableRef2OutputSpec<table_t::ref>();
568 }
569
570 static constexpr auto ref()
571 {
572 return soa::tableRef2OutputRef<table_t::ref>();
573 }
574};
575
580template <is_producable T>
582};
583
584template <typename T>
585concept is_produces = requires(T t) { typename T::cursor_t; typename T::persistent_table_t; &T::cursor; };
586
596};
597
598template <typename T>
599concept is_produces_group = std::derived_from<T, ProducesGroup>;
600
602template <soa::is_metadata M, soa::TableRef Ref>
604 using metadata = M;
605 constexpr static auto sources = M::template generateSources<o2::aod::Hash<Ref.origin_hash>>();
606
607 template <soa::TableRef R>
608 static auto base_spec()
609 {
610 return soa::tableRef2InputSpec<R>();
611 }
612
613 static auto base_specs()
614 {
615 return []<size_t... Is>(std::index_sequence<Is...>) {
616 return std::array{base_spec<sources[Is]>()...};
617 }(std::make_index_sequence<sources.size()>{});
618 }
619
620 static constexpr auto spec()
621 {
622 return soa::tableRef2OutputSpec<Ref>();
623 }
624
625 static constexpr auto output()
626 {
627 return soa::tableRef2Output<Ref>();
628 }
629
630 static constexpr auto ref()
631 {
632 return soa::tableRef2OutputRef<Ref>();
633 }
634};
635
638template <typename T>
639concept is_spawnable = soa::has_metadata<aod::MetadataTrait<o2::aod::Hash<T::originals[T::originals.size() - 1].desc_hash>>> && soa::has_extension<typename aod::MetadataTrait<o2::aod::Hash<T::originals[T::originals.size() - 1].desc_hash>>::metadata>;
640
641template <typename T>
642concept is_dynamically_spawnable = soa::has_metadata<aod::MetadataTrait<o2::aod::Hash<T::originals[T::originals.size() - 1].desc_hash>>> && soa::has_configurable_extension<typename aod::MetadataTrait<o2::aod::Hash<T::originals[T::originals.size() - 1].desc_hash>>::metadata>;
643
644template <is_spawnable T>
645constexpr auto transformBase()
646{
647 using metadata = typename aod::MetadataTrait<o2::aod::Hash<T::originals[T::originals.size() - 1].desc_hash>>::metadata;
648 return TableTransform<metadata, metadata::template extension_table_t_from<o2::aod::Hash<T::originals[T::originals.size() - 1].origin_hash>>::ref>{};
649}
650
651template <is_spawnable T>
652struct Spawns : decltype(transformBase<T>()) {
653 using spawnable_t = T;
654 using metadata = decltype(transformBase<T>())::metadata;
655 using extension_t = typename metadata::template extension_table_t_from<o2::aod::Hash<T::originals[T::originals.size() - 1].origin_hash>>;
656 using expression_pack_t = typename metadata::expression_pack_t;
657 static constexpr size_t N = framework::pack_size(expression_pack_t{});
658
659 typename T::table_t* operator->()
660 {
661 return table.get();
662 }
663 typename T::table_t const& operator*() const
664 {
665 return *table;
666 }
667
669 {
670 return extension->asArrowTable();
671 }
672
673 std::shared_ptr<typename T::table_t> table = nullptr;
674 std::shared_ptr<extension_t> extension = nullptr;
675 std::array<o2::framework::expressions::Projector, N> projectors = []<typename... C>(framework::pack<C...>) -> std::array<expressions::Projector, sizeof...(C)>
676 {
677 return {{std::move(C::Projector())...}};
678 }
680 std::shared_ptr<gandiva::Projector> projector = nullptr;
681 std::shared_ptr<arrow::Schema> schema = []() {
682 auto s = std::make_shared<arrow::Schema>(o2::soa::createFieldsFromColumns(expression_pack_t{}));
683 s->WithMetadata(std::make_shared<arrow::KeyValueMetadata>(std::vector{std::string{"label"}}, std::vector{std::string{o2::aod::label<T::ref>()}}));
684 return s;
685 }();
686};
687
688template <typename T>
689concept is_spawns = requires(T t) {
690 typename T::metadata;
691 typename T::expression_pack_t;
692 requires std::same_as<decltype(t.projector), std::shared_ptr<gandiva::Projector>>;
693};
694
699
700template <is_dynamically_spawnable T, bool DELAYED = false>
701struct Defines : decltype(transformBase<T>()) {
702 static constexpr bool delayed = DELAYED;
703 using spawnable_t = T;
704 using metadata = decltype(transformBase<T>())::metadata;
705 using extension_t = typename metadata::template extension_table_t_from<o2::aod::Hash<T::originals[T::originals.size() - 1].origin_hash>>;
706 using placeholders_pack_t = typename metadata::placeholders_pack_t;
707 static constexpr size_t N = framework::pack_size(placeholders_pack_t{});
708
709 typename T::table_t* operator->()
710 {
711 return table.get();
712 }
713 typename T::table_t const& operator*() const
714 {
715 return *table;
716 }
717
719 {
720 return extension->asArrowTable();
721 }
722 std::shared_ptr<typename T::table_t> table = nullptr;
723 std::shared_ptr<extension_t> extension = nullptr;
724
725 std::array<o2::framework::expressions::Projector, N> projectors;
726 std::shared_ptr<gandiva::Projector> projector = nullptr;
727 std::shared_ptr<arrow::Schema> schema = []() {
728 auto s = std::make_shared<arrow::Schema>(o2::soa::createFieldsFromColumns(placeholders_pack_t{}));
729 s->WithMetadata(std::make_shared<arrow::KeyValueMetadata>(std::vector{std::string{"label"}}, std::vector{std::string{o2::aod::label<T::ref>()}}));
730 return s;
731 }();
732 std::shared_ptr<arrow::Schema> inputSchema = nullptr;
733
734 bool needRecompilation = false;
735
740};
741
742template <is_dynamically_spawnable T>
744
745template <typename T>
746concept is_defines = requires(T t) {
747 typename T::metadata;
748 typename T::placeholders_pack_t;
749 requires std::same_as<decltype(t.projector), std::shared_ptr<gandiva::Projector>>;
750 requires std::same_as<decltype(t.needRecompilation), bool>;
751 &T::recompile;
752};
753
758struct Exclusive {
759};
760struct Sparse {
761};
762
764
765template <soa::is_index_table T>
766constexpr auto transformBase()
767{
768 using metadata = typename aod::MetadataTrait<o2::aod::Hash<T::ref.desc_hash>>::metadata;
770}
771
772template <soa::is_index_table T>
773struct Builds : decltype(transformBase<T>()) {
774 using buildable_t = T;
775 using metadata = decltype(transformBase<T>())::metadata;
776 using Key = metadata::Key;
777 using H = typename T::first_t;
778 using Ts = typename T::rest_t;
779 using index_pack_t = metadata::index_pack_t;
780
781 std::shared_ptr<arrow::Schema> outputSchema = []() { return std::make_shared<arrow::Schema>(soa::createFieldsFromColumns(index_pack_t{}))->WithMetadata(std::make_shared<arrow::KeyValueMetadata>(std::vector{std::string{"label"}}, std::vector{std::string{o2::aod::label<T::ref>()}})); }();
782
783 std::vector<soa::IndexRecord> map = soa::getIndexMapping<metadata>();
784
785 std::vector<framework::IndexColumnBuilder> builders;
786
788 {
789 return table.get();
790 }
791 T const& operator*() const
792 {
793 return *table;
794 }
795
797 {
798 return table->asArrowTable();
799 }
800 std::shared_ptr<T> table = nullptr;
801
802 constexpr auto pack()
803 {
804 return index_pack_t{};
805 }
806
807 auto build(std::vector<std::shared_ptr<arrow::Table>>&& tables)
808 {
809 this->table = std::make_shared<T>(soa::IndexBuilder::materialize(builders, std::forward<std::vector<std::shared_ptr<arrow::Table>>>(tables), map, outputSchema, metadata::exclusive));
810 return (this->table != nullptr);
811 }
812};
813
814template <typename T>
815concept is_builds = requires(T t) {
816 typename T::metadata;
817 typename T::Key;
818 requires std::same_as<decltype(t.map), std::vector<soa::IndexRecord>>;
819};
820
828template <typename T>
829struct OutputObj {
830 using obj_t = T;
831
833 : object(std::make_shared<T>(t)),
834 label(t.GetName()),
835 policy{policy_},
836 sourceType{sourceType_},
837 mTaskHash{0}
838 {
839 }
840
842 : object(nullptr),
843 label(label_),
844 policy{policy_},
845 sourceType{sourceType_},
846 mTaskHash{0}
847 {
848 }
849
850 void setObject(T const& t)
851 {
852 object = std::make_shared<T>(t);
853 object->SetName(label.c_str());
854 }
855
856 void setObject(T&& t)
857 {
858 object = std::make_shared<T>(t);
859 object->SetName(label.c_str());
860 }
861
862 void setObject(T* t)
863 {
864 object.reset(t);
865 object->SetName(label.c_str());
866 }
867
868 void setObject(std::shared_ptr<T> t)
869 {
870 object = t;
871 object->SetName(label.c_str());
872 }
873
874 void setHash(uint32_t hash)
875 {
876 mTaskHash = hash;
877 }
878
881 {
883 auto lhash = runtime_hash(label.c_str());
884 std::memset(desc.str, '_', 16);
885 std::stringstream s;
886 s << std::hex << lhash;
887 s << std::hex << mTaskHash;
888 s << std::hex << reinterpret_cast<uint64_t>(this);
889 std::memcpy(desc.str, s.str().c_str(), 12);
890 return OutputSpec{OutputLabel{label}, "ATSK", desc, 0, Lifetime::QA};
891 }
892
894 {
895 return object.get();
896 }
897
899 {
900 return *object.get();
901 }
902
903 OutputRef ref(uint16_t index, uint16_t max)
904 {
905 return OutputRef{std::string{label}, 0,
907 }
908
909 std::shared_ptr<T> object;
910 std::string label;
913 uint32_t mTaskHash;
914};
915
916template <typename T>
917concept is_outputobj = requires(T t) {
918 &T::setHash;
919 &T::spec;
920 &T::ref;
921 requires std::same_as<decltype(t.operator->()), typename T::obj_t*>;
922 requires std::same_as<decltype(t.object), std::shared_ptr<typename T::obj_t>>;
923};
924
928template <typename T>
929struct Service {
930 using service_t = T;
932
933 decltype(auto) operator->() const
934 {
936 return service->get();
937 } else {
938 return service;
939 }
940 }
941};
942
943template <typename T>
944concept is_service = requires(T t) {
945 requires std::same_as<decltype(t.service), typename T::service_t*>;
946 &T::operator->;
947};
948
950{
951 return std::make_unique<o2::soa::Filtered<std::decay_t<decltype(table)>>>(std::vector{table}, std::forward<soa::SelectionVector>(selection));
952}
953
955{
956 return std::make_unique<o2::soa::Filtered<std::decay_t<decltype(table)>>>(std::vector{table.asArrowTable()}, std::forward<soa::SelectionVector>(selection));
957}
958
959void initializePartitionCaches(std::set<uint32_t> const& hashes, std::shared_ptr<arrow::Schema> const& schema, expressions::Filter const& filter, gandiva::NodePtr& tree, gandiva::FilterPtr& gfilter);
960
961template <typename T>
962struct Partition {
963 using content_t = T;
964 Partition(expressions::Node&& filter_) : filter{std::forward<expressions::Node>(filter_)}
965 {
966 }
967
968 Partition(expressions::Node&& filter_, T const& table)
969 : filter{std::forward<expressions::Node>(filter_)}
970 {
971 setTable(table);
972 }
973
974 void intializeCaches(std::set<uint32_t> const& hashes, std::shared_ptr<arrow::Schema> const& schema)
975 {
977 }
978
979 void bindTable(T const& table)
980 {
981 intializeCaches(T::table_t::hashes(), table.asArrowTable()->schema());
982 if (dataframeChanged) {
984 dataframeChanged = false;
985 }
986 }
987
988 template <typename... Ts>
989 void bindExternalIndices(Ts*... tables)
990 {
991 if (mFiltered != nullptr) {
992 mFiltered->bindExternalIndices(tables...);
993 }
994 }
995
996 template <typename E>
998 {
999 if (mFiltered != nullptr) {
1000 mFiltered->bindInternalIndicesTo(ptr);
1001 }
1002 }
1003
1005 {
1007 }
1008
1009 [[nodiscard]] std::shared_ptr<arrow::Table> asArrowTable() const
1010 {
1011 return mFiltered->asArrowTable();
1012 }
1013
1015 {
1016 return mFiltered.get();
1017 }
1018
1019 template <typename T1>
1020 [[nodiscard]] auto rawSliceBy(o2::framework::Preslice<T1> const& container, int value) const
1021 {
1022 return mFiltered->rawSliceBy(container, value);
1023 }
1024
1026 {
1027 return mFiltered->sliceByCached(node, value, cache);
1028 }
1029
1031 {
1032 return mFiltered->sliceByCachedUnsorted(node, value, cache);
1033 }
1034
1035 template <typename T1, typename Policy, bool OPT>
1036 [[nodiscard]] auto sliceBy(o2::framework::PresliceBase<T1, Policy, OPT> const& container, int value) const
1037 {
1038 return mFiltered->sliceBy(container, value);
1039 }
1040
1042 std::unique_ptr<o2::soa::Filtered<T>> mFiltered = nullptr;
1043 gandiva::NodePtr tree = nullptr;
1045 bool dataframeChanged = true;
1046
1052 {
1053 return mFiltered->begin();
1054 }
1056 {
1057 return mFiltered->end();
1058 }
1060 {
1061 return mFiltered->begin();
1062 }
1064 {
1065 return mFiltered->end();
1066 }
1067
1068 int64_t size() const
1069 {
1070 return mFiltered->size();
1071 }
1072};
1073
1074template <typename T>
1075concept is_partition = requires(T t) {
1076 &T::updatePlaceholders;
1077 requires std::same_as<decltype(t.filter), expressions::Filter>;
1078 requires std::same_as<decltype(t.mFiltered), std::unique_ptr<o2::soa::Filtered<typename T::content_t>>>;
1079};
1080} // namespace o2::framework
1081
1082namespace o2::soa
1083{
1085template <soa::is_table T, soa::is_spawnable_column... Cs>
1086auto Extend(T const& table)
1087{
1088 using output_t = Join<T, soa::Table<o2::aod::Hash<"JOIN"_h>, o2::aod::Hash<"JOIN/0"_h>, o2::aod::Hash<"JOIN"_h>, Cs...>>;
1089 static std::array<framework::expressions::Projector, sizeof...(Cs)> projectors{{std::move(Cs::Projector())...}};
1090 static std::shared_ptr<gandiva::Projector> projector = nullptr;
1091 static auto schema = std::make_shared<arrow::Schema>(o2::soa::createFieldsFromColumns(framework::pack<Cs...>{}));
1092 return output_t{{o2::framework::spawner(framework::pack<Cs...>{}, {table.asArrowTable()}, "dynamicExtension", projectors.data(), projector, schema), table.asArrowTable()}, 0};
1093}
1094
1097template <soa::is_table T, soa::is_dynamic_column... Cs>
1098auto Attach(T const& table)
1099{
1100 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...>>;
1101 return output_t{{table.asArrowTable()}, table.offset()};
1102}
1103} // namespace o2::soa
1104
1105#endif // o2_framework_AnalysisHelpers_H_DEFINED
bool exclusive
std::vector< o2::soa::IndexRecord > records
std::vector< expressions::Projector > projectors
std::vector< std::shared_ptr< gandiva::Expression > > expressions
std::vector< std::string > labels
o2::monitoring::tags::Key Key
uint32_t hash
std::shared_ptr< arrow::Schema > schema
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:3884
T::template iterator_template_o< FilteredIndexPolicy, self_t > iterator
Definition ASoA.h:3882
Helper to check if a type T is an iterator.
Definition ASoA.h:1313
GLuint64EXT * result
Definition glcorearb.h:5662
GLsizeiptr size
Definition glcorearb.h:659
GLuint index
Definition glcorearb.h:781
GLuint const GLchar * name
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
GLsizei GLenum const void * indices
Definition glcorearb.h:400
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
GLint ref
Definition glcorearb.h:291
GLsizei GLenum * sources
Definition glcorearb.h:2516
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 ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
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.
std::string serializeSchema(std::shared_ptr< arrow::Schema > schema)
std::string serializeProjectors(std::vector< framework::expressions::Projector > &projectors)
std::shared_ptr< arrow::Table > spawnerHelper(std::shared_ptr< arrow::Table > const &fullTable, std::shared_ptr< arrow::Schema > newSchema, size_t nColumns, expressions::Projector *projectors, const char *name, std::shared_ptr< gandiva::Projector > &projector)
constexpr std::size_t pack_size(pack< Ts... > const &)
template function to determine number of types in a pack
Definition Pack.h:28
constexpr auto transformBase()
This helper struct allows you to declare index tables to be created in a task.
std::string serializeIndexRecords(std::vector< o2::soa::IndexRecord > &irs)
memfun_type< decltype(&F::operator())>::type FFL(F const &func)
auto getTableFromFilter(soa::is_filtered_table auto const &table, soa::SelectionVector &&selection)
std::vector< std::shared_ptr< arrow::Table > > extractSources(ProcessingContext &pc, std::vector< std::string > const &labels)
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 > makeEmptyTableImpl(const char *name, std::shared_ptr< arrow::Schema > &schema)
auto createFieldsFromColumns(framework::pack< C... >)
Definition ASoA.h:58
SelectionVector selectionToVector(gandiva::Selection const &sel)
Definition ASoA.cxx:48
constexpr auto tableRef2InputSpec()
constexpr auto tableRef2Output()
std::vector< int64_t > SelectionVector
Definition ASoA.h:443
auto Attach(T const &table)
constexpr auto tableRef2Schema()
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
header::DataDescription description
std::vector< o2::soa::IndexRecord > records
std::vector< std::string > labels
std::vector< framework::ConcreteDataMatcher > matchers
header::DataOrigin origin
std::shared_ptr< std::vector< framework::IndexColumnBuilder > > builders
header::DataHeader::SubSpecificationType version
std::shared_ptr< arrow::Schema > outputSchema
std::shared_ptr< arrow::Table > materialize(ProcessingContext &pc)
std::shared_ptr< T > table
constexpr auto pack()
auto build(std::vector< std::shared_ptr< arrow::Table > > &&tables)
std::vector< soa::IndexRecord > map
std::vector< framework::IndexColumnBuilder > builders
std::shared_ptr< arrow::Schema > outputSchema
typename T::first_t H
T const & operator*() const
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
typename metadata::template extension_table_t_from< o2::aod::Hash< T::originals[T::originals.size() - 1].origin_hash > > extension_t
decltype(transformBase< T >())::metadata metadata
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
static constexpr bool delayed
static constexpr size_t N
typename metadata::placeholders_pack_t placeholders_pack_t
std::shared_ptr< gandiva::Projector > projector
static constexpr auto spec()
static constexpr auto ref()
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()
header::DataDescription description
std::vector< std::string > labels
std::vector< std::shared_ptr< gandiva::Expression > > expressions
std::shared_ptr< gandiva::Projector > projector
header::DataOrigin origin
std::vector< framework::ConcreteDataMatcher > matchers
header::DataHeader::SubSpecificationType version
std::shared_ptr< arrow::Schema > schema
std::shared_ptr< arrow::Table > materialize(ProcessingContext &pc) const
std::shared_ptr< arrow::Schema > inputSchema
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
std::shared_ptr< arrow::Schema > schema
typename metadata::expression_pack_t expression_pack_t
std::array< o2::framework::expressions::Projector, N > projectors
decltype(transformBase< T >())::metadata metadata
std::shared_ptr< typename T::table_t > table
typename metadata::template extension_table_t_from< o2::aod::Hash< T::originals[T::originals.size() - 1].origin_hash > > extension_t
Helper template for table transformations.
static constexpr auto spec()
static constexpr auto ref()
static constexpr auto output()
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.
uint32_t SubSpecificationType
Definition DataHeader.h:622
a move-only header stack with serialized headers This is the flat buffer where all the headers in a m...
Definition Stack.h:33
static std::shared_ptr< arrow::Table > joinTables(std::vector< std::shared_ptr< arrow::Table > > &&tables)
Definition ASoA.cxx:72
static void resetBuilders(std::vector< framework::IndexColumnBuilder > &builders, std::vector< std::shared_ptr< arrow::Table > > &&tables)
static std::vector< framework::IndexColumnBuilder > makeBuilders(std::vector< std::shared_ptr< arrow::Table > > &&tables, std::vector< soa::IndexRecord > const &records)
static std::shared_ptr< arrow::Table > materialize(std::vector< framework::IndexColumnBuilder > &builders, std::vector< std::shared_ptr< arrow::Table > > &&tables, std::vector< soa::IndexRecord > const &records, std::shared_ptr< arrow::Schema > const &schema, bool exclusive)
std::shared_ptr< arrow::Field > field() const
auto operator==(IndexRecord const &other) const
framework::ConcreteDataMatcher matcher
constexpr size_t max
VectorOfTObjectPtrs other
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))