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
00042
00043
00044 pset.getUntrackedParameter<ParameterSet>("dataset", ParameterSet());
00045 }
00046
00047 PoolOutputModule::OutputItem::Sorter::Sorter(TTree * tree) {
00048
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
00061
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
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
00091
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
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 }