CMS 3D CMS Logo

MuonTriggerPrimitive.cc
Go to the documentation of this file.
2 
3 // Muon primitive digi types
12 
13 // Muon detector ID types
19 
20 #include <iostream>
21 
22 using namespace L1TMuon;
23 
24 namespace {
25  const char subsystem_names[][4] = {"DT", "CSC", "RPC", "GEM", "ME0"};
26 }
27 
28 // _____________________________________________________________________________
29 // Constructors from DT data
31  const L1MuDTChambPhDigi& digi_phi,
32  const int segment_number)
33  : _id(detid), _subsystem(L1TMuon::kDT) {
35  _eta = 0.;
36  _phi = 0.;
37  _rho = 0.;
38  _theta = 0.;
39  // fill in information from theta trigger
40  _dt.theta_bti_group = -1;
41  _dt.segment_number = segment_number;
42  _dt.theta_code = -1;
43  _dt.theta_quality = -1;
44  // now phi trigger
45  _dt.bx = digi_phi.bxNum();
46  _dt.wheel = digi_phi.whNum();
47  _dt.sector = digi_phi.scNum();
48  _dt.station = digi_phi.stNum();
49  _dt.radialAngle = digi_phi.phi();
50  _dt.bendingAngle = digi_phi.phiB();
51  _dt.qualityCode = digi_phi.code();
52  _dt.Ts2TagCode = digi_phi.Ts2Tag();
53  _dt.BxCntCode = digi_phi.BxCnt();
54  _dt.RpcBit = digi_phi.RpcBit();
55 }
56 
58  const L1MuDTChambThDigi& digi_th,
59  const int theta_bti_group)
60  : _id(detid), _subsystem(L1TMuon::kDT) {
62  _eta = 0.;
63  _phi = 0.;
64  _rho = 0.;
65  _theta = 0.;
66  // fill in information from theta trigger
67  _dt.theta_bti_group = theta_bti_group;
68  _dt.segment_number = digi_th.position(theta_bti_group);
69  _dt.theta_code = digi_th.code(theta_bti_group);
70  _dt.theta_quality = digi_th.quality(theta_bti_group);
71  // now phi trigger
72  _dt.bx = digi_th.bxNum();
73  _dt.wheel = digi_th.whNum();
74  _dt.sector = digi_th.scNum();
75  _dt.station = digi_th.stNum();
76  _dt.radialAngle = -1;
77  _dt.bendingAngle = -1;
78  _dt.qualityCode = -1;
79  _dt.Ts2TagCode = -1;
80  _dt.BxCntCode = -1;
81  _dt.RpcBit = -10;
82 }
83 
85  const L1MuDTChambPhDigi& digi_phi,
86  const L1MuDTChambThDigi& digi_th,
87  const int theta_bti_group)
88  : _id(detid), _subsystem(L1TMuon::kDT) {
90  _eta = 0.;
91  _phi = 0.;
92  _rho = 0.;
93  _theta = 0.;
94  // fill in information from theta trigger
95  _dt.theta_bti_group = theta_bti_group;
96  _dt.segment_number = digi_th.position(theta_bti_group);
97  _dt.theta_code = digi_th.code(theta_bti_group);
98  _dt.theta_quality = digi_th.quality(theta_bti_group);
99  // now phi trigger
100  _dt.bx = digi_phi.bxNum();
101  _dt.wheel = digi_phi.whNum();
102  _dt.sector = digi_phi.scNum();
103  _dt.station = digi_phi.stNum();
104  _dt.radialAngle = digi_phi.phi();
105  _dt.bendingAngle = digi_phi.phiB();
106  _dt.qualityCode = digi_phi.code();
107  _dt.Ts2TagCode = digi_phi.Ts2Tag();
108  _dt.BxCntCode = digi_phi.BxCnt();
109  _dt.RpcBit = digi_phi.RpcBit();
110 }
111 
112 // _____________________________________________________________________________
113 // Constructor from CSC data
115  : _id(detid), _subsystem(L1TMuon::kCSC) {
117  _eta = 0.;
118  _phi = 0.;
119  _rho = 0.;
120  _theta = 0.;
121  _csc.trknmb = digi.getTrknmb();
122  _csc.valid = digi.isValid();
123  _csc.quality = digi.getQuality();
124  _csc.keywire = digi.getKeyWG();
125  _csc.strip = digi.getStrip();
126  _csc.pattern = digi.getPattern();
127  _csc.bend = digi.getBend();
128  _csc.bx = digi.getBX();
129  _csc.mpclink = digi.getMPCLink();
130  _csc.bx0 = digi.getBX0();
131  _csc.syncErr = digi.getSyncErr();
132  _csc.cscID = digi.getCSCID();
133  _csc.alct_quality = digi.getALCT().getQuality();
134  _csc.clct_quality = digi.getCLCT().getQuality();
135  // run-3
137  _csc.slope = digi.getSlope();
140  _csc.strip_quart = digi.getStrip(4);
141  _csc.strip_eighth = digi.getStrip(8);
142 
143  // Use ME1/1a --> ring 4 convention
144  const bool is_me11a = (detid.station() == 1 && detid.ring() == 1 && digi.getStrip() >= 128);
145  if (is_me11a) {
146  _id = CSCDetId(detid.endcap(), detid.station(), 4, detid.chamber(), detid.layer());
147  _csc.strip = digi.getStrip() - 128;
148  }
149 }
150 
151 // _____________________________________________________________________________
152 // Constructors from RPC data
153 TriggerPrimitive::TriggerPrimitive(const RPCDetId& detid, const RPCDigi& digi) : _id(detid), _subsystem(L1TMuon::kRPC) {
155  _eta = 0.;
156  _phi = 0.;
157  _rho = 0.;
158  _theta = 0.;
159  _rpc.strip = digi.strip();
160  _rpc.strip_low = digi.strip();
161  _rpc.strip_hi = digi.strip();
162  _rpc.phi_int = 0;
163  _rpc.theta_int = 0;
164  _rpc.emtf_sector = 0;
165  _rpc.emtf_link = 0;
166  _rpc.bx = digi.bx();
167  _rpc.valid = 1;
168  _rpc.x = digi.hasX() ? digi.coordinateX() : -999999.;
169  _rpc.y = digi.hasY() ? digi.coordinateY() : -999999.;
170  _rpc.time = digi.hasTime() ? digi.time() : -999999.;
171  _rpc.isCPPF = false;
172 }
173 
175  : _id(detid), _subsystem(L1TMuon::kRPC) {
177  _eta = 0.;
178  _phi = 0.;
179  _rho = 0.;
180  _theta = 0.;
181  _rpc.strip = rechit.firstClusterStrip() + (rechit.clusterSize() - 1) / 2;
182  _rpc.strip_low = rechit.firstClusterStrip();
183  _rpc.strip_hi = rechit.firstClusterStrip() + rechit.clusterSize() - 1;
184  _rpc.phi_int = 0;
185  _rpc.theta_int = 0;
186  _rpc.emtf_sector = 0;
187  _rpc.emtf_link = 0;
188  _rpc.bx = rechit.BunchX();
189  _rpc.valid = 1;
190  _rpc.x = rechit.localPosition().x();
191  _rpc.y = rechit.localPosition().y();
192  _rpc.time = rechit.time();
193  _rpc.isCPPF = false;
194 }
195 
196 // _____________________________________________________________________________
197 // Constructor from CPPF data
199  : _id(detid), _subsystem(L1TMuon::kRPC) {
201  _eta = 0.;
202  _phi = 0.;
203  _rho = 0.;
204  _theta = 0.;
205  // In unpacked CPPF digis, the strip number and cluster size are not available, and are set to -99
206  _rpc.strip = (digi.first_strip() < 0 ? 0 : digi.first_strip() + ((digi.cluster_size() - 1) / 2));
207  _rpc.strip_low = (digi.first_strip() < 0 ? 0 : digi.first_strip());
208  _rpc.strip_hi = (digi.first_strip() < 0 ? 0 : digi.first_strip() + digi.cluster_size() - 1);
209  _rpc.phi_int = digi.phi_int();
210  _rpc.theta_int = digi.theta_int();
211  _rpc.emtf_sector = digi.emtf_sector();
212  _rpc.emtf_link = digi.emtf_link();
213  _rpc.bx = digi.bx();
214  _rpc.valid = digi.valid();
215  _rpc.x = -999999.;
216  _rpc.y = -999999.;
217  _rpc.time = -999999.;
218  _rpc.isCPPF = true;
219 }
220 
221 // _____________________________________________________________________________
222 // Constructor from GEM data
224  : _id(detid), _subsystem(L1TMuon::kGEM) {
226  _eta = 0.;
227  _phi = 0.;
228  _rho = 0.;
229  _theta = 0.;
230  _gem.pad = digi.pads().front() + ((digi.pads().size() - 1) / 2);
231  _gem.pad_low = digi.pads().front();
232  _gem.pad_hi = digi.pads().front() + digi.pads().size() - 1;
233  _gem.bx = digi.bx();
234 }
235 
236 // _____________________________________________________________________________
237 // Constructor from ME0 data
239  : _id(detid), _subsystem(L1TMuon::kME0) {
241  _eta = 0.;
242  _phi = 0.;
243  _rho = 0.;
244  _theta = 0.;
245  _me0.chamberid = digi.getChamberid();
246  _me0.quality = digi.getQuality();
248  _me0.partition = digi.getPartition();
249  _me0.deltaphi = digi.getDeltaphi();
250  _me0.bend = digi.getBend();
251  _me0.bx = digi.getBX();
252 }
253 
254 // Constructor from GE0 data
256  : _id(detid), _subsystem(L1TMuon::kME0) {
258  _eta = 0.;
259  _phi = 0.;
260  _rho = 0.;
261  _theta = 0.;
262  _me0.chamberid = digi.getChamberid();
263  _me0.quality = digi.getQuality();
265  _me0.partition = digi.getPartition();
266  _me0.deltaphi = digi.getDeltaphi();
267  _me0.bend = digi.getBend();
268  _me0.bx = digi.getBX();
269 }
270 
271 // _____________________________________________________________________________
272 // Copy constructor
274  : _dt(tp._dt),
275  _csc(tp._csc),
276  _rpc(tp._rpc),
277  _gem(tp._gem),
278  _me0(tp._me0),
279  _id(tp._id),
280  _subsystem(tp._subsystem),
281  _globalsector(tp._globalsector),
282  _subsector(tp._subsector),
283  _eta(tp._eta),
284  _phi(tp._phi),
285  _rho(tp._rho),
286  _theta(tp._theta) {}
287 
289  this->_dt = tp._dt;
290  this->_csc = tp._csc;
291  this->_rpc = tp._rpc;
292  this->_gem = tp._gem;
293  this->_me0 = tp._me0;
294  this->_id = tp._id;
295  this->_subsystem = tp._subsystem;
296  this->_globalsector = tp._globalsector;
297  this->_subsector = tp._subsector;
298  this->_eta = tp._eta;
299  this->_phi = tp._phi;
300  this->_rho = tp._rho;
301  this->_theta = tp._theta;
302  return *this;
303 }
304 
306  // Copied from Numpy
307  // https://github.com/numpy/numpy/blob/v1.14.0/numpy/core/numeric.py#L2260-L2355
308  auto isclose = [](float a, float b, float rtol = 1.e-5, float atol = 1.e-8) {
309  return std::abs(a - b) <= (atol + rtol * std::abs(b));
310  };
311 
312  switch (_subsystem) {
313  case kDT:
314  return (this->_dt.bx == tp._dt.bx && this->_dt.wheel == tp._dt.wheel && this->_dt.sector == tp._dt.sector &&
315  this->_dt.station == tp._dt.station && this->_dt.radialAngle == tp._dt.radialAngle &&
316  this->_dt.bendingAngle == tp._dt.bendingAngle && this->_dt.qualityCode == tp._dt.qualityCode &&
317  this->_dt.Ts2TagCode == tp._dt.Ts2TagCode && this->_dt.BxCntCode == tp._dt.BxCntCode &&
318  this->_dt.RpcBit == tp._dt.RpcBit && this->_dt.theta_bti_group == tp._dt.theta_bti_group &&
319  this->_dt.segment_number == tp._dt.segment_number && this->_dt.theta_code == tp._dt.theta_code &&
320  this->_dt.theta_quality == tp._dt.theta_quality && this->_id == tp._id &&
321  this->_subsystem == tp._subsystem && this->_globalsector == tp._globalsector &&
322  this->_subsector == tp._subsector);
323  case kCSC:
324  return (this->_csc.trknmb == tp._csc.trknmb && this->_csc.valid == tp._csc.valid &&
325  this->_csc.quality == tp._csc.quality && this->_csc.keywire == tp._csc.keywire &&
326  this->_csc.strip == tp._csc.strip && this->_csc.pattern == tp._csc.pattern &&
327  this->_csc.bend == tp._csc.bend && this->_csc.bx == tp._csc.bx && this->_csc.mpclink == tp._csc.mpclink &&
328  this->_csc.bx0 == tp._csc.bx0 && this->_csc.syncErr == tp._csc.syncErr &&
329  this->_csc.cscID == tp._csc.cscID && this->_csc.alct_quality == tp._csc.alct_quality &&
330  this->_csc.clct_quality == tp._csc.clct_quality && this->_id == tp._id &&
331  this->_subsystem == tp._subsystem && this->_globalsector == tp._globalsector &&
332  this->_subsector == tp._subsector);
333  case kRPC:
334  return (this->_rpc.strip == tp._rpc.strip && this->_rpc.strip_low == tp._rpc.strip_low &&
335  this->_rpc.strip_hi == tp._rpc.strip_hi && this->_rpc.phi_int == tp._rpc.phi_int &&
336  this->_rpc.theta_int == tp._rpc.theta_int && this->_rpc.emtf_sector == tp._rpc.emtf_sector &&
337  this->_rpc.emtf_link == tp._rpc.emtf_link && this->_rpc.bx == tp._rpc.bx &&
338  this->_rpc.valid == tp._rpc.valid && isclose(this->_rpc.x, tp._rpc.x) && // floating-point
339  isclose(this->_rpc.y, tp._rpc.y) && // floating-point
340  isclose(this->_rpc.time, tp._rpc.time) && // floating-point
341  this->_rpc.isCPPF == tp._rpc.isCPPF && this->_id == tp._id && this->_subsystem == tp._subsystem &&
342  this->_globalsector == tp._globalsector && this->_subsector == tp._subsector);
343  case kGEM:
344  return (this->_gem.pad == tp._gem.pad && this->_gem.pad_low == tp._gem.pad_low &&
345  this->_gem.pad_hi == tp._gem.pad_hi && this->_gem.bx == tp._gem.bx && this->_id == tp._id &&
346  this->_subsystem == tp._subsystem && this->_globalsector == tp._globalsector &&
347  this->_subsector == tp._subsector);
348  case kME0:
349  return (this->_me0.chamberid == tp._me0.chamberid && this->_me0.quality == tp._me0.quality &&
350  this->_me0.phiposition == tp._me0.phiposition && this->_me0.partition == tp._me0.partition &&
351  this->_me0.deltaphi == tp._me0.deltaphi && this->_me0.bend == tp._me0.bend &&
352  this->_me0.bx == tp._me0.bx && this->_id == tp._id && this->_subsystem == tp._subsystem &&
353  this->_globalsector == tp._globalsector && this->_subsector == tp._subsector);
354  default:
355  throw cms::Exception("Invalid Subsystem")
356  << "The specified subsystem for this track stub is out of range" << std::endl;
357  }
358  return false;
359 }
360 
361 // _____________________________________________________________________________
363  switch (_subsystem) {
364  case kDT:
365  return _dt.bx;
366  case kCSC:
367  return _csc.bx;
368  case kRPC:
369  return _rpc.bx;
370  case kGEM:
371  return _gem.bx;
372  case kME0:
373  return _me0.bx;
374  default:
375  throw cms::Exception("Invalid Subsystem")
376  << "The specified subsystem for this track stub is out of range" << std::endl;
377  }
378  return -1;
379 }
380 
382  switch (_subsystem) {
383  case kDT:
384  return _dt.radialAngle;
385  case kCSC:
386  return _csc.strip;
387  case kRPC:
388  return _rpc.strip;
389  case kGEM:
390  return _gem.pad;
391  case kME0:
392  return _me0.phiposition;
393  default:
394  throw cms::Exception("Invalid Subsystem")
395  << "The specified subsystem for this track stub is out of range" << std::endl;
396  }
397  return -1;
398 }
399 
401  switch (_subsystem) {
402  case kDT:
403  return _dt.theta_bti_group;
404  case kCSC:
405  return _csc.keywire;
406  case kRPC:
407  return -1;
408  case kGEM:
409  return -1;
410  case kME0:
411  return -1;
412  default:
413  throw cms::Exception("Invalid Subsystem")
414  << "The specified subsystem for this track stub is out of range" << std::endl;
415  }
416  return -1;
417 }
418 
420  switch (_subsystem) {
421  case kDT:
422  return -1;
423  case kCSC:
424  return _csc.pattern;
425  case kRPC:
426  return -1;
427  case kGEM:
428  return -1;
429  case kME0:
430  return -1;
431  default:
432  throw cms::Exception("Invalid Subsystem")
433  << "The specified subsystem for this track stub is out of range" << std::endl;
434  }
435  return -1;
436 }
437 
438 void TriggerPrimitive::print(std::ostream& out) const {
439  unsigned idx = (unsigned)_subsystem;
440  out << subsystem_names[idx] << " Trigger Primitive" << std::endl;
441  out << "eta: " << _eta << " phi: " << _phi << " rho: " << _rho << " theta: " << _theta << std::endl;
442  switch (_subsystem) {
443  case kDT:
444  out << detId<DTChamberId>() << std::endl;
445  out << "Local BX : " << _dt.bx << std::endl;
446  out << "Segment Nmb : " << _dt.segment_number << std::endl;
447  out << "Packed Phi : " << _dt.radialAngle << std::endl;
448  out << "Packed Bend : " << _dt.bendingAngle << std::endl;
449  out << "Quality Code : " << _dt.qualityCode << std::endl;
450  out << "Ts2Tag Code : " << _dt.Ts2TagCode << std::endl;
451  out << "BxCnt Code : " << _dt.BxCntCode << std::endl;
452  out << "RPC Bit : " << _dt.RpcBit << std::endl;
453  out << "Theta BTI Grp : " << _dt.theta_bti_group << std::endl;
454  out << "Theta Code : " << _dt.theta_code << std::endl;
455  out << "Theta Quality : " << _dt.theta_quality << std::endl;
456  break;
457  case kCSC:
458  out << detId<CSCDetId>() << std::endl;
459  out << "Local BX : " << _csc.bx << std::endl;
460  out << "Segment Nmb : " << _csc.trknmb << std::endl;
461  out << "Segment Valid : " << _csc.valid << std::endl;
462  out << "Quality Code : " << _csc.quality << std::endl;
463  out << "Key Wire Grp : " << _csc.keywire << std::endl;
464  out << "Half-Strip : " << _csc.strip << std::endl;
465  out << "CLCT Pattern : " << _csc.pattern << std::endl;
466  out << "Packed Bend : " << _csc.bend << std::endl;
467  out << "MPC Link : " << _csc.mpclink << std::endl;
468  out << "BX0 : " << _csc.bx0 << std::endl;
469  out << "Sync Error : " << _csc.syncErr << std::endl;
470  out << "CSCID : " << _csc.cscID << std::endl;
471  out << "ALCT Quality : " << _csc.alct_quality << std::endl;
472  out << "CLCT Quality : " << _csc.clct_quality << std::endl;
473  break;
474  case kRPC:
475  out << detId<RPCDetId>() << std::endl;
476  out << "Local BX : " << _rpc.bx << std::endl;
477  out << "Strip : " << _rpc.strip << std::endl;
478  out << "Strip low : " << _rpc.strip_low << std::endl;
479  out << "Strip high : " << _rpc.strip_hi << std::endl;
480  out << "Integer phi : " << _rpc.phi_int << std::endl;
481  out << "Integer theta : " << _rpc.theta_int << std::endl;
482  out << "EMTF sector : " << _rpc.emtf_sector << std::endl;
483  out << "EMTF link : " << _rpc.emtf_link << std::endl;
484  out << "Valid : " << _rpc.valid << std::endl;
485  out << "Local x : " << _rpc.x << std::endl;
486  out << "Local y : " << _rpc.y << std::endl;
487  out << "Time : " << _rpc.time << std::endl;
488  out << "IsCPPF : " << _rpc.isCPPF << std::endl;
489  break;
490  case kGEM:
491  out << detId<GEMDetId>() << std::endl;
492  out << "Local BX : " << _gem.bx << std::endl;
493  out << "Pad : " << _gem.pad << std::endl;
494  out << "Pad low : " << _gem.pad_low << std::endl;
495  out << "Pad high : " << _gem.pad_hi << std::endl;
496  break;
497  case kME0:
498  if (detId<DetId>().subdetId() == MuonSubdetId::ME0) {
499  out << detId<ME0DetId>() << std::endl;
500  } else {
501  out << detId<GEMDetId>() << std::endl;
502  }
503 
504  out << "Local BX : " << _me0.bx << std::endl;
505  out << "Chamber id : " << _me0.chamberid << std::endl;
506  out << "Quality : " << _me0.quality << std::endl;
507  out << "Phiposition : " << _me0.phiposition << std::endl;
508  out << "Partition : " << _me0.partition << std::endl;
509  out << "Deltaphi : " << _me0.deltaphi << std::endl;
510  out << "Bend : " << _me0.bend << std::endl;
511  break;
512  default:
513  throw cms::Exception("Invalid Subsystem")
514  << "The specified subsystem for this track stub is out of range" << std::endl;
515  }
516 }
double coordinateY() const
Definition: RPCDigi.h:31
int bx() const
Definition: RPCDigi.h:28
void print(std::ostream &) const
const std::vector< uint16_t > & pads() const
int bx() const
Definition: CPPFDigi.h:52
LocalPoint localPosition() const override
Return the 3-dimensional local position.
Definition: RPCRecHit.h:37
uint16_t getSlope() const
return the slope
uint16_t getPattern() const
return the Run-2 pattern ID
bool operator==(const TriggerPrimitive &tp) const
bool hasY() const
Definition: RPCDigi.h:34
int theta_int() const
Definition: CPPFDigi.h:54
uint16_t getQuality() const
return quality of a pattern (number of layers hit!)
Definition: CSCCLCTDigi.h:56
int getQuality() const
return the Quality
TriggerPrimitive & operator=(const TriggerPrimitive &tp)
int position(const int i) const
int getChamberid() const
return chamber number in one CTP7
double coordinateX() const
Definition: RPCDigi.h:30
bool hasX() const
Definition: RPCDigi.h:33
int emtf_sector() const
Definition: CPPFDigi.h:58
int phi_int() const
Definition: CPPFDigi.h:53
uint16_t getQuality() const
return quality of a pattern
Definition: CSCALCTDigi.h:46
int getBend() const
return bend
void calculateGlobalSector(const IDType &chid, unsigned &globalsector, unsigned &subsector) const
int emtf_link() const
Definition: CPPFDigi.h:59
int getDeltaphi() const
return bending angle
uint16_t getMPCLink() const
return MPC link number, 0 means not sorted, 1-3 give MPC sorting rank
int code(const int i) const
uint16_t getBX() const
return BX
int BunchX() const
Definition: RPCRecHit.h:73
bool isValid() const
return valid pattern bit
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int first_strip() const
Definition: CPPFDigi.h:60
static constexpr int ME0
Definition: MuonSubdetId.h:15
bool getEighthStripBit() const
get single eighth strip bit
int getPhiposition() const
return the phi position, resolution: half strip level
bool hasTime() const
Definition: RPCDigi.h:32
uint16_t getSyncErr() const
float time() const
Definition: RPCRecHit.h:79
uint16_t getTrknmb() const
return track number
uint16_t getQuality() const
return the Quality
uint16_t getStrip(uint16_t n=2) const
return the key halfstrip from 0,159
const CSCCLCTDigi & getCLCT() const
bool getQuartStripBit() const
get single quart strip bit
int getBX() const
return BX
int clusterSize() const
Definition: RPCRecHit.h:77
double b
Definition: hdecay.h:120
double time() const
Definition: RPCDigi.h:29
uint16_t getKeyWG() const
return the key wire group. counts from 0.
int strip() const
Definition: RPCDigi.h:27
int valid() const
Definition: CPPFDigi.h:55
int firstClusterStrip() const
Definition: RPCRecHit.h:75
int cluster_size() const
Definition: CPPFDigi.h:61
double a
Definition: hdecay.h:121
int quality(const int i) const
int getPartition() const
return the key "partition"
uint16_t getRun3Pattern() const
return the Run-3 pattern ID
const CSCALCTDigi & getALCT() const