Logo ROOT   6.10/09
Reference Guide
basic.cxx
Go to the documentation of this file.
1 #include "TEntryListArray.h"
2 #include "TLeaf.h"
3 #include "TROOT.h"
4 #include "TTree.h"
5 #include "TTreeReader.h"
6 #include "TTreeReaderValue.h"
7 #include "TTreeReaderArray.h"
8 
9 #include "gtest/gtest.h"
10 #include <stdlib.h>
11 
13  double x[3]{};
14  float z = 0.;
15  struct {
16  unsigned int ny = 100;
17  int y[100];
18  } yData;
19  std::string str;
20  Double32_t Double32 = 12.;
21  Float16_t Float16 = -12.;
22 
23 
24  TTree* tree = new TTree("T", "test tree");
25  tree->Branch("one", &x, "x[3]/D");
26  tree->Branch("two", &yData, "ny/i:y[ny]/I");
27  tree->Branch("three", &z, "z");
28  tree->Branch("str", &str);
29  tree->Branch("d32", &Double32);
30  tree->Branch("f16", &Float16);
31 
32  x[1] = 42.;
33  yData.ny = 42;
34  yData.y[0] = 17;
35  str = "first";
36  tree->Fill();
37 
38  x[2] = 43.;
39  yData.ny = 5;
40  yData.y[4] = 7;
41  str = "";
42  tree->Fill();
43 
44  for (int entry = 2; entry < 20; ++entry) {
45  z = entry * (1 - 2 * (entry % 2)); // +entry for even, -entry for odd
46  str = std::string(entry, '*');
47  tree->Fill();
48  }
49 
50  tree->ResetBranchAddresses();
51 
52  return tree;
53 }
54 
55 TEST(TTreeReaderBasic, Interfaces) {
56  TTree* tree = MakeTree();
57 
58  TTreeReader tr(tree);
59  TTreeReaderArray<double> x(tr, "one.x");
60  TTreeReaderArray<int> y(tr, "two.y");
61  TTreeReaderValue<unsigned int> ny(tr, "two.ny");
62  TTreeReaderValue<std::string> nstr(tr, "str");
63 
64  // Before reading data:
65  EXPECT_NE(tr.begin(), tr.end());
66  //MISSING: EXPECT_EQ(2, tr.end() - tr.begin());
67  EXPECT_EQ(-1, tr.GetCurrentEntry());
68  EXPECT_EQ(20, tr.GetEntries(false));
70  EXPECT_EQ(tree, tr.GetTree());
71  EXPECT_FALSE(tr.IsChain());
72 
73  EXPECT_EQ(nullptr, ny.GetAddress());
74  EXPECT_FALSE(ny.IsValid());
75  EXPECT_STREQ("two.ny", ny.GetBranchName());
79 
80  // Skip to second entry:
81  EXPECT_TRUE(tr.Next());
82  EXPECT_TRUE(tr.Next());
83 
84  EXPECT_NE(tr.begin(), tr.end());
85  //MISSING: EXPECT_EQ(2, tr.end() - tr.begin());
86  EXPECT_EQ(1, tr.GetCurrentEntry());
87  EXPECT_EQ(20, tr.GetEntries(false));
88 
89 
90  EXPECT_EQ(5u, *ny);
91  EXPECT_NE(nullptr, ny.GetAddress());
92  EXPECT_TRUE(ny.IsValid());
93  EXPECT_EQ(ny.GetAddress(), ny.Get());
94  EXPECT_STREQ("two", ny.GetBranchName());
95  EXPECT_STREQ("ny", ny.GetLeaf()->GetName());
99 
100  EXPECT_EQ(3u, x.GetSize());
101  EXPECT_EQ(5u, y.GetSize());
102  EXPECT_DOUBLE_EQ(43., x[2]);
103  //FAILS: EXPECT_EQ(7, y[4]);
104 
105  for (int entry = 2; entry < 20; ++entry)
106  EXPECT_TRUE(tr.Next());
107 
108  EXPECT_FALSE(tr.Next());
109  //FAILS: EXPECT_FALSE(ny.IsValid());
110 }
111 
112 
113 TEST(TTreeReaderBasic, ErrorProbing) {
114  TTreeReader tr("doesNotExist", gROOT);
115  EXPECT_EQ(TTreeReader::kEntryNoTree, tr.GetEntryStatus());
116  EXPECT_EQ(nullptr, tr.GetTree());
117 
118  tr.SetTree((TTree*)nullptr);
119  EXPECT_EQ(TTreeReader::kEntryNoTree, tr.GetEntryStatus());
120  EXPECT_EQ(nullptr, tr.GetTree());
121 
123  EXPECT_FALSE(val.IsValid());
124 }
125 
126 
127 TEST(TTreeReaderBasic, Range) {
128  TTree* tree = MakeTree();
129  TTreeReader tr(tree);
130 
131  EXPECT_EQ(TTreeReader::kEntryValid, tr.SetEntriesRange(5, 8));
132 
133  EXPECT_TRUE(tr.Next());
134  EXPECT_EQ(5, tr.GetCurrentEntry());
135  EXPECT_EQ(TTreeReader::kEntryValid, tr.GetEntryStatus());
136 
137  EXPECT_TRUE(tr.Next());
138  EXPECT_EQ(6, tr.GetCurrentEntry());
139  EXPECT_EQ(TTreeReader::kEntryValid, tr.GetEntryStatus());
140 
141  EXPECT_TRUE(tr.Next());
142  EXPECT_EQ(7, tr.GetCurrentEntry());
143  EXPECT_EQ(TTreeReader::kEntryValid, tr.GetEntryStatus());
144 
145  // Reached end:
146  EXPECT_FALSE(tr.Next());
147  EXPECT_EQ(8, tr.GetCurrentEntry());
149 
150  // Read beyond end:
151  EXPECT_FALSE(tr.Next());
153  EXPECT_EQ(9, tr.GetCurrentEntry());
154 
155 
156  // Restart, now with different entries.
157  tr.Restart();
158  EXPECT_EQ(TTreeReader::kEntryValid, tr.SetEntriesRange(0, 2));
159 
160  EXPECT_TRUE(tr.Next());
161  EXPECT_EQ(0, tr.GetCurrentEntry());
162  EXPECT_EQ(TTreeReader::kEntryValid, tr.GetEntryStatus());
163 
164  EXPECT_TRUE(tr.Next());
165  EXPECT_EQ(1, tr.GetCurrentEntry());
166  EXPECT_EQ(TTreeReader::kEntryValid, tr.GetEntryStatus());
167 
168  // Reached end:
169  EXPECT_FALSE(tr.Next());
170  EXPECT_EQ(2, tr.GetCurrentEntry());
172 
173 }
174 
175 TEST(TTreeReaderBasic, InvalidRange) {
176  TTree *tree = MakeTree();
177  TTreeReader tr(tree);
178 
179  EXPECT_EQ(TTreeReader::kEntryNotFound, tr.SetEntriesRange(tree->GetEntries(), 0));
180 
181  // Is SetEntriesRange() simply ignored as it should be?
182  EXPECT_TRUE(tr.Next());
183  EXPECT_EQ(0, tr.GetCurrentEntry());
184  EXPECT_EQ(TTreeReader::kEntryValid, tr.GetEntryStatus());
185 }
186 
187 
188 TEST(TTreeReaderBasic, OneEntryRange) {
189  TTree* tree = MakeTree();
190  TTreeReader tr(tree);
191 
192  EXPECT_EQ(TTreeReader::kEntryValid, tr.SetEntriesRange(1, 2));
193 
194  EXPECT_TRUE(tr.Next());
195  EXPECT_EQ(1, tr.GetCurrentEntry());
196  EXPECT_EQ(TTreeReader::kEntryValid, tr.GetEntryStatus());
197 
198  // Read beyond end:
199  EXPECT_FALSE(tr.Next());
201  EXPECT_EQ(2, tr.GetCurrentEntry());
202 
203  for (int entry = 2; entry < tree->GetEntries(); ++entry)
204  EXPECT_FALSE(tr.Next());
205 }
206 
207 
208 TEST(TTreeReaderBasic, ZeroEntryRange) {
209  TTree* tree = MakeTree();
210  TTreeReader tr(tree);
211 
212  // end is ignored:
213  EXPECT_EQ(TTreeReader::kEntryValid, tr.SetEntriesRange(18, 18));
214 
215  EXPECT_TRUE(tr.Next());
216  EXPECT_EQ(18, tr.GetCurrentEntry());
217  EXPECT_EQ(TTreeReader::kEntryValid, tr.GetEntryStatus());
218 
219  EXPECT_TRUE(tr.Next());
220  EXPECT_EQ(19, tr.GetCurrentEntry());
221  EXPECT_EQ(TTreeReader::kEntryValid, tr.GetEntryStatus());
222 
223  // Read beyond end:
224  EXPECT_FALSE(tr.Next());
225  // As the TTree only has up to entry 19, 20 is kEntryNotFound:
227  EXPECT_EQ(20, tr.GetCurrentEntry());
228 }
229 
230 
231 TEST(TTreeReaderBasic, InvertedEntryRange) {
232  TTree* tree = MakeTree();
233  TTreeReader tr(tree);
234 
235  EXPECT_EQ(TTreeReader::kEntryValid, tr.SetEntriesRange(18, 3));
236 
237  EXPECT_TRUE(tr.Next());
238  EXPECT_EQ(18, tr.GetCurrentEntry());
239  EXPECT_EQ(TTreeReader::kEntryValid, tr.GetEntryStatus());
240 
241  EXPECT_TRUE(tr.Next());
242  EXPECT_EQ(19, tr.GetCurrentEntry());
243  EXPECT_EQ(TTreeReader::kEntryValid, tr.GetEntryStatus());
244 
245  // Read beyond end:
246  EXPECT_FALSE(tr.Next());
247  // As the TTree only has up to entry 19, 20 is kEntryNotFound:
249  EXPECT_EQ(20, tr.GetCurrentEntry());
250 }
251 
252 
253 TEST(TTreeReaderBasic, EntryList) {
254  // See https://root.cern.ch/phpBB3/viewtopic.php?f=3&t=22850&p=100796
255  TTree* tree = MakeTree();
256  EXPECT_EQ(9, tree->Draw(">>negZ","three.z<0", "entrylistarray"));
257  TEntryListArray* selected = (TEntryListArray*)gDirectory->Get("negZ");
258  TTreeReader aReader(tree, selected);
259 
260  EXPECT_EQ(9, aReader.GetEntries(false));
261 
262  TTreeReaderValue<float> z(aReader, "three.z");
263 
264  int count = 0;
265  while (aReader.Next()) {
266  // Make sure all Next()-ed entries have z<0 as selected by the entry list.
267  EXPECT_LT(*z, 0);
268  ++count;
269  }
270  EXPECT_EQ(9, count);
271 
272  aReader.Restart();
273  EXPECT_EQ(TTreeReader::kEntryValid, aReader.SetEntriesRange(0, 2));
274 
275  EXPECT_TRUE(aReader.Next());
276  EXPECT_EQ(0, aReader.GetCurrentEntry());
277  EXPECT_EQ(TTreeReader::kEntryValid, aReader.GetEntryStatus());
278 
279  EXPECT_EQ(9, aReader.GetEntries(false));
280 }
281 
282 TEST(TTreeReaderBasic, EntryListBeyondEnd) {
283  TTree* tree = MakeTree();
284  TEntryList selected;
285  // Add the last valid entry; a subsequent Next() must return false.
286  selected.Enter(tree->GetEntries() - 1);
287 
288  TTreeReader aReader(tree, &selected);
289 
290  EXPECT_EQ(1, aReader.GetEntries(false));
291 
292  EXPECT_TRUE(aReader.Next());
293  EXPECT_EQ(0, aReader.GetCurrentEntry());
294  EXPECT_EQ(TTreeReader::kEntryValid, aReader.GetEntryStatus());
295 
296  EXPECT_FALSE(aReader.Next());
297  EXPECT_EQ(1, aReader.GetCurrentEntry());
298  EXPECT_EQ(TTreeReader::kEntryNotFound, aReader.GetEntryStatus());
299 }
300 
301 
302 TEST(TTreeReaderBasic, Values) {
303  TTree* tree = MakeTree();
304  TTreeReader tr(tree);
305  TTreeReaderArray<double> x(tr, "one.x");
306  TTreeReaderArray<int> y(tr, "two.y");
307  TTreeReaderValue<unsigned int> ny(tr, "two.ny");
308  TTreeReaderValue<std::string> str(tr, "str");
309  TTreeReaderValue<Double32_t> d32(tr, "d32");
310  TTreeReaderValue<Float16_t> f16(tr, "f16");
311 
312  // Check values for first entry.
313  EXPECT_TRUE(tr.Next());
314 
315  EXPECT_DOUBLE_EQ(42, x[1]);
316  EXPECT_EQ(42u, *ny);
317  // FAILS! Already in TLeafI, fNData == 42 (good!) but GetValue(0) == 0.
318  // EXPECT_EQ(17, y[0]);
319  EXPECT_STREQ("first", str->c_str());
320  EXPECT_FLOAT_EQ(12, *d32);
321  EXPECT_FLOAT_EQ(-12, *f16);
322 }
the tree does not exist
Definition: TTreeReader.h:127
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
TEST(TTreeReaderBasic, Interfaces)
Definition: basic.cxx:55
TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple...
Definition: TTreeReader.h:43
The branch class type is not a collection.
A list of entries and subentries in a TTree or TChain.
Long64_t GetCurrentEntry() const
Returns the index of the current entry being read.
Definition: TTreeReader.h:209
virtual Int_t Fill()
Fill all branches.
Definition: TTree.cxx:4383
#define gROOT
Definition: TROOT.h:375
EReadStatus ProxyRead()
Try to read the value from the TBranchProxy, returns the status of the read.
float Float16_t
Definition: RtypesCore.h:54
TTree * GetTree() const
Definition: TTreeReader.h:152
Double_t x[n]
Definition: legend1.C:17
TTree * MakeTree()
Definition: basic.cxx:12
const int ny
Definition: kalman.C:17
the tree entry number does not exist
Definition: TTreeReader.h:128
virtual EReadStatus GetReadStatus() const
Iterator_t begin()
Return an iterator to the 0th TTree entry.
Definition: TTreeReader.h:212
double Double32_t
Definition: RtypesCore.h:56
Extracts data from a TTree.
Iterator_t end() const
Return an iterator beyond the last TTree entry.
Definition: TTreeReader.h:216
Long64_t GetEntries(Bool_t force) const
no entry has been loaded yet
Definition: TTreeReader.h:126
void * GetAddress()
Returns the memory address of the object being read.
void Restart()
Restart a Next() loop from entry 0 (of TEntryList index 0 of fEntryList is set).
Extracts array data from a TTree.
please use SetEntriesRange()!")
Definition: TTreeReader.h:188
virtual void ResetBranchAddresses()
Tell all of our branches to drop their current objects and allocate new ones.
Definition: TTree.cxx:7629
virtual void Draw(Option_t *opt)
Default Draw method for all objects.
Definition: TTree.h:355
Double_t y[n]
Definition: legend1.C:17
virtual Bool_t Enter(Long64_t entry, TTree *tree=0)
Add entry #entry to the list.
Definition: TEntryList.cxx:562
EEntryStatus GetEntryStatus() const
Definition: TTreeReader.h:198
virtual Long64_t GetEntries() const
Definition: TTree.h:381
Bool_t IsChain() const
Definition: TTreeReader.h:150
TLeaf * GetLeaf()
If we are reading a leaf, return the corresponding TLeaf.
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
virtual Int_t Branch(TCollection *list, Int_t bufsize=32000, Int_t splitlevel=99, const char *name="")
Create one branch for each element in the collection.
Definition: TTree.cxx:1660
Ta Range(0, 0, 1, 1)
Bool_t Next()
Move to the next entry (or index of the TEntryList if that is set).
Definition: TTreeReader.h:161
Definition: tree.py:1
A TTree object has a header with a name and a title.
Definition: TTree.h:78
#define gDirectory
Definition: TDirectory.h:211
void SetTree(TTree *tree, TEntryList *entryList=nullptr)
A List of entry numbers in a TTree or TChain.
Definition: TEntryList.h:25
last entry loop has reached its end
Definition: TTreeReader.h:132