ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/AnalysisFramework/Plotting/Modules/GeneralToolBox.C
Revision: 1.40
Committed: Mon Oct 24 15:05:37 2011 UTC (13 years, 6 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.39: +64 -20 lines
Log Message:
Upgrade from HoneyPot to IceCreamBowl: merged in offpeak stuff, different warning color for frederic, saving to rootfile, only 3 attempts when computing limits and much, much more

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