CMS 3D CMS Logo

List of all members | Public Member Functions | Private Member Functions | Private Attributes
Cordic Class Reference

#include <Cordic.h>

Public Member Functions

 Cordic (const uint32_t &aPhiScale, const uint32_t &aMagnitudeBits, const uint32_t &aSteps)
 
 Cordic ()
 
 Cordic (const int aSteps, bool debug)
 
template<typename T >
void cordic_subfunc (T &x, T &y, T &z) const
 
int32_t IntegerizeMagnitude (const double &aMagnitude) const
 
double NormalizeMagnitude (const uint32_t &aMagnitude) const
 
double NormalizePhi (const uint32_t &aPhi) const
 
void operator() (int32_t aX, int32_t aY, int32_t &aPhi, uint32_t &aMagnitude) const
 
l1tmetemu::EtMiss toPolar (l1tmetemu::Et_t x, l1tmetemu::Et_t y) const
 
virtual ~Cordic ()
 

Private Member Functions

uint32_t tower (const double &aRadians) const
 

Private Attributes

std::vector< l1tmetemu::atan_lut_fixed_tatanLUT
 
const int cordicSteps
 
const bool debug
 
std::vector< l1tmetemu::atan_lut_fixed_tmagNormalisationLUT
 
uint32_t mMagnitudeBits
 
uint64_t mMagnitudeRenormalization
 
uint32_t mMagnitudeScale
 
uint32_t mPhiScale
 
const double mPi
 
std::vector< uint32_t > mRotations
 
uint32_t mSteps
 

Detailed Description

Definition at line 7 of file Cordic.h.

Constructor & Destructor Documentation

◆ Cordic() [1/3]

Cordic::Cordic ( const uint32_t &  aPhiScale,
const uint32_t &  aMagnitudeBits,
const uint32_t &  aSteps 
)

Definition at line 9 of file Cordic.cc.

References mMagnitudeRenormalization, mMagnitudeScale, mRotations, mSteps, conifer::pow(), mathSSE::sqrt(), and tower().

10  : mPhiScale(aPhiScale),
11  mMagnitudeScale(1 << aMagnitudeBits),
12  mMagnitudeBits(aMagnitudeBits),
13  mSteps(aSteps),
14  mPi(3.1415926535897932384626433832795) {
15  mRotations.reserve(mSteps);
16 
17  double lValue(1.0);
18 
19  for (uint32_t lStep(0); lStep != mSteps; ++lStep) {
20  lValue /= sqrt(1.0 + pow(4.0, -double(lStep)));
21  mRotations.push_back(tower(atan(pow(2.0, -double(lStep)))));
22  }
23  mMagnitudeRenormalization = uint32_t(round(mMagnitudeScale * lValue));
24 }
uint32_t mMagnitudeBits
Definition: Cordic.h:24
constexpr int pow(int x)
Definition: conifer.h:24
uint32_t mPhiScale
Definition: Cordic.h:22
uint32_t tower(const double &aRadians) const
Definition: Cordic.cc:36
T sqrt(T t)
Definition: SSEVec.h:19
const double mPi
Definition: Cordic.h:29
uint32_t mSteps
Definition: Cordic.h:25
uint64_t mMagnitudeRenormalization
Definition: Cordic.h:26
uint32_t mMagnitudeScale
Definition: Cordic.h:23
std::vector< uint32_t > mRotations
Definition: Cordic.h:27

◆ ~Cordic()

Cordic::~Cordic ( )
virtual

Definition at line 26 of file Cordic.cc.

26 {}

◆ Cordic() [2/3]

Cordic::Cordic ( )

◆ Cordic() [3/3]

Cordic::Cordic ( const int  aSteps,
bool  debug 
)

Definition at line 9 of file Cordic.cc.

References atanLUT, debug, mps_fire::i, dqmiolumiharvest::j, magNormalisationLUT, conifer::pow(), and heppy_batch::val.

9  : cordicSteps(aSteps), debug(debug) {
10  atanLUT.reserve(aSteps);
11  magNormalisationLUT.reserve(aSteps);
12 
13  if (debug) {
14  edm::LogVerbatim("L1TkEtMissEmulator") << "=====atan LUT=====";
15  }
16 
17  for (int i = 0; i < aSteps; i++) {
18  atanLUT.push_back(l1tmetemu::atan_lut_fixed_t(atan(pow(2, -i))));
19  if (debug) {
20  edm::LogVerbatim("L1TkEtMissEmulator") << atanLUT[i] << " | ";
21  }
22  }
23  if (debug) {
24  edm::LogVerbatim("L1TkEtMissEmulator") << "\n=====Normalisation LUT=====";
25  }
26 
27  double val = 1.0;
28  for (int j = 0; j < aSteps; j++) {
29  val = val / (pow(1 + pow(4, -j), 0.5));
31  if (debug) {
32  edm::LogVerbatim("L1TkEtMissEmulator") << magNormalisationLUT[j] << " | ";
33  }
34  }
35 }
Log< level::Info, true > LogVerbatim
std::vector< l1tmetemu::atan_lut_fixed_t > magNormalisationLUT
Definition: Cordic.h:32
const int cordicSteps
Definition: Cordic.h:25
const bool debug
Definition: Cordic.h:27
ap_ufixed< kAtanLUTSize, kAtanLUTMagSize, AP_RND_CONV, AP_SAT > atan_lut_fixed_t
constexpr int pow(int x)
Definition: conifer.h:24
std::vector< l1tmetemu::atan_lut_fixed_t > atanLUT
Definition: Cordic.h:30

Member Function Documentation

◆ cordic_subfunc()

template<typename T >
void Cordic::cordic_subfunc ( T x,
T y,
T z 
) const

Definition at line 38 of file Cordic.cc.

References atanLUT, cordicSteps, debug, l1tmetemu::kStepMETwordPhi, magNormalisationLUT, x, y, and z.

Referenced by toPolar().

38  {
39  if (debug) {
40  edm::LogVerbatim("L1TkEtMissEmulator") << "\n=====Cordic Initial Conditions=====\n"
41  << "Cordic x: " << x << " Cordic y: " << y << " Cordic z: " << z << "\n"
42  << "\n=====Cordic Steps=====";
43  }
44 
45  T tx, ty, tz;
46 
47  for (int step = 0; step < cordicSteps; step++) {
48  if (y < 0) {
49  tx = x - (y >> step);
50  ty = y + (x >> step);
51  tz = z - atanLUT[step];
52  } else {
53  tx = x + (y >> step);
54  ty = y - (x >> step);
55  tz = z + atanLUT[step];
56  }
57 
58  x = tx;
59  y = ty;
60  z = tz;
61 
62  if (debug) {
63  edm::LogVerbatim("L1TkEtMissEmulator")
64  << "Cordic x: " << x << " Cordic y: " << y << " Cordic phi: " << z << "\n"
65  << " Cordic gain: " << magNormalisationLUT[step] << " kStepMETwordPhi: " << kStepMETwordPhi << "\n";
66  }
67  }
68 }
Log< level::Info, true > LogVerbatim
std::vector< l1tmetemu::atan_lut_fixed_t > magNormalisationLUT
Definition: Cordic.h:32
const int cordicSteps
Definition: Cordic.h:25
const bool debug
Definition: Cordic.h:27
std::vector< l1tmetemu::atan_lut_fixed_t > atanLUT
Definition: Cordic.h:30
const double kStepMETwordPhi
step
Definition: StallMonitor.cc:98
long double T

◆ IntegerizeMagnitude()

int32_t Cordic::IntegerizeMagnitude ( const double &  aMagnitude) const

Definition at line 34 of file Cordic.cc.

References mMagnitudeScale.

34 { return int32_t(aMagnitude * mMagnitudeScale); }
uint32_t mMagnitudeScale
Definition: Cordic.h:23

◆ NormalizeMagnitude()

double Cordic::NormalizeMagnitude ( const uint32_t &  aMagnitude) const

Definition at line 30 of file Cordic.cc.

References mMagnitudeScale.

30  {
31  return double(aMagnitude) / double(mMagnitudeScale);
32 }
uint32_t mMagnitudeScale
Definition: Cordic.h:23

◆ NormalizePhi()

double Cordic::NormalizePhi ( const uint32_t &  aPhi) const

Definition at line 28 of file Cordic.cc.

References simKBmtfDigis_cfi::aPhi, and mPhiScale.

28 { return double(aPhi) / double(mPhiScale); }
uint32_t mPhiScale
Definition: Cordic.h:22

◆ operator()()

void Cordic::operator() ( int32_t  aX,
int32_t  aY,
int32_t &  aPhi,
uint32_t &  aMagnitude 
) const

Definition at line 38 of file Cordic.cc.

References simKBmtfDigis_cfi::aPhi, mMagnitudeBits, mMagnitudeRenormalization, mPi, mRotations, mSteps, tower(), testProducerWithPsetDescEmpty_cfi::x1, and testProducerWithPsetDescEmpty_cfi::x2.

38  {
39  bool lSign(true);
40 
41  switch (((aY >= 0) ? 0x0 : 0x2) | ((aX >= 0) ? 0x0 : 0x1)) {
42  case 0:
43  aPhi = tower(mPi);
44  break;
45  case 1:
46  aPhi = tower(2 * mPi);
47  lSign = false;
48  aX = -aX;
49  break;
50  case 2:
51  aPhi = tower(mPi);
52  lSign = false;
53  aY = -aY;
54  break;
55  case 3:
56  aPhi = 0;
57  aX = -aX;
58  aY = -aY;
59  break;
60  default:
61  throw 0;
62  }
63 
64  for (uint32_t lStep(0); lStep != mSteps; ++lStep) {
65  if ((aY < 0) == lSign) {
66  aPhi -= mRotations[lStep];
67  } else {
68  aPhi += mRotations[lStep];
69  }
70 
71  int32_t lX(aX), lY(aY);
72  if (lY < 0) {
73  aX = lX - (lY >> lStep);
74  aY = lY + (lX >> lStep);
75  } else {
76  aX = lX + (lY >> lStep);
77  aY = lY - (lX >> lStep);
78  }
79  }
80 
81  aMagnitude = (aX * mMagnitudeRenormalization) >> mMagnitudeBits;
82 }
uint32_t mMagnitudeBits
Definition: Cordic.h:24
uint32_t tower(const double &aRadians) const
Definition: Cordic.cc:36
const double mPi
Definition: Cordic.h:29
uint32_t mSteps
Definition: Cordic.h:25
uint64_t mMagnitudeRenormalization
Definition: Cordic.h:26
std::vector< uint32_t > mRotations
Definition: Cordic.h:27

◆ toPolar()

EtMiss Cordic::toPolar ( l1tmetemu::Et_t  x,
l1tmetemu::Et_t  y 
) const

Definition at line 70 of file Cordic.cc.

References cordic_subfunc(), cordicSteps, debug, l1tmetemu::EtMiss::Et, mps_fire::i, l1tmetemu::kBinsInPi, l1tmetemu::kStepMETwordPhi, M_PI, magNormalisationLUT, l1tmetemu::EtMiss::Phi, pi, pi2, ApeEstimator_cff::width, x, and y.

70  {
71  EtMiss ret_etmiss;
72 
73  if (debug) {
74  edm::LogVerbatim("L1TkEtMissEmulator") << "\n=====toPolar input=====\n"
75  << "x: " << x << " y: " << y;
76  }
77 
78  // Some needed constants
79  const ap_fixed<l1tmetemu::Et_t::width + 1, 3> pi = M_PI; // pi
80  const ap_fixed<l1tmetemu::Et_t::width + 2, 3> pi2 = M_PI / 2.; // pi/2
81  const l1tmetemu::METWordphi_t pistep = M_PI / l1tmetemu::kStepMETwordPhi; // (pi) / l1tmetemu::kStepMETwordPhi
82  const l1tmetemu::METWordphi_t pi2step = pistep / 2.; // (pi/2) / l1tmetemu::kStepMETwordPhi
83 
84  // Find the sign of the inputs
85  ap_uint<2> signx = (x > 0) ? 2 : (x == 0) ? 1 : 0;
86  ap_uint<2> signy = (y > 0) ? 2 : (y == 0) ? 1 : 0;
87 
88  // Corner cases
89  if (signy == 1 && signx == 2) { // y == 0 and x > 0
90  ret_etmiss.Et = x;
91  ret_etmiss.Phi = 0;
92  return ret_etmiss;
93  } else if (signy == 1 && signx == 0) { // y == 0 and x < 0
94  ret_etmiss.Et = -x;
95  ret_etmiss.Phi = pistep;
96  return ret_etmiss;
97  } else if (signy == 2 && signx == 1) { // y > 0 and x == 0
98  ret_etmiss.Et = y;
99  ret_etmiss.Phi = pi2step;
100  return ret_etmiss;
101  } else if (signy == 0 && signx == 1) { // y < 0 and x == 0
102  ret_etmiss.Et = -y;
103  ret_etmiss.Phi = -pi2step;
104  return ret_etmiss;
105  }
106 
107  // Take absolute values to operate on the range (0, pi/2)
108  ap_fixed<Et_t::width + 1, Et_t::iwidth + 1, Et_t::qmode, Et_t::omode> absx, absy;
109  if (signy == 0) {
110  absy = -y;
111  } else {
112  absy = y;
113  }
114 
115  if (signx == 0) {
116  absx = -x;
117  } else {
118  absx = x;
119  }
120 
121  if (debug) {
122  edm::LogVerbatim("L1TkEtMissEmulator") << "\n=====Abs input=====\n"
123  << "abs(x): " << absx.to_double() << " abs(y): " << absy.to_double();
124  }
125 
126  // Normalization (operate on a unit circle)
127  ap_fixed<Et_t::width + 1, 2, Et_t::qmode, Et_t::omode> absx_sft, absy_sft;
128  for (int i = 0; i < Et_t::width + 1; i++) {
129  absx_sft[i] = absx[i];
130  absy_sft[i] = absy[i];
131  }
132 
133  if (debug) {
134  edm::LogVerbatim("L1TkEtMissEmulator")
135  << "\n=====Normalized input=====\n"
136  << "norm(abs(x)): " << absx_sft.to_double() << " norm(abs(y)): " << absy_sft.to_double();
137  }
138 
139  // Setup the CORDIC inputs/outputs
140  ap_fixed<Et_t::width + 7, 3, Et_t::qmode, Et_t::omode> cx, cy, cphi;
141  if (absy > absx) {
142  cx = absy_sft;
143  cy = absx_sft;
144  cphi = 0;
145  } else {
146  cx = absx_sft;
147  cy = absy_sft;
148  cphi = 0;
149  }
150 
151  if (debug) {
152  edm::LogVerbatim("L1TkEtMissEmulator")
153  << "\n=====CORDIC function arguments=====\n"
154  << "x: " << cx.to_double() << " y: " << cy.to_double() << " phi: " << cphi.to_double();
155  }
156 
157  // Perform the CORDIC (vectoring) function
158  cordic_subfunc(cx, cy, cphi);
159 
160  // Reorient the outputs to their appropriate quadrant
161  if (absy > absx) {
162  cphi = pi2 - cphi;
163  }
164 
165  ap_fixed<Et_t::width, 3, Et_t::qmode, Et_t::omode> ophi;
166  if (signx == 0 && signy == 2) { // x < 0 and y > 0
167  ophi = pi - cphi;
168  } else if (signx == 0 && signy == 0) { // x < 0 and y < 0
169  ophi = cphi - pi;
170  } else if (signx == 2 && signy == 0) { // x > 0 and y < 0
171  ophi = -cphi;
172  } else {
173  ophi = cphi;
174  }
175 
176  // Re-scale the outputs
177  Et_t magnitude = ((ap_fixed<Et_t::width + Et_t::iwidth + 3 + 1, Et_t::iwidth, Et_t::qmode, Et_t::omode>)cx)
178  << (Et_t::iwidth + 1 - 2);
179  ret_etmiss.Et = l1tmetemu::Et_t(magnitude * magNormalisationLUT[cordicSteps - 1]);
180  ret_etmiss.Phi = ophi * pi_bins_fixed_t(kBinsInPi);
181 
182  if (debug) {
183  edm::LogVerbatim("L1TkEtMissEmulator")
184  << "\n=====toPolar output=====\n"
185  << std::setprecision(8) << "magnitude: " << magnitude.to_double() << " phi: " << ophi.to_double()
186  << " kBinsInPi: " << pi_bins_fixed_t(kBinsInPi).to_double() << "\n"
187  << "Et: " << ret_etmiss.Et.to_double() << " phi (int): " << ret_etmiss.Phi.to_int() << "\n";
188  }
189 
190  return ret_etmiss;
191 }
Log< level::Info, true > LogVerbatim
ap_int< kMETPhiSize > METWordphi_t
ap_fixed< kMETSize+kEtExtra, kMETMagSize+kEtExtra, AP_RND_CONV, AP_SAT > Et_t
std::vector< l1tmetemu::atan_lut_fixed_t > magNormalisationLUT
Definition: Cordic.h:32
const int cordicSteps
Definition: Cordic.h:25
void cordic_subfunc(T &x, T &y, T &z) const
Definition: Cordic.cc:38
const bool debug
Definition: Cordic.h:27
const double pi2
Definition: Thrust.cc:4
const Double_t pi
const double kStepMETwordPhi
#define M_PI
const double kBinsInPi
ap_ufixed< kMETPhiSize+kEtExtra+7, kMETPhiSize - 2, AP_RND_CONV, AP_SAT > pi_bins_fixed_t

◆ tower()

uint32_t Cordic::tower ( const double &  aRadians) const
private

Definition at line 36 of file Cordic.cc.

References mPhiScale, and mPi.

Referenced by Cordic(), and operator()().

36 { return uint32_t(round(mPhiScale * 0.5 * aRadians / mPi)); }
uint32_t mPhiScale
Definition: Cordic.h:22
const double mPi
Definition: Cordic.h:29

Member Data Documentation

◆ atanLUT

std::vector<l1tmetemu::atan_lut_fixed_t> Cordic::atanLUT
private

Definition at line 30 of file Cordic.h.

Referenced by Cordic(), and cordic_subfunc().

◆ cordicSteps

const int Cordic::cordicSteps
private

Definition at line 25 of file Cordic.h.

Referenced by cordic_subfunc(), and toPolar().

◆ debug

const bool Cordic::debug
private

◆ magNormalisationLUT

std::vector<l1tmetemu::atan_lut_fixed_t> Cordic::magNormalisationLUT
private

Definition at line 32 of file Cordic.h.

Referenced by Cordic(), cordic_subfunc(), and toPolar().

◆ mMagnitudeBits

uint32_t Cordic::mMagnitudeBits
private

Definition at line 24 of file Cordic.h.

Referenced by operator()().

◆ mMagnitudeRenormalization

uint64_t Cordic::mMagnitudeRenormalization
private

Definition at line 26 of file Cordic.h.

Referenced by Cordic(), and operator()().

◆ mMagnitudeScale

uint32_t Cordic::mMagnitudeScale
private

Definition at line 23 of file Cordic.h.

Referenced by Cordic(), IntegerizeMagnitude(), and NormalizeMagnitude().

◆ mPhiScale

uint32_t Cordic::mPhiScale
private

Definition at line 22 of file Cordic.h.

Referenced by NormalizePhi(), and tower().

◆ mPi

const double Cordic::mPi
private

Definition at line 29 of file Cordic.h.

Referenced by operator()(), and tower().

◆ mRotations

std::vector<uint32_t> Cordic::mRotations
private

Definition at line 27 of file Cordic.h.

Referenced by Cordic(), and operator()().

◆ mSteps

uint32_t Cordic::mSteps
private

Definition at line 25 of file Cordic.h.

Referenced by Cordic(), and operator()().