ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.41
Committed: Fri Apr 26 07:00:24 2013 UTC (12 years ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.40: +5 -5 lines
Log Message:
Drawing error bars also from points outside the range

File Contents

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