// Lightweight interface adaptor that binds a RooAbsReal object to a subset
// of its servers and present it as a simple array oriented interface.
// END_HTML
#include "RooFit.h"
#include "Riostream.h"
#include "RooRealBinding.h"
#include "RooAbsReal.h"
#include "RooArgSet.h"
#include "RooAbsRealLValue.h"
#include "RooNameReg.h"
#include "RooMsgService.h"
#include <assert.h>
using namespace std;
ClassImp(RooRealBinding)
;
RooRealBinding::RooRealBinding(const RooAbsReal& func, const RooArgSet &vars, const RooArgSet* nset, Bool_t clipInvalid, const TNamed* rangeName) :
RooAbsFunc(vars.getSize()), _func(&func), _vars(0), _nset(nset), _clipInvalid(clipInvalid), _xsave(0), _rangeName(rangeName), _funcSave(0)
{
_vars= new RooAbsRealLValue*[getDimension()];
if(0 == _vars) {
_valid= kFALSE;
return;
}
RooAbsArg *var = 0;
TIterator* iter = vars.createIterator() ;
Int_t index(0) ;
while((var=(RooAbsArg*)iter->Next())) {
_vars[index]= dynamic_cast<RooAbsRealLValue*>(var);
if(0 == _vars[index]) {
oocoutE((TObject*)0,InputArguments) << "RooRealBinding: cannot bind to " << var->GetName() << endl ;
_valid= kFALSE;
}
index++ ;
}
delete iter ;
_xvecValid = kTRUE ;
}
RooRealBinding::RooRealBinding(const RooRealBinding& other, const RooArgSet* nset) :
RooAbsFunc(other), _func(other._func), _nset(nset?nset:other._nset), _xvecValid(other._xvecValid),
_clipInvalid(other._clipInvalid), _xsave(0), _rangeName(other._rangeName), _funcSave(other._funcSave)
{
_vars= new RooAbsRealLValue*[getDimension()];
for(unsigned int index=0 ; index<getDimension() ; index++) {
_vars[index]= other._vars[index] ;
}
}
RooRealBinding::~RooRealBinding()
{
if(0 != _vars) delete[] _vars;
if (_xsave) delete[] _xsave ;
}
void RooRealBinding::saveXVec() const
{
if (!_xsave) {
_xsave = new Double_t[getDimension()] ;
RooArgSet* comps = _func->getComponents() ;
RooFIter iter = comps->fwdIterator() ;
RooAbsArg* arg ;
while ((arg=iter.next())) {
if (dynamic_cast<RooAbsReal*>(arg)) {
_compList.push_back((RooAbsReal*)(arg)) ;
_compSave.push_back(0) ;
}
}
delete comps ;
}
_funcSave = _func->_value ;
list<RooAbsReal*>::iterator ci = _compList.begin() ;
list<Double_t>::iterator si = _compSave.begin() ;
while(ci!=_compList.end()) {
*si = (*ci)->_value ;
si++ ; ci++ ;
}
for (UInt_t i=0 ; i<getDimension() ; i++) {
_xsave[i] = _vars[i]->getVal() ;
}
}
void RooRealBinding::restoreXVec() const
{
if (!_xsave) {
return ;
}
_func->_value = _funcSave ;
list<RooAbsReal*>::iterator ci = _compList.begin() ;
list<Double_t>::iterator si = _compSave.begin() ;
while (ci!=_compList.end()) {
(*ci)->_value = *si ;
ci++ ; si++ ;
}
for (UInt_t i=0 ; i<getDimension() ; i++) {
_vars[i]->setVal(_xsave[i]) ;
}
}
void RooRealBinding::loadValues(const Double_t xvector[]) const
{
_xvecValid = kTRUE ;
const char* range = RooNameReg::instance().constStr(_rangeName) ;
for(UInt_t index= 0; index < _dimension; index++) {
if (_clipInvalid && !_vars[index]->isValidReal(xvector[index])) {
_xvecValid = kFALSE ;
} else {
_vars[index]->setVal(xvector[index],range);
}
}
}
Double_t RooRealBinding::operator()(const Double_t xvector[]) const
{
assert(isValid());
_ncall++ ;
loadValues(xvector);
return _xvecValid ? _func->getVal(_nset) : 0. ;
}
Double_t RooRealBinding::getMinLimit(UInt_t index) const
{
assert(isValid());
return _vars[index]->getMin(RooNameReg::str(_rangeName));
}
Double_t RooRealBinding::getMaxLimit(UInt_t index) const
{
assert(isValid());
return _vars[index]->getMax(RooNameReg::str(_rangeName));
}
const char* RooRealBinding::getName() const
{
return _func->GetName() ;
}
std::list<Double_t>* RooRealBinding::plotSamplingHint(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
{
return _func->plotSamplingHint(obs,xlo,xhi) ;
}
std::list<Double_t>* RooRealBinding::binBoundaries(Int_t index) const
{
return _func->binBoundaries(*_vars[index],getMinLimit(index),getMaxLimit(index));
}