Logo ROOT  
Reference Guide
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Loading...
Searching...
No Matches
RooFormulaVar.cxx
Go to the documentation of this file.
1/*****************************************************************************
2 * Project: RooFit *
3 * Package: RooFitCore *
4 * @(#)root/roofitcore:$Id$
5 * Authors: *
6 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8 * *
9 * Copyright (c) 2000-2005, Regents of the University of California *
10 * and Stanford University. All rights reserved. *
11 * *
12 * Redistribution and use in source and binary forms, *
13 * with or without modification, are permitted according to the terms *
14 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15 *****************************************************************************/
16
17//////////////////////////////////////////////////////////////////////////////
18/// \class RooFormulaVar
19///
20/// A RooFormulaVar is a generic implementation of a real-valued object,
21/// which takes a RooArgList of servers and a C++ expression string defining how
22/// its value should be calculated from the given list of servers.
23/// RooFormulaVar uses a RooFormula object to perform the expression evaluation.
24///
25/// If RooAbsPdf objects are supplied to RooFormulaVar as servers, their
26/// raw (unnormalized) values will be evaluated. Use RooGenericPdf, which
27/// constructs generic PDF functions, to access their properly normalized
28/// values.
29///
30/// The string expression can be any valid TFormula expression referring to the
31/// listed servers either by name or by their ordinal list position. These three are
32/// equivalent:
33/// ```
34/// RooFormulaVar("gen", "x*y", RooArgList(x,y)) // reference by name
35/// RooFormulaVar("gen", "@0*@1", RooArgList(x,y)) // reference by ordinal with @
36/// RooFormulaVar("gen", "x[0]*x[1]", RooArgList(x,y)) // TFormula-builtin reference by ordinal
37/// ```
38/// Note that `x[i]` is an expression reserved for TFormula. All variable references
39/// are automatically converted to the TFormula-native format. If a variable with
40/// the name `x` is given, the RooFormula interprets `x[i]` as a list position,
41/// but `x` without brackets as the name of a RooFit object.
42///
43/// The last two versions, while slightly less readable, are more versatile because
44/// the names of the arguments are not hard coded.
45///
46
47
48#include "Riostream.h"
49
50#include "RooFormulaVar.h"
51#include "RooStreamParser.h"
52#include "RooMsgService.h"
53#include "RooTrace.h"
54#include "RooFormula.h"
55
56#ifdef ROOFIT_LEGACY_EVAL_BACKEND
57#include "RooNLLVar.h"
58#include "RooChi2Var.h"
59#endif
60
61using std::ostream, std::istream, std::list;
62
63
65
70
71////////////////////////////////////////////////////////////////////////////////
72/// Constructor with formula expression and list of input variables.
73/// \param[in] name Name of the formula.
74/// \param[in] title Title of the formula.
75/// \param[in] inFormula Expression to be evaluated.
76/// \param[in] dependents Variables that should be passed to the formula.
77/// \param[in] checkVariables Check that all variables from `dependents` are used in the expression.
78RooFormulaVar::RooFormulaVar(const char *name, const char *title, const char* inFormula, const RooArgList& dependents,
79 bool checkVariables) :
80 RooAbsReal(name,title),
81 _actualVars("actualVars","Variables used by formula expression",this),
82 _formExpr(inFormula)
83{
84 if (dependents.empty()) {
85 _value = traceEval(nullptr);
86 } else {
88 _formExpr = _formula->formulaString().c_str();
90 }
91}
92
93
94
95////////////////////////////////////////////////////////////////////////////////
96/// Constructor with formula expression, title and list of input variables.
97/// \param[in] name Name of the formula.
98/// \param[in] title Formula expression. Will also be used as the title.
99/// \param[in] dependents Variables that should be passed to the formula.
100/// \param[in] checkVariables Check that all variables from `dependents` are used in the expression.
101RooFormulaVar::RooFormulaVar(const char *name, const char *title, const RooArgList& dependents,
102 bool checkVariables) :
103 RooAbsReal(name,title),
104 _actualVars("actualVars","Variables used by formula expression",this),
105 _formExpr(title)
106{
107 if (dependents.empty()) {
108 _value = traceEval(nullptr);
109 } else {
111 _formExpr = _formula->formulaString().c_str();
113 }
114}
115
116
117
118////////////////////////////////////////////////////////////////////////////////
119/// Copy constructor
120
123 _actualVars("actualVars",this,other._actualVars),
124 _formExpr(other._formExpr)
125{
126 if (other._formula && other._formula->ok()) {
127 _formula = new RooFormula(*other._formula);
128 _formExpr = _formula->formulaString().c_str();
129 }
130}
131
132
133////////////////////////////////////////////////////////////////////////////////
134/// Return reference to internal RooFormula object.
135/// If it doesn't exist, create it on the fly.
137{
138 if (!_formula) {
139 // After being read from file, the formula object might not exist, yet:
141 const_cast<TString&>(_formExpr) = _formula->formulaString().c_str();
142 }
143
144 return *_formula;
145}
146
147
148bool RooFormulaVar::ok() const { return getFormula().ok() ; }
149
150
152
153
154////////////////////////////////////////////////////////////////////////////////
155/// Calculate current value of object from internal formula
156
158{
159 return getFormula().eval(_actualVars.nset());
160}
161
162
164{
165 getFormula().doEval(ctx);
166}
167
168
169////////////////////////////////////////////////////////////////////////////////
170/// Propagate server change information to embedded RooFormula object
171
179
180
181
182////////////////////////////////////////////////////////////////////////////////
183/// Print info about this object to the specified stream.
184
185void RooFormulaVar::printMultiline(ostream& os, Int_t contents, bool verbose, TString indent) const
186{
187 RooAbsReal::printMultiline(os,contents,verbose,indent);
188 if(verbose) {
189 indent.Append(" ");
190 os << indent;
191 getFormula().printMultiline(os,contents,verbose,indent);
192 }
193}
194
195
196
197////////////////////////////////////////////////////////////////////////////////
198/// Add formula expression as meta argument in printing interface
199
200void RooFormulaVar::printMetaArgs(ostream& os) const
201{
202 os << "formula=\"" << _formExpr << "\" " ;
203}
204
205
206
207
208////////////////////////////////////////////////////////////////////////////////
209/// Read object contents from given stream
210
211bool RooFormulaVar::readFromStream(istream& /*is*/, bool /*compact*/, bool /*verbose*/)
212{
213 coutE(InputArguments) << "RooFormulaVar::readFromStream(" << GetName() << "): can't read" << std::endl ;
214 return true ;
215}
216
217
218
219////////////////////////////////////////////////////////////////////////////////
220/// Write object contents to given stream
221
222void RooFormulaVar::writeToStream(ostream& os, bool compact) const
223{
224 if (compact) {
225 std::cout << getVal() << std::endl ;
226 } else {
227 os << GetTitle() ;
228 }
229}
230
231
232
233////////////////////////////////////////////////////////////////////////////////
234/// Forward the plot sampling hint from the p.d.f. that defines the observable obs
235
236std::list<double>* RooFormulaVar::binBoundaries(RooAbsRealLValue& obs, double xlo, double xhi) const
237{
238 for (const auto par : _actualVars) {
239 auto func = static_cast<const RooAbsReal*>(par);
240 list<double>* binb = nullptr;
241
242 if (func && (binb = func->binBoundaries(obs,xlo,xhi)) ) {
243 return binb;
244 }
245 }
246
247 return nullptr;
248}
249
250
251
252////////////////////////////////////////////////////////////////////////////////
253/// Forward the plot sampling hint from the p.d.f. that defines the observable obs
254
255std::list<double>* RooFormulaVar::plotSamplingHint(RooAbsRealLValue& obs, double xlo, double xhi) const
256{
257 for (const auto par : _actualVars) {
258 auto func = dynamic_cast<const RooAbsReal*>(par);
259 list<double>* hint = nullptr;
260
261 if (func && (hint = func->plotSamplingHint(obs,xlo,xhi)) ) {
262 return hint;
263 }
264 }
265
266 return nullptr;
267}
268
269
270
271////////////////////////////////////////////////////////////////////////////////
272/// Return the default error level for MINUIT error analysis
273/// If the formula contains one or more RooNLLVars and
274/// no RooChi2Vars, return the defaultErrorLevel() of
275/// RooNLLVar. If the addition contains one ore more RooChi2Vars
276/// and no RooNLLVars, return the defaultErrorLevel() of
277/// RooChi2Var. If the addition contains neither or both
278/// issue a warning message and return a value of 1
279
281{
282 RooAbsReal* nllArg(nullptr) ;
283 RooAbsReal* chi2Arg(nullptr) ;
284
285#ifdef ROOFIT_LEGACY_EVAL_BACKEND
286 for (const auto arg : _actualVars) {
287 if (dynamic_cast<RooNLLVar*>(arg)) {
288 nllArg = static_cast<RooAbsReal*>(arg) ;
289 }
290 if (dynamic_cast<RooChi2Var*>(arg)) {
291 chi2Arg = static_cast<RooAbsReal*>(arg) ;
292 }
293 }
294#endif
295
296 if (nllArg && !chi2Arg) {
297 coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName()
298 << ") Formula contains a RooNLLVar, using its error level" << std::endl ;
299 return nllArg->defaultErrorLevel() ;
300 } else if (chi2Arg && !nllArg) {
301 coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName()
302 << ") Formula contains a RooChi2Var, using its error level" << std::endl ;
303 return chi2Arg->defaultErrorLevel() ;
304 } else if (!nllArg && !chi2Arg) {
305 coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName() << ") WARNING: "
306 << "Formula contains neither RooNLLVar nor RooChi2Var server, using default level of 1.0" << std::endl ;
307 } else {
308 coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName() << ") WARNING: "
309 << "Formula contains BOTH RooNLLVar and RooChi2Var server, using default level of 1.0" << std::endl ;
310 }
311
312 return 1.0 ;
313}
314
316{
318}
#define coutI(a)
#define coutE(a)
static void indent(ostringstream &buf, int indent_level)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
char name[80]
Definition TGX11.cxx:110
Abstract container object that can hold multiple RooAbsArg objects.
const RooArgSet * nset() const
Definition RooAbsProxy.h:52
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:59
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:103
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Structure printing.
bool redirectServersHook(const RooAbsCollection &newServerList, bool mustReplaceAll, bool nameChange, bool isRecursiveStep) override
Function that is called at the end of redirectServers().
double _value
Cache for current value of object.
Definition RooAbsReal.h:535
double traceEval(const RooArgSet *set) const
Calculate current value of object, with error tracing wrapper.
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition RooArgList.h:22
Simple calculation from a binned dataset and a PDF.
Definition RooChi2Var.h:19
bool add(const RooAbsArg &var, bool valueServer, bool shapeServer, bool silent)
Overloaded RooCollection_t::add() method insert object into set and registers object as server to own...
A RooFormulaVar is a generic implementation of a real-valued object, which takes a RooArgList of serv...
~RooFormulaVar() override
RooListProxy _actualVars
Actual parameters used by formula engine.
RooFormula & getFormula() const
Return reference to internal RooFormula object.
RooFormula * _formula
! Formula engine
void doEval(RooFit::EvalContext &ctx) const override
Base function for computing multiple values of a RooAbsReal.
void dumpFormula()
Dump the formula to stdout.
double defaultErrorLevel() const override
Return the default error level for MINUIT error analysis If the formula contains one or more RooNLLVa...
bool redirectServersHook(const RooAbsCollection &newServerList, bool mustReplaceAll, bool nameChange, bool isRecursive) override
Propagate server change information to embedded RooFormula object.
bool ok() const
const RooArgList & dependents() const
std::list< double > * binBoundaries(RooAbsRealLValue &, double, double) const override
Forward the plot sampling hint from the p.d.f. that defines the observable obs.
bool readFromStream(std::istream &is, bool compact, bool verbose=false) override
Read object contents from given stream.
TString _formExpr
Formula expression string.
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Print info about this object to the specified stream.
std::string getUniqueFuncName() const
double evaluate() const override
Calculate current value of object from internal formula.
void writeToStream(std::ostream &os, bool compact) const override
Write object contents to given stream.
void printMetaArgs(std::ostream &os) const override
Add formula expression as meta argument in printing interface.
std::list< double > * plotSamplingHint(RooAbsRealLValue &, double, double) const override
Forward the plot sampling hint from the p.d.f. that defines the observable obs.
Internally uses ROOT's TFormula to compute user-defined expressions of RooAbsArgs.
Definition RooFormula.h:27
TFormula * getTFormula() const
Definition RooFormula.h:72
std::string formulaString() const
Definition RooFormula.h:71
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Printing interface.
RooArgSet actualDependents() const
Return list of arguments which are used in the formula.
Definition RooFormula.h:39
bool ok() const
Definition RooFormula.h:50
void dump() const
DEBUG: Dump state information.
double eval(const RooArgSet *nset=nullptr) const
Evaluate all parameters/observables, and then evaluate formula.
bool changeDependents(const RooAbsCollection &newDeps, bool mustReplaceAll, bool nameChange)
Change used variables to those with the same name in given list.
void doEval(RooFit::EvalContext &) const
Implements a -log(likelihood) calculation from a dataset and a PDF.
Definition RooNLLVar.h:20
TString GetUniqueFuncName() const
Definition TFormula.h:253
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:48
Basic string class.
Definition TString.h:139
const char * Data() const
Definition TString.h:376