00001 #ifndef UtilAlgos_Matcher_h
00002 #define UtilAlgos_Matcher_h
00003
00004
00005
00006
00007
00008 #include "FWCore/Framework/interface/EDProducer.h"
00009 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00010 #include "FWCore/Utilities/interface/InputTag.h"
00011 #include "CommonTools/UtilAlgos/interface/DeltaR.h"
00012 #include "FWCore/Framework/interface/Event.h"
00013 #include "DataFormats/Common/interface/Handle.h"
00014 #include "DataFormats/Common/interface/AssociationMap.h"
00015 #include "DataFormats/Common/interface/OneToOne.h"
00016 #include "DataFormats/Common/interface/getRef.h"
00017
00018 namespace reco {
00019 namespace modules {
00020 template<typename C1, typename C2, typename M = edm::AssociationMap<edm::OneToOne<C1, C2> > >
00021 class MatcherBase : public edm::EDProducer {
00022 public:
00023 MatcherBase( const edm::ParameterSet & );
00024 ~MatcherBase();
00025
00026 protected:
00027 typedef typename C1::value_type T1;
00028 typedef typename C2::value_type T2;
00029 typedef M MatchMap;
00030
00031 private:
00032 void produce( edm::Event&, const edm::EventSetup& );
00033 edm::InputTag src_;
00034 edm::InputTag matched_;
00035 double distMin_;
00036 virtual double matchDistance( const T1 &, const T2 & ) const = 0;
00037 virtual bool select( const T1 &, const T2 & ) const = 0;
00038 };
00039
00040 template<typename C1, typename C2,
00041 typename S, typename D = DeltaR<typename C1::value_type, typename C2::value_type>,
00042 typename M = edm::AssociationMap<edm::OneToOne<C1, C2> > >
00043 class Matcher : public MatcherBase<C1, C2, M> {
00044 public:
00045 Matcher( const edm::ParameterSet & cfg ) :
00046 MatcherBase<C1, C2, M>( cfg ),
00047 select_( reco::modules::make<S>( cfg ) ),
00048 distance_( reco::modules::make<D>( cfg ) ) { }
00049 ~Matcher() { }
00050 private:
00051 typedef typename MatcherBase<C1, C2, M>::T1 T1;
00052 typedef typename MatcherBase<C1, C2, M>::T2 T2;
00053 typedef typename MatcherBase<C1, C2, M>::MatchMap MatchMap;
00054
00055 double matchDistance( const T1 & c1, const T2 & c2 ) const {
00056 return distance_( c1, c2 );
00057 }
00058 bool select( const T1 & c1, const T2 & c2 ) const {
00059 return select_( c1, c2 );
00060 }
00061 S select_;
00062 D distance_;
00063 };
00064
00065 namespace helper {
00066 typedef std::pair<size_t, double> MatchPair;
00067
00068 struct SortBySecond {
00069 bool operator()( const MatchPair & p1, const MatchPair & p2 ) const {
00070 return p1.second < p2.second;
00071 }
00072 };
00073 }
00074
00075 template<typename C1, typename C2, typename M>
00076 MatcherBase<C1, C2, M>::MatcherBase( const edm::ParameterSet & cfg ) :
00077 src_( cfg.template getParameter<edm::InputTag>( "src" ) ),
00078 matched_( cfg.template getParameter<edm::InputTag>( "matched" ) ),
00079 distMin_( cfg.template getParameter<double>( "distMin" ) ) {
00080 produces<MatchMap>();
00081 }
00082
00083 template<typename C1, typename C2, typename M>
00084 MatcherBase<C1, C2, M>::~MatcherBase() { }
00085
00086 template<typename C1, typename C2, typename M>
00087 void MatcherBase<C1, C2, M>::produce( edm::Event& evt, const edm::EventSetup& ) {
00088 using namespace edm;
00089 using namespace std;
00090 Handle<C2> matched;
00091 evt.getByLabel( matched_, matched );
00092 Handle<C1> cands;
00093 evt.getByLabel( src_, cands );
00094 typedef typename MatchMap::ref_type ref_type;
00095 typedef typename ref_type::key_type key_ref_type;
00096 typedef typename ref_type::value_type value_ref_type;
00097 auto_ptr<MatchMap> matchMap( new MatchMap( ref_type( key_ref_type( cands ),
00098 value_ref_type( matched ) ) ) );
00099 for( size_t c = 0; c != cands->size(); ++ c ) {
00100 const T1 & cand = (*cands)[ c ];
00101 vector<helper::MatchPair> v;
00102 for( size_t m = 0; m != matched->size(); ++ m ) {
00103 const T2 & match = ( * matched )[ m ];
00104 if ( select( cand, match ) ) {
00105 double dist = matchDistance( cand, match );
00106 if ( dist < distMin_ ) v.push_back( make_pair( m, dist ) );
00107 }
00108 }
00109 if ( v.size() > 0 ) {
00110 size_t mMin = min_element( v.begin(), v.end(), helper::SortBySecond() )->first;
00111 typedef typename MatchMap::key_type key_type;
00112 typedef typename MatchMap::data_type data_type;
00113 matchMap->insert( edm::getRef( cands, c ), edm::getRef( matched, mMin ) );
00114 }
00115 }
00116 evt.put( matchMap );
00117 }
00118
00119 }
00120 }
00121
00122 #endif