00001 #include "TrackingTools/GeomPropagators/interface/HelixForwardPlaneCrossing.h"
00002 #include "DataFormats/GeometrySurface/interface/Plane.h"
00003
00004 #include <cmath>
00005 #include <cfloat>
00006
00007 HelixForwardPlaneCrossing::HelixForwardPlaneCrossing(const PositionType& point,
00008 const DirectionType& direction,
00009 const float curvature,
00010 const PropagationDirection propDir) :
00011 theX0(point.x()),
00012 theY0(point.y()),
00013 theZ0(point.z()),
00014 theRho(curvature),
00015 thePropDir(propDir),
00016 theCachedS(0),
00017 theCachedDPhi(0.),
00018 theCachedSDPhi(0.),
00019 theCachedCDPhi(1.)
00020 {
00021
00022
00023
00024 double px = direction.x();
00025 double py = direction.y();
00026 double pz = direction.z();
00027 double pt = px*px+py*py;
00028 double p = sqrt(pt+pz*pz);
00029 pt = sqrt(pt);
00030 theCosPhi0 = px/pt;
00031 theSinPhi0 = py/pt;
00032 theCosTheta = pz/p;
00033 theSinTheta = pt/p;
00034 }
00035
00036
00037
00038 std::pair<bool,double>
00039 HelixForwardPlaneCrossing::pathLength(const Plane& plane) {
00040
00041
00042
00043 if ( fabs(theCosTheta/theSinTheta)<FLT_MIN ) return std::pair<bool,double>(false,0);
00044 double dS = (plane.position().z()-theZ0) / theCosTheta;
00045 if ( (thePropDir==alongMomentum && dS<0.) ||
00046 (thePropDir==oppositeToMomentum && dS>0.) ) return std::pair<bool,double>(false,0);
00047
00048
00049
00050 return std::pair<bool,double>(true,dS);
00051 }
00052
00053
00054
00055 HelixPlaneCrossing::PositionType
00056 HelixForwardPlaneCrossing::position (double s) const {
00057
00058
00059
00060 if ( s!=theCachedS ) {
00061 theCachedS = s;
00062 theCachedDPhi = theCachedS*theRho*theSinTheta;
00063 theCachedSDPhi = sin(theCachedDPhi);
00064 theCachedCDPhi = cos(theCachedDPhi);
00065 }
00066
00067
00068
00069
00070 if ( fabs(theCachedDPhi)>1.e-4 ) {
00071
00072 return PositionType(theX0+(-theSinPhi0*(1.-theCachedCDPhi)+theCosPhi0*theCachedSDPhi)/theRho,
00073 theY0+(theCosPhi0*(1.-theCachedCDPhi)+theSinPhi0*theCachedSDPhi)/theRho,
00074 theZ0+theCachedS*theCosTheta);
00075 }
00076 else {
00077
00078 double st = theCachedS*theSinTheta;
00079 return PositionType(theX0+(theCosPhi0-st*0.5*theRho*theSinPhi0)*st,
00080 theY0+(theSinPhi0+st*0.5*theRho*theCosPhi0)*st,
00081 theZ0+st*theCosTheta/theSinTheta);
00082 }
00083 }
00084
00085
00086
00087 HelixPlaneCrossing::DirectionType
00088 HelixForwardPlaneCrossing::direction (double s) const {
00089
00090
00091
00092 if ( s!=theCachedS ) {
00093 theCachedS = s;
00094 theCachedDPhi = theCachedS*theRho*theSinTheta;
00095 theCachedSDPhi = sin(theCachedDPhi);
00096 theCachedCDPhi = cos(theCachedDPhi);
00097 }
00098
00099 if ( fabs(theCachedDPhi)>1.e-4 ) {
00100
00101 return DirectionType(theCosPhi0*theCachedCDPhi-theSinPhi0*theCachedSDPhi,
00102 theSinPhi0*theCachedCDPhi+theCosPhi0*theCachedSDPhi,
00103 theCosTheta/theSinTheta);
00104 }
00105 else {
00106
00107 double dph = theCachedS*theRho*theSinTheta;
00108 return DirectionType(theCosPhi0-(theSinPhi0+0.5*theCosPhi0*dph)*dph,
00109 theSinPhi0+(theCosPhi0-0.5*theSinPhi0*dph)*dph,
00110 theCosTheta/theSinTheta);
00111 }
00112 }
00113
00114 const float HelixForwardPlaneCrossing::theNumericalPrecision = 5.e-7;