20#include <TBufferFile.h>
21#include <TDirectory.h>
23#include <TDirectoryFile.h>
25#include <arrow/dataset/file_base.h>
26#include <arrow/filesystem/filesystem.h>
34auto lookForAodFile = [](ConfigParamRegistry& registry,
int argc,
char** argv) ->
bool {
36 if (registry.hasOption(
"aod-file") && registry.isSet(
"aod-file")) {
37 for (
size_t i = 0;
i < argc;
i++) {
38 std::string_view arg = argv[
i];
39 if (arg.starts_with(
"--aod-metadata-")) {
43 O2_SIGNPOST_EVENT_EMIT(capabilities, sid,
"DiscoverMetadataInAODCapability",
"Metadata not found in arguments. Checking in AOD file.");
49auto lookForCommandLineOptions = [](ConfigParamRegistry& registry,
int argc,
char** argv) ->
bool {
51 for (
size_t i = 0;
i < argc;
i++) {
52 std::string_view arg = argv[
i];
53 if (arg.starts_with(
"--aod-metadata-")) {
54 O2_SIGNPOST_EVENT_EMIT(capabilities, sid,
"DiscoverMetadataInCommandLineCapability",
"Metadata found in arguments. Populating from them.");
61auto lookForCommandLineAODOptions = [](ConfigParamRegistry& registry,
int argc,
char** argv) ->
bool {
64 for (
size_t i = 0;
i < argc;
i++) {
65 std::string_view arg = argv[
i];
66 if (arg.starts_with(
"--aod-writer-")) {
67 O2_SIGNPOST_EVENT_EMIT(capabilities, sid,
"DiscoverAODOptionsInCommandLineCapability",
"AOD options found in arguments. Populating from them.");
70 if (arg.starts_with(
"--aod-parent-")) {
71 O2_SIGNPOST_EVENT_EMIT(capabilities, sid,
"DiscoverAODOptionsInCommandLineCapability",
"AOD options found in arguments. Populating from them.");
74 if (arg.starts_with(
"--aod-origin-")) {
75 O2_SIGNPOST_EVENT_EMIT(capabilities, sid,
"DiscoverAODOptionsInCommandLineCapability",
"AOD options found in arguments. Populating from them.");
86 .name =
"DiscoverMetadataInAODCapability",
87 .checkIfNeeded = lookForAodFile,
88 .requiredPlugin =
"O2FrameworkAnalysisSupport:DiscoverMetadataInAOD"};
97 .name =
"DiscoverMetadataInCommandLineCapability",
98 .checkIfNeeded = lookForCommandLineOptions,
99 .requiredPlugin =
"O2Framework:DiscoverMetadataInCommandLine"};
107 .name =
"DiscoverAODOptionsInCommandLineCapability",
108 .checkIfNeeded = lookForCommandLineAODOptions,
109 .requiredPlugin =
"O2Framework:DiscoverAODOptionsInCommandLine"};
118 .discover = [](ConfigParamRegistry& registry,
int argc,
char** argv) -> std::vector<ConfigParamSpec> {
121 "Discovering metadata for analysis from well known environment variables.");
122 std::vector<ConfigParamSpec> results;
123 for (
size_t i = 0;
i < argc;
i++) {
124 std::string_view arg = argv[
i];
125 if (!arg.starts_with(
"--aod-metadata")) {
128 std::string
key = arg.data() + 2;
129 std::string
value = argv[
i + 1];
131 "Found %{public}s with value %{public}s.",
key.c_str(),
value.c_str());
132 if (
key ==
"aod-metadata-tables") {
133 std::stringstream is(
value);
134 auto arrayValue = VariantJSONHelpers::read<VariantType::ArrayString>(is);
135 results.push_back(ConfigParamSpec{
key, VariantType::ArrayString, arrayValue, {
"Metadata in command line"}});
137 results.push_back(ConfigParamSpec{
key, VariantType::String,
value, {
"Metadata in command line"}});
150 .discover = [](ConfigParamRegistry& registry,
int argc,
char** argv) -> std::vector<ConfigParamSpec> {
153 "Discovering AOD handling related options in commandline arguments.");
154 std::vector<ConfigParamSpec> results;
155 bool injectOption =
true;
156 for (
size_t i = 0;
i < argc;
i++) {
157 std::string_view arg = argv[
i];
158 if (!arg.starts_with(
"--aod-writer-") && !arg.starts_with(
"--aod-parent-") && !arg.starts_with(
"--aod-origin-")) {
161 std::string
key = arg.data() + 2;
162 std::string
value = argv[
i + 1];
164 "Found %{public}s with value %{public}s.",
key.c_str(),
value.c_str());
165 if (
key ==
"aod-writer-compression") {
166 int numericValue = std::stoi(
value);
167 results.push_back(ConfigParamSpec{
"aod-writer-compression", VariantType::Int, numericValue, {
"AOD Compression options"}});
168 injectOption =
false;
170 if (
key ==
"aod-parent-base-path-replacement") {
171 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.)"}});
173 if (
key ==
"aod-parent-access-level") {
174 results.push_back(ConfigParamSpec{
"aod-parent-access-level", VariantType::String,
value, {
"Allow parent file access up to specified level. Default: no (0)"}});
176 if (
key ==
"aod-origin-level-mapping") {
177 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\"."}});
181 results.push_back(ConfigParamSpec{
"aod-writer-compression", VariantType::Int, 505, {
"AOD Compression options"}});
188struct ImplementationContext {
189 std::vector<RootArrowFactory> implementations;
192std::function<
void*(std::shared_ptr<arrow::fs::FileSystem>, std::string
const&)> getHandleByClass(
char const* classname)
194 return [
c = TClass::GetClass(classname)](std::shared_ptr<arrow::fs::FileSystem> fs, std::string
const&
path) ->
void* {
195 if (
auto tfileFS = std::dynamic_pointer_cast<TFileFileSystem>(fs)) {
196 return tfileFS->GetFile()->GetObjectChecked(
path.c_str(),
c);
197 }
else if (
auto tbufferFS = std::dynamic_pointer_cast<TBufferFileFS>(fs)) {
198 tbufferFS->GetBuffer()->Reset();
199 return tbufferFS->GetBuffer()->ReadObjectAny(
c);
205std::function<
bool(
char const*)> matchClassByName(std::string_view classname)
207 return [
c = classname](
char const* attempt) ->
bool {
212void lazyLoadFactory(std::vector<RootArrowFactory>& implementations,
char const* specs)
215 if (implementations.empty()) {
216 std::vector<LoadablePlugin> plugins;
218 for (
auto& extra : morePlugins) {
219 plugins.push_back(extra);
221 PluginManager::loadFromPlugin<RootArrowFactory, RootArrowFactoryPlugin>(plugins, implementations);
222 if (implementations.empty()) {
231 auto context =
new ImplementationContext;
236 .lfn2objectPath = [](std::string
s) -> std::string {
237 std::replace(
s.begin()+1,
s.end(),
'/',
'-');
238#if __has_include(<ROOT/RFieldBase.hxx>)
239 if (
s.starts_with(
"/")) {
240 return std::string(
s.begin() + 1,
s.end());
245 if (
s.starts_with(
"/")) {
251#if __has_include(<ROOT/RFieldBase.hxx>)
252 .getHandle = getHandleByClass(
"ROOT::RNTuple"),
253 .checkSupport = matchClassByName(
"ROOT::RNTuple"),
255 .getHandle = getHandleByClass(
"ROOT::Experimental::RNTuple"),
256 .checkSupport = matchClassByName(
"ROOT::Experimental::RNTuple"),
258 .factory = [context]() -> RootArrowFactory& {
259 lazyLoadFactory(context->implementations,
"O2FrameworkAnalysisRNTupleSupport:RNTupleObjectReadingImplementation");
260 return context->implementations.back();
269 auto context =
new ImplementationContext;
273 .lfn2objectPath = [](std::string
s) {
return s; },
274 .getHandle = getHandleByClass(
"TTree"),
275 .checkSupport = matchClassByName(
"TTree"),
276 .accountBytes = [](
void* handle,
size_t& compressed,
size_t& uncompressed) {
277 auto*
tree = (TTree*)handle;
278 compressed +=
tree->GetZipBytes();
279 uncompressed +=
tree->GetTotBytes(); },
280 .factory = [context]() -> RootArrowFactory& {
281 lazyLoadFactory(context->implementations,
"O2FrameworkAnalysisTTreeSupport:TTreeObjectReadingImplementation");
282 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
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))