Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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     template <typename PROD>
0105     void getManyByType(std::vector<Handle<PROD>>& results) const;
0106 
0107     ///Put a new product.
0108     template <typename PROD>
0109     void put(std::unique_ptr<PROD> product) {
0110       put<PROD>(std::move(product), std::string());
0111     }
0112 
0113     ///Put a new product with a 'product instance name'
0114     template <typename PROD>
0115     void put(std::unique_ptr<PROD> product, std::string const& productInstanceName);
0116 
0117     template <typename PROD>
0118     void put(EDPutToken token, std::unique_ptr<PROD> product);
0119 
0120     template <typename PROD>
0121     void put(EDPutTokenT<PROD> token, std::unique_ptr<PROD> product);
0122 
0123     ///puts a new product
0124     template <typename PROD, typename... Args>
0125     void emplace(EDPutTokenT<PROD> token, Args&&... args);
0126 
0127     template <typename PROD, typename... Args>
0128     void emplace(EDPutToken token, Args&&... args);
0129 
0130     Provenance const& getProvenance(BranchID const& theID) const;
0131 
0132     StableProvenance const& getStableProvenance(BranchID const& theID) const;
0133 
0134     void getAllStableProvenance(std::vector<StableProvenance const*>& provenances) const;
0135 
0136     // Return true if this Run has been subjected to a process with
0137     // the given processName, and false otherwise.
0138     // If true is returned, then ps is filled with the ParameterSets
0139     // (possibly more than one) used to configure the identified
0140     // process(es). Equivalent ParameterSets are compressed out of the
0141     // result.
0142     // This function is not yet implemented in full.
0143     //bool
0144     //getProcessParameterSet(std::string const& processName, std::vector<ParameterSet>& ps) const;
0145 
0146     ProcessHistoryID const& processHistoryID() const;
0147 
0148     ProcessHistory const& processHistory() const;
0149 
0150     ModuleCallingContext const* moduleCallingContext() const { return moduleCallingContext_; }
0151 
0152     void labelsForToken(EDGetToken const& iToken, ProductLabels& oLabels) const {
0153       provRecorder_.labelsForToken(iToken, oLabels);
0154     }
0155 
0156   private:
0157     RunPrincipal const& runPrincipal() const;
0158 
0159     // Override version from RunBase class
0160     BasicHandle getByLabelImpl(std::type_info const& iWrapperType,
0161                                std::type_info const& iProductType,
0162                                InputTag const& iTag) const final;
0163 
0164     template <typename PROD>
0165     void putImpl(EDPutToken::value_type token, std::unique_ptr<PROD> product);
0166 
0167     template <typename PROD, typename... Args>
0168     void emplaceImpl(EDPutToken::value_type token, Args&&... args);
0169 
0170     typedef std::vector<edm::propagate_const<std::unique_ptr<WrapperBase>>> ProductPtrVec;
0171     ProductPtrVec& putProducts() { return putProducts_; }
0172     ProductPtrVec const& putProducts() const { return putProducts_; }
0173 
0174     // commit_() is called to complete the transaction represented by
0175     // this PrincipalGetAdapter. The friendships required seems gross, but any
0176     // alternative is not great either.  Putting it into the
0177     // public interface is asking for trouble
0178     friend class RawInputSource;
0179     friend class ProducerBase;
0180     template <typename T>
0181     friend class stream::ProducingModuleAdaptorBase;
0182 
0183     void commit_(std::vector<edm::ProductResolverIndex> const& iShouldPut);
0184 
0185     PrincipalGetAdapter provRecorder_;
0186     ProductPtrVec putProducts_;
0187     RunAuxiliary const& aux_;
0188     ModuleCallingContext const* moduleCallingContext_;
0189     SharedResourcesAcquirer*
0190         sharedResourcesAcquirer_;  // We do not use propagate_const because the acquirer is itself mutable.
0191 
0192     static const std::string emptyString_;
0193   };
0194 
0195   template <typename PROD>
0196   void Run::putImpl(EDPutToken::value_type index, std::unique_ptr<PROD> product) {
0197     // The following will call post_insert if T has such a function,
0198     // and do nothing if T has no such function.
0199     std::conditional_t<detail::has_postinsert<PROD>::value, DoPostInsert<PROD>, DoNotPostInsert<PROD>> maybe_inserter;
0200     maybe_inserter(product.get());
0201 
0202     assert(index < putProducts().size());
0203 
0204     std::unique_ptr<Wrapper<PROD>> wp(new Wrapper<PROD>(std::move(product)));
0205     putProducts()[index] = std::move(wp);
0206   }
0207 
0208   template <typename PROD>
0209   void Run::put(std::unique_ptr<PROD> product, std::string const& productInstanceName) {
0210     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0211       TypeID typeID(typeid(PROD));
0212       principal_get_adapter_detail::throwOnPutOfNullProduct("Run", typeID, productInstanceName);
0213     }
0214     auto index = provRecorder_.getPutTokenIndex(TypeID(*product), productInstanceName);
0215     putImpl(index, std::move(product));
0216   }
0217 
0218   template <typename PROD>
0219   void Run::put(EDPutTokenT<PROD> token, std::unique_ptr<PROD> product) {
0220     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0221       TypeID typeID(typeid(PROD));
0222       principal_get_adapter_detail::throwOnPutOfNullProduct("Run", typeID, provRecorder_.productInstanceLabel(token));
0223     }
0224     if (UNLIKELY(token.isUninitialized())) {
0225       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Run", typeid(PROD));
0226     }
0227     putImpl(token.index(), std::move(product));
0228   }
0229 
0230   template <typename PROD>
0231   void Run::put(EDPutToken token, std::unique_ptr<PROD> product) {
0232     if (UNLIKELY(product.get() == 0)) {  // null pointer is illegal
0233       TypeID typeID(typeid(PROD));
0234       principal_get_adapter_detail::throwOnPutOfNullProduct("Run", typeID, provRecorder_.productInstanceLabel(token));
0235     }
0236     if (UNLIKELY(token.isUninitialized())) {
0237       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Run", typeid(PROD));
0238     }
0239     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0240       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0241                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0242     }
0243 
0244     putImpl(token.index(), std::move(product));
0245   }
0246 
0247   template <typename PROD, typename... Args>
0248   void Run::emplace(EDPutTokenT<PROD> token, Args&&... args) {
0249     if (UNLIKELY(token.isUninitialized())) {
0250       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Run", typeid(PROD));
0251     }
0252     emplaceImpl<PROD>(token.index(), std::forward<Args>(args)...);
0253   }
0254 
0255   template <typename PROD, typename... Args>
0256   void Run::emplace(EDPutToken token, Args&&... args) {
0257     if (UNLIKELY(token.isUninitialized())) {
0258       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Run", typeid(PROD));
0259     }
0260     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0261       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0262                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0263     }
0264 
0265     emplaceImpl(token.index(), std::forward<Args>(args)...);
0266   }
0267 
0268   template <typename PROD, typename... Args>
0269   void Run::emplaceImpl(EDPutToken::value_type index, Args&&... args) {
0270     assert(index < putProducts().size());
0271 
0272     std::unique_ptr<Wrapper<PROD>> wp(new Wrapper<PROD>(WrapperBase::Emplace{}, std::forward<Args>(args)...));
0273 
0274     // The following will call post_insert if T has such a function,
0275     // and do nothing if T has no such function.
0276     std::conditional_t<detail::has_postinsert<PROD>::value, DoPostInsert<PROD>, DoNotPostInsert<PROD>> maybe_inserter;
0277     maybe_inserter(&(wp->bareProduct()));
0278 
0279     putProducts()[index] = std::move(wp);
0280   }
0281 
0282   template <typename PROD>
0283   bool Run::getByLabel(std::string const& label, Handle<PROD>& result) const {
0284     return getByLabel(label, emptyString_, result);
0285   }
0286 
0287   template <typename PROD>
0288   bool Run::getByLabel(std::string const& label, std::string const& productInstanceName, Handle<PROD>& result) const {
0289     if (!provRecorder_.checkIfComplete<PROD>()) {
0290       principal_get_adapter_detail::throwOnPrematureRead("Run", 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 Run::getByLabel(InputTag const& tag, Handle<PROD>& result) const {
0305     if (!provRecorder_.checkIfComplete<PROD>()) {
0306       principal_get_adapter_detail::throwOnPrematureRead("Run", 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 Run::getByToken(EDGetToken token, Handle<PROD>& result) const {
0319     if (!provRecorder_.checkIfComplete<PROD>()) {
0320       principal_get_adapter_detail::throwOnPrematureRead("Run", 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 Run::getByToken(EDGetTokenT<PROD> token, Handle<PROD>& result) const {
0333     if (!provRecorder_.checkIfComplete<PROD>()) {
0334       principal_get_adapter_detail::throwOnPrematureRead("Run", 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> Run::getHandle(EDGetTokenT<PROD> token) const {
0347     if (!provRecorder_.checkIfComplete<PROD>()) {
0348       principal_get_adapter_detail::throwOnPrematureRead("Run", 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& Run::get(EDGetTokenT<PROD> token) const noexcept(false) {
0356     if (!provRecorder_.checkIfComplete<PROD>()) {
0357       principal_get_adapter_detail::throwOnPrematureRead("Run", 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   template <typename PROD>
0364   void Run::getManyByType(std::vector<Handle<PROD>>& results) const {
0365     if (!provRecorder_.checkIfComplete<PROD>()) {
0366       principal_get_adapter_detail::throwOnPrematureRead("Run", TypeID(typeid(PROD)));
0367     }
0368     return provRecorder_.getManyByType(results, moduleCallingContext_);
0369   }
0370 
0371   // Free functions to retrieve a collection from the Run.
0372   // Will throw an exception if the collection is not available.
0373 
0374   template <typename T>
0375   T const& get(Run const& event, InputTag const& tag) {
0376     Handle<T> handle;
0377     event.getByLabel(tag, handle);
0378     // throw if the handle is not valid
0379     return *handle.product();
0380   }
0381 
0382   template <typename T>
0383   T const& get(Run const& event, EDGetToken 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   template <typename T>
0391   T const& get(Run const& event, EDGetTokenT<T> const& token) {
0392     Handle<T> handle;
0393     event.getByToken(token, handle);
0394     // throw if the handle is not valid
0395     return *handle.product();
0396   }
0397 
0398 }  // namespace edm
0399 
0400 #endif  // FWCore_Framework_Run_h