CMS 3D CMS Logo

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