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
22RooTreeDataStore is a TTree-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 namespace std ;
64
66
67
69
70
71
72////////////////////////////////////////////////////////////////////////////////
73
75
76
77
78////////////////////////////////////////////////////////////////////////////////
79/// Constructor to facilitate reading of legacy RooDataSets
80
81RooTreeDataStore::RooTreeDataStore(TTree* t, const RooArgSet& vars, const char* wgtVarName) :
82 RooAbsDataStore("blah","blah",varsNoWeight(vars,wgtVarName)),
83 _tree(t),
84 _defCtor(true),
85 _varsww(vars),
86 _wgtVar(weightVar(vars,wgtVarName))
87{
88}
89
90
91
92
93////////////////////////////////////////////////////////////////////////////////
94
95RooTreeDataStore::RooTreeDataStore(RooStringView name, RooStringView title, const RooArgSet& vars, const char* wgtVarName) :
96 RooAbsDataStore(name,title,varsNoWeight(vars,wgtVarName)),
97 _varsww(vars),
98 _wgtVar(weightVar(vars,wgtVarName))
99{
100 initialize() ;
101}
102
103
104////////////////////////////////////////////////////////////////////////////////
105
106RooTreeDataStore::RooTreeDataStore(RooStringView name, RooStringView title, const RooArgSet& vars, TTree& t, const char* selExpr, const char* wgtVarName) :
107 RooAbsDataStore(name,title,varsNoWeight(vars,wgtVarName)),
108 _varsww(vars),
109 _wgtVar(weightVar(vars,wgtVarName))
110{
111 initialize() ;
112
113 if (selExpr && *selExpr) {
114 // Create a RooFormulaVar cut from given cut expression
115 RooFormulaVar select(selExpr, selExpr, _vars, /*checkVariables=*/false);
116 loadValues(&t,&select);
117 } else {
118 loadValues(&t);
119 }
120}
121
122
123////////////////////////////////////////////////////////////////////////////////
124
125RooTreeDataStore::RooTreeDataStore(RooStringView name, RooStringView title, const RooArgSet& vars, const RooAbsDataStore& ads, const char* selExpr, const char* wgtVarName) :
126 RooAbsDataStore(name,title,varsNoWeight(vars,wgtVarName)),
127 _varsww(vars),
128 _wgtVar(weightVar(vars,wgtVarName))
129{
130 initialize() ;
131
132 if (selExpr && *selExpr) {
133 // Create a RooFormulaVar cut from given cut expression
134 RooFormulaVar select(selExpr, selExpr, _vars, /*checkVariables=*/false);
135 loadValues(&ads,&select);
136 } else {
137 loadValues(&ads);
138 }
139}
140
141
142
143
144////////////////////////////////////////////////////////////////////////////////
145
147 const RooArgSet& vars, const RooFormulaVar* cutVar, const char* cutRange,
148 Int_t nStart, Int_t nStop, const char* wgtVarName) :
149 RooAbsDataStore(name,title,varsNoWeight(vars,wgtVarName)), _defCtor(false),
150 _varsww(vars),
151 _wgtVar(weightVar(vars,wgtVarName))
152{
153 // WVE NEED TO ADJUST THIS FOR WEIGHTS
154
155 // Protected constructor for internal use only
156 _tree = nullptr ;
157 _cacheTree = nullptr ;
158 createTree(makeTreeName(), title);
159
160 // Deep clone cutVar and attach clone to this dataset
161 std::unique_ptr<RooFormulaVar> cloneVar;
162 if (cutVar) {
163 cloneVar.reset(static_cast<RooFormulaVar*>(cutVar->cloneTree()));
164 cloneVar->attachDataStore(tds) ;
165 }
166
167 // Constructor from existing data set with list of variables that preserves the cache
168 initialize();
169
170 attachCache(nullptr,((RooTreeDataStore&)tds)._cachedVars) ;
171
172 // WVE copy values of cached variables here!!!
174 _cacheOwner = nullptr ;
175
176 loadValues(&tds,cloneVar.get(),cutRange,nStart,nStop);
177}
178
179
180std::unique_ptr<RooAbsDataStore> RooTreeDataStore::reduce(RooStringView name, RooStringView title,
181 const RooArgSet& vars, const RooFormulaVar* cutVar, const char* cutRange,
182 std::size_t nStart, std::size_t nStop) {
183 RooArgSet tmp(vars) ;
184 if(_wgtVar && !tmp.contains(*_wgtVar)) {
185 tmp.add(*_wgtVar) ;
186 }
187 const char* wgtVarName = _wgtVar ? _wgtVar->GetName() : nullptr;
188 return std::make_unique<RooTreeDataStore>(name, title, *this, tmp, cutVar, cutRange, nStart, nStop, wgtVarName);
189}
190
191
192////////////////////////////////////////////////////////////////////////////////
193/// Utility function for constructors
194/// Return RooArgSet that is copy of allVars minus variable matching wgtName if specified
195
196RooArgSet RooTreeDataStore::varsNoWeight(const RooArgSet& allVars, const char* wgtName)
197{
198 RooArgSet ret(allVars) ;
199 if(wgtName) {
200 RooAbsArg* wgt = allVars.find(wgtName) ;
201 if (wgt) {
202 ret.remove(*wgt,true,true) ;
203 }
204 }
205 return ret ;
206}
207
208
209
210////////////////////////////////////////////////////////////////////////////////
211/// Utility function for constructors
212/// Return pointer to weight variable if it is defined
213
214RooRealVar* RooTreeDataStore::weightVar(const RooArgSet& allVars, const char* wgtName)
215{
216 if(wgtName) {
217 RooRealVar* wgt = dynamic_cast<RooRealVar*>(allVars.find(wgtName)) ;
218 return wgt ;
219 }
220 return nullptr ;
221}
222
223
224
225
226////////////////////////////////////////////////////////////////////////////////
227/// Initialize cache of dataset: attach variables of cache ArgSet
228/// to the corresponding TTree branches
229
230void RooTreeDataStore::attachCache(const RooAbsArg* newOwner, const RooArgSet& cachedVarsIn)
231{
232 // iterate over the cache variables for this dataset
234 for (RooAbsArg * var : cachedVarsIn) {
235 var->attachToTree(*_cacheTree,_defTreeBufSize) ;
236 _cachedVars.add(*var) ;
237 }
238 _cacheOwner = newOwner ;
239
240}
241
242
243
244
245
246
247////////////////////////////////////////////////////////////////////////////////
248
249RooTreeDataStore::RooTreeDataStore(const RooTreeDataStore& other, const char* newname) :
250 RooAbsDataStore(other,newname),
251 _varsww(other._varsww),
252 _wgtVar(other._wgtVar),
253 _extWgtArray(other._extWgtArray),
254 _extWgtErrLoArray(other._extWgtErrLoArray),
255 _extWgtErrHiArray(other._extWgtErrHiArray),
256 _extSumW2Array(other._extSumW2Array),
257 _curWgt(other._curWgt),
258 _curWgtErrLo(other._curWgtErrLo),
259 _curWgtErrHi(other._curWgtErrHi),
260 _curWgtErr(other._curWgtErr)
261{
262 initialize() ;
263 loadValues(&other) ;
264}
265
266
267////////////////////////////////////////////////////////////////////////////////
268
269RooTreeDataStore::RooTreeDataStore(const RooTreeDataStore& other, const RooArgSet& vars, const char* newname) :
270 RooAbsDataStore(other,varsNoWeight(vars,other._wgtVar?other._wgtVar->GetName():nullptr),newname),
271 _varsww(vars),
272 _wgtVar(other._wgtVar?weightVar(vars,other._wgtVar->GetName()):nullptr),
273 _extWgtArray(other._extWgtArray),
274 _extWgtErrLoArray(other._extWgtErrLoArray),
275 _extWgtErrHiArray(other._extWgtErrHiArray),
276 _extSumW2Array(other._extSumW2Array),
277 _curWgt(other._curWgt),
278 _curWgtErrLo(other._curWgtErrLo),
279 _curWgtErrHi(other._curWgtErrHi),
280 _curWgtErr(other._curWgtErr)
281{
282 initialize() ;
283 loadValues(&other) ;
284}
285
286
287
288
289////////////////////////////////////////////////////////////////////////////////
290/// Destructor
291
293{
294 if (_tree) {
295 delete _tree ;
296 }
297 if (_cacheTree) {
298 delete _cacheTree ;
299 }
300}
301
302
303
304////////////////////////////////////////////////////////////////////////////////
305/// One-time initialization common to all constructor forms. Attach
306/// variables of internal ArgSet to the corresponding TTree branches
307
309{
310 // Recreate (empty) cache tree
312
313 // Attach each variable to the dataset
314 for (auto var : _varsww) {
315 var->attachToTree(*_tree,_defTreeBufSize) ;
316 }
317}
318
319
320
321
322
323////////////////////////////////////////////////////////////////////////////////
324/// Create TTree object that lives in memory, independent of current
325/// location of gDirectory
326
328{
329 if (!_tree) {
330 _tree = new TTree(name.c_str(),title.c_str());
333 _tree->SetDirectory(nullptr);
334 }
335
336 TString pwd(gDirectory->GetPath()) ;
337 TString memDir(gROOT->GetName()) ;
338 memDir.Append(":/") ;
339 bool notInMemNow= (pwd!=memDir) ;
340
341 // cout << "RooTreeData::createTree pwd=" << pwd << " memDir=" << memDir << " notInMemNow = " << (notInMemNow?"T":"F") << endl ;
342
343 if (notInMemNow) {
344 gDirectory->cd(memDir) ;
345 }
346
347 if (!_cacheTree) {
348 _cacheTree = new TTree(TString{name.c_str()} + "_cacheTree", TString{title.c_str()});
349 _cacheTree->SetDirectory(nullptr) ;
350 gDirectory->RecursiveRemove(_cacheTree) ;
351 }
352
353 if (notInMemNow) {
354 gDirectory->cd(pwd) ;
355 }
356
357}
358
359
360
361
362////////////////////////////////////////////////////////////////////////////////
363/// Load values from tree 't' into this data collection, optionally
364/// selecting events using the RooFormulaVar 'select'.
365///
366/// The source tree 't' is cloned to not disturb its branch
367/// structure when retrieving information from it.
368void RooTreeDataStore::loadValues(const TTree *t, const RooFormulaVar* select, const char* /*rangeName*/, Int_t /*nStart*/, Int_t /*nStop*/)
369{
370 // Make our local copy of the tree, so we can safely loop through it.
371 // We need a custom deleter, because if we don't deregister the Tree from the directory
372 // of the original, it tears it down at destruction time!
373 auto deleter = [](TTree* tree){tree->SetDirectory(nullptr); delete tree;};
374 std::unique_ptr<TTree, decltype(deleter)> tClone(static_cast<TTree*>(t->Clone()), deleter);
375 tClone->SetDirectory(t->GetDirectory());
376
377 // Clone list of variables
378 RooArgSet sourceArgSet;
379 _varsww.snapshot(sourceArgSet, false);
380
381 // Check that we have the branches:
382 bool missingBranches = false;
383 for (const auto var : sourceArgSet) {
384 if (!tClone->GetBranch(var->GetName())) {
385 missingBranches = true;
386 coutE(InputArguments) << "Didn't find a branch in Tree '" << tClone->GetName() << "' to read variable '"
387 << var->GetName() << "' from."
388 << "\n\tNote: Name the RooFit variable the same as the branch." << std::endl;
389 }
390 }
391 if (missingBranches) {
392 coutE(InputArguments) << "Cannot import data from TTree '" << tClone->GetName()
393 << "' because some branches are missing !" << std::endl;
394 return;
395 }
396
397 // Attach args in cloned list to cloned source tree
398 for (const auto sourceArg : sourceArgSet) {
399 sourceArg->attachToTree(*tClone,_defTreeBufSize) ;
400 }
401
402 // Redirect formula servers to sourceArgSet
403 std::unique_ptr<RooFormulaVar> selectClone;
404 if (select) {
405 selectClone.reset( static_cast<RooFormulaVar*>(select->cloneTree()) );
406 selectClone->recursiveRedirectServers(sourceArgSet) ;
407 selectClone->setOperMode(RooAbsArg::ADirty,true) ;
408 }
409
410 // Loop over events in source tree
411 Int_t numInvalid(0) ;
412 const Long64_t nevent = tClone->GetEntries();
413 for(Long64_t i=0; i < nevent; ++i) {
414 const auto entryNumber = tClone->GetEntryNumber(i);
415 if (entryNumber<0) break;
416 tClone->GetEntry(entryNumber,1);
417
418 // Copy from source to destination
419 bool allOK(true) ;
420 for (unsigned int j=0; j < sourceArgSet.size(); ++j) {
421 auto destArg = _varsww[j];
422 const auto sourceArg = sourceArgSet[j];
423
424 destArg->copyCache(sourceArg) ;
425 sourceArg->copyCache(destArg) ;
426 if (!destArg->isValid()) {
427 numInvalid++ ;
428 allOK=false ;
429 if (numInvalid < 5) {
430 auto& log = coutI(DataHandling);
431 log << "RooTreeDataStore::loadValues(" << GetName() << ") Skipping event #" << i << " because " << destArg->GetName()
432 << " cannot accommodate the value ";
433 if(sourceArg->isCategory()) {
434 log << static_cast<RooAbsCategory*>(sourceArg)->getCurrentIndex();
435 } else {
436 log << static_cast<RooAbsReal*>(sourceArg)->getVal();
437 }
438 log << std::endl;
439 } else if (numInvalid == 5) {
440 coutI(DataHandling) << "RooTreeDataStore::loadValues(" << GetName() << ") Skipping ..." << std::endl;
441 }
442 break ;
443 }
444 }
445
446 // Does this event pass the cuts?
447 if (!allOK || (selectClone && selectClone->getVal()==0)) {
448 continue ;
449 }
450
451 fill() ;
452 }
453
454 if (numInvalid>0) {
455 coutW(DataHandling) << "RooTreeDataStore::loadValues(" << GetName() << ") Ignored " << numInvalid << " out-of-range events" << endl ;
456 }
457
458 SetTitle(t->GetTitle());
459}
460
461
462
463
464
465
466////////////////////////////////////////////////////////////////////////////////
467/// Load values from dataset 't' into this data collection, optionally
468/// selecting events using 'select' RooFormulaVar
469///
470
472 const char* rangeName, std::size_t nStart, std::size_t nStop)
473{
474 // Redirect formula servers to source data row
475 std::unique_ptr<RooFormulaVar> selectClone;
476 if (select) {
477 selectClone.reset( static_cast<RooFormulaVar*>(select->cloneTree()) );
478 selectClone->recursiveRedirectServers(*ads->get()) ;
479 selectClone->setOperMode(RooAbsArg::ADirty,true) ;
480 }
481
482 // Force RDS internal initialization
483 ads->get(0) ;
484
485 // Loop over events in source tree
486 const auto numEntr = static_cast<std::size_t>(ads->numEntries());
487 std::size_t nevent = nStop < numEntr ? nStop : numEntr;
488
489 auto TDS = dynamic_cast<const RooTreeDataStore*>(ads) ;
490 if (TDS) {
491 const_cast<RooTreeDataStore*>(TDS)->resetBuffers();
492 }
493
494 std::vector<std::string> ranges;
495 if (rangeName) {
496 ranges = ROOT::Split(rangeName, ",");
497 }
498
499 for (auto i=nStart; i < nevent ; ++i) {
500 ads->get(i) ;
501
502 // Does this event pass the cuts?
503 if (selectClone && selectClone->getVal()==0) {
504 continue ;
505 }
506
507
508 if (TDS) {
509 _varsww.assignValueOnly(TDS->_varsww) ;
510 } else {
511 _varsww.assignValueOnly(*ads->get()) ;
512 }
513
514 // Check that all copied values are valid
515 bool allValid = true;
516 for (const auto arg : _varsww) {
517 allValid = arg->isValid() && (ranges.empty() || std::any_of(ranges.begin(), ranges.end(),
518 [arg](const std::string& range){return arg->inRange(range.c_str());}) );
519 if (!allValid)
520 break ;
521 }
522
523 if (!allValid) {
524 continue ;
525 }
526
527 _cachedVars.assign(((RooTreeDataStore*)ads)->_cachedVars) ;
528 fill() ;
529 }
530
531 if (TDS) {
532 const_cast<RooTreeDataStore*>(TDS)->restoreAlternateBuffers();
533 }
534
535 SetTitle(ads->GetTitle());
536}
537
538
539////////////////////////////////////////////////////////////////////////////////
540/// Interface function to TTree::Fill
541
543{
544 return _tree->Fill() ;
545}
546
547
548
549////////////////////////////////////////////////////////////////////////////////
550/// Load the n-th data point (n='index') in memory
551/// and return a pointer to the internal RooArgSet
552/// holding its coordinates.
553
555{
556 checkInit() ;
557
558 Int_t ret = ((RooTreeDataStore*)this)->GetEntry(index, 1) ;
559
560 if(!ret) return nullptr;
561
562 if (_doDirtyProp) {
563 // Raise all dirty flags
564 for (auto var : _vars) {
565 var->setValueDirty(); // This triggers recalculation of all clients
566 }
567
568 for (auto var : _cachedVars) {
569 var->setValueDirty(); // This triggers recalculation of all clients, but doesn't recalculate self
570 var->clearValueDirty();
571 }
572 }
573
574 // Update current weight cache
575 if (_extWgtArray) {
576
577 // If external array is specified use that
582
583 } else if (_wgtVar) {
584
585 // Otherwise look for weight variable
586 _curWgt = _wgtVar->getVal() ;
590
591 } else {
592
593 // Otherwise return 1
594 _curWgt=1.0 ;
595 _curWgtErrLo = 0 ;
596 _curWgtErrHi = 0 ;
597 _curWgtErr = 0 ;
598
599 }
600
601 return &_vars;
602}
603
604
605////////////////////////////////////////////////////////////////////////////////
606/// Return the weight of the n-th data point (n='index') in memory
607
609{
610 return _curWgt ;
611}
612
613
614////////////////////////////////////////////////////////////////////////////////
615
617{
618 if (_extWgtArray) {
619
620 // We have a weight array, use that info
621
622 // Return symmetric error on current bin calculated either from Poisson statistics or from SumOfWeights
623 double lo = 0, hi =0;
624 weightError(lo,hi,etype) ;
625 return (lo+hi)/2 ;
626
627 } else if (_wgtVar) {
628
629 // We have a weight variable, use that info
630 if (_wgtVar->hasAsymError()) {
631 return ( _wgtVar->getAsymErrorHi() - _wgtVar->getAsymErrorLo() ) / 2 ;
632 } else {
633 return _wgtVar->getError() ;
634 }
635
636 } else {
637
638 // We have no weights
639 return 0 ;
640
641 }
642}
643
644
645
646////////////////////////////////////////////////////////////////////////////////
647
648void RooTreeDataStore::weightError(double& lo, double& hi, RooAbsData::ErrorType etype) const
649{
650 if (_extWgtArray) {
651
652 // We have a weight array, use that info
653 switch (etype) {
654
655 case RooAbsData::Auto:
656 throw string(Form("RooDataHist::weightError(%s) error type Auto not allowed here",GetName())) ;
657 break ;
658
660 throw string(Form("RooDataHist::weightError(%s) error type Expected not allowed here",GetName())) ;
661 break ;
662
664 // Weight may be preset or precalculated
665 if (_curWgtErrLo>=0) {
666 lo = _curWgtErrLo ;
667 hi = _curWgtErrHi ;
668 return ;
669 }
670
671 // Otherwise Calculate poisson errors
672 double ym,yp ;
674 lo = weight()-ym ;
675 hi = yp-weight() ;
676 return ;
677
679 lo = _curWgtErr ;
680 hi = _curWgtErr ;
681 return ;
682
683 case RooAbsData::None:
684 lo = 0 ;
685 hi = 0 ;
686 return ;
687 }
688
689 } else if (_wgtVar) {
690
691 // We have a weight variable, use that info
692 if (_wgtVar->hasAsymError()) {
694 lo = _wgtVar->getAsymErrorLo() ;
695 } else {
696 hi = _wgtVar->getError() ;
697 lo = _wgtVar->getError() ;
698 }
699
700 } else {
701
702 // We are unweighted
703 lo=0 ;
704 hi=0 ;
705
706 }
707}
708
709
710////////////////////////////////////////////////////////////////////////////////
711/// Change name of internal observable named 'from' into 'to'
712
713bool RooTreeDataStore::changeObservableName(const char* from, const char* to)
714{
715 // Find observable to be changed
716 RooAbsArg* var = _vars.find(from) ;
717
718 // Check that we found it
719 if (!var) {
720 coutE(InputArguments) << "RooTreeDataStore::changeObservableName(" << GetName() << " no observable " << from << " in this dataset" << endl ;
721 return true ;
722 }
723
724 // Process name change
725 TString oldBranchName = var->cleanBranchName() ;
726 var->SetName(to) ;
727
728 // Change the branch name as well
729 if (_tree->GetBranch(oldBranchName.Data())) {
730
731 // Simple case varName = branchName
732 _tree->GetBranch(oldBranchName.Data())->SetName(var->cleanBranchName().Data()) ;
733
734 // Process any error branch if existing
735 if (_tree->GetBranch(Form("%s_err",oldBranchName.Data()))) {
736 _tree->GetBranch(Form("%s_err",oldBranchName.Data()))->SetName(Form("%s_err",var->cleanBranchName().Data())) ;
737 }
738 if (_tree->GetBranch(Form("%s_aerr_lo",oldBranchName.Data()))) {
739 _tree->GetBranch(Form("%s_aerr_lo",oldBranchName.Data()))->SetName(Form("%s_aerr_lo",var->cleanBranchName().Data())) ;
740 }
741 if (_tree->GetBranch(Form("%s_aerr_hi",oldBranchName.Data()))) {
742 _tree->GetBranch(Form("%s_aerr_hi",oldBranchName.Data()))->SetName(Form("%s_aerr_hi",var->cleanBranchName().Data())) ;
743 }
744
745 } else {
746
747 // Native category case branchNames = varName_idx and varName_lbl
748 if (_tree->GetBranch(Form("%s_idx",oldBranchName.Data()))) {
749 _tree->GetBranch(Form("%s_idx",oldBranchName.Data()))->SetName(Form("%s_idx",var->cleanBranchName().Data())) ;
750 }
751 if (_tree->GetBranch(Form("%s_lbl",oldBranchName.Data()))) {
752 _tree->GetBranch(Form("%s_lbl",oldBranchName.Data()))->SetName(Form("%s_lb",var->cleanBranchName().Data())) ;
753 }
754
755 }
756
757 return false ;
758}
759
760
761
762////////////////////////////////////////////////////////////////////////////////
763/// Add a new column to the data set which holds the pre-calculated values
764/// of 'newVar'. This operation is only meaningful if 'newVar' is a derived
765/// value.
766///
767/// The return value points to the added element holding 'newVar's value
768/// in the data collection. The element is always the corresponding fundamental
769/// type of 'newVar' (e.g. a RooRealVar if 'newVar' is a RooFormulaVar)
770///
771/// Note: This function is explicitly NOT intended as a speed optimization
772/// opportunity for the user. Components of complex PDFs that can be
773/// precalculated with the dataset are automatically identified as such
774/// and will be precalculated when fitting to a dataset
775///
776/// By forcibly precalculating functions with non-trivial Jacobians,
777/// or functions of multiple variables occurring in the data set,
778/// using addColumn(), you may alter the outcome of the fit.
779///
780/// Only in cases where such a modification of fit behaviour is intentional,
781/// this function should be used.
782
784{
785 checkInit() ;
786
787 // Create a fundamental object of the right type to hold newVar values
788 auto valHolder = std::unique_ptr<RooAbsArg>{newVar.createFundamental()}.release();
789 // Sanity check that the holder really is fundamental
790 if(!valHolder->isFundamental()) {
791 coutE(InputArguments) << GetName() << "::addColumn: holder argument is not fundamental: \""
792 << valHolder->GetName() << "\"" << endl;
793 return nullptr;
794 }
795
796 // WVE need to reset TTRee buffers to original datamembers here
797 resetBuffers() ;
798
799 // Clone variable and attach to cloned tree
800 RooAbsArg* newVarClone = newVar.cloneTree() ;
801 newVarClone->recursiveRedirectServers(_vars,false) ;
802
803 // Attach value place holder to this tree
804 ((RooAbsArg*)valHolder)->attachToTree(*_tree,_defTreeBufSize) ;
805 _vars.add(*valHolder) ;
806 _varsww.add(*valHolder) ;
807
808
809 // Fill values of placeholder
810 for (int i=0 ; i<GetEntries() ; i++) {
811 get(i) ;
812
813 newVarClone->syncCache(&_vars) ;
814 valHolder->copyCache(newVarClone) ;
815 valHolder->fillTreeBranch(*_tree) ;
816 }
817
818 // WVE need to restore TTRee buffers to previous values here
820
821 if (adjustRange) {
822// // Set range of valHolder to (just) bracket all values stored in the dataset
823// double vlo,vhi ;
824// RooRealVar* rrvVal = dynamic_cast<RooRealVar*>(valHolder) ;
825// if (rrvVal) {
826// getRange(*rrvVal,vlo,vhi,0.05) ;
827// rrvVal->setRange(vlo,vhi) ;
828// }
829 }
830
831
832
833 delete newVarClone ;
834 return valHolder ;
835}
836
837
838////////////////////////////////////////////////////////////////////////////////
839/// Merge columns of supplied data set(s) with this data set. All
840/// data sets must have equal number of entries. In case of
841/// duplicate columns the column of the last dataset in the list
842/// prevails
843
844RooAbsDataStore* RooTreeDataStore::merge(const RooArgSet& allVars, list<RooAbsDataStore*> dstoreList)
845{
846 RooTreeDataStore* mergedStore = new RooTreeDataStore("merged","merged",allVars) ;
847
848 Int_t nevt = dstoreList.front()->numEntries() ;
849 for (int i=0 ; i<nevt ; i++) {
850
851 // Cope data from self
852 mergedStore->_vars.assign(*get(i)) ;
853
854 // Copy variables from merge sets
855 for (list<RooAbsDataStore*>::iterator iter = dstoreList.begin() ; iter!=dstoreList.end() ; ++iter) {
856 const RooArgSet* partSet = (*iter)->get(i) ;
857 mergedStore->_vars.assign(*partSet) ;
858 }
859
860 mergedStore->fill() ;
861 }
862 return mergedStore ;
863}
864
865
866
867
868
869////////////////////////////////////////////////////////////////////////////////
870
872{
873 Int_t nevt = other.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
888{
889 if (_wgtVar) {
890
891 double sum(0), carry(0);
892 Int_t nevt = numEntries() ;
893 for (int i=0 ; i<nevt ; i++) {
894 get(i) ;
895 // Kahan's algorithm for summing to avoid loss of precision
896 double y = _wgtVar->getVal() - carry;
897 double t = sum + y;
898 carry = (t - sum) - y;
899 sum = t;
900 }
901 return sum ;
902
903 } else if (_extWgtArray) {
904
905 double sum(0) , carry(0);
906 Int_t nevt = numEntries() ;
907 for (int i=0 ; i<nevt ; i++) {
908 // Kahan's algorithm for summing to avoid loss of precision
909 double y = _extWgtArray[i] - carry;
910 double t = sum + y;
911 carry = (t - sum) - y;
912 sum = t;
913 }
914 return sum ;
915
916 } else {
917
918 return numEntries() ;
919
920 }
921}
922
923
924
925
926////////////////////////////////////////////////////////////////////////////////
927
929{
930 return _tree->GetEntries() ;
931}
932
933
934
935////////////////////////////////////////////////////////////////////////////////
936
938{
939 Reset() ;
940}
941
942
943
944////////////////////////////////////////////////////////////////////////////////
945/// Cache given RooAbsArgs with this tree: The tree is
946/// given direct write access of the args internal cache
947/// the args values is pre-calculated for all data points
948/// in this data collection. Upon a get() call, the
949/// internal cache of 'newVar' will be loaded with the
950/// precalculated value and it's dirty flag will be cleared.
951
952void RooTreeDataStore::cacheArgs(const RooAbsArg* owner, RooArgSet& newVarSet, const RooArgSet* nset, bool /*skipZeroWeights*/)
953{
954 checkInit() ;
955
956 _cacheOwner = owner ;
957
958 std::unique_ptr<RooArgSet> constExprVarSet{static_cast<RooArgSet*>(newVarSet.selectByAttrib("ConstantExpression",true))};
959
960 bool doTreeFill = (_cachedVars.empty()) ;
961
962 for (RooAbsArg * arg : *constExprVarSet) {
963 // Attach original newVar to this tree
964 arg->attachToTree(*_cacheTree,_defTreeBufSize) ;
965 //arg->recursiveRedirectServers(_vars) ;
966 _cachedVars.add(*arg) ;
967 }
968
969 // WVE need to reset TTRee buffers to original datamembers here
970 //resetBuffers() ;
971
972 // Refill regular and cached variables of current tree from clone
973 for (int i=0 ; i<GetEntries() ; i++) {
974 get(i) ;
975
976 // Evaluate the cached variables and store the results
977 for (RooAbsArg * arg : *constExprVarSet) {
978 arg->setValueDirty() ;
979 arg->syncCache(nset) ;
980 if (!doTreeFill) {
981 arg->fillTreeBranch(*_cacheTree) ;
982 }
983 }
984
985 if (doTreeFill) {
986 _cacheTree->Fill() ;
987 }
988 }
989
990 // WVE need to restore TTRee buffers to previous values here
991 //restoreAlternateBuffers() ;
992}
993
994
995
996
997////////////////////////////////////////////////////////////////////////////////
998/// Activate or deactivate the branch status of the TTree branch associated
999/// with the given set of dataset observables
1000
1001void RooTreeDataStore::setArgStatus(const RooArgSet& set, bool active)
1002{
1003 for (RooAbsArg * arg : set) {
1004 RooAbsArg* depArg = _vars.find(arg->GetName()) ;
1005 if (!depArg) {
1006 coutE(InputArguments) << "RooTreeDataStore::setArgStatus(" << GetName()
1007 << ") dataset doesn't contain variable " << arg->GetName() << endl ;
1008 continue ;
1009 }
1010 depArg->setTreeBranchStatus(*_tree,active) ;
1011 }
1012}
1013
1014
1015
1016////////////////////////////////////////////////////////////////////////////////
1017/// Remove tree with values of cached observables
1018/// and clear list of cached observables
1019
1021{
1022 // Empty list of cached functions
1024
1025 // Delete & recreate cache tree
1026 delete _cacheTree ;
1027 _cacheTree = nullptr ;
1028 createTree(makeTreeName().c_str(), GetTitle());
1029
1030 return ;
1031}
1032
1033
1034
1035
1036////////////////////////////////////////////////////////////////////////////////
1037
1039{
1041 for (const auto arg : _varsww) {
1042 RooAbsArg* extArg = extObs.find(arg->GetName()) ;
1043 if (extArg) {
1044 if (arg->getAttribute("StoreError")) {
1045 extArg->setAttribute("StoreError") ;
1046 }
1047 if (arg->getAttribute("StoreAsymError")) {
1048 extArg->setAttribute("StoreAsymError") ;
1049 }
1050 extArg->attachToTree(*_tree) ;
1051 _attachedBuffers.add(*extArg) ;
1052 }
1053 }
1054}
1055
1056
1057
1058////////////////////////////////////////////////////////////////////////////////
1059
1061{
1062 for(RooAbsArg * arg : _varsww) {
1063 arg->attachToTree(*_tree) ;
1064 }
1065}
1066
1067
1068
1069////////////////////////////////////////////////////////////////////////////////
1070
1072{
1073 for(RooAbsArg * arg : _attachedBuffers) {
1074 arg->attachToTree(*_tree) ;
1075 }
1076}
1077
1078
1079
1080////////////////////////////////////////////////////////////////////////////////
1081
1083{
1084 if (_defCtor) {
1085 const_cast<RooTreeDataStore*>(this)->initialize() ;
1086 _defCtor = false ;
1087 }
1088}
1089
1090
1091
1092
1093
1094////////////////////////////////////////////////////////////////////////////////
1095/// Interface function to TTree::GetEntries
1096
1098{
1099 return _tree->GetEntries() ;
1100}
1101
1102
1103////////////////////////////////////////////////////////////////////////////////
1104/// Interface function to TTree::Reset
1105
1107{
1108 _tree->Reset(option) ;
1109}
1110
1111
1112////////////////////////////////////////////////////////////////////////////////
1113/// Interface function to TTree::Fill
1114
1116{
1117 return _tree->Fill() ;
1118}
1119
1120
1121////////////////////////////////////////////////////////////////////////////////
1122/// Interface function to TTree::GetEntry
1123
1125{
1126 Int_t ret1 = _tree->GetEntry(entry,getall) ;
1127 if (!ret1) return 0 ;
1128 _cacheTree->GetEntry(entry,getall) ;
1129 return ret1 ;
1130}
1131
1132
1133////////////////////////////////////////////////////////////////////////////////
1134
1136{
1137 _tree->Draw(option) ;
1138}
1139
1140////////////////////////////////////////////////////////////////////////////////
1141/// Stream an object of class RooTreeDataStore.
1142
1144{
1145 if (R__b.IsReading()) {
1146 UInt_t R__s, R__c;
1147 const Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
1148
1149 R__b.ReadClassBuffer(RooTreeDataStore::Class(), this, R__v, R__s, R__c);
1150
1151 if (!_tree) {
1152 // If the tree has not been deserialised automatically, it is time to load
1153 // it now.
1154 TFile* parent = dynamic_cast<TFile*>(R__b.GetParent());
1155 assert(parent);
1156 parent->GetObject(makeTreeName().c_str(), _tree);
1157 }
1158
1159 initialize();
1160
1161 } else {
1162
1163 TTree* tmpTree = _tree;
1164 auto parent = dynamic_cast<TDirectory*>(R__b.GetParent());
1165 if (_tree && parent) {
1166 // Large trees cannot be written because of the 1Gb I/O limitation.
1167 // Here, we take the tree away from our instance, write it, and continue
1168 // to write the rest of the class normally
1169 auto tmpDir = _tree->GetDirectory();
1170
1171 _tree->SetDirectory(parent);
1172 _tree->FlushBaskets(false);
1173 parent->WriteObject(_tree, makeTreeName().c_str());
1174 _tree->SetDirectory(tmpDir);
1175 _tree = nullptr;
1176 }
1177
1179
1180 _tree = tmpTree;
1181 }
1182}
1183
1184////////////////////////////////////////////////////////////////////////////////
1185/// Generate a name for the storage tree from the name and title of this instance.
1187 std::string title = GetTitle();
1188 std::replace(title.begin(), title.end(), ' ', '_');
1189 std::replace(title.begin(), title.end(), '-', '_');
1190 return std::string("RooTreeDataStore_") + GetName() + "_" + title;
1191}
1192
1193
1194////////////////////////////////////////////////////////////////////////////////
1195/// Get the weights of the events in the range [first, first+len).
1196/// This implementation will fill a vector with every event retrieved one by one
1197/// (even if the weight is constant). Then, it returns a span.
1198std::span<const double> RooTreeDataStore::getWeightBatch(std::size_t first, std::size_t len) const {
1199
1200 if (_extWgtArray) {
1201 return {_extWgtArray + first, len};
1202 }
1203
1204 if (!_weightBuffer) {
1205 _weightBuffer = std::make_unique<std::vector<double>>();
1206 _weightBuffer->reserve(len);
1207
1208 for (std::size_t i = 0; i < GetEntries(); ++i) {
1209 _weightBuffer->push_back(weight(i));
1210 }
1211 }
1212
1213 return {_weightBuffer->data() + first, len};
1214}
#define coutI(a)
#define coutW(a)
#define coutE(a)
int Int_t
Definition RtypesCore.h:45
short Version_t
Definition RtypesCore.h:65
long long Long64_t
Definition RtypesCore.h:80
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:377
#define gDirectory
Definition TDirectory.h:384
Option_t Option_t option
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:110
#define hi
#define gROOT
Definition TROOT.h:407
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2467
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:79
bool recursiveRedirectServers(const RooAbsCollection &newServerList, bool mustReplaceAll=false, bool nameChange=false, bool recurseInNewSet=true)
Recursively replace all servers with the new servers in newSet.
virtual void syncCache(const RooArgSet *nset=nullptr)=0
void SetName(const char *name) override
Set the name of the TNamed.
virtual RooFit::OwningPtr< RooAbsArg > createFundamental(const char *newname=nullptr) const =0
Create a fundamental-type object that stores our type of value.
virtual void attachToTree(TTree &t, Int_t bufSize=32000)=0
Overloadable function for derived classes to implement attachment as branch to a TTree.
virtual void setTreeBranchStatus(TTree &t, bool active)=0
virtual RooAbsArg * cloneTree(const char *newname=nullptr) const
Clone tree expression of objects.
TString cleanBranchName() const
Construct a mangled name from the actual name that is free of any math symbols that might be interpre...
void setAttribute(const Text_t *name, bool value=true)
Set (default) or clear a named boolean attribute of this object.
RooAbsCollection * selectByAttrib(const char *name, bool value) const
Create a subset of the current collection, consisting only of those elements with the specified attri...
virtual void removeAll()
Remove all arguments from our set, deleting them if we own them.
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
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.
bool contains(const RooAbsArg &var) const
Check if collection contains an argument with the same name as var.
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...
Storage_t::size_type size() const
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
bool _doDirtyProp
Switch do (de)activate dirty state propagation when loading a data point.
virtual double weight() const =0
virtual Int_t numEntries() const =0
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:103
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition RooArgSet.h:178
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.
bool getPoissonInterval(Int_t n, double &mu1, double &mu2, double nSigma=1) const
Return a confidence interval for the expected number of events given n observed (unweighted) events.
RooRealVar represents a 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:58
bool hasAsymError(bool allowZero=true) const
Definition RooRealVar.h:64
double getAsymErrorHi() const
Definition RooRealVar.h:63
double getAsymErrorLo() const
Definition RooRealVar.h:62
The RooStringView is a wrapper around a C-style string that can also be constructed from a std::strin...
const char * c_str() const
RooTreeDataStore is a 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
Buffer for weights in case a batch of values is requested.
void Draw(Option_t *option="") override
Default Draw method for all objects.
void attachCache(const RooAbsArg *newOwner, const RooArgSet &cachedVars) override
Initialize cache of dataset: attach variables of cache ArgSet to the corresponding TTree branches.
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
Stat_t GetEntries() const
Interface function to TTree::GetEntries.
void attachBuffers(const RooArgSet &extObs) override
Int_t GetEntry(Int_t entry=0, Int_t getall=0)
Interface function to TTree::GetEntry.
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
Object owning cache contents.
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 Reset(Option_t *option=nullptr)
Interface function to TTree::Reset.
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
Int_t Fill()
Interface function to TTree::Fill.
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'.
void resetCache() override
Remove tree with values of cached observables and clear list of cached observables.
void setArgStatus(const RooArgSet &set, bool active) override
Activate or deactivate the branch status of the TTree branch associated with the given set of dataset...
void cacheArgs(const RooAbsArg *owner, RooArgSet &varSet, const RooArgSet *nset=nullptr, bool skipZeroWeights=false) override
Cache given RooAbsArgs with this tree: The tree is given direct write access of the args internal cac...
virtual const RooArgSet * get() const
const RooAbsArg * _cacheOwner
TTree holding the cached function values.
RooArgSet _varsww
Was object constructed with default ctor?
Buffer base class used for serializing objects.
Definition TBuffer.h:43
virtual Version_t ReadVersion(UInt_t *start=nullptr, UInt_t *bcnt=nullptr, const TClass *cl=nullptr)=0
TObject * GetParent() const
Return pointer to parent of this buffer.
Definition TBuffer.cxx:262
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=nullptr)=0
Bool_t IsReading() const
Definition TBuffer.h:86
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
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:212
A ROOT file is composed of a header, followed by consecutive data records (TKey instances) with a wel...
Definition TFile.h:53
TObject * Clone(const char *newname="") const override
Make a clone of an object using the Streamer facility.
Definition TNamed.cxx:74
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:164
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:48
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:140
void ResetBit(UInt_t f)
Definition TObject.h:198
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:62
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition TObject.h:64
Basic string class.
Definition TString.h:139
const char * Data() const
Definition TString.h:380
TString & Append(const char *cs)
Definition TString.h:576
A TTree represents a columnar dataset.
Definition TTree.h:79
virtual Int_t Fill()
Fill all branches.
Definition TTree.cxx:4600
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
Definition TTree.cxx:5291
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:5635
virtual Int_t FlushBaskets(Bool_t 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:5126
void Draw(Option_t *opt) override
Default Draw method for all objects.
Definition TTree.h:431
virtual Long64_t CopyEntries(TTree *tree, Long64_t nentries=-1, Option_t *option="", Bool_t needCopyAddresses=false)
Copy nentries from given tree to this tree.
Definition TTree.cxx:3531
TDirectory * GetDirectory() const
Definition TTree.h:462
virtual void SetDirectory(TDirectory *dir)
Change the tree's directory.
Definition TTree.cxx:8953
virtual Long64_t GetEntries() const
Definition TTree.h:463
virtual void Reset(Option_t *option="")
Reset baskets, buffers and entries count in all branches and leaves.
Definition TTree.cxx:8000
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.
Definition first.py:1
Definition tree.py:1
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2345