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