CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/Geometry/EcalAlgo/src/EcalPreshowerGeometry.cc

Go to the documentation of this file.
00001 #include "Geometry/CaloGeometry/interface/PreshowerStrip.h"
00002 #include "Geometry/CaloGeometry/interface/CaloGenericDetId.h"
00003 #include "Geometry/EcalAlgo/interface/EcalPreshowerGeometry.h"
00004 #include "DataFormats/EcalDetId/interface/ESDetId.h"
00005 #include "FWCore/Utilities/interface/Exception.h"
00006 #include <iostream>
00007 
00008 typedef CaloCellGeometry::CCGFloat CCGFloat ;
00009 typedef CaloCellGeometry::Pt3D     Pt3D     ;
00010 typedef CaloCellGeometry::Pt3DVec  Pt3DVec  ;
00011 typedef HepGeom::Plane3D<CCGFloat> Pl3D     ;
00012 
00013 EcalPreshowerGeometry::EcalPreshowerGeometry() :
00014    m_xWidWaf      ( 6.3  ) ,
00015    m_xInterLadGap ( 0.05 ) , // additional gap between wafers in adj ladders
00016    m_xIntraLadGap ( 0.04 ) , // gap between wafers in same ladder
00017    m_yWidAct      ( 6.1  ) ,
00018    m_yCtrOff      ( 0.05 ) ,  // gap at center
00019    m_cellVec      ( k_NumberOfCellsForCorners )
00020 {
00021   m_zplane[0] = 0. ;
00022   m_zplane[1] = 0. ;
00023   m_zplane[2] = 0. ;
00024   m_zplane[3] = 0. ;
00025 }
00026 
00027 
00028 EcalPreshowerGeometry::~EcalPreshowerGeometry()
00029 {
00030 }
00031 
00032 unsigned int
00033 EcalPreshowerGeometry::alignmentTransformIndexLocal( const DetId& id )
00034 {
00035    const CaloGenericDetId gid ( id ) ;
00036 
00037    assert( gid.isES() ) ;
00038 
00039 // plane 2 is split into 2 dees along x=0 for both signs of z
00040 
00041 // plane 1 at zsign=-1 is split into 2 dees between six=19 and six=20 for siy<=20,
00042 //                                             and six=21 and 22 for siy>=21
00043 
00044 // plane 1 at zsign=+1 is split into 2 dees between six=20 and six=21 for siy<=20,
00045 //                                             and six=19 and 20 for siy>=21
00046 
00047 
00048 // Desired numbering 
00049 //                LEFT    RIGHT (as one faces the Dee from the IP)
00050 //  ES-  pl=2     0       1
00051 //       pl=1     2       3    the reversal of pl=2 and pl=1 is intentional here (CM Kuo)
00052 //  ES+  pl=1     4       5
00053 //       pl=2     6       7
00054 
00055    const ESDetId esid ( id ) ;
00056    const int jx ( esid.six() - 1 ) ;
00057    const int jy ( esid.siy() - 1 ) ;
00058    const int jz ( esid.zside() + 1 ) ;
00059    const int pl ( esid.plane() - 1 ) ;
00060    const bool second ( 1 == pl ) ;
00061    const bool top   ( 19 < jy ) ;
00062    const bool negz  ( 0 == jz ) ;
00063    const int lrl    ( 19>jx ? 0 : 1 ) ;
00064    const int lrr    ( 21>jx ? 0 : 1 ) ;
00065 
00066    return ( second ? jx/20 + 3*jz :  // 2nd plane split along middle
00067             ( negz && !top ? lrl + 2 :  // 1st plane at neg z and bottom half split at six=19&20
00068               ( negz && top ? lrr + 2 : // 1st plane at neg z and top half split at six=21&22
00069                 ( !negz && !top ? lrr + 4 : lrl + 4 ) ) ) ) ; // opposite at positive z
00070 }
00071 
00072 DetId 
00073 EcalPreshowerGeometry::detIdFromLocalAlignmentIndex( unsigned int iLoc )
00074 {
00075    return ESDetId( 1, 10 + 20*( iLoc%2 ), 10, 2>iLoc || 5<iLoc ? 2 : 1, 2*( iLoc/4 ) - 1 ) ;
00076 }
00077 
00078 unsigned int
00079 EcalPreshowerGeometry::alignmentTransformIndexGlobal( const DetId& /*id*/ )
00080 {
00081    return (unsigned int)DetId::Ecal - 1 ;
00082 }
00083 
00084 
00085 void 
00086 EcalPreshowerGeometry::initializeParms() 
00087 {
00088    unsigned int n1minus ( 0 ) ;
00089    unsigned int n2minus ( 0 ) ;
00090    unsigned int n1plus ( 0 ) ;
00091    unsigned int n2plus ( 0 ) ;
00092    CCGFloat z1minus ( 0 ) ;
00093    CCGFloat z2minus ( 0 ) ;
00094    CCGFloat z1plus ( 0 ) ;
00095    CCGFloat z2plus ( 0 ) ;
00096    const std::vector<DetId>& esDetIds ( getValidDetIds() ) ;
00097 
00098    for( unsigned int i ( 0 ) ; i != esDetIds.size() ; ++i )
00099    {
00100       const ESDetId esid ( esDetIds[i] ) ;
00101       const CaloCellGeometry* cell ( getGeometry( esid ) ) ;
00102       if( 0 != cell )
00103       {
00104          const CCGFloat zz ( cell->getPosition().z() ) ; 
00105          if( 1 == esid.plane() )
00106          {
00107             if( 0 > esid.zside() )
00108             {
00109                z1minus += zz ;
00110                ++n1minus ;
00111             }
00112             else
00113             {
00114                z1plus += zz ;
00115                ++n1plus ;
00116             }
00117          }
00118          if( 2 == esid.plane() )
00119          {
00120             if( 0 > esid.zside() )
00121             {
00122                z2minus += zz ;
00123                ++n2minus ;
00124             }
00125             else
00126             {
00127                z2plus += zz ;
00128                ++n2plus ;
00129             }
00130          }
00131       }
00132    }
00133    assert( 0 != n1minus &&
00134            0 != n2minus &&
00135            0 != n1plus  &&
00136            0 != n2plus     ) ;
00137    z1minus /= (1.*n1minus) ;
00138    z2minus /= (1.*n2minus) ;
00139    z1plus /= (1.*n1plus) ;
00140    z2plus /= (1.*n2plus) ;
00141    assert( 0 != z1minus &&
00142            0 != z2minus &&
00143            0 != z1plus  &&
00144            0 != z2plus     ) ;
00145    setzPlanes( z1minus, z2minus, z1plus, z2plus ) ;
00146 }
00147 
00148 
00149 void 
00150 EcalPreshowerGeometry::setzPlanes( CCGFloat z1minus, 
00151                                    CCGFloat z2minus,
00152                                    CCGFloat z1plus, 
00153                                    CCGFloat z2plus ) 
00154 {
00155    assert( 0 > z1minus &&
00156            0 > z2minus &&
00157            0 < z1plus  &&
00158            0 < z2plus     ) ;
00159 
00160    m_zplane[0] = z1minus ;
00161    m_zplane[1] = z2minus ;
00162    m_zplane[2] = z1plus ;
00163    m_zplane[3] = z2plus ;
00164 }
00165 
00166 
00167 // Get closest cell, etc...
00168 DetId 
00169 EcalPreshowerGeometry::getClosestCell( const GlobalPoint& point ) const
00170 {
00171   return getClosestCellInPlane( point, 2 );
00172 } 
00173 
00174 DetId 
00175 EcalPreshowerGeometry::getClosestCellInPlane( const GlobalPoint& point,
00176                                               int                plane          ) const
00177 {
00178    const CCGFloat x ( point.x() ) ;
00179    const CCGFloat y ( point.y() ) ;
00180    const CCGFloat z ( point.z() ) ;
00181 
00182    if( 0 == z    ||
00183        1 > plane ||
00184        2 < plane    ) return DetId( 0 ) ;
00185 
00186    const unsigned int iz ( ( 0>z ? 0 : 2 ) + plane - 1 ) ;
00187 
00188    const CCGFloat ze ( m_zplane[iz] ) ;
00189    const CCGFloat xe ( x * ze/z ) ;
00190    const CCGFloat ye ( y * ze/z ) ;
00191 
00192    const CCGFloat x0 ( 1 == plane ? xe : ye ) ;
00193    const CCGFloat y0 ( 1 == plane ? ye : xe ) ;
00194 
00195    static const CCGFloat xWid ( m_xWidWaf + m_xIntraLadGap + m_xInterLadGap ) ;
00196 
00197    const int row ( 1 + int( y0 + 20.*m_yWidAct - m_yCtrOff )/m_yWidAct ) ;
00198    const int col ( 1 + int( ( x0 + 20.*xWid )/xWid ) ) ;
00199 
00200    CCGFloat closest ( 1e9 ) ; 
00201 
00202    DetId detId ( 0 ) ;
00203 
00204    const int jz ( 0 > ze ? -1 : 1 ) ;
00205 
00206 
00207 //   std::cout<<"** p="<<point<<", ("<<xe<<", "<<ye<<", "<<ze<<"), row="<<row<<", col="<<col<<std::endl;
00208 
00209    for( int ix ( -1 ); ix != 2 ; ++ix ) // search within +-1 in row and col
00210    {
00211       for( int iy ( -1 ); iy != 2 ; ++iy )
00212       {
00213          for( int jstrip ( ESDetId::ISTRIP_MIN ) ; jstrip <= ESDetId::ISTRIP_MAX ; ++jstrip )
00214          {
00215             const int jx ( 1 == plane ? col + ix : row + iy ) ;
00216             const int jy ( 1 == plane ? row + iy : col + ix ) ;
00217             if( ESDetId::validDetId( jstrip, jx, jy, plane, jz ) )
00218             {
00219                const ESDetId esId ( jstrip, jx, jy, plane, jz ) ;
00220                const CaloCellGeometry* cell ( getGeometry( esId ) ) ;
00221                if( 0 != cell )
00222                {
00223                   const GlobalPoint& p ( cell->getPosition() ) ;
00224                   const CCGFloat dist2 ( (p.x()-xe)*(p.x()-xe) + (p.y()-ye)*(p.y()-ye) ) ;
00225                   if( dist2 < closest && present( esId ) )
00226                   {
00227                      closest = dist2 ;
00228                      detId   = esId  ;
00229                   }
00230                }
00231             }
00232          }
00233       }
00234    }
00235    return detId ;
00236 }
00237 
00238 void
00239 EcalPreshowerGeometry::localCorners( Pt3DVec&        lc  ,
00240                                      const CCGFloat* pv  ,
00241                                      unsigned int    /*i*/   ,
00242                                      Pt3D&           ref   )
00243 {
00244    PreshowerStrip::localCorners( lc, pv, ref ) ;
00245 }
00246 
00247 void
00248 EcalPreshowerGeometry::newCell( const GlobalPoint& f1 ,
00249                                 const GlobalPoint& /*f2*/ ,
00250                                 const GlobalPoint& /*f3*/ ,
00251                                 const CCGFloat*    parm ,
00252                                 const DetId&       detId    ) 
00253 {
00254    const unsigned int cellIndex ( ESDetId( detId ).denseIndex() ) ;
00255    m_cellVec[ cellIndex ] = PreshowerStrip( f1, cornersMgr(), parm ) ;
00256    m_validIds.push_back( detId ) ;
00257 }
00258 
00259 const CaloCellGeometry* 
00260 EcalPreshowerGeometry::cellGeomPtr( uint32_t index ) const
00261 {
00262    const CaloCellGeometry* cell ( &m_cellVec[ index ] ) ;
00263    return ( m_cellVec.size() < index ||
00264             0 == cell->param() ? 0 : cell ) ;
00265 }