CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/TrackingTools/GeomPropagators/src/AnalyticalImpactPointExtrapolator.cc

Go to the documentation of this file.
00001 #include "TrackingTools/GeomPropagators/interface/AnalyticalImpactPointExtrapolator.h"
00002 #include "TrackingTools/GeomPropagators/interface/IterativeHelixExtrapolatorToLine.h"
00003 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00004 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
00005 #include "TrackingTools/GeomPropagators/interface/AnalyticalPropagator.h"
00006 #include "TrackingTools/AnalyticalJacobians/interface/AnalyticalCurvilinearJacobian.h"
00007 #include "DataFormats/GeometrySurface/interface/Plane.h"
00008 #include "DataFormats/GeometrySurface/interface/PlaneBuilder.h"
00009 
00010 // #include "CommonDet/DetUtilities/interface/DetailedDetTimer.h"
00011 
00012 AnalyticalImpactPointExtrapolator::AnalyticalImpactPointExtrapolator (const MagneticField* field) :
00013   thePropagator(new AnalyticalPropagator(theField, anyDirection)),
00014   theField(field)
00015 {}
00016 
00017 AnalyticalImpactPointExtrapolator::AnalyticalImpactPointExtrapolator (const Propagator& propagator,
00018                                                                       const MagneticField* field) :
00019   thePropagator(propagator.clone()),
00020   theField(field)
00021 {
00022   thePropagator->setPropagationDirection(anyDirection);
00023 }
00024 
00025 TrajectoryStateOnSurface 
00026 AnalyticalImpactPointExtrapolator::extrapolate (const FreeTrajectoryState& fts, 
00027                                                 const GlobalPoint& vtx) const
00028 {
00029 //   static TimingReport::Item& timer = detailedDetTimer("AnalyticalImpactPointExtrapolator");
00030 //   TimeMe t(timer,false);
00031 
00032   return extrapolateSingleState(fts, vtx);
00033 }
00034 
00035 TrajectoryStateOnSurface 
00036 AnalyticalImpactPointExtrapolator::extrapolate (const TrajectoryStateOnSurface tsos, 
00037                                                 const GlobalPoint& vtx) const
00038 {
00039   if ( tsos.isValid() )  return extrapolateFullState(tsos,vtx);
00040   else  return tsos;
00041 }
00042 
00043 TrajectoryStateOnSurface 
00044 AnalyticalImpactPointExtrapolator::extrapolateFullState (const TrajectoryStateOnSurface tsos, 
00045                                                          const GlobalPoint& vertex) const
00046 {
00047   //
00048   // first determine IP plane using propagation with (single) FTS
00049   // could be optimised (will propagate errors even if duplicated below)
00050   //
00051   TrajectoryStateOnSurface singleState = 
00052     extrapolateSingleState(*tsos.freeTrajectoryState(),vertex);
00053   if ( !singleState.isValid() || tsos.components().size()==1 )  return singleState;
00054   //
00055   // propagate multiTsos to plane found above
00056   //
00057   return thePropagator->propagate(tsos,singleState.surface());
00058 }
00059 
00060 TrajectoryStateOnSurface 
00061 AnalyticalImpactPointExtrapolator::extrapolateSingleState (const FreeTrajectoryState& fts, 
00062                                                            const GlobalPoint& vertex) const
00063 {
00064   //
00065   // initialisation of position, momentum and transverse curvature
00066   //
00067   GlobalPoint x(fts.position());
00068   GlobalVector p(fts.momentum());
00069   double rho = fts.transverseCurvature();
00070   //
00071   // Straight line approximation? |rho|<1.e-10 equivalent to ~ 1um 
00072   // difference in transversal position at 10m.
00073   //
00074   double s(0);
00075   if( fabs(rho)<1.e-10 ) {
00076     GlobalVector dx(p.dot(vertex-x)/p.mag2()*p);
00077     x += dx;
00078     float sign = p.dot(dx);
00079     s = sign>0 ? dx.mag() : -dx.mag();
00080   }
00081   //
00082   // Helix case 
00083   //
00084   else {
00085     HelixLineExtrapolation::PositionType helixPos(x);
00086     HelixLineExtrapolation::DirectionType helixDir(p);
00087     IterativeHelixExtrapolatorToLine extrapolator(helixPos,helixDir,rho,anyDirection);
00088     if ( !propagateWithHelix(extrapolator,vertex,x,p,s) )  return TrajectoryStateOnSurface();
00089   }
00090   //
00091   // Define target surface: origin on line, x_local from line 
00092   //   to helix at closest approach, z_local along the helix
00093   //   and y_local to complete right-handed system
00094   //
00095   GlobalVector zLocal(p.unit());
00096   GlobalVector yLocal(zLocal.cross(x-vertex).unit());
00097   GlobalVector xLocal(yLocal.cross(zLocal));
00098   Surface::RotationType rot(xLocal,yLocal,zLocal);
00099   PlaneBuilder::ReturnType surface = PlaneBuilder().plane(vertex,rot);
00100   //
00101   // Compute propagated state
00102   //
00103   GlobalTrajectoryParameters gtp(x,p,fts.charge(), theField);
00104   if (fts.hasError()) {
00105     //
00106     // compute jacobian
00107     //
00108     AnalyticalCurvilinearJacobian analyticalJacobian(fts.parameters(), gtp.position(), gtp.momentum(), s);
00109     CurvilinearTrajectoryError cte( ROOT::Math::Similarity( analyticalJacobian.jacobian(), 
00110                                                             fts.curvilinearError().matrix()) );
00111     return TrajectoryStateOnSurface(gtp,cte,*surface);
00112   }
00113   else {
00114     //
00115     // return state without errors
00116     //
00117     return TrajectoryStateOnSurface(gtp,*surface);
00118   }
00119 }
00120 
00121 bool
00122 AnalyticalImpactPointExtrapolator::propagateWithHelix (const IterativeHelixExtrapolatorToLine& extrapolator,
00123                                                        const GlobalPoint& vertex,
00124                                                        GlobalPoint& x, GlobalVector& p, double& s) const {
00125   //
00126   // save absolute value of momentum
00127   //
00128   double pmag(p.mag());
00129   //
00130   // get path length to solution
00131   //
00132   std::pair<bool,double> propResult = extrapolator.pathLength(vertex);
00133   if ( !propResult.first )  return false;
00134   s = propResult.second;
00135   // 
00136   // get point and (normalised) direction from path length
00137   //
00138   HelixLineExtrapolation::PositionType xGen = extrapolator.position(s);
00139   HelixLineExtrapolation::DirectionType pGen = extrapolator.direction(s);
00140   //
00141   // Fix normalisation and convert back to GlobalPoint / GlobalVector
00142   //
00143   x = GlobalPoint(xGen);
00144   pGen *= pmag/pGen.mag();
00145   p = GlobalVector(pGen);
00146   //
00147   return true;
00148 }