CMS 3D CMS Logo

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

Generated on Tue Jun 9 17:48:36 2009 for CMSSW by  doxygen 1.5.4