CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/IOPool/Input/src/PoolSource.cc

Go to the documentation of this file.
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       //this is the registry used by the 'outside' world and only has the primary file information in it at present
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           //now make sure this is marked as not dropped else the product will not be 'get'table from the Event
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   // Rewind to before the first event that was read.
00219   void
00220   PoolSource::rewind_() {
00221     primaryFileSequence_->rewind_();
00222   }
00223 
00224   // Advance "offset" events.  Offset can be positive or negative (or zero).
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 }