ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/AnalysisFramework/Plotting/Modules/GeneralToolBox.C
Revision: 1.26
Committed: Thu Aug 25 13:09:38 2011 UTC (13 years, 8 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.25: +32 -40 lines
Log Message:
Adapted legend function so that one can draw a legend without the header; also, the header can now be drawn with a customized luminosity though it defaults to the official luminosity.

File Contents

# User Rev Content
1 buchmann 1.1 #include <iostream>
2 fronga 1.17 #include <iomanip>
3 buchmann 1.1 #include <sstream>
4 buchmann 1.13 #include <fstream>
5 buchmann 1.1 #include <vector>
6     #include <stdio.h>
7     #include <stdlib.h>
8     #include <sys/types.h>
9     #include <sys/stat.h>
10 buchmann 1.15 #include <limits>
11 buchmann 1.1
12     #include <TFile.h>
13     #include <TTree.h>
14     #include <TCut.h>
15     #include <TLegend.h>
16     #include <TLatex.h>
17     #include <TText.h>
18     #include <TGraph.h>
19     #include <TH1.h>
20 buchmann 1.2 #include <TF1.h>
21 buchmann 1.1 #include <TMath.h>
22     #include <TStyle.h>
23     #include <TCanvas.h>
24     #include <TError.h>
25 buchmann 1.3 #include <TVirtualPad.h>
26 buchmann 1.1 #include <TGraphAsymmErrors.h>
27 buchmann 1.7 #include <TPaveText.h>
28 buchmann 1.1 #include <TRandom.h>
29     #ifndef Verbosity
30     #define Verbosity 0
31     #endif
32    
33     /*
34     #ifndef SampleClassLoaded
35     #include "SampleClass.C"
36     #endif
37     */
38     #define GeneralToolBoxLoaded
39    
40     using namespace std;
41    
42     bool dopng=false;
43     bool doC=false;
44     bool doeps=false;
45 buchmann 1.5 bool dopdf=false;
46 buchmann 1.1 string basedirectory="";
47 buchmann 1.26 float generaltoolboxlumi;
48 buchmann 1.1
49 buchmann 1.26 TLegend* make_legend(string title,float posx,float posy, bool drawleg);
50     TText* write_title(bool, string);
51 buchmann 1.1 TText* write_title_low(string title);
52    
53     TText* write_text(float xpos,float ypos,string title);
54     float computeRatioError(float a, float da, float b, float db);
55     float computeProductError(float a, float da, float b, float db);
56     TGraphAsymmErrors *histRatio(TH1F *h1,TH1F *h2, int id, vector<float>binning);
57     void setlumi(float l);
58 buchmann 1.26 void DrawPrelim(float writelumi);
59 buchmann 1.1 void CompleteSave(TCanvas *can, string filename, bool feedback);
60 buchmann 1.3 void CompleteSave(TVirtualPad *can, string filename, bool feedback);
61 buchmann 1.1 void write_warning(string funcname, string text);
62     void write_error(string funcname, string text);
63     void write_info(string funcname, string text);
64 buchmann 1.13 string get_directory();
65 buchmann 1.1 //-------------------------------------------------------------------------------------
66 buchmann 1.13
67 buchmann 1.15 template<typename U>
68     inline bool isanyinf(U value)
69     {
70     return !(value >= std::numeric_limits<U>::min() && value <=
71     std::numeric_limits<U>::max());
72     }
73 buchmann 1.13
74 buchmann 1.1 template<class A>
75     string any2string(const A& a){
76     ostringstream out;
77     out << a;
78     return out.str();
79     }
80    
81     void do_png(bool s) { dopng=s;}
82     void do_eps(bool s) { doeps=s;}
83     void do_C(bool s) { doC=s;}
84 buchmann 1.5 void do_pdf(bool s) { dopdf=s;}
85 buchmann 1.1
86     string topdir(string child) {
87     string tempdirectory=child;
88     if(tempdirectory.substr(tempdirectory.length()-1,1)=="/") tempdirectory=tempdirectory.substr(0,tempdirectory.length());
89     //we now have a directory without the trailing slash so we can just look for the last non-slash character :-)
90     for(int ichar=tempdirectory.length()-1;ichar>=0;ichar--) {
91     if(tempdirectory.substr(ichar,1)=="/") {
92     return tempdirectory.substr(0,ichar);
93     }
94     }
95     }
96    
97 buchmann 1.12 template < typename CHAR_TYPE,
98     typename TRAITS_TYPE = std::char_traits<CHAR_TYPE> >
99    
100     struct basic_teebuf : public std::basic_streambuf< CHAR_TYPE, TRAITS_TYPE >
101     {
102     typedef std::basic_streambuf< CHAR_TYPE, TRAITS_TYPE > streambuf_type ;
103     typedef typename TRAITS_TYPE::int_type int_type ;
104    
105     basic_teebuf( streambuf_type* buff_a, streambuf_type* buff_b )
106     : first(buff_a), second(buff_b) {}
107    
108     protected:
109     virtual int_type overflow( int_type c )
110     {
111     const int_type eof = TRAITS_TYPE::eof() ;
112     if( TRAITS_TYPE::eq_int_type( c, eof ) )
113     return TRAITS_TYPE::not_eof(c) ;
114     else
115     {
116     const CHAR_TYPE ch = TRAITS_TYPE::to_char_type(c) ;
117     if( TRAITS_TYPE::eq_int_type( first->sputc(ch), eof ) ||
118     TRAITS_TYPE::eq_int_type( second->sputc(ch), eof ) )
119     return eof ;
120     else return c ;
121     }
122     }
123    
124     virtual int sync()
125     { return !first->pubsync() && !second->pubsync() ? 0 : -1 ; }
126    
127     private:
128     streambuf_type* first ;
129     streambuf_type* second ;
130     };
131    
132     template < typename CHAR_TYPE,
133     typename TRAITS_TYPE = std::char_traits<CHAR_TYPE> >
134     struct basic_teestream : public std::basic_ostream< CHAR_TYPE, TRAITS_TYPE >
135     {
136     typedef std::basic_ostream< CHAR_TYPE, TRAITS_TYPE > stream_type ;
137     typedef basic_teebuf< CHAR_TYPE, TRAITS_TYPE > streambuff_type ;
138    
139     basic_teestream( stream_type& first, stream_type& second )
140     : stream_type( &stmbuf), stmbuf( first.rdbuf(), second.rdbuf() ) {}
141    
142     ~basic_teestream() { stmbuf.pubsync() ; }
143    
144     private: streambuff_type stmbuf ;
145     };
146    
147     typedef basic_teebuf<char> teebuf ;
148     typedef basic_teestream<char> teestream ;
149    
150 buchmann 1.13 std::ofstream file("LOG.txt",ios::app) ;
151 buchmann 1.14 std::ofstream efile("LOGerr.txt",ios::app) ;
152 buchmann 1.13 teestream dout( file, std::cout ) ; // double out
153     teestream eout( efile, std::cout ) ; // double out (errors)
154 buchmann 1.12
155 buchmann 1.1 void ensure_directory_exists(string thisdirectory) {
156     struct stat st;
157     if(stat(thisdirectory.c_str(),&st) == 0) {
158 buchmann 1.13 if(Verbosity>0) dout << "Directory " << thisdirectory << " exists!" << endl;
159 buchmann 1.1 }
160     else {
161 buchmann 1.13 if(Verbosity>0) dout << "Directory " << thisdirectory << " does not exist. Need to create it!" << endl;
162 buchmann 1.1 ensure_directory_exists(topdir(thisdirectory));
163     if (mkdir(thisdirectory.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH))
164 buchmann 1.13 if(Verbosity>0) dout << "Created the directory " << thisdirectory << endl;
165 buchmann 1.1 }
166     }
167    
168 buchmann 1.13 void initialize_log() {
169 buchmann 1.14 dout << "____________________________________________________________" << endl;
170     dout << endl;
171 buchmann 1.13 dout << " " << endl;
172     dout << " JJJJJJJJJJJZZZZZZZZZZZZZZZZZZZBBBBBBBBBBBBBBBBB " << endl;
173     dout << " J:::::::::JZ:::::::::::::::::ZB::::::::::::::::B " << endl;
174     dout << " J:::::::::JZ:::::::::::::::::ZB::::::BBBBBB:::::B " << endl;
175     dout << " JJ:::::::JJZ:::ZZZZZZZZ:::::Z BB:::::B B:::::B" << endl;
176     dout << " J:::::J ZZZZZ Z:::::Z B::::B B:::::B" << endl;
177     dout << " J:::::J Z:::::Z B::::B B:::::B" << endl;
178     dout << " J:::::J Z:::::Z B::::BBBBBB:::::B " << endl;
179     dout << " J:::::j Z:::::Z B:::::::::::::BB " << endl;
180     dout << " J:::::J Z:::::Z B::::BBBBBB:::::B " << endl;
181     dout << "JJJJJJJ J:::::J Z:::::Z B::::B B:::::B" << endl;
182     dout << "J:::::J J:::::J Z:::::Z B::::B B:::::B" << endl;
183     dout << "J::::::J J::::::J ZZZ:::::Z ZZZZZ B::::B B:::::B" << endl;
184     dout << "J:::::::JJJ:::::::J Z::::::ZZZZZZZZ:::ZBB:::::BBBBBB::::::B" << endl;
185     dout << " JJ:::::::::::::JJ Z:::::::::::::::::ZB:::::::::::::::::B " << endl;
186     dout << " JJ:::::::::JJ Z:::::::::::::::::ZB::::::::::::::::B " << endl;
187     dout << " JJJJJJJJJ ZZZZZZZZZZZZZZZZZZZBBBBBBBBBBBBBBBBB " << endl;
188     dout << " " << endl;
189     dout << endl << endl;
190     dout << "____________________________________________________________" << endl;
191     time_t rawtime;
192     struct tm * timeinfo;
193     time ( &rawtime );
194     dout << " Analysis run on " << asctime (localtime ( &rawtime ));
195     dout << "____________________________________________________________" << endl;
196     dout << " Results saved in : " << get_directory() << endl << endl;
197     }
198    
199 buchmann 1.1 void set_directory(string basedir="") {
200     if(basedir.substr(0,1)=="/") basedir=basedir.substr(1,basedir.length()-1);
201     if(basedir.substr(basedir.length()-1,1)!="/") basedir+="/";
202     char currentpath[1024];
203     getcwd(currentpath,1024);
204 buchmann 1.20 basedirectory=(string)currentpath+"/Plots/"+basedir;
205 buchmann 1.1 ensure_directory_exists(basedirectory);
206 buchmann 1.13 initialize_log();
207 buchmann 1.1 }
208    
209 buchmann 1.6 string get_directory() {
210     return basedirectory;
211     }
212    
213 buchmann 1.1 string extract_directory(string savethis) {
214     bool foundslash=false;
215     int position=savethis.length();
216     while(!foundslash&&position>0) {
217     position--;
218     if(savethis.substr(position,1)=="/") foundslash=true;
219     }
220     if(position>0) return savethis.substr(0,position+1);
221     else return "";
222     }
223    
224 fronga 1.18 void CompleteSave(TCanvas *can, string filename, bool feedback=false, bool redraw=true) {
225 buchmann 1.3 //any change you make here should also be done below in the CompleteSave function for virtual pads
226 buchmann 1.1 Int_t currlevel=gErrorIgnoreLevel;
227     if(!feedback) gErrorIgnoreLevel=1001;
228 fronga 1.18 if(redraw) can->RedrawAxis();
229 buchmann 1.1 ensure_directory_exists(extract_directory(basedirectory+filename));
230     if(dopng) can->SaveAs((basedirectory+filename+".png").c_str());
231     if(doeps) can->SaveAs((basedirectory+filename+".eps").c_str());
232 buchmann 1.5 if(dopdf) can->SaveAs((basedirectory+filename+".pdf").c_str());
233 buchmann 1.1 if(doC) can->SaveAs((basedirectory+filename+".C").c_str());
234     gErrorIgnoreLevel=currlevel;
235 buchmann 1.13 dout << "Saved " << filename << " in all requested formats" << endl;
236 buchmann 1.1 }
237 buchmann 1.3
238 fronga 1.18 void CompleteSave(TVirtualPad *can, string filename, bool feedback=false, bool redraw=true) {
239 buchmann 1.3 Int_t currlevel=gErrorIgnoreLevel;
240     if(!feedback) gErrorIgnoreLevel=1001;
241 fronga 1.18 if(redraw) can->RedrawAxis();
242 buchmann 1.3 ensure_directory_exists(extract_directory(basedirectory+filename));
243     if(dopng) can->SaveAs((basedirectory+filename+".png").c_str());
244     if(doeps) can->SaveAs((basedirectory+filename+".eps").c_str());
245     if(doC) can->SaveAs((basedirectory+filename+".C").c_str());
246     gErrorIgnoreLevel=currlevel;
247 buchmann 1.13 dout << "Saved " << filename << " in all requested formats" << endl;
248 buchmann 1.3 }
249    
250 buchmann 1.1
251     void setlumi(float l) {
252 buchmann 1.24 generaltoolboxlumi=l;
253 buchmann 1.1 }
254    
255     int write_first_line(vector<vector<string> > &entries) {
256     if(entries.size()>0) {
257     vector<string> firstline = entries[0];
258     int ncolumns=firstline.size();
259     int ndividers=ncolumns+1;
260     int cellwidth=(int)(((float)(60-ndividers))/(ncolumns));
261 buchmann 1.13 dout << " |";
262 buchmann 1.1 for(int idiv=0;idiv<ncolumns;idiv++) {
263 buchmann 1.13 for(int isig=0;isig<cellwidth;isig++) dout << "-";
264     dout << "|";
265 buchmann 1.1 }
266 buchmann 1.13 dout << endl;
267 buchmann 1.1 return ncolumns;
268     } else {
269     return 0;
270     }
271     }
272    
273     void write_entry(string entry,int width,int iline=0,int ientry=0) {
274     int currwidth=entry.size();
275     while(currwidth<width) {
276     entry=" "+entry;
277     if(entry.size()<width) entry=entry+" ";
278     currwidth=entry.size();
279     }
280     bool do_special=false;
281 buchmann 1.13 if(iline==1&&ientry==1) { dout << "\033[1;32m" << entry << "\033[0m|";do_special=true;}//observed
282     if(iline==1&&ientry==2) { dout << "\033[1;34m" << entry << "\033[0m|";do_special=true;}//predicted (1)
283     if(iline==2&&ientry==1) { dout << "\033[1;34m" << entry << "\033[0m|";do_special=true;}//predicted (1)
284     if(iline==2&&ientry==2) { dout << "\033[1;34m" << entry << "\033[0m|";do_special=true;}//predicted (1)
285     if(!do_special) dout << entry << "|";
286 buchmann 1.1 }
287    
288     void make_nice_table(vector<vector <string> > &entries) {
289     int ncolumns=write_first_line(entries);
290     int cellwidth=(int)(((float)(60-(ncolumns+1)))/(ncolumns));
291     for(int iline=0;iline<entries.size();iline++) {
292     vector<string> currline = entries[iline];
293 buchmann 1.13 dout << " |";
294 buchmann 1.1 for(int ientry=0;ientry<currline.size();ientry++) {
295     write_entry(currline[ientry],cellwidth);
296     }
297 buchmann 1.13 dout << endl;
298 buchmann 1.1 if(iline==0) write_first_line(entries);
299     }
300     write_first_line(entries);
301     }
302    
303     void make_nice_jzb_table(vector<vector <string> > &entries) {
304     int ncolumns=write_first_line(entries);
305     int cellwidth=(int)(((float)(60-(ncolumns+1)))/(ncolumns));
306     for(int iline=0;iline<entries.size();iline++) {
307     vector<string> currline = entries[iline];
308 buchmann 1.13 dout << " |";
309 buchmann 1.1 for(int ientry=0;ientry<currline.size();ientry++) {
310     write_entry(currline[ientry],cellwidth,iline,ientry);
311     }
312 buchmann 1.13 dout << endl;
313 buchmann 1.1 if(iline==0) write_first_line(entries);
314     }
315     write_first_line(entries);
316     }
317    
318    
319     void write_warning(string funcname, string text) {
320 buchmann 1.13 eout << endl << endl;
321     eout << "\033[1;33m" << " _ " << endl;
322     eout << "\033[1;33m" << " (_) " << endl;
323     eout << "\033[1;33m" << "__ ____ _ _ __ _ __ _ _ __ __ _ " << endl;
324     eout << "\033[1;33m" << "\\ \\ /\\ / / _` | '__| '_ \\| | '_ \\ / _` |" << endl;
325     eout << "\033[1;33m" << " \\ V V / (_| | | | | | | | | | | (_| |" << endl;
326     eout << "\033[1;33m" << " \\_/\\_/ \\__,_|_| |_| |_|_|_| |_|\\__, |" << endl;
327     eout << "\033[1;33m" << " __/ |" << endl;
328     eout << "\033[1;33m" << " |___/ " << endl;
329     eout << endl;
330     eout << "\033[1;33m [" << funcname << "] " << text << " \033[0m" << endl;
331     eout << endl << endl;
332 buchmann 1.1 }
333     void write_error(string funcname, string text) {
334 buchmann 1.13 eout << endl << endl;
335     eout << "\033[1;31m ___ _ __ _ __ ___ _ __ " << endl;
336     eout << "\033[1;31m / _ \\ __| __/ _ \\| '__|" << endl;
337     eout << "\033[1;31m| __/ | | | | (_) | | " << endl;
338     eout << "\033[1;31m \\___|_| |_| \\___/|_| " << endl;
339     eout << endl;
340     eout << "\033[1;31m [" << funcname << "] " << text << " \033[0m" << endl;
341     eout << endl << endl;
342 buchmann 1.1 }
343    
344     void write_info(string funcname, string text) {
345 buchmann 1.13 dout << endl << endl;
346     dout << "\033[1;34m _____ __ " << endl;
347     dout << "\033[1;34m |_ _| / _| " << endl;
348     dout << "\033[1;34m | | _ __ | |_ ___ " << endl;
349     dout << "\033[1;34m | | | '_ \\| _/ _ \\ " << endl;
350     dout << "\033[1;34m _| |_| | | | || (_) | " << endl;
351     dout << "\033[1;34m |_____|_| |_|_| \\___/ " << endl;
352     dout << endl;
353     dout << "\033[1;34m [" << funcname << "] " << text << " \033[0m" << endl;
354     dout << endl << endl;
355 buchmann 1.1 }
356    
357     TText* write_text(float xpos,float ypos,string title)
358     {
359     TLatex* titlebox = new TLatex (xpos,ypos,title.c_str());
360     titlebox->SetNDC(true);
361     titlebox->SetTextFont(42);
362     titlebox->SetTextSize(0.04);
363     titlebox->SetTextAlign(21);
364     return titlebox;
365     }
366    
367     TText* write_title(string title)
368     {
369 buchmann 1.15 TText* titlebox = write_text(0.5,0.945,title);
370 buchmann 1.1 return titlebox;
371     }
372    
373 buchmann 1.7 TText* write_cut_on_canvas(string cut) {
374     // TLatex *normbox = new TLatex(0.96,0.5,cut.c_str());
375     TLatex *normbox = new TLatex(0.96,0.5,"");//currently deactivated
376     normbox->SetNDC(true);
377     normbox->SetTextFont(42);
378     normbox->SetTextSize(0.01);
379     normbox->SetTextAlign(21);
380     normbox->SetTextAngle(270);
381     return normbox;
382     }
383    
384 buchmann 1.1 TText* write_title_low(string title)
385     {
386     TText* titlebox = write_text(0.5,0.94,title);
387     return titlebox;
388     }
389    
390 buchmann 1.26 void DrawPrelim(float writelumi=generaltoolboxlumi) {
391     string barn="pb";
392     if(writelumi>=1000)
393     {
394     writelumi/=1000;
395     barn="fb";
396     }
397    
398     stringstream prelimtext;
399     //prelimtext << "CMS Preliminary 2011 , #sqrt{s}= 7 TeV, L= O(1) fb^{-1}"; //temporary replacement
400     prelimtext << "CMS Preliminary 2011 , #sqrt{s}= 7 TeV, L= "
401     << std::setprecision(2) <<writelumi<<" "<<barn<<"^{-1}";
402     TPaveText *eventSelectionPaveText = new TPaveText(0.27, 0.93,0.77, 1.0,"blNDC");
403     eventSelectionPaveText->SetFillStyle(4000);
404     eventSelectionPaveText->SetBorderSize(0.1);
405     eventSelectionPaveText->SetFillColor(kWhite);
406     eventSelectionPaveText->SetTextFont(42);
407     eventSelectionPaveText->SetTextSize(0.042);
408     eventSelectionPaveText->AddText(prelimtext.str().c_str());
409     eventSelectionPaveText->Draw();
410     }
411    
412     TLegend* make_legend(string title="", float posx=0.6, float posy=0.55, bool drawleg=true)
413 buchmann 1.1 {
414     // TLegend *leg = new TLegend(0.65,0.65,0.89,0.89);
415     gStyle->SetTextFont(42);
416 buchmann 1.7 TLegend *leg = new TLegend(posx,posy,0.89,0.89);
417 buchmann 1.1 if(title!="") leg->SetHeader(title.c_str());
418     leg->SetTextFont(42);
419 fronga 1.17 leg->SetTextSize(0.04);
420 buchmann 1.1 leg->SetFillColor(kWhite);
421     leg->SetBorderSize(0);
422     leg->SetLineColor(kWhite);
423 buchmann 1.26 if(drawleg) DrawPrelim();
424 buchmann 1.5 /* TText *writeline1 = write_text(0.77,0.87,"CMS Preliminary 2011");
425 buchmann 1.1 stringstream lumitext;
426 buchmann 1.5 lumitext<<"#sqrt{s}=7, L = "<<lumi<<" pb^{-1}";
427 buchmann 1.1 TText *writeline2 = write_text(0.77,0.83,lumitext.str().c_str());
428     writeline1->SetTextSize(0.03);
429     writeline2->SetTextSize(0.03);
430     writeline1->Draw();
431     writeline2->Draw();
432 buchmann 1.5 */
433 buchmann 1.1 return leg;
434     }
435    
436 buchmann 1.26 TLegend* make_legend(bool drawleg, string title) {
437     return make_legend(title,0.6,0.55,drawleg);
438     }
439    
440 buchmann 1.1 TGraph* make_nice_ratio(int nbins,float binning[],TH1F* histo)
441     {
442     float errorsquared[nbins];
443     float errors[nbins];
444     float bincontent[nbins];
445     for (int i=0;i<nbins;i++) {
446     errorsquared[i]=0;
447     bincontent[i]=0;
448     errors[i]=0;
449     }
450     float currlimit=binning[0];
451     int currtoplim=1;
452     for(int ibin=1;ibin<=histo->GetNbinsX();ibin++)
453     {
454     if(binning[currtoplim]<histo->GetBinCenter(ibin)) currtoplim++;
455 buchmann 1.13 dout << "Bin i=" << ibin << " with bin center " << histo->GetBinCenter(ibin) << " contains " << histo->GetBinContent(ibin) << " is within " << binning[currtoplim-1] << " and " << binning[currtoplim] << endl;
456 buchmann 1.1
457     }
458    
459     return 0;
460     }
461    
462     float statErrorN(float x){return x - 0.5*TMath::ChisquareQuantile(0.3173/2,2*x);}
463     float statErrorP(float x){return 0.5*TMath::ChisquareQuantile(1-0.3173/2,2*(x+1))-x;}
464     float lowLimit(float a, float x){return 0.5*TMath::ChisquareQuantile(a,2*x);}
465     float highLimit(float a,float x){return 0.5*TMath::ChisquareQuantile(1-a,2*(x+1));}
466    
467     float computeRatioError(float a, float da, float b, float db)
468     {
469     float val=0.;
470     float errorSquare = (a/b)*(a/b)*( (da/a)*(da/a) + (db/b)*(db/b));
471     val = TMath::Sqrt(errorSquare);
472     return val;
473    
474     }
475     float computeProductError(float a, float da, float b, float db)
476     {
477     float val=0.;
478     float errorSquare = (a*b)*(a*b)*( (da/a)*(da/a) + (db/b)*(db/b));
479     val = TMath::Sqrt(errorSquare);
480     return val;
481     }
482    
483 buchmann 1.23 TGraphAsymmErrors *histRatio(TH1F *h1,TH1F *h2, int id, vector<float>binning, bool precise=false)
484 buchmann 1.1 {
485     int absJZBbinsNumber = binning.size()-1;
486     TGraphAsymmErrors* graph = new TGraphAsymmErrors(absJZBbinsNumber);
487    
488     for(unsigned int i=0;i<absJZBbinsNumber;i++)
489     {
490     float xCenter=h1->GetBinCenter(i+1);
491     float xWidth=(h1->GetBinWidth(i+1))*0.5;
492     float nominatorError = h1->GetBinError(i+1);
493     float nominator=h1->GetBinContent(i+1);
494     float denominatorError=h2->GetBinError(i+1);
495     float denominator=h2->GetBinContent(i+1);
496     float errorN = 0;
497     float errorP = computeRatioError(nominator,nominatorError,denominator,denominatorError);
498     if(id==1) // (is data)
499     {
500 buchmann 1.23 if(!precise) errorP = computeRatioError(nominator,statErrorP(nominator),denominator,statErrorP(denominator));
501     else errorP = computeRatioError(nominator,nominatorError,denominator,denominatorError);
502 buchmann 1.1 errorN = errorP; // symmetrize using statErrorP
503     } else {
504     errorN = computeRatioError(nominator,nominatorError,denominator,denominatorError);
505 buchmann 1.23 errorP = errorN;
506 buchmann 1.1 }
507     if(denominator!=0) {
508     graph->SetPoint(i, xCenter, nominator/denominator);
509     graph->SetPointError(i,xWidth,xWidth,errorN,errorP);
510     }
511     else {
512     graph->SetPoint(i, xCenter, -999);
513     graph->SetPointError(i,xWidth,xWidth,errorN,errorP);
514     }
515     }
516     return graph;
517     }
518    
519     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!
520     float uperr=0,downerr=0;
521     if(down>up&&down>cent) uperr=down-cent;
522     if(up>down&&up>cent) uperr=up-cent;
523     if(down<cent&&down<up) downerr=cent-down;
524     if(up<cent&&up<down) downerr=cent-up;
525     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!");
526     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!");
527     stringstream result;
528     result << cent << " + " << uperr << " - " << downerr;
529     return result.str();
530     }
531    
532     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")
533     {
534     int last = size - 2;
535     int isChanged = 1;
536    
537     while ( last >= 0 && isChanged )
538     {
539     isChanged = 0;
540     for ( int k = 0; k <= last; k++ )
541     if ( arr[k] > arr[k+1] )
542     {
543     swap ( arr[k], arr[k+1] );
544     isChanged = 1;
545     int bkp=order[k];
546     order[k]=order[k+1];
547     order[k+1]=bkp;
548     }
549     last--;
550     }
551     }
552    
553     void swapvec(vector<float> &vec,int j, int k) {
554     float bkp=vec[j];
555     vec[j]=vec[k];
556     vec[k]=bkp;
557     }
558    
559     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")
560     {
561     int last = arr.size() - 2;
562     int isChanged = 1;
563    
564     while ( last >= 0 && isChanged )
565     {
566     isChanged = 0;
567     for ( int k = 0; k <= last; k++ )
568     if ( arr[k] > arr[k+1] )
569     {
570     swapvec (arr,k,k+1);
571     isChanged = 1;
572     int bkp=order[k];
573     order[k]=order[k+1];
574     order[k+1]=bkp;
575     }
576     last--;
577     }
578     }
579    
580     int numerichistoname=0;
581 buchmann 1.16 bool givingnumber=false;
582 buchmann 1.1 string GetNumericHistoName() {
583 buchmann 1.16 while(givingnumber) sleep(1);
584     givingnumber=true;
585 buchmann 1.1 stringstream b;
586     b << "h_" << numerichistoname;
587     numerichistoname++;
588 buchmann 1.16 givingnumber=false;
589 buchmann 1.1 return b.str();
590     }
591    
592     //********************** BELOW : CUT INTERPRETATION **************************//
593     void splitupcut(string incut, vector<string> &partvector)
594     {
595     //idea: go thru the string called incut; if a parantheses is opened, then the cut cannot be split up until the parantheses is closed.
596     //ok anyway screw the parantheses.
597     int paranthesis_open=0;
598     int substr_start=0;
599     string currchar="";
600     for (int ichar=0;ichar<incut.length();ichar++)
601     {
602     currchar=incut.substr(ichar,1);
603     // if(currchar=="(") paranthesis_open++;
604     // if(currchar==")") paranthesis_open--;
605     if(currchar=="&"&&incut.substr(ichar+1,1)=="&"&&paranthesis_open==0) {
606     partvector.push_back(incut.substr(substr_start,ichar-substr_start));
607     substr_start=ichar+2;
608     }
609     }
610     partvector.push_back(incut.substr(substr_start,incut.length()-substr_start));
611     if(Verbosity>1) {
612 buchmann 1.13 dout << "[ splitupcut() ] : The cut vector now contains the following elements: "<< endl;
613 buchmann 1.1 for (int ipart=0;ipart<partvector.size();ipart++)
614     {
615 buchmann 1.13 dout << " - " << partvector[ipart] << endl;
616 buchmann 1.1 }
617     }
618     }
619    
620     int atleastvalue(string expression, int &morethanlessthan) // takes in an expression such as ">2" or ">=3" and returns e.g. 3 (in both examples)
621     {
622     int retval=0;
623     if(expression.substr(0,1)==">"&&expression.substr(1,1)=="=") {
624 buchmann 1.13 // dout << "The expression " << expression << " is saying that we have at least " << atoi(expression.substr(2,1).c_str()) << " jets" << endl;
625 buchmann 1.1 morethanlessthan=1;
626     return atoi(expression.substr(2,1).c_str());
627     }
628     if(expression.substr(0,1)=="="&&expression.substr(1,1)=="=") {
629 buchmann 1.13 // dout << "The expression " << expression << " is saying that we have at least " << atoi(expression.substr(1,1).c_str())+1 << " jets" << endl;
630 buchmann 1.1 morethanlessthan=0;
631     return atoi(expression.substr(1,1).c_str());
632     }
633     if(expression.substr(0,1)=="<"&&expression.substr(1,1)=="=") {
634 buchmann 1.13 // dout << "The expression " << expression << " is saying that we have at least " << atoi(expression.substr(1,1).c_str())+1 << " jets" << endl;
635 buchmann 1.1 morethanlessthan=-1;
636     return 1+atoi(expression.substr(1,1).c_str());
637     }
638     if(expression.substr(0,1)==">") {
639 buchmann 1.13 // dout << "The expression " << expression << " is saying that we have at least " << atoi(expression.substr(2,1).c_str()) << " jets" << endl;
640 buchmann 1.1 morethanlessthan=1;
641     return 1+atoi(expression.substr(2,1).c_str());
642     }
643     if(expression.substr(0,1)=="<"&&expression.substr(1,1)=="=") {
644 buchmann 1.13 // dout << "The expression " << expression << " is saying that we have at least " << atoi(expression.substr(2,1).c_str()) << " jets" << endl;
645 buchmann 1.1 morethanlessthan=-1;
646     return 1+atoi(expression.substr(2,1).c_str());
647     }
648     }
649    
650     int do_jet_cut(string incut, int *nJets) {
651     string expression=(incut.substr(12,incut.size()-12));
652 buchmann 1.13 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;
653 buchmann 1.1 if(expression.substr(0,1)=="<"&&expression.substr(1,1)=="=") {
654     int nJet=atoi(expression.substr(2,1).c_str());
655     for(int i=nJet+1;i<20;i++) nJets[i]=0;
656 buchmann 1.13 dout << "Is of type <=" << endl;
657 buchmann 1.1 return 0;
658     }
659     if(expression.substr(0,1)=="="&&expression.substr(1,1)=="=") {
660     int nJet=atoi(expression.substr(2,1).c_str());
661     for(int i=0;i<20&&i!=nJet;i++) nJets[i]=0;
662 buchmann 1.13 dout << "Is of type ==" << endl;
663 buchmann 1.1 return 0;
664     }
665     if(expression.substr(0,1)==">"&&expression.substr(1,1)=="=") {
666     int nJet=atoi(expression.substr(2,1).c_str());
667     for(int i=0;i<nJet&&i!=nJet;i++) nJets[i]=0;
668 buchmann 1.13 dout << "Is of type >=" << endl;
669 buchmann 1.1 return 0;
670     }
671     if(expression.substr(0,1)=="<") {
672     int nJet=atoi(expression.substr(1,1).c_str());
673     for(int i=nJet;i<20;i++) nJets[i]=0;
674 buchmann 1.13 dout << "Is of type <" << endl;
675 buchmann 1.1 return 0;
676     }
677     if(expression.substr(0,1)==">") {
678     int nJet=atoi(expression.substr(1,1).c_str());
679     for(int i=0;i<nJet+1&&i!=nJet;i++) nJets[i]=0;
680 buchmann 1.13 dout << "Is of type >" << endl;
681 buchmann 1.1 return 0;
682     }
683     }
684    
685     string interpret_cut(string incut, bool &isJetCut, int *permittednJets)
686     {
687     // isJetCut=false;nJets=-1;
688     if(incut=="()") return "";
689     while(incut.substr(0,1)=="(") incut=incut.substr(1,incut.length()-1);
690     while(incut.length()>0&&incut.substr(incut.length()-1,1)==")") incut=incut.substr(0,incut.length()-1);
691     // 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.
692    
693     if(Verbosity>0) {
694 buchmann 1.13 dout << "Now interpreting cut " << incut << endl;
695 buchmann 1.1 }
696     /*
697     if(incut=="ch1*ch2<0") return "OS";
698     if(incut=="id1==id2") return "SF";
699     if(incut=="id1!=id2") return "OF";
700     */
701     if(incut=="ch1*ch2<0") return "";
702 buchmann 1.5 if(incut=="(mll>55&&mll<70)||(mll>112&&mll<160)") return "SB";
703     if(incut=="(mll>61&&mll<70)||(mll>112&&mll<190)") return "SB'";
704 buchmann 1.1 if(incut=="id1==id2") return "";
705     if(incut=="id1!=id2") return "";
706     if(incut=="mll>2") return "";
707    
708     if(incut=="mll>0") return ""; // my typical "fake cut"
709    
710     if(incut=="passed_triggers||!is_data") return "Triggers";
711     if(incut=="pfjzb[0]>-998") return "";
712    
713    
714     if(incut=="id1==0") return "ee";
715     if(incut=="id1==1") return "#mu#mu";
716     if(incut=="abs(mll-91.2)<20") return "|m_{l^{+}l^{-}}-m_{Z}|<20";
717     if(incut=="pfJetGoodID[0]") return "";
718     if(incut=="pfJetGoodID[1]") return "";
719     if((int)incut.find("pfJetGoodNum")>-1) {
720     //do_jet_cut(incut,permittednJets);
721     stringstream result;
722     result << "nJets" << incut.substr(12,incut.size()-12);
723 buchmann 1.13 /* dout << "Dealing with a jet cut: " << incut << endl;
724 buchmann 1.1 stringstream result;
725     result << "nJets" << incut.substr(12,incut.size()-12);
726     isJetCut=true;
727     if(exactjetcut(incut,nJets))
728     // nJets=atleastvalue((incut.substr(12,incut.size()-12)),morethanlessthan);
729     return result.str();*/
730     return result.str();
731     }
732     return incut;
733     }
734    
735     string interpret_nJet_range(int *nJets) {
736 buchmann 1.13 for (int i=0;i<20;i++) dout << i << " : " << nJets[i] << endl;
737 buchmann 1.1 return "hello";
738     }
739    
740     string interpret_cuts(vector<string> &cutparts)
741     {
742     stringstream nicecut;
743     int nJets;
744     bool isJetCut;
745     int finalJetCut=-1;
746     int permittednJets[20];
747     for(int ijet=0;ijet<20;ijet++) permittednJets[ijet]=1;
748     int morethanlessthan=0;//-1: less than, 0: exactly, 1: more than
749     for(int icut=0;icut<cutparts.size();icut++)
750     {
751     if(icut==0) nicecut<<interpret_cut(cutparts[icut],isJetCut,permittednJets);
752     else {
753     string nice_this_cut = interpret_cut(cutparts[icut],isJetCut,permittednJets);//blublu
754     if(nice_this_cut.length()>0&&nicecut.str().length()>0) {
755     if(!isJetCut) nicecut<<"&&"<<nice_this_cut;
756     else {
757     if(nJets>finalJetCut) finalJetCut=nJets;
758     }
759     }
760     if(nice_this_cut.length()>0&&nicecut.str().length()==0) {
761     if(!isJetCut) {
762     nicecut<<nice_this_cut;
763     }
764     else {
765     if(nJets>finalJetCut) finalJetCut=nJets;
766     }
767     }
768     }
769     }
770     if(finalJetCut>-1) {
771     if(nicecut.str().length()==0) {
772     nicecut << "nJets#geq" << finalJetCut;
773     }
774     else
775     {
776     nicecut << "&&nJets#geq " << finalJetCut;
777     }
778     }
779    
780 buchmann 1.13 // dout << "The nJet allowed range is given by: " << interpret_nJet_range(permittednJets) << endl;
781 buchmann 1.1
782     return nicecut.str();
783     }
784    
785     string decipher_cut(TCut originalcut,TCut ignorethispart)
786     {
787     string incut=(const char*)originalcut;
788     string ignore=(const char*)ignorethispart;
789    
790     if(ignore.length()>0 && incut.find(ignore)!=string::npos) incut=incut.replace(incut.find(ignore),ignore.length(),"");
791    
792     vector<string>cutparts;
793     splitupcut(incut,cutparts);
794     string write_cut=interpret_cuts(cutparts);
795     return write_cut;
796     }
797    
798     //********************** ABOVE : CUT INTERPRETATION **************************//
799 buchmann 1.2
800     Double_t GausRandom(Double_t mu, Double_t sigma) {
801     return gRandom->Gaus(mu,sigma);// real deal
802     //return mu;//debugging : no smearing.
803     }
804    
805 buchmann 1.3 int functionalhistocounter=0;
806 buchmann 1.2 TH1F * makehistofromfunction(TF1 *f1,TH1F *model) {
807     TH1F *histo = (TH1F*)model->Clone();
808 buchmann 1.3 functionalhistocounter++;
809     stringstream histoname;
810     histoname << "histo_based_on_function_" << f1->GetName() << "__"<<functionalhistocounter;
811     histo->SetTitle(histoname.str().c_str());
812     histo->SetName(histoname.str().c_str());
813 buchmann 1.2 int nbins=histo->GetNbinsX();
814     float low=histo->GetBinLowEdge(1);
815     float hi=histo->GetBinLowEdge(histo->GetNbinsX())+histo->GetBinWidth(histo->GetNbinsX());
816    
817     for(int i=0;i<=nbins;i++) {
818 buchmann 1.4 histo->SetBinContent(i,(f1->Integral(histo->GetBinLowEdge(i),histo->GetBinLowEdge(i)+histo->GetBinWidth(i)))/histo->GetBinWidth(i));
819     histo->SetBinError(i,TMath::Sqrt(histo->GetBinContent(i)));
820 buchmann 1.2 }
821    
822     return histo;
823 buchmann 1.4 }
824    
825     float hintegral(TH1 *histo, float low, float high) {
826     float sum=0;
827     for(int i=1;i<histo->GetNbinsX();i++) {
828     if((histo->GetBinLowEdge(i)>=low)&&(histo->GetBinLowEdge(i)+histo->GetBinWidth(i))<=high) sum+=histo->GetBinContent(i);
829     //now on to the less clear cases!
830     if(histo->GetBinLowEdge(i)<low&&(histo->GetBinLowEdge(i)+histo->GetBinWidth(i))>low) {
831     //need to consider this case still ... the bin is kind of in range but not sooooo much.
832     }
833     if(histo->GetBinLowEdge(i)<high&&(histo->GetBinLowEdge(i)+histo->GetBinWidth(i))>high) {
834     //need to consider this case still ... the bin is kind of in range but not sooooo much.
835     }
836    
837     }
838     return sum;
839 buchmann 1.5 }
840    
841 buchmann 1.6 string newjzbexpression(string oldexpression,float shift) {
842     stringstream ss;
843     if(shift>0) ss<<"("<<oldexpression<<"+"<<shift<<")";
844     if(shift<0) ss<<"("<<oldexpression<<shift<<")";
845     if(shift==0) ss<<oldexpression;
846     return ss.str();
847     }
848    
849 buchmann 1.11 double Round(double num, unsigned int dig)
850     {
851     num *= pow(10, dig);
852     if (num >= 0)
853     num = floor(num + 0.5);
854     else
855     num = ceil(num - 0.5);
856     num/= pow(10, dig);
857     return num;
858 buchmann 1.16 }
859    
860     // The two functions below are for distributed processing
861    
862     int get_job_number(float ipoint, float Npoints,float Njobs) {
863     float pointposition=(ipoint/Npoints);
864     int njob=floor(pointposition*Njobs);
865     if(njob>=Njobs) njob--;
866     // cout << "Looking at point " << ipoint << " out of " << Npoints << " which is at position " << pointposition << " corresponding to " << pointposition*Njobs << " --> JOB " << njob << endl;
867     return njob;
868     }
869    
870    
871     bool do_this_point(int ipoint, int Npoints, int jobnumber, int Njobs) {
872     if(get_job_number(ipoint,Npoints,Njobs)==jobnumber) return true;
873     return false;
874     }
875 buchmann 1.19
876     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 ,
877     Option_t *option, Bool_t doError)
878     {
879     // internal function compute integral and optionally the error between the limits
880     // specified by the bin number values working for all histograms (1D, 2D and 3D)
881    
882     Int_t nbinsx = histo->GetNbinsX();
883     if (binx1 < 0) binx1 = 0;
884     if (binx2 > nbinsx+1 || binx2 < binx1) binx2 = nbinsx+1;
885     if (histo->GetDimension() > 1) {
886     Int_t nbinsy = histo->GetNbinsY();
887     if (biny1 < 0) biny1 = 0;
888     if (biny2 > nbinsy+1 || biny2 < biny1) biny2 = nbinsy+1;
889     } else {
890     biny1 = 0; biny2 = 0;
891     }
892     if (histo->GetDimension() > 2) {
893     Int_t nbinsz = histo->GetNbinsZ();
894     if (binz1 < 0) binz1 = 0;
895     if (binz2 > nbinsz+1 || binz2 < binz1) binz2 = nbinsz+1;
896     } else {
897     binz1 = 0; binz2 = 0;
898     }
899    
900     // - Loop on bins in specified range
901     TString opt = option;
902     opt.ToLower();
903     Bool_t width = kFALSE;
904     if (opt.Contains("width")) width = kTRUE;
905    
906    
907     Double_t dx = 1.;
908     Double_t dy = 1.;
909     Double_t dz = 1.;
910     Double_t integral = 0;
911     Double_t igerr2 = 0;
912     for (Int_t binx = binx1; binx <= binx2; ++binx) {
913     if (width) dx = histo->GetXaxis()->GetBinWidth(binx);
914     for (Int_t biny = biny1; biny <= biny2; ++biny) {
915     if (width) dy = histo->GetYaxis()->GetBinWidth(biny);
916     for (Int_t binz = binz1; binz <= binz2; ++binz) {
917     if (width) dz = histo->GetZaxis()->GetBinWidth(binz);
918     Int_t bin = histo->GetBin(binx, biny, binz);
919     if (width) integral += histo->GetBinContent(bin)*dx*dy*dz;
920     else integral += histo->GetBinContent(bin);
921     if (doError) {
922     if (width) igerr2 += histo->GetBinError(bin)*histo->GetBinError(bin)*dx*dx*dy*dy*dz*dz;
923     else igerr2 += histo->GetBinError(bin)*histo->GetBinError(bin);
924     }
925     }
926     }
927     }
928    
929     if (doError) error = TMath::Sqrt(igerr2);
930     return integral;
931     }
932    
933     Double_t IntegralAndError(TH1F *histo, Int_t binx1, Int_t binx2, Double_t & error, Option_t *option)
934     {
935     //Return integral of bin contents in range [binx1,binx2] and its error
936     // By default the integral is computed as the sum of bin contents in the range.
937     // if option "width" is specified, the integral is the sum of
938     // the bin contents multiplied by the bin width in x.
939     // the error is computed using error propagation from the bin errors assumming that
940     // all the bins are uncorrelated
941     return DoIntegral(histo,binx1,binx2,0,-1,0,-1,error,option,kTRUE);
942 buchmann 1.21 }
943    
944     void print_usage() {
945     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;
946 buchmann 1.22 }
947    
948    
949     string format_number( int value )
950     {
951     if( value == 0 ) return "00";
952     if( value < 10 ) return "0"+any2string(value);
953     return any2string(value);
954     }
955    
956     string seconds_to_time(int seconds) {
957     const static unsigned int SECONDS_IN_AN_HOUR = 3600;
958     const static unsigned int SECONDS_IN_A_MINUTE = 60;
959     stringstream answer;
960     if( seconds > 0 )
961     {
962     answer << format_number( (unsigned int)(seconds / SECONDS_IN_AN_HOUR) ) << ":";
963     answer << format_number( (unsigned int)((seconds % SECONDS_IN_AN_HOUR) / SECONDS_IN_A_MINUTE) ) << ":";
964     answer << format_number( (unsigned int)((seconds % SECONDS_IN_AN_HOUR) % (SECONDS_IN_A_MINUTE)) );
965     }
966     else
967     {
968     answer << "00:00:00";
969     }
970     return answer.str();
971     }
972