Project
Loading...
Searching...
No Matches
inspect.cxx
Go to the documentation of this file.
1// Copyright 2019-2026 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.
11
12// o2-aod-native-inspect <file> [--json]
13//
14// Prints the file header, every top-level key and, per DF and tree, the
15// branch layout and basket locations, using only the ROOT-free reader.
16
17#include "AODNative/Container.h"
18#include "AODNative/Errors.h"
19#include <fmt/format.h>
20#include <cstdio>
21#include <cstring>
22#include <string>
23
24using namespace o2::aod::native;
25
26namespace
27{
28std::string quote(std::string const& s)
29{
30 std::string out = "\"";
31 for (unsigned char c : s) {
32 if (c == '"' || c == '\\') {
33 out += '\\';
34 out += (char)c;
35 } else if (c < 0x20) {
36 out += fmt::format("\\u{:04x}", c);
37 } else {
38 out += (char)c;
39 }
40 }
41 return out + "\"";
42}
43
44char const* boolean(bool b)
45{
46 return b ? "true" : "false";
47}
48
49void printJSON(RootFile& file)
50{
51 auto& h = file.header();
52 fmt::print("{{\n");
53 fmt::print(R"( "header": {{"version": {}, "begin": {}, "end": {}, "seekFree": {}, "nbytesFree": {}, "nfree": {}, )"
54 R"("nbytesName": {}, "units": {}, "compress": {}, "seekInfo": {}, "nbytesInfo": {}}},)"
55 "\n",
56 h.version, h.begin, h.end, h.seekFree, h.nbytesFree, h.nfree, h.nbytesName, (int)h.units, h.compress, h.seekInfo, h.nbytesInfo);
57 fmt::print(R"( "keys": [)");
58 char const* sep = "\n";
59 for (auto& k : file.topKeys()) {
60 fmt::print(R"({} {{"name": {}, "class": {}, "cycle": {}, "seek": {}, "nbytes": {}, "objlen": {}}})",
61 sep, quote(k.name), quote(k.className), k.cycle, k.seekKey, k.nbytes, k.objlen);
62 sep = ",\n";
63 }
64 fmt::print("\n ],\n");
65 fmt::print(R"( "dataFrames": [)");
66 char const* dfSep = "\n";
67 for (auto& df : file.dataFrames()) {
68 fmt::print(R"({} {{"name": {}, "trees": [)", dfSep, quote(df));
69 dfSep = ",\n";
70 char const* treeSep = "\n";
71 for (auto& key : file.keysOf(df)) {
72 if (key.className != "TTree") {
73 continue;
74 }
75 auto tree = file.readTree(key);
76 fmt::print(R"({} {{"name": {}, "entries": {}, "totBytes": {}, "zipBytes": {}, "branches": [)",
77 treeSep, quote(tree.name), tree.entries, tree.totBytes, tree.zipBytes);
78 treeSep = ",\n";
79 char const* branchSep = "\n";
80 for (auto& b : tree.branches) {
81 fmt::print(R"({} {{"name": {}, "leaf": "TLeaf{}", "len": {}, "isUnsigned": {}, "countBranch": {}, )"
82 R"("entries": {}, "totBytes": {}, "zipBytes": {}, "baskets": [)",
83 branchSep, quote(b.name), b.leafClass, b.fixedLen, boolean(b.isUnsigned), quote(b.countBranch),
84 b.entries, b.totBytes, b.zipBytes);
85 branchSep = ",\n";
86 char const* basketSep = "";
87 for (auto& basket : b.baskets) {
88 fmt::print("{}[{}, {}, {}, {}, {}]", basketSep, basket.seek, basket.nbytes, basket.firstEntry, basket.nEntries,
89 boolean(basket.embedded));
90 basketSep = ", ";
91 }
92 fmt::print("]}}");
93 }
94 fmt::print("\n ]}}");
95 }
96 fmt::print("\n ]}}");
97 }
98 fmt::print("\n ]\n}}\n");
99}
100
101void printText(RootFile& file)
102{
103 auto& h = file.header();
104 fmt::print("ROOT file version {}, begin {}, end {}, compression {}, {} seeks\n", h.version, h.begin, h.end, h.compress,
105 h.version >= 1000000 ? "64-bit" : "32-bit");
106 fmt::print("\n{:<32} {:<16} {:>5} {:>14} {:>10} {:>10}\n", "key", "class", "cycle", "seek", "nbytes", "objlen");
107 for (auto& k : file.topKeys()) {
108 fmt::print("{:<32} {:<16} {:>5} {:>14} {:>10} {:>10}\n", k.name, k.className, k.cycle, k.seekKey, k.nbytes, k.objlen);
109 }
110 for (auto& df : file.dataFrames()) {
111 fmt::print("\n{}\n", df);
112 for (auto& key : file.keysOf(df)) {
113 if (key.className != "TTree") {
114 fmt::print(" {} ({}, skipped)\n", key.name, key.className);
115 continue;
116 }
117 auto tree = file.readTree(key);
118 fmt::print(" {}: {} entries, {} bytes, {} compressed\n", tree.name, tree.entries, tree.totBytes, tree.zipBytes);
119 for (auto& b : tree.branches) {
120 fmt::print(" {:<28} TLeaf{}{} len {}{}{}, {} baskets:", b.name, b.leafClass, b.isUnsigned ? " unsigned" : "",
121 b.fixedLen, b.countBranch.empty() ? "" : ", count ", b.countBranch, b.baskets.size());
122 for (auto& basket : b.baskets) {
123 if (basket.embedded) {
124 fmt::print(" [embedded {}+{}]", basket.firstEntry, basket.nEntries);
125 } else {
126 fmt::print(" [{}:{} {}+{}]", basket.seek, basket.nbytes, basket.firstEntry, basket.nEntries);
127 }
128 }
129 fmt::print("\n");
130 }
131 }
132 }
133}
134} // namespace
135
136int main(int argc, char** argv)
137{
138 std::string path;
139 bool json = false;
140 for (int i = 1; i < argc; ++i) {
141 if (std::strcmp(argv[i], "--json") == 0) {
142 json = true;
143 } else if (path.empty()) {
144 path = argv[i];
145 } else {
146 path.clear();
147 break;
148 }
149 }
150 if (path.empty()) {
151 fmt::print(stderr, "usage: {} <file> [--json]\n", argv[0]);
152 return 2;
153 }
154 try {
156 if (json) {
157 printJSON(file);
158 } else {
159 printText(file);
160 }
161 } catch (FormatError const& e) {
162 std::fflush(stdout);
163 fmt::print(stderr, "{}: {}\n", argv[0], e.what());
164 return 1;
165 }
166 return 0;
167}
int32_t i
uint32_t c
Definition RawData.h:2
StringRef key
Class for time synchronization of RawReader instances.
static std::unique_ptr< ByteSource > open(std::string url, const Options &)
GLsizeiptr size
Definition glcorearb.h:659
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLsizei const GLchar *const * path
Definition glcorearb.h:3591
int32_t const char * file
void empty(int)
nlohmann::json json
#define main
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))