ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.32
Committed: Thu Jan 24 08:21:38 2013 UTC (12 years, 3 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.31: +8 -5 lines
Log Message:
Updated saving method (with sys and ratio) to not chew up provided tvirtualpad

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.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) {
1333 buchmann 1.1 //this function saves the pad being passed as well as a new one including the ratio.
1334 buchmann 1.32
1335     TVirtualPad *canvas = (TVirtualPad*) orig_canvas->Clone("TempCanvas");//otherwise the main_canvas will own our pad and destroy it upon deletion
1336 buchmann 1.1 CompleteSave(canvas,savemeas);
1337 buchmann 1.31
1338 buchmann 1.1 float bottommargin=gStyle->GetPadBottomMargin();
1339     float canvas_height=gStyle->GetCanvasDefH();
1340     float canvas_width=gStyle->GetCanvasDefW();
1341     float ratiospace=0.25;// space the ratio should take up (relative to original pad)
1342    
1343     float ratiobottommargin=0.3;
1344     float ratiotopmargin=0.1;
1345    
1346     float xstretchfactor=((1-ratiospace)*(1-gStyle->GetPadTopMargin()))/((1)*ratiospace);
1347    
1348     TCanvas *main_canvas = new TCanvas("main_canvas","main_canvas",(Int_t)canvas_width,(Int_t)(canvas_height*(1+ratiospace)));
1349     TPad *mainpad = new TPad("mainpad","mainpad",0,1-(1.0/(1+ratiospace)),1,1);//top (main) pad
1350     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
1351     TPad *bottompad = new TPad("bottompad", "Ratio Pad",0,0,1,(1-(1-bottommargin)/(1+ratiospace))-0.015); //bottom pad
1352    
1353     main_canvas->Range(0,0,1,1);
1354     main_canvas->SetBorderSize(0);
1355     main_canvas->SetFrameFillColor(0);
1356    
1357     mainpad->Draw();
1358     mainpad->cd();
1359     mainpad->Range(0,0,1,1);
1360     mainpad->SetFillColor(kWhite);
1361     mainpad->SetBorderSize(0);
1362     mainpad->SetFrameFillColor(0);
1363     canvas->Range(0,0,1,1);
1364     canvas->Draw("same");
1365     mainpad->Modified();
1366     main_canvas->cd();
1367     coverpad->Draw();
1368     coverpad->cd();
1369     coverpad->Range(0,0,1,1);
1370     coverpad->SetFillColor(kWhite);
1371     coverpad->SetBorderSize(0);
1372     coverpad->SetFrameFillColor(0);
1373     coverpad->Modified();
1374     main_canvas->cd();
1375     bottompad->SetTopMargin(ratiotopmargin);
1376     bottompad->SetBottomMargin(ratiobottommargin);
1377     bottompad->Draw();
1378     bottompad->cd();
1379     bottompad->Range(0,0,1,1);
1380     bottompad->SetFillColor(kWhite);
1381     TH1F *ratio = (TH1F*)nominator->Clone(GetNumericHistoName().c_str());
1382     ratio->Divide(denominator);
1383    
1384     TGraphAsymmErrors *eratio;
1385 buchmann 1.14 TH1F *SystDown;
1386     TH1F *SystUp;
1387    
1388 buchmann 1.1 if(!do_bpred_ratio) eratio = produce_ratio_graph(ratio);
1389     else {
1390     bool using_data=false;
1391     if((int)savemeas.find("Data")>0) using_data=true;
1392     eratio = histRatio(nominator,denominator,using_data,PlottingSetup::global_ratio_binning,false);
1393 buchmann 1.13 if(syshisto!=0) {
1394 buchmann 1.14 SystDown = (TH1F*)syshisto->Clone("SystDown");
1395     SystUp = (TH1F*)syshisto->Clone("SystUp");
1396     for(int i=1;i<=syshisto->GetNbinsX();i++) {
1397     SystDown->SetBinContent(i,1-syshisto->GetBinContent(i));
1398     SystUp->SetBinContent(i,1+syshisto->GetBinContent(i));
1399     }
1400     SystDown->SetLineColor(TColor::GetColor("#006DE1"));
1401     SystUp->SetLineColor(TColor::GetColor("#006DE1"));
1402 buchmann 1.13 }
1403 buchmann 1.1 for(int i=1;i<=ratio->GetNbinsX();i++) {
1404     ratio->SetBinContent(i,0);
1405     ratio->SetBinError(i,0);
1406     }
1407 buchmann 1.13
1408 buchmann 1.1 }
1409 buchmann 1.25
1410     if(syshisto && !do_bpred_ratio) {
1411     SystDown = (TH1F*)syshisto->Clone("SystDown");
1412     SystUp = (TH1F*)syshisto->Clone("SystUp");
1413     for(int i=1;i<=syshisto->GetNbinsX();i++) {
1414     SystDown->SetBinContent(i,1-syshisto->GetBinContent(i));
1415     SystUp->SetBinContent(i,1+syshisto->GetBinContent(i));
1416     }
1417     SystDown->SetLineColor(TColor::GetColor("#006DE1"));
1418     SystUp->SetLineColor(TColor::GetColor("#006DE1"));
1419     }
1420 buchmann 1.1 eratio->SetFillColor(TColor::GetColor("#00ADE1"));
1421    
1422     ratio->SetTitle("");
1423 buchmann 1.21 ratio->GetYaxis()->SetRangeUser(0.0,2.0);
1424 buchmann 1.1 if(do_bpred_ratio) ratio->GetYaxis()->SetRangeUser(0.0,2.0);
1425     if(extendrange) ratio->GetYaxis()->SetRangeUser(0.0,4.0);
1426     ratio->GetXaxis()->SetTitle(nominator->GetXaxis()->GetTitle());
1427     ratio->GetXaxis()->CenterTitle();
1428     ratio->GetYaxis()->SetTitle(yaxistitle.c_str());
1429     ratio->GetYaxis()->SetTitleOffset(0.4);
1430     ratio->GetYaxis()->CenterTitle();
1431     ratio->SetStats(0);
1432     ratio->GetXaxis()->SetLabelSize(xstretchfactor*ratio->GetXaxis()->GetLabelSize());
1433     ratio->GetYaxis()->SetLabelSize(xstretchfactor*ratio->GetYaxis()->GetLabelSize());
1434     ratio->GetXaxis()->SetTitleSize(xstretchfactor*gStyle->GetTitleSize());
1435     ratio->GetYaxis()->SetTitleSize(xstretchfactor*gStyle->GetTitleSize());
1436     ratio->GetYaxis()->SetNdivisions(502,false);
1437     ratio->SetFillColor(TColor::GetColor("#58D3F7"));
1438     ratio->SetMarkerSize(0);
1439     ratio->Draw("e2");
1440 buchmann 1.28
1441     TGraphAsymmErrors *ratio_center = (TGraphAsymmErrors*)eratio->Clone("ratio_center");
1442     for(int i=0;i<ratio_center->GetN();i++) {
1443     ratio_center->SetPointError(i,ratio_center->GetErrorXlow(i),ratio_center->GetErrorXhigh(i),0.005,0.005);
1444     }
1445    
1446     ratio_center->SetFillColor(TColor::GetColor("#006381"));
1447    
1448 buchmann 1.13 if(syshisto!=0) {
1449     // sysratio->Draw("2");
1450     // eratio->Draw("2,same");
1451     eratio->Draw("2");
1452 buchmann 1.14 SystDown->Draw("histo,same");
1453     SystUp->Draw("histo,same");
1454 buchmann 1.13 } else {
1455     eratio->Draw("2");
1456     }
1457 buchmann 1.28 ratio_center->Draw("2");
1458 buchmann 1.1 ratio->Draw("same,axis");
1459     TLine *oneline = new TLine(ratio->GetXaxis()->GetBinLowEdge(1),1,ratio->GetXaxis()->GetBinLowEdge(ratio->GetNbinsX())+ratio->GetXaxis()->GetBinWidth(ratio->GetNbinsX()),1);
1460     oneline->SetLineStyle(2);
1461     oneline->SetLineColor(kBlue);
1462     oneline->Draw("same");
1463    
1464     main_canvas->cd();
1465     main_canvas->Modified();
1466     main_canvas->cd();
1467     main_canvas->SetSelected(main_canvas);
1468    
1469     CompleteSave(main_canvas,savemeas+"_withratio");
1470     bottompad->cd();
1471    
1472     Double_t chi2;
1473     Int_t ndf,igood;
1474 buchmann 1.7 // Double_t res=0.0;
1475 buchmann 1.1 Double_t chi2prob = MarcosChi2TestX(nominator,denominator,chi2,ndf,igood,"UW");
1476    
1477     stringstream Chi2text;
1478     Chi2text << "#chi^{2} / ndf: " << chi2 << " / " << ndf;
1479     stringstream Chi2probtext;
1480     Chi2probtext << "#chi^{2} prob: " << chi2prob;
1481     TText* chi2box = write_text(0.02,0.11,Chi2text.str());
1482     chi2box->SetTextSize(0.08);
1483     chi2box->SetTextAlign(11);
1484     chi2box->Draw();
1485     TText* chi2probbox = write_text(0.02,0.04,Chi2probtext.str());
1486     chi2probbox->SetTextSize(0.08);
1487     chi2probbox->SetTextAlign(11);
1488     chi2probbox->Draw();
1489 buchmann 1.11
1490     stringstream CompRatio;
1491     CompRatio << "Ratio: " << nominator->Integral() << " / " << denominator->Integral() << " \n " << nominator->Integral()/denominator->Integral();
1492     TText *CompleteRatio = write_text(0.98,0.04,CompRatio.str());
1493     CompleteRatio->SetTextSize(0.08);
1494     CompleteRatio->SetTextAlign(31);
1495     CompleteRatio->Draw();
1496    
1497 buchmann 1.1 CompleteSave(main_canvas,savemeas+"_withratio_and_Chi2");
1498    
1499     // float KS = nominator->KolmogorovTest(denominator);
1500     // stringstream KStext;
1501     // Chi2text << "KS = " << KS << endl;
1502     //cout << "Found : " << KStext.str() << endl;
1503    
1504 buchmann 1.31 delete eratio;
1505     delete ratio_center;
1506     delete ratio;
1507 buchmann 1.1 delete main_canvas;
1508     }
1509    
1510 buchmann 1.32 void save_with_ratio_and_sys_band(TH1F *nominator, TH1F *denominator, TVirtualPad *orig_canvas, string savemeas, bool do_bpred_ratio=false, bool extendrange=false, string yaxistitle="ratio",TH1F *syshisto=NULL) {
1511 buchmann 1.19 //this function saves the pad being passed as well as a new one including the SysRatio.
1512 buchmann 1.32 TVirtualPad *canvas = (TVirtualPad*) orig_canvas->Clone("TempCanvas");//otherwise the main_canvas will own our pad and destroy it upon deletion
1513 buchmann 1.19 CompleteSave(canvas,savemeas);
1514    
1515     float bottommargin=gStyle->GetPadBottomMargin();
1516     float canvas_height=gStyle->GetCanvasDefH();
1517     float canvas_width=gStyle->GetCanvasDefW();
1518 buchmann 1.25 float ratiospace=0.25;// space the ratio should take up (relative to original pad)
1519    
1520     float ratiobottommargin=0.3;
1521     float ratiotopmargin=0.1;
1522 buchmann 1.19
1523 buchmann 1.25 float xstretchfactor=((1-ratiospace)*(1-gStyle->GetPadTopMargin()))/((1)*ratiospace);
1524    
1525     TCanvas *main_canvas = new TCanvas("main_canvas","main_canvas",(Int_t)canvas_width,(Int_t)(canvas_height*(1+ratiospace)));
1526     TPad *mainpad = new TPad("mainpad","mainpad",0,1-(1.0/(1+ratiospace)),1,1);//top (main) pad
1527     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
1528     TPad *bottompad = new TPad("bottompad", "Ratio Pad",0,0,1,(1-(1-bottommargin)/(1+ratiospace))-0.015); //bottom pad
1529 buchmann 1.19
1530 buchmann 1.25 main_canvas->Range(0,0,1,1);
1531     main_canvas->SetBorderSize(0);
1532     main_canvas->SetFrameFillColor(0);
1533 buchmann 1.19
1534 buchmann 1.25 mainpad->Draw();
1535     mainpad->cd();
1536     mainpad->Range(0,0,1,1);
1537     mainpad->SetFillColor(kWhite);
1538     mainpad->SetBorderSize(0);
1539     mainpad->SetFrameFillColor(0);
1540 buchmann 1.19 canvas->Range(0,0,1,1);
1541     canvas->Draw("same");
1542 buchmann 1.25 mainpad->Modified();
1543     main_canvas->cd();
1544     coverpad->Draw();
1545     coverpad->cd();
1546     coverpad->Range(0,0,1,1);
1547     coverpad->SetFillColor(kWhite);
1548     coverpad->SetBorderSize(0);
1549     coverpad->SetFrameFillColor(0);
1550     coverpad->Modified();
1551     main_canvas->cd();
1552     bottompad->SetTopMargin(ratiotopmargin);
1553     bottompad->SetBottomMargin(ratiobottommargin);
1554     bottompad->Draw();
1555     bottompad->cd();
1556     bottompad->Range(0,0,1,1);
1557     bottompad->SetFillColor(kWhite);
1558     TH1F *ratio = (TH1F*)nominator->Clone(GetNumericHistoName().c_str());
1559     ratio->Divide(denominator);
1560 buchmann 1.19
1561    
1562 buchmann 1.25 TGraphAsymmErrors *eratio;
1563     TGraphAsymmErrors *SysEnvelope = new TGraphAsymmErrors();
1564    
1565     if(syshisto && !do_bpred_ratio) {
1566     for(int i=1;i<=syshisto->GetNbinsX();i++) {
1567 buchmann 1.26 float dx=syshisto->GetBinWidth(i)/2.0;
1568     float dy=syshisto->GetBinContent(i);
1569     if(dy<0.01) dy=0.07;
1570 buchmann 1.25 SysEnvelope->SetPoint(i-1,syshisto->GetBinCenter(i),1.0);
1571 buchmann 1.26 SysEnvelope->SetPointError(i-1,dx,dx,dy,dy);
1572 buchmann 1.25 }
1573     SysEnvelope->SetFillColor(TColor::GetColor("#006DE1"));
1574     }
1575 buchmann 1.19
1576 buchmann 1.25 ratio->SetTitle("");
1577     ratio->GetYaxis()->SetRangeUser(0.0,2.0);
1578     if(do_bpred_ratio) ratio->GetYaxis()->SetRangeUser(0.0,2.0);
1579     if(extendrange) ratio->GetYaxis()->SetRangeUser(0.0,4.0);
1580     ratio->GetXaxis()->SetTitle(nominator->GetXaxis()->GetTitle());
1581     ratio->GetXaxis()->CenterTitle();
1582     ratio->GetYaxis()->SetTitle(yaxistitle.c_str());
1583     ratio->GetYaxis()->SetTitleOffset(0.4);
1584     ratio->GetYaxis()->CenterTitle();
1585     ratio->SetStats(0);
1586     ratio->GetXaxis()->SetLabelSize(xstretchfactor*ratio->GetXaxis()->GetLabelSize());
1587     ratio->GetYaxis()->SetLabelSize(xstretchfactor*ratio->GetYaxis()->GetLabelSize());
1588     ratio->GetXaxis()->SetTitleSize(xstretchfactor*gStyle->GetTitleSize());
1589     ratio->GetYaxis()->SetTitleSize(xstretchfactor*gStyle->GetTitleSize());
1590     ratio->GetYaxis()->SetNdivisions(502,false);
1591     ratio->SetFillColor(TColor::GetColor("#58D3F7"));
1592     ratio->Draw("e1");
1593 buchmann 1.19
1594 buchmann 1.25 if(syshisto!=0) {
1595     SysEnvelope->SetFillColor(TColor::GetColor("#FE9A2E"));
1596     SysEnvelope->Draw("2,same");
1597     ratio->Draw("e1,same");
1598     } else {
1599     eratio->Draw("1");
1600     }
1601     ratio->Draw("same,axis");
1602     TLine *oneline = new TLine(ratio->GetXaxis()->GetBinLowEdge(1),1,ratio->GetXaxis()->GetBinLowEdge(ratio->GetNbinsX())+ratio->GetXaxis()->GetBinWidth(ratio->GetNbinsX()),1);
1603 buchmann 1.19 oneline->SetLineStyle(2);
1604     oneline->SetLineColor(kBlue);
1605     oneline->Draw("same");
1606    
1607 buchmann 1.25 main_canvas->cd();
1608     main_canvas->Modified();
1609     main_canvas->cd();
1610     main_canvas->SetSelected(main_canvas);
1611    
1612     CompleteSave(main_canvas,savemeas+"_withSysRatio");
1613     bottompad->cd();
1614    
1615     Double_t chi2;
1616     Int_t ndf,igood;
1617     Double_t chi2prob = MarcosChi2TestX(nominator,denominator,chi2,ndf,igood,"UW");
1618    
1619     stringstream Chi2text;
1620     Chi2text << "#chi^{2} / ndf: " << chi2 << " / " << ndf;
1621     stringstream Chi2probtext;
1622     Chi2probtext << "#chi^{2} prob: " << chi2prob;
1623     TText* chi2box = write_text(0.02,0.11,Chi2text.str());
1624     chi2box->SetTextSize(0.08);
1625     chi2box->SetTextAlign(11);
1626     chi2box->Draw();
1627     TText* chi2probbox = write_text(0.02,0.04,Chi2probtext.str());
1628     chi2probbox->SetTextSize(0.08);
1629     chi2probbox->SetTextAlign(11);
1630     chi2probbox->Draw();
1631    
1632     stringstream CompRatio;
1633     CompRatio << "Ratio: " << nominator->Integral() << " / " << denominator->Integral() << " \n " << nominator->Integral()/denominator->Integral();
1634     TText *CompleteRatio = write_text(0.98,0.04,CompRatio.str());
1635     CompleteRatio->SetTextSize(0.08);
1636     CompleteRatio->SetTextAlign(31);
1637     CompleteRatio->Draw();
1638    
1639     CompleteSave(main_canvas,savemeas+"_withSysRatio_and_Chi2");
1640     delete main_canvas;
1641 buchmann 1.31 delete ratio;
1642 buchmann 1.19 }
1643 buchmann 1.1
1644 buchmann 1.31 TH1F* CollapseStack(THStack stack,TString hname="CollapsedStack") {
1645 buchmann 1.1 TH1F *bhist = ((TH1F*)((stack.GetHists())->At(0)));
1646 fronga 1.22 TH1F *basehisto = (TH1F*)bhist->Clone(hname);
1647 buchmann 1.1 TIter next(stack.GetHists());
1648     TH1F *h;
1649     int counter=0;
1650     while ((h=(TH1F*)next())) {
1651     counter++;
1652     if(counter==1) continue;
1653     basehisto->Add(h);
1654     }
1655     return basehisto;
1656     }
1657    
1658 buchmann 1.32 void Save_With_Ratio(TH1F *nominator, THStack denominator, TVirtualPad *canvas, string savemeas, bool do_bpred_ratio=false) {
1659     TH1F *denominator_histo = (TH1F*) CollapseStack(denominator);
1660     Save_With_Ratio(nominator, denominator_histo, canvas, savemeas, do_bpred_ratio);
1661 buchmann 1.31 delete denominator_histo;
1662 buchmann 1.1 }
1663    
1664     void flag_this_change(string function, int line, int checked=0) {
1665     stringstream peakmodificationwarning;
1666     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 :-) ";
1667     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)";
1668     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.";
1669    
1670    
1671     if(checked==0) write_warning(function,peakmodificationwarning.str());
1672     // if(checked==1) write_info(function,peakmodificationwarning.str());
1673     peakmodificationwarning << " This modification has been checked and the changes have been reproduced. Checks completed.";
1674     if(checked==2) write_info(function,peakmodificationwarning.str());
1675     }
1676    
1677 buchmann 1.8 void write_analysis_type(bool isonpeak, bool dobtag) {
1678 buchmann 1.1 //http://www.network-science.de/ascii/, ogre
1679     if(!PlottingSetup::publicmode) {
1680     if(isonpeak) {
1681 buchmann 1.8 //font: big
1682 buchmann 1.1 dout << "\033[1;34m" << endl;
1683 buchmann 1.8 dout << " _ __________ " << endl;
1684     dout << " | |___ / _ \\ " << endl;
1685     dout << " /\\ ___ | | / /| |_) | " << endl;
1686     dout << " / \\ / _|_ | | / / | _ < " << endl;
1687     dout << " / \\ | (_| |__| |/ /__| |_) | " << endl;
1688     dout << " \\___|\\____//_____|____/ " << endl;
1689 buchmann 1.1 } else {
1690 buchmann 1.8 //font: big
1691 buchmann 1.1 dout << "\033[1;33m" << endl;
1692 buchmann 1.5 dout << " _ _ __________ " << endl;
1693     dout << " (_) | |___ / _ \\ " << endl;
1694     dout << " /\\ _ | | / /| |_) | " << endl;
1695     dout << " /\\/ \\ | |_ | | / / | _ < " << endl;
1696     dout << " / \\ | | |__| |/ /__| |_) | " << endl;
1697     dout << " |_|\\____//_____|____/ " << endl;
1698 buchmann 1.1 }
1699 buchmann 1.8
1700     if(dobtag) {
1701     //font: big
1702     dout << "\033[1;32m \\ / " << endl;
1703     dout << " \\ o ^ o / " << endl;
1704     dout << " \\ ( ) / " << endl;
1705     dout << " ____________(%%%%%%%)____________ _ _ __________ " << endl;
1706     dout << " ( / / )%%%%%%%( \\ \\ ) | | | |___ / _ \\ " << endl;
1707     dout << " (___/___/__/ \\__\\___\\___) | |__ | | / /| |_) | " << endl;
1708     dout << " ( / /(%%%%%%%)\\ \\ ) | '_ \\ _ | | / / | _ < " << endl;
1709     dout << " (__/___/ (%%%%%%%) \\___\\__) | |_) | |__| |/ /__| |_) | " << endl;
1710     dout << " /( )\\ |_.__/ \\____//_____|____/ " << endl;
1711     dout << " / (%%%%%) \\ " << endl;
1712     dout << " (%%%) " << endl;
1713     dout << " ! " << endl;
1714     }
1715     } else {
1716     //we're in public! don't advertise what we're up to :-)
1717     dout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
1718     dout << " Starting the analysis " << endl;
1719 buchmann 1.11 dout << " i:" << !isonpeak << " , b " << dobtag << endl;
1720 buchmann 1.8 dout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
1721 buchmann 1.1 }
1722 buchmann 1.8 dout << "\033[0m" << endl;
1723    
1724 buchmann 1.1 }
1725    
1726    
1727     vector<string> StringSplit(string str, string delim)
1728     {
1729     vector<string> results;
1730    
1731     int cutAt;
1732 buchmann 1.7 while( (cutAt = str.find_first_of(delim)) != (int)str.npos )
1733 buchmann 1.1 {
1734     if(cutAt > 0)
1735     {
1736     results.push_back(str.substr(0,cutAt));
1737     }
1738     str = str.substr(cutAt+1);
1739     }
1740     if(str.length() > 0)
1741     {
1742     results.push_back(str);
1743     }
1744     return results;
1745     }
1746    
1747     void manually_set_jzb_cuts(vector<float> &jzb_cut,string jzbcut_string) {
1748     vector<string> jzbcutvector = StringSplit(jzbcut_string,",");
1749 buchmann 1.7 for(int i=0;i<(int)jzbcutvector.size();i++) {
1750 buchmann 1.1 jzb_cut.push_back(atoi(jzbcutvector[i].c_str()));
1751     dout << "Added a JZB cut manually at " << atoi(jzbcutvector[i].c_str()) << endl;
1752     }
1753     }
1754    
1755     void process_directory(TString directory, vector<string> &files)
1756     {
1757     DIR *dp;
1758     struct dirent *ep;
1759    
1760     dp = opendir (directory);
1761     if (dp != NULL)
1762     {
1763 buchmann 1.7 while ((ep = readdir (dp)))
1764 buchmann 1.1 {
1765     string filename=(string)ep->d_name;
1766 buchmann 1.7 if((int)filename.find(".root")!=-1)
1767 buchmann 1.1 {
1768     files.push_back(string(directory)+filename);
1769     }
1770     }
1771     (void) closedir (dp);
1772     }
1773     else
1774     perror ("Couldn't open the directory");
1775     }
1776    
1777 buchmann 1.14 void ClearHisto(TH1* histo) {
1778 buchmann 1.12 for(int ix=0;ix<=histo->GetNbinsX()+1;ix++) {//also reset over- and underflow
1779     histo->SetBinContent(ix,0);
1780     histo->SetBinContent(ix,0);
1781     }
1782     }
1783    
1784     void AddSquared(TH1F *histo, TH1F *addthis, float weight) {
1785 buchmann 1.14 for(int ix=1;ix<=addthis->GetNbinsX()+1;ix++) {//also include over- and underflow
1786     float bincenter=addthis->GetBinCenter(ix);
1787     int nBinHisto= histo->FindBin(bincenter);
1788     float old_content=histo->GetBinContent(nBinHisto);
1789     histo->SetBinContent(nBinHisto,old_content+((addthis->GetBinContent(ix))*(addthis->GetBinContent(ix))*weight));
1790 buchmann 1.12 }
1791     }
1792    
1793 buchmann 1.14 void SQRT(TH1* histo) {
1794 buchmann 1.12 for(int ix=0;ix<=histo->GetNbinsX()+1;ix++) {//also include over- and underflow
1795     histo->SetBinContent(ix,TMath::Sqrt(histo->GetBinContent(ix)));
1796     }
1797     }
1798    
1799 buchmann 1.1 /*string GetCompleteHostname() {
1800     struct addrinfo hints, *info, *p;
1801     int gai_result;
1802     char hostname[1024];
1803     hostname[1023] = '\0';
1804     gethostname(hostname, 1023);
1805    
1806     string answer="GetCompleteHostname_ERROR";
1807    
1808     memset(&hints, 0, sizeof hints);
1809     hints.ai_family = AF_UNSPEC;
1810     hints.ai_socktype = SOCK_STREAM;
1811     hints.ai_flags = AI_CANONNAME;
1812    
1813     if ((gai_result = getaddrinfo(hostname, "http", &hints, &info)) != 0) {
1814     fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(gai_result));
1815     }
1816    
1817     for(p = info; p != NULL; p = p->ai_next) {
1818     answer=p->ai_canonname;
1819     printf("hostname: %s\n", p->ai_canonname);
1820     }
1821     return answer;
1822     }*/
1823    
1824     const char* concatenate (const char* a, const char* b) {
1825     stringstream bla;
1826     bla << a << b;
1827     return bla.str().c_str();
1828     }
1829    
1830 buchmann 1.8
1831     string ReplaceCharacter(string originalstring,string replacethis,string replacewiththis)
1832     {
1833     int pos = originalstring.find(replacethis);
1834     while(pos != -1) {
1835     originalstring.replace(pos, replacewiththis.length(), replacewiththis);
1836     pos = originalstring.find(replacethis);
1837     }
1838     return originalstring;
1839     }
1840    
1841     string removefunnystring(string name) {
1842     name=ReplaceCharacter(name,"[","_");
1843     name=ReplaceCharacter(name,"]","_");
1844     name=ReplaceCharacter(name,"{","_");
1845     name=ReplaceCharacter(name,"}","_");
1846 buchmann 1.28 name=ReplaceCharacter(name,"(","_");
1847     name=ReplaceCharacter(name,")","_");
1848     name=ReplaceCharacter(name," ","_");
1849 buchmann 1.8 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     name=ReplaceCharacter(name,"+","_");
1858     name=ReplaceCharacter(name,"-","_");
1859     name=ReplaceCharacter(name,"/","_");
1860     return name;
1861     }
1862    
1863 buchmann 1.24 TPolyLine* GetFitUncertaintyShape(TF1 *fit, float low, float high,float x0,float x1) {
1864 buchmann 1.23 int nPoints=1000;
1865     double x[nPoints+1];
1866     double y[nPoints];
1867    
1868     float par1=fit->GetParameter(0);
1869     float dpar1=fit->GetParError(0);
1870     float par2=fit->GetParameter(1);
1871     float dpar2=fit->GetParError(1);
1872    
1873     float step=(x1-x0)/(nPoints/2.0 -1);
1874     for(int i=0;i<nPoints/2.0;i++) {
1875     x[i]=x0+i*step;
1876     y[i]=(par1+x[i]*par2) - sqrt(dpar1*dpar1+dpar2*dpar2*x[i]*x[i]);
1877     x[nPoints-1-i]=x[i];
1878     y[nPoints-1-i]=(par1+x[i]*par2) + sqrt(dpar1*dpar1+dpar2*dpar2*x[i]*x[i]);
1879     if(y[i]<low) y[i]=low;
1880     if(y[i]>high) y[i]=high;
1881     if(y[nPoints-1-i]<low) y[nPoints-1-i]=low;
1882     if(y[nPoints-1-i]>high) y[nPoints-1-i]=high;
1883     }
1884    
1885     x[nPoints]=x[0];
1886     y[nPoints]=y[0];
1887    
1888     TPolyLine *l = new TPolyLine(nPoints+1,x,y);
1889     l->SetFillColor(TColor::GetColor("#5858FA"));
1890 buchmann 1.24 l->SetLineColor(TColor::GetColor("#5858FA"));
1891     l->SetLineWidth(1);
1892 buchmann 1.23 return l;
1893 buchmann 1.24 }
1894    
1895 buchmann 1.27 //code for ReplaceAll copied from
1896     //http://stackoverflow.com/questions/5343190/c-how-do-i-replace-all-instances-of-of-a-string-with-another-string
1897     string ReplaceAll(string str, string from, string to) {
1898     size_t start_pos = 0;
1899     while((start_pos = str.find(from, start_pos)) != std::string::npos) {
1900     str.replace(start_pos, from.length(), to);
1901     start_pos += to.length(); // ...
1902     }
1903     return str;
1904     }
1905 buchmann 1.24
1906     TPolyLine* GetFitUncertaintyShape(TH1 *histo, string fitname, float low, float high) {
1907     TF1 *fit = (TF1*)histo->GetFunction(fitname.c_str());
1908     if(!fit) {
1909     cout << "CANNOT PRODUCE FIT UNCERTAINTY AS THERE IS NO FIT CALLED " << fitname << " IN " << histo->GetName() << endl;
1910     return NULL;
1911     }
1912     float x0=histo->GetBinLowEdge(1);
1913     float x1=histo->GetBinLowEdge(histo->GetNbinsX())+histo->GetBinWidth(histo->GetNbinsX());
1914     return GetFitUncertaintyShape(fit, low, high,x0,x1);
1915     }
1916    
1917     TPolyLine* GetFitUncertaintyShape(TGraphErrors *gr, string fitname, float low, float high, float minx=-999, float maxx=-999) {
1918     TF1 *fit = (TF1*)gr->GetFunction(fitname.c_str());
1919     if(!fit) {
1920     cout << "CANNOT PRODUCE FIT UNCERTAINTY AS THERE IS NO FIT CALLED " << fitname << " IN " << gr->GetName() << endl;
1921     return NULL;
1922     }
1923     double x,y;
1924     gr->GetPoint(0,x,y);
1925     float min=x;
1926     gr->GetPoint(gr->GetN()-1,x,y);
1927     float max=x;
1928     if(minx>-999 && maxx>-999 && minx<maxx) {
1929     max=maxx;
1930     min=minx;
1931     }
1932     return GetFitUncertaintyShape(fit, low, high,min,max);
1933 buchmann 1.23 }
1934    
1935 buchmann 1.1 stringstream all_bugs;
1936    
1937     void bug_tracker(string function, int line, string description) {
1938     cout << "\033[1;31m .-. " << endl;
1939     cout << " o \\ .-. " << endl;
1940     cout << " .----.' \\ " << endl;
1941     cout << " .'o) / `. o " << 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 << " /`.___.'\\ |.`|________| " << endl;
1958     cout << " | /`.__.'|'.` " << endl;
1959     cout << " __/ \\ __/ \\ " << endl;
1960     cout << " /__.-.) /__.-.) LGB " << endl;
1961     cout << "" << endl;
1962     // bug ascii from : http://www.chris.com/ASCII/index.php?art=animals/insects/other
1963     cout << "There is a bug in " << function << " on line " << line << endl;
1964     cout << "The bug description is : " << description << endl;
1965     all_bugs << "There is a bug in " << function << " on line " << line << endl;
1966     all_bugs << "The bug description is : " << description << " \033[0m" << endl;
1967     }
1968    
1969     //TODO: Write a bug summary at the end.
1970    
1971 buchmann 1.2 float pSTAR(float mglu, float mlsp, float mchi2) {
1972 buchmann 1.20 float mz=91.0;
1973 buchmann 1.2 float res=((mchi2*mchi2)-(mlsp+mz)*(mlsp+mz));
1974     res*=((mchi2*mchi2)-(mlsp-mz)*(mlsp-mz));
1975     res=TMath::Sqrt(res)/(2*mchi2);
1976     return res;
1977     }
1978 buchmann 1.3
1979     float generalizedpSTAR(float massmother, float massdaughter1, float massdaughter2) {
1980     float res=((massmother*massmother)-(massdaughter1+massdaughter2)*(massdaughter1+massdaughter2));
1981     res*=((massmother*massmother)-(massdaughter1-massdaughter2)*(massdaughter1-massdaughter2));
1982     res=TMath::Sqrt(res)/(2*massmother);
1983     return res;
1984     }
1985 buchmann 1.24
1986     void FindMinMax(TGraphErrors *gr, float &min, float &max) {
1987     double x,y;
1988     gr->GetPoint(0,x,y);
1989     min=500*y;
1990     max=0.0002*y;
1991     for(int i=0;i<gr->GetN();i++) {
1992     gr->GetPoint(i,x,y);
1993     cout << "Point at " << x << "/" << y << " with error " << gr->GetErrorY(i) << endl;
1994     float potmin=y-1.5*gr->GetErrorY(i); // taking 1.5 times the error to allow for enough space to present the plot
1995     float potmax=y+1.5*gr->GetErrorY(i); // taking 1.5 times the error to allow for enough space to present the plot
1996     if(potmin<min) min=potmin;
1997     if(potmax>max) max=potmax;
1998     }
1999     }
2000 buchmann 1.28
2001    
2002     void CleanLegends() {
2003     for(int ihist=(int)PlottingSetup::FakeHistoHeap.size()-1;ihist>=0;ihist--) {
2004     PlottingSetup::FakeHistoHeap[ihist]->Delete();
2005     PlottingSetup::FakeHistoHeap.pop_back();
2006     }
2007     }