CMS 3D CMS Logo

IdealObliquePrism.cc

Go to the documentation of this file.
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             /* In this case, the faces are parallel to the zaxis.  
00037                This implies that all corners will have the same 
00038                cylindrical radius. 
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 ) ; // (+,+,near)
00046             corners[ 1 ] = etaPhiPerp( eta + dEta() , phi - dPhi() , r_near ) ; // (+,-,near)
00047             corners[ 2 ] = etaPhiPerp( eta - dEta() , phi - dPhi() , r_near ) ; // (-,-,near)
00048             corners[ 3 ] = etaPhiPerp( eta - dEta() , phi + dPhi() , r_near ) ; // (-,+,near)
00049             corners[ 4 ] = etaPhiPerp( eta + dEta() , phi + dPhi() , r_far ) ; // (+,+,far)
00050             corners[ 5 ] = etaPhiPerp( eta + dEta() , phi - dPhi() , r_far ) ; // (+,-,far)
00051             corners[ 6 ] = etaPhiPerp( eta - dEta() , phi - dPhi() , r_far ) ; // (-,-,far)
00052             corners[ 7 ] = etaPhiPerp( eta - dEta() , phi + dPhi() , r_far ) ; // (-,+,far)
00053          } 
00054          else 
00055          {
00056             /* In this case, the faces are perpendicular to the zaxis.  
00057                This implies that all corners will have the same 
00058                z-dimension. 
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 ) ) ; // negative to correct sign
00064             const float       eta    ( p.eta() ) ;
00065             const float       phi    ( p.phi() ) ;
00066             
00067             corners[ 0 ] = etaPhiZ( eta + dEta(), phi + dPhi(), z_near ) ; // (+,+,near)
00068             corners[ 1 ] = etaPhiZ( eta + dEta(), phi - dPhi(), z_near ) ; // (+,-,near)
00069             corners[ 2 ] = etaPhiZ( eta - dEta(), phi - dPhi(), z_near ) ; // (-,-,near)
00070             corners[ 3 ] = etaPhiZ( eta - dEta(), phi + dPhi(), z_near ) ; // (-,+,near)
00071             corners[ 4 ] = etaPhiZ( eta + dEta(), phi + dPhi(), z_far  ) ; // (+,+,far)
00072             corners[ 5 ] = etaPhiZ( eta + dEta(), phi - dPhi(), z_far  ) ; // (+,-,far)
00073             corners[ 6 ] = etaPhiZ( eta - dEta(), phi - dPhi(), z_far  ) ; // (-,-,far)
00074             corners[ 7 ] = etaPhiZ( eta - dEta(), phi + dPhi(), z_far  ) ; // (-,+,far)
00075 
00076          }
00077       }
00078       return co ;
00079    }
00080 
00081    bool 
00082    IdealObliquePrism::inside( const GlobalPoint& point ) const 
00083    {
00084       // first check eta/phi
00085       bool is_inside ( false ) ;
00086 
00087       const GlobalPoint& face ( getPosition() ) ;
00088 
00089       // eta
00090       if( fabs( point.eta() - face.eta() ) <= dEta()  &&
00091           fabs( point.phi() - face.phi() ) <= dPhi()     )
00092       {
00093          // distance (trickier)
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          { // here, it is just a Z test.
00105             is_inside = ( ( ( face.z()<0 ) ? ( point.z()<=face.z()  ) :
00106                             ( point.z()>=face.z()  ) ) && // "front" face
00107                           ( ( face.z()<0 ) ? ( point.z()>=face2.z() ) :
00108                             ( point.z()<=face2.z() ) ) ); // "back" face
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 }

Generated on Tue Jun 9 17:37:17 2009 for CMSSW by  doxygen 1.5.4