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
91 {
92
93 if (argc < 4) {
return usage(argv[0], -1); }
94
95 std::string output_dir = "";
98
99 gStyle->SetPadRightMargin(0.05);
100 gStyle->SetPadTopMargin(0.05);
101
102 gStyle->SetPadLeftMargin(0.14);
103 gStyle->SetPadBottomMargin(0.14);
104
105
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
124
126
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
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") {
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") {
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) {
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
241
242
243 if (ftest == 0 || ( noref==false && frefname=="" ) ) {
244 return usage(argv[0], -4);
245 }
246
247 if ( fref == 0 && !noref ) {
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
259
260 gStyle->SetErrorX(0);
261
262 if ( noref ) fref = ftest;
263
265
266 if ( ftest && autochains ) {
267
268 ftest->cd();
269
270 std::vector<std::string>
dirs;
271
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
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
305
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
314 }
315
316
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
325 }
326#endif
327
328 TFile fcck( "fcck.root", "recreate" );
329
330
333
334
335
336
337
338
340
341
342
343 std::cout <<
"\nhistogram " <<
histograms.at(
histogram) <<
" : with " << algorithms.size() <<
" algorithms" << std::endl;
344
345
347 std::string yaxis = "Entries";
348
349
350
351
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 );
362
364 double x2 = xoffset+0.25;
367
371
373
374
376
377 std::string xaxis_tmp = xaxis;
378 bool fractional =
contains( histname,
"Fractional" );
380
381
382
383
384
385
386
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
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
461
464 std::string algpname = algorithms[
algorithm];
466
468
469
470
471
472 plots.push_back(
Plotter( testhist, refhist,
" "+algname ) );
473
474 std::string plotname =
key + algpname +
tag;
475
477
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
492
493
494 std::vector<std::string>
chains;
495 chains.push_back( algname + tag );
496
497 bool ylogt = ylog;
498
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;
534
535 double pmin = rmin-delta*0.1;
536 if ( pmin>0 )
plots.Min( pmin );
538
539 }
540
541 std::vector<double>
range =
plots.findxrange();
542
543 double lower =
range[0];
545
546 if ( lower<0 ) lower = 0;
547
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
568
569 std::cout <<
"done algorithm " <<
algorithm <<
" " << algorithms[
algorithm] << std::endl;
570 }
571
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
593 delete fref;
594 }
595
596
597 delete ftest;
598
599#endif
600
601 std::cout << "done" << std::endl;
602
603 return 0;
604}
void ATLASLabel(Double_t x, Double_t y, char *text=NULL, Color_t color=1)
slightly more convenient legend class
static void setmeanplotref(bool b)
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
int ir
counter of the current depth
std::string replace(std::string s, const std::string &s2, const std::string &s3)
bool contains(const std::string &s, const std::string ®x)
does a string contain the substring
std::string find(const std::string &s)
return a remapped string
std::map< std::string, int > dirs
list of directories to be explicitly included, together with corresponding depths of subdirectories
std::string label(const std::string &format, int i)
std::vector< std::string > patterns
mkdir(path, recursive=True)
TH1F(name, title, nxbins, bins_par2, bins_par3=None, path='', **kwargs)
std::string dirname(std::string name)