CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
L1MuDTAssignmentUnit.cc
Go to the documentation of this file.
1 //-------------------------------------------------
2 //
3 // Class: L1MuDTAssignmentUnit
4 //
5 // Description: Assignment Unit
6 //
7 //
8 // $Date: 2010/09/10 12:26:35 $
9 // $Revision: 1.11 $
10 //
11 // Author :
12 // N. Neumeister CERN EP
13 // J. Troconiz UAM Madrid
14 //
15 //--------------------------------------------------
16 
17 //-----------------------
18 // This Class's Header --
19 //-----------------------
20 
22 
23 //---------------
24 // C++ Headers --
25 //---------------
26 
27 #include <iostream>
28 #include <cmath>
29 #include <cassert>
30 
31 //-------------------------------
32 // Collaborating Class Headers --
33 //-------------------------------
34 
47 
48 using namespace std;
49 
50 // --------------------------------
51 // class L1MuDTAssignmentUnit
52 //---------------------------------
53 
54 //----------------
55 // Constructors --
56 //----------------
57 
59  m_sp(sp), m_id(id),
60  m_addArray(), m_TSphi(), m_ptAssMethod(NODEF) {
61 
62  m_TSphi.reserve(4); // a track candidate can consist of max 4 TS
63  reset();
64 
65  setPrecision();
66 
67 }
68 
69 
70 //--------------
71 // Destructor --
72 //--------------
73 
75 
76 
77 //--------------
78 // Operations --
79 //--------------
80 
81 //
82 // run Assignment Unit
83 //
85 
86  // enable track candidate
87  m_sp.track(m_id)->enable();
88  m_sp.tracK(m_id)->enable();
89 
90  // set track class
91  TrackClass tc = m_sp.TA()->trackClass(m_id);
92  m_sp.track(m_id)->setTC(tc);
93  m_sp.tracK(m_id)->setTC(tc);
94 
95  // get relative addresses of matching track segments
99 
100  // get track segments (track segment router)
101  TSR();
104 
105  // set bunch-crossing (use first track segment)
106  vector<const L1MuDTTrackSegPhi*>::const_iterator iter = m_TSphi.begin();
107  int bx = (*iter)->bx();
108  m_sp.track(m_id)->setBx(bx);
109  m_sp.tracK(m_id)->setBx(bx);
110 
111  // assign phi
112  PhiAU(c);
113 
114  // assign pt and charge
115  PtAU(c);
116 
117  // assign quality
118  QuaAU();
119 
120  // special hack for overlap region
121  // for ( iter = m_TSphi.begin(); iter != m_TSphi.end(); iter++ ) {
122  // int wheel = abs((*iter)->wheel());
123  // if ( wheel == 3 && (*iter)->etaFlag() ) m_sp.track(m_id)->disable();
124  // if ( wheel == 3 && (*iter)->etaFlag() ) m_sp.tracK(m_id)->disable();
125  // }
126 
127 }
128 
129 
130 //
131 // reset Assignment Unit
132 //
134 
135  m_addArray.reset();
136  m_TSphi.clear();
138 
139 }
140 
141 
142 //
143 // assign phi with 8 bit precision
144 //
146 
147  // calculate phi at station 2 using 8 bits (precision = 2.5 degrees)
148 
149  c.get< L1MuDTPhiLutRcd >().get( thePhiLUTs );
150 
151  int sh_phi = 12 - L1MuDTTFConfig::getNbitsPhiPhi();
152  int sh_phib = 10 - L1MuDTTFConfig::getNbitsPhiPhib();
153 
154  const L1MuDTTrackSegPhi* second = getTSphi(2); // track segment at station 2
155  const L1MuDTTrackSegPhi* first = getTSphi(1); // track segment at station 1
156  const L1MuDTTrackSegPhi* forth = getTSphi(4); // track segment at station 4
157 
158  int phi2 = 0; // phi-value at station 2
159  int sector = 0;
160 
161  if ( second ) {
162  phi2 = second->phi() >> sh_phi;
163  sector = second->sector();
164  }
165  else if ( second == 0 && first ) {
166  phi2 = first->phi() >> sh_phi;
167  sector = first->sector();
168  }
169  else if ( second == 0 && forth ) {
170  phi2 = forth->phi() >> sh_phi;
171  sector = forth->sector();
172  }
173 
174  int sector0 = m_sp.id().sector();
175 
176  // convert sector difference to values in the range -6 to +5
177 
178  int sectordiff = (sector - sector0)%12;
179  if ( sectordiff >= 6 ) sectordiff -= 12;
180  if ( sectordiff < -6 ) sectordiff += 12;
181 
182  // assert( abs(sectordiff) <= 1 );
183 
184  // get sector center in 8 bit coding
185  int sector_8 = convertSector(sector0);
186 
187  // convert phi to 2.5 degree precision
188  int phi_precision = 4096 >> sh_phi;
189  const double k = 57.2958/2.5/static_cast<float>(phi_precision);
190  double phi_f = static_cast<double>(phi2);
191  int phi_8 = static_cast<int>(floor(phi_f*k));
192 
193  if ( second == 0 && first ) {
194  int bend_angle = (first->phib() >> sh_phib) << sh_phib;
195  phi_8 = phi_8 + thePhiLUTs->getDeltaPhi(0,bend_angle);
196  }
197  else if ( second == 0 && forth ) {
198  int bend_angle = (forth->phib() >> sh_phib) << sh_phib;
199  phi_8 = phi_8 + thePhiLUTs->getDeltaPhi(1,bend_angle);
200  }
201 
202  phi_8 += sectordiff*12;
203 
204  if (phi_8 > 15) phi_8 = 15;
205  if (phi_8 < -16) phi_8 = -16;
206 
207  int phi = (sector_8 + phi_8 + 144)%144;
208  phi_8 = (phi_8 + 32)%32;
209 
210  m_sp.track(m_id)->setPhi(phi);
211  m_sp.tracK(m_id)->setPhi(phi_8);
212 
213 }
214 
215 
216 //
217 // assign pt with 5 bit precision
218 //
220 
221  c.get< L1MuDTPtaLutRcd >().get( thePtaLUTs );
222 
223  // get pt-assignment method as function of track class and TS phib values
225 
226  // get input address for look-up table
227  int bend_angle = getPtAddress(m_ptAssMethod);
228  int bend_carga = getPtAddress(m_ptAssMethod, 1);
229 
230  // retrieve pt value from look-up table
231  int lut_idx = m_ptAssMethod;
232  int pt = thePtaLUTs->getPt(lut_idx,bend_angle );
233 
234  m_sp.track(m_id)->setPt(pt);
235  m_sp.tracK(m_id)->setPt(pt);
236 
237  // assign charge
238  int chsign = getCharge(m_ptAssMethod);
239  int charge = ( bend_carga >= 0 ) ? chsign : -1 * chsign;
240  m_sp.track(m_id)->setCharge(charge);
241  m_sp.tracK(m_id)->setCharge(charge);
242 
243 }
244 
245 
246 //
247 // assign 3 bit quality code
248 //
250 
251  unsigned int quality = 0;
252 
253  const TrackClass tc = m_sp.TA()->trackClass(m_id);
254 
255  switch ( tc ) {
256  case T1234 : { quality = 7; break; }
257  case T123 : { quality = 6; break; }
258  case T124 : { quality = 6; break; }
259  case T134 : { quality = 5; break; }
260  case T234 : { quality = 4; break; }
261  case T12 : { quality = 3; break; }
262  case T13 : { quality = 3; break; }
263  case T14 : { quality = 3; break; }
264  case T23 : { quality = 2; break; }
265  case T24 : { quality = 2; break; }
266  case T34 : { quality = 1; break; }
267  default : { quality = 0; break; }
268  }
269 
270  m_sp.track(m_id)->setQuality(quality);
271  m_sp.tracK(m_id)->setQuality(quality);
272 
273 }
274 
275 
276 //
277 // Track Segment Router (TSR)
278 //
280 
281  // get the track segments from the data buffer
282  const L1MuDTTrackSegPhi* ts = 0;
283  for ( int stat = 1; stat <= 4; stat++ ) {
284  int adr = m_addArray.station(stat);
285  if ( adr != 15 ) {
286  ts = m_sp.data()->getTSphi(stat,adr);
287  if ( ts != 0 ) m_TSphi.push_back( ts );
288  }
289  }
290 
291 }
292 
293 
294 //
295 // get track segment from a given station
296 //
298 
299  vector<const L1MuDTTrackSegPhi*>::const_iterator iter;
300  for ( iter = m_TSphi.begin(); iter != m_TSphi.end(); iter++ ) {
301  int stat = (*iter)->station();
302  if ( station == stat ) {
303  return (*iter);
304  break;
305  }
306  }
307 
308  return 0;
309 
310 }
311 
312 
313 //
314 // convert sector Id to a precision of 2.5 degrees using 8 bits (= sector center)
315 //
317 
318  // assert( sector >=0 && sector < 12 );
319  const int sectorvalues[12] = { 0, 12, 24, 36, 48, 60, 72, 84,
320  96, 108, 120, 132 };
321 
322  return sectorvalues[sector];
323 
324 }
325 
326 
327 //
328 // determine charge
329 //
331 
332  int chargesign = 0;
333  switch ( method ) {
334  case PT12L : { chargesign = -1; break; }
335  case PT12H : { chargesign = -1; break; }
336  case PT13L : { chargesign = -1; break; }
337  case PT13H : { chargesign = -1; break; }
338  case PT14L : { chargesign = -1; break; }
339  case PT14H : { chargesign = -1; break; }
340  case PT23L : { chargesign = -1; break; }
341  case PT23H : { chargesign = -1; break; }
342  case PT24L : { chargesign = -1; break; }
343  case PT24H : { chargesign = -1; break; }
344  case PT34L : { chargesign = 1; break; }
345  case PT34H : { chargesign = 1; break; }
346  case PT12LO : { chargesign = -1; break; }
347  case PT12HO : { chargesign = -1; break; }
348  case PT13LO : { chargesign = -1; break; }
349  case PT13HO : { chargesign = -1; break; }
350  case PT14LO : { chargesign = -1; break; }
351  case PT14HO : { chargesign = -1; break; }
352  case PT23LO : { chargesign = -1; break; }
353  case PT23HO : { chargesign = -1; break; }
354  case PT24LO : { chargesign = -1; break; }
355  case PT24HO : { chargesign = -1; break; }
356  case PT34LO : { chargesign = 1; break; }
357  case PT34HO : { chargesign = 1; break; }
358  case PT15LO : { chargesign = -1; break; }
359  case PT15HO : { chargesign = -1; break; }
360  case PT25LO : { chargesign = -1; break; }
361  case PT25HO : { chargesign = -1; break; }
362  case NODEF : { chargesign = 0;
363  // cerr << "AssignmentUnit::getCharge : undefined PtAssMethod!"
364  // << endl;
365  break;
366  }
367  }
368 
369  return chargesign;
370 
371 }
372 
373 
374 //
375 // determine pt-assignment method
376 //
378 
379  // determine which pt-assignment method should be used as a function
380  // of the track class and
381  // of the phib values of the track segments making up this track candidate.
382 
383  // get bitmap of track candidate
384  const bitset<4> s = m_sp.TA()->trackBitMap(m_id);
385 
386  int method = -1;
387 
388  if ( s.test(0) && s.test(3) ) method = 2; // stations 1 and 4
389  if ( s.test(0) && s.test(2) ) method = 1; // stations 1 and 3
390  if ( s.test(0) && s.test(1) ) method = 0; // stations 1 and 2
391  if ( !s.test(0) && s.test(1) && s.test(3) ) method = 4; // stations 2 and 4
392  if ( !s.test(0) && s.test(1) && s.test(2) ) method = 3; // stations 2 and 3
393  if ( !s.test(0) && !s.test(1) && s.test(2) && s.test(3) ) method = 5; // stations 3 and 4
394 
395  if ( m_sp.ovl() ) {
396  int adr = m_addArray.station(3);
397  bool s5 = (adr == 15) ? false : ((adr/2)%2 == 1);
398  if ( s.test(0) && s.test(3) ) method = 8; // stations 1 and 4
399  if ( s.test(0) && s.test(2) && s5 ) method = 12; // stations 1 and 5
400  if ( s.test(0) && s.test(2) && !s5 ) method = 7; // stations 1 and 3
401  if ( s.test(0) && s.test(1) ) method = 6; // stations 1 and 2
402  if ( !s.test(0) && s.test(1) && s.test(3) ) method = 10; // stations 2 and 4
403  if ( !s.test(0) && s.test(1) && s.test(2) && s5 ) method = 13; // stations 2 and 5
404  if ( !s.test(0) && s.test(1) && s.test(2) && !s5 ) method = 9; // stations 2 and 3
405  if ( !s.test(0) && !s.test(1) && s.test(2) && s.test(3) ) method = 11; // stations 3 and 4
406  }
407 
408  int threshold = thePtaLUTs->getPtLutThreshold(method);
409 
410  // phib values of track segments from stations 1, 2 and 4
411  int phib1 = ( getTSphi(1) != 0 ) ? getTSphi(1)->phib() : 0;
412  int phib2 = ( getTSphi(2) != 0 ) ? getTSphi(2)->phib() : 0;
413  int phib4 = ( getTSphi(4) != 0 ) ? getTSphi(4)->phib() : 0;
414 
415  PtAssMethod pam = NODEF;
416 
417  switch ( method ) {
418  case 0 : { pam = ( abs(phib1) < threshold ) ? PT12H : PT12L; break; }
419  case 1 : { pam = ( abs(phib1) < threshold ) ? PT13H : PT13L; break; }
420  case 2 : { pam = ( abs(phib1) < threshold ) ? PT14H : PT14L; break; }
421  case 3 : { pam = ( abs(phib2) < threshold ) ? PT23H : PT23L; break; }
422  case 4 : { pam = ( abs(phib2) < threshold ) ? PT24H : PT24L; break; }
423  case 5 : { pam = ( abs(phib4) < threshold ) ? PT34H : PT34L; break; }
424  case 6 : { pam = ( abs(phib1) < threshold ) ? PT12HO : PT12LO; break; }
425  case 7 : { pam = ( abs(phib1) < threshold ) ? PT13HO : PT13LO; break; }
426  case 8 : { pam = ( abs(phib1) < threshold ) ? PT14HO : PT14LO; break; }
427  case 9 : { pam = ( abs(phib2) < threshold ) ? PT23HO : PT23LO; break; }
428  case 10 : { pam = ( abs(phib2) < threshold ) ? PT24HO : PT24LO; break; }
429  case 11 : { pam = ( abs(phib4) < threshold ) ? PT34HO : PT34LO; break; }
430  case 12 : { pam = ( abs(phib1) < threshold ) ? PT15HO : PT15LO; break; }
431  case 13 : { pam = ( abs(phib2) < threshold ) ? PT25HO : PT25LO; break; }
432  default : ;
433  //cout << "L1MuDTAssignmentUnit : Error in PT ass method evaluation" << endl;
434  }
435 
436  return pam;
437 
438 }
439 
440 
441 //
442 // calculate bend angle
443 //
445 
446  // calculate bend angle as difference of two azimuthal positions
447 
448  int bendangle = 0;
449  switch (method) {
450  case PT12L : { bendangle = phiDiff(1,2); break; }
451  case PT12H : { bendangle = phiDiff(1,2); break; }
452  case PT13L : { bendangle = phiDiff(1,3); break; }
453  case PT13H : { bendangle = phiDiff(1,3); break; }
454  case PT14L : { bendangle = phiDiff(1,4); break; }
455  case PT14H : { bendangle = phiDiff(1,4); break; }
456  case PT23L : { bendangle = phiDiff(2,3); break; }
457  case PT23H : { bendangle = phiDiff(2,3); break; }
458  case PT24L : { bendangle = phiDiff(2,4); break; }
459  case PT24H : { bendangle = phiDiff(2,4); break; }
460  case PT34L : { bendangle = phiDiff(4,3); break; }
461  case PT34H : { bendangle = phiDiff(4,3); break; }
462  case PT12LO : { bendangle = phiDiff(1,2); break; }
463  case PT12HO : { bendangle = phiDiff(1,2); break; }
464  case PT13LO : { bendangle = phiDiff(1,3); break; }
465  case PT13HO : { bendangle = phiDiff(1,3); break; }
466  case PT14LO : { bendangle = phiDiff(1,4); break; }
467  case PT14HO : { bendangle = phiDiff(1,4); break; }
468  case PT23LO : { bendangle = phiDiff(2,3); break; }
469  case PT23HO : { bendangle = phiDiff(2,3); break; }
470  case PT24LO : { bendangle = phiDiff(2,4); break; }
471  case PT24HO : { bendangle = phiDiff(2,4); break; }
472  case PT34LO : { bendangle = phiDiff(4,3); break; }
473  case PT34HO : { bendangle = phiDiff(4,3); break; }
474  case PT15LO : { bendangle = phiDiff(1,3); break; }
475  case PT15HO : { bendangle = phiDiff(1,3); break; }
476  case PT25LO : { bendangle = phiDiff(2,3); break; }
477  case PT25HO : { bendangle = phiDiff(2,3); break; }
478  case NODEF : { bendangle = 0;
479  // cerr << "AssignmentUnit::getPtAddress : undefined PtAssMethod" << endl;
480  break;
481  }
482  }
483 
484  int signo = 1;
485  bendangle = (bendangle+8192)%4096;
486  if ( bendangle > 2047 ) bendangle -= 4096;
487  if ( bendangle < 0 ) signo = -1;
488 
489  if (bendcharge) return signo;
490 
491  bendangle = (bendangle+2048)%1024;
492  if ( bendangle > 511 ) bendangle -= 1024;
493 
494  return bendangle;
495 
496 }
497 
498 
499 //
500 // build difference of two phi values
501 //
502 int L1MuDTAssignmentUnit::phiDiff(int stat1, int stat2) const {
503 
504  // calculate bit shift
505 
506  int sh_phi = 12 - nbit_phi;
507 
508  // get 2 phi values and add offset (30 degrees ) for adjacent sector
509  int sector1 = getTSphi(stat1)->sector();
510  int sector2 = getTSphi(stat2)->sector();
511  int phi1 = getTSphi(stat1)->phi() >> sh_phi;
512  int phi2 = getTSphi(stat2)->phi() >> sh_phi;
513 
514  // convert sector difference to values in the range -6 to +5
515 
516  int sectordiff = (sector2 - sector1)%12;
517  if ( sectordiff >= 6 ) sectordiff -= 12;
518  if ( sectordiff < -6 ) sectordiff += 12;
519 
520  // assert( abs(sectordiff) <= 1 );
521 
522  int offset = (2144 >> sh_phi) * sectordiff;
523  int bendangle = (phi2 - phi1 + offset) << sh_phi;
524 
525  return bendangle;
526 
527 }
528 
529 
530 //
531 // set precision for pt-assignment of phi and phib
532 // default is 12 bits for phi and 10 bits for phib
533 //
535 
538 
539 }
540 
541 
542 // static data members
543 
544 unsigned short int L1MuDTAssignmentUnit::nbit_phi = 12;
545 unsigned short int L1MuDTAssignmentUnit::nbit_phib = 10;
void PtAU(const edm::EventSetup &c)
assign pt and charge
void setPt(int pt)
set pt-code of muon candidate
Definition: L1MuDTTrack.h:149
L1MuDTTrack * tracK(int id) const
return pointer to muon candidate, index [0,1]
edm::ESHandle< L1MuDTPhiLut > thePhiLUTs
phi-assignment look-up tables
void QuaAU()
assign quality
int station() const
return station
void reset()
reset address array
edm::ESHandle< L1MuDTPtaLut > thePtaLUTs
pt-assignment look-up tables
#define abs(x)
Definition: mlp_lapack.h:159
void setTSphi(const std::vector< const L1MuDTTrackSegPhi * > &tsList)
set phi track segments used to form the muon candidate
Definition: L1MuDTTrack.cc:170
static int getCharge(PtAssMethod)
determine charge
int phi() const
return phi
void setTC(TrackClass tc)
set track-class of muon candidate
Definition: L1MuDTTrack.h:137
L1MuDTAddressArray m_addArray
double charge(const std::vector< uint8_t > &Ampls)
static int getNbitsPhiPhi()
void setAddresses(const L1MuDTAddressArray &addr)
set relative addresses of muon candidate
Definition: L1MuDTTrack.h:158
static int getNbitsPtaPhi()
void enable()
enable muon candidate
Definition: L1MuDTTrack.h:128
int sector() const
return sector number
const L1MuDTDataBuffer * data() const
return pointer to Data Buffer
U second(std::pair< T, U > const &p)
L1MuDTSectorProcessor & m_sp
void setBx(int bx)
Set Bunch Crossing.
std::vector< const L1MuDTTrackSegPhi * > m_TSphi
static unsigned short nbit_phib
of bits used for pt-assignment
virtual void reset()
reset Assignment Unit
virtual ~L1MuDTAssignmentUnit()
destructor
const L1MuDTTrackAssembler * TA() const
return pointer to Track Assembler
void TSR()
Track Segment Router.
const L1MuDTTrackSegPhi * getTSphi(int station) const
get track segment from a given station
virtual void run()
run processor logic
const std::bitset< 4 > & trackBitMap(int id) const
return bitmap of found track
int phib() const
return phib
int phiDiff(int stat1, int stat2) const
build difference of two phi values
const L1MuDTSecProcId & id() const
return Sector Processor identifier
void setQuality(unsigned int quality)
set quality of muon candidate
Definition: L1MuDTTrack.h:155
unsigned int offset(bool)
bool first
Definition: L1TdeRCT.cc:94
int k[5][pyjets_maxn]
static int getNbitsPhiPhib()
const TSPhivector & getTSphi() const
get all track segments from the buffer
static int convertSector(int)
convert sector Id to 8 bit code (= sector center)
void PhiAU(const edm::EventSetup &c)
assign phi
static void setPrecision()
set precision of phi and phib
const T & get() const
Definition: EventSetup.h:55
int getPtAddress(PtAssMethod, int bendcharge=0) const
calculate bend angle
int sector() const
return sector
static int getNbitsPtaPhib()
TrackClass trackClass(int id) const
return Track Class of found track
PtAssMethod getPtMethod() const
determine pt assignment method
L1MuDTTrack * track(int id) const
return pointer to muon candidate, index [0,1]
int address(int id, int stat) const
get address of a single station of selected track candidate
unsigned short station(int stat) const
get address of a given station [1-4]
L1MuDTAssignmentUnit(L1MuDTSectorProcessor &sp, int id)
constructor
void setPhi(int phi)
set phi-code of muon candidate
Definition: L1MuDTTrack.h:140
bool ovl() const
is it an overlap region Sector Processor?
static unsigned short nbit_phi
of bits used for pt-assignment
PtAssMethod
void setCharge(int charge)
set charge of muon candidate
Definition: L1MuDTTrack.h:152
Definition: DDAxes.h:10