00001 #include "Geometry/CaloGeometry/interface/TruncatedPyramid.h"
00002 #include <algorithm>
00003 #include <iostream>
00004
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
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 )
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 ;
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
00105
00106 std::vector<HepGeom::Point3D<double> > lc ( localCorners( pv, ref ) ) ;
00107 HepGeom::Point3D<double> tmp ;
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
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 ) ) ;
00155 const double ta2 ( tan( a2 ) ) ;
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
00206
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
00216
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
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 ) ;
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] ;
00236 }
00237
00238 if( refl ||
00239 h1>h2 )
00240 {
00241 if( 11.2 < dz )
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
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() ) ;
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