CMS 3D CMS Logo

FastCandMatcher.h

Go to the documentation of this file.
00001 #ifndef CandUtils_FastCandMatcher_h
00002 #define CandUtils_FastCandMatcher_h
00003 /* class CandMatcher
00004  *
00005  * \author Luca Lista, INFN
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     // check for composite candidate c
00054     // navigate to daughters and find parent matches
00055     set<const reco::Candidate *> momsIntersection, momDaughters, tmp;
00056     for( Candidate::const_iterator dau = c.begin(); dau != c.end(); ++ dau ) {
00057       // check here generically if status == 3, then descend down to one more level
00058       const Candidate * dauMatch = (*this)( * dau );
00059       // if a daughter does not match, return a null ref.
00060       if ( dauMatch == 0 ) return 0;
00061       // get matched mothers
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           // assume a single mother at this point...
00068           mom = mom->mother( 0 );
00069         }
00070         momDaughters.insert( mom );
00071       }
00072       // if no mother was found return null reference
00073       if ( momDaughters.size() == 0 ) return 0;
00074       // the first time, momsIntersection is set to momDaughters
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     // if multiple mothers are found, return a null reference
00086     if ( momsIntersection.size() > 1 ) return 0;
00087     // return a reference to the unique mother
00088     return * momsIntersection.begin();
00089   } else {
00090     // check for non-composite (leaf) candidate 
00091     // if one of the maps contains the candidate c
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

Generated on Tue Jun 9 17:41:03 2009 for CMSSW by  doxygen 1.5.4