#include "RooDataHist.h"
#include "RooDataSet.h"
#include "RooGlobalFunc.h"
#include "RooNLLVar.h"
#include "RooRealVar.h"
#include "RooTreeData.h"
#include "RooWorkspace.h"
#include "TH1.h"
#include "RooStats/HybridCalculator.h"
ClassImp(RooStats::HybridCalculator)
using namespace RooStats;
HybridCalculator::HybridCalculator(const char *name,
const char *title ) :
TNamed(TString(name), TString(title)),
fSbModel(0),
fBModel(0),
fObservables(0),
fParameters(0),
fPriorPdf(0),
fData(0),
fWS(0)
{
SetTestStatistics(1);
SetNumberOfToys(1000);
UseNuisance(false);
}
HybridCalculator::HybridCalculator( const char *name,
const char *title,
RooAbsPdf& sbModel,
RooAbsPdf& bModel,
RooArgList& observables,
RooArgSet& nuisance_parameters,
RooAbsPdf& priorPdf ) :
TNamed(name,title),
fSbModel(&sbModel),
fBModel(&bModel),
fParameters(&nuisance_parameters),
fPriorPdf(&priorPdf),
fData(0),
fWS(0)
{
fObservables = new RooArgList(observables);
SetTestStatistics(1);
SetNumberOfToys(1000);
UseNuisance(true);
}
HybridCalculator::HybridCalculator( RooAbsData & data,
RooAbsPdf& sbModel,
RooAbsPdf& bModel,
RooArgSet* nuisance_parameters,
RooAbsPdf* priorPdf ) :
fSbModel(0),
fBModel(0),
fObservables(0),
fParameters(0),
fPriorPdf(0),
fData(0),
fWS(0)
{
Initialize(data, bModel, sbModel, 0, 0, nuisance_parameters, priorPdf);
SetTestStatistics(1);
SetNumberOfToys(1000);
if (priorPdf) UseNuisance(true);
}
HybridCalculator::HybridCalculator( const char *name,
const char *title,
RooAbsData & data,
RooAbsPdf& sbModel,
RooAbsPdf& bModel,
RooArgSet* nuisance_parameters,
RooAbsPdf* priorPdf ) :
TNamed(name,title),
fSbModel(0),
fBModel(0),
fObservables(0),
fParameters(0),
fPriorPdf(0),
fData(0),
fWS(0)
{
Initialize(data, bModel, sbModel, 0, 0, nuisance_parameters, priorPdf);
SetTestStatistics(1);
SetNumberOfToys(1000);
if (priorPdf) UseNuisance(true);
}
HybridCalculator::HybridCalculator( RooWorkspace & wks,
const char * data,
const char * sbModel,
const char * bModel,
RooArgSet* nuisance_parameters,
const char* priorPdf ) :
fSbModel(0),
fBModel(0),
fObservables(0),
fParameters(0),
fPriorPdf(0),
fData(0),
fWS(0)
{
Initialize(wks, data, bModel, sbModel, 0, 0, nuisance_parameters, priorPdf);
SetTestStatistics(1);
SetNumberOfToys(1000);
if (priorPdf) UseNuisance(true);
}
HybridCalculator::HybridCalculator( const char *name,
const char *title,
RooWorkspace & wks,
const char * data,
const char * sbModel,
const char * bModel,
RooArgSet* nuisance_parameters,
const char* priorPdf ) :
TNamed(name,title),
fSbModel(0),
fBModel(0),
fObservables(0),
fParameters(0),
fPriorPdf(0),
fData(0),
fWS(0)
{
Initialize(wks, data, bModel, sbModel, 0, 0, nuisance_parameters, priorPdf);
SetTestStatistics(1);
SetNumberOfToys(1000);
if (priorPdf) UseNuisance(true);
}
HybridCalculator::~HybridCalculator()
{
if (fObservables) delete fObservables;
}
void HybridCalculator::SetTestStatistics(int index)
{
fTestStatisticsIdx = index;
}
HybridResult* HybridCalculator::Calculate(TH1& data, unsigned int nToys, bool usePriors) const
{
TString dataHistName = GetName(); dataHistName += "_roodatahist";
RooDataHist dataHist(dataHistName,"Data distribution as RooDataHist converted from TH1",*fObservables,&data);
HybridResult* result = Calculate(dataHist,nToys,usePriors);
return result;
}
HybridResult* HybridCalculator::Calculate(RooTreeData& data, unsigned int nToys, bool usePriors) const
{
double testStatData = 0;
if ( fTestStatisticsIdx==2 ) {
double nEvents = data.sumEntries();
testStatData = nEvents;
} else {
RooNLLVar sb_nll("sb_nll","sb_nll",*fSbModel,data,RooFit::Extended());
RooNLLVar b_nll("b_nll","b_nll",*fBModel,data,RooFit::Extended());
double m2lnQ = 2*(sb_nll.getVal()-b_nll.getVal());
testStatData = m2lnQ;
}
HybridResult* result = Calculate(nToys,usePriors);
result->SetDataTestStatistics(testStatData);
return result;
}
HybridResult* HybridCalculator::Calculate(unsigned int nToys, bool usePriors) const
{
std::vector<double> bVals;
bVals.reserve(nToys);
std::vector<double> sbVals;
sbVals.reserve(nToys);
RunToys(bVals,sbVals,nToys,usePriors);
HybridResult* result = new HybridResult(GetName(),GetTitle(),sbVals,bVals);
return result;
}
void HybridCalculator::RunToys(std::vector<double>& bVals, std::vector<double>& sbVals, unsigned int nToys, bool usePriors) const
{
std::cout << "HybridCalculator: run " << nToys << " toy-MC experiments\n";
std::cout << "with test statistics index: " << fTestStatisticsIdx << "\n";
if (usePriors) std::cout << "marginalize nuisance parameters \n";
assert(nToys > 0);
assert(fBModel);
assert(fSbModel);
if (usePriors) {
assert(fPriorPdf);
assert(fParameters);
}
std::vector<double> parameterValues;
int nParameters = (fParameters) ? fParameters->getSize() : 0;
RooArgList parametersList("parametersList");
if (usePriors && nParameters>0) {
parametersList.add(*fParameters);
parameterValues.resize(nParameters);
for (int iParameter=0; iParameter<nParameters; iParameter++) {
RooRealVar* oneParam = (RooRealVar*) parametersList.at(iParameter);
parameterValues[iParameter] = oneParam->getVal();
}
}
for (unsigned int iToy=0; iToy<nToys; iToy++) {
if ( iToy>0 && iToy%500==0) {
std::cout << "Running toy number " << iToy << " / " << nToys << std::endl;
}
if (usePriors && nParameters>0) {
RooDataSet* tmpValues = (RooDataSet*) fPriorPdf->generate(*fParameters,1);
for (int iParameter=0; iParameter<nParameters; iParameter++) {
RooRealVar* oneParam = (RooRealVar*) parametersList.at(iParameter);
oneParam->setVal(tmpValues->get()->getRealValue(oneParam->GetName()));
}
delete tmpValues;
}
RooTreeData* sbData = static_cast<RooTreeData*> (fSbModel->generate(*fObservables,RooFit::Extended()));
bool sbIsEmpty = false;
if (sbData==NULL) {
sbIsEmpty = true;
RooDataSet* sbDataDummy=new RooDataSet("sbDataDummy","empty dataset",*fObservables);
sbData = static_cast<RooTreeData*>(new RooDataHist ("sbDataEmpty","",*fObservables,*sbDataDummy));
delete sbDataDummy;
}
RooTreeData* bData = static_cast<RooTreeData*> (fBModel->generate(*fObservables,RooFit::Extended()));
bool bIsEmpty = false;
if (bData==NULL) {
bIsEmpty = true;
RooDataSet* bDataDummy=new RooDataSet("bDataDummy","empty dataset",*fObservables);
bData = static_cast<RooTreeData*>(new RooDataHist ("bDataEmpty","",*fObservables,*bDataDummy));
delete bDataDummy;
}
if (usePriors && nParameters>0) {
for (int iParameter=0; iParameter<nParameters; iParameter++) {
RooRealVar* oneParam = (RooRealVar*) parametersList.at(iParameter);
oneParam->setVal(parameterValues[iParameter]);
}
}
if ( fTestStatisticsIdx==2 ) {
double nEvents = 0;
if ( !sbIsEmpty ) nEvents = sbData->numEntries();
sbVals.push_back(nEvents);
} else {
RooNLLVar sb_sb_nll("sb_sb_nll","sb_sb_nll",*fSbModel,*sbData,RooFit::Extended());
RooNLLVar b_sb_nll("b_sb_nll","b_sb_nll",*fBModel,*sbData,RooFit::Extended());
double m2lnQ = 2*(sb_sb_nll.getVal()-b_sb_nll.getVal());
sbVals.push_back(m2lnQ);
}
if ( fTestStatisticsIdx==2 ) {
double nEvents = 0;
if ( !bIsEmpty ) nEvents = bData->numEntries();
bVals.push_back(nEvents);
} else {
RooNLLVar sb_b_nll("sb_b_nll","sb_b_nll",*fSbModel,*bData,RooFit::Extended());
RooNLLVar b_b_nll("b_b_nll","b_b_nll",*fBModel,*bData,RooFit::Extended());
double m2lnQ = 2*(sb_b_nll.getVal()-b_b_nll.getVal());
bVals.push_back(m2lnQ);
}
delete sbData;
delete bData;
}
if (usePriors && nParameters>0) {
for (int iParameter=0; iParameter<nParameters; iParameter++) {
RooRealVar* oneParam = (RooRealVar*) parametersList.at(iParameter);
oneParam->setVal(parameterValues[iParameter]);
}
}
return;
}
void HybridCalculator::PrintMore(const char* options) const
{
if (fSbModel) {
std::cout << "Signal plus background model:\n";
fSbModel->Print(options);
}
if (fBModel) {
std::cout << "\nBackground model:\n";
fBModel->Print(options);
}
if (fObservables) {
std::cout << "\nObservables:\n";
fObservables->Print(options);
}
if (fParameters) {
std::cout << "\nParameters being integrated:\n";
fParameters->Print(options);
}
if (fPriorPdf) {
std::cout << "\nPrior PDF model for integration:\n";
fPriorPdf->Print(options);
}
return;
}
HybridResult* HybridCalculator::GetHypoTest() const {
if (fWS) {
if (!(const_cast<HybridCalculator &>(*this)).DoInitializeFromWS() ) return 0;
}
if (!DoCheckInputs()) return 0;
RooTreeData * treeData = dynamic_cast<RooTreeData *> (fData);
if (!treeData) {
std::cerr << "Error in HybridCalculator::GetHypoTest - invalid data type - return NULL" << std::endl;
return 0;
}
bool usePrior = (fUsePriorPdf && fPriorPdf );
return Calculate( *treeData, fNToys, usePrior);
}
bool HybridCalculator::DoInitializeFromWS() {
if (!fWS) return false;
fData = fWS->data(fDataName);
if (!fData) {
std::cerr << "Error in HybridCalculator::DoInitializeFromWS - data " << fDataName << " is NOT found in workspace" << std::endl;
return false;
}
if (fData->get() ) fObservables = new RooArgList( *fData->get() );
if (!fObservables) {
std::cerr << "Error in HybridCalculator::DoInitializeFromWS - data " << fDataName << " has not observables" << std::endl;
return false;
}
fSbModel = fWS->pdf(fSbModelName);
if (!fSbModel) {
std::cerr << "Error in HybridCalculator::DoInitializeFromWS - S+B pdf " << fSbModelName << " is NOT found in workspace" << std::endl;
return false;
}
fBModel = fWS->pdf(fBModelName);
if (!fBModel) {
std::cerr << "Error in HybridCalculator::DoInitializeFromWS - B pdf " << fBModelName << " is NOT found in workspace" << std::endl;
return false;
}
if (fUsePriorPdf) {
fPriorPdf = fWS->pdf(fPriorPdfName);
if (!fPriorPdf) {
std::cerr << "Warning in HybridCalculator::DoInitializeFromWS - Prior pdf " << fPriorPdfName << " is NOT found in workspace" << std::endl;
UseNuisance(false);
}
}
return true;
}
bool HybridCalculator::DoCheckInputs() const {
if (!fData) {
std::cerr << "Error in HybridCalculator - data have not been set" << std::endl;
return false;
}
if (!fObservables && fData->get() ) fObservables = new RooArgList( *fData->get() );
if (!fObservables) {
std::cerr << "Error in HybridCalculator - no observables" << std::endl;
return false;
}
if (!fSbModel) {
std::cerr << "Error in HybridCalculator - S+B pdf has not been set " << std::endl;
return false;
}
if (!fBModel) {
std::cerr << "Error in HybridCalculator - B pdf has not been set" << std::endl;
return false;
}
if (fUsePriorPdf && !fParameters) {
std::cerr << "Error in HybridCalculator - nuisance parameters have not been set " << std::endl;
return false;
}
if (fUsePriorPdf && !fPriorPdf) {
std::cerr << "Error in HybridCalculator - prior pdf has not been set " << std::endl;
return false;
}
return true;
}
void HybridCalculator::SetWorkspace(RooWorkspace& ws) {
if (!fWS) {
fWS = &ws;
}
else {
fWS->merge(ws);
}
}
Last change: Wed Dec 17 08:53:06 2008
Last generated: 2008-12-17 08:53
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.