Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RooExpensiveObjectCache.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 RooExpensiveObjectCache.cxx
19 \class RooExpensiveObjectCache
20 \ingroup Roofitcore
21 
22 RooExpensiveObjectCache is a singleton class that serves as repository
23 for objects that are expensive to calculate. Owners of such objects
24 can registers these here with associated parameter values for which
25 the object is valid, so that other instances can, at a later moment
26 retrieve these precalculated objects.
27 **/
28 
29 
30 #include "TClass.h"
31 #include "RooFit.h"
32 #include "RooAbsReal.h"
33 #include "RooAbsCategory.h"
34 #include "RooArgSet.h"
35 #include "RooMsgService.h"
36 #include <iostream>
37 using namespace std ;
38 
40 
41 ClassImp(RooExpensiveObjectCache);
42 ClassImp(RooExpensiveObjectCache::ExpensiveObject);
43 
44 
45 ////////////////////////////////////////////////////////////////////////////////
46 /// Constructor
47 
48 RooExpensiveObjectCache::RooExpensiveObjectCache() : _nextUID(0)
49 {
50 }
51 
52 
53 
54 ////////////////////////////////////////////////////////////////////////////////
55 /// Copy constructor
56 
57 RooExpensiveObjectCache::RooExpensiveObjectCache(const RooExpensiveObjectCache& other) :
58  TObject(other), _nextUID(0)
59 {
60 }
61 
62 
63 
64 ////////////////////////////////////////////////////////////////////////////////
65 /// Destructor.
66 
67 RooExpensiveObjectCache::~RooExpensiveObjectCache()
68 {
69  for (std::map<TString,ExpensiveObject*>::iterator iter = _map.begin() ; iter!=_map.end() ; ++iter) {
70  delete iter->second ;
71  }
72 }
73 
74 
75 
76 
77 ////////////////////////////////////////////////////////////////////////////////
78 /// Return reference to singleton instance
79 
80 RooExpensiveObjectCache& RooExpensiveObjectCache::instance()
81 {
82  static RooExpensiveObjectCache instance;
83  return instance;
84 }
85 
86 
87 ////////////////////////////////////////////////////////////////////////////////
88 /// Register object associated with given name and given associated parameters with given values in cache.
89 /// The cache will take _ownership_of_object_ and is indexed under the given name (which does not
90 /// need to be the name of cacheObject and with given set of dependent parameters with validity for the
91 /// current values of those parameters. It can be retrieved later by callin retrieveObject()
92 
93 Bool_t RooExpensiveObjectCache::registerObject(const char* ownerName, const char* objectName, TObject& cacheObject, const RooArgSet& params)
94 {
95  TIterator* parIter = params.createIterator() ;
96  Bool_t ret = registerObject(ownerName,objectName,cacheObject,parIter) ;
97  delete parIter ;
98 
99  return ret ;
100 }
101 
102 
103 
104 ////////////////////////////////////////////////////////////////////////////////
105 /// Register object associated with given name and given associated parameters with given values in cache.
106 /// The cache will take _ownership_of_object_ and is indexed under the given name (which does not
107 /// need to be the name of cacheObject and with given set of dependent parameters with validity for the
108 /// current values of those parameters. It can be retrieved later by callin retrieveObject()
109 
110 Bool_t RooExpensiveObjectCache::registerObject(const char* ownerName, const char* objectName, TObject& cacheObject, TIterator* parIter)
111 {
112  // Delete any previous object
113  ExpensiveObject* eo = _map[objectName] ;
114  Int_t olduid(-1) ;
115  if (eo) {
116  olduid = eo->uid() ;
117  delete eo ;
118  }
119  // Install new object
120  _map[objectName] = new ExpensiveObject(olduid!=-1?olduid:_nextUID++, ownerName,cacheObject,parIter) ;
121 
122  return kFALSE ;
123 }
124 
125 
126 
127 ////////////////////////////////////////////////////////////////////////////////
128 /// Retrieve object from cache that was registered under given name with given parameters, _if_
129 /// current parameter values match those that were stored in the registry for this object.
130 /// The return object is owned by the cache instance.
131 
132 const TObject* RooExpensiveObjectCache::retrieveObject(const char* name, TClass* tc, const RooArgSet& params)
133 {
134  ExpensiveObject* eo = _map[name] ;
135 
136  // If no cache element found, return 0 ;
137  if (!eo) {
138  return 0 ;
139  }
140 
141  // If parameters also match, return payload ;
142  if (eo->matches(tc,params)) {
143  return eo->payload() ;
144  }
145 
146  return 0 ;
147 }
148 
149 
150 
151 ////////////////////////////////////////////////////////////////////////////////
152 /// Retrieve payload object of cache element with given unique ID
153 
154 const TObject* RooExpensiveObjectCache::getObj(Int_t uid)
155 {
156  for (std::map<TString,ExpensiveObject*>::iterator iter = _map.begin() ; iter !=_map.end() ; ++iter) {
157  if (iter->second->uid() == uid) {
158  return iter->second->payload() ;
159  }
160  }
161  return 0 ;
162 }
163 
164 
165 
166 ////////////////////////////////////////////////////////////////////////////////
167 /// Clear cache element with given unique ID
168 /// Retrieve payload object of cache element with given unique ID
169 
170 Bool_t RooExpensiveObjectCache::clearObj(Int_t uid)
171 {
172  for (std::map<TString,ExpensiveObject*>::iterator iter = _map.begin() ; iter !=_map.end() ; ++iter) {
173  if (iter->second->uid() == uid) {
174  _map.erase(iter->first) ;
175  return kFALSE ;
176  }
177  }
178  return kTRUE ;
179 }
180 
181 
182 
183 ////////////////////////////////////////////////////////////////////////////////
184 /// Place new payload object in cache element with given unique ID. Cache
185 /// will take ownership of provided object!
186 
187 Bool_t RooExpensiveObjectCache::setObj(Int_t uid, TObject* obj)
188 {
189  for (std::map<TString,ExpensiveObject*>::iterator iter = _map.begin() ; iter !=_map.end() ; ++iter) {
190  if (iter->second->uid() == uid) {
191  iter->second->setPayload(obj) ;
192  return kFALSE ;
193  }
194  }
195  return kTRUE ;
196 }
197 
198 
199 
200 ////////////////////////////////////////////////////////////////////////////////
201 /// Clear all cache elements
202 
203 void RooExpensiveObjectCache::clearAll()
204 {
205  _map.clear() ;
206 }
207 
208 
209 
210 
211 
212 
213 ////////////////////////////////////////////////////////////////////////////////
214 /// Construct ExpensiveObject oject for inPayLoad and store reference values
215 /// for all RooAbsReal and RooAbsCategory parameters in params.
216 
217 RooExpensiveObjectCache::ExpensiveObject::ExpensiveObject(Int_t uidIn, const char* inOwnerName, TObject& inPayload, TIterator* parIter)
218 {
219  _uid = uidIn ;
220  _ownerName = inOwnerName;
221 
222  _payload = &inPayload ;
223 
224  RooAbsArg* arg ;
225  parIter->Reset() ;
226  while((arg=(RooAbsArg*)parIter->Next() )) {
227  RooAbsReal* real = dynamic_cast<RooAbsReal*>(arg) ;
228  if (real) {
229  _realRefParams[real->GetName()] = real->getVal() ;
230  } else {
231  RooAbsCategory* cat = dynamic_cast<RooAbsCategory*>(arg) ;
232  if (cat) {
233  _catRefParams[cat->GetName()] = cat->getIndex() ;
234  } else {
235  oocoutW(&inPayload,Caching) << "RooExpensiveObject::registerObject() WARNING: ignoring non-RooAbsReal/non-RooAbsCategory reference parameter " << arg->GetName() << endl ;
236  }
237  }
238  }
239 
240 }
241 
242 
243 
244 ////////////////////////////////////////////////////////////////////////////////
245 
246 RooExpensiveObjectCache::ExpensiveObject::ExpensiveObject(Int_t uidIn, const ExpensiveObject& other) :
247  _uid(uidIn),
248  _realRefParams(other._realRefParams),
249  _catRefParams(other._catRefParams),
250  _ownerName(other._ownerName)
251 {
252  _payload = other._payload->Clone() ;
253 }
254 
255 
256 
257 ////////////////////////////////////////////////////////////////////////////////
258 
259 RooExpensiveObjectCache::ExpensiveObject::~ExpensiveObject()
260 {
261  delete _payload ;
262 }
263 
264 
265 
266 
267 
268 ////////////////////////////////////////////////////////////////////////////////
269 /// Check object type ;
270 
271 Bool_t RooExpensiveObjectCache::ExpensiveObject::matches(TClass* tc, const RooArgSet& params)
272 {
273  if (_payload->IsA() != tc) {
274  return kFALSE;
275  }
276 
277  // Check parameters
278  TIterator* iter = params.createIterator() ;
279  RooAbsArg* arg ;
280  while((arg=(RooAbsArg*)iter->Next() )) {
281  RooAbsReal* real = dynamic_cast<RooAbsReal*>(arg) ;
282  if (real) {
283  if (fabs(real->getVal()-_realRefParams[real->GetName()])>1e-12) {
284  delete iter ;
285  return kFALSE ;
286  }
287  } else {
288  RooAbsCategory* cat = dynamic_cast<RooAbsCategory*>(arg) ;
289  if (cat) {
290  if (cat->getIndex() != _catRefParams[cat->GetName()]) {
291  delete iter ;
292  return kFALSE ;
293  }
294  }
295  }
296  }
297  delete iter ;
298 
299  return kTRUE ;
300 
301 }
302 
303 
304 
305 ////////////////////////////////////////////////////////////////////////////////
306 
307 void RooExpensiveObjectCache::print() const
308 {
309  map<TString,ExpensiveObject*>::const_iterator iter = _map.begin() ;
310 
311  while(iter!=_map.end()) {
312  cout << "uid = " << iter->second->uid() << " key=" << iter->first << " value=" ;
313  iter->second->print() ;
314  ++iter ;
315  }
316 }
317 
318 
319 
320 ////////////////////////////////////////////////////////////////////////////////
321 
322 void RooExpensiveObjectCache::ExpensiveObject::print() const
323 {
324  cout << _payload->IsA()->GetName() << "::" << _payload->GetName() ;
325  if (_realRefParams.size()>0 || _catRefParams.size()>0) {
326  cout << " parameters=( " ;
327  auto iter = _realRefParams.begin() ;
328  while(iter!=_realRefParams.end()) {
329  cout << iter->first << "=" << iter->second << " " ;
330  ++iter ;
331  }
332  auto iter2 = _catRefParams.begin() ;
333  while(iter2!=_catRefParams.end()) {
334  cout << iter2->first << "=" << iter2->second << " " ;
335  ++iter2 ;
336  }
337  cout << ")" ;
338  }
339  cout << endl ;
340 }
341 
342 
343 
344 
345 ////////////////////////////////////////////////////////////////////////////////
346 
347 void RooExpensiveObjectCache::importCacheObjects(RooExpensiveObjectCache& other, const char* ownerName, Bool_t verbose)
348 {
349  map<TString,ExpensiveObject*>::const_iterator iter = other._map.begin() ;
350  while(iter!=other._map.end()) {
351  if (string(ownerName)==iter->second->ownerName()) {
352  _map[iter->first.Data()] = new ExpensiveObject(_nextUID++, *iter->second) ;
353  if (verbose) {
354  oocoutI(iter->second->payload(),Caching) << "RooExpensiveObjectCache::importCache() importing cache object "
355  << iter->first << " associated with object " << iter->second->ownerName() << endl ;
356  }
357  }
358  ++iter ;
359  }
360 
361 }