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);
143template <is_spawns T>
146 return "control:spawn";
149template <is_builds T>
150const char* controlOption()
152 return "control:build";
155template <is_defines T>
156const char* controlOption()
158 return "control:define";
164template <with_base_table T>
165bool requestInputs(std::vector<InputSpec>& inputs, T
const& entity)
167 auto base_specs = entity.base_specs();
168 for (
auto base_spec : base_specs) {
181template <is_condition C>
182bool newDataframeCondition(
InputRecord& record, C& condition)
184 condition.instance = (
typename C::type*)record.
get<
typename C::type*>(condition.path).get();
188template <is_condition_group C>
189bool newDataframeCondition(
InputRecord& record, C& conditionGroup)
191 homogeneous_apply_refs<true>([&record](
auto&& condition) {
return newDataframeCondition(record, condition); }, conditionGroup);
202template <is_produces T>
203bool appendOutput(std::vector<OutputSpec>& outputs, T&, uint32_t)
209template <is_produces_group T>
210bool appendOutput(std::vector<OutputSpec>& outputs, T& producesGroup, uint32_t hash)
212 homogeneous_apply_refs<true>([&outputs, hash](
auto& produces) {
return appendOutput(outputs, produces, hash); }, producesGroup);
216template <is_histogram_registry T>
217bool appendOutput(std::vector<OutputSpec>& outputs, T& hr, uint32_t hash)
220 outputs.emplace_back(hr.spec());
224template <is_outputobj T>
225bool appendOutput(std::vector<OutputSpec>& outputs, T& obj, uint32_t hash)
228 outputs.emplace_back(obj.spec());
233 requires(is_spawns<T> || is_builds<T> || is_defines<T>)
234bool appendOutput(std::vector<OutputSpec>& outputs, T& entity, uint32_t)
236 outputs.emplace_back(entity.spec());
246template <is_histogram_registry T>
250 context.
outputs().
snapshot(hr.ref(deviceSpec.inputTimesliceId, deviceSpec.maxInputTimeslices), *(hr.getListOfHistograms()));
255template <is_outputobj T>
259 context.
outputs().
snapshot(obj.ref(deviceSpec.inputTimesliceId, deviceSpec.maxInputTimeslices), *obj);
269template <is_produces T>
276template <is_produces_group T>
279 homogeneous_apply_refs<true>([&context](
auto& produces) {
return prepareOutput(context, produces); }, producesGroup);
283template <is_spawns T>
287 auto originalTable =
soa::ArrowHelpers::joinTables(extractOriginals<metadata::sources.
size(), metadata::sources>(context), std::span{metadata::base_table_t::originalLabels});
288 if (originalTable->schema()->fields().empty() ==
true) {
289 using base_table_t =
typename T::base_table_t::table_t;
290 originalTable = makeEmptyTable<base_table_t>(o2::aod::label<metadata::extension_table_t::ref>());
292 using D =
o2::aod::Hash<metadata::extension_table_t::ref.desc_hash>;
294 spawns.extension = std::make_shared<typename T::extension_t>(o2::framework::spawner<D>(originalTable,
295 o2::aod::label<metadata::extension_table_t::ref>(),
296 spawns.projectors.data(),
299 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}));
303template <is_builds T>
307 return builds.template build<typename T::buildable_t::indexing_t>(builds.pack(), extractOriginals<metadata::sources.size(), metadata::sources>(context));
310template <is_defines T>
312 requires(T::delayed ==
false)
315 auto originalTable =
soa::ArrowHelpers::joinTables(extractOriginals<metadata::sources.
size(), metadata::sources>(context), std::span{metadata::base_table_t::originalLabels});
316 if (originalTable->schema()->fields().empty() ==
true) {
317 using base_table_t =
typename T::base_table_t::table_t;
318 originalTable = makeEmptyTable<base_table_t>(o2::aod::label<metadata::extension_table_t::ref>());
320 if (defines.inputSchema ==
nullptr) {
321 defines.inputSchema = originalTable->schema();
323 using D =
o2::aod::Hash<metadata::extension_table_t::ref.desc_hash>;
325 defines.extension = std::make_shared<typename T::extension_t>(o2::framework::spawner<D>(originalTable,
326 o2::aod::label<metadata::extension_table_t::ref>(),
327 defines.projectors.data(),
330 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}));
340template <is_defines T>
341 requires(T::delayed ==
true)
344 if (defines.needRecompilation) {
348 auto originalTable =
soa::ArrowHelpers::joinTables(extractOriginals<metadata::sources.
size(), metadata::sources>(context), std::span{metadata::base_table_t::originalLabels});
349 if (originalTable->schema()->fields().empty() ==
true) {
350 using base_table_t =
typename T::base_table_t::table_t;
351 originalTable = makeEmptyTable<base_table_t>(o2::aod::label<metadata::extension_table_t::ref>());
353 if (defines.inputSchema ==
nullptr) {
354 defines.inputSchema = originalTable->schema();
356 using D =
o2::aod::Hash<metadata::extension_table_t::ref.desc_hash>;
358 defines.extension = std::make_shared<typename T::extension_t>(o2::framework::spawner<D>(originalTable,
359 o2::aod::label<metadata::extension_table_t::ref>(),
360 defines.projectors.data(),
363 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}));
373template <is_produces T>
376 produces.setLabel(o2::aod::label<T::persistent_table_t::ref>());
381template <is_produces_group T>
384 homogeneous_apply_refs<true>([&context](
auto& produces) {
return finalizeOutput(context, produces); }, producesGroup);
388template <is_spawns T>
391 context.outputs().adopt(spawns.output(), spawns.asArrowTable());
395template <is_builds T>
398 context.outputs().adopt(builds.output(), builds.asArrowTable());
402template <is_defines T>
405 context.outputs().adopt(defines.output(), defines.asArrowTable());
416template <is_service T>
417bool addService(std::vector<ServiceSpec>& specs, T&)
420 auto p =
typename T::service_t{};
422 PluginManager::loadFromPlugin<ServiceSpec, ServicePlugin>(loadableServices, specs);
433template <is_service T>
434bool prepareService(
InitContext& context, T& service)
436 using S =
typename T::service_t;
437 if constexpr (
requires { &S::instance; }) {
438 service.service = &(S::instance());
453template <is_service T>
458 if constexpr (
requires { &T::service_t::endOfStream; }) {
459 service.service->endOfStream();
472template <expressions::is_filter T>
479template <is_partition T>
480bool updatePlaceholders(
InitContext& context, T& partition)
482 partition.updatePlaceholders(context);
492template <expressions::is_filter T>
493bool createExpressionTrees(std::vector<ExpressionInfo>& expressionInfos, T&
filter)
505template <is_partition T>
506bool newDataframePartition(T& partition)
508 partition.dataframeChanged =
true;
512template <
typename P,
typename... T>
520 ([&]() {
if constexpr (std::same_as<typename P::content_t, T>) {partition.bindTable(tables);} }(), ...);
523template <
typename P,
typename T>
528template <is_partition P,
typename T>
529void bindInternalIndicesPartition(
P& partition, T* table)
531 if constexpr (o2::soa::is_binding_compatible_v<typename P::content_t, std::decay_t<T>>()) {
532 partition.bindInternalIndicesTo(table);
536template <
typename P,
typename... T>
544 partition.bindExternalIndices(tables...);
560template <is_slice_cache T>
563 if (cache.ptr ==
nullptr) {
570template <
typename C,
typename TG,
typename... Ts>
576static void setGroupedCombination(C& comb, TG& grouping, std::tuple<Ts...>& associated)
578 if constexpr (std::same_as<typename C::g_t, std::decay_t<TG>>) {
579 comb.setTables(grouping, associated);
585 requires(!is_preslice<T> && !is_preslice_group<T>)
591template <is_preslice T>
592 requires std::same_as<typename T::policy_t, framework::PreslicePolicySorted>
595 if constexpr (T::optional) {
596 if (preslice.binding ==
"[MISSING]") {
600 auto locate = std::find_if(bsks.begin(), bsks.end(), [&](
auto const&
entry) { return (entry.binding == preslice.bindingKey.binding) && (entry.key == preslice.bindingKey.key); });
601 if (locate == bsks.end()) {
602 bsks.emplace_back(preslice.getBindingKey());
603 }
else if (locate->enabled ==
false) {
604 locate->enabled =
true;
609template <is_preslice T>
610 requires std::same_as<typename T::policy_t, framework::PreslicePolicyGeneral>
613 if constexpr (T::optional) {
614 if (preslice.binding ==
"[MISSING]") {
618 auto locate = std::find_if(bsksU.begin(), bsksU.end(), [&](
auto const&
entry) { return (entry.binding == preslice.bindingKey.binding) && (entry.key == preslice.bindingKey.key); });
619 if (locate == bsksU.end()) {
620 bsksU.emplace_back(preslice.getBindingKey());
621 }
else if (locate->enabled ==
false) {
622 locate->enabled =
true;
627template <is_preslice_group T>
630 homogeneous_apply_refs<true>([&bsks, &bsksU](
auto& preslice) {
return registerCache(preslice, bsks, bsksU); }, presliceGroup);
641template <is_preslice T>
643 requires std::same_as<typename T::policy_t, framework::PreslicePolicySorted>
645 if constexpr (T::optional) {
646 if (preslice.binding ==
"[MISSING]") {
650 preslice.updateSliceInfo(cache.getCacheFor(preslice.getBindingKey()));
654template <is_preslice T>
656 requires std::same_as<typename T::policy_t, framework::PreslicePolicyGeneral>
658 if constexpr (T::optional) {
659 if (preslice.binding ==
"[MISSING]") {
663 preslice.updateSliceInfo(cache.getCacheUnsortedFor(preslice.getBindingKey()));
667template <is_preslice_group T>
668static bool updateSliceInfo(T& presliceGroup, ArrowTableSlicingCache& cache)
670 homogeneous_apply_refs<true>([&cache](
auto& preslice) {
return updateSliceInfo(preslice, cache); }, presliceGroup);
676static bool setProcessSwitch(std::pair<std::string, bool>, T&)
681template <is_process_configurable T>
682static bool setProcessSwitch(std::pair<std::string, bool> setting, T& pc)
684 if (pc.name == setting.first) {
685 pc.value = setting.second;