8 #include <RooAbsFunc.h>
10 #include <RooRealVar.h>
12 #include <RooBrentRootFinder.h>
13 #include <RooFormulaVar.h>
14 #include <RooGenericPdf.h>
16 #include <RooProdPdf.h>
17 #include <RooDataHist.h>
19 #include <RooHistPdf.h>
21 #include <RooStats/MarkovChain.h>
23 #include "../../BAT/BCLog.h"
24 #include "../../BAT/BCAux.h"
25 #include "../../BAT/BCH1D.h"
27 #include "BCRooInterface.h"
28 #include "BATCalculator.h"
39 BATCalculator::BATCalculator()
48 , fIntegratedLikelihood(0)
52 , fBrfPrecision(0.00005)
53 , fValidInterval(false)
54 , fValidMCMCInterval(false)
55 , fConnectedInterval(false)
58 , fLeftSideFraction(0.5)
65 BATCalculator::BATCalculator(
81 , fIntegratedLikelihood(0)
85 , fBrfPrecision(0.00005)
86 , fValidInterval(false)
87 , fValidMCMCInterval(false)
88 , fConnectedInterval(false)
91 , fLeftSideFraction(0.5)
97 _myRooInterface =
new BCRooInterface(
"BCRooInterfaceForBAT",fillChain);
101 BATCalculator::BATCalculator( RooAbsData & data, ModelConfig & model,
bool fillChain)
103 , fPdf(model.GetPdf())
104 , fPOI(*model.GetParametersOfInterest())
105 , fPrior(model.GetPriorPdf())
106 , fparams(model.GetNuisanceParameters())
111 , fIntegratedLikelihood(0)
115 , fBrfPrecision(0.00005)
116 , fValidInterval(false)
117 , fValidMCMCInterval(false)
118 , fConnectedInterval(false)
121 , fLeftSideFraction(0.5)
123 std::cout <<
"BATCalculator calling constructor ..." << std::endl;
126 _myRooInterface =
new BCRooInterface(
"BCRooInterfaceForBAT",fillChain);
127 std::cout <<
"BATCalculator constructed" << std::endl;
131 BATCalculator::~BATCalculator()
133 std::cout <<
"BATCalculator calling destructor ..." << std::endl;
136 delete _myRooInterface;
140 void BATCalculator::ClearAll()
const
149 if (fIntegratedLikelihood)
150 delete fIntegratedLikelihood;
152 delete fPosteriorPdf;
157 fIntegratedLikelihood = 0;
160 fValidInterval =
false;
161 fValidMCMCInterval =
false;
165 void BATCalculator::SetModel(
const ModelConfig & )
183 RooArgSet * BATCalculator::GetMode(RooArgSet * )
const
195 RooAbsPdf * BATCalculator::GetPosteriorPdf1D()
const
197 const char * POIname = fPOI.first()->GetName();
198 return GetPosteriorPdf1D(POIname);
203 RooAbsPdf * BATCalculator::GetPosteriorPdf1D(
const char * POIname)
const
208 std::cerr <<
"BATCalculator::GetPosteriorPdf - missing pdf model" << std::endl;
213 std::cerr <<
"BATCalculator::GetPosteriorPdf - missing prior pdf" << std::endl;
216 if (fPOI.getSize() == 0) {
217 std::cerr <<
"BATCalculator::GetPosteriorPdf - missing parameter of interest" << std::endl;
221 if (fPOI.getSize() > 1) {
222 std::cerr <<
"BATCalculator::GetPosteriorPdf - current implementation works only on 1D intervals" << std::endl;
227 _myRooInterface->Initialize(*fData,*fPdf,*fPrior,fparams,fPOI);
228 _myRooInterface->MCMCSetNIterationsRun(_nMCMC);
229 _myRooInterface->MarginalizeAll();
230 _myRooInterface->FindMode();
231 const BCParameter * myPOI = _myRooInterface->GetParameter(POIname);
232 BCH1D * myPosterior =_myRooInterface->GetMarginalized(myPOI);
234 _posteriorTH1D =
static_cast<TH1D *
>(posteriorTH1D->Clone(
"_posteriorTH1D"));
235 RooDataHist * posteriorRooDataHist =
new RooDataHist(
"posteriorhist",
"", fPOI,posteriorTH1D);
236 fPosteriorPdf =
new RooHistPdf(
"posteriorPdf",
"",fPOI,*posteriorRooDataHist);
264 return fPosteriorPdf;
269 RooPlot * BATCalculator::GetPosteriorPlot1D()
const
274 std::cout <<
"BATCalculator::GetPosteriorPlot1D:"
275 <<
"Warning : posterior not available" << std::endl;
278 if ((!fValidInterval) && (!fValidMCMCInterval)){
279 std::cout <<
"BATCalculator::GetPosteriorPlot1D:"
280 <<
"Warning : interval not available" << std::endl;
284 RooAbsRealLValue * poi =
dynamic_cast<RooAbsRealLValue *
>( fPOI.first() );
287 RooPlot* plot = poi->frame();
289 plot->SetTitle(TString(
"Posterior probability of parameter \"")+TString(poi->GetName())+TString(
"\""));
290 fPosteriorPdf->plotOn(plot,RooFit::Range(fLower,fUpper,kFALSE),RooFit::VLines(),RooFit::DrawOption(
"F"),RooFit::MoveToBack(),RooFit::FillColor(kGray));
291 fPosteriorPdf->plotOn(plot);
292 plot->GetYaxis()->SetTitle(
"posterior probability");
299 SimpleInterval * BATCalculator::GetInterval1D()
const
301 const char * POIname = fPOI.first()->GetName();
302 return GetInterval1D(POIname);
308 SimpleInterval * BATCalculator::GetInterval1D(
const char * POIname)
const
313 std::cout <<
"BATCalculator::GetShortestInterval1D:"
314 <<
"Warning : recomputing interval for the same CL and same model" << std::endl;
317 RooRealVar * poi =
dynamic_cast<RooRealVar*
>( fPOI.find(POIname) );
322 fPosteriorPdf = (RooAbsPdf*) GetPosteriorPdf1D();
326 Double_t minpoi = poi->getMin();
327 Double_t maxpoi = poi->getMax();
330 Int_t stepnumber = _posteriorTH1D->GetNbinsX();
331 std::cout <<
"stepnumber is: " << stepnumber << std::endl;
334 Double_t stepsize = (maxpoi-minpoi)/stepnumber;
335 std::cout <<
"stepsize is: " << stepsize << std::endl;
338 std::vector< std::pair< Int_t,Double_t > > posteriorVector;
341 Double_t histoIntegral = 0;
343 posteriorVector.resize(stepnumber);
351 std::vector< std::pair< Int_t,Double_t > >::iterator vecit = posteriorVector.begin();
352 std::vector< std::pair< Int_t,Double_t > >::iterator vecit_end = posteriorVector.end();
353 for( ; vecit != vecit_end ; ++vecit) {
354 poi->setVal(poi->getMin()+i*stepsize);
355 posteriorVector[i] = std::make_pair(i, _posteriorTH1D->GetBinContent(i+1) );
356 histoIntegral+=_posteriorTH1D->GetBinContent(i);
361 std::cout <<
"histoIntegral is: " << histoIntegral << std::endl;
363 double lowerProbLim = (1.-ConfidenceLevel())*fLeftSideFraction;
364 double upperProbLim = 1. -( (1.-ConfidenceLevel())*(1.-fLeftSideFraction) );
365 std::cout <<
"lowerProbLim is: " << lowerProbLim <<
"upperProbLim is: " << histoIntegral << std::endl;
369 bool lowerlimset =
false;
370 bool upperlimset =
false;
373 if(fLeftSideFraction == 0){
378 if(fLeftSideFraction == 1){
384 Double_t integratedposterior = 0.;
387 vecit = posteriorVector.begin();
388 for( ; vecit != vecit_end ; ++vecit) {
389 integratedposterior += posteriorVector[i].second;
390 if( (lowerlimset !=
true) && ((integratedposterior/histoIntegral) >= lowerProbLim) ){
391 fLower = poi->getMin()+i*stepsize;
394 if( (upperlimset !=
true) && ((integratedposterior/histoIntegral) >= upperProbLim) ){
395 fUpper = poi->getMin()+i*stepsize;
402 TString interval_name = TString(
"CentralBayesianInterval_a") + TString(this->GetName());
403 SimpleInterval * interval =
new SimpleInterval(interval_name,*poi,fLower,fUpper,ConfidenceLevel());
404 interval->SetTitle(
"SimpleInterval from BATCalculator");
479 SimpleInterval * BATCalculator::GetShortestInterval1D()
const
481 const char * POIname = fPOI.first()->GetName();
482 bool checkConnected =
true;
483 return GetShortestInterval1D(POIname, checkConnected);
493 SimpleInterval * BATCalculator::GetShortestInterval1D(
const char * POIname,
bool & checkConnected)
const
497 std::cout <<
"BATCalculator::GetShortestInterval1D:"
498 <<
"Warning : recomputing interval for the same CL and same model" << std::endl;
501 RooRealVar * poi =
dynamic_cast<RooRealVar*
>( fPOI.find(POIname) );
506 fPosteriorPdf = (RooAbsPdf*) GetPosteriorPdf1D();
510 Double_t minpoi = poi->getMin();
511 Double_t maxpoi = poi->getMax();
514 Int_t stepnumber = _posteriorTH1D->GetNbinsX();
515 std::cout <<
"stepnumber is: " << stepnumber << std::endl;
518 Double_t stepsize = (maxpoi-minpoi)/stepnumber;
519 std::cout <<
"stepsize is: " << stepsize << std::endl;
522 std::vector< std::pair< Int_t,Double_t > > posteriorVector;
525 Double_t histoIntegral = 0;
527 posteriorVector.resize(stepnumber);
530 Double_t tmpVal = poi->getVal();
534 std::vector< std::pair< Int_t,Double_t > >::iterator vecit = posteriorVector.begin();
535 std::vector< std::pair< Int_t,Double_t > >::iterator vecit_end = posteriorVector.end();
536 for( ; vecit != vecit_end ; ++vecit) {
537 poi->setVal(poi->getMin()+i*stepsize);
538 posteriorVector[i] = std::make_pair(i, _posteriorTH1D->GetBinContent(i+1) );
539 histoIntegral+=_posteriorTH1D->GetBinContent(i);
544 std::cout <<
"histoIntegral is: " << histoIntegral << std::endl;
547 std::sort(posteriorVector.begin(), posteriorVector.end(), sortbyposterior);
550 Double_t integratedposterior = 0.;
553 Double_t lowerLim=posteriorVector.size();
557 std::vector<bool> inInterval;
558 inInterval.resize(posteriorVector.size());
561 for (
unsigned int k = 0; k < inInterval.size(); k++)
562 inInterval[k] =
false;
570 while(((integratedposterior/histoIntegral) < (1-fSize)) && (j < posteriorVector.size())) {
572 integratedposterior+=posteriorVector[j].second;
577 inInterval[posteriorVector[j].first] =
true;
579 if(posteriorVector[j].first < lowerLim) {
580 lowerLim = posteriorVector[j].first;
581 std::cout <<
"updating lower lim to: " << lowerLim << std::endl;
583 if(posteriorVector[j].first > upperLim) {
584 upperLim = posteriorVector[j].first;
585 std::cout <<
"updating upper lim to: " << upperLim << std::endl;
588 fLower = lowerLim * stepsize;
589 fUpper = upperLim * stepsize;
595 bool runInside =
false;
596 for (
unsigned int l = 0; l < inInterval.size(); l++) {
597 if ( (runInside ==
false) && (inInterval[l] ==
true) ) {
598 _intervalBorders1D.push_back(static_cast<double>(l)* stepsize);
601 if ( ( runInside ==
true) && (l < (inInterval.size()-1) ) && (inInterval[l+1] ==
false) ) {
602 _intervalBorders1D.push_back(static_cast<double>(l)* stepsize);
605 if ( ( runInside ==
true) && (l == (inInterval.size()-1)) ) {
606 _intervalBorders1D.push_back(static_cast<double>(l)* stepsize);
612 if (_intervalBorders1D.size() > 2) {
613 fConnectedInterval =
false;
616 fConnectedInterval =
true;
622 fValidInterval =
true;
624 TString interval_name = TString(
"ShortestBayesianInterval_a") + TString(this->GetName());
625 SimpleInterval * interval =
new SimpleInterval(interval_name,*poi,fLower,fUpper,ConfidenceLevel());
626 interval->SetTitle(
"Shortest SimpleInterval from BATCalculator");
633 MCMCInterval* BATCalculator::GetInterval()
const{
637 std::cerr <<
"BATCalculator::GetInterval - missing pdf model" << std::endl;
642 std::cerr <<
"BATCalculator::GetInterval - missing prior pdf" << std::endl;
645 if (fPOI.getSize() == 0) {
646 std::cerr <<
"BATCalculator::GetInterval - missing parameter of interest" << std::endl;
652 _myRooInterface->Initialize(*fData,*fPdf,*fPrior,fparams,fPOI);
653 _myRooInterface->MCMCSetNIterationsRun(_nMCMC);
654 _myRooInterface->MarginalizeAll();
655 _myRooInterface->FindMode();
658 MarkovChain * roostats_chain = GetBCRooInterface()->GetRooStatsMarkovChain();
659 MCMCInterval * mcmcInterval =
new MCMCInterval(
"roostatsmcmcinterval", fPOI , *roostats_chain);
661 mcmcInterval->SetUseKeys(
false);
662 mcmcInterval->SetConfidenceLevel(1.-fSize);
663 fValidMCMCInterval =
true;
668 void BATCalculator::SetNumBins(
const char * parname,
int nbins)
670 _myRooInterface->SetNumBins(parname, nbins);
673 void BATCalculator::SetNumBins(
int nbins)
675 _myRooInterface->SetNumBins(nbins);
678 void BATCalculator::SetLeftSideTailFraction(Double_t leftSideFraction ){
679 if( (leftSideFraction >= 0.) && (leftSideFraction <= 1.) ){
680 fLeftSideFraction = leftSideFraction;
683 std::cout <<
"BATCalculator::SetLeftSideTailFraction(Double_t leftSideFraction ) - value needs to be in the interval [0.,1.] to be meaningful, your value: " << leftSideFraction <<
" ,left side tail fraction has not been changed!" << std::endl;
690 Double_t BATCalculator::GetOneSidedUperLim()
694 std::cout <<
"calculating " << (1.-fSize/2) <<
"upper limit" << std::endl;
695 return GetInterval1D()->UpperLimit();
707 bool sortbyposterior(std::pair< Int_t,Double_t > pair1, std::pair< Int_t,Double_t > pair2)
709 return (pair1.second > pair2.second);
A class representing a parameter of a model.
A class for handling 1D distributions.