CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/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 //#include "assert.h"
00005 
00006 //----------------------------------------------------------------------
00007 
00008 HepGeom::Transform3D
00009 TruncatedPyramid::getTransform( std::vector<HepGeom::Point3D<double> >* lptr ) const 
00010 {
00011    const GlobalPoint& p ( CaloCellGeometry::getPosition() ) ;
00012    const HepGeom::Point3D<double>    gFront ( p.x(), p.y(), p.z() ) ;
00013 
00014    const double dz ( param()[0] ) ;
00015 
00016    HepGeom::Point3D<double>  lFront ;
00017    assert(                               0 != param() ) ;
00018    std::vector<HepGeom::Point3D<double> > lc ( 11.2 > dz ?
00019                                 localCorners( param(), lFront ) :
00020                                 localCornersSwap( param(), lFront )  ) ;
00021 
00022    // figure out if reflction volume or not
00023 
00024    HepGeom::Point3D<double>  lBack  ( 0.25*(lc[4]+lc[5]+lc[6]+lc[7]) ) ;
00025 
00026    assert( 0 != m_corOne ) ;
00027 
00028    const double disl ( ( lFront - lc[0] ).mag() ) ;
00029    const double disr ( ( lFront - lc[3] ).mag() ) ;
00030    const double disg ( ( gFront - (*m_corOne) ).mag() ) ;
00031 
00032    const double dell ( fabs( disg - disl ) ) ;
00033    const double delr ( fabs( disg - disr ) ) ;
00034 
00035    if( 11.2<dz &&
00036        delr < dell ) // reflection volume if true
00037    {
00038       lc = localCornersReflection( param(), lFront ) ;
00039       lBack  = 0.25*( lc[4] + lc[5] + lc[6] + lc[7] ) ;
00040    }
00041 
00042    const HepGeom::Point3D<double>  lOne  ( lc[0] ) ;
00043 
00044    const HepGeom::Vector3D<double>  gAxis ( axis().x(), axis().y(), axis().z() ) ;
00045 
00046 
00047    const HepGeom::Point3D<double>  gBack ( gFront + (lBack-lFront).mag()*gAxis ) ;
00048    const HepGeom::Point3D<double>  gOneT ( gFront + ( lOne - lFront ).mag()*( (*m_corOne) - gFront ).unit() ) ;
00049 
00050    const double langle ( ( lBack - lFront).angle( lOne - lFront ) ) ;
00051    const double gangle ( ( gBack - gFront).angle( gOneT- gFront ) ) ;
00052    const double dangle ( langle - gangle ) ;
00053 
00054    const HepGeom::Plane3D<double>  gPl (  gFront, gOneT, gBack ) ;
00055    const HepGeom::Point3D<double>  p2  ( gFront + gPl.normal().unit() ) ;
00056 
00057    const HepGeom::Point3D<double>  gOne ( gFront + HepGeom::Rotate3D( -dangle, gFront, p2 )*
00058                            HepGeom::Vector3D<double> ( gOneT - gFront ) ) ;
00059 
00060    const HepGeom::Transform3D tr ( lFront , lBack , lOne ,
00061                              gFront , gBack , gOne    ) ;
00062 
00063    if( 0 != lptr ) (*lptr) = lc ;
00064 
00065    return tr ;
00066 }
00067 
00068 const CaloCellGeometry::CornersVec& 
00069 TruncatedPyramid::getCorners() const 
00070 {
00071    const CornersVec& co ( CaloCellGeometry::getCorners() ) ;
00072    if( co.uninitialized() ) 
00073    {
00074       CornersVec& corners ( setCorners() ) ;
00075 
00076       std::vector<HepGeom::Point3D<double> > lc ;
00077 
00078       const HepGeom::Transform3D tr ( getTransform( &lc ) ) ;
00079 
00080       for( unsigned int i ( 0 ) ; i != 8 ; ++i )
00081       {
00082          const HepGeom::Point3D<double>  corn ( tr*lc[i] ) ;
00083          corners[i] = GlobalPoint( corn.x(), corn.y(), corn.z() ) ;
00084       }
00085 
00086       delete m_corOne ; // no longer needed
00087       m_corOne = 0 ;
00088    }
00089    return co ;
00090 }
00091 
00092 namespace truncPyr
00093 {
00094    HepGeom::Point3D<double>  refl( const HepGeom::Point3D<double> & p )
00095    {
00096       return HepGeom::Point3D<double> ( -p.x(), p.y(), p.z() ) ;
00097    }
00098 }
00099 
00100 std::vector<HepGeom::Point3D<double> >
00101 TruncatedPyramid::localCornersReflection( const double* pv,
00102                                           HepGeom::Point3D<double> &   ref )
00103 {
00104 //   using namespace truncPyr ;
00105 
00106    std::vector<HepGeom::Point3D<double> > lc ( localCorners( pv, ref ) ) ;
00107    HepGeom::Point3D<double>  tmp ;
00108 /*
00109    tmp   = lc[0] ;
00110    lc[0] = refl( lc[2] ) ;
00111    lc[2] = refl( tmp   ) ;
00112    tmp   = lc[1] ;
00113    lc[1] = refl( lc[3] ) ;
00114    lc[3] = refl( tmp   ) ;
00115    tmp   = lc[4] ;
00116    lc[4] = refl( lc[6] ) ;
00117    lc[6] = refl( tmp   ) ;
00118    tmp   = lc[5] ;
00119    lc[5] = refl( lc[7] ) ;
00120    lc[7] = refl( tmp   ) ;
00121 */
00122    lc[0] = truncPyr::refl( lc[0] ) ;
00123    lc[1] = truncPyr::refl( lc[1] ) ;
00124    lc[2] = truncPyr::refl( lc[2] ) ;
00125    lc[3] = truncPyr::refl( lc[3] ) ;
00126    lc[4] = truncPyr::refl( lc[4] ) ;
00127    lc[5] = truncPyr::refl( lc[5] ) ;
00128    lc[6] = truncPyr::refl( lc[6] ) ;
00129    lc[7] = truncPyr::refl( lc[7] ) ;
00130 
00131 
00132    ref   = 0.25*( lc[0] + lc[1] + lc[2] + lc[3] ) ;
00133    return lc ;
00134 }
00135 
00136 std::vector<HepGeom::Point3D<double> >
00137 TruncatedPyramid::localCorners( const double* pv,
00138                                 HepGeom::Point3D<double> &   ref )
00139 {
00140    assert( 0 != pv ) ;
00141 
00142    const double dz ( pv[0] ) ;
00143    const double th ( pv[1] ) ;
00144    const double ph ( pv[2] ) ;
00145    const double h1 ( pv[3] ) ;
00146    const double b1 ( pv[4] ) ;
00147    const double t1 ( pv[5] ) ;
00148    const double a1 ( pv[6] ) ;
00149    const double h2 ( pv[7] ) ;
00150    const double b2 ( pv[8] ) ;
00151    const double t2 ( pv[9] ) ;
00152    const double a2 ( pv[10]) ;
00153   
00154    const double ta1 ( tan( a1 ) ) ; // lower plane
00155    const double ta2 ( tan( a2 ) ) ; // upper plane
00156 
00157    const double tth   ( tan( th )       ) ;
00158    const double tthcp ( tth * cos( ph ) ) ;
00159    const double tthsp ( tth * sin( ph ) ) ;
00160 
00161    const unsigned int off ( h1<h2 ? 0 :  4 ) ;
00162 
00163    std::vector<HepGeom::Point3D<double> > lc ( 8, HepGeom::Point3D<double> (0,0,0) ) ;
00164 
00165    lc[0+off] = HepGeom::Point3D<double> ( -dz*tthcp - h1*ta1 - b1, -dz*tthsp - h1 , -dz ); // (-,-,-)
00166    lc[1+off] = HepGeom::Point3D<double> ( -dz*tthcp + h1*ta1 - t1, -dz*tthsp + h1 , -dz ); // (-,+,-)
00167    lc[2+off] = HepGeom::Point3D<double> ( -dz*tthcp + h1*ta1 + t1, -dz*tthsp + h1 , -dz ); // (+,+,-)
00168    lc[3+off] = HepGeom::Point3D<double> ( -dz*tthcp - h1*ta1 + b1, -dz*tthsp - h1 , -dz ); // (+,-,-)
00169    lc[4-off] = HepGeom::Point3D<double> (  dz*tthcp - h2*ta2 - b2,  dz*tthsp - h2 ,  dz ); // (-,-,+)
00170    lc[5-off] = HepGeom::Point3D<double> (  dz*tthcp + h2*ta2 - t2,  dz*tthsp + h2 ,  dz ); // (-,+,+)
00171    lc[6-off] = HepGeom::Point3D<double> (  dz*tthcp + h2*ta2 + t2,  dz*tthsp + h2 ,  dz ); // (+,+,+)
00172    lc[7-off] = HepGeom::Point3D<double> (  dz*tthcp - h2*ta2 + b2,  dz*tthsp - h2 ,  dz ); // (+,-,+)
00173 
00174    ref   = 0.25*( lc[0] + lc[1] + lc[2] + lc[3] ) ;
00175 
00176    return lc ;
00177 }
00178 
00179 std::vector<HepGeom::Point3D<double> >
00180 TruncatedPyramid::localCornersSwap( const double* pv,
00181                                     HepGeom::Point3D<double> &   ref )
00182 {
00183    std::vector<HepGeom::Point3D<double> > lc ( localCorners( pv, ref ) ) ;
00184 
00185    HepGeom::Point3D<double>  tmp ;
00186    tmp   = lc[0] ;
00187    lc[0] = lc[3] ;
00188    lc[3] = tmp   ;
00189    tmp   = lc[1] ;
00190    lc[1] = lc[2] ;
00191    lc[2] = tmp   ;
00192    tmp   = lc[4] ;
00193    lc[4] = lc[7] ;
00194    lc[7] = tmp   ;
00195    tmp   = lc[5] ;
00196    lc[5] = lc[6] ;
00197    lc[6] = tmp   ;
00198 
00199    ref   = 0.25*( lc[0] + lc[1] + lc[2] + lc[3] ) ;
00200 
00201    return lc ;
00202 }
00203 
00204 
00205 // the following function is static and a helper for the endcap & barrel loader classes
00206 // when initializing from DDD: fills corners vector from trap params plus transform
00207 
00208 void 
00209 TruncatedPyramid::createCorners( const std::vector<double>&    pv ,
00210                                  const HepGeom::Transform3D&         tr ,
00211                                  CaloCellGeometry::CornersVec& co   )
00212 {
00213    assert( 11 == pv.size() ) ;
00214 
00215    // to get the ordering right for fast sim, we have to use their convention
00216    // which were based on the old static geometry. Some gymnastics required here.
00217 
00218    const double dz ( pv[0] ) ;
00219    const double h1 ( pv[3] ) ;
00220    const double h2 ( pv[7] ) ;
00221    std::vector<HepGeom::Point3D<double> > ko ( 8, HepGeom::Point3D<double> (0,0,0) ) ;
00222 
00223    // if reflection, different things for barrel and endcap
00224    static const HepGeom::Vector3D<double>  x ( 1, 0, 0 ) ;
00225    static const HepGeom::Vector3D<double>  y ( 0, 1, 0 ) ;
00226    static const HepGeom::Vector3D<double>  z ( 0, 0, 1 ) ;
00227    const bool refl ( ( ( tr*x ).cross( tr*y ) ).dot( tr*z ) < 0 ) ; // has reflection!
00228 
00229 
00230    HepGeom::Point3D<double>  tmp ;
00231    std::vector<HepGeom::Point3D<double> > to ( localCorners( &pv.front(), tmp ) ) ;
00232 
00233    for( unsigned int i ( 0 ) ; i != 8 ; ++i )
00234    {
00235       ko[i] = tr * to[i] ; // apply transformation
00236    }
00237 
00238    if( refl || 
00239        h1>h2  )
00240    {
00241       if( 11.2 < dz ) //barrel
00242       {
00243          if( !refl )
00244          {
00245             to[0] = ko[3] ;
00246             to[1] = ko[2] ;
00247             to[2] = ko[1] ;
00248             to[3] = ko[0] ;
00249             to[4] = ko[7] ;
00250             to[5] = ko[6] ;
00251             to[6] = ko[5] ;      
00252             to[7] = ko[4] ;      
00253          }
00254          else
00255          {
00256             to[0] = ko[0] ;
00257             to[1] = ko[1] ;
00258             to[2] = ko[2] ;
00259             to[3] = ko[3] ;
00260             to[4] = ko[4] ;
00261             to[5] = ko[5] ;
00262             to[6] = ko[6] ;      
00263             to[7] = ko[7] ;      
00264          }
00265       }
00266       else //endcap
00267       {
00268          to[0] = ko[0] ;
00269          to[1] = ko[3] ;
00270          to[2] = ko[2] ;
00271          to[3] = ko[1] ;
00272          to[4] = ko[4] ;
00273          to[5] = ko[7] ;
00274          to[6] = ko[6] ;      
00275          to[7] = ko[5] ;      
00276       }
00277       copy( to.begin(), to.end(), ko.begin() ) ; // faster than ko = to ? maybe.
00278    }
00279    for( unsigned int i ( 0 ) ; i != 8 ; ++i )
00280    {
00281       const HepGeom::Point3D<double> & p ( ko[i] ) ;
00282       co[ i ] = GlobalPoint( p.x(), p.y(), p.z() ) ;
00283    }
00284 }
00285 //----------------------------------------------------------------------
00286 //----------------------------------------------------------------------
00287 
00288 std::ostream& operator<<( std::ostream& s, const TruncatedPyramid& cell ) 
00289 {
00290    s << "Center: " <<  ( (const CaloCellGeometry&) cell).getPosition() << std::endl;
00291    const float thetaaxis ( cell.getThetaAxis() ) ;
00292    const float phiaxis   ( cell.getPhiAxis()   ) ;
00293    s << "Axis: " <<  thetaaxis << " " << phiaxis << std::endl ;
00294    const CaloCellGeometry::CornersVec& corners ( cell.getCorners() ) ;
00295    for ( unsigned int i=0 ; i != corners.size() ; ++i ) 
00296    {
00297       s << "Corner: " << corners[i] << std::endl;
00298    }
00299   return s ;
00300 }
00301