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
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
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
00069 measErr = Similarity(measToLocal, state.cartesianCovariance());
00070
00071
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
00079 measPredErr = Similarity(h, pred.covariance());
00080
00081
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
00099 Matrix2S invErr = kalmanState.measPredErr +
00100 (1.0 / state.weight()) * kalmanState.measErr;
00101 if (!invErr.Invert())
00102 return pred;
00103
00104
00105 Matrix42 gain = pred.covariance() * Transpose(kalmanState.h) * invErr;
00106
00107
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
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
00139
00140
00141
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 }