Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-07-19 01:43:48

0001 /*----------------------------------------------------------------------
0002 ----------------------------------------------------------------------*/
0003 
0004 #include <algorithm>
0005 
0006 #include "FWCore/Framework/interface/PrincipalGetAdapter.h"
0007 #include "DataFormats/Provenance/interface/ProductRegistry.h"
0008 #include "FWCore/Framework/interface/Principal.h"
0009 #include "FWCore/Utilities/interface/EDMException.h"
0010 #include "FWCore/Utilities/interface/ProductKindOfType.h"
0011 #include "FWCore/Utilities/interface/Likely.h"
0012 #include "DataFormats/Provenance/interface/ModuleDescription.h"
0013 #include "DataFormats/Provenance/interface/ProductResolverIndexHelper.h"
0014 #include "DataFormats/Common/interface/FunctorHandleExceptionFactory.h"
0015 #include "FWCore/Framework/interface/EDConsumerBase.h"
0016 #include "FWCore/Framework/interface/ProducerBase.h"
0017 
0018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0019 
0020 namespace edm {
0021 
0022   PrincipalGetAdapter::PrincipalGetAdapter(Principal const& pcpl, ModuleDescription const& md, bool isComplete)
0023       :  //putProducts_(),
0024         principal_(pcpl),
0025         md_(md),
0026         consumer_(nullptr),
0027         resourcesAcquirer_(nullptr),
0028         isComplete_(isComplete) {}
0029 
0030   PrincipalGetAdapter::~PrincipalGetAdapter() {}
0031 
0032   void principal_get_adapter_detail::throwOnPutOfNullProduct(char const* principalType,
0033                                                              TypeID const& productType,
0034                                                              std::string const& productInstanceName) {
0035     throw Exception(errors::NullPointerError)
0036         << principalType << "::put: A null unique_ptr was passed to 'put'.\n"
0037         << "The pointer is of type " << productType << ".\nThe specified productInstanceName was '"
0038         << productInstanceName << "'.\n";
0039   }
0040 
0041   void principal_get_adapter_detail::throwOnPutOfUninitializedToken(char const* principalType,
0042                                                                     std::type_info const& type) {
0043     TypeID productType{type};
0044     throw Exception(errors::LogicError) << principalType << "::put: An uninitialized EDPutToken was passed to 'put'.\n"
0045                                         << "The pointer is of type " << productType << ".\n";
0046   }
0047 
0048   void principal_get_adapter_detail::throwOnPutOfWrongType(std::type_info const& wrongType, TypeID const& rightType) {
0049     TypeID wrongTypeID{wrongType};
0050     throw Exception(errors::LogicError) << "The registered type for an EDPutToken does not match the put type.\n"
0051                                         << "The expected type " << rightType << "\nThe put type " << wrongTypeID
0052                                         << ".\n";
0053   }
0054 
0055   void principal_get_adapter_detail::throwOnPrematureRead(char const* principalType,
0056                                                           TypeID const& productType,
0057                                                           std::string const& moduleLabel,
0058                                                           std::string const& productInstanceName) {
0059     //throw Exception(errors::LogicError)
0060     LogWarning("LogicError") << "::getByLabel: An attempt was made to read a " << principalType << " product before end"
0061                              << principalType << "() was called.\n"
0062                              << "The product is of type '" << productType << "'.\nThe specified ModuleLabel was '"
0063                              << moduleLabel << "'.\nThe specified productInstanceName was '" << productInstanceName
0064                              << "'.\n";
0065   }
0066 
0067   void principal_get_adapter_detail::throwOnPrematureRead(char const* principalType, TypeID const& productType) {
0068     //throw Exception(errors::LogicError)
0069     LogWarning("LogicError") << "::getManyByType: An attempt was made to read a " << principalType
0070                              << " product before end" << principalType << "() was called.\n"
0071                              << "The product is of type '" << productType << "'.\n";
0072   }
0073 
0074   void principal_get_adapter_detail::throwOnPrematureRead(char const* principalType,
0075                                                           TypeID const& productType,
0076                                                           EDGetToken token) {
0077     throw Exception(errors::LogicError) << "::getByToken: An attempt was made to read a " << principalType
0078                                         << " product before end" << principalType << "() was called.\n"
0079                                         << "The index of the token was " << token.index() << ".\n";
0080   }
0081 
0082   size_t PrincipalGetAdapter::numberOfProductsConsumed() const { return consumer_->itemsToGetFrom(InEvent).size(); }
0083 
0084   void PrincipalGetAdapter::labelsForToken(EDGetToken const& iToken, ProductLabels& oLabels) const {
0085     consumer_->labelsForToken(iToken, oLabels);
0086   }
0087 
0088   unsigned int PrincipalGetAdapter::processBlockIndex(std::string const& processName) const {
0089     return principal_.processBlockIndex(processName);
0090   }
0091 
0092   BasicHandle PrincipalGetAdapter::makeFailToGetException(KindOfType kindOfType,
0093                                                           TypeID const& productType,
0094                                                           EDGetToken token) const {
0095     EDConsumerBase::Labels labels;
0096     consumer_->labelsForToken(token, labels);
0097     //no need to copy memory since the exception will no occur after the
0098     // const char* have been deleted
0099     return BasicHandle(
0100         makeHandleExceptionFactory([labels, kindOfType, productType]() -> std::shared_ptr<cms::Exception> {
0101           std::shared_ptr<cms::Exception> exception(std::make_shared<Exception>(errors::ProductNotFound));
0102           if (kindOfType == PRODUCT_TYPE) {
0103             *exception << "Principal::getByToken: Found zero products matching all criteria\nLooking for type: "
0104                        << productType << "\n"
0105                        << "Looking for module label: " << labels.module << "\n"
0106                        << "Looking for productInstanceName: " << labels.productInstance << "\n"
0107                        << (0 == labels.process[0] ? "" : "Looking for process: ") << labels.process << "\n";
0108           } else {
0109             *exception << "Principal::getByToken: Found zero products matching all criteria\nLooking for a container "
0110                           "with elements of type: "
0111                        << productType << "\n"
0112                        << "Looking for module label: " << labels.module << "\n"
0113                        << "Looking for productInstanceName: " << labels.productInstance << "\n"
0114                        << (0 == labels.process[0] ? "" : "Looking for process: ") << labels.process << "\n";
0115           }
0116           return exception;
0117         }));
0118   }
0119 
0120   void PrincipalGetAdapter::throwAmbiguousException(TypeID const& productType, EDGetToken token) const {
0121     EDConsumerBase::Labels labels;
0122     consumer_->labelsForToken(token, labels);
0123     cms::Exception exception("AmbiguousProduct");
0124     exception << "Principal::getByToken: More than 1 product matches all criteria\nLooking for a container with "
0125                  "elements of type: "
0126               << productType << "\n"
0127               << "Looking for module label: " << labels.module << "\n"
0128               << "Looking for productInstanceName: " << labels.productInstance << "\n"
0129               << (0 == labels.process[0] ? "" : "Looking for process: ") << labels.process << "\n"
0130               << "This can only occur with get function calls using a Handle<View> argument.\n"
0131               << "Try a get not using a View or change the instance name of one of the products";
0132     throw exception;
0133   }
0134 
0135   BranchType const& PrincipalGetAdapter::branchType() const { return principal_.branchType(); }
0136 
0137   BasicHandle PrincipalGetAdapter::getByLabel_(TypeID const& typeID,
0138                                                InputTag const& tag,
0139                                                ModuleCallingContext const* mcc) const {
0140     return principal_.getByLabel(PRODUCT_TYPE, typeID, tag, consumer_, resourcesAcquirer_, mcc);
0141   }
0142 
0143   BasicHandle PrincipalGetAdapter::getByLabel_(TypeID const& typeID,
0144                                                std::string const& label,
0145                                                std::string const& instance,
0146                                                std::string const& process,
0147                                                ModuleCallingContext const* mcc) const {
0148     return principal_.getByLabel(PRODUCT_TYPE, typeID, label, instance, process, consumer_, resourcesAcquirer_, mcc);
0149   }
0150 
0151   BasicHandle PrincipalGetAdapter::getByToken_(TypeID const& id,
0152                                                KindOfType kindOfType,
0153                                                EDGetToken token,
0154                                                ModuleCallingContext const* mcc) const {
0155     ProductResolverIndexAndSkipBit indexAndBit = consumer_->indexFrom(token, branchType(), id);
0156     ProductResolverIndex index = indexAndBit.productResolverIndex();
0157     bool skipCurrentProcess = indexAndBit.skipCurrentProcess();
0158     if (UNLIKELY(index == ProductResolverIndexInvalid)) {
0159       return makeFailToGetException(kindOfType, id, token);
0160     } else if (UNLIKELY(index == ProductResolverIndexAmbiguous)) {
0161       // This deals with ambiguities where the process is specified
0162       throwAmbiguousException(id, token);
0163     }
0164     bool ambiguous = false;
0165     BasicHandle h =
0166         principal_.getByToken(kindOfType, id, index, skipCurrentProcess, ambiguous, resourcesAcquirer_, mcc);
0167     if (ambiguous) {
0168       // This deals with ambiguities where the process is not specified
0169       throwAmbiguousException(id, token);
0170     } else if (!h.isValid()) {
0171       return makeFailToGetException(kindOfType, id, token);
0172     }
0173     return h;
0174   }
0175 
0176   BasicHandle PrincipalGetAdapter::getMatchingSequenceByLabel_(TypeID const& typeID,
0177                                                                InputTag const& tag,
0178                                                                ModuleCallingContext const* mcc) const {
0179     return principal_.getByLabel(ELEMENT_TYPE, typeID, tag, consumer_, resourcesAcquirer_, mcc);
0180   }
0181 
0182   BasicHandle PrincipalGetAdapter::getMatchingSequenceByLabel_(TypeID const& typeID,
0183                                                                std::string const& label,
0184                                                                std::string const& instance,
0185                                                                std::string const& process,
0186                                                                ModuleCallingContext const* mcc) const {
0187     auto h = principal_.getByLabel(ELEMENT_TYPE, typeID, label, instance, process, consumer_, resourcesAcquirer_, mcc);
0188     return h;
0189   }
0190 
0191   void PrincipalGetAdapter::getManyByType_(TypeID const& tid,
0192                                            BasicHandleVec& results,
0193                                            ModuleCallingContext const* mcc) const {
0194     principal_.getManyByType(tid, results, consumer_, resourcesAcquirer_, mcc);
0195   }
0196 
0197   ProcessHistory const& PrincipalGetAdapter::processHistory() const { return principal_.processHistory(); }
0198 
0199   void PrincipalGetAdapter::throwUnregisteredPutException(TypeID const& type,
0200                                                           std::string const& productInstanceName) const {
0201     std::ostringstream str;
0202     for (auto branchDescription : principal_.productRegistry().allBranchDescriptions()) {
0203       if (branchDescription->moduleLabel() == md_.moduleLabel() and
0204           branchDescription->processName() == md_.processName()) {
0205         str << *branchDescription << "-----\n";
0206       }
0207     }
0208     throw edm::Exception(edm::errors::InsertFailure)
0209         << "Illegal attempt to 'put' an unregistered product.\n"
0210         << "No product is registered for\n"
0211         << "  product friendly class name: '" << type.friendlyClassName() << "'\n"
0212         << "  module label:                '" << md_.moduleLabel() << "'\n"
0213         << "  product instance name:       '" << productInstanceName << "'\n"
0214         << "  process name:                '" << md_.processName() << "'\n"
0215 
0216         << "The following data products are registered for production by " << md_.moduleLabel() << ":\n"
0217         << str.str() << '\n'
0218         << "To correct the problem:\n"
0219            "   1) make sure the proper 'produce' call is being made in the module's constructor,\n"
0220            "   2) if 'produce' exists and uses a product instance name make sure that same name is used during the "
0221            "'put' call.";
0222   }
0223 
0224   BranchDescription const& PrincipalGetAdapter::getBranchDescription(TypeID const& type,
0225                                                                      std::string const& productInstanceName) const {
0226     ProductResolverIndexHelper const& productResolverIndexHelper = principal_.productLookup();
0227     ProductResolverIndex index = productResolverIndexHelper.index(
0228         PRODUCT_TYPE, type, md_.moduleLabel().c_str(), productInstanceName.c_str(), md_.processName().c_str());
0229     if (UNLIKELY(index == ProductResolverIndexInvalid)) {
0230       throwUnregisteredPutException(type, productInstanceName);
0231     }
0232     ProductResolverBase const* phb = principal_.getProductResolverByIndex(index);
0233     assert(phb != nullptr);
0234     return phb->branchDescription();
0235   }
0236 
0237   BranchDescription const& PrincipalGetAdapter::getBranchDescription(unsigned int iPutTokenIndex) const {
0238     auto index = prodBase_->putTokenIndexToProductResolverIndex()[iPutTokenIndex];
0239     ProductResolverBase const* phb = principal_.getProductResolverByIndex(index);
0240     assert(phb != nullptr);
0241     return phb->branchDescription();
0242   }
0243 
0244   ProductID const& PrincipalGetAdapter::getProductID(unsigned int iPutTokenIndex) const {
0245     auto index = prodBase_->putTokenIndexToProductResolverIndex()[iPutTokenIndex];
0246     ProductResolverBase const* phb = principal_.getProductResolverByIndex(index);
0247     assert(phb != nullptr);
0248     auto prov = phb->stableProvenance();
0249     assert(prov != nullptr);
0250     return prov->productID();
0251   }
0252 
0253   Transition PrincipalGetAdapter::transition() const {
0254     if (LIKELY(principal().branchType() == InEvent)) {
0255       return Transition::Event;
0256     }
0257     if (principal().branchType() == InRun) {
0258       if (isComplete()) {
0259         return Transition::EndRun;
0260       } else {
0261         return Transition::BeginRun;
0262       }
0263     }
0264     if (isComplete()) {
0265       return Transition::EndLuminosityBlock;
0266     }
0267     return Transition::BeginLuminosityBlock;
0268     //Must be lumi
0269   }
0270 
0271   EDPutToken::value_type PrincipalGetAdapter::getPutTokenIndex(TypeID const& type,
0272                                                                std::string const& productInstanceName) const {
0273     auto tran = transition();
0274     size_t index = 0;
0275     for (auto const& tl : prodBase_->typeLabelList()) {
0276       if ((tran == tl.transition_) and (type == tl.typeID_) and (productInstanceName == tl.productInstanceName_)) {
0277         return index;
0278       }
0279       ++index;
0280     }
0281     throwUnregisteredPutException(type, productInstanceName);
0282     return std::numeric_limits<unsigned int>::max();
0283   }
0284 
0285   std::string const& PrincipalGetAdapter::productInstanceLabel(EDPutToken iToken) const {
0286     return prodBase_->typeLabelList()[iToken.index()].productInstanceName_;
0287   }
0288 
0289   TypeID const& PrincipalGetAdapter::getTypeIDForPutTokenIndex(EDPutToken::value_type index) const {
0290     return prodBase_->typeLabelList()[index].typeID_;
0291   }
0292 
0293   std::vector<edm::ProductResolverIndex> const& PrincipalGetAdapter::putTokenIndexToProductResolverIndex() const {
0294     return prodBase_->putTokenIndexToProductResolverIndex();
0295   }
0296 
0297   std::vector<bool> const& PrincipalGetAdapter::recordProvenanceList() const {
0298     return prodBase_->recordProvenanceList();
0299   }
0300 
0301   EDProductGetter const* PrincipalGetAdapter::prodGetter() const { return principal_.prodGetter(); }
0302 }  // namespace edm