ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.24
Committed: Fri Nov 23 12:12:03 2012 UTC (12 years, 5 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.23: +50 -10 lines
Log Message:
Added function providing nice lower and upper range of a tgrapherror; added function to draw the correct uncertainty of a tf1 based on a polynomial

File Contents

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