CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_2_9_HLT1_bphpatch4/src/Geometry/HcalTowerAlgo/src/HcalHardcodeGeometryLoader.cc

Go to the documentation of this file.
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; // just from drawings.  All thicknesses needs to be done right
00029 
00030   theHB15aThickness = theHBThickness * 12.0/17.0; // relative weight from layer count!
00031   theHB15bThickness = theHBThickness * 4.0/17.0;  // relative weight from layer count!
00032   theHB16aThickness = theHBThickness * 1.0/17.0;  // relative weight from layer count!
00033   theHB16bThickness = theHBThickness * 7.0/17.0;  // relative weight from layer count!
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    // start by making the new HcalDetIds
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    // for each new HcalDetId, make a CaloCellGeometry
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    // the two eta boundaries of the cell
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       // double-width in eta at depth 3 in ieta=28
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    // in radians
00159    double dphi_nominal = 2.0*M_PI / extTopology->nPhiBins(1); // always the same
00160    double dphi_half = M_PI / extTopology->nPhiBins(etaRing); // half-width
00161   
00162    double phi_low = dphi_nominal*(detId.iphi()-1); // low-edge boundaries are constant...
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       { // HO
00208          r = theOuterRadius;
00209          thickness = theHOThickness;
00210       } 
00211       z = r * sinh(eta); // sinh(eta) == 1/tan(theta)
00212       thickness *= cosh(eta); // cosh(eta) == 1/sin(theta)
00213    } 
00214    else 
00215    {
00216       int depth = detId.depth();
00217       if(subdet == HcalEndcap) 
00218       { // Sadly, Z must be made a function of ieta.
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) // special case for tower 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(); // get the sign right.
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