/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
CommonTools/CandUtils/interface/CandCombinerBase.h
373 строки
16 KB
Cms Build
Clang-Format
03 июн 2019, 06:44
03 июн 2019, 06:44
6a63925
Код
Авторство
О чём код?
#ifndef CommonTools_CandUtils_CandCombinerBase_h #define CommonTools_CandUtils_CandCombinerBase_h /** \class CandCombinerBase * * \author Luca Lista, INFN * */ #include "DataFormats/Candidate/interface/Candidate.h" #include "DataFormats/Candidate/interface/OverlapChecker.h" #include <vector> #include <string> template <typename OutputCollection, typename CandPtr> class CandCombinerBase { public: typedef std::vector<std::string> vstring; /// default construct explicit CandCombinerBase(const std::string = ""); /// construct from two charge values CandCombinerBase(int, int, const std::string = ""); /// construct from three charge values CandCombinerBase(int, int, int, const std::string = ""); /// construct from four charge values CandCombinerBase(int, int, int, int, const std::string = ""); /// constructor from a selector, specifying optionally to check for charge CandCombinerBase(bool checkCharge, bool checkOverlap, const std::vector<int> &, const std::string = ""); /// destructor virtual ~CandCombinerBase(); /// return all selected candidate pairs std::unique_ptr<OutputCollection> combine(const std::vector<edm::Handle<reco::CandidateView> > &, const vstring & = vstring()) const; /// return all selected candidate pairs std::unique_ptr<OutputCollection> combine(const edm::Handle<reco::CandidateView> &, const vstring & = vstring()) const; /// return all selected candidate pairs std::unique_ptr<OutputCollection> combine(const edm::Handle<reco::CandidateView> &, const edm::Handle<reco::CandidateView> &, const vstring & = vstring()) const; /// return all selected candidate pairs std::unique_ptr<OutputCollection> combine(const edm::Handle<reco::CandidateView> &, const edm::Handle<reco::CandidateView> &, const edm::Handle<reco::CandidateView> &, const vstring & = vstring()) const; /// return all selected candidate pairs std::unique_ptr<OutputCollection> combine(const edm::Handle<reco::CandidateView> &, const edm::Handle<reco::CandidateView> &, const edm::Handle<reco::CandidateView> &, const edm::Handle<reco::CandidateView> &, const vstring & = vstring()) const; private: /// verify that the two candidate don't overlap and check charge bool preselect(const reco::Candidate &, const reco::Candidate &) const; /// returns a composite candidate combined from two daughters void combine(typename OutputCollection::value_type &, const CandPtr &, const CandPtr &, const std::string = "", const std::string = "") const; /// temporary candidate stack typedef std::vector< std::pair<std::pair<CandPtr, size_t>, std::vector<edm::Handle<reco::CandidateView> >::const_iterator> > CandStack; typedef std::vector<int> ChargeStack; /// returns a composite candidate combined from two daughters void combine(size_t collectionIndex, CandStack &, ChargeStack &, std::vector<edm::Handle<reco::CandidateView> >::const_iterator begin, std::vector<edm::Handle<reco::CandidateView> >::const_iterator end, OutputCollection *comps, const vstring &name = vstring()) const; /// select a candidate virtual bool select(const reco::Candidate &) const = 0; /// select a candidate pair virtual bool selectPair(const reco::Candidate &c1, const reco::Candidate &c2) const = 0; /// set kinematics to reconstructed composite virtual void setup(typename OutputCollection::value_type &) const = 0; /// add candidate daughter virtual void addDaughter(typename OutputCollection::value_type &cmp, const CandPtr &c, const std::string = "") const = 0; /// flag to specify the checking of electric charge bool checkCharge_; /// flag to specify the checking of overlaps bool checkOverlap_; /// electric charges of the daughters std::vector<int> dauCharge_; /// utility to check candidate daughters overlap OverlapChecker overlap_; /// composite name (if applies) std::string name_; }; template <typename OutputCollection, typename CandPtr> CandCombinerBase<OutputCollection, CandPtr>::CandCombinerBase(const std::string name) : checkCharge_(false), checkOverlap_(true), dauCharge_(), overlap_(), name_(name) {} template <typename OutputCollection, typename CandPtr> CandCombinerBase<OutputCollection, CandPtr>::CandCombinerBase(int q1, int q2, const std::string name) : checkCharge_(true), checkOverlap_(true), dauCharge_(2), overlap_(), name_(name) { dauCharge_[0] = q1; dauCharge_[1] = q2; } template <typename OutputCollection, typename CandPtr> CandCombinerBase<OutputCollection, CandPtr>::CandCombinerBase(int q1, int q2, int q3, const std::string name) : checkCharge_(true), checkOverlap_(true), dauCharge_(3), overlap_(), name_(name) { dauCharge_[0] = q1; dauCharge_[1] = q2; dauCharge_[2] = q3; } template <typename OutputCollection, typename CandPtr> CandCombinerBase<OutputCollection, CandPtr>::CandCombinerBase(int q1, int q2, int q3, int q4, const std::string name) : checkCharge_(true), checkOverlap_(true), dauCharge_(4), overlap_(), name_(name) { dauCharge_[0] = q1; dauCharge_[1] = q2; dauCharge_[2] = q3; dauCharge_[3] = q4; } template <typename OutputCollection, typename CandPtr> CandCombinerBase<OutputCollection, CandPtr>::CandCombinerBase(bool checkCharge, bool checkOverlap, const std::vector<int> &dauCharge, const std::string name) : checkCharge_(checkCharge), checkOverlap_(checkOverlap), dauCharge_(dauCharge), overlap_(), name_(name) {} template <typename OutputCollection, typename CandPtr> CandCombinerBase<OutputCollection, CandPtr>::~CandCombinerBase() {} template <typename OutputCollection, typename CandPtr> bool CandCombinerBase<OutputCollection, CandPtr>::preselect(const reco::Candidate &c1, const reco::Candidate &c2) const { if (checkCharge_) { int dq1 = dauCharge_[0], dq2 = dauCharge_[1], q1 = c1.charge(), q2 = c2.charge(); bool matchCharge = (q1 == dq1 && q2 == dq2) || (q1 == -dq1 && q2 == -dq2); if (!matchCharge) return false; } if (checkOverlap_ && overlap_(c1, c2)) return false; return selectPair(c1, c2); } template <typename OutputCollection, typename CandPtr> void CandCombinerBase<OutputCollection, CandPtr>::combine(typename OutputCollection::value_type &cmp, const CandPtr &c1, const CandPtr &c2, const std::string name1, const std::string name2) const { addDaughter(cmp, c1, name1); addDaughter(cmp, c2, name2); setup(cmp); } template <typename OutputCollection, typename CandPtr> std::unique_ptr<OutputCollection> CandCombinerBase<OutputCollection, CandPtr>::combine( const std::vector<edm::Handle<reco::CandidateView> > &src, const vstring &names) const { size_t srcSize = src.size(); if (checkCharge_ && dauCharge_.size() != srcSize) throw edm::Exception(edm::errors::Configuration) << "CandCombiner: trying to combine " << srcSize << " collections" << " but configured to check against " << dauCharge_.size() << " charges."; std::unique_ptr<OutputCollection> comps(new OutputCollection); size_t namesSize = names.size(); if (srcSize == 2) { std::string name1 = "", name2 = ""; if (namesSize > 0) { if (namesSize != 2) throw edm::Exception(edm::errors::Configuration) << "CandCombiner: should specify exactly two " << " names in configuration (" << namesSize << " specified).\n"; name1 = names[0]; name2 = names[1]; } edm::Handle<reco::CandidateView> src1 = src[0], src2 = src[1]; if (src1.id() == src2.id()) { const reco::CandidateView &cands = *src1; const size_t n = cands.size(); for (size_t i1 = 0; i1 < n; ++i1) { const reco::Candidate &c1 = cands[i1]; CandPtr cr1(src1, i1); for (size_t i2 = i1 + 1; i2 < n; ++i2) { const reco::Candidate &c2 = cands[i2]; if (preselect(c1, c2)) { CandPtr cr2(src2, i2); typename OutputCollection::value_type c; combine(c, cr1, cr2, name1, name2); if (select(c)) comps->push_back(c); } } } } else { const reco::CandidateView &cands1 = *src1, &cands2 = *src2; const size_t n1 = cands1.size(), n2 = cands2.size(); for (size_t i1 = 0; i1 < n1; ++i1) { const reco::Candidate &c1 = cands1[i1]; CandPtr cr1(src1, i1); for (size_t i2 = 0; i2 < n2; ++i2) { const reco::Candidate &c2 = cands2[i2]; if (preselect(c1, c2)) { CandPtr cr2(src2, i2); typename OutputCollection::value_type c; combine(c, cr1, cr2, name1, name2); if (select(c)) comps->push_back(c); } } } } } else { CandStack stack; ChargeStack qStack; combine(0, stack, qStack, src.begin(), src.end(), comps.get(), names); } return comps; } template <typename OutputCollection, typename CandPtr> std::unique_ptr<OutputCollection> CandCombinerBase<OutputCollection, CandPtr>::combine( const edm::Handle<reco::CandidateView> &src, const vstring &names) const { if (checkCharge_ && dauCharge_.size() != 2) throw edm::Exception(edm::errors::Configuration) << "CandCombiner: trying to combine 2 collections" << " but configured to check against " << dauCharge_.size() << " charges."; std::unique_ptr<OutputCollection> comps(new OutputCollection); size_t namesSize = names.size(); std::string name1, name2; if (namesSize > 0) { if (namesSize != 2) throw edm::Exception(edm::errors::Configuration) << "CandCombiner: should specify exactly two " << " names in configuration (" << namesSize << " specified).\n"; name1 = names[0]; name2 = names[1]; } const reco::CandidateView &cands = *src; const size_t n = cands.size(); for (size_t i1 = 0; i1 < n; ++i1) { const reco::Candidate &c1 = cands[i1]; CandPtr cr1(src, i1); for (size_t i2 = i1 + 1; i2 < n; ++i2) { const reco::Candidate &c2 = cands[i2]; if (preselect(c1, c2)) { CandPtr cr2(src, i2); typename OutputCollection::value_type c; combine(c, cr1, cr2, name1, name2); if (select(c)) comps->push_back(c); } } } return comps; } template <typename OutputCollection, typename CandPtr> std::unique_ptr<OutputCollection> CandCombinerBase<OutputCollection, CandPtr>::combine( const edm::Handle<reco::CandidateView> &src1, const edm::Handle<reco::CandidateView> &src2, const vstring &names) const { std::vector<edm::Handle<reco::CandidateView> > src; src.push_back(src1); src.push_back(src2); return combine(src, names); } template <typename OutputCollection, typename CandPtr> std::unique_ptr<OutputCollection> CandCombinerBase<OutputCollection, CandPtr>::combine( const edm::Handle<reco::CandidateView> &src1, const edm::Handle<reco::CandidateView> &src2, const edm::Handle<reco::CandidateView> &src3, const vstring &names) const { std::vector<edm::Handle<reco::CandidateView> > src; src.push_back(src1); src.push_back(src2); src.push_back(src3); return combine(src, names); } template <typename OutputCollection, typename CandPtr> std::unique_ptr<OutputCollection> CandCombinerBase<OutputCollection, CandPtr>::combine( const edm::Handle<reco::CandidateView> &src1, const edm::Handle<reco::CandidateView> &src2, const edm::Handle<reco::CandidateView> &src3, const edm::Handle<reco::CandidateView> &src4, const vstring &names) const { std::vector<edm::Handle<reco::CandidateView> > src; src.push_back(src1); src.push_back(src2); src.push_back(src3); src.push_back(src4); return combine(src, names); } template <typename OutputCollection, typename CandPtr> void CandCombinerBase<OutputCollection, CandPtr>::combine( size_t collectionIndex, CandStack &stack, ChargeStack &qStack, std::vector<edm::Handle<reco::CandidateView> >::const_iterator collBegin, std::vector<edm::Handle<reco::CandidateView> >::const_iterator collEnd, OutputCollection *comps, const vstring &names) const { if (collBegin == collEnd) { static const int undetermined = 0, sameDecay = 1, conjDecay = -1, wrongDecay = 2; int decayType = undetermined; if (checkCharge_) { assert(qStack.size() == stack.size()); for (size_t i = 0; i < qStack.size(); ++i) { int q = qStack[i], dq = dauCharge_[i]; if (decayType == undetermined) { if (q != 0 && dq != 0) { if (q == dq) decayType = sameDecay; else if (q == -dq) decayType = conjDecay; else decayType = wrongDecay; } } else if ((decayType == sameDecay && q != dq) || (decayType == conjDecay && q != -dq)) { decayType = wrongDecay; } if (decayType == wrongDecay) break; } } if (decayType != wrongDecay) { typename OutputCollection::value_type c; size_t nameIndex = 0; for (typename CandStack::const_iterator i = stack.begin(); i != stack.end(); ++i, ++nameIndex) { if (!names.empty()) addDaughter(c, i->first.first, names[nameIndex]); else addDaughter(c, i->first.first); } setup(c); if (select(c)) comps->push_back(c); } } else { const edm::Handle<reco::CandidateView> &srcRef = *collBegin; const reco::CandidateView &src = *srcRef; size_t candBegin = 0, candEnd = src.size(); for (typename CandStack::const_iterator i = stack.begin(); i != stack.end(); ++i) if (srcRef.id() == i->second->id()) candBegin = i->first.second + 1; for (size_t candIndex = candBegin; candIndex != candEnd; ++candIndex) { CandPtr candRef(srcRef, candIndex); bool noOverlap = true; const reco::Candidate &cand = *candRef; for (typename CandStack::const_iterator i = stack.begin(); i != stack.end(); ++i) if (checkOverlap_ && overlap_(cand, *(i->first.first))) { noOverlap = false; break; } if (noOverlap) { stack.push_back(std::make_pair(std::make_pair(candRef, candIndex), collBegin)); if (checkCharge_) qStack.push_back(cand.charge()); combine(collectionIndex + 1, stack, qStack, collBegin + 1, collEnd, comps, names); stack.pop_back(); qStack.pop_back(); } } } } #endif