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