00001 #include "FWCore/Framework/interface/EventPrincipal.h"
00002 #include "FWCore/Framework/interface/UnscheduledHandler.h"
00003 #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h"
00004 #include "FWCore/Framework/interface/Group.h"
00005 #include "FWCore/Utilities/interface/Algorithms.h"
00006 #include "DataFormats/Common/interface/BasicHandle.h"
00007 #include "DataFormats/Provenance/interface/Provenance.h"
00008
00009 #include <algorithm>
00010
00011 namespace edm {
00012 EventPrincipal::EventPrincipal(EventAuxiliary const& aux,
00013 boost::shared_ptr<ProductRegistry const> reg,
00014 ProcessConfiguration const& pc,
00015 ProcessHistoryID const& hist,
00016 boost::shared_ptr<BranchMapper> mapper,
00017 boost::shared_ptr<DelayedReader> rtrv) :
00018 Base(reg, pc, hist, mapper, rtrv),
00019 aux_(aux),
00020 luminosityBlockPrincipal_(),
00021 unscheduledHandler_(),
00022 moduleLabelsRunning_(),
00023 eventHistory_() {
00024 }
00025
00026 RunPrincipal const&
00027 EventPrincipal::runPrincipal() const {
00028 return luminosityBlockPrincipal().runPrincipal();
00029 }
00030
00031 RunPrincipal &
00032 EventPrincipal::runPrincipal() {
00033 return luminosityBlockPrincipal().runPrincipal();
00034 }
00035
00036 void
00037 EventPrincipal::addOnDemandGroup(ConstBranchDescription const& desc) {
00038 std::auto_ptr<Group> g(new Group(desc, true));
00039 addOrReplaceGroup(g);
00040 }
00041
00042 void
00043 EventPrincipal::addOrReplaceGroup(std::auto_ptr<Group> g) {
00044 Group const* group = getExistingGroup(*g);
00045 if (group != 0) {
00046 if(!group->onDemand()) {
00047 ConstBranchDescription const& bd = group->productDescription();
00048 throw edm::Exception(edm::errors::InsertFailure,"AlreadyPresent")
00049 << "addGroup_: Problem found while adding product provenance, "
00050 << "product already exists for ("
00051 << bd.friendlyClassName() << ","
00052 << bd.moduleLabel() << ","
00053 << bd.productInstanceName() << ","
00054 << bd.processName()
00055 << ")\n";
00056 }
00057 replaceGroup(g);
00058 } else {
00059 addGroup_(g);
00060 }
00061 }
00062
00063 void
00064 EventPrincipal::addGroup(ConstBranchDescription const& bd) {
00065 std::auto_ptr<Group> g(new Group(bd));
00066 addOrReplaceGroup(g);
00067 }
00068
00069 void
00070 EventPrincipal::addGroup(std::auto_ptr<EDProduct> prod,
00071 ConstBranchDescription const& bd,
00072 std::auto_ptr<EventEntryInfo> entryInfo) {
00073 std::auto_ptr<Group> g(new Group(prod, bd, entryInfo));
00074 addOrReplaceGroup(g);
00075 }
00076
00077 void
00078 EventPrincipal::addGroup(ConstBranchDescription const& bd,
00079 std::auto_ptr<EventEntryInfo> entryInfo) {
00080 std::auto_ptr<Group> g(new Group(bd, entryInfo));
00081 addOrReplaceGroup(g);
00082 }
00083
00084 void
00085 EventPrincipal::addGroup(std::auto_ptr<EDProduct> prod,
00086 ConstBranchDescription const& bd,
00087 boost::shared_ptr<EventEntryInfo> entryInfo) {
00088 std::auto_ptr<Group> g(new Group(prod, bd, entryInfo));
00089 addOrReplaceGroup(g);
00090 }
00091
00092 void
00093 EventPrincipal::addGroup(ConstBranchDescription const& bd,
00094 boost::shared_ptr<EventEntryInfo> entryInfo) {
00095 std::auto_ptr<Group> g(new Group(bd, entryInfo));
00096 addOrReplaceGroup(g);
00097 }
00098
00099 void
00100 EventPrincipal::put(std::auto_ptr<EDProduct> edp,
00101 ConstBranchDescription const& bd,
00102 std::auto_ptr<EventEntryInfo> entryInfo) {
00103
00104 if (edp.get() == 0) {
00105 throw edm::Exception(edm::errors::InsertFailure,"Null Pointer")
00106 << "put: Cannot put because auto_ptr to product is null."
00107 << "\n";
00108 }
00109 this->addToProcessHistory();
00110
00111 if (!entryInfo->productID().isValid()) {
00112 throw edm::Exception(edm::errors::InsertFailure,"Null Product ID")
00113 << "put: Cannot put product with null Product ID."
00114 << "\n";
00115 }
00116 branchMapperPtr()->insert(*entryInfo);
00117 this->addGroup(edp, bd, entryInfo);
00118 }
00119
00120 BasicHandle
00121 EventPrincipal::getByProductID(ProductID const& oid) const {
00122 BranchID bid = branchMapperPtr()->productToBranch(oid);
00123 SharedConstGroupPtr const& g = getGroup(bid, true, true, true);
00124 if (g.get() == 0) {
00125 if (!oid.isValid()) {
00126 throw edm::Exception(edm::errors::ProductNotFound,"InvalidID")
00127 << "get by product ID: invalid ProductID supplied\n";
00128 }
00129 boost::shared_ptr<cms::Exception> whyFailed( new edm::Exception(edm::errors::ProductNotFound,"InvalidID") );
00130 *whyFailed
00131 << "get by product ID: no product with given id: "<< oid << "\n";
00132 return BasicHandle(whyFailed);
00133 }
00134
00135
00136
00137 if (g->onDemand()) {
00138 boost::shared_ptr<cms::Exception> whyFailed( new edm::Exception(edm::errors::ProductNotFound,"InvalidID") );
00139 *whyFailed
00140 << "get by product ID: no product with given id: " << oid << "\n"
00141 << "onDemand production failed to produce it.\n";
00142 return BasicHandle(whyFailed);
00143 }
00144 return BasicHandle(g->product(), g->provenance());
00145 }
00146
00147 EDProduct const *
00148 EventPrincipal::getIt(ProductID const& oid) const {
00149 return getByProductID(oid).wrapper();
00150 }
00151
00152 Provenance
00153 EventPrincipal::getProvenance(BranchID const& bid) const {
00154 SharedConstGroupPtr const& g = getGroup(bid, false, true, true);
00155 if (g.get() == 0) {
00156 throw edm::Exception(edm::errors::ProductNotFound,"InvalidID")
00157 << "getProvenance: no product with given branch id: "<< bid << "\n";
00158 }
00159
00160 if (g->onDemand()) {
00161 unscheduledFill(g->productDescription().moduleLabel());
00162 }
00163
00164
00165 if (g->onDemand()) {
00166 throw edm::Exception(edm::errors::ProductNotFound)
00167 << "getProvenance: no product with given BranchID: "<< bid <<"\n";
00168 }
00169
00170 return *g->provenance();
00171 }
00172
00173 Provenance
00174 EventPrincipal::getProvenance(ProductID const& pid) const {
00175 BranchID bid = branchMapperPtr()->productToBranch(pid);
00176 return getProvenance(bid);
00177 }
00178
00179
00180
00181
00182 void
00183 EventPrincipal::getAllProvenance(std::vector<Provenance const*> & provenances) const {
00184 provenances.clear();
00185 for (Base::const_iterator i = begin(), iEnd = end(); i != iEnd; ++i) {
00186 if (i->second->provenanceAvailable()) {
00187 resolveProvenance(*i->second);
00188 if (i->second->provenance()->branchEntryInfoSharedPtr() &&
00189 i->second->provenance()->isPresent() &&
00190 i->second->provenance()->product().present())
00191 provenances.push_back(i->second->provenance());
00192 }
00193 }
00194 }
00195
00196 void
00197 EventPrincipal::resolveProvenance(Group const& g) const {
00198 if (!g.entryInfoPtr()) {
00199
00200 g.setProvenance(branchMapperPtr()->branchToEntryInfo(g.productDescription().branchID()));
00201 }
00202 }
00203
00204 void
00205 EventPrincipal::setUnscheduledHandler(boost::shared_ptr<UnscheduledHandler> iHandler) {
00206 unscheduledHandler_ = iHandler;
00207 }
00208
00209 EventSelectionIDVector const&
00210 EventPrincipal::eventSelectionIDs() const
00211 {
00212 return eventHistory_.eventSelectionIDs();
00213 }
00214
00215 History const&
00216 EventPrincipal::history() const
00217 {
00218 return eventHistory_;
00219 }
00220
00221 bool
00222 EventPrincipal::unscheduledFill(std::string const& moduleLabel) const {
00223
00224
00225
00226
00227
00228
00229 std::vector<std::string>::const_iterator i =
00230 find_in_all(moduleLabelsRunning_, moduleLabel);
00231
00232 if (i != moduleLabelsRunning_.end()) {
00233 throw edm::Exception(errors::LogicError)
00234 << "Hit circular dependency while trying to run an unscheduled module.\n"
00235 << "Current implementation of unscheduled execution cannot always determine\n"
00236 << "the proper order for module execution. It is also possible the modules\n"
00237 << "have a built in circular dependence that will not work with any order.\n"
00238 << "In the first case, scheduling some or all required modules in paths will help.\n"
00239 << "In the second case, the modules themselves will have to be fixed.\n";
00240 }
00241
00242 moduleLabelsRunning_.push_back(moduleLabel);
00243
00244 if (unscheduledHandler_) {
00245 unscheduledHandler_->tryToFill(moduleLabel, *const_cast<EventPrincipal *>(this));
00246 }
00247 moduleLabelsRunning_.pop_back();
00248 return true;
00249 }
00250
00251 void
00252 EventPrincipal::setHistory(History const& h) {
00253 eventHistory_ = h;
00254 }
00255 }