ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.25
Committed: Mon Dec 10 16:40:13 2012 UTC (12 years, 4 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.24: +140 -99 lines
Log Message:
Added function permitting ratio with systematic band

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