Logo ROOT  
Reference Guide
TTreeReader.h
Go to the documentation of this file.
1// @(#)root/tree:$Id$
2// Author: Axel Naumann, 2010-08-02
3
4/*************************************************************************
5 * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers. *
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#ifndef ROOT_TTreeReader
13#define ROOT_TTreeReader
14
15
16////////////////////////////////////////////////////////////////////////////
17// //
18// TTreeReader //
19// //
20// A simple interface for reading trees or chains. //
21// //
22// //
23////////////////////////////////////////////////////////////////////////////
24
25#include "TTree.h"
26#include "TTreeReaderUtils.h"
27#include "TNotifyLink.h"
28
29#include <deque>
30#include <iterator>
31#include <unordered_map>
32#include <string>
33
34class TDictionary;
35class TDirectory;
36class TFileCollection;
37
38namespace ROOT {
39namespace Internal {
41}
42}
43
44class TTreeReader: public TObject {
45public:
46
47 ///\class TTreeReader::Iterator_t
48 /// Iterate through the entries of a TTree.
49 ///
50 /// This iterator drives the associated TTreeReader; its
51 /// dereferencing (and actually even the iteration) will
52 /// set the entry number represented by this iterator.
53 /// It does not really represent a data element; it simply
54 /// returns the entry number (or -1 once the end of the tree
55 /// is reached).
56 class Iterator_t {
57 private:
58 Long64_t fEntry; ///< Entry number of the tree referenced by this iterator; -1 is invalid.
59 TTreeReader* fReader; ///< The reader we select the entries on.
60
61 /// Whether the iterator points to a valid entry.
62 bool IsValid() const { return fEntry >= 0; }
63
64 public:
65 using iterator_category = std::input_iterator_tag;
66 using value_type = const Long64_t;
68 using pointer = const Long64_t *;
69 using const_pointer = const Long64_t *;
70 using reference = const Long64_t &;
71
72 /// Default-initialize the iterator as "past the end".
73 Iterator_t(): fEntry(-1), fReader(nullptr) {}
74
75 /// Initialize the iterator with the reader it steers and a
76 /// tree entry number; -1 is invalid.
78 fEntry(entry), fReader(&reader) {}
79
80 /// Compare two iterators for equality.
81 bool operator==(const Iterator_t& lhs) const {
82 // From C++14: value initialized (past-end) it compare equal.
83 if (!IsValid() && !lhs.IsValid()) return true;
84 return fEntry == lhs.fEntry && fReader == lhs.fReader;
85 }
86
87 /// Compare two iterators for inequality.
88 bool operator!=(const Iterator_t& lhs) const {
89 return !(*this == lhs);
90 }
91
92 /// Increment the iterator (postfix i++).
94 Iterator_t ret = *this;
95 this->operator++();
96 return ret;
97 }
98
99 /// Increment the iterator (prefix ++i).
101 if (IsValid()) {
102 ++fEntry;
103 // Force validity check of new fEntry.
104 this->operator*();
105 // Don't set the old entry: op* will if needed, and
106 // in most cases it just adds a lot of spinning back
107 // and forth: in most cases the sequence is ++i; *i.
108 }
109 return *this;
110 }
111
112 /// Set the entry number in the reader and return it.
114 if (IsValid()) {
115 // If we cannot access that entry, mark the iterator invalid.
117 fEntry = -1;
118 }
119 }
120 // There really is no data in this iterator; return the number.
121 return fEntry;
122 }
123
124 const Long64_t& operator*() const {
125 return **const_cast<Iterator_t*>(this);
126 }
127 };
128
130
132 kEntryValid = 0, ///< data read okay
133 kEntryNotLoaded, ///< no entry has been loaded yet
134 kEntryNoTree, ///< the tree does not exist
135 kEntryNotFound, ///< the tree entry number does not exist
136 kEntryChainSetupError, ///< problem in accessing a chain element, e.g. file without the tree
137 kEntryChainFileError, ///< problem in opening a chain's file
138 kEntryDictionaryError, ///< problem reading dictionary info from tree
139 kEntryBeyondEnd, ///< last entry loop has reached its end
140 kEntryBadReader, ///< One of the readers was not successfully initialized.
141 kEntryUnknownError ///< LoadTree return less than -4, likely a 'newer' error code.
142 };
143
145 kNoTree = 0, ///< default state, no TTree is connected (formerly 'Zombie' state)
146 kLoadTreeNone, ///< Notify has not been called yet.
147 kInternalLoadTree, ///< Notify/LoadTree was last called from SetEntryBase
148 kExternalLoadTree ///< User code called LoadTree directly.
149 };
150
151 static constexpr const char * const fgEntryStatusText[kEntryUnknownError + 1] = {
152 "valid entry",
153 "the tree does not exist",
154 "the tree entry number does not exist",
155 "cannot access chain element",
156 "problem in opening a chain's file",
157 "problem reading dictionary info from tree",
158 "last entry loop has reached its end",
159 "one of the readers was not successfully initialized",
160 "LoadTree return less than -4, likely a 'newer' error code"
161 };
162
163 TTreeReader();
164
165 TTreeReader(TTree* tree, TEntryList* entryList = nullptr);
166 TTreeReader(const char* keyname, TDirectory* dir, TEntryList* entryList = nullptr);
167 TTreeReader(const char *keyname, TEntryList *entryList = nullptr) : TTreeReader(keyname, nullptr, entryList) {}
168
169 ~TTreeReader();
170
171 void SetTree(TTree* tree, TEntryList* entryList = nullptr);
172 void SetTree(const char* keyname, TEntryList* entryList = nullptr) {
173 SetTree(keyname, nullptr, entryList);
174 }
175 void SetTree(const char* keyname, TDirectory* dir, TEntryList* entryList = nullptr);
176
177 Bool_t IsChain() const { return TestBit(kBitIsChain); }
178
180
181 TTree* GetTree() const { return fTree; }
182 TEntryList* GetEntryList() const { return fEntryList; }
183
184 ///\{ \name Entry setters
185
186 /// Move to the next entry (or index of the TEntryList if that is set).
187 ///
188 /// \return false if the previous entry was already the last entry. This allows
189 /// the function to be used in `while (reader.Next()) { ... }`
191 return SetEntry(GetCurrentEntry() + 1) == kEntryValid;
192 }
193
194 /// Set the next entry (or index of the TEntryList if that is set).
195 ///
196 /// \param entry If not TEntryList is set, the entry is a global entry (i.e.
197 /// not the entry number local to the chain's current tree).
198 /// \returns the `entry`'s read status, i.e. whether the entry is available.
200
201 /// Set the next local tree entry. If a TEntryList is set, this function is
202 /// equivalent to `SetEntry()`.
203 ///
204 /// \param entry Entry number of the TChain's current TTree. This is the
205 /// entry number passed for instance by `TSelector::Process(entry)`, i.e.
206 /// within `TSelector::Process()` always use `SetLocalEntry()` and not
207 /// `SetEntry()`!
208 /// \return the `entry`'s read status, i.e. whether the entry is available.
210
211 EEntryStatus SetEntriesRange(Long64_t beginEntry, Long64_t endEntry);
212
213 /// Get the begin and end entry numbers
214 ///
215 /// \return a pair contained the begin and end entry numbers.
216 std::pair<Long64_t, Long64_t> GetEntriesRange() const { return std::make_pair(fBeginEntry, fEndEntry); }
217
218 /// Restart a Next() loop from entry 0 (of TEntryList index 0 of fEntryList is set).
219 void Restart();
220
221 ///\}
222
224
225 Long64_t GetEntries() const;
227
228 /// Returns the index of the current entry being read.
229 ///
230 /// If `IsChain()`, the returned index corresponds to the global entry number
231 /// (i.e. not the entry number local to the chain's current tree).
232 /// If `fEntryList`, the returned index corresponds to an index in the
233 /// TEntryList; to translate to the TChain's / TTree's entry number pass it
234 /// through `reader.GetEntryList()->GetEntry(reader.GetCurrentEntry())`.
235 Long64_t GetCurrentEntry() const { return fEntry; }
236
237 Bool_t Notify();
238
239 /// Return an iterator to the 0th TTree entry.
241 return Iterator_t(*this, 0);
242 }
243 /// Return an iterator beyond the last TTree entry.
244 Iterator_t end() const { return Iterator_t(); }
245
246protected:
247 using NamedProxies_t = std::unordered_map<std::string, std::unique_ptr<ROOT::Internal::TNamedBranchProxy>>;
248 void Initialize();
249 ROOT::Internal::TNamedBranchProxy* FindProxy(const char* branchname) const
250 {
251 const auto proxyIt = fProxies.find(branchname);
252 return fProxies.end() != proxyIt ? proxyIt->second.get() : nullptr;
253 }
254
256 {
257 auto bpName = p->GetName();
258#ifndef NDEBUG
259 if (fProxies.end() != fProxies.find(bpName)) {
260 std::string err = "A proxy with key " + std::string(bpName) + " was already stored!";
261 throw std::runtime_error(err);
262 }
263#endif
264
265 fProxies[bpName].reset(p);
266 }
267
270
272
274
275private:
276
277 std::string GetProxyKey(const char *branchname)
278 {
279 std::string key(branchname);
280 //key += reinterpret_cast<std::uintptr_t>(fTree);
281 return key;
282 }
283
285 kBitIsChain = BIT(14), ///< our tree is a chain
286 kBitHaveWarnedAboutEntryListAttachedToTTree = BIT(15), ///< the tree had a TEntryList and we have warned about that
287 kBitSetEntryBaseCallingLoadTree = BIT(16) ///< SetEntryBase is in the process of calling TChain/TTree::%LoadTree.
288 };
289
290 TTree* fTree = nullptr; ///< tree that's read
291 TEntryList* fEntryList = nullptr; ///< entry list to be used
292 EEntryStatus fEntryStatus = kEntryNotLoaded; ///< status of most recent read request
293 ELoadTreeStatus fLoadTreeStatus = kNoTree; ///< Indicator on how LoadTree was called 'last' time.
294 TNotifyLink<TTreeReader> fNotify; // Callback object used by the TChain to update this proxy
295 ROOT::Internal::TBranchProxyDirector* fDirector = nullptr; ///< proxying director, owned
296 std::deque<ROOT::Internal::TFriendProxy*> fFriendProxies; ///< proxying for friend TTrees, owned
297 std::deque<ROOT::Internal::TTreeReaderValueBase*> fValues; ///< readers that use our director
298 NamedProxies_t fProxies; ///< attached ROOT::TNamedBranchProxies; owned
299
300 Long64_t fEntry = -1; ///< Current (non-local) entry of fTree or of fEntryList if set.
301
302 /// The end of the entry loop. When set (i.e. >= 0), it provides a way
303 /// to stop looping over the TTree when we reach a certain entry: Next()
304 /// returns kFALSE when GetCurrentEntry() reaches fEndEntry.
306 Long64_t fBeginEntry = 0LL; ///< This allows us to propagate the range to the TTreeCache
307 Bool_t fProxiesSet = kFALSE; ///< True if the proxies have been set, false otherwise
308 Bool_t fSetEntryBaseCallingLoadTree = kFALSE; ///< True if during the LoadTree execution triggered by SetEntryBase.
309
312
313 ClassDef(TTreeReader, 0); // A simple interface to read trees
314};
315
316#endif // defined TTreeReader
bool Bool_t
Definition: RtypesCore.h:63
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 ClassDef(name, id)
Definition: Rtypes.h:335
#define BIT(n)
Definition: Rtypes.h:85
winID h TVirtualViewer3D TVirtualGLPainter p
Base class of TTreeReaderArray.
Base class of TTreeReaderValue.
This class is used to 'drive' and hold a serie of TBranchProxy objects which represent and give acces...
This class defines an abstract interface that must be implemented by all classes that contain diction...
Definition: TDictionary.h:167
Describe directory structure in memory.
Definition: TDirectory.h:45
A List of entry numbers in a TTree or TChain.
Definition: TEntryList.h:26
Class that contains a list of TFileInfo's and accumulated meta data information about its entries.
Mother of all ROOT objects.
Definition: TObject.h:37
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:359
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:187
EStatusBits
Definition: TObject.h:57
Iterate through the entries of a TTree.
Definition: TTreeReader.h:56
const Long64_t * const_pointer
Definition: TTreeReader.h:69
const Long64_t value_type
Definition: TTreeReader.h:66
Iterator_t & operator++()
Increment the iterator (prefix ++i).
Definition: TTreeReader.h:100
Iterator_t()
Default-initialize the iterator as "past the end".
Definition: TTreeReader.h:73
const Long64_t & operator*() const
Definition: TTreeReader.h:124
Long64_t fEntry
Entry number of the tree referenced by this iterator; -1 is invalid.
Definition: TTreeReader.h:58
Iterator_t(TTreeReader &reader, Long64_t entry)
Initialize the iterator with the reader it steers and a tree entry number; -1 is invalid.
Definition: TTreeReader.h:77
const Long64_t & reference
Definition: TTreeReader.h:70
bool operator==(const Iterator_t &lhs) const
Compare two iterators for equality.
Definition: TTreeReader.h:81
TTreeReader * fReader
The reader we select the entries on.
Definition: TTreeReader.h:59
const Long64_t & operator*()
Set the entry number in the reader and return it.
Definition: TTreeReader.h:113
bool IsValid() const
Whether the iterator points to a valid entry.
Definition: TTreeReader.h:62
std::input_iterator_tag iterator_category
Definition: TTreeReader.h:65
bool operator!=(const Iterator_t &lhs) const
Compare two iterators for inequality.
Definition: TTreeReader.h:88
Iterator_t operator++(int)
Increment the iterator (postfix i++).
Definition: TTreeReader.h:93
const Long64_t * pointer
Definition: TTreeReader.h:68
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.
Definition: TTreeReader.h:307
ELoadTreeStatus fLoadTreeStatus
Indicator on how LoadTree was called 'last' time.
Definition: TTreeReader.h:293
void SetTree(const char *keyname, TEntryList *entryList=nullptr)
Definition: TTreeReader.h:172
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
Definition: TTreeReader.h:292
std::unordered_map< std::string, std::unique_ptr< ROOT::Internal::TNamedBranchProxy > > NamedProxies_t
Definition: TTreeReader.h:247
void SetTree(TTree *tree, TEntryList *entryList=nullptr)
Set (or update) the which tree to read from.
std::pair< Long64_t, Long64_t > GetEntriesRange() const
Get the begin and end entry numbers.
Definition: TTreeReader.h:216
TNotifyLink< TTreeReader > fNotify
Definition: TTreeReader.h:294
Bool_t SetProxies()
Tell readers we now have a tree.
Bool_t IsChain() const
Definition: TTreeReader.h:177
@ kEntryNotFound
the tree entry number does not exist
Definition: TTreeReader.h:135
@ kEntryUnknownError
LoadTree return less than -4, likely a 'newer' error code.
Definition: TTreeReader.h:141
@ kEntryDictionaryError
problem reading dictionary info from tree
Definition: TTreeReader.h:138
@ kEntryChainSetupError
problem in accessing a chain element, e.g. file without the tree
Definition: TTreeReader.h:136
@ kEntryNotLoaded
no entry has been loaded yet
Definition: TTreeReader.h:133
@ kEntryBeyondEnd
last entry loop has reached its end
Definition: TTreeReader.h:139
@ kEntryChainFileError
problem in opening a chain's file
Definition: TTreeReader.h:137
@ kEntryNoTree
the tree does not exist
Definition: TTreeReader.h:134
@ kEntryBadReader
One of the readers was not successfully initialized.
Definition: TTreeReader.h:140
@ kEntryValid
data read okay
Definition: TTreeReader.h:132
std::deque< ROOT::Internal::TTreeReaderValueBase * > fValues
readers that use our director
Definition: TTreeReader.h:297
Bool_t Notify()
Callback from TChain and TTree's LoadTree.
TTree * fTree
tree that's read
Definition: TTreeReader.h:290
ROOT::Internal::TBranchProxyDirector * fDirector
proxying director, owned
Definition: TTreeReader.h:295
TTree * GetTree() const
Definition: TTreeReader.h:181
Iterator_t end() const
Return an iterator beyond the last TTree entry.
Definition: TTreeReader.h:244
~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
Definition: TTreeReader.h:296
std::string GetProxyKey(const char *branchname)
Definition: TTreeReader.h:277
Bool_t fSetEntryBaseCallingLoadTree
True if during the LoadTree execution triggered by SetEntryBase.
Definition: TTreeReader.h:308
EEntryStatus GetEntryStatus() const
Definition: TTreeReader.h:223
@ kInternalLoadTree
Notify/LoadTree was last called from SetEntryBase.
Definition: TTreeReader.h:147
@ kNoTree
default state, no TTree is connected (formerly 'Zombie' state)
Definition: TTreeReader.h:145
@ kExternalLoadTree
User code called LoadTree directly.
Definition: TTreeReader.h:148
@ kLoadTreeNone
Notify has not been called yet.
Definition: TTreeReader.h:146
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
Definition: TTreeReader.h:291
Long64_t fEntry
Current (non-local) entry of fTree or of fEntryList if set.
Definition: TTreeReader.h:300
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.
Definition: TTreeReader.h:306
void AddProxy(ROOT::Internal::TNamedBranchProxy *p)
Definition: TTreeReader.h:255
void DeregisterValueReader(ROOT::Internal::TTreeReaderValueBase *reader)
Remove a value reader for this tree.
@ kBitSetEntryBaseCallingLoadTree
SetEntryBase is in the process of calling TChain/TTree::LoadTree.
Definition: TTreeReader.h:287
@ kBitHaveWarnedAboutEntryListAttachedToTTree
the tree had a TEntryList and we have warned about that
Definition: TTreeReader.h:286
@ kBitIsChain
our tree is a chain
Definition: TTreeReader.h:285
EEntryStatus SetLocalEntry(Long64_t entry)
Set the next local tree entry.
Definition: TTreeReader.h:209
NamedProxies_t fProxies
attached ROOT::TNamedBranchProxies; owned
Definition: TTreeReader.h:298
TEntryList * GetEntryList() const
Definition: TTreeReader.h:182
Bool_t IsInvalid() const
Definition: TTreeReader.h:179
Iterator_t begin()
Return an iterator to the 0th TTree entry.
Definition: TTreeReader.h:240
TTreeReader(const char *keyname, TEntryList *entryList=nullptr)
Definition: TTreeReader.h:167
Long64_t fEndEntry
The end of the entry loop.
Definition: TTreeReader.h:305
Iterator_t iterator
Definition: TTreeReader.h:129
EEntryStatus SetEntry(Long64_t entry)
Set the next entry (or index of the TEntryList if that is set).
Definition: TTreeReader.h:199
static constexpr const char *const fgEntryStatusText[kEntryUnknownError+1]
Definition: TTreeReader.h:151
Bool_t Next()
Move to the next entry (or index of the TEntryList if that is set).
Definition: TTreeReader.h:190
ROOT::Internal::TNamedBranchProxy * FindProxy(const char *branchname) const
Definition: TTreeReader.h:249
Long64_t GetCurrentEntry() const
Returns the index of the current entry being read.
Definition: TTreeReader.h:235
A TTree represents a columnar dataset.
Definition: TTree.h:79
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
Definition: tree.py:1