Logo ROOT   6.12/06
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 "THashTable.h"
26 #include "TTree.h"
27 #include "TTreeReaderUtils.h"
28 
29 #include <deque>
30 #include <iterator>
31 
32 class TDictionary;
33 class TDirectory;
34 class TFileCollection;
35 
36 namespace ROOT {
37 namespace Internal {
38  class TBranchProxyDirector;
39 }
40 }
41 
42 class TTreeReader: public TObject {
43 public:
44 
45  ///\class TTreeReader::Iterator_t
46  /// Iterate through the entries of a TTree.
47  ///
48  /// This iterator drives the associated TTreeReader; its
49  /// dereferencing (and actually even the iteration) will
50  /// set the entry number represented by this iterator.
51  /// It does not really represent a data element; it simply
52  /// returns the entry number (or -1 once the end of the tree
53  /// is reached).
54  class Iterator_t:
55  public std::iterator<std::input_iterator_tag, const Long64_t, Long64_t> {
56  private:
57  Long64_t fEntry; ///< Entry number of the tree referenced by this iterator; -1 is invalid.
58  TTreeReader* fReader; ///< The reader we select the entries on.
59 
60  /// Whether the iterator points to a valid entry.
61  bool IsValid() const { return fEntry >= 0; }
62 
63  public:
64  /// Default-initialize the iterator as "past the end".
65  Iterator_t(): fEntry(-1), fReader() {}
66 
67  /// Initialize the iterator with the reader it steers and a
68  /// tree entry number; -1 is invalid.
70  fEntry(entry), fReader(&reader) {}
71 
72  /// Compare two iterators for equality.
73  bool operator==(const Iterator_t& lhs) const {
74  // From C++14: value initialized (past-end) it compare equal.
75  if (!IsValid() && !lhs.IsValid()) return true;
76  return fEntry == lhs.fEntry && fReader == lhs.fReader;
77  }
78 
79  /// Compare two iterators for inequality.
80  bool operator!=(const Iterator_t& lhs) const {
81  return !(*this == lhs);
82  }
83 
84  /// Increment the iterator (postfix i++).
86  Iterator_t ret = *this;
87  this->operator++();
88  return ret;
89  }
90 
91  /// Increment the iterator (prefix ++i).
93  if (IsValid()) {
94  ++fEntry;
95  // Force validity check of new fEntry.
96  this->operator*();
97  // Don't set the old entry: op* will if needed, and
98  // in most cases it just adds a lot of spinning back
99  // and forth: in most cases teh sequence is ++i; *i.
100  }
101  return *this;
102  }
103 
104  /// Set the entry number in the reader and return it.
105  const Long64_t& operator*() {
106  if (IsValid()) {
107  // If we cannot access that entry, mark the iterator invalid.
108  if (fReader->SetEntry(fEntry) != kEntryValid) {
109  fEntry = -1;
110  }
111  }
112  // There really is no data in this iterator; return the number.
113  return fEntry;
114  }
115 
116  const Long64_t& operator*() const {
117  return **const_cast<Iterator_t*>(this);
118  }
119  };
120 
122 
124  kEntryValid = 0, ///< data read okay
125  kEntryNotLoaded, ///< no entry has been loaded yet
126  kEntryNoTree, ///< the tree does not exist
127  kEntryNotFound, ///< the tree entry number does not exist
128  kEntryChainSetupError, ///< problem in accessing a chain element, e.g. file without the tree
129  kEntryChainFileError, ///< problem in opening a chain's file
130  kEntryDictionaryError, ///< problem reading dictionary info from tree
131  kEntryBeyondEnd ///< last entry loop has reached its end
132  };
133 
134  static constexpr const char * const fgEntryStatusText[kEntryBeyondEnd + 1] = {
135  "valid entry",
136  "the tree does not exist",
137  "the tree entry number does not exist",
138  "cannot access chain element",
139  "problem in opening a chain's file",
140  "problem reading dictionary info from tree",
141  "last entry loop has reached its end"
142  };
143 
144  TTreeReader() = default;
145 
146  TTreeReader(TTree* tree, TEntryList* entryList = nullptr);
147  TTreeReader(const char* keyname, TDirectory* dir, TEntryList* entryList = nullptr);
148  TTreeReader(const char* keyname, TEntryList* entryList = nullptr):
149  TTreeReader(keyname, nullptr, entryList) {}
150 
151  ~TTreeReader();
152 
153  void SetTree(TTree* tree, TEntryList* entryList = nullptr);
154  void SetTree(const char* keyname, TEntryList* entryList = nullptr) {
155  SetTree(keyname, nullptr, entryList);
156  }
157  void SetTree(const char* keyname, TDirectory* dir, TEntryList* entryList = nullptr);
158 
159  Bool_t IsChain() const { return TestBit(kBitIsChain); }
160 
161  TTree* GetTree() const { return fTree; }
162  TEntryList* GetEntryList() const { return fEntryList; }
163 
164  ///\{ \name Entry setters
165 
166  /// Move to the next entry (or index of the TEntryList if that is set).
167  ///
168  /// \return false if the previous entry was already the last entry. This allows
169  /// the function to be used in `while (reader.Next()) { ... }`
171  return SetEntry(GetCurrentEntry() + 1) == kEntryValid;
172  }
173 
174  /// Set the next entry (or index of the TEntryList if that is set).
175  ///
176  /// \param entry If not TEntryList is set, the entry is a global entry (i.e.
177  /// not the entry number local to the chain's current tree).
178  /// \returns the `entry`'s read status, i.e. whether the entry is available.
179  EEntryStatus SetEntry(Long64_t entry) { return SetEntryBase(entry, kFALSE); }
180 
181  /// Set the next local tree entry. If a TEntryList is set, this function is
182  /// equivalent to `SetEntry()`.
183  ///
184  /// \param entry Entry number of the TChain's current TTree. This is the
185  /// entry number passed for instance by `TSelector::Process(entry)`, i.e.
186  /// within `TSelector::Process()` always use `SetLocalEntry()` and not
187  /// `SetEntry()`!
188  /// \return the `entry`'s read status, i.e. whether the entry is available.
190 
191  /// Sets the entry that `Next()` will stop iteration on.
192  ///
193  /// \param beginEntry The first entry that `Next()` will load.
194  /// \param endEntry The entry that `Next()` will return `kFALSE` on (i.e. not
195  /// load anymore).
196  EEntryStatus SetEntriesRange(Long64_t beginEntry, Long64_t endEntry);
197 
198  /// Restart a Next() loop from entry 0 (of TEntryList index 0 of fEntryList is set).
199  void Restart();
200 
201  ///\}
202 
204 
205  Long64_t GetEntries(Bool_t force) const;
206 
207  /// Returns the index of the current entry being read.
208  ///
209  /// If `IsChain()`, the returned index corresponds to the global entry number
210  /// (i.e. not the entry number local to the chain's current tree).
211  /// If `fEntryList`, the returned index corresponds to an index in the
212  /// TEntryList; to translate to the TChain's / TTree's entry number pass it
213  /// through `reader.GetEntryList()->GetEntry(reader.GetCurrentEntry())`.
214  Long64_t GetCurrentEntry() const { return fEntry; }
215 
216  /// Return an iterator to the 0th TTree entry.
218  return Iterator_t(*this, 0);
219  }
220  /// Return an iterator beyond the last TTree entry.
221  Iterator_t end() const { return Iterator_t(); }
222 
223 protected:
224  void Initialize();
225  ROOT::Internal::TNamedBranchProxy* FindProxy(const char* branchname) const {
226  return (ROOT::Internal::TNamedBranchProxy*) fProxies.FindObject(branchname); }
228 
231 
233 
234 private:
235 
236  enum EStatusBits {
237  kBitIsChain = BIT(14), ///< our tree is a chain
238  kBitHaveWarnedAboutEntryListAttachedToTTree = BIT(15) ///< the tree had a TEntryList and we have warned about that
239  };
240 
241  TTree* fTree = nullptr; ///< tree that's read
242  TEntryList* fEntryList = nullptr; ///< entry list to be used
243  EEntryStatus fEntryStatus = kEntryNotLoaded; ///< status of most recent read request
244  Int_t fMostRecentTreeNumber = -1; ///< TTree::GetTreeNumber() of the most recent tree
245  ROOT::Internal::TBranchProxyDirector* fDirector = nullptr; ///< proxying director, owned
246  std::deque<ROOT::Internal::TTreeReaderValueBase*> fValues; ///< readers that use our director
247  THashTable fProxies; ///< attached ROOT::TNamedBranchProxies; owned
248 
249  Long64_t fEntry = -1; ///< Current (non-local) entry of fTree or of fEntryList if set.
250 
251  /// The end of the entry loop. When set (i.e. >= 0), it provides a way
252  /// to stop looping over the TTree when we reach a certain entry: Next()
253  /// returns kFALSE when GetCurrentEntry() reaches fEndEntry.
255  Bool_t fProxiesSet = kFALSE; ///< True if the proxies have been set, false otherwise
256 
259 
260  ClassDef(TTreeReader, 0); // A simple interface to read trees
261 };
262 
263 #endif // defined TTreeReader
ROOT::Internal::TNamedBranchProxy * FindProxy(const char *branchname) const
Definition: TTreeReader.h:225
the tree does not exist
Definition: TTreeReader.h:126
Iterate through the entries of a TTree.
Definition: TTreeReader.h:54
bool operator!=(const Iterator_t &lhs) const
Compare two iterators for inequality.
Definition: TTreeReader.h:80
long long Long64_t
Definition: RtypesCore.h:69
TCollection * GetProxies()
Definition: TTreeReader.h:227
TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple...
Definition: TTreeReader.h:42
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
Long64_t GetCurrentEntry() const
Returns the index of the current entry being read.
Definition: TTreeReader.h:214
TTreeReader(const char *keyname, TEntryList *entryList=nullptr)
Definition: TTreeReader.h:148
#define BIT(n)
Definition: Rtypes.h:78
std::deque< ROOT::Internal::TTreeReaderValueBase * > fValues
readers that use our director
Definition: TTreeReader.h:246
void SetTree(const char *keyname, TEntryList *entryList=nullptr)
Definition: TTreeReader.h:154
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
Long64_t fEntry
Entry number of the tree referenced by this iterator; -1 is invalid.
Definition: TTreeReader.h:57
Long64_t fEndEntry
The end of the entry loop.
Definition: TTreeReader.h:254
bool IsValid() const
Whether the iterator points to a valid entry.
Definition: TTreeReader.h:61
THashTable fProxies
attached ROOT::TNamedBranchProxies; owned
Definition: TTreeReader.h:247
Bool_t RegisterValueReader(ROOT::Internal::TTreeReaderValueBase *reader)
Add a value reader for this tree.
EEntryStatus SetEntryBase(Long64_t entry, Bool_t local)
Load an entry into the tree, return the status of the read.
TTree * GetTree() const
Definition: TTreeReader.h:161
THashTable implements a hash table to store TObject&#39;s.
Definition: THashTable.h:35
#define ClassDef(name, id)
Definition: Rtypes.h:320
the tree entry number does not exist
Definition: TTreeReader.h:127
Iterator_t begin()
Return an iterator to the 0th TTree entry.
Definition: TTreeReader.h:217
EEntryStatus fEntryStatus
status of most recent read request
Definition: TTreeReader.h:243
const Long64_t & operator*()
Set the entry number in the reader and return it.
Definition: TTreeReader.h:105
EEntryStatus SetEntriesRange(Long64_t beginEntry, Long64_t endEntry)
Sets the entry that Next() will stop iteration on.
TEntryList * fEntryList
entry list to be used
Definition: TTreeReader.h:242
Iterator_t()
Default-initialize the iterator as "past the end".
Definition: TTreeReader.h:65
Iterator_t end() const
Return an iterator beyond the last TTree entry.
Definition: TTreeReader.h:221
ROOT::Internal::TBranchProxyDirector * fDirector
proxying director, owned
Definition: TTreeReader.h:245
This class defines an abstract interface that must be implemented by all classes that contain diction...
Definition: TDictionary.h:158
Bool_t fProxiesSet
True if the proxies have been set, false otherwise.
Definition: TTreeReader.h:255
Collection abstract base class.
Definition: TCollection.h:63
Long64_t GetEntries(Bool_t force) const
Returns the number of entries of the TEntryList if one is provided, else of the TTree / TChain...
Iterator_t iterator
Definition: TTreeReader.h:121
~TTreeReader()
Tell all value readers that the tree reader does not exist anymore.
EEntryStatus SetEntry(Long64_t entry)
Set the next entry (or index of the TEntryList if that is set).
Definition: TTreeReader.h:179
no entry has been loaded yet
Definition: TTreeReader.h:125
const Long64_t & operator*() const
Definition: TTreeReader.h:116
problem in opening a chain&#39;s file
Definition: TTreeReader.h:129
problem in accessing a chain element, e.g. file without the tree
Definition: TTreeReader.h:128
const Bool_t kFALSE
Definition: RtypesCore.h:88
TTreeReader()=default
void Restart()
Restart a Next() loop from entry 0 (of TEntryList index 0 of fEntryList is set).
TObject * FindObject(const char *name) const
Find object using its name.
Definition: THashTable.cxx:227
Iterator_t operator++(int)
Increment the iterator (postfix i++).
Definition: TTreeReader.h:85
EEntryStatus SetLocalEntry(Long64_t entry)
Set the next local tree entry.
Definition: TTreeReader.h:189
Describe directory structure in memory.
Definition: TDirectory.h:34
EStatusBits
Definition: TObject.h:57
TTree * fTree
tree that&#39;s read
Definition: TTreeReader.h:241
void Initialize()
Initialization of the director.
the tree had a TEntryList and we have warned about that
Definition: TTreeReader.h:238
void DeregisterValueReader(ROOT::Internal::TTreeReaderValueBase *reader)
Remove a value reader for this tree.
problem reading dictionary info from tree
Definition: TTreeReader.h:130
EEntryStatus GetEntryStatus() const
Definition: TTreeReader.h:203
our tree is a chain
Definition: TTreeReader.h:237
Bool_t IsChain() const
Definition: TTreeReader.h:159
Iterator_t & operator++()
Increment the iterator (prefix ++i).
Definition: TTreeReader.h:92
TEntryList * GetEntryList() const
Definition: TTreeReader.h:162
Mother of all ROOT objects.
Definition: TObject.h:37
Bool_t Next()
Move to the next entry (or index of the TEntryList if that is set).
Definition: TTreeReader.h:170
Long64_t fEntry
Current (non-local) entry of fTree or of fEntryList if set.
Definition: TTreeReader.h:249
Class that contains a list of TFileInfo&#39;s and accumulated meta data information about its entries...
static constexpr const char *const fgEntryStatusText[kEntryBeyondEnd+1]
Definition: TTreeReader.h:134
Definition: tree.py:1
bool operator==(const Iterator_t &lhs) const
Compare two iterators for equality.
Definition: TTreeReader.h:73
A TTree object has a header with a name and a title.
Definition: TTree.h:70
void SetTree(TTree *tree, TEntryList *entryList=nullptr)
Set (or update) the which tree to read from.
TTreeReader * fReader
The reader we select the entries on.
Definition: TTreeReader.h:58
Int_t fMostRecentTreeNumber
TTree::GetTreeNumber() of the most recent tree.
Definition: TTreeReader.h:244
A List of entry numbers in a TTree or TChain.
Definition: TEntryList.h:25
const Bool_t kTRUE
Definition: RtypesCore.h:87
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:69
last entry loop has reached its end
Definition: TTreeReader.h:131