// RooGenericPdf is a concrete implementation of a probability density function,
// which takes a RooArgList of servers and a C++ expression string defining how
// its value should be calculated from the given list of servers.
// A fully numerical integration is automatically performed to normalize the given
// expression. RooGenericPdf uses a RooFormula object to perform the expression evaluation
//
// The string expression can be any valid TFormula expression referring to the
// listed servers either by name or by their ordinal list position:
//
// RooGenericPdf("gen","x*y",RooArgList(x,y)) or
// RooGenericPdf("gen","@0*@1",RooArgList(x,y))
//
// The latter form, while slightly less readable, is more versatile because it
// doesn't hardcode any of the variable names it expects
// END_HTML
#include "RooFit.h"
#include "Riostream.h"
#include "RooGenericPdf.h"
#include "RooGenericPdf.h"
#include "RooStreamParser.h"
#include "RooMsgService.h"
#include "RooArgList.h"
ClassImp(RooGenericPdf)
RooGenericPdf::RooGenericPdf(const char *name, const char *title, const RooArgList& dependents) :
RooAbsPdf(name,title),
_actualVars("actualVars","Variables used by PDF expression",this),
_formula(0),
_formExpr(title)
{
_actualVars.add(dependents) ;
if (_actualVars.getSize()==0) _value = traceEval(0) ;
}
RooGenericPdf::RooGenericPdf(const char *name, const char *title,
const char* inFormula, const RooArgList& dependents) :
RooAbsPdf(name,title),
_actualVars("actualVars","Variables used by PDF expression",this),
_formula(0),
_formExpr(inFormula)
{
_actualVars.add(dependents) ;
if (_actualVars.getSize()==0) _value = traceEval(0) ;
}
RooGenericPdf::RooGenericPdf(const RooGenericPdf& other, const char* name) :
RooAbsPdf(other, name),
_actualVars("actualVars",this,other._actualVars),
_formula(0),
_formExpr(other._formExpr)
{
}
RooGenericPdf::~RooGenericPdf()
{
if (_formula) delete _formula ;
}
RooFormula& RooGenericPdf::formula() const
{
if (!_formula) {
_formula = new RooFormula(GetName(),_formExpr.Data(),_actualVars) ;
}
return *_formula ;
}
Double_t RooGenericPdf::evaluate() const
{
return formula().eval(_normSet) ;
}
Bool_t RooGenericPdf::setFormula(const char* inFormula)
{
if (formula().reCompile(inFormula)) return kTRUE ;
_formExpr = inFormula ;
setValueDirty() ;
return kFALSE ;
}
Bool_t RooGenericPdf::isValidReal(Double_t , Bool_t ) const
{
return kTRUE ;
}
Bool_t RooGenericPdf::redirectServersHook(const RooAbsCollection& newServerList, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t )
{
if (_formula) {
return _formula->changeDependents(newServerList,mustReplaceAll,nameChange) ;
} else {
return kTRUE ;
}
}
void RooGenericPdf::printMultiline(ostream& os, Int_t content, Bool_t verbose, TString indent) const
{
RooAbsPdf::printMultiline(os,content,verbose,indent);
if (verbose) {
os << " --- RooGenericPdf --- " << endl ;
indent.Append(" ");
os << indent ;
formula().printMultiline(os,content,verbose,indent);
}
}
void RooGenericPdf::printMetaArgs(ostream& os) const
{
os << "formula=\"" << _formExpr << "\" " ;
}
Bool_t RooGenericPdf::readFromStream(istream& is, Bool_t compact, Bool_t )
{
if (compact) {
coutE(InputArguments) << "RooGenericPdf::readFromStream(" << GetName() << "): can't read in compact mode" << endl ;
return kTRUE ;
} else {
RooStreamParser parser(is) ;
return setFormula(parser.readLine()) ;
}
}
void RooGenericPdf::writeToStream(ostream& os, Bool_t compact) const
{
if (compact) {
os << getVal() << endl ;
} else {
os << GetTitle() ;
}
}