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
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()", "Start entry (%lld) must be lower than the available entries (%lld).", beginEntry,
420 GetEntries(false));
421 return kEntryNotFound;
422 }
423
424 // Update data members to correctly reflect the defined range
425 if (endEntry > beginEntry)
426 fEndEntry = endEntry;
427 else
428 fEndEntry = -1;
429
430 fBeginEntry = beginEntry;
431
432 if (beginEntry - 1 < 0)
433 // Reset the cache if reading from the first entry of the tree
434 Restart();
435 else {
436 // Load the first entry in the range. SetEntry() will also call SetProxies(),
437 // thus adding all the branches to the cache and triggering the learning phase.
438 EEntryStatus es = SetEntry(beginEntry - 1);
439 if (es != kEntryValid) {
440 Error("SetEntriesRange()", "Error setting first entry %lld: %s",
441 beginEntry, fgEntryStatusText[(int)es]);
442 return es;
443 }
444 }
445
446 return kEntryValid;
447}
448
451 fProxiesSet = false; // we might get more value readers, meaning new proxies.
452 fEntry = -1;
453 if (const auto curFile = fTree->GetCurrentFile()) {
454 if (auto tc = fTree->GetTree()->GetReadCache(curFile, true)) {
455 tc->DropBranch("*", true);
456 tc->ResetCache();
457 }
458 }
459}
460
461////////////////////////////////////////////////////////////////////////////////
462/// Returns the number of entries of the TEntryList if one is provided, else
463/// of the TTree / TChain, independent of a range set by SetEntriesRange()
464/// by calling TTree/TChain::%GetEntriesFast.
465
466
468 if (fEntryList)
469 return fEntryList->GetN();
470 if (!fTree)
471 return -1;
472 return fTree->GetEntriesFast();
473}
474
475
476////////////////////////////////////////////////////////////////////////////////
477/// Returns the number of entries of the TEntryList if one is provided, else
478/// of the TTree / TChain, independent of a range set by SetEntriesRange().
479///
480/// \param force If `IsChain()` and `force`, determines whether all TFiles of
481/// this TChain should be opened to determine the exact number of entries
482/// of the TChain. If `!IsChain()`, `force` is ignored.
483
485 if (fEntryList)
486 return fEntryList->GetN();
487 if (!fTree)
488 return -1;
489 if (force) {
491 auto res = fTree->GetEntries();
492 // Go back to where we were:
495 return res;
496 }
497 return fTree->GetEntriesFast();
498}
499
500
501
502////////////////////////////////////////////////////////////////////////////////
503/// Load an entry into the tree, return the status of the read.
504/// For chains, entry is the global (i.e. not tree-local) entry number, unless
505/// `local` is `true`, in which case `entry` specifies the entry number within
506/// the current tree. This is needed for instance for TSelector::Process().
507
509{
510 if (IsInvalid()) {
512 fEntry = -1;
513 return fEntryStatus;
514 }
515
516 fEntry = entry;
517
518 Long64_t entryAfterList = entry;
519 if (fEntryList) {
520 if (entry >= fEntryList->GetN()) {
521 // Passed the end of the chain, Restart() was not called:
522 // don't try to load entries anymore. Can happen in these cases:
523 // while (tr.Next()) {something()};
524 // while (tr.Next()) {somethingelse()}; // should not be calling somethingelse().
526 return fEntryStatus;
527 }
528 if (entry >= 0) {
529 if (fEntryList->GetLists()) {
531 int treenum = -1;
532 entryAfterList = fEntryList->GetEntryAndTree(entry, treenum);
533 entryAfterList += static_cast<TChain *>(fTree)->GetTreeOffset()[treenum];
534 // We always translate local entry numbers to global entry numbers for TChain+TEntryList with sublists
535 local = false;
536 } else {
537 // Could be a TTree or a TChain (TTreeReader also supports single TEntryLists for TChains).
538 // In both cases, we are using the global entry numbers coming from the single TEntryList.
539 entryAfterList = fEntryList->GetEntry(entry);
540 }
541 }
542 }
543
544 TTree* treeToCallLoadOn = local ? fTree->GetTree() : fTree;
545
547 const Long64_t loadResult = treeToCallLoadOn->LoadTree(entryAfterList);
549
550 if (loadResult < 0) {
551 // ROOT-9628 We cover here the case when:
552 // - We deal with a TChain
553 // - The last file is opened
554 // - The TTree is not correctly loaded
555 // The system is robust against issues with TTrees associated to the chain
556 // when they are not at the end of it.
557 if (loadResult == -3 && TestBit(kBitIsChain) && !fTree->GetTree()) {
558 fDirector->Notify();
559 if (fProxiesSet) {
560 for (auto value: fValues) {
561 value->NotifyNewTree(fTree->GetTree());
562 }
563 }
564 Warning("SetEntryBase()",
565 "There was an issue opening the last file associated to the TChain "
566 "being processed.");
568 return fEntryStatus;
569 }
570
571 if (loadResult == -2) {
572 fDirector->Notify();
573 if (fProxiesSet) {
574 for (auto value: fValues) {
575 value->NotifyNewTree(fTree->GetTree());
576 }
577 }
579 return fEntryStatus;
580 }
581
582 if (loadResult == -1) {
583 // The chain is empty
585 return fEntryStatus;
586 }
587
588 if (loadResult == -4) {
589 // The TChainElement corresponding to the entry is missing or
590 // the TTree is missing from the file.
591 fDirector->Notify();
592 if (fProxiesSet) {
593 for (auto value: fValues) {
594 value->NotifyNewTree(fTree->GetTree());
595 }
596 }
598 return fEntryStatus;
599 }
600
601 Warning("SetEntryBase()",
602 "Unexpected error '%lld' in %s::LoadTree", loadResult,
603 treeToCallLoadOn->IsA()->GetName());
604
606 return fEntryStatus;
607 }
608
609 if (!fProxiesSet) {
610 if (!SetProxies()) {
612 return fEntryStatus;
613 }
614 }
615
616 if ((fEndEntry >= 0 && entry >= fEndEntry) || (fEntry >= fTree->GetEntriesFast())) {
618 return fEntryStatus;
619 }
620 fDirector->SetReadEntry(loadResult);
622 return fEntryStatus;
623}
624
625////////////////////////////////////////////////////////////////////////////////
626/// Set (or update) the which tree to read from. `tree` can be
627/// a TTree or a TChain.
628
629void TTreeReader::SetTree(TTree* tree, TEntryList* entryList /*= nullptr*/)
630{
631 fTree = tree;
632 fEntryList = entryList;
633 fEntry = -1;
634
635 if (fTree) {
638 } else {
640 }
641
642 if (!fDirector) {
643 Initialize();
644 }
645 else {
648 }
649}
650
651////////////////////////////////////////////////////////////////////////////////
652/// Set (or update) the which tree to read from, passing the name of a tree in a
653/// directory.
654///
655/// \param keyname - name of the tree in `dir`
656/// \param dir - the `TDirectory` to load `keyname` from (or gDirectory if `nullptr`)
657/// \param entryList - the `TEntryList` to attach to the `TTreeReader`.
658
659void TTreeReader::SetTree(const char* keyname, TDirectory* dir, TEntryList* entryList /*= nullptr*/)
660{
661 TTree* tree = nullptr;
662 if (!dir)
663 dir = gDirectory;
664 dir->GetObject(keyname, tree);
665 SetTree(tree, entryList);
666}
667
668////////////////////////////////////////////////////////////////////////////////
669/// Add a value reader for this tree.
670
672{
673 if (fProxiesSet) {
674 Error("RegisterValueReader",
675 "Error registering reader for %s: TTreeReaderValue/Array objects must be created before the call to Next() / SetEntry() / SetLocalEntry(), or after TTreeReader::Restart()!",
676 reader->GetBranchName());
677 return false;
678 }
679 fValues.push_back(reader);
680 return true;
681}
682
683////////////////////////////////////////////////////////////////////////////////
684/// Remove a value reader for this tree.
685
687{
688 std::deque<ROOT::Internal::TTreeReaderValueBase*>::iterator iReader
689 = std::find(fValues.begin(), fValues.end(), reader);
690 if (iReader == fValues.end()) {
691 Error("DeregisterValueReader", "Cannot find reader of type %s for branch %s", reader->GetDerivedTypeName(), reader->fBranchName.Data());
692 return;
693 }
694 fValues.erase(iReader);
695}
#define e(i)
Definition RSha256.hxx:103
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
long long Long64_t
Definition RtypesCore.h:80
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
#define ClassImp(name)
Definition Rtypes.h:377
#define gDirectory
Definition TDirectory.h:386
#define R__ASSERT(e)
Definition TError.h:117
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
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
static TClass * Class()
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:76
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:78
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
void RemoveLink(Notifier &notifier)
Definition TNotifyLink.h:68
void PrependLink(Notifier &notifier)
Definition TNotifyLink.h:56
Bool_t IsLinked()
Definition TNotifyLink.h:85
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:956
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:774
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:525
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:970
const char * Data() const
Definition TString.h:380
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 range of entries to be loaded by Next(); end will not be loaded.
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:9429
TFile * GetCurrentFile() const
Return pointer to the current file.
Definition TTree.cxx:5470
TTreeCache * GetReadCache(TFile *file) const
Find and return the TTreeCache registered with the file and which may contain branches for us.
Definition TTree.cxx:6309
virtual TEntryList * GetEntryList()
Returns the entry list assigned to this tree.
Definition TTree.cxx:5845
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:6464
virtual Long64_t GetEntriesFast() const
Definition TTree.h:462
TClass * IsA() const override
Definition TTree.h:654
virtual Int_t SetCacheEntryRange(Long64_t first, Long64_t last)
interface to TTreeCache to set the cache entry range
Definition TTree.cxx:8812
static constexpr Long64_t kMaxEntries
Definition TTree.h:226
Definition tree.py:1