Stores Level-1 missing Et in (Ex, Ey) form, allowing it to be retrieved as (magnitude, angle) More...
#include <L1GctMet.h>
Classes | |
struct | etmiss_internal |
struct | etmiss_vec |
Public Types | |
typedef L1GctWheelEnergyFpga::etComponentType | etComponentType |
typedef L1GctUnsignedInt < L1GctEtMiss::kEtMissPhiNBits > | etMissPhiType |
typedef L1GctUnsignedInt < L1GctEtMiss::kEtMissNBits > | etMissType |
enum | metAlgoType { cordicTranslate, useHtMissLut, oldGct, floatingPoint } |
Public Member Functions | |
const double | componentLsb () const |
const L1CaloEtScale * | etScale () const |
metAlgoType | getAlgoType () const |
unsigned | getBitShift () const |
etComponentType | getExComponent () const |
etComponentType | getEyComponent () const |
const L1GctHtMissLut * | getHtMissLut () const |
L1GctMet (const unsigned ex=0, const unsigned ey=0, const metAlgoType algo=cordicTranslate) | |
L1GctMet (const etComponentType &ex, const etComponentType &ey, const metAlgoType algo=cordicTranslate) | |
etmiss_vec | metVector () const |
void | setAlgoType (const metAlgoType algo) |
void | setBitShift (const unsigned nbits) |
void | setComponents (const unsigned ex, const unsigned ey) |
void | setComponents (const etComponentType &ex, const etComponentType &ey) |
void | setEtComponentLsb (const double lsb) |
void | setEtScale (const L1CaloEtScale *const fn) |
void | setExComponent (const unsigned ex) |
void | setExComponent (const etComponentType &ex) |
void | setEyComponent (const etComponentType &ey) |
void | setEyComponent (const unsigned ey) |
~L1GctMet () | |
Private Types | |
enum | etComponentShift { kExOrEyMissComponentShift = 4 } |
Private Member Functions | |
int | cordicShiftAndRoundBits (const int e, const unsigned nBits) const |
etmiss_internal | cordicTranslateAlgo (const int ex, const int ey, const bool of) const |
etmiss_internal | floatingPointAlgo (const int ex, const int ey) const |
const bool | inputOverFlow () const |
etmiss_internal | oldGctAlgo (const int ex, const int ey) const |
etmiss_internal | useHtMissLutAlgo (const int ex, const int ey, const bool of) const |
Private Attributes | |
metAlgoType | m_algoType |
unsigned short | m_bitShift |
etComponentType | m_exComponent |
etComponentType | m_eyComponent |
L1GctHtMissLut * | m_htMissLut |
Stores Level-1 missing Et in (Ex, Ey) form, allowing it to be retrieved as (magnitude, angle)
Allows the implementation of alternative algorithms
Definition at line 20 of file L1GctMet.h.
Definition at line 28 of file L1GctMet.h.
typedef L1GctUnsignedInt< L1GctEtMiss::kEtMissPhiNBits > L1GctMet::etMissPhiType |
Definition at line 27 of file L1GctMet.h.
typedef L1GctUnsignedInt< L1GctEtMiss::kEtMissNBits > L1GctMet::etMissType |
Definition at line 26 of file L1GctMet.h.
enum L1GctMet::etComponentShift [private] |
Definition at line 72 of file L1GctMet.h.
{ kExOrEyMissComponentShift=4 };
Definition at line 24 of file L1GctMet.h.
L1GctMet::L1GctMet | ( | const unsigned | ex = 0 , |
const unsigned | ey = 0 , |
||
const metAlgoType | algo = cordicTranslate |
||
) |
Definition at line 7 of file L1GctMet.cc.
: m_exComponent(ex), m_eyComponent(ey), m_algoType(algo), m_bitShift(0), m_htMissLut(new L1GctHtMissLut()) { }
L1GctMet::L1GctMet | ( | const etComponentType & | ex, |
const etComponentType & | ey, | ||
const metAlgoType | algo = cordicTranslate |
||
) |
Definition at line 15 of file L1GctMet.cc.
: m_exComponent(ex), m_eyComponent(ey), m_algoType(algo), m_bitShift(0), m_htMissLut(new L1GctHtMissLut()) { }
L1GctMet::~L1GctMet | ( | ) |
Definition at line 23 of file L1GctMet.cc.
{}
const double L1GctMet::componentLsb | ( | ) | const |
Definition at line 333 of file L1GctMet.cc.
References L1GctHtMissLut::componentLsb(), and m_htMissLut.
{ return m_htMissLut->componentLsb(); }
int L1GctMet::cordicShiftAndRoundBits | ( | const int | e, |
const unsigned | nBits | ||
) | const [private] |
Definition at line 161 of file L1GctMet.cc.
References alignCSCRings::e, and alignCSCRings::r.
Referenced by cordicTranslateAlgo().
L1GctMet::etmiss_internal L1GctMet::cordicTranslateAlgo | ( | const int | ex, |
const int | ey, | ||
const bool | of | ||
) | const [private] |
Definition at line 79 of file L1GctMet.cc.
References cordicShiftAndRoundBits(), i, L1GctMet::etmiss_internal::mag, L1GctMet::etmiss_internal::phi, query::result, x, detailsBasic3DVector::y, and z.
Referenced by metVector().
{ //--------------------------------------------------------------------------------- // // This is an implementation of the CORDIC algorithm (COordinate Rotation for DIgital Computers) // // Starting from an initial two-component vector ex, ey, we perform successively smaller rotations // to transform the y component to zero. At the end of the procedure, the x component is the magnitude // of the original vector, scaled by a known constant factor. The azimuth angle phi is the sum of the // rotations applied. // // The algorithm can be used in a number of different variants for calculation of trigonometric // and hyperbolic functions as well as exponentials, logarithms and square roots. This variant // is called the "vector translation" mode in the Xilinx documentation. // // Original references: // Volder, J., "The CORDIC Trigonometric Computing Technique" IRE Trans. Electronic Computing, Vol. // EC-8, Sept. 1959, pp330-334 // Walther, J.S., "A Unified Algorithm for Elementary Functions," Spring Joint computer conf., 1971, // proc., pp379-385 // // Other information sources: http://www.xilinx.com/support/documentation/ip_documentation/cordic.pdf; // http://www.fpga-guru.com/files/crdcsrvy.pdf; and http://en.wikipedia.org/wiki/CORDIC // //--------------------------------------------------------------------------------- etmiss_internal result; static const int of_val = 0x1FFF; // set components to 8191 (decimal) if there's an overflow on the input static const int n_iterations = 6; // The angle units here are 1/32 of a 5 degree bin. // So a 90 degree rotation is 32*18=576 or 240 hex. const int cordic_angles[n_iterations] = { 0x120, 0x0AA, 0x05A, 0x02E, 0x017, 0x00B }; const int cordic_starting_angle_090 = 0x240; const int cordic_starting_angle_270 = 0x6C0; const int cordic_angle_360 = 0x900; const int cordic_scale_factor = 0x26E; // decimal 622 int x, y; int dx,dy; int z; if (of) { x = of_val; y = -of_val; z = cordic_starting_angle_090; } else { if (ey>=0) { x = ey; y = -ex; z = cordic_starting_angle_090; } else { x = -ey; y = ex; z = cordic_starting_angle_270; } } for (int i=0; i<n_iterations; i++) { dx = cordicShiftAndRoundBits (y,i); dy = cordicShiftAndRoundBits (x,i); if (y>=0) { x = x + dx; y = y - dy; z = z + cordic_angles[i]; } else { x = x - dx; y = y + dy; z = z - cordic_angles[i]; } } int scaled_magnitude = x * cordic_scale_factor; int adjusted_angle = ( (z < 0) ? (z + cordic_angle_360) : z ) % cordic_angle_360; result.mag = scaled_magnitude >> 10; result.phi = adjusted_angle >> 5; if (result.mag > (unsigned) of_val) result.mag = (unsigned) of_val; return result; }
const L1CaloEtScale * L1GctMet::etScale | ( | ) | const |
Definition at line 328 of file L1GctMet.cc.
References L1GctHtMissLut::etScale(), and m_htMissLut.
{ return m_htMissLut->etScale(); }
L1GctMet::etmiss_internal L1GctMet::floatingPointAlgo | ( | const int | ex, |
const int | ey | ||
) | const [private] |
Definition at line 297 of file L1GctMet.cc.
References M_PI, L1GctMet::etmiss_internal::mag, L1GctMet::etmiss_internal::phi, query::result, and mathSSE::sqrt().
Referenced by metVector().
{ etmiss_internal result; double fx = static_cast<double>(ex); double fy = static_cast<double>(ey); double fmag = sqrt(fx*fx + fy*fy); double fphi = 36.*atan2(fy, fx)/M_PI; result.mag = static_cast<unsigned>(fmag); if (fphi>=0) { result.phi = static_cast<unsigned>(fphi); } else { result.phi = static_cast<unsigned>(fphi+72.); } return result; }
metAlgoType L1GctMet::getAlgoType | ( | ) | const [inline] |
unsigned L1GctMet::getBitShift | ( | ) | const [inline] |
etComponentType L1GctMet::getExComponent | ( | ) | const [inline] |
etComponentType L1GctMet::getEyComponent | ( | ) | const [inline] |
const L1GctHtMissLut* L1GctMet::getHtMissLut | ( | ) | const [inline] |
Definition at line 62 of file L1GctMet.h.
References m_htMissLut.
Referenced by L1GctGlobalEnergyAlgos::getHtMissLut().
{ return m_htMissLut; }
const bool L1GctMet::inputOverFlow | ( | ) | const [private] |
Private method to check for an overflow condition on the input components Allows the check to depend on the algorithm type
Definition at line 340 of file L1GctMet.cc.
References kExOrEyMissComponentShift, L1GctHtMissLut::kHxOrHyMissComponentNBits, m_algoType, m_exComponent, m_eyComponent, L1GctTwosComplement< nBits >::overFlow(), query::result, useHtMissLut, and L1GctTwosComplement< nBits >::value().
Referenced by metVector().
{ bool result = m_exComponent.overFlow() || m_eyComponent.overFlow(); if (m_algoType == useHtMissLut) { static const int maxComponentInput = ( 1 << (L1GctHtMissLut::kHxOrHyMissComponentNBits+kExOrEyMissComponentShift-1) ) - 1; // Emulate the (symmetric) overflow condition used in the firmware result |= (m_exComponent.value() > maxComponentInput) || (m_exComponent.value() < -maxComponentInput) || (m_eyComponent.value() > maxComponentInput) || (m_eyComponent.value() < -maxComponentInput); } return result; }
L1GctMet::etmiss_vec L1GctMet::metVector | ( | ) | const |
Definition at line 27 of file L1GctMet.cc.
References cordicTranslate, cordicTranslateAlgo(), floatingPoint, floatingPointAlgo(), inputOverFlow(), 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, query::result, L1GctUnsignedInt< nBits >::setOverFlow(), L1GctUnsignedInt< nBits >::setValue(), useHtMissLut, useHtMissLutAlgo(), and L1GctTwosComplement< nBits >::value().
Referenced by L1GctGlobalEnergyAlgos::process().
{ etmiss_vec result; etmiss_internal algoResult; switch (m_algoType) { case cordicTranslate: algoResult = cordicTranslateAlgo (m_exComponent.value(), m_eyComponent.value(), (m_exComponent.overFlow() || m_eyComponent.overFlow()) ); break; case useHtMissLut: algoResult = useHtMissLutAlgo (m_exComponent.value(), m_eyComponent.value(), (m_exComponent.overFlow() || m_eyComponent.overFlow()) ); break; case oldGct: algoResult = oldGctAlgo (m_exComponent.value(), m_eyComponent.value()); break; case floatingPoint: algoResult = floatingPointAlgo (m_exComponent.value(), m_eyComponent.value()); break; default: algoResult.mag = 0; algoResult.phi = 0; break; } // The parameter m_bitShift allows us to discard additional LSB // in order to change the output scale. result.mag.setValue(algoResult.mag>>(m_bitShift)); result.phi.setValue(algoResult.phi); result.mag.setOverFlow( result.mag.overFlow() || inputOverFlow() ); return result; }
L1GctMet::etmiss_internal L1GctMet::oldGctAlgo | ( | const int | ex, |
const int | ey | ||
) | const [private] |
Definition at line 219 of file L1GctMet.cc.
References abs, b, i, L1GctMet::etmiss_internal::mag, max(), L1GctMet::etmiss_internal::phi, query::result, and alignCSCRings::s.
Referenced by metVector().
{ //--------------------------------------------------------------------------------- // // Calculates magnitude and direction of missing Et, given measured Ex and Ey. // // The algorithm used is suitable for implementation in hardware, using integer // multiplication, addition and comparison and bit shifting operations. // // Proceed in two stages. The first stage gives a result that lies between // 92% and 100% of the true Et, with the direction measured in 45 degree bins. // The final precision depends on the number of factors used in corrFact. // The present version with eleven factors gives a precision of 1% on Et, and // finds the direction to the nearest 5 degrees. // //--------------------------------------------------------------------------------- etmiss_internal result; unsigned eneCoarse, phiCoarse; unsigned eneCorect, phiCorect; const unsigned root2fact = 181; const unsigned corrFact[11] = {24, 39, 51, 60, 69, 77, 83, 89, 95, 101, 106}; const unsigned corrDphi[11] = { 0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4}; std::vector<bool> s(3); unsigned Mx, My, Mw; unsigned Dx, Dy; unsigned eFact; unsigned b,phibin; bool midphi=false; // Here's the coarse calculation, with just one multiply operation // My = static_cast<unsigned>(abs(ey)); Mx = static_cast<unsigned>(abs(ex)); Mw = (((Mx+My)*root2fact)+0x80)>>8; s.at(0) = (ey<0); s.at(1) = (ex<0); s.at(2) = (My>Mx); phibin = 0; b = 0; for (int i=0; i<3; i++) { if (s.at(i)) { b=1-b;} phibin = 2*phibin + b; } eneCoarse = std::max(std::max(Mx, My), Mw); phiCoarse = phibin*9; // For the fine calculation we multiply both input components // by all the factors in the corrFact list in order to find // the required corrections to the energy and angle // for (eFact=0; eFact<10; eFact++) { Dx = (Mx*corrFact[eFact])>>8; Dy = (My*corrFact[eFact])>>8; if ((Dx>=My) || (Dy>=Mx)) {midphi=false; break;} if ((Mx+Dx)>=(My-Dy) && (My+Dy)>=(Mx-Dx)) {midphi=true; break;} } eneCorect = (eneCoarse*(128+eFact))>>7; if (midphi ^ (b==1)) { phiCorect = phiCoarse + 8 - corrDphi[eFact]; } else { phiCorect = phiCoarse + corrDphi[eFact]; } // Store the result of the calculation // result.mag = eneCorect; result.phi = phiCorect; return result; }
void L1GctMet::setAlgoType | ( | const metAlgoType | algo | ) | [inline] |
void L1GctMet::setBitShift | ( | const unsigned | nbits | ) | [inline] |
Definition at line 58 of file L1GctMet.h.
References m_bitShift.
Referenced by L1GctGlobalEnergyAlgos::L1GctGlobalEnergyAlgos().
{ m_bitShift = nbits; }
void L1GctMet::setComponents | ( | const unsigned | ex, |
const unsigned | ey | ||
) | [inline] |
Definition at line 43 of file L1GctMet.h.
References setExComponent(), and setEyComponent().
Referenced by L1GctGlobalEnergyAlgos::process().
{ setExComponent(ex); setEyComponent(ey); }
void L1GctMet::setComponents | ( | const etComponentType & | ex, |
const etComponentType & | ey | ||
) | [inline] |
Definition at line 44 of file L1GctMet.h.
References setExComponent(), and setEyComponent().
{ setExComponent(ex); setEyComponent(ey); }
void L1GctMet::setEtComponentLsb | ( | const double | lsb | ) |
Definition at line 323 of file L1GctMet.cc.
References kExOrEyMissComponentShift, m_htMissLut, and L1GctHtMissLut::setExEyLsb().
Referenced by L1GctGlobalEnergyAlgos::setJetFinderParams().
{ m_htMissLut->setExEyLsb( lsb * static_cast<double>( 1<<kExOrEyMissComponentShift ) ); }
void L1GctMet::setEtScale | ( | const L1CaloEtScale *const | fn | ) |
Definition at line 318 of file L1GctMet.cc.
References m_htMissLut, and L1GctHtMissLut::setEtScale().
Referenced by L1GctGlobalEnergyAlgos::setHtMissScale().
{ m_htMissLut->setEtScale(fn); }
void L1GctMet::setExComponent | ( | const etComponentType & | ex | ) | [inline] |
void L1GctMet::setExComponent | ( | const unsigned | ex | ) |
Definition at line 66 of file L1GctMet.cc.
References groupFilesInBlocks::temp.
Referenced by setComponents().
{ etComponentType temp(ex); setExComponent(temp); }
void L1GctMet::setEyComponent | ( | const etComponentType & | ey | ) | [inline] |
void L1GctMet::setEyComponent | ( | const unsigned | ey | ) |
Definition at line 71 of file L1GctMet.cc.
References groupFilesInBlocks::temp.
Referenced by setComponents().
{ etComponentType temp(ey); setEyComponent(temp); }
L1GctMet::etmiss_internal L1GctMet::useHtMissLutAlgo | ( | const int | ex, |
const int | ey, | ||
const bool | of | ||
) | const [private] |
Definition at line 174 of file L1GctMet.cc.
References abs, kExOrEyMissComponentShift, L1GctHtMissLut::kHtMissAngleNBits, L1GctHtMissLut::kHtMissMagnitudeNBits, L1GctHtMissLut::kHxOrHyMissComponentNBits, L1GctLut< NAddressBits, NDataBits >::lutValue(), m_htMissLut, L1GctMet::etmiss_internal::mag, L1GctMet::etmiss_internal::phi, and query::result.
Referenced by metVector().
{ // The firmware discards the LSB of the input values, before forming // the address for the LUT. We do the same here. static const int maxComponent = 1<<L1GctHtMissLut::kHxOrHyMissComponentNBits; static const int componentMask = maxComponent-1; static const int maxPosComponent = componentMask >> 1; static const int maxInput = 1<<(L1GctHtMissLut::kHxOrHyMissComponentNBits+kExOrEyMissComponentShift-1); static const unsigned resultMagMask = (1<<L1GctHtMissLut::kHtMissMagnitudeNBits) - 1; static const unsigned resultPhiMask = (1<<L1GctHtMissLut::kHtMissAngleNBits) - 1; etmiss_internal result; if (m_htMissLut == 0) { result.mag = 0; result.phi = 0; } else { // Extract the bit fields of the input components to be used for the LUT address int hxCompBits = (ex >> kExOrEyMissComponentShift) & componentMask; int hyCompBits = (ey >> kExOrEyMissComponentShift) & componentMask; if (of || (abs(ex) >= maxInput) || (abs(ey) >= maxInput)) { hxCompBits = maxPosComponent; hyCompBits = maxPosComponent; } // Perform the table lookup to get the missing Ht magnitude and phi uint16_t lutAddress = static_cast<uint16_t> ( (hxCompBits << L1GctHtMissLut::kHxOrHyMissComponentNBits) | hyCompBits ); uint16_t lutData = m_htMissLut->lutValue(lutAddress); result.mag = static_cast<unsigned>(lutData>>L1GctHtMissLut::kHtMissAngleNBits) & resultMagMask; result.phi = static_cast<unsigned>(lutData) & resultPhiMask; } return result; }
metAlgoType L1GctMet::m_algoType [private] |
Definition at line 86 of file L1GctMet.h.
Referenced by getAlgoType(), inputOverFlow(), metVector(), and setAlgoType().
unsigned short L1GctMet::m_bitShift [private] |
Definition at line 87 of file L1GctMet.h.
Referenced by getBitShift(), metVector(), and setBitShift().
etComponentType L1GctMet::m_exComponent [private] |
Definition at line 84 of file L1GctMet.h.
Referenced by getExComponent(), inputOverFlow(), metVector(), and setExComponent().
etComponentType L1GctMet::m_eyComponent [private] |
Definition at line 85 of file L1GctMet.h.
Referenced by getEyComponent(), inputOverFlow(), metVector(), and setEyComponent().
L1GctHtMissLut* L1GctMet::m_htMissLut [private] |
Definition at line 89 of file L1GctMet.h.
Referenced by componentLsb(), etScale(), getHtMissLut(), setEtComponentLsb(), setEtScale(), and useHtMissLutAlgo().