00001 #include "RecoVertex/KinematicFit/interface/KinematicConstrainedVertexUpdator.h"
00002 #include "RecoVertex/VertexPrimitives/interface/VertexException.h"
00003
00004 KinematicConstrainedVertexUpdator::KinematicConstrainedVertexUpdator()
00005 {
00006 vFactory = new KinematicVertexFactory();
00007 vConstraint = new VertexKinematicConstraint();
00008 }
00009
00010 KinematicConstrainedVertexUpdator::~KinematicConstrainedVertexUpdator()
00011 {
00012 delete vFactory;
00013 delete vConstraint;
00014 }
00015
00016 pair<pair<vector<KinematicState>, AlgebraicMatrix >, RefCountedKinematicVertex >
00017 KinematicConstrainedVertexUpdator::update(const AlgebraicVector& inPar,
00018 const AlgebraicMatrix& inCov, vector<KinematicState> lStates,
00019 const GlobalPoint& lPoint, MultiTrackKinematicConstraint * cs)const
00020 {
00021 const MagneticField* field=lStates.front().magneticField();
00022 AlgebraicMatrix d_matrix = vConstraint->parametersDerivative(lStates, lPoint);
00023 AlgebraicMatrix e_matrix = vConstraint->positionDerivative(lStates, lPoint);
00024 AlgebraicVector val_s = vConstraint->value(lStates, lPoint);
00025 int vSize = lStates.size();
00026
00027
00028 AlgebraicVector d_a(7*vSize + 3);
00029 d_a(1) = lPoint.x();
00030 d_a(2) = lPoint.y();
00031 d_a(3) = lPoint.z();
00032
00033 int cst = 0;
00034 for(vector<KinematicState>::const_iterator i = lStates.begin(); i != lStates.end(); i++)
00035 {
00036 AlgebraicVector lst_par = asHepVector<7>(i->kinematicParameters().vector());
00037 for(int j = 1; j<lst_par.num_row()+1; j++)
00038 {d_a(3+7*cst+j) = lst_par(j);}
00039 cst++;
00040 }
00041
00042
00043 AlgebraicVector delta_alpha = inPar - d_a;
00044
00045
00046
00047
00048
00049 AlgebraicMatrix g;
00050 AlgebraicVector val;
00051 if(cs == 0)
00052 {
00053
00054
00055 g = AlgebraicMatrix(2*vSize,7*vSize+3,0);
00056 val = AlgebraicVector(2*vSize);
00057
00058
00059 g.sub(1,1,e_matrix);
00060 g.sub(1,4,d_matrix);
00061
00062
00063 val = val_s;
00064 }else{
00065
00066
00067 int n_eq =cs->numberOfEquations();
00068 g = AlgebraicMatrix(n_eq + 2*vSize,7*vSize + 3,0);
00069 val = AlgebraicVector(n_eq + 2*vSize);
00070 AlgebraicMatrix n_x = cs->positionDerivative(lStates, lPoint);
00071 AlgebraicMatrix n_alpha = cs->parametersDerivative(lStates, lPoint);
00072 AlgebraicVector c_val = cs->value(lStates, lPoint);
00073
00074
00075
00076
00077
00078 g.sub(1,1,n_x);
00079 g.sub(1,4,n_alpha);
00080 g.sub(n_eq+1, 1, e_matrix);
00081 g.sub(n_eq+1, 4, d_matrix);
00082
00083
00084 for(int i = 1;i< n_eq+1; i++)
00085 {val(i) = c_val(i);}
00086 for(int i = 1; i<(2*vSize+1); i++)
00087 {val(i+n_eq) = val_s(i);}
00088 }
00089
00090
00091 AlgebraicSymMatrix in_cov_sym(7*vSize + 3,0);
00092
00093 for(int i = 1; i<7*vSize+4; ++i)
00094 {
00095 for(int j = 1; j<7*vSize+4; ++j)
00096 {if(i<=j) in_cov_sym(i,j) = inCov(i,j);}
00097 }
00098
00099
00100 AlgebraicSymMatrix v_g_sym = in_cov_sym.similarity(g);
00101
00102 int ifl1 = 0;
00103 v_g_sym.invert(ifl1);
00104 if(ifl1 !=0) throw VertexException("KinematicConstrainedVertexFitter::unable to invert SYM gain matrix");
00105
00106
00107
00108
00109 AlgebraicVector lambda = v_g_sym *(g*delta_alpha + val);
00110
00111
00112 AlgebraicVector finPar = inPar - in_cov_sym * g.T() * lambda;
00113
00114
00115 AlgebraicMatrix mFactor = in_cov_sym *(v_g_sym.similarityT(g))* in_cov_sym;
00116
00117
00118 AlgebraicMatrix rCov = in_cov_sym - mFactor;
00119
00120
00121 AlgebraicSymMatrix r_cov_sym(7*vSize+3,0);
00122 for(int i = 1; i<7*vSize+4; ++i)
00123 {
00124 for(int j = 1; j<7*vSize+4; ++j)
00125 {if(i<=j)r_cov_sym(i,j) = rCov(i,j);}
00126 }
00127
00128 AlgebraicSymMatrix pCov = r_cov_sym.sub(1,3);
00129
00130
00131 AlgebraicVector chi = lambda.T()*(g*delta_alpha + val);
00132
00133
00134
00135 float ndf = 2*vSize - 3;
00136 if(cs != 0){ndf += cs->numberOfEquations();}
00137
00138
00139
00140 GlobalPoint vPos (finPar(1),finPar(2),finPar(3));
00141 VertexState st(vPos,GlobalError(pCov));
00142 RefCountedKinematicVertex rVtx = vFactory->vertex(st,chi(1),ndf);
00143
00144
00145 int i_int = 0;
00146 vector<KinematicState> ns;
00147 for(vector<KinematicState>::iterator i_st=lStates.begin(); i_st != lStates.end(); i_st++)
00148 {
00149 AlgebraicVector7 newPar;
00150 for(int i =0; i<7; i++)
00151 {newPar(i) = finPar(4 + i_int*7 + i);}
00152
00153 AlgebraicSymMatrix nCovariance = r_cov_sym.sub(4 + i_int*7, 10 + i_int*7);
00154 TrackCharge chl = i_st->particleCharge();
00155 KinematicParameters nrPar(newPar);
00156 KinematicParametersError nrEr(asSMatrix<7>(nCovariance));
00157 KinematicState newState(nrPar,nrEr,chl, field);
00158 ns.push_back(newState);
00159 i_int++;
00160 }
00161 pair<vector<KinematicState>, AlgebraicMatrix> ns_m(ns,rCov);
00162 return pair<pair<vector<KinematicState>, AlgebraicMatrix>, RefCountedKinematicVertex >(ns_m,rVtx);
00163 }