00001 #include "RecoVertex/KinematicFit/interface/VertexKinematicConstraintT.h"
00002 #include "RecoVertex/VertexPrimitives/interface/VertexException.h"
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004
00005 VertexKinematicConstraintT::VertexKinematicConstraintT()
00006 {}
00007
00008 VertexKinematicConstraintT::~VertexKinematicConstraintT()
00009 {}
00010
00011
00012 void VertexKinematicConstraintT::init(const std::vector<KinematicState>& states,
00013 const GlobalPoint& ipoint, const GlobalVector& fieldValue) {
00014 int num = states.size();
00015 if(num!=2) throw VertexException("VertexKinematicConstraintT !=2 states passed");
00016 double mfz = fieldValue.z();
00017
00018 int j=0;
00019 for(std::vector<KinematicState>::const_iterator i = states.begin(); i != states.end(); i++)
00020 {
00021 mom[j] = i->globalMomentum();
00022 dpos[j] = ipoint - i->globalPosition();
00023 a_i[j] = - i->particleCharge() * mfz;
00024
00025 double pvx = mom[j].x() - a_i[j]*dpos[j].y();
00026 double pvy = mom[j].y() + a_i[j]*dpos[j].x();
00027 double pvt2 = pvx*pvx+pvy*pvy;
00028 novera[j] = (dpos[j].x() * mom[j].x() + dpos[j].y()*mom[j].y());
00029 n[j] = a_i[j]*novera[j];
00030 m[j] = (pvx*mom[j].x() + pvy*mom[j].y());
00031 k[j] = -mom[j].z()/(mom[j].perp2()*pvt2);
00032 delta[j] = std::atan2(n[j],m[j]);
00033
00034 ++j;
00035 }
00036 }
00037
00038
00039
00040 void VertexKinematicConstraintT::fillValue() const
00041 {
00042
00043 for(int j = 0; j!=2; ++j) {
00044
00045 if(a_i[j] !=0) {
00046
00047 super::vl(j*2) = dpos[j].y()*mom[j].x() - dpos[j].x()*mom[j].y() -a_i[j]*(dpos[j].x()*dpos[j].x() + dpos[j].y()*dpos[j].y())*0.5;
00048 super::vl(j*2 +1) = dpos[j].z() - mom[j].z()*delta[j]/a_i[j];
00049 }else{
00050
00051 double pt2Inverse = 1./mom[j].perp2();
00052 super::vl(j*2) = dpos[j].y()*mom[j].x() - dpos[j].x()*mom[j].y();
00053 super::vl(j*2 +1) = dpos[j].z() - mom[j].z()*(dpos[j].x() * mom[j].x() + dpos[j].y() * mom[j].y())*pt2Inverse;
00054 }
00055 }
00056 }
00057
00058 void VertexKinematicConstraintT::fillParametersDerivative() const {
00059 ROOT::Math::SMatrix<double,2,7> el_part_d;
00060 for(int j = 0; j!=2; ++j) {
00061
00062 if(a_i[j] !=0) {
00063
00064
00065
00066
00067 el_part_d(0,0) = mom[j].y() + a_i[j]*dpos[j].x();
00068 el_part_d(0,1) = -mom[j].x() + a_i[j]*dpos[j].y();
00069 el_part_d(1,0) = -k[j]*(m[j]*mom[j].x() - n[j]*mom[j].y());
00070 el_part_d(1,1) = -k[j]*(m[j]*mom[j].y() + n[j]*mom[j].x());
00071 el_part_d(1,2) = -1.;
00072 el_part_d(0,3) = dpos[j].y();
00073 el_part_d(0,4) = -dpos[j].x();
00074 el_part_d(1,3) = k[j]*(m[j]*dpos[j].x() - novera[j]*(2*mom[j].x() - a_i[j]*dpos[j].y()));
00075 el_part_d(1,4) = k[j]*(m[j]*dpos[j].y() - novera[j]*(2*mom[j].y() + a_i[j]*dpos[j].x()));
00076 el_part_d(1,5) = -delta[j] /a_i[j];
00077 super::jac_d().Place_at(el_part_d,j*2, j*7);
00078 }else{
00079
00080 double pt2Inverse = 1./mom[j].perp2();
00081 el_part_d(0,0) = mom[j].y();
00082 el_part_d(0,1) = -mom[j].x();
00083 el_part_d(1,0) = mom[j].x() * (mom[j].z()*pt2Inverse);
00084 el_part_d(1,1) = mom[j].y() * (mom[j].z()*pt2Inverse);
00085 el_part_d(1,2) = -1.;
00086 el_part_d(0,3) = dpos[j].y();
00087 el_part_d(0,4) = -dpos[j].x();
00088 el_part_d(1,3) = 2*(dpos[j].x()*mom[j].x()+dpos[j].y()*mom[j].y())*pt2Inverse*mom[j].x()*(mom[j].z()*pt2Inverse) - dpos[j].x()*(mom[j].z()*pt2Inverse);
00089 el_part_d(1,4) = 2*(dpos[j].x()*mom[j].x()+dpos[j].y()*mom[j].y())*pt2Inverse*mom[j].y()*(mom[j].z()*pt2Inverse) - dpos[j].x()*(mom[j].z()*pt2Inverse);
00090 el_part_d(1,5) = - (dpos[j].x()*mom[j].x()+dpos[j].y()*mom[j].y())*pt2Inverse;
00091 super::jac_d().Place_at(el_part_d,j*2, j*7);
00092 }
00093 }
00094 }
00095
00096 void VertexKinematicConstraintT::fillPositionDerivative() const {
00097
00098 ROOT::Math::SMatrix<double,2,3> el_part_e;
00099 for(int j = 0; j!=2; ++j) {
00100
00101 if(a_i[j] !=0) {
00102
00103
00104
00105
00106 el_part_e(0,0) = -(mom[j].y() + a_i[j]*dpos[j].x());
00107 el_part_e(0,1) = mom[j].x() - a_i[j]*dpos[j].y();
00108 el_part_e(1,0) = k[j]*(m[j]*mom[j].x() - n[j]*mom[j].y());
00109 el_part_e(1,1) = k[j]*(m[j]*mom[j].y() + n[j]*mom[j].x());
00110 el_part_e(1,2) = 1;
00111 super::jac_e().Place_at(el_part_e,2*j,0);
00112 }else{
00113
00114 double pt2Inverse = 1./mom[j].perp2();
00115 el_part_e(0,0) = - mom[j].y();
00116 el_part_e(0,1) = mom[j].x();
00117 el_part_e(1,0) = -mom[j].x()*mom[j].z()*pt2Inverse;
00118 el_part_e(1,1) = -mom[j].y()*mom[j].z()*pt2Inverse;
00119 el_part_e(1,2) = 1;
00120 super::jac_e().Place_at(el_part_e,2*j,0);
00121 }
00122 }
00123 }
00124
00125 int VertexKinematicConstraintT::numberOfEquations() const
00126 {return 2;}