CMS 3D CMS Logo

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