CMS 3D CMS Logo

NamedCandCombinerBase.cc

Go to the documentation of this file.
00001 #include "PhysicsTools/CandUtils/interface/NamedCandCombinerBase.h"
00002 #include <utility>
00003 using namespace std;
00004 using namespace reco;
00005 
00006 NamedCandCombinerBase::NamedCandCombinerBase(std::string name) :
00007   checkCharge_(false), dauCharge_(), overlap_(), name_(name) {
00008 }
00009 
00010 NamedCandCombinerBase::NamedCandCombinerBase(std::string name, int q1, int q2) :
00011   checkCharge_(true), dauCharge_(2), overlap_(), name_(name) {
00012   dauCharge_[0] = q1;
00013   dauCharge_[1] = q2;
00014 }
00015 
00016 NamedCandCombinerBase::NamedCandCombinerBase(std::string name, int q1, int q2, int q3) :
00017   checkCharge_(true), dauCharge_(3), overlap_(), name_(name) {
00018   dauCharge_[0] = q1;
00019   dauCharge_[1] = q2;
00020   dauCharge_[2] = q3;
00021 }
00022 
00023 NamedCandCombinerBase::NamedCandCombinerBase(std::string name, int q1, int q2, int q3, int q4) :
00024   checkCharge_(true), dauCharge_(4), overlap_(), name_(name) {
00025   dauCharge_[0] = q1;
00026   dauCharge_[1] = q2;
00027   dauCharge_[2] = q3;
00028   dauCharge_[3] = q4;
00029 }
00030 
00031 NamedCandCombinerBase::NamedCandCombinerBase(std::string name, bool checkCharge, const vector<int> & dauCharge) :
00032   checkCharge_(checkCharge), dauCharge_(dauCharge), overlap_() {
00033 }
00034 
00035 NamedCandCombinerBase::~NamedCandCombinerBase() {
00036 }
00037 
00038 bool NamedCandCombinerBase::preselect(const Candidate & c1, const Candidate & c2) const {
00039   if (checkCharge_) {
00040     int dq1 = dauCharge_[0], dq2 = dauCharge_[1], q1 = c1.charge(), q2 = c2.charge();
00041     bool matchCharge = (q1 == dq1 && q2 == dq2) || (q1 == -dq1 && q2 == -dq2); 
00042     if (!matchCharge) return false; 
00043   }
00044   if (overlap_(c1, c2)) return false;
00045   return selectPair(c1, c2);
00046 }
00047 
00048 void NamedCandCombinerBase::combine(NamedCompositeCandidate & cmp, const CandidatePtr & c1, const CandidatePtr & c2,
00049                                     std::string n1, std::string n2 ) const {
00050   addDaughter(cmp, c1, n1);
00051   addDaughter(cmp, c2, n2);
00052   setup(cmp);
00053 }
00054 
00055 auto_ptr<NamedCompositeCandidateCollection> 
00056 NamedCandCombinerBase::combine(const vector<CandidatePtrVector> & src,
00057                                string_coll const & names) const {
00058   size_t srcSize = src.size();
00059   if (checkCharge_ && dauCharge_.size() != srcSize)
00060     throw edm::Exception(edm::errors::Configuration) 
00061       << "NamedCandCombiner: trying to combine " << srcSize << " collections"
00062       << " but configured to check against " << dauCharge_.size() << " charges.";
00063 
00064   if ( names.size() < 2 )
00065     throw edm::Exception(edm::errors::Configuration)
00066       << "NamedCandCombiner: need to add 2 names, but size is " << names.size();
00067   
00068   auto_ptr<NamedCompositeCandidateCollection> comps(new NamedCompositeCandidateCollection);
00069   if(srcSize == 2) {
00070     CandidatePtrVector src1 = src[0], src2 = src[1];
00071     if(src1 == src2) {
00072       const int n = src1.size();
00073       for(int i1 = 0; i1 < n; ++i1) {
00074         const Candidate & c1 = *(src1[i1]);
00075         for(int i2 = i1 + 1; i2 < n; ++i2) {
00076           const Candidate & c2 = *(src1[i2]);
00077           if (preselect(c1, c2)) {
00078             NamedCompositeCandidate c; 
00079             combine(c, src1[i1], src1[i2], names[0], names[1]);
00080             if(select(c))
00081               comps->push_back(c);
00082           }
00083         }
00084       }
00085     } else {
00086       const int n1 = src1.size(), n2 = src2.size();
00087       for(int i1 = 0; i1 < n1; ++i1) {
00088         const Candidate & c1 = *(src1[i1]);
00089         for(int i2 = 0; i2 < n2; ++i2) {
00090           const Candidate & c2 = *(src2[i2]);
00091           if(preselect(c1, c2)) {
00092             NamedCompositeCandidate c;
00093             combine(c, src1[i1], src2[i2], names[0], names[1]);
00094             if(select(c))
00095               comps->push_back(c);
00096           }
00097         }
00098       }
00099     }
00100   } else {
00101     CandStack stack;
00102     ChargeStack qStack;
00103     combine(0, stack, qStack, names, src.begin(), src.end(), comps);
00104   }
00105 
00106   return comps;
00107 }
00108 
00109 auto_ptr<NamedCompositeCandidateCollection> 
00110 NamedCandCombinerBase::combine(const CandidatePtrVector & src, string_coll const & names) const {
00111   if(checkCharge_ && dauCharge_.size() != 2)
00112     throw edm::Exception(edm::errors::Configuration) 
00113       << "NamedCandCombiner: trying to combine 2 collections"
00114       << " but configured to check against " << dauCharge_.size() << " charges.";
00115 
00116   if ( names.size() < 2 )
00117     throw edm::Exception(edm::errors::Configuration)
00118       << "NamedCandCombiner: need to add 2 names, but size is " << names.size();
00119 
00120   auto_ptr<NamedCompositeCandidateCollection> comps(new NamedCompositeCandidateCollection);
00121   const int n = src.size();
00122   for(int i1 = 0; i1 < n; ++i1) {
00123     const Candidate & c1 = *(src[i1]);
00124     for(int i2 = i1 + 1; i2 < n; ++i2) {
00125       const Candidate & c2 = *(src[i2]);
00126       if(preselect(c1, c2)) {
00127         NamedCompositeCandidate c;
00128         combine(c, src[i1], src[i2], names[0], names[1]);
00129         if(select(c))
00130           comps->push_back(c);
00131       }
00132     } 
00133   }
00134 
00135   return comps;
00136 }
00137 
00138 auto_ptr<NamedCompositeCandidateCollection> 
00139 NamedCandCombinerBase::combine(const CandidatePtrVector & src1, const CandidatePtrVector & src2, string_coll const & names) const {
00140   vector<CandidatePtrVector> src;
00141   src.push_back(src1);
00142   src.push_back(src2);
00143   return combine(src, names);
00144 }
00145 
00146 auto_ptr<NamedCompositeCandidateCollection> 
00147 NamedCandCombinerBase::combine(const CandidatePtrVector & src1, const CandidatePtrVector & src2, const CandidatePtrVector & src3, 
00148                                string_coll const & names) const {
00149   vector<CandidatePtrVector> src;
00150   src.push_back(src1);
00151   src.push_back(src2);
00152   src.push_back(src3);
00153   return combine(src, names);
00154 }
00155 
00156 auto_ptr<NamedCompositeCandidateCollection> 
00157 NamedCandCombinerBase::combine(const CandidatePtrVector & src1, const CandidatePtrVector & src2, 
00158                                const CandidatePtrVector & src3, const CandidatePtrVector & src4, 
00159                                string_coll const & names) const {
00160   vector<CandidatePtrVector> src;
00161   src.push_back(src1);
00162   src.push_back(src2);
00163   src.push_back(src3);
00164   src.push_back(src4);
00165   return combine(src, names);
00166 }
00167 
00168 void NamedCandCombinerBase::combine(size_t collectionIndex, CandStack & stack, ChargeStack & qStack, 
00169                                     string_coll const & names,
00170                                     vector<CandidatePtrVector>::const_iterator collBegin,
00171                                     vector<CandidatePtrVector>::const_iterator collEnd,
00172                                     auto_ptr<NamedCompositeCandidateCollection> & comps) const {
00173   if(collBegin == collEnd) {
00174     static const int undetermined = 0, sameDecay = 1, conjDecay = -1, wrongDecay = 2;
00175     int decayType = undetermined;
00176     if(checkCharge_) {
00177       assert(qStack.size() == stack.size());
00178       for(size_t i = 0; i < qStack.size(); ++i) {
00179         int q = qStack[i], dq = dauCharge_[i];
00180         if(decayType == undetermined) {
00181           if(q != 0 && dq != 0) {
00182             if(q == dq) decayType = sameDecay;
00183             else if(q == -dq) decayType = conjDecay;
00184             else decayType = wrongDecay;
00185           }
00186         } else if((decayType == sameDecay && q != dq) ||
00187                   (decayType == conjDecay && q != -dq)) {
00188           decayType = wrongDecay;
00189         }
00190         if(decayType == wrongDecay) break;
00191       }
00192     }
00193     if(decayType != wrongDecay) { 
00194       NamedCompositeCandidate c;
00195       int ii = 0;
00196       for(CandStack::const_iterator i = stack.begin(); i != stack.end(); ++i, ++ii) {
00197         addDaughter(c, i->first.first, names[ii]);
00198       }
00199       setup(c);
00200       if(select(c))
00201         comps->push_back(c);
00202     }
00203   } else {
00204     const CandidatePtrVector & src = * collBegin;
00205     size_t candBegin = 0, candEnd = src.size();
00206     for(CandStack::const_iterator i = stack.begin(); i != stack.end(); ++i) 
00207       if(src == * i->second) 
00208         candBegin = i->first.second + 1;
00209     for(size_t candIndex = candBegin; candIndex != candEnd; ++ candIndex) {
00210       const CandidatePtr & candPtr(src[candIndex]);
00211 
00212       bool noOverlap = true;
00213       const Candidate & cand = *candPtr;
00214       for(CandStack::const_iterator i = stack.begin(); i != stack.end(); ++i) 
00215         if(overlap_(cand, *(i->first.first))) { 
00216           noOverlap = false; 
00217           break; 
00218         }
00219       if(noOverlap) {
00220         stack.push_back(make_pair(make_pair(candPtr, candIndex), collBegin));
00221         if(checkCharge_) qStack.push_back(cand.charge()); 
00222         combine(collectionIndex + 1, stack, qStack, names, collBegin + 1, collEnd, comps);
00223         stack.pop_back();
00224         qStack.pop_back();
00225       }
00226     }
00227   }
00228 }

Generated on Tue Jun 9 17:41:04 2009 for CMSSW by  doxygen 1.5.4