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
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
00036
00037 template <class T> std::pair<bool,double>
00038 IterativeHelixExtrapolatorToLine::genericPathLength (const T& object) const {
00039
00040
00041
00042 const int maxIterations(100);
00043
00044
00045
00046 PropagationDirection propDir = thePropDir;
00047 PositionTypeDouble xnew(theX0,theY0,theZ0);
00048 DirectionTypeDouble pnew(theCosPhi0,theSinPhi0,theCosTheta/theSinTheta);
00049
00050
00051
00052 int iteration(maxIterations);
00053 double dSTotal(0.);
00054
00055
00056
00057 double maxDeltaS2 = 2*1.e-4/theSinTheta/theSinTheta/fabs(theRho);
00058
00059 bool first(true);
00060 while ( true ) {
00061
00062
00063
00064 if ( --iteration<0 ) {
00065 return std::pair<bool,double>(false,0);
00066 }
00067
00068
00069
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
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
00097
00098 if ( deltaS1.second*deltaS1.second<maxDeltaS2 ) break;
00099
00100
00101
00102 xnew = positionInDouble(dSTotal);
00103 pnew = directionInDouble(dSTotal);
00104 }
00105
00106
00107
00108 return std::pair<bool,double>(true,dSTotal);
00109 }
00110
00111
00112
00113
00114 HelixLineExtrapolation::PositionType
00115 IterativeHelixExtrapolatorToLine::position (double s) const {
00116
00117 return PositionType(positionInDouble(s));
00118 }
00119
00120
00121
00122
00123 HelixLineExtrapolation::PositionTypeDouble
00124 IterativeHelixExtrapolatorToLine::positionInDouble (double s) const {
00125
00126
00127
00128 if ( s!=theCachedS ) {
00129 theCachedS = s;
00130 theCachedDPhi = theCachedS*theRho*theSinTheta;
00131 theCachedSDPhi = sin(theCachedDPhi);
00132 theCachedCDPhi = cos(theCachedDPhi);
00133 }
00134
00135
00136
00137
00138
00139 if ( fabs(theCachedDPhi)>1.e-4 ) {
00140
00141 return PositionTypeDouble(theX0+(-theSinPhi0*(1.-theCachedCDPhi)+theCosPhi0*theCachedSDPhi)/theRho,
00142 theY0+(theCosPhi0*(1.-theCachedCDPhi)+theSinPhi0*theCachedSDPhi)/theRho,
00143 theZ0+theCachedS*theCosTheta);
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153 else {
00154
00155 return theQuadraticSolutionFromStart.positionInDouble(theCachedS);
00156 }
00157 }
00158
00159
00160
00161
00162 HelixLineExtrapolation::DirectionType
00163 IterativeHelixExtrapolatorToLine::direction (double s) const {
00164
00165
00166
00167 return DirectionType(directionInDouble(s));
00168 }
00169
00170
00171
00172
00173 HelixLineExtrapolation::DirectionTypeDouble
00174 IterativeHelixExtrapolatorToLine::directionInDouble (double s) const {
00175
00176
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
00187 return DirectionTypeDouble(theCosPhi0*theCachedCDPhi-theSinPhi0*theCachedSDPhi,
00188 theSinPhi0*theCachedCDPhi+theCosPhi0*theCachedSDPhi,
00189 theCosTheta/theSinTheta);
00190 }
00191 else {
00192
00193 return theQuadraticSolutionFromStart.directionInDouble(theCachedS);
00194 }
00195 }