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
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
00058
00059
00060
00061 AlgebraicVector7 par;
00062 AlgebraicSymMatrix77 cov;
00063
00064
00065 GlobalTrajectoryParameters inPar(state.globalPosition(),state.globalMomentum(),
00066 state.particleCharge(), state.magneticField());
00067 ParticleMass mass = state.mass();
00068 GlobalVector inMom = state.globalMomentum();
00069
00070
00071
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
00100
00101
00102
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
00117
00118
00119 AlgebraicSymMatrix66 cov1 = ROOT::Math::Similarity(ca2cu, state.kinematicParametersError().matrix());
00120
00121
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
00128 AlgebraicSymMatrix66 cov2 = ROOT::Math::Similarity(pr, cov1);
00129
00130
00131 cov = ROOT::Math::Similarity(cu2ca, cov2);
00132
00133
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
00143 AlgebraicVector7 par;
00144 AlgebraicSymMatrix77 cov;
00145
00146
00147 GlobalTrajectoryParameters inPar(state.globalPosition(),state.globalMomentum(),
00148 state.particleCharge(), state.magneticField());
00149
00150
00151
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
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
00179 par(6) = state.mass();
00180
00181
00182
00183
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
00199
00200
00201 AlgebraicSymMatrix66 cov1 = ROOT::Math::Similarity(ca2cu, state.kinematicParametersError().matrix());
00202
00203
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
00210 AlgebraicSymMatrix66 cov2 = ROOT::Math::Similarity(pr, cov1);
00211
00212
00213 cov = ROOT::Math::Similarity(cu2ca, cov2);
00214
00215
00216 KinematicParameters resPar(par);
00217 KinematicParametersError resEr(cov);
00218 return KinematicState(resPar,resEr,state.particleCharge(), state.magneticField());
00219 }
00220
00221