CMS 3D CMS Logo

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