CMS 3D CMS Logo

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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  // Keep the first two clusters
213  if (tmp_primitives.size() > 2)
214  tmp_primitives.erase(tmp_primitives.begin()+2, tmp_primitives.end());
215 
216  // Apply cluster size cut
217  tmp_primitives.erase(
218  std::remove_if(tmp_primitives.begin(), tmp_primitives.end(), cluster_size_cut),
219  tmp_primitives.end()
220  );
221  }
222  } // end if apply_truncation
223 
224  // Map RPC subsector and chamber to CSC chambers
225  // Note: RE3/2 & RE3/3 are considered as one chamber; RE4/2 & RE4/3 too.
226  bool map_rpc_to_csc = true;
227  if (map_rpc_to_csc) {
228  std::map<int, TriggerPrimitiveCollection> tmp_selected_rpc_map;
229 
230  std::map<int, TriggerPrimitiveCollection>::iterator map_tp_it = selected_rpc_map.begin();
231  std::map<int, TriggerPrimitiveCollection>::iterator map_tp_end = selected_rpc_map.end();
232 
233  for (; map_tp_it != map_tp_end; ++map_tp_it) {
234  int selected = map_tp_it->first;
235  TriggerPrimitiveCollection& tmp_primitives = map_tp_it->second; // pass by reference
236 
237  int rpc_sub = selected / 8;
238  int rpc_chm = selected % 8;
239 
240  int pc_station = -1;
241  int pc_chamber = -1;
242 
243  if (rpc_sub != 6) { // native
244  if (rpc_chm == 0) { // RE1/2
245  if (0 <= rpc_sub && rpc_sub < 3) {
246  pc_station = 0;
247  pc_chamber = 3 + rpc_sub;
248  } else if (3 <= rpc_sub && rpc_sub < 6) {
249  pc_station = 1;
250  pc_chamber = 3 + (rpc_sub - 3);
251  }
252  } else if (rpc_chm == 1) { // RE2/2
253  pc_station = 2;
254  pc_chamber = 3 + rpc_sub;
255  } else if (2 <= rpc_chm && rpc_chm <= 3) { // RE3/2, RE3/3
256  pc_station = 3;
257  pc_chamber = 3 + rpc_sub;
258  } else if (4 <= rpc_chm && rpc_chm <= 5) { // RE4/2, RE4/3
259  pc_station = 4;
260  pc_chamber = 3 + rpc_sub;
261  }
262 
263  } else { // neighbor
264  pc_station = 5;
265  if (rpc_chm == 0) { // RE1/2
266  pc_chamber = 1;
267  } else if (rpc_chm == 1) { // RE2/2
268  pc_chamber = 4;
269  } else if (2 <= rpc_chm && rpc_chm <= 3) { // RE3/2, RE3/3
270  pc_chamber = 6;
271  } else if (4 <= rpc_chm && rpc_chm <= 5) { // RE4/2, RE4/3
272  pc_chamber = 8;
273  }
274  }
275 
276  if (not(pc_station != -1 && pc_chamber != -1))
277  { edm::LogError("L1T") << "pc_station = " << pc_station << ", pc_chamber = " << pc_chamber; return; }
278 
279  selected = (pc_station * 9) + pc_chamber;
280 
281  bool ignore_this_rpc_chm = false;
282  if (rpc_chm == 3 || rpc_chm == 5) { // special case of RE3,4/2 and RE3,4/3 chambers
283  // if RE3,4/2 exists, ignore RE3,4/3. In C++, this assumes that the loop
284  // over selected_rpc_map will always find RE3,4/2 before RE3,4/3
285  if (tmp_selected_rpc_map.find(selected) != tmp_selected_rpc_map.end())
286  ignore_this_rpc_chm = true;
287  }
288 
289  if (ignore_this_rpc_chm) {
290  // Set RPC stubs as invalid
291  for (auto&& tp : tmp_primitives) {
292  tp.accessRPCData().valid = 0;
293  }
294  }
295 
296  if (tmp_selected_rpc_map.find(selected) == tmp_selected_rpc_map.end()) {
297  tmp_selected_rpc_map[selected] = tmp_primitives;
298  } else {
299  tmp_selected_rpc_map[selected].insert(tmp_selected_rpc_map[selected].end(), tmp_primitives.begin(), tmp_primitives.end());
300  }
301  } // end loop over selected_rpc_map
302 
303  std::swap(selected_rpc_map, tmp_selected_rpc_map); // replace the original map
304  } // end if map_rpc_to_csc
305 }
306 
307 
308 // _____________________________________________________________________________
309 // Specialized process() for GEM
310 template<>
312  GEMTag tag,
313  const TriggerPrimitiveCollection& muon_primitives,
314  std::map<int, TriggerPrimitiveCollection>& selected_gem_map
315 ) const {
316  TriggerPrimitiveCollection::const_iterator tp_it = muon_primitives.begin();
317  TriggerPrimitiveCollection::const_iterator tp_end = muon_primitives.end();
318 
319  for (; tp_it != tp_end; ++tp_it) {
320  int selected_gem = select_gem(*tp_it); // Returns GEM "link" index (0 - 53)
321 
322  if (selected_gem >= 0) {
323  if (not(selected_gem < NUM_GEM_CHAMBERS))
324  { edm::LogError("L1T") << "selected_gem = " << selected_gem << ", NUM_GEM_CHAMBERS = " << NUM_GEM_CHAMBERS; return; }
325  selected_gem_map[selected_gem].push_back(*tp_it);
326  }
327  }
328 
329  // Apply truncation: max cluster size = 8 pads, keep first 8 clusters.
330  bool apply_truncation = true;
331  if (apply_truncation) {
332  struct {
334  bool operator()(const value_type& x) const {
335  int sz = x.getGEMData().pad_hi - x.getGEMData().pad_low + 1;
336  return sz > 8;
337  }
338  } cluster_size_cut;
339 
340  std::map<int, TriggerPrimitiveCollection>::iterator map_tp_it = selected_gem_map.begin();
341  std::map<int, TriggerPrimitiveCollection>::iterator map_tp_end = selected_gem_map.end();
342 
343  for (; map_tp_it != map_tp_end; ++map_tp_it) {
344  //int selected = map_tp_it->first;
345  TriggerPrimitiveCollection& tmp_primitives = map_tp_it->second; // pass by reference
346 
347  // Apply cluster size cut
348  tmp_primitives.erase(
349  std::remove_if(tmp_primitives.begin(), tmp_primitives.end(), cluster_size_cut),
350  tmp_primitives.end()
351  );
352 
353  // Keep the first 8 clusters
354  if (tmp_primitives.size() > 8)
355  tmp_primitives.erase(tmp_primitives.begin()+8, tmp_primitives.end());
356  }
357  } // end if apply_truncation
358 }
359 
360 
361 // _____________________________________________________________________________
362 // Put the hits from CSC, RPC, GEM together in one collection
363 
364 // Notes from Alex (2017-03-28):
365 //
366 // The RPC inclusion logic is very simple currently:
367 // - each CSC is analyzed for having track stubs in each BX
368 // - IF a CSC chamber is missing at least one track stub,
369 // AND there is an RPC overlapping with it in phi and theta,
370 // AND that RPC has hits,
371 // THEN RPC hit is inserted instead of missing CSC stub.
372 //
373 // This is done at the output of coord_delay module, so such
374 // inserted RPC hits can be matched to patterns by match_ph_segments
375 // module, just like any CSC stubs. Note that substitution of missing
376 // CSC stubs with RPC hits happens regardless of what's going on in
377 // other chambers, regardless of whether a pattern has been detected
378 // or not, basically regardless of anything. RPCs are treated as a
379 // supplemental source of stubs for CSCs.
380 
382  const std::map<int, TriggerPrimitiveCollection>& selected_csc_map,
383  const std::map<int, TriggerPrimitiveCollection>& selected_rpc_map,
384  const std::map<int, TriggerPrimitiveCollection>& selected_gem_map,
385  std::map<int, TriggerPrimitiveCollection>& selected_prim_map
386 ) const {
387  // First, put CSC hits
388  std::map<int, TriggerPrimitiveCollection>::const_iterator map_tp_it = selected_csc_map.begin();
389  std::map<int, TriggerPrimitiveCollection>::const_iterator map_tp_end = selected_csc_map.end();
390 
391  for (; map_tp_it != map_tp_end; ++map_tp_it) {
392  int selected_csc = map_tp_it->first;
393  const TriggerPrimitiveCollection& csc_primitives = map_tp_it->second;
394  if (not(csc_primitives.size() <= 4)) // at most 4 hits, including duplicated hits
395  { edm::LogError("L1T") << "csc_primitives.size() = " << csc_primitives.size(); return; }
396 
397  // Insert all CSC hits
398  selected_prim_map[selected_csc] = csc_primitives;
399  }
400 
401  // Second, insert GEM stubs if there is no CSC hits
402  map_tp_it = selected_gem_map.begin();
403  map_tp_end = selected_gem_map.end();
404 
405  for (; map_tp_it != map_tp_end; ++map_tp_it) {
406  int selected_gem = map_tp_it->first;
407  const TriggerPrimitiveCollection& gem_primitives = map_tp_it->second;
408  if (gem_primitives.empty()) continue;
409  if (not(gem_primitives.size() <= 8)) // at most 8 hits
410  { edm::LogError("L1T") << "gem_primitives.size() = " << gem_primitives.size(); return; }
411 
412  bool found = (selected_prim_map.find(selected_gem) != selected_prim_map.end());
413  if (!found) {
414  // No CSC hits, insert all GEM hits
415  selected_prim_map[selected_gem] = gem_primitives;
416 
417  } else {
418  // Do nothing
419  }
420  }
421 
422  // Third, insert RPC stubs if there is no CSC/GEM hits
423  map_tp_it = selected_rpc_map.begin();
424  map_tp_end = selected_rpc_map.end();
425 
426  for (; map_tp_it != map_tp_end; ++map_tp_it) {
427  int selected_rpc = map_tp_it->first;
428  const TriggerPrimitiveCollection& rpc_primitives = map_tp_it->second;
429  if (rpc_primitives.empty()) continue;
430  if (not(rpc_primitives.size() <= 4)) // at most 4 hits
431  { edm::LogError("L1T") << "rpc_primitives.size() = " << rpc_primitives.size(); return; }
432 
433  bool found = (selected_prim_map.find(selected_rpc) != selected_prim_map.end());
434  if (!found) {
435  // No CSC/GEM hits, insert all RPC hits
436  //selected_prim_map[selected_rpc] = rpc_primitives;
437 
438  // No CSC/GEM hits, insert the valid RPC hits
439  TriggerPrimitiveCollection tmp_rpc_primitives;
440  for (const auto& tp : rpc_primitives) {
441  if (tp.getRPCData().valid != 0) {
442  tmp_rpc_primitives.push_back(tp);
443  }
444  }
445  if (not(rpc_primitives.size() <= 2)) // at most 2 hits
446  { edm::LogError("L1T") << "rpc_primitives.size() = " << rpc_primitives.size(); return; }
447  selected_prim_map[selected_rpc] = tmp_rpc_primitives;
448 
449  } else {
450  // Initial FW in 2017; was disabled on June 7.
451  // If only one CSC/GEM hit, insert the first RPC hit
452  //TriggerPrimitiveCollection& tmp_primitives = selected_prim_map[selected_rpc]; // pass by reference
453 
454  //if (tmp_primitives.size() < 2) {
455  // tmp_primitives.push_back(rpc_primitives.front());
456  //}
457  }
458  }
459 }
460 
462  const std::map<int, TriggerPrimitiveCollection>& selected_csc_map,
463  const std::map<int, TriggerPrimitiveCollection>& selected_rpc_map,
464  const std::map<int, TriggerPrimitiveCollection>& selected_gem_map,
465  std::map<int, TriggerPrimitiveCollection>& selected_prim_map
466 ) const {
467  // First, put CSC hits
468  merge_map_into_map(selected_csc_map, selected_prim_map);
469 
470  // Second, insert GEM hits
471  merge_map_into_map(selected_gem_map, selected_prim_map);
472 
473  // Third, insert RPC hits
474  merge_map_into_map(selected_rpc_map, selected_prim_map);
475 }
476 
477 
478 // _____________________________________________________________________________
479 // CSC functions
480 int PrimitiveSelection::select_csc(const TriggerPrimitive& muon_primitive) const {
481  int selected = -1;
482 
483  if (muon_primitive.subsystem() == TriggerPrimitive::kCSC) {
484  const CSCDetId& tp_detId = muon_primitive.detId<CSCDetId>();
485  const CSCData& tp_data = muon_primitive.getCSCData();
486 
487  int tp_endcap = tp_detId.endcap();
488  int tp_sector = tp_detId.triggerSector();
489  int tp_station = tp_detId.station();
490  int tp_ring = tp_detId.ring();
491  int tp_chamber = tp_detId.chamber();
492 
493  int tp_bx = tp_data.bx;
494  int tp_csc_ID = tp_data.cscID;
495 
496  if ( !(emtf::MIN_ENDCAP <= tp_endcap && tp_endcap <= emtf::MAX_ENDCAP) ) {
497  edm::LogWarning("L1T") << "EMTF CSC format error: tp_endcap = " << tp_endcap; return selected; }
498  if ( !(emtf::MIN_TRIGSECTOR <= tp_sector && tp_sector <= emtf::MAX_TRIGSECTOR) ) {
499  edm::LogWarning("L1T") << "EMTF CSC format error: tp_sector = " << tp_sector; return selected; }
500  if ( !(1 <= tp_station && tp_station <= 4) ) {
501  edm::LogWarning("L1T") << "EMTF CSC format error: tp_station = " << tp_station; return selected; }
502  if ( !(1 <= tp_csc_ID && tp_csc_ID <= 9) ) {
503  edm::LogWarning("L1T") << "EMTF CSC format error: tp_csc_ID = " << tp_csc_ID; return selected; }
504  if ( !(tp_data.valid == true) ) {
505  edm::LogWarning("L1T") << "EMTF CSC format error: tp_data.valid = " << tp_data.valid ; return selected; }
506  if ( !(tp_data.pattern <= 10) ) {
507  edm::LogWarning("L1T") << "EMTF CSC format error: tp_data.pattern = " << tp_data.pattern; return selected; }
508  if ( !(tp_data.quality > 0) ) {
509  edm::LogWarning("L1T") << "EMTF CSC format error: tp_data.quality = " << tp_data.quality; return selected; }
510 
511  int max_strip = 0;
512  int max_wire = 0;
513  if (tp_station == 1 && tp_ring == 4) { // ME1/1a
514  max_strip = 96;
515  max_wire = 48;
516  } else if (tp_station == 1 && tp_ring == 1) { // ME1/1b
517  max_strip = 128;
518  max_wire = 48;
519  } else if (tp_station == 1 && tp_ring == 2) { // ME1/2
520  max_strip = 160;
521  max_wire = 64;
522  } else if (tp_station == 1 && tp_ring == 3) { // ME1/3
523  max_strip = 128;
524  max_wire = 32;
525  } else if (tp_station == 2 && tp_ring == 1) { // ME2/1
526  max_strip = 160;
527  max_wire = 112;
528  } else if (tp_station >= 3 && tp_ring == 1) { // ME3/1, ME4/1
529  max_strip = 160;
530  max_wire = 96;
531  } else if (tp_station >= 2 && tp_ring == 2) { // ME2/2, ME3/2, ME4/2
532  max_strip = 160;
533  max_wire = 64;
534  }
535 
536  if ( !(tp_data.strip < max_strip) ) {
537  edm::LogWarning("L1T") << "EMTF CSC format error in station " << tp_station << ", ring " << tp_ring
538  << ": tp_data.strip = " << tp_data.strip << " (max = " << max_strip - 1 << ")" << std::endl;
539  return selected; }
540  if ( !(tp_data.keywire < max_wire) ) {
541  edm::LogWarning("L1T") << "EMTF CSC format error in station " << tp_station << ", ring " << tp_ring
542  << ": tp_data.keywire = " << tp_data.keywire << " (max = " << max_wire - 1 << ")" << std::endl;
543  return selected; }
544 
545 
546  // station 1 --> subsector 1 or 2
547  // station 2,3,4 --> subsector 0
548  int tp_subsector = (tp_station != 1) ? 0 : ((tp_chamber%6 > 2) ? 1 : 2);
549 
550  // Selection
551  if (is_in_bx_csc(tp_bx)) {
552  if (is_in_sector_csc(tp_endcap, tp_sector)) {
553  selected = get_index_csc(tp_subsector, tp_station, tp_csc_ID, false);
554  } else if (is_in_neighbor_sector_csc(tp_endcap, tp_sector, tp_subsector, tp_station, tp_csc_ID)) {
555  selected = get_index_csc(tp_subsector, tp_station, tp_csc_ID, true);
556  }
557  }
558  }
559  return selected;
560 }
561 
562 bool PrimitiveSelection::is_in_sector_csc(int tp_endcap, int tp_sector) const {
563  return ((endcap_ == tp_endcap) && (sector_ == tp_sector));
564 }
565 
566 bool PrimitiveSelection::is_in_neighbor_sector_csc(int tp_endcap, int tp_sector, int tp_subsector, int tp_station, int tp_csc_ID) const {
567  auto get_neighbor = [](int sector) {
568  return (sector == 1) ? 6 : sector - 1;
569  };
570 
571  if (includeNeighbor_) {
572  if ((endcap_ == tp_endcap) && (get_neighbor(sector_) == tp_sector)) {
573  if (tp_station == 1) {
574  if ((tp_subsector == 2) && (tp_csc_ID == 3 || tp_csc_ID == 6 || tp_csc_ID == 9))
575  return true;
576 
577  } else {
578  if (tp_csc_ID == 3 || tp_csc_ID == 9)
579  return true;
580  }
581  }
582  }
583  return false;
584 }
585 
586 bool PrimitiveSelection::is_in_bx_csc(int tp_bx) const {
587  tp_bx += bxShiftCSC_;
588  return (bx_ == tp_bx);
589 }
590 
591 // Returns CSC input "link". Index used by FW for unique chamber identification.
592 int PrimitiveSelection::get_index_csc(int tp_subsector, int tp_station, int tp_csc_ID, bool is_neighbor) const {
593  int selected = -1;
594 
595  if (!is_neighbor) {
596  if (tp_station == 1) { // ME1: 0 - 8, 9 - 17
597  selected = (tp_subsector-1) * 9 + (tp_csc_ID-1);
598  } else { // ME2,3,4: 18 - 26, 27 - 35, 36 - 44
599  selected = (tp_station) * 9 + (tp_csc_ID-1);
600  }
601 
602  } else {
603  if (tp_station == 1) { // ME1: 45 - 47
604  selected = (5) * 9 + (tp_csc_ID-1)/3;
605  } else { // ME2,3,4: 48 - 53
606  selected = (5) * 9 + (tp_station) * 2 - 1 + (tp_csc_ID-1 < 3 ? 0 : 1);
607  }
608  }
609  return selected;
610 }
611 
612 
613 // _____________________________________________________________________________
614 // RPC functions
615 int PrimitiveSelection::select_rpc(const TriggerPrimitive& muon_primitive) const {
616  int selected = -1;
617 
618  if (muon_primitive.subsystem() == TriggerPrimitive::kRPC) {
619  const RPCDetId& tp_detId = muon_primitive.detId<RPCDetId>();
620  const RPCData& tp_data = muon_primitive.getRPCData();
621 
622  int tp_region = tp_detId.region(); // 0 for Barrel, +/-1 for +/- Endcap
623  int tp_endcap = (tp_region == -1) ? 2 : tp_region;
624  int tp_sector = tp_detId.sector(); // 1 - 6 (60 degrees in phi, sector 1 begins at -5 deg)
625  int tp_subsector = tp_detId.subsector(); // 1 - 6 (10 degrees in phi; staggered in z)
626  int tp_station = tp_detId.station(); // 1 - 4
627  int tp_ring = tp_detId.ring(); // 2 - 3 (increasing theta)
628  int tp_roll = tp_detId.roll(); // 1 - 3 (decreasing theta; aka A - C; space between rolls is 9 - 15 in theta_fp)
629  //int tp_layer = tp_detId.layer();
630 
631  int tp_bx = tp_data.bx;
632  int tp_strip = tp_data.strip;
633 
634  if ( !(tp_region != 0) ) {
635  edm::LogWarning("L1T") << "EMTF RPC format error: tp_region = " << tp_region; return selected; }
636  if ( !(emtf::MIN_ENDCAP <= tp_endcap && tp_endcap <= emtf::MAX_ENDCAP) ) {
637  edm::LogWarning("L1T") << "EMTF RPC format error: tp_endcap = " << tp_endcap; return selected; }
638  if ( !(emtf::MIN_TRIGSECTOR <= tp_sector && tp_sector <= emtf::MAX_TRIGSECTOR) ) {
639  edm::LogWarning("L1T") << "EMTF RPC format error: tp_sector = " << tp_sector; return selected; }
640  if ( !(1 <= tp_subsector && tp_subsector <= 6) ) {
641  edm::LogWarning("L1T") << "EMTF RPC format error: tp_subsector = " << tp_subsector; return selected; }
642  if ( !(1 <= tp_station && tp_station <= 4) ) {
643  edm::LogWarning("L1T") << "EMTF RPC format error: tp_station = " << tp_station; return selected; }
644  if ( !(2 <= tp_ring && tp_ring <= 3) ) {
645  edm::LogWarning("L1T") << "EMTF RPC format error: tp_ring = " << tp_ring; return selected; }
646  if ( !(1 <= tp_roll && tp_roll <= 3) ) {
647  edm::LogWarning("L1T") << "EMTF RPC format error: tp_roll = " << tp_roll; return selected; }
648  if ( !(1 <= tp_strip && tp_strip <= 32) ) {
649  edm::LogWarning("L1T") << "EMTF RPC format error: tp_data.strip = " << tp_data.strip; return selected; }
650  if ( !(tp_station > 2 || tp_ring != 3) ) {
651  edm::LogWarning("L1T") << "EMTF RPC format error: tp_station = " << tp_station << ", tp_ring = " << tp_ring; return selected; }
652 
653 
654  // Selection
655  if (is_in_bx_rpc(tp_bx)) {
656  if (is_in_sector_rpc(tp_endcap, tp_station, tp_ring, tp_sector, tp_subsector)) {
657  selected = get_index_rpc(tp_station, tp_ring, tp_subsector, false);
658  } else if (is_in_neighbor_sector_rpc(tp_endcap, tp_station, tp_ring, tp_sector, tp_subsector)) {
659  selected = get_index_rpc(tp_station, tp_ring, tp_subsector, true);
660  }
661  }
662  }
663  return selected;
664 }
665 
666 bool PrimitiveSelection::is_in_sector_rpc(int tp_endcap, int tp_station, int tp_ring, int tp_sector, int tp_subsector) const {
667  // RPC sector X, subsectors 1-2 corresponds to CSC sector X-1
668  // RPC sector X, subsectors 3-6 corresponds to CSC sector X
669  auto get_csc_sector = [](int tp_station, int tp_ring, int tp_sector, int tp_subsector) {
670  // 10 degree chamber
671  int corr = (tp_subsector < 3) ? (tp_sector == 1 ? +5 : -1) : 0;
672  return tp_sector + corr;
673  };
674  return ((endcap_ == tp_endcap) && (sector_ == get_csc_sector(tp_station, tp_ring, tp_sector, tp_subsector)));
675 }
676 
677 bool PrimitiveSelection::is_in_neighbor_sector_rpc(int tp_endcap, int tp_station, int tp_ring, int tp_sector, int tp_subsector) const {
678  auto get_csc_neighbor_subsector = [](int tp_station, int tp_ring) {
679  // 10 degree chamber
680  return 2;
681  };
682  return (includeNeighbor_ && (endcap_ == tp_endcap) && (sector_ == tp_sector) && (tp_subsector == get_csc_neighbor_subsector(tp_station, tp_ring)));
683 }
684 
685 bool PrimitiveSelection::is_in_bx_rpc(int tp_bx) const {
686  tp_bx += bxShiftRPC_;
687  return (bx_ == tp_bx);
688 }
689 
690 int PrimitiveSelection::get_index_rpc(int tp_station, int tp_ring, int tp_subsector, bool is_neighbor) const {
691  int selected = -1;
692 
693  // CPPF RX data come in 3 frames x 64 bits, for 7 links. Each 64-bit data
694  // carry 2 words of 32 bits. Each word carries phi (11 bits) and theta (5 bits)
695  // of 2 segments (x2).
696  //
697  // Firmware uses 'rpc_sub' as RPC subsector index and 'rpc_chm' as RPC chamber index
698  // rpc_sub [0,6] = RPC subsector 3, 4, 5, 6, 1 from neighbor, 2 from neighbor, 2. They correspond to
699  // CSC sector phi 0-10 deg, 10-20, 20-30, 30-40, 40-50, 50-60, 50-60 from neighbor
700  // rpc_chm [0,5] = RPC chamber RE1/2, RE2/2, RE3/2, RE3/3, RE4/2, RE4/3
701  //
702  int rpc_sub = -1;
703  int rpc_chm = -1;
704 
705  if (!is_neighbor) {
706  rpc_sub = ((tp_subsector + 3) % 6);
707  } else {
708  rpc_sub = 6;
709  }
710 
711  if (tp_station <= 2) {
712  rpc_chm = (tp_station - 1);
713  } else {
714  rpc_chm = 2 + (tp_station - 3)*2 + (tp_ring - 2);
715  }
716 
717  if (not(rpc_sub != -1 && rpc_chm != -1))
718  { edm::LogError("L1T") << "rpc_sub = " << rpc_sub << ", rpc_chm = " << rpc_chm; return selected; }
719 
720  selected = (rpc_sub * 8) + rpc_chm;
721  return selected;
722 }
723 
724 
725 // _____________________________________________________________________________
726 // GEM functions
727 int PrimitiveSelection::select_gem(const TriggerPrimitive& muon_primitive) const {
728  int selected = -1;
729 
730  if (muon_primitive.subsystem() == TriggerPrimitive::kGEM) {
731  const EMTFGEMDetId& tp_detId = emtf::construct_EMTFGEMDetId(muon_primitive);
732  const GEMData& tp_data = muon_primitive.getGEMData();
733 
734  int tp_region = tp_detId.region(); // 0 for Barrel, +/-1 for +/- Endcap
735  int tp_endcap = (tp_region == -1) ? 2 : tp_region;
736  int tp_station = tp_detId.station();
737  int tp_ring = tp_detId.ring();
738  int tp_roll = tp_detId.roll();
739  int tp_layer = tp_detId.layer();
740  int tp_chamber = tp_detId.chamber();
741 
742  int tp_bx = tp_data.bx;
743  int tp_pad = tp_data.pad;
744 
745  // Use CSC trigger sector definitions
746  // Code copied from DataFormats/MuonDetId/src/CSCDetId.cc
747  auto get_trigger_sector = [](int ring, int station, int chamber) {
748  int result = 0;
749  if( station > 1 && ring > 1 ) {
750  result = ((static_cast<unsigned>(chamber-3) & 0x7f) / 6) + 1; // ch 3-8->1, 9-14->2, ... 1,2 -> 6
751  }
752  else if( station == 1 && ring != 4 ) {
753  result = ((static_cast<unsigned>(chamber-3) & 0x7f) / 6) + 1; // ch 3-8->1, 9-14->2, ... 1,2 -> 6
754  }
755  else {
756  result = ((static_cast<unsigned>(chamber-2) & 0x1f) / 3) + 1; // ch 2-4-> 1, 5-7->2, ...
757  }
758  return (result <= 6) ? result : 6; // max sector is 6, some calculations give a value greater than six but this is expected.
759  };
760 
761  // Use CSC trigger "CSC ID" definitions
762  // Code copied from DataFormats/MuonDetId/src/CSCDetId.cc
763  auto get_trigger_csc_ID = [](int ring, int station, int chamber) {
764  int result = 0;
765  if( station == 1 ) {
766  result = (chamber) % 3 + 1; // 1,2,3
767  switch (ring) {
768  case 1:
769  break;
770  case 2:
771  result += 3; // 4,5,6
772  break;
773  case 3:
774  result += 6; // 7,8,9
775  break;
776  }
777  }
778  else {
779  if( ring == 1 ) {
780  result = (chamber+1) % 3 + 1; // 1,2,3
781  }
782  else {
783  result = (chamber+3) % 6 + 4; // 4,5,6,7,8,9
784  }
785  }
786  return result;
787  };
788 
789  int tp_sector = get_trigger_sector(tp_ring, tp_station, tp_chamber);
790  int tp_csc_ID = get_trigger_csc_ID(tp_ring, tp_station, tp_chamber);
791 
792  // station 1 --> subsector 1 or 2
793  // station 2,3,4 --> subsector 0
794  int tp_subsector = (tp_station != 1) ? 0 : ((tp_chamber%6 > 2) ? 1 : 2);
795 
796 
797  if ( !(emtf::MIN_ENDCAP <= tp_endcap && tp_endcap <= emtf::MAX_ENDCAP) ) {
798  edm::LogWarning("L1T") << "EMTF GEM format error: tp_endcap = " << tp_endcap; return selected; }
799  if ( !(emtf::MIN_TRIGSECTOR <= tp_sector && tp_sector <= emtf::MAX_TRIGSECTOR) ) {
800  edm::LogWarning("L1T") << "EMTF GEM format error: tp_sector = " << tp_sector; return selected; }
801  if ( !(1 <= tp_station && tp_station <= 2) ) {
802  edm::LogWarning("L1T") << "EMTF GEM format error: tp_station = " << tp_station; return selected; }
803  if ( !(1 <= tp_ring && tp_ring <= 1) ) {
804  edm::LogWarning("L1T") << "EMTF GEM format error: tp_ring = " << tp_ring; return selected; }
805  if ( !(1 <= tp_csc_ID && tp_csc_ID <= 9) ) {
806  edm::LogWarning("L1T") << "EMTF GEM format error: tp_csc_ID = " << tp_csc_ID; return selected; }
807  if (!(tp_station == 1 && 1 <= tp_roll && tp_roll <= 8) || (tp_station != 1)) {
808  edm::LogWarning("L1T") << "EMTF GEM format error: tp_station = " << tp_station
809  << ", tp_roll = " << tp_roll; return selected; }
810  if ( !(tp_station == 2 && 1 <= tp_roll && tp_roll <= 12) || (tp_station != 2)) {
811  edm::LogWarning("L1T") << "EMTF GEM format error: tp_station = " << tp_station
812  << ", tp_roll = " << tp_roll; return selected; }
813  if ( !(1 <= tp_layer && tp_layer <= 2)) {
814  edm::LogWarning("L1T") << "EMTF GEM format error: tp_layer = " << tp_layer; return selected; }
815  if ( !((tp_station == 1 && 1 <= tp_pad && tp_pad <= 192) || (tp_station != 1))) {
816  edm::LogWarning("L1T") << "EMTF GEM format error: tp_station = " << tp_station
817  << ", tp_pad = " << tp_pad; return selected; }
818  if ( !((tp_station == 2 && 1 <= tp_pad && tp_pad <= 192) || (tp_station != 2))) {
819  edm::LogWarning("L1T") << "EMTF GEM format error: tp_station = " << tp_station
820  << ", tp_pad = " << tp_pad; return selected; }
821 
822  // Selection
823  if (is_in_bx_gem(tp_bx)) {
824  if (is_in_sector_gem(tp_endcap, tp_sector)) {
825  selected = get_index_gem(tp_subsector, tp_station, tp_csc_ID, false);
826  } else if (is_in_neighbor_sector_gem(tp_endcap, tp_sector, tp_subsector, tp_station, tp_csc_ID)) {
827  selected = get_index_gem(tp_subsector, tp_station, tp_csc_ID, true);
828  }
829  }
830  }
831  return selected;
832 }
833 
834 bool PrimitiveSelection::is_in_sector_gem(int tp_endcap, int tp_sector) const {
835  // Identical to the corresponding CSC function
836  return is_in_sector_csc(tp_endcap, tp_sector);
837 }
838 
839 bool PrimitiveSelection::is_in_neighbor_sector_gem(int tp_endcap, int tp_sector, int tp_subsector, int tp_station, int tp_csc_ID) const {
840  // Identical to the corresponding CSC function
841  return is_in_neighbor_sector_csc(tp_endcap, tp_sector, tp_subsector, tp_station, tp_csc_ID);
842 }
843 
844 bool PrimitiveSelection::is_in_bx_gem(int tp_bx) const {
845  tp_bx += bxShiftGEM_;
846  return (bx_ == tp_bx);
847 }
848 
849 int PrimitiveSelection::get_index_gem(int tp_subsector, int tp_station, int tp_csc_ID, bool is_neighbor) const {
850  // Identical to the corresponding CSC function
851  return get_index_csc(tp_subsector, tp_station, tp_csc_ID, is_neighbor);
852 }
size
Write out results.
int chamber() const
Definition: CSCDetId.h:68
int MAX_TRIGSECTOR
Definition: Common.h:61
const subsystem_type subsystem() const
bool is_in_sector_csc(int tp_endcap, int tp_sector) const
bool verbose
const GEMData getGEMData() const
#define NUM_GEM_CHAMBERS
int MIN_ENDCAP
Definition: Common.h:56
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
int roll() const
Definition: EMTFGEMDetId.cc:69
int MIN_TRIGSECTOR
Definition: Common.h:60
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:588
EMTFGEMDetId construct_EMTFGEMDetId(const TriggerPrimitive &tp)
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:33
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:57
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
#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