CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_9/src/RecoVertex/KinematicFitPrimitives/src/TrackKinematicStatePropagator.cc

Go to the documentation of this file.
00001 #include "RecoVertex/KinematicFitPrimitives/interface/TrackKinematicStatePropagator.h"
00002 #include "TrackingTools/AnalyticalJacobians/interface/JacobianCartesianToCurvilinear.h"
00003 #include "TrackingTools/AnalyticalJacobians/interface/JacobianCurvilinearToCartesian.h"
00004 #include "TrackingTools/AnalyticalJacobians/interface/AnalyticalCurvilinearJacobian.h"
00005 #include "DataFormats/GeometrySurface/interface/BoundPlane.h"
00006 #include "DataFormats/GeometrySurface/interface/OpenBounds.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 
00009 using namespace std;
00010 
00011 KinematicState
00012 TrackKinematicStatePropagator::propagateToTheTransversePCA
00013         (const KinematicState& state, const GlobalPoint& referencePoint) const
00014 {
00015  if( state.particleCharge() == 0. ) {
00016     return propagateToTheTransversePCANeutral(state, referencePoint);
00017   } else {
00018     return propagateToTheTransversePCACharged(state, referencePoint);
00019   }
00020 }
00021 
00022 pair<HelixBarrelPlaneCrossingByCircle, BoundPlane::BoundPlanePointer>
00023 TrackKinematicStatePropagator::planeCrossing(const FreeTrajectoryState& state,
00024         const GlobalPoint& point) const
00025 {
00026  GlobalPoint inPos = state.position();
00027  GlobalVector inMom = state.momentum();
00028  double kappa = state.transverseCurvature();
00029  double fac = 1./state.charge()/state.parameters().magneticField().inInverseGeV(point).z();
00030  
00031  GlobalVectorDouble xOrig2Centre = GlobalVectorDouble(fac * inMom.y(), -fac * inMom.x(), 0.);
00032  GlobalVectorDouble xOrigProj = GlobalVectorDouble(inPos.x(), inPos.y(), 0.);
00033  GlobalVectorDouble xRefProj = GlobalVectorDouble(point.x(), point.y(), 0.);
00034  GlobalVectorDouble deltax = xRefProj-xOrigProj-xOrig2Centre;
00035  GlobalVectorDouble ndeltax = deltax.unit();
00036   
00037  PropagationDirection direction = anyDirection;
00038  Surface::PositionType pos(point);
00039   
00040 // Need to define plane with orientation as the ImpactPointSurface
00041  GlobalVector X(ndeltax.x(), ndeltax.y(), ndeltax.z());
00042  GlobalVector Y(0.,0.,1.);
00043  Surface::RotationType rot(X,Y);
00044  BoundPlane::BoundPlanePointer plane = BoundPlane::build(pos,rot,OpenBounds());
00045  HelixBarrelPlaneCrossingByCircle 
00046    planeCrossing(HelixPlaneCrossing::PositionType(inPos.x(), inPos.y(), inPos.z()),
00047                  HelixPlaneCrossing::DirectionType(inMom.x(), inMom.y(), inMom.z()), 
00048                  kappa, direction);
00049  return std::pair<HelixBarrelPlaneCrossingByCircle,BoundPlane::BoundPlanePointer>(planeCrossing,plane);
00050 }
00051 
00052 
00053 KinematicState
00054 TrackKinematicStatePropagator::propagateToTheTransversePCACharged
00055         (const KinematicState& state, const GlobalPoint& referencePoint) const
00056 {
00057 //first use the existing FTS propagator to obtain parameters at PCA
00058 //in transverse plane to the given point
00059 
00060 //final parameters and covariance
00061   AlgebraicVector7 par;
00062   AlgebraicSymMatrix77 cov;
00063     
00064 //initial parameters as class and vectors:  
00065   GlobalTrajectoryParameters inPar(state.globalPosition(),state.globalMomentum(), 
00066                 state.particleCharge(), state.magneticField());
00067   ParticleMass mass = state.mass();                                                       
00068   GlobalVector inMom = state.globalMomentum();                                                    
00069   
00070 //making a free trajectory state and looking 
00071 //for helix barrel plane crossing  
00072   FreeTrajectoryState fState = state.freeTrajectoryState();             
00073   GlobalPoint iP = referencePoint;                                        
00074   std::pair<HelixBarrelPlaneCrossingByCircle, BoundPlane::BoundPlanePointer> cros = planeCrossing(fState,iP);      
00075   
00076   HelixBarrelPlaneCrossingByCircle planeCrossing = cros.first; 
00077   BoundPlane::BoundPlanePointer plane = cros.second;
00078   std::pair<bool,double> propResult = planeCrossing.pathLength(*plane);
00079   if ( !propResult.first ) {
00080     LogDebug("RecoVertex/TrackKinematicStatePropagator") 
00081          << "Propagation failed! State is invalid\n";
00082     return  KinematicState();
00083   }
00084   double s = propResult.second;
00085   
00086   HelixPlaneCrossing::PositionType xGen = planeCrossing.position(s);
00087   GlobalPoint nPosition(xGen.x(),xGen.y(),xGen.z());
00088   HelixPlaneCrossing::DirectionType pGen = planeCrossing.direction(s);
00089   pGen *= inMom.mag()/pGen.mag();
00090   GlobalVector nMomentum(pGen.x(),pGen.y(),pGen.z()); 
00091   par(0) = nPosition.x();
00092   par(1) = nPosition.y();
00093   par(2) = nPosition.z();
00094   par(3) = nMomentum.x();
00095   par(4) = nMomentum.y();
00096   par(5) = nMomentum.z();
00097   par(6) = mass;
00098   
00099 //covariance matrix business  
00100 //elements of 7x7 covariance matrix responcible for the mass and
00101 //mass - momentum projections corellations do change under such a transformation:
00102 //special Jacobian needed  
00103   GlobalTrajectoryParameters fPar(nPosition, nMomentum, state.particleCharge(),
00104                                 state.magneticField());
00105                                                                                                   
00106   JacobianCartesianToCurvilinear cart2curv(inPar);
00107   JacobianCurvilinearToCartesian curv2cart(fPar);
00108   
00109   AlgebraicMatrix67 ca2cu;
00110   AlgebraicMatrix76 cu2ca;
00111   ca2cu.Place_at(cart2curv.jacobian(),0,0);
00112   cu2ca.Place_at(curv2cart.jacobian(),0,0);
00113   ca2cu(5,6) = 1;  
00114   cu2ca(6,5) = 1;
00115 
00116 //now both transformation jacobians: cartesian to curvilinear and back are done
00117 //We transform matrix to curv frame, then propagate it and translate it back to
00118 //cartesian frame.  
00119   AlgebraicSymMatrix66 cov1 = ROOT::Math::Similarity(ca2cu, state.kinematicParametersError().matrix());
00120 
00121 //propagation jacobian
00122   AnalyticalCurvilinearJacobian prop(inPar,nPosition,nMomentum,s);
00123   AlgebraicMatrix66 pr;
00124   pr(5,5) = 1;
00125   pr.Place_at(prop.jacobian(),0,0);
00126 
00127 //transportation
00128   AlgebraicSymMatrix66 cov2 = ROOT::Math::Similarity(pr, cov1);
00129   
00130 //now geting back to 7-parametrization from curvilinear
00131   cov = ROOT::Math::Similarity(cu2ca, cov2);
00132   
00133 //return parameters as a kiematic state  
00134   KinematicParameters resPar(par);
00135   KinematicParametersError resEr(cov);
00136   return  KinematicState(resPar,resEr,state.particleCharge(), state.magneticField()); 
00137  }
00138   
00139 KinematicState TrackKinematicStatePropagator::propagateToTheTransversePCANeutral
00140         (const KinematicState& state, const GlobalPoint& referencePoint) const
00141 {
00142 //new parameters vector and covariance:
00143  AlgebraicVector7 par;
00144  AlgebraicSymMatrix77 cov;
00145  
00146  //AlgebraicVector7 inStatePar = state.kinematicParameters().vector();
00147  GlobalTrajectoryParameters inPar(state.globalPosition(),state.globalMomentum(), 
00148                 state.particleCharge(), state.magneticField());
00149  
00150 //first making a free trajectory state and propagating it according
00151 //to the algorithm provided by Thomas Speer and Wolfgang Adam 
00152  FreeTrajectoryState fState = state.freeTrajectoryState();
00153   
00154  GlobalPoint xvecOrig = fState.position();
00155  double phi = fState.momentum().phi();
00156  double theta = fState.momentum().theta();
00157  double xOrig = xvecOrig.x();
00158  double yOrig = xvecOrig.y();
00159  double zOrig = xvecOrig.z();
00160  double xR = referencePoint.x();
00161  double yR = referencePoint.y();
00162 
00163  double s2D = (xR - xOrig)  * cos(phi) + (yR - yOrig)  * sin(phi);
00164  double s = s2D / sin(theta);
00165  double xGen = xOrig + s2D*cos(phi);
00166  double yGen = yOrig + s2D*sin(phi);
00167  double zGen = zOrig + s2D/tan(theta);
00168  GlobalPoint xPerigee = GlobalPoint(xGen, yGen, zGen);
00169 
00170 //new parameters
00171  GlobalVector pPerigee = fState.momentum();
00172  par(0) = xPerigee.x();
00173  par(1) = xPerigee.y(); 
00174  par(2) = xPerigee.z(); 
00175  par(3) = pPerigee.x(); 
00176  par(4) = pPerigee.y(); 
00177  par(5) = pPerigee.z(); 
00178  // par(6) = inStatePar(7);
00179  par(6) = state.mass();
00180 
00181 //covariance matrix business:
00182 //everything lake it was before: jacobains are smart enouhg to 
00183 //distinguish between neutral and charged states themselves
00184 
00185  GlobalTrajectoryParameters fPar(xPerigee, pPerigee, state.particleCharge(),
00186                                 state.magneticField());
00187 
00188  JacobianCartesianToCurvilinear cart2curv(inPar);
00189  JacobianCurvilinearToCartesian curv2cart(fPar);
00190   
00191   AlgebraicMatrix67 ca2cu;
00192   AlgebraicMatrix76 cu2ca;
00193   ca2cu.Place_at(cart2curv.jacobian(),0,0);
00194   cu2ca.Place_at(curv2cart.jacobian(),0,0);
00195   ca2cu(5,6) = 1;  
00196   cu2ca(6,5) = 1;
00197 
00198 //now both transformation jacobians: cartesian to curvilinear and back are done
00199 //We transform matrix to curv frame, then propagate it and translate it back to
00200 //cartesian frame.  
00201   AlgebraicSymMatrix66 cov1 = ROOT::Math::Similarity(ca2cu, state.kinematicParametersError().matrix());
00202 
00203 //propagation jacobian
00204   AnalyticalCurvilinearJacobian prop(inPar,xPerigee,pPerigee,s);
00205   AlgebraicMatrix66 pr;
00206   pr(5,5) = 1;
00207   pr.Place_at(prop.jacobian(),0,0);
00208   
00209 //transportation
00210   AlgebraicSymMatrix66 cov2 = ROOT::Math::Similarity(pr, cov1);
00211   
00212 //now geting back to 7-parametrization from curvilinear
00213   cov = ROOT::Math::Similarity(cu2ca, cov2);
00214  
00215 //return parameters as a kiematic state  
00216  KinematicParameters resPar(par);
00217  KinematicParametersError resEr(cov);
00218  return  KinematicState(resPar,resEr,state.particleCharge(), state.magneticField());    
00219 }
00220 
00221