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 "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] inFormula 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{
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{
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 = std::make_unique<RooFormula>(*other._formula);
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(_actualVars.nset());
152}
153
154
155////////////////////////////////////////////////////////////////////////////////
156/// Evaluate the formula for all entries of our servers found in `inputData`.
158 if (normSet != _lastNSet) {
159 // TODO: Remove dependence on _lastNSet
160 // See also comment in RooAbsReal::getValBatch().
161 std::cerr << "Formula " << GetName() << " " << GetTitle() << "\n\tBeing evaluated with normSet " << normSet << "\n";
162 normSet->Print("V");
163 std::cerr << "\tHowever, _lastNSet = " << _lastNSet << "\n";
164 if (_lastNSet) _lastNSet->Print("V");
165
166 throw std::logic_error("Got conflicting norm sets. This shouldn't happen.");
167 }
168
169 return formula().evaluateSpan(this, inputData, normSet);
170}
171
172
173////////////////////////////////////////////////////////////////////////////////
174/// Propagate server change information to embedded RooFormula object
175
176Bool_t RooFormulaVar::redirectServersHook(const RooAbsCollection& newServerList, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t /*isRecursive*/)
177{
178 bool success = getFormula().changeDependents(newServerList,mustReplaceAll,nameChange);
179
181 return success;
182}
183
184
185
186////////////////////////////////////////////////////////////////////////////////
187/// Print info about this object to the specified stream.
188
189void RooFormulaVar::printMultiline(ostream& os, Int_t contents, Bool_t verbose, TString indent) const
190{
191 RooAbsReal::printMultiline(os,contents,verbose,indent);
192 if(verbose) {
193 indent.Append(" ");
194 os << indent;
195 getFormula().printMultiline(os,contents,verbose,indent);
196 }
197}
198
199
200
201////////////////////////////////////////////////////////////////////////////////
202/// Add formula expression as meta argument in printing interface
203
204void RooFormulaVar::printMetaArgs(ostream& os) const
205{
206 os << "formula=\"" << _formExpr << "\" " ;
207}
208
209
210
211
212////////////////////////////////////////////////////////////////////////////////
213/// Read object contents from given stream
214
215Bool_t RooFormulaVar::readFromStream(istream& /*is*/, Bool_t /*compact*/, Bool_t /*verbose*/)
216{
217 coutE(InputArguments) << "RooFormulaVar::readFromStream(" << GetName() << "): can't read" << endl ;
218 return kTRUE ;
219}
220
221
222
223////////////////////////////////////////////////////////////////////////////////
224/// Write object contents to given stream
225
226void RooFormulaVar::writeToStream(ostream& os, Bool_t compact) const
227{
228 if (compact) {
229 cout << getVal() << endl ;
230 } else {
231 os << GetTitle() ;
232 }
233}
234
235
236
237////////////////////////////////////////////////////////////////////////////////
238/// Forward the plot sampling hint from the p.d.f. that defines the observable obs
239
240std::list<Double_t>* RooFormulaVar::binBoundaries(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
241{
242 for (const auto par : _actualVars) {
243 auto func = static_cast<const RooAbsReal*>(par);
244 list<Double_t>* binb = nullptr;
245
246 if (func && (binb = func->binBoundaries(obs,xlo,xhi)) ) {
247 return binb;
248 }
249 }
250
251 return nullptr;
252}
253
254
255
256////////////////////////////////////////////////////////////////////////////////
257/// Forward the plot sampling hint from the p.d.f. that defines the observable obs
258
259std::list<Double_t>* RooFormulaVar::plotSamplingHint(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
260{
261 for (const auto par : _actualVars) {
262 auto func = dynamic_cast<const RooAbsReal*>(par);
263 list<Double_t>* hint = nullptr;
264
265 if (func && (hint = func->plotSamplingHint(obs,xlo,xhi)) ) {
266 return hint;
267 }
268 }
269
270 return nullptr;
271}
272
273
274
275////////////////////////////////////////////////////////////////////////////////
276/// Return the default error level for MINUIT error analysis
277/// If the formula contains one or more RooNLLVars and
278/// no RooChi2Vars, return the defaultErrorLevel() of
279/// RooNLLVar. If the addition contains one ore more RooChi2Vars
280/// and no RooNLLVars, return the defaultErrorLevel() of
281/// RooChi2Var. If the addition contains neither or both
282/// issue a warning message and return a value of 1
283
285{
286 RooAbsReal* nllArg(0) ;
287 RooAbsReal* chi2Arg(0) ;
288
289 for (const auto arg : _actualVars) {
290 if (dynamic_cast<RooNLLVar*>(arg)) {
291 nllArg = (RooAbsReal*)arg ;
292 }
293 if (dynamic_cast<RooChi2Var*>(arg)) {
294 chi2Arg = (RooAbsReal*)arg ;
295 }
296 }
297
298 if (nllArg && !chi2Arg) {
299 coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName()
300 << ") Formula contains a RooNLLVar, using its error level" << endl ;
301 return nllArg->defaultErrorLevel() ;
302 } else if (chi2Arg && !nllArg) {
303 coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName()
304 << ") Formula contains a RooChi2Var, using its error level" << endl ;
305 return chi2Arg->defaultErrorLevel() ;
306 } else if (!nllArg && !chi2Arg) {
307 coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName() << ") WARNING: "
308 << "Formula contains neither RooNLLVar nor RooChi2Var server, using default level of 1.0" << endl ;
309 } else {
310 coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName() << ") WARNING: "
311 << "Formula contains BOTH RooNLLVar and RooChi2Var server, using default level of 1.0" << endl ;
312 }
313
314 return 1.0 ;
315}
316
317
318
319
#define coutI(a)
#define coutE(a)
const Bool_t kTRUE
Definition RtypesCore.h:100
#define ClassImp(name)
Definition Rtypes.h:364
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.
Int_t getSize() const
virtual void Print(Option_t *options=0) const
This method must be overridden when a class wants to print itself.
const RooArgSet * nset() const
Definition RooAbsProxy.h:45
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:64
virtual Double_t defaultErrorLevel() const
Definition RooAbsReal.h:256
RooArgSet * _lastNSet
Definition RooAbsReal.h:585
Double_t traceEval(const RooArgSet *set) const
Calculate current value of object, with error tracing wrapper.
Double_t _value
Definition RooAbsReal.h:484
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Structure printing.
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:94
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:35
RooChi2Var implements a simple 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...
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
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.
double 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.
const RooFormula & formula() const
Get reference to the internal formula object.
const RooArgList & dependents() const
TString _formExpr
Normalization set to be passed along to contents.
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
RooSpan< double > evaluateSpan(RooBatchCompute::RunContext &evalData, const RooArgSet *normSet) const
Evaluate the formula for all entries of our servers found in inputData.
std::unique_ptr< RooFormula > _formula
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:33
RooSpan< double > evaluateSpan(const RooAbsReal *dataOwner, RooBatchCompute::RunContext &inputData, const RooArgSet *nset=nullptr) const
Double_t eval(const RooArgSet *nset=0) const
Evalute all parameters/observables, and then evaluate formula.
void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Printing interface.
Bool_t changeDependents(const RooAbsCollection &newDeps, Bool_t mustReplaceAll, Bool_t nameChange)
Change used variables to those with the same name in given list.
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE) override
Reimplementation of standard RooArgList::add()
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
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:136
This struct enables passing computation data around between elements of a computation graph.
Definition RunContext.h:32