ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.26
Committed: Tue Dec 11 09:11:11 2012 UTC (12 years, 4 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.25: +4 -22 lines
Log Message:
Added ratio with systematic band

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