00001 #include "Geometry/CaloGeometry/interface/Line3D.h"
00002 #include "Geometry/CaloGeometry/interface/CaloCellCrossing.h"
00003
00004 CaloCellCrossing::CaloCellCrossing( const GlobalPoint& gp ,
00005 const GlobalVector& gv ,
00006 const CaloCellCrossing::DetIds* di ,
00007 const CaloSubdetectorGeometry* sg ,
00008 DetId::Detector det ,
00009 int subdet,
00010 double small,
00011 bool onewayonly ) :
00012 m_gp ( gp ) ,
00013 m_gv ( gv )
00014 {
00015 const double eps ( fabs( small ) > 1.e-15 ? fabs( small ) : 1.e-10 ) ;
00016 static unsigned int k_rlen ( 30 ) ;
00017 m_detId.reserve( k_rlen ) ;
00018 m_ctr .reserve( k_rlen ) ;
00019 m_entr .reserve( k_rlen ) ;
00020 m_exit .reserve( k_rlen ) ;
00021
00022 const HepLine3D line ( HepGeom::Point3D<double> ( gp.x(), gp.y(), gp.z() ),
00023 HepGeom::Vector3D<double> ( gv.x(), gv.y(), gv.z() ), eps ) ;
00024
00025
00026
00027 const DetIds& ids ( 0 == di ? sg->getValidDetIds( det, subdet ) : *di ) ;
00028
00029 for( DetIds::const_iterator id ( ids.begin() ) ; id != ids.end() ; ++id )
00030 {
00031 const DetId dId ( *id ) ;
00032 unsigned int found ( 0 ) ;
00033 const CaloCellGeometry& cg ( *sg->getGeometry( dId ) ) ;
00034 const CaloCellGeometry::CornersVec& gc ( cg.getCorners() ) ;
00035 const HepGeom::Point3D<double> fr ( cg.getPosition().x(),
00036 cg.getPosition().y(),
00037 cg.getPosition().z() ) ;
00038 const double bCut2 ( ( gc[0] - gc[6] ).mag2() ) ;
00039
00040 if( ( !onewayonly ||
00041 eps < HepGeom::Vector3D<double> ( fr - line.pt() ).dot( line.uv() ) ) &&
00042 bCut2 > line.dist2( fr ) )
00043 {
00044
00045 const HepGeom::Point3D<double> cv[8] =
00046 { HepGeom::Point3D<double> ( gc[0].x(), gc[0].y(), gc[0].z() ) ,
00047 HepGeom::Point3D<double> ( gc[1].x(), gc[1].y(), gc[1].z() ) ,
00048 HepGeom::Point3D<double> ( gc[2].x(), gc[2].y(), gc[2].z() ) ,
00049 HepGeom::Point3D<double> ( gc[3].x(), gc[3].y(), gc[3].z() ) ,
00050 HepGeom::Point3D<double> ( gc[4].x(), gc[4].y(), gc[4].z() ) ,
00051 HepGeom::Point3D<double> ( gc[5].x(), gc[5].y(), gc[5].z() ) ,
00052 HepGeom::Point3D<double> ( gc[6].x(), gc[6].y(), gc[6].z() ) ,
00053 HepGeom::Point3D<double> ( gc[7].x(), gc[7].y(), gc[7].z() ) } ;
00054 const HepGeom::Point3D<double> ctr ( 0.125*(cv[0]+cv[1]+cv[2]+cv[3]+
00055 cv[4]+cv[5]+cv[6]+cv[7]) ) ;
00056 const double dCut2 ( bCut2/4. ) ;
00057 if( dCut2 > line.dist2( ctr ) )
00058
00059 {
00060
00061
00062 static const unsigned int nc[6][4] =
00063 { { 0,1,2,3 }, { 0,4,5,1 }, { 0,4,7,3 },
00064 { 6,7,4,5 }, { 6,2,3,7 }, { 6,2,1,5 } } ;
00065 for( unsigned int face ( 0 ) ; face != 6 ; ++face )
00066 {
00067 const unsigned int* ic ( &nc[face][0] ) ;
00068 const HepGeom::Plane3D<double> pl ( cv[ic[0]], cv[ic[1]], cv[ic[2]] ) ;
00069 bool parallel ;
00070 const HepGeom::Point3D<double> pt ( line.point( pl, parallel ) ) ;
00071
00072 if( !parallel )
00073 {
00074
00075 const HepLine3D la ( cv[ic[0]], cv[ic[1]], eps ) ;
00076 const HepLine3D lb ( cv[ic[2]], cv[ic[3]], eps ) ;
00077
00078
00079
00080
00081
00082 if( eps > ( la.point( pt ) - pt ).dot( ( lb.point( pt ) - pt ) ) )
00083 {
00084 const HepLine3D lc ( cv[ic[0]], cv[ic[3]], eps ) ;
00085 const HepLine3D ld ( cv[ic[1]], cv[ic[2]], eps ) ;
00086
00087
00088 if( eps > ( lc.point( pt ) - pt ).dot( ( ld.point( pt ) - pt ) ) )
00089 {
00090 if( 0 == found )
00091 {
00092 ++found ;
00093 m_detId.push_back( dId ) ;
00094 m_ctr .push_back( GlobalPoint( ctr.x(), ctr.y(), ctr.z() ) ) ;
00095 m_entr.push_back( GlobalPoint( pt.x(), pt.y(), pt.z() ) ) ;
00096 }
00097 else
00098 {
00099 if( 1 == found )
00100 {
00101 ++found ;
00102 m_exit.push_back( GlobalPoint( pt.x(), pt.y(), pt.z() ) ) ;
00103 }
00104 else
00105 {
00106 const double dist1 (
00107 ( pt - HepGeom::Point3D<double> ( m_entr.back().x(),
00108 m_entr.back().y(),
00109 m_entr.back().z() ) ).mag() ) ;
00110 const double dist2 (
00111 ( pt - HepGeom::Point3D<double> ( m_exit.back().x(),
00112 m_exit.back().y(),
00113 m_exit.back().z() ) ).mag() ) ;
00114 if( eps < dist1 &&
00115 eps < dist2 )
00116 {
00117 std::cout << "********For DetId = " << dId
00118 << " distances too big: "
00119 << dist1 << ", " << dist2
00120 << std::endl ;
00121 }
00122 }
00123 }
00124 }
00125 }
00126 }
00127 }
00128 }
00129 }
00130 assert( 2 >= found ) ;
00131 if( 1 == found ) m_exit.push_back( m_entr.back() ) ;
00132 }
00133
00134 assert( m_detId.size() == m_entr.size() &&
00135 m_detId.size() == m_ctr .size() &&
00136 m_detId.size() == m_exit.size() ) ;
00137
00138 m_len.reserve( m_entr.size() ) ;
00139 for( unsigned int i ( 0 ) ; i != m_entr.size() ; ++i )
00140 {
00141 m_len.push_back( ( m_exit[i] - m_entr[i] ).mag() ) ;
00142 }
00143 }
00144