00001 #include "RootTree.h"
00002 #include "RootDelayedReader.h"
00003 #include "FWCore/Framework/interface/Principal.h"
00004 #include "FWCore/Utilities/interface/EDMException.h"
00005 #include "FWCore/Utilities/interface/Exception.h"
00006 #include "DataFormats/Provenance/interface/BranchDescription.h"
00007 #include "DataFormats/Provenance/interface/ConstBranchDescription.h"
00008 #include "InputFile.h"
00009 #include "TTree.h"
00010 #include "TTreeIndex.h"
00011 #include "TTreeCache.h"
00012
00013 #include <iostream>
00014
00015 namespace edm {
00016 namespace {
00017 TBranch* getAuxiliaryBranch(TTree* tree, BranchType const& branchType) {
00018 TBranch* branch = tree->GetBranch(BranchTypeToAuxiliaryBranchName(branchType).c_str());
00019 if (branch == 0) {
00020 branch = tree->GetBranch(BranchTypeToAuxBranchName(branchType).c_str());
00021 }
00022 return branch;
00023 }
00024 TBranch* getProductProvenanceBranch(TTree* tree, BranchType const& branchType) {
00025 TBranch* branch = tree->GetBranch(BranchTypeToBranchEntryInfoBranchName(branchType).c_str());
00026 return branch;
00027 }
00028 TBranch* getStatusBranch(TTree* tree, BranchType const& branchType) {
00029 TBranch* branch = tree->GetBranch(BranchTypeToProductStatusBranchName(branchType).c_str());
00030 return branch;
00031 }
00032 }
00033 RootTree::RootTree(boost::shared_ptr<InputFile> filePtr,
00034 BranchType const& branchType,
00035 unsigned int maxVirtualSize,
00036 unsigned int cacheSize,
00037 unsigned int learningEntries) :
00038 filePtr_(filePtr),
00039 tree_(dynamic_cast<TTree*>(filePtr_.get() != 0 ? filePtr->Get(BranchTypeToProductTreeName(branchType).c_str()) : 0)),
00040 metaTree_(dynamic_cast<TTree*>(filePtr_.get() != 0 ? filePtr->Get(BranchTypeToMetaDataTreeName(branchType).c_str()) : 0)),
00041 branchType_(branchType),
00042 auxBranch_(tree_ ? getAuxiliaryBranch(tree_, branchType_) : 0),
00043 branchEntryInfoBranch_(metaTree_ ? getProductProvenanceBranch(metaTree_, branchType_) : getProductProvenanceBranch(tree_, branchType_)),
00044 treeCache_(),
00045 entries_(tree_ ? tree_->GetEntries() : 0),
00046 entryNumber_(-1),
00047 branchNames_(),
00048 branches_(new BranchMap),
00049 trained_(kFALSE),
00050 learningEntries_(learningEntries),
00051 productStatuses_(),
00052 pProductStatuses_(&productStatuses_),
00053 infoTree_(dynamic_cast<TTree*>(filePtr_.get() != 0 ? filePtr->Get(BranchTypeToInfoTreeName(branchType).c_str()) : 0)),
00054 statusBranch_(infoTree_ ? getStatusBranch(infoTree_, branchType_) : 0) {
00055 setTreeMaxVirtualSize(maxVirtualSize);
00056 setCacheSize(cacheSize);
00057 }
00058
00059 RootTree::~RootTree() {}
00060
00061 bool
00062 RootTree::isValid() const {
00063 if (metaTree_ == 0 || metaTree_->GetNbranches() == 0) {
00064 return tree_ != 0 && auxBranch_ != 0;
00065 }
00066 if (tree_ != 0 && auxBranch_ != 0 && metaTree_ != 0) {
00067 if (branchEntryInfoBranch_ != 0 || statusBranch_ != 0) return true;
00068 return (entries_ == metaTree_->GetEntries() && tree_->GetNbranches() <= metaTree_->GetNbranches() + 1);
00069 }
00070 return false;
00071 }
00072
00073 void
00074 RootTree::setPresence(BranchDescription const& prod) {
00075 assert(isValid());
00076 prod.init();
00077 if(tree_->GetBranch(prod.branchName().c_str()) == 0){
00078 prod.setDropped();
00079 }
00080 }
00081
00082 void
00083 RootTree::addBranch(BranchKey const& key,
00084 BranchDescription const& prod,
00085 std::string const& oldBranchName) {
00086 assert(isValid());
00087 prod.init();
00088
00089 TBranch* branch = tree_->GetBranch(oldBranchName.c_str());
00090 input::BranchInfo info = input::BranchInfo(ConstBranchDescription(prod));
00091 info.productBranch_ = 0;
00092 if (prod.present()) {
00093 info.productBranch_ = branch;
00094
00095 branchNames_.push_back(prod.branchName());
00096 }
00097 TTree* provTree = (metaTree_ != 0 ? metaTree_ : tree_);
00098 info.provenanceBranch_ = provTree->GetBranch(oldBranchName.c_str());
00099 branches_->insert(std::make_pair(key, info));
00100 }
00101
00102 void
00103 RootTree::dropBranch(std::string const& oldBranchName) {
00104
00105 TBranch* branch = tree_->GetBranch(oldBranchName.c_str());
00106 if (branch != 0) {
00107 TObjArray* leaves = tree_->GetListOfLeaves();
00108 int entries = leaves->GetEntries();
00109 for (int i = 0; i < entries; ++i) {
00110 TLeaf* leaf = (TLeaf*)(*leaves)[i];
00111 if (leaf == 0) continue;
00112 TBranch* br = leaf->GetBranch();
00113 if (br == 0) continue;
00114 if (br->GetMother() == branch) {
00115 leaves->Remove(leaf);
00116 }
00117 }
00118 leaves->Compress();
00119 tree_->GetListOfBranches()->Remove(branch);
00120 tree_->GetListOfBranches()->Compress();
00121 delete branch;
00122 }
00123 }
00124
00125 input::BranchMap const&
00126 RootTree::branches() const {return *branches_;}
00127
00128 boost::shared_ptr<DelayedReader>
00129 RootTree::makeDelayedReader(FileFormatVersion const& fileFormatVersion) const {
00130 boost::shared_ptr<DelayedReader>
00131 store(new RootDelayedReader(entryNumber_, branches_, treeCache_, filePtr_, fileFormatVersion));
00132 return store;
00133 }
00134
00135 void
00136 RootTree::setCacheSize(unsigned int cacheSize) {
00137 tree_->SetCacheSize(static_cast<Long64_t>(cacheSize));
00138 treeCache_.reset(dynamic_cast<TTreeCache*>(filePtr_->GetCacheRead()));
00139 filePtr_->SetCacheRead(0);
00140 }
00141
00142 void
00143 RootTree::setTreeMaxVirtualSize(int treeMaxVirtualSize) {
00144 if (treeMaxVirtualSize >= 0) tree_->SetMaxVirtualSize(static_cast<Long64_t>(treeMaxVirtualSize));
00145 }
00146
00147 void
00148 RootTree::setEntryNumber(EntryNumber theEntryNumber) {
00149 filePtr_->SetCacheRead(treeCache_.get());
00150 entryNumber_ = theEntryNumber;
00151 tree_->LoadTree(theEntryNumber);
00152 if (treeCache_ && !trained_ && theEntryNumber >= 0) {
00153 assert(treeCache_->GetOwner() == tree_);
00154 treeCache_->SetLearnEntries(learningEntries_);
00155 treeCache_->SetEntryRange(theEntryNumber, tree_->GetEntries());
00156 treeCache_->StartLearningPhase();
00157 treeCache_->AddBranch(BranchTypeToAuxiliaryBranchName(branchType_).c_str());
00158 if (branchType_ == edm::InEvent) {
00159 treeCache_->AddBranch(poolNames::branchListIndexesBranchName().c_str());
00160 }
00161 trained_ = kTRUE;
00162 }
00163 filePtr_->SetCacheRead(0);
00164 }
00165
00166
00167 void
00168 RootTree::close () {
00169
00170
00171 auxBranch_ = branchEntryInfoBranch_ = statusBranch_ = 0;
00172 tree_ = metaTree_ = infoTree_ = 0;
00173
00174
00175
00176 filePtr_->SetCacheRead(0);
00177 trained_ = kFALSE;
00178
00179 filePtr_.reset();
00180 }
00181
00182 namespace input {
00183 Int_t
00184 getEntry(TBranch* branch, EntryNumber entryNumber) {
00185 Int_t n = 0;
00186 try {
00187 n = branch->GetEntry(entryNumber);
00188 }
00189 catch(cms::Exception const& e) {
00190 throw edm::Exception(edm::errors::FileReadError) << e.explainSelf() << "\n";
00191 }
00192 return n;
00193 }
00194
00195 Int_t
00196 getEntry(TTree* tree, EntryNumber entryNumber) {
00197 Int_t n = 0;
00198 try {
00199 n = tree->GetEntry(entryNumber);
00200 }
00201 catch(cms::Exception const& e) {
00202 throw edm::Exception(edm::errors::FileReadError) << e.explainSelf() << "\n";
00203 }
00204 return n;
00205 }
00206
00207 Int_t
00208 getEntryWithCache(TBranch* branch, EntryNumber entryNumber, TTreeCache* tc, InputFile* filePtr) {
00209 if (tc == 0) {
00210 return getEntry(branch, entryNumber);
00211 }
00212 filePtr->SetCacheRead(tc);
00213 Int_t n = getEntry(branch, entryNumber);
00214 filePtr->SetCacheRead(0);
00215 return n;
00216 }
00217
00218 Int_t
00219 getEntryWithCache(TTree* tree, EntryNumber entryNumber, TTreeCache* tc, InputFile* filePtr) {
00220 if (tc == 0) {
00221 return getEntry(tree, entryNumber);
00222 }
00223 filePtr->SetCacheRead(tc);
00224 Int_t n = getEntry(tree, entryNumber);
00225 filePtr->SetCacheRead(0);
00226 return n;
00227 }
00228 }
00229 }