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