ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.33
Committed: Fri Feb 1 11:52:38 2013 UTC (12 years, 3 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.32: +49 -30 lines
Log Message:
Added selection writing function; renamed ratio canvas to avoid conflicts with other main canvases

File Contents

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