ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.45
Committed: Thu Jun 13 16:04:18 2013 UTC (11 years, 10 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.44: +12 -9 lines
Log Message:
Several fixes for iJZB

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