Go to the documentation of this file.00001 #include "RecoVertex/VertexTools/interface/PerigeeLinearizedTrackState.h"
00002 #include "RecoVertex/VertexTools/interface/PerigeeRefittedTrackState.h"
00003 #include "TrackingTools/TrajectoryState/interface/PerigeeConversions.h"
00004 #include "RecoVertex/VertexPrimitives/interface/VertexException.h"
00005 #include "MagneticField/Engine/interface/MagneticField.h"
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007
00008
00009
00010
00014 const AlgebraicVector5 & PerigeeLinearizedTrackState::constantTerm() const
00015 {
00016 if (!jacobiansAvailable) computeJacobians();
00017 return theConstantTerm;
00018 }
00019
00023 const AlgebraicMatrix53 & PerigeeLinearizedTrackState::positionJacobian() const
00024 {
00025 if (!jacobiansAvailable) computeJacobians();
00026 return thePositionJacobian;
00027 }
00028
00032 const AlgebraicMatrix53 & PerigeeLinearizedTrackState::momentumJacobian() const
00033 {
00034 if (!jacobiansAvailable) computeJacobians();
00035 return theMomentumJacobian;
00036 }
00037
00040 const AlgebraicVector5 & PerigeeLinearizedTrackState::parametersFromExpansion() const
00041 {
00042 if (!jacobiansAvailable) computeJacobians();
00043 return theExpandedParams;
00044 }
00045
00050 const TrajectoryStateClosestToPoint & PerigeeLinearizedTrackState::predictedState() const
00051 {
00052 if (!jacobiansAvailable) computeJacobians();
00053 return thePredState;
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 void PerigeeLinearizedTrackState::computeJacobians() const
00065 {
00066 GlobalPoint paramPt(theLinPoint);
00067
00068
00069
00070
00071
00072 thePredState = builder(theTSOS, paramPt);
00073 if (!thePredState.isValid())
00074 return;
00075
00076
00077
00078 double field = theTrack.field()->inInverseGeV(thePredState.theState().position()).z();
00079
00080 if ((std::abs(theCharge)<1e-5)||(fabs(field)<1.e-10)){
00081
00082 computeNeutralJacobians();
00083 } else {
00084
00085
00086
00087 computeChargedJacobians();
00088
00089
00090 }
00091
00092
00093
00094
00095 jacobiansAvailable = true;
00096 }
00097
00098
00099
00100
00101
00102
00103
00104 bool PerigeeLinearizedTrackState::hasError() const
00105 {
00106 if (!jacobiansAvailable) computeJacobians();
00107 return thePredState.hasError();
00108 }
00109
00110 AlgebraicVector5 PerigeeLinearizedTrackState::predictedStateParameters() const
00111 {
00112 if (!jacobiansAvailable) computeJacobians();
00113 return thePredState.perigeeParameters().vector();
00114 }
00115
00116 AlgebraicVector3 PerigeeLinearizedTrackState::predictedStateMomentumParameters() const
00117 {
00118 if (!jacobiansAvailable) computeJacobians();
00119 AlgebraicVector3 momentum;
00120 momentum[0] = thePredState.perigeeParameters().vector()(0);
00121 momentum[1] = thePredState.perigeeParameters().theta();
00122 momentum[2] = thePredState.perigeeParameters().phi();
00123 return momentum;
00124 }
00125
00126 AlgebraicSymMatrix55 PerigeeLinearizedTrackState::predictedStateWeight(int & error) const
00127 {
00128 if (!jacobiansAvailable) computeJacobians();
00129 if (!thePredState.isValid()) {
00130 error = 1;
00131 return AlgebraicSymMatrix55();
00132 }
00133 return thePredState.perigeeError().weightMatrix(error);
00134 }
00135
00136 AlgebraicSymMatrix55 PerigeeLinearizedTrackState::predictedStateError() const
00137 {
00138 if (!jacobiansAvailable) computeJacobians();
00139 return thePredState.perigeeError().covarianceMatrix();
00140 }
00141
00142 AlgebraicSymMatrix33 PerigeeLinearizedTrackState::predictedStateMomentumError() const
00143 {
00144 if (!jacobiansAvailable) computeJacobians();
00145 return thePredState.perigeeError().covarianceMatrix().Sub<AlgebraicSymMatrix33>(0,2);
00146 }
00147
00148 bool PerigeeLinearizedTrackState::operator ==(LinearizedTrackState<5> & other)const
00149 {
00150 const PerigeeLinearizedTrackState* otherP =
00151 dynamic_cast<const PerigeeLinearizedTrackState*>(&other);
00152 if (otherP == 0) {
00153 throw VertexException("PerigeeLinearizedTrackState: don't know how to compare myself to non-perigee track state");
00154 }
00155 return (otherP->track() == theTrack);
00156 }
00157
00158
00159 bool PerigeeLinearizedTrackState::operator ==(ReferenceCountingPointer<LinearizedTrackState<5> >& other)const
00160 {
00161 const PerigeeLinearizedTrackState* otherP =
00162 dynamic_cast<const PerigeeLinearizedTrackState*>(other.get());
00163 if (otherP == 0) {
00164 throw VertexException("PerigeeLinearizedTrackState: don't know how to compare myself to non-perigee track state");
00165 }
00166 return (otherP->track() == theTrack);
00167 }
00168
00169
00170 PerigeeLinearizedTrackState::RefCountedLinearizedTrackState
00171 PerigeeLinearizedTrackState::stateWithNewLinearizationPoint
00172 (const GlobalPoint & newLP) const
00173 {
00174 return RefCountedLinearizedTrackState(
00175 new PerigeeLinearizedTrackState(newLP, track(), theTSOS));
00176 }
00177
00178 PerigeeLinearizedTrackState::RefCountedRefittedTrackState
00179 PerigeeLinearizedTrackState::createRefittedTrackState(
00180 const GlobalPoint & vertexPosition,
00181 const AlgebraicVector3 & vectorParameters,
00182 const AlgebraicSymMatrix66 & covarianceMatrix) const
00183 {
00184 PerigeeConversions perigeeConversions;
00185 TrajectoryStateClosestToPoint refittedTSCP =
00186 perigeeConversions.trajectoryStateClosestToPoint(
00187 vectorParameters, vertexPosition, charge(), covarianceMatrix, theTrack.field());
00188 return RefCountedRefittedTrackState(new PerigeeRefittedTrackState(refittedTSCP, vectorParameters));
00189 }
00190
00191 std::vector< PerigeeLinearizedTrackState::RefCountedLinearizedTrackState >
00192 PerigeeLinearizedTrackState::components() const
00193 {
00194 std::vector<RefCountedLinearizedTrackState> result; result.reserve(1);
00195 result.push_back(RefCountedLinearizedTrackState(
00196 const_cast<PerigeeLinearizedTrackState*>(this)));
00197 return result;
00198 }
00199
00200
00201 AlgebraicVector5 PerigeeLinearizedTrackState::refittedParamFromEquation(
00202 const RefCountedRefittedTrackState & theRefittedState) const
00203 {
00204 AlgebraicVector3 vertexPosition;
00205 vertexPosition(0) = theRefittedState->position().x();
00206 vertexPosition(1) = theRefittedState->position().y();
00207 vertexPosition(2) = theRefittedState->position().z();
00208 AlgebraicVector3 momentum = theRefittedState->momentumVector();
00209 if ((momentum(2)*predictedStateMomentumParameters()(2) < 0)&&(fabs(momentum(2))>M_PI/2) ) {
00210 if (predictedStateMomentumParameters()(2) < 0.) momentum(2)-= 2*M_PI;
00211 if (predictedStateMomentumParameters()(2) > 0.) momentum(2)+= 2*M_PI;
00212 }
00213 AlgebraicVectorN param = constantTerm() +
00214 positionJacobian() * vertexPosition +
00215 momentumJacobian() * momentum;
00216 if (param(2) > M_PI) param(2)-= 2*M_PI;
00217 if (param(2) < -M_PI) param(2)+= 2*M_PI;
00218
00219 return param;
00220 }
00221
00222
00223 void PerigeeLinearizedTrackState::checkParameters(AlgebraicVector5 & parameters) const
00224 {
00225 if (parameters(2) > M_PI) parameters(2)-= 2*M_PI;
00226 if (parameters(2) < -M_PI) parameters(2)+= 2*M_PI;
00227 }
00228
00229 void PerigeeLinearizedTrackState::computeChargedJacobians() const
00230 {
00231 GlobalPoint paramPt(theLinPoint);
00232
00233 double field = theTrack.field()->inInverseGeV(thePredState.theState().position()).z();
00234 double signTC = -theCharge;
00235
00236 double thetaAtEP = thePredState.theState().momentum().theta();
00237 double phiAtEP = thePredState.theState().momentum().phi();
00238 double ptAtEP = thePredState.theState().momentum().perp();
00239 double transverseCurvatureAtEP = field / ptAtEP*signTC;
00240
00241 double x_v = thePredState.theState().position().x();
00242 double y_v = thePredState.theState().position().y();
00243 double z_v = thePredState.theState().position().z();
00244 double X = x_v - paramPt.x() - sin(phiAtEP) / transverseCurvatureAtEP;
00245 double Y = y_v - paramPt.y() + cos(phiAtEP) / transverseCurvatureAtEP;
00246 double SS = X*X + Y*Y;
00247 double S = sqrt(SS);
00248
00249
00250
00251 theExpandedParams[0] = transverseCurvatureAtEP;
00252 theExpandedParams[1] = thetaAtEP;
00253 theExpandedParams[3] = 1/transverseCurvatureAtEP - signTC * S;
00254 double phiFEP;
00255 if (std::abs(X)>std::abs(Y)) {
00256 double signX = (X>0.0? +1.0:-1.0);
00257 phiFEP = -signTC * signX*acos(signTC*Y/S);
00258 } else {
00259 phiFEP = asin(-signTC*X/S);
00260 if ((signTC*Y)<0.0)
00261 phiFEP = M_PI - phiFEP;
00262 }
00263 if (phiFEP>M_PI) phiFEP-= 2*M_PI;
00264 theExpandedParams[2] = phiFEP;
00265 theExpandedParams[4] = z_v - paramPt.z() -
00266 (phiAtEP - theExpandedParams[2]) / tan(thetaAtEP)/transverseCurvatureAtEP;
00267
00268
00269
00270
00271
00272
00273 thePositionJacobian(2,0) = - Y / (SS);
00274 thePositionJacobian(2,1) = X / (SS);
00275 thePositionJacobian(3,0) = - signTC * X / S;
00276 thePositionJacobian(3,1) = - signTC * Y / S;
00277 thePositionJacobian(4,0) = thePositionJacobian(2,0)/tan(thetaAtEP)/transverseCurvatureAtEP;
00278 thePositionJacobian(4,1) = thePositionJacobian(2,1)/tan(thetaAtEP)/transverseCurvatureAtEP;
00279 thePositionJacobian(4,2) = 1;
00280
00281
00282
00283
00284 theMomentumJacobian(0,0) = 1;
00285 theMomentumJacobian(1,1) = 1;
00286
00287 theMomentumJacobian(2,0) = -
00288 (X*cos(phiAtEP) + Y*sin(phiAtEP))/
00289 (SS*transverseCurvatureAtEP*transverseCurvatureAtEP);
00290
00291 theMomentumJacobian(2,2) = (Y*cos(phiAtEP) - X*sin(phiAtEP)) /
00292 (SS*transverseCurvatureAtEP);
00293
00294 theMomentumJacobian(3,0) =
00295 (signTC * (Y*cos(phiAtEP) - X*sin(phiAtEP)) / S - 1)/
00296 (transverseCurvatureAtEP*transverseCurvatureAtEP);
00297
00298 theMomentumJacobian(3,2) = signTC *(X*cos(phiAtEP) + Y*sin(phiAtEP))/
00299 (S*transverseCurvatureAtEP);
00300
00301 theMomentumJacobian(4,0) = (phiAtEP - theExpandedParams[2]) /
00302 tan(thetaAtEP)/(transverseCurvatureAtEP*transverseCurvatureAtEP)+
00303 theMomentumJacobian(2,0) / tan(thetaAtEP)/transverseCurvatureAtEP;
00304
00305 theMomentumJacobian(4,1) = (phiAtEP - theExpandedParams[2]) *
00306 (1 + 1/(tan(thetaAtEP)*tan(thetaAtEP)))/transverseCurvatureAtEP;
00307
00308 theMomentumJacobian(4,2) = (theMomentumJacobian(2,2) - 1) /
00309 tan(thetaAtEP)/transverseCurvatureAtEP;
00310
00311
00312
00313 AlgebraicVector3 expansionPoint;
00314 expansionPoint(0) = thePredState.theState().position().x();
00315 expansionPoint(1) = thePredState.theState().position().y();
00316 expansionPoint(2) = thePredState.theState().position().z();
00317 AlgebraicVector3 momentumAtExpansionPoint;
00318 momentumAtExpansionPoint(0) = transverseCurvatureAtEP;
00319 momentumAtExpansionPoint(1) = thetaAtEP;
00320 momentumAtExpansionPoint(2) = phiAtEP;
00321
00322 theConstantTerm = AlgebraicVector5( theExpandedParams -
00323 thePositionJacobian * expansionPoint -
00324 theMomentumJacobian * momentumAtExpansionPoint );
00325
00326 }
00327
00328
00329
00330
00331
00332 void PerigeeLinearizedTrackState::computeNeutralJacobians() const
00333 {
00334 GlobalPoint paramPt(theLinPoint);
00335
00336
00337 double thetaAtEP = thePredState.theState().momentum().theta();
00338 double phiAtEP = thePredState.theState().momentum().phi();
00339 double ptAtEP = thePredState.theState().momentum().perp();
00340
00341 double x_v = thePredState.theState().position().x();
00342 double y_v = thePredState.theState().position().y();
00343 double z_v = thePredState.theState().position().z();
00344 double X = x_v - paramPt.x();
00345 double Y = y_v - paramPt.y();
00346
00347
00348
00349 theExpandedParams(0) = 1 / ptAtEP;
00350 theExpandedParams(1) = thetaAtEP;
00351 theExpandedParams(2) = phiAtEP;
00352 theExpandedParams(3) = X*sin(phiAtEP) - Y*cos(phiAtEP);
00353 theExpandedParams(4) = z_v - paramPt.z() -
00354 (X*cos(phiAtEP) + Y*sin(phiAtEP)) / tan(thetaAtEP);
00355
00356
00357
00358
00359
00360
00361 thePositionJacobian(3,0) = sin(phiAtEP);
00362 thePositionJacobian(3,1) = - cos(phiAtEP);
00363 thePositionJacobian(4,0) = - cos(phiAtEP)/tan(thetaAtEP);
00364 thePositionJacobian(4,1) = - sin(phiAtEP)/tan(thetaAtEP);
00365 thePositionJacobian(4,2) = 1;
00366
00367
00368
00369
00370
00371 theMomentumJacobian(0,0) = 1;
00372 theMomentumJacobian(1,1) = 1;
00373 theMomentumJacobian(2,2) = 1;
00374
00375 theMomentumJacobian(3,2) = X*cos(phiAtEP) + Y*sin(phiAtEP);
00376
00377 theMomentumJacobian(4,1) = theMomentumJacobian(3,2)*
00378 (1 + 1/(tan(thetaAtEP)*tan(thetaAtEP)));
00379
00380 theMomentumJacobian(4,2) = (X*sin(phiAtEP) - Y*cos(phiAtEP))/tan(thetaAtEP);
00381
00382
00383
00384 AlgebraicVector3 expansionPoint;
00385 expansionPoint(0) = thePredState.theState().position().x();
00386 expansionPoint(1) = thePredState.theState().position().y();
00387 expansionPoint(2) = thePredState.theState().position().z();
00388 AlgebraicVector3 momentumAtExpansionPoint;
00389 momentumAtExpansionPoint(0) = 1 / ptAtEP;
00390 momentumAtExpansionPoint(1) = thetaAtEP;
00391 momentumAtExpansionPoint(2) = phiAtEP;
00392
00393 theConstantTerm = AlgebraicVector5( theExpandedParams -
00394 thePositionJacobian * expansionPoint -
00395 theMomentumJacobian * momentumAtExpansionPoint );
00396
00397 }
00398
00399 bool PerigeeLinearizedTrackState::isValid() const
00400 {
00401 if (!theTSOS.isValid())
00402 return false;
00403
00404 if (!jacobiansAvailable)
00405 computeJacobians();
00406
00407 return jacobiansAvailable;
00408 }