CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/TrackingTools/GeomPropagators/src/IterativeHelixExtrapolatorToLine.cc

Go to the documentation of this file.
00001 #include "TrackingTools/GeomPropagators/interface/IterativeHelixExtrapolatorToLine.h"
00002 #include <iostream>
00003 
00004 IterativeHelixExtrapolatorToLine::IterativeHelixExtrapolatorToLine
00005 (const PositionType& point,
00006  const DirectionType& direction,
00007  const float curvature,
00008  const PropagationDirection propDir) :
00009   theX0(point.x()),
00010   theY0(point.y()),
00011   theZ0(point.z()),
00012   theRho(curvature),
00013   theQuadraticSolutionFromStart(point,direction,curvature,propDir),
00014   thePropDir(propDir),
00015   theCachedS(0),
00016   theCachedDPhi(0.),
00017   theCachedSDPhi(0.),
00018   theCachedCDPhi(1.)
00019 {
00020   //
00021   // Components of direction vector (with correct normalisation)
00022   //
00023   double px = direction.x();
00024   double py = direction.y();
00025   double pz = direction.z();
00026   double pt = px*px+py*py;
00027   double p = sqrt(pt+pz*pz);
00028   pt = sqrt(pt);
00029   theCosPhi0 = px/pt;
00030   theSinPhi0 = py/pt;
00031   theCosTheta = pz/p;
00032   theSinTheta = pt/p;
00033 }
00034 //
00035 // Propagation status and path length to intersection
00036 //
00037 template <class T> std::pair<bool,double>
00038 IterativeHelixExtrapolatorToLine::genericPathLength (const T& object) const {
00039   //
00040   // Constants used for control of convergence
00041   //
00042   const int maxIterations(100);
00043   //
00044   // Prepare internal value of the propagation direction and position / direction vectors for iteration 
00045   //
00046   PropagationDirection propDir = thePropDir;
00047   PositionTypeDouble xnew(theX0,theY0,theZ0);
00048   DirectionTypeDouble pnew(theCosPhi0,theSinPhi0,theCosTheta/theSinTheta);
00049   //
00050   // Prepare iterations: count and total pathlength
00051   //
00052   int iteration(maxIterations);
00053   double dSTotal(0.);
00054   //
00055   // Convergence criterion: maximal lateral displacement in a step < 1um
00056   //
00057   double maxDeltaS2 = 2*1.e-4/theSinTheta/theSinTheta/fabs(theRho);
00058   //
00059   bool first(true);
00060   while ( true ) {
00061     //
00062     // return empty solution vector if no convergence after maxIterations iterations
00063     //
00064     if ( --iteration<0 ) {
00065       return std::pair<bool,double>(false,0);
00066     }
00067     //
00068     // Use existing second order object at first pass, create temporary object
00069     // for subsequent passes.
00070     //
00071     std::pair<bool,double> deltaS1;
00072     if ( first ) {
00073       first = false;
00074       deltaS1 = theQuadraticSolutionFromStart.pathLength(object);
00075     }
00076     else {
00077       HelixExtrapolatorToLine2Order linearCrossing(xnew.x(),xnew.y(),xnew.z(),
00078                                                    pnew.x(),pnew.y(),
00079                                                    theCosTheta,theSinTheta,
00080                                                    theRho,anyDirection);
00081       deltaS1 = linearCrossing.pathLength(object);
00082     }
00083     if ( !deltaS1.first )  return deltaS1;
00084     //
00085     // Calculate total pathlength
00086     //
00087     dSTotal += deltaS1.second;
00088     PropagationDirection newDir = dSTotal>=0 ? alongMomentum : oppositeToMomentum;
00089     if ( propDir == anyDirection ) {
00090       propDir = newDir;
00091     }
00092     else {
00093       if ( newDir!=propDir )  return std::pair<bool,double>(false,0);
00094     }
00095     //
00096     // Check convergence
00097     //
00098     if ( deltaS1.second*deltaS1.second<maxDeltaS2 )  break;
00099     //
00100     // Step forward by dSTotal.
00101     //
00102     xnew = positionInDouble(dSTotal);
00103     pnew = directionInDouble(dSTotal);
00104   }
00105   //
00106   // Return result
00107   //
00108   return std::pair<bool,double>(true,dSTotal);
00109 }
00110 
00111 //
00112 // Position on helix after a step of path length s.
00113 //
00114 HelixLineExtrapolation::PositionType
00115 IterativeHelixExtrapolatorToLine::position (double s) const {
00116   // use result in double precision
00117   return PositionType(positionInDouble(s));
00118 }
00119 
00120 //
00121 // Position on helix after a step of path length s in double precision.
00122 //
00123 HelixLineExtrapolation::PositionTypeDouble
00124 IterativeHelixExtrapolatorToLine::positionInDouble (double s) const {
00125   //
00126   // Calculate delta phi (if not already available)
00127   //
00128   if ( s!=theCachedS ) {
00129     theCachedS = s;
00130     theCachedDPhi = theCachedS*theRho*theSinTheta;
00131     theCachedSDPhi = sin(theCachedDPhi);
00132     theCachedCDPhi = cos(theCachedDPhi);
00133   }
00134   //
00135   // Calculate with appropriate formulation of full helix formula or with 
00136   //   1st order approximation.
00137   //
00138 //    if ( fabs(theCachedDPhi)>1.e-1 ) {
00139   if ( fabs(theCachedDPhi)>1.e-4 ) {
00140     // "standard" helix formula
00141     return PositionTypeDouble(theX0+(-theSinPhi0*(1.-theCachedCDPhi)+theCosPhi0*theCachedSDPhi)/theRho,
00142                               theY0+(theCosPhi0*(1.-theCachedCDPhi)+theSinPhi0*theCachedSDPhi)/theRho,
00143                               theZ0+theCachedS*theCosTheta);
00144     }
00145 //    else if ( fabs(theCachedDPhi)>theNumericalPrecision ) {
00146 //      // full helix formula, but avoiding (1-cos(deltaPhi)) for small angles
00147 //      return PositionTypeDouble(theX0+(-theSinPhi0*theCachedSDPhi*theCachedSDPhi/(1.+theCachedCDPhi)+
00148 //                                   theCosPhi0*theCachedSDPhi)/theRho,
00149 //                            theY0+(theCosPhi0*theCachedSDPhi*theCachedSDPhi/(1.+theCachedCDPhi)+
00150 //                                   theSinPhi0*theCachedSDPhi)/theRho,
00151 //                            theZ0+theCachedS*theCosTheta);
00152 //    }
00153   else {
00154     // Use 1st order.
00155     return theQuadraticSolutionFromStart.positionInDouble(theCachedS);
00156   }
00157 }
00158 
00159 //
00160 // Direction vector on helix after a step of path length s.
00161 //
00162 HelixLineExtrapolation::DirectionType
00163 IterativeHelixExtrapolatorToLine::direction (double s) const {
00164   // use result in double precision
00165 //   DirectionTypeDouble dir = directionInDouble(s);
00166 //   return DirectionType(dir.x(),dir.y(),dir.z());
00167   return DirectionType(directionInDouble(s));
00168 }
00169 
00170 //
00171 // Direction vector on helix after a step of path length s in double precision.
00172 //
00173 HelixLineExtrapolation::DirectionTypeDouble
00174 IterativeHelixExtrapolatorToLine::directionInDouble (double s) const {
00175   //
00176   // Calculate delta phi (if not already available)
00177   //
00178   if ( s!=theCachedS ) {
00179     theCachedS = s;
00180     theCachedDPhi = theCachedS*theRho*theSinTheta;
00181     theCachedSDPhi = sin(theCachedDPhi);
00182     theCachedCDPhi = cos(theCachedDPhi);
00183   }
00184 
00185   if ( fabs(theCachedDPhi)>1.e-4 ) {
00186     // full helix formula
00187     return DirectionTypeDouble(theCosPhi0*theCachedCDPhi-theSinPhi0*theCachedSDPhi,
00188                                theSinPhi0*theCachedCDPhi+theCosPhi0*theCachedSDPhi,
00189                                theCosTheta/theSinTheta);
00190   }
00191   else {
00192     // 1st order
00193     return theQuadraticSolutionFromStart.directionInDouble(theCachedS);
00194   }
00195 }