Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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     std::conditional_t<detail::has_postinsert<PROD>::value, DoPostInsert<PROD>, DoNotPostInsert<PROD>> maybe_inserter;
0378     maybe_inserter(product.get());
0379 
0380     assert(index < putProducts().size());
0381 
0382     std::unique_ptr<Wrapper<PROD>> wp(new Wrapper<PROD>(std::move(product)));
0383     PROD const* prod = wp->product();
0384 
0385     putProducts()[index] = std::move(wp);
0386     auto const& prodID = provRecorder_.getProductID(index);
0387     return (OrphanHandle<PROD>(prod, prodID));
0388   }
0389 
0390   template <typename PROD>
0391   OrphanHandle<PROD> Event::put(std::unique_ptr<PROD> product, std::string const& productInstanceName) {
0392     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0393       TypeID typeID(typeid(PROD));
0394       principal_get_adapter_detail::throwOnPutOfNullProduct("Event", typeID, productInstanceName);
0395     }
0396 
0397     auto index = provRecorder_.getPutTokenIndex(TypeID(*product), productInstanceName);
0398     return putImpl(index, std::move(product));
0399   }
0400 
0401   template <typename PROD>
0402   OrphanHandle<PROD> Event::put(EDPutTokenT<PROD> token, std::unique_ptr<PROD> product) {
0403     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0404       TypeID typeID(typeid(PROD));
0405       principal_get_adapter_detail::throwOnPutOfNullProduct("Event", typeID, provRecorder_.productInstanceLabel(token));
0406     }
0407     if (UNLIKELY(token.isUninitialized())) {
0408       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0409     }
0410     return putImpl(token.index(), std::move(product));
0411   }
0412 
0413   template <typename PROD>
0414   OrphanHandle<PROD> Event::put(EDPutToken token, std::unique_ptr<PROD> product) {
0415     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0416       TypeID typeID(typeid(PROD));
0417       principal_get_adapter_detail::throwOnPutOfNullProduct("Event", typeID, provRecorder_.productInstanceLabel(token));
0418     }
0419     if (UNLIKELY(token.isUninitialized())) {
0420       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0421     }
0422     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0423       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0424                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0425     }
0426 
0427     return putImpl(token.index(), std::move(product));
0428   }
0429 
0430   template <typename PROD, typename... Args>
0431   OrphanHandle<PROD> Event::emplace(EDPutTokenT<PROD> token, Args&&... args) {
0432     if (UNLIKELY(token.isUninitialized())) {
0433       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0434     }
0435     return emplaceImpl<PROD>(token.index(), std::forward<Args>(args)...);
0436   }
0437 
0438   template <typename PROD, typename... Args>
0439   OrphanHandle<PROD> Event::emplace(EDPutToken token, Args&&... args) {
0440     if (UNLIKELY(token.isUninitialized())) {
0441       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0442     }
0443     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0444       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0445                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0446     }
0447 
0448     return emplaceImpl(token.index(), std::forward<Args>(args)...);
0449   }
0450 
0451   template <typename PROD, typename... Args>
0452   OrphanHandle<PROD> Event::emplaceImpl(EDPutToken::value_type index, Args&&... args) {
0453     assert(index < putProducts().size());
0454 
0455     std::unique_ptr<Wrapper<PROD>> wp(new Wrapper<PROD>(WrapperBase::Emplace{}, std::forward<Args>(args)...));
0456 
0457     // The following will call post_insert if T has such a function,
0458     // and do nothing if T has no such function.
0459     std::conditional_t<detail::has_postinsert<PROD>::value, DoPostInsert<PROD>, DoNotPostInsert<PROD>> maybe_inserter;
0460     maybe_inserter(&(wp->bareProduct()));
0461 
0462     PROD const* prod = wp->product();
0463 
0464     putProducts()[index] = std::move(wp);
0465     auto const& prodID = provRecorder_.getProductID(index);
0466     return (OrphanHandle<PROD>(prod, prodID));
0467   }
0468 
0469   template <typename PROD>
0470   RefProd<PROD> Event::getRefBeforePut(std::string const& productInstanceName) {
0471     auto index = provRecorder_.getPutTokenIndex(TypeID{typeid(PROD)}, productInstanceName);
0472 
0473     //should keep track of what Ref's have been requested and make sure they are 'put'
0474     return RefProd<PROD>(provRecorder_.getProductID(index), provRecorder_.prodGetter());
0475   }
0476 
0477   template <typename PROD>
0478   RefProd<PROD> Event::getRefBeforePut(EDPutTokenT<PROD> token) {
0479     if (UNLIKELY(token.isUninitialized())) {
0480       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0481     }
0482     return RefProd<PROD>(provRecorder_.getProductID(token.index()), provRecorder_.prodGetter());
0483   }
0484 
0485   template <typename PROD>
0486   RefProd<PROD> Event::getRefBeforePut(EDPutToken token) {
0487     if (UNLIKELY(token.isUninitialized())) {
0488       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0489     }
0490     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0491       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0492                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0493     }
0494     return RefProd<PROD>(provRecorder_.getProductID(token.index()), provRecorder_.prodGetter());
0495   }
0496 
0497   template <typename PROD>
0498   bool Event::getByLabel(InputTag const& tag, Handle<PROD>& result) const {
0499     result.clear();
0500     BasicHandle bh = provRecorder_.getByLabel_(TypeID(typeid(PROD)), tag, moduleCallingContext_);
0501     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0502     if UNLIKELY (result.failedToGet()) {
0503       return false;
0504     }
0505     addToGotBranchIDs(*result.provenance());
0506     return true;
0507   }
0508 
0509   template <typename PROD>
0510   bool Event::getByLabel(std::string const& label, std::string const& productInstanceName, Handle<PROD>& result) const {
0511     result.clear();
0512     BasicHandle bh = provRecorder_.getByLabel_(
0513         TypeID(typeid(PROD)), label, productInstanceName, emptyString_, moduleCallingContext_);
0514     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0515     if UNLIKELY (result.failedToGet()) {
0516       return false;
0517     }
0518     addToGotBranchIDs(*result.provenance());
0519     return true;
0520   }
0521 
0522   template <typename PROD>
0523   bool Event::getByLabel(std::string const& label, Handle<PROD>& result) const {
0524     return getByLabel(label, emptyString_, result);
0525   }
0526 
0527   template <typename PROD>
0528   bool Event::getByToken(EDGetToken token, Handle<PROD>& result) const {
0529     result.clear();
0530     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0531     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0532     if UNLIKELY (result.failedToGet()) {
0533       return false;
0534     }
0535     addToGotBranchIDs(*result.provenance());
0536     return true;
0537   }
0538 
0539   template <typename PROD>
0540   bool Event::getByToken(EDGetTokenT<PROD> token, Handle<PROD>& result) const {
0541     result.clear();
0542     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0543     result = convert_handle<PROD>(std::move(bh));
0544     if UNLIKELY (result.failedToGet()) {
0545       return false;
0546     }
0547     addToGotBranchIDs(*result.provenance());
0548     return true;
0549   }
0550 
0551   template <typename PROD>
0552   Handle<PROD> Event::getHandle(EDGetTokenT<PROD> token) const {
0553     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0554     auto result = convert_handle<PROD>(std::move(bh));
0555     if LIKELY (not result.failedToGet()) {
0556       addToGotBranchIDs(*result.provenance());
0557     }
0558     return result;
0559   }
0560 
0561   template <typename PROD>
0562   PROD const& Event::get(EDGetTokenT<PROD> token) const noexcept(false) {
0563     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0564     auto result = convert_handle<PROD>(std::move(bh));
0565     if LIKELY (not result.failedToGet()) {
0566       addToGotBranchIDs(*result.provenance());
0567     }
0568     return *result;
0569   }
0570 
0571   template <typename ELEMENT>
0572   bool Event::getByLabel(InputTag const& tag, Handle<View<ELEMENT>>& result) const {
0573     result.clear();
0574     BasicHandle bh = provRecorder_.getMatchingSequenceByLabel_(TypeID(typeid(ELEMENT)), tag, moduleCallingContext_);
0575     if UNLIKELY (bh.failedToGet()) {
0576       Handle<View<ELEMENT>> h(std::move(bh.whyFailedFactory()));
0577       h.swap(result);
0578       return false;
0579     }
0580     result = fillView_<ELEMENT>(bh);
0581     return true;
0582   }
0583 
0584   template <typename ELEMENT>
0585   bool Event::getByLabel(std::string const& moduleLabel,
0586                          std::string const& productInstanceName,
0587                          Handle<View<ELEMENT>>& result) const {
0588     result.clear();
0589     BasicHandle bh = provRecorder_.getMatchingSequenceByLabel_(
0590         TypeID(typeid(ELEMENT)), moduleLabel, productInstanceName, emptyString_, moduleCallingContext_);
0591     if UNLIKELY (bh.failedToGet()) {
0592       Handle<View<ELEMENT>> h(std::move(bh.whyFailedFactory()));
0593       h.swap(result);
0594       return false;
0595     }
0596     result = fillView_<ELEMENT>(bh);
0597     return true;
0598   }
0599 
0600   template <typename ELEMENT>
0601   bool Event::getByLabel(std::string const& moduleLabel, Handle<View<ELEMENT>>& result) const {
0602     return getByLabel(moduleLabel, emptyString_, result);
0603   }
0604 
0605   template <typename ELEMENT>
0606   bool Event::getByToken(EDGetToken token, Handle<View<ELEMENT>>& result) const {
0607     result.clear();
0608     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(ELEMENT)), ELEMENT_TYPE, token, moduleCallingContext_);
0609     if UNLIKELY (bh.failedToGet()) {
0610       Handle<View<ELEMENT>> h(std::move(bh.whyFailedFactory()));
0611       h.swap(result);
0612       return false;
0613     }
0614     result = fillView_<ELEMENT>(bh);
0615     return true;
0616   }
0617 
0618   template <typename ELEMENT>
0619   bool Event::getByToken(EDGetTokenT<View<ELEMENT>> token, Handle<View<ELEMENT>>& result) const {
0620     result.clear();
0621     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(ELEMENT)), ELEMENT_TYPE, token, moduleCallingContext_);
0622     if UNLIKELY (bh.failedToGet()) {
0623       Handle<View<ELEMENT>> h(std::move(bh.whyFailedFactory()));
0624       h.swap(result);
0625       return false;
0626     }
0627     result = fillView_<ELEMENT>(bh);
0628     return true;
0629   }
0630 
0631   template <typename ELEMENT>
0632   Handle<View<ELEMENT>> Event::getHandle(EDGetTokenT<View<ELEMENT>> token) const {
0633     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(ELEMENT)), ELEMENT_TYPE, token, moduleCallingContext_);
0634     if UNLIKELY (bh.failedToGet()) {
0635       return Handle<View<ELEMENT>>(std::move(bh.whyFailedFactory()));
0636     }
0637     return fillView_<ELEMENT>(bh);
0638   }
0639 
0640   template <typename ELEMENT>
0641   View<ELEMENT> const& Event::get(EDGetTokenT<View<ELEMENT>> token) const noexcept(false) {
0642     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(ELEMENT)), ELEMENT_TYPE, token, moduleCallingContext_);
0643     if UNLIKELY (bh.failedToGet()) {
0644       bh.whyFailedFactory()->make()->raise();
0645     }
0646     return *fillView_<ELEMENT>(bh);
0647   }
0648 
0649   template <typename ELEMENT>
0650   Handle<View<ELEMENT>> Event::fillView_(BasicHandle& bh) const {
0651     std::vector<void const*> pointersToElements;
0652     FillViewHelperVector helpers;
0653     // the following must initialize the
0654     //  fill the helper vector
0655     bh.wrapper()->fillView(bh.id(), pointersToElements, helpers);
0656 
0657     auto newview = std::make_shared<View<ELEMENT>>(pointersToElements, helpers, &(productGetter()));
0658 
0659     addToGotBranchIDs(*bh.provenance());
0660     gotViews_.push_back(newview);
0661     return Handle<View<ELEMENT>>(newview.get(), bh.provenance());
0662   }
0663 
0664   // Free functions to retrieve a collection from the Event.
0665   // Will throw an exception if the collection is not available.
0666 
0667   template <typename T>
0668   T const& get(Event const& event, InputTag const& tag) noexcept(false) {
0669     Handle<T> handle;
0670     event.getByLabel(tag, handle);
0671     // throw if the handle is not valid
0672     return *handle.product();
0673   }
0674 
0675   template <typename T>
0676   T const& get(Event const& event, EDGetToken const& token) noexcept(false) {
0677     Handle<T> handle;
0678     event.getByToken(token, handle);
0679     // throw if the handle is not valid
0680     return *handle.product();
0681   }
0682 
0683   template <typename T>
0684   T const& get(Event const& event, EDGetTokenT<T> const& token) noexcept(false) {
0685     return event.get(token);
0686   }
0687 
0688 }  // namespace edm
0689 
0690 #endif  // FWCore_Framework_Event_h