Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
22Combines several disjunct datasets into one. This is useful for simultaneous PDFs
23that do not depend on the same observable such as a PDF depending on `x` combined with another one depending
24on `y`.
25The composite storage will store two different datasets, `{x}` and `{y}`, but they can be passed as a single
26dataset to RooFit operations. A category tag will define which dataset has to be passed to which likelihood.
27
28When iterated from start to finish, datasets will be traversed in the order of the category index.
29**/
30
32
33#include "RooMsgService.h"
34#include "RooFormulaVar.h"
35#include "RooRealVar.h"
36#include "RooCategory.h"
37
38#include <algorithm>
39#include <iomanip>
40#include <iostream>
41
42using std::map, std::list, std::string;
43
44
45
46////////////////////////////////////////////////////////////////////////////////
47
51
52
53
54////////////////////////////////////////////////////////////////////////////////
55/// Convert map by label to map by index for more efficient internal use
56
60 RooAbsDataStore(name,title,RooArgSet(vars,indexCat)), _indexCat(&indexCat)
61{
62 for (const auto& iter : inputData) {
63 const RooAbsCategory::value_type idx = indexCat.lookupIndex(iter.first);
64 _dataMap[idx] = iter.second;
65 }
66}
67
68
69////////////////////////////////////////////////////////////////////////////////
70/// Convert map by label to map by index for more efficient internal use
71
73 RooAbsDataStore(other,newname), _indexCat(other._indexCat), _curStore(other._curStore), _curIndex(other._curIndex), _ownComps(true)
74{
75 for (const auto& item : other._dataMap) {
76 RooAbsDataStore* clonedata = item.second->clone() ;
77 _dataMap[item.first] = clonedata ;
78 }
79}
80
81
82////////////////////////////////////////////////////////////////////////////////
83/// Update index category pointer, if it is contained in input argument vars
84
86 RooAbsDataStore(other,vars,newname), _indexCat(other._indexCat), _curStore(other._curStore), _curIndex(other._curIndex), _ownComps(true)
87{
88 RooCategory* newIdx = static_cast<RooCategory*>(vars.find(other._indexCat->GetName())) ;
89 if (newIdx) {
91 }
92
93 // Convert map by label to map by index for more efficient internal use
94 for (const auto& item : other._dataMap) {
95 RooAbsDataStore* clonedata = item.second->clone(vars) ;
96 _dataMap[item.first] = clonedata ;
97 }
98}
99
100
101
102
103////////////////////////////////////////////////////////////////////////////////
104/// Destructor
105
107{
108 if (_ownComps) {
109 for (auto& item : _dataMap) {
110 delete item.second;
111 }
112 }
113}
114
115
116std::unique_ptr<RooAbsDataStore> RooCompositeDataStore::reduce(
117 RooStringView name, RooStringView title, const RooArgSet& vars, const RooFormulaVar* cutVar,
118 const char* cutRange, std::size_t nStart, std::size_t nStop)
119{
120 // for the components, we need the set of variables without the index category
122 if (RooAbsArg * indexCat = varsNoIndex.find(*_indexCat)) {
123 varsNoIndex.remove(*indexCat,true) ;
124 }
125
126 // create an empty RooCompositeDataStore
127 auto out = std::make_unique<RooCompositeDataStore>(name, title, varsNoIndex, *_indexCat, std::map<std::string,RooAbsDataStore*>{});
128
129 RooCategory* indexCatForCut = nullptr;
131 if (cutVar) {
132 // find _indexCat in the formula recursive servers, if present
134 cutVar->getObservables(&_vars, formulaObservables);
136 if (indexCatForCut) {
137 // save initial index to restore it later
138 initialIndex = indexCatForCut->getCurrentIndex();
139 }
140 }
141
142 // fill it with reduced versions of components
143 for (const auto& item : _dataMap) {
144 if (indexCatForCut) indexCatForCut->setIndex(item.first);
145 out->_dataMap[item.first] = item.second->reduce(name, title, varsNoIndex, cutVar, cutRange, nStart, nStop).release();
146 }
147 if (indexCatForCut) {
148 // restore initial index
149 indexCatForCut->setIndex(initialIndex);
150 }
151
152 // indiceate component ownership and return
153 out->_ownComps = true;
154 return out;
155}
156
157
158////////////////////////////////////////////////////////////////////////////////
159/// Forward fill request to appropriate subset
160
162{
164 const_cast<RooArgSet*>((subset->get()))->assignValueOnly(_vars) ;
165 return subset->fill() ;
166}
167
168
169
170////////////////////////////////////////////////////////////////////////////////
171/// Forward fill request to appropriate subset
172
174{
175 double sum(0) ;
176
177 for (auto const& item : _dataMap) {
178 sum+= item.second->sumEntries() ;
179 }
180 return sum ;
181}
182
183
184
185////////////////////////////////////////////////////////////////////////////////
186/// Load the n-th data point (n='idx') in memory
187/// and return a pointer to the internal RooArgSet
188/// holding its coordinates.
189
191{
192 Int_t offset(0) ;
193 for (auto const& item : _dataMap) {
194 if (idx>=(offset+item.second->numEntries())) {
195 offset += item.second->numEntries() ;
196 continue ;
197 }
198 _vars.assign(*item.second->get(idx-offset)) ;
199
200 _indexCat->setIndex(item.first) ;
201 _curStore = item.second ;
202 _curIndex = idx-offset ;
203
204 return &_vars ;
205 }
206 return nullptr ;
207}
208
209
210
211////////////////////////////////////////////////////////////////////////////////
212
214{
215 if (!_curStore) get(0) ;
216 // coverity[FORWARD_NULL]
217 return _curStore->weight(_curIndex) ;
218}
219
220
221////////////////////////////////////////////////////////////////////////////////
222
224{
225 if (!_curStore) get(0) ;
226 // coverity[FORWARD_NULL]
227 return _curStore->weightError(etype) ;
228}
229
230
231
232
233////////////////////////////////////////////////////////////////////////////////
234
235void RooCompositeDataStore::weightError(double& lo, double& hi, RooAbsData::ErrorType etype) const
236{
237 if (!_curStore) get(0) ;
238 // coverity[FORWARD_NULL]
239 return _curStore->weightError(lo,hi,etype) ;
240}
241
242
243
244
245////////////////////////////////////////////////////////////////////////////////
246
248{
249 for (auto const& item : _dataMap) {
250 if (item.second->isWeighted()) return true ;
251 }
252 return false ;
253}
254
255
256////////////////////////////////////////////////////////////////////////////////
257
258void RooCompositeDataStore::loadValues(const RooAbsDataStore*, const RooFormulaVar*, const char*, std::size_t, std::size_t)
259{
260 throw(std::runtime_error("RooCompositeDataSore::loadValues() NOT IMPLEMENTED")) ;
261}
262
263
264
265////////////////////////////////////////////////////////////////////////////////
266/// Change name of internal observable named 'from' into 'to'
267
268bool RooCompositeDataStore::changeObservableName(const char* from, const char* to)
269{
270
271 // Find observable to be changed
272 RooAbsArg* var = _vars.find(from) ;
273
274 // Check that we found it
275 if (!var) {
276 coutE(InputArguments) << "RooCompositeDataStore::changeObservableName(" << GetName() << " no observable " << from << " in this dataset" << std::endl ;
277 return true ;
278 }
279
280 // Process name change
281 var->SetName(to) ;
282
283 // Forward name change request to component datasets
284 bool ret(false) ;
285 for (auto const& item : _dataMap) {
286 ret |= item.second->changeObservableName(from,to) ;
287 }
288
289 return ret ;
290}
291
292
293
294////////////////////////////////////////////////////////////////////////////////
295/// WVE ownership issue here!! Caller (a RooAbsData) should take ownership of all
296/// arguments, but only does for the first one here...
297
299{
300 RooAbsArg* ret(nullptr) ;
301 for (auto const& item : _dataMap) {
302 ret = item.second->addColumn(newVar,adjustRange) ;
303 }
304 if (ret) {
305 _vars.add(*ret) ;
306 }
307 return ret ;
308}
309
310
311////////////////////////////////////////////////////////////////////////////////
312
314{
315 throw string("RooCompositeDataStore::merge() is not implemented yet") ;
316}
317
318
319
320
321
322////////////////////////////////////////////////////////////////////////////////
323
325{
326 Int_t nevt = other.numEntries() ;
327 for (int i=0 ; i<nevt ; i++) {
328 _vars.assign(*other.get(i)) ;
329 fill() ;
330 }
331}
332
333
334
335////////////////////////////////////////////////////////////////////////////////
336
338{
339 Int_t n(0) ;
340 for (auto const& item : _dataMap) {
341 n += item.second->numEntries() ;
342 }
343 return n ;
344}
345
346
347
348
349////////////////////////////////////////////////////////////////////////////////
350
352{
353 for (auto const& item : _dataMap) {
354 item.second->reset() ;
355 }
356}
357
358
359
360////////////////////////////////////////////////////////////////////////////////
361
363{
364 for (auto const& item : _dataMap) {
365 item.second->attachBuffers(extObs);
366 }
367 return ;
368}
369
370
371
372////////////////////////////////////////////////////////////////////////////////
373
375{
376 for (auto const& item : _dataMap) {
377 item.second->resetBuffers();
378 }
379 return ;
380}
381
382
383////////////////////////////////////////////////////////////////////////////////
384
386{
387 std::cout << "RooCompositeDataStore::dump()" << std::endl ;
388 for (auto const& item : _dataMap) {
389 std::cout << "state number " << item.first << " has store " << item.second->ClassName() << " with variables " << *item.second->get() ;
390 if (item.second->isWeighted()) std::cout << " and is weighted " ;
391 std::cout << std::endl ;
392 }
393}
394
395
396////////////////////////////////////////////////////////////////////////////////
397/// Get the weights of the events in the range [first, first+len).
398/// This implementation will fill a vector with every event retrieved one by one
399/// (even if the weight is constant). Then, it returns a span.
400std::span<const double> RooCompositeDataStore::getWeightBatch(std::size_t first, std::size_t len) const {
401 if (!_weightBuffer) {
402 _weightBuffer = std::make_unique<std::vector<double>>();
403 _weightBuffer->reserve(len);
404
405 for (std::size_t i = 0; i < static_cast<std::size_t>(numEntries()); ++i) {
406 _weightBuffer->push_back(weight(i));
407 }
408 }
409
410 return {_weightBuffer->data() + first, len};
411}
412
413////////////////////////////////////////////////////////////////////////////////
414/// Fill the internal per-column buffers for batch access by loading the
415/// composite rows one by one, like getWeightBatch() does for the weights.
416/// This also synthesizes a column for the index category, which is not
417/// stored in any of the component datasets.
419{
420 const auto n = static_cast<std::size_t>(numEntries());
421
422 if (!_realBatchBuffers.empty() || !_catBatchBuffers.empty()) {
423 // Refill from scratch if entries were added or removed since the last
424 // fill. Value mutations that keep the number of entries are not
425 // detected, like for the weight buffer above.
426 const std::size_t nFilled = !_realBatchBuffers.empty() ? _realBatchBuffers.begin()->second.size()
427 : _catBatchBuffers.begin()->second.size();
428 if (nFilled == n)
429 return;
430 _realBatchBuffers.clear();
431 _catBatchBuffers.clear();
432 }
433
434 std::vector<std::pair<RooAbsReal const *, std::vector<double> *>> realCols;
435 std::vector<std::pair<RooAbsCategory const *, std::vector<RooAbsCategory::value_type> *>> catCols;
436
437 for (RooAbsArg const *arg : _vars) {
438 if (auto cat = dynamic_cast<RooAbsCategory const *>(arg)) {
439 auto &buf = _catBatchBuffers[arg];
440 buf.reserve(n);
441 catCols.emplace_back(cat, &buf);
442 } else if (auto real = dynamic_cast<RooAbsReal const *>(arg)) {
443 auto &buf = _realBatchBuffers[arg];
444 buf.reserve(n);
445 realCols.emplace_back(real, &buf);
446 }
447 }
448
449 for (std::size_t i = 0; i < n; ++i) {
450 get(i);
451 for (auto &col : realCols)
452 col.second->push_back(col.first->getVal());
453 for (auto &col : catCols)
454 col.second->push_back(col.first->getCurrentIndex());
455 }
456}
457
458////////////////////////////////////////////////////////////////////////////////
459/// Get the batches of the real-valued columns in the range [first, first+len).
460/// The columns of the component datasets are lazily concatenated into
461/// internal buffers in composite row order.
463{
465
466 // Clamp against the actual number of entries, because the default
467 // arguments of RooAbsData::getBatches() ask for the maximum length.
468 first = std::min(first, static_cast<std::size_t>(numEntries()));
469 len = std::min(len, static_cast<std::size_t>(numEntries()) - first);
470
472 for (auto const &item : _realBatchBuffers) {
473 out.emplace(item.first, std::span<const double>{item.second.data() + first, len});
474 }
475 return out;
476}
477
478////////////////////////////////////////////////////////////////////////////////
479/// Get the batches of the category columns in the range [first, first+len),
480/// including the index category. See getBatches().
482{
484
485 // See getBatches() for the clamping rationale.
486 first = std::min(first, static_cast<std::size_t>(numEntries()));
487 len = std::min(len, static_cast<std::size_t>(numEntries()) - first);
488
490 for (auto const &item : _catBatchBuffers) {
491 out.emplace(item.first, std::span<const RooAbsCategory::value_type>{item.second.data() + first, len});
492 }
493 return out;
494}
#define coutE(a)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
char name[80]
Definition TGX11.cxx:142
#define hi
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:76
void SetName(const char *name) override
Set the name of the TNamed.
A space to attach TBranches.
value_type lookupIndex(const std::string &stateName) const
Find the index number corresponding to the state name.
RooAbsCollection & assignValueOnly(const RooAbsCollection &other, bool forceIfSizeOne=false)
Sets the value of any argument in our set that also appears in the other set.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
void assign(const RooAbsCollection &other) const
Sets the value, cache and constant attribute of any argument in our set that also appears in the othe...
RooAbsArg * find(const char *name) const
Find object with given name in list.
Abstract base class for a data collection.
virtual double weightError(RooAbsData::ErrorType etype=RooAbsData::Poisson) const =0
virtual double weight() const =0
std::map< RooFit::Detail::DataKey, std::span< const double > > RealSpans
Definition RooAbsData.h:131
std::map< RooFit::Detail::DataKey, std::span< const RooAbsCategory::value_type > > CategorySpans
Definition RooAbsData.h:132
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:63
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
Object to represent discrete states.
Definition RooCategory.h:28
bool setIndex(Int_t index, bool printError=true) override
Set value by specifying the index code of the desired state.
value_type getCurrentIndex() const final
Return current index.
Definition RooCategory.h:40
Combines several disjunct datasets into one.
RooAbsArg * addColumn(RooAbsArg &var, bool adjustRange=true) override
WVE ownership issue here!! Caller (a RooAbsData) should take ownership of all arguments,...
std::unique_ptr< std::vector< double > > _weightBuffer
! Buffer for weights in case a batch of values is requested.
Int_t _curIndex
! Index associated with current event
void loadValues(const RooAbsDataStore *tds, const RooFormulaVar *select=nullptr, const char *rangeName=nullptr, std::size_t nStart=0, std::size_t nStop=std::numeric_limits< std::size_t >::max()) override
Int_t numEntries() const override
std::span< const double > getWeightBatch(std::size_t first, std::size_t len) const override
Get the weights of the events in the range [first, first+len).
RooAbsDataStore * merge(const RooArgSet &allvars, std::list< RooAbsDataStore * > dstoreList) override
std::map< RooAbsArg const *, std::vector< double > > _realBatchBuffers
! Buffers for real-valued columns in case batches of values are requested.
bool changeObservableName(const char *from, const char *to) override
Change name of internal observable named 'from' into 'to'.
RooAbsData::CategorySpans getCategoryBatches(std::size_t first, std::size_t len) const override
Get the batches of the category columns in the range [first, first+len), including the index category...
~RooCompositeDataStore() override
Destructor.
RooAbsData::RealSpans getBatches(std::size_t first, std::size_t len) const override
Get the batches of the real-valued columns in the range [first, first+len).
bool isWeighted() const override
RooAbsDataStore * _curStore
! Datastore associated with current event
double weightError(RooAbsData::ErrorType etype=RooAbsData::Poisson) const override
double sumEntries() const override
Forward fill request to appropriate subset.
std::map< Int_t, RooAbsDataStore * > _dataMap
std::unique_ptr< RooAbsDataStore > reduce(RooStringView name, RooStringView title, const RooArgSet &vars, const RooFormulaVar *cutVar, const char *cutRange, std::size_t nStart, std::size_t nStop) override
Int_t fill() override
Forward fill request to appropriate subset.
void fillBatchBuffers() const
Fill the internal per-column buffers for batch access by loading the composite rows one by one,...
void attachBuffers(const RooArgSet &extObs) override
double weight() const override
void append(RooAbsDataStore &other) override
virtual const RooArgSet * get() const
std::map< RooAbsArg const *, std::vector< RooAbsCategory::value_type > > _catBatchBuffers
! Buffers for category columns in case batches of values are requested.
A RooFormulaVar is a generic implementation of a real-valued object, which takes a RooArgList of serv...
The RooStringView is a wrapper around a C-style string that can also be constructed from a std::strin...
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const Int_t n
Definition legend1.C:16
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2335