Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include "CommonTools/CandUtils/interface/NamedCandCombinerBase.h"
0002 #include <utility>
0003 using namespace std;
0004 using namespace reco;
0005 
0006 NamedCandCombinerBase::NamedCandCombinerBase(std::string name)
0007     : checkCharge_(false), checkOverlap_(true), dauCharge_(), overlap_(), name_(name) {}
0008 
0009 NamedCandCombinerBase::NamedCandCombinerBase(std::string name, int q1, int q2)
0010     : checkCharge_(true), checkOverlap_(true), dauCharge_(2), overlap_(), name_(name) {
0011   dauCharge_[0] = q1;
0012   dauCharge_[1] = q2;
0013 }
0014 
0015 NamedCandCombinerBase::NamedCandCombinerBase(std::string name, int q1, int q2, int q3)
0016     : checkCharge_(true), checkOverlap_(true), dauCharge_(3), overlap_(), name_(name) {
0017   dauCharge_[0] = q1;
0018   dauCharge_[1] = q2;
0019   dauCharge_[2] = q3;
0020 }
0021 
0022 NamedCandCombinerBase::NamedCandCombinerBase(std::string name, int q1, int q2, int q3, int q4)
0023     : checkCharge_(true), checkOverlap_(true), dauCharge_(4), overlap_(), name_(name) {
0024   dauCharge_[0] = q1;
0025   dauCharge_[1] = q2;
0026   dauCharge_[2] = q3;
0027   dauCharge_[3] = q4;
0028 }
0029 
0030 NamedCandCombinerBase::NamedCandCombinerBase(std::string name,
0031                                              bool checkCharge,
0032                                              bool checkOverlap,
0033                                              const vector<int>& dauCharge)
0034     : checkCharge_(checkCharge), checkOverlap_(checkOverlap), dauCharge_(dauCharge), overlap_() {}
0035 
0036 NamedCandCombinerBase::~NamedCandCombinerBase() {}
0037 
0038 bool NamedCandCombinerBase::preselect(const Candidate& c1, const Candidate& c2) const {
0039   if (checkCharge_) {
0040     int dq1 = dauCharge_[0], dq2 = dauCharge_[1], q1 = c1.charge(), q2 = c2.charge();
0041     bool matchCharge = (q1 == dq1 && q2 == dq2) || (q1 == -dq1 && q2 == -dq2);
0042     if (!matchCharge)
0043       return false;
0044   }
0045   if (checkOverlap_ && overlap_(c1, c2))
0046     return false;
0047   return selectPair(c1, c2);
0048 }
0049 
0050 void NamedCandCombinerBase::combine(NamedCompositeCandidate& cmp,
0051                                     const CandidatePtr& c1,
0052                                     const CandidatePtr& c2,
0053                                     std::string n1,
0054                                     std::string n2) const {
0055   addDaughter(cmp, c1, n1);
0056   addDaughter(cmp, c2, n2);
0057   setup(cmp);
0058 }
0059 
0060 unique_ptr<NamedCompositeCandidateCollection> NamedCandCombinerBase::combine(const vector<CandidatePtrVector>& src,
0061                                                                              string_coll const& names) const {
0062   size_t srcSize = src.size();
0063   if (checkCharge_ && dauCharge_.size() != srcSize)
0064     throw edm::Exception(edm::errors::Configuration)
0065         << "NamedCandCombiner: trying to combine " << srcSize << " collections"
0066         << " but configured to check against " << dauCharge_.size() << " charges.";
0067 
0068   if (names.size() < 2)
0069     throw edm::Exception(edm::errors::Configuration)
0070         << "NamedCandCombiner: need to add 2 names, but size is " << names.size();
0071 
0072   unique_ptr<NamedCompositeCandidateCollection> comps(new NamedCompositeCandidateCollection);
0073   if (srcSize == 2) {
0074     CandidatePtrVector src1 = src[0], src2 = src[1];
0075     if (src1 == src2) {
0076       const int n = src1.size();
0077       for (int i1 = 0; i1 < n; ++i1) {
0078         const Candidate& c1 = *(src1[i1]);
0079         for (int i2 = i1 + 1; i2 < n; ++i2) {
0080           const Candidate& c2 = *(src1[i2]);
0081           if (preselect(c1, c2)) {
0082             NamedCompositeCandidate c;
0083             combine(c, src1[i1], src1[i2], names[0], names[1]);
0084             if (select(c))
0085               comps->push_back(c);
0086           }
0087         }
0088       }
0089     } else {
0090       const int n1 = src1.size(), n2 = src2.size();
0091       for (int i1 = 0; i1 < n1; ++i1) {
0092         const Candidate& c1 = *(src1[i1]);
0093         for (int i2 = 0; i2 < n2; ++i2) {
0094           const Candidate& c2 = *(src2[i2]);
0095           if (preselect(c1, c2)) {
0096             NamedCompositeCandidate c;
0097             combine(c, src1[i1], src2[i2], names[0], names[1]);
0098             if (select(c))
0099               comps->push_back(c);
0100           }
0101         }
0102       }
0103     }
0104   } else {
0105     CandStack stack;
0106     ChargeStack qStack;
0107     combine(0, stack, qStack, names, src.begin(), src.end(), comps);
0108   }
0109 
0110   return comps;
0111 }
0112 
0113 unique_ptr<NamedCompositeCandidateCollection> NamedCandCombinerBase::combine(const CandidatePtrVector& src,
0114                                                                              string_coll const& names) const {
0115   if (checkCharge_ && dauCharge_.size() != 2)
0116     throw edm::Exception(edm::errors::Configuration)
0117         << "NamedCandCombiner: trying to combine 2 collections"
0118         << " but configured to check against " << dauCharge_.size() << " charges.";
0119 
0120   if (names.size() < 2)
0121     throw edm::Exception(edm::errors::Configuration)
0122         << "NamedCandCombiner: need to add 2 names, but size is " << names.size();
0123 
0124   unique_ptr<NamedCompositeCandidateCollection> comps(new NamedCompositeCandidateCollection);
0125   const int n = src.size();
0126   for (int i1 = 0; i1 < n; ++i1) {
0127     const Candidate& c1 = *(src[i1]);
0128     for (int i2 = i1 + 1; i2 < n; ++i2) {
0129       const Candidate& c2 = *(src[i2]);
0130       if (preselect(c1, c2)) {
0131         NamedCompositeCandidate c;
0132         combine(c, src[i1], src[i2], names[0], names[1]);
0133         if (select(c))
0134           comps->push_back(c);
0135       }
0136     }
0137   }
0138 
0139   return comps;
0140 }
0141 
0142 unique_ptr<NamedCompositeCandidateCollection> NamedCandCombinerBase::combine(const CandidatePtrVector& src1,
0143                                                                              const CandidatePtrVector& src2,
0144                                                                              string_coll const& names) const {
0145   vector<CandidatePtrVector> src;
0146   src.push_back(src1);
0147   src.push_back(src2);
0148   return combine(src, names);
0149 }
0150 
0151 unique_ptr<NamedCompositeCandidateCollection> NamedCandCombinerBase::combine(const CandidatePtrVector& src1,
0152                                                                              const CandidatePtrVector& src2,
0153                                                                              const CandidatePtrVector& src3,
0154                                                                              string_coll const& names) const {
0155   vector<CandidatePtrVector> src;
0156   src.push_back(src1);
0157   src.push_back(src2);
0158   src.push_back(src3);
0159   return combine(src, names);
0160 }
0161 
0162 unique_ptr<NamedCompositeCandidateCollection> NamedCandCombinerBase::combine(const CandidatePtrVector& src1,
0163                                                                              const CandidatePtrVector& src2,
0164                                                                              const CandidatePtrVector& src3,
0165                                                                              const CandidatePtrVector& src4,
0166                                                                              string_coll const& names) const {
0167   vector<CandidatePtrVector> src;
0168   src.push_back(src1);
0169   src.push_back(src2);
0170   src.push_back(src3);
0171   src.push_back(src4);
0172   return combine(src, names);
0173 }
0174 
0175 void NamedCandCombinerBase::combine(size_t collectionIndex,
0176                                     CandStack& stack,
0177                                     ChargeStack& qStack,
0178                                     string_coll const& names,
0179                                     vector<CandidatePtrVector>::const_iterator collBegin,
0180                                     vector<CandidatePtrVector>::const_iterator collEnd,
0181                                     unique_ptr<NamedCompositeCandidateCollection>& comps) const {
0182   if (collBegin == collEnd) {
0183     static const int undetermined = 0, sameDecay = 1, conjDecay = -1, wrongDecay = 2;
0184     int decayType = undetermined;
0185     if (checkCharge_) {
0186       assert(qStack.size() == stack.size());
0187       for (size_t i = 0; i < qStack.size(); ++i) {
0188         int q = qStack[i], dq = dauCharge_[i];
0189         if (decayType == undetermined) {
0190           if (q != 0 && dq != 0) {
0191             if (q == dq)
0192               decayType = sameDecay;
0193             else if (q == -dq)
0194               decayType = conjDecay;
0195             else
0196               decayType = wrongDecay;
0197           }
0198         } else if ((decayType == sameDecay && q != dq) || (decayType == conjDecay && q != -dq)) {
0199           decayType = wrongDecay;
0200         }
0201         if (decayType == wrongDecay)
0202           break;
0203       }
0204     }
0205     if (decayType != wrongDecay) {
0206       NamedCompositeCandidate c;
0207       int ii = 0;
0208       for (CandStack::const_iterator i = stack.begin(); i != stack.end(); ++i, ++ii) {
0209         addDaughter(c, i->first.first, names[ii]);
0210       }
0211       setup(c);
0212       if (select(c))
0213         comps->push_back(c);
0214     }
0215   } else {
0216     const CandidatePtrVector& src = *collBegin;
0217     size_t candBegin = 0, candEnd = src.size();
0218     for (CandStack::const_iterator i = stack.begin(); i != stack.end(); ++i)
0219       if (src == *i->second)
0220         candBegin = i->first.second + 1;
0221     for (size_t candIndex = candBegin; candIndex != candEnd; ++candIndex) {
0222       const CandidatePtr& candPtr(src[candIndex]);
0223 
0224       bool noOverlap = true;
0225       const Candidate& cand = *candPtr;
0226       for (CandStack::const_iterator i = stack.begin(); i != stack.end(); ++i)
0227         if (checkOverlap_ && overlap_(cand, *(i->first.first))) {
0228           noOverlap = false;
0229           break;
0230         }
0231       if (noOverlap) {
0232         stack.push_back(make_pair(make_pair(candPtr, candIndex), collBegin));
0233         if (checkCharge_)
0234           qStack.push_back(cand.charge());
0235         combine(collectionIndex + 1, stack, qStack, names, collBegin + 1, collEnd, comps);
0236         stack.pop_back();
0237         qStack.pop_back();
0238       }
0239     }
0240   }
0241 }