ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.7
Committed: Mon Apr 30 08:39:09 2012 UTC (13 years ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.6: +26 -24 lines
Log Message:
fixed some uint vs int comparisons; commented out/removed unused variables; made Wall happy

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