CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/TrackingTools/GeomPropagators/src/StraightLineCylinderCrossing.cc

Go to the documentation of this file.
00001 #include "TrackingTools/GeomPropagators/interface/StraightLineCylinderCrossing.h"
00002 
00003 #include "DataFormats/GeometrySurface/interface/Cylinder.h"
00004 #include "TrackingTools/GeomPropagators/src/RealQuadEquation.h"
00005 
00006 #include <cmath>
00007 #include <iostream>
00008 using namespace std;
00009 
00010 StraightLineCylinderCrossing::
00011 StraightLineCylinderCrossing( const LocalPoint& startingPos, const LocalVector& startingDir,
00012                               const PropagationDirection propDir, double tolerance) :
00013   theX0(startingPos),
00014   theP0(startingDir.unit()),
00015   thePropDir(propDir), 
00016   theTolerance(tolerance) {}
00017 
00018 std::pair<bool,double>
00019 StraightLineCylinderCrossing::pathLength (const Cylinder& cylinder) const
00020 {
00021   //
00022   // radius of cylinder and transversal position relative to axis
00023   //
00024   double R(cylinder.radius());
00025   PositionType2D xt2d(theX0.x(),theX0.y());
00026   //
00027   // transverse direction
00028   // 
00029   DirectionType2D pt2d(theP0.x(),theP0.y());
00030   //
00031   // solution of quadratic equation for s - assume |theP0|=1
00032   //
00033   RealQuadEquation eq(pt2d.mag2(),2.*xt2d.dot(pt2d),xt2d.mag2()-R*R);
00034   if ( !eq.hasSolution ) {
00035     /*
00036     double A=   pt2d.mag2(); 
00037     double B=   2.*xt2d.dot(pt2d);
00038     double C=   xt2d.mag2()-R*R;
00039     cout << "A= " << pt2d.mag2() 
00040          << " B= " << 2.*xt2d.dot(pt2d)
00041          << " C= " << xt2d.mag2()-R*R
00042          << " D= " << B*B - 4*A*C
00043          << endl;
00044     */
00045     return std::pair<bool,double>(false,0.);
00046   }
00047   //
00048   // choice of solution and verification of direction
00049   //
00050   return chooseSolution(eq.first,eq.second);
00051 }
00052 
00053 std::pair<bool,double>
00054 StraightLineCylinderCrossing::chooseSolution (const double s1, 
00055                                               const double s2) const
00056 {
00057   //
00058   // follows the logic implemented in HelixBarrelCylinderCrossing
00059   //
00060   if ( thePropDir==anyDirection ) {
00061     return std::pair<bool,double>(true,(fabs(s1)<fabs(s2)?s1:s2));
00062   }
00063   else {
00064     int propSign = thePropDir==alongMomentum ? 1 : -1;
00065     if ( s1*s2 < 0) {
00066       // if different signs return the positive one
00067       return std::pair<bool,double>(true,((s1*propSign>0)?s1:s2));
00068     }
00069     else if ( s1*propSign>0 ) {
00070       // if both positive, return the shortest
00071       return std::pair<bool,double>(true,(fabs(s1)<fabs(s2)?s1:s2));
00072     }
00073     else {
00074       // if both negative, check if the smaller (abs value) is smaller then tolerance
00075       double shorter = std::min( fabs(s1), fabs(s2));
00076       if (shorter < theTolerance) return std::pair<bool,double>(true,0);
00077       else                        return std::pair<bool,double>(false,0.);
00078     }
00079   }
00080 }