Logo ROOT  
Reference Guide
 
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 "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.empty()) {
80 _value = traceEval(nullptr);
81 } else {
82 _formula = std::make_unique<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.empty()) {
104 _value = traceEval(0);
105 } else {
106 _formula = std::make_unique<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>&>(_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(_actualVars.nset());
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 RooFormulaVar::redirectServersHook(const RooAbsCollection& newServerList, bool mustReplaceAll, bool nameChange, bool isRecursive)
176{
177 bool error = getFormula().changeDependents(newServerList,mustReplaceAll,nameChange);
178
180 return error || RooAbsReal::redirectServersHook(newServerList, mustReplaceAll, nameChange, isRecursive);
181}
182
183
184
185////////////////////////////////////////////////////////////////////////////////
186/// Print info about this object to the specified stream.
187
188void RooFormulaVar::printMultiline(ostream& os, Int_t contents, bool verbose, TString indent) const
189{
190 RooAbsReal::printMultiline(os,contents,verbose,indent);
191 if(verbose) {
192 indent.Append(" ");
193 os << indent;
194 getFormula().printMultiline(os,contents,verbose,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 RooFormulaVar::readFromStream(istream& /*is*/, bool /*compact*/, bool /*verbose*/)
215{
216 coutE(InputArguments) << "RooFormulaVar::readFromStream(" << GetName() << "): can't read" << endl ;
217 return true ;
218}
219
220
221
222////////////////////////////////////////////////////////////////////////////////
223/// Write object contents to given stream
224
225void RooFormulaVar::writeToStream(ostream& os, bool 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>* RooFormulaVar::binBoundaries(RooAbsRealLValue& obs, double xlo, double xhi) const
240{
241 for (const auto par : _actualVars) {
242 auto func = static_cast<const RooAbsReal*>(par);
243 list<double>* 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>* RooFormulaVar::plotSamplingHint(RooAbsRealLValue& obs, double xlo, double xhi) const
259{
260 for (const auto par : _actualVars) {
261 auto func = dynamic_cast<const RooAbsReal*>(par);
262 list<double>* 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)
#define coutE(a)
#define ClassImp(name)
Definition Rtypes.h:377
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=nullptr) const override
This method must be overridden when a class wants to print itself.
const RooArgSet * nset() const
Definition RooAbsProxy.h:52
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:62
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:91
RooArgSet * _lastNSet
!
Definition RooAbsReal.h:598
virtual double defaultErrorLevel() const
Definition RooAbsReal.h:253
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
A buffer for reading values from trees.
double _value
Cache for current value of object.
Definition RooAbsReal.h:509
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
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
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...
RooListProxy _actualVars
Actual parameters used by formula engine.
RooFormula & getFormula() const
Return reference to internal RooFormula object.
const RooFormula & formula() const
Get reference to the internal formula object.
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.
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.
RooSpan< double > evaluateSpan(RooBatchCompute::RunContext &evalData, const RooArgSet *normSet) const override
Evaluate the formula for all entries of our servers found in inputData.
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.
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::unique_ptr< RooFormula > _formula
! Formula engine
std::list< double > * plotSamplingHint(RooAbsRealLValue &, double, double) const override
Forward the plot sampling hint from the p.d.f. that defines the observable obs.
RooFormula internally uses ROOT's TFormula to compute user-defined expressions of RooAbsArgs.
Definition RooFormula.h:33
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Printing interface.
RooSpan< double > evaluateSpan(const RooAbsReal *dataOwner, RooBatchCompute::RunContext &inputData, const RooArgSet *nset=nullptr) const
double eval(const RooArgSet *nset=nullptr) const
Evalute 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.
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:139
This struct enables passing computation data around between elements of a computation graph.
Definition RunContext.h:32