ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.46
Committed: Fri Jun 28 15:03:02 2013 UTC (11 years, 10 months ago) by buchmann
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.45: +1 -0 lines
Log Message:
Updated files for migration to git (sync)

File Contents

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