57namespace analysis_task_parsers
67template <is_configurable O>
68bool appendOption(std::vector<ConfigParamSpec>& options, O& option)
73template <is_configurable_group O>
74bool appendOption(std::vector<ConfigParamSpec>& options, O& optionGroup)
76 if constexpr (
requires { optionGroup.prefix; }) {
77 homogeneous_apply_refs<true>([prefix = optionGroup.prefix]<
typename C>(C& option) {
78 if constexpr (requires { option.name; }) {
79 option.name.insert(0, 1,
'.');
80 option.name.insert(0, prefix);
86 homogeneous_apply_refs<true>([&options](
auto& option) {
return appendOption(options, option); }, optionGroup);
96template <is_configurable O>
97bool prepareOption(
InitContext& context, O& configurable)
100 configurable.value = context.
options().
get<
typename O::type>(configurable.name.c_str());
102 auto pt = context.
options().
get<boost::property_tree::ptree>(configurable.name.c_str());
103 configurable.value = RootConfigParamHelpers::as<typename O::type>(pt);
108template <is_configurable_group O>
109bool prepareOption(InitContext& context, O& configurableGroup)
111 homogeneous_apply_refs<true>([&context](
auto&& configurable) {
return prepareOption(context, configurable); }, configurableGroup);
122template <is_condition C>
123bool appendCondition(std::vector<InputSpec>& inputs, C& condition)
129template <is_condition_group C>
130bool appendCondition(std::vector<InputSpec>& inputs, C& conditionGroup)
132 homogeneous_apply_refs<true>([&inputs](
auto& condition) {
return appendCondition(inputs, condition); }, conditionGroup);
154template <is_spawns T>
157 return "control:spawn";
160template <is_builds T>
161const char* controlOption()
163 return "control:build";
166template <is_defines T>
167const char* controlOption()
169 return "control:define";
172template <with_required_inputs T>
175 entity.requiredInputs = entity.getRequiredInputs(newOrigin);
176 for (
auto base_spec : entity.requiredInputs) {
186template <with_updateable_output T>
189 entity.outputSpec = entity.updateOutputSpec(newOrigin);
193template <is_produces_group T>
196 homogeneous_apply_refs<true>([&newOrigin](
auto& produces) {
return updateOutputSpec(produces, newOrigin); }, producesGroup);
206template <is_condition C>
207bool newDataframeCondition(
InputRecord& record, C& condition)
209 condition.instance = (
typename C::type*)record.
get<
typename C::type*>(condition.path).release();
213template <is_condition_group C>
214bool newDataframeCondition(
InputRecord& record, C& conditionGroup)
216 homogeneous_apply_refs<true>([&record](
auto&& condition) {
return newDataframeCondition(record, condition); }, conditionGroup);
227template <is_produces T>
228constexpr bool appendOutput(std::vector<OutputSpec>& outputs, T& produces, uint32_t)
230 outputs.emplace_back(produces.outputSpec);
234template <is_produces_group T>
235constexpr bool appendOutput(std::vector<OutputSpec>& outputs, T& producesGroup, uint32_t
hash)
237 homogeneous_apply_refs<true>([&outputs,
hash](
auto& produces) {
return appendOutput(outputs, produces,
hash); }, producesGroup);
241template <is_histogram_registry T>
245 outputs.emplace_back(hr.spec());
249template <is_outputobj T>
250bool appendOutput(std::vector<OutputSpec>& outputs, T& obj, uint32_t
hash)
253 outputs.emplace_back(obj.spec());
258 requires(is_spawns<T> || is_builds<T> || is_defines<T>)
259bool appendOutput(std::vector<OutputSpec>& outputs, T& entity, uint32_t)
261 outputs.emplace_back(entity.outputSpec);
271template <is_histogram_registry T>
275 auto sendHistos = [deviceSpec, &context](
HistogramRegistry const& self, TNamed* obj)
mutable {
276 context.
outputs().
snapshot(self.ref(deviceSpec.inputTimesliceId, deviceSpec.maxInputTimeslices), *obj);
278 hr.apply(sendHistos);
283template <is_outputobj T>
284bool postRunOutput(EndOfStreamContext& context, T& obj)
287 context.
outputs().snapshot(obj.ref(deviceSpec.inputTimesliceId, deviceSpec.maxInputTimeslices), *obj);
297template <is_produces T>
305template <is_produces_group T>
308 homogeneous_apply_refs<true>([&context](
auto& produces) {
return prepareOutput(context, produces); }, producesGroup);
312template <is_spawns T>
316 auto originalTable =
soa::ArrowHelpers::joinTables(framework::extractTablesFromRecord(context.inputs(), spawns.requiredInputs | std::views::transform([](
auto const& input) { return DataSpecUtils::asConcreteDataMatcher(input); })));
317 if (originalTable->num_rows() == 0) {
318 originalTable =
makeEmptyTable(
"EMPTY",
typename metadata::base_table_t::persistent_columns_t{});
320 using D =
o2::aod::Hash<metadata::extension_table_t::ref.desc_hash>;
322 spawns.extension = std::make_shared<typename T::extension_t>(o2::framework::spawner<D>(originalTable,
323 o2::aod::label<metadata::extension_table_t::ref>(),
324 spawns.projectors.data(),
327 spawns.table = std::make_shared<typename T::spawnable_t::table_t>(
soa::ArrowHelpers::joinTables({spawns.extension->asArrowTable(), originalTable}, std::span{T::spawnable_t::table_t::originalLabels}));
331template <is_builds T>
334 return builds.build(framework::extractTablesFromRecord(context.inputs(), builds.requiredInputs | std::views::transform([](
auto const& input) { return DataSpecUtils::asConcreteDataMatcher(input); })));
337template <is_defines T>
339 requires(T::delayed ==
false)
342 auto originalTable =
soa::ArrowHelpers::joinTables(framework::extractTablesFromRecord(context.inputs(), defines.requiredInputs | std::views::transform([](
auto const& input) { return DataSpecUtils::asConcreteDataMatcher(input); })));
343 if (originalTable->num_rows() == 0) {
344 originalTable =
makeEmptyTable(
"EMPTY",
typename metadata::base_table_t::persistent_columns_t{});
346 if (defines.inputSchema ==
nullptr) {
347 defines.inputSchema = originalTable->schema();
349 using D =
o2::aod::Hash<metadata::extension_table_t::ref.desc_hash>;
351 defines.extension = std::make_shared<typename T::extension_t>(o2::framework::spawner<D>(originalTable,
352 o2::aod::label<metadata::extension_table_t::ref>(),
353 defines.projectors.data(),
356 defines.table = std::make_shared<typename T::spawnable_t::table_t>(
soa::ArrowHelpers::joinTables({defines.extension->asArrowTable(), originalTable}, std::span{T::spawnable_t::table_t::originalLabels}));
366template <is_defines T>
367 requires(T::delayed ==
true)
370 if (defines.needRecompilation) {
374 auto originalTable =
soa::ArrowHelpers::joinTables(framework::extractTablesFromRecord(context.
inputs(), defines.requiredInputs | std::views::transform([](
auto const& input) { return DataSpecUtils::asConcreteDataMatcher(input); })));
375 if (originalTable->num_rows() == 0) {
376 originalTable = makeEmptyTable<metadata::base_table_t::ref>();
378 if (defines.inputSchema ==
nullptr) {
379 defines.inputSchema = originalTable->schema();
381 using D =
o2::aod::Hash<metadata::extension_table_t::ref.desc_hash>;
383 defines.extension = std::make_shared<typename T::extension_t>(o2::framework::spawner<D>(originalTable,
384 o2::aod::label<metadata::extension_table_t::ref>(),
385 defines.projectors.data(),
388 defines.table = std::make_shared<typename T::spawnable_t::table_t>(
soa::ArrowHelpers::joinTables({defines.extension->asArrowTable(), originalTable}, std::span{T::spawnable_t::table_t::originalLabels}));
398template <is_produces T>
401 produces.setLabel(o2::aod::label<T::persistent_table_t::ref>());
406template <is_produces_group T>
409 homogeneous_apply_refs<true>([&context](
auto& produces) {
return finalizeOutput(context, produces); }, producesGroup);
413template <is_spawns T>
421template <is_builds T>
429template <is_defines T>
444template <is_service T>
445bool addService(std::vector<ServiceSpec>& specs, T&)
448 auto p =
typename T::service_t{};
450 PluginManager::loadFromPlugin<ServiceSpec, ServicePlugin>(loadableServices, specs);
461template <is_service T>
462bool prepareService(
InitContext& context, T& service)
464 using S =
typename T::service_t;
465 if constexpr (
requires { &S::instance; }) {
466 service.service = &(S::instance());
481template <is_service T>
486 if constexpr (
requires { &T::service_t::endOfStream; }) {
487 service.service->endOfStream();
500template <expressions::is_filter T>
507template <is_partition T>
508bool updatePlaceholders(
InitContext& context, T& partition)
510 partition.updatePlaceholders(context);
520template <expressions::is_filter T>
521bool createExpressionTrees(std::vector<ExpressionInfo>& expressionInfos, T&
filter)
533template <is_partition T>
534bool newDataframePartition(T& partition)
536 partition.dataframeChanged =
true;
540template <
typename P,
typename... T>
548 ([&]() {
if constexpr (std::same_as<typename P::content_t, T>) {partition.bindTable(tables);} }(), ...);
551template <
typename P,
typename T>
556template <is_partition P,
typename T>
557void bindInternalIndicesPartition(
P& partition, T* table)
559 if constexpr (o2::soa::is_binding_compatible_v<typename P::content_t, std::decay_t<T>>()) {
560 partition.bindInternalIndicesTo(table);
564template <
typename P,
typename... T>
572 partition.bindExternalIndices(tables...);
582template <is_slice_cache T>
585 if (cache.ptr ==
nullptr) {
592template <
typename C,
typename TG,
typename... Ts>
598static void setGroupedCombination(C& comb, TG& grouping, std::tuple<Ts...>& associated)
600 if constexpr (std::same_as<typename C::g_t, std::decay_t<TG>>) {
601 comb.setTables(grouping, associated);
607 requires(!is_preslice<T> && !is_preslice_group<T>)
613template <is_preslice T>
616 if ((T::target_t::binding_origin ==
"AOD"_h) && (newOrigin !=
header::DataOrigin{
"AOD"})) {
623template <is_preslice_group T>
626 homogeneous_apply_refs<true>([&newOrigin](
auto& preslice) {
return replaceOrigin(preslice, newOrigin); }, presliceGroup);
631 requires(!is_preslice<T> && !is_preslice_group<T>)
637template <is_preslice T>
638 requires std::same_as<typename T::policy_t, framework::PreslicePolicySorted>
641 if constexpr (T::optional) {
642 if (preslice.binding ==
"[MISSING]") {
646 auto locate = std::find(bsks.begin(), bsks.end(), preslice.getBindingKey());
647 if (locate == bsks.end()) {
648 bsks.emplace_back(preslice.getBindingKey());
649 }
else if (locate->enabled ==
false) {
650 locate->enabled =
true;
655template <is_preslice T>
656 requires std::same_as<typename T::policy_t, framework::PreslicePolicyGeneral>
659 if constexpr (T::optional) {
660 if (preslice.binding ==
"[MISSING]") {
664 auto locate = std::find(bsksU.begin(), bsksU.end(), preslice.getBindingKey());
665 if (locate == bsksU.end()) {
666 bsksU.emplace_back(preslice.getBindingKey());
667 }
else if (locate->enabled ==
false) {
668 locate->enabled =
true;
673template <is_preslice_group T>
676 homogeneous_apply_refs<true>([&bsks, &bsksU](
auto& preslice) {
return registerCache(preslice, bsks, bsksU); }, presliceGroup);
687template <is_preslice T>
689 requires std::same_as<typename T::policy_t, framework::PreslicePolicySorted>
691 if constexpr (T::optional) {
692 if (preslice.binding ==
"[MISSING]") {
696 preslice.updateSliceInfo(cache.getCacheFor(preslice.getBindingKey()));
700template <is_preslice T>
702 requires std::same_as<typename T::policy_t, framework::PreslicePolicyGeneral>
704 if constexpr (T::optional) {
705 if (preslice.binding ==
"[MISSING]") {
709 preslice.updateSliceInfo(cache.getCacheUnsortedFor(preslice.getBindingKey()));
713template <is_preslice_group T>
714static bool updateSliceInfo(T& presliceGroup, ArrowTableSlicingCache& cache)
716 homogeneous_apply_refs<true>([&cache](
auto& preslice) {
return updateSliceInfo(preslice, cache); }, presliceGroup);
722static bool setProcessSwitch(std::pair<std::string, bool>, T&)
727template <is_process_configurable T>
728static bool setProcessSwitch(std::pair<std::string, bool> setting, T& pc)
730 if (pc.name == setting.first) {
731 pc.value = setting.second;