Logo ROOT   6.16/01
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
22RooFormula an implementation of ROOT::v5::TFormula that interfaces it to RooAbsArg
23value objects. It allows to use the value of a given list of RooAbsArg objects in the formula
24expression. Reference is done either by the RooAbsArgs name
25or by list ordinal postion ('@0,@1,...'). State information
26of RooAbsCategories can be accessed used the '::' operator,
27e.g. 'tagCat::Kaon' will resolve to the numerical value of
28the '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
46using namespace std;
47
49
50
51////////////////////////////////////////////////////////////////////////////////
52/// Default constructor
53/// coverity[UNINIT_CTOR]
54
56{
57}
58
59
60////////////////////////////////////////////////////////////////////////////////
61/// Constructor with expression string and list of RooAbsArg variables
62
63RooFormula::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
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
89RooFormula::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() ;
104}
105
106
107
108////////////////////////////////////////////////////////////////////////////////
109/// Recompile formula with new expression
110
111Bool_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{
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
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
191Bool_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
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
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
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
414void 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
426void RooFormula::printValue(ostream& os) const
427{
428 os << const_cast<RooFormula*>(this)->eval(0) ;
429}
430
431
432////////////////////////////////////////////////////////////////////////////////
433/// Print name of formula
434
435void RooFormula::printName(ostream& os) const
436{
437 os << GetName() ;
438}
439
440
441////////////////////////////////////////////////////////////////////////////////
442/// Print title of formula
443
444void RooFormula::printTitle(ostream& os) const
445{
446 os << GetTitle() ;
447}
448
449
450////////////////////////////////////////////////////////////////////////////////
451/// Print class name of formula
452
453void 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
462void RooFormula::printArgs(ostream& os) const
463{
464 os << "[ actualVars=" << _actual << " ]" ;
465}
SVector< double, 2 > v
Definition: Dict.h:5
#define coutE(a)
Definition: RooMsgService.h:34
int Int_t
Definition: RtypesCore.h:41
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:363
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=0)
Definition: TFormula.h:235
virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const
Evaluate this formula.
virtual Int_t Compile(const char *expression="")
Compile expression already stored in fTitle.
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:66
void setStringAttribute(const Text_t *key, const Text_t *value)
Associate string 'value' to this object under key 'key'.
Definition: RooAbsArg.cxx:273
const Text_t * getStringAttribute(const Text_t *key) const
Get string attribute mapped under key 'key'.
Definition: RooAbsArg.cxx:286
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:1043
RooAbsCategory is the common abstract base class for objects that represent a discrete value with a f...
virtual Int_t getIndex() const
Return index number of current state.
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.
RooAbsCollection is an abstract container object that can hold multiple RooAbsArg objects.
virtual void removeAll()
Remove all arguments from our set, deleting them if we own them.
TIterator * createIterator(Bool_t dir=kIterForward) const
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:53
Double_t getVal(const RooArgSet *set=0) const
Evaluate object. Returns either cached value or triggers a recalculation.
Definition: RooAbsReal.h:64
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:28
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:88
Int_t getVal() const
Definition: RooCatType.h:79
RooFormula an implementation of ROOT::v5::TFormula that interfaces it to RooAbsArg value objects.
Definition: RooFormula.h:27
Bool_t reCompile(const char *newFormula)
Recompile formula with new expression.
Definition: RooFormula.cxx:111
virtual void printName(std::ostream &os) const
Print name of formula.
Definition: RooFormula.cxx:435
RooArgSet * _nset
Definition: RooFormula.h:80
virtual void printTitle(std::ostream &os) const
Print title of formula.
Definition: RooFormula.cxx:444
virtual void printClassName(std::ostream &os) const
Print class name of formula.
Definition: RooFormula.cxx:453
RooLinkedList _origList
Definition: RooFormula.h:82
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:260
virtual ~RooFormula()
Destructor.
Definition: RooFormula.cxx:132
RooArgSet & actualDependents() const
Return list of RooAbsArg dependents that is actually used by formula expression.
Definition: RooFormula.cxx:142
virtual void printValue(std::ostream &os) const
Print value of formula.
Definition: RooFormula.cxx:426
RooFormula()
Default constructor coverity[UNINIT_CTOR].
Definition: RooFormula.cxx:55
std::vector< Bool_t > _useIsCat
Original list of dependents.
Definition: RooFormula.h:83
RooLinkedList _labelList
Set of actual dependents.
Definition: RooFormula.h:86
RooArgSet _actual
List of actual dependents.
Definition: RooFormula.h:85
Bool_t _isOK
Definition: RooFormula.h:81
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
void dump()
DEBUG: Dump state information.
Definition: RooFormula.cxx:166
void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Printing interface.
Definition: RooFormula.cxx:414
virtual void printArgs(std::ostream &os) const
Print arguments of formula, i.e. dependents that are actually used.
Definition: RooFormula.cxx:462
RooLinkedList _useList
Is given slot in _useList a category?
Definition: RooFormula.h:84
Bool_t _compiled
Definition: RooFormula.h:87
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
RooLinkedListIter is the TIterator implementation for RooLinkedList.
Int_t GetSize() const
Definition: RooLinkedList.h:60
RooLinkedListIter iterator(Bool_t dir=kTRUE) const
TObject * FindObject(const char *name) const
Return pointer to obejct with given name.
TIterator * MakeIterator(Bool_t dir=kTRUE) const
Return an iterator over this list.
TObject * At(Int_t index) const
Return object stored in sequential position given by index.
void Delete(Option_t *o=0)
Remove all elements in collection and delete all elements NB: Collection does not own elements,...
virtual void Add(TObject *arg)
Definition: RooLinkedList.h:62
void Clear(Option_t *o=0)
Remove all elements from collection.
Bool_t Replace(const TObject *oldArg, const TObject *newArg)
Replace object 'oldArg' in collection with new object 'newArg'.
RooPlotable is a 'mix-in' base class that define the standard RooFit plotting and printing methods.
Definition: RooPrintable.h:25
The Formula class.
Definition: TFormula.h:84
Iterator abstract base class.
Definition: TIterator.h:30
virtual TObject * Next()=0
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
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
Collectable string class.
Definition: TObjString.h:28
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
@ InputArguments
Definition: RooGlobalFunc.h:58
@ LinkStateMgmt
Definition: RooGlobalFunc.h:57
STL namespace.
const char * String
Definition: TXMLSetup.cxx:93