Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-09-28 23:48:42

0001 //-------------------------------------------------
0002 //
0003 //   Class: L1MuBMAssignmentUnit
0004 //
0005 //   Description: Assignment Unit
0006 //
0007 //
0008 //
0009 //   Author :
0010 //   N. Neumeister            CERN EP
0011 //   J. Troconiz              UAM Madrid
0012 //   Modifications:
0013 //   G. Flouris               U. Ioannina
0014 //   G Karathanasis           U. Athens
0015 //--------------------------------------------------
0016 
0017 //-----------------------
0018 // This Class's Header --
0019 //-----------------------
0020 
0021 #include "L1Trigger/L1TMuonBarrel/src/L1MuBMAssignmentUnit.h"
0022 
0023 //---------------
0024 // C++ Headers --
0025 //---------------
0026 
0027 #include <iostream>
0028 #include <cmath>
0029 #include <cassert>
0030 
0031 //-------------------------------
0032 // Collaborating Class Headers --
0033 //-------------------------------
0034 
0035 #include "L1Trigger/L1TMuonBarrel/src/L1MuBMTFConfig.h"
0036 #include "L1Trigger/L1TMuonBarrel/src/L1MuBMSectorProcessor.h"
0037 #include "L1Trigger/L1TMuonBarrel/src/L1MuBMDataBuffer.h"
0038 #include "L1Trigger/L1TMuonBarrel/src/L1MuBMTrackAssembler.h"
0039 #include "DataFormats/L1TMuon/interface/L1MuBMTrackSegPhi.h"
0040 #include "DataFormats/L1TMuon/interface/BMTF/L1MuBMTrackSegLoc.h"
0041 #include "DataFormats/L1TMuon/interface/BMTF/L1MuBMTrackAssParam.h"
0042 
0043 #include <iostream>
0044 #include <iomanip>
0045 
0046 using namespace std;
0047 // --------------------------------
0048 //       class L1MuBMAssignmentUnit
0049 //---------------------------------
0050 
0051 //----------------
0052 // Constructors --
0053 //----------------
0054 
0055 L1MuBMAssignmentUnit::L1MuBMAssignmentUnit(L1MuBMSectorProcessor& sp, int id)
0056     : m_sp(sp), m_id(id), m_addArray(), m_TSphi(), m_ptAssMethod(L1MuBMLUTHandler::NODEF) {
0057   m_TSphi.reserve(4);  // a track candidate can consist of max 4 TS
0058   reset();
0059   setPrecision();
0060 }
0061 
0062 //--------------
0063 // Destructor --
0064 //--------------
0065 
0066 L1MuBMAssignmentUnit::~L1MuBMAssignmentUnit() {}
0067 
0068 //--------------
0069 // Operations --
0070 //--------------
0071 
0072 //
0073 // run Assignment Unit
0074 //
0075 void L1MuBMAssignmentUnit::run(const L1TMuonBarrelParams& bmtfParams) {
0076   // enable track candidate
0077   m_sp.track(m_id)->enable();
0078   m_sp.tracK(m_id)->enable();
0079 
0080   // set track class
0081   TrackClass tc = m_sp.TA()->trackClass(m_id);
0082   m_sp.track(m_id)->setTC(tc);
0083   m_sp.tracK(m_id)->setTC(tc);
0084 
0085   // get relative addresses of matching track segments
0086   m_addArray = m_sp.TA()->address(m_id);
0087   m_sp.track(m_id)->setAddresses(m_addArray);
0088   m_sp.tracK(m_id)->setAddresses(m_addArray);
0089 
0090   // get track segments (track segment router)
0091   TSR();
0092   m_sp.track(m_id)->setTSphi(m_TSphi);
0093   m_sp.tracK(m_id)->setTSphi(m_TSphi);
0094 
0095   // set bunch-crossing (use first track segment)
0096   vector<const L1MuBMTrackSegPhi*>::const_iterator iter = m_TSphi.begin();
0097   int bx = (*iter)->bx();
0098   m_sp.track(m_id)->setBx(bx);
0099   m_sp.tracK(m_id)->setBx(bx);
0100 
0101   // assign phi
0102   PhiAU(bmtfParams);
0103 
0104   // assign pt and charge
0105   PtAU(bmtfParams);
0106 
0107   // assign quality
0108   QuaAU();
0109 }
0110 
0111 //
0112 // reset Assignment Unit
0113 //
0114 void L1MuBMAssignmentUnit::reset() {
0115   m_addArray.reset();
0116   m_TSphi.clear();
0117   m_ptAssMethod = L1MuBMLUTHandler::NODEF;
0118 }
0119 
0120 //
0121 // assign phi with 8 bit precision
0122 //
0123 void L1MuBMAssignmentUnit::PhiAU(const L1TMuonBarrelParams& bmtfParams) {
0124   thePhiLUTs = new L1MuBMLUTHandler(bmtfParams);  ///< phi-assignment look-up tables
0125   //thePhiLUTs->print();
0126   // calculate phi at station 2 using 8 bits (precision = 0.625 degrees)
0127   int sh_phi = 12 - L1MuBMTFConfig::getNbitsPhiPhi();
0128   int sh_phib = 10 - L1MuBMTFConfig::getNbitsPhiPhib();
0129 
0130   const L1MuBMTrackSegPhi* second = getTSphi(2);  // track segment at station 2
0131   const L1MuBMTrackSegPhi* first = getTSphi(1);   // track segment at station 1
0132   const L1MuBMTrackSegPhi* forth = getTSphi(4);   // track segment at station 4
0133 
0134   int phi2 = 0;  // phi-value at station 2
0135   int sector = 0;
0136   if (second) {
0137     phi2 = second->phi() >> sh_phi;
0138     sector = second->sector();
0139   } else if (second == nullptr && first) {
0140     phi2 = first->phi() >> sh_phi;
0141     sector = first->sector();
0142   } else if (second == nullptr && forth) {
0143     phi2 = forth->phi() >> sh_phi;
0144     sector = forth->sector();
0145   }
0146 
0147   int sector0 = m_sp.id().sector();
0148 
0149   // convert sector difference to values in the range -6 to +5
0150 
0151   int sectordiff = (sector - sector0) % 12;
0152   if (sectordiff >= 6)
0153     sectordiff -= 12;
0154   if (sectordiff < -6)
0155     sectordiff += 12;
0156 
0157   // convert phi to 0.625 degree precision
0158   int phi_precision = 4096 >> sh_phi;
0159   const double k = 57.2958 / 0.625 / static_cast<float>(phi_precision);
0160   double phi_f = static_cast<double>(phi2);
0161   int bit_div_phi = static_cast<int>(phi2) % 4;
0162   if (bit_div_phi < 0)
0163     bit_div_phi += 4;
0164   phi_f = phi_f - std::abs(bit_div_phi);
0165   int phi_8 = static_cast<int>(floor(phi_f * k));
0166 
0167   if (second == nullptr && first) {
0168     int bend_angle = (first->phib() >> sh_phib) << sh_phib;
0169     phi_8 = phi_8 + thePhiLUTs->getDeltaPhi(0, bend_angle);
0170     //phi_8 = phi_8 + getDeltaPhi(0, bend_angle, bmtfParams->phi_lut());
0171   } else if (second == nullptr && forth) {
0172     int bend_angle = (forth->phib() >> sh_phib) << sh_phib;
0173     phi_8 = phi_8 + thePhiLUTs->getDeltaPhi(1, bend_angle);
0174     //phi_8 = phi_8 + getDeltaPhi(1, bend_angle, bmtfParams->phi_lut());
0175   }
0176 
0177   //If muon is found at the neighbour sector - second station
0178   //a shift is needed by 48
0179   phi_8 += sectordiff * 48;
0180 
0181   int phi = phi_8 + 24;
0182   // 78 phi bins (-8 to 69) correspond 30 degree sector plus
0183   // additional lower and higher bins for neighboring sectors.
0184   if (phi > 69)
0185     phi = 69;
0186   if (phi < -8)
0187     phi = -8;
0188 
0189   m_sp.track(m_id)->setPhi(phi);  // Regional
0190   m_sp.tracK(m_id)->setPhi(phi);
0191 
0192   delete thePhiLUTs;
0193 }
0194 
0195 //
0196 // assign pt with 5 bit precision
0197 //
0198 void L1MuBMAssignmentUnit::PtAU(const L1TMuonBarrelParams& bmtfParams1) {
0199   const L1TMuonBarrelParamsAllPublic bmtfParams(bmtfParams1);
0200   thePtaLUTs = new L1MuBMLUTHandler(bmtfParams);  ///< pt-assignment look-up tables
0201   //thePtaLUTs->print();
0202   // get pt-assignment method as function of track class and TS phib values
0203   //m_ptAssMethod = getPtMethod(bmtfParams);
0204   m_ptAssMethod = getPtMethod();
0205   // get input address for look-up table
0206   int bend_angle = getPtAddress(m_ptAssMethod);
0207   int bend_carga = getPtAddress(m_ptAssMethod, 1);
0208 
0209   // retrieve pt value from look-up table
0210   int lut_idx = m_ptAssMethod;
0211   int pt = thePtaLUTs->getPt(lut_idx, bend_angle);
0212   //int pt = getPt(lut_idx, bend_angle, bmtfParams->pta_lut());
0213 
0214   if (!bmtfParams.get_DisableNewAlgo()) {
0215     if (Quality() < 4) {
0216       int ptj = pt;
0217       L1MuBMLUTHandler::PtAssMethod jj1 = getPt1Method(m_ptAssMethod);
0218       L1MuBMLUTHandler::PtAssMethod jj2 = getPt2Method(m_ptAssMethod);
0219       if (jj1 != L1MuBMLUTHandler::NODEF) {
0220         lut_idx = jj1;
0221         bend_angle = getPt1Address(m_ptAssMethod);
0222         if (abs(bend_angle) < 512)
0223           ptj = thePtaLUTs->getPt(lut_idx, bend_angle);
0224       } else if (jj2 != L1MuBMLUTHandler::NODEF) {
0225         lut_idx = jj2;
0226         bend_angle = getPt2Address(m_ptAssMethod);
0227         if (abs(bend_angle) < 512)
0228           ptj = thePtaLUTs->getPt(lut_idx, bend_angle);
0229       }
0230       if (ptj < pt)
0231         pt = ptj;
0232     }
0233   }
0234 
0235   m_sp.track(m_id)->setPt(pt);
0236   m_sp.tracK(m_id)->setPt(pt);
0237 
0238   // assign charge
0239   int chsign = getCharge(m_ptAssMethod);
0240   int charge = (bend_carga >= 0) ? chsign : -1 * chsign;
0241   m_sp.track(m_id)->setCharge(charge);
0242   m_sp.tracK(m_id)->setCharge(charge);
0243   delete thePtaLUTs;
0244 }
0245 
0246 //
0247 // assign 4 bit quality code
0248 //
0249 void L1MuBMAssignmentUnit::QuaAU() {
0250   unsigned int quality = 0;
0251 
0252   const TrackClass tc = m_sp.TA()->trackClass(m_id);
0253 
0254   ///Two LSBs of BMTF Q = Nstations-1
0255   switch (tc) {
0256     case T1234: {
0257       quality = 3;
0258       break;
0259     }
0260     case T123: {
0261       quality = 2;
0262       break;
0263     }
0264     case T124: {
0265       quality = 2;
0266       break;
0267     }
0268     case T134: {
0269       quality = 2;
0270       break;
0271     }
0272     case T234: {
0273       quality = 2;
0274       break;
0275     }
0276     case T12: {
0277       quality = 1;
0278       break;
0279     }
0280     case T13: {
0281       quality = 1;
0282       break;
0283     }
0284     case T14: {
0285       quality = 1;
0286       break;
0287     }
0288     case T23: {
0289       quality = 0;
0290       break;
0291     }
0292     case T24: {
0293       quality = 0;
0294       break;
0295     }
0296     case T34: {
0297       quality = 0;
0298       break;
0299     }
0300     default: {
0301       quality = 0;
0302       break;
0303     }
0304   }
0305 
0306   ///Two MSB of BMTF Q = 11
0307   quality += 12;
0308 
0309   m_sp.track(m_id)->setQuality(quality);
0310   m_sp.tracK(m_id)->setQuality(quality);
0311 }
0312 
0313 //
0314 // assign 3 bit quality code
0315 //
0316 unsigned int L1MuBMAssignmentUnit::Quality() {
0317   unsigned int quality = 0;
0318 
0319   const TrackClass tc = m_sp.TA()->trackClass(m_id);
0320 
0321   switch (tc) {
0322     case T1234: {
0323       quality = 7;
0324       break;
0325     }
0326     case T123: {
0327       quality = 6;
0328       break;
0329     }
0330     case T124: {
0331       quality = 6;
0332       break;
0333     }
0334     case T134: {
0335       quality = 5;
0336       break;
0337     }
0338     case T234: {
0339       quality = 4;
0340       break;
0341     }
0342     case T12: {
0343       quality = 3;
0344       break;
0345     }
0346     case T13: {
0347       quality = 3;
0348       break;
0349     }
0350     case T14: {
0351       quality = 3;
0352       break;
0353     }
0354     case T23: {
0355       quality = 2;
0356       break;
0357     }
0358     case T24: {
0359       quality = 2;
0360       break;
0361     }
0362     case T34: {
0363       quality = 1;
0364       break;
0365     }
0366     default: {
0367       quality = 0;
0368     }
0369   }
0370 
0371   return quality;
0372 }
0373 
0374 //
0375 // Track Segment Router (TSR)
0376 //
0377 void L1MuBMAssignmentUnit::TSR() {
0378   // get the track segments from the data buffer
0379   const L1MuBMTrackSegPhi* ts = nullptr;
0380   for (int stat = 1; stat <= 4; stat++) {
0381     int adr = m_addArray.station(stat);
0382     if (adr != 15) {
0383       ts = m_sp.data()->getTSphi(stat, adr);
0384       if (ts != nullptr)
0385         m_TSphi.push_back(ts);
0386     }
0387   }
0388 }
0389 
0390 //
0391 // get track segment from a given station
0392 //
0393 const L1MuBMTrackSegPhi* L1MuBMAssignmentUnit::getTSphi(int station) const {
0394   vector<const L1MuBMTrackSegPhi*>::const_iterator iter;
0395   for (iter = m_TSphi.begin(); iter != m_TSphi.end(); iter++) {
0396     int stat = (*iter)->station();
0397     if (station == stat) {
0398       return (*iter);
0399       break;
0400     }
0401   }
0402 
0403   return nullptr;
0404 }
0405 
0406 //
0407 // convert sector Id to a precision of 2.5 degrees using 8 bits (= sector center)
0408 //
0409 int L1MuBMAssignmentUnit::convertSector(int sector) {
0410   //  assert( sector >=0 && sector < 12 );
0411   const int sectorvalues[12] = {0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132};
0412 
0413   return sectorvalues[sector];
0414 }
0415 
0416 //
0417 // determine charge
0418 //
0419 int L1MuBMAssignmentUnit::getCharge(L1MuBMLUTHandler::PtAssMethod method) {
0420   int chargesign = 0;
0421   switch (method) {
0422     case L1MuBMLUTHandler::PT12L: {
0423       chargesign = -1;
0424       break;
0425     }
0426     case L1MuBMLUTHandler::PT12H: {
0427       chargesign = -1;
0428       break;
0429     }
0430     case L1MuBMLUTHandler::PT13L: {
0431       chargesign = -1;
0432       break;
0433     }
0434     case L1MuBMLUTHandler::PT13H: {
0435       chargesign = -1;
0436       break;
0437     }
0438     case L1MuBMLUTHandler::PT14L: {
0439       chargesign = -1;
0440       break;
0441     }
0442     case L1MuBMLUTHandler::PT14H: {
0443       chargesign = -1;
0444       break;
0445     }
0446     case L1MuBMLUTHandler::PT23L: {
0447       chargesign = -1;
0448       break;
0449     }
0450     case L1MuBMLUTHandler::PT23H: {
0451       chargesign = -1;
0452       break;
0453     }
0454     case L1MuBMLUTHandler::PT24L: {
0455       chargesign = -1;
0456       break;
0457     }
0458     case L1MuBMLUTHandler::PT24H: {
0459       chargesign = -1;
0460       break;
0461     }
0462     case L1MuBMLUTHandler::PT34L: {
0463       chargesign = 1;
0464       break;
0465     }
0466     case L1MuBMLUTHandler::PT34H: {
0467       chargesign = 1;
0468       break;
0469     }
0470 
0471     case L1MuBMLUTHandler::NODEF: {
0472       chargesign = 0;
0473       //                    cerr << "AssignmentUnit::getCharge : undefined PtAssMethod!"
0474       //                         << endl;
0475       break;
0476     }
0477     default: {
0478       chargesign = 0;
0479     }
0480   }
0481 
0482   return chargesign;
0483 }
0484 
0485 //
0486 // determine pt-assignment method
0487 //
0488 //PtAssMethod L1MuBMAssignmentUnit::getPtMethod(L1TMuonBarrelParams *l1tbmparams) const {
0489 L1MuBMLUTHandler::PtAssMethod L1MuBMAssignmentUnit::getPtMethod() const {
0490   // determine which pt-assignment method should be used as a function
0491   // of the track class and
0492   // of the phib values of the track segments making up this track candidate.
0493 
0494   // get bitmap of track candidate
0495   const bitset<4> s = m_sp.TA()->trackBitMap(m_id);
0496 
0497   int method = -1;
0498 
0499   if (s.test(0) && s.test(3))
0500     method = 2;  // stations 1 and 4
0501   if (s.test(0) && s.test(2))
0502     method = 1;  // stations 1 and 3
0503   if (s.test(0) && s.test(1))
0504     method = 0;  // stations 1 and 2
0505   if (!s.test(0) && s.test(1) && s.test(3))
0506     method = 4;  // stations 2 and 4
0507   if (!s.test(0) && s.test(1) && s.test(2))
0508     method = 3;  // stations 2 and 3
0509   if (!s.test(0) && !s.test(1) && s.test(2) && s.test(3))
0510     method = 5;  // stations 3 and 4
0511   int threshold = thePtaLUTs->getPtLutThreshold(method);
0512 
0513   // phib values of track segments from stations 1, 2 and 4
0514   int phib1 = (getTSphi(1) != nullptr) ? getTSphi(1)->phib() : 0;
0515   int phib2 = (getTSphi(2) != nullptr) ? getTSphi(2)->phib() : 0;
0516   int phib4 = (getTSphi(4) != nullptr) ? getTSphi(4)->phib() : 0;
0517 
0518   L1MuBMLUTHandler::PtAssMethod pam = L1MuBMLUTHandler::NODEF;
0519 
0520   switch (method) {
0521     case 0: {
0522       pam = (abs(phib1) < threshold) ? L1MuBMLUTHandler::PT12H : L1MuBMLUTHandler::PT12L;
0523       break;
0524     }
0525     case 1: {
0526       pam = (abs(phib1) < threshold) ? L1MuBMLUTHandler::PT13H : L1MuBMLUTHandler::PT13L;
0527       break;
0528     }
0529     case 2: {
0530       pam = (abs(phib1) < threshold) ? L1MuBMLUTHandler::PT14H : L1MuBMLUTHandler::PT14L;
0531       break;
0532     }
0533     case 3: {
0534       pam = (abs(phib2) < threshold) ? L1MuBMLUTHandler::PT23H : L1MuBMLUTHandler::PT23L;
0535       break;
0536     }
0537     case 4: {
0538       pam = (abs(phib2) < threshold) ? L1MuBMLUTHandler::PT24H : L1MuBMLUTHandler::PT24L;
0539       break;
0540     }
0541     case 5: {
0542       pam = (abs(phib4) < threshold) ? L1MuBMLUTHandler::PT34H : L1MuBMLUTHandler::PT34L;
0543       break;
0544     }
0545     default:;
0546       //cout << "L1MuBMAssignmentUnit : Error in PT ass method evaluation" << endl;
0547   }
0548 
0549   return pam;
0550 }
0551 
0552 //
0553 // calculate bend angle
0554 //
0555 int L1MuBMAssignmentUnit::getPtAddress(L1MuBMLUTHandler::PtAssMethod method, int bendcharge) const {
0556   // calculate bend angle as difference of two azimuthal positions
0557 
0558   int bendangle = 0;
0559   switch (method) {
0560     case L1MuBMLUTHandler::PT12L: {
0561       bendangle = phiDiff(1, 2);
0562       break;
0563     }
0564     case L1MuBMLUTHandler::PT12H: {
0565       bendangle = phiDiff(1, 2);
0566       break;
0567     }
0568     case L1MuBMLUTHandler::PT13L: {
0569       bendangle = phiDiff(1, 3);
0570       break;
0571     }
0572     case L1MuBMLUTHandler::PT13H: {
0573       bendangle = phiDiff(1, 3);
0574       break;
0575     }
0576     case L1MuBMLUTHandler::PT14L: {
0577       bendangle = phiDiff(1, 4);
0578       break;
0579     }
0580     case L1MuBMLUTHandler::PT14H: {
0581       bendangle = phiDiff(1, 4);
0582       break;
0583     }
0584     case L1MuBMLUTHandler::PT23L: {
0585       bendangle = phiDiff(2, 3);
0586       break;
0587     }
0588     case L1MuBMLUTHandler::PT23H: {
0589       bendangle = phiDiff(2, 3);
0590       break;
0591     }
0592     case L1MuBMLUTHandler::PT24L: {
0593       bendangle = phiDiff(2, 4);
0594       break;
0595     }
0596     case L1MuBMLUTHandler::PT24H: {
0597       bendangle = phiDiff(2, 4);
0598       break;
0599     }
0600     case L1MuBMLUTHandler::PT34L: {
0601       bendangle = phiDiff(4, 3);
0602       break;
0603     }
0604     case L1MuBMLUTHandler::PT34H: {
0605       bendangle = phiDiff(4, 3);
0606       break;
0607     }
0608     case L1MuBMLUTHandler::NODEF: {
0609       bendangle = 0;
0610       //                    cerr << "AssignmentUnit::getPtAddress : undefined PtAssMethod" << endl;
0611       break;
0612     }
0613     default: {
0614       bendangle = 0;
0615     }
0616   }
0617 
0618   int signo = 1;
0619   bendangle = (bendangle + 8192) % 4096;
0620   if (bendangle > 2047)
0621     bendangle -= 4096;
0622   if (bendangle < 0)
0623     signo = -1;
0624 
0625   if (bendcharge)
0626     return signo;
0627 
0628   bendangle = (bendangle + 2048) % 1024;
0629   if (bendangle > 511)
0630     bendangle -= 1024;
0631 
0632   return bendangle;
0633 }
0634 
0635 //
0636 // build difference of two phi values
0637 //
0638 int L1MuBMAssignmentUnit::phiDiff(int stat1, int stat2) const {
0639   // calculate bit shift
0640 
0641   int sh_phi = 12 - nbit_phi;
0642 
0643   // get 2 phi values and add offset (30 degrees ) for adjacent sector
0644   int sector1 = getTSphi(stat1)->sector();
0645   int sector2 = getTSphi(stat2)->sector();
0646   int phi1 = getTSphi(stat1)->phi() >> sh_phi;
0647   int phi2 = getTSphi(stat2)->phi() >> sh_phi;
0648 
0649   // convert sector difference to values in the range -6 to +5
0650 
0651   int sectordiff = (sector2 - sector1) % 12;
0652   if (sectordiff >= 6)
0653     sectordiff -= 12;
0654   if (sectordiff < -6)
0655     sectordiff += 12;
0656 
0657   //  assert( abs(sectordiff) <= 1 );
0658 
0659   int offset = (2144 >> sh_phi) * sectordiff;
0660   int bendangle = (phi2 - phi1 + offset) << sh_phi;
0661 
0662   return bendangle;
0663 }
0664 
0665 //
0666 // determine pt-assignment method
0667 //
0668 L1MuBMLUTHandler::PtAssMethod L1MuBMAssignmentUnit::getPt1Method(L1MuBMLUTHandler::PtAssMethod method) const {
0669   // quality values of track segments from stations 1, 2 and 4
0670   int qual1 = (getTSphi(1) != nullptr) ? getTSphi(1)->quality() : 0;
0671   int qual2 = (getTSphi(2) != nullptr) ? getTSphi(2)->quality() : 0;
0672   int qual4 = (getTSphi(4) != nullptr) ? getTSphi(4)->quality() : 0;
0673 
0674   L1MuBMLUTHandler::PtAssMethod pam = L1MuBMLUTHandler::NODEF;
0675 
0676   switch (method) {
0677     case L1MuBMLUTHandler::PT12H: {
0678       if (qual1 > 3)
0679         pam = L1MuBMLUTHandler::PB12H;
0680       break;
0681     }
0682     case L1MuBMLUTHandler::PT13H: {
0683       if (qual1 > 3)
0684         pam = L1MuBMLUTHandler::PB13H;
0685       break;
0686     }
0687     case L1MuBMLUTHandler::PT14H: {
0688       if (qual1 > 3)
0689         pam = L1MuBMLUTHandler::PB14H;
0690       break;
0691     }
0692     case L1MuBMLUTHandler::PT23H: {
0693       if (qual2 > 3)
0694         pam = L1MuBMLUTHandler::PB23H;
0695       break;
0696     }
0697     case L1MuBMLUTHandler::PT24H: {
0698       if (qual2 > 3)
0699         pam = L1MuBMLUTHandler::PB24H;
0700       break;
0701     }
0702     case L1MuBMLUTHandler::PT34H: {
0703       if (qual4 > 3)
0704         pam = L1MuBMLUTHandler::PB34H;
0705       break;
0706     }
0707     case L1MuBMLUTHandler::NODEF: {
0708       pam = L1MuBMLUTHandler::NODEF;
0709       break;
0710     }
0711     default: {
0712       pam = L1MuBMLUTHandler::NODEF;
0713     }
0714   }
0715 
0716   return pam;
0717 }
0718 
0719 //
0720 // determine pt-assignment method
0721 //
0722 L1MuBMLUTHandler::PtAssMethod L1MuBMAssignmentUnit::getPt2Method(L1MuBMLUTHandler::PtAssMethod method) const {
0723   // quality values of track segments from stations 2 and 4
0724   int qual2 = (getTSphi(2) != nullptr) ? getTSphi(2)->quality() : 0;
0725   //  int qual4 = ( getTSphi(4) != 0 ) ? getTSphi(4)->quality() : 0;
0726 
0727   L1MuBMLUTHandler::PtAssMethod pam = L1MuBMLUTHandler::NODEF;
0728 
0729   switch (method) {
0730     case L1MuBMLUTHandler::PT12H: {
0731       if (qual2 > 3)
0732         pam = L1MuBMLUTHandler::PB21H;
0733       break;
0734     }
0735       //    case PT14H  : { if (qual4 > 3) pam = PB34H;  break; }
0736       //    case PT24H  : { if (qual4 > 3) pam = PB34H;  break; }
0737     //case PT12HO : { if (qual2 > 3) pam = PB21HO; break; }
0738     //    case PT14HO : { if (qual4 > 3) pam = PB34HO; break; }
0739     //    case PT24HO : { if (qual4 > 3) pam = PB34HO; break; }
0740     case L1MuBMLUTHandler::NODEF: {
0741       pam = L1MuBMLUTHandler::NODEF;
0742       break;
0743     }
0744     default: {
0745       pam = L1MuBMLUTHandler::NODEF;
0746     }
0747   }
0748 
0749   return pam;
0750 }
0751 
0752 //
0753 // calculate bend angle
0754 //
0755 int L1MuBMAssignmentUnit::getPt1Address(L1MuBMLUTHandler::PtAssMethod method) const {
0756   // phib values of track segments from stations 1, 2 and 4
0757   int phib1 = (getTSphi(1) != nullptr) ? getTSphi(1)->phib() : -999;
0758   int phib2 = (getTSphi(2) != nullptr) ? getTSphi(2)->phib() : -999;
0759   int phib4 = (getTSphi(4) != nullptr) ? getTSphi(4)->phib() : -999;
0760 
0761   int bendangle = -999;
0762   switch (method) {
0763     case L1MuBMLUTHandler::PT12H: {
0764       bendangle = phib1;
0765       break;
0766     }
0767     case L1MuBMLUTHandler::PT13H: {
0768       bendangle = phib1;
0769       break;
0770     }
0771     case L1MuBMLUTHandler::PT14H: {
0772       bendangle = phib1;
0773       break;
0774     }
0775     case L1MuBMLUTHandler::PT23H: {
0776       bendangle = phib2;
0777       break;
0778     }
0779     case L1MuBMLUTHandler::PT24H: {
0780       bendangle = phib2;
0781       break;
0782     }
0783     case L1MuBMLUTHandler::PT34H: {
0784       bendangle = phib4;
0785       break;
0786     }
0787     case L1MuBMLUTHandler::NODEF: {
0788       bendangle = -999;
0789       break;
0790     }
0791     default: {
0792       bendangle = -999;
0793     }
0794   }
0795 
0796   return bendangle;
0797 }
0798 
0799 //
0800 // calculate bend angle
0801 //
0802 int L1MuBMAssignmentUnit::getPt2Address(L1MuBMLUTHandler::PtAssMethod method) const {
0803   // phib values of track segments from stations 1, 2 and 4
0804   int phib2 = (getTSphi(2) != nullptr) ? getTSphi(2)->phib() : -999;
0805   int phib4 = (getTSphi(4) != nullptr) ? getTSphi(4)->phib() : -999;
0806 
0807   int bendangle = -999;
0808   switch (method) {
0809     case L1MuBMLUTHandler::PT12H: {
0810       bendangle = phib2;
0811       break;
0812     }
0813     case L1MuBMLUTHandler::PT14H: {
0814       bendangle = phib4;
0815       break;
0816     }
0817     case L1MuBMLUTHandler::PT24H: {
0818       bendangle = phib4;
0819       break;
0820     }
0821     //case L1MuBMLUTHandler::PT12HO : { bendangle = phib2;  break; }
0822     //case L1MuBMLUTHandler::PT14HO : { bendangle = phib4;  break; }
0823     //case L1MuBMLUTHandler::PT24HO : { bendangle = phib4;  break; }
0824     case L1MuBMLUTHandler::NODEF: {
0825       bendangle = -999;
0826       break;
0827     }
0828     default: {
0829       bendangle = -999;
0830     }
0831   }
0832 
0833   return bendangle;
0834 }
0835 
0836 //
0837 // set precision for pt-assignment of phi and phib
0838 // default is 12 bits for phi and 10 bits for phib
0839 //
0840 void L1MuBMAssignmentUnit::setPrecision() {
0841   nbit_phi = L1MuBMTFConfig::getNbitsPtaPhi();
0842   nbit_phib = L1MuBMTFConfig::getNbitsPtaPhib();
0843 }
0844 
0845 // static data members
0846 
0847 unsigned short int L1MuBMAssignmentUnit::nbit_phi = 12;
0848 unsigned short int L1MuBMAssignmentUnit::nbit_phib = 10;