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