Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef FWCore_Framework_LuminosityBlock_h
0002 #define FWCore_Framework_LuminosityBlock_h
0003 
0004 // -*- C++ -*-
0005 //
0006 // Package:     Framework
0007 // Class  :     LuminosityBlock
0008 //
0009 /**\class LuminosityBlock LuminosityBlock.h FWCore/Framework/interface/LuminosityBlock.h
0010 
0011 Description: This is the primary interface for accessing per luminosity block EDProducts
0012 and inserting new derived per luminosity block EDProducts.
0013 
0014 For its usage, see "FWCore/Framework/interface/PrincipalGetAdapter.h"
0015 
0016 */
0017 /*----------------------------------------------------------------------
0018 
0019 ----------------------------------------------------------------------*/
0020 
0021 #include "DataFormats/Common/interface/Wrapper.h"
0022 #include "FWCore/Common/interface/LuminosityBlockBase.h"
0023 #include "FWCore/Framework/interface/Frameworkfwd.h"
0024 #include "FWCore/Framework/interface/PrincipalGetAdapter.h"
0025 #include "FWCore/Framework/interface/Run.h"
0026 #include "FWCore/Utilities/interface/EDGetToken.h"
0027 #include "FWCore/Utilities/interface/EDPutToken.h"
0028 #include "FWCore/Utilities/interface/ProductKindOfType.h"
0029 #include "FWCore/Utilities/interface/LuminosityBlockIndex.h"
0030 #include "FWCore/Utilities/interface/propagate_const.h"
0031 #include "FWCore/Utilities/interface/Likely.h"
0032 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0033 
0034 #include <memory>
0035 #include <string>
0036 #include <typeinfo>
0037 #include <vector>
0038 #include <optional>
0039 
0040 namespace edm {
0041   class ModuleCallingContext;
0042   class ProducerBase;
0043   class SharedResourcesAcquirer;
0044 
0045   namespace stream {
0046     template <typename T>
0047     class ProducingModuleAdaptorBase;
0048   }
0049 
0050   class LuminosityBlock : public LuminosityBlockBase {
0051   public:
0052     LuminosityBlock(LumiTransitionInfo const&, ModuleDescription const&, ModuleCallingContext const*, bool isAtEnd);
0053     LuminosityBlock(LuminosityBlockPrincipal const&,
0054                     ModuleDescription const&,
0055                     ModuleCallingContext const*,
0056                     bool isAtEnd);
0057     ~LuminosityBlock() override;
0058 
0059     // AUX functions are defined in LuminosityBlockBase
0060     LuminosityBlockAuxiliary const& luminosityBlockAuxiliary() const final;
0061 
0062     /**\return Reusable index which can be used to separate data for different simultaneous LuminosityBlocks.
0063      */
0064     LuminosityBlockIndex index() const;
0065 
0066     /**If you are caching data from the LuminosityBlock, you should also keep
0067      this number.  If this number changes then you know that
0068      the data you have cached is invalid.
0069      The value of '0' will never be returned so you can use that to
0070      denote that you have not yet checked the value.
0071      */
0072     typedef unsigned long CacheIdentifier_t;
0073     CacheIdentifier_t cacheIdentifier() const;
0074 
0075     //Used in conjunction with EDGetToken
0076     void setConsumer(EDConsumerBase const* iConsumer);
0077 
0078     void setSharedResourcesAcquirer(SharedResourcesAcquirer* iResourceAcquirer);
0079 
0080     void setProducer(ProducerBase const* iProducer);
0081 
0082     template <typename PROD>
0083     bool getByLabel(std::string const& label, Handle<PROD>& result) const;
0084 
0085     template <typename PROD>
0086     bool getByLabel(std::string const& label, std::string const& productInstanceName, Handle<PROD>& result) const;
0087 
0088     /// same as above, but using the InputTag class
0089     template <typename PROD>
0090     bool getByLabel(InputTag const& tag, Handle<PROD>& result) const;
0091 
0092     template <typename PROD>
0093     bool getByToken(EDGetToken token, Handle<PROD>& result) const;
0094 
0095     template <typename PROD>
0096     bool getByToken(EDGetTokenT<PROD> token, Handle<PROD>& result) const;
0097 
0098     template <typename PROD>
0099     Handle<PROD> getHandle(EDGetTokenT<PROD> token) const;
0100 
0101     template <typename PROD>
0102     PROD const& get(EDGetTokenT<PROD> token) const noexcept(false);
0103 
0104     Run const& getRun() const {
0105       if (not run_) {
0106         fillRun();
0107       }
0108       return run_.value();
0109     }
0110 
0111     ///Put a new product.
0112     template <typename PROD>
0113     void put(std::unique_ptr<PROD> product) {
0114       put<PROD>(std::move(product), std::string());
0115     }
0116 
0117     ///Put a new product with a 'product instance name'
0118     template <typename PROD>
0119     void put(std::unique_ptr<PROD> product, std::string const& productInstanceName);
0120 
0121     template <typename PROD>
0122     void put(EDPutToken token, std::unique_ptr<PROD> product);
0123 
0124     template <typename PROD>
0125     void put(EDPutTokenT<PROD> token, std::unique_ptr<PROD> product);
0126 
0127     ///puts a new product
0128     template <typename PROD, typename... Args>
0129     void emplace(EDPutTokenT<PROD> token, Args&&... args);
0130 
0131     template <typename PROD, typename... Args>
0132     void emplace(EDPutToken token, Args&&... args);
0133 
0134     Provenance const& getProvenance(BranchID const& theID) const;
0135 
0136     StableProvenance const& getStableProvenance(BranchID const& theID) const;
0137 
0138     void getAllStableProvenance(std::vector<StableProvenance const*>& provenances) const;
0139 
0140     ProcessHistoryID const& processHistoryID() const;
0141 
0142     ProcessHistory const& processHistory() const;
0143 
0144     ModuleCallingContext const* moduleCallingContext() const { return moduleCallingContext_; }
0145 
0146     void labelsForToken(EDGetToken const& iToken, ProductLabels& oLabels) const {
0147       provRecorder_.labelsForToken(iToken, oLabels);
0148     }
0149 
0150   private:
0151     LuminosityBlockPrincipal const& luminosityBlockPrincipal() const;
0152 
0153     // Override version from LuminosityBlockBase class
0154     BasicHandle getByLabelImpl(std::type_info const& iWrapperType,
0155                                std::type_info const& iProductType,
0156                                InputTag const& iTag) const final;
0157 
0158     template <typename PROD>
0159     void putImpl(EDPutToken::value_type token, std::unique_ptr<PROD> product);
0160 
0161     template <typename PROD, typename... Args>
0162     void emplaceImpl(EDPutToken::value_type token, Args&&... args);
0163 
0164     typedef std::vector<edm::propagate_const<std::unique_ptr<WrapperBase>>> ProductPtrVec;
0165     ProductPtrVec& putProducts() { return putProducts_; }
0166     ProductPtrVec const& putProducts() const { return putProducts_; }
0167 
0168     void fillRun() const;
0169 
0170     // commit_() is called to complete the transaction represented by
0171     // this PrincipalGetAdapter. The friendships required seems gross, but any
0172     // alternative is not great either.  Putting it into the
0173     // public interface is asking for trouble
0174     friend class RawInputSource;
0175     friend class ProducerBase;
0176     template <typename T>
0177     friend class stream::ProducingModuleAdaptorBase;
0178 
0179     void commit_(std::vector<edm::ProductResolverIndex> const& iShouldPut);
0180 
0181     PrincipalGetAdapter provRecorder_;
0182     ProductPtrVec putProducts_;
0183     LuminosityBlockAuxiliary const& aux_;
0184     //This class is intended to be used by only one thread
0185     CMS_SA_ALLOW mutable std::optional<Run> run_;
0186     ModuleCallingContext const* moduleCallingContext_;
0187 
0188     static const std::string emptyString_;
0189   };
0190 
0191   template <typename PROD>
0192   void LuminosityBlock::putImpl(EDPutToken::value_type index, std::unique_ptr<PROD> product) {
0193     // The following will call post_insert if T has such a function,
0194     // and do nothing if T has no such function.
0195     std::conditional_t<detail::has_postinsert<PROD>::value, DoPostInsert<PROD>, DoNotPostInsert<PROD>> maybe_inserter;
0196     maybe_inserter(product.get());
0197 
0198     assert(index < putProducts().size());
0199 
0200     std::unique_ptr<Wrapper<PROD>> wp(new Wrapper<PROD>(std::move(product)));
0201     putProducts()[index] = std::move(wp);
0202   }
0203 
0204   template <typename PROD>
0205   void LuminosityBlock::put(std::unique_ptr<PROD> product, std::string const& productInstanceName) {
0206     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0207       TypeID typeID(typeid(PROD));
0208       principal_get_adapter_detail::throwOnPutOfNullProduct("LuminosityBlock", typeID, productInstanceName);
0209     }
0210     auto index = provRecorder_.getPutTokenIndex(TypeID(*product), productInstanceName);
0211     putImpl(index, std::move(product));
0212   }
0213 
0214   template <typename PROD>
0215   void LuminosityBlock::put(EDPutTokenT<PROD> token, std::unique_ptr<PROD> product) {
0216     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0217       TypeID typeID(typeid(PROD));
0218       principal_get_adapter_detail::throwOnPutOfNullProduct(
0219           "LuminosityBlock", typeID, provRecorder_.productInstanceLabel(token));
0220     }
0221     if (UNLIKELY(token.isUninitialized())) {
0222       principal_get_adapter_detail::throwOnPutOfUninitializedToken("LuminosityBlock", typeid(PROD));
0223     }
0224     putImpl(token.index(), std::move(product));
0225   }
0226 
0227   template <typename PROD>
0228   void LuminosityBlock::put(EDPutToken token, std::unique_ptr<PROD> product) {
0229     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0230       TypeID typeID(typeid(PROD));
0231       principal_get_adapter_detail::throwOnPutOfNullProduct(
0232           "LuminosityBlock", typeID, provRecorder_.productInstanceLabel(token));
0233     }
0234     if (UNLIKELY(token.isUninitialized())) {
0235       principal_get_adapter_detail::throwOnPutOfUninitializedToken("LuminosityBlock", typeid(PROD));
0236     }
0237     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0238       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0239                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0240     }
0241 
0242     putImpl(token.index(), std::move(product));
0243   }
0244 
0245   template <typename PROD, typename... Args>
0246   void LuminosityBlock::emplace(EDPutTokenT<PROD> token, Args&&... args) {
0247     if (UNLIKELY(token.isUninitialized())) {
0248       principal_get_adapter_detail::throwOnPutOfUninitializedToken("LuminosityBlock", typeid(PROD));
0249     }
0250     emplaceImpl<PROD>(token.index(), std::forward<Args>(args)...);
0251   }
0252 
0253   template <typename PROD, typename... Args>
0254   void LuminosityBlock::emplace(EDPutToken token, Args&&... args) {
0255     if (UNLIKELY(token.isUninitialized())) {
0256       principal_get_adapter_detail::throwOnPutOfUninitializedToken("LuminosityBlock", typeid(PROD));
0257     }
0258     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0259       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0260                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0261     }
0262 
0263     emplaceImpl(token.index(), std::forward<Args>(args)...);
0264   }
0265 
0266   template <typename PROD, typename... Args>
0267   void LuminosityBlock::emplaceImpl(EDPutToken::value_type index, Args&&... args) {
0268     assert(index < putProducts().size());
0269 
0270     std::unique_ptr<Wrapper<PROD>> wp(new Wrapper<PROD>(WrapperBase::Emplace{}, std::forward<Args>(args)...));
0271 
0272     // The following will call post_insert if T has such a function,
0273     // and do nothing if T has no such function.
0274     std::conditional_t<detail::has_postinsert<PROD>::value, DoPostInsert<PROD>, DoNotPostInsert<PROD>> maybe_inserter;
0275     maybe_inserter(&(wp->bareProduct()));
0276 
0277     putProducts()[index] = std::move(wp);
0278   }
0279 
0280   template <typename PROD>
0281   bool LuminosityBlock::getByLabel(std::string const& label, Handle<PROD>& result) const {
0282     return getByLabel(label, emptyString_, result);
0283   }
0284 
0285   template <typename PROD>
0286   bool LuminosityBlock::getByLabel(std::string const& label,
0287                                    std::string const& productInstanceName,
0288                                    Handle<PROD>& result) const {
0289     if (!provRecorder_.checkIfComplete<PROD>()) {
0290       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)), label, productInstanceName);
0291     }
0292     result.clear();
0293     BasicHandle bh = provRecorder_.getByLabel_(
0294         TypeID(typeid(PROD)), label, productInstanceName, emptyString_, moduleCallingContext_);
0295     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0296     if (result.failedToGet()) {
0297       return false;
0298     }
0299     return true;
0300   }
0301 
0302   /// same as above, but using the InputTag class
0303   template <typename PROD>
0304   bool LuminosityBlock::getByLabel(InputTag const& tag, Handle<PROD>& result) const {
0305     if (!provRecorder_.checkIfComplete<PROD>()) {
0306       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)), tag.label(), tag.instance());
0307     }
0308     result.clear();
0309     BasicHandle bh = provRecorder_.getByLabel_(TypeID(typeid(PROD)), tag, moduleCallingContext_);
0310     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0311     if (result.failedToGet()) {
0312       return false;
0313     }
0314     return true;
0315   }
0316 
0317   template <typename PROD>
0318   bool LuminosityBlock::getByToken(EDGetToken token, Handle<PROD>& result) const {
0319     if (!provRecorder_.checkIfComplete<PROD>()) {
0320       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)), token);
0321     }
0322     result.clear();
0323     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0324     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0325     if (result.failedToGet()) {
0326       return false;
0327     }
0328     return true;
0329   }
0330 
0331   template <typename PROD>
0332   bool LuminosityBlock::getByToken(EDGetTokenT<PROD> token, Handle<PROD>& result) const {
0333     if (!provRecorder_.checkIfComplete<PROD>()) {
0334       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)), token);
0335     }
0336     result.clear();
0337     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0338     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0339     if (result.failedToGet()) {
0340       return false;
0341     }
0342     return true;
0343   }
0344 
0345   template <typename PROD>
0346   Handle<PROD> LuminosityBlock::getHandle(EDGetTokenT<PROD> token) const {
0347     if UNLIKELY (!provRecorder_.checkIfComplete<PROD>()) {
0348       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)), token);
0349     }
0350     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0351     return convert_handle<PROD>(std::move(bh));
0352   }
0353 
0354   template <typename PROD>
0355   PROD const& LuminosityBlock::get(EDGetTokenT<PROD> token) const noexcept(false) {
0356     if UNLIKELY (!provRecorder_.checkIfComplete<PROD>()) {
0357       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)), token);
0358     }
0359     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0360     return *convert_handle<PROD>(std::move(bh));
0361   }
0362 
0363   // Free functions to retrieve a collection from the LuminosityBlock.
0364   // Will throw an exception if the collection is not available.
0365 
0366   template <typename T>
0367   T const& get(LuminosityBlock const& event, InputTag const& tag) {
0368     Handle<T> handle;
0369     event.getByLabel(tag, handle);
0370     // throw if the handle is not valid
0371     return *handle.product();
0372   }
0373 
0374   template <typename T>
0375   T const& get(LuminosityBlock const& event, EDGetToken const& token) {
0376     Handle<T> handle;
0377     event.getByToken(token, handle);
0378     // throw if the handle is not valid
0379     return *handle.product();
0380   }
0381 
0382   template <typename T>
0383   T const& get(LuminosityBlock const& event, EDGetTokenT<T> const& token) {
0384     Handle<T> handle;
0385     event.getByToken(token, handle);
0386     // throw if the handle is not valid
0387     return *handle.product();
0388   }
0389 
0390 }  // namespace edm
0391 
0392 #endif  // FWCore_Framework_LuminosityBlock_h