Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TTreeReaderFast.cxx
Go to the documentation of this file.
1 // Author: Brian Bockelman, 2017-03-21
2 
3 /*************************************************************************
4  * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers and al. *
5  * All rights reserved. *
6  * *
7  * For the licensing terms see $ROOTSYS/LICENSE. *
8  * For the list of contributors see $ROOTSYS/README/CREDITS. *
9  *************************************************************************/
10 
11 #include <climits>
12 
13 #include "TTreeReader.h"
14 #include "ROOT/TTreeReaderFast.hxx"
15 
16 #include "TChain.h"
17 #include "TDirectory.h"
19 
20 using namespace ROOT::Experimental;
21 
22 TTreeReaderFast::TTreeReaderFast(TTree* tree):
23  fTree(tree)
24 {
25  if (!fTree) {
26  ::Error("TTreeReaderFast::TTreeReaderFast", "TTree is NULL!");
27  } else {
28  Initialize();
29  }
30 }
31 
32 TTreeReaderFast::TTreeReaderFast(const char* keyname, TDirectory* dir /*= NULL*/):
33  fDirectory(dir)
34 {
35  if (!fDirectory) fDirectory = gDirectory;
36  fDirectory->GetObject(keyname, fTree);
37  Initialize();
38 }
39 
40 ////////////////////////////////////////////////////////////////////////////////
41 /// Tell all value readers that the tree reader does not exist anymore.
42 
43 TTreeReaderFast::~TTreeReaderFast()
44 {
45  for (auto &reader : fValues) {
46  reader->MarkTreeReaderUnavailable();
47  }
48 }
49 
50 ////////////////////////////////////////////////////////////////////////////////
51 /// Initialization of the director.
52 
53 void TTreeReaderFast::Initialize()
54 {
55  if (!fTree) {
56  MakeZombie();
57  fEntryStatus = TTreeReader::kEntryNoTree;
58  } else {
59  fDirector = new ROOT::Internal::TBranchProxyDirector(fTree, -1);
60  }
61 
62  bool IsOK = true;
63  // Tell readers we now have a tree
64  for (auto &reader : fValues) {
65  reader->CreateProxy();
66  if (reader->GetSetupStatus() != ROOT::Internal::TTreeReaderValueBase::kSetupMatch) {
67  //printf("Reader setup failed. Status: %d\n", reader->GetSetupStatus());
68  IsOK = false;
69  }
70  }
71  if (!IsOK) {
72  //printf("Failed to initialize the reader.\n");
73  fEntryStatus = TTreeReader::kEntryBadReader;
74  }
75 }
76 
77 ////////////////////////////////////////////////////////////////////////////////
78 /// Set an entry to be read.
79 
80 TTreeReader::EEntryStatus
81 TTreeReaderFast::SetEntry(Long64_t entry)
82 {
83  if (!fTree) {
84  fEntryStatus =TTreeReader::kEntryNoTree;
85  return fEntryStatus;
86  }
87 
88  TTree* prevTree = fDirector->GetTree();
89 
90  Int_t treeNumInChainBeforeLoad = fTree->GetTreeNumber();
91 
92  TTree* treeToCallLoadOn = fTree->GetTree();
93  Long64_t loadResult = treeToCallLoadOn->LoadTree(entry);
94 
95  if (loadResult == -2) {
96  fEntryStatus = TTreeReader::kEntryNotFound;
97  return fEntryStatus;
98  }
99 
100  if (treeNumInChainBeforeLoad != fTree->GetTreeNumber()) {
101  fDirector->SetTree(fTree->GetTree());
102  }
103 
104  if (!prevTree || fDirector->GetReadEntry() == -1)
105  {
106  bool IsOK = true;
107  // Tell readers we now have a tree
108  for (auto &reader : fValues) {
109  reader->CreateProxy();
110  if (reader->GetSetupStatus() != ROOT::Internal::TTreeReaderValueBase::kSetupMatch) IsOK = false;
111  }
112  fEntryStatus = IsOK ? TTreeReader::kEntryValid : TTreeReader::kEntryBadReader;
113  }
114 
115  return fEntryStatus;
116 }
117 
118 ////////////////////////////////////////////////////////////////////////////////
119 /// Add a value reader for this tree.
120 
121 void TTreeReaderFast::RegisterValueReader(ROOT::Experimental::Internal::TTreeReaderValueFastBase* reader)
122 {
123  fValues.push_back(reader);
124 }
125 
126 ////////////////////////////////////////////////////////////////////////////////
127 /// Remove a value reader for this tree.
128 
129 void TTreeReaderFast::DeregisterValueReader(ROOT::Experimental::Internal::TTreeReaderValueFastBase* reader)
130 {
131  auto iReader = std::find(fValues.begin(), fValues.end(), reader);
132  if (iReader == fValues.end()) {
133  Error("DeregisterValueReader", "Cannot find reader of type %s for branch %s", reader->GetTypeName(), reader->fBranchName.c_str());
134  return;
135  }
136  fValues.erase(iReader);
137 }
138 
139 ////////////////////////////////////////////////////////////////////////////////
140 /// Advance to the next range in the file; returns the number of events in the range.
141 ///
142 /// Returned number is the number of events we can process before one of the Value
143 /// objects will hit the end of its buffer.
144 
145 Int_t
146 TTreeReaderFast::GetNextRange(Int_t eventNum)
147 {
148  Int_t remaining = INT_MAX;
149  for (auto &value : fValues) {
150  Int_t valueRemaining = value->GetEvents(eventNum);
151  if (valueRemaining < remaining) {
152  remaining = valueRemaining;
153  }
154  }
155  //printf("TTreeReaderFast::GetNextRange: Starting at %d, remaining events %d.\n", eventNum, remaining);
156  return remaining;
157 }
158