CMS 3D CMS Logo

RootTree.cc

Go to the documentation of this file.
00001 #include "RootTree.h"
00002 #include "RootDelayedReader.h"
00003 #include "FWCore/Framework/interface/Principal.h"
00004 #include "FWCore/Utilities/interface/WrappedClassName.h"
00005 #include "DataFormats/Provenance/interface/BranchDescription.h"
00006 #include "DataFormats/Provenance/interface/ConstBranchDescription.h"
00007 #include "DataFormats/Provenance/interface/Provenance.h"
00008 #include "Rtypes.h"
00009 #include "TFile.h"
00010 #include "TVirtualIndex.h"
00011 #include "TTreeIndex.h"
00012 #include "TTreeCache.h"
00013 
00014 #include <iostream>
00015 
00016 namespace edm {
00017   namespace {
00018     TBranch * getAuxiliaryBranch(TTree * tree, BranchType const& branchType) {
00019       TBranch *branch = tree->GetBranch(BranchTypeToAuxiliaryBranchName(branchType).c_str());
00020       if (branch == 0) {
00021         branch = tree->GetBranch(BranchTypeToAuxBranchName(branchType).c_str());
00022       }
00023       return branch;
00024     }
00025     TBranch * getEventEntryInfoBranch(TTree * tree, BranchType const& branchType) {
00026       TBranch *branch = tree->GetBranch(BranchTypeToBranchEntryInfoBranchName(branchType).c_str());
00027       return branch;
00028     }
00029     TBranch * getStatusBranch(TTree * tree, BranchType const& branchType) {
00030       TBranch *branch = tree->GetBranch(BranchTypeToProductStatusBranchName(branchType).c_str());
00031       return branch;
00032     }
00033   }
00034   RootTree::RootTree(boost::shared_ptr<TFile> filePtr, BranchType const& branchType) :
00035     filePtr_(filePtr),
00036     tree_(dynamic_cast<TTree *>(filePtr_.get() != 0 ? filePtr->Get(BranchTypeToProductTreeName(branchType).c_str()) : 0)),
00037     metaTree_(dynamic_cast<TTree *>(filePtr_.get() != 0 ? filePtr->Get(BranchTypeToMetaDataTreeName(branchType).c_str()) : 0)),
00038     branchType_(branchType),
00039     auxBranch_(tree_ ? getAuxiliaryBranch(tree_, branchType_) : 0),
00040     branchEntryInfoBranch_(metaTree_ ? getEventEntryInfoBranch(metaTree_, branchType_) : 0),
00041     entries_(tree_ ? tree_->GetEntries() : 0),
00042     entryNumber_(-1),
00043     branchNames_(),
00044     branches_(new BranchMap),
00045     productStatuses_(),
00046     pProductStatuses_(&productStatuses_),
00047     infoTree_(dynamic_cast<TTree *>(filePtr_.get() != 0 ? filePtr->Get(BranchTypeToInfoTreeName(branchType).c_str()) : 0)),
00048     statusBranch_(infoTree_ ? getStatusBranch(infoTree_, branchType_) : 0)
00049   { }
00050 
00051   bool
00052   RootTree::isValid() const {
00053     if (metaTree_ == 0 || metaTree_->GetNbranches() == 0) {
00054       return tree_ != 0 && auxBranch_ != 0 && tree_->GetNbranches() == 1; 
00055     }
00056     if (tree_ != 0 && auxBranch_ != 0 && metaTree_ != 0) {
00057       if (branchEntryInfoBranch_ != 0 || statusBranch_ != 0) return true;
00058       return (entries_ == metaTree_->GetEntries() && tree_->GetNbranches() <= metaTree_->GetNbranches() + 1); 
00059     }
00060     return false;
00061   }
00062 
00063   void
00064   RootTree::setPresence(BranchDescription const& prod) {
00065       assert(isValid());
00066       prod.init();
00067       prod.setPresent(tree_->GetBranch(prod.branchName().c_str()) != 0);
00068   }
00069 
00070   void
00071   RootTree::addBranch(BranchKey const& key,
00072                       BranchDescription const& prod,
00073                       std::string const& oldBranchName) {
00074       assert(isValid());
00075       prod.init();
00076       //use the translated branch name 
00077       TBranch * branch = tree_->GetBranch(oldBranchName.c_str());
00078       assert (prod.present() == (branch != 0));
00079       input::BranchInfo info = input::BranchInfo(ConstBranchDescription(prod));
00080       info.productBranch_ = 0;
00081       if (prod.present()) {
00082         info.productBranch_ = branch;
00083         //we want the new branch name for the JobReport
00084         branchNames_.push_back(prod.branchName());
00085       }
00086       info.provenanceBranch_ = metaTree_->GetBranch(oldBranchName.c_str());
00087       branches_->insert(std::make_pair(key, info));
00088   }
00089 
00090   void
00091   RootTree::dropBranch(std::string const& oldBranchName) {
00092       //use the translated branch name 
00093       TBranch * branch = tree_->GetBranch(oldBranchName.c_str());
00094       if (branch != 0) {
00095         TObjArray * leaves = tree_->GetListOfLeaves();
00096         int entries = leaves->GetEntries();
00097         for (int i = 0; i < entries; ++i) {
00098           TLeaf *leaf = (TLeaf *)(*leaves)[i];
00099           if (leaf == 0) continue;
00100           TBranch* br = leaf->GetBranch();
00101           if (br == 0) continue;
00102           if (br->GetMother() == branch) {
00103             leaves->Remove(leaf);
00104           }
00105         }
00106         leaves->Compress();
00107         tree_->GetListOfBranches()->Remove(branch);
00108         tree_->GetListOfBranches()->Compress();
00109         delete branch;
00110       }
00111   }
00112 
00113   boost::shared_ptr<DelayedReader>
00114   RootTree::makeDelayedReader() const {
00115     boost::shared_ptr<DelayedReader> store(new RootDelayedReader(entryNumber_, branches_, filePtr_));
00116     return store;
00117   }
00118 
00119   void
00120   RootTree::setCacheSize(unsigned int cacheSize) const {
00121     tree_->SetCacheSize(static_cast<Long64_t>(cacheSize));
00122   }
00123 
00124   void
00125   RootTree::setTreeMaxVirtualSize(int treeMaxVirtualSize) {
00126     if (treeMaxVirtualSize >= 0) tree_->SetMaxVirtualSize(static_cast<Long64_t>(treeMaxVirtualSize));
00127   }
00128 
00129   void
00130   RootTree::setEntryNumber(EntryNumber theEntryNumber) {
00131     if (TTreeCache *tc = dynamic_cast<TTreeCache *>(filePtr_->GetCacheRead())) {
00132       if (theEntryNumber >= 0 && tc->GetOwner() == tree_ && tc->IsLearning()) {
00133         tc->SetLearnEntries(1);
00134         tc->SetEntryRange(0, tree_->GetEntries());
00135         for (BranchMap::const_iterator i = branches_->begin(), e = branches_->end(); i != e; ++i) {
00136           if (i->second.productBranch_) {
00137             tc->AddBranch(i->second.productBranch_, kTRUE);
00138           }
00139         }
00140         tc->StopLearningPhase();
00141       }
00142     }
00143 
00144     entryNumber_ = theEntryNumber;
00145     tree_->LoadTree(theEntryNumber);
00146   }
00147 
00148   namespace input {
00149     Int_t
00150     getEntry(TBranch* branch, EntryNumber entryNumber) {
00151       Int_t n = 0;
00152       try {
00153         n = branch->GetEntry(entryNumber);
00154       }
00155       catch(cms::Exception e) {
00156         throw edm::Exception(edm::errors::FileReadError) << e.explainSelf() << "\n";
00157       }
00158       return n;
00159     }
00160 
00161     Int_t
00162     getEntry(TTree* tree, EntryNumber entryNumber) {
00163       Int_t n = 0;
00164       try {
00165         n = tree->GetEntry(entryNumber);
00166       }
00167       catch(cms::Exception e) {
00168         throw edm::Exception(edm::errors::FileReadError) << e.explainSelf() << "\n";
00169       }
00170       return n;
00171     }
00172   }
00173 }

Generated on Tue Jun 9 17:39:14 2009 for CMSSW by  doxygen 1.5.4