ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.40
Committed: Fri Apr 12 13:34:35 2013 UTC (12 years ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.39: +2 -9 lines
Log Message:
Adapted style a bit more (space between lumi and integral removed)

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.40 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.39 if(njets==3) sel="Low E_{T}^{miss} selection";
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 mainpad->Draw();
1376     mainpad->cd();
1377     mainpad->Range(0,0,1,1);
1378     mainpad->SetFillColor(kWhite);
1379     mainpad->SetBorderSize(0);
1380     mainpad->SetFrameFillColor(0);
1381     canvas->Range(0,0,1,1);
1382     canvas->Draw("same");
1383     mainpad->Modified();
1384 buchmann 1.33 Ratio_main_canvas->cd();
1385 buchmann 1.1 coverpad->Draw();
1386     coverpad->cd();
1387     coverpad->Range(0,0,1,1);
1388     coverpad->SetFillColor(kWhite);
1389     coverpad->SetBorderSize(0);
1390     coverpad->SetFrameFillColor(0);
1391     coverpad->Modified();
1392 buchmann 1.33 Ratio_main_canvas->cd();
1393 buchmann 1.1 bottompad->SetTopMargin(ratiotopmargin);
1394     bottompad->SetBottomMargin(ratiobottommargin);
1395     bottompad->Draw();
1396     bottompad->cd();
1397     bottompad->Range(0,0,1,1);
1398     bottompad->SetFillColor(kWhite);
1399     TH1F *ratio = (TH1F*)nominator->Clone(GetNumericHistoName().c_str());
1400     ratio->Divide(denominator);
1401     TGraphAsymmErrors *eratio;
1402 buchmann 1.14 TH1F *SystDown;
1403     TH1F *SystUp;
1404    
1405 buchmann 1.1 if(!do_bpred_ratio) eratio = produce_ratio_graph(ratio);
1406     else {
1407     bool using_data=false;
1408     if((int)savemeas.find("Data")>0) using_data=true;
1409     eratio = histRatio(nominator,denominator,using_data,PlottingSetup::global_ratio_binning,false);
1410 buchmann 1.13 if(syshisto!=0) {
1411 buchmann 1.14 SystDown = (TH1F*)syshisto->Clone("SystDown");
1412     SystUp = (TH1F*)syshisto->Clone("SystUp");
1413     for(int i=1;i<=syshisto->GetNbinsX();i++) {
1414     SystDown->SetBinContent(i,1-syshisto->GetBinContent(i));
1415     SystUp->SetBinContent(i,1+syshisto->GetBinContent(i));
1416     }
1417     SystDown->SetLineColor(TColor::GetColor("#006DE1"));
1418     SystUp->SetLineColor(TColor::GetColor("#006DE1"));
1419 buchmann 1.13 }
1420 buchmann 1.1 for(int i=1;i<=ratio->GetNbinsX();i++) {
1421     ratio->SetBinContent(i,0);
1422     ratio->SetBinError(i,0);
1423     }
1424 buchmann 1.13
1425 buchmann 1.1 }
1426 buchmann 1.25
1427     if(syshisto && !do_bpred_ratio) {
1428     SystDown = (TH1F*)syshisto->Clone("SystDown");
1429     SystUp = (TH1F*)syshisto->Clone("SystUp");
1430     for(int i=1;i<=syshisto->GetNbinsX();i++) {
1431     SystDown->SetBinContent(i,1-syshisto->GetBinContent(i));
1432     SystUp->SetBinContent(i,1+syshisto->GetBinContent(i));
1433     }
1434     SystDown->SetLineColor(TColor::GetColor("#006DE1"));
1435     SystUp->SetLineColor(TColor::GetColor("#006DE1"));
1436     }
1437 buchmann 1.1 eratio->SetFillColor(TColor::GetColor("#00ADE1"));
1438     ratio->SetTitle("");
1439 buchmann 1.21 ratio->GetYaxis()->SetRangeUser(0.0,2.0);
1440 buchmann 1.1 if(do_bpred_ratio) ratio->GetYaxis()->SetRangeUser(0.0,2.0);
1441     if(extendrange) ratio->GetYaxis()->SetRangeUser(0.0,4.0);
1442     ratio->GetXaxis()->SetTitle(nominator->GetXaxis()->GetTitle());
1443     ratio->GetXaxis()->CenterTitle();
1444     ratio->GetYaxis()->SetTitle(yaxistitle.c_str());
1445     ratio->GetYaxis()->SetTitleOffset(0.4);
1446     ratio->GetYaxis()->CenterTitle();
1447     ratio->SetStats(0);
1448     ratio->GetXaxis()->SetLabelSize(xstretchfactor*ratio->GetXaxis()->GetLabelSize());
1449     ratio->GetYaxis()->SetLabelSize(xstretchfactor*ratio->GetYaxis()->GetLabelSize());
1450     ratio->GetXaxis()->SetTitleSize(xstretchfactor*gStyle->GetTitleSize());
1451     ratio->GetYaxis()->SetTitleSize(xstretchfactor*gStyle->GetTitleSize());
1452     ratio->GetYaxis()->SetNdivisions(502,false);
1453     ratio->SetFillColor(TColor::GetColor("#58D3F7"));
1454     ratio->SetMarkerSize(0);
1455     ratio->Draw("e2");
1456 buchmann 1.28
1457     TGraphAsymmErrors *ratio_center = (TGraphAsymmErrors*)eratio->Clone("ratio_center");
1458     for(int i=0;i<ratio_center->GetN();i++) {
1459     ratio_center->SetPointError(i,ratio_center->GetErrorXlow(i),ratio_center->GetErrorXhigh(i),0.005,0.005);
1460     }
1461     ratio_center->SetFillColor(TColor::GetColor("#006381"));
1462    
1463 buchmann 1.13 if(syshisto!=0) {
1464     // sysratio->Draw("2");
1465     // eratio->Draw("2,same");
1466     eratio->Draw("2");
1467 buchmann 1.14 SystDown->Draw("histo,same");
1468     SystUp->Draw("histo,same");
1469 buchmann 1.13 } else {
1470     eratio->Draw("2");
1471     }
1472 buchmann 1.28 ratio_center->Draw("2");
1473 buchmann 1.1 ratio->Draw("same,axis");
1474     TLine *oneline = new TLine(ratio->GetXaxis()->GetBinLowEdge(1),1,ratio->GetXaxis()->GetBinLowEdge(ratio->GetNbinsX())+ratio->GetXaxis()->GetBinWidth(ratio->GetNbinsX()),1);
1475     oneline->SetLineStyle(2);
1476     oneline->SetLineColor(kBlue);
1477     oneline->Draw("same");
1478 buchmann 1.38 if(PlottingSetup::DrawMetSignalRegionMllLines) {
1479     cout << "Drawing extra lines in ratio this time around ... " << endl;
1480     float RatioYMax=2.0;
1481     if(extendrange) RatioYMax=4.0;
1482    
1483     TLine *SRline = new TLine(70,0,70,RatioYMax);
1484     TLine *ZLowLine = new TLine(91.2-PlottingSetup::ConsideredZWidth,0,91.2-PlottingSetup::ConsideredZWidth,RatioYMax);
1485     TLine *ZHiLine = new TLine(91.2+PlottingSetup::ConsideredZWidth,0,91.2+PlottingSetup::ConsideredZWidth,RatioYMax);
1486    
1487     SRline->SetLineStyle(2);
1488     ZLowLine->SetLineStyle(2);
1489     ZHiLine->SetLineStyle(2);
1490     SRline->SetLineColor(kGray+2);
1491     ZLowLine->SetLineColor(kGray+2);
1492     ZHiLine->SetLineColor(kGray+2);
1493     SRline->Draw();
1494     ZLowLine->Draw();
1495     ZHiLine->Draw();
1496     }
1497    
1498 buchmann 1.33 Ratio_main_canvas->cd();
1499     Ratio_main_canvas->Modified();
1500     Ratio_main_canvas->cd();
1501     Ratio_main_canvas->SetSelected(Ratio_main_canvas);
1502 buchmann 1.1
1503 buchmann 1.33 CompleteSave(Ratio_main_canvas,savemeas+"_withratio");
1504 buchmann 1.1 bottompad->cd();
1505    
1506     Double_t chi2;
1507     Int_t ndf,igood;
1508 buchmann 1.7 // Double_t res=0.0;
1509 buchmann 1.1 Double_t chi2prob = MarcosChi2TestX(nominator,denominator,chi2,ndf,igood,"UW");
1510    
1511     stringstream Chi2text;
1512     Chi2text << "#chi^{2} / ndf: " << chi2 << " / " << ndf;
1513     stringstream Chi2probtext;
1514     Chi2probtext << "#chi^{2} prob: " << chi2prob;
1515     TText* chi2box = write_text(0.02,0.11,Chi2text.str());
1516     chi2box->SetTextSize(0.08);
1517     chi2box->SetTextAlign(11);
1518     chi2box->Draw();
1519     TText* chi2probbox = write_text(0.02,0.04,Chi2probtext.str());
1520     chi2probbox->SetTextSize(0.08);
1521     chi2probbox->SetTextAlign(11);
1522     chi2probbox->Draw();
1523 buchmann 1.11
1524     stringstream CompRatio;
1525     CompRatio << "Ratio: " << nominator->Integral() << " / " << denominator->Integral() << " \n " << nominator->Integral()/denominator->Integral();
1526     TText *CompleteRatio = write_text(0.98,0.04,CompRatio.str());
1527     CompleteRatio->SetTextSize(0.08);
1528     CompleteRatio->SetTextAlign(31);
1529     CompleteRatio->Draw();
1530    
1531 buchmann 1.33 CompleteSave(Ratio_main_canvas,savemeas+"_withratio_and_Chi2");
1532 buchmann 1.1
1533     // float KS = nominator->KolmogorovTest(denominator);
1534     // stringstream KStext;
1535     // Chi2text << "KS = " << KS << endl;
1536     //cout << "Found : " << KStext.str() << endl;
1537    
1538 buchmann 1.31 delete eratio;
1539     delete ratio_center;
1540     delete ratio;
1541 buchmann 1.33 delete Ratio_main_canvas;
1542 buchmann 1.1 }
1543    
1544 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) {
1545     PlottingSetup::ConsideredZWidth=10.0;
1546     PlottingSetup::DrawMetSignalRegionMllLines=true;
1547     Save_With_Ratio(nominator, denominator, orig_canvas, savemeas, do_bpred_ratio, extendrange, yaxistitle,syshisto);
1548     PlottingSetup::DrawMetSignalRegionMllLines=false;
1549     }
1550    
1551     void Save_With_Ratio_And_Line(TH1F *nominator, THStack denominator, TVirtualPad *canvas, string savemeas, bool do_bpred_ratio=false) {
1552     TH1F *denominator_histo = (TH1F*) CollapseStack(denominator,"TemporaryStack");
1553     Save_With_Ratio_And_Line(nominator, denominator_histo, canvas, savemeas, do_bpred_ratio);
1554     delete denominator_histo;
1555     }
1556    
1557     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) {
1558 buchmann 1.19 //this function saves the pad being passed as well as a new one including the SysRatio.
1559 buchmann 1.33 orig_canvas->cd();
1560     orig_canvas->Update();
1561     CompleteSave(orig_canvas,savemeas);
1562    
1563     TVirtualPad *canvas = (TVirtualPad*) orig_canvas->Clone("TempCanvas");//otherwise the Ratio_main_canvas will own our pad and destroy it upon deletion
1564 buchmann 1.19
1565     float bottommargin=gStyle->GetPadBottomMargin();
1566     float canvas_height=gStyle->GetCanvasDefH();
1567     float canvas_width=gStyle->GetCanvasDefW();
1568 buchmann 1.25 float ratiospace=0.25;// space the ratio should take up (relative to original pad)
1569    
1570     float ratiobottommargin=0.3;
1571     float ratiotopmargin=0.1;
1572 buchmann 1.19
1573 buchmann 1.25 float xstretchfactor=((1-ratiospace)*(1-gStyle->GetPadTopMargin()))/((1)*ratiospace);
1574    
1575 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)));
1576 buchmann 1.25 TPad *mainpad = new TPad("mainpad","mainpad",0,1-(1.0/(1+ratiospace)),1,1);//top (main) pad
1577     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
1578     TPad *bottompad = new TPad("bottompad", "Ratio Pad",0,0,1,(1-(1-bottommargin)/(1+ratiospace))-0.015); //bottom pad
1579 buchmann 1.19
1580 buchmann 1.33 Ratio_main_canvas->Range(0,0,1,1);
1581     Ratio_main_canvas->SetBorderSize(0);
1582     Ratio_main_canvas->SetFrameFillColor(0);
1583 buchmann 1.19
1584 buchmann 1.25 mainpad->Draw();
1585     mainpad->cd();
1586     mainpad->Range(0,0,1,1);
1587     mainpad->SetFillColor(kWhite);
1588     mainpad->SetBorderSize(0);
1589     mainpad->SetFrameFillColor(0);
1590 buchmann 1.19 canvas->Range(0,0,1,1);
1591     canvas->Draw("same");
1592 buchmann 1.25 mainpad->Modified();
1593 buchmann 1.33 Ratio_main_canvas->cd();
1594 buchmann 1.25 coverpad->Draw();
1595     coverpad->cd();
1596     coverpad->Range(0,0,1,1);
1597     coverpad->SetFillColor(kWhite);
1598     coverpad->SetBorderSize(0);
1599     coverpad->SetFrameFillColor(0);
1600     coverpad->Modified();
1601 buchmann 1.33 Ratio_main_canvas->cd();
1602 buchmann 1.25 bottompad->SetTopMargin(ratiotopmargin);
1603     bottompad->SetBottomMargin(ratiobottommargin);
1604     bottompad->Draw();
1605     bottompad->cd();
1606     bottompad->Range(0,0,1,1);
1607     bottompad->SetFillColor(kWhite);
1608     TH1F *ratio = (TH1F*)nominator->Clone(GetNumericHistoName().c_str());
1609     ratio->Divide(denominator);
1610 buchmann 1.19
1611    
1612 buchmann 1.25 TGraphAsymmErrors *eratio;
1613     TGraphAsymmErrors *SysEnvelope = new TGraphAsymmErrors();
1614    
1615     if(syshisto && !do_bpred_ratio) {
1616     for(int i=1;i<=syshisto->GetNbinsX();i++) {
1617 buchmann 1.26 float dx=syshisto->GetBinWidth(i)/2.0;
1618     float dy=syshisto->GetBinContent(i);
1619     if(dy<0.01) dy=0.07;
1620 buchmann 1.25 SysEnvelope->SetPoint(i-1,syshisto->GetBinCenter(i),1.0);
1621 buchmann 1.26 SysEnvelope->SetPointError(i-1,dx,dx,dy,dy);
1622 buchmann 1.25 }
1623     SysEnvelope->SetFillColor(TColor::GetColor("#006DE1"));
1624     }
1625 buchmann 1.19
1626 buchmann 1.25 ratio->SetTitle("");
1627     ratio->GetYaxis()->SetRangeUser(0.0,2.0);
1628     if(do_bpred_ratio) ratio->GetYaxis()->SetRangeUser(0.0,2.0);
1629     if(extendrange) ratio->GetYaxis()->SetRangeUser(0.0,4.0);
1630     ratio->GetXaxis()->SetTitle(nominator->GetXaxis()->GetTitle());
1631     ratio->GetXaxis()->CenterTitle();
1632     ratio->GetYaxis()->SetTitle(yaxistitle.c_str());
1633     ratio->GetYaxis()->SetTitleOffset(0.4);
1634     ratio->GetYaxis()->CenterTitle();
1635     ratio->SetStats(0);
1636     ratio->GetXaxis()->SetLabelSize(xstretchfactor*ratio->GetXaxis()->GetLabelSize());
1637     ratio->GetYaxis()->SetLabelSize(xstretchfactor*ratio->GetYaxis()->GetLabelSize());
1638     ratio->GetXaxis()->SetTitleSize(xstretchfactor*gStyle->GetTitleSize());
1639     ratio->GetYaxis()->SetTitleSize(xstretchfactor*gStyle->GetTitleSize());
1640     ratio->GetYaxis()->SetNdivisions(502,false);
1641     ratio->SetFillColor(TColor::GetColor("#58D3F7"));
1642 buchmann 1.39 ratio->Draw("e0");
1643 buchmann 1.19
1644 buchmann 1.25 if(syshisto!=0) {
1645     SysEnvelope->SetFillColor(TColor::GetColor("#FE9A2E"));
1646     SysEnvelope->Draw("2,same");
1647 buchmann 1.39 ratio->Draw("e0,same");
1648 buchmann 1.25 } else {
1649 buchmann 1.39 eratio->Draw("0");
1650 buchmann 1.25 }
1651     ratio->Draw("same,axis");
1652     TLine *oneline = new TLine(ratio->GetXaxis()->GetBinLowEdge(1),1,ratio->GetXaxis()->GetBinLowEdge(ratio->GetNbinsX())+ratio->GetXaxis()->GetBinWidth(ratio->GetNbinsX()),1);
1653 buchmann 1.19 oneline->SetLineStyle(2);
1654     oneline->SetLineColor(kBlue);
1655     oneline->Draw("same");
1656 buchmann 1.38
1657    
1658    
1659     if(ConsideredZWidth>0.1) {
1660     cout << "Drawing extra lines in ratio this time around ... " << endl;
1661     float RatioYMax=2.0;
1662     if(extendrange) RatioYMax=4.0;
1663    
1664     TLine *SRline = new TLine(70,0,70,RatioYMax);
1665     TLine *ZLowLine = new TLine(91.2-ConsideredZWidth,0,91.2-ConsideredZWidth,RatioYMax);
1666     TLine *ZHiLine = new TLine(91.2+ConsideredZWidth,0,91.2+ConsideredZWidth,RatioYMax);
1667    
1668     SRline->SetLineStyle(2);
1669     ZLowLine->SetLineStyle(2);
1670     ZHiLine->SetLineStyle(2);
1671     SRline->SetLineColor(kGray+2);
1672     ZLowLine->SetLineColor(kGray+2);
1673     ZHiLine->SetLineColor(kGray+2);
1674     SRline->Draw();
1675     ZLowLine->Draw();
1676     ZHiLine->Draw();
1677     }
1678 buchmann 1.19
1679 buchmann 1.33 Ratio_main_canvas->cd();
1680     Ratio_main_canvas->Modified();
1681     Ratio_main_canvas->cd();
1682     Ratio_main_canvas->SetSelected(Ratio_main_canvas);
1683 buchmann 1.25
1684 buchmann 1.33 CompleteSave(Ratio_main_canvas,savemeas+"_withSysRatio");
1685 buchmann 1.25 bottompad->cd();
1686    
1687     Double_t chi2;
1688     Int_t ndf,igood;
1689     Double_t chi2prob = MarcosChi2TestX(nominator,denominator,chi2,ndf,igood,"UW");
1690    
1691     stringstream Chi2text;
1692     Chi2text << "#chi^{2} / ndf: " << chi2 << " / " << ndf;
1693     stringstream Chi2probtext;
1694     Chi2probtext << "#chi^{2} prob: " << chi2prob;
1695     TText* chi2box = write_text(0.02,0.11,Chi2text.str());
1696     chi2box->SetTextSize(0.08);
1697     chi2box->SetTextAlign(11);
1698     chi2box->Draw();
1699     TText* chi2probbox = write_text(0.02,0.04,Chi2probtext.str());
1700     chi2probbox->SetTextSize(0.08);
1701     chi2probbox->SetTextAlign(11);
1702     chi2probbox->Draw();
1703    
1704     stringstream CompRatio;
1705     CompRatio << "Ratio: " << nominator->Integral() << " / " << denominator->Integral() << " \n " << nominator->Integral()/denominator->Integral();
1706     TText *CompleteRatio = write_text(0.98,0.04,CompRatio.str());
1707     CompleteRatio->SetTextSize(0.08);
1708     CompleteRatio->SetTextAlign(31);
1709     CompleteRatio->Draw();
1710    
1711 buchmann 1.33 CompleteSave(Ratio_main_canvas,savemeas+"_withSysRatio_and_Chi2");
1712     delete Ratio_main_canvas;
1713 buchmann 1.31 delete ratio;
1714 buchmann 1.19 }
1715 buchmann 1.1
1716 buchmann 1.31 TH1F* CollapseStack(THStack stack,TString hname="CollapsedStack") {
1717 buchmann 1.1 TH1F *bhist = ((TH1F*)((stack.GetHists())->At(0)));
1718 fronga 1.22 TH1F *basehisto = (TH1F*)bhist->Clone(hname);
1719 buchmann 1.1 TIter next(stack.GetHists());
1720     TH1F *h;
1721     int counter=0;
1722     while ((h=(TH1F*)next())) {
1723     counter++;
1724     if(counter==1) continue;
1725     basehisto->Add(h);
1726     }
1727     return basehisto;
1728     }
1729    
1730 buchmann 1.32 void Save_With_Ratio(TH1F *nominator, THStack denominator, TVirtualPad *canvas, string savemeas, bool do_bpred_ratio=false) {
1731     TH1F *denominator_histo = (TH1F*) CollapseStack(denominator);
1732     Save_With_Ratio(nominator, denominator_histo, canvas, savemeas, do_bpred_ratio);
1733 buchmann 1.31 delete denominator_histo;
1734 buchmann 1.1 }
1735    
1736     void flag_this_change(string function, int line, int checked=0) {
1737     stringstream peakmodificationwarning;
1738     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 :-) ";
1739     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)";
1740     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.";
1741    
1742    
1743     if(checked==0) write_warning(function,peakmodificationwarning.str());
1744     // if(checked==1) write_info(function,peakmodificationwarning.str());
1745     peakmodificationwarning << " This modification has been checked and the changes have been reproduced. Checks completed.";
1746     if(checked==2) write_info(function,peakmodificationwarning.str());
1747     }
1748    
1749 buchmann 1.8 void write_analysis_type(bool isonpeak, bool dobtag) {
1750 buchmann 1.1 //http://www.network-science.de/ascii/, ogre
1751     if(!PlottingSetup::publicmode) {
1752     if(isonpeak) {
1753 buchmann 1.8 //font: big
1754 buchmann 1.1 dout << "\033[1;34m" << endl;
1755 buchmann 1.8 dout << " _ __________ " << endl;
1756     dout << " | |___ / _ \\ " << endl;
1757     dout << " /\\ ___ | | / /| |_) | " << endl;
1758     dout << " / \\ / _|_ | | / / | _ < " << endl;
1759     dout << " / \\ | (_| |__| |/ /__| |_) | " << endl;
1760     dout << " \\___|\\____//_____|____/ " << endl;
1761 buchmann 1.1 } else {
1762 buchmann 1.8 //font: big
1763 buchmann 1.1 dout << "\033[1;33m" << endl;
1764 buchmann 1.5 dout << " _ _ __________ " << endl;
1765     dout << " (_) | |___ / _ \\ " << endl;
1766     dout << " /\\ _ | | / /| |_) | " << endl;
1767     dout << " /\\/ \\ | |_ | | / / | _ < " << endl;
1768     dout << " / \\ | | |__| |/ /__| |_) | " << endl;
1769     dout << " |_|\\____//_____|____/ " << endl;
1770 buchmann 1.1 }
1771 buchmann 1.8
1772     if(dobtag) {
1773     //font: big
1774     dout << "\033[1;32m \\ / " << endl;
1775     dout << " \\ o ^ o / " << endl;
1776     dout << " \\ ( ) / " << endl;
1777     dout << " ____________(%%%%%%%)____________ _ _ __________ " << endl;
1778     dout << " ( / / )%%%%%%%( \\ \\ ) | | | |___ / _ \\ " << endl;
1779     dout << " (___/___/__/ \\__\\___\\___) | |__ | | / /| |_) | " << endl;
1780     dout << " ( / /(%%%%%%%)\\ \\ ) | '_ \\ _ | | / / | _ < " << endl;
1781     dout << " (__/___/ (%%%%%%%) \\___\\__) | |_) | |__| |/ /__| |_) | " << endl;
1782     dout << " /( )\\ |_.__/ \\____//_____|____/ " << endl;
1783     dout << " / (%%%%%) \\ " << endl;
1784     dout << " (%%%) " << endl;
1785     dout << " ! " << endl;
1786     }
1787     } else {
1788     //we're in public! don't advertise what we're up to :-)
1789     dout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
1790     dout << " Starting the analysis " << endl;
1791 buchmann 1.11 dout << " i:" << !isonpeak << " , b " << dobtag << endl;
1792 buchmann 1.8 dout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
1793 buchmann 1.1 }
1794 buchmann 1.8 dout << "\033[0m" << endl;
1795    
1796 buchmann 1.1 }
1797    
1798    
1799     vector<string> StringSplit(string str, string delim)
1800     {
1801     vector<string> results;
1802    
1803     int cutAt;
1804 buchmann 1.7 while( (cutAt = str.find_first_of(delim)) != (int)str.npos )
1805 buchmann 1.1 {
1806     if(cutAt > 0)
1807     {
1808     results.push_back(str.substr(0,cutAt));
1809     }
1810     str = str.substr(cutAt+1);
1811     }
1812     if(str.length() > 0)
1813     {
1814     results.push_back(str);
1815     }
1816     return results;
1817     }
1818    
1819     void manually_set_jzb_cuts(vector<float> &jzb_cut,string jzbcut_string) {
1820     vector<string> jzbcutvector = StringSplit(jzbcut_string,",");
1821 buchmann 1.7 for(int i=0;i<(int)jzbcutvector.size();i++) {
1822 buchmann 1.1 jzb_cut.push_back(atoi(jzbcutvector[i].c_str()));
1823     dout << "Added a JZB cut manually at " << atoi(jzbcutvector[i].c_str()) << endl;
1824     }
1825     }
1826    
1827     void process_directory(TString directory, vector<string> &files)
1828     {
1829     DIR *dp;
1830     struct dirent *ep;
1831    
1832     dp = opendir (directory);
1833     if (dp != NULL)
1834     {
1835 buchmann 1.7 while ((ep = readdir (dp)))
1836 buchmann 1.1 {
1837     string filename=(string)ep->d_name;
1838 buchmann 1.7 if((int)filename.find(".root")!=-1)
1839 buchmann 1.1 {
1840     files.push_back(string(directory)+filename);
1841     }
1842     }
1843     (void) closedir (dp);
1844     }
1845     else
1846     perror ("Couldn't open the directory");
1847     }
1848    
1849 buchmann 1.14 void ClearHisto(TH1* histo) {
1850 buchmann 1.12 for(int ix=0;ix<=histo->GetNbinsX()+1;ix++) {//also reset over- and underflow
1851     histo->SetBinContent(ix,0);
1852     histo->SetBinContent(ix,0);
1853     }
1854     }
1855    
1856     void AddSquared(TH1F *histo, TH1F *addthis, float weight) {
1857 buchmann 1.14 for(int ix=1;ix<=addthis->GetNbinsX()+1;ix++) {//also include over- and underflow
1858     float bincenter=addthis->GetBinCenter(ix);
1859     int nBinHisto= histo->FindBin(bincenter);
1860     float old_content=histo->GetBinContent(nBinHisto);
1861     histo->SetBinContent(nBinHisto,old_content+((addthis->GetBinContent(ix))*(addthis->GetBinContent(ix))*weight));
1862 buchmann 1.12 }
1863     }
1864    
1865 buchmann 1.14 void SQRT(TH1* histo) {
1866 buchmann 1.12 for(int ix=0;ix<=histo->GetNbinsX()+1;ix++) {//also include over- and underflow
1867     histo->SetBinContent(ix,TMath::Sqrt(histo->GetBinContent(ix)));
1868     }
1869     }
1870    
1871 buchmann 1.1 /*string GetCompleteHostname() {
1872     struct addrinfo hints, *info, *p;
1873     int gai_result;
1874     char hostname[1024];
1875     hostname[1023] = '\0';
1876     gethostname(hostname, 1023);
1877    
1878     string answer="GetCompleteHostname_ERROR";
1879    
1880     memset(&hints, 0, sizeof hints);
1881     hints.ai_family = AF_UNSPEC;
1882     hints.ai_socktype = SOCK_STREAM;
1883     hints.ai_flags = AI_CANONNAME;
1884    
1885     if ((gai_result = getaddrinfo(hostname, "http", &hints, &info)) != 0) {
1886     fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(gai_result));
1887     }
1888    
1889     for(p = info; p != NULL; p = p->ai_next) {
1890     answer=p->ai_canonname;
1891     printf("hostname: %s\n", p->ai_canonname);
1892     }
1893     return answer;
1894     }*/
1895    
1896     const char* concatenate (const char* a, const char* b) {
1897     stringstream bla;
1898     bla << a << b;
1899     return bla.str().c_str();
1900     }
1901    
1902 buchmann 1.8
1903     string ReplaceCharacter(string originalstring,string replacethis,string replacewiththis)
1904     {
1905     int pos = originalstring.find(replacethis);
1906     while(pos != -1) {
1907     originalstring.replace(pos, replacewiththis.length(), replacewiththis);
1908     pos = originalstring.find(replacethis);
1909     }
1910     return originalstring;
1911     }
1912    
1913     string removefunnystring(string name) {
1914     name=ReplaceCharacter(name,"[","_");
1915     name=ReplaceCharacter(name,"]","_");
1916     name=ReplaceCharacter(name,"{","_");
1917     name=ReplaceCharacter(name,"}","_");
1918 buchmann 1.28 name=ReplaceCharacter(name,"(","_");
1919     name=ReplaceCharacter(name,")","_");
1920     name=ReplaceCharacter(name," ","_");
1921 buchmann 1.8 name=ReplaceCharacter(name,".","_");
1922     name=ReplaceCharacter(name,",","_");
1923     name=ReplaceCharacter(name,";","_");
1924     name=ReplaceCharacter(name,":","_");
1925     name=ReplaceCharacter(name,"'","_");
1926     name=ReplaceCharacter(name,"$","_");
1927     name=ReplaceCharacter(name,"@","_");
1928     name=ReplaceCharacter(name,"#","_");
1929     name=ReplaceCharacter(name,"+","_");
1930     name=ReplaceCharacter(name,"-","_");
1931     name=ReplaceCharacter(name,"/","_");
1932     return name;
1933     }
1934    
1935 buchmann 1.24 TPolyLine* GetFitUncertaintyShape(TF1 *fit, float low, float high,float x0,float x1) {
1936 buchmann 1.23 int nPoints=1000;
1937     double x[nPoints+1];
1938     double y[nPoints];
1939    
1940     float par1=fit->GetParameter(0);
1941     float dpar1=fit->GetParError(0);
1942     float par2=fit->GetParameter(1);
1943     float dpar2=fit->GetParError(1);
1944    
1945     float step=(x1-x0)/(nPoints/2.0 -1);
1946     for(int i=0;i<nPoints/2.0;i++) {
1947     x[i]=x0+i*step;
1948     y[i]=(par1+x[i]*par2) - sqrt(dpar1*dpar1+dpar2*dpar2*x[i]*x[i]);
1949     x[nPoints-1-i]=x[i];
1950     y[nPoints-1-i]=(par1+x[i]*par2) + sqrt(dpar1*dpar1+dpar2*dpar2*x[i]*x[i]);
1951     if(y[i]<low) y[i]=low;
1952     if(y[i]>high) y[i]=high;
1953     if(y[nPoints-1-i]<low) y[nPoints-1-i]=low;
1954     if(y[nPoints-1-i]>high) y[nPoints-1-i]=high;
1955     }
1956    
1957     x[nPoints]=x[0];
1958     y[nPoints]=y[0];
1959    
1960     TPolyLine *l = new TPolyLine(nPoints+1,x,y);
1961 buchmann 1.36 l->SetFillColor(TColor::GetColor("#A2A2FA"));
1962     l->SetLineColor(TColor::GetColor("#A2A2FA"));
1963 buchmann 1.24 l->SetLineWidth(1);
1964 buchmann 1.23 return l;
1965 buchmann 1.24 }
1966    
1967 buchmann 1.27 //code for ReplaceAll copied from
1968     //http://stackoverflow.com/questions/5343190/c-how-do-i-replace-all-instances-of-of-a-string-with-another-string
1969     string ReplaceAll(string str, string from, string to) {
1970     size_t start_pos = 0;
1971     while((start_pos = str.find(from, start_pos)) != std::string::npos) {
1972     str.replace(start_pos, from.length(), to);
1973     start_pos += to.length(); // ...
1974     }
1975     return str;
1976     }
1977 buchmann 1.24
1978     TPolyLine* GetFitUncertaintyShape(TH1 *histo, string fitname, float low, float high) {
1979     TF1 *fit = (TF1*)histo->GetFunction(fitname.c_str());
1980     if(!fit) {
1981     cout << "CANNOT PRODUCE FIT UNCERTAINTY AS THERE IS NO FIT CALLED " << fitname << " IN " << histo->GetName() << endl;
1982     return NULL;
1983     }
1984     float x0=histo->GetBinLowEdge(1);
1985     float x1=histo->GetBinLowEdge(histo->GetNbinsX())+histo->GetBinWidth(histo->GetNbinsX());
1986     return GetFitUncertaintyShape(fit, low, high,x0,x1);
1987     }
1988    
1989     TPolyLine* GetFitUncertaintyShape(TGraphErrors *gr, string fitname, float low, float high, float minx=-999, float maxx=-999) {
1990     TF1 *fit = (TF1*)gr->GetFunction(fitname.c_str());
1991     if(!fit) {
1992     cout << "CANNOT PRODUCE FIT UNCERTAINTY AS THERE IS NO FIT CALLED " << fitname << " IN " << gr->GetName() << endl;
1993     return NULL;
1994     }
1995     double x,y;
1996     gr->GetPoint(0,x,y);
1997     float min=x;
1998     gr->GetPoint(gr->GetN()-1,x,y);
1999     float max=x;
2000     if(minx>-999 && maxx>-999 && minx<maxx) {
2001     max=maxx;
2002     min=minx;
2003     }
2004     return GetFitUncertaintyShape(fit, low, high,min,max);
2005 buchmann 1.23 }
2006    
2007 buchmann 1.1 stringstream all_bugs;
2008    
2009     void bug_tracker(string function, int line, string description) {
2010     cout << "\033[1;31m .-. " << endl;
2011     cout << " o \\ .-. " << endl;
2012     cout << " .----.' \\ " << endl;
2013     cout << " .'o) / `. o " << endl;
2014     cout << " / | " << endl;
2015     cout << " \\_) /-. " << endl;
2016     cout << " '_.` \\ \\ " << endl;
2017     cout << " `. | \\ " << endl;
2018     cout << " | \\ | " << endl;
2019     cout << " .--/`-. / / " << endl;
2020     cout << " .'.-/`-. `. .\\| " << 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 << " /__.-.) /__.-.) LGB " << endl;
2033     cout << "" << endl;
2034     // bug ascii from : http://www.chris.com/ASCII/index.php?art=animals/insects/other
2035     cout << "There is a bug in " << function << " on line " << line << endl;
2036     cout << "The bug description is : " << description << endl;
2037     all_bugs << "There is a bug in " << function << " on line " << line << endl;
2038     all_bugs << "The bug description is : " << description << " \033[0m" << endl;
2039     }
2040    
2041     //TODO: Write a bug summary at the end.
2042    
2043 buchmann 1.2 float pSTAR(float mglu, float mlsp, float mchi2) {
2044 buchmann 1.20 float mz=91.0;
2045 buchmann 1.2 float res=((mchi2*mchi2)-(mlsp+mz)*(mlsp+mz));
2046     res*=((mchi2*mchi2)-(mlsp-mz)*(mlsp-mz));
2047     res=TMath::Sqrt(res)/(2*mchi2);
2048     return res;
2049     }
2050 buchmann 1.3
2051     float generalizedpSTAR(float massmother, float massdaughter1, float massdaughter2) {
2052     float res=((massmother*massmother)-(massdaughter1+massdaughter2)*(massdaughter1+massdaughter2));
2053     res*=((massmother*massmother)-(massdaughter1-massdaughter2)*(massdaughter1-massdaughter2));
2054     res=TMath::Sqrt(res)/(2*massmother);
2055     return res;
2056     }
2057 buchmann 1.24
2058     void FindMinMax(TGraphErrors *gr, float &min, float &max) {
2059     double x,y;
2060     gr->GetPoint(0,x,y);
2061     min=500*y;
2062     max=0.0002*y;
2063     for(int i=0;i<gr->GetN();i++) {
2064     gr->GetPoint(i,x,y);
2065     cout << "Point at " << x << "/" << y << " with error " << gr->GetErrorY(i) << endl;
2066     float potmin=y-1.5*gr->GetErrorY(i); // taking 1.5 times the error to allow for enough space to present the plot
2067     float potmax=y+1.5*gr->GetErrorY(i); // taking 1.5 times the error to allow for enough space to present the plot
2068     if(potmin<min) min=potmin;
2069     if(potmax>max) max=potmax;
2070     }
2071     }
2072 buchmann 1.28
2073    
2074     void CleanLegends() {
2075     for(int ihist=(int)PlottingSetup::FakeHistoHeap.size()-1;ihist>=0;ihist--) {
2076     PlottingSetup::FakeHistoHeap[ihist]->Delete();
2077     PlottingSetup::FakeHistoHeap.pop_back();
2078     }
2079     }
2080 buchmann 1.34
2081     string DigitsAfterComma(float number, int digits) {
2082     float temp=number*pow(10.0,digits);
2083     temp=int(temp)/pow(10.0,digits);
2084     return any2string(temp);
2085     }