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