Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:49:56

0001 #ifndef CandUtils_CandMatcherNew_h
0002 #define CandUtils_CandMatcherNew_h
0003 /* class CandMatcher

0004  *

0005  * \author Luca Lista, INFN

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       /// map type

0022       typedef edm::Association<C> map_type;
0023       /// ref type

0024       typedef typename edm::Association<C>::reference_type reference_type;
0025       typedef std::vector<const map_type *> map_vector;
0026       /// constructor

0027       explicit CandMatcher(const map_vector &maps);
0028       /// constructor

0029       explicit CandMatcher(const map_type &map);
0030       /// destructor

0031       virtual ~CandMatcher();
0032       /// get match from transient reference

0033       reference_type operator[](const reco::Candidate &) const;
0034       /// reference to matched collection

0035       typename map_type::refprod_type ref() const { return map_.ref(); }
0036 
0037     protected:
0038       /// match map at leaf level

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   }  // namespace utilsNew

0095 }  // namespace reco

0096 
0097 #endif