Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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 /// Set the begin and end entry numbers
212 ///
213 /// \param beginEntry The first entry that `Next()` will load.
214 /// \param endEntry The entry that `Next()` will return `kFALSE` on (i.e. not
215 /// load anymore).
216 EEntryStatus SetEntriesRange(Long64_t beginEntry, Long64_t endEntry);
217
218 /// Get the begin and end entry numbers
219 ///
220 /// \return a pair contained the begin and end entry numbers.
221 std::pair<Long64_t, Long64_t> GetEntriesRange() const { return std::make_pair(fBeginEntry, fEndEntry); }
222
223 /// Restart a Next() loop from entry 0 (of TEntryList index 0 of fEntryList is set).
224 void Restart();
225
226 ///\}
227
229
230 Long64_t GetEntries() const;
232
233 /// Returns the index of the current entry being read.
234 ///
235 /// If `IsChain()`, the returned index corresponds to the global entry number
236 /// (i.e. not the entry number local to the chain's current tree).
237 /// If `fEntryList`, the returned index corresponds to an index in the
238 /// TEntryList; to translate to the TChain's / TTree's entry number pass it
239 /// through `reader.GetEntryList()->GetEntry(reader.GetCurrentEntry())`.
240 Long64_t GetCurrentEntry() const { return fEntry; }
241
242 Bool_t Notify();
243
244 /// Return an iterator to the 0th TTree entry.
246 return Iterator_t(*this, 0);
247 }
248 /// Return an iterator beyond the last TTree entry.
249 Iterator_t end() const { return Iterator_t(); }
250
251protected:
252 using NamedProxies_t = std::unordered_map<std::string, std::unique_ptr<ROOT::Internal::TNamedBranchProxy>>;
253 void Initialize();
254 ROOT::Internal::TNamedBranchProxy* FindProxy(const char* branchname) const
255 {
256 const auto proxyIt = fProxies.find(branchname);
257 return fProxies.end() != proxyIt ? proxyIt->second.get() : nullptr;
258 }
259
261 {
262 auto bpName = p->GetName();
263#ifndef NDEBUG
264 if (fProxies.end() != fProxies.find(bpName)) {
265 std::string err = "A proxy with key " + std::string(bpName) + " was already stored!";
266 throw std::runtime_error(err);
267 }
268#endif
269
270 fProxies[bpName].reset(p);
271 }
272
275
277
279
280private:
281
282 std::string GetProxyKey(const char *branchname)
283 {
284 std::string key(branchname);
285 //key += reinterpret_cast<std::uintptr_t>(fTree);
286 return key;
287 }
288
290 kBitIsChain = BIT(14), ///< our tree is a chain
291 kBitHaveWarnedAboutEntryListAttachedToTTree = BIT(15), ///< the tree had a TEntryList and we have warned about that
292 kBitSetEntryBaseCallingLoadTree = BIT(16) ///< SetEntryBase is in the process of calling TChain/TTree::LoadTree.
293 };
294
295 TTree* fTree = nullptr; ///< tree that's read
296 TEntryList* fEntryList = nullptr; ///< entry list to be used
297 EEntryStatus fEntryStatus = kEntryNotLoaded; ///< status of most recent read request
298 ELoadTreeStatus fLoadTreeStatus = kNoTree; ///< Indicator on how LoadTree was called 'last' time.
299 TNotifyLink<TTreeReader> fNotify; // Callback object used by the TChain to update this proxy
300 ROOT::Internal::TBranchProxyDirector* fDirector = nullptr; ///< proxying director, owned
301 std::deque<ROOT::Internal::TFriendProxy*> fFriendProxies; ///< proxying for friend TTrees, owned
302 std::deque<ROOT::Internal::TTreeReaderValueBase*> fValues; ///< readers that use our director
303 NamedProxies_t fProxies; ///< attached ROOT::TNamedBranchProxies; owned
304
305 Long64_t fEntry = -1; ///< Current (non-local) entry of fTree or of fEntryList if set.
306
307 /// The end of the entry loop. When set (i.e. >= 0), it provides a way
308 /// to stop looping over the TTree when we reach a certain entry: Next()
309 /// returns kFALSE when GetCurrentEntry() reaches fEndEntry.
311 Long64_t fBeginEntry = 0LL; ///< This allows us to propagate the range to the TTreeCache
312 Bool_t fProxiesSet = kFALSE; ///< True if the proxies have been set, false otherwise
313 Bool_t fSetEntryBaseCallingLoadTree = kFALSE; ///< True if during the LoadTree execution triggered by SetEntryBase.
314
317
318 ClassDef(TTreeReader, 0); // A simple interface to read trees
319};
320
321#endif // defined TTreeReader
const Bool_t kFALSE
Definition RtypesCore.h:101
bool Bool_t
Definition RtypesCore.h:63
long long Long64_t
Definition RtypesCore.h:80
const Bool_t kTRUE
Definition RtypesCore.h:100
#define ClassDef(name, id)
Definition Rtypes.h:325
#define BIT(n)
Definition Rtypes.h:85
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...
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:41
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:201
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).
Iterator_t()
Default-initialize the iterator as "past the end".
Definition TTreeReader.h:73
const Long64_t & operator*() const
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.
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.
ELoadTreeStatus fLoadTreeStatus
Indicator on how LoadTree was called 'last' time.
void SetTree(const char *keyname, TEntryList *entryList=nullptr)
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
std::unordered_map< std::string, std::unique_ptr< ROOT::Internal::TNamedBranchProxy > > NamedProxies_t
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.
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
@ kEntryChainSetupError
problem in accessing a chain element, e.g. file without the tree
@ kEntryNotLoaded
no entry has been loaded yet
@ kEntryBeyondEnd
last entry loop has reached its end
@ kEntryChainFileError
problem in opening a chain's file
@ kEntryNoTree
the tree does not exist
@ kEntryBadReader
One of the readers was not successfully initialized.
@ 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
TTree * GetTree() const
Iterator_t end() const
Return an iterator beyond the last TTree entry.
~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
std::string GetProxyKey(const char *branchname)
Bool_t fSetEntryBaseCallingLoadTree
True if during the LoadTree execution triggered by SetEntryBase.
EEntryStatus GetEntryStatus() const
@ 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 AddProxy(ROOT::Internal::TNamedBranchProxy *p)
void DeregisterValueReader(ROOT::Internal::TTreeReaderValueBase *reader)
Remove a value reader for this tree.
@ kBitSetEntryBaseCallingLoadTree
SetEntryBase is in the process of calling TChain/TTree::LoadTree.
@ kBitHaveWarnedAboutEntryListAttachedToTTree
the tree had a TEntryList and we have warned about that
@ kBitIsChain
our tree is a chain
EEntryStatus SetLocalEntry(Long64_t entry)
Set the next local tree entry.
NamedProxies_t fProxies
attached ROOT::TNamedBranchProxies; owned
TEntryList * GetEntryList() const
Bool_t IsInvalid() const
Iterator_t begin()
Return an iterator to the 0th TTree entry.
TTreeReader(const char *keyname, TEntryList *entryList=nullptr)
Long64_t fEndEntry
The end of the entry loop.
Iterator_t iterator
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]
Bool_t Next()
Move to the next entry (or index of the TEntryList if that is set).
ROOT::Internal::TNamedBranchProxy * FindProxy(const char *branchname) const
Long64_t GetCurrentEntry() const
Returns the index of the current entry being read.
A TTree represents a columnar dataset.
Definition TTree.h:79
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Definition tree.py:1