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
00008 #include <algorithm>
00009
00010
00011 template <unsigned int N>
00012 CachingVertex<N> KalmanVertexUpdator<N>::update(const CachingVertex<N> & oldVertex,
00013 const RefCountedVertexTrack track, float weight, int sign) const
00014 {
00015 if(abs(sign) != 1) throw VertexException
00016 ("KalmanVertexUpdator::abs(sign) not equal to 1");
00017
00018 VertexState newVertexState = positionUpdate(oldVertex.vertexState(),
00019 track->linearizedTrack(), weight, sign);
00020 if (!newVertexState.isValid()) return CachingVertex<N>();
00021
00022 float chi1 = oldVertex.totalChiSquared();
00023 std::pair <bool, double> chi2P = chi2Increment(oldVertex.vertexState(), newVertexState,
00024 track->linearizedTrack() , weight );
00025 if (!chi2P.first) return CachingVertex<N>();
00026
00027 chi1 +=sign * chi2P.second;
00028
00029
00030 std::vector<RefCountedVertexTrack> newVertexTracks = oldVertex.tracks();
00031
00032 if (sign > 0) {
00033 newVertexTracks.push_back(track);
00034 }else{
00035
00036 typename std::vector<RefCountedVertexTrack>::iterator pos
00037 = find(newVertexTracks.begin(), newVertexTracks.end(), track);
00038 if (pos != newVertexTracks.end()) {
00039 newVertexTracks.erase(pos);
00040 } else {
00041 std::cout<<"KalmanVertexUpdator::Unable to find requested track in the current vertex"<<std::endl;
00042 throw VertexException("KalmanVertexUpdator::Unable to find requested track in the current vertex");
00043 }
00044 }
00045
00046 if (oldVertex.hasPrior()) {
00047 return CachingVertex<N>( oldVertex.priorVertexState(),
00048 newVertexState, newVertexTracks, chi1);
00049 } else {
00050 return CachingVertex<N>(newVertexState, newVertexTracks, chi1);
00051 }
00052 }
00053
00054
00055 template <unsigned int N>
00056 CachingVertex<N> KalmanVertexUpdator<N>::add(const CachingVertex<N> & oldVertex,
00057 const RefCountedVertexTrack track) const
00058 {
00059 float weight = track->weight();
00060 return update(oldVertex,track,weight,+1);
00061 }
00062
00063 template <unsigned int N>
00064 CachingVertex<N> KalmanVertexUpdator<N>::remove(const CachingVertex<N> & oldVertex,
00065 const RefCountedVertexTrack track) const
00066 {
00067 float weight = track->weight();
00068 return update(oldVertex,track,weight,-1);
00069 }
00070
00071
00072 template <unsigned int N>
00073 VertexState
00074 KalmanVertexUpdator<N>::positionUpdate (const VertexState & oldVertex,
00075 const RefCountedLinearizedTrackState linearizedTrack,
00076 const float weight, int sign) const
00077 {
00078 int error;
00079
00080 if (!linearizedTrack->isValid())
00081 return VertexState();
00082
00083 const AlgebraicMatrixN3 & a = linearizedTrack->positionJacobian();
00084 const AlgebraicMatrixNM & b = linearizedTrack->momentumJacobian();
00085
00086
00087
00088
00089 AlgebraicSymMatrixNN trackParametersWeight =
00090 linearizedTrack->predictedStateWeight(error);
00091 if(error != 0) {
00092 edm::LogWarning("KalmanVertexUpdator") << "predictedState error matrix inversion failed. An invalid vertex will be returned.";
00093 return VertexState();
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103 AlgebraicSymMatrixMM s = ROOT::Math::SimilarityT(b,trackParametersWeight);
00104 error = ! s.Invert();
00105 if(error != 0) {
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 =
00122 oldVertex.weightTimesPosition() + 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 error = ! s.Invert();
00168 if(error!=0) {
00169 edm::LogWarning("KalmanVertexUpdator") << "S matrix inversion failed. An invalid vertex will be returned.";
00170 return std::pair <bool, double> (false, -1.);
00171 }
00172
00173 const AlgebraicVectorN & theResidual = linearizedTrack->constantTerm();
00174 AlgebraicVectorM newTrackMomentumP = s * ROOT::Math::Transpose(b) * trackParametersWeight *
00175 (trackParameters - theResidual - a*newVertexPositionV);
00176
00177
00178
00179
00180 AlgebraicVectorN parameterResiduals = trackParameters -
00181 ( theResidual + a * newVertexPositionV + b * newTrackMomentumP);
00182 linearizedTrack->checkParameters(parameterResiduals);
00183
00184 double chi2 = weight * ROOT::Math::Similarity(parameterResiduals, trackParametersWeight);
00185
00186
00187 chi2 += helper.vertexChi2(oldVertex, newVertexState);
00188
00189 return std::pair <bool, double> (true, chi2);
00190 }
00191
00192 template class KalmanVertexUpdator<5>;
00193 template class KalmanVertexUpdator<6>;