00001 #ifndef CandUtils_CandMatcherNew_h
00002 #define CandUtils_CandMatcherNew_h
00003
00004
00005
00006
00007
00008 #include "DataFormats/Candidate/interface/Candidate.h"
00009 #include "DataFormats/Common/interface/Association.h"
00010 #include "FWCore/Utilities/interface/EDMException.h"
00011 #include <algorithm>
00012 #include <iterator>
00013 #include <set>
00014
00015 namespace reco {
00016 namespace utilsNew {
00017
00018 template<typename C>
00019 class CandMatcher {
00020 public:
00022 typedef edm::Association<C> map_type;
00024 typedef typename edm::Association<C>::reference_type reference_type;
00025 typedef std::vector<const map_type *> map_vector;
00027 explicit CandMatcher(const map_vector & maps);
00029 explicit CandMatcher(const map_type & map);
00031 virtual ~CandMatcher();
00033 reference_type operator[](const reco::Candidate &) const;
00035 typename map_type::refprod_type ref() const { return map_.ref(); }
00036 protected:
00038 map_type map_;
00039
00040 private:
00041 };
00042
00043 template<typename C>
00044 CandMatcher<C>::CandMatcher(const typename CandMatcher<C>::map_vector & maps):
00045 map_() {
00046 for(typename map_vector::const_iterator i = maps.begin(); i != maps.end(); ++ i)
00047 map_ += **i;
00048 }
00049
00050 template<typename C>
00051 CandMatcher<C>::CandMatcher(const typename CandMatcher<C>::map_type & map):
00052 map_(map) {
00053 }
00054
00055 template<typename C>
00056 CandMatcher<C>::~CandMatcher() {
00057 }
00058
00059 template<typename C>
00060 typename CandMatcher<C>::reference_type CandMatcher<C>::operator[](const reco::Candidate & c) const {
00061 using namespace reco;
00062 using namespace std;
00063 if (c.hasMasterClone()) {
00064 CandidateBaseRef master = c.masterClone();
00065 return master->numberOfDaughters() == 0 ? map_[master] : (*this)[*master];
00066 }
00067 size_t nDau = c.numberOfDaughters();
00068 if(nDau == 0) return reference_type();
00069 set<size_t> momIdx, common, tmp;
00070 for(size_t i = 0; i < nDau; ++ i) {
00071 const Candidate & d = * c.daughter(i);
00072 reference_type m = (*this)[d];
00073 if (m.isNull()) return reference_type();
00074 momIdx.clear();
00075 while(m->numberOfMothers() == 1) {
00076 m = m->motherRef();
00077 momIdx.insert(m.key());
00078 }
00079 if(momIdx.size() == 0) return reference_type();
00080 if (common.size() == 0) common = momIdx;
00081 else {
00082 tmp.clear();
00083 set_intersection(common.begin(), common.end(),
00084 momIdx.begin(), momIdx.end(),
00085 inserter(tmp, tmp.begin()));
00086 swap(common, tmp);
00087 }
00088 if (common.size() == 0) return reference_type();
00089 }
00090 size_t idx = * max_element(common.begin(), common.end());
00091 return reference_type(map_.ref(), idx);
00092 }
00093
00094 }
00095 }
00096
00097 #endif