00001
00002
00003 #include "PoolSource.h"
00004 #include "RootInputFileSequence.h"
00005 #include "DataFormats/Provenance/interface/ProductRegistry.h"
00006 #include "FWCore/Framework/interface/EventPrincipal.h"
00007 #include "FWCore/Framework/interface/FileBlock.h"
00008 #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h"
00009 #include "FWCore/Framework/interface/RunPrincipal.h"
00010 #include "FWCore/Utilities/interface/Exception.h"
00011 #include "FWCore/Utilities/interface/EDMException.h"
00012
00013 #include "TTreeCache.h"
00014
00015 #include <set>
00016
00017 namespace edm {
00018 namespace {
00019 void checkHistoryConsistency(Principal const& primary, Principal const& secondary) {
00020 ProcessHistory const& ph1 = primary.processHistory();
00021 ProcessHistory const& ph2 = secondary.processHistory();
00022 if (ph1 != ph2 && !isAncestor(ph2, ph1)) {
00023 throw edm::Exception(errors::MismatchedInputFiles, "PoolSource::checkConsistency") <<
00024 "The secondary file is not an ancestor of the primary file\n";
00025 }
00026 }
00027 void checkConsistency(EventPrincipal const& primary, EventPrincipal const& secondary) {
00028 if (!isSameEvent(primary, secondary)) {
00029 throw edm::Exception(errors::MismatchedInputFiles, "PoolSource::checkConsistency") <<
00030 primary.id() << " has inconsistent EventAuxiliary data in the primary and secondary file\n";
00031 }
00032 checkHistoryConsistency(primary, secondary);
00033 }
00034 void checkConsistency(LuminosityBlockPrincipal const& primary, LuminosityBlockPrincipal const& secondary) {
00035 if (primary.id() != secondary.id()) {
00036 throw edm::Exception(errors::MismatchedInputFiles, "PoolSource::checkConsistency") <<
00037 primary.id() << " has inconsistent LuminosityBlockAuxiliary data in the primary and secondary file\n";
00038 }
00039 checkHistoryConsistency(primary, secondary);
00040 }
00041 void checkConsistency(RunPrincipal const& primary, RunPrincipal const& secondary) {
00042 if (primary.id() != secondary.id()) {
00043 throw edm::Exception(errors::MismatchedInputFiles, "PoolSource::checkConsistency") <<
00044 primary.id() << " has inconsistent RunAuxiliary data in the primary and secondary file\n";
00045 }
00046 checkHistoryConsistency(primary, secondary);
00047 }
00048 }
00049
00050 PoolSource::PoolSource(ParameterSet const& pset, InputSourceDescription const& desc) :
00051 VectorInputSource(pset, desc),
00052 rootServiceChecker_(),
00053 primaryFileSequence_(new RootInputFileSequence(pset, *this, catalog(), primary())),
00054 secondaryFileSequence_(catalog(1).empty() ? 0 : new RootInputFileSequence(pset, *this, catalog(1), false)),
00055 branchIDsToReplace_() {
00056 if (secondaryFileSequence_) {
00057 boost::array<std::set<BranchID>, NumBranchTypes> idsToReplace;
00058 ProductRegistry::ProductList const& secondary = secondaryFileSequence_->fileProductRegistry().productList();
00059 ProductRegistry::ProductList const& primary = primaryFileSequence_->fileProductRegistry().productList();
00060 typedef ProductRegistry::ProductList::const_iterator const_iterator;
00061 for (const_iterator it = secondary.begin(), itEnd = secondary.end(); it != itEnd; ++it) {
00062 if (it->second.present()) idsToReplace[it->second.branchType()].insert(it->second.branchID());
00063 }
00064 for (const_iterator it = primary.begin(), itEnd = primary.end(); it != itEnd; ++it) {
00065 if (it->second.present()) idsToReplace[it->second.branchType()].erase(it->second.branchID());
00066 }
00067 if (idsToReplace[InEvent].empty() && idsToReplace[InLumi].empty() && idsToReplace[InRun].empty()) {
00068 secondaryFileSequence_.reset();
00069 }
00070 else {
00071 for (int i = InEvent; i < NumBranchTypes; ++i) {
00072 branchIDsToReplace_[i].reserve(idsToReplace[i].size());
00073 for (std::set<BranchID>::const_iterator it = idsToReplace[i].begin(), itEnd = idsToReplace[i].end();
00074 it != itEnd; ++it) {
00075 branchIDsToReplace_[i].push_back(*it);
00076 }
00077 }
00078 }
00079 }
00080 }
00081
00082 PoolSource::~PoolSource() {}
00083
00084 void
00085 PoolSource::endJob() {
00086 if (secondaryFileSequence_) secondaryFileSequence_->endJob();
00087 primaryFileSequence_->endJob();
00088 }
00089
00090 boost::shared_ptr<FileBlock>
00091 PoolSource::readFile_() {
00092 if (secondaryFileSequence_) {
00093 boost::shared_ptr<FileBlock> fb = primaryFileSequence_->readFile_();
00094 fb->setNotFastCopyable();
00095 return fb;
00096 }
00097 return primaryFileSequence_->readFile_();
00098 }
00099
00100 void PoolSource::closeFile_() {
00101 primaryFileSequence_->closeFile_();
00102 }
00103
00104 boost::shared_ptr<RunPrincipal>
00105 PoolSource::readRun_() {
00106 if (secondaryFileSequence_ && !branchIDsToReplace_[InRun].empty()) {
00107 boost::shared_ptr<RunPrincipal> primaryPrincipal = primaryFileSequence_->readRun_();
00108 boost::shared_ptr<RunPrincipal> secondaryPrincipal = secondaryFileSequence_->readIt(primaryPrincipal->id());
00109 if (secondaryPrincipal.get() != 0) {
00110 checkConsistency(*primaryPrincipal, *secondaryPrincipal);
00111 primaryPrincipal->recombine(*secondaryPrincipal, branchIDsToReplace_[InRun]);
00112 } else {
00113 throw edm::Exception(errors::MismatchedInputFiles, "PoolSource::readRun_")
00114 << " Run " << primaryPrincipal->run()
00115 << " is not found in the secondary input files\n";
00116 }
00117 return primaryPrincipal;
00118 }
00119 return primaryFileSequence_->readRun_();
00120 }
00121
00122 boost::shared_ptr<LuminosityBlockPrincipal>
00123 PoolSource::readLuminosityBlock_() {
00124 if (secondaryFileSequence_ && !branchIDsToReplace_[InLumi].empty()) {
00125 boost::shared_ptr<LuminosityBlockPrincipal> primaryPrincipal = primaryFileSequence_->readLuminosityBlock_();
00126 boost::shared_ptr<LuminosityBlockPrincipal> secondaryPrincipal = secondaryFileSequence_->readIt(primaryPrincipal->id());
00127 if (secondaryPrincipal.get() != 0) {
00128 checkConsistency(*primaryPrincipal, *secondaryPrincipal);
00129 primaryPrincipal->recombine(*secondaryPrincipal, branchIDsToReplace_[InLumi]);
00130 } else {
00131 throw edm::Exception(errors::MismatchedInputFiles, "PoolSource::readLuminosityBlock_")
00132 << " Run " << primaryPrincipal->run()
00133 << " LuminosityBlock " << primaryPrincipal->luminosityBlock()
00134 << " is not found in the secondary input files\n";
00135 }
00136 return primaryPrincipal;
00137 }
00138 return primaryFileSequence_->readLuminosityBlock_();
00139 }
00140
00141 std::auto_ptr<EventPrincipal>
00142 PoolSource::readEvent_() {
00143 if (secondaryFileSequence_ && !branchIDsToReplace_[InEvent].empty()) {
00144 std::auto_ptr<EventPrincipal> primaryPrincipal = primaryFileSequence_->readEvent_();
00145 std::auto_ptr<EventPrincipal> secondaryPrincipal = secondaryFileSequence_->readIt(primaryPrincipal->id(), primaryPrincipal->luminosityBlock(), true);
00146 if (secondaryPrincipal.get() != 0) {
00147 checkConsistency(*primaryPrincipal, *secondaryPrincipal);
00148 primaryPrincipal->recombine(*secondaryPrincipal, branchIDsToReplace_[InEvent]);
00149 } else {
00150 throw edm::Exception(errors::MismatchedInputFiles, "PoolSource::readEvent_") <<
00151 primaryPrincipal->id() << " is not found in the secondary input files\n";
00152 }
00153 return primaryPrincipal;
00154 }
00155 EventSourceSentry(*this);
00156 return primaryFileSequence_->readEvent_();
00157 }
00158
00159 std::auto_ptr<EventPrincipal>
00160 PoolSource::readIt(EventID const& id) {
00161 if (secondaryFileSequence_) {
00162 std::auto_ptr<EventPrincipal> primaryPrincipal = primaryFileSequence_->readIt(id);
00163 std::auto_ptr<EventPrincipal> secondaryPrincipal = secondaryFileSequence_->readIt(id, primaryPrincipal->luminosityBlock(), true);
00164 if (secondaryPrincipal.get() != 0) {
00165 checkConsistency(*primaryPrincipal, *secondaryPrincipal);
00166 primaryPrincipal->recombine(*secondaryPrincipal, branchIDsToReplace_[InEvent]);
00167 } else {
00168 throw edm::Exception(errors::MismatchedInputFiles, "PoolSource::readIt") <<
00169 primaryPrincipal->id() << " is not found in the secondary input files\n";
00170 }
00171 return primaryPrincipal;
00172 }
00173 EventSourceSentry(*this);
00174 return primaryFileSequence_->readIt(id);
00175 }
00176
00177 InputSource::ItemType
00178 PoolSource::getNextItemType() {
00179 return primaryFileSequence_->getNextItemType();
00180 }
00181
00182
00183 void
00184 PoolSource::rewind_() {
00185 primaryFileSequence_->rewind_();
00186 }
00187
00188
00189 void
00190 PoolSource::skip(int offset) {
00191 primaryFileSequence_->skip(offset);
00192 }
00193
00194 void
00195 PoolSource::readMany_(int number, EventPrincipalVector& result) {
00196 assert (!secondaryFileSequence_);
00197 primaryFileSequence_->readMany_(number, result);
00198 }
00199
00200 void
00201 PoolSource::readMany_(int number, EventPrincipalVector& result, EventID const& id, unsigned int fileSeqNumber) {
00202 assert (!secondaryFileSequence_);
00203 primaryFileSequence_->readMany_(number, result, id, fileSeqNumber);
00204 }
00205
00206 void
00207 PoolSource::readManyRandom_(int number, EventPrincipalVector& result, unsigned int& fileSeqNumber) {
00208 assert (!secondaryFileSequence_);
00209 primaryFileSequence_->readManyRandom_(number, result, fileSeqNumber);
00210 }
00211
00212 void
00213 PoolSource::dropUnwantedBranches_(std::vector<std::string> const& wantedBranches) {
00214 assert (!secondaryFileSequence_);
00215 assert (!primary());
00216 primaryFileSequence_->dropUnwantedBranches_(wantedBranches);
00217 }
00218 }
00219