File indexing completed on 2024-04-06 12:01:08
0001 #ifndef RecoAlgos_CandidateProducer_h
0002 #define RecoAlgos_CandidateProducer_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
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 }
0062 }
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
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
0082 ~CandidateProducer() override {}
0083
0084 private:
0085
0086 void beginRun(const edm::Run&, const edm::EventSetup& es) override {
0087 if (!initialized_) {
0088 converter_.beginFirstRun(es);
0089 initialized_ = true;
0090 }
0091 }
0092
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
0110 edm::EDGetTokenT<TColl> srcToken_;
0111
0112 Conv converter_;
0113
0114 Init selectorInit_;
0115 Selector selector_;
0116
0117 bool initialized_;
0118 };
0119
0120 #endif