CMS 3D CMS Logo

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

Generated on Tue Jun 9 17:37:17 2009 for CMSSW by  doxygen 1.5.4