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