00001 #include "TrackingTools/GeomPropagators/interface/AnalyticalTrajectoryExtrapolatorToLine.h"
00002
00003 #include "TrackingTools/GeomPropagators/interface/IterativeHelixExtrapolatorToLine.h"
00004 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00005 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
00006 #include "TrackingTools/GeomPropagators/interface/AnalyticalPropagator.h"
00007 #include "TrackingTools/AnalyticalJacobians/interface/AnalyticalCurvilinearJacobian.h"
00008
00009 #include "DataFormats/GeometrySurface/interface/PlaneBuilder.h"
00010 #include "DataFormats/GeometrySurface/interface/Line.h"
00011
00012 #include <cmath>
00013
00014
00015 AnalyticalTrajectoryExtrapolatorToLine::AnalyticalTrajectoryExtrapolatorToLine (const MagneticField* field) :
00016 thePropagator(new AnalyticalPropagator(field, anyDirection)) {}
00017
00018 AnalyticalTrajectoryExtrapolatorToLine::AnalyticalTrajectoryExtrapolatorToLine
00019 (const Propagator& propagator) : thePropagator(propagator.clone())
00020 {
00021 thePropagator->setPropagationDirection(anyDirection);
00022 }
00023
00024 TrajectoryStateOnSurface
00025 AnalyticalTrajectoryExtrapolatorToLine::extrapolate (const FreeTrajectoryState& fts,
00026 const Line& line) const
00027 {
00028 return extrapolateSingleState(fts,line);
00029 }
00030
00031 TrajectoryStateOnSurface
00032 AnalyticalTrajectoryExtrapolatorToLine::extrapolate (const TrajectoryStateOnSurface tsos,
00033 const Line& line) const
00034 {
00035 if ( tsos.isValid() ) return extrapolateFullState(tsos,line);
00036 else return tsos;
00037 }
00038
00039 TrajectoryStateOnSurface
00040 AnalyticalTrajectoryExtrapolatorToLine::extrapolateFullState (const TrajectoryStateOnSurface tsos,
00041 const Line& line) const
00042 {
00043
00044
00045
00046
00047 TrajectoryStateOnSurface singleState =
00048 extrapolateSingleState(*tsos.freeTrajectoryState(),line);
00049 if ( !singleState.isValid() || tsos.components().size()==1 ) return singleState;
00050
00051
00052
00053 return thePropagator->propagate(tsos,singleState.surface());
00054 }
00055
00056 TrajectoryStateOnSurface
00057 AnalyticalTrajectoryExtrapolatorToLine::extrapolateSingleState (const FreeTrajectoryState& fts,
00058 const Line& line) const
00059 {
00060
00061
00062
00063
00064
00065 GlobalPoint x(fts.position());
00066 GlobalVector p(fts.momentum());
00067 double rho = fts.transverseCurvature();
00068
00069
00070
00071
00072 double s(0);
00073 if( fabs(rho)<1.e-10 ) {
00074 Line tangent(x,p);
00075 GlobalPoint xold(x);
00076 x = tangent.closerPointToLine(line);
00077 GlobalVector dx(x-xold);
00078 float sign = p.dot(x-xold);
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,line,x,p,s) ) return TrajectoryStateOnSurface();
00089 }
00090
00091
00092
00093
00094
00095 GlobalPoint origin(line.closerPointToLine(Line(x,p)));
00096 GlobalVector zLocal(p.unit());
00097 GlobalVector yLocal(zLocal.cross(x-origin).unit());
00098 GlobalVector xLocal(yLocal.cross(zLocal));
00099 Surface::RotationType rot(xLocal,yLocal,zLocal);
00100 PlaneBuilder::ReturnType surface = PlaneBuilder().plane(origin,rot);
00101
00102
00103
00104 GlobalTrajectoryParameters gtp(x,p,fts.charge(), thePropagator->magneticField());
00105 if (fts.hasError()) {
00106
00107
00108
00109 AnalyticalCurvilinearJacobian analyticalJacobian(fts.parameters(), gtp.position(), gtp.momentum(), s);
00110 const AlgebraicMatrix55 &jacobian = analyticalJacobian.jacobian();
00111 CurvilinearTrajectoryError cte( ROOT::Math::Similarity (jacobian, fts.curvilinearError().matrix()) );
00112 return TrajectoryStateOnSurface(gtp,cte,*surface);
00113 }
00114 else {
00115
00116
00117
00118 return TrajectoryStateOnSurface(gtp,*surface);
00119 }
00120 }
00121
00122 bool
00123 AnalyticalTrajectoryExtrapolatorToLine::propagateWithHelix (const IterativeHelixExtrapolatorToLine& extrapolator,
00124 const Line& line,
00125 GlobalPoint& x, GlobalVector& p, double& s) const {
00126
00127
00128
00129 double pmag(p.mag());
00130
00131
00132
00133 std::pair<bool,double> propResult = extrapolator.pathLength(line);
00134 if ( !propResult.first ) return false;
00135 s = propResult.second;
00136
00137
00138
00139 HelixLineExtrapolation::PositionType xGen = extrapolator.position(s);
00140 HelixLineExtrapolation::DirectionType pGen = extrapolator.direction(s);
00141
00142
00143
00144 x = GlobalPoint(xGen);
00145 pGen *= pmag/pGen.mag();
00146 p = GlobalVector(pGen);
00147
00148 return true;
00149 }