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> combine(const std::vector<edm::Handle<reco::CandidateView> > &,
31  const vstring & = vstring()) const;
33  std::unique_ptr<OutputCollection> combine(const edm::Handle<reco::CandidateView> &,
34  const vstring & = vstring()) const;
36  std::unique_ptr<OutputCollection> combine(const edm::Handle<reco::CandidateView> &,
38  const vstring & = vstring()) const;
40  std::unique_ptr<OutputCollection> combine(const edm::Handle<reco::CandidateView> &,
43  const vstring & = vstring()) const;
45  std::unique_ptr<OutputCollection> combine(const edm::Handle<reco::CandidateView> &,
49  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 &,
58  const std::string = "",
59  const std::string = "") const;
61  typedef std::vector<
62  std::pair<std::pair<CandPtr, size_t>, std::vector<edm::Handle<reco::CandidateView> >::const_iterator> >
64  typedef std::vector<int> ChargeStack;
66  void combine(size_t collectionIndex,
67  CandStack &,
68  ChargeStack &,
69  std::vector<edm::Handle<reco::CandidateView> >::const_iterator begin,
71  OutputCollection *comps,
72  const vstring &name = vstring()) const;
74  virtual bool select(const reco::Candidate &) const = 0;
76  virtual bool selectPair(const reco::Candidate &c1, const reco::Candidate &c2) const = 0;
78  virtual void setup(typename OutputCollection::value_type &) const = 0;
80  virtual void addDaughter(typename OutputCollection::value_type &cmp,
81  const CandPtr &c,
82  const std::string = "") const = 0;
88  std::vector<int> dauCharge_;
93 };
94 
95 template <typename OutputCollection, typename CandPtr>
97  : checkCharge_(false), checkOverlap_(true), dauCharge_(), overlap_(), name_(name) {}
98 
99 template <typename OutputCollection, typename CandPtr>
101  : checkCharge_(true), checkOverlap_(true), dauCharge_(2), overlap_(), name_(name) {
102  dauCharge_[0] = q1;
103  dauCharge_[1] = q2;
104 }
105 
106 template <typename OutputCollection, typename CandPtr>
108  : checkCharge_(true), checkOverlap_(true), dauCharge_(3), overlap_(), name_(name) {
109  dauCharge_[0] = q1;
110  dauCharge_[1] = q2;
111  dauCharge_[2] = q3;
112 }
113 
114 template <typename OutputCollection, typename CandPtr>
116  : checkCharge_(true), checkOverlap_(true), dauCharge_(4), overlap_(), name_(name) {
117  dauCharge_[0] = q1;
118  dauCharge_[1] = q2;
119  dauCharge_[2] = q3;
120  dauCharge_[3] = q4;
121 }
122 
123 template <typename OutputCollection, typename CandPtr>
125  bool checkOverlap,
126  const std::vector<int> &dauCharge,
127  const std::string name)
128  : checkCharge_(checkCharge), checkOverlap_(checkOverlap), dauCharge_(dauCharge), overlap_(), name_(name) {}
129 
130 template <typename OutputCollection, typename CandPtr>
132 
133 template <typename OutputCollection, typename CandPtr>
135  const reco::Candidate &c2) const {
136  if (checkCharge_) {
137  int dq1 = dauCharge_[0], dq2 = dauCharge_[1], q1 = c1.charge(), q2 = c2.charge();
138  bool matchCharge = (q1 == dq1 && q2 == dq2) || (q1 == -dq1 && q2 == -dq2);
139  if (!matchCharge)
140  return false;
141  }
142  if (checkOverlap_ && overlap_(c1, c2))
143  return false;
144  return selectPair(c1, c2);
145 }
146 
147 template <typename OutputCollection, typename CandPtr>
149  const CandPtr &c1,
150  const CandPtr &c2,
151  const std::string name1,
152  const std::string name2) const {
153  addDaughter(cmp, c1, name1);
154  addDaughter(cmp, c2, name2);
155  setup(cmp);
156 }
157 
158 template <typename OutputCollection, typename CandPtr>
161  size_t srcSize = src.size();
162  if (checkCharge_ && dauCharge_.size() != srcSize)
164  << "CandCombiner: trying to combine " << srcSize << " collections"
165  << " but configured to check against " << dauCharge_.size() << " charges.";
166  std::unique_ptr<OutputCollection> comps(new OutputCollection);
167  size_t namesSize = names.size();
168  if (srcSize == 2) {
169  std::string name1 = "", name2 = "";
170  if (namesSize > 0) {
171  if (namesSize != 2)
173  << "CandCombiner: should specify exactly two "
174  << " names in configuration (" << namesSize << " specified).\n";
175  name1 = names[0];
176  name2 = names[1];
177  }
178  edm::Handle<reco::CandidateView> src1 = src[0], src2 = src[1];
179  if (src1.id() == src2.id()) {
180  const reco::CandidateView &cands = *src1;
181  const size_t n = cands.size();
182  for (size_t i1 = 0; i1 < n; ++i1) {
183  const reco::Candidate &c1 = cands[i1];
184  CandPtr cr1(src1, i1);
185  for (size_t i2 = i1 + 1; i2 < n; ++i2) {
186  const reco::Candidate &c2 = cands[i2];
187  if (preselect(c1, c2)) {
188  CandPtr cr2(src2, i2);
190  combine(c, cr1, cr2, name1, name2);
191  if (select(c))
192  comps->push_back(c);
193  }
194  }
195  }
196  } else {
197  const reco::CandidateView &cands1 = *src1, &cands2 = *src2;
198  const size_t n1 = cands1.size(), n2 = cands2.size();
199  for (size_t i1 = 0; i1 < n1; ++i1) {
200  const reco::Candidate &c1 = cands1[i1];
201  CandPtr cr1(src1, i1);
202  for (size_t i2 = 0; i2 < n2; ++i2) {
203  const reco::Candidate &c2 = cands2[i2];
204  if (preselect(c1, c2)) {
205  CandPtr cr2(src2, i2);
207  combine(c, cr1, cr2, name1, name2);
208  if (select(c))
209  comps->push_back(c);
210  }
211  }
212  }
213  }
214  } else {
216  ChargeStack qStack;
217  combine(0, stack, qStack, src.begin(), src.end(), comps.get(), names);
218  }
219 
220  return comps;
221 }
222 
223 template <typename OutputCollection, typename CandPtr>
225  const edm::Handle<reco::CandidateView> &src, const vstring &names) const {
226  if (checkCharge_ && dauCharge_.size() != 2)
228  << "CandCombiner: trying to combine 2 collections"
229  << " but configured to check against " << dauCharge_.size() << " charges.";
230 
231  std::unique_ptr<OutputCollection> comps(new OutputCollection);
232  size_t namesSize = names.size();
233  std::string name1, name2;
234  if (namesSize > 0) {
235  if (namesSize != 2)
236  throw edm::Exception(edm::errors::Configuration) << "CandCombiner: should specify exactly two "
237  << " names in configuration (" << namesSize << " specified).\n";
238  name1 = names[0];
239  name2 = names[1];
240  }
241  const reco::CandidateView &cands = *src;
242  const size_t n = cands.size();
243  for (size_t i1 = 0; i1 < n; ++i1) {
244  const reco::Candidate &c1 = cands[i1];
245  CandPtr cr1(src, i1);
246  for (size_t i2 = i1 + 1; i2 < n; ++i2) {
247  const reco::Candidate &c2 = cands[i2];
248  if (preselect(c1, c2)) {
249  CandPtr cr2(src, i2);
251  combine(c, cr1, cr2, name1, name2);
252  if (select(c))
253  comps->push_back(c);
254  }
255  }
256  }
257 
258  return comps;
259 }
260 
261 template <typename OutputCollection, typename CandPtr>
265  const vstring &names) const {
266  std::vector<edm::Handle<reco::CandidateView> > src;
267  src.push_back(src1);
268  src.push_back(src2);
269  return combine(src, names);
270 }
271 
272 template <typename OutputCollection, typename CandPtr>
277  const vstring &names) const {
278  std::vector<edm::Handle<reco::CandidateView> > src;
279  src.push_back(src1);
280  src.push_back(src2);
281  src.push_back(src3);
282  return combine(src, names);
283 }
284 
285 template <typename OutputCollection, typename CandPtr>
291  const vstring &names) const {
292  std::vector<edm::Handle<reco::CandidateView> > src;
293  src.push_back(src1);
294  src.push_back(src2);
295  src.push_back(src3);
296  src.push_back(src4);
297  return combine(src, names);
298 }
299 
300 template <typename OutputCollection, typename CandPtr>
302  size_t collectionIndex,
303  CandStack &stack,
304  ChargeStack &qStack,
305  std::vector<edm::Handle<reco::CandidateView> >::const_iterator collBegin,
306  std::vector<edm::Handle<reco::CandidateView> >::const_iterator collEnd,
307  OutputCollection *comps,
308  const vstring &names) const {
309  if (collBegin == collEnd) {
310  static const int undetermined = 0, sameDecay = 1, conjDecay = -1, wrongDecay = 2;
311  int decayType = undetermined;
312  if (checkCharge_) {
313  assert(qStack.size() == stack.size());
314  for (size_t i = 0; i < qStack.size(); ++i) {
315  int q = qStack[i], dq = dauCharge_[i];
316  if (decayType == undetermined) {
317  if (q != 0 && dq != 0) {
318  if (q == dq)
319  decayType = sameDecay;
320  else if (q == -dq)
321  decayType = conjDecay;
322  else
323  decayType = wrongDecay;
324  }
325  } else if ((decayType == sameDecay && q != dq) || (decayType == conjDecay && q != -dq)) {
326  decayType = wrongDecay;
327  }
328  if (decayType == wrongDecay)
329  break;
330  }
331  }
332  if (decayType != wrongDecay) {
334  size_t nameIndex = 0;
335  for (typename CandStack::const_iterator i = stack.begin(); i != stack.end(); ++i, ++nameIndex) {
336  if (!names.empty())
337  addDaughter(c, i->first.first, names[nameIndex]);
338  else
339  addDaughter(c, i->first.first);
340  }
341  setup(c);
342  if (select(c))
343  comps->push_back(c);
344  }
345  } else {
346  const edm::Handle<reco::CandidateView> &srcRef = *collBegin;
347  const reco::CandidateView &src = *srcRef;
348  size_t candBegin = 0, candEnd = src.size();
349  for (typename CandStack::const_iterator i = stack.begin(); i != stack.end(); ++i)
350  if (srcRef.id() == i->second->id())
351  candBegin = i->first.second + 1;
352  for (size_t candIndex = candBegin; candIndex != candEnd; ++candIndex) {
353  CandPtr candRef(srcRef, candIndex);
354  bool noOverlap = true;
355  const reco::Candidate &cand = *candRef;
356  for (typename CandStack::const_iterator i = stack.begin(); i != stack.end(); ++i)
357  if (checkOverlap_ && overlap_(cand, *(i->first.first))) {
358  noOverlap = false;
359  break;
360  }
361  if (noOverlap) {
362  stack.push_back(std::make_pair(std::make_pair(candRef, candIndex), collBegin));
363  if (checkCharge_)
364  qStack.push_back(cand.charge());
365  combine(collectionIndex + 1, stack, qStack, collBegin + 1, collEnd, comps, names);
366  stack.pop_back();
367  qStack.pop_back();
368  }
369  }
370  }
371 }
372 
373 #endif
ProductID id() const
Definition: HandleBase.cc:29
virtual bool select(const reco::Candidate &) const =0
select a candidate
virtual bool selectPair(const reco::Candidate &c1, const reco::Candidate &c2) const =0
select a candidate pair
for(int i=first, nt=offsets[nh];i< nt;i+=gridDim.x *blockDim.x)
bool checkOverlap_
flag to specify the checking of overlaps
bool checkCharge_
flag to specify the checking of electric charge
OverlapChecker overlap_
utility to check candidate daughters overlap
CandCombinerBase(const std::string="")
default construct
assert(be >=bs)
const std::string names[nVars_]
size_type size() const
static const unsigned int namesSize
static type combine(const A &_1, const B &_2)
Definition: Factorize.h:176
stack
Definition: svgfig.py:559
virtual ~CandCombinerBase()
destructor
virtual void addDaughter(typename OutputCollection::value_type &cmp, const CandPtr &c, const std::string="") const =0
add candidate daughter
virtual int charge() const =0
electric charge
bool preselect(const reco::Candidate &, const reco::Candidate &) const
verify that the two candidate don&#39;t overlap and check charge
std::unique_ptr< OutputCollection > combine(const std::vector< edm::Handle< reco::CandidateView > > &, const vstring &=vstring()) const
return all selected candidate pairs
std::vector< int > dauCharge_
electric charges of the daughters
std::vector< std::pair< std::pair< CandPtr, size_t >, std::vector< edm::Handle< reco::CandidateView > >::const_iterator > > CandStack
temporary candidate stack
def checkOverlap(process)
std::vector< std::string > vstring
std::string name_
composite name (if applies)
virtual void setup(typename OutputCollection::value_type &) const =0
set kinematics to reconstructed composite
std::vector< int > ChargeStack