CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_6/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 
00040   std::pair<bool,double> IterativeHelixExtrapolatorToLine::pathLength (const GlobalPoint& point) const {
00041     return genericPathLength(point);
00042   }
00043 
00048   std::pair<bool,double> IterativeHelixExtrapolatorToLine::pathLength (const Line& line) const {
00049     return genericPathLength(line);
00050   }
00051 
00052 
00053 
00054 //
00055 // Propagation status and path length to intersection
00056 //
00057 template <class T> std::pair<bool,double>
00058 IterativeHelixExtrapolatorToLine::genericPathLength (const T& object) const {
00059   //
00060   // Constants used for control of convergence
00061   //
00062   const int maxIterations(100);
00063   //
00064   // Prepare internal value of the propagation direction and position / direction vectors for iteration 
00065   //
00066   PropagationDirection propDir = thePropDir;
00067   PositionTypeDouble xnew(theX0,theY0,theZ0);
00068   DirectionTypeDouble pnew(theCosPhi0,theSinPhi0,theCosTheta/theSinTheta);
00069   //
00070   // Prepare iterations: count and total pathlength
00071   //
00072   unsigned int iteration(maxIterations+1);
00073   double dSTotal(0.);
00074   //
00075   // Convergence criterion: maximal lateral displacement in a step < 1um
00076   //
00077   double maxDeltaS2 = 2*1.e-4/theSinTheta/theSinTheta/fabs(theRho);
00078   //
00079   bool first(true);
00080   while ( true ) {
00081     //
00082     // return empty solution vector if no convergence after maxIterations iterations
00083     //
00084     if ( --iteration == 0 ) {
00085       return std::pair<bool,double>(false,0);
00086     }
00087     //
00088     // Use existing second order object at first pass, create temporary object
00089     // for subsequent passes.
00090     //
00091     std::pair<bool,double> deltaS1;
00092     if ( first ) {
00093       first = false;
00094       deltaS1 = theQuadraticSolutionFromStart.pathLength(object);
00095     }
00096     else {
00097       HelixExtrapolatorToLine2Order linearCrossing(xnew.x(),xnew.y(),xnew.z(),
00098                                                    pnew.x(),pnew.y(),
00099                                                    theCosTheta,theSinTheta,
00100                                                    theRho,anyDirection);
00101       deltaS1 = linearCrossing.pathLength(object);
00102     }
00103     if ( !deltaS1.first )  return deltaS1;
00104     //
00105     // Calculate total pathlength
00106     //
00107     dSTotal += deltaS1.second;
00108     PropagationDirection newDir = dSTotal>=0 ? alongMomentum : oppositeToMomentum;
00109     if ( propDir == anyDirection ) {
00110       propDir = newDir;
00111     }
00112     else {
00113       if ( newDir!=propDir )  return std::pair<bool,double>(false,0);
00114     }
00115     //
00116     // Check convergence
00117     //
00118     if ( deltaS1.second*deltaS1.second<maxDeltaS2 )  break;
00119     //
00120     // Step forward by dSTotal.
00121     //
00122     xnew = positionInDouble(dSTotal);
00123     pnew = directionInDouble(dSTotal);
00124   }
00125   //
00126   // Return result
00127   //
00128   return std::pair<bool,double>(true,dSTotal);
00129 }
00130 
00131 //
00132 // Position on helix after a step of path length s.
00133 //
00134 HelixLineExtrapolation::PositionType
00135 IterativeHelixExtrapolatorToLine::position (double s) const {
00136   // use result in double precision
00137   return PositionType(positionInDouble(s));
00138 }
00139 
00140 //
00141 // Position on helix after a step of path length s in double precision.
00142 //
00143 HelixLineExtrapolation::PositionTypeDouble
00144 IterativeHelixExtrapolatorToLine::positionInDouble (double s) const {
00145   //
00146   // Calculate delta phi (if not already available)
00147   //
00148   if ( s!=theCachedS ) {
00149     theCachedS = s;
00150     theCachedDPhi = theCachedS*theRho*theSinTheta;
00151     theCachedSDPhi = sin(theCachedDPhi);
00152     theCachedCDPhi = cos(theCachedDPhi);
00153   }
00154   //
00155   // Calculate with appropriate formulation of full helix formula or with 
00156   //   1st order approximation.
00157   //
00158 //    if ( fabs(theCachedDPhi)>1.e-1 ) {
00159   if ( fabs(theCachedDPhi)>1.e-4 ) {
00160     // "standard" helix formula
00161     return PositionTypeDouble(theX0+(-theSinPhi0*(1.-theCachedCDPhi)+theCosPhi0*theCachedSDPhi)/theRho,
00162                               theY0+(theCosPhi0*(1.-theCachedCDPhi)+theSinPhi0*theCachedSDPhi)/theRho,
00163                               theZ0+theCachedS*theCosTheta);
00164     }
00165 //    else if ( fabs(theCachedDPhi)>theNumericalPrecision ) {
00166 //      // full helix formula, but avoiding (1-cos(deltaPhi)) for small angles
00167 //      return PositionTypeDouble(theX0+(-theSinPhi0*theCachedSDPhi*theCachedSDPhi/(1.+theCachedCDPhi)+
00168 //                                   theCosPhi0*theCachedSDPhi)/theRho,
00169 //                            theY0+(theCosPhi0*theCachedSDPhi*theCachedSDPhi/(1.+theCachedCDPhi)+
00170 //                                   theSinPhi0*theCachedSDPhi)/theRho,
00171 //                            theZ0+theCachedS*theCosTheta);
00172 //    }
00173   else {
00174     // Use 1st order.
00175     return theQuadraticSolutionFromStart.positionInDouble(theCachedS);
00176   }
00177 }
00178 
00179 //
00180 // Direction vector on helix after a step of path length s.
00181 //
00182 HelixLineExtrapolation::DirectionType
00183 IterativeHelixExtrapolatorToLine::direction (double s) const {
00184   // use result in double precision
00185 //   DirectionTypeDouble dir = directionInDouble(s);
00186 //   return DirectionType(dir.x(),dir.y(),dir.z());
00187   return DirectionType(directionInDouble(s));
00188 }
00189 
00190 //
00191 // Direction vector on helix after a step of path length s in double precision.
00192 //
00193 HelixLineExtrapolation::DirectionTypeDouble
00194 IterativeHelixExtrapolatorToLine::directionInDouble (double s) const {
00195   //
00196   // Calculate delta phi (if not already available)
00197   //
00198   if ( s!=theCachedS ) {
00199     theCachedS = s;
00200     theCachedDPhi = theCachedS*theRho*theSinTheta;
00201     theCachedSDPhi = sin(theCachedDPhi);
00202     theCachedCDPhi = cos(theCachedDPhi);
00203   }
00204 
00205   if ( fabs(theCachedDPhi)>1.e-4 ) {
00206     // full helix formula
00207     return DirectionTypeDouble(theCosPhi0*theCachedCDPhi-theSinPhi0*theCachedSDPhi,
00208                                theSinPhi0*theCachedCDPhi+theCosPhi0*theCachedSDPhi,
00209                                theCosTheta/theSinTheta);
00210   }
00211   else {
00212     // 1st order
00213     return theQuadraticSolutionFromStart.directionInDouble(theCachedS);
00214   }
00215 }