CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/RecoVertex/VertexTools/src/PerigeeLinearizedTrackState.cc

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 // #include "CommonReco/PatternTools/interface/TransverseImpactPointExtrapolator.h"
00009 // #include "CommonDet/DetUtilities/interface/FastTimeMe.h"
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 // /** Method returning the impact point measurement     
00057 //  */      
00058 // ImpactPointMeasurement  PerigeeLinearizedTrackState::impactPointMeasurement() const 
00059 // {
00060 //   if (!impactPointAvailable) compute3DImpactPoint(); 
00061 //     return the3DImpactPoint;
00062 // }
00063 // 
00064 void PerigeeLinearizedTrackState::computeJacobians() const
00065 {
00066   GlobalPoint paramPt(theLinPoint);
00067 
00068 //   std::cout << "Track "
00069 //   << "\n Param    " << theTSOS.globalParameters ()
00070 //   << "\n Dir      " << theTSOS.globalDirection ()
00071 //    << "\n";
00072   thePredState = builder(theTSOS, paramPt); 
00073   if (!thePredState.isValid())
00074     return;
00075 //   std::cout << "thePredState " << thePredState.theState().position()<<std::endl;
00076 //   edm::LogInfo("RecoVertex/PerigeeLTS") 
00077 //     << "predstate built" << "\n";
00078   double field =  theTrack.field()->inInverseGeV(thePredState.theState().position()).z();
00079 
00080   if ((std::abs(theCharge)<1e-5)||(fabs(field)<1.e-10)){
00081     //neutral track
00082     computeNeutralJacobians();
00083   } else {
00084     //charged track
00085 //     edm::LogInfo("RecoVertex/PerigeeLTS") 
00086 //       << "about to compute charged jac" << "\n";
00087     computeChargedJacobians();
00088 //     edm::LogInfo("RecoVertex/PerigeeLTS") 
00089 //       << "charged jac computed" << "\n";
00090   }
00091 
00092 
00093 
00094 
00095   jacobiansAvailable = true;
00096 }
00097 
00098 // void PerigeeLinearizedTrackState::compute3DImpactPoint() const 
00099 // {
00100 //   the3DImpactPoint = theIPMExtractor.impactPointMeasurement(theTrack, theLinPoint);
00101 //   impactPointAvailable = true;
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   //tarjectory parameters
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   // The track parameters at the expansion point
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   // The Jacobian: (all at the expansion point)
00269   // [i,j]
00270   // i = 0: rho , 1: theta, 2: phi_p, 3: epsilon, 4: z_p
00271   // j = 0: x_v, 1: y_v, 2: z_v
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   // [i,j]
00282   // i = 0: rho , 1: theta, 2: phi_p, 3: epsilon, 4: z_p
00283   // j = 0: rho, 1: theta, 2: phi_v
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    // And finally the residuals:
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;  // Transverse Curv
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   //tarjectory parameters
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   // The track parameters at the expansion point
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   // The Jacobian: (all at the expansion point)
00357   // [i,j]
00358   // i = 0: rho = 1/pt , 1: theta, 2: phi_p, 3: epsilon, 4: z_p
00359   // j = 0: x_v, 1: y_v, 2: z_v
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   // [i,j]
00368   // i = 0: rho = 1/pt , 1: theta, 2: phi_p, 3: epsilon, 4: z_p
00369   // j = 0: rho = 1/pt , 1: theta, 2: phi_v
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    // And finally the residuals:
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 }