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