CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CandCombinerBase.h
Go to the documentation of this file.
1 #ifndef PhysicsTools_CandUtils_CandCombinerBase_h
2 #define PhysicsTools_CandUtils_CandCombinerBase_h
3 
10 #include <vector>
11 #include <string>
12 
13 template<typename OutputCollection, typename CandPtr>
14 class CandCombinerBase {
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, const std::vector <int> &, const std::string = "");
28  virtual ~CandCombinerBase();
30  std::auto_ptr<OutputCollection>
31  combine(const std::vector<edm::Handle<reco::CandidateView> > &, const vstring = vstring()) const;
33  std::auto_ptr<OutputCollection>
34  combine(const edm::Handle<reco::CandidateView> &, const vstring = vstring()) const;
36  std::auto_ptr<OutputCollection>
38  const edm::Handle<reco::CandidateView> &, const vstring = vstring()) const;
40  std::auto_ptr<OutputCollection>
43  const edm::Handle<reco::CandidateView> &, const vstring = vstring()) const;
45  std::auto_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  std::auto_ptr<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;
77  bool checkCharge_;
79  std::vector<int> dauCharge_;
83  std::string name_;
84 };
85 
86 template<typename OutputCollection, typename CandPtr>
88  checkCharge_(false), dauCharge_(), overlap_(), name_(name) {
89 }
90 
91 template<typename OutputCollection, typename CandPtr>
93  checkCharge_(true), dauCharge_(2), overlap_(), name_(name) {
94  dauCharge_[0] = q1;
95  dauCharge_[1] = q2;
96 }
97 
98 template<typename OutputCollection, typename CandPtr>
99 CandCombinerBase<OutputCollection, CandPtr>::CandCombinerBase(int q1, int q2, int q3, const std::string name) :
100  checkCharge_(true), dauCharge_(3), overlap_(), name_(name) {
101  dauCharge_[0] = q1;
102  dauCharge_[1] = q2;
103  dauCharge_[2] = q3;
104 }
105 
106 template<typename OutputCollection, typename CandPtr>
107 CandCombinerBase<OutputCollection, CandPtr>::CandCombinerBase(int q1, int q2, int q3, int q4, const std::string name) :
108  checkCharge_(true), dauCharge_(4), overlap_(), name_(name) {
109  dauCharge_[0] = q1;
110  dauCharge_[1] = q2;
111  dauCharge_[2] = q3;
112  dauCharge_[3] = q4;
113 }
114 
115 template<typename OutputCollection, typename CandPtr>
116 CandCombinerBase<OutputCollection, CandPtr>::CandCombinerBase(bool checkCharge, const std::vector<int> & dauCharge, const std::string name) :
117  checkCharge_(checkCharge), dauCharge_(dauCharge), overlap_(), name_(name) {
118 }
119 
120 template<typename OutputCollection, typename CandPtr>
122 }
123 
124 template<typename OutputCollection, typename CandPtr>
126  if (checkCharge_) {
127  int dq1 = dauCharge_[0], dq2 = dauCharge_[1], q1 = c1.charge(), q2 = c2.charge();
128  bool matchCharge = (q1 == dq1 && q2 == dq2) || (q1 == -dq1 && q2 == -dq2);
129  if (!matchCharge) return false;
130  }
131  if (overlap_(c1, c2)) return false;
132  return selectPair(c1, c2);
133 }
134 
135 template<typename OutputCollection, typename CandPtr>
137  const CandPtr & c1, const CandPtr & c2,
138  const std::string name1, const std::string name2) const {
139  addDaughter(cmp, c1, name1);
140  addDaughter(cmp, c2, name2);
141  setup(cmp);
142 }
143 
144 template<typename OutputCollection, typename CandPtr>
145 std::auto_ptr<OutputCollection>
147  const vstring names) const {
148  size_t srcSize = src.size();
149  if (checkCharge_ && dauCharge_.size() != srcSize)
151  << "CandCombiner: trying to combine " << srcSize << " collections"
152  << " but configured to check against " << dauCharge_.size() << " charges.";
153  std::auto_ptr<OutputCollection> comps(new OutputCollection);
154  size_t namesSize = names.size();
155  if(srcSize == 2) {
156  std::string name1="", name2="";
157  if(namesSize > 0) {
158  if(namesSize != 2)
160  << "CandCombiner: should specify exactly two "
161  << " names in configuration (" << namesSize << " specified).\n";
162  name1 = names[0];
163  name2 = names[1];
164  }
166  if(src1.id() == src2.id()) {
167  const reco::CandidateView & cands = * src1;
168  const size_t n = cands.size();
169  for(size_t i1 = 0; i1 < n; ++i1) {
170  const reco::Candidate & c1 = cands[i1];
171  CandPtr cr1(src1, i1);
172  for(size_t i2 = i1 + 1; i2 < n; ++i2) {
173  const reco::Candidate & c2 = cands[i2];
174  if(preselect(c1, c2)) {
175  CandPtr cr2(src2, i2);
177  combine(c, cr1, cr2, name1, name2);
178  if(select(c))
179  comps->push_back(c);
180  }
181  }
182  }
183  } else {
184  const reco::CandidateView & cands1 = * src1, & cands2 = * src2;
185  const size_t n1 = cands1.size(), n2 = cands2.size();
186  for(size_t i1 = 0; i1 < n1; ++i1) {
187  const reco::Candidate & c1 = cands1[i1];
188  CandPtr cr1(src1, i1);
189  for(size_t i2 = 0; i2 < n2; ++i2) {
190  const reco::Candidate & c2 = cands2[i2];
191  if(preselect(c1, c2)) {
192  CandPtr cr2(src2, i2);
194  combine(c, cr1, cr2, name1, name2);
195  if(select(c))
196  comps->push_back(c);
197  }
198  }
199  }
200  }
201  } else {
202  CandStack stack;
203  ChargeStack qStack;
204  combine(0, stack, qStack, src.begin(), src.end(), comps, names);
205  }
206 
207  return comps;
208 }
209 
210 template<typename OutputCollection, typename CandPtr>
211 std::auto_ptr<OutputCollection>
213  const vstring names) const {
214  if(checkCharge_ && dauCharge_.size() != 2)
216  << "CandCombiner: trying to combine 2 collections"
217  << " but configured to check against " << dauCharge_.size() << " charges.";
218 
219  std::auto_ptr<OutputCollection> comps(new OutputCollection);
220  size_t namesSize = names.size();
221  std::string name1, name2;
222  if(namesSize > 0) {
223  if(namesSize != 2)
225  << "CandCombiner: should specify exactly two "
226  << " names in configuration (" << namesSize << " specified).\n";
227  name1 = names[0];
228  name2 = names[1];
229  }
230  const reco::CandidateView & cands = * src;
231  const size_t n = cands.size();
232  for(size_t i1 = 0; i1 < n; ++i1) {
233  const reco::Candidate & c1 = cands[i1];
234  CandPtr cr1(src, i1);
235  for(size_t i2 = i1 + 1; i2 < n; ++i2) {
236  const reco::Candidate & c2 = cands[i2];
237  if(preselect(c1, c2)) {
238  CandPtr cr2(src, i2);
240  combine(c, cr1, cr2, name1, name2);
241  if(select(c))
242  comps->push_back(c);
243  }
244  }
245  }
246 
247  return comps;
248 }
249 
250 template<typename OutputCollection, typename CandPtr>
251 std::auto_ptr<OutputCollection>
254  const vstring names) const {
255  std::vector<edm::Handle<reco::CandidateView> > src;
256  src.push_back(src1);
257  src.push_back(src2);
258  return combine(src, names);
259 }
260 
261 template<typename OutputCollection, typename CandPtr>
262 std::auto_ptr<OutputCollection>
264  const edm::Handle<reco::CandidateView> & src2,
266  const vstring names) const {
267  std::vector<edm::Handle<reco::CandidateView> > src;
268  src.push_back(src1);
269  src.push_back(src2);
270  src.push_back(src3);
271  return combine(src, names);
272 }
273 
274 template<typename OutputCollection, typename CandPtr>
275 std::auto_ptr<OutputCollection>
277  const edm::Handle<reco::CandidateView> & src2,
278  const edm::Handle<reco::CandidateView> & src3,
280  const vstring names) const {
281  std::vector<edm::Handle<reco::CandidateView> > src;
282  src.push_back(src1);
283  src.push_back(src2);
284  src.push_back(src3);
285  src.push_back(src4);
286  return combine(src, names);
287 }
288 
289 template<typename OutputCollection, typename CandPtr>
290 void CandCombinerBase<OutputCollection, CandPtr>::combine(size_t collectionIndex, CandStack & stack, ChargeStack & qStack,
291  std::vector<edm::Handle<reco::CandidateView> >::const_iterator collBegin,
292  std::vector<edm::Handle<reco::CandidateView> >::const_iterator collEnd,
293  std::auto_ptr<OutputCollection> & comps,
294  const vstring names) const {
295  if(collBegin == collEnd) {
296  static const int undetermined = 0, sameDecay = 1, conjDecay = -1, wrongDecay = 2;
297  int decayType = undetermined;
298  if(checkCharge_) {
299  assert(qStack.size() == stack.size());
300  for(size_t i = 0; i < qStack.size(); ++i) {
301  int q = qStack[i], dq = dauCharge_[i];
302  if(decayType == undetermined) {
303  if(q != 0 && dq != 0) {
304  if(q == dq) decayType = sameDecay;
305  else if(q == -dq) decayType = conjDecay;
306  else decayType = wrongDecay;
307  }
308  } else if((decayType == sameDecay && q != dq) ||
309  (decayType == conjDecay && q != -dq)) {
310  decayType = wrongDecay;
311  }
312  if(decayType == wrongDecay) break;
313  }
314  }
315  if(decayType != wrongDecay) {
317  size_t nameIndex = 0;
318  for(typename CandStack::const_iterator i = stack.begin(); i != stack.end(); ++i, ++ nameIndex) {
319  if ( names.size() > 0 )
320  addDaughter(c, i->first.first, names[nameIndex]);
321  else
322  addDaughter(c, i->first.first);
323  }
324  setup(c);
325  if(select(c))
326  comps->push_back(c);
327  }
328  } else {
329  const edm::Handle<reco::CandidateView> & srcRef = * collBegin;
330  const reco::CandidateView & src = * srcRef;
331  size_t candBegin = 0, candEnd = src.size();
332  for(typename CandStack::const_iterator i = stack.begin(); i != stack.end(); ++i)
333  if(srcRef.id() == i->second->id())
334  candBegin = i->first.second + 1;
335  for(size_t candIndex = candBegin; candIndex != candEnd; ++ candIndex) {
336  CandPtr candRef(srcRef, candIndex);
337  bool noOverlap = true;
338  const reco::Candidate & cand = * candRef;
339  for(typename CandStack::const_iterator i = stack.begin(); i != stack.end(); ++i)
340  if(overlap_(cand, *(i->first.first))) {
341  noOverlap = false;
342  break;
343  }
344  if(noOverlap) {
345  stack.push_back(std::make_pair(std::make_pair(candRef, candIndex), collBegin));
346  if(checkCharge_) qStack.push_back(cand.charge());
347  combine(collectionIndex + 1, stack, qStack, collBegin + 1, collEnd, comps, names);
348  stack.pop_back();
349  qStack.pop_back();
350  }
351  }
352  }
353 }
354 
355 #endif
int i
Definition: DBlmapReader.cc:9
std::vector< ProtoJet > OutputCollection
Definition: JetRecoTypes.h:63
virtual bool select(const reco::Candidate &) const =0
select a candidate
static const HistoName names[]
virtual bool selectPair(const reco::Candidate &c1, const reco::Candidate &c2) const =0
select a candidate pair
ProductID id() const
Definition: HandleBase.cc:15
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
OverlapChecker overlap_
utility to check candidate daughters overlap
CandCombinerBase(const std::string="")
default construct
double q2[4]
Definition: TauolaWrapper.h:88
static const unsigned int namesSize
static type combine(const A &_1, const B &_2)
Definition: Factorize.h:186
stack
Definition: svgfig.py:558
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
#define end
Definition: vmac.h:38
Container::value_type value_type
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
size_type size() const
std::vector< std::string > vstring
std::vector< std::string > vstring
#define begin
Definition: vmac.h:31
std::vector< int > dauCharge_
electric charges of the daughters
ProductIndex id() const
Definition: ProductID.h:38
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
void setup(std::vector< TH2F > &depth, std::string name, std::string units="")
std::auto_ptr< OutputCollection > combine(const std::vector< edm::Handle< reco::CandidateView > > &, const vstring=vstring()) const
return all selected candidate pairs