#include <L1Trigger/GlobalCaloTrigger/interface/L1GctMet.h>
Definition at line 17 of file L1GctMet.h.
Definition at line 25 of file L1GctMet.h.
typedef L1GctUnsignedInt< L1GctEtMiss::kEtMissPhiNBits > L1GctMet::etMissPhiType |
Definition at line 24 of file L1GctMet.h.
typedef L1GctUnsignedInt< L1GctEtMiss::kEtMissNBits > L1GctMet::etMissType |
Definition at line 23 of file L1GctMet.h.
L1GctMet::L1GctMet | ( | const unsigned | ex = 0 , |
|
const unsigned | ey = 0 , |
|||
const metAlgoType | algo = cordicTranslate | |||
) |
Definition at line 5 of file L1GctMet.cc.
00005 : 00006 m_exComponent(ex), 00007 m_eyComponent(ey), 00008 m_algoType(algo), 00009 m_bitShift(0) 00010 { }
L1GctMet::L1GctMet | ( | const etComponentType & | ex, | |
const etComponentType & | ey, | |||
const metAlgoType | algo = cordicTranslate | |||
) |
Definition at line 12 of file L1GctMet.cc.
00012 : 00013 m_exComponent(ex), 00014 m_eyComponent(ey), 00015 m_algoType(algo), 00016 m_bitShift(0) 00017 { }
L1GctMet::~L1GctMet | ( | ) |
Definition at line 145 of file L1GctMet.cc.
References r.
Referenced by cordicTranslateAlgo().
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 }
L1GctMet::etmiss_internal L1GctMet::cordicTranslateAlgo | ( | const int | ex, | |
const int | ey | |||
) | const [private] |
Definition at line 72 of file L1GctMet.cc.
References cordicShiftAndRoundBits(), i, L1GctMet::etmiss_internal::mag, L1GctMet::etmiss_internal::phi, HLT_VtxMuL3::result, x, y, and z.
Referenced by metVector().
00073 { 00074 //--------------------------------------------------------------------------------- 00075 // 00076 // This is an implementation of the CORDIC algorithm (COordinate Rotation for DIgital Computers) 00077 // 00078 // Starting from an initial two-component vector ex, ey, we perform successively smaller rotations 00079 // to transform the y component to zero. At the end of the procedure, the x component is the magnitude 00080 // of the original vector, scaled by a known constant factor. The azimuth angle phi is the sum of the 00081 // rotations applied. 00082 // 00083 // The algorithm can be used in a number of different variants for calculation of trigonometric 00084 // and hyperbolic functions as well as exponentials, logarithms and square roots. This variant 00085 // is called the "vector translation" mode in the Xilinx documentation. 00086 // 00087 // Original references: 00088 // Volder, J., "The CORDIC Trigonometric Computing Technique" IRE Trans. Electronic Computing, Vol. 00089 // EC-8, Sept. 1959, pp330-334 00090 // Walther, J.S., "A Unified Algorithm for Elementary Functions," Spring Joint computer conf., 1971, 00091 // proc., pp379-385 00092 // 00093 // Other information sources: https://www.xilinx.com/support/documentation/ip_documentation/cordic.pdf; 00094 // https://www.fpga-guru.com/files/crdcsrvy.pdf; and https://en.wikipedia.org/wiki/CORDIC 00095 // 00096 //--------------------------------------------------------------------------------- 00097 00098 etmiss_internal result; 00099 00100 static const int n_iterations = 6; 00101 // The angle units here are 1/32 of a 5 degree bin. 00102 // So a 90 degree rotation is 32*18=576 or 240 hex. 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; // decimal 622 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 }
L1GctMet::etmiss_internal L1GctMet::floatingPointAlgo | ( | const int | ex, | |
const int | ey | |||
) | const [private] |
Definition at line 236 of file L1GctMet.cc.
References L1GctMet::etmiss_internal::mag, L1GctMet::etmiss_internal::phi, HLT_VtxMuL3::result, and funct::sqrt().
Referenced by metVector().
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 }
metAlgoType L1GctMet::getAlgoType | ( | ) | const [inline] |
unsigned L1GctMet::getBitShift | ( | ) | const [inline] |
etComponentType L1GctMet::getExComponent | ( | ) | const [inline] |
etComponentType L1GctMet::getEyComponent | ( | ) | const [inline] |
L1GctMet::etmiss_vec L1GctMet::metVector | ( | ) | const |
Definition at line 23 of file L1GctMet.cc.
References cordicTranslate, cordicTranslateAlgo(), floatingPoint, floatingPointAlgo(), m_algoType, m_bitShift, m_exComponent, m_eyComponent, L1GctMet::etmiss_internal::mag, L1GctMet::etmiss_vec::mag, oldGct, oldGctAlgo(), L1GctUnsignedInt< nBits >::overFlow(), L1GctTwosComplement< nBits >::overFlow(), L1GctMet::etmiss_vec::phi, L1GctMet::etmiss_internal::phi, HLT_VtxMuL3::result, L1GctUnsignedInt< nBits >::setOverFlow(), L1GctUnsignedInt< nBits >::setValue(), and L1GctTwosComplement< nBits >::value().
Referenced by L1GctGlobalEnergyAlgos::process().
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 // Discard the least significant bits of the result 00046 // NB One extra LSB is added during the conversion of strip sums 00047 // to x and y components (in the JetLeafCard). 00048 // The parameter m_bitShift allows us to discard additional LSB 00049 // in order to change the output scale. 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 }
L1GctMet::etmiss_internal L1GctMet::oldGctAlgo | ( | const int | ex, | |
const int | ey | |||
) | const [private] |
Definition at line 158 of file L1GctMet.cc.
References funct::abs(), b, i, L1GctMet::etmiss_internal::mag, max, L1GctMet::etmiss_internal::phi, HLT_VtxMuL3::result, and s.
Referenced by metVector().
00159 { 00160 //--------------------------------------------------------------------------------- 00161 // 00162 // Calculates magnitude and direction of missing Et, given measured Ex and Ey. 00163 // 00164 // The algorithm used is suitable for implementation in hardware, using integer 00165 // multiplication, addition and comparison and bit shifting operations. 00166 // 00167 // Proceed in two stages. The first stage gives a result that lies between 00168 // 92% and 100% of the true Et, with the direction measured in 45 degree bins. 00169 // The final precision depends on the number of factors used in corrFact. 00170 // The present version with eleven factors gives a precision of 1% on Et, and 00171 // finds the direction to the nearest 5 degrees. 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 // Here's the coarse calculation, with just one multiply operation 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 // For the fine calculation we multiply both input components 00211 // by all the factors in the corrFact list in order to find 00212 // the required corrections to the energy and angle 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 // Store the result of the calculation 00228 // 00229 result.mag = eneCorect; 00230 result.phi = phiCorect; 00231 00232 return result; 00233 }
void L1GctMet::setAlgoType | ( | const metAlgoType | algo | ) | [inline] |
void L1GctMet::setBitShift | ( | const unsigned | nbits | ) | [inline] |
void L1GctMet::setComponents | ( | const etComponentType & | ex, | |
const etComponentType & | ey | |||
) | [inline] |
Definition at line 41 of file L1GctMet.h.
References setExComponent(), and setEyComponent().
00041 { setExComponent(ex); setEyComponent(ey); }
void L1GctMet::setComponents | ( | const unsigned | ex, | |
const unsigned | ey | |||
) | [inline] |
Definition at line 40 of file L1GctMet.h.
References setExComponent(), and setEyComponent().
Referenced by L1GctGlobalEnergyAlgos::process().
00040 { setExComponent(ex); setEyComponent(ey); }
void L1GctMet::setExComponent | ( | const etComponentType & | ex | ) | [inline] |
void L1GctMet::setExComponent | ( | const unsigned | ex | ) |
Definition at line 59 of file L1GctMet.cc.
References pyDBSRunClass::temp.
Referenced by setComponents().
00059 { 00060 etComponentType temp(ex); 00061 setExComponent(temp); 00062 }
void L1GctMet::setEyComponent | ( | const etComponentType & | ey | ) | [inline] |
void L1GctMet::setEyComponent | ( | const unsigned | ey | ) |
Definition at line 64 of file L1GctMet.cc.
References pyDBSRunClass::temp.
Referenced by setComponents().
00064 { 00065 etComponentType temp(ey); 00066 setEyComponent(temp); 00067 }
metAlgoType L1GctMet::m_algoType [private] |
Definition at line 67 of file L1GctMet.h.
Referenced by getAlgoType(), metVector(), and setAlgoType().
unsigned short L1GctMet::m_bitShift [private] |
Definition at line 68 of file L1GctMet.h.
Referenced by getBitShift(), metVector(), and setBitShift().
etComponentType L1GctMet::m_exComponent [private] |
Definition at line 65 of file L1GctMet.h.
Referenced by getExComponent(), metVector(), and setExComponent().
etComponentType L1GctMet::m_eyComponent [private] |
Definition at line 66 of file L1GctMet.h.
Referenced by getEyComponent(), metVector(), and setEyComponent().