File indexing completed on 2022-09-11 22:29:29
0001 #ifndef FWCore_Framework_EDConsumerBase_h
0002 #define FWCore_Framework_EDConsumerBase_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include <array>
0023 #include <map>
0024 #include <string>
0025 #include <vector>
0026 #include <array>
0027 #include <cassert>
0028
0029
0030 #include "DataFormats/Provenance/interface/BranchType.h"
0031 #include "DataFormats/Provenance/interface/ProvenanceFwd.h"
0032 #include "FWCore/Common/interface/FWCoreCommonFwd.h"
0033 #include "FWCore/Framework/interface/ProductResolverIndexAndSkipBit.h"
0034 #include "FWCore/Framework/interface/EventSetupRecordKey.h"
0035 #include "FWCore/Framework/interface/HCTypeTag.h"
0036 #include "FWCore/Framework/interface/DataKey.h"
0037 #include "FWCore/Framework/interface/data_default_record_trait.h"
0038 #include "FWCore/ServiceRegistry/interface/ConsumesInfo.h"
0039 #include "FWCore/Utilities/interface/ESIndices.h"
0040 #include "FWCore/Utilities/interface/TypeID.h"
0041 #include "FWCore/Utilities/interface/TypeToGet.h"
0042 #include "FWCore/Utilities/interface/InputTag.h"
0043 #include "FWCore/Utilities/interface/EDGetToken.h"
0044 #include "FWCore/Utilities/interface/ESGetToken.h"
0045 #include "FWCore/Utilities/interface/ESGetTokenGeneric.h"
0046 #include "FWCore/Utilities/interface/ESInputTag.h"
0047 #include "FWCore/Utilities/interface/SoATuple.h"
0048 #include "FWCore/Utilities/interface/Transition.h"
0049 #include "FWCore/Utilities/interface/ProductResolverIndex.h"
0050 #include "FWCore/Utilities/interface/ProductKindOfType.h"
0051 #include "FWCore/Utilities/interface/ProductLabels.h"
0052
0053
0054
0055 namespace edm {
0056 class ModuleProcessName;
0057 class ProductResolverIndexHelper;
0058 class ConsumesCollector;
0059 template <Transition Tr>
0060 class EDConsumerBaseESAdaptor;
0061 template <Transition Tr>
0062 class EDConsumerBaseWithTagESAdaptor;
0063 template <BranchType B>
0064 class EDConsumerBaseAdaptor;
0065 template <typename T>
0066 class WillGetIfMatch;
0067
0068 namespace eventsetup {
0069 class ESRecordsToProxyIndices;
0070 }
0071
0072 class EDConsumerBase {
0073 public:
0074 EDConsumerBase();
0075 virtual ~EDConsumerBase() noexcept(false);
0076
0077
0078 EDConsumerBase(EDConsumerBase const&) = delete;
0079 EDConsumerBase const& operator=(EDConsumerBase const&) = delete;
0080
0081
0082 EDConsumerBase(EDConsumerBase&&) = default;
0083 EDConsumerBase& operator=(EDConsumerBase&&) = default;
0084
0085
0086 ProductResolverIndexAndSkipBit indexFrom(EDGetToken, BranchType, TypeID const&) const;
0087 ProductResolverIndexAndSkipBit uncheckedIndexFrom(EDGetToken) const;
0088
0089 void itemsToGet(BranchType, std::vector<ProductResolverIndexAndSkipBit>&) const;
0090 void itemsMayGet(BranchType, std::vector<ProductResolverIndexAndSkipBit>&) const;
0091
0092
0093 std::vector<ProductResolverIndexAndSkipBit> const& itemsToGetFrom(BranchType iType) const {
0094 return itemsToGetFromBranch_[iType];
0095 }
0096
0097
0098 bool registeredToConsume(ProductResolverIndex, bool, BranchType) const;
0099
0100
0101 bool registeredToConsumeMany(TypeID const&, BranchType) const;
0102
0103
0104
0105 void updateLookup(BranchType iBranchType, ProductResolverIndexHelper const&, bool iPrefetchMayGet);
0106 void updateLookup(eventsetup::ESRecordsToProxyIndices const&);
0107 void selectInputProcessBlocks(ProductRegistry const& productRegistry,
0108 ProcessBlockHelperBase const& processBlockHelperBase) {
0109 doSelectInputProcessBlocks(productRegistry, processBlockHelperBase);
0110 }
0111
0112 typedef ProductLabels Labels;
0113 void labelsForToken(EDGetToken iToken, Labels& oLabels) const;
0114
0115 void modulesWhoseProductsAreConsumed(std::array<std::vector<ModuleDescription const*>*, NumBranchTypes>& modulesAll,
0116 std::vector<ModuleProcessName>& modulesInPreviousProcesses,
0117 ProductRegistry const& preg,
0118 std::map<std::string, ModuleDescription const*> const& labelsToDesc,
0119 std::string const& processName) const;
0120
0121
0122 void convertCurrentProcessAlias(std::string const& processName);
0123
0124 std::vector<ConsumesInfo> consumesInfo() const;
0125
0126 ESProxyIndex const* esGetTokenIndices(edm::Transition iTrans) const {
0127 if (iTrans < edm::Transition::NumberOfEventSetupTransitions) {
0128 auto const& v = esItemsToGetFromTransition_[static_cast<unsigned int>(iTrans)];
0129 if (v.empty()) {
0130 return nullptr;
0131 }
0132 return &(esItemsToGetFromTransition_[static_cast<unsigned int>(iTrans)].front());
0133 }
0134 return nullptr;
0135 }
0136
0137 std::vector<ESProxyIndex> const& esGetTokenIndicesVector(edm::Transition iTrans) const {
0138 assert(iTrans < edm::Transition::NumberOfEventSetupTransitions);
0139 return esItemsToGetFromTransition_[static_cast<unsigned int>(iTrans)];
0140 }
0141
0142 std::vector<ESRecordIndex> const& esGetTokenRecordIndicesVector(edm::Transition iTrans) const {
0143 assert(iTrans < edm::Transition::NumberOfEventSetupTransitions);
0144 return esRecordsToGetFromTransition_[static_cast<unsigned int>(iTrans)];
0145 }
0146
0147 protected:
0148 friend class ConsumesCollector;
0149 template <Transition Tr>
0150 friend class EDConsumerBaseESAdaptor;
0151 template <Transition Tr>
0152 friend class EDConsumerBaseWithTagESAdaptor;
0153 template <BranchType B>
0154 friend class EDConsumerBaseAdaptor;
0155 template <typename T>
0156 friend class WillGetIfMatch;
0157
0158 ConsumesCollector consumesCollector();
0159
0160 template <typename ProductType, BranchType B = InEvent>
0161 EDGetTokenT<ProductType> consumes(edm::InputTag const& tag) {
0162 TypeToGet tid = TypeToGet::make<ProductType>();
0163 return EDGetTokenT<ProductType>{recordConsumes(B, tid, checkIfEmpty(tag), true)};
0164 }
0165
0166 template <BranchType B = InEvent>
0167 [[nodiscard]] EDConsumerBaseAdaptor<B> consumes(edm::InputTag tag) noexcept {
0168 return EDConsumerBaseAdaptor<B>(this, std::move(tag));
0169 }
0170
0171 EDGetToken consumes(const TypeToGet& id, edm::InputTag const& tag) {
0172 return EDGetToken{recordConsumes(InEvent, id, checkIfEmpty(tag), true)};
0173 }
0174
0175 template <BranchType B>
0176 EDGetToken consumes(TypeToGet const& id, edm::InputTag const& tag) {
0177 return EDGetToken{recordConsumes(B, id, checkIfEmpty(tag), true)};
0178 }
0179
0180 template <typename ProductType, BranchType B = InEvent>
0181 EDGetTokenT<ProductType> mayConsume(edm::InputTag const& tag) {
0182 TypeToGet tid = TypeToGet::make<ProductType>();
0183 return EDGetTokenT<ProductType>{recordConsumes(B, tid, checkIfEmpty(tag), false)};
0184 }
0185
0186 EDGetToken mayConsume(const TypeToGet& id, edm::InputTag const& tag) { return mayConsume<InEvent>(id, tag); }
0187
0188 template <BranchType B>
0189 EDGetToken mayConsume(const TypeToGet& id, edm::InputTag const& tag) {
0190 return EDGetToken{recordConsumes(B, id, checkIfEmpty(tag), false)};
0191 }
0192
0193 template <typename ProductType, BranchType B = InEvent>
0194 void consumesMany() {
0195 TypeToGet tid = TypeToGet::make<ProductType>();
0196 consumesMany<B>(tid);
0197 }
0198
0199 void consumesMany(const TypeToGet& id) { consumesMany<InEvent>(id); }
0200
0201 template <BranchType B>
0202 void consumesMany(const TypeToGet& id) {
0203 recordConsumes(B, id, edm::InputTag{}, true);
0204 }
0205
0206
0207 template <typename ESProduct, typename ESRecord, Transition Tr = Transition::Event>
0208 auto esConsumes() {
0209 return esConsumes<ESProduct, ESRecord, Tr>(ESInputTag{});
0210 }
0211
0212 template <typename ESProduct, typename ESRecord, Transition Tr = Transition::Event>
0213 auto esConsumes(ESInputTag const& tag) {
0214 auto index = recordESConsumes(Tr,
0215 eventsetup::EventSetupRecordKey::makeKey<
0216 std::conditional_t<std::is_same_v<ESRecord, edm::DefaultRecord>,
0217 eventsetup::default_record_t<ESHandleAdapter<ESProduct>>,
0218 ESRecord>>(),
0219 eventsetup::heterocontainer::HCTypeTag::make<ESProduct>(),
0220 tag);
0221 return ESGetToken<ESProduct, ESRecord>{static_cast<unsigned int>(Tr), index, labelFor(index)};
0222 }
0223
0224 template <Transition Tr = Transition::Event>
0225 [[nodiscard]] constexpr auto esConsumes() {
0226 return EDConsumerBaseESAdaptor<Tr>(this);
0227 }
0228
0229 template <Transition Tr = Transition::Event>
0230 [[nodiscard]] auto esConsumes(ESInputTag tag) {
0231 return EDConsumerBaseWithTagESAdaptor<Tr>(this, std::move(tag));
0232 }
0233
0234
0235 template <Transition Tr = Transition::Event>
0236 ESGetTokenGeneric esConsumes(eventsetup::EventSetupRecordKey const& iRecord, eventsetup::DataKey const& iKey) {
0237 return ESGetTokenGeneric(static_cast<unsigned int>(Tr),
0238 recordESConsumes(Tr, iRecord, iKey.type(), ESInputTag("", iKey.name().value())),
0239 iRecord.type());
0240 }
0241
0242
0243 void resetItemsToGetFrom(BranchType iType) { itemsToGetFromBranch_[iType].clear(); }
0244
0245 private:
0246 virtual void extendUpdateLookup(BranchType iBranchType, ProductResolverIndexHelper const&);
0247 virtual void registerLateConsumes(eventsetup::ESRecordsToProxyIndices const&) {}
0248 unsigned int recordConsumes(BranchType iBranch, TypeToGet const& iType, edm::InputTag const& iTag, bool iAlwaysGets);
0249 ESTokenIndex recordESConsumes(Transition,
0250 eventsetup::EventSetupRecordKey const&,
0251 eventsetup::heterocontainer::HCTypeTag const&,
0252 edm::ESInputTag const& iTag);
0253
0254 const char* labelFor(ESTokenIndex) const;
0255
0256 void throwTypeMismatch(edm::TypeID const&, EDGetToken) const;
0257 void throwBranchMismatch(BranchType, EDGetToken) const;
0258 void throwBadToken(edm::TypeID const& iType, EDGetToken iToken) const;
0259 void throwConsumesCallAfterFrozen(TypeToGet const&, InputTag const&) const;
0260 void throwESConsumesCallAfterFrozen(eventsetup::EventSetupRecordKey const&,
0261 eventsetup::heterocontainer::HCTypeTag const&,
0262 edm::ESInputTag const&) const;
0263 void throwESConsumesInProcessBlock() const;
0264
0265 edm::InputTag const& checkIfEmpty(edm::InputTag const& tag);
0266
0267 virtual void doSelectInputProcessBlocks(ProductRegistry const&, ProcessBlockHelperBase const&);
0268
0269
0270
0271 struct TokenLookupInfo {
0272 TokenLookupInfo(edm::TypeID const& iID, ProductResolverIndex iIndex, bool skipCurrentProcess, BranchType iBranch)
0273 : m_type(iID), m_index(iIndex, skipCurrentProcess), m_branchType(iBranch) {}
0274 edm::TypeID m_type;
0275 ProductResolverIndexAndSkipBit m_index;
0276 BranchType m_branchType;
0277 };
0278
0279 struct LabelPlacement {
0280 LabelPlacement(unsigned int iStartOfModuleLabel,
0281 unsigned short iDeltaToProductInstance,
0282 unsigned short iDeltaToProcessName)
0283 : m_startOfModuleLabel(iStartOfModuleLabel),
0284 m_deltaToProductInstance(iDeltaToProductInstance),
0285 m_deltaToProcessName(iDeltaToProcessName) {}
0286 unsigned int m_startOfModuleLabel;
0287 unsigned short m_deltaToProductInstance;
0288 unsigned short m_deltaToProcessName;
0289 };
0290
0291
0292 enum { kLookupInfo, kAlwaysGets, kLabels, kKind };
0293 edm::SoATuple<TokenLookupInfo, bool, LabelPlacement, edm::KindOfType> m_tokenInfo;
0294
0295
0296
0297 std::vector<char> m_tokenLabels;
0298
0299 std::array<std::vector<ProductResolverIndexAndSkipBit>, edm::NumBranchTypes> itemsToGetFromBranch_;
0300
0301 struct ESTokenLookupInfo {
0302 eventsetup::EventSetupRecordKey m_record;
0303 eventsetup::DataKey m_key;
0304 unsigned int m_startOfComponentName;
0305 };
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316 enum { kESLookupInfo, kESProxyIndex };
0317 edm::SoATuple<ESTokenLookupInfo, ESProxyIndex> m_esTokenInfo;
0318 std::array<std::vector<ESProxyIndex>, static_cast<unsigned int>(edm::Transition::NumberOfEventSetupTransitions)>
0319 esItemsToGetFromTransition_;
0320 std::array<std::vector<ESRecordIndex>, static_cast<unsigned int>(edm::Transition::NumberOfEventSetupTransitions)>
0321 esRecordsToGetFromTransition_;
0322 bool frozen_;
0323 bool containsCurrentProcessAlias_;
0324 };
0325
0326 template <Transition TR>
0327 class EDConsumerBaseESAdaptor {
0328 public:
0329 template <typename TYPE, typename REC>
0330 ESGetToken<TYPE, REC> consumes() {
0331 return m_consumer->template esConsumes<TYPE, REC, TR>();
0332 }
0333
0334 private:
0335
0336 friend class EDConsumerBase;
0337 EDConsumerBaseESAdaptor(EDConsumerBase* iBase) : m_consumer(iBase) {}
0338
0339 EDConsumerBase* m_consumer;
0340 };
0341
0342 template <Transition TR>
0343 class EDConsumerBaseWithTagESAdaptor {
0344 public:
0345 template <typename TYPE, typename REC>
0346 ESGetToken<TYPE, REC> consumes() {
0347 return m_consumer->template esConsumes<TYPE, REC, TR>(m_tag);
0348 }
0349
0350 private:
0351
0352 friend class EDConsumerBase;
0353 EDConsumerBaseWithTagESAdaptor(EDConsumerBase* iBase, ESInputTag iTag) noexcept
0354 : m_consumer(iBase), m_tag(std::move(iTag)) {}
0355
0356 EDConsumerBase* m_consumer;
0357 ESInputTag const m_tag;
0358 };
0359
0360 template <BranchType B>
0361 class EDConsumerBaseAdaptor {
0362 public:
0363 template <typename TYPE>
0364 EDGetTokenT<TYPE> consumes() {
0365 return m_consumer->template consumes<TYPE, B>(m_tag);
0366 }
0367
0368 private:
0369
0370 friend class EDConsumerBase;
0371 EDConsumerBaseAdaptor(EDConsumerBase* iBase, edm::InputTag iTag) noexcept
0372 : m_consumer(iBase), m_tag(std::move(iTag)) {}
0373
0374 EDConsumerBase* m_consumer;
0375 edm::InputTag const m_tag;
0376 };
0377
0378 }
0379
0380 #endif