00001 #include "RecoVertex/KinematicFit/interface/KinematicConstrainedVertexUpdator.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.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 std::pair<std::pair<std::vector<KinematicState>, AlgebraicMatrix >, RefCountedKinematicVertex >
00017 KinematicConstrainedVertexUpdator::update(const AlgebraicVector& inPar,
00018 const AlgebraicMatrix& inCov, std::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(std::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 for(int i = 1; i<=val.num_row();++i) {
00092 if (std::isnan(val(i))) {
00093 LogDebug("KinematicConstrainedVertexUpdator")
00094 << "catched NaN.\n";
00095 return std::pair<std::pair<std::vector<KinematicState>, AlgebraicMatrix>, RefCountedKinematicVertex >(
00096 std::pair<std::vector<KinematicState>, AlgebraicMatrix>(std::vector<KinematicState>(), AlgebraicMatrix(1,0)),
00097 RefCountedKinematicVertex());
00098 }
00099 }
00100
00101
00102 AlgebraicSymMatrix in_cov_sym(7*vSize + 3,0);
00103
00104 for(int i = 1; i<7*vSize+4; ++i)
00105 {
00106 for(int j = 1; j<7*vSize+4; ++j)
00107 {if(i<=j) in_cov_sym(i,j) = inCov(i,j);}
00108 }
00109
00110
00111 AlgebraicSymMatrix v_g_sym = in_cov_sym.similarity(g);
00112
00113 int ifl1 = 0;
00114 v_g_sym.invert(ifl1);
00115 if(ifl1 !=0) {
00116 LogDebug("KinematicConstrainedVertexFitter")
00117 << "Fit failed: unable to invert SYM gain matrix\n";
00118 return std::pair<std::pair<std::vector<KinematicState>, AlgebraicMatrix>, RefCountedKinematicVertex >(
00119 std::pair<std::vector<KinematicState>, AlgebraicMatrix>(std::vector<KinematicState>(), AlgebraicMatrix(1,0)),
00120 RefCountedKinematicVertex());
00121 }
00122
00123
00124
00125 AlgebraicVector lambda = v_g_sym *(g*delta_alpha + val);
00126
00127
00128 AlgebraicVector finPar = inPar - in_cov_sym * g.T() * lambda;
00129
00130
00131 AlgebraicMatrix mFactor = in_cov_sym *(v_g_sym.similarityT(g))* in_cov_sym;
00132
00133
00134 AlgebraicMatrix rCov = in_cov_sym - mFactor;
00135
00136
00137 AlgebraicSymMatrix r_cov_sym(7*vSize+3,0);
00138 for(int i = 1; i<7*vSize+4; ++i)
00139 {
00140 for(int j = 1; j<7*vSize+4; ++j)
00141 {if(i<=j)r_cov_sym(i,j) = rCov(i,j);}
00142 }
00143
00144 AlgebraicSymMatrix pCov = r_cov_sym.sub(1,3);
00145
00146
00147 AlgebraicVector chi = lambda.T()*(g*delta_alpha + val);
00148
00149
00150
00151 float ndf = 2*vSize - 3;
00152 if(cs != 0){ndf += cs->numberOfEquations();}
00153
00154
00155
00156 GlobalPoint vPos (finPar(1),finPar(2),finPar(3));
00157 VertexState st(vPos,GlobalError(pCov));
00158 RefCountedKinematicVertex rVtx = vFactory->vertex(st,chi(1),ndf);
00159
00160
00161 int i_int = 0;
00162 std::vector<KinematicState> ns;
00163 for(std::vector<KinematicState>::iterator i_st=lStates.begin(); i_st != lStates.end(); i_st++)
00164 {
00165 AlgebraicVector7 newPar;
00166 for(int i =0; i<7; i++)
00167 {newPar(i) = finPar(4 + i_int*7 + i);}
00168
00169 AlgebraicSymMatrix nCovariance = r_cov_sym.sub(4 + i_int*7, 10 + i_int*7);
00170 TrackCharge chl = i_st->particleCharge();
00171 KinematicParameters nrPar(newPar);
00172 KinematicParametersError nrEr(asSMatrix<7>(nCovariance));
00173 KinematicState newState(nrPar,nrEr,chl, field);
00174 ns.push_back(newState);
00175 i_int++;
00176 }
00177 std::pair<std::vector<KinematicState>, AlgebraicMatrix> ns_m(ns,rCov);
00178 return std::pair<std::pair<std::vector<KinematicState>, AlgebraicMatrix>, RefCountedKinematicVertex >(ns_m,rVtx);
00179 }