CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/TrackingTools/GeomPropagators/src/AnalyticalPropagator.cc

Go to the documentation of this file.
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   // check curvature
00032   double rho = fts.transverseCurvature();
00033   
00034   // propagate parameters
00035   GlobalPoint x;
00036   GlobalVector p;
00037   double s;
00038   
00039   // check if already on plane
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     // propagate
00045     bool parametersOK = this->propagateParametersOnPlane(fts, plane, x, p, s);
00046     // check status and deltaPhi limit
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   // Compute propagated state and check change in curvature
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   // construct TrajectoryStateOnSurface
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   // check curvature
00079   double rho = fts.transverseCurvature();
00080 
00081   // propagate parameters
00082   GlobalPoint x;
00083   GlobalVector p;
00084   double s = 0;
00085 
00086   bool parametersOK = this->propagateParametersOnCylinder(fts, cylinder, x, p, s);
00087   // check status and deltaPhi limit
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   // Compute propagated state and check change in curvature
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   // create result TSOS on TangentPlane (local parameters & errors are better defined)
00099   //
00100   ReferenceCountingPointer<TangentPlane> plane(cylinder.tangentPlane(x));  // need to be here until tsos is created!
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   // for forward propagation: state is before surface,
00112   // for backward propagation: state is after surface
00113   //
00114   SurfaceSide side = PropagationDirectionFromPath()(s,propagationDirection())==alongMomentum 
00115     ? beforeSurface : afterSurface;
00116   // 
00117   //
00118   // error propagation (if needed) and conversion to a TrajectoryStateOnSurface
00119   //
00120   if (fts.hasError()) {
00121     //
00122     // compute jacobian
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     // return state without errors
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   // preset output
00147   x = fts.position();
00148   p = fts.momentum();
00149   s = 0;
00150   // (transverse) curvature
00151   double rho = fts.transverseCurvature();
00152   //
00153   // Straight line approximation? |rho|<1.e-10 equivalent to ~ 1um 
00154   // difference in transversal position at 10m.
00155   //
00156   if( fabs(rho)<1.e-10 )
00157     return propagateWithLineCrossing(fts.position(),p,cylinder,x,s);
00158   //
00159   // Helix case
00160   //
00161   // check for possible intersection
00162   const double tolerance = 1.e-4; // 1 micron distance
00163   double rdiff = x.perp() - cylinder.radius();
00164   if ( fabs(rdiff) < tolerance )  return true;
00165   //
00166   // Instantiate HelixBarrelCylinderCrossing and get solutions
00167   //
00168   HelixBarrelCylinderCrossing cylinderCrossing(fts.position(),fts.momentum(),rho,
00169                                                propagationDirection(),cylinder);
00170   if ( !cylinderCrossing.hasSolution() )  return false;
00171   // path length
00172   s = cylinderCrossing.pathLength();
00173   // point
00174   x = cylinderCrossing.position();
00175   // direction (renormalised)
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   // initialisation of position, momentum and path length
00188   x = fts.position();
00189   p = fts.momentum();
00190   s = 0;
00191   // (transverse) curvature
00192   double rho = fts.transverseCurvature();
00193   //
00194   // Straight line approximation? |rho|<1.e-10 equivalent to ~ 1um 
00195   // difference in transversal position at 10m.
00196   //
00197   if( fabs(rho)<1.e-10 )
00198     return propagateWithLineCrossing(fts.position(),p,plane,x,s);
00199   //
00200   // Helix case 
00201   //
00202   GlobalVector u = plane.normalVector();
00203   const double small = 1.e-6; // for orientation of planes
00204   //
00205   // Frame-independant point and vector are created explicitely to 
00206   // avoid confusing gcc (refuses to compile with temporary objects
00207   // in the constructor).
00208   //
00209   HelixPlaneCrossing::PositionType helixPos(x);
00210   HelixPlaneCrossing::DirectionType helixDir(p);
00211   if (fabs(u.z()) < small) {
00212     // barrel plane:
00213     // instantiate HelixBarrelPlaneCrossing, get vector of solutions and check for existance
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     // forward plane:
00219     // instantiate HelixForwardPlaneCrossing, get vector of solutions and check for existance
00220     HelixForwardPlaneCrossing planeCrossing(helixPos,helixDir,rho,propagationDirection());
00221     return propagateWithHelixCrossing(planeCrossing,plane,fts.momentum().mag(),x,p,s);
00222   }
00223   else {
00224     // arbitrary plane:
00225     // instantiate HelixArbitraryPlaneCrossing, get vector of solutions and check for existance
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   // Instantiate auxiliary object for finding intersection.
00238   // Frame-independant point and vector are created explicitely to 
00239   // avoid confusing gcc (refuses to compile with temporary objects
00240   // in the constructor).
00241   //
00242   StraightLinePlaneCrossing::PositionType pos(x0);
00243   StraightLinePlaneCrossing::DirectionType dir(p0);
00244   StraightLinePlaneCrossing planeCrossing(pos,dir,propagationDirection());
00245   //
00246   // get solution
00247   //
00248   std::pair<bool,double> propResult = planeCrossing.pathLength(plane);
00249   if ( !propResult.first )  return false;
00250   s = propResult.second;
00251   // point (reconverted to GlobalPoint)
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   // Instantiate auxiliary object for finding intersection.
00264   // Frame-independant point and vector are created explicitely to 
00265   // avoid confusing gcc (refuses to compile with temporary objects
00266   // in the constructor).
00267   //
00268   StraightLineBarrelCylinderCrossing cylCrossing(x0,p0,propagationDirection());
00269   //
00270   // get solution
00271   //
00272   std::pair<bool,double> propResult = cylCrossing.pathLength(cylinder);
00273   if ( !propResult.first )  return false;
00274   s = propResult.second;
00275   // point (reconverted to GlobalPoint)
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   // get solution
00289   std::pair<bool,double> propResult = planeCrossing.pathLength(plane);
00290   if ( !propResult.first )  return false;
00291   s = propResult.second;
00292   // point (reconverted to GlobalPoint)
00293   HelixPlaneCrossing::PositionType xGen = planeCrossing.position(s);
00294   x = GlobalPoint(xGen);
00295   // direction (reconverted to GlobalVector, renormalised)
00296   HelixPlaneCrossing::DirectionType pGen = planeCrossing.direction(s);
00297   pGen *= pmag/pGen.mag();
00298   p = GlobalVector(pGen);
00299   //
00300   return true;
00301 }