CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/CommonTools/UtilAlgos/interface/Matcher.h

Go to the documentation of this file.
00001 #ifndef UtilAlgos_Matcher_h
00002 #define UtilAlgos_Matcher_h
00003 /* \class Matcher
00004  *
00005  * \author Luca Lista, INFN
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