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,6 +84,32 @@ 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
@@ -94,8 +121,6 @@ struct DiscoverMetadataInAOD : o2::framework::ConfigDiscoveryPlugin {
94121 if (filename.empty ()) {
95122 return {};
96123 }
97- std::vector<ConfigParamSpec> results;
98- TFile* currentFile = nullptr ;
99124 if (filename.at (0 ) == ' @' ) {
100125 filename.erase (0 , 1 );
101126 // read the text file and set filename to the contents of the first line
@@ -110,39 +135,64 @@ struct DiscoverMetadataInAOD : o2::framework::ConfigDiscoveryPlugin {
110135 TGrid::Connect (" alien://" );
111136 }
112137 LOGP (info, " Loading metadata from file {} in PID {}" , filename, getpid ());
113- currentFile = TFile::Open (filename.c_str ());
114- if (! currentFile) {
138+ std::unique_ptr<TFile> currentFile{ TFile::Open (filename.c_str ())} ;
139+ if (currentFile. get () == nullptr ) {
115140 LOGP (fatal, " Couldn't open file \" {}\" !" , filename);
116141 }
142+ std::vector<ConfigParamSpec> results = readMetadata (currentFile);
143+ // Found metadata already in the main file.
144+ if (!results.empty ()) {
145+ auto tables = getListOfTables (currentFile);
146+ if (tables.empty () == false ) {
147+ results.push_back (ConfigParamSpec{" aod-metadata-tables" , VariantType::ArrayString, tables, {" Tables in first AOD" }});
148+ }
149+ results.push_back (ConfigParamSpec{" aod-metadata-source" , VariantType::String, filename, {" File from which the metadata was extracted." }});
150+ return results;
151+ }
117152
118- // Get the metadata, if any
119- auto m = (TMap*)currentFile->Get (" metaData " );
120- if (!m ) {
153+ // Lets try in parent files
154+ auto parentFiles = (TMap*)currentFile->Get (" parentFiles " );
155+ if (!parentFiles ) {
121156 LOGP (info, " No metadata found in file \" {}\" " , filename);
122157 results.push_back (ConfigParamSpec{" aod-metadata-disable" , VariantType::String, " 1" , {" Metadata not found in AOD" }});
123158 return results;
124159 }
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 ;
160+ for (auto * p : *parentFiles) {
161+ std::string parentFilename = ((TPair*)p)->Value ()->GetName ();
162+ // Do the replacement. Notice this will require changing aod-parent-base-path-replacement to be
163+ // a workflow option (because the metadata itself is potentially changing the topology).
164+ if (registry.isSet (" aod-parent-base-path-replacement" )) {
165+ auto parentFileReplacement = registry.get <std::string>(" aod-parent-base-path-replacement" );
166+ auto pos = parentFileReplacement.find (' ;' );
167+ if (pos == std::string::npos) {
168+ throw std::runtime_error (fmt::format (" Invalid syntax in aod-parent-base-path-replacement: \" {}\" " , parentFileReplacement.c_str ()));
169+ }
170+ auto from = parentFileReplacement.substr (0 , pos);
171+ auto to = parentFileReplacement.substr (pos + 1 );
172+ pos = parentFilename.find (from);
173+ if (pos != std::string::npos) {
174+ parentFilename.replace (pos, from.length (), to);
175+ }
133176 }
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- }
140177
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" }});
178+ std::unique_ptr<TFile> parentFile{TFile::Open (parentFilename.c_str ())};
179+ if (parentFile.get () == nullptr ) {
180+ LOGP (fatal, " Couldn't open derived file \" {}\" !" , parentFilename);
181+ }
182+ results = readMetadata (parentFile);
183+ // Found metadata already in the main file.
184+ if (!results.empty ()) {
185+ auto tables = getListOfTables (parentFile);
186+ if (tables.empty () == false ) {
187+ results.push_back (ConfigParamSpec{" aod-metadata-tables" , VariantType::ArrayString, tables, {" Tables in first AOD" }});
188+ }
189+ results.push_back (ConfigParamSpec{" aod-metadata-source" , VariantType::String, filename, {" File from which the metadata was extracted." }});
190+ return results;
191+ }
192+ LOGP (info, " No metadata found in file \" {}\" nor in its parent file \" {}\" " , filename, parentFilename);
193+ break ;
144194 }
145- currentFile-> Close ( );
195+ results. push_back (ConfigParamSpec{ " aod-metadata-disable " , VariantType::String, " 1 " , { " Metadata not found in AOD " }} );
146196 return results;
147197 }};
148198 }
0 commit comments