Go to the documentation of this file.00001 #include "TrackingTools/GeomPropagators/interface/HelixBarrelCylinderCrossing.h"
00002 #include "TrackingTools/GeomPropagators/src/RealQuadEquation.h"
00003 #include "TrackingTools/GeomPropagators/interface/StraightLineCylinderCrossing.h"
00004
00005 #include "DataFormats/GeometrySurface/interface/Cylinder.h"
00006
00007 #include <iostream>
00008 #include <cmath>
00009
00010 template <typename T>
00011 inline T sqr(const T& t) {return t*t;}
00012
00013 HelixBarrelCylinderCrossing::
00014 HelixBarrelCylinderCrossing( const GlobalPoint& startingPos,
00015 const GlobalVector& startingDir,
00016 double rho, PropagationDirection propDir,
00017 const Cylinder& cyl)
00018 {
00019
00020 double R = cyl.radius();
00021
00022
00023 const double sraightLineCutoff = 1.e-7;
00024 if (fabs(rho)*R < sraightLineCutoff &&
00025 fabs(rho)*startingPos.perp() < sraightLineCutoff) {
00026
00027 StraightLineCylinderCrossing slc( cyl.toLocal(startingPos),
00028 cyl.toLocal(startingDir), propDir);
00029 std::pair<bool,double> pl = slc.pathLength( cyl);
00030 if (pl.first) {
00031 theSolExists = true;
00032 theS = pl.second;
00033 thePos = cyl.toGlobal(slc.position(theS));
00034 theDir = startingDir;
00035 }
00036 else theSolExists = false;
00037 return;
00038 }
00039
00040 double R2cyl = R*R;
00041 double pt = startingDir.perp();
00042 Point center( startingPos.x()-startingDir.y()/(pt*rho),
00043 startingPos.y()+startingDir.x()/(pt*rho));
00044 double p2 = startingPos.perp2();
00045 bool solveForX;
00046 double B, C, E, F;
00047 if (fabs(center.x()) > fabs(center.y())) {
00048 solveForX = false;
00049 E = (R2cyl - p2) / (2.*center.x());
00050 F = center.y()/center.x();
00051 B = 2.*( startingPos.y() - F*startingPos.x() - E*F);
00052 C = 2.*E*startingPos.x() + E*E + p2 - R2cyl;
00053 }
00054 else {
00055 solveForX = true;
00056 E = (R2cyl - p2) / (2.*center.y());
00057 F = center.x()/center.y();
00058 B = 2.*( startingPos.x() - F*startingPos.y() - E*F);
00059 C = 2.*E*startingPos.y() + E*E + p2 - R2cyl;
00060 }
00061
00062 RealQuadEquation eq( 1+F*F, B, C);
00063 if (!eq.hasSolution) {
00064 theSolExists = false;
00065 return;
00066 }
00067
00068 Vector d1, d2;;
00069 if (solveForX) {
00070 d1 = Point(eq.first, E-F*eq.first);
00071 d2 = Point(eq.second, E-F*eq.second);
00072 }
00073 else {
00074 d1 = Point( E-F*eq.first, eq.first);
00075 d2 = Point( E-F*eq.second, eq.second);
00076 }
00077
00078 chooseSolution(d1, d2, startingPos, startingDir, propDir);
00079 if (!theSolExists) return;
00080
00081 double ipabs = 1./startingDir.mag();
00082 double sinTheta = pt * ipabs;
00083 double cosTheta = startingDir.z() * ipabs;
00084
00085
00086
00087
00088
00089
00090
00091 int theActualDir1 = propDir==alongMomentum ? 1 : -1;
00092 int theActualDir2 = propDir==alongMomentum ? 1 : -1;
00093
00094
00095 double dMag1 = d1.mag();
00096 double tmp1 = 0.5 * dMag1 * rho;
00097 if (std::abs(tmp1)>1.) tmp1 = ::copysign(1.,tmp1);
00098 double theS1 = theActualDir1 * 2.* asin( tmp1 ) / (rho*sinTheta);
00099 thePos1 = GlobalPoint( startingPos.x() + d1.x(),
00100 startingPos.y() + d1.y(),
00101 startingPos.z() + theS1*cosTheta);
00102
00103
00104 double dMag2 = d2.mag();
00105 double tmp2 = 0.5 * dMag2 * rho;
00106 if (std::abs(tmp2)>1.) tmp2 = ::copysign(1.,tmp2);
00107 double theS2 = theActualDir2 * 2.* asin( tmp2 ) / (rho*sinTheta);
00108 thePos2 = GlobalPoint( startingPos.x() + d2.x(),
00109 startingPos.y() + d2.y(),
00110 startingPos.z() + theS2*cosTheta);
00111
00112
00113 double dMag = theD.mag();
00114 double tmp = 0.5 * dMag * rho;
00115 if (std::abs(tmp)>1.) tmp = ::copysign(1.,tmp);
00116 theS = theActualDir * 2.* asin( tmp ) / (rho*sinTheta);
00117 thePos = GlobalPoint( startingPos.x() + theD.x(),
00118 startingPos.y() + theD.y(),
00119 startingPos.z() + theS*cosTheta);
00120
00121 if (theS < 0) tmp = -tmp;
00122 double sinPhi = 2.*tmp*sqrt(1.-tmp*tmp);
00123 double cosPhi = 1.-2.*tmp*tmp;
00124 theDir = DirectionType(startingDir.x()*cosPhi-startingDir.y()*sinPhi,
00125 startingDir.x()*sinPhi+startingDir.y()*cosPhi,
00126 startingDir.z());
00127 }
00128
00129 void HelixBarrelCylinderCrossing::chooseSolution( const Vector& d1, const Vector& d2,
00130 const PositionType& startingPos,
00131 const DirectionType& startingDir,
00132 PropagationDirection propDir)
00133 {
00134 double momProj1 = startingDir.x()*d1.x() + startingDir.y()*d1.y();
00135 double momProj2 = startingDir.x()*d2.x() + startingDir.y()*d2.y();
00136
00137 if ( propDir == anyDirection ) {
00138 theSolExists = true;
00139 if (d1.mag2()<d2.mag2()) {
00140 theD = d1;
00141 theActualDir = (momProj1 > 0) ? 1 : -1;
00142 }
00143 else {
00144 theD = d2;
00145 theActualDir = (momProj2 > 0) ? 1 : -1;
00146 }
00147 }
00148 else {
00149 int propSign = propDir==alongMomentum ? 1 : -1;
00150 if (momProj1*momProj2 < 0) {
00151
00152 theSolExists = true;
00153 theD = (momProj1*propSign > 0) ? d1 : d2;
00154 theActualDir = propSign;
00155 }
00156 else if (momProj1*propSign > 0) {
00157
00158 theSolExists = true;
00159 theD = (d1.mag2()<d2.mag2()) ? d1 : d2;
00160 theActualDir = propSign;
00161 }
00162 else theSolExists = false;
00163 }
00164 }
00165