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