CMS 3D CMS Logo

L1MuDTAssignmentUnit.cc
Go to the documentation of this file.
1 //-------------------------------------------------
2 //
3 // Class: L1MuDTAssignmentUnit
4 //
5 // Description: Assignment Unit
6 //
7 //
8 //
9 // Author :
10 // N. Neumeister CERN EP
11 // J. Troconiz UAM Madrid
12 //
13 //--------------------------------------------------
14 
15 //-----------------------
16 // This Class's Header --
17 //-----------------------
18 
20 
21 //---------------
22 // C++ Headers --
23 //---------------
24 
25 #include <iostream>
26 #include <cmath>
27 #include <cassert>
28 
29 //-------------------------------
30 // Collaborating Class Headers --
31 //-------------------------------
32 
47 
48 using namespace std;
49 
50 // --------------------------------
51 // class L1MuDTAssignmentUnit
52 //---------------------------------
53 
54 //----------------
55 // Constructors --
56 //----------------
57 
59  : m_sp(sp),
60  m_id(id),
61  m_addArray(),
62  m_TSphi(),
63  m_ptAssMethod(NODEF),
64  thePhiToken(iC.esConsumes()),
65  thePtaToken(iC.esConsumes()),
66  nbit_phi(12),
67  nbit_phib(10) {
68  m_TSphi.reserve(4); // a track candidate can consist of max 4 TS
69  reset();
70 
71  setPrecision();
72 }
73 
74 //--------------
75 // Destructor --
76 //--------------
77 
79 
80 //--------------
81 // Operations --
82 //--------------
83 
84 //
85 // run Assignment Unit
86 //
88  // enable track candidate
89  m_sp.track(m_id)->enable();
90  m_sp.tracK(m_id)->enable();
91 
92  // set track class
93  TrackClass tc = m_sp.TA()->trackClass(m_id);
94  m_sp.track(m_id)->setTC(tc);
95  m_sp.tracK(m_id)->setTC(tc);
96 
97  // get relative addresses of matching track segments
101 
102  // get track segments (track segment router)
103  TSR();
106 
107  // set bunch-crossing (use first track segment)
108  vector<const L1MuDTTrackSegPhi*>::const_iterator iter = m_TSphi.begin();
109  int bx = (*iter)->bx();
110  m_sp.track(m_id)->setBx(bx);
111  m_sp.tracK(m_id)->setBx(bx);
112 
113  // assign phi
114  PhiAU(c);
115 
116  // assign pt and charge
117  PtAU(c);
118 
119  // assign quality
120  QuaAU();
121 
122  // special hack for overlap region
123  // for ( iter = m_TSphi.begin(); iter != m_TSphi.end(); iter++ ) {
124  // int wheel = abs((*iter)->wheel());
125  // if ( wheel == 3 && (*iter)->etaFlag() ) m_sp.track(m_id)->disable();
126  // if ( wheel == 3 && (*iter)->etaFlag() ) m_sp.tracK(m_id)->disable();
127  // }
128 }
129 
130 //
131 // reset Assignment Unit
132 //
134  m_addArray.reset();
135  m_TSphi.clear();
137 }
138 
139 //
140 // assign phi with 8 bit precision
141 //
143  // calculate phi at station 2 using 8 bits (precision = 2.5 degrees)
144 
145  thePhiLUTs = c.getHandle(thePhiToken);
146 
147  int sh_phi = 12 - m_sp.tf().config()->getNbitsPhiPhi();
148  int sh_phib = 10 - m_sp.tf().config()->getNbitsPhiPhib();
149 
150  const L1MuDTTrackSegPhi* second = getTSphi(2); // track segment at station 2
151  const L1MuDTTrackSegPhi* first = getTSphi(1); // track segment at station 1
152  const L1MuDTTrackSegPhi* forth = getTSphi(4); // track segment at station 4
153 
154  int phi2 = 0; // phi-value at station 2
155  int sector = 0;
156 
157  if (second) {
158  phi2 = second->phi() >> sh_phi;
159  sector = second->sector();
160  } else if (second == nullptr && first) {
161  phi2 = first->phi() >> sh_phi;
162  sector = first->sector();
163  } else if (second == nullptr && forth) {
164  phi2 = forth->phi() >> sh_phi;
165  sector = forth->sector();
166  }
167 
168  int sector0 = m_sp.id().sector();
169 
170  // convert sector difference to values in the range -6 to +5
171 
172  int sectordiff = (sector - sector0) % 12;
173  if (sectordiff >= 6)
174  sectordiff -= 12;
175  if (sectordiff < -6)
176  sectordiff += 12;
177 
178  // assert( abs(sectordiff) <= 1 );
179 
180  // get sector center in 8 bit coding
181  int sector_8 = convertSector(sector0);
182 
183  // convert phi to 2.5 degree precision
184  int phi_precision = 4096 >> sh_phi;
185  const double k = 57.2958 / 2.5 / static_cast<float>(phi_precision);
186  double phi_f = static_cast<double>(phi2);
187  int phi_8 = static_cast<int>(floor(phi_f * k));
188 
189  if (second == nullptr && first) {
190  int bend_angle = l1t::bitShift((first->phib() >> sh_phib), sh_phib);
191  phi_8 = phi_8 + thePhiLUTs->getDeltaPhi(0, bend_angle);
192  } else if (second == nullptr && forth) {
193  int bend_angle = l1t::bitShift((forth->phib() >> sh_phib), sh_phib);
194  phi_8 = phi_8 + thePhiLUTs->getDeltaPhi(1, bend_angle);
195  }
196 
197  phi_8 += sectordiff * 12;
198 
199  if (phi_8 > 15)
200  phi_8 = 15;
201  if (phi_8 < -16)
202  phi_8 = -16;
203 
204  int phi = (sector_8 + phi_8 + 144) % 144;
205  phi_8 = (phi_8 + 32) % 32;
206 
207  m_sp.track(m_id)->setPhi(phi);
208  m_sp.tracK(m_id)->setPhi(phi_8);
209 }
210 
211 //
212 // assign pt with 5 bit precision
213 //
215  thePtaLUTs = c.getHandle(thePtaToken);
216 
217  // get pt-assignment method as function of track class and TS phib values
219 
220  // get input address for look-up table
221  int bend_angle = getPtAddress(m_ptAssMethod);
222  int bend_carga = getPtAddress(m_ptAssMethod, 1);
223 
224  // retrieve pt value from look-up table
225  int lut_idx = m_ptAssMethod;
226  int pt = thePtaLUTs->getPt(lut_idx, bend_angle);
227 
228  m_sp.track(m_id)->setPt(pt);
229  m_sp.tracK(m_id)->setPt(pt);
230 
231  // assign charge
232  int chsign = getCharge(m_ptAssMethod);
233  int charge = (bend_carga >= 0) ? chsign : -1 * chsign;
236 }
237 
238 //
239 // assign 3 bit quality code
240 //
242  unsigned int quality = 0;
243 
244  const TrackClass tc = m_sp.TA()->trackClass(m_id);
245 
246  switch (tc) {
247  case T1234: {
248  quality = 7;
249  break;
250  }
251  case T123: {
252  quality = 6;
253  break;
254  }
255  case T124: {
256  quality = 6;
257  break;
258  }
259  case T134: {
260  quality = 5;
261  break;
262  }
263  case T234: {
264  quality = 4;
265  break;
266  }
267  case T12: {
268  quality = 3;
269  break;
270  }
271  case T13: {
272  quality = 3;
273  break;
274  }
275  case T14: {
276  quality = 3;
277  break;
278  }
279  case T23: {
280  quality = 2;
281  break;
282  }
283  case T24: {
284  quality = 2;
285  break;
286  }
287  case T34: {
288  quality = 1;
289  break;
290  }
291  default: {
292  quality = 0;
293  break;
294  }
295  }
296 
299 }
300 
301 //
302 // Track Segment Router (TSR)
303 //
305  // get the track segments from the data buffer
306  const L1MuDTTrackSegPhi* ts = nullptr;
307  for (int stat = 1; stat <= 4; stat++) {
308  int adr = m_addArray.station(stat);
309  if (adr != 15) {
310  ts = m_sp.data()->getTSphi(stat, adr);
311  if (ts != nullptr)
312  m_TSphi.push_back(ts);
313  }
314  }
315 }
316 
317 //
318 // get track segment from a given station
319 //
321  vector<const L1MuDTTrackSegPhi*>::const_iterator iter;
322  for (iter = m_TSphi.begin(); iter != m_TSphi.end(); iter++) {
323  int stat = (*iter)->station();
324  if (station == stat) {
325  return (*iter);
326  break;
327  }
328  }
329 
330  return nullptr;
331 }
332 
333 //
334 // convert sector Id to a precision of 2.5 degrees using 8 bits (= sector center)
335 //
337  // assert( sector >=0 && sector < 12 );
338  const int sectorvalues[12] = {0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132};
339 
340  return sectorvalues[sector];
341 }
342 
343 //
344 // determine charge
345 //
347  int chargesign = 0;
348  switch (method) {
349  case PT12L: {
350  chargesign = -1;
351  break;
352  }
353  case PT12H: {
354  chargesign = -1;
355  break;
356  }
357  case PT13L: {
358  chargesign = -1;
359  break;
360  }
361  case PT13H: {
362  chargesign = -1;
363  break;
364  }
365  case PT14L: {
366  chargesign = -1;
367  break;
368  }
369  case PT14H: {
370  chargesign = -1;
371  break;
372  }
373  case PT23L: {
374  chargesign = -1;
375  break;
376  }
377  case PT23H: {
378  chargesign = -1;
379  break;
380  }
381  case PT24L: {
382  chargesign = -1;
383  break;
384  }
385  case PT24H: {
386  chargesign = -1;
387  break;
388  }
389  case PT34L: {
390  chargesign = 1;
391  break;
392  }
393  case PT34H: {
394  chargesign = 1;
395  break;
396  }
397  case PT12LO: {
398  chargesign = -1;
399  break;
400  }
401  case PT12HO: {
402  chargesign = -1;
403  break;
404  }
405  case PT13LO: {
406  chargesign = -1;
407  break;
408  }
409  case PT13HO: {
410  chargesign = -1;
411  break;
412  }
413  case PT14LO: {
414  chargesign = -1;
415  break;
416  }
417  case PT14HO: {
418  chargesign = -1;
419  break;
420  }
421  case PT23LO: {
422  chargesign = -1;
423  break;
424  }
425  case PT23HO: {
426  chargesign = -1;
427  break;
428  }
429  case PT24LO: {
430  chargesign = -1;
431  break;
432  }
433  case PT24HO: {
434  chargesign = -1;
435  break;
436  }
437  case PT34LO: {
438  chargesign = 1;
439  break;
440  }
441  case PT34HO: {
442  chargesign = 1;
443  break;
444  }
445  case PT15LO: {
446  chargesign = -1;
447  break;
448  }
449  case PT15HO: {
450  chargesign = -1;
451  break;
452  }
453  case PT25LO: {
454  chargesign = -1;
455  break;
456  }
457  case PT25HO: {
458  chargesign = -1;
459  break;
460  }
461  case NODEF: {
462  chargesign = 0;
463  // cerr << "AssignmentUnit::getCharge : undefined PtAssMethod!"
464  // << endl;
465  break;
466  }
467  }
468 
469  return chargesign;
470 }
471 
472 //
473 // determine pt-assignment method
474 //
476  // determine which pt-assignment method should be used as a function
477  // of the track class and
478  // of the phib values of the track segments making up this track candidate.
479 
480  // get bitmap of track candidate
481  const bitset<4> s = m_sp.TA()->trackBitMap(m_id);
482 
483  int method = -1;
484 
485  if (s.test(0) && s.test(3))
486  method = 2; // stations 1 and 4
487  if (s.test(0) && s.test(2))
488  method = 1; // stations 1 and 3
489  if (s.test(0) && s.test(1))
490  method = 0; // stations 1 and 2
491  if (!s.test(0) && s.test(1) && s.test(3))
492  method = 4; // stations 2 and 4
493  if (!s.test(0) && s.test(1) && s.test(2))
494  method = 3; // stations 2 and 3
495  if (!s.test(0) && !s.test(1) && s.test(2) && s.test(3))
496  method = 5; // stations 3 and 4
497 
498  if (m_sp.ovl()) {
499  int adr = m_addArray.station(3);
500  bool s5 = (adr == 15) ? false : ((adr / 2) % 2 == 1);
501  if (s.test(0) && s.test(3))
502  method = 8; // stations 1 and 4
503  if (s.test(0) && s.test(2) && s5)
504  method = 12; // stations 1 and 5
505  if (s.test(0) && s.test(2) && !s5)
506  method = 7; // stations 1 and 3
507  if (s.test(0) && s.test(1))
508  method = 6; // stations 1 and 2
509  if (!s.test(0) && s.test(1) && s.test(3))
510  method = 10; // stations 2 and 4
511  if (!s.test(0) && s.test(1) && s.test(2) && s5)
512  method = 13; // stations 2 and 5
513  if (!s.test(0) && s.test(1) && s.test(2) && !s5)
514  method = 9; // stations 2 and 3
515  if (!s.test(0) && !s.test(1) && s.test(2) && s.test(3))
516  method = 11; // stations 3 and 4
517  }
518 
520 
521  // phib values of track segments from stations 1, 2 and 4
522  int phib1 = (getTSphi(1) != nullptr) ? getTSphi(1)->phib() : 0;
523  int phib2 = (getTSphi(2) != nullptr) ? getTSphi(2)->phib() : 0;
524  int phib4 = (getTSphi(4) != nullptr) ? getTSphi(4)->phib() : 0;
525 
526  PtAssMethod pam = NODEF;
527 
528  switch (method) {
529  case 0: {
530  pam = (abs(phib1) < threshold) ? PT12H : PT12L;
531  break;
532  }
533  case 1: {
534  pam = (abs(phib1) < threshold) ? PT13H : PT13L;
535  break;
536  }
537  case 2: {
538  pam = (abs(phib1) < threshold) ? PT14H : PT14L;
539  break;
540  }
541  case 3: {
542  pam = (abs(phib2) < threshold) ? PT23H : PT23L;
543  break;
544  }
545  case 4: {
546  pam = (abs(phib2) < threshold) ? PT24H : PT24L;
547  break;
548  }
549  case 5: {
550  pam = (abs(phib4) < threshold) ? PT34H : PT34L;
551  break;
552  }
553  case 6: {
554  pam = (abs(phib1) < threshold) ? PT12HO : PT12LO;
555  break;
556  }
557  case 7: {
558  pam = (abs(phib1) < threshold) ? PT13HO : PT13LO;
559  break;
560  }
561  case 8: {
562  pam = (abs(phib1) < threshold) ? PT14HO : PT14LO;
563  break;
564  }
565  case 9: {
566  pam = (abs(phib2) < threshold) ? PT23HO : PT23LO;
567  break;
568  }
569  case 10: {
570  pam = (abs(phib2) < threshold) ? PT24HO : PT24LO;
571  break;
572  }
573  case 11: {
574  pam = (abs(phib4) < threshold) ? PT34HO : PT34LO;
575  break;
576  }
577  case 12: {
578  pam = (abs(phib1) < threshold) ? PT15HO : PT15LO;
579  break;
580  }
581  case 13: {
582  pam = (abs(phib2) < threshold) ? PT25HO : PT25LO;
583  break;
584  }
585  default:;
586  //cout << "L1MuDTAssignmentUnit : Error in PT ass method evaluation" << endl;
587  }
588 
589  return pam;
590 }
591 
592 //
593 // calculate bend angle
594 //
596  // calculate bend angle as difference of two azimuthal positions
597 
598  int bendangle = 0;
599  switch (method) {
600  case PT12L: {
601  bendangle = phiDiff(1, 2);
602  break;
603  }
604  case PT12H: {
605  bendangle = phiDiff(1, 2);
606  break;
607  }
608  case PT13L: {
609  bendangle = phiDiff(1, 3);
610  break;
611  }
612  case PT13H: {
613  bendangle = phiDiff(1, 3);
614  break;
615  }
616  case PT14L: {
617  bendangle = phiDiff(1, 4);
618  break;
619  }
620  case PT14H: {
621  bendangle = phiDiff(1, 4);
622  break;
623  }
624  case PT23L: {
625  bendangle = phiDiff(2, 3);
626  break;
627  }
628  case PT23H: {
629  bendangle = phiDiff(2, 3);
630  break;
631  }
632  case PT24L: {
633  bendangle = phiDiff(2, 4);
634  break;
635  }
636  case PT24H: {
637  bendangle = phiDiff(2, 4);
638  break;
639  }
640  case PT34L: {
641  bendangle = phiDiff(4, 3);
642  break;
643  }
644  case PT34H: {
645  bendangle = phiDiff(4, 3);
646  break;
647  }
648  case PT12LO: {
649  bendangle = phiDiff(1, 2);
650  break;
651  }
652  case PT12HO: {
653  bendangle = phiDiff(1, 2);
654  break;
655  }
656  case PT13LO: {
657  bendangle = phiDiff(1, 3);
658  break;
659  }
660  case PT13HO: {
661  bendangle = phiDiff(1, 3);
662  break;
663  }
664  case PT14LO: {
665  bendangle = phiDiff(1, 4);
666  break;
667  }
668  case PT14HO: {
669  bendangle = phiDiff(1, 4);
670  break;
671  }
672  case PT23LO: {
673  bendangle = phiDiff(2, 3);
674  break;
675  }
676  case PT23HO: {
677  bendangle = phiDiff(2, 3);
678  break;
679  }
680  case PT24LO: {
681  bendangle = phiDiff(2, 4);
682  break;
683  }
684  case PT24HO: {
685  bendangle = phiDiff(2, 4);
686  break;
687  }
688  case PT34LO: {
689  bendangle = phiDiff(4, 3);
690  break;
691  }
692  case PT34HO: {
693  bendangle = phiDiff(4, 3);
694  break;
695  }
696  case PT15LO: {
697  bendangle = phiDiff(1, 3);
698  break;
699  }
700  case PT15HO: {
701  bendangle = phiDiff(1, 3);
702  break;
703  }
704  case PT25LO: {
705  bendangle = phiDiff(2, 3);
706  break;
707  }
708  case PT25HO: {
709  bendangle = phiDiff(2, 3);
710  break;
711  }
712  case NODEF: {
713  bendangle = 0;
714  // cerr << "AssignmentUnit::getPtAddress : undefined PtAssMethod" << endl;
715  break;
716  }
717  }
718 
719  int signo = 1;
720  bendangle = (bendangle + 8192) % 4096;
721  if (bendangle > 2047)
722  bendangle -= 4096;
723  if (bendangle < 0)
724  signo = -1;
725 
726  if (bendcharge)
727  return signo;
728 
729  bendangle = (bendangle + 2048) % 1024;
730  if (bendangle > 511)
731  bendangle -= 1024;
732 
733  return bendangle;
734 }
735 
736 //
737 // build difference of two phi values
738 //
739 int L1MuDTAssignmentUnit::phiDiff(int stat1, int stat2) const {
740  // calculate bit shift
741 
742  int sh_phi = 12 - nbit_phi;
743 
744  // get 2 phi values and add offset (30 degrees ) for adjacent sector
745  int sector1 = getTSphi(stat1)->sector();
746  int sector2 = getTSphi(stat2)->sector();
747  int phi1 = getTSphi(stat1)->phi() >> sh_phi;
748  int phi2 = getTSphi(stat2)->phi() >> sh_phi;
749 
750  // convert sector difference to values in the range -6 to +5
751 
752  int sectordiff = (sector2 - sector1) % 12;
753  if (sectordiff >= 6)
754  sectordiff -= 12;
755  if (sectordiff < -6)
756  sectordiff += 12;
757 
758  // assert( abs(sectordiff) <= 1 );
759 
760  int offset = (2144 >> sh_phi) * sectordiff;
761  int bendangle = l1t::bitShift((phi2 - phi1 + offset), sh_phi);
762 
763  return bendangle;
764 }
765 
766 //
767 // set precision for pt-assignment of phi and phib
768 // default is 12 bits for phi and 10 bits for phib
769 //
773 }
774 
775 // static data members
unsigned short station(int stat) const
get address of a given station [1-4]
int address(int id, int stat) const
get address of a single station of selected track candidate
int getPtLutThreshold(int pta_ind) const
get pt-assignment LUT threshold
void PtAU(const edm::EventSetup &c)
assign pt and charge
int getNbitsPtaPhi() const
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
void setPt(int pt)
set pt-code of muon candidate
Definition: L1MuDTTrack.h:146
const L1MuDTTrackFinder & tf() const
return reference to barrel MTTF
bool ovl() const
is it an overlap region Sector Processor?
void QuaAU()
assign quality
unsigned short nbit_phib
of bits used for pt-assignment
void reset()
reset address array
const L1MuDTTrack * tracK(int id) const
return pointer to muon candidate, index [0,1]
int getNbitsPtaPhib() const
edm::ESGetToken< L1MuDTPtaLut, L1MuDTPtaLutRcd > thePtaToken
int getDeltaPhi(int idx, int address) const
get delta-phi for a given address (bend-angle)
int sector() const
return sector number
int getCharge(PtAssMethod)
determine charge
const L1MuDTTrackSegPhi * getTSphi(int station) const
get track segment from a given station
int phib() const
return phib
void setTC(TrackClass tc)
set track-class of muon candidate
Definition: L1MuDTTrack.h:134
L1MuDTAddressArray m_addArray
const L1MuDTDataBuffer * data() const
return pointer to Data Buffer
const TSPhivector & getTSphi() const
get all track segments from the buffer
void setAddresses(const L1MuDTAddressArray &addr)
set relative addresses of muon candidate
Definition: L1MuDTTrack.h:158
void run(const edm::EventSetup &c)
run Assignment Unit
void enable()
enable muon candidate
Definition: L1MuDTTrack.h:122
edm::ESHandle< L1MuDTPtaLut > thePtaLUTs
pt-assignment look-up tables
U second(std::pair< T, U > const &p)
L1MuDTSectorProcessor & m_sp
void setBx(int bx)
Set Bunch Crossing.
std::vector< const L1MuDTTrackSegPhi * > m_TSphi
const L1MuDTSecProcId & id() const
return Sector Processor identifier
PtAssMethod getPtMethod() const
determine pt assignment method
void reset()
reset Assignment Unit
unsigned short nbit_phi
of bits used for pt-assignment
int phiDiff(int stat1, int stat2) const
build difference of two phi values
~L1MuDTAssignmentUnit()
destructor
void TSR()
Track Segment Router.
int getNbitsPhiPhi() const
int phi() const
return phi
void setTSphi(const std::vector< const L1MuDTTrackSegPhi *> &tsList)
set phi track segments used to form the muon candidate
Definition: L1MuDTTrack.cc:145
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int getPtAddress(PtAssMethod, int bendcharge=0) const
calculate bend angle
void setQuality(unsigned int quality)
set quality of muon candidate
Definition: L1MuDTTrack.h:155
L1MuDTAssignmentUnit(L1MuDTSectorProcessor &sp, int id, edm::ConsumesCollector)
constructor
int convertSector(int)
convert sector Id to 8 bit code (= sector center)
void PhiAU(const edm::EventSetup &c)
assign phi
void setPrecision()
set precision of phi and phib
int sector() const
return sector
static L1MuDTTFConfig * config()
return configuration
TrackClass trackClass(int id) const
return Track Class of found track
edm::ESGetToken< L1MuDTPhiLut, L1MuDTPhiLutRcd > thePhiToken
edm::ESHandle< L1MuDTPhiLut > thePhiLUTs
phi-assignment look-up tables
const L1MuDTTrackAssembler * TA() const
return pointer to Track Assembler
string quality
int getNbitsPhiPhib() const
const L1MuDTTrack * track(int id) const
return pointer to muon candidate, index [0,1]
int getPt(int pta_ind, int address) const
get pt-value for a given address
int bitShift(int num, int bits)
Definition: BitShift.h:6
const std::bitset< 4 > & trackBitMap(int id) const
return bitmap of found track
void setPhi(int phi)
set phi-code of muon candidate
Definition: L1MuDTTrack.h:137
PtAssMethod
void setCharge(int charge)
set charge of muon candidate
Definition: L1MuDTTrack.h:149