CMS 3D CMS Logo

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