CMS 3D CMS Logo

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