00001 #include "RecoVertex/KinematicFitPrimitives/interface/KinematicPerigeeConversions.h"
00002 #include "TrackingTools/TrajectoryState/interface/PerigeeConversions.h"
00003
00004
00005 ExtendedPerigeeTrajectoryParameters
00006 KinematicPerigeeConversions::extendedPerigeeFromKinematicParameters(
00007 const KinematicState& state, const GlobalPoint& point) const
00008 {
00009
00010
00011 AlgebraicVector6 res;
00012 res(5) = state.mass();
00013
00014 GlobalVector impactDistance = state.globalPosition() - point;
00015 double theta = state.globalMomentum().theta();
00016 double phi = state.globalMomentum().phi();
00017 double pt = state.globalMomentum().transverse();
00018
00019 double field = state.magneticField()->inInverseGeV(state.globalPosition()).z();
00020
00021
00022
00023
00024 double positiveMomentumPhi = ((phi>0) ? phi : (2*M_PI + phi));
00025 double positionPhi = impactDistance.phi();
00026 double positivePositionPhi =
00027 ( (positionPhi>0) ? positionPhi : (2*M_PI+positionPhi) );
00028 double phiDiff = positiveMomentumPhi - positivePositionPhi;
00029 if (phiDiff<0.0) phiDiff+= (2*M_PI);
00030 double signEpsilon = ( (phiDiff > M_PI) ? -1.0 : 1.0);
00031
00032 double epsilon = signEpsilon *
00033 sqrt(impactDistance.x()*impactDistance.x() +
00034 impactDistance.y()*impactDistance.y());
00035
00036 double signTC = -state.particleCharge();
00037 bool isCharged = (signTC!=0);
00038
00039 if (isCharged) {
00040 res(0) = field / pt*signTC;
00041 } else {
00042 res(0) = 1 / pt;
00043 }
00044
00045 res(1) = theta;
00046 res(2) = phi;
00047 res(3) = epsilon;
00048 res(4) = impactDistance.z();
00049 return ExtendedPerigeeTrajectoryParameters(res,state.particleCharge());
00050 }
00051
00052 KinematicParameters KinematicPerigeeConversions::kinematicParametersFromExPerigee(
00053 const ExtendedPerigeeTrajectoryParameters& pr, const GlobalPoint& point,
00054 const MagneticField* field) const
00055 {
00056 AlgebraicVector7 par;
00057 AlgebraicVector6 theVector = pr.vector();
00058 double pt;
00059 if(pr.charge() !=0){
00060 pt = std::abs(field->inInverseGeV(point).z() / theVector(1));
00061 }else{pt = 1/theVector(1);}
00062 par(6) = theVector[5];
00063 par(0) = theVector[3]*sin(theVector[2])+point.x();
00064 par(1) = -theVector[3]*cos(theVector[2])+point.y();
00065 par(2) = theVector[4]+point.z();
00066 par(3) = cos(theVector[2]) * pt;
00067 par(4) = sin(theVector[2]) * pt;
00068 par(5) = pt/tan(theVector[1]);
00069
00070 return KinematicParameters(par);
00071 }
00072
00073
00074 KinematicState
00075 KinematicPerigeeConversions::kinematicState(const AlgebraicVector4& momentum,
00076 const GlobalPoint& referencePoint, const TrackCharge& charge,
00077 const AlgebraicSymMatrix77& theCovarianceMatrix, const MagneticField* field) const
00078 {
00079 AlgebraicMatrix77 param2cart = jacobianParameters2Kinematic(momentum,
00080 referencePoint, charge, field);
00081 AlgebraicSymMatrix77 kinematicErrorMatrix = ROOT::Math::Similarity(param2cart,theCovarianceMatrix);
00082
00083
00084 KinematicParametersError kinematicParamError(kinematicErrorMatrix);
00085 AlgebraicVector7 par;
00086 AlgebraicVector4 mm = momentumFromPerigee(momentum, referencePoint, charge, field);
00087 par(0) = referencePoint.x();
00088 par(1) = referencePoint.y();
00089 par(2) = referencePoint.z();
00090 par(3) = mm(0);
00091 par(4) = mm(1);
00092 par(5) = mm(2);
00093 par(6) = mm(3);
00094 KinematicParameters kPar(par);
00095 return KinematicState(kPar, kinematicParamError, charge, field);
00096 }
00097
00098 AlgebraicMatrix77 KinematicPerigeeConversions::jacobianParameters2Kinematic(
00099 const AlgebraicVector4& momentum, const GlobalPoint& referencePoint,
00100 const TrackCharge& charge, const MagneticField* field)const
00101 {
00102 PerigeeConversions pc;
00103 AlgebraicMatrix66 param2cart = pc.jacobianParameters2Cartesian
00104 (AlgebraicVector3(momentum[0],momentum[1],momentum[2]),
00105 referencePoint, charge, field);
00106 AlgebraicMatrix77 frameTransJ;
00107 for (int i =0;i<6;++i)
00108 for (int j =0;j<6;++j)
00109 frameTransJ(i, j) = param2cart(i, j);
00110 frameTransJ(6, 6) = 1;
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 return frameTransJ;
00131
00132 }
00133
00134
00135 AlgebraicVector4
00136 KinematicPerigeeConversions::momentumFromPerigee(const AlgebraicVector4& momentum,
00137 const GlobalPoint& referencePoint, const TrackCharge& ch,
00138 const MagneticField* field)const
00139 {
00140 AlgebraicVector4 mm;
00141 double pt;
00142 if(ch !=0){
00143
00144 pt = std::abs(field->inInverseGeV(referencePoint).z() / momentum[0]);
00145 }else{pt = 1/ momentum[0];}
00146 mm(0) = cos(momentum[2]) * pt;
00147 mm(1) = sin(momentum[2]) * pt;
00148 mm(2) = pt/tan(momentum[1]);
00149 mm(3) = momentum[3];
00150 return mm;
00151 }
00152