00001 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00002 #include "Geometry/HcalTowerAlgo/interface/HcalGeometry.h"
00003 #include "Geometry/HcalTowerAlgo//src/HcalHardcodeGeometryData.h"
00004
00005 HcalGeometry::HcalGeometry(const HcalTopology * topology)
00006 : theTopology(topology),
00007 lastReqDet_(DetId::Detector(0)),
00008 lastReqSubdet_(0)
00009 {
00010 }
00011
00012
00013 HcalGeometry::~HcalGeometry()
00014 {
00015 }
00016
00017
00018 std::vector<DetId> const & HcalGeometry::getValidDetIds(DetId::Detector det, int subdet) const {
00019 if (lastReqDet_!=det || lastReqSubdet_!=subdet) {
00020 lastReqDet_=det;
00021 lastReqSubdet_=subdet;
00022 m_validIds.clear();
00023 }
00024 if (m_validIds.empty()) {
00025 m_validIds.reserve(cellGeometries().size());
00026 CaloSubdetectorGeometry::CellCont::const_iterator i;
00027 for (i=cellGeometries().begin(); i!=cellGeometries().end(); i++) {
00028 DetId id(i->first);
00029 if (id.det()==det && id.subdetId()==subdet)
00030 m_validIds.push_back(id);
00031 }
00032 std::sort(m_validIds.begin(),m_validIds.end());
00033 }
00034
00035 return m_validIds;
00036 }
00037
00038
00039 DetId HcalGeometry::getClosestCell(const GlobalPoint& r) const
00040 {
00041
00042
00043 double abseta = fabs(r.eta());
00044
00045
00046 HcalSubdetector bc= HcalEmpty;
00047 if( abseta <= theHBHEEtaBounds[theTopology->lastHBRing()] )
00048 {
00049 bc = HcalBarrel;
00050 }
00051 else if( abseta <= theHBHEEtaBounds[theTopology->lastHERing()] )
00052 {
00053 bc = HcalEndcap;
00054 }
00055 else
00056 {
00057 bc = HcalForward;
00058 }
00059
00060 if (bc == HcalForward) {
00061 static const double z_long=1100.0;
00062 static const double z_short=1120.0;
00063
00064 double radius=sqrt(pow(r.x(),2)+pow(r.y(),2));
00065 double trueAeta=asinh(z_long/radius);
00066
00067 int etaring = etaRing(bc, trueAeta);
00068 if (etaring>theTopology->lastHFRing()) etaring=theTopology->lastHFRing();
00069
00070 int phibin = phiBin(r.phi(), etaring);
00071
00072
00073 int etabin = (r.z() > 0) ? etaring : -etaring;
00074 HcalDetId bestId(bc,etabin,phibin,((fabs(r.z())>=z_short)?(2):(1)));
00075 return bestId;
00076 } else {
00077
00078
00079 int etaring = etaRing(bc, abseta);
00080
00081 int phibin = phiBin(r.phi(), etaring);
00082
00083
00084 int etabin = (r.z() > 0) ? etaring : -etaring;
00085
00086
00087 int dbin = 1;
00088 double pointradius=r.mag();
00089 double dradius=99999.;
00090 HcalDetId currentId(bc, etabin, phibin, dbin);
00091 HcalDetId bestId;
00092 for( ; currentId != HcalDetId(); theTopology->incrementDepth(currentId))
00093 {
00094 const CaloCellGeometry * cell = getGeometry(currentId);
00095 assert(cell != 0);
00096 double radius=cell->getPosition().mag();
00097 if(fabs(pointradius-radius)<dradius)
00098 {
00099 bestId = currentId;
00100 dradius=fabs(pointradius-radius);
00101 }
00102 }
00103
00104 return bestId;
00105 }
00106 }
00107
00108
00109 int HcalGeometry::etaRing(HcalSubdetector bc, double abseta) const
00110 {
00111 int etaring;
00112 if( bc == HcalForward ) {
00113 for(etaring = theTopology->firstHFRing();
00114 etaring <= theTopology->lastHFRing(); ++etaring)
00115 {
00116 if(theHFEtaBounds[etaring-theTopology->firstHFRing()+1] > abseta) break;
00117 }
00118 }
00119 else
00120 {
00121 for(etaring = 1;
00122 etaring <= theTopology->lastHERing(); ++etaring)
00123 {
00124 if(theHBHEEtaBounds[etaring] >= abseta) break;
00125 }
00126 }
00127
00128 return etaring;
00129 }
00130
00131
00132 int HcalGeometry::phiBin(double phi, int etaring) const
00133 {
00134 double twopi = M_PI+M_PI;
00135
00136 if(phi<0.0) phi += twopi;
00137 int nphibins = theTopology->nPhiBins(etaring);
00138 int phibin= static_cast<int>(phi/twopi*nphibins)+1;
00139 int iphi;
00140
00141
00142
00143
00144
00145 if(etaring >= theTopology->firstHFQuadPhiRing())
00146 {
00147 phi+=(twopi/36);
00148 phibin=static_cast<int>(phi/twopi*nphibins);
00149 if (phibin==0) phibin=18;
00150 iphi=phibin*4-1;
00151 } else {
00152
00153 iphi=(phibin-1)*(72/nphibins) + 1;
00154 }
00155
00156 return iphi;
00157 }
00158