00001
00002
00003 #include "PoolSource.h"
00004 #include "InputFile.h"
00005 #include "InputType.h"
00006 #include "RootInputFileSequence.h"
00007 #include "DataFormats/Provenance/interface/ProductRegistry.h"
00008 #include "FWCore/Framework/interface/EventPrincipal.h"
00009 #include "FWCore/Framework/interface/FileBlock.h"
00010 #include "FWCore/Framework/interface/InputSourceDescription.h"
00011 #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h"
00012 #include "FWCore/Framework/interface/RunPrincipal.h"
00013 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
00014 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
00015 #include "FWCore/Utilities/interface/EDMException.h"
00016 #include "FWCore/Utilities/interface/Exception.h"
00017
00018 #include <set>
00019
00020 namespace edm {
00021
00022 class LuminosityBlockID;
00023 class EventID;
00024
00025 namespace {
00026 void checkHistoryConsistency(Principal const& primary, Principal const& secondary) {
00027 ProcessHistory const& ph1 = primary.processHistory();
00028 ProcessHistory const& ph2 = secondary.processHistory();
00029 if(ph1 != ph2 && !isAncestor(ph2, ph1)) {
00030 throw Exception(errors::MismatchedInputFiles, "PoolSource::checkConsistency") <<
00031 "The secondary file is not an ancestor of the primary file\n";
00032 }
00033 }
00034 void checkConsistency(EventPrincipal const& primary, EventPrincipal const& secondary) {
00035 if(!isSameEvent(primary, secondary)) {
00036 throw Exception(errors::MismatchedInputFiles, "PoolSource::checkConsistency") <<
00037 primary.id() << " has inconsistent EventAuxiliary data in the primary and secondary file\n";
00038 }
00039 }
00040 void checkConsistency(LuminosityBlockAuxiliary const& primary, LuminosityBlockAuxiliary const& secondary) {
00041 if(primary.id() != secondary.id()) {
00042 throw Exception(errors::MismatchedInputFiles, "PoolSource::checkConsistency") <<
00043 primary.id() << " has inconsistent LuminosityBlockAuxiliary data in the primary and secondary file\n";
00044 }
00045 }
00046 void checkConsistency(RunAuxiliary const& primary, RunAuxiliary const& secondary) {
00047 if(primary.id() != secondary.id()) {
00048 throw Exception(errors::MismatchedInputFiles, "PoolSource::checkConsistency") <<
00049 primary.id() << " has inconsistent RunAuxiliary data in the primary and secondary file\n";
00050 }
00051 }
00052 }
00053
00054 PoolSource::PoolSource(ParameterSet const& pset, InputSourceDescription const& desc) :
00055 VectorInputSource(pset, desc),
00056 rootServiceChecker_(),
00057 primaryFileSequence_(new RootInputFileSequence(pset, *this, catalog(),
00058 primary() ? InputType::Primary : InputType::SecondarySource)),
00059 secondaryFileSequence_(catalog(1).empty() ? 0 :
00060 new RootInputFileSequence(pset, *this, catalog(1), InputType::SecondaryFile)),
00061 secondaryRunPrincipal_(),
00062 secondaryLumiPrincipal_(),
00063 secondaryEventPrincipal_(secondaryFileSequence_ ? new EventPrincipal(secondaryFileSequence_->fileProductRegistry(), secondaryFileSequence_->fileBranchIDListHelper(), processConfiguration()) : 0),
00064 branchIDsToReplace_() {
00065 if(secondaryFileSequence_) {
00066 assert(primary());
00067 std::array<std::set<BranchID>, NumBranchTypes> idsToReplace;
00068 ProductRegistry::ProductList const& secondary = secondaryFileSequence_->fileProductRegistry()->productList();
00069 ProductRegistry::ProductList const& primary = primaryFileSequence_->fileProductRegistry()->productList();
00070 typedef ProductRegistry::ProductList::const_iterator const_iterator;
00071 typedef ProductRegistry::ProductList::iterator iterator;
00072
00073 ProductRegistry::ProductList& fullList = productRegistryUpdate().productListUpdator();
00074 for(const_iterator it = secondary.begin(), itEnd = secondary.end(); it != itEnd; ++it) {
00075 if(it->second.present()) {
00076 idsToReplace[it->second.branchType()].insert(it->second.branchID());
00077
00078 iterator itFound = fullList.find(it->first);
00079 if(itFound != fullList.end()) {
00080 itFound->second.dropped()=false;
00081 }
00082 }
00083 }
00084 for(const_iterator it = primary.begin(), itEnd = primary.end(); it != itEnd; ++it) {
00085 if(it->second.present()) idsToReplace[it->second.branchType()].erase(it->second.branchID());
00086 }
00087 if(idsToReplace[InEvent].empty() && idsToReplace[InLumi].empty() && idsToReplace[InRun].empty()) {
00088 secondaryFileSequence_.reset();
00089 } else {
00090 for(int i = InEvent; i < NumBranchTypes; ++i) {
00091 branchIDsToReplace_[i].reserve(idsToReplace[i].size());
00092 for(std::set<BranchID>::const_iterator it = idsToReplace[i].begin(), itEnd = idsToReplace[i].end();
00093 it != itEnd; ++it) {
00094 branchIDsToReplace_[i].push_back(*it);
00095 }
00096 }
00097 }
00098 }
00099 }
00100
00101 PoolSource::~PoolSource() {}
00102
00103 void
00104 PoolSource::endJob() {
00105 if(secondaryFileSequence_) secondaryFileSequence_->endJob();
00106 primaryFileSequence_->endJob();
00107 InputFile::reportReadBranches();
00108 }
00109
00110 boost::shared_ptr<FileBlock>
00111 PoolSource::readFile_() {
00112 boost::shared_ptr<FileBlock> fb = primaryFileSequence_->readFile_();
00113 if(secondaryFileSequence_) {
00114 fb->setNotFastClonable(FileBlock::HasSecondaryFileSequence);
00115 }
00116 return fb;
00117 }
00118
00119 void PoolSource::closeFile_() {
00120 primaryFileSequence_->closeFile_();
00121 }
00122
00123 boost::shared_ptr<RunAuxiliary>
00124 PoolSource::readRunAuxiliary_() {
00125 return primaryFileSequence_->readRunAuxiliary_();
00126 }
00127
00128 boost::shared_ptr<LuminosityBlockAuxiliary>
00129 PoolSource::readLuminosityBlockAuxiliary_() {
00130 return primaryFileSequence_->readLuminosityBlockAuxiliary_();
00131 }
00132
00133 boost::shared_ptr<RunPrincipal>
00134 PoolSource::readRun_(boost::shared_ptr<RunPrincipal> runPrincipal) {
00135 if(secondaryFileSequence_ && !branchIDsToReplace_[InRun].empty()) {
00136 boost::shared_ptr<RunPrincipal> primaryPrincipal = primaryFileSequence_->readRun_(runPrincipal);
00137 bool found = secondaryFileSequence_->skipToItem(primaryPrincipal->run(), 0U, 0U);
00138 if(found) {
00139 boost::shared_ptr<RunAuxiliary> secondaryAuxiliary = secondaryFileSequence_->readRunAuxiliary_();
00140 checkConsistency(primaryPrincipal->aux(), *secondaryAuxiliary);
00141 boost::shared_ptr<RunPrincipal> rp(new RunPrincipal(secondaryAuxiliary, secondaryFileSequence_->fileProductRegistry(), processConfiguration()));
00142 secondaryRunPrincipal_ = secondaryFileSequence_->readRun_(rp);
00143 checkHistoryConsistency(*primaryPrincipal, *secondaryRunPrincipal_);
00144 primaryPrincipal->recombine(*secondaryRunPrincipal_, branchIDsToReplace_[InRun]);
00145 } else {
00146 throw Exception(errors::MismatchedInputFiles, "PoolSource::readRun_")
00147 << " Run " << primaryPrincipal->run()
00148 << " is not found in the secondary input files\n";
00149 }
00150 return primaryPrincipal;
00151 }
00152 return primaryFileSequence_->readRun_(runPrincipal);
00153 }
00154
00155 boost::shared_ptr<LuminosityBlockPrincipal>
00156 PoolSource::readLuminosityBlock_(boost::shared_ptr<LuminosityBlockPrincipal> lumiPrincipal) {
00157 if(secondaryFileSequence_ && !branchIDsToReplace_[InLumi].empty()) {
00158 boost::shared_ptr<LuminosityBlockPrincipal> primaryPrincipal = primaryFileSequence_->readLuminosityBlock_(lumiPrincipal);
00159 bool found = secondaryFileSequence_->skipToItem(primaryPrincipal->run(), primaryPrincipal->luminosityBlock(), 0U);
00160 if(found) {
00161 boost::shared_ptr<LuminosityBlockAuxiliary> secondaryAuxiliary = secondaryFileSequence_->readLuminosityBlockAuxiliary_();
00162 checkConsistency(primaryPrincipal->aux(), *secondaryAuxiliary);
00163 boost::shared_ptr<LuminosityBlockPrincipal> lbp(new LuminosityBlockPrincipal(secondaryAuxiliary, secondaryFileSequence_->fileProductRegistry(), processConfiguration()));
00164 secondaryLumiPrincipal_ = secondaryFileSequence_->readLuminosityBlock_(lbp);
00165 checkHistoryConsistency(*primaryPrincipal, *secondaryLumiPrincipal_);
00166 primaryPrincipal->recombine(*secondaryLumiPrincipal_, branchIDsToReplace_[InLumi]);
00167 } else {
00168 throw Exception(errors::MismatchedInputFiles, "PoolSource::readLuminosityBlock_")
00169 << " Run " << primaryPrincipal->run()
00170 << " LuminosityBlock " << primaryPrincipal->luminosityBlock()
00171 << " is not found in the secondary input files\n";
00172 }
00173 return primaryPrincipal;
00174 }
00175 return primaryFileSequence_->readLuminosityBlock_(lumiPrincipal);
00176 }
00177
00178 EventPrincipal*
00179 PoolSource::readEvent_(EventPrincipal& eventPrincipal) {
00180 EventSourceSentry(*this);
00181 EventPrincipal* primaryPrincipal = primaryFileSequence_->readEvent(eventPrincipal);
00182 if(secondaryFileSequence_ && !branchIDsToReplace_[InEvent].empty()) {
00183 bool found = secondaryFileSequence_->skipToItem(primaryPrincipal->run(),
00184 primaryPrincipal->luminosityBlock(),
00185 primaryPrincipal->id().event());
00186 if(found) {
00187 EventPrincipal* secondaryPrincipal = secondaryFileSequence_->readEvent(*secondaryEventPrincipal_);
00188 checkConsistency(*primaryPrincipal, *secondaryPrincipal);
00189 checkHistoryConsistency(*primaryPrincipal, *secondaryPrincipal);
00190 primaryPrincipal->recombine(*secondaryPrincipal, branchIDsToReplace_[InEvent]);
00191 primaryPrincipal->mergeMappers(*secondaryPrincipal);
00192 secondaryEventPrincipal_->clearPrincipal();
00193 } else {
00194 throw Exception(errors::MismatchedInputFiles, "PoolSource::readEvent_") <<
00195 primaryPrincipal->id() << " is not found in the secondary input files\n";
00196 }
00197 }
00198 return primaryPrincipal;
00199 }
00200
00201 EventPrincipal*
00202 PoolSource::readIt(EventID const& id, EventPrincipal& eventPrincipal) {
00203 bool found = primaryFileSequence_->skipToItem(id.run(), id.luminosityBlock(), id.event());
00204 if(!found) return 0;
00205 return readEvent_(eventPrincipal);
00206 }
00207
00208 InputSource::ItemType
00209 PoolSource::getNextItemType() {
00210 return primaryFileSequence_->getNextItemType();;
00211 }
00212
00213 void
00214 PoolSource::preForkReleaseResources() {
00215 primaryFileSequence_->closeFile_();
00216 }
00217
00218
00219 void
00220 PoolSource::rewind_() {
00221 primaryFileSequence_->rewind_();
00222 }
00223
00224
00225 void
00226 PoolSource::skip(int offset) {
00227 primaryFileSequence_->skipEvents(offset);
00228 }
00229
00230 bool
00231 PoolSource::goToEvent_(EventID const& eventID) {
00232 return primaryFileSequence_->goToEvent(eventID);
00233 }
00234
00235 EventPrincipal*
00236 PoolSource::readOneRandom() {
00237 assert(!secondaryFileSequence_);
00238 return primaryFileSequence_->readOneRandom();
00239 }
00240
00241 EventPrincipal*
00242 PoolSource::readOneRandomWithID(LuminosityBlockID const& lumiID) {
00243 assert(!secondaryFileSequence_);
00244 return primaryFileSequence_->readOneRandomWithID(lumiID);
00245 }
00246
00247 EventPrincipal*
00248 PoolSource::readOneSequential() {
00249 assert(!secondaryFileSequence_);
00250 return primaryFileSequence_->readOneSequential();
00251 }
00252
00253 EventPrincipal*
00254 PoolSource::readOneSequentialWithID(LuminosityBlockID const& lumiID) {
00255 assert(!secondaryFileSequence_);
00256 return primaryFileSequence_->readOneSequentialWithID(lumiID);
00257 }
00258
00259 EventPrincipal*
00260 PoolSource::readOneSpecified(EventID const& id) {
00261 assert(!secondaryFileSequence_);
00262 return primaryFileSequence_->readOneSpecified(id);
00263 }
00264
00265 void
00266 PoolSource::dropUnwantedBranches_(std::vector<std::string> const& wantedBranches) {
00267 assert(!secondaryFileSequence_);
00268 primaryFileSequence_->dropUnwantedBranches_(wantedBranches);
00269 }
00270
00271 void
00272 PoolSource::fillDescriptions(ConfigurationDescriptions & descriptions) {
00273
00274 ParameterSetDescription desc;
00275
00276 desc.setComment("Reads EDM/Root files.");
00277 VectorInputSource::fillDescription(desc);
00278 RootInputFileSequence::fillDescription(desc);
00279
00280 descriptions.add("source", desc);
00281 }
00282
00283 bool
00284 PoolSource::randomAccess_() const {
00285 return true;
00286 }
00287
00288 ProcessingController::ForwardState
00289 PoolSource::forwardState_() const {
00290 return primaryFileSequence_->forwardState();
00291 }
00292
00293 ProcessingController::ReverseState
00294 PoolSource::reverseState_() const {
00295 return primaryFileSequence_->reverseState();
00296 }
00297 }