CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
RootTree.cc
Go to the documentation of this file.
1 #include "RootTree.h"
2 #include "RootDelayedReader.h"
6 #include "InputFile.h"
7 #include "TTree.h"
8 #include "TTreeIndex.h"
9 #include "TTreeCache.h"
10 
11 #include <iostream>
12 
13 namespace edm {
14  namespace {
15  TBranch* getAuxiliaryBranch(TTree* tree, BranchType const& branchType) {
16  TBranch* branch = tree->GetBranch(BranchTypeToAuxiliaryBranchName(branchType).c_str());
17  if (branch == 0) {
18  branch = tree->GetBranch(BranchTypeToAuxBranchName(branchType).c_str());
19  }
20  return branch;
21  }
22  TBranch* getProductProvenanceBranch(TTree* tree, BranchType const& branchType) {
23  TBranch* branch = tree->GetBranch(BranchTypeToBranchEntryInfoBranchName(branchType).c_str());
24  return branch;
25  }
26  }
27  RootTree::RootTree(boost::shared_ptr<InputFile> filePtr,
28  BranchType const& branchType,
29  unsigned int maxVirtualSize,
30  unsigned int cacheSize,
31  unsigned int learningEntries) :
32  filePtr_(filePtr),
33  tree_(dynamic_cast<TTree*>(filePtr_.get() != 0 ? filePtr_->Get(BranchTypeToProductTreeName(branchType).c_str()) : 0)),
34  metaTree_(dynamic_cast<TTree*>(filePtr_.get() != 0 ? filePtr_->Get(BranchTypeToMetaDataTreeName(branchType).c_str()) : 0)),
35  branchType_(branchType),
36  auxBranch_(tree_ ? getAuxiliaryBranch(tree_, branchType_) : 0),
37  treeCache_(),
38  rawTreeCache_(),
39  entries_(tree_ ? tree_->GetEntries() : 0),
40  entryNumber_(-1),
41  branchNames_(),
42  branches_(new BranchMap),
43  trainNow_(false),
44  switchOverEntry_(-1),
45  learningEntries_(learningEntries),
46  cacheSize_(cacheSize),
47  treeAutoFlush_(tree_ ? tree_->GetAutoFlush() : 0),
48  rootDelayedReader_(new RootDelayedReader(*this, filePtr)),
49  branchEntryInfoBranch_(metaTree_ ? getProductProvenanceBranch(metaTree_, branchType_) : (tree_ ? getProductProvenanceBranch(tree_, branchType_) : 0)),
50  infoTree_(dynamic_cast<TTree*>(filePtr_.get() != 0 ? filePtr->Get(BranchTypeToInfoTreeName(branchType).c_str()) : 0)) // backward compatibility
51  {
52  assert(tree_);
53  // On merged files in older releases of ROOT, the autoFlush setting is always negative; we must guess.
54  // TODO: On newer merged files, we should be able to get this from the cluster iterator.
55  if (treeAutoFlush_ < 0) {
56  // The "+1" is here to avoid divide-by-zero in degenerate cases.
57  Long64_t averageEventSizeBytes = tree_->GetZipBytes() / (tree_->GetEntries()+1) + 1;
58  treeAutoFlush_ = cacheSize_/averageEventSizeBytes+1;
59  }
60  setTreeMaxVirtualSize(maxVirtualSize);
61  setCacheSize(cacheSize);
62  }
63 
65  }
66 
67  bool
69  if (metaTree_ == 0 || metaTree_->GetNbranches() == 0) {
70  return tree_ != 0 && auxBranch_ != 0;
71  }
72  if (tree_ != 0 && auxBranch_ != 0 && metaTree_ != 0) { // backward compatibility
73  if (branchEntryInfoBranch_ != 0 || infoTree_ != 0) return true; // backward compatibility
74  return (entries_ == metaTree_->GetEntries() && tree_->GetNbranches() <= metaTree_->GetNbranches() + 1); // backward compatibility
75  } // backward compatibility
76  return false;
77  }
78 
81  rootDelayedReader_->reset();
82  return rootDelayedReader_.get();
83  }
84 
85  void
86  RootTree::setPresence(BranchDescription const& prod, std::string const& oldBranchName) {
87  assert(isValid());
88  prod.init();
89  if(tree_->GetBranch(oldBranchName.c_str()) == 0){
90  prod.setDropped();
91  }
92  }
93 
94  void
96  BranchDescription const& prod,
97  std::string const& oldBranchName) {
98  assert(isValid());
99  prod.init();
100  //use the translated branch name
101  TBranch* branch = tree_->GetBranch(oldBranchName.c_str());
103  info.productBranch_ = 0;
104  if (prod.present()) {
105  info.productBranch_ = branch;
106  //we want the new branch name for the JobReport
107  branchNames_.push_back(prod.branchName());
108  }
109  TTree* provTree = (metaTree_ != 0 ? metaTree_ : tree_);
110  info.provenanceBranch_ = provTree->GetBranch(oldBranchName.c_str());
111  branches_->insert(std::make_pair(key, info));
112  }
113 
114  void
115  RootTree::dropBranch(std::string const& oldBranchName) {
116  //use the translated branch name
117  TBranch* branch = tree_->GetBranch(oldBranchName.c_str());
118  if (branch != 0) {
119  TObjArray* leaves = tree_->GetListOfLeaves();
120  int entries = leaves->GetEntries();
121  for (int i = 0; i < entries; ++i) {
122  TLeaf* leaf = (TLeaf*)(*leaves)[i];
123  if (leaf == 0) continue;
124  TBranch* br = leaf->GetBranch();
125  if (br == 0) continue;
126  if (br->GetMother() == branch) {
127  leaves->Remove(leaf);
128  }
129  }
130  leaves->Compress();
131  tree_->GetListOfBranches()->Remove(branch);
132  tree_->GetListOfBranches()->Compress();
133  delete branch;
134  }
135  }
136 
137  roottree::BranchMap const&
138  RootTree::branches() const {return *branches_;}
139 
140  void
141  RootTree::setCacheSize(unsigned int cacheSize) {
142  cacheSize_ = cacheSize;
143  tree_->SetCacheSize(static_cast<Long64_t>(cacheSize));
144  treeCache_.reset(dynamic_cast<TTreeCache*>(filePtr_->GetCacheRead()));
145  filePtr_->SetCacheRead(0);
146  rawTreeCache_.reset();
147  }
148 
149  void
150  RootTree::setTreeMaxVirtualSize(int treeMaxVirtualSize) {
151  if (treeMaxVirtualSize >= 0) tree_->SetMaxVirtualSize(static_cast<Long64_t>(treeMaxVirtualSize));
152  }
153 
154  void
156  filePtr_->SetCacheRead(treeCache_.get());
157 
158  // Detect a backward skip. If the skip is sufficiently large, we roll the dice and reset the treeCache.
159  // This will cause some amount of over-reading: we pre-fetch all the events in some prior cluster.
160  // However, because reading one event in the cluster is supposed to be equivalent to reading all events in the cluster,
161  // we're not incurring additional over-reading - we're just doing it more efficiently.
162  // NOTE: Constructor guarantees treeAutoFlush_ is positive, even if TTree->GetAutoFlush() is negative.
163  if ((theEntryNumber < static_cast<EntryNumber>(entryNumber_-treeAutoFlush_)) &&
164  (treeCache_) && (!treeCache_->IsLearning()) && (entries_ > 0) && (switchOverEntry_ >= 0)) {
165  treeCache_->SetEntryRange(theEntryNumber, entries_);
166  treeCache_->FillBuffer();
167  }
168 
169  entryNumber_ = theEntryNumber;
170  tree_->LoadTree(entryNumber_);
171  filePtr_->SetCacheRead(0);
172  if(treeCache_ && trainNow_ && entryNumber_ >= 0) {
173  startTraining();
174  trainNow_ = false;
175  }
176  if (treeCache_ && treeCache_->IsLearning() && switchOverEntry_ >= 0 && entryNumber_ >= switchOverEntry_) {
177  stopTraining();
178  }
179  }
180 
181  void
182  RootTree::getEntry(TBranch* branch, EntryNumber entryNumber) const {
183  try {
184  if (!treeCache_) {
185  filePtr_->SetCacheRead(0);
186  branch->GetEntry(entryNumber);
187  } else if (treeCache_->IsLearning() && rawTreeCache_) {
188  treeCache_->AddBranch(branch, kTRUE);
189  filePtr_->SetCacheRead(rawTreeCache_.get());
190  branch->GetEntry(entryNumber);
191  filePtr_->SetCacheRead(0);
192  } else {
193  filePtr_->SetCacheRead(treeCache_.get());
194  branch->GetEntry(entryNumber);
195  filePtr_->SetCacheRead(0);
196  }
197  } catch(cms::Exception const& e) {
198  // We make sure the treeCache_ is detached from the file,
199  // so that ROOT does not also delete it.
200  filePtr_->SetCacheRead(0);
202  t.addContext(std::string("Reading branch ")+branch->GetName());
203  throw t;
204  }
205  }
206 
207  void
209  if (cacheSize_ == 0) {
210  return;
211  }
212  assert(treeCache_ && treeCache_->GetOwner() == tree_);
213  assert(branchType_ == InEvent);
214  assert(!rawTreeCache_);
215  treeCache_->SetLearnEntries(learningEntries_);
216  tree_->SetCacheSize(static_cast<Long64_t>(cacheSize_));
217  rawTreeCache_.reset(dynamic_cast<TTreeCache *>(filePtr_->GetCacheRead()));
218  filePtr_->SetCacheRead(0);
219  rawTreeCache_->SetLearnEntries(0);
221  rawTreeCache_->StartLearningPhase();
223  rawTreeCache_->AddBranch("*", kTRUE);
224  rawTreeCache_->StopLearningPhase();
225  treeCache_->StartLearningPhase();
226  treeCache_->SetEntryRange(switchOverEntry_, tree_->GetEntries());
227  treeCache_->AddBranch(poolNames::branchListIndexesBranchName().c_str(), kTRUE);
228  treeCache_->AddBranch(BranchTypeToAuxiliaryBranchName(branchType_).c_str(), kTRUE);
229  }
230 
231  void
233  filePtr_->SetCacheRead(treeCache_.get());
234  treeCache_->StopLearningPhase();
235  rawTreeCache_.reset();
236  }
237 
238  void
240  // The TFile is about to be closed, and destructed.
241  // Just to play it safe, zero all pointers to quantities that are owned by the TFile.
243  tree_ = metaTree_ = infoTree_ = 0;
244  // We own the treeCache_.
245  // We make sure the treeCache_ is detached from the file,
246  // so that ROOT does not also delete it.
247  filePtr_->SetCacheRead(0);
248  // We give up our shared ownership of the TFile itself.
249  filePtr_.reset();
250  }
251 
252  void
253  RootTree::trainCache(char const* branchNames) {
254  if (cacheSize_ == 0) {
255  return;
256  }
257  tree_->LoadTree(0);
258  assert(treeCache_);
259  filePtr_->SetCacheRead(treeCache_.get());
260  assert(treeCache_->GetOwner() == tree_);
261  treeCache_->StartLearningPhase();
262  treeCache_->SetEntryRange(0, tree_->GetEntries());
263  treeCache_->AddBranch(branchNames, kTRUE);
264  treeCache_->StopLearningPhase();
265  // We own the treeCache_.
266  // We make sure the treeCache_ is detached from the file,
267  // so that ROOT does not also delete it.
268  filePtr_->SetCacheRead(0);
269  }
270 
271  namespace roottree {
272  Int_t
273  getEntry(TBranch* branch, EntryNumber entryNumber) {
274  Int_t n = 0;
275  try {
276  n = branch->GetEntry(entryNumber);
277  }
278  catch(cms::Exception const& e) {
279  throw Exception(errors::FileReadError, "", e);
280  }
281  return n;
282  }
283 
284  Int_t
285  getEntry(TTree* tree, EntryNumber entryNumber) {
286  Int_t n = 0;
287  try {
288  n = tree->GetEntry(entryNumber);
289  }
290  catch(cms::Exception const& e) {
291  throw Exception (errors::FileReadError, "", e);
292  }
293  return n;
294  }
295 
296  std::unique_ptr<TTreeCache>
297  trainCache(TTree* tree, InputFile& file, unsigned int cacheSize, char const* branchNames) {
298  tree->LoadTree(0);
299  tree->SetCacheSize(cacheSize);
300  std::unique_ptr<TTreeCache> treeCache(dynamic_cast<TTreeCache*>(file.GetCacheRead()));
301  if (0 != treeCache.get()) {
302  treeCache->StartLearningPhase();
303  treeCache->SetEntryRange(0, tree->GetEntries());
304  treeCache->AddBranch(branchNames, kTRUE);
305  treeCache->StopLearningPhase();
306  }
307  // We own the treeCache_.
308  // We make sure the treeCache_ is detached from the file,
309  // so that ROOT does not also delete it.
310  file.SetCacheRead(0);
311  return treeCache;
312  }
313  }
314 }
EntryNumber entryNumber_
Definition: RootTree.h:143
Int_t getEntry(TBranch *branch, EntryNumber entryNumber)
Definition: RootTree.cc:273
boost::shared_ptr< TTreeCache > treeCache_
Definition: RootTree.h:140
int i
Definition: DBlmapReader.cc:9
std::string const & BranchTypeToMetaDataTreeName(BranchType const &branchType)
Definition: BranchType.cc:106
std::string const & BranchTypeToAuxiliaryBranchName(BranchType const &branchType)
Definition: BranchType.cc:114
unsigned int learningEntries_
Definition: RootTree.h:148
void addBranch(BranchKey const &key, BranchDescription const &prod, std::string const &oldBranchName)
Definition: RootTree.cc:95
void dropBranch(std::string const &oldBranchName)
Definition: RootTree.cc:115
std::vector< std::string > branchNames_
Definition: RootTree.h:144
void setPresence(BranchDescription const &prod, std::string const &oldBranchName)
Definition: RootTree.cc:86
std::string & branchName() const
TTree * tree_
Definition: RootTree.h:133
bool trainNow_
Definition: RootTree.h:146
TFileCacheRead * GetCacheRead() const
Definition: InputFile.h:45
roottree::BranchMap BranchMap
Definition: RootTree.h:58
EntryNumber const & entries() const
Definition: RootTree.h:85
TTree * metaTree_
Definition: RootTree.h:134
void stopTraining()
Definition: RootTree.cc:232
TBranch * branchEntryInfoBranch_
Definition: RootTree.h:153
EntryNumber entries_
Definition: RootTree.h:142
boost::shared_ptr< TTreeCache > rawTreeCache_
Definition: RootTree.h:141
void trainCache(char const *branchNames)
Definition: RootTree.cc:253
void setTreeMaxVirtualSize(int treeMaxVirtualSize)
Definition: RootTree.cc:150
std::map< BranchKey const, BranchInfo > BranchMap
Definition: RootTree.h:50
BranchType
Definition: BranchType.h:11
RootTree(boost::shared_ptr< InputFile > filePtr, BranchType const &branchType, unsigned int maxVirtualSize, unsigned int cacheSize, unsigned int learningEntries)
Definition: RootTree.cc:27
tuple br
Definition: scaleCards.py:54
tuple leaf
Definition: Node.py:62
std::string const & BranchTypeToBranchEntryInfoBranchName(BranchType const &branchType)
Definition: BranchType.cc:126
std::string const & BranchTypeToProductTreeName(BranchType const &branchType)
Definition: BranchType.cc:102
TBranch * auxBranch_
Definition: RootTree.h:136
long int treeAutoFlush_
Definition: RootTree.h:150
std::string const & BranchTypeToInfoTreeName(BranchType const &branchType)
Definition: BranchType.cc:110
TBranch * provenanceBranch_
Definition: RootTree.h:47
DelayedReader * rootDelayedReader() const
Definition: RootTree.cc:80
void close()
Definition: RootTree.cc:239
void getEntry(TBranch *branch, EntryNumber entry) const
Definition: RootTree.cc:182
void startTraining()
Definition: RootTree.cc:208
boost::shared_ptr< BranchMap > branches_
Definition: RootTree.h:145
void addContext(std::string const &context)
Definition: Exception.cc:227
bool isValid() const
Definition: RootTree.cc:68
TBranch * productBranch_
Definition: RootTree.h:46
void setCacheSize(unsigned int cacheSize)
Definition: RootTree.cc:141
list key
Definition: combine.py:13
unsigned int cacheSize_
Definition: RootTree.h:149
Long64_t EntryNumber
Definition: RootTree.h:38
std::string const & BranchTypeToAuxBranchName(BranchType const &branchType)
Definition: BranchType.cc:118
BranchMap const & branches() const
Definition: RootTree.cc:138
std::unique_ptr< DelayedReader > rootDelayedReader_
Definition: RootTree.h:151
boost::shared_ptr< InputFile > filePtr_
Definition: RootTree.h:129
std::string const & branchListIndexesBranchName()
Definition: BranchType.cc:241
std::unique_ptr< TTreeCache > trainCache(TTree *tree, InputFile &file, unsigned int cacheSize, char const *branchNames)
Definition: RootTree.cc:297
void SetCacheRead(TFileCacheRead *tfcr)
Definition: InputFile.h:46
EntryNumber switchOverEntry_
Definition: RootTree.h:147
T get(const Candidate &c)
Definition: component.h:56
BranchType branchType_
Definition: RootTree.h:135
TTree * infoTree_
Definition: RootTree.h:155
void setEntryNumber(EntryNumber theEntryNumber)
Definition: RootTree.cc:155
roottree::EntryNumber EntryNumber
Definition: RootTree.h:59