00001 #include "RecoVertex/KinematicFit/interface/LagrangeParentParticleFitter.h"
00002 #include "RecoVertex/KinematicFitPrimitives/interface/KinematicVertexFactory.h"
00003
00004 #include "RecoVertex/KinematicFit/interface/InputSort.h"
00005 #include "RecoVertex/VertexPrimitives/interface/VertexException.h"
00006
00007 LagrangeParentParticleFitter::LagrangeParentParticleFitter()
00008 {readParameters();}
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 vector<RefCountedKinematicTree> LagrangeParentParticleFitter::fit(vector<RefCountedKinematicTree> trees,
00123 KinematicConstraint * cs)const
00124 {
00125
00126 InputSort iSort;
00127 vector<RefCountedKinematicParticle> prt = iSort.sort(trees);
00128 int nStates = prt.size();
00129
00130
00131 AlgebraicVector part(7*nStates,0);
00132 AlgebraicSymMatrix cov(7*nStates,0);
00133
00134 AlgebraicVector chi_in(nStates,0);
00135 AlgebraicVector ndf_in(nStates,0);
00136 int l_c=0;
00137 for(vector<RefCountedKinematicParticle>::const_iterator i = prt.begin(); i != prt.end(); i++)
00138 {
00139 AlgebraicVector7 lp = (*i)->currentState().kinematicParameters().vector();
00140 for(int j = 1; j != 8; j++){part(7*l_c + j) = lp(j-1);}
00141 AlgebraicSymMatrix lc= asHepMatrix<7>((*i)->currentState().kinematicParametersError().matrix());
00142 cov.sub(7*l_c+1,lc);
00143 chi_in(l_c+1) = (*i)->chiSquared();
00144 ndf_in(l_c+1) = (*i)->degreesOfFreedom();
00145 l_c++;
00146 }
00147
00148
00149 AlgebraicVector refPar;
00150 AlgebraicSymMatrix refCovS;
00151
00152
00153 AlgebraicVector vl;
00154 AlgebraicMatrix dr;
00155 AlgebraicVector dev;
00156 int nstep = 0;
00157 double df = 0.;
00158 AlgebraicVector exPoint = part;
00159
00160
00161
00162
00163
00164 AlgebraicVector chi;
00165 AlgebraicVector ndf;
00166
00167 do{
00168 df = 0.;
00169 chi = chi_in;
00170 ndf = ndf_in;
00171
00172 vl = cs->value(exPoint).first;
00173 dr = cs->derivative(exPoint).first;
00174 dev = cs->deviations(nStates);
00175
00176
00177
00178
00179
00180
00181
00182
00183 AlgebraicVector delta_alpha = part - exPoint;
00184
00185
00186
00187 AlgebraicMatrix drt = dr.T();
00188 AlgebraicMatrix v_d = dr * cov * drt;
00189 int ifail = 0;
00190 v_d.invert(ifail);
00191 if(ifail != 0) throw VertexException("ParentParticleFitter::error inverting covariance matrix");
00192
00193
00194
00195 AlgebraicVector lambda = v_d * (dr*delta_alpha + vl);
00196
00197
00198 refPar = part - (cov * drt * lambda);
00199
00200
00201 refCovS = cov;
00202 AlgebraicMatrix sPart = drt * v_d * dr;
00203 AlgebraicMatrix covF = cov * sPart * cov;
00204
00205
00206 AlgebraicSymMatrix sCovF(nStates*7,0);
00207 for(int i = 1; i< nStates*7 +1; ++i)
00208 {
00209 for(int j = 1; j< nStates*7 +1; j++)
00210 {if(i<=j) sCovF(i,j) = covF(i,j);}
00211 }
00212
00213 refCovS -= sCovF;
00214
00215
00216 for(int i = 1; i < nStates+1; i++)
00217 {for(int j = 1; j<8; j++){refCovS((i-1)+j,(i-1)+j) += dev(j);}}
00218
00219
00220 for(int k =1; k<nStates+1; k++)
00221 {
00222 chi(k) += (lambda.T() * (dr*delta_alpha + vl))(1);
00223 ndf(k) += cs->numberOfEquations();
00224 }
00225
00226 exPoint = refPar;
00227 AlgebraicVector vlp = cs->value(exPoint).first;
00228 for(int i = 1; i< vl.num_row();i++)
00229 {df += abs(vlp(i));}
00230 nstep++;
00231 }while(df>theMaxDiff && nstep<theMaxStep);
00232
00233
00234
00235
00236 vector<RefCountedKinematicParticle> refPart;
00237 vector<RefCountedKinematicTree> refTrees = trees;
00238
00239 int j=1;
00240 vector<RefCountedKinematicTree>::const_iterator tr = refTrees.begin();
00241 for(vector<RefCountedKinematicParticle>::const_iterator i = prt.begin(); i!= prt.end(); i++)
00242 {
00243 AlgebraicVector7 lRefPar;
00244 for(int k = 1; k<8 ; k++)
00245 {lRefPar(k-1) = refPar((j-1)*7+k);}
00246 AlgebraicSymMatrix77 lRefCovS = asSMatrix<7>(refCovS.sub((j-1)*7 +1,(j-1)*7+7));
00247
00248
00249 KinematicParameters param(lRefPar);
00250 KinematicParametersError er(lRefCovS);
00251 KinematicState kState(param,er,(*i)->initialState().particleCharge(), (**i).magneticField());
00252 RefCountedKinematicParticle refParticle = (*i)->refittedParticle(kState,chi(j),ndf(j),cs->clone());
00253
00254
00255 (*tr)->findParticle(*i);
00256 RefCountedKinematicVertex inVertex = (*tr)->currentDecayVertex();
00257 (*tr)->replaceCurrentParticle(refParticle);
00258
00259
00260 GlobalPoint nvPos(param.vector()(1), param.vector()(2), param.vector()(3));
00261 AlgebraicSymMatrix nvMatrix = asHepMatrix<7>(er.matrix()).sub(1,3);
00262 GlobalError nvError(nvMatrix);
00263 VertexState vState(nvPos, nvError, 1.0);
00264 KinematicVertexFactory vFactory;
00265 RefCountedKinematicVertex nVertex = vFactory.vertex(vState,inVertex,chi(j),ndf(j));
00266 (*tr)->replaceCurrentVertex(nVertex);
00267 tr++;
00268 j++;
00269 }
00270 return refTrees;
00271 }
00272
00273 void LagrangeParentParticleFitter::readParameters()
00274 {
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 theMaxDiff = 0.01;
00285 theMaxStep = 10;
00286 }