CMS 3D CMS Logo

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