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 
59 using 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.
72 RooFormulaVar::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.
96 RooFormulaVar::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 
117 RooFormulaVar::RooFormulaVar(const RooFormulaVar& other, const char* name) :
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 /// 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 
176 Bool_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 
189 void RooFormulaVar::printMultiline(ostream& os, Int_t contents, Bool_t verbose, TString indent) const
190 {
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 
204 void RooFormulaVar::printMetaArgs(ostream& os) const
205 {
206  os << "formula=\"" << _formExpr << "\" " ;
207 }
208 
209 
210 
211 
212 ////////////////////////////////////////////////////////////////////////////////
213 /// Read object contents from given stream
214 
215 Bool_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 
226 void 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 
240 std::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 
259 std::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 
RooFormulaVar.h
RooStreamParser.h
RooFormulaVar::_actualVars
RooListProxy _actualVars
Definition: RooFormulaVar.h:84
RooFormulaVar::defaultErrorLevel
virtual Double_t defaultErrorLevel() const
Return the default error level for MINUIT error analysis If the formula contains one or more RooNLLVa...
Definition: RooFormulaVar.cxx:284
RooFormula
RooFormula internally uses ROOT's TFormula to compute user-defined expressions of RooAbsArgs.
Definition: RooFormula.h:34
RooFormulaVar::evaluate
virtual Double_t evaluate() const
Calculate current value of object from internal formula.
Definition: RooFormulaVar.cxx:149
RooFit::Minimization
@ Minimization
Definition: RooGlobalFunc.h:60
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:100
RooMsgService.h
RooFormulaVar::plotSamplingHint
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
Definition: RooFormulaVar.cxx:259
RooFit.h
RooFit::InputArguments
@ InputArguments
Definition: RooGlobalFunc.h:61
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
TNamed::GetTitle
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
coutE
#define coutE(a)
Definition: RooMsgService.h:33
RooFormulaVar::binBoundaries
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
Definition: RooFormulaVar.cxx:240
RooFormulaVar::printMultiline
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.
Definition: RooFormulaVar.cxx:189
RooArgList
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgList.h:21
RooAbsReal::defaultErrorLevel
virtual Double_t defaultErrorLevel() const
Definition: RooAbsReal.h:252
RooAbsReal::getVal
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:91
RooFormulaVar::readFromStream
virtual Bool_t readFromStream(std::istream &is, Bool_t compact, Bool_t verbose=kFALSE)
Read object contents from given stream.
Definition: RooFormulaVar.cxx:215
RooChi2Var
Definition: RooChi2Var.h:25
coutI
#define coutI(a)
Definition: RooMsgService.h:30
indent
static void indent(ostringstream &buf, int indent_level)
Definition: TClingCallFunc.cxx:87
RooAbsReal
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:61
RooFormulaVar::getFormula
RooFormula & getFormula() const
Return reference to internal RooFormula object.
Definition: RooFormulaVar.cxx:132
RooFormulaVar::writeToStream
virtual void writeToStream(std::ostream &os, Bool_t compact) const
Write object contents to given stream.
Definition: RooFormulaVar.cxx:226
TString
Basic string class.
Definition: TString.h:136
RooFormulaVar::_formExpr
TString _formExpr
Normalization set to be passed along to contents.
Definition: RooFormulaVar.h:87
RooFormulaVar::_formula
std::unique_ptr< RooFormula > _formula
Definition: RooFormulaVar.h:85
RooNLLVar.h
bool
RooChi2Var.h
RooTrace.h
RooFormula::changeDependents
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:306
RooFormulaVar
A RooFormulaVar is a generic implementation of a real-valued object, which takes a RooArgList of serv...
Definition: RooFormulaVar.h:30
RooNLLVar
Class RooNLLVar implements a -log(likelihood) calculation from a dataset and a PDF.
Definition: RooNLLVar.h:30
RooAbsCollection
RooAbsCollection is an abstract container object that can hold multiple RooAbsArg objects.
Definition: RooAbsCollection.h:33
RooFormulaVar::printMetaArgs
void printMetaArgs(std::ostream &os) const
Add formula expression as meta argument in printing interface.
Definition: RooFormulaVar.cxx:204
RooFormula::evaluateSpan
RooSpan< double > evaluateSpan(const RooAbsReal *dataOwner, RooBatchCompute::RunContext &inputData, const RooArgSet *nset=nullptr) const
Definition: RooFormula.cxx:368
RooAbsReal::_value
Double_t _value
Definition: RooAbsReal.h:477
RooFormulaVar::evaluateSpan
RooSpan< double > evaluateSpan(RooBatchCompute::RunContext &evalData, const RooArgSet *normSet) const
Evaluate the formula for all entries of our servers found in inputData.
Definition: RooFormulaVar.cxx:157
RooAbsReal::traceEval
Double_t traceEval(const RooArgSet *set) const
Calculate current value of object, with error tracing wrapper.
Definition: RooAbsReal.cxx:354
Double_t
double Double_t
Definition: RtypesCore.h:59
RooFormulaVar::formula
const RooFormula & formula() const
Get reference to the internal formula object.
Definition: RooFormulaVar.h:62
name
char name[80]
Definition: TGX11.cxx:110
RooAbsReal::printMultiline
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Structure printing.
Definition: RooAbsReal.cxx:490
genreflex::verbose
bool verbose
Definition: rootcling_impl.cxx:133
RooFormula::printMultiline
void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Printing interface.
Definition: RooFormula.cxx:414
RooListProxy::add
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE) override
Reimplementation of standard RooArgList::add()
Definition: RooListProxy.cxx:104
RooAbsCollection::Print
virtual void Print(Option_t *options=0) const
This method must be overridden when a class wants to print itself.
Definition: RooAbsCollection.h:259
TNamed::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Riostream.h
RooFormula::eval
Double_t eval(const RooArgSet *nset=0) const
Evalute all parameters/observables, and then evaluate formula.
Definition: RooFormula.cxx:342
RooAbsRealLValue
RooAbsRealLValue is the common abstract base class for objects that represent a real value that may a...
Definition: RooAbsRealLValue.h:31
RooFormulaVar::redirectServersHook
virtual Bool_t redirectServersHook(const RooAbsCollection &newServerList, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t isRecursive)
Propagate server change information to embedded RooFormula object.
Definition: RooFormulaVar.cxx:176
RooFormulaVar::RooFormulaVar
RooFormulaVar()
Definition: RooFormulaVar.h:33
RooBatchCompute::RunContext
This struct enables passing computation data around between elements of a computation graph.
Definition: RunContext.h:31
RooAbsCollection::getSize
Int_t getSize() const
Definition: RooAbsCollection.h:231
RooSpan
A simple container to hold a batch of data values.
Definition: RooSpan.h:34
RooArgSet
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:33
RooAbsReal::_lastNSet
RooArgSet * _lastNSet
Definition: RooAbsReal.h:578
int