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
00066 branchListIndexes_->push_back(productRegistry().producedBranchListIndex());
00067 }
00068
00069
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
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
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
00125 g->putProduct(edp, productProvenance);
00126 }
00127
00128 void
00129 EventPrincipal::resolveProduct_(Group const& g, bool fillOnDemand) const {
00130
00131 if(g.onDemand()) {
00132 if(fillOnDemand) {
00133 unscheduledFill(g.branchDescription().moduleLabel());
00134 }
00135 return;
00136 }
00137
00138 if(g.branchDescription().produced()) return;
00139 if(g.product()) return;
00140 if(g.productUnavailable()) return;
00141
00142
00143 BranchKey const bk = BranchKey(g.branchDescription());
00144 std::auto_ptr<EDProduct> edp(store()->getProduct(bk, this));
00145
00146
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
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
00197
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
00243
00244
00245
00246
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 }