Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooTreeDataStore.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 RooTreeDataStore.cxx
19\class RooTreeDataStore
20\ingroup Roofitcore
21
22TTree-backed data storage. When a file is opened before
23creating the data storage, the storage will be file-backed. This reduces memory
24pressure because it allows storing the data in the file and reading it on demand.
25For a completely memory-backed storage, which is faster than the file-backed storage,
26RooVectorDataStore can be used.
27
28With tree-backed storage, the tree can be found in the file with the name
29`RooTreeDataStore_name_title` for a dataset created as
30`RooDataSet("name", "title", ...)`.
31
32\note A file needs to be opened **before** creating the data storage to enable file-backed
33storage.
34```
35TFile outputFile("filename.root", "RECREATE");
36RooAbsData::setDefaultStorageType(RooAbsData::Tree);
37RooDataSet mydata(...);
38```
39
40One can also change between TTree- and std::vector-backed storage using
41RooAbsData::convertToTreeStore() and
42RooAbsData::convertToVectorStore().
43**/
44
45#include "RooTreeDataStore.h"
46
47#include "RooMsgService.h"
48#include "RooFormulaVar.h"
49#include "RooRealVar.h"
50#include "RooHistError.h"
51
52#include "ROOT/StringUtils.hxx"
53
54#include "TTree.h"
55#include "TFile.h"
56#include "TChain.h"
57#include "TDirectory.h"
58#include "TBuffer.h"
59#include "TBranch.h"
60#include "TROOT.h"
61
62#include <iomanip>
63using std::endl, std::list, std::string;
64
65
66
68
69
70
71////////////////////////////////////////////////////////////////////////////////
72
74
75
76
77////////////////////////////////////////////////////////////////////////////////
78/// Constructor to facilitate reading of legacy RooDataSets
79
81 RooAbsDataStore("blah","blah",varsNoWeight(vars,wgtVarName)),
82 _tree(t),
83 _defCtor(true),
84 _varsww(vars),
85 _wgtVar(weightVar(vars,wgtVarName))
86{
87}
88
89
90
91
92////////////////////////////////////////////////////////////////////////////////
93
95 RooAbsDataStore(name,title,varsNoWeight(vars,wgtVarName)),
96 _varsww(vars),
97 _wgtVar(weightVar(vars,wgtVarName))
98{
99 initialize() ;
100}
101
102
103////////////////////////////////////////////////////////////////////////////////
104
106 RooAbsDataStore(name,title,varsNoWeight(vars,wgtVarName)),
107 _varsww(vars),
108 _wgtVar(weightVar(vars,wgtVarName))
109{
110 initialize() ;
111
112 if (selExpr && *selExpr) {
113 // Create a RooFormulaVar cut from given cut expression
114 RooFormulaVar select(selExpr, selExpr, _vars, /*checkVariables=*/false);
115 loadValues(&t,&select);
116 } else {
117 loadValues(&t);
118 }
119}
120
121
122////////////////////////////////////////////////////////////////////////////////
123
125 RooAbsDataStore(name,title,varsNoWeight(vars,wgtVarName)),
126 _varsww(vars),
127 _wgtVar(weightVar(vars,wgtVarName))
128{
129 initialize() ;
130
131 if (selExpr && *selExpr) {
132 // Create a RooFormulaVar cut from given cut expression
133 RooFormulaVar select(selExpr, selExpr, _vars, /*checkVariables=*/false);
134 loadValues(&ads,&select);
135 } else {
136 loadValues(&ads);
137 }
138}
139
140
141
142
143////////////////////////////////////////////////////////////////////////////////
144
146 const RooFormulaVar *cutVar, const char *cutRange, Int_t nStart, Int_t nStop,
147 const char *wgtVarName)
148 : RooAbsDataStore(name, title, varsNoWeight(vars, wgtVarName)),
149 _varsww(vars),
150 _wgtVar(weightVar(vars, wgtVarName))
151{
152 // WVE NEED TO ADJUST THIS FOR WEIGHTS
153
154 // Protected constructor for internal use only
155
156 createTree(makeTreeName(), title);
157
158 // Deep clone cutVar and attach clone to this dataset
159 std::unique_ptr<RooFormulaVar> cloneVar;
160 if (cutVar) {
161 cloneVar.reset(static_cast<RooFormulaVar*>(cutVar->cloneTree()));
162 cloneVar->attachDataStore(tds) ;
163 }
164
165 // Constructor from existing data set with list of variables that preserves the cache
166 initialize();
167
168 loadValues(&tds,cloneVar.get(),cutRange,nStart,nStop);
169}
170
171
172std::unique_ptr<RooAbsDataStore> RooTreeDataStore::reduce(RooStringView name, RooStringView title,
173 const RooArgSet& vars, const RooFormulaVar* cutVar, const char* cutRange,
174 std::size_t nStart, std::size_t nStop) {
175 RooArgSet tmp(vars) ;
176 if(_wgtVar && !tmp.contains(*_wgtVar)) {
177 tmp.add(*_wgtVar) ;
178 }
179 const char* wgtVarName = _wgtVar ? _wgtVar->GetName() : nullptr;
180 return std::make_unique<RooTreeDataStore>(name, title, *this, tmp, cutVar, cutRange, nStart, nStop, wgtVarName);
181}
182
183
184////////////////////////////////////////////////////////////////////////////////
185/// Utility function for constructors
186/// Return RooArgSet that is copy of allVars minus variable matching wgtName if specified
187
189{
190 RooArgSet ret(allVars) ;
191 if(wgtName) {
192 RooAbsArg* wgt = allVars.find(wgtName) ;
193 if (wgt) {
194 ret.remove(*wgt,true,true) ;
195 }
196 }
197 return ret ;
198}
199
200
201
202////////////////////////////////////////////////////////////////////////////////
203/// Utility function for constructors
204/// Return pointer to weight variable if it is defined
205
207{
208 if(wgtName) {
209 RooRealVar* wgt = dynamic_cast<RooRealVar*>(allVars.find(wgtName)) ;
210 return wgt ;
211 }
212 return nullptr ;
213}
214
215
216////////////////////////////////////////////////////////////////////////////////
217
220 _varsww(other._varsww),
221 _wgtVar(other._wgtVar),
222 _extWgtArray(other._extWgtArray),
223 _extWgtErrLoArray(other._extWgtErrLoArray),
224 _extWgtErrHiArray(other._extWgtErrHiArray),
225 _extSumW2Array(other._extSumW2Array),
226 _curWgt(other._curWgt),
227 _curWgtErrLo(other._curWgtErrLo),
228 _curWgtErrHi(other._curWgtErrHi),
229 _curWgtErr(other._curWgtErr)
230{
231 initialize() ;
232 loadValues(&other) ;
233}
234
235
236////////////////////////////////////////////////////////////////////////////////
237
239 RooAbsDataStore(other,varsNoWeight(vars,other._wgtVar?other._wgtVar->GetName():nullptr),newname),
240 _varsww(vars),
241 _wgtVar(other._wgtVar?weightVar(vars,other._wgtVar->GetName()):nullptr),
242 _extWgtArray(other._extWgtArray),
243 _extWgtErrLoArray(other._extWgtErrLoArray),
244 _extWgtErrHiArray(other._extWgtErrHiArray),
245 _extSumW2Array(other._extSumW2Array),
246 _curWgt(other._curWgt),
247 _curWgtErrLo(other._curWgtErrLo),
248 _curWgtErrHi(other._curWgtErrHi),
249 _curWgtErr(other._curWgtErr)
250{
251 initialize() ;
252 loadValues(&other) ;
253}
254
255
256
257
258////////////////////////////////////////////////////////////////////////////////
259/// Destructor
260
262{
263 if (_tree) {
264 delete _tree ;
265 }
266}
267
268
269
270////////////////////////////////////////////////////////////////////////////////
271/// One-time initialization common to all constructor forms. Attach
272/// variables of internal ArgSet to the corresponding TTree branches
273
275{
276 // Recreate (empty) cache tree
278
279 // Attach each variable to the dataset
280 for (auto var : _varsww) {
281 var->attachToTree(*_tree,_defTreeBufSize) ;
282 }
283}
284
285
286
287
288
289////////////////////////////////////////////////////////////////////////////////
290/// Create TTree object that lives in memory, independent of current
291/// location of gDirectory
292
294{
295 if (!_tree) {
296 _tree = new TTree(name.c_str(),title.c_str());
299 _tree->SetDirectory(nullptr);
300 }
301
302 TString pwd(gDirectory->GetPath()) ;
303 TString memDir(gROOT->GetName()) ;
304 memDir.Append(":/") ;
305 bool notInMemNow= (pwd!=memDir) ;
306
307 // std::cout << "RooTreeData::createTree pwd=" << pwd << " memDir=" << memDir << " notInMemNow = " << (notInMemNow?"T":"F") << std::endl ;
308
309 if (notInMemNow) {
310 gDirectory->cd(memDir) ;
311 }
312
313 if (notInMemNow) {
314 gDirectory->cd(pwd) ;
315 }
316
317}
318
319
320
321
322////////////////////////////////////////////////////////////////////////////////
323/// Load values from tree 't' into this data collection, optionally
324/// selecting events using the RooFormulaVar 'select'.
325///
326/// The source tree 't' is cloned to not disturb its branch
327/// structure when retrieving information from it.
328void RooTreeDataStore::loadValues(const TTree *t, const RooFormulaVar* select, const char* /*rangeName*/, Int_t /*nStart*/, Int_t /*nStop*/)
329{
330 // Make our local copy of the tree, so we can safely loop through it.
331 // We need a custom deleter, because if we don't deregister the Tree from the directory
332 // of the original, it tears it down at destruction time!
333 auto deleter = [](TTree* tree){tree->SetDirectory(nullptr); delete tree;};
334 std::unique_ptr<TTree, decltype(deleter)> tClone(static_cast<TTree*>(t->Clone()), deleter);
335 tClone->SetDirectory(t->GetDirectory());
336
337 // Clone list of variables
340
341 // Check that we have the branches:
342 bool missingBranches = false;
343 for (const auto var : sourceArgSet) {
344 if (!tClone->GetBranch(var->GetName())) {
345 missingBranches = true;
346 coutE(InputArguments) << "Didn't find a branch in Tree '" << tClone->GetName() << "' to read variable '"
347 << var->GetName() << "' from."
348 << "\n\tNote: Name the RooFit variable the same as the branch." << std::endl;
349 }
350 }
351 if (missingBranches) {
352 coutE(InputArguments) << "Cannot import data from TTree '" << tClone->GetName()
353 << "' because some branches are missing !" << std::endl;
354 return;
355 }
356
357 // Attach args in cloned list to cloned source tree
358 for (const auto sourceArg : sourceArgSet) {
359 sourceArg->attachToTree(*tClone,_defTreeBufSize) ;
360 }
361
362 // Redirect formula servers to sourceArgSet
363 std::unique_ptr<RooFormulaVar> selectClone;
364 if (select) {
365 selectClone.reset( static_cast<RooFormulaVar*>(select->cloneTree()) );
366 selectClone->recursiveRedirectServers(sourceArgSet) ;
367 selectClone->setOperMode(RooAbsArg::ADirty,true) ;
368 }
369
370 // Loop over events in source tree
371 Int_t numInvalid(0) ;
372 const Long64_t nevent = tClone->GetEntries();
373 for(Long64_t i=0; i < nevent; ++i) {
374 const auto entryNumber = tClone->GetEntryNumber(i);
375 if (entryNumber<0) break;
376 tClone->GetEntry(entryNumber,1);
377
378 // Copy from source to destination
379 bool allOK(true) ;
380 for (unsigned int j=0; j < sourceArgSet.size(); ++j) {
381 auto destArg = _varsww[j];
382 const auto sourceArg = sourceArgSet[j];
383
384 destArg->copyCache(sourceArg) ;
385 sourceArg->copyCache(destArg) ;
386 if (!destArg->isValid()) {
387 numInvalid++ ;
388 allOK=false ;
389 if (numInvalid < 5) {
390 auto& log = coutI(DataHandling);
391 log << "RooTreeDataStore::loadValues(" << GetName() << ") Skipping event #" << i << " because " << destArg->GetName()
392 << " cannot accommodate the value ";
393 if(sourceArg->isCategory()) {
395 } else {
397 }
398 log << std::endl;
399 } else if (numInvalid == 5) {
400 coutI(DataHandling) << "RooTreeDataStore::loadValues(" << GetName() << ") Skipping ..." << std::endl;
401 }
402 break ;
403 }
404 }
405
406 // Does this event pass the cuts?
407 if (!allOK || (selectClone && selectClone->getVal()==0)) {
408 continue ;
409 }
410
411 fill() ;
412 }
413
414 if (numInvalid>0) {
415 coutW(DataHandling) << "RooTreeDataStore::loadValues(" << GetName() << ") Ignored " << numInvalid << " out-of-range events" << std::endl ;
416 }
417
418 SetTitle(t->GetTitle());
419}
420
421
422
423
424
425
426////////////////////////////////////////////////////////////////////////////////
427/// Load values from dataset 't' into this data collection, optionally
428/// selecting events using 'select' RooFormulaVar
429///
430
432 const char* rangeName, std::size_t nStart, std::size_t nStop)
433{
434 // Redirect formula servers to source data row
435 std::unique_ptr<RooFormulaVar> selectClone;
436 if (select) {
437 selectClone.reset( static_cast<RooFormulaVar*>(select->cloneTree()) );
438 selectClone->recursiveRedirectServers(*ads->get()) ;
439 selectClone->setOperMode(RooAbsArg::ADirty,true) ;
440 }
441
442 // Force RDS internal initialization
443 ads->get(0) ;
444
445 // Loop over events in source tree
446 const auto numEntr = static_cast<std::size_t>(ads->numEntries());
447 std::size_t nevent = nStop < numEntr ? nStop : numEntr;
448
449 auto TDS = dynamic_cast<const RooTreeDataStore*>(ads) ;
450 if (TDS) {
451 const_cast<RooTreeDataStore*>(TDS)->resetBuffers();
452 }
453
454 std::vector<std::string> ranges;
455 if (rangeName) {
456 ranges = ROOT::Split(rangeName, ",");
457 }
458
459 for (auto i=nStart; i < nevent ; ++i) {
460 ads->get(i) ;
461
462 // Does this event pass the cuts?
463 if (selectClone && selectClone->getVal()==0) {
464 continue ;
465 }
466
467
468 if (TDS) {
469 _varsww.assignValueOnly(TDS->_varsww) ;
470 } else {
471 _varsww.assignValueOnly(*ads->get()) ;
472 }
473
474 // Check that all copied values are valid
475 bool allValid = true;
476 for (const auto arg : _varsww) {
477 allValid = arg->isValid() && (ranges.empty() || std::any_of(ranges.begin(), ranges.end(),
478 [arg](const std::string& range){return arg->inRange(range.c_str());}) );
479 if (!allValid)
480 break ;
481 }
482
483 if (!allValid) {
484 continue ;
485 }
486
487 fill() ;
488 }
489
490 if (TDS) {
492 }
493
494 SetTitle(ads->GetTitle());
495}
496
497
498////////////////////////////////////////////////////////////////////////////////
499/// Interface function to TTree::Fill
500
502{
503 return _tree->Fill() ;
504}
505
506
507
508////////////////////////////////////////////////////////////////////////////////
509/// Load the n-th data point (n='index') in memory
510/// and return a pointer to the internal RooArgSet
511/// holding its coordinates.
512
514{
515 checkInit() ;
516
518
519 if(!ret) return nullptr;
520
521 if (_doDirtyProp) {
522 // Raise all dirty flags
523 for (auto var : _vars) {
524 var->setValueDirty(); // This triggers recalculation of all clients
525 }
526 }
527
528 // Update current weight cache
529 if (_extWgtArray) {
530
531 // If external array is specified use that
536
537 } else if (_wgtVar) {
538
539 // Otherwise look for weight variable
540 _curWgt = _wgtVar->getVal() ;
544
545 } else {
546
547 // Otherwise return 1
548 _curWgt=1.0 ;
549 _curWgtErrLo = 0 ;
550 _curWgtErrHi = 0 ;
551 _curWgtErr = 0 ;
552
553 }
554
555 return &_vars;
556}
557
558
559////////////////////////////////////////////////////////////////////////////////
560/// Return the weight of the n-th data point (n='index') in memory
561
563{
564 return _curWgt ;
565}
566
567
568////////////////////////////////////////////////////////////////////////////////
569
571{
572 if (_extWgtArray) {
573
574 // We have a weight array, use that info
575
576 // Return symmetric error on current bin calculated either from Poisson statistics or from SumOfWeights
577 double lo = 0;
578 double hi = 0;
579 weightError(lo,hi,etype) ;
580 return (lo+hi)/2 ;
581
582 } else if (_wgtVar) {
583
584 // We have a weight variable, use that info
585 if (_wgtVar->hasAsymError()) {
586 return ( _wgtVar->getAsymErrorHi() - _wgtVar->getAsymErrorLo() ) / 2 ;
587 } else {
588 return _wgtVar->getError() ;
589 }
590
591 }
592
593 // We have no weights
594 return 0.0;
595}
596
597
598
599////////////////////////////////////////////////////////////////////////////////
600
601void RooTreeDataStore::weightError(double& lo, double& hi, RooAbsData::ErrorType etype) const
602{
603 if (_extWgtArray) {
604
605 // We have a weight array, use that info
606 switch (etype) {
607
608 case RooAbsData::Auto:
609 throw string(Form("RooDataHist::weightError(%s) error type Auto not allowed here",GetName())) ;
610 break ;
611
613 throw string(Form("RooDataHist::weightError(%s) error type Expected not allowed here",GetName())) ;
614 break ;
615
617 // Weight may be preset or precalculated
618 if (_curWgtErrLo>=0) {
619 lo = _curWgtErrLo ;
620 hi = _curWgtErrHi ;
621 return ;
622 }
623
624 // Otherwise Calculate poisson errors
625 double ym;
626 double yp;
627 RooHistError::instance().getPoissonInterval(Int_t(weight()+0.5),ym,yp,1) ;
628 lo = weight()-ym ;
629 hi = yp-weight() ;
630 return ;
631
633 lo = _curWgtErr ;
634 hi = _curWgtErr ;
635 return ;
636
637 case RooAbsData::None:
638 lo = 0 ;
639 hi = 0 ;
640 return ;
641 }
642
643 } else if (_wgtVar) {
644
645 // We have a weight variable, use that info
646 if (_wgtVar->hasAsymError()) {
648 lo = _wgtVar->getAsymErrorLo() ;
649 } else {
650 hi = _wgtVar->getError() ;
651 lo = _wgtVar->getError() ;
652 }
653
654 } else {
655
656 // We are unweighted
657 lo=0 ;
658 hi=0 ;
659
660 }
661}
662
663
664////////////////////////////////////////////////////////////////////////////////
665/// Change name of internal observable named 'from' into 'to'
666
667bool RooTreeDataStore::changeObservableName(const char* from, const char* to)
668{
669 // Find observable to be changed
670 RooAbsArg* var = _vars.find(from) ;
671
672 // Check that we found it
673 if (!var) {
674 coutE(InputArguments) << "RooTreeDataStore::changeObservableName(" << GetName() << " no observable " << from << " in this dataset" << std::endl ;
675 return true ;
676 }
677
678 // Process name change
680 var->SetName(to) ;
681
682 // Change the branch name as well
683 if (_tree->GetBranch(oldBranchName.Data())) {
684
685 // Simple case varName = branchName
686 _tree->GetBranch(oldBranchName.Data())->SetName(var->cleanBranchName().Data()) ;
687
688 // Process any error branch if existing
689 if (_tree->GetBranch(Form("%s_err",oldBranchName.Data()))) {
690 _tree->GetBranch(Form("%s_err",oldBranchName.Data()))->SetName(Form("%s_err",var->cleanBranchName().Data())) ;
691 }
692 if (_tree->GetBranch(Form("%s_aerr_lo",oldBranchName.Data()))) {
693 _tree->GetBranch(Form("%s_aerr_lo",oldBranchName.Data()))->SetName(Form("%s_aerr_lo",var->cleanBranchName().Data())) ;
694 }
695 if (_tree->GetBranch(Form("%s_aerr_hi",oldBranchName.Data()))) {
696 _tree->GetBranch(Form("%s_aerr_hi",oldBranchName.Data()))->SetName(Form("%s_aerr_hi",var->cleanBranchName().Data())) ;
697 }
698
699 } else {
700
701 // Native category case branchNames = varName_idx and varName_lbl
702 if (_tree->GetBranch(Form("%s_idx",oldBranchName.Data()))) {
703 _tree->GetBranch(Form("%s_idx",oldBranchName.Data()))->SetName(Form("%s_idx",var->cleanBranchName().Data())) ;
704 }
705 if (_tree->GetBranch(Form("%s_lbl",oldBranchName.Data()))) {
706 _tree->GetBranch(Form("%s_lbl",oldBranchName.Data()))->SetName(Form("%s_lb",var->cleanBranchName().Data())) ;
707 }
708
709 }
710
711 return false ;
712}
713
714
715
716////////////////////////////////////////////////////////////////////////////////
717/// Add a new column to the data set which holds the pre-calculated values
718/// of 'newVar'. This operation is only meaningful if 'newVar' is a derived
719/// value.
720///
721/// The return value points to the added element holding 'newVar's value
722/// in the data collection. The element is always the corresponding fundamental
723/// type of 'newVar' (e.g. a RooRealVar if 'newVar' is a RooFormulaVar)
724///
725/// Note: This function is explicitly NOT intended as a speed optimization
726/// opportunity for the user. Components of complex PDFs that can be
727/// precalculated with the dataset are automatically identified as such
728/// and will be precalculated when fitting to a dataset
729///
730/// By forcibly precalculating functions with non-trivial Jacobians,
731/// or functions of multiple variables occurring in the data set,
732/// using addColumn(), you may alter the outcome of the fit.
733///
734/// Only in cases where such a modification of fit behaviour is intentional,
735/// this function should be used.
736
738{
739 checkInit() ;
740
741 // Create a fundamental object of the right type to hold newVar values
742 auto valHolder = std::unique_ptr<RooAbsArg>{newVar.createFundamental()}.release();
743 // Sanity check that the holder really is fundamental
744 if(!valHolder->isFundamental()) {
745 coutE(InputArguments) << GetName() << "::addColumn: holder argument is not fundamental: \""
746 << valHolder->GetName() << "\"" << std::endl;
747 return nullptr;
748 }
749
750 // WVE need to reset TTRee buffers to original datamembers here
751 resetBuffers() ;
752
753 // Clone variable and attach to cloned tree
754 std::unique_ptr<RooAbsArg> newVarClone{newVar.cloneTree()};
755 newVarClone->recursiveRedirectServers(_vars,false) ;
756
757 // Attach value place holder to this tree
758 ((RooAbsArg*)valHolder)->attachToTree(*_tree,_defTreeBufSize) ;
761
762
763 // Fill values of placeholder
764 for (int i=0 ; i < _tree->GetEntries() ; i++) {
765 get(i) ;
766
767 newVarClone->syncCache(&_vars) ;
768 valHolder->copyCache(newVarClone.get());
769 valHolder->fillTreeBranch(*_tree) ;
770 }
771
772 // WVE need to restore TTRee buffers to previous values here
774
775 if (adjustRange) {
776// // Set range of valHolder to (just) bracket all values stored in the dataset
777// double vlo,vhi ;
778// RooRealVar* rrvVal = dynamic_cast<RooRealVar*>(valHolder) ;
779// if (rrvVal) {
780// getRange(*rrvVal,vlo,vhi,0.05) ;
781// rrvVal->setRange(vlo,vhi) ;
782// }
783 }
784
785 return valHolder ;
786}
787
788
789////////////////////////////////////////////////////////////////////////////////
790/// Merge columns of supplied data set(s) with this data set. All
791/// data sets must have equal number of entries. In case of
792/// duplicate columns the column of the last dataset in the list
793/// prevails
794
796{
797 RooTreeDataStore* mergedStore = new RooTreeDataStore("merged","merged",allVars) ;
798
799 Int_t nevt = dstoreList.front()->numEntries() ;
800 for (int i=0 ; i<nevt ; i++) {
801
802 // Cope data from self
803 mergedStore->_vars.assign(*get(i)) ;
804
805 // Copy variables from merge sets
806 for (list<RooAbsDataStore*>::iterator iter = dstoreList.begin() ; iter!=dstoreList.end() ; ++iter) {
807 const RooArgSet* partSet = (*iter)->get(i) ;
808 mergedStore->_vars.assign(*partSet) ;
809 }
810
811 mergedStore->fill() ;
812 }
813 return mergedStore ;
814}
815
816
817
818
819
820////////////////////////////////////////////////////////////////////////////////
821
823{
824 Int_t nevt = other.numEntries() ;
825 for (int i=0 ; i<nevt ; i++) {
826 _vars.assign(*other.get(i)) ;
827 if (_wgtVar) {
828 _wgtVar->setVal(other.weight()) ;
829 }
830
831 fill() ;
832 }
833}
834
835
836////////////////////////////////////////////////////////////////////////////////
837
839{
840 if (_wgtVar) {
841
842 double sum(0);
843 double carry(0);
844 Int_t nevt = numEntries() ;
845 for (int i=0 ; i<nevt ; i++) {
846 get(i) ;
847 // Kahan's algorithm for summing to avoid loss of precision
848 double y = _wgtVar->getVal() - carry;
849 double t = sum + y;
850 carry = (t - sum) - y;
851 sum = t;
852 }
853 return sum ;
854
855 } else if (_extWgtArray) {
856
857 double sum(0);
858 double carry(0);
859 Int_t nevt = numEntries() ;
860 for (int i=0 ; i<nevt ; i++) {
861 // Kahan's algorithm for summing to avoid loss of precision
862 double y = _extWgtArray[i] - carry;
863 double t = sum + y;
864 carry = (t - sum) - y;
865 sum = t;
866 }
867 return sum ;
868
869 } else {
870
871 return numEntries() ;
872
873 }
874}
875
876
877
878
879////////////////////////////////////////////////////////////////////////////////
880
882{
883 return _tree->GetEntries() ;
884}
885
886
887
888////////////////////////////////////////////////////////////////////////////////
889
891{
892 _tree->Reset() ;
893}
894
895
896
897////////////////////////////////////////////////////////////////////////////////
898
900{
902 for (const auto arg : _varsww) {
903 RooAbsArg* extArg = extObs.find(arg->GetName()) ;
904 if (extArg) {
905 if (arg->getAttribute("StoreError")) {
906 extArg->setAttribute("StoreError") ;
907 }
908 if (arg->getAttribute("StoreAsymError")) {
909 extArg->setAttribute("StoreAsymError") ;
910 }
911 extArg->attachToTree(*_tree) ;
913 }
914 }
915}
916
917
918
919////////////////////////////////////////////////////////////////////////////////
920
922{
923 for(RooAbsArg * arg : _varsww) {
924 arg->attachToTree(*_tree) ;
925 }
926}
927
928
929
930////////////////////////////////////////////////////////////////////////////////
931
933{
934 for(RooAbsArg * arg : _attachedBuffers) {
935 arg->attachToTree(*_tree) ;
936 }
937}
938
939
940
941////////////////////////////////////////////////////////////////////////////////
942
944{
945 if (_defCtor) {
946 const_cast<RooTreeDataStore*>(this)->initialize() ;
947 _defCtor = false ;
948 }
949}
950
951////////////////////////////////////////////////////////////////////////////////
952/// Stream an object of class RooTreeDataStore.
953
955{
956 if (R__b.IsReading()) {
957 UInt_t R__s;
958 UInt_t R__c;
959 const Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
960
961 R__b.ReadClassBuffer(RooTreeDataStore::Class(), this, R__v, R__s, R__c);
962
963 if (!_tree) {
964 // If the tree has not been deserialised automatically, it is time to load
965 // it now.
966 TFile* parent = dynamic_cast<TFile*>(R__b.GetParent());
967 assert(parent);
968 parent->GetObject(makeTreeName().c_str(), _tree);
969 }
970
971 initialize();
972
973 } else {
974
976 auto parent = dynamic_cast<TDirectory*>(R__b.GetParent());
977 if (_tree && parent) {
978 // Large trees cannot be written because of the 1Gb I/O limitation.
979 // Here, we take the tree away from our instance, write it, and continue
980 // to write the rest of the class normally
981 auto tmpDir = _tree->GetDirectory();
982
983 _tree->SetDirectory(parent);
984 _tree->FlushBaskets(false);
985 parent->WriteObject(_tree, makeTreeName().c_str());
987 _tree = nullptr;
988 }
989
990 R__b.WriteClassBuffer(RooTreeDataStore::Class(), this);
991
992 _tree = tmpTree;
993 }
994}
995
996////////////////////////////////////////////////////////////////////////////////
997/// Generate a name for the storage tree from the name and title of this instance.
999 std::string title = GetTitle();
1000 std::replace(title.begin(), title.end(), ' ', '_');
1001 std::replace(title.begin(), title.end(), '-', '_');
1002 return std::string("RooTreeDataStore_") + GetName() + "_" + title;
1003}
1004
1005
1006////////////////////////////////////////////////////////////////////////////////
1007/// Get the weights of the events in the range [first, first+len).
1008/// This implementation will fill a vector with every event retrieved one by one
1009/// (even if the weight is constant). Then, it returns a span.
1010std::span<const double> RooTreeDataStore::getWeightBatch(std::size_t first, std::size_t len) const {
1011
1012 if (_extWgtArray) {
1013 return {_extWgtArray + first, len};
1014 }
1015
1016 if (!_weightBuffer) {
1017 _weightBuffer = std::make_unique<std::vector<double>>();
1018 _weightBuffer->reserve(len);
1019
1020 for (int i = 0; i < _tree->GetEntries(); ++i) {
1021 _weightBuffer->push_back(weight(i));
1022 }
1023 }
1024
1025 return {_weightBuffer->data() + first, len};
1026}
#define coutI(a)
#define coutW(a)
#define coutE(a)
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
short Version_t
Class version identifier (short)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define gDirectory
Definition TDirectory.h:385
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
#define gROOT
Definition TROOT.h:417
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2571
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
void SetName(const char *name) override
Set the name of the TNamed.
TString cleanBranchName() const
Construct a mangled name from the actual name that is free of any math symbols that might be interpre...
virtual void removeAll()
Remove all arguments from our set, deleting them if we own them.
RooAbsCollection & assignValueOnly(const RooAbsCollection &other, bool forceIfSizeOne=false)
Sets the value of any argument in our set that also appears in the other set.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
void assign(const RooAbsCollection &other) const
Sets the value, cache and constant attribute of any argument in our set that also appears in the othe...
RooAbsArg * find(const char *name) const
Find object with given name in list.
Abstract base class for a data collection.
bool _doDirtyProp
Switch do (de)activate dirty state propagation when loading a data point.
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
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition RooArgSet.h:159
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 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...
const char * c_str() const
TTree-backed data storage.
void initialize()
One-time initialization common to all constructor forms.
double _curWgtErr
Weight of current event.
double weightError(RooAbsData::ErrorType etype=RooAbsData::Poisson) const override
void resetBuffers() override
double _curWgt
Weight of current event.
double _curWgtErrHi
Weight of current event.
static TClass * Class()
Int_t numEntries() const override
std::string makeTreeName() const
Generate a name for the storage tree from the name and title of this instance.
RooArgSet varsNoWeight(const RooArgSet &allVars, const char *wgtName=nullptr)
Utility function for constructors Return RooArgSet that is copy of allVars minus variable matching wg...
~RooTreeDataStore() override
Destructor.
void createTree(RooStringView name, RooStringView title)
Create TTree object that lives in memory, independent of current location of gDirectory.
const double * _extWgtErrHiArray
! External weight array - high error
void attachBuffers(const RooArgSet &extObs) override
void reset() override
RooAbsDataStore * merge(const RooArgSet &allvars, std::list< RooAbsDataStore * > dstoreList) override
Merge columns of supplied data set(s) with this data set.
static Int_t _defTreeBufSize
RooArgSet _attachedBuffers
! Currently attached buffers (if different from _varsww)
Int_t fill() override
Interface function to TTree::Fill.
double sumEntries() const override
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
bool _defCtor
! Was object constructed with default ctor?
RooAbsArg * addColumn(RooAbsArg &var, bool adjustRange=true) override
Add a new column to the data set which holds the pre-calculated values of 'newVar'.
double weight() const override
Return the weight of the n-th data point (n='index') in memory.
void loadValues(const TTree *t, const RooFormulaVar *select=nullptr, const char *rangeName=nullptr, Int_t nStart=0, Int_t nStop=2000000000)
Load values from tree 't' into this data collection, optionally selecting events using the RooFormula...
void append(RooAbsDataStore &other) override
std::span< const double > getWeightBatch(std::size_t first, std::size_t len) const override
Get the weights of the events in the range [first, first+len).
const double * _extWgtErrLoArray
! External weight array - low error
void checkInit() const override
std::unique_ptr< std::vector< double > > _weightBuffer
! Buffer for weights in case a batch of values is requested.
const double * _extSumW2Array
! External sum of weights array
void Streamer(TBuffer &) override
Stream an object of class RooTreeDataStore.
RooRealVar * weightVar(const RooArgSet &allVars, const char *wgtName=nullptr)
Utility function for constructors Return pointer to weight variable if it is defined.
const double * _extWgtArray
! External weight array
double _curWgtErrLo
Weight of current event.
bool changeObservableName(const char *from, const char *to) override
Change name of internal observable named 'from' into 'to'.
virtual const RooArgSet * get() const
Buffer base class used for serializing objects.
Definition TBuffer.h:43
Describe directory structure in memory.
Definition TDirectory.h:45
void GetObject(const char *namecycle, T *&ptr)
Get an object with proper type checking.
Definition TDirectory.h:213
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
Definition TFile.h:130
TObject * Clone(const char *newname="") const override
Make a clone of an object using the Streamer facility.
Definition TNamed.cxx:73
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
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
void ResetBit(UInt_t f)
Definition TObject.h:203
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:71
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition TObject.h:73
Basic string class.
Definition TString.h:137
const char * Data() const
Definition TString.h:385
A TTree represents a columnar dataset.
Definition TTree.h:89
virtual Int_t Fill()
Fill all branches.
Definition TTree.cxx:4674
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
Definition TTree.cxx:5457
virtual Int_t FlushBaskets(bool create_cluster=true) const
Write to disk all the basket that have not yet been individually written and create an event cluster ...
Definition TTree.cxx:5205
virtual Int_t GetEntry(Long64_t entry, Int_t getall=0)
Read all branches of entry and return total number of bytes read.
Definition TTree.cxx:5745
TDirectory * GetDirectory() const
Definition TTree.h:517
virtual void SetDirectory(TDirectory *dir)
Change the tree's directory.
Definition TTree.cxx:9363
virtual Long64_t GetEntries() const
Definition TTree.h:518
virtual void Reset(Option_t *option="")
Reset baskets, buffers and entries count in all branches and leaves.
Definition TTree.cxx:8339
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.
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2335