CMS 3D CMS Logo

PoolOutputModule.cc

Go to the documentation of this file.
00001 #include "IOPool/Output/src/PoolOutputModule.h"
00002 
00003 #include "FWCore/MessageLogger/interface/JobReport.h" 
00004 #include "IOPool/Output/src/RootOutputFile.h" 
00005 
00006 #include "FWCore/Framework/interface/EventPrincipal.h"
00007 #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h"
00008 #include "FWCore/Framework/interface/RunPrincipal.h"
00009 #include "FWCore/Framework/interface/FileBlock.h"
00010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00011 #include "FWCore/ServiceRegistry/interface/Service.h"
00012 #include "DataFormats/Provenance/interface/FileFormatVersion.h"
00013 #include "FWCore/Utilities/interface/EDMException.h"
00014 
00015 #include "TTree.h"
00016 #include "TBranchElement.h"
00017 #include "TObjArray.h"
00018 
00019 #include <iomanip>
00020 #include <sstream>
00021 
00022 namespace edm {
00023   PoolOutputModule::PoolOutputModule(ParameterSet const& pset) :
00024     OutputModule(pset),
00025     rootServiceChecker_(),
00026     selectedOutputItemList_(), 
00027     fileName_(pset.getUntrackedParameter<std::string>("fileName")),
00028     logicalFileName_(pset.getUntrackedParameter<std::string>("logicalFileName", std::string())),
00029     catalog_(pset.getUntrackedParameter<std::string>("catalog", std::string())),
00030     maxFileSize_(pset.getUntrackedParameter<int>("maxSize", 0x7f000000)),
00031     compressionLevel_(pset.getUntrackedParameter<int>("compressionLevel", 7)),
00032     basketSize_(pset.getUntrackedParameter<int>("basketSize", 16384)),
00033     splitLevel_(pset.getUntrackedParameter<int>("splitLevel", 99)),
00034     treeMaxVirtualSize_(pset.getUntrackedParameter<int>("treeMaxVirtualSize", -1)),
00035     fastCloning_(pset.getUntrackedParameter<bool>("fastCloning", true) && wantAllEvents()),
00036     dropMetaDataForDroppedData_(pset.getUntrackedParameter<bool>("dropMetaDataForDroppedData", false)),
00037     moduleLabel_(pset.getParameter<std::string>("@module_label")),
00038     outputFileCount_(0),
00039     inputFileCount_(0),
00040     rootOutputFile_() {
00041     // We don't use this next parameter, but we read it anyway because it is part
00042     // of the configuration of this module.  An external parser creates the
00043     // configuration by reading this source code.
00044     pset.getUntrackedParameter<ParameterSet>("dataset", ParameterSet());
00045   }
00046 
00047   PoolOutputModule::OutputItem::Sorter::Sorter(TTree * tree) {
00048     // Fill a map mapping branch names to an index specifying the order in the tree.
00049     if (tree != 0) {
00050       TObjArray * branches = tree->GetListOfBranches();
00051       for (int i = 0; i < branches->GetEntries(); ++i) {
00052         TBranchElement * br = (TBranchElement *)branches->At(i);
00053         treeMap_.insert(std::make_pair(std::string(br->GetName()), i));
00054       }
00055     }
00056   }
00057 
00058   bool
00059   PoolOutputModule::OutputItem::Sorter::operator()(OutputItem const& lh, OutputItem const& rh) const {
00060     // Provides a comparison for sorting branches according to the index values in treeMap_.
00061     // Branches not found are always put at the end (i.e. not found > found).
00062     if (treeMap_.empty()) return lh < rh;
00063     std::string const& lstring = lh.branchDescription_->branchName();
00064     std::string const& rstring = rh.branchDescription_->branchName();
00065     std::map<std::string, int>::const_iterator lit = treeMap_.find(lstring);
00066     std::map<std::string, int>::const_iterator rit = treeMap_.find(rstring);
00067     bool lfound = (lit != treeMap_.end());
00068     bool rfound = (rit != treeMap_.end());
00069     if (lfound && rfound) {
00070       return lit->second < rit->second;
00071     } else if (lfound) {
00072       return true;
00073     } else if (rfound) {
00074       return false;
00075     }
00076     return lh < rh;
00077   }
00078 
00079   void PoolOutputModule::fillSelectedItemList(BranchType branchType, TTree * theTree) {
00080 
00081     Selections const& keptVector =    keptProducts()[branchType];
00082     OutputItemList&   outputItemList = selectedOutputItemList_[branchType];
00083 
00084     // Fill outputItemList with an entry for each branch.
00085     for (Selections::const_iterator it = keptVector.begin(), itEnd = keptVector.end(); it != itEnd; ++it) {
00086       BranchDescription const& prod = **it;
00087       outputItemList.push_back(OutputItem(&prod));
00088     }
00089 
00090     // Sort outputItemList to allow fast copying.
00091     // The branches in outputItemList must be in the same order as in the input tree, with all new branches at the end.
00092     sort_all(outputItemList, OutputItem::Sorter(theTree));
00093   }
00094 
00095   void PoolOutputModule::openFile(FileBlock const& fb) {
00096     if (!isFileOpen()) {
00097       if (fb.tree() == 0 || fb.fileFormatVersion().value_ < 8) {
00098         fastCloning_ = false;
00099       }
00100       doOpenFile();
00101       respondToOpenInputFile(fb);
00102     }
00103   }
00104 
00105   void PoolOutputModule::respondToOpenInputFile(FileBlock const& fb) {
00106     for (int i = InEvent; i < NumBranchTypes; ++i) {
00107       BranchType branchType = static_cast<BranchType>(i);
00108       if (inputFileCount_ == 0) {
00109         TTree * theTree = (branchType == InEvent ? fb.tree() : 
00110                           (branchType == InLumi ? fb.lumiTree() :
00111                           fb.runTree()));
00112         fillSelectedItemList(branchType, theTree);
00113       }
00114     }
00115     ++inputFileCount_;
00116     if (isFileOpen()) {
00117       bool fastCloneThisOne = fb.tree() != 0 &&
00118                             (remainingEvents() < 0 || remainingEvents() >= fb.tree()->GetEntries());
00119       rootOutputFile_->beginInputFile(fb, fastCloneThisOne && fastCloning_);
00120     }
00121   }
00122 
00123   void PoolOutputModule::respondToCloseInputFile(FileBlock const& fb) {
00124     if (rootOutputFile_) rootOutputFile_->respondToCloseInputFile(fb);
00125   }
00126 
00127   PoolOutputModule::~PoolOutputModule() {
00128   }
00129 
00130   void PoolOutputModule::write(EventPrincipal const& e) {
00131       if (hasNewlyDroppedBranch()[InEvent]) e.addToProcessHistory();
00132       rootOutputFile_->writeOne(e);
00133   }
00134 
00135   void PoolOutputModule::writeLuminosityBlock(LuminosityBlockPrincipal const& lb) {
00136       if (hasNewlyDroppedBranch()[InLumi]) lb.addToProcessHistory();
00137       rootOutputFile_->writeLuminosityBlock(lb);
00138       Service<JobReport> reportSvc;
00139       reportSvc->reportLumiSection(lb.id().run(), lb.id().luminosityBlock());
00140   }
00141 
00142   void PoolOutputModule::writeRun(RunPrincipal const& r) {
00143       if (hasNewlyDroppedBranch()[InRun]) r.addToProcessHistory();
00144       rootOutputFile_->writeRun(r);
00145       Service<JobReport> reportSvc;
00146       reportSvc->reportRunNumber(r.run());
00147   }
00148 
00149   // At some later date, we may move functionality from finishEndFile() to here.
00150   void PoolOutputModule::startEndFile() { }
00151 
00152 
00153   void PoolOutputModule::writeFileFormatVersion() { rootOutputFile_->writeFileFormatVersion(); }
00154   void PoolOutputModule::writeFileIdentifier() { rootOutputFile_->writeFileIdentifier(); }
00155   void PoolOutputModule::writeFileIndex() { rootOutputFile_->writeFileIndex(); }
00156   void PoolOutputModule::writeEventHistory() { rootOutputFile_->writeEventHistory(); }
00157   void PoolOutputModule::writeProcessConfigurationRegistry() { rootOutputFile_->writeProcessConfigurationRegistry(); }
00158   void PoolOutputModule::writeProcessHistoryRegistry() { rootOutputFile_->writeProcessHistoryRegistry(); }
00159   void PoolOutputModule::writeModuleDescriptionRegistry() { rootOutputFile_->writeModuleDescriptionRegistry(); }
00160   void PoolOutputModule::writeParameterSetRegistry() { rootOutputFile_->writeParameterSetRegistry(); }
00161   void PoolOutputModule::writeProductDescriptionRegistry() { rootOutputFile_->writeProductDescriptionRegistry(); }
00162   void PoolOutputModule::writeProductDependencies() { rootOutputFile_->writeProductDependencies(); }
00163   void PoolOutputModule::writeEntryDescriptions() { rootOutputFile_->writeEntryDescriptions(); }
00164   void PoolOutputModule::finishEndFile() { rootOutputFile_->finishEndFile(); rootOutputFile_.reset(); }
00165   bool PoolOutputModule::isFileOpen() const { return rootOutputFile_.get() != 0; }
00166   bool PoolOutputModule::shouldWeCloseFile() const { return rootOutputFile_->shouldWeCloseFile(); }
00167 
00168   void PoolOutputModule::doOpenFile() {
00169       if (inputFileCount_ == 0) {
00170         throw edm::Exception(edm::errors::LogicError)
00171           << "Attempt to open output file before input file. "
00172           << "Please report this to the core framework developers.\n";
00173       }
00174       std::string suffix(".root");
00175       std::string::size_type offset = fileName().rfind(suffix);
00176       bool ext = (offset == fileName().size() - suffix.size());
00177       if (!ext) suffix.clear();
00178       std::string fileBase(ext ? fileName().substr(0, offset) : fileName());
00179       std::ostringstream ofilename;
00180       std::ostringstream lfilename;
00181       ofilename << fileBase;
00182       lfilename << logicalFileName();
00183       if (outputFileCount_) {
00184         ofilename << std::setw(3) << std::setfill('0') << outputFileCount_;
00185         if (!logicalFileName().empty()) {
00186           lfilename << std::setw(3) << std::setfill('0') << outputFileCount_;
00187         }
00188       }
00189       ofilename << suffix;
00190       rootOutputFile_.reset(new RootOutputFile(this, ofilename.str(), lfilename.str()));
00191       ++outputFileCount_;
00192   }
00193 }

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