CMS 3D CMS Logo

L1HPSPFTauEmulator.h
Go to the documentation of this file.
1 #ifndef L1HPSPFTAUEMULATOR_H
2 #define L1HPSPFTAUEMULATOR_H
3 
4 #include "ap_int.h"
5 #include "ap_fixed.h"
6 #include <iostream>
7 #include <vector>
8 #include <numeric>
9 #include <algorithm>
12 
13 namespace l1HPSPFTauEmu {
14 
15  //mapping the eta phi onto bits
16 
17  constexpr float etaphi_base = 720. / M_PI;
18  constexpr float dz_base = 0.05;
19  typedef l1ct::pt_t pt_t;
21 
22  typedef ap_int<13> detaphi_t;
23 
24  typedef ap_uint<20> detaphi2_t;
25  typedef ap_uint<5> count_t; //type for multiplicity
26  typedef ap_uint<3> type_t; //type for particle type
27  typedef l1ct::z0_t dz_t;
28 
29  class Particle : public l1ct::PuppiObj {
30  public:
33  };
34 
35  class Tau : public l1ct::Tau {
36  public:
37  ap_uint<5> seed_index;
42  };
43 
44  //constants
47 
51  const dz_t dzCut = 0.4 / dz_base;
53 
54  template <int W, int I, ap_q_mode _AP_Q, ap_o_mode _AP_O>
55  ap_ufixed<W, I> fp_abs(ap_fixed<W, I, _AP_Q, _AP_O> x) {
56  ap_ufixed<W, I> result;
57  if (x < 0) {
58  result = -x;
59  } else {
60  result = x;
61  }
62  return result;
63  }
64 
65  template <int W>
66  inline ap_uint<W> int_abs(ap_int<W> x) {
67  ap_uint<W> result;
68  if (x < 0) {
69  result = -x;
70  } else {
71  result = x;
72  }
73  return result;
74  }
75 
76  template <class inP>
77  inline bool is_charged(inP part) {
78  bool charge = false;
79  if ((part.pID == 0) || (part.pID == 1) || (part.pID == 4)) {
80  charge = true;
81  } else {
82  charge = false;
83  }
84  return charge;
85  }
86 
87  inline ap_uint<20> setSConeSize2(pt_t tpt) {
88  ap_ufixed<16, 14> total_pt = tpt * 4;
89  ap_uint<20> SignalConeSizeSquare;
90  if (total_pt < 115) {
91  SignalConeSizeSquare = 23 * 23;
92  } else if (total_pt < 120) {
93  SignalConeSizeSquare = 22 * 22;
94  } else if (total_pt < 126) {
95  SignalConeSizeSquare = 21 * 21;
96  } else if (total_pt < 132) {
97  SignalConeSizeSquare = 20 * 20;
98  } else if (total_pt < 139) {
99  SignalConeSizeSquare = 19 * 19;
100  } else if (total_pt < 147) {
101  SignalConeSizeSquare = 18 * 18;
102  } else if (total_pt < 156) {
103  SignalConeSizeSquare = 17 * 17;
104  } else if (total_pt < 166) {
105  SignalConeSizeSquare = 16 * 16;
106  } else if (total_pt < 178) {
107  SignalConeSizeSquare = 15 * 15;
108  } else if (total_pt < 191) {
109  SignalConeSizeSquare = 14 * 14;
110  } else if (total_pt < 206) {
111  SignalConeSizeSquare = 13 * 13;
112  } else if (total_pt < 224) {
113  SignalConeSizeSquare = 12 * 12;
114  } else {
115  SignalConeSizeSquare = 12 * 12;
116  }
117  return SignalConeSizeSquare;
118  }
119 
121  bool inCone = false;
122  detaphi2_t isoConeSize2 = isoConeSize * isoConeSize;
123 
124  if (part.hwPt != 0) {
125  detaphi_t deltaEta = part.hwEta - seed.hwEta;
126  detaphi_t deltaPhi = part.hwPhi - seed.hwPhi;
127  if ((deltaEta * deltaEta + deltaPhi * deltaPhi) < isoConeSize2) {
128  inCone = true;
129  } else {
130  inCone = false;
131  }
132  } else {
133  inCone = false;
134  }
135  return inCone;
136  }
137 
138  inline bool inSignalCone(
139  Particle part, Particle seed, const int track_count, ap_uint<20> cone2, pt_t& iso_pt, bool& isLead) {
140  //finds the signal cone candidates (including strip pt check
141 
142  bool isPotentialLead = false;
143 
144  isPotentialLead =
145  is_charged(part) && part.pID != 4 && part.hwPt > min_leadChargedPfCand_pt && int_abs(part.hwEta) < etaCutoff;
146 
147  //calculate the deta and dphi
148  bool inCone = false;
149 
150  if (part.hwPt != 0) {
151  detaphi_t deltaEta = part.hwEta - seed.hwEta;
152  detaphi_t deltaPhi = part.hwPhi - seed.hwPhi;
153  detaphi2_t deltaEta2 = deltaEta * deltaEta;
154  detaphi2_t deltaPhi2 = deltaPhi * deltaPhi;
155  dz_t deltaZ = 0;
156  if (part.tempZ0 && seed.tempZ0) {
157  deltaZ = part.tempZ0 - seed.tempZ0;
158  }
159 
160  if ((int_abs(deltaEta) < strip_eta) && (int_abs(deltaPhi) < strip_phi) && (part.pID == 3 || (part.pID == 1))) {
161  if (isPotentialLead) {
162  isLead = true;
163  }
164  inCone = true;
165 
166  } else if (((deltaEta2 + deltaPhi2) < cone2) && !((part.pID == 0) && (track_count > 3)) &&
167  !(is_charged(part) && int_abs(deltaZ) > dzCut)) {
168  if (isPotentialLead) {
169  isLead = true;
170  }
171  inCone = true;
172  } else {
173  if (is_charged(part) && int_abs(deltaZ) > dzCut) {
174  iso_pt += part.hwPt;
175  inCone = false;
176  }
177  }
178  }
179  return inCone;
180  }
181 
182  inline Tau makeHPSTauHW(const std::vector<Particle>& parts,
183  const Particle seed,
184  const pt_t total_pt /*, Config config*/) {
185  using namespace l1HPSPFTauEmu;
186 
187  ap_uint<20> scone2 = setSConeSize2(total_pt);
188 
189  pt_t isocone_pt = 0;
190 
191  pt_t sum_pt = 0;
192 
193  ap_fixed<22, 20> sum_eta = 0;
194  ap_fixed<22, 20> sum_phi = 0;
195 
196  pt_t tau_pt = 0;
197  etaphi_t tau_eta = 0;
198  etaphi_t tau_phi = 0;
199 
200  pt_t chargedIsoPileup = 0;
201  std::vector<Particle> signalParts;
202  std::vector<Particle> outsideParts;
203 
204  int trct = 0;
205  bool leadCand = false;
206  bool leadSet = false;
207  Particle lead;
208  for (std::vector<int>::size_type i = 0; i != parts.size(); i++) {
209  bool isSignal = inSignalCone(parts.at(i), seed, trct, scone2, isocone_pt, leadCand);
210  if (isSignal) {
211  signalParts.push_back(parts.at(i));
212  if (parts[i].pID == 0) {
213  trct++;
214  }
215  if (leadCand) {
216  if (leadSet == false) {
217  lead = parts[i];
218  leadCand = false;
219  leadSet = true;
220  } else {
221  if (parts[i].hwPt > lead.hwPt) {
222  lead = parts[i];
223  leadCand = false;
224  } else {
225  leadCand = false;
226  }
227  }
228  }
229  } else {
230  outsideParts.push_back(parts.at(i));
231  }
232  }
233 
234  for (std::vector<int>::size_type i = 0; i != signalParts.size(); i++) {
235  Particle sigP = signalParts.at(i);
236  if (is_charged(sigP) || (sigP.pID == 3)) {
237  sum_pt += sigP.hwPt;
238  sum_eta += sigP.hwPt * sigP.hwEta;
239  sum_phi += sigP.hwPt * sigP.hwPhi;
240  }
241  }
242 
243  pt_t div_pt = 1;
244  if (sum_pt == 0) {
245  div_pt = 1;
246  } else {
247  div_pt = sum_pt;
248  }
249 
250  tau_pt = sum_pt;
251  tau_eta = sum_eta / div_pt;
252  tau_phi = sum_phi / div_pt;
253 
254  if (tau_pt > l1ct::Scales::makePtFromFloat(20.) && int_abs(tau_eta) < etaCutoff && leadSet == true &&
255  isocone_pt < tau_pt) {
256  Tau tau;
257  tau.hwPt = tau_pt;
258  tau.hwEta = tau_eta;
259  tau.hwPhi = tau_phi;
260  return tau;
261  } else {
262  Tau tau;
263  tau.hwPt = 0.;
264  tau.hwEta = 0.;
265  tau.hwPhi = 0.;
266  return tau;
267  }
268  }
269 
270  inline std::vector<Tau> emulateEvent(std::vector<Particle>& parts, std::vector<Particle>& jets, bool jEnable) {
271  using namespace l1HPSPFTauEmu;
272 
273  std::vector<Particle> parts_copy;
274  parts_copy.resize(parts.size());
275  std::transform(parts.begin(), parts.end(), parts_copy.begin(), [](const Particle& part) { return part; });
276  //sorting by pt
277  std::sort(
278  parts_copy.begin(), parts_copy.end(), [](const Particle& i, const Particle& j) { return (i.hwPt > j.hwPt); });
279 
280  //sorting jets by pt
281  std::vector<Particle> jets_copy;
282  jets_copy.resize(jets.size());
283  std::transform(jets.begin(), jets.end(), jets_copy.begin(), [](const Particle& jet) { return jet; });
284  std::sort(
285  jets_copy.begin(), jets_copy.end(), [](const Particle& i, const Particle& j) { return (i.hwPt > j.hwPt); });
286 
287  std::vector<Tau> taus;
288  std::vector<Tau> cleaned_taus;
289  taus.reserve(20);
290  std::vector<Particle> preseed;
291  preseed.reserve(144);
292 
293  //jet seeds reserve
294  //4 for now
295  int jets_index = 0;
296  int jets_max = jets_copy.size();
297 
298  std::vector<Particle> jseeds;
299  jseeds.reserve(4);
300 
301  int parts_index = 0;
302  int parts_max = parts_copy.size();
303  //first find the seeds
304  while (preseed.size() < 128 && parts_index != parts_max) {
305  Particle pSeed = parts_copy.at(parts_index);
306 
307  if (pSeed.hwPt > l1ct::Scales::makePtFromFloat(5.) && is_charged(pSeed) && int_abs(pSeed.hwEta) < etaCutoff) {
308  preseed.push_back(pSeed);
309  }
310 
311  parts_index++;
312  }
313 
314  std::vector<Particle> seeds;
315  seeds.reserve(16); //up to 16 track + 4 jet seeds right now
316  std::vector<int>::size_type pseed_index = 0;
317  while (seeds.size() < 16 && pseed_index < preseed.size()) {
318  seeds.push_back(preseed.at(pseed_index));
319  pseed_index++;
320  }
321 
322  //With jets
323  if (jEnable) {
324  while (jseeds.size() < 4 && jets_index != jets_max) {
325  Particle jSeed = jets_copy.at(jets_index);
326 
327  if (jSeed.hwPt > l1ct::Scales::makePtFromFloat(20.) && int_abs(jSeed.hwEta) < etaCutoff) {
328  jseeds.push_back(jSeed);
329  }
330  jets_index++;
331  }
332  }
333  for (std::vector<int>::size_type i = 0; i != seeds.size(); i++) {
334  Particle seed = seeds[i];
335 
336  std::vector<Particle> iso_parts;
337 
338  iso_parts.reserve(30);
339  pt_t total_pt = 0;
340  std::vector<int>::size_type iso_index = 0;
341  while (iso_index < parts_copy.size() && iso_parts.size() < 30) {
342  Particle isoCand = parts_copy.at(iso_index);
343  if (inIsolationCone(isoCand, seed)) {
344  iso_parts.push_back(isoCand);
345  total_pt += isoCand.hwPt;
346  }
347  iso_index++;
348  }
349 
350  taus.push_back(makeHPSTauHW(iso_parts, seed, total_pt));
351  }
352 
353  //add in the jet taus
354  if (jEnable) {
355  for (std::vector<int>::size_type i = 0; i != jseeds.size(); i++) {
356  Particle jseed = jseeds[i];
357  std::vector<Particle> iso_parts;
358  iso_parts.reserve(30);
359  pt_t total_pt = 0;
360  std::vector<int>::size_type iso_index = 0;
361 
362  pt_t max_pt_j = 0;
363  while (iso_index < parts_copy.size()) {
364  Particle isoCand = parts_copy.at(iso_index);
365 
366  if (inIsolationCone(isoCand, jseed)) {
367  if (is_charged(isoCand) && isoCand.hwPt > max_pt_j) {
368  if (isoCand.tempZ0) {
369  jseed.tempZ0 = isoCand.tempZ0;
370  }
371  max_pt_j = isoCand.hwPt;
372  }
373 
374  if (iso_parts.size() < 30) {
375  iso_parts.push_back(isoCand);
376  total_pt += isoCand.hwPt;
377  }
378  }
379  iso_index++;
380  }
381  taus.push_back(makeHPSTauHW(iso_parts, jseed, total_pt));
382  }
383  }
384 
385  std::sort(taus.begin(), taus.end(), [](const Tau& i, const Tau& j) { return (i.hwPt > j.hwPt); });
386 
387  int taus_max = taus.size();
388 
389  bool matrix[380];
390 
391  for (int i = 0; i < (taus_max - 1); i++) {
392  for (int j = i + 1; j < taus_max; j++) {
393  etaphi_t deltaE = taus[i].hwEta - taus[j].hwEta;
394  etaphi_t deltaP = taus[i].hwPhi - taus[j].hwPhi;
395  if ((deltaE * deltaE + deltaP * deltaP) < (delta_Rclean * delta_Rclean)) {
396  matrix[i * 19 + j] = true;
397  } else {
398  matrix[i * 19 + j] = false;
399  }
400  }
401  }
402 
403  if (!taus.empty()) {
404  if (taus[0].hwPt > 0) {
405  cleaned_taus.push_back(taus.at(0));
406  }
407 
408  bool clean[20];
409 
410  for (int i = 0; i < 20; i++) {
411  clean[i] = false;
412  }
413  for (int i = 1; i < taus_max; i++) {
414  for (int j = i - 1; j >= 0; j--) {
415  clean[i] |= (matrix[j * 19 + i] && !clean[j]);
416  }
417  if (!clean[i] && taus[i].hwPt > 0) {
418  cleaned_taus.push_back(taus.at(i));
419  }
420  }
421  }
422 
423  return cleaned_taus;
424  }
425 
426 }; // namespace l1HPSPFTauEmu
427 
428 #endif
Tau makeHPSTauHW(const std::vector< Particle > &parts, const Particle seed, const pt_t total_pt)
bool is_charged(inP part)
const detaphi_t strip_eta
const pt_t min_leadChargedPfCand_pt
const detaphi_t delta_Rclean
const detaphi_t isoConeSize
pt_t makePtFromFloat(float pt)
Definition: datatypes.h:183
std::vector< Tau > emulateEvent(std::vector< Particle > &parts, std::vector< Particle > &jets, bool jEnable)
uint16_t size_type
InputIterator leadCand(InputIterator begin, InputIterator end)
static const double deltaEta
Definition: CaloConstants.h:8
ap_uint< W > int_abs(ap_int< W > x)
bool inSignalCone(Particle part, Particle seed, const int track_count, ap_uint< 20 > cone2, pt_t &iso_pt, bool &isLead)
static void clean(char *s)
const etaphi_t etaCutoff
ap_int< 13 > detaphi_t
bool inIsolationCone(Particle part, Particle seed)
glbeta_t hwEta
Definition: puppi.h:13
const detaphi_t strip_phi
ap_uint< 3 > type_t
ap_uint< 5 > count_t
glbphi_t hwPhi
Definition: puppi.h:14
ap_uint< 20 > detaphi2_t
ap_int< 10 > z0_t
Definition: datatypes.h:21
#define M_PI
Definition: taus.h:10
Definition: Tau.py:1
ap_ufixed< 14, 12, AP_TRN, AP_SAT > pt_t
Definition: datatypes.h:10
l1ct::glbeta_t etaphi_t
part
Definition: HCALResponse.h:20
pt_t hwPt
Definition: puppi.h:12
ap_uint< 20 > setSConeSize2(pt_t tpt)
float x
bool inCone(l1t::PFCandidate seed, l1t::PFCandidate part, detaphi_t cone2)
Definition: TauNNIdHW.h:123
ap_ufixed< W, I > fp_abs(ap_fixed< W, I, _AP_Q, _AP_O > x)
constexpr float dz_base
ap_int< 12 > glbeta_t
Definition: datatypes.h:18
constexpr float etaphi_base
unsigned transform(const HcalDetId &id, unsigned transformCode)