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 double dMag = theD.mag();
00086 double tmp = 0.5 * dMag * rho;
00087 if (std::abs(tmp)>1.) tmp = ::copysign(1.,tmp);
00088 theS = theActualDir * 2.* asin( tmp ) / (rho*sinTheta);
00089 thePos = GlobalPoint( startingPos.x() + theD.x(),
00090 startingPos.y() + theD.y(),
00091 startingPos.z() + theS*cosTheta);
00092
00093 if (theS < 0) tmp = -tmp;
00094 double sinPhi = 2.*tmp*sqrt(1.-tmp*tmp);
00095 double cosPhi = 1.-2.*tmp*tmp;
00096 theDir = DirectionType(startingDir.x()*cosPhi-startingDir.y()*sinPhi,
00097 startingDir.x()*sinPhi+startingDir.y()*cosPhi,
00098 startingDir.z());
00099 }
00100
00101 void HelixBarrelCylinderCrossing::chooseSolution( const Vector& d1, const Vector& d2,
00102 const PositionType& startingPos,
00103 const DirectionType& startingDir,
00104 PropagationDirection propDir)
00105 {
00106 double momProj1 = startingDir.x()*d1.x() + startingDir.y()*d1.y();
00107 double momProj2 = startingDir.x()*d2.x() + startingDir.y()*d2.y();
00108
00109 if ( propDir == anyDirection ) {
00110 theSolExists = true;
00111 if (d1.mag2()<d2.mag2()) {
00112 theD = d1;
00113 theActualDir = (momProj1 > 0) ? 1 : -1;
00114 }
00115 else {
00116 theD = d2;
00117 theActualDir = (momProj2 > 0) ? 1 : -1;
00118 }
00119 }
00120 else {
00121 int propSign = propDir==alongMomentum ? 1 : -1;
00122 if (momProj1*momProj2 < 0) {
00123
00124 theSolExists = true;
00125 theD = (momProj1*propSign > 0) ? d1 : d2;
00126 theActualDir = propSign;
00127 }
00128 else if (momProj1*propSign > 0) {
00129
00130 theSolExists = true;
00131 theD = (d1.mag2()<d2.mag2()) ? d1 : d2;
00132 theActualDir = propSign;
00133 }
00134 else theSolExists = false;
00135 }
00136 }
00137