Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-07-19 01:43:40

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     void getManyByType(std::vector<Handle<PROD>>& results) const;
0182 
0183     template <typename PROD>
0184     bool getByToken(EDGetToken token, Handle<PROD>& result) const;
0185 
0186     template <typename PROD>
0187     bool getByToken(EDGetTokenT<PROD> token, Handle<PROD>& result) const;
0188 
0189     template <typename PROD>
0190     Handle<PROD> getHandle(EDGetTokenT<PROD> token) const;
0191 
0192     template <typename PROD>
0193     PROD const& get(EDGetTokenT<PROD> token) const noexcept(false);
0194 
0195     // Template member overload to deal with Views.
0196     template <typename ELEMENT>
0197     bool getByLabel(std::string const& label, Handle<View<ELEMENT>>& result) const;
0198 
0199     template <typename ELEMENT>
0200     bool getByLabel(std::string const& label,
0201                     std::string const& productInstanceName,
0202                     Handle<View<ELEMENT>>& result) const;
0203 
0204     template <typename ELEMENT>
0205     bool getByLabel(InputTag const& tag, Handle<View<ELEMENT>>& result) const;
0206 
0207     template <typename ELEMENT>
0208     bool getByToken(EDGetToken token, Handle<View<ELEMENT>>& result) const;
0209 
0210     template <typename ELEMENT>
0211     bool getByToken(EDGetTokenT<View<ELEMENT>> token, Handle<View<ELEMENT>>& result) const;
0212 
0213     template <typename ELEMENT>
0214     Handle<View<ELEMENT>> getHandle(EDGetTokenT<View<ELEMENT>> token) const;
0215 
0216     template <typename ELEMENT>
0217     View<ELEMENT> const& get(EDGetTokenT<View<ELEMENT>> token) const noexcept(false);
0218 
0219     template <typename ELEMENT>
0220     Handle<View<ELEMENT>> fillView_(BasicHandle& bh) const;
0221 
0222     Provenance const& getProvenance(BranchID const& theID) const;
0223 
0224     Provenance const& getProvenance(ProductID const& theID) const;
0225 
0226     StableProvenance const& getStableProvenance(BranchID const& theID) const;
0227 
0228     StableProvenance const& getStableProvenance(ProductID const& theID) const;
0229 
0230     // Get the provenance for all products that may be in the event
0231     void getAllProvenance(std::vector<Provenance const*>& provenances) const;
0232 
0233     // Get the provenance for all products that may be in the event,
0234     // excluding the per-event provenance (the parentage information).
0235     // The excluded information may change from event to event.
0236     void getAllStableProvenance(std::vector<StableProvenance const*>& provenances) const;
0237 
0238     // Return true if this Event has been subjected to a process with
0239     // the given processName, and false otherwise.
0240     // If true is returned, then ps is filled with the ParameterSet
0241     // used to configure the identified process.
0242     bool getProcessParameterSet(std::string const& processName, ParameterSet& ps) const;
0243 
0244     ProcessHistory const& processHistory() const override;
0245 
0246     edm::ParameterSet const* parameterSet(edm::ParameterSetID const& psID) const override;
0247 
0248     size_t size() const;
0249 
0250     edm::TriggerNames const& triggerNames(edm::TriggerResults const& triggerResults) const override;
0251     TriggerResultsByName triggerResultsByName(edm::TriggerResults const& triggerResults) const override;
0252 
0253     ModuleCallingContext const* moduleCallingContext() const { return moduleCallingContext_; }
0254 
0255     void labelsForToken(EDGetToken const& iToken, ProductLabels& oLabels) const {
0256       provRecorder_.labelsForToken(iToken, oLabels);
0257     }
0258 
0259     typedef std::vector<edm::propagate_const<std::unique_ptr<WrapperBase>>> ProductPtrVec;
0260 
0261     EDProductGetter const& productGetter() const;
0262 
0263     unsigned int processBlockIndex(std::string const& processName) const {
0264       return provRecorder_.processBlockIndex(processName);
0265     }
0266 
0267   private:
0268     //for testing
0269     friend class ::testEventGetRefBeforePut;
0270     friend class ::testEvent;
0271 
0272     EventPrincipal const& eventPrincipal() const;
0273 
0274     void fillLuminosityBlock() const;
0275 
0276     ProductID makeProductID(BranchDescription const& desc) const;
0277 
0278     //override used by EventBase class
0279     BasicHandle getByLabelImpl(std::type_info const& iWrapperType,
0280                                std::type_info const& iProductType,
0281                                InputTag const& iTag) const override;
0282 
0283     //override used by EventBase class
0284     BasicHandle getImpl(std::type_info const& iProductType, ProductID const& pid) const override;
0285 
0286     template <typename PROD>
0287     OrphanHandle<PROD> putImpl(EDPutToken::value_type token, std::unique_ptr<PROD> product);
0288 
0289     template <typename PROD, typename... Args>
0290     OrphanHandle<PROD> emplaceImpl(EDPutToken::value_type token, Args&&... args);
0291 
0292     // commit_() is called to complete the transaction represented by
0293     // this PrincipalGetAdapter. The friendships required seems gross, but any
0294     // alternative is not great either.  Putting it into the
0295     // public interface is asking for trouble
0296     friend class ProducerSourceBase;
0297     friend class InputSource;
0298     friend class RawInputSource;
0299     friend class ProducerBase;
0300     template <typename T>
0301     friend class stream::ProducingModuleAdaptorBase;
0302 
0303     void commit_(std::vector<edm::ProductResolverIndex> const& iShouldPut, ParentageID* previousParentageId = nullptr);
0304     void commit_aux(ProductPtrVec& products, ParentageID* previousParentageId = nullptr);
0305 
0306     BasicHandle getByProductID_(ProductID const& oid) const;
0307 
0308     ProductPtrVec& putProducts() { return putProducts_; }
0309     ProductPtrVec const& putProducts() const { return putProducts_; }
0310 
0311     PrincipalGetAdapter provRecorder_;
0312 
0313     // putProducts_ is a holding pen for EDProducts inserted into this
0314     // PrincipalGetAdapter.
0315     //
0316     ProductPtrVec putProducts_;
0317 
0318     EventAuxiliary const& aux_;
0319     // measurable performance gain by only creating LuminosityBlock when needed
0320     // mutables are allowed in this case because edm::Event is only accessed by one thread
0321     CMS_SA_ALLOW mutable std::optional<LuminosityBlock> luminosityBlock_;
0322 
0323     // gotBranchIDs_ must be mutable because it records all 'gets',
0324     // which do not logically modify the PrincipalGetAdapter. gotBranchIDs_ is
0325     // merely a cache reflecting what has been retrieved from the
0326     // Principal class.
0327     typedef std::unordered_set<BranchID::value_type> BranchIDSet;
0328     CMS_SA_ALLOW mutable BranchIDSet gotBranchIDs_;
0329     CMS_SA_ALLOW mutable std::vector<bool> gotBranchIDsFromPrevious_;
0330     std::vector<BranchID>* previousBranchIDs_ = nullptr;
0331     std::vector<BranchID>* gotBranchIDsFromAcquire_ = nullptr;
0332 
0333     void addToGotBranchIDs(Provenance const& prov) const;
0334     void addToGotBranchIDs(BranchID const& branchID) const;
0335 
0336     // We own the retrieved Views, and have to destroy them.
0337     CMS_SA_ALLOW mutable std::vector<std::shared_ptr<ViewBase>> gotViews_;
0338 
0339     StreamID streamID_;
0340     ModuleCallingContext const* moduleCallingContext_;
0341 
0342     static const std::string emptyString_;
0343   };
0344 
0345   template <typename PROD>
0346   bool Event::get(ProductID const& oid, Handle<PROD>& result) const {
0347     result.clear();
0348     BasicHandle bh = this->getByProductID_(oid);
0349     result = convert_handle_check_type<PROD>(std::move(bh));  // throws on conversion error
0350     if (result.failedToGet()) {
0351       return false;
0352     }
0353     addToGotBranchIDs(*bh.provenance());
0354     return true;
0355   }
0356 
0357   template <typename ELEMENT>
0358   bool Event::get(ProductID const& oid, Handle<View<ELEMENT>>& result) const {
0359     result.clear();
0360     BasicHandle bh = this->getByProductID_(oid);
0361 
0362     if (bh.failedToGet()) {
0363       result = Handle<View<ELEMENT>>(makeHandleExceptionFactory([oid]() -> std::shared_ptr<cms::Exception> {
0364         std::shared_ptr<cms::Exception> whyFailed = std::make_shared<edm::Exception>(edm::errors::ProductNotFound);
0365         *whyFailed << "get View by ID failed: no product with ID = " << oid << "\n";
0366         return whyFailed;
0367       }));
0368       return false;
0369     }
0370 
0371     result = fillView_<ELEMENT>(bh);
0372     return true;
0373   }
0374 
0375   template <typename PROD>
0376   OrphanHandle<PROD> Event::putImpl(EDPutToken::value_type index, std::unique_ptr<PROD> product) {
0377     // The following will call post_insert if T has such a function,
0378     // and do nothing if T has no such function.
0379     std::conditional_t<detail::has_postinsert<PROD>::value, DoPostInsert<PROD>, DoNotPostInsert<PROD>> maybe_inserter;
0380     maybe_inserter(product.get());
0381 
0382     assert(index < putProducts().size());
0383 
0384     std::unique_ptr<Wrapper<PROD>> wp(new Wrapper<PROD>(std::move(product)));
0385     PROD const* prod = wp->product();
0386 
0387     putProducts()[index] = std::move(wp);
0388     auto const& prodID = provRecorder_.getProductID(index);
0389     return (OrphanHandle<PROD>(prod, prodID));
0390   }
0391 
0392   template <typename PROD>
0393   OrphanHandle<PROD> Event::put(std::unique_ptr<PROD> product, std::string const& productInstanceName) {
0394     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0395       TypeID typeID(typeid(PROD));
0396       principal_get_adapter_detail::throwOnPutOfNullProduct("Event", typeID, productInstanceName);
0397     }
0398 
0399     auto index = provRecorder_.getPutTokenIndex(TypeID(*product), productInstanceName);
0400     return putImpl(index, std::move(product));
0401   }
0402 
0403   template <typename PROD>
0404   OrphanHandle<PROD> Event::put(EDPutTokenT<PROD> token, std::unique_ptr<PROD> product) {
0405     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0406       TypeID typeID(typeid(PROD));
0407       principal_get_adapter_detail::throwOnPutOfNullProduct("Event", typeID, provRecorder_.productInstanceLabel(token));
0408     }
0409     if (UNLIKELY(token.isUninitialized())) {
0410       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0411     }
0412     return putImpl(token.index(), std::move(product));
0413   }
0414 
0415   template <typename PROD>
0416   OrphanHandle<PROD> Event::put(EDPutToken token, std::unique_ptr<PROD> product) {
0417     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0418       TypeID typeID(typeid(PROD));
0419       principal_get_adapter_detail::throwOnPutOfNullProduct("Event", typeID, provRecorder_.productInstanceLabel(token));
0420     }
0421     if (UNLIKELY(token.isUninitialized())) {
0422       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0423     }
0424     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0425       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0426                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0427     }
0428 
0429     return putImpl(token.index(), std::move(product));
0430   }
0431 
0432   template <typename PROD, typename... Args>
0433   OrphanHandle<PROD> Event::emplace(EDPutTokenT<PROD> token, Args&&... args) {
0434     if (UNLIKELY(token.isUninitialized())) {
0435       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0436     }
0437     return emplaceImpl<PROD>(token.index(), std::forward<Args>(args)...);
0438   }
0439 
0440   template <typename PROD, typename... Args>
0441   OrphanHandle<PROD> Event::emplace(EDPutToken token, Args&&... args) {
0442     if (UNLIKELY(token.isUninitialized())) {
0443       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0444     }
0445     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0446       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0447                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0448     }
0449 
0450     return emplaceImpl(token.index(), std::forward<Args>(args)...);
0451   }
0452 
0453   template <typename PROD, typename... Args>
0454   OrphanHandle<PROD> Event::emplaceImpl(EDPutToken::value_type index, Args&&... args) {
0455     assert(index < putProducts().size());
0456 
0457     std::unique_ptr<Wrapper<PROD>> wp(new Wrapper<PROD>(WrapperBase::Emplace{}, std::forward<Args>(args)...));
0458 
0459     // The following will call post_insert if T has such a function,
0460     // and do nothing if T has no such function.
0461     std::conditional_t<detail::has_postinsert<PROD>::value, DoPostInsert<PROD>, DoNotPostInsert<PROD>> maybe_inserter;
0462     maybe_inserter(&(wp->bareProduct()));
0463 
0464     PROD const* prod = wp->product();
0465 
0466     putProducts()[index] = std::move(wp);
0467     auto const& prodID = provRecorder_.getProductID(index);
0468     return (OrphanHandle<PROD>(prod, prodID));
0469   }
0470 
0471   template <typename PROD>
0472   RefProd<PROD> Event::getRefBeforePut(std::string const& productInstanceName) {
0473     auto index = provRecorder_.getPutTokenIndex(TypeID{typeid(PROD)}, productInstanceName);
0474 
0475     //should keep track of what Ref's have been requested and make sure they are 'put'
0476     return RefProd<PROD>(provRecorder_.getProductID(index), provRecorder_.prodGetter());
0477   }
0478 
0479   template <typename PROD>
0480   RefProd<PROD> Event::getRefBeforePut(EDPutTokenT<PROD> token) {
0481     if (UNLIKELY(token.isUninitialized())) {
0482       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0483     }
0484     return RefProd<PROD>(provRecorder_.getProductID(token.index()), provRecorder_.prodGetter());
0485   }
0486 
0487   template <typename PROD>
0488   RefProd<PROD> Event::getRefBeforePut(EDPutToken token) {
0489     if (UNLIKELY(token.isUninitialized())) {
0490       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0491     }
0492     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0493       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0494                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0495     }
0496     return RefProd<PROD>(provRecorder_.getProductID(token.index()), provRecorder_.prodGetter());
0497   }
0498 
0499   template <typename PROD>
0500   bool Event::getByLabel(InputTag const& tag, Handle<PROD>& result) const {
0501     result.clear();
0502     BasicHandle bh = provRecorder_.getByLabel_(TypeID(typeid(PROD)), tag, moduleCallingContext_);
0503     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0504     if UNLIKELY (result.failedToGet()) {
0505       return false;
0506     }
0507     addToGotBranchIDs(*result.provenance());
0508     return true;
0509   }
0510 
0511   template <typename PROD>
0512   bool Event::getByLabel(std::string const& label, std::string const& productInstanceName, Handle<PROD>& result) const {
0513     result.clear();
0514     BasicHandle bh = provRecorder_.getByLabel_(
0515         TypeID(typeid(PROD)), label, productInstanceName, emptyString_, moduleCallingContext_);
0516     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0517     if UNLIKELY (result.failedToGet()) {
0518       return false;
0519     }
0520     addToGotBranchIDs(*result.provenance());
0521     return true;
0522   }
0523 
0524   template <typename PROD>
0525   bool Event::getByLabel(std::string const& label, Handle<PROD>& result) const {
0526     return getByLabel(label, emptyString_, result);
0527   }
0528 
0529   template <typename PROD>
0530   void Event::getManyByType(std::vector<Handle<PROD>>& results) const {
0531     provRecorder_.getManyByType(results, moduleCallingContext_);
0532     for (typename std::vector<Handle<PROD>>::const_iterator it = results.begin(), itEnd = results.end(); it != itEnd;
0533          ++it) {
0534       addToGotBranchIDs(*it->provenance());
0535     }
0536   }
0537 
0538   template <typename PROD>
0539   bool Event::getByToken(EDGetToken token, Handle<PROD>& result) const {
0540     result.clear();
0541     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0542     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0543     if UNLIKELY (result.failedToGet()) {
0544       return false;
0545     }
0546     addToGotBranchIDs(*result.provenance());
0547     return true;
0548   }
0549 
0550   template <typename PROD>
0551   bool Event::getByToken(EDGetTokenT<PROD> token, Handle<PROD>& result) const {
0552     result.clear();
0553     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0554     result = convert_handle<PROD>(std::move(bh));
0555     if UNLIKELY (result.failedToGet()) {
0556       return false;
0557     }
0558     addToGotBranchIDs(*result.provenance());
0559     return true;
0560   }
0561 
0562   template <typename PROD>
0563   Handle<PROD> Event::getHandle(EDGetTokenT<PROD> token) const {
0564     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0565     auto result = convert_handle<PROD>(std::move(bh));
0566     if LIKELY (not result.failedToGet()) {
0567       addToGotBranchIDs(*result.provenance());
0568     }
0569     return result;
0570   }
0571 
0572   template <typename PROD>
0573   PROD const& Event::get(EDGetTokenT<PROD> token) const noexcept(false) {
0574     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0575     auto result = convert_handle<PROD>(std::move(bh));
0576     if LIKELY (not result.failedToGet()) {
0577       addToGotBranchIDs(*result.provenance());
0578     }
0579     return *result;
0580   }
0581 
0582   template <typename ELEMENT>
0583   bool Event::getByLabel(InputTag const& tag, Handle<View<ELEMENT>>& result) const {
0584     result.clear();
0585     BasicHandle bh = provRecorder_.getMatchingSequenceByLabel_(TypeID(typeid(ELEMENT)), tag, moduleCallingContext_);
0586     if UNLIKELY (bh.failedToGet()) {
0587       Handle<View<ELEMENT>> h(std::move(bh.whyFailedFactory()));
0588       h.swap(result);
0589       return false;
0590     }
0591     result = fillView_<ELEMENT>(bh);
0592     return true;
0593   }
0594 
0595   template <typename ELEMENT>
0596   bool Event::getByLabel(std::string const& moduleLabel,
0597                          std::string const& productInstanceName,
0598                          Handle<View<ELEMENT>>& result) const {
0599     result.clear();
0600     BasicHandle bh = provRecorder_.getMatchingSequenceByLabel_(
0601         TypeID(typeid(ELEMENT)), moduleLabel, productInstanceName, emptyString_, moduleCallingContext_);
0602     if UNLIKELY (bh.failedToGet()) {
0603       Handle<View<ELEMENT>> h(std::move(bh.whyFailedFactory()));
0604       h.swap(result);
0605       return false;
0606     }
0607     result = fillView_<ELEMENT>(bh);
0608     return true;
0609   }
0610 
0611   template <typename ELEMENT>
0612   bool Event::getByLabel(std::string const& moduleLabel, Handle<View<ELEMENT>>& result) const {
0613     return getByLabel(moduleLabel, emptyString_, result);
0614   }
0615 
0616   template <typename ELEMENT>
0617   bool Event::getByToken(EDGetToken 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   bool Event::getByToken(EDGetTokenT<View<ELEMENT>> token, Handle<View<ELEMENT>>& result) const {
0631     result.clear();
0632     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(ELEMENT)), ELEMENT_TYPE, token, moduleCallingContext_);
0633     if UNLIKELY (bh.failedToGet()) {
0634       Handle<View<ELEMENT>> h(std::move(bh.whyFailedFactory()));
0635       h.swap(result);
0636       return false;
0637     }
0638     result = fillView_<ELEMENT>(bh);
0639     return true;
0640   }
0641 
0642   template <typename ELEMENT>
0643   Handle<View<ELEMENT>> Event::getHandle(EDGetTokenT<View<ELEMENT>> token) const {
0644     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(ELEMENT)), ELEMENT_TYPE, token, moduleCallingContext_);
0645     if UNLIKELY (bh.failedToGet()) {
0646       return Handle<View<ELEMENT>>(std::move(bh.whyFailedFactory()));
0647     }
0648     return fillView_<ELEMENT>(bh);
0649   }
0650 
0651   template <typename ELEMENT>
0652   View<ELEMENT> const& Event::get(EDGetTokenT<View<ELEMENT>> token) const noexcept(false) {
0653     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(ELEMENT)), ELEMENT_TYPE, token, moduleCallingContext_);
0654     if UNLIKELY (bh.failedToGet()) {
0655       bh.whyFailedFactory()->make()->raise();
0656     }
0657     return *fillView_<ELEMENT>(bh);
0658   }
0659 
0660   template <typename ELEMENT>
0661   Handle<View<ELEMENT>> Event::fillView_(BasicHandle& bh) const {
0662     std::vector<void const*> pointersToElements;
0663     FillViewHelperVector helpers;
0664     // the following must initialize the
0665     //  fill the helper vector
0666     bh.wrapper()->fillView(bh.id(), pointersToElements, helpers);
0667 
0668     auto newview = std::make_shared<View<ELEMENT>>(pointersToElements, helpers, &(productGetter()));
0669 
0670     addToGotBranchIDs(*bh.provenance());
0671     gotViews_.push_back(newview);
0672     return Handle<View<ELEMENT>>(newview.get(), bh.provenance());
0673   }
0674 
0675   // Free functions to retrieve a collection from the Event.
0676   // Will throw an exception if the collection is not available.
0677 
0678   template <typename T>
0679   T const& get(Event const& event, InputTag const& tag) noexcept(false) {
0680     Handle<T> handle;
0681     event.getByLabel(tag, handle);
0682     // throw if the handle is not valid
0683     return *handle.product();
0684   }
0685 
0686   template <typename T>
0687   T const& get(Event const& event, EDGetToken const& token) noexcept(false) {
0688     Handle<T> handle;
0689     event.getByToken(token, handle);
0690     // throw if the handle is not valid
0691     return *handle.product();
0692   }
0693 
0694   template <typename T>
0695   T const& get(Event const& event, EDGetTokenT<T> const& token) noexcept(false) {
0696     return event.get(token);
0697   }
0698 
0699 }  // namespace edm
0700 
0701 #endif  // FWCore_Framework_Event_h