ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.18
Committed: Wed Sep 5 14:06:38 2012 UTC (12 years, 8 months ago) by fronga
Content type: text/plain
Branch: MAIN
Changes since 1.17: +2 -1 lines
Log Message:
New parameter to open the box.

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 = false;
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.2)<20") return "|m_{l^{+}l^{-}}-m_{Z}|<20";
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.5,1.5);
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
1504 TH1F* CollapseStack(THStack stack) {
1505 TH1F *bhist = ((TH1F*)((stack.GetHists())->At(0)));
1506 TH1F *basehisto = (TH1F*)bhist->Clone("base");
1507 TIter next(stack.GetHists());
1508 TH1F *h;
1509 int counter=0;
1510 while ((h=(TH1F*)next())) {
1511 counter++;
1512 if(counter==1) continue;
1513 basehisto->Add(h);
1514 }
1515 return basehisto;
1516 }
1517
1518 void save_with_ratio(TH1F *nominator, THStack denominator, TVirtualPad *canvas, string savemeas, bool do_bpred_ratio=false) {
1519 save_with_ratio(nominator, CollapseStack(denominator), canvas, savemeas, do_bpred_ratio);
1520 }
1521
1522 void flag_this_change(string function, int line, int checked=0) {
1523 stringstream peakmodificationwarning;
1524 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 :-) ";
1525 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)";
1526 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.";
1527
1528
1529 if(checked==0) write_warning(function,peakmodificationwarning.str());
1530 // if(checked==1) write_info(function,peakmodificationwarning.str());
1531 peakmodificationwarning << " This modification has been checked and the changes have been reproduced. Checks completed.";
1532 if(checked==2) write_info(function,peakmodificationwarning.str());
1533 }
1534
1535 void write_analysis_type(bool isonpeak, bool dobtag) {
1536 //http://www.network-science.de/ascii/, ogre
1537 if(!PlottingSetup::publicmode) {
1538 if(isonpeak) {
1539 //font: big
1540 dout << "\033[1;34m" << endl;
1541 dout << " _ __________ " << endl;
1542 dout << " | |___ / _ \\ " << endl;
1543 dout << " /\\ ___ | | / /| |_) | " << endl;
1544 dout << " / \\ / _|_ | | / / | _ < " << endl;
1545 dout << " / \\ | (_| |__| |/ /__| |_) | " << endl;
1546 dout << " \\___|\\____//_____|____/ " << endl;
1547 } else {
1548 //font: big
1549 dout << "\033[1;33m" << endl;
1550 dout << " _ _ __________ " << endl;
1551 dout << " (_) | |___ / _ \\ " << endl;
1552 dout << " /\\ _ | | / /| |_) | " << endl;
1553 dout << " /\\/ \\ | |_ | | / / | _ < " << endl;
1554 dout << " / \\ | | |__| |/ /__| |_) | " << endl;
1555 dout << " |_|\\____//_____|____/ " << endl;
1556 }
1557
1558 if(dobtag) {
1559 //font: big
1560 dout << "\033[1;32m \\ / " << endl;
1561 dout << " \\ o ^ o / " << endl;
1562 dout << " \\ ( ) / " << endl;
1563 dout << " ____________(%%%%%%%)____________ _ _ __________ " << endl;
1564 dout << " ( / / )%%%%%%%( \\ \\ ) | | | |___ / _ \\ " << endl;
1565 dout << " (___/___/__/ \\__\\___\\___) | |__ | | / /| |_) | " << endl;
1566 dout << " ( / /(%%%%%%%)\\ \\ ) | '_ \\ _ | | / / | _ < " << endl;
1567 dout << " (__/___/ (%%%%%%%) \\___\\__) | |_) | |__| |/ /__| |_) | " << endl;
1568 dout << " /( )\\ |_.__/ \\____//_____|____/ " << endl;
1569 dout << " / (%%%%%) \\ " << endl;
1570 dout << " (%%%) " << endl;
1571 dout << " ! " << endl;
1572 }
1573 } else {
1574 //we're in public! don't advertise what we're up to :-)
1575 dout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
1576 dout << " Starting the analysis " << endl;
1577 dout << " i:" << !isonpeak << " , b " << dobtag << endl;
1578 dout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
1579 }
1580 dout << "\033[0m" << endl;
1581
1582 }
1583
1584
1585 vector<string> StringSplit(string str, string delim)
1586 {
1587 vector<string> results;
1588
1589 int cutAt;
1590 while( (cutAt = str.find_first_of(delim)) != (int)str.npos )
1591 {
1592 if(cutAt > 0)
1593 {
1594 results.push_back(str.substr(0,cutAt));
1595 }
1596 str = str.substr(cutAt+1);
1597 }
1598 if(str.length() > 0)
1599 {
1600 results.push_back(str);
1601 }
1602 return results;
1603 }
1604
1605 void manually_set_jzb_cuts(vector<float> &jzb_cut,string jzbcut_string) {
1606 vector<string> jzbcutvector = StringSplit(jzbcut_string,",");
1607 for(int i=0;i<(int)jzbcutvector.size();i++) {
1608 jzb_cut.push_back(atoi(jzbcutvector[i].c_str()));
1609 dout << "Added a JZB cut manually at " << atoi(jzbcutvector[i].c_str()) << endl;
1610 }
1611 }
1612
1613 void process_directory(TString directory, vector<string> &files)
1614 {
1615 DIR *dp;
1616 struct dirent *ep;
1617
1618 dp = opendir (directory);
1619 if (dp != NULL)
1620 {
1621 while ((ep = readdir (dp)))
1622 {
1623 string filename=(string)ep->d_name;
1624 if((int)filename.find(".root")!=-1)
1625 {
1626 files.push_back(string(directory)+filename);
1627 }
1628 }
1629 (void) closedir (dp);
1630 }
1631 else
1632 perror ("Couldn't open the directory");
1633 }
1634
1635 void ClearHisto(TH1* histo) {
1636 for(int ix=0;ix<=histo->GetNbinsX()+1;ix++) {//also reset over- and underflow
1637 histo->SetBinContent(ix,0);
1638 histo->SetBinContent(ix,0);
1639 }
1640 }
1641
1642 void AddSquared(TH1F *histo, TH1F *addthis, float weight) {
1643 for(int ix=1;ix<=addthis->GetNbinsX()+1;ix++) {//also include over- and underflow
1644 float bincenter=addthis->GetBinCenter(ix);
1645 int nBinHisto= histo->FindBin(bincenter);
1646 float old_content=histo->GetBinContent(nBinHisto);
1647 histo->SetBinContent(nBinHisto,old_content+((addthis->GetBinContent(ix))*(addthis->GetBinContent(ix))*weight));
1648 }
1649 }
1650
1651 void SQRT(TH1* histo) {
1652 for(int ix=0;ix<=histo->GetNbinsX()+1;ix++) {//also include over- and underflow
1653 histo->SetBinContent(ix,TMath::Sqrt(histo->GetBinContent(ix)));
1654 }
1655 }
1656
1657 /*string GetCompleteHostname() {
1658 struct addrinfo hints, *info, *p;
1659 int gai_result;
1660 char hostname[1024];
1661 hostname[1023] = '\0';
1662 gethostname(hostname, 1023);
1663
1664 string answer="GetCompleteHostname_ERROR";
1665
1666 memset(&hints, 0, sizeof hints);
1667 hints.ai_family = AF_UNSPEC;
1668 hints.ai_socktype = SOCK_STREAM;
1669 hints.ai_flags = AI_CANONNAME;
1670
1671 if ((gai_result = getaddrinfo(hostname, "http", &hints, &info)) != 0) {
1672 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(gai_result));
1673 }
1674
1675 for(p = info; p != NULL; p = p->ai_next) {
1676 answer=p->ai_canonname;
1677 printf("hostname: %s\n", p->ai_canonname);
1678 }
1679 return answer;
1680 }*/
1681
1682 const char* concatenate (const char* a, const char* b) {
1683 stringstream bla;
1684 bla << a << b;
1685 return bla.str().c_str();
1686 }
1687
1688
1689 string ReplaceCharacter(string originalstring,string replacethis,string replacewiththis)
1690 {
1691 int pos = originalstring.find(replacethis);
1692 while(pos != -1) {
1693 originalstring.replace(pos, replacewiththis.length(), replacewiththis);
1694 pos = originalstring.find(replacethis);
1695 }
1696 return originalstring;
1697 }
1698
1699 string removefunnystring(string name) {
1700 name=ReplaceCharacter(name,"[","_");
1701 name=ReplaceCharacter(name,"]","_");
1702 name=ReplaceCharacter(name,"{","_");
1703 name=ReplaceCharacter(name,"}","_");
1704 name=ReplaceCharacter(name,".","_");
1705 name=ReplaceCharacter(name,",","_");
1706 name=ReplaceCharacter(name,";","_");
1707 name=ReplaceCharacter(name,":","_");
1708 name=ReplaceCharacter(name,"'","_");
1709 name=ReplaceCharacter(name,"$","_");
1710 name=ReplaceCharacter(name,"@","_");
1711 name=ReplaceCharacter(name,"#","_");
1712 name=ReplaceCharacter(name,"+","_");
1713 name=ReplaceCharacter(name,"-","_");
1714 name=ReplaceCharacter(name,"/","_");
1715 return name;
1716 }
1717
1718 stringstream all_bugs;
1719
1720 void bug_tracker(string function, int line, string description) {
1721 cout << "\033[1;31m .-. " << endl;
1722 cout << " o \\ .-. " << endl;
1723 cout << " .----.' \\ " << endl;
1724 cout << " .'o) / `. o " << endl;
1725 cout << " / | " << endl;
1726 cout << " \\_) /-. " << endl;
1727 cout << " '_.` \\ \\ " << endl;
1728 cout << " `. | \\ " << endl;
1729 cout << " | \\ | " << endl;
1730 cout << " .--/`-. / / " << endl;
1731 cout << " .'.-/`-. `. .\\| " << endl;
1732 cout << " /.' /`._ `- '-. " << endl;
1733 cout << " ____(|__/`-..`- '-._ \\ " << endl;
1734 cout << " |`------.'-._ ` ||\\ \\ " << endl;
1735 cout << " || # /-. ` / || \\| " << endl;
1736 cout << " || #/ `--' / /_::_|)__ " << endl;
1737 cout << " `|____|-._.-` / ||`--------` " << endl;
1738 cout << " \\-.___.` | / || # | " << endl;
1739 cout << " \\ | | || # # | " << endl;
1740 cout << " /`.___.'\\ |.`|________| " << endl;
1741 cout << " | /`.__.'|'.` " << endl;
1742 cout << " __/ \\ __/ \\ " << endl;
1743 cout << " /__.-.) /__.-.) LGB " << endl;
1744 cout << "" << endl;
1745 // bug ascii from : http://www.chris.com/ASCII/index.php?art=animals/insects/other
1746 cout << "There is a bug in " << function << " on line " << line << endl;
1747 cout << "The bug description is : " << description << endl;
1748 all_bugs << "There is a bug in " << function << " on line " << line << endl;
1749 all_bugs << "The bug description is : " << description << " \033[0m" << endl;
1750 }
1751
1752 //TODO: Write a bug summary at the end.
1753
1754 float pSTAR(float mglu, float mlsp, float mchi2) {
1755 float mz=91.2;
1756 float res=((mchi2*mchi2)-(mlsp+mz)*(mlsp+mz));
1757 res*=((mchi2*mchi2)-(mlsp-mz)*(mlsp-mz));
1758 res=TMath::Sqrt(res)/(2*mchi2);
1759 return res;
1760 }
1761
1762 float generalizedpSTAR(float massmother, float massdaughter1, float massdaughter2) {
1763 float res=((massmother*massmother)-(massdaughter1+massdaughter2)*(massdaughter1+massdaughter2));
1764 res*=((massmother*massmother)-(massdaughter1-massdaughter2)*(massdaughter1-massdaughter2));
1765 res=TMath::Sqrt(res)/(2*massmother);
1766 return res;
1767 }