Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef FWCore_Framework_Event_h
0002 #define FWCore_Framework_Event_h
0003 
0004 // -*- C++ -*-
0005 //
0006 // Package:     Framework
0007 // Class  :     Event
0008 //
0009 /**\class Event Event.h FWCore/Framework/interface/Event.h
0010 
0011 Description: This is the primary interface for accessing EDProducts
0012 from a single collision and inserting new derived products.
0013 
0014 For its usage, see "FWCore/Framework/interface/PrincipalGetAdapter.h"
0015 
0016 */
0017 /*----------------------------------------------------------------------
0018 ----------------------------------------------------------------------*/
0019 
0020 #include "DataFormats/Common/interface/BasicHandle.h"
0021 #include "DataFormats/Common/interface/ConvertHandle.h"
0022 #include "DataFormats/Common/interface/Handle.h"
0023 #include "DataFormats/Common/interface/OrphanHandle.h"
0024 #include "DataFormats/Common/interface/Wrapper.h"
0025 #include "DataFormats/Common/interface/FillViewHelperVector.h"
0026 #include "DataFormats/Common/interface/FunctorHandleExceptionFactory.h"
0027 
0028 #include "DataFormats/Provenance/interface/EventID.h"
0029 #include "DataFormats/Provenance/interface/EventSelectionID.h"
0030 #include "DataFormats/Provenance/interface/ProductID.h"
0031 #include "DataFormats/Provenance/interface/RunID.h"
0032 
0033 #include "FWCore/Common/interface/EventBase.h"
0034 #include "FWCore/Framework/interface/Frameworkfwd.h"
0035 #include "FWCore/Framework/interface/PrincipalGetAdapter.h"
0036 #include "FWCore/Framework/interface/LuminosityBlock.h"
0037 #include "FWCore/Utilities/interface/TypeID.h"
0038 #include "FWCore/Utilities/interface/EDGetToken.h"
0039 #include "FWCore/Utilities/interface/EDPutToken.h"
0040 #include "FWCore/Utilities/interface/ProductKindOfType.h"
0041 #include "FWCore/Utilities/interface/StreamID.h"
0042 #include "FWCore/Utilities/interface/propagate_const.h"
0043 #include "FWCore/Utilities/interface/Likely.h"
0044 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0045 
0046 #include <memory>
0047 #include <string>
0048 #include <unordered_set>
0049 #include <typeinfo>
0050 #include <type_traits>
0051 #include <vector>
0052 
0053 class testEventGetRefBeforePut;
0054 class testEvent;
0055 
0056 namespace edm {
0057 
0058   class BranchDescription;
0059   class ModuleCallingContext;
0060   class TriggerResultsByName;
0061   class TriggerResults;
0062   class TriggerNames;
0063   class EDConsumerBase;
0064   class EDProductGetter;
0065   class ProducerBase;
0066   class SharedResourcesAcquirer;
0067 
0068   namespace stream {
0069     template <typename T>
0070     class ProducingModuleAdaptorBase;
0071   }
0072 
0073   class Event : public EventBase {
0074   public:
0075     Event(EventTransitionInfo const&, ModuleDescription const&, ModuleCallingContext const*);
0076     Event(EventPrincipal const&, ModuleDescription const&, ModuleCallingContext const*);
0077     ~Event() override;
0078 
0079     //Used in conjunction with EDGetToken
0080     void setConsumer(EDConsumerBase const* iConsumer);
0081 
0082     void setSharedResourcesAcquirer(SharedResourcesAcquirer* iResourceAcquirer);
0083 
0084     void setProducerCommon(ProducerBase const* iProd, std::vector<BranchID>* previousParentage);
0085 
0086     void setProducer(ProducerBase const* iProd,
0087                      std::vector<BranchID>* previousParentage,
0088                      std::vector<BranchID>* gotBranchIDsFromAcquire = nullptr);
0089 
0090     void setProducerForAcquire(ProducerBase const* iProd,
0091                                std::vector<BranchID>* previousParentage,
0092                                std::vector<BranchID>& gotBranchIDsFromAcquire);
0093 
0094     // AUX functions are defined in EventBase
0095     EventAuxiliary const& eventAuxiliary() const override { return aux_; }
0096 
0097     ///\return The id for the particular Stream processing the Event
0098     StreamID streamID() const { return streamID_; }
0099 
0100     LuminosityBlock const& getLuminosityBlock() const {
0101       if (not luminosityBlock_) {
0102         fillLuminosityBlock();
0103       }
0104       return *luminosityBlock_;
0105     }
0106 
0107     Run const& getRun() const;
0108 
0109     RunNumber_t run() const { return id().run(); }
0110 
0111     /**If you are caching data from the Event, you should also keep
0112      this number.  If this number changes then you know that
0113      the data you have cached is invalid.
0114      The value of '0' will never be returned so you can use that to
0115      denote that you have not yet checked the value.
0116      */
0117     typedef unsigned long CacheIdentifier_t;
0118     CacheIdentifier_t cacheIdentifier() const;
0119 
0120     template <typename PROD>
0121     bool get(ProductID const& oid, Handle<PROD>& result) const;
0122 
0123     // Template member overload to deal with Views.
0124     template <typename ELEMENT>
0125     bool get(ProductID const& oid, Handle<View<ELEMENT>>& result) const;
0126 
0127     EventSelectionIDVector const& eventSelectionIDs() const;
0128 
0129     ProcessHistoryID const& processHistoryID() const;
0130 
0131     ///Put a new product.
0132     template <typename PROD>
0133     OrphanHandle<PROD> put(std::unique_ptr<PROD> product) {
0134       return put<PROD>(std::move(product), std::string());
0135     }
0136 
0137     ///Put a new product with a 'product instance name'
0138     template <typename PROD>
0139     OrphanHandle<PROD> put(std::unique_ptr<PROD> product, std::string const& productInstanceName);
0140 
0141     template <typename PROD>
0142     OrphanHandle<PROD> put(EDPutToken token, std::unique_ptr<PROD> product);
0143 
0144     template <typename PROD>
0145     OrphanHandle<PROD> put(EDPutTokenT<PROD> token, std::unique_ptr<PROD> product);
0146 
0147     ///puts a new product
0148     template <typename PROD, typename... Args>
0149     OrphanHandle<PROD> emplace(EDPutTokenT<PROD> token, Args&&... args);
0150 
0151     template <typename PROD, typename... Args>
0152     OrphanHandle<PROD> emplace(EDPutToken token, Args&&... args);
0153 
0154     ///Returns a RefProd to a product before that product has been placed into the Event.
0155     /// The RefProd (and any Ref's made from it) will no work properly until after the
0156     /// Event has been committed (which happens after leaving the EDProducer::produce method)
0157     template <typename PROD>
0158     RefProd<PROD> getRefBeforePut() {
0159       return getRefBeforePut<PROD>(std::string());
0160     }
0161 
0162     template <typename PROD>
0163     RefProd<PROD> getRefBeforePut(std::string const& productInstanceName);
0164 
0165     template <typename PROD>
0166     RefProd<PROD> getRefBeforePut(EDPutTokenT<PROD>);
0167 
0168     template <typename PROD>
0169     RefProd<PROD> getRefBeforePut(EDPutToken);
0170 
0171     template <typename PROD>
0172     bool getByLabel(InputTag const& tag, Handle<PROD>& result) const;
0173 
0174     template <typename PROD>
0175     bool getByLabel(std::string const& label, Handle<PROD>& result) const;
0176 
0177     template <typename PROD>
0178     bool getByLabel(std::string const& label, std::string const& productInstanceName, Handle<PROD>& result) const;
0179 
0180     template <typename PROD>
0181     bool getByToken(EDGetToken token, Handle<PROD>& result) const;
0182 
0183     template <typename PROD>
0184     bool getByToken(EDGetTokenT<PROD> token, Handle<PROD>& result) const;
0185 
0186     template <typename PROD>
0187     Handle<PROD> getHandle(EDGetTokenT<PROD> token) const;
0188 
0189     template <typename PROD>
0190     PROD const& get(EDGetTokenT<PROD> token) const noexcept(false);
0191 
0192     // Template member overload to deal with Views.
0193     template <typename ELEMENT>
0194     bool getByLabel(std::string const& label, Handle<View<ELEMENT>>& result) const;
0195 
0196     template <typename ELEMENT>
0197     bool getByLabel(std::string const& label,
0198                     std::string const& productInstanceName,
0199                     Handle<View<ELEMENT>>& result) const;
0200 
0201     template <typename ELEMENT>
0202     bool getByLabel(InputTag const& tag, Handle<View<ELEMENT>>& result) const;
0203 
0204     template <typename ELEMENT>
0205     bool getByToken(EDGetToken token, Handle<View<ELEMENT>>& result) const;
0206 
0207     template <typename ELEMENT>
0208     bool getByToken(EDGetTokenT<View<ELEMENT>> token, Handle<View<ELEMENT>>& result) const;
0209 
0210     template <typename ELEMENT>
0211     Handle<View<ELEMENT>> getHandle(EDGetTokenT<View<ELEMENT>> token) const;
0212 
0213     template <typename ELEMENT>
0214     View<ELEMENT> const& get(EDGetTokenT<View<ELEMENT>> token) const noexcept(false);
0215 
0216     template <typename ELEMENT>
0217     Handle<View<ELEMENT>> fillView_(BasicHandle& bh) const;
0218 
0219     Provenance const& getProvenance(BranchID const& theID) const;
0220 
0221     Provenance const& getProvenance(ProductID const& theID) const;
0222 
0223     StableProvenance const& getStableProvenance(BranchID const& theID) const;
0224 
0225     StableProvenance const& getStableProvenance(ProductID const& theID) const;
0226 
0227     // Get the provenance for all products that may be in the event
0228     void getAllProvenance(std::vector<Provenance const*>& provenances) const;
0229 
0230     // Get the provenance for all products that may be in the event,
0231     // excluding the per-event provenance (the parentage information).
0232     // The excluded information may change from event to event.
0233     void getAllStableProvenance(std::vector<StableProvenance const*>& provenances) const;
0234 
0235     // Return true if this Event has been subjected to a process with
0236     // the given processName, and false otherwise.
0237     // If true is returned, then ps is filled with the ParameterSet
0238     // used to configure the identified process.
0239     bool getProcessParameterSet(std::string const& processName, ParameterSet& ps) const;
0240 
0241     ProcessHistory const& processHistory() const override;
0242 
0243     edm::ParameterSet const* parameterSet(edm::ParameterSetID const& psID) const override;
0244 
0245     size_t size() const;
0246 
0247     edm::TriggerNames const& triggerNames(edm::TriggerResults const& triggerResults) const override;
0248     TriggerResultsByName triggerResultsByName(edm::TriggerResults const& triggerResults) const override;
0249 
0250     ModuleCallingContext const* moduleCallingContext() const { return moduleCallingContext_; }
0251 
0252     void labelsForToken(EDGetToken const& iToken, ProductLabels& oLabels) const {
0253       provRecorder_.labelsForToken(iToken, oLabels);
0254     }
0255 
0256     typedef std::vector<edm::propagate_const<std::unique_ptr<WrapperBase>>> ProductPtrVec;
0257 
0258     EDProductGetter const& productGetter() const;
0259 
0260     unsigned int processBlockIndex(std::string const& processName) const {
0261       return provRecorder_.processBlockIndex(processName);
0262     }
0263 
0264   private:
0265     //for testing
0266     friend class ::testEventGetRefBeforePut;
0267     friend class ::testEvent;
0268 
0269     EventPrincipal const& eventPrincipal() const;
0270 
0271     void fillLuminosityBlock() const;
0272 
0273     ProductID makeProductID(BranchDescription const& desc) const;
0274 
0275     //override used by EventBase class
0276     BasicHandle getByLabelImpl(std::type_info const& iWrapperType,
0277                                std::type_info const& iProductType,
0278                                InputTag const& iTag) const override;
0279     BasicHandle getByTokenImpl(std::type_info const& iProductType, EDGetToken iToken) const override;
0280 
0281     //override used by EventBase class
0282     BasicHandle getImpl(std::type_info const& iProductType, ProductID const& pid) const override;
0283 
0284     template <typename PROD>
0285     OrphanHandle<PROD> putImpl(EDPutToken::value_type token, std::unique_ptr<PROD> product);
0286 
0287     template <typename PROD, typename... Args>
0288     OrphanHandle<PROD> emplaceImpl(EDPutToken::value_type token, Args&&... args);
0289 
0290     // commit_() is called to complete the transaction represented by
0291     // this PrincipalGetAdapter. The friendships required seems gross, but any
0292     // alternative is not great either.  Putting it into the
0293     // public interface is asking for trouble
0294     friend class ProducerSourceBase;
0295     friend class InputSource;
0296     friend class RawInputSource;
0297     friend class ProducerBase;
0298     template <typename T>
0299     friend class stream::ProducingModuleAdaptorBase;
0300 
0301     void commit_(std::vector<edm::ProductResolverIndex> const& iShouldPut, ParentageID* previousParentageId = nullptr);
0302     void commit_aux(ProductPtrVec& products, ParentageID* previousParentageId = nullptr);
0303 
0304     BasicHandle getByProductID_(ProductID const& oid) const;
0305 
0306     ProductPtrVec& putProducts() { return putProducts_; }
0307     ProductPtrVec const& putProducts() const { return putProducts_; }
0308 
0309     PrincipalGetAdapter provRecorder_;
0310 
0311     // putProducts_ is a holding pen for EDProducts inserted into this
0312     // PrincipalGetAdapter.
0313     //
0314     ProductPtrVec putProducts_;
0315 
0316     EventAuxiliary const& aux_;
0317     // measurable performance gain by only creating LuminosityBlock when needed
0318     // mutables are allowed in this case because edm::Event is only accessed by one thread
0319     CMS_SA_ALLOW mutable std::optional<LuminosityBlock> luminosityBlock_;
0320 
0321     // gotBranchIDs_ must be mutable because it records all 'gets',
0322     // which do not logically modify the PrincipalGetAdapter. gotBranchIDs_ is
0323     // merely a cache reflecting what has been retrieved from the
0324     // Principal class.
0325     typedef std::unordered_set<BranchID::value_type> BranchIDSet;
0326     CMS_SA_ALLOW mutable BranchIDSet gotBranchIDs_;
0327     CMS_SA_ALLOW mutable std::vector<bool> gotBranchIDsFromPrevious_;
0328     std::vector<BranchID>* previousBranchIDs_ = nullptr;
0329     std::vector<BranchID>* gotBranchIDsFromAcquire_ = nullptr;
0330 
0331     void addToGotBranchIDs(Provenance const& prov) const;
0332     void addToGotBranchIDs(BranchID const& branchID) const;
0333 
0334     // We own the retrieved Views, and have to destroy them.
0335     CMS_SA_ALLOW mutable std::vector<std::shared_ptr<ViewBase>> gotViews_;
0336 
0337     StreamID streamID_;
0338     ModuleCallingContext const* moduleCallingContext_;
0339 
0340     static const std::string emptyString_;
0341   };
0342 
0343   template <typename PROD>
0344   bool Event::get(ProductID const& oid, Handle<PROD>& result) const {
0345     result.clear();
0346     BasicHandle bh = this->getByProductID_(oid);
0347     result = convert_handle_check_type<PROD>(std::move(bh));  // throws on conversion error
0348     if (result.failedToGet()) {
0349       return false;
0350     }
0351     addToGotBranchIDs(*bh.provenance());
0352     return true;
0353   }
0354 
0355   template <typename ELEMENT>
0356   bool Event::get(ProductID const& oid, Handle<View<ELEMENT>>& result) const {
0357     result.clear();
0358     BasicHandle bh = this->getByProductID_(oid);
0359 
0360     if (bh.failedToGet()) {
0361       result = Handle<View<ELEMENT>>(makeHandleExceptionFactory([oid]() -> std::shared_ptr<cms::Exception> {
0362         std::shared_ptr<cms::Exception> whyFailed = std::make_shared<edm::Exception>(edm::errors::ProductNotFound);
0363         *whyFailed << "get View by ID failed: no product with ID = " << oid << "\n";
0364         return whyFailed;
0365       }));
0366       return false;
0367     }
0368 
0369     result = fillView_<ELEMENT>(bh);
0370     return true;
0371   }
0372 
0373   template <typename PROD>
0374   OrphanHandle<PROD> Event::putImpl(EDPutToken::value_type index, std::unique_ptr<PROD> product) {
0375     // The following will call post_insert if T has such a function,
0376     // and do nothing if T has no such function.
0377     detail::do_post_insert_if_available(*product.get());
0378 
0379     assert(index < putProducts().size());
0380 
0381     std::unique_ptr<Wrapper<PROD>> wp(new Wrapper<PROD>(std::move(product)));
0382     PROD const* prod = wp->product();
0383 
0384     putProducts()[index] = std::move(wp);
0385     auto const& prodID = provRecorder_.getProductID(index);
0386     return (OrphanHandle<PROD>(prod, prodID));
0387   }
0388 
0389   template <typename PROD>
0390   OrphanHandle<PROD> Event::put(std::unique_ptr<PROD> product, std::string const& productInstanceName) {
0391     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0392       TypeID typeID(typeid(PROD));
0393       principal_get_adapter_detail::throwOnPutOfNullProduct("Event", typeID, productInstanceName);
0394     }
0395 
0396     auto index = provRecorder_.getPutTokenIndex(TypeID(*product), productInstanceName);
0397     return putImpl(index, std::move(product));
0398   }
0399 
0400   template <typename PROD>
0401   OrphanHandle<PROD> Event::put(EDPutTokenT<PROD> token, std::unique_ptr<PROD> product) {
0402     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0403       TypeID typeID(typeid(PROD));
0404       principal_get_adapter_detail::throwOnPutOfNullProduct("Event", typeID, provRecorder_.productInstanceLabel(token));
0405     }
0406     if (UNLIKELY(token.isUninitialized())) {
0407       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0408     }
0409     return putImpl(token.index(), std::move(product));
0410   }
0411 
0412   template <typename PROD>
0413   OrphanHandle<PROD> Event::put(EDPutToken token, std::unique_ptr<PROD> product) {
0414     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0415       TypeID typeID(typeid(PROD));
0416       principal_get_adapter_detail::throwOnPutOfNullProduct("Event", typeID, provRecorder_.productInstanceLabel(token));
0417     }
0418     if (UNLIKELY(token.isUninitialized())) {
0419       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0420     }
0421     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0422       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0423                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0424     }
0425 
0426     return putImpl(token.index(), std::move(product));
0427   }
0428 
0429   template <typename PROD, typename... Args>
0430   OrphanHandle<PROD> Event::emplace(EDPutTokenT<PROD> token, Args&&... args) {
0431     if (UNLIKELY(token.isUninitialized())) {
0432       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0433     }
0434     return emplaceImpl<PROD>(token.index(), std::forward<Args>(args)...);
0435   }
0436 
0437   template <typename PROD, typename... Args>
0438   OrphanHandle<PROD> Event::emplace(EDPutToken token, Args&&... args) {
0439     if (UNLIKELY(token.isUninitialized())) {
0440       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0441     }
0442     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0443       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0444                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0445     }
0446 
0447     return emplaceImpl(token.index(), std::forward<Args>(args)...);
0448   }
0449 
0450   template <typename PROD, typename... Args>
0451   OrphanHandle<PROD> Event::emplaceImpl(EDPutToken::value_type index, Args&&... args) {
0452     assert(index < putProducts().size());
0453 
0454     std::unique_ptr<Wrapper<PROD>> wp(new Wrapper<PROD>(WrapperBase::Emplace{}, std::forward<Args>(args)...));
0455 
0456     // The following will call post_insert if T has such a function,
0457     // and do nothing if T has no such function.
0458     detail::do_post_insert_if_available(wp->bareProduct());
0459 
0460     PROD const* prod = wp->product();
0461 
0462     putProducts()[index] = std::move(wp);
0463     auto const& prodID = provRecorder_.getProductID(index);
0464     return (OrphanHandle<PROD>(prod, prodID));
0465   }
0466 
0467   template <typename PROD>
0468   RefProd<PROD> Event::getRefBeforePut(std::string const& productInstanceName) {
0469     auto index = provRecorder_.getPutTokenIndex(TypeID{typeid(PROD)}, productInstanceName);
0470 
0471     //should keep track of what Ref's have been requested and make sure they are 'put'
0472     return RefProd<PROD>(provRecorder_.getProductID(index), provRecorder_.prodGetter());
0473   }
0474 
0475   template <typename PROD>
0476   RefProd<PROD> Event::getRefBeforePut(EDPutTokenT<PROD> token) {
0477     if (UNLIKELY(token.isUninitialized())) {
0478       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0479     }
0480     return RefProd<PROD>(provRecorder_.getProductID(token.index()), provRecorder_.prodGetter());
0481   }
0482 
0483   template <typename PROD>
0484   RefProd<PROD> Event::getRefBeforePut(EDPutToken token) {
0485     if (UNLIKELY(token.isUninitialized())) {
0486       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0487     }
0488     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0489       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0490                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0491     }
0492     return RefProd<PROD>(provRecorder_.getProductID(token.index()), provRecorder_.prodGetter());
0493   }
0494 
0495   template <typename PROD>
0496   bool Event::getByLabel(InputTag const& tag, Handle<PROD>& result) const {
0497     result.clear();
0498     BasicHandle bh = provRecorder_.getByLabel_(TypeID(typeid(PROD)), tag, moduleCallingContext_);
0499     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0500     if UNLIKELY (result.failedToGet()) {
0501       return false;
0502     }
0503     addToGotBranchIDs(*result.provenance());
0504     return true;
0505   }
0506 
0507   template <typename PROD>
0508   bool Event::getByLabel(std::string const& label, std::string const& productInstanceName, Handle<PROD>& result) const {
0509     result.clear();
0510     BasicHandle bh = provRecorder_.getByLabel_(
0511         TypeID(typeid(PROD)), label, productInstanceName, emptyString_, moduleCallingContext_);
0512     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0513     if UNLIKELY (result.failedToGet()) {
0514       return false;
0515     }
0516     addToGotBranchIDs(*result.provenance());
0517     return true;
0518   }
0519 
0520   template <typename PROD>
0521   bool Event::getByLabel(std::string const& label, Handle<PROD>& result) const {
0522     return getByLabel(label, emptyString_, result);
0523   }
0524 
0525   template <typename PROD>
0526   bool Event::getByToken(EDGetToken token, Handle<PROD>& result) const {
0527     result.clear();
0528     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0529     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0530     if UNLIKELY (result.failedToGet()) {
0531       return false;
0532     }
0533     addToGotBranchIDs(*result.provenance());
0534     return true;
0535   }
0536 
0537   template <typename PROD>
0538   bool Event::getByToken(EDGetTokenT<PROD> token, Handle<PROD>& result) const {
0539     result.clear();
0540     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0541     result = convert_handle<PROD>(std::move(bh));
0542     if UNLIKELY (result.failedToGet()) {
0543       return false;
0544     }
0545     addToGotBranchIDs(*result.provenance());
0546     return true;
0547   }
0548 
0549   template <typename PROD>
0550   Handle<PROD> Event::getHandle(EDGetTokenT<PROD> token) const {
0551     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0552     auto result = convert_handle<PROD>(std::move(bh));
0553     if LIKELY (not result.failedToGet()) {
0554       addToGotBranchIDs(*result.provenance());
0555     }
0556     return result;
0557   }
0558 
0559   template <typename PROD>
0560   PROD const& Event::get(EDGetTokenT<PROD> token) const noexcept(false) {
0561     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0562     auto result = convert_handle<PROD>(std::move(bh));
0563     if LIKELY (not result.failedToGet()) {
0564       addToGotBranchIDs(*result.provenance());
0565     }
0566     return *result;
0567   }
0568 
0569   template <typename ELEMENT>
0570   bool Event::getByLabel(InputTag const& tag, Handle<View<ELEMENT>>& result) const {
0571     result.clear();
0572     BasicHandle bh = provRecorder_.getMatchingSequenceByLabel_(TypeID(typeid(ELEMENT)), tag, moduleCallingContext_);
0573     if UNLIKELY (bh.failedToGet()) {
0574       Handle<View<ELEMENT>> h(std::move(bh.whyFailedFactory()));
0575       h.swap(result);
0576       return false;
0577     }
0578     result = fillView_<ELEMENT>(bh);
0579     return true;
0580   }
0581 
0582   template <typename ELEMENT>
0583   bool Event::getByLabel(std::string const& moduleLabel,
0584                          std::string const& productInstanceName,
0585                          Handle<View<ELEMENT>>& result) const {
0586     result.clear();
0587     BasicHandle bh = provRecorder_.getMatchingSequenceByLabel_(
0588         TypeID(typeid(ELEMENT)), moduleLabel, productInstanceName, emptyString_, moduleCallingContext_);
0589     if UNLIKELY (bh.failedToGet()) {
0590       Handle<View<ELEMENT>> h(std::move(bh.whyFailedFactory()));
0591       h.swap(result);
0592       return false;
0593     }
0594     result = fillView_<ELEMENT>(bh);
0595     return true;
0596   }
0597 
0598   template <typename ELEMENT>
0599   bool Event::getByLabel(std::string const& moduleLabel, Handle<View<ELEMENT>>& result) const {
0600     return getByLabel(moduleLabel, emptyString_, result);
0601   }
0602 
0603   template <typename ELEMENT>
0604   bool Event::getByToken(EDGetToken token, Handle<View<ELEMENT>>& result) const {
0605     result.clear();
0606     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(ELEMENT)), ELEMENT_TYPE, token, moduleCallingContext_);
0607     if UNLIKELY (bh.failedToGet()) {
0608       Handle<View<ELEMENT>> h(std::move(bh.whyFailedFactory()));
0609       h.swap(result);
0610       return false;
0611     }
0612     result = fillView_<ELEMENT>(bh);
0613     return true;
0614   }
0615 
0616   template <typename ELEMENT>
0617   bool Event::getByToken(EDGetTokenT<View<ELEMENT>> token, Handle<View<ELEMENT>>& result) const {
0618     result.clear();
0619     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(ELEMENT)), ELEMENT_TYPE, token, moduleCallingContext_);
0620     if UNLIKELY (bh.failedToGet()) {
0621       Handle<View<ELEMENT>> h(std::move(bh.whyFailedFactory()));
0622       h.swap(result);
0623       return false;
0624     }
0625     result = fillView_<ELEMENT>(bh);
0626     return true;
0627   }
0628 
0629   template <typename ELEMENT>
0630   Handle<View<ELEMENT>> Event::getHandle(EDGetTokenT<View<ELEMENT>> token) const {
0631     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(ELEMENT)), ELEMENT_TYPE, token, moduleCallingContext_);
0632     if UNLIKELY (bh.failedToGet()) {
0633       return Handle<View<ELEMENT>>(std::move(bh.whyFailedFactory()));
0634     }
0635     return fillView_<ELEMENT>(bh);
0636   }
0637 
0638   template <typename ELEMENT>
0639   View<ELEMENT> const& Event::get(EDGetTokenT<View<ELEMENT>> token) const noexcept(false) {
0640     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(ELEMENT)), ELEMENT_TYPE, token, moduleCallingContext_);
0641     if UNLIKELY (bh.failedToGet()) {
0642       bh.whyFailedFactory()->make()->raise();
0643     }
0644     return *fillView_<ELEMENT>(bh);
0645   }
0646 
0647   template <typename ELEMENT>
0648   Handle<View<ELEMENT>> Event::fillView_(BasicHandle& bh) const {
0649     std::vector<void const*> pointersToElements;
0650     FillViewHelperVector helpers;
0651     // the following must initialize the
0652     //  fill the helper vector
0653     bh.wrapper()->fillView(bh.id(), pointersToElements, helpers);
0654 
0655     auto newview = std::make_shared<View<ELEMENT>>(pointersToElements, helpers, &(productGetter()));
0656 
0657     addToGotBranchIDs(*bh.provenance());
0658     gotViews_.push_back(newview);
0659     return Handle<View<ELEMENT>>(newview.get(), bh.provenance());
0660   }
0661 
0662   // Free functions to retrieve a collection from the Event.
0663   // Will throw an exception if the collection is not available.
0664 
0665   template <typename T>
0666   T const& get(Event const& event, InputTag const& tag) noexcept(false) {
0667     Handle<T> handle;
0668     event.getByLabel(tag, handle);
0669     // throw if the handle is not valid
0670     return *handle.product();
0671   }
0672 
0673   template <typename T>
0674   T const& get(Event const& event, EDGetToken const& token) noexcept(false) {
0675     Handle<T> handle;
0676     event.getByToken(token, handle);
0677     // throw if the handle is not valid
0678     return *handle.product();
0679   }
0680 
0681   template <typename T>
0682   T const& get(Event const& event, EDGetTokenT<T> const& token) noexcept(false) {
0683     return event.get(token);
0684   }
0685 
0686 }  // namespace edm
0687 
0688 #endif  // FWCore_Framework_Event_h