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
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 RooFormulaVar *cutVar, const char *cutRange, Int_t nStart, Int_t nStop,
148 const char *wgtVarName)
149 : RooAbsDataStore(name, title, varsNoWeight(vars, wgtVarName)),
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
157 createTree(makeTreeName(), title);
158
159 // Deep clone cutVar and attach clone to this dataset
160 std::unique_ptr<RooFormulaVar> cloneVar;
161 if (cutVar) {
162 cloneVar.reset(static_cast<RooFormulaVar*>(cutVar->cloneTree()));
163 cloneVar->attachDataStore(tds) ;
164 }
165
166 // Constructor from existing data set with list of variables that preserves the cache
167 initialize();
168
169 attachCache(nullptr,(static_cast<RooTreeDataStore&>(tds))._cachedVars) ;
170
171 // WVE copy values of cached variables here!!!
172 _cacheTree->CopyEntries((static_cast<RooTreeDataStore&>(tds))._cacheTree) ;
173 _cacheOwner = nullptr ;
174
175 loadValues(&tds,cloneVar.get(),cutRange,nStart,nStop);
176}
177
178
179std::unique_ptr<RooAbsDataStore> RooTreeDataStore::reduce(RooStringView name, RooStringView title,
180 const RooArgSet& vars, const RooFormulaVar* cutVar, const char* cutRange,
181 std::size_t nStart, std::size_t nStop) {
182 RooArgSet tmp(vars) ;
183 if(_wgtVar && !tmp.contains(*_wgtVar)) {
184 tmp.add(*_wgtVar) ;
185 }
186 const char* wgtVarName = _wgtVar ? _wgtVar->GetName() : nullptr;
187 return std::make_unique<RooTreeDataStore>(name, title, *this, tmp, cutVar, cutRange, nStart, nStop, wgtVarName);
188}
189
190
191////////////////////////////////////////////////////////////////////////////////
192/// Utility function for constructors
193/// Return RooArgSet that is copy of allVars minus variable matching wgtName if specified
194
195RooArgSet RooTreeDataStore::varsNoWeight(const RooArgSet& allVars, const char* wgtName)
196{
197 RooArgSet ret(allVars) ;
198 if(wgtName) {
199 RooAbsArg* wgt = allVars.find(wgtName) ;
200 if (wgt) {
201 ret.remove(*wgt,true,true) ;
202 }
203 }
204 return ret ;
205}
206
207
208
209////////////////////////////////////////////////////////////////////////////////
210/// Utility function for constructors
211/// Return pointer to weight variable if it is defined
212
213RooRealVar* RooTreeDataStore::weightVar(const RooArgSet& allVars, const char* wgtName)
214{
215 if(wgtName) {
216 RooRealVar* wgt = dynamic_cast<RooRealVar*>(allVars.find(wgtName)) ;
217 return wgt ;
218 }
219 return nullptr ;
220}
221
222
223
224
225////////////////////////////////////////////////////////////////////////////////
226/// Initialize cache of dataset: attach variables of cache ArgSet
227/// to the corresponding TTree branches
228
229void RooTreeDataStore::attachCache(const RooAbsArg* newOwner, const RooArgSet& cachedVarsIn)
230{
231 // iterate over the cache variables for this dataset
233 for (RooAbsArg * var : cachedVarsIn) {
234 var->attachToTree(*_cacheTree,_defTreeBufSize) ;
235 _cachedVars.add(*var) ;
236 }
237 _cacheOwner = newOwner ;
238
239}
240
241
242
243
244
245
246////////////////////////////////////////////////////////////////////////////////
247
248RooTreeDataStore::RooTreeDataStore(const RooTreeDataStore& other, const char* newname) :
249 RooAbsDataStore(other,newname),
250 _varsww(other._varsww),
251 _wgtVar(other._wgtVar),
252 _extWgtArray(other._extWgtArray),
253 _extWgtErrLoArray(other._extWgtErrLoArray),
254 _extWgtErrHiArray(other._extWgtErrHiArray),
255 _extSumW2Array(other._extSumW2Array),
256 _curWgt(other._curWgt),
257 _curWgtErrLo(other._curWgtErrLo),
258 _curWgtErrHi(other._curWgtErrHi),
259 _curWgtErr(other._curWgtErr)
260{
261 initialize() ;
262 loadValues(&other) ;
263}
264
265
266////////////////////////////////////////////////////////////////////////////////
267
268RooTreeDataStore::RooTreeDataStore(const RooTreeDataStore& other, const RooArgSet& vars, const char* newname) :
269 RooAbsDataStore(other,varsNoWeight(vars,other._wgtVar?other._wgtVar->GetName():nullptr),newname),
270 _varsww(vars),
271 _wgtVar(other._wgtVar?weightVar(vars,other._wgtVar->GetName()):nullptr),
272 _extWgtArray(other._extWgtArray),
273 _extWgtErrLoArray(other._extWgtErrLoArray),
274 _extWgtErrHiArray(other._extWgtErrHiArray),
275 _extSumW2Array(other._extSumW2Array),
276 _curWgt(other._curWgt),
277 _curWgtErrLo(other._curWgtErrLo),
278 _curWgtErrHi(other._curWgtErrHi),
279 _curWgtErr(other._curWgtErr)
280{
281 initialize() ;
282 loadValues(&other) ;
283}
284
285
286
287
288////////////////////////////////////////////////////////////////////////////////
289/// Destructor
290
292{
293 if (_tree) {
294 delete _tree ;
295 }
296 if (_cacheTree) {
297 delete _cacheTree ;
298 }
299}
300
301
302
303////////////////////////////////////////////////////////////////////////////////
304/// One-time initialization common to all constructor forms. Attach
305/// variables of internal ArgSet to the corresponding TTree branches
306
308{
309 // Recreate (empty) cache tree
311
312 // Attach each variable to the dataset
313 for (auto var : _varsww) {
314 var->attachToTree(*_tree,_defTreeBufSize) ;
315 }
316}
317
318
319
320
321
322////////////////////////////////////////////////////////////////////////////////
323/// Create TTree object that lives in memory, independent of current
324/// location of gDirectory
325
327{
328 if (!_tree) {
329 _tree = new TTree(name.c_str(),title.c_str());
332 _tree->SetDirectory(nullptr);
333 }
334
335 TString pwd(gDirectory->GetPath()) ;
336 TString memDir(gROOT->GetName()) ;
337 memDir.Append(":/") ;
338 bool notInMemNow= (pwd!=memDir) ;
339
340 // cout << "RooTreeData::createTree pwd=" << pwd << " memDir=" << memDir << " notInMemNow = " << (notInMemNow?"T":"F") << endl ;
341
342 if (notInMemNow) {
343 gDirectory->cd(memDir) ;
344 }
345
346 if (!_cacheTree) {
347 _cacheTree = new TTree(TString{name.c_str()} + "_cacheTree", TString{title.c_str()});
348 _cacheTree->SetDirectory(nullptr) ;
349 gDirectory->RecursiveRemove(_cacheTree) ;
350 }
351
352 if (notInMemNow) {
353 gDirectory->cd(pwd) ;
354 }
355
356}
357
358
359
360
361////////////////////////////////////////////////////////////////////////////////
362/// Load values from tree 't' into this data collection, optionally
363/// selecting events using the RooFormulaVar 'select'.
364///
365/// The source tree 't' is cloned to not disturb its branch
366/// structure when retrieving information from it.
367void RooTreeDataStore::loadValues(const TTree *t, const RooFormulaVar* select, const char* /*rangeName*/, Int_t /*nStart*/, Int_t /*nStop*/)
368{
369 // Make our local copy of the tree, so we can safely loop through it.
370 // We need a custom deleter, because if we don't deregister the Tree from the directory
371 // of the original, it tears it down at destruction time!
372 auto deleter = [](TTree* tree){tree->SetDirectory(nullptr); delete tree;};
373 std::unique_ptr<TTree, decltype(deleter)> tClone(static_cast<TTree*>(t->Clone()), deleter);
374 tClone->SetDirectory(t->GetDirectory());
375
376 // Clone list of variables
377 RooArgSet sourceArgSet;
378 _varsww.snapshot(sourceArgSet, false);
379
380 // Check that we have the branches:
381 bool missingBranches = false;
382 for (const auto var : sourceArgSet) {
383 if (!tClone->GetBranch(var->GetName())) {
384 missingBranches = true;
385 coutE(InputArguments) << "Didn't find a branch in Tree '" << tClone->GetName() << "' to read variable '"
386 << var->GetName() << "' from."
387 << "\n\tNote: Name the RooFit variable the same as the branch." << std::endl;
388 }
389 }
390 if (missingBranches) {
391 coutE(InputArguments) << "Cannot import data from TTree '" << tClone->GetName()
392 << "' because some branches are missing !" << std::endl;
393 return;
394 }
395
396 // Attach args in cloned list to cloned source tree
397 for (const auto sourceArg : sourceArgSet) {
398 sourceArg->attachToTree(*tClone,_defTreeBufSize) ;
399 }
400
401 // Redirect formula servers to sourceArgSet
402 std::unique_ptr<RooFormulaVar> selectClone;
403 if (select) {
404 selectClone.reset( static_cast<RooFormulaVar*>(select->cloneTree()) );
405 selectClone->recursiveRedirectServers(sourceArgSet) ;
406 selectClone->setOperMode(RooAbsArg::ADirty,true) ;
407 }
408
409 // Loop over events in source tree
410 Int_t numInvalid(0) ;
411 const Long64_t nevent = tClone->GetEntries();
412 for(Long64_t i=0; i < nevent; ++i) {
413 const auto entryNumber = tClone->GetEntryNumber(i);
414 if (entryNumber<0) break;
415 tClone->GetEntry(entryNumber,1);
416
417 // Copy from source to destination
418 bool allOK(true) ;
419 for (unsigned int j=0; j < sourceArgSet.size(); ++j) {
420 auto destArg = _varsww[j];
421 const auto sourceArg = sourceArgSet[j];
422
423 destArg->copyCache(sourceArg) ;
424 sourceArg->copyCache(destArg) ;
425 if (!destArg->isValid()) {
426 numInvalid++ ;
427 allOK=false ;
428 if (numInvalid < 5) {
429 auto& log = coutI(DataHandling);
430 log << "RooTreeDataStore::loadValues(" << GetName() << ") Skipping event #" << i << " because " << destArg->GetName()
431 << " cannot accommodate the value ";
432 if(sourceArg->isCategory()) {
433 log << static_cast<RooAbsCategory*>(sourceArg)->getCurrentIndex();
434 } else {
435 log << static_cast<RooAbsReal*>(sourceArg)->getVal();
436 }
437 log << std::endl;
438 } else if (numInvalid == 5) {
439 coutI(DataHandling) << "RooTreeDataStore::loadValues(" << GetName() << ") Skipping ..." << std::endl;
440 }
441 break ;
442 }
443 }
444
445 // Does this event pass the cuts?
446 if (!allOK || (selectClone && selectClone->getVal()==0)) {
447 continue ;
448 }
449
450 fill() ;
451 }
452
453 if (numInvalid>0) {
454 coutW(DataHandling) << "RooTreeDataStore::loadValues(" << GetName() << ") Ignored " << numInvalid << " out-of-range events" << endl ;
455 }
456
457 SetTitle(t->GetTitle());
458}
459
460
461
462
463
464
465////////////////////////////////////////////////////////////////////////////////
466/// Load values from dataset 't' into this data collection, optionally
467/// selecting events using 'select' RooFormulaVar
468///
469
471 const char* rangeName, std::size_t nStart, std::size_t nStop)
472{
473 // Redirect formula servers to source data row
474 std::unique_ptr<RooFormulaVar> selectClone;
475 if (select) {
476 selectClone.reset( static_cast<RooFormulaVar*>(select->cloneTree()) );
477 selectClone->recursiveRedirectServers(*ads->get()) ;
478 selectClone->setOperMode(RooAbsArg::ADirty,true) ;
479 }
480
481 // Force RDS internal initialization
482 ads->get(0) ;
483
484 // Loop over events in source tree
485 const auto numEntr = static_cast<std::size_t>(ads->numEntries());
486 std::size_t nevent = nStop < numEntr ? nStop : numEntr;
487
488 auto TDS = dynamic_cast<const RooTreeDataStore*>(ads) ;
489 if (TDS) {
490 const_cast<RooTreeDataStore*>(TDS)->resetBuffers();
491 }
492
493 std::vector<std::string> ranges;
494 if (rangeName) {
495 ranges = ROOT::Split(rangeName, ",");
496 }
497
498 for (auto i=nStart; i < nevent ; ++i) {
499 ads->get(i) ;
500
501 // Does this event pass the cuts?
502 if (selectClone && selectClone->getVal()==0) {
503 continue ;
504 }
505
506
507 if (TDS) {
508 _varsww.assignValueOnly(TDS->_varsww) ;
509 } else {
510 _varsww.assignValueOnly(*ads->get()) ;
511 }
512
513 // Check that all copied values are valid
514 bool allValid = true;
515 for (const auto arg : _varsww) {
516 allValid = arg->isValid() && (ranges.empty() || std::any_of(ranges.begin(), ranges.end(),
517 [arg](const std::string& range){return arg->inRange(range.c_str());}) );
518 if (!allValid)
519 break ;
520 }
521
522 if (!allValid) {
523 continue ;
524 }
525
526 _cachedVars.assign(static_cast<RooTreeDataStore const*>(ads)->_cachedVars) ;
527 fill() ;
528 }
529
530 if (TDS) {
531 const_cast<RooTreeDataStore*>(TDS)->restoreAlternateBuffers();
532 }
533
534 SetTitle(ads->GetTitle());
535}
536
537
538////////////////////////////////////////////////////////////////////////////////
539/// Interface function to TTree::Fill
540
542{
543 return _tree->Fill() ;
544}
545
546
547
548////////////////////////////////////////////////////////////////////////////////
549/// Load the n-th data point (n='index') in memory
550/// and return a pointer to the internal RooArgSet
551/// holding its coordinates.
552
554{
555 checkInit() ;
556
557 Int_t ret = const_cast<RooTreeDataStore*>(this)->GetEntry(index, 1);
558
559 if(!ret) return nullptr;
560
561 if (_doDirtyProp) {
562 // Raise all dirty flags
563 for (auto var : _vars) {
564 var->setValueDirty(); // This triggers recalculation of all clients
565 }
566
567 for (auto var : _cachedVars) {
568 var->setValueDirty(); // This triggers recalculation of all clients, but doesn't recalculate self
569 var->clearValueDirty();
570 }
571 }
572
573 // Update current weight cache
574 if (_extWgtArray) {
575
576 // If external array is specified use that
581
582 } else if (_wgtVar) {
583
584 // Otherwise look for weight variable
585 _curWgt = _wgtVar->getVal() ;
589
590 } else {
591
592 // Otherwise return 1
593 _curWgt=1.0 ;
594 _curWgtErrLo = 0 ;
595 _curWgtErrHi = 0 ;
596 _curWgtErr = 0 ;
597
598 }
599
600 return &_vars;
601}
602
603
604////////////////////////////////////////////////////////////////////////////////
605/// Return the weight of the n-th data point (n='index') in memory
606
608{
609 return _curWgt ;
610}
611
612
613////////////////////////////////////////////////////////////////////////////////
614
616{
617 if (_extWgtArray) {
618
619 // We have a weight array, use that info
620
621 // Return symmetric error on current bin calculated either from Poisson statistics or from SumOfWeights
622 double lo = 0;
623 double 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;
673 double yp;
675 lo = weight()-ym ;
676 hi = yp-weight() ;
677 return ;
678
680 lo = _curWgtErr ;
681 hi = _curWgtErr ;
682 return ;
683
684 case RooAbsData::None:
685 lo = 0 ;
686 hi = 0 ;
687 return ;
688 }
689
690 } else if (_wgtVar) {
691
692 // We have a weight variable, use that info
693 if (_wgtVar->hasAsymError()) {
695 lo = _wgtVar->getAsymErrorLo() ;
696 } else {
697 hi = _wgtVar->getError() ;
698 lo = _wgtVar->getError() ;
699 }
700
701 } else {
702
703 // We are unweighted
704 lo=0 ;
705 hi=0 ;
706
707 }
708}
709
710
711////////////////////////////////////////////////////////////////////////////////
712/// Change name of internal observable named 'from' into 'to'
713
714bool RooTreeDataStore::changeObservableName(const char* from, const char* to)
715{
716 // Find observable to be changed
717 RooAbsArg* var = _vars.find(from) ;
718
719 // Check that we found it
720 if (!var) {
721 coutE(InputArguments) << "RooTreeDataStore::changeObservableName(" << GetName() << " no observable " << from << " in this dataset" << endl ;
722 return true ;
723 }
724
725 // Process name change
726 TString oldBranchName = var->cleanBranchName() ;
727 var->SetName(to) ;
728
729 // Change the branch name as well
730 if (_tree->GetBranch(oldBranchName.Data())) {
731
732 // Simple case varName = branchName
733 _tree->GetBranch(oldBranchName.Data())->SetName(var->cleanBranchName().Data()) ;
734
735 // Process any error branch if existing
736 if (_tree->GetBranch(Form("%s_err",oldBranchName.Data()))) {
737 _tree->GetBranch(Form("%s_err",oldBranchName.Data()))->SetName(Form("%s_err",var->cleanBranchName().Data())) ;
738 }
739 if (_tree->GetBranch(Form("%s_aerr_lo",oldBranchName.Data()))) {
740 _tree->GetBranch(Form("%s_aerr_lo",oldBranchName.Data()))->SetName(Form("%s_aerr_lo",var->cleanBranchName().Data())) ;
741 }
742 if (_tree->GetBranch(Form("%s_aerr_hi",oldBranchName.Data()))) {
743 _tree->GetBranch(Form("%s_aerr_hi",oldBranchName.Data()))->SetName(Form("%s_aerr_hi",var->cleanBranchName().Data())) ;
744 }
745
746 } else {
747
748 // Native category case branchNames = varName_idx and varName_lbl
749 if (_tree->GetBranch(Form("%s_idx",oldBranchName.Data()))) {
750 _tree->GetBranch(Form("%s_idx",oldBranchName.Data()))->SetName(Form("%s_idx",var->cleanBranchName().Data())) ;
751 }
752 if (_tree->GetBranch(Form("%s_lbl",oldBranchName.Data()))) {
753 _tree->GetBranch(Form("%s_lbl",oldBranchName.Data()))->SetName(Form("%s_lb",var->cleanBranchName().Data())) ;
754 }
755
756 }
757
758 return false ;
759}
760
761
762
763////////////////////////////////////////////////////////////////////////////////
764/// Add a new column to the data set which holds the pre-calculated values
765/// of 'newVar'. This operation is only meaningful if 'newVar' is a derived
766/// value.
767///
768/// The return value points to the added element holding 'newVar's value
769/// in the data collection. The element is always the corresponding fundamental
770/// type of 'newVar' (e.g. a RooRealVar if 'newVar' is a RooFormulaVar)
771///
772/// Note: This function is explicitly NOT intended as a speed optimization
773/// opportunity for the user. Components of complex PDFs that can be
774/// precalculated with the dataset are automatically identified as such
775/// and will be precalculated when fitting to a dataset
776///
777/// By forcibly precalculating functions with non-trivial Jacobians,
778/// or functions of multiple variables occurring in the data set,
779/// using addColumn(), you may alter the outcome of the fit.
780///
781/// Only in cases where such a modification of fit behaviour is intentional,
782/// this function should be used.
783
785{
786 checkInit() ;
787
788 // Create a fundamental object of the right type to hold newVar values
789 auto valHolder = std::unique_ptr<RooAbsArg>{newVar.createFundamental()}.release();
790 // Sanity check that the holder really is fundamental
791 if(!valHolder->isFundamental()) {
792 coutE(InputArguments) << GetName() << "::addColumn: holder argument is not fundamental: \""
793 << valHolder->GetName() << "\"" << endl;
794 return nullptr;
795 }
796
797 // WVE need to reset TTRee buffers to original datamembers here
798 resetBuffers() ;
799
800 // Clone variable and attach to cloned tree
801 RooAbsArg* newVarClone = newVar.cloneTree() ;
802 newVarClone->recursiveRedirectServers(_vars,false) ;
803
804 // Attach value place holder to this tree
805 ((RooAbsArg*)valHolder)->attachToTree(*_tree,_defTreeBufSize) ;
806 _vars.add(*valHolder) ;
807 _varsww.add(*valHolder) ;
808
809
810 // Fill values of placeholder
811 for (int i=0 ; i<GetEntries() ; i++) {
812 get(i) ;
813
814 newVarClone->syncCache(&_vars) ;
815 valHolder->copyCache(newVarClone) ;
816 valHolder->fillTreeBranch(*_tree) ;
817 }
818
819 // WVE need to restore TTRee buffers to previous values here
821
822 if (adjustRange) {
823// // Set range of valHolder to (just) bracket all values stored in the dataset
824// double vlo,vhi ;
825// RooRealVar* rrvVal = dynamic_cast<RooRealVar*>(valHolder) ;
826// if (rrvVal) {
827// getRange(*rrvVal,vlo,vhi,0.05) ;
828// rrvVal->setRange(vlo,vhi) ;
829// }
830 }
831
832
833
834 delete newVarClone ;
835 return valHolder ;
836}
837
838
839////////////////////////////////////////////////////////////////////////////////
840/// Merge columns of supplied data set(s) with this data set. All
841/// data sets must have equal number of entries. In case of
842/// duplicate columns the column of the last dataset in the list
843/// prevails
844
845RooAbsDataStore* RooTreeDataStore::merge(const RooArgSet& allVars, list<RooAbsDataStore*> dstoreList)
846{
847 RooTreeDataStore* mergedStore = new RooTreeDataStore("merged","merged",allVars) ;
848
849 Int_t nevt = dstoreList.front()->numEntries() ;
850 for (int i=0 ; i<nevt ; i++) {
851
852 // Cope data from self
853 mergedStore->_vars.assign(*get(i)) ;
854
855 // Copy variables from merge sets
856 for (list<RooAbsDataStore*>::iterator iter = dstoreList.begin() ; iter!=dstoreList.end() ; ++iter) {
857 const RooArgSet* partSet = (*iter)->get(i) ;
858 mergedStore->_vars.assign(*partSet) ;
859 }
860
861 mergedStore->fill() ;
862 }
863 return mergedStore ;
864}
865
866
867
868
869
870////////////////////////////////////////////////////////////////////////////////
871
873{
874 Int_t nevt = other.numEntries() ;
875 for (int i=0 ; i<nevt ; i++) {
876 _vars.assign(*other.get(i)) ;
877 if (_wgtVar) {
878 _wgtVar->setVal(other.weight()) ;
879 }
880
881 fill() ;
882 }
883}
884
885
886////////////////////////////////////////////////////////////////////////////////
887
889{
890 if (_wgtVar) {
891
892 double sum(0);
893 double carry(0);
894 Int_t nevt = numEntries() ;
895 for (int i=0 ; i<nevt ; i++) {
896 get(i) ;
897 // Kahan's algorithm for summing to avoid loss of precision
898 double y = _wgtVar->getVal() - carry;
899 double t = sum + y;
900 carry = (t - sum) - y;
901 sum = t;
902 }
903 return sum ;
904
905 } else if (_extWgtArray) {
906
907 double sum(0);
908 double carry(0);
909 Int_t nevt = numEntries() ;
910 for (int i=0 ; i<nevt ; i++) {
911 // Kahan's algorithm for summing to avoid loss of precision
912 double y = _extWgtArray[i] - carry;
913 double t = sum + y;
914 carry = (t - sum) - y;
915 sum = t;
916 }
917 return sum ;
918
919 } else {
920
921 return numEntries() ;
922
923 }
924}
925
926
927
928
929////////////////////////////////////////////////////////////////////////////////
930
932{
933 return _tree->GetEntries() ;
934}
935
936
937
938////////////////////////////////////////////////////////////////////////////////
939
941{
942 Reset() ;
943}
944
945
946
947////////////////////////////////////////////////////////////////////////////////
948/// Cache given RooAbsArgs with this tree: The tree is
949/// given direct write access of the args internal cache
950/// the args values is pre-calculated for all data points
951/// in this data collection. Upon a get() call, the
952/// internal cache of 'newVar' will be loaded with the
953/// precalculated value and it's dirty flag will be cleared.
954
955void RooTreeDataStore::cacheArgs(const RooAbsArg* owner, RooArgSet& newVarSet, const RooArgSet* nset, bool /*skipZeroWeights*/)
956{
957 checkInit() ;
958
959 _cacheOwner = owner ;
960
961 std::unique_ptr<RooArgSet> constExprVarSet{static_cast<RooArgSet*>(newVarSet.selectByAttrib("ConstantExpression",true))};
962
963 bool doTreeFill = (_cachedVars.empty()) ;
964
965 for (RooAbsArg * arg : *constExprVarSet) {
966 // Attach original newVar to this tree
967 arg->attachToTree(*_cacheTree,_defTreeBufSize) ;
968 //arg->recursiveRedirectServers(_vars) ;
969 _cachedVars.add(*arg) ;
970 }
971
972 // WVE need to reset TTRee buffers to original datamembers here
973 //resetBuffers() ;
974
975 // Refill regular and cached variables of current tree from clone
976 for (int i=0 ; i<GetEntries() ; i++) {
977 get(i) ;
978
979 // Evaluate the cached variables and store the results
980 for (RooAbsArg * arg : *constExprVarSet) {
981 arg->setValueDirty() ;
982 arg->syncCache(nset) ;
983 if (!doTreeFill) {
984 arg->fillTreeBranch(*_cacheTree) ;
985 }
986 }
987
988 if (doTreeFill) {
989 _cacheTree->Fill() ;
990 }
991 }
992
993 // WVE need to restore TTRee buffers to previous values here
994 //restoreAlternateBuffers() ;
995}
996
997
998
999
1000////////////////////////////////////////////////////////////////////////////////
1001/// Activate or deactivate the branch status of the TTree branch associated
1002/// with the given set of dataset observables
1003
1004void RooTreeDataStore::setArgStatus(const RooArgSet& set, bool active)
1005{
1006 for (RooAbsArg * arg : set) {
1007 RooAbsArg* depArg = _vars.find(arg->GetName()) ;
1008 if (!depArg) {
1009 coutE(InputArguments) << "RooTreeDataStore::setArgStatus(" << GetName()
1010 << ") dataset doesn't contain variable " << arg->GetName() << endl ;
1011 continue ;
1012 }
1013 depArg->setTreeBranchStatus(*_tree,active) ;
1014 }
1015}
1016
1017
1018
1019////////////////////////////////////////////////////////////////////////////////
1020/// Remove tree with values of cached observables
1021/// and clear list of cached observables
1022
1024{
1025 // Empty list of cached functions
1027
1028 // Delete & recreate cache tree
1029 delete _cacheTree ;
1030 _cacheTree = nullptr ;
1031 createTree(makeTreeName().c_str(), GetTitle());
1032
1033 return ;
1034}
1035
1036
1037
1038
1039////////////////////////////////////////////////////////////////////////////////
1040
1042{
1044 for (const auto arg : _varsww) {
1045 RooAbsArg* extArg = extObs.find(arg->GetName()) ;
1046 if (extArg) {
1047 if (arg->getAttribute("StoreError")) {
1048 extArg->setAttribute("StoreError") ;
1049 }
1050 if (arg->getAttribute("StoreAsymError")) {
1051 extArg->setAttribute("StoreAsymError") ;
1052 }
1053 extArg->attachToTree(*_tree) ;
1054 _attachedBuffers.add(*extArg) ;
1055 }
1056 }
1057}
1058
1059
1060
1061////////////////////////////////////////////////////////////////////////////////
1062
1064{
1065 for(RooAbsArg * arg : _varsww) {
1066 arg->attachToTree(*_tree) ;
1067 }
1068}
1069
1070
1071
1072////////////////////////////////////////////////////////////////////////////////
1073
1075{
1076 for(RooAbsArg * arg : _attachedBuffers) {
1077 arg->attachToTree(*_tree) ;
1078 }
1079}
1080
1081
1082
1083////////////////////////////////////////////////////////////////////////////////
1084
1086{
1087 if (_defCtor) {
1088 const_cast<RooTreeDataStore*>(this)->initialize() ;
1089 _defCtor = false ;
1090 }
1091}
1092
1093
1094
1095
1096
1097////////////////////////////////////////////////////////////////////////////////
1098/// Interface function to TTree::GetEntries
1099
1101{
1102 return _tree->GetEntries() ;
1103}
1104
1105
1106////////////////////////////////////////////////////////////////////////////////
1107/// Interface function to TTree::Reset
1108
1110{
1111 _tree->Reset(option) ;
1112}
1113
1114
1115////////////////////////////////////////////////////////////////////////////////
1116/// Interface function to TTree::Fill
1117
1119{
1120 return _tree->Fill() ;
1121}
1122
1123
1124////////////////////////////////////////////////////////////////////////////////
1125/// Interface function to TTree::GetEntry
1126
1128{
1129 Int_t ret1 = _tree->GetEntry(entry,getall) ;
1130 if (!ret1) return 0 ;
1131 _cacheTree->GetEntry(entry,getall) ;
1132 return ret1 ;
1133}
1134
1135
1136////////////////////////////////////////////////////////////////////////////////
1137
1139{
1140 _tree->Draw(option) ;
1141}
1142
1143////////////////////////////////////////////////////////////////////////////////
1144/// Stream an object of class RooTreeDataStore.
1145
1147{
1148 if (R__b.IsReading()) {
1149 UInt_t R__s;
1150 UInt_t R__c;
1151 const Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
1152
1153 R__b.ReadClassBuffer(RooTreeDataStore::Class(), this, R__v, R__s, R__c);
1154
1155 if (!_tree) {
1156 // If the tree has not been deserialised automatically, it is time to load
1157 // it now.
1158 TFile* parent = dynamic_cast<TFile*>(R__b.GetParent());
1159 assert(parent);
1160 parent->GetObject(makeTreeName().c_str(), _tree);
1161 }
1162
1163 initialize();
1164
1165 } else {
1166
1167 TTree* tmpTree = _tree;
1168 auto parent = dynamic_cast<TDirectory*>(R__b.GetParent());
1169 if (_tree && parent) {
1170 // Large trees cannot be written because of the 1Gb I/O limitation.
1171 // Here, we take the tree away from our instance, write it, and continue
1172 // to write the rest of the class normally
1173 auto tmpDir = _tree->GetDirectory();
1174
1175 _tree->SetDirectory(parent);
1176 _tree->FlushBaskets(false);
1177 parent->WriteObject(_tree, makeTreeName().c_str());
1178 _tree->SetDirectory(tmpDir);
1179 _tree = nullptr;
1180 }
1181
1183
1184 _tree = tmpTree;
1185 }
1186}
1187
1188////////////////////////////////////////////////////////////////////////////////
1189/// Generate a name for the storage tree from the name and title of this instance.
1191 std::string title = GetTitle();
1192 std::replace(title.begin(), title.end(), ' ', '_');
1193 std::replace(title.begin(), title.end(), '-', '_');
1194 return std::string("RooTreeDataStore_") + GetName() + "_" + title;
1195}
1196
1197
1198////////////////////////////////////////////////////////////////////////////////
1199/// Get the weights of the events in the range [first, first+len).
1200/// This implementation will fill a vector with every event retrieved one by one
1201/// (even if the weight is constant). Then, it returns a span.
1202std::span<const double> RooTreeDataStore::getWeightBatch(std::size_t first, std::size_t len) const {
1203
1204 if (_extWgtArray) {
1205 return {_extWgtArray + first, len};
1206 }
1207
1208 if (!_weightBuffer) {
1209 _weightBuffer = std::make_unique<std::vector<double>>();
1210 _weightBuffer->reserve(len);
1211
1212 for (std::size_t i = 0; i < GetEntries(); ++i) {
1213 _weightBuffer->push_back(weight(i));
1214 }
1215 }
1216
1217 return {_weightBuffer->data() + first, len};
1218}
#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:406
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2489
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:77
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.
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.
Abstract base class for a data collection.
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.
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
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:200
@ 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:376
TString & Append(const char *cs)
Definition TString.h:572
A TTree represents a columnar dataset.
Definition TTree.h:79
virtual Int_t Fill()
Fill all branches.
Definition TTree.cxx:4603
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
Definition TTree.cxx:5294
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:5129
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:5638
void Draw(Option_t *opt) override
Default Draw method for all objects.
Definition TTree.h:431
TDirectory * GetDirectory() const
Definition TTree.h:462
virtual void SetDirectory(TDirectory *dir)
Change the tree's directory.
Definition TTree.cxx:8956
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:8003
virtual Long64_t CopyEntries(TTree *tree, Long64_t nentries=-1, Option_t *option="", bool needCopyAddresses=false)
Copy nentries from given tree to this tree.
Definition TTree.cxx:3534
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:2345