Logo ROOT   6.16/01
Reference Guide
rs_numberCountingCombination.C
Go to the documentation of this file.
1/// \file
2/// \ingroup tutorial_roostats
3/// \notebook -js
4/// 'Number Counting Example' RooStats tutorial macro #100
5///
6/// This tutorial shows an example of a combination of
7/// two searches using number counting with background uncertainty.
8///
9/// The macro uses a RooStats "factory" to construct a PDF
10/// that represents the two number counting analyses with background
11/// uncertainties. The uncertainties are taken into account by
12/// considering a sideband measurement of a size that corresponds to the
13/// background uncertainty. The problem has been studied in these references:
14/// - http://arxiv.org/abs/physics/0511028
15/// - http://arxiv.org/abs/physics/0702156
16/// - http://cdsweb.cern.ch/record/1099969?ln=en
17///
18/// After using the factory to make the model, we use a RooStats
19/// ProfileLikelihoodCalculator for a Hypothesis test and a confidence interval.
20/// The calculator takes into account systematics by eliminating nuisance parameters
21/// with the profile likelihood. This is equivalent to the method of MINOS.
22///
23///
24/// \macro_image
25/// \macro_output
26/// \macro_code
27///
28/// \author Kyle Cranmer
29
30
36#include "RooRealVar.h"
37
38#include <cassert>
39
40// use this order for safety on library loading
41using namespace RooFit;
42using namespace RooStats;
43
44
45// declare three variations on the same tutorial
46void rs_numberCountingCombination_expected();
47void rs_numberCountingCombination_observed();
48void rs_numberCountingCombination_observedWithTau();
49
50// -------------------------------
51// main driver to choose one
52void rs_numberCountingCombination(int flag=1)
53{
54 if(flag==1)
55 rs_numberCountingCombination_expected();
56 if(flag==2)
57 rs_numberCountingCombination_observed();
58 if(flag==3)
59 rs_numberCountingCombination_observedWithTau();
60}
61
62// -------------------------------
63void rs_numberCountingCombination_expected()
64{
65
66 /////////////////////////////////////////
67 // An example of a number counting combination with two channels.
68 // We consider both hypothesis testing and the equivalent confidence interval.
69 /////////////////////////////////////////
70
71
72 /////////////////////////////////////////
73 // The Model building stage
74 /////////////////////////////////////////
75
76 // Step 1, define arrays with signal & bkg expectations and background uncertainties
77 Double_t s[2] = {20.,10.}; // expected signal
78 Double_t b[2] = {100.,100.}; // expected background
79 Double_t db[2] = {.0100,.0100}; // fractional background uncertainty
80
81
82 // Step 2, use a RooStats factory to build a PDF for a
83 // number counting combination and add it to the workspace.
84 // We need to give the signal expectation to relate the masterSignal
85 // to the signal contribution in the individual channels.
86 // The model neglects correlations in background uncertainty,
87 // but they could be added without much change to the example.
89 RooWorkspace* wspace = new RooWorkspace();
90 f.AddModel(s,2,wspace,"TopLevelPdf", "masterSignal");
91
92 // Step 3, use a RooStats factory to add datasets to the workspace.
93 // Step 3a.
94 // Add the expected data to the workspace
95 f.AddExpData(s, b, db, 2, wspace, "ExpectedNumberCountingData");
96
97 // see below for a printout of the workspace
98 // wspace->Print(); //uncomment to see structure of workspace
99
100 /////////////////////////////////////////
101 // The Hypothesis testing stage:
102 /////////////////////////////////////////
103 // Step 4, Define the null hypothesis for the calculator
104 // Here you need to know the name of the variables corresponding to hypothesis.
105 RooRealVar* mu = wspace->var("masterSignal");
106 RooArgSet* poi = new RooArgSet(*mu);
107 RooArgSet* nullParams = new RooArgSet("nullParams");
108 nullParams->addClone(*mu);
109 // here we explicitly set the value of the parameters for the null
110 nullParams->setRealValue("masterSignal",0);
111
112 // Step 5, Create a calculator for doing the hypothesis test.
113 // because this is a
114 ProfileLikelihoodCalculator plc( *wspace->data("ExpectedNumberCountingData"),
115 *wspace->pdf("TopLevelPdf"), *poi, 0.05, nullParams);
116
117
118 // Step 6, Use the Calculator to get a HypoTestResult
119 HypoTestResult* htr = plc.GetHypoTest();
120 assert(htr != 0);
121 cout << "-------------------------------------------------" << endl;
122 cout << "The p-value for the null is " << htr->NullPValue() << endl;
123 cout << "Corresponding to a significance of " << htr->Significance() << endl;
124 cout << "-------------------------------------------------\n\n" << endl;
125
126 /* expected case should return:
127 -------------------------------------------------
128 The p-value for the null is 0.015294
129 Corresponding to a significance of 2.16239
130 -------------------------------------------------
131 */
132
133 //////////////////////////////////////////
134 // Confidence Interval Stage
135
136 // Step 8, Here we re-use the ProfileLikelihoodCalculator to return a confidence interval.
137 // We need to specify what are our parameters of interest
138 RooArgSet* paramsOfInterest = nullParams; // they are the same as before in this case
139 plc.SetParameters(*paramsOfInterest);
140 LikelihoodInterval* lrint = (LikelihoodInterval*) plc.GetInterval(); // that was easy.
141 lrint->SetConfidenceLevel(0.95);
142
143 // Step 9, make a plot of the likelihood ratio and the interval obtained
144 //paramsOfInterest->setRealValue("masterSignal",1.);
145 // find limits
146 double lower = lrint->LowerLimit(*mu);
147 double upper = lrint->UpperLimit(*mu);
148
149 LikelihoodIntervalPlot lrPlot(lrint);
150 lrPlot.SetMaximum(3.);
151 lrPlot.Draw();
152
153 // Step 10a. Get upper and lower limits
154 cout << "lower limit on master signal = " << lower << endl;
155 cout << "upper limit on master signal = " << upper << endl;
156
157
158 // Step 10b, Ask if masterSignal=0 is in the interval.
159 // Note, this is equivalent to the question of a 2-sigma hypothesis test:
160 // "is the parameter point masterSignal=0 inside the 95% confidence interval?"
161 // Since the significance of the Hypothesis test was > 2-sigma it should not be:
162 // eg. we exclude masterSignal=0 at 95% confidence.
163 paramsOfInterest->setRealValue("masterSignal",0.);
164 cout << "-------------------------------------------------" << endl;
165 std::cout << "Consider this parameter point:" << std::endl;
166 paramsOfInterest->first()->Print();
167 if( lrint->IsInInterval(*paramsOfInterest) )
168 std::cout << "It IS in the interval." << std::endl;
169 else
170 std::cout << "It is NOT in the interval." << std::endl;
171 cout << "-------------------------------------------------\n\n" << endl;
172
173 // Step 10c, We also ask about the parameter point masterSignal=2, which is inside the interval.
174 paramsOfInterest->setRealValue("masterSignal",2.);
175 cout << "-------------------------------------------------" << endl;
176 std::cout << "Consider this parameter point:" << std::endl;
177 paramsOfInterest->first()->Print();
178 if( lrint->IsInInterval(*paramsOfInterest) )
179 std::cout << "It IS in the interval." << std::endl;
180 else
181 std::cout << "It is NOT in the interval." << std::endl;
182 cout << "-------------------------------------------------\n\n" << endl;
183
184
185 delete lrint;
186 delete htr;
187 delete wspace;
188 delete poi;
189 delete nullParams;
190
191
192
193 /*
194 // Here's an example of what is in the workspace
195 // wspace->Print();
196 RooWorkspace(NumberCountingWS) Number Counting WS contents
197
198 variables
199 ---------
200 (x_0,masterSignal,expected_s_0,b_0,y_0,tau_0,x_1,expected_s_1,b_1,y_1,tau_1)
201
202 p.d.f.s
203 -------
204 RooProdPdf::joint[ pdfs=(sigRegion_0,sideband_0,sigRegion_1,sideband_1) ] = 2.20148e-08
205 RooPoisson::sigRegion_0[ x=x_0 mean=splusb_0 ] = 0.036393
206 RooPoisson::sideband_0[ x=y_0 mean=bTau_0 ] = 0.00398939
207 RooPoisson::sigRegion_1[ x=x_1 mean=splusb_1 ] = 0.0380088
208 RooPoisson::sideband_1[ x=y_1 mean=bTau_1 ] = 0.00398939
209
210 functions
211 --------
212 RooAddition::splusb_0[ set1=(s_0,b_0) set2=() ] = 120
213 RooProduct::s_0[ compRSet=(masterSignal,expected_s_0) compCSet=() ] = 20
214 RooProduct::bTau_0[ compRSet=(b_0,tau_0) compCSet=() ] = 10000
215 RooAddition::splusb_1[ set1=(s_1,b_1) set2=() ] = 110
216 RooProduct::s_1[ compRSet=(masterSignal,expected_s_1) compCSet=() ] = 10
217 RooProduct::bTau_1[ compRSet=(b_1,tau_1) compCSet=() ] = 10000
218
219 datasets
220 --------
221 RooDataSet::ExpectedNumberCountingData(x_0,y_0,x_1,y_1)
222
223 embedded pre-calculated expensive components
224 -------------------------------------------
225 */
226
227}
228
229
230
231void rs_numberCountingCombination_observed()
232{
233
234 /////////////////////////////////////////
235 // The same example with observed data in a main
236 // measurement and an background-only auxiliary
237 // measurement with a factor tau more background
238 // than in the main measurement.
239
240 /////////////////////////////////////////
241 // The Model building stage
242 /////////////////////////////////////////
243
244 // Step 1, define arrays with signal & bkg expectations and background uncertainties
245 // We still need the expectation to relate signal in different channels with the master signal
246 Double_t s[2] = {20.,10.}; // expected signal
247
248
249 // Step 2, use a RooStats factory to build a PDF for a
250 // number counting combination and add it to the workspace.
251 // We need to give the signal expectation to relate the masterSignal
252 // to the signal contribution in the individual channels.
253 // The model neglects correlations in background uncertainty,
254 // but they could be added without much change to the example.
256 RooWorkspace* wspace = new RooWorkspace();
257 f.AddModel(s,2,wspace,"TopLevelPdf", "masterSignal");
258
259 // Step 3, use a RooStats factory to add datasets to the workspace.
260 // Add the observed data to the workspace
261 Double_t mainMeas[2] = {123.,117.}; // observed main measurement
262 Double_t bkgMeas[2] = {111.23,98.76}; // observed background
263 Double_t dbMeas[2] = {.011,.0095}; // observed fractional background uncertainty
264 f.AddData(mainMeas, bkgMeas, dbMeas, 2, wspace,"ObservedNumberCountingData");
265
266 // see below for a printout of the workspace
267 // wspace->Print(); //uncomment to see structure of workspace
268
269 /////////////////////////////////////////
270 // The Hypothesis testing stage:
271 /////////////////////////////////////////
272 // Step 4, Define the null hypothesis for the calculator
273 // Here you need to know the name of the variables corresponding to hypothesis.
274 RooRealVar* mu = wspace->var("masterSignal");
275 RooArgSet* poi = new RooArgSet(*mu);
276 RooArgSet* nullParams = new RooArgSet("nullParams");
277 nullParams->addClone(*mu);
278 // here we explicitly set the value of the parameters for the null
279 nullParams->setRealValue("masterSignal",0);
280
281 // Step 5, Create a calculator for doing the hypothesis test.
282 // because this is a
283 ProfileLikelihoodCalculator plc( *wspace->data("ObservedNumberCountingData"),
284 *wspace->pdf("TopLevelPdf"), *poi, 0.05, nullParams);
285
286 wspace->var("tau_0")->Print();
287 wspace->var("tau_1")->Print();
288
289 // Step 7, Use the Calculator to get a HypoTestResult
290 HypoTestResult* htr = plc.GetHypoTest();
291 cout << "-------------------------------------------------" << endl;
292 cout << "The p-value for the null is " << htr->NullPValue() << endl;
293 cout << "Corresponding to a significance of " << htr->Significance() << endl;
294 cout << "-------------------------------------------------\n\n" << endl;
295
296 /* observed case should return:
297 -------------------------------------------------
298 The p-value for the null is 0.0351669
299 Corresponding to a significance of 1.80975
300 -------------------------------------------------
301 */
302
303
304 //////////////////////////////////////////
305 // Confidence Interval Stage
306
307 // Step 8, Here we re-use the ProfileLikelihoodCalculator to return a confidence interval.
308 // We need to specify what are our parameters of interest
309 RooArgSet* paramsOfInterest = nullParams; // they are the same as before in this case
310 plc.SetParameters(*paramsOfInterest);
311 LikelihoodInterval* lrint = (LikelihoodInterval*) plc.GetInterval(); // that was easy.
312 lrint->SetConfidenceLevel(0.95);
313
314 // Step 9c. Get upper and lower limits
315 cout << "lower limit on master signal = " << lrint->LowerLimit(*mu ) << endl;
316 cout << "upper limit on master signal = " << lrint->UpperLimit(*mu ) << endl;
317
318 delete lrint;
319 delete htr;
320 delete wspace;
321 delete nullParams;
322 delete poi;
323
324
325}
326
327
328void rs_numberCountingCombination_observedWithTau()
329{
330
331 /////////////////////////////////////////
332 // The same example with observed data in a main
333 // measurement and an background-only auxiliary
334 // measurement with a factor tau more background
335 // than in the main measurement.
336
337 /////////////////////////////////////////
338 // The Model building stage
339 /////////////////////////////////////////
340
341 // Step 1, define arrays with signal & bkg expectations and background uncertainties
342 // We still need the expectation to relate signal in different channels with the master signal
343 Double_t s[2] = {20.,10.}; // expected signal
344
345 // Step 2, use a RooStats factory to build a PDF for a
346 // number counting combination and add it to the workspace.
347 // We need to give the signal expectation to relate the masterSignal
348 // to the signal contribution in the individual channels.
349 // The model neglects correlations in background uncertainty,
350 // but they could be added without much change to the example.
352 RooWorkspace* wspace = new RooWorkspace();
353 f.AddModel(s,2,wspace,"TopLevelPdf", "masterSignal");
354
355 // Step 3, use a RooStats factory to add datasets to the workspace.
356 // Add the observed data to the workspace in the on-off problem.
357 Double_t mainMeas[2] = {123.,117.}; // observed main measurement
358 Double_t sideband[2] = {11123.,9876.}; // observed sideband
359 Double_t tau[2] = {100.,100.}; // ratio of bkg in sideband to bkg in main measurement, from experimental design.
360 f.AddDataWithSideband(mainMeas, sideband, tau, 2, wspace,"ObservedNumberCountingDataWithSideband");
361
362 // see below for a printout of the workspace
363 // wspace->Print(); //uncomment to see structure of workspace
364
365 /////////////////////////////////////////
366 // The Hypothesis testing stage:
367 /////////////////////////////////////////
368 // Step 4, Define the null hypothesis for the calculator
369 // Here you need to know the name of the variables corresponding to hypothesis.
370 RooRealVar* mu = wspace->var("masterSignal");
371 RooArgSet* poi = new RooArgSet(*mu);
372 RooArgSet* nullParams = new RooArgSet("nullParams");
373 nullParams->addClone(*mu);
374 // here we explicitly set the value of the parameters for the null
375 nullParams->setRealValue("masterSignal",0);
376
377 // Step 5, Create a calculator for doing the hypothesis test.
378 // because this is a
379 ProfileLikelihoodCalculator plc( *wspace->data("ObservedNumberCountingDataWithSideband"),
380 *wspace->pdf("TopLevelPdf"), *poi, 0.05, nullParams);
381
382
383 // Step 7, Use the Calculator to get a HypoTestResult
384 HypoTestResult* htr = plc.GetHypoTest();
385 cout << "-------------------------------------------------" << endl;
386 cout << "The p-value for the null is " << htr->NullPValue() << endl;
387 cout << "Corresponding to a significance of " << htr->Significance() << endl;
388 cout << "-------------------------------------------------\n\n" << endl;
389
390 /* observed case should return:
391 -------------------------------------------------
392 The p-value for the null is 0.0352035
393 Corresponding to a significance of 1.80928
394 -------------------------------------------------
395 */
396
397
398 //////////////////////////////////////////
399 // Confidence Interval Stage
400
401 // Step 8, Here we re-use the ProfileLikelihoodCalculator to return a confidence interval.
402 // We need to specify what are our parameters of interest
403 RooArgSet* paramsOfInterest = nullParams; // they are the same as before in this case
404 plc.SetParameters(*paramsOfInterest);
405 LikelihoodInterval* lrint = (LikelihoodInterval*) plc.GetInterval(); // that was easy.
406 lrint->SetConfidenceLevel(0.95);
407
408
409
410 // Step 9c. Get upper and lower limits
411 cout << "lower limit on master signal = " << lrint->LowerLimit(*mu ) << endl;
412 cout << "upper limit on master signal = " << lrint->UpperLimit(*mu ) << endl;
413
414 delete lrint;
415 delete htr;
416 delete wspace;
417 delete nullParams;
418 delete poi;
419
420
421}
#define b(i)
Definition: RSha256.hxx:100
#define f(i)
Definition: RSha256.hxx:104
double Double_t
Definition: RtypesCore.h:55
virtual void Print(Option_t *options=0) const
Print TNamed name and title.
Definition: RooAbsArg.h:227
RooAbsArg * first() const
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:28
Bool_t setRealValue(const char *name, Double_t newVal=0, Bool_t verbose=kFALSE)
Set value of a RooAbsRealLValye stored in set with given name to newVal No error messages are printed...
Definition: RooArgSet.cxx:493
virtual void addClone(const RooAbsCollection &col, Bool_t silent=kFALSE)
Add a collection of arguments to this collection by calling addOwned() for each element in the source...
Definition: RooArgSet.h:96
RooRealVar represents a fundamental (non-derived) real valued object.
Definition: RooRealVar.h:36
HypoTestResult is a base class for results from hypothesis tests.
virtual Double_t Significance() const
familiar name for the Null p-value in terms of 1-sided Gaussian significance
virtual Double_t NullPValue() const
Return p-value for null hypothesis.
This class provides simple and straightforward utilities to plot a LikelihoodInterval object.
LikelihoodInterval is a concrete implementation of the RooStats::ConfInterval interface.
Double_t LowerLimit(const RooRealVar &param)
return the lower bound of the interval on a given parameter
virtual void SetConfidenceLevel(Double_t cl)
set the confidence level for the interval (e.g 0.682 for a 1-sigma interval)
Double_t UpperLimit(const RooRealVar &param)
return the upper bound of the interval on a given parameter
virtual Bool_t IsInInterval(const RooArgSet &) const
check if given point is in the interval
A factory for building PDFs and data for a number counting combination.
ProfileLikelihoodCalculator is a concrete implementation of CombinedCalculator (the interface class f...
The RooWorkspace is a persistable container for RooFit projects.
Definition: RooWorkspace.h:43
RooAbsData * data(const char *name) const
Retrieve dataset (binned or unbinned) with given name. A null pointer is returned if not found.
RooRealVar * var(const char *name) const
Retrieve real-valued variable (RooRealVar) with given name. A null pointer is returned if not found.
RooAbsPdf * pdf(const char *name) const
Retrieve p.d.f (RooAbsPdf) with given name. A null pointer is returned if not found.
@(#)root/roostats:$Id$ Author: George Lewis, Kyle Cranmer
Definition: Asimov.h:20
static constexpr double s