Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef FWCore_Framework_Run_h
0002 #define FWCore_Framework_Run_h
0003 
0004 // -*- C++ -*-
0005 //
0006 // Package:     Framework
0007 // Class  :     Run
0008 //
0009 /**\class Run Run.h FWCore/Framework/interface/Run.h
0010 
0011 Description: This is the primary interface for accessing per run EDProducts and inserting new derived products.
0012 
0013 For its usage, see "FWCore/Framework/interface/PrincipalGetAdapter.h"
0014 
0015 */
0016 /*----------------------------------------------------------------------
0017 
0018 ----------------------------------------------------------------------*/
0019 
0020 #include "DataFormats/Common/interface/Wrapper.h"
0021 #include "FWCore/Framework/interface/PrincipalGetAdapter.h"
0022 #include "FWCore/Framework/interface/Frameworkfwd.h"
0023 #include "FWCore/Common/interface/RunBase.h"
0024 #include "FWCore/Utilities/interface/EDGetToken.h"
0025 #include "FWCore/Utilities/interface/EDPutToken.h"
0026 #include "FWCore/Utilities/interface/ProductKindOfType.h"
0027 #include "FWCore/Utilities/interface/RunIndex.h"
0028 #include "FWCore/Utilities/interface/Likely.h"
0029 
0030 #include <memory>
0031 #include <string>
0032 #include <typeinfo>
0033 #include <vector>
0034 
0035 namespace edm {
0036   class ModuleCallingContext;
0037   class ProducerBase;
0038   class SharedResourcesAcquirer;
0039 
0040   namespace stream {
0041     template <typename T>
0042     class ProducingModuleAdaptorBase;
0043   }
0044 
0045   class Run : public RunBase {
0046   public:
0047     Run(RunTransitionInfo const&, ModuleDescription const&, ModuleCallingContext const*, bool isAtEnd);
0048     Run(RunPrincipal const&, ModuleDescription const&, ModuleCallingContext const*, bool isAtEnd);
0049     ~Run() override;
0050 
0051     //Used in conjunction with EDGetToken
0052     void setConsumer(EDConsumerBase const* iConsumer) { provRecorder_.setConsumer(iConsumer); }
0053 
0054     void setSharedResourcesAcquirer(SharedResourcesAcquirer* iResourceAcquirer) {
0055       provRecorder_.setSharedResourcesAcquirer(iResourceAcquirer);
0056     }
0057 
0058     void setProducer(ProducerBase const* iProducer);
0059 
0060     typedef PrincipalGetAdapter Base;
0061     // AUX functions are defined in RunBase
0062     RunAuxiliary const& runAuxiliary() const final;
0063     // AUX functions.
0064     //     RunID const& id() const {return aux_.id();}
0065     //     RunNumber_t run() const {return aux_.run();}
0066     //     Timestamp const& beginTime() const {return aux_.beginTime();}
0067     //     Timestamp const& endTime() const {return aux_.endTime();}
0068 
0069     /**\return Reusable index which can be used to separate data for different simultaneous Runs.
0070      */
0071     RunIndex index() const;
0072 
0073     /**If you are caching data from the Run, you should also keep
0074      this number.  If this number changes then you know that
0075      the data you have cached is invalid.
0076      The value of '0' will never be returned so you can use that to
0077      denote that you have not yet checked the value.
0078      */
0079     typedef unsigned long CacheIdentifier_t;
0080     CacheIdentifier_t cacheIdentifier() const;
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     ///Put a new product.
0105     template <typename PROD>
0106     void put(std::unique_ptr<PROD> product) {
0107       put<PROD>(std::move(product), std::string());
0108     }
0109 
0110     ///Put a new product with a 'product instance name'
0111     template <typename PROD>
0112     void put(std::unique_ptr<PROD> product, std::string const& productInstanceName);
0113 
0114     template <typename PROD>
0115     void put(EDPutToken token, std::unique_ptr<PROD> product);
0116 
0117     template <typename PROD>
0118     void put(EDPutTokenT<PROD> token, std::unique_ptr<PROD> product);
0119 
0120     ///puts a new product
0121     template <typename PROD, typename... Args>
0122     void emplace(EDPutTokenT<PROD> token, Args&&... args);
0123 
0124     template <typename PROD, typename... Args>
0125     void emplace(EDPutToken token, Args&&... args);
0126 
0127     Provenance const& getProvenance(BranchID const& theID) const;
0128 
0129     StableProvenance const& getStableProvenance(BranchID const& theID) const;
0130 
0131     void getAllStableProvenance(std::vector<StableProvenance const*>& provenances) const;
0132 
0133     // Return true if this Run has been subjected to a process with
0134     // the given processName, and false otherwise.
0135     // If true is returned, then ps is filled with the ParameterSets
0136     // (possibly more than one) used to configure the identified
0137     // process(es). Equivalent ParameterSets are compressed out of the
0138     // result.
0139     // This function is not yet implemented in full.
0140     //bool
0141     //getProcessParameterSet(std::string const& processName, std::vector<ParameterSet>& ps) 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     RunPrincipal const& runPrincipal() const;
0155 
0156     // Override version from RunBase 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     // commit_() is called to complete the transaction represented by
0172     // this PrincipalGetAdapter. The friendships required seems gross, but any
0173     // alternative is not great either.  Putting it into the
0174     // public interface is asking for trouble
0175     friend class RawInputSource;
0176     friend class ProducerBase;
0177     template <typename T>
0178     friend class stream::ProducingModuleAdaptorBase;
0179 
0180     void commit_(std::vector<edm::ProductResolverIndex> const& iShouldPut);
0181 
0182     PrincipalGetAdapter provRecorder_;
0183     ProductPtrVec putProducts_;
0184     RunAuxiliary const& aux_;
0185     ModuleCallingContext const* moduleCallingContext_;
0186     SharedResourcesAcquirer*
0187         sharedResourcesAcquirer_;  // We do not use propagate_const because the acquirer is itself mutable.
0188 
0189     static const std::string emptyString_;
0190   };
0191 
0192   template <typename PROD>
0193   void Run::putImpl(EDPutToken::value_type index, std::unique_ptr<PROD> product) {
0194     // The following will call post_insert if T has such a function,
0195     // and do nothing if T has no such function.
0196     std::conditional_t<detail::has_postinsert<PROD>::value, DoPostInsert<PROD>, DoNotPostInsert<PROD>> maybe_inserter;
0197     maybe_inserter(product.get());
0198 
0199     assert(index < putProducts().size());
0200 
0201     std::unique_ptr<Wrapper<PROD>> wp(new Wrapper<PROD>(std::move(product)));
0202     putProducts()[index] = std::move(wp);
0203   }
0204 
0205   template <typename PROD>
0206   void Run::put(std::unique_ptr<PROD> product, std::string const& productInstanceName) {
0207     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0208       TypeID typeID(typeid(PROD));
0209       principal_get_adapter_detail::throwOnPutOfNullProduct("Run", typeID, productInstanceName);
0210     }
0211     auto index = provRecorder_.getPutTokenIndex(TypeID(*product), productInstanceName);
0212     putImpl(index, std::move(product));
0213   }
0214 
0215   template <typename PROD>
0216   void Run::put(EDPutTokenT<PROD> token, std::unique_ptr<PROD> product) {
0217     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0218       TypeID typeID(typeid(PROD));
0219       principal_get_adapter_detail::throwOnPutOfNullProduct("Run", typeID, provRecorder_.productInstanceLabel(token));
0220     }
0221     if (UNLIKELY(token.isUninitialized())) {
0222       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Run", typeid(PROD));
0223     }
0224     putImpl(token.index(), std::move(product));
0225   }
0226 
0227   template <typename PROD>
0228   void Run::put(EDPutToken token, std::unique_ptr<PROD> product) {
0229     if (UNLIKELY(product.get() == 0)) {  // null pointer is illegal
0230       TypeID typeID(typeid(PROD));
0231       principal_get_adapter_detail::throwOnPutOfNullProduct("Run", typeID, provRecorder_.productInstanceLabel(token));
0232     }
0233     if (UNLIKELY(token.isUninitialized())) {
0234       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Run", 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 Run::emplace(EDPutTokenT<PROD> token, Args&&... args) {
0246     if (UNLIKELY(token.isUninitialized())) {
0247       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Run", typeid(PROD));
0248     }
0249     emplaceImpl<PROD>(token.index(), std::forward<Args>(args)...);
0250   }
0251 
0252   template <typename PROD, typename... Args>
0253   void Run::emplace(EDPutToken token, Args&&... args) {
0254     if (UNLIKELY(token.isUninitialized())) {
0255       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Run", 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 Run::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     std::conditional_t<detail::has_postinsert<PROD>::value, DoPostInsert<PROD>, DoNotPostInsert<PROD>> maybe_inserter;
0274     maybe_inserter(&(wp->bareProduct()));
0275 
0276     putProducts()[index] = std::move(wp);
0277   }
0278 
0279   template <typename PROD>
0280   bool Run::getByLabel(std::string const& label, Handle<PROD>& result) const {
0281     return getByLabel(label, emptyString_, result);
0282   }
0283 
0284   template <typename PROD>
0285   bool Run::getByLabel(std::string const& label, std::string const& productInstanceName, Handle<PROD>& result) const {
0286     if (!provRecorder_.checkIfComplete<PROD>()) {
0287       principal_get_adapter_detail::throwOnPrematureRead("Run", TypeID(typeid(PROD)), label, productInstanceName);
0288     }
0289     result.clear();
0290     BasicHandle bh = provRecorder_.getByLabel_(
0291         TypeID(typeid(PROD)), label, productInstanceName, emptyString_, moduleCallingContext_);
0292     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0293     if (result.failedToGet()) {
0294       return false;
0295     }
0296     return true;
0297   }
0298 
0299   /// same as above, but using the InputTag class
0300   template <typename PROD>
0301   bool Run::getByLabel(InputTag const& tag, Handle<PROD>& result) const {
0302     if (!provRecorder_.checkIfComplete<PROD>()) {
0303       principal_get_adapter_detail::throwOnPrematureRead("Run", TypeID(typeid(PROD)), tag.label(), tag.instance());
0304     }
0305     result.clear();
0306     BasicHandle bh = provRecorder_.getByLabel_(TypeID(typeid(PROD)), tag, moduleCallingContext_);
0307     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0308     if (result.failedToGet()) {
0309       return false;
0310     }
0311     return true;
0312   }
0313 
0314   template <typename PROD>
0315   bool Run::getByToken(EDGetToken token, Handle<PROD>& result) const {
0316     if (!provRecorder_.checkIfComplete<PROD>()) {
0317       principal_get_adapter_detail::throwOnPrematureRead("Run", TypeID(typeid(PROD)), token);
0318     }
0319     result.clear();
0320     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0321     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0322     if (result.failedToGet()) {
0323       return false;
0324     }
0325     return true;
0326   }
0327 
0328   template <typename PROD>
0329   bool Run::getByToken(EDGetTokenT<PROD> token, Handle<PROD>& result) const {
0330     if (!provRecorder_.checkIfComplete<PROD>()) {
0331       principal_get_adapter_detail::throwOnPrematureRead("Run", TypeID(typeid(PROD)), token);
0332     }
0333     result.clear();
0334     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0335     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0336     if (result.failedToGet()) {
0337       return false;
0338     }
0339     return true;
0340   }
0341 
0342   template <typename PROD>
0343   Handle<PROD> Run::getHandle(EDGetTokenT<PROD> token) const {
0344     if (!provRecorder_.checkIfComplete<PROD>()) {
0345       principal_get_adapter_detail::throwOnPrematureRead("Run", TypeID(typeid(PROD)), token);
0346     }
0347     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0348     return convert_handle<PROD>(std::move(bh));
0349   }
0350 
0351   template <typename PROD>
0352   PROD const& Run::get(EDGetTokenT<PROD> token) const noexcept(false) {
0353     if (!provRecorder_.checkIfComplete<PROD>()) {
0354       principal_get_adapter_detail::throwOnPrematureRead("Run", TypeID(typeid(PROD)), token);
0355     }
0356     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0357     return *convert_handle<PROD>(std::move(bh));
0358   }
0359 
0360   // Free functions to retrieve a collection from the Run.
0361   // Will throw an exception if the collection is not available.
0362 
0363   template <typename T>
0364   T const& get(Run const& event, InputTag const& tag) {
0365     Handle<T> handle;
0366     event.getByLabel(tag, handle);
0367     // throw if the handle is not valid
0368     return *handle.product();
0369   }
0370 
0371   template <typename T>
0372   T const& get(Run const& event, EDGetToken const& token) {
0373     Handle<T> handle;
0374     event.getByToken(token, handle);
0375     // throw if the handle is not valid
0376     return *handle.product();
0377   }
0378 
0379   template <typename T>
0380   T const& get(Run const& event, EDGetTokenT<T> const& token) {
0381     Handle<T> handle;
0382     event.getByToken(token, handle);
0383     // throw if the handle is not valid
0384     return *handle.product();
0385   }
0386 
0387 }  // namespace edm
0388 
0389 #endif  // FWCore_Framework_Run_h