CMS 3D CMS Logo

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