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
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
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
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
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
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
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
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
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
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
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;}