Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-12-16 00:32:50

0001 #ifndef UtilAlgos_Matcher_h
0002 #define UtilAlgos_Matcher_h
0003 /* \class Matcher
0004  *
0005  * \author Luca Lista, INFN
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     }  // namespace helper
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   }  // namespace modules
0115 }  // namespace reco
0116 
0117 #endif