ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/GeneralToolBox.C
Revision: 1.44
Committed: Tue May 21 11:50:31 2013 UTC (11 years, 11 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.43: +7 -2 lines
Log Message:
Added option for iJZB analysis; added possibility to use WriteYield function to get yields in general and not only have them printed on screen

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