WCSim
hadd_wcsim_compileMe.C
Go to the documentation of this file.
1 #include <TSystem.h>
2 #include <string.h>
3 #include "TChain.h"
4 #include "TFile.h"
5 #include "TH1.h"
6 #include "TTree.h"
7 #include "TKey.h"
8 #include "Riostream.h"
9 #include <TROOT.h>
10 
11 // Compile Me
12 // g++ -o hadd_wcsim.exe hadd_wcsim_compileMe.C `root-config --cflags --libs`
13 
14 using namespace std;
15 
16 TList *FileList;
17 TFile *Target;
18 
19 void MergeRootfile( TDirectory *target, TList *sourcelist );
20 void hadd(const char* list, const char* out);
21 
22 
23 int main(int argc , char* argv[]){
24 
25  const char* list;
26  const char* out;
27  if( argc<3 ){
28  std::cout<<" Usage: ./hadd_wcsim.exe wcsim.list wcsim_hadd.root " << std::endl;
29  std::cout<<" Should provide names of input list and output ROOT file" << std::endl;
30  std::cout<<" Using default names wcsim.list and wcsim_hadd.root" << std::endl;
31  }
32  else{
33  list = argv[1]; std::cout<<"Input list: "<< list << std::endl;
34  out = argv[2]; std::cout<<"Output ROOT file:: "<< out << std::endl;
35  }
36  gROOT->Reset();
37  char* wcsimdirenv;
38  wcsimdirenv = getenv ("WCSIMDIR");
39  if(wcsimdirenv != NULL){
40  gSystem->Load("${WCSIMDIR}/libWCSimRoot.so");
41  }
42  else{
43  cout<<"Must set WCSIMDIR" << std::endl;
44  }
45 
46  std::cout<<"Run hadd function"<< std::endl;
47  hadd(list, out);
48  std::cout<<"Completed hadd function"<< std::endl;
49 }
50 
51 
52 void hadd(const char* list, const char* out){
53 
54  Target = TFile::Open( out , "RECREATE" );
55 
56  FileList = new TList();
57  // Reading a list to add to RList
58  std::ifstream w_file( list );
59  if (w_file.is_open()) {
60  std::string w_line;
61  while (getline(w_file, w_line)) {
62  FileList->Add( TFile::Open( w_line.c_str() ));
63  }
64  w_file.close();
65  }
67 }
68 
69 
70 void MergeRootfile( TDirectory *target, TList *sourcelist ) {
71 
72  // cout << "Target path: " << target->GetPath() << endl;
73  TString path( (char*)strstr( target->GetPath(), ":" ) );
74  path.Remove( 0, 2 );
75 
76  TFile *first_source = (TFile*)sourcelist->First();
77  first_source->cd( path );
78  TDirectory *current_sourcedir = gDirectory;
79  //gain time, do not add the objects in the list in memory
80  Bool_t status = TH1::AddDirectoryStatus();
81  TH1::AddDirectory(kFALSE);
82 
83  // loop over all keys in this directory
84  TChain *globChain = 0;
85  TIter nextkey( current_sourcedir->GetListOfKeys() );
86  TKey *key, *oldkey=0;
87  while ( (key = (TKey*)nextkey())) {
88 
89  //keep only the highest cycle number for each key
90  if (oldkey && !strcmp(oldkey->GetName(),key->GetName())) continue;
91 
92  // read object from first source file
93  first_source->cd( path );
94  TObject *obj = key->ReadObj();
95 
96  if ( obj->IsA()->InheritsFrom( TH1::Class() ) ) {
97  // descendant of TH1 -> merge it
98 
99  // cout << "Merging histogram " << obj->GetName() << endl;
100  TH1 *h1 = (TH1*)obj;
101 
102  // loop over all source files and add the content of the
103  // correspondant histogram to the one pointed to by "h1"
104  TFile *nextsource = (TFile*)sourcelist->After( first_source );
105  while ( nextsource ) {
106 
107  // make sure we are at the correct directory level by cd'ing to path
108  nextsource->cd( path );
109  TKey *key2 = (TKey*)gDirectory->GetListOfKeys()->FindObject(h1->GetName());
110  if (key2) {
111  TH1 *h2 = (TH1*)key2->ReadObj();
112  h1->Add( h2 );
113  delete h2;
114  }
115 
116  nextsource = (TFile*)sourcelist->After( nextsource );
117  }
118  }
119  else if ( obj->IsA()->InheritsFrom( TTree::Class() ) ) {
120 
121  // loop over all source files create a chain of Trees "globChain"
122  const char* obj_name= obj->GetName();
123 
124  globChain = new TChain(obj_name);
125  globChain->Add(first_source->GetName());
126  TFile *nextsource = (TFile*)sourcelist->After( first_source );
127  // const char* file_name = nextsource->GetName();
128  // cout << "file name " << file_name << endl;
129  while ( nextsource ) {
130 
131  globChain->Add(nextsource->GetName());
132  nextsource = (TFile*)sourcelist->After( nextsource );
133  }
134 
135  } else if ( obj->IsA()->InheritsFrom( TDirectory::Class() ) ) {
136  // it's a subdirectory
137 
138  cout << "Found subdirectory " << obj->GetName() << endl;
139 
140  // create a new subdir of same name and title in the target file
141  target->cd();
142  TDirectory *newdir = target->mkdir( obj->GetName(), obj->GetTitle() );
143 
144  // newdir is now the starting point of another round of merging
145  // newdir still knows its depth within the target file via
146  // GetPath(), so we can still figure out where we are in the recursion
147  MergeRootfile( newdir, sourcelist );
148 
149  } else {
150 
151  // object is of no type that we know or can handle
152  cout << "Unknown object type, name: "
153  << obj->GetName() << " title: " << obj->GetTitle() << endl;
154  }
155 
156  // now write the merged histogram (which is "in" obj) to the target file
157  // note that this will just store obj in the current directory level,
158  // which is not persistent until the complete directory itself is stored
159  // by "target->Write()" below
160  if ( obj ) {
161  target->cd();
162 
164  if(obj->IsA()->InheritsFrom( TTree::Class() ))
165  globChain->Merge(target->GetFile(),0,"keep");
166  else
167  obj->Write( key->GetName() );
168  }
169 
170  } // while ( ( TKey *key = (TKey*)nextkey() ) )
171 
172  // save modifications to target file
173  target->SaveSelf(kTRUE);
174  TH1::AddDirectory(status);
175 
176 }
int main(int argc, char *argv[])
Definition: json.hpp:5295
void MergeRootfile(TDirectory *target, TList *sourcelist)
void hadd(const char *list, const char *out)
TList * FileList
TFile * Target