00001 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctMet.h"
00002
00003 #include <math.h>
00004
00005 L1GctMet::L1GctMet(const unsigned ex, const unsigned ey, const L1GctMet::metAlgoType algo) :
00006 m_exComponent(ex),
00007 m_eyComponent(ey),
00008 m_algoType(algo),
00009 m_bitShift(0)
00010 { }
00011
00012 L1GctMet::L1GctMet(const etComponentType& ex, const etComponentType& ey, const metAlgoType algo) :
00013 m_exComponent(ex),
00014 m_eyComponent(ey),
00015 m_algoType(algo),
00016 m_bitShift(0)
00017 { }
00018
00019 L1GctMet::~L1GctMet() {}
00020
00021
00022 L1GctMet::etmiss_vec
00023 L1GctMet::metVector () const
00024 {
00025 etmiss_vec result;
00026 etmiss_internal algoResult;
00027 switch (m_algoType)
00028 {
00029 case cordicTranslate:
00030 algoResult = cordicTranslateAlgo (m_exComponent.value(), m_eyComponent.value());
00031 break;
00032
00033 case oldGct:
00034 algoResult = oldGctAlgo (m_exComponent.value(), m_eyComponent.value());
00035 break;
00036
00037 case floatingPoint:
00038 algoResult = floatingPointAlgo (m_exComponent.value(), m_eyComponent.value());
00039 break;
00040
00041 default:
00042 break;
00043 }
00044
00045
00046
00047
00048
00049
00050 result.mag.setValue(algoResult.mag>>(1+m_bitShift));
00051 result.phi.setValue(algoResult.phi);
00052
00053 result.mag.setOverFlow( result.mag.overFlow() || m_exComponent.overFlow() || m_eyComponent.overFlow() );
00054
00055 return result;
00056
00057 }
00058
00059 void L1GctMet::setExComponent(const unsigned ex) {
00060 etComponentType temp(ex);
00061 setExComponent(temp);
00062 }
00063
00064 void L1GctMet::setEyComponent(const unsigned ey) {
00065 etComponentType temp(ey);
00066 setEyComponent(temp);
00067 }
00068
00069
00070
00071 L1GctMet::etmiss_internal
00072 L1GctMet::cordicTranslateAlgo (const int ex, const int ey) const
00073 {
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 etmiss_internal result;
00099
00100 static const int n_iterations = 6;
00101
00102
00103 const int cordic_angles[n_iterations] = { 0x120, 0x0AA, 0x05A, 0x02E, 0x017, 0x00B };
00104 const int cordic_starting_angle_090 = 0x240;
00105 const int cordic_starting_angle_270 = 0x6C0;
00106 const int cordic_angle_360 = 0x900;
00107
00108 const int cordic_scale_factor = 0x26E;
00109
00110 int x, y;
00111 int dx,dy;
00112 int z;
00113
00114 if (ey>=0) {
00115 x = ey;
00116 y = -ex;
00117 z = cordic_starting_angle_090;
00118 } else {
00119 x = -ey;
00120 y = ex;
00121 z = cordic_starting_angle_270;
00122 }
00123
00124 for (int i=0; i<n_iterations; i++) {
00125 dx = cordicShiftAndRoundBits (y,i);
00126 dy = cordicShiftAndRoundBits (x,i);
00127 if (y>=0) {
00128 x = x + dx;
00129 y = y - dy;
00130 z = z + cordic_angles[i];
00131 } else {
00132 x = x - dx;
00133 y = y + dy;
00134 z = z - cordic_angles[i];
00135 }
00136 }
00137
00138 int scaled_magnitude = x * cordic_scale_factor;
00139 int adjusted_angle = ( (z < 0) ? (z + cordic_angle_360) : z ) % cordic_angle_360;
00140 result.mag = scaled_magnitude >> 10;
00141 result.phi = adjusted_angle >> 5;
00142 return result;
00143 }
00144
00145 int L1GctMet::cordicShiftAndRoundBits (const int e, const unsigned nBits) const
00146 {
00147 int r;
00148 if (nBits==0) {
00149 r = e;
00150 } else {
00151 r = (((e>>(nBits-1)) + 1)>>1);
00152 }
00153 return r;
00154 }
00155
00156
00157 L1GctMet::etmiss_internal
00158 L1GctMet::oldGctAlgo (const int ex, const int ey) const
00159 {
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 etmiss_internal result;
00175
00176 unsigned eneCoarse, phiCoarse;
00177 unsigned eneCorect, phiCorect;
00178
00179 const unsigned root2fact = 181;
00180 const unsigned corrFact[11] = {24, 39, 51, 60, 69, 77, 83, 89, 95, 101, 106};
00181 const unsigned corrDphi[11] = { 0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4};
00182
00183 std::vector<bool> s(3);
00184 unsigned Mx, My, Mw;
00185
00186 unsigned Dx, Dy;
00187 unsigned eFact;
00188
00189 unsigned b,phibin;
00190 bool midphi=false;
00191
00192
00193
00194 My = static_cast<unsigned>(abs(ey));
00195 Mx = static_cast<unsigned>(abs(ex));
00196 Mw = (((Mx+My)*root2fact)+0x80)>>8;
00197
00198 s.at(0) = (ey<0);
00199 s.at(1) = (ex<0);
00200 s.at(2) = (My>Mx);
00201
00202 phibin = 0; b = 0;
00203 for (int i=0; i<3; i++) {
00204 if (s.at(i)) { b=1-b;} phibin = 2*phibin + b;
00205 }
00206
00207 eneCoarse = std::max(std::max(Mx, My), Mw);
00208 phiCoarse = phibin*9;
00209
00210
00211
00212
00213
00214 for (eFact=0; eFact<10; eFact++) {
00215 Dx = (Mx*corrFact[eFact])>>8;
00216 Dy = (My*corrFact[eFact])>>8;
00217 if ((Dx>=My) || (Dy>=Mx)) {midphi=false; break;}
00218 if ((Mx+Dx)>=(My-Dy) && (My+Dy)>=(Mx-Dx)) {midphi=true; break;}
00219 }
00220 eneCorect = (eneCoarse*(128+eFact))>>7;
00221 if (midphi ^ (b==1)) {
00222 phiCorect = phiCoarse + 8 - corrDphi[eFact];
00223 } else {
00224 phiCorect = phiCoarse + corrDphi[eFact];
00225 }
00226
00227
00228
00229 result.mag = eneCorect;
00230 result.phi = phiCorect;
00231
00232 return result;
00233 }
00234
00235 L1GctMet::etmiss_internal
00236 L1GctMet::floatingPointAlgo (const int ex, const int ey) const
00237 {
00238
00239 etmiss_internal result;
00240
00241 double fx = static_cast<double>(ex);
00242 double fy = static_cast<double>(ey);
00243 double fmag = sqrt(fx*fx + fy*fy);
00244 double fphi = 36.*atan2(fy, fx)/M_PI;
00245
00246 result.mag = static_cast<unsigned>(fmag);
00247 if (fphi>=0) {
00248 result.phi = static_cast<unsigned>(fphi);
00249 } else {
00250 result.phi = static_cast<unsigned>(fphi+72.);
00251 }
00252
00253 return result;
00254
00255 }
00256