55 ClassImp(RooStats::NumberCountingPdfFactory); ;
58 using namespace RooStats;
59 using namespace RooFit;
66 NumberCountingPdfFactory::NumberCountingPdfFactory() {
72 NumberCountingPdfFactory::~NumberCountingPdfFactory(){
82 void NumberCountingPdfFactory::AddModel(Double_t* sig,
85 const char* pdfName,
const char* muName) {
89 using namespace RooFit;
92 TList likelihoodFactors;
96 RooRealVar* masterSignal =
97 new RooRealVar(muName,
"masterSignal",1., 0., 3.);
101 for(Int_t i=0; i<nbins; ++i){
103 std::stringstream str;
105 RooRealVar* expectedSignal =
106 new RooRealVar((
"expected_s"+str.str()).c_str(),(
"expected_s"+str.str()).c_str(),sig[i], 0., 2*sig[i]);
107 expectedSignal->setConstant(kTRUE);
110 new RooProduct((
"s"+str.str()).c_str(),(
"s"+str.str()).c_str(), RooArgSet(*masterSignal, *expectedSignal));
113 new RooRealVar((
"b"+str.str()).c_str(),(
"b"+str.str()).c_str(), .5, 0.,1.);
115 new RooRealVar((
"tau"+str.str()).c_str(),(
"tau"+str.str()).c_str(), .5, 0., 1.);
116 tau->setConstant(kTRUE);
118 RooAddition* splusb =
119 new RooAddition((
"splusb"+str.str()).c_str(),(
"s"+str.str()+
"+"+
"b"+str.str()).c_str(),
122 new RooProduct((
"bTau"+str.str()).c_str(),(
"b*tau"+str.str()).c_str(), RooArgSet(*b, *tau));
124 new RooRealVar((
"x"+str.str()).c_str(),(
"x"+str.str()).c_str(), 0.5 , 0., 1.);
126 new RooRealVar((
"y"+str.str()).c_str(),(
"y"+str.str()).c_str(), 0.5, 0., 1.);
129 RooPoisson* sigRegion =
130 new RooPoisson((
"sigRegion"+str.str()).c_str(),(
"sigRegion"+str.str()).c_str(), *x,*splusb);
133 RooPoisson* sideband =
134 new RooPoisson((
"sideband"+str.str()).c_str(),(
"sideband"+str.str()).c_str(), *y,*bTau,
true);
136 likelihoodFactors.Add(sigRegion);
137 likelihoodFactors.Add(sideband);
141 RooArgSet likelihoodFactorSet(likelihoodFactors);
142 RooProdPdf joint(pdfName,
"joint", likelihoodFactorSet );
148 RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;
150 RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;
157 void NumberCountingPdfFactory::AddExpData(Double_t* sig,
161 RooWorkspace* ws,
const char* dsName) {
163 std::vector<Double_t> mainMeas(nbins);
166 for(Int_t i=0; i<nbins; ++i){
167 mainMeas[i] = sig[i] + back[i];
169 return AddData(&mainMeas[0], back, back_syst, nbins, ws, dsName);
177 void NumberCountingPdfFactory::AddExpDataWithSideband(Double_t* sigExp,
181 RooWorkspace* ws,
const char* dsName) {
183 std::vector<Double_t> mainMeas(nbins);
184 std::vector<Double_t> sideband(nbins);
185 for(Int_t i=0; i<nbins; ++i){
186 mainMeas[i] = sigExp[i] + backExp[i];
187 sideband[i] = backExp[i]*tau[i];
189 return AddDataWithSideband(&mainMeas[0], &sideband[0], tau, nbins, ws, dsName);
197 RooRealVar* NumberCountingPdfFactory::SafeObservableCreation(RooWorkspace* ws,
const char* varName, Double_t value) {
198 return SafeObservableCreation(ws, varName, value, 10.*value);
206 RooRealVar* NumberCountingPdfFactory::SafeObservableCreation(RooWorkspace* ws,
const char* varName,
207 Double_t value, Double_t maximum) {
208 RooRealVar* x = ws->var( varName );
210 x =
new RooRealVar(varName, varName, value, 0, maximum );
211 if( x->getMax() < value )
212 x->setMax( max(x->getMax(), 10*value ) );
223 void NumberCountingPdfFactory::AddData(Double_t* mainMeas,
227 RooWorkspace* ws,
const char* dsName) {
229 using namespace RooFit;
232 Double_t MaxSigma = 8;
234 TList observablesCollection;
236 TTree* tree =
new TTree();
237 std::vector<Double_t> xForTree(nbins);
238 std::vector<Double_t> yForTree(nbins);
241 for(Int_t i=0; i<nbins; ++i){
242 std::stringstream str;
247 Double_t err = back_syst[i];
248 Double_t _tau = (1.0 + sqrt(1 + 4 * err * err))/ (2. * err * err)/ back[i];
250 RooRealVar* tau = SafeObservableCreation(ws, (
"tau"+str.str()).c_str(), _tau );
252 oocoutW(ws,ObjectHandling) <<
"NumberCountingPdfFactory: changed value of " << tau->GetName() <<
" to " << tau->getVal() <<
253 " to be consistent with background and its uncertainty. " <<
254 " Also stored these values of tau into workspace with name . " << (string(tau->GetName())+
string(dsName)).c_str() <<
255 " if you test with a different dataset, you should adjust tau appropriately.\n"<< endl;
256 RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;
257 ws->import(*((RooRealVar*) tau->clone( (
string(tau->GetName())+
string(dsName)).c_str() ) ) );
258 RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;
261 RooRealVar* x = SafeObservableCreation(ws, (
"x"+str.str()).c_str(), mainMeas[i]);
264 RooRealVar* y = SafeObservableCreation(ws, (
"y"+str.str()).c_str(), back[i]*_tau );
266 observablesCollection.Add(x);
267 observablesCollection.Add(y);
269 xForTree[i] = mainMeas[i];
270 yForTree[i] = back[i]*_tau;
272 tree->Branch((
"x"+str.str()).c_str(), &xForTree[i] ,(
"x"+str.str()+
"/D").c_str());
273 tree->Branch((
"y"+str.str()).c_str(), &yForTree[i] ,(
"y"+str.str()+
"/D").c_str());
275 ws->var((
"b"+str.str()).c_str())->setMax( 1.2*back[i]+MaxSigma*(sqrt(back[i])+back[i]*back_syst[i]) );
276 ws->var((
"b"+str.str()).c_str())->setVal( back[i] );
283 RooArgList* observableList =
new RooArgList(observablesCollection);
288 RooDataSet* data =
new RooDataSet(dsName,
"Number Counting Data", tree, *observableList);
293 RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL) ;
295 RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;
303 void NumberCountingPdfFactory::AddDataWithSideband(Double_t* mainMeas,
305 Double_t* tauForTree,
307 RooWorkspace* ws,
const char* dsName) {
309 using namespace RooFit;
312 Double_t MaxSigma = 8;
314 TList observablesCollection;
316 TTree* tree =
new TTree();
318 std::vector<Double_t> xForTree(nbins);
319 std::vector<Double_t> yForTree(nbins);
323 for(Int_t i=0; i<nbins; ++i){
324 std::stringstream str;
327 Double_t _tau = tauForTree[i];
328 Double_t back_syst = 1./sqrt(sideband[i]);
329 Double_t back = (sideband[i]/_tau);
332 RooRealVar* tau = SafeObservableCreation(ws, (
"tau"+str.str()).c_str(), _tau );
334 oocoutW(ws,ObjectHandling) <<
"NumberCountingPdfFactory: changed value of " << tau->GetName() <<
" to " << tau->getVal() <<
335 " to be consistent with background and its uncertainty. " <<
336 " Also stored these values of tau into workspace with name . " << (string(tau->GetName())+
string(dsName)).c_str() <<
337 " if you test with a different dataset, you should adjust tau appropriately.\n"<< endl;
338 RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;
339 ws->import(*((RooRealVar*) tau->clone( (
string(tau->GetName())+
string(dsName)).c_str() ) ) );
340 RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;
343 RooRealVar* x = SafeObservableCreation(ws, (
"x"+str.str()).c_str(), mainMeas[i]);
346 RooRealVar* y = SafeObservableCreation(ws, (
"y"+str.str()).c_str(), sideband[i] );
349 observablesCollection.Add(x);
350 observablesCollection.Add(y);
352 xForTree[i] = mainMeas[i];
353 yForTree[i] = sideband[i];
355 tree->Branch((
"x"+str.str()).c_str(), &xForTree[i] ,(
"x"+str.str()+
"/D").c_str());
356 tree->Branch((
"y"+str.str()).c_str(), &yForTree[i] ,(
"y"+str.str()+
"/D").c_str());
358 ws->var((
"b"+str.str()).c_str())->setMax( 1.2*back+MaxSigma*(sqrt(back)+back*back_syst) );
359 ws->var((
"b"+str.str()).c_str())->setVal( back );
366 RooArgList* observableList =
new RooArgList(observablesCollection);
371 RooDataSet* data =
new RooDataSet(dsName,
"Number Counting Data", tree, *observableList);
376 RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL) ;
378 RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;