Logo ROOT  
Reference Guide
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 "RooFit.h"
49#include "Riostream.h"
50
51#include "RooFormulaVar.h"
52#include "RooStreamParser.h"
53#include "RooNLLVar.h"
54#include "RooChi2Var.h"
55#include "RooMsgService.h"
56#include "RooTrace.h"
57
58
59using namespace std;
60
62
63
64
65////////////////////////////////////////////////////////////////////////////////
66/// Constructor with formula expression and list of input variables.
67/// \param[in] name Name of the formula.
68/// \param[in] title Title of the formula.
69/// \param[in] formula Expression to be evaluated.
70/// \param[in] dependents Variables that should be passed to the formula.
71/// \param[in] checkVariables Check that all variables from `dependents` are used in the expression.
72RooFormulaVar::RooFormulaVar(const char *name, const char *title, const char* inFormula, const RooArgList& dependents,
73 bool checkVariables) :
74 RooAbsReal(name,title),
75 _actualVars("actualVars","Variables used by formula expression",this),
76 _formExpr(inFormula)
77{
78 _actualVars.add(dependents) ;
79
80 if (_actualVars.getSize()==0) {
81 _value = traceEval(0);
82 } else {
83 _formula.reset(new RooFormula(GetName(), _formExpr, _actualVars, checkVariables));
84 _formExpr = _formula->formulaString().c_str();
85 }
86}
87
88
89
90////////////////////////////////////////////////////////////////////////////////
91/// Constructor with formula expression, title and list of input variables.
92/// \param[in] name Name of the formula.
93/// \param[in] title Formula expression. Will also be used as the title.
94/// \param[in] dependents Variables that should be passed to the formula.
95/// \param[in] checkVariables Check that all variables from `dependents` are used in the expression.
96RooFormulaVar::RooFormulaVar(const char *name, const char *title, const RooArgList& dependents,
97 bool checkVariables) :
98 RooAbsReal(name,title),
99 _actualVars("actualVars","Variables used by formula expression",this),
100 _formExpr(title)
101{
102 _actualVars.add(dependents) ;
103
104 if (_actualVars.getSize()==0) {
105 _value = traceEval(0);
106 } else {
107 _formula.reset(new RooFormula(GetName(), _formExpr, _actualVars, checkVariables));
108 _formExpr = _formula->formulaString().c_str();
109 }
110}
111
112
113
114////////////////////////////////////////////////////////////////////////////////
115/// Copy constructor
116
118 RooAbsReal(other, name),
119 _actualVars("actualVars",this,other._actualVars),
120 _formExpr(other._formExpr)
121{
122 if (other._formula && other._formula->ok()) {
123 _formula.reset(new RooFormula(GetName(), _formExpr, _actualVars, /*checkVariables=*/false));
124 _formExpr = _formula->formulaString().c_str();
125 }
126}
127
128
129////////////////////////////////////////////////////////////////////////////////
130/// Return reference to internal RooFormula object.
131/// If it doesn't exist, create it on the fly.
133{
134 if (!_formula) {
135 // After being read from file, the formula object might not exist, yet:
136 auto theFormula = new RooFormula(GetName(), _formExpr, _actualVars);
137 const_cast<std::unique_ptr<RooFormula>&>(this->_formula).reset(theFormula);
138 const_cast<TString&>(_formExpr) = _formula->formulaString().c_str();
139 }
140
141 return *_formula;
142}
143
144
145
146////////////////////////////////////////////////////////////////////////////////
147/// Calculate current value of object from internal formula
148
150{
151 return getFormula().eval(_lastNSet);
152}
153
154
155////////////////////////////////////////////////////////////////////////////////
156/// Propagate server change information to embedded RooFormula object
157
158Bool_t RooFormulaVar::redirectServersHook(const RooAbsCollection& newServerList, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t /*isRecursive*/)
159{
160 bool success = getFormula().changeDependents(newServerList,mustReplaceAll,nameChange);
161
163 return success;
164}
165
166
167
168////////////////////////////////////////////////////////////////////////////////
169/// Print info about this object to the specified stream.
170
172{
174 if(verbose) {
175 indent.Append(" ");
176 os << indent;
178 }
179}
180
181
182
183////////////////////////////////////////////////////////////////////////////////
184/// Add formula expression as meta argument in printing interface
185
186void RooFormulaVar::printMetaArgs(ostream& os) const
187{
188 os << "formula=\"" << _formExpr << "\" " ;
189}
190
191
192
193
194////////////////////////////////////////////////////////////////////////////////
195/// Read object contents from given stream
196
197Bool_t RooFormulaVar::readFromStream(istream& /*is*/, Bool_t /*compact*/, Bool_t /*verbose*/)
198{
199 coutE(InputArguments) << "RooFormulaVar::readFromStream(" << GetName() << "): can't read" << endl ;
200 return kTRUE ;
201}
202
203
204
205////////////////////////////////////////////////////////////////////////////////
206/// Write object contents to given stream
207
208void RooFormulaVar::writeToStream(ostream& os, Bool_t compact) const
209{
210 if (compact) {
211 cout << getVal() << endl ;
212 } else {
213 os << GetTitle() ;
214 }
215}
216
217
218
219////////////////////////////////////////////////////////////////////////////////
220/// Forward the plot sampling hint from the p.d.f. that defines the observable obs
221
222std::list<Double_t>* RooFormulaVar::binBoundaries(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
223{
224 for (const auto par : _actualVars) {
225 auto func = static_cast<const RooAbsReal*>(par);
226 list<Double_t>* binb = nullptr;
227
228 if (func && (binb = func->binBoundaries(obs,xlo,xhi)) ) {
229 return binb;
230 }
231 }
232
233 return nullptr;
234}
235
236
237
238////////////////////////////////////////////////////////////////////////////////
239/// Forward the plot sampling hint from the p.d.f. that defines the observable obs
240
241std::list<Double_t>* RooFormulaVar::plotSamplingHint(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
242{
243 for (const auto par : _actualVars) {
244 auto func = dynamic_cast<const RooAbsReal*>(par);
245 list<Double_t>* hint = nullptr;
246
247 if (func && (hint = func->plotSamplingHint(obs,xlo,xhi)) ) {
248 return hint;
249 }
250 }
251
252 return nullptr;
253}
254
255
256
257////////////////////////////////////////////////////////////////////////////////
258/// Return the default error level for MINUIT error analysis
259/// If the formula contains one or more RooNLLVars and
260/// no RooChi2Vars, return the defaultErrorLevel() of
261/// RooNLLVar. If the addition contains one ore more RooChi2Vars
262/// and no RooNLLVars, return the defaultErrorLevel() of
263/// RooChi2Var. If the addition contains neither or both
264/// issue a warning message and return a value of 1
265
267{
268 RooAbsReal* nllArg(0) ;
269 RooAbsReal* chi2Arg(0) ;
270
271 for (const auto arg : _actualVars) {
272 if (dynamic_cast<RooNLLVar*>(arg)) {
273 nllArg = (RooAbsReal*)arg ;
274 }
275 if (dynamic_cast<RooChi2Var*>(arg)) {
276 chi2Arg = (RooAbsReal*)arg ;
277 }
278 }
279
280 if (nllArg && !chi2Arg) {
281 coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName()
282 << ") Formula contains a RooNLLVar, using its error level" << endl ;
283 return nllArg->defaultErrorLevel() ;
284 } else if (chi2Arg && !nllArg) {
285 coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName()
286 << ") Formula contains a RooChi2Var, using its error level" << endl ;
287 return chi2Arg->defaultErrorLevel() ;
288 } else if (!nllArg && !chi2Arg) {
289 coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName() << ") WARNING: "
290 << "Formula contains neither RooNLLVar nor RooChi2Var server, using default level of 1.0" << endl ;
291 } else {
292 coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName() << ") WARNING: "
293 << "Formula contains BOTH RooNLLVar and RooChi2Var server, using default level of 1.0" << endl ;
294 }
295
296 return 1.0 ;
297}
298
299
300
301
int Int_t
Definition: CPyCppyy.h:43
#define coutI(a)
Definition: RooMsgService.h:30
#define coutE(a)
Definition: RooMsgService.h:33
bool Bool_t
Definition: RtypesCore.h:61
double Double_t
Definition: RtypesCore.h:57
const Bool_t kTRUE
Definition: RtypesCore.h:89
#define ClassImp(name)
Definition: Rtypes.h:361
static void indent(ostringstream &buf, int indent_level)
char name[80]
Definition: TGX11.cxx:109
RooAbsCollection is an abstract container object that can hold multiple RooAbsArg objects.
Int_t getSize() const
RooAbsRealLValue is the common abstract base class for objects that represent a real value that may a...
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:60
virtual Double_t defaultErrorLevel() const
Definition: RooAbsReal.h:224
RooArgSet * _lastNSet
Definition: RooAbsReal.h:551
Double_t traceEval(const RooArgSet *set) const
Calculate current value of object, with error tracing wrapper.
Definition: RooAbsReal.cxx:339
Double_t _value
Definition: RooAbsReal.h:449
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Structure printing.
Definition: RooAbsReal.cxx:475
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:90
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgList.h:21
Class RooChi2Var implements a simple chi^2 calculation from a binned dataset and a PDF.
Definition: RooChi2Var.h:25
A RooFormulaVar is a generic implementation of a real-valued object, which takes a RooArgList of serv...
Definition: RooFormulaVar.h:29
virtual std::list< Double_t > * binBoundaries(RooAbsRealLValue &, Double_t, Double_t) const
Forward the plot sampling hint from the p.d.f. that defines the observable obs
RooListProxy _actualVars
Definition: RooFormulaVar.h:82
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Print info about this object to the specified stream.
virtual Double_t evaluate() const
Calculate current value of object from internal formula.
virtual void writeToStream(std::ostream &os, Bool_t compact) const
Write object contents to given stream.
virtual Bool_t readFromStream(std::istream &is, Bool_t compact, Bool_t verbose=kFALSE)
Read object contents from given stream.
RooFormula & getFormula() const
Return reference to internal RooFormula object.
TString _formExpr
Normalization set to be passed along to contents.
Definition: RooFormulaVar.h:85
virtual Bool_t redirectServersHook(const RooAbsCollection &newServerList, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t isRecursive)
Propagate server change information to embedded RooFormula object.
virtual std::list< Double_t > * plotSamplingHint(RooAbsRealLValue &, Double_t, Double_t) const
Forward the plot sampling hint from the p.d.f. that defines the observable obs
std::unique_ptr< RooFormula > _formula
Definition: RooFormulaVar.h:83
void printMetaArgs(std::ostream &os) const
Add formula expression as meta argument in printing interface.
virtual Double_t defaultErrorLevel() const
Return the default error level for MINUIT error analysis If the formula contains one or more RooNLLVa...
RooFormula internally uses ROOT's TFormula to compute user-defined expressions of RooAbsArgs.
Definition: RooFormula.h:28
Double_t eval(const RooArgSet *nset=0) const
Evalute all parameters/observables, and then evaluate formula.
Definition: RooFormula.cxx:340
void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Printing interface.
Definition: RooFormula.cxx:369
Bool_t changeDependents(const RooAbsCollection &newDeps, Bool_t mustReplaceAll, Bool_t nameChange)
Change used variables to those with the same name in given list.
Definition: RooFormula.cxx:304
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Reimplementation of standard RooArgList::add()
Class RooNLLVar implements a -log(likelihood) calculation from a dataset and a PDF.
Definition: RooNLLVar.h:26
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
Basic string class.
Definition: TString.h:131
@ Minimization
Definition: RooGlobalFunc.h:67
@ InputArguments
Definition: RooGlobalFunc.h:68