ATLAS Offline Software
Loading...
Searching...
No Matches
cpucost.cxx File Reference
#include <stdlib.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <iostream>
#include <string>
#include <vector>
#include "utils.h"
#include "label.h"
#include "DrawLabel.h"
#include "TCanvas.h"
#include "TFile.h"
#include "TH1D.h"
#include "TLegend.h"
#include "TStyle.h"
#include "TSystem.h"
#include "TKey.h"
#include "TList.h"
#include "TDirectory.h"
#include "computils.h"
#include "AtlasStyle.h"
#include "AtlasLabels.h"

Go to the source code of this file.

Classes

struct  histoinfo

Functions

int usage (const std::string &name, int status)
 Prints usage instructions to standard output and returns given status.
std::ostream & operator<< (std::ostream &s, const histoinfo &h)
void binwidth (TH1F *h)
int main (int argc, char **argv)

Detailed Description

Author
ben sowden
Date
Mon 04 Aug 2014 10:45:00 BST

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

Definition in file cpucost.cxx.

Function Documentation

◆ binwidth()

void binwidth ( TH1F * h)

Definition at line 82 of file cpucost.cxx.

82 {
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}
Header file for AthHistogramAlgorithm.

◆ main()

int main ( int argc,
char ** argv )

no longer adjust the legend if no reference times are to be plotted as we now more properly set the legend size automatically depending on the number of entries

skip TH2 and TProfiles for the moment ...

if we cannot find the reference histogram, try replacing all patterns that are requested in the reference hist name

could simply run gPad->SetLogyx( logx ); but that would interfere with the individual plot setting from the config file

Definition at line 91 of file cpucost.cxx.

91 {
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)
std::string histogram
Definition chains.cxx:52
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
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
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
str directory
Definition DeMoScan.py:78
mkdir(path, recursive=True)
TH1F(name, title, nxbins, bins_par2, bins_par3=None, path='', **kwargs)
TFile * file
std::string dirname(std::string name)
Definition utils.cxx:200

◆ operator<<()

std::ostream & operator<< ( std::ostream & s,
const histoinfo & h )

Definition at line 77 of file cpucost.cxx.

77 {
78 return s << h.fname << " : " << h.dname;
79}

◆ usage()

int usage ( const std::string & name,
int status )

Prints usage instructions to standard output and returns given status.

Definition at line 42 of file cpucost.cxx.

42 {
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}
status
Definition merge.py:16