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