// RooHistFunc implements a real-valued function sampled from a
// multidimensional histogram. The histogram can have an arbitrary number of real or
// discrete dimensions and may have negative values
// END_HTML
#include "RooFit.h"
#include "Riostream.h"
#include "RooHistFunc.h"
#include "RooDataHist.h"
#include "RooMsgService.h"
#include "RooRealVar.h"
#include "RooCategory.h"
ClassImp(RooHistFunc)
;
RooHistFunc::RooHistFunc() :
_dataHist(0),
_intOrder(0),
_cdfBoundaries(kFALSE),
_totVolume(0),
_unitNorm(kFALSE)
{
}
RooHistFunc::RooHistFunc(const char *name, const char *title, const RooArgSet& vars,
const RooDataHist& dhist, Int_t intOrder) :
RooAbsReal(name,title),
_depList("depList","List of dependents",this),
_dataHist((RooDataHist*)&dhist),
_codeReg(10),
_intOrder(intOrder),
_cdfBoundaries(kFALSE),
_totVolume(0),
_unitNorm(kFALSE)
{
_depList.add(vars) ;
const RooArgSet* dvars = dhist.get() ;
if (vars.getSize()!=dvars->getSize()) {
coutE(InputArguments) << "RooHistFunc::ctor(" << GetName()
<< ") ERROR variable list and RooDataHist must contain the same variables." << endl ;
assert(0) ;
}
TIterator* iter = vars.createIterator() ;
RooAbsArg* arg ;
while((arg=(RooAbsArg*)iter->Next())) {
if (!dvars->find(arg->GetName())) {
coutE(InputArguments) << "RooHistFunc::ctor(" << GetName()
<< ") ERROR variable list and RooDataHist must contain the same variables." << endl ;
assert(0) ;
}
}
delete iter ;
}
RooHistFunc::RooHistFunc(const RooHistFunc& other, const char* name) :
RooAbsReal(other,name),
_depList("depList",this,other._depList),
_dataHist(other._dataHist),
_codeReg(other._codeReg),
_intOrder(other._intOrder),
_cdfBoundaries(other._cdfBoundaries),
_totVolume(other._totVolume),
_unitNorm(other._unitNorm)
{
}
Double_t RooHistFunc::evaluate() const
{
Double_t ret = _dataHist->weight(_depList,_intOrder,kFALSE,_cdfBoundaries) ;
return ret ;
}
Double_t RooHistFunc::totVolume() const
{
if (_totVolume>0) {
return _totVolume ;
}
_totVolume = 1. ;
TIterator* iter = _depList.createIterator() ;
RooAbsArg* arg ;
while((arg=(RooAbsArg*)iter->Next())) {
RooRealVar* real = dynamic_cast<RooRealVar*>(arg) ;
if (real) {
_totVolume *= (real->getMax()-real->getMin()) ;
} else {
RooCategory* cat = dynamic_cast<RooCategory*>(arg) ;
if (cat) {
_totVolume *= cat->numTypes() ;
}
}
}
delete iter ;
return _totVolume ;
}
Int_t RooHistFunc::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* rangeName) const
{
if (rangeName!=0) {
return 0 ;
}
RooAbsCollection *allVarsCommon = allVars.selectCommon(_depList) ;
Bool_t intAllObs = (allVarsCommon->getSize()==_depList.getSize()) ;
delete allVarsCommon ;
if (intAllObs && matchArgs(allVars,analVars,_depList)) {
return 1000 ;
}
if (_intOrder>0) {
return 0 ;
}
RooArgSet* allVarsSel = (RooArgSet*) allVars.selectCommon(_depList) ;
if (allVarsSel->getSize()==0) {
delete allVarsSel ;
return 0 ;
}
Int_t code(0),n(0) ;
TIterator* iter = _depList.createIterator() ;
RooAbsArg* arg ;
while((arg=(RooAbsArg*)iter->Next())) {
if (allVars.find(arg->GetName())) code |= (1<<n) ;
n++ ;
}
delete iter ;
analVars.add(*allVarsSel) ;
return code ;
}
Double_t RooHistFunc::analyticalIntegral(Int_t code, const char* ) const
{
if (code==1000) {
return _dataHist->sum(kTRUE) ;
}
RooArgSet intSet ;
TIterator* iter = _depList.createIterator() ;
RooAbsArg* arg ;
Int_t n(0) ;
while((arg=(RooAbsArg*)iter->Next())) {
if (code & (1<<n)) {
intSet.add(*arg) ;
}
n++ ;
}
delete iter ;
Double_t ret = _dataHist->sum(intSet,_depList,kTRUE) ;
return ret ;
}
list<Double_t>* RooHistFunc::plotSamplingHint(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
{
if (_intOrder>0) {
return 0 ;
}
RooAbsLValue* lvarg = dynamic_cast<RooAbsLValue*>(_dataHist->get()->find(obs.GetName())) ;
if (!lvarg) {
return 0 ;
}
const RooAbsBinning* binning = lvarg->getBinningPtr(0) ;
Double_t* boundaries = binning->array() ;
list<Double_t>* hint = new list<Double_t> ;
xlo = xlo - 0.01*(xhi-xlo) ;
xhi = xhi + 0.01*(xhi-xlo) ;
Double_t delta = (xhi-xlo)*1e-8 ;
for (Int_t i=0 ; i<binning->numBoundaries() ; i++) {
if (boundaries[i]>=xlo && boundaries[i]<=xhi) {
hint->push_back(boundaries[i]-delta) ;
hint->push_back(boundaries[i]+delta) ;
}
}
return hint ;
}
void RooHistFunc::Streamer(TBuffer &R__b)
{
if (R__b.IsReading()) {
R__b.ReadClassBuffer(RooHistFunc::Class(),this);
_proxyList.Clear() ;
registerProxy(_depList) ;
} else {
R__b.WriteClassBuffer(RooHistFunc::Class(),this);
}
}