CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/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 
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   std::vector<DetId> vNeighborsDetId;
00078   HcalDetId neighbors[2];
00079   for (int i=0;i<decIEta(HcalDetId(id),neighbors);i++)
00080     vNeighborsDetId.push_back(DetId(neighbors[i].rawId()));
00081   return vNeighborsDetId;
00082 }
00083 
00084 std::vector<DetId> HcalTopology::west(const DetId& id) const {
00085   std::vector<DetId> vNeighborsDetId;
00086   HcalDetId neighbors[2];
00087   for (int i=0;i<incIEta(HcalDetId(id),neighbors);i++)
00088     vNeighborsDetId.push_back(DetId(neighbors[i].rawId()));
00089   return  vNeighborsDetId;
00090 }
00091 
00092 std::vector<DetId> HcalTopology::north(const DetId& id) const {
00093   std::vector<DetId> vNeighborsDetId;
00094   HcalDetId neighbor;
00095   if (incIPhi(HcalDetId(id),neighbor))
00096     vNeighborsDetId.push_back(DetId(neighbor.rawId()));
00097   return  vNeighborsDetId;
00098 }
00099 
00100 std::vector<DetId> HcalTopology::south(const DetId& id) const {
00101   std::vector<DetId> vNeighborsDetId;
00102   HcalDetId neighbor;
00103   if (decIPhi(HcalDetId(id),neighbor))
00104     vNeighborsDetId.push_back(DetId(neighbor.rawId()));
00105   return  vNeighborsDetId;
00106 }
00107 
00108 std::vector<DetId> HcalTopology::up(const DetId& id) const {
00109   HcalDetId neighbor = id;
00110   //A.N.
00111   //  incrementDepth(neighbor);
00112   std::vector<DetId> vNeighborsDetId;
00113   if(incrementDepth(neighbor)) 
00114   {
00115     vNeighborsDetId.push_back(neighbor);
00116   }
00117   return  vNeighborsDetId;
00118 }
00119 
00120 std::vector<DetId> HcalTopology::down(const DetId& id) const {
00121   std::cout << "HcalTopology::down() not yet implemented" << std::endl; 
00122   std::vector<DetId> vNeighborsDetId;
00123   return  vNeighborsDetId;
00124 }
00125 
00126 int HcalTopology::exclude(HcalSubdetector subdet, int ieta1, int ieta2, int iphi1, int iphi2, int depth1, int depth2) {
00127 
00128   bool exed=false;
00129   // first, check the full detector exclusions...  (fast)
00130   switch (subdet) {
00131   case(HcalBarrel): exed=excludeHB_; break;
00132   case(HcalEndcap): exed=excludeHE_; break;
00133   case(HcalOuter): exed=excludeHO_; break;
00134   case(HcalForward): exed=excludeHF_; break;
00135   default: exed=false;
00136   }
00137   if (exed) return 0; // if the whole detector is excluded...
00138 
00139   int ieta_l=std::min(ieta1,ieta2);
00140   int ieta_h=std::max(ieta1,ieta2);
00141   int iphi_l=std::min(iphi1,iphi2);
00142   int iphi_h=std::max(iphi1,iphi2);
00143   int depth_l=std::min(depth1,depth2);
00144   int depth_h=std::max(depth1,depth2);
00145 
00146   int n=0;
00147   for (int ieta=ieta_l; ieta<=ieta_h; ieta++) 
00148     for (int iphi=iphi_l; iphi<=iphi_h; iphi++) 
00149       for (int depth=depth_l; depth<=depth_h; depth++) {
00150         HcalDetId id(subdet,ieta,iphi,depth);
00151         if (validRaw(id)) { // use 'validRaw' to include check validity in "uncut" detector
00152           exclude(id);  
00153           n++;
00154         }
00155       }
00156   return n;
00157 }
00158 
00186 bool HcalTopology::validRaw(const HcalDetId& id) const {
00187   bool ok=true;
00188   int ieta=id.ieta();
00189   int aieta=id.ietaAbs();
00190   int depth=id.depth();
00191   int iphi=id.iphi();
00192 
00193   if ((ieta==0 || iphi<=0 || iphi>IPHI_MAX) || aieta>41) return false; // outer limits
00194     
00195   if (ok) {
00196     HcalSubdetector subdet=id.subdet();
00197     if (subdet==HcalBarrel) {
00198       if (aieta>16 || depth>2 || (aieta<=14 && depth>1)) ok=false;          
00199     } else if (subdet==HcalEndcap) {
00200       if (depth>3 || aieta<16 || aieta>lastHERing() ||
00201           (aieta==16 && depth!=3) ||
00202           (aieta==17 && depth!=1 && !h2mode_) || // special case at H2
00203           (((aieta>=17 && aieta<firstHETripleDepthRing()) || aieta==29) && depth>2) ||
00204           (aieta>=firstHEDoublePhiRing() && (iphi%2)==0)) ok=false;
00205     } else if (subdet==HcalOuter) {
00206       if (aieta>15 || iphi>IPHI_MAX || depth!=4) ok=false;
00207     } else if (subdet==HcalForward) {
00208       if (aieta<firstHFRing() || aieta>lastHFRing() ||
00209           ((iphi%2)==0) ||
00210           (depth>2) ||
00211           (aieta>=firstHFQuadPhiRing() && ((iphi+1)%4)!=0)) ok=false;
00212     } else ok=false;
00213   }
00214     
00215   return ok;
00216 }
00217 
00218   
00219 bool HcalTopology::incIPhi(const HcalDetId& id, HcalDetId &neighbor) const {
00220   bool ok=valid(id);
00221   if (ok) {
00222     switch (id.subdet()) {
00223     case (HcalBarrel):
00224     case (HcalOuter):
00225       if (id.iphi()==IPHI_MAX) neighbor=HcalDetId(id.subdet(),id.ieta(),1,id.depth()); 
00226       else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()+1,id.depth()); 
00227       break;
00228     case (HcalEndcap):
00229       if (id.ietaAbs()>=firstHEDoublePhiRing()) {
00230         if (id.iphi()==IPHI_MAX-1) neighbor=HcalDetId(id.subdet(),id.ieta(),1,id.depth()); 
00231         else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()+2,id.depth()); 
00232       } else {
00233         if (id.iphi()==IPHI_MAX) neighbor=HcalDetId(id.subdet(),id.ieta(),1,id.depth()); 
00234         else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()+1,id.depth()); 
00235       } 
00236       break;
00237     case (HcalForward):
00238       if (id.ietaAbs()>=firstHFQuadPhiRing()) {
00239         if (id.iphi()==IPHI_MAX-1) neighbor=HcalDetId(id.subdet(),id.ieta(),3,id.depth()); 
00240         else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()+4,id.depth()); 
00241       } else {
00242         if (id.iphi()==IPHI_MAX-1) neighbor=HcalDetId(id.subdet(),id.ieta(),1,id.depth()); 
00243         else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()+2,id.depth()); 
00244       }
00245       break;
00246     default: ok=false;
00247     }
00248   } 
00249   return ok;
00250 }
00251 
00253 bool HcalTopology::decIPhi(const HcalDetId& id, HcalDetId &neighbor) const {
00254   bool ok=valid(id);
00255   if (ok) {
00256     switch (id.subdet()) {
00257     case (HcalBarrel):
00258     case (HcalOuter):
00259       if (id.iphi()==1) neighbor=HcalDetId(id.subdet(),id.ieta(),IPHI_MAX,id.depth()); 
00260       else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()-1,id.depth()); 
00261       break;
00262     case (HcalEndcap):
00263       if (id.ietaAbs()>=firstHEDoublePhiRing()) {
00264         if (id.iphi()==1) neighbor=HcalDetId(id.subdet(),id.ieta(),IPHI_MAX-1,id.depth()); 
00265         else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()-2,id.depth()); 
00266       } else {
00267         if (id.iphi()==1) neighbor=HcalDetId(id.subdet(),id.ieta(),IPHI_MAX,id.depth()); 
00268         else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()-1,id.depth()); 
00269       }
00270       break;
00271     case (HcalForward):
00272       if (id.ietaAbs()>=firstHFQuadPhiRing()) {
00273         if (id.iphi()==3) neighbor=HcalDetId(id.subdet(),id.ieta(),IPHI_MAX-1,id.depth()); 
00274         else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()-4,id.depth()); 
00275       } else {
00276         if (id.iphi()==1) neighbor=HcalDetId(id.subdet(),id.ieta(),IPHI_MAX-1,id.depth()); 
00277         else neighbor=HcalDetId(id.subdet(),id.ieta(),id.iphi()-2,id.depth()); 
00278       }
00279       break;
00280     default: ok=false;
00281     }
00282   } 
00283   return ok;
00284 }
00285 
00286 int HcalTopology::incIEta(const HcalDetId& id, HcalDetId neighbors[2]) const {
00287   if (id.zside()==1) return incAIEta(id,neighbors);
00288   else return decAIEta(id,neighbors);
00289 }
00290 
00291 int HcalTopology::decIEta(const HcalDetId& id, HcalDetId neighbors[2]) const {
00292   if (id.zside()==1) return decAIEta(id,neighbors);
00293   else return incAIEta(id,neighbors);
00294 }
00295 
00297 int HcalTopology::incAIEta(const HcalDetId& id, HcalDetId neighbors[2]) const {
00298   int n=1;
00299   int aieta=id.ietaAbs();
00300 
00301   if (aieta==firstHEDoublePhiRing()-1 && (id.iphi()%2)==0) 
00302     neighbors[0]=HcalDetId(HcalEndcap,(aieta+1)*id.zside(),id.iphi()-1,id.depth());
00303   else if (aieta==firstHFQuadPhiRing()-1 && ((id.iphi()+1)%4)!=0) 
00304     neighbors[0]=(id.iphi()==1)? HcalDetId(HcalForward,(aieta+1)*id.zside(),71,id.depth()) : HcalDetId(HcalForward,(aieta+1)*id.zside(),(id.iphi()-2),id.depth());
00305   else if (aieta==lastHBRing()) 
00306     neighbors[0]=HcalDetId(HcalEndcap,(aieta+1)*id.zside(),id.iphi(),1);
00307   else if (aieta==lastHERing()) 
00308     neighbors[0]=HcalDetId(HcalForward,(aieta+1)*id.zside(),id.iphi(),1);
00309   else
00310     neighbors[0]=HcalDetId(id.subdet(),(aieta+1)*id.zside(),id.iphi(),id.depth());
00311   
00312   if (!valid(neighbors[0])) n=0;
00313   return n;
00314 }
00315 
00317 int HcalTopology::decAIEta(const HcalDetId& id, HcalDetId neighbors[2]) const {
00318   int n=1;
00319   int aieta=id.ietaAbs();
00320 
00321   if (aieta==firstHEDoublePhiRing()) { 
00322     n=2;
00323     neighbors[0]=HcalDetId(HcalEndcap,(aieta-1)*id.zside(),id.iphi(),id.depth());
00324     neighbors[1]=HcalDetId(HcalEndcap,(aieta-1)*id.zside(),id.iphi()+1,id.depth());
00325   } else if (aieta==firstHFQuadPhiRing()) {
00326     n=2;
00327     neighbors[0]=HcalDetId(HcalForward,(aieta-1)*id.zside(),id.iphi(),id.depth());
00328     if (id.iphi()==IPHI_MAX-1) neighbors[1]=HcalDetId(HcalForward,(aieta-1)*id.zside(),1,id.depth());
00329     else neighbors[1]=HcalDetId(HcalForward,(aieta-1)*id.zside(),id.iphi()+2,id.depth());
00330   } else if (aieta==1) {
00331     neighbors[0]=HcalDetId(id.subdet(),-aieta*id.zside(),id.iphi(),id.depth());
00332   } else if (aieta==lastHBRing()+1) {
00333     neighbors[0]=HcalDetId(HcalBarrel,(aieta-1)*id.zside(),id.iphi(),id.depth());
00334   } else if (aieta==lastHERing()+1) {
00335     neighbors[0]=HcalDetId(HcalEndcap,(aieta-1)*id.zside(),id.iphi(),id.depth());
00336   } else
00337     neighbors[0]=HcalDetId(id.subdet(),(aieta-1)*id.zside(),id.iphi(),id.depth());
00338   
00339   if (!valid(neighbors[0]) && n==2) {
00340     if (!valid(neighbors[1])) n=0;
00341     else {
00342       n=1;
00343       neighbors[0]=neighbors[1];
00344     }
00345   }
00346   if (n==2 && !valid(neighbors[1])) n=1;
00347   if (n==1 && !valid(neighbors[0])) n=0;
00348 
00349   return n;
00350 }
00351 
00352 
00353 void HcalTopology::depthBinInformation(HcalSubdetector subdet, int etaRing,
00354                                        int & nDepthBins, int & startingBin) const {
00355   if(subdet == HcalBarrel) {
00356     if (etaRing<=14) {
00357       nDepthBins = 1;
00358       startingBin = 1;
00359     } else {
00360       nDepthBins = 2;
00361       startingBin = 1;
00362     }
00363   } else if(subdet == HcalEndcap) {
00364     if (etaRing==16) {
00365       nDepthBins = 1;
00366       startingBin = 3;
00367     } else if (etaRing==17) {
00368       nDepthBins = 1;
00369       startingBin = 1;
00370     } else if (etaRing==lastHERing()) {
00371       nDepthBins = 2;
00372       startingBin = 1;
00373     }
00374     else {
00375       nDepthBins = (etaRing >= firstHETripleDepthRing()) ? 3 : 2;
00376       startingBin = 1;
00377     }
00378   }
00379 
00380   else if(subdet == HcalForward) {
00381     nDepthBins = 2;
00382     startingBin = 1;
00383   }
00384 
00385   else if(subdet == HcalOuter) {
00386     nDepthBins = 1;
00387     startingBin = 4;
00388   }
00389 
00390   else {
00391     std::cerr << "Bad HCAL subdetector " << subdet << std::endl;
00392   }
00393 }
00394 
00395 
00396 bool HcalTopology::incrementDepth(HcalDetId & detId) const
00397 {
00398   HcalSubdetector subdet = detId.subdet();
00399   int ieta = detId.ieta();
00400   int etaRing = detId.ietaAbs();
00401   int depth = detId.depth();
00402   int nDepthBins, startingBin;
00403   depthBinInformation(subdet, etaRing, nDepthBins, startingBin);
00404 
00405   // see if the new depth bin exists
00406   ++depth;
00407   if(depth > nDepthBins)
00408   {
00409     // handle on a case-by-case basis
00410     if(subdet == HcalBarrel && etaRing < lastHORing())
00411     {
00412       // HO
00413       subdet = HcalOuter;
00414       depth = 4;
00415     }
00416     else if(subdet == HcalBarrel && etaRing == lastHBRing())
00417     {
00418       // overlap
00419       subdet = HcalEndcap;
00420     }
00421     else if(subdet == HcalEndcap && etaRing ==  lastHERing()-1)
00422     {
00423       // guard ring HF29 is behind HE 28
00424       subdet = HcalForward;
00425       (ieta > 0) ? ++ieta : --ieta;
00426       depth = 1;
00427     }
00428     else if(subdet == HcalEndcap && etaRing ==  lastHERing())
00429     {
00430       // split cells go to bigger granularity.  Ring 29 -> 28
00431       (ieta > 0) ? --ieta : ++ieta;
00432     }
00433     else 
00434     {
00435       // no more chances
00436       detId = HcalDetId();
00437       return false;
00438     }
00439   }
00440   detId = HcalDetId(subdet, ieta, detId.iphi(), depth);
00441   //A.N.  
00442   // assert(validRaw(detId));
00443   return validRaw(detId);
00444   //A.N.  return true;
00445 }
00446 
00447 
00448 int HcalTopology::nPhiBins(int etaRing) const {
00449   int lastPhiBin=singlePhiBins_;
00450   if (etaRing>= firstHFQuadPhiRing()) lastPhiBin=doublePhiBins_/2;
00451   else if (etaRing>= firstHEDoublePhiRing()) lastPhiBin=doublePhiBins_;
00452   return lastPhiBin;
00453 }
00454 
00455 
00456