CMS 3D CMS Logo

CandCombinerBase.h
Go to the documentation of this file.
1 #ifndef CommonTools_CandUtils_CandCombinerBase_h
2 #define CommonTools_CandUtils_CandCombinerBase_h
3 
10 #include <vector>
11 #include <string>
12 
13 template<typename OutputCollection, typename CandPtr>
15 public:
16  typedef std::vector<std::string> vstring;
18  explicit CandCombinerBase(const std::string = "");
20  CandCombinerBase(int, int, const std::string = "");
22  CandCombinerBase(int, int, int, const std::string = "");
24  CandCombinerBase(int, int, int, int, const std::string = "");
26  CandCombinerBase(bool checkCharge, bool checkOverlap, const std::vector <int> &, const std::string = "");
28  virtual ~CandCombinerBase();
30  std::unique_ptr<OutputCollection>
31  combine(const std::vector<edm::Handle<reco::CandidateView> > &, const vstring& = vstring()) const;
33  std::unique_ptr<OutputCollection>
34  combine(const edm::Handle<reco::CandidateView> &, const vstring& = vstring()) const;
36  std::unique_ptr<OutputCollection>
38  const edm::Handle<reco::CandidateView> &, const vstring& = vstring()) const;
40  std::unique_ptr<OutputCollection>
43  const edm::Handle<reco::CandidateView> &, const vstring& = vstring()) const;
45  std::unique_ptr<OutputCollection>
49  const edm::Handle<reco::CandidateView> &, const vstring& = vstring()) const;
50 
51 private:
53  bool preselect(const reco::Candidate &, const reco::Candidate &) const;
55  void combine(typename OutputCollection::value_type &,
56  const CandPtr &,
57  const CandPtr &, const std::string = "", const std::string = "") const;
59  typedef std::vector<std::pair<std::pair<CandPtr, size_t>,
60  std::vector<edm::Handle<reco::CandidateView> >::const_iterator> > CandStack;
61  typedef std::vector<int> ChargeStack;
63  void combine(size_t collectionIndex, CandStack &, ChargeStack &,
64  std::vector<edm::Handle<reco::CandidateView> >::const_iterator begin,
65  std::vector<edm::Handle<reco::CandidateView> >::const_iterator end,
66  OutputCollection* comps,
67  const vstring& name = vstring()) const;
69  virtual bool select(const reco::Candidate &) const = 0;
71  virtual bool selectPair(const reco::Candidate & c1, const reco::Candidate & c2) const = 0;
73  virtual void setup(typename OutputCollection::value_type &) const = 0;
75  virtual void addDaughter(typename OutputCollection::value_type & cmp, const CandPtr & c, const std::string = "") const = 0;
81  std::vector<int> dauCharge_;
86 };
87 
88 template<typename OutputCollection, typename CandPtr>
91 }
92 
93 template<typename OutputCollection, typename CandPtr>
96  dauCharge_[0] = q1;
97  dauCharge_[1] = q2;
98 }
99 
100 template<typename OutputCollection, typename CandPtr>
103  dauCharge_[0] = q1;
104  dauCharge_[1] = q2;
105  dauCharge_[2] = q3;
106 }
107 
108 template<typename OutputCollection, typename CandPtr>
111  dauCharge_[0] = q1;
112  dauCharge_[1] = q2;
113  dauCharge_[2] = q3;
114  dauCharge_[3] = q4;
115 }
116 
117 template<typename OutputCollection, typename CandPtr>
119  checkCharge_(checkCharge), checkOverlap_(checkOverlap), dauCharge_(dauCharge), overlap_(), name_(name) {
120 }
121 
122 template<typename OutputCollection, typename CandPtr>
124 }
125 
126 template<typename OutputCollection, typename CandPtr>
128  if (checkCharge_) {
129  int dq1 = dauCharge_[0], dq2 = dauCharge_[1], q1 = c1.charge(), q2 = c2.charge();
130  bool matchCharge = (q1 == dq1 && q2 == dq2) || (q1 == -dq1 && q2 == -dq2);
131  if (!matchCharge) return false;
132  }
133  if (checkOverlap_ && overlap_(c1, c2)) return false;
134  return selectPair(c1, c2);
135 }
136 
137 template<typename OutputCollection, typename CandPtr>
139  const CandPtr & c1, const CandPtr & c2,
140  const std::string name1, const std::string name2) const {
141  addDaughter(cmp, c1, name1);
142  addDaughter(cmp, c2, name2);
143  setup(cmp);
144 }
145 
146 template<typename OutputCollection, typename CandPtr>
147 std::unique_ptr<OutputCollection>
149  const vstring& names) const {
150  size_t srcSize = src.size();
151  if (checkCharge_ && dauCharge_.size() != srcSize)
153  << "CandCombiner: trying to combine " << srcSize << " collections"
154  << " but configured to check against " << dauCharge_.size() << " charges.";
155  std::unique_ptr<OutputCollection> comps(new OutputCollection);
156  size_t namesSize = names.size();
157  if(srcSize == 2) {
158  std::string name1="", name2="";
159  if(namesSize > 0) {
160  if(namesSize != 2)
162  << "CandCombiner: should specify exactly two "
163  << " names in configuration (" << namesSize << " specified).\n";
164  name1 = names[0];
165  name2 = names[1];
166  }
167  edm::Handle<reco::CandidateView> src1 = src[0], src2 = src[1];
168  if(src1.id() == src2.id()) {
169  const reco::CandidateView & cands = * src1;
170  const size_t n = cands.size();
171  for(size_t i1 = 0; i1 < n; ++i1) {
172  const reco::Candidate & c1 = cands[i1];
173  CandPtr cr1(src1, i1);
174  for(size_t i2 = i1 + 1; i2 < n; ++i2) {
175  const reco::Candidate & c2 = cands[i2];
176  if(preselect(c1, c2)) {
177  CandPtr cr2(src2, i2);
179  combine(c, cr1, cr2, name1, name2);
180  if(select(c))
181  comps->push_back(c);
182  }
183  }
184  }
185  } else {
186  const reco::CandidateView & cands1 = * src1, & cands2 = * src2;
187  const size_t n1 = cands1.size(), n2 = cands2.size();
188  for(size_t i1 = 0; i1 < n1; ++i1) {
189  const reco::Candidate & c1 = cands1[i1];
190  CandPtr cr1(src1, i1);
191  for(size_t i2 = 0; i2 < n2; ++i2) {
192  const reco::Candidate & c2 = cands2[i2];
193  if(preselect(c1, c2)) {
194  CandPtr cr2(src2, i2);
196  combine(c, cr1, cr2, name1, name2);
197  if(select(c))
198  comps->push_back(c);
199  }
200  }
201  }
202  }
203  } else {
204  CandStack stack;
205  ChargeStack qStack;
206  combine(0, stack, qStack, src.begin(), src.end(), comps.get(), names);
207  }
208 
209  return comps;
210 }
211 
212 template<typename OutputCollection, typename CandPtr>
213 std::unique_ptr<OutputCollection>
215  const vstring& names) const {
216  if(checkCharge_ && dauCharge_.size() != 2)
218  << "CandCombiner: trying to combine 2 collections"
219  << " but configured to check against " << dauCharge_.size() << " charges.";
220 
221  std::unique_ptr<OutputCollection> comps(new OutputCollection);
222  size_t namesSize = names.size();
223  std::string name1, name2;
224  if(namesSize > 0) {
225  if(namesSize != 2)
227  << "CandCombiner: should specify exactly two "
228  << " names in configuration (" << namesSize << " specified).\n";
229  name1 = names[0];
230  name2 = names[1];
231  }
232  const reco::CandidateView & cands = * src;
233  const size_t n = cands.size();
234  for(size_t i1 = 0; i1 < n; ++i1) {
235  const reco::Candidate & c1 = cands[i1];
236  CandPtr cr1(src, i1);
237  for(size_t i2 = i1 + 1; i2 < n; ++i2) {
238  const reco::Candidate & c2 = cands[i2];
239  if(preselect(c1, c2)) {
240  CandPtr cr2(src, i2);
242  combine(c, cr1, cr2, name1, name2);
243  if(select(c))
244  comps->push_back(c);
245  }
246  }
247  }
248 
249  return comps;
250 }
251 
252 template<typename OutputCollection, typename CandPtr>
253 std::unique_ptr<OutputCollection>
256  const vstring& names) const {
257  std::vector<edm::Handle<reco::CandidateView> > src;
258  src.push_back(src1);
259  src.push_back(src2);
260  return combine(src, names);
261 }
262 
263 template<typename OutputCollection, typename CandPtr>
264 std::unique_ptr<OutputCollection>
266  const edm::Handle<reco::CandidateView> & src2,
268  const vstring& names) const {
269  std::vector<edm::Handle<reco::CandidateView> > src;
270  src.push_back(src1);
271  src.push_back(src2);
272  src.push_back(src3);
273  return combine(src, names);
274 }
275 
276 template<typename OutputCollection, typename CandPtr>
277 std::unique_ptr<OutputCollection>
279  const edm::Handle<reco::CandidateView> & src2,
280  const edm::Handle<reco::CandidateView> & src3,
282  const vstring& names) const {
283  std::vector<edm::Handle<reco::CandidateView> > src;
284  src.push_back(src1);
285  src.push_back(src2);
286  src.push_back(src3);
287  src.push_back(src4);
288  return combine(src, names);
289 }
290 
291 template<typename OutputCollection, typename CandPtr>
292 void CandCombinerBase<OutputCollection, CandPtr>::combine(size_t collectionIndex, CandStack & stack, ChargeStack & qStack,
293  std::vector<edm::Handle<reco::CandidateView> >::const_iterator collBegin,
294  std::vector<edm::Handle<reco::CandidateView> >::const_iterator collEnd,
295  OutputCollection* comps,
296  const vstring& names) const {
297  if(collBegin == collEnd) {
298  static const int undetermined = 0, sameDecay = 1, conjDecay = -1, wrongDecay = 2;
299  int decayType = undetermined;
300  if(checkCharge_) {
301  assert(qStack.size() == stack.size());
302  for(size_t i = 0; i < qStack.size(); ++i) {
303  int q = qStack[i], dq = dauCharge_[i];
304  if(decayType == undetermined) {
305  if(q != 0 && dq != 0) {
306  if(q == dq) decayType = sameDecay;
307  else if(q == -dq) decayType = conjDecay;
308  else decayType = wrongDecay;
309  }
310  } else if((decayType == sameDecay && q != dq) ||
311  (decayType == conjDecay && q != -dq)) {
312  decayType = wrongDecay;
313  }
314  if(decayType == wrongDecay) break;
315  }
316  }
317  if(decayType != wrongDecay) {
319  size_t nameIndex = 0;
320  for(typename CandStack::const_iterator i = stack.begin(); i != stack.end(); ++i, ++ nameIndex) {
321  if ( !names.empty() )
322  addDaughter(c, i->first.first, names[nameIndex]);
323  else
324  addDaughter(c, i->first.first);
325  }
326  setup(c);
327  if(select(c))
328  comps->push_back(c);
329  }
330  } else {
331  const edm::Handle<reco::CandidateView> & srcRef = * collBegin;
332  const reco::CandidateView & src = * srcRef;
333  size_t candBegin = 0, candEnd = src.size();
334  for(typename CandStack::const_iterator i = stack.begin(); i != stack.end(); ++i)
335  if(srcRef.id() == i->second->id())
336  candBegin = i->first.second + 1;
337  for(size_t candIndex = candBegin; candIndex != candEnd; ++ candIndex) {
338  CandPtr candRef(srcRef, candIndex);
339  bool noOverlap = true;
340  const reco::Candidate & cand = * candRef;
341  for(typename CandStack::const_iterator i = stack.begin(); i != stack.end(); ++i)
342  if(checkOverlap_ && overlap_(cand, *(i->first.first))) {
343  noOverlap = false;
344  break;
345  }
346  if(noOverlap) {
347  stack.push_back(std::make_pair(std::make_pair(candRef, candIndex), collBegin));
348  if(checkCharge_) qStack.push_back(cand.charge());
349  combine(collectionIndex + 1, stack, qStack, collBegin + 1, collEnd, comps, names);
350  stack.pop_back();
351  qStack.pop_back();
352  }
353  }
354  }
355 }
356 
357 #endif
ProductID id() const
Definition: HandleBase.cc:15
bool checkOverlap_
flag to specify the checking of overlaps
bool checkCharge_
flag to specify the checking of electric charge
bool preselect(const reco::Candidate &, const reco::Candidate &) const
verify that the two candidate don&#39;t overlap and check charge
virtual void setup(typename OutputCollection::value_type &) const =0
set kinematics to reconstructed composite
OverlapChecker overlap_
utility to check candidate daughters overlap
size_type size() const
CandCombinerBase(const std::string="")
default construct
const std::string names[nVars_]
double q2[4]
Definition: TauolaWrapper.h:88
static const unsigned int namesSize
virtual bool selectPair(const reco::Candidate &c1, const reco::Candidate &c2) const =0
select a candidate pair
stack
Definition: svgfig.py:559
virtual ~CandCombinerBase()
destructor
#define end
Definition: vmac.h:39
virtual void addDaughter(typename OutputCollection::value_type &cmp, const CandPtr &c, const std::string="") const =0
add candidate daughter
std::unique_ptr< OutputCollection > combine(const std::vector< edm::Handle< reco::CandidateView > > &, const vstring &=vstring()) const
return all selected candidate pairs
std::vector< std::pair< std::pair< CandPtr, size_t >, std::vector< edm::Handle< reco::CandidateView > >::const_iterator > > CandStack
temporary candidate stack
double q1[4]
Definition: TauolaWrapper.h:87
std::vector< int > dauCharge_
electric charges of the daughters
def checkOverlap(process)
virtual int charge() const =0
electric charge
std::vector< std::string > vstring
#define begin
Definition: vmac.h:32
virtual bool select(const reco::Candidate &) const =0
select a candidate
ProductIndex id() const
Definition: ProductID.h:38
std::string name_
composite name (if applies)
std::vector< int > ChargeStack