CMS 3D CMS Logo

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