Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TTreeReader.cxx
Go to the documentation of this file.
1// @(#)root/treeplayer:$Id$
2// Author: Axel Naumann, 2011-09-21
3
4/*************************************************************************
5 * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers and al. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include "TTreeReader.h"
13
14#include "TChain.h"
15#include "TDirectory.h"
16#include "TEntryList.h"
17#include "TTreeCache.h"
18#include "TTreeReaderValue.h"
19#include "TFriendProxy.h"
20
21
22// clang-format off
23/**
24 \class TTreeReader
25 \ingroup treeplayer
26 \brief A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree, TChain or TNtuple
27
28 TTreeReader is associated to TTreeReaderValue and TTreeReaderArray which are handles to concretely
29 access the information in the dataset.
30
31 Example code can be found in
32 - tutorials/tree/hsimpleReader.C
33 - tutorials/tree/h1analysisTreeReader.C
34 - <a href="https://github.com/root-project/roottest/tree/master/root/tree/reader">This example</a>
35
36 You can generate a skeleton of `TTreeReaderValue<T>` and `TTreeReaderArray<T>` declarations
37 for all of a tree's branches using `TTree::MakeSelector()`.
38
39 Roottest contains an
40 <a href="https://github.com/root-project/roottest/tree/master/root/tree/reader">example</a>
41 showing the full power.
42
43A simpler analysis example can be found below: it histograms a function of the px and py branches.
44
45~~~{.cpp}
46// A simple TTreeReader use: read data from hsimple.root (written by hsimple.C)
47
48#include "TFile.h"
49#include "TH1F.h"
50#include "TTreeReader.h"
51#include "TTreeReaderValue.h"
52
53void hsimpleReader() {
54 // Create a histogram for the values we read.
55 TH1F("h1", "ntuple", 100, -4, 4);
56
57 // Open the file containing the tree.
58 TFile *myFile = TFile::Open("$ROOTSYS/tutorials/hsimple.root");
59
60 // Create a TTreeReader for the tree, for instance by passing the
61 // TTree's name and the TDirectory / TFile it is in.
62 TTreeReader myReader("ntuple", myFile);
63
64 // The branch "px" contains floats; access them as myPx.
65 TTreeReaderValue<Float_t> myPx(myReader, "px");
66 // The branch "py" contains floats, too; access those as myPy.
67 TTreeReaderValue<Float_t> myPy(myReader, "py");
68
69 // Loop over all entries of the TTree or TChain.
70 while (myReader.Next()) {
71 // Just access the data as if myPx and myPy were iterators (note the '*'
72 // in front of them):
73 myHist->Fill(*myPx + *myPy);
74 }
75
76 myHist->Draw();
77}
78~~~
79
80A more complete example including error handling and a few combinations of
81TTreeReaderValue and TTreeReaderArray would look like this:
82
83~~~{.cpp}
84#include <TFile.h>
85#include <TH1.h>
86#include <TTreeReader.h>
87#include <TTreeReaderValue.h>
88#include <TTreeReaderArray.h>
89
90#include "TriggerInfo.h"
91#include "Muon.h"
92#include "Tau.h"
93
94#include <vector>
95#include <iostream>
96
97bool CheckValue(ROOT::Internal::TTreeReaderValueBase& value) {
98 if (value.GetSetupStatus() < 0) {
99 std::cerr << "Error " << value.GetSetupStatus()
100 << "setting up reader for " << value.GetBranchName() << '\n';
101 return false;
102 }
103 return true;
104}
105
106
107// Analyze the tree "MyTree" in the file passed into the function.
108// Returns false in case of errors.
109bool analyze(TFile* file) {
110 // Create a TTreeReader named "MyTree" from the given TDirectory.
111 // The TTreeReader gives access to the TTree to the TTreeReaderValue and
112 // TTreeReaderArray objects. It knows the current entry number and knows
113 // how to iterate through the TTree.
114 TTreeReader reader("MyTree", file);
115
116 // Read a single float value in each tree entries:
117 TTreeReaderValue<float> weight(reader, "event.weight");
118
119 // Read a TriggerInfo object from the tree entries:
120 TTreeReaderValue<TriggerInfo> triggerInfo(reader, "triggerInfo");
121
122 //Read a vector of Muon objects from the tree entries:
123 TTreeReaderValue<std::vector<Muon>> muons(reader, "muons");
124
125 //Read the pT for all jets in the tree entry:
126 TTreeReaderArray<double> jetPt(reader, "jets.pT");
127
128 // Read the taus in the tree entry:
129 TTreeReaderArray<Tau> taus(reader, "taus");
130
131
132 // Now iterate through the TTree entries and fill a histogram.
133
134 TH1F("hist", "TTreeReader example histogram", 10, 0., 100.);
135
136 bool firstEntry = true;
137 while (reader.Next()) {
138 if (firstEntry) {
139 // Check that branches exist and their types match our expectation.
140 if (!CheckValue(weight)) return false;
141 if (!CheckValue(triggerInfo)) return false;
142 if (!CheckValue(muons)) return false;
143 if (!CheckValue(jetPt)) return false;
144 if (!CheckValue(taus)) return false;
145 firstentry = false;
146 }
147
148 // Access the TriggerInfo object as if it's a pointer.
149 if (!triggerInfo->hasMuonL1())
150 continue;
151
152 // Ditto for the vector<Muon>.
153 if (!muons->size())
154 continue;
155
156 // Access the jetPt as an array, whether the TTree stores this as
157 // a std::vector, std::list, TClonesArray or Jet* C-style array, with
158 // fixed or variable array size.
159 if (jetPt.GetSize() < 2 || jetPt[0] < 100)
160 continue;
161
162 // Access the array of taus.
163 if (!taus.IsEmpty()) {
164 // Access a float value - need to dereference as TTreeReaderValue
165 // behaves like an iterator
166 float currentWeight = *weight;
167 for (const Tau& tau: taus) {
168 hist->Fill(tau.eta(), currentWeight);
169 }
170 }
171 } // TTree entry / event loop
172
173 // Return true if we have iterated through all entries.
174 return reader.GetEntryStatus() == TTreeReader::kEntryBeyondEnd;
175}
176~~~
177*/
178// clang-format on
179
181
182using namespace ROOT::Internal;
183
184// Provide some storage for the poor little symbol.
186
187////////////////////////////////////////////////////////////////////////////////
188/// Default constructor. Call SetTree to connect to a TTree.
189
190TTreeReader::TTreeReader() : fNotify(this) {}
191
192////////////////////////////////////////////////////////////////////////////////
193/// Access data from tree.
194///
195/// \param tree The TTree or TChain to read from
196/// \param entryList It can be a single TEntryList with global entry numbers (supported, as
197/// an extension, also in the case of a TChain) or, if the first parameter
198/// is a TChain, a TEntryList with sub-TEntryLists with local entry numbers.
199/// In the latter case, the TEntryList must be associated to the TChain, as
200/// per chain.SetEntryList(&entryList).
201
202TTreeReader::TTreeReader(TTree* tree, TEntryList* entryList /*= nullptr*/):
203 fTree(tree),
204 fEntryList(entryList),
205 fNotify(this)
206{
207 if (!fTree) {
208 ::Error("TTreeReader::TTreeReader", "TTree is NULL!");
209 } else {
210 Initialize();
211 }
212}
213
214////////////////////////////////////////////////////////////////////////////////
215/// Access data from the tree called keyname in the directory (e.g. TFile)
216/// dir, or the current directory if dir is NULL. If keyname cannot be
217/// found, or if it is not a TTree, IsInvalid() will return true.
218///
219/// \param keyname The name of the TTree to read from file
220/// \param dir The TDirectory to read keyname from
221/// \param entryList It can be a single TEntryList with global entry numbers (supported, as
222/// an extension, also in the case of a TChain) or, if the first parameter
223/// is a TChain, a TEntryList with sub-TEntryLists with local entry numbers.
224/// In the latter case, the TEntryList must be associated to the TChain, as
225/// per chain.SetEntryList(&entryList).
226
227TTreeReader::TTreeReader(const char* keyname, TDirectory* dir, TEntryList* entryList /*= nullptr*/):
228 fEntryList(entryList),
229 fNotify(this)
230{
231 if (!dir) dir = gDirectory;
232 dir->GetObject(keyname, fTree);
233 if (!fTree) {
234 std::string msg = "No TTree called ";
235 msg += keyname;
236 msg += " was found in the selected TDirectory.";
237 Error("TTreeReader", "%s", msg.c_str());
238 }
239 Initialize();
240}
241
242////////////////////////////////////////////////////////////////////////////////
243/// Tell all value readers that the tree reader does not exist anymore.
244
246{
247 for (std::deque<ROOT::Internal::TTreeReaderValueBase*>::const_iterator
248 i = fValues.begin(), e = fValues.end(); i != e; ++i) {
249 (*i)->MarkTreeReaderUnavailable();
250 }
251 if (fTree && fNotify.IsLinked())
253
254 // Need to clear the map of proxies before deleting the director otherwise
255 // they will have a dangling pointer.
256 fProxies.clear();
257
258 for (auto feproxy: fFriendProxies) {
259 delete feproxy;
260 }
261 fFriendProxies.clear();
262
263 delete fDirector;
264}
265
266////////////////////////////////////////////////////////////////////////////////
267/// Initialization of the director.
268
270{
271 fEntry = -1;
272 if (!fTree) {
275 return;
276 }
277
279 if (fTree->InheritsFrom(TChain::Class())) {
281 } else if (fEntryList && fEntryList->GetLists()) {
282 Error("Initialize", "We are not processing a TChain but the TEntryList contains sublists. Please "
283 "provide a simple TEntryList with no sublists instead.");
286 return;
287 }
288
290
291 if (!fNotify.IsLinked()) {
293
294 if (fTree->GetTree()) {
295 // The current TTree is already available.
297 Notify();
299 }
300 }
301}
302
303////////////////////////////////////////////////////////////////////////////////
304/// Callback from TChain and TTree's LoadTree.
305
307{
308
311 // This can happen if someone switched trees behind us.
312 // Likely cause: a TChain::LoadTree() e.g. from TTree::Process().
313 // This means that "local" should be set!
314 // There are two entities switching trees which is bad.
315 Warning("SetEntryBase()",
316 "The current tree in the TChain %s has changed (e.g. by TTree::Process) "
317 "even though TTreeReader::SetEntry() was called, which switched the tree "
318 "again. Did you mean to call TTreeReader::SetLocalEntry()?",
319 fTree->GetName());
320 }
322 } else {
324 }
325
327 Warning("SetEntryBase()",
328 "The TTree / TChain has an associated TEntryList. "
329 "TTreeReader ignores TEntryLists unless you construct the TTreeReader passing a TEntryList.");
331 }
332
333 if (!fDirector->Notify()) {
334 Error("SetEntryBase()", "There was an error while notifying the proxies.");
335 return false;
336 }
337
338 if (fProxiesSet) {
339 for (auto value: fValues) {
340 value->NotifyNewTree(fTree->GetTree());
341 }
342 }
343
344 return kTRUE;
345}
346
347////////////////////////////////////////////////////////////////////////////////
348/// Tell readers we now have a tree.
349/// fValues gets insertions during this loop (when parametrized arrays are read),
350/// invalidating iterators. Use old-school counting instead.
351
353
354 for (size_t i = 0; i < fValues.size(); ++i) {
356 reader->CreateProxy();
357 if (!reader->GetProxy()){
358 return kFALSE;
359 }
360
361 }
362 // If at least one proxy was there and no error occurred, we assume the proxies to be set.
363 fProxiesSet = !fValues.empty();
364
365 // Now we need to properly set the TTreeCache. We do this in steps:
366 // 1. We set the entry range according to the entry range of the TTreeReader
367 // 2. We add to the cache the branches identifying them by the name the user provided
368 // upon creation of the TTreeReader{Value, Array}s
369 // 3. We stop the learning phase.
370 // Operations 1, 2 and 3 need to happen in this order. See: https://sft.its.cern.ch/jira/browse/ROOT-9773?focusedCommentId=87837
371 if (fProxiesSet) {
372 const auto curFile = fTree->GetCurrentFile();
373 if (curFile && fTree->GetTree()->GetReadCache(curFile, true)) {
374 if (!(-1LL == fEndEntry && 0ULL == fBeginEntry)) {
375 // We need to avoid to pass -1 as end entry to the SetCacheEntryRange method
376 const auto lastEntry = (-1LL == fEndEntry) ? fTree->GetEntriesFast() : fEndEntry;
378 }
379 for (auto value: fValues) {
380 fTree->AddBranchToCache(value->GetProxy()->GetBranchName(), true);
381 }
383 }
384 }
385
386 return kTRUE;
387}
388
389////////////////////////////////////////////////////////////////////////////////
390/// Set the range of entries to be loaded by `Next()`; end will not be loaded.
391///
392/// If end <= begin, `end` is ignored (set to `-1`, i.e. will run on all entries from `begin` onwards).
393///
394/// Example:
395///
396/// ~~~ {.cpp}
397/// reader.SetEntriesRange(3, 5);
398/// while (reader.Next()) {
399/// // Will load entries 3 and 4.
400/// }
401/// ~~~
402///
403/// Note that if a TEntryList is present, beginEntry and endEntry refer to the beginEntry-th/endEntry-th entries of the
404/// TEntryList (or the main TEntryList in case it has sub-entrylists). In other words, SetEntriesRange can
405/// be used to only loop over part of the TEntryList, but not to further restrict the actual TTree/TChain entry numbers
406/// considered.
407///
408/// \param beginEntry The first entry to be loaded by `Next()`.
409/// \param endEntry The entry where `Next()` will return kFALSE, not loading it.
410
412{
413 if (beginEntry < 0)
414 return kEntryNotFound;
415 // Complain if the entries number is larger than the tree's / chain's / entry
416 // list's number of entries, unless it's a TChain and "max entries" is
417 // uninitialized (i.e. TTree::kMaxEntries).
418 if (beginEntry >= GetEntries(false) && !(IsChain() && GetEntries(false) == TTree::kMaxEntries)) {
419 Error("SetEntriesRange()", "first entry out of range 0..%lld", GetEntries(false));
420 return kEntryNotFound;
421 }
422
423 // Update data members to correctly reflect the defined range
424 if (endEntry > beginEntry)
425 fEndEntry = endEntry;
426 else
427 fEndEntry = -1;
428
429 fBeginEntry = beginEntry;
430
431 if (beginEntry - 1 < 0)
432 // Reset the cache if reading from the first entry of the tree
433 Restart();
434 else {
435 // Load the first entry in the range. SetEntry() will also call SetProxies(),
436 // thus adding all the branches to the cache and triggering the learning phase.
437 EEntryStatus es = SetEntry(beginEntry - 1);
438 if (es != kEntryValid) {
439 Error("SetEntriesRange()", "Error setting first entry %lld: %s",
440 beginEntry, fgEntryStatusText[(int)es]);
441 return es;
442 }
443 }
444
445 return kEntryValid;
446}
447
450 fProxiesSet = false; // we might get more value readers, meaning new proxies.
451 fEntry = -1;
452 if (const auto curFile = fTree->GetCurrentFile()) {
453 if (auto tc = fTree->GetTree()->GetReadCache(curFile, true)) {
454 tc->DropBranch("*", true);
455 tc->ResetCache();
456 }
457 }
458}
459
460////////////////////////////////////////////////////////////////////////////////
461/// Returns the number of entries of the TEntryList if one is provided, else
462/// of the TTree / TChain, independent of a range set by SetEntriesRange()
463/// by calling TTree/TChain::GetEntriesFast.
464
465
467 if (fEntryList)
468 return fEntryList->GetN();
469 if (!fTree)
470 return -1;
471 return fTree->GetEntriesFast();
472}
473
474
475////////////////////////////////////////////////////////////////////////////////
476/// Returns the number of entries of the TEntryList if one is provided, else
477/// of the TTree / TChain, independent of a range set by SetEntriesRange().
478///
479/// \param force If `IsChain()` and `force`, determines whether all TFiles of
480/// this TChain should be opened to determine the exact number of entries
481/// of the TChain. If `!IsChain()`, `force` is ignored.
482
484 if (fEntryList)
485 return fEntryList->GetN();
486 if (!fTree)
487 return -1;
488 if (force) {
490 auto res = fTree->GetEntries();
491 // Go back to where we were:
494 return res;
495 }
496 return fTree->GetEntriesFast();
497}
498
499
500
501////////////////////////////////////////////////////////////////////////////////
502/// Load an entry into the tree, return the status of the read.
503/// For chains, entry is the global (i.e. not tree-local) entry number, unless
504/// `local` is `true`, in which case `entry` specifies the entry number within
505/// the current tree. This is needed for instance for TSelector::Process().
506
508{
509 if (IsInvalid()) {
511 fEntry = -1;
512 return fEntryStatus;
513 }
514
515 fEntry = entry;
516
517 Long64_t entryAfterList = entry;
518 if (fEntryList) {
519 if (entry >= fEntryList->GetN()) {
520 // Passed the end of the chain, Restart() was not called:
521 // don't try to load entries anymore. Can happen in these cases:
522 // while (tr.Next()) {something()};
523 // while (tr.Next()) {somethingelse()}; // should not be calling somethingelse().
525 return fEntryStatus;
526 }
527 if (entry >= 0) {
528 if (fEntryList->GetLists()) {
530 int treenum = -1;
531 entryAfterList = fEntryList->GetEntryAndTree(entry, treenum);
532 entryAfterList += static_cast<TChain *>(fTree)->GetTreeOffset()[treenum];
533 // We always translate local entry numbers to global entry numbers for TChain+TEntryList with sublists
534 local = false;
535 } else {
536 // Could be a TTree or a TChain (TTreeReader also supports single TEntryLists for TChains).
537 // In both cases, we are using the global entry numbers coming from the single TEntryList.
538 entryAfterList = fEntryList->GetEntry(entry);
539 }
540 }
541 }
542
543 TTree* treeToCallLoadOn = local ? fTree->GetTree() : fTree;
544
546 const Long64_t loadResult = treeToCallLoadOn->LoadTree(entryAfterList);
548
549 if (loadResult < 0) {
550 // ROOT-9628 We cover here the case when:
551 // - We deal with a TChain
552 // - The last file is opened
553 // - The TTree is not correctly loaded
554 // The system is robust against issues with TTrees associated to the chain
555 // when they are not at the end of it.
556 if (loadResult == -3 && TestBit(kBitIsChain) && !fTree->GetTree()) {
557 fDirector->Notify();
558 if (fProxiesSet) {
559 for (auto value: fValues) {
560 value->NotifyNewTree(fTree->GetTree());
561 }
562 }
563 Warning("SetEntryBase()",
564 "There was an issue opening the last file associated to the TChain "
565 "being processed.");
567 return fEntryStatus;
568 }
569
570 if (loadResult == -2) {
571 fDirector->Notify();
572 if (fProxiesSet) {
573 for (auto value: fValues) {
574 value->NotifyNewTree(fTree->GetTree());
575 }
576 }
578 return fEntryStatus;
579 }
580
581 if (loadResult == -1) {
582 // The chain is empty
584 return fEntryStatus;
585 }
586
587 if (loadResult == -4) {
588 // The TChainElement corresponding to the entry is missing or
589 // the TTree is missing from the file.
590 fDirector->Notify();
591 if (fProxiesSet) {
592 for (auto value: fValues) {
593 value->NotifyNewTree(fTree->GetTree());
594 }
595 }
597 return fEntryStatus;
598 }
599
600 Warning("SetEntryBase()",
601 "Unexpected error '%lld' in %s::LoadTree", loadResult,
602 treeToCallLoadOn->IsA()->GetName());
603
605 return fEntryStatus;
606 }
607
608 if (!fProxiesSet) {
609 if (!SetProxies()) {
611 return fEntryStatus;
612 }
613 }
614
615 if ((fEndEntry >= 0 && entry >= fEndEntry) || (fEntry >= fTree->GetEntriesFast())) {
617 return fEntryStatus;
618 }
619 fDirector->SetReadEntry(loadResult);
621 return fEntryStatus;
622}
623
624////////////////////////////////////////////////////////////////////////////////
625/// Set (or update) the which tree to read from. `tree` can be
626/// a TTree or a TChain.
627
628void TTreeReader::SetTree(TTree* tree, TEntryList* entryList /*= nullptr*/)
629{
630 fTree = tree;
631 fEntryList = entryList;
632 fEntry = -1;
633
634 if (fTree) {
636 SetBit(kBitIsChain, fTree->InheritsFrom(TChain::Class()));
637 } else {
639 }
640
641 if (!fDirector) {
642 Initialize();
643 }
644 else {
647 }
648}
649
650////////////////////////////////////////////////////////////////////////////////
651/// Set (or update) the which tree to read from, passing the name of a tree in a
652/// directory.
653///
654/// \param keyname - name of the tree in `dir`
655/// \param dir - the `TDirectory` to load `keyname` from (or gDirectory if `nullptr`)
656/// \param entryList - the `TEntryList` to attach to the `TTreeReader`.
657
658void TTreeReader::SetTree(const char* keyname, TDirectory* dir, TEntryList* entryList /*= nullptr*/)
659{
660 TTree* tree = nullptr;
661 if (!dir)
662 dir = gDirectory;
663 dir->GetObject(keyname, tree);
664 SetTree(tree, entryList);
665}
666
667////////////////////////////////////////////////////////////////////////////////
668/// Add a value reader for this tree.
669
671{
672 if (fProxiesSet) {
673 Error("RegisterValueReader",
674 "Error registering reader for %s: TTreeReaderValue/Array objects must be created before the call to Next() / SetEntry() / SetLocalEntry(), or after TTreeReader::Restart()!",
675 reader->GetBranchName());
676 return false;
677 }
678 fValues.push_back(reader);
679 return true;
680}
681
682////////////////////////////////////////////////////////////////////////////////
683/// Remove a value reader for this tree.
684
686{
687 std::deque<ROOT::Internal::TTreeReaderValueBase*>::iterator iReader
688 = std::find(fValues.begin(), fValues.end(), reader);
689 if (iReader == fValues.end()) {
690 Error("DeregisterValueReader", "Cannot find reader of type %s for branch %s", reader->GetDerivedTypeName(), reader->fBranchName.Data());
691 return;
692 }
693 fValues.erase(iReader);
694}
#define e(i)
Definition RSha256.hxx:103
const Bool_t kFALSE
Definition RtypesCore.h:101
long long Long64_t
Definition RtypesCore.h:80
const Bool_t kTRUE
Definition RtypesCore.h:100
#define ClassImp(name)
Definition Rtypes.h:364
#define gDirectory
Definition TDirectory.h:385
#define R__ASSERT(e)
Definition TError.h:118
void SetReadEntry(Long64_t entry)
Move to a new entry to read entry is the 'local' entry number; i.e.
TTree * SetTree(TTree *newtree)
Set the BranchProxy to be looking at a new tree.
Base class of TTreeReaderValue.
Detail::TBranchProxy * GetProxy() const
virtual const char * GetDerivedTypeName() const =0
TString fBranchName
Name of the branch to read data from.
virtual void CreateProxy()
Create the proxy object for our branch.
A chain is a collection of files containing TTree objects.
Definition TChain.h:33
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 List of entry numbers in a TTree or TChain.
Definition TEntryList.h:26
virtual TList * GetLists() const
Definition TEntryList.h:75
virtual Long64_t GetEntryAndTree(Long64_t index, Int_t &treenum)
Return the index of "index"-th non-zero entry in the TTree or TChain and the # of the corresponding t...
virtual Long64_t GetEntry(Long64_t index)
Return the number of the entry #index of this TEntryList in the TTree or TChain See also Next().
virtual Long64_t GetN() const
Definition TEntryList.h:77
virtual const char * GetName() const
Returns name of object.
Definition TNamed.h:47
void RemoveLink(Notifier &notifier)
Definition TNotifyLink.h:66
void PrependLink(Notifier &notifier)
Definition TNotifyLink.h:55
Bool_t IsLinked()
Definition TNotifyLink.h:82
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:201
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:949
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:766
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:515
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:963
const char * Data() const
Definition TString.h:369
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
Definition TTreeReader.h:44
TTreeReader()
Default constructor. Call SetTree to connect to a TTree.
Bool_t fProxiesSet
True if the proxies have been set, false otherwise.
ELoadTreeStatus fLoadTreeStatus
Indicator on how LoadTree was called 'last' time.
Long64_t GetEntries() const
Returns the number of entries of the TEntryList if one is provided, else of the TTree / TChain,...
EEntryStatus fEntryStatus
status of most recent read request
void SetTree(TTree *tree, TEntryList *entryList=nullptr)
Set (or update) the which tree to read from.
TNotifyLink< TTreeReader > fNotify
Bool_t SetProxies()
Tell readers we now have a tree.
Bool_t IsChain() const
@ kEntryNotFound
the tree entry number does not exist
@ kEntryUnknownError
LoadTree return less than -4, likely a 'newer' error code.
@ kEntryDictionaryError
problem reading dictionary info from tree
@ kEntryBeyondEnd
last entry loop has reached its end
@ kEntryChainFileError
problem in opening a chain's file
@ kEntryNoTree
the tree does not exist
@ kEntryValid
data read okay
std::deque< ROOT::Internal::TTreeReaderValueBase * > fValues
readers that use our director
Bool_t Notify()
Callback from TChain and TTree's LoadTree.
TTree * fTree
tree that's read
ROOT::Internal::TBranchProxyDirector * fDirector
proxying director, owned
~TTreeReader()
Tell all value readers that the tree reader does not exist anymore.
EEntryStatus SetEntriesRange(Long64_t beginEntry, Long64_t endEntry)
Set the begin and end entry numbers.
std::deque< ROOT::Internal::TFriendProxy * > fFriendProxies
proxying for friend TTrees, owned
Bool_t fSetEntryBaseCallingLoadTree
True if during the LoadTree execution triggered by SetEntryBase.
@ kInternalLoadTree
Notify/LoadTree was last called from SetEntryBase.
@ kNoTree
default state, no TTree is connected (formerly 'Zombie' state)
@ kExternalLoadTree
User code called LoadTree directly.
@ kLoadTreeNone
Notify has not been called yet.
void Initialize()
Initialization of the director.
void Restart()
Restart a Next() loop from entry 0 (of TEntryList index 0 of fEntryList is set).
EEntryStatus SetEntryBase(Long64_t entry, Bool_t local)
Load an entry into the tree, return the status of the read.
TEntryList * fEntryList
entry list to be used
Long64_t fEntry
Current (non-local) entry of fTree or of fEntryList if set.
Bool_t RegisterValueReader(ROOT::Internal::TTreeReaderValueBase *reader)
Add a value reader for this tree.
Long64_t fBeginEntry
This allows us to propagate the range to the TTreeCache.
void DeregisterValueReader(ROOT::Internal::TTreeReaderValueBase *reader)
Remove a value reader for this tree.
@ kBitHaveWarnedAboutEntryListAttachedToTTree
the tree had a TEntryList and we have warned about that
@ kBitIsChain
our tree is a chain
NamedProxies_t fProxies
attached ROOT::TNamedBranchProxies; owned
Bool_t IsInvalid() const
Long64_t fEndEntry
The end of the entry loop.
EEntryStatus SetEntry(Long64_t entry)
Set the next entry (or index of the TEntryList if that is set).
static constexpr const char *const fgEntryStatusText[kEntryUnknownError+1]
Long64_t GetCurrentEntry() const
Returns the index of the current entry being read.
A TTree represents a columnar dataset.
Definition TTree.h:79
virtual Int_t AddBranchToCache(const char *bname, Bool_t subbranches=kFALSE)
Add branch with name bname to the Tree cache.
Definition TTree.cxx:1058
virtual Int_t StopCacheLearningPhase()
Stop the cache learning phase.
Definition TTree.cxx:9414
TFile * GetCurrentFile() const
Return pointer to the current file.
Definition TTree.cxx:5463
TTreeCache * GetReadCache(TFile *file) const
Find and return the TTreeCache registered with the file and which may contain branches for us.
Definition TTree.cxx:6302
virtual TEntryList * GetEntryList()
Returns the entry list assigned to this tree.
Definition TTree.cxx:5838
virtual Long64_t GetEntries() const
Definition TTree.h:460
virtual TTree * GetTree() const
Definition TTree.h:514
virtual Long64_t LoadTree(Long64_t entry)
Set current entry.
Definition TTree.cxx:6457
virtual Long64_t GetEntriesFast() const
Definition TTree.h:462
virtual Int_t SetCacheEntryRange(Long64_t first, Long64_t last)
interface to TTreeCache to set the cache entry range
Definition TTree.cxx:8797
static constexpr Long64_t kMaxEntries
Definition TTree.h:226
Definition tree.py:1