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