CMS 3D CMS Logo

PrimitiveConversion.cc
Go to the documentation of this file.
2 
9 
12 
13 
15  const GeometryTranslator* tp_geom,
16  const SectorProcessorLUT* lut,
17  int verbose, int endcap, int sector, int bx,
18  int bxShiftCSC, int bxShiftRPC, int bxShiftGEM,
19  const std::vector<int>& zoneBoundaries, int zoneOverlap,
20  bool duplicateTheta, bool fixZonePhi, bool useNewZones, bool fixME11Edges,
21  bool bugME11Dupes
22 ) {
23  if (not(tp_geom != nullptr))
24  { edm::LogError("L1T") << "tp_geom = " << tp_geom; return; }
25  if (not(lut != nullptr))
26  { edm::LogError("L1T") << "lut = " << lut; return; }
27 
28  tp_geom_ = tp_geom;
29  lut_ = lut;
30 
31  verbose_ = verbose;
32  endcap_ = endcap; // 1 for ME+, 2 for ME-
33  sector_ = sector;
34  bx_ = bx;
35 
36  bxShiftCSC_ = bxShiftCSC;
37  bxShiftRPC_ = bxShiftRPC;
38  bxShiftGEM_ = bxShiftGEM;
39 
40  zoneBoundaries_ = zoneBoundaries;
41  zoneOverlap_ = zoneOverlap;
42  duplicateTheta_ = duplicateTheta;
43  fixZonePhi_ = fixZonePhi;
44  useNewZones_ = useNewZones;
45  fixME11Edges_ = fixME11Edges;
46  bugME11Dupes_ = bugME11Dupes;
47 }
48 
50  const std::map<int, TriggerPrimitiveCollection>& selected_prim_map,
51  EMTFHitCollection& conv_hits
52 ) const {
53  std::map<int, TriggerPrimitiveCollection>::const_iterator map_tp_it = selected_prim_map.begin();
54  std::map<int, TriggerPrimitiveCollection>::const_iterator map_tp_end = selected_prim_map.end();
55 
56  for (; map_tp_it != map_tp_end; ++map_tp_it) {
57  // Unique chamber ID in FW, {0, 53} as defined in get_index_csc in src/PrimitiveSelection.cc
58  int selected = map_tp_it->first;
59  // "Primitive Conversion" sector/station/chamber ID scheme used in FW
60  int pc_sector = sector_;
61  int pc_station = selected / 9; // {0, 5} = {ME1 sub 1, ME1 sub 2, ME2, ME3, ME4, neighbor}
62  int pc_chamber = selected % 9; // Equals CSC ID - 1 for all except neighbor chambers
63  int pc_segment = 0; // Counts hits in a single chamber
64 
65  TriggerPrimitiveCollection::const_iterator tp_it = map_tp_it->second.begin();
66  TriggerPrimitiveCollection::const_iterator tp_end = map_tp_it->second.end();
67 
68  for (; tp_it != tp_end; ++tp_it) {
69  EMTFHit conv_hit;
70  if (tp_it->subsystem() == TriggerPrimitive::kCSC) {
71  convert_csc(pc_sector, pc_station, pc_chamber, pc_segment, *tp_it, conv_hit);
72  } else if (tp_it->subsystem() == TriggerPrimitive::kRPC) {
73  convert_rpc(pc_sector, pc_station, pc_chamber, pc_segment, *tp_it, conv_hit);
74  } else if (tp_it->subsystem() == TriggerPrimitive::kGEM) {
75  convert_gem(pc_sector, pc_station, pc_chamber, pc_segment, *tp_it, conv_hit);
76  } else {
77  if (not(false && "Incorrect subsystem type"))
78  { edm::LogError("L1T") << "Incorrect subsystem type"; return; }
79  }
80  conv_hits.push_back(conv_hit);
81  pc_segment += 1;
82  }
83  }
84 }
85 
86 
87 // _____________________________________________________________________________
88 // CSC functions
90  int pc_sector, int pc_station, int pc_chamber, int pc_segment,
91  const TriggerPrimitive& muon_primitive,
92  EMTFHit& conv_hit
93 ) const {
94  const CSCDetId& tp_detId = muon_primitive.detId<CSCDetId>();
95  const CSCData& tp_data = muon_primitive.getCSCData();
96 
97  int tp_endcap = tp_detId.endcap();
98  int tp_sector = tp_detId.triggerSector();
99  int tp_station = tp_detId.station();
100  int tp_ring = tp_detId.ring();
101  int tp_chamber = tp_detId.chamber();
102 
103  int tp_bx = tp_data.bx;
104  int tp_csc_ID = tp_data.cscID;
105 
106  // station 1 --> subsector 1 or 2
107  // station 2,3,4 --> subsector 0
108  int tp_subsector = (tp_station != 1) ? 0 : ((tp_chamber % 6 > 2) ? 1 : 2);
109 
110  const bool is_neighbor = (pc_station == 5);
111 
112  int csc_nID = tp_csc_ID; // modify csc_ID if coming from neighbor sector
113  if (is_neighbor) {
114  // station 1 has 3 neighbor chambers: 13,14,15 in rings 1,2,3
115  // (where are chambers 10,11,12 in station 1? they were used to label ME1/1a, but not anymore)
116  // station 2,3,4 have 2 neighbor chambers: 10,11 in rings 1,2
117  csc_nID = (pc_chamber < 3) ? (pc_chamber + 12) : ( ((pc_chamber - 1) % 2) + 9);
118  csc_nID += 1;
119 
120  if (tp_station == 1) { // neighbor ME1
121  if (not(tp_subsector == 2))
122  { edm::LogError("L1T") << "tp_subsector = " << tp_subsector; return; }
123  }
124  }
125 
126  // Set properties
127  conv_hit.SetCSCDetId ( tp_detId );
128 
129  conv_hit.set_endcap ( (tp_endcap == 2) ? -1 : tp_endcap );
130  conv_hit.set_station ( tp_station );
131  conv_hit.set_ring ( tp_ring );
132  //conv_hit.set_roll ( tp_roll );
133  conv_hit.set_chamber ( tp_chamber );
134  conv_hit.set_sector ( tp_sector );
135  conv_hit.set_subsector ( tp_subsector );
136  conv_hit.set_csc_ID ( tp_csc_ID );
137  conv_hit.set_csc_nID ( csc_nID );
138  conv_hit.set_track_num ( tp_data.trknmb );
139  conv_hit.set_sync_err ( tp_data.syncErr );
140  //conv_hit.set_sector_RPC ( tp_sector );
141  //conv_hit.set_subsector_RPC ( tp_subsector );
142 
143  conv_hit.set_bx ( tp_bx + bxShiftCSC_ );
145  conv_hit.set_is_CSC ( true );
146  conv_hit.set_is_RPC ( false );
147  conv_hit.set_is_GEM ( false );
148 
149  conv_hit.set_pc_sector ( pc_sector );
150  conv_hit.set_pc_station ( pc_station );
151  conv_hit.set_pc_chamber ( pc_chamber );
152  conv_hit.set_pc_segment ( pc_segment );
153 
154  conv_hit.set_valid ( tp_data.valid );
155  conv_hit.set_strip ( tp_data.strip );
156  //conv_hit.set_strip_low ( tp_data.strip_low );
157  //conv_hit.set_strip_hi ( tp_data.strip_hi );
158  conv_hit.set_wire ( tp_data.keywire );
159  conv_hit.set_quality ( tp_data.quality );
160  conv_hit.set_pattern ( tp_data.pattern );
161  conv_hit.set_bend ( tp_data.bend );
162  //conv_hit.set_time ( tp_data.time );
163  conv_hit.set_alct_quality ( tp_data.alct_quality );
164  conv_hit.set_clct_quality ( tp_data.clct_quality );
165 
166  conv_hit.set_neighbor ( is_neighbor );
167  conv_hit.set_sector_idx ( (endcap_ == 1) ? sector_ - 1 : sector_ + 5 );
168 
169  convert_csc_details(conv_hit);
170 
171  // Add coordinates from fullsim
172  {
173  const GlobalPoint& gp = tp_geom_->getGlobalPoint(muon_primitive);
174  double glob_phi = emtf::rad_to_deg(gp.phi().value());
175  double glob_theta = emtf::rad_to_deg(gp.theta());
176  double glob_eta = gp.eta();
177  double glob_rho = gp.perp();
178  double glob_z = gp.z();
179 
180  conv_hit.set_phi_sim ( glob_phi );
181  conv_hit.set_theta_sim ( glob_theta );
182  conv_hit.set_eta_sim ( glob_eta );
183  conv_hit.set_rho_sim ( glob_rho );
184  conv_hit.set_z_sim ( glob_z );
185  }
186 }
187 
189  const bool is_neighbor = conv_hit.Neighbor();
190 
191  // Defined as in firmware
192  // endcap : 0-1 for ME+,ME-
193  // sector : 0-5
194  // station: 0-4 for st1 sub1 or st1 sub2 from neighbor, st1 sub2, st2, st3, st4
195  // cscid : 0-14 (excluding 11), including neighbors
196  const int fw_endcap = (endcap_-1);
197  const int fw_sector = (sector_-1);
198  const int fw_station = (conv_hit.Station() == 1) ? (is_neighbor ? 0 : (conv_hit.Subsector()-1)) : conv_hit.Station();
199  const int fw_cscid = (conv_hit.CSC_nID()-1);
200  const int fw_strip = conv_hit.Strip(); // it is half-strip, despite the name
201  const int fw_wire = conv_hit.Wire(); // it is wiregroup, despite the name
202 
203  // Primitive converter unit
204  // station: 0-5 for st1 sub1, st1 sub2, st2, st3, st4, neigh all st*
205  // chamber: 0-8
206  const int pc_station = conv_hit.PC_station();
207  const int pc_chamber = conv_hit.PC_chamber();
208  const int pc_segment = conv_hit.PC_segment();
209 
210  const bool is_me11a = (conv_hit.Station() == 1 && conv_hit.Ring() == 4);
211  const bool is_me11b = (conv_hit.Station() == 1 && conv_hit.Ring() == 1);
212  const bool is_me13 = (conv_hit.Station() == 1 && conv_hit.Ring() == 3);
213 
214  // Is this chamber mounted in reverse direction?
215  // (i.e., phi vs. strip number is reversed)
216  bool ph_reverse = false;
217  if ((fw_endcap == 0 && fw_station >= 3) || (fw_endcap == 1 && fw_station < 3))
218  ph_reverse = true;
219 
220  // Chamber coverage if phi_reverse = true
221  int ph_coverage = 0; // Offset for coordinate conversion
222  if (ph_reverse) {
223  if (fw_station <= 1 && ((fw_cscid >= 6 && fw_cscid <= 8) || fw_cscid == 14)) // ME1/3
224  ph_coverage = 15;
225  else if (fw_station >= 2 && (fw_cscid <= 2 || fw_cscid == 9)) // ME2,3,4/1
226  ph_coverage = 40;
227  else // all others
228  ph_coverage = 20;
229  }
230 
231  // Is this 10-deg or 20-deg chamber?
232  bool is_10degree = false;
233  if (
234  (fw_station <= 1) || // ME1
235  (fw_station >= 2 && ((fw_cscid >= 3 && fw_cscid <= 8) || fw_cscid == 10)) // ME2,3,4/2
236  ) {
237  is_10degree = true;
238  }
239 
240  // LUT index
241  // There are 54 CSC chambers including the neighbors in a sector, but 61 LUT indices
242  // This comes from dividing the 6 chambers + 1 neighbor in ME1/1 into ME1/1a and ME1/1b
243  int pc_lut_id = pc_chamber;
244  if (pc_station == 0) { // ME1 sub 1: 0 - 11
245  pc_lut_id = is_me11a ? pc_lut_id + 9 : pc_lut_id;
246  } else if (pc_station == 1) { // ME1 sub 2: 16 - 27
247  pc_lut_id += 16;
248  pc_lut_id = is_me11a ? pc_lut_id + 9 : pc_lut_id;
249  } else if (pc_station == 2) { // ME2: 28 - 36
250  pc_lut_id += 28;
251  } else if (pc_station == 3) { // ME3: 39 - 47
252  pc_lut_id += 39;
253  } else if (pc_station == 4) { // ME4 : 50 - 58
254  pc_lut_id += 50;
255  } else if (pc_station == 5 && pc_chamber < 3) { // neighbor ME1: 12 - 15
256  pc_lut_id = is_me11a ? pc_lut_id + 15 : pc_lut_id + 12;
257  } else if (pc_station == 5 && pc_chamber < 5) { // neighbor ME2: 37 - 38
258  pc_lut_id += 28 + 9 - 3;
259  } else if (pc_station == 5 && pc_chamber < 7) { // neighbor ME3: 48 - 49
260  pc_lut_id += 39 + 9 - 5;
261  } else if (pc_station == 5 && pc_chamber < 9) { // neighbor ME4: 59 - 60
262  pc_lut_id += 50 + 9 - 7;
263  }
264  if (not(pc_lut_id < 61))
265  { edm::LogError("L1T") << "pc_lut_id = " << pc_lut_id; return; }
266 
267  if (verbose_ > 1) { // debug
268  std::cout << "pc_station: " << pc_station << " pc_chamber: " << pc_chamber
269  << " fw_station: " << fw_station << " fw_cscid: " << fw_cscid
270  << " lut_id: " << pc_lut_id
271  << " ph_init: " << lut().get_ph_init(fw_endcap, fw_sector, pc_lut_id)
272  << " ph_disp: " << lut().get_ph_disp(fw_endcap, fw_sector, pc_lut_id)
273  << " th_init: " << lut().get_th_init(fw_endcap, fw_sector, pc_lut_id)
274  << " th_disp: " << lut().get_th_disp(fw_endcap, fw_sector, pc_lut_id)
275  << " ph_init_hard: " << lut().get_ph_init_hard(fw_station, fw_cscid)
276  << std::endl;
277  }
278 
279  // ___________________________________________________________________________
280  // phi conversion
281 
282  // Convert half-strip into 1/8-strip
283  int eighth_strip = 0;
284 
285  // Apply phi correction from CLCT pattern number (from src/SectorProcessorLUT.cc)
286  int clct_pat_corr = lut().get_ph_patt_corr(conv_hit.Pattern());
287  int clct_pat_corr_sign = (lut().get_ph_patt_corr_sign(conv_hit.Pattern()) == 0) ? 1 : -1;
288 
289  // At strip number 0, protect against negative correction
290  bool bugStrip0BeforeFW48200 = false;
291  if (bugStrip0BeforeFW48200 == false && fw_strip == 0 && clct_pat_corr_sign == -1)
292  clct_pat_corr = 0;
293 
294  if (is_10degree) {
295  eighth_strip = fw_strip << 2; // full precision, uses only 2 bits of pattern correction
296  eighth_strip += clct_pat_corr_sign * (clct_pat_corr >> 1);
297  } else {
298  eighth_strip = fw_strip << 3; // multiply by 2, uses all 3 bits of pattern correction
299  eighth_strip += clct_pat_corr_sign * (clct_pat_corr >> 0);
300  }
301  if (not(bugStrip0BeforeFW48200 == true || eighth_strip >= 0))
302  { edm::LogError("L1T") << "bugStrip0BeforeFW48200 = " << bugStrip0BeforeFW48200
303  << ", eighth_strip = " << eighth_strip; return; }
304 
305  // Multiplicative factor for eighth_strip
306  int factor = 1024;
307  if (is_me11a)
308  factor = 1707; // ME1/1a
309  else if (is_me11b)
310  factor = 1301; // ME1/1b
311  else if (is_me13)
312  factor = 947; // ME1/3
313 
314  // ph_tmp is full-precision phi, but local to chamber (counted from strip 0)
315  // full phi precision: ( 1/60) deg (1/8-strip)
316  // zone phi precision: (32/60) deg (4-strip, 32 times coarser than full phi precision)
317  int ph_tmp = (eighth_strip * factor) >> 10;
318  int ph_tmp_sign = (ph_reverse == 0) ? 1 : -1;
319 
320  int fph = lut().get_ph_init(fw_endcap, fw_sector, pc_lut_id);
321  fph = fph + ph_tmp_sign * ph_tmp;
322 
323  int ph_hit = lut().get_ph_disp(fw_endcap, fw_sector, pc_lut_id);
324  ph_hit = (ph_hit >> 1) + ph_tmp_sign * (ph_tmp >> 5) + ph_coverage;
325 
326  // Full phi +16 to put the rounded value into the middle of error range
327  // Divide full phi by 32, subtract chamber start
328  int ph_hit_fixed = -1 * lut().get_ph_init_hard(fw_station, fw_cscid);
329  ph_hit_fixed = ph_hit_fixed + ((fph + (1<<4)) >> 5);
330 
331  if (fixZonePhi_)
332  ph_hit = ph_hit_fixed;
333 
334  // Zone phi
335  int zone_hit = lut().get_ph_zone_offset(pc_station, pc_chamber);
336  zone_hit += ph_hit;
337 
338  int zone_hit_fixed = lut().get_ph_init_hard(fw_station, fw_cscid);
339  zone_hit_fixed += ph_hit_fixed;
340  // Since ph_hit_fixed = ((fph + (1<<4)) >> 5) - lut().get_ph_init_hard(), the following is equivalent:
341  //zone_hit_fixed = ((fph + (1<<4)) >> 5);
342 
343  if (fixZonePhi_)
344  zone_hit = zone_hit_fixed;
345 
346  if (not(0 <= fph && fph < 5000))
347  { edm::LogError("L1T") << "fph = " << fph; return; }
348  if (not(0 <= zone_hit && zone_hit < 192))
349  { edm::LogError("L1T") << "zone_hit = " << zone_hit; return; }
350 
351  // ___________________________________________________________________________
352  // theta conversion
353 
354  // th_tmp is theta local to chamber
355  int pc_wire_id = (fw_wire & 0x7f); // 7-bit
356  int th_tmp = lut().get_th_lut(fw_endcap, fw_sector, pc_lut_id, pc_wire_id);
357 
358  // For ME1/1 with tilted wires, add theta correction as a function of (wire,strip) index
359  if (!fixME11Edges_ && (is_me11a || is_me11b)) {
360  int pc_wire_strip_id = (((fw_wire >> 4) & 0x3) << 5) | ((eighth_strip >> 4) & 0x1f); // 2-bit from wire, 5-bit from 2-strip
361 
362  // Only affect runs before FW changeset 47114 is applied
363  // e.g. Run 281707 and earlier
364  if (bugME11Dupes_) {
365  bool bugME11DupesBeforeFW47114 = false;
366  if (bugME11DupesBeforeFW47114) {
367  if (pc_segment == 1) {
368  pc_wire_strip_id = (((fw_wire >> 4) & 0x3) << 5) | (0); // 2-bit from wire, 5-bit from 2-strip
369  }
370  }
371  }
372 
373  int th_corr = lut().get_th_corr_lut(fw_endcap, fw_sector, pc_lut_id, pc_wire_strip_id);
374  int th_corr_sign = (ph_reverse == 0) ? 1 : -1;
375 
376  th_tmp = th_tmp + th_corr_sign * th_corr;
377 
378  // Check that correction did not make invalid value outside chamber coverage
379  const int th_negative = 50;
380  const int th_coverage = 45;
381  if (th_tmp > th_negative || th_tmp < 0 || fw_wire == 0)
382  th_tmp = 0; // limit at the bottom
383  if (th_tmp > th_coverage)
384  th_tmp = th_coverage; // limit at the top
385 
386  } else if (fixME11Edges_ && (is_me11a || is_me11b)) {
387  int pc_wire_strip_id = (((fw_wire >> 4) & 0x3) << 5) | ((eighth_strip >> 4) & 0x1f); // 2-bit from wire, 5-bit from 2-strip
388  if (is_me11a)
389  pc_wire_strip_id = (((fw_wire >> 4) & 0x3) << 5) | ((((eighth_strip*341)>>8) >> 4) & 0x1f); // correct for ME1/1a strip number (341/256 =~ 1.333)
390  int th_corr = lut().get_th_corr_lut(fw_endcap, fw_sector, pc_lut_id, pc_wire_strip_id);
391 
392  th_tmp = th_tmp + th_corr;
393 
394  // Check that correction did not make invalid value outside chamber coverage
395  const int th_coverage = 46; // max coverage for front chamber is 47, max coverage for rear chamber is 45
396  if (fw_wire == 0)
397  th_tmp = 0; // limit at the bottom
398  if (th_tmp > th_coverage)
399  th_tmp = th_coverage; // limit at the top
400  }
401 
402  // theta precision: (36.5/128) deg
403  // theta starts at 8.5 deg: {1, 127} <--> {8.785, 44.715}
404  int th = lut().get_th_init(fw_endcap, fw_sector, pc_lut_id);
405  th = th + th_tmp;
406 
407  if (not(0 <= th && th < 128))
408  { edm::LogError("L1T") << "th = " << th; return; }
409  th = (th == 0) ? 1 : th; // protect against invalid value
410 
411  // ___________________________________________________________________________
412  // Zone codes and other segment IDs
413 
414  //int zone_hit = ((fph + (1<<4)) >> 5);
415  int zone_code = get_zone_code(conv_hit, th);
416  int phzvl = get_phzvl(conv_hit, zone_code);
417 
418  int fs_zone_code = get_fs_zone_code(conv_hit);
419  int fs_segment = get_fs_segment(conv_hit, fw_station, fw_cscid, pc_segment);
420 
421  int bt_station = get_bt_station(conv_hit, fw_station, fw_cscid, pc_segment);
422  int bt_segment = get_bt_segment(conv_hit, fw_station, fw_cscid, pc_segment);
423 
424  // ___________________________________________________________________________
425  // Output
426 
427  conv_hit.set_phi_fp ( fph ); // Full-precision integer phi
428  conv_hit.set_theta_fp ( th ); // Full-precision integer theta
429  conv_hit.set_phzvl ( phzvl ); // Local zone word: (1*low) + (2*mid) + (4*low) - used in FW debugging
430  conv_hit.set_ph_hit ( ph_hit ); // Intermediate quantity in phi calculation - used in FW debugging
431  conv_hit.set_zone_hit ( zone_hit ); // Phi value for building patterns (0.53333 deg precision)
432  conv_hit.set_zone_code ( zone_code ); // Full zone word: 1*(zone 0) + 2*(zone 1) + 4*(zone 2) + 8*(zone 3)
433 
434  conv_hit.set_fs_segment ( fs_segment ); // Segment number used in primitive matching
435  conv_hit.set_fs_zone_code ( fs_zone_code ); // Zone word used in primitive matching
436 
437  conv_hit.set_bt_station ( bt_station );
438  conv_hit.set_bt_segment ( bt_segment );
439 
440  conv_hit.set_phi_loc ( emtf::calc_phi_loc_deg(fph) );
441  conv_hit.set_phi_glob ( emtf::calc_phi_glob_deg(conv_hit.Phi_loc(), conv_hit.PC_sector()) );
442  conv_hit.set_theta ( emtf::calc_theta_deg_from_int(th) );
443  conv_hit.set_eta ( emtf::calc_eta_from_theta_deg(conv_hit.Theta(), conv_hit.Endcap()) );
444 }
445 
446 
447 // _____________________________________________________________________________
448 // RPC functions
450  int pc_sector, int pc_station, int pc_chamber, int pc_segment,
451  const TriggerPrimitive& muon_primitive,
452  EMTFHit& conv_hit
453 ) const {
454  const RPCDetId& tp_detId = muon_primitive.detId<RPCDetId>();
455  const RPCData& tp_data = muon_primitive.getRPCData();
456 
457  int tp_region = tp_detId.region(); // 0 for Barrel, +/-1 for +/- Endcap
458  int tp_endcap = (tp_region == -1) ? 2 : tp_region;
459  int tp_sector = tp_detId.sector(); // 1 - 6 (60 degrees in phi, sector 1 begins at -5 deg)
460  int tp_subsector = tp_detId.subsector(); // 1 - 6 (10 degrees in phi; staggered in z)
461  int tp_station = tp_detId.station(); // 1 - 4
462  int tp_ring = tp_detId.ring(); // 2 - 3 (increasing theta)
463  int tp_roll = tp_detId.roll(); // 1 - 3 (decreasing theta; aka A - C; space between rolls is 9 - 15 in theta_fp)
464  //int tp_layer = tp_detId.layer();
465 
466  int tp_bx = tp_data.bx;
467  int tp_strip = ((tp_data.strip_low + tp_data.strip_hi) / 2); // in full-strip unit
468  int tp_valid = tp_data.valid;
469 
470  const bool is_neighbor = (pc_station == 5);
471 
472  // CSC-like sector, subsector and chamber numbers
473  int csc_tp_chamber = (tp_sector - 1)*6 + tp_subsector;
474  int csc_tp_sector = (tp_subsector > 2) ? tp_sector : ((tp_sector + 4) % 6) + 1; // Rotate by 20 deg
475  int csc_tp_subsector = ((tp_subsector + 3) % 6) + 1; // Rotate by 2
476 
477  // Set properties
478  conv_hit.SetRPCDetId ( tp_detId );
479 
480  conv_hit.set_endcap ( (tp_endcap == 2) ? -1 : tp_endcap );
481  conv_hit.set_station ( tp_station );
482  conv_hit.set_ring ( tp_ring );
483  conv_hit.set_roll ( tp_roll );
484  conv_hit.set_chamber ( csc_tp_chamber );
485  conv_hit.set_sector ( csc_tp_sector );
486  conv_hit.set_subsector ( csc_tp_subsector );
487  //conv_hit.set_csc_ID ( tp_csc_ID );
488  //conv_hit.set_csc_nID ( csc_nID );
489  //conv_hit.set_track_num ( tp_data.trknmb );
490  //conv_hit.set_sync_err ( tp_data.syncErr );
491  conv_hit.set_sector_RPC ( tp_sector ); // In RPC convention in CMSSW (RPCDetId.h), sector 1 starts at -5 deg
492  conv_hit.set_subsector_RPC ( tp_subsector );
493 
494  conv_hit.set_bx ( tp_bx + bxShiftRPC_ );
496  conv_hit.set_is_CSC ( false );
497  conv_hit.set_is_RPC ( true );
498  conv_hit.set_is_GEM ( false );
499 
500  conv_hit.set_pc_sector ( pc_sector );
501  conv_hit.set_pc_station ( pc_station );
502  conv_hit.set_pc_chamber ( pc_chamber );
503  conv_hit.set_pc_segment ( pc_segment );
504 
505  conv_hit.set_valid ( tp_valid );
506  conv_hit.set_strip ( tp_strip );
507  conv_hit.set_strip_low ( tp_data.strip_low );
508  conv_hit.set_strip_hi ( tp_data.strip_hi );
509  //conv_hit.set_wire ( tp_data.keywire );
510  //conv_hit.set_quality ( tp_data.quality );
511  conv_hit.set_pattern ( 0 ); // In firmware, this marks RPC stub
512  //conv_hit.set_bend ( tp_data.bend );
513  conv_hit.set_time ( tp_data.time );
514  //conv_hit.set_alct_quality ( tp_data.alct_quality );
515  //conv_hit.set_clct_quality ( tp_data.clct_quality );
516 
517  conv_hit.set_neighbor ( is_neighbor );
518  conv_hit.set_sector_idx ( (endcap_ == 1) ? sector_ - 1 : sector_ + 5 );
519 
520 
521  // Get coordinates from fullsim since LUTs do not exist yet
522  bool use_fullsim_coords = true;
523  if (use_fullsim_coords) {
524  const GlobalPoint& gp = tp_geom_->getGlobalPoint(muon_primitive);
525  double glob_phi = emtf::rad_to_deg(gp.phi().value());
526  double glob_theta = emtf::rad_to_deg(gp.theta());
527  double glob_eta = gp.eta();
528  double glob_rho = gp.perp();
529  double glob_z = gp.z();
530 
531  // Use RPC-specific convention in docs/CPPF-EMTF-format_2016_11_01.docx
532  // Phi precision is 1/15 degrees (11 bits), 4x larger than CSC precision of 1/60 degrees (13 bits)
533  // Theta precision is 36.5/32 degrees (5 bits), 4x larger than CSC precision of 36.5/128 degrees (7 bits)
534  //
535  // NOTE: fph and th are recalculated using CPPF LUTs in the convert_rpc_details() function,
536  // this part is still kept because it is needed for Phase 2 iRPC hits.
537  //
538  int fph = emtf::calc_phi_loc_int_rpc(glob_phi, conv_hit.PC_sector());
539  int th = emtf::calc_theta_int_rpc(glob_theta, conv_hit.Endcap());
540 
541  if (not(0 <= fph && fph < 1250))
542  { edm::LogError("L1T") << "fph = " << fph; return; }
543  if (not(0 <= th && th < 32))
544  { edm::LogError("L1T") << "th = " << th; return; }
545  if (not(th != 0b11111)) // RPC hit valid when data is not all ones
546  { edm::LogError("L1T") << "th = " << th; return; }
547  fph <<= 2; // upgrade to full CSC precision by adding 2 zeros
548  th <<= 2; // upgrade to full CSC precision by adding 2 zeros
549  th = (th == 0) ? 1 : th; // protect against invalid value
550 
551  // _________________________________________________________________________
552  // Output
553 
554  conv_hit.set_phi_sim ( glob_phi );
555  conv_hit.set_theta_sim ( glob_theta );
556  conv_hit.set_eta_sim ( glob_eta );
557  conv_hit.set_rho_sim ( glob_rho );
558  conv_hit.set_z_sim ( glob_z );
559 
560  conv_hit.set_phi_fp ( fph ); // Full-precision integer phi
561  conv_hit.set_theta_fp ( th ); // Full-precision integer theta
562  }
563 
564  convert_rpc_details(conv_hit);
565 }
566 
568  const bool is_neighbor = conv_hit.Neighbor();
569 
570  const int pc_station = conv_hit.PC_station();
571  const int pc_chamber = conv_hit.PC_chamber();
572  const int pc_segment = conv_hit.PC_segment();
573 
574  //const int fw_endcap = (endcap_-1);
575  //const int fw_sector = (sector_-1);
576  const int fw_station = (conv_hit.Station() == 1) ? (is_neighbor ? 0 : pc_station) : conv_hit.Station();
577 
578  int fw_cscid = pc_chamber;
579  if (is_neighbor) {
580  int csc_nID = -1;
581 
582  // station 1 has 3 neighbor chambers: 13,14,15 in rings 1,2,3
583  // (where are chambers 10,11,12 in station 1? they were used to label ME1/1a, but not anymore)
584  // station 2,3,4 have 2 neighbor chambers: 10,11 in rings 1,2
585  csc_nID = (pc_chamber < 3) ? (pc_chamber + 12) : ( ((pc_chamber - 1) % 2) + 9);
586  csc_nID += 1;
587 
588  fw_cscid = csc_nID - 1;
589  }
590 
591  int fph = conv_hit.Phi_fp();
592  int th = conv_hit.Theta_fp();
593 
594  bool use_cppf_coords = true;
595  if (use_cppf_coords) {
596  int halfstrip = (conv_hit.Strip_low() + conv_hit.Strip_hi() - 1);
597  if (not(1 <= halfstrip && halfstrip <= 64))
598  { edm::LogError("L1T") << "halfstrip = " << halfstrip; return; }
599 
600  int fph2 = lut().get_cppf_ph_lut(conv_hit.Endcap(), conv_hit.Sector_RPC(), conv_hit.Station(), conv_hit.Ring(), conv_hit.Subsector_RPC(), conv_hit.Roll(), halfstrip, is_neighbor);
601  int th2 = lut().get_cppf_th_lut(conv_hit.Endcap(), conv_hit.Sector_RPC(), conv_hit.Station(), conv_hit.Ring(), conv_hit.Subsector_RPC(), conv_hit.Roll());
602  fph = fph2;
603  th = th2;
604 
605  if (not(0 <= fph && fph < 1250))
606  { edm::LogError("L1T") << "fph = " << fph; return; }
607  if (not(0 <= th && th < 32))
608  { edm::LogError("L1T") << "th = " << th; return; }
609  if (not(th != 0b11111)) // RPC hit valid when data is not all ones
610  { edm::LogError("L1T") << "th = " << th; return; }
611  fph <<= 2; // upgrade to full CSC precision by adding 2 zeros
612  th <<= 2; // upgrade to full CSC precision by adding 2 zeros
613  th = (th == 0) ? 1 : th; // protect against invalid value
614  }
615 
616  if (verbose_ > 1) { // debug
617  std::cout << "RPC hit pc_station: " << pc_station << " pc_chamber: " << pc_chamber
618  << " fw_station: " << fw_station << " fw_cscid: " << fw_cscid
619  << " tp_station: " << conv_hit.Station() << " tp_ring: " << conv_hit.Ring()
620  << " tp_sector: " << conv_hit.Sector_RPC() << " tp_subsector: " << conv_hit.Subsector_RPC()
621  << " fph: " << fph << " th: " << th
622  << std::endl;
623  }
624 
625  // ___________________________________________________________________________
626  // Zone codes and other segment IDs
627 
628  int zone_hit = ((fph + (1<<4)) >> 5);
629  int zone_code = get_zone_code(conv_hit, th);
630  //int phzvl = get_phzvl(conv_hit, zone_code);
631 
632  int fs_zone_code = get_fs_zone_code(conv_hit);
633  int fs_segment = get_fs_segment(conv_hit, fw_station, fw_cscid, pc_segment);
634 
635  int bt_station = get_bt_station(conv_hit, fw_station, fw_cscid, pc_segment);
636  int bt_segment = get_bt_segment(conv_hit, fw_station, fw_cscid, pc_segment);
637 
638  // ___________________________________________________________________________
639  // Output
640 
641  conv_hit.set_phi_fp ( fph ); // Full-precision integer phi
642  conv_hit.set_theta_fp ( th ); // Full-precision integer theta
643  //conv_hit.set_phzvl ( phzvl ); // Local zone word: (1*low) + (2*mid) + (4*low) - used in FW debugging
644  //conv_hit.set_ph_hit ( ph_hit ); // Intermediate quantity in phi calculation - used in FW debugging
645  conv_hit.set_zone_hit ( zone_hit ); // Phi value for building patterns (0.53333 deg precision)
646  conv_hit.set_zone_code ( zone_code ); // Full zone word: 1*(zone 0) + 2*(zone 1) + 4*(zone 2) + 8*(zone 3)
647 
648  conv_hit.set_fs_segment ( fs_segment ); // Segment number used in primitive matching
649  conv_hit.set_fs_zone_code ( fs_zone_code ); // Zone word used in primitive matching
650 
651  conv_hit.set_bt_station ( bt_station );
652  conv_hit.set_bt_segment ( bt_segment );
653 
654  conv_hit.set_phi_loc ( emtf::calc_phi_loc_deg(fph) );
655  conv_hit.set_phi_glob ( emtf::calc_phi_glob_deg(conv_hit.Phi_loc(), conv_hit.PC_sector()) );
656  conv_hit.set_theta ( emtf::calc_theta_deg_from_int(th) );
657  conv_hit.set_eta ( emtf::calc_eta_from_theta_deg(conv_hit.Theta(), conv_hit.Endcap()) );
658 }
659 
660 
661 // _____________________________________________________________________________
662 // GEM functions
664  int pc_sector, int pc_station, int pc_chamber, int pc_segment,
665  const TriggerPrimitive& muon_primitive,
666  EMTFHit& conv_hit
667 ) const {
668  const EMTFGEMDetId& tp_detId = emtf::construct_EMTFGEMDetId(muon_primitive);
669  const GEMData& tp_data = muon_primitive.getGEMData();
670 
671  int tp_region = tp_detId.region(); // 0 for Barrel, +/-1 for +/- Endcap
672  int tp_endcap = (tp_region == -1) ? 2 : tp_region;
673  int tp_station = tp_detId.station();
674  int tp_ring = tp_detId.ring();
675  int tp_roll = tp_detId.roll();
676  //int tp_layer = tp_detId.layer();
677  int tp_chamber = tp_detId.chamber();
678 
679  int tp_bx = tp_data.bx;
680  int tp_strip = ((tp_data.pad_low + tp_data.pad_hi) / 2); // in full-strip unit
681 
682  // Use CSC trigger sector definitions
683  // Code copied from DataFormats/MuonDetId/src/CSCDetId.cc
684  auto get_trigger_sector = [](int ring, int station, int chamber) {
685  int result = 0;
686  if( station > 1 && ring > 1 ) {
687  result = ((static_cast<unsigned>(chamber-3) & 0x7f) / 6) + 1; // ch 3-8->1, 9-14->2, ... 1,2 -> 6
688  }
689  else {
690  result = (station != 1) ? ((static_cast<unsigned>(chamber-2) & 0x1f) / 3) + 1 : // ch 2-4-> 1, 5-7->2, ...
691  ((static_cast<unsigned>(chamber-3) & 0x7f) / 6) + 1;
692  }
693  return (result <= 6) ? result : 6; // max sector is 6, some calculations give a value greater than six but this is expected.
694  };
695 
696  // Use CSC trigger "CSC ID" definitions
697  // Code copied from DataFormats/MuonDetId/src/CSCDetId.cc
698  auto get_trigger_csc_ID = [](int ring, int station, int chamber) {
699  int result = 0;
700  if( station == 1 ) {
701  result = (chamber) % 3 + 1; // 1,2,3
702  switch (ring) {
703  case 1:
704  break;
705  case 2:
706  result += 3; // 4,5,6
707  break;
708  case 3:
709  result += 6; // 7,8,9
710  break;
711  }
712  }
713  else {
714  if( ring == 1 ) {
715  result = (chamber+1) % 3 + 1; // 1,2,3
716  }
717  else {
718  result = (chamber+3) % 6 + 4; // 4,5,6,7,8,9
719  }
720  }
721  return result;
722  };
723 
724  int tp_sector = get_trigger_sector(tp_ring, tp_station, tp_chamber);
725  int tp_csc_ID = get_trigger_csc_ID(tp_ring, tp_station, tp_chamber);
726 
727  // station 1 --> subsector 1 or 2
728  // station 2,3,4 --> subsector 0
729  int tp_subsector = (tp_station != 1) ? 0 : ((tp_chamber%6 > 2) ? 1 : 2);
730 
731  const bool is_neighbor = (pc_station == 5);
732 
733  int csc_nID = tp_csc_ID; // modify csc_ID if coming from neighbor sector
734  if (is_neighbor) {
735  // station 1 has 3 neighbor chambers: 13,14,15 in rings 1,2,3
736  // (where are chambers 10,11,12 in station 1? they were used to label ME1/1a, but not anymore)
737  // station 2,3,4 have 2 neighbor chambers: 10,11 in rings 1,2
738  csc_nID = (pc_chamber < 3) ? (pc_chamber + 12) : ( ((pc_chamber - 1) % 2) + 9);
739  csc_nID += 1;
740 
741  if (tp_station == 1) { // neighbor ME1
742  if (not(tp_subsector == 2))
743  { edm::LogError("L1T") << "tp_subsector = " << tp_subsector; return; }
744  }
745  }
746 
747  // Set properties
748  //conv_hit.SetGEMDetId ( tp_detId ); // Temporarily disable, caused compile error - AWB 12.04.2018
749 
750  conv_hit.set_endcap ( (tp_endcap == 2) ? -1 : tp_endcap );
751  conv_hit.set_station ( tp_station );
752  conv_hit.set_ring ( tp_ring );
753  conv_hit.set_roll ( tp_roll );
754  conv_hit.set_chamber ( tp_chamber );
755  conv_hit.set_sector ( tp_sector );
756  conv_hit.set_subsector ( tp_subsector );
757  conv_hit.set_csc_ID ( tp_csc_ID );
758  conv_hit.set_csc_nID ( csc_nID );
759  //conv_hit.set_track_num ( tp_data.trknmb );
760  //conv_hit.set_sync_err ( tp_data.syncErr );
761  //conv_hit.set_sector_RPC ( tp_sector );
762  //conv_hit.set_subsector_RPC ( tp_subsector );
763 
764  conv_hit.set_bx ( tp_bx + bxShiftGEM_ );
766  conv_hit.set_is_CSC ( false );
767  conv_hit.set_is_RPC ( false );
768  conv_hit.set_is_GEM ( true );
769 
770  conv_hit.set_pc_sector ( pc_sector );
771  conv_hit.set_pc_station ( pc_station );
772  conv_hit.set_pc_chamber ( pc_chamber );
773  conv_hit.set_pc_segment ( pc_segment );
774 
775  conv_hit.set_valid ( true );
776  conv_hit.set_strip ( tp_strip );
777  conv_hit.set_strip_low ( tp_data.pad_low );
778  conv_hit.set_strip_hi ( tp_data.pad_hi );
779  //conv_hit.set_wire ( tp_data.keywire );
780  //conv_hit.set_quality ( tp_data.quality );
781  conv_hit.set_pattern ( 1 ); // In firmware, this marks GEM stub (unconfirmed!)
782  conv_hit.set_bend ( tp_data.bend );
783  //conv_hit.set_time ( tp_data.time );
784  //conv_hit.set_alct_quality ( tp_data.alct_quality );
785  //conv_hit.set_clct_quality ( tp_data.clct_quality );
786 
787  conv_hit.set_neighbor ( is_neighbor );
788  conv_hit.set_sector_idx ( (endcap_ == 1) ? sector_ - 1 : sector_ + 5 );
789 
790 
791  // Get coordinates from fullsim since LUTs do not exist yet
792  bool use_fullsim_coords = true;
793  if (use_fullsim_coords) {
794  const GlobalPoint& gp = tp_geom_->getGlobalPoint(muon_primitive);
795  double glob_phi = emtf::rad_to_deg(gp.phi().value());
796  double glob_theta = emtf::rad_to_deg(gp.theta());
797  double glob_eta = gp.eta();
798  double glob_rho = gp.perp();
799  double glob_z = gp.z();
800 
801 
802  // Use the CSC precision (unconfirmed!)
803  int fph = emtf::calc_phi_loc_int(glob_phi, conv_hit.PC_sector());
804  int th = emtf::calc_theta_int(glob_theta, conv_hit.Endcap());
805 
806  if (not(0 <= fph && fph < 5000))
807  { edm::LogError("L1T") << "fph = " << fph; return; }
808  if (not(0 <= th && th < 128))
809  { edm::LogError("L1T") << "th = " << th; return; }
810  th = (th == 0) ? 1 : th; // protect against invalid value
811 
812  // _________________________________________________________________________
813  // Output
814 
815  conv_hit.set_phi_sim ( glob_phi );
816  conv_hit.set_theta_sim ( glob_theta );
817  conv_hit.set_eta_sim ( glob_eta );
818  conv_hit.set_rho_sim ( glob_rho );
819  conv_hit.set_z_sim ( glob_z );
820 
821  conv_hit.set_phi_fp ( fph ); // Full-precision integer phi
822  conv_hit.set_theta_fp ( th ); // Full-precision integer theta
823  }
824 
825  convert_gem_details(conv_hit);
826 }
827 
829  const bool is_neighbor = conv_hit.Neighbor();
830 
831  const int pc_station = conv_hit.PC_station();
832  const int pc_chamber = conv_hit.PC_chamber();
833  const int pc_segment = conv_hit.PC_segment();
834 
835  //const int fw_endcap = (endcap_-1);
836  //const int fw_sector = (sector_-1);
837  const int fw_station = (conv_hit.Station() == 1) ? (is_neighbor ? 0 : (conv_hit.Subsector()-1)) : conv_hit.Station();
838  const int fw_cscid = (conv_hit.CSC_nID()-1);
839 
840  int fph = conv_hit.Phi_fp();
841  int th = conv_hit.Theta_fp();
842 
843  if (verbose_ > 1) { // debug
844  std::cout << "GEM hit pc_station: " << pc_station << " pc_chamber: " << pc_chamber
845  << " fw_station: " << fw_station << " fw_cscid: " << fw_cscid
846  << " tp_station: " << conv_hit.Station() << " tp_ring: " << conv_hit.Ring()
847  << " tp_sector: " << conv_hit.Sector() << " tp_subsector: " << conv_hit.Subsector()
848  << " fph: " << fph << " th: " << th
849  << std::endl;
850  }
851 
852  // ___________________________________________________________________________
853  // Zone codes and other segment IDs
854 
855  int zone_hit = ((fph + (1<<4)) >> 5);
856  int zone_code = get_zone_code(conv_hit, th);
857  //int phzvl = get_phzvl(conv_hit, zone_code);
858 
859  int fs_zone_code = get_fs_zone_code(conv_hit);
860  int fs_segment = get_fs_segment(conv_hit, fw_station, fw_cscid, pc_segment);
861 
862  int bt_station = get_bt_station(conv_hit, fw_station, fw_cscid, pc_segment);
863  int bt_segment = get_bt_segment(conv_hit, fw_station, fw_cscid, pc_segment);
864 
865  // ___________________________________________________________________________
866  // Output
867 
868  conv_hit.set_phi_fp ( fph ); // Full-precision integer phi
869  conv_hit.set_theta_fp ( th ); // Full-precision integer theta
870  //conv_hit.set_phzvl ( phzvl ); // Local zone word: (1*low) + (2*mid) + (4*low) - used in FW debugging
871  //conv_hit.set_ph_hit ( ph_hit ); // Intermediate quantity in phi calculation - used in FW debugging
872  conv_hit.set_zone_hit ( zone_hit ); // Phi value for building patterns (0.53333 deg precision)
873  conv_hit.set_zone_code ( zone_code ); // Full zone word: 1*(zone 0) + 2*(zone 1) + 4*(zone 2) + 8*(zone 3)
874 
875  conv_hit.set_fs_segment ( fs_segment ); // Segment number used in primitive matching
876  conv_hit.set_fs_zone_code ( fs_zone_code ); // Zone word used in primitive matching
877 
878  conv_hit.set_bt_station ( bt_station );
879  conv_hit.set_bt_segment ( bt_segment );
880 
881  conv_hit.set_phi_loc ( emtf::calc_phi_loc_deg(fph) );
882  conv_hit.set_phi_glob ( emtf::calc_phi_glob_deg(conv_hit.Phi_loc(), conv_hit.PC_sector()) );
883  conv_hit.set_theta ( emtf::calc_theta_deg_from_int(th) );
884  conv_hit.set_eta ( emtf::calc_eta_from_theta_deg(conv_hit.Theta(), conv_hit.Endcap()) );
885 }
886 
887 
888 // _____________________________________________________________________________
889 // Aux functions
890 int PrimitiveConversion::get_zone_code(const EMTFHit& conv_hit, int th) const {
891  // ph zone boundaries for chambers that cover more than one zone
892  // bnd1 is the lower boundary, bnd2 the upper boundary
893  int zone_code = 0;
894 
895  bool is_csc = (conv_hit.Subsystem() == TriggerPrimitive::kCSC);
896  bool is_me13 = (is_csc && conv_hit.Station() == 1 && conv_hit.Ring() == 3);
897 
898  for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
899  int zone_code_tmp = get_fs_zone_code(conv_hit);
900  if (zone_code_tmp & (1<<izone)) {
901  bool no_use_bnd1 = ((izone==0) || ((zone_code_tmp & (1<<(izone-1))) == 0) || is_me13); // first possible zone for this hit
902  bool no_use_bnd2 = (((zone_code_tmp & (1<<(izone+1))) == 0) || is_me13); // last possible zone for this hit
903 
904  int ph_zone_bnd1 = no_use_bnd1 ? zoneBoundaries_.at(0) : zoneBoundaries_.at(izone);
905  int ph_zone_bnd2 = no_use_bnd2 ? zoneBoundaries_.at(emtf::NUM_ZONES) : zoneBoundaries_.at(izone+1);
906 
907  if ((th > (ph_zone_bnd1 - zoneOverlap_)) && (th <= (ph_zone_bnd2 + zoneOverlap_))) {
908  zone_code |= (1<<izone);
909  }
910  }
911  }
912  if (not(zone_code > 0))
913  { edm::LogError("L1T") << "zone_code = " << zone_code; return 0; }
914  return zone_code;
915 }
916 
917 int PrimitiveConversion::get_phzvl(const EMTFHit& conv_hit, int zone_code) const {
918  // For backward compatibility, no longer needed (only explicitly used in FW)
919  // phzvl: each chamber overlaps with at most 3 zones, so this "local" zone word says
920  // which of the possible zones contain the hit: 1 for lower, 2 for middle, 4 for upper
921  int phzvl = 0;
922  if (conv_hit.Ring() == 1 || conv_hit.Ring() == 4) {
923  phzvl = (zone_code >> 0);
924  } else if (conv_hit.Ring() == 2) {
925  if (conv_hit.Station() == 3 || conv_hit.Station() == 4) {
926  phzvl = (zone_code >> 1);
927  } else if (conv_hit.Station() == 1 || conv_hit.Station() == 2) {
928  phzvl = (zone_code >> 2);
929  }
930  } else if (conv_hit.Ring() == 3) {
931  phzvl = (zone_code >> 3);
932  }
933  return phzvl;
934 }
935 
936 int PrimitiveConversion::get_fs_zone_code(const EMTFHit& conv_hit) const {
937  static const unsigned int zone_code_table[4][3] = { // map (station,ring) to zone_code
938  {0b0011, 0b0100, 0b1000}, // st1 r1: [z0,z1], r2: [z2], r3: [z3]
939  {0b0011, 0b1100, 0b1100}, // st2 r1: [z0,z1], r2: [z2,z3], r3 = r2
940  {0b0001, 0b1110, 0b1110}, // st3 r1: [z0], r2: [z1,z2,z3], r3 = r2
941  {0b0001, 0b0110, 0b0110} // st4 r1: [z0], r2: [z1,z2], r3 = r2
942  };
943 
944  static const unsigned int zone_code_table_new[4][3] = { // map (station,ring) to zone_code
945  {0b0011, 0b0110, 0b1000}, // st1 r1: [z0,z1], r2: [z1,z2], r3: [z3]
946  {0b0011, 0b1110, 0b1110}, // st2 r1: [z0,z1], r2: [z1,z2,z3], r3 = r2
947  {0b0011, 0b1110, 0b1110}, // st3 r1: [z0,z1], r2: [z1,z2,z3], r3 = r2
948  {0b0001, 0b0110, 0b0110} // st4 r1: [z0], r2: [z1,z2], r3 = r2
949  };
950 
951  unsigned int istation = (conv_hit.Station()-1);
952  unsigned int iring = (conv_hit.Ring() == 4) ? 0 : (conv_hit.Ring()-1);
953  if (not(istation < 4 && iring < 3))
954  { edm::LogError("L1T") << "istation = " << istation << ", iring = " << iring; return 0; }
955  unsigned int zone_code = useNewZones_ ? zone_code_table_new[istation][iring] : zone_code_table[istation][iring];
956  return zone_code;
957 }
958 
959 int PrimitiveConversion::get_fs_segment(const EMTFHit& conv_hit, int fw_station, int fw_cscid, int pc_segment) const {
960  // For later use in primitive matching
961  // (in the firmware, this happens in the find_segment module)
962  int fs_history = 0; // history id: not set here, to be set in primitive matching
963  int fs_chamber = -1; // chamber id
964  int fs_segment = pc_segment % 2; // segment id
965 
966  // For ME1
967  // j = 0 is neighbor sector chamber
968  // j = 1,2,3 are native subsector 1 chambers
969  // j = 4,5,6 are native subsector 2 chambers
970  // For ME2,3,4:
971  // j = 0 is neighbor sector chamber
972  // j = 1,2,3,4,5,6 are native sector chambers
973  const bool is_neighbor = conv_hit.Neighbor();
974  if (fw_station <= 1) { // ME1
975  int n = fw_cscid % 3;
976  fs_chamber = is_neighbor ? 0 : ((fw_station == 0) ? 1+n : 4+n);
977  } else { // ME2,3,4
978  int n = (conv_hit.Ring() == 1) ? fw_cscid : (fw_cscid-3);
979  fs_chamber = is_neighbor ? 0 : 1+n;
980  }
981 
982  if (not(fs_history == 0 && (0 <= fs_chamber && fs_chamber < 7) && (0 <= fs_segment && fs_segment < 2)))
983  { edm::LogError("L1T") << "fs_history = " << fs_history << ", fs_chamber = " << fs_chamber
984  << ", fs_segment = " << fs_segment; return 0; }
985  // fs_segment is a 6-bit word, HHCCCS, encoding the segment number S in the chamber (1 or 2),
986  // the chamber number CCC ("j" above: uniquely identifies chamber within station and ring),
987  // and the history HH (0 for current BX, 1 for previous BX, 2 for BX before that)
988  fs_segment = ((fs_history & 0x3)<<4) | ((fs_chamber & 0x7)<<1) | (fs_segment & 0x1);
989  return fs_segment;
990 }
991 
992 int PrimitiveConversion::get_bt_station(const EMTFHit& conv_hit, int fw_station, int fw_cscid, int pc_segment) const {
993  int bt_station = fw_station;
994  return bt_station;
995 }
996 
997 int PrimitiveConversion::get_bt_segment(const EMTFHit& conv_hit, int fw_station, int fw_cscid, int pc_segment) const {
998  // For later use in angle calculation and best track selection
999  // (in the firmware, this happens in the best_tracks module)
1000  int bt_history = 0; // history id: not set here, to be set in primitive matching
1001  int bt_chamber = -1; // chamber id
1002  int bt_segment = pc_segment % 2; // segment id
1003 
1004  // For ME1
1005  // j = 0 is No valid LCT
1006  // j = 1 .. 9 are native sector chambers
1007  // j = 10 .. 12 are neighbor sector chambers
1008  // For ME2,3,4
1009  // j = 0 is No valid LCT
1010  // j = 1 .. 9 are native sector chambers
1011  // j = 10 .. 11 are neighbor sector chambers
1012  bt_chamber = fw_cscid+1;
1013  if (fw_station == 0 && bt_chamber >= 13) // ME1 neighbor chambers 13,14,15 -> 10,11,12
1014  bt_chamber -= 3;
1015 
1016  if (not(bt_history == 0 && (0 <= bt_chamber && bt_chamber < 13) && (0 <= bt_segment && bt_segment < 2)))
1017  { edm::LogError("L1T") << "bt_history = " << bt_history << ", bt_chamber = " << bt_chamber
1018  << ", bt_segment = " << bt_segment; return 0; }
1019 
1020  // bt_segment is a 7-bit word, HHCCCCS, encoding the segment number S in the chamber (1 or 2),
1021  // the chamber number CCCC ("j" above: uniquely identifies chamber within station and ring),
1022  // and the history HH (0 for current BX, 1 for previous BX, 2 for BX before that)
1023  bt_segment = ((bt_history & 0x3)<<5) | ((bt_chamber & 0xf)<<1) | (bt_segment & 0x1);
1024  return bt_segment;
1025 }
void set_subsector_RPC(int bits)
Definition: EMTFHit.h:88
void set_phi_glob(float val)
Definition: EMTFHit.h:123
int chamber() const
Definition: CSCDetId.h:68
int Strip_hi() const
Definition: EMTFHit.h:159
void set_theta_sim(float val)
Definition: EMTFHit.h:128
void set_is_GEM(int bits)
Definition: EMTFHit.h:136
void set_neighbor(int bits)
Definition: EMTFHit.h:93
int Subsystem() const
Definition: EMTFHit.h:195
void set_rho_sim(float val)
Definition: EMTFHit.h:130
int get_bt_station(const EMTFHit &conv_hit, int fw_station, int fw_cscid, int pc_segment) const
void set_csc_nID(int bits)
Definition: EMTFHit.h:91
float Phi_loc() const
Definition: EMTFHit.h:180
void set_pc_station(int bits)
Definition: EMTFHit.h:96
void set_phi_sim(float val)
Definition: EMTFHit.h:127
int Strip() const
Definition: EMTFHit.h:158
T perp() const
Definition: PV3DBase.h:72
int get_zone_code(const EMTFHit &conv_hit, int th) const
void convert_gem_details(EMTFHit &conv_hit) const
bool verbose
void configure(const GeometryTranslator *tp_geom, const SectorProcessorLUT *lut, int verbose, int endcap, int sector, int bx, int bxShiftCSC, int bxShiftRPC, int bxShiftGEM, const std::vector< int > &zoneBoundaries, int zoneOverlap, bool duplicateTheta, bool fixZonePhi, bool useNewZones, bool fixME11Edges, bool bugME11Dupes)
const GEMData getGEMData() const
int CSC_nID() const
Definition: EMTFHit.h:149
const SectorProcessorLUT * lut_
int Phi_fp() const
Definition: EMTFHit.h:170
void set_station(int bits)
Definition: EMTFHit.h:82
void set_ph_hit(int bits)
Definition: EMTFHit.h:115
void set_theta(float val)
Definition: EMTFHit.h:124
int NUM_ZONES
Definition: Common.h:65
float Theta() const
Definition: EMTFHit.h:182
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
void set_bt_station(int bits)
Definition: EMTFHit.h:120
void set_eta_sim(float val)
Definition: EMTFHit.h:129
void convert_gem(int pc_sector, int pc_station, int pc_chamber, int pc_segment, const TriggerPrimitive &muon_primitive, EMTFHit &conv_hit) const
double calc_phi_loc_deg(int bits)
Definition: TrackTools.h:163
void set_sector_idx(int bits)
Definition: EMTFHit.h:86
void convert_rpc(int pc_sector, int pc_station, int pc_chamber, int pc_segment, const TriggerPrimitive &muon_primitive, EMTFHit &conv_hit) const
int calc_phi_loc_int(double glob, int sector)
Definition: TrackTools.h:190
int Roll() const
Definition: EMTFHit.h:150
void set_sync_err(int bits)
Definition: EMTFHit.h:108
uint32_t get_ph_patt_corr_sign(int pattern) const
const CSCData getCSCData() const
int get_bt_segment(const EMTFHit &conv_hit, int fw_station, int fw_cscid, int pc_segment) const
void set_theta_fp(int bits)
Definition: EMTFHit.h:113
void set_endcap(int bits)
Definition: EMTFHit.h:81
void set_ring(int bits)
Definition: EMTFHit.h:83
int calc_theta_int_rpc(double theta, int endcap)
Definition: TrackTools.h:135
int PC_sector() const
Definition: EMTFHit.h:153
const RPCData getRPCData() const
int Wire() const
Definition: EMTFHit.h:157
Geom::Theta< T > theta() const
Definition: PV3DBase.h:75
void SetRPCDetId(const RPCDetId &id)
Definition: EMTFHit.h:66
int endcap() const
Definition: CSCDetId.h:93
uint32_t get_th_init(int fw_endcap, int fw_sector, int pc_lut_id) const
int Subsector() const
Definition: EMTFHit.h:145
int PC_station() const
Definition: EMTFHit.h:154
int get_fs_segment(const EMTFHit &conv_hit, int fw_station, int fw_cscid, int pc_segment) const
int Sector() const
Definition: EMTFHit.h:142
void set_strip_low(int bits)
Definition: EMTFHit.h:102
double calc_theta_deg_from_int(int theta_int)
Definition: TrackTools.h:109
int Strip_low() const
Definition: EMTFHit.h:160
int roll() const
Definition: RPCDetId.h:120
void set_phzvl(int bits)
Definition: EMTFHit.h:114
int roll() const
Definition: EMTFGEMDetId.cc:69
void set_bt_segment(int bits)
Definition: EMTFHit.h:121
int PC_segment() const
Definition: EMTFHit.h:156
int region() const
The identifiers.
Definition: EMTFGEMDetId.cc:32
int ring() const
Definition: RPCDetId.h:72
uint32_t get_cppf_th_lut(int rpc_region, int rpc_sector, int rpc_station, int rpc_ring, int rpc_subsector, int rpc_roll) const
void set_is_CSC(int bits)
Definition: EMTFHit.h:134
void set_pattern(int bits)
Definition: EMTFHit.h:105
T z() const
Definition: PV3DBase.h:64
int Subsector_RPC() const
Definition: EMTFHit.h:146
void set_csc_ID(int bits)
Definition: EMTFHit.h:90
void set_pc_chamber(int bits)
Definition: EMTFHit.h:97
void set_strip_hi(int bits)
Definition: EMTFHit.h:101
void set_wire(int bits)
Definition: EMTFHit.h:99
int calc_phi_loc_int_rpc(double glob, int sector)
Definition: TrackTools.h:198
void convert_csc_details(EMTFHit &conv_hit) const
l1t::EMTFHitCollection EMTFHitCollection
Definition: Common.h:24
int Ring() const
Definition: EMTFHit.h:141
double calc_phi_glob_deg(double loc, int sector)
Definition: TrackTools.h:153
int chamber() const
Definition: EMTFGEMDetId.cc:62
void set_time(float val)
Definition: EMTFHit.h:126
void set_phi_loc(float val)
Definition: EMTFHit.h:122
uint32_t get_th_disp(int fw_endcap, int fw_sector, int pc_lut_id) const
int calc_theta_int(double theta, int endcap)
Definition: TrackTools.h:128
int Sector_RPC() const
Definition: EMTFHit.h:143
void set_pc_segment(int bits)
Definition: EMTFHit.h:98
int PC_chamber() const
Definition: EMTFHit.h:155
uint32_t get_ph_disp(int fw_endcap, int fw_sector, int pc_lut_id) const
void set_is_RPC(int bits)
Definition: EMTFHit.h:135
void SetCSCDetId(const CSCDetId &id)
Definition: EMTFHit.h:65
EMTFGEMDetId construct_EMTFGEMDetId(const TriggerPrimitive &tp)
void set_fs_segment(int bits)
Definition: EMTFHit.h:118
int ring() const
Definition: CSCDetId.h:75
void set_sector_RPC(int bits)
Definition: EMTFHit.h:85
std::vector< int > zoneBoundaries_
int station() const
Definition: EMTFGEMDetId.cc:47
void set_sector(int bits)
Definition: EMTFHit.h:84
void process(const std::map< int, TriggerPrimitiveCollection > &selected_prim_map, EMTFHitCollection &conv_hits) const
int Station() const
Definition: EMTFHit.h:140
void set_valid(int bits)
Definition: EMTFHit.h:107
void set_z_sim(float val)
Definition: EMTFHit.h:131
void set_strip(int bits)
Definition: EMTFHit.h:100
int triggerSector() const
Definition: CSCDetId.cc:3
double calc_eta_from_theta_deg(double theta_deg, int endcap)
Definition: TrackTools.h:94
uint32_t get_ph_zone_offset(int pc_station, int pc_chamber) const
int sector() const
Sector id: the group of chambers at same phi (and increasing r)
Definition: RPCDetId.h:102
void set_subsystem(int bits)
Definition: EMTFHit.h:137
T eta() const
Definition: PV3DBase.h:76
void set_track_num(int bits)
Definition: EMTFHit.h:103
int subsector() const
SubSector id : some sectors are divided along the phi direction in subsectors (from 1 to 4 in Barrel...
Definition: RPCDetId.h:114
void set_zone_code(int bits)
Definition: EMTFHit.h:117
uint32_t get_ph_patt_corr(int pattern) const
int Pattern() const
Definition: EMTFHit.h:163
void set_bx(int bits)
Definition: EMTFHit.h:110
void set_zone_hit(int bits)
Definition: EMTFHit.h:116
int Endcap() const
Definition: EMTFHit.h:139
uint32_t get_th_lut(int fw_endcap, int fw_sector, int pc_lut_id, int pc_wire_id) const
int station() const
Definition: CSCDetId.h:86
double rad_to_deg(double rad)
Definition: TrackTools.h:54
void convert_rpc_details(EMTFHit &conv_hit) const
int get_phzvl(const EMTFHit &conv_hit, int zone_code) const
const SectorProcessorLUT & lut() const
int get_fs_zone_code(const EMTFHit &conv_hit) const
uint32_t get_ph_init_hard(int fw_station, int fw_cscid) const
void set_fs_zone_code(int bits)
Definition: EMTFHit.h:119
int Theta_fp() const
Definition: EMTFHit.h:171
void set_clct_quality(int bits)
Definition: EMTFHit.h:133
void set_quality(int bits)
Definition: EMTFHit.h:104
void set_chamber(int bits)
Definition: EMTFHit.h:89
uint32_t get_ph_init(int fw_endcap, int fw_sector, int pc_lut_id) const
int Neighbor() const
Definition: EMTFHit.h:151
uint32_t get_th_corr_lut(int fw_endcap, int fw_sector, int pc_lut_id, int pc_wire_strip_id) const
void set_subsector(int bits)
Definition: EMTFHit.h:87
void set_bend(int bits)
Definition: EMTFHit.h:106
void set_alct_quality(int bits)
Definition: EMTFHit.h:132
const GeometryTranslator * tp_geom_
uint32_t get_cppf_ph_lut(int rpc_region, int rpc_sector, int rpc_station, int rpc_ring, int rpc_subsector, int rpc_roll, int halfstrip, bool is_neighbor) const
void convert_csc(int pc_sector, int pc_station, int pc_chamber, int pc_segment, const TriggerPrimitive &muon_primitive, EMTFHit &conv_hit) const
void set_phi_fp(int bits)
Definition: EMTFHit.h:112
void set_roll(int bits)
Definition: EMTFHit.h:92
int ring() const
Definition: EMTFGEMDetId.cc:39
void set_pc_sector(int bits)
Definition: EMTFHit.h:95
int region() const
Region id: 0 for Barrel, +/-1 For +/- Endcap.
Definition: RPCDetId.h:63
int station() const
Definition: RPCDetId.h:96
void set_eta(float val)
Definition: EMTFHit.h:125
GlobalPoint getGlobalPoint(const TriggerPrimitive &) const