ATLAS Offline Software
Loading...
Searching...
No Matches
HanOutputFile_V2toV1_translation.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4#include <iostream>
5#include <nlohmann/json.hpp> //to write JSON strings
6#include <typeinfo> //to print the type of variable
7#include <TFile.h>
8#include <TH1.h>
9#include <TKey.h>
10#include <TObjString.h>
11#include <TROOT.h> //To use gRoot
12#include <gperftools/profiler.h>
13
14#include <chrono> //To measure time
15#include <cstring> //to convert string to char array (to save json file as TObjString)
16
17// compilation
18// g++ -std=c++11 HanOutputFile_V2toV1_translation.cxx -O2 `root-config --cflags` `root-config --libs --glibs` -o
19// HanOutputFile_V2toV1_translation
20
21// Function, that converts JSON string back to TDirectory structure
22void from_JSON_to_TDirectory(nlohmann::json str_content, TDirectory* place_to_save);
23// Function, that converts back ATLAS file from new vesrion to old version
24void conversion_back(TObject* obj_in, TObject* obj_to);
25// Function, that checks, if "dirname" TDirectory exists inside obj_in or not
26int dir_exists(TString dirname, TObject* obj_in);
27
28int main() {
29 TFile* f = new TFile("run_364030_lowStat_LB121-140_han_converted.root");
30 TFile* f_output = new TFile("run_364030_lowStat_LB121-140_han_converted_back.root", "recreate");
31 // Find a TObjString with JSON inside
32 auto start = std::chrono::system_clock::now();
33
34 conversion_back(f, f_output);
35 auto end = std::chrono::system_clock::now();
36 std::chrono::duration<double> elapsed_seconds = end - start;
37 std::cout << "elapsed time: " << elapsed_seconds.count() << "s\n";
38
39 f->Close(); // Close the file
40 f_output->Close();
41 return 0;
42}
43
44void conversion_back(TObject* obj_in, TObject* obj_to) {
45 TObjString* TOS_w_JSON; // JSON string
46
47 std::string content;
48 TString obj_input_type = obj_in->ClassName();
49 bool is_file;
50 if (obj_input_type == "TFile") {
51 is_file = true;
52 } else {
53 is_file = false;
54 }
55 TDirectory* obj_in_dir = static_cast<TDirectory*> (obj_in);
56 TDirectory* obj_to_dir = static_cast<TDirectory*> (obj_to);
57 TString name = obj_in->GetName();
58 TDirectory* copy_dir;
59 if (is_file == false) {
60 copy_dir = obj_to_dir->mkdir(name);
61 } else {
62 copy_dir = obj_to_dir;
63 }
64 copy_dir->cd();
65
66 TIter next(obj_in_dir->GetListOfKeys());
67 TKey* key;
68 while ((key = (TKey*) next())) {
69 TObject* obj_inside;
70 TString key_name = key->GetName();
71 TString key_type = key->GetClassName();
72 if (key_type == "TObjString") {
73 if (key_name == "File_version") { // File version is a flag of new version of files
74 continue;
75 } else {
76 obj_in_dir->GetObject(key_name, TOS_w_JSON);
77 // Get JSON from TObjString
78 content = TOS_w_JSON->GetString();
79 TDirectoryFile* idir;
80 if (dir_exists(key_name, copy_dir) == 0) { // When Reference hist should be saved to Results dir
81 // there is no Results dir at that moment and we created it. So, when
82 // it's time to process
83 // JOSN string "Results", we shouldn't create Results directory again
84 copy_dir->cd();
85 idir = new TDirectoryFile(key_name, "");
86 } else {
87 copy_dir->GetObject(key_name, idir);
88 }
89 using json = nlohmann::json;
90 // Get JSON from TObjString
91 auto j = json::parse(content);
93 copy_dir->cd();
94 idir->Write();
95 delete idir;
96 delete TOS_w_JSON;
97 }
98 }
99 // We process hist another way, than TObjstrings and TDirectories
100 else if (key_type == "TH1I" || key_type == "TH2I" || key_type == "TH1F" || key_type == "TH2F" ||
101 key_type == "TProfile2D" || key_type == "TProfile" || key_type == "TGraphAsymmErrors" ||
102 key_type == "TGraphErrors" || key_type == "TH1D" || key_type == "TH2S") {
103 obj_inside = obj_in_dir->GetKey(key_name)->ReadObj();
104 copy_dir->cd();
105 if (key_name == "Reference") { // We should place "Reference" hists to result in old-version files
106 if (!dir_exists("Results", copy_dir)) {
107 copy_dir->mkdir("Results");
108 }
109 copy_dir->cd("Results");
110 }
111 obj_inside->Write(key_name);
112 copy_dir->cd();
113 delete obj_inside;
114 } else if (key_type == "TDirectoryFile") {
115 obj_inside = obj_in_dir->GetKey(key_name)->ReadObj();
116 conversion_back(obj_inside, copy_dir);
117 delete obj_inside;
118 }
119 }
120}
121
122void from_JSON_to_TDirectory(nlohmann::json str_content, TDirectory* place_to_save) {
123 using json = nlohmann::json;
124 // Get the size of JSON
125 int size = str_content.size();
126 int num_of_key = 0;
127 for (json::iterator it = str_content.begin(); it != str_content.end(); ++it) {
128 // Create array of subdirectories
129 TDirectory* nextLevelDirs[size];
130 // Keyname of json will become subdirectory name
131 const char* keyname = it.key().c_str();
132 auto valuestring = it.value();
133 // Now lets make subdir in our dir
134 if (dir_exists(keyname, place_to_save) == 0) {
135 place_to_save->mkdir(keyname);
136 }
137 place_to_save->cd(keyname);
138 nextLevelDirs[num_of_key] = gDirectory;
139 if (strncmp(valuestring.type_name(), "string", 6) == 0) {
140 TObjString leaf;
141 nextLevelDirs[num_of_key]->cd();
142 TString string_name = valuestring.dump();
143 leaf.SetString(string_name);
144 nextLevelDirs[num_of_key]->WriteTObject(&leaf, string_name);
145 // leaf.Write();
146 } else {
147 from_JSON_to_TDirectory(valuestring, nextLevelDirs[num_of_key]);
148 }
149 num_of_key++;
150 }
151 return;
152}
153
154int dir_exists(TString dirname, TObject* obj_in) {
155 TDirectory* obj_in_dir = static_cast<TDirectory*> (obj_in);
156 TList* keys = obj_in_dir->GetListOfKeys();
157 TKey* k = (TKey*) keys->FindObject(dirname);
158
159 if (k && !strcmp(k->GetClassName(), "TDirectoryFile")) {
160 return 1;
161 } else {
162 return 0;
163 }
164 return 0;
165}
void conversion_back(TObject *obj_in, TObject *obj_to)
void from_JSON_to_TDirectory(nlohmann::json str_content, TDirectory *place_to_save)
int dir_exists(TString dirname, TObject *obj_in)
nlohmann::json json
std::string dirname(std::string name)
Definition utils.cxx:200