CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/Geometry/CaloGeometry/src/TruncatedPyramid.cc

Go to the documentation of this file.
00001 #include "Geometry/CaloGeometry/interface/TruncatedPyramid.h"
00002 #include <algorithm>
00003 #include <iostream>
00004 
00005 
00006 typedef TruncatedPyramid::CCGFloat CCGFloat ;
00007 typedef TruncatedPyramid::Pt3D     Pt3D     ;
00008 typedef TruncatedPyramid::Pt3DVec  Pt3DVec  ;
00009 typedef TruncatedPyramid::Tr3D     Tr3D     ;
00010 
00011 typedef HepGeom::Vector3D<CCGFloat> Vec3D   ;
00012 typedef HepGeom::Plane3D<CCGFloat>  Plane3D ;
00013 
00014 typedef HepGeom::Vector3D<double> DVec3D ;
00015 typedef HepGeom::Plane3D<double>  DPlane3D ;
00016 typedef HepGeom::Point3D<double>  DPt3D ;
00017 
00018 //----------------------------------------------------------------------
00019 
00020 TruncatedPyramid::TruncatedPyramid() : 
00021    CaloCellGeometry() ,
00022    m_axis ( 0., 0., 0. ),
00023    m_corOne ( 0., 0., 0. ) 
00024 {}
00025 
00026 TruncatedPyramid::TruncatedPyramid( const TruncatedPyramid& tr )
00027   : CaloCellGeometry( tr )
00028 {
00029   *this = tr ; 
00030 }
00031 
00032 TruncatedPyramid& 
00033 TruncatedPyramid::operator=( const TruncatedPyramid& tr ) 
00034 {
00035    CaloCellGeometry::operator=( tr ) ;
00036    if( this != &tr )
00037    {
00038       m_axis   = tr.m_axis ;
00039       m_corOne = tr.m_corOne ; 
00040    }
00041    return *this ; 
00042 }
00043 
00044 TruncatedPyramid::TruncatedPyramid( const CornersMgr*  cMgr ,
00045                                     const GlobalPoint& fCtr ,
00046                                     const GlobalPoint& bCtr ,
00047                                     const GlobalPoint& cor1 ,
00048                                     const CCGFloat*    parV   ) :
00049    CaloCellGeometry ( fCtr, cMgr, parV ) ,
00050    m_axis           ( ( bCtr - fCtr ).unit() ) ,
00051    m_corOne         ( cor1.x(), cor1.y(), cor1.z() ) 
00052 {} 
00053 
00054 TruncatedPyramid::TruncatedPyramid( const CornersVec& corn ,
00055                                     const CCGFloat*   par    ) :
00056    CaloCellGeometry ( corn, par   ) , 
00057    m_axis           ( makeAxis()  ) ,
00058    m_corOne         ( corn[0].x(), corn[0].y(), corn[0].z()  )
00059 {} 
00060 
00061 TruncatedPyramid::~TruncatedPyramid() 
00062 {}
00063 
00064 const GlobalPoint 
00065 TruncatedPyramid::getPosition( CCGFloat depth ) const 
00066 {
00067    return CaloCellGeometry::getPosition() + depth*m_axis ;
00068 }
00069 
00070 CCGFloat 
00071 TruncatedPyramid::getThetaAxis() const 
00072 { 
00073    return m_axis.theta() ; 
00074 } 
00075 
00076 CCGFloat 
00077 TruncatedPyramid::getPhiAxis() const 
00078 {
00079    return m_axis.phi() ; 
00080 } 
00081 
00082 const GlobalVector& 
00083 TruncatedPyramid::axis() const
00084 { 
00085    return m_axis ; 
00086 }
00087 
00088 void
00089 TruncatedPyramid::vocalCorners( Pt3DVec&        vec ,
00090                                 const CCGFloat* pv  ,
00091                                 Pt3D&           ref  ) const
00092 { 
00093    localCorners( vec, pv, ref ) ; 
00094 }
00095 
00096 GlobalVector 
00097 TruncatedPyramid::makeAxis() 
00098 { 
00099    return GlobalVector( backCtr() -
00100                         CaloCellGeometry::getPosition() ).unit() ;
00101 }
00102 
00103 const GlobalPoint 
00104 TruncatedPyramid::backCtr() const 
00105 {
00106    return GlobalPoint( 0.25*( getCorners()[4].x() + getCorners()[5].x() +
00107                               getCorners()[6].x() + getCorners()[7].x() ),
00108                        0.25*( getCorners()[4].y() + getCorners()[5].y() +
00109                               getCorners()[6].y() + getCorners()[7].y() ),
00110                        0.25*( getCorners()[4].z() + getCorners()[5].z() +
00111                               getCorners()[6].z() + getCorners()[7].z() ) ) ;
00112 }
00113 
00114 void
00115 TruncatedPyramid::getTransform( Tr3D& tr, Pt3DVec* lptr ) const 
00116 {
00117    const GlobalPoint& p ( CaloCellGeometry::getPosition() ) ;
00118    const Pt3D         gFront ( p.x(), p.y(), p.z() ) ;
00119    const DPt3D        dgFront ( p.x(), p.y(), p.z() ) ;
00120 
00121    const double dz ( param()[0] ) ;
00122 
00123    Pt3D  lFront ;
00124    assert( 0 != param() ) ;
00125    std::vector<Pt3D > lc( 8, Pt3D(0,0,0) ) ;
00126    if( 11.2 > dz )
00127    {
00128       localCorners( lc, param(), lFront ) ;
00129    }
00130    else
00131    {
00132       localCornersSwap( lc, param(), lFront ) ;
00133    }
00134 
00135    // figure out if reflction volume or not
00136 
00137    Pt3D  lBack  ( 0.25*(lc[4]+lc[5]+lc[6]+lc[7]) ) ;
00138 
00139    const double disl ( ( lFront - lc[0] ).mag() ) ;
00140    const double disr ( ( lFront - lc[3] ).mag() ) ;
00141    const double disg ( ( gFront - m_corOne ).mag() ) ;
00142 
00143    const double dell ( fabs( disg - disl ) ) ;
00144    const double delr ( fabs( disg - disr ) ) ;
00145 
00146    if( 11.2<dz &&
00147        delr < dell ) // reflection volume if true
00148    {
00149       localCornersReflection( lc, param(), lFront ) ;
00150       lBack  = 0.25*( lc[4] + lc[5] + lc[6] + lc[7] ) ;
00151    }
00152 
00153    const DPt3D dlFront ( lFront.x(), lFront.y(), lFront.z() ) ;
00154    const DPt3D dlBack  ( lBack.x() , lBack.y() , lBack.z()  ) ;
00155    const DPt3D dlOne   ( lc[0].x() , lc[0].y() , lc[0].z()  ) ;
00156 
00157    const Vec3D dgAxis  ( axis().x(), axis().y(), axis().z() ) ;
00158 
00159    const DPt3D dmOne   ( m_corOne.x(), m_corOne.y(), m_corOne.z() ) ;
00160 
00161    const DPt3D dgBack  ( dgFront + ( dlBack - dlFront ).mag()*dgAxis ) ;
00162    DPt3D dgOne ( dgFront + ( dlOne - dlFront ).mag()*( dmOne - dgFront ).unit() ) ;
00163 
00164    const double dlangle ( ( dlBack - dlFront).angle( dlOne - dlFront ) ) ;
00165    const double dgangle ( ( dgBack - dgFront).angle( dgOne - dgFront ) ) ;
00166    const double dangle  ( dlangle - dgangle ) ;
00167 
00168    if( 1.e-6 < fabs(dangle) )//guard against precision problems
00169    {
00170       const DPlane3D dgPl ( dgFront, dgOne, dgBack ) ;
00171       const DPt3D    dp2  ( dgFront + dgPl.normal().unit() ) ;
00172 
00173       DPt3D dgOld ( dgOne ) ;
00174 
00175       dgOne = ( dgFront + HepGeom::Rotate3D( -dangle, dgFront, dp2 )*
00176                 DVec3D( dgOld - dgFront ) ) ;
00177    }
00178 
00179    tr = Tr3D( dlFront , dlBack , dlOne ,
00180               dgFront , dgBack , dgOne    ) ;
00181 
00182    if( 0 != lptr ) (*lptr) = lc ;
00183 }
00184 
00185 const CaloCellGeometry::CornersVec& 
00186 TruncatedPyramid::getCorners() const 
00187 {
00188    const CornersVec& co ( CaloCellGeometry::getCorners() ) ;
00189    if( co.uninitialized() ) 
00190    {
00191       CornersVec& corners ( setCorners() ) ;
00192 
00193       Pt3DVec lc ;
00194 
00195       Tr3D tr ;
00196       getTransform( tr, &lc ) ;
00197 
00198       for( unsigned int i ( 0 ) ; i != 8 ; ++i )
00199       {
00200          const Pt3D corn ( tr*lc[i] ) ;
00201          corners[i] = GlobalPoint( corn.x(), corn.y(), corn.z() ) ;
00202       }
00203    }
00204    return co ;
00205 }
00206 
00207 namespace truncPyr
00208 {
00209    Pt3D  refl( const Pt3D & p )
00210    {
00211       return Pt3D ( -p.x(), p.y(), p.z() ) ;
00212    }
00213 }
00214 
00215 void
00216 TruncatedPyramid::localCornersReflection( Pt3DVec&        lc  ,
00217                                           const CCGFloat* pv  ,
00218                                           Pt3D&           ref  )
00219 {
00220 //   using namespace truncPyr ;
00221    localCorners( lc, pv, ref ) ;
00222    Pt3D    tmp ;
00223 /*
00224    tmp   = lc[0] ;
00225    lc[0] = refl( lc[2] ) ;
00226    lc[2] = refl( tmp   ) ;
00227    tmp   = lc[1] ;
00228    lc[1] = refl( lc[3] ) ;
00229    lc[3] = refl( tmp   ) ;
00230    tmp   = lc[4] ;
00231    lc[4] = refl( lc[6] ) ;
00232    lc[6] = refl( tmp   ) ;
00233    tmp   = lc[5] ;
00234    lc[5] = refl( lc[7] ) ;
00235    lc[7] = refl( tmp   ) ;
00236 */
00237    lc[0] = truncPyr::refl( lc[0] ) ;
00238    lc[1] = truncPyr::refl( lc[1] ) ;
00239    lc[2] = truncPyr::refl( lc[2] ) ;
00240    lc[3] = truncPyr::refl( lc[3] ) ;
00241    lc[4] = truncPyr::refl( lc[4] ) ;
00242    lc[5] = truncPyr::refl( lc[5] ) ;
00243    lc[6] = truncPyr::refl( lc[6] ) ;
00244    lc[7] = truncPyr::refl( lc[7] ) ;
00245 
00246    ref   = 0.25*( lc[0] + lc[1] + lc[2] + lc[3] ) ;
00247 }
00248 
00249 void
00250 TruncatedPyramid::localCorners( Pt3DVec&        lc  ,
00251                                 const CCGFloat* pv  ,
00252                                 Pt3D&           ref   )
00253 {
00254    assert( 0 != pv ) ;
00255    assert( 8 == lc.size() ) ;
00256 
00257    const CCGFloat dz ( pv[0] ) ;
00258    const CCGFloat th ( pv[1] ) ;
00259    const CCGFloat ph ( pv[2] ) ;
00260    const CCGFloat h1 ( pv[3] ) ;
00261    const CCGFloat b1 ( pv[4] ) ;
00262    const CCGFloat t1 ( pv[5] ) ;
00263    const CCGFloat a1 ( pv[6] ) ;
00264    const CCGFloat h2 ( pv[7] ) ;
00265    const CCGFloat b2 ( pv[8] ) ;
00266    const CCGFloat t2 ( pv[9] ) ;
00267    const CCGFloat a2 ( pv[10]) ;
00268   
00269    const CCGFloat ta1 ( tan( a1 ) ) ; // lower plane
00270    const CCGFloat ta2 ( tan( a2 ) ) ; // upper plane
00271 
00272    const CCGFloat tth   ( tan( th )       ) ;
00273    const CCGFloat tthcp ( tth * cos( ph ) ) ;
00274    const CCGFloat tthsp ( tth * sin( ph ) ) ;
00275 
00276    const unsigned int off ( h1<h2 ? 0 :  4 ) ;
00277 
00278    lc[0+off] = Pt3D ( -dz*tthcp - h1*ta1 - b1, -dz*tthsp - h1 , -dz ); // (-,-,-)
00279    lc[1+off] = Pt3D ( -dz*tthcp + h1*ta1 - t1, -dz*tthsp + h1 , -dz ); // (-,+,-)
00280    lc[2+off] = Pt3D ( -dz*tthcp + h1*ta1 + t1, -dz*tthsp + h1 , -dz ); // (+,+,-)
00281    lc[3+off] = Pt3D ( -dz*tthcp - h1*ta1 + b1, -dz*tthsp - h1 , -dz ); // (+,-,-)
00282    lc[4-off] = Pt3D (  dz*tthcp - h2*ta2 - b2,  dz*tthsp - h2 ,  dz ); // (-,-,+)
00283    lc[5-off] = Pt3D (  dz*tthcp + h2*ta2 - t2,  dz*tthsp + h2 ,  dz ); // (-,+,+)
00284    lc[6-off] = Pt3D (  dz*tthcp + h2*ta2 + t2,  dz*tthsp + h2 ,  dz ); // (+,+,+)
00285    lc[7-off] = Pt3D (  dz*tthcp - h2*ta2 + b2,  dz*tthsp - h2 ,  dz ); // (+,-,+)
00286 
00287    ref   = 0.25*( lc[0] + lc[1] + lc[2] + lc[3] ) ;
00288 }
00289 
00290 void
00291 TruncatedPyramid::localCornersSwap( Pt3DVec&        lc  ,
00292                                     const CCGFloat* pv  ,
00293                                     Pt3D&           ref  )
00294 {
00295    localCorners( lc, pv, ref ) ;
00296 
00297    Pt3D  tmp ;
00298    tmp   = lc[0] ;
00299    lc[0] = lc[3] ;
00300    lc[3] = tmp   ;
00301    tmp   = lc[1] ;
00302    lc[1] = lc[2] ;
00303    lc[2] = tmp   ;
00304    tmp   = lc[4] ;
00305    lc[4] = lc[7] ;
00306    lc[7] = tmp   ;
00307    tmp   = lc[5] ;
00308    lc[5] = lc[6] ;
00309    lc[6] = tmp   ;
00310 
00311    ref   = 0.25*( lc[0] + lc[1] + lc[2] + lc[3] ) ;
00312 }
00313 
00314 
00315 // the following function is static and a helper for the endcap & barrel loader classes
00316 // when initializing from DDD: fills corners vector from trap params plus transform
00317 
00318 void 
00319 TruncatedPyramid::createCorners( const std::vector<CCGFloat>&  pv ,
00320                                  const Tr3D&                   tr ,
00321                                  std::vector<GlobalPoint>&     co   )
00322 {
00323    assert( 11 == pv.size() ) ;
00324    assert( 8 == co.size() ) ;
00325    // to get the ordering right for fast sim, we have to use their convention
00326    // which were based on the old static geometry. Some gymnastics required here.
00327 
00328    const CCGFloat dz ( pv[0] ) ;
00329    const CCGFloat h1 ( pv[3] ) ;
00330    const CCGFloat h2 ( pv[7] ) ;
00331    Pt3DVec        ko ( 8, Pt3D(0,0,0) ) ;
00332 
00333    // if reflection, different things for barrel and endcap
00334    static const Vec3D  x ( 1, 0, 0 ) ;
00335    static const Vec3D  y ( 0, 1, 0 ) ;
00336    static const Vec3D  z ( 0, 0, 1 ) ;
00337    const bool refl ( ( ( tr*x ).cross( tr*y ) ).dot( tr*z ) < 0 ) ; // has reflection!
00338 
00339    Pt3D    tmp ;
00340    Pt3DVec to ( 8, Pt3D(0,0,0) ) ;
00341    localCorners( to, &pv.front(), tmp ) ;
00342 
00343    for( unsigned int i ( 0 ) ; i != 8 ; ++i )
00344    {
00345       ko[i] = tr * to[i] ; // apply transformation
00346    }
00347 
00348    if( refl || 
00349        h1>h2  )
00350    {
00351       if( 11.2 < dz ) //barrel
00352       {
00353          if( !refl )
00354          {
00355             to[0] = ko[3] ;
00356             to[1] = ko[2] ;
00357             to[2] = ko[1] ;
00358             to[3] = ko[0] ;
00359             to[4] = ko[7] ;
00360             to[5] = ko[6] ;
00361             to[6] = ko[5] ;      
00362             to[7] = ko[4] ;      
00363          }
00364          else
00365          {
00366             to[0] = ko[0] ;
00367             to[1] = ko[1] ;
00368             to[2] = ko[2] ;
00369             to[3] = ko[3] ;
00370             to[4] = ko[4] ;
00371             to[5] = ko[5] ;
00372             to[6] = ko[6] ;      
00373             to[7] = ko[7] ;      
00374          }
00375       }
00376       else //endcap
00377       {
00378          to[0] = ko[0] ;
00379          to[1] = ko[3] ;
00380          to[2] = ko[2] ;
00381          to[3] = ko[1] ;
00382          to[4] = ko[4] ;
00383          to[5] = ko[7] ;
00384          to[6] = ko[6] ;      
00385          to[7] = ko[5] ;      
00386       }
00387       copy( to.begin(), to.end(), ko.begin() ) ; // faster than ko = to ? maybe.
00388    }
00389    for( unsigned int i ( 0 ) ; i != 8 ; ++i )
00390    {
00391       const Pt3D & p ( ko[i] ) ;
00392       co[ i ] = GlobalPoint( p.x(), p.y(), p.z() ) ;
00393    }
00394 }
00395 //----------------------------------------------------------------------
00396 //----------------------------------------------------------------------
00397 
00398 std::ostream& operator<<( std::ostream& s, const TruncatedPyramid& cell ) 
00399 {
00400    s << "Center: " <<  ( (const CaloCellGeometry&) cell).getPosition() << std::endl;
00401    const float thetaaxis ( cell.getThetaAxis() ) ;
00402    const float phiaxis   ( cell.getPhiAxis()   ) ;
00403    s << "Axis: " <<  thetaaxis << " " << phiaxis << std::endl ;
00404    const CaloCellGeometry::CornersVec& corners ( cell.getCorners() ) ;
00405    for ( unsigned int i=0 ; i != corners.size() ; ++i ) 
00406    {
00407       s << "Corner: " << corners[i] << std::endl;
00408    }
00409   return s ;
00410 }
00411