CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/Geometry/HcalTowerAlgo/src/HcalGeometry.cc

Go to the documentation of this file.
00001 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00002 #include "Geometry/CaloGeometry/interface/CaloGenericDetId.h"
00003 #include "Geometry/CaloGeometry/interface/IdealObliquePrism.h"
00004 #include "Geometry/CaloGeometry/interface/IdealZPrism.h"
00005 #include "Geometry/HcalTowerAlgo/interface/HcalGeometry.h"
00006 #include "Geometry/HcalTowerAlgo//src/HcalHardcodeGeometryData.h"
00007 #include <algorithm>
00008 
00009 HcalGeometry::HcalGeometry() :
00010    theTopology    ( new HcalTopology ),
00011    m_ownsTopology ( true )
00012 {
00013 }
00014 
00015 HcalGeometry::HcalGeometry( const HcalTopology* topology ) :
00016    theTopology    ( topology ) ,
00017    m_ownsTopology ( false ) 
00018 {
00019 }
00020   
00021 
00022 HcalGeometry::~HcalGeometry() 
00023 {
00024    if( m_ownsTopology ) delete theTopology ;
00025 }
00026 
00027 
00028 void
00029 HcalGeometry::fillDetIds() const
00030 {
00031    const std::vector<DetId>& baseIds ( CaloSubdetectorGeometry::getValidDetIds() ) ;
00032    for( unsigned int i ( 0 ) ; i != baseIds.size() ; ++i ) 
00033    {
00034       const DetId id ( baseIds[i] );
00035       if( id.subdetId() == HcalBarrel )
00036       { 
00037          m_hbIds.push_back( id ) ;
00038       }
00039       else
00040       {
00041          if( id.subdetId() == HcalEndcap )
00042          { 
00043             m_heIds.push_back( id ) ;
00044          }
00045          else
00046          {
00047             if( id.subdetId() == HcalOuter )
00048             { 
00049                m_hoIds.push_back( id ) ;
00050             }
00051             else
00052             {
00053                if( id.subdetId() == HcalForward )
00054                { 
00055                   m_hfIds.push_back( id ) ;
00056                }
00057             }
00058          }
00059       }
00060    }
00061    std::sort( m_hbIds.begin(), m_hbIds.end() ) ;   
00062    std::sort( m_heIds.begin(), m_heIds.end() ) ;   
00063    std::sort( m_hoIds.begin(), m_hoIds.end() ) ;   
00064    std::sort( m_hfIds.begin(), m_hfIds.end() ) ;   
00065    m_emptyIds.resize( 0 ) ;
00066 }
00067 
00068 const std::vector<DetId>& 
00069 HcalGeometry::getValidDetIds( DetId::Detector det,
00070                               int             subdet ) const 
00071 {
00072    if( 0 != subdet &&
00073        0 == m_hbIds.size() ) fillDetIds() ;
00074    return ( 0 == subdet ? CaloSubdetectorGeometry::getValidDetIds() :
00075             ( HcalBarrel == subdet ? m_hbIds :
00076               ( HcalEndcap == subdet ? m_heIds :
00077                 ( HcalOuter == subdet ? m_hoIds :
00078                   ( HcalForward == subdet ? m_hfIds : m_emptyIds ) ) ) ) ) ;
00079 }
00080 
00081 DetId HcalGeometry::getClosestCell(const GlobalPoint& r) const {
00082 
00083   // Now find the closest eta_bin, eta value of a bin i is average
00084   // of eta[i] and eta[i-1]
00085   double abseta = fabs(r.eta());
00086   
00087   // figure out subdetector, giving preference to HE in HE/HF overlap region
00088   HcalSubdetector bc= HcalEmpty;
00089   if (abseta <= theHBHEEtaBounds[theTopology->lastHBRing()] ) {
00090     bc = HcalBarrel;
00091   } else if (abseta <= theHBHEEtaBounds[theTopology->lastHERing()] ) {
00092     bc = HcalEndcap;
00093   } else {
00094     bc = HcalForward;
00095   }
00096 
00097   if (bc == HcalForward) {
00098     static const double z_short=1137.0;
00099     int etaring = etaRing(bc, abseta);  // This is safer
00100     /*
00101       static const double z_long=1115.0;
00102       // determine front-face eta
00103       double radius=sqrt(pow(r.x(),2)+pow(r.y(),2));
00104       double trueAeta=asinh(z_long/radius);
00105       // find eta bin
00106       int etaring = etaRing(bc, trueAeta);
00107     */
00108     if (etaring>theTopology->lastHFRing()) etaring=theTopology->lastHFRing(); 
00109   
00110     int phibin = phiBin(r.phi(), etaring);
00111 
00112     // add a sign to the etaring
00113     int etabin = (r.z() > 0) ? etaring : -etaring;
00114     // Next line is premature depth 1 and 2 can coexist for large z-extent
00115     HcalDetId bestId(bc,etabin,phibin,((fabs(r.z())>=z_short)?(2):(1)));
00116     return bestId;
00117   } else {
00118 
00119     // find eta bin
00120     int etaring = etaRing(bc, abseta);
00121     
00122     int phibin = phiBin(r.phi(), etaring);
00123     
00124     // add a sign to the etaring
00125     int etabin = (r.z() > 0) ? etaring : -etaring;
00126     
00127     //Now do depth if required
00128     int dbin = 1;
00129     double pointrz=0, drz=99999.;
00130     HcalDetId currentId(bc, etabin, phibin, dbin);
00131     if (bc == HcalBarrel) pointrz = r.mag();
00132     else                  pointrz = std::abs(r.z());
00133     HcalDetId bestId;
00134     for ( ; currentId != HcalDetId(); theTopology->incrementDepth(currentId)) {
00135       const CaloCellGeometry * cell = getGeometry(currentId);
00136       assert(cell != 0);
00137       double rz;
00138       if (bc == HcalEndcap) rz = std::abs(cell->getPosition().z());
00139       else                  rz = cell->getPosition().mag();
00140       if (std::abs(pointrz-rz)<drz) {
00141         bestId = currentId;
00142         drz    = std::abs(pointrz-rz);
00143       }
00144     }
00145     
00146     return bestId;
00147   }
00148 }
00149 
00150 
00151 int HcalGeometry::etaRing(HcalSubdetector bc, double abseta) const
00152 {
00153   int etaring;
00154   if( bc == HcalForward ) {
00155     for(etaring = theTopology->firstHFRing();
00156         etaring <= theTopology->lastHFRing(); ++etaring)
00157     {
00158       if(theHFEtaBounds[etaring-theTopology->firstHFRing()+1] > abseta) break;
00159     }
00160   }
00161   else
00162   {
00163     for(etaring = 1;
00164         etaring <= theTopology->lastHERing(); ++etaring)
00165     {
00166       if(theHBHEEtaBounds[etaring] >= abseta) break;
00167     }
00168   }
00169 
00170   return etaring;
00171 }
00172 
00173 
00174 int HcalGeometry::phiBin(double phi, int etaring) const
00175 {
00176    static const double twopi = M_PI+M_PI;
00177   //put phi in correct range (0->2pi)
00178   if(phi<0.0) phi += twopi;
00179   if(phi>twopi) phi -= twopi;
00180   int nphibins = theTopology->nPhiBins(etaring);
00181   int phibin= static_cast<int>(phi/twopi*nphibins)+1;
00182   int iphi;
00183 
00184   // rings 40 and 41 are offset wrt the other phi numbering
00185   //  1        1         1         2
00186   //  ------------------------------
00187   //  72       36        36        1
00188   if(etaring >= theTopology->firstHFQuadPhiRing())
00189   {
00190     phi+=(twopi/36); //shift by half tower.    
00191     phibin=static_cast<int>(phi/twopi*nphibins);
00192     if (phibin==0) phibin=18;
00193     iphi=phibin*4-1; // 71,3,5,
00194   } else {
00195     // convert to the convention of numbering 1,3,5, in 36 phi bins
00196     iphi=(phibin-1)*(72/nphibins) + 1;
00197   }
00198 
00199   return iphi;
00200 }
00201 
00202 CaloSubdetectorGeometry::DetIdSet 
00203 HcalGeometry::getCells( const GlobalPoint& r, 
00204                         double             dR ) const 
00205 {
00206    CaloSubdetectorGeometry::DetIdSet dis;  // this is the return object
00207 
00208    if( 0.000001 < dR )
00209    {
00210       if( dR > M_PI/2. ) // this version needs "small" dR
00211       {
00212          dis = CaloSubdetectorGeometry::getCells( r, dR ) ; // base class version
00213       }
00214       else
00215       {
00216          const double dR2     ( dR*dR ) ;
00217          const double reta    ( r.eta() ) ;
00218          const double rphi    ( r.phi() ) ;
00219          const double lowEta  ( reta - dR ) ;
00220          const double highEta ( reta + dR ) ;
00221          const double lowPhi  ( rphi - dR ) ;
00222          const double highPhi ( rphi + dR ) ;
00223          
00224          const double hfEtaHi ( theHFEtaBounds[ theTopology->lastHFRing() -
00225                                                 theTopology->firstHFRing() + 1 ] ) ;
00226          
00227          if( highEta > -hfEtaHi &&
00228              lowEta  <  hfEtaHi    ) // in hcal
00229          {
00230             const HcalSubdetector hs[] = { HcalBarrel, HcalOuter, HcalEndcap, HcalForward } ;
00231 
00232             for( unsigned int is ( 0 ) ; is != 4 ; ++is )
00233             {
00234                const int sign        (  reta>0 ? 1 : -1 ) ;
00235                const int ieta_center ( sign*etaRing( hs[is], fabs( reta ) ) ) ;
00236                const int ieta_lo     ( ( 0 < lowEta*sign ? sign : -sign )*etaRing( hs[is], fabs( lowEta ) ) ) ;
00237                const int ieta_hi     ( ( 0 < highEta*sign ? sign : -sign )*etaRing( hs[is], fabs( highEta ) ) ) ;
00238                const int iphi_lo     ( phiBin( lowPhi , ieta_center ) ) ;
00239                const int iphi_hi     ( phiBin( highPhi, ieta_center ) ) ;
00240                const int jphi_lo     ( iphi_lo>iphi_hi ? iphi_lo - 72 : iphi_lo ) ;
00241                const int jphi_hi     ( iphi_hi ) ;
00242 
00243                const int idep_lo     ( 1 == is ? 4 : 1 ) ;
00244                const int idep_hi     ( 1 == is ? 4 :
00245                                        ( 2 == is ? 3 : 2 ) ) ;
00246                for( int ieta ( ieta_lo ) ; ieta <= ieta_hi ; ++ieta ) // over eta limits
00247                {
00248                   if( ieta != 0 )
00249                   {
00250                      for( int jphi ( jphi_lo ) ; jphi <= jphi_hi ; ++jphi )  // over phi limits
00251                      {
00252                         const int iphi ( 1 > jphi ? jphi+72 : jphi ) ;
00253 
00254                         for( int idep ( idep_lo ) ; idep <= idep_hi ; ++idep )
00255                         {
00256                            if( HcalDetId::validDetId( hs[is], ieta, iphi, idep ) )
00257                            {
00258                               const HcalDetId did ( hs[is], ieta, iphi, idep ) ;
00259                               const CaloCellGeometry* cell ( getGeometry( did ) );
00260                               if( 0 != cell )
00261                               {
00262                                  const GlobalPoint& p   ( cell->getPosition() ) ;
00263                                  const double       eta ( p.eta() ) ;
00264                                  const double       phi ( p.phi() ) ;
00265                                  if( reco::deltaR2( eta, phi, reta, rphi ) < dR2 ) dis.insert( did ) ;
00266                               }
00267                            }
00268                         }
00269                      }
00270                   }
00271                }
00272             }
00273          }
00274       }
00275    }
00276    return dis;
00277 }
00278 
00279 
00280 unsigned int
00281 HcalGeometry::alignmentTransformIndexLocal( const DetId& id )
00282 {
00283    const CaloGenericDetId gid ( id ) ;
00284 
00285    assert( gid.isHcal() ) ;
00286 
00287 
00288    const HcalDetId hid ( id ) ;
00289 
00290    const int jz ( ( hid.zside() + 1 )/2 ) ;
00291 
00292    const int zoff ( jz*numberOfAlignments()/2 ) ;
00293 
00294    const int detoff ( zoff + 
00295                       ( gid.isHB() ? 0 :
00296                         ( gid.isHE() ? numberOfBarrelAlignments()/2 :
00297                           ( gid.isHF() ? ( numberOfBarrelAlignments() +
00298                                            numberOfEndcapAlignments() )/2 :
00299                             ( numberOfBarrelAlignments() +
00300                               numberOfEndcapAlignments() +
00301                               numberOfForwardAlignments() )/2 ) ) ) ) ; 
00302 
00303    const int iphi ( hid.iphi() ) ;
00304 
00305    unsigned int index ( numberOfAlignments() ) ;
00306    if( gid.isHO() )
00307    {
00308       const int ieta ( hid.ieta() ) ;
00309       const int ring ( ieta < -10 ? 0 :
00310                        ( ieta < -4 ? 1 :
00311                          ( ieta < 5 ? 2 :
00312                            ( ieta < 11 ? 3 : 4 ) ) ) ) ;
00313 
00314       index = detoff + 12*ring + ( iphi - 1 )%6 ;
00315    }
00316    else
00317    {
00318       index = detoff + ( iphi - 1 )%4 ;
00319    }
00320 
00321    assert( index < numberOfAlignments() ) ;
00322    return index ;
00323 }
00324 
00325 unsigned int
00326 HcalGeometry::alignmentTransformIndexGlobal( const DetId& id )
00327 {
00328    return (unsigned int)DetId::Hcal - 1 ;
00329 }
00330 
00331 std::vector<HepGeom::Point3D<double> > 
00332 HcalGeometry::localCorners( const double* pv,
00333                             unsigned int  i,
00334                             HepGeom::Point3D<double> &   ref )
00335 {
00336    const HcalDetId hid ( HcalDetId::detIdFromDenseIndex( i ) ) ;
00337    const CaloGenericDetId cgid ( hid ) ;
00338    if( cgid.isHF() )
00339    {
00340       return ( calogeom::IdealZPrism::localCorners( pv, ref ) ) ;
00341    }
00342    else
00343    {
00344       return ( calogeom::IdealObliquePrism::localCorners( pv, ref ) ) ;
00345    }
00346 }
00347 
00348 CaloCellGeometry* 
00349 HcalGeometry::newCell( const GlobalPoint& f1 ,
00350                        const GlobalPoint& f2 ,
00351                        const GlobalPoint& f3 ,
00352                        CaloCellGeometry::CornersMgr* mgr,
00353                        const double*      parm ,
00354                        const DetId&       detId   ) 
00355 {
00356    const CaloGenericDetId cgid ( detId ) ;
00357 
00358    assert( cgid.isHcal() ) ;
00359 
00360    if( cgid.isHF() )
00361    {
00362       return ( new calogeom::IdealZPrism( f1, mgr, parm ) ) ;
00363    }
00364    else
00365    {
00366       return ( new calogeom::IdealObliquePrism( f1, mgr, parm ) ) ;
00367    }
00368 }