20#include <TBufferFile.h>
21#include <TDirectory.h>
22#include <TDirectoryFile.h>
24#include <arrow/dataset/file_base.h>
25#include <arrow/filesystem/filesystem.h>
33auto lookForAodFile = [](ConfigParamRegistry& registry,
int argc,
char** argv) ->
bool {
35 if (registry.hasOption(
"aod-file") && registry.isSet(
"aod-file")) {
36 for (
size_t i = 0;
i < argc;
i++) {
37 std::string_view arg = argv[
i];
38 if (arg.starts_with(
"--aod-metadata-")) {
42 O2_SIGNPOST_EVENT_EMIT(capabilities, sid,
"DiscoverMetadataInAODCapability",
"Metadata not found in arguments. Checking in AOD file.");
48auto lookForCommandLineOptions = [](ConfigParamRegistry& registry,
int argc,
char** argv) ->
bool {
50 for (
size_t i = 0;
i < argc;
i++) {
51 std::string_view arg = argv[
i];
52 if (arg.starts_with(
"--aod-metadata-")) {
53 O2_SIGNPOST_EVENT_EMIT(capabilities, sid,
"DiscoverMetadataInCommandLineCapability",
"Metadata found in arguments. Populating from them.");
60auto lookForCommandLineAODOptions = [](ConfigParamRegistry& registry,
int argc,
char** argv) ->
bool {
63 for (
size_t i = 0;
i < argc;
i++) {
64 std::string_view arg = argv[
i];
65 if (arg.starts_with(
"--aod-writer-")) {
66 O2_SIGNPOST_EVENT_EMIT(capabilities, sid,
"DiscoverAODOptionsInCommandLineCapability",
"AOD options found in arguments. Populating from them.");
69 if (arg.starts_with(
"--aod-parent-")) {
70 O2_SIGNPOST_EVENT_EMIT(capabilities, sid,
"DiscoverAODOptionsInCommandLineCapability",
"AOD options found in arguments. Populating from them.");
73 if (arg.starts_with(
"--aod-origin-")) {
74 O2_SIGNPOST_EVENT_EMIT(capabilities, sid,
"DiscoverAODOptionsInCommandLineCapability",
"AOD options found in arguments. Populating from them.");
85 .name =
"DiscoverMetadataInAODCapability",
86 .checkIfNeeded = lookForAodFile,
87 .requiredPlugin =
"O2FrameworkAnalysisSupport:DiscoverMetadataInAOD"};
96 .name =
"DiscoverMetadataInCommandLineCapability",
97 .checkIfNeeded = lookForCommandLineOptions,
98 .requiredPlugin =
"O2Framework:DiscoverMetadataInCommandLine"};
106 .name =
"DiscoverAODOptionsInCommandLineCapability",
107 .checkIfNeeded = lookForCommandLineAODOptions,
108 .requiredPlugin =
"O2Framework:DiscoverAODOptionsInCommandLine"};
117 .discover = [](ConfigParamRegistry& registry,
int argc,
char** argv) -> std::vector<ConfigParamSpec> {
120 "Discovering metadata for analysis from well known environment variables.");
121 std::vector<ConfigParamSpec> results;
122 for (
size_t i = 0;
i < argc;
i++) {
123 std::string_view arg = argv[
i];
124 if (!arg.starts_with(
"--aod-metadata")) {
127 std::string
key = arg.data() + 2;
128 std::string
value = argv[
i + 1];
130 "Found %{public}s with value %{public}s.",
key.c_str(),
value.c_str());
131 if (
key ==
"aod-metadata-tables") {
132 std::stringstream is(
value);
133 auto arrayValue = VariantJSONHelpers::read<VariantType::ArrayString>(is);
134 results.push_back(ConfigParamSpec{
key, VariantType::ArrayString, arrayValue, {
"Metadata in command line"}});
136 results.push_back(ConfigParamSpec{
key, VariantType::String,
value, {
"Metadata in command line"}});
149 .discover = [](ConfigParamRegistry& registry,
int argc,
char** argv) -> std::vector<ConfigParamSpec> {
152 "Discovering AOD handling related options in commandline arguments.");
153 std::vector<ConfigParamSpec> results;
154 bool injectOption =
true;
155 for (
size_t i = 0;
i < argc;
i++) {
156 std::string_view arg = argv[
i];
157 if (!arg.starts_with(
"--aod-writer-") && !arg.starts_with(
"--aod-parent-") && !arg.starts_with(
"--aod-origin-")) {
160 std::string
key = arg.data() + 2;
161 std::string
value = argv[
i + 1];
163 "Found %{public}s with value %{public}s.",
key.c_str(),
value.c_str());
164 if (
key ==
"aod-writer-compression") {
165 int numericValue = std::stoi(
value);
166 results.push_back(ConfigParamSpec{
"aod-writer-compression", VariantType::Int, numericValue, {
"AOD Compression options"}});
167 injectOption =
false;
169 if (
key ==
"aod-parent-base-path-replacement") {
170 results.push_back(ConfigParamSpec{
"aod-parent-base-path-replacement", VariantType::String,
value, {R
"(Replace base path of parent files. Syntax: FROM;TO. E.g. "alien:///path/in/alien;/local/path". Enclose in "" on the command line.)"}});
172 if (
key ==
"aod-parent-access-level") {
173 results.push_back(ConfigParamSpec{
"aod-parent-access-level", VariantType::String,
value, {
"Allow parent file access up to specified level. Default: no (0)"}});
175 if (
key ==
"aod-origin-level-mapping") {
176 results.push_back(ConfigParamSpec{
"aod-origin-level-mapping", VariantType::String,
value, {
"Map origin to parent level for AOD reading. Syntax: ORIGIN:LEVEL[,ORIGIN2:LEVEL2,...]. E.g. \"DYN:1\"."}});
180 results.push_back(ConfigParamSpec{
"aod-writer-compression", VariantType::Int, 505, {
"AOD Compression options"}});
187struct ImplementationContext {
188 std::vector<RootArrowFactory> implementations;
191std::function<
void*(std::shared_ptr<arrow::fs::FileSystem>, std::string
const&)> getHandleByClass(
char const* classname)
193 return [
c = TClass::GetClass(classname)](std::shared_ptr<arrow::fs::FileSystem> fs, std::string
const&
path) ->
void* {
194 if (
auto tfileFS = std::dynamic_pointer_cast<TFileFileSystem>(fs)) {
195 return tfileFS->GetFile()->GetObjectChecked(
path.c_str(),
c);
196 }
else if (
auto tbufferFS = std::dynamic_pointer_cast<TBufferFileFS>(fs)) {
197 tbufferFS->GetBuffer()->Reset();
198 return tbufferFS->GetBuffer()->ReadObjectAny(
c);
204std::function<
bool(
char const*)> matchClassByName(std::string_view classname)
206 return [
c = classname](
char const* attempt) ->
bool {
211void lazyLoadFactory(std::vector<RootArrowFactory>& implementations,
char const* specs)
214 if (implementations.empty()) {
215 std::vector<LoadablePlugin> plugins;
217 for (
auto& extra : morePlugins) {
218 plugins.push_back(extra);
220 PluginManager::loadFromPlugin<RootArrowFactory, RootArrowFactoryPlugin>(plugins, implementations);
221 if (implementations.empty()) {
230 auto context =
new ImplementationContext;
235 .lfn2objectPath = [](std::string
s) -> std::string {
236 std::replace(
s.begin()+1,
s.end(),
'/',
'-');
237#if __has_include(<ROOT/RFieldBase.hxx>)
238 if (
s.starts_with(
"/")) {
239 return std::string(
s.begin() + 1,
s.end());
244 if (
s.starts_with(
"/")) {
250#if __has_include(<ROOT/RFieldBase.hxx>)
251 .getHandle = getHandleByClass(
"ROOT::RNTuple"),
252 .checkSupport = matchClassByName(
"ROOT::RNTuple"),
254 .getHandle = getHandleByClass(
"ROOT::Experimental::RNTuple"),
255 .checkSupport = matchClassByName(
"ROOT::Experimental::RNTuple"),
257 .factory = [context]() -> RootArrowFactory& {
258 lazyLoadFactory(context->implementations,
"O2FrameworkAnalysisRNTupleSupport:RNTupleObjectReadingImplementation");
259 return context->implementations.back();
268 auto context =
new ImplementationContext;
272 .lfn2objectPath = [](std::string
s) {
return s; },
273 .getHandle = getHandleByClass(
"TTree"),
274 .checkSupport = matchClassByName(
"TTree"),
275 .factory = [context]() -> RootArrowFactory& {
276 lazyLoadFactory(context->implementations,
"O2FrameworkAnalysisTTreeSupport:TTreeObjectReadingImplementation");
277 return context->implementations.back();
#define DEFINE_DPL_PLUGIN_INSTANCE(NAME, KIND)
#define DEFINE_DPL_PLUGINS_END
#define DEFINE_DPL_PLUGINS_BEGIN
#define O2_DECLARE_DYNAMIC_LOG(name)
#define O2_SIGNPOST_ID_GENERATE(name, log)
#define O2_SIGNPOST_EVENT_EMIT(log, id, name, format,...)
GLsizei const GLfloat * value
GLsizei const GLchar *const * path
ConcreteParserVariants< PageSize, BOUNDS_CHECKS > create(T const *buffer, size_t size)
create a raw parser depending on version of RAWDataHeader found at beginning of data
Defining ITS Vertex explicitly as messageable.
@ RootObjectReadingCapability
static std::vector< LoadablePlugin > parsePluginSpecString(char const *str)
Parse a comma separated list of <library>:<plugin-name> plugin declarations.
virtual RootObjectReadingCapability * create()=0