CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PFBenchmarkAlgo.h
Go to the documentation of this file.
1 #ifndef RecoParticleFlow_Benchmark_PFBenchmarkAlgo_h
2 #define RecoParticleFlow_Benchmark_PFBenchmarkAlgo_h
3 
6 
7 #include <cmath>
8 #include <vector>
9 
10 // Notes on template implementation:
11 // - T, U are arbitrary types (must have et(), eta(), etc. defined)
12 // support for Candidate-derived objects is explicit
13 // - Collection is a generic container class. Support for edm::OwnVector
14 // and std::vector is explicit.
15 
17 public:
18 
19  // Calculate Delta-Et for the pair of Candidates (T - U)
20  template <typename T, typename U>
21  static double deltaEt(const T *, const U *);
22 
23  // Calculate Delta-Eta for the pair of Candidates (T - U)
24  template <typename T, typename U>
25  static double deltaEta(const T *, const U *);
26 
27  // Calculate Delta-Phi for the pair of Candidates (T - U)
28  template <typename T, typename U>
29  static double deltaPhi(const T *, const U *);
30 
31  // Calculate Delta-R for the pair of Candidates
32  template <typename T, typename U>
33  static double deltaR(const T *, const U *);
34 
35  // Match Candidate T to a Candidate in the Collection based on minimum Delta-R
36  template <typename T, typename Collection>
37  static const typename Collection::value_type *matchByDeltaR(const T *, const Collection *);
38 
39  // Match Candidate T to a Candidate U in the Collection based on minimum Delta-Et
40  template <typename T, typename Collection>
41  static const typename Collection::value_type *matchByDeltaEt(const T *, const Collection *);
42 
43  // Copy the input Collection (useful when sorting)
44  template <typename T, typename Collection>
45  static Collection copyCollection(const Collection *);
46 
47  // Sort the U Candidates to the T Candidate based on minimum Delta-R
48  template <typename T, typename Collection>
49  static void sortByDeltaR(const T *, Collection &);
50 
51  // Sort the U Candidates to the T Candidate based on minimum Delta-Et
52  template <typename T, typename Collection>
53  static void sortByDeltaEt(const T *, Collection &);
54 
55  // Constrain the U Candidates to the T Candidate based on Delta-R to T
56  template <typename T, typename Collection>
57  static Collection findAllInCone(const T *, const Collection *, double);
58 
59  // Constrain the U Candidates to the T Candidate based on Delta-Et to T
60  template <typename T, typename Collection>
61  static Collection findAllInEtWindow(const T *, const Collection *, double);
62 
63 private:
64 
65  // std::vector sort helper function
66  template <typename T, typename U, template <typename,typename> class Sorter>
67  static void vector_sort(std::vector<T> &candidates, Sorter<T,U> S) {
68  sort(candidates.begin(),candidates.end(),S);
69  }
70 
71  // std::vector push_back helper function
72  template <typename T>
73  static void vector_add(const T *c1, std::vector<T> &candidates) {
74  candidates.push_back(*c1);
75  }
76 
77  // edm::OwnVector sort helper functions
78  template <typename T, typename U, template <typename,typename> class Sorter>
79  static void vector_sort(edm::OwnVector<T> &candidates, Sorter<T,U> S) {
80  candidates.sort(S);
81  }
82 
83  // edm::OwnVector push_back helper function
84  template <typename T>
85  static void vector_add(const T *c1, edm::OwnVector<T> &candidates) {
86  candidates.push_back((T *const)c1->clone());
87  }
88 
89 };
90 
91 // ========================================================================
92 // implementation follows (required to be in header for templates)
93 // ========================================================================
94 
95 // Helper class for sorting U Collections by Delta-R to a Candidate T
96 template <typename T, typename U> class deltaRSorter {
97 public:
98 
99  deltaRSorter(const T *Ref) { cref = Ref; }
100  bool operator()(const U &c1, const U &c2) const {
102  }
103 
104 private:
105 
106  const T *cref;
107 
108 };
109 
110 // Helper class for sorting U Collections by Delta-Et to a Candidate T
111 template <typename T, typename U> class deltaEtSorter {
112 public:
113 
114  deltaEtSorter(const T *Ref) { cref = Ref; }
115  bool operator()(const U &c1, const U &c2) const {
116  return fabs(PFBenchmarkAlgo::deltaEt(cref,&c1)) < fabs(PFBenchmarkAlgo::deltaEt(cref,&c2));
117  }
118 
119 private:
120 
121  const T *cref;
122 
123 };
124 
125 // Calculate Delta-Et for Candidates (T - U)
126 template <typename T, typename U>
127 double PFBenchmarkAlgo::deltaEt(const T *c1, const U *c2) {
128 
129  if (c1 == NULL || c2 == NULL)
130  throw cms::Exception("Invalid Arg") << "attempted to calculate deltaEt for invalid Candidate(s)";
131 
132  return c1->et() - c2->et();
133 
134 }
135 
136 // Calculate Delta-Eta for Candidates (T - U)
137 template <typename T, typename U>
138 double PFBenchmarkAlgo::deltaEta(const T *c1, const U *c2) {
139 
140  if (c1 == NULL || c2 == NULL)
141  throw cms::Exception("Invalid Arg") << "attempted to calculate deltaEta for invalid Candidate(s)";
142 
143  return c1->eta() - c2->eta();
144 
145 }
146 
147 // Calculate Delta-Phi for Candidates (T - U)
148 template <typename T, typename U>
149 double PFBenchmarkAlgo::deltaPhi(const T *c1, const U *c2) {
150 
151  if (c1 == NULL || c2 == NULL)
152  throw cms::Exception("Invalid Arg") << "attempted to calculate deltaPhi for invalid Candidate(s)";
153 
154 
155  double phi1 = c1->phi();
156  if (phi1 > M_PI) phi1 -= ceil((phi1 - M_PI) / (2 * M_PI)) * 2 * M_PI;
157  if (phi1 <= - M_PI) phi1 += ceil((phi1 + M_PI) / (-2. * M_PI)) * 2. * M_PI;
158 
159  double phi2 = c2->phi();
160  if (phi2 > M_PI) phi2 -= ceil((phi2 - M_PI) / (2 * M_PI)) * 2 * M_PI;
161  if (phi2 <= - M_PI) phi2 += ceil((phi2 + M_PI) / (-2. * M_PI)) * 2 * M_PI;
162 
163  // alternative method:
164  // while (phi > M_PI) phi -= 2 * M_PI;
165  // while (phi <= - M_PI) phi += 2 * M_PI;
166 
167  double deltaphi=-999.0;
168  if (fabs(phi1 - phi2)<M_PI)
169  {
170  deltaphi=(phi1-phi2);
171  }
172  else
173  {
174  if ((phi1-phi2)>0.0)
175  {
176  deltaphi=(2*M_PI - fabs(phi1 - phi2));
177  }
178  else
179  {
180  deltaphi=-(2*M_PI - fabs(phi1 - phi2));
181  }
182  }
183  return deltaphi;
184  //return ( (fabs(phi1 - phi2)<M_PI)?(phi1-phi2):(2*M_PI - fabs(phi1 - phi2) ) ); // FL: wrong
185 }
186 
187 // Calculate Delta-R for Candidates
188 template <typename T, typename U>
189 double PFBenchmarkAlgo::deltaR(const T *c1, const U *c2) {
190 
191  if (c1 == NULL || c2 == NULL)
192  throw cms::Exception("Invalid Arg") << "attempted to calculate deltaR for invalid Candidate(s)";
193 
194  return sqrt(std::pow(deltaPhi(c1,c2),2) + std::pow(deltaEta(c1,c2),2));
195 
196 }
197 
198 // Match Candidate T to a Candidate in the Collection based on minimum Delta-R
199 template <typename T, typename Collection>
200 const typename Collection::value_type *PFBenchmarkAlgo::matchByDeltaR(const T *c1, const Collection *candidates) {
201 
202  typedef typename Collection::value_type U;
203 
204  // Try to verify the validity of the Candidate and Collection
205  if (!c1) throw cms::Exception("Invalid Arg") << "attempted to match invalid Candidate";
206  if (!candidates) throw cms::Exception("Invalid Arg") << "attempted to match to invalid Collection";
207 
208  double minDeltaR = 9999.;
209  const U *match = NULL;
210 
211  // Loop Over the Candidates...
212  for (unsigned int i = 0; i < candidates->size(); i++) {
213 
214  const U *c2 = &(*candidates)[i];
215  if (!c2) throw cms::Exception("Invalid Arg") << "attempted to match to invalid Candidate";
216 
217  // Find Minimal Delta-R
218  double dR = deltaR(c1,c2);
219  if (dR <= minDeltaR) { match = c2; minDeltaR = dR; }
220 
221  }
222 
223  // Return the Candidate with the smallest dR
224  return match;
225 
226 }
227 
228 // Match Candidate T to a Candidate U in the Collection based on minimum Delta-Et
229 template <typename T, typename Collection>
230 const typename Collection::value_type *PFBenchmarkAlgo::matchByDeltaEt(const T *c1, const Collection *candidates) {
231 
232  typedef typename Collection::value_type U;
233 
234  // Try to verify the validity of the Candidate and Collection
235  if (!c1) throw cms::Exception("Invalid Arg") << "attempted to match invalid Candidate";
236  if (!candidates) throw cms::Exception("Invalid Arg") << "attempted to match to invalid Collection";
237 
238  double minDeltaEt = 9999.;
239  const U *match = NULL;
240 
241  // Loop Over the Candidates...
242  for (unsigned int i = 0; i < candidates->size(); i++) {
243 
244  const T *c2 = &(*candidates)[i];
245  if (!c2) throw cms::Exception("Invalid Arg") << "attempted to match to invalid Candidate";
246 
247  // Find Minimal Delta-R
248  double dEt = fabs(deltaEt(c1,c2));
249  if (dEt <= minDeltaEt) { match = c2; minDeltaEt = dEt; }
250 
251  }
252 
253  // Return the Candidate with the smallest dR
254  return match;
255 
256 }
257 
258 // Copy the Collection (useful when sorting)
259 template <typename T, typename Collection>
260 Collection PFBenchmarkAlgo::copyCollection(const Collection *candidates) {
261 
262  typedef typename Collection::value_type U;
263 
264  // Try to verify the validity of the Collection
265  if (!candidates) throw cms::Exception("Invalid Arg") << "attempted to copy invalid Collection";
266 
267  Collection copy;
268 
269  for (unsigned int i = 0; i < candidates->size(); i++)
270  vector_add(&(*candidates)[i],copy);
271 
272  return copy;
273 
274 }
275 
276 
277 // Sort the U Candidates to the Candidate T based on minimum Delta-R
278 template <typename T, typename Collection>
279 void PFBenchmarkAlgo::sortByDeltaR(const T *c1, Collection &candidates) {
280 
281  typedef typename Collection::value_type U;
282 
283  // Try to verify the validity of Candidate and Collection
284  if (!c1) throw cms::Exception("Invalid Arg") << "attempted to sort by invalid Candidate";
285  if (!candidates) throw cms::Exception("Invalid Arg") << "attempted to sort invalid Candidates";
286 
287  // Sort the collection
288  vector_sort(candidates,deltaRSorter<T,U>(c1));
289 
290 }
291 
292 // Sort the U Candidates to the Candidate T based on minimum Delta-Et
293 template <typename T, typename Collection>
294 void PFBenchmarkAlgo::sortByDeltaEt(const T *c1, Collection &candidates) {
295 
296  typedef typename Collection::value_type U;
297 
298  // Try to verify the validity of Candidate and Collection
299  if (!c1) throw cms::Exception("Invalid Arg") << "attempted to sort by invalid Candidate";
300  if (!candidates) throw cms::Exception("Invalid Arg") << "attempted to sort invalid Candidates";
301 
302  // Sort the collection
303  vector_sort(candidates,deltaEtSorter<T,U>(c1));
304 
305 }
306 
307 // Constrain the U Candidates to the T Candidate based on Delta-R to T
308 template <typename T, typename Collection>
309 Collection PFBenchmarkAlgo::findAllInCone(const T *c1, const Collection *candidates, double ConeSize) {
310 
311  typedef typename Collection::value_type U;
312 
313  // Try to verify the validity of Candidate and the Collection
314  if (!c1) throw cms::Exception("Invalid Arg") << "attempted to constrain to invalid Candidate";
315  if (!candidates) throw cms::Exception("Invalid Arg") << "attempted to constrain invalid Collection";
316  if (ConeSize <= 0) throw cms::Exception("Invalid Arg") << "zero or negative cone size specified";
317 
318  Collection constrained;
319 
320  for (unsigned int i = 0; i < candidates->size(); i++) {
321 
322  const U *c2 = &(*candidates)[i];
323 
324  // Add in-cone Candidates to the new Collection
325  double dR = deltaR(c1,c2);
326  if (dR < ConeSize) vector_add(c2,constrained);
327 
328  }
329 
330  // Sort and return Collection
331  sortByDeltaR(c1,constrained);
332  return constrained;
333 
334 }
335 
336 // Constrain the U Candidates to the T Candidate based on Delta-Et to T
337 template <typename T, typename Collection>
338 Collection PFBenchmarkAlgo::findAllInEtWindow(const T *c1, const Collection *candidates, double EtWindow) {
339 
340  typedef typename Collection::value_type U;
341 
342  // Try to verify the validity of Candidate and the Collection
343  if (!c1) throw cms::Exception("Invalid Arg") << "attempted to constrain to invalid Candidate";
344  if (!candidates) throw cms::Exception("Invalid Arg") << "attempted to constrain invalid Collection";
345  if (EtWindow <= 0) throw cms::Exception("Invalid Arg") << "zero or negative cone size specified";
346 
347  Collection constrained;
348 
349  //CandidateCollection::const_iterator candidate;
350  //for (candidate = candidates->begin(); candidate != candidates->end(); candidate++) {
351  for (unsigned int i = 0; i < candidates->size(); i++) {
352 
353  const U *c2 = &(*candidates)[i];
354 
355  // Add in-cone Candidates to the new Collection
356  double dEt = fabs(deltaEt(c1,c2));
357  if (dEt < EtWindow) vector_add(c2,constrained);
358 
359  }
360 
361  // Sort and return Collection
362  sortByDeltaEt(c1,constrained);
363  return constrained;
364 
365 }
366 
367 #endif // RecoParticleFlow_Benchmark_PFBenchmarkAlgo_h
static Collection copyCollection(const Collection *)
int i
Definition: DBlmapReader.cc:9
static void vector_add(const T *c1, edm::OwnVector< T > &candidates)
static void vector_add(const T *c1, std::vector< T > &candidates)
bool operator()(const U &c1, const U &c2) const
static void sortByDeltaR(const T *, Collection &)
#define NULL
Definition: scimark2.h:8
static const Collection::value_type * matchByDeltaEt(const T *, const Collection *)
static double deltaEt(const T *, const U *)
bool operator()(const U &c1, const U &c2) const
void push_back(D *&d)
Definition: OwnVector.h:274
static double deltaEta(const T *, const U *)
const T * cref
static void vector_sort(std::vector< T > &candidates, Sorter< T, U > S)
static Collection findAllInCone(const T *, const Collection *, double)
T sqrt(T t)
Definition: SSEVec.h:48
static double deltaR(const T *, const U *)
deltaRSorter(const T *Ref)
Container::value_type value_type
#define M_PI
static const Collection::value_type * matchByDeltaR(const T *, const Collection *)
static void sortByDeltaEt(const T *, Collection &)
void sort(S s)
Definition: OwnVector.h:391
static void vector_sort(edm::OwnVector< T > &candidates, Sorter< T, U > S)
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:6
static double deltaPhi(const T *, const U *)
long double T
static Collection findAllInEtWindow(const T *, const Collection *, double)
deltaEtSorter(const T *Ref)
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40