00001 #ifndef CandUtils_FastCandMatcher_h
00002 #define CandUtils_FastCandMatcher_h
00003
00004
00005
00006
00007
00008 #include <set>
00009 #include "DataFormats/Candidate/interface/Candidate.h"
00010 #include "DataFormats/Common/interface/AssociationMap.h"
00011 #include "DataFormats/Common/interface/OneToOne.h"
00012 #include "FWCore/Utilities/interface/EDMException.h"
00013
00014 template<typename C>
00015 class FastCandMatcher {
00016 public:
00018 typedef edm::AssociationMap<edm::OneToOne<C, reco::CandidateCollection> > map_type;
00020 typedef std::vector<const map_type *> map_vector;
00022 explicit FastCandMatcher( const map_vector & maps );
00024 explicit FastCandMatcher( const map_type & map );
00026 const reco::Candidate * operator()( const reco::Candidate & ) const;
00027
00028 protected:
00029 const std::vector<const map_type *> & maps() const { return maps_; }
00030 private:
00032 std::vector<const map_type *> maps_;
00033 };
00034
00035 template<typename C>
00036 FastCandMatcher<C>::FastCandMatcher( const typename FastCandMatcher<C>::map_vector & maps ):
00037 maps_( maps ) {
00038 }
00039
00040 template<typename C>
00041 FastCandMatcher<C>::FastCandMatcher( const typename FastCandMatcher<C>::map_type & map ):
00042 maps_( 1, & map ) {
00043 }
00044
00045 template<typename C>
00046 const reco::Candidate * FastCandMatcher<C>::operator()( const reco::Candidate & c ) const {
00047 using namespace reco;
00048 using namespace std;
00049 if ( c.hasMasterClone() )
00050 return (*this)( * c.masterClone() );
00051 unsigned int nDau = c.numberOfDaughters();
00052 if ( nDau > 0 ) {
00053
00054
00055 set<const reco::Candidate *> momsIntersection, momDaughters, tmp;
00056 for( Candidate::const_iterator dau = c.begin(); dau != c.end(); ++ dau ) {
00057
00058 const Candidate * dauMatch = (*this)( * dau );
00059
00060 if ( dauMatch == 0 ) return 0;
00061
00062 size_t mothers = dauMatch->numberOfMothers();
00063 for( size_t i = 0; i < mothers; ++ i ) {
00064 const reco::Candidate * mom = dauMatch->mother( i );
00065 if ( mom != 0 && mom->pdgId() == dauMatch->pdgId() &&
00066 mom->status() == 3 && dauMatch->status() == 1 ) {
00067
00068 mom = mom->mother( 0 );
00069 }
00070 momDaughters.insert( mom );
00071 }
00072
00073 if ( momDaughters.size() == 0 ) return 0;
00074
00075 if ( momsIntersection.size() == 0 ) momsIntersection = momDaughters;
00076 else {
00077 tmp.clear();
00078 set_intersection( momsIntersection.begin(), momsIntersection.end(),
00079 momDaughters.begin(), momDaughters.end(),
00080 inserter( tmp, tmp.begin() ) );
00081 swap( momsIntersection, tmp );
00082 }
00083 if ( momsIntersection.size() == 0 ) return 0;
00084 }
00085
00086 if ( momsIntersection.size() > 1 ) return 0;
00087
00088 return * momsIntersection.begin();
00089 } else {
00090
00091
00092 for( typename std::vector<const map_type *>::const_iterator m = maps_.begin();
00093 m != maps_.end(); ++ m ) {
00094 for( typename map_type::const_iterator i = (*m)->begin(); i != (*m)->end(); ++ i ) {
00095 if ( & * i->key == & c )
00096 return & * i->val;
00097 }
00098 }
00099 return 0;
00100 }
00101 }
00102
00103 #endif