Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:08:13

0001 #include "Geometry/HcalTowerAlgo/interface/HcalTrigTowerGeometry.h"
0002 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
0003 #include "DataFormats/HcalDetId/interface/HcalTrigTowerDetId.h"
0004 
0005 #include <iostream>
0006 #include <cassert>
0007 
0008 HcalTrigTowerGeometry::HcalTrigTowerGeometry(const HcalTopology* topology) : theTopology(topology) {
0009   auto tmode = theTopology->triggerMode();
0010   useRCT_ = tmode <= HcalTopologyMode::TriggerMode_2016;
0011   use1x1_ = tmode >= HcalTopologyMode::TriggerMode_2016;
0012   use2017_ = tmode >= HcalTopologyMode::TriggerMode_2017 or tmode == HcalTopologyMode::TriggerMode_2018legacy;
0013 }
0014 
0015 std::vector<HcalTrigTowerDetId> HcalTrigTowerGeometry::towerIds(const HcalDetId& cellId) const {
0016   std::vector<HcalTrigTowerDetId> results;
0017 
0018   if (cellId.subdet() == HcalForward) {
0019     if (useRCT_) {
0020       // first do eta

0021       int hfRing = cellId.ietaAbs();
0022       int ieta = firstHFTower(0);
0023       // find the tower that contains this ring

0024       while (hfRing >= firstHFRingInTower(ieta + 1)) {
0025         ++ieta;
0026       }
0027 
0028       ieta *= cellId.zside();
0029 
0030       // now for phi

0031       // HF towers are quad, 18 in phi.

0032       // go two cells per trigger tower.

0033 
0034       int iphi = (((cellId.iphi() + 1) / 4) * 4 + 1) % 72;  // 71+1 --> 1, 3+5 --> 5

0035       results.emplace_back(HcalTrigTowerDetId(ieta, iphi));
0036     }
0037     if (use1x1_) {
0038       int hfRing = cellId.ietaAbs();
0039       if (hfRing == 29)
0040         hfRing = 30;  // sum 29 into 30.

0041 
0042       int ieta = hfRing * cellId.zside();
0043       int iphi = cellId.iphi();
0044 
0045       HcalTrigTowerDetId id(ieta, iphi);
0046       id.setVersion(1);  // version 1 for 1x1 HF granularity

0047       results.emplace_back(id);
0048     }
0049 
0050   } else {
0051     // the first twenty rings are one-to-one

0052     if (cellId.ietaAbs() <= theTopology->lastHBRing()) {
0053       results.emplace_back(HcalTrigTowerDetId(cellId.ieta(), cellId.iphi()));
0054     } else if (theTopology->maxDepthHE() == 0) {
0055       // Ignore these

0056     } else if (cellId.ietaAbs() < theTopology->firstHEDoublePhiRing()) {
0057       results.emplace_back(HcalTrigTowerDetId(cellId.ieta(), cellId.iphi()));
0058     } else {
0059       // the remaining rings are two-to-one in phi

0060       int iphi1 = cellId.iphi();
0061       int ieta = cellId.ieta();
0062       int depth = cellId.depth();
0063       // the last eta ring in HE is split.  Recombine.

0064       if (ieta == theTopology->lastHERing())
0065         --ieta;
0066       if (ieta == -theTopology->lastHERing())
0067         ++ieta;
0068 
0069       if (use2017_) {
0070         if (ieta == 26 and depth == 7)
0071           ++ieta;
0072         if (ieta == -26 and depth == 7)
0073           --ieta;
0074       }
0075 
0076       results.emplace_back(HcalTrigTowerDetId(ieta, iphi1));
0077       results.emplace_back(HcalTrigTowerDetId(ieta, iphi1 + 1));
0078     }
0079   }
0080 
0081   return results;
0082 }
0083 
0084 std::vector<HcalDetId> HcalTrigTowerGeometry::detIds(const HcalTrigTowerDetId& hcalTrigTowerDetId) const {
0085   // Written, tested by E. Berry (Princeton)

0086   std::vector<HcalDetId> results;
0087 
0088   int tower_ieta = hcalTrigTowerDetId.ieta();
0089   int tower_iphi = hcalTrigTowerDetId.iphi();
0090 
0091   int cell_ieta = tower_ieta;
0092   int cell_iphi = tower_iphi;
0093 
0094   int min_depth, n_depths;
0095 
0096   // HB

0097 
0098   if (abs(cell_ieta) <= theTopology->lastHBRing()) {
0099     theTopology->depthBinInformation(
0100         HcalBarrel, abs(tower_ieta), tower_iphi, hcalTrigTowerDetId.zside(), n_depths, min_depth);
0101     for (int cell_depth = min_depth; cell_depth <= min_depth + n_depths - 1; cell_depth++)
0102       results.emplace_back(HcalDetId(HcalBarrel, cell_ieta, cell_iphi, cell_depth));
0103   }
0104 
0105   // HO

0106 
0107   if (abs(cell_ieta) <= theTopology->lastHORing()) {
0108     theTopology->depthBinInformation(
0109         HcalOuter, abs(tower_ieta), tower_iphi, hcalTrigTowerDetId.zside(), n_depths, min_depth);
0110     for (int ho_depth = min_depth; ho_depth <= min_depth + n_depths - 1; ho_depth++)
0111       results.emplace_back(HcalDetId(HcalOuter, cell_ieta, cell_iphi, ho_depth));
0112   }
0113 
0114   // HE

0115 
0116   if (abs(cell_ieta) >= theTopology->firstHERing() && abs(cell_ieta) < theTopology->lastHERing()) {
0117     theTopology->depthBinInformation(
0118         HcalEndcap, abs(tower_ieta), tower_iphi, hcalTrigTowerDetId.zside(), n_depths, min_depth);
0119 
0120     // Special for double-phi cells

0121     if (abs(cell_ieta) >= theTopology->firstHEDoublePhiRing())
0122       if (tower_iphi % 2 == 0)
0123         cell_iphi = tower_iphi - 1;
0124 
0125     if (use2017_) {
0126       if (abs(tower_ieta) == 26)
0127         --n_depths;
0128       if (tower_ieta == 27)
0129         results.emplace_back(HcalDetId(HcalEndcap, cell_ieta - 1, cell_iphi, 7));
0130       if (tower_ieta == -27)
0131         results.emplace_back(HcalDetId(HcalEndcap, cell_ieta + 1, cell_iphi, 7));
0132     }
0133 
0134     for (int cell_depth = min_depth; cell_depth <= min_depth + n_depths - 1; cell_depth++)
0135       results.emplace_back(HcalDetId(HcalEndcap, cell_ieta, cell_iphi, cell_depth));
0136 
0137     // Special for split-eta cells

0138     if (abs(tower_ieta) == 28) {
0139       theTopology->depthBinInformation(
0140           HcalEndcap, abs(tower_ieta) + 1, tower_iphi, hcalTrigTowerDetId.zside(), n_depths, min_depth);
0141       for (int cell_depth = min_depth; cell_depth <= min_depth + n_depths - 1; cell_depth++) {
0142         if (tower_ieta < 0)
0143           results.emplace_back(HcalDetId(HcalEndcap, tower_ieta - 1, cell_iphi, cell_depth));
0144         if (tower_ieta > 0)
0145           results.emplace_back(HcalDetId(HcalEndcap, tower_ieta + 1, cell_iphi, cell_depth));
0146       }
0147     }
0148   }
0149 
0150   // HF

0151 
0152   if (abs(cell_ieta) >= theTopology->firstHFRing()) {
0153     if (hcalTrigTowerDetId.version() == 0) {
0154       int HfTowerPhiSize = 72 / nPhiBins(tower_ieta, 0);
0155 
0156       int HfTowerEtaSize = hfTowerEtaSize(tower_ieta);
0157       int FirstHFRingInTower = firstHFRingInTower(abs(tower_ieta));
0158 
0159       for (int iHFTowerPhiSegment = 0; iHFTowerPhiSegment < HfTowerPhiSize; iHFTowerPhiSegment++) {
0160         cell_iphi = (tower_iphi / HfTowerPhiSize) * HfTowerPhiSize;  // Find the minimum phi segment

0161         cell_iphi -= 2;                   // The first trigger tower starts at HCAL iphi = 71, not HCAL iphi = 1

0162         cell_iphi += iHFTowerPhiSegment;  // Get all of the HCAL iphi values in this trigger tower

0163         cell_iphi += 72;                  // Don't want to take the mod of a negative number

0164         cell_iphi = cell_iphi % 72;       // There are, at most, 72 cells.

0165         cell_iphi += 1;                   // There is no cell at iphi = 0

0166 
0167         if (cell_iphi % 2 == 0)
0168           continue;  // These cells don't exist.

0169 
0170         for (int iHFTowerEtaSegment = 0; iHFTowerEtaSegment < HfTowerEtaSize; iHFTowerEtaSegment++) {
0171           cell_ieta = FirstHFRingInTower + iHFTowerEtaSegment;
0172 
0173           if (cell_ieta >= 40 && cell_iphi % 4 == 1)
0174             continue;  // These cells don't exist.

0175 
0176           theTopology->depthBinInformation(
0177               HcalForward, cell_ieta, tower_iphi, hcalTrigTowerDetId.zside(), n_depths, min_depth);
0178 
0179           // Negative tower_ieta -> negative cell_ieta

0180           int zside = 1;
0181           if (tower_ieta < 0)
0182             zside = -1;
0183 
0184           cell_ieta *= zside;
0185 
0186           for (int cell_depth = min_depth; cell_depth <= min_depth + n_depths - 1; cell_depth++)
0187             results.emplace_back(HcalDetId(HcalForward, cell_ieta, cell_iphi, cell_depth));
0188 
0189           if (zside * cell_ieta == 30) {
0190             theTopology->depthBinInformation(
0191                 HcalForward, 29 * zside, tower_iphi, hcalTrigTowerDetId.zside(), n_depths, min_depth);
0192             for (int cell_depth = min_depth; cell_depth <= min_depth + n_depths - 1; cell_depth++)
0193               results.emplace_back(HcalDetId(HcalForward, 29 * zside, cell_iphi, cell_depth));
0194           }
0195         }
0196       }
0197     } else if (hcalTrigTowerDetId.version() == 1) {
0198       theTopology->depthBinInformation(
0199           HcalForward, tower_ieta, tower_iphi, hcalTrigTowerDetId.zside(), n_depths, min_depth);
0200       for (int cell_depth = min_depth; cell_depth <= min_depth + n_depths - 1; cell_depth++)
0201         results.emplace_back(HcalDetId(HcalForward, tower_ieta, tower_iphi, cell_depth));
0202       if (abs(tower_ieta) == 30) {
0203         int i29 = 29;
0204         if (tower_ieta < 0)
0205           i29 = -29;
0206         theTopology->depthBinInformation(HcalForward, i29, tower_iphi, hcalTrigTowerDetId.zside(), n_depths, min_depth);
0207         for (int cell_depth = min_depth; cell_depth <= min_depth + n_depths - 1; cell_depth++)
0208           results.emplace_back(HcalDetId(HcalForward, i29, tower_iphi, cell_depth));
0209       }
0210     }
0211   }
0212 
0213   return results;
0214 }
0215 
0216 int HcalTrigTowerGeometry::hfTowerEtaSize(int ieta) const {
0217   int ietaAbs = abs(ieta);
0218   assert(ietaAbs >= firstHFTower(0) && ietaAbs <= nTowers(0));
0219   // the first three come from rings 29-31, 32-34, 35-37. The last has 4 rings: 38-41

0220   return (ietaAbs == nTowers(0)) ? 4 : 3;
0221 }
0222 
0223 int HcalTrigTowerGeometry::firstHFRingInTower(int ietaTower) const {
0224   // count up to the correct HF ring

0225   int inputTower = abs(ietaTower);
0226   int result = theTopology->firstHFRing();
0227   for (int iTower = firstHFTower(0); iTower != inputTower; ++iTower) {
0228     result += hfTowerEtaSize(iTower);
0229   }
0230 
0231   // negative in, negative out.

0232   if (ietaTower < 0)
0233     result *= -1;
0234   return result;
0235 }
0236 
0237 void HcalTrigTowerGeometry::towerEtaBounds(int ieta, int version, double& eta1, double& eta2) const {
0238   int ietaAbs = abs(ieta);
0239   std::pair<double, double> etas = (ietaAbs < firstHFTower(version)) ? theTopology->etaRange(HcalBarrel, ietaAbs)
0240                                                                      : theTopology->etaRange(HcalForward, ietaAbs);
0241   eta1 = etas.first;
0242   eta2 = etas.second;
0243 
0244   // get the signs and order right

0245   if (ieta < 0) {
0246     double tmp = eta1;
0247     eta1 = -eta2;
0248     eta2 = -tmp;
0249   }
0250 }