Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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