Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:20:50

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