ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.46
Committed: Fri Jun 28 15:03:02 2013 UTC (11 years, 10 months ago) by buchmann
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.45: +1 -0 lines
Log Message:
Updated files for migration to git (sync)

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