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 :
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
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
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
0098
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
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
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
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 }