00001 #include "Geometry/HcalTowerAlgo/interface/HcalHardcodeGeometryLoader.h"
00002 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00003 #include "Geometry/CaloGeometry/interface/IdealObliquePrism.h"
00004 #include "Geometry/CaloGeometry/interface/IdealZPrism.h"
00005 #include "Geometry/HcalTowerAlgo/interface/HcalGeometry.h"
00006 #include "HcalHardcodeGeometryData.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 #include <algorithm>
00009
00010 typedef CaloCellGeometry::CCGFloat CCGFloat ;
00011
00012 HcalHardcodeGeometryLoader::HcalHardcodeGeometryLoader():
00013 theTopology ( new HcalTopology ),
00014 extTopology ( theTopology )
00015 {
00016 init();
00017 }
00018
00019 HcalHardcodeGeometryLoader::HcalHardcodeGeometryLoader(const HcalTopology& ht) :
00020 theTopology ( 0 ) ,
00021 extTopology ( &ht )
00022 {
00023 init();
00024 }
00025
00026 void
00027 HcalHardcodeGeometryLoader::init()
00028 {
00029 theBarrelRadius = 190.;
00030 theHBThickness = 93.6;
00031
00032 theHB15aThickness = theHBThickness * 12.0/17.0;
00033 theHB15bThickness = theHBThickness * 4.0/17.0;
00034 theHB16aThickness = theHBThickness * 1.0/17.0;
00035 theHB16bThickness = theHBThickness * 7.0/17.0;
00036
00037 theOuterRadius = 406;
00038 theHOThickness = 1.;
00039
00040 theHEZPos[0] = 388.0;
00041 theHEZPos[1] = 397.0;
00042 theHEZPos[2] = 450.0;
00043 theHEZPos[3] = 568.0;
00044
00045 theHFZPos[0] = 1100.0;
00046 theHFZPos[1] = 1120.0;
00047 theHFThickness = 165;
00048
00049 }
00050
00051
00052 HcalHardcodeGeometryLoader::ReturnType
00053 HcalHardcodeGeometryLoader::load( DetId::Detector det,
00054 int subdet )
00055 {
00056 HcalSubdetector hsub=static_cast<HcalSubdetector>( subdet );
00057 ReturnType hg( new HcalGeometry( extTopology) );
00058
00059 if( hg->cornersMgr() == 0 ) hg->allocateCorners( HcalGeometry::k_NumberOfCellsForCorners ) ;
00060 if( hg->parMgr() == 0 ) hg->allocatePar(
00061 HcalGeometry::k_NumberOfParametersPerShape*HcalGeometry::k_NumberOfShapes,
00062 HcalGeometry::k_NumberOfParametersPerShape ) ;
00063
00064 switch (hsub)
00065 {
00066 case (HcalBarrel) : fill(hsub, extTopology->firstHBRing(), extTopology->lastHBRing(), hg ); break;
00067 case (HcalEndcap) : fill(hsub, extTopology->firstHERing(), extTopology->lastHERing(), hg ); break;
00068 case (HcalForward) : fill(hsub, extTopology->firstHFRing(), extTopology->lastHFRing(), hg ); break;
00069 case (HcalOuter) : fill(hsub, extTopology->firstHORing(), extTopology->lastHORing(), hg ); break;
00070 default: break;
00071 }
00072 return hg;
00073 }
00074
00075 HcalHardcodeGeometryLoader::ReturnType
00076 HcalHardcodeGeometryLoader::load()
00077 {
00078 ReturnType hg( new HcalGeometry( extTopology ) ) ;
00079
00080 if( hg->cornersMgr() == 0 ) hg->allocateCorners( HcalDetId::kSizeForDenseIndexing ) ;
00081 if( hg->parMgr() == 0 ) hg->allocatePar( 500, 5 ) ;
00082
00083 fill(HcalBarrel, extTopology->firstHBRing(), extTopology->lastHBRing(), hg);
00084 fill(HcalEndcap, extTopology->firstHERing(), extTopology->lastHERing(), hg);
00085 fill(HcalForward, extTopology->firstHFRing(), extTopology->lastHFRing(), hg);
00086 fill(HcalOuter, extTopology->firstHORing(), extTopology->lastHORing(), hg);
00087 return hg;
00088 }
00089
00090 void
00091 HcalHardcodeGeometryLoader::fill( HcalSubdetector subdet,
00092 int firstEtaRing,
00093 int lastEtaRing,
00094 ReturnType geom )
00095 {
00096
00097 std::vector<HcalDetId> hcalIds;
00098 int nDepthSegments, startingDepthSegment;
00099 for(int etaRing = firstEtaRing; etaRing <= lastEtaRing; ++etaRing) {
00100 extTopology->depthBinInformation(subdet, etaRing, nDepthSegments, startingDepthSegment);
00101 unsigned int nPhiBins = extTopology->nPhiBins(etaRing);
00102 unsigned int phiInc=72/std::max(36u,nPhiBins);
00103 for(int idepth = 0; idepth < nDepthSegments; ++idepth) {
00104 int depthBin = startingDepthSegment + idepth;
00105
00106 for(unsigned iphi = 1; iphi <= 72; iphi+=phiInc) {
00107 for(int zsign = -1; zsign <= 1; zsign += 2) {
00108 HcalDetId id( subdet, zsign * etaRing, iphi, depthBin);
00109 if (extTopology->valid(id)) hcalIds.push_back(id);
00110 }
00111 }
00112 }
00113 }
00114
00115 edm::LogInfo("HcalHardcodeGeometry") << "Number of HCAL DetIds made: "
00116 << subdet
00117 << " " << hcalIds.size();
00118
00119 for(std::vector<HcalDetId>::const_iterator hcalIdItr = hcalIds.begin();
00120 hcalIdItr != hcalIds.end(); ++hcalIdItr)
00121 {
00122 makeCell(*hcalIdItr,geom) ;
00123 }
00124 }
00125
00126
00127 inline double theta_from_eta(double eta){return (2.0*atan(exp(-eta)));}
00128
00129 void
00130 HcalHardcodeGeometryLoader::makeCell( const HcalDetId& detId ,
00131 ReturnType geom ) const
00132 {
00133
00134 double eta1, eta2;
00135 HcalSubdetector subdet = detId.subdet();
00136 int etaRing = detId.ietaAbs();
00137 if(subdet == HcalForward)
00138 {
00139 eta1 = theHFEtaBounds[etaRing-extTopology->firstHFRing()];
00140 eta2 = theHFEtaBounds[etaRing-extTopology->firstHFRing()+1];
00141 }
00142 else if (etaRing==28 && detId.depth()==3)
00143 {
00144
00145 eta1 = theHBHEEtaBounds[etaRing-1];
00146 eta2 = theHBHEEtaBounds[etaRing+1];
00147 }
00148 else
00149 {
00150 eta1 = theHBHEEtaBounds[etaRing-1];
00151 eta2 = theHBHEEtaBounds[etaRing];
00152 }
00153 double eta = 0.5*(eta1+eta2) * detId.zside();
00154 double deta = 0.5*(eta2-eta1);
00155 double theta = theta_from_eta(eta);
00156
00157 int nDepthBins, startingBin;
00158 extTopology->depthBinInformation(subdet,etaRing,nDepthBins,startingBin);
00159
00160
00161 double dphi_nominal = 2.0*M_PI / extTopology->nPhiBins(1);
00162 double dphi_half = M_PI / extTopology->nPhiBins(etaRing);
00163
00164 double phi_low = dphi_nominal*(detId.iphi()-1);
00165 double phi = phi_low+dphi_half;
00166
00167 bool isBarrel = (subdet == HcalBarrel || subdet == HcalOuter);
00168
00169 double x,y,z,r;
00170 double thickness;
00171
00172 if(isBarrel)
00173 {
00174 if(subdet == HcalBarrel)
00175 {
00176 if (detId.ietaAbs()==15)
00177 {
00178 if (detId.depth()==1)
00179 {
00180 r = theBarrelRadius;
00181 thickness = theHB15aThickness;
00182 }
00183 else
00184 {
00185 r = theBarrelRadius+theHB15aThickness;
00186 thickness = theHB15bThickness;
00187 }
00188 }
00189 else if (detId.ietaAbs()==16)
00190 {
00191 if (detId.depth()==1)
00192 {
00193 r = theBarrelRadius;
00194 thickness = theHB16aThickness;
00195 }
00196 else
00197 {
00198 r = theBarrelRadius+theHB16aThickness;
00199 thickness = theHB16bThickness;
00200 }
00201 }
00202 else
00203 {
00204 r = theBarrelRadius;
00205 thickness = theHBThickness;
00206 }
00207 }
00208 else
00209 {
00210 r = theOuterRadius;
00211 thickness = theHOThickness;
00212 }
00213 z = r * sinh(eta);
00214 thickness *= cosh(eta);
00215 }
00216 else
00217 {
00218 int depth = detId.depth();
00219 if(subdet == HcalEndcap)
00220 {
00221 if (nDepthBins==1)
00222 {
00223 z = theHEZPos[depth - 1];
00224 thickness = theHEZPos[3] - z;
00225 }
00226 else if (nDepthBins==2 && depth==2)
00227 {
00228 z = theHEZPos[depth - 1];
00229 if (etaRing==29)
00230 thickness = theHEZPos[depth] - z;
00231 else
00232 thickness = theHEZPos[3] - z;
00233 }
00234 else
00235 {
00236 z = theHEZPos[depth - 1];
00237 thickness = theHEZPos[depth] - z;
00238 }
00239 thickness /= fabs(tanh(eta));
00240 }
00241 else
00242 {
00243 z = theHFZPos[depth - 1];
00244 thickness = theHFThickness-(theHFZPos[depth-1]-theHFZPos[0]);
00245 }
00246 z*=detId.zside();
00247 r = z * tan(theta);
00248 assert(r>0.);
00249 }
00250
00251 x = r * cos(phi);
00252 y = r * sin(phi);
00253 GlobalPoint point(x,y,z);
00254
00255 std::vector<CCGFloat> hp ;
00256 hp.reserve(5) ;
00257
00258 if (subdet==HcalForward)
00259 {
00260 hp.push_back( deta ) ;
00261 hp.push_back( dphi_half ) ;
00262 hp.push_back( thickness/2 ) ;
00263 hp.push_back( fabs( point.eta() ) ) ;
00264 hp.push_back( fabs( point.z() ) ) ;
00265 }
00266 else
00267 {
00268 const double mysign ( isBarrel ? 1 : -1 ) ;
00269 hp.push_back( deta ) ;
00270 hp.push_back( dphi_half ) ;
00271 hp.push_back( mysign*thickness/2. ) ;
00272 hp.push_back( fabs( point.eta() ) ) ;
00273 hp.push_back( fabs( point.z() ) ) ;
00274 }
00275 geom->newCell( point, point, point,
00276 CaloCellGeometry::getParmPtr( hp,
00277 geom->parMgr(),
00278 geom->parVecVec() ),
00279 detId );
00280 }
00281
00282