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
00012
00013 HcalDDDGeometryLoader::HcalDDDGeometryLoader(const DDCompactView & cpv) {
00014 std::string name = "HcalHits";
00015 numberingFromDDD = new HcalNumberingFromDDD(name, cpv);
00016 }
00017
00018 HcalDDDGeometryLoader::~HcalDDDGeometryLoader() {
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 if ( geom->cornersMgr() == 0 ) {
00031 const unsigned int count (numberingFromDDD->numberOfCells(HcalBarrel ) +
00032 numberingFromDDD->numberOfCells(HcalEndcap ) +
00033 numberingFromDDD->numberOfCells(HcalForward) +
00034 numberingFromDDD->numberOfCells(HcalOuter ) );
00035 geom->allocateCorners( count ) ;
00036 }
00037
00038
00039
00040 if ( geom->parMgr() == 0 ) geom->allocatePar( 500, 3 ) ;
00041
00042 fill (hsub, gDDD, geom );
00043 return geom ;
00044 }
00045
00046 HcalDDDGeometryLoader::ReturnType
00047 HcalDDDGeometryLoader::load() {
00048
00049 HcalDDDGeometry* gDDD ( new HcalDDDGeometry );
00050 ReturnType geom ( gDDD );
00051
00052 if( geom->cornersMgr() == 0 ) {
00053 const unsigned int count (numberingFromDDD->numberOfCells(HcalBarrel ) +
00054 numberingFromDDD->numberOfCells(HcalEndcap ) +
00055 numberingFromDDD->numberOfCells(HcalForward) +
00056 numberingFromDDD->numberOfCells(HcalOuter ) );
00057 geom->allocateCorners( count ) ;
00058 }
00059 if( geom->parMgr() == 0 ) geom->allocatePar( 500, 3 ) ;
00060
00061 fill(HcalBarrel, gDDD, geom);
00062 fill(HcalEndcap, gDDD, geom);
00063 fill(HcalForward, gDDD, geom);
00064 fill(HcalOuter, gDDD, geom);
00065 return geom ;
00066 }
00067
00068 void HcalDDDGeometryLoader::fill(HcalSubdetector subdet,
00069 HcalDDDGeometry* geometryDDD,
00070 CaloSubdetectorGeometry* geom ) {
00071
00072
00073 std::vector<HcalCellType> hcalCells = numberingFromDDD->HcalCellTypes(subdet);
00074 geometryDDD->insertCell(hcalCells);
00075 #ifdef DebugLog
00076 LogDebug("HCalGeom") << "HcalDDDGeometryLoader::fill gets "
00077 << hcalCells.size() << " cells for subdetector "
00078 << subdet;
00079 #endif
00080
00081
00082 double deg = M_PI/180.;
00083 std::vector<HcalDetId> hcalIds;
00084 for (unsigned int i=0; i<hcalCells.size(); i++) {
00085 int etaRing = hcalCells[i].etaBin();
00086 int depthBin = hcalCells[i].depthSegment();
00087 int phiInc = 4/hcalCells[i].nPhiModule();
00088 unsigned int iphi = 1;
00089 if (hcalCells[i].unitPhi() == 4) iphi = 3;
00090 double dphi = (hcalCells[i].phiBinWidth())*deg;
00091 double phi =-(hcalCells[i].phiOffset())*deg + 0.5*dphi;
00092 std::vector<int>missPlus = hcalCells[i].missingPhiPlus();
00093 std::vector<int>missMinus = hcalCells[i].missingPhiMinus();
00094 #ifdef DebugLog
00095 LogDebug("HCalGeom") << "HcalDDDGeometryLoader: Subdet " << subdet
00096 << " eta " << etaRing << " depth " << depthBin
00097 << " modules " << hcalCells[i].nPhiModule() << " "
00098 << phiInc << " phi " << phi/deg << " " << dphi/deg
00099 << " Missing " << missPlus.size() << "/"
00100 << missMinus.size();
00101 #endif
00102 for (int k = 0; k < hcalCells[i].nPhiBins(); k++) {
00103 bool ok = true;
00104 for (unsigned int kk = 0; kk < missPlus.size(); kk++)
00105 if (iphi == (unsigned int)(missPlus[kk])) ok = false;
00106 if (ok) {
00107 #ifdef DebugLog
00108 LogDebug("HCalGeom") << "HcalDDDGeometryLoader::fill Cell " << i
00109 << " eta " << etaRing << " phi " << iphi << "("
00110 << phi/deg << ", " << dphi/deg << ") depth "
00111 << depthBin;
00112 #endif
00113 HcalDetId id(subdet, etaRing, iphi, depthBin);
00114 hcalIds.push_back(id);
00115 geom->addCell( id, makeCell(id,hcalCells[i],phi,dphi,geom) );
00116 }
00117 if (hcalCells[i].nHalves() > 1) {
00118 ok = true;
00119 for (unsigned int kk = 0; kk < missMinus.size(); kk++)
00120 if (iphi == (unsigned int)(missMinus[kk])) ok = false;
00121 if (ok) {
00122 #ifdef DebugLog
00123 LogDebug("HCalGeom") << "HcalDDDGeometryLoader::fill Cell " << i
00124 << " eta " << -etaRing << " phi " << iphi <<" ("
00125 << phi/deg << ", " << dphi/deg << ") depth "
00126 << depthBin;
00127 #endif
00128 HcalDetId id(subdet, -etaRing, iphi, depthBin);
00129 hcalIds.push_back(id);
00130 geom->addCell( id, makeCell(id,hcalCells[i],phi,dphi,geom) );
00131 }
00132 }
00133 iphi += phiInc;
00134 phi += dphi;
00135 }
00136 }
00137
00138 edm::LogInfo("HCalGeom") << "Number of HCAL DetIds made for " << subdet
00139 << " is " << hcalIds.size();
00140 }
00141
00142 CaloCellGeometry*
00143 HcalDDDGeometryLoader::makeCell( const HcalDetId& detId,
00144 HcalCellType hcalCell,
00145 double phi,
00146 double dphi,
00147 CaloSubdetectorGeometry* geom) const {
00148
00149
00150 double eta1 = hcalCell.etaMin();
00151 double eta2 = hcalCell.etaMax();
00152 HcalSubdetector subdet = detId.subdet();
00153 double eta = 0.5*(eta1+eta2) * detId.zside();
00154 double deta = (eta2-eta1);
00155 double theta = 2.0*atan(exp(-eta));
00156
00157
00158 bool rzType = hcalCell.depthType();
00159 bool isBarrel = (subdet == HcalBarrel || subdet == HcalOuter);
00160
00161 double z, r, thickness;
00162 #ifdef DebugLog
00163 double r0, r1, r2;
00164 #endif
00165 if (rzType) {
00166 r = hcalCell.depthMin();
00167 if (isBarrel) {
00168 z = r * sinh(eta);
00169 thickness = (hcalCell.depthMax() - r) * cosh(eta);
00170 #ifdef DebugLog
00171 r1 = r;
00172 r2 = hcalCell.depthMax();
00173 r0 = 0.5*(r1+r2);
00174 #endif
00175 } else {
00176 z = r * sinh(eta2);
00177 thickness = 2. * hcalCell.halfSize();
00178 r = z/sinh(std::abs(eta));
00179 #ifdef DebugLog
00180 r0 = z/sinh(std::abs(eta));
00181 r1 = z/sinh(std::abs(eta)+0.5*deta);
00182 r2 = z/sinh(std::abs(eta)-0.5*deta);
00183 #endif
00184 }
00185 #ifdef DebugLog
00186 LogDebug("HCalGeom") << "HcalDDDGeometryLoader::makeCell SubDet " << subdet
00187 << " eta = " << eta << " theta = " << theta
00188 << " r = " << r << " thickness = " << thickness
00189 << " r0-r2 (" << r0 << ":" << r1 << ":" << r2 << ")";
00190 #endif
00191 } else {
00192 z = hcalCell.depthMin();
00193 thickness = hcalCell.depthMax() - z;
00194 z *= detId.zside();
00195 r = z * tan(theta);
00196 thickness /= std::abs(cos(theta));
00197 #ifdef DebugLog
00198 r0 = z/sinh(std::abs(eta));
00199 r1 = z/sinh(std::abs(eta)+0.5*deta);
00200 r2 = z/sinh(std::abs(eta)-0.5*deta);
00201 LogDebug("HCalGeom") << "HcalDDDGeometryLoader::makeCell SubDet " << subdet
00202 << " eta = " << eta << " theta = " << theta
00203 << " z = " << z << " r = " << r << " thickness = "
00204 << thickness << " r0-r2 (" << r0 << ":" << r1 << ":"
00205 << r2 << ")";
00206 #endif
00207 }
00208
00209 double x = r * cos(phi);
00210 double y = r * sin(phi);
00211 GlobalPoint point(x,y,z);
00212
00213 #ifdef DebugLog
00214 LogDebug("HCalGeom") << "HcalDDDGeometryLoader::makeCell for " << detId
00215 << " Point " << point << " deta = " << deta
00216 << " dphi = " << dphi << " thickness = " << thickness
00217 << " isBarrel = " << isBarrel << " " << rzType;
00218 #endif
00219
00220 if (subdet==HcalForward) {
00221 std::vector<double> hf ;
00222 hf.reserve(3) ;
00223 hf.push_back(deta/2.) ;
00224 hf.push_back(dphi/2.) ;
00225 hf.push_back(thickness/2.) ;
00226 return new calogeom::IdealZPrism(point,
00227 geom->cornersMgr(),
00228 CaloCellGeometry::getParmPtr(hf,
00229 geom->parMgr(),
00230 geom->parVecVec() ) );
00231 } else {
00232 const double sign ( isBarrel ? 1 : -1 ) ;
00233 std::vector<double> hh ;
00234 hh.reserve(3) ;
00235 hh.push_back(deta/2.) ;
00236 hh.push_back(dphi/2.) ;
00237 hh.push_back(sign*thickness/2.) ;
00238 return new calogeom::IdealObliquePrism(point,
00239 geom->cornersMgr(),
00240 CaloCellGeometry::getParmPtr(hh,
00241 geom->parMgr(),
00242 geom->parVecVec() ) );
00243 }
00244 }