ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/AnalysisFramework/Plotting/Modules/GeneralToolBox.C
Revision: 1.38
Committed: Thu Oct 13 09:51:31 2011 UTC (13 years, 6 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.37: +123 -1 lines
Log Message:
Changed the way ratios are drawn; no more smoothing.

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