ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.26
Committed: Tue Dec 11 09:11:11 2012 UTC (12 years, 4 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.25: +4 -22 lines
Log Message:
Added ratio with systematic band

File Contents

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