RooArgSet.cxx

Go to the documentation of this file.
00001 /***************************************************************************** * Project: RooFit                                                           *
00002  * Package: RooFitCore                                                       *
00003  * @(#)root/roofitcore:$Id: RooArgSet.cxx 36230 2010-10-09 20:21:02Z wouter $
00004  * Authors:                                                                  *
00005  *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
00006  *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
00007  *                                                                           *
00008  * Copyright (c) 2000-2005, Regents of the University of California          *
00009  *                          and Stanford University. All rights reserved.    *
00010  *                                                                           *
00011  * Redistribution and use in source and binary forms,                        *
00012  * with or without modification, are permitted according to the terms        *
00013  * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
00014  *****************************************************************************/
00015 
00016 //////////////////////////////////////////////////////////////////////////////
00017 // 
00018 // RooArgSet is a container object that can hold multiple RooAbsArg objects.
00019 // The container has set semantics which means that:
00020 //
00021 //  - Every object it contains must have a unique name returned by GetName().
00022 //
00023 //  - Contained objects are not ordered, although the set can be traversed
00024 //    using an iterator returned by createIterator(). The iterator does not
00025 //    necessarily follow the object insertion order.
00026 //
00027 //  - Objects can be retrieved by name only, and not by index.
00028 //
00029 //
00030 // Ownership of contents. 
00031 //
00032 // Unowned objects are inserted with the add() method. Owned objects
00033 // are added with addOwned() or addClone(). A RooArgSet either owns all 
00034 // of it contents, or none, which is determined by the first <add>
00035 // call. Once an ownership status is selected, inappropriate <add> calls
00036 // will return error status. Clearing the list via removeAll() resets the 
00037 // ownership status. Arguments supplied in the constructor are always added 
00038 // as unowned elements.
00039 //
00040 //
00041 
00042 #include "RooFit.h"
00043 
00044 #include "Riostream.h"
00045 #include <iomanip>
00046 #include <fstream>
00047 #include <list>
00048 #include "TClass.h"
00049 #include "RooArgSet.h"
00050 #include "RooStreamParser.h"
00051 #include "RooFormula.h"
00052 #include "RooAbsRealLValue.h"
00053 #include "RooAbsCategoryLValue.h"
00054 #include "RooStringVar.h"
00055 #include "RooTrace.h"
00056 #include "RooArgList.h"
00057 #include "RooSentinel.h"
00058 #include "RooMsgService.h"
00059 
00060 using namespace std ;
00061 
00062 #if (__GNUC__==3&&__GNUC_MINOR__==2&&__GNUC_PATCHLEVEL__==3)
00063 char* operator+( streampos&, char* );
00064 #endif
00065 
00066 ClassImp(RooArgSet)
00067   ;
00068 
00069 char* RooArgSet::_poolBegin = 0 ;
00070 char* RooArgSet::_poolCur = 0 ;
00071 char* RooArgSet::_poolEnd = 0 ;
00072 #define POOLSIZE 1048576
00073 
00074 struct POOLDATA 
00075 {
00076   void* _base ;
00077 } ;
00078 
00079 static std::list<POOLDATA> _memPoolList ;
00080 
00081 //_____________________________________________________________________________
00082 void RooArgSet::cleanup()
00083 {
00084   // Clear memoery pool on exit to avoid reported memory leaks
00085 
00086   std::list<POOLDATA>::iterator iter = _memPoolList.begin() ;
00087   while(iter!=_memPoolList.end()) {
00088     free(iter->_base) ;
00089     iter->_base=0 ;
00090     iter++ ;
00091   }
00092   _memPoolList.clear() ;
00093 }
00094 
00095 
00096 #ifdef USEMEMPOOL
00097 
00098 //_____________________________________________________________________________
00099 void* RooArgSet::operator new (size_t bytes)
00100 {
00101   // Overloaded new operator guarantees that all RooArgSets allocated with new
00102   // have a unique address, a property that is exploited in several places
00103   // in roofit to quickly index contents on normalization set pointers. 
00104   // The memory pool only allocates space for the class itself. The elements
00105   // stored in the set are stored outside the pool.
00106 
00107   //cout << " RooArgSet::operator new(" << bytes << ")" << endl ;
00108 
00109   if (!_poolBegin || _poolCur+(sizeof(RooArgSet)) >= _poolEnd) {
00110 
00111     if (_poolBegin!=0) {
00112       oocxcoutD((TObject*)0,Caching) << "RooArgSet::operator new(), starting new 1MB memory pool" << endl ;
00113     }
00114 
00115     // Start pruning empty memory pools if number exceeds 3
00116     if (_memPoolList.size()>3) {
00117       
00118       void* toFree(0) ;
00119 
00120       for (std::list<POOLDATA>::iterator poolIter =  _memPoolList.begin() ; poolIter!=_memPoolList.end() ; ++poolIter) {
00121 
00122         // If pool is empty, delete it and remove it from list
00123         if ((*(Int_t*)(poolIter->_base))==0) {
00124           oocxcoutD((TObject*)0,Caching) << "RooArgSet::operator new(), pruning empty memory pool " << (void*)(poolIter->_base) << endl ;
00125 
00126           toFree = poolIter->_base ;
00127           _memPoolList.erase(poolIter) ;
00128           break ;
00129         }
00130       }      
00131 
00132       free(toFree) ;      
00133     }
00134     
00135     void* mem = malloc(POOLSIZE) ;
00136 
00137     _poolBegin = (char*)mem ;
00138     // Reserve space for pool counter at head of pool
00139     _poolCur = _poolBegin+sizeof(Int_t) ;
00140     _poolEnd = _poolBegin+(POOLSIZE) ;
00141 
00142     // Clear pool counter
00143     *((Int_t*)_poolBegin)=0 ;
00144     
00145     POOLDATA p ;
00146     p._base=mem ;
00147     _memPoolList.push_back(p) ;
00148 
00149     RooSentinel::activate() ;
00150   }
00151 
00152   char* ptr = _poolCur ;
00153   _poolCur += bytes ;
00154 
00155   // Increment use counter of pool
00156   (*((Int_t*)_poolBegin))++ ;
00157 
00158   return ptr ;
00159 
00160 }
00161 
00162 
00163 
00164 //_____________________________________________________________________________
00165 void RooArgSet::operator delete (void* ptr)
00166 {
00167   // Memory is owned by pool, we need to do nothing to release it
00168 
00169   // Decrease use count in pool that ptr is on
00170   for (std::list<POOLDATA>::iterator poolIter =  _memPoolList.begin() ; poolIter!=_memPoolList.end() ; ++poolIter) {
00171     if ((char*)ptr > (char*)poolIter->_base && (char*)ptr < (char*)poolIter->_base + POOLSIZE) {
00172       (*(Int_t*)(poolIter->_base))-- ;
00173       break ;
00174     }
00175   }
00176   
00177 }
00178 
00179 #endif
00180 
00181 
00182 //_____________________________________________________________________________
00183 RooArgSet::RooArgSet() :
00184   RooAbsCollection()
00185 {
00186   // Default constructor
00187 }
00188 
00189 
00190 
00191 //_____________________________________________________________________________
00192 RooArgSet::RooArgSet(const RooArgList& list) :
00193   RooAbsCollection(list.GetName())
00194 {
00195   // Constructor from a RooArgList. If the list contains multiple
00196   // objects with the same name, only the first is store in the set.
00197   // Warning messages will be printed for dropped items.
00198 
00199   add(list,kTRUE) ; // verbose to catch duplicate errors
00200 }
00201 
00202 
00203 
00204 //_____________________________________________________________________________
00205 RooArgSet::RooArgSet(const RooArgList& list, const RooAbsArg* var1) :
00206   RooAbsCollection(list.GetName())
00207 {
00208   // Constructor from a RooArgList. If the list contains multiple
00209   // objects with the same name, only the first is store in the set.
00210   // Warning messages will be printed for dropped items.
00211 
00212   if (var1) {
00213     add(*var1,kTRUE) ;
00214   }
00215   add(list,kTRUE) ; // verbose to catch duplicate errors
00216 }
00217 
00218 
00219 
00220 //_____________________________________________________________________________
00221 RooArgSet::RooArgSet(const char *name) :
00222   RooAbsCollection(name)
00223 {
00224   // Empty set constructor
00225 }
00226 
00227 
00228 
00229 
00230 //_____________________________________________________________________________
00231 RooArgSet::RooArgSet(const RooArgSet& set1, const RooArgSet& set2, const char *name) : RooAbsCollection(name)
00232 {
00233   // Construct a set from two existing sets
00234   add(set1) ;
00235   add(set2) ;
00236     
00237 }
00238 
00239 
00240 
00241 
00242 //_____________________________________________________________________________
00243 RooArgSet::RooArgSet(const RooAbsArg& var1,
00244                      const char *name) :
00245   RooAbsCollection(name)
00246 {
00247   // Constructor for set containing 1 initial object
00248 
00249   add(var1);
00250 }
00251 
00252 
00253 
00254 //_____________________________________________________________________________
00255 RooArgSet::RooArgSet(const RooAbsArg& var1, const RooAbsArg& var2,
00256                      const char *name) :
00257   RooAbsCollection(name)
00258 {
00259   // Constructor for set containing 2 initial objects
00260 
00261   add(var1); add(var2);
00262 }
00263 
00264 
00265 
00266 //_____________________________________________________________________________
00267 RooArgSet::RooArgSet(const RooAbsArg& var1, const RooAbsArg& var2, 
00268                      const RooAbsArg& var3,
00269                      const char *name) :
00270   RooAbsCollection(name)
00271 {
00272   // Constructor for set containing 3 initial objects
00273 
00274   add(var1); add(var2); add(var3);
00275 }
00276 
00277 
00278 
00279 //_____________________________________________________________________________
00280 RooArgSet::RooArgSet(const RooAbsArg& var1, const RooAbsArg& var2, 
00281                      const RooAbsArg& var3, const RooAbsArg& var4,
00282                      const char *name) :
00283   RooAbsCollection(name)
00284 {
00285   // Constructor for set containing 4 initial objects
00286 
00287   add(var1); add(var2); add(var3); add(var4);
00288 }
00289 
00290 
00291 
00292 //_____________________________________________________________________________
00293 RooArgSet::RooArgSet(const RooAbsArg& var1,
00294                      const RooAbsArg& var2, const RooAbsArg& var3,
00295                      const RooAbsArg& var4, const RooAbsArg& var5,
00296                      const char *name) :
00297   RooAbsCollection(name)
00298 {
00299   // Constructor for set containing 5 initial objects
00300 
00301   add(var1); add(var2); add(var3); add(var4); add(var5);
00302 }
00303 
00304 
00305 
00306 //_____________________________________________________________________________
00307 RooArgSet::RooArgSet(const RooAbsArg& var1, const RooAbsArg& var2, 
00308                      const RooAbsArg& var3, const RooAbsArg& var4, 
00309                      const RooAbsArg& var5, const RooAbsArg& var6,
00310                      const char *name) :
00311   RooAbsCollection(name)
00312 {
00313   // Constructor for set containing 6 initial objects
00314 
00315   add(var1); add(var2); add(var3); add(var4); add(var5); add(var6);
00316 }
00317 
00318 
00319 
00320 //_____________________________________________________________________________
00321 RooArgSet::RooArgSet(const RooAbsArg& var1, const RooAbsArg& var2, 
00322                      const RooAbsArg& var3, const RooAbsArg& var4, 
00323                      const RooAbsArg& var5, const RooAbsArg& var6, 
00324                      const RooAbsArg& var7,
00325                      const char *name) :
00326   RooAbsCollection(name)
00327 {
00328   // Constructor for set containing 7 initial objects
00329 
00330   add(var1); add(var2); add(var3); add(var4); add(var5); add(var6); add(var7) ;
00331 }
00332 
00333 
00334 
00335 //_____________________________________________________________________________
00336 RooArgSet::RooArgSet(const RooAbsArg& var1, const RooAbsArg& var2, 
00337                      const RooAbsArg& var3, const RooAbsArg& var4, 
00338                      const RooAbsArg& var5, const RooAbsArg& var6, 
00339                      const RooAbsArg& var7, const RooAbsArg& var8,
00340                      const char *name) :
00341   RooAbsCollection(name)
00342 {
00343   // Constructor for set containing 8 initial objects
00344 
00345   add(var1); add(var2); add(var3); add(var4); add(var5); add(var6); add(var7) ;add(var8) ;
00346 }
00347 
00348 
00349 
00350 //_____________________________________________________________________________
00351 RooArgSet::RooArgSet(const RooAbsArg& var1, const RooAbsArg& var2, 
00352                      const RooAbsArg& var3, const RooAbsArg& var4, 
00353                      const RooAbsArg& var5, const RooAbsArg& var6, 
00354                      const RooAbsArg& var7, const RooAbsArg& var8,
00355                      const RooAbsArg& var9, const char *name) :
00356   RooAbsCollection(name)
00357 {
00358   // Constructor for set containing 9 initial objects
00359 
00360   add(var1); add(var2); add(var3); add(var4); add(var5); add(var6); add(var7); add(var8); add(var9);
00361 }
00362 
00363 
00364 
00365 //_____________________________________________________________________________
00366 RooArgSet::RooArgSet(const TCollection& tcoll, const char* name) :
00367   RooAbsCollection(name)
00368 {
00369   // Constructor from a root TCollection. Elements in the collection that
00370   // do not inherit from RooAbsArg will be skipped. A warning message
00371   // will be printed for every skipped item.
00372 
00373   TIterator* iter = tcoll.MakeIterator() ;
00374   TObject* obj ;
00375   while((obj=iter->Next())) {
00376     if (!dynamic_cast<RooAbsArg*>(obj)) {
00377       coutW(InputArguments) << "RooArgSet::RooArgSet(TCollection) element " << obj->GetName() 
00378                             << " is not a RooAbsArg, ignored" << endl ;
00379       continue ;
00380     }
00381     add(*(RooAbsArg*)obj) ;
00382   }
00383   delete iter ;
00384 }
00385 
00386 
00387 
00388 //_____________________________________________________________________________
00389 RooArgSet::RooArgSet(const RooArgSet& other, const char *name) 
00390   : RooAbsCollection(other,name)
00391 {
00392   // Copy constructor. Note that a copy of a set is always non-owning,
00393   // even the source set is owning. To create an owning copy of
00394   // a set (owning or not), use the snaphot() method.
00395 }
00396 
00397 
00398 
00399 //_____________________________________________________________________________
00400 RooArgSet::~RooArgSet() 
00401 {
00402   // Destructor
00403   
00404 }
00405 
00406 
00407 
00408 //_____________________________________________________________________________
00409 Bool_t RooArgSet::add(const RooAbsArg& var, Bool_t silent) 
00410 {
00411   // Add element to non-owning set. The operation will fail if
00412   // a similarly named object already exists in the set, or
00413   // the set is specified to own its elements. Eventual error messages
00414   // can be suppressed with the silent flag
00415 
00416   return checkForDup(var,silent)? kFALSE : RooAbsCollection::add(var,silent) ;
00417 }
00418 
00419 
00420 
00421 //_____________________________________________________________________________
00422 Bool_t RooArgSet::addOwned(RooAbsArg& var, Bool_t silent)
00423 {
00424   // Add element to an owning set. The operation will fail if
00425   // a similarly named object already exists in the set, or
00426   // the set is not specified to own its elements. Eventual error messages
00427   // can be suppressed with the silent flag
00428 
00429   return checkForDup(var,silent)? kFALSE : RooAbsCollection::addOwned(var,silent) ;
00430 }
00431 
00432 
00433 
00434 //_____________________________________________________________________________
00435 RooAbsArg* RooArgSet::addClone(const RooAbsArg& var, Bool_t silent) 
00436 {
00437   // Add clone of specified element to an owning set. If sucessful, the
00438   // set will own the clone, not the original. The operation will fail if
00439   // a similarly named object already exists in the set, or
00440   // the set is not specified to own its elements. Eventual error messages
00441   // can be suppressed with the silent flag
00442 
00443   return checkForDup(var,silent)? 0 : RooAbsCollection::addClone(var,silent) ;
00444 }
00445 
00446 
00447 
00448 //_____________________________________________________________________________
00449 RooAbsArg& RooArgSet::operator[](const char* name) const 
00450 {     
00451   // Array operator. Named element must exist in set, otherwise
00452   // code will abort. 
00453   //
00454   // When used as lvalue in assignment operations, the element contained in
00455   // the list will not be changed, only the value of the existing element!
00456 
00457   RooAbsArg* arg = find(name) ;
00458   if (!arg) {
00459     coutE(InputArguments) << "RooArgSet::operator[](" << GetName() << ") ERROR: no element named " << name << " in set" << endl ;
00460     RooErrorHandler::softAbort() ;
00461   }
00462   return *arg ; 
00463 }
00464 
00465 
00466 
00467 //_____________________________________________________________________________
00468 Bool_t RooArgSet::checkForDup(const RooAbsArg& var, Bool_t silent) const 
00469 {
00470   // Check if element with var's name is already in set
00471 
00472   RooAbsArg *other = 0;
00473   if((other= find(var.GetName()))) {
00474     if(other != &var) {
00475       if (!silent)
00476         // print a warning if this variable is not the same one we
00477         // already have
00478         coutE(InputArguments) << "RooArgSet::checkForDup: ERROR argument with name " << var.GetName() << " is already in this set" << endl;
00479     }
00480     // don't add duplicates
00481     return kTRUE;
00482   }
00483 
00484   return kFALSE ;
00485 }
00486 
00487 
00488 
00489 //_____________________________________________________________________________
00490 Double_t RooArgSet::getRealValue(const char* name, Double_t defVal, Bool_t verbose) const
00491 {
00492   // Get value of a RooAbsReal stored in set with given name. If none is found, value of defVal is returned.
00493   // No error messages are printed unless the verbose flag is set
00494 
00495   RooAbsArg* raa = find(name) ;
00496   if (!raa) {
00497     if (verbose) coutE(InputArguments) << "RooArgSet::getRealValue(" << GetName() << ") ERROR no object with name '" << name << "' found" << endl ;
00498     return defVal ;
00499   }
00500   RooAbsReal* rar = dynamic_cast<RooAbsReal*>(raa) ;
00501   if (!rar) {
00502     if (verbose) coutE(InputArguments) << "RooArgSet::getRealValue(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsReal" << endl ;
00503     return defVal ;
00504   }
00505   return rar->getVal() ;
00506 }
00507 
00508 
00509 
00510 //_____________________________________________________________________________
00511 Bool_t RooArgSet::setRealValue(const char* name, Double_t newVal, Bool_t verbose) 
00512 {
00513   // Set value of a RooAbsRealLValye stored in set with given name to newVal
00514   // No error messages are printed unless the verbose flag is set
00515 
00516   RooAbsArg* raa = find(name) ;
00517   if (!raa) {
00518     if (verbose) coutE(InputArguments) << "RooArgSet::setRealValue(" << GetName() << ") ERROR no object with name '" << name << "' found" << endl ;
00519     return kTRUE ;
00520   }
00521   RooAbsRealLValue* rar = dynamic_cast<RooAbsRealLValue*>(raa) ;
00522   if (!rar) {
00523     if (verbose) coutE(InputArguments) << "RooArgSet::setRealValue(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsRealLValue" << endl ;
00524     return kTRUE;
00525   }
00526   rar->setVal(newVal) ;
00527   return kFALSE ;
00528 }
00529 
00530 
00531 
00532 //_____________________________________________________________________________
00533 const char* RooArgSet::getCatLabel(const char* name, const char* defVal, Bool_t verbose) const
00534 {
00535   // Get state name of a RooAbsCategory stored in set with given name. If none is found, value of defVal is returned.
00536   // No error messages are printed unless the verbose flag is set
00537 
00538   RooAbsArg* raa = find(name) ;
00539   if (!raa) {
00540     if (verbose) coutE(InputArguments) << "RooArgSet::getCatLabel(" << GetName() << ") ERROR no object with name '" << name << "' found" << endl ;
00541     return defVal ;
00542   }
00543   RooAbsCategory* rac = dynamic_cast<RooAbsCategory*>(raa) ;
00544   if (!rac) {
00545     if (verbose) coutE(InputArguments) << "RooArgSet::getCatLabel(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsCategory" << endl ;
00546     return defVal ;
00547   }
00548   return rac->getLabel() ;
00549 }
00550 
00551 
00552 
00553 //_____________________________________________________________________________
00554 Bool_t RooArgSet::setCatLabel(const char* name, const char* newVal, Bool_t verbose) 
00555 {
00556   // Set state name of a RooAbsCategoryLValue stored in set with given name to newVal.
00557   // No error messages are printed unless the verbose flag is set
00558 
00559   RooAbsArg* raa = find(name) ;
00560   if (!raa) {
00561     if (verbose) coutE(InputArguments) << "RooArgSet::setCatLabel(" << GetName() << ") ERROR no object with name '" << name << "' found" << endl ;
00562     return kTRUE ;
00563   }
00564   RooAbsCategoryLValue* rac = dynamic_cast<RooAbsCategoryLValue*>(raa) ;
00565   if (!rac) {
00566     if (verbose) coutE(InputArguments) << "RooArgSet::setCatLabel(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsCategory" << endl ;
00567     return kTRUE ;
00568   }
00569   rac->setLabel(newVal) ;
00570   return kFALSE ;
00571 }
00572 
00573 
00574 
00575 //_____________________________________________________________________________
00576 Int_t RooArgSet::getCatIndex(const char* name, Int_t defVal, Bool_t verbose) const
00577 {
00578   // Get index value of a RooAbsCategory stored in set with given name. If none is found, value of defVal is returned.
00579   // No error messages are printed unless the verbose flag is set
00580 
00581   RooAbsArg* raa = find(name) ;
00582   if (!raa) {
00583     if (verbose) coutE(InputArguments) << "RooArgSet::getCatLabel(" << GetName() << ") ERROR no object with name '" << name << "' found" << endl ;
00584     return defVal ;
00585   }
00586   RooAbsCategory* rac = dynamic_cast<RooAbsCategory*>(raa) ;
00587   if (!rac) {
00588     if (verbose) coutE(InputArguments) << "RooArgSet::getCatLabel(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsCategory" << endl ;
00589     return defVal ;
00590   }
00591   return rac->getIndex() ;
00592 }
00593 
00594 
00595 
00596 //_____________________________________________________________________________
00597 Bool_t RooArgSet::setCatIndex(const char* name, Int_t newVal, Bool_t verbose) 
00598 {
00599   // Set index value of a RooAbsCategoryLValue stored in set with given name to newVal.
00600   // No error messages are printed unless the verbose flag is set
00601 
00602   RooAbsArg* raa = find(name) ;
00603   if (!raa) {
00604     if (verbose) coutE(InputArguments) << "RooArgSet::setCatLabel(" << GetName() << ") ERROR no object with name '" << name << "' found" << endl ;
00605     return kTRUE ;
00606   }
00607   RooAbsCategoryLValue* rac = dynamic_cast<RooAbsCategoryLValue*>(raa) ;
00608   if (!rac) {
00609     if (verbose) coutE(InputArguments) << "RooArgSet::setCatLabel(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsCategory" << endl ;
00610     return kTRUE ;
00611   }
00612   rac->setIndex(newVal) ;
00613   return kFALSE ;
00614 }
00615 
00616 
00617 
00618 //_____________________________________________________________________________
00619 const char* RooArgSet::getStringValue(const char* name, const char* defVal, Bool_t verbose) const
00620 {
00621   // Get string value of a RooAbsString stored in set with given name. If none is found, value of defVal is returned.
00622   // No error messages are printed unless the verbose flag is set
00623 
00624   RooAbsArg* raa = find(name) ;
00625   if (!raa) {
00626     if (verbose) coutE(InputArguments) << "RooArgSet::getStringValue(" << GetName() << ") ERROR no object with name '" << name << "' found" << endl ;
00627     return defVal ;
00628   }
00629   RooAbsString* ras = dynamic_cast<RooAbsString*>(raa) ;
00630   if (!ras) {
00631     if (verbose) coutE(InputArguments) << "RooArgSet::getStringValue(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsString" << endl ;
00632     return defVal ;
00633   }
00634   return ras->getVal() ;
00635 }
00636 
00637 
00638 
00639 //_____________________________________________________________________________
00640 Bool_t RooArgSet::setStringValue(const char* name, const char* newVal, Bool_t verbose) 
00641 {
00642   // Set string value of a RooStringVar stored in set with given name to newVal.
00643   // No error messages are printed unless the verbose flag is set
00644 
00645   RooAbsArg* raa = find(name) ;
00646   if (!raa) {
00647     if (verbose) coutE(InputArguments) << "RooArgSet::setStringValue(" << GetName() << ") ERROR no object with name '" << name << "' found" << endl ;
00648     return kTRUE ;
00649   }
00650   RooStringVar* ras = dynamic_cast<RooStringVar*>(raa) ;
00651   if (!ras) {
00652     if (verbose) coutE(InputArguments) << "RooArgSet::setStringValue(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsString" << endl ;
00653     return kTRUE ;
00654   }
00655   ras->setVal(newVal) ;
00656   return kFALSE ;
00657 }
00658 
00659 
00660 
00661 //_____________________________________________________________________________
00662 void RooArgSet::writeToFile(const char* fileName) const
00663 {
00664   // Write contents of the argset to specified file.
00665   // See writeToStream() for details
00666 
00667   ofstream ofs(fileName) ;
00668   if (ofs.fail()) {
00669     coutE(InputArguments) << "RooArgSet::writeToFile(" << GetName() << ") error opening file " << fileName << endl ;
00670     return ;
00671   }
00672   writeToStream(ofs,kFALSE) ;
00673 }
00674 
00675 
00676 
00677 //_____________________________________________________________________________
00678 Bool_t RooArgSet::readFromFile(const char* fileName, const char* flagReadAtt, const char* section, Bool_t verbose) 
00679 {
00680   // Read contents of the argset from specified file.
00681   // See readFromStream() for details
00682 
00683   ifstream ifs(fileName) ;
00684   if (ifs.fail()) {
00685     coutE(InputArguments) << "RooArgSet::readFromFile(" << GetName() << ") error opening file " << fileName << endl ;
00686     return kTRUE ;
00687   }
00688   return readFromStream(ifs,kFALSE,flagReadAtt,section,verbose) ;
00689 }
00690 
00691 
00692 
00693 
00694 //_____________________________________________________________________________
00695 void RooArgSet::writeToStream(ostream& os, Bool_t compact, const char* /*section*/) const
00696 {
00697   // Write the contents of the argset in ASCII form to given stream.
00698   // 
00699   // A line is written for each element contained in the form
00700   // <argName> = <argValue>
00701   // 
00702   // The <argValue> part of each element is written by the arguments' 
00703   // writeToStream() function.
00704 
00705   if (compact) {
00706     coutE(InputArguments) << "RooArgSet::writeToStream(" << GetName() << ") compact mode not supported" << endl ;
00707     return ;
00708   }
00709 
00710   TIterator *iterator= createIterator();
00711   RooAbsArg *next = 0;
00712   while((0 != (next= (RooAbsArg*)iterator->Next()))) {
00713     os << next->GetName() << " = " ;
00714     next->writeToStream(os,kFALSE) ;
00715     os << endl ;
00716   }
00717   delete iterator;  
00718 }
00719 
00720 
00721 
00722 
00723 //_____________________________________________________________________________
00724 Bool_t RooArgSet::readFromStream(istream& is, Bool_t compact, const char* flagReadAtt, const char* section, Bool_t verbose) 
00725 {
00726   // Read the contents of the argset in ASCII form from given stream.
00727   // 
00728   // The stream is read to end-of-file and each line is assumed to be
00729   // of the form
00730   //
00731   // <argName> = <argValue>
00732   // 
00733   // Lines starting with argNames not matching any element in the list
00734   // will be ignored with a warning message. In addition limited C++ style 
00735   // preprocessing and flow control is provided. The following constructions 
00736   // are recognized:
00737   //
00738   // > #include "include.file"       
00739   // 
00740   // Include given file, recursive inclusion OK
00741   // 
00742   // > if (<boolean_expression>)
00743   // >   <name> = <value>
00744   // >   ....
00745   // > else if (<boolean_expression>)
00746   //     ....
00747   // > else
00748   //     ....
00749   // > endif
00750   //
00751   // All expressions are evaluated by RooFormula, and may involve any of
00752   // the sets variables. 
00753   //
00754   // > echo <Message>
00755   //
00756   // Print console message while reading from stream
00757   //
00758   // > abort
00759   //
00760   // Force termination of read sequence with error status 
00761   //
00762   // The value of each argument is read by the arguments readFromStream
00763   // function.
00764 
00765   if (compact) {
00766     coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << ") compact mode not supported" << endl ;
00767     return kTRUE ;
00768   }
00769 
00770   RooStreamParser parser(is) ;
00771   parser.setPunctuation("=") ;
00772   TString token ;
00773   Bool_t retVal(kFALSE) ;
00774   
00775   // Conditional stack and related state variables
00776   Bool_t anyCondTrue[100] ;
00777   Bool_t condStack[100] ;
00778   Bool_t lastLineWasElse=kFALSE ;
00779   Int_t condStackLevel=0 ;
00780   condStack[0]=kTRUE ;
00781   
00782   // Prepare section processing
00783   TString sectionHdr("[") ;
00784   if (section) sectionHdr.Append(section) ;
00785   sectionHdr.Append("]") ;
00786   Bool_t inSection(section?kFALSE:kTRUE) ;
00787 
00788   Bool_t reprocessToken = kFALSE ;
00789   while (1) {
00790 
00791     if (is.eof() || is.fail() || parser.atEOF()) {
00792       break ;
00793     }
00794     
00795     // Read next token until end of file
00796     if (!reprocessToken) {
00797       token = parser.readToken() ;
00798     }
00799     reprocessToken = kFALSE ;
00800 
00801     // Skip empty lines 
00802     if (token.IsNull()) {
00803       continue ;
00804     }
00805 
00806     // Process include directives
00807     if (!token.CompareTo("include")) {
00808       if (parser.atEOL()) {
00809         coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() 
00810                               << "): no filename found after include statement" << endl ;
00811         return kTRUE ;
00812       }
00813       TString filename = parser.readLine() ;
00814       ifstream incfs(filename) ;
00815       if (!incfs.good()) {
00816         coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): cannot open include file " << filename << endl ;
00817         return kTRUE ;
00818       }
00819       coutI(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): processing include file " 
00820                             << filename << endl ;
00821       if (readFromStream(incfs,compact,flagReadAtt,inSection?0:section,verbose)) return kTRUE ;
00822       continue ;
00823     }
00824 
00825     // Process section headers if requested
00826     if (*token.Data()=='[') {
00827       TString hdr(token) ;
00828       const char* last = token.Data() + token.Length() -1 ;
00829       if (*last != ']') {
00830         hdr.Append(" ") ;
00831         hdr.Append(parser.readLine()) ;
00832       }
00833 //       parser.putBackToken(token) ;
00834 //       token = parser.readLine() ;
00835       if (section) {
00836         inSection = !sectionHdr.CompareTo(hdr) ;
00837       }
00838       continue ;
00839     }
00840 
00841     // If section is specified, ignore all data outside specified section
00842     if (!inSection) {
00843       parser.zapToEnd(kTRUE) ;
00844       continue ;
00845     }
00846 
00847     // Conditional statement evaluation
00848     if (!token.CompareTo("if")) {
00849       
00850       // Extract conditional expressions and check validity
00851       TString expr = parser.readLine() ;
00852       RooFormula form(expr,expr,*this) ;
00853       if (!form.ok()) return kTRUE ;
00854       
00855       // Evaluate expression
00856       Bool_t status = form.eval()?kTRUE:kFALSE ;
00857       if (lastLineWasElse) {
00858         anyCondTrue[condStackLevel] |= status ;
00859         lastLineWasElse=kFALSE ;
00860       } else {
00861         condStackLevel++ ;
00862         anyCondTrue[condStackLevel] = status ;
00863       }
00864       condStack[condStackLevel] = status ;
00865       
00866       if (verbose) cxcoutD(Eval) << "RooArgSet::readFromStream(" << GetName() 
00867                                  << "): conditional expression " << expr << " = " 
00868                                  << (condStack[condStackLevel]?"true":"false") << endl ;
00869       continue ; // go to next line
00870     }
00871     
00872     if (!token.CompareTo("else")) {
00873       // Must have seen an if statement before
00874       if (condStackLevel==0) {
00875         coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): unmatched 'else'" << endl ;
00876       }
00877       
00878       if (parser.atEOL()) {
00879         // simple else: process if nothing else was true
00880         condStack[condStackLevel] = !anyCondTrue[condStackLevel] ; 
00881         parser.zapToEnd(kFALSE) ;
00882         continue ;
00883       } else {
00884         // if anything follows it should be 'if'
00885         token = parser.readToken() ;
00886         if (token.CompareTo("if")) {
00887           coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): syntax error: 'else " << token << "'" << endl ;
00888           return kTRUE ;
00889         } else {
00890           if (anyCondTrue[condStackLevel]) {
00891             // No need for further checking, true conditional already processed
00892             condStack[condStackLevel] = kFALSE ;
00893             parser.zapToEnd(kFALSE) ;
00894             continue ;
00895           } else {
00896             // Process as normal 'if' no true conditional was encountered 
00897             reprocessToken = kTRUE ;
00898             lastLineWasElse=kTRUE ;
00899             continue ;
00900           }
00901         }
00902       } 
00903     }
00904     
00905     if (!token.CompareTo("endif")) {
00906       // Must have seen an if statement before
00907       if (condStackLevel==0) {
00908         coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): unmatched 'endif'" << endl ;
00909         return kTRUE ;
00910       }
00911       
00912       // Decrease stack by one
00913       condStackLevel-- ;
00914       continue ;
00915     } 
00916     
00917     // If current conditional is true
00918     if (condStack[condStackLevel]) {
00919       
00920       // Process echo statements
00921       if (!token.CompareTo("echo")) {
00922         TString message = parser.readLine() ;
00923         coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): >> " << message << endl ;
00924         continue ;
00925       } 
00926       
00927       // Process abort statements
00928       if (!token.CompareTo("abort")) {
00929         TString message = parser.readLine() ;
00930         coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): USER ABORT" << endl ;
00931         return kTRUE ;
00932       } 
00933       
00934       // Interpret the rest as <arg> = <value_expr> 
00935       RooAbsArg *arg ;
00936 
00937       if ((arg = find(token)) && !arg->getAttribute("Dynamic")) {
00938         if (parser.expectToken("=",kTRUE)) {
00939           parser.zapToEnd(kTRUE) ;
00940           retVal=kTRUE ;
00941           coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() 
00942                                 << "): missing '=' sign: " << arg << endl ;
00943           continue ;
00944         }
00945         Bool_t argRet = arg->readFromStream(is,kFALSE,verbose) ;        
00946         if (!argRet && flagReadAtt) arg->setAttribute(flagReadAtt,kTRUE) ;
00947         retVal |= argRet ;
00948       } else {
00949         if (verbose) {
00950           coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): argument " 
00951                                 << token << " not in list, ignored" << endl ;
00952         }
00953         parser.zapToEnd(kTRUE) ;
00954       }
00955     } else {
00956       parser.readLine() ;
00957     }
00958   }
00959   
00960   // Did we fully unwind the conditional stack?
00961   if (condStackLevel!=0) {
00962     coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): missing 'endif'" << endl ;
00963     return kTRUE ;
00964   }
00965   
00966   return retVal ;
00967 }
00968 
00969 
00970 Bool_t RooArgSet::isInRange(const char* rangeSpec) 
00971 {
00972   char buf[1024] ;
00973   strlcpy(buf,rangeSpec,1024) ;
00974   char* token = strtok(buf,",") ;
00975   
00976   TIterator* iter = createIterator() ;
00977 
00978   while(token) {
00979 
00980     Bool_t accept=kTRUE ;
00981     iter->Reset() ;
00982     RooAbsArg* arg ;
00983     while((arg=(RooAbsArg*)iter->Next())) {
00984       RooAbsRealLValue* lvarg = dynamic_cast<RooAbsRealLValue*>(arg) ;
00985       if (lvarg) {
00986         if (!lvarg->inRange(token)) {
00987           accept=kFALSE ;
00988           break ;
00989         }
00990       }
00991       // WVE MUST HANDLE RooAbsCategoryLValue ranges as well
00992     }
00993     if (accept) {
00994       delete iter ;
00995       return kTRUE ;
00996     }
00997 
00998     token = strtok(0,",") ;
00999   }
01000 
01001   delete iter ;
01002   return kFALSE ;
01003 }
01004 
01005 
01006 

Generated on Tue Jul 5 15:06:04 2011 for ROOT_528-00b_version by  doxygen 1.5.1