Logo ROOT   6.07/09
Reference Guide
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 "TTreeReaderValue.h"
17 
18 /** \class TTreeReader
19  TTreeReader is a simple, robust and fast interface to read values from a TTree,
20  TChain or TNtuple.
21 
22  It uses TTreeReaderValue<T> and TTreeReaderArray<T> to access the data.
23 
24  Example code can be found in
25  tutorials/tree/hsimpleReader.C and tutorials/trees/h1analysisTreeReader.h and
26  tutorials/trees/h1analysisTreeReader.C for a TSelector.
27 
28  Roottest contains an
29  <a href="http://root.cern.ch/gitweb?p=roottest.git;a=tree;f=root/tree/reader;hb=HEAD">example</a>
30  showing the full power.
31 
32 A simpler analysis example - the one from the tutorials - can be found below:
33 it histograms a function of the px and py branches.
34 
35 ~~~{.cpp}
36 // A simple TTreeReader use: read data from hsimple.root (written by hsimple.C)
37 
38 #include "TFile.h
39 #include "TH1F.h
40 #include "TTreeReader.h
41 #include "TTreeReaderValue.h
42 
43 void hsimpleReader() {
44  // Create a histogram for the values we read.
45  TH1F("h1", "ntuple", 100, -4, 4);
46 
47  // Open the file containing the tree.
48  TFile *myFile = TFile::Open("$ROOTSYS/tutorials/hsimple.root");
49 
50  // Create a TTreeReader for the tree, for instance by passing the
51  // TTree's name and the TDirectory / TFile it is in.
52  TTreeReader myReader("ntuple", myFile);
53 
54  // The branch "px" contains floats; access them as myPx.
55  TTreeReaderValue<Float_t> myPx(myReader, "px");
56  // The branch "py" contains floats, too; access those as myPy.
57  TTreeReaderValue<Float_t> myPy(myReader, "py");
58 
59  // Loop over all entries of the TTree or TChain.
60  while (myReader.Next()) {
61  // Just access the data as if myPx and myPy were iterators (note the '*'
62  // in front of them):
63  myHist->Fill(*myPx + *myPy);
64  }
65 
66  myHist->Draw();
67 }
68 ~~~
69 
70 A more complete example including error handling and a few combinations of
71 TTreeReaderValue and TTreeReaderArray would look like this:
72 
73 ~~~{.cpp}
74 #include <TFile.h>
75 #include <TH1.h>
76 #include <TTreeReader.h>
77 #include <TTreeReaderValue.h>
78 #include <TTreeReaderArray.h>
79 
80 #include "TriggerInfo.h"
81 #include "Muon.h"
82 #include "Tau.h"
83 
84 #include <vector>
85 #include <iostream>
86 
87 bool CheckValue(ROOT::TTreeReaderValueBase* value) {
88  if (value->GetSetupStatus() < 0) {
89  std::cerr << "Error " << value->GetSetupStatus()
90  << "setting up reader for " << value->GetBranchName() << '\n';
91  return false;
92  }
93  return true;
94 }
95 
96 
97 // Analyze the tree "MyTree" in the file passed into the function.
98 // Returns false in case of errors.
99 bool analyze(TFile* file) {
100  // Create a TTreeReader named "MyTree" from the given TDirectory.
101  // The TTreeReader gives access to the TTree to the TTreeReaderValue and
102  // TTreeReaderArray objects. It knows the current entry number and knows
103  // how to iterate through the TTree.
104  TTreeReader reader("MyTree", file);
105 
106  // Read a single float value in each tree entries:
107  TTreeReaderValue<float> weight(reader, "event.weight");
108  if (!CheckValue(weight)) return false;
109 
110  // Read a TriggerInfo object from the tree entries:
111  TTreeReaderValue<TriggerInfo> triggerInfo(reader, "triggerInfo");
112  if (!CheckValue(triggerInfo)) return false;
113 
114  //Read a vector of Muon objects from the tree entries:
115  TTreeReaderValue<std::vector<Muon>> muons(reader, "muons");
116  if (!CheckValue(muons)) return false;
117 
118  //Read the pT for all jets in the tree entry:
119  TTreeReaderArray<double> jetPt(reader, "jets.pT");
120  if (!CheckValue(jetPt)) return false;
121 
122  // Read the taus in the tree entry:
123  TTreeReaderArray<Tau> taus(reader, "taus");
124  if (!CheckValue(taus)) return false;
125 
126 
127  // Now iterate through the TTree entries and fill a histogram.
128 
129  TH1F("hist", "TTreeReader example histogram", 10, 0., 100.);
130 
131  while (reader.Next()) {
132 
133  if (reader.GetEntryStatus() == kEntryValid) {
134  std::cout << "Loaded entry " << reader.GetCurrentEntry() << '\n';
135  } else {
136  switch (reader.GetEntryStatus()) {
137  kEntryValid:
138  // Handled above.
139  break;
140  kEntryNotLoaded:
141  std::cerr << "Error: TTreeReader has not loaded any data yet!\n";
142  break;
143  kEntryNoTree:
144  std::cerr << "Error: TTreeReader cannot find a tree names \"MyTree\"!\n";
145  break;
146  kEntryNotFound:
147  // Can't really happen as TTreeReader::Next() knows when to stop.
148  std::cerr << "Error: The entry number doe not exist\n";
149  break;
150  kEntryChainSetupError:
151  std::cerr << "Error: TTreeReader cannot access a chain element, e.g. file without the tree\n";
152  break;
153  kEntryChainFileError:
154  std::cerr << "Error: TTreeReader cannot open a chain element, e.g. missing file\n";
155  break;
156  kEntryDictionaryError:
157  std::cerr << "Error: TTreeReader cannot find the dictionary for some data\n";
158  break;
159  }
160  return false;
161  }
162 
163  // Access the TriggerInfo object as if it's a pointer.
164  if (!triggerInfo->hasMuonL1())
165  continue;
166 
167  // Ditto for the vector<Muon>.
168  if (!muons->size())
169  continue;
170 
171  // Access the jetPt as an array, whether the TTree stores this as
172  // a std::vector, std::list, TClonesArray or Jet* C-style array, with
173  // fixed or variable array size.
174  if (jetPt.GetSize() < 2 || jetPt[0] < 100)
175  continue;
176 
177  // Access the array of taus.
178  if (!taus.IsEmpty()) {
179  float currentWeight = *weight;
180  for (int iTau = 0, nTau = taus.GetSize(); iTau < nTau; ++iTau) {
181  // Access a float value - need to dereference as TTreeReaderValue
182  // behaves like an iterator
183  hist->Fill(taus[iTau].eta(), currentWeight);
184  }
185  }
186  } // TTree entry / event loop
187 }
188 ~~~
189 */
190 
192 
193 using namespace ROOT::Internal;
194 
195 ////////////////////////////////////////////////////////////////////////////////
196 /// Access data from tree.
197 
199  fTree(tree),
200  fDirectory(0),
201  fEntryStatus(kEntryNotLoaded),
202  fDirector(0),
203  fLastEntry(-1),
204  fProxiesSet(kFALSE)
205 {
206  if (!fTree) {
207  Error("TTreeReader", "TTree is NULL!");
208  } else {
209  Initialize();
210  }
211 }
212 
213 ////////////////////////////////////////////////////////////////////////////////
214 /// Access data from the tree called keyname in the directory (e.g. TFile)
215 /// dir, or the current directory if dir is NULL. If keyname cannot be
216 /// found, or if it is not a TTree, IsZombie() will return true.
217 
218 TTreeReader::TTreeReader(const char* keyname, TDirectory* dir /*= NULL*/):
219  fTree(0),
220  fDirectory(dir),
221  fEntryStatus(kEntryNotLoaded),
222  fDirector(0),
223  fLastEntry(-1),
224  fProxiesSet(kFALSE)
225 {
227  fDirectory->GetObject(keyname, fTree);
228  Initialize();
229 }
230 
231 ////////////////////////////////////////////////////////////////////////////////
232 /// Tell all value readers that the tree reader does not exist anymore.
233 
235 {
236  for (std::deque<ROOT::Internal::TTreeReaderValueBase*>::const_iterator
237  i = fValues.begin(), e = fValues.end(); i != e; ++i) {
238  (*i)->MarkTreeReaderUnavailable();
239  }
240  delete fDirector;
241  fProxies.SetOwner();
242 }
243 
244 ////////////////////////////////////////////////////////////////////////////////
245 /// Initialization of the director.
246 
248 {
249  if (!fTree) {
250  MakeZombie();
252  } else {
254  }
255 }
256 
257 ////////////////////////////////////////////////////////////////////////////////
258 /// Set the range of entries to be processed.
259 /// If last > first, this call is equivalent to
260 /// `SetEntry(first); SetLastEntry(last);`. Otherwise `last` is ignored and
261 /// only `first` is set.
262 /// \return the EEntryStatus that would be returned by SetEntry(first)
263 
265 {
266  if(last > first)
267  fLastEntry = last;
268  else
269  fLastEntry = -1;
270  return SetEntry(first);
271 }
272 
273 ////////////////////////////////////////////////////////////////////////////////
274 ///Returns the index of the current entry being read
275 
277  if (!fDirector) return 0;
278  Long64_t currentTreeEntry = fDirector->GetReadEntry();
279  if (fTree->IsA() == TChain::Class() && currentTreeEntry >= 0) {
280  return ((TChain*)fTree)->GetChainEntryNumber(currentTreeEntry);
281  }
282  return currentTreeEntry;
283 }
284 
285 ////////////////////////////////////////////////////////////////////////////////
286 /// Load an entry into the tree, return the status of the read.
287 /// For chains, entry is the global (i.e. not tree-local) entry number, unless
288 /// `local` is `true`, in which case `entry` specifies the entry number within
289 /// the current tree. This is needed for instance for TSelector::Process().
290 
292 {
293  if (!fTree) {
295  return fEntryStatus;
296  }
297 
298  TTree* prevTree = fDirector->GetTree();
299 
300  Int_t treeNumInChainBeforeLoad = fTree->GetTreeNumber();
301 
302  TTree* treeToCallLoadOn = local ? fTree->GetTree() : fTree;
303  Long64_t loadResult = treeToCallLoadOn->LoadTree(entry);
304 
305  if (loadResult == -2) {
307  return fEntryStatus;
308  }
309 
310  if (treeNumInChainBeforeLoad != fTree->GetTreeNumber()) {
312  }
313 
314  if (!prevTree || fDirector->GetReadEntry() == -1 || !fProxiesSet) {
315  // Tell readers we now have a tree
316  for (std::deque<ROOT::Internal::TTreeReaderValueBase*>::const_iterator
317  i = fValues.begin(); i != fValues.end(); ++i) { // Iterator end changes when parameterized arrays are read
318  (*i)->CreateProxy();
319 
320  if (!(*i)->GetProxy()){
322  return fEntryStatus;
323  }
324  }
325  // If at least one proxy was there and no error occurred, we assume the proxies to be set.
326  fProxiesSet = !fValues.empty();
327  }
328  if (fLastEntry >= 0 && loadResult >= fLastEntry) {
330  return fEntryStatus;
331  }
332  fDirector->SetReadEntry(loadResult);
334  return fEntryStatus;
335 }
336 
337 ////////////////////////////////////////////////////////////////////////////////
338 /// Set (or update) the which tree to reader from. tree can be
339 /// a TTree or a TChain.
340 
342 {
343  fTree = tree;
344  if (fTree) {
345  ResetBit(kZombie);
346  if (fTree->InheritsFrom(TChain::Class())) {
348  }
349  }
350 
351  if (!fDirector) {
352  Initialize();
353  }
354  else {
356  fDirector->SetReadEntry(-1);
357  }
358 }
359 
360 ////////////////////////////////////////////////////////////////////////////////
361 /// Add a value reader for this tree.
362 
364 {
365  fValues.push_back(reader);
366 }
367 
368 ////////////////////////////////////////////////////////////////////////////////
369 /// Remove a value reader for this tree.
370 
372 {
373  std::deque<ROOT::Internal::TTreeReaderValueBase*>::iterator iReader
374  = std::find(fValues.begin(), fValues.end(), reader);
375  if (iReader == fValues.end()) {
376  Error("DeregisterValueReader", "Cannot find reader of type %s for branch %s", reader->GetDerivedTypeName(), reader->fBranchName.Data());
377  return;
378  }
379  fValues.erase(iReader);
380 }
the tree does not exist
Definition: TTreeReader.h:132
object ctor failed
Definition: TObject.h:77
long long Long64_t
Definition: RtypesCore.h:69
TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple...
Definition: TTreeReader.h:48
This namespace contains pre-defined functions to be used in conjuction with TExecutor::Map and TExecu...
Definition: StringConv.hxx:21
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:488
last entry was reached
Definition: TTreeReader.h:137
void GetObject(const char *namecycle, T *&ptr)
Definition: TDirectory.h:147
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
std::deque< ROOT::Internal::TTreeReaderValueBase * > fValues
readers that use our director
Definition: TTreeReader.h:200
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual const char * GetDerivedTypeName() const =0
const char * Class
Definition: TXMLSetup.cxx:64
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:739
THashTable fProxies
attached ROOT::TNamedBranchProxies; owned
Definition: TTreeReader.h:201
const char * Data() const
Definition: TString.h:349
EEntryStatus SetEntryBase(Long64_t entry, Bool_t local)
Load an entry into the tree, return the status of the read.
virtual Long64_t LoadTree(Long64_t entry)
Set current entry.
Definition: TTree.cxx:5967
the tree entry number does not exist
Definition: TTreeReader.h:133
Long64_t GetCurrentEntry() const
Returns the index of the current entry being read.
TDirectory * fDirectory
directory (or current file for chains)
Definition: TTreeReader.h:197
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:925
EEntryStatus fEntryStatus
status of most recent read request
Definition: TTreeReader.h:198
void Error(const char *location, const char *msgfmt,...)
Long64_t fLastEntry
The last entry to be processed.
Definition: TTreeReader.h:206
void RegisterValueReader(ROOT::Internal::TTreeReaderValueBase *reader)
Add a value reader for this tree.
ROOT::Internal::TBranchProxyDirector * fDirector
proxying director, owned
Definition: TTreeReader.h:199
void Initialize(Bool_t useTMVAStyle=kTRUE)
Definition: tmvaglob.cxx:176
virtual Int_t GetTreeNumber() const
Definition: TTree.h:445
Bool_t fProxiesSet
True if the proxies have been set, false otherwise.
Definition: TTreeReader.h:207
~TTreeReader()
Tell all value readers that the tree reader does not exist anymore.
EEntryStatus SetEntry(Long64_t entry)
Definition: TTreeReader.h:162
#define ClassImp(name)
Definition: Rtypes.h:279
Describe directory structure in memory.
Definition: TDirectory.h:44
TTree * fTree
tree that&#39;s read
Definition: TTreeReader.h:196
void Initialize()
Initialization of the director.
void DeregisterValueReader(ROOT::Internal::TTreeReaderValueBase *reader)
Remove a value reader for this tree.
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
virtual TTree * GetTree() const
Definition: TTree.h:443
problem reading dictionary info from tree
Definition: TTreeReader.h:136
our tree is a chain
Definition: TTreeReader.h:193
void MakeZombie()
Definition: TObject.h:54
A chain is a collection of files containg TTree objects.
Definition: TChain.h:35
Definition: tree.py:1
A TTree object has a header with a name and a title.
Definition: TTree.h:98
#define gDirectory
Definition: TDirectory.h:221
void SetTree(TTree *tree)
Set (or update) the which tree to reader from.
void ResetBit(UInt_t f)
Definition: TObject.h:158
Definition: first.py:1
EEntryStatus SetEntriesRange(Long64_t first, Long64_t last)
Set the range of entries to be processed.