Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-03-26 02:43:42

0001 #include "L1Trigger/L1TTrackMatch/interface/Cordic.h"
0002 
0003 #include <cmath>
0004 #include <memory>
0005 
0006 using namespace l1tmetemu;
0007 
0008 Cordic::Cordic(int aPhiScale, int aMagnitudeBits, const int aSteps, bool debug)
0009     : mPhiScale(aPhiScale),
0010       mMagnitudeScale(1 << aMagnitudeBits),
0011       mMagnitudeBits(aMagnitudeBits),
0012       cordicSteps(aSteps),
0013       debug(debug) {
0014   atanLUT.reserve(aSteps);
0015   magNormalisationLUT.reserve(aSteps);
0016 
0017   if (debug) {
0018     edm::LogVerbatim("L1TkEtMissEmulator") << "=====atan LUT=====";
0019   }
0020 
0021   for (int i = 0; i < aSteps; i++) {
0022     atanLUT.push_back(METphi_t(round(mPhiScale * atan(pow(2, -i)) / (2 * M_PI))));
0023     if (debug) {
0024       edm::LogVerbatim("L1TkEtMissEmulator") << atanLUT[i] << " | ";
0025     }
0026   }
0027   if (debug) {
0028     edm::LogVerbatim("L1TkEtMissEmulator") << "\n=====Normalisation LUT=====";
0029   }
0030 
0031   float val = 1.0;
0032   for (int j = 0; j < aSteps; j++) {
0033     val = val / (pow(1 + pow(4, -j), 0.5));
0034     magNormalisationLUT.push_back(Et_t(round(mMagnitudeScale * val)));
0035     if (debug) {
0036       edm::LogVerbatim("L1TkEtMissEmulator") << magNormalisationLUT[j] << " | ";
0037     }
0038   }
0039 }
0040 
0041 EtMiss Cordic::toPolar(Et_t x, Et_t y) const {
0042   Et_t new_x = 0;
0043   Et_t new_y = 0;
0044 
0045   METphi_t phi = 0;
0046   METphi_t new_phi = 0;
0047   bool sign = false;
0048 
0049   EtMiss ret_etmiss;
0050 
0051   if (debug) {
0052     edm::LogVerbatim("L1TkEtMissEmulator") << "\n=====Cordic Steps=====";
0053   }
0054 
0055   if (x >= 0 && y >= 0) {
0056     phi = 0;
0057     sign = true;
0058     //x = x;
0059     //y = y;
0060   } else if (x < 0 && y >= 0) {
0061     phi = mPhiScale >> 1;
0062     sign = false;
0063     x = -x;
0064     //y = y;
0065   } else if (x < 0 && y < 0) {
0066     phi = mPhiScale >> 1;
0067     sign = true;
0068     x = -x;
0069     y = -y;
0070   } else {
0071     phi = mPhiScale;
0072     sign = false;
0073     //x = x;
0074     y = -y;
0075   }
0076 
0077   for (int step = 0; step < cordicSteps; step++) {
0078     if (y < 0) {
0079       new_x = x - (y >> step);
0080       new_y = y + (x >> step);
0081     } else {
0082       new_x = x + (y >> step);
0083       new_y = y - (x >> step);
0084     }
0085 
0086     if ((y < 0) == sign) {
0087       new_phi = phi - atanLUT[step];
0088     } else {
0089       new_phi = phi + atanLUT[step];
0090     }
0091 
0092     x = new_x;
0093     y = new_y;
0094     phi = new_phi;
0095 
0096     if (debug) {
0097       edm::LogVerbatim("L1TkEtMissEmulator")
0098           << " Cordic x: " << x << " Cordic y: " << y << " Cordic phi: " << phi << "\n";
0099     }
0100   }
0101 
0102   // Cordic performs calculation in internal Et granularity, convert to final
0103   // granularity for Et word
0104 
0105   // emulate fw rounding with float division then floor
0106   float tempMET = (float)(x * magNormalisationLUT[cordicSteps - 1] * kMaxTrackPt) / ((float)kMaxMET);
0107   ret_etmiss.Et = (int)floor(tempMET) >> (mMagnitudeBits + TTTrack_TrackWord::TrackBitWidths::kRinvSize - kMETSize);
0108   ret_etmiss.Phi = phi;
0109   return ret_etmiss;
0110 }