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 // _____________________________________________________________________________
255 // Copy constructor
257  : _dt(tp._dt),
258  _csc(tp._csc),
259  _rpc(tp._rpc),
260  _gem(tp._gem),
261  _me0(tp._me0),
262  _id(tp._id),
263  _subsystem(tp._subsystem),
264  _globalsector(tp._globalsector),
265  _subsector(tp._subsector),
266  _eta(tp._eta),
267  _phi(tp._phi),
268  _rho(tp._rho),
269  _theta(tp._theta) {}
270 
272  this->_dt = tp._dt;
273  this->_csc = tp._csc;
274  this->_rpc = tp._rpc;
275  this->_gem = tp._gem;
276  this->_me0 = tp._me0;
277  this->_id = tp._id;
278  this->_subsystem = tp._subsystem;
279  this->_globalsector = tp._globalsector;
280  this->_subsector = tp._subsector;
281  this->_eta = tp._eta;
282  this->_phi = tp._phi;
283  this->_rho = tp._rho;
284  this->_theta = tp._theta;
285  return *this;
286 }
287 
289  // Copied from Numpy
290  // https://github.com/numpy/numpy/blob/v1.14.0/numpy/core/numeric.py#L2260-L2355
291  auto isclose = [](float a, float b, float rtol = 1.e-5, float atol = 1.e-8) {
292  return std::abs(a - b) <= (atol + rtol * std::abs(b));
293  };
294 
295  switch (_subsystem) {
296  case kDT:
297  return (this->_dt.bx == tp._dt.bx && this->_dt.wheel == tp._dt.wheel && this->_dt.sector == tp._dt.sector &&
298  this->_dt.station == tp._dt.station && this->_dt.radialAngle == tp._dt.radialAngle &&
299  this->_dt.bendingAngle == tp._dt.bendingAngle && this->_dt.qualityCode == tp._dt.qualityCode &&
300  this->_dt.Ts2TagCode == tp._dt.Ts2TagCode && this->_dt.BxCntCode == tp._dt.BxCntCode &&
301  this->_dt.RpcBit == tp._dt.RpcBit && this->_dt.theta_bti_group == tp._dt.theta_bti_group &&
302  this->_dt.segment_number == tp._dt.segment_number && this->_dt.theta_code == tp._dt.theta_code &&
303  this->_dt.theta_quality == tp._dt.theta_quality && this->_id == tp._id &&
304  this->_subsystem == tp._subsystem && this->_globalsector == tp._globalsector &&
305  this->_subsector == tp._subsector);
306  case kCSC:
307  return (this->_csc.trknmb == tp._csc.trknmb && this->_csc.valid == tp._csc.valid &&
308  this->_csc.quality == tp._csc.quality && this->_csc.keywire == tp._csc.keywire &&
309  this->_csc.strip == tp._csc.strip && this->_csc.pattern == tp._csc.pattern &&
310  this->_csc.bend == tp._csc.bend && this->_csc.bx == tp._csc.bx && this->_csc.mpclink == tp._csc.mpclink &&
311  this->_csc.bx0 == tp._csc.bx0 && this->_csc.syncErr == tp._csc.syncErr &&
312  this->_csc.cscID == tp._csc.cscID && this->_csc.alct_quality == tp._csc.alct_quality &&
313  this->_csc.clct_quality == tp._csc.clct_quality && this->_id == tp._id &&
314  this->_subsystem == tp._subsystem && this->_globalsector == tp._globalsector &&
315  this->_subsector == tp._subsector);
316  case kRPC:
317  return (this->_rpc.strip == tp._rpc.strip && this->_rpc.strip_low == tp._rpc.strip_low &&
318  this->_rpc.strip_hi == tp._rpc.strip_hi && this->_rpc.phi_int == tp._rpc.phi_int &&
319  this->_rpc.theta_int == tp._rpc.theta_int && this->_rpc.emtf_sector == tp._rpc.emtf_sector &&
320  this->_rpc.emtf_link == tp._rpc.emtf_link && this->_rpc.bx == tp._rpc.bx &&
321  this->_rpc.valid == tp._rpc.valid && isclose(this->_rpc.x, tp._rpc.x) && // floating-point
322  isclose(this->_rpc.y, tp._rpc.y) && // floating-point
323  isclose(this->_rpc.time, tp._rpc.time) && // floating-point
324  this->_rpc.isCPPF == tp._rpc.isCPPF && this->_id == tp._id && this->_subsystem == tp._subsystem &&
325  this->_globalsector == tp._globalsector && this->_subsector == tp._subsector);
326  case kGEM:
327  return (this->_gem.pad == tp._gem.pad && this->_gem.pad_low == tp._gem.pad_low &&
328  this->_gem.pad_hi == tp._gem.pad_hi && this->_gem.bx == tp._gem.bx && this->_id == tp._id &&
329  this->_subsystem == tp._subsystem && this->_globalsector == tp._globalsector &&
330  this->_subsector == tp._subsector);
331  case kME0:
332  return (this->_me0.chamberid == tp._me0.chamberid && this->_me0.quality == tp._me0.quality &&
333  this->_me0.phiposition == tp._me0.phiposition && this->_me0.partition == tp._me0.partition &&
334  this->_me0.deltaphi == tp._me0.deltaphi && this->_me0.bend == tp._me0.bend &&
335  this->_me0.bx == tp._me0.bx && this->_id == tp._id && this->_subsystem == tp._subsystem &&
336  this->_globalsector == tp._globalsector && this->_subsector == tp._subsector);
337  default:
338  throw cms::Exception("Invalid Subsystem")
339  << "The specified subsystem for this track stub is out of range" << std::endl;
340  }
341  return false;
342 }
343 
344 // _____________________________________________________________________________
346  switch (_subsystem) {
347  case kDT:
348  return _dt.bx;
349  case kCSC:
350  return _csc.bx;
351  case kRPC:
352  return _rpc.bx;
353  case kGEM:
354  return _gem.bx;
355  case kME0:
356  return _me0.bx;
357  default:
358  throw cms::Exception("Invalid Subsystem")
359  << "The specified subsystem for this track stub is out of range" << std::endl;
360  }
361  return -1;
362 }
363 
365  switch (_subsystem) {
366  case kDT:
367  return _dt.radialAngle;
368  case kCSC:
369  return _csc.strip;
370  case kRPC:
371  return _rpc.strip;
372  case kGEM:
373  return _gem.pad;
374  case kME0:
375  return _me0.phiposition;
376  default:
377  throw cms::Exception("Invalid Subsystem")
378  << "The specified subsystem for this track stub is out of range" << std::endl;
379  }
380  return -1;
381 }
382 
384  switch (_subsystem) {
385  case kDT:
386  return _dt.theta_bti_group;
387  case kCSC:
388  return _csc.keywire;
389  case kRPC:
390  return -1;
391  case kGEM:
392  return -1;
393  case kME0:
394  return -1;
395  default:
396  throw cms::Exception("Invalid Subsystem")
397  << "The specified subsystem for this track stub is out of range" << std::endl;
398  }
399  return -1;
400 }
401 
403  switch (_subsystem) {
404  case kDT:
405  return -1;
406  case kCSC:
407  return _csc.pattern;
408  case kRPC:
409  return -1;
410  case kGEM:
411  return -1;
412  case kME0:
413  return -1;
414  default:
415  throw cms::Exception("Invalid Subsystem")
416  << "The specified subsystem for this track stub is out of range" << std::endl;
417  }
418  return -1;
419 }
420 
421 void TriggerPrimitive::print(std::ostream& out) const {
422  unsigned idx = (unsigned)_subsystem;
423  out << subsystem_names[idx] << " Trigger Primitive" << std::endl;
424  out << "eta: " << _eta << " phi: " << _phi << " rho: " << _rho << " theta: " << _theta << std::endl;
425  switch (_subsystem) {
426  case kDT:
427  out << detId<DTChamberId>() << std::endl;
428  out << "Local BX : " << _dt.bx << std::endl;
429  out << "Segment Nmb : " << _dt.segment_number << std::endl;
430  out << "Packed Phi : " << _dt.radialAngle << std::endl;
431  out << "Packed Bend : " << _dt.bendingAngle << std::endl;
432  out << "Quality Code : " << _dt.qualityCode << std::endl;
433  out << "Ts2Tag Code : " << _dt.Ts2TagCode << std::endl;
434  out << "BxCnt Code : " << _dt.BxCntCode << std::endl;
435  out << "RPC Bit : " << _dt.RpcBit << std::endl;
436  out << "Theta BTI Grp : " << _dt.theta_bti_group << std::endl;
437  out << "Theta Code : " << _dt.theta_code << std::endl;
438  out << "Theta Quality : " << _dt.theta_quality << std::endl;
439  break;
440  case kCSC:
441  out << detId<CSCDetId>() << std::endl;
442  out << "Local BX : " << _csc.bx << std::endl;
443  out << "Segment Nmb : " << _csc.trknmb << std::endl;
444  out << "Segment Valid : " << _csc.valid << std::endl;
445  out << "Quality Code : " << _csc.quality << std::endl;
446  out << "Key Wire Grp : " << _csc.keywire << std::endl;
447  out << "Half-Strip : " << _csc.strip << std::endl;
448  out << "CLCT Pattern : " << _csc.pattern << std::endl;
449  out << "Packed Bend : " << _csc.bend << std::endl;
450  out << "MPC Link : " << _csc.mpclink << std::endl;
451  out << "BX0 : " << _csc.bx0 << std::endl;
452  out << "Sync Error : " << _csc.syncErr << std::endl;
453  out << "CSCID : " << _csc.cscID << std::endl;
454  out << "ALCT Quality : " << _csc.alct_quality << std::endl;
455  out << "CLCT Quality : " << _csc.clct_quality << std::endl;
456  break;
457  case kRPC:
458  out << detId<RPCDetId>() << std::endl;
459  out << "Local BX : " << _rpc.bx << std::endl;
460  out << "Strip : " << _rpc.strip << std::endl;
461  out << "Strip low : " << _rpc.strip_low << std::endl;
462  out << "Strip high : " << _rpc.strip_hi << std::endl;
463  out << "Integer phi : " << _rpc.phi_int << std::endl;
464  out << "Integer theta : " << _rpc.theta_int << std::endl;
465  out << "EMTF sector : " << _rpc.emtf_sector << std::endl;
466  out << "EMTF link : " << _rpc.emtf_link << std::endl;
467  out << "Valid : " << _rpc.valid << std::endl;
468  out << "Local x : " << _rpc.x << std::endl;
469  out << "Local y : " << _rpc.y << std::endl;
470  out << "Time : " << _rpc.time << std::endl;
471  out << "IsCPPF : " << _rpc.isCPPF << std::endl;
472  break;
473  case kGEM:
474  out << detId<GEMDetId>() << std::endl;
475  out << "Local BX : " << _gem.bx << std::endl;
476  out << "Pad : " << _gem.pad << std::endl;
477  out << "Pad low : " << _gem.pad_low << std::endl;
478  out << "Pad high : " << _gem.pad_hi << std::endl;
479  break;
480  case kME0:
481  out << detId<ME0DetId>() << std::endl;
482  out << "Local BX : " << _me0.bx << std::endl;
483  out << "Chamber id : " << _me0.chamberid << std::endl;
484  out << "Quality : " << _me0.quality << std::endl;
485  out << "Phiposition : " << _me0.phiposition << std::endl;
486  out << "Partition : " << _me0.partition << std::endl;
487  out << "Deltaphi : " << _me0.deltaphi << std::endl;
488  out << "Bend : " << _me0.bend << std::endl;
489  break;
490  default:
491  throw cms::Exception("Invalid Subsystem")
492  << "The specified subsystem for this track stub is out of range" << std::endl;
493  }
494 }
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
int layer() const
Definition: CSCDetId.h:56
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 chamber() const
Definition: CSCDetId.h:62
int first_strip() const
Definition: CPPFDigi.h:60
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
int station() const
Definition: CSCDetId.h:79
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:118
int endcap() const
Definition: CSCDetId.h:85
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:119
int quality(const int i) const
int getPartition() const
return the key "partition"
int ring() const
Definition: CSCDetId.h:68
uint16_t getRun3Pattern() const
return the Run-3 pattern ID
const CSCALCTDigi & getALCT() const