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
00101
00102 ReferenceCountingPointer<TangentPlane> plane(cylinder.tangentPlane(x));
00103 return propagatedStateWithPath(fts,*plane,gtp,s);
00104
00105
00106
00107
00108
00109
00110
00111
00112 }
00113
00114 std::pair<TrajectoryStateOnSurface,double>
00115 AnalyticalPropagator::propagatedStateWithPath (const FreeTrajectoryState& fts,
00116 const Surface& surface,
00117 const GlobalTrajectoryParameters& gtp,
00118 const double& s) const
00119 {
00120
00121
00122
00123
00124 SurfaceSide side = PropagationDirectionFromPath()(s,propagationDirection())==alongMomentum
00125 ? beforeSurface : afterSurface;
00126
00127
00128
00129
00130 if (fts.hasError()) {
00131
00132
00133
00134 AnalyticalCurvilinearJacobian analyticalJacobian(fts.parameters(), gtp.position(), gtp.momentum(), s);
00135 const AlgebraicMatrix55 &jacobian = analyticalJacobian.jacobian();
00136 CurvilinearTrajectoryError cte(ROOT::Math::Similarity(jacobian, fts.curvilinearError().matrix()));
00137 return TsosWP(TrajectoryStateOnSurface(gtp,cte,surface,side),s);
00138 }
00139 else {
00140
00141
00142
00143 return TsosWP(TrajectoryStateOnSurface(gtp,surface,side),s);
00144 }
00145 }
00146
00147 bool AnalyticalPropagator::propagateParametersOnCylinder(
00148 const FreeTrajectoryState& fts, const Cylinder& cylinder,
00149 GlobalPoint& x, GlobalVector& p, double& s) const
00150 {
00151
00152 GlobalPoint const & sp = cylinder.position();
00153 if (sp.x()!=0. || sp.y()!=0.) {
00154 throw PropagationException("Cannot propagate to an arbitrary cylinder");
00155 }
00156
00157 x = fts.position();
00158 p = fts.momentum();
00159 s = 0;
00160
00161 double rho = fts.transverseCurvature();
00162
00163
00164
00165
00166 if( fabs(rho)<1.e-10 )
00167 return propagateWithLineCrossing(fts.position(),p,cylinder,x,s);
00168
00169
00170
00171
00172 const double tolerance = 1.e-4;
00173 double rdiff = x.perp() - cylinder.radius();
00174 if ( fabs(rdiff) < tolerance ) return true;
00175
00176
00177
00178 HelixBarrelCylinderCrossing cylinderCrossing(fts.position(),fts.momentum(),rho,
00179 propagationDirection(),cylinder);
00180 if ( !cylinderCrossing.hasSolution() ) return false;
00181
00182 s = cylinderCrossing.pathLength();
00183
00184 x = cylinderCrossing.position();
00185
00186 p = cylinderCrossing.direction().unit()*fts.momentum().mag();
00187 return true;
00188 }
00189
00190 bool
00191 AnalyticalPropagator::propagateParametersOnPlane(const FreeTrajectoryState& fts,
00192 const Plane& plane,
00193 GlobalPoint& x,
00194 GlobalVector& p,
00195 double& s) const
00196 {
00197
00198 x = fts.position();
00199 p = fts.momentum();
00200 s = 0;
00201
00202 double rho = fts.transverseCurvature();
00203
00204
00205
00206
00207 if( fabs(rho)<1.e-10 )
00208 return propagateWithLineCrossing(fts.position(),p,plane,x,s);
00209
00210
00211
00212 GlobalVector u = plane.normalVector();
00213 const double small = 1.e-6;
00214
00215
00216
00217
00218
00219 HelixPlaneCrossing::PositionType helixPos(x);
00220 HelixPlaneCrossing::DirectionType helixDir(p);
00221 if (fabs(u.z()) < small) {
00222
00223
00224 HelixBarrelPlaneCrossingByCircle planeCrossing(helixPos,helixDir,rho,propagationDirection());
00225 return propagateWithHelixCrossing(planeCrossing,plane,fts.momentum().mag(),x,p,s);
00226 }
00227 if (fabs(u.x()) < small && fabs(u.y()) < small) {
00228
00229
00230 HelixForwardPlaneCrossing planeCrossing(helixPos,helixDir,rho,propagationDirection());
00231 return propagateWithHelixCrossing(planeCrossing,plane,fts.momentum().mag(),x,p,s);
00232 }
00233 else {
00234
00235
00236 HelixArbitraryPlaneCrossing planeCrossing(helixPos,helixDir,rho,propagationDirection());
00237 return propagateWithHelixCrossing(planeCrossing,plane,fts.momentum().mag(),x,p,s);
00238 }
00239 }
00240
00241 bool
00242 AnalyticalPropagator::propagateWithLineCrossing (const GlobalPoint& x0,
00243 const GlobalVector& p0,
00244 const Plane& plane,
00245 GlobalPoint& x, double& s) const {
00246
00247
00248
00249
00250
00251
00252 StraightLinePlaneCrossing::PositionType pos(x0);
00253 StraightLinePlaneCrossing::DirectionType dir(p0);
00254 StraightLinePlaneCrossing planeCrossing(pos,dir,propagationDirection());
00255
00256
00257
00258 std::pair<bool,double> propResult = planeCrossing.pathLength(plane);
00259 if ( !propResult.first ) return false;
00260 s = propResult.second;
00261
00262 x = GlobalPoint(planeCrossing.position(s));
00263
00264 return true;
00265 }
00266
00267 bool
00268 AnalyticalPropagator::propagateWithLineCrossing (const GlobalPoint& x0,
00269 const GlobalVector& p0,
00270 const Cylinder& cylinder,
00271 GlobalPoint& x, double& s) const {
00272
00273
00274
00275
00276
00277
00278 StraightLineBarrelCylinderCrossing cylCrossing(x0,p0,propagationDirection());
00279
00280
00281
00282 std::pair<bool,double> propResult = cylCrossing.pathLength(cylinder);
00283 if ( !propResult.first ) return false;
00284 s = propResult.second;
00285
00286 x = cylCrossing.position(s);
00287
00288 return true;
00289 }
00290
00291 bool
00292 AnalyticalPropagator::propagateWithHelixCrossing (HelixPlaneCrossing& planeCrossing,
00293 const Plane& plane,
00294 const float pmag,
00295 GlobalPoint& x,
00296 GlobalVector& p,
00297 double& s) const {
00298
00299 std::pair<bool,double> propResult = planeCrossing.pathLength(plane);
00300 if ( !propResult.first ) return false;
00301 s = propResult.second;
00302
00303 HelixPlaneCrossing::PositionType xGen = planeCrossing.position(s);
00304 x = GlobalPoint(xGen);
00305
00306 HelixPlaneCrossing::DirectionType pGen = planeCrossing.direction(s);
00307 pGen *= pmag/pGen.mag();
00308 p = GlobalVector(pGen);
00309
00310 return true;
00311 }