CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/RecoVertex/KinematicFit/src/VertexKinematicConstraint.cc

Go to the documentation of this file.
00001 #include "RecoVertex/KinematicFit/interface/VertexKinematicConstraint.h"
00002 #include "RecoVertex/VertexPrimitives/interface/VertexException.h"
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004 
00005 VertexKinematicConstraint::VertexKinematicConstraint()
00006 {}
00007 
00008 VertexKinematicConstraint::~VertexKinematicConstraint()
00009 {}
00010 
00011 AlgebraicVector VertexKinematicConstraint::value(const std::vector<KinematicState> states,
00012                         const GlobalPoint& point) const
00013 {
00014  int num = states.size();
00015  if(num<2) throw VertexException("VertexKinematicConstraint::<2 states passed");
00016 
00017 //it is 2 equations per track
00018  AlgebraicVector  vl(2*num,0);
00019  int num_r = 0;
00020  for(std::vector<KinematicState>::const_iterator i = states.begin(); i != states.end(); i++)
00021  {
00022   TrackCharge ch = i->particleCharge();
00023   GlobalVector mom = i->globalMomentum();
00024   GlobalPoint pos =  i->globalPosition();
00025   double d_x = point.x() - pos.x();
00026   double d_y = point.y() - pos.y();
00027   double d_z = point.z() - pos.z();
00028   double pt = mom.transverse();
00029   
00030   if(ch !=0)
00031   {
00032 
00033 //charged particle
00034    double a_i = - ch * i->magneticField()->inInverseGeV(pos).z();
00035 
00036    double pvx = mom.x() - a_i*d_y;
00037    double pvy = mom.y() + a_i*d_x;
00038    double n = a_i*(d_x * mom.x() + d_y * mom.y());
00039    double m = (pvx*mom.x() + pvy*mom.y());
00040    double delta = atan2(n,m);
00041 
00042 //vector of values
00043    vl(num_r*2 +1) = d_y*mom.x() - d_x*mom.y() -a_i*(d_x*d_x + d_y*d_y)/2;
00044    vl(num_r*2 +2) = d_z - mom.z()*delta/a_i;
00045   }else{
00046 
00047 //neutral particle
00048    vl(num_r*2 +1) = d_y*mom.x() - d_x*mom.y();
00049    vl(num_r*2 +2) = d_z - mom.z()*(d_x * mom.x() + d_y * mom.y())/(pt*pt);
00050   }
00051   num_r++;
00052  }
00053  return vl;
00054 }
00055 
00056 AlgebraicMatrix VertexKinematicConstraint::parametersDerivative(const std::vector<KinematicState> states,
00057                         const GlobalPoint& point) const
00058 {
00059   int num = states.size();
00060   if(num<2) throw VertexException("VertexKinematicConstraint::<2 states passed");
00061   AlgebraicMatrix jac_d(2*num,7*num);
00062   int num_r = 0;
00063   for(std::vector<KinematicState>::const_iterator i = states.begin(); i != states.end(); i++)
00064   {
00065     AlgebraicMatrix el_part_d(2,7,0);
00066     TrackCharge ch = i->particleCharge();
00067     GlobalVector mom = i->globalMomentum();
00068     GlobalPoint pos =  i->globalPosition();
00069     double d_x = point.x() - pos.x();
00070     double d_y = point.y() - pos.y();
00071     double pt = mom.transverse();
00072     
00073     if(ch !=0){
00074 
00075   //charged particle
00076    double a_i = - ch * i->magneticField()->inInverseGeV(pos).z();
00077    
00078    double pvx = mom.x() - a_i*d_y;
00079    double pvy = mom.y() + a_i*d_x;
00080    double pvt = sqrt(pvx*pvx+pvy*pvy);
00081    double novera = (d_x * mom.x() + d_y * mom.y());
00082    double n = a_i*novera;
00083    double m = (pvx*mom.x() + pvy*mom.y());
00084    double k = -mom.z()/(pvt*pvt*pt*pt);
00085    double delta = atan2(n,m);
00086 
00087   //D Jacobian matrix
00088      el_part_d(1,1) =  mom.y() + a_i*d_x;
00089      el_part_d(1,2) = -mom.x() + a_i*d_y;
00090      el_part_d(2,1) =  -k*(m*mom.x() - n*mom.y());
00091      el_part_d(2,2) =  -k*(m*mom.y() + n*mom.x());
00092      el_part_d(2,3) = -1.;
00093      el_part_d(1,4) = d_y;
00094      el_part_d(1,5) = -d_x;
00095      el_part_d(2,4) = k*(m*d_x - novera*(2*mom.x() - a_i*d_y));
00096      el_part_d(2,5) = k*(m*d_y - novera*(2*mom.y() + a_i*d_x));
00097      el_part_d(2,6) = -delta /a_i;
00098      jac_d.sub(num_r*2+1, num_r*7+1, el_part_d);
00099     }else{
00100   //neutral particle
00101       el_part_d(1,1) =  mom.y();
00102       el_part_d(1,2) = -mom.x();
00103       el_part_d(2,1) =  mom.x() * mom.z()/(pt*pt);
00104       el_part_d(2,2) =  mom.y() * mom.z()/(pt*pt);
00105       el_part_d(2,3) = -1.;
00106       el_part_d(1,4) = d_y;
00107       el_part_d(1,5) = -d_x;
00108       el_part_d(2,4) = 2*(d_x*mom.x()+d_y*mom.y())*mom.x()*mom.z()/(pt*pt*pt*pt) - mom.z()*d_x/(pt*pt);
00109       el_part_d(2,5) = 2*(d_x*mom.x()+d_y*mom.y())*mom.y()*mom.z()/(pt*pt*pt*pt) - mom.z()*d_y/(pt*pt);
00110       el_part_d(2,6) =-(d_x * mom.x() + d_y * mom.y())/(pt*pt);
00111       jac_d.sub(num_r*2+1, num_r*7+1, el_part_d);
00112     }
00113     num_r++;
00114   }
00115   return jac_d;
00116 }
00117 
00118 AlgebraicMatrix VertexKinematicConstraint::positionDerivative(const std::vector<KinematicState> states,
00119                                     const GlobalPoint& point) const
00120 {
00121  int num = states.size();
00122  if(num<2) throw VertexException("VertexKinematicConstraint::<2 states passed");
00123  AlgebraicMatrix jac_e(2*num,3);
00124  int num_r = 0;
00125  for(std::vector<KinematicState>::const_iterator i = states.begin(); i != states.end(); i++)
00126  {
00127   AlgebraicMatrix el_part_e(2,3,0);
00128   TrackCharge ch = i->particleCharge();
00129   GlobalVector mom = i->globalMomentum();
00130   GlobalPoint pos =  i->globalPosition();
00131   double d_x = point.x() - pos.x();
00132   double d_y = point.y() - pos.y();
00133   double pt = mom.transverse();
00134   
00135   if(ch !=0 )
00136   {
00137 
00138 //charged particle
00139    double a_i = - ch * i->magneticField()->inInverseGeV(pos).z();
00140 
00141    double pvx = mom.x() - a_i*d_y;
00142    double pvy = mom.y() + a_i*d_x;
00143    double pvt = sqrt(pvx*pvx+pvy*pvy);
00144    double n = a_i*(d_x * mom.x() + d_y * mom.y());
00145    double m = (pvx*mom.x() + pvy*mom.y());
00146    double k = -mom.z()/(pvt*pvt*pt*pt);
00147 
00148 //E jacobian matrix
00149    el_part_e(1,1) = -(mom.y() + a_i*d_x);
00150    el_part_e(1,2) = mom.x() - a_i*d_y;
00151    el_part_e(2,1) = k*(m*mom.x() - n*mom.y());
00152    el_part_e(2,2) = k*(m*mom.y() + n*mom.x());
00153    el_part_e(2,3) = 1;
00154    jac_e.sub(2*num_r+1,1,el_part_e);
00155   }else{
00156 
00157 //neutral particle
00158    el_part_e(1,1) = - mom.y();
00159    el_part_e(1,2) = mom.x();
00160    el_part_e(2,1) = -mom.x()*mom.z()/(pt*pt);
00161    el_part_e(2,2) = -mom.y()*mom.z()/(pt*pt);
00162    el_part_e(2,3) = 1;
00163    jac_e.sub(2*num_r+1,1,el_part_e);
00164   }
00165   num_r++;
00166  }
00167  return jac_e;
00168 }
00169 
00170 int VertexKinematicConstraint::numberOfEquations() const
00171 {return 2;}