CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_4/src/RecoVertex/GhostTrackFitter/src/KalmanGhostTrackUpdater.cc

Go to the documentation of this file.
00001 #include <vector>
00002 #include <cmath>
00003 
00004 #include <Math/SVector.h>
00005 #include <Math/SMatrix.h>
00006 #include <Math/MatrixFunctions.h>
00007 
00008 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00009 #include "DataFormats/GeometryVector/interface/GlobalVector.h" 
00010 #include "DataFormats/GeometryCommonDetAlgo/interface/GlobalError.h"
00011 
00012 #include "RecoVertex/GhostTrackFitter/interface/GhostTrackPrediction.h"
00013 #include "RecoVertex/GhostTrackFitter/interface/GhostTrackState.h"
00014 
00015 #include "RecoVertex/GhostTrackFitter/interface/KalmanGhostTrackUpdater.h"
00016 
00017 using namespace reco;
00018 
00019 namespace {
00020         static inline double sqr(double arg) { return arg * arg; }
00021 
00022         using namespace ROOT::Math;
00023 
00024         typedef SVector<double, 4> Vector4;
00025         typedef SVector<double, 2> Vector2;
00026 
00027         typedef SMatrix<double, 4, 4, MatRepSym<double, 4> > Matrix4S;
00028         typedef SMatrix<double, 3, 3, MatRepSym<double, 3> > Matrix3S;
00029         typedef SMatrix<double, 2, 2, MatRepSym<double, 2> > Matrix2S;
00030         typedef SMatrix<double, 4, 4> Matrix44;
00031         typedef SMatrix<double, 4, 2> Matrix42;
00032         typedef SMatrix<double, 2, 4> Matrix24;
00033         typedef SMatrix<double, 2, 3> Matrix23;
00034         typedef SMatrix<double, 2, 2> Matrix22;
00035 
00036         struct KalmanState {
00037                 KalmanState(const GhostTrackPrediction &pred,
00038                             const GhostTrackState &state);
00039 
00040                 Vector2         residual;
00041                 Matrix2S        measErr, measPredErr;
00042                 Matrix24        h;
00043         };
00044 }
00045 
00046 KalmanState::KalmanState(const GhostTrackPrediction &pred,
00047                          const GhostTrackState &state)
00048 {
00049         using namespace ROOT::Math;
00050 
00051         GlobalPoint point = state.globalPosition();
00052 
00053         // precomputed values
00054         double x = std::cos(pred.phi());
00055         double y = std::sin(pred.phi());
00056         double dz = pred.cotTheta();
00057         double lip = x * point.x() + y * point.y();
00058         double tip = x * point.y() - y * point.x();
00059 
00060         // jacobian of global -> local
00061         Matrix23 measToLocal;
00062         measToLocal(0, 0) = - dz * x;
00063         measToLocal(0, 1) = - dz * y;
00064         measToLocal(0, 2) = 1.;
00065         measToLocal(1, 0) = y;
00066         measToLocal(1, 1) = -x;
00067 
00068         // measurement error on the 2d plane projection
00069         measErr = Similarity(measToLocal, state.cartesianCovariance());
00070 
00071         // jacobian of representation to measurement transformation
00072         h(0, 0) = 1.;
00073         h(0, 2) = lip;
00074         h(0, 3) = dz * tip;
00075         h(1, 1) = -1.;
00076         h(1, 3) = -lip;
00077 
00078         // error on prediction
00079         measPredErr = Similarity(h, pred.covariance());
00080 
00081         // residual
00082         residual[0] = point.z() - pred.z() - dz * lip;
00083         residual[1] = pred.ip() - tip;
00084 }
00085 
00086 GhostTrackPrediction KalmanGhostTrackUpdater::update(
00087                                         const GhostTrackPrediction &pred,
00088                                         const GhostTrackState &state,
00089                                         double &ndof, double &chi2) const
00090 {
00091         using namespace ROOT::Math;
00092 
00093         KalmanState kalmanState(pred, state);
00094 
00095         if (state.weight() < 1.0e-3)
00096                 return pred;
00097 
00098         // inverted combined error
00099         Matrix2S invErr = kalmanState.measPredErr +
00100                           (1.0 / state.weight()) * kalmanState.measErr;
00101         if (!invErr.Invert())
00102                 return pred;
00103 
00104         // gain
00105         Matrix42 gain = pred.covariance() * Transpose(kalmanState.h) * invErr;
00106 
00107         // new prediction
00108         Vector4 newPred = pred.prediction() + (gain * kalmanState.residual);
00109         Matrix44 tmp44 = SMatrixIdentity();
00110         tmp44 = (tmp44 - gain * kalmanState.h) * pred.covariance();
00111         Matrix4S newError(tmp44.LowerBlock());
00112 
00113         // filtered residuals
00114         Matrix22 tmp22 = SMatrixIdentity();
00115         tmp22 = tmp22 - kalmanState.h * gain;
00116         Vector2 filtRes = tmp22 * kalmanState.residual;
00117         tmp22 *= kalmanState.measErr;
00118         Matrix2S filtResErr(tmp22.LowerBlock());
00119         if (!filtResErr.Invert())
00120                 return pred;
00121 
00122         ndof += state.weight() * 2.;
00123         chi2 += state.weight() * Similarity(filtRes, filtResErr);
00124 
00125         return GhostTrackPrediction(newPred, newError);
00126 }
00127 
00128 void KalmanGhostTrackUpdater::contribution(
00129                                 const GhostTrackPrediction &pred,
00130                                 const GhostTrackState &state,
00131                                 double &ndof, double &chi2,
00132                                 bool withPredError) const
00133 {
00134         using namespace ROOT::Math;
00135 
00136         KalmanState kalmanState(pred, state);
00137 
00138         // this is called on the full predicted state,
00139         // so the residual is already with respect to the filtered state
00140 
00141         // inverted error
00142         Matrix2S invErr = kalmanState.measErr;
00143         if (withPredError)
00144                 invErr += kalmanState.measPredErr;
00145         if (!invErr.Invert()) {
00146                 ndof = 0.;
00147                 chi2 = 0.;
00148         }
00149 
00150         ndof = 2.;
00151         chi2 = Similarity(kalmanState.residual, invErr);
00152 }