Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:01:08

0001 #ifndef RecoAlgos_CandidateProducer_h
0002 #define RecoAlgos_CandidateProducer_h
0003 /** \class CandidateProducer
0004  *
0005  * Framework module that produces a collection
0006  * of candidates from generic compoment
0007  *
0008  * \author Luca Lista, INFN
0009  *
0010  * \version $Revision: 1.4 $
0011  *
0012  * $Id: CandidateProducer.h,v 1.4 2010/02/11 00:10:53 wmtan Exp $
0013  *
0014  */
0015 #include "FWCore/Utilities/interface/InputTag.h"
0016 #include "FWCore/ParameterSet/interface/ParameterSetfwd.h"
0017 #include "FWCore/Framework/interface/stream/EDProducer.h"
0018 #include "FWCore/Framework/interface/Event.h"
0019 #include "DataFormats/Common/interface/Handle.h"
0020 #include "DataFormats/Candidate/interface/CandidateFwd.h"
0021 #include "CommonTools/UtilAlgos/interface/MasterCollectionHelper.h"
0022 #include "CommonTools/UtilAlgos/interface/AnySelector.h"
0023 #include "CommonTools/UtilAlgos/interface/EventSetupInitTrait.h"
0024 
0025 namespace converter {
0026   namespace helper {
0027     template <typename T>
0028     struct CandConverter {};
0029 
0030     struct ConcreteCreator {
0031       template <typename CColl, typename Comp, typename Conv>
0032       static void create(size_t idx, CColl& cands, const Comp& components, Conv& converter) {
0033         typename Conv::Candidate c;
0034         typedef edm::Ref<std::vector<typename Conv::value_type> > ref_type;
0035         ref_type ref = components.template getConcreteRef<ref_type>(idx);
0036         converter.convert(ref, c);
0037         cands.push_back(c);
0038       }
0039     };
0040 
0041     struct PolymorphicCreator {
0042       template <typename CColl, typename Comp, typename Conv>
0043       static void create(size_t idx, CColl& cands, const Comp& components, Conv& converter) {
0044         typename Conv::Candidate* c = new typename Conv::Candidate;
0045         typedef edm::Ref<std::vector<typename Conv::value_type> > ref_type;
0046         ref_type ref = components.template getConcreteRef<ref_type>(idx);
0047         converter.convert(ref, *c);
0048         cands.push_back(c);
0049       }
0050     };
0051 
0052     template <typename CColl>
0053     struct CandCreator {
0054       typedef ConcreteCreator type;
0055     };
0056 
0057     template <>
0058     struct CandCreator<reco::CandidateCollection> {
0059       typedef PolymorphicCreator type;
0060     };
0061   }  // namespace helper
0062 }  // namespace converter
0063 
0064 template <typename TColl,
0065           typename CColl,
0066           typename Selector = AnySelector,
0067           typename Conv = typename converter::helper::CandConverter<typename TColl::value_type>::type,
0068           typename Creator = typename converter::helper::CandCreator<CColl>::type,
0069           typename Init = typename ::reco::modules::EventSetupInit<Selector>::type>
0070 class CandidateProducer : public edm::stream::EDProducer<> {
0071 public:
0072   /// constructor from parameter set
0073   CandidateProducer(const edm::ParameterSet& cfg)
0074       : srcToken_(consumes<TColl>(cfg.template getParameter<edm::InputTag>("src"))),
0075         converter_(cfg, consumesCollector()),
0076         selectorInit_(consumesCollector()),
0077         selector_(reco::modules::make<Selector>(cfg, consumesCollector())),
0078         initialized_(false) {
0079     produces<CColl>();
0080   }
0081   /// destructor
0082   ~CandidateProducer() override {}
0083 
0084 private:
0085   /// begin job (first run)
0086   void beginRun(const edm::Run&, const edm::EventSetup& es) override {
0087     if (!initialized_) {
0088       converter_.beginFirstRun(es);
0089       initialized_ = true;
0090     }
0091   }
0092   /// process one event
0093   void produce(edm::Event& evt, const edm::EventSetup& es) override {
0094     edm::Handle<TColl> src;
0095     evt.getByToken(srcToken_, src);
0096     selectorInit_.init(selector_, evt, es);
0097     ::helper::MasterCollection<TColl> master(src, evt);
0098     std::unique_ptr<CColl> cands(new CColl);
0099     if (!src->empty()) {
0100       size_t size = src->size();
0101       cands->reserve(size);
0102       for (size_t idx = 0; idx != size; ++idx) {
0103         if (selector_((*src)[idx]))
0104           Creator::create(master.index(idx), *cands, master, converter_);
0105       }
0106     }
0107     evt.put(std::move(cands));
0108   }
0109   /// label of source collection and tag
0110   edm::EDGetTokenT<TColl> srcToken_;
0111   /// converter helper
0112   Conv converter_;
0113   /// selector
0114   Init selectorInit_;
0115   Selector selector_;
0116   /// particles initialized?
0117   bool initialized_;
0118 };
0119 
0120 #endif