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