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
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
00030
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
00049
00050
00051 TrajectoryStateOnSurface singleState =
00052 extrapolateSingleState(*tsos.freeTrajectoryState(),vertex);
00053 if ( !singleState.isValid() || tsos.components().size()==1 ) return singleState;
00054
00055
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
00066
00067 GlobalPoint x(fts.position());
00068 GlobalVector p(fts.momentum());
00069 double rho = fts.transverseCurvature();
00070
00071
00072
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
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
00092
00093
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
00102
00103 GlobalTrajectoryParameters gtp(x,p,fts.charge(), theField);
00104 if (fts.hasError()) {
00105
00106
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
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
00127
00128 double pmag(p.mag());
00129
00130
00131
00132 std::pair<bool,double> propResult = extrapolator.pathLength(vertex);
00133 if ( !propResult.first ) return false;
00134 s = propResult.second;
00135
00136
00137
00138 HelixLineExtrapolation::PositionType xGen = extrapolator.position(s);
00139 HelixLineExtrapolation::DirectionType pGen = extrapolator.direction(s);
00140
00141
00142
00143 x = GlobalPoint(xGen);
00144 pGen *= pmag/pGen.mag();
00145 p = GlobalVector(pGen);
00146
00147 return true;
00148 }