00001 #ifndef RecoParticleFlow_Benchmark_PFBenchmarkAlgo_h
00002 #define RecoParticleFlow_Benchmark_PFBenchmarkAlgo_h
00003
00004 #include "FWCore/Utilities/interface/Exception.h"
00005 #include "DataFormats/Common/interface/OwnVector.h"
00006
00007 #include <cmath>
00008 #include <vector>
00009
00010
00011
00012
00013
00014
00015
00016 class PFBenchmarkAlgo {
00017 public:
00018
00019
00020 template <typename T, typename U>
00021 static double deltaEt(const T *, const U *);
00022
00023
00024 template <typename T, typename U>
00025 static double deltaEta(const T *, const U *);
00026
00027
00028 template <typename T, typename U>
00029 static double deltaPhi(const T *, const U *);
00030
00031
00032 template <typename T, typename U>
00033 static double deltaR(const T *, const U *);
00034
00035
00036 template <typename T, typename Collection>
00037 static const typename Collection::value_type *matchByDeltaR(const T *, const Collection *);
00038
00039
00040 template <typename T, typename Collection>
00041 static const typename Collection::value_type *matchByDeltaEt(const T *, const Collection *);
00042
00043
00044 template <typename T, typename Collection>
00045 static Collection copyCollection(const Collection *);
00046
00047
00048 template <typename T, typename Collection>
00049 static void sortByDeltaR(const T *, Collection &);
00050
00051
00052 template <typename T, typename Collection>
00053 static void sortByDeltaEt(const T *, Collection &);
00054
00055
00056 template <typename T, typename Collection>
00057 static Collection findAllInCone(const T *, const Collection *, double);
00058
00059
00060 template <typename T, typename Collection>
00061 static Collection findAllInEtWindow(const T *, const Collection *, double);
00062
00063 private:
00064
00065
00066 template <typename T, typename U, template <typename,typename> class Sorter>
00067 static void vector_sort(std::vector<T> &candidates, Sorter<T,U> S) {
00068 sort(candidates.begin(),candidates.end(),S);
00069 }
00070
00071
00072 template <typename T>
00073 static void vector_add(const T *c1, std::vector<T> &candidates) {
00074 candidates.push_back(*c1);
00075 }
00076
00077
00078 template <typename T, typename U, template <typename,typename> class Sorter>
00079 static void vector_sort(edm::OwnVector<T> &candidates, Sorter<T,U> S) {
00080 candidates.sort(S);
00081 }
00082
00083
00084 template <typename T>
00085 static void vector_add(const T *c1, edm::OwnVector<T> &candidates) {
00086 candidates.push_back((T *const)c1->clone());
00087 }
00088
00089 };
00090
00091
00092
00093
00094
00095
00096 template <typename T, typename U> class deltaRSorter {
00097 public:
00098
00099 deltaRSorter(const T *Ref) { cref = Ref; }
00100 bool operator()(const U &c1, const U &c2) const {
00101 return PFBenchmarkAlgo::deltaR(cref,&c1) < PFBenchmarkAlgo::deltaR(cref,&c2);
00102 }
00103
00104 private:
00105
00106 const T *cref;
00107
00108 };
00109
00110
00111 template <typename T, typename U> class deltaEtSorter {
00112 public:
00113
00114 deltaEtSorter(const T *Ref) { cref = Ref; }
00115 bool operator()(const U &c1, const U &c2) const {
00116 return fabs(PFBenchmarkAlgo::deltaEt(cref,&c1)) < fabs(PFBenchmarkAlgo::deltaEt(cref,&c2));
00117 }
00118
00119 private:
00120
00121 const T *cref;
00122
00123 };
00124
00125
00126 template <typename T, typename U>
00127 double PFBenchmarkAlgo::deltaEt(const T *c1, const U *c2) {
00128
00129 if (c1 == NULL || c2 == NULL)
00130 throw cms::Exception("Invalid Arg") << "attempted to calculate deltaEt for invalid Candidate(s)";
00131
00132 return c1->et() - c2->et();
00133
00134 }
00135
00136
00137 template <typename T, typename U>
00138 double PFBenchmarkAlgo::deltaEta(const T *c1, const U *c2) {
00139
00140 if (c1 == NULL || c2 == NULL)
00141 throw cms::Exception("Invalid Arg") << "attempted to calculate deltaEta for invalid Candidate(s)";
00142
00143 return c1->eta() - c2->eta();
00144
00145 }
00146
00147
00148 template <typename T, typename U>
00149 double PFBenchmarkAlgo::deltaPhi(const T *c1, const U *c2) {
00150
00151 if (c1 == NULL || c2 == NULL)
00152 throw cms::Exception("Invalid Arg") << "attempted to calculate deltaPhi for invalid Candidate(s)";
00153
00154
00155 double phi1 = c1->phi();
00156 if (phi1 > M_PI) phi1 -= ceil((phi1 - M_PI) / (2 * M_PI)) * 2 * M_PI;
00157 if (phi1 <= - M_PI) phi1 += ceil((phi1 + M_PI) / (-2. * M_PI)) * 2. * M_PI;
00158
00159 double phi2 = c2->phi();
00160 if (phi2 > M_PI) phi2 -= ceil((phi2 - M_PI) / (2 * M_PI)) * 2 * M_PI;
00161 if (phi2 <= - M_PI) phi2 += ceil((phi2 + M_PI) / (-2. * M_PI)) * 2 * M_PI;
00162
00163
00164
00165
00166
00167 double deltaphi=-999.0;
00168 if (fabs(phi1 - phi2)<M_PI)
00169 {
00170 deltaphi=(phi1-phi2);
00171 }
00172 else
00173 {
00174 if ((phi1-phi2)>0.0)
00175 {
00176 deltaphi=(2*M_PI - fabs(phi1 - phi2));
00177 }
00178 else
00179 {
00180 deltaphi=-(2*M_PI - fabs(phi1 - phi2));
00181 }
00182 }
00183 return deltaphi;
00184
00185 }
00186
00187
00188 template <typename T, typename U>
00189 double PFBenchmarkAlgo::deltaR(const T *c1, const U *c2) {
00190
00191 if (c1 == NULL || c2 == NULL)
00192 throw cms::Exception("Invalid Arg") << "attempted to calculate deltaR for invalid Candidate(s)";
00193
00194 return sqrt(std::pow(deltaPhi(c1,c2),2) + std::pow(deltaEta(c1,c2),2));
00195
00196 }
00197
00198
00199 template <typename T, typename Collection>
00200 const typename Collection::value_type *PFBenchmarkAlgo::matchByDeltaR(const T *c1, const Collection *candidates) {
00201
00202 typedef typename Collection::value_type U;
00203
00204
00205 if (!c1) throw cms::Exception("Invalid Arg") << "attempted to match invalid Candidate";
00206 if (!candidates) throw cms::Exception("Invalid Arg") << "attempted to match to invalid Collection";
00207
00208 double minDeltaR = 9999.;
00209 const U *match = NULL;
00210
00211
00212 for (unsigned int i = 0; i < candidates->size(); i++) {
00213
00214 const U *c2 = &(*candidates)[i];
00215 if (!c2) throw cms::Exception("Invalid Arg") << "attempted to match to invalid Candidate";
00216
00217
00218 double dR = deltaR(c1,c2);
00219 if (dR <= minDeltaR) { match = c2; minDeltaR = dR; }
00220
00221 }
00222
00223
00224 return match;
00225
00226 }
00227
00228
00229 template <typename T, typename Collection>
00230 const typename Collection::value_type *PFBenchmarkAlgo::matchByDeltaEt(const T *c1, const Collection *candidates) {
00231
00232 typedef typename Collection::value_type U;
00233
00234
00235 if (!c1) throw cms::Exception("Invalid Arg") << "attempted to match invalid Candidate";
00236 if (!candidates) throw cms::Exception("Invalid Arg") << "attempted to match to invalid Collection";
00237
00238 double minDeltaEt = 9999.;
00239 const U *match = NULL;
00240
00241
00242 for (unsigned int i = 0; i < candidates->size(); i++) {
00243
00244 const T *c2 = &(*candidates)[i];
00245 if (!c2) throw cms::Exception("Invalid Arg") << "attempted to match to invalid Candidate";
00246
00247
00248 double dEt = fabs(deltaEt(c1,c2));
00249 if (dEt <= minDeltaEt) { match = c2; minDeltaEt = dEt; }
00250
00251 }
00252
00253
00254 return match;
00255
00256 }
00257
00258
00259 template <typename T, typename Collection>
00260 Collection PFBenchmarkAlgo::copyCollection(const Collection *candidates) {
00261
00262 typedef typename Collection::value_type U;
00263
00264
00265 if (!candidates) throw cms::Exception("Invalid Arg") << "attempted to copy invalid Collection";
00266
00267 Collection copy;
00268
00269 for (unsigned int i = 0; i < candidates->size(); i++)
00270 vector_add(&(*candidates)[i],copy);
00271
00272 return copy;
00273
00274 }
00275
00276
00277
00278 template <typename T, typename Collection>
00279 void PFBenchmarkAlgo::sortByDeltaR(const T *c1, Collection &candidates) {
00280
00281 typedef typename Collection::value_type U;
00282
00283
00284 if (!c1) throw cms::Exception("Invalid Arg") << "attempted to sort by invalid Candidate";
00285 if (!candidates) throw cms::Exception("Invalid Arg") << "attempted to sort invalid Candidates";
00286
00287
00288 vector_sort(candidates,deltaRSorter<T,U>(c1));
00289
00290 }
00291
00292
00293 template <typename T, typename Collection>
00294 void PFBenchmarkAlgo::sortByDeltaEt(const T *c1, Collection &candidates) {
00295
00296 typedef typename Collection::value_type U;
00297
00298
00299 if (!c1) throw cms::Exception("Invalid Arg") << "attempted to sort by invalid Candidate";
00300 if (!candidates) throw cms::Exception("Invalid Arg") << "attempted to sort invalid Candidates";
00301
00302
00303 vector_sort(candidates,deltaEtSorter<T,U>(c1));
00304
00305 }
00306
00307
00308 template <typename T, typename Collection>
00309 Collection PFBenchmarkAlgo::findAllInCone(const T *c1, const Collection *candidates, double ConeSize) {
00310
00311 typedef typename Collection::value_type U;
00312
00313
00314 if (!c1) throw cms::Exception("Invalid Arg") << "attempted to constrain to invalid Candidate";
00315 if (!candidates) throw cms::Exception("Invalid Arg") << "attempted to constrain invalid Collection";
00316 if (ConeSize <= 0) throw cms::Exception("Invalid Arg") << "zero or negative cone size specified";
00317
00318 Collection constrained;
00319
00320 for (unsigned int i = 0; i < candidates->size(); i++) {
00321
00322 const U *c2 = &(*candidates)[i];
00323
00324
00325 double dR = deltaR(c1,c2);
00326 if (dR < ConeSize) vector_add(c2,constrained);
00327
00328 }
00329
00330
00331 sortByDeltaR(c1,constrained);
00332 return constrained;
00333
00334 }
00335
00336
00337 template <typename T, typename Collection>
00338 Collection PFBenchmarkAlgo::findAllInEtWindow(const T *c1, const Collection *candidates, double EtWindow) {
00339
00340 typedef typename Collection::value_type U;
00341
00342
00343 if (!c1) throw cms::Exception("Invalid Arg") << "attempted to constrain to invalid Candidate";
00344 if (!candidates) throw cms::Exception("Invalid Arg") << "attempted to constrain invalid Collection";
00345 if (EtWindow <= 0) throw cms::Exception("Invalid Arg") << "zero or negative cone size specified";
00346
00347 Collection constrained;
00348
00349
00350
00351 for (unsigned int i = 0; i < candidates->size(); i++) {
00352
00353 const U *c2 = &(*candidates)[i];
00354
00355
00356 double dEt = fabs(deltaEt(c1,c2));
00357 if (dEt < EtWindow) vector_add(c2,constrained);
00358
00359 }
00360
00361
00362 sortByDeltaEt(c1,constrained);
00363 return constrained;
00364
00365 }
00366
00367 #endif // RecoParticleFlow_Benchmark_PFBenchmarkAlgo_h