2222#include < TObjString.h>
2323#include < TString.h>
2424#include < fmt/format.h>
25+ #include < memory>
2526
2627O2_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
87114struct 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