ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/AnalysisFramework/Plotting/Modules/GeneralToolBox.C
Revision: 1.57
Committed: Tue Jan 10 13:57:28 2012 UTC (13 years, 4 months ago) by pablom
Content type: text/plain
Branch: MAIN
Changes since 1.56: +2 -2 lines
Log Message:
Blank space removed before a comma in the window text.

File Contents

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