File indexing completed on 2024-04-06 12:27:19
0001 #ifndef RecoParticleFlow_Benchmark_PFBenchmarkAlgo_h
0002 #define RecoParticleFlow_Benchmark_PFBenchmarkAlgo_h
0003
0004 #include "FWCore/Utilities/interface/Exception.h"
0005 #include "DataFormats/Common/interface/OwnVector.h"
0006
0007 #include <cmath>
0008 #include <vector>
0009
0010
0011
0012
0013
0014
0015
0016 class PFBenchmarkAlgo {
0017 public:
0018
0019 template <typename T, typename U>
0020 static double deltaEt(const T *, const U *);
0021
0022
0023 template <typename T, typename U>
0024 static double deltaEta(const T *, const U *);
0025
0026
0027 template <typename T, typename U>
0028 static double deltaPhi(const T *, const U *);
0029
0030
0031 template <typename T, typename U>
0032 static double deltaR(const T *, const U *);
0033
0034
0035 template <typename T, typename Collection>
0036 static const typename Collection::value_type *matchByDeltaR(const T *, const Collection *);
0037
0038
0039 template <typename T, typename Collection>
0040 static const typename Collection::value_type *matchByDeltaEt(const T *, const Collection *);
0041
0042
0043 template <typename T, typename Collection>
0044 static Collection copyCollection(const Collection *);
0045
0046
0047 template <typename T, typename Collection>
0048 static void sortByDeltaR(const T *, Collection &);
0049
0050
0051 template <typename T, typename Collection>
0052 static void sortByDeltaEt(const T *, Collection &);
0053
0054
0055 template <typename T, typename Collection>
0056 static Collection findAllInCone(const T *, const Collection *, double);
0057
0058
0059 template <typename T, typename Collection>
0060 static Collection findAllInEtWindow(const T *, const Collection *, double);
0061
0062 private:
0063
0064 template <typename T, typename U, template <typename, typename> class Sorter>
0065 static void vector_sort(std::vector<T> &candidates, Sorter<T, U> S) {
0066 sort(candidates.begin(), candidates.end(), S);
0067 }
0068
0069
0070 template <typename T>
0071 static void vector_add(const T *c1, std::vector<T> &candidates) {
0072 candidates.push_back(*c1);
0073 }
0074
0075
0076 template <typename T, typename U, template <typename, typename> class Sorter>
0077 static void vector_sort(edm::OwnVector<T> &candidates, Sorter<T, U> S) {
0078 candidates.sort(S);
0079 }
0080
0081
0082 template <typename T>
0083 static void vector_add(const T *c1, edm::OwnVector<T> &candidates) {
0084 candidates.push_back((T *const)c1->clone());
0085 }
0086 };
0087
0088
0089
0090
0091
0092
0093 template <typename T, typename U>
0094 class deltaRSorter {
0095 public:
0096 deltaRSorter(const T *Ref) { cref = Ref; }
0097 bool operator()(const U &c1, const U &c2) const {
0098 return PFBenchmarkAlgo::deltaR(cref, &c1) < PFBenchmarkAlgo::deltaR(cref, &c2);
0099 }
0100
0101 private:
0102 const T *cref;
0103 };
0104
0105
0106 template <typename T, typename U>
0107 class deltaEtSorter {
0108 public:
0109 deltaEtSorter(const T *Ref) { cref = Ref; }
0110 bool operator()(const U &c1, const U &c2) const {
0111 return fabs(PFBenchmarkAlgo::deltaEt(cref, &c1)) < fabs(PFBenchmarkAlgo::deltaEt(cref, &c2));
0112 }
0113
0114 private:
0115 const T *cref;
0116 };
0117
0118
0119 template <typename T, typename U>
0120 double PFBenchmarkAlgo::deltaEt(const T *c1, const U *c2) {
0121 if (c1 == nullptr || c2 == nullptr)
0122 throw cms::Exception("Invalid Arg") << "attempted to calculate deltaEt for invalid Candidate(s)";
0123
0124 return c1->et() - c2->et();
0125 }
0126
0127
0128 template <typename T, typename U>
0129 double PFBenchmarkAlgo::deltaEta(const T *c1, const U *c2) {
0130 if (c1 == nullptr || c2 == nullptr)
0131 throw cms::Exception("Invalid Arg") << "attempted to calculate deltaEta for invalid Candidate(s)";
0132
0133 return c1->eta() - c2->eta();
0134 }
0135
0136
0137 template <typename T, typename U>
0138 double PFBenchmarkAlgo::deltaPhi(const T *c1, const U *c2) {
0139 if (c1 == nullptr || c2 == nullptr)
0140 throw cms::Exception("Invalid Arg") << "attempted to calculate deltaPhi for invalid Candidate(s)";
0141
0142 double phi1 = c1->phi();
0143 if (phi1 > M_PI)
0144 phi1 -= ceil((phi1 - M_PI) / (2 * M_PI)) * 2 * M_PI;
0145 if (phi1 <= -M_PI)
0146 phi1 += ceil((phi1 + M_PI) / (-2. * M_PI)) * 2. * M_PI;
0147
0148 double phi2 = c2->phi();
0149 if (phi2 > M_PI)
0150 phi2 -= ceil((phi2 - M_PI) / (2 * M_PI)) * 2 * M_PI;
0151 if (phi2 <= -M_PI)
0152 phi2 += ceil((phi2 + M_PI) / (-2. * M_PI)) * 2 * M_PI;
0153
0154
0155
0156
0157
0158 double deltaphi = -999.0;
0159 if (fabs(phi1 - phi2) < M_PI) {
0160 deltaphi = (phi1 - phi2);
0161 } else {
0162 if ((phi1 - phi2) > 0.0) {
0163 deltaphi = (2 * M_PI - fabs(phi1 - phi2));
0164 } else {
0165 deltaphi = -(2 * M_PI - fabs(phi1 - phi2));
0166 }
0167 }
0168 return deltaphi;
0169
0170 }
0171
0172
0173 template <typename T, typename U>
0174 double PFBenchmarkAlgo::deltaR(const T *c1, const U *c2) {
0175 if (c1 == nullptr || c2 == nullptr)
0176 throw cms::Exception("Invalid Arg") << "attempted to calculate deltaR for invalid Candidate(s)";
0177
0178 return sqrt(std::pow(deltaPhi(c1, c2), 2) + std::pow(deltaEta(c1, c2), 2));
0179 }
0180
0181
0182 template <typename T, typename Collection>
0183 const typename Collection::value_type *PFBenchmarkAlgo::matchByDeltaR(const T *c1, const Collection *candidates) {
0184 typedef typename Collection::value_type U;
0185
0186
0187 if (!c1)
0188 throw cms::Exception("Invalid Arg") << "attempted to match invalid Candidate";
0189 if (!candidates)
0190 throw cms::Exception("Invalid Arg") << "attempted to match to invalid Collection";
0191
0192 double minDeltaR = 9999.;
0193 const U *match = nullptr;
0194
0195
0196 for (unsigned int i = 0; i < candidates->size(); i++) {
0197 const U *c2 = &(*candidates)[i];
0198 if (!c2)
0199 throw cms::Exception("Invalid Arg") << "attempted to match to invalid Candidate";
0200
0201
0202 double dR = deltaR(c1, c2);
0203 if (dR <= minDeltaR) {
0204 match = c2;
0205 minDeltaR = dR;
0206 }
0207 }
0208
0209
0210 return match;
0211 }
0212
0213
0214 template <typename T, typename Collection>
0215 const typename Collection::value_type *PFBenchmarkAlgo::matchByDeltaEt(const T *c1, const Collection *candidates) {
0216 typedef typename Collection::value_type U;
0217
0218
0219 if (!c1)
0220 throw cms::Exception("Invalid Arg") << "attempted to match invalid Candidate";
0221 if (!candidates)
0222 throw cms::Exception("Invalid Arg") << "attempted to match to invalid Collection";
0223
0224 double minDeltaEt = 9999.;
0225 const U *match = NULL;
0226
0227
0228 for (unsigned int i = 0; i < candidates->size(); i++) {
0229 const T *c2 = &(*candidates)[i];
0230 if (!c2)
0231 throw cms::Exception("Invalid Arg") << "attempted to match to invalid Candidate";
0232
0233
0234 double dEt = fabs(deltaEt(c1, c2));
0235 if (dEt <= minDeltaEt) {
0236 match = c2;
0237 minDeltaEt = dEt;
0238 }
0239 }
0240
0241
0242 return match;
0243 }
0244
0245
0246 template <typename T, typename Collection>
0247 Collection PFBenchmarkAlgo::copyCollection(const Collection *candidates) {
0248 typedef typename Collection::value_type U;
0249
0250
0251 if (!candidates)
0252 throw cms::Exception("Invalid Arg") << "attempted to copy invalid Collection";
0253
0254 Collection copy;
0255
0256 for (unsigned int i = 0; i < candidates->size(); i++)
0257 vector_add(&(*candidates)[i], copy);
0258
0259 return copy;
0260 }
0261
0262
0263 template <typename T, typename Collection>
0264 void PFBenchmarkAlgo::sortByDeltaR(const T *c1, Collection &candidates) {
0265 typedef typename Collection::value_type U;
0266
0267
0268 if (!c1)
0269 throw cms::Exception("Invalid Arg") << "attempted to sort by invalid Candidate";
0270 if (!candidates)
0271 throw cms::Exception("Invalid Arg") << "attempted to sort invalid Candidates";
0272
0273
0274 vector_sort(candidates, deltaRSorter<T, U>(c1));
0275 }
0276
0277
0278 template <typename T, typename Collection>
0279 void PFBenchmarkAlgo::sortByDeltaEt(const T *c1, Collection &candidates) {
0280 typedef typename Collection::value_type U;
0281
0282
0283 if (!c1)
0284 throw cms::Exception("Invalid Arg") << "attempted to sort by invalid Candidate";
0285 if (!candidates)
0286 throw cms::Exception("Invalid Arg") << "attempted to sort invalid Candidates";
0287
0288
0289 vector_sort(candidates, deltaEtSorter<T, U>(c1));
0290 }
0291
0292
0293 template <typename T, typename Collection>
0294 Collection PFBenchmarkAlgo::findAllInCone(const T *c1, const Collection *candidates, double ConeSize) {
0295 typedef typename Collection::value_type U;
0296
0297
0298 if (!c1)
0299 throw cms::Exception("Invalid Arg") << "attempted to constrain to invalid Candidate";
0300 if (!candidates)
0301 throw cms::Exception("Invalid Arg") << "attempted to constrain invalid Collection";
0302 if (ConeSize <= 0)
0303 throw cms::Exception("Invalid Arg") << "zero or negative cone size specified";
0304
0305 Collection constrained;
0306
0307 for (unsigned int i = 0; i < candidates->size(); i++) {
0308 const U *c2 = &(*candidates)[i];
0309
0310
0311 double dR = deltaR(c1, c2);
0312 if (dR < ConeSize)
0313 vector_add(c2, constrained);
0314 }
0315
0316
0317 sortByDeltaR(c1, constrained);
0318 return constrained;
0319 }
0320
0321
0322 template <typename T, typename Collection>
0323 Collection PFBenchmarkAlgo::findAllInEtWindow(const T *c1, const Collection *candidates, double EtWindow) {
0324 typedef typename Collection::value_type U;
0325
0326
0327 if (!c1)
0328 throw cms::Exception("Invalid Arg") << "attempted to constrain to invalid Candidate";
0329 if (!candidates)
0330 throw cms::Exception("Invalid Arg") << "attempted to constrain invalid Collection";
0331 if (EtWindow <= 0)
0332 throw cms::Exception("Invalid Arg") << "zero or negative cone size specified";
0333
0334 Collection constrained;
0335
0336
0337
0338 for (unsigned int i = 0; i < candidates->size(); i++) {
0339 const U *c2 = &(*candidates)[i];
0340
0341
0342 double dEt = fabs(deltaEt(c1, c2));
0343 if (dEt < EtWindow)
0344 vector_add(c2, constrained);
0345 }
0346
0347
0348 sortByDeltaEt(c1, constrained);
0349 return constrained;
0350 }
0351
0352 #endif