ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/AnalysisFramework/Plotting/Modules/GeneralToolBox.C
Revision: 1.24
Committed: Fri Aug 19 17:05:20 2011 UTC (13 years, 8 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.23: +4 -4 lines
Log Message:
Fixing an issue with similarly named variables (lumi and luminosity; the former is now called gentoolboxlumi, as it is only set in the general toolbox at one point and forgotten afterwards)

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    
48 buchmann 1.5 TLegend* make_legend(string title,float posx,float posy);
49 buchmann 1.1 TText* write_title(string title);
50     TText* write_title_low(string title);
51    
52     TText* write_text(float xpos,float ypos,string title);
53     float computeRatioError(float a, float da, float b, float db);
54     float computeProductError(float a, float da, float b, float db);
55     TGraphAsymmErrors *histRatio(TH1F *h1,TH1F *h2, int id, vector<float>binning);
56     void setlumi(float l);
57     void CompleteSave(TCanvas *can, string filename, bool feedback);
58 buchmann 1.3 void CompleteSave(TVirtualPad *can, string filename, bool feedback);
59 buchmann 1.1 void write_warning(string funcname, string text);
60     void write_error(string funcname, string text);
61     void write_info(string funcname, string text);
62 buchmann 1.5 void DrawPrelim();
63 buchmann 1.13 string get_directory();
64 buchmann 1.1 //-------------------------------------------------------------------------------------
65 buchmann 1.24 float generaltoolboxlumi;
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 fronga 1.17 TLegend* make_legend(string title="", float posx=0.6, float posy=0.55)
391 buchmann 1.1 {
392     // TLegend *leg = new TLegend(0.65,0.65,0.89,0.89);
393     gStyle->SetTextFont(42);
394 buchmann 1.7 TLegend *leg = new TLegend(posx,posy,0.89,0.89);
395 buchmann 1.1 if(title!="") leg->SetHeader(title.c_str());
396     leg->SetTextFont(42);
397 fronga 1.17 leg->SetTextSize(0.04);
398 buchmann 1.1 leg->SetFillColor(kWhite);
399     leg->SetBorderSize(0);
400     leg->SetLineColor(kWhite);
401 buchmann 1.5 DrawPrelim();
402     /* TText *writeline1 = write_text(0.77,0.87,"CMS Preliminary 2011");
403 buchmann 1.1 stringstream lumitext;
404 buchmann 1.5 lumitext<<"#sqrt{s}=7, L = "<<lumi<<" pb^{-1}";
405 buchmann 1.1 TText *writeline2 = write_text(0.77,0.83,lumitext.str().c_str());
406     writeline1->SetTextSize(0.03);
407     writeline2->SetTextSize(0.03);
408     writeline1->Draw();
409     writeline2->Draw();
410 buchmann 1.5 */
411 buchmann 1.1 return leg;
412     }
413    
414     TGraph* make_nice_ratio(int nbins,float binning[],TH1F* histo)
415     {
416     float errorsquared[nbins];
417     float errors[nbins];
418     float bincontent[nbins];
419     for (int i=0;i<nbins;i++) {
420     errorsquared[i]=0;
421     bincontent[i]=0;
422     errors[i]=0;
423     }
424     float currlimit=binning[0];
425     int currtoplim=1;
426     for(int ibin=1;ibin<=histo->GetNbinsX();ibin++)
427     {
428     if(binning[currtoplim]<histo->GetBinCenter(ibin)) currtoplim++;
429 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;
430 buchmann 1.1
431     }
432    
433     return 0;
434     }
435    
436     float statErrorN(float x){return x - 0.5*TMath::ChisquareQuantile(0.3173/2,2*x);}
437     float statErrorP(float x){return 0.5*TMath::ChisquareQuantile(1-0.3173/2,2*(x+1))-x;}
438     float lowLimit(float a, float x){return 0.5*TMath::ChisquareQuantile(a,2*x);}
439     float highLimit(float a,float x){return 0.5*TMath::ChisquareQuantile(1-a,2*(x+1));}
440    
441     float computeRatioError(float a, float da, float b, float db)
442     {
443     float val=0.;
444     float errorSquare = (a/b)*(a/b)*( (da/a)*(da/a) + (db/b)*(db/b));
445     val = TMath::Sqrt(errorSquare);
446     return val;
447    
448     }
449     float computeProductError(float a, float da, float b, float db)
450     {
451     float val=0.;
452     float errorSquare = (a*b)*(a*b)*( (da/a)*(da/a) + (db/b)*(db/b));
453     val = TMath::Sqrt(errorSquare);
454     return val;
455     }
456    
457 buchmann 1.23 TGraphAsymmErrors *histRatio(TH1F *h1,TH1F *h2, int id, vector<float>binning, bool precise=false)
458 buchmann 1.1 {
459     int absJZBbinsNumber = binning.size()-1;
460     TGraphAsymmErrors* graph = new TGraphAsymmErrors(absJZBbinsNumber);
461    
462     for(unsigned int i=0;i<absJZBbinsNumber;i++)
463     {
464     float xCenter=h1->GetBinCenter(i+1);
465     float xWidth=(h1->GetBinWidth(i+1))*0.5;
466     float nominatorError = h1->GetBinError(i+1);
467     float nominator=h1->GetBinContent(i+1);
468     float denominatorError=h2->GetBinError(i+1);
469     float denominator=h2->GetBinContent(i+1);
470     float errorN = 0;
471     float errorP = computeRatioError(nominator,nominatorError,denominator,denominatorError);
472     if(id==1) // (is data)
473     {
474 buchmann 1.23 if(!precise) errorP = computeRatioError(nominator,statErrorP(nominator),denominator,statErrorP(denominator));
475     else errorP = computeRatioError(nominator,nominatorError,denominator,denominatorError);
476 buchmann 1.1 errorN = errorP; // symmetrize using statErrorP
477     } else {
478     errorN = computeRatioError(nominator,nominatorError,denominator,denominatorError);
479 buchmann 1.23 errorP = errorN;
480 buchmann 1.1 }
481     if(denominator!=0) {
482     graph->SetPoint(i, xCenter, nominator/denominator);
483     graph->SetPointError(i,xWidth,xWidth,errorN,errorP);
484     }
485     else {
486     graph->SetPoint(i, xCenter, -999);
487     graph->SetPointError(i,xWidth,xWidth,errorN,errorP);
488     }
489     }
490     return graph;
491     }
492    
493     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!
494     float uperr=0,downerr=0;
495     if(down>up&&down>cent) uperr=down-cent;
496     if(up>down&&up>cent) uperr=up-cent;
497     if(down<cent&&down<up) downerr=cent-down;
498     if(up<cent&&up<down) downerr=cent-up;
499     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!");
500     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!");
501     stringstream result;
502     result << cent << " + " << uperr << " - " << downerr;
503     return result.str();
504     }
505    
506     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")
507     {
508     int last = size - 2;
509     int isChanged = 1;
510    
511     while ( last >= 0 && isChanged )
512     {
513     isChanged = 0;
514     for ( int k = 0; k <= last; k++ )
515     if ( arr[k] > arr[k+1] )
516     {
517     swap ( arr[k], arr[k+1] );
518     isChanged = 1;
519     int bkp=order[k];
520     order[k]=order[k+1];
521     order[k+1]=bkp;
522     }
523     last--;
524     }
525     }
526    
527     void swapvec(vector<float> &vec,int j, int k) {
528     float bkp=vec[j];
529     vec[j]=vec[k];
530     vec[k]=bkp;
531     }
532    
533     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")
534     {
535     int last = arr.size() - 2;
536     int isChanged = 1;
537    
538     while ( last >= 0 && isChanged )
539     {
540     isChanged = 0;
541     for ( int k = 0; k <= last; k++ )
542     if ( arr[k] > arr[k+1] )
543     {
544     swapvec (arr,k,k+1);
545     isChanged = 1;
546     int bkp=order[k];
547     order[k]=order[k+1];
548     order[k+1]=bkp;
549     }
550     last--;
551     }
552     }
553    
554     int numerichistoname=0;
555 buchmann 1.16 bool givingnumber=false;
556 buchmann 1.1 string GetNumericHistoName() {
557 buchmann 1.16 while(givingnumber) sleep(1);
558     givingnumber=true;
559 buchmann 1.1 stringstream b;
560     b << "h_" << numerichistoname;
561     numerichistoname++;
562 buchmann 1.16 givingnumber=false;
563 buchmann 1.1 return b.str();
564     }
565    
566     //********************** BELOW : CUT INTERPRETATION **************************//
567     void splitupcut(string incut, vector<string> &partvector)
568     {
569     //idea: go thru the string called incut; if a parantheses is opened, then the cut cannot be split up until the parantheses is closed.
570     //ok anyway screw the parantheses.
571     int paranthesis_open=0;
572     int substr_start=0;
573     string currchar="";
574     for (int ichar=0;ichar<incut.length();ichar++)
575     {
576     currchar=incut.substr(ichar,1);
577     // if(currchar=="(") paranthesis_open++;
578     // if(currchar==")") paranthesis_open--;
579     if(currchar=="&"&&incut.substr(ichar+1,1)=="&"&&paranthesis_open==0) {
580     partvector.push_back(incut.substr(substr_start,ichar-substr_start));
581     substr_start=ichar+2;
582     }
583     }
584     partvector.push_back(incut.substr(substr_start,incut.length()-substr_start));
585     if(Verbosity>1) {
586 buchmann 1.13 dout << "[ splitupcut() ] : The cut vector now contains the following elements: "<< endl;
587 buchmann 1.1 for (int ipart=0;ipart<partvector.size();ipart++)
588     {
589 buchmann 1.13 dout << " - " << partvector[ipart] << endl;
590 buchmann 1.1 }
591     }
592     }
593    
594     int atleastvalue(string expression, int &morethanlessthan) // takes in an expression such as ">2" or ">=3" and returns e.g. 3 (in both examples)
595     {
596     int retval=0;
597     if(expression.substr(0,1)==">"&&expression.substr(1,1)=="=") {
598 buchmann 1.13 // dout << "The expression " << expression << " is saying that we have at least " << atoi(expression.substr(2,1).c_str()) << " jets" << endl;
599 buchmann 1.1 morethanlessthan=1;
600     return atoi(expression.substr(2,1).c_str());
601     }
602     if(expression.substr(0,1)=="="&&expression.substr(1,1)=="=") {
603 buchmann 1.13 // dout << "The expression " << expression << " is saying that we have at least " << atoi(expression.substr(1,1).c_str())+1 << " jets" << endl;
604 buchmann 1.1 morethanlessthan=0;
605     return atoi(expression.substr(1,1).c_str());
606     }
607     if(expression.substr(0,1)=="<"&&expression.substr(1,1)=="=") {
608 buchmann 1.13 // dout << "The expression " << expression << " is saying that we have at least " << atoi(expression.substr(1,1).c_str())+1 << " jets" << endl;
609 buchmann 1.1 morethanlessthan=-1;
610     return 1+atoi(expression.substr(1,1).c_str());
611     }
612     if(expression.substr(0,1)==">") {
613 buchmann 1.13 // dout << "The expression " << expression << " is saying that we have at least " << atoi(expression.substr(2,1).c_str()) << " jets" << endl;
614 buchmann 1.1 morethanlessthan=1;
615     return 1+atoi(expression.substr(2,1).c_str());
616     }
617     if(expression.substr(0,1)=="<"&&expression.substr(1,1)=="=") {
618 buchmann 1.13 // dout << "The expression " << expression << " is saying that we have at least " << atoi(expression.substr(2,1).c_str()) << " jets" << endl;
619 buchmann 1.1 morethanlessthan=-1;
620     return 1+atoi(expression.substr(2,1).c_str());
621     }
622     }
623    
624     int do_jet_cut(string incut, int *nJets) {
625     string expression=(incut.substr(12,incut.size()-12));
626 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;
627 buchmann 1.1 if(expression.substr(0,1)=="<"&&expression.substr(1,1)=="=") {
628     int nJet=atoi(expression.substr(2,1).c_str());
629     for(int i=nJet+1;i<20;i++) nJets[i]=0;
630 buchmann 1.13 dout << "Is of type <=" << endl;
631 buchmann 1.1 return 0;
632     }
633     if(expression.substr(0,1)=="="&&expression.substr(1,1)=="=") {
634     int nJet=atoi(expression.substr(2,1).c_str());
635     for(int i=0;i<20&&i!=nJet;i++) nJets[i]=0;
636 buchmann 1.13 dout << "Is of type ==" << endl;
637 buchmann 1.1 return 0;
638     }
639     if(expression.substr(0,1)==">"&&expression.substr(1,1)=="=") {
640     int nJet=atoi(expression.substr(2,1).c_str());
641     for(int i=0;i<nJet&&i!=nJet;i++) nJets[i]=0;
642 buchmann 1.13 dout << "Is of type >=" << endl;
643 buchmann 1.1 return 0;
644     }
645     if(expression.substr(0,1)=="<") {
646     int nJet=atoi(expression.substr(1,1).c_str());
647     for(int i=nJet;i<20;i++) nJets[i]=0;
648 buchmann 1.13 dout << "Is of type <" << endl;
649 buchmann 1.1 return 0;
650     }
651     if(expression.substr(0,1)==">") {
652     int nJet=atoi(expression.substr(1,1).c_str());
653     for(int i=0;i<nJet+1&&i!=nJet;i++) nJets[i]=0;
654 buchmann 1.13 dout << "Is of type >" << endl;
655 buchmann 1.1 return 0;
656     }
657     }
658    
659     string interpret_cut(string incut, bool &isJetCut, int *permittednJets)
660     {
661     // isJetCut=false;nJets=-1;
662     if(incut=="()") return "";
663     while(incut.substr(0,1)=="(") incut=incut.substr(1,incut.length()-1);
664     while(incut.length()>0&&incut.substr(incut.length()-1,1)==")") incut=incut.substr(0,incut.length()-1);
665     // 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.
666    
667     if(Verbosity>0) {
668 buchmann 1.13 dout << "Now interpreting cut " << incut << endl;
669 buchmann 1.1 }
670     /*
671     if(incut=="ch1*ch2<0") return "OS";
672     if(incut=="id1==id2") return "SF";
673     if(incut=="id1!=id2") return "OF";
674     */
675     if(incut=="ch1*ch2<0") return "";
676 buchmann 1.5 if(incut=="(mll>55&&mll<70)||(mll>112&&mll<160)") return "SB";
677     if(incut=="(mll>61&&mll<70)||(mll>112&&mll<190)") return "SB'";
678 buchmann 1.1 if(incut=="id1==id2") return "";
679     if(incut=="id1!=id2") return "";
680     if(incut=="mll>2") return "";
681    
682     if(incut=="mll>0") return ""; // my typical "fake cut"
683    
684     if(incut=="passed_triggers||!is_data") return "Triggers";
685     if(incut=="pfjzb[0]>-998") return "";
686    
687    
688     if(incut=="id1==0") return "ee";
689     if(incut=="id1==1") return "#mu#mu";
690     if(incut=="abs(mll-91.2)<20") return "|m_{l^{+}l^{-}}-m_{Z}|<20";
691     if(incut=="pfJetGoodID[0]") return "";
692     if(incut=="pfJetGoodID[1]") return "";
693     if((int)incut.find("pfJetGoodNum")>-1) {
694     //do_jet_cut(incut,permittednJets);
695     stringstream result;
696     result << "nJets" << incut.substr(12,incut.size()-12);
697 buchmann 1.13 /* dout << "Dealing with a jet cut: " << incut << endl;
698 buchmann 1.1 stringstream result;
699     result << "nJets" << incut.substr(12,incut.size()-12);
700     isJetCut=true;
701     if(exactjetcut(incut,nJets))
702     // nJets=atleastvalue((incut.substr(12,incut.size()-12)),morethanlessthan);
703     return result.str();*/
704     return result.str();
705     }
706     return incut;
707     }
708    
709     string interpret_nJet_range(int *nJets) {
710 buchmann 1.13 for (int i=0;i<20;i++) dout << i << " : " << nJets[i] << endl;
711 buchmann 1.1 return "hello";
712     }
713    
714     string interpret_cuts(vector<string> &cutparts)
715     {
716     stringstream nicecut;
717     int nJets;
718     bool isJetCut;
719     int finalJetCut=-1;
720     int permittednJets[20];
721     for(int ijet=0;ijet<20;ijet++) permittednJets[ijet]=1;
722     int morethanlessthan=0;//-1: less than, 0: exactly, 1: more than
723     for(int icut=0;icut<cutparts.size();icut++)
724     {
725     if(icut==0) nicecut<<interpret_cut(cutparts[icut],isJetCut,permittednJets);
726     else {
727     string nice_this_cut = interpret_cut(cutparts[icut],isJetCut,permittednJets);//blublu
728     if(nice_this_cut.length()>0&&nicecut.str().length()>0) {
729     if(!isJetCut) nicecut<<"&&"<<nice_this_cut;
730     else {
731     if(nJets>finalJetCut) finalJetCut=nJets;
732     }
733     }
734     if(nice_this_cut.length()>0&&nicecut.str().length()==0) {
735     if(!isJetCut) {
736     nicecut<<nice_this_cut;
737     }
738     else {
739     if(nJets>finalJetCut) finalJetCut=nJets;
740     }
741     }
742     }
743     }
744     if(finalJetCut>-1) {
745     if(nicecut.str().length()==0) {
746     nicecut << "nJets#geq" << finalJetCut;
747     }
748     else
749     {
750     nicecut << "&&nJets#geq " << finalJetCut;
751     }
752     }
753    
754 buchmann 1.13 // dout << "The nJet allowed range is given by: " << interpret_nJet_range(permittednJets) << endl;
755 buchmann 1.1
756     return nicecut.str();
757     }
758    
759     string decipher_cut(TCut originalcut,TCut ignorethispart)
760     {
761     string incut=(const char*)originalcut;
762     string ignore=(const char*)ignorethispart;
763    
764     if(ignore.length()>0 && incut.find(ignore)!=string::npos) incut=incut.replace(incut.find(ignore),ignore.length(),"");
765    
766     vector<string>cutparts;
767     splitupcut(incut,cutparts);
768     string write_cut=interpret_cuts(cutparts);
769     return write_cut;
770     }
771    
772     //********************** ABOVE : CUT INTERPRETATION **************************//
773 buchmann 1.2
774     Double_t GausRandom(Double_t mu, Double_t sigma) {
775     return gRandom->Gaus(mu,sigma);// real deal
776     //return mu;//debugging : no smearing.
777     }
778    
779 buchmann 1.3 int functionalhistocounter=0;
780 buchmann 1.2 TH1F * makehistofromfunction(TF1 *f1,TH1F *model) {
781     TH1F *histo = (TH1F*)model->Clone();
782 buchmann 1.3 functionalhistocounter++;
783     stringstream histoname;
784     histoname << "histo_based_on_function_" << f1->GetName() << "__"<<functionalhistocounter;
785     histo->SetTitle(histoname.str().c_str());
786     histo->SetName(histoname.str().c_str());
787 buchmann 1.2 int nbins=histo->GetNbinsX();
788     float low=histo->GetBinLowEdge(1);
789     float hi=histo->GetBinLowEdge(histo->GetNbinsX())+histo->GetBinWidth(histo->GetNbinsX());
790    
791     for(int i=0;i<=nbins;i++) {
792 buchmann 1.4 histo->SetBinContent(i,(f1->Integral(histo->GetBinLowEdge(i),histo->GetBinLowEdge(i)+histo->GetBinWidth(i)))/histo->GetBinWidth(i));
793     histo->SetBinError(i,TMath::Sqrt(histo->GetBinContent(i)));
794 buchmann 1.2 }
795    
796     return histo;
797 buchmann 1.4 }
798    
799     float hintegral(TH1 *histo, float low, float high) {
800     float sum=0;
801     for(int i=1;i<histo->GetNbinsX();i++) {
802     if((histo->GetBinLowEdge(i)>=low)&&(histo->GetBinLowEdge(i)+histo->GetBinWidth(i))<=high) sum+=histo->GetBinContent(i);
803     //now on to the less clear cases!
804     if(histo->GetBinLowEdge(i)<low&&(histo->GetBinLowEdge(i)+histo->GetBinWidth(i))>low) {
805     //need to consider this case still ... the bin is kind of in range but not sooooo much.
806     }
807     if(histo->GetBinLowEdge(i)<high&&(histo->GetBinLowEdge(i)+histo->GetBinWidth(i))>high) {
808     //need to consider this case still ... the bin is kind of in range but not sooooo much.
809     }
810    
811     }
812     return sum;
813 buchmann 1.5 }
814    
815 buchmann 1.7 void DrawPrelim_OLD() {
816 buchmann 1.5 TText *writeline1 = write_text(0.77,0.87,"CMS Preliminary 2011");
817     stringstream lumitext;
818 buchmann 1.24 lumitext<<"#sqrt{s}=7, L="<< generaltoolboxlumi/1000<<" fb^{-1}";
819 buchmann 1.5 TText *writeline2 = write_text(0.77,0.83,lumitext.str().c_str());
820     writeline1->SetTextSize(0.03);
821     writeline2->SetTextSize(0.03);
822     writeline1->Draw();
823     writeline2->Draw();
824     }
825 buchmann 1.6
826 buchmann 1.7 void DrawPrelim() {
827     string barn="pb";
828 buchmann 1.24 float writelumi=generaltoolboxlumi;
829 buchmann 1.7 if(writelumi>=1000)
830     {
831     writelumi/=1000;
832     barn="fb";
833     }
834    
835 buchmann 1.8 stringstream prelimtext;
836 buchmann 1.9 //prelimtext << "CMS Preliminary 2011 , #sqrt{s}= 7 TeV, L= O(1) fb^{-1}"; //temporary replacement
837 fronga 1.17 prelimtext << "CMS Preliminary 2011 , #sqrt{s}= 7 TeV, L= "
838     << std::setprecision(2) <<writelumi<<" "<<barn<<"^{-1}";
839 buchmann 1.10 TPaveText *eventSelectionPaveText = new TPaveText(0.27, 0.93,0.77, 1.0,"blNDC");
840 buchmann 1.8 eventSelectionPaveText->SetFillStyle(4000);
841     eventSelectionPaveText->SetBorderSize(0.1);
842     eventSelectionPaveText->SetFillColor(kWhite);
843     eventSelectionPaveText->SetTextFont(42);
844 buchmann 1.10 eventSelectionPaveText->SetTextSize(0.0415);
845 buchmann 1.8 eventSelectionPaveText->AddText(prelimtext.str().c_str());
846     eventSelectionPaveText->Draw();
847 buchmann 1.7 }
848    
849 buchmann 1.6 string newjzbexpression(string oldexpression,float shift) {
850     stringstream ss;
851     if(shift>0) ss<<"("<<oldexpression<<"+"<<shift<<")";
852     if(shift<0) ss<<"("<<oldexpression<<shift<<")";
853     if(shift==0) ss<<oldexpression;
854     return ss.str();
855     }
856    
857 buchmann 1.11 double Round(double num, unsigned int dig)
858     {
859     num *= pow(10, dig);
860     if (num >= 0)
861     num = floor(num + 0.5);
862     else
863     num = ceil(num - 0.5);
864     num/= pow(10, dig);
865     return num;
866 buchmann 1.16 }
867    
868     // The two functions below are for distributed processing
869    
870     int get_job_number(float ipoint, float Npoints,float Njobs) {
871     float pointposition=(ipoint/Npoints);
872     int njob=floor(pointposition*Njobs);
873     if(njob>=Njobs) njob--;
874     // cout << "Looking at point " << ipoint << " out of " << Npoints << " which is at position " << pointposition << " corresponding to " << pointposition*Njobs << " --> JOB " << njob << endl;
875     return njob;
876     }
877    
878    
879     bool do_this_point(int ipoint, int Npoints, int jobnumber, int Njobs) {
880     if(get_job_number(ipoint,Npoints,Njobs)==jobnumber) return true;
881     return false;
882     }
883 buchmann 1.19
884     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 ,
885     Option_t *option, Bool_t doError)
886     {
887     // internal function compute integral and optionally the error between the limits
888     // specified by the bin number values working for all histograms (1D, 2D and 3D)
889    
890     Int_t nbinsx = histo->GetNbinsX();
891     if (binx1 < 0) binx1 = 0;
892     if (binx2 > nbinsx+1 || binx2 < binx1) binx2 = nbinsx+1;
893     if (histo->GetDimension() > 1) {
894     Int_t nbinsy = histo->GetNbinsY();
895     if (biny1 < 0) biny1 = 0;
896     if (biny2 > nbinsy+1 || biny2 < biny1) biny2 = nbinsy+1;
897     } else {
898     biny1 = 0; biny2 = 0;
899     }
900     if (histo->GetDimension() > 2) {
901     Int_t nbinsz = histo->GetNbinsZ();
902     if (binz1 < 0) binz1 = 0;
903     if (binz2 > nbinsz+1 || binz2 < binz1) binz2 = nbinsz+1;
904     } else {
905     binz1 = 0; binz2 = 0;
906     }
907    
908     // - Loop on bins in specified range
909     TString opt = option;
910     opt.ToLower();
911     Bool_t width = kFALSE;
912     if (opt.Contains("width")) width = kTRUE;
913    
914    
915     Double_t dx = 1.;
916     Double_t dy = 1.;
917     Double_t dz = 1.;
918     Double_t integral = 0;
919     Double_t igerr2 = 0;
920     for (Int_t binx = binx1; binx <= binx2; ++binx) {
921     if (width) dx = histo->GetXaxis()->GetBinWidth(binx);
922     for (Int_t biny = biny1; biny <= biny2; ++biny) {
923     if (width) dy = histo->GetYaxis()->GetBinWidth(biny);
924     for (Int_t binz = binz1; binz <= binz2; ++binz) {
925     if (width) dz = histo->GetZaxis()->GetBinWidth(binz);
926     Int_t bin = histo->GetBin(binx, biny, binz);
927     if (width) integral += histo->GetBinContent(bin)*dx*dy*dz;
928     else integral += histo->GetBinContent(bin);
929     if (doError) {
930     if (width) igerr2 += histo->GetBinError(bin)*histo->GetBinError(bin)*dx*dx*dy*dy*dz*dz;
931     else igerr2 += histo->GetBinError(bin)*histo->GetBinError(bin);
932     }
933     }
934     }
935     }
936    
937     if (doError) error = TMath::Sqrt(igerr2);
938     return integral;
939     }
940    
941     Double_t IntegralAndError(TH1F *histo, Int_t binx1, Int_t binx2, Double_t & error, Option_t *option)
942     {
943     //Return integral of bin contents in range [binx1,binx2] and its error
944     // By default the integral is computed as the sum of bin contents in the range.
945     // if option "width" is specified, the integral is the sum of
946     // the bin contents multiplied by the bin width in x.
947     // the error is computed using error propagation from the bin errors assumming that
948     // all the bins are uncorrelated
949     return DoIntegral(histo,binx1,binx2,0,-1,0,-1,error,option,kTRUE);
950 buchmann 1.21 }
951    
952     void print_usage() {
953     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;
954 buchmann 1.22 }
955    
956    
957     string format_number( int value )
958     {
959     if( value == 0 ) return "00";
960     if( value < 10 ) return "0"+any2string(value);
961     return any2string(value);
962     }
963    
964     string seconds_to_time(int seconds) {
965     const static unsigned int SECONDS_IN_AN_HOUR = 3600;
966     const static unsigned int SECONDS_IN_A_MINUTE = 60;
967     stringstream answer;
968     if( seconds > 0 )
969     {
970     answer << format_number( (unsigned int)(seconds / SECONDS_IN_AN_HOUR) ) << ":";
971     answer << format_number( (unsigned int)((seconds % SECONDS_IN_AN_HOUR) / SECONDS_IN_A_MINUTE) ) << ":";
972     answer << format_number( (unsigned int)((seconds % SECONDS_IN_AN_HOUR) % (SECONDS_IN_A_MINUTE)) );
973     }
974     else
975     {
976     answer << "00:00:00";
977     }
978     return answer.str();
979     }
980