CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoVertex/KinematicFit/src/VertexKinematicConstraintT.cc

Go to the documentation of this file.
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   //it is 2 equations per track
00043   for(int j = 0; j!=2; ++j) {
00044 
00045     if(a_i[j] !=0) {
00046       //vector of values
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       //neutral particle
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       //charged particle
00065             
00066       //D Jacobian matrix
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       //neutral particle
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       //charged particle
00104 
00105       //E jacobian matrix
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       //neutral particle
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;}