CMS 3D CMS Logo

PrimitiveSelection.cc
Go to the documentation of this file.
2 
9 
10 
11 #include "helper.h" // merge_map_into_map, assert_no_abort
12 
13 #define NUM_CSC_CHAMBERS 6*9 // 18 in ME1; 9x3 in ME2,3,4; 9 from neighbor sector.
14  // Arranged in FW as 6 stations, 9 chambers per station.
15 #define NUM_RPC_CHAMBERS 7*8 // 6x2 in RE1,2; 12x2 in RE3,4; 6 from neighbor sector.
16  // Arranged in FW as 7 stations, 6 chambers per station. (8 with iRPC)
17 #define NUM_GEM_CHAMBERS 6*9 // 6 in GE1/1; 3 in GE2/1; 2 from neighbor sector.
18  // Arranged in FW as 6 stations, 9 chambers per station, mimicking CSC. (unconfirmed!)
19 
20 
22  int verbose, int endcap, int sector, int bx,
23  int bxShiftCSC, int bxShiftRPC, int bxShiftGEM,
24  bool includeNeighbor, bool duplicateTheta,
25  bool bugME11Dupes
26 ) {
27  verbose_ = verbose;
28  endcap_ = endcap;
29  sector_ = sector;
30  bx_ = bx;
31 
32  bxShiftCSC_ = bxShiftCSC;
33  bxShiftRPC_ = bxShiftRPC;
34  bxShiftGEM_ = bxShiftGEM;
35 
36  includeNeighbor_ = includeNeighbor;
37  duplicateTheta_ = duplicateTheta;
38  bugME11Dupes_ = bugME11Dupes;
39 }
40 
41 
42 // _____________________________________________________________________________
43 // Specialized process() for CSC
44 template<>
46  CSCTag tag,
47  const TriggerPrimitiveCollection& muon_primitives,
48  std::map<int, TriggerPrimitiveCollection>& selected_csc_map
49 ) const {
50  TriggerPrimitiveCollection::const_iterator tp_it = muon_primitives.begin();
51  TriggerPrimitiveCollection::const_iterator tp_end = muon_primitives.end();
52 
53  for (; tp_it != tp_end; ++tp_it) {
54  TriggerPrimitive new_tp = *tp_it; // make a copy and apply patches to this copy
55 
56  // Patch the CLCT pattern number
57  // It should be 0-10, see: L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc
58  bool patchPattern = true;
59  if (patchPattern && new_tp.subsystem() == TriggerPrimitive::kCSC) {
60  if (new_tp.getCSCData().pattern == 11 || new_tp.getCSCData().pattern == 12 || new_tp.getCSCData().pattern == 13 || new_tp.getCSCData().pattern == 14) { // 11, 12, 13, 14 -> 10
61  edm::LogWarning("L1T") << "EMTF patching corrupt CSC LCT pattern: changing " << new_tp.getCSCData().pattern << " to 10";
62  new_tp.accessCSCData().pattern = 10;
63  }
64  }
65 
66  // Patch the LCT quality number
67  // It should be 1-15, see: L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc
68  bool patchQuality = true;
69  if (patchQuality && new_tp.subsystem() == TriggerPrimitive::kCSC) {
70  if (new_tp.getCSCData().quality == 0) { // 0 -> 1
71  edm::LogWarning("L1T") << "EMTF patching corrupt CSC LCT quality: changing " << new_tp.getCSCData().quality << " to 1";
72  new_tp.accessCSCData().quality = 1;
73  }
74  }
75 
76  int selected_csc = select_csc(new_tp); // Returns CSC "link" index (0 - 53)
77 
78  if (selected_csc >= 0) {
79  if (not(selected_csc < NUM_CSC_CHAMBERS))
80  { edm::LogError("L1T") << "selected_csc = " << selected_csc << ", NUM_CSC_CHAMBERS = " << NUM_CSC_CHAMBERS; return; }
81 
82  if (selected_csc_map[selected_csc].size() < 2) {
83  selected_csc_map[selected_csc].push_back(new_tp);
84  }
85  else {
86  edm::LogWarning("L1T") << "\n******************* EMTF EMULATOR: SUPER-BIZZARE CASE *******************";
87  edm::LogWarning("L1T") << "Found 3 CSC trigger primitives in the same chamber";
88  for (int ii = 0; ii < 3; ii++) {
89  TriggerPrimitive tp_err = (ii < 2 ? selected_csc_map[selected_csc].at(ii) : new_tp);
90  edm::LogWarning("L1T") << "LCT #" << ii+1 << ": BX " << tp_err.getBX()
91  << ", endcap " << tp_err.detId<CSCDetId>().endcap() << ", sector " << tp_err.detId<CSCDetId>().triggerSector()
92  << ", station " << tp_err.detId<CSCDetId>().station() << ", ring " << tp_err.detId<CSCDetId>().ring()
93  << ", chamber " << tp_err.detId<CSCDetId>().chamber() << ", CSC ID " << tp_err.getCSCData().cscID
94  << ": strip " << tp_err.getStrip() << ", wire " << tp_err.getWire();
95  }
96  edm::LogWarning("L1T") << "************************* ONLY KEEP FIRST TWO *************************\n\n";
97  }
98 
99  } // End conditional: if (selected_csc >= 0)
100  } // End loop: for (; tp_it != tp_end; ++tp_it)
101 
102  // Duplicate CSC muon primitives
103  // If there are 2 LCTs in the same chamber with (strip, wire) = (s1, w1) and (s2, w2)
104  // make all combinations with (s1, w1), (s2, w1), (s1, w2), (s2, w2)
105  if (duplicateTheta_) {
106  std::map<int, TriggerPrimitiveCollection>::iterator map_tp_it = selected_csc_map.begin();
107  std::map<int, TriggerPrimitiveCollection>::iterator map_tp_end = selected_csc_map.end();
108 
109  for (; map_tp_it != map_tp_end; ++map_tp_it) {
110  int selected = map_tp_it->first;
111  TriggerPrimitiveCollection& tmp_primitives = map_tp_it->second; // pass by reference
112 
113  if (tmp_primitives.size() >= 4) {
114  edm::LogWarning("L1T") << "EMTF found 4 or more CSC LCTs in one chamber: keeping only two";
115  tmp_primitives.erase(tmp_primitives.begin() + 4, tmp_primitives.end()); // erase 5th element++
116  tmp_primitives.erase(tmp_primitives.begin() + 2); // erase 3rd element
117  tmp_primitives.erase(tmp_primitives.begin() + 1); // erase 2nd element
118  } else if (tmp_primitives.size() == 3) {
119  edm::LogWarning("L1T") << "EMTF found 3 CSC LCTs in one chamber: keeping only two";
120  tmp_primitives.erase(tmp_primitives.begin() + 2); // erase 3rd element
121  }
122  if (not(tmp_primitives.size() <= 2)) // at most 2 hits
123  { edm::LogError("L1T") << "tmp_primitives.size() = " << tmp_primitives.size() ; return; }
124 
125  if (tmp_primitives.size() == 2) {
126  if (
127  (tmp_primitives.at(0).getStrip() != tmp_primitives.at(1).getStrip()) &&
128  (tmp_primitives.at(0).getWire() != tmp_primitives.at(1).getWire())
129  ) {
130  // Swap wire numbers
131  TriggerPrimitive tp0 = tmp_primitives.at(0); // (s1,w1)
132  TriggerPrimitive tp1 = tmp_primitives.at(1); // (s2,w2)
133  uint16_t tmp_keywire = tp0.accessCSCData().keywire;
134  tp0.accessCSCData().keywire = tp1.accessCSCData().keywire; // (s1,w2)
135  tp1.accessCSCData().keywire = tmp_keywire; // (s2,w1)
136 
137  tmp_primitives.insert(tmp_primitives.begin()+1, tp1); // (s2,w1) at 2nd pos
138  tmp_primitives.insert(tmp_primitives.begin()+2, tp0); // (s1,w2) at 3rd pos
139  }
140 
141  const bool is_csc_me11 = (0 <= selected && selected <= 2) || (9 <= selected && selected <= 11) || (selected == 45); // ME1/1 sub 1 or ME1/1 sub 2 or ME1/1 from neighbor
142 
143  if (bugME11Dupes_ && is_csc_me11) {
144  // For ME1/1, always make 4 LCTs without checking strip & wire combination
145  if (tmp_primitives.size() == 2) {
146  // Swap wire numbers
147  TriggerPrimitive tp0 = tmp_primitives.at(0); // (s1,w1)
148  TriggerPrimitive tp1 = tmp_primitives.at(1); // (s2,w2)
149  uint16_t tmp_keywire = tp0.accessCSCData().keywire;
150  tp0.accessCSCData().keywire = tp1.accessCSCData().keywire; // (s1,w2)
151  tp1.accessCSCData().keywire = tmp_keywire; // (s2,w1)
152 
153  tmp_primitives.insert(tmp_primitives.begin()+1, tp1); // (s2,w1) at 2nd pos
154  tmp_primitives.insert(tmp_primitives.begin()+2, tp0); // (s1,w2) at 3rd pos
155  }
156  if (not(tmp_primitives.size() == 1 || tmp_primitives.size() == 4))
157  { edm::LogError("L1T") << "tmp_primitives.size() = " << tmp_primitives.size(); return; }
158  }
159 
160  } // end if tmp_primitives.size() == 2
161  } // end loop over selected_csc_map
162  } // end if duplicate theta
163 }
164 
165 
166 // _____________________________________________________________________________
167 // Specialized process() for RPC
168 template<>
170  RPCTag tag,
171  const TriggerPrimitiveCollection& muon_primitives,
172  std::map<int, TriggerPrimitiveCollection>& selected_rpc_map
173 ) const {
174  TriggerPrimitiveCollection::const_iterator tp_it = muon_primitives.begin();
175  TriggerPrimitiveCollection::const_iterator tp_end = muon_primitives.end();
176 
177  for (; tp_it != tp_end; ++tp_it) {
178  int selected_rpc = select_rpc(*tp_it); // Returns RPC "link" index (0 - 41)
179 
180  if (selected_rpc >= 0) {
181  if (not(selected_rpc < NUM_RPC_CHAMBERS))
182  { edm::LogError("L1T") << "selected_rpc = " << selected_rpc << ", NUM_RPC_CHAMBERS = " << NUM_RPC_CHAMBERS; return; }
183  selected_rpc_map[selected_rpc].push_back(*tp_it);
184  }
185  }
186 
187  // Apply truncation as in firmware: keep first 2 clusters, max cluster
188  // size = 3 strips.
189  // According to Karol Bunkowski, for one chamber (so 3 eta rolls) only up
190  // to 2 hits (cluster centres) are produced. First two 'first' clusters are
191  // chosen, and only after the cut on the cluster size is applied. So if
192  // there are 1 large cluster and 2 small clusters, it is possible that
193  // one of the two small clusters is discarded first, and the large cluster
194  // then is removed by the cluster size cut, leaving only one cluster.
195  bool apply_truncation = true;
196  if (apply_truncation) {
197  struct {
199  bool operator()(const value_type& x) const {
200  int sz = x.getRPCData().strip_hi - x.getRPCData().strip_low + 1;
201  return sz > 3;
202  }
203  } cluster_size_cut;
204 
205  std::map<int, TriggerPrimitiveCollection>::iterator map_tp_it = selected_rpc_map.begin();
206  std::map<int, TriggerPrimitiveCollection>::iterator map_tp_end = selected_rpc_map.end();
207 
208  for (; map_tp_it != map_tp_end; ++map_tp_it) {
209  //int selected = map_tp_it->first;
210  TriggerPrimitiveCollection& tmp_primitives = map_tp_it->second; // pass by reference
211 
212  // Check to see if unpacked CPPF digis have <= 2 digis per chamber, as expected
213  if (tmp_primitives.size() > 2 && tmp_primitives.at(0).getRPCData().isCPPF) {
214  edm::LogWarning("L1T") << "\n******************* EMTF EMULATOR: SUPER-BIZZARE CASE *******************";
215  edm::LogWarning("L1T") << "Found " << tmp_primitives.size() << " CPPF digis in the same chamber";
216  for (const auto & tp : tmp_primitives) tp.print(std::cout);
217  edm::LogWarning("L1T") << "************************* ONLY KEEP FIRST TWO *************************\n\n";
218  }
219 
220  // Keep the first two clusters
221  if (tmp_primitives.size() > 2)
222  tmp_primitives.erase(tmp_primitives.begin()+2, tmp_primitives.end());
223 
224  // Skip cluster size cut if primitives are from CPPF emulator or EMTF unpacker (already clustered)
225  if (!tmp_primitives.empty() && tmp_primitives.at(0).getRPCData().isCPPF)
226  break;
227 
228  // Apply cluster size cut
229  tmp_primitives.erase(
230  std::remove_if(tmp_primitives.begin(), tmp_primitives.end(), cluster_size_cut),
231  tmp_primitives.end()
232  );
233  }
234  } // end if apply_truncation
235 
236  // Map RPC subsector and chamber to CSC chambers
237  // Note: RE3/2 & RE3/3 are considered as one chamber; RE4/2 & RE4/3 too.
238  bool map_rpc_to_csc = true;
239  if (map_rpc_to_csc) {
240  std::map<int, TriggerPrimitiveCollection> tmp_selected_rpc_map;
241 
242  std::map<int, TriggerPrimitiveCollection>::iterator map_tp_it = selected_rpc_map.begin();
243  std::map<int, TriggerPrimitiveCollection>::iterator map_tp_end = selected_rpc_map.end();
244 
245  for (; map_tp_it != map_tp_end; ++map_tp_it) {
246  int selected = map_tp_it->first;
247  TriggerPrimitiveCollection& tmp_primitives = map_tp_it->second; // pass by reference
248 
249  int rpc_sub = selected / 8;
250  int rpc_chm = selected % 8;
251 
252  int pc_station = -1;
253  int pc_chamber = -1;
254 
255  if (rpc_sub != 6) { // native
256  if (rpc_chm == 0) { // RE1/2
257  if (0 <= rpc_sub && rpc_sub < 3) {
258  pc_station = 0;
259  pc_chamber = 3 + rpc_sub;
260  } else if (3 <= rpc_sub && rpc_sub < 6) {
261  pc_station = 1;
262  pc_chamber = 3 + (rpc_sub - 3);
263  }
264  } else if (rpc_chm == 1) { // RE2/2
265  pc_station = 2;
266  pc_chamber = 3 + rpc_sub;
267  } else if (2 <= rpc_chm && rpc_chm <= 3) { // RE3/2, RE3/3
268  pc_station = 3;
269  pc_chamber = 3 + rpc_sub;
270  } else if (4 <= rpc_chm && rpc_chm <= 5) { // RE4/2, RE4/3
271  pc_station = 4;
272  pc_chamber = 3 + rpc_sub;
273  }
274 
275  } else { // neighbor
276  pc_station = 5;
277  if (rpc_chm == 0) { // RE1/2
278  pc_chamber = 1;
279  } else if (rpc_chm == 1) { // RE2/2
280  pc_chamber = 4;
281  } else if (2 <= rpc_chm && rpc_chm <= 3) { // RE3/2, RE3/3
282  pc_chamber = 6;
283  } else if (4 <= rpc_chm && rpc_chm <= 5) { // RE4/2, RE4/3
284  pc_chamber = 8;
285  }
286  }
287 
288  if (not(pc_station != -1 && pc_chamber != -1))
289  { edm::LogError("L1T") << "pc_station = " << pc_station << ", pc_chamber = " << pc_chamber; return; }
290 
291  selected = (pc_station * 9) + pc_chamber;
292 
293  bool ignore_this_rpc_chm = false;
294  if (rpc_chm == 3 || rpc_chm == 5) { // special case of RE3,4/2 and RE3,4/3 chambers
295  // if RE3,4/2 exists, ignore RE3,4/3. In C++, this assumes that the loop
296  // over selected_rpc_map will always find RE3,4/2 before RE3,4/3
297  if (tmp_selected_rpc_map.find(selected) != tmp_selected_rpc_map.end())
298  ignore_this_rpc_chm = true;
299  }
300 
301  if (ignore_this_rpc_chm) {
302  // Set RPC stubs as invalid
303  for (auto&& tp : tmp_primitives) {
304  tp.accessRPCData().valid = 0;
305  }
306  }
307 
308  if (tmp_selected_rpc_map.find(selected) == tmp_selected_rpc_map.end()) {
309  tmp_selected_rpc_map[selected] = tmp_primitives;
310  } else {
311  tmp_selected_rpc_map[selected].insert(tmp_selected_rpc_map[selected].end(), tmp_primitives.begin(), tmp_primitives.end());
312  }
313  } // end loop over selected_rpc_map
314 
315  std::swap(selected_rpc_map, tmp_selected_rpc_map); // replace the original map
316  } // end if map_rpc_to_csc
317 }
318 
319 
320 // _____________________________________________________________________________
321 // Specialized process() for GEM
322 template<>
324  GEMTag tag,
325  const TriggerPrimitiveCollection& muon_primitives,
326  std::map<int, TriggerPrimitiveCollection>& selected_gem_map
327 ) const {
328  TriggerPrimitiveCollection::const_iterator tp_it = muon_primitives.begin();
329  TriggerPrimitiveCollection::const_iterator tp_end = muon_primitives.end();
330 
331  for (; tp_it != tp_end; ++tp_it) {
332  int selected_gem = select_gem(*tp_it); // Returns GEM "link" index (0 - 53)
333 
334  if (selected_gem >= 0) {
335  if (not(selected_gem < NUM_GEM_CHAMBERS))
336  { edm::LogError("L1T") << "selected_gem = " << selected_gem << ", NUM_GEM_CHAMBERS = " << NUM_GEM_CHAMBERS; return; }
337  selected_gem_map[selected_gem].push_back(*tp_it);
338  }
339  }
340 
341  // Apply truncation: max cluster size = 8 pads, keep first 8 clusters.
342  bool apply_truncation = true;
343  if (apply_truncation) {
344  struct {
346  bool operator()(const value_type& x) const {
347  int sz = x.getGEMData().pad_hi - x.getGEMData().pad_low + 1;
348  return sz > 8;
349  }
350  } cluster_size_cut;
351 
352  std::map<int, TriggerPrimitiveCollection>::iterator map_tp_it = selected_gem_map.begin();
353  std::map<int, TriggerPrimitiveCollection>::iterator map_tp_end = selected_gem_map.end();
354 
355  for (; map_tp_it != map_tp_end; ++map_tp_it) {
356  //int selected = map_tp_it->first;
357  TriggerPrimitiveCollection& tmp_primitives = map_tp_it->second; // pass by reference
358 
359  // Apply cluster size cut
360  tmp_primitives.erase(
361  std::remove_if(tmp_primitives.begin(), tmp_primitives.end(), cluster_size_cut),
362  tmp_primitives.end()
363  );
364 
365  // Keep the first 8 clusters
366  if (tmp_primitives.size() > 8)
367  tmp_primitives.erase(tmp_primitives.begin()+8, tmp_primitives.end());
368  }
369  } // end if apply_truncation
370 }
371 
372 
373 // _____________________________________________________________________________
374 // Put the hits from CSC, RPC, GEM together in one collection
375 
376 // Notes from Alex (2017-03-28):
377 //
378 // The RPC inclusion logic is very simple currently:
379 // - each CSC is analyzed for having track stubs in each BX
380 // - IF a CSC chamber is missing at least one track stub,
381 // AND there is an RPC overlapping with it in phi and theta,
382 // AND that RPC has hits,
383 // THEN RPC hit is inserted instead of missing CSC stub.
384 //
385 // This is done at the output of coord_delay module, so such
386 // inserted RPC hits can be matched to patterns by match_ph_segments
387 // module, just like any CSC stubs. Note that substitution of missing
388 // CSC stubs with RPC hits happens regardless of what's going on in
389 // other chambers, regardless of whether a pattern has been detected
390 // or not, basically regardless of anything. RPCs are treated as a
391 // supplemental source of stubs for CSCs.
392 
394  const std::map<int, TriggerPrimitiveCollection>& selected_csc_map,
395  const std::map<int, TriggerPrimitiveCollection>& selected_rpc_map,
396  const std::map<int, TriggerPrimitiveCollection>& selected_gem_map,
397  std::map<int, TriggerPrimitiveCollection>& selected_prim_map
398 ) const {
399  // First, put CSC hits
400  std::map<int, TriggerPrimitiveCollection>::const_iterator map_tp_it = selected_csc_map.begin();
401  std::map<int, TriggerPrimitiveCollection>::const_iterator map_tp_end = selected_csc_map.end();
402 
403  for (; map_tp_it != map_tp_end; ++map_tp_it) {
404  int selected_csc = map_tp_it->first;
405  const TriggerPrimitiveCollection& csc_primitives = map_tp_it->second;
406  if (not(csc_primitives.size() <= 4)) // at most 4 hits, including duplicated hits
407  { edm::LogError("L1T") << "csc_primitives.size() = " << csc_primitives.size(); return; }
408 
409  // Insert all CSC hits
410  selected_prim_map[selected_csc] = csc_primitives;
411  }
412 
413  // Second, insert GEM stubs if there is no CSC hits
414  map_tp_it = selected_gem_map.begin();
415  map_tp_end = selected_gem_map.end();
416 
417  for (; map_tp_it != map_tp_end; ++map_tp_it) {
418  int selected_gem = map_tp_it->first;
419  const TriggerPrimitiveCollection& gem_primitives = map_tp_it->second;
420  if (gem_primitives.empty()) continue;
421  if (not(gem_primitives.size() <= 8)) // at most 8 hits
422  { edm::LogError("L1T") << "gem_primitives.size() = " << gem_primitives.size(); return; }
423 
424  bool found = (selected_prim_map.find(selected_gem) != selected_prim_map.end());
425  if (!found) {
426  // No CSC hits, insert all GEM hits
427  selected_prim_map[selected_gem] = gem_primitives;
428 
429  } else {
430  // Do nothing
431  }
432  }
433 
434  // Third, insert RPC stubs if there is no CSC/GEM hits
435  map_tp_it = selected_rpc_map.begin();
436  map_tp_end = selected_rpc_map.end();
437 
438  for (; map_tp_it != map_tp_end; ++map_tp_it) {
439  int selected_rpc = map_tp_it->first;
440  const TriggerPrimitiveCollection& rpc_primitives = map_tp_it->second;
441  if (rpc_primitives.empty()) continue;
442  if (not(rpc_primitives.size() <= 4)) // at most 4 hits
443  { edm::LogError("L1T") << "rpc_primitives.size() = " << rpc_primitives.size(); return; }
444 
445  bool found = (selected_prim_map.find(selected_rpc) != selected_prim_map.end());
446  if (!found) {
447  // No CSC/GEM hits, insert all RPC hits
448  //selected_prim_map[selected_rpc] = rpc_primitives;
449 
450  // No CSC/GEM hits, insert the valid RPC hits
451  TriggerPrimitiveCollection tmp_rpc_primitives;
452  for (const auto& tp : rpc_primitives) {
453  if (tp.getRPCData().valid != 0) {
454  tmp_rpc_primitives.push_back(tp);
455  }
456  }
457  if (not(tmp_rpc_primitives.size() <= 2)) // at most 2 hits
458  { edm::LogError("L1T") << "tmp_rpc_primitives.size() = " << tmp_rpc_primitives.size(); return; }
459 
460  selected_prim_map[selected_rpc] = tmp_rpc_primitives;
461 
462  } else {
463  // Initial FW in 2017; was disabled on June 7.
464  // If only one CSC/GEM hit, insert the first RPC hit
465  //TriggerPrimitiveCollection& tmp_primitives = selected_prim_map[selected_rpc]; // pass by reference
466 
467  //if (tmp_primitives.size() < 2) {
468  // tmp_primitives.push_back(rpc_primitives.front());
469  //}
470  }
471  }
472 }
473 
475  const std::map<int, TriggerPrimitiveCollection>& selected_csc_map,
476  const std::map<int, TriggerPrimitiveCollection>& selected_rpc_map,
477  const std::map<int, TriggerPrimitiveCollection>& selected_gem_map,
478  std::map<int, TriggerPrimitiveCollection>& selected_prim_map
479 ) const {
480  // First, put CSC hits
481  merge_map_into_map(selected_csc_map, selected_prim_map);
482 
483  // Second, insert GEM hits
484  merge_map_into_map(selected_gem_map, selected_prim_map);
485 
486  // Third, insert RPC hits
487  merge_map_into_map(selected_rpc_map, selected_prim_map);
488 }
489 
490 
491 // _____________________________________________________________________________
492 // CSC functions
493 int PrimitiveSelection::select_csc(const TriggerPrimitive& muon_primitive) const {
494  int selected = -1;
495 
496  if (muon_primitive.subsystem() == TriggerPrimitive::kCSC) {
497  const CSCDetId& tp_detId = muon_primitive.detId<CSCDetId>();
498  const CSCData& tp_data = muon_primitive.getCSCData();
499 
500  int tp_endcap = tp_detId.endcap();
501  int tp_sector = tp_detId.triggerSector();
502  int tp_station = tp_detId.station();
503  int tp_ring = tp_detId.ring();
504  int tp_chamber = tp_detId.chamber();
505 
506  int tp_bx = tp_data.bx;
507  int tp_csc_ID = tp_data.cscID;
508 
509  if ( !(emtf::MIN_ENDCAP <= tp_endcap && tp_endcap <= emtf::MAX_ENDCAP) ) {
510  edm::LogWarning("L1T") << "EMTF CSC format error: tp_endcap = " << tp_endcap; return selected; }
511  if ( !(emtf::MIN_TRIGSECTOR <= tp_sector && tp_sector <= emtf::MAX_TRIGSECTOR) ) {
512  edm::LogWarning("L1T") << "EMTF CSC format error: tp_sector = " << tp_sector; return selected; }
513  if ( !(1 <= tp_station && tp_station <= 4) ) {
514  edm::LogWarning("L1T") << "EMTF CSC format error: tp_station = " << tp_station; return selected; }
515  if ( !(1 <= tp_csc_ID && tp_csc_ID <= 9) ) {
516  edm::LogWarning("L1T") << "EMTF CSC format error: tp_csc_ID = " << tp_csc_ID; return selected; }
517  if ( !(tp_data.valid == true) ) {
518  edm::LogWarning("L1T") << "EMTF CSC format error: tp_data.valid = " << tp_data.valid ; return selected; }
519  if ( !(tp_data.pattern <= 10) ) {
520  edm::LogWarning("L1T") << "EMTF CSC format error: tp_data.pattern = " << tp_data.pattern; return selected; }
521  if ( !(tp_data.quality > 0) ) {
522  edm::LogWarning("L1T") << "EMTF CSC format error: tp_data.quality = " << tp_data.quality; return selected; }
523 
524  int max_strip = 0;
525  int max_wire = 0;
526  if (tp_station == 1 && tp_ring == 4) { // ME1/1a
527  max_strip = 96;
528  max_wire = 48;
529  } else if (tp_station == 1 && tp_ring == 1) { // ME1/1b
530  max_strip = 128;
531  max_wire = 48;
532  } else if (tp_station == 1 && tp_ring == 2) { // ME1/2
533  max_strip = 160;
534  max_wire = 64;
535  } else if (tp_station == 1 && tp_ring == 3) { // ME1/3
536  max_strip = 128;
537  max_wire = 32;
538  } else if (tp_station == 2 && tp_ring == 1) { // ME2/1
539  max_strip = 160;
540  max_wire = 112;
541  } else if (tp_station >= 3 && tp_ring == 1) { // ME3/1, ME4/1
542  max_strip = 160;
543  max_wire = 96;
544  } else if (tp_station >= 2 && tp_ring == 2) { // ME2/2, ME3/2, ME4/2
545  max_strip = 160;
546  max_wire = 64;
547  }
548 
549  if ( !(tp_data.strip < max_strip) ) {
550  edm::LogWarning("L1T") << "EMTF CSC format error in station " << tp_station << ", ring " << tp_ring
551  << ": tp_data.strip = " << tp_data.strip << " (max = " << max_strip - 1 << ")" << std::endl;
552  return selected; }
553  if ( !(tp_data.keywire < max_wire) ) {
554  edm::LogWarning("L1T") << "EMTF CSC format error in station " << tp_station << ", ring " << tp_ring
555  << ": tp_data.keywire = " << tp_data.keywire << " (max = " << max_wire - 1 << ")" << std::endl;
556  return selected; }
557 
558 
559  // station 1 --> subsector 1 or 2
560  // station 2,3,4 --> subsector 0
561  int tp_subsector = (tp_station != 1) ? 0 : ((tp_chamber%6 > 2) ? 1 : 2);
562 
563  // Selection
564  if (is_in_bx_csc(tp_bx)) {
565  if (is_in_sector_csc(tp_endcap, tp_sector)) {
566  selected = get_index_csc(tp_subsector, tp_station, tp_csc_ID, false);
567  } else if (is_in_neighbor_sector_csc(tp_endcap, tp_sector, tp_subsector, tp_station, tp_csc_ID)) {
568  selected = get_index_csc(tp_subsector, tp_station, tp_csc_ID, true);
569  }
570  }
571  }
572  return selected;
573 }
574 
575 bool PrimitiveSelection::is_in_sector_csc(int tp_endcap, int tp_sector) const {
576  return ((endcap_ == tp_endcap) && (sector_ == tp_sector));
577 }
578 
579 bool PrimitiveSelection::is_in_neighbor_sector_csc(int tp_endcap, int tp_sector, int tp_subsector, int tp_station, int tp_csc_ID) const {
580  auto get_neighbor = [](int sector) {
581  return (sector == 1) ? 6 : sector - 1;
582  };
583 
584  if (includeNeighbor_) {
585  if ((endcap_ == tp_endcap) && (get_neighbor(sector_) == tp_sector)) {
586  if (tp_station == 1) {
587  if ((tp_subsector == 2) && (tp_csc_ID == 3 || tp_csc_ID == 6 || tp_csc_ID == 9))
588  return true;
589 
590  } else {
591  if (tp_csc_ID == 3 || tp_csc_ID == 9)
592  return true;
593  }
594  }
595  }
596  return false;
597 }
598 
599 bool PrimitiveSelection::is_in_bx_csc(int tp_bx) const {
600  tp_bx += bxShiftCSC_;
601  return (bx_ == tp_bx);
602 }
603 
604 // Returns CSC input "link". Index used by FW for unique chamber identification.
605 int PrimitiveSelection::get_index_csc(int tp_subsector, int tp_station, int tp_csc_ID, bool is_neighbor) const {
606  int selected = -1;
607 
608  if (!is_neighbor) {
609  if (tp_station == 1) { // ME1: 0 - 8, 9 - 17
610  selected = (tp_subsector-1) * 9 + (tp_csc_ID-1);
611  } else { // ME2,3,4: 18 - 26, 27 - 35, 36 - 44
612  selected = (tp_station) * 9 + (tp_csc_ID-1);
613  }
614 
615  } else {
616  if (tp_station == 1) { // ME1: 45 - 47
617  selected = (5) * 9 + (tp_csc_ID-1)/3;
618  } else { // ME2,3,4: 48 - 53
619  selected = (5) * 9 + (tp_station) * 2 - 1 + (tp_csc_ID-1 < 3 ? 0 : 1);
620  }
621  }
622  return selected;
623 }
624 
625 
626 // _____________________________________________________________________________
627 // RPC functions
628 int PrimitiveSelection::select_rpc(const TriggerPrimitive& muon_primitive) const {
629  int selected = -1;
630 
631  if (muon_primitive.subsystem() == TriggerPrimitive::kRPC) {
632  const RPCDetId& tp_detId = muon_primitive.detId<RPCDetId>();
633  const RPCData& tp_data = muon_primitive.getRPCData();
634 
635  int tp_region = tp_detId.region(); // 0 for Barrel, +/-1 for +/- Endcap
636  int tp_endcap = (tp_region == -1) ? 2 : tp_region;
637  int tp_sector = tp_detId.sector(); // 1 - 6 (60 degrees in phi, sector 1 begins at -5 deg)
638  int tp_subsector = tp_detId.subsector(); // 1 - 6 (10 degrees in phi; staggered in z)
639  int tp_station = tp_detId.station(); // 1 - 4
640  int tp_ring = tp_detId.ring(); // 2 - 3 (increasing theta)
641  int tp_roll = tp_detId.roll(); // 1 - 3 (decreasing theta; aka A - C; space between rolls is 9 - 15 in theta_fp)
642  //int tp_layer = tp_detId.layer();
643 
644  int tp_bx = tp_data.bx;
645  int tp_strip = tp_data.strip;
646  int tp_emtf_sect = tp_data.emtf_sector;
647  bool tp_CPPF = tp_data.isCPPF;
648 
649  // In neighbor chambers, have two separate CPPFDigis for the two EMTF sectors
650  if (tp_CPPF && (tp_emtf_sect != sector_)) return selected;
651 
652  if ( !(tp_region != 0) ) {
653  edm::LogWarning("L1T") << "EMTF RPC format error: tp_region = " << tp_region; return selected; }
654  if ( !(emtf::MIN_ENDCAP <= tp_endcap && tp_endcap <= emtf::MAX_ENDCAP) ) {
655  edm::LogWarning("L1T") << "EMTF RPC format error: tp_endcap = " << tp_endcap; return selected; }
656  if ( !(emtf::MIN_TRIGSECTOR <= tp_sector && tp_sector <= emtf::MAX_TRIGSECTOR) ) {
657  edm::LogWarning("L1T") << "EMTF RPC format error: tp_sector = " << tp_sector; return selected; }
658  if ( !(1 <= tp_subsector && tp_subsector <= 6) ) {
659  edm::LogWarning("L1T") << "EMTF RPC format error: tp_subsector = " << tp_subsector; return selected; }
660  if ( !(1 <= tp_station && tp_station <= 4) ) {
661  edm::LogWarning("L1T") << "EMTF RPC format error: tp_station = " << tp_station; return selected; }
662  if ( !(2 <= tp_ring && tp_ring <= 3) ) {
663  edm::LogWarning("L1T") << "EMTF RPC format error: tp_ring = " << tp_ring; return selected; }
664  if ( !(1 <= tp_roll && tp_roll <= 3) ) {
665  edm::LogWarning("L1T") << "EMTF RPC format error: tp_roll = " << tp_roll; return selected; }
666  if ( !(tp_CPPF || (1 <= tp_strip && tp_strip <= 32)) ) {
667  edm::LogWarning("L1T") << "EMTF RPC format error: tp_data.strip = " << tp_data.strip; return selected; }
668  if ( !(tp_station > 2 || tp_ring != 3) ) {
669  edm::LogWarning("L1T") << "EMTF RPC format error: tp_station = " << tp_station << ", tp_ring = " << tp_ring; return selected; }
670 
671 
672  // Selection
673  if (is_in_bx_rpc(tp_bx)) {
674  if (is_in_sector_rpc(tp_endcap, tp_station, tp_ring, tp_sector, tp_subsector)) {
675  selected = get_index_rpc(tp_station, tp_ring, tp_subsector, false);
676  } else if (is_in_neighbor_sector_rpc(tp_endcap, tp_station, tp_ring, tp_sector, tp_subsector)) {
677  selected = get_index_rpc(tp_station, tp_ring, tp_subsector, true);
678  }
679  }
680  }
681  return selected;
682 }
683 
684 bool PrimitiveSelection::is_in_sector_rpc(int tp_endcap, int tp_station, int tp_ring, int tp_sector, int tp_subsector) const {
685  // RPC sector X, subsectors 1-2 corresponds to CSC sector X-1
686  // RPC sector X, subsectors 3-6 corresponds to CSC sector X
687  auto get_csc_sector = [](int tp_station, int tp_ring, int tp_sector, int tp_subsector) {
688  // 10 degree chamber
689  int corr = (tp_subsector < 3) ? (tp_sector == 1 ? +5 : -1) : 0;
690  return tp_sector + corr;
691  };
692  return ((endcap_ == tp_endcap) && (sector_ == get_csc_sector(tp_station, tp_ring, tp_sector, tp_subsector)));
693 }
694 
695 bool PrimitiveSelection::is_in_neighbor_sector_rpc(int tp_endcap, int tp_station, int tp_ring, int tp_sector, int tp_subsector) const {
696  auto get_csc_neighbor_subsector = [](int tp_station, int tp_ring) {
697  // 10 degree chamber
698  return 2;
699  };
700  return (includeNeighbor_ && (endcap_ == tp_endcap) && (sector_ == tp_sector) && (tp_subsector == get_csc_neighbor_subsector(tp_station, tp_ring)));
701 }
702 
703 bool PrimitiveSelection::is_in_bx_rpc(int tp_bx) const {
704  tp_bx += bxShiftRPC_;
705  return (bx_ == tp_bx);
706 }
707 
708 int PrimitiveSelection::get_index_rpc(int tp_station, int tp_ring, int tp_subsector, bool is_neighbor) const {
709  int selected = -1;
710 
711  // CPPF RX data come in 3 frames x 64 bits, for 7 links. Each 64-bit data
712  // carry 2 words of 32 bits. Each word carries phi (11 bits) and theta (5 bits)
713  // of 2 segments (x2).
714  //
715  // Firmware uses 'rpc_sub' as RPC subsector index and 'rpc_chm' as RPC chamber index
716  // rpc_sub [0,6] = RPC subsector 3, 4, 5, 6, 1 from neighbor, 2 from neighbor, 2. They correspond to
717  // CSC sector phi 0-10 deg, 10-20, 20-30, 30-40, 40-50, 50-60, 50-60 from neighbor
718  // rpc_chm [0,5] = RPC chamber RE1/2, RE2/2, RE3/2, RE3/3, RE4/2, RE4/3
719  //
720  int rpc_sub = -1;
721  int rpc_chm = -1;
722 
723  if (!is_neighbor) {
724  rpc_sub = ((tp_subsector + 3) % 6);
725  } else {
726  rpc_sub = 6;
727  }
728 
729  if (tp_station <= 2) {
730  rpc_chm = (tp_station - 1);
731  } else {
732  rpc_chm = 2 + (tp_station - 3)*2 + (tp_ring - 2);
733  }
734 
735  if (not(rpc_sub != -1 && rpc_chm != -1))
736  { edm::LogError("L1T") << "rpc_sub = " << rpc_sub << ", rpc_chm = " << rpc_chm; return selected; }
737 
738  selected = (rpc_sub * 8) + rpc_chm;
739  return selected;
740 }
741 
742 
743 // _____________________________________________________________________________
744 // GEM functions
745 int PrimitiveSelection::select_gem(const TriggerPrimitive& muon_primitive) const {
746  int selected = -1;
747 
748  if (muon_primitive.subsystem() == TriggerPrimitive::kGEM) {
749  const EMTFGEMDetId& tp_detId = emtf::construct_EMTFGEMDetId(muon_primitive);
750  const GEMData& tp_data = muon_primitive.getGEMData();
751 
752  int tp_region = tp_detId.region(); // 0 for Barrel, +/-1 for +/- Endcap
753  int tp_endcap = (tp_region == -1) ? 2 : tp_region;
754  int tp_station = tp_detId.station();
755  int tp_ring = tp_detId.ring();
756  int tp_roll = tp_detId.roll();
757  int tp_layer = tp_detId.layer();
758  int tp_chamber = tp_detId.chamber();
759 
760  int tp_bx = tp_data.bx;
761  int tp_pad = tp_data.pad;
762 
763  // Use CSC trigger sector definitions
764  // Code copied from DataFormats/MuonDetId/src/CSCDetId.cc
765  auto get_trigger_sector = [](int ring, int station, int chamber) {
766  int result = 0;
767  if( station > 1 && ring > 1 ) {
768  result = ((static_cast<unsigned>(chamber-3) & 0x7f) / 6) + 1; // ch 3-8->1, 9-14->2, ... 1,2 -> 6
769  }
770  else if( station == 1 && ring != 4 ) {
771  result = ((static_cast<unsigned>(chamber-3) & 0x7f) / 6) + 1; // ch 3-8->1, 9-14->2, ... 1,2 -> 6
772  }
773  else {
774  result = ((static_cast<unsigned>(chamber-2) & 0x1f) / 3) + 1; // ch 2-4-> 1, 5-7->2, ...
775  }
776  return (result <= 6) ? result : 6; // max sector is 6, some calculations give a value greater than six but this is expected.
777  };
778 
779  // Use CSC trigger "CSC ID" definitions
780  // Code copied from DataFormats/MuonDetId/src/CSCDetId.cc
781  auto get_trigger_csc_ID = [](int ring, int station, int chamber) {
782  int result = 0;
783  if( station == 1 ) {
784  result = (chamber) % 3 + 1; // 1,2,3
785  switch (ring) {
786  case 1:
787  break;
788  case 2:
789  result += 3; // 4,5,6
790  break;
791  case 3:
792  result += 6; // 7,8,9
793  break;
794  }
795  }
796  else {
797  if( ring == 1 ) {
798  result = (chamber+1) % 3 + 1; // 1,2,3
799  }
800  else {
801  result = (chamber+3) % 6 + 4; // 4,5,6,7,8,9
802  }
803  }
804  return result;
805  };
806 
807  int tp_sector = get_trigger_sector(tp_ring, tp_station, tp_chamber);
808  int tp_csc_ID = get_trigger_csc_ID(tp_ring, tp_station, tp_chamber);
809 
810  // station 1 --> subsector 1 or 2
811  // station 2,3,4 --> subsector 0
812  int tp_subsector = (tp_station != 1) ? 0 : ((tp_chamber%6 > 2) ? 1 : 2);
813 
814 
815  if ( !(emtf::MIN_ENDCAP <= tp_endcap && tp_endcap <= emtf::MAX_ENDCAP) ) {
816  edm::LogWarning("L1T") << "EMTF GEM format error: tp_endcap = " << tp_endcap; return selected; }
817  if ( !(emtf::MIN_TRIGSECTOR <= tp_sector && tp_sector <= emtf::MAX_TRIGSECTOR) ) {
818  edm::LogWarning("L1T") << "EMTF GEM format error: tp_sector = " << tp_sector; return selected; }
819  if ( !(1 <= tp_station && tp_station <= 2) ) {
820  edm::LogWarning("L1T") << "EMTF GEM format error: tp_station = " << tp_station; return selected; }
821  if ( !(1 <= tp_ring && tp_ring <= 1) ) {
822  edm::LogWarning("L1T") << "EMTF GEM format error: tp_ring = " << tp_ring; return selected; }
823  if ( !(1 <= tp_csc_ID && tp_csc_ID <= 9) ) {
824  edm::LogWarning("L1T") << "EMTF GEM format error: tp_csc_ID = " << tp_csc_ID; return selected; }
825  if (!(tp_station == 1 && 1 <= tp_roll && tp_roll <= 8) || (tp_station != 1)) {
826  edm::LogWarning("L1T") << "EMTF GEM format error: tp_station = " << tp_station
827  << ", tp_roll = " << tp_roll; return selected; }
828  if ( !(tp_station == 2 && 1 <= tp_roll && tp_roll <= 12) || (tp_station != 2)) {
829  edm::LogWarning("L1T") << "EMTF GEM format error: tp_station = " << tp_station
830  << ", tp_roll = " << tp_roll; return selected; }
831  if ( !(1 <= tp_layer && tp_layer <= 2)) {
832  edm::LogWarning("L1T") << "EMTF GEM format error: tp_layer = " << tp_layer; return selected; }
833  if ( !((tp_station == 1 && 1 <= tp_pad && tp_pad <= 192) || (tp_station != 1))) {
834  edm::LogWarning("L1T") << "EMTF GEM format error: tp_station = " << tp_station
835  << ", tp_pad = " << tp_pad; return selected; }
836  if ( !((tp_station == 2 && 1 <= tp_pad && tp_pad <= 192) || (tp_station != 2))) {
837  edm::LogWarning("L1T") << "EMTF GEM format error: tp_station = " << tp_station
838  << ", tp_pad = " << tp_pad; return selected; }
839 
840  // Selection
841  if (is_in_bx_gem(tp_bx)) {
842  if (is_in_sector_gem(tp_endcap, tp_sector)) {
843  selected = get_index_gem(tp_subsector, tp_station, tp_csc_ID, false);
844  } else if (is_in_neighbor_sector_gem(tp_endcap, tp_sector, tp_subsector, tp_station, tp_csc_ID)) {
845  selected = get_index_gem(tp_subsector, tp_station, tp_csc_ID, true);
846  }
847  }
848  }
849  return selected;
850 }
851 
852 bool PrimitiveSelection::is_in_sector_gem(int tp_endcap, int tp_sector) const {
853  // Identical to the corresponding CSC function
854  return is_in_sector_csc(tp_endcap, tp_sector);
855 }
856 
857 bool PrimitiveSelection::is_in_neighbor_sector_gem(int tp_endcap, int tp_sector, int tp_subsector, int tp_station, int tp_csc_ID) const {
858  // Identical to the corresponding CSC function
859  return is_in_neighbor_sector_csc(tp_endcap, tp_sector, tp_subsector, tp_station, tp_csc_ID);
860 }
861 
862 bool PrimitiveSelection::is_in_bx_gem(int tp_bx) const {
863  tp_bx += bxShiftGEM_;
864  return (bx_ == tp_bx);
865 }
866 
867 int PrimitiveSelection::get_index_gem(int tp_subsector, int tp_station, int tp_csc_ID, bool is_neighbor) const {
868  // Identical to the corresponding CSC function
869  return get_index_csc(tp_subsector, tp_station, tp_csc_ID, is_neighbor);
870 }
size
Write out results.
int chamber() const
Definition: CSCDetId.h:68
int MAX_TRIGSECTOR
Definition: Common.h:63
const subsystem_type subsystem() const
bool is_in_sector_csc(int tp_endcap, int tp_sector) const
const GEMData getGEMData() const
#define NUM_GEM_CHAMBERS
int MIN_ENDCAP
Definition: Common.h:58
int get_index_gem(int tp_subsector, int tp_station, int tp_csc_ID, bool is_neighbor) const
#define NUM_RPC_CHAMBERS
const CSCData getCSCData() const
int select_gem(const TriggerPrimitive &muon_primitive) const
bool is_in_sector_gem(int tp_endcap, int tp_sector) const
void merge_no_truncate(const std::map< int, TriggerPrimitiveCollection > &selected_csc_map, const std::map< int, TriggerPrimitiveCollection > &selected_rpc_map, const std::map< int, TriggerPrimitiveCollection > &selected_gem_map, std::map< int, TriggerPrimitiveCollection > &selected_prim_map) const
const RPCData getRPCData() const
void configure(int verbose, int endcap, int sector, int bx, int bxShiftCSC, int bxShiftRPC, int bxShiftGEM, bool includeNeighbor, bool duplicateTheta, bool bugME11Dupes)
bool is_in_sector_rpc(int tp_endcap, int tp_station, int tp_ring, int tp_sector, int tp_subsector) const
int endcap() const
Definition: CSCDetId.h:93
int layer() const
Definition: EMTFGEMDetId.cc:55
bool is_in_bx_gem(int tp_bx) const
int roll() const
Definition: RPCDetId.h:120
static int verbose
int roll() const
Definition: EMTFGEMDetId.cc:69
int MIN_TRIGSECTOR
Definition: Common.h:62
int region() const
The identifiers.
Definition: EMTFGEMDetId.cc:32
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
int ring() const
Definition: RPCDetId.h:72
int select_rpc(const TriggerPrimitive &muon_primitive) const
int select_csc(const TriggerPrimitive &muon_primitive) const
void process(T tag, const TriggerPrimitiveCollection &muon_primitives, std::map< int, TriggerPrimitiveCollection > &selected_prim_map) const
#define end
Definition: vmac.h:39
bool is_in_neighbor_sector_csc(int tp_endcap, int tp_sector, int tp_subsector, int tp_station, int tp_csc_ID) const
int chamber() const
Definition: EMTFGEMDetId.cc:62
bool is_in_bx_csc(int tp_bx) const
int get_index_csc(int tp_subsector, int tp_station, int tp_csc_ID, bool is_neighbor) const
JetCorrectorParameters corr
Definition: classes.h:5
ii
Definition: cuy.py:590
int ring() const
Definition: CSCDetId.h:75
void merge(const std::map< int, TriggerPrimitiveCollection > &selected_csc_map, const std::map< int, TriggerPrimitiveCollection > &selected_rpc_map, const std::map< int, TriggerPrimitiveCollection > &selected_gem_map, std::map< int, TriggerPrimitiveCollection > &selected_prim_map) const
int station() const
Definition: EMTFGEMDetId.cc:47
bool is_in_bx_rpc(int tp_bx) const
L1TMuon::TriggerPrimitiveCollection TriggerPrimitiveCollection
Definition: Common.h:34
int triggerSector() const
Definition: CSCDetId.cc:3
int sector() const
Sector id: the group of chambers at same phi (and increasing r)
Definition: RPCDetId.h:102
int MAX_ENDCAP
Definition: Common.h:59
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
int station() const
Definition: CSCDetId.h:86
int get_index_rpc(int tp_station, int tp_ring, int tp_subsector, bool is_neighbor) const
EMTFGEMDetId construct_EMTFGEMDetId(const L1TMuon::TriggerPrimitive &tp)
#define NUM_CSC_CHAMBERS
Int_t triggerSector(Int_t station, Int_t ring, Int_t chamber) const
bool is_in_neighbor_sector_rpc(int tp_endcap, int tp_station, int tp_ring, int tp_sector, int tp_subsector) const
int ring() const
Definition: EMTFGEMDetId.cc:39
bool is_in_neighbor_sector_gem(int tp_endcap, int tp_sector, int tp_subsector, int tp_station, int tp_csc_ID) const
int region() const
Region id: 0 for Barrel, +/-1 For +/- Endcap.
Definition: RPCDetId.h:63
int station() const
Definition: RPCDetId.h:96