00001 #include "Geometry/CaloTopology/interface/HcalTopology.h"
00002 #include <cmath>
00003 #include <iostream>
00004 #include <cassert>
00005 #include <algorithm>
00006 #include "FWCore/Utilities/interface/Exception.h"
00007 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00008 #include "DataFormats/HcalDetId/interface/HcalTrigTowerDetId.h"
00009 #include "DataFormats/HcalDetId/interface/HcalCalibDetId.h"
00010
00011 static const int IPHI_MAX=72;
00012
00013 HcalTopology::HcalTopology(HcalTopologyMode::Mode mode, int maxDepthHB, int maxDepthHE, HcalTopologyMode::TriggerMode tmode) :
00014 excludeHB_(false),
00015 excludeHE_(false),
00016 excludeHO_(false),
00017 excludeHF_(false),
00018 mode_(mode),
00019 triggerMode_(tmode),
00020 firstHBRing_(1),
00021 lastHBRing_(16),
00022 firstHERing_(16),
00023 lastHERing_(29),
00024 firstHFRing_(29),
00025 lastHFRing_(41),
00026 firstHORing_(1),
00027 lastHORing_(15),
00028 firstHEDoublePhiRing_((mode==HcalTopologyMode::H2 || mode==HcalTopologyMode::H2HE)?(22):(21)),
00029 firstHFQuadPhiRing_(40),
00030 firstHETripleDepthRing_((mode==HcalTopologyMode::H2 || mode==HcalTopologyMode::H2HE)?(24):(27)),
00031 singlePhiBins_(72),
00032 doublePhiBins_(36),
00033 maxDepthHB_(maxDepthHB),
00034 maxDepthHE_(maxDepthHE),
00035 HBSize_(kHBSizePreLS1),
00036 HESize_(kHESizePreLS1),
00037 HOSize_(kHOSizePreLS1),
00038 HFSize_(kHFSizePreLS1),
00039 numberOfShapes_(( mode==HcalTopologyMode::SLHC ) ? 500 : 87 ) {
00040
00041 if (mode_==HcalTopologyMode::LHC) {
00042 topoVersion_=0;
00043 HBSize_= kHBSizePreLS1;
00044 HESize_= kHESizePreLS1;
00045 HOSize_= kHOSizePreLS1;
00046 HFSize_= kHFSizePreLS1;
00047 } else if (mode_==HcalTopologyMode::SLHC) {
00048 HBSize_= maxDepthHB*16*72*2;
00049 HESize_= maxDepthHE*(29-16+1)*72*2;
00050 HOSize_= 15*72*2;
00051 HFSize_= 72*13*2*2;
00052
00053 topoVersion_=10;
00054 }
00055
00056 }
00057
00058 bool HcalTopology::valid(const DetId& id) const {
00059 assert(id.det()==DetId::Hcal);
00060 return validHcal(id);
00061 }
00062
00063 bool HcalTopology::validHcal(const HcalDetId& id) const {
00064
00065 bool ok=validRaw(id);
00066
00067 ok=ok && !isExcluded(id);
00068
00069 return ok;
00070 }
00071
00072 bool HcalTopology::isExcluded(const HcalDetId& id) const {
00073 bool exed=false;
00074
00075 switch (id.subdet()) {
00076 case(HcalBarrel): exed=excludeHB_; break;
00077 case(HcalEndcap): exed=excludeHE_; break;
00078 case(HcalOuter): exed=excludeHO_; break;
00079 case(HcalForward): exed=excludeHF_; break;
00080 default: exed=false;
00081 }
00082
00083 if (!exed && !exclusionList_.empty()) {
00084 std::vector<HcalDetId>::const_iterator i=std::lower_bound(exclusionList_.begin(),exclusionList_.end(),id);
00085 if (i!=exclusionList_.end() && *i==id) exed=true;
00086 }
00087 return exed;
00088 }
00089
00090 void HcalTopology::exclude(const HcalDetId& id) {
00091 std::vector<HcalDetId>::iterator i=std::lower_bound(exclusionList_.begin(),exclusionList_.end(),id);
00092 if (i==exclusionList_.end() || *i!=id) {
00093 exclusionList_.insert(i,id);
00094 }
00095 }
00096
00097 void HcalTopology::excludeSubdetector(HcalSubdetector subdet) {
00098 switch (subdet) {
00099 case(HcalBarrel): excludeHB_=true; break;
00100 case(HcalEndcap): excludeHE_=true; break;
00101 case(HcalOuter): excludeHO_=true; break;
00102 case(HcalForward): excludeHF_=true; break;
00103 default: break;
00104 }
00105 }
00106
00107 std::vector<DetId> HcalTopology::east(const DetId& id) const {
00108 std::vector<DetId> vNeighborsDetId;
00109 HcalDetId neighbors[2];
00110 for (int i=0;i<decIEta(HcalDetId(id),neighbors);i++)
00111 vNeighborsDetId.push_back(DetId(neighbors[i].rawId()));
00112 return vNeighborsDetId;
00113 }
00114
00115 std::vector<DetId> HcalTopology::west(const DetId& id) const {
00116 std::vector<DetId> vNeighborsDetId;
00117 HcalDetId neighbors[2];
00118 for (int i=0;i<incIEta(HcalDetId(id),neighbors);i++)
00119 vNeighborsDetId.push_back(DetId(neighbors[i].rawId()));
00120 return vNeighborsDetId;
00121 }
00122
00123 std::vector<DetId> HcalTopology::north(const DetId& id) const {
00124 std::vector<DetId> vNeighborsDetId;
00125 HcalDetId neighbor;
00126 if (incIPhi(HcalDetId(id),neighbor))
00127 vNeighborsDetId.push_back(DetId(neighbor.rawId()));
00128 return vNeighborsDetId;
00129 }
00130
00131 std::vector<DetId> HcalTopology::south(const DetId& id) const {
00132 std::vector<DetId> vNeighborsDetId;
00133 HcalDetId neighbor;
00134 if (decIPhi(HcalDetId(id),neighbor))
00135 vNeighborsDetId.push_back(DetId(neighbor.rawId()));
00136 return vNeighborsDetId;
00137 }
00138
00139 std::vector<DetId> HcalTopology::up(const DetId& id) const {
00140 HcalDetId neighbor = id;
00141
00142
00143 std::vector<DetId> vNeighborsDetId;
00144 if(incrementDepth(neighbor))
00145 {
00146 vNeighborsDetId.push_back(neighbor);
00147 }
00148 return vNeighborsDetId;
00149 }
00150
00151 std::vector<DetId> HcalTopology::down(const DetId& id) const {
00152 std::cout << "HcalTopology::down() not yet implemented" << std::endl;
00153 std::vector<DetId> vNeighborsDetId;
00154 return vNeighborsDetId;
00155 }
00156
00157 int HcalTopology::exclude(HcalSubdetector subdet, int ieta1, int ieta2, int iphi1, int iphi2, int depth1, int depth2) {
00158
00159 bool exed=false;
00160
00161 switch (subdet) {
00162 case(HcalBarrel): exed=excludeHB_; break;
00163 case(HcalEndcap): exed=excludeHE_; break;
00164 case(HcalOuter): exed=excludeHO_; break;
00165 case(HcalForward): exed=excludeHF_; break;
00166 default: exed=false;
00167 }
00168 if (exed) return 0;
00169
00170 int ieta_l=std::min(ieta1,ieta2);
00171 int ieta_h=std::max(ieta1,ieta2);
00172 int iphi_l=std::min(iphi1,iphi2);
00173 int iphi_h=std::max(iphi1,iphi2);
00174 int depth_l=std::min(depth1,depth2);
00175 int depth_h=std::max(depth1,depth2);
00176
00177 int n=0;
00178 for (int ieta=ieta_l; ieta<=ieta_h; ieta++)
00179 for (int iphi=iphi_l; iphi<=iphi_h; iphi++)
00180 for (int depth=depth_l; depth<=depth_h; depth++) {
00181 HcalDetId id(subdet,ieta,iphi,depth);
00182 if (validRaw(id)) {
00183 exclude(id);
00184 n++;
00185 }
00186 }
00187 return n;
00188 }
00189
00216 bool HcalTopology::validDetIdPreLS1(const HcalDetId& id) const {
00217 const HcalSubdetector sd (id.subdet());
00218 const int ie (id.ietaAbs());
00219 const int ip (id.iphi());
00220 const int dp (id.depth());
00221
00222 return ( ( ip >= 1 ) &&
00223 ( ip <= IPHI_MAX ) &&
00224 ( dp >= 1 ) &&
00225 ( ie >= 1 ) &&
00226 ( ( ( sd == HcalBarrel ) &&
00227 ( ( ( ie <= 14 ) &&
00228 ( dp == 1 ) ) ||
00229 ( ( ( ie == 15 ) || ( ie == 16 ) ) &&
00230 ( dp <= 2 ) ) ) ) ||
00231 ( ( sd == HcalEndcap ) &&
00232 ( ( ( ie == firstHERing() ) &&
00233 ( dp == 3 ) ) ||
00234 ( ( ie == 17 ) &&
00235 ( dp == 1 ) ) ||
00236 ( ( ie >= 18 ) &&
00237 ( ie <= 20 ) &&
00238 ( dp <= 2 ) ) ||
00239 ( ( ie >= 21 ) &&
00240 ( ie <= 26 ) &&
00241 ( dp <= 2 ) &&
00242 ( ip%2 == 1 ) ) ||
00243 ( ( ie >= 27 ) &&
00244 ( ie <= 28 ) &&
00245 ( dp <= 3 ) &&
00246 ( ip%2 == 1 ) ) ||
00247 ( ( ie == 29 ) &&
00248 ( dp <= 2 ) &&
00249 ( ip%2 == 1 ) ) ) ) ||
00250 ( ( sd == HcalOuter ) &&
00251 ( ie <= 15 ) &&
00252 ( dp == 4 ) ) ||
00253 ( ( sd == HcalForward ) &&
00254 ( dp <= 2 ) &&
00255 ( ( ( ie >= firstHFRing() ) &&
00256 ( ie < firstHFQuadPhiRing() ) &&
00257 ( ip%2 == 1 ) ) ||
00258 ( ( ie >= firstHFQuadPhiRing() ) &&
00259 ( ie <= lastHFRing() ) &&
00260 ( ip%4 == 3 ) ) ) ) ) ) ;
00261 }
00262
00264 bool HcalTopology::validRaw(const HcalDetId& id) const {
00265 bool ok=true;
00266 int ieta=id.ieta();
00267 int aieta=id.ietaAbs();
00268 int depth=id.depth();
00269 int iphi=id.iphi();
00270 if ((ieta==0 || iphi<=0 || iphi>IPHI_MAX) || aieta>lastHFRing()) return false;
00271
00272 if (ok) {
00273 HcalSubdetector subdet=id.subdet();
00274 if (subdet==HcalBarrel) {
00275 if (mode_==HcalTopologyMode::SLHC || mode_==HcalTopologyMode::H2HE) {
00276 if ((aieta>lastHBRing() || depth>maxDepthHB_ || (aieta==lastHBRing() && depth > 2))) ok=false;
00277 } else {
00278 if (aieta>lastHBRing() || depth>2 || (aieta<=14 && depth>1)) ok=false;
00279 }
00280 } else if (subdet==HcalEndcap) {
00281 if (mode_==HcalTopologyMode::SLHC || mode_==HcalTopologyMode::H2HE) {
00282 if (depth>maxDepthHE_ || aieta<firstHERing() || aieta>lastHERing() || (aieta==firstHERing() && depth<3) || (aieta>=firstHEDoublePhiRing() && (iphi%2)==0)) ok=false;
00283 } else {
00284 if (depth>3 || aieta<firstHERing() || aieta>lastHERing() || (aieta==firstHERing() && depth!=3) || (aieta==17 && depth!=1 && mode_!=HcalTopologyMode::H2) ||
00285 (((aieta>=17 && aieta<firstHETripleDepthRing()) || aieta==lastHERing()) && depth>2) ||
00286 (aieta>=firstHEDoublePhiRing() && (iphi%2)==0)) ok=false;
00287 }
00288 } else if (subdet==HcalOuter) {
00289 if (aieta>lastHORing() || iphi>IPHI_MAX || depth!=4) ok=false;
00290 } else if (subdet==HcalForward) {
00291 if (aieta<firstHFRing() || aieta>lastHFRing() || ((iphi%2)==0) || (depth>2) || (aieta>=firstHFQuadPhiRing() && ((iphi+1)%4)!=0)) ok=false;
00292 } else {
00293 ok=false;
00294 }
00295 }
00296 return ok;
00297 }
00298
00299
00300 bool HcalTopology::incIPhi(const HcalDetId& id, HcalDetId &neighbor) const {
00301 bool ok=valid(id);
00302 if (ok) {
00303 switch (id.subdet()) {
00304 case (HcalBarrel):
00305 case (HcalOuter):
00306 if (id.iphi()==IPHI_MAX) neighbor=HcalDetId(id.subdet(),id.ieta(),1,id.depth());
00307 else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()+1,id.depth());
00308 break;
00309 case (HcalEndcap):
00310 if (id.ietaAbs()>=firstHEDoublePhiRing()) {
00311 if (id.iphi()==IPHI_MAX-1) neighbor=HcalDetId(id.subdet(),id.ieta(),1,id.depth());
00312 else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()+2,id.depth());
00313 } else {
00314 if (id.iphi()==IPHI_MAX) neighbor=HcalDetId(id.subdet(),id.ieta(),1,id.depth());
00315 else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()+1,id.depth());
00316 }
00317 break;
00318 case (HcalForward):
00319 if (id.ietaAbs()>=firstHFQuadPhiRing()) {
00320 if (id.iphi()==IPHI_MAX-1) neighbor=HcalDetId(id.subdet(),id.ieta(),3,id.depth());
00321 else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()+4,id.depth());
00322 } else {
00323 if (id.iphi()==IPHI_MAX-1) neighbor=HcalDetId(id.subdet(),id.ieta(),1,id.depth());
00324 else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()+2,id.depth());
00325 }
00326 break;
00327 default: ok=false;
00328 }
00329 }
00330 return ok;
00331 }
00332
00334 bool HcalTopology::decIPhi(const HcalDetId& id, HcalDetId &neighbor) const {
00335 bool ok=valid(id);
00336 if (ok) {
00337 switch (id.subdet()) {
00338 case (HcalBarrel):
00339 case (HcalOuter):
00340 if (id.iphi()==1) neighbor=HcalDetId(id.subdet(),id.ieta(),IPHI_MAX,id.depth());
00341 else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()-1,id.depth());
00342 break;
00343 case (HcalEndcap):
00344 if (id.ietaAbs()>=firstHEDoublePhiRing()) {
00345 if (id.iphi()==1) neighbor=HcalDetId(id.subdet(),id.ieta(),IPHI_MAX-1,id.depth());
00346 else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()-2,id.depth());
00347 } else {
00348 if (id.iphi()==1) neighbor=HcalDetId(id.subdet(),id.ieta(),IPHI_MAX,id.depth());
00349 else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()-1,id.depth());
00350 }
00351 break;
00352 case (HcalForward):
00353 if (id.ietaAbs()>=firstHFQuadPhiRing()) {
00354 if (id.iphi()==3) neighbor=HcalDetId(id.subdet(),id.ieta(),IPHI_MAX-1,id.depth());
00355 else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()-4,id.depth());
00356 } else {
00357 if (id.iphi()==1) neighbor=HcalDetId(id.subdet(),id.ieta(),IPHI_MAX-1,id.depth());
00358 else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()-2,id.depth());
00359 }
00360 break;
00361 default: ok=false;
00362 }
00363 }
00364 return ok;
00365 }
00366
00367 int HcalTopology::incIEta(const HcalDetId& id, HcalDetId neighbors[2]) const {
00368 if (id.zside()==1) return incAIEta(id,neighbors);
00369 else return decAIEta(id,neighbors);
00370 }
00371
00372 int HcalTopology::decIEta(const HcalDetId& id, HcalDetId neighbors[2]) const {
00373 if (id.zside()==1) return decAIEta(id,neighbors);
00374 else return incAIEta(id,neighbors);
00375 }
00376
00378 int HcalTopology::incAIEta(const HcalDetId& id, HcalDetId neighbors[2]) const {
00379 int n=1;
00380 int aieta=id.ietaAbs();
00381
00382 if (aieta==firstHEDoublePhiRing()-1 && (id.iphi()%2)==0)
00383 neighbors[0]=HcalDetId(id.subdet(),(aieta+1)*id.zside(),id.iphi()-1,id.depth());
00384 else if (aieta==firstHFQuadPhiRing()-1 && ((id.iphi()+1)%4)!=0)
00385 neighbors[0]=HcalDetId(id.subdet(),(aieta+1)*id.zside(),((id.iphi()==1)?(71):(id.iphi()-2)),id.depth());
00386 else if (aieta==lastHBRing())
00387 neighbors[0]=HcalDetId(HcalEndcap,(aieta+1)*id.zside(),id.iphi(),1);
00388 else if (aieta==lastHERing())
00389 neighbors[0]=HcalDetId(HcalForward,(aieta+1)*id.zside(),id.iphi(),1);
00390 else
00391 neighbors[0]=HcalDetId(id.subdet(),(aieta+1)*id.zside(),id.iphi(),id.depth());
00392
00393 if (!valid(neighbors[0])) n=0;
00394 return n;
00395 }
00396
00398 int HcalTopology::decAIEta(const HcalDetId& id, HcalDetId neighbors[2]) const {
00399 int n=1;
00400 int aieta=id.ietaAbs();
00401
00402 if (aieta==firstHEDoublePhiRing()) {
00403 n=2;
00404 neighbors[0]=HcalDetId(id.subdet(),(aieta-1)*id.zside(),id.iphi(),id.depth());
00405 neighbors[1]=HcalDetId(id.subdet(),(aieta-1)*id.zside(),id.iphi()+1,id.depth());
00406 } else if (aieta==firstHFQuadPhiRing()) {
00407 n=2;
00408 neighbors[0]=HcalDetId(id.subdet(),(aieta-1)*id.zside(),id.iphi(),id.depth());
00409 if (id.iphi()==IPHI_MAX-1) neighbors[1]=HcalDetId(id.subdet(),(aieta-1)*id.zside(),1,id.depth());
00410 else neighbors[1]=HcalDetId(id.subdet(),(aieta-1)*id.zside(),id.iphi()+2,id.depth());
00411 } else if (aieta==1) {
00412 neighbors[0]=HcalDetId(id.subdet(),-aieta*id.zside(),id.iphi(),id.depth());
00413 } else if (aieta==lastHBRing()+1) {
00414 neighbors[0]=HcalDetId(HcalBarrel,(aieta-1)*id.zside(),id.iphi(),id.depth());
00415 } else if (aieta==lastHERing()+1) {
00416 neighbors[0]=HcalDetId(HcalEndcap,(aieta-1)*id.zside(),id.iphi(),id.depth());
00417 } else
00418 neighbors[0]=HcalDetId(id.subdet(),(aieta-1)*id.zside(),id.iphi(),id.depth());
00419
00420 if (!valid(neighbors[0]) && n==2) {
00421 if (!valid(neighbors[1])) n=0;
00422 else {
00423 n=1;
00424 neighbors[0]=neighbors[1];
00425 }
00426 }
00427 if (n==2 && !valid(neighbors[1])) n=1;
00428 if (n==1 && !valid(neighbors[0])) n=0;
00429
00430 return n;
00431 }
00432
00433
00434 void HcalTopology::depthBinInformation(HcalSubdetector subdet, int etaRing,
00435 int & nDepthBins, int & startingBin) const {
00436
00437 if(subdet == HcalBarrel) {
00438 if (mode_==HcalTopologyMode::SLHC || mode_==HcalTopologyMode::H2HE) {
00439 startingBin = 1;
00440 if (etaRing==lastHBRing()) {
00441 nDepthBins = 2;
00442 } else {
00443 nDepthBins = maxDepthHB_;
00444 }
00445 } else {
00446 if (etaRing<=14) {
00447 nDepthBins = 1;
00448 startingBin = 1;
00449 } else {
00450 nDepthBins = 2;
00451 startingBin = 1;
00452 }
00453 }
00454 } else if(subdet == HcalEndcap) {
00455 if (mode_==HcalTopologyMode::SLHC || mode_==HcalTopologyMode::H2HE) {
00456 if (etaRing==firstHERing()) {
00457 nDepthBins = maxDepthHE_ - 2;
00458 startingBin = 3;
00459 } else {
00460 nDepthBins = maxDepthHE_;
00461 startingBin = 1;
00462 }
00463 } else {
00464 if (etaRing==firstHERing()) {
00465 nDepthBins = 1;
00466 startingBin = 3;
00467 } else if (etaRing==17) {
00468 nDepthBins = 1;
00469 startingBin = 1;
00470 } else if (etaRing==lastHERing()) {
00471 nDepthBins = 2;
00472 startingBin = 1;
00473 } else {
00474 nDepthBins = (etaRing >= firstHETripleDepthRing()) ? 3 : 2;
00475 startingBin = 1;
00476 }
00477 }
00478 } else if(subdet == HcalForward) {
00479 nDepthBins = 2;
00480 startingBin = 1;
00481 } else if(subdet == HcalOuter) {
00482 nDepthBins = 1;
00483 startingBin = 4;
00484 } else {
00485 std::cerr << "Bad HCAL subdetector " << subdet << std::endl;
00486 }
00487 }
00488
00489
00490 bool HcalTopology::incrementDepth(HcalDetId & detId) const
00491 {
00492 HcalSubdetector subdet = detId.subdet();
00493 int ieta = detId.ieta();
00494 int etaRing = detId.ietaAbs();
00495 int depth = detId.depth();
00496 int nDepthBins, startingBin;
00497 depthBinInformation(subdet, etaRing, nDepthBins, startingBin);
00498
00499
00500 ++depth;
00501 if(depth > nDepthBins) {
00502
00503 if(subdet == HcalBarrel && etaRing < lastHORing()) {
00504
00505 subdet = HcalOuter;
00506 depth = 4;
00507 } else if(subdet == HcalBarrel && etaRing == lastHBRing()) {
00508
00509 subdet = HcalEndcap;
00510 } else if(subdet == HcalEndcap && etaRing == lastHERing()-1) {
00511
00512 subdet = HcalForward;
00513 (ieta > 0) ? ++ieta : --ieta;
00514 depth = 1;
00515 } else if(subdet == HcalEndcap && etaRing == lastHERing()) {
00516
00517 (ieta > 0) ? --ieta : ++ieta;
00518 } else {
00519
00520 detId = HcalDetId();
00521 return false;
00522 }
00523 }
00524 detId = HcalDetId(subdet, ieta, detId.iphi(), depth);
00525
00526
00527 return validRaw(detId);
00528
00529 }
00530
00531
00532 int HcalTopology::nPhiBins(int etaRing) const {
00533 int lastPhiBin=singlePhiBins_;
00534 if (etaRing>= firstHFQuadPhiRing()) lastPhiBin=doublePhiBins_/2;
00535 else if (etaRing>= firstHEDoublePhiRing()) lastPhiBin=doublePhiBins_;
00536 return lastPhiBin;
00537 }
00538
00539 void HcalTopology::getDepthSegmentation(unsigned ring, std::vector<int> & readoutDepths) const
00540 {
00541
00542
00543 SegmentationMap::const_iterator pos = depthSegmentation_.upper_bound(ring);
00544 if(pos == depthSegmentation_.begin()) {
00545 throw cms::Exception("HcalTopology") << "No depth segmentation found for ring" << ring;
00546 }
00547 --pos;
00548
00549 readoutDepths = pos->second;
00550 }
00551
00552 void HcalTopology::setDepthSegmentation(unsigned ring, const std::vector<int> & readoutDepths)
00553 {
00554 depthSegmentation_[ring] = readoutDepths;
00555 }
00556
00557 std::pair<int, int> HcalTopology::segmentBoundaries(unsigned ring, unsigned depth) const {
00558 std::vector<int> readoutDepths;
00559 getDepthSegmentation(ring, readoutDepths);
00560 int d1 = std::lower_bound(readoutDepths.begin(), readoutDepths.end(), depth) - readoutDepths.begin();
00561 int d2 = std::upper_bound(readoutDepths.begin(), readoutDepths.end(), depth) - readoutDepths.begin();
00562 return std::pair<int, int>(d1, d2);
00563 }
00564
00565 unsigned int HcalTopology::detId2denseIdPreLS1 (const DetId& id) const {
00566
00567 HcalDetId hid(id);
00568 const HcalSubdetector sd (hid.subdet() ) ;
00569 const int ip (hid.iphi() ) ;
00570 const int ie (hid.ietaAbs() ) ;
00571 const int dp (hid.depth() ) ;
00572 const int zn (hid.zside() < 0 ? 1 : 0 ) ;
00573 unsigned int retval = ( ( sd == HcalBarrel ) ?
00574 ( ip - 1 )*18 + dp - 1 + ie - ( ie<16 ? 1 : 0 ) + zn*kHBhalf :
00575 ( ( sd == HcalEndcap ) ?
00576 2*kHBhalf + ( ip - 1 )*8 + ( ip/2 )*20 +
00577 ( ( ie==16 || ie==17 ) ? ie - 16 :
00578 ( ( ie>=18 && ie<=20 ) ? 2 + 2*( ie - 18 ) + dp - 1 :
00579 ( ( ie>=21 && ie<=26 ) ? 8 + 2*( ie - 21 ) + dp - 1 :
00580 ( ( ie>=27 && ie<=28 ) ? 20 + 3*( ie - 27 ) + dp - 1 :
00581 26 + 2*( ie - 29 ) + dp - 1 ) ) ) ) + zn*kHEhalf :
00582 ( ( sd == HcalOuter ) ?
00583 2*kHBhalf + 2*kHEhalf + ( ip - 1 )*15 + ( ie - 1 ) + zn*kHOhalf :
00584 ( ( sd == HcalForward ) ?
00585 2*kHBhalf + 2*kHEhalf + 2*kHOhalf +
00586 ( ( ip - 1 )/4 )*4 + ( ( ip - 1 )/2 )*22 +
00587 2*( ie - 29 ) + ( dp - 1 ) + zn*kHFhalf : 0xFFFFFFFFu ) ) ) ) ;
00588 return retval;
00589 }
00590
00591
00592 unsigned int HcalTopology::detId2denseIdHB(const DetId& id) const {
00593 HcalDetId hid(id);
00594 const int ip (hid.iphi() ) ;
00595 const int ie (hid.ietaAbs() ) ;
00596 const int dp (hid.depth() ) ;
00597 const int zn (hid.zside() < 0 ? 1 : 0 ) ;
00598 unsigned int retval = 0xFFFFFFFFu;
00599 if (topoVersion_==0) {
00600 retval=( ip - 1 )*18 + dp - 1 + ie - ( ie<16 ? 1 : 0 ) + zn*kHBhalf;
00601 } else if (topoVersion_==10) {
00602 retval=dp-1 + maxDepthHB_*(ip-1)+maxDepthHB_*72*(hid.ieta()-1+33*zn);
00603 }
00604 return retval;
00605 }
00606
00607 unsigned int HcalTopology::detId2denseIdHE(const DetId& id) const {
00608 HcalDetId hid(id);
00609 const int ip (hid.iphi() ) ;
00610 const int ie (hid.ietaAbs() ) ;
00611 const int dp (hid.depth() ) ;
00612 const int zn (hid.zside() < 0 ? 1 : 0 ) ;
00613 unsigned int retval = 0xFFFFFFFFu;
00614 if (topoVersion_==0) {
00615 retval=( ip - 1 )*8 + ( ip/2 )*20 +
00616 ( ( ie==16 || ie==17 ) ? ie - 16 :
00617 ( ( ie>=18 && ie<=20 ) ? 2 + 2*( ie - 18 ) + dp - 1 :
00618 ( ( ie>=21 && ie<=26 ) ? 8 + 2*( ie - 21 ) + dp - 1 :
00619 ( ( ie>=27 && ie<=28 ) ? 20 + 3*( ie - 27 ) + dp - 1 :
00620 26 + 2*( ie - 29 ) + dp - 1 ) ) ) ) + zn*kHEhalf;
00621 } else if (topoVersion_==10) {
00622 retval=(dp-1)+maxDepthHE_*(ip-1)+maxDepthHE_*72*(hid.ieta()-16+zn*(14+29+16));
00623 }
00624 return retval;
00625 }
00626
00627 unsigned int HcalTopology::detId2denseIdHO(const DetId& id) const {
00628 HcalDetId hid(id);
00629 const int ip (hid.iphi() ) ;
00630 const int ie (hid.ietaAbs() ) ;
00631 const int zn (hid.zside() < 0 ? 1 : 0 ) ;
00632
00633 unsigned int retval = 0xFFFFFFFFu;
00634 if (topoVersion_==0) {
00635 retval=( ip - 1 )*15 + ( ie - 1 ) + zn*kHOhalf;
00636 } else if (topoVersion_==10) {
00637 retval=( ip - 1 )*15 + ( ie - 1 ) + zn*kHOhalf;
00638 }
00639 return retval;
00640 }
00641
00642 unsigned int HcalTopology::detId2denseIdHF(const DetId& id) const {
00643 HcalDetId hid(id);
00644 const int ip (hid.iphi() ) ;
00645 const int ie (hid.ietaAbs() ) ;
00646 const int dp (hid.depth() ) ;
00647 const int zn (hid.zside() < 0 ? 1 : 0 ) ;
00648
00649 unsigned int retval = 0xFFFFFFFFu;
00650 if (topoVersion_==0) {
00651 retval = ( ( ip - 1 )/4 )*4 + ( ( ip - 1 )/2 )*22 +
00652 2*( ie - 29 ) + ( dp - 1 ) + zn*kHFhalf;
00653 } else if (topoVersion_==10) {
00654 retval = ( ( ip - 1 )/4 )*4 + ( ( ip - 1 )/2 )*22 +
00655 2*( ie - 29 ) + ( dp - 1 ) + zn*kHFhalf;
00656 }
00657 return retval;
00658 }
00659
00660 unsigned int HcalTopology::detId2denseIdHT(const DetId& id) const {
00661 HcalTrigTowerDetId tid(id);
00662 int zside = tid.zside();
00663 unsigned int ietaAbs = tid.ietaAbs();
00664 unsigned int iphi = tid.iphi();
00665
00666 unsigned int index;
00667 if ((iphi-1)%4==0) index = (iphi-1)*32 + (ietaAbs-1) - (12*((iphi-1)/4));
00668 else index = (iphi-1)*28 + (ietaAbs-1) + (4*(((iphi-1)/4)+1));
00669
00670 if (zside == -1) index += kHThalf;
00671
00672 return index;
00673 }
00674
00675 unsigned int HcalTopology::detId2denseIdCALIB(const DetId& id) const {
00676 HcalCalibDetId tid(id);
00677 int channel = tid.cboxChannel();
00678 int ieta = tid.ieta();
00679 int iphi = tid.iphi();
00680 int zside = tid.zside();
00681 unsigned int index=0xFFFFFFFFu;
00682
00683 if (tid.calibFlavor()==HcalCalibDetId::CalibrationBox) {
00684
00685 HcalSubdetector subDet = tid.hcalSubdet();
00686
00687 if (subDet==HcalBarrel) {
00688
00689
00690
00691 index = ((iphi+1)/4-1) + 18*channel + 27*(ieta+1);
00692 } else if (subDet==HcalEndcap) {
00693
00694
00695
00696 if (channel>2) channel-=1;
00697 index = ((iphi+1)/4-1) + 18*channel + 54*(ieta+1) + 108;
00698 } else if (subDet==HcalForward) {
00699
00700
00701 if (channel==8) channel = 2;
00702
00703 index = (iphi-1)/18 + 4*channel + 6*(ieta+1) + 324;
00704 } else if (subDet==HcalOuter) {
00705
00706
00707 if (channel==7) {
00708 channel = 2;
00709 index = (ieta+2) + 420;
00710
00711
00712 } else{
00713 if (ieta<0) index = ((iphi+1)/12-1) + 36*channel + 6*(ieta+2) + 348;
00714 else if (ieta>0) index = ((iphi+1)/12-1) + 36*channel + 6*(ieta+2) + 6 + 348;
00715 else index = ((iphi+1)/6-1) + 36*channel + 6*(ieta+2) + 348;
00716 }
00717 } else {
00718 std::cout << "HCAL Det Id not valid!" << std::endl;
00719 index = 0;
00720 }
00721
00722 } else if (tid.calibFlavor()==HcalCalibDetId::HOCrosstalk) {
00723
00724
00725
00726 if (abs(ieta)==4) index = ((iphi-1)%36) + (((zside+1)*36)/2) + 72 + 425;
00727 else index = (iphi-1) + (36*(zside+1)*2) + 425;
00728 }
00729
00730 return index;
00731 }
00732
00733
00734 unsigned int HcalTopology::detId2denseId(const DetId& id) const {
00735 unsigned int retval(0);
00736 if (topoVersion_==0) {
00737 retval = detId2denseIdPreLS1(id);
00738 } else if (topoVersion_==10) {
00739 HcalDetId hid(id);
00740 if (hid.subdet()==HcalBarrel) {
00741 retval=(hid.depth()-1)+maxDepthHB_*(hid.iphi()-1);
00742 if (hid.ieta()>0) {
00743 retval+=maxDepthHB_*72*(hid.ieta()-1);
00744 } else {
00745 retval+=maxDepthHB_*72*(32+hid.ieta());
00746 }
00747 } else if (hid.subdet()==HcalEndcap) {
00748 retval=HBSize_;
00749 retval+=(hid.depth()-1)+maxDepthHE_*(hid.iphi()-1);
00750 if (hid.ieta()>0) {
00751 retval+=maxDepthHE_*72*(hid.ieta()-16);
00752 } else {
00753 retval+=maxDepthHE_*72*((14+29)+hid.ieta());
00754 }
00755 } else if (hid.subdet()==HcalOuter) {
00756 retval=HBSize_+HESize_;
00757 if (hid.ieta()>0) retval+=(hid.iphi()-1)+72*(hid.ieta()-1);
00758 else retval+=(hid.iphi()-1)+72*(30+hid.ieta());
00759 } else if (hid.subdet()==HcalForward) {
00760 retval=HBSize_+HESize_+HOSize_;
00761 retval+=hid.depth()-1+2*(hid.iphi()-1);
00762 if (hid.ieta()>0) retval+=2*72*(hid.ieta()-29);
00763 else retval+=2*72*((41+13)+hid.ieta());
00764 } else {
00765 return 0xFFFFFFFu;
00766 }
00767 }
00768 return retval;
00769 }
00770
00771 DetId HcalTopology::denseId2detId(unsigned int denseid) const {
00772
00773 HcalSubdetector sd ( HcalBarrel ) ;
00774 int ie ( 0 ) ;
00775 int ip ( 0 ) ;
00776 int dp ( 0 ) ;
00777 int in ( denseid ) ;
00778 int iz ( 1 ) ;
00779 if (topoVersion_==0) {
00780 if (denseid < kSizeForDenseIndexingPreLS1) {
00781 if ( in > 2*( kHBhalf + kHEhalf + kHOhalf ) - 1 ) {
00782 sd = HcalForward ;
00783 in -= 2*( kHBhalf + kHEhalf + kHOhalf ) ;
00784 iz = ( in<kHFhalf ? 1 : -1 ) ;
00785 in %= kHFhalf ;
00786 ip = 4*( in/48 ) ;
00787 in %= 48 ;
00788 ip += 1 + ( in>21 ? 2 : 0 ) ;
00789 if( 3 == ip%4 ) in -= 22 ;
00790 ie = 29 + in/2 ;
00791 dp = 1 + in%2 ;
00792 } else if ( in > 2*( kHBhalf + kHEhalf ) - 1 ) {
00793 sd = HcalOuter ;
00794 in -= 2*( kHBhalf + kHEhalf ) ;
00795 iz = ( in<kHOhalf ? 1 : -1 ) ;
00796 in %= kHOhalf ;
00797 dp = 4 ;
00798 ip = 1 + in/15 ;
00799 ie = 1 + ( in - 15*( ip - 1 ) ) ;
00800 } else if ( in > 2*kHBhalf - 1 ) {
00801 sd = HcalEndcap ;
00802 in -= 2*kHBhalf ;
00803 iz = ( in<kHEhalf ? 1 : -1 ) ;
00804 in %= kHEhalf ;
00805 ip = 2*( in/36 ) ;
00806 in %= 36 ;
00807 ip += 1 + in/28 ;
00808 if( 0 == ip%2 ) in %= 28 ;
00809 ie = 15 + ( in<2 ? 1 + in : 2 +
00810 ( in<20 ? 1 + ( in - 2 )/2 : 9 +
00811 ( in<26 ? 1 + ( in - 20 )/3 : 3 ) ) ) ;
00812 dp = ( in<1 ? 3 :
00813 ( in<2 ? 1 :
00814 ( in<20 ? 1 + ( in - 2 )%2 :
00815 ( in<26 ? 1 + ( in - 20 )%3 :
00816 ( 1 + ( in - 26 )%2 ) ) ) ) ) ;
00817 } else {
00818 iz = ( in<kHBhalf ? 1 : -1 ) ;
00819 in %= kHBhalf ;
00820 ip = in/18 + 1 ;
00821 in %= 18 ;
00822 if ( in < 14 ) {
00823 dp = 1 ;
00824 ie = in + 1 ;
00825 } else {
00826 in %= 14 ;
00827 dp = 1 + in%2 ;
00828 ie = 15 + in/2 ;
00829 }
00830 }
00831 }
00832 } else if (topoVersion_==10) {
00833 if (denseid < ncells()) {
00834 if (denseid >= (HBSize_+HESize_+HOSize_)) {
00835 sd = HcalForward ;
00836 in -= (HBSize_+HESize_+HOSize_);
00837 dp = (in%2) + 1;
00838 ip = (in - dp + 1)%144;
00839 ip = (ip/2) + 1;
00840 ie = (in - dp + 1 - 2*(ip -1))/144;
00841 if (ie > 12) {ie = 54 -ie; iz = -1;}
00842 else {ie += 29; iz = 1;}
00843 } else if (denseid >= (HBSize_+HESize_)) {
00844 sd = HcalOuter ;
00845 in -= (HBSize_+HESize_);
00846 dp = 4;
00847 ip = (in%72) + 1;
00848 ie = (in - ip + 1)/72;
00849 if (ie > 14) {ie = 30 -ie; iz = -1;}
00850 else {ie += 1; iz = 1;}
00851 } else if (denseid >= (HBSize_)) {
00852 sd = HcalEndcap ;
00853 in -= (HBSize_);
00854 dp = (in%maxDepthHE_)+1;
00855 ip = (in - dp + 1)%(maxDepthHE_*72);
00856 ip = (ip/maxDepthHE_) + 1;
00857 ie = (in - dp + 1 - maxDepthHE_*(ip-1))/(72*maxDepthHE_);
00858 if (ie > 13) {ie = 43 - ie; iz = -1;}
00859 else {ie += 16; iz = 1;}
00860 } else {
00861 sd = HcalBarrel ;
00862 dp = (in%maxDepthHB_)+1;
00863 ip = (in - dp + 1)%(maxDepthHB_*72);
00864 ip = (ip/maxDepthHB_) + 1;
00865 ie = (in - dp + 1 - maxDepthHB_*(ip-1))/(72*maxDepthHB_);
00866 if (ie > 15) {ie = 32 - ie; iz = -1;}
00867 else {ie += 1; iz = 1;}
00868 }
00869 }
00870 }
00871 return HcalDetId( sd, iz*int(ie), ip, dp );
00872 }
00873
00874 unsigned int HcalTopology::ncells() const {
00875 return HBSize_+HESize_+HOSize_+HFSize_;
00876 }
00877
00878 int HcalTopology::topoVersion() const {
00879 return topoVersion_;
00880 }