00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef RooStats_NumberCountingPdfFactory
00040 #include "RooStats/NumberCountingPdfFactory.h"
00041 #endif
00042
00043 #ifndef RooStats_RooStatsUtils
00044 #include "RooStats/RooStatsUtils.h"
00045 #endif
00046
00047 #include "RooRealVar.h"
00048 #include "RooAddition.h"
00049 #include "RooProduct.h"
00050 #include "RooDataSet.h"
00051 #include "RooProdPdf.h"
00052 #include "RooFitResult.h"
00053 #include "RooPoisson.h"
00054 #include "RooGlobalFunc.h"
00055 #include "RooCmdArg.h"
00056 #include "RooWorkspace.h"
00057 #include "RooMsgService.h"
00058 #include "TTree.h"
00059 #include <sstream>
00060
00061
00062
00063 ClassImp(RooStats::NumberCountingPdfFactory) ;
00064
00065
00066 using namespace RooStats;
00067 using namespace RooFit;
00068
00069
00070
00071 NumberCountingPdfFactory::NumberCountingPdfFactory() {
00072
00073
00074 }
00075
00076
00077 NumberCountingPdfFactory::~NumberCountingPdfFactory(){
00078
00079 }
00080
00081
00082 void NumberCountingPdfFactory::AddModel(Double_t* sig,
00083 Int_t nbins,
00084 RooWorkspace* ws,
00085 const char* pdfName, const char* muName) {
00086
00087
00088
00089
00090
00091
00092
00093
00094 using namespace RooFit;
00095 using std::vector;
00096
00097 TList likelihoodFactors;
00098
00099
00100
00101 RooRealVar* masterSignal =
00102 new RooRealVar(muName,"masterSignal",1., 0., 3.);
00103
00104
00105
00106 for(Int_t i=0; i<nbins; ++i){
00107
00108 std::stringstream str;
00109 str<<"_"<<i;
00110 RooRealVar* expectedSignal =
00111 new RooRealVar(("expected_s"+str.str()).c_str(),("expected_s"+str.str()).c_str(),sig[i], 0., 2*sig[i]);
00112 expectedSignal->setConstant(kTRUE);
00113
00114 RooProduct* s =
00115 new RooProduct(("s"+str.str()).c_str(),("s"+str.str()).c_str(), RooArgSet(*masterSignal, *expectedSignal));
00116
00117 RooRealVar* b =
00118 new RooRealVar(("b"+str.str()).c_str(),("b"+str.str()).c_str(), .5, 0.,1.);
00119 RooRealVar* tau =
00120 new RooRealVar(("tau"+str.str()).c_str(),("tau"+str.str()).c_str(), .5, 0., 1.);
00121 tau->setConstant(kTRUE);
00122
00123 RooAddition* splusb =
00124 new RooAddition(("splusb"+str.str()).c_str(),("s"+str.str()+"+"+"b"+str.str()).c_str(),
00125 RooArgSet(*s,*b));
00126 RooProduct* bTau =
00127 new RooProduct(("bTau"+str.str()).c_str(),("b*tau"+str.str()).c_str(), RooArgSet(*b, *tau));
00128 RooRealVar* x =
00129 new RooRealVar(("x"+str.str()).c_str(),("x"+str.str()).c_str(), 0.5 , 0., 1.);
00130 RooRealVar* y =
00131 new RooRealVar(("y"+str.str()).c_str(),("y"+str.str()).c_str(), 0.5, 0., 1.);
00132
00133
00134 RooPoisson* sigRegion =
00135 new RooPoisson(("sigRegion"+str.str()).c_str(),("sigRegion"+str.str()).c_str(), *x,*splusb);
00136 RooPoisson* sideband =
00137 new RooPoisson(("sideband"+str.str()).c_str(),("sideband"+str.str()).c_str(), *y,*bTau);
00138
00139 likelihoodFactors.Add(sigRegion);
00140 likelihoodFactors.Add(sideband);
00141
00142 }
00143
00144 RooArgSet likelihoodFactorSet(likelihoodFactors);
00145 RooProdPdf joint(pdfName,"joint", likelihoodFactorSet );
00146
00147
00148
00149
00150
00151 RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;
00152 ws->import(joint);
00153 RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;
00154 }
00155
00156
00157 void NumberCountingPdfFactory::AddExpData(Double_t* sig,
00158 Double_t* back,
00159 Double_t* back_syst,
00160 Int_t nbins,
00161 RooWorkspace* ws, const char* dsName) {
00162
00163
00164
00165
00166 using std::vector;
00167 Double_t* mainMeas = new Double_t[nbins];
00168
00169
00170 for(Int_t i=0; i<nbins; ++i){
00171 mainMeas[i] = sig[i] + back[i];
00172 }
00173 return AddData(mainMeas, back, back_syst, nbins, ws, dsName);
00174 }
00175
00176
00177 void NumberCountingPdfFactory::AddExpDataWithSideband(Double_t* sigExp,
00178 Double_t* backExp,
00179 Double_t* tau,
00180 Int_t nbins,
00181 RooWorkspace* ws, const char* dsName) {
00182
00183
00184
00185
00186 Double_t* mainMeas = new Double_t[nbins];
00187 Double_t* sideband = new Double_t[nbins];
00188 for(Int_t i=0; i<nbins; ++i){
00189 mainMeas[i] = sigExp[i] + backExp[i];
00190 sideband[i] = backExp[i]*tau[i];
00191 }
00192 return AddDataWithSideband(mainMeas, sideband, tau, nbins, ws, dsName);
00193
00194 }
00195
00196
00197 RooRealVar* NumberCountingPdfFactory::SafeObservableCreation(RooWorkspace* ws, const char* varName, Double_t value) {
00198
00199
00200
00201 return SafeObservableCreation(ws, varName, value, 10.*value);
00202
00203 }
00204
00205
00206 RooRealVar* NumberCountingPdfFactory::SafeObservableCreation(RooWorkspace* ws, const char* varName,
00207 Double_t value, Double_t maximum) {
00208
00209
00210
00211 RooRealVar* x = ws->var( varName );
00212 if( !x )
00213 x = new RooRealVar(varName, varName, value, 0, maximum );
00214 if( x->getMax() < value )
00215 x->setMax( max(x->getMax(), 10*value ) );
00216 x->setVal( value );
00217
00218 return x;
00219 }
00220
00221
00222
00223 void NumberCountingPdfFactory::AddData(Double_t* mainMeas,
00224 Double_t* back,
00225 Double_t* back_syst,
00226 Int_t nbins,
00227 RooWorkspace* ws, const char* dsName) {
00228
00229
00230
00231
00232 using namespace RooFit;
00233 using std::vector;
00234
00235 Double_t MaxSigma = 8;
00236
00237 TList observablesCollection;
00238
00239 TTree* tree = new TTree();
00240 Double_t* xForTree = new Double_t[nbins];
00241 Double_t* yForTree = new Double_t[nbins];
00242
00243
00244 for(Int_t i=0; i<nbins; ++i){
00245 std::stringstream str;
00246 str<<"_"<<i;
00247
00248 Double_t _tau = 1./back[i]/back_syst[i]/back_syst[i];
00249 RooRealVar* tau = SafeObservableCreation(ws, ("tau"+str.str()).c_str(), _tau );
00250
00251 oocoutW(ws,ObjectHandling) << "NumberCountingPdfFactory: changed value of " << tau->GetName() << " to " << tau->getVal() <<
00252 " to be consistent with background and its uncertainty. " <<
00253 " Also stored these values of tau into workspace with name . " << (string(tau->GetName())+string(dsName)).c_str() <<
00254 " if you test with a different dataset, you should adjust tau appropriately.\n"<< endl;
00255 RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;
00256 ws->import(*((RooRealVar*) tau->clone( (string(tau->GetName())+string(dsName)).c_str() ) ) );
00257 RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;
00258
00259
00260 RooRealVar* x = SafeObservableCreation(ws, ("x"+str.str()).c_str(), mainMeas[i]);
00261
00262
00263 RooRealVar* y = SafeObservableCreation(ws, ("y"+str.str()).c_str(), back[i]*_tau );
00264
00265 observablesCollection.Add(x);
00266 observablesCollection.Add(y);
00267
00268 xForTree[i] = mainMeas[i];
00269 yForTree[i] = back[i]*_tau;
00270
00271 tree->Branch(("x"+str.str()).c_str(), xForTree+i ,("x"+str.str()+"/D").c_str());
00272 tree->Branch(("y"+str.str()).c_str(), yForTree+i ,("y"+str.str()+"/D").c_str());
00273
00274 ws->var(("b"+str.str()).c_str())->setMax( 1.2*back[i]+MaxSigma*(sqrt(back[i])+back[i]*back_syst[i]) );
00275 ws->var(("b"+str.str()).c_str())->setVal( back[i] );
00276
00277 }
00278 tree->Fill();
00279
00280
00281
00282 RooArgList* observableList = new RooArgList(observablesCollection);
00283
00284
00285
00286
00287 RooDataSet* data = new RooDataSet(dsName,"Number Counting Data", tree, *observableList);
00288
00289
00290
00291
00292 RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL) ;
00293 ws->import(*data);
00294 RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;
00295
00296 }
00297
00298
00299 void NumberCountingPdfFactory::AddDataWithSideband(Double_t* mainMeas,
00300 Double_t* sideband,
00301 Double_t* tauForTree,
00302 Int_t nbins,
00303 RooWorkspace* ws, const char* dsName) {
00304
00305
00306
00307
00308 using namespace RooFit;
00309 using std::vector;
00310
00311 Double_t MaxSigma = 8;
00312
00313 TList observablesCollection;
00314
00315 TTree* tree = new TTree();
00316 Double_t* xForTree = new Double_t[nbins];
00317 Double_t* yForTree = new Double_t[nbins];
00318
00319
00320 for(Int_t i=0; i<nbins; ++i){
00321 std::stringstream str;
00322 str<<"_"<<i;
00323
00324 Double_t _tau = tauForTree[i];
00325 Double_t back_syst = 1./sqrt(sideband[i]);
00326 Double_t back = (sideband[i]/_tau);
00327
00328
00329 RooRealVar* tau = SafeObservableCreation(ws, ("tau"+str.str()).c_str(), _tau );
00330
00331 oocoutW(ws,ObjectHandling) << "NumberCountingPdfFactory: changed value of " << tau->GetName() << " to " << tau->getVal() <<
00332 " to be consistent with background and its uncertainty. " <<
00333 " Also stored these values of tau into workspace with name . " << (string(tau->GetName())+string(dsName)).c_str() <<
00334 " if you test with a different dataset, you should adjust tau appropriately.\n"<< endl;
00335 RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;
00336 ws->import(*((RooRealVar*) tau->clone( (string(tau->GetName())+string(dsName)).c_str() ) ) );
00337 RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;
00338
00339
00340 RooRealVar* x = SafeObservableCreation(ws, ("x"+str.str()).c_str(), mainMeas[i]);
00341
00342
00343 RooRealVar* y = SafeObservableCreation(ws, ("y"+str.str()).c_str(), sideband[i] );
00344
00345
00346 observablesCollection.Add(x);
00347 observablesCollection.Add(y);
00348
00349 xForTree[i] = mainMeas[i];
00350 yForTree[i] = sideband[i];
00351
00352 tree->Branch(("x"+str.str()).c_str(), xForTree+i ,("x"+str.str()+"/D").c_str());
00353 tree->Branch(("y"+str.str()).c_str(), yForTree+i ,("y"+str.str()+"/D").c_str());
00354
00355 ws->var(("b"+str.str()).c_str())->setMax( 1.2*back+MaxSigma*(sqrt(back)+back*back_syst) );
00356 ws->var(("b"+str.str()).c_str())->setVal( back );
00357
00358 }
00359 tree->Fill();
00360
00361
00362
00363 RooArgList* observableList = new RooArgList(observablesCollection);
00364
00365
00366
00367
00368 RooDataSet* data = new RooDataSet(dsName,"Number Counting Data", tree, *observableList);
00369
00370
00371
00372
00373 RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL) ;
00374 ws->import(*data);
00375 RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;
00376
00377 }
00378
00379
00380