File indexing completed on 2022-01-24 01:11:35
0001 #include "FWCore/Framework/interface/EventPrincipal.h"
0002
0003 #include "DataFormats/Common/interface/BasicHandle.h"
0004 #include "DataFormats/Common/interface/FunctorHandleExceptionFactory.h"
0005 #include "DataFormats/Common/interface/ThinnedAssociation.h"
0006 #include "DataFormats/Common/interface/Wrapper.h"
0007 #include "DataFormats/Common/interface/getThinned_implementation.h"
0008 #include "DataFormats/Provenance/interface/BranchIDList.h"
0009 #include "DataFormats/Provenance/interface/BranchIDListHelper.h"
0010 #include "DataFormats/Provenance/interface/BranchListIndex.h"
0011 #include "DataFormats/Provenance/interface/RunLumiEventNumber.h"
0012 #include "DataFormats/Provenance/interface/ProductIDToBranchID.h"
0013 #include "DataFormats/Provenance/interface/ProductRegistry.h"
0014 #include "DataFormats/Provenance/interface/Provenance.h"
0015 #include "DataFormats/Provenance/interface/ThinnedAssociationsHelper.h"
0016 #include "FWCore/Common/interface/ProcessBlockHelperBase.h"
0017 #include "FWCore/Framework/interface/DelayedReader.h"
0018 #include "FWCore/Framework/interface/ProductResolverBase.h"
0019 #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h"
0020 #include "FWCore/Framework/src/ProductDeletedException.h"
0021 #include "FWCore/Framework/interface/ProductPutterBase.h"
0022 #include "FWCore/Framework/interface/SharedResourcesAcquirer.h"
0023 #include "FWCore/Utilities/interface/Algorithms.h"
0024 #include "FWCore/Utilities/interface/EDMException.h"
0025 #include "FWCore/ServiceRegistry/interface/ModuleCallingContext.h"
0026
0027 #include <algorithm>
0028 #include <cassert>
0029 #include <limits>
0030 #include <memory>
0031
0032 namespace edm {
0033 EventPrincipal::EventPrincipal(std::shared_ptr<ProductRegistry const> reg,
0034 std::shared_ptr<BranchIDListHelper const> branchIDListHelper,
0035 std::shared_ptr<ThinnedAssociationsHelper const> thinnedAssociationsHelper,
0036 ProcessConfiguration const& pc,
0037 HistoryAppender* historyAppender,
0038 unsigned int streamIndex,
0039 bool isForPrimaryProcess,
0040 ProcessBlockHelperBase const* processBlockHelper)
0041 : Base(reg, reg->productLookup(InEvent), pc, InEvent, historyAppender, isForPrimaryProcess),
0042 aux_(),
0043 luminosityBlockPrincipal_(nullptr),
0044 provRetrieverPtr_(new ProductProvenanceRetriever(streamIndex, *reg)),
0045 eventSelectionIDs_(),
0046 branchIDListHelper_(branchIDListHelper),
0047 processBlockHelper_(processBlockHelper),
0048 thinnedAssociationsHelper_(thinnedAssociationsHelper),
0049 branchListIndexes_(),
0050 branchListIndexToProcessIndex_(),
0051 streamID_(streamIndex) {
0052 assert(thinnedAssociationsHelper_);
0053
0054 for (auto& prod : *this) {
0055 if (prod->singleProduct()) {
0056 prod->setProductProvenanceRetriever(productProvenanceRetrieverPtr());
0057 }
0058 }
0059 }
0060
0061 void EventPrincipal::clearEventPrincipal() {
0062 clearPrincipal();
0063 aux_ = EventAuxiliary();
0064
0065
0066 provRetrieverPtr_->reset();
0067 }
0068
0069 void EventPrincipal::fillEventPrincipal(EventAuxiliary const& aux,
0070 ProcessHistory const* processHistory,
0071 EventSelectionIDVector eventSelectionIDs,
0072 BranchListIndexes branchListIndexes,
0073 EventToProcessBlockIndexes const& eventToProcessBlockIndexes,
0074 ProductProvenanceRetriever const& provRetriever,
0075 DelayedReader* reader,
0076 bool deepCopyRetriever) {
0077 eventSelectionIDs_ = std::move(eventSelectionIDs);
0078 if (deepCopyRetriever) {
0079 provRetrieverPtr_->deepCopy(provRetriever);
0080 } else {
0081 provRetrieverPtr_->mergeParentProcessRetriever(provRetriever);
0082 }
0083 if (wasBranchListIndexesChangedFromInput(branchListIndexes)) {
0084 if (branchIDListHelper_->hasProducedProducts()) {
0085
0086 branchListIndexes.push_back(branchIDListHelper_->producedBranchListIndex());
0087 }
0088 updateBranchListIndexes(std::move(branchListIndexes));
0089 }
0090 eventToProcessBlockIndexes_ = eventToProcessBlockIndexes;
0091 commonFillEventPrincipal(aux, processHistory, reader);
0092 }
0093
0094 void EventPrincipal::fillEventPrincipal(EventAuxiliary const& aux,
0095 ProcessHistory const* processHistory,
0096 EventSelectionIDVector eventSelectionIDs,
0097 BranchListIndexes branchListIndexes,
0098 DelayedReader* reader) {
0099 eventSelectionIDs_ = std::move(eventSelectionIDs);
0100
0101 if (wasBranchListIndexesChangedFromInput(branchListIndexes)) {
0102 if (branchIDListHelper_->hasProducedProducts()) {
0103
0104 branchListIndexes.push_back(branchIDListHelper_->producedBranchListIndex());
0105 }
0106 updateBranchListIndexes(std::move(branchListIndexes));
0107 }
0108 commonFillEventPrincipal(aux, processHistory, reader);
0109 }
0110
0111 void EventPrincipal::fillEventPrincipal(EventAuxiliary const& aux,
0112 ProcessHistory const* processHistory,
0113 DelayedReader* reader) {
0114 if (branchListIndexes_.empty() and branchIDListHelper_->hasProducedProducts()) {
0115
0116
0117 BranchListIndexes indexes;
0118 indexes.push_back(branchIDListHelper_->producedBranchListIndex());
0119 updateBranchListIndexes(std::move(indexes));
0120 }
0121 commonFillEventPrincipal(aux, processHistory, reader);
0122 }
0123
0124 void EventPrincipal::commonFillEventPrincipal(EventAuxiliary const& aux,
0125 ProcessHistory const* processHistory,
0126 DelayedReader* reader) {
0127 if (aux.event() == invalidEventNumber) {
0128 throw Exception(errors::LogicError) << "EventPrincipal::fillEventPrincipal, Invalid event number provided in "
0129 "EventAuxiliary, It is illegal for the event number to be 0\n";
0130 }
0131
0132 fillPrincipal(aux.processHistoryID(), processHistory, reader);
0133 aux_ = aux;
0134 aux_.setProcessHistoryID(processHistoryID());
0135 }
0136
0137 bool EventPrincipal::wasBranchListIndexesChangedFromInput(BranchListIndexes const& fromInput) const {
0138
0139 auto end = branchListIndexes_.end();
0140 if (end != branchListIndexes_.begin() and branchIDListHelper_->hasProducedProducts()) {
0141 --end;
0142 }
0143
0144 return not std::equal(fromInput.begin(), fromInput.end(), branchListIndexes_.begin(), end);
0145 }
0146
0147 void EventPrincipal::updateBranchListIndexes(BranchListIndexes&& branchListIndexes) {
0148 branchListIndexes_ = std::move(branchListIndexes);
0149 branchListIndexToProcessIndex_.clear();
0150
0151 if (not branchListIndexes_.empty()) {
0152 ProcessIndex pix = 0;
0153 branchListIndexToProcessIndex_.resize(1 + *std::max_element(branchListIndexes_.begin(), branchListIndexes_.end()),
0154 std::numeric_limits<BranchListIndex>::max());
0155 for (auto const& blindex : branchListIndexes_) {
0156 branchListIndexToProcessIndex_[blindex] = pix;
0157 ++pix;
0158 }
0159 }
0160
0161
0162 for (auto& prod : *this) {
0163 if (prod->singleProduct()) {
0164
0165
0166
0167
0168
0169 auto const& bd = prod->branchDescription();
0170 prod->setProductID(branchIDToProductID(bd.isAlias() ? bd.originalBranchID() : bd.branchID()));
0171 }
0172 }
0173 }
0174
0175 void EventPrincipal::setLuminosityBlockPrincipal(LuminosityBlockPrincipal* lbp) { luminosityBlockPrincipal_ = lbp; }
0176
0177 void EventPrincipal::setRunAndLumiNumber(RunNumber_t run, LuminosityBlockNumber_t lumi) {
0178 assert(run == luminosityBlockPrincipal_->run());
0179 assert(lumi == luminosityBlockPrincipal_->luminosityBlock());
0180 EventNumber_t event = aux_.id().event();
0181 aux_.id() = EventID(run, lumi, event);
0182 }
0183
0184 RunPrincipal const& EventPrincipal::runPrincipal() const { return luminosityBlockPrincipal().runPrincipal(); }
0185
0186 void EventPrincipal::put(BranchDescription const& bd,
0187 std::unique_ptr<WrapperBase> edp,
0188 ProductProvenance const& productProvenance) const {
0189
0190
0191 if (edp.get() == nullptr) {
0192 throw Exception(errors::InsertFailure, "Null Pointer") << "put: Cannot put because ptr to product is null."
0193 << "\n";
0194 }
0195 productProvenanceRetrieverPtr()->insertIntoSet(productProvenance);
0196 auto phb = getExistingProduct(bd.branchID());
0197 assert(phb);
0198
0199 dynamic_cast<ProductPutterBase const*>(phb)->putProduct(std::move(edp));
0200 }
0201
0202 void EventPrincipal::put(ProductResolverIndex index, std::unique_ptr<WrapperBase> edp, ParentageID parentage) const {
0203 if (edp.get() == nullptr) {
0204 throw Exception(errors::InsertFailure, "Null Pointer") << "put: Cannot put because ptr to product is null."
0205 << "\n";
0206 }
0207 auto phb = getProductResolverByIndex(index);
0208
0209 productProvenanceRetrieverPtr()->insertIntoSet(
0210 ProductProvenance(phb->branchDescription().branchID(), std::move(parentage)));
0211
0212 assert(phb);
0213
0214 dynamic_cast<ProductPutterBase const*>(phb)->putProduct(std::move(edp));
0215 }
0216
0217 void EventPrincipal::putOnRead(BranchDescription const& bd,
0218 std::unique_ptr<WrapperBase> edp,
0219 std::optional<ProductProvenance> productProvenance) const {
0220 assert(!bd.produced());
0221 if (productProvenance) {
0222 productProvenanceRetrieverPtr()->insertIntoSet(std::move(*productProvenance));
0223 }
0224 auto phb = getExistingProduct(bd.branchID());
0225 assert(phb);
0226
0227 dynamic_cast<ProductPutterBase const*>(phb)->putProduct(std::move(edp));
0228 }
0229
0230 BranchID EventPrincipal::pidToBid(ProductID const& pid) const {
0231 if (!pid.isValid()) {
0232 throw Exception(errors::ProductNotFound, "InvalidID") << "get by product ID: invalid ProductID supplied\n";
0233 }
0234 return productIDToBranchID(pid, branchIDListHelper_->branchIDLists(), branchListIndexes_);
0235 }
0236
0237 ProductID EventPrincipal::branchIDToProductID(BranchID const& bid) const {
0238 if (!bid.isValid()) {
0239 throw Exception(errors::NotFound, "InvalidID") << "branchIDToProductID: invalid BranchID supplied\n";
0240 }
0241 typedef BranchIDListHelper::BranchIDToIndexMap BIDToIndexMap;
0242 typedef BIDToIndexMap::const_iterator Iter;
0243 typedef std::pair<Iter, Iter> IndexRange;
0244
0245 IndexRange range = branchIDListHelper_->branchIDToIndexMap().equal_range(bid);
0246 for (Iter it = range.first; it != range.second; ++it) {
0247 BranchListIndex blix = it->second.first;
0248 if (blix < branchListIndexToProcessIndex_.size()) {
0249 auto v = branchListIndexToProcessIndex_[blix];
0250 if (v != std::numeric_limits<BranchListIndex>::max()) {
0251 ProductIndex productIndex = it->second.second;
0252 ProcessIndex processIndex = v;
0253 return ProductID(processIndex + 1, productIndex + 1);
0254 }
0255 }
0256 }
0257
0258 return ProductID();
0259 }
0260
0261 unsigned int EventPrincipal::processBlockIndex(std::string const& processName) const {
0262 return processBlockHelper_->processBlockIndex(processName, eventToProcessBlockIndexes_);
0263 }
0264
0265 unsigned int EventPrincipal::transitionIndex_() const { return streamID_.value(); }
0266
0267 void EventPrincipal::changedIndexes_() { provRetrieverPtr_->update(productRegistry()); }
0268
0269 static void throwProductDeletedException(ProductID const& pid,
0270 edm::EventPrincipal::ConstProductResolverPtr const phb) {
0271 ProductDeletedException exception;
0272 exception << "get by product ID: The product with given id: " << pid << "\ntype: " << phb->productType()
0273 << "\nproduct instance name: " << phb->productInstanceName() << "\nprocess name: " << phb->processName()
0274 << "\nwas already deleted. This is a configuration error. Please change the configuration of the module "
0275 "which caused this exception to state it reads this data.";
0276 throw exception;
0277 }
0278
0279 BasicHandle EventPrincipal::getByProductID(ProductID const& pid) const {
0280 BranchID bid = pidToBid(pid);
0281 ConstProductResolverPtr const phb = getProductResolver(bid);
0282 if (phb == nullptr) {
0283 return BasicHandle(makeHandleExceptionFactory([pid]() -> std::shared_ptr<cms::Exception> {
0284 std::shared_ptr<cms::Exception> whyFailed(std::make_shared<Exception>(errors::ProductNotFound, "InvalidID"));
0285 *whyFailed << "get by product ID: no product with given id: " << pid << "\n";
0286 return whyFailed;
0287 }));
0288 }
0289
0290
0291 if (phb->productWasDeleted()) {
0292 throwProductDeletedException(pid, phb);
0293 }
0294
0295
0296 if (phb->unscheduledWasNotRun()) {
0297 return BasicHandle(makeHandleExceptionFactory([pid]() -> std::shared_ptr<cms::Exception> {
0298 std::shared_ptr<cms::Exception> whyFailed(std::make_shared<Exception>(errors::ProductNotFound, "InvalidID"));
0299 *whyFailed << "get by ProductID: could not get product with id: " << pid << "\n"
0300 << "Unscheduled execution not allowed to get via ProductID.\n";
0301 return whyFailed;
0302 }));
0303 }
0304 auto resolution = phb->resolveProduct(*this, false, nullptr, nullptr);
0305
0306 auto data = resolution.data();
0307 if (data) {
0308 return BasicHandle(data->wrapper(), &(data->provenance()));
0309 }
0310 return BasicHandle(nullptr, nullptr);
0311 }
0312
0313 WrapperBase const* EventPrincipal::getIt(ProductID const& pid) const { return getByProductID(pid).wrapper(); }
0314
0315 std::optional<std::tuple<WrapperBase const*, unsigned int>> EventPrincipal::getThinnedProduct(
0316 ProductID const& pid, unsigned int key) const {
0317 return detail::getThinnedProduct(
0318 pid,
0319 key,
0320 *thinnedAssociationsHelper_,
0321 [this](ProductID const& p) { return pidToBid(p); },
0322 [this](BranchID const& b) { return getThinnedAssociation(b); },
0323 [this](ProductID const& p) { return getIt(p); });
0324 }
0325
0326 void EventPrincipal::getThinnedProducts(ProductID const& pid,
0327 std::vector<WrapperBase const*>& foundContainers,
0328 std::vector<unsigned int>& keys) const {
0329 detail::getThinnedProducts(
0330 pid,
0331 *thinnedAssociationsHelper_,
0332 [this](ProductID const& p) { return pidToBid(p); },
0333 [this](BranchID const& b) { return getThinnedAssociation(b); },
0334 [this](ProductID const& p) { return getIt(p); },
0335 foundContainers,
0336 keys);
0337 }
0338
0339 OptionalThinnedKey EventPrincipal::getThinnedKeyFrom(ProductID const& parentID,
0340 unsigned int key,
0341 ProductID const& thinnedID) const {
0342 BranchID parent = pidToBid(parentID);
0343 BranchID thinned = pidToBid(thinnedID);
0344
0345 try {
0346 auto ret = detail::getThinnedKeyFrom_implementation(
0347 parentID, parent, key, thinnedID, thinned, *thinnedAssociationsHelper_, [this](BranchID const& branchID) {
0348 return getThinnedAssociation(branchID);
0349 });
0350 if (auto factory = std::get_if<detail::GetThinnedKeyFromExceptionFactory>(&ret)) {
0351 return [func = *factory]() {
0352 auto ex = func();
0353 ex.addContext("Calling EventPrincipal::getThinnedKeyFrom()");
0354 return ex;
0355 };
0356 } else {
0357 return ret;
0358 }
0359 } catch (Exception& ex) {
0360 ex.addContext("Calling EventPrincipal::getThinnedKeyFrom()");
0361 throw ex;
0362 }
0363 }
0364
0365 Provenance const& EventPrincipal::getProvenance(ProductID const& pid) const {
0366 BranchID bid = pidToBid(pid);
0367 return getProvenance(bid);
0368 }
0369
0370 StableProvenance const& EventPrincipal::getStableProvenance(ProductID const& pid) const {
0371 BranchID bid = pidToBid(pid);
0372 return getStableProvenance(bid);
0373 }
0374
0375 EventSelectionIDVector const& EventPrincipal::eventSelectionIDs() const { return eventSelectionIDs_; }
0376
0377 BranchListIndexes const& EventPrincipal::branchListIndexes() const { return branchListIndexes_; }
0378
0379 EventToProcessBlockIndexes const& EventPrincipal::eventToProcessBlockIndexes() const {
0380 return eventToProcessBlockIndexes_;
0381 }
0382
0383 edm::ThinnedAssociation const* EventPrincipal::getThinnedAssociation(edm::BranchID const& branchID) const {
0384 ConstProductResolverPtr const phb = getProductResolver(branchID);
0385
0386 if (phb == nullptr) {
0387 throw Exception(errors::LogicError)
0388 << "EventPrincipal::getThinnedAssociation, ThinnedAssociation ProductResolver cannot be found\n"
0389 << "This should never happen. Contact a Framework developer";
0390 }
0391 ProductData const* productData = (phb->resolveProduct(*this, false, nullptr, nullptr)).data();
0392 if (productData == nullptr) {
0393 return nullptr;
0394 }
0395 WrapperBase const* product = productData->wrapper();
0396 if (!(typeid(edm::ThinnedAssociation) == product->dynamicTypeInfo())) {
0397 throw Exception(errors::LogicError)
0398 << "EventPrincipal::getThinnedProduct, product has wrong type, not a ThinnedAssociation.\n";
0399 }
0400 Wrapper<ThinnedAssociation> const* wrapper = static_cast<Wrapper<ThinnedAssociation> const*>(product);
0401 return wrapper->product();
0402 }
0403
0404 }