Go to the documentation of this file.00001 #include "TrackingTools/GeomPropagators/interface/HelixArbitraryPlaneCrossing2Order.h"
00002
00003 #include "DataFormats/GeometrySurface/interface/Plane.h"
00004 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00005
00006 #include <cmath>
00007 #include <cfloat>
00008
00009 HelixArbitraryPlaneCrossing2Order::HelixArbitraryPlaneCrossing2Order(const PositionType& point,
00010 const DirectionType& direction,
00011 const float curvature,
00012 const PropagationDirection propDir) :
00013 theX0(point.x()),
00014 theY0(point.y()),
00015 theZ0(point.z()),
00016 theRho(curvature),
00017 thePropDir(propDir)
00018 {
00019
00020
00021
00022 double px = direction.x();
00023 double py = direction.y();
00024 double pz = direction.z();
00025 double pt2 = px*px+py*py;
00026 double p2 = pt2+pz*pz;
00027 double pI = 1./sqrt(p2);
00028 double ptI = 1./sqrt(pt2);
00029 theCosPhi0 = px*ptI;
00030 theSinPhi0 = py*ptI;
00031 theCosTheta = pz*pI;
00032 theSinThetaI = p2*pI*ptI;
00033 }
00034
00035
00036
00037
00038 std::pair<bool,double>
00039 HelixArbitraryPlaneCrossing2Order::pathLength(const Plane& plane) {
00040
00041
00042
00043
00044 GlobalVector normalToPlane = plane.normalVector();
00045 double nPx = normalToPlane.x();
00046 double nPy = normalToPlane.y();
00047 double nPz = normalToPlane.z();
00048 double cP = plane.localZ(GlobalPoint(theX0,theY0,theZ0));
00049
00050
00051
00052
00053 double ceq1 = theRho*(nPx*theSinPhi0-nPy*theCosPhi0);
00054 double ceq2 = nPx*theCosPhi0 + nPy*theSinPhi0 + nPz*theCosTheta*theSinThetaI;
00055 double ceq3 = cP;
00056
00057
00058
00059
00060 double dS1,dS2;
00061 if ( fabs(ceq1)>FLT_MIN ) {
00062 double deq1 = ceq2*ceq2;
00063 double deq2 = ceq1*ceq3;
00064 if ( fabs(deq1)<FLT_MIN || fabs(deq2/deq1)>1.e-6 ) {
00065
00066
00067
00068 double deq = deq1+2*deq2;
00069 if ( deq<0. ) return std::pair<bool,double>(false,0);
00070 double ceq = -0.5*(ceq2+(ceq2>0?1:-1)*sqrt(deq));
00071 dS1 = -2*(ceq/ceq1)*theSinThetaI;
00072 dS2 = (ceq3/ceq)*theSinThetaI;
00073 }
00074 else {
00075
00076
00077
00078 double ceq = (ceq2/ceq1)*theSinThetaI;
00079 double deq = deq2/deq1;
00080 deq *= (1-0.5*deq);
00081 dS1 = -ceq*deq;
00082 dS2 = ceq*(2+deq);
00083 }
00084 }
00085 else {
00086
00087
00088
00089 dS1 = dS2 = -(ceq3/ceq2)*theSinThetaI;
00090 }
00091
00092
00093
00094 return solutionByDirection(dS1,dS2);
00095 }
00096
00097
00098
00099
00100 HelixPlaneCrossing::PositionType
00101 HelixArbitraryPlaneCrossing2Order::position (double s) const {
00102
00103 PositionTypeDouble pos = positionInDouble(s);
00104 return PositionType(pos.x(),pos.y(),pos.z());
00105 }
00106
00107
00108
00109 HelixArbitraryPlaneCrossing2Order::PositionTypeDouble
00110 HelixArbitraryPlaneCrossing2Order::positionInDouble (double s) const {
00111
00112 double st = s/theSinThetaI;
00113 return PositionTypeDouble(theX0+(theCosPhi0-(st*0.5*theRho)*theSinPhi0)*st,
00114 theY0+(theSinPhi0+(st*0.5*theRho)*theCosPhi0)*st,
00115 theZ0+st*theCosTheta*theSinThetaI);
00116 }
00117
00118
00119
00120 HelixPlaneCrossing::DirectionType
00121 HelixArbitraryPlaneCrossing2Order::direction (double s) const {
00122
00123 DirectionTypeDouble dir = directionInDouble(s);
00124 return DirectionType(dir.x(),dir.y(),dir.z());
00125 }
00126
00127
00128
00129 HelixArbitraryPlaneCrossing2Order::DirectionTypeDouble
00130 HelixArbitraryPlaneCrossing2Order::directionInDouble (double s) const {
00131
00132 double dph = s*theRho/theSinThetaI;
00133 return DirectionTypeDouble(theCosPhi0-(theSinPhi0+0.5*dph*theCosPhi0)*dph,
00134 theSinPhi0+(theCosPhi0-0.5*dph*theSinPhi0)*dph,
00135 theCosTheta*theSinThetaI);
00136 }
00137
00138
00139
00140 std::pair<bool,double>
00141 HelixArbitraryPlaneCrossing2Order::solutionByDirection(const double dS1,
00142 const double dS2) const {
00143 bool valid = false;
00144 double path = 0;
00145 if ( thePropDir == anyDirection ) {
00146 valid = true;
00147 path = smallestPathLength(dS1,dS2);
00148 }
00149 else {
00150
00151 double propSign = thePropDir==alongMomentum ? 1 : -1;
00152 double s1(propSign*dS1);
00153 double s2(propSign*dS2);
00154
00155 if ( s1 > s2 ) {
00156 double aux = s1;
00157 s1 = s2;
00158 s2 = aux;
00159 }
00160
00161 if ( s1<0 && s2>=0 ) {
00162
00163 valid = true;
00164 path = propSign*s2;
00165 }
00166 else if ( s1>=0 ) {
00167
00168 valid = true;
00169 path = propSign*s1;
00170 }
00171 }
00172 return std::pair<bool,double>(valid,path);
00173 }