ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.37
Committed: Mon Apr 8 14:10:34 2013 UTC (12 years, 1 month ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.36: +3 -3 lines
Log Message:
Adopting our style to agree with Aachen's

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