File indexing completed on 2025-12-16 10:31:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef ROOT_TTreeReader
0014 #define ROOT_TTreeReader
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include "TTree.h"
0026 #include "TTreeReaderUtils.h"
0027 #include "TNotifyLink.h"
0028
0029 #include <deque>
0030 #include <iterator>
0031 #include <unordered_map>
0032 #include <set>
0033 #include <string>
0034
0035 class TDictionary;
0036 class TDirectory;
0037 class TFileCollection;
0038
0039 namespace ROOT {
0040 namespace Internal {
0041 class TBranchProxyDirector;
0042 class TFriendProxy;
0043 }
0044 }
0045
0046 class TTreeReader : public TObject {
0047 public:
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 class Iterator_t {
0058 private:
0059 Long64_t fEntry;
0060 TTreeReader *fReader;
0061
0062
0063 bool IsValid() const { return fEntry >= 0; }
0064
0065 public:
0066 using iterator_category = std::input_iterator_tag;
0067 using value_type = const Long64_t;
0068 using difference_type = Long64_t;
0069 using pointer = const Long64_t *;
0070 using const_pointer = const Long64_t *;
0071 using reference = const Long64_t &;
0072
0073
0074 Iterator_t() : fEntry(-1), fReader(nullptr) {}
0075
0076
0077
0078 Iterator_t(TTreeReader &reader, Long64_t entry) : fEntry(entry), fReader(&reader) {}
0079
0080
0081 bool operator==(const Iterator_t &lhs) const
0082 {
0083
0084 if (!IsValid() && !lhs.IsValid())
0085 return true;
0086
0087 if (fReader != lhs.fReader)
0088 return false;
0089
0090
0091
0092
0093
0094
0095
0096
0097 if (fReader->GetTree()->GetEntriesFast() == 0 && fEntry == 0 && !lhs.IsValid()) {
0098 return true;
0099 }
0100 if (lhs.fReader->GetTree()->GetEntriesFast() == 0 && lhs.fEntry == 0 && !IsValid()) {
0101 return true;
0102 }
0103 return fEntry == lhs.fEntry;
0104 }
0105
0106
0107 bool operator!=(const Iterator_t &lhs) const { return !(*this == lhs); }
0108
0109
0110 Iterator_t operator++(int)
0111 {
0112 Iterator_t ret = *this;
0113 this->operator++();
0114 return ret;
0115 }
0116
0117
0118 Iterator_t &operator++()
0119 {
0120 if (IsValid()) {
0121 ++fEntry;
0122
0123 this->operator*();
0124
0125
0126
0127 }
0128 return *this;
0129 }
0130
0131
0132 const Long64_t &operator*()
0133 {
0134 if (IsValid()) {
0135
0136 if (fReader->SetEntry(fEntry) != kEntryValid) {
0137 fEntry = -1;
0138 }
0139 }
0140
0141 return fEntry;
0142 }
0143
0144 const Long64_t &operator*() const { return **const_cast<Iterator_t *>(this); }
0145 };
0146
0147 typedef Iterator_t iterator;
0148
0149 enum EEntryStatus {
0150 kEntryValid = 0,
0151 kEntryNotLoaded,
0152 kEntryNoTree,
0153 kEntryNotFound,
0154 kEntryChainSetupError,
0155 kEntryChainFileError,
0156 kEntryDictionaryError,
0157 kEntryBeyondEnd,
0158 kEntryBadReader,
0159 kIndexedFriendNoMatch,
0160 kMissingBranchWhenSwitchingTree,
0161 kEntryUnknownError
0162 };
0163
0164 enum ELoadTreeStatus {
0165 kNoTree = 0,
0166 kLoadTreeNone,
0167 kInternalLoadTree,
0168 kExternalLoadTree,
0169 kMissingBranchFromTree
0170 };
0171
0172 static constexpr const char *const fgEntryStatusText[kEntryUnknownError + 1] = {
0173 "valid entry",
0174 "the tree does not exist",
0175 "the tree entry number does not exist",
0176 "cannot access chain element",
0177 "problem in opening a chain's file",
0178 "problem reading dictionary info from tree",
0179 "last entry loop has reached its end",
0180 "one of the readers was not successfully initialized",
0181 "A friend with TTreeIndex doesn't have an entry for this index",
0182 "A branch was not found when switching to the next TTree in the chain",
0183 "LoadTree return less than -6, likely a 'newer' error code"};
0184
0185 TTreeReader();
0186
0187 TTreeReader(TTree *tree, TEntryList *entryList = nullptr, bool warnAboutLongerFriends = true,
0188 const std::set<std::string> &suppressErrorsForMissingBranches = {});
0189 TTreeReader(const char *keyname, TDirectory *dir, TEntryList *entryList = nullptr);
0190 TTreeReader(const char *keyname, TEntryList *entryList = nullptr) : TTreeReader(keyname, nullptr, entryList) {}
0191
0192 ~TTreeReader() override;
0193
0194 void SetTree(TTree *tree, TEntryList *entryList = nullptr);
0195 void SetTree(const char *keyname, TEntryList *entryList = nullptr) { SetTree(keyname, nullptr, entryList); }
0196 void SetTree(const char *keyname, TDirectory *dir, TEntryList *entryList = nullptr);
0197
0198 bool IsChain() const { return TestBit(kBitIsChain); }
0199
0200 bool IsInvalid() const { return fLoadTreeStatus == kNoTree; }
0201
0202 TTree *GetTree() const { return fTree; }
0203 TEntryList *GetEntryList() const { return fEntryList; }
0204
0205
0206
0207
0208
0209
0210
0211 bool Next() { return SetEntry(GetCurrentEntry() + 1) == kEntryValid; }
0212
0213
0214
0215
0216
0217
0218 EEntryStatus SetEntry(Long64_t entry) { return SetEntryBase(entry, false); }
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228 EEntryStatus SetLocalEntry(Long64_t entry) { return SetEntryBase(entry, true); }
0229
0230 EEntryStatus SetEntriesRange(Long64_t beginEntry, Long64_t endEntry);
0231
0232
0233
0234
0235 std::pair<Long64_t, Long64_t> GetEntriesRange() const { return std::make_pair(fBeginEntry, fEndEntry); }
0236
0237
0238 void Restart();
0239
0240
0241
0242 EEntryStatus GetEntryStatus() const { return fEntryStatus; }
0243
0244 Long64_t GetEntries() const;
0245 Long64_t GetEntries(bool force);
0246
0247
0248
0249
0250
0251
0252
0253
0254 Long64_t GetCurrentEntry() const { return fEntry; }
0255
0256 bool Notify() override;
0257
0258
0259 Iterator_t begin() { return Iterator_t(*this, 0); }
0260
0261 Iterator_t end() { return Iterator_t(*this, -1); }
0262
0263 void SetSuppressErrorsForMissingBranches(const std::set<std::string> &suppressErrorsForMissingBranches)
0264 {
0265 fSuppressErrorsForMissingBranches = suppressErrorsForMissingBranches;
0266 }
0267
0268 protected:
0269 using NamedProxies_t = std::unordered_map<std::string, std::unique_ptr<ROOT::Internal::TNamedBranchProxy>>;
0270 void Initialize();
0271 ROOT::Internal::TNamedBranchProxy *FindProxy(const char *branchname) const
0272 {
0273 const auto proxyIt = fProxies.find(branchname);
0274 return fProxies.end() != proxyIt ? proxyIt->second.get() : nullptr;
0275 }
0276
0277 void AddProxy(std::unique_ptr<ROOT::Internal::TNamedBranchProxy> p)
0278 {
0279 auto bpName = p->GetName();
0280 #ifndef NDEBUG
0281 if (fProxies.end() != fProxies.find(bpName)) {
0282 std::string err = "A proxy with key " + std::string(bpName) + " was already stored!";
0283 throw std::runtime_error(err);
0284 }
0285 #endif
0286
0287 fProxies[bpName] = std::move(p);
0288 }
0289
0290 ROOT::Internal::TFriendProxy &AddFriendProxy(std::size_t friendIdx);
0291
0292 bool RegisterValueReader(ROOT::Internal::TTreeReaderValueBase *reader);
0293 void DeregisterValueReader(ROOT::Internal::TTreeReaderValueBase *reader);
0294
0295 EEntryStatus SetEntryBase(Long64_t entry, bool local);
0296
0297 bool SetProxies();
0298
0299 private:
0300 std::string GetProxyKey(const char *branchname)
0301 {
0302 std::string key(branchname);
0303
0304 return key;
0305 }
0306
0307 enum EStatusBits {
0308 kBitIsChain = BIT(14),
0309 kBitHaveWarnedAboutEntryListAttachedToTTree =
0310 BIT(15),
0311 kBitSetEntryBaseCallingLoadTree = BIT(16),
0312 kBitIsExternalTree = BIT(17)
0313 };
0314
0315 TTree *fTree = nullptr;
0316 TEntryList *fEntryList = nullptr;
0317 EEntryStatus fEntryStatus = kEntryNotLoaded;
0318 ELoadTreeStatus fLoadTreeStatus = kNoTree;
0319
0320 TNotifyLink<TTreeReader> fNotify;
0321 std::unique_ptr<ROOT::Internal::TBranchProxyDirector> fDirector{nullptr};
0322
0323 std::vector<std::unique_ptr<ROOT::Internal::TFriendProxy>> fFriendProxies;
0324 std::deque<ROOT::Internal::TTreeReaderValueBase *> fValues;
0325 NamedProxies_t fProxies;
0326
0327 Long64_t fEntry = -1;
0328
0329
0330
0331
0332 Long64_t fEndEntry = -1LL;
0333 Long64_t fBeginEntry = 0LL;
0334 bool fProxiesSet = false;
0335 bool fSetEntryBaseCallingLoadTree = false;
0336
0337
0338
0339
0340
0341
0342 bool fWarnAboutLongerFriends{true};
0343 void WarnIfFriendsHaveMoreEntries();
0344
0345
0346
0347 std::set<std::string> fSuppressErrorsForMissingBranches{};
0348 std::set<std::string> fMissingProxies{};
0349
0350 friend class ROOT::Internal::TTreeReaderValueBase;
0351 friend class ROOT::Internal::TTreeReaderArrayBase;
0352
0353 ClassDefOverride(TTreeReader, 0);
0354 };
0355
0356 #endif