ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/AnalysisFramework/Plotting/Modules/GeneralToolBox.C
Revision: 1.39
Committed: Thu Oct 13 09:53:54 2011 UTC (13 years, 6 months ago) by buchmann
Content type: text/plain
Branch: MAIN
CVS Tags: Honeypot, cbaf_2p1ifb
Changes since 1.38: +0 -8 lines
Log Message:
Removed duplicate flagging function

File Contents

# Content
1 #include <iostream>
2 #include <iomanip>
3 #include <sstream>
4 #include <fstream>
5 #include <vector>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <limits>
11
12 #include <TFile.h>
13 #include <TTree.h>
14 #include <TCut.h>
15 #include <TLegend.h>
16 #include <TLatex.h>
17 #include <TText.h>
18 #include <TGraph.h>
19 #include <TH1.h>
20 #include <TF1.h>
21 #include <TMath.h>
22 #include <THStack.h>
23 #include <TColor.h>
24 #include <TStyle.h>
25 #include <TCanvas.h>
26 #include <TError.h>
27 #include <TVirtualPad.h>
28 #include <TGraphAsymmErrors.h>
29 #include <TPaveText.h>
30 #include <TRandom.h>
31 #include <TGraphErrors.h>
32 #ifndef Verbosity
33 #define Verbosity 0
34 #endif
35
36
37 /*
38 #ifndef SampleClassLoaded
39 #include "SampleClass.C"
40 #endif
41 */
42 #define GeneralToolBoxLoaded
43
44 using namespace std;
45
46 namespace PlottingSetup {
47 string cbafbasedir="";
48 string basedirectory="";
49 }
50
51 bool dopng=false;
52 bool doC=false;
53 bool doeps=false;
54 bool dopdf=false;
55 bool doroot=false;
56 float generaltoolboxlumi;
57
58 TLegend* make_legend(string title,float posx,float posy, bool drawleg);
59 TText* write_title(bool, string);
60 TText* write_title_low(string title);
61
62 TText* write_text(float xpos,float ypos,string title);
63 float computeRatioError(float a, float da, float b, float db);
64 float computeProductError(float a, float da, float b, float db);
65 TGraphAsymmErrors *histRatio(TH1F *h1,TH1F *h2, int id, vector<float>binning);
66 void setlumi(float l);
67 void DrawPrelim(float writelumi);
68 void CompleteSave(TCanvas *can, string filename, bool feedback);
69 void CompleteSave(TVirtualPad *can, string filename, bool feedback);
70 void write_warning(string funcname, string text);
71 void write_error(string funcname, string text);
72 void write_info(string funcname, string text);
73 string get_directory();
74 //-------------------------------------------------------------------------------------
75
76 template<typename U>
77 inline bool isanyinf(U value)
78 {
79 return !(value >= std::numeric_limits<U>::min() && value <=
80 std::numeric_limits<U>::max());
81 }
82
83 stringstream warningsummary;
84 stringstream infosummary;
85 stringstream errorsummary;
86
87 template<class A>
88 string any2string(const A& a){
89 ostringstream out;
90 out << a;
91 return out.str();
92 }
93
94 void do_png(bool s) { dopng=s;}
95 void do_eps(bool s) { doeps=s;}
96 void do_C(bool s) { doC=s;}
97 void do_pdf(bool s) { dopdf=s;}
98 void do_root(bool s){ doroot=s;}
99
100 string topdir(string child) {
101 string tempdirectory=child;
102 if(tempdirectory.substr(tempdirectory.length()-1,1)=="/") tempdirectory=tempdirectory.substr(0,tempdirectory.length());
103 //we now have a directory without the trailing slash so we can just look for the last non-slash character :-)
104 for(int ichar=tempdirectory.length()-1;ichar>=0;ichar--) {
105 if(tempdirectory.substr(ichar,1)=="/") {
106 return tempdirectory.substr(0,ichar);
107 }
108 }
109 }
110
111 template < typename CHAR_TYPE,
112 typename TRAITS_TYPE = std::char_traits<CHAR_TYPE> >
113
114 struct basic_teebuf : public std::basic_streambuf< CHAR_TYPE, TRAITS_TYPE >
115 {
116 typedef std::basic_streambuf< CHAR_TYPE, TRAITS_TYPE > streambuf_type ;
117 typedef typename TRAITS_TYPE::int_type int_type ;
118
119 basic_teebuf( streambuf_type* buff_a, streambuf_type* buff_b )
120 : first(buff_a), second(buff_b) {}
121
122 protected:
123 virtual int_type overflow( int_type c )
124 {
125 const int_type eof = TRAITS_TYPE::eof() ;
126 if( TRAITS_TYPE::eq_int_type( c, eof ) )
127 return TRAITS_TYPE::not_eof(c) ;
128 else
129 {
130 const CHAR_TYPE ch = TRAITS_TYPE::to_char_type(c) ;
131 if( TRAITS_TYPE::eq_int_type( first->sputc(ch), eof ) ||
132 TRAITS_TYPE::eq_int_type( second->sputc(ch), eof ) )
133 return eof ;
134 else return c ;
135 }
136 }
137
138 virtual int sync()
139 { return !first->pubsync() && !second->pubsync() ? 0 : -1 ; }
140
141 private:
142 streambuf_type* first ;
143 streambuf_type* second ;
144 };
145
146 template < typename CHAR_TYPE,
147 typename TRAITS_TYPE = std::char_traits<CHAR_TYPE> >
148 struct basic_teestream : public std::basic_ostream< CHAR_TYPE, TRAITS_TYPE >
149 {
150 typedef std::basic_ostream< CHAR_TYPE, TRAITS_TYPE > stream_type ;
151 typedef basic_teebuf< CHAR_TYPE, TRAITS_TYPE > streambuff_type ;
152
153 basic_teestream( stream_type& first, stream_type& second )
154 : stream_type( &stmbuf), stmbuf( first.rdbuf(), second.rdbuf() ) {}
155
156 ~basic_teestream() { stmbuf.pubsync() ; }
157
158 private: streambuff_type stmbuf ;
159 };
160
161 typedef basic_teebuf<char> teebuf ;
162 typedef basic_teestream<char> teestream ;
163
164 std::ofstream file("LOG.txt",ios::app) ;
165 std::ofstream texfile("Tex.txt") ;
166 std::ofstream efile("LOGerr.txt",ios::app) ;
167 teestream dout( file, std::cout ) ; // double out
168 teestream eout( efile, std::cout ) ; // double out (errors)
169
170 template < typename CHAR_TYPE,
171 typename TRAITS_TYPE = std::char_traits<CHAR_TYPE> >
172
173 struct basic_tripbuf : public std::basic_streambuf< CHAR_TYPE, TRAITS_TYPE >
174 {
175 typedef std::basic_streambuf< CHAR_TYPE, TRAITS_TYPE > streambuf_type ;
176 typedef typename TRAITS_TYPE::int_type int_type ;
177
178 basic_tripbuf( streambuf_type* buff_a, streambuf_type* buff_b, streambuf_type* buff_c )
179 : first(buff_a), second(buff_b), third(buff_c) {}
180
181 protected:
182 virtual int_type overflow( int_type d )
183 {
184 const int_type eof = TRAITS_TYPE::eof() ;
185 if( TRAITS_TYPE::eq_int_type( d, eof ) )
186 return TRAITS_TYPE::not_eof(d) ;
187 else
188 {
189 const CHAR_TYPE ch = TRAITS_TYPE::to_char_type(d) ;
190 if( TRAITS_TYPE::eq_int_type( first->sputc(ch), eof ) ||
191 TRAITS_TYPE::eq_int_type( second->sputc(ch), eof )||
192 TRAITS_TYPE::eq_int_type( third->sputc(ch), eof ) )
193 return eof ;
194 else return d ;
195 }
196 }
197
198 virtual int sync()
199 { return !first->pubsync() && !second->pubsync() && !third->pubsync() ? 0 : -1 ; }
200
201 private:
202 streambuf_type* first ;
203 streambuf_type* second ;
204 streambuf_type* third ;
205 };
206
207 template < typename CHAR_TYPE,
208 typename TRAITS_TYPE = std::char_traits<CHAR_TYPE> >
209 struct basic_tripstream : public std::basic_ostream< CHAR_TYPE, TRAITS_TYPE >
210 {
211 typedef std::basic_ostream< CHAR_TYPE, TRAITS_TYPE > stream_type ;
212 typedef basic_tripbuf< CHAR_TYPE, TRAITS_TYPE > streambuff_type ;
213
214 basic_tripstream( stream_type& first, stream_type& second, stream_type& third )
215 : stream_type( &stmbuf), stmbuf( first.rdbuf(), second.rdbuf(), third.rdbuf() ) {}
216
217 ~basic_tripstream() { stmbuf.pubsync() ; }
218
219 private: streambuff_type stmbuf ;
220 };
221
222 //typedef basic_tripbuf<char> teebuf ;
223 typedef basic_tripstream<char> tripplestream ;
224
225 tripplestream tout( file, texfile , std::cout ) ; // tripple out
226
227 void ensure_directory_exists(string thisdirectory) {
228 struct stat st;
229 if(stat(thisdirectory.c_str(),&st) == 0) {
230 if(Verbosity>0) dout << "Directory " << thisdirectory << " exists!" << endl;
231 }
232 else {
233 if(Verbosity>0) dout << "Directory " << thisdirectory << " does not exist. Need to create it!" << endl;
234 ensure_directory_exists(topdir(thisdirectory));
235 if (mkdir(thisdirectory.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH))
236 if(Verbosity>0) dout << "Created the directory " << thisdirectory << endl;
237 }
238 }
239
240 void initialize_log() {
241 dout << "____________________________________________________________" << endl;
242 dout << endl;
243 dout << " " << endl;
244 dout << " JJJJJJJJJJJZZZZZZZZZZZZZZZZZZZBBBBBBBBBBBBBBBBB " << endl;
245 dout << " J:::::::::JZ:::::::::::::::::ZB::::::::::::::::B " << endl;
246 dout << " J:::::::::JZ:::::::::::::::::ZB::::::BBBBBB:::::B " << endl;
247 dout << " JJ:::::::JJZ:::ZZZZZZZZ:::::Z BB:::::B B:::::B" << endl;
248 dout << " J:::::J ZZZZZ Z:::::Z B::::B B:::::B" << endl;
249 dout << " J:::::J Z:::::Z B::::B B:::::B" << endl;
250 dout << " J:::::J Z:::::Z B::::BBBBBB:::::B " << endl;
251 dout << " J:::::j Z:::::Z B:::::::::::::BB " << endl;
252 dout << " J:::::J Z:::::Z B::::BBBBBB:::::B " << endl;
253 dout << "JJJJJJJ J:::::J Z:::::Z B::::B B:::::B" << endl;
254 dout << "J:::::J J:::::J Z:::::Z B::::B B:::::B" << endl;
255 dout << "J::::::J J::::::J ZZZ:::::Z ZZZZZ B::::B B:::::B" << endl;
256 dout << "J:::::::JJJ:::::::J Z::::::ZZZZZZZZ:::ZBB:::::BBBBBB::::::B" << endl;
257 dout << " JJ:::::::::::::JJ Z:::::::::::::::::ZB:::::::::::::::::B " << endl;
258 dout << " JJ:::::::::JJ Z:::::::::::::::::ZB::::::::::::::::B " << endl;
259 dout << " JJJJJJJJJ ZZZZZZZZZZZZZZZZZZZBBBBBBBBBBBBBBBBB " << endl;
260 dout << " " << endl;
261 dout << endl << endl;
262 dout << "____________________________________________________________" << endl;
263 time_t rawtime;
264 struct tm * timeinfo;
265 time ( &rawtime );
266 dout << " Analysis run on " << asctime (localtime ( &rawtime ));
267 dout << "____________________________________________________________" << endl;
268 dout << " Results saved in : " << get_directory() << endl << endl;
269 }
270
271 void extract_cbaf_dir(string curpath) {
272 int position=curpath.find("/Plotting");
273 if(position<0) position=curpath.find("/DistributedModelCalculations");
274 if(position<0) position=curpath.find("/various_assignments");
275 PlottingSetup::cbafbasedir=curpath.substr(0,position);
276 }
277
278 void set_directory(string basedir="") {
279 if(basedir.substr(0,1)=="/") basedir=basedir.substr(1,basedir.length()-1);
280 if(basedir.substr(basedir.length()-1,1)!="/") basedir+="/";
281 char currentpath[1024];
282 char *path = getcwd(currentpath,1024);
283 PlottingSetup::basedirectory=(string)currentpath+"/Plots/"+basedir;
284 ensure_directory_exists(PlottingSetup::basedirectory);
285 initialize_log();
286 extract_cbaf_dir(currentpath);
287 }
288
289 string get_directory() {
290 return PlottingSetup::basedirectory;
291 }
292
293 string extract_directory(string savethis) {
294 bool foundslash=false;
295 int position=savethis.length();
296 while(!foundslash&&position>0) {
297 position--;
298 if(savethis.substr(position,1)=="/") foundslash=true;
299 }
300 if(position>0) return savethis.substr(0,position+1);
301 else return "";
302 }
303
304 string extract_root_dir(string name) {
305 int position = -1;
306 if(name.substr(0,1)=="/") name=name.substr(1,name.length()-1);
307 for(int ipos=0;ipos<name.length();ipos++) {
308 if(name.substr(ipos,1)=="/") position=ipos;
309 }
310 if(position==-1) return "";
311 return name.substr(0,position);
312 }
313
314 string extract_root_filename(string name) {
315 int position = -1;
316 if(name.substr(0,1)=="/") name=name.substr(1,name.length()-1);
317 for(int ipos=0;ipos<name.length();ipos++) {
318 if(name.substr(ipos,1)=="/") position=ipos;
319 }
320 return name.substr(position+1,name.length()-position-1);
321 }
322
323 void SaveToRoot_REAL(TCanvas *can, string name) {
324 TFile *fout = new TFile((TString(PlottingSetup::basedirectory)+TString("allplots.root")),"UPDATE");
325 fout->cd();
326 string directory=extract_root_dir(name);
327 string filename=extract_root_filename(name);
328 if(directory!="") {
329 if(fout->GetDirectory(directory.c_str())) {
330 fout->cd(directory.c_str());
331 can->Write(filename.c_str());
332 }else {
333 fout->mkdir(directory.c_str());
334 fout->cd(directory.c_str());
335 can->Write(filename.c_str());
336 }
337 } else {
338 can->Write(filename.c_str());
339 }
340 fout->cd();
341 fout->Close();
342 }
343
344 void SaveToRoot(TCanvas *can, string name) {
345 write_warning(__FUNCTION__,"Saving to root file has been deactivated (it works but when opening ROOT complains a bit about filenames which is unelegant)");
346 //if you want to activate this feature anyway, you can rename this to SaveToRoot_Placeholder and rename SaveToRoot_REAL to SaveToRoot.
347 }
348
349 void CompleteSave(TCanvas *can, string filename, bool feedback=false, bool redraw=true) {
350 //any change you make here should also be done below in the CompleteSave function for virtual pads
351 Int_t currlevel=gErrorIgnoreLevel;
352 if(!feedback) gErrorIgnoreLevel=1001;
353 if(redraw) can->RedrawAxis();
354 ensure_directory_exists(extract_directory(PlottingSetup::basedirectory+filename));
355 if(dopng) can->SaveAs((PlottingSetup::basedirectory+filename+".png").c_str());
356 if(doeps) can->SaveAs((PlottingSetup::basedirectory+filename+".eps").c_str());
357 if(dopdf) can->SaveAs((PlottingSetup::basedirectory+filename+".pdf").c_str());
358 if(doC) can->SaveAs((PlottingSetup::basedirectory+filename+".C").c_str());
359 if(doroot) SaveToRoot(can,filename);
360 gErrorIgnoreLevel=currlevel;
361 dout << "Saved " << filename << " in all requested formats" << endl;
362 }
363
364 void CompleteSave(TVirtualPad *can, string filename, bool feedback=false, bool redraw=true) {
365 Int_t currlevel=gErrorIgnoreLevel;
366 if(!feedback) gErrorIgnoreLevel=1001;
367 if(redraw) can->RedrawAxis();
368 ensure_directory_exists(extract_directory(PlottingSetup::basedirectory+filename));
369 if(dopng) can->SaveAs((PlottingSetup::basedirectory+filename+".png").c_str());
370 if(doeps) can->SaveAs((PlottingSetup::basedirectory+filename+".eps").c_str());
371 if(doC) can->SaveAs((PlottingSetup::basedirectory+filename+".C").c_str());
372 gErrorIgnoreLevel=currlevel;
373 dout << "Saved " << filename << " in all requested formats" << endl;
374 }
375
376
377 void setlumi(float l) {
378 generaltoolboxlumi=l;
379 }
380
381 int write_first_line(vector<vector<string> > &entries) {
382 if(entries.size()>0) {
383 vector<string> firstline = entries[0];
384 int ncolumns=firstline.size();
385 int ndividers=ncolumns+1;
386 int cellwidth=(int)(((float)(60-ndividers))/(ncolumns));
387 dout << " |";
388 for(int idiv=0;idiv<ncolumns;idiv++) {
389 for(int isig=0;isig<cellwidth;isig++) dout << "-";
390 dout << "|";
391 }
392 dout << endl;
393 return ncolumns;
394 } else {
395 return 0;
396 }
397 }
398
399 void write_entry(string entry,int width,int iline=0,int ientry=0) {
400 int currwidth=entry.size();
401 while(currwidth<width) {
402 entry=" "+entry;
403 if(entry.size()<width) entry=entry+" ";
404 currwidth=entry.size();
405 }
406 bool do_special=false;
407 if(iline==1&&ientry==1) { dout << "\033[1;32m" << entry << "\033[0m|";do_special=true;}//observed
408 if(iline==1&&ientry==2) { dout << "\033[1;34m" << entry << "\033[0m|";do_special=true;}//predicted (1)
409 if(iline==2&&ientry==1) { dout << "\033[1;34m" << entry << "\033[0m|";do_special=true;}//predicted (1)
410 if(iline==2&&ientry==2) { dout << "\033[1;34m" << entry << "\033[0m|";do_special=true;}//predicted (1)
411 if(!do_special) dout << entry << "|";
412 }
413
414 void make_nice_table(vector<vector <string> > &entries) {
415 int ncolumns=write_first_line(entries);
416 int cellwidth=(int)(((float)(60-(ncolumns+1)))/(ncolumns));
417 for(int iline=0;iline<entries.size();iline++) {
418 vector<string> currline = entries[iline];
419 dout << " |";
420 for(int ientry=0;ientry<currline.size();ientry++) {
421 write_entry(currline[ientry],cellwidth);
422 }
423 dout << endl;
424 if(iline==0) write_first_line(entries);
425 }
426 write_first_line(entries);
427 }
428
429 void make_nice_jzb_table(vector<vector <string> > &entries) {
430 int ncolumns=write_first_line(entries);
431 int cellwidth=(int)(((float)(60-(ncolumns+1)))/(ncolumns));
432 for(int iline=0;iline<entries.size();iline++) {
433 vector<string> currline = entries[iline];
434 dout << " |";
435 for(int ientry=0;ientry<currline.size();ientry++) {
436 write_entry(currline[ientry],cellwidth,iline,ientry);
437 }
438 dout << endl;
439 if(iline==0) write_first_line(entries);
440 }
441 write_first_line(entries);
442 }
443
444
445 void write_warning(string funcname, string text) {
446 eout << endl << endl;
447 eout << "\033[1;33m" << " _ " << endl;
448 eout << "\033[1;33m" << " (_) " << endl;
449 eout << "\033[1;33m" << "__ ____ _ _ __ _ __ _ _ __ __ _ " << endl;
450 eout << "\033[1;33m" << "\\ \\ /\\ / / _` | '__| '_ \\| | '_ \\ / _` |" << endl;
451 eout << "\033[1;33m" << " \\ V V / (_| | | | | | | | | | | (_| |" << endl;
452 eout << "\033[1;33m" << " \\_/\\_/ \\__,_|_| |_| |_|_|_| |_|\\__, |" << endl;
453 eout << "\033[1;33m" << " __/ |" << endl;
454 eout << "\033[1;33m" << " |___/ " << endl;
455 eout << endl;
456 eout << "\033[1;33m [" << funcname << "] " << text << " \033[0m" << endl;
457 eout << endl << endl;
458 warningsummary << "[" << funcname << "] " << text << endl;
459 }
460 void write_error(string funcname, string text) {
461 eout << endl << endl;
462 eout << "\033[1;31m ___ _ __ _ __ ___ _ __ " << endl;
463 eout << "\033[1;31m / _ \\ __| __/ _ \\| '__|" << endl;
464 eout << "\033[1;31m| __/ | | | | (_) | | " << endl;
465 eout << "\033[1;31m \\___|_| |_| \\___/|_| " << endl;
466 eout << endl;
467 eout << "\033[1;31m [" << funcname << "] " << text << " \033[0m" << endl;
468 eout << endl << endl;
469 errorsummary << "[" << funcname << "] " << text << endl;
470 }
471
472 void write_info(string funcname, string text) {
473 dout << endl << endl;
474 dout << "\033[1;34m _____ __ " << endl;
475 dout << "\033[1;34m |_ _| / _| " << endl;
476 dout << "\033[1;34m | | _ __ | |_ ___ " << endl;
477 dout << "\033[1;34m | | | '_ \\| _/ _ \\ " << endl;
478 dout << "\033[1;34m _| |_| | | | || (_) | " << endl;
479 dout << "\033[1;34m |_____|_| |_|_| \\___/ " << endl;
480 dout << endl;
481 dout << "\033[1;34m [" << funcname << "] " << text << " \033[0m" << endl;
482 dout << endl << endl;
483 infosummary << "[" << funcname << "] " << text << endl;
484 }
485
486 TText* write_text(float xpos,float ypos,string title)
487 {
488 TLatex* titlebox = new TLatex (xpos,ypos,title.c_str());
489 titlebox->SetNDC(true);
490 titlebox->SetTextFont(42);
491 titlebox->SetTextSize(0.04);
492 titlebox->SetTextAlign(21);
493 return titlebox;
494 }
495
496 TText* write_title(string title)
497 {
498 TText* titlebox = write_text(0.5,0.945,title);
499 return titlebox;
500 }
501
502 TText* write_cut_on_canvas(string cut) {
503 // TLatex *normbox = new TLatex(0.96,0.5,cut.c_str());
504 TLatex *normbox = new TLatex(0.96,0.5,"");//currently deactivated
505 normbox->SetNDC(true);
506 normbox->SetTextFont(42);
507 normbox->SetTextSize(0.01);
508 normbox->SetTextAlign(21);
509 normbox->SetTextAngle(270);
510 return normbox;
511 }
512
513 TText* write_title_low(string title)
514 {
515 TText* titlebox = write_text(0.5,0.94,title);
516 return titlebox;
517 }
518
519 void DrawPrelim(float writelumi=generaltoolboxlumi,bool isMC=false) {
520 string barn="pb";
521 if(writelumi>=1000)
522 {
523 writelumi/=1000;
524 barn="fb";
525 }
526
527 stringstream prelimtext;
528 //prelimtext << "CMS Preliminary 2011 , #sqrt{s}= 7 TeV, L= O(1) fb^{-1}"; //temporary replacement
529 if(isMC) prelimtext << "CMS MC Simulation , #sqrt{s} = 7 TeV, L_{int} = " << std::setprecision(2) <<writelumi<<" "<<barn<<"^{-1}";
530 else prelimtext << "CMS Preliminary, #sqrt{s} = 7 TeV, L_{int} = " << std::setprecision(2) <<writelumi<<" "<<barn<<"^{-1}";
531 TPaveText *eventSelectionPaveText = new TPaveText(0.27, 0.93,0.77, 1.0,"blNDC");
532 eventSelectionPaveText->SetFillStyle(4000);
533 eventSelectionPaveText->SetBorderSize(0.1);
534 eventSelectionPaveText->SetFillColor(kWhite);
535 eventSelectionPaveText->SetTextFont(42);
536 eventSelectionPaveText->SetTextSize(0.042);
537 eventSelectionPaveText->AddText(prelimtext.str().c_str());
538 eventSelectionPaveText->Draw();
539 }
540
541 void DrawMCPrelim(float writelumi=generaltoolboxlumi) {
542 DrawPrelim(writelumi,true);
543 }
544
545 TLegend* make_legend(string title="", float posx=0.6, float posy=0.55, bool drawleg=true)
546 {
547 gStyle->SetTextFont(42);
548 TLegend *leg = new TLegend(posx,posy,0.89,0.89);
549 if(title!="") leg->SetHeader(title.c_str());
550 leg->SetTextFont(42);
551 leg->SetTextSize(0.04);
552 leg->SetFillColor(kWhite);
553 leg->SetBorderSize(0);
554 leg->SetLineColor(kWhite);
555 if(drawleg) DrawPrelim();
556 return leg;
557 }
558
559 TLegend* make_legend(bool drawleg, string title) {
560 return make_legend(title,0.6,0.55,drawleg);
561 }
562
563 TGraph* make_nice_ratio(int nbins,float binning[],TH1F* histo)
564 {
565 float errorsquared[nbins];
566 float errors[nbins];
567 float bincontent[nbins];
568 for (int i=0;i<nbins;i++) {
569 errorsquared[i]=0;
570 bincontent[i]=0;
571 errors[i]=0;
572 }
573 float currlimit=binning[0];
574 int currtoplim=1;
575 for(int ibin=1;ibin<=histo->GetNbinsX();ibin++)
576 {
577 if(binning[currtoplim]<histo->GetBinCenter(ibin)) currtoplim++;
578 dout << "Bin i=" << ibin << " with bin center " << histo->GetBinCenter(ibin) << " contains " << histo->GetBinContent(ibin) << " is within " << binning[currtoplim-1] << " and " << binning[currtoplim] << endl;
579
580 }
581
582 return 0;
583 }
584
585 float statErrorN(float x){return x - 0.5*TMath::ChisquareQuantile(0.3173/2,2*x);}
586 float statErrorP(float x){return 0.5*TMath::ChisquareQuantile(1-0.3173/2,2*(x+1))-x;}
587 float lowLimit(float a, float x){return 0.5*TMath::ChisquareQuantile(a,2*x);}
588 float highLimit(float a,float x){return 0.5*TMath::ChisquareQuantile(1-a,2*(x+1));}
589
590 float computeRatioError(float a, float da, float b, float db)
591 {
592 float val=0.;
593 float errorSquare = (a/b)*(a/b)*( (da/a)*(da/a) + (db/b)*(db/b));
594 val = TMath::Sqrt(errorSquare);
595 return val;
596
597 }
598 float computeProductError(float a, float da, float b, float db)
599 {
600 float val=0.;
601 float errorSquare = (a*b)*(a*b)*( (da/a)*(da/a) + (db/b)*(db/b));
602 val = TMath::Sqrt(errorSquare);
603 return val;
604 }
605
606 TGraphAsymmErrors *histRatio(TH1F *h1,TH1F *h2, int id, vector<float>binning, bool precise=false)
607 {
608 int absJZBbinsNumber = binning.size()-1;
609 TGraphAsymmErrors* graph = new TGraphAsymmErrors(absJZBbinsNumber);
610
611 for(unsigned int i=0;i<absJZBbinsNumber;i++)
612 {
613 float xCenter=h1->GetBinCenter(i+1);
614 float xWidth=(h1->GetBinWidth(i+1))*0.5;
615 float nominatorError = h1->GetBinError(i+1);
616 float nominator=h1->GetBinContent(i+1);
617 float denominatorError=h2->GetBinError(i+1);
618 float denominator=h2->GetBinContent(i+1);
619 float errorN = 0;
620 float errorP = computeRatioError(nominator,nominatorError,denominator,denominatorError);
621 if(id==1) // (is data)
622 {
623 if(!precise) errorP = computeRatioError(nominator,statErrorP(nominator),denominator,statErrorP(denominator));
624 else errorP = computeRatioError(nominator,nominatorError,denominator,denominatorError);
625 errorN = errorP; // symmetrize using statErrorP
626 } else {
627 errorN = computeRatioError(nominator,nominatorError,denominator,denominatorError);
628 errorP = errorN;
629 }
630 if(denominator!=0) {
631 graph->SetPoint(i, xCenter, nominator/denominator);
632 graph->SetPointError(i,xWidth,xWidth,errorN,errorP);
633 }
634 else {
635 graph->SetPoint(i, xCenter, -999);
636 graph->SetPointError(i,xWidth,xWidth,errorN,errorP);
637 }
638 }
639 return graph;
640 }
641
642 string print_range(float cent, float down, float up) {//note that up&down can be flipped, we don't care, but the central value needs to come 1st!
643 float uperr=0,downerr=0;
644 if(down>up&&down>cent) uperr=down-cent;
645 if(up>down&&up>cent) uperr=up-cent;
646 if(down<cent&&down<up) downerr=cent-down;
647 if(up<cent&&up<down) downerr=cent-up;
648 if(cent>up&&cent>down&&(up!=0&&down!=0)) write_error("print_range"," WATCH OUT: THE CENTRAL VALUE SEEMS TO BE LARGER THAN BOTH UP&DOWN!");
649 if(cent<up&&cent<down&&(up!=0&&down!=0)) write_error("print_range"," WATCH OUT: THE CENTRAL VALUE SEEMS TO BE SMALLER THAN BOTH UP&DOWN!");
650 stringstream result;
651 result << cent << " + " << uperr << " - " << downerr;
652 return result.str();
653 }
654
655 void bubbleSort ( int arr [ ], int size, int order [ ]) // nice way to sort an array (called arr) which is currently in a random order (indices in (order")
656 {
657 int last = size - 2;
658 int isChanged = 1;
659
660 while ( last >= 0 && isChanged )
661 {
662 isChanged = 0;
663 for ( int k = 0; k <= last; k++ )
664 if ( arr[k] > arr[k+1] )
665 {
666 swap ( arr[k], arr[k+1] );
667 isChanged = 1;
668 int bkp=order[k];
669 order[k]=order[k+1];
670 order[k+1]=bkp;
671 }
672 last--;
673 }
674 }
675
676 void swapvec(vector<float> &vec,int j, int k) {
677 float bkp=vec[j];
678 vec[j]=vec[k];
679 vec[k]=bkp;
680 }
681
682 void bubbleSort ( vector<float> &arr , vector<int> &order) // nice way to sort an array (called arr) which is currently in a random order (indices in (order")
683 {
684 int last = arr.size() - 2;
685 int isChanged = 1;
686
687 while ( last >= 0 && isChanged )
688 {
689 isChanged = 0;
690 for ( int k = 0; k <= last; k++ )
691 if ( arr[k] > arr[k+1] )
692 {
693 swapvec (arr,k,k+1);
694 isChanged = 1;
695 int bkp=order[k];
696 order[k]=order[k+1];
697 order[k+1]=bkp;
698 }
699 last--;
700 }
701 }
702
703 int numerichistoname=0;
704 bool givingnumber=false;
705 string GetNumericHistoName() {
706 while(givingnumber) sleep(1);
707 givingnumber=true;
708 stringstream b;
709 b << "h_" << numerichistoname;
710 numerichistoname++;
711 givingnumber=false;
712 return b.str();
713 }
714
715 //********************** BELOW : CUT INTERPRETATION **************************//
716 void splitupcut(string incut, vector<string> &partvector)
717 {
718 //idea: go thru the string called incut; if a parantheses is opened, then the cut cannot be split up until the parantheses is closed.
719 //ok anyway screw the parantheses.
720 int paranthesis_open=0;
721 int substr_start=0;
722 string currchar="";
723 for (int ichar=0;ichar<incut.length();ichar++)
724 {
725 currchar=incut.substr(ichar,1);
726 // if(currchar=="(") paranthesis_open++;
727 // if(currchar==")") paranthesis_open--;
728 if(currchar=="&"&&incut.substr(ichar+1,1)=="&"&&paranthesis_open==0) {
729 partvector.push_back(incut.substr(substr_start,ichar-substr_start));
730 substr_start=ichar+2;
731 }
732 }
733 partvector.push_back(incut.substr(substr_start,incut.length()-substr_start));
734 if(Verbosity>1) {
735 dout << "[ splitupcut() ] : The cut vector now contains the following elements: "<< endl;
736 for (int ipart=0;ipart<partvector.size();ipart++)
737 {
738 dout << " - " << partvector[ipart] << endl;
739 }
740 }
741 }
742
743 int atleastvalue(string expression, int &morethanlessthan) // takes in an expression such as ">2" or ">=3" and returns e.g. 3 (in both examples)
744 {
745 int retval=0;
746 if(expression.substr(0,1)==">"&&expression.substr(1,1)=="=") {
747 // dout << "The expression " << expression << " is saying that we have at least " << atoi(expression.substr(2,1).c_str()) << " jets" << endl;
748 morethanlessthan=1;
749 return atoi(expression.substr(2,1).c_str());
750 }
751 if(expression.substr(0,1)=="="&&expression.substr(1,1)=="=") {
752 // dout << "The expression " << expression << " is saying that we have at least " << atoi(expression.substr(1,1).c_str())+1 << " jets" << endl;
753 morethanlessthan=0;
754 return atoi(expression.substr(1,1).c_str());
755 }
756 if(expression.substr(0,1)=="<"&&expression.substr(1,1)=="=") {
757 // dout << "The expression " << expression << " is saying that we have at least " << atoi(expression.substr(1,1).c_str())+1 << " jets" << endl;
758 morethanlessthan=-1;
759 return 1+atoi(expression.substr(1,1).c_str());
760 }
761 if(expression.substr(0,1)==">") {
762 // dout << "The expression " << expression << " is saying that we have at least " << atoi(expression.substr(2,1).c_str()) << " jets" << endl;
763 morethanlessthan=1;
764 return 1+atoi(expression.substr(2,1).c_str());
765 }
766 if(expression.substr(0,1)=="<"&&expression.substr(1,1)=="=") {
767 // dout << "The expression " << expression << " is saying that we have at least " << atoi(expression.substr(2,1).c_str()) << " jets" << endl;
768 morethanlessthan=-1;
769 return 1+atoi(expression.substr(2,1).c_str());
770 }
771 }
772
773 int do_jet_cut(string incut, int *nJets) {
774 string expression=(incut.substr(12,incut.size()-12));
775 dout << "Going to analyze the jet cut : " << expression << " with 0,1 being " << expression.substr(0,1) << " and 1,1 being " << expression.substr(1,1) << endl;
776 if(expression.substr(0,1)=="<"&&expression.substr(1,1)=="=") {
777 int nJet=atoi(expression.substr(2,1).c_str());
778 for(int i=nJet+1;i<20;i++) nJets[i]=0;
779 dout << "Is of type <=" << endl;
780 return 0;
781 }
782 if(expression.substr(0,1)=="="&&expression.substr(1,1)=="=") {
783 int nJet=atoi(expression.substr(2,1).c_str());
784 for(int i=0;i<20&&i!=nJet;i++) nJets[i]=0;
785 dout << "Is of type ==" << endl;
786 return 0;
787 }
788 if(expression.substr(0,1)==">"&&expression.substr(1,1)=="=") {
789 int nJet=atoi(expression.substr(2,1).c_str());
790 for(int i=0;i<nJet&&i!=nJet;i++) nJets[i]=0;
791 dout << "Is of type >=" << endl;
792 return 0;
793 }
794 if(expression.substr(0,1)=="<") {
795 int nJet=atoi(expression.substr(1,1).c_str());
796 for(int i=nJet;i<20;i++) nJets[i]=0;
797 dout << "Is of type <" << endl;
798 return 0;
799 }
800 if(expression.substr(0,1)==">") {
801 int nJet=atoi(expression.substr(1,1).c_str());
802 for(int i=0;i<nJet+1&&i!=nJet;i++) nJets[i]=0;
803 dout << "Is of type >" << endl;
804 return 0;
805 }
806 }
807
808 string interpret_cut(string incut, bool &isJetCut, int *permittednJets)
809 {
810 // isJetCut=false;nJets=-1;
811 if(incut=="()") return "";
812 while(incut.substr(0,1)=="(") incut=incut.substr(1,incut.length()-1);
813 while(incut.length()>0&&incut.substr(incut.length()-1,1)==")") incut=incut.substr(0,incut.length()-1);
814 // if(incut.substr(0,1)=="("&&incut.substr(incut.length()-1,1)==")") incut=incut.substr(1,incut.length()-2); //this is to make (cut) to cut.
815
816 if(Verbosity>0) {
817 dout << "Now interpreting cut " << incut << endl;
818 }
819 /*
820 if(incut=="ch1*ch2<0") return "OS";
821 if(incut=="id1==id2") return "SF";
822 if(incut=="id1!=id2") return "OF";
823 */
824 if(incut=="ch1*ch2<0") return "";
825 if(incut=="(mll>55&&mll<70)||(mll>112&&mll<160)") return "SB";
826 if(incut=="(mll>61&&mll<70)||(mll>112&&mll<190)") return "SB'";
827 if(incut=="id1==id2") return "";
828 if(incut=="id1!=id2") return "";
829 if(incut=="mll>2") return "";
830
831 if(incut=="mll>0") return ""; // my typical "fake cut"
832
833 if(incut=="passed_triggers||!is_data") return "Triggers";
834 if(incut=="pfjzb[0]>-998") return "";
835
836
837 if(incut=="id1==0") return "ee";
838 if(incut=="id1==1") return "#mu#mu";
839 if(incut=="abs(mll-91.2)<20") return "|m_{l^{+}l^{-}}-m_{Z}|<20";
840 if(incut=="pfJetGoodID[0]") return "";
841 if(incut=="pfJetGoodID[1]") return "";
842 if((int)incut.find("pfJetGoodNum")>-1) {
843 //do_jet_cut(incut,permittednJets);
844 stringstream result;
845 result << "nJets" << incut.substr(12,incut.size()-12);
846 /* dout << "Dealing with a jet cut: " << incut << endl;
847 stringstream result;
848 result << "nJets" << incut.substr(12,incut.size()-12);
849 isJetCut=true;
850 if(exactjetcut(incut,nJets))
851 // nJets=atleastvalue((incut.substr(12,incut.size()-12)),morethanlessthan);
852 return result.str();*/
853 return result.str();
854 }
855 return incut;
856 }
857
858 string interpret_nJet_range(int *nJets) {
859 for (int i=0;i<20;i++) dout << i << " : " << nJets[i] << endl;
860 return "hello";
861 }
862
863 string interpret_cuts(vector<string> &cutparts)
864 {
865 stringstream nicecut;
866 int nJets;
867 bool isJetCut;
868 int finalJetCut=-1;
869 int permittednJets[20];
870 for(int ijet=0;ijet<20;ijet++) permittednJets[ijet]=1;
871 int morethanlessthan=0;//-1: less than, 0: exactly, 1: more than
872 for(int icut=0;icut<cutparts.size();icut++)
873 {
874 if(icut==0) nicecut<<interpret_cut(cutparts[icut],isJetCut,permittednJets);
875 else {
876 string nice_this_cut = interpret_cut(cutparts[icut],isJetCut,permittednJets);//blublu
877 if(nice_this_cut.length()>0&&nicecut.str().length()>0) {
878 if(!isJetCut) nicecut<<"&&"<<nice_this_cut;
879 else {
880 if(nJets>finalJetCut) finalJetCut=nJets;
881 }
882 }
883 if(nice_this_cut.length()>0&&nicecut.str().length()==0) {
884 if(!isJetCut) {
885 nicecut<<nice_this_cut;
886 }
887 else {
888 if(nJets>finalJetCut) finalJetCut=nJets;
889 }
890 }
891 }
892 }
893 if(finalJetCut>-1) {
894 if(nicecut.str().length()==0) {
895 nicecut << "nJets#geq" << finalJetCut;
896 }
897 else
898 {
899 nicecut << "&&nJets#geq " << finalJetCut;
900 }
901 }
902
903 // dout << "The nJet allowed range is given by: " << interpret_nJet_range(permittednJets) << endl;
904
905 return nicecut.str();
906 }
907
908 string decipher_cut(TCut originalcut,TCut ignorethispart)
909 {
910 string incut=(const char*)originalcut;
911 string ignore=(const char*)ignorethispart;
912
913 if(ignore.length()>0 && incut.find(ignore)!=string::npos) incut=incut.replace(incut.find(ignore),ignore.length(),"");
914
915 vector<string>cutparts;
916 splitupcut(incut,cutparts);
917 string write_cut=interpret_cuts(cutparts);
918 return write_cut;
919 }
920
921 //********************** ABOVE : CUT INTERPRETATION **************************//
922
923 Double_t GausRandom(Double_t mu, Double_t sigma) {
924 return gRandom->Gaus(mu,sigma);// real deal
925 //return mu;//debugging : no smearing.
926 }
927
928 int functionalhistocounter=0;
929 TH1F * makehistofromfunction(TF1 *f1,TH1F *model) {
930 TH1F *histo = (TH1F*)model->Clone();
931 functionalhistocounter++;
932 stringstream histoname;
933 histoname << "histo_based_on_function_" << f1->GetName() << "__"<<functionalhistocounter;
934 histo->SetTitle(histoname.str().c_str());
935 histo->SetName(histoname.str().c_str());
936 int nbins=histo->GetNbinsX();
937 float low=histo->GetBinLowEdge(1);
938 float hi=histo->GetBinLowEdge(histo->GetNbinsX())+histo->GetBinWidth(histo->GetNbinsX());
939
940 for(int i=0;i<=nbins;i++) {
941 histo->SetBinContent(i,(f1->Integral(histo->GetBinLowEdge(i),histo->GetBinLowEdge(i)+histo->GetBinWidth(i)))/histo->GetBinWidth(i));
942 histo->SetBinError(i,TMath::Sqrt(histo->GetBinContent(i)));
943 }
944
945 return histo;
946 }
947
948 float hintegral(TH1 *histo, float low, float high) {
949 float sum=0;
950 for(int i=1;i<histo->GetNbinsX();i++) {
951 if((histo->GetBinLowEdge(i)>=low)&&(histo->GetBinLowEdge(i)+histo->GetBinWidth(i))<=high) sum+=histo->GetBinContent(i);
952 //now on to the less clear cases!
953 if(histo->GetBinLowEdge(i)<low&&(histo->GetBinLowEdge(i)+histo->GetBinWidth(i))>low) {
954 //need to consider this case still ... the bin is kind of in range but not sooooo much.
955 }
956 if(histo->GetBinLowEdge(i)<high&&(histo->GetBinLowEdge(i)+histo->GetBinWidth(i))>high) {
957 //need to consider this case still ... the bin is kind of in range but not sooooo much.
958 }
959
960 }
961 return sum;
962 }
963
964 string newjzbexpression(string oldexpression,float shift) {
965 stringstream ss;
966 if(shift>0) ss<<"("<<oldexpression<<"+"<<shift<<")";
967 if(shift<0) ss<<"("<<oldexpression<<shift<<")";
968 if(shift==0) ss<<oldexpression;
969 return ss.str();
970 }
971
972 float Round(float num, unsigned int dig)
973 {
974 num *= pow(10, dig);
975 if (num >= 0)
976 num = floor(num + 0.5);
977 else
978 num = ceil(num - 0.5);
979 num/= pow(10, dig);
980 return num;
981 }
982
983 float SigDig(float num, int digits) {
984 //produces a number with only the given number of significant digits
985
986 }
987
988 // The two functions below are for distributed processing
989
990 int get_job_number(float ipoint, float Npoints,float Njobs) {
991 float pointposition=(ipoint/Npoints);
992 int njob=floor(pointposition*Njobs);
993 if(njob>=Njobs) njob--;
994 // cout << "Looking at point " << ipoint << " out of " << Npoints << " which is at position " << pointposition << " corresponding to " << pointposition*Njobs << " --> JOB " << njob << endl;
995 return njob;
996 }
997
998
999 bool do_this_point(int ipoint, int Npoints, int jobnumber, int Njobs) {
1000 if(get_job_number(ipoint,Npoints,Njobs)==jobnumber) return true;
1001 return false;
1002 }
1003
1004 Double_t DoIntegral(TH1F *histo, Int_t binx1, Int_t binx2, Int_t biny1, Int_t biny2, Int_t binz1, Int_t binz2, Double_t & error ,
1005 Option_t *option, Bool_t doError)
1006 {
1007 // internal function compute integral and optionally the error between the limits
1008 // specified by the bin number values working for all histograms (1D, 2D and 3D)
1009
1010 Int_t nbinsx = histo->GetNbinsX();
1011 if (binx1 < 0) binx1 = 0;
1012 if (binx2 > nbinsx+1 || binx2 < binx1) binx2 = nbinsx+1;
1013 if (histo->GetDimension() > 1) {
1014 Int_t nbinsy = histo->GetNbinsY();
1015 if (biny1 < 0) biny1 = 0;
1016 if (biny2 > nbinsy+1 || biny2 < biny1) biny2 = nbinsy+1;
1017 } else {
1018 biny1 = 0; biny2 = 0;
1019 }
1020 if (histo->GetDimension() > 2) {
1021 Int_t nbinsz = histo->GetNbinsZ();
1022 if (binz1 < 0) binz1 = 0;
1023 if (binz2 > nbinsz+1 || binz2 < binz1) binz2 = nbinsz+1;
1024 } else {
1025 binz1 = 0; binz2 = 0;
1026 }
1027
1028 // - Loop on bins in specified range
1029 TString opt = option;
1030 opt.ToLower();
1031 Bool_t width = kFALSE;
1032 if (opt.Contains("width")) width = kTRUE;
1033
1034
1035 Double_t dx = 1.;
1036 Double_t dy = 1.;
1037 Double_t dz = 1.;
1038 Double_t integral = 0;
1039 Double_t igerr2 = 0;
1040 for (Int_t binx = binx1; binx <= binx2; ++binx) {
1041 if (width) dx = histo->GetXaxis()->GetBinWidth(binx);
1042 for (Int_t biny = biny1; biny <= biny2; ++biny) {
1043 if (width) dy = histo->GetYaxis()->GetBinWidth(biny);
1044 for (Int_t binz = binz1; binz <= binz2; ++binz) {
1045 if (width) dz = histo->GetZaxis()->GetBinWidth(binz);
1046 Int_t bin = histo->GetBin(binx, biny, binz);
1047 if (width) integral += histo->GetBinContent(bin)*dx*dy*dz;
1048 else integral += histo->GetBinContent(bin);
1049 if (doError) {
1050 if (width) igerr2 += histo->GetBinError(bin)*histo->GetBinError(bin)*dx*dx*dy*dy*dz*dz;
1051 else igerr2 += histo->GetBinError(bin)*histo->GetBinError(bin);
1052 }
1053 }
1054 }
1055 }
1056
1057 if (doError) error = TMath::Sqrt(igerr2);
1058 return integral;
1059 }
1060
1061 Double_t IntegralAndError(TH1F *histo, Int_t binx1, Int_t binx2, Double_t & error, Option_t *option)
1062 {
1063 //Return integral of bin contents in range [binx1,binx2] and its error
1064 // By default the integral is computed as the sum of bin contents in the range.
1065 // if option "width" is specified, the integral is the sum of
1066 // the bin contents multiplied by the bin width in x.
1067 // the error is computed using error propagation from the bin errors assumming that
1068 // all the bins are uncorrelated
1069 return DoIntegral(histo,binx1,binx2,0,-1,0,-1,error,option,kTRUE);
1070 }
1071
1072 void print_usage() {
1073 cout << "Some distributed model calculations call Create_All_Plots.exec with the argument \"1\" to calculate some basic quantities, such as the peak position in MC and data, observed and predicted, and so on. If you want to test this, you can just run this program with argument 1 yourself :-) " << endl;
1074 }
1075
1076
1077 string format_number( int value )
1078 {
1079 if( value == 0 ) return "00";
1080 if( value < 10 ) return "0"+any2string(value);
1081 return any2string(value);
1082 }
1083
1084 string seconds_to_time(int seconds) {
1085 const static unsigned int SECONDS_IN_AN_HOUR = 3600;
1086 const static unsigned int SECONDS_IN_A_MINUTE = 60;
1087 stringstream answer;
1088 if( seconds > 0 )
1089 {
1090 answer << format_number( (unsigned int)(seconds / SECONDS_IN_AN_HOUR) ) << ":";
1091 answer << format_number( (unsigned int)((seconds % SECONDS_IN_AN_HOUR) / SECONDS_IN_A_MINUTE) ) << ":";
1092 answer << format_number( (unsigned int)((seconds % SECONDS_IN_AN_HOUR) % (SECONDS_IN_A_MINUTE)) );
1093 }
1094 else
1095 {
1096 answer << "00:00:00";
1097 }
1098 return answer.str();
1099 }
1100
1101 bool Contains(string wholestring, string findme) {
1102 if((int)wholestring.find(findme)>-1) return true;
1103 else return false;
1104 }
1105
1106 //////////////////////////////////////////////////////////////////////////////
1107 //
1108 // http://stackoverflow.com/questions/669438/how-to-get-memory-usage-at-run-time-in-c
1109 // process_mem_usage(double &, double &) - takes two doubles by reference,
1110 // attempts to read the system-dependent data for a process' virtual memory
1111 // size and resident set size, and return the results in KB.
1112 //
1113 // On failure, returns 0.0, 0.0
1114
1115 /* usage:
1116 double vm2, rss2;
1117 process_mem_usage(vm2, rss2);
1118 cout << "Memory usage: VM: " << vm << "; RSS: " << rss << endl;
1119 */
1120
1121 void process_mem_usage(double& vm_usage, double& resident_set)
1122 {
1123 using std::ios_base;
1124 using std::ifstream;
1125 using std::string;
1126
1127 vm_usage = 0.0;
1128 resident_set = 0.0;
1129
1130 // 'file' stat seems to give the most reliable results
1131 //
1132 ifstream stat_stream("/proc/self/stat",ios_base::in);
1133
1134 // dummy vars for leading entries in stat that we don't care about
1135 //
1136 string pid, comm, state, ppid, pgrp, session, tty_nr;
1137 string tpgid, flags, minflt, cminflt, majflt, cmajflt;
1138 string utime, stime, cutime, cstime, priority, nice;
1139 string O, itrealvalue, starttime;
1140
1141 // the two fields we want
1142 //
1143 unsigned long vsize;
1144 long rss;
1145
1146 stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
1147 >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
1148 >> utime >> stime >> cutime >> cstime >> priority >> nice
1149 >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest
1150
1151 stat_stream.close();
1152
1153 long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages
1154 vm_usage = vsize / 1024.0;
1155 resident_set = rss * page_size_kb;
1156 }
1157
1158 TGraphErrors* produce_ratio_graph(TH1F *baseratio) {
1159 int nbins=baseratio->GetNbinsX();
1160 double x[nbins];
1161 double y[nbins];
1162 double ex[nbins];
1163 double ey[nbins];
1164
1165 for(int ibin=1;ibin<=nbins;ibin++) {
1166 x[ibin-1]=baseratio->GetBinCenter(ibin);
1167 y[ibin-1]=baseratio->GetBinContent(ibin);
1168 ex[ibin-1]=0.5*baseratio->GetBinWidth(ibin);
1169 ey[ibin-1]=baseratio->GetBinError(ibin);
1170 }
1171
1172 TGraphErrors *result = new TGraphErrors(nbins, x,y,ex,ey);
1173 return result;
1174 }
1175
1176 TCanvas* draw_ratio_on_canvas(TH1F *nominator, TH1F *denominator, TVirtualPad *canvas) {
1177
1178 float bottommargin=gStyle->GetPadBottomMargin();
1179 string canvasname="anyname";
1180 float canvas_height=gStyle->GetCanvasDefH();
1181 float canvas_width=gStyle->GetCanvasDefW();
1182 float ratiospace=0.25;// space the ratio should take up (relative to original pad)
1183
1184 float ratiobottommargin=0.3;
1185 float ratiotopmargin=0.1;
1186
1187 float xstretchfactor=((1-ratiospace)*(1-gStyle->GetPadTopMargin()))/((1)*ratiospace);
1188
1189 TCanvas *main_canvas = new TCanvas("main_canvas","main_canvas",canvas_width,canvas_height*(1+ratiospace));
1190 TPad *mainpad = new TPad("mainpad","mainpad",0,1-(1.0/(1+ratiospace)),1,1);//top (main) pad
1191 TPad *bottompad = new TPad("bottompad", "Ratio Pad",0,0,1,(1-(1-bottommargin)/(1+ratiospace))-0.01); //bottom pad
1192
1193 main_canvas->Range(0,0,1,1);
1194 main_canvas->SetBorderSize(0);
1195 main_canvas->SetFrameFillColor(0);
1196
1197 mainpad->Draw();
1198 mainpad->cd();
1199 mainpad->Range(0,0,1,1);
1200 mainpad->SetFillColor(kWhite);
1201 mainpad->SetBorderSize(0);
1202 mainpad->SetFrameFillColor(0);
1203 canvas->Range(0,0,1,1);
1204 canvas->Draw("same");
1205 mainpad->Modified();
1206 main_canvas->cd();
1207 bottompad->SetTopMargin(ratiotopmargin);
1208 bottompad->SetBottomMargin(ratiobottommargin);
1209 bottompad->Draw();
1210 bottompad->cd();
1211 bottompad->Range(0,0,1,1);
1212 bottompad->SetFillColor(kWhite);
1213 TH1F *ratio = (TH1F*)nominator->Clone(GetNumericHistoName().c_str());
1214 ratio->Divide(denominator);
1215 TGraphErrors *eratio = produce_ratio_graph(ratio);
1216 eratio->SetFillColor(TColor::GetColor("#00ADE1"));
1217
1218 ratio->SetTitle("");
1219 ratio->GetYaxis()->SetRangeUser(0.5,1.5);
1220 ratio->GetXaxis()->SetTitle(nominator->GetXaxis()->GetTitle());
1221 ratio->GetXaxis()->CenterTitle();
1222 ratio->GetYaxis()->SetTitle("ratio");
1223 ratio->GetYaxis()->SetTitleOffset(0.4);
1224 ratio->GetYaxis()->CenterTitle();
1225 ratio->SetStats(0);
1226 ratio->GetXaxis()->SetLabelSize(xstretchfactor*ratio->GetXaxis()->GetLabelSize());
1227 ratio->GetYaxis()->SetLabelSize(xstretchfactor*ratio->GetYaxis()->GetLabelSize());
1228 ratio->GetXaxis()->SetTitleSize(xstretchfactor*gStyle->GetTitleSize());
1229 ratio->GetYaxis()->SetTitleSize(xstretchfactor*gStyle->GetTitleSize());
1230 ratio->GetYaxis()->SetNdivisions(502,false);
1231 ratio->SetFillColor(TColor::GetColor("#58D3F7"));
1232 ratio->SetMarkerSize(0);
1233 ratio->Draw("e2");
1234 eratio->Draw("2");
1235 ratio->Draw("same,axis");
1236 TLine *oneline = new TLine(ratio->GetXaxis()->GetBinLowEdge(1),1,ratio->GetXaxis()->GetBinLowEdge(ratio->GetNbinsX())+ratio->GetXaxis()->GetBinWidth(ratio->GetNbinsX()),1);
1237 oneline->SetLineStyle(2);
1238 oneline->SetLineColor(kBlue);
1239 oneline->Draw("same");
1240
1241 main_canvas->cd();
1242 main_canvas->Modified();
1243 main_canvas->cd();
1244 main_canvas->SetSelected(main_canvas);
1245
1246 return main_canvas;
1247 }
1248
1249
1250 TH1F* CollapseStack(THStack stack) {
1251 TH1F *bhist = ((TH1F*)((stack.GetHists())->At(0)));
1252 TH1F *basehisto = (TH1F*)bhist->Clone("base");
1253 TIter next(stack.GetHists());
1254 TH1F *h;
1255 int counter=0;
1256 while ((h=(TH1F*)next())) {
1257 counter++;
1258 if(counter==1) continue;
1259 basehisto->Add(h);
1260 }
1261 return basehisto;
1262 }
1263
1264 TCanvas* draw_ratio_on_canvas(TH1F *nominator, THStack denominator, TVirtualPad *canvas) {
1265 return draw_ratio_on_canvas(nominator, CollapseStack(denominator), canvas);
1266 }
1267
1268 void flag_this_change(string function, int line, bool checked=false) {
1269 stringstream peakmodificationwarning;
1270 peakmodificationwarning << "There's been a change on line " << line << " in function " << function << " that affects the functionality you're using. If you've checked that it works well please change the function call to flag_this_change(..,..,true) so this will only be an info instead of a warning :-) ";
1271 if(!checked) write_warning(function,peakmodificationwarning.str());
1272 else write_info(function,peakmodificationwarning.str());
1273 }