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
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 )
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) )
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
00221 localCorners( lc, pv, ref ) ;
00222 Pt3D tmp ;
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
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 ) ) ;
00270 const CCGFloat ta2 ( tan( a2 ) ) ;
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
00316
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
00326
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
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 ) ;
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] ;
00346 }
00347
00348 if( refl ||
00349 h1>h2 )
00350 {
00351 if( 11.2 < dz )
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
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() ) ;
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