Project
Loading...
Searching...
No Matches
o2AO2DToAO3D.cxx
Go to the documentation of this file.
1// Copyright 2019-2024 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
13#include <TDirectory.h>
14#include <TDirectoryFile.h>
15#include <getopt.h>
16#include <TFile.h>
17#include <iostream>
18#include <TMap.h>
19#include <TTree.h>
20#include <fmt/format.h>
21#include <arrow/record_batch.h>
22
23int main(int argc, char** argv)
24{
25
26 char* input_file = nullptr;
27 char* output_file = nullptr;
28
29 // Define long options
30 static struct option long_options[] = {
31 {"input", required_argument, nullptr, 'i'},
32 {"output", required_argument, nullptr, 'o'},
33 {nullptr, 0, nullptr, 0} // End of options
34 };
35
36 int option_index = 0;
37 int c;
38
39 // Parse options
40 while ((c = getopt_long(argc, argv, "i:o:", long_options, &option_index)) != -1) {
41 switch (c) {
42 case 'i':
43 input_file = optarg;
44 break;
45 case 'o':
46 output_file = optarg;
47 break;
48 case '?':
49 // Unknown option
50 printf("Unknown option. Use --input <file> and --output <file>\n");
51 return 1;
52 default:
53 break;
54 }
55 }
56
57 // Check if input and output files are provided
58 if (input_file && output_file) {
59 printf("Input file: %s\n", input_file);
60 printf("Output file: %s\n", output_file);
61 } else {
62 fprintf(stderr, "Usage: %s --input <file> --output <file>\n", argv[0]);
63 return 1;
64 }
65
66 // Plugins which understand
67 std::vector<char const*> capabilitiesSpecs = {
68 "O2Framework:RNTupleObjectReadingCapability",
69 "O2Framework:TTreeObjectReadingCapability",
70 };
71
73
74 std::vector<LoadablePlugin> plugins;
75 for (auto spec : capabilitiesSpecs) {
77 for (auto& extra : morePlugins) {
78 plugins.push_back(extra);
79 }
80 }
81
82 auto in = TFile::Open(input_file, "READ");
83 auto out = TFile::Open(output_file, "RECREATE");
84
85 auto fs = std::make_shared<o2::framework::TFileFileSystem>(in, 50 * 1024 * 1024, factory);
86 auto outFs = std::make_shared<o2::framework::TFileFileSystem>(out, 0, factory);
87
88 o2::framework::PluginManager::loadFromPlugin<o2::framework::RootObjectReadingCapability, o2::framework::RootObjectReadingCapabilityPlugin>(plugins, factory.capabilities);
89
90 // Plugins are hardcoded for now...
91 auto rNtupleFormat = factory.capabilities[0].factory().format();
92 auto format = factory.capabilities[1].factory().format();
93
94 for (TObject* dk : *in->GetListOfKeys()) {
95 if (dk->GetName() == std::string("metaData")) {
96 TMap* m = dynamic_cast<TMap*>(in->Get(dk->GetName()));
97 m->Print();
98 auto* copy = m->Clone("metaData");
99 out->WriteTObject(copy);
100 continue;
101 }
102 if (dk->GetName() == std::string("parentFiles")) {
103 TMap* m = dynamic_cast<TMap*>(in->Get(dk->GetName()));
104 m->Print();
105 auto* copy = m->Clone("parentFiles");
106 out->WriteTObject(copy);
107 continue;
108 }
109 auto* d = (TDirectory*)in->Get(dk->GetName());
110 std::cout << "Processing: " << dk->GetName() << std::endl;
111 // For the moment RNTuple does not support TDirectory, so
112 // we write everything at toplevel.
113 auto destination = outFs->OpenOutputStream("/", {});
114 if (!destination.ok()) {
115 std::cerr << "Could not open destination folder " << output_file << std::endl;
116 exit(1);
117 }
118
119 for (TObject* tk : *d->GetListOfKeys()) {
120 auto sourceUrl = fmt::format("{}/{}", dk->GetName(), tk->GetName());
121 // FIXME: there is no support for TDirectory yet. Let's write everything
122 // at the same level.
123 auto destUrl = fmt::format("/{}-{}", dk->GetName(), tk->GetName());
124 arrow::dataset::FileSource source(sourceUrl, fs);
125 if (!format->IsSupported(source).ok()) {
126 std::cout << "Source " << source.path() << " is not supported" << std::endl;
127 continue;
128 }
129 std::cout << " Processing tree: " << tk->GetName() << std::endl;
130 auto schemaOpt = format->Inspect(source);
131 if (!schemaOpt.ok()) {
132 std::cout << "Could not inspect source " << source.path() << std::endl;
133 }
134 auto schema = *schemaOpt;
135 auto fragment = format->MakeFragment(source, {}, schema);
136 if (!fragment.ok()) {
137 std::cout << "Could not make fragment from " << source.path() << "with schema:" << schema->ToString() << std::endl;
138 continue;
139 }
140 auto options = std::make_shared<arrow::dataset::ScanOptions>();
141 options->dataset_schema = schema;
142 auto scanner = format->ScanBatchesAsync(options, *fragment);
143 if (!scanner.ok()) {
144 std::cout << "Scanner not ok" << std::endl;
145 continue;
146 }
147 auto batches = (*scanner)();
148 auto result = batches.result();
149 if (!result.ok()) {
150 std::cout << "Could not get batches." << std::endl;
151 continue;
152 }
153 std::cout << " Found a table with " << (*result)->columns().size() << " columns " << (*result)->num_rows() << " rows." << std::endl;
154
155 if ((*result)->num_rows() == 0) {
156 std::cout << "Empty table, skipping for now" << std::endl;
157 continue;
158 }
159 arrow::fs::FileLocator locator{outFs, destUrl};
160 std::cout << schema->ToString() << std::endl;
161 auto writer = rNtupleFormat->MakeWriter(*destination, schema, {}, locator);
162 auto success = writer->get()->Write(*result);
163 if (!success.ok()) {
164 std::cout << "Error while writing" << std::endl;
165 continue;
166 }
167 }
168 out->ls();
169 auto rootDestination = std::dynamic_pointer_cast<o2::framework::TDirectoryFileOutputStream>(*destination);
170 }
171 in->Close();
172 out->Close();
173}
uint32_t c
Definition RawData.h:2
const GLfloat * m
Definition glcorearb.h:4066
GLuint64EXT * result
Definition glcorearb.h:5662
GLsizei GLsizei GLchar * source
Definition glcorearb.h:798
GLint GLint GLsizei GLint GLenum format
Definition glcorearb.h:275
static std::vector< LoadablePlugin > parsePluginSpecString(char const *str)
Parse a comma separated list of <library>:<plugin-name> plugin declarations.
std::vector< RootObjectReadingCapability > capabilities
#define main