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