ROOT  6.06/09
Reference Guide
HybridPlot.cxx
Go to the documentation of this file.
1 // @(#)root/hist:$Id$
2 
3 ////////////////////////////////////////////////////////////////////////////////
4 
5 
6 
7 #include "assert.h"
8 #include <cmath>
9 #include <iostream>
10 #include <map>
11 
12 #include "RooStats/HybridPlot.h"
13 #include "TStyle.h"
14 #include "TF1.h"
15 #include "TAxis.h"
16 #include "TH1.h"
17 #include "TLine.h"
18 #include "TLegend.h"
19 #include "TFile.h"
20 #include "TVirtualPad.h"
21 
22 #include <algorithm>
23 
24 /// To build the THtml documentation
25 using namespace std;
26 
28 
29 using namespace RooStats;
30 
31 /*----------------------------------------------------------------------------*/
32 
33 HybridPlot::HybridPlot(const char* name,
34  const char* title,
35  const std::vector<double> & sb_vals,
36  const std::vector<double> & b_vals,
37  double testStat_data,
38  int n_bins,
39  bool verbosity):
40  TNamed(name,title),
41  fSb_histo(NULL),
42  fSb_histo_shaded(NULL),
43  fB_histo(NULL),
44  fB_histo_shaded(NULL),
45  fData_testStat_line(0),
46  fLegend(0),
47  fPad(0),
48  fVerbose(verbosity)
49 {
50  // HybridPlot constructor
51 
52  int nToysSB = sb_vals.size();
53  int nToysB = sb_vals.size();
54  assert (nToysSB >0);
55  assert (nToysB >0);
56 
57  // Get the max and the min of the plots
58  double min = *std::min_element(sb_vals.begin(), sb_vals.end());
59  double max = *std::max_element(sb_vals.begin(), sb_vals.end());
60 
61  double min_b = *std::min_element(b_vals.begin(), b_vals.end());
62  double max_b = *std::max_element(b_vals.begin(), b_vals.end());
63 
64 
65  if ( min_b < min) min = min_b;
66  if ( max_b > max) max = max_b;
67 
68  if (testStat_data<min) min = testStat_data;
69  if (testStat_data>max) max = testStat_data;
70 
71  min *= 1.1;
72  max *= 1.1;
73 
74  // Build the histos
75 
76  fSb_histo = new TH1F ("SB_model",title,n_bins,min,max);
77  fSb_histo->SetTitle(fSb_histo->GetTitle());
78  fSb_histo->SetLineColor(kBlue);
79  fSb_histo->GetXaxis()->SetTitle("test statistics");
80  fSb_histo->SetLineWidth(2);
81 
82  fB_histo = new TH1F ("B_model",title,n_bins,min,max);
83  fB_histo->SetTitle(fB_histo->GetTitle());
84  fB_histo->SetLineColor(kRed);
85  fB_histo->GetXaxis()->SetTitle("test statistics");
86  fB_histo->SetLineWidth(2);
87 
88  for (int i=0;i<nToysSB;++i) fSb_histo->Fill(sb_vals[i]);
89  for (int i=0;i<nToysB;++i) fB_histo->Fill(b_vals[i]);
90 
91  double histos_max_y = fSb_histo->GetMaximum();
92  double line_hight = histos_max_y/nToysSB;
93  if (histos_max_y<fB_histo->GetMaximum()) histos_max_y = fB_histo->GetMaximum()/nToysB;
94 
95  // Build the line of the measured -2lnQ
96  fData_testStat_line = new TLine(testStat_data,0,testStat_data,line_hight);
97  fData_testStat_line->SetLineWidth(3);
98  fData_testStat_line->SetLineColor(kBlack);
99 
100  // The legend
101  double golden_section = (std::sqrt(5.)-1)/2;
102 
103  fLegend = new TLegend(0.75,0.95-0.2*golden_section,0.95,0.95);
104  TString title_leg="test statistics distributions ";
105  title_leg+=sb_vals.size();
106  title_leg+=" toys";
107  fLegend->SetName(title_leg.Data());
108  fLegend->AddEntry(fSb_histo,"SB toy datasets");
109  fLegend->AddEntry(fB_histo,"B toy datasets");
110  fLegend->AddEntry((TLine*)fData_testStat_line,"test statistics on data","L");
111  fLegend->SetFillColor(0);
112 
113 }
114 
115 /*----------------------------------------------------------------------------*/
116 
117 HybridPlot::~HybridPlot()
118 {
119  // destructor
120 
121  if (fSb_histo) delete fSb_histo;
122  if (fB_histo) delete fB_histo;
123  if (fSb_histo_shaded) delete fSb_histo_shaded;
124  if (fB_histo_shaded) delete fB_histo_shaded;
125  if (fData_testStat_line) delete fData_testStat_line;
126  if (fLegend) delete fLegend;
127 }
128 
129 /*----------------------------------------------------------------------------*/
130 
131 void HybridPlot::Draw(const char* )
132 {
133  // draw the S+B and B histogram in the current canvas
134 
135 
136  // We don't want the statistics of the histos
137  gStyle->SetOptStat(0);
138 
139  // The histos
140 
141  if (fSb_histo->GetMaximum()>fB_histo->GetMaximum()){
142  fSb_histo->DrawNormalized();
143  fB_histo->DrawNormalized("same");
144  }
145  else{
146  fB_histo->DrawNormalized();
147  fSb_histo->DrawNormalized("same");
148  }
149 
150  // Shaded
151  fB_histo_shaded = (TH1F*)fB_histo->Clone("b_shaded");
152  fB_histo_shaded->SetFillStyle(3005);
153  fB_histo_shaded->SetFillColor(kRed);
154 
155  fSb_histo_shaded = (TH1F*)fSb_histo->Clone("sb_shaded");
156  fSb_histo_shaded->SetFillStyle(3004);
157  fSb_histo_shaded->SetFillColor(kBlue);
158 
159  // Empty the bins according to the data -2lnQ
160  double data_m2lnq= fData_testStat_line->GetX1();
161  for (int i=1;i<=fSb_histo->GetNbinsX();++i){
162  if (fSb_histo->GetBinCenter(i)<data_m2lnq){
163  fSb_histo_shaded->SetBinContent(i,0);
164  fB_histo_shaded->SetBinContent(i,fB_histo->GetBinContent(i)/fB_histo->GetSumOfWeights());
165  }
166  else{
167  fB_histo_shaded->SetBinContent(i,0);
168  fSb_histo_shaded->SetBinContent(i,fSb_histo->GetBinContent(i)/fSb_histo->GetSumOfWeights());
169  }
170  }
171 
172  // Draw the shaded histos
173  fB_histo_shaded->Draw("same");
174  fSb_histo_shaded->Draw("same");
175 
176  // The line
177  fData_testStat_line->Draw("same");
178 
179  // The legend
180  fLegend->Draw("same");
181 
182  if (gPad) {
183  gPad->SetName(GetName());
184  gPad->SetTitle(GetTitle() );
185  }
186 
187  fPad = gPad;
188 
189 }
190 
191 /*----------------------------------------------------------------------------*/
192 
193 void HybridPlot::DumpToFile (const char* RootFileName, const char* options)
194 {
195  // All the objects are written to rootfile
196 
197  TFile ofile(RootFileName,options);
198  ofile.cd();
199 
200  // The histos
201  fSb_histo->Write();
202  fB_histo->Write();
203 
204  // The shaded histos
205  if (fB_histo_shaded!=NULL && fSb_histo_shaded!=NULL){
206  fB_histo_shaded->Write();
207  fSb_histo_shaded->Write();
208  }
209 
210  // The line
211  fData_testStat_line->Write("Measured test statistics line tag");
212 
213  // The legend
214  fLegend->Write();
215 
216  ofile.Close();
217 
218 }
219 
220 void HybridPlot::DumpToImage(const char * filename) {
221  if (!fPad) {
222  Error("HybridPlot","Hybrid plot has not yet been drawn ");
223  return;
224  }
225  fPad->Print(filename);
226 }
227 
228 /*----------------------------------------------------------------------------*/
229 
230 // from Rsc.cxx
231 
232 
233 /**
234  Perform 2 times a gaussian fit to fetch the center of the histo.
235  To get the second fit range get an interval that tries to keep into account
236  the skewness of the distribution.
237 **/
238 double HybridPlot::GetHistoCenter(TH1* histo_orig, double n_rms, bool display_result){
239  // Get the center of the histo
240 
241  TString optfit = "Q0";
242  if (display_result) optfit = "Q";
243 
244  TH1F* histo = (TH1F*)histo_orig->Clone();
245 
246  // get the histo x extremes
247  double x_min = histo->GetXaxis()->GetXmin();
248  double x_max = histo->GetXaxis()->GetXmax();
249 
250  // First fit!
251 
252  TF1* gaus = new TF1("mygaus", "gaus", x_min, x_max);
253 
254  gaus->SetParameter("Constant",histo->GetEntries());
255  gaus->SetParameter("Mean",histo->GetMean());
256  gaus->SetParameter("Sigma",histo->GetRMS());
257 
258  histo->Fit(gaus,optfit);
259 
260  // Second fit!
261  double sigma = gaus->GetParameter("Sigma");
262  double mean = gaus->GetParameter("Mean");
263 
264  delete gaus;
265 
266  std::cout << "Center is 1st pass = " << mean << std::endl;
267 
268  double skewness = histo->GetSkewness();
269 
270  x_min = mean - n_rms*sigma - sigma*skewness/2;
271  x_max = mean + n_rms*sigma - sigma*skewness/2;;
272 
273  TF1* gaus2 = new TF1("mygaus2", "gaus", x_min, x_max);
274  gaus2->SetParameter("Mean",mean);
275 
276  // second fit : likelihood fit
277  optfit += "L";
278  histo->Fit(gaus2,optfit,"", x_min, x_max);
279 
280 
281  double center = gaus2->GetParameter("Mean");
282 
283  if (display_result) {
284  histo->Draw();
285  gaus2->Draw("same");
286  }
287  else {
288  delete histo;
289  }
290  delete gaus2;
291 
292  return center;
293 
294 
295 }
296 
297 /**
298  We let an orizzontal bar go down and we stop when we have the integral
299  equal to the desired one.
300 **/
301 
302 double* HybridPlot::GetHistoPvals (TH1* histo, double percentage){
303 
304  if (percentage>1){
305  std::cerr << "Percentage greater or equal to 1!\n";
306  return NULL;
307  }
308 
309  // Get the integral of the histo
310  double* h_integral=histo->GetIntegral();
311 
312  // Start the iteration
313  std::map<int,int> extremes_map;
314 
315  for (int i=0;i<histo->GetNbinsX();++i){
316  for (int j=0;j<histo->GetNbinsX();++j){
317  double integral = h_integral[j]-h_integral[i];
318  if (integral>percentage){
319  extremes_map[i]=j;
320  break;
321  }
322  }
323  }
324 
325  // Now select the couple of extremes which have the lower bin content diff
326  std::map<int,int>::iterator it;
327  int a,b;
328  double left_bin_center(0.),right_bin_center(0.);
329  double diff=10e40;
330  double current_diff;
331  for (it = extremes_map.begin();it != extremes_map.end();++it){
332  a=it->first;
333  b=it->second;
334  current_diff=std::fabs(histo->GetBinContent(a)-histo->GetBinContent(b));
335  if (current_diff<diff){
336  //std::cout << "a=" << a << " b=" << b << std::endl;
337  diff=current_diff;
338  left_bin_center=histo->GetBinCenter(a);
339  right_bin_center=histo->GetBinCenter(b);
340  }
341  }
342 
343  double* d = new double[2];
344  d[0]=left_bin_center;
345  d[1]=right_bin_center;
346  return d;
347 }
348 
349 //----------------------------------------------------------------------------//
350 /**
351  Get the median of an histogram.
352 **/
353 double HybridPlot::GetMedian(TH1* histo){
354 
355  //int xbin_median;
356  Double_t* integral = histo->GetIntegral();
357  int median_i = 0;
358  for (int j=0;j<histo->GetNbinsX(); j++)
359  if (integral[j]<0.5)
360  median_i = j;
361 
362  double median_x =
363  histo->GetBinCenter(median_i)+
364  (histo->GetBinCenter(median_i+1)-
365  histo->GetBinCenter(median_i))*
366  (0.5-integral[median_i])/(integral[median_i+1]-integral[median_i]);
367 
368  return median_x;
369 }
370 
371 
virtual Bool_t cd(const char *path=0)
Change current directory to "this" directory.
static Vc_ALWAYS_INLINE int_v min(const int_v &x, const int_v &y)
Definition: vector.h:433
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4629
This class displays a legend box (TPaveText) containing several legend entries.
Definition: TLegend.h:35
Definition: Rtypes.h:61
#define assert(cond)
Definition: unittest.h:542
R__EXTERN TStyle * gStyle
Definition: TStyle.h:423
Definition: Rtypes.h:60
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:45
THist< 1, float > TH1F
Definition: THist.h:315
static const char * filename()
Basic string class.
Definition: TString.h:137
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:570
TArc * a
Definition: textangle.C:12
virtual void Draw(Option_t *option="")
Draw this function with its current attributes.
Definition: TF1.cxx:1075
virtual Int_t GetNbinsX() const
Definition: TH1.h:296
STL namespace.
virtual Double_t GetEntries() const
return the current number of entries
Definition: TH1.cxx:4051
TObject * Clone(const char *newname=0) const
Make a complete copy of the underlying object.
Definition: TH1.cxx:2565
const char * Data() const
Definition: TString.h:349
virtual Double_t GetSkewness(Int_t axis=1) const
For axis = 1, 2 or 3 returns skewness of the histogram along x, y or z axis.
Definition: TH1.cxx:7118
double sqrt(double)
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
This class provides the plots for the result of a study performed with the HybridCalculatorOriginal c...
Definition: HybridPlot.h:53
Double_t GetXmin() const
Definition: TAxis.h:137
ClassImp(RooStats::HybridPlot) using namespace RooStats
void Error(const char *location, const char *msgfmt,...)
th1 Draw()
virtual Double_t * GetIntegral()
Return a pointer to the array of bins integral.
Definition: TH1.cxx:2422
virtual Double_t GetBinCenter(Int_t bin) const
return bin center for 1D historam Better to use h1.GetXaxis().GetBinCenter(bin)
Definition: TH1.cxx:8470
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
virtual Double_t GetMean(Int_t axis=1) const
For axis = 1,2 or 3 returns the mean value of the histogram along X,Y or Z axis.
Definition: TH1.cxx:7014
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2878
A simple line.
Definition: TLine.h:41
Double_t GetRMS(Int_t axis=1) const
Definition: TH1.h:315
Namespace for the RooStats classes.
Definition: Asimov.h:20
double Double_t
Definition: RtypesCore.h:55
Double_t GetXmax() const
Definition: TAxis.h:138
The TH1 histogram class.
Definition: TH1.h:80
static Vc_ALWAYS_INLINE int_v max(const int_v &x, const int_v &y)
Definition: vector.h:440
#define name(a, b)
Definition: linkTestLib0.cpp:5
virtual Double_t GetParameter(Int_t ipar) const
Definition: TF1.h:359
1-Dim function class
Definition: TF1.h:149
void SetOptStat(Int_t stat=1)
The type of information printed in the histogram statistics box can be selected via the parameter mod...
Definition: TStyle.cxx:1252
#define NULL
Definition: Rtypes.h:82
#define gPad
Definition: TVirtualPad.h:288
Definition: Rtypes.h:61
virtual void SetParameter(Int_t param, Double_t value)
Definition: TF1.h:431
virtual TFitResultPtr Fit(const char *formula, Option_t *option="", Option_t *goption="", Double_t xmin=0, Double_t xmax=0)
Fit histogram with function fname.
Definition: TH1.cxx:3607
TAxis * GetXaxis()
Definition: TH1.h:319
virtual void Close(Option_t *option="")
Close a file.
Definition: TFile.cxx:898