Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
NumberCountingPdfFactory.cxx
Go to the documentation of this file.
1// @(#)root/roostats:$Id$
2// Author: Kyle Cranmer 28/07/2008
3
4/*************************************************************************
5 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12////////////////////////////////////////////////////////////////////////////////
13
14/** \class RooStats::NumberCountingPdfFactory
15 \ingroup Roostats
16
17A factory for building PDFs and data for a number counting combination.
18The factory produces a PDF for N channels with uncorrelated background
19uncertainty. Correlations can be added by extending this PDF with additional terms.
20The factory relates the signal in each channel to a master signal strength times the
21expected signal in each channel. Thus, the final test is performed on the master signal strength.
22This yields a more powerful test than letting signal in each channel be independent.
23
24The problem has been studied in these references:
25
26 - http://arxiv.org/abs/physics/0511028
27 - http://arxiv.org/abs/physics/0702156
28 - http://cdsweb.cern.ch/record/1099969?ln=en
29
30One can incorporate uncertainty on the expected signal by adding additional terms.
31For the future, perhaps this factory should be extended to include the efficiency terms automatically.
32
33*/
34
36
38
39#include "RooRealVar.h"
40#include "RooAddition.h"
41#include "RooProduct.h"
42#include "RooDataSet.h"
43#include "RooProdPdf.h"
44#include "RooFitResult.h"
45#include "RooPoisson.h"
46#include "RooGlobalFunc.h"
47#include "RooCmdArg.h"
48#include "RooWorkspace.h"
49#include "RooMsgService.h"
50#include "TTree.h"
51#include <sstream>
52
53
54
55
56
57////////////////////////////////////////////////////////////////////////////////
58/// This method produces a PDF for N channels with uncorrelated background
59/// uncertainty. It relates the signal in each channel to a master signal strength times the
60/// expected signal in each channel.
61///
62/// For the future, perhaps this method should be extended to include the efficiency terms automatically.
63
65 const char *muName)
66{
68
69 // double MaxSigma = 8; // Needed to set ranges for variables.
70
72 new RooRealVar(muName,"masterSignal",1., 0., 3.);
73
74
75 // loop over individual channels
76 for(Int_t i=0; i<nbins; ++i){
77 // need to name the variables dynamically, so please forgive the string manipulation and focus on values & ranges.
78 std::stringstream str;
79 str<<"_"<<i;
81 new RooRealVar(("expected_s"+str.str()).c_str(),("expected_s"+str.str()).c_str(),sig[i], 0., 2*sig[i]);
82 expectedSignal->setConstant(true);
83
84 RooProduct* s =
85 new RooProduct(("s"+str.str()).c_str(),("s"+str.str()).c_str(), RooArgSet(*masterSignal, *expectedSignal));
86
87 RooRealVar* b =
88 new RooRealVar(("b"+str.str()).c_str(),("b"+str.str()).c_str(), .5, 0.,1.);
89 RooRealVar* tau =
90 new RooRealVar(("tau"+str.str()).c_str(),("tau"+str.str()).c_str(), .5, 0., 1.);
91 tau->setConstant(true);
92
94 new RooAddition(("splusb"+str.str()).c_str(),("s"+str.str()+"+"+"b"+str.str()).c_str(),
95 RooArgSet(*s,*b));
97 new RooProduct(("bTau"+str.str()).c_str(),("b*tau"+str.str()).c_str(), RooArgSet(*b, *tau));
98 RooRealVar* x =
99 new RooRealVar(("x"+str.str()).c_str(),("x"+str.str()).c_str(), 0.5 , 0., 1.);
100 RooRealVar* y =
101 new RooRealVar(("y"+str.str()).c_str(),("y"+str.str()).c_str(), 0.5, 0., 1.);
102
103
105 new RooPoisson(("sigRegion"+str.str()).c_str(),("sigRegion"+str.str()).c_str(), *x,*splusb);
106
107 //LM: need to set noRounding since y can take non integer values
109 new RooPoisson(("sideband"+str.str()).c_str(),("sideband"+str.str()).c_str(), *y,*bTau,true);
110
113
114 }
115
118 // joint.printCompactTree();
119
120 // add this PDF to workspace.
121 // Need to do import into workspace now to get all the structure imported as well.
122 // Just returning the WS will loose the rest of the structure b/c it will go out of scope
123 RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;
124 ws->import(joint);
125 RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;
126}
127
128////////////////////////////////////////////////////////////////////////////////
129/// Arguments are an array of expected signal, expected background, and relative
130/// background uncertainty (eg. 0.1 for 10% uncertainty), and the number of channels.
131
132void RooStats::NumberCountingPdfFactory::AddExpData(double *sig, double *back, double *back_syst, Int_t nbins,
133 RooWorkspace *ws, const char *dsName)
134{
135 std::vector<double> mainMeas(nbins);
136
137 // loop over channels
138 for(Int_t i=0; i<nbins; ++i){
139 mainMeas[i] = sig[i] + back[i];
140 }
141 return AddData(&mainMeas[0], back, back_syst, nbins, ws, dsName);
142}
143
144////////////////////////////////////////////////////////////////////////////////
145/// Arguments are an array of expected signal, expected background, and relative
146/// ratio of background expected in the sideband to that expected in signal region,
147/// and the number of channels.
148
150 Int_t nbins, RooWorkspace *ws, const char *dsName)
151{
152 std::vector<double> mainMeas(nbins);
153 std::vector<double> sideband(nbins);
154 for(Int_t i=0; i<nbins; ++i){
155 mainMeas[i] = sigExp[i] + backExp[i];
156 sideband[i] = backExp[i]*tau[i];
157 }
158 return AddDataWithSideband(&mainMeas[0], &sideband[0], tau, nbins, ws, dsName);
159
160}
161
162////////////////////////////////////////////////////////////////////////////////
163/// need to be careful here that the range of observable in the dataset is consistent with the one in the workspace
164/// don't rescale unless necessary. If it is necessary, then rescale by x10 or a defined maximum.
165
168{
169 return SafeObservableCreation(ws, varName, value, 10. * value);
170}
171
172////////////////////////////////////////////////////////////////////////////////
173/// need to be careful here that the range of observable in the dataset is consistent with the one in the workspace
174/// don't rescale unless necessary. If it is necessary, then rescale by x10 or a defined maximum.
175
177 double value, double maximum)
178{
179 RooRealVar* x = ws->var( varName );
180 if( !x )
181 x = new RooRealVar(varName, varName, value, 0, maximum );
182 if( x->getMax() < value )
183 x->setMax( std::max(x->getMax(), 10*value ) );
184 x->setVal( value );
185
186 return x;
187}
188
189
190////////////////////////////////////////////////////////////////////////////////
191/// Arguments are an array of results from a main measurement, a measured background,
192/// and relative background uncertainty (eg. 0.1 for 10% uncertainty), and the number of channels.
193
194void RooStats::NumberCountingPdfFactory::AddData(double *mainMeas, double *back, double *back_syst, Int_t nbins,
195 RooWorkspace *ws, const char *dsName)
196{
197 double MaxSigma = 8; // Needed to set ranges for variables.
198
200
201 TTree* tree = new TTree();
202 std::vector<double> xForTree(nbins);
203 std::vector<double> yForTree(nbins);
204
205 // loop over channels
206 for(Int_t i=0; i<nbins; ++i){
207 std::stringstream str;
208 str<<"_"<<i;
209
210 //double _tau = 1./back[i]/back_syst[i]/back_syst[i];
211 // LM: compute tau correctly for the Gamma distribution : mode = tau*b and variance is (tau*b+1)
212 double err = back_syst[i];
213 double _tau = (1.0 + sqrt(1 + 4 * err * err))/ (2. * err * err)/ back[i];
214
215 RooRealVar* tau = SafeObservableCreation(ws, ("tau"+str.str()).c_str(), _tau );
216
217 oocoutW(ws,ObjectHandling) << "NumberCountingPdfFactory: changed value of " << tau->GetName() << " to " << tau->getVal() <<
218 " to be consistent with background and its uncertainty. " <<
219 " Also stored these values of tau into workspace with name . " << (std::string{tau->GetName()}+dsName).c_str() <<
220 " if you test with a different dataset, you should adjust tau appropriately.\n"<< std::endl;
221 RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;
222 ws->import(*(static_cast<RooRealVar*>(tau->clone( (std::string{tau->GetName()}+dsName).c_str() )) ) );
223 RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;
224
225 // need to be careful
226 RooRealVar* x = SafeObservableCreation(ws, ("x"+str.str()).c_str(), mainMeas[i]);
227
228 // need to be careful
229 RooRealVar* y = SafeObservableCreation(ws, ("y"+str.str()).c_str(), back[i]*_tau );
230
233
234 xForTree[i] = mainMeas[i];
235 yForTree[i] = back[i]*_tau;
236
237 tree->Branch(("x"+str.str()).c_str(), &xForTree[i] ,("x"+str.str()+"/D").c_str());
238 tree->Branch(("y"+str.str()).c_str(), &yForTree[i] ,("y"+str.str()+"/D").c_str());
239
240 ws->var("b"+str.str())->setMax( 1.2*back[i]+MaxSigma*(sqrt(back[i])+back[i]*back_syst[i]) );
241 ws->var("b"+str.str())->setVal( back[i] );
242
243 }
244 tree->Fill();
245 // tree->Print();
246 // tree->Scan();
247
249
250 // observableSet->Print();
251 // observableList->Print();
252
253 RooDataSet data{dsName,"Number Counting Data", *observableList, RooFit::Import(*tree)}; // one experiment
254
255 // import hypothetical data
256 RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL) ;
257 ws->import(data);
258 RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;
259
260}
261
262////////////////////////////////////////////////////////////////////////////////
263/// Arguments are an array of expected signal, expected background, and relative
264/// background uncertainty (eg. 0.1 for 10% uncertainty), and the number of channels.
265
267 Int_t nbins, RooWorkspace *ws, const char *dsName)
268{
269 double MaxSigma = 8; // Needed to set ranges for variables.
270
272
273 TTree* tree = new TTree();
274
275 std::vector<double> xForTree(nbins);
276 std::vector<double> yForTree(nbins);
277
278
279 // loop over channels
280 for(Int_t i=0; i<nbins; ++i){
281 std::stringstream str;
282 str<<"_"<<i;
283
284 double _tau = tauForTree[i];
285 double back_syst = 1./sqrt(sideband[i]);
286 double back = (sideband[i]/_tau);
287
288
289 RooRealVar* tau = SafeObservableCreation(ws, ("tau"+str.str()).c_str(), _tau );
290
291 oocoutW(ws,ObjectHandling) << "NumberCountingPdfFactory: changed value of " << tau->GetName() << " to " << tau->getVal() <<
292 " to be consistent with background and its uncertainty. " <<
293 " Also stored these values of tau into workspace with name . " << (std::string{tau->GetName()}+dsName).c_str() <<
294 " if you test with a different dataset, you should adjust tau appropriately.\n"<< std::endl;
295 RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;
296 ws->import(*(static_cast<RooRealVar*>(tau->clone( (std::string{tau->GetName()}+dsName).c_str() )) ) );
297 RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;
298
299 // need to be careful
300 RooRealVar* x = SafeObservableCreation(ws, ("x"+str.str()).c_str(), mainMeas[i]);
301
302 // need to be careful
303 RooRealVar* y = SafeObservableCreation(ws, ("y"+str.str()).c_str(), sideband[i] );
304
305
308
309 xForTree[i] = mainMeas[i];
310 yForTree[i] = sideband[i];
311
312 tree->Branch(("x"+str.str()).c_str(), &xForTree[i] ,("x"+str.str()+"/D").c_str());
313 tree->Branch(("y"+str.str()).c_str(), &yForTree[i] ,("y"+str.str()+"/D").c_str());
314
315 ws->var("b"+str.str())->setMax( 1.2*back+MaxSigma*(sqrt(back)+back*back_syst) );
316 ws->var("b"+str.str())->setVal( back );
317
318 }
319 tree->Fill();
320
322
323 RooDataSet data{dsName,"Number Counting Data", observableList, RooFit::Import(*tree)}; // one experiment
324
325 // import hypothetical data
326 RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL) ;
327 ws->import(data);
328 RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;
329}
#define b(i)
Definition RSha256.hxx:100
#define oocoutW(o, a)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
void setConstant(bool value=true)
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:103
Calculates the sum of a set of RooAbsReal terms, or when constructed with two sets,...
Definition RooAddition.h:27
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition RooArgList.h:22
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
Container class to hold unbinned data.
Definition RooDataSet.h:34
static RooMsgService & instance()
Return reference to singleton instance.
Poisson pdf.
Definition RooPoisson.h:19
Efficient implementation of a product of PDFs of the form.
Definition RooProdPdf.h:36
Represents the product of a given set of RooAbsReal objects.
Definition RooProduct.h:29
Variable that can be changed from the outside.
Definition RooRealVar.h:37
void setVal(double value) override
Set value of variable to 'value'.
TObject * clone(const char *newname) const override
Definition RooRealVar.h:48
void setMax(const char *name, double value)
Set maximum of name range to given value.
void AddDataWithSideband(double *mainMeas, double *sideband, double *tau, Int_t nbins, RooWorkspace *ws, const char *dsName="ExpectedNumberCountingData")
Arguments are an array of expected signal, expected background, and relative background uncertainty (...
void AddModel(double *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.
void AddData(double *mainMeas, double *bkgMeas, double *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...
void AddExpData(double *sigExp, double *bkgExp, double *db, Int_t nbins, RooWorkspace *ws, const char *dsName="ExpectedNumberCountingData")
Arguments are an array of expected signal, expected background, and relative background uncertainty (...
RooRealVar * SafeObservableCreation(RooWorkspace *ws, const char *varName, double value)
need to be careful here that the range of observable in the dataset is consistent with the one in the...
void AddExpDataWithSideband(double *sigExp, double *bkgExp, double *tau, Int_t nbins, RooWorkspace *ws, const char *dsName="NumberCountingData")
Arguments are an array of expected signal, expected background, and relative ratio of background expe...
Persistable container for RooFit projects.
RooRealVar * var(RooStringView name) const
Retrieve real-valued variable (RooRealVar) with given name. A null pointer is returned if not found.
bool import(const RooAbsArg &arg, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}, const RooCmdArg &arg9={})
Import a RooAbsArg object, e.g.
A doubly linked list.
Definition TList.h:38
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
A TTree represents a columnar dataset.
Definition TTree.h:79
RooCmdArg Import(const char *state, TH1 &histo)
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17