Logo ROOT   6.14/05
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 #include <cassert>
39 
40 // use this order for safety on library loading
41 using namespace RooFit;
42 using namespace RooStats;
43 
44 
45 // declare three variations on the same tutorial
46 void rs_numberCountingCombination_expected();
47 void rs_numberCountingCombination_observed();
48 void rs_numberCountingCombination_observedWithTau();
49 
50 // -------------------------------
51 // main driver to choose one
52 void 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 // -------------------------------
63 void 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 
231 void 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 
328 void 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 }
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:547
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...
#define f(i)
Definition: RSha256.hxx:104
A factory for building PDFs and data for a number counting combination.
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")
Arguments are an array of expected signal, expected background, and relative background uncertainty (...
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:36
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
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
static constexpr double s
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")
Arguments are an array of expected signal, expected background, and relative background uncertainty (...
void AddData(Double_t *mainMeas, Double_t *bkgMeas, Double_t *db, Int_t nbins, RooWorkspace *ws, const char *dsName="NumberCountingData")
Arguments are an array of results from a main measurement, a measured background, and relative backgr...
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")
This method produces a PDF for N channels with uncorrelated background uncertainty.
The RooWorkspace is a persistable container for RooFit projects.
Definition: RooWorkspace.h:43