ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.2
Committed: Thu Feb 16 16:04:58 2012 UTC (13 years, 2 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.1: +7 -0 lines
Log Message:
Added p star to general toolbox

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