11#ifndef o2_framework_AnalysisHelpers_H_DEFINED
12#define o2_framework_AnalysisHelpers_H_DEFINED
41 std::string{
"input:"} + o2::aod::label<R>(),
49template <soa::with_sources T>
50inline constexpr auto getSources()
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>();
59template <soa::with_ccdb_urls T>
60inline constexpr auto getCCDBUrls()
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]},
72template <soa::with_sources T>
73constexpr auto getInputMetadata() -> std::vector<framework::ConfigParamSpec>
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());
85 requires(!soa::with_sources<T>)
86constexpr auto getInputMetadata() -> std::vector<framework::ConfigParamSpec>
91template <soa::with_ccdb_urls T>
92constexpr auto getCCDBMetadata() -> std::vector<framework::ConfigParamSpec>
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());
102constexpr auto getCCDBMetadata() -> std::vector<framework::ConfigParamSpec>
107template <soa::with_expression_pack T>
108constexpr auto getExpressionMetadata() -> std::vector<framework::ConfigParamSpec>
110 using expression_pack_t = T::expression_pack_t;
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())), ...);
116 }(expression_pack_t{});
126 requires(!soa::with_expression_pack<T>)
127constexpr auto getExpressionMetadata() -> std::vector<framework::ConfigParamSpec>
137 std::vector<framework::ConfigParamSpec> metadata;
139 metadata.insert(metadata.end(),
m.begin(),
m.end());
141 metadata.insert(metadata.end(), ccdbMetadata.begin(), ccdbMetadata.end());
143 metadata.insert(metadata.end(), p.begin(), p.end());
147 o2::aod::origin<R>(),
148 o2::aod::description(o2::aod::signature<R>()),
150 framework::Lifetime::Timeframe,
159 o2::aod::origin<R>(),
160 o2::aod::description(o2::aod::signature<R>()),
168 o2::aod::origin<R>(),
169 o2::aod::description(o2::aod::signature<R>()),
195template <is_producable T>
201 template <
typename...
Ts>
203 requires(
sizeof...(Ts) ==
framework::pack_size(
typename persistent_table_t::persistent_columns_t{}))
206 cursor(0, extract(args)...);
217 mBuilder = std::move(builder);
225 mBuilder->setLabel(
label);
232 mBuilder->reserve(
typename persistent_table_t::column_types{},
size);
245 return arg.globalIndex();
248 template <
typename A>
250 static decltype(
auto) extract(
A&& arg)
263template <soa::is_table T>
268template <soa::is_iterator T>
269consteval auto typeWithRef() ->
typename T::parent_t
274 requires soa::is_table<T> || soa::is_iterator<T>
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};
286 return OutputRef{aod::label<table_t::ref>(), table_t::ref.version};
294template <is_producable T>
299concept is_produces =
requires(T t) {
typename T::cursor_t;
typename T::persistent_table_t; &T::cursor; };
316template <soa::is_metadata M, soa::TableRef Ref>
321 template <soa::TableRef R>
324 return soa::tableRef2InputSpec<R>();
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()>{});
336 return soa::tableRef2OutputSpec<Ref>();
341 return soa::tableRef2Output<Ref>();
344 constexpr auto ref()
const
346 return soa::tableRef2OutputRef<Ref>();
358template <is_spawnable T>
365template <is_spawnable T>
366struct Spawns : decltype(transformBase<T>()) {
392 std::shared_ptr<typename T::table_t>
table =
nullptr;
396 return {{std::move(C::Projector())...}};
399 std::shared_ptr<gandiva::Projector>
projector =
nullptr;
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>>;
415template <is_dynamically_spawnable T,
bool DELAYED = false>
416struct Defines : decltype(transformBase<T>()) {
443 std::shared_ptr<typename T::table_t>
table =
nullptr;
446 std::array<o2::framework::expressions::Projector, N>
projectors;
447 std::shared_ptr<gandiva::Projector>
projector =
nullptr;
459template <is_dynamically_spawnable 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>;
482template <
typename T,
typename Key>
483inline std::shared_ptr<arrow::ChunkedArray> getIndexToKey(arrow::Table* table)
486 return table->column(framework::has_type_at_v<IC>(
typename T::persistent_columns_t{}));
489template <soa::is_column C>
493 static consteval auto listSize()
495 if constexpr (std::same_as<typename C::type, std::vector<int>>) {
497 }
else if constexpr (std::same_as<int[2], typename C::type>) {
504 template <
typename T,
typename Key>
505 static std::shared_ptr<SelfIndexColumnBuilder> makeColumnBuilder(arrow::Table* table, arrow::MemoryPool* pool)
507 if constexpr (!std::same_as<T, Key>) {
508 return std::make_shared<IndexColumnBuilder>(getIndexToKey<T, Key>(table), C::columnLabel(), listSize(), pool);
510 return std::make_shared<SelfIndexColumnBuilder>(C::columnLabel(), pool);
515template <
typename Key,
typename C>
517 using type =
typename std::conditional<soa::is_binding_compatible_v<Key, typename C::binding_t>(), SelfIndexColumnBuilder, IndexColumnBuilder>
::type;
520template <
typename Key,
typename C>
521using reduced_t = Reduction<Key, C>::type;
524template <
typename Kind>
526 template <
typename Key,
size_t N, std::array<soa::TableRef, N> refs,
typename C1,
typename... Cs>
529 auto pool = arrow::default_memory_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>()));
536 auto sq = std::make_index_sequence<
sizeof...(Cs)>();
538 auto columnBuilders = [&tables, &pool ]<
size_t... Is>(std::index_sequence<Is...>) -> std::array<std::shared_ptr<framework::SelfIndexColumnBuilder>,
sizeof...(Cs)>
540 return {[](arrow::Table* table, arrow::MemoryPool* pool) {
542 if constexpr (!Key::template hasOriginal<refs[Is + 1]>()) {
544 return std::make_shared<IndexColumnBuilder>(table->column(
pos), T::columnLabel(), ColumnTrait<T>::listSize(), pool);
546 return std::make_shared<SelfIndexColumnBuilder>(T::columnLabel(), pool);
548 }(tables[Is + 1].get(), pool)...};
552 std::array<bool,
sizeof...(Cs)> finds;
556 if constexpr (Key::template hasOriginal<refs[0]>()) {
559 idx = keyIndex->valueAt(
counter);
561 finds = [&idx, &columnBuilders]<
size_t... Is>(std::index_sequence<Is...>) {
563 [&idx, &columnBuilders]() {
565 return std::static_pointer_cast<reduced_t<Key, T>>(columnBuilders[Is])->
template find<T>(idx);
568 if constexpr (std::same_as<Kind, Sparse>) {
569 [&idx, &columnBuilders]<
size_t... Is>(std::index_sequence<Is...>) {
570 ([&idx, &columnBuilders]() {
572 return std::static_pointer_cast<reduced_t<Key, T>>(columnBuilders[Is])->
template fill<T>(idx); }(), ...);
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]() {
580 return std::static_pointer_cast<reduced_t<Key, T>>(columnBuilders[Is])->
template fill<T>(idx);
589 return [&
label, &columnBuilders, &self]<
size_t... Is>(std::index_sequence<Is...>) {
591 {self.template
result<C1>(), [&columnBuilders]() {
593 return std::static_pointer_cast<reduced_t<Key, T>>(columnBuilders[Is])->
template result<T>();
595 {self.field(), [&columnBuilders]() {
597 return std::static_pointer_cast<reduced_t<Key, T>>(columnBuilders[Is])->field();
605template <soa::is_index_table T>
612template <soa::is_index_table T>
613struct Builds : decltype(transformBase<T>()) {
617 using Key = metadata::Key;
618 using H =
typename T::first_t;
619 using Ts =
typename T::rest_t;
633 return table->asArrowTable();
642 template <
typename Key,
typename... Cs>
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);
652 typename T::metadata;
654 requires std::same_as<
decltype(t.pack()),
typename T::index_pack_t>;
688 object = std::make_shared<T>(t);
689 object->SetName(
label.c_str());
694 object = std::make_shared<T>(t);
695 object->SetName(
label.c_str());
701 object->SetName(
label.c_str());
707 object->SetName(
label.c_str());
720 std::memset(desc.str,
'_', 16);
722 s << std::hex << lhash;
724 s << std::hex << reinterpret_cast<uint64_t>(
this);
725 std::memcpy(desc.str, s.str().c_str(), 12);
736 return *
object.get();
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>>;
769 decltype(
auto) operator->()
const
781 requires std::same_as<
decltype(t.service),
typename T::service_t*>;
787 return std::make_unique<
o2::soa::Filtered<std::decay_t<
decltype(table)>>>(std::vector{table}, std::forward<soa::SelectionVector>(selection));
792 return std::make_unique<
o2::soa::Filtered<std::decay_t<
decltype(table)>>>(std::vector{table.asArrowTable()}, std::forward<soa::SelectionVector>(selection));
824 template <
typename...
Ts>
828 mFiltered->bindExternalIndices(tables...);
832 template <
typename E>
855 template <
typename T1>
871 template <
typename T1,
typename Policy,
bool OPT>
878 std::unique_ptr<o2::soa::Filtered<T>>
mFiltered =
nullptr;
879 gandiva::NodePtr
tree =
nullptr;
912 &T::updatePlaceholders;
913 requires std::same_as<
decltype(t.filter), expressions::Filter>;
926 static std::shared_ptr<gandiva::Projector>
projector =
nullptr;
937 return output_t{{table.asArrowTable()}, table.offset()};
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
std::unique_ptr< expressions::Node > node
constexpr uint32_t runtime_hash(char const *str)
T::template iterator_template_o< FilteredIndexPolicy, self_t > iterator
Helper to check if a type T is an iterator.
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * value
GLint GLint GLsizei GLint GLenum GLenum type
GLuint GLsizei const GLchar * label
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLboolean GLboolean GLboolean GLboolean a
std::shared_ptr< gandiva::Filter > FilterPtr
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
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
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... >)
SelectionVector selectionToVector(gandiva::Selection const &sel)
constexpr auto tableRef2InputSpec()
constexpr auto tableRef2Output()
std::vector< int64_t > SelectionVector
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()
Defining DataPointCompositeObject explicitly as copiable.
std::shared_ptr< T > table
T const & operator*() const
auto build(framework::pack< Cs... >, std::vector< std::shared_ptr< arrow::Table > > &&tables)
metadata::index_pack_t index_pack_t
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
T::table_t * operator->()
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
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
void setObject(T const &t)
OutputObj(std::string const &label_, OutputObjHandlingPolicy policy_=OutputObjHandlingPolicy::AnalysisObject, OutputObjSourceType sourceType_=OutputObjSourceType::OutputObjSource)
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
void bindInternalIndicesTo(E *ptr)
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
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
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)
void reserve(int64_t size)
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.
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))