Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-06-28 02:52:56

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     template <typename PROD>
0105     void getManyByType(std::vector<Handle<PROD>>& results) const;
0106 
0107     Run const& getRun() const {
0108       if (not run_) {
0109         fillRun();
0110       }
0111       return run_.value();
0112     }
0113 
0114     ///Put a new product.
0115     template <typename PROD>
0116     void put(std::unique_ptr<PROD> product) {
0117       put<PROD>(std::move(product), std::string());
0118     }
0119 
0120     ///Put a new product with a 'product instance name'
0121     template <typename PROD>
0122     void put(std::unique_ptr<PROD> product, std::string const& productInstanceName);
0123 
0124     template <typename PROD>
0125     void put(EDPutToken token, std::unique_ptr<PROD> product);
0126 
0127     template <typename PROD>
0128     void put(EDPutTokenT<PROD> token, std::unique_ptr<PROD> product);
0129 
0130     ///puts a new product
0131     template <typename PROD, typename... Args>
0132     void emplace(EDPutTokenT<PROD> token, Args&&... args);
0133 
0134     template <typename PROD, typename... Args>
0135     void emplace(EDPutToken token, Args&&... args);
0136 
0137     Provenance const& getProvenance(BranchID const& theID) const;
0138 
0139     StableProvenance const& getStableProvenance(BranchID const& theID) const;
0140 
0141     void getAllStableProvenance(std::vector<StableProvenance const*>& provenances) const;
0142 
0143     ProcessHistoryID const& processHistoryID() const;
0144 
0145     ProcessHistory const& processHistory() const;
0146 
0147     ModuleCallingContext const* moduleCallingContext() const { return moduleCallingContext_; }
0148 
0149     void labelsForToken(EDGetToken const& iToken, ProductLabels& oLabels) const {
0150       provRecorder_.labelsForToken(iToken, oLabels);
0151     }
0152 
0153   private:
0154     LuminosityBlockPrincipal const& luminosityBlockPrincipal() const;
0155 
0156     // Override version from LuminosityBlockBase class
0157     BasicHandle getByLabelImpl(std::type_info const& iWrapperType,
0158                                std::type_info const& iProductType,
0159                                InputTag const& iTag) const final;
0160 
0161     template <typename PROD>
0162     void putImpl(EDPutToken::value_type token, std::unique_ptr<PROD> product);
0163 
0164     template <typename PROD, typename... Args>
0165     void emplaceImpl(EDPutToken::value_type token, Args&&... args);
0166 
0167     typedef std::vector<edm::propagate_const<std::unique_ptr<WrapperBase>>> ProductPtrVec;
0168     ProductPtrVec& putProducts() { return putProducts_; }
0169     ProductPtrVec const& putProducts() const { return putProducts_; }
0170 
0171     void fillRun() const;
0172 
0173     // commit_() is called to complete the transaction represented by
0174     // this PrincipalGetAdapter. The friendships required seems gross, but any
0175     // alternative is not great either.  Putting it into the
0176     // public interface is asking for trouble
0177     friend class RawInputSource;
0178     friend class ProducerBase;
0179     template <typename T>
0180     friend class stream::ProducingModuleAdaptorBase;
0181 
0182     void commit_(std::vector<edm::ProductResolverIndex> const& iShouldPut);
0183 
0184     PrincipalGetAdapter provRecorder_;
0185     ProductPtrVec putProducts_;
0186     LuminosityBlockAuxiliary const& aux_;
0187     //This class is intended to be used by only one thread
0188     CMS_SA_ALLOW mutable std::optional<Run> run_;
0189     ModuleCallingContext const* moduleCallingContext_;
0190 
0191     static const std::string emptyString_;
0192   };
0193 
0194   template <typename PROD>
0195   void LuminosityBlock::putImpl(EDPutToken::value_type index, std::unique_ptr<PROD> product) {
0196     // The following will call post_insert if T has such a function,
0197     // and do nothing if T has no such function.
0198     std::conditional_t<detail::has_postinsert<PROD>::value, DoPostInsert<PROD>, DoNotPostInsert<PROD>> maybe_inserter;
0199     maybe_inserter(product.get());
0200 
0201     assert(index < putProducts().size());
0202 
0203     std::unique_ptr<Wrapper<PROD>> wp(new Wrapper<PROD>(std::move(product)));
0204     putProducts()[index] = std::move(wp);
0205   }
0206 
0207   template <typename PROD>
0208   void LuminosityBlock::put(std::unique_ptr<PROD> product, std::string const& productInstanceName) {
0209     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0210       TypeID typeID(typeid(PROD));
0211       principal_get_adapter_detail::throwOnPutOfNullProduct("LuminosityBlock", typeID, productInstanceName);
0212     }
0213     auto index = provRecorder_.getPutTokenIndex(TypeID(*product), productInstanceName);
0214     putImpl(index, std::move(product));
0215   }
0216 
0217   template <typename PROD>
0218   void LuminosityBlock::put(EDPutTokenT<PROD> token, std::unique_ptr<PROD> product) {
0219     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0220       TypeID typeID(typeid(PROD));
0221       principal_get_adapter_detail::throwOnPutOfNullProduct(
0222           "LuminosityBlock", typeID, provRecorder_.productInstanceLabel(token));
0223     }
0224     if (UNLIKELY(token.isUninitialized())) {
0225       principal_get_adapter_detail::throwOnPutOfUninitializedToken("LuminosityBlock", typeid(PROD));
0226     }
0227     putImpl(token.index(), std::move(product));
0228   }
0229 
0230   template <typename PROD>
0231   void LuminosityBlock::put(EDPutToken token, std::unique_ptr<PROD> product) {
0232     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0233       TypeID typeID(typeid(PROD));
0234       principal_get_adapter_detail::throwOnPutOfNullProduct(
0235           "LuminosityBlock", typeID, provRecorder_.productInstanceLabel(token));
0236     }
0237     if (UNLIKELY(token.isUninitialized())) {
0238       principal_get_adapter_detail::throwOnPutOfUninitializedToken("LuminosityBlock", typeid(PROD));
0239     }
0240     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0241       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0242                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0243     }
0244 
0245     putImpl(token.index(), std::move(product));
0246   }
0247 
0248   template <typename PROD, typename... Args>
0249   void LuminosityBlock::emplace(EDPutTokenT<PROD> token, Args&&... args) {
0250     if (UNLIKELY(token.isUninitialized())) {
0251       principal_get_adapter_detail::throwOnPutOfUninitializedToken("LuminosityBlock", typeid(PROD));
0252     }
0253     emplaceImpl<PROD>(token.index(), std::forward<Args>(args)...);
0254   }
0255 
0256   template <typename PROD, typename... Args>
0257   void LuminosityBlock::emplace(EDPutToken token, Args&&... args) {
0258     if (UNLIKELY(token.isUninitialized())) {
0259       principal_get_adapter_detail::throwOnPutOfUninitializedToken("LuminosityBlock", typeid(PROD));
0260     }
0261     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0262       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0263                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0264     }
0265 
0266     emplaceImpl(token.index(), std::forward<Args>(args)...);
0267   }
0268 
0269   template <typename PROD, typename... Args>
0270   void LuminosityBlock::emplaceImpl(EDPutToken::value_type index, Args&&... args) {
0271     assert(index < putProducts().size());
0272 
0273     std::unique_ptr<Wrapper<PROD>> wp(new Wrapper<PROD>(WrapperBase::Emplace{}, std::forward<Args>(args)...));
0274 
0275     // The following will call post_insert if T has such a function,
0276     // and do nothing if T has no such function.
0277     std::conditional_t<detail::has_postinsert<PROD>::value, DoPostInsert<PROD>, DoNotPostInsert<PROD>> maybe_inserter;
0278     maybe_inserter(&(wp->bareProduct()));
0279 
0280     putProducts()[index] = std::move(wp);
0281   }
0282 
0283   template <typename PROD>
0284   bool LuminosityBlock::getByLabel(std::string const& label, Handle<PROD>& result) const {
0285     return getByLabel(label, emptyString_, result);
0286   }
0287 
0288   template <typename PROD>
0289   bool LuminosityBlock::getByLabel(std::string const& label,
0290                                    std::string const& productInstanceName,
0291                                    Handle<PROD>& result) const {
0292     if (!provRecorder_.checkIfComplete<PROD>()) {
0293       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)), label, productInstanceName);
0294     }
0295     result.clear();
0296     BasicHandle bh = provRecorder_.getByLabel_(
0297         TypeID(typeid(PROD)), label, productInstanceName, emptyString_, moduleCallingContext_);
0298     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0299     if (result.failedToGet()) {
0300       return false;
0301     }
0302     return true;
0303   }
0304 
0305   /// same as above, but using the InputTag class
0306   template <typename PROD>
0307   bool LuminosityBlock::getByLabel(InputTag const& tag, Handle<PROD>& result) const {
0308     if (!provRecorder_.checkIfComplete<PROD>()) {
0309       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)), tag.label(), tag.instance());
0310     }
0311     result.clear();
0312     BasicHandle bh = provRecorder_.getByLabel_(TypeID(typeid(PROD)), tag, moduleCallingContext_);
0313     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0314     if (result.failedToGet()) {
0315       return false;
0316     }
0317     return true;
0318   }
0319 
0320   template <typename PROD>
0321   bool LuminosityBlock::getByToken(EDGetToken token, Handle<PROD>& result) const {
0322     if (!provRecorder_.checkIfComplete<PROD>()) {
0323       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)), token);
0324     }
0325     result.clear();
0326     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0327     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0328     if (result.failedToGet()) {
0329       return false;
0330     }
0331     return true;
0332   }
0333 
0334   template <typename PROD>
0335   bool LuminosityBlock::getByToken(EDGetTokenT<PROD> token, Handle<PROD>& result) const {
0336     if (!provRecorder_.checkIfComplete<PROD>()) {
0337       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)), token);
0338     }
0339     result.clear();
0340     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0341     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0342     if (result.failedToGet()) {
0343       return false;
0344     }
0345     return true;
0346   }
0347 
0348   template <typename PROD>
0349   Handle<PROD> LuminosityBlock::getHandle(EDGetTokenT<PROD> token) const {
0350     if UNLIKELY (!provRecorder_.checkIfComplete<PROD>()) {
0351       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)), token);
0352     }
0353     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0354     return convert_handle<PROD>(std::move(bh));
0355   }
0356 
0357   template <typename PROD>
0358   PROD const& LuminosityBlock::get(EDGetTokenT<PROD> token) const noexcept(false) {
0359     if UNLIKELY (!provRecorder_.checkIfComplete<PROD>()) {
0360       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)), token);
0361     }
0362     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0363     return *convert_handle<PROD>(std::move(bh));
0364   }
0365 
0366   template <typename PROD>
0367   void LuminosityBlock::getManyByType(std::vector<Handle<PROD>>& results) const {
0368     if (!provRecorder_.checkIfComplete<PROD>()) {
0369       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)));
0370     }
0371     return provRecorder_.getManyByType(results, moduleCallingContext_);
0372   }
0373 
0374   // Free functions to retrieve a collection from the LuminosityBlock.
0375   // Will throw an exception if the collection is not available.
0376 
0377   template <typename T>
0378   T const& get(LuminosityBlock const& event, InputTag const& tag) {
0379     Handle<T> handle;
0380     event.getByLabel(tag, handle);
0381     // throw if the handle is not valid
0382     return *handle.product();
0383   }
0384 
0385   template <typename T>
0386   T const& get(LuminosityBlock const& event, EDGetToken const& token) {
0387     Handle<T> handle;
0388     event.getByToken(token, handle);
0389     // throw if the handle is not valid
0390     return *handle.product();
0391   }
0392 
0393   template <typename T>
0394   T const& get(LuminosityBlock const& event, EDGetTokenT<T> const& token) {
0395     Handle<T> handle;
0396     event.getByToken(token, handle);
0397     // throw if the handle is not valid
0398     return *handle.product();
0399   }
0400 
0401 }  // namespace edm
0402 
0403 #endif  // FWCore_Framework_LuminosityBlock_h