Back to home page

Project CMSSW displayed by LXR

 
 

    


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     //do not clear luminosityBlockPrincipal_ since
0065     // it is only connected at beginLumi transition
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         // Add index into BranchIDListRegistry for products produced this process
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         // Add index into BranchIDListRegistry for products produced this process
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       // Add index into BranchIDListRegistry for products produced this process
0116       //  if it hasn't already been filled in by the other fillEventPrincipal or by an earlier call to this function
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     //fromInput does not contain entries for what is being produced in this job.
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     // Fill in helper map for Branch to ProductID mapping
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     // Fill in the product ID's in the product holders.
0162     for (auto& prod : *this) {
0163       if (prod->singleProduct()) {
0164         // If an alias is in the same process as the original then isAlias will be true.
0165         //  Under that condition, we want the ProductID to be the same as the original.
0166         //  If not, then we've internally changed the original BranchID to the alias BranchID
0167         //  in the ProductID lookup so we need the alias BranchID.
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     // assert commented out for DaqSource.  When DaqSource no longer uses put(), the assert can be restored.
0190     //assert(produced());
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     // ProductResolver assumes ownership
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     // ProductResolver assumes ownership
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     // ProductResolver assumes ownership
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     // cannot throw, because some products may legitimately not have product ID's (e.g. pile-up).
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     // Was this already deleted?
0291     if (phb->productWasDeleted()) {
0292       throwProductDeletedException(pid, phb);
0293     }
0294     // Check for case where we tried on demand production and
0295     // it failed to produce the object
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 }  // namespace edm