CMS 3D CMS Logo

CaloTowerTopology.cc
Go to the documentation of this file.
4 #include <cassert>
5 #include <algorithm>
6 
7 //#define EDM_ML_DEBUG
8 
9 CaloTowerTopology::CaloTowerTopology(const HcalTopology* topology) : hcaltopo(topology) {
10  //get number of towers in each hcal subdet from hcaltopo
11  int nEtaHB, nEtaHO, nEtaHF;
12  nEtaHB = hcaltopo->lastHBRing() - hcaltopo->firstHBRing() + 1;
14  nEtaHO = hcaltopo->lastHORing() - hcaltopo->firstHORing() + 1;
15  nEtaHF = hcaltopo->lastHFRing() - hcaltopo->firstHFRing() + 1;
16 #ifdef EDM_ML_DEBUG
17  edm::LogVerbatim("CaloTower") << "CaloTowerTopology:(1) " << nEtaHB << ":" << nEtaHE_ << ":" << nEtaHO << ":"
18  << nEtaHF << ":" << hcaltopo->isBH();
19 #endif
20  if (hcaltopo->isBH())
21  nEtaHE_ = 0;
22 
23  //setup continuous ieta
24  firstHBRing_ = 1;
25  lastHBRing_ = firstHBRing_ + nEtaHB - 1;
26  firstHERing_ = lastHBRing_; //crossover
27  lastHERing_ = firstHERing_ + std::max(nEtaHE_ - 1, 0); //max = protection for case with no HE
28  //no crossover for CaloTowers; HF crossover cells go in the subsequent non-crossover HF tower
30  lastHFRing_ = firstHFRing_ + (nEtaHF - 1) - 1; //nEtaHF - 1 to account for no crossover
31  firstHORing_ = 1;
32  lastHORing_ = firstHORing_ + nEtaHO - 1;
33 #ifdef EDM_ML_DEBUG
34  edm::LogVerbatim("CaloTower") << "CaloTowerTopology: (2) " << firstHBRing_ << ":" << lastHBRing_ << ":"
35  << firstHERing_ << ":" << lastHERing_ << ":" << firstHFRing_ << ":" << lastHFRing_
36  << ":" << firstHORing_ << ":" << lastHORing_;
37 #endif
38 
39  //translate phi segmentation boundaries into continuous ieta
40  if (hcaltopo->firstHEDoublePhiRing() == 999 || nEtaHE_ == 0)
42  else
46 
47  //number of etas per phi segmentation type
48  int nEtaSinglePhi_, nEtaDoublePhi_, nEtaQuadPhi_;
49  nEtaSinglePhi_ = firstHEDoublePhiRing_ - firstHBRing_;
50  nEtaDoublePhi_ = firstHFQuadPhiRing_ - firstHEDoublePhiRing_;
51  nEtaQuadPhi_ = lastHFRing_ - firstHFQuadPhiRing_ + 1; //include lastHFRing
52 
53  //total number of towers per phi segmentation type
54  nSinglePhi_ = nEtaSinglePhi_ * 72;
55  nDoublePhi_ = nEtaDoublePhi_ * 36;
56  nQuadPhi_ = nEtaQuadPhi_ * 18;
57 
58 #ifdef EDM_ML_DEBUG
59  edm::LogVerbatim("CaloTower") << "CaloTowerTopology: (3) " << nEtaSinglePhi_ << ":" << nEtaDoublePhi_ << ":"
60  << nEtaQuadPhi_ << ":" << nSinglePhi_ << ":" << nDoublePhi_ << ":" << nQuadPhi_;
61 #endif
62 
63  //calculate maximum dense index size
65 }
66 
67 //convert CaloTowerTopology ieta to HcalTopology ieta
68 int CaloTowerTopology::convertCTtoHcal(int ct_ieta) const {
69  if (ct_ieta <= lastHBRing_)
70  return ct_ieta - firstHBRing_ + hcaltopo->firstHBRing();
71  else if (ct_ieta <= lastHERing_)
72  return ct_ieta - firstHERing_ + hcaltopo->firstHERing();
73  else if (ct_ieta <= lastHFRing_)
74  return ct_ieta - firstHFRing_ + hcaltopo->firstHFRing() + 1; //account for no HF crossover
75  else
76  return 0; //if ct_ieta outside range
77 }
78 
79 //convert HcalTopology ieta to CaloTowerTopology ieta
80 int CaloTowerTopology::convertHcaltoCT(int hcal_ieta, HcalSubdetector subdet) const {
81  if (subdet == HcalBarrel && hcal_ieta >= hcaltopo->firstHBRing() && hcal_ieta <= hcaltopo->lastHBRing()) {
82  return hcal_ieta - hcaltopo->firstHBRing() + firstHBRing_;
83  } else if (subdet == HcalEndcap && hcal_ieta >= hcaltopo->firstHERing() && hcal_ieta <= hcaltopo->lastHERing()) {
84  return ((nEtaHE_ == 0) ? 0 : (hcal_ieta - hcaltopo->firstHERing() + firstHERing_));
85  } else if (subdet == HcalForward && hcal_ieta >= hcaltopo->firstHFRing() && hcal_ieta <= hcaltopo->lastHFRing()) {
86  if (hcal_ieta == hcaltopo->firstHFRing())
87  hcal_ieta++; //account for no HF crossover
88  return hcal_ieta - hcaltopo->firstHFRing() + firstHFRing_ - 1;
89  } else if (subdet == HcalOuter && hcal_ieta >= hcaltopo->firstHORing() && hcal_ieta <= hcaltopo->lastHORing()) {
90  return hcal_ieta - hcaltopo->firstHORing() + firstHORing_;
91  } else
92  return 0; //if hcal_ieta outside range, or unknown subdet
93 }
94 
95 bool CaloTowerTopology::valid(const DetId& id) const {
96  assert(id.det() == DetId::Calo && id.subdetId() == CaloTowerDetId::SubdetId);
97  return validDetId(id);
98 }
99 
101  int ia = id.ietaAbs();
102  int ip = id.iphi();
103 
104  return ((ia >= firstHBRing_) && (ia <= lastHFRing_) //eta range
105  && (ip >= 1) && (ip <= 72) //phi range
106  && ((ia < firstHEDoublePhiRing_) //72 phi segments
107  || (ia < firstHFQuadPhiRing_ && (ip - 1) % 2 == 0) //36 phi segments, numbered 1,3,...,33,35
108  || (ia >= firstHFQuadPhiRing_ && (ip - 3) % 4 == 0)) //18 phi segments, numbered 71,3,7,11,...
109  );
110 }
111 
112 //decreasing ieta
113 std::vector<DetId> CaloTowerTopology::east(const DetId& id) const {
114  std::vector<DetId> dd;
115  CaloTowerDetId tid(id);
116  int ieta = tid.ieta();
117  int iphi = tid.iphi();
118 
119  if (ieta == 1) { //no ieta=0
120  ieta = -1;
121  } else if (ieta == firstHEDoublePhiRing_) {
122  //currently double phi, going to single phi (positive eta) -> extra neighbor
123  ieta--;
124  dd.emplace_back(CaloTowerDetId(ieta, iphi + 1));
125  } else if (ieta - 1 == -firstHEDoublePhiRing_) {
126  //currently single phi, going to double phi (negative eta) -> change numbering
127  if ((iphi % 2) == 0)
128  iphi--;
129  ieta--;
130  } else if (ieta == firstHFQuadPhiRing_) { //currently quad phi, going to double phi (positive eta) -> extra neighbor
131  ieta--;
132  dd.emplace_back(CaloTowerDetId(ieta, ((iphi + 1) % 72) + 1));
133  } else if (ieta - 1 == -firstHFQuadPhiRing_) {
134  //currently double phi, going to quad phi (negative eta) -> change numbering
135  if (((iphi - 1) % 4) == 0) {
136  if (iphi == 1)
137  iphi = 71;
138  else
139  iphi -= 2;
140  }
141  ieta--;
142  } else { //general case
143  ieta--;
144  }
145 
146  if (ieta >= -lastHFRing_)
147  dd.emplace_back(CaloTowerDetId(ieta, iphi));
148  return dd;
149 }
150 
151 //increasing ieta
152 std::vector<DetId> CaloTowerTopology::west(const DetId& id) const {
153  std::vector<DetId> dd;
154  CaloTowerDetId tid(id);
155 
156  int ieta = tid.ieta();
157  int iphi = tid.iphi();
158 
159  if (ieta == -1) { //no ieta=0
160  ieta = 1;
161  } else if (ieta == -firstHEDoublePhiRing_) {
162  //currently double phi, going to single phi (negative eta) -> extra neighbor
163  ieta++;
164  dd.emplace_back(CaloTowerDetId(ieta, iphi + 1));
165  } else if (ieta + 1 == firstHEDoublePhiRing_) {
166  //currently single phi, going to double phi (positive eta) -> change numbering
167  if ((iphi % 2) == 0)
168  iphi--;
169  ieta++;
170  } else if (ieta == -firstHFQuadPhiRing_) { //currently quad phi, going to double phi (negative eta) -> extra neighbor
171  ieta++;
172  dd.emplace_back(CaloTowerDetId(ieta, ((iphi + 1) % 72) + 1));
173  } else if (ieta + 1 == firstHFQuadPhiRing_) {
174  //currently double phi, going to quad phi (positive eta) -> change numbering
175  if (((iphi - 1) % 4) == 0) {
176  if (iphi == 1)
177  iphi = 71;
178  else
179  iphi -= 2;
180  }
181  ieta++;
182  } else {
183  ieta++;
184  }
185 
186  if (ieta <= lastHFRing_)
187  dd.emplace_back(CaloTowerDetId(ieta, iphi));
188 
189  return dd;
190 }
191 
192 //increasing iphi
193 std::vector<DetId> CaloTowerTopology::north(const DetId& id) const {
194  CaloTowerDetId tid(id);
195  int iphi_n = tid.iphi() + 1;
196  if (iphi_n > 72)
197  iphi_n = 1;
198  if (tid.ietaAbs() >= firstHFQuadPhiRing_) { //18 phi segments, numbered 71,3,7,11,...
199  iphi_n += 3;
200  if (iphi_n > 72)
201  iphi_n -= 72;
202  } else if (tid.ietaAbs() >= firstHEDoublePhiRing_ && (iphi_n % 2) == 0) { //36 phi segments, numbered 1,3,...,33,35
203  iphi_n++;
204  if (iphi_n > 72)
205  iphi_n -= 72;
206  }
207 
208  std::vector<DetId> dd;
209  dd.emplace_back(CaloTowerDetId(tid.ieta(), iphi_n));
210  return dd;
211 }
212 
213 //decreasing iphi
214 std::vector<DetId> CaloTowerTopology::south(const DetId& id) const {
215  CaloTowerDetId tid(id);
216  int iphi_s = tid.iphi() - 1;
217  if (iphi_s == 0)
218  iphi_s = 72;
219  if (tid.ietaAbs() >= firstHFQuadPhiRing_) { //18 phi segments, numbered 71,3,7,11,...
220  iphi_s -= 3;
221  if (iphi_s <= 0)
222  iphi_s += 72;
223  } else if (tid.ietaAbs() >= firstHEDoublePhiRing_ && (iphi_s % 2) == 0) { //36 phi segments, numbered 1,3,...,33,35
224  iphi_s--;
225  }
226 
227  std::vector<DetId> dd;
228  dd.emplace_back(CaloTowerDetId(tid.ieta(), iphi_s));
229  return dd;
230 }
231 
232 std::vector<DetId> CaloTowerTopology::up(const DetId& /*id*/) const { return std::vector<DetId>(); }
233 
234 std::vector<DetId> CaloTowerTopology::down(const DetId& /*id*/) const { return std::vector<DetId>(); }
235 
236 uint32_t CaloTowerTopology::denseIndex(const DetId& id) const {
237  CaloTowerDetId tid(id);
238  const int ie(tid.ietaAbs());
239  const int ip(tid.iphi() - 1);
240 
241  return ((0 > tid.zside() ? 0 : kSizeForDenseIndexing / 2) +
242  ((firstHEDoublePhiRing_ > ie
243  ? (ie - 1) * 72 + ip
244  : (firstHFQuadPhiRing_ > ie ? nSinglePhi_ + (ie - firstHEDoublePhiRing_) * 36 + ip / 2
245  : nSinglePhi_ + nDoublePhi_ + (ie - firstHFQuadPhiRing_) * 18 + ip / 4))));
246 }
247 
249  const int iz(din < kSizeForDenseIndexing / 2 ? -1 : 1);
250  din %= kSizeForDenseIndexing / 2;
251  const int ie(nSinglePhi_ + nDoublePhi_ - 1 < (int)(din)
253  : (nSinglePhi_ - 1 < (int)din ? firstHEDoublePhiRing_ + (din - nSinglePhi_) / 36 : din / 72 + 1));
254 
255  const int ip(nSinglePhi_ + nDoublePhi_ - 1 < (int)(din)
256  ? ((din - nSinglePhi_ - nDoublePhi_) % 18) * 4 + 3
257  : (nSinglePhi_ - 1 < (int)(din) ? ((din - nSinglePhi_) % 36) * 2 + 1 : din % 72 + 1));
258 
259  return (validDenseIndex(din) ? CaloTowerDetId(iz * ie, ip) : CaloTowerDetId());
260 }
Log< level::Info, true > LogVerbatim
virtual bool validDetId(const CaloTowerDetId &id) const
int firstHORing() const
Definition: HcalTopology.h:98
int ietaAbs() const
get the absolute value of the tower ieta
bool isBH() const
Definition: HcalTopology.h:162
std::vector< DetId > down(const DetId &id) const override
int lastHORing() const
Definition: HcalTopology.h:99
uint32_t kSizeForDenseIndexing
bool valid(const DetId &id) const override
is this detid present in the Topology?
assert(be >=bs)
CaloTowerTopology(const HcalTopology *topology)
standard constructor
string dd
Definition: createTree.py:154
int firstHBRing() const
Definition: HcalTopology.h:91
CaloTowerDetId detIdFromDenseIndex(uint32_t din) const
std::vector< DetId > south(const DetId &id) const override
int firstHFQuadPhiRing() const
Definition: HcalTopology.h:103
std::vector< DetId > up(const DetId &id) const override
static const int SubdetId
int lastHBRing() const
Definition: HcalTopology.h:92
int convertCTtoHcal(int ct_ieta) const
HcalSubdetector
Definition: HcalAssistant.h:31
int convertHcaltoCT(int hcal_ieta, HcalSubdetector subdet) const
const HcalTopology * hcaltopo
int firstHEQuadPhiRing() const
Definition: HcalTopology.h:102
Definition: DetId.h:17
std::vector< DetId > north(const DetId &id) const override
int iphi() const
get the tower iphi
bool validDenseIndex(uint32_t din) const
int firstHEDoublePhiRing() const
Definition: HcalTopology.h:101
std::vector< DetId > east(const DetId &id) const override
int ieta() const
get the tower ieta
int zside() const
get the z-side of the tower (1/-1)
int lastHERing() const
Definition: HcalTopology.h:94
uint32_t denseIndex(const DetId &id) const
int lastHFRing() const
Definition: HcalTopology.h:97
int firstHFRing() const
Definition: HcalTopology.h:96
int firstHERing() const
Definition: HcalTopology.h:93
std::vector< DetId > west(const DetId &id) const override