00001 #include "RecoVertex/KalmanVertexFit/interface/KalmanVertexUpdator.h"
00002 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
00003 #include "DataFormats/CLHEP/interface/AlgebraicObjects.h"
00004 #include "RecoVertex/VertexPrimitives/interface/VertexException.h"
00005 #include "DataFormats/GeometrySurface/interface/ReferenceCounted.h"
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007 #include "DataFormats/Math/interface/invertPosDefMatrix.h"
00008
00009 #include <algorithm>
00010
00011
00012 template <unsigned int N>
00013 CachingVertex<N> KalmanVertexUpdator<N>::update(const CachingVertex<N> & oldVertex,
00014 const RefCountedVertexTrack track, float weight, int sign) const
00015 {
00016 if(abs(sign) != 1) throw VertexException
00017 ("KalmanVertexUpdator::abs(sign) not equal to 1");
00018
00019 VertexState newVertexState = positionUpdate(oldVertex.vertexState(),
00020 track->linearizedTrack(), weight, sign);
00021 if (!newVertexState.isValid()) return CachingVertex<N>();
00022
00023 float chi1 = oldVertex.totalChiSquared();
00024 std::pair <bool, double> chi2P = chi2Increment(oldVertex.vertexState(), newVertexState,
00025 track->linearizedTrack() , weight );
00026 if (!chi2P.first) return CachingVertex<N>();
00027
00028 chi1 +=sign * chi2P.second;
00029
00030
00031 std::vector<RefCountedVertexTrack> newVertexTracks = oldVertex.tracks();
00032
00033 if (sign > 0) {
00034 newVertexTracks.push_back(track);
00035 }else{
00036
00037 typename std::vector<RefCountedVertexTrack>::iterator pos
00038 = find(newVertexTracks.begin(), newVertexTracks.end(), track);
00039 if (pos != newVertexTracks.end()) {
00040 newVertexTracks.erase(pos);
00041 } else {
00042 std::cout<<"KalmanVertexUpdator::Unable to find requested track in the current vertex"<<std::endl;
00043 throw VertexException("KalmanVertexUpdator::Unable to find requested track in the current vertex");
00044 }
00045 }
00046
00047 if (oldVertex.hasPrior()) {
00048 return CachingVertex<N>( oldVertex.priorVertexState(),
00049 newVertexState, newVertexTracks, chi1);
00050 } else {
00051 return CachingVertex<N>(newVertexState, newVertexTracks, chi1);
00052 }
00053 }
00054
00055
00056 template <unsigned int N>
00057 CachingVertex<N> KalmanVertexUpdator<N>::add(const CachingVertex<N> & oldVertex,
00058 const RefCountedVertexTrack track) const
00059 {
00060 float weight = track->weight();
00061 return update(oldVertex,track,weight,+1);
00062 }
00063
00064 template <unsigned int N>
00065 CachingVertex<N> KalmanVertexUpdator<N>::remove(const CachingVertex<N> & oldVertex,
00066 const RefCountedVertexTrack track) const
00067 {
00068 float weight = track->weight();
00069 return update(oldVertex,track,weight,-1);
00070 }
00071
00072
00073 template <unsigned int N>
00074 VertexState
00075 KalmanVertexUpdator<N>::positionUpdate (const VertexState & oldVertex,
00076 const RefCountedLinearizedTrackState linearizedTrack,
00077 const float weight, int sign) const
00078 {
00079 int error;
00080
00081 if (!linearizedTrack->isValid())
00082 return VertexState();
00083
00084 const AlgebraicMatrixN3 & a = linearizedTrack->positionJacobian();
00085 const AlgebraicMatrixNM & b = linearizedTrack->momentumJacobian();
00086
00087
00088
00089
00090 AlgebraicSymMatrixNN trackParametersWeight =
00091 linearizedTrack->predictedStateWeight(error);
00092 if(error != 0) {
00093 edm::LogWarning("KalmanVertexUpdator") << "predictedState error matrix inversion failed. An invalid vertex will be returned.";
00094 return VertexState();
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104 AlgebraicSymMatrixMM s = ROOT::Math::SimilarityT(b,trackParametersWeight);
00105 if (!invertPosDefMatrix(s)) {
00106 edm::LogWarning("KalmanVertexUpdator") << "S matrix inversion failed. An invalid vertex will be returned.";
00107 return VertexState();
00108 }
00109
00110 AlgebraicSymMatrixNN gB = trackParametersWeight -
00111 ROOT::Math::Similarity(trackParametersWeight, ROOT::Math::Similarity(b,s));
00112
00113
00114
00115 AlgebraicSymMatrix33 newVertexWeight = oldVertex.weight().matrix_new()
00116 + (weight * sign) * ROOT::Math::SimilarityT(a,gB);
00117
00118
00119
00120
00121 AlgebraicVector3 newSwr = oldVertex.weightTimesPosition()
00122 + (weight * sign) * ( (ROOT::Math::Transpose(a) * gB) *
00123 ( linearizedTrack->predictedStateParameters() - linearizedTrack->constantTerm()) );
00124
00125
00126
00127 VertexState newpos (newSwr, GlobalWeight(newVertexWeight), 1.0);
00128
00129
00130
00131
00132 return newpos;
00133 }
00134
00135
00136 template <unsigned int N>
00137 std::pair <bool, double> KalmanVertexUpdator<N>::chi2Increment(const VertexState & oldVertex,
00138 const VertexState & newVertexState,
00139 const RefCountedLinearizedTrackState linearizedTrack,
00140 float weight) const
00141 {
00142 int error;
00143 GlobalPoint newVertexPosition = newVertexState.position();
00144
00145 if (!linearizedTrack->isValid())
00146 return std::pair <bool, double> ( false, -1. );
00147
00148 AlgebraicVector3 newVertexPositionV;
00149 newVertexPositionV(0) = newVertexPosition.x();
00150 newVertexPositionV(1) = newVertexPosition.y();
00151 newVertexPositionV(2) = newVertexPosition.z();
00152
00153 const AlgebraicMatrixN3 & a = linearizedTrack->positionJacobian();
00154 const AlgebraicMatrixNM & b = linearizedTrack->momentumJacobian();
00155
00156 AlgebraicVectorN trackParameters =
00157 linearizedTrack->predictedStateParameters();
00158
00159 AlgebraicSymMatrixNN trackParametersWeight =
00160 linearizedTrack->predictedStateWeight(error);
00161 if(error!=0) {
00162 edm::LogWarning("KalmanVertexUpdator") << "predictedState error matrix inversion failed. An invalid vertex will be returned.";
00163 return std::pair <bool, double> (false, -1.);
00164 }
00165
00166 AlgebraicSymMatrixMM s = ROOT::Math::SimilarityT(b,trackParametersWeight);
00167 if (!invertPosDefMatrix(s)) {
00168 edm::LogWarning("KalmanVertexUpdator") << "S matrix inversion failed. An invalid vertex will be returned.";
00169 return std::pair <bool, double> (false, -1.);
00170 }
00171
00172 const AlgebraicVectorN & theResidual = linearizedTrack->constantTerm();
00173 AlgebraicVectorN vv = trackParameters - theResidual - a*newVertexPositionV;
00174 AlgebraicVectorM newTrackMomentumP = s * ROOT::Math::Transpose(b) * trackParametersWeight * vv;
00175
00176
00177
00178
00179 AlgebraicVectorN parameterResiduals = vv - b * newTrackMomentumP;
00180 linearizedTrack->checkParameters(parameterResiduals);
00181
00182 double chi2 = weight * ROOT::Math::Similarity(parameterResiduals, trackParametersWeight);
00183
00184
00185 chi2 += helper.vertexChi2(oldVertex, newVertexState);
00186
00187 return std::pair <bool, double> (true, chi2);
00188 }
00189
00190 template class KalmanVertexUpdator<5>;
00191 template class KalmanVertexUpdator<6>;