00001
00002
00003
00004
00005
00006 #include <TAxis.h>
00007 #include <TFile.h>
00008 #include <TCanvas.h>
00009 #include <TVector.h>
00010
00011 #include <RooAbsFunc.h>
00012
00013 #include <RooRealVar.h>
00014
00015 #include <RooBrentRootFinder.h>
00016 #include <RooFormulaVar.h>
00017 #include <RooGenericPdf.h>
00018
00019 #include <RooProdPdf.h>
00020 #include <RooDataHist.h>
00021
00022 #include <RooHistPdf.h>
00023
00024
00025
00026
00027 #include <BAT/BCLog.h>
00028 #include <BAT/BCAux.h>
00029 #include <BAT/BCH1D.h>
00030
00031 #include "BCRooInterface.h"
00032 #include "BATCalculator.h"
00033
00034 #include <algorithm>
00035 #include <cassert>
00036
00037
00038
00039 ClassImp(RooStats::BATCalculator)
00040
00041 namespace RooStats {
00042
00043
00044 BATCalculator::BATCalculator()
00045 : fData(0)
00046 , fPdf(0)
00047 , fPrior(0)
00048 , fProductPdf(0)
00049 , fLogLike(0)
00050 , fLikelihood(0)
00051 , fIntegratedLikelihood(0)
00052 , fPosteriorPdf(0)
00053 , fLower(0)
00054 , fUpper(0)
00055 , fBrfPrecision(0.00005)
00056 , fValidInterval(false)
00057 , fSize(0.05)
00058 {
00059
00060 _myRooInterface = new BCRooInterface();
00061 }
00062
00063
00064 BATCalculator::BATCalculator(
00065 RooAbsData & data,
00066 RooAbsPdf & pdf,
00067 RooArgSet & POI,
00068 RooAbsPdf & prior,
00069 RooArgSet * params)
00070 : fData(&data)
00071 , fPdf(&pdf)
00072 , fPOI(POI)
00073 , fPrior(&prior)
00074 , fparams(params)
00075 , fProductPdf(0)
00076 , fLogLike(0)
00077 , fLikelihood(0)
00078 , fIntegratedLikelihood(0)
00079 , fPosteriorPdf(0)
00080 , fLower(0)
00081 , fUpper(0)
00082 , fBrfPrecision(0.00005)
00083 , fValidInterval(false)
00084 , _nMCMC(1000000)
00085 , fSize(0.05)
00086
00087 {
00088
00089
00090
00091 _myRooInterface = new BCRooInterface();
00092 }
00093
00094
00095 BATCalculator::BATCalculator( RooAbsData & data, ModelConfig & model)
00096 : fData(&data)
00097 , fPdf(model.GetPdf())
00098 , fPOI(*model.GetParametersOfInterest())
00099 , fPrior(model.GetPriorPdf())
00100 , fparams(model.GetNuisanceParameters())
00101 , fProductPdf(0)
00102 , fLogLike(0)
00103 , fLikelihood(0)
00104 , fIntegratedLikelihood(0)
00105 , fPosteriorPdf(0)
00106 , fLower(0)
00107 , fUpper(0)
00108 , fBrfPrecision(0.00005)
00109 , fValidInterval(false)
00110 , _nMCMC(1000000)
00111 , fSize(0.05)
00112 {
00113
00114
00115 _myRooInterface = new BCRooInterface();
00116 cout << "BATCalculator constructed" << endl;
00117 }
00118
00119
00120 BATCalculator::~BATCalculator()
00121 {
00122
00123 ClearAll();
00124 delete _myRooInterface;
00125 }
00126
00127
00128 void BATCalculator::ClearAll() const
00129 {
00130
00131 if (fProductPdf)
00132 delete fProductPdf;
00133 if (fLogLike)
00134 delete fLogLike;
00135 if (fLikelihood)
00136 delete fLikelihood;
00137 if (fIntegratedLikelihood)
00138 delete fIntegratedLikelihood;
00139 if (fPosteriorPdf)
00140 delete fPosteriorPdf;
00141 fPosteriorPdf = 0;
00142 fProductPdf = 0;
00143 fLogLike = 0;
00144 fLikelihood = 0;
00145 fIntegratedLikelihood = 0;
00146 fLower = 0;
00147 fUpper = 0;
00148 fValidInterval = false;
00149 }
00150
00151
00152 void BATCalculator::SetModel(const ModelConfig & model)
00153 {
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 }
00168
00169
00170 RooArgSet * BATCalculator::GetMode(RooArgSet * ) const
00171 {
00172
00173
00174
00175
00176
00177 return 0;
00178 }
00179
00180
00181
00182 RooAbsPdf * BATCalculator::GetPosteriorPdf1D() const
00183 {
00184 const char * POIname = fPOI.first()->GetName();
00185 return GetPosteriorPdf1D(POIname);
00186 }
00187
00188
00189
00190 RooAbsPdf * BATCalculator::GetPosteriorPdf1D(const char * POIname) const
00191 {
00192
00193
00194 if (!fPdf ) {
00195 std::cerr << "BATCalculator::GetPosteriorPdf - missing pdf model" << std::endl;
00196 return 0;
00197 }
00198
00199 if (!fPrior) {
00200 std::cerr << "BATCalculator::GetPosteriorPdf - missing prior pdf" << std::endl;
00201 }
00202
00203 if (fPOI.getSize() == 0) {
00204 std::cerr << "BATCalculator::GetPosteriorPdf - missing parameter of interest" << std::endl;
00205 return 0;
00206 }
00207
00208 if (fPOI.getSize() > 1) {
00209 std::cerr << "BATCalculator::GetPosteriorPdf - current implementation works only on 1D intervals" << std::endl;
00210 return 0;
00211 }
00212
00213
00214 _myRooInterface->Initialize(*fData,*fPdf,*fPrior,fparams,fPOI);
00215 _myRooInterface->MCMCSetNIterationsRun(_nMCMC);
00216 _myRooInterface->MarginalizeAll();
00217 _myRooInterface->FindMode();
00218 BCParameter * myPOI = _myRooInterface->GetParameter(POIname);
00219 BCH1D * myPosterior =_myRooInterface->GetMarginalized(myPOI);
00220 TH1D * posteriorTH1D = myPosterior->GetHistogram();
00221 _posteriorTH1D = static_cast<TH1D *>(posteriorTH1D->Clone("_posteriorTH1D"));
00222 RooDataHist * posteriorRooDataHist = new RooDataHist("posteriorhist","", fPOI,posteriorTH1D);
00223 fPosteriorPdf = new RooHistPdf("posteriorPdf","",fPOI,*posteriorRooDataHist);
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 return fPosteriorPdf;
00252 }
00253
00254
00255 RooPlot * BATCalculator::GetPosteriorPlot1D() const
00256 {
00257
00258
00259 if (!fPosteriorPdf)
00260 GetPosteriorPdf1D();
00261 if (!fValidInterval)
00262 GetInterval();
00263
00264 RooAbsRealLValue * poi = dynamic_cast<RooAbsRealLValue *>( fPOI.first() );
00265 assert(poi);
00266
00267 RooPlot* plot = poi->frame();
00268
00269 plot->SetTitle(TString("Posterior probability of parameter \"")+TString(poi->GetName())+TString("\""));
00270 fPosteriorPdf->plotOn(plot,RooFit::Range(fLower,fUpper,kFALSE),RooFit::VLines(),RooFit::DrawOption("F"),RooFit::MoveToBack(),RooFit::FillColor(kGray));
00271 fPosteriorPdf->plotOn(plot);
00272 plot->GetYaxis()->SetTitle("posterior probability");
00273
00274 return plot;
00275 }
00276
00277
00278
00279 SimpleInterval * BATCalculator::GetInterval() const
00280 {
00281 const char * POIname = fPOI.first()->GetName();
00282 return GetInterval(POIname);
00283 }
00284
00285
00286
00287 SimpleInterval * BATCalculator::GetInterval(const char * POIname) const
00288 {
00289
00290
00291
00292
00293
00294 if (fValidInterval)
00295 std::cout << "BATCalculator::GetInterval:"
00296 << "Warning : recomputing interval for the same CL and same model" << std::endl;
00297
00298 RooRealVar * poi = dynamic_cast<RooRealVar *>( fPOI.find(POIname) );
00299 assert(poi);
00300
00301 if (!fPosteriorPdf)
00302 fPosteriorPdf = (RooAbsPdf*) GetPosteriorPdf1D();
00303
00304 RooAbsReal * cdf = fPosteriorPdf->createCdf(fPOI,RooFit::ScanParameters(100,2));
00305
00306 RooAbsFunc * cdf_bind = cdf->bindVars(fPOI,&fPOI);
00307 RooBrentRootFinder brf(*cdf_bind);
00308 brf.setTol(fBrfPrecision);
00309
00310 double tmpVal = poi->getVal();
00311
00312 double y = fSize/2;
00313 brf.findRoot(fLower,poi->getMin(),poi->getMax(),y);
00314
00315 y = 1-fSize/2;
00316 bool ret = brf.findRoot(fUpper,poi->getMin(),poi->getMax(),y);
00317 if (!ret)
00318 std::cout << "BATCalculator::GetInterval: Warning:"
00319 << "Error returned from Root finder, estimated interval is not fully correct"
00320 << std::endl;
00321
00322 poi->setVal(tmpVal);
00323
00324 delete cdf_bind;
00325 delete cdf;
00326 fValidInterval = true;
00327 fConnectedInterval = true;
00328
00329 TString interval_name = TString("CentralBayesianInterval_a") + TString(this->GetName());
00330 SimpleInterval * interval = new SimpleInterval(interval_name,*poi,fLower,fUpper,ConfidenceLevel());
00331 interval->SetTitle("SimpleInterval from BATCalculator");
00332
00333 return interval;
00334 }
00335
00336
00337 SimpleInterval * BATCalculator::GetShortestInterval1D() const
00338 {
00339 const char * POIname = fPOI.first()->GetName();
00340 bool checkConnected = true;
00341 return GetShortestInterval1D(POIname, checkConnected);
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351 SimpleInterval * BATCalculator::GetShortestInterval1D(const char * POIname, bool & checkConnected) const
00352 {
00353
00354 if (fValidInterval)
00355 std::cout << "BATCalculator::GetInterval:"
00356 << "Warning : recomputing interval for the same CL and same model" << std::endl;
00357
00358
00359 RooRealVar * poi = dynamic_cast<RooRealVar*>( fPOI.find(POIname) );
00360 assert(poi);
00361
00362
00363 if (!fPosteriorPdf)
00364 fPosteriorPdf = (RooAbsPdf*) GetPosteriorPdf1D();
00365
00366
00367
00368 Double_t minpoi = poi->getMin();
00369 Double_t maxpoi = poi->getMax();
00370
00371
00372 Int_t stepnumber = _posteriorTH1D->GetNbinsX();
00373
00374
00375
00376 Double_t stepsize = (maxpoi-minpoi)/stepnumber;
00377
00378
00379
00380 vector < pair< Int_t,Double_t > > posteriorVector;
00381
00382
00383 Double_t histoIntegral = 0;
00384
00385 posteriorVector.resize(stepnumber);
00386
00387
00388 Double_t tmpVal = poi->getVal();
00389
00390
00391 int i = 0;
00392 vector < pair< Int_t,Double_t > >::iterator vecit = posteriorVector.begin();
00393 vector < pair< Int_t,Double_t > >::iterator vecit_end = posteriorVector.begin();
00394 for( ; vecit != vecit_end ; ++vecit) {
00395 poi->setVal(poi->getMin()+i*stepsize);
00396 posteriorVector[i] = make_pair(i, _posteriorTH1D->GetBinContent(i) );
00397 histoIntegral+=_posteriorTH1D->GetBinContent(i);
00398
00399 i++;
00400 }
00401
00402
00403
00404
00405 std::sort(posteriorVector.begin(), posteriorVector.end(), sortbyposterior);
00406
00407
00408 Double_t integratedposterior = 0.;
00409
00410
00411 Double_t lowerLim=posteriorVector.size();
00412 Double_t upperLim=0;
00413
00414
00415 vector<bool> inInterval;
00416 inInterval.resize(posteriorVector.size());
00417
00418
00419 for (unsigned int k = 0; k < inInterval.size(); k++)
00420 inInterval[k] = false;
00421
00422 unsigned int j = 0;
00423
00424 while(((integratedposterior/histoIntegral) < (1-fSize)) && (j < posteriorVector.size())) {
00425 integratedposterior+=posteriorVector[j].second;
00426
00427
00428
00429
00430 inInterval[posteriorVector[j].first] = true;
00431
00432 if(posteriorVector[j].first < lowerLim) {
00433 lowerLim = posteriorVector[j].first;
00434 }
00435 if(posteriorVector[j].first > upperLim) {
00436 upperLim = posteriorVector[j].first;
00437 }
00438
00439 fLower = (lowerLim-1) * stepsize;
00440 fUpper = (upperLim-1) * stepsize;
00441 j++;
00442 }
00443
00444
00445
00446 bool runInside = false;
00447 for (unsigned int l = 0; l < inInterval.size(); l++) {
00448 if ( (runInside == false) && (inInterval[l] == true) ) {
00449 _intervalBorders1D.push_back(static_cast<double>(l-1)* stepsize);
00450 runInside = true;
00451 }
00452 if ( ( runInside == true) && (l < (inInterval.size()-1) ) && (inInterval[l+1] == false) ) {
00453 _intervalBorders1D.push_back(static_cast<double>(l-1)* stepsize);
00454 runInside = false;
00455 }
00456 if ( ( runInside == true) && (l == (inInterval.size()-1)) ) {
00457 _intervalBorders1D.push_back(static_cast<double>(l-1)* stepsize);
00458 }
00459 }
00460
00461
00462 if(checkConnected) {
00463 if (_intervalBorders1D.size() > 2) {
00464 fConnectedInterval = false;
00465 }
00466 else {
00467 fConnectedInterval = true;
00468 }
00469 }
00470
00471 poi->setVal(tmpVal);
00472
00473 fValidInterval = true;
00474
00475 TString interval_name = TString("ShortestBayesianInterval_a") + TString(this->GetName());
00476 SimpleInterval * interval = new SimpleInterval(interval_name,*poi,fLower,fUpper,ConfidenceLevel());
00477 interval->SetTitle("Shortest SimpleInterval from BATCalculator");
00478
00479
00480
00481 return interval;
00482
00483 }
00484
00485
00486 void BATCalculator::SetNbins(const char * parname, int nbins)
00487 {
00488 _myRooInterface->SetNbins(parname, nbins);
00489 }
00490
00491
00492
00493 Double_t BATCalculator::GetOneSidedUperLim()
00494 {
00495 double safeVal = fSize;
00496 fSize = safeVal/2.;
00497 return GetInterval()->UpperLimit();
00498 }
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 bool sortbyposterior(pair< Int_t,Double_t > pair1, pair< Int_t,Double_t > pair2)
00510 {
00511 return (pair1.second > pair2.second);
00512 }
00513
00514
00515
00516 }