00001 #include "Geometry/CaloTopology/interface/HcalTopology.h"
00002 #include <cmath>
00003 #include <iostream>
00004 #include <cassert>
00005
00006
00007 static const int IPHI_MAX=72;
00008
00009 HcalTopology::HcalTopology(bool h2_mode) :
00010 excludeHB_(false),
00011 excludeHE_(false),
00012 excludeHO_(false),
00013 excludeHF_(false),
00014 h2mode_(h2_mode),
00015 firstHBRing_(1),
00016 lastHBRing_(16),
00017 firstHERing_(16),
00018 lastHERing_(29),
00019 firstHFRing_(29),
00020 lastHFRing_(41),
00021 firstHORing_(1),
00022 lastHORing_(15),
00023 firstHEDoublePhiRing_((h2_mode)?(22):(21)),
00024 firstHFQuadPhiRing_(40),
00025 firstHETripleDepthRing_((h2_mode)?(24):(27)),
00026 singlePhiBins_(72),
00027 doublePhiBins_(36)
00028 {
00029 }
00030
00031
00032 bool HcalTopology::valid(const HcalDetId& id) const {
00033
00034 bool ok=validRaw(id);
00035
00036 ok=ok && !isExcluded(id);
00037
00038 return ok;
00039 }
00040
00041 bool HcalTopology::isExcluded(const HcalDetId& id) const {
00042 bool exed=false;
00043
00044 switch (id.subdet()) {
00045 case(HcalBarrel): exed=excludeHB_; break;
00046 case(HcalEndcap): exed=excludeHE_; break;
00047 case(HcalOuter): exed=excludeHO_; break;
00048 case(HcalForward): exed=excludeHF_; break;
00049 default: exed=false;
00050 }
00051
00052 if (!exed && !exclusionList_.empty()) {
00053 std::vector<HcalDetId>::const_iterator i=std::lower_bound(exclusionList_.begin(),exclusionList_.end(),id);
00054 if (i!=exclusionList_.end() && *i==id) exed=true;
00055 }
00056 return exed;
00057 }
00058
00059 void HcalTopology::exclude(const HcalDetId& id) {
00060 std::vector<HcalDetId>::iterator i=std::lower_bound(exclusionList_.begin(),exclusionList_.end(),id);
00061 if (i==exclusionList_.end() || *i!=id) {
00062 exclusionList_.insert(i,id);
00063 }
00064 }
00065
00066 void HcalTopology::excludeSubdetector(HcalSubdetector subdet) {
00067 switch (subdet) {
00068 case(HcalBarrel): excludeHB_=true; break;
00069 case(HcalEndcap): excludeHE_=true; break;
00070 case(HcalOuter): excludeHO_=true; break;
00071 case(HcalForward): excludeHF_=true; break;
00072 default: break;
00073 }
00074 }
00075
00076 std::vector<DetId> HcalTopology::east(const DetId& id) const
00077 {
00078 std::vector<DetId> vNeighborsDetId;
00079 HcalDetId neighbors[2];
00080 for (int i=0;i<decIEta(HcalDetId(id),neighbors);i++)
00081 vNeighborsDetId.push_back(DetId(neighbors[i].rawId()));
00082 return vNeighborsDetId;
00083 }
00084
00085 std::vector<DetId> HcalTopology::west(const DetId& id) const
00086 {
00087 std::vector<DetId> vNeighborsDetId;
00088 HcalDetId neighbors[2];
00089 for (int i=0;i<incIEta(HcalDetId(id),neighbors);i++)
00090 vNeighborsDetId.push_back(DetId(neighbors[i].rawId()));
00091 return vNeighborsDetId;
00092 }
00093
00094 std::vector<DetId> HcalTopology::north(const DetId& id) const
00095 {
00096 std::vector<DetId> vNeighborsDetId;
00097 HcalDetId neighbor;
00098 if (incIPhi(HcalDetId(id),neighbor))
00099 vNeighborsDetId.push_back(DetId(neighbor.rawId()));
00100 return vNeighborsDetId;
00101 }
00102
00103 std::vector<DetId> HcalTopology::south(const DetId& id) const
00104 {
00105 std::vector<DetId> vNeighborsDetId;
00106 HcalDetId neighbor;
00107 if (decIPhi(HcalDetId(id),neighbor))
00108 vNeighborsDetId.push_back(DetId(neighbor.rawId()));
00109 return vNeighborsDetId;
00110 }
00111
00112 std::vector<DetId> HcalTopology::up(const DetId& id) const
00113 {
00114 HcalDetId neighbor = id;
00115
00116
00117 std::vector<DetId> vNeighborsDetId;
00118 if(incrementDepth(neighbor))
00119 {
00120 vNeighborsDetId.push_back(neighbor);
00121 }
00122 return vNeighborsDetId;
00123 }
00124
00125 std::vector<DetId> HcalTopology::down(const DetId& id) const
00126 {
00127 std::cout << "HcalTopology::down() not yet implemented" << std::endl;
00128 std::vector<DetId> vNeighborsDetId;
00129 return vNeighborsDetId;
00130 }
00131
00132 int HcalTopology::exclude(HcalSubdetector subdet, int ieta1, int ieta2, int iphi1, int iphi2, int depth1, int depth2) {
00133
00134 bool exed=false;
00135
00136 switch (subdet) {
00137 case(HcalBarrel): exed=excludeHB_; break;
00138 case(HcalEndcap): exed=excludeHE_; break;
00139 case(HcalOuter): exed=excludeHO_; break;
00140 case(HcalForward): exed=excludeHF_; break;
00141 default: exed=false;
00142 }
00143 if (exed) return 0;
00144
00145 int ieta_l=std::min(ieta1,ieta2);
00146 int ieta_h=std::max(ieta1,ieta2);
00147 int iphi_l=std::min(iphi1,iphi2);
00148 int iphi_h=std::max(iphi1,iphi2);
00149 int depth_l=std::min(depth1,depth2);
00150 int depth_h=std::max(depth1,depth2);
00151
00152 int n=0;
00153 for (int ieta=ieta_l; ieta<=ieta_h; ieta++)
00154 for (int iphi=iphi_l; iphi<=iphi_h; iphi++)
00155 for (int depth=depth_l; depth<=depth_h; depth++) {
00156 HcalDetId id(subdet,ieta,iphi,depth);
00157 if (validRaw(id)) {
00158 exclude(id);
00159 n++;
00160 }
00161 }
00162 return n;
00163 }
00164
00192 bool HcalTopology::validRaw(const HcalDetId& id) const {
00193 bool ok=true;
00194 int ieta=id.ieta();
00195 int aieta=id.ietaAbs();
00196 int depth=id.depth();
00197 int iphi=id.iphi();
00198
00199 if ((ieta==0 || iphi<=0 || iphi>IPHI_MAX) || aieta>41) return false;
00200
00201 if (ok) {
00202 HcalSubdetector subdet=id.subdet();
00203 if (subdet==HcalBarrel) {
00204 if (aieta>16 || depth>2 || (aieta<=14 && depth>1)) ok=false;
00205 } else if (subdet==HcalEndcap) {
00206 if (depth>3 || aieta<16 || aieta>29 ||
00207 (aieta==16 && depth!=3) ||
00208 (aieta==17 && depth!=1 && !h2mode_) ||
00209 (((aieta>=17 && aieta<firstHETripleDepthRing_) || aieta==29) && depth>2) ||
00210 (aieta>=firstHEDoublePhiRing_ && (iphi%2)==0)) ok=false;
00211 } else if (subdet==HcalOuter) {
00212 if (aieta>15 || iphi>IPHI_MAX || depth!=4) ok=false;
00213 } else if (subdet==HcalForward) {
00214 if (aieta<29 || aieta>41 ||
00215 ((iphi%2)==0) ||
00216 (depth>2) ||
00217 (aieta>=40 && ((iphi+1)%4)!=0)) ok=false;
00218 } else ok=false;
00219 }
00220
00221 return ok;
00222 }
00223
00224
00225 bool HcalTopology::incIPhi(const HcalDetId& id, HcalDetId &neighbor) const {
00226 bool ok=valid(id);
00227 if (ok) {
00228 switch (id.subdet()) {
00229 case (HcalBarrel):
00230 case (HcalOuter):
00231 if (id.iphi()==IPHI_MAX) neighbor=HcalDetId(id.subdet(),id.ieta(),1,id.depth());
00232 else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()+1,id.depth());
00233 break;
00234 case (HcalEndcap):
00235 if (id.ietaAbs()>=21) {
00236 if (id.iphi()==IPHI_MAX-1) neighbor=HcalDetId(HcalEndcap,id.ieta(),1,id.depth());
00237 else neighbor=HcalDetId(HcalEndcap,id.ieta(),id.iphi()+2,id.depth());
00238 } else {
00239 if (id.iphi()==IPHI_MAX) neighbor=HcalDetId(HcalEndcap,id.ieta(),1,id.depth());
00240 else neighbor=HcalDetId(HcalEndcap,id.ieta(),id.iphi()+1,id.depth());
00241 }
00242 break;
00243 case (HcalForward):
00244 if (id.ietaAbs()>=40) {
00245 if (id.iphi()==IPHI_MAX-1) neighbor=HcalDetId(HcalEndcap,id.ieta(),3,id.depth());
00246 else neighbor=HcalDetId(HcalEndcap,id.ieta(),id.iphi()+4,id.depth());
00247 } else {
00248 if (id.iphi()==IPHI_MAX-1) neighbor=HcalDetId(HcalEndcap,id.ieta(),1,id.depth());
00249 else neighbor=HcalDetId(HcalEndcap,id.ieta(),id.iphi()+2,id.depth());
00250 }
00251 break;
00252 default: ok=false;
00253 }
00254 }
00255 return ok;
00256 }
00258 bool HcalTopology::decIPhi(const HcalDetId& id, HcalDetId &neighbor) const {
00259 bool ok=valid(id);
00260 if (ok) {
00261 switch (id.subdet()) {
00262 case (HcalBarrel):
00263 case (HcalOuter):
00264 if (id.iphi()==1) neighbor=HcalDetId(id.subdet(),id.ieta(),IPHI_MAX,id.depth());
00265 else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()-1,id.depth());
00266 break;
00267 case (HcalEndcap):
00268 if (id.ietaAbs()>=21) {
00269 if (id.iphi()==1) neighbor=HcalDetId(HcalEndcap,id.ieta(),IPHI_MAX-1,id.depth());
00270 else neighbor=HcalDetId(HcalEndcap,id.ieta(),id.iphi()-2,id.depth());
00271 } else {
00272 if (id.iphi()==1) neighbor=HcalDetId(HcalEndcap,id.ieta(),IPHI_MAX,id.depth());
00273 else neighbor=HcalDetId(HcalEndcap,id.ieta(),id.iphi()-1,id.depth());
00274 }
00275 break;
00276 case (HcalForward):
00277 if (id.ietaAbs()>=40) {
00278 if (id.iphi()==3) neighbor=HcalDetId(HcalEndcap,id.ieta(),IPHI_MAX-1,id.depth());
00279 else neighbor=HcalDetId(HcalEndcap,id.ieta(),id.iphi()-4,id.depth());
00280 } else {
00281 if (id.iphi()==1) neighbor=HcalDetId(HcalEndcap,id.ieta(),IPHI_MAX-1,id.depth());
00282 else neighbor=HcalDetId(HcalEndcap,id.ieta(),id.iphi()-2,id.depth());
00283 }
00284 break;
00285 default: ok=false;
00286 }
00287 }
00288 return ok;
00289 }
00290
00291 int HcalTopology::incIEta(const HcalDetId& id, HcalDetId neighbors[2]) const {
00292 if (id.zside()==1) return incAIEta(id,neighbors);
00293 else return decAIEta(id,neighbors);
00294 }
00295
00296 int HcalTopology::decIEta(const HcalDetId& id, HcalDetId neighbors[2]) const {
00297 if (id.zside()==1) return decAIEta(id,neighbors);
00298 else return incAIEta(id,neighbors);
00299 }
00300
00302 int HcalTopology::incAIEta(const HcalDetId& id, HcalDetId neighbors[2]) const {
00303 int n=1;
00304 int aieta=id.ietaAbs();
00305
00306 if (aieta==20 && (id.iphi()%2)==0)
00307 neighbors[0]=HcalDetId(id.subdet(),(aieta+1)*id.zside(),id.iphi()-1,id.depth());
00308 else if (aieta==39 && ((id.iphi()+1)%4)!=0)
00309 neighbors[0]=HcalDetId(id.subdet(),(aieta+1)*id.zside(),((id.iphi()==1)?(71):(id.iphi()-2)),id.depth());
00310 else
00311 neighbors[0]=HcalDetId(id.subdet(),(aieta+1)*id.zside(),id.iphi(),id.depth());
00312
00313 if (!valid(neighbors[0])) n=0;
00314 return n;
00315 }
00316
00318 int HcalTopology::decAIEta(const HcalDetId& id, HcalDetId neighbors[2]) const {
00319 int n=1;
00320 int aieta=id.ietaAbs();
00321
00322 if (aieta==21) {
00323 n=2;
00324 neighbors[0]=HcalDetId(id.subdet(),(aieta-1)*id.zside(),id.iphi(),id.depth());
00325 neighbors[1]=HcalDetId(id.subdet(),(aieta-1)*id.zside(),id.iphi()+1,id.depth());
00326 } else if (aieta==40) {
00327 n=2;
00328 neighbors[0]=HcalDetId(id.subdet(),(aieta-1)*id.zside(),id.iphi(),id.depth());
00329 if (id.iphi()==IPHI_MAX-1) neighbors[1]=HcalDetId(id.subdet(),(aieta-1)*id.zside(),1,id.depth());
00330 else neighbors[1]=HcalDetId(id.subdet(),(aieta-1)*id.zside(),id.iphi()+2,id.depth());
00331 } else if (aieta==1) {
00332 neighbors[0]=HcalDetId(id.subdet(),-aieta*id.zside(),id.iphi(),id.depth());
00333 } else
00334 neighbors[0]=HcalDetId(id.subdet(),(aieta-1)*id.zside(),id.iphi(),id.depth());
00335
00336 if (!valid(neighbors[0]) && n==2) {
00337 if (!valid(neighbors[1])) n=0;
00338 else {
00339 n=1;
00340 neighbors[0]=neighbors[1];
00341 }
00342 }
00343 if (n==2 && !valid(neighbors[1])) n=1;
00344
00345 return n;
00346 }
00347
00348
00349 void HcalTopology::depthBinInformation(HcalSubdetector subdet, int etaRing,
00350 int & nDepthBins, int & startingBin) const {
00351 if(subdet == HcalBarrel) {
00352 if (etaRing<=14) {
00353 nDepthBins = 1;
00354 startingBin = 1;
00355 } else {
00356 nDepthBins = 2;
00357 startingBin = 1;
00358 }
00359 } else if(subdet == HcalEndcap) {
00360 if (etaRing==16) {
00361 nDepthBins = 1;
00362 startingBin = 3;
00363 } else if (etaRing==17) {
00364 nDepthBins = 1;
00365 startingBin = 1;
00366 } else if (etaRing==lastHERing()) {
00367 nDepthBins = 2;
00368 startingBin = 1;
00369 }
00370 else {
00371 nDepthBins = (etaRing >= firstHETripleDepthRing_) ? 3 : 2;
00372 startingBin = 1;
00373 }
00374 }
00375
00376 else if(subdet == HcalForward) {
00377 nDepthBins = 2;
00378 startingBin = 1;
00379 }
00380
00381 else if(subdet == HcalOuter) {
00382 nDepthBins = 1;
00383 startingBin = 4;
00384 }
00385
00386 else {
00387 std::cerr << "Bad HCAL subdetector " << subdet << std::endl;
00388 }
00389 }
00390
00391
00392 bool HcalTopology::incrementDepth(HcalDetId & detId) const
00393 {
00394 HcalSubdetector subdet = detId.subdet();
00395 int ieta = detId.ieta();
00396 int etaRing = detId.ietaAbs();
00397 int depth = detId.depth();
00398 int nDepthBins, startingBin;
00399 depthBinInformation(subdet, etaRing, nDepthBins, startingBin);
00400
00401
00402 ++depth;
00403 if(depth > nDepthBins)
00404 {
00405
00406 if(subdet == HcalBarrel && etaRing < lastHORing())
00407 {
00408
00409 subdet = HcalOuter;
00410 depth = 4;
00411 }
00412 else if(subdet == HcalBarrel && etaRing == lastHBRing())
00413 {
00414
00415 subdet = HcalEndcap;
00416 }
00417 else if(subdet == HcalEndcap && etaRing == lastHERing()-1)
00418 {
00419
00420 subdet = HcalForward;
00421 (ieta > 0) ? ++ieta : --ieta;
00422 depth = 1;
00423 }
00424 else if(subdet == HcalEndcap && etaRing == lastHERing())
00425 {
00426
00427 (ieta > 0) ? --ieta : ++ieta;
00428 }
00429 else
00430 {
00431
00432 detId = HcalDetId();
00433 return false;
00434 }
00435 }
00436 detId = HcalDetId(subdet, ieta, detId.iphi(), depth);
00437
00438
00439 return validRaw(detId);
00440
00441 }
00442
00443
00444 int HcalTopology::nPhiBins(int etaRing) const {
00445 int lastPhiBin=singlePhiBins_;
00446 if (etaRing>= firstHFQuadPhiRing_) lastPhiBin=doublePhiBins_/2;
00447 else if (etaRing>= firstHEDoublePhiRing_) lastPhiBin=doublePhiBins_;
00448 return lastPhiBin;
00449 }
00450
00451
00452