CMS 3D CMS Logo

List of all members | Public Member Functions | Private Attributes
AngleCalculation Class Reference

#include <AngleCalculation.h>

Public Member Functions

void calculate_angles (EMTFTrack &track, const int izone) const
 
void calculate_bx (EMTFTrack &track) const
 
void configure (int verbose, int endcap, int sector, int bx, int bxWindow, int thetaWindow, int thetaWindowZone0, bool bugME11Dupes, bool bugAmbigThetaWin, bool twoStationSameBX)
 
void erase_tracks (EMTFTrackCollection &tracks) const
 
void process (emtf::zone_array< EMTFTrackCollection > &zone_tracks) const
 

Private Attributes

bool bugAmbigThetaWin_
 
bool bugME11Dupes_
 
int bx_
 
int bxWindow_
 
int endcap_
 
int sector_
 
int thetaWindow_
 
int thetaWindowZone0_
 
bool twoStationSameBX_
 
int verbose_
 

Detailed Description

Definition at line 6 of file AngleCalculation.h.

Member Function Documentation

void AngleCalculation::calculate_angles ( EMTFTrack track,
const int  izone 
) const

Definition at line 80 of file AngleCalculation.cc.

References a, funct::abs(), b, l1t::EMTFPtLUT::bt_ci, l1t::EMTFPtLUT::bt_hi, l1t::EMTFPtLUT::bt_si, l1t::EMTFPtLUT::bt_vi, bugAmbigThetaWin_, bugME11Dupes_, emtf::calc_eta_from_theta_deg(), emtf::calc_phi_glob_deg(), emtf::calc_phi_loc_deg(), emtf::calc_theta_deg_from_int(), relativeConstraints::chamber, l1t::EMTFTrack::clear_Hits(), l1t::EMTFPtLUT::cpattern, l1t::EMTFPtLUT::delta_ph, l1t::EMTFPtLUT::delta_th, l1t::EMTFTrack::Endcap(), l1t::EMTFPtLUT::fr, l1t::EMTFTrack::Hits(), mps_fire::i, L1TMuon::TriggerPrimitive::kGEM, ALCARECOPromptCalibProdSiPixelAli0T_cff::mode, emtf::NUM_STATION_PAIRS, emtf::NUM_STATIONS, l1t::EMTFTrack::Phi_loc(), l1t::EMTFTrack::Rank(), mps_fire::result, relativeConstraints::ring, l1t::EMTFTrack::Sector(), l1t::EMTFTrack::set_eta(), l1t::EMTFTrack::set_Hits(), l1t::EMTFTrack::set_mode(), l1t::EMTFTrack::set_mode_inv(), l1t::EMTFTrack::set_phi_fp(), l1t::EMTFTrack::set_phi_glob(), l1t::EMTFTrack::set_phi_loc(), l1t::EMTFTrack::set_PtLUT(), l1t::EMTFTrack::set_rank(), l1t::EMTFTrack::set_theta(), l1t::EMTFTrack::set_theta_fp(), l1t::EMTFPtLUT::sign_ph, l1t::EMTFPtLUT::sign_th, l1t::EMTFPtLUT::st1_ring2, relativeConstraints::station, hcal2_dqm_sourceclient-live_cfg::subsystem, theta(), l1t::EMTFTrack::Theta(), thetaWindow_, thetaWindowZone0_, findQualityFiles::v, and testProducerWithPsetDescEmpty_cfi::x1.

Referenced by process().

80  {
81  // Group track hits by station
82  std::array<EMTFHitCollection, emtf::NUM_STATIONS> st_conv_hits;
83 
84  for (int istation = 0; istation < emtf::NUM_STATIONS; ++istation) {
85  for (const auto& conv_hit : track.Hits()) {
86  if ((conv_hit.Station() - 1) == istation) {
87  st_conv_hits.at(istation).push_back(conv_hit);
88  }
89  }
90 
91  if (bugME11Dupes_) {
92  if (not(st_conv_hits.at(istation).size() <= 4)) // ambiguity in theta is max 4
93  {
94  edm::LogError("L1T") << "st_conv_hits.at(istation).size() = " << st_conv_hits.at(istation).size();
95  return;
96  }
97  } else {
98  if (not(st_conv_hits.at(istation).size() <= 2)) // ambiguity in theta is max 2
99  {
100  edm::LogError("L1T") << "st_conv_hits.at(istation).size() = " << st_conv_hits.at(istation).size();
101  return;
102  }
103  }
104  }
105  if (not(st_conv_hits.size() == emtf::NUM_STATIONS)) {
106  edm::LogError("L1T") << "st_conv_hits.size() = " << st_conv_hits.size()
107  << ", emtf::NUM_STATIONS = " << emtf::NUM_STATIONS;
108  return;
109  }
110 
111  // Best theta deltas and phi deltas
112  // from 0 to 5: dtheta12, dtheta13, dtheta14, dtheta23, dtheta24, dtheta34
113  std::array<int, emtf::NUM_STATION_PAIRS>
114  best_dtheta_arr; // Best of up to 4 dTheta values per pair of stations (with duplicate thetas)
115  std::array<int, emtf::NUM_STATION_PAIRS> best_dtheta_sign_arr;
116  std::array<int, emtf::NUM_STATION_PAIRS>
117  best_dphi_arr; // Not really "best" - there is only one dPhi value per pair of stations
118  std::array<int, emtf::NUM_STATION_PAIRS> best_dphi_sign_arr;
119 
120  // Best angles
121  // from 0 to 5: ME2, ME3, ME4, ME2, ME2, ME3
122  // dtheta12, dtheta13, dtheta14, dtheta23, dtheta24, dtheta34
123  std::array<int, emtf::NUM_STATION_PAIRS> best_theta_arr;
124  std::array<int, emtf::NUM_STATION_PAIRS> best_phi_arr;
125 
126  // Keep track of which pair is valid
127  std::array<bool, emtf::NUM_STATION_PAIRS> best_dtheta_valid_arr;
128  // std::array<bool, emtf::NUM_STATION_PAIRS> best_has_rpc_arr; // Not used currently
129 
130  // Initialize
131  best_dtheta_arr.fill(invalid_dtheta);
132  best_dtheta_sign_arr.fill(1);
133  best_dphi_arr.fill(invalid_dphi);
134  best_dphi_sign_arr.fill(1);
135  best_phi_arr.fill(0);
136  best_theta_arr.fill(0);
137  best_dtheta_valid_arr.fill(false);
138  // best_has_rpc_arr .fill(false);
139 
140  auto abs_diff = [](int a, int b) { return std::abs(a - b); };
141 
142  // Calculate angles
143  int ipair = 0;
144 
145  for (int ist1 = 0; ist1 + 1 < emtf::NUM_STATIONS; ++ist1) { // station A
146  for (int ist2 = ist1 + 1; ist2 < emtf::NUM_STATIONS; ++ist2) { // station B
147  const EMTFHitCollection& conv_hitsA = st_conv_hits.at(ist1);
148  const EMTFHitCollection& conv_hitsB = st_conv_hits.at(ist2);
149 
150  // More than 1 hit per station when hit has ambigous theta
151  for (const auto& conv_hitA : conv_hitsA) {
152  for (const auto& conv_hitB : conv_hitsB) {
153  // bool has_rpc = (conv_hitA.Subsystem() == TriggerPrimitive::kRPC || conv_hitB.Subsystem() == TriggerPrimitive::kRPC);
154 
155  // Calculate theta deltas
156  int thA = conv_hitA.Theta_fp();
157  int thB = conv_hitB.Theta_fp();
158  int dth = abs_diff(thA, thB);
159  int dth_sign = (thA <= thB); // sign
160  if (not(thA != 0 && thB != 0)) {
161  edm::LogError("L1T") << "thA = " << thA << ", thB = " << thB;
162  return;
163  }
164  if (not(dth < invalid_dtheta)) {
165  edm::LogError("L1T") << "dth = " << dth << ", invalid_dtheta = " << invalid_dtheta;
166  return;
167  }
168 
169  if (best_dtheta_arr.at(ipair) >= dth) {
170  best_dtheta_arr.at(ipair) = dth;
171  best_dtheta_sign_arr.at(ipair) = dth_sign;
172  best_dtheta_valid_arr.at(ipair) = true;
173  // best_has_rpc_arr.at(ipair) = has_rpc; // FW doesn't currently check whether a segment is CSC or RPC
174 
175  // first 3 pairs, use station B
176  // last 3 pairs, use station A
177  best_theta_arr.at(ipair) = (ipair < 3) ? thB : thA;
178  }
179 
180  // Calculate phi deltas
181  int phA = conv_hitA.Phi_fp();
182  int phB = conv_hitB.Phi_fp();
183  int dph = abs_diff(phA, phB);
184  int dph_sign = (phA <= phB);
185 
186  if (best_dphi_arr.at(ipair) >= dph) {
187  best_dphi_arr.at(ipair) = dph;
188  best_dphi_sign_arr.at(ipair) = dph_sign;
189 
190  // first 3 pairs, use station B
191  // last 3 pairs, use station A
192  best_phi_arr.at(ipair) = (ipair < 3) ? phB : phA;
193  }
194  } // end loop over conv_hits in station B
195  } // end loop over conv_hits in station A
196 
197  ++ipair;
198  } // end loop over station B
199  } // end loop over station A
200  if (not(ipair == emtf::NUM_STATION_PAIRS)) {
201  edm::LogError("L1T") << "ipair = " << ipair << ", emtf::NUM_STATION_PAIRS = " << emtf::NUM_STATION_PAIRS;
202  return;
203  }
204 
205  // Apply cuts on dtheta
206 
207  // There is a possible bug in FW. After a dtheta pair fails the theta window
208  // cut, the valid flag of the pair is not updated. Later on, theta from
209  // this pair is used to assign the precise theta of the track.
210  std::array<bool, emtf::NUM_STATION_PAIRS> best_dtheta_valid_arr_1;
211 
212  for (int ipair = 0; ipair < emtf::NUM_STATION_PAIRS; ++ipair) {
213  if (izone == 0) // Tighter theta window for Zone 0 (Ring 1), where there are no RPCs
214  best_dtheta_valid_arr_1.at(ipair) =
215  best_dtheta_valid_arr.at(ipair) && (best_dtheta_arr.at(ipair) <= thetaWindowZone0_);
216  else
217  best_dtheta_valid_arr_1.at(ipair) =
218  best_dtheta_valid_arr.at(ipair) && (best_dtheta_arr.at(ipair) <= thetaWindow_);
219  }
220 
221  // Find valid segments
222  // vmask contains valid station mask = {ME4,ME3,ME2,ME1}. "0b" prefix for binary.
223  int vmask1 = 0, vmask2 = 0, vmask3 = 0;
224 
225  if (best_dtheta_valid_arr_1.at(0)) {
226  vmask1 |= 0b0011; // 12
227  }
228  if (best_dtheta_valid_arr_1.at(1)) {
229  vmask1 |= 0b0101; // 13
230  }
231  if (best_dtheta_valid_arr_1.at(2)) {
232  vmask1 |= 0b1001; // 14
233  }
234  if (best_dtheta_valid_arr_1.at(3)) {
235  vmask2 |= 0b0110; // 23
236  }
237  if (best_dtheta_valid_arr_1.at(4)) {
238  vmask2 |= 0b1010; // 24
239  }
240  if (best_dtheta_valid_arr_1.at(5)) {
241  vmask3 |= 0b1100; // 34
242  }
243 
244  // merge station masks only if they share bits
245  // Station 1 hits pass if any dTheta1X values pass
246  // Station 2 hits pass if any dTheta2X values pass, *EXCEPT* the following cases:
247  // Only {13, 24} pass, only {13, 24, 34} pass,
248  // Only {14, 23} pass, only {14, 23, 34} pass.
249  // Station 3 hits pass if any dTheta3X values pass, *EXCEPT* the following cases:
250  // Only {12, 34} pass, only {14, 23} pass.
251  // Station 4 hits pass if any dTheta4X values pass, *EXCEPT* the following cases:
252  // Only {12, 34} pass, only {13, 24} pass.
253  int vstat = vmask1; // valid stations based on th coordinates
254  if ((vstat & vmask2) != 0 || vstat == 0)
255  vstat |= vmask2;
256  if ((vstat & vmask3) != 0 || vstat == 0)
257  vstat |= vmask3;
258 
259  // Truth table to remove ambiguity in passing the dTheta window cut when there are
260  // two LCTs in the same station with the same phi value, but different theta values
261  static const int trk_bld[64] = {
262  0b1111, 0b0111, 0b0111, 0b0111, 0b1011, 0b0011, 0b1110, 0b0011, 0b0111, 0b0111, 0b0111, 0b0111, 0b1011,
263  0b0011, 0b0011, 0b0011, 0b1011, 0b1101, 0b0011, 0b0011, 0b1011, 0b0011, 0b0011, 0b0011, 0b1011, 0b0011,
264  0b0011, 0b0011, 0b1011, 0b0011, 0b0011, 0b0011, 0b1101, 0b1101, 0b1110, 0b0101, 0b1110, 0b1001, 0b1110,
265  0b0110, 0b0101, 0b0101, 0b0101, 0b0101, 0b1001, 0b1001, 0b0110, 0b0110, 0b1101, 0b1101, 0b0101, 0b0101,
266  0b1001, 0b1001, 0b1010, 0b1100, 0b0101, 0b0101, 0b0101, 0b0101, 0b1001, 0b1001, 0b1010, 0b0000};
267 
268  if (not bugAmbigThetaWin_) { // Fixed at the beginning of 2018
269  // construct bad delta word
270  // dth_bad = {12,23,34,13,14,24}
271  unsigned dth_bad = 0b111111; // "1" is bad. if valid, change to "0" (good)
272  if (best_dtheta_valid_arr_1.at(0)) {
273  dth_bad &= (~(1 << 5)); // 12
274  }
275  if (best_dtheta_valid_arr_1.at(1)) {
276  dth_bad &= (~(1 << 2)); // 13
277  }
278  if (best_dtheta_valid_arr_1.at(2)) {
279  dth_bad &= (~(1 << 1)); // 14
280  }
281  if (best_dtheta_valid_arr_1.at(3)) {
282  dth_bad &= (~(1 << 4)); // 23
283  }
284  if (best_dtheta_valid_arr_1.at(4)) {
285  dth_bad &= (~(1 << 0)); // 24
286  }
287  if (best_dtheta_valid_arr_1.at(5)) {
288  dth_bad &= (~(1 << 3)); // 34
289  }
290  assert(dth_bad < 64);
291 
292  // extract station mask from LUT
293  vstat = trk_bld[dth_bad];
294  }
295 
296  // remove valid flag for station if hit does not pass the dTheta mask
297  for (int istation = 0; istation < emtf::NUM_STATIONS; ++istation) {
298  if ((vstat & (1 << istation)) == 0) { // station bit not set
299  st_conv_hits.at(istation).clear();
300  }
301  }
302 
303  // assign precise phi and theta for the track
304  int phi_fp = 0;
305  int theta_fp = 0;
306  int best_pair = -1;
307 
308  if ((vstat & (1 << 1)) != 0) { // ME2 present
309  if (best_dtheta_valid_arr.at(0)) // 12
310  best_pair = 0;
311  else if (best_dtheta_valid_arr.at(3)) // 23
312  best_pair = 3;
313  else if (best_dtheta_valid_arr.at(4)) // 24
314  best_pair = 4;
315  } else if ((vstat & (1 << 2)) != 0) { // ME3 present
316  if (best_dtheta_valid_arr.at(1)) // 13
317  best_pair = 1;
318  else if (best_dtheta_valid_arr.at(5)) // 34
319  best_pair = 5;
320  } else if ((vstat & (1 << 3)) != 0) { // ME4 present
321  if (best_dtheta_valid_arr.at(2)) // 14
322  best_pair = 2;
323  }
324 
325  // // Possible logic preferring CSC LCTs for the track theta and phi assignment
326  // if ((vstat & (1<<1)) != 0) { // ME2 present
327  // if (!best_has_rpc_arr.at(0) && best_dtheta_valid_arr.at(0)) // 12, no RPC
328  // best_pair = 0;
329  // else if (!best_has_rpc_arr.at(3) && best_dtheta_valid_arr.at(3)) // 23, no RPC
330  // best_pair = 3;
331  // else if (!best_has_rpc_arr.at(4) && best_dtheta_valid_arr.at(4)) // 24, no RPC
332  // best_pair = 4;
333  // else if (best_dtheta_valid_arr.at(0)) // 12, has RPC
334  // best_pair = 0;
335  // else if (best_dtheta_valid_arr.at(3)) // 23, has RPC
336  // best_pair = 3;
337  // else if (best_dtheta_valid_arr.at(4)) // 24, has RPC
338  // best_pair = 4;
339  // } else if ((vstat & (1<<2)) != 0) { // ME3 present
340  // if (!best_has_rpc_arr.at(1) && best_dtheta_valid_arr.at(1)) // 13, no RPC
341  // best_pair = 1;
342  // else if (!best_has_rpc_arr.at(5) && best_dtheta_valid_arr.at(5)) // 34, no RPC
343  // best_pair = 5;
344  // else if (best_dtheta_valid_arr.at(1)) // 13, has RPC
345  // best_pair = 1;
346  // else if (best_dtheta_valid_arr.at(5)) // 34, has RPC
347  // best_pair = 5;
348  // } else if ((vstat & (1<<3)) != 0) { // ME4 present
349  // if (best_dtheta_valid_arr.at(2)) // 14
350  // best_pair = 2;
351  // }
352 
353  if (best_pair != -1) {
354  phi_fp = best_phi_arr.at(best_pair);
355  theta_fp = best_theta_arr.at(best_pair);
356  if (not(theta_fp != 0)) {
357  edm::LogError("L1T") << "theta_fp = " << theta_fp;
358  return;
359  }
360 
361  // In firmware, the track is associated to LCTs by the segment number, which
362  // identifies the best strip, but does not resolve the ambiguity in theta.
363  // In emulator, this additional logic also resolves the ambiguity in theta.
364  struct {
365  typedef EMTFHit value_type;
366  bool operator()(const value_type& lhs, const value_type& rhs) const {
367  return std::abs(lhs.Theta_fp() - theta) < std::abs(rhs.Theta_fp() - theta);
368  }
369  int theta;
370  } less_dtheta_cmp;
371  less_dtheta_cmp.theta = theta_fp; // capture
372 
373  for (int istation = 0; istation < emtf::NUM_STATIONS; ++istation) {
374  std::stable_sort(st_conv_hits.at(istation).begin(), st_conv_hits.at(istation).end(), less_dtheta_cmp);
375  if (st_conv_hits.at(istation).size() > 1)
376  st_conv_hits.at(istation).resize(1); // just the minimum in dtheta
377  }
378  }
379 
380  // update rank taking into account available stations after theta deltas
381  // keep straightness as it was
382  int old_rank = (track.Rank() << 1); // output rank is one bit longer than input rank, to accomodate ME4 separately
383  int rank = ((((old_rank >> 6) & 1) << 6) | // straightness
384  (((old_rank >> 4) & 1) << 4) | // straightness
385  (((old_rank >> 2) & 1) << 2) | // straightness
386  (((vstat >> 0) & 1) << 5) | // ME1
387  (((vstat >> 1) & 1) << 3) | // ME2
388  (((vstat >> 2) & 1) << 1) | // ME3
389  (((vstat >> 3) & 1) << 0) // ME4
390  );
391 
392  int mode = ((((vstat >> 0) & 1) << 3) | // ME1
393  (((vstat >> 1) & 1) << 2) | // ME2
394  (((vstat >> 2) & 1) << 1) | // ME3
395  (((vstat >> 3) & 1) << 0) // ME4
396  );
397 
398  int mode_inv = vstat;
399 
400  // if less than 2 segments, kill rank
401  if (vstat == 0b0001 || vstat == 0b0010 || vstat == 0b0100 || vstat == 0b1000 || vstat == 0)
402  rank = 0;
403 
404  // From RecoMuon/DetLayers/src/MuonCSCDetLayerGeometryBuilder.cc
405  auto isFront = [](int station, int ring, int chamber, int subsystem) {
406  // // RPCs are behind the CSCs in stations 1, 3, and 4; in front in 2
407  // if (subsystem == TriggerPrimitive::kRPC)
408  // return (station == 2);
409 
410  // In EMTF firmware, RPC hits are treated as if they came from the corresponding
411  // CSC chamber, so the FR bit assignment is the same as for CSCs - AWB 06.06.17
412 
413  // GEMs are in front of the CSCs
415  return true;
416 
417  bool result = false;
418  bool isOverlapping = !(station == 1 && ring == 3);
419  // not overlapping means back
420  if (isOverlapping) {
421  bool isEven = (chamber % 2 == 0);
422  // odd chambers are bolted to the iron, which faces
423  // forward in 1&2, backward in 3&4, so...
424  result = (station < 3) ? isEven : !isEven;
425  }
426  return result;
427  };
428 
429  // Fill ptlut_data
430  EMTFPtLUT ptlut_data = {};
431  for (int i = 0; i < emtf::NUM_STATION_PAIRS; ++i) {
432  ptlut_data.delta_ph[i] = best_dphi_arr.at(i);
433  ptlut_data.sign_ph[i] = best_dphi_sign_arr.at(i);
434  ptlut_data.delta_th[i] = best_dtheta_arr.at(i);
435  ptlut_data.sign_th[i] = best_dtheta_sign_arr.at(i);
436  }
437 
438  for (int i = 0; i < emtf::NUM_STATIONS; ++i) {
439  const auto& v = st_conv_hits.at(i);
440  ptlut_data.cpattern[i] = v.empty() ? 0 : v.front().Pattern(); // Automatically set to 0 for RPCs
441  ptlut_data.fr[i] =
442  v.empty() ? 0 : isFront(v.front().Station(), v.front().Ring(), v.front().Chamber(), v.front().Subsystem());
443  if (i == 0)
444  ptlut_data.st1_ring2 =
445  v.empty() ? 0 : (v.front().Station() == 1 && (v.front().Ring() == 2 || v.front().Ring() == 3));
446  }
447 
448  for (int i = 0; i < emtf::NUM_STATIONS + 1; ++i) { // 'bt' arrays use 5-station convention
449  ptlut_data.bt_vi[i] = 0;
450  ptlut_data.bt_hi[i] = 0;
451  ptlut_data.bt_ci[i] = 0;
452  ptlut_data.bt_si[i] = 0;
453  }
454 
455  for (int i = 0; i < emtf::NUM_STATIONS; ++i) {
456  const auto& v = st_conv_hits.at(i);
457  if (!v.empty()) {
458  int bt_station = v.front().BT_station();
459  if (not(0 <= bt_station && bt_station <= 4)) {
460  edm::LogError("L1T") << "bt_station = " << bt_station;
461  return;
462  }
463 
464  int bt_segment = v.front().BT_segment();
465  ptlut_data.bt_vi[bt_station] = 1;
466  ptlut_data.bt_hi[bt_station] = (bt_segment >> 5) & 0x3;
467  ptlut_data.bt_ci[bt_station] = (bt_segment >> 1) & 0xf;
468  ptlut_data.bt_si[bt_station] = (bt_segment >> 0) & 0x1;
469  }
470  }
471 
472  // ___________________________________________________________________________
473  // Output
474 
475  track.set_rank(rank);
476  track.set_mode(mode);
477  track.set_mode_inv(mode_inv);
478  track.set_phi_fp(phi_fp);
479  track.set_theta_fp(theta_fp);
480  track.set_PtLUT(ptlut_data);
481 
482  track.set_phi_loc(emtf::calc_phi_loc_deg(phi_fp));
483  track.set_phi_glob(emtf::calc_phi_glob_deg(track.Phi_loc(), track.Sector()));
484  track.set_theta(emtf::calc_theta_deg_from_int(theta_fp));
485  track.set_eta(emtf::calc_eta_from_theta_deg(track.Theta(), track.Endcap()));
486 
487  // Only keep the best segments
488  track.clear_Hits();
489 
490  EMTFHitCollection tmp_hits = track.Hits();
491  flatten_container(st_conv_hits, tmp_hits);
492  track.set_Hits(tmp_hits);
493 }
void set_mode(int bits)
Definition: EMTFTrack.h:121
void clear_Hits()
Definition: EMTFTrack.h:77
float Theta() const
Definition: EMTFTrack.h:168
int NUM_STATION_PAIRS
Definition: Common.h:72
uint16_t bt_si[5]
Definition: EMTFTrack.h:31
uint16_t bt_ci[5]
Definition: EMTFTrack.h:30
uint16_t sign_ph[6]
Definition: EMTFTrack.h:24
int Endcap() const
Definition: EMTFTrack.h:148
void set_phi_fp(int bits)
Definition: EMTFTrack.h:137
int Sector() const
Definition: EMTFTrack.h:149
uint16_t bt_vi[5]
Definition: EMTFTrack.h:28
Geom::Theta< T > theta() const
double calc_phi_loc_deg(int bits)
Definition: TrackTools.h:165
l1t::EMTFHitCollection EMTFHitCollection
Definition: Common.h:25
uint16_t delta_ph[6]
Definition: EMTFTrack.h:22
void set_PtLUT(EMTFPtLUT bits)
Definition: EMTFTrack.h:115
uint16_t delta_th[6]
Definition: EMTFTrack.h:23
double calc_theta_deg_from_int(int theta_int)
Definition: TrackTools.h:117
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
uint16_t cpattern[4]
Definition: EMTFTrack.h:26
int NUM_STATIONS
Definition: Common.h:71
double calc_phi_glob_deg(double loc, int sector)
Definition: TrackTools.h:155
uint16_t fr[4]
Definition: EMTFTrack.h:27
void set_rank(int bits)
Definition: EMTFTrack.h:123
void set_theta_fp(int bits)
Definition: EMTFTrack.h:134
void set_eta(float val)
Definition: EMTFTrack.h:136
EMTFHitCollection Hits() const
Definition: EMTFTrack.h:107
float Phi_loc() const
Definition: EMTFTrack.h:171
void set_theta(float val)
Definition: EMTFTrack.h:135
uint16_t sign_th[6]
Definition: EMTFTrack.h:25
uint16_t st1_ring2
Definition: EMTFTrack.h:20
double b
Definition: hdecay.h:118
double calc_eta_from_theta_deg(double theta_deg, int endcap)
Definition: TrackTools.h:102
double a
Definition: hdecay.h:119
void set_Hits(const EMTFHitCollection &hits)
Definition: EMTFTrack.h:96
void set_phi_loc(float val)
Definition: EMTFTrack.h:138
void set_phi_glob(float val)
Definition: EMTFTrack.h:139
uint16_t bt_hi[5]
Definition: EMTFTrack.h:29
void set_mode_inv(int bits)
Definition: EMTFTrack.h:122
int Rank() const
Definition: EMTFTrack.h:156
void AngleCalculation::calculate_bx ( EMTFTrack track) const

Definition at line 495 of file AngleCalculation.cc.

References bx_, bxWindow_, counter, l1t::EMTFTrack::Hits(), mps_fire::i, l1t::EMTFTrack::set_first_bx(), and l1t::EMTFTrack::set_second_bx().

Referenced by process().

495  {
496  const int delayBX = bxWindow_ - 1;
497  if (not(delayBX >= 0)) {
498  edm::LogError("L1T") << "delayBX = " << delayBX;
499  return;
500  }
501  std::vector<int> counter(delayBX + 1, 0);
502 
503  for (const auto& conv_hit : track.Hits()) {
504  for (int i = delayBX; i >= 0; i--) {
505  if (conv_hit.BX() <= bx_ - i)
506  counter.at(i) += 1; // Count stubs delayed by i BX or more
507  }
508  }
509 
510  int first_bx = bx_ - delayBX;
511  int second_bx = 99;
512  for (int i = delayBX; i >= 0; i--) {
513  if (counter.at(i) >= 2) { // If 2 or more stubs are delayed by i BX or more
514  second_bx = bx_ - i; // if i == delayBX, analyze immediately
515  break;
516  }
517  }
518  if (not(second_bx != 99)) {
519  edm::LogError("L1T") << "second_bx = " << second_bx;
520  return;
521  }
522 
523  // ___________________________________________________________________________
524  // Output
525 
526  track.set_first_bx(first_bx);
527  track.set_second_bx(second_bx);
528 }
void set_second_bx(int bits)
Definition: EMTFTrack.h:128
void set_first_bx(int bits)
Definition: EMTFTrack.h:127
EMTFHitCollection Hits() const
Definition: EMTFTrack.h:107
static std::atomic< unsigned int > counter
void AngleCalculation::configure ( int  verbose,
int  endcap,
int  sector,
int  bx,
int  bxWindow,
int  thetaWindow,
int  thetaWindowZone0,
bool  bugME11Dupes,
bool  bugAmbigThetaWin,
bool  twoStationSameBX 
)

Definition at line 13 of file AngleCalculation.cc.

References bugAmbigThetaWin_, bugME11Dupes_, l1GtPatternGenerator_cfi::bx, bx_, bxWindow_, makeMuonMisalignmentScenario::endcap, endcap_, sector_, thetaWindow_, thetaWindowZone0_, twoStationSameBX_, verbose, and verbose_.

Referenced by SectorProcessor::process_single_bx().

22  {
23  verbose_ = verbose;
24  endcap_ = endcap;
25  sector_ = sector;
26  bx_ = bx;
27 
28  bxWindow_ = bxWindow;
29  thetaWindow_ = thetaWindow;
30  thetaWindowZone0_ = thetaWindowZone0;
31  bugME11Dupes_ = bugME11Dupes;
32  bugAmbigThetaWin_ = bugAmbigThetaWin;
33  twoStationSameBX_ = twoStationSameBX;
34 }
static int verbose
void AngleCalculation::erase_tracks ( EMTFTrackCollection tracks) const

Definition at line 530 of file AngleCalculation.cc.

References emtf::NUM_STATIONS, HLT_2018_cff::track, twoStationSameBX_, and x.

Referenced by process().

530  {
531  // Erase tracks with rank == 0
532  // using erase-remove idiom
533  struct {
534  typedef EMTFTrack value_type;
535  bool operator()(const value_type& x) const { return (x.Rank() == 0); }
536  } rank_zero_pred;
537 
538  // Erase two-station tracks with hits in different BX
539  struct {
540  typedef EMTFTrack value_type;
541  bool operator()(const value_type& x) const {
542  return (x.NumHits() == 2 && x.Hits().at(0).BX() != x.Hits().at(1).BX());
543  }
544  } two_station_mistime;
545 
546  tracks.erase(std::remove_if(tracks.begin(), tracks.end(), rank_zero_pred), tracks.end());
547 
548  if (twoStationSameBX_) { // Modified at the beginning of 2018
549  tracks.erase(std::remove_if(tracks.begin(), tracks.end(), two_station_mistime), tracks.end());
550  }
551 
552  for (const auto& track : tracks) {
553  if (not(!track.Hits().empty())) {
554  edm::LogError("L1T") << "track.Hits().empty() = " << track.Hits().empty();
555  return;
556  }
557  if (not(track.Hits().size() <= emtf::NUM_STATIONS)) {
558  edm::LogError("L1T") << "track.Hits().size() = " << track.Hits().size()
559  << ", emtf::NUM_STATIONS= " << emtf::NUM_STATIONS;
560  return;
561  }
562  }
563 }
int NUM_STATIONS
Definition: Common.h:71
void AngleCalculation::process ( emtf::zone_array< EMTFTrackCollection > &  zone_tracks) const

Definition at line 36 of file AngleCalculation.cc.

References calculate_angles(), calculate_bx(), gather_cfg::cout, erase_tracks(), emtf::NUM_ZONES, to_hex(), HLT_2018_cff::track, PDWG_EXOHSCP_cff::tracks, and verbose_.

Referenced by SectorProcessor::process_single_bx().

36  {
37  for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
38  EMTFTrackCollection& tracks = zone_tracks.at(izone); // pass by reference
39 
40  EMTFTrackCollection::iterator tracks_it = tracks.begin();
41  EMTFTrackCollection::iterator tracks_end = tracks.end();
42 
43  // Calculate deltas
44  for (; tracks_it != tracks_end; ++tracks_it) {
45  calculate_angles(*tracks_it, izone);
46  }
47 
48  // Erase tracks with rank = 0
49  // Erase hits that are not selected as the best phi and theta in each station
50  // Erase two-station tracks with hits in different BX (2018)
51  erase_tracks(tracks);
52 
53  tracks_it = tracks.begin();
54  tracks_end = tracks.end();
55 
56  // Calculate bx
57  // (in the firmware, this happens during best track selection.)
58  for (; tracks_it != tracks_end; ++tracks_it) {
59  calculate_bx(*tracks_it);
60  }
61  } // end loop over zones
62 
63  if (verbose_ > 0) { // debug
64  for (const auto& tracks : zone_tracks) {
65  for (const auto& track : tracks) {
66  std::cout << "deltas: z: " << track.Zone() - 1 << " pat: " << track.Winner()
67  << " rank: " << to_hex(track.Rank()) << " delta_ph: " << array_as_string(track.PtLUT().delta_ph)
68  << " delta_th: " << array_as_string(track.PtLUT().delta_th)
69  << " sign_ph: " << array_as_string(track.PtLUT().sign_ph)
70  << " sign_th: " << array_as_string(track.PtLUT().sign_th) << " phi: " << track.Phi_fp()
71  << " theta: " << track.Theta_fp() << " cpat: " << array_as_string(track.PtLUT().cpattern)
72  << " v: " << array_as_string(track.PtLUT().bt_vi) << " h: " << array_as_string(track.PtLUT().bt_hi)
73  << " c: " << array_as_string(track.PtLUT().bt_ci) << " s: " << array_as_string(track.PtLUT().bt_si)
74  << std::endl;
75  }
76  }
77  }
78 }
static char to_hex(unsigned int i)
Definition: types.cc:27
l1t::EMTFTrackCollection EMTFTrackCollection
Definition: Common.h:29
void calculate_bx(EMTFTrack &track) const
int NUM_ZONES
Definition: Common.h:67
void calculate_angles(EMTFTrack &track, const int izone) const
void erase_tracks(EMTFTrackCollection &tracks) const

Member Data Documentation

bool AngleCalculation::bugAmbigThetaWin_
private

Definition at line 32 of file AngleCalculation.h.

Referenced by calculate_angles(), and configure().

bool AngleCalculation::bugME11Dupes_
private

Definition at line 32 of file AngleCalculation.h.

Referenced by calculate_angles(), and configure().

int AngleCalculation::bx_
private

Definition at line 28 of file AngleCalculation.h.

Referenced by calculate_bx(), and configure().

int AngleCalculation::bxWindow_
private

Definition at line 30 of file AngleCalculation.h.

Referenced by calculate_bx(), and configure().

int AngleCalculation::endcap_
private

Definition at line 28 of file AngleCalculation.h.

Referenced by configure().

int AngleCalculation::sector_
private

Definition at line 28 of file AngleCalculation.h.

Referenced by configure().

int AngleCalculation::thetaWindow_
private

Definition at line 31 of file AngleCalculation.h.

Referenced by calculate_angles(), and configure().

int AngleCalculation::thetaWindowZone0_
private

Definition at line 31 of file AngleCalculation.h.

Referenced by calculate_angles(), and configure().

bool AngleCalculation::twoStationSameBX_
private

Definition at line 32 of file AngleCalculation.h.

Referenced by configure(), and erase_tracks().

int AngleCalculation::verbose_
private

Definition at line 28 of file AngleCalculation.h.

Referenced by configure(), and process().