ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.3
Committed: Fri Mar 2 08:37:58 2012 UTC (13 years, 2 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.2: +8 -0 lines
Log Message:
Added a generalized pstar function (not only for chi2->chi1 z but also possible for gluino->chi2+jets

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