ATLAS Offline Software
Loading...
Searching...
No Matches
cpucost.cxx
Go to the documentation of this file.
1
9
10// cppcheck-suppress-file stlIfStrFind; cannot use C++20 starts_with in this standalone code
11
12#include <stdlib.h>
13#include <sys/time.h>
14#include <sys/stat.h>
15#include <sys/types.h>
16
17#include <iostream>
18#include <string>
19#include <vector>
20
21#include "utils.h"
22#include "label.h"
23#include "DrawLabel.h"
24
25#include "TCanvas.h"
26#include "TFile.h"
27#include "TH1D.h"
28#include "TLegend.h"
29#include "TStyle.h"
30#include "TSystem.h"
31
32#include "TKey.h"
33#include "TList.h"
34#include "TDirectory.h"
35
36#include "computils.h"
37
38#include "AtlasStyle.h"
39#include "AtlasLabels.h"
40
42int usage(const std::string& name, int status) {
43 std::ostream& s = std::cout;
44 s << "Usage: " << name << " [OPTIONS] expert-monitoring.root reference.root algorithm1 algorithm2 algorithm3 ...\n\n";
45 s << " TIDA \'" << name << "\' extracts timing histograms\n\n";
46 s << "Options: \n";
47 s << " -o, --outputfolder value\t puts output in folder 'value' making it if it doesn't exist, \n\n";
48 s << " -t, --tag value \t appends tag 'value' to the end of output plot names, \n";
49 s << " -k, --key value \t prepends key 'value' to the front of output plot names, \n\n";
50 s << " -a, --auto \t process all histograms that are in the file, \n";
51 s << " -r, --replace patt rep\t replace patt wiht rep in the file name\n";
52 s << " -d, --directory value \t if auto is set, search only in specifed directory, \n";
53 s << " --nodir \t do not print the directory name on the plot,\n";
54 s << " -p, --pattern value \t if auto is set, search for histograms containing this string, \n\n";
55 s << " -f, --frac \t explicitly include the fractional plots\n";
56 s << " -nr, --noref \t do not use the reference file, \n\n";
57 s << " -x, --xoffset value \t offset the key by value \n";
58 s << " --logx \t force logx \n";
59 s << " -w, --binwidth \t normalise by bin width\n";
60 s << " -as, --atlasstyle \t use the ATLAS style \n\n";
61 s << " -al, --atlaslabel \t show the ATLAS label \n\n";
62 s << " -v, --verbose \t verbose output\n\n";
63 s << " -h, --help \t this help\n";
64 s << std::endl;
65 return status;
66}
67
68
69
70struct histoinfo {
71 histoinfo( const std::string& f, const std::string& d ) : fname(f), dname(d) { }
72 std::string fname; // File name
73 std::string dname; // Display name
74};
75
76
77std::ostream& operator<<( std::ostream& s, const histoinfo& h ) {
78 return s << h.fname << " : " << h.dname;
79}
80
81
82void binwidth( TH1F* h ) {
83 for ( int i=0 ; i<h->GetNbinsX() ; i++ ) {
84 double w = h->GetBinLowEdge(i+2)-h->GetBinLowEdge(i+1);
85 h->SetBinContent( i+1, h->GetBinContent(i+1)/w );
86 h->SetBinError( i+1, h->GetBinError(i+1)/w );
87 }
88}
89
90
91int main(int argc, char** argv) {
92
93 if (argc < 4) { return usage(argv[0], -1); }
94
95 std::string output_dir = "";
96 std::string tag = "";
97 std::string key = "";
98
99 gStyle->SetPadRightMargin(0.05);
100 gStyle->SetPadTopMargin(0.05);
101
102 gStyle->SetPadLeftMargin(0.14);
103 gStyle->SetPadBottomMargin(0.14);
104 // gStyle->SetTitleXOffset(0.1);
105 // gStyle->SetTitleYOffset(0.1);
106
107
108 TFile* ftest = 0;
109 TFile* fref = 0;
110
111 bool atlasstyle = false;
112 bool atlaslabel = false;
113 bool ylog = true;
114 bool nopng = false;
115
116 bool autochains = false;
117
118 std::string autopattern = "";
119
120 std::vector<std::string> taglabels;
121
122 std::string directory = "TIMERS";
123 std::vector<std::string> patterns;
124
125 TDirectory* tdir = gDirectory;
126
127 bool verbose = false;
128
129 bool noref = false;
130
131 std::string frefname = "";
132
133 double xoffset = 0.17;
134
135 bool show_directory = true;
136
137 bool norm_width = true;
138
139 bool logx = false;
140
141 bool withlumiblock = false;
142
143 bool withfractional = false;
144
145 std::vector<std::string> replace_list;
146
147 // Parse the arguments
148 std::vector<std::string> algorithms;
149 for(int argnum = 1; argnum < argc; argnum++){
150 std::string arg = argv[argnum];
151
152 if (arg == "-h" || arg == "--help") {
153 return usage(argv[0], 0);
154 }
155 else if (arg == "-o" || arg == "--outputfolder") {
156 if (++argnum < argc) { output_dir = argv[argnum]; }
157 else { return usage(argv[0], -1); }
158 }
159 else if (arg == "-x" || arg == "--xoffset") {
160 if (++argnum < argc) { xoffset = std::atof(argv[argnum]); }
161 else { return usage(argv[0], -1); }
162 }
163 else if (arg == "-t" || arg == "--tag") {
164 if (++argnum < argc) { tag = std::string("-") + argv[argnum]; }
165 else { return usage(argv[0], -1); }
166 }
167 else if (arg == "-k" || arg == "--key") {
168 if (++argnum < argc) { key = argv[argnum] + std::string("-"); }
169 else { return usage(argv[0], -1); }
170 }
171 else if (arg == "-r" || arg == "--replace") {
172 if (++argnum < argc) replace_list.push_back( argv[argnum] );
173 else { return usage(argv[0], -1); }
174 if (++argnum < argc) replace_list.push_back( argv[argnum] );
175 else { return usage(argv[0], -1); }
176 }
177 else if ( arg == "--logx") {
178 logx = true;
179 }
180 else if (arg == "-np" || arg == "--nopng") {
181 nopng = true;
182 }
183 else if (arg == "-f" || arg == "--frac" ) {
184 withfractional = true;
185 }
186 else if (arg == "-a" || arg == "--auto") {
187 autochains = true;
188 }
189 else if (arg == "--nodir") {
190 show_directory = false;
191 }
192 else if (arg == "-v" || arg == "--verbose") {
193 verbose = true;
194 }
195 else if (arg == "-lb" ) {
196 withlumiblock = true;
197 }
198 else if (arg == "-nr" || arg == "--noref") {
199 noref = true;
200 }
201 else if (arg == "-w" || arg == "--binwidth") {
202 norm_width = true;
203 }
204 else if (arg == "-as" || arg == "--atlasstyle") {
205 atlasstyle = true;
206 }
207 else if (arg == "-al" || arg == "--atlaslabel") {
208 atlaslabel = true;
209 }
210 else if (arg == "-ap" || arg == "--autopattern") {
211 if (++argnum < argc) autopattern = argv[argnum];
212 else return usage(argv[0], -1);
213 }
214 else if (arg == "-d" || arg == "--directory") {
215 if (++argnum < argc) directory = argv[argnum];
216 else return usage(argv[0], -1);
217 }
218 else if (arg == "-p" || arg == "--pattern") {
219 if (++argnum < argc) patterns.push_back(argv[argnum]);
220 else return usage(argv[0], -1);
221 }
222 else {
223 if (ftest == 0) {
224 std::string file = globbed(arg);
225 if (exists(file)) {
226 ftest = new TFile( file.c_str() );
227 }
228 else {
229 std::cerr << "main(): test file " << arg << " does not exist" << std::endl;
230 return -2;
231 }
232 }
233 else if ( frefname=="" ) frefname = std::move(arg);
234 else {
235 algorithms.push_back(std::move(arg));
236 }
237 }
238 }
239
240 if ( patterns.empty() ) patterns.push_back( "_TotalTime" );
241
242
243 if (ftest == 0 || ( noref==false && frefname=="" ) ) {
244 return usage(argv[0], -4);
245 }
246
247 if ( fref == 0 && !noref ) {
248 std::string file = globbed(frefname);
249 if (exists(file)) {
250 fref = new TFile( file.c_str() );
251 }
252 else {
253 std::cerr << "main(): ref file " << frefname << " does not exist" << std::endl;
254 return -3;
255 }
256 }
257
258 if ( atlasstyle ) SetAtlasStyle();
259
260 gStyle->SetErrorX(0);
261
262 if ( noref ) fref = ftest;
263
264 if ( noref ) Plotter::setmeanplotref(!noref);
265
266 if ( ftest && autochains ) {
267
268 ftest->cd();
269
270 std::vector<std::string> dirs;
271
272 contents( dirs, gDirectory, directory, patterns );
273
274 if ( autopattern=="" ) {
275 for ( unsigned j=0 ; j<dirs.size() ; j++ ) {
276 if ( verbose ) std::cout << "\talgorithm " << dirs[j] << std::endl;
277 algorithms.push_back( dirs[j] );
278 }
279 }
280 else {
281 std::cout << "autopattern : " << autopattern << std::endl;
282 for ( unsigned j=0 ; j<dirs.size() ; j++ ) {
283 if ( dirs[j].find(autopattern)!=std::string::npos ) {
284 algorithms.push_back( dirs[j] );
285 std::cout << "adding " << algorithms.back() << std::endl;
286 }
287 }
288 }
289
290 }
291
292
293
294 // Make output directory
295 if ( output_dir != "" ) {
296 if ( mkdir( output_dir.c_str(), 0777 ) ) {
297 if ( exists(output_dir) ) std::cerr << "main() directory " << output_dir << " aleady exists" << std::endl;
298 else std::cerr << "main() could not create directory " << output_dir << std::endl;
299 }
300 output_dir += "/";
301 }
302
303#if 0
304 // Get the timers directories from input files
305 // TDirectoryFile* testtimers = 0;
306 TDirectory* testtimers = 0;
307
308 if ( directory!="" ) ftest->GetObject( directory.c_str(), testtimers );
309 else testtimers = ftest;
310
311 if (testtimers == 0 ) {
312 std::cerr << "main(): can not find timers in test file" << std::endl;
313 // return -1;
314 }
315
316 // TDirectoryFile* reftimers = 0;
317 TDirectory* reftimers = 0;
318
319 if ( directory!="" ) fref->GetObject( directory.c_str(), reftimers );
320 else reftimers = fref;
321
322 if (reftimers == 0 ) {
323 std::cerr << "main(): can not find timers in ref file" << std::endl;
324 // return -1;
325 }
326#endif
327
328 TFile fcck( "fcck.root", "recreate" );
329
330
331 std::vector<histoinfo> histograms;
332 histograms.push_back( histoinfo("_TotalTime", "Total time") );
333
334 // Provide output to user for progress status
335 // std::cout << "main() processing algorithms : " << algorithms << std::endl;
336
337 // Loop over histograms
338 // for (unsigned int histogram = 0; histogram < histograms.size(); ++histogram) {
339 for (unsigned int histogram=histograms.size(); histogram-- ; ) {
340
341
342
343 std::cout << "\nhistogram " << histograms.at(histogram) << " : with " << algorithms.size() << " algorithms" << std::endl;
344
345
346 std::string xaxis = histograms.at(histogram).dname + " [ms]";
347 std::string yaxis = "Entries";
348
349
350 // Loop over input algorithms
351 // for (unsigned int algorithm = 0; algorithm < algorithms.size(); ++algorithm) {
352 for (unsigned int algorithm = algorithms.size(); algorithm-- ; ) {
353
354 if ( !withlumiblock && algorithms[algorithm].find("LumiBlock")!=std::string::npos ) continue;
355
356 if ( !withfractional && algorithms[algorithm].find("Fractional")!=std::string::npos ) continue;
357
358 std::cout << "\nmain() processing algorithm : " << algorithms[algorithm] << std::endl;
359
360 TCanvas* c1 = new TCanvas( label("canvas-%d",int(histogram)).c_str(), "histogram", 800, 600 );
361 c1->cd();
362
363 double x1 = xoffset;
364 double x2 = xoffset+0.25;
365 double y1 = 0.75;
366 double y2 = 0.87;
367
371
372 Legend legend(x1, x2, y1, y2);
373
374
375 std::string histname = algorithms[algorithm]; // + histograms.at(histogram).fname;
376
377 std::string xaxis_tmp = xaxis;
378 bool fractional = contains( histname, "Fractional" );
379 if ( fractional ) xaxis_tmp = "Fraction of " + histograms.at(histogram).dname;
380
381
382 // std::cout << "\t" << histname << "\t" << algorithms.at(algorithm) << " " << histograms.at(histogram).fname << std::endl;
383
384
385 // std::cout << "Directory: " << gDirectory->GetName() << std::endl;
386
387 TH1F* testhist = (TH1F*)ftest->Get(histname.c_str());
388
389 if (testhist == 0 ) {
390 std::cerr << "main(): can not find hist " << histname << " in test file" << std::endl;
391 continue;
392 }
393
394 std::cout << "mean time: " << testhist->GetMean() << "\t:: " << testhist->GetName() << std::endl;
395
396 if ( norm_width ) binwidth( testhist );
397
399 if ( std::string(testhist->ClassName()).find("TH1")==std::string::npos ) continue;
400
401 testhist->SetName( tail(algorithms[algorithm],"/").c_str() );
402 testhist->Write();
403
404 // std::cout << "\n\nfound histname " << histname << std::endl;
405
406 std::string refhistname = std::move(histname);
407
408
409 TH1F* refhist = (TH1F*)fref->Get(refhistname.c_str());
410
411
414
415 if ( refhist==0 && replace_list.size()>=2 ) {
416
417 for ( size_t ir=0 ; ir<replace_list.size()-1 ; ir+=2 ) {
418
419 size_t pos = refhistname.find(replace_list[ir]);
420 if ( pos != std::string::npos ) {
421
422 while( pos!=std::string::npos ) {
423 refhistname.replace( pos, replace_list[ir].size(), "XXXX" );
424 pos = refhistname.find(replace_list[ir]);
425 }
426
427 pos = refhistname.find("XXXX");
428 while( pos!=std::string::npos ) {
429 refhistname.replace( pos, 4, replace_list[ir+1] );
430 pos = refhistname.find("XXXX");
431 }
432 }
433
434 }
435
436 refhist = (TH1F*)fref->Get(refhistname.c_str());
437
438 }
439
440 if (refhist == 0 ) {
441 std::cerr << "main(): can not find hist " << refhistname << " in ref file" << std::endl;
442 continue;
443 }
444
445 if ( norm_width ) binwidth( refhist );
446
447 testhist->GetYaxis()->SetTitle(yaxis.c_str());
448 testhist->GetYaxis()->SetTitleOffset(1.5);
449
450 refhist->GetYaxis()->SetTitle(yaxis.c_str());
451 refhist->GetYaxis()->SetTitleOffset(1.5);
452
453 testhist->GetXaxis()->SetTitle(xaxis_tmp.c_str());
454 testhist->GetXaxis()->SetTitleOffset(1.5);
455
456 refhist->GetXaxis()->SetTitle(xaxis_tmp.c_str());
457 refhist->GetXaxis()->SetTitleOffset(1.5);
458
459
460 Plots plots;
461
462 std::string algname = tail(algorithms[algorithm], "/" );
463 std::string dirname = tail( head(algorithms[algorithm], "/" ), "/" );
464 std::string algpname = algorithms[algorithm];
465 replace( algpname, '/', '_' );
466
467 if ( algname.find("h_")==0 ) algname.erase(0, 2);
468
469 // size_t indetpos = algname.find("InDet");
470 // if ( indetpos!=std::string::npos ) algname.erase( indetpos, 5);
471
472 plots.push_back( Plotter( testhist, refhist, " "+algname ) );
473
474 std::string plotname = key + algpname + tag;
475
476 std::string stub = directory;
477
478 size_t pos = stub.find('/');
479 while ( pos!=std::string::npos ) { stub.erase( pos, 1 ); pos = stub.find('/'); }
480
481 while ( plotname.find(stub)!=std::string::npos ) {
482 plotname.erase( 0, plotname.find(stub)+stub.size() );
483 }
484
485 while ( plotname.find('_')==0 ) plotname.erase( 0, 1 );
486
487 plotname = output_dir + plotname;
488
489 std::cout << "output dir " << output_dir << "\tkey " << key << "\talgname " << algname << "\ttag " << tag << std::endl;
490
491 // std::cout << "testhist " << testhist << " " << refhist << std::endl;
492
493
494 std::vector<std::string> chains;
495 chains.push_back( algname + tag );
496
497 bool ylogt = ylog;
498
499 double Nent = plotable( testhist );
500 double Nent_ref = plotable( refhist );
501
502 if ( fractional ) ylogt = false;
503
504 if ( Nent==0 || Nent_ref==0 ) {
505 ylogt = false;
506 std::cerr << "histograms empty: " << testhist->GetName() << std::endl;
507 continue;
508 }
509
510
511 testhist->SetTitle("");
512 refhist->SetTitle("");
513
514
515 plots.SetLogy(ylogt);
516
517 if ( logx ) plots.SetLogx(true);
518
519 double rmin = plots.realmin();
520 double rmax = plots.realmax();
521
522 if ( rmin == rmax ) rmin = 0;
523
524 if ( ylogt ) {
525 if ( rmin == 0 ) rmin = rmax*0.0001;
526 double delta = std::log10(rmax)-std::log10(rmin);
527 if ( atlasstyle ) plots.Max( rmax*std::pow(10,delta*0.15*2*(chains.size()+taglabels.size()+1.5)) );
528 else plots.Max( rmax*std::pow(10,delta*0.15*2*(chains.size()+taglabels.size()+1.0)) );
529 plots.Min( rmin*std::pow(10,-delta*0.1) );
530 }
531 else {
532 double delta = rmax-rmin;
533 plots.Max( rmax+delta*0.1*2*chains.size() );
534
535 double pmin = rmin-delta*0.1;
536 if ( pmin>0 ) plots.Min( pmin );
537 else plots.Min( 0 );
538
539 }
540
541 std::vector<double> range = plots.findxrange();
542
543 double lower = range[0];
544 double upper = range[1];
545
546 if ( lower<0 ) lower = 0;
547
548 plots.SetRangeUser( lower, upper );
549
550 plots.Draw( legend, true );
551
552 std::string dirtitle = std::move(dirname);
553 if ( dirtitle.find("HLT_")==0 && dirtitle.find("__")!=std::string::npos ) dirtitle.erase( dirtitle.find("__"), dirtitle.size() );
554
555 if ( show_directory ) DrawLabel( x1+0.02, y2+0.02, dirtitle, kBlack, legend.TextSize(), legend.TextFont() );
556
557 if ( atlasstyle && atlaslabel ) ATLASLabel(0.68, 0.88, "Internal");
558
562 if ( logx ) gPad->SetLogx(true);
563
564 plots.back().Print( (plotname+".pdf").c_str() );
565 if ( !nopng ) plots.back().Print( (plotname+".png").c_str() );
566
567 delete c1;
568
569 std::cout << "done algorithm " << algorithm << " " << algorithms[algorithm] << std::endl;
570 }
571
572 std::cout << "done hist " << histogram << " " << histograms.at(histogram).dname << " " << std::endl;
573 }
574
575 fcck.Write();
576 fcck.Close();
577
578 tdir->cd();
579
580
581#ifdef USE_SLOW_ROOT_FILE_DELETION
582
583 std::cout << "deleting ftest" << std::endl;
584
587
588
589 if ( fref!=ftest ) {
590 std::cout << "deleting fref" << std::endl;
591
592 // delete reftimers;
593 delete fref;
594 }
595
596 // delete testtimers;
597 delete ftest;
598
599#endif
600
601 std::cout << "done" << std::endl;
602
603 return 0;
604}
int DrawLabel(float xstart, float ystart, string label)
int upper(int c)
void ATLASLabel(Double_t x, Double_t y, char *text=NULL, Color_t color=1)
ATLAS Style, based on a style file from BaBar.
std::string histogram
Definition chains.cxx:52
Header file for AthHistogramAlgorithm.
slightly more convenient legend class
Definition computils.h:337
set of generic plots
Definition computils.h:917
static void setmeanplotref(bool b)
Definition computils.h:862
double plotable(TH1 *h)
void contents(std::vector< std::string > &keys, TDirectory *td, const std::string &directory, const std::string &pattern, const std::string &path)
std::string globbed(const std::string &s)
match a file name
bool exists(const std::string &filename)
does a file exist
std::string tail(std::string s, const std::string &pattern)
tail of a string
std::string head(std::string s, const std::string &pattern)
head of a string
tPlotter< TH1F > Plotter
Definition computils.h:886
std::ostream & operator<<(std::ostream &s, const histoinfo &h)
Definition cpucost.cxx:77
int ir
counter of the current depth
Definition fastadd.cxx:49
StatusCode usage()
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition hcg.cxx:310
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:114
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138
std::string algorithm
Definition hcg.cxx:85
bool verbose
Definition hcg.cxx:73
std::map< std::string, int > dirs
list of directories to be explicitly included, together with corresponding depths of subdirectories
Definition hcg.cxx:102
int main()
Definition hello.cxx:18
std::string label(const std::string &format, int i)
Definition label.h:19
bool binwidth
Definition listroot.cxx:58
std::vector< std::string > patterns
Definition listroot.cxx:187
histoinfo(const std::string &f, const std::string &d)
Definition cpucost.cxx:71
std::string dname
Definition cpucost.cxx:73
std::string fname
Definition cpucost.cxx:72
TFile * file
std::string dirname(std::string name)
Definition utils.cxx:200