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 "Riostream.h"
49
50#include "RooFormulaVar.h"
51#include "RooStreamParser.h"
52#include "RooNLLVar.h"
53#include "RooChi2Var.h"
54#include "RooMsgService.h"
55#include "RooTrace.h"
56
57
58using namespace std;
59
61
62
63
64////////////////////////////////////////////////////////////////////////////////
65/// Constructor with formula expression and list of input variables.
66/// \param[in] name Name of the formula.
67/// \param[in] title Title of the formula.
68/// \param[in] inFormula Expression to be evaluated.
69/// \param[in] dependents Variables that should be passed to the formula.
70/// \param[in] checkVariables Check that all variables from `dependents` are used in the expression.
71RooFormulaVar::RooFormulaVar(const char *name, const char *title, const char* inFormula, const RooArgList& dependents,
72 bool checkVariables) :
73 RooAbsReal(name,title),
74 _actualVars("actualVars","Variables used by formula expression",this),
75 _formExpr(inFormula)
76{
78
79 if (_actualVars.getSize()==0) {
80 _value = traceEval(0);
81 } else {
82 _formula.reset(new RooFormula(GetName(), _formExpr, _actualVars, checkVariables));
83 _formExpr = _formula->formulaString().c_str();
84 }
85}
86
87
88
89////////////////////////////////////////////////////////////////////////////////
90/// Constructor with formula expression, title and list of input variables.
91/// \param[in] name Name of the formula.
92/// \param[in] title Formula expression. Will also be used as the title.
93/// \param[in] dependents Variables that should be passed to the formula.
94/// \param[in] checkVariables Check that all variables from `dependents` are used in the expression.
95RooFormulaVar::RooFormulaVar(const char *name, const char *title, const RooArgList& dependents,
96 bool checkVariables) :
97 RooAbsReal(name,title),
98 _actualVars("actualVars","Variables used by formula expression",this),
99 _formExpr(title)
100{
102
103 if (_actualVars.getSize()==0) {
104 _value = traceEval(0);
105 } else {
106 _formula.reset(new RooFormula(GetName(), _formExpr, _actualVars, checkVariables));
107 _formExpr = _formula->formulaString().c_str();
108 }
109}
110
111
112
113////////////////////////////////////////////////////////////////////////////////
114/// Copy constructor
115
117 RooAbsReal(other, name),
118 _actualVars("actualVars",this,other._actualVars),
119 _formExpr(other._formExpr)
120{
121 if (other._formula && other._formula->ok()) {
122 _formula = std::make_unique<RooFormula>(*other._formula);
123 _formExpr = _formula->formulaString().c_str();
124 }
125}
126
127
128////////////////////////////////////////////////////////////////////////////////
129/// Return reference to internal RooFormula object.
130/// If it doesn't exist, create it on the fly.
132{
133 if (!_formula) {
134 // After being read from file, the formula object might not exist, yet:
135 auto theFormula = new RooFormula(GetName(), _formExpr, _actualVars);
136 const_cast<std::unique_ptr<RooFormula>&>(this->_formula).reset(theFormula);
137 const_cast<TString&>(_formExpr) = _formula->formulaString().c_str();
138 }
139
140 return *_formula;
141}
142
143
144
145////////////////////////////////////////////////////////////////////////////////
146/// Calculate current value of object from internal formula
147
149{
150 return getFormula().eval(_lastNSet);
151}
152
153
154////////////////////////////////////////////////////////////////////////////////
155/// Evaluate the formula for all entries of our servers found in `inputData`.
157 if (normSet != _lastNSet) {
158 // TODO: Remove dependence on _lastNSet
159 // See also comment in RooAbsReal::getValBatch().
160 std::cerr << "Formula " << GetName() << " " << GetTitle() << "\n\tBeing evaluated with normSet " << normSet << "\n";
161 normSet->Print("V");
162 std::cerr << "\tHowever, _lastNSet = " << _lastNSet << "\n";
163 if (_lastNSet) _lastNSet->Print("V");
164
165 throw std::logic_error("Got conflicting norm sets. This shouldn't happen.");
166 }
167
168 return formula().evaluateSpan(this, inputData, normSet);
169}
170
171
172////////////////////////////////////////////////////////////////////////////////
173/// Propagate server change information to embedded RooFormula object
174
175Bool_t RooFormulaVar::redirectServersHook(const RooAbsCollection& newServerList, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t /*isRecursive*/)
176{
177 bool success = getFormula().changeDependents(newServerList,mustReplaceAll,nameChange);
178
180 return success;
181}
182
183
184
185////////////////////////////////////////////////////////////////////////////////
186/// Print info about this object to the specified stream.
187
189{
191 if(verbose) {
192 indent.Append(" ");
193 os << indent;
195 }
196}
197
198
199
200////////////////////////////////////////////////////////////////////////////////
201/// Add formula expression as meta argument in printing interface
202
203void RooFormulaVar::printMetaArgs(ostream& os) const
204{
205 os << "formula=\"" << _formExpr << "\" " ;
206}
207
208
209
210
211////////////////////////////////////////////////////////////////////////////////
212/// Read object contents from given stream
213
214Bool_t RooFormulaVar::readFromStream(istream& /*is*/, Bool_t /*compact*/, Bool_t /*verbose*/)
215{
216 coutE(InputArguments) << "RooFormulaVar::readFromStream(" << GetName() << "): can't read" << endl ;
217 return kTRUE ;
218}
219
220
221
222////////////////////////////////////////////////////////////////////////////////
223/// Write object contents to given stream
224
225void RooFormulaVar::writeToStream(ostream& os, Bool_t compact) const
226{
227 if (compact) {
228 cout << getVal() << endl ;
229 } else {
230 os << GetTitle() ;
231 }
232}
233
234
235
236////////////////////////////////////////////////////////////////////////////////
237/// Forward the plot sampling hint from the p.d.f. that defines the observable obs
238
239std::list<Double_t>* RooFormulaVar::binBoundaries(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
240{
241 for (const auto par : _actualVars) {
242 auto func = static_cast<const RooAbsReal*>(par);
243 list<Double_t>* binb = nullptr;
244
245 if (func && (binb = func->binBoundaries(obs,xlo,xhi)) ) {
246 return binb;
247 }
248 }
249
250 return nullptr;
251}
252
253
254
255////////////////////////////////////////////////////////////////////////////////
256/// Forward the plot sampling hint from the p.d.f. that defines the observable obs
257
258std::list<Double_t>* RooFormulaVar::plotSamplingHint(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
259{
260 for (const auto par : _actualVars) {
261 auto func = dynamic_cast<const RooAbsReal*>(par);
262 list<Double_t>* hint = nullptr;
263
264 if (func && (hint = func->plotSamplingHint(obs,xlo,xhi)) ) {
265 return hint;
266 }
267 }
268
269 return nullptr;
270}
271
272
273
274////////////////////////////////////////////////////////////////////////////////
275/// Return the default error level for MINUIT error analysis
276/// If the formula contains one or more RooNLLVars and
277/// no RooChi2Vars, return the defaultErrorLevel() of
278/// RooNLLVar. If the addition contains one ore more RooChi2Vars
279/// and no RooNLLVars, return the defaultErrorLevel() of
280/// RooChi2Var. If the addition contains neither or both
281/// issue a warning message and return a value of 1
282
284{
285 RooAbsReal* nllArg(0) ;
286 RooAbsReal* chi2Arg(0) ;
287
288 for (const auto arg : _actualVars) {
289 if (dynamic_cast<RooNLLVar*>(arg)) {
290 nllArg = (RooAbsReal*)arg ;
291 }
292 if (dynamic_cast<RooChi2Var*>(arg)) {
293 chi2Arg = (RooAbsReal*)arg ;
294 }
295 }
296
297 if (nllArg && !chi2Arg) {
298 coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName()
299 << ") Formula contains a RooNLLVar, using its error level" << endl ;
300 return nllArg->defaultErrorLevel() ;
301 } else if (chi2Arg && !nllArg) {
302 coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName()
303 << ") Formula contains a RooChi2Var, using its error level" << endl ;
304 return chi2Arg->defaultErrorLevel() ;
305 } else if (!nllArg && !chi2Arg) {
306 coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName() << ") WARNING: "
307 << "Formula contains neither RooNLLVar nor RooChi2Var server, using default level of 1.0" << endl ;
308 } else {
309 coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName() << ") WARNING: "
310 << "Formula contains BOTH RooNLLVar and RooChi2Var server, using default level of 1.0" << endl ;
311 }
312
313 return 1.0 ;
314}
315
316
317
318
#define coutI(a)
Definition: RooMsgService.h:30
#define coutE(a)
Definition: RooMsgService.h:33
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:375
static void indent(ostringstream &buf, int indent_level)
char name[80]
Definition: TGX11.cxx:110
RooAbsCollection is an abstract container object that can hold multiple RooAbsArg objects.
void Print(Option_t *options=0) const override
This method must be overridden when a class wants to print itself.
Int_t getSize() const
Return the number of elements in the collection.
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:63
virtual Double_t defaultErrorLevel() const
Definition: RooAbsReal.h:255
RooArgSet * _lastNSet
!
Definition: RooAbsReal.h:584
Double_t traceEval(const RooArgSet *set) const
Calculate current value of object, with error tracing wrapper.
Definition: RooAbsReal.cxx:359
Double_t _value
Cache for current value of object.
Definition: RooAbsReal.h:483
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:93
void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const override
Structure printing.
Definition: RooAbsReal.cxx:495
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgList.h:22
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:57
RooChi2Var implements a simple calculation from a binned dataset and a PDF.
Definition: RooChi2Var.h:25
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...
Definition: RooFormulaVar.h:30
std::list< Double_t > * binBoundaries(RooAbsRealLValue &, Double_t, Double_t) const override
Forward the plot sampling hint from the p.d.f. that defines the observable obs.
RooListProxy _actualVars
Actual parameters used by formula engine.
Definition: RooFormulaVar.h:91
void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const override
Print info about this object to the specified stream.
RooFormula & getFormula() const
Return reference to internal RooFormula object.
const RooFormula & formula() const
Get reference to the internal formula object.
Definition: RooFormulaVar.h:64
const RooArgList & dependents() const
Definition: RooFormulaVar.h:41
RooSpan< double > evaluateSpan(RooBatchCompute::RunContext &evalData, const RooArgSet *normSet) const override
Evaluate the formula for all entries of our servers found in inputData.
Bool_t readFromStream(std::istream &is, Bool_t compact, Bool_t verbose=kFALSE) override
Read object contents from given stream.
void writeToStream(std::ostream &os, Bool_t compact) const override
Write object contents to given stream.
Double_t defaultErrorLevel() const override
Return the default error level for MINUIT error analysis If the formula contains one or more RooNLLVa...
TString _formExpr
Formula expression string.
Definition: RooFormulaVar.h:94
Bool_t redirectServersHook(const RooAbsCollection &newServerList, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t isRecursive) override
Propagate server change information to embedded RooFormula object.
void printMetaArgs(std::ostream &os) const override
Add formula expression as meta argument in printing interface.
std::unique_ptr< RooFormula > _formula
! Formula engine
Definition: RooFormulaVar.h:92
std::list< Double_t > * plotSamplingHint(RooAbsRealLValue &, Double_t, Double_t) const override
Forward the plot sampling hint from the p.d.f. that defines the observable obs.
Double_t evaluate() const override
Calculate current value of object from internal formula.
RooFormula internally uses ROOT's TFormula to compute user-defined expressions of RooAbsArgs.
Definition: RooFormula.h:32
void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const override
Printing interface.
Definition: RooFormula.cxx:519
RooSpan< double > evaluateSpan(const RooAbsReal *dataOwner, RooBatchCompute::RunContext &inputData, const RooArgSet *nset=nullptr) const
Definition: RooFormula.cxx:458
Double_t eval(const RooArgSet *nset=0) const
Evalute all parameters/observables, and then evaluate formula.
Definition: RooFormula.cxx:432
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:396
Class RooNLLVar implements a -log(likelihood) calculation from a dataset and a PDF.
Definition: RooNLLVar.h:30
A simple container to hold a batch of data values.
Definition: RooSpan.h:34
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:136
@ Minimization
Definition: RooGlobalFunc.h:63
@ InputArguments
Definition: RooGlobalFunc.h:64
This struct enables passing computation data around between elements of a computation graph.
Definition: RunContext.h:31