Logo ROOT  
Reference Guide
RooVectorDataStore.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 RooVectorDataStore.cxx
19\class RooVectorDataStore
20\ingroup Roofitcore
21
22RooVectorDataStore uses std::vectors to store data columns. Each of these vectors
23is associated to an instance of a RooAbsReal, whose values it represents. Those
24RooAbsReal are the observables of the dataset.
25In addition to the observables, a data column can be bound to a different instance
26of a RooAbsReal (e.g., the column "x" can be bound to the observable "x" of a computation
27graph using attachBuffers()). In this case, a get() operation writes the value of
28the requested column into the bound real.
29
30As a faster alternative to loading values one-by-one, one can use the function getBatches(),
31which returns spans pointing directly to the data.
32**/
33
34#include "RooVectorDataStore.h"
35
36#include "RooFit.h"
37#include "RooMsgService.h"
38#include "RooTreeDataStore.h"
39#include "RooFormulaVar.h"
40#include "RooRealVar.h"
41#include "RooCategory.h"
42#include "RooHistError.h"
43#include "RooTrace.h"
44#include "RunContext.h"
45#include "RooHelpers.h"
46
47#include "Math/Util.h"
48#include "ROOT/StringUtils.hxx"
49#include "TList.h"
50#include "TBuffer.h"
51
52#include <iomanip>
53using namespace std;
54
57
58
59////////////////////////////////////////////////////////////////////////////////
60
62 _wgtVar(0),
63 _sumWeight(0),
64 _sumWeightCarry(0),
65 _extWgtArray(0),
66 _extWgtErrLoArray(0),
67 _extWgtErrHiArray(0),
68 _extSumW2Array(0),
69 _cache(0),
70 _cacheOwner(0),
71 _forcedUpdate(kFALSE)
72{
74}
75
76
77
78////////////////////////////////////////////////////////////////////////////////
79
81 RooAbsDataStore(name,title,varsNoWeight(vars,wgtVarName)),
82 _varsww(vars),
83 _wgtVar(weightVar(vars,wgtVarName)),
84 _sumWeight(0),
85 _sumWeightCarry(0),
86 _extWgtArray(0),
87 _extWgtErrLoArray(0),
88 _extWgtErrHiArray(0),
89 _extSumW2Array(0),
90 _cache(0),
91 _cacheOwner(0),
92 _forcedUpdate(kFALSE)
93{
94 for (auto arg : _varsww) {
95 arg->attachToVStore(*this) ;
96 }
97
100}
101
102
103
104////////////////////////////////////////////////////////////////////////////////
105
107{
108 for (auto realVec : _realStoreList) {
109 realVec->setNativeBuffer();
110 }
111
112 for (auto fullVec : _realfStoreList) {
113 fullVec->setNativeBuffer();
114 }
115
116 for (auto catVec : _catStoreList) {
117 catVec->setNativeBuffer();
118 }
119}
120
121
122
123
124////////////////////////////////////////////////////////////////////////////////
125/// Utility function for constructors
126/// Return RooArgSet that is copy of allVars minus variable matching wgtName if specified
127
128RooArgSet RooVectorDataStore::varsNoWeight(const RooArgSet& allVars, const char* wgtName)
129{
130 RooArgSet ret(allVars) ;
131 if(wgtName) {
132 RooAbsArg* wgt = allVars.find(wgtName) ;
133 if (wgt) {
134 ret.remove(*wgt,kTRUE,kTRUE) ;
135 }
136 }
137 return ret ;
138}
139
140
141
142////////////////////////////////////////////////////////////////////////////////
143/// Utility function for constructors
144/// Return pointer to weight variable if it is defined
145
146RooRealVar* RooVectorDataStore::weightVar(const RooArgSet& allVars, const char* wgtName)
147{
148 if(wgtName) {
149 RooRealVar* wgt = dynamic_cast<RooRealVar*>(allVars.find(wgtName)) ;
150 return wgt ;
151 }
152 return 0 ;
153}
154
155
156
157
158////////////////////////////////////////////////////////////////////////////////
159/// Regular copy ctor
160
162 RooAbsDataStore(other,newname),
163 _varsww(other._varsww),
164 _wgtVar(other._wgtVar),
165 _sumWeight(other._sumWeight),
166 _sumWeightCarry(other._sumWeightCarry),
167 _extWgtArray(other._extWgtArray),
168 _extWgtErrLoArray(other._extWgtErrLoArray),
169 _extWgtErrHiArray(other._extWgtErrHiArray),
170 _extSumW2Array(other._extSumW2Array),
171 _currentWeightIndex(other._currentWeightIndex),
172 _cache(0),
173 _cacheOwner(0),
174 _forcedUpdate(kFALSE)
175{
176 for (const auto realVec : other._realStoreList) {
177 _realStoreList.push_back(new RealVector(*realVec, (RooAbsReal*)_varsww.find(realVec->_nativeReal->GetName()))) ;
178 }
179
180 for (const auto realFullVec : other._realfStoreList) {
181 _realfStoreList.push_back(new RealFullVector(*realFullVec, (RooAbsReal*)_varsww.find(realFullVec->_nativeReal->GetName()))) ;
182 }
183
184 for (const auto catVec : other._catStoreList) {
185 _catStoreList.push_back(new CatVector(*catVec, (RooAbsCategory*)_varsww.find(catVec->_cat->GetName()))) ;
186 }
187
189
191}
192
193
194////////////////////////////////////////////////////////////////////////////////
195
196RooVectorDataStore::RooVectorDataStore(const RooTreeDataStore& other, const RooArgSet& vars, const char* newname) :
197 RooAbsDataStore(other,varsNoWeight(vars,other._wgtVar?other._wgtVar->GetName():0),newname),
198 _varsww(vars),
199 _wgtVar(weightVar(vars,other._wgtVar?other._wgtVar->GetName():0)),
200 _sumWeight(0),
201 _sumWeightCarry(0),
202 _extWgtArray(0),
203 _extWgtErrLoArray(0),
204 _extWgtErrHiArray(0),
205 _extSumW2Array(0),
206 _currentWeightIndex(0),
207 _cache(0),
208 _cacheOwner(0),
209 _forcedUpdate(kFALSE)
210{
211 for (const auto arg : _varsww) {
212 arg->attachToVStore(*this) ;
213 }
214
216
217 // now copy contents of tree storage here
218 reserve(other.numEntries());
219 for (Int_t i=0 ; i<other.numEntries() ; i++) {
220 other.get(i) ;
221 _varsww.assign(other._varsww) ;
222 fill() ;
223 }
225
226}
227
228
229////////////////////////////////////////////////////////////////////////////////
230/// Clone ctor, must connect internal storage to given new external set of vars
231
232RooVectorDataStore::RooVectorDataStore(const RooVectorDataStore& other, const RooArgSet& vars, const char* newname) :
233 RooAbsDataStore(other,varsNoWeight(vars,other._wgtVar?other._wgtVar->GetName():0),newname),
234 _varsww(vars),
235 _wgtVar(other._wgtVar?weightVar(vars,other._wgtVar->GetName()):0),
236 _sumWeight(other._sumWeight),
237 _sumWeightCarry(other._sumWeightCarry),
238 _extWgtArray(other._extWgtArray),
239 _extWgtErrLoArray(other._extWgtErrLoArray),
240 _extWgtErrHiArray(other._extWgtErrHiArray),
241 _extSumW2Array(other._extSumW2Array),
242 _currentWeightIndex(other._currentWeightIndex),
243 _cache(0),
244 _forcedUpdate(kFALSE)
245{
246 for (const auto realVec : other._realStoreList) {
247 auto real = static_cast<RooAbsReal*>(vars.find(realVec->bufArg()->GetName()));
248 if (real) {
249 // Clone vector
250 _realStoreList.push_back(new RealVector(*realVec, real)) ;
251 // Adjust buffer pointer
252 real->attachToVStore(*this) ;
253 }
254 }
255
256 vector<RealFullVector*>::const_iterator fiter = other._realfStoreList.begin() ;
257 for (; fiter!=other._realfStoreList.end() ; ++fiter) {
258 RooAbsReal* real = (RooAbsReal*) vars.find((*fiter)->bufArg()->GetName()) ;
259 if (real) {
260 // Clone vector
261 _realfStoreList.push_back(new RealFullVector(**fiter,real)) ;
262 // Adjust buffer pointer
263 real->attachToVStore(*this) ;
264 }
265 }
266
267 vector<CatVector*>::const_iterator citer = other._catStoreList.begin() ;
268 for (; citer!=other._catStoreList.end() ; ++citer) {
269 RooAbsCategory* cat = (RooAbsCategory*) vars.find((*citer)->bufArg()->GetName()) ;
270 if (cat) {
271 // Clone vector
272 _catStoreList.push_back(new CatVector(**citer,cat)) ;
273 // Adjust buffer pointer
274 cat->attachToVStore(*this) ;
275 }
276 }
277
279
281
282}
283
284
285
286
287
288////////////////////////////////////////////////////////////////////////////////
289
291 const RooArgSet& vars, const RooFormulaVar* cutVar, const char* cutRange,
292 std::size_t nStart, std::size_t nStop, Bool_t /*copyCache*/, const char* wgtVarName) :
293
294 RooAbsDataStore(name,title,varsNoWeight(vars,wgtVarName)),
295 _varsww(vars),
296 _wgtVar(weightVar(vars,wgtVarName)),
297 _sumWeight(0),
298 _sumWeightCarry(0),
299 _extWgtArray(0),
300 _extWgtErrLoArray(0),
301 _extWgtErrHiArray(0),
302 _extSumW2Array(0),
303 _cache(0),
304 _forcedUpdate(kFALSE)
305{
306 for (const auto arg : _varsww) {
307 arg->attachToVStore(*this) ;
308 }
309
311
312 // Deep clone cutVar and attach clone to this dataset
313 RooFormulaVar* cloneVar = 0;
314 if (cutVar) {
315 cloneVar = (RooFormulaVar*) cutVar->cloneTree() ;
316 cloneVar->attachDataStore(tds) ;
317 }
318
319 RooVectorDataStore* vds = dynamic_cast<RooVectorDataStore*>(&tds) ;
320 if (vds && vds->_cache) {
321 _cache = new RooVectorDataStore(*vds->_cache) ;
322 }
323
324 loadValues(&tds,cloneVar,cutRange,nStart,nStop);
325
326 delete cloneVar ;
328}
329
330
331
332
333
334
335////////////////////////////////////////////////////////////////////////////////
336/// Destructor
337
339{
340 for (auto elm : _realStoreList) {
341 delete elm;
342 }
343
344 for (auto elm : _realfStoreList) {
345 delete elm;
346 }
347
348 for (auto elm : _catStoreList) {
349 delete elm;
350 }
351
352 delete _cache ;
354}
355
356
357////////////////////////////////////////////////////////////////////////////////
358/// Interface function to TTree::Fill
359
361{
362 for (auto realVec : _realStoreList) {
363 realVec->fill() ;
364 }
365
366 for (auto fullVec : _realfStoreList) {
367 fullVec->fill() ;
368 }
369
370 for (auto catVec : _catStoreList) {
371 catVec->fill() ;
372 }
373 // use Kahan's algorithm to sum up weights to avoid loss of precision
375 Double_t t = _sumWeight + y;
376 _sumWeightCarry = (t - _sumWeight) - y;
377 _sumWeight = t;
378
379 return 0 ;
380}
381
382
383
384////////////////////////////////////////////////////////////////////////////////
385/// Load the n-th data point (n='index') into the variables of this dataset,
386/// and return a pointer to the RooArgSet that holds them.
388{
389 if (index < 0 || static_cast<std::size_t>(index) >= size()) return 0;
390
391 for (const auto realV : _realStoreList) {
392 realV->load(index);
393 }
394
395 for (const auto fullRealP : _realfStoreList) {
396 fullRealP->get(index);
397 }
398
399 for (const auto catP : _catStoreList) {
400 catP->load(index);
401 }
402
403 if (_doDirtyProp) {
404 // Raise all dirty flags
405 for (auto var : _vars) {
406 var->setValueDirty(); // This triggers recalculation of all clients
407 }
408 }
409
410 // Update current weight cache
411 _currentWeightIndex = index;
412
413 if (_cache) {
414 _cache->get(index) ;
415 }
416
417 return &_vars;
418}
419
420
421////////////////////////////////////////////////////////////////////////////////
422/// Load the n-th data point (n='index') into the variables of this dataset,
423/// and return a pointer to the RooArgSet that holds them.
425{
426 if (index < 0 || static_cast<std::size_t>(index) >= size()) return 0;
427
428 for (const auto realV : _realStoreList) {
429 realV->loadToNative(index) ;
430 }
431
432 for (const auto fullRealP : _realfStoreList) {
433 fullRealP->loadToNative(index);
434 }
435
436 for (const auto catP : _catStoreList) {
437 catP->loadToNative(index);
438 }
439
440 if (_doDirtyProp) {
441 // Raise all dirty flags
442 for (auto var : _vars) {
443 var->setValueDirty() ; // This triggers recalculation of all clients
444 }
445 }
446
447 // Update current weight cache
448 _currentWeightIndex = index;
449
450 if (_cache) {
451 _cache->getNative(index) ;
452 }
453
454 return &_vars;
455}
456
457
458////////////////////////////////////////////////////////////////////////////////
459/// Return the error of the current weight.
460/// @param[in] etype Switch between simple Poisson or sum-of-weights statistics
461
463{
464 if (_extWgtArray) {
465
466 // We have a weight array, use that info
467
468 // Return symmetric error on current bin calculated either from Poisson statistics or from SumOfWeights
469 Double_t lo = 0, hi = 0 ;
470 weightError(lo,hi,etype) ;
471 return (lo+hi)/2 ;
472
473 } else if (_wgtVar) {
474
475 // We have a a weight variable, use that info
476 if (_wgtVar->hasAsymError()) {
477 return ( _wgtVar->getAsymErrorHi() - _wgtVar->getAsymErrorLo() ) / 2 ;
478 } else if (_wgtVar->hasError(kFALSE)) {
479 return _wgtVar->getError();
480 } else {
481 return 0 ;
482 }
483
484 } else {
485
486 // We have no weights
487 return 0 ;
488
489 }
490}
491
492
493
494////////////////////////////////////////////////////////////////////////////////
495
497{
498 if (_extWgtArray) {
499 double wgt;
500
501 // We have a weight array, use that info
502 switch (etype) {
503
504 case RooAbsData::Auto:
505 throw string(Form("RooDataHist::weightError(%s) error type Auto not allowed here",GetName())) ;
506 break ;
507
509 throw string(Form("RooDataHist::weightError(%s) error type Expected not allowed here",GetName())) ;
510 break ;
511
513 // Weight may be preset or precalculated
517 return ;
518 }
519
520 // Otherwise Calculate poisson errors
521 wgt = weight();
522 Double_t ym,yp ;
524 lo = wgt-ym;
525 hi = yp-wgt;
526 return ;
527
530 hi = lo;
531 return ;
532
533 case RooAbsData::None:
534 lo = 0 ;
535 hi = 0 ;
536 return ;
537 }
538
539 } else if (_wgtVar) {
540
541 // We have a a weight variable, use that info
542 if (_wgtVar->hasAsymError()) {
544 lo = _wgtVar->getAsymErrorLo() ;
545 } else {
546 hi = _wgtVar->getError() ;
547 lo = _wgtVar->getError() ;
548 }
549
550 } else {
551
552 // We are unweighted
553 lo=0 ;
554 hi=0 ;
555
556 }
557}
558
559
560
561////////////////////////////////////////////////////////////////////////////////
562///
563
564void RooVectorDataStore::loadValues(const RooAbsDataStore *ads, const RooFormulaVar* select, const char* rangeName, std::size_t nStart, std::size_t nStop)
565{
566 // Load values from dataset 't' into this data collection, optionally
567 // selecting events using 'select' RooFormulaVar
568 //
569
570 // Redirect formula servers to source data row
571 std::unique_ptr<RooFormulaVar> selectClone;
572 if (select) {
573 selectClone.reset( static_cast<RooFormulaVar*>(select->cloneTree()) );
574 selectClone->recursiveRedirectServers(*ads->get()) ;
575 selectClone->setOperMode(RooAbsArg::ADirty,kTRUE) ;
576 }
577
578 // Force DS internal initialization
579 ads->get(0) ;
580
581 // Loop over events in source tree
582 const auto numEntr = static_cast<std::size_t>(ads->numEntries());
583 const std::size_t nevent = nStop < numEntr ? nStop : numEntr;
584
585 auto TDS = dynamic_cast<const RooTreeDataStore*>(ads);
586 auto VDS = dynamic_cast<const RooVectorDataStore*>(ads);
587
588 // Check if weight is being renamed - if so set flag to enable special handling in copy loop
589 Bool_t weightRename(kFALSE) ;
590 Bool_t newWeightVar = _wgtVar ? _wgtVar->getAttribute("NewWeight") : kFALSE ;
591
592 if (_wgtVar && VDS && ((RooVectorDataStore*)(ads))->_wgtVar) {
593 if (string(_wgtVar->GetName())!=((RooVectorDataStore*)(ads))->_wgtVar->GetName() && !newWeightVar) {
594 weightRename=kTRUE ;
595 }
596 }
597 if (_wgtVar && TDS && ((RooTreeDataStore*)(ads))->_wgtVar) {
598 if (string(_wgtVar->GetName())!=((RooTreeDataStore*)(ads))->_wgtVar->GetName() && !newWeightVar) {
599 weightRename=kTRUE ;
600 }
601 }
602
603 std::vector<std::string> ranges;
604 if (rangeName) {
605 ranges = ROOT::Split(rangeName, ",");
606 }
607
608 reserve(numEntries() + (nevent - nStart));
609 for(auto i=nStart; i < nevent ; ++i) {
610 ads->get(i);
611
612 // Does this event pass the cuts?
613 if (selectClone && selectClone->getVal()==0) {
614 continue ;
615 }
616
617 if (TDS) {
618 _varsww.assignValueOnly(TDS->_varsww) ;
619 if (weightRename) {
620 _wgtVar->setVal(TDS->_wgtVar->getVal()) ;
621 }
622 } else if (VDS) {
623 _varsww.assignValueOnly(VDS->_varsww) ;
624 if (weightRename) {
625 _wgtVar->setVal(VDS->_wgtVar->getVal()) ;
626 }
627 } else {
628 _varsww.assignValueOnly(*ads->get()) ;
629 }
630
631 // Check that all copied values are valid and in range
632 bool allValid = true;
633 for (const auto arg : _varsww) {
634 allValid &= arg->isValid();
635 if (allValid && !ranges.empty()) {
636 // If we have one or multiple ranges to be selected, the value
637 // must be in one of them to be valid
638 allValid &= std::any_of(ranges.begin(), ranges.end(), [arg](const std::string& range){
639 return arg->inRange(range.c_str());});
640 }
641 if (!allValid)
642 break ;
643 }
644
645 if (!allValid) {
646 continue ;
647 }
648
649 fill() ;
650 }
651
652 SetTitle(ads->GetTitle());
653}
654
655
656
657
658
659////////////////////////////////////////////////////////////////////////////////
660
661Bool_t RooVectorDataStore::changeObservableName(const char* /*from*/, const char* /*to*/)
662{
663 return kFALSE ;
664}
665
666
667
668////////////////////////////////////////////////////////////////////////////////
669/// Add a new column to the data set which holds the pre-calculated values
670/// of 'newVar'. This operation is only meaningful if 'newVar' is a derived
671/// value.
672///
673/// The return value points to the added element holding 'newVar's value
674/// in the data collection. The element is always the corresponding fundamental
675/// type of 'newVar' (e.g. a RooRealVar if 'newVar' is a RooFormulaVar)
676///
677/// Note: This function is explicitly NOT intended as a speed optimization
678/// opportunity for the user. Components of complex PDFs that can be
679/// precalculated with the dataset are automatically identified as such
680/// and will be precalculated when fitting to a dataset
681///
682/// By forcibly precalculating functions with non-trivial Jacobians,
683/// or functions of multiple variables occurring in the data set,
684/// using addColumn(), you may alter the outcome of the fit.
685///
686/// Only in cases where such a modification of fit behaviour is intentional,
687/// this function should be used.
688
690{
691 // Create a fundamental object of the right type to hold newVar values
692 RooAbsArg* valHolder= newVar.createFundamental();
693 // Sanity check that the holder really is fundamental
694 if(!valHolder->isFundamental()) {
695 coutE(InputArguments) << GetName() << "::addColumn: holder argument is not fundamental: \""
696 << valHolder->GetName() << "\"" << endl;
697 return 0;
698 }
699
700 // Attention: need to do this now, as adding an empty column might give 0 as size
701 const std::size_t numEvt = size();
702
703 // Clone variable and attach to cloned tree
704 RooAbsArg* newVarClone = newVar.cloneTree() ;
706
707 // Attach value place holder to this tree
708 valHolder->attachToVStore(*this) ;
709 _vars.add(*valHolder) ;
710 _varsww.add(*valHolder) ;
711
712 // Fill values of placeholder
713 RealVector* rv(0) ;
714 CatVector* cv(0) ;
715 assert(numEvt != 0);
716 if (dynamic_cast<RooAbsReal*>(valHolder)) {
717 rv = addReal((RooAbsReal*)valHolder);
718 rv->resize(numEvt) ;
719 } else if (dynamic_cast<RooAbsCategory*>((RooAbsCategory*)valHolder)) {
720 cv = addCategory((RooAbsCategory*)valHolder) ;
721 cv->resize(numEvt) ;
722 }
723
724 for (std::size_t i=0; i < numEvt; i++) {
725 getNative(i) ;
726
727 newVarClone->syncCache(&_vars) ;
728 valHolder->copyCache(newVarClone) ;
729
730 if (rv) rv->write(i) ;
731 if (cv) cv->write(i) ;
732 }
733
734 delete newVarClone ;
735 return valHolder ;
736
737}
738
739
740
741////////////////////////////////////////////////////////////////////////////////
742/// Utility function to add multiple columns in one call
743/// See addColumn() for details
744
746{
747 checkInit() ;
748
749 TList cloneSetList ;
750 RooArgSet cloneSet ;
751 RooArgSet* holderSet = new RooArgSet ;
752
753 // Attention: need to do this now, as adding an empty column might give 0 as size
754 const std::size_t numEvt = size();
755
756 for (const auto var : varList) {
757 // Create a fundamental object of the right type to hold newVar values
758 RooAbsArg* valHolder= var->createFundamental();
759 holderSet->add(*valHolder) ;
760
761 // Sanity check that the holder really is fundamental
762 if(!valHolder->isFundamental()) {
763 coutE(InputArguments) << GetName() << "::addColumn: holder argument is not fundamental: \""
764 << valHolder->GetName() << "\"" << endl;
765 return 0;
766 }
767
768 // Clone variable and attach to cloned tree
769 RooArgSet* newVarCloneList = (RooArgSet*) RooArgSet(*var).snapshot() ;
770 if (!newVarCloneList) {
771 coutE(InputArguments) << "RooTreeDataStore::RooTreeData(" << GetName()
772 << ") Couldn't deep-clone variable " << var->GetName() << ", abort." << endl ;
773 return 0 ;
774 }
775 RooAbsArg* newVarClone = newVarCloneList->find(var->GetName()) ;
777 newVarClone->recursiveRedirectServers(*holderSet,kFALSE) ;
778
779 cloneSetList.Add(newVarCloneList) ;
780 cloneSet.add(*newVarClone) ;
781
782 // Attach value place holder to this tree
783 valHolder->attachToVStore(*this) ;
784 _vars.add(*valHolder) ;
785 }
786
787 // Dimension storage area for new vectors
788 for (const auto holder : *holderSet) {
789 if (dynamic_cast<RooAbsReal*>(holder)) {
790 addReal((RooAbsReal*)holder)->resize(numEvt) ;
791 } else {
792 addCategory((RooAbsCategory*)holder)->resize(numEvt);
793 }
794 }
795
796 // Fill values of of placeholder
797 for (std::size_t i=0; i < numEvt; i++) {
798 getNative(i) ;
799
800 for (unsigned int j=0; j < holderSet->size(); ++j) {
801 const auto holder = (*holderSet)[j];
802 const auto cloneArg = cloneSet[j];
803
804 cloneArg->syncCache(&_vars) ;
805
806 holder->copyCache(cloneArg) ;
807
808 if (dynamic_cast<RooAbsReal*>(holder)) {
809 addReal((RooAbsReal*)holder)->write(i) ;
810 } else {
811 addCategory((RooAbsCategory*)holder)->write(i) ;
812 }
813 }
814 }
815
816 cloneSetList.Delete() ;
817 return holderSet ;
818}
819
820
821
822
823////////////////////////////////////////////////////////////////////////////////
824/// Merge columns of supplied data set(s) with this data set. All
825/// data sets must have equal number of entries. In case of
826/// duplicate columns the column of the last dataset in the list
827/// prevails
828
829RooAbsDataStore* RooVectorDataStore::merge(const RooArgSet& allVars, list<RooAbsDataStore*> dstoreList)
830{
831 RooVectorDataStore* mergedStore = new RooVectorDataStore("merged","merged",allVars) ;
832
833 const auto nevt = dstoreList.front()->numEntries();
834 mergedStore->reserve(nevt);
835 for (int i=0 ; i<nevt ; i++) {
836
837 // Copy data from self
838 mergedStore->_vars.assign(*get(i)) ;
839
840 // Copy variables from merge sets
841 for (list<RooAbsDataStore*>::iterator iter = dstoreList.begin() ; iter!=dstoreList.end() ; ++iter) {
842 const RooArgSet* partSet = (*iter)->get(i) ;
843 mergedStore->_vars.assign(*partSet) ;
844 }
845
846 mergedStore->fill() ;
847 }
848 return mergedStore ;
849}
850
851
852
854{
855 for (auto elm : _realStoreList) {
856 elm->reserve(nEvts);
857 }
858
859 for (auto elm : _realfStoreList) {
860 elm->reserve(nEvts);
861 }
862
863 for (auto elm : _catStoreList) {
864 elm->reserve(nEvts);
865 }
866}
867
868////////////////////////////////////////////////////////////////////////////////
869
871{
872 Int_t nevt = other.numEntries() ;
873 reserve(nevt + numEntries());
874 for (int i=0 ; i<nevt ; i++) {
875 _vars.assign(*other.get(i)) ;
876 if (_wgtVar) {
877 _wgtVar->setVal(other.weight()) ;
878 }
879
880 fill() ;
881 }
882}
883
884
885
886////////////////////////////////////////////////////////////////////////////////
887
889{
891
892 for (auto elm : _realStoreList) {
893 elm->reset() ;
894 }
895
896 for (auto elm : _realfStoreList) {
897 elm->reset() ;
898 }
899
900 for (auto elm : _catStoreList) {
901 elm->reset() ;
902 }
903
904}
905
906////////////////////////////////////////////////////////////////////////////////
907/// Cache given RooAbsArgs: The tree is
908/// given direct write access of the args internal cache
909/// the args values is pre-calculated for all data points
910/// in this data collection. Upon a get() call, the
911/// internal cache of 'newVar' will be loaded with the
912/// precalculated value and it's dirty flag will be cleared.
913
914void RooVectorDataStore::cacheArgs(const RooAbsArg* owner, RooArgSet& newVarSet, const RooArgSet* nset, Bool_t skipZeroWeights)
915{
916 // Delete previous cache, if any
917 delete _cache ;
918 _cache = 0 ;
919
920 // Reorder cached elements. First constant nodes, then tracked nodes in order of dependence
921
922 // Step 1 - split in constant and tracked
923 RooArgSet newVarSetCopy(newVarSet);
924 RooArgSet orderedArgs;
925 vector<RooAbsArg*> trackArgs;
926 for (const auto arg : newVarSetCopy) {
927 if (arg->getAttribute("ConstantExpression") && !arg->getAttribute("NOCacheAndTrack")) {
928 orderedArgs.add(*arg) ;
929 } else {
930
931 // Explicitly check that arg depends on any of the observables, if this
932 // is not the case, skip it, as inclusion would result in repeated
933 // calculation of a function that has the same value for every event
934 // in the likelihood
935 if (arg->dependsOn(_vars) && !arg->getAttribute("NOCacheAndTrack")) {
936 trackArgs.push_back(arg) ;
937 } else {
938 newVarSet.remove(*arg) ;
939 }
940 }
941 }
942
943 // Step 2 - reorder tracked nodes
944 std::sort(trackArgs.begin(), trackArgs.end(), [](RooAbsArg* left, RooAbsArg* right){
945 //LM: exclude same comparison. This avoids an issue when using sort in MacOS versions
946 if (left == right) return false;
947 return right->dependsOn(*left);
948 });
949
950 // Step 3 - put back together
951 for (const auto trackedArg : trackArgs) {
952 orderedArgs.add(*trackedArg);
953 }
954
955 // WVE need to prune tracking entries _below_ constant nodes as the're not needed
956// cout << "Number of Cache-and-Tracked args are " << trackArgs.size() << endl ;
957// cout << "Compound ordered cache parameters = " << endl ;
958// orderedArgs.Print("v") ;
959
960 checkInit() ;
961
962 std::vector<RooArgSet*> vlist;
963 RooArgList cloneSet;
964
965 for (const auto var : orderedArgs) {
966
967 // Clone variable and attach to cloned tree
968 RooArgSet* newVarCloneList = (RooArgSet*) RooArgSet(*var).snapshot() ;
969 RooAbsArg* newVarClone = newVarCloneList->find(var->GetName()) ;
971
972 vlist.push_back(newVarCloneList) ;
973 cloneSet.add(*newVarClone) ;
974 }
975
976 _cacheOwner = (RooAbsArg*) owner ;
977 RooVectorDataStore* newCache = new RooVectorDataStore("cache","cache",orderedArgs) ;
978
979
981
982 std::vector<RooArgSet*> nsetList ;
983 std::vector<RooArgSet*> argObsList ;
984
985 // Now need to attach branch buffers of clones
986 for (const auto arg : cloneSet) {
987 arg->attachToVStore(*newCache) ;
988
989 RooArgSet* argObs = nset ? arg->getObservables(*nset) : arg->getVariables() ;
990 argObsList.push_back(argObs) ;
991
992 RooArgSet* normSet(0) ;
993 const char* catNset = arg->getStringAttribute("CATNormSet") ;
994 if (catNset) {
995// cout << "RooVectorDataStore::cacheArgs() cached node " << arg->GetName() << " has a normalization set specification CATNormSet = " << catNset << endl ;
996
997 RooArgSet anset = RooHelpers::selectFromArgSet(nset ? *nset : RooArgSet{}, catNset);
998 normSet = (RooArgSet*) anset.selectCommon(*argObs) ;
999
1000 }
1001 const char* catCset = arg->getStringAttribute("CATCondSet") ;
1002 if (catCset) {
1003// cout << "RooVectorDataStore::cacheArgs() cached node " << arg->GetName() << " has a conditional observable set specification CATCondSet = " << catCset << endl ;
1004
1005 RooArgSet acset = RooHelpers::selectFromArgSet(nset ? *nset : RooArgSet{}, catCset);
1006 argObs->remove(acset,kTRUE,kTRUE) ;
1007 normSet = argObs ;
1008 }
1009
1010 // now construct normalization set for component from cset/nset spec
1011// if (normSet) {
1012// cout << "RooVectorDaraStore::cacheArgs() component " << arg->GetName() << " has custom normalization set " << *normSet << endl ;
1013// }
1014 nsetList.push_back(normSet) ;
1015 }
1016
1017
1018 // Fill values of of placeholder
1019 const std::size_t numEvt = size();
1020 newCache->reserve(numEvt);
1021 for (std::size_t i=0; i < numEvt; i++) {
1022 getNative(i) ;
1023 if (weight()!=0 || !skipZeroWeights) {
1024 for (unsigned int j = 0; j < cloneSet.size(); ++j) {
1025 auto& cloneArg = cloneSet[j];
1026 auto argNSet = nsetList[j];
1027 // WVE need to intervene here for condobs from ProdPdf
1028 cloneArg.syncCache(argNSet ? argNSet : nset) ;
1029 }
1030 }
1031 newCache->fill() ;
1032 }
1033
1035
1036
1037 // Now need to attach branch buffers of original function objects
1038 for (const auto arg : orderedArgs) {
1039 arg->attachToVStore(*newCache) ;
1040
1041 // Activate change tracking mode, if requested
1042 if (!arg->getAttribute("ConstantExpression") && dynamic_cast<RooAbsReal*>(arg)) {
1043 RealVector* rv = newCache->addReal((RooAbsReal*)arg) ;
1044 RooArgSet* deps = arg->getParameters(_vars) ;
1045 rv->setDependents(*deps) ;
1046
1047 // WV lookup normalization set and associate with RealVector
1048 // find ordinal number of arg in original list
1049 Int_t idx = cloneSet.index(arg->GetName()) ;
1050
1051 coutI(Optimization) << "RooVectorDataStore::cacheArg() element " << arg->GetName() << " has change tracking enabled on parameters " << *deps << endl ;
1052 rv->setNset(nsetList[idx]) ;
1053 delete deps ;
1054 }
1055
1056 }
1057
1058
1059 for (auto set : vlist) {
1060 delete set;
1061 }
1062 for (auto set : argObsList) {
1063 delete set;
1064 }
1065
1066 _cache = newCache ;
1068}
1069
1070
1072{
1073 if (_cache) _forcedUpdate = kTRUE ;
1074}
1075
1076
1077
1078////////////////////////////////////////////////////////////////////////////////
1079
1080void RooVectorDataStore::recalculateCache( const RooArgSet *projectedArgs, Int_t firstEvent, Int_t lastEvent, Int_t stepSize, Bool_t skipZeroWeights)
1081{
1082 if (!_cache) return ;
1083
1084 std::vector<RooVectorDataStore::RealVector *> tv;
1085 tv.reserve(static_cast<std::size_t>(_cache->_realStoreList.size() * 0.7)); // Typically, 30..60% need to be recalculated
1086
1087 // Check which items need recalculation
1088 for (const auto realVec : _cache->_realStoreList) {
1089 if (_forcedUpdate || realVec->needRecalc()) {
1090 tv.push_back(realVec);
1091 realVec->_nativeReal->setOperMode(RooAbsArg::ADirty);
1092 realVec->_nativeReal->_operMode = RooAbsArg::Auto;
1093 }
1094 }
1096
1097 // If no recalculations are needed stop here
1098 if (tv.empty()) {
1099 return;
1100 }
1101
1102
1103 // Refill caches of elements that require recalculation
1104 RooArgSet* ownedNset = 0 ;
1105 RooArgSet* usedNset = 0 ;
1106 if (projectedArgs && projectedArgs->getSize()>0) {
1107 ownedNset = (RooArgSet*) _vars.snapshot(kFALSE) ;
1108 ownedNset->remove(*projectedArgs,kFALSE,kTRUE);
1109 usedNset = ownedNset ;
1110 } else {
1111 usedNset = &_vars ;
1112 }
1113
1114
1115 for (int i=firstEvent ; i<lastEvent ; i+=stepSize) {
1116 get(i) ;
1117 Bool_t zeroWeight = (weight()==0) ;
1118 if (!zeroWeight || !skipZeroWeights) {
1119 for (auto realVector : tv) {
1120 realVector->_nativeReal->_valueDirty = kTRUE;
1121 realVector->_nativeReal->getValV(realVector->_nset ? realVector->_nset : usedNset);
1122 realVector->write(i);
1123 }
1124 }
1125 }
1126
1127 for (auto realVector : tv) {
1128 realVector->_nativeReal->setOperMode(RooAbsArg::AClean);
1129 }
1130
1131 delete ownedNset ;
1132
1133}
1134
1135
1136////////////////////////////////////////////////////////////////////////////////
1137/// Initialize cache of dataset: attach variables of cache ArgSet
1138/// to the corresponding TTree branches
1139
1140void RooVectorDataStore::attachCache(const RooAbsArg* newOwner, const RooArgSet& cachedVarsIn)
1141{
1142 // Only applicable if a cache exists
1143 if (!_cache) return ;
1144
1145 // Clone ctor, must connect internal storage to given new external set of vars
1146 std::vector<RealVector*> cacheElements(_cache->realStoreList());
1147 cacheElements.insert(cacheElements.end(), _cache->_realfStoreList.begin(), _cache->_realfStoreList.end());
1148
1149 for (const auto elm : cacheElements) {
1150 auto real = static_cast<RooAbsReal*>(cachedVarsIn.find(elm->bufArg()->GetName()));
1151 if (real) {
1152 // Adjust buffer pointer
1153 real->attachToVStore(*_cache) ;
1154 }
1155 }
1156
1157 for (const auto catVec : _cache->_catStoreList) {
1158 auto cat = static_cast<RooAbsCategory*>(cachedVarsIn.find(catVec->bufArg()->GetName()));
1159 if (cat) {
1160 // Adjust buffer pointer
1161 cat->attachToVStore(*_cache) ;
1162 }
1163 }
1164
1165 _cacheOwner = (RooAbsArg*) newOwner ;
1166}
1167
1168
1169
1170
1171////////////////////////////////////////////////////////////////////////////////
1172
1174{
1175 delete _cache;
1176 _cache = nullptr;
1177 _cacheOwner = nullptr;
1178 return ;
1179}
1180
1181
1182
1183
1184
1185////////////////////////////////////////////////////////////////////////////////
1186/// Disabling of branches is (intentionally) not implemented in vector
1187/// data stores (as the doesn't result in a net saving of time)
1188
1189void RooVectorDataStore::setArgStatus(const RooArgSet& /*set*/, Bool_t /*active*/)
1190{
1191 return ;
1192}
1193
1194
1195
1196
1197////////////////////////////////////////////////////////////////////////////////
1198
1200{
1201 for (auto arg : _varsww) {
1202 RooAbsArg* extArg = extObs.find(arg->GetName()) ;
1203 if (extArg) {
1204 extArg->attachToVStore(*this) ;
1205 }
1206 }
1207}
1208
1209
1210
1211////////////////////////////////////////////////////////////////////////////////
1212
1214{
1215 for (auto arg : _varsww) {
1216 arg->attachToVStore(*this);
1217 }
1218}
1219
1220
1221
1222////////////////////////////////////////////////////////////////////////////////
1223
1225{
1226 cout << "RooVectorDataStor::dump()" << endl ;
1227
1228 cout << "_varsww = " << endl ; _varsww.Print("v") ;
1229 cout << "realVector list is" << endl ;
1230
1231 for (const auto elm : _realStoreList) {
1232 cout << "RealVector " << elm << " _nativeReal = " << elm->_nativeReal << " = " << elm->_nativeReal->GetName() << " bufptr = " << elm->_buf << endl ;
1233 cout << " values : " ;
1234 Int_t imax = elm->_vec.size()>10 ? 10 : elm->_vec.size() ;
1235 for (Int_t i=0 ; i<imax ; i++) {
1236 cout << elm->_vec[i] << " " ;
1237 }
1238 cout << endl ;
1239 }
1240
1241 for (const auto elm : _realfStoreList) {
1242 cout << "RealFullVector " << elm << " _nativeReal = " << elm->_nativeReal << " = " << elm->_nativeReal->GetName()
1243 << " bufptr = " << elm->_buf << " errbufptr = " << elm->_bufE << endl ;
1244
1245 cout << " values : " ;
1246 Int_t imax = elm->_vec.size()>10 ? 10 : elm->_vec.size() ;
1247 for (Int_t i=0 ; i<imax ; i++) {
1248 cout << elm->_vec[i] << " " ;
1249 }
1250 cout << endl ;
1251 if (elm->_vecE) {
1252 cout << " errors : " ;
1253 for (Int_t i=0 ; i<imax ; i++) {
1254 cout << (*elm->_vecE)[i] << " " ;
1255 }
1256 cout << endl ;
1257
1258 }
1259 }
1260}
1261
1262
1263////////////////////////////////////////////////////////////////////////////////
1264/// Stream an object of class RooVectorDataStore.
1265
1266void RooVectorDataStore::Streamer(TBuffer &R__b)
1267{
1268 if (R__b.IsReading()) {
1270
1271 for (auto elm : _realStoreList) {
1272 RooAbsArg* arg = _varsww.find(elm->_nativeReal->GetName()) ;
1273 arg->attachToVStore(*this) ;
1274 }
1275 for (auto elm : _realfStoreList) {
1276 RooAbsArg* arg = _varsww.find(elm->_nativeReal->GetName()) ;
1277 arg->attachToVStore(*this) ;
1278 }
1279 for (auto elm : _catStoreList) {
1280 RooAbsArg* arg = _varsww.find(elm->_cat->GetName()) ;
1281 arg->attachToVStore(*this) ;
1282 }
1283
1284 } else {
1286 }
1287}
1288
1289
1290////////////////////////////////////////////////////////////////////////////////
1291/// Stream an object of class RooVectorDataStore::RealFullVector.
1292
1293void RooVectorDataStore::RealFullVector::Streamer(TBuffer &R__b)
1294{
1295 if (R__b.IsReading()) {
1297
1298 // WVE - It seems that ROOT persistence turns null pointers to vectors into pointers to null-sized vectors
1299 // Intervene here to remove those null-sized vectors and replace with null pointers to not break
1300 // assumptions made elsewhere in this class
1301 if (_vecE && _vecE->empty()) { delete _vecE ; _vecE = 0 ; }
1302 if (_vecEL && _vecEL->empty()) { delete _vecEL ; _vecEL = 0 ; }
1303 if (_vecEH && _vecEH->empty()) { delete _vecEH ; _vecEH = 0 ; }
1304 } else {
1306 }
1307}
1308
1309
1310////////////////////////////////////////////////////////////////////////////////
1311/// Return batches of the data columns for the requested events.
1312/// \param[in] first First event in the batches.
1313/// \param[in] len Number of events in batches.
1314/// \return RunContext object whose member `spans` maps RooAbsReal pointers to spans with
1315/// the associated data.
1318
1319 auto emplace = [this,&evalData,first,len](const RealVector* realVec) {
1320 auto span = realVec->getRange(first, first + len);
1321 auto result = evalData.spans.emplace(realVec->_nativeReal, span);
1322 if (result.second == false || result.first->second.size() != len) {
1323 const auto size = result.second ? result.first->second.size() : 0;
1324 coutE(DataHandling) << "A batch of data for '" << realVec->_nativeReal->GetName()
1325 << "' was requested from " << first << " to " << first+len
1326 << ", but only the events [" << first << ", " << first + size << ") are available." << std::endl;
1327 }
1328 if (realVec->_real) {
1329 // If a buffer is attached, i.e. we are ready to load into a RooAbsReal outside of our dataset,
1330 // we can directly map our spans to this real.
1331 evalData.spans.emplace(realVec->_real, std::move(span));
1332 }
1333 };
1334
1335 for (const auto realVec : _realStoreList) {
1336 emplace(realVec);
1337 }
1338 for (const auto realVec : _realfStoreList) {
1339 emplace(realVec);
1340 }
1341
1342 if (_cache) {
1343 for (const auto realVec : _cache->_realStoreList) {
1344 emplace(realVec);
1345 }
1346 for (const auto realVec : _cache->_realfStoreList) {
1347 emplace(realVec);
1348 }
1349 }
1350
1351 return evalData;
1352}
1353
1354
1355////////////////////////////////////////////////////////////////////////////////
1356/// Return the weights of all events in the range [first, first+len).
1357/// If an array with weights is stored, a batch with these weights will be returned. If
1358/// no weights are stored, an empty batch is returned. Use weight() to check if there's
1359/// a constant weight.
1361{
1362 if (_extWgtArray) {
1364 }
1365
1366 if (_wgtVar) {
1367 auto findWeightVar = [this](const RealVector* realVec) {
1368 return realVec->_nativeReal == _wgtVar || realVec->_nativeReal->GetName() == _wgtVar->GetName();
1369 };
1370
1371 auto storageIter = std::find_if(_realStoreList.begin(), _realStoreList.end(), findWeightVar);
1372 if (storageIter != _realStoreList.end())
1373 return (*storageIter)->getRange(first, first + len);
1374
1375 auto fstorageIter = std::find_if(_realfStoreList.begin(), _realfStoreList.end(), findWeightVar);
1376 if (fstorageIter != _realfStoreList.end())
1377 return (*fstorageIter)->getRange(first, first + len);
1378
1379 throw std::logic_error("RooVectorDataStore::getWeightBatch(): Could not retrieve data for _wgtVar.");
1380 }
1381 return {};
1382}
1383
1384
1386
1387 // First try a match by name
1388 for (auto catVec : _catStoreList) {
1389 if (std::string(catVec->bufArg()->GetName())==cat->GetName()) {
1390 return catVec;
1391 }
1392 }
1393
1394 // If nothing found this will make an entry
1395 _catStoreList.push_back(new CatVector(cat)) ;
1396
1397 return _catStoreList.back() ;
1398}
1399
1400
1402
1403 // First try a match by name
1404 for (auto realVec : _realStoreList) {
1405 if (realVec->bufArg()->namePtr()==real->namePtr()) {
1406 return realVec;
1407 }
1408 }
1409
1410 // Then check if an entry already exists for a full real
1411 for (auto fullVec : _realfStoreList) {
1412 if (fullVec->bufArg()->namePtr()==real->namePtr()) {
1413 // Return full vector as RealVector base class here
1414 return fullVec;
1415 }
1416 }
1417
1418 // If nothing found this will make an entry
1419 _realStoreList.push_back(new RealVector(real)) ;
1420
1421 return _realStoreList.back() ;
1422}
1423
1424
1426
1427 // First try a match by name
1428 for (auto fullVec : _realfStoreList) {
1429 if (std::string(fullVec->bufArg()->GetName())==real->GetName()) {
1430 return kTRUE ;
1431 }
1432 }
1433 return kFALSE ;
1434}
1435
1436
1438
1439 // First try a match by name
1440 for (auto fullVec : _realfStoreList) {
1441 if (std::string(fullVec->bufArg()->GetName())==real->GetName()) {
1442 return fullVec->_vecE ? kTRUE : kFALSE ;
1443 }
1444 }
1445 return kFALSE ;
1446}
1447
1448
1450
1451 // First try a match by name
1452 for (auto fullVec : _realfStoreList) {
1453 if (std::string(fullVec->bufArg()->GetName())==real->GetName()) {
1454 return fullVec->_vecEL ? kTRUE : kFALSE ;
1455 }
1456 }
1457 return kFALSE ;
1458}
1459
1460
1462
1463 // First try a match by name
1464 for (auto fullVec : _realfStoreList) {
1465 if (std::string(fullVec->bufArg()->GetName())==real->GetName()) {
1466 return fullVec;
1467 }
1468 }
1469
1470 // Then check if an entry already exists for a bare real
1471 for (auto realVec : _realStoreList) {
1472 if (std::string(realVec->bufArg()->GetName())==real->GetName()) {
1473
1474 // Convert element to full and add to full list
1475 _realfStoreList.push_back(new RealFullVector(*realVec,real)) ;
1476
1477 // Delete bare element
1478 _realStoreList.erase(std::find(_realStoreList.begin(), _realStoreList.end(), realVec));
1479 delete realVec;
1480
1481 return _realfStoreList.back() ;
1482 }
1483 }
1484
1485 // If nothing found this will make an entry
1486 _realfStoreList.push_back(new RealFullVector(real)) ;
1487
1488 return _realfStoreList.back() ;
1489}
1490
1491
1492/// Trigger a recomputation of the cached weight sums. Meant for use by RooFit
1493/// dataset converter functions such as the NumPy converter functions
1494/// implemented as pythonizations.
1496 double const* arr = nullptr;
1497 if (_extWgtArray) {
1498 arr = _extWgtArray;
1499 }
1500 if (_wgtVar) {
1501 const std::string wgtName = _wgtVar->GetName();
1502 for(auto const* real : _realStoreList) {
1503 if(wgtName == real->_nativeReal->GetName())
1504 arr = real->_vec.data();
1505 }
1506 for(auto const* real : _realfStoreList) {
1507 if(wgtName == real->_nativeReal->GetName())
1508 arr = real->_vec.data();
1509 }
1510 }
1511 if(arr == nullptr) {
1512 _sumWeight = size();
1513 return;
1514 }
1515 auto result = ROOT::Math::KahanSum<double, 4>::Accumulate(arr, arr + size(), 0.0);
1516 _sumWeight = result.Sum();
1517 _sumWeightCarry = result.Carry();
1518}
1519
1520
1521/// Exports all arrays in this RooVectorDataStore into a simple datastructure
1522/// to be used by RooFit internal export functions.
1524 ArraysStruct out;
1525 out.size = size();
1526
1527 for(auto const* real : _realStoreList) {
1528 out.reals.emplace_back(real->_nativeReal->GetName(), real->_vec.data());
1529 }
1530 for(auto const* realf : _realfStoreList) {
1531 std::string name = realf->_nativeReal->GetName();
1532 out.reals.emplace_back(name, realf->_vec.data());
1533 if(realf->_vecE) out.reals.emplace_back(name + "Err", realf->_vecE->data());
1534 if(realf->_vecEL) out.reals.emplace_back(name + "ErrLo", realf->_vecEL->data());
1535 if(realf->_vecEH) out.reals.emplace_back(name + "ErrHi", realf->_vecEH->data());
1536 }
1537 for(auto const* cat : _catStoreList) {
1538 out.cats.emplace_back(cat->_cat->GetName(), cat->_vec.data());
1539 }
1540
1541 if(_extWgtArray) out.reals.emplace_back("weight", _extWgtArray);
1542 if(_extWgtErrLoArray) out.reals.emplace_back("wgtErrLo", _extWgtErrLoArray);
1543 if(_extWgtErrHiArray) out.reals.emplace_back("wgtErrHi", _extWgtErrHiArray);
1544 if(_extSumW2Array) out.reals.emplace_back("sumW2",_extSumW2Array);
1545
1546 return out;
1547}
void Class()
Definition: Class.C:29
#define coutI(a)
Definition: RooMsgService.h:30
#define coutE(a)
Definition: RooMsgService.h:33
#define TRACE_DESTROY
Definition: RooTrace.h:24
#define TRACE_CREATE
Definition: RooTrace.h:23
int Int_t
Definition: RtypesCore.h:45
const Bool_t kFALSE
Definition: RtypesCore.h:101
bool Bool_t
Definition: RtypesCore.h:63
double Double_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:364
char name[80]
Definition: TGX11.cxx:110
float type_of_call hi(const int &, const int &)
char * Form(const char *fmt,...)
static KahanSum< T, N > Accumulate(Iterator begin, Iterator end, T initialValue=T{})
Iterate over a range and return an instance of a KahanSum.
Definition: Util.h:211
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition: RooAbsArg.h:72
virtual RooAbsArg * cloneTree(const char *newname=0) const
Clone tree expression of objects.
Definition: RooAbsArg.cxx:2232
const TNamed * namePtr() const
De-duplicated pointer to this object's name.
Definition: RooAbsArg.h:544
void attachDataStore(const RooAbsDataStore &set)
Replace server nodes with names matching the dataset variable names with those data set variables,...
Definition: RooAbsArg.cxx:1583
virtual void copyCache(const RooAbsArg *source, Bool_t valueOnly=kFALSE, Bool_t setValDirty=kTRUE)=0
static void setDirtyInhibit(Bool_t flag)
Control global dirty inhibit mode.
Definition: RooAbsArg.cxx:264
virtual Bool_t isFundamental() const
Is this object a fundamental type that can be added to a dataset? Fundamental-type subclasses overrid...
Definition: RooAbsArg.h:243
virtual void syncCache(const RooArgSet *nset=0)=0
virtual void attachToVStore(RooVectorDataStore &vstore)=0
Bool_t getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
Definition: RooAbsArg.cxx:314
virtual RooAbsArg * createFundamental(const char *newname=0) const =0
Create a fundamental-type object that stores our type of value.
RooArgSet * getParameters(const RooAbsData *data, bool stripDisconnected=true) const
Create a list of leaf nodes in the arg tree starting with ourself as top node that don't match any of...
Definition: RooAbsArg.cxx:578
Bool_t recursiveRedirectServers(const RooAbsCollection &newServerList, Bool_t mustReplaceAll=kFALSE, Bool_t nameChange=kFALSE, Bool_t recurseInNewSet=kTRUE)
Recursively replace all servers with the new servers in newSet.
Definition: RooAbsArg.cxx:1159
RooAbsCategory is the base class for objects that represent a discrete value with a finite number of ...
virtual void attachToVStore(RooVectorDataStore &vstore)
Attach the category index and label to as branches to the given vector store.
Storage_t const & get() const
Const access to the underlying stl container.
RooAbsCollection & assignValueOnly(const RooAbsCollection &other, bool forceIfSizeOne=false)
Sets the value of any argument in our set that also appears in the other set.
Int_t getSize() const
Int_t index(const RooAbsArg *arg) const
Returns index of given arg, or -1 if arg is not in the collection.
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
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...
Storage_t::size_type size() const
virtual void Print(Option_t *options=0) const
This method must be overridden when a class wants to print itself.
bool selectCommon(const RooAbsCollection &refColl, RooAbsCollection &outColl) const
Create a subset of the current collection, consisting only of those elements that are contained as we...
virtual Bool_t remove(const RooAbsArg &var, Bool_t silent=kFALSE, Bool_t matchByNameOnly=kFALSE)
Remove the specified argument from our list.
RooAbsArg * find(const char *name) const
Find object with given name in list.
RooAbsDataStore is the abstract base class for data collection that use a TTree as internal storage m...
virtual const RooArgSet * get(Int_t index) const =0
virtual void checkInit() const
virtual Double_t weight() const =0
virtual Int_t numEntries() const =0
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:61
virtual void attachToVStore(RooVectorDataStore &vstore)
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:91
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgList.h:22
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:35
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition: RooArgSet.h:154
A RooFormulaVar is a generic implementation of a real-valued object, which takes a RooArgList of serv...
Definition: RooFormulaVar.h:30
Bool_t getPoissonInterval(Int_t n, Double_t &mu1, Double_t &mu2, Double_t nSigma=1) const
Return a confidence interval for the expected number of events given n observed (unweighted) events.
static const RooHistError & instance()
Return a reference to a singleton object that is created the first time this method is called.
RooRealVar represents a variable that can be changed from the outside.
Definition: RooRealVar.h:39
Double_t getAsymErrorLo() const
Definition: RooRealVar.h:64
Bool_t hasAsymError(Bool_t allowZero=kTRUE) const
Definition: RooRealVar.h:66
Double_t getAsymErrorHi() const
Definition: RooRealVar.h:65
Bool_t hasError(Bool_t allowZero=kTRUE) const
Definition: RooRealVar.h:61
Double_t getError() const
Definition: RooRealVar.h:60
virtual void setVal(Double_t value)
Set value of variable to 'value'.
Definition: RooRealVar.cxx:282
A simple container to hold a batch of data values.
Definition: RooSpan.h:34
RooTreeDataStore is a TTree-backed data storage.
virtual const RooArgSet * get(Int_t index) const
Load the n-th data point (n='index') in memory and return a pointer to the internal RooArgSet holding...
RooArgSet _varsww
Was object constructed with default ctor?
virtual Int_t numEntries() const
void setNset(RooArgSet *newNset)
void setDependents(const RooArgSet &deps)
RooVectorDataStore uses std::vectors to store data columns.
const Double_t * _extWgtErrHiArray
External weight array - low error.
Bool_t hasAsymError(RooAbsReal *real)
virtual void resetCache() override
virtual Int_t numEntries() const override
virtual void attachCache(const RooAbsArg *newOwner, const RooArgSet &cachedVars) override
Initialize cache of dataset: attach variables of cache ArgSet to the corresponding TTree branches.
std::vector< RealFullVector * > _realfStoreList
Bool_t isFullReal(RooAbsReal *real)
RooVectorDataStore * _cache
virtual void resetBuffers() override
RooRealVar * weightVar(const RooArgSet &allVars, const char *wgtName)
Utility function for constructors Return pointer to weight variable if it is defined.
std::vector< RealVector * > _realStoreList
CatVector * addCategory(RooAbsCategory *cat)
virtual RooArgSet * addColumns(const RooArgList &varList) override
Utility function to add multiple columns in one call See addColumn() for details.
void loadValues(const RooAbsDataStore *tds, const RooFormulaVar *select=0, const char *rangeName=0, std::size_t nStart=0, std::size_t nStop=std::numeric_limits< std::size_t >::max()) override
virtual const RooArgSet * get(Int_t index) const override
Load the n-th data point (n='index') into the variables of this dataset, and return a pointer to the ...
virtual Bool_t changeObservableName(const char *from, const char *to) override
RealFullVector * addRealFull(RooAbsReal *real)
const Double_t * _extWgtErrLoArray
External weight array.
virtual const RooArgSet * getNative(Int_t index) const
Load the n-th data point (n='index') into the variables of this dataset, and return a pointer to the ...
Double_t weight() const override
Return the weight of the last-retrieved data point.
virtual Int_t fill() override
Interface function to TTree::Fill.
virtual void append(RooAbsDataStore &other) override
std::vector< CatVector * > _catStoreList
Bool_t _forcedUpdate
Cache owner.
const Double_t * _extSumW2Array
External weight array - high error.
virtual void reset() override
RooBatchCompute::RunContext getBatches(std::size_t first, std::size_t len) const override
Return batches of the data columns for the requested events.
virtual void attachBuffers(const RooArgSet &extObs) override
ArraysStruct getArrays() const
Exports all arrays in this RooVectorDataStore into a simple datastructure to be used by RooFit intern...
virtual void setDirtyProp(Bool_t flag) override
RooAbsDataStore * merge(const RooArgSet &allvars, std::list< RooAbsDataStore * > dstoreList) override
Merge columns of supplied data set(s) with this data set.
virtual void cacheArgs(const RooAbsArg *owner, RooArgSet &varSet, const RooArgSet *nset=0, Bool_t skipZeroWeights=kTRUE) override
Cache given RooAbsArgs: The tree is given direct write access of the args internal cache the args val...
RealVector * addReal(RooAbsReal *real)
virtual Double_t weightError(RooAbsData::ErrorType etype=RooAbsData::Poisson) const override
Return the error of the current weight.
void forceCacheUpdate() override
void recomputeSumWeight()
Trigger a recomputation of the cached weight sums.
std::vector< RealVector * > & realStoreList()
virtual void recalculateCache(const RooArgSet *, Int_t firstEvent, Int_t lastEvent, Int_t stepSize, Bool_t skipZeroWeights) override
std::size_t size() const
Get size of stored dataset.
Bool_t hasError(RooAbsReal *real)
void reserve(Int_t nEvt)
virtual RooSpan< const double > getWeightBatch(std::size_t first, std::size_t len) const override
Return the weights of all events in the range [first, first+len).
virtual const RooArgSet * get() const
virtual ~RooVectorDataStore()
Destructor.
RooArgSet varsNoWeight(const RooArgSet &allVars, const char *wgtName)
Utility function for constructors Return RooArgSet that is copy of allVars minus variable matching wg...
const Double_t * _extWgtArray
std::size_t _currentWeightIndex
External sum of weights array.
virtual RooAbsArg * addColumn(RooAbsArg &var, Bool_t adjustRange=kTRUE) override
Add a new column to the data set which holds the pre-calculated values of 'newVar'.
virtual void setArgStatus(const RooArgSet &set, Bool_t active) override
Disabling of branches is (intentionally) not implemented in vector data stores (as the doesn't result...
RooAbsArg * _cacheOwner
Optimization cache.
Buffer base class used for serializing objects.
Definition: TBuffer.h:43
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
Bool_t IsReading() const
Definition: TBuffer.h:86
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:470
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Double_t y[n]
Definition: legend1.C:17
basic_string_view< char > string_view
VecExpr< UnaryOp< Sqrt< T >, VecExpr< A, T, D >, T >, T, D > sqrt(const VecExpr< A, T, D > &rhs)
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.
Definition: StringUtils.cxx:23
@ Optimization
Definition: RooGlobalFunc.h:61
@ DataHandling
Definition: RooGlobalFunc.h:62
@ InputArguments
Definition: RooGlobalFunc.h:61
RooArgSet selectFromArgSet(RooArgSet const &, std::string const &names)
Construct a RooArgSet of objects in a RooArgSet whose names match to those in the names string.
Definition: RooHelpers.cxx:269
Definition: first.py:1
This struct enables passing computation data around between elements of a computation graph.
Definition: RunContext.h:31
std::unordered_map< const RooAbsReal *, RooSpan< const double > > spans
Once an object has computed its value(s), the span pointing to the results is registered here.
Definition: RunContext.h:52
Output struct for the RooVectorDataStore::getArrays() helper function.
std::vector< ArrayInfo< double > > reals
std::vector< ArrayInfo< RooAbsCategory::value_type > > cats