File indexing completed on 2024-04-06 12:01:16
0001 #ifndef UtilAlgos_Matcher_h
0002 #define UtilAlgos_Matcher_h
0003
0004
0005
0006
0007
0008 #include "FWCore/Framework/interface/global/EDProducer.h"
0009 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0010 #include "FWCore/Utilities/interface/InputTag.h"
0011 #include "CommonTools/UtilAlgos/interface/DeltaR.h"
0012 #include "FWCore/Framework/interface/Event.h"
0013 #include "DataFormats/Common/interface/Handle.h"
0014 #include "DataFormats/Common/interface/AssociationMap.h"
0015 #include "DataFormats/Common/interface/OneToOne.h"
0016 #include "DataFormats/Common/interface/getRef.h"
0017
0018 namespace reco {
0019 namespace modules {
0020 template <typename C1, typename C2, typename M = edm::AssociationMap<edm::OneToOne<C1, C2> > >
0021 class MatcherBase : public edm::global::EDProducer<> {
0022 public:
0023 MatcherBase(const edm::ParameterSet&);
0024 ~MatcherBase() override;
0025
0026 protected:
0027 typedef typename C1::value_type T1;
0028 typedef typename C2::value_type T2;
0029 typedef M MatchMap;
0030
0031 private:
0032 void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
0033 edm::EDGetTokenT<C1> srcToken_;
0034 edm::EDGetTokenT<C2> matchedToken_;
0035 double distMin_;
0036 virtual double matchDistance(const T1&, const T2&) const = 0;
0037 virtual bool select(const T1&, const T2&) const = 0;
0038 };
0039
0040 template <typename C1,
0041 typename C2,
0042 typename S,
0043 typename D = DeltaR<typename C1::value_type, typename C2::value_type>,
0044 typename M = edm::AssociationMap<edm::OneToOne<C1, C2> > >
0045 class Matcher : public MatcherBase<C1, C2, M> {
0046 public:
0047 Matcher(const edm::ParameterSet& cfg)
0048 : MatcherBase<C1, C2, M>(cfg), select_(reco::modules::make<S>(cfg)), distance_(reco::modules::make<D>(cfg)) {}
0049 ~Matcher() override {}
0050
0051 private:
0052 typedef typename MatcherBase<C1, C2, M>::T1 T1;
0053 typedef typename MatcherBase<C1, C2, M>::T2 T2;
0054 typedef typename MatcherBase<C1, C2, M>::MatchMap MatchMap;
0055
0056 double matchDistance(const T1& c1, const T2& c2) const override { return distance_(c1, c2); }
0057 bool select(const T1& c1, const T2& c2) const override { return select_(c1, c2); }
0058 S select_;
0059 D distance_;
0060 };
0061
0062 namespace helper {
0063 typedef std::pair<size_t, double> MatchPair;
0064
0065 struct SortBySecond {
0066 bool operator()(const MatchPair& p1, const MatchPair& p2) const { return p1.second < p2.second; }
0067 };
0068 }
0069
0070 template <typename C1, typename C2, typename M>
0071 MatcherBase<C1, C2, M>::MatcherBase(const edm::ParameterSet& cfg)
0072 : srcToken_(consumes<C1>(cfg.template getParameter<edm::InputTag>("src"))),
0073 matchedToken_(consumes<C2>(cfg.template getParameter<edm::InputTag>("matched"))),
0074 distMin_(cfg.template getParameter<double>("distMin")) {
0075 produces<MatchMap>();
0076 }
0077
0078 template <typename C1, typename C2, typename M>
0079 MatcherBase<C1, C2, M>::~MatcherBase() {}
0080
0081 template <typename C1, typename C2, typename M>
0082 void MatcherBase<C1, C2, M>::produce(edm::StreamID, edm::Event& evt, const edm::EventSetup&) const {
0083 using namespace edm;
0084 using namespace std;
0085 Handle<C2> matched;
0086 evt.getByToken(matchedToken_, matched);
0087 Handle<C1> cands;
0088 evt.getByToken(srcToken_, cands);
0089 typedef typename MatchMap::ref_type ref_type;
0090 typedef typename ref_type::key_type key_ref_type;
0091 typedef typename ref_type::value_type value_ref_type;
0092 unique_ptr<MatchMap> matchMap(new MatchMap(ref_type(key_ref_type(cands), value_ref_type(matched))));
0093 for (size_t c = 0; c != cands->size(); ++c) {
0094 const T1& cand = (*cands)[c];
0095 vector<helper::MatchPair> v;
0096 for (size_t m = 0; m != matched->size(); ++m) {
0097 const T2& match = (*matched)[m];
0098 if (select(cand, match)) {
0099 double dist = matchDistance(cand, match);
0100 if (dist < distMin_)
0101 v.push_back(make_pair(m, dist));
0102 }
0103 }
0104 if (!v.empty()) {
0105 size_t mMin = min_element(v.begin(), v.end(), helper::SortBySecond())->first;
0106 typedef typename MatchMap::key_type key_type;
0107 typedef typename MatchMap::data_type data_type;
0108 matchMap->insert(edm::getRef(cands, c), edm::getRef(matched, mMin));
0109 }
0110 }
0111 evt.put(std::move(matchMap));
0112 }
0113
0114 }
0115 }
0116
0117 #endif