Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
35#include "RooRealVar.h"
36
37#include <cassert>
38
39// use this order for safety on library loading
40using namespace RooFit;
41using namespace RooStats;
42
43// declare three variations on the same tutorial
44void rs_numberCountingCombination_expected();
45void rs_numberCountingCombination_observed();
46void rs_numberCountingCombination_observedWithTau();
47
48// -------------------------------
49// main driver to choose one
50void rs_numberCountingCombination(int flag = 1)
51{
52 if (flag == 1)
53 rs_numberCountingCombination_expected();
54 if (flag == 2)
55 rs_numberCountingCombination_observed();
56 if (flag == 3)
57 rs_numberCountingCombination_observedWithTau();
58}
59
60// -------------------------------
61void rs_numberCountingCombination_expected()
62{
63
64 /////////////////////////////////////////
65 // An example of a number counting combination with two channels.
66 // We consider both hypothesis testing and the equivalent confidence interval.
67 /////////////////////////////////////////
68
69 /////////////////////////////////////////
70 // The Model building stage
71 /////////////////////////////////////////
72
73 // Step 1, define arrays with signal & bkg expectations and background uncertainties
74 double s[2] = {20., 10.}; // expected signal
75 double b[2] = {100., 100.}; // expected background
76 double db[2] = {.0100, .0100}; // fractional background uncertainty
77
78 // Step 2, use a RooStats factory to build a PDF for a
79 // number counting combination and add it to the workspace.
80 // We need to give the signal expectation to relate the masterSignal
81 // to the signal contribution in the individual channels.
82 // The model neglects correlations in background uncertainty,
83 // but they could be added without much change to the example.
85 RooWorkspace wspace{};
86 f.AddModel(s, 2, &wspace, "TopLevelPdf", "masterSignal");
87
88 // Step 3, use a RooStats factory to add datasets to the workspace.
89 // Step 3a.
90 // Add the expected data to the workspace
91 f.AddExpData(s, b, db, 2, &wspace, "ExpectedNumberCountingData");
92
93 // see below for a printout of the workspace
94 // wspace.Print(); //uncomment to see structure of workspace
95
96 /////////////////////////////////////////
97 // The Hypothesis testing stage:
98 /////////////////////////////////////////
99 // Step 4, Define the null hypothesis for the calculator
100 // Here you need to know the name of the variables corresponding to hypothesis.
101 RooRealVar *mu = wspace.var("masterSignal");
102 RooArgSet poi{*mu};
103 RooArgSet nullParams{"nullParams"};
104 nullParams.addClone(*mu);
105 // here we explicitly set the value of the parameters for the null
106 nullParams.setRealValue("masterSignal", 0);
107
108 // Step 5, Create a calculator for doing the hypothesis test.
109 // because this is a
110 ProfileLikelihoodCalculator plc(*wspace.data("ExpectedNumberCountingData"), *wspace.pdf("TopLevelPdf"), poi, 0.05,
111 &nullParams);
112
113 // Step 6, Use the Calculator to get a HypoTestResult
114 std::unique_ptr<HypoTestResult> htr{plc.GetHypoTest()};
115 std::cout << "-------------------------------------------------" << std::endl;
116 std::cout << "The p-value for the null is " << htr->NullPValue() << std::endl;
117 std::cout << "Corresponding to a significance of " << htr->Significance() << std::endl;
118 std::cout << "-------------------------------------------------\n\n" << std::endl;
119
120 /* expected case should return:
121 -------------------------------------------------
122 The p-value for the null is 0.015294
123 Corresponding to a significance of 2.16239
124 -------------------------------------------------
125 */
126
127 //////////////////////////////////////////
128 // Confidence Interval Stage
129
130 // Step 8, Here we re-use the ProfileLikelihoodCalculator to return a confidence interval.
131 // We need to specify what are our parameters of interest
132 RooArgSet &paramsOfInterest = nullParams; // they are the same as before in this case
133 plc.SetParameters(paramsOfInterest);
134 std::unique_ptr<LikelihoodInterval> lrint{static_cast<LikelihoodInterval *>(plc.GetInterval())};
135 lrint->SetConfidenceLevel(0.95);
136
137 // Step 9, make a plot of the likelihood ratio and the interval obtained
138 // paramsOfInterest.setRealValue("masterSignal",1.);
139 // find limits
140 double lower = lrint->LowerLimit(*mu);
141 double upper = lrint->UpperLimit(*mu);
142
143 LikelihoodIntervalPlot lrPlot(lrint.get());
144 lrPlot.SetMaximum(3.);
145 lrPlot.Draw();
146
147 // Step 10a. Get upper and lower limits
148 std::cout << "lower limit on master signal = " << lower << std::endl;
149 std::cout << "upper limit on master signal = " << upper << std::endl;
150
151 // Step 10b, Ask if masterSignal=0 is in the interval.
152 // Note, this is equivalent to the question of a 2-sigma hypothesis test:
153 // "is the parameter point masterSignal=0 inside the 95% confidence interval?"
154 // Since the significance of the Hypothesis test was > 2-sigma it should not be:
155 // eg. we exclude masterSignal=0 at 95% confidence.
156 paramsOfInterest.setRealValue("masterSignal", 0.);
157 std::cout << "-------------------------------------------------" << std::endl;
158 std::cout << "Consider this parameter point:" << std::endl;
159 paramsOfInterest.first()->Print();
160 if (lrint->IsInInterval(paramsOfInterest))
161 std::cout << "It IS in the interval." << std::endl;
162 else
163 std::cout << "It is NOT in the interval." << std::endl;
164 std::cout << "-------------------------------------------------\n\n" << std::endl;
165
166 // Step 10c, We also ask about the parameter point masterSignal=2, which is inside the interval.
167 paramsOfInterest.setRealValue("masterSignal", 2.);
168 std::cout << "-------------------------------------------------" << std::endl;
169 std::cout << "Consider this parameter point:" << std::endl;
170 paramsOfInterest.first()->Print();
171 if (lrint->IsInInterval(paramsOfInterest))
172 std::cout << "It IS in the interval." << std::endl;
173 else
174 std::cout << "It is NOT in the interval." << std::endl;
175 std::cout << "-------------------------------------------------\n\n" << std::endl;
176
177 /*
178 // Here's an example of what is in the workspace
179 // wspace.Print();
180 RooWorkspace(NumberCountingWS) Number Counting WS contents
181
182 variables
183 ---------
184 (x_0,masterSignal,expected_s_0,b_0,y_0,tau_0,x_1,expected_s_1,b_1,y_1,tau_1)
185
186 p.d.f.s
187 -------
188 RooProdPdf::joint[ pdfs=(sigRegion_0,sideband_0,sigRegion_1,sideband_1) ] = 2.20148e-08
189 RooPoisson::sigRegion_0[ x=x_0 mean=splusb_0 ] = 0.036393
190 RooPoisson::sideband_0[ x=y_0 mean=bTau_0 ] = 0.00398939
191 RooPoisson::sigRegion_1[ x=x_1 mean=splusb_1 ] = 0.0380088
192 RooPoisson::sideband_1[ x=y_1 mean=bTau_1 ] = 0.00398939
193
194 functions
195 --------
196 RooAddition::splusb_0[ set1=(s_0,b_0) set2=() ] = 120
197 RooProduct::s_0[ compRSet=(masterSignal,expected_s_0) compCSet=() ] = 20
198 RooProduct::bTau_0[ compRSet=(b_0,tau_0) compCSet=() ] = 10000
199 RooAddition::splusb_1[ set1=(s_1,b_1) set2=() ] = 110
200 RooProduct::s_1[ compRSet=(masterSignal,expected_s_1) compCSet=() ] = 10
201 RooProduct::bTau_1[ compRSet=(b_1,tau_1) compCSet=() ] = 10000
202
203 datasets
204 --------
205 RooDataSet::ExpectedNumberCountingData(x_0,y_0,x_1,y_1)
206
207 embedded pre-calculated expensive components
208 -------------------------------------------
209 */
210}
211
212void rs_numberCountingCombination_observed()
213{
214
215 /////////////////////////////////////////
216 // The same example with observed data in a main
217 // measurement and an background-only auxiliary
218 // measurement with a factor tau more background
219 // than in the main measurement.
220
221 /////////////////////////////////////////
222 // The Model building stage
223 /////////////////////////////////////////
224
225 // Step 1, define arrays with signal & bkg expectations and background uncertainties
226 // We still need the expectation to relate signal in different channels with the master signal
227 double s[2] = {20., 10.}; // expected signal
228
229 // Step 2, use a RooStats factory to build a PDF for a
230 // number counting combination and add it to the workspace.
231 // We need to give the signal expectation to relate the masterSignal
232 // to the signal contribution in the individual channels.
233 // The model neglects correlations in background uncertainty,
234 // but they could be added without much change to the example.
236 RooWorkspace wspace{};
237 f.AddModel(s, 2, &wspace, "TopLevelPdf", "masterSignal");
238
239 // Step 3, use a RooStats factory to add datasets to the workspace.
240 // Add the observed data to the workspace
241 double mainMeas[2] = {123., 117.}; // observed main measurement
242 double bkgMeas[2] = {111.23, 98.76}; // observed background
243 double dbMeas[2] = {.011, .0095}; // observed fractional background uncertainty
244 f.AddData(mainMeas, bkgMeas, dbMeas, 2, &wspace, "ObservedNumberCountingData");
245
246 // see below for a printout of the workspace
247 // wspace.Print(); //uncomment to see structure of workspace
248
249 /////////////////////////////////////////
250 // The Hypothesis testing stage:
251 /////////////////////////////////////////
252 // Step 4, Define the null hypothesis for the calculator
253 // Here you need to know the name of the variables corresponding to hypothesis.
254 RooRealVar *mu = wspace.var("masterSignal");
255 RooArgSet poi{*mu};
256 RooArgSet nullParams{"nullParams"};
257 nullParams.addClone(*mu);
258 // here we explicitly set the value of the parameters for the null
259 nullParams.setRealValue("masterSignal", 0);
260
261 // Step 5, Create a calculator for doing the hypothesis test.
262 // because this is a
263 ProfileLikelihoodCalculator plc(*wspace.data("ObservedNumberCountingData"), *wspace.pdf("TopLevelPdf"), poi, 0.05,
264 &nullParams);
265
266 wspace.var("tau_0")->Print();
267 wspace.var("tau_1")->Print();
268
269 // Step 7, Use the Calculator to get a HypoTestResult
270 std::unique_ptr<HypoTestResult> htr{plc.GetHypoTest()};
271 std::cout << "-------------------------------------------------" << std::endl;
272 std::cout << "The p-value for the null is " << htr->NullPValue() << std::endl;
273 std::cout << "Corresponding to a significance of " << htr->Significance() << std::endl;
274 std::cout << "-------------------------------------------------\n\n" << std::endl;
275
276 /* observed case should return:
277 -------------------------------------------------
278 The p-value for the null is 0.0351669
279 Corresponding to a significance of 1.80975
280 -------------------------------------------------
281 */
282
283 //////////////////////////////////////////
284 // Confidence Interval Stage
285
286 // Step 8, Here we re-use the ProfileLikelihoodCalculator to return a confidence interval.
287 // We need to specify what are our parameters of interest
288 RooArgSet &paramsOfInterest = nullParams; // they are the same as before in this case
289 plc.SetParameters(paramsOfInterest);
290 std::unique_ptr<LikelihoodInterval> lrint{static_cast<LikelihoodInterval *>(plc.GetInterval())};
291 lrint->SetConfidenceLevel(0.95);
292
293 // Step 9c. Get upper and lower limits
294 std::cout << "lower limit on master signal = " << lrint->LowerLimit(*mu) << std::endl;
295 std::cout << "upper limit on master signal = " << lrint->UpperLimit(*mu) << std::endl;
296}
297
298void rs_numberCountingCombination_observedWithTau()
299{
300
301 /////////////////////////////////////////
302 // The same example with observed data in a main
303 // measurement and an background-only auxiliary
304 // measurement with a factor tau more background
305 // than in the main measurement.
306
307 /////////////////////////////////////////
308 // The Model building stage
309 /////////////////////////////////////////
310
311 // Step 1, define arrays with signal & bkg expectations and background uncertainties
312 // We still need the expectation to relate signal in different channels with the master signal
313 double s[2] = {20., 10.}; // expected signal
314
315 // Step 2, use a RooStats factory to build a PDF for a
316 // number counting combination and add it to the workspace.
317 // We need to give the signal expectation to relate the masterSignal
318 // to the signal contribution in the individual channels.
319 // The model neglects correlations in background uncertainty,
320 // but they could be added without much change to the example.
322 RooWorkspace wspace{};
323 f.AddModel(s, 2, &wspace, "TopLevelPdf", "masterSignal");
324
325 // Step 3, use a RooStats factory to add datasets to the workspace.
326 // Add the observed data to the workspace in the on-off problem.
327 double mainMeas[2] = {123., 117.}; // observed main measurement
328 double sideband[2] = {11123., 9876.}; // observed sideband
329 double tau[2] = {100., 100.}; // ratio of bkg in sideband to bkg in main measurement, from experimental design.
330 f.AddDataWithSideband(mainMeas, sideband, tau, 2, &wspace, "ObservedNumberCountingDataWithSideband");
331
332 // see below for a printout of the workspace
333 // wspace.Print(); //uncomment to see structure of workspace
334
335 /////////////////////////////////////////
336 // The Hypothesis testing stage:
337 /////////////////////////////////////////
338 // Step 4, Define the null hypothesis for the calculator
339 // Here you need to know the name of the variables corresponding to hypothesis.
340 RooRealVar *mu = wspace.var("masterSignal");
341 RooArgSet poi{*mu};
342 RooArgSet nullParams{"nullParams"};
343 nullParams.addClone(*mu);
344 // here we explicitly set the value of the parameters for the null
345 nullParams.setRealValue("masterSignal", 0);
346
347 // Step 5, Create a calculator for doing the hypothesis test.
348 // because this is a
349 ProfileLikelihoodCalculator plc(*wspace.data("ObservedNumberCountingDataWithSideband"), *wspace.pdf("TopLevelPdf"),
350 poi, 0.05, &nullParams);
351
352 // Step 7, Use the Calculator to get a HypoTestResult
353 std::unique_ptr<HypoTestResult> htr{plc.GetHypoTest()};
354 std::cout << "-------------------------------------------------" << std::endl;
355 std::cout << "The p-value for the null is " << htr->NullPValue() << std::endl;
356 std::cout << "Corresponding to a significance of " << htr->Significance() << std::endl;
357 std::cout << "-------------------------------------------------\n\n" << std::endl;
358
359 /* observed case should return:
360 -------------------------------------------------
361 The p-value for the null is 0.0352035
362 Corresponding to a significance of 1.80928
363 -------------------------------------------------
364 */
365
366 //////////////////////////////////////////
367 // Confidence Interval Stage
368
369 // Step 8, Here we re-use the ProfileLikelihoodCalculator to return a confidence interval.
370 // We need to specify what are our parameters of interest
371 RooArgSet &paramsOfInterest = nullParams; // they are the same as before in this case
372 plc.SetParameters(paramsOfInterest);
373 std::unique_ptr<LikelihoodInterval> lrint{static_cast<LikelihoodInterval *>(plc.GetInterval())};
374 lrint->SetConfidenceLevel(0.95);
375
376 // Step 9c. Get upper and lower limits
377 std::cout << "lower limit on master signal = " << lrint->LowerLimit(*mu) << std::endl;
378 std::cout << "upper limit on master signal = " << lrint->UpperLimit(*mu) << std::endl;
379}
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
void Print(Option_t *options=nullptr) const override
Print the object to the defaultPrintStream().
Definition RooAbsArg.h:263
RooAbsArg * first() const
bool setRealValue(const char *name, double newVal=0.0, bool verbose=false)
Set value of a RooAbsRealLValue stored in set with given name to newVal No error messages are printed...
virtual RooAbsArg * addClone(const RooAbsArg &var, bool silent=false)
Add a clone of the specified argument to list.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
Variable that can be changed from the outside.
Definition RooRealVar.h:37
This class provides simple and straightforward utilities to plot a LikelihoodInterval object.
LikelihoodInterval is a concrete implementation of the RooStats::ConfInterval interface.
void SetConfidenceLevel(double cl) override
set the confidence level for the interval (e.g 0.682 for a 1-sigma interval)
A factory for building PDFs and data for a number counting combination.
The ProfileLikelihoodCalculator is a concrete implementation of CombinedCalculator (the interface cla...
Persistable container for RooFit projects.
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Definition CodegenImpl.h:64
Namespace for the RooStats classes.
Definition CodegenImpl.h:58