Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:20:24

0001 ///
0002 /// \class l1t::Stage2Layer2ClusterAlgorithmFirmwareImp1
0003 ///
0004 /// \author: Jim Brooke
0005 ///
0006 /// Description: first iteration of stage 2 jet algo
0007 
0008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0009 #include "L1Trigger/L1TCalorimeter/interface/Stage2Layer2ClusterAlgorithmFirmware.h"
0010 //#include "DataFormats/Math/interface/LorentzVector.h "
0011 
0012 #include "L1Trigger/L1TCalorimeter/interface/CaloTools.h"
0013 #include "L1Trigger/L1TCalorimeter/interface/CaloStage2Nav.h"
0014 
0015 #include "L1Trigger/L1TCalorimeter/interface/CaloParamsHelper.h"
0016 
0017 /*****************************************************************/
0018 l1t::Stage2Layer2ClusterAlgorithmFirmwareImp1::Stage2Layer2ClusterAlgorithmFirmwareImp1(CaloParamsHelper const* params,
0019                                                                                         ClusterInput clusterInput)
0020     : clusterInput_(clusterInput),
0021       seedThreshold_(1),
0022       clusterThreshold_(1),
0023       hcalThreshold_(1),
0024       params_(params)
0025 /*****************************************************************/
0026 {}
0027 
0028 /*****************************************************************/
0029 l1t::Stage2Layer2ClusterAlgorithmFirmwareImp1::~Stage2Layer2ClusterAlgorithmFirmwareImp1()
0030 /*****************************************************************/
0031 {}
0032 
0033 /*****************************************************************/
0034 void l1t::Stage2Layer2ClusterAlgorithmFirmwareImp1::processEvent(const std::vector<l1t::CaloTower>& towers,
0035                                                                  std::vector<l1t::CaloCluster>& clusters)
0036 /*****************************************************************/
0037 {
0038   if (clusterInput_ == E) {
0039     seedThreshold_ = floor(params_->egSeedThreshold() / params_->towerLsbE());
0040     clusterThreshold_ = floor(params_->egNeighbourThreshold() / params_->towerLsbE());
0041   } else if (clusterInput_ == EH) {
0042     seedThreshold_ = floor(params_->egSeedThreshold() / params_->towerLsbSum());
0043     clusterThreshold_ = floor(params_->egNeighbourThreshold() / params_->towerLsbSum());
0044   }
0045   if (clusterInput_ == H) {
0046     seedThreshold_ = floor(params_->egSeedThreshold() / params_->towerLsbH());
0047     clusterThreshold_ = floor(params_->egNeighbourThreshold() / params_->towerLsbH());
0048   }
0049 
0050   hcalThreshold_ = floor(params_->egHcalThreshold() / params_->towerLsbH());
0051 
0052   clustering(towers, clusters);
0053   filtering(towers, clusters);
0054   //No sharing in new implementation
0055   //sharing   (towers, clusters);
0056   refining(towers, clusters);
0057 }
0058 
0059 /*****************************************************************/
0060 void l1t::Stage2Layer2ClusterAlgorithmFirmwareImp1::clustering(const std::vector<l1t::CaloTower>& towers,
0061                                                                std::vector<l1t::CaloCluster>& clusters)
0062 /*****************************************************************/
0063 {
0064   // navigator
0065   l1t::CaloStage2Nav caloNav;
0066 
0067   // Build clusters passing seed threshold
0068   for (const auto& tower : towers) {
0069     int iEta = tower.hwEta();
0070     int iPhi = tower.hwPhi();
0071     int hwEt = 0;
0072     if (clusterInput_ == E)
0073       hwEt = tower.hwEtEm();
0074     else if (clusterInput_ == EH)
0075       hwEt = tower.hwPt();
0076     else if (clusterInput_ == H)
0077       hwEt = tower.hwEtHad();
0078     int hwEtEm = tower.hwEtEm();
0079     int hwEtHad = tower.hwEtHad();
0080     // Check if the seed tower pass the seed threshold
0081     if (hwEt >= seedThreshold_) {
0082       math::XYZTLorentzVector emptyP4;
0083       clusters.push_back(l1t::CaloCluster(emptyP4, hwEt, iEta, iPhi));
0084       l1t::CaloCluster& cluster = clusters.back();
0085       cluster.setHwPtEm(hwEtEm);
0086       cluster.setHwPtHad(hwEtHad);
0087       cluster.setHwSeedPt(hwEt);
0088 
0089       bool hOverE = idHoverE(tower);
0090       cluster.setHOverE(hOverE);
0091       // FG of the cluster is FG of the seed
0092       bool fg = (tower.hwQual() & (0x1 << 3));
0093       cluster.setFgECAL((int)fg);
0094     }
0095   }
0096 
0097   // check if neighbour towers are below clustering threshold
0098   for (auto& cluster : clusters) {
0099     if (cluster.isValid()) {
0100       // look at the energies in neighbour towers
0101       int iEta = cluster.hwEta();
0102       int iPhi = cluster.hwPhi();
0103       int iEtaP = caloNav.offsetIEta(iEta, 1);
0104       int iEtaM = caloNav.offsetIEta(iEta, -1);
0105       int iPhiP = caloNav.offsetIPhi(iPhi, 1);
0106       int iPhiP2 = caloNav.offsetIPhi(iPhi, 2);
0107       int iPhiM = caloNav.offsetIPhi(iPhi, -1);
0108       int iPhiM2 = caloNav.offsetIPhi(iPhi, -2);
0109       const l1t::CaloTower& towerNW = l1t::CaloTools::getTower(towers, iEtaM, iPhiM);
0110       const l1t::CaloTower& towerN = l1t::CaloTools::getTower(towers, iEta, iPhiM);
0111       const l1t::CaloTower& towerNE = l1t::CaloTools::getTower(towers, iEtaP, iPhiM);
0112       const l1t::CaloTower& towerE = l1t::CaloTools::getTower(towers, iEtaP, iPhi);
0113       const l1t::CaloTower& towerSE = l1t::CaloTools::getTower(towers, iEtaP, iPhiP);
0114       const l1t::CaloTower& towerS = l1t::CaloTools::getTower(towers, iEta, iPhiP);
0115       const l1t::CaloTower& towerSW = l1t::CaloTools::getTower(towers, iEtaM, iPhiP);
0116       const l1t::CaloTower& towerW = l1t::CaloTools::getTower(towers, iEtaM, iPhi);
0117       const l1t::CaloTower& towerNN = l1t::CaloTools::getTower(towers, iEta, iPhiM2);
0118       const l1t::CaloTower& towerSS = l1t::CaloTools::getTower(towers, iEta, iPhiP2);
0119       int towerEtNW = 0;
0120       int towerEtN = 0;
0121       int towerEtNE = 0;
0122       int towerEtE = 0;
0123       int towerEtSE = 0;
0124       int towerEtS = 0;
0125       int towerEtSW = 0;
0126       int towerEtW = 0;
0127       int towerEtNN = 0;
0128       int towerEtSS = 0;
0129       if (clusterInput_ == E) {
0130         towerEtNW = towerNW.hwEtEm();
0131         towerEtN = towerN.hwEtEm();
0132         towerEtNE = towerNE.hwEtEm();
0133         towerEtE = towerE.hwEtEm();
0134         towerEtSE = towerSE.hwEtEm();
0135         towerEtS = towerS.hwEtEm();
0136         towerEtSW = towerSW.hwEtEm();
0137         towerEtW = towerW.hwEtEm();
0138         towerEtNN = towerNN.hwEtEm();
0139         towerEtSS = towerSS.hwEtEm();
0140       } else if (clusterInput_ == EH) {
0141         towerEtNW = towerNW.hwPt();
0142         towerEtN = towerN.hwPt();
0143         towerEtNE = towerNE.hwPt();
0144         towerEtE = towerE.hwPt();
0145         towerEtSE = towerSE.hwPt();
0146         towerEtS = towerS.hwPt();
0147         towerEtSW = towerSW.hwPt();
0148         towerEtW = towerW.hwPt();
0149         towerEtNN = towerNN.hwPt();
0150         towerEtSS = towerSS.hwPt();
0151       } else if (clusterInput_ == H) {
0152         towerEtNW = towerNW.hwEtHad();
0153         towerEtN = towerN.hwEtHad();
0154         towerEtNE = towerNE.hwEtHad();
0155         towerEtE = towerE.hwEtHad();
0156         towerEtSE = towerSE.hwEtHad();
0157         towerEtS = towerS.hwEtHad();
0158         towerEtSW = towerSW.hwEtHad();
0159         towerEtW = towerW.hwEtHad();
0160         towerEtNN = towerNN.hwEtHad();
0161         towerEtSS = towerSS.hwEtHad();
0162       }
0163 
0164       // check which towers can be clustered to the seed
0165       if (towerEtNW < clusterThreshold_)
0166         cluster.setClusterFlag(CaloCluster::INCLUDE_NW, false);
0167       if (towerEtN < clusterThreshold_) {
0168         cluster.setClusterFlag(CaloCluster::INCLUDE_N, false);
0169         cluster.setClusterFlag(CaloCluster::INCLUDE_NN, false);
0170       }
0171       if (towerEtNE < clusterThreshold_)
0172         cluster.setClusterFlag(CaloCluster::INCLUDE_NE, false);
0173       if (towerEtE < clusterThreshold_)
0174         cluster.setClusterFlag(CaloCluster::INCLUDE_E, false);
0175       if (towerEtSE < clusterThreshold_)
0176         cluster.setClusterFlag(CaloCluster::INCLUDE_SE, false);
0177       if (towerEtS < clusterThreshold_) {
0178         cluster.setClusterFlag(CaloCluster::INCLUDE_S, false);
0179         cluster.setClusterFlag(CaloCluster::INCLUDE_SS, false);
0180       }
0181       if (towerEtSW < clusterThreshold_)
0182         cluster.setClusterFlag(CaloCluster::INCLUDE_SW, false);
0183       if (towerEtW < clusterThreshold_)
0184         cluster.setClusterFlag(CaloCluster::INCLUDE_W, false);
0185       if (towerEtNN < clusterThreshold_)
0186         cluster.setClusterFlag(CaloCluster::INCLUDE_NN, false);
0187       if (towerEtSS < clusterThreshold_)
0188         cluster.setClusterFlag(CaloCluster::INCLUDE_SS, false);
0189     }
0190   }
0191 }
0192 
0193 /*****************************************************************/
0194 void l1t::Stage2Layer2ClusterAlgorithmFirmwareImp1::filtering(const std::vector<l1t::CaloTower>& towers,
0195                                                               std::vector<l1t::CaloCluster>& clusters)
0196 /*****************************************************************/
0197 {
0198   // adapted from jet overlap filtering
0199 
0200   constexpr int mask[9][3] = {
0201       {2, 2, 2},
0202       {2, 2, 2},
0203       {2, 2, 2},
0204       {1, 2, 2},
0205       {1, 0, 2},
0206       {1, 1, 2},
0207       {1, 1, 1},
0208       {1, 1, 1},
0209       {1, 1, 1},
0210   };
0211 
0212   // navigator
0213   l1t::CaloStage2Nav caloNav;
0214 
0215   // Filter: keep only local maxima in a 9x3 region
0216   // If two neighbor seeds have the same energy, favor the most central one
0217   for (auto& cluster : clusters) {
0218     // retrieve neighbour cluster candidates. At this stage they only contain the seed tower.
0219     int iEta = cluster.hwEta();
0220     int iPhi = cluster.hwPhi();
0221     bool filter = false;
0222     for (int deta = -1; deta < 2; ++deta) {
0223       for (int dphi = -4; dphi < 5; ++dphi) {
0224         int iEtaNeigh = caloNav.offsetIEta(iEta, deta);
0225         int iPhiNeigh = caloNav.offsetIPhi(iPhi, dphi);
0226         const l1t::CaloCluster& clusterNeigh = l1t::CaloTools::getCluster(clusters, iEtaNeigh, iPhiNeigh);
0227 
0228         if (mask[8 - (dphi + 4)][deta + 1] == 0)
0229           continue;
0230         else if (mask[8 - (dphi + 4)][deta + 1] == 1)
0231           filter = (clusterNeigh.hwPt() > cluster.hwPt());
0232         else if (mask[8 - (dphi + 4)][deta + 1] == 2)
0233           filter = (clusterNeigh.hwPt() >= cluster.hwPt());
0234         if (filter) {
0235           cluster.setClusterFlag(CaloCluster::INCLUDE_SEED, false);
0236           break;
0237         }
0238       }
0239       if (filter)
0240         break;
0241     }
0242   }
0243 }
0244 
0245 /*****************************************************************/
0246 void l1t::Stage2Layer2ClusterAlgorithmFirmwareImp1::refining(const std::vector<l1t::CaloTower>& towers,
0247                                                              std::vector<l1t::CaloCluster>& clusters)
0248 /*****************************************************************/
0249 {
0250   // navigator
0251   l1t::CaloStage2Nav caloNav;
0252 
0253   // trim cluster
0254   for (auto& cluster : clusters) {
0255     if (cluster.isValid()) {
0256       int iEta = cluster.hwEta();
0257       int iPhi = cluster.hwPhi();
0258       int iEtaP = caloNav.offsetIEta(iEta, 1);
0259       int iEtaM = caloNav.offsetIEta(iEta, -1);
0260       int iPhiP = caloNav.offsetIPhi(iPhi, 1);
0261       int iPhiP2 = caloNav.offsetIPhi(iPhi, 2);
0262       int iPhiM = caloNav.offsetIPhi(iPhi, -1);
0263       int iPhiM2 = caloNav.offsetIPhi(iPhi, -2);
0264       const l1t::CaloTower& towerNW = l1t::CaloTools::getTower(towers, iEtaM, iPhiM);
0265       const l1t::CaloTower& towerN = l1t::CaloTools::getTower(towers, iEta, iPhiM);
0266       const l1t::CaloTower& towerNE = l1t::CaloTools::getTower(towers, iEtaP, iPhiM);
0267       const l1t::CaloTower& towerE = l1t::CaloTools::getTower(towers, iEtaP, iPhi);
0268       const l1t::CaloTower& towerSE = l1t::CaloTools::getTower(towers, iEtaP, iPhiP);
0269       const l1t::CaloTower& towerS = l1t::CaloTools::getTower(towers, iEta, iPhiP);
0270       const l1t::CaloTower& towerSW = l1t::CaloTools::getTower(towers, iEtaM, iPhiP);
0271       const l1t::CaloTower& towerW = l1t::CaloTools::getTower(towers, iEtaM, iPhi);
0272       const l1t::CaloTower& towerNN = l1t::CaloTools::getTower(towers, iEta, iPhiM2);
0273       const l1t::CaloTower& towerSS = l1t::CaloTools::getTower(towers, iEta, iPhiP2);
0274 
0275       int towerEtNW = 0;
0276       int towerEtN = 0;
0277       int towerEtNE = 0;
0278       int towerEtE = 0;
0279       int towerEtSE = 0;
0280       int towerEtS = 0;
0281       int towerEtSW = 0;
0282       int towerEtW = 0;
0283       int towerEtNN = 0;
0284       int towerEtSS = 0;
0285       if (clusterInput_ == E) {
0286         towerEtNW = towerNW.hwEtEm();
0287         towerEtN = towerN.hwEtEm();
0288         towerEtNE = towerNE.hwEtEm();
0289         towerEtE = towerE.hwEtEm();
0290         towerEtSE = towerSE.hwEtEm();
0291         towerEtS = towerS.hwEtEm();
0292         towerEtSW = towerSW.hwEtEm();
0293         towerEtW = towerW.hwEtEm();
0294         towerEtNN = towerNN.hwEtEm();
0295         towerEtSS = towerSS.hwEtEm();
0296       } else if (clusterInput_ == EH) {
0297         towerEtNW = towerNW.hwPt();
0298         towerEtN = towerN.hwPt();
0299         towerEtNE = towerNE.hwPt();
0300         towerEtE = towerE.hwPt();
0301         towerEtSE = towerSE.hwPt();
0302         towerEtS = towerS.hwPt();
0303         towerEtSW = towerSW.hwPt();
0304         towerEtW = towerW.hwPt();
0305         towerEtNN = towerNN.hwPt();
0306         towerEtSS = towerSS.hwPt();
0307 
0308       } else if (clusterInput_ == H) {
0309         towerEtNW = towerNW.hwEtHad();
0310         towerEtN = towerN.hwEtHad();
0311         towerEtNE = towerNE.hwEtHad();
0312         towerEtE = towerE.hwEtHad();
0313         towerEtSE = towerSE.hwEtHad();
0314         towerEtS = towerS.hwEtHad();
0315         towerEtSW = towerSW.hwEtHad();
0316         towerEtW = towerW.hwEtHad();
0317         towerEtNN = towerNN.hwEtHad();
0318         towerEtSS = towerSS.hwEtHad();
0319       }
0320 
0321       int towerEtEmNW = towerNW.hwEtEm();
0322       int towerEtEmN = towerN.hwEtEm();
0323       int towerEtEmNE = towerNE.hwEtEm();
0324       int towerEtEmE = towerE.hwEtEm();
0325       int towerEtEmSE = towerSE.hwEtEm();
0326       int towerEtEmS = towerS.hwEtEm();
0327       int towerEtEmSW = towerSW.hwEtEm();
0328       int towerEtEmW = towerW.hwEtEm();
0329       int towerEtEmNN = towerNN.hwEtEm();
0330       int towerEtEmSS = towerSS.hwEtEm();
0331       //
0332       int towerEtHadNW = towerNW.hwEtHad();
0333       int towerEtHadN = towerN.hwEtHad();
0334       int towerEtHadNE = towerNE.hwEtHad();
0335       int towerEtHadE = towerE.hwEtHad();
0336       int towerEtHadSE = towerSE.hwEtHad();
0337       int towerEtHadS = towerS.hwEtHad();
0338       int towerEtHadSW = towerSW.hwEtHad();
0339       int towerEtHadW = towerW.hwEtHad();
0340       int towerEtHadNN = towerNN.hwEtHad();
0341       int towerEtHadSS = towerSS.hwEtHad();
0342 
0343       // trim one eta-side
0344       // The side with largest energy will be kept
0345       int EtEtaRight = 0;
0346       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_NE))
0347         EtEtaRight += towerEtNE;
0348       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_E))
0349         EtEtaRight += towerEtE;
0350       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_SE))
0351         EtEtaRight += towerEtSE;
0352       int EtEtaLeft = 0;
0353       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_NW))
0354         EtEtaLeft += towerEtNW;
0355       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_W))
0356         EtEtaLeft += towerEtW;
0357       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_SW))
0358         EtEtaLeft += towerEtSW;
0359 
0360       cluster.setClusterFlag(CaloCluster::TRIM_LEFT, (EtEtaRight >= EtEtaLeft));
0361 
0362       if (cluster.checkClusterFlag(CaloCluster::TRIM_LEFT)) {
0363         cluster.setClusterFlag(CaloCluster::INCLUDE_NW, false);
0364         cluster.setClusterFlag(CaloCluster::INCLUDE_W, false);
0365         cluster.setClusterFlag(CaloCluster::INCLUDE_SW, false);
0366       } else {
0367         cluster.setClusterFlag(CaloCluster::INCLUDE_NE, false);
0368         cluster.setClusterFlag(CaloCluster::INCLUDE_E, false);
0369         cluster.setClusterFlag(CaloCluster::INCLUDE_SE, false);
0370       }
0371 
0372       // compute cluster energy according to cluster flags
0373       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_NW))
0374         cluster.setHwPt(cluster.hwPt() + towerEtNW);
0375       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_N))
0376         cluster.setHwPt(cluster.hwPt() + towerEtN);
0377       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_NE))
0378         cluster.setHwPt(cluster.hwPt() + towerEtNE);
0379       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_E))
0380         cluster.setHwPt(cluster.hwPt() + towerEtE);
0381       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_SE))
0382         cluster.setHwPt(cluster.hwPt() + towerEtSE);
0383       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_S))
0384         cluster.setHwPt(cluster.hwPt() + towerEtS);
0385       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_SW))
0386         cluster.setHwPt(cluster.hwPt() + towerEtSW);
0387       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_W))
0388         cluster.setHwPt(cluster.hwPt() + towerEtW);
0389       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_NN))
0390         cluster.setHwPt(cluster.hwPt() + towerEtNN);
0391       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_SS))
0392         cluster.setHwPt(cluster.hwPt() + towerEtSS);
0393       //
0394       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_NW))
0395         cluster.setHwPtEm(cluster.hwPtEm() + towerEtEmNW);
0396       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_N))
0397         cluster.setHwPtEm(cluster.hwPtEm() + towerEtEmN);
0398       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_NE))
0399         cluster.setHwPtEm(cluster.hwPtEm() + towerEtEmNE);
0400       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_E))
0401         cluster.setHwPtEm(cluster.hwPtEm() + towerEtEmE);
0402       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_SE))
0403         cluster.setHwPtEm(cluster.hwPtEm() + towerEtEmSE);
0404       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_S))
0405         cluster.setHwPtEm(cluster.hwPtEm() + towerEtEmS);
0406       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_SW))
0407         cluster.setHwPtEm(cluster.hwPtEm() + towerEtEmSW);
0408       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_W))
0409         cluster.setHwPtEm(cluster.hwPtEm() + towerEtEmW);
0410       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_NN))
0411         cluster.setHwPtEm(cluster.hwPtEm() + towerEtEmNN);
0412       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_SS))
0413         cluster.setHwPtEm(cluster.hwPtEm() + towerEtEmSS);
0414       //
0415       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_NW))
0416         cluster.setHwPtHad(cluster.hwPtHad() + towerEtHadNW);
0417       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_N))
0418         cluster.setHwPtHad(cluster.hwPtHad() + towerEtHadN);
0419       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_NE))
0420         cluster.setHwPtHad(cluster.hwPtHad() + towerEtHadNE);
0421       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_E))
0422         cluster.setHwPtHad(cluster.hwPtHad() + towerEtHadE);
0423       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_SE))
0424         cluster.setHwPtHad(cluster.hwPtHad() + towerEtHadSE);
0425       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_S))
0426         cluster.setHwPtHad(cluster.hwPtHad() + towerEtHadS);
0427       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_SW))
0428         cluster.setHwPtHad(cluster.hwPtHad() + towerEtHadSW);
0429       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_W))
0430         cluster.setHwPtHad(cluster.hwPtHad() + towerEtHadW);
0431       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_NN))
0432         cluster.setHwPtHad(cluster.hwPtHad() + towerEtHadNN);
0433       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_SS))
0434         cluster.setHwPtHad(cluster.hwPtHad() + towerEtHadSS);
0435 
0436       // Compute fine-grain position within the seed tower,
0437       // according to the distribution of energy in the cluster
0438       int fgEta = 0;
0439       int fgPhi = 0;
0440 
0441       if (EtEtaRight > EtEtaLeft)
0442         fgEta = 2;
0443       else if (EtEtaLeft > EtEtaRight)
0444         fgEta = 1;
0445 
0446       int EtUp = 0;
0447       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_NE))
0448         EtUp += towerEtNE;
0449       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_N))
0450         EtUp += towerEtN;
0451       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_NW))
0452         EtUp += towerEtNW;
0453       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_NN))
0454         EtUp += towerEtNN;
0455       int EtDown = 0;
0456       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_SE))
0457         EtDown += towerEtSE;
0458       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_S))
0459         EtDown += towerEtS;
0460       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_SW))
0461         EtDown += towerEtSW;
0462       if (cluster.checkClusterFlag(CaloCluster::INCLUDE_SS))
0463         EtDown += towerEtSS;
0464       //
0465       if (EtDown > EtUp)
0466         fgPhi = 2;
0467       else if (EtUp > EtDown)
0468         fgPhi = 1;
0469       //
0470       cluster.setFgEta(fgEta);
0471       cluster.setFgPhi(fgPhi);
0472     }
0473   }
0474 }
0475 
0476 bool l1t::Stage2Layer2ClusterAlgorithmFirmwareImp1::idHoverE(const l1t::CaloTower tow) {
0477   bool hOverEBit = true;
0478 
0479   int ratio = tow.hwEtRatio();
0480   int qual = tow.hwQual();
0481   bool denomZeroFlag = ((qual & 0x1) > 0);
0482   bool eOverHFlag = ((qual & 0x2) > 0);
0483 
0484   if (denomZeroFlag && !eOverHFlag)
0485     hOverEBit = false;
0486   if (denomZeroFlag && eOverHFlag)
0487     hOverEBit = true;
0488   if (!denomZeroFlag && !eOverHFlag)  // H > E, ratio = log(H/E)
0489     hOverEBit = false;
0490   if (!denomZeroFlag && eOverHFlag) {  // E >= H , so ratio==log(E/H)
0491     if (abs(tow.hwEta()) < 16)
0492       hOverEBit = ratio > params_->egHOverEcutBarrel();  // equivalent to H/E<=pow(2,-egHOverEcut)
0493     else
0494       hOverEBit = ratio > params_->egHOverEcutEndcap();
0495   }
0496 
0497   return hOverEBit;
0498 }