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