File indexing completed on 2024-04-06 12:01:04
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 }