#include "RooFit.h"
#include "Riostream.h"
#include "RooFormulaVar.h"
#include "RooFormulaVar.h"
#include "RooStreamParser.h"
#include "RooNLLVar.h"
#include "RooChi2Var.h"
#include "RooMsgService.h"
#include "RooTrace.h"
using namespace std;
ClassImp(RooFormulaVar)
RooFormulaVar::RooFormulaVar(const char *name, const char *title, const char* inFormula, const RooArgList& dependents) :
RooAbsReal(name,title),
_actualVars("actualVars","Variables used by formula expression",this),
_formula(0), _formExpr(inFormula)
{
_actualVars.add(dependents) ;
if (_actualVars.getSize()==0) _value = traceEval(0) ;
TRACE_CREATE
}
RooFormulaVar::RooFormulaVar(const char *name, const char *title, const RooArgList& dependents) :
RooAbsReal(name,title),
_actualVars("actualVars","Variables used by formula expression",this),
_formula(0), _formExpr(title)
{
_actualVars.add(dependents) ;
if (_actualVars.getSize()==0) _value = traceEval(0) ;
TRACE_CREATE
}
RooFormulaVar::RooFormulaVar(const RooFormulaVar& other, const char* name) :
RooAbsReal(other, name),
_actualVars("actualVars",this,other._actualVars),
_formula(0), _formExpr(other._formExpr)
{
TRACE_CREATE
}
RooFormulaVar::~RooFormulaVar()
{
if (_formula) delete _formula ;
TRACE_DESTROY
}
RooFormula& RooFormulaVar::formula() const
{
if (!_formula) {
_formula = new RooFormula(GetName(),_formExpr,_actualVars) ;
}
return *_formula ;
}
Double_t RooFormulaVar::evaluate() const
{
return formula().eval(_lastNSet) ;
}
Bool_t RooFormulaVar::isValidReal(Double_t , Bool_t ) const
{
return kTRUE ;
}
Bool_t RooFormulaVar::redirectServersHook(const RooAbsCollection& newServerList, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t )
{
return formula().changeDependents(newServerList,mustReplaceAll,nameChange) ;
}
void RooFormulaVar::printMultiline(ostream& os, Int_t contents, Bool_t verbose, TString indent) const
{
RooAbsReal::printMultiline(os,contents,verbose,indent);
if(verbose) {
indent.Append(" ");
os << indent;
formula().printMultiline(os,contents,verbose,indent);
}
}
void RooFormulaVar::printMetaArgs(ostream& os) const
{
os << "formula=\"" << _formExpr << "\" " ;
}
Bool_t RooFormulaVar::readFromStream(istream& , Bool_t , Bool_t )
{
coutE(InputArguments) << "RooFormulaVar::readFromStream(" << GetName() << "): can't read" << endl ;
return kTRUE ;
}
void RooFormulaVar::writeToStream(ostream& os, Bool_t compact) const
{
if (compact) {
cout << getVal() << endl ;
} else {
os << GetTitle() ;
}
}
std::list<Double_t>* RooFormulaVar::binBoundaries(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
{
RooFIter iter = _actualVars.fwdIterator() ;
RooAbsReal* func ;
while((func=(RooAbsReal*)iter.next())) {
list<Double_t>* binb = func->binBoundaries(obs,xlo,xhi) ;
if (binb) {
return binb ;
}
}
return 0 ;
}
std::list<Double_t>* RooFormulaVar::plotSamplingHint(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
{
RooFIter iter = _actualVars.fwdIterator() ;
RooAbsReal* func ;
while((func=(RooAbsReal*)iter.next())) {
list<Double_t>* hint = func->plotSamplingHint(obs,xlo,xhi) ;
if (hint) {
return hint ;
}
}
return 0 ;
}
Double_t RooFormulaVar::defaultErrorLevel() const
{
RooAbsReal* nllArg(0) ;
RooAbsReal* chi2Arg(0) ;
TIterator* iter = _actualVars.createIterator() ;
RooAbsArg* arg ;
while((arg=(RooAbsArg*)iter->Next())) {
if (dynamic_cast<RooNLLVar*>(arg)) {
nllArg = (RooAbsReal*)arg ;
}
if (dynamic_cast<RooChi2Var*>(arg)) {
chi2Arg = (RooAbsReal*)arg ;
}
}
delete iter ;
if (nllArg && !chi2Arg) {
coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName()
<< ") Formula contains a RooNLLVar, using its error level" << endl ;
return nllArg->defaultErrorLevel() ;
} else if (chi2Arg && !nllArg) {
coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName()
<< ") Formula contains a RooChi2Var, using its error level" << endl ;
return chi2Arg->defaultErrorLevel() ;
} else if (!nllArg && !chi2Arg) {
coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName() << ") WARNING: "
<< "Formula contains neither RooNLLVar nor RooChi2Var server, using default level of 1.0" << endl ;
} else {
coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName() << ") WARNING: "
<< "Formula contains BOTH RooNLLVar and RooChi2Var server, using default level of 1.0" << endl ;
}
return 1.0 ;
}