CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/TrackingTools/GeomPropagators/src/HelixForwardPlaneCrossing.cc

Go to the documentation of this file.
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   // Components of direction vector (with correct normalisation)
00023   //
00024   double px = direction.x();
00025   double py = direction.y();
00026   double pz = direction.z();
00027   double pt2 = px*px+py*py;
00028   double p2 = pt2+pz*pz;
00029   double pI = 1./sqrt(p2);
00030   double ptI = 1./sqrt(pt2);
00031   theCosPhi0 = px*ptI;
00032   theSinPhi0 = py*ptI;
00033   theCosTheta = pz*pI;
00034   theSinTheta = pt2*ptI*pI;
00035 
00036 }
00037 //
00038 // Propagation status  and path length to intersection
00039 //
00040 std::pair<bool,double>
00041 HelixForwardPlaneCrossing::pathLength(const Plane& plane) {
00042   //
00043   // Protect against p_z=0 and calculate path length
00044   //
00045   if ( std::abs(theCosTheta/theSinTheta)<FLT_MIN )  return std::pair<bool,double>(false,0);
00046 
00047   double dS = (plane.position().z()-theZ0) / theCosTheta;
00048 
00049   if ( (thePropDir==alongMomentum && dS<0.) ||
00050        (thePropDir==oppositeToMomentum && dS>0.) )  return std::pair<bool,double>(false,0);
00051   //
00052   // Return result
00053   //
00054   return std::pair<bool,double>(true,dS);
00055 }
00056 //
00057 // Position on helix after a step of path length s. 
00058 //
00059 HelixPlaneCrossing::PositionType
00060 HelixForwardPlaneCrossing::position (double s) const {
00061   //
00062   // Calculate delta phi (if not already available)
00063   //
00064   if ( s!=theCachedS ) {
00065     theCachedS = s;
00066     theCachedDPhi = theCachedS*theRho*theSinTheta;
00067     theCachedSDPhi = sin(theCachedDPhi);
00068     theCachedCDPhi = cos(theCachedDPhi);
00069   }
00070   //
00071   // Calculate with appropriate formulation of full helix formula or with 
00072   //   2nd order approximation.
00073   //
00074   if ( std::abs(theCachedDPhi)>1.e-4 ) {
00075     // "standard" helix formula
00076     // "standard" helix formula
00077     double o = 1./theRho;
00078     return PositionTypeDouble(theX0+(-theSinPhi0*(1.-theCachedCDPhi)+theCosPhi0*theCachedSDPhi)*o,
00079                               theY0+( theCosPhi0*(1.-theCachedCDPhi)+theSinPhi0*theCachedSDPhi)*o,
00080                               theZ0+theCachedS*theCosTheta);
00081   }
00082   else {
00083     // 2nd order
00084     double st = theCachedS*theSinTheta;
00085     return PositionType(theX0+(theCosPhi0-st*0.5*theRho*theSinPhi0)*st,
00086                         theY0+(theSinPhi0+st*0.5*theRho*theCosPhi0)*st,
00087                         theZ0+st*theCosTheta/theSinTheta);
00088   }
00089 }
00090 //
00091 // Direction vector on helix after a step of path length s.
00092 //
00093 HelixPlaneCrossing::DirectionType
00094 HelixForwardPlaneCrossing::direction (double s) const {
00095   //
00096   // Calculate delta phi (if not already available)
00097   //
00098   if ( s!=theCachedS ) {
00099     theCachedS = s;
00100     theCachedDPhi = theCachedS*theRho*theSinTheta;
00101     theCachedSDPhi = sin(theCachedDPhi);
00102     theCachedCDPhi = cos(theCachedDPhi);
00103   }
00104 
00105   if ( fabs(theCachedDPhi)>1.e-4 ) {
00106     // full helix formula
00107     return DirectionType(theCosPhi0*theCachedCDPhi-theSinPhi0*theCachedSDPhi,
00108                          theSinPhi0*theCachedCDPhi+theCosPhi0*theCachedSDPhi,
00109                          theCosTheta/theSinTheta);
00110   }
00111   else {
00112     // 2nd order
00113     double dph = theCachedS*theRho*theSinTheta;
00114     return DirectionType(theCosPhi0-(theSinPhi0+0.5*theCosPhi0*dph)*dph,
00115                          theSinPhi0+(theCosPhi0-0.5*theSinPhi0*dph)*dph,
00116                          theCosTheta/theSinTheta);
00117   }
00118 }
00119 
00120 const float HelixForwardPlaneCrossing::theNumericalPrecision = 5.e-7;