00001 #include "TrackingTools/GeomPropagators/interface/AnalyticalPropagator.h"
00002
00003 #include "DataFormats/GeometrySurface/interface/Cylinder.h"
00004 #include "DataFormats/GeometrySurface/interface/TangentPlane.h"
00005 #include "DataFormats/GeometrySurface/interface/Plane.h"
00006
00007 #include "MagneticField/Engine/interface/MagneticField.h"
00008
00009 #include "TrackingTools/GeomPropagators/interface/PropagationExceptions.h"
00010 #include "TrackingTools/GeomPropagators/interface/StraightLinePlaneCrossing.h"
00011 #include "TrackingTools/GeomPropagators/interface/StraightLineBarrelCylinderCrossing.h"
00012 #include "TrackingTools/GeomPropagators/interface/HelixBarrelPlaneCrossingByCircle.h"
00013 #include "TrackingTools/GeomPropagators/interface/HelixForwardPlaneCrossing.h"
00014 #include "TrackingTools/GeomPropagators/interface/HelixArbitraryPlaneCrossing.h"
00015 #include "TrackingTools/GeomPropagators/interface/HelixBarrelCylinderCrossing.h"
00016 #include "TrackingTools/AnalyticalJacobians/interface/AnalyticalCurvilinearJacobian.h"
00017 #include "TrackingTools/GeomPropagators/interface/PropagationDirectionFromPath.h"
00018 #include "TrackingTools/TrajectoryState/interface/SurfaceSideDefinition.h"
00019 #include "TrackingTools/GeomPropagators/interface/PropagationExceptions.h"
00020
00021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00022
00023 #include <cmath>
00024
00025 using namespace SurfaceSideDefinition;
00026
00027 std::pair<TrajectoryStateOnSurface,double>
00028 AnalyticalPropagator::propagateWithPath(const FreeTrajectoryState& fts,
00029 const Plane& plane) const
00030 {
00031
00032 double rho = fts.transverseCurvature();
00033
00034
00035 GlobalPoint x;
00036 GlobalVector p;
00037 double s;
00038
00039
00040 const float maxDistToPlane(0.1e-4);
00041 const float numericalPrecision(5.e-7);
00042 float maxDz = numericalPrecision*plane.position().mag();
00043 if ( fabs(plane.localZ(fts.position()))>(maxDistToPlane>maxDz?maxDistToPlane:maxDz) ) {
00044
00045 bool parametersOK = this->propagateParametersOnPlane(fts, plane, x, p, s);
00046
00047 float dphi2 = s*rho;
00048 dphi2 = dphi2*dphi2*fts.momentum().perp2()/fts.momentum().mag2();
00049 if ( !parametersOK || dphi2>theMaxDPhi2 ) return TsosWP(TrajectoryStateOnSurface(),0.);
00050 }
00051 else {
00052 LogDebug("AnalyticalPropagator")<<"not going anywhere. Already on surface.\n"
00053 <<"plane.localZ(fts.position()): "<<plane.localZ(fts.position())<<"\n"
00054 <<"maxDistToPlane: "<<maxDistToPlane<<"\n"
00055 <<"maxDz: "<<maxDz<<"\n"
00056 <<"plane.position().mag(): "<<plane.position().mag();
00057 x = fts.position();
00058 p = fts.momentum();
00059 s = 0.;
00060 }
00061
00062
00063
00064 GlobalTrajectoryParameters gtp(x,p,fts.charge(),theField);
00065 if ( fabs(rho)>1.e-10 && fabs((gtp.transverseCurvature()-rho)/rho)>theMaxDBzRatio )
00066 return TsosWP(TrajectoryStateOnSurface(),0.);
00067
00068
00069
00070 return propagatedStateWithPath(fts,plane,gtp,s);
00071 }
00072
00073
00074 std::pair<TrajectoryStateOnSurface,double>
00075 AnalyticalPropagator::propagateWithPath(const FreeTrajectoryState& fts,
00076 const Cylinder& cylinder) const
00077 {
00078
00079 double rho = fts.transverseCurvature();
00080
00081
00082 GlobalPoint x;
00083 GlobalVector p;
00084 double s = 0;
00085
00086 bool parametersOK = this->propagateParametersOnCylinder(fts, cylinder, x, p, s);
00087
00088 float dphi2 = s*rho;
00089 dphi2 = dphi2*dphi2*fts.momentum().perp2()/fts.momentum().mag2();
00090 if ( !parametersOK || dphi2>theMaxDPhi2 ) return TsosWP(TrajectoryStateOnSurface(),0.);
00091
00092
00093
00094 GlobalTrajectoryParameters gtp(x,p,fts.charge(),theField);
00095 if ( fabs(rho)>1.e-10 && fabs((gtp.transverseCurvature()-rho)/rho)>theMaxDBzRatio )
00096 return TsosWP(TrajectoryStateOnSurface(),0.);
00097
00098
00099
00100 ReferenceCountingPointer<TangentPlane> plane(cylinder.tangentPlane(x));
00101 return propagatedStateWithPath(fts,*plane,gtp,s);
00102 }
00103
00104 std::pair<TrajectoryStateOnSurface,double>
00105 AnalyticalPropagator::propagatedStateWithPath (const FreeTrajectoryState& fts,
00106 const Surface& surface,
00107 const GlobalTrajectoryParameters& gtp,
00108 const double& s) const
00109 {
00110
00111
00112
00113
00114 SurfaceSide side = PropagationDirectionFromPath()(s,propagationDirection())==alongMomentum
00115 ? beforeSurface : afterSurface;
00116
00117
00118
00119
00120 if (fts.hasError()) {
00121
00122
00123
00124 AnalyticalCurvilinearJacobian analyticalJacobian(fts.parameters(), gtp.position(), gtp.momentum(), s);
00125 const AlgebraicMatrix55 &jacobian = analyticalJacobian.jacobian();
00126 CurvilinearTrajectoryError cte(ROOT::Math::Similarity(jacobian, fts.curvilinearError().matrix()));
00127 return TsosWP(TrajectoryStateOnSurface(gtp,cte,surface,side),s);
00128 }
00129 else {
00130
00131
00132
00133 return TsosWP(TrajectoryStateOnSurface(gtp,surface,side),s);
00134 }
00135 }
00136
00137 bool AnalyticalPropagator::propagateParametersOnCylinder(
00138 const FreeTrajectoryState& fts, const Cylinder& cylinder,
00139 GlobalPoint& x, GlobalVector& p, double& s) const
00140 {
00141
00142 GlobalPoint const & sp = cylinder.position();
00143 if (sp.x()!=0. || sp.y()!=0.) {
00144 throw PropagationException("Cannot propagate to an arbitrary cylinder");
00145 }
00146
00147 x = fts.position();
00148 p = fts.momentum();
00149 s = 0;
00150
00151 double rho = fts.transverseCurvature();
00152
00153
00154
00155
00156 if( fabs(rho)<1.e-10 )
00157 return propagateWithLineCrossing(fts.position(),p,cylinder,x,s);
00158
00159
00160
00161
00162 const double tolerance = 1.e-4;
00163 double rdiff = x.perp() - cylinder.radius();
00164 if ( fabs(rdiff) < tolerance ) return true;
00165
00166
00167
00168 HelixBarrelCylinderCrossing cylinderCrossing(fts.position(),fts.momentum(),rho,
00169 propagationDirection(),cylinder);
00170 if ( !cylinderCrossing.hasSolution() ) return false;
00171
00172 s = cylinderCrossing.pathLength();
00173
00174 x = cylinderCrossing.position();
00175
00176 p = cylinderCrossing.direction().unit()*fts.momentum().mag();
00177 return true;
00178 }
00179
00180 bool
00181 AnalyticalPropagator::propagateParametersOnPlane(const FreeTrajectoryState& fts,
00182 const Plane& plane,
00183 GlobalPoint& x,
00184 GlobalVector& p,
00185 double& s) const
00186 {
00187
00188 x = fts.position();
00189 p = fts.momentum();
00190 s = 0;
00191
00192 double rho = fts.transverseCurvature();
00193
00194
00195
00196
00197 if( fabs(rho)<1.e-10 )
00198 return propagateWithLineCrossing(fts.position(),p,plane,x,s);
00199
00200
00201
00202 GlobalVector u = plane.normalVector();
00203 const double small = 1.e-6;
00204
00205
00206
00207
00208
00209 HelixPlaneCrossing::PositionType helixPos(x);
00210 HelixPlaneCrossing::DirectionType helixDir(p);
00211 if (fabs(u.z()) < small) {
00212
00213
00214 HelixBarrelPlaneCrossingByCircle planeCrossing(helixPos,helixDir,rho,propagationDirection());
00215 return propagateWithHelixCrossing(planeCrossing,plane,fts.momentum().mag(),x,p,s);
00216 }
00217 if (fabs(u.x()) < small && fabs(u.y()) < small) {
00218
00219
00220 HelixForwardPlaneCrossing planeCrossing(helixPos,helixDir,rho,propagationDirection());
00221 return propagateWithHelixCrossing(planeCrossing,plane,fts.momentum().mag(),x,p,s);
00222 }
00223 else {
00224
00225
00226 HelixArbitraryPlaneCrossing planeCrossing(helixPos,helixDir,rho,propagationDirection());
00227 return propagateWithHelixCrossing(planeCrossing,plane,fts.momentum().mag(),x,p,s);
00228 }
00229 }
00230
00231 bool
00232 AnalyticalPropagator::propagateWithLineCrossing (const GlobalPoint& x0,
00233 const GlobalVector& p0,
00234 const Plane& plane,
00235 GlobalPoint& x, double& s) const {
00236
00237
00238
00239
00240
00241
00242 StraightLinePlaneCrossing::PositionType pos(x0);
00243 StraightLinePlaneCrossing::DirectionType dir(p0);
00244 StraightLinePlaneCrossing planeCrossing(pos,dir,propagationDirection());
00245
00246
00247
00248 std::pair<bool,double> propResult = planeCrossing.pathLength(plane);
00249 if ( !propResult.first ) return false;
00250 s = propResult.second;
00251
00252 x = GlobalPoint(planeCrossing.position(s));
00253
00254 return true;
00255 }
00256
00257 bool
00258 AnalyticalPropagator::propagateWithLineCrossing (const GlobalPoint& x0,
00259 const GlobalVector& p0,
00260 const Cylinder& cylinder,
00261 GlobalPoint& x, double& s) const {
00262
00263
00264
00265
00266
00267
00268 StraightLineBarrelCylinderCrossing cylCrossing(x0,p0,propagationDirection());
00269
00270
00271
00272 std::pair<bool,double> propResult = cylCrossing.pathLength(cylinder);
00273 if ( !propResult.first ) return false;
00274 s = propResult.second;
00275
00276 x = cylCrossing.position(s);
00277
00278 return true;
00279 }
00280
00281 bool
00282 AnalyticalPropagator::propagateWithHelixCrossing (HelixPlaneCrossing& planeCrossing,
00283 const Plane& plane,
00284 const float pmag,
00285 GlobalPoint& x,
00286 GlobalVector& p,
00287 double& s) const {
00288
00289 std::pair<bool,double> propResult = planeCrossing.pathLength(plane);
00290 if ( !propResult.first ) return false;
00291 s = propResult.second;
00292
00293 HelixPlaneCrossing::PositionType xGen = planeCrossing.position(s);
00294 x = GlobalPoint(xGen);
00295
00296 HelixPlaneCrossing::DirectionType pGen = planeCrossing.direction(s);
00297 pGen *= pmag/pGen.mag();
00298 p = GlobalVector(pGen);
00299
00300 return true;
00301 }