00001 #include "Geometry/HcalTowerAlgo/interface/HcalDDDGeometryLoader.h"
00002 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00003 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00004 #include "Geometry/CaloGeometry/interface/IdealObliquePrism.h"
00005 #include "Geometry/CaloGeometry/interface/IdealZPrism.h"
00006 #include "Geometry/CaloEventSetup/interface/CaloGeometryLoader.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008
00009 #include<string>
00010
00011 HcalDDDGeometryLoader::HcalDDDGeometryLoader(const DDCompactView & cpv)
00012 {
00013 std::string name = "HcalHits";
00014 numberingFromDDD = new HcalNumberingFromDDD(name, cpv);
00015 }
00016
00017 HcalDDDGeometryLoader::~HcalDDDGeometryLoader()
00018 {
00019 delete numberingFromDDD;
00020 }
00021
00022
00023 HcalDDDGeometryLoader::ReturnType
00024 HcalDDDGeometryLoader::load(DetId::Detector det, int subdet)
00025 {
00026 HcalSubdetector hsub = static_cast<HcalSubdetector>(subdet);
00027 HcalDDDGeometry* gDDD ( new HcalDDDGeometry );
00028 ReturnType geom ( gDDD );
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 if( geom->cornersMgr() == 0 )
00041 {
00042 geom->allocateCorners( 2592 ) ;
00043 }
00044 if( geom->parMgr() == 0 ) geom->allocatePar( 75, 3 ) ;
00045
00046 fill (hsub, gDDD, geom );
00047 return geom ;
00048 }
00049
00050 HcalDDDGeometryLoader::ReturnType
00051 HcalDDDGeometryLoader::load()
00052 {
00053 HcalDDDGeometry* gDDD ( new HcalDDDGeometry );
00054 ReturnType geom ( gDDD );
00055
00056 if( geom->cornersMgr() == 0 )
00057 {
00058 const unsigned int count (
00059 numberingFromDDD->HcalCellTypes( HcalBarrel ).size() +
00060 numberingFromDDD->HcalCellTypes( HcalEndcap ).size() +
00061 numberingFromDDD->HcalCellTypes( HcalForward ).size() +
00062 numberingFromDDD->HcalCellTypes( HcalOuter ).size() ) ;
00063 geom->allocateCorners( count ) ;
00064 }
00065 if( geom->parMgr() == 0 ) geom->allocatePar( 500, 3 ) ;
00066
00067 fill(HcalBarrel, gDDD, geom);
00068 fill(HcalEndcap, gDDD, geom);
00069 fill(HcalForward, gDDD, geom);
00070 fill(HcalOuter, gDDD, geom);
00071 return geom ;
00072 }
00073
00074 void
00075 HcalDDDGeometryLoader::fill( HcalSubdetector subdet,
00076 HcalDDDGeometry* geometryDDD,
00077 CaloSubdetectorGeometry* geom )
00078 {
00079
00080 std::vector<HcalCellType::HcalCellType> hcalCells = numberingFromDDD->HcalCellTypes(subdet);
00081 geometryDDD->insertCell(hcalCells);
00082 LogDebug("HCalGeom") << "HcalDDDGeometryLoader::fill gets "
00083 << hcalCells.size() << " cells for subdetector "
00084 << subdet;
00085
00086
00087
00088 double deg = M_PI/180.;
00089 std::vector<HcalDetId> hcalIds;
00090 for (unsigned int i=0; i<hcalCells.size(); i++) {
00091 int etaRing = hcalCells[i].etaBin();
00092 int depthBin = hcalCells[i].depthSegment();
00093 int phiInc = 4/hcalCells[i].nPhiModule();
00094 unsigned int iphi = 1;
00095 double dphi = (hcalCells[i].phiBinWidth())*deg;
00096 double phi =-(hcalCells[i].phiOffset())*deg + 0.5*dphi;
00097 LogDebug("HCalGeom") << "HcalDDDGeometryLoader: Subdet " << subdet
00098 << " eta " << etaRing << " depth " << depthBin
00099 << " modules " << hcalCells[i].nPhiModule() << " "
00100 << phiInc << " phi " << phi/deg << " " << dphi/deg;
00101 for (int k = 0; k < hcalCells[i].nPhiBins(); k++) {
00102 LogDebug("HCalGeom") << "HcalDDDGeometryLoader::fill Cell " << i
00103 << " eta " << etaRing << " phi " << iphi << "("
00104 << phi/deg << ", " << dphi/deg << ") depth "
00105 << depthBin;
00106 HcalDetId id(subdet, etaRing, iphi, depthBin);
00107 hcalIds.push_back(id);
00108 const CaloCellGeometry * geometry = makeCell(id,hcalCells[i],phi,dphi,geom);
00109 geom->addCell(id, geometry);
00110 if (hcalCells[i].nHalves() > 1) {
00111 LogDebug("HCalGeom") << "HcalDDDGeometryLoader::fill Cell " << i
00112 << " eta " << -etaRing << " phi " << iphi << " ("
00113 << phi/deg << ", " << dphi/deg << ") depth "
00114 << depthBin;
00115 HcalDetId id(subdet, -etaRing, iphi, depthBin);
00116 hcalIds.push_back(id);
00117 const CaloCellGeometry * geometry = makeCell(id,hcalCells[i],phi,dphi,geom);
00118 geom->addCell(id, geometry);
00119 }
00120 iphi += phiInc;
00121 phi += dphi;
00122 }
00123 }
00124
00125 edm::LogInfo("HCalGeom") << "Number of HCAL DetIds made for " << subdet
00126 << " is " << hcalIds.size();
00127 }
00128
00129 const CaloCellGeometry*
00130 HcalDDDGeometryLoader::makeCell(const HcalDetId& detId,
00131 HcalCellType::HcalCellType hcalCell,
00132 double phi,
00133 double dphi,
00134 CaloSubdetectorGeometry* geom) const
00135 {
00136
00137 double eta1 = hcalCell.etaMin();
00138 double eta2 = hcalCell.etaMax();
00139 HcalSubdetector subdet = detId.subdet();
00140 double eta = 0.5*(eta1+eta2) * detId.zside();
00141 double deta = (eta2-eta1);
00142 double theta = 2.0*atan(exp(-eta));
00143
00144
00145 bool isBarrel = (subdet == HcalBarrel || subdet == HcalOuter);
00146
00147 double z, r, thickness;
00148
00149 if (isBarrel) {
00150 r = hcalCell.depthMin();
00151 thickness = hcalCell.depthMax() - r;
00152 LogDebug("HCalGeom") << "HcalDDDGeometryLoader::makeCell SubDet " << subdet
00153 << " eta = " << eta << " theta = " << theta
00154 << " r = " << r << " thickness = " << thickness;
00155 z = r * sinh(eta);
00156 thickness *= cosh(eta);
00157 } else {
00158 z = hcalCell.depthMin();
00159 thickness = hcalCell.depthMax() - z;
00160 LogDebug("HCalGeom") << "HcalDDDGeometryLoader::makeCell SubDet " << subdet
00161 << " eta = " << eta << " theta = " << theta
00162 << " z = " << z << " thickness = " << thickness;
00163 z *= detId.zside();
00164 r = z * tan(theta);
00165 }
00166
00167 double x = r * cos(phi);
00168 double y = r * sin(phi);
00169 GlobalPoint point(x,y,z);
00170
00171 LogDebug("HCalGeom") << "HcalDDDGeometryLoader::makeCell for " << detId
00172 << " Point " << point << " deta = " << deta
00173 << " dphi = " << dphi << " thickness = " << thickness
00174 << " isBarrel = " << isBarrel;
00175
00176
00177 if (subdet==HcalForward)
00178 {
00179 std::vector<float> hf ;
00180 hf.reserve(3) ;
00181 hf.push_back( deta/2. ) ;
00182 hf.push_back( dphi/2. ) ;
00183 hf.push_back( thickness/2. ) ;
00184 return new calogeom::IdealZPrism(
00185 point,
00186 geom->cornersMgr(),
00187 CaloCellGeometry::getParmPtr( hf,
00188 geom->parMgr(),
00189 geom->parVecVec() ) );
00190 }
00191 else
00192 {
00193 const double sign ( isBarrel ? 1 : -1 ) ;
00194 std::vector<float> hh ;
00195 hh.reserve(3) ;
00196 hh.push_back( deta/2. ) ;
00197 hh.push_back( dphi/2. ) ;
00198 hh.push_back( sign*thickness/2. ) ;
00199 return new calogeom::IdealObliquePrism(
00200 point,
00201 geom->cornersMgr(),
00202 CaloCellGeometry::getParmPtr( hh,
00203 geom->parMgr(),
00204 geom->parVecVec() ) );
00205 }
00206 }