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