File indexing completed on 2024-07-24 04:45:12
0001 #include "RecoVertex/KinematicFitPrimitives/interface/ParticleKinematicLinearizedTrackState.h"
0002 #include "RecoVertex/KinematicFitPrimitives/interface/KinematicRefittedTrackState.h"
0003 #include "RecoVertex/KinematicFitPrimitives/interface/KinematicPerigeeConversions.h"
0004
0005 const AlgebraicVector6& ParticleKinematicLinearizedTrackState::constantTerm() const {
0006 if (!jacobiansAvailable)
0007 computeJacobians();
0008 return theConstantTerm;
0009 }
0010
0011 const AlgebraicMatrix63& ParticleKinematicLinearizedTrackState::positionJacobian() const {
0012 if (!jacobiansAvailable)
0013 computeJacobians();
0014 return thePositionJacobian;
0015 }
0016
0017 const AlgebraicMatrix64& ParticleKinematicLinearizedTrackState::momentumJacobian() const {
0018 if (!jacobiansAvailable)
0019 computeJacobians();
0020 return theMomentumJacobian;
0021 }
0022
0023 const AlgebraicVector6& ParticleKinematicLinearizedTrackState::parametersFromExpansion() const {
0024 if (!jacobiansAvailable)
0025 computeJacobians();
0026 return theExpandedParams;
0027 }
0028
0029 AlgebraicVector6 ParticleKinematicLinearizedTrackState::predictedStateParameters() const {
0030 if (!jacobiansAvailable)
0031 computeJacobians();
0032 return thePredState.perigeeParameters().vector();
0033 }
0034
0035 AlgebraicSymMatrix66 ParticleKinematicLinearizedTrackState::predictedStateWeight(int& error) const {
0036 if (!jacobiansAvailable)
0037 computeJacobians();
0038 int i = 0;
0039 AlgebraicSymMatrix66 z = thePredState.perigeeError().weightMatrix(i);
0040 error = i;
0041 return z;
0042
0043 }
0044
0045 AlgebraicSymMatrix66 ParticleKinematicLinearizedTrackState::predictedStateError() const {
0046 if (!jacobiansAvailable)
0047 computeJacobians();
0048 return thePredState.perigeeError().covarianceMatrix();
0049 }
0050
0051
0052
0053
0054 TrackCharge ParticleKinematicLinearizedTrackState::charge() const { return part->initialState().particleCharge(); }
0055
0056 RefCountedKinematicParticle ParticleKinematicLinearizedTrackState::particle() const { return part; }
0057
0058 bool ParticleKinematicLinearizedTrackState::operator==(const LinearizedTrackState<6>& other) const {
0059 const ParticleKinematicLinearizedTrackState* otherP =
0060 dynamic_cast<const ParticleKinematicLinearizedTrackState*>(&other);
0061 if (otherP == nullptr) {
0062 throw VertexException(
0063 " ParticleKinematicLinearizedTrackState:: don't know how to compare myself to non-kinematic track state");
0064 }
0065 return (*(otherP->particle()) == *part);
0066 }
0067
0068 bool ParticleKinematicLinearizedTrackState::hasError() const {
0069 if (!jacobiansAvailable)
0070 computeJacobians();
0071 return thePredState.isValid();
0072 }
0073
0074
0075
0076
0077
0078
0079 void ParticleKinematicLinearizedTrackState::computeJacobians() const {
0080 GlobalPoint paramPt(theLinPoint);
0081 thePredState = builder(part->currentState(), paramPt);
0082
0083
0084
0085 if (std::abs(theCharge) < 1e-5) {
0086
0087 computeNeutralJacobians();
0088 } else {
0089
0090 computeChargedJacobians();
0091 }
0092 jacobiansAvailable = true;
0093 }
0094
0095 ReferenceCountingPointer<LinearizedTrackState<6> >
0096 ParticleKinematicLinearizedTrackState::stateWithNewLinearizationPoint(const GlobalPoint& newLP) const {
0097 RefCountedKinematicParticle pr = part;
0098 return new ParticleKinematicLinearizedTrackState(newLP, pr);
0099 }
0100
0101 ParticleKinematicLinearizedTrackState::RefCountedRefittedTrackState
0102 ParticleKinematicLinearizedTrackState::createRefittedTrackState(const GlobalPoint& vertexPosition,
0103 const AlgebraicVector4& vectorParameters,
0104 const AlgebraicSymMatrix77& covarianceMatrix) const {
0105 KinematicPerigeeConversions conversions;
0106 KinematicState lst = conversions.kinematicState(
0107 vectorParameters, vertexPosition, charge(), covarianceMatrix, part->currentState().magneticField());
0108 RefCountedRefittedTrackState rst =
0109 RefCountedRefittedTrackState(new KinematicRefittedTrackState(lst, vectorParameters));
0110 return rst;
0111 }
0112
0113 AlgebraicVector4 ParticleKinematicLinearizedTrackState::predictedStateMomentumParameters() const {
0114 if (!jacobiansAvailable)
0115 computeJacobians();
0116 AlgebraicVector4 res;
0117 res[0] = thePredState.perigeeParameters().vector()(0);
0118 res[1] = thePredState.perigeeParameters().vector()(1);
0119 res[2] = thePredState.perigeeParameters().vector()(2);
0120 res[3] = thePredState.perigeeParameters().vector()(5);
0121 return res;
0122 }
0123
0124 AlgebraicSymMatrix44 ParticleKinematicLinearizedTrackState::predictedStateMomentumError() const {
0125 int error;
0126 if (!jacobiansAvailable)
0127 computeJacobians();
0128 AlgebraicSymMatrix44 res;
0129 AlgebraicSymMatrix33 m3 = thePredState.perigeeError().weightMatrix(error).Sub<AlgebraicSymMatrix33>(0, 0);
0130 res.Place_at(m3, 0, 0);
0131 res(3, 0) = thePredState.perigeeError().weightMatrix(error)(5, 5);
0132 res(3, 1) = thePredState.perigeeError().weightMatrix(error)(5, 0);
0133 res(3, 2) = thePredState.perigeeError().weightMatrix(error)(5, 1);
0134 res(3, 3) = thePredState.perigeeError().weightMatrix(error)(5, 2);
0135 return res;
0136 }
0137
0138 double ParticleKinematicLinearizedTrackState::weightInMixture() const { return 1.; }
0139
0140 std::vector<ReferenceCountingPointer<LinearizedTrackState<6> > > ParticleKinematicLinearizedTrackState::components()
0141 const {
0142 std::vector<ReferenceCountingPointer<LinearizedTrackState<6> > > res;
0143 res.reserve(1);
0144 res.push_back(RefCountedLinearizedTrackState(const_cast<ParticleKinematicLinearizedTrackState*>(this)));
0145 return res;
0146 }
0147
0148 AlgebraicVector6 ParticleKinematicLinearizedTrackState::refittedParamFromEquation(
0149 const RefCountedRefittedTrackState& theRefittedState) const {
0150 AlgebraicVectorM momentum = theRefittedState->momentumVector();
0151 if ((momentum(2) * predictedStateMomentumParameters()(2) < 0) && (std::fabs(momentum(2)) > M_PI / 2)) {
0152 if (predictedStateMomentumParameters()(2) < 0.)
0153 momentum(2) -= 2 * M_PI;
0154 if (predictedStateMomentumParameters()(2) > 0.)
0155 momentum(2) += 2 * M_PI;
0156 }
0157
0158 AlgebraicVector3 vertexPosition;
0159 vertexPosition(0) = theRefittedState->position().x();
0160 vertexPosition(1) = theRefittedState->position().y();
0161 vertexPosition(2) = theRefittedState->position().z();
0162 AlgebraicVector6 param = constantTerm() + positionJacobian() * vertexPosition + momentumJacobian() * momentum;
0163
0164 if (param(2) > M_PI)
0165 param(2) -= 2 * M_PI;
0166 if (param(2) < -M_PI)
0167 param(2) += 2 * M_PI;
0168
0169 return param;
0170 }
0171
0172 void ParticleKinematicLinearizedTrackState::checkParameters(AlgebraicVector6& parameters) const {
0173 if (parameters(2) > M_PI)
0174 parameters(2) -= 2 * M_PI;
0175 if (parameters(2) < -M_PI)
0176 parameters(2) += 2 * M_PI;
0177 }
0178
0179 void ParticleKinematicLinearizedTrackState::computeChargedJacobians() const {
0180 GlobalPoint paramPt(theLinPoint);
0181
0182 double field = part->currentState().magneticField()->inInverseGeV(thePredState.theState().globalPosition()).z();
0183 double signTC = -part->currentState().particleCharge();
0184
0185 double thetaAtEP = thePredState.theState().globalMomentum().theta();
0186 double phiAtEP = thePredState.theState().globalMomentum().phi();
0187 double ptAtEP = thePredState.theState().globalMomentum().perp();
0188 double transverseCurvatureAtEP = field / ptAtEP * signTC;
0189
0190
0191 if (field * part->currentState().magneticField()->inInverseGeV(part->currentState().globalPosition()).z() < 0.) {
0192 signTC = -signTC;
0193 }
0194
0195 double x_v = thePredState.theState().globalPosition().x();
0196 double y_v = thePredState.theState().globalPosition().y();
0197 double z_v = thePredState.theState().globalPosition().z();
0198 double X = x_v - paramPt.x() - sin(phiAtEP) / transverseCurvatureAtEP;
0199 double Y = y_v - paramPt.y() + cos(phiAtEP) / transverseCurvatureAtEP;
0200 double SS = X * X + Y * Y;
0201 double S = sqrt(SS);
0202
0203
0204 theExpandedParams[0] = transverseCurvatureAtEP;
0205 theExpandedParams[1] = thetaAtEP;
0206 theExpandedParams[3] = 1 / transverseCurvatureAtEP - signTC * S;
0207
0208 theExpandedParams[5] = part->currentState().mass();
0209
0210 double phiFEP;
0211 if (std::abs(X) > std::abs(Y)) {
0212 double signX = (X > 0.0 ? +1.0 : -1.0);
0213 phiFEP = -signTC * signX * acos(signTC * Y / S);
0214 } else {
0215 phiFEP = asin(-signTC * X / S);
0216 if ((signTC * Y) < 0.0)
0217 phiFEP = M_PI - phiFEP;
0218 }
0219 if (phiFEP > M_PI)
0220 phiFEP -= 2 * M_PI;
0221 theExpandedParams[2] = phiFEP;
0222 theExpandedParams[4] =
0223 z_v - paramPt.z() - (phiAtEP - theExpandedParams[2]) / tan(thetaAtEP) / transverseCurvatureAtEP;
0224
0225 thePositionJacobian(2, 0) = -Y / (SS);
0226 thePositionJacobian(2, 1) = X / (SS);
0227 thePositionJacobian(3, 0) = -signTC * X / S;
0228 thePositionJacobian(3, 1) = -signTC * Y / S;
0229 thePositionJacobian(4, 0) = thePositionJacobian(2, 0) / tan(thetaAtEP) / transverseCurvatureAtEP;
0230 thePositionJacobian(4, 1) = thePositionJacobian(2, 1) / tan(thetaAtEP) / transverseCurvatureAtEP;
0231 thePositionJacobian(4, 2) = 1;
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244 theMomentumJacobian(0, 0) = 1;
0245 theMomentumJacobian(1, 1) = 1;
0246
0247 theMomentumJacobian(2, 0) =
0248 -(X * cos(phiAtEP) + Y * sin(phiAtEP)) / (SS * transverseCurvatureAtEP * transverseCurvatureAtEP);
0249
0250 theMomentumJacobian(2, 2) = (Y * cos(phiAtEP) - X * sin(phiAtEP)) / (SS * transverseCurvatureAtEP);
0251
0252 theMomentumJacobian(3, 0) =
0253 (signTC * (Y * cos(phiAtEP) - X * sin(phiAtEP)) / S - 1) / (transverseCurvatureAtEP * transverseCurvatureAtEP);
0254
0255 theMomentumJacobian(3, 2) = signTC * (X * cos(phiAtEP) + Y * sin(phiAtEP)) / (S * transverseCurvatureAtEP);
0256
0257 theMomentumJacobian(4, 0) =
0258 (phiAtEP - theExpandedParams(2)) / tan(thetaAtEP) / (transverseCurvatureAtEP * transverseCurvatureAtEP) +
0259 theMomentumJacobian(2, 0) / tan(thetaAtEP) / transverseCurvatureAtEP;
0260
0261 theMomentumJacobian(4, 1) =
0262 (phiAtEP - theExpandedParams(2)) * (1 + 1 / (tan(thetaAtEP) * tan(thetaAtEP))) / transverseCurvatureAtEP;
0263
0264 theMomentumJacobian(4, 2) = (theMomentumJacobian(2, 2) - 1) / tan(thetaAtEP) / transverseCurvatureAtEP;
0265
0266 theMomentumJacobian(5, 3) = 1;
0267
0268
0269 AlgebraicVector3 expansionPoint;
0270 expansionPoint[0] = thePredState.theState().globalPosition().x();
0271 expansionPoint[1] = thePredState.theState().globalPosition().y();
0272 expansionPoint[2] = thePredState.theState().globalPosition().z();
0273 AlgebraicVector4 momentumAtExpansionPoint;
0274 momentumAtExpansionPoint[0] = transverseCurvatureAtEP;
0275 momentumAtExpansionPoint[1] = thetaAtEP;
0276 momentumAtExpansionPoint[2] = phiAtEP;
0277 momentumAtExpansionPoint[3] = theExpandedParams[5];
0278
0279 theConstantTerm = AlgebraicVector6(theExpandedParams - thePositionJacobian * expansionPoint -
0280 theMomentumJacobian * momentumAtExpansionPoint);
0281 }
0282
0283 void ParticleKinematicLinearizedTrackState::computeNeutralJacobians() const {
0284 GlobalPoint paramPt(theLinPoint);
0285 double thetaAtEP = thePredState.theState().globalMomentum().theta();
0286 double phiAtEP = thePredState.theState().globalMomentum().phi();
0287 double ptAtEP = thePredState.theState().globalMomentum().perp();
0288
0289 double x_v = thePredState.theState().globalPosition().x();
0290 double y_v = thePredState.theState().globalPosition().y();
0291 double z_v = thePredState.theState().globalPosition().z();
0292 double X = x_v - paramPt.x();
0293 double Y = y_v - paramPt.y();
0294
0295
0296 theExpandedParams[0] = 1 / ptAtEP;
0297 theExpandedParams[1] = thetaAtEP;
0298 theExpandedParams[2] = phiAtEP;
0299 theExpandedParams[3] = X * sin(phiAtEP) - Y * cos(phiAtEP);
0300 theExpandedParams[4] = z_v - paramPt.z() - (X * cos(phiAtEP) + Y * sin(phiAtEP)) / tan(thetaAtEP);
0301 theExpandedParams[5] = part->currentState().mass();
0302
0303
0304
0305
0306
0307 thePositionJacobian(3, 0) = sin(phiAtEP);
0308 thePositionJacobian(3, 1) = -cos(phiAtEP);
0309 thePositionJacobian(4, 0) = -cos(phiAtEP) / tan(thetaAtEP);
0310 thePositionJacobian(4, 1) = -sin(phiAtEP) / tan(thetaAtEP);
0311 thePositionJacobian(4, 2) = 1;
0312
0313
0314
0315
0316 theMomentumJacobian(0, 0) = 1;
0317 theMomentumJacobian(1, 1) = 1;
0318 theMomentumJacobian(2, 2) = 1;
0319
0320 theMomentumJacobian(3, 2) = X * cos(phiAtEP) + Y * sin(phiAtEP);
0321 theMomentumJacobian(4, 1) = theMomentumJacobian(3, 2) * (1 + 1 / (tan(thetaAtEP) * tan(thetaAtEP)));
0322
0323 theMomentumJacobian(4, 2) = (X * sin(phiAtEP) - Y * cos(phiAtEP)) / tan(thetaAtEP);
0324 theMomentumJacobian(5, 3) = 1;
0325
0326
0327 AlgebraicVector3 expansionPoint;
0328 expansionPoint[0] = thePredState.theState().globalPosition().x();
0329 expansionPoint[1] = thePredState.theState().globalPosition().y();
0330 expansionPoint[2] = thePredState.theState().globalPosition().z();
0331 AlgebraicVector4 momentumAtExpansionPoint;
0332 momentumAtExpansionPoint[0] = 1 / ptAtEP;
0333 momentumAtExpansionPoint[1] = thetaAtEP;
0334 momentumAtExpansionPoint[2] = phiAtEP;
0335 momentumAtExpansionPoint[3] = theExpandedParams[5];
0336
0337 theConstantTerm = AlgebraicVector6(theExpandedParams - thePositionJacobian * expansionPoint -
0338 theMomentumJacobian * momentumAtExpansionPoint);
0339 }
0340
0341 reco::TransientTrack ParticleKinematicLinearizedTrackState::track() const {
0342 throw VertexException(" ParticleKinematicLinearizedTrackState:: no TransientTrack to return");
0343 }