Back to home page

Project CMSSW displayed by LXR

 
 

    


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     //do not clear luminosityBlockPrincipal_ since
0066     // it is only connected at beginLumi transition
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         // Add index into BranchIDListRegistry for products produced this process
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         // Add index into BranchIDListRegistry for products produced this process
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       // Add index into BranchIDListRegistry for products produced this process
0117       //  if it hasn't already been filled in by the other fillEventPrincipal or by an earlier call to this function
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     //fromInput does not contain entries for what is being produced in this job.
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     // Fill in helper map for Branch to ProductID mapping
0152     if (not branchListIndexes_.empty()) {
0153       branchListIndexToProcessIndex_ = makeBranchListIndexToProcessIndex(branchListIndexes_);
0154     }
0155 
0156     // Fill in the product ID's in the product holders.
0157     for (auto& prod : *this) {
0158       if (prod->singleProduct()) {
0159         // If an alias is in the same process as the original then isAlias will be true.
0160         //  Under that condition, we want the ProductID to be the same as the original.
0161         //  If not, then we've internally changed the original BranchID to the alias BranchID
0162         //  in the ProductID lookup so we need the alias BranchID.
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     // assert commented out for DaqSource.  When DaqSource no longer uses put(), the assert can be restored.
0185     //assert(produced());
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     // ProductResolver assumes ownership
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     // ProductResolver assumes ownership
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     // ProductResolver assumes ownership
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     //If new Retrievers were added, we need to pass the provenance retriever
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     // Was this already deleted?
0273     if (phb->productWasDeleted()) {
0274       throwProductDeletedException(pid, phb);
0275     }
0276     // Check for case where we tried on demand production and
0277     // it failed to produce the object
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 }  // namespace edm