File indexing completed on 2024-09-07 04:36:51
0001
0002
0003
0004
0005
0006
0007
0008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0009 #include "L1Trigger/L1TCalorimeter/interface/Stage2Layer2EGammaAlgorithmFirmware.h"
0010
0011 #include "L1Trigger/L1TCalorimeter/interface/CaloStage2Nav.h"
0012 #include "L1Trigger/L1TCalorimeter/interface/CaloTools.h"
0013 #include "L1Trigger/L1TCalorimeter/interface/BitonicSort.h"
0014 #include "L1Trigger/L1TCalorimeter/interface/AccumulatingSort.h"
0015
0016 namespace l1t {
0017 bool operator>(const l1t::EGamma& a, const l1t::EGamma& b) { return a.pt() > b.pt(); }
0018 }
0019
0020
0021 l1t::Stage2Layer2EGammaAlgorithmFirmwareImp1::Stage2Layer2EGammaAlgorithmFirmwareImp1(CaloParamsHelper const* params)
0022 : params_(params)
0023
0024 {}
0025
0026
0027 void l1t::Stage2Layer2EGammaAlgorithmFirmwareImp1::processEvent(const std::vector<l1t::CaloCluster>& clusters,
0028 const std::vector<l1t::CaloTower>& towers,
0029 std::vector<l1t::EGamma>& egammas)
0030
0031 {
0032 l1t::CaloStage2Nav caloNav;
0033 egammas.clear();
0034
0035
0036 std::vector<l1t::EGamma> egammas_raw;
0037
0038 for (const auto& cluster : clusters) {
0039
0040 if (cluster.isValid()) {
0041
0042 int iEta = cluster.hwEta();
0043 int iPhi = cluster.hwPhi();
0044 int iEtaP = caloNav.offsetIEta(iEta, 1);
0045 int iEtaM = caloNav.offsetIEta(iEta, -1);
0046 int iPhiP = caloNav.offsetIPhi(iPhi, 1);
0047 int iPhiP2 = caloNav.offsetIPhi(iPhi, 2);
0048 int iPhiM = caloNav.offsetIPhi(iPhi, -1);
0049 int iPhiM2 = caloNav.offsetIPhi(iPhi, -2);
0050 const l1t::CaloTower& seed = l1t::CaloTools::getTower(towers, iEta, iPhi);
0051 const l1t::CaloTower& towerNW = l1t::CaloTools::getTower(towers, iEtaM, iPhiM);
0052 const l1t::CaloTower& towerN = l1t::CaloTools::getTower(towers, iEta, iPhiM);
0053 const l1t::CaloTower& towerNE = l1t::CaloTools::getTower(towers, iEtaP, iPhiM);
0054 const l1t::CaloTower& towerE = l1t::CaloTools::getTower(towers, iEtaP, iPhi);
0055 const l1t::CaloTower& towerSE = l1t::CaloTools::getTower(towers, iEtaP, iPhiP);
0056 const l1t::CaloTower& towerS = l1t::CaloTools::getTower(towers, iEta, iPhiP);
0057 const l1t::CaloTower& towerSW = l1t::CaloTools::getTower(towers, iEtaM, iPhiP);
0058 const l1t::CaloTower& towerW = l1t::CaloTools::getTower(towers, iEtaM, iPhi);
0059 const l1t::CaloTower& towerNN = l1t::CaloTools::getTower(towers, iEta, iPhiM2);
0060 const l1t::CaloTower& towerSS = l1t::CaloTools::getTower(towers, iEta, iPhiP2);
0061
0062
0063 int seedEt = seed.hwPt();
0064 int towerEtNW = towerNW.hwPt();
0065 int towerEtN = towerN.hwPt();
0066 int towerEtNE = towerNE.hwPt();
0067 int towerEtE = towerE.hwPt();
0068 int towerEtSE = towerSE.hwPt();
0069 int towerEtS = towerS.hwPt();
0070 int towerEtSW = towerSW.hwPt();
0071 int towerEtW = towerW.hwPt();
0072 int towerEtNN = towerNN.hwPt();
0073 int towerEtSS = towerSS.hwPt();
0074
0075 if (abs(iEta) > params_->egEtaCut())
0076 continue;
0077
0078
0079 egammas_raw.push_back(cluster);
0080 l1t::EGamma& egamma = egammas_raw.back();
0081
0082
0083 l1t::CaloCluster clusterTrim = trimCluster(cluster);
0084
0085
0086 egamma.setHwPt(seedEt);
0087 if (clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_NW))
0088 egamma.setHwPt(egamma.hwPt() + towerEtNW);
0089 if (clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_N))
0090 egamma.setHwPt(egamma.hwPt() + towerEtN);
0091 if (clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_NE))
0092 egamma.setHwPt(egamma.hwPt() + towerEtNE);
0093 if (clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_E))
0094 egamma.setHwPt(egamma.hwPt() + towerEtE);
0095 if (clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_SE))
0096 egamma.setHwPt(egamma.hwPt() + towerEtSE);
0097 if (clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_S))
0098 egamma.setHwPt(egamma.hwPt() + towerEtS);
0099 if (clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_SW))
0100 egamma.setHwPt(egamma.hwPt() + towerEtSW);
0101 if (clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_W))
0102 egamma.setHwPt(egamma.hwPt() + towerEtW);
0103 if (clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_NN))
0104 egamma.setHwPt(egamma.hwPt() + towerEtNN);
0105 if (clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_SS))
0106 egamma.setHwPt(egamma.hwPt() + towerEtSS);
0107
0108
0109 bool HoE_ext = idHoverE_ext(seed);
0110 HoE_ext &= idHoverE_ext(towerNW);
0111 HoE_ext &= idHoverE_ext(towerN);
0112 HoE_ext &= idHoverE_ext(towerNE);
0113 HoE_ext &= idHoverE_ext(towerE);
0114 HoE_ext &= idHoverE_ext(towerSE);
0115 HoE_ext &= idHoverE_ext(towerS);
0116 HoE_ext &= idHoverE_ext(towerSW);
0117 HoE_ext &= idHoverE_ext(towerW);
0118
0119 if (cluster.checkClusterFlag(CaloCluster::INCLUDE_NN))
0120 HoE_ext &= idHoverE_ext(towerNN);
0121 if (cluster.checkClusterFlag(CaloCluster::INCLUDE_SS))
0122 HoE_ext &= idHoverE_ext(towerSS);
0123
0124
0125
0126 bool hOverEBit = cluster.hOverE() > 0 || params_->egBypassHoE();
0127 bool hOverEExtBit = HoE_ext || params_->egBypassExtHOverE();
0128 if (!params_->egBypassExtHOverE())
0129 hOverEExtBit = HoE_ext;
0130 bool shapeBit = idShape(cluster, egamma.hwPt()) || params_->egBypassShape();
0131 bool fgBit = !(cluster.fgECAL()) || params_->egBypassECALFG();
0132 int qual = 0;
0133 if (fgBit)
0134 qual |= (0x1);
0135 if (hOverEBit)
0136 qual |= (0x1 << 1);
0137 if (shapeBit)
0138 qual |= (0x1 << 2);
0139 if (hOverEExtBit)
0140 qual |= (0x1 << 3);
0141 egamma.setHwQual(qual);
0142
0143
0144 int isoLeftExtension = params_->egIsoAreaNrTowersEta();
0145 int isoRightExtension = params_->egIsoAreaNrTowersEta();
0146
0147 if (cluster.checkClusterFlag(CaloCluster::TRIM_LEFT))
0148 isoRightExtension++;
0149 else
0150 isoLeftExtension++;
0151
0152 int hwEtSum = CaloTools::calHwEtSum(cluster.hwEta(),
0153 cluster.hwPhi(),
0154 towers,
0155 -isoLeftExtension,
0156 isoRightExtension,
0157 -1 * params_->egIsoAreaNrTowersPhi(),
0158 params_->egIsoAreaNrTowersPhi(),
0159 params_->egPUSParam(2));
0160
0161 int hwFootPrint = isoCalEgHwFootPrint(cluster, towers);
0162 int nrTowers = CaloTools::calNrTowers(-1 * params_->egPUSParam(1),
0163 params_->egPUSParam(1),
0164 1,
0165 72,
0166 towers,
0167 1 + params_->pileUpTowerThreshold(),
0168 999,
0169 CaloTools::CALO);
0170 unsigned int lutAddress = isoLutIndex(egamma.hwEta(), nrTowers, egamma.hwPt());
0171
0172 int isolBit = (((hwEtSum - hwFootPrint) < params_->egIsolationLUT()->data(lutAddress)) ||
0173 (params_->egIsolationLUT()->data(lutAddress) > 255));
0174 int isolBit2 = (((hwEtSum - hwFootPrint) < params_->egIsolationLUT2()->data(lutAddress)) ||
0175 (params_->egIsolationLUT2()->data(lutAddress) > 255));
0176 isolBit += (isolBit2 << 1);
0177 egamma.setHwIso(isolBit);
0178 int hwIsoEnergy = hwEtSum - hwFootPrint;
0179
0180
0181 egamma.setTowerIPhi((short int)cluster.hwPhi());
0182 egamma.setTowerIEta((short int)cluster.hwEta());
0183 egamma.setRawEt((short int)egamma.hwPt());
0184 egamma.setIsoEt((short int)hwIsoEnergy);
0185 egamma.setFootprintEt((short int)hwFootPrint);
0186 egamma.setNTT((short int)nrTowers);
0187 egamma.setShape((short int)returnShape(cluster));
0188 egamma.setTowerHoE((short int)returnHoE(seed));
0189
0190
0191
0192 int calibPt = calibratedPt(cluster, egamma.hwPt());
0193 egamma.setHwPt(calibPt);
0194
0195
0196 double eta = 0.;
0197 double phi = 0.;
0198 double seedEta = CaloTools::towerEta(cluster.hwEta());
0199 double seedEtaSize = CaloTools::towerEtaSize(cluster.hwEta());
0200 double seedPhi = CaloTools::towerPhi(cluster.hwEta(), cluster.hwPhi());
0201 double seedPhiSize = CaloTools::towerPhiSize(cluster.hwEta());
0202 if (cluster.fgEta() == 0)
0203 eta = seedEta;
0204
0205 else if (cluster.fgEta() == 2)
0206 eta = seedEta + seedEtaSize * 0.251;
0207 else if (cluster.fgEta() == 1)
0208 eta = seedEta - seedEtaSize * 0.251;
0209
0210
0211 int fgPhi = 0;
0212
0213 int EtUp = 0;
0214 if (clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_NE))
0215 EtUp += towerEtNE;
0216 if (clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_N))
0217 EtUp += towerEtN;
0218 if (clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_NW))
0219 EtUp += towerEtNW;
0220 if (clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_NN))
0221 EtUp += towerEtNN;
0222 int EtDown = 0;
0223 if (clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_SE))
0224 EtDown += towerEtSE;
0225 if (clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_S))
0226 EtDown += towerEtS;
0227 if (clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_SW))
0228 EtDown += towerEtSW;
0229 if (clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_SS))
0230 EtDown += towerEtSS;
0231
0232 if (EtDown > EtUp)
0233 fgPhi = 2;
0234 else if (EtUp > EtDown)
0235 fgPhi = 1;
0236
0237 if (fgPhi == 0)
0238 phi = seedPhi;
0239 else if (fgPhi == 2)
0240 phi = seedPhi + seedPhiSize * 0.251;
0241 else if (fgPhi == 1)
0242 phi = seedPhi - seedPhiSize * 0.251;
0243
0244
0245 math::PtEtaPhiMLorentzVector calibP4((double)calibPt * params_->egLsb(), eta, phi, 0.);
0246 egamma.setP4(calibP4);
0247
0248 }
0249 }
0250
0251
0252 math::PtEtaPhiMLorentzVector emptyP4;
0253 l1t::EGamma tempEG(emptyP4, 0, 0, 0, 0);
0254 std::vector<std::vector<l1t::EGamma> > egEtaPos(params_->egEtaCut(), std::vector<l1t::EGamma>(18, tempEG));
0255 std::vector<std::vector<l1t::EGamma> > egEtaNeg(params_->egEtaCut(), std::vector<l1t::EGamma>(18, tempEG));
0256 for (unsigned int iEG = 0; iEG < egammas_raw.size(); iEG++) {
0257 int fgBit = egammas_raw.at(iEG).hwQual() & (0x1);
0258 int hOverEBit = egammas_raw.at(iEG).hwQual() >> 1 & (0x1);
0259 int shapeBit = egammas_raw.at(iEG).hwQual() >> 2 & (0x1);
0260 int hOverEExtBit = egammas_raw.at(iEG).hwQual() >> 3 & (0x1);
0261
0262 bool IDcuts = (fgBit && hOverEBit && shapeBit && hOverEExtBit) ||
0263 (egammas_raw.at(iEG).pt() >= params_->egMaxPtHOverE()) || (params_->egBypassEGVetos());
0264
0265 if (!IDcuts)
0266 continue;
0267 egammas_raw.at(iEG).setHwQual(7);
0268
0269 if (egammas_raw.at(iEG).hwEta() > 0)
0270 egEtaPos.at(egammas_raw.at(iEG).hwEta() - 1).at((72 - egammas_raw.at(iEG).hwPhi()) / 4) = egammas_raw.at(iEG);
0271 else
0272 egEtaNeg.at(-(egammas_raw.at(iEG).hwEta() + 1)).at((72 - egammas_raw.at(iEG).hwPhi()) / 4) = egammas_raw.at(iEG);
0273 }
0274
0275 AccumulatingSort<l1t::EGamma> etaPosSorter(6);
0276 AccumulatingSort<l1t::EGamma> etaNegSorter(6);
0277 std::vector<l1t::EGamma> accumEtaPos;
0278 std::vector<l1t::EGamma> accumEtaNeg;
0279
0280 for (int ieta = 0; ieta < params_->egEtaCut(); ++ieta) {
0281
0282 std::vector<l1t::EGamma>::iterator start_, end_;
0283 start_ = egEtaPos.at(ieta).begin();
0284 end_ = egEtaPos.at(ieta).end();
0285 BitonicSort<l1t::EGamma>(down, start_, end_);
0286 etaPosSorter.Merge(egEtaPos.at(ieta), accumEtaPos);
0287
0288
0289 start_ = egEtaNeg.at(ieta).begin();
0290 end_ = egEtaNeg.at(ieta).end();
0291 BitonicSort<l1t::EGamma>(down, start_, end_);
0292 etaNegSorter.Merge(egEtaNeg.at(ieta), accumEtaNeg);
0293 }
0294
0295
0296 egammas.clear();
0297 for (const l1t::EGamma& acceg : accumEtaPos) {
0298 if (acceg.hwPt() > 0)
0299 egammas.push_back(acceg);
0300 }
0301 for (const l1t::EGamma& acceg : accumEtaNeg) {
0302 if (acceg.hwPt() > 0)
0303 egammas.push_back(acceg);
0304 }
0305 }
0306
0307
0308 bool l1t::Stage2Layer2EGammaAlgorithmFirmwareImp1::idShape(const l1t::CaloCluster& clus, int hwPt)
0309
0310 {
0311 unsigned int shape = 0;
0312 if ((clus.checkClusterFlag(CaloCluster::INCLUDE_N)))
0313 shape |= (0x1);
0314 if ((clus.checkClusterFlag(CaloCluster::INCLUDE_S)))
0315 shape |= (0x1 << 1);
0316 if (clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_E)))
0317 shape |= (0x1 << 2);
0318 if (!clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_W)))
0319 shape |= (0x1 << 2);
0320 if (clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_NE)))
0321 shape |= (0x1 << 3);
0322 if (!clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_NW)))
0323 shape |= (0x1 << 3);
0324 if (clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_SE)))
0325 shape |= (0x1 << 4);
0326 if (!clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_SW)))
0327 shape |= (0x1 << 4);
0328 if (clus.checkClusterFlag(CaloCluster::INCLUDE_NN))
0329 shape |= (0x1 << 5);
0330 if (clus.checkClusterFlag(CaloCluster::INCLUDE_SS))
0331 shape |= (0x1 << 6);
0332
0333 unsigned int lutAddress = idShapeLutIndex(clus.hwEta(), hwPt, shape);
0334 bool shapeBit = ((params_->egCalibrationLUT()->data(lutAddress)) >> 9) & 0x1;
0335
0336 return shapeBit;
0337 }
0338
0339
0340 unsigned int l1t::Stage2Layer2EGammaAlgorithmFirmwareImp1::idShapeLutIndex(int iEta, int E, int shape)
0341
0342 {
0343 if (params_->egShapeIdType() == "compressed") {
0344 unsigned int iEtaNormed = abs(iEta);
0345 if (iEtaNormed > 28)
0346 iEtaNormed = 28;
0347 if (E > 255)
0348 E = 255;
0349 unsigned int compressedShape = params_->egCompressShapesLUT()->data(shape);
0350 unsigned int compressedE = params_->egCompressShapesLUT()->data((0x1 << 7) + E);
0351 unsigned int compressedEta = params_->egCompressShapesLUT()->data((0x1 << 7) + (0x1 << 8) + iEtaNormed);
0352 return (compressedShape | compressedE | compressedEta);
0353 } else
0354 {
0355 unsigned int iEtaNormed = abs(iEta);
0356 if (iEtaNormed > 28)
0357 iEtaNormed = 28;
0358 if (E > 255)
0359 E = 255;
0360 unsigned int compressedShape = params_->egCompressShapesLUT()->data(shape);
0361 return E + compressedShape * 256 + (iEtaNormed - 1) * 256 * 64;
0362 }
0363 }
0364
0365
0366
0367 int l1t::Stage2Layer2EGammaAlgorithmFirmwareImp1::isoCalEgHwFootPrint(const l1t::CaloCluster& clus,
0368 const std::vector<l1t::CaloTower>& towers)
0369
0370 {
0371 int iEta = clus.hwEta();
0372 int iPhi = clus.hwPhi();
0373
0374
0375
0376
0377 int etaSide =
0378 clus.checkClusterFlag(CaloCluster::TRIM_LEFT) ? 1 : -1;
0379 int phiSide = iEta > 0 ? 1 : -1;
0380
0381 int ecalHwFootPrint = CaloTools::calHwEtSum(iEta,
0382 iPhi,
0383 towers,
0384 0,
0385 0,
0386 -1 * params_->egIsoVetoNrTowersPhi(),
0387 params_->egIsoVetoNrTowersPhi(),
0388 params_->egPUSParam(2),
0389 CaloTools::ECAL) +
0390 CaloTools::calHwEtSum(iEta,
0391 iPhi,
0392 towers,
0393 etaSide,
0394 etaSide,
0395 -1 * params_->egIsoVetoNrTowersPhi(),
0396 params_->egIsoVetoNrTowersPhi(),
0397 params_->egPUSParam(2),
0398 CaloTools::ECAL);
0399
0400
0401 int ecalHwFootPrint_2x1 =
0402 CaloTools::calHwEtSum(iEta, iPhi, towers, 0, 0, 0, 0, params_->egPUSParam(2), CaloTools::ECAL) +
0403 CaloTools::calHwEtSum(iEta, iPhi, towers, 0, 0, phiSide, phiSide, params_->egPUSParam(2), CaloTools::ECAL);
0404
0405 int ecalhcal_HwFootPrint_2x1 =
0406 CaloTools::calHwEtSum(iEta, iPhi, towers, 0, 0, 0, 0, params_->egPUSParam(2)) +
0407 CaloTools::calHwEtSum(iEta, iPhi, towers, 0, 0, phiSide, phiSide, params_->egPUSParam(2));
0408
0409 return ecalHwFootPrint - ecalHwFootPrint_2x1 + ecalhcal_HwFootPrint_2x1;
0410 }
0411
0412
0413
0414 unsigned l1t::Stage2Layer2EGammaAlgorithmFirmwareImp1::isoLutIndex(int iEta, unsigned int nrTowers, int E)
0415
0416 {
0417 if (params_->egIsolationType() == "compressed") {
0418 if (nrTowers > 255)
0419 nrTowers = 255;
0420 unsigned int iEtaNormed = abs(iEta);
0421 if (iEtaNormed > 28)
0422 iEtaNormed = 28;
0423 if (E > 255)
0424 E = 255;
0425 unsigned int compressednTT = params_->egCompressShapesLUT()->data((0x1 << 7) + (0x1 << 8) + (0x1 << 5) + nrTowers);
0426 unsigned int compressedE = params_->egCompressShapesLUT()->data((0x1 << 7) + E) << 1;
0427 unsigned int compressedEta = params_->egCompressShapesLUT()->data((0x1 << 7) + (0x1 << 8) + iEtaNormed) << 1;
0428
0429 return (compressednTT | compressedE | compressedEta);
0430 }
0431
0432 else
0433 {
0434 const unsigned int kNrTowersInSum = 72 * params_->egPUSParam(1) * 2;
0435 const unsigned int kTowerGranularity = params_->egPUSParam(0);
0436 const unsigned int kMaxAddress = kNrTowersInSum % kTowerGranularity == 0
0437 ? (kNrTowersInSum / kTowerGranularity + 1) * 28 * 2
0438 : (kNrTowersInSum / kTowerGranularity) * 28 * 2;
0439
0440 unsigned int nrTowersNormed = nrTowers / kTowerGranularity;
0441
0442 unsigned int iEtaNormed = iEta + 28;
0443 if (iEta > 0)
0444 iEtaNormed--;
0445
0446 if (std::abs(iEta) > 28 || iEta == 0 || nrTowers > kNrTowersInSum)
0447 return kMaxAddress;
0448 else
0449 return iEtaNormed * (kNrTowersInSum / kTowerGranularity + 1) + nrTowersNormed;
0450 }
0451 }
0452
0453
0454 int l1t::Stage2Layer2EGammaAlgorithmFirmwareImp1::calibratedPt(const l1t::CaloCluster& clus, int hwPt)
0455
0456 {
0457 unsigned int shape = 0;
0458 if ((clus.checkClusterFlag(CaloCluster::INCLUDE_N)))
0459 shape |= (0x1);
0460 if ((clus.checkClusterFlag(CaloCluster::INCLUDE_S)))
0461 shape |= (0x1 << 1);
0462 if (clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_E)))
0463 shape |= (0x1 << 2);
0464 if (!clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_W)))
0465 shape |= (0x1 << 2);
0466 if (clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_NE)))
0467 shape |= (0x1 << 3);
0468 if (!clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_NW)))
0469 shape |= (0x1 << 3);
0470 if (clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_SE)))
0471 shape |= (0x1 << 4);
0472 if (!clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_SW)))
0473 shape |= (0x1 << 4);
0474 if (clus.checkClusterFlag(CaloCluster::INCLUDE_NN))
0475 shape |= (0x1 << 5);
0476 if (clus.checkClusterFlag(CaloCluster::INCLUDE_SS))
0477 shape |= (0x1 << 6);
0478
0479 unsigned int lutAddress = calibrationLutIndex(clus.hwEta(), hwPt, shape);
0480 int corr = params_->egCalibrationLUT()->data(lutAddress) & (0x1ff);
0481
0482 int rawPt = hwPt;
0483 int corrXrawPt = corr * rawPt;
0484
0485 int corrPt = corrXrawPt >> 8;
0486
0487
0488 if (corrPt > 4095)
0489 corrPt = 4095;
0490
0491 return corrPt;
0492 }
0493
0494
0495 unsigned int l1t::Stage2Layer2EGammaAlgorithmFirmwareImp1::calibrationLutIndex(int iEta, int E, int shape)
0496
0497 {
0498 if (params_->egCalibrationType() == "compressed") {
0499 unsigned int iEtaNormed = abs(iEta);
0500 if (iEtaNormed > 28)
0501 iEtaNormed = 28;
0502 if (E > 255)
0503 E = 255;
0504 unsigned int compressedShape = params_->egCompressShapesLUT()->data(shape);
0505 unsigned int compressedE = params_->egCompressShapesLUT()->data((0x1 << 7) + E);
0506 unsigned int compressedEta = params_->egCompressShapesLUT()->data((0x1 << 7) + (0x1 << 8) + iEtaNormed);
0507 return (compressedShape | compressedE | compressedEta);
0508 } else
0509 {
0510 unsigned int iEtaNormed = abs(iEta);
0511 if (iEtaNormed > 28)
0512 iEtaNormed = 28;
0513 if (E > 255)
0514 E = 255;
0515 if (E < 22)
0516 E = 22;
0517 unsigned int compressedShape = params_->egCompressShapesLUT()->data(shape);
0518 if (compressedShape > 31)
0519 compressedShape = 31;
0520 return (E - 20) + compressedShape * 236 + (iEtaNormed - 1) * 236 * 32;
0521 }
0522 }
0523
0524
0525 l1t::CaloCluster l1t::Stage2Layer2EGammaAlgorithmFirmwareImp1::trimCluster(const l1t::CaloCluster& clus)
0526
0527 {
0528 l1t::CaloCluster clusCopy = clus;
0529
0530 unsigned int shape = 0;
0531 if ((clus.checkClusterFlag(CaloCluster::INCLUDE_N)))
0532 shape |= (0x1);
0533 if ((clus.checkClusterFlag(CaloCluster::INCLUDE_S)))
0534 shape |= (0x1 << 1);
0535 if (clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_E)))
0536 shape |= (0x1 << 2);
0537 if (!clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_W)))
0538 shape |= (0x1 << 2);
0539 if (clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_NE)))
0540 shape |= (0x1 << 3);
0541 if (!clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_NW)))
0542 shape |= (0x1 << 3);
0543 if (clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_SE)))
0544 shape |= (0x1 << 4);
0545 if (!clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_SW)))
0546 shape |= (0x1 << 4);
0547 if (clus.checkClusterFlag(CaloCluster::INCLUDE_NN))
0548 shape |= (0x1 << 5);
0549 if (clus.checkClusterFlag(CaloCluster::INCLUDE_SS))
0550 shape |= (0x1 << 6);
0551
0552 unsigned int lutAddress = trimmingLutIndex(shape, clus.hwEta());
0553 unsigned int shapeTrim = params_->egTrimmingLUT()->data(lutAddress);
0554
0555 clusCopy.setClusterFlag(CaloCluster::INCLUDE_N, (shapeTrim & (0x1)) ? true : false);
0556 clusCopy.setClusterFlag(CaloCluster::INCLUDE_S, (shapeTrim & (0x1 << 1)) ? true : false);
0557 clusCopy.setClusterFlag(CaloCluster::INCLUDE_NN, (shapeTrim & (0x1 << 5)) ? true : false);
0558 clusCopy.setClusterFlag(CaloCluster::INCLUDE_SS, (shapeTrim & (0x1 << 6)) ? true : false);
0559 if (clusCopy.checkClusterFlag(CaloCluster::TRIM_LEFT)) {
0560 clusCopy.setClusterFlag(CaloCluster::INCLUDE_E, (shapeTrim & (0x1 << 2)) ? true : false);
0561 clusCopy.setClusterFlag(CaloCluster::INCLUDE_NE, (shapeTrim & (0x1 << 3)) ? true : false);
0562 clusCopy.setClusterFlag(CaloCluster::INCLUDE_SE, (shapeTrim & (0x1 << 4)) ? true : false);
0563 } else {
0564 clusCopy.setClusterFlag(CaloCluster::INCLUDE_W, (shapeTrim & (0x1 << 2)) ? true : false);
0565 clusCopy.setClusterFlag(CaloCluster::INCLUDE_NW, (shapeTrim & (0x1 << 3)) ? true : false);
0566 clusCopy.setClusterFlag(CaloCluster::INCLUDE_SW, (shapeTrim & (0x1 << 4)) ? true : false);
0567 }
0568 return clusCopy;
0569 }
0570
0571
0572 unsigned int l1t::Stage2Layer2EGammaAlgorithmFirmwareImp1::trimmingLutIndex(unsigned int shape, int iEta)
0573
0574 {
0575 unsigned int iEtaNormed = abs(iEta) - 1;
0576 if (iEtaNormed > 31)
0577 iEtaNormed = 31;
0578 if (shape > 127)
0579 shape = 127;
0580 unsigned int index = iEtaNormed * 128 + shape;
0581 return index;
0582 }
0583
0584
0585 unsigned int l1t::Stage2Layer2EGammaAlgorithmFirmwareImp1::returnShape(const l1t::CaloCluster& clus)
0586
0587 {
0588 unsigned int shape = 0;
0589 if ((clus.checkClusterFlag(CaloCluster::INCLUDE_N)))
0590 shape |= (0x1);
0591 if ((clus.checkClusterFlag(CaloCluster::INCLUDE_S)))
0592 shape |= (0x1 << 1);
0593 if (clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_E)))
0594 shape |= (0x1 << 2);
0595 if (!clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_W)))
0596 shape |= (0x1 << 2);
0597 if (clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_NE)))
0598 shape |= (0x1 << 3);
0599 if (!clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_NW)))
0600 shape |= (0x1 << 3);
0601 if (clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_SE)))
0602 shape |= (0x1 << 4);
0603 if (!clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_SW)))
0604 shape |= (0x1 << 4);
0605 if (clus.checkClusterFlag(CaloCluster::INCLUDE_NN))
0606 shape |= (0x1 << 5);
0607 if (clus.checkClusterFlag(CaloCluster::INCLUDE_SS))
0608 shape |= (0x1 << 6);
0609
0610 return shape;
0611 }
0612
0613
0614 int l1t::Stage2Layer2EGammaAlgorithmFirmwareImp1::returnHoE(const l1t::CaloTower& tow)
0615
0616 {
0617 int ratio = tow.hwEtRatio();
0618 int qual = tow.hwQual();
0619 bool denomZeroFlag = ((qual & 0x1) > 0);
0620 bool eOverHFlag = ((qual & 0x2) > 0);
0621
0622 if (denomZeroFlag && !eOverHFlag)
0623 ratio = -1;
0624 if (denomZeroFlag && eOverHFlag)
0625 ratio = 8;
0626 if (!denomZeroFlag && !eOverHFlag)
0627 ratio = -1;
0628
0629
0630 return ratio;
0631 }
0632
0633 bool l1t::Stage2Layer2EGammaAlgorithmFirmwareImp1::idHoverE_ext(const l1t::CaloTower tow) {
0634 int qual = tow.hwQual();
0635 bool eOverHFlag = ((qual & 0x2) > 0);
0636
0637 if (tow.hwPt() <= 10)
0638 return true;
0639 else
0640 return eOverHFlag;
0641 }