00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "RooFit.h"
00031
00032 #include "Riostream.h"
00033 #include "Riostream.h"
00034 #include <stdlib.h>
00035 #include "TROOT.h"
00036 #include "TClass.h"
00037 #include "TObjString.h"
00038 #include "RooFormula.h"
00039 #include "RooAbsReal.h"
00040 #include "RooAbsCategory.h"
00041 #include "RooArgList.h"
00042 #include "RooMsgService.h"
00043
00044 ClassImp(RooFormula)
00045
00046
00047
00048 RooFormula::RooFormula() : TFormula(), _nset(0)
00049 {
00050
00051
00052 }
00053
00054
00055
00056 RooFormula::RooFormula(const char* name, const char* formula, const RooArgList& list) :
00057 TFormula(), _isOK(kTRUE), _compiled(kFALSE)
00058 {
00059
00060
00061 SetName(name) ;
00062 SetTitle(formula) ;
00063
00064 TIterator* iter = list.createIterator() ;
00065 RooAbsArg* arg ;
00066 while ((arg=(RooAbsArg*)iter->Next())) {
00067 _origList.Add(arg) ;
00068 }
00069 delete iter ;
00070
00071 _compiled = kTRUE ;
00072 if (Compile()) {
00073 coutE(InputArguments) << "RooFormula::RooFormula(" << GetName() << "): compile error" << endl ;
00074 _isOK = kFALSE ;
00075 return ;
00076 }
00077 }
00078
00079
00080
00081
00082 RooFormula::RooFormula(const RooFormula& other, const char* name) :
00083 TFormula(), RooPrintable(other), _isOK(other._isOK), _compiled(kFALSE)
00084 {
00085
00086
00087 SetName(name?name:other.GetName()) ;
00088 SetTitle(other.GetTitle()) ;
00089
00090 TIterator* iter = other._origList.MakeIterator() ;
00091 RooAbsArg* arg ;
00092 while ((arg=(RooAbsArg*)iter->Next())) {
00093 _origList.Add(arg) ;
00094 }
00095 delete iter ;
00096
00097 Compile() ;
00098 _compiled=kTRUE ;
00099 }
00100
00101
00102
00103
00104 Bool_t RooFormula::reCompile(const char* newFormula)
00105 {
00106
00107
00108 fNval=0 ;
00109 _useList.Clear() ;
00110
00111 TString oldFormula=GetTitle() ;
00112 if (Compile(newFormula)) {
00113 coutE(InputArguments) << "RooFormula::reCompile: new equation doesn't compile, formula unchanged" << endl ;
00114 reCompile(oldFormula) ;
00115 return kTRUE ;
00116 }
00117
00118 SetTitle(newFormula) ;
00119 return kFALSE ;
00120 }
00121
00122
00123
00124
00125 RooFormula::~RooFormula()
00126 {
00127
00128
00129 _labelList.Delete() ;
00130 }
00131
00132
00133
00134
00135 RooArgSet& RooFormula::actualDependents() const
00136 {
00137
00138
00139 if (!_compiled) {
00140 _isOK = !((RooFormula*)this)->Compile() ;
00141 _compiled = kTRUE ;
00142 }
00143
00144
00145
00146 _actual.removeAll();
00147
00148 int i ;
00149 for (i=0 ; i<_useList.GetSize() ; i++) {
00150 _actual.add((RooAbsArg&)*_useList.At(i),kTRUE) ;
00151 }
00152
00153 return _actual ;
00154 }
00155
00156
00157
00158
00159 void RooFormula::dump()
00160 {
00161
00162
00163 int i ;
00164 cout << "RooFormula::dump()" << endl ;
00165 cout << "useList:" << endl ;
00166 for (i=0 ; i<_useList.GetSize() ; i++) {
00167 cout << "[" << i << "] = " << (void*) _useList.At(i) << " " << _useList.At(i)->GetName() << endl ;
00168 }
00169 cout << "labelList:" << endl ;
00170 for (i=0 ; i<_labelList.GetSize() ; i++) {
00171 cout << "[" << i << "] = " << (void*) _labelList.At(i) << " " << _labelList.At(i)->GetName() << endl ;
00172 }
00173 cout << "origList:" << endl ;
00174 for (i=0 ; i<_origList.GetSize() ; i++) {
00175 cout << "[" << i << "] = " << (void*) _origList.At(i) << " " << _origList.At(i)->GetName() << endl ;
00176 }
00177 }
00178
00179
00180
00181
00182 Bool_t RooFormula::changeDependents(const RooAbsCollection& newDeps, Bool_t mustReplaceAll, Bool_t nameChange)
00183 {
00184
00185
00186
00187
00188
00189 Bool_t errorStat(kFALSE) ;
00190 int i ;
00191
00192 for (i=0 ; i<_useList.GetSize() ; i++) {
00193 RooAbsReal* replace = (RooAbsReal*) ((RooAbsArg*)_useList.At(i))->findNewServer(newDeps,nameChange) ;
00194 if (replace) {
00195 _useList.Replace(_useList.At(i),replace) ;
00196 } else if (mustReplaceAll) {
00197 coutE(LinkStateMgmt) << "RooFormula::changeDependents(1): cannot find replacement for "
00198 << _useList.At(i)->GetName() << endl ;
00199 errorStat = kTRUE ;
00200 }
00201 }
00202
00203 TIterator* iter = _origList.MakeIterator() ;
00204 RooAbsArg* arg ;
00205 while ((arg=(RooAbsArg*)iter->Next())) {
00206 RooAbsReal* replace = (RooAbsReal*) arg->findNewServer(newDeps,nameChange) ;
00207 if (replace) {
00208 _origList.Replace(arg,replace) ;
00209 } else if (mustReplaceAll) {
00210 errorStat = kTRUE ;
00211 }
00212 }
00213 delete iter ;
00214
00215 return errorStat ;
00216 }
00217
00218
00219
00220
00221 Double_t RooFormula::eval(const RooArgSet* nset)
00222 {
00223
00224
00225
00226 if (!_compiled) {
00227 _isOK = !Compile() ;
00228 _compiled = kTRUE ;
00229 }
00230
00231
00232 if (!_isOK) {
00233 coutE(Eval) << "RooFormula::eval(" << GetName() << "): Formula doesn't compile: " << GetTitle() << endl ;
00234 return 0. ;
00235 }
00236
00237
00238 _nset = (RooArgSet*) nset ;
00239
00240 return EvalPar(0,0) ;
00241 }
00242
00243
00244 Double_t
00245
00246
00247 RooFormula::DefinedValue(Int_t code)
00248 {
00249
00250
00251
00252
00253 if (code>=_useList.GetSize()) return 0 ;
00254 RooAbsArg* arg=(RooAbsArg*)_useList.At(code) ;
00255
00256 const RooAbsReal *absReal= dynamic_cast<const RooAbsReal*>(arg);
00257 if(0 != absReal) {
00258 return absReal->getVal(_nset) ;
00259 } else {
00260 const RooAbsCategory *absCat= dynamic_cast<const RooAbsCategory*>(arg);
00261 if(0 != absCat) {
00262 TString& label=((TObjString*)_labelList.At(code))->String() ;
00263 if (label.IsNull()) {
00264 return absCat->getIndex() ;
00265 } else {
00266 return absCat->lookupType(label)->getVal() ;
00267 }
00268 }
00269 }
00270 assert(0) ;
00271 return 0 ;
00272 }
00273
00274
00275
00276
00277 Int_t RooFormula::DefinedVariable(TString &name, int& action)
00278 {
00279
00280
00281
00282
00283 Int_t ret = DefinedVariable(name) ;
00284 if (ret>=0) {
00285
00286 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
00287 action = kDefinedVariable;
00288 #else
00289 action = 0 ;
00290 #endif
00291
00292 }
00293 return ret ;
00294 }
00295
00296
00297
00298
00299 Int_t RooFormula::DefinedVariable(TString &name)
00300 {
00301
00302
00303
00304
00305 char argName[1024];
00306 strlcpy(argName,name.Data(),1024) ;
00307
00308
00309 char *labelName = strstr(argName,"::") ;
00310 if (labelName) {
00311 *labelName = 0 ;
00312 labelName+= 2 ;
00313 }
00314
00315
00316 RooAbsArg *arg = 0;
00317 if (argName[0] == '@') {
00318
00319 Int_t index = atoi(argName+1) ;
00320 if (index>=0 && index<_origList.GetSize()) {
00321 arg = (RooAbsArg*) _origList.At(index) ;
00322 } else {
00323 coutE(Eval) << "RooFormula::DefinedVariable(" << GetName()
00324 << ") ERROR: ordinal variable reference " << name
00325 << " out of range (0 - " << _origList.GetSize()-1 << ")" << endl ;
00326 }
00327 } else {
00328
00329 arg= (RooAbsArg*) _origList.FindObject(argName) ;
00330 }
00331
00332
00333 if (!arg) return -1 ;
00334
00335
00336 if (labelName) {
00337 RooAbsCategory* cat = dynamic_cast<RooAbsCategory*>(arg) ;
00338 if (!cat) {
00339 coutE(Eval) << "RooFormula::DefinedVariable(" << GetName() << ") ERROR: "
00340 << arg->GetName() << "' is not a RooAbsCategory" << endl ;
00341 return -1 ;
00342 }
00343
00344 if (!cat->lookupType(labelName)) {
00345 coutE(Eval) << "RooFormula::DefinedVariable(" << GetName() << ") ERROR '"
00346 << labelName << "' is not a state of " << arg->GetName() << endl ;
00347 return -1 ;
00348 }
00349
00350 }
00351
00352
00353
00354 Int_t i ;
00355 for(i=0 ; i<_useList.GetSize() ; i++) {
00356 RooAbsArg* var = (RooAbsArg*) _useList.At(i) ;
00357 Bool_t varMatch = !TString(var->GetName()).CompareTo(arg->GetName()) ;
00358
00359 if (varMatch) {
00360 TString& lbl= ((TObjString*) _labelList.At(i))->String() ;
00361 Bool_t lblMatch(kFALSE) ;
00362 if (!labelName && lbl.IsNull()) {
00363 lblMatch=kTRUE ;
00364 } else if (labelName && !lbl.CompareTo(labelName)) {
00365 lblMatch=kTRUE ;
00366 }
00367
00368 if (lblMatch) {
00369
00370 return i ;
00371 }
00372 }
00373 }
00374
00375
00376 _useList.Add(arg) ;
00377 if (!labelName) {
00378 _labelList.Add(new TObjString("")) ;
00379 } else {
00380 _labelList.Add(new TObjString(labelName)) ;
00381 }
00382
00383 return (_useList.GetSize()-1) ;
00384 }
00385
00386
00387
00388
00389 void RooFormula::printMultiline(ostream& os, Int_t , Bool_t , TString indent) const
00390 {
00391
00392
00393 os << indent << "--- RooFormula ---" << endl;
00394 os << indent << " Formula: \"" << GetTitle() << "\"" << endl;
00395 indent.Append(" ");
00396 os << indent << actualDependents() << endl ;
00397 }
00398
00399
00400
00401 void RooFormula::printValue(ostream& os) const
00402 {
00403
00404
00405 os << const_cast<RooFormula*>(this)->eval(0) ;
00406 }
00407
00408
00409
00410 void RooFormula::printName(ostream& os) const
00411 {
00412
00413
00414 os << GetName() ;
00415 }
00416
00417
00418
00419 void RooFormula::printTitle(ostream& os) const
00420 {
00421
00422
00423 os << GetTitle() ;
00424 }
00425
00426
00427
00428 void RooFormula::printClassName(ostream& os) const
00429 {
00430
00431
00432 os << IsA()->GetName() ;
00433 }
00434
00435
00436
00437 void RooFormula::printArgs(ostream& os) const
00438 {
00439
00440
00441 os << "[ actualVars=" << _actual << " ]" ;
00442 }