ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.38
Committed: Tue Apr 9 14:13:51 2013 UTC (12 years, 1 month ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.37: +66 -7 lines
Log Message:
Adapted style towards congergence: E_{T}^{miss} instead of MET, N_{jets} instead of N_{J}, mll plots starting at 20 GeV, lines at 70 GeV (end of SR), 81 and 101 (Z region); integral L instead of L_{int}

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