ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/AnalysisFramework/Plotting/Modules/GeneralToolBox.C
Revision: 1.54
Committed: Mon Dec 5 18:06:26 2011 UTC (13 years, 5 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.53: +13 -3 lines
Log Message:
Added function to provide number with a given number of significant digits; updated CompleteSave for Virtualpads for saving to pdf

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