ATLAS Offline Software
Loading...
Searching...
No Matches
HanOutputFile_translation.cxx File Reference
#include <iostream>
#include <nlohmann/json.hpp>
#include <TFile.h>
#include <TFolder.h>
#include <TH1.h>
#include <TKey.h>
#include <TObjString.h>
#include <TROOT.h>
#include <unistd.h>
#include <chrono>
#include <cstring>

Go to the source code of this file.

Functions

int include_hist (TObject *obj)
 Instructions: COMPILE g++ -std=c++11 HanOutputFile_translation.cxx -O2 root-config --cflags root-config --libs --glibs -o HanOutputFile_translation.
int number_of_objects_in_dir (TIter next)
nlohmann::ordered_json to_JSON (TObject *obj)
int work_with_no_hist_dir (TObject *obj, TObject *destination_to_save)
int work_with_results_dir (TObject *obj_in, TObject *obj_to)
int convert_file (TObject *obj_in, TObject *obj_to)
int main (int argc, char *argv[])

Function Documentation

◆ convert_file()

int convert_file ( TObject * obj_in,
TObject * obj_to )

Definition at line 134 of file HanOutputFile_translation.cxx.

134 {
135 TString obj_input_type = obj_input->ClassName();
136 bool is_file;
137
138 if (obj_input_type == "TFile") {
139 is_file = true;
140 } else {
141 is_file = false;
142 }
143
144 TDirectory* dir;
145 TDirectory* save_to = dynamic_cast<TDirectory*>(obj_outout);
146 TString name = obj_input->GetName();
147
148 if (dir = dynamic_cast<TDirectory*>(obj_input)) { // obj_input is a TDirectory
149 TString name = dir->GetName();
150 if (name == "Results") { // From Results folder should be extracted Reference histogrma (in an upper level), and
151 // Results --> JSON
152 work_with_results_dir(dir, save_to);
153 } else if (name == "Config") { // Config --> JSON
154 work_with_no_hist_dir(dir, save_to);
155 } else {
156 // Treat as TDirectory
157 // 1-st, lets create this dir
158 TDirectory* copy_dir;
159 if (is_file == false) {
160 copy_dir = save_to->mkdir(name);
161 } else {
162 copy_dir = save_to;
163 }
164 // All files in this dir should be saved in the created one
165 copy_dir->cd();
166 // 2-nd, create iterator to iterate through the objects in the original dir
167 TIter next(dir->GetListOfKeys());
168 TKey* key;
169 // 3-rd, Analyse, from which elements this dir consists of
170 while ((key = (TKey*) next())) {
171 TObject* next_level_obj;
172 TString key_name = key->GetName();
173 next_level_obj = dir->GetKey(key_name)->ReadObj();
174 convert_file(next_level_obj, copy_dir);
175 }
176 }
177 } else { // If the object is not a Tdirectory (a histogram or TObjsStrin)
178 // just save it as it is where it should be
179 save_to->cd();
180 obj_input->Write(name);
181 }
182 return 1;
183}
int convert_file(TObject *obj_in, TObject *obj_to)
int work_with_no_hist_dir(TObject *obj, TObject *destination_to_save)
int work_with_results_dir(TObject *obj_in, TObject *obj_to)
copy_dir(source, destination)

◆ include_hist()

int include_hist ( TObject * obj)

Instructions: COMPILE g++ -std=c++11 HanOutputFile_translation.cxx -O2 root-config --cflags root-config --libs --glibs -o HanOutputFile_translation.

RUN ./HanOutputFile_translation or ./HanOutputFile_translation <input_file_name> or ./HanOutputFile_translation <input_file_name> <output_dir_path> or ./HanOutputFile_translation <input_dir_path> <input_file_name> <output_dir_path> Declarations of functions protoypes

Definition at line 241 of file HanOutputFile_translation.cxx.

241 {
242 using namespace std;
243
244 TDirectory* dir = static_cast<TDirectory*> (obj);
245 TKey* key;
246 TString key_type;
247 TString key_name;
248 // Look, what the directory stores
249 dir->cd();
250 TIter next(dir->GetListOfKeys());
251 while ((key = (TKey*) next())) {
252 TObject* obj_inside;
253 key_name = key->GetName();
254 obj_inside =
255 dir->GetKey(key_name)->ReadObj(); // Get the object. This procedure is better, since it is able to read
256 // names with "/"
257 key_type = obj_inside->ClassName();
258 // If the object is histogram
259 if (key_type == "TH1I" || key_type == "TH2I" || key_type == "TH1F" || key_type == "TH2F" ||
260 key_type == "TProfile2D" || key_type == "TProfile" || key_type == "TGraphAsymmErrors" ||
261 key_type == "TGraphErrors" || key_type == "TH1D" || key_type == "TH2S") {
262 return 1;
263 }
264 // Also check all the subdirectories
265 if (key_type == "TDirectoryFile") {
266 if (include_hist(obj_inside) == 1) {
267 return 1;
268 }
269 }
270 }
271 return 0;
272}
int include_hist(TObject *obj)
Instructions: COMPILE g++ -std=c++11 HanOutputFile_translation.cxx -O2 root-config --cflags root-conf...
STL namespace.

◆ main()

int main ( int argc,
char * argv[] )

Definition at line 60 of file HanOutputFile_translation.cxx.

60 {
61 using namespace std;
62 // ATLAS Data Quality space
63 TString input_file_path = "/eos/atlas/atlascerngroupdisk/data-dqm/examples/han_output_translation_example/";
64 TString input_file_name = "run_364030_lowStat_LB121-140_han.root"; // Example file
65 TString output_file_path = "./";
66
67 if (argc == 2) {
69 }
70 if (argc == 3) {
72 output_file_path = argv[2];
73 }
74 if (argc == 4) {
75 input_file_path = argv[1];
77 output_file_path = argv[3];
78 }
79
80 auto start = std::chrono::system_clock::now(); // Start time counting
81 // Open file from which to convert
82 TFile* f_input = new TFile(input_file_path + input_file_name);
83 // Open file where to convert
84 // Enter here the path where you want to store the iutput file
85 TFile* f_output = new TFile(output_file_path + input_file_name, "recreate");
86 // Counting time elapsed for the translation
87 auto end = std::chrono::system_clock::now(); // Stop time counting
88 std::chrono::duration<double> elapsed_seconds = end - start;
89 std::cout << "elapsed time to open files: " << elapsed_seconds.count() << "s\n";
90 start = std::chrono::system_clock::now(); // Start time counting
91
92 // Convert from V1-->V2.3
93 convert_file(f_input, f_output);
94
95 // Add the version flag
96
97 f_output->cd("HanMetadata_");
98 TDirectory* version_dir = gDirectory->mkdir("File");
99 version_dir->cd();
100 TDirectory* version_sub_dir = gDirectory->mkdir("Version_name");
101 version_sub_dir->cd();
102 TObjString file_version;
103 file_version.Write("V.2.3");
104
105 end = std::chrono::system_clock::now(); // Stop time counting
106 elapsed_seconds = end - start;
107 std::cout << "elapsed time for algorythm implementation: " << elapsed_seconds.count() << "s\n";
108 // From root forum
109 // To reduce the time spent in the ‘garbage collection’ and assuming that you are 100% sure
110 // that no pointer to the contained object is shared and assuming you explicitly delete the
111 // TFile object, you can remove the TFile object from the list of files
112 // “gROOT->GetListOfFiles()->Remove(myfile);”
113
114 // This is a known problem with file with very large number of histograms in a file
115 //(and in particular in a directory). You can work around the problem, if (and only if)
116 // you are sure the same histogram is not shared between two directories:
117 // TFile *outputFile = ..... ..... gROOT->GetListOfFiles()->Remove(outputFile); delete outputFile;
118
119 // start = std::chrono::system_clock::now(); // Start time counting
120 gROOT->GetListOfFiles()->Remove(f_input); // removes the file from a list of “files to cleanup”, so that the objects
121 // they contain are not cleaned at the end.
122 gROOT->GetListOfFiles()->Remove(f_output);
123 f_output->Close();
124 f_input->Close(); // Close the file
125 delete f_input;
126 delete f_output;
127 end = std::chrono::system_clock::now(); // Stop time counting
128 elapsed_seconds = end - start;
129 std::cout << "elapsed time to close files: " << elapsed_seconds.count() << "s\n";
130 return 0;
131}

◆ number_of_objects_in_dir()

int number_of_objects_in_dir ( TIter next)

Definition at line 274 of file HanOutputFile_translation.cxx.

274 {
275 const TCollection* next_coll = next.GetCollection();
276 Int_t level_size = next_coll->Capacity();
277
278 return level_size;
279}

◆ to_JSON()

nlohmann::ordered_json to_JSON ( TObject * obj)

Definition at line 281 of file HanOutputFile_translation.cxx.

281 {
282 using json = nlohmann::ordered_json;
283 TString obj_type = obj->ClassName();
284 json j;
285
286 if (obj_type == "TObjString") { // If the object type, that were passed to this function is TObjString (should be
287 // impossible), this means, that there is a TObjString, that is not a single file in
288 // a
289 // directory (not a usual case)
290 std::cout << "WARNING: Strange case: TObjString is not a single object in a dir" << std::endl;
291 } else if (obj_type != "TDirectoryFile" && obj_type != "TFile") { // No other type than TDirectory or TFile should be
292 // passed to this function normally
293 std::cout << "WARNING: Strange type: " << obj_type << std::endl;
294 }
295
296 TDirectory* dir = static_cast<TDirectory*> (obj);
297 TString dir_name = dir->GetName();
298 TIter next(dir->GetListOfKeys());
299 TKey* key;
300 TString key_name;
301
302 int size_next = number_of_objects_in_dir(next);
303
304 // We should write to JSON all the objects
305 while ((key = (TKey*) next())) {
306 TObject* next_level_obj;
307 key_name = key->GetName();
308 next_level_obj =
309 dir->GetKey(key_name)->ReadObj(); // Get object. This procedure is better, since it is able to read
310 // names with "/"
311 TString key_type = next_level_obj->ClassName();
312
313 if (size_next == 1 && key_type == "TObjString") { // If this is a directory just before the leaf (the TObjString
314 // file)
315 j = key_name; // This is the leaf
316 if (key_name == dir_name) {
317 std::cout << "WARNING: The names of Directory and TObjstring inside this directory are the same: " << dir_name
318 << std::endl;
319 }
320 }
321 // We will ignore Hists in "Results" directory, since we have already written them in a higher level
322 else if ((dir_name == "Results") &&
323 (key_type == "TH1I" || key_type == "TH2I" || key_type == "TH1F" || key_type == "TH2F" ||
324 key_type == "TProfile2D" || key_type == "TProfile" || key_type == "TGraphAsymmErrors" ||
325 key_type == "TGraphErrors" || key_type == "TH1D" || key_type == "TH2S")) {
326 continue;
327 }
328 // If inside this directory other subdirrectory
329 else { // Write Directory_names as keys and content of the dirrectories as a values
330 // Convert TString to string
331 std::string key_name_string(key_name.Data());
332 // Write JSON to rootFile
333 j.emplace(key_name_string, to_JSON(next_level_obj));
334 }
335 }
336 return j;
337}
nlohmann::ordered_json to_JSON(TObject *obj)
int number_of_objects_in_dir(TIter next)
nlohmann::json json

◆ work_with_no_hist_dir()

int work_with_no_hist_dir ( TObject * obj,
TObject * destination_to_save )

Definition at line 217 of file HanOutputFile_translation.cxx.

217 {
218 TDirectory* save_place = static_cast<TDirectory*> (destination_to_save);
219
220 // If directory has no hists in it, we convert it to JSON
221 // histogram_ Tdirectory is an exception. It will always be a Tdirectory
222 save_place->cd();
223 nlohmann::ordered_json j = to_JSON(obj);
224 // Then, save JSON to file as TObjString
225 // Convert json to string
226 std::string string = j.dump(4);
227 // Write JSON to rootFile
228
229 TObjString string_to_tfile;
230 // string_to_tfile.SetString(cstr);//Original
231 if (j.is_null()) {
232 string_to_tfile.SetString("{}"); // Content of a JSON string
233 } else {
234 string_to_tfile.SetString(string.data()); // Content of a JSON string
235 }
236 TString key_name = obj->GetName();
237 string_to_tfile.Write(key_name);
238 return 0;
239}
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11

◆ work_with_results_dir()

int work_with_results_dir ( TObject * obj_in,
TObject * obj_to )

Definition at line 185 of file HanOutputFile_translation.cxx.

185 {
186 TDirectory* dir = static_cast<TDirectory*> (obj_input);
187 TDirectory* save_to = static_cast<TDirectory*> (obj_outout);
188
189 if (include_hist(dir)) {
190 TKey* key;
191 TString key_type;
192 TString key_name;
193 TIter next(dir->GetListOfKeys());
194 while ((key = (TKey*) next())) {
195 TObject* obj_inside;
196 key_name = key->GetName();
197 obj_inside = dir->GetKey(key_name)->ReadObj();
198 key_type = obj_inside->ClassName();
199 // If an element in "Results" directory is a hist, we will save it in higher level
200 if (key_type == "TH1I" || key_type == "TH2I" || key_type == "TH1F" || key_type == "TH2F" ||
201 key_type == "TProfile2D" || key_type == "TProfile" || key_type == "TGraphAsymmErrors" ||
202 key_type == "TGraphErrors" || key_type == "TH1D" || key_type == "TH2S") {
203 save_to->cd();
204 obj_inside->Write(key_name);
205 }
206 }
207 // Then we will work with this directory as with ones without hists
208 work_with_no_hist_dir(obj_input, obj_outout);
209 }
210 // If "Results" has no histograms inside, we will work with it as with the usual directory
211 else {
212 work_with_no_hist_dir(obj_input, obj_outout);
213 }
214 return 1;
215}