ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.24
Committed: Fri Nov 23 12:12:03 2012 UTC (12 years, 5 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.23: +50 -10 lines
Log Message:
Added function providing nice lower and upper range of a tgrapherror; added function to draw the correct uncertainty of a tf1 based on a polynomial

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.15 /*void save_with_difference(TH1F *obs, vector<TH1F*> predictions, vector<float> prediction_weights, vector<float> prediction_uncerts, TVirtualPad *canvas, string savemeas) {
1321     if(predictions.size()<1) {
1322     write_warning(__FUNCTION__,"Cannot make a pred-obs prediction plot because the prediction vector is empty. aborting!");
1323     return;
1324     }
1325     TH1F *comppred = predictions[0]->Clone("comppred");
1326     comppred->Scale(prediction_weights[0]);
1327     for(int i=1;i<predictions.size();i++) comppred->Add(predictions[i],prediction_weights[i]);
1328    
1329     TH1F *statpred = (TH1F*)comppred->Clone("statpred");
1330     for(int i=1;i<=statpred->GetNbinsX();i++) statpred->SetBinContent(0);
1331    
1332     TH1F *syspred = predictions[0];
1333     for(int i=1;i<=syspred->GetNbinsX();i++) syspred->SetBinContent(i,prediction_weights[0]*prediction_weights[0]*prediction_uncerts[0]*prediction_uncerts[0]*syspred->GetBinContent(i)*syspred->GetBinContent(i));
1334     for(int i=1;i<predictions.size();i++) {
1335     for(int ibin=1;ibin<=predictions[i]->GetNbinsX();ibin++) {
1336     float newentry=syspred->GetBinContent(ibin);
1337     newentry+=(predictions[i]->GetBinContent(ibin))*(predictions[i]->GetBinContent(ibin))*prediction_weights[i]*prediction_weights[i]*prediction_uncerts[i]*prediction_uncerts[i];
1338     syspred->SetBinContent(ibin,newentry);
1339     }
1340     }
1341     for(int ibin=1;ibin<=syspred->GetNbinsX();ibin++) {
1342     syspred->SetBinError(ibin,syspred->GetBinContent(i)+statpred->GetBinError());
1343     syspred->SetBinContent(ibin,0);
1344     }
1345    
1346    
1347     }
1348     */
1349 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) {
1350 buchmann 1.1 //this function saves the pad being passed as well as a new one including the ratio.
1351     CompleteSave(canvas,savemeas);
1352    
1353     float bottommargin=gStyle->GetPadBottomMargin();
1354     float canvas_height=gStyle->GetCanvasDefH();
1355     float canvas_width=gStyle->GetCanvasDefW();
1356     float ratiospace=0.25;// space the ratio should take up (relative to original pad)
1357    
1358     float ratiobottommargin=0.3;
1359     float ratiotopmargin=0.1;
1360    
1361     float xstretchfactor=((1-ratiospace)*(1-gStyle->GetPadTopMargin()))/((1)*ratiospace);
1362    
1363     TCanvas *main_canvas = new TCanvas("main_canvas","main_canvas",(Int_t)canvas_width,(Int_t)(canvas_height*(1+ratiospace)));
1364     TPad *mainpad = new TPad("mainpad","mainpad",0,1-(1.0/(1+ratiospace)),1,1);//top (main) pad
1365     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
1366     TPad *bottompad = new TPad("bottompad", "Ratio Pad",0,0,1,(1-(1-bottommargin)/(1+ratiospace))-0.015); //bottom pad
1367    
1368     main_canvas->Range(0,0,1,1);
1369     main_canvas->SetBorderSize(0);
1370     main_canvas->SetFrameFillColor(0);
1371    
1372     mainpad->Draw();
1373     mainpad->cd();
1374     mainpad->Range(0,0,1,1);
1375     mainpad->SetFillColor(kWhite);
1376     mainpad->SetBorderSize(0);
1377     mainpad->SetFrameFillColor(0);
1378     canvas->Range(0,0,1,1);
1379     canvas->Draw("same");
1380     mainpad->Modified();
1381     main_canvas->cd();
1382     coverpad->Draw();
1383     coverpad->cd();
1384     coverpad->Range(0,0,1,1);
1385     coverpad->SetFillColor(kWhite);
1386     coverpad->SetBorderSize(0);
1387     coverpad->SetFrameFillColor(0);
1388     coverpad->Modified();
1389     main_canvas->cd();
1390     bottompad->SetTopMargin(ratiotopmargin);
1391     bottompad->SetBottomMargin(ratiobottommargin);
1392     bottompad->Draw();
1393     bottompad->cd();
1394     bottompad->Range(0,0,1,1);
1395     bottompad->SetFillColor(kWhite);
1396     TH1F *ratio = (TH1F*)nominator->Clone(GetNumericHistoName().c_str());
1397     ratio->Divide(denominator);
1398    
1399    
1400     TGraphAsymmErrors *eratio;
1401 buchmann 1.14 TH1F *SystDown;
1402     TH1F *SystUp;
1403    
1404 buchmann 1.1 if(!do_bpred_ratio) eratio = produce_ratio_graph(ratio);
1405     else {
1406     bool using_data=false;
1407     if((int)savemeas.find("Data")>0) using_data=true;
1408     eratio = histRatio(nominator,denominator,using_data,PlottingSetup::global_ratio_binning,false);
1409 buchmann 1.13 if(syshisto!=0) {
1410 buchmann 1.14 SystDown = (TH1F*)syshisto->Clone("SystDown");
1411     SystUp = (TH1F*)syshisto->Clone("SystUp");
1412     for(int i=1;i<=syshisto->GetNbinsX();i++) {
1413     SystDown->SetBinContent(i,1-syshisto->GetBinContent(i));
1414     SystUp->SetBinContent(i,1+syshisto->GetBinContent(i));
1415     }
1416     SystDown->SetLineColor(TColor::GetColor("#006DE1"));
1417     SystUp->SetLineColor(TColor::GetColor("#006DE1"));
1418 buchmann 1.13 }
1419 buchmann 1.1 for(int i=1;i<=ratio->GetNbinsX();i++) {
1420     ratio->SetBinContent(i,0);
1421     ratio->SetBinError(i,0);
1422     }
1423 buchmann 1.13
1424 buchmann 1.1 }
1425     eratio->SetFillColor(TColor::GetColor("#00ADE1"));
1426 buchmann 1.13
1427 buchmann 1.1
1428     ratio->SetTitle("");
1429 buchmann 1.21 ratio->GetYaxis()->SetRangeUser(0.0,2.0);
1430 buchmann 1.1 if(do_bpred_ratio) ratio->GetYaxis()->SetRangeUser(0.0,2.0);
1431     if(extendrange) ratio->GetYaxis()->SetRangeUser(0.0,4.0);
1432     ratio->GetXaxis()->SetTitle(nominator->GetXaxis()->GetTitle());
1433     ratio->GetXaxis()->CenterTitle();
1434     ratio->GetYaxis()->SetTitle(yaxistitle.c_str());
1435     ratio->GetYaxis()->SetTitleOffset(0.4);
1436     ratio->GetYaxis()->CenterTitle();
1437     ratio->SetStats(0);
1438     ratio->GetXaxis()->SetLabelSize(xstretchfactor*ratio->GetXaxis()->GetLabelSize());
1439     ratio->GetYaxis()->SetLabelSize(xstretchfactor*ratio->GetYaxis()->GetLabelSize());
1440     ratio->GetXaxis()->SetTitleSize(xstretchfactor*gStyle->GetTitleSize());
1441     ratio->GetYaxis()->SetTitleSize(xstretchfactor*gStyle->GetTitleSize());
1442     ratio->GetYaxis()->SetNdivisions(502,false);
1443     ratio->SetFillColor(TColor::GetColor("#58D3F7"));
1444     ratio->SetMarkerSize(0);
1445     ratio->Draw("e2");
1446 buchmann 1.13 if(syshisto!=0) {
1447     // sysratio->Draw("2");
1448     // eratio->Draw("2,same");
1449     eratio->Draw("2");
1450 buchmann 1.14 SystDown->Draw("histo,same");
1451     SystUp->Draw("histo,same");
1452 buchmann 1.13 } else {
1453     eratio->Draw("2");
1454     }
1455 buchmann 1.1 ratio->Draw("same,axis");
1456     TLine *oneline = new TLine(ratio->GetXaxis()->GetBinLowEdge(1),1,ratio->GetXaxis()->GetBinLowEdge(ratio->GetNbinsX())+ratio->GetXaxis()->GetBinWidth(ratio->GetNbinsX()),1);
1457     oneline->SetLineStyle(2);
1458     oneline->SetLineColor(kBlue);
1459     oneline->Draw("same");
1460    
1461     main_canvas->cd();
1462     main_canvas->Modified();
1463     main_canvas->cd();
1464     main_canvas->SetSelected(main_canvas);
1465    
1466     CompleteSave(main_canvas,savemeas+"_withratio");
1467     bottompad->cd();
1468    
1469     Double_t chi2;
1470     Int_t ndf,igood;
1471 buchmann 1.7 // Double_t res=0.0;
1472 buchmann 1.1 Double_t chi2prob = MarcosChi2TestX(nominator,denominator,chi2,ndf,igood,"UW");
1473    
1474     stringstream Chi2text;
1475     Chi2text << "#chi^{2} / ndf: " << chi2 << " / " << ndf;
1476     stringstream Chi2probtext;
1477     Chi2probtext << "#chi^{2} prob: " << chi2prob;
1478     TText* chi2box = write_text(0.02,0.11,Chi2text.str());
1479     chi2box->SetTextSize(0.08);
1480     chi2box->SetTextAlign(11);
1481     chi2box->Draw();
1482     TText* chi2probbox = write_text(0.02,0.04,Chi2probtext.str());
1483     chi2probbox->SetTextSize(0.08);
1484     chi2probbox->SetTextAlign(11);
1485     chi2probbox->Draw();
1486 buchmann 1.11
1487     stringstream CompRatio;
1488     CompRatio << "Ratio: " << nominator->Integral() << " / " << denominator->Integral() << " \n " << nominator->Integral()/denominator->Integral();
1489     TText *CompleteRatio = write_text(0.98,0.04,CompRatio.str());
1490     CompleteRatio->SetTextSize(0.08);
1491     CompleteRatio->SetTextAlign(31);
1492     CompleteRatio->Draw();
1493    
1494 buchmann 1.1 CompleteSave(main_canvas,savemeas+"_withratio_and_Chi2");
1495    
1496     // float KS = nominator->KolmogorovTest(denominator);
1497     // stringstream KStext;
1498     // Chi2text << "KS = " << KS << endl;
1499     //cout << "Found : " << KStext.str() << endl;
1500    
1501    
1502     delete main_canvas;
1503     }
1504    
1505 buchmann 1.19 void save_with_ratio_and_sys_band(TH1F *nominator, TH1F *denominator, TVirtualPad *canvas, string savemeas, float systematic, string yaxistitle="SysRatio") {
1506     //this function saves the pad being passed as well as a new one including the SysRatio.
1507     CompleteSave(canvas,savemeas);
1508    
1509     float bottommargin=gStyle->GetPadBottomMargin();
1510     float canvas_height=gStyle->GetCanvasDefH();
1511     float canvas_width=gStyle->GetCanvasDefW();
1512     float SysRatiospace=0.25;// space the SysRatio should take up (relative to original pad)
1513    
1514     float SysRatiobottommargin=0.3;
1515     float SysRatiotopmargin=0.1;
1516    
1517     float xstretchfactor=((1-SysRatiospace)*(1-gStyle->GetPadTopMargin()))/((1)*SysRatiospace);
1518    
1519     TCanvas *MainCanvas = new TCanvas("MainCanvas","MainCanvas",(Int_t)canvas_width,(Int_t)(canvas_height*(1+SysRatiospace)));
1520     TPad *MainPad = new TPad("MainPad","MainPad",0,1-(1.0/(1+SysRatiospace)),1,1);//top (main) pad
1521     TPad *CoverPad = new TPad("CoverPad","CoverPad",gStyle->GetPadLeftMargin()-0.008,1-(1.0/(1+SysRatiospace))-0.04,1,1-(1.0/(1+SysRatiospace))+0.103);//pad covering up the x scale
1522     TPad *BottomPad = new TPad("BottomPad", "Ratio Pad",0,0,1,(1-(1-bottommargin)/(1+SysRatiospace))-0.015); //bottom pad
1523    
1524     MainCanvas->Range(0,0,1,1);
1525     MainCanvas->SetBorderSize(0);
1526     MainCanvas->SetFrameFillColor(0);
1527    
1528     MainPad->Draw();
1529     MainPad->cd();
1530     MainPad->Range(0,0,1,1);
1531     MainPad->SetFillColor(kWhite);
1532     MainPad->SetBorderSize(0);
1533     MainPad->SetFrameFillColor(0);
1534     canvas->Range(0,0,1,1);
1535     canvas->Draw("same");
1536     MainPad->Modified();
1537     MainCanvas->cd();
1538     CoverPad->Draw();
1539     CoverPad->cd();
1540     CoverPad->Range(0,0,1,1);
1541     CoverPad->SetFillColor(kWhite);
1542     CoverPad->SetBorderSize(0);
1543     CoverPad->SetFrameFillColor(0);
1544     CoverPad->Modified();
1545     MainCanvas->cd();
1546     BottomPad->SetTopMargin(SysRatiotopmargin);
1547     BottomPad->SetBottomMargin(SysRatiobottommargin);
1548     BottomPad->Draw();
1549     BottomPad->cd();
1550     BottomPad->Range(0,0,1,1);
1551     BottomPad->SetFillColor(kWhite);
1552     TH1F *SysRatio = (TH1F*)nominator->Clone(GetNumericHistoName().c_str());
1553     SysRatio->Divide(denominator);
1554    
1555    
1556    
1557     SysRatio->SetTitle("");
1558     SysRatio->GetYaxis()->SetRangeUser(0.0,2.0);
1559     SysRatio->GetXaxis()->SetTitle(nominator->GetXaxis()->GetTitle());
1560     SysRatio->GetXaxis()->CenterTitle();
1561     SysRatio->GetYaxis()->SetTitle(yaxistitle.c_str());
1562     SysRatio->GetYaxis()->SetTitleOffset(0.4);
1563     SysRatio->GetYaxis()->CenterTitle();
1564     SysRatio->SetStats(0);
1565     SysRatio->GetXaxis()->SetLabelSize(xstretchfactor*SysRatio->GetXaxis()->GetLabelSize());
1566     SysRatio->GetYaxis()->SetLabelSize(xstretchfactor*SysRatio->GetYaxis()->GetLabelSize());
1567     SysRatio->GetXaxis()->SetTitleSize(xstretchfactor*gStyle->GetTitleSize());
1568     SysRatio->GetYaxis()->SetTitleSize(xstretchfactor*gStyle->GetTitleSize());
1569     SysRatio->GetYaxis()->SetNdivisions(502,false);
1570     SysRatio->SetFillColor(TColor::GetColor("#58D3F7"));
1571     TBox *sysbox = new TBox(SysRatio->GetXaxis()->GetBinLowEdge(1),1-systematic,SysRatio->GetXaxis()->GetBinLowEdge(SysRatio->GetNbinsX())+SysRatio->GetXaxis()->GetBinWidth(SysRatio->GetNbinsX()),1+systematic);
1572     sysbox->SetFillColor(TColor::GetColor("#82FA58")); // light green
1573    
1574 buchmann 1.20 SysRatio->Draw("e1");
1575 buchmann 1.19 sysbox->Draw();
1576 buchmann 1.20 SysRatio->Draw("e1,same");
1577     SysRatio->Draw("e1,axis,same");
1578 buchmann 1.19
1579     TLine *oneline = new TLine(SysRatio->GetXaxis()->GetBinLowEdge(1),1,SysRatio->GetXaxis()->GetBinLowEdge(SysRatio->GetNbinsX())+SysRatio->GetXaxis()->GetBinWidth(SysRatio->GetNbinsX()),1);
1580     oneline->SetLineStyle(2);
1581     oneline->SetLineColor(kBlue);
1582     oneline->Draw("same");
1583    
1584     MainCanvas->cd();
1585     MainCanvas->Modified();
1586     MainCanvas->cd();
1587     MainCanvas->SetSelected(MainCanvas);
1588    
1589     CompleteSave(MainCanvas,savemeas+"_withSYSSysRatio");
1590     delete SysRatio;
1591     delete MainCanvas;
1592     }
1593 buchmann 1.1
1594 fronga 1.22 TH1F* CollapseStack(THStack stack,TString hname="base") {
1595 buchmann 1.1 TH1F *bhist = ((TH1F*)((stack.GetHists())->At(0)));
1596 fronga 1.22 TH1F *basehisto = (TH1F*)bhist->Clone(hname);
1597 buchmann 1.1 TIter next(stack.GetHists());
1598     TH1F *h;
1599     int counter=0;
1600     while ((h=(TH1F*)next())) {
1601     counter++;
1602     if(counter==1) continue;
1603     basehisto->Add(h);
1604     }
1605     return basehisto;
1606     }
1607    
1608     void save_with_ratio(TH1F *nominator, THStack denominator, TVirtualPad *canvas, string savemeas, bool do_bpred_ratio=false) {
1609     save_with_ratio(nominator, CollapseStack(denominator), canvas, savemeas, do_bpred_ratio);
1610     }
1611    
1612     void flag_this_change(string function, int line, int checked=0) {
1613     stringstream peakmodificationwarning;
1614     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 :-) ";
1615     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)";
1616     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.";
1617    
1618    
1619     if(checked==0) write_warning(function,peakmodificationwarning.str());
1620     // if(checked==1) write_info(function,peakmodificationwarning.str());
1621     peakmodificationwarning << " This modification has been checked and the changes have been reproduced. Checks completed.";
1622     if(checked==2) write_info(function,peakmodificationwarning.str());
1623     }
1624    
1625 buchmann 1.8 void write_analysis_type(bool isonpeak, bool dobtag) {
1626 buchmann 1.1 //http://www.network-science.de/ascii/, ogre
1627     if(!PlottingSetup::publicmode) {
1628     if(isonpeak) {
1629 buchmann 1.8 //font: big
1630 buchmann 1.1 dout << "\033[1;34m" << endl;
1631 buchmann 1.8 dout << " _ __________ " << endl;
1632     dout << " | |___ / _ \\ " << endl;
1633     dout << " /\\ ___ | | / /| |_) | " << endl;
1634     dout << " / \\ / _|_ | | / / | _ < " << endl;
1635     dout << " / \\ | (_| |__| |/ /__| |_) | " << endl;
1636     dout << " \\___|\\____//_____|____/ " << endl;
1637 buchmann 1.1 } else {
1638 buchmann 1.8 //font: big
1639 buchmann 1.1 dout << "\033[1;33m" << endl;
1640 buchmann 1.5 dout << " _ _ __________ " << endl;
1641     dout << " (_) | |___ / _ \\ " << endl;
1642     dout << " /\\ _ | | / /| |_) | " << endl;
1643     dout << " /\\/ \\ | |_ | | / / | _ < " << endl;
1644     dout << " / \\ | | |__| |/ /__| |_) | " << endl;
1645     dout << " |_|\\____//_____|____/ " << endl;
1646 buchmann 1.1 }
1647 buchmann 1.8
1648     if(dobtag) {
1649     //font: big
1650     dout << "\033[1;32m \\ / " << endl;
1651     dout << " \\ o ^ o / " << endl;
1652     dout << " \\ ( ) / " << endl;
1653     dout << " ____________(%%%%%%%)____________ _ _ __________ " << endl;
1654     dout << " ( / / )%%%%%%%( \\ \\ ) | | | |___ / _ \\ " << endl;
1655     dout << " (___/___/__/ \\__\\___\\___) | |__ | | / /| |_) | " << endl;
1656     dout << " ( / /(%%%%%%%)\\ \\ ) | '_ \\ _ | | / / | _ < " << endl;
1657     dout << " (__/___/ (%%%%%%%) \\___\\__) | |_) | |__| |/ /__| |_) | " << endl;
1658     dout << " /( )\\ |_.__/ \\____//_____|____/ " << endl;
1659     dout << " / (%%%%%) \\ " << endl;
1660     dout << " (%%%) " << endl;
1661     dout << " ! " << endl;
1662     }
1663     } else {
1664     //we're in public! don't advertise what we're up to :-)
1665     dout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
1666     dout << " Starting the analysis " << endl;
1667 buchmann 1.11 dout << " i:" << !isonpeak << " , b " << dobtag << endl;
1668 buchmann 1.8 dout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
1669 buchmann 1.1 }
1670 buchmann 1.8 dout << "\033[0m" << endl;
1671    
1672 buchmann 1.1 }
1673    
1674    
1675     vector<string> StringSplit(string str, string delim)
1676     {
1677     vector<string> results;
1678    
1679     int cutAt;
1680 buchmann 1.7 while( (cutAt = str.find_first_of(delim)) != (int)str.npos )
1681 buchmann 1.1 {
1682     if(cutAt > 0)
1683     {
1684     results.push_back(str.substr(0,cutAt));
1685     }
1686     str = str.substr(cutAt+1);
1687     }
1688     if(str.length() > 0)
1689     {
1690     results.push_back(str);
1691     }
1692     return results;
1693     }
1694    
1695     void manually_set_jzb_cuts(vector<float> &jzb_cut,string jzbcut_string) {
1696     vector<string> jzbcutvector = StringSplit(jzbcut_string,",");
1697 buchmann 1.7 for(int i=0;i<(int)jzbcutvector.size();i++) {
1698 buchmann 1.1 jzb_cut.push_back(atoi(jzbcutvector[i].c_str()));
1699     dout << "Added a JZB cut manually at " << atoi(jzbcutvector[i].c_str()) << endl;
1700     }
1701     }
1702    
1703     void process_directory(TString directory, vector<string> &files)
1704     {
1705     DIR *dp;
1706     struct dirent *ep;
1707    
1708     dp = opendir (directory);
1709     if (dp != NULL)
1710     {
1711 buchmann 1.7 while ((ep = readdir (dp)))
1712 buchmann 1.1 {
1713     string filename=(string)ep->d_name;
1714 buchmann 1.7 if((int)filename.find(".root")!=-1)
1715 buchmann 1.1 {
1716     files.push_back(string(directory)+filename);
1717     }
1718     }
1719     (void) closedir (dp);
1720     }
1721     else
1722     perror ("Couldn't open the directory");
1723     }
1724    
1725 buchmann 1.14 void ClearHisto(TH1* histo) {
1726 buchmann 1.12 for(int ix=0;ix<=histo->GetNbinsX()+1;ix++) {//also reset over- and underflow
1727     histo->SetBinContent(ix,0);
1728     histo->SetBinContent(ix,0);
1729     }
1730     }
1731    
1732     void AddSquared(TH1F *histo, TH1F *addthis, float weight) {
1733 buchmann 1.14 for(int ix=1;ix<=addthis->GetNbinsX()+1;ix++) {//also include over- and underflow
1734     float bincenter=addthis->GetBinCenter(ix);
1735     int nBinHisto= histo->FindBin(bincenter);
1736     float old_content=histo->GetBinContent(nBinHisto);
1737     histo->SetBinContent(nBinHisto,old_content+((addthis->GetBinContent(ix))*(addthis->GetBinContent(ix))*weight));
1738 buchmann 1.12 }
1739     }
1740    
1741 buchmann 1.14 void SQRT(TH1* histo) {
1742 buchmann 1.12 for(int ix=0;ix<=histo->GetNbinsX()+1;ix++) {//also include over- and underflow
1743     histo->SetBinContent(ix,TMath::Sqrt(histo->GetBinContent(ix)));
1744     }
1745     }
1746    
1747 buchmann 1.1 /*string GetCompleteHostname() {
1748     struct addrinfo hints, *info, *p;
1749     int gai_result;
1750     char hostname[1024];
1751     hostname[1023] = '\0';
1752     gethostname(hostname, 1023);
1753    
1754     string answer="GetCompleteHostname_ERROR";
1755    
1756     memset(&hints, 0, sizeof hints);
1757     hints.ai_family = AF_UNSPEC;
1758     hints.ai_socktype = SOCK_STREAM;
1759     hints.ai_flags = AI_CANONNAME;
1760    
1761     if ((gai_result = getaddrinfo(hostname, "http", &hints, &info)) != 0) {
1762     fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(gai_result));
1763     }
1764    
1765     for(p = info; p != NULL; p = p->ai_next) {
1766     answer=p->ai_canonname;
1767     printf("hostname: %s\n", p->ai_canonname);
1768     }
1769     return answer;
1770     }*/
1771    
1772     const char* concatenate (const char* a, const char* b) {
1773     stringstream bla;
1774     bla << a << b;
1775     return bla.str().c_str();
1776     }
1777    
1778 buchmann 1.8
1779     string ReplaceCharacter(string originalstring,string replacethis,string replacewiththis)
1780     {
1781     int pos = originalstring.find(replacethis);
1782     while(pos != -1) {
1783     originalstring.replace(pos, replacewiththis.length(), replacewiththis);
1784     pos = originalstring.find(replacethis);
1785     }
1786     return originalstring;
1787     }
1788    
1789     string removefunnystring(string name) {
1790     name=ReplaceCharacter(name,"[","_");
1791     name=ReplaceCharacter(name,"]","_");
1792     name=ReplaceCharacter(name,"{","_");
1793     name=ReplaceCharacter(name,"}","_");
1794     name=ReplaceCharacter(name,".","_");
1795     name=ReplaceCharacter(name,",","_");
1796     name=ReplaceCharacter(name,";","_");
1797     name=ReplaceCharacter(name,":","_");
1798     name=ReplaceCharacter(name,"'","_");
1799     name=ReplaceCharacter(name,"$","_");
1800     name=ReplaceCharacter(name,"@","_");
1801     name=ReplaceCharacter(name,"#","_");
1802     name=ReplaceCharacter(name,"+","_");
1803     name=ReplaceCharacter(name,"-","_");
1804     name=ReplaceCharacter(name,"/","_");
1805     return name;
1806     }
1807    
1808 buchmann 1.24 TPolyLine* GetFitUncertaintyShape(TF1 *fit, float low, float high,float x0,float x1) {
1809 buchmann 1.23 int nPoints=1000;
1810    
1811     double x[nPoints+1];
1812     double y[nPoints];
1813    
1814     float par1=fit->GetParameter(0);
1815     float dpar1=fit->GetParError(0);
1816     float par2=fit->GetParameter(1);
1817     float dpar2=fit->GetParError(1);
1818    
1819     float step=(x1-x0)/(nPoints/2.0 -1);
1820     for(int i=0;i<nPoints/2.0;i++) {
1821     x[i]=x0+i*step;
1822     y[i]=(par1+x[i]*par2) - sqrt(dpar1*dpar1+dpar2*dpar2*x[i]*x[i]);
1823     x[nPoints-1-i]=x[i];
1824     y[nPoints-1-i]=(par1+x[i]*par2) + sqrt(dpar1*dpar1+dpar2*dpar2*x[i]*x[i]);
1825     if(y[i]<low) y[i]=low;
1826     if(y[i]>high) y[i]=high;
1827     if(y[nPoints-1-i]<low) y[nPoints-1-i]=low;
1828     if(y[nPoints-1-i]>high) y[nPoints-1-i]=high;
1829     }
1830    
1831     x[nPoints]=x[0];
1832     y[nPoints]=y[0];
1833    
1834     TPolyLine *l = new TPolyLine(nPoints+1,x,y);
1835     l->SetFillColor(TColor::GetColor("#5858FA"));
1836 buchmann 1.24 l->SetLineColor(TColor::GetColor("#5858FA"));
1837     l->SetLineWidth(1);
1838 buchmann 1.23 return l;
1839 buchmann 1.24 }
1840    
1841    
1842     TPolyLine* GetFitUncertaintyShape(TH1 *histo, string fitname, float low, float high) {
1843     TF1 *fit = (TF1*)histo->GetFunction(fitname.c_str());
1844     if(!fit) {
1845     cout << "CANNOT PRODUCE FIT UNCERTAINTY AS THERE IS NO FIT CALLED " << fitname << " IN " << histo->GetName() << endl;
1846     return NULL;
1847     }
1848     float x0=histo->GetBinLowEdge(1);
1849     float x1=histo->GetBinLowEdge(histo->GetNbinsX())+histo->GetBinWidth(histo->GetNbinsX());
1850     return GetFitUncertaintyShape(fit, low, high,x0,x1);
1851     }
1852    
1853     TPolyLine* GetFitUncertaintyShape(TGraphErrors *gr, string fitname, float low, float high, float minx=-999, float maxx=-999) {
1854     TF1 *fit = (TF1*)gr->GetFunction(fitname.c_str());
1855     if(!fit) {
1856     cout << "CANNOT PRODUCE FIT UNCERTAINTY AS THERE IS NO FIT CALLED " << fitname << " IN " << gr->GetName() << endl;
1857     return NULL;
1858     }
1859     double x,y;
1860     gr->GetPoint(0,x,y);
1861     float min=x;
1862     gr->GetPoint(gr->GetN()-1,x,y);
1863     float max=x;
1864     if(minx>-999 && maxx>-999 && minx<maxx) {
1865     max=maxx;
1866     min=minx;
1867     }
1868     return GetFitUncertaintyShape(fit, low, high,min,max);
1869 buchmann 1.23 }
1870    
1871 buchmann 1.1 stringstream all_bugs;
1872    
1873     void bug_tracker(string function, int line, string description) {
1874     cout << "\033[1;31m .-. " << endl;
1875     cout << " o \\ .-. " << endl;
1876     cout << " .----.' \\ " << endl;
1877     cout << " .'o) / `. o " << endl;
1878     cout << " / | " << endl;
1879     cout << " \\_) /-. " << endl;
1880     cout << " '_.` \\ \\ " << endl;
1881     cout << " `. | \\ " << endl;
1882     cout << " | \\ | " << endl;
1883     cout << " .--/`-. / / " << endl;
1884     cout << " .'.-/`-. `. .\\| " << endl;
1885     cout << " /.' /`._ `- '-. " << endl;
1886     cout << " ____(|__/`-..`- '-._ \\ " << endl;
1887     cout << " |`------.'-._ ` ||\\ \\ " << endl;
1888     cout << " || # /-. ` / || \\| " << endl;
1889     cout << " || #/ `--' / /_::_|)__ " << endl;
1890     cout << " `|____|-._.-` / ||`--------` " << endl;
1891     cout << " \\-.___.` | / || # | " << endl;
1892     cout << " \\ | | || # # | " << endl;
1893     cout << " /`.___.'\\ |.`|________| " << endl;
1894     cout << " | /`.__.'|'.` " << endl;
1895     cout << " __/ \\ __/ \\ " << endl;
1896     cout << " /__.-.) /__.-.) LGB " << endl;
1897     cout << "" << endl;
1898     // bug ascii from : http://www.chris.com/ASCII/index.php?art=animals/insects/other
1899     cout << "There is a bug in " << function << " on line " << line << endl;
1900     cout << "The bug description is : " << description << endl;
1901     all_bugs << "There is a bug in " << function << " on line " << line << endl;
1902     all_bugs << "The bug description is : " << description << " \033[0m" << endl;
1903     }
1904    
1905     //TODO: Write a bug summary at the end.
1906    
1907 buchmann 1.2 float pSTAR(float mglu, float mlsp, float mchi2) {
1908 buchmann 1.20 float mz=91.0;
1909 buchmann 1.2 float res=((mchi2*mchi2)-(mlsp+mz)*(mlsp+mz));
1910     res*=((mchi2*mchi2)-(mlsp-mz)*(mlsp-mz));
1911     res=TMath::Sqrt(res)/(2*mchi2);
1912     return res;
1913     }
1914 buchmann 1.3
1915     float generalizedpSTAR(float massmother, float massdaughter1, float massdaughter2) {
1916     float res=((massmother*massmother)-(massdaughter1+massdaughter2)*(massdaughter1+massdaughter2));
1917     res*=((massmother*massmother)-(massdaughter1-massdaughter2)*(massdaughter1-massdaughter2));
1918     res=TMath::Sqrt(res)/(2*massmother);
1919     return res;
1920     }
1921 buchmann 1.24
1922     void FindMinMax(TGraphErrors *gr, float &min, float &max) {
1923     double x,y;
1924     gr->GetPoint(0,x,y);
1925     min=500*y;
1926     max=0.0002*y;
1927     for(int i=0;i<gr->GetN();i++) {
1928     gr->GetPoint(i,x,y);
1929     cout << "Point at " << x << "/" << y << " with error " << gr->GetErrorY(i) << endl;
1930     float potmin=y-1.5*gr->GetErrorY(i); // taking 1.5 times the error to allow for enough space to present the plot
1931     float potmax=y+1.5*gr->GetErrorY(i); // taking 1.5 times the error to allow for enough space to present the plot
1932     if(potmin<min) min=potmin;
1933     if(potmax>max) max=potmax;
1934     }
1935     }