File indexing completed on 2023-10-25 09:46:49
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 ESRecordsToProductResolverIndices;
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
0102
0103 void updateLookup(BranchType iBranchType, ProductResolverIndexHelper const&, bool iPrefetchMayGet);
0104 void updateLookup(eventsetup::ESRecordsToProductResolverIndices const&);
0105 void selectInputProcessBlocks(ProductRegistry const& productRegistry,
0106 ProcessBlockHelperBase const& processBlockHelperBase) {
0107 doSelectInputProcessBlocks(productRegistry, processBlockHelperBase);
0108 }
0109
0110 typedef ProductLabels Labels;
0111 void labelsForToken(EDGetToken iToken, Labels& oLabels) const;
0112
0113 void modulesWhoseProductsAreConsumed(std::array<std::vector<ModuleDescription const*>*, NumBranchTypes>& modulesAll,
0114 std::vector<ModuleProcessName>& modulesInPreviousProcesses,
0115 ProductRegistry const& preg,
0116 std::map<std::string, ModuleDescription const*> const& labelsToDesc,
0117 std::string const& processName) const;
0118
0119
0120 void convertCurrentProcessAlias(std::string const& processName);
0121
0122 std::vector<ConsumesInfo> consumesInfo() const;
0123
0124 ESResolverIndex const* esGetTokenIndices(edm::Transition iTrans) const {
0125 if (iTrans < edm::Transition::NumberOfEventSetupTransitions) {
0126 auto const& v = esItemsToGetFromTransition_[static_cast<unsigned int>(iTrans)];
0127 if (v.empty()) {
0128 return nullptr;
0129 }
0130 return &(esItemsToGetFromTransition_[static_cast<unsigned int>(iTrans)].front());
0131 }
0132 return nullptr;
0133 }
0134
0135 std::vector<ESResolverIndex> const& esGetTokenIndicesVector(edm::Transition iTrans) const {
0136 assert(iTrans < edm::Transition::NumberOfEventSetupTransitions);
0137 return esItemsToGetFromTransition_[static_cast<unsigned int>(iTrans)];
0138 }
0139
0140 std::vector<ESRecordIndex> const& esGetTokenRecordIndicesVector(edm::Transition iTrans) const {
0141 assert(iTrans < edm::Transition::NumberOfEventSetupTransitions);
0142 return esRecordsToGetFromTransition_[static_cast<unsigned int>(iTrans)];
0143 }
0144
0145 protected:
0146 friend class ConsumesCollector;
0147 template <Transition Tr>
0148 friend class EDConsumerBaseESAdaptor;
0149 template <Transition Tr>
0150 friend class EDConsumerBaseWithTagESAdaptor;
0151 template <BranchType B>
0152 friend class EDConsumerBaseAdaptor;
0153 template <typename T>
0154 friend class WillGetIfMatch;
0155
0156 ConsumesCollector consumesCollector();
0157
0158 template <typename ProductType, BranchType B = InEvent>
0159 EDGetTokenT<ProductType> consumes(edm::InputTag const& tag) {
0160 TypeToGet tid = TypeToGet::make<ProductType>();
0161 return EDGetTokenT<ProductType>{recordConsumes(B, tid, checkIfEmpty(tag), true)};
0162 }
0163
0164 template <BranchType B = InEvent>
0165 [[nodiscard]] EDConsumerBaseAdaptor<B> consumes(edm::InputTag tag) noexcept {
0166 return EDConsumerBaseAdaptor<B>(this, std::move(tag));
0167 }
0168
0169 EDGetToken consumes(const TypeToGet& id, edm::InputTag const& tag) {
0170 return EDGetToken{recordConsumes(InEvent, id, checkIfEmpty(tag), true)};
0171 }
0172
0173 template <BranchType B>
0174 EDGetToken consumes(TypeToGet const& id, edm::InputTag const& tag) {
0175 return EDGetToken{recordConsumes(B, id, checkIfEmpty(tag), true)};
0176 }
0177
0178 template <typename ProductType, BranchType B = InEvent>
0179 EDGetTokenT<ProductType> mayConsume(edm::InputTag const& tag) {
0180 TypeToGet tid = TypeToGet::make<ProductType>();
0181 return EDGetTokenT<ProductType>{recordConsumes(B, tid, checkIfEmpty(tag), false)};
0182 }
0183
0184 EDGetToken mayConsume(const TypeToGet& id, edm::InputTag const& tag) { return mayConsume<InEvent>(id, tag); }
0185
0186 template <BranchType B>
0187 EDGetToken mayConsume(const TypeToGet& id, edm::InputTag const& tag) {
0188 return EDGetToken{recordConsumes(B, id, checkIfEmpty(tag), false)};
0189 }
0190
0191
0192 template <typename ESProduct, typename ESRecord, Transition Tr = Transition::Event>
0193 auto esConsumes() {
0194 return esConsumes<ESProduct, ESRecord, Tr>(ESInputTag{});
0195 }
0196
0197 template <typename ESProduct, typename ESRecord, Transition Tr = Transition::Event>
0198 auto esConsumes(ESInputTag const& tag) {
0199 auto index = recordESConsumes(Tr,
0200 eventsetup::EventSetupRecordKey::makeKey<
0201 std::conditional_t<std::is_same_v<ESRecord, edm::DefaultRecord>,
0202 eventsetup::default_record_t<ESHandleAdapter<ESProduct>>,
0203 ESRecord>>(),
0204 eventsetup::heterocontainer::HCTypeTag::make<ESProduct>(),
0205 tag);
0206 return ESGetToken<ESProduct, ESRecord>{static_cast<unsigned int>(Tr), index, labelFor(index)};
0207 }
0208
0209 template <Transition Tr = Transition::Event>
0210 [[nodiscard]] constexpr auto esConsumes() {
0211 return EDConsumerBaseESAdaptor<Tr>(this);
0212 }
0213
0214 template <Transition Tr = Transition::Event>
0215 [[nodiscard]] auto esConsumes(ESInputTag tag) {
0216 return EDConsumerBaseWithTagESAdaptor<Tr>(this, std::move(tag));
0217 }
0218
0219
0220 template <Transition Tr = Transition::Event>
0221 ESGetTokenGeneric esConsumes(eventsetup::EventSetupRecordKey const& iRecord, eventsetup::DataKey const& iKey) {
0222 return ESGetTokenGeneric(static_cast<unsigned int>(Tr),
0223 recordESConsumes(Tr, iRecord, iKey.type(), ESInputTag("", iKey.name().value())),
0224 iRecord.type());
0225 }
0226
0227
0228 void resetItemsToGetFrom(BranchType iType) { itemsToGetFromBranch_[iType].clear(); }
0229
0230 private:
0231 virtual void extendUpdateLookup(BranchType iBranchType, ProductResolverIndexHelper const&);
0232 virtual void registerLateConsumes(eventsetup::ESRecordsToProductResolverIndices const&) {}
0233 unsigned int recordConsumes(BranchType iBranch, TypeToGet const& iType, edm::InputTag const& iTag, bool iAlwaysGets);
0234 ESTokenIndex recordESConsumes(Transition,
0235 eventsetup::EventSetupRecordKey const&,
0236 eventsetup::heterocontainer::HCTypeTag const&,
0237 edm::ESInputTag const& iTag);
0238
0239 const char* labelFor(ESTokenIndex) const;
0240
0241 void throwTypeMismatch(edm::TypeID const&, EDGetToken) const;
0242 void throwBranchMismatch(BranchType, EDGetToken) const;
0243 void throwBadToken(edm::TypeID const& iType, EDGetToken iToken) const;
0244 void throwConsumesCallAfterFrozen(TypeToGet const&, InputTag const&) const;
0245 void throwESConsumesCallAfterFrozen(eventsetup::EventSetupRecordKey const&,
0246 eventsetup::heterocontainer::HCTypeTag const&,
0247 edm::ESInputTag const&) const;
0248 void throwESConsumesInProcessBlock() const;
0249
0250 edm::InputTag const& checkIfEmpty(edm::InputTag const& tag);
0251
0252 virtual void doSelectInputProcessBlocks(ProductRegistry const&, ProcessBlockHelperBase const&);
0253
0254
0255
0256 struct TokenLookupInfo {
0257 TokenLookupInfo(edm::TypeID const& iID, ProductResolverIndex iIndex, bool skipCurrentProcess, BranchType iBranch)
0258 : m_type(iID), m_index(iIndex, skipCurrentProcess), m_branchType(iBranch) {}
0259 edm::TypeID m_type;
0260 ProductResolverIndexAndSkipBit m_index;
0261 BranchType m_branchType;
0262 };
0263
0264 struct LabelPlacement {
0265 LabelPlacement(unsigned int iStartOfModuleLabel,
0266 unsigned short iDeltaToProductInstance,
0267 unsigned short iDeltaToProcessName)
0268 : m_startOfModuleLabel(iStartOfModuleLabel),
0269 m_deltaToProductInstance(iDeltaToProductInstance),
0270 m_deltaToProcessName(iDeltaToProcessName) {}
0271 unsigned int m_startOfModuleLabel;
0272 unsigned short m_deltaToProductInstance;
0273 unsigned short m_deltaToProcessName;
0274 };
0275
0276
0277 enum { kLookupInfo, kAlwaysGets, kLabels, kKind };
0278 edm::SoATuple<TokenLookupInfo, bool, LabelPlacement, edm::KindOfType> m_tokenInfo;
0279
0280
0281
0282 std::vector<char> m_tokenLabels;
0283
0284 std::array<std::vector<ProductResolverIndexAndSkipBit>, edm::NumBranchTypes> itemsToGetFromBranch_;
0285
0286 struct ESTokenLookupInfo {
0287 eventsetup::EventSetupRecordKey m_record;
0288 eventsetup::DataKey m_key;
0289 unsigned int m_startOfComponentName;
0290 };
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301 enum { kESLookupInfo, kESResolverIndex };
0302 edm::SoATuple<ESTokenLookupInfo, ESResolverIndex> m_esTokenInfo;
0303 std::array<std::vector<ESResolverIndex>, static_cast<unsigned int>(edm::Transition::NumberOfEventSetupTransitions)>
0304 esItemsToGetFromTransition_;
0305 std::array<std::vector<ESRecordIndex>, static_cast<unsigned int>(edm::Transition::NumberOfEventSetupTransitions)>
0306 esRecordsToGetFromTransition_;
0307 bool frozen_;
0308 bool containsCurrentProcessAlias_;
0309 };
0310
0311 template <Transition TR>
0312 class EDConsumerBaseESAdaptor {
0313 public:
0314 template <typename TYPE, typename REC>
0315 ESGetToken<TYPE, REC> consumes() {
0316 return m_consumer->template esConsumes<TYPE, REC, TR>();
0317 }
0318
0319 private:
0320
0321 friend class EDConsumerBase;
0322 EDConsumerBaseESAdaptor(EDConsumerBase* iBase) : m_consumer(iBase) {}
0323
0324 EDConsumerBase* m_consumer;
0325 };
0326
0327 template <Transition TR>
0328 class EDConsumerBaseWithTagESAdaptor {
0329 public:
0330 template <typename TYPE, typename REC>
0331 ESGetToken<TYPE, REC> consumes() {
0332 return m_consumer->template esConsumes<TYPE, REC, TR>(m_tag);
0333 }
0334
0335 private:
0336
0337 friend class EDConsumerBase;
0338 EDConsumerBaseWithTagESAdaptor(EDConsumerBase* iBase, ESInputTag iTag) noexcept
0339 : m_consumer(iBase), m_tag(std::move(iTag)) {}
0340
0341 EDConsumerBase* m_consumer;
0342 ESInputTag const m_tag;
0343 };
0344
0345 template <BranchType B>
0346 class EDConsumerBaseAdaptor {
0347 public:
0348 template <typename TYPE>
0349 EDGetTokenT<TYPE> consumes() {
0350 return m_consumer->template consumes<TYPE, B>(m_tag);
0351 }
0352
0353 private:
0354
0355 friend class EDConsumerBase;
0356 EDConsumerBaseAdaptor(EDConsumerBase* iBase, edm::InputTag iTag) noexcept
0357 : m_consumer(iBase), m_tag(std::move(iTag)) {}
0358
0359 EDConsumerBase* m_consumer;
0360 edm::InputTag const m_tag;
0361 };
0362
0363 }
0364
0365 #endif