ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.23
Committed: Thu Nov 22 09:01:30 2012 UTC (12 years, 5 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.22: +40 -0 lines
Log Message:
Added function to draw fit with its uncertainty

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