CMS 3D CMS Logo

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