12 #ifndef ROOT_TTreeReader
13 #define ROOT_TTreeReader
31 #include <unordered_map>
35 class TFileCollection;
39 class TBranchProxyDirector;
43 class TTreeReader:
public TObject {
56 public std::iterator<std::input_iterator_tag, const Long64_t, Long64_t> {
62 bool IsValid()
const {
return fEntry >= 0; }
66 Iterator_t(): fEntry(-1), fReader() {}
70 Iterator_t(TTreeReader& reader, Long64_t entry):
71 fEntry(entry), fReader(&reader) {}
74 bool operator==(
const Iterator_t& lhs)
const {
76 if (!IsValid() && !lhs.IsValid())
return true;
77 return fEntry == lhs.fEntry && fReader == lhs.fReader;
81 bool operator!=(
const Iterator_t& lhs)
const {
82 return !(*
this == lhs);
86 Iterator_t operator++(
int) {
87 Iterator_t ret = *
this;
93 Iterator_t& operator++() {
106 const Long64_t& operator*() {
109 if (fReader->SetEntry(fEntry) != kEntryValid) {
117 const Long64_t& operator*()
const {
118 return **
const_cast<Iterator_t*
>(
this);
122 typedef Iterator_t iterator;
129 kEntryChainSetupError,
130 kEntryChainFileError,
131 kEntryDictionaryError,
137 enum ELoadTreeStatus {
144 static constexpr
const char *
const fgEntryStatusText[kEntryBeyondEnd + 1] = {
146 "the tree does not exist",
147 "the tree entry number does not exist",
148 "cannot access chain element",
149 "problem in opening a chain's file",
150 "problem reading dictionary info from tree",
151 "last entry loop has reached its end"
156 TTreeReader(TTree* tree, TEntryList* entryList =
nullptr);
157 TTreeReader(
const char* keyname, TDirectory* dir, TEntryList* entryList =
nullptr);
158 TTreeReader(
const char* keyname, TEntryList* entryList =
nullptr):
159 TTreeReader(keyname, nullptr, entryList) {}
163 void SetTree(TTree* tree, TEntryList* entryList =
nullptr);
164 void SetTree(
const char* keyname, TEntryList* entryList =
nullptr) {
165 SetTree(keyname,
nullptr, entryList);
167 void SetTree(
const char* keyname, TDirectory* dir, TEntryList* entryList =
nullptr);
169 Bool_t IsChain()
const {
return TestBit(kBitIsChain); }
171 Bool_t IsInvalid()
const {
return fLoadTreeStatus == kNoTree; }
173 TTree* GetTree()
const {
return fTree; }
174 TEntryList* GetEntryList()
const {
return fEntryList; }
183 return SetEntry(GetCurrentEntry() + 1) == kEntryValid;
191 EEntryStatus SetEntry(Long64_t entry) {
return SetEntryBase(entry, kFALSE); }
201 EEntryStatus SetLocalEntry(Long64_t entry) {
return SetEntryBase(entry, kTRUE); }
208 EEntryStatus SetEntriesRange(Long64_t beginEntry, Long64_t endEntry);
213 std::pair<Long64_t, Long64_t> GetEntriesRange()
const {
return std::make_pair(fBeginEntry, fEndEntry); }
220 EEntryStatus GetEntryStatus()
const {
return fEntryStatus; }
222 Long64_t GetEntries()
const;
223 Long64_t GetEntries(Bool_t force);
232 Long64_t GetCurrentEntry()
const {
return fEntry; }
238 return Iterator_t(*
this, 0);
241 Iterator_t end()
const {
return Iterator_t(); }
244 using NamedProxies_t = std::unordered_map<std::string, std::unique_ptr<ROOT::Internal::TNamedBranchProxy>>;
246 ROOT::Internal::TNamedBranchProxy* FindProxy(
const char* branchname)
const
248 const auto proxyIt = fProxies.find(branchname);
249 return fProxies.end() != proxyIt ? proxyIt->second.get() :
nullptr;
252 void AddProxy(ROOT::Internal::TNamedBranchProxy *p)
254 auto bpName = p->GetName();
256 if (fProxies.end() != fProxies.find(bpName)) {
257 std::string err =
"A proxy with key " + std::string(bpName) +
" was already stored!";
258 throw std::runtime_error(err);
262 fProxies[bpName].reset(p);
265 Bool_t RegisterValueReader(ROOT::Internal::TTreeReaderValueBase* reader);
266 void DeregisterValueReader(ROOT::Internal::TTreeReaderValueBase* reader);
268 EEntryStatus SetEntryBase(Long64_t entry, Bool_t local);
274 std::string GetProxyKey(
const char *branchname)
276 std::string key(branchname);
282 kBitIsChain = BIT(14),
283 kBitHaveWarnedAboutEntryListAttachedToTTree = BIT(15),
284 kBitSetEntryBaseCallingLoadTree = BIT(16)
287 TTree* fTree =
nullptr;
288 TEntryList* fEntryList =
nullptr;
289 EEntryStatus fEntryStatus = kEntryNotLoaded;
290 ELoadTreeStatus fLoadTreeStatus = kNoTree;
291 TNotifyLink<TTreeReader> fNotify;
292 ROOT::Internal::TBranchProxyDirector* fDirector =
nullptr;
293 std::deque<ROOT::Internal::TFriendProxy*> fFriendProxies;
294 std::deque<ROOT::Internal::TTreeReaderValueBase*> fValues;
295 NamedProxies_t fProxies;
297 Long64_t fEntry = -1;
302 Long64_t fEndEntry = -1LL;
303 Long64_t fBeginEntry = 0LL;
304 Bool_t fProxiesSet = kFALSE;
305 Bool_t fSetEntryBaseCallingLoadTree = kFALSE;
307 friend class ROOT::Internal::TTreeReaderValueBase;
308 friend class ROOT::Internal::TTreeReaderArrayBase;
310 ClassDef(TTreeReader, 0);
313 #endif // defined TTreeReader