00001 #ifndef KinematicConstrainedVertexUpdatorT_H
00002 #define KinematicConstrainedVertexUpdatorT_H
00003
00004 #include "RecoVertex/KinematicFitPrimitives/interface/MultiTrackKinematicConstraintT.h"
00005 #include "RecoVertex/KinematicFitPrimitives/interface/KinematicVertexFactory.h"
00006 #include "RecoVertex/KinematicFit/interface/VertexKinematicConstraintT.h"
00007 #include "DataFormats/Math/interface/invertPosDefMatrix.h"
00008 #include<cassert>
00009 #include<iostream>
00010
00011 namespace KineDebug3 {
00012 struct Count {
00013 int n;
00014 Count() : n(0){}
00015 ~Count() {
00016 }
00017
00018 };
00019 inline void count() {
00020 static Count c;
00021 ++c.n;
00022 }
00023
00024 }
00025
00031 template < int nTrk, int nConstraint> class KinematicConstrainedVertexUpdatorT
00032 {
00033 public:
00034
00038 KinematicConstrainedVertexUpdatorT();
00039
00040 ~KinematicConstrainedVertexUpdatorT();
00041
00050 RefCountedKinematicVertex
00051 update(const ROOT::Math::SVector<double, 3+7*nTrk> & inState,
00052 ROOT::Math::SMatrix<double, 3+7*nTrk,3+7*nTrk ,ROOT::Math::MatRepSym<double,3+7*nTrk> >& inCov, std::vector<KinematicState> & lStates,
00053 const GlobalPoint& lPoint, GlobalVector const & fieldValue, MultiTrackKinematicConstraintT< nTrk, nConstraint > * cs);
00054
00055 private:
00056
00057 KinematicVertexFactory vFactory;
00058 VertexKinematicConstraintT vConstraint;
00059 ROOT::Math::SVector<double,3+7*nTrk> delta_alpha;
00060 ROOT::Math::SMatrix<double,nConstraint+4,3+7*nTrk> g;
00061 ROOT::Math::SVector<double,nConstraint+4> val;
00062
00063
00064 ROOT::Math::SVector<double, 3+7*nTrk> finPar;
00065 ROOT::Math::SVector<double, nConstraint+4> lambda;
00066
00067 ROOT::Math::SMatrix<double,3,3,ROOT::Math::MatRepSym<double,3> > pCov;
00068 ROOT::Math::SMatrix<double,7,7,ROOT::Math::MatRepSym<double,7> > nCovariance;
00069 ROOT::Math::SMatrix<double,nConstraint+4,nConstraint+4,ROOT::Math::MatRepSym<double,nConstraint+4> > v_g_sym;
00070
00071 };
00072
00073 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00074
00075 template < int nTrk, int nConstraint>
00076 KinematicConstrainedVertexUpdatorT< nTrk, nConstraint >::KinematicConstrainedVertexUpdatorT()
00077 {}
00078
00079 template < int nTrk, int nConstraint>
00080 KinematicConstrainedVertexUpdatorT< nTrk, nConstraint >::~KinematicConstrainedVertexUpdatorT()
00081 {}
00082
00083 template < int nTrk, int nConstraint>
00084 RefCountedKinematicVertex
00085 KinematicConstrainedVertexUpdatorT< nTrk, nConstraint >::update(const ROOT::Math::SVector<double,3+7*nTrk>& inPar,
00086 ROOT::Math::SMatrix<double, 3+7*nTrk,3+7*nTrk ,ROOT::Math::MatRepSym<double,3+7*nTrk> >& inCov,
00087 std::vector<KinematicState> & lStates,
00088 const GlobalPoint& lPoint,
00089 GlobalVector const & fieldValue,
00090 MultiTrackKinematicConstraintT< nTrk, nConstraint > * cs)
00091 {
00092 KineDebug3::count();
00093
00094 int vSize = lStates.size();
00095
00096 assert( nConstraint==0 || cs!=0);
00097 assert(vSize == nConstraint);
00098
00099 const MagneticField* field=lStates.front().magneticField();
00100
00101 delta_alpha=inPar;
00102 delta_alpha(0)-=lPoint.x();
00103 delta_alpha(1)-=lPoint.y();
00104 delta_alpha(2)-=lPoint.z();
00105 int cst=3;
00106 for(std::vector<KinematicState>::const_iterator i = lStates.begin(); i != lStates.end(); i++)
00107 for ( int j=0; j<7; j++) {
00108 delta_alpha(cst)-=i->kinematicParameters()(j);
00109 cst++;
00110 }
00111
00112
00113
00114
00115
00116
00117 if( nConstraint !=0) {
00118 cs->init(lStates, lPoint, fieldValue);
00119 val.Place_at(cs->value(),0);
00120 g.Place_at(cs->positionDerivative(),0,0);
00121 g.Place_at(cs->parametersDerivative(),0,3);
00122 }
00123
00124 vConstraint.init(lStates, lPoint, fieldValue);
00125 val.Place_at(vConstraint.value(),nConstraint);
00126 g.Place_at(vConstraint.positionDerivative(),nConstraint, 0);
00127 g.Place_at(vConstraint.parametersDerivative(),nConstraint, 3);
00128
00129
00130
00131
00132
00133 v_g_sym = ROOT::Math::Similarity(g,inCov);
00134
00135
00136 bool ifl1 = invertPosDefMatrix(v_g_sym);
00137 if(!ifl1) {
00138 std::cout << "invert failed\n";
00139 std::cout << v_g_sym << std::endl;
00140 LogDebug("KinematicConstrainedVertexFitter3")
00141 << "Fit failed: unable to invert SYM gain matrix\n";
00142 return RefCountedKinematicVertex();
00143 }
00144
00145
00146
00147 val += g*delta_alpha;
00148 lambda = v_g_sym *val;
00149
00150
00151 finPar = inPar - inCov * (ROOT::Math::Transpose(g) * lambda);
00152
00153
00154 ROOT::Math::SMatrix<double,3+7*nTrk,3+7*nTrk,ROOT::Math::MatRepSym<double,3+7*nTrk> > prod = ROOT::Math::SimilarityT(g,v_g_sym);
00155 ROOT::Math::SMatrix<double,3+7*nTrk,3+7*nTrk,ROOT::Math::MatRepSym<double,3+7*nTrk> > prod1;
00156 ROOT::Math::AssignSym::Evaluate(prod1, inCov * prod * inCov);
00157
00158 inCov -= prod1;
00159
00160 pCov = inCov.template Sub< ROOT::Math::SMatrix<double,3,3,ROOT::Math::MatRepSym<double,3> > >(0,0);
00161
00162
00163 double chi = ROOT::Math::Dot(lambda,val);
00164
00165
00166
00167 float ndf = 2*vSize - 3;
00168 ndf += nConstraint;
00169
00170
00171
00172 GlobalPoint vPos (finPar(0),finPar(1),finPar(2));
00173 VertexState st(vPos,GlobalError(pCov));
00174 RefCountedKinematicVertex rVtx = vFactory.vertex(st,chi,ndf);
00175
00176
00177 AlgebraicVector7 newPar;
00178 int i_int = 0;
00179 for(std::vector<KinematicState>::iterator i_st=lStates.begin(); i_st != lStates.end(); i_st++)
00180 {
00181 for(int i =0; i<7; i++)
00182 {newPar(i) = finPar(3 + i_int*7 + i);}
00183
00184 nCovariance = inCov.template Sub<ROOT::Math::SMatrix<double, 7,7,ROOT::Math::MatRepSym<double,7> > >(3 + i_int*7, 3 + i_int*7);
00185 TrackCharge chl = i_st->particleCharge();
00186 KinematicParameters nrPar(newPar);
00187 KinematicParametersError nrEr(nCovariance);
00188 KinematicState newState(nrPar,nrEr,chl, field);
00189 (*i_st) = newState;
00190 i_int++;
00191 }
00192 return rVtx;
00193 }
00194
00195 #endif