File indexing completed on 2024-04-06 12:19:53
0001 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctMet.h"
0002
0003 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctHtMissLut.h"
0004
0005 #include <cmath>
0006
0007 L1GctMet::L1GctMet(const unsigned ex, const unsigned ey, const L1GctMet::metAlgoType algo)
0008 : m_exComponent(ex), m_eyComponent(ey), m_algoType(algo), m_bitShift(0), m_htMissLut(new L1GctHtMissLut()) {}
0009
0010 L1GctMet::L1GctMet(const etComponentType& ex, const etComponentType& ey, const metAlgoType algo)
0011 : m_exComponent(ex), m_eyComponent(ey), m_algoType(algo), m_bitShift(0), m_htMissLut(new L1GctHtMissLut()) {}
0012
0013 L1GctMet::~L1GctMet() {}
0014
0015
0016 L1GctMet::etmiss_vec L1GctMet::metVector() const {
0017 etmiss_vec result;
0018 etmiss_internal algoResult;
0019 switch (m_algoType) {
0020 case cordicTranslate:
0021 algoResult = cordicTranslateAlgo(
0022 m_exComponent.value(), m_eyComponent.value(), (m_exComponent.overFlow() || m_eyComponent.overFlow()));
0023 break;
0024
0025 case useHtMissLut:
0026 algoResult = useHtMissLutAlgo(
0027 m_exComponent.value(), m_eyComponent.value(), (m_exComponent.overFlow() || m_eyComponent.overFlow()));
0028 break;
0029
0030 case oldGct:
0031 algoResult = oldGctAlgo(m_exComponent.value(), m_eyComponent.value());
0032 break;
0033
0034 case floatingPoint:
0035 algoResult = floatingPointAlgo(m_exComponent.value(), m_eyComponent.value());
0036 break;
0037
0038 default:
0039 algoResult.mag = 0;
0040 algoResult.phi = 0;
0041 break;
0042 }
0043
0044
0045
0046 result.mag.setValue(algoResult.mag >> (m_bitShift));
0047 result.phi.setValue(algoResult.phi);
0048
0049 result.mag.setOverFlow(result.mag.overFlow() || inputOverFlow());
0050
0051 return result;
0052 }
0053
0054 void L1GctMet::setExComponent(const unsigned ex) {
0055 etComponentType temp(ex);
0056 setExComponent(temp);
0057 }
0058
0059 void L1GctMet::setEyComponent(const unsigned ey) {
0060 etComponentType temp(ey);
0061 setEyComponent(temp);
0062 }
0063
0064
0065
0066 L1GctMet::etmiss_internal L1GctMet::cordicTranslateAlgo(const int ex, const int ey, const bool of) const {
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091 etmiss_internal result;
0092
0093 static const int of_val = 0x1FFF;
0094
0095 static const int n_iterations = 6;
0096
0097
0098 const int cordic_angles[n_iterations] = {0x120, 0x0AA, 0x05A, 0x02E, 0x017, 0x00B};
0099 const int cordic_starting_angle_090 = 0x240;
0100 const int cordic_starting_angle_270 = 0x6C0;
0101 const int cordic_angle_360 = 0x900;
0102
0103 const int cordic_scale_factor = 0x26E;
0104
0105 int x, y;
0106 int dx, dy;
0107 int z;
0108
0109 if (of) {
0110 x = of_val;
0111 y = -of_val;
0112 z = cordic_starting_angle_090;
0113 } else {
0114 if (ey >= 0) {
0115 x = ey;
0116 y = -ex;
0117 z = cordic_starting_angle_090;
0118 } else {
0119 x = -ey;
0120 y = ex;
0121 z = cordic_starting_angle_270;
0122 }
0123 }
0124
0125 for (int i = 0; i < n_iterations; i++) {
0126 dx = cordicShiftAndRoundBits(y, i);
0127 dy = cordicShiftAndRoundBits(x, i);
0128 if (y >= 0) {
0129 x = x + dx;
0130 y = y - dy;
0131 z = z + cordic_angles[i];
0132 } else {
0133 x = x - dx;
0134 y = y + dy;
0135 z = z - cordic_angles[i];
0136 }
0137 }
0138
0139 int scaled_magnitude = x * cordic_scale_factor;
0140 int adjusted_angle = ((z < 0) ? (z + cordic_angle_360) : z) % cordic_angle_360;
0141 result.mag = scaled_magnitude >> 10;
0142 result.phi = adjusted_angle >> 5;
0143 if (result.mag > (unsigned)of_val)
0144 result.mag = (unsigned)of_val;
0145 return result;
0146 }
0147
0148 int L1GctMet::cordicShiftAndRoundBits(const int e, const unsigned nBits) const {
0149 int r;
0150 if (nBits == 0) {
0151 r = e;
0152 } else {
0153 r = (((e >> (nBits - 1)) + 1) >> 1);
0154 }
0155 return r;
0156 }
0157
0158 L1GctMet::etmiss_internal L1GctMet::useHtMissLutAlgo(const int ex, const int ey, const bool of) const {
0159
0160
0161 static const int maxComponent = 1 << L1GctHtMissLut::kHxOrHyMissComponentNBits;
0162 static const int componentMask = maxComponent - 1;
0163 static const int maxPosComponent = componentMask >> 1;
0164
0165 static const int maxInput = 1 << (L1GctHtMissLut::kHxOrHyMissComponentNBits + kExOrEyMissComponentShift - 1);
0166
0167 static const unsigned resultMagMask = (1 << L1GctHtMissLut::kHtMissMagnitudeNBits) - 1;
0168 static const unsigned resultPhiMask = (1 << L1GctHtMissLut::kHtMissAngleNBits) - 1;
0169
0170 etmiss_internal result;
0171
0172 if (m_htMissLut == nullptr) {
0173 result.mag = 0;
0174 result.phi = 0;
0175
0176 } else {
0177
0178 int hxCompBits = (ex >> kExOrEyMissComponentShift) & componentMask;
0179 int hyCompBits = (ey >> kExOrEyMissComponentShift) & componentMask;
0180
0181 if (of || (abs(ex) >= maxInput) || (abs(ey) >= maxInput)) {
0182 hxCompBits = maxPosComponent;
0183 hyCompBits = maxPosComponent;
0184 }
0185
0186
0187 uint16_t lutAddress = static_cast<uint16_t>((hxCompBits << L1GctHtMissLut::kHxOrHyMissComponentNBits) | hyCompBits);
0188
0189 uint16_t lutData = m_htMissLut->lutValue(lutAddress);
0190
0191 result.mag = static_cast<unsigned>(lutData >> L1GctHtMissLut::kHtMissAngleNBits) & resultMagMask;
0192 result.phi = static_cast<unsigned>(lutData) & resultPhiMask;
0193 }
0194
0195 return result;
0196 }
0197
0198 L1GctMet::etmiss_internal L1GctMet::oldGctAlgo(const int ex, const int ey) const {
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213 etmiss_internal result;
0214
0215 unsigned eneCoarse, phiCoarse;
0216 unsigned eneCorect, phiCorect;
0217
0218 const unsigned root2fact = 181;
0219 const unsigned corrFact[11] = {24, 39, 51, 60, 69, 77, 83, 89, 95, 101, 106};
0220 const unsigned corrDphi[11] = {0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4};
0221
0222 std::vector<bool> s(3);
0223 unsigned Mx, My, Mw;
0224
0225 unsigned Dx, Dy;
0226 unsigned eFact;
0227
0228 unsigned b, phibin;
0229 bool midphi = false;
0230
0231
0232
0233 My = static_cast<unsigned>(abs(ey));
0234 Mx = static_cast<unsigned>(abs(ex));
0235 Mw = (((Mx + My) * root2fact) + 0x80) >> 8;
0236
0237 s.at(0) = (ey < 0);
0238 s.at(1) = (ex < 0);
0239 s.at(2) = (My > Mx);
0240
0241 phibin = 0;
0242 b = 0;
0243 for (int i = 0; i < 3; i++) {
0244 if (s.at(i)) {
0245 b = 1 - b;
0246 }
0247 phibin = 2 * phibin + b;
0248 }
0249
0250 eneCoarse = std::max(std::max(Mx, My), Mw);
0251 phiCoarse = phibin * 9;
0252
0253
0254
0255
0256
0257 for (eFact = 0; eFact < 10; eFact++) {
0258 Dx = (Mx * corrFact[eFact]) >> 8;
0259 Dy = (My * corrFact[eFact]) >> 8;
0260 if ((Dx >= My) || (Dy >= Mx)) {
0261 midphi = false;
0262 break;
0263 }
0264 if ((Mx + Dx) >= (My - Dy) && (My + Dy) >= (Mx - Dx)) {
0265 midphi = true;
0266 break;
0267 }
0268 }
0269 eneCorect = (eneCoarse * (128 + eFact)) >> 7;
0270 if (midphi ^ (b == 1)) {
0271 phiCorect = phiCoarse + 8 - corrDphi[eFact];
0272 } else {
0273 phiCorect = phiCoarse + corrDphi[eFact];
0274 }
0275
0276
0277
0278 result.mag = eneCorect;
0279 result.phi = phiCorect;
0280
0281 return result;
0282 }
0283
0284 L1GctMet::etmiss_internal L1GctMet::floatingPointAlgo(const int ex, const int ey) const {
0285 etmiss_internal result;
0286
0287 double fx = static_cast<double>(ex);
0288 double fy = static_cast<double>(ey);
0289 double fmag = sqrt(fx * fx + fy * fy);
0290 double fphi = 36. * atan2(fy, fx) / M_PI;
0291
0292 result.mag = static_cast<unsigned>(fmag);
0293 if (fphi >= 0) {
0294 result.phi = static_cast<unsigned>(fphi);
0295 } else {
0296 result.phi = static_cast<unsigned>(fphi + 72.);
0297 }
0298
0299 return result;
0300 }
0301
0302 void L1GctMet::setEtScale(const L1CaloEtScale* const fn) { m_htMissLut->setEtScale(fn); }
0303
0304 void L1GctMet::setEtComponentLsb(const double lsb) {
0305 m_htMissLut->setExEyLsb(lsb * static_cast<double>(1 << kExOrEyMissComponentShift));
0306 }
0307
0308 const L1CaloEtScale* L1GctMet::etScale() const { return m_htMissLut->etScale(); }
0309
0310 const double L1GctMet::componentLsb() const { return m_htMissLut->componentLsb(); }
0311
0312
0313
0314 const bool L1GctMet::inputOverFlow() const {
0315 bool result = m_exComponent.overFlow() || m_eyComponent.overFlow();
0316
0317 if (m_algoType == useHtMissLut) {
0318 static const int maxComponentInput =
0319 (1 << (L1GctHtMissLut::kHxOrHyMissComponentNBits + kExOrEyMissComponentShift - 1)) - 1;
0320
0321
0322 result |= (m_exComponent.value() > maxComponentInput) || (m_exComponent.value() < -maxComponentInput) ||
0323 (m_eyComponent.value() > maxComponentInput) || (m_eyComponent.value() < -maxComponentInput);
0324 }
0325
0326 return result;
0327 }