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 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 vector<RefCountedVertexTrack> newVertexTracks = oldVertex.tracks();
00031
00032 if (sign > 0) {
00033 newVertexTracks.push_back(track);
00034 }else{
00035
00036 typename vector<RefCountedVertexTrack>::iterator pos
00037 = find(newVertexTracks.begin(), newVertexTracks.end(), track);
00038 if (pos != newVertexTracks.end()) {
00039 newVertexTracks.erase(pos);
00040 } else {
00041 cout<<"KalmanVertexUpdator::Unable to find requested track in the current vertex"<<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 template <unsigned int N>
00072 float KalmanVertexUpdator<N>::vertexPositionChi2( const VertexState& oldVertex,
00073 const GlobalPoint& newVertexPosition) const
00074 {
00075 GlobalPoint oldVertexPosition = oldVertex.position();
00076 AlgebraicVector3 oldVertexPositionV;
00077 oldVertexPositionV(0) = oldVertexPosition.x();
00078 oldVertexPositionV(1) = oldVertexPosition.y();
00079 oldVertexPositionV(2) = oldVertexPosition.z();
00080
00081 AlgebraicVector3 newVertexPositionV;
00082 newVertexPositionV(0) = newVertexPosition.x();
00083 newVertexPositionV(1) = newVertexPosition.y();
00084 newVertexPositionV(2) = newVertexPosition.z();
00085
00086 AlgebraicVector3 positionResidual = newVertexPositionV - oldVertexPositionV;
00087 float result = ROOT::Math::Similarity(positionResidual, oldVertex.weight().matrix_new());
00088
00089 return result;
00090 }
00091
00092
00093 template <unsigned int N>
00094 VertexState
00095 KalmanVertexUpdator<N>::positionUpdate (const VertexState & oldVertex,
00096 const RefCountedLinearizedTrackState linearizedTrack,
00097 const float weight, int sign) const
00098 {
00099 int ifail;
00100
00101 const AlgebraicMatrixN3 & a = linearizedTrack->positionJacobian();
00102 const AlgebraicMatrixNM & b = linearizedTrack->momentumJacobian();
00103
00104
00105
00106
00107 AlgebraicSymMatrixNN trackParametersWeight =
00108 linearizedTrack->predictedStateWeight();
00109
00110
00111
00112
00113
00114
00115
00116
00117 AlgebraicSymMatrixMM s = ROOT::Math::SimilarityT(b,trackParametersWeight);
00118 ifail = ! s.Invert();
00119 if(ifail != 0) {
00120 edm::LogWarning("KalmanVertexUpdator") << "S matrix inversion failed";
00121 return VertexState();
00122 }
00123
00124 AlgebraicSymMatrixNN gB = trackParametersWeight -
00125 ROOT::Math::Similarity(trackParametersWeight, ROOT::Math::Similarity(b,s));
00126
00127
00128
00129 AlgebraicSymMatrix33 newVertexWeight = oldVertex.weight().matrix_new()
00130 + weight * sign * ROOT::Math::SimilarityT(a,gB);
00131
00132
00133
00134
00135 AlgebraicVector3 newSwr =
00136 oldVertex.weightTimesPosition() + weight * sign * ROOT::Math::Transpose(a) * gB *
00137 ( linearizedTrack->predictedStateParameters() - linearizedTrack->constantTerm());
00138
00139
00140
00141 VertexState newpos (newSwr, GlobalWeight(newVertexWeight), 1.0);
00142
00143
00144
00145
00146 return newpos;
00147 }
00148
00149
00150 template <unsigned int N>
00151 pair <bool, double> KalmanVertexUpdator<N>::chi2Increment(const VertexState & oldVertex,
00152 const VertexState & newVertexState,
00153 const RefCountedLinearizedTrackState linearizedTrack,
00154 float weight) const
00155 {
00156 GlobalPoint newVertexPosition = newVertexState.position();
00157
00158 AlgebraicVector3 newVertexPositionV;
00159 newVertexPositionV(0) = newVertexPosition.x();
00160 newVertexPositionV(1) = newVertexPosition.y();
00161 newVertexPositionV(2) = newVertexPosition.z();
00162
00163 const AlgebraicMatrixN3 & a = linearizedTrack->positionJacobian();
00164 const AlgebraicMatrixNM & b = linearizedTrack->momentumJacobian();
00165
00166 AlgebraicVectorN trackParameters =
00167 linearizedTrack->predictedStateParameters();
00168
00169 AlgebraicSymMatrixNN trackParametersWeight =
00170 linearizedTrack->predictedStateWeight();
00171
00172 AlgebraicSymMatrixMM s = ROOT::Math::SimilarityT(b,trackParametersWeight);
00173 bool ret = s.Invert();
00174 if(!ret) {
00175 edm::LogWarning("KalmanVertexUpdator") << "S matrix inversion failed";
00176 return pair <bool, double> (false, -1.);
00177 }
00178
00179 const AlgebraicVectorN & theResidual = linearizedTrack->constantTerm();
00180 AlgebraicVectorM newTrackMomentumP = s * ROOT::Math::Transpose(b) * trackParametersWeight *
00181 (trackParameters - theResidual - a*newVertexPositionV);
00182
00183
00184
00185
00186 AlgebraicVectorN parameterResiduals = trackParameters -
00187 ( theResidual + a * newVertexPositionV + b * newTrackMomentumP);
00188 linearizedTrack->checkParameters(parameterResiduals);
00189
00190 double chi2 = weight * ROOT::Math::Similarity(parameterResiduals, trackParametersWeight);
00191
00192
00193 chi2 += helper.vertexChi2(oldVertex, newVertexState);
00194
00195 return pair <bool, double> (true, chi2);
00196 }
00197
00198 template class KalmanVertexUpdator<5>;
00199 template class KalmanVertexUpdator<6>;