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
00070 branchListIndexes_->push_back(productRegistry().producedBranchListIndex());
00071 }
00072
00073
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
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
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
00131 g->putProduct(edp, productProvenance);
00132 }
00133
00134 void
00135 EventPrincipal::resolveProduct_(Group const& g, bool fillOnDemand) const {
00136
00137 if(g.onDemand()) {
00138 if(fillOnDemand) {
00139 unscheduledFill(g.branchDescription().moduleLabel());
00140 }
00141 return;
00142 }
00143
00144 if(g.branchDescription().produced()) return;
00145 if(g.product()) return;
00146 if(g.productUnavailable()) return;
00147 if(!reader()) return;
00148
00149
00150 BranchKey const bk = BranchKey(g.branchDescription());
00151 WrapperOwningHolder edp(reader()->getProduct(bk, g.productData().getInterface(), this));
00152
00153
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
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
00204
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
00250
00251
00252
00253
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 }