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 "RooFormulaVar.h"
53#include "RooStreamParser.h"
54#include "RooNLLVar.h"
55#include "RooChi2Var.h"
56#include "RooMsgService.h"
57#include "RooTrace.h"
58
59
60using namespace std;
61
63
64
65
66////////////////////////////////////////////////////////////////////////////////
67/// Constructor with formula expression and list of input variables.
68/// \param[in] name Name of the formula.
69/// \param[in] title Title of the formula.
70/// \param[in] formula Expression to be evaluated.
71/// \param[in] dependents Variables that should be passed to the formula.
72/// \param[in] checkVariables Check that all variables from `dependents` are used in the expression.
73RooFormulaVar::RooFormulaVar(const char *name, const char *title, const char* inFormula, const RooArgList& dependents,
74 bool checkVariables) :
75 RooAbsReal(name,title),
76 _actualVars("actualVars","Variables used by formula expression",this),
77 _formExpr(inFormula)
78{
79 _actualVars.add(dependents) ;
80
81 if (_actualVars.getSize()==0) {
82 _value = traceEval(0);
83 } else {
84 _formula.reset(new RooFormula(GetName(), _formExpr, _actualVars, checkVariables));
85 _formExpr = _formula->formulaString().c_str();
86 }
87}
88
89
90
91////////////////////////////////////////////////////////////////////////////////
92/// Constructor with formula expression, title and list of input variables.
93/// \param[in] name Name of the formula.
94/// \param[in] title Formula expression. Will also be used as the title.
95/// \param[in] dependents Variables that should be passed to the formula.
96/// \param[in] checkVariables Check that all variables from `dependents` are used in the expression.
97RooFormulaVar::RooFormulaVar(const char *name, const char *title, const RooArgList& dependents,
98 bool checkVariables) :
99 RooAbsReal(name,title),
100 _actualVars("actualVars","Variables used by formula expression",this),
101 _formExpr(title)
102{
103 _actualVars.add(dependents) ;
104
105 if (_actualVars.getSize()==0) {
106 _value = traceEval(0);
107 } else {
108 _formula.reset(new RooFormula(GetName(), _formExpr, _actualVars, checkVariables));
109 _formExpr = _formula->formulaString().c_str();
110 }
111}
112
113
114
115////////////////////////////////////////////////////////////////////////////////
116/// Copy constructor
117
119 RooAbsReal(other, name),
120 _actualVars("actualVars",this,other._actualVars),
121 _formExpr(other._formExpr)
122{
123 if (other._formula && other._formula->ok()) {
124 _formula.reset(new RooFormula(GetName(), _formExpr, _actualVars, /*checkVariables=*/false));
125 _formExpr = _formula->formulaString().c_str();
126 }
127}
128
129
130////////////////////////////////////////////////////////////////////////////////
131/// Return reference to internal RooFormula object.
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 formula().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 = formula().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;
177 formula().printMultiline(os,contents,verbose,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
#define coutI(a)
Definition: RooMsgService.h:31
#define coutE(a)
Definition: RooMsgService.h:34
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:365
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:59
virtual Double_t defaultErrorLevel() const
Definition: RooAbsReal.h:221
RooArgSet * _lastNSet
Definition: RooAbsReal.h:555
Double_t traceEval(const RooArgSet *set) const
Calculate current value of object, with error tracing wrapper.
Definition: RooAbsReal.cxx:341
Double_t _value
Definition: RooAbsReal.h:446
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Structure printing.
Definition: RooAbsReal.cxx:477
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:87
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:77
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 & formula() const
Return reference to internal RooFormula object.
TString _formExpr
Normalization set to be passed along to contents.
Definition: RooFormulaVar.h:80
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:78
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:352
void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Printing interface.
Definition: RooFormula.cxx:381
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:316
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 * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Basic string class.
Definition: TString.h:131
@ Minimization
Definition: RooGlobalFunc.h:67
@ InputArguments
Definition: RooGlobalFunc.h:68