File indexing completed on 2024-04-06 12:01:03
0001 #ifndef CandUtils_CandMatcherNew_h
0002 #define CandUtils_CandMatcherNew_h
0003
0004
0005
0006
0007
0008 #include "DataFormats/Candidate/interface/Candidate.h"
0009 #include "DataFormats/Common/interface/Association.h"
0010 #include "FWCore/Utilities/interface/EDMException.h"
0011 #include <algorithm>
0012 #include <iterator>
0013 #include <set>
0014
0015 namespace reco {
0016 namespace utilsNew {
0017
0018 template <typename C>
0019 class CandMatcher {
0020 public:
0021
0022 typedef edm::Association<C> map_type;
0023
0024 typedef typename edm::Association<C>::reference_type reference_type;
0025 typedef std::vector<const map_type *> map_vector;
0026
0027 explicit CandMatcher(const map_vector &maps);
0028
0029 explicit CandMatcher(const map_type &map);
0030
0031 virtual ~CandMatcher();
0032
0033 reference_type operator[](const reco::Candidate &) const;
0034
0035 typename map_type::refprod_type ref() const { return map_.ref(); }
0036
0037 protected:
0038
0039 map_type map_;
0040
0041 private:
0042 };
0043
0044 template <typename C>
0045 CandMatcher<C>::CandMatcher(const typename CandMatcher<C>::map_vector &maps) : map_() {
0046 for (typename map_vector::const_iterator i = maps.begin(); i != maps.end(); ++i)
0047 map_ += **i;
0048 }
0049
0050 template <typename C>
0051 CandMatcher<C>::CandMatcher(const typename CandMatcher<C>::map_type &map) : map_(map) {}
0052
0053 template <typename C>
0054 CandMatcher<C>::~CandMatcher() {}
0055
0056 template <typename C>
0057 typename CandMatcher<C>::reference_type CandMatcher<C>::operator[](const reco::Candidate &c) const {
0058 using namespace reco;
0059 using namespace std;
0060 if (c.hasMasterClone()) {
0061 const CandidateBaseRef &master = c.masterClone();
0062 return master->numberOfDaughters() == 0 ? map_[master] : (*this)[*master];
0063 }
0064 size_t nDau = c.numberOfDaughters();
0065 if (nDau == 0)
0066 return reference_type();
0067 set<size_t> momIdx, common, tmp;
0068 for (size_t i = 0; i < nDau; ++i) {
0069 const Candidate &d = *c.daughter(i);
0070 reference_type m = (*this)[d];
0071 if (m.isNull())
0072 return reference_type();
0073 momIdx.clear();
0074 while (m->numberOfMothers() == 1) {
0075 m = m->motherRef();
0076 momIdx.insert(m.key());
0077 }
0078 if (momIdx.empty())
0079 return reference_type();
0080 if (common.empty())
0081 common = momIdx;
0082 else {
0083 tmp.clear();
0084 set_intersection(common.begin(), common.end(), momIdx.begin(), momIdx.end(), inserter(tmp, tmp.begin()));
0085 swap(common, tmp);
0086 }
0087 if (common.empty())
0088 return reference_type();
0089 }
0090 size_t idx = *max_element(common.begin(), common.end());
0091 return reference_type(map_.ref(), idx);
0092 }
0093
0094 }
0095 }
0096
0097 #endif