ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.32
Committed: Thu Jan 24 08:21:38 2013 UTC (12 years, 3 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.31: +8 -5 lines
Log Message:
Updated saving method (with sys and ratio) to not chew up provided tvirtualpad

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 << ", L_{int} = " << std::setprecision(3) <<writelumi<<" "<<barn<<"^{-1}";
608 else prelimtext << "CMS" << prel << ", #sqrt{s} = " << energy << ", L_{int} = " << 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 // http://stackoverflow.com/questions/669438/how-to-get-memory-usage-at-run-time-in-c
1242 // process_mem_usage(double &, double &) - takes two doubles by reference,
1243 // attempts to read the system-dependent data for a process' virtual memory
1244 // size and resident set size, and return the results in KB.
1245 //
1246 // On failure, returns 0.0, 0.0
1247
1248 /* usage:
1249 double vm2, rss2;
1250 process_mem_usage(vm2, rss2);
1251 cout << "Memory usage: VM: " << vm << "; RSS: " << rss << endl;
1252 */
1253
1254 void process_mem_usage(double& vm_usage, double& resident_set)
1255 {
1256 using std::ios_base;
1257 using std::ifstream;
1258 using std::string;
1259
1260 vm_usage = 0.0;
1261 resident_set = 0.0;
1262
1263 // 'file' stat seems to give the most reliable results
1264 //
1265 ifstream stat_stream("/proc/self/stat",ios_base::in);
1266
1267 // dummy vars for leading entries in stat that we don't care about
1268 //
1269 string pid, comm, state, ppid, pgrp, session, tty_nr;
1270 string tpgid, flags, minflt, cminflt, majflt, cmajflt;
1271 string utime, stime, cutime, cstime, priority, nice;
1272 string O, itrealvalue, starttime;
1273
1274 // the two fields we want
1275 //
1276 unsigned long vsize;
1277 long rss;
1278
1279 stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
1280 >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
1281 >> utime >> stime >> cutime >> cstime >> priority >> nice
1282 >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest
1283
1284 stat_stream.close();
1285
1286 long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages
1287 vm_usage = vsize / 1024.0;
1288 resident_set = rss * page_size_kb;
1289 }
1290
1291 TGraphAsymmErrors* produce_ratio_graph(TH1F *baseratio) {
1292 int nbins=baseratio->GetNbinsX();
1293 double x[nbins];
1294 double y[nbins];
1295 double ex[nbins];
1296 double ey[nbins];
1297
1298 for(int ibin=1;ibin<=nbins;ibin++) {
1299 x[ibin-1]=baseratio->GetBinCenter(ibin);
1300 y[ibin-1]=baseratio->GetBinContent(ibin);
1301 ex[ibin-1]=0.5*baseratio->GetBinWidth(ibin);
1302 ey[ibin-1]=baseratio->GetBinError(ibin);
1303 }
1304
1305 TGraphAsymmErrors *result = new TGraphAsymmErrors(nbins, x,y,ex,ex,ey,ey);
1306 return result;
1307 }
1308
1309
1310 Double_t MarcosChi2TestX(const TH1* h1, const TH1* h2, Double_t &chi2, Int_t &ndf, Int_t &igood, Option_t *option)
1311 {
1312
1313 TString opt = option;
1314 opt.ToUpper();
1315
1316 Double_t prob = h1->Chi2TestX(h2,chi2,ndf,igood,option);
1317
1318 if(opt.Contains("P")) {
1319 printf("Chi2 = %f, Prob = %g, NDF = %d, igood = %d\n", chi2,prob,ndf,igood);
1320 }
1321 if(opt.Contains("CHI2/NDF")) {
1322 if (ndf == 0) return 0;
1323 return chi2/ndf;
1324 }
1325 if(opt.Contains("CHI2")) {
1326 return chi2;
1327 }
1328
1329 return prob;
1330 }
1331
1332 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) {
1333 //this function saves the pad being passed as well as a new one including the ratio.
1334
1335 TVirtualPad *canvas = (TVirtualPad*) orig_canvas->Clone("TempCanvas");//otherwise the main_canvas will own our pad and destroy it upon deletion
1336 CompleteSave(canvas,savemeas);
1337
1338 float bottommargin=gStyle->GetPadBottomMargin();
1339 float canvas_height=gStyle->GetCanvasDefH();
1340 float canvas_width=gStyle->GetCanvasDefW();
1341 float ratiospace=0.25;// space the ratio should take up (relative to original pad)
1342
1343 float ratiobottommargin=0.3;
1344 float ratiotopmargin=0.1;
1345
1346 float xstretchfactor=((1-ratiospace)*(1-gStyle->GetPadTopMargin()))/((1)*ratiospace);
1347
1348 TCanvas *main_canvas = new TCanvas("main_canvas","main_canvas",(Int_t)canvas_width,(Int_t)(canvas_height*(1+ratiospace)));
1349 TPad *mainpad = new TPad("mainpad","mainpad",0,1-(1.0/(1+ratiospace)),1,1);//top (main) pad
1350 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
1351 TPad *bottompad = new TPad("bottompad", "Ratio Pad",0,0,1,(1-(1-bottommargin)/(1+ratiospace))-0.015); //bottom pad
1352
1353 main_canvas->Range(0,0,1,1);
1354 main_canvas->SetBorderSize(0);
1355 main_canvas->SetFrameFillColor(0);
1356
1357 mainpad->Draw();
1358 mainpad->cd();
1359 mainpad->Range(0,0,1,1);
1360 mainpad->SetFillColor(kWhite);
1361 mainpad->SetBorderSize(0);
1362 mainpad->SetFrameFillColor(0);
1363 canvas->Range(0,0,1,1);
1364 canvas->Draw("same");
1365 mainpad->Modified();
1366 main_canvas->cd();
1367 coverpad->Draw();
1368 coverpad->cd();
1369 coverpad->Range(0,0,1,1);
1370 coverpad->SetFillColor(kWhite);
1371 coverpad->SetBorderSize(0);
1372 coverpad->SetFrameFillColor(0);
1373 coverpad->Modified();
1374 main_canvas->cd();
1375 bottompad->SetTopMargin(ratiotopmargin);
1376 bottompad->SetBottomMargin(ratiobottommargin);
1377 bottompad->Draw();
1378 bottompad->cd();
1379 bottompad->Range(0,0,1,1);
1380 bottompad->SetFillColor(kWhite);
1381 TH1F *ratio = (TH1F*)nominator->Clone(GetNumericHistoName().c_str());
1382 ratio->Divide(denominator);
1383
1384 TGraphAsymmErrors *eratio;
1385 TH1F *SystDown;
1386 TH1F *SystUp;
1387
1388 if(!do_bpred_ratio) eratio = produce_ratio_graph(ratio);
1389 else {
1390 bool using_data=false;
1391 if((int)savemeas.find("Data")>0) using_data=true;
1392 eratio = histRatio(nominator,denominator,using_data,PlottingSetup::global_ratio_binning,false);
1393 if(syshisto!=0) {
1394 SystDown = (TH1F*)syshisto->Clone("SystDown");
1395 SystUp = (TH1F*)syshisto->Clone("SystUp");
1396 for(int i=1;i<=syshisto->GetNbinsX();i++) {
1397 SystDown->SetBinContent(i,1-syshisto->GetBinContent(i));
1398 SystUp->SetBinContent(i,1+syshisto->GetBinContent(i));
1399 }
1400 SystDown->SetLineColor(TColor::GetColor("#006DE1"));
1401 SystUp->SetLineColor(TColor::GetColor("#006DE1"));
1402 }
1403 for(int i=1;i<=ratio->GetNbinsX();i++) {
1404 ratio->SetBinContent(i,0);
1405 ratio->SetBinError(i,0);
1406 }
1407
1408 }
1409
1410 if(syshisto && !do_bpred_ratio) {
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 eratio->SetFillColor(TColor::GetColor("#00ADE1"));
1421
1422 ratio->SetTitle("");
1423 ratio->GetYaxis()->SetRangeUser(0.0,2.0);
1424 if(do_bpred_ratio) ratio->GetYaxis()->SetRangeUser(0.0,2.0);
1425 if(extendrange) ratio->GetYaxis()->SetRangeUser(0.0,4.0);
1426 ratio->GetXaxis()->SetTitle(nominator->GetXaxis()->GetTitle());
1427 ratio->GetXaxis()->CenterTitle();
1428 ratio->GetYaxis()->SetTitle(yaxistitle.c_str());
1429 ratio->GetYaxis()->SetTitleOffset(0.4);
1430 ratio->GetYaxis()->CenterTitle();
1431 ratio->SetStats(0);
1432 ratio->GetXaxis()->SetLabelSize(xstretchfactor*ratio->GetXaxis()->GetLabelSize());
1433 ratio->GetYaxis()->SetLabelSize(xstretchfactor*ratio->GetYaxis()->GetLabelSize());
1434 ratio->GetXaxis()->SetTitleSize(xstretchfactor*gStyle->GetTitleSize());
1435 ratio->GetYaxis()->SetTitleSize(xstretchfactor*gStyle->GetTitleSize());
1436 ratio->GetYaxis()->SetNdivisions(502,false);
1437 ratio->SetFillColor(TColor::GetColor("#58D3F7"));
1438 ratio->SetMarkerSize(0);
1439 ratio->Draw("e2");
1440
1441 TGraphAsymmErrors *ratio_center = (TGraphAsymmErrors*)eratio->Clone("ratio_center");
1442 for(int i=0;i<ratio_center->GetN();i++) {
1443 ratio_center->SetPointError(i,ratio_center->GetErrorXlow(i),ratio_center->GetErrorXhigh(i),0.005,0.005);
1444 }
1445
1446 ratio_center->SetFillColor(TColor::GetColor("#006381"));
1447
1448 if(syshisto!=0) {
1449 // sysratio->Draw("2");
1450 // eratio->Draw("2,same");
1451 eratio->Draw("2");
1452 SystDown->Draw("histo,same");
1453 SystUp->Draw("histo,same");
1454 } else {
1455 eratio->Draw("2");
1456 }
1457 ratio_center->Draw("2");
1458 ratio->Draw("same,axis");
1459 TLine *oneline = new TLine(ratio->GetXaxis()->GetBinLowEdge(1),1,ratio->GetXaxis()->GetBinLowEdge(ratio->GetNbinsX())+ratio->GetXaxis()->GetBinWidth(ratio->GetNbinsX()),1);
1460 oneline->SetLineStyle(2);
1461 oneline->SetLineColor(kBlue);
1462 oneline->Draw("same");
1463
1464 main_canvas->cd();
1465 main_canvas->Modified();
1466 main_canvas->cd();
1467 main_canvas->SetSelected(main_canvas);
1468
1469 CompleteSave(main_canvas,savemeas+"_withratio");
1470 bottompad->cd();
1471
1472 Double_t chi2;
1473 Int_t ndf,igood;
1474 // Double_t res=0.0;
1475 Double_t chi2prob = MarcosChi2TestX(nominator,denominator,chi2,ndf,igood,"UW");
1476
1477 stringstream Chi2text;
1478 Chi2text << "#chi^{2} / ndf: " << chi2 << " / " << ndf;
1479 stringstream Chi2probtext;
1480 Chi2probtext << "#chi^{2} prob: " << chi2prob;
1481 TText* chi2box = write_text(0.02,0.11,Chi2text.str());
1482 chi2box->SetTextSize(0.08);
1483 chi2box->SetTextAlign(11);
1484 chi2box->Draw();
1485 TText* chi2probbox = write_text(0.02,0.04,Chi2probtext.str());
1486 chi2probbox->SetTextSize(0.08);
1487 chi2probbox->SetTextAlign(11);
1488 chi2probbox->Draw();
1489
1490 stringstream CompRatio;
1491 CompRatio << "Ratio: " << nominator->Integral() << " / " << denominator->Integral() << " \n " << nominator->Integral()/denominator->Integral();
1492 TText *CompleteRatio = write_text(0.98,0.04,CompRatio.str());
1493 CompleteRatio->SetTextSize(0.08);
1494 CompleteRatio->SetTextAlign(31);
1495 CompleteRatio->Draw();
1496
1497 CompleteSave(main_canvas,savemeas+"_withratio_and_Chi2");
1498
1499 // float KS = nominator->KolmogorovTest(denominator);
1500 // stringstream KStext;
1501 // Chi2text << "KS = " << KS << endl;
1502 //cout << "Found : " << KStext.str() << endl;
1503
1504 delete eratio;
1505 delete ratio_center;
1506 delete ratio;
1507 delete main_canvas;
1508 }
1509
1510 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) {
1511 //this function saves the pad being passed as well as a new one including the SysRatio.
1512 TVirtualPad *canvas = (TVirtualPad*) orig_canvas->Clone("TempCanvas");//otherwise the main_canvas will own our pad and destroy it upon deletion
1513 CompleteSave(canvas,savemeas);
1514
1515 float bottommargin=gStyle->GetPadBottomMargin();
1516 float canvas_height=gStyle->GetCanvasDefH();
1517 float canvas_width=gStyle->GetCanvasDefW();
1518 float ratiospace=0.25;// space the ratio should take up (relative to original pad)
1519
1520 float ratiobottommargin=0.3;
1521 float ratiotopmargin=0.1;
1522
1523 float xstretchfactor=((1-ratiospace)*(1-gStyle->GetPadTopMargin()))/((1)*ratiospace);
1524
1525 TCanvas *main_canvas = new TCanvas("main_canvas","main_canvas",(Int_t)canvas_width,(Int_t)(canvas_height*(1+ratiospace)));
1526 TPad *mainpad = new TPad("mainpad","mainpad",0,1-(1.0/(1+ratiospace)),1,1);//top (main) pad
1527 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
1528 TPad *bottompad = new TPad("bottompad", "Ratio Pad",0,0,1,(1-(1-bottommargin)/(1+ratiospace))-0.015); //bottom pad
1529
1530 main_canvas->Range(0,0,1,1);
1531 main_canvas->SetBorderSize(0);
1532 main_canvas->SetFrameFillColor(0);
1533
1534 mainpad->Draw();
1535 mainpad->cd();
1536 mainpad->Range(0,0,1,1);
1537 mainpad->SetFillColor(kWhite);
1538 mainpad->SetBorderSize(0);
1539 mainpad->SetFrameFillColor(0);
1540 canvas->Range(0,0,1,1);
1541 canvas->Draw("same");
1542 mainpad->Modified();
1543 main_canvas->cd();
1544 coverpad->Draw();
1545 coverpad->cd();
1546 coverpad->Range(0,0,1,1);
1547 coverpad->SetFillColor(kWhite);
1548 coverpad->SetBorderSize(0);
1549 coverpad->SetFrameFillColor(0);
1550 coverpad->Modified();
1551 main_canvas->cd();
1552 bottompad->SetTopMargin(ratiotopmargin);
1553 bottompad->SetBottomMargin(ratiobottommargin);
1554 bottompad->Draw();
1555 bottompad->cd();
1556 bottompad->Range(0,0,1,1);
1557 bottompad->SetFillColor(kWhite);
1558 TH1F *ratio = (TH1F*)nominator->Clone(GetNumericHistoName().c_str());
1559 ratio->Divide(denominator);
1560
1561
1562 TGraphAsymmErrors *eratio;
1563 TGraphAsymmErrors *SysEnvelope = new TGraphAsymmErrors();
1564
1565 if(syshisto && !do_bpred_ratio) {
1566 for(int i=1;i<=syshisto->GetNbinsX();i++) {
1567 float dx=syshisto->GetBinWidth(i)/2.0;
1568 float dy=syshisto->GetBinContent(i);
1569 if(dy<0.01) dy=0.07;
1570 SysEnvelope->SetPoint(i-1,syshisto->GetBinCenter(i),1.0);
1571 SysEnvelope->SetPointError(i-1,dx,dx,dy,dy);
1572 }
1573 SysEnvelope->SetFillColor(TColor::GetColor("#006DE1"));
1574 }
1575
1576 ratio->SetTitle("");
1577 ratio->GetYaxis()->SetRangeUser(0.0,2.0);
1578 if(do_bpred_ratio) ratio->GetYaxis()->SetRangeUser(0.0,2.0);
1579 if(extendrange) ratio->GetYaxis()->SetRangeUser(0.0,4.0);
1580 ratio->GetXaxis()->SetTitle(nominator->GetXaxis()->GetTitle());
1581 ratio->GetXaxis()->CenterTitle();
1582 ratio->GetYaxis()->SetTitle(yaxistitle.c_str());
1583 ratio->GetYaxis()->SetTitleOffset(0.4);
1584 ratio->GetYaxis()->CenterTitle();
1585 ratio->SetStats(0);
1586 ratio->GetXaxis()->SetLabelSize(xstretchfactor*ratio->GetXaxis()->GetLabelSize());
1587 ratio->GetYaxis()->SetLabelSize(xstretchfactor*ratio->GetYaxis()->GetLabelSize());
1588 ratio->GetXaxis()->SetTitleSize(xstretchfactor*gStyle->GetTitleSize());
1589 ratio->GetYaxis()->SetTitleSize(xstretchfactor*gStyle->GetTitleSize());
1590 ratio->GetYaxis()->SetNdivisions(502,false);
1591 ratio->SetFillColor(TColor::GetColor("#58D3F7"));
1592 ratio->Draw("e1");
1593
1594 if(syshisto!=0) {
1595 SysEnvelope->SetFillColor(TColor::GetColor("#FE9A2E"));
1596 SysEnvelope->Draw("2,same");
1597 ratio->Draw("e1,same");
1598 } else {
1599 eratio->Draw("1");
1600 }
1601 ratio->Draw("same,axis");
1602 TLine *oneline = new TLine(ratio->GetXaxis()->GetBinLowEdge(1),1,ratio->GetXaxis()->GetBinLowEdge(ratio->GetNbinsX())+ratio->GetXaxis()->GetBinWidth(ratio->GetNbinsX()),1);
1603 oneline->SetLineStyle(2);
1604 oneline->SetLineColor(kBlue);
1605 oneline->Draw("same");
1606
1607 main_canvas->cd();
1608 main_canvas->Modified();
1609 main_canvas->cd();
1610 main_canvas->SetSelected(main_canvas);
1611
1612 CompleteSave(main_canvas,savemeas+"_withSysRatio");
1613 bottompad->cd();
1614
1615 Double_t chi2;
1616 Int_t ndf,igood;
1617 Double_t chi2prob = MarcosChi2TestX(nominator,denominator,chi2,ndf,igood,"UW");
1618
1619 stringstream Chi2text;
1620 Chi2text << "#chi^{2} / ndf: " << chi2 << " / " << ndf;
1621 stringstream Chi2probtext;
1622 Chi2probtext << "#chi^{2} prob: " << chi2prob;
1623 TText* chi2box = write_text(0.02,0.11,Chi2text.str());
1624 chi2box->SetTextSize(0.08);
1625 chi2box->SetTextAlign(11);
1626 chi2box->Draw();
1627 TText* chi2probbox = write_text(0.02,0.04,Chi2probtext.str());
1628 chi2probbox->SetTextSize(0.08);
1629 chi2probbox->SetTextAlign(11);
1630 chi2probbox->Draw();
1631
1632 stringstream CompRatio;
1633 CompRatio << "Ratio: " << nominator->Integral() << " / " << denominator->Integral() << " \n " << nominator->Integral()/denominator->Integral();
1634 TText *CompleteRatio = write_text(0.98,0.04,CompRatio.str());
1635 CompleteRatio->SetTextSize(0.08);
1636 CompleteRatio->SetTextAlign(31);
1637 CompleteRatio->Draw();
1638
1639 CompleteSave(main_canvas,savemeas+"_withSysRatio_and_Chi2");
1640 delete main_canvas;
1641 delete ratio;
1642 }
1643
1644 TH1F* CollapseStack(THStack stack,TString hname="CollapsedStack") {
1645 TH1F *bhist = ((TH1F*)((stack.GetHists())->At(0)));
1646 TH1F *basehisto = (TH1F*)bhist->Clone(hname);
1647 TIter next(stack.GetHists());
1648 TH1F *h;
1649 int counter=0;
1650 while ((h=(TH1F*)next())) {
1651 counter++;
1652 if(counter==1) continue;
1653 basehisto->Add(h);
1654 }
1655 return basehisto;
1656 }
1657
1658 void Save_With_Ratio(TH1F *nominator, THStack denominator, TVirtualPad *canvas, string savemeas, bool do_bpred_ratio=false) {
1659 TH1F *denominator_histo = (TH1F*) CollapseStack(denominator);
1660 Save_With_Ratio(nominator, denominator_histo, canvas, savemeas, do_bpred_ratio);
1661 delete denominator_histo;
1662 }
1663
1664 void flag_this_change(string function, int line, int checked=0) {
1665 stringstream peakmodificationwarning;
1666 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 :-) ";
1667 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)";
1668 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.";
1669
1670
1671 if(checked==0) write_warning(function,peakmodificationwarning.str());
1672 // if(checked==1) write_info(function,peakmodificationwarning.str());
1673 peakmodificationwarning << " This modification has been checked and the changes have been reproduced. Checks completed.";
1674 if(checked==2) write_info(function,peakmodificationwarning.str());
1675 }
1676
1677 void write_analysis_type(bool isonpeak, bool dobtag) {
1678 //http://www.network-science.de/ascii/, ogre
1679 if(!PlottingSetup::publicmode) {
1680 if(isonpeak) {
1681 //font: big
1682 dout << "\033[1;34m" << endl;
1683 dout << " _ __________ " << endl;
1684 dout << " | |___ / _ \\ " << endl;
1685 dout << " /\\ ___ | | / /| |_) | " << endl;
1686 dout << " / \\ / _|_ | | / / | _ < " << endl;
1687 dout << " / \\ | (_| |__| |/ /__| |_) | " << endl;
1688 dout << " \\___|\\____//_____|____/ " << endl;
1689 } else {
1690 //font: big
1691 dout << "\033[1;33m" << endl;
1692 dout << " _ _ __________ " << endl;
1693 dout << " (_) | |___ / _ \\ " << endl;
1694 dout << " /\\ _ | | / /| |_) | " << endl;
1695 dout << " /\\/ \\ | |_ | | / / | _ < " << endl;
1696 dout << " / \\ | | |__| |/ /__| |_) | " << endl;
1697 dout << " |_|\\____//_____|____/ " << endl;
1698 }
1699
1700 if(dobtag) {
1701 //font: big
1702 dout << "\033[1;32m \\ / " << endl;
1703 dout << " \\ o ^ o / " << endl;
1704 dout << " \\ ( ) / " << endl;
1705 dout << " ____________(%%%%%%%)____________ _ _ __________ " << endl;
1706 dout << " ( / / )%%%%%%%( \\ \\ ) | | | |___ / _ \\ " << endl;
1707 dout << " (___/___/__/ \\__\\___\\___) | |__ | | / /| |_) | " << endl;
1708 dout << " ( / /(%%%%%%%)\\ \\ ) | '_ \\ _ | | / / | _ < " << endl;
1709 dout << " (__/___/ (%%%%%%%) \\___\\__) | |_) | |__| |/ /__| |_) | " << endl;
1710 dout << " /( )\\ |_.__/ \\____//_____|____/ " << endl;
1711 dout << " / (%%%%%) \\ " << endl;
1712 dout << " (%%%) " << endl;
1713 dout << " ! " << endl;
1714 }
1715 } else {
1716 //we're in public! don't advertise what we're up to :-)
1717 dout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
1718 dout << " Starting the analysis " << endl;
1719 dout << " i:" << !isonpeak << " , b " << dobtag << endl;
1720 dout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
1721 }
1722 dout << "\033[0m" << endl;
1723
1724 }
1725
1726
1727 vector<string> StringSplit(string str, string delim)
1728 {
1729 vector<string> results;
1730
1731 int cutAt;
1732 while( (cutAt = str.find_first_of(delim)) != (int)str.npos )
1733 {
1734 if(cutAt > 0)
1735 {
1736 results.push_back(str.substr(0,cutAt));
1737 }
1738 str = str.substr(cutAt+1);
1739 }
1740 if(str.length() > 0)
1741 {
1742 results.push_back(str);
1743 }
1744 return results;
1745 }
1746
1747 void manually_set_jzb_cuts(vector<float> &jzb_cut,string jzbcut_string) {
1748 vector<string> jzbcutvector = StringSplit(jzbcut_string,",");
1749 for(int i=0;i<(int)jzbcutvector.size();i++) {
1750 jzb_cut.push_back(atoi(jzbcutvector[i].c_str()));
1751 dout << "Added a JZB cut manually at " << atoi(jzbcutvector[i].c_str()) << endl;
1752 }
1753 }
1754
1755 void process_directory(TString directory, vector<string> &files)
1756 {
1757 DIR *dp;
1758 struct dirent *ep;
1759
1760 dp = opendir (directory);
1761 if (dp != NULL)
1762 {
1763 while ((ep = readdir (dp)))
1764 {
1765 string filename=(string)ep->d_name;
1766 if((int)filename.find(".root")!=-1)
1767 {
1768 files.push_back(string(directory)+filename);
1769 }
1770 }
1771 (void) closedir (dp);
1772 }
1773 else
1774 perror ("Couldn't open the directory");
1775 }
1776
1777 void ClearHisto(TH1* histo) {
1778 for(int ix=0;ix<=histo->GetNbinsX()+1;ix++) {//also reset over- and underflow
1779 histo->SetBinContent(ix,0);
1780 histo->SetBinContent(ix,0);
1781 }
1782 }
1783
1784 void AddSquared(TH1F *histo, TH1F *addthis, float weight) {
1785 for(int ix=1;ix<=addthis->GetNbinsX()+1;ix++) {//also include over- and underflow
1786 float bincenter=addthis->GetBinCenter(ix);
1787 int nBinHisto= histo->FindBin(bincenter);
1788 float old_content=histo->GetBinContent(nBinHisto);
1789 histo->SetBinContent(nBinHisto,old_content+((addthis->GetBinContent(ix))*(addthis->GetBinContent(ix))*weight));
1790 }
1791 }
1792
1793 void SQRT(TH1* histo) {
1794 for(int ix=0;ix<=histo->GetNbinsX()+1;ix++) {//also include over- and underflow
1795 histo->SetBinContent(ix,TMath::Sqrt(histo->GetBinContent(ix)));
1796 }
1797 }
1798
1799 /*string GetCompleteHostname() {
1800 struct addrinfo hints, *info, *p;
1801 int gai_result;
1802 char hostname[1024];
1803 hostname[1023] = '\0';
1804 gethostname(hostname, 1023);
1805
1806 string answer="GetCompleteHostname_ERROR";
1807
1808 memset(&hints, 0, sizeof hints);
1809 hints.ai_family = AF_UNSPEC;
1810 hints.ai_socktype = SOCK_STREAM;
1811 hints.ai_flags = AI_CANONNAME;
1812
1813 if ((gai_result = getaddrinfo(hostname, "http", &hints, &info)) != 0) {
1814 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(gai_result));
1815 }
1816
1817 for(p = info; p != NULL; p = p->ai_next) {
1818 answer=p->ai_canonname;
1819 printf("hostname: %s\n", p->ai_canonname);
1820 }
1821 return answer;
1822 }*/
1823
1824 const char* concatenate (const char* a, const char* b) {
1825 stringstream bla;
1826 bla << a << b;
1827 return bla.str().c_str();
1828 }
1829
1830
1831 string ReplaceCharacter(string originalstring,string replacethis,string replacewiththis)
1832 {
1833 int pos = originalstring.find(replacethis);
1834 while(pos != -1) {
1835 originalstring.replace(pos, replacewiththis.length(), replacewiththis);
1836 pos = originalstring.find(replacethis);
1837 }
1838 return originalstring;
1839 }
1840
1841 string removefunnystring(string name) {
1842 name=ReplaceCharacter(name,"[","_");
1843 name=ReplaceCharacter(name,"]","_");
1844 name=ReplaceCharacter(name,"{","_");
1845 name=ReplaceCharacter(name,"}","_");
1846 name=ReplaceCharacter(name,"(","_");
1847 name=ReplaceCharacter(name,")","_");
1848 name=ReplaceCharacter(name," ","_");
1849 name=ReplaceCharacter(name,".","_");
1850 name=ReplaceCharacter(name,",","_");
1851 name=ReplaceCharacter(name,";","_");
1852 name=ReplaceCharacter(name,":","_");
1853 name=ReplaceCharacter(name,"'","_");
1854 name=ReplaceCharacter(name,"$","_");
1855 name=ReplaceCharacter(name,"@","_");
1856 name=ReplaceCharacter(name,"#","_");
1857 name=ReplaceCharacter(name,"+","_");
1858 name=ReplaceCharacter(name,"-","_");
1859 name=ReplaceCharacter(name,"/","_");
1860 return name;
1861 }
1862
1863 TPolyLine* GetFitUncertaintyShape(TF1 *fit, float low, float high,float x0,float x1) {
1864 int nPoints=1000;
1865 double x[nPoints+1];
1866 double y[nPoints];
1867
1868 float par1=fit->GetParameter(0);
1869 float dpar1=fit->GetParError(0);
1870 float par2=fit->GetParameter(1);
1871 float dpar2=fit->GetParError(1);
1872
1873 float step=(x1-x0)/(nPoints/2.0 -1);
1874 for(int i=0;i<nPoints/2.0;i++) {
1875 x[i]=x0+i*step;
1876 y[i]=(par1+x[i]*par2) - sqrt(dpar1*dpar1+dpar2*dpar2*x[i]*x[i]);
1877 x[nPoints-1-i]=x[i];
1878 y[nPoints-1-i]=(par1+x[i]*par2) + sqrt(dpar1*dpar1+dpar2*dpar2*x[i]*x[i]);
1879 if(y[i]<low) y[i]=low;
1880 if(y[i]>high) y[i]=high;
1881 if(y[nPoints-1-i]<low) y[nPoints-1-i]=low;
1882 if(y[nPoints-1-i]>high) y[nPoints-1-i]=high;
1883 }
1884
1885 x[nPoints]=x[0];
1886 y[nPoints]=y[0];
1887
1888 TPolyLine *l = new TPolyLine(nPoints+1,x,y);
1889 l->SetFillColor(TColor::GetColor("#5858FA"));
1890 l->SetLineColor(TColor::GetColor("#5858FA"));
1891 l->SetLineWidth(1);
1892 return l;
1893 }
1894
1895 //code for ReplaceAll copied from
1896 //http://stackoverflow.com/questions/5343190/c-how-do-i-replace-all-instances-of-of-a-string-with-another-string
1897 string ReplaceAll(string str, string from, string to) {
1898 size_t start_pos = 0;
1899 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
1900 str.replace(start_pos, from.length(), to);
1901 start_pos += to.length(); // ...
1902 }
1903 return str;
1904 }
1905
1906 TPolyLine* GetFitUncertaintyShape(TH1 *histo, string fitname, float low, float high) {
1907 TF1 *fit = (TF1*)histo->GetFunction(fitname.c_str());
1908 if(!fit) {
1909 cout << "CANNOT PRODUCE FIT UNCERTAINTY AS THERE IS NO FIT CALLED " << fitname << " IN " << histo->GetName() << endl;
1910 return NULL;
1911 }
1912 float x0=histo->GetBinLowEdge(1);
1913 float x1=histo->GetBinLowEdge(histo->GetNbinsX())+histo->GetBinWidth(histo->GetNbinsX());
1914 return GetFitUncertaintyShape(fit, low, high,x0,x1);
1915 }
1916
1917 TPolyLine* GetFitUncertaintyShape(TGraphErrors *gr, string fitname, float low, float high, float minx=-999, float maxx=-999) {
1918 TF1 *fit = (TF1*)gr->GetFunction(fitname.c_str());
1919 if(!fit) {
1920 cout << "CANNOT PRODUCE FIT UNCERTAINTY AS THERE IS NO FIT CALLED " << fitname << " IN " << gr->GetName() << endl;
1921 return NULL;
1922 }
1923 double x,y;
1924 gr->GetPoint(0,x,y);
1925 float min=x;
1926 gr->GetPoint(gr->GetN()-1,x,y);
1927 float max=x;
1928 if(minx>-999 && maxx>-999 && minx<maxx) {
1929 max=maxx;
1930 min=minx;
1931 }
1932 return GetFitUncertaintyShape(fit, low, high,min,max);
1933 }
1934
1935 stringstream all_bugs;
1936
1937 void bug_tracker(string function, int line, string description) {
1938 cout << "\033[1;31m .-. " << endl;
1939 cout << " o \\ .-. " << endl;
1940 cout << " .----.' \\ " << endl;
1941 cout << " .'o) / `. o " << endl;
1942 cout << " / | " << endl;
1943 cout << " \\_) /-. " << endl;
1944 cout << " '_.` \\ \\ " << endl;
1945 cout << " `. | \\ " << endl;
1946 cout << " | \\ | " << endl;
1947 cout << " .--/`-. / / " << endl;
1948 cout << " .'.-/`-. `. .\\| " << endl;
1949 cout << " /.' /`._ `- '-. " << endl;
1950 cout << " ____(|__/`-..`- '-._ \\ " << endl;
1951 cout << " |`------.'-._ ` ||\\ \\ " << endl;
1952 cout << " || # /-. ` / || \\| " << endl;
1953 cout << " || #/ `--' / /_::_|)__ " << endl;
1954 cout << " `|____|-._.-` / ||`--------` " << endl;
1955 cout << " \\-.___.` | / || # | " << endl;
1956 cout << " \\ | | || # # | " << endl;
1957 cout << " /`.___.'\\ |.`|________| " << endl;
1958 cout << " | /`.__.'|'.` " << endl;
1959 cout << " __/ \\ __/ \\ " << endl;
1960 cout << " /__.-.) /__.-.) LGB " << endl;
1961 cout << "" << endl;
1962 // bug ascii from : http://www.chris.com/ASCII/index.php?art=animals/insects/other
1963 cout << "There is a bug in " << function << " on line " << line << endl;
1964 cout << "The bug description is : " << description << endl;
1965 all_bugs << "There is a bug in " << function << " on line " << line << endl;
1966 all_bugs << "The bug description is : " << description << " \033[0m" << endl;
1967 }
1968
1969 //TODO: Write a bug summary at the end.
1970
1971 float pSTAR(float mglu, float mlsp, float mchi2) {
1972 float mz=91.0;
1973 float res=((mchi2*mchi2)-(mlsp+mz)*(mlsp+mz));
1974 res*=((mchi2*mchi2)-(mlsp-mz)*(mlsp-mz));
1975 res=TMath::Sqrt(res)/(2*mchi2);
1976 return res;
1977 }
1978
1979 float generalizedpSTAR(float massmother, float massdaughter1, float massdaughter2) {
1980 float res=((massmother*massmother)-(massdaughter1+massdaughter2)*(massdaughter1+massdaughter2));
1981 res*=((massmother*massmother)-(massdaughter1-massdaughter2)*(massdaughter1-massdaughter2));
1982 res=TMath::Sqrt(res)/(2*massmother);
1983 return res;
1984 }
1985
1986 void FindMinMax(TGraphErrors *gr, float &min, float &max) {
1987 double x,y;
1988 gr->GetPoint(0,x,y);
1989 min=500*y;
1990 max=0.0002*y;
1991 for(int i=0;i<gr->GetN();i++) {
1992 gr->GetPoint(i,x,y);
1993 cout << "Point at " << x << "/" << y << " with error " << gr->GetErrorY(i) << endl;
1994 float potmin=y-1.5*gr->GetErrorY(i); // taking 1.5 times the error to allow for enough space to present the plot
1995 float potmax=y+1.5*gr->GetErrorY(i); // taking 1.5 times the error to allow for enough space to present the plot
1996 if(potmin<min) min=potmin;
1997 if(potmax>max) max=potmax;
1998 }
1999 }
2000
2001
2002 void CleanLegends() {
2003 for(int ihist=(int)PlottingSetup::FakeHistoHeap.size()-1;ihist>=0;ihist--) {
2004 PlottingSetup::FakeHistoHeap[ihist]->Delete();
2005 PlottingSetup::FakeHistoHeap.pop_back();
2006 }
2007 }