ATLAS Offline Software
Loading...
Searching...
No Matches
fastadd.cxx File Reference

navigates through the directory structure of identically organised root files adding them all together More...

#include <iostream>
#include <vector>
#include <string>
#include <stdio.h>
#include "TKey.h"
#include "TH1D.h"
#include "TH2D.h"
#include "TProfile.h"
#include "TFile.h"
#include "TClass.h"
#include "simpletimer.h"
#include "dataset.h"
#include <cstdlib>

Go to the source code of this file.

Functions

template<class T>
bool add (const std::string &hname, TKey *tobj)
void search (TDirectory *td=0, const std::string &s="")
 recursive directory search for TH1 and TH2
bool file_exists (const std::string &s)
void cost (const std::string &outputfile)
int usage (std::ostream &s, int, char **argv)
int main (int argc, char **argv)

Variables

std::vector< std::string > files
 file names and file pointers
std::vector< TFile * > fptr
struct timeval global_timer
 glabal timer - how long have I taken so far?
std::string depth = ""
 tag string for intendation
int ir =0
 counter of the current depth

Detailed Description

navigates through the directory structure of identically organised root files adding them all together

Author
mark sutton
Date
Thu 5 Sep 2013 20:32:47 CEST

Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration

Definition in file fastadd.cxx.

Function Documentation

◆ add()

template<class T>
bool add ( const std::string & hname,
TKey * tobj )

Definition at line 55 of file fastadd.cxx.

55 {
56
57 T* h0 = (T*)tobj->ReadObj();
58
59 // std::cout << "h0 " << h0;
60 // if ( h0 ) std::cout << " : " << h0->GetName();
61 // std::cout << std::endl;
62
63 bool changed = false;
64
65 if ( h0==0 ) {
66 std::cerr << "object " << hname << " can't be found" << std::endl;
67 return false;
68 }
69
70 if ( h0->GetSumw2N()==0 ) h0->Sumw2();
71
72
73 static int count = 0;
74
75 for ( unsigned ifile=1 ; ifile<fptr.size() ; ifile++ ) {
76
77 // std::cout << "TFile* fptr " << fptr[ifile] << " " << files[ifile] << std::endl;
78
79 if ( fptr[ifile] ) {
80
81 // std::cout << "h (get) >" << hname << "<" << std::endl;
82
83 T* h = (T*)fptr[ifile]->Get(hname.c_str());
84
85
86
87 if ( h==0 ) {
88 std::cout << "h (add) " << h << " " << hname << " can't be opened" << std::endl;
89 if ( count>20 ) exit(-1);
90 count++;
91 continue;
92 }
93
94 if ( h->GetSumw2N()==0 ) h->Sumw2();
95
96 // std::cout << "h " << h->GetName() << std::endl;
97
98 changed = true;
99 h0->Add( h );
100
101 delete h;
102
103 }
104 }
105
106
107
108 if ( changed ) {
109 h0->SetDirectory(0);
110 h0->Write("",TObject::kOverwrite);
111 // h0->Write(); // "",TObject::kOverwrite);
112 }
113
114 delete h0;
115
116 return true;
117}
Header file for AthHistogramAlgorithm.
T * Get(TFile &f, const std::string &n, const std::string &dir="", const chainmap_t *chainmap=0, std::vector< std::string > *saved=0)
get a histogram given a path, and an optional initial directory if histogram is not found,...
std::vector< TFile * > fptr
Definition hcg.cxx:51
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146

◆ cost()

void cost ( const std::string & outputfile)

no point doing anything if there is only 1 input file because there would be nothing to add to it

don't over write esisting files

copy the first file so we add to this copy

don't bother to open the first file - we've copied it to the output and will update the contents

open the output file

recursively look through the directory structure

close the files

don't need to write the histogram again - writing them as we go along

Definition at line 231 of file fastadd.cxx.

231 {
232
235 if ( files.size()<2 ) return;
236
237 std::cout << "processing" << std::endl;
238
240 if ( file_exists(outputfile) ) {
241 std::cerr << "output file " << outputfile << " already exists" << std::endl;
242 return;
243 }
244
245 std::cout << "copying file to " << outputfile << std::endl;
246
248 system( ("cp "+files[0]+" "+outputfile).c_str() );
249
250
253
254 std::cout << "opening root files" << std::endl;
255
256 fptr.resize(files.size());
257
258
259 std::cout << "opening " << files[0] << std::endl;
260
262 fptr[0] = new TFile( outputfile.c_str(), "update" );
263
264 if ( fptr[0]==0 ) {
265 std::cerr << "cannot open " << outputfile.c_str() << std::endl;
266 return;
267 }
268
269 for ( unsigned ifile=1 ; ifile<files.size() ; ifile++ ) {
270 std::cout << "opening " << files[ifile] << std::endl;
271 fptr[ifile] = new TFile( files[ifile].c_str() );
272 }
273
274
275 for ( unsigned ifile=0 ; ifile<files.size() ; ifile++ ) {
276 if ( fptr[ifile]==0 ) {
277 std::cerr << "file " << files[ifile] << " cannot be openened" << std::endl;
278 return;
279 }
280 }
281
282 fptr[0]->cd();
283
284 TDirectory* here = gDirectory;
285
287
290 search();
291
292 here->cd();
293
294 std::cout << "closing the files" << std::endl;
295
297 for ( unsigned ifile=1 ; ifile<files.size() ; ifile++ ) {
298 if ( fptr[ifile] ) {
299 fptr[ifile]->Close();
300 delete fptr[ifile];
301 }
302 }
303
305 // f0->Write();
306 fptr[0]->Close();
307
308}
ofstream outputfile
struct timeval simpletimer_start(void)
struct timeval global_timer
glabal timer - how long have I taken so far?
Definition fastadd.cxx:42
void search(TDirectory *td=0, const std::string &s="")
recursive directory search for TH1 and TH2
Definition fastadd.cxx:126
bool file_exists(const std::string &s)
Definition fastadd.cxx:220
std::vector< std::string > files
file names and file pointers
Definition hcg.cxx:50

◆ file_exists()

bool file_exists ( const std::string & s)

Definition at line 220 of file fastadd.cxx.

220 {
221 if ( FILE* testfile=fopen(s.c_str(),"r") ) {
222 fclose(testfile);
223 return true;
224 }
225 return false;
226}

◆ main()

int main ( int argc,
char ** argv )

if output file is not defined

check som input files

Definition at line 324 of file fastadd.cxx.

324 {
325
326 // if ( argc<3 ) usage( std::cerr << "not enough command options", argc, argv );
327 if ( argc<3 ) return usage( std::cerr, argc, argv );
328
329
330 for ( int i=1 ; i<argc ; i++ ) {
331 if ( std::string(argv[i])=="-h" || std::string(argv[i])=="--help" ) return usage( std::cout, argc, argv );
332 }
333
334 bool verbose = false;
335
336 std::string output_file = "";
337
338 for ( int i=1 ; i<argc ; i++ ) {
339 if ( std::string(argv[i])=="--verbose" ) verbose = true;
340 else if ( std::string(argv[i])=="-o" ) {
341 if ( ++i<argc ) output_file = argv[i];
342 else return usage( std::cerr, argc, argv );
343 }
344 else {
345 files.push_back(argv[i]);
346 }
347 }
348
349
351 if ( output_file == "" ) return usage( std::cerr, argc, argv );
352
353 // dataset data("test_EF");
354 // files = data.datafiles();
355
357
358
359 if ( files.size()<1 ) return usage( std::cerr, argc, argv );
360
361 for ( size_t i=files.size() ; i-- ; ) if ( files[i]==output_file ) return usage( std::cerr, argc, argv );
362
363 // time the actual running of the cost() routine
364
365 if ( verbose ) std::cout << "timing" << std::endl;
366
367 struct timeval tv = simpletimer_start();
368
369 cost(output_file);
370
371 double t = simpletimer_stop(tv);
372
373 std::cout << "\ntotal time " << t*0.001 << " s (" << (t*0.001/60) << " min)" << std::endl;
374
375 return 0;
376}
double simpletimer_stop(const struct timeval &start_time)
void cost(const std::string &outputfile)
Definition fastadd.cxx:231
StatusCode usage()
bool verbose
Definition hcg.cxx:73

◆ search()

void search ( TDirectory * td = 0,
const std::string & s = "" )

recursive directory search for TH1 and TH2

don;t go more than 10 directories deep

Definition at line 126 of file fastadd.cxx.

126 {
127
128 ir++;
129
131
132 if ( ir>10 ) exit(0);
133
134
135
136 TDirectory* here = gDirectory;
137
138 // gDirectory->pwd();
139
140 std::string ns = s;
141
142 if ( ns!="" ) ns += "/";
143
144 if ( td ) {
145 gDirectory->cd(td->GetName());
146
147 ns += td->GetName();
148
149 std::cout << "\n" << depth << "Directory " << ns; // << std::endl;
150 }
151
152 std::string savedepth = depth;
153 depth += "\t";
154
155 // std::cout << ir << " " << ns << "TDirectory " << gDirectory->GetPath() << " " << gDirectory->GetName() << std::endl;
156
157 TList* tl = gDirectory->GetListOfKeys();
158
159 struct timeval tv = simpletimer_start();
160
161 // std::cout << "\ttl " << tl << std::endl;
162
163 for ( int i=tl->GetSize() ; i-- ; ) {
164
165 TKey* tobj = (TKey*)tl->At(i);
166
167 if ( tobj==0 ) continue;
168
169 // std::cout << "tobj " << tobj;
170 // if ( tobj ) std::cout << " : \t" << tobj->GetName();
171 // std::cout << std::endl;
172
173 if ( std::string(tobj->GetClassName()).find("TDirectory")!=std::string::npos ) {
174 // std::cout << ns << "Directory " << tobj->GetName() << std::endl;
175
176 TDirectory* tnd = (TDirectory*)tobj->ReadObj();
177
178 if ( tnd ) search( tnd, ns );
179 }
180 else {
181 // bool status = false;
182
183 std::string objname = ns;
184 if ( objname!="" ) objname += std::string("/") + tobj->GetName();
185
186 // if ( std::string(tobj->GetClassName()).find("TH1")!=std::string::npos ) status = add<TH1>( objname.c_str(), tobj );
187 // if ( std::string(tobj->GetClassName()).find("TH2")!=std::string::npos ) status = add<TH2>( objname.c_str(), tobj );
188 if ( std::string(tobj->GetClassName()).find("TH1")!=std::string::npos ) add<TH1>( objname, tobj );
189 if ( std::string(tobj->GetClassName()).find("TH2")!=std::string::npos ) add<TH2>( objname, tobj );
190 if ( std::string(tobj->GetClassName()).find("TProfile")!=std::string::npos ) add<TProfile>( objname, tobj );
191
192 // if ( !status ) std::cerr << "bad status" << std::endl;
193 }
194
195 }
196
197 const double t = simpletimer_stop(tv);
198
199 const double global_time = simpletimer_stop(global_timer);
200
201
202 std::cout << "\tprocessed directory in " << t*0.001 << " s from " << global_time*0.001 << " s";
203
204
205 depth = std::move(savedepth);
206
207 ir--;
208
209 here->cd();
210
211}
int ir
counter of the current depth
Definition fastadd.cxx:49
bool add(const std::string &hname, TKey *tobj)
Definition fastadd.cxx:55
std::string depth
tag string for intendation
Definition fastadd.cxx:46

◆ usage()

int usage ( std::ostream & s,
int ,
char ** argv )

Definition at line 313 of file fastadd.cxx.

313 {
314 s << "Usage: " << argv[0] << " [OPTIONS] -o output.root input1.root ... inputN.root\n\n";
315 s << " -o filename \tname of output (filename required)\n";
316 s << " -h, --help \tdisplay this help\n";
317 s << std::endl;
318 return 0;
319}

Variable Documentation

◆ depth

std::string depth = ""

tag string for intendation

Definition at line 46 of file fastadd.cxx.

◆ files

std::vector<std::string> files

file names and file pointers

Definition at line 37 of file fastadd.cxx.

◆ fptr

std::vector<TFile*> fptr

Definition at line 38 of file fastadd.cxx.

◆ global_timer

struct timeval global_timer

glabal timer - how long have I taken so far?

Definition at line 42 of file fastadd.cxx.

◆ ir

int ir =0

counter of the current depth

Definition at line 49 of file fastadd.cxx.