CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/FWCore/Framework/src/EventPrincipal.cc

Go to the documentation of this file.
00001 #include "FWCore/Framework/interface/EventPrincipal.h"
00002 
00003 #include "DataFormats/Common/interface/BasicHandle.h"
00004 #include "DataFormats/Provenance/interface/BranchIDList.h"
00005 #include "DataFormats/Provenance/interface/BranchIDListRegistry.h"
00006 #include "DataFormats/Provenance/interface/BranchListIndex.h"
00007 #include "DataFormats/Provenance/interface/ProductIDToBranchID.h"
00008 #include "DataFormats/Provenance/interface/ProductRegistry.h"
00009 #include "DataFormats/Provenance/interface/Provenance.h"
00010 #include "FWCore/Framework/interface/DelayedReader.h"
00011 #include "FWCore/Framework/interface/Group.h"
00012 #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h"
00013 #include "FWCore/Framework/interface/UnscheduledHandler.h"
00014 #include "FWCore/Utilities/interface/Algorithms.h"
00015 #include "FWCore/Utilities/interface/EDMException.h"
00016 
00017 #include <algorithm>
00018 
00019 namespace edm {
00020   EventPrincipal::EventPrincipal(
00021         boost::shared_ptr<ProductRegistry const> reg,
00022         ProcessConfiguration const& pc) :
00023           Base(reg, pc, InEvent),
00024           aux_(),
00025           luminosityBlockPrincipal_(),
00026           unscheduledHandler_(),
00027           moduleLabelsRunning_(),
00028           eventSelectionIDs_(new EventSelectionIDVector),
00029           branchListIndexes_(new BranchListIndexes),
00030           branchListIndexToProcessIndex_() {}
00031 
00032   void
00033   EventPrincipal::clearEventPrincipal() {
00034     clearPrincipal();
00035     aux_ = EventAuxiliary();
00036     luminosityBlockPrincipal_.reset();
00037     unscheduledHandler_.reset();
00038     moduleLabelsRunning_.clear();
00039     eventSelectionIDs_->clear();
00040     branchListIndexes_->clear();
00041     branchListIndexToProcessIndex_.clear();
00042   }
00043 
00044   void
00045   EventPrincipal::fillEventPrincipal(EventAuxiliary const& aux,
00046         boost::shared_ptr<LuminosityBlockPrincipal> lbp,
00047         boost::shared_ptr<EventSelectionIDVector> eventSelectionIDs,
00048         boost::shared_ptr<BranchListIndexes> branchListIndexes,
00049         boost::shared_ptr<BranchMapper> mapper,
00050         DelayedReader* reader) {
00051     fillPrincipal(aux.processHistoryID(), mapper, reader);
00052     aux_ = aux;
00053     luminosityBlockPrincipal_ = lbp;
00054     if(eventSelectionIDs) {
00055       eventSelectionIDs_ = eventSelectionIDs;
00056     }
00057     if(luminosityBlockPrincipal_) {
00058       setProcessHistory(*luminosityBlockPrincipal_);
00059       aux_.setProcessHistoryID(processHistoryID());
00060     }
00061 
00062     branchMapperPtr()->processHistoryID() = processHistoryID();
00063     if(branchListIndexes) {
00064       branchListIndexes_ = branchListIndexes;
00065     }
00066 
00067     BranchIDListHelper::fixBranchListIndexes(*branchListIndexes_);
00068     if(productRegistry().productProduced(InEvent)) {
00069       // Add index into BranchIDListRegistry for products produced this process
00070       branchListIndexes_->push_back(productRegistry().producedBranchListIndex());
00071     }
00072 
00073     // Fill in helper map for Branch to ProductID mapping
00074     for(BranchListIndexes::const_iterator
00075         it = branchListIndexes_->begin(),
00076         itEnd = branchListIndexes_->end();
00077         it != itEnd; ++it) {
00078       ProcessIndex pix = it - branchListIndexes_->begin();
00079       branchListIndexToProcessIndex_.insert(std::make_pair(*it, pix));
00080     }
00081 
00082     // Fill in the product ID's in the groups.
00083     for(const_iterator it = this->begin(), itEnd = this->end(); it != itEnd; ++it) {
00084       (*it)->setProvenance(branchMapperPtr(), branchIDToProductID((*it)->branchDescription().branchID()));
00085     }
00086   }
00087 
00088   RunPrincipal const&
00089   EventPrincipal::runPrincipal() const {
00090     return luminosityBlockPrincipal().runPrincipal();
00091   }
00092 
00093   RunPrincipal &
00094   EventPrincipal::runPrincipal() {
00095     return luminosityBlockPrincipal().runPrincipal();
00096   }
00097 
00098   void
00099   EventPrincipal::put(
00100         ConstBranchDescription const& bd,
00101         WrapperOwningHolder const& edp,
00102         ProductProvenance const& productProvenance) {
00103 
00104     assert(bd.produced());
00105     if(!edp.isValid()) {
00106       throw Exception(errors::InsertFailure, "Null Pointer")
00107         << "put: Cannot put because ptr to product is null."
00108         << "\n";
00109     }
00110     branchMapperPtr()->insert(productProvenance);
00111     Group* g = getExistingGroup(bd.branchID());
00112     assert(g);
00113     checkUniquenessAndType(edp, g);
00114     // Group assumes ownership
00115     g->putProduct(edp, productProvenance);
00116   }
00117 
00118   void
00119   EventPrincipal::putOnRead(
00120         ConstBranchDescription const& bd,
00121         void const* product,
00122         ProductProvenance const& productProvenance) {
00123 
00124     assert(!bd.produced());
00125     branchMapperPtr()->insert(productProvenance);
00126     Group* g = getExistingGroup(bd.branchID());
00127     assert(g);
00128     WrapperOwningHolder const edp(product, g->productData().getInterface());
00129     checkUniquenessAndType(edp, g);
00130     // Group assumes ownership
00131     g->putProduct(edp, productProvenance);
00132   }
00133 
00134   void
00135   EventPrincipal::resolveProduct_(Group const& g, bool fillOnDemand) const {
00136     // Try unscheduled production.
00137     if(g.onDemand()) {
00138       if(fillOnDemand) {
00139         unscheduledFill(g.branchDescription().moduleLabel());
00140       }
00141       return;
00142     }
00143 
00144     if(g.branchDescription().produced()) return; // nothing to do.
00145     if(g.product()) return; // nothing to do.
00146     if(g.productUnavailable()) return; // nothing to do.
00147     if(!reader()) return; // nothing to do.
00148 
00149     // must attempt to load from persistent store
00150     BranchKey const bk = BranchKey(g.branchDescription());
00151     WrapperOwningHolder edp(reader()->getProduct(bk, g.productData().getInterface(), this));
00152 
00153     // Now fix up the Group
00154     checkUniquenessAndType(edp, &g);
00155     g.putProduct(edp);
00156   }
00157 
00158   BranchID
00159   EventPrincipal::pidToBid(ProductID const& pid) const {
00160     if(!pid.isValid()) {
00161       throw Exception(errors::ProductNotFound, "InvalidID")
00162         << "get by product ID: invalid ProductID supplied\n";
00163     }
00164     return productIDToBranchID(pid, BranchIDListRegistry::instance()->data(), *branchListIndexes_);
00165   }
00166 
00167   ProductID
00168   EventPrincipal::branchIDToProductID(BranchID const& bid) const {
00169     if(!bid.isValid()) {
00170       throw Exception(errors::NotFound, "InvalidID")
00171         << "branchIDToProductID: invalid BranchID supplied\n";
00172     }
00173     typedef BranchIDListHelper::BranchIDToIndexMap BIDToIndexMap;
00174     typedef BIDToIndexMap::const_iterator Iter;
00175     typedef std::pair<Iter, Iter> IndexRange;
00176 
00177     BIDToIndexMap const& branchIDToIndexMap = BranchIDListRegistry::instance()->extra().branchIDToIndexMap();
00178     IndexRange range = branchIDToIndexMap.equal_range(bid);
00179     for(Iter it = range.first; it != range.second; ++it) {
00180       BranchListIndex blix = it->second.first;
00181       std::map<BranchListIndex, ProcessIndex>::const_iterator i = branchListIndexToProcessIndex_.find(blix);
00182       if(i != branchListIndexToProcessIndex_.end()) {
00183         ProductIndex productIndex = it->second.second;
00184         ProcessIndex processIndex = i->second;
00185         return ProductID(processIndex+1, productIndex+1);
00186       }
00187     }
00188     // cannot throw, because some products may legitimately not have product ID's (e.g. pile-up).
00189     return ProductID();
00190   }
00191 
00192   BasicHandle
00193   EventPrincipal::getByProductID(ProductID const& pid) const {
00194     BranchID bid = pidToBid(pid);
00195     ConstGroupPtr const g = getGroup(bid, true, true);
00196     if(g == 0) {
00197       boost::shared_ptr<cms::Exception> whyFailed(new Exception(errors::ProductNotFound, "InvalidID"));
00198       *whyFailed
00199         << "get by product ID: no product with given id: " << pid << "\n";
00200       return BasicHandle(whyFailed);
00201     }
00202 
00203     // Check for case where we tried on demand production and
00204     // it failed to produce the object
00205     if(g->onDemand()) {
00206       boost::shared_ptr<cms::Exception> whyFailed(new Exception(errors::ProductNotFound, "InvalidID"));
00207       *whyFailed
00208         << "get by product ID: no product with given id: " << pid << "\n"
00209         << "onDemand production failed to produce it.\n";
00210       return BasicHandle(whyFailed);
00211     }
00212     return BasicHandle(g->productData());
00213   }
00214 
00215   WrapperHolder
00216   EventPrincipal::getIt(ProductID const& pid) const {
00217     return getByProductID(pid).wrapperHolder();
00218   }
00219 
00220   Provenance
00221   EventPrincipal::getProvenance(ProductID const& pid) const {
00222     BranchID bid = pidToBid(pid);
00223     return getProvenance(bid);
00224   }
00225 
00226   void
00227   EventPrincipal::setUnscheduledHandler(boost::shared_ptr<UnscheduledHandler> iHandler) {
00228     unscheduledHandler_ = iHandler;
00229   }
00230 
00231   boost::shared_ptr<UnscheduledHandler>
00232   EventPrincipal::unscheduledHandler() const {
00233      return unscheduledHandler_;
00234   }
00235 
00236   EventSelectionIDVector const&
00237   EventPrincipal::eventSelectionIDs() const {
00238     return *eventSelectionIDs_;
00239   }
00240 
00241   BranchListIndexes const&
00242   EventPrincipal::branchListIndexes() const {
00243     return *branchListIndexes_;
00244   }
00245 
00246   bool
00247   EventPrincipal::unscheduledFill(std::string const& moduleLabel) const {
00248 
00249     // If it is a module already currently running in unscheduled
00250     // mode, then there is a circular dependency related to which
00251     // EDProducts modules require and produce.  There is no safe way
00252     // to recover from this.  Here we check for this problem and throw
00253     // an exception.
00254     std::vector<std::string>::const_iterator i =
00255       find_in_all(moduleLabelsRunning_, moduleLabel);
00256 
00257     if(i != moduleLabelsRunning_.end()) {
00258       throw Exception(errors::LogicError)
00259         << "Hit circular dependency while trying to run an unscheduled module.\n"
00260         << "Current implementation of unscheduled execution cannot always determine\n"
00261         << "the proper order for module execution.  It is also possible the modules\n"
00262         << "have a built in circular dependence that will not work with any order.\n"
00263         << "In the first case, scheduling some or all required modules in paths will help.\n"
00264         << "In the second case, the modules themselves will have to be fixed.\n";
00265     }
00266 
00267     moduleLabelsRunning_.push_back(moduleLabel);
00268 
00269     if(unscheduledHandler_) {
00270       unscheduledHandler_->tryToFill(moduleLabel, *const_cast<EventPrincipal*>(this));
00271     }
00272     moduleLabelsRunning_.pop_back();
00273     return true;
00274   }
00275 
00276   ProductID
00277   EventPrincipal::oldToNewProductID_(ProductID const& oldProductID) const {
00278     BranchID bid = branchMapperPtr()->oldProductIDToBranchID(oldProductID);
00279     if(!bid.isValid()) return oldProductID;
00280     return branchIDToProductID(bid);
00281   }
00282 }