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
72
73using namespace RooStats;
74using std::numeric_limits, std::endl;
75
76////////////////////////////////////////////////////////////////////////////////
77/// Default constructor
78
81 fNullPValue(NaN), fAlternatePValue(NaN),
82 fNullPValueError(0), fAlternatePValueError(0),
83 fTestStatisticData(NaN),
84 fAllTestStatisticsData(nullptr),
85 fNullDistr(nullptr), fAltDistr(nullptr),
86 fNullDetailedOutput(nullptr), fAltDetailedOutput(nullptr),
87 fPValueIsRightTail(true),
88 fBackgroundIsAlt(false)
89{
90}
91
92////////////////////////////////////////////////////////////////////////////////
93/// Alternate constructor
94
95HypoTestResult::HypoTestResult(const char* name, double nullp, double altp) :
97 fNullPValue(nullp), fAlternatePValue(altp),
98 fNullPValueError(0), fAlternatePValueError(0),
99 fTestStatisticData(NaN),
100 fAllTestStatisticsData(nullptr),
101 fNullDistr(nullptr), fAltDistr(nullptr),
102 fNullDetailedOutput(nullptr), fAltDetailedOutput(nullptr),
103 fPValueIsRightTail(true),
104 fBackgroundIsAlt(false)
105{
106}
107
108////////////////////////////////////////////////////////////////////////////////
109/// copy constructor
110
112 TNamed(other),
113 fNullPValue(other.fNullPValue), fAlternatePValue(other.fAlternatePValue),
114 fNullPValueError(other.fNullPValueError), fAlternatePValueError(other.fAlternatePValueError),
115 fTestStatisticData(other.fTestStatisticData),
116 fAllTestStatisticsData(nullptr),
117 fNullDistr(nullptr), fAltDistr(nullptr),
118 fNullDetailedOutput(nullptr), fAltDetailedOutput(nullptr),
119 fPValueIsRightTail( other.GetPValueIsRightTail() ),
120 fBackgroundIsAlt( other.GetBackGroundIsAlt() )
121{
122 this->Append( &other );
123}
124
125////////////////////////////////////////////////////////////////////////////////
126/// Destructor
127
132
133////////////////////////////////////////////////////////////////////////////////
134/// assignment operator
135
137 if (this == &other) return *this;
138 SetName(other.GetName());
139 SetTitle(other.GetTitle());
140 fNullPValue = other.fNullPValue;
141 fAlternatePValue = other.fAlternatePValue;
142 fNullPValueError = other.fNullPValueError;
143 fAlternatePValueError = other.fAlternatePValueError;
144 fTestStatisticData = other.fTestStatisticData;
145
146
147 fAllTestStatisticsData = nullptr;
148 fNullDistr = nullptr;
149 fAltDistr = nullptr;
150 fNullDetailedOutput = nullptr;
151 fAltDetailedOutput = nullptr;
152
153 fFitInfo = nullptr;
154
155 fPValueIsRightTail = other.GetPValueIsRightTail();
156 fBackgroundIsAlt = other.GetBackGroundIsAlt();
157
158 this->Append( &other );
159
160 return *this;
161}
162
163////////////////////////////////////////////////////////////////////////////////
164/// Add additional toy-MC experiments to the current results.
165/// Use the data test statistics of the added object if it is not already
166/// set (otherwise, ignore the new one).
167
169 if (fNullDistr) {
170 fNullDistr->Add(other->GetNullDistribution());
171 } else if (other->GetNullDistribution()) {
172 fNullDistr = std::make_unique<SamplingDistribution>(*other->GetNullDistribution());
173 }
174
175 if (fAltDistr) {
176 fAltDistr->Add(other->GetAltDistribution());
177 } else if (other->GetAltDistribution()) {
178 fAltDistr = std::make_unique<SamplingDistribution>(*other->GetAltDistribution());
179 }
180
181 if( fNullDetailedOutput ) {
182 if( other->GetNullDetailedOutput() ) fNullDetailedOutput->append( *other->GetNullDetailedOutput() );
183 }else{
184 if( other->GetNullDetailedOutput() ) fNullDetailedOutput = std::make_unique<RooDataSet>( *other->GetNullDetailedOutput() );
185 }
186
187 if( fAltDetailedOutput ) {
188 if( other->GetAltDetailedOutput() ) fAltDetailedOutput->append( *other->GetAltDetailedOutput() );
189 }else{
190 if( other->GetAltDetailedOutput() ) fAltDetailedOutput = std::make_unique<RooDataSet>( *other->GetAltDetailedOutput() );
191 }
192
193 if( fFitInfo ) {
194 if( other->GetFitInfo() ) fFitInfo->append( *other->GetFitInfo() );
195 }else{
196 if( other->GetFitInfo() ) fFitInfo = std::make_unique<RooDataSet>( *other->GetFitInfo());
197 }
198
199 // if no data is present use the other HypoTestResult's data
200 if(IsNaN(fTestStatisticData)) fTestStatisticData = other->GetTestStatisticData();
201
204}
205
206////////////////////////////////////////////////////////////////////////////////
207
212
213////////////////////////////////////////////////////////////////////////////////
214
219
220////////////////////////////////////////////////////////////////////////////////
221
228
229////////////////////////////////////////////////////////////////////////////////
230
232 if (tsd) fAllTestStatisticsData.reset(static_cast<const RooArgList*>(tsd->snapshot()));
233
235 RooRealVar* firstTS = static_cast<RooRealVar*>(fAllTestStatisticsData->at(0));
236 if( firstTS ) SetTestStatisticData( firstTS->getVal() );
237 }
238}
239
240////////////////////////////////////////////////////////////////////////////////
241
248
249////////////////////////////////////////////////////////////////////////////////
250
254
255////////////////////////////////////////////////////////////////////////////////
256
258 // compute error on Null pvalue
259 return fNullPValueError;
260}
261
262////////////////////////////////////////////////////////////////////////////////
263/// compute \f$CL_{b}\f$ error
264/// \f$CL_{b}\f$ = 1 - NullPValue()
265/// must use opposite condition that routine above
266
270
271////////////////////////////////////////////////////////////////////////////////
272
276
277////////////////////////////////////////////////////////////////////////////////
278/// Taylor expansion series approximation for standard deviation (error propagation)
279
283
284////////////////////////////////////////////////////////////////////////////////
285/// Returns an estimate of the error on \f$CL_{s}\f$ through combination of the
286/// errors on \f$CL_{b}\f$ and \f$CL_{s+b}\f$:
287/// \f[
288/// \sigma_{CL_s} = CL_s
289/// \sqrt{\left( \frac{\sigma_{CL_{s+b}}}{CL_{s+b}} \right)^2 + \left( \frac{\sigma_{CL_{b}}}{CL_{b}} \right)^2}
290/// \f]
291
293 if(!fAltDistr || !fNullDistr) return 0.0;
294
295 // unsigned const int n_b = fNullDistr->GetSamplingDistribution().size();
296 // unsigned const int n_sb = fAltDistr->GetSamplingDistribution().size();
297
298 // if CLb() == 0 CLs = -1 so return a -1 error
299 if (CLb() == 0 ) return -1;
300
301 double cl_b_err2 = pow(CLbError(),2);
302 double cl_sb_err2 = pow(CLsplusbError(),2);
303
304 return std::sqrt(cl_sb_err2 + cl_b_err2 * pow(CLs(),2))/CLb();
305}
306
307////////////////////////////////////////////////////////////////////////////////
308/// updates the pvalue if sufficient data is available
309
310void HypoTestResult::UpdatePValue(const SamplingDistribution* distr, double &pvalue, double &perror, bool /*isNull*/) {
311 if(IsNaN(fTestStatisticData)) return;
312 if(!distr) return;
313
314 /* Got to be careful for discrete distributions:
315 * To get the right behaviour for limits, the p-value must
316 * include the value of fTestStatistic both for Alt and Null cases
317 */
319 pvalue = distr->IntegralAndError(perror, fTestStatisticData, RooNumber::infinity(), true,
320 true , true ); // always closed interval [ fTestStatistic, inf ]
321
322 }else{
323 pvalue = distr->IntegralAndError(perror, -RooNumber::infinity(), fTestStatisticData, true,
324 true, true ); // // always closed [ -inf, fTestStatistic ]
325 }
326}
327
328////////////////////////////////////////////////////////////////////////////////
329/// Print out some information about the results
330/// Note: use Alt/Null labels for the hypotheses here as the Null
331/// might be the s+b hypothesis.
332
334{
335 bool fromToys = (fAltDistr || fNullDistr);
336
337 std::cout << std::endl << "Results " << GetName() << ": " << std::endl;
338 std::cout << " - Null p-value = " << NullPValue();
339 if (fromToys) std::cout << " +/- " << NullPValueError();
340 std::cout << std::endl;
341 std::cout << " - Significance = " << Significance();
342 if (fromToys) std::cout << " +/- " << SignificanceError() << " sigma";
343 std::cout << std::endl;
344 if(fAltDistr)
345 std::cout << " - Number of Alt toys: " << fAltDistr->GetSize() << std::endl;
346 if(fNullDistr)
347 std::cout << " - Number of Null toys: " << fNullDistr->GetSize() << std::endl;
348
349 if (HasTestStatisticData() ) std::cout << " - Test statistic evaluated on data: " << fTestStatisticData << std::endl;
350 std::cout << " - CL_b: " << CLb();
351 if (fromToys) std::cout << " +/- " << CLbError();
352 std::cout << std::endl;
353 std::cout << " - CL_s+b: " << CLsplusb();
354 if (fromToys) std::cout << " +/- " << CLsplusbError();
355 std::cout << std::endl;
356 std::cout << " - CL_s: " << CLs();
357 if (fromToys) std::cout << " +/- " << CLsError();
358 std::cout << std::endl;
359
360 return;
361}
#define NaN
#define IsNaN(a)
#define NaN
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:374
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