ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.37
Committed: Mon Apr 8 14:10:34 2013 UTC (12 years ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.36: +3 -3 lines
Log Message:
Adopting our style to agree with Aachen's

File Contents

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