ROOT  6.06/09
Reference Guide
HypoTestInverterPlot.cxx
Go to the documentation of this file.
1 // @(#)root/roostats:$Id$
2 // Author: Kyle Cranmer, Lorenzo Moneta, Gregory Schott, Wouter Verkerke
3 /*************************************************************************
4  * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. *
5  * All rights reserved. *
6  * *
7  * For the licensing terms see $ROOTSYS/LICENSE. *
8  * For the list of contributors see $ROOTSYS/README/CREDITS. *
9  *************************************************************************/
10 
11 /**
12  HypoTestInverterPlot class
13 **/
14 
15 #include <cmath>
16 
17 // include other header files
18 #include "RooStats/HybridResult.h"
19 
20 // include header file of this class
23 #include "RooStats/HypoTestPlot.h"
24 
25 #include "TGraphErrors.h"
26 #include "TGraphAsymmErrors.h"
27 #include "TMultiGraph.h"
28 #include "TROOT.h"
29 #include "TLine.h"
30 #include "TAxis.h"
31 #include "TLegend.h"
32 #include "TH1.h"
33 #include "TPad.h"
34 #include "Math/DistFuncMathCore.h"
35 
36 using namespace std;
37 
39 
40 using namespace RooStats;
41 
42 
44  TNamed( results->GetName(), results->GetTitle() ),
45  fResults(results)
46 {
47  // constructor from a HypoTestInverterResult class
48  // name and title are taken from the result class
49 }
50 
51 
52 HypoTestInverterPlot::HypoTestInverterPlot( const char* name,
53  const char* title,
54  HypoTestInverterResult* results ) :
55  TNamed( TString(name), TString(title) ),
56  fResults(results)
57 {
58  // constructor with name and title from a HypoTestInverterResult class
59 }
60 
61 
63 {
64  // Make the plot of the result of the scan
65  // using the observed data
66  // By default plot CLs or CLsb depending if the flag UseCLs is set
67  //
68  // If Option = "CLb" return CLb plot
69  // = "CLs+b" return CLs+b plot independently of the flag
70  // = "CLs" return CLs plot independently of the flag
71 
72  TString option(opt);
73  option.ToUpper();
74  int type = 0; // use default
75  if (option.Contains("CLB")) type = 1; // CLb
76  else if (option.Contains("CLS+B") || option.Contains("CLSPLUSB")) type = 2; // CLs+b
77  else if (option.Contains("CLS" )) type = 3; // CLs
78 
79  const int nEntries = fResults->ArraySize();
80 
81  // sort the arrays based on the x values
82  std::vector<unsigned int> index(nEntries);
83  TMath::SortItr(fResults->fXValues.begin(), fResults->fXValues.end(), index.begin(), false);
84 
85  // copy result in sorted arrays
86  std::vector<Double_t> xArray(nEntries);
87  std::vector<Double_t> yArray(nEntries);
88  std::vector<Double_t> yErrArray(nEntries);
89  for (int i=0; i<nEntries; i++) {
90  xArray[i] = fResults->GetXValue(index[i]);
91  if (type == 0) {
92  yArray[i] = fResults->GetYValue(index[i]);
93  yErrArray[i] = fResults->GetYError(index[i]);
94  } else if (type == 1) {
95  yArray[i] = fResults->CLb(index[i]);
96  yErrArray[i] = fResults->CLbError(index[i]);
97  } else if (type == 2) {
98  yArray[i] = fResults->CLsplusb(index[i]);
99  yErrArray[i] = fResults->CLsplusbError(index[i]);
100  } else if (type == 3) {
101  yArray[i] = fResults->CLs(index[i]);
102  yErrArray[i] = fResults->CLsError(index[i]);
103  }
104  }
105 
106  TGraphErrors* graph = new TGraphErrors(nEntries,&xArray.front(),&yArray.front(),0,&yErrArray.front());
107  TString pValueName = "CLs";
108  if (type == 1 ) pValueName = "CLb";
109  if (type == 2 || (type == 0 && !fResults->fUseCLs) ) pValueName = "CLs+b";
110  TString name = pValueName + TString("_observed");
111  TString title = TString("Observed ") + pValueName;
112  graph->SetName(name);
113  graph->SetTitle(title);
114  graph->SetMarkerStyle(20);
115  graph->SetLineWidth(2);
116  return graph;
117 }
118 
120 {
121  // Make the expected plot and the bands
122  // nsig1 and nsig2 indicates the n-sigma value for the bands
123  // if nsig1 = 0 no band is drawn (only expected value)
124  // if nsig2 > nsig1 (default is nsig1=1 and nsig2=2) the second band is also drawn
125  // The first band is drawn in green while the second in yellow
126  // THe return result is a TMultiGraph object
127 
128 
129 
130  const int nEntries = fResults->ArraySize();
131  bool doFirstBand = (nsig1 > 0);
132  bool doSecondBand = (nsig2 > nsig1);
133 
134  nsig1 = std::abs(nsig1);
135  nsig2 = std::abs(nsig2);
136 
137  // sort the arrays based on the x values
138  std::vector<unsigned int> index(nEntries);
139  TMath::SortItr(fResults->fXValues.begin(), fResults->fXValues.end(), index.begin(), false);
140 
141  // create the graphs
142  TGraph * g0 = new TGraph;
143  TString pValueName = "CLs";
144  if (!fResults->fUseCLs) pValueName = "CLs+b";
145  g0->SetTitle(TString::Format("Expected %s - Median",pValueName.Data()) );
146  TGraphAsymmErrors * g1 = 0;
147  TGraphAsymmErrors * g2 = 0;
148  if (doFirstBand) {
149  g1 = new TGraphAsymmErrors;
150  if (nsig1 - int(nsig1) < 0.01)
151  g1->SetTitle(TString::Format("Expected %s #pm %d #sigma",pValueName.Data(),int(nsig1)) );
152  else
153  g1->SetTitle(TString::Format("Expected %s #pm %3.1f #sigma",pValueName.Data(),nsig1) );
154  }
155  if (doSecondBand) {
156  g2 = new TGraphAsymmErrors;
157  if (nsig2 - int(nsig2) < 0.01)
158  g2->SetTitle(TString::Format("Expected %s #pm %d #sigma",pValueName.Data(),int(nsig2)) );
159  else
160  g2->SetTitle(TString::Format("Expected %s #pm %3.1f #sigma",pValueName.Data(),nsig2) );
161  }
162  double p[7];
163  double q[7];
164  p[0] = ROOT::Math::normal_cdf(-nsig2);
165  p[1] = ROOT::Math::normal_cdf(-nsig1);
166  p[2] = 0.5;
167  p[3] = ROOT::Math::normal_cdf(nsig1);
168  p[4] = ROOT::Math::normal_cdf(nsig2);
169 
170  bool resultIsAsymptotic = ( !fResults->GetNullTestStatDist(0) && !fResults->GetAltTestStatDist(0) );
171  int np = 0;
172  for (int j=0; j<nEntries; ++j) {
173  int i = index[j]; // i is the order index
175  if ( !s) continue;
176  const std::vector<double> & values = s->GetSamplingDistribution();
177  // special case for asymptotic results (cannot use TMath::quantile in that case)
178  if (resultIsAsymptotic) {
179  double maxSigma = fResults->fgAsymptoticMaxSigma;
180  double dsig = 2* maxSigma/ (values.size() -1) ;
181  int i0 = (int) TMath::Floor ( ( -nsig2 + maxSigma )/dsig + 0.5);
182  int i1 = (int) TMath::Floor ( (-nsig1 + maxSigma )/dsig + 0.5);
183  int i2 = (int) TMath::Floor ( ( maxSigma)/dsig + 0.5);
184  int i3 = (int) TMath::Floor ( ( nsig1 + maxSigma)/dsig + 0.5);
185  int i4 = (int) TMath::Floor ( ( nsig2 + maxSigma)/dsig + 0.5);
186  q[0] = values[i0];
187  q[1] = values[i1];
188  q[2] = values[i2];
189  q[3] = values[i3];
190  q[4] = values[i4];
191  }
192  else {
193  double * x = const_cast<double *>(&values[0]); // need to change TMath::Quantiles
194  TMath::Quantiles(values.size(), 5, x,q,p,false);
195  }
196 
197  g0->SetPoint(np, fResults->GetXValue(i), q[2]);
198  if (g1) {
199  g1->SetPoint(np, fResults->GetXValue(i), q[2]);
200  g1->SetPointEYlow(np, q[2] - q[1]); // -1 sigma errorr
201  g1->SetPointEYhigh(np, q[3] - q[2]);//+1 sigma error
202  }
203  if (g2) {
204  g2->SetPoint(np, fResults->GetXValue(i), q[2]);
205 
206  g2->SetPointEYlow(np, q[2]-q[0]); // -2 -- -1 sigma error
207  g2->SetPointEYhigh(np, q[4]-q[2]);
208  }
209  if (s) delete s;
210  np++;
211  }
212 
213 
214 
215  TString name = GetName() + TString("_expected");
216  TString title = TString("Expected ") + GetTitle();
217  TMultiGraph* graph = new TMultiGraph(name,title);
218 
219  // set the graphics options and add in multi graph
220  // orderof adding is drawing order
221  if (g2) {
222  g2->SetFillColor(kYellow);
223  graph->Add(g2,"3");
224  }
225  if (g1) {
226  g1->SetFillColor(kGreen);
227  graph->Add(g1,"3");
228  }
229  g0->SetLineStyle(2);
230  g0->SetLineWidth(2);
231  graph->Add(g0,"L");
232 
233  return graph;
234 }
235 
237 {
238  // destructor
239 }
240 
242  // Draw the result in the current canvas
243  // Possible options:
244  // SAME : draw in the current axis
245  // OBS : draw only the observed plot
246  // EXP : draw only the expected plot
247  //
248  // CLB : draw also the CLB
249  // 2CL : drow both clsplusb and cls
250  //
251  // default draw observed + expected with 1 and 2 sigma bands
252 
253  TString option(opt);
254  option.ToUpper();
255  bool drawAxis = !option.Contains("SAME");
256  bool drawObs = option.Contains("OBS") || !option.Contains("EXP");
257  bool drawExp = option.Contains("EXP") || !option.Contains("OBS");
258  bool drawCLb = option.Contains("CLB");
259  bool draw2CL = option.Contains("2CL");
260 
261  TGraphErrors * gobs = 0;
262  TGraph * gplot = 0;
263  if (drawObs) {
264  gobs = MakePlot();
265  // add object to top-level directory to avoid mem leak
266  if (gROOT) gROOT->Add(gobs);
267  if (drawAxis) {
268  gobs->Draw("APL");
269  gplot = gobs;
270  gplot->GetHistogram()->SetTitle( GetTitle() );
271  }
272  else gobs->Draw("PL");
273 
274  }
275  TMultiGraph * gexp = 0;
276  if (drawExp) {
277  gexp = MakeExpectedPlot();
278  // add object to current directory to avoid mem leak
279  if (gROOT) gROOT->Add(gexp);
280  if (drawAxis && !drawObs) {
281  gexp->Draw("A");
282  if (gexp->GetHistogram()) gexp->GetHistogram()->SetTitle( GetTitle() );
283  gplot = (TGraph*) gexp->GetListOfGraphs()->First();
284  }
285  else
286  gexp->Draw();
287 
288  }
289 
290  // draw also an horizontal line at the desired conf level
291  if (gplot) {
292  double alpha = 1.-fResults->ConfidenceLevel();
293  double x1 = gplot->GetXaxis()->GetXmin();
294  double x2 = gplot->GetXaxis()->GetXmax();
295  TLine * line = new TLine(x1, alpha, x2,alpha);
296  line->SetLineColor(kRed);
297  line->Draw();
298  // put axis labels
299  RooAbsArg * arg = fResults->fParameters.first();
300  if (arg) gplot->GetXaxis()->SetTitle(arg->GetName());
301  gplot->GetYaxis()->SetTitle("p value");
302  }
303 
304 
305  TGraph *gclb = 0;
306  if (drawCLb) {
307  gclb = MakePlot("CLb");
308  if (gROOT) gROOT->Add(gclb);
309  gclb->SetMarkerColor(kBlue+4);
310  gclb->Draw("PL");
311  // draw in red observed cls or clsb
312  if (gobs) gobs->SetMarkerColor(kRed);
313  }
314  TGraph * gclsb = 0;
315  TGraph * gcls = 0;
316  if (draw2CL) {
317  if (fResults->fUseCLs) {
318  gclsb = MakePlot("CLs+b");
319  if (gROOT) gROOT->Add(gclsb);
320  gclsb->SetMarkerColor(kBlue);
321  gclsb->Draw("PL");
322  gclsb->SetLineStyle(3);
323  }
324  else {
325  gcls = MakePlot("CLs");
326  if (gROOT) gROOT->Add(gcls);
327  gcls->SetMarkerColor(kBlue);
328  gcls->Draw("PL");
329  gcls->SetLineStyle(3);
330  }
331  }
332  // draw again observed values otherwise will be covered by the bands
333  if (gobs) {
334  gobs->Draw("PL");
335  }
336 
337 
338  double y0 = 0.6;
339  double verticalSize = (gexp || draw2CL || drawCLb ) ? 0.3 : 0.15;
340  double y1 = y0 + verticalSize;
341  TLegend * l = new TLegend(0.6,y0,0.9,y1);
342  if (gobs) l->AddEntry(gobs,"","PEL");
343  if (gclsb) l->AddEntry(gclsb,"","PEL");
344  if (gcls) l->AddEntry(gcls,"","PEL");
345  if (gclb) l->AddEntry(gclb,"","PEL");
346  if (gexp) {
347  // loop in reverse order (opposite to drawing one)
348  int ngraphs = gexp->GetListOfGraphs()->GetSize();
349  for (int i = ngraphs-1; i>=0; --i) {
350  TObject * obj = gexp->GetListOfGraphs()->At(i);
351  TString lopt = "F";
352  if (i == ngraphs-1) lopt = "L";
353  if (obj) l->AddEntry(obj,"",lopt);
354  }
355  }
356  l->Draw();
357  // redraw the axis
358  if (gPad) gPad->RedrawAxis();
359 
360 }
361 
363  // plot the test statistic distributions
364  // type =0 null and alt
365  // type = 1 only null (S+B)
366  // type = 2 only alt (B)
367  SamplingDistPlot * pl = 0;
368  if (type == 0) {
370  if (result)
371  pl = new HypoTestPlot(*result, nbins );
372  return pl;
373  }
374  if (type == 1) {
376  if (sbDist) {
377  pl = new SamplingDistPlot( nbins);
378  pl->AddSamplingDistribution(sbDist);
379  return pl;
380  }
381  }
382  if (type == 2) {
384  if (bDist) {
385  pl = new SamplingDistPlot( nbins);
386  pl->AddSamplingDistribution(bDist);
387  return pl;
388  }
389  }
390  return 0;
391 }
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
virtual void SetLineWidth(Width_t lwidth)
Definition: TAttLine.h:57
Double_t Floor(Double_t x)
Definition: TMath.h:473
virtual Double_t ConfidenceLevel() const
return confidence level
This class displays a legend box (TPaveText) containing several legend entries.
Definition: TLegend.h:35
TLine * line
double CLbError(int index) const
return the observed CLb value for the i-th entry
TList * GetListOfGraphs() const
Definition: TMultiGraph.h:71
const char Option_t
Definition: RtypesCore.h:62
int ArraySize() const
number of entries in the results array
Definition: Rtypes.h:61
virtual void SetName(const char *name)
Change (i.e.
Definition: TNamed.cxx:128
virtual void Draw(Option_t *option="")
Draw this legend with its current attributes.
Definition: TLegend.cxx:373
HypoTestResult is a base class for results from hypothesis tests.
A TMultiGraph is a collection of TGraph (or derived) objects.
Definition: TMultiGraph.h:37
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1101
Double_t AddSamplingDistribution(const SamplingDistribution *samplingDist, Option_t *drawOptions="NORMALIZE HIST")
adds the sampling distribution and returns the scale factor
#define gROOT
Definition: TROOT.h:340
SamplingDistribution * GetSignalAndBackgroundTestStatDist(int index) const
Basic string class.
Definition: TString.h:137
This class provides the plots for the result of a study performed with any of the HypoTestCalculatorG...
Definition: HypoTestPlot.h:37
double GetYError(int index) const
function to return the estimated error on the value of the confidence level for the i^th entry in the...
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition: TObject.cxx:254
virtual void SetTitle(const char *title="")
Set graph title.
Definition: TGraph.cxx:2153
int nbins[3]
Definition: Rtypes.h:61
TH1F * GetHistogram() const
Returns a pointer to the histogram used to draw the axis Takes into account the two following cases...
Definition: TGraph.cxx:1443
Definition: Rtypes.h:61
STL namespace.
TMultiGraph * MakeExpectedPlot(double sig1=1, double sig2=2)
Make the expected plot and the bands nsig1 and nsig2 indicates the n-sigma value for the bands if nsi...
SamplingDistribution * GetBackgroundTestStatDist(int index) const
const std::vector< Double_t > & GetSamplingDistribution() const
Get test statistics values.
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:310
virtual void Draw(Option_t *chopt="")
Draw this graph with its current attributes.
Definition: TGraph.cxx:740
const char * Data() const
Definition: TString.h:349
HypoTestInverterResult * fResults
TGraph with assymetric error bars.
static const double x2[5]
Double_t x[n]
Definition: legend1.C:17
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2334
double CLsError(int index) const
return the observed CLb value for the i-th entry
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
void Quantiles(Int_t n, Int_t nprob, Double_t *x, Double_t *quantiles, Double_t *prob, Bool_t isSorted=kTRUE, Int_t *index=0, Int_t type=7)
Computes sample quantiles, corresponding to the given probabilities Parameters: x -the data sample n ...
Definition: TMath.cxx:1173
double normal_cdf(double x, double sigma=1, double x0=0)
Cumulative distribution function of the normal (Gaussian) distribution (lower tail).
virtual void SetPointEYlow(Int_t i, Double_t eyl)
Set EYlow for point i.
virtual void SetMarkerColor(Color_t mcolor=1)
Definition: TAttMarker.h:51
static Vc_ALWAYS_INLINE Vector< T > abs(const Vector< T > &x)
Definition: vector.h:450
virtual void Draw(Option_t *chopt="")
Draw this multigraph with its current attributes.
Double_t GetXmin() const
Definition: TAxis.h:137
double CLsplusb(int index) const
return the observed CLsplusb value for the i-th entry
virtual void SetLineColor(Color_t lcolor)
Definition: TAttLine.h:54
SamplingDistPlot * MakeTestStatPlot(int index, int type=0, int nbins=100)
Plot the test statistic distributions type =0 null and alt type = 1 only null (S+B) type = 2 only alt...
ClassImp(RooStats::HypoTestInverterPlot) using namespace RooStats
TAxis * GetXaxis() const
Get x axis of the graph.
Definition: TGraph.cxx:1563
TGraphErrors * MakePlot(Option_t *opt="")
return a TGraphErrors with the obtained observed p-values resultinf from the scan By default (Option ...
SamplingDistribution * GetExpectedPValueDist(int index) const
return expected distribution of p-values (Cls or Clsplusb)
virtual void SetFillColor(Color_t fcolor)
Definition: TAttFill.h:50
A simple line.
Definition: TLine.h:41
TLine * l
Definition: textangle.C:4
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
virtual void SetMarkerStyle(Style_t mstyle=1)
Definition: TAttMarker.h:53
SamplingDistribution * GetAltTestStatDist(int index) const
This class simply holds a sampling distribution of some test statistic.
double GetXValue(int index) const
function to return the value of the parameter of interest for the i^th entry in the results ...
Namespace for the RooStats classes.
Definition: Asimov.h:20
virtual Int_t GetSize() const
Definition: TCollection.h:95
static const double x1[5]
double CLs(int index) const
return the observed CLb value for the i-th entry
HypoTestInverterResult class: holds the array of hypothesis test results and compute a confidence int...
TLegendEntry * AddEntry(const TObject *obj, const char *label="", Option_t *option="lpf")
Add a new entry to this legend.
Definition: TLegend.cxx:280
Class to plot an HypoTestInverterResult, result of the HypoTestInverter calculator.
int type
Definition: TGX11.cxx:120
Double_t GetXmax() const
Definition: TAxis.h:138
double GetYValue(int index) const
function to return the value of the confidence level for the i^th entry in the results ...
double CLsplusbError(int index) const
return the observed CLsplusb value for the i-th entry
TH1F * GetHistogram() const
Returns a pointer to the histogram used to draw the axis.
virtual void SetLineStyle(Style_t lstyle)
Definition: TAttLine.h:56
#define name(a, b)
Definition: linkTestLib0.cpp:5
This class provides simple and straightforward utilities to plot SamplingDistribution objects...
Mother of all ROOT objects.
Definition: TObject.h:58
TAxis * GetYaxis() const
Get y axis of the graph.
Definition: TGraph.cxx:1573
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:556
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
Definition: TGraph.cxx:2127
void Draw(Option_t *opt="")
Draw the scan result in the current canvas Possible options: "" (default): draw observed + expected w...
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
A Graph is a graphics object made of two arrays X and Y with npoints each.
Definition: TGraph.h:53
A TGraphErrors is a TGraph with error bars.
Definition: TGraphErrors.h:28
#define gPad
Definition: TVirtualPad.h:288
double result[121]
Definition: Rtypes.h:61
virtual void SetTitle(const char *title)
Change (i.e.
Definition: TH1.cxx:6268
virtual void Add(TGraph *graph, Option_t *chopt="")
Add a new graph to the list of graphs.
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:66
float * q
Definition: THbookFile.cxx:87
double CLb(int index) const
return the observed CLb value for the i-th entry
virtual void SetTitle(const char *title="")
Change (i.e. set) the title of the TNamed.
Definition: TNamed.cxx:152
TObject * obj
virtual void SetPointEYhigh(Int_t i, Double_t eyh)
Set EYhigh for point i.
void SortItr(Iterator first, Iterator last, IndexIterator index, Bool_t down=kTRUE)
Definition: TMath.h:977
SamplingDistribution * GetNullTestStatDist(int index) const
same in terms of alt and null
std::vector< double > fXValues
max sigma value used to scan asymptotic expected p values