Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RooCompositeDataStore.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 RooCompositeDataStore.cxx
19 \class RooCompositeDataStore
20 \ingroup Roofitcore
21 
22 RooCompositeDataStore combines several disjunct datasets into one. This is useful for simultaneous PDFs
23 that do not depend on the same observable such as a PDF depending on `x` combined with another one depending
24 on `y`.
25 The composite storage will store two different datasets, `{x}` and `{y}`, but they can be passed as a single
26 dataset to RooFit operations. A category tag will define which dataset has to be passed to which likelihood.
27 
28 When iterated from start to finish, datasets will be traversed in the order of the category index.
29 **/
30 
31 #include "RooFit.h"
32 #include "RooMsgService.h"
33 #include "RooCompositeDataStore.h"
34 
35 #include "Riostream.h"
36 #include "TTree.h"
37 #include "TChain.h"
38 #include "TDirectory.h"
39 #include "TROOT.h"
40 #include "RooFormulaVar.h"
41 #include "RooRealVar.h"
42 #include "RooTrace.h"
43 #include "RooCategory.h"
44 #include <iomanip>
45 using namespace std ;
46 
47 ClassImp(RooCompositeDataStore);
48 ;
49 
50 
51 ////////////////////////////////////////////////////////////////////////////////
52 
53 RooCompositeDataStore::RooCompositeDataStore() : _indexCat(0), _curStore(0), _curIndex(0), _ownComps(kFALSE)
54 {
55  TRACE_CREATE
56 }
57 
58 
59 
60 ////////////////////////////////////////////////////////////////////////////////
61 /// Convert map by label to map by index for more efficient internal use
62 
63 RooCompositeDataStore::RooCompositeDataStore(const char* name, const char* title, const RooArgSet& vars, RooCategory& indexCat,map<std::string,RooAbsDataStore*> inputData) :
64  RooAbsDataStore(name,title,RooArgSet(vars,indexCat)), _indexCat(&indexCat), _curStore(0), _curIndex(0), _ownComps(kFALSE)
65 {
66  for (map<string,RooAbsDataStore*>::iterator iter=inputData.begin() ; iter!=inputData.end() ; ++iter) {
67  _dataMap[indexCat.lookupType(iter->first.c_str())->getVal()] = iter->second ;
68  }
69  TRACE_CREATE
70 }
71 
72 
73 
74 
75 ////////////////////////////////////////////////////////////////////////////////
76 /// Convert map by label to map by index for more efficient internal use
77 
78 RooCompositeDataStore::RooCompositeDataStore(const RooCompositeDataStore& other, const char* newname) :
79  RooAbsDataStore(other,newname), _indexCat(other._indexCat), _curStore(other._curStore), _curIndex(other._curIndex), _ownComps(kTRUE)
80 {
81  for (map<Int_t,RooAbsDataStore*>::const_iterator iter=other._dataMap.begin() ; iter!=other._dataMap.end() ; ++iter) {
82  RooAbsDataStore* clonedata = iter->second->clone() ;
83  _dataMap[iter->first] = clonedata ;
84  }
85  TRACE_CREATE
86 }
87 
88 
89 ////////////////////////////////////////////////////////////////////////////////
90 /// Update index category pointer, if it is contained in input argument vars
91 
92 RooCompositeDataStore::RooCompositeDataStore(const RooCompositeDataStore& other, const RooArgSet& vars, const char* newname) :
93  RooAbsDataStore(other,vars,newname), _indexCat(other._indexCat), _curStore(other._curStore), _curIndex(other._curIndex), _ownComps(kTRUE)
94 {
95  RooCategory* newIdx = (RooCategory*) vars.find(other._indexCat->GetName()) ;
96  if (newIdx) {
97  _indexCat = newIdx ;
98  }
99 
100  // Convert map by label to map by index for more efficient internal use
101  for (map<Int_t,RooAbsDataStore*>::const_iterator iter=other._dataMap.begin() ; iter!=other._dataMap.end() ; ++iter) {
102  RooAbsDataStore* clonedata = iter->second->clone(vars) ;
103  _dataMap[iter->first] = clonedata ;
104  }
105  TRACE_CREATE
106 }
107 
108 
109 
110 
111 ////////////////////////////////////////////////////////////////////////////////
112 /// Destructor
113 
114 RooCompositeDataStore::~RooCompositeDataStore()
115 {
116  if (_ownComps) {
117  map<int,RooAbsDataStore*>::const_iterator iter ;
118  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
119  delete iter->second ;
120  }
121  }
122  TRACE_DESTROY
123 }
124 
125 
126 ////////////////////////////////////////////////////////////////////////////////
127 /// Return true if currently loaded coordinate is considered valid within
128 /// the current range definitions of all observables
129 
130 Bool_t RooCompositeDataStore::valid() const
131 {
132  return kTRUE ;
133 }
134 
135 
136 
137 
138 ////////////////////////////////////////////////////////////////////////////////
139 /// Forward recalculate request to all subsets
140 
141 void RooCompositeDataStore::recalculateCache(const RooArgSet* proj, Int_t firstEvent, Int_t lastEvent, Int_t stepSize, Bool_t skipZeroWeights)
142 {
143  map<int,RooAbsDataStore*>::const_iterator iter ;
144  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
145  iter->second->recalculateCache(proj,firstEvent,lastEvent,stepSize,skipZeroWeights) ;
146  }
147 }
148 
149 
150 ////////////////////////////////////////////////////////////////////////////////
151 
152 Bool_t RooCompositeDataStore::hasFilledCache() const
153 {
154  Bool_t ret(kFALSE) ;
155  map<int,RooAbsDataStore*>::const_iterator iter ;
156  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
157  ret |= iter->second->hasFilledCache() ;
158  }
159  return ret ;
160 }
161 
162 
163 ////////////////////////////////////////////////////////////////////////////////
164 
165 void RooCompositeDataStore::forceCacheUpdate()
166 {
167  map<int,RooAbsDataStore*>::const_iterator iter ;
168  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
169  iter->second->forceCacheUpdate() ;
170  }
171 }
172 
173 
174 
175 ////////////////////////////////////////////////////////////////////////////////
176 /// Forward fill request to appropriate subset
177 
178 Int_t RooCompositeDataStore::fill()
179 {
180  RooAbsDataStore* subset = _dataMap[_indexCat->getIndex()] ;
181  const_cast<RooArgSet*>((subset->get()))->assignValueOnly(_vars) ;
182  return subset->fill() ;
183 }
184 
185 
186 
187 ////////////////////////////////////////////////////////////////////////////////
188 /// Forward fill request to appropriate subset
189 
190 Double_t RooCompositeDataStore::sumEntries() const
191 {
192  Double_t sum(0) ;
193 
194  map<int,RooAbsDataStore*>::const_iterator iter ;
195  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
196  sum+= iter->second->sumEntries() ;
197  }
198  return sum ;
199 }
200 
201 
202 
203 ////////////////////////////////////////////////////////////////////////////////
204 /// Load the n-th data point (n='idx') in memory
205 /// and return a pointer to the internal RooArgSet
206 /// holding its coordinates.
207 
208 const RooArgSet* RooCompositeDataStore::get(Int_t idx) const
209 {
210  Int_t offset(0) ;
211  map<int,RooAbsDataStore*>::const_iterator iter ;
212  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
213  if (idx>=(offset+iter->second->numEntries())) {
214  offset += iter->second->numEntries() ;
215  continue ;
216  }
217  const_cast<RooCompositeDataStore*>(this)->_vars = (*iter->second->get(idx-offset)) ;
218 
219  _indexCat->setIndex(iter->first) ;
220  _curStore = iter->second ;
221  _curIndex = idx-offset ;
222 
223  return &_vars ;
224  }
225  return 0 ;
226 }
227 
228 
229 
230 ////////////////////////////////////////////////////////////////////////////////
231 
232 Double_t RooCompositeDataStore::weight() const
233 {
234  if (!_curStore) get(0) ;
235  // coverity[FORWARD_NULL]
236  return _curStore->weight(_curIndex) ;
237 }
238 
239 
240 
241 
242 
243 ////////////////////////////////////////////////////////////////////////////////
244 
245 Double_t RooCompositeDataStore::weight(Int_t idx) const
246 {
247  get(idx) ;
248  return weight() ;
249 }
250 
251 
252 
253 
254 ////////////////////////////////////////////////////////////////////////////////
255 
256 Double_t RooCompositeDataStore::weightError(RooAbsData::ErrorType etype) const
257 {
258  if (!_curStore) get(0) ;
259  // coverity[FORWARD_NULL]
260  return _curStore->weightError(etype) ;
261 }
262 
263 
264 
265 
266 ////////////////////////////////////////////////////////////////////////////////
267 
268 void RooCompositeDataStore::weightError(Double_t& lo, Double_t& hi, RooAbsData::ErrorType etype) const
269 {
270  if (!_curStore) get(0) ;
271  // coverity[FORWARD_NULL]
272  return _curStore->weightError(lo,hi,etype) ;
273 }
274 
275 
276 
277 
278 ////////////////////////////////////////////////////////////////////////////////
279 
280 Bool_t RooCompositeDataStore::isWeighted() const
281 {
282  map<int,RooAbsDataStore*>::const_iterator iter ;
283  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
284  if (iter->second->isWeighted()) return kTRUE ;
285  }
286  return kFALSE ; ;
287 }
288 
289 
290 ////////////////////////////////////////////////////////////////////////////////
291 
292 void RooCompositeDataStore::loadValues(const RooAbsDataStore*, const RooFormulaVar*, const char*, Int_t, Int_t)
293 {
294  throw(std::string("RooCompositeDataSore::loadValues() NOT IMPLEMENTED")) ;
295 }
296 
297 
298 
299 ////////////////////////////////////////////////////////////////////////////////
300 /// Change name of internal observable named 'from' into 'to'
301 
302 Bool_t RooCompositeDataStore::changeObservableName(const char* from, const char* to)
303 {
304 
305  // Find observable to be changed
306  RooAbsArg* var = _vars.find(from) ;
307 
308  // Check that we found it
309  if (!var) {
310  coutE(InputArguments) << "RooCompositeDataStore::changeObservableName(" << GetName() << " no observable " << from << " in this dataset" << endl ;
311  return kTRUE ;
312  }
313 
314  // Process name change
315  var->SetName(to) ;
316 
317  // Forward name change request to component datasets
318  Bool_t ret(kFALSE) ;
319  map<int,RooAbsDataStore*>::const_iterator iter ;
320  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
321  ret |= iter->second->changeObservableName(from,to) ;
322  }
323 
324  return ret ;
325 }
326 
327 
328 
329 ////////////////////////////////////////////////////////////////////////////////
330 /// WVE ownership issue here!! Caller (a RooAbsData) should take ownership of all
331 /// arguments, but only does for the first one here...
332 
333 RooAbsArg* RooCompositeDataStore::addColumn(RooAbsArg& newVar, Bool_t adjustRange)
334 {
335  RooAbsArg* ret(0) ;
336  map<int,RooAbsDataStore*>::const_iterator iter ;
337  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
338  ret = iter->second->addColumn(newVar,adjustRange) ;
339  }
340  if (ret) {
341  _vars.add(*ret) ;
342  }
343  return ret ;
344 }
345 
346 
347 
348 ////////////////////////////////////////////////////////////////////////////////
349 /// WVE ownership issue here!! Caller (a RooAbsData) should take ownership of all
350 /// arguments, but only does for the first one here...
351 
352 RooArgSet* RooCompositeDataStore::addColumns(const RooArgList& varList)
353 {
354  RooArgSet* ret(0) ;
355  map<int,RooAbsDataStore*>::const_iterator iter ;
356  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
357  ret = iter->second->addColumns(varList) ;
358  }
359  if (ret) {
360  _vars.add(*ret) ;
361  }
362  return ret ;
363 }
364 
365 
366 
367 
368 ////////////////////////////////////////////////////////////////////////////////
369 
370 RooAbsDataStore* RooCompositeDataStore::merge(const RooArgSet& /*allVars*/, list<RooAbsDataStore*> /*dstoreList*/)
371 {
372  throw string("RooCompositeDataStore::merge() is not implemented yet") ;
373 }
374 
375 
376 
377 
378 
379 ////////////////////////////////////////////////////////////////////////////////
380 
381 void RooCompositeDataStore::append(RooAbsDataStore& other)
382 {
383  Int_t nevt = other.numEntries() ;
384  for (int i=0 ; i<nevt ; i++) {
385  _vars = *other.get(i) ;
386  fill() ;
387  }
388 }
389 
390 
391 
392 ////////////////////////////////////////////////////////////////////////////////
393 
394 Int_t RooCompositeDataStore::numEntries() const
395 {
396  Int_t n(0) ;
397  map<int,RooAbsDataStore*>::const_iterator iter ;
398  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
399  n += iter->second->numEntries() ;
400  }
401  return n ;
402 }
403 
404 
405 
406 
407 ////////////////////////////////////////////////////////////////////////////////
408 
409 void RooCompositeDataStore::reset()
410 {
411  map<int,RooAbsDataStore*>::const_iterator iter ;
412  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
413  iter->second->reset() ;
414  }
415 }
416 
417 
418 
419 ////////////////////////////////////////////////////////////////////////////////
420 
421 void RooCompositeDataStore::cacheArgs(const RooAbsArg* owner, RooArgSet& newVarSet, const RooArgSet* nset, Bool_t skipZeroWeights)
422 {
423  map<int,RooAbsDataStore*>::const_iterator iter ;
424  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
425  iter->second->cacheArgs(owner,newVarSet,nset,skipZeroWeights) ;
426  }
427 }
428 
429 
430 
431 ////////////////////////////////////////////////////////////////////////////////
432 
433 void RooCompositeDataStore::setArgStatus(const RooArgSet& set, Bool_t active)
434 {
435  map<int,RooAbsDataStore*>::const_iterator iter ;
436  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
437  RooArgSet* subset = (RooArgSet*) set.selectCommon(*iter->second->get()) ;
438  iter->second->setArgStatus(*subset,active) ;
439  delete subset ;
440  }
441  return ;
442 }
443 
444 
445 
446 ////////////////////////////////////////////////////////////////////////////////
447 /// Initialize cache of dataset: attach variables of cache ArgSet
448 /// to the corresponding TTree branches
449 
450 void RooCompositeDataStore::attachCache(const RooAbsArg* newOwner, const RooArgSet& inCachedVars)
451 {
452  map<int,RooAbsDataStore*>::const_iterator iter ;
453  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
454  iter->second->attachCache(newOwner,inCachedVars) ;
455  }
456  return ;
457 }
458 
459 
460 
461 ////////////////////////////////////////////////////////////////////////////////
462 
463 void RooCompositeDataStore::resetCache()
464 {
465  map<int,RooAbsDataStore*>::const_iterator iter ;
466  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
467  iter->second->resetCache() ;
468  }
469  return ;
470 }
471 
472 
473 
474 ////////////////////////////////////////////////////////////////////////////////
475 
476 void RooCompositeDataStore::attachBuffers(const RooArgSet& extObs)
477 {
478  map<int,RooAbsDataStore*>::const_iterator iter ;
479  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
480  iter->second->attachBuffers(extObs);
481  }
482  return ;
483 }
484 
485 
486 
487 ////////////////////////////////////////////////////////////////////////////////
488 
489 void RooCompositeDataStore::resetBuffers()
490 {
491  map<int,RooAbsDataStore*>::const_iterator iter ;
492  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
493  iter->second->resetBuffers();
494  }
495  return ;
496 }
497 
498 
499 ////////////////////////////////////////////////////////////////////////////////
500 
501 void RooCompositeDataStore::dump()
502 {
503  cout << "RooCompositeDataStore::dump()" << endl ;
504  map<int,RooAbsDataStore*>::const_iterator iter ;
505  for (iter = _dataMap.begin() ; iter!=_dataMap.end() ; ++iter) {
506  cout << "state number " << iter->first << " has store " << iter->second->IsA()->GetName() << " with variables " << *iter->second->get() ;
507  if (iter->second->isWeighted()) cout << " and is weighted " ;
508  cout << endl ;
509  }
510 }
511 
512