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
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 )
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) )
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
00224 localCorners( lc, pv, ref ) ;
00225 Pt3D tmp ;
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
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 ) ) ;
00273 const CCGFloat ta2 ( tan( a2 ) ) ;
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
00319
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
00329
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
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 ) ;
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] ;
00349 }
00350
00351 if( refl ||
00352 h1>h2 )
00353 {
00354 if( 11.2 < dz )
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
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() ) ;
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