ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.43
Committed: Sun May 12 20:22:53 2013 UTC (11 years, 11 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.42: +5 -2 lines
Log Message:
GetYield now returns Value object (i.e. central value with error) instead of just central value

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