Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:19:42

0001 //-------------------------------------------------
0002 //
0003 //   Class: L1MuDTEUX
0004 //
0005 //   Description: Extrapolator
0006 //
0007 //
0008 //
0009 //   Author :
0010 //   N. Neumeister            CERN EP
0011 //
0012 //--------------------------------------------------
0013 
0014 //-----------------------
0015 // This Class's Header --
0016 //-----------------------
0017 
0018 #include "L1Trigger/DTTrackFinder/src/L1MuDTEUX.h"
0019 
0020 //---------------
0021 // C++ Headers --
0022 //---------------
0023 
0024 #include <iostream>
0025 
0026 //-------------------------------
0027 // Collaborating Class Headers --
0028 //-------------------------------
0029 
0030 #include "L1Trigger/DTTrackFinder/interface/L1MuDTTFConfig.h"
0031 #include "L1Trigger/DTTrackFinder/interface/L1MuDTTrackFinder.h"
0032 #include "CondFormats/L1TObjects/interface/L1MuDTExtParam.h"
0033 #include "L1Trigger/DTTrackFinder/src/L1MuDTSectorProcessor.h"
0034 #include "L1Trigger/DTTrackFinder/src/L1MuDTSEU.h"
0035 #include "L1Trigger/DTTrackFinder/interface/L1MuDTTrackSegPhi.h"
0036 #include "CondFormats/L1TObjects/interface/L1MuDTExtLut.h"
0037 #include "CondFormats/L1TObjects/interface/L1MuDTTFParameters.h"
0038 #include "L1Trigger/L1TCommon/interface/BitShift.h"
0039 
0040 using namespace std;
0041 
0042 // --------------------------------
0043 //       class L1MuDTEUX
0044 //---------------------------------
0045 
0046 //----------------
0047 // Constructors --
0048 //----------------
0049 
0050 L1MuDTEUX::L1MuDTEUX(const L1MuDTSectorProcessor& sp, const L1MuDTSEU& seu, int id)
0051     : m_sp(sp),
0052       m_seu(seu),
0053       m_id(id),
0054       m_result(false),
0055       m_quality(0),
0056       m_address(15),
0057       m_start(nullptr),
0058       m_target(nullptr),
0059       theExtFilter(sp.tf().config()->getExtTSFilter()),
0060       nbit_phi(sp.tf().config()->getNbitsExtPhi()),
0061       nbit_phib(sp.tf().config()->getNbitsExtPhib()) {}
0062 
0063 //--------------
0064 // Destructor --
0065 //--------------
0066 
0067 L1MuDTEUX::~L1MuDTEUX() {}
0068 
0069 //--------------
0070 // Operations --
0071 //--------------
0072 
0073 //
0074 // Equal operator
0075 //
0076 bool L1MuDTEUX::operator==(const L1MuDTEUX& eux) const {
0077   if (m_id != eux.id())
0078     return false;
0079   if (m_result != eux.result())
0080     return false;
0081   if (m_quality != eux.quality())
0082     return false;
0083   if (m_address != eux.address())
0084     return false;
0085   return true;
0086 }
0087 
0088 //
0089 // run EUX
0090 //
0091 void L1MuDTEUX::run(const L1MuDTExtLut& extLUTs, const L1MuDTTFParameters& pars) {
0092   const bool debug4 = m_sp.tf().config()->Debug(4);
0093   if (debug4)
0094     cout << "Run EUX " << m_id << endl;
0095   if (debug4)
0096     cout << "start :  " << *m_start << endl;
0097   if (debug4)
0098     cout << "target : " << *m_target << endl;
0099 
0100   if (m_start == nullptr || m_target == nullptr) {
0101     if (debug4)
0102       cout << "Error: EUX has no data loaded" << endl;
0103     return;
0104   }
0105 
0106   // start sector
0107   int sector_st = m_start->sector();
0108 
0109   // target sector
0110   int sector_ta = m_target->sector();
0111 
0112   // get index of look-up table
0113   int lut_idx = m_seu.ext();
0114   if (abs(m_target->wheel()) == 3) {
0115     switch (m_seu.ext()) {
0116       case EX13: {
0117         lut_idx = EX15;
0118         break;
0119       }
0120       case EX23: {
0121         lut_idx = EX25;
0122         break;
0123       }
0124       default: {
0125         lut_idx = m_seu.ext();
0126         break;
0127       }
0128     }
0129   }
0130 
0131   if (m_sp.tf().config()->Debug(5))
0132     cout << "EUX : using look-up table : " << static_cast<Extrapolation>(lut_idx) << endl;
0133 
0134   // Extrapolation TS quality filter
0135   int qcut = 0;
0136   if (m_seu.ext() == EX12)
0137     qcut = pars.get_soc_qcut_st1(m_sp.id().wheel(), m_sp.id().sector());
0138   if (m_seu.ext() == EX13)
0139     qcut = pars.get_soc_qcut_st1(m_sp.id().wheel(), m_sp.id().sector());
0140   if (m_seu.ext() == EX14)
0141     qcut = pars.get_soc_qcut_st1(m_sp.id().wheel(), m_sp.id().sector());
0142   if (m_seu.ext() == EX21)
0143     qcut = pars.get_soc_qcut_st2(m_sp.id().wheel(), m_sp.id().sector());
0144   if (m_seu.ext() == EX23)
0145     qcut = pars.get_soc_qcut_st2(m_sp.id().wheel(), m_sp.id().sector());
0146   if (m_seu.ext() == EX24)
0147     qcut = pars.get_soc_qcut_st2(m_sp.id().wheel(), m_sp.id().sector());
0148   if (m_seu.ext() == EX34)
0149     qcut = pars.get_soc_qcut_st4(m_sp.id().wheel(), m_sp.id().sector());
0150 
0151   if (m_start->quality() < qcut)
0152     return;
0153 
0154   // calculate bit shift
0155   int sh_phi = 12 - nbit_phi;
0156   int sh_phib = 10 - nbit_phib;
0157 
0158   int phi_target = m_target->phi() >> sh_phi;
0159   int phi_start = m_start->phi() >> sh_phi;
0160   int phib_start = l1t::bitShift((m_start->phib() >> sh_phib), sh_phib);
0161   if (phib_start < 0)
0162     phib_start += (1 << sh_phib) - 1;
0163 
0164   // compute difference in phi
0165   int diff = phi_target - phi_start;
0166 
0167   // get low and high values from look-up table
0168   // and add offset (30 degrees ) for extrapolation to adjacent sector
0169   int offset = -2144 >> sh_phi;
0170   offset *= sec_mod(sector_ta - sector_st);
0171   int low = extLUTs.getLow(lut_idx, phib_start);
0172   int high = extLUTs.getHigh(lut_idx, phib_start);
0173   if (low < 0)
0174     low += (1 << sh_phi) - 1;
0175   if (high < 0)
0176     high += (1 << sh_phi) - 1;
0177   low = (low >> sh_phi) + offset;
0178   high = (high >> sh_phi) + offset;
0179 
0180   int phi_offset = phi_target - offset;
0181   if ((lut_idx == EX34) || (lut_idx == EX21))
0182     phi_offset = phi_start + offset;
0183   if (phi_offset >= (1 << (nbit_phi - 1)) - 1)
0184     return;
0185   if (phi_offset < -(1 << (nbit_phi - 1)) + 1)
0186     return;
0187 
0188   // is phi-difference within the extrapolation window?
0189   bool openlut = pars.get_soc_openlut_extr(m_sp.id().wheel(), m_sp.id().sector());
0190   if ((diff >= low && diff <= high) || m_sp.tf().config()->getopenLUTs() || openlut) {
0191     m_result = true;
0192     int qual_st = m_start->quality();
0193     int qual_ta = m_target->quality();
0194     if (m_seu.ext() == EX34 || m_seu.ext() == EX21) {
0195       m_quality = (qual_st == 7) ? 0 : qual_st + 1;
0196     } else {
0197       m_quality = (qual_ta == 7) ? 0 : qual_ta + 1;
0198     }
0199     m_address = m_id;
0200   }
0201 
0202   if (m_sp.tf().config()->Debug(5))
0203     cout << "diff : " << low << " " << diff << " " << high << " : " << m_result << " " << endl;
0204 }
0205 
0206 //
0207 // load data into EUX
0208 //
0209 void L1MuDTEUX::load(const L1MuDTTrackSegPhi* start_ts, const L1MuDTTrackSegPhi* target_ts) {
0210   m_start = start_ts;
0211   m_target = target_ts;
0212 
0213   // in case of EX34 and EX21 exchange start and target
0214   if ((m_seu.ext() == EX34) || (m_seu.ext() == EX21)) {
0215     m_start = target_ts;
0216     m_target = start_ts;
0217   }
0218 }
0219 
0220 //
0221 // reset this EUX
0222 //
0223 
0224 void L1MuDTEUX::reset() {
0225   m_result = false;
0226   m_quality = 0;
0227   m_address = 15;
0228 
0229   m_start = nullptr;
0230   m_target = nullptr;
0231 }
0232 
0233 //
0234 // return pointer to start and target track segment
0235 //
0236 pair<const L1MuDTTrackSegPhi*, const L1MuDTTrackSegPhi*> L1MuDTEUX::ts() const {
0237   return pair<const L1MuDTTrackSegPhi*, const L1MuDTTrackSegPhi*>(m_start, m_target);
0238 }
0239 
0240 //
0241 // symmetric modulo function for sectors
0242 // output values in the range -6 to +5
0243 //
0244 int L1MuDTEUX::sec_mod(int sector) const {
0245   int new_sector = sector % 12;
0246   if (new_sector >= 6)
0247     new_sector = new_sector - 12;
0248   if (new_sector < -6)
0249     new_sector = new_sector + 12;
0250 
0251   return new_sector;
0252 }