ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.31
Committed: Mon Jan 21 11:39:02 2013 UTC (12 years, 3 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.30: +9 -3 lines
Log Message:
Gave collapsed stack histogram a clearer name; fixed some potential memory leaks

File Contents

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