Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
HypoTestResult.cxx
Go to the documentation of this file.
1// @(#)root/roostats:$Id$
2// Author: Kyle Cranmer, Lorenzo Moneta, Gregory Schott, Wouter Verkerke, Sven Kreiss
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 * Project: RooStats
13 * Package: RooFit/RooStats
14 * @(#)root/roofit/roostats:$Id$
15 * Authors:
16 * Kyle Cranmer, Lorenzo Moneta, Gregory Schott, Wouter Verkerke, Sven Kreiss
17 *
18 *****************************************************************************/
19
20
21/** \class RooStats::HypoTestResult
22 \ingroup Roostats
23
24HypoTestResult is a base class for results from hypothesis tests.
25Any tool inheriting from HypoTestCalculator can return a HypoTestResult.
26As such, it stores a p-value for the null-hypothesis (eg. background-only)
27and an alternate hypothesis (eg. signal+background).
28The p-values can also be transformed into confidence levels
29(\f$CL_{b}\f$, \f$CL_{s+b}\f$) in a trivial way.
30The ratio of the \f$CL_{s+b}\f$ to \f$CL_{b}\f$ is often called
31\f$CL_{s}\f$, and is considered useful, though it is not a probability.
32Finally, the p-value of the null can be transformed into a number of
33equivalent Gaussian sigma using the Significance method.
34
35The p-value of the null for a given test statistic is rigorously defined and
36this is the starting point for the following conventions.
37
38### Conventions used in this class
39
40The p-value for the null and alternate are on the **same side** of the
41observed value of the test statistic. This is the more standard
42convention and avoids confusion when doing inverted tests.
43
44For exclusion, we also want the formula \f$CL_{s} = CL_{s+b} / CL_{b}\f$
45to hold which therefore defines our conventions for \f$CL_{s+b}\f$ and
46\f$CL_{b}\f$. \f$CL_{s}\f$ was specifically invented for exclusion
47and therefore all quantities need be related through the assignments
48as they are for exclusion: \f$CL_{s+b} = p_{s+b}\f$; \f$CL_{b} = p_{b}\f$. This
49is derived by considering the scenarios of a powerful and not powerful
50inverted test, where for the not so powerful test, \f$CL_{s}\f$ must be
51close to one.
52
53For results of Hypothesis tests,
54\f$CL_{s}\f$ has no similar direct interpretation as for exclusion and can
55be larger than one.
56
57*/
58
61#include "RooAbsReal.h"
62
64
65#include <TMath.h>
66
67#include <limits>
68#define NaN numeric_limits<float>::quiet_NaN()
69#define IsNaN(a) TMath::IsNaN(a)
70
71
72using namespace RooStats;
73using std::numeric_limits, std::endl;
74
75////////////////////////////////////////////////////////////////////////////////
76/// Default constructor
77
80 fNullPValue(NaN), fAlternatePValue(NaN),
81 fNullPValueError(0), fAlternatePValueError(0),
82 fTestStatisticData(NaN),
83 fAllTestStatisticsData(nullptr),
84 fNullDistr(nullptr), fAltDistr(nullptr),
85 fNullDetailedOutput(nullptr), fAltDetailedOutput(nullptr),
86 fPValueIsRightTail(true),
87 fBackgroundIsAlt(false)
88{
89}
90
91////////////////////////////////////////////////////////////////////////////////
92/// Alternate constructor
93
94HypoTestResult::HypoTestResult(const char* name, double nullp, double altp) :
96 fNullPValue(nullp), fAlternatePValue(altp),
97 fNullPValueError(0), fAlternatePValueError(0),
98 fTestStatisticData(NaN),
99 fAllTestStatisticsData(nullptr),
100 fNullDistr(nullptr), fAltDistr(nullptr),
101 fNullDetailedOutput(nullptr), fAltDetailedOutput(nullptr),
102 fPValueIsRightTail(true),
103 fBackgroundIsAlt(false)
104{
105}
106
107////////////////////////////////////////////////////////////////////////////////
108/// copy constructor
109
111 TNamed(other),
112 fNullPValue(other.fNullPValue), fAlternatePValue(other.fAlternatePValue),
113 fNullPValueError(other.fNullPValueError), fAlternatePValueError(other.fAlternatePValueError),
114 fTestStatisticData(other.fTestStatisticData),
115 fAllTestStatisticsData(nullptr),
116 fNullDistr(nullptr), fAltDistr(nullptr),
117 fNullDetailedOutput(nullptr), fAltDetailedOutput(nullptr),
118 fPValueIsRightTail( other.GetPValueIsRightTail() ),
119 fBackgroundIsAlt( other.GetBackGroundIsAlt() )
120{
121 this->Append( &other );
122}
123
124////////////////////////////////////////////////////////////////////////////////
125/// Destructor
126
131
132////////////////////////////////////////////////////////////////////////////////
133/// assignment operator
134
136 if (this == &other) return *this;
137 SetName(other.GetName());
138 SetTitle(other.GetTitle());
139 fNullPValue = other.fNullPValue;
140 fAlternatePValue = other.fAlternatePValue;
141 fNullPValueError = other.fNullPValueError;
142 fAlternatePValueError = other.fAlternatePValueError;
143 fTestStatisticData = other.fTestStatisticData;
144
145
146 fAllTestStatisticsData = nullptr;
147 fNullDistr = nullptr;
148 fAltDistr = nullptr;
149 fNullDetailedOutput = nullptr;
150 fAltDetailedOutput = nullptr;
151
152 fFitInfo = nullptr;
153
154 fPValueIsRightTail = other.GetPValueIsRightTail();
155 fBackgroundIsAlt = other.GetBackGroundIsAlt();
156
157 this->Append( &other );
158
159 return *this;
160}
161
162////////////////////////////////////////////////////////////////////////////////
163/// Add additional toy-MC experiments to the current results.
164/// Use the data test statistics of the added object if it is not already
165/// set (otherwise, ignore the new one).
166
168 if (fNullDistr) {
169 fNullDistr->Add(other->GetNullDistribution());
170 } else if (other->GetNullDistribution()) {
171 fNullDistr = std::make_unique<SamplingDistribution>(*other->GetNullDistribution());
172 }
173
174 if (fAltDistr) {
175 fAltDistr->Add(other->GetAltDistribution());
176 } else if (other->GetAltDistribution()) {
177 fAltDistr = std::make_unique<SamplingDistribution>(*other->GetAltDistribution());
178 }
179
180 if( fNullDetailedOutput ) {
181 if( other->GetNullDetailedOutput() ) fNullDetailedOutput->append( *other->GetNullDetailedOutput() );
182 }else{
183 if( other->GetNullDetailedOutput() ) fNullDetailedOutput = std::make_unique<RooDataSet>( *other->GetNullDetailedOutput() );
184 }
185
186 if( fAltDetailedOutput ) {
187 if( other->GetAltDetailedOutput() ) fAltDetailedOutput->append( *other->GetAltDetailedOutput() );
188 }else{
189 if( other->GetAltDetailedOutput() ) fAltDetailedOutput = std::make_unique<RooDataSet>( *other->GetAltDetailedOutput() );
190 }
191
192 if( fFitInfo ) {
193 if( other->GetFitInfo() ) fFitInfo->append( *other->GetFitInfo() );
194 }else{
195 if( other->GetFitInfo() ) fFitInfo = std::make_unique<RooDataSet>( *other->GetFitInfo());
196 }
197
198 // if no data is present use the other HypoTestResult's data
199 if(IsNaN(fTestStatisticData)) fTestStatisticData = other->GetTestStatisticData();
200
203}
204
205////////////////////////////////////////////////////////////////////////////////
206
211
212////////////////////////////////////////////////////////////////////////////////
213
218
219////////////////////////////////////////////////////////////////////////////////
220
227
228////////////////////////////////////////////////////////////////////////////////
229
231 if (tsd) fAllTestStatisticsData.reset(static_cast<const RooArgList*>(tsd->snapshot()));
232
234 RooRealVar* firstTS = static_cast<RooRealVar*>(fAllTestStatisticsData->at(0));
235 if( firstTS ) SetTestStatisticData( firstTS->getVal() );
236 }
237}
238
239////////////////////////////////////////////////////////////////////////////////
240
247
248////////////////////////////////////////////////////////////////////////////////
249
253
254////////////////////////////////////////////////////////////////////////////////
255
257 // compute error on Null pvalue
258 return fNullPValueError;
259}
260
261////////////////////////////////////////////////////////////////////////////////
262/// compute \f$CL_{b}\f$ error
263/// \f$CL_{b}\f$ = 1 - NullPValue()
264/// must use opposite condition that routine above
265
269
270////////////////////////////////////////////////////////////////////////////////
271
275
276////////////////////////////////////////////////////////////////////////////////
277/// Taylor expansion series approximation for standard deviation (error propagation)
278
282
283////////////////////////////////////////////////////////////////////////////////
284/// Returns an estimate of the error on \f$CL_{s}\f$ through combination of the
285/// errors on \f$CL_{b}\f$ and \f$CL_{s+b}\f$:
286/// \f[
287/// \sigma_{CL_s} = CL_s
288/// \sqrt{\left( \frac{\sigma_{CL_{s+b}}}{CL_{s+b}} \right)^2 + \left( \frac{\sigma_{CL_{b}}}{CL_{b}} \right)^2}
289/// \f]
290
292 if(!fAltDistr || !fNullDistr) return 0.0;
293
294 // unsigned const int n_b = fNullDistr->GetSamplingDistribution().size();
295 // unsigned const int n_sb = fAltDistr->GetSamplingDistribution().size();
296
297 // if CLb() == 0 CLs = -1 so return a -1 error
298 if (CLb() == 0 ) return -1;
299
300 double cl_b_err2 = pow(CLbError(),2);
301 double cl_sb_err2 = pow(CLsplusbError(),2);
302
303 return std::sqrt(cl_sb_err2 + cl_b_err2 * pow(CLs(),2))/CLb();
304}
305
306////////////////////////////////////////////////////////////////////////////////
307/// updates the pvalue if sufficient data is available
308
309void HypoTestResult::UpdatePValue(const SamplingDistribution* distr, double &pvalue, double &perror, bool /*isNull*/) {
310 if(IsNaN(fTestStatisticData)) return;
311 if(!distr) return;
312
313 /* Got to be careful for discrete distributions:
314 * To get the right behaviour for limits, the p-value must
315 * include the value of fTestStatistic both for Alt and Null cases
316 */
318 pvalue = distr->IntegralAndError(perror, fTestStatisticData, RooNumber::infinity(), true,
319 true , true ); // always closed interval [ fTestStatistic, inf ]
320
321 }else{
322 pvalue = distr->IntegralAndError(perror, -RooNumber::infinity(), fTestStatisticData, true,
323 true, true ); // // always closed [ -inf, fTestStatistic ]
324 }
325}
326
327////////////////////////////////////////////////////////////////////////////////
328/// Print out some information about the results
329/// Note: use Alt/Null labels for the hypotheses here as the Null
330/// might be the s+b hypothesis.
331
333{
334 bool fromToys = (fAltDistr || fNullDistr);
335
336 std::cout << std::endl << "Results " << GetName() << ": " << std::endl;
337 std::cout << " - Null p-value = " << NullPValue();
338 if (fromToys) std::cout << " +/- " << NullPValueError();
339 std::cout << std::endl;
340 std::cout << " - Significance = " << Significance();
341 if (fromToys) std::cout << " +/- " << SignificanceError() << " sigma";
342 std::cout << std::endl;
343 if(fAltDistr)
344 std::cout << " - Number of Alt toys: " << fAltDistr->GetSize() << std::endl;
345 if(fNullDistr)
346 std::cout << " - Number of Null toys: " << fNullDistr->GetSize() << std::endl;
347
348 if (HasTestStatisticData() ) std::cout << " - Test statistic evaluated on data: " << fTestStatisticData << std::endl;
349 std::cout << " - CL_b: " << CLb();
350 if (fromToys) std::cout << " +/- " << CLbError();
351 std::cout << std::endl;
352 std::cout << " - CL_s+b: " << CLsplusb();
353 if (fromToys) std::cout << " +/- " << CLsplusbError();
354 std::cout << std::endl;
355 std::cout << " - CL_s: " << CLs();
356 if (fromToys) std::cout << " +/- " << CLsError();
357 std::cout << std::endl;
358
359 return;
360}
#define NaN
#define IsNaN(a)
#define NaN
const char Option_t
Definition RtypesCore.h:66
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
char name[80]
Definition TGX11.cxx:110
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition RooArgList.h:22
static constexpr double infinity()
Return internal infinity representation.
Definition RooNumber.h:25
Variable that can be changed from the outside.
Definition RooRealVar.h:37
HypoTestResult is a base class for results from hypothesis tests.
std::unique_ptr< RooDataSet > fNullDetailedOutput
void UpdatePValue(const SamplingDistribution *distr, double &pvalue, double &perror, bool pIsRightTail)
updates the pvalue if sufficient data is available
void Print(const Option_t *="") const override
Print out some information about the results Note: use Alt/Null labels for the hypotheses here as the...
double fNullPValue
p-value for the null hypothesis (small number means disfavoured)
bool HasTestStatisticData(void) const
double fAlternatePValueError
error of p-value for the alternate hypothesis (small number means disfavoured)
HypoTestResult & operator=(const HypoTestResult &other)
assignment operator
virtual double CLsplusb() const
Convert AlternatePValue into a "confidence level".
std::unique_ptr< RooDataSet > fAltDetailedOutput
void SetAllTestStatisticsData(const RooArgList *tsd)
virtual void Append(const HypoTestResult *other)
add values from another HypoTestResult
double NullPValueError() const
The error on the Null p-value.
double CLsError() const
The error on the ratio .
virtual double Significance() const
familiar name for the Null p-value in terms of 1-sided Gaussian significance
void SetNullDistribution(SamplingDistribution *null)
~HypoTestResult() override
destructor
HypoTestResult(const char *name=nullptr)
default constructor
double SignificanceError() const
The error on the significance, computed from NullPValueError via error propagation.
virtual double NullPValue() const
Return p-value for null hypothesis.
double CLbError() const
The error on the "confidence level" of the null hypothesis.
void SetTestStatisticData(const double tsd)
double CLsplusbError() const
The error on the "confidence level" of the alternative hypothesis.
double fNullPValueError
error of p-value for the null hypothesis (small number means disfavoured)
double fTestStatisticData
result of the test statistic evaluated on data
void SetAltDistribution(SamplingDistribution *alt)
std::unique_ptr< const RooArgList > fAllTestStatisticsData
for the case of multiple test statistics, holds all the results
std::unique_ptr< RooDataSet > fFitInfo
std::unique_ptr< SamplingDistribution > fAltDistr
virtual double CLs() const
is simply (not a method, but a quantity)
double fAlternatePValue
p-value for the alternate hypothesis (small number means disfavoured)
std::unique_ptr< SamplingDistribution > fNullDistr
virtual double CLb() const
Convert NullPValue into a "confidence level".
This class simply holds a sampling distribution of some test statistic.
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:164
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:140
double normal_pdf(double x, double sigma=1, double x0=0)
Probability density function of the normal (Gaussian) distribution with mean x0 and standard deviatio...
Namespace for the RooStats classes.
Definition CodegenImpl.h:58