Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:12:13

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,
0068                                                           TypeID const& productType,
0069                                                           EDGetToken token) {
0070     throw Exception(errors::LogicError) << "::getByToken: An attempt was made to read a " << principalType
0071                                         << " product before end" << principalType << "() was called.\n"
0072                                         << "The index of the token was " << token.index() << ".\n";
0073   }
0074 
0075   size_t PrincipalGetAdapter::numberOfProductsConsumed() const { return consumer_->itemsToGetFrom(InEvent).size(); }
0076 
0077   void PrincipalGetAdapter::labelsForToken(EDGetToken const& iToken, ProductLabels& oLabels) const {
0078     consumer_->labelsForToken(iToken, oLabels);
0079   }
0080 
0081   unsigned int PrincipalGetAdapter::processBlockIndex(std::string const& processName) const {
0082     return principal_.processBlockIndex(processName);
0083   }
0084 
0085   BasicHandle PrincipalGetAdapter::makeFailToGetException(KindOfType kindOfType,
0086                                                           TypeID const& productType,
0087                                                           EDGetToken token) const {
0088     EDConsumerBase::Labels labels;
0089     consumer_->labelsForToken(token, labels);
0090     //no need to copy memory since the exception will no occur after the
0091     // const char* have been deleted
0092     return BasicHandle(
0093         makeHandleExceptionFactory([labels, kindOfType, productType]() -> std::shared_ptr<cms::Exception> {
0094           std::shared_ptr<cms::Exception> exception(std::make_shared<Exception>(errors::ProductNotFound));
0095           if (kindOfType == PRODUCT_TYPE) {
0096             *exception << "Principal::getByToken: Found zero products matching all criteria\nLooking for type: "
0097                        << productType << "\n"
0098                        << "Looking for module label: " << labels.module << "\n"
0099                        << "Looking for productInstanceName: " << labels.productInstance << "\n"
0100                        << (0 == labels.process[0] ? "" : "Looking for process: ") << labels.process << "\n";
0101           } else {
0102             *exception << "Principal::getByToken: Found zero products matching all criteria\nLooking for a container "
0103                           "with elements of 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           }
0109           return exception;
0110         }));
0111   }
0112 
0113   void PrincipalGetAdapter::throwAmbiguousException(TypeID const& productType, EDGetToken token) const {
0114     EDConsumerBase::Labels labels;
0115     consumer_->labelsForToken(token, labels);
0116     cms::Exception exception("AmbiguousProduct");
0117     exception << "Principal::getByToken: More than 1 product matches all criteria\nLooking for a container with "
0118                  "elements of type: "
0119               << productType << "\n"
0120               << "Looking for module label: " << labels.module << "\n"
0121               << "Looking for productInstanceName: " << labels.productInstance << "\n"
0122               << (0 == labels.process[0] ? "" : "Looking for process: ") << labels.process << "\n"
0123               << "This can only occur with get function calls using a Handle<View> argument.\n"
0124               << "Try a get not using a View or change the instance name of one of the products";
0125     throw exception;
0126   }
0127 
0128   BranchType const& PrincipalGetAdapter::branchType() const { return principal_.branchType(); }
0129 
0130   BasicHandle PrincipalGetAdapter::getByLabel_(TypeID const& typeID,
0131                                                InputTag const& tag,
0132                                                ModuleCallingContext const* mcc) const {
0133     return principal_.getByLabel(PRODUCT_TYPE, typeID, tag, consumer_, resourcesAcquirer_, mcc);
0134   }
0135 
0136   BasicHandle PrincipalGetAdapter::getByLabel_(TypeID const& typeID,
0137                                                std::string const& label,
0138                                                std::string const& instance,
0139                                                std::string const& process,
0140                                                ModuleCallingContext const* mcc) const {
0141     return principal_.getByLabel(PRODUCT_TYPE, typeID, label, instance, process, consumer_, resourcesAcquirer_, mcc);
0142   }
0143 
0144   BasicHandle PrincipalGetAdapter::getByToken_(TypeID const& id,
0145                                                KindOfType kindOfType,
0146                                                EDGetToken token,
0147                                                ModuleCallingContext const* mcc) const {
0148     ProductResolverIndexAndSkipBit indexAndBit = consumer_->indexFrom(token, branchType(), id);
0149     ProductResolverIndex index = indexAndBit.productResolverIndex();
0150     bool skipCurrentProcess = indexAndBit.skipCurrentProcess();
0151     if (UNLIKELY(index == ProductResolverIndexInvalid)) {
0152       return makeFailToGetException(kindOfType, id, token);
0153     } else if (UNLIKELY(index == ProductResolverIndexAmbiguous)) {
0154       // This deals with ambiguities where the process is specified
0155       throwAmbiguousException(id, token);
0156     }
0157     bool ambiguous = false;
0158     BasicHandle h =
0159         principal_.getByToken(kindOfType, id, index, skipCurrentProcess, ambiguous, resourcesAcquirer_, mcc);
0160     if (ambiguous) {
0161       // This deals with ambiguities where the process is not specified
0162       throwAmbiguousException(id, token);
0163     } else if (!h.isValid()) {
0164       return makeFailToGetException(kindOfType, id, token);
0165     }
0166     return h;
0167   }
0168 
0169   BasicHandle PrincipalGetAdapter::getMatchingSequenceByLabel_(TypeID const& typeID,
0170                                                                InputTag const& tag,
0171                                                                ModuleCallingContext const* mcc) const {
0172     return principal_.getByLabel(ELEMENT_TYPE, typeID, tag, consumer_, resourcesAcquirer_, mcc);
0173   }
0174 
0175   BasicHandle PrincipalGetAdapter::getMatchingSequenceByLabel_(TypeID const& typeID,
0176                                                                std::string const& label,
0177                                                                std::string const& instance,
0178                                                                std::string const& process,
0179                                                                ModuleCallingContext const* mcc) const {
0180     auto h = principal_.getByLabel(ELEMENT_TYPE, typeID, label, instance, process, consumer_, resourcesAcquirer_, mcc);
0181     return h;
0182   }
0183 
0184   ProcessHistory const& PrincipalGetAdapter::processHistory() const { return principal_.processHistory(); }
0185 
0186   void PrincipalGetAdapter::throwUnregisteredPutException(TypeID const& type,
0187                                                           std::string const& productInstanceName) const {
0188     std::ostringstream str;
0189     for (auto branchDescription : principal_.productRegistry().allBranchDescriptions()) {
0190       if (branchDescription->moduleLabel() == md_.moduleLabel() and
0191           branchDescription->processName() == md_.processName()) {
0192         str << *branchDescription << "-----\n";
0193       }
0194     }
0195     throw edm::Exception(edm::errors::InsertFailure)
0196         << "Illegal attempt to 'put' an unregistered product.\n"
0197         << "No product is registered for\n"
0198         << "  product friendly class name: '" << type.friendlyClassName() << "'\n"
0199         << "  module label:                '" << md_.moduleLabel() << "'\n"
0200         << "  product instance name:       '" << productInstanceName << "'\n"
0201         << "  process name:                '" << md_.processName() << "'\n"
0202 
0203         << "The following data products are registered for production by " << md_.moduleLabel() << ":\n"
0204         << str.str() << '\n'
0205         << "To correct the problem:\n"
0206            "   1) make sure the proper 'produce' call is being made in the module's constructor,\n"
0207            "   2) if 'produce' exists and uses a product instance name make sure that same name is used during the "
0208            "'put' call.";
0209   }
0210 
0211   BranchDescription const& PrincipalGetAdapter::getBranchDescription(TypeID const& type,
0212                                                                      std::string const& productInstanceName) const {
0213     ProductResolverIndexHelper const& productResolverIndexHelper = principal_.productLookup();
0214     ProductResolverIndex index = productResolverIndexHelper.index(
0215         PRODUCT_TYPE, type, md_.moduleLabel().c_str(), productInstanceName.c_str(), md_.processName().c_str());
0216     if (UNLIKELY(index == ProductResolverIndexInvalid)) {
0217       throwUnregisteredPutException(type, productInstanceName);
0218     }
0219     ProductResolverBase const* phb = principal_.getProductResolverByIndex(index);
0220     assert(phb != nullptr);
0221     return phb->branchDescription();
0222   }
0223 
0224   BranchDescription const& PrincipalGetAdapter::getBranchDescription(unsigned int iPutTokenIndex) const {
0225     auto index = prodBase_->putTokenIndexToProductResolverIndex()[iPutTokenIndex];
0226     ProductResolverBase const* phb = principal_.getProductResolverByIndex(index);
0227     assert(phb != nullptr);
0228     return phb->branchDescription();
0229   }
0230 
0231   ProductID const& PrincipalGetAdapter::getProductID(unsigned int iPutTokenIndex) const {
0232     auto index = prodBase_->putTokenIndexToProductResolverIndex()[iPutTokenIndex];
0233     ProductResolverBase const* phb = principal_.getProductResolverByIndex(index);
0234     assert(phb != nullptr);
0235     auto prov = phb->stableProvenance();
0236     assert(prov != nullptr);
0237     return prov->productID();
0238   }
0239 
0240   Transition PrincipalGetAdapter::transition() const {
0241     if (LIKELY(principal().branchType() == InEvent)) {
0242       return Transition::Event;
0243     }
0244     if (principal().branchType() == InRun) {
0245       if (isComplete()) {
0246         return Transition::EndRun;
0247       } else {
0248         return Transition::BeginRun;
0249       }
0250     }
0251     if (isComplete()) {
0252       return Transition::EndLuminosityBlock;
0253     }
0254     return Transition::BeginLuminosityBlock;
0255     //Must be lumi
0256   }
0257 
0258   EDPutToken::value_type PrincipalGetAdapter::getPutTokenIndex(TypeID const& type,
0259                                                                std::string const& productInstanceName) const {
0260     auto tran = transition();
0261     size_t index = 0;
0262     for (auto const& tl : prodBase_->typeLabelList()) {
0263       if ((tran == tl.transition_) and (type == tl.typeID_) and (productInstanceName == tl.productInstanceName_)) {
0264         return index;
0265       }
0266       ++index;
0267     }
0268     throwUnregisteredPutException(type, productInstanceName);
0269     return std::numeric_limits<unsigned int>::max();
0270   }
0271 
0272   std::string const& PrincipalGetAdapter::productInstanceLabel(EDPutToken iToken) const {
0273     return prodBase_->typeLabelList()[iToken.index()].productInstanceName_;
0274   }
0275 
0276   TypeID const& PrincipalGetAdapter::getTypeIDForPutTokenIndex(EDPutToken::value_type index) const {
0277     return prodBase_->typeLabelList()[index].typeID_;
0278   }
0279 
0280   std::vector<edm::ProductResolverIndex> const& PrincipalGetAdapter::putTokenIndexToProductResolverIndex() const {
0281     return prodBase_->putTokenIndexToProductResolverIndex();
0282   }
0283 
0284   std::vector<bool> const& PrincipalGetAdapter::recordProvenanceList() const {
0285     return prodBase_->recordProvenanceList();
0286   }
0287 
0288   EDProductGetter const* PrincipalGetAdapter::prodGetter() const { return principal_.prodGetter(); }
0289 }  // namespace edm