CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2/src/Geometry/CaloTopology/src/HcalTopology.cc

Go to the documentation of this file.
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; //DL
00043     HBSize_= kHBSizePreLS1; // qie-per-fiber * fiber/rm * rm/rbx * rbx/barrel * barrel/hcal
00044     HESize_= kHESizePreLS1; // qie-per-fiber * fiber/rm * rm/rbx * rbx/endcap * endcap/hcal
00045     HOSize_= kHOSizePreLS1; // ieta * iphi * 2
00046     HFSize_= kHFSizePreLS1; // phi * eta * depth * pm 
00047   } else if (mode_==HcalTopologyMode::SLHC) { // need to know more eventually
00048     HBSize_= maxDepthHB*16*72*2;
00049     HESize_= maxDepthHE*(29-16+1)*72*2;
00050     HOSize_= 15*72*2; // ieta * iphi * 2
00051     HFSize_= 72*13*2*2; // phi * eta * depth * pm 
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   // check the raw rules
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   // first, check the full detector exclusions...  (fast)
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   // next, check the list (slower)
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   //A.N.
00142   //  incrementDepth(neighbor);
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   // first, check the full detector exclusions...  (fast)
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; // if the whole detector is excluded...
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)) { // use 'validRaw' to include check validity in "uncut" detector
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; // outer limits
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) || // special case at 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   // see if the new depth bin exists
00500   ++depth;
00501   if(depth > nDepthBins) {
00502     // handle on a case-by-case basis
00503     if(subdet == HcalBarrel && etaRing < lastHORing())  {
00504       // HO
00505       subdet = HcalOuter;
00506       depth = 4;
00507     } else if(subdet == HcalBarrel && etaRing == lastHBRing()) {
00508       // overlap
00509       subdet = HcalEndcap;
00510     } else if(subdet == HcalEndcap && etaRing ==  lastHERing()-1) {
00511       // guard ring HF29 is behind HE 28
00512       subdet = HcalForward;
00513       (ieta > 0) ? ++ieta : --ieta;
00514       depth = 1;
00515     } else if(subdet == HcalEndcap && etaRing ==  lastHERing()) {
00516       // split cells go to bigger granularity.  Ring 29 -> 28
00517       (ieta > 0) ? --ieta : ++ieta;
00518     } else {
00519       // no more chances
00520       detId = HcalDetId();
00521       return false;
00522     }
00523   }
00524   detId = HcalDetId(subdet, ieta, detId.iphi(), depth);
00525   //A.N.  
00526   // assert(validRaw(detId));
00527   return validRaw(detId);
00528   //A.N.  return true;
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   // if it doesn't exist, return the first entry with a lower index.  So if we only
00542   // have entries for 1 and 17, any input from 1-16 should return the entry for ring 1
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     // pos now refers to the last element with key <= ring.
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       //std::cout<<"CALIB_HB:  ";
00689       //dphi = 4 (18 phi values), 3 channel types (0,1,2), eta = -1 or 1
00690       //total of 18*3*2=108 channels
00691       index = ((iphi+1)/4-1) + 18*channel + 27*(ieta+1);
00692     } else if (subDet==HcalEndcap) {
00693       //std::cout<<"CALIB_HE:  ";
00694       //dphi = 4 (18 phi values), 6 channel types (0,1,3,4,5,6), eta = -1 or 1
00695       //total of 18*6*2=216 channels
00696       if (channel>2) channel-=1;
00697       index = ((iphi+1)/4-1) + 18*channel + 54*(ieta+1) + 108;
00698     } else if (subDet==HcalForward) {
00699       //std::cout<<"CALIB_HF:  ";
00700       //dphi = 18 (4 phi values), 3 channel types (0,1,8), eta = -1 or 1
00701       if (channel==8) channel = 2;
00702       //total channels 4*3*2=24
00703       index = (iphi-1)/18 + 4*channel + 6*(ieta+1) + 324;
00704     } else if (subDet==HcalOuter) {
00705       //std::cout<<"CALIB_HO:  ";
00706       //there are 5 special calib crosstalk channels, one in each ring
00707       if (channel==7) {
00708         channel = 2;
00709         index = (ieta+2) + 420;
00710       //for HOM/HOP dphi = 6 (12 phi values),  2 channel types (0,1), eta = -2,-1 or 1,2
00711       //for HO0/YB0 dphi = 12 (6 phi values),  2 channel types (0,1), eta = 0
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     //std::cout<<"HX:  ";
00724     //for YB0/HO0 phi is grouped in 6 groups of 6 with dphi=2 but the transitions are 1 or 3
00725     // in such a way that the %36 operation yeilds unique values for every iphi
00726     if (abs(ieta)==4)  index = ((iphi-1)%36) + (((zside+1)*36)/2) + 72 + 425;   //ieta = 1 YB0/HO0;
00727     else               index = (iphi-1) + (36*(zside+1)*2) + 425;  //ieta = 0 for HO2M/HO1M ieta=2 for HO1P/HO2P;
00728   }
00729   //std::cout << "  " << ieta << "  " << zside << "  " << iphi << "  " << depth << "  " << index << std::endl;
00730   return index;
00731 }
00732 
00733 
00734 unsigned int HcalTopology::detId2denseId(const DetId& id) const {
00735   unsigned int retval(0);
00736   if (topoVersion_==0) { // pre-LS1
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) { //DL// pre-LS1
00780     if (denseid < kSizeForDenseIndexingPreLS1) {
00781       if ( in > 2*( kHBhalf + kHEhalf + kHOhalf ) - 1 ) { // HF
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 ) { // HO
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 ) { // Endcap
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 { // barrel
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 }