Skip to content

Commit b91adae

Browse files
committed
DPL: read metadata from parent files
If the metadata is not found in the main file and if there is a list of parent files, try those as well.
1 parent f422114 commit b91adae

File tree

1 file changed

+77
-26
lines changed

1 file changed

+77
-26
lines changed

Framework/AnalysisSupport/src/Plugin.cxx

Lines changed: 77 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <TObjString.h>
2323
#include <TString.h>
2424
#include <fmt/format.h>
25+
#include <memory>
2526

2627
O2_DECLARE_DYNAMIC_LOG(analysis_support);
2728

@@ -65,7 +66,7 @@ struct RunSummary : o2::framework::ServicePlugin {
6566
}
6667
};
6768

68-
std::vector<std::string> getListOfTables(TFile* f)
69+
std::vector<std::string> getListOfTables(std::unique_ptr<TFile>& f)
6970
{
7071
std::vector<std::string> r;
7172
TList* keyList = f->GetListOfKeys();
@@ -83,19 +84,44 @@ std::vector<std::string> getListOfTables(TFile* f)
8384
}
8485
return r;
8586
}
87+
auto readMetadata(std::unique_ptr<TFile>& currentFile) -> std::vector<ConfigParamSpec>
88+
{
89+
// Get the metadata, if any
90+
auto m = (TMap*)currentFile->Get("metaData");
91+
if (!m) {
92+
return {};
93+
}
94+
std::vector<ConfigParamSpec> results;
95+
auto it = m->MakeIterator();
96+
97+
// Serialise metadata into a ; separated string with : separating key and value
98+
bool first = true;
99+
while (auto obj = it->Next()) {
100+
if (first) {
101+
LOGP(info, "Metadata for file \"{}\":", currentFile->GetName());
102+
first = false;
103+
}
104+
auto objString = (TObjString*)m->GetValue(obj);
105+
LOGP(info, "- {}: {}", obj->GetName(), objString->String().Data());
106+
std::string key = "aod-metadata-" + std::string(obj->GetName());
107+
char const* value = strdup(objString->String());
108+
results.push_back(ConfigParamSpec{key, VariantType::String, value, {"Metadata in AOD"}});
109+
}
110+
111+
return results;
112+
}
86113

87114
struct DiscoverMetadataInAOD : o2::framework::ConfigDiscoveryPlugin {
88115
ConfigDiscovery* create() override
89116
{
90117
return new ConfigDiscovery{
91118
.init = []() {},
92119
.discover = [](ConfigParamRegistry& registry, int argc, char** argv) -> std::vector<ConfigParamSpec> {
120+
std::string parentFileReplacement;
93121
auto filename = registry.get<std::string>("aod-file");
94122
if (filename.empty()) {
95123
return {};
96124
}
97-
std::vector<ConfigParamSpec> results;
98-
TFile* currentFile = nullptr;
99125
if (filename.at(0) == '@') {
100126
filename.erase(0, 1);
101127
// read the text file and set filename to the contents of the first line
@@ -110,39 +136,64 @@ struct DiscoverMetadataInAOD : o2::framework::ConfigDiscoveryPlugin {
110136
TGrid::Connect("alien://");
111137
}
112138
LOGP(info, "Loading metadata from file {} in PID {}", filename, getpid());
113-
currentFile = TFile::Open(filename.c_str());
114-
if (!currentFile) {
139+
std::unique_ptr<TFile> currentFile{TFile::Open(filename.c_str())};
140+
if (currentFile.get() == nullptr) {
115141
LOGP(fatal, "Couldn't open file \"{}\"!", filename);
116142
}
143+
std::vector<ConfigParamSpec> results = readMetadata(currentFile);
144+
// Found metadata already in the main file.
145+
if (!results.empty()) {
146+
auto tables = getListOfTables(currentFile);
147+
if (tables.empty() == false) {
148+
results.push_back(ConfigParamSpec{"aod-metadata-tables", VariantType::ArrayString, tables, {"Tables in first AOD"}});
149+
}
150+
results.push_back(ConfigParamSpec{"aod-metadata-source", VariantType::String, filename, {"File from which the metadata was extracted."}});
151+
return results;
152+
}
117153

118-
// Get the metadata, if any
119-
auto m = (TMap*)currentFile->Get("metaData");
120-
if (!m) {
154+
// Lets try in parent files
155+
auto parentFiles = (TMap*)currentFile->Get("parentFiles");
156+
if (!parentFiles) {
121157
LOGP(info, "No metadata found in file \"{}\"", filename);
122158
results.push_back(ConfigParamSpec{"aod-metadata-disable", VariantType::String, "1", {"Metadata not found in AOD"}});
123159
return results;
124160
}
125-
auto it = m->MakeIterator();
126-
127-
// Serialise metadata into a ; separated string with : separating key and value
128-
bool first = true;
129-
while (auto obj = it->Next()) {
130-
if (first) {
131-
LOGP(info, "Metadata for file \"{}\":", filename);
132-
first = false;
161+
for (auto* p : *parentFiles) {
162+
std::string parentFilename = ((TPair*)p)->Value()->GetName();
163+
// Do the replacement. Notice this will require changing aod-parent-base-path-replacement to be
164+
// a workflow option (because the metadata itself is potentially changing the topology).
165+
if (registry.isSet("aod-parent-base-path-replacement")) {
166+
parentFileReplacement = registry.get<std::string>("aod-parent-base-path-replacement");
167+
auto pos = parentFileReplacement.find(';');
168+
if (pos == std::string::npos) {
169+
throw std::runtime_error(fmt::format("Invalid syntax in aod-parent-base-path-replacement: \"{}\"", parentFileReplacement.c_str()));
170+
}
171+
auto from = parentFileReplacement.substr(0, pos);
172+
auto to = parentFileReplacement.substr(pos + 1);
173+
pos = parentFilename.find(from);
174+
if (pos != std::string::npos) {
175+
parentFilename.replace(pos, from.length(), to);
176+
}
133177
}
134-
auto objString = (TObjString*)m->GetValue(obj);
135-
LOGP(info, "- {}: {}", obj->GetName(), objString->String().Data());
136-
std::string key = "aod-metadata-" + std::string(obj->GetName());
137-
char const* value = strdup(objString->String());
138-
results.push_back(ConfigParamSpec{key, VariantType::String, value, {"Metadata in AOD"}});
139-
}
140178

141-
auto tables = getListOfTables(currentFile);
142-
if (tables.empty() == false) {
143-
results.push_back(ConfigParamSpec{"aod-metadata-tables", VariantType::ArrayString, tables, {"Tables in first AOD"}});
179+
std::unique_ptr<TFile> parentFile{TFile::Open(parentFilename.c_str())};
180+
if (parentFile.get() == nullptr) {
181+
LOGP(fatal, "Couldn't open derived file \"{}\"!", parentFilename);
182+
}
183+
results = readMetadata(parentFile);
184+
// Found metadata already in the main file.
185+
if (!results.empty()) {
186+
auto tables = getListOfTables(parentFile);
187+
if (tables.empty() == false) {
188+
results.push_back(ConfigParamSpec{"aod-metadata-tables", VariantType::ArrayString, tables, {"Tables in first AOD"}});
189+
}
190+
results.push_back(ConfigParamSpec{"aod-metadata-source", VariantType::String, filename, {"File from which the metadata was extracted."}});
191+
return results;
192+
}
193+
LOGP(info, "No metadata found in file \"{}\" nor in its parent file \"{}\"", filename, parentFilename);
194+
break;
144195
}
145-
currentFile->Close();
196+
results.push_back(ConfigParamSpec{"aod-metadata-disable", VariantType::String, "1", {"Metadata not found in AOD"}});
146197
return results;
147198
}};
148199
}

0 commit comments

Comments
 (0)