Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
22Uses `std::vector` 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 "RooMsgService.h"
37#include "RooTreeDataStore.h"
38#include "RooFormulaVar.h"
39#include "RooRealVar.h"
40#include "RooCategory.h"
41#include "RooHistError.h"
42#include "RooFitImplHelpers.h"
43
44#include "Math/Util.h"
45#include "ROOT/StringUtils.hxx"
46#include "TBuffer.h"
47
48#include <iomanip>
49using std::string, std::vector, std::list;
50
51
52
53////////////////////////////////////////////////////////////////////////////////
54
58
59
60
61////////////////////////////////////////////////////////////////////////////////
62
64 RooAbsDataStore(name,title,varsNoWeight(vars,wgtVarName)),
65 _varsww(vars),
66 _wgtVar(weightVar(vars,wgtVarName))
67{
68 for (auto arg : _varsww) {
69 arg->attachToVStore(*this) ;
70 }
71
73}
74
75
76
77////////////////////////////////////////////////////////////////////////////////
78
80{
81 for (auto realVec : _realStoreList) {
82 realVec->setNativeBuffer();
83 }
84
85 for (auto fullVec : _realfStoreList) {
86 fullVec->setNativeBuffer();
87 }
88
89 for (auto catVec : _catStoreList) {
90 catVec->setNativeBuffer();
91 }
92}
93
94
95
96
97////////////////////////////////////////////////////////////////////////////////
98/// Utility function for constructors
99/// Return RooArgSet that is copy of allVars minus variable matching wgtName if specified
100
102{
103 RooArgSet ret(allVars) ;
104 if(wgtName) {
105 RooAbsArg* wgt = allVars.find(wgtName) ;
106 if (wgt) {
107 ret.remove(*wgt,true,true) ;
108 }
109 }
110 return ret ;
111}
112
113
114
115////////////////////////////////////////////////////////////////////////////////
116/// Utility function for constructors
117/// Return pointer to weight variable if it is defined
118
120{
121 if(wgtName) {
122 RooRealVar* wgt = dynamic_cast<RooRealVar*>(allVars.find(wgtName)) ;
123 return wgt ;
124 }
125 return nullptr ;
126}
127
128
129
130
131////////////////////////////////////////////////////////////////////////////////
132/// Regular copy constructor.
133
136 _varsww(other._varsww),
137 _wgtVar(other._wgtVar),
138 _sumWeight(other._sumWeight),
139 _sumWeightCarry(other._sumWeightCarry),
140 _extWgtArray(other._extWgtArray),
141 _extWgtErrLoArray(other._extWgtErrLoArray),
142 _extWgtErrHiArray(other._extWgtErrHiArray),
143 _extSumW2Array(other._extSumW2Array),
144 _currentWeightIndex(other._currentWeightIndex)
145{
146 for (const auto realVec : other._realStoreList) {
147 _realStoreList.push_back(new RealVector(*realVec, static_cast<RooAbsReal*>(_varsww.find(realVec->_nativeReal->GetName())))) ;
148 }
149
150 for (const auto realFullVec : other._realfStoreList) {
151 _realfStoreList.push_back(new RealFullVector(*realFullVec, static_cast<RooAbsReal*>(_varsww.find(realFullVec->_nativeReal->GetName())))) ;
152 }
153
154 for (const auto catVec : other._catStoreList) {
155 _catStoreList.push_back(new CatVector(*catVec, static_cast<RooAbsCategory*>(_varsww.find(catVec->_cat->GetName())))) ;
156 }
157
159
160}
161
162
163////////////////////////////////////////////////////////////////////////////////
164
166 RooAbsDataStore(other,varsNoWeight(vars,other._wgtVar?other._wgtVar->GetName():nullptr),newname),
167 _varsww(vars),
168 _wgtVar(weightVar(vars,other._wgtVar?other._wgtVar->GetName():nullptr))
169{
170 for (const auto arg : _varsww) {
171 arg->attachToVStore(*this) ;
172 }
173
175
176 // now copy contents of tree storage here
177 reserve(other.numEntries());
178 for (Int_t i=0 ; i<other.numEntries() ; i++) {
179 other.get(i) ;
180 _varsww.assign(other._varsww) ;
181 fill() ;
182 }
183
184}
185
186
187////////////////////////////////////////////////////////////////////////////////
188/// Clone constructor, must connect internal storage to given new external set of variables.
189
191 RooAbsDataStore(other,varsNoWeight(vars,other._wgtVar?other._wgtVar->GetName():nullptr),newname),
192 _varsww(vars),
193 _wgtVar(other._wgtVar?weightVar(vars,other._wgtVar->GetName()):nullptr),
194 _sumWeight(other._sumWeight),
195 _sumWeightCarry(other._sumWeightCarry),
196 _extWgtArray(other._extWgtArray),
197 _extWgtErrLoArray(other._extWgtErrLoArray),
198 _extWgtErrHiArray(other._extWgtErrHiArray),
199 _extSumW2Array(other._extSumW2Array),
200 _currentWeightIndex(other._currentWeightIndex)
201{
202 for (const auto realVec : other._realStoreList) {
203 auto real = static_cast<RooAbsReal*>(vars.find(realVec->bufArg()->GetName()));
204 if (real) {
205 // Clone vector
206 _realStoreList.push_back(new RealVector(*realVec, real)) ;
207 // Adjust buffer pointer
208 real->attachToVStore(*this) ;
209 }
210 }
211
212 auto forwardIter = other._realfStoreList.begin() ;
213 for (; forwardIter!=other._realfStoreList.end() ; ++forwardIter) {
214 RooAbsReal* real = static_cast<RooAbsReal*>(vars.find((*forwardIter)->bufArg()->GetName())) ;
215 if (real) {
216 // Clone vector
218 // Adjust buffer pointer
219 real->attachToVStore(*this) ;
220 }
221 }
222
223 vector<CatVector*>::const_iterator citer = other._catStoreList.begin() ;
224 for (; citer!=other._catStoreList.end() ; ++citer) {
225 RooAbsCategory* cat = static_cast<RooAbsCategory*>(vars.find((*citer)->bufArg()->GetName())) ;
226 if (cat) {
227 // Clone vector
228 _catStoreList.push_back(new CatVector(**citer,cat)) ;
229 // Adjust buffer pointer
230 cat->attachToVStore(*this) ;
231 }
232 }
233
235
236}
237
238
239std::unique_ptr<RooAbsDataStore> RooVectorDataStore::reduce(RooStringView name, RooStringView title,
240 const RooArgSet& vars, const RooFormulaVar* cutVar, const char* cutRange,
241 std::size_t nStart, std::size_t nStop) {
242 RooArgSet tmp(vars) ;
243 if(_wgtVar && !tmp.contains(*_wgtVar)) {
244 tmp.add(*_wgtVar) ;
245 }
246 const char* wgtVarName = _wgtVar ? _wgtVar->GetName() : nullptr;
247 return std::make_unique<RooVectorDataStore>(name, title, *this, tmp, cutVar, cutRange, nStart, nStop, wgtVarName);
248}
249
250
251
252////////////////////////////////////////////////////////////////////////////////
253
255 const RooArgSet& vars, const RooFormulaVar* cutVar, const char* cutRange,
256 std::size_t nStart, std::size_t nStop, const char* wgtVarName) :
257
258 RooAbsDataStore(name,title,varsNoWeight(vars,wgtVarName)),
259 _varsww(vars),
260 _wgtVar(weightVar(vars,wgtVarName))
261{
262 for (const auto arg : _varsww) {
263 arg->attachToVStore(*this) ;
264 }
265
267
268 // Deep clone cutVar and attach clone to this dataset
269 std::unique_ptr<RooFormulaVar> cloneVar;
270 if (cutVar) {
271 cloneVar.reset(static_cast<RooFormulaVar*>(cutVar->cloneTree()));
272 cloneVar->attachDataStore(tds) ;
273 }
274
275 loadValues(&tds,cloneVar.get(),cutRange,nStart,nStop);
276
277}
278
279
280
281
282
283
284////////////////////////////////////////////////////////////////////////////////
285/// Destructor
286
288{
289 for (auto elm : _realStoreList) {
290 delete elm;
291 }
292
293 for (auto elm : _realfStoreList) {
294 delete elm;
295 }
296
297 for (auto elm : _catStoreList) {
298 delete elm;
299 }
300}
301
302
303////////////////////////////////////////////////////////////////////////////////
304/// Interface function to TTree::Fill
305
307{
308 for (auto realVec : _realStoreList) {
309 realVec->fill() ;
310 }
311
312 for (auto fullVec : _realfStoreList) {
313 fullVec->fill() ;
314 }
315
316 for (auto catVec : _catStoreList) {
317 catVec->fill() ;
318 }
319 // use Kahan's algorithm to sum up weights to avoid loss of precision
320 double y = (_wgtVar ? _wgtVar->getVal() : 1.) - _sumWeightCarry;
321 double t = _sumWeight + y;
322 _sumWeightCarry = (t - _sumWeight) - y;
323 _sumWeight = t;
324
325 return 0 ;
326}
327
328
329
330////////////////////////////////////////////////////////////////////////////////
331/// Load the n-th data point (n='index') into the variables of this dataset,
332/// and return a pointer to the RooArgSet that holds them.
334{
335 if (index < 0 || static_cast<std::size_t>(index) >= size()) return nullptr;
336
337 for (const auto realV : _realStoreList) {
338 realV->load(index);
339 }
340
341 for (const auto fullRealP : _realfStoreList) {
342 fullRealP->load(index);
343 }
344
345 for (const auto catP : _catStoreList) {
346 catP->load(index);
347 }
348
349 if (_doDirtyProp) {
350 // Raise all dirty flags
351 for (auto var : _vars) {
352 var->setValueDirty(); // This triggers recalculation of all clients
353 }
354 }
355
356 // Update current weight cache
358
359 return &_vars;
360}
361
362
363////////////////////////////////////////////////////////////////////////////////
364/// Return the error of the current weight.
365/// @param[in] etype Switch between simple Poisson or sum-of-weights statistics
366
368{
369 if (_extWgtArray) {
370
371 // We have a weight array, use that info
372
373 // Return symmetric error on current bin calculated either from Poisson statistics or from SumOfWeights
374 double lo = 0;
375 double hi = 0;
376 weightError(lo,hi,etype) ;
377 return (lo+hi)/2 ;
378
379 } else if (_wgtVar) {
380
381 // We have a weight variable, use that info
382 if (_wgtVar->hasAsymError()) {
383 return ( _wgtVar->getAsymErrorHi() - _wgtVar->getAsymErrorLo() ) / 2 ;
384 } else if (_wgtVar->hasError(false)) {
385 return _wgtVar->getError();
386 } else {
387 return 0 ;
388 }
389
390 } else {
391
392 // We have no weights
393 return 0 ;
394
395 }
396}
397
398
399
400////////////////////////////////////////////////////////////////////////////////
401
402void RooVectorDataStore::weightError(double& lo, double& hi, RooAbsData::ErrorType etype) const
403{
404 if (_extWgtArray) {
405 double wgt;
406
407 // We have a weight array, use that info
408 switch (etype) {
409
410 case RooAbsData::Auto:
411 throw string(Form("RooDataHist::weightError(%s) error type Auto not allowed here",GetName())) ;
412 break ;
413
415 throw string(Form("RooDataHist::weightError(%s) error type Expected not allowed here",GetName())) ;
416 break ;
417
419 // Weight may be preset or precalculated
423 return ;
424 }
425
426 // Otherwise Calculate poisson errors
427 wgt = weight();
428 double ym;
429 double yp;
430 RooHistError::instance().getPoissonInterval(Int_t(wgt+0.5),ym,yp,1);
431 lo = wgt-ym;
432 hi = yp-wgt;
433 return ;
434
437 hi = lo;
438 return ;
439
440 case RooAbsData::None:
441 lo = 0 ;
442 hi = 0 ;
443 return ;
444 }
445
446 } else if (_wgtVar) {
447
448 // We have a weight variable, use that info
449 if (_wgtVar->hasAsymError()) {
451 lo = _wgtVar->getAsymErrorLo() ;
452 } else {
453 hi = _wgtVar->getError() ;
454 lo = _wgtVar->getError() ;
455 }
456
457 } else {
458
459 // We are unweighted
460 lo=0 ;
461 hi=0 ;
462
463 }
464}
465
466
467
468////////////////////////////////////////////////////////////////////////////////
469///
470
471void RooVectorDataStore::loadValues(const RooAbsDataStore *ads, const RooFormulaVar* select, const char* rangeName, std::size_t nStart, std::size_t nStop)
472{
473 // Load values from dataset 't' into this data collection, optionally
474 // selecting events using 'select' RooFormulaVar
475 //
476
477 // Redirect formula servers to source data row
478 std::unique_ptr<RooFormulaVar> selectClone;
479 if (select) {
480 selectClone.reset( static_cast<RooFormulaVar*>(select->cloneTree()) );
481 selectClone->recursiveRedirectServers(*ads->get()) ;
482 selectClone->setOperMode(RooAbsArg::ADirty,true) ;
483 }
484
485 // Force DS internal initialization
486 ads->get(0) ;
487
488 // Loop over events in source tree
489 const auto numEntr = static_cast<std::size_t>(ads->numEntries());
490 const std::size_t nevent = nStop < numEntr ? nStop : numEntr;
491
492 auto treeDS = dynamic_cast<const RooTreeDataStore*>(ads);
493 auto vectorDS = dynamic_cast<const RooVectorDataStore*>(ads);
494
495 // Check if weight is being renamed - if so set flag to enable special handling in copy loop
496 bool weightRename(false) ;
497 const bool newWeightVar = _wgtVar ? _wgtVar->getAttribute("NewWeight") : false ;
498
499 if (_wgtVar && vectorDS && vectorDS->_wgtVar) {
500 if (std::string(_wgtVar->GetName()) != vectorDS->_wgtVar->GetName() && !newWeightVar) {
502 }
503 }
504 if (_wgtVar && treeDS && treeDS->_wgtVar) {
505 if (std::string(_wgtVar->GetName()) != treeDS->_wgtVar->GetName() && !newWeightVar) {
507 }
508 }
509
510 std::vector<std::string> ranges;
511 if (rangeName) {
512 ranges = ROOT::Split(rangeName, ",");
513 }
514
515 reserve(numEntries() + (nevent - nStart));
516 for(auto i=nStart; i < nevent ; ++i) {
517 ads->get(i);
518
519 // Does this event pass the cuts?
520 if (selectClone && selectClone->getVal()==0) {
521 continue ;
522 }
523
524 RooArgSet const* otherVarsww = nullptr;
525
526 if (treeDS) {
527 otherVarsww = &treeDS->_varsww;
528 if (weightRename) {
529 _wgtVar->setVal(treeDS->_wgtVar->getVal()) ;
530 }
531 } else if (vectorDS) {
532 otherVarsww = &vectorDS->_varsww;
533 if (weightRename) {
534 _wgtVar->setVal(vectorDS->_wgtVar->getVal()) ;
535 }
536 } else {
537 otherVarsww = ads->get();
538 }
539
540 // Check that all copied values are valid and in range
541 bool allValid = true;
542 for (const auto arg : *otherVarsww) {
543 allValid &= arg->isValid();
544 if (allValid && !ranges.empty()) {
545 // If we have one or multiple ranges to be selected, the value
546 // must be in one of them to be valid
547 allValid &= std::any_of(ranges.begin(), ranges.end(), [arg](const std::string& range){
548 return arg->inRange(range.c_str());});
549 }
550 if (!allValid)
551 break ;
552 }
553
554 if (!allValid) {
555 continue ;
556 }
557
559
560 fill() ;
561 }
562
563 SetTitle(ads->GetTitle());
564}
565
566
567
568
569
570////////////////////////////////////////////////////////////////////////////////
571
572bool RooVectorDataStore::changeObservableName(const char* /*from*/, const char* /*to*/)
573{
574 return false ;
575}
576
577
578
579////////////////////////////////////////////////////////////////////////////////
580/// Add a new column to the data set which holds the pre-calculated values
581/// of 'newVar'. This operation is only meaningful if 'newVar' is a derived
582/// value.
583///
584/// The return value points to the added element holding 'newVar's value
585/// in the data collection. The element is always the corresponding fundamental
586/// type of 'newVar' (e.g. a RooRealVar if 'newVar' is a RooFormulaVar)
587///
588/// Note: This function is explicitly NOT intended as a speed optimization
589/// opportunity for the user. Components of complex PDFs that can be
590/// precalculated with the dataset are automatically identified as such
591/// and will be precalculated when fitting to a dataset
592///
593/// By forcibly precalculating functions with non-trivial Jacobians,
594/// or functions of multiple variables occurring in the data set,
595/// using addColumn(), you may alter the outcome of the fit.
596///
597/// Only in cases where such a modification of fit behaviour is intentional,
598/// this function should be used.
599
601{
602 // Create a fundamental object of the right type to hold newVar values
603 auto valHolder = std::unique_ptr<RooAbsArg>{newVar.createFundamental()}.release();
604 // Sanity check that the holder really is fundamental
605 if(!valHolder->isFundamental()) {
606 coutE(InputArguments) << GetName() << "::addColumn: holder argument is not fundamental: \""
607 << valHolder->GetName() << "\"" << std::endl;
608 return nullptr;
609 }
610
611 // Attention: need to do this now, as adding an empty column might give 0 as size
612 const std::size_t numEvt = size();
613
614 // Clone variable and attach to cloned tree
615 std::unique_ptr<RooAbsArg> newVarClone{newVar.cloneTree()};
616 newVarClone->recursiveRedirectServers(_vars,false) ;
617
618 // Attach value place holder to this tree
619 valHolder->attachToVStore(*this) ;
622
623 // Fill values of placeholder
624 RealVector* rv(nullptr) ;
625 CatVector* cv(nullptr) ;
626 assert(numEvt != 0);
627 if (dynamic_cast<RooAbsReal*>(valHolder)) {
628 rv = addReal(static_cast<RooAbsReal*>(valHolder));
629 rv->resize(numEvt) ;
630 } else if (dynamic_cast<RooAbsCategory*>(static_cast<RooAbsCategory*>(valHolder))) {
631 cv = addCategory(static_cast<RooAbsCategory*>(valHolder)) ;
632 cv->resize(numEvt) ;
633 }
634
635 for (std::size_t i=0; i < numEvt; i++) {
636 get(i) ;
637
638 newVarClone->syncCache(&_vars) ;
639 valHolder->copyCache(newVarClone.get()) ;
640
641 if (rv) rv->write(i) ;
642 if (cv) cv->write(i) ;
643 }
644
645 return valHolder ;
646}
647
648
649
650////////////////////////////////////////////////////////////////////////////////
651/// Merge columns of supplied data set(s) with this data set. All
652/// data sets must have equal number of entries. In case of
653/// duplicate columns the column of the last dataset in the list
654/// prevails
655
657{
658 RooVectorDataStore* mergedStore = new RooVectorDataStore("merged","merged",allVars) ;
659
660 const auto nevt = dstoreList.front()->numEntries();
661 mergedStore->reserve(nevt);
662 for (int i=0 ; i<nevt ; i++) {
663
664 // Copy data from self
665 mergedStore->_vars.assign(*get(i)) ;
666
667 // Copy variables from merge sets
668 for (list<RooAbsDataStore*>::iterator iter = dstoreList.begin() ; iter!=dstoreList.end() ; ++iter) {
669 const RooArgSet* partSet = (*iter)->get(i) ;
670 mergedStore->_vars.assign(*partSet) ;
671 }
672
673 mergedStore->fill() ;
674 }
675 return mergedStore ;
676}
677
678
679
681{
682 for (auto elm : _realStoreList) {
683 elm->reserve(nEvts);
684 }
685
686 for (auto elm : _realfStoreList) {
687 elm->reserve(nEvts);
688 }
689
690 for (auto elm : _catStoreList) {
691 elm->reserve(nEvts);
692 }
693}
694
695////////////////////////////////////////////////////////////////////////////////
696
698{
699 Int_t nevt = other.numEntries() ;
700 reserve(nevt + numEntries());
701 for (int i=0 ; i<nevt ; i++) {
702 _vars.assign(*other.get(i)) ;
703 if (_wgtVar) {
704 _wgtVar->setVal(other.weight()) ;
705 }
706
707 fill() ;
708 }
709}
710
711
712
713////////////////////////////////////////////////////////////////////////////////
714
716{
718
719 for (auto elm : _realStoreList) {
720 elm->reset() ;
721 }
722
723 for (auto elm : _realfStoreList) {
724 elm->reset() ;
725 }
726
727 for (auto elm : _catStoreList) {
728 elm->reset() ;
729 }
730
731}
732
733////////////////////////////////////////////////////////////////////////////////
734
736{
737 for (auto arg : _varsww) {
738 RooAbsArg* extArg = extObs.find(arg->GetName()) ;
739 if (extArg) {
740 extArg->attachToVStore(*this) ;
741 }
742 }
743}
744
745
746
747////////////////////////////////////////////////////////////////////////////////
748
750{
751 for (auto arg : _varsww) {
752 arg->attachToVStore(*this);
753 }
754}
755
756
757
758////////////////////////////////////////////////////////////////////////////////
759
761{
762 std::cout << "RooVectorDataStor::dump()" << std::endl ;
763
764 std::cout << "_varsww = " << std::endl ; _varsww.Print("v") ;
765 std::cout << "realVector list is" << std::endl ;
766
767 for (const auto elm : _realStoreList) {
768 std::cout << "RealVector " << elm << " _nativeReal = " << elm->_nativeReal << " = " << elm->_nativeReal->GetName() << " bufptr = " << elm->_buf << std::endl ;
769 std::cout << " values : " ;
770 Int_t imax = elm->_vec.size()>10 ? 10 : elm->_vec.size() ;
771 for (Int_t i=0 ; i<imax ; i++) {
772 std::cout << elm->_vec[i] << " " ;
773 }
774 std::cout << std::endl ;
775 }
776
777 for (const auto elm : _realfStoreList) {
778 std::cout << "RealFullVector " << elm << " _nativeReal = " << elm->_nativeReal << " = " << elm->_nativeReal->GetName()
779 << " bufptr = " << elm->_buf << " errbufptr = " << elm->bufE() << std::endl ;
780
781 std::cout << " values : " ;
782 Int_t imax = elm->_vec.size()>10 ? 10 : elm->_vec.size() ;
783 for (Int_t i=0 ; i<imax ; i++) {
784 std::cout << elm->_vec[i] << " " ;
785 }
786 std::cout << std::endl ;
787 if (elm->bufE()) {
788 std::cout << " errors : " ;
789 for (Int_t i=0 ; i<imax ; i++) {
790 std::cout << elm->dataE()[i] << " " ;
791 }
792 std::cout << std::endl ;
793
794 }
795 }
796}
797
798
799////////////////////////////////////////////////////////////////////////////////
800/// Stream an object of class RooVectorDataStore.
801
803{
804 if (R__b.IsReading()) {
805 R__b.ReadClassBuffer(RooVectorDataStore::Class(),this);
806
807 for (auto elm : _realStoreList) {
808 RooAbsArg* arg = _varsww.find(elm->_nativeReal->GetName()) ;
809 arg->attachToVStore(*this) ;
810 }
811 for (auto elm : _realfStoreList) {
812 RooAbsArg* arg = _varsww.find(elm->_nativeReal->GetName()) ;
813 arg->attachToVStore(*this) ;
814 }
815 for (auto elm : _catStoreList) {
816 RooAbsArg* arg = _varsww.find(elm->_cat->GetName()) ;
817 arg->attachToVStore(*this) ;
818 }
819
820 } else {
821 R__b.WriteClassBuffer(RooVectorDataStore::Class(),this);
822 }
823}
824
825
826////////////////////////////////////////////////////////////////////////////////
827/// Return batches of the data columns for the requested events.
828/// \param[in] first First event in the batches.
829/// \param[in] len Number of events in batches.
830/// \return Spans with the associated data.
831RooAbsData::RealSpans RooVectorDataStore::getBatches(std::size_t first, std::size_t len) const {
833
834 auto emplace = [this,&evalData,first,len](const RealVector* realVec) {
835 auto span = realVec->getRange(first, first + len);
836 auto result = evalData.emplace(realVec->_nativeReal, span);
837 if (result.second == false || result.first->second.size() != len) {
838 const auto size = result.second ? result.first->second.size() : 0;
839 coutE(DataHandling) << "A batch of data for '" << realVec->_nativeReal->GetName()
840 << "' was requested from " << first << " to " << first+len
841 << ", but only the events [" << first << ", " << first + size << ") are available." << std::endl;
842 }
843 if (realVec->_real) {
844 // If a buffer is attached, i.e. we are ready to load into a RooAbsReal outside of our dataset,
845 // we can directly map our spans to this real.
846 evalData.emplace(realVec->_real, span);
847 }
848 };
849
850 for (const auto realVec : _realStoreList) {
851 emplace(realVec);
852 }
853 for (const auto realVec : _realfStoreList) {
854 emplace(realVec);
855 }
856
857 return evalData;
858}
859
860
863
864 auto emplace = [this,&evalData,first,len](const CatVector* catVec) {
865 auto span = catVec->getRange(first, first + len);
866 auto result = evalData.emplace(catVec->_cat, span);
867 if (result.second == false || result.first->second.size() != len) {
868 const auto size = result.second ? result.first->second.size() : 0;
869 coutE(DataHandling) << "A batch of data for '" << catVec->_cat->GetName()
870 << "' was requested from " << first << " to " << first+len
871 << ", but only the events [" << first << ", " << first + size << ") are available." << std::endl;
872 }
873 };
874
875 for (const auto& catVec : _catStoreList) {
876 emplace(catVec);
877 }
878
879 return evalData;
880}
881
882
883////////////////////////////////////////////////////////////////////////////////
884/// Return the weights of all events in the range [first, first+len).
885/// If an array with weights is stored, a batch with these weights will be returned. If
886/// no weights are stored, an empty batch is returned. Use weight() to check if there's
887/// a constant weight.
888std::span<const double> RooVectorDataStore::getWeightBatch(std::size_t first, std::size_t len) const
889{
890 if (_extWgtArray) {
891 return std::span<const double>(_extWgtArray + first, _extWgtArray + first + len);
892 }
893
894 if (_wgtVar) {
895 auto findWeightVar = [this](const RealVector* realVec) {
896 return realVec->_nativeReal == _wgtVar || realVec->_nativeReal->GetName() == _wgtVar->GetName();
897 };
898
899 auto storageIter = std::find_if(_realStoreList.begin(), _realStoreList.end(), findWeightVar);
901 return (*storageIter)->getRange(first, first + len);
902
903 auto fstorageIter = std::find_if(_realfStoreList.begin(), _realfStoreList.end(), findWeightVar);
905 return (*fstorageIter)->getRange(first, first + len);
906
907 throw std::logic_error("RooVectorDataStore::getWeightBatch(): Could not retrieve data for _wgtVar.");
908 }
909 return {};
910}
911
912
914
915 // First try a match by name
916 for (auto catVec : _catStoreList) {
917 if (std::string(catVec->bufArg()->GetName())==cat->GetName()) {
918 return catVec;
919 }
920 }
921
922 // If nothing found this will make an entry
923 _catStoreList.push_back(new CatVector(cat)) ;
924
925 return _catStoreList.back() ;
926}
927
928
930
931 // First try a match by name
932 for (auto realVec : _realStoreList) {
933 if (realVec->bufArg()->namePtr()==real->namePtr()) {
934 return realVec;
935 }
936 }
937
938 // Then check if an entry already exists for a full real
939 for (auto fullVec : _realfStoreList) {
940 if (fullVec->bufArg()->namePtr()==real->namePtr()) {
941 // Return full vector as RealVector base class here
942 return fullVec;
943 }
944 }
945
946 // If nothing found this will make an entry
947 _realStoreList.push_back(new RealVector(real)) ;
948
949 return _realStoreList.back() ;
950}
951
952
954
955 // First try a match by name
956 for (auto fullVec : _realfStoreList) {
957 if (std::string(fullVec->bufArg()->GetName())==real->GetName()) {
958 return true ;
959 }
960 }
961 return false ;
962}
963
964
966
967 // First try a match by name
968 for (auto fullVec : _realfStoreList) {
969 if (std::string(fullVec->bufArg()->GetName())==real->GetName()) {
970 return fullVec->bufE();
971 }
972 }
973 return false ;
974}
975
976
978
979 // First try a match by name
980 for (auto fullVec : _realfStoreList) {
981 if (std::string(fullVec->bufArg()->GetName())==real->GetName()) {
982 return fullVec->bufEL();
983 }
984 }
985 return false ;
986}
987
988
990
991 // First try a match by name
992 for (auto fullVec : _realfStoreList) {
993 if (std::string(fullVec->bufArg()->GetName())==real->GetName()) {
994 return fullVec;
995 }
996 }
997
998 // Then check if an entry already exists for a bare real
999 for (auto realVec : _realStoreList) {
1000 if (std::string(realVec->bufArg()->GetName())==real->GetName()) {
1001
1002 // Convert element to full and add to full list
1003 _realfStoreList.push_back(new RealFullVector(*realVec,real)) ;
1004
1005 // Delete bare element
1006 _realStoreList.erase(std::find(_realStoreList.begin(), _realStoreList.end(), realVec));
1007 delete realVec;
1008
1009 return _realfStoreList.back() ;
1010 }
1011 }
1012
1013 // If nothing found this will make an entry
1014 _realfStoreList.push_back(new RealFullVector(real)) ;
1015
1016 return _realfStoreList.back() ;
1017}
1018
1019
1020/// Trigger a recomputation of the cached weight sums. Meant for use by RooFit
1021/// dataset converter functions such as the NumPy converter functions
1022/// implemented as pythonizations.
1024 double const* arr = nullptr;
1025 if (_extWgtArray) {
1026 arr = _extWgtArray;
1027 }
1028 if (_wgtVar) {
1029 const std::string wgtName = _wgtVar->GetName();
1030 for(auto const* real : _realStoreList) {
1031 if(wgtName == real->_nativeReal->GetName())
1032 arr = real->_vec.data();
1033 }
1034 for(auto const* real : _realfStoreList) {
1035 if(wgtName == real->_nativeReal->GetName())
1036 arr = real->_vec.data();
1037 }
1038 }
1039 if(arr == nullptr) {
1040 _sumWeight = size();
1041 return;
1042 }
1044 _sumWeight = result.Sum();
1045 _sumWeightCarry = result.Carry();
1046}
1047
1048
1049/// Exports all arrays in this RooVectorDataStore into a simple datastructure
1050/// to be used by RooFit internal export functions.
1052 ArraysStruct out;
1053 out.size = size();
1054
1055 for(auto const* real : _realStoreList) {
1056 out.reals.emplace_back(real->_nativeReal->GetName(), real->_vec.data());
1057 }
1058 for(auto const* realf : _realfStoreList) {
1059 std::string name = realf->_nativeReal->GetName();
1060 out.reals.emplace_back(name, realf->_vec.data());
1061 if(realf->bufE()) out.reals.emplace_back(name + "Err", realf->dataE().data());
1062 if(realf->bufEL()) out.reals.emplace_back(name + "ErrLo", realf->dataEL().data());
1063 if(realf->bufEH()) out.reals.emplace_back(name + "ErrHi", realf->dataEH().data());
1064 }
1065 for(auto const* cat : _catStoreList) {
1066 out.cats.emplace_back(cat->_cat->GetName(), cat->_vec.data());
1067 }
1068
1069 if(_extWgtArray) out.reals.emplace_back("weight", _extWgtArray);
1070 if(_extWgtErrLoArray) out.reals.emplace_back("wgtErrLo", _extWgtErrLoArray);
1071 if(_extWgtErrHiArray) out.reals.emplace_back("wgtErrHi", _extWgtErrHiArray);
1072 if(_extSumW2Array) out.reals.emplace_back("sumW2",_extSumW2Array);
1073
1074 return out;
1075}
#define coutE(a)
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
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 result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
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
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2570
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:230
const_iterator begin() const
const_iterator end() const
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:76
bool getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
virtual void attachToVStore(RooVectorDataStore &vstore)=0
A space to attach TBranches.
void attachToVStore(RooVectorDataStore &vstore) override
Attach the category index and label to as branches to the given vector store.
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.
void Print(Option_t *options=nullptr) const override
This method must be overridden when a class wants to print itself.
Abstract base class for a data collection.
bool _doDirtyProp
Switch do (de)activate dirty state propagation when loading a data point.
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
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:107
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
A RooFormulaVar is a generic implementation of a real-valued object, which takes a RooArgList of serv...
static const RooHistError & instance()
Return a reference to a singleton object that is created the first time this method is called.
Variable that can be changed from the outside.
Definition RooRealVar.h:37
void setVal(double value) override
Set value of variable to 'value'.
double getError() const
Definition RooRealVar.h:59
bool hasError(bool allowZero=true) const
Definition RooRealVar.h:60
bool hasAsymError(bool allowZero=true) const
Definition RooRealVar.h:65
double getAsymErrorHi() const
Definition RooRealVar.h:64
double getAsymErrorLo() const
Definition RooRealVar.h:63
The RooStringView is a wrapper around a C-style string that can also be constructed from a std::strin...
TTree-backed data storage.
Uses std::vector to store data columns.
std::vector< RealFullVector * > _realfStoreList
Int_t numEntries() const override
RooAbsArg * addColumn(RooAbsArg &var, bool adjustRange=true) override
Add a new column to the data set which holds the pre-calculated values of 'newVar'.
const double * _extWgtErrHiArray
! External weight array - high error
std::span< 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).
~RooVectorDataStore() override
Destructor.
void resetBuffers() override
static TClass * Class()
RooRealVar * weightVar(const RooArgSet &allVars, const char *wgtName)
Utility function for constructors Return pointer to weight variable if it is defined.
RooRealVar * _wgtVar
Pointer to weight variable (if set)
std::vector< RealVector * > _realStoreList
CatVector * addCategory(RooAbsCategory *cat)
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
RealFullVector * addRealFull(RooAbsReal *real)
double weight() const override
Return the weight of the last-retrieved data point.
RooAbsData::RealSpans getBatches(std::size_t first, std::size_t len) const override
Return batches of the data columns for the requested events.
bool isFullReal(RooAbsReal *real)
Int_t fill() override
Interface function to TTree::Fill.
const double * _extWgtErrLoArray
! External weight array - low error
void append(RooAbsDataStore &other) override
bool hasError(RooAbsReal *real)
std::vector< CatVector * > _catStoreList
double weightError(RooAbsData::ErrorType etype=RooAbsData::Poisson) const override
Return the error of the current weight.
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...
RooAbsData::CategorySpans getCategoryBatches(std::size_t, std::size_t len) const override
RooAbsDataStore * merge(const RooArgSet &allvars, std::list< RooAbsDataStore * > dstoreList) override
Merge columns of supplied data set(s) with this data set.
RealVector * addReal(RooAbsReal *real)
bool hasAsymError(RooAbsReal *real)
bool changeObservableName(const char *from, const char *to) override
const double * _extSumW2Array
! External sum of weights array
void recomputeSumWeight()
Trigger a recomputation of the cached weight sums.
std::size_t size() const
Get size of stored dataset.
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
virtual const RooArgSet * get() const
const double * _extWgtArray
! External weight array
void Streamer(TBuffer &) override
Stream an object of class RooVectorDataStore.
RooArgSet varsNoWeight(const RooArgSet &allVars, const char *wgtName)
Utility function for constructors Return RooArgSet that is copy of allVars minus variable matching wg...
Buffer base class used for serializing objects.
Definition TBuffer.h:43
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:173
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
Double_t y[n]
Definition legend1.C:17
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.
Output struct for the RooVectorDataStore::getArrays() helper function.
std::vector< ArrayInfo< double > > reals
std::vector< ArrayInfo< RooAbsCategory::value_type > > cats