00001 #include "Geometry/CaloGeometry/interface/IdealObliquePrism.h"
00002 #include <math.h>
00003
00004 namespace calogeom {
00005
00006 static GlobalPoint etaPhiR( float eta, float phi, float rad )
00007 {
00008 return GlobalPoint( rad*cosf(phi)/coshf(eta) ,
00009 rad*sinf(phi)/coshf(eta) ,
00010 rad*tanhf(eta) ) ;
00011 }
00012
00013 static GlobalPoint etaPhiPerp( float eta, float phi, float perp )
00014 {
00015 return GlobalPoint( perp*cosf(phi) ,
00016 perp*sinf(phi) ,
00017 perp*sinhf(eta) ) ;
00018 }
00019
00020 static GlobalPoint etaPhiZ(float eta, float phi, float z)
00021 {
00022 return GlobalPoint( z*cosf(phi)/sinhf(eta) ,
00023 z*sinf(phi)/sinhf(eta) ,
00024 z ) ;
00025 }
00026
00027 const CaloCellGeometry::CornersVec&
00028 IdealObliquePrism::getCorners() const
00029 {
00030 const CornersVec& co ( CaloCellGeometry::getCorners() ) ;
00031 if( co.uninitialized() )
00032 {
00033 CornersVec& corners ( setCorners() ) ;
00034 if( dz()>0 )
00035 {
00036
00037
00038
00039
00040 const GlobalPoint p ( getPosition() ) ;
00041 const float r_near ( p.perp()/cos(dPhi()) ) ;
00042 const float r_far ( r_near*( ( p.mag() + 2*dz() )/p.mag() ) ) ;
00043 const float eta ( p.eta() ) ;
00044 const float phi ( p.phi() ) ;
00045 corners[ 0 ] = etaPhiPerp( eta + dEta() , phi + dPhi() , r_near ) ;
00046 corners[ 1 ] = etaPhiPerp( eta + dEta() , phi - dPhi() , r_near ) ;
00047 corners[ 2 ] = etaPhiPerp( eta - dEta() , phi - dPhi() , r_near ) ;
00048 corners[ 3 ] = etaPhiPerp( eta - dEta() , phi + dPhi() , r_near ) ;
00049 corners[ 4 ] = etaPhiPerp( eta + dEta() , phi + dPhi() , r_far ) ;
00050 corners[ 5 ] = etaPhiPerp( eta + dEta() , phi - dPhi() , r_far ) ;
00051 corners[ 6 ] = etaPhiPerp( eta - dEta() , phi - dPhi() , r_far ) ;
00052 corners[ 7 ] = etaPhiPerp( eta - dEta() , phi + dPhi() , r_far ) ;
00053 }
00054 else
00055 {
00056
00057
00058
00059
00060 const GlobalPoint p ( getPosition() ) ;
00061 const float z_near ( p.z() ) ;
00062 const float mag ( p.mag() ) ;
00063 const float z_far ( z_near*( 1 - 2*dz()/mag ) ) ;
00064 const float eta ( p.eta() ) ;
00065 const float phi ( p.phi() ) ;
00066
00067 corners[ 0 ] = etaPhiZ( eta + dEta(), phi + dPhi(), z_near ) ;
00068 corners[ 1 ] = etaPhiZ( eta + dEta(), phi - dPhi(), z_near ) ;
00069 corners[ 2 ] = etaPhiZ( eta - dEta(), phi - dPhi(), z_near ) ;
00070 corners[ 3 ] = etaPhiZ( eta - dEta(), phi + dPhi(), z_near ) ;
00071 corners[ 4 ] = etaPhiZ( eta + dEta(), phi + dPhi(), z_far ) ;
00072 corners[ 5 ] = etaPhiZ( eta + dEta(), phi - dPhi(), z_far ) ;
00073 corners[ 6 ] = etaPhiZ( eta - dEta(), phi - dPhi(), z_far ) ;
00074 corners[ 7 ] = etaPhiZ( eta - dEta(), phi + dPhi(), z_far ) ;
00075
00076 }
00077 }
00078 return co ;
00079 }
00080
00081 bool
00082 IdealObliquePrism::inside( const GlobalPoint& point ) const
00083 {
00084
00085 bool is_inside ( false ) ;
00086
00087 const GlobalPoint& face ( getPosition() ) ;
00088
00089
00090 if( fabs( point.eta() - face.eta() ) <= dEta() &&
00091 fabs( point.phi() - face.phi() ) <= dPhi() )
00092 {
00093
00094 GlobalPoint face2 ( etaPhiR( face.eta(),
00095 face.phi(),
00096 face.mag() + 2*fabs( dz() ) ) );
00097 if( dz() > 0 )
00098 {
00099 const float projection ( point.perp()*cos( point.phi() - face.phi() ) ) ;
00100 is_inside = ( projection >= face.perp() &&
00101 projection <= face2.perp() ) ;
00102 }
00103 else
00104 {
00105 is_inside = ( ( ( face.z()<0 ) ? ( point.z()<=face.z() ) :
00106 ( point.z()>=face.z() ) ) &&
00107 ( ( face.z()<0 ) ? ( point.z()>=face2.z() ) :
00108 ( point.z()<=face2.z() ) ) );
00109 }
00110 }
00111 return is_inside;
00112 }
00113
00114 std::ostream& operator<<( std::ostream& s, const IdealObliquePrism& cell )
00115 {
00116 s << "Center: " << cell.getPosition() << std::endl ;
00117 s << "dEta = " << cell.dEta() << ", dPhi = " << cell.dPhi() << ", dz = " << cell.dz() << std::endl ;
00118 return s;
00119 }
00120
00121 }