00001 #ifndef RecoAlgos_CandidateProducer_h 00002 #define RecoAlgos_CandidateProducer_h 00003 00015 #include "FWCore/ParameterSet/interface/InputTag.h" 00016 #include "FWCore/ParameterSet/interface/ParameterSetfwd.h" 00017 #include "FWCore/Framework/interface/EDProducer.h" 00018 #include "FWCore/Framework/interface/Event.h" 00019 #include "DataFormats/Common/interface/Handle.h" 00020 #include "DataFormats/Candidate/interface/CandidateFwd.h" 00021 #include "PhysicsTools/UtilAlgos/interface/MasterCollectionHelper.h" 00022 #include "PhysicsTools/UtilAlgos/interface/AnySelector.h" 00023 #include "PhysicsTools/UtilAlgos/interface/EventSetupInitTrait.h" 00024 00025 namespace converter { 00026 namespace helper { 00027 template<typename T> 00028 struct CandConverter { }; 00029 00030 struct ConcreteCreator { 00031 template<typename CColl, typename Comp, typename Conv> 00032 static void create(size_t idx, CColl & cands, const Comp & components, Conv & converter) { 00033 typename Conv::Candidate c; 00034 typedef edm::Ref<std::vector<typename Conv::value_type> > ref_type; 00035 ref_type ref = components.template getConcreteRef<ref_type>(idx); 00036 converter.convert(ref, c); 00037 cands.push_back(c); 00038 } 00039 }; 00040 00041 struct PolymorphicCreator { 00042 template<typename CColl, typename Comp, typename Conv> 00043 static void create(size_t idx, CColl & cands, const Comp & components, Conv & converter) { 00044 typename Conv::Candidate * c = new typename Conv::Candidate; 00045 typedef edm::Ref<std::vector<typename Conv::value_type> > ref_type; 00046 ref_type ref = components.template getConcreteRef<ref_type>(idx); 00047 converter.convert(ref, * c); 00048 cands.push_back(c); 00049 } 00050 }; 00051 00052 template<typename CColl> 00053 struct CandCreator { 00054 typedef ConcreteCreator type; 00055 }; 00056 00057 template<> 00058 struct CandCreator<reco::CandidateCollection> { 00059 typedef PolymorphicCreator type; 00060 }; 00061 } 00062 } 00063 00064 template<typename TColl, typename CColl, typename Selector = AnySelector, 00065 typename Conv = typename converter::helper::CandConverter<typename TColl::value_type>::type, 00066 typename Creator = typename converter::helper::CandCreator<CColl>::type, 00067 typename Init = typename ::reco::modules::EventSetupInit<Selector>::type> 00068 class CandidateProducer : public edm::EDProducer { 00069 public: 00071 CandidateProducer(const edm::ParameterSet & cfg) : 00072 src_(cfg.template getParameter<edm::InputTag>("src")), 00073 converter_(cfg), 00074 selector_(reco::modules::make<Selector>(cfg)){ 00075 produces<CColl>(); 00076 } 00078 ~CandidateProducer() { } 00079 00080 private: 00082 void beginJob(const edm::EventSetup& es) { converter_.beginJob(es); } 00084 void produce(edm::Event& evt, const edm::EventSetup& es) { 00085 edm::Handle<TColl> src; 00086 evt.getByLabel(src_, src); 00087 Init::init(selector_, evt, es); 00088 ::helper::MasterCollection<TColl> master(src); 00089 std::auto_ptr<CColl> cands(new CColl); 00090 if(src->size()!= 0) { 00091 size_t size = src->size(); 00092 cands->reserve(size); 00093 for(size_t idx = 0; idx != size; ++ idx) { 00094 if(selector_((*src)[idx])) 00095 Creator::create(master.index(idx), *cands, master, converter_); 00096 } 00097 } 00098 evt.put(cands); 00099 } 00101 edm::InputTag src_; 00103 Conv converter_; 00105 Selector selector_; 00106 }; 00107 00108 #endif