CMS 3D CMS Logo

HelixBarrelCylinderCrossing.cc

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   // assumes the cylinder is centered at 0,0
00020   double R = cyl.radius();
00021 
00022   // protect for zero curvature case
00023   const double sraightLineCutoff = 1.e-7;
00024   if (fabs(rho)*R < sraightLineCutoff && 
00025       fabs(rho)*startingPos.perp()  < sraightLineCutoff) {
00026     // switch to straight line case
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; // all needed data members have been set
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 pabs = startingDir.mag();
00082   double sinTheta = pt / pabs;
00083   double cosTheta = startingDir.z() / pabs;
00084 
00085   double dMag = theD.mag();
00086   theS = theActualDir * 2.* asin( dMag*rho/2.) / (rho*sinTheta);
00087   thePos =  GlobalPoint( startingPos.x() + theD.x(),
00088                          startingPos.y() + theD.y(),
00089                          startingPos.z() + theS*cosTheta);
00090 
00091   double tmp = 0.5 * dMag * rho;
00092   if (theS < 0) tmp = -tmp;
00093   double sinPhi = 2.*tmp*sqrt(1.-tmp*tmp);
00094   double cosPhi = 1.-2.*tmp*tmp;
00095   theDir = DirectionType(startingDir.x()*cosPhi-startingDir.y()*sinPhi,
00096                          startingDir.x()*sinPhi+startingDir.y()*cosPhi,
00097                          startingDir.z());
00098 }
00099 void HelixBarrelCylinderCrossing::chooseSolution( const Vector& d1, const Vector& d2,
00100                                                   const PositionType& startingPos,
00101                                                   const DirectionType& startingDir, 
00102                                                   PropagationDirection propDir)
00103 {
00104   double momProj1 = startingDir.x()*d1.x() + startingDir.y()*d1.y();
00105   double momProj2 = startingDir.x()*d2.x() + startingDir.y()*d2.y();
00106 
00107   if ( propDir == anyDirection ) {
00108     theSolExists = true;
00109     if (d1.mag2()<d2.mag2()) {
00110       theD = d1;
00111       theActualDir = (momProj1 > 0) ? 1 : -1;
00112     }
00113     else {
00114       theD = d2;
00115       theActualDir = (momProj2 > 0) ? 1 : -1;
00116     }
00117   }
00118   else {
00119     int propSign = propDir==alongMomentum ? 1 : -1;
00120     if (momProj1*momProj2 < 0) {
00121       // if different signs return the positive one
00122       theSolExists = true;
00123       theD = (momProj1*propSign > 0) ? d1 : d2;
00124       theActualDir = propSign;
00125     }
00126     else if (momProj1*propSign > 0) {
00127       // if both positive, return the shortest
00128       theSolExists = true;
00129       theD = (d1.mag2()<d2.mag2()) ? d1 : d2;
00130       theActualDir = propSign;
00131     }
00132     else theSolExists = false;
00133   }
00134 }
00135 

Generated on Tue Jun 9 17:48:17 2009 for CMSSW by  doxygen 1.5.4