00001 #include "RecoVertex/KinematicFitPrimitives/interface/ParticleKinematicLinearizedTrackState.h"
00002 #include "RecoVertex/KinematicFitPrimitives/interface/KinematicRefittedTrackState.h"
00003 #include "RecoVertex/KinematicFitPrimitives/interface/KinematicPerigeeConversions.h"
00004
00005 const AlgebraicVector6 & ParticleKinematicLinearizedTrackState::constantTerm() const
00006 {
00007 if (!jacobiansAvailable) computeJacobians();
00008 return theConstantTerm;
00009 }
00010
00011 const AlgebraicMatrix63 & ParticleKinematicLinearizedTrackState::positionJacobian() const
00012 {
00013 if (!jacobiansAvailable) computeJacobians();
00014 return thePositionJacobian;
00015 }
00016
00017 const AlgebraicMatrix64 & ParticleKinematicLinearizedTrackState::momentumJacobian() const
00018 {
00019 if (!jacobiansAvailable)computeJacobians();
00020 return theMomentumJacobian;
00021 }
00022
00023 const AlgebraicVector6 & ParticleKinematicLinearizedTrackState::parametersFromExpansion() const
00024 {
00025 if (!jacobiansAvailable) computeJacobians();
00026 return theExpandedParams;
00027 }
00028
00029 AlgebraicVector6 ParticleKinematicLinearizedTrackState::predictedStateParameters() const
00030 {
00031 if(!jacobiansAvailable) computeJacobians();
00032
00033 return thePredState.perigeeParameters().vector();
00034 }
00035
00036 AlgebraicSymMatrix66 ParticleKinematicLinearizedTrackState::predictedStateWeight() const
00037 {
00038 if(!jacobiansAvailable) computeJacobians();
00039 return thePredState.perigeeError().weightMatrix();
00040 }
00041
00042 AlgebraicSymMatrix66 ParticleKinematicLinearizedTrackState::predictedStateError() const
00043 {
00044 if(!jacobiansAvailable) computeJacobians();
00045 return thePredState.perigeeError().covarianceMatrix();
00046 }
00047
00048
00049
00050
00051 TrackCharge ParticleKinematicLinearizedTrackState::charge() const
00052 {return part->initialState().particleCharge();}
00053
00054 RefCountedKinematicParticle ParticleKinematicLinearizedTrackState::particle() const
00055 {return part;}
00056
00057 bool ParticleKinematicLinearizedTrackState::operator ==(LinearizedTrackState<6>& other)const
00058 {
00059 const ParticleKinematicLinearizedTrackState* otherP =
00060 dynamic_cast<const ParticleKinematicLinearizedTrackState*>(&other);
00061 if (otherP == 0) {
00062 throw VertexException(" ParticleKinematicLinearizedTrackState:: don't know how to compare myself to non-kinematic track state");
00063 }
00064 return (*(otherP->particle()) == *part);}
00065
00066 bool ParticleKinematicLinearizedTrackState::hasError() const
00067 {
00068 if (!jacobiansAvailable) computeJacobians();
00069 return thePredState.isValid();
00070 }
00071
00072
00073
00074
00075
00076
00077
00078 void ParticleKinematicLinearizedTrackState::computeJacobians() const
00079 {
00080 GlobalPoint paramPt(theLinPoint);
00081 thePredState = builder(part->currentState(), paramPt);
00082
00083
00084 if (abs(theCharge)<1e-5) {
00085
00086
00087 computeNeutralJacobians();
00088 }else{
00089
00090
00091 computeChargedJacobians();
00092 }
00093 jacobiansAvailable = true;
00094 }
00095 ReferenceCountingPointer<LinearizedTrackState<6> >
00096 ParticleKinematicLinearizedTrackState::stateWithNewLinearizationPoint
00097 (const GlobalPoint & newLP) const
00098 {
00099 RefCountedKinematicParticle pr = part;
00100 return new ParticleKinematicLinearizedTrackState(newLP, pr);
00101 }
00102
00103 ParticleKinematicLinearizedTrackState::RefCountedRefittedTrackState
00104 ParticleKinematicLinearizedTrackState::createRefittedTrackState(
00105 const GlobalPoint & vertexPosition, const AlgebraicVector4 & vectorParameters,
00106 const AlgebraicSymMatrix77 & covarianceMatrix) const
00107 {
00108 KinematicPerigeeConversions conversions;
00109 KinematicState lst = conversions.kinematicState(vectorParameters, vertexPosition,
00110 charge(), covarianceMatrix, part->currentState().magneticField());
00111 RefCountedRefittedTrackState rst = RefCountedRefittedTrackState(new KinematicRefittedTrackState(lst));
00112 return rst;
00113 }
00114
00115 AlgebraicVector4 ParticleKinematicLinearizedTrackState::predictedStateMomentumParameters() const
00116 {
00117 if(!jacobiansAvailable) computeJacobians();
00118 AlgebraicVector4 res;
00119 res[0] = thePredState.perigeeParameters().vector()(0);
00120 res[1] = thePredState.perigeeParameters().vector()(1);
00121 res[2] = thePredState.perigeeParameters().vector()(2);
00122 res[3] = thePredState.perigeeParameters().vector()(5);
00123 return res;
00124 }
00125
00126 AlgebraicSymMatrix44 ParticleKinematicLinearizedTrackState::predictedStateMomentumError() const
00127 {
00128 if(!jacobiansAvailable) computeJacobians();
00129 AlgebraicSymMatrix44 res;
00130 AlgebraicSymMatrix33 m3 =
00131 thePredState.perigeeError().weightMatrix().Sub<AlgebraicSymMatrix33>(0,0);
00132 res.Place_at(m3,0,0);
00133 res(3,0) = thePredState.perigeeError().weightMatrix()(5,5);
00134 res(3,1) = thePredState.perigeeError().weightMatrix()(5,0);
00135 res(3,2) = thePredState.perigeeError().weightMatrix()(5,1);
00136 res(3,3) = thePredState.perigeeError().weightMatrix()(5,2);
00137 return res;
00138 }
00139
00140 double ParticleKinematicLinearizedTrackState::weightInMixture() const
00141 {return 1.;}
00142
00143
00144 std::vector<ReferenceCountingPointer<LinearizedTrackState<6> > >
00145 ParticleKinematicLinearizedTrackState::components()const
00146 {
00147 std::vector<ReferenceCountingPointer<LinearizedTrackState<6> > > res;
00148 res.reserve(1);
00149 res.push_back(RefCountedLinearizedTrackState(
00150 const_cast< ParticleKinematicLinearizedTrackState*>(this)));
00151 return res;
00152 }
00153
00154
00155 AlgebraicVector6 ParticleKinematicLinearizedTrackState::refittedParamFromEquation(
00156 const RefCountedRefittedTrackState & theRefittedState) const
00157 {
00158 AlgebraicVector3 vertexPosition;
00159 vertexPosition(0) = theRefittedState->position().x();
00160 vertexPosition(1) = theRefittedState->position().y();
00161 vertexPosition(2) = theRefittedState->position().z();
00162 AlgebraicVector6 param = constantTerm() +
00163 positionJacobian() * vertexPosition +
00164 momentumJacobian() * theRefittedState->momentumVector();
00165 if (param(2) > M_PI) param(2)-= 2*M_PI;
00166 if (param(2) < -M_PI) param(2)+= 2*M_PI;
00167
00168 return param;
00169 }
00170
00171
00172 void ParticleKinematicLinearizedTrackState::checkParameters(AlgebraicVector6 & parameters) const
00173 {
00174 if (parameters(2) > M_PI) parameters(2)-= 2*M_PI;
00175 if (parameters(2) < -M_PI) parameters(2)+= 2*M_PI;
00176 }
00177
00178
00179 void ParticleKinematicLinearizedTrackState::computeChargedJacobians() const
00180 {
00181 GlobalPoint paramPt(theLinPoint);
00182
00183
00184 double field = part->currentState().magneticField()->inInverseGeV(thePredState.theState().globalPosition()).z();
00185 double signTC = -part->currentState().particleCharge();
00186
00187 double thetaAtEP = thePredState.theState().globalMomentum().theta();
00188 double phiAtEP = thePredState.theState().globalMomentum().phi();
00189 double ptAtEP = thePredState.theState().globalMomentum().perp();
00190 double transverseCurvatureAtEP = field / ptAtEP*signTC;
00191
00192 double x_v = thePredState.theState().globalPosition().x();
00193 double y_v = thePredState.theState().globalPosition().y();
00194 double z_v = thePredState.theState().globalPosition().z();
00195 double X = x_v - paramPt.x() - sin(phiAtEP) / transverseCurvatureAtEP;
00196 double Y = y_v - paramPt.y() + cos(phiAtEP) / transverseCurvatureAtEP;
00197 double SS = X*X + Y*Y;
00198 double S = sqrt(SS);
00199
00200
00201 theExpandedParams[0] = transverseCurvatureAtEP;
00202 theExpandedParams[1] = thetaAtEP;
00203 theExpandedParams[3] = 1/transverseCurvatureAtEP - signTC * S;
00204
00205 theExpandedParams[5] = part->currentState().mass();
00206
00207 double phiFEP;
00208 if (std::abs(X)>std::abs(Y)) {
00209 double signX = (X>0.0? +1.0:-1.0);
00210 phiFEP = -signTC * signX*acos(signTC*Y/S);
00211 } else {
00212 phiFEP = asin(-signTC*X/S);
00213 if ((signTC*Y)<0.0)
00214 phiFEP = M_PI - phiFEP;
00215 }
00216 if (phiFEP>M_PI) phiFEP-= 2*M_PI;
00217 theExpandedParams[2] = phiFEP;
00218 theExpandedParams[4] = z_v - paramPt.z() -
00219 (phiAtEP - theExpandedParams[2]) / tan(thetaAtEP)/transverseCurvatureAtEP;
00220
00221 thePositionJacobian(2, 0) = - Y / (SS);
00222 thePositionJacobian(2, 1) = X / (SS);
00223 thePositionJacobian(3, 0) = - signTC * X / S;
00224 thePositionJacobian(3, 1) = - signTC * Y / S;
00225 thePositionJacobian(4, 0) = thePositionJacobian(2, 0)/tan(thetaAtEP)/transverseCurvatureAtEP;
00226 thePositionJacobian(4, 1) = thePositionJacobian(2, 1)/tan(thetaAtEP)/transverseCurvatureAtEP;
00227 thePositionJacobian(4, 2) = 1;
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 theMomentumJacobian(0, 0) = 1;
00241 theMomentumJacobian(1, 1) = 1;
00242
00243 theMomentumJacobian(2, 0) = -
00244 (X*cos(phiAtEP) + Y*sin(phiAtEP))/
00245 (SS*transverseCurvatureAtEP*transverseCurvatureAtEP);
00246
00247 theMomentumJacobian(2, 2) = (Y*cos(phiAtEP) - X*sin(phiAtEP)) /
00248 (SS*transverseCurvatureAtEP);
00249
00250 theMomentumJacobian(3, 0) =
00251 (signTC * (Y*cos(phiAtEP) - X*sin(phiAtEP)) / S - 1)/
00252 (transverseCurvatureAtEP*transverseCurvatureAtEP);
00253
00254 theMomentumJacobian(3, 2) = signTC *(X*cos(phiAtEP) + Y*sin(phiAtEP))/
00255 (S*transverseCurvatureAtEP);
00256
00257 theMomentumJacobian(4, 0) = (phiAtEP - theExpandedParams(2)) /
00258 tan(thetaAtEP)/(transverseCurvatureAtEP*transverseCurvatureAtEP)+
00259 theMomentumJacobian(2, 0) / tan(thetaAtEP)/transverseCurvatureAtEP;
00260
00261 theMomentumJacobian(4, 1) = (phiAtEP - theExpandedParams(2)) *
00262 (1 + 1/(tan(thetaAtEP)*tan(thetaAtEP)))/transverseCurvatureAtEP;
00263
00264 theMomentumJacobian(4, 2) = (theMomentumJacobian(2, 2) - 1) /
00265 tan(thetaAtEP)/transverseCurvatureAtEP;
00266
00267
00268 theMomentumJacobian(5, 3) = 1;
00269
00270
00271 AlgebraicVector3 expansionPoint;
00272 expansionPoint[0] = thePredState.theState().globalPosition().x();
00273 expansionPoint[1] = thePredState.theState().globalPosition().y();
00274 expansionPoint[2] = thePredState.theState().globalPosition().z();
00275 AlgebraicVector4 momentumAtExpansionPoint;
00276 momentumAtExpansionPoint[0] = transverseCurvatureAtEP;
00277 momentumAtExpansionPoint[1] = thetaAtEP;
00278 momentumAtExpansionPoint[2] = phiAtEP;
00279 momentumAtExpansionPoint[3] = theExpandedParams[5];
00280
00281 theConstantTerm = AlgebraicVector6( theExpandedParams -
00282 thePositionJacobian * expansionPoint -
00283 theMomentumJacobian * momentumAtExpansionPoint );
00284 }
00285
00286
00287 void ParticleKinematicLinearizedTrackState::computeNeutralJacobians() const
00288 {
00289 GlobalPoint paramPt(theLinPoint);
00290 double thetaAtEP = thePredState.theState().globalMomentum().theta();
00291 double phiAtEP = thePredState.theState().globalMomentum().phi();
00292 double ptAtEP = thePredState.theState().globalMomentum().perp();
00293
00294
00295 double x_v = thePredState.theState().globalPosition().x();
00296 double y_v = thePredState.theState().globalPosition().y();
00297 double z_v = thePredState.theState().globalPosition().z();
00298 double X = x_v - paramPt.x();
00299 double Y = y_v - paramPt.y();
00300
00301
00302 theExpandedParams[0] = 1 / ptAtEP;
00303 theExpandedParams[1] = thetaAtEP;
00304 theExpandedParams[2] = phiAtEP;
00305 theExpandedParams[3] = X*sin(phiAtEP) - Y*cos(phiAtEP);
00306 theExpandedParams[4] = z_v - paramPt.z() -
00307 (X*cos(phiAtEP) + Y*sin(phiAtEP)) / tan(thetaAtEP);
00308 theExpandedParams[5] = part->currentState().mass();
00309
00310
00311
00312
00313
00314 thePositionJacobian(3, 0) = sin(phiAtEP);
00315 thePositionJacobian(3, 1) = - cos(phiAtEP);
00316 thePositionJacobian(4, 0) = - cos(phiAtEP)/tan(thetaAtEP);
00317 thePositionJacobian(4, 1) = - sin(phiAtEP)/tan(thetaAtEP);
00318 thePositionJacobian(4, 2) = 1;
00319
00320
00321
00322
00323 theMomentumJacobian(0, 0) = 1;
00324 theMomentumJacobian(1, 1) = 1;
00325 theMomentumJacobian(2, 2) = 1;
00326
00327 theMomentumJacobian(3, 2) = X*cos(phiAtEP) + Y*sin(phiAtEP);
00328 theMomentumJacobian(4, 1) = theMomentumJacobian(3,2)*
00329 (1 + 1/(tan(thetaAtEP)*tan(thetaAtEP)));
00330
00331 theMomentumJacobian(4, 2) = (X*sin(phiAtEP) - Y*cos(phiAtEP))/tan(thetaAtEP);
00332 theMomentumJacobian(5, 3) = 1;
00333
00334
00335 AlgebraicVector3 expansionPoint;
00336 expansionPoint[0] = thePredState.theState().globalPosition().x();
00337 expansionPoint[1] = thePredState.theState().globalPosition().y();
00338 expansionPoint[2] = thePredState.theState().globalPosition().z();
00339 AlgebraicVector4 momentumAtExpansionPoint;
00340 momentumAtExpansionPoint[0] = 1 / ptAtEP;
00341 momentumAtExpansionPoint[1] = thetaAtEP;
00342 momentumAtExpansionPoint[2] = phiAtEP;
00343 momentumAtExpansionPoint[3] = theExpandedParams[5];
00344
00345 theConstantTerm = AlgebraicVector6( theExpandedParams -
00346 thePositionJacobian * expansionPoint -
00347 theMomentumJacobian * momentumAtExpansionPoint );
00348 }
00349
00350 reco::TransientTrack ParticleKinematicLinearizedTrackState::track() const
00351 {
00352 throw VertexException(" ParticleKinematicLinearizedTrackState:: no TransientTrack to return");
00353 }
00354
00355
00356