CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/TrackingTools/TrajectoryState/src/PerigeeConversions.cc

Go to the documentation of this file.
00001 #include "TrackingTools/TrajectoryState/interface/PerigeeConversions.h"
00002 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateClosestToPoint.h"
00003 #include "MagneticField/Engine/interface/MagneticField.h" 
00004 #include <cmath>
00005 
00006 PerigeeTrajectoryParameters PerigeeConversions::ftsToPerigeeParameters
00007   (const FTS& originalFTS, const GlobalPoint& referencePoint, double & pt) const
00008 
00009 {
00010   GlobalVector impactDistance = originalFTS.position() - referencePoint;
00011 
00012   pt = originalFTS.momentum().perp();
00013   if (pt==0.) throw cms::Exception("PerigeeConversions", "Track with pt=0");
00014   
00015   double theta = originalFTS.momentum().theta();
00016   double phi = originalFTS.momentum().phi();
00017   double field  = originalFTS.parameters().magneticField().inInverseGeV(originalFTS.position()).z();
00018 //   if (field==0.) throw cms::Exception("PerigeeConversions", "Field is 0") << " at " << originalFTS.position() << "\n" ;
00019 
00020   double positiveMomentumPhi = ( (phi>0) ? phi : (2*M_PI+phi) );
00021   double positionPhi = impactDistance.phi();
00022   double positivePositionPhi =
00023    ( (positionPhi>0) ? positionPhi : (2*M_PI+positionPhi) );
00024   double phiDiff = positiveMomentumPhi - positivePositionPhi;
00025   if (phiDiff<0.0) phiDiff+= (2*M_PI);
00026   double signEpsilon = ( (phiDiff > M_PI) ? -1.0 : 1.0);
00027 
00028   double epsilon = signEpsilon *
00029                      sqrt ( impactDistance.x()*impactDistance.x() +
00030                             impactDistance.y()*impactDistance.y() );
00031 
00032   // The track parameters:
00033   AlgebraicVector5 theTrackParameters;
00034 
00035   double signTC = - originalFTS.charge();
00036   bool isCharged = (signTC!=0) && (fabs(field)>1.e-10);
00037   if (isCharged) {
00038     theTrackParameters[0] = field / pt*signTC;
00039   } else {
00040     theTrackParameters[0] = 1 / pt;
00041   }
00042   theTrackParameters[1] = theta;
00043   theTrackParameters[2] = phi;
00044   theTrackParameters[3] = epsilon;
00045   theTrackParameters[4] = impactDistance.z();
00046   return PerigeeTrajectoryParameters(theTrackParameters, isCharged);
00047 }
00048 
00049 // PerigeeTrajectoryParameters PerigeeConversions::helixToPerigeeParameters
00050 //   (const reco::helix::Parameters & helixPar, const GlobalPoint& referencePoint) const
00051 // {
00052 //   AlgebraicVector theTrackParameters = AlgebraicVector(5);
00053 //   double field  = TrackingTools::FakeField::Field::inTesla(helixPar.vertex()).z() * 2.99792458e-3;
00054 //   theTrackParameters[0] = - field*helixPar.omega();
00055 //   theTrackParameters[1] = atan(1/helixPar.tanDip());
00056 //   theTrackParameters[2] = helixPar.phi0() - M_PI/2;
00057 //   theTrackParameters[3] = helixPar.d0();
00058 //   theTrackParameters[4] = helixPar.dz();
00059 //   return PerigeeTrajectoryParameters(theTrackParameters, helixPar.pt(), true);
00060 // }
00061 
00062 PerigeeTrajectoryError PerigeeConversions::ftsToPerigeeError
00063   (const FTS& originalFTS) const
00064 {
00065   AlgebraicSymMatrix55 errorMatrix = originalFTS.curvilinearError().matrix();
00066   AlgebraicMatrix55 curv2perigee = jacobianCurvilinear2Perigee(originalFTS);
00067   return PerigeeTrajectoryError(ROOT::Math::Similarity(curv2perigee,errorMatrix));
00068 }
00069 
00070 // PerigeeTrajectoryError PerigeeConversions::helixToPerigeeError
00071 //   (const reco::helix::Parameters & helixPar, 
00072 //      const reco::helix::Covariance & helixCov) const
00073 // {
00074 // //FIXME: verify that the order of the parameters are correct
00075 //   AlgebraicSymMatrix55 helixCovMatrix;
00076 //   helixCovMatrix(0,0) = helixCov(reco::helix::i_d0,reco::helix::i_d0);
00077 //   helixCovMatrix(1,1) = helixCov(reco::helix::i_phi0,reco::helix::i_phi0);
00078 //   helixCovMatrix(2,2) = helixCov(reco::helix::i_omega,reco::helix::i_omega);
00079 //   helixCovMatrix(3,3) = helixCov(reco::helix::i_dz,reco::helix::i_dz);
00080 //   helixCovMatrix(4,4) = helixCov(reco::helix::i_tanDip,reco::helix::i_tanDip);
00081 // 
00082 //   helixCovMatrix(0,1) = helixCov(reco::helix::i_d0,reco::helix::i_phi0);
00083 //   helixCovMatrix(0,2) = helixCov(reco::helix::i_d0,reco::helix::i_omega);
00084 //   helixCovMatrix(0,3) = helixCov(reco::helix::i_d0,reco::helix::i_dz);
00085 //   helixCovMatrix(0,4) = helixCov(reco::helix::i_d0,reco::helix::i_tanDip);
00086 // 
00087 //   helixCovMatrix(1,2) = helixCov(reco::helix::i_phi0,reco::helix::i_omega);
00088 //   helixCovMatrix(1,3) = helixCov(reco::helix::i_phi0,reco::helix::i_dz);
00089 //   helixCovMatrix(1,4) = helixCov(reco::helix::i_phi0,reco::helix::i_tanDip);
00090 // 
00091 //   helixCovMatrix(2,3) = helixCov(reco::helix::i_omega,reco::helix::i_dz);
00092 //   helixCovMatrix(2,4) = helixCov(reco::helix::i_omega,reco::helix::i_tanDip);
00093 // 
00094 //   helixCovMatrix(3,4) = helixCov(reco::helix::i_dz,reco::helix::i_tanDip);
00095 // 
00096 //   AlgebraicMatrix helix2perigee = jacobianHelix2Perigee(helixPar, helixCov);
00097 //   return PerigeeTrajectoryError(helixCovMatrix.similarity(helix2perigee));
00098 // }
00099 
00100 
00101 CurvilinearTrajectoryError PerigeeConversions::curvilinearError
00102   (const PerigeeTrajectoryError& perigeeError, const GlobalTrajectoryParameters& gtp) const
00103 {
00104   AlgebraicMatrix55 perigee2curv = jacobianPerigee2Curvilinear(gtp);
00105   return CurvilinearTrajectoryError(ROOT::Math::Similarity(perigee2curv, perigeeError.covarianceMatrix()));
00106 }
00107 
00108 GlobalPoint PerigeeConversions::positionFromPerigee
00109   (const PerigeeTrajectoryParameters& parameters, const GlobalPoint& referencePoint) const
00110 {
00111   AlgebraicVector5 theVector = parameters.vector();
00112   return GlobalPoint(theVector[3]*sin(theVector[2])+referencePoint.x(),
00113                      -theVector[3]*cos(theVector[2])+referencePoint.y(),
00114                      theVector[4]+referencePoint.z());
00115 }
00116 
00117 
00118 GlobalVector PerigeeConversions::momentumFromPerigee
00119   (const PerigeeTrajectoryParameters& parameters, double pt, const GlobalPoint& referencePoint) const
00120 {
00121   return GlobalVector(cos(parameters.phi()) * pt,
00122                       sin(parameters.phi()) * pt,
00123                       pt / tan(parameters.theta()));
00124 }
00125 
00126 GlobalVector PerigeeConversions::momentumFromPerigee
00127   (const AlgebraicVector& momentum, const TrackCharge& charge, 
00128    const GlobalPoint& referencePoint, const MagneticField* field) const {
00129       return momentumFromPerigee(asSVector<3>(momentum), charge, referencePoint, field);
00130   }
00131 
00132 GlobalVector PerigeeConversions::momentumFromPerigee
00133   (const AlgebraicVector3& momentum, const TrackCharge& charge, 
00134    const GlobalPoint& referencePoint, const MagneticField* field) const
00135 {
00136   double pt;
00137   if (momentum[0]==0.) throw cms::Exception("PerigeeConversions", "Track with rho=0");
00138 
00139   double bz = fabs(field->inInverseGeV(referencePoint).z());
00140   if ( charge!=0 && bz>1.e-10 ) {
00141     pt = std::abs(bz/momentum[0]);
00142     if (pt<1.e-10) throw cms::Exception("PerigeeConversions", "pt is 0");
00143   } else {
00144     pt = 1 / momentum[0];
00145   }
00146 
00147   return GlobalVector(cos(momentum[2]) * pt,
00148                       sin(momentum[2]) * pt,
00149                       pt/tan(momentum[1]));
00150 }
00151 
00152 TrackCharge PerigeeConversions::chargeFromPerigee
00153   (const PerigeeTrajectoryParameters& parameters) const
00154 {
00155   return parameters.charge();
00156 }
00157 
00158 TrajectoryStateClosestToPoint PerigeeConversions::trajectoryStateClosestToPoint
00159         (const AlgebraicVector& momentum, const GlobalPoint& referencePoint,
00160          const TrackCharge& charge, const AlgebraicMatrix& theCovarianceMatrix, 
00161          const MagneticField* field) const {
00162             AlgebraicSymMatrix sym; sym.assign(theCovarianceMatrix); // below, this was used for Matrix => SymMatrix
00163             return trajectoryStateClosestToPoint(asSVector<3>(momentum), referencePoint, 
00164                     charge, asSMatrix<6>(sym), field);
00165 
00166         }
00167 
00168 
00169 TrajectoryStateClosestToPoint PerigeeConversions::trajectoryStateClosestToPoint
00170         (const AlgebraicVector3& momentum, const GlobalPoint& referencePoint,
00171          const TrackCharge& charge, const AlgebraicSymMatrix66& theCovarianceMatrix,
00172          const MagneticField* field) const
00173 {
00174   AlgebraicMatrix66 param2cart = jacobianParameters2Cartesian
00175         (momentum, referencePoint, charge, field);
00176   CartesianTrajectoryError cartesianTrajErr(ROOT::Math::Similarity(param2cart, theCovarianceMatrix));
00177 
00178   FTS theFTS(GlobalTrajectoryParameters(referencePoint,
00179             momentumFromPerigee(momentum, charge, referencePoint, field), charge,
00180             field), cartesianTrajErr);
00181 
00182   return TrajectoryStateClosestToPoint(theFTS, referencePoint);
00183 }
00184 
00185 AlgebraicMatrix
00186 PerigeeConversions::jacobianParameters2Cartesian_old(
00187         const AlgebraicVector& momentum, const GlobalPoint& position,
00188         const TrackCharge& charge, const MagneticField* field) const {
00189     return asHepMatrix(jacobianParameters2Cartesian(asSVector<3>(momentum), position, charge, field));
00190 }
00191 
00192 AlgebraicMatrix66
00193 PerigeeConversions::jacobianParameters2Cartesian(
00194         const AlgebraicVector3& momentum, const GlobalPoint& position,
00195         const TrackCharge& charge, const MagneticField* field) const
00196 {
00197   if (momentum[0]==0.) throw cms::Exception("PerigeeConversions", "Track with rho=0");
00198   double factor = 1.;
00199   double bField = field->inInverseGeV(position).z();
00200   if (charge!=0 && fabs(bField)>1.e-10) {
00201 //     if (bField==0.) throw cms::Exception("PerigeeConversions", "Field is 0");
00202     factor = -bField*charge;
00203   }
00204   AlgebraicMatrix66 frameTransJ;
00205   frameTransJ(0,0) = 1;
00206   frameTransJ(1,1) = 1;
00207   frameTransJ(2,2) = 1;
00208   frameTransJ(3,3) = - factor * cos(momentum[2]) / (momentum[0]*momentum[0]);
00209   frameTransJ(4,3) = - factor * sin(momentum[2]) / (momentum[0]*momentum[0]);
00210   frameTransJ(5,3) = - factor / tan(momentum[1]) / (momentum[0]*momentum[0]);
00211 
00212   frameTransJ(3,5) = - factor * sin(momentum[2])  / (momentum[0]);
00213   frameTransJ(4,5) = factor * cos(momentum[2]) / (momentum[0]);
00214   frameTransJ(5,4) = - factor / (momentum[0]*sin(momentum[1])*sin(momentum[1]));
00215 
00216   return frameTransJ;
00217 }
00218 
00219 AlgebraicMatrix
00220 PerigeeConversions::jacobianCurvilinear2Perigee_old(const FreeTrajectoryState& fts) const {
00221     return asHepMatrix(jacobianCurvilinear2Perigee(fts));
00222 }
00223 
00224 
00225 AlgebraicMatrix55
00226 PerigeeConversions::jacobianCurvilinear2Perigee(const FreeTrajectoryState& fts) const {
00227 
00228   GlobalVector p = fts.momentum();
00229 
00230   GlobalVector Z = GlobalVector(0.,0.,1.);
00231   GlobalVector T = p.unit();
00232   GlobalVector U = Z.cross(T).unit();; 
00233   GlobalVector V = T.cross(U);
00234 
00235   GlobalVector I = GlobalVector(-p.x(), -p.y(), 0.); //opposite to track dir.
00236   I = I.unit();
00237   GlobalVector J(-I.y(), I.x(),0.); //counterclockwise rotation
00238   GlobalVector K(Z);
00239   GlobalPoint x = fts.position();
00240   GlobalVector B  = fts.parameters().magneticField().inInverseGeV(x);
00241   GlobalVector H = B.unit();
00242   GlobalVector HxT = H.cross(T);
00243   GlobalVector N = HxT.unit();
00244   double alpha = HxT.mag();
00245   double qbp = fts.signedInverseMomentum();
00246   double Q = -B.mag() * qbp;
00247   double alphaQ = alpha * Q;
00248 
00249   double lambda = 0.5 * M_PI - p.theta();
00250   double coslambda = cos(lambda), tanlambda = tan(lambda);
00251 
00252   double TI = T.dot(I);
00253   double NU = N.dot(U);
00254   double NV = N.dot(V);
00255   double UI = U.dot(I);
00256   double VI = V.dot(I);
00257   double UJ = U.dot(J);
00258   double VJ = V.dot(J);
00259   double UK = U.dot(K);
00260   double VK = V.dot(K);
00261 
00262   AlgebraicMatrix55 jac;
00263 
00264   if( fabs(fts.transverseCurvature())<1.e-10 ) {
00265     jac(0,0) = 1/coslambda;
00266     jac(0,1) = tanlambda/coslambda/fts.parameters().momentum().mag();
00267   }else{
00268     double Bz = B.z();
00269     jac(0,0) = -Bz/coslambda;
00270     jac(0,1) = -Bz * tanlambda/coslambda*qbp;
00271     jac(1,3) = alphaQ * NV * UI/TI;
00272     jac(1,4) = alphaQ * NV * VI/TI;
00273     jac(0,3) = -jac(0,1) * jac(1,3);
00274     jac(0,4) = -jac(0,1) * jac(1,4);
00275     jac(2,3) = -alphaQ/coslambda * NU * UI/TI;
00276     jac(2,4) = -alphaQ/coslambda * NU * VI/TI;
00277   }
00278   jac(1,1) = -1.;
00279   jac(2,2) = 1.;
00280   jac(3,3) = VK/TI;
00281   jac(3,4) = -UK/TI;
00282   jac(4,3) = -VJ/TI;
00283   jac(4,4) = UJ/TI;
00284   
00285   return jac;
00286   
00287 }
00288 
00289 
00290 AlgebraicMatrix 
00291 PerigeeConversions::jacobianPerigee2Curvilinear_old(const GlobalTrajectoryParameters& gtp) const {
00292     return asHepMatrix(jacobianPerigee2Curvilinear(gtp));
00293 }
00294 
00295 AlgebraicMatrix55 
00296 PerigeeConversions::jacobianPerigee2Curvilinear(const GlobalTrajectoryParameters& gtp) const {
00297 
00298   GlobalVector p = gtp.momentum();
00299 
00300   GlobalVector Z = GlobalVector(0.,0.,1.);
00301   GlobalVector T = p.unit();
00302   GlobalVector U = Z.cross(T).unit();; 
00303   GlobalVector V = T.cross(U);
00304 
00305   GlobalVector I = GlobalVector(-p.x(), -p.y(), 0.); //opposite to track dir.
00306   I = I.unit();
00307   GlobalVector J(-I.y(), I.x(),0.); //counterclockwise rotation
00308   GlobalVector K(Z);
00309   GlobalPoint x = gtp.position();
00310   GlobalVector B  = gtp.magneticField().inInverseGeV(x);
00311   GlobalVector H = B.unit();
00312   GlobalVector HxT = H.cross(T);
00313   GlobalVector N = HxT.unit();
00314   double alpha = HxT.mag();
00315   double qbp = gtp.signedInverseMomentum();
00316   double Q = -B.mag() * qbp;
00317   double alphaQ = alpha * Q;
00318 
00319   double lambda = 0.5 * M_PI - p.theta();
00320   double coslambda = cos(lambda), sinlambda = sin(lambda);
00321   double mqbpt = -1./coslambda * qbp;
00322 
00323   double TJ = T.dot(J);
00324   double TK = T.dot(K);
00325   double NU = N.dot(U);
00326   double NV = N.dot(V);
00327   double UJ = U.dot(J);
00328   double VJ = V.dot(J);
00329   double UK = U.dot(K);
00330   double VK = V.dot(K);
00331 
00332   AlgebraicMatrix55 jac;
00333 
00334   if( fabs(gtp.transverseCurvature())<1.e-10 ) {
00335     jac(0,0) = coslambda;
00336     jac(0,1) = sinlambda/coslambda/gtp.momentum().mag();
00337   }else{
00338     jac(0,0) = -coslambda/B.z();
00339     jac(0,1) = -sinlambda * mqbpt;
00340     jac(1,3) = -alphaQ * NV * TJ;
00341     jac(1,4) = -alphaQ * NV * TK;
00342     jac(2,3) = -alphaQ/coslambda * NU * TJ;
00343     jac(2,4) = -alphaQ/coslambda * NU * TK;
00344   }
00345   jac(1,1) = -1.;
00346   jac(2,2) = 1.;
00347   jac(3,3) = UJ;
00348   jac(3,4) = UK;
00349   jac(4,3) = VJ;
00350   jac(4,4) = VK;
00351   
00352   return jac;
00353 }
00354 
00355 // AlgebraicMatrix 
00356 // PerigeeConversions::jacobianHelix2Perigee(const reco::helix::Parameters & helixPar, 
00357 //      const reco::helix::Covariance & helixCov) const
00358 // {
00359 //   AlgebraicMatrix55 jac;
00360 // 
00361 //   jac(3,0) = 1.;
00362 //   jac(2,1) = 1.;
00363 // //   jac(0,2) = - 1. / magField.inTesla(helixPar.vertex()).z() * 2.99792458e-3;
00364 //   jac(0,2) = - 1. / (TrackingTools::FakeField::Field::inTesla(helixPar.vertex()).z() * 2.99792458e-3);
00365 //   jac(4,3) = 1.;
00366 //   jac(1,4) = -(1. + helixPar.tanDip()*helixPar.tanDip());
00367 // std::std::cout << jac;
00368 //   return jac;
00369 // }