Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-08-22 04:57:37

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     detail::do_post_insert_if_available(*product.get());
0196 
0197     assert(index < putProducts().size());
0198 
0199     std::unique_ptr<Wrapper<PROD>> wp(new Wrapper<PROD>(std::move(product)));
0200     putProducts()[index] = std::move(wp);
0201   }
0202 
0203   template <typename PROD>
0204   void LuminosityBlock::put(std::unique_ptr<PROD> product, std::string const& productInstanceName) {
0205     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0206       TypeID typeID(typeid(PROD));
0207       principal_get_adapter_detail::throwOnPutOfNullProduct("LuminosityBlock", typeID, productInstanceName);
0208     }
0209     auto index = provRecorder_.getPutTokenIndex(TypeID(*product), productInstanceName);
0210     putImpl(index, std::move(product));
0211   }
0212 
0213   template <typename PROD>
0214   void LuminosityBlock::put(EDPutTokenT<PROD> token, std::unique_ptr<PROD> product) {
0215     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0216       TypeID typeID(typeid(PROD));
0217       principal_get_adapter_detail::throwOnPutOfNullProduct(
0218           "LuminosityBlock", typeID, provRecorder_.productInstanceLabel(token));
0219     }
0220     if (UNLIKELY(token.isUninitialized())) {
0221       principal_get_adapter_detail::throwOnPutOfUninitializedToken("LuminosityBlock", typeid(PROD));
0222     }
0223     putImpl(token.index(), std::move(product));
0224   }
0225 
0226   template <typename PROD>
0227   void LuminosityBlock::put(EDPutToken token, std::unique_ptr<PROD> product) {
0228     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0229       TypeID typeID(typeid(PROD));
0230       principal_get_adapter_detail::throwOnPutOfNullProduct(
0231           "LuminosityBlock", typeID, provRecorder_.productInstanceLabel(token));
0232     }
0233     if (UNLIKELY(token.isUninitialized())) {
0234       principal_get_adapter_detail::throwOnPutOfUninitializedToken("LuminosityBlock", typeid(PROD));
0235     }
0236     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0237       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0238                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0239     }
0240 
0241     putImpl(token.index(), std::move(product));
0242   }
0243 
0244   template <typename PROD, typename... Args>
0245   void LuminosityBlock::emplace(EDPutTokenT<PROD> token, Args&&... args) {
0246     if (UNLIKELY(token.isUninitialized())) {
0247       principal_get_adapter_detail::throwOnPutOfUninitializedToken("LuminosityBlock", typeid(PROD));
0248     }
0249     emplaceImpl<PROD>(token.index(), std::forward<Args>(args)...);
0250   }
0251 
0252   template <typename PROD, typename... Args>
0253   void LuminosityBlock::emplace(EDPutToken token, Args&&... args) {
0254     if (UNLIKELY(token.isUninitialized())) {
0255       principal_get_adapter_detail::throwOnPutOfUninitializedToken("LuminosityBlock", typeid(PROD));
0256     }
0257     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0258       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0259                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0260     }
0261 
0262     emplaceImpl(token.index(), std::forward<Args>(args)...);
0263   }
0264 
0265   template <typename PROD, typename... Args>
0266   void LuminosityBlock::emplaceImpl(EDPutToken::value_type index, Args&&... args) {
0267     assert(index < putProducts().size());
0268 
0269     std::unique_ptr<Wrapper<PROD>> wp(new Wrapper<PROD>(WrapperBase::Emplace{}, std::forward<Args>(args)...));
0270 
0271     // The following will call post_insert if T has such a function,
0272     // and do nothing if T has no such function.
0273     detail::do_post_insert_if_available(wp->bareProduct());
0274 
0275     putProducts()[index] = std::move(wp);
0276   }
0277 
0278   template <typename PROD>
0279   bool LuminosityBlock::getByLabel(std::string const& label, Handle<PROD>& result) const {
0280     return getByLabel(label, emptyString_, result);
0281   }
0282 
0283   template <typename PROD>
0284   bool LuminosityBlock::getByLabel(std::string const& label,
0285                                    std::string const& productInstanceName,
0286                                    Handle<PROD>& result) const {
0287     if (!provRecorder_.checkIfComplete<PROD>()) {
0288       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)), label, productInstanceName);
0289     }
0290     result.clear();
0291     BasicHandle bh = provRecorder_.getByLabel_(
0292         TypeID(typeid(PROD)), label, productInstanceName, emptyString_, moduleCallingContext_);
0293     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0294     if (result.failedToGet()) {
0295       return false;
0296     }
0297     return true;
0298   }
0299 
0300   /// same as above, but using the InputTag class
0301   template <typename PROD>
0302   bool LuminosityBlock::getByLabel(InputTag const& tag, Handle<PROD>& result) const {
0303     if (!provRecorder_.checkIfComplete<PROD>()) {
0304       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)), tag.label(), tag.instance());
0305     }
0306     result.clear();
0307     BasicHandle bh = provRecorder_.getByLabel_(TypeID(typeid(PROD)), tag, moduleCallingContext_);
0308     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0309     if (result.failedToGet()) {
0310       return false;
0311     }
0312     return true;
0313   }
0314 
0315   template <typename PROD>
0316   bool LuminosityBlock::getByToken(EDGetToken token, Handle<PROD>& result) const {
0317     if (!provRecorder_.checkIfComplete<PROD>()) {
0318       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)), token);
0319     }
0320     result.clear();
0321     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0322     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0323     if (result.failedToGet()) {
0324       return false;
0325     }
0326     return true;
0327   }
0328 
0329   template <typename PROD>
0330   bool LuminosityBlock::getByToken(EDGetTokenT<PROD> token, Handle<PROD>& result) const {
0331     if (!provRecorder_.checkIfComplete<PROD>()) {
0332       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)), token);
0333     }
0334     result.clear();
0335     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0336     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0337     if (result.failedToGet()) {
0338       return false;
0339     }
0340     return true;
0341   }
0342 
0343   template <typename PROD>
0344   Handle<PROD> LuminosityBlock::getHandle(EDGetTokenT<PROD> token) const {
0345     if UNLIKELY (!provRecorder_.checkIfComplete<PROD>()) {
0346       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)), token);
0347     }
0348     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0349     return convert_handle<PROD>(std::move(bh));
0350   }
0351 
0352   template <typename PROD>
0353   PROD const& LuminosityBlock::get(EDGetTokenT<PROD> token) const noexcept(false) {
0354     if UNLIKELY (!provRecorder_.checkIfComplete<PROD>()) {
0355       principal_get_adapter_detail::throwOnPrematureRead("Lumi", TypeID(typeid(PROD)), token);
0356     }
0357     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0358     return *convert_handle<PROD>(std::move(bh));
0359   }
0360 
0361   // Free functions to retrieve a collection from the LuminosityBlock.
0362   // Will throw an exception if the collection is not available.
0363 
0364   template <typename T>
0365   T const& get(LuminosityBlock const& event, InputTag const& tag) {
0366     Handle<T> handle;
0367     event.getByLabel(tag, handle);
0368     // throw if the handle is not valid
0369     return *handle.product();
0370   }
0371 
0372   template <typename T>
0373   T const& get(LuminosityBlock const& event, EDGetToken const& token) {
0374     Handle<T> handle;
0375     event.getByToken(token, handle);
0376     // throw if the handle is not valid
0377     return *handle.product();
0378   }
0379 
0380   template <typename T>
0381   T const& get(LuminosityBlock const& event, EDGetTokenT<T> const& token) {
0382     Handle<T> handle;
0383     event.getByToken(token, handle);
0384     // throw if the handle is not valid
0385     return *handle.product();
0386   }
0387 
0388 }  // namespace edm
0389 
0390 #endif  // FWCore_Framework_LuminosityBlock_h