CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/IOPool/Input/src/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/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) { // backward compatibility
00029       TBranch* branch = tree->GetBranch(BranchTypeToProductStatusBranchName(branchType).c_str()); // backward compatibility
00030       return branch; // backward compatibility
00031     } // backward compatibility
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_(), // backward compatibility
00052     pProductStatuses_(&productStatuses_), // backward compatibility
00053     infoTree_(dynamic_cast<TTree*>(filePtr_.get() != 0 ? filePtr->Get(BranchTypeToInfoTreeName(branchType).c_str()) : 0)), // backward compatibility
00054     statusBranch_(infoTree_ ? getStatusBranch(infoTree_, branchType_) : 0) { // backward compatibility
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) { // backward compatibility
00067       if (branchEntryInfoBranch_ != 0 || statusBranch_ != 0) return true; // backward compatibility
00068       return (entries_ == metaTree_->GetEntries() && tree_->GetNbranches() <= metaTree_->GetNbranches() + 1);  // backward compatibility
00069     } // backward compatibility
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       //use the translated branch name
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         //we want the new branch name for the JobReport
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       //use the translated branch name
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     // The InputFile is about to be closed, and destructed.
00170     // Just to play it safe, zero all pointers to quantities that are owned by the InputFile.
00171     auxBranch_  = branchEntryInfoBranch_ = statusBranch_ = 0;
00172     tree_ = metaTree_ = infoTree_ = 0;
00173     // We own the treeCache_.
00174     // We make sure the treeCache_ is detatched from the file,
00175     // so that ROOT does not also delete it.
00176     filePtr_->SetCacheRead(0);
00177     trained_ = kFALSE;
00178     // We give up our shared ownership of the InputFile itself.
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 }