Logo ROOT   6.10/09
Reference Guide
RooFormula.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 \file RooFormula.cxx
19 \class RooFormula
20 \ingroup Roofitcore
21 
22 RooFormula an implementation of ROOT::v5::TFormula that interfaces it to RooAbsArg
23 value objects. It allows to use the value of a given list of RooAbsArg objects in the formula
24 expression. Reference is done either by the RooAbsArgs name
25 or by list ordinal postion ('@0,@1,...'). State information
26 of RooAbsCategories can be accessed used the '::' operator,
27 e.g. 'tagCat::Kaon' will resolve to the numerical value of
28 the 'Kaon' state of the RooAbsCategory object named tagCat.
29 **/
30 
31 #include "RooFit.h"
32 
33 #include "Riostream.h"
34 #include "Riostream.h"
35 #include <stdlib.h>
36 #include "TROOT.h"
37 #include "TClass.h"
38 #include "TObjString.h"
39 #include "RooFormula.h"
40 #include "RooAbsReal.h"
41 #include "RooAbsCategory.h"
42 #include "RooArgList.h"
43 #include "RooMsgService.h"
44 #include "RooTrace.h"
45 
46 using namespace std;
47 
49 
50 
51 ////////////////////////////////////////////////////////////////////////////////
52 /// Default constructor
53 /// coverity[UNINIT_CTOR]
54 
55 RooFormula::RooFormula() : ROOT::v5::TFormula(), _nset(0)
56 {
57 }
58 
59 
60 ////////////////////////////////////////////////////////////////////////////////
61 /// Constructor with expression string and list of RooAbsArg variables
62 
63 RooFormula::RooFormula(const char* name, const char* formula, const RooArgList& list) :
64  ROOT::v5::TFormula(), _isOK(kTRUE), _compiled(kFALSE)
65 {
66  SetName(name) ;
67  SetTitle(formula) ;
68 
69  TIterator* iter = list.createIterator() ;
70  RooAbsArg* arg ;
71  while ((arg=(RooAbsArg*)iter->Next())) {
72  _origList.Add(arg) ;
73  }
74  delete iter ;
75 
76  _compiled = kTRUE ;
77  if (Compile()) {
78  coutE(InputArguments) << "RooFormula::RooFormula(" << GetName() << "): compile error" << endl ;
79  _isOK = kFALSE ;
80  return ;
81  }
82 }
83 
84 
85 
86 ////////////////////////////////////////////////////////////////////////////////
87 /// Copy constructor
88 
89 RooFormula::RooFormula(const RooFormula& other, const char* name) :
90  ROOT::v5::TFormula(), RooPrintable(other), _isOK(other._isOK), _compiled(kFALSE)
91 {
92  SetName(name?name:other.GetName()) ;
93  SetTitle(other.GetTitle()) ;
94 
95  TIterator* iter = other._origList.MakeIterator() ;
96  RooAbsArg* arg ;
97  while ((arg=(RooAbsArg*)iter->Next())) {
98  _origList.Add(arg) ;
99  }
100  delete iter ;
101 
102  Compile() ;
103  _compiled=kTRUE ;
104 }
105 
106 
107 
108 ////////////////////////////////////////////////////////////////////////////////
109 /// Recompile formula with new expression
110 
111 Bool_t RooFormula::reCompile(const char* newFormula)
112 {
113  fNval=0 ;
114  _useList.Clear() ;
115 
116  TString oldFormula=GetTitle() ;
117  if (Compile(newFormula)) {
118  coutE(InputArguments) << "RooFormula::reCompile: new equation doesn't compile, formula unchanged" << endl ;
119  reCompile(oldFormula) ;
120  return kTRUE ;
121  }
122 
123  SetTitle(newFormula) ;
124  return kFALSE ;
125 }
126 
127 
128 
129 ////////////////////////////////////////////////////////////////////////////////
130 /// Destructor
131 
133 {
134  _labelList.Delete() ;
135 }
136 
137 
138 
139 ////////////////////////////////////////////////////////////////////////////////
140 /// Return list of RooAbsArg dependents that is actually used by formula expression
141 
143 {
144  if (!_compiled) {
145  _isOK = !((RooFormula*)this)->Compile() ;
146  _compiled = kTRUE ;
147  }
148 
149  // Return list of dependents used in formula expression
150 
151  _actual.removeAll();
152 
153  int i ;
154  for (i=0 ; i<_useList.GetSize() ; i++) {
156  }
157 
158  return _actual ;
159 }
160 
161 
162 
163 ////////////////////////////////////////////////////////////////////////////////
164 /// DEBUG: Dump state information
165 
167 {
168  int i ;
169  cout << "RooFormula::dump()" << endl ;
170  cout << "useList:" << endl ;
171  for (i=0 ; i<_useList.GetSize() ; i++) {
172  cout << "[" << i << "] = " << (void*) _useList.At(i) << " " << _useList.At(i)->GetName() << endl ;
173  }
174  cout << "labelList:" << endl ;
175  for (i=0 ; i<_labelList.GetSize() ; i++) {
176  cout << "[" << i << "] = " << (void*) _labelList.At(i) << " " << _labelList.At(i)->GetName() << endl ;
177  }
178  cout << "origList:" << endl ;
179  for (i=0 ; i<_origList.GetSize() ; i++) {
180  cout << "[" << i << "] = " << (void*) _origList.At(i) << " " << _origList.At(i)->GetName() << endl ;
181  }
182 }
183 
184 
185 
186 ////////////////////////////////////////////////////////////////////////////////
187 /// Change used variables to those with the same name in given list
188 /// If mustReplaceAll is true and error is generated if one of the
189 /// elements of newDeps is not found as a server
190 
191 Bool_t RooFormula::changeDependents(const RooAbsCollection& newDeps, Bool_t mustReplaceAll, Bool_t nameChange)
192 {
193  //Change current servers to new servers with the same name given in list
194  Bool_t errorStat(kFALSE) ;
195  int i ;
196 
197  for (i=0 ; i<_useList.GetSize() ; i++) {
198  RooAbsReal* replace = (RooAbsReal*) ((RooAbsArg*)_useList.At(i))->findNewServer(newDeps,nameChange) ;
199  if (replace) {
200  _useList.Replace(_useList.At(i),replace) ;
201  } else if (mustReplaceAll) {
202  coutE(LinkStateMgmt) << "RooFormula::changeDependents(1): cannot find replacement for "
203  << _useList.At(i)->GetName() << endl ;
204  errorStat = kTRUE ;
205  }
206  }
207 
208  TIterator* iter = _origList.MakeIterator() ;
209  RooAbsArg* arg ;
210  while ((arg=(RooAbsArg*)iter->Next())) {
211  RooAbsReal* replace = (RooAbsReal*) arg->findNewServer(newDeps,nameChange) ;
212  if (replace) {
213  _origList.Replace(arg,replace) ;
214  if (arg->getStringAttribute("origName")) {
215  replace->setStringAttribute("origName",arg->getStringAttribute("origName")) ;
216  } else {
217  replace->setStringAttribute("origName",arg->GetName()) ;
218  }
219  } else if (mustReplaceAll) {
220  errorStat = kTRUE ;
221  }
222  }
223  delete iter ;
224 
225  return errorStat ;
226 }
227 
228 
229 
230 ////////////////////////////////////////////////////////////////////////////////
231 /// Evaluate ROOT::v5::TFormula using given normalization set to be used as
232 /// observables definition passed to RooAbsReal::getVal()
233 
235 {
236  if (!_compiled) {
237  _isOK = !Compile() ;
238  _compiled = kTRUE ;
239  }
240 
241  // WVE sanity check should go here
242  if (!_isOK) {
243  coutE(Eval) << "RooFormula::eval(" << GetName() << "): Formula doesn't compile: " << GetTitle() << endl ;
244  return 0. ;
245  }
246 
247  // Pass current dataset pointer to DefinedValue
248  _nset = (RooArgSet*) nset ;
249 
250  return EvalPar(0,0) ;
251 }
252 
253 
254 Double_t
255 
256 ////////////////////////////////////////////////////////////////////////////////
257 /// Interface to ROOT::v5::TFormula, return value defined by object with id 'code'
258 /// Object ids are mapped from object names by method DefinedVariable()
259 
261 {
262  // Return current value for variable indicated by internal reference code
263  if (code>=_useList.GetSize()) return 0 ;
264 
265  RooAbsArg* arg=(RooAbsArg*)_useList.At(code) ;
266  if (_useIsCat[code]) {
267 
268  // Process as category
269  const RooAbsCategory *absCat = (const RooAbsCategory*)(arg);
270  TString& label=((TObjString*)_labelList.At(code))->String() ;
271  if (label.IsNull()) {
272  return absCat->getIndex() ;
273  } else {
274  return absCat->lookupType(label)->getVal() ; // DK: why not call getVal(_nset) here also?
275  }
276 
277  } else {
278 
279  // Process as real
280  const RooAbsReal *absReal= (const RooAbsReal*)(arg);
281  return absReal->getVal(_nset) ;
282 
283  }
284 
285  return 0 ;
286 }
287 
288 
289 
290 ////////////////////////////////////////////////////////////////////////////////
291 /// Interface to ROOT::v5::TFormula. If name passed by ROOT::v5::TFormula is recognized
292 /// as one of our RooAbsArg servers, return a unique id integer
293 /// that represent this variable.
294 
295 Int_t RooFormula::DefinedVariable(TString &name, int& action)
296 {
297  Int_t ret = DefinedVariable(name) ;
298  if (ret>=0) {
299 
300 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
301  action = kDefinedVariable;
302 #else
303  action = 0 ; // prevents compiler warning
304 #endif
305 
306  }
307  return ret ;
308 }
309 
310 
311 
312 ////////////////////////////////////////////////////////////////////////////////
313 /// Interface to ROOT::v5::TFormula. If name passed by ROOT::v5::TFormula is recognized
314 /// as one of our RooAbsArg servers, return a unique id integer
315 /// that represent this variable.
316 
318 {
319  char argName[1024];
320  strlcpy(argName,name.Data(),1024) ;
321 
322  // Find :: operator and split string if found
323  char *labelName = strstr(argName,"::") ;
324  if (labelName) {
325  *labelName = 0 ;
326  labelName+= 2 ;
327  }
328 
329  // Defined internal reference code for given named variable
330  RooAbsArg *arg = 0;
331  if (argName[0] == '@') {
332  // Access by ordinal number
333  Int_t index = atoi(argName+1) ;
334  if (index>=0 && index<_origList.GetSize()) {
335  arg = (RooAbsArg*) _origList.At(index) ;
336  } else {
337  coutE(Eval) << "RooFormula::DefinedVariable(" << GetName()
338  << ") ERROR: ordinal variable reference " << name
339  << " out of range (0 - " << _origList.GetSize()-1 << ")" << endl ;
340  }
341  } else {
342  // Access by name
343  arg= (RooAbsArg*) _origList.FindObject(argName) ;
344  if (!arg) {
345  for (RooLinkedListIter it = _origList.iterator(); RooAbsArg* v = dynamic_cast<RooAbsArg*>(it.Next());) {
346  if (!TString(argName).CompareTo(v->getStringAttribute("origName"))) {
347  arg= v ;
348  }
349  }
350  }
351  }
352 
353  // Check that arg exists
354  if (!arg) return -1 ;
355 
356  // Check that optional label corresponds to actual category state
357  if (labelName) {
358  RooAbsCategory* cat = dynamic_cast<RooAbsCategory*>(arg) ;
359  if (!cat) {
360  coutE(Eval) << "RooFormula::DefinedVariable(" << GetName() << ") ERROR: "
361  << arg->GetName() << "' is not a RooAbsCategory" << endl ;
362  return -1 ;
363  }
364 
365  if (!cat->lookupType(labelName)) {
366  coutE(Eval) << "RooFormula::DefinedVariable(" << GetName() << ") ERROR '"
367  << labelName << "' is not a state of " << arg->GetName() << endl ;
368  return -1 ;
369  }
370 
371  }
372 
373 
374  // Check if already registered
375  Int_t i ;
376  for(i=0 ; i<_useList.GetSize() ; i++) {
377  RooAbsArg* var = (RooAbsArg*) _useList.At(i) ;
378  //Bool_t varMatch = !TString(var->GetName()).CompareTo(arg->GetName()) ;
379  Bool_t varMatch = !TString(var->GetName()).CompareTo(arg->GetName()) && !TString(var->getStringAttribute("origName")).CompareTo(arg->GetName());
380 
381  if (varMatch) {
382  TString& lbl= ((TObjString*) _labelList.At(i))->String() ;
383  Bool_t lblMatch(kFALSE) ;
384  if (!labelName && lbl.IsNull()) {
385  lblMatch=kTRUE ;
386  } else if (labelName && !lbl.CompareTo(labelName)) {
387  lblMatch=kTRUE ;
388  }
389 
390  if (lblMatch) {
391  // Label and variable name match, recycle entry
392  return i ;
393  }
394  }
395  }
396 
397  // Register new entry ;
398  _useList.Add(arg) ;
399  _useIsCat.push_back(dynamic_cast<RooAbsCategory*>(arg)) ;
400  if (!labelName) {
401  _labelList.Add(new TObjString("")) ;
402  } else {
403  _labelList.Add(new TObjString(labelName)) ;
404  }
405 
406  return (_useList.GetSize()-1) ;
407 }
408 
409 
410 
411 ////////////////////////////////////////////////////////////////////////////////
412 /// Printing interface
413 
414 void RooFormula::printMultiline(ostream& os, Int_t /*contents*/, Bool_t /*verbose*/, TString indent) const
415 {
416  os << indent << "--- RooFormula ---" << endl;
417  os << indent << " Formula: \"" << GetTitle() << "\"" << endl;
418  indent.Append(" ");
419  os << indent << actualDependents() << endl ;
420 }
421 
422 
423 ////////////////////////////////////////////////////////////////////////////////
424 /// Print value of formula
425 
426 void RooFormula::printValue(ostream& os) const
427 {
428  os << const_cast<RooFormula*>(this)->eval(0) ;
429 }
430 
431 
432 ////////////////////////////////////////////////////////////////////////////////
433 /// Print name of formula
434 
435 void RooFormula::printName(ostream& os) const
436 {
437  os << GetName() ;
438 }
439 
440 
441 ////////////////////////////////////////////////////////////////////////////////
442 /// Print title of formula
443 
444 void RooFormula::printTitle(ostream& os) const
445 {
446  os << GetTitle() ;
447 }
448 
449 
450 ////////////////////////////////////////////////////////////////////////////////
451 /// Print class name of formula
452 
453 void RooFormula::printClassName(ostream& os) const
454 {
455  os << IsA()->GetName() ;
456 }
457 
458 
459 ////////////////////////////////////////////////////////////////////////////////
460 /// Print arguments of formula, i.e. dependents that are actually used
461 
462 void RooFormula::printArgs(ostream& os) const
463 {
464  os << "[ actualVars=" << _actual << " ]" ;
465 }
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
TIterator * createIterator(Bool_t dir=kIterForward) const
#define coutE(a)
Definition: RooMsgService.h:34
TObject * FindObject(const char *name) const
Return pointer to obejct with given name.
virtual Bool_t add(const RooAbsCollection &col, Bool_t silent=kFALSE)
Add a collection of arguments to this collection by calling add() for each element in the source coll...
Definition: RooArgSet.h:86
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=0)
Definition: TFormula.h:235
RooLinkedList _origList
Definition: RooFormula.h:82
Collectable string class.
Definition: TObjString.h:28
Bool_t reCompile(const char *newFormula)
Recompile formula with new expression.
Definition: RooFormula.cxx:111
Double_t getVal(const RooArgSet *set=0) const
Definition: RooAbsReal.h:64
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:131
RooArgSet * _nset
Definition: RooFormula.h:80
virtual void printName(std::ostream &os) const
Print name of formula.
Definition: RooFormula.cxx:435
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
virtual Int_t getIndex() const
Return index number of current state.
STL namespace.
virtual Int_t Compile(const char *expression="")
Compile expression already stored in fTitle.
void Clear(Option_t *o=0)
Remove all elements from collection.
Int_t GetSize() const
Definition: RooLinkedList.h:60
Iterator abstract base class.
Definition: TIterator.h:30
Bool_t Replace(const TObject *oldArg, const TObject *newArg)
Replace object &#39;oldArg&#39; in collection with new object &#39;newArg&#39;.
RooArgSet & actualDependents() const
Return list of RooAbsArg dependents that is actually used by formula expression.
Definition: RooFormula.cxx:142
const char * String
Definition: TXMLSetup.cxx:94
RooAbsArg * findNewServer(const RooAbsCollection &newSet, Bool_t nameChange) const
Find the new server in the specified set that matches the old server.
Definition: RooAbsArg.cxx:1051
void setStringAttribute(const Text_t *key, const Text_t *value)
Associate string &#39;value&#39; to this object under key &#39;key&#39;.
Definition: RooAbsArg.cxx:298
virtual void printClassName(std::ostream &os) const
Print class name of formula.
Definition: RooFormula.cxx:453
RooPlotable is a &#39;mix-in&#39; base class that define the standard RooFit plotting and printing methods...
Definition: RooPrintable.h:25
virtual void removeAll()
Remove all arguments from our set, deleting them if we own them.
Bool_t _compiled
Definition: RooFormula.h:87
Bool_t _isOK
Definition: RooFormula.h:81
RooLinkedList _labelList
Set of actual dependents.
Definition: RooFormula.h:86
void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Printing interface.
Definition: RooFormula.cxx:414
std::vector< Bool_t > _useIsCat
Original list of dependents.
Definition: RooFormula.h:83
RooFormula an implementation of ROOT::v5::TFormula that interfaces it to RooAbsArg value objects...
Definition: RooFormula.h:27
Double_t eval(const RooArgSet *nset=0)
Evaluate ROOT::v5::TFormula using given normalization set to be used as observables definition passed...
Definition: RooFormula.cxx:234
Int_t DefinedVariable(TString &name, int &action)
Interface to ROOT::v5::TFormula.
Definition: RooFormula.cxx:295
RooLinkedList _useList
Is given slot in _useList a category?
Definition: RooFormula.h:84
virtual void Add(TObject *arg)
Definition: RooLinkedList.h:62
Double_t DefinedValue(Int_t code)
Interface to ROOT::v5::TFormula, return value defined by object with id &#39;code&#39; Object ids are mapped ...
Definition: RooFormula.cxx:260
virtual void printArgs(std::ostream &os) const
Print arguments of formula, i.e. dependents that are actually used.
Definition: RooFormula.cxx:462
SVector< double, 2 > v
Definition: Dict.h:5
TObject * At(Int_t index) const
Return object stored in sequential position given by index.
The Formula class.
Definition: TFormula.h:83
virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const
Evaluate this formula.
const RooCatType * lookupType(Int_t index, Bool_t printError=kFALSE) const
Find our type corresponding to the specified index, or return 0 for no match.
const Text_t * getStringAttribute(const Text_t *key) const
Get string attribute mapped under key &#39;key&#39;.
Definition: RooAbsArg.cxx:313
RooLinkedListIter iterator(Bool_t dir=kTRUE) const
const Bool_t kFALSE
Definition: RtypesCore.h:92
RooFormula()
Default constructor coverity[UNINIT_CTOR].
Definition: RooFormula.cxx:55
void Delete(Option_t *o=0)
Remove all elements in collection and delete all elements NB: Collection does not own elements...
#define ClassImp(name)
Definition: Rtypes.h:336
double Double_t
Definition: RtypesCore.h:55
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:53
RooAbsCollection is an abstract container object that can hold multiple RooAbsArg objects...
Int_t getVal() const
Definition: RooCatType.h:79
TIterator * MakeIterator(Bool_t dir=kTRUE) const
Return an iterator over this list.
virtual void printTitle(std::ostream &os) const
Print title of formula.
Definition: RooFormula.cxx:444
virtual ~RooFormula()
Destructor.
Definition: RooFormula.cxx:132
virtual TObject * Next()=0
RooAbsCategory is the common abstract base class for objects that represent a discrete value with a f...
RooArgSet _actual
List of actual dependents.
Definition: RooFormula.h:85
Bool_t changeDependents(const RooAbsCollection &newDeps, Bool_t mustReplaceAll, Bool_t nameChange)
Change used variables to those with the same name in given list If mustReplaceAll is true and error i...
Definition: RooFormula.cxx:191
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:66
void dump()
DEBUG: Dump state information.
Definition: RooFormula.cxx:166
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:364
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:155
const Bool_t kTRUE
Definition: RtypesCore.h:91
RooLinkedListIter is the TIterator implementation for RooLinkedList.
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual void printValue(std::ostream &os) const
Print value of formula.
Definition: RooFormula.cxx:426