RooExpensiveObjectCache.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  * @(#)root/roofitcore:$Id: RooExpensiveObjectCache.cxx 28259 2009-04-16 16:21:16Z wouter $
00005  * Authors:                                                                  *
00006  *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
00007  *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
00008  *                                                                           *
00009  * Copyright (c) 2000-2005, Regents of the University of California          *
00010  *                          and Stanford University. All rights reserved.    *
00011  *                                                                           *
00012  * Redistribution and use in source and binary forms,                        *
00013  * with or without modification, are permitted according to the terms        *
00014  * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
00015  *****************************************************************************/
00016 
00017 //////////////////////////////////////////////////////////////////////////////
00018 //
00019 // BEGIN_HTML
00020 // RooExpensiveObjectCache is a singleton class that serves as repository
00021 // for objects that are expensive to calculate. Owners of such objects
00022 // can registers these here with associated parameter values for which
00023 // the object is valid, so that other instances can, at a later moment
00024 // retrieve these precalculated objects
00025 
00026 // END_HTML
00027 //
00028 
00029 
00030 #include "TClass.h"
00031 #include "RooFit.h"
00032 #include "RooSentinel.h"
00033 #include "RooAbsReal.h"
00034 #include "RooAbsCategory.h"
00035 #include "RooArgSet.h"
00036 #include "RooMsgService.h"
00037 #include <iostream>
00038 #include <math.h>
00039 using namespace std ;
00040 
00041 #include "RooExpensiveObjectCache.h"
00042 
00043 ClassImp(RooExpensiveObjectCache)
00044 ClassImp(RooExpensiveObjectCache::ExpensiveObject)
00045   ;
00046 
00047 RooExpensiveObjectCache* RooExpensiveObjectCache::_instance = 0 ;
00048 
00049 
00050 //_____________________________________________________________________________
00051 RooExpensiveObjectCache::RooExpensiveObjectCache() : _nextUID(0)
00052 {
00053   // Constructor
00054 }
00055 
00056 
00057 
00058 //_____________________________________________________________________________
00059 RooExpensiveObjectCache::RooExpensiveObjectCache(const RooExpensiveObjectCache& other) :
00060   TObject(other), _nextUID(0)
00061 {
00062   // Copy constructor
00063 }
00064 
00065 
00066 
00067 //_____________________________________________________________________________
00068 RooExpensiveObjectCache::~RooExpensiveObjectCache() 
00069 {
00070   // Destructor. 
00071 
00072   for (std::map<TString,ExpensiveObject*>::iterator iter = _map.begin() ; iter!=_map.end() ; ++iter) {
00073     delete iter->second ;
00074   }
00075 
00076   if (_instance == this) {
00077     _instance = 0 ;
00078   }
00079 }
00080 
00081  
00082 
00083 
00084 //_____________________________________________________________________________
00085 RooExpensiveObjectCache& RooExpensiveObjectCache::instance() 
00086 {
00087   // Return reference to singleton instance 
00088 
00089   if (!_instance) {
00090     _instance = new RooExpensiveObjectCache() ;    
00091     RooSentinel::activate() ;    
00092   }
00093   return *_instance ;
00094 }
00095 
00096 
00097 
00098 
00099 //_____________________________________________________________________________
00100 void RooExpensiveObjectCache::cleanup() 
00101 {
00102   // Static function called by RooSentinel atexit() handler to cleanup at end of program
00103   delete _instance ;
00104 }
00105 
00106 
00107 
00108 
00109 //_____________________________________________________________________________
00110 Bool_t RooExpensiveObjectCache::registerObject(const char* ownerName, const char* objectName, TObject& cacheObject, const RooArgSet& params) 
00111 {
00112   // Register object associated with given name and given associated parameters with given values in cache.
00113   // The cache will take _ownership_of_object_ and is indexed under the given name (which does not
00114   // need to be the name of cacheObject and with given set of dependent parameters with validity for the
00115   // current values of those parameters. It can be retrieved later by callin retrieveObject()
00116 
00117   TIterator* parIter = params.createIterator() ;
00118   Bool_t ret = registerObject(ownerName,objectName,cacheObject,parIter) ;
00119   delete parIter ;
00120 
00121   return ret ;
00122 }
00123 
00124 
00125 
00126 //_____________________________________________________________________________
00127 Bool_t RooExpensiveObjectCache::registerObject(const char* ownerName, const char* objectName, TObject& cacheObject, TIterator* parIter) 
00128 {
00129   // Register object associated with given name and given associated parameters with given values in cache.
00130   // The cache will take _ownership_of_object_ and is indexed under the given name (which does not
00131   // need to be the name of cacheObject and with given set of dependent parameters with validity for the
00132   // current values of those parameters. It can be retrieved later by callin retrieveObject()
00133 
00134   // Delete any previous object
00135   ExpensiveObject* eo = _map[objectName] ;
00136   Int_t olduid(-1) ;
00137   if (eo) {
00138     olduid = eo->uid() ;
00139     delete eo ;
00140   }
00141   // Install new object
00142   _map[objectName] = new ExpensiveObject(olduid!=-1?olduid:_nextUID++, ownerName,cacheObject,parIter) ;
00143 
00144   return kFALSE ;
00145 }
00146 
00147 
00148 
00149 //_____________________________________________________________________________
00150 const TObject* RooExpensiveObjectCache::retrieveObject(const char* name, TClass* tc, const RooArgSet& params) 
00151 {
00152   // Retrieve object from cache that was registered under given name with given parameters, _if_
00153   // current parameter values match those that were stored in the registry for this object.
00154   // The return object is owned by the cache instance.
00155 
00156   ExpensiveObject* eo = _map[name] ;
00157 
00158   // If no cache element found, return 0 ;
00159   if (!eo) {
00160     return 0 ;
00161   }
00162   
00163   // If parameters also match, return payload ;
00164   if (eo->matches(tc,params)) {
00165     return eo->payload() ;
00166   }
00167 
00168   return 0 ;
00169 }
00170 
00171 
00172 
00173 //_____________________________________________________________________________
00174 const TObject* RooExpensiveObjectCache::getObj(Int_t uid) 
00175 {
00176   // Retrieve payload object of cache element with given unique ID  
00177   for (std::map<TString,ExpensiveObject*>::iterator iter = _map.begin() ; iter !=_map.end() ; iter++) {
00178     if (iter->second->uid() == uid) {
00179       return iter->second->payload() ;
00180     }
00181   }  
00182   return 0 ;
00183 }
00184 
00185 
00186 
00187 //_____________________________________________________________________________
00188 Bool_t RooExpensiveObjectCache::clearObj(Int_t uid) 
00189 {
00190   // Clear cache element with given unique ID
00191   // Retrieve payload object of cache element with given unique ID  
00192   for (std::map<TString,ExpensiveObject*>::iterator iter = _map.begin() ; iter !=_map.end() ; iter++) {
00193     if (iter->second->uid() == uid) {
00194       _map.erase(iter->first) ;
00195       return kFALSE ;
00196     }
00197   }  
00198   return kTRUE ;  
00199 }
00200 
00201 
00202 
00203 //_____________________________________________________________________________
00204 Bool_t RooExpensiveObjectCache::setObj(Int_t uid, TObject* obj) 
00205 {
00206   // Place new payload object in cache element with given unique ID. Cache
00207   // will take ownership of provided object!
00208 
00209   for (std::map<TString,ExpensiveObject*>::iterator iter = _map.begin() ; iter !=_map.end() ; iter++) {
00210     if (iter->second->uid() == uid) {
00211       iter->second->setPayload(obj) ;
00212       return kFALSE ;
00213     }
00214   }  
00215   return kTRUE ;
00216 }
00217 
00218 
00219 
00220 //_____________________________________________________________________________
00221 void RooExpensiveObjectCache::clearAll() 
00222 {
00223   // Clear all cache elements
00224   _map.clear() ;
00225 }
00226 
00227 
00228 
00229 
00230 
00231 
00232 //_____________________________________________________________________________
00233 RooExpensiveObjectCache::ExpensiveObject::ExpensiveObject(Int_t uidIn, const char* inOwnerName, TObject& inPayload, TIterator* parIter) 
00234 {
00235   // Construct ExpensiveObject oject for inPayLoad and store reference values
00236   // for all RooAbsReal and RooAbsCategory parameters in params.
00237 
00238   _uid = uidIn ;
00239   _ownerName = inOwnerName;
00240 
00241   _payload = &inPayload ;
00242 
00243   RooAbsArg* arg ;
00244   parIter->Reset() ;
00245   while((arg=(RooAbsArg*)parIter->Next() )) {
00246     RooAbsReal* real = dynamic_cast<RooAbsReal*>(arg) ;
00247     if (real) {
00248       _realRefParams[real->GetName()] = real->getVal() ;
00249     } else {
00250       RooAbsCategory* cat = dynamic_cast<RooAbsCategory*>(arg) ;
00251       if (cat) {
00252         _catRefParams[cat->GetName()] = cat->getIndex() ;
00253       } else {
00254         oocoutW(&inPayload,Caching) << "RooExpensiveObject::registerObject() WARNING: ignoring non-RooAbsReal/non-RooAbsCategory reference parameter " << arg->GetName() << endl ;
00255       }
00256     }
00257   }
00258   
00259 }
00260 
00261 
00262 
00263 //_____________________________________________________________________________
00264 RooExpensiveObjectCache::ExpensiveObject::ExpensiveObject(Int_t uidIn, const ExpensiveObject& other) : 
00265   _uid(uidIn),
00266   _realRefParams(other._realRefParams), 
00267   _catRefParams(other._catRefParams),
00268   _ownerName(other._ownerName)
00269 {
00270   _payload = other._payload->Clone() ;
00271 }
00272 
00273 
00274 
00275 //_____________________________________________________________________________
00276 RooExpensiveObjectCache::ExpensiveObject::~ExpensiveObject() 
00277 {
00278   delete _payload ;
00279 }
00280 
00281 
00282 
00283 
00284 
00285 //_____________________________________________________________________________
00286 Bool_t RooExpensiveObjectCache::ExpensiveObject::matches(TClass* tc, const RooArgSet& params) 
00287 {
00288   // Check object type ;
00289   if (_payload->IsA() != tc) {
00290     return kFALSE; 
00291   }
00292 
00293   // Check parameters 
00294   TIterator* iter = params.createIterator() ;
00295   RooAbsArg* arg ;
00296   while((arg=(RooAbsArg*)iter->Next() )) {
00297     RooAbsReal* real = dynamic_cast<RooAbsReal*>(arg) ;
00298     if (real) {
00299       if (fabs(real->getVal()-_realRefParams[real->GetName()])>1e-12) {
00300         delete iter ;
00301         return kFALSE ;
00302       } 
00303     } else {
00304       RooAbsCategory* cat = dynamic_cast<RooAbsCategory*>(arg) ;
00305       if (cat) {
00306         if (cat->getIndex() != _catRefParams[cat->GetName()]) {
00307           delete iter ;
00308           return kFALSE ;
00309         }
00310       }
00311     }
00312   }
00313   delete iter ;
00314 
00315   return kTRUE ;
00316 
00317 }
00318 
00319 
00320 
00321 //_____________________________________________________________________________
00322 void RooExpensiveObjectCache::print() const 
00323 {
00324   map<TString,ExpensiveObject*>::const_iterator iter = _map.begin() ;
00325 
00326   while(iter!=_map.end()) {
00327     cout << "uid = " << iter->second->uid() << " key=" << iter->first << " value=" ;
00328     iter->second->print() ;    
00329     ++iter ;
00330   }
00331 }
00332 
00333 
00334 
00335 //_____________________________________________________________________________
00336 void RooExpensiveObjectCache::ExpensiveObject::print() 
00337 {
00338   cout << _payload->IsA()->GetName() << "::" << _payload->GetName() ;
00339   if (_realRefParams.size()>0 || _catRefParams.size()>0) {
00340     cout << " parameters=( " ;
00341     map<TString,Double_t>::iterator iter = _realRefParams.begin() ;
00342     while(iter!=_realRefParams.end()) {
00343       cout << iter->first << "=" << iter->second << " " ;
00344       ++iter ;
00345     }  
00346     map<TString,Int_t>::iterator iter2 = _catRefParams.begin() ;
00347     while(iter2!=_catRefParams.end()) {
00348       cout << iter2->first << "=" << iter2->second << " " ;
00349       ++iter2 ;
00350     }
00351     cout << ")" ;
00352   }
00353   cout << endl ;
00354 }
00355 
00356 
00357 
00358 
00359 //_____________________________________________________________________________
00360 void RooExpensiveObjectCache::importCacheObjects(RooExpensiveObjectCache& other, const char* ownerName, Bool_t verbose) 
00361 {
00362   map<TString,ExpensiveObject*>::const_iterator iter = other._map.begin() ;
00363   while(iter!=other._map.end()) {
00364     if (string(ownerName)==iter->second->ownerName()) {      
00365       _map[iter->first.Data()] = new ExpensiveObject(_nextUID++, *iter->second) ;
00366       if (verbose) {
00367         oocoutI(iter->second->payload(),Caching) << "RooExpensiveObjectCache::importCache() importing cache object " 
00368                                                  << iter->first << " associated with object " << iter->second->ownerName() << endl ;
00369       }
00370     }
00371     ++iter ;
00372   }
00373   
00374 }

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