ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.19
Committed: Fri Sep 14 10:19:04 2012 UTC (12 years, 7 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.18: +93 -1 lines
Log Message:
Added function to draw ratio with systematics

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