CMS 3D CMS Logo

Classes | Public Types | Public Member Functions | Private Types | Private Member Functions | Private Attributes

L1GctMet Class Reference

Stores Level-1 missing Et in (Ex, Ey) form, allowing it to be retrieved as (magnitude, angle) More...

#include <L1GctMet.h>

List of all members.

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 L1CaloEtScaleetScale () const
metAlgoType getAlgoType () const
unsigned getBitShift () const
etComponentType getExComponent () const
etComponentType getEyComponent () const
const L1GctHtMissLutgetHtMissLut () 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
L1GctHtMissLutm_htMissLut

Detailed Description

Stores Level-1 missing Et in (Ex, Ey) form, allowing it to be retrieved as (magnitude, angle)

Author:
Greg Heath
Date:
April 2008

Allows the implementation of alternative algorithms

Definition at line 20 of file L1GctMet.h.


Member Typedef Documentation

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.


Member Enumeration Documentation

Enumerator:
kExOrEyMissComponentShift 

Definition at line 72 of file L1GctMet.h.

Enumerator:
cordicTranslate 
useHtMissLut 
oldGct 
floatingPoint 

Definition at line 24 of file L1GctMet.h.


Constructor & Destructor Documentation

L1GctMet::L1GctMet ( const unsigned  ex = 0,
const unsigned  ey = 0,
const metAlgoType  algo = cordicTranslate 
)

Definition at line 7 of file L1GctMet.cc.

L1GctMet::L1GctMet ( const etComponentType ex,
const etComponentType ey,
const metAlgoType  algo = cordicTranslate 
)

Definition at line 15 of file L1GctMet.cc.

L1GctMet::~L1GctMet ( )

Definition at line 23 of file L1GctMet.cc.

{}

Member Function Documentation

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 ExpressReco_HICollisions_FallBack::e, and csvReporter::r.

Referenced by cordicTranslateAlgo().

{
  int r;
  if (nBits==0) {
    r = e;
  } else {
    r = (((e>>(nBits-1)) + 1)>>1);
  }
  return r;
}
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, ExpressReco_HICollisions_FallBack::x, ExpressReco_HICollisions_FallBack::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: https://www.xilinx.com/support/documentation/ip_documentation/cordic.pdf;
  // https://www.fpga-guru.com/files/crdcsrvy.pdf; and https://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]

Definition at line 54 of file L1GctMet.h.

References m_algoType.

{ return m_algoType; }
unsigned L1GctMet::getBitShift ( ) const [inline]

Definition at line 59 of file L1GctMet.h.

References m_bitShift.

{ return m_bitShift; }
etComponentType L1GctMet::getExComponent ( ) const [inline]

Definition at line 49 of file L1GctMet.h.

References m_exComponent.

{ return m_exComponent; }
etComponentType L1GctMet::getEyComponent ( ) const [inline]

Definition at line 50 of file L1GctMet.h.

References m_eyComponent.

{ return m_eyComponent; }
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 asciidump::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]

Definition at line 53 of file L1GctMet.h.

References ExpressReco_HICollisions_FallBack::algo, and m_algoType.

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().

void L1GctMet::setComponents ( const etComponentType ex,
const etComponentType ey 
) [inline]

Definition at line 44 of file L1GctMet.h.

References setExComponent(), and setEyComponent().

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().

void L1GctMet::setExComponent ( const etComponentType ex) [inline]

Definition at line 47 of file L1GctMet.h.

References m_exComponent.

{ m_exComponent = ex; }
void L1GctMet::setExComponent ( const unsigned  ex)

Definition at line 66 of file L1GctMet.cc.

References cond::rpcobtemp::temp.

Referenced by setComponents().

void L1GctMet::setEyComponent ( const etComponentType ey) [inline]

Definition at line 48 of file L1GctMet.h.

References m_eyComponent.

{ m_eyComponent = ey; }
void L1GctMet::setEyComponent ( const unsigned  ey)

Definition at line 71 of file L1GctMet.cc.

References cond::rpcobtemp::temp.

Referenced by setComponents().

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;
}

Member Data Documentation

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().

Definition at line 84 of file L1GctMet.h.

Referenced by getExComponent(), inputOverFlow(), metVector(), and setExComponent().

Definition at line 85 of file L1GctMet.h.

Referenced by getEyComponent(), inputOverFlow(), metVector(), and setEyComponent().