ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.44
Committed: Tue May 21 11:50:31 2013 UTC (11 years, 11 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.43: +7 -2 lines
Log Message:
Added option for iJZB analysis; added possibility to use WriteYield function to get yields in general and not only have them printed on screen

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