00001 #include "RecoVertex/KinematicFit/interface/ColinearityKinematicConstraint.h"
00002 #include "RecoVertex/VertexPrimitives/interface/VertexException.h"
00003
00004 ColinearityKinematicConstraint::ColinearityKinematicConstraint(ConstraintDim dim)
00005 {
00006 dimension = dim;
00007 if (dimension == Phi) size = 1;
00008 else size = 2;
00009 }
00010
00011 AlgebraicVector ColinearityKinematicConstraint::value(const std::vector<KinematicState> states,
00012 const GlobalPoint& point) const
00013 {
00014 if(states.size()<2) throw VertexException("ColinearityKinematicConstraint::<2 states passed");
00015 AlgebraicVector res(size,0);
00016
00017 double a_1 = -states[0].particleCharge()*states[0].magneticField()->inInverseGeV(states[0].globalPosition()).z();
00018 double a_2 = -states[1].particleCharge()*states[1].magneticField()->inInverseGeV(states[1].globalPosition()).z();
00019
00020 AlgebraicVector7 p1 = states[0].kinematicParameters().vector();
00021 AlgebraicVector7 p2 = states[1].kinematicParameters().vector();
00022
00023 double p1vx = p1(3) - a_1*(point.y() - p1(1));
00024 double p1vy = p1(4) + a_1*(point.x() - p1(0));
00025 double pt1 = sqrt(p1(3)*p1(3)+p1(4)*p1(4));
00026
00027 double p2vx = p2(3) - a_2*(point.y() - p2(1));
00028 double p2vy = p2(4) + a_2*(point.x() - p2(0));
00029 double pt2 = sqrt(p2(3)*p2(3)+p2(4)*p2(4));
00030
00031
00032 res(1) = atan2(p1vy,p1vx) - atan2(p2vy,p2vx);
00033 if ( res(1) > M_PI ) res(1) -= 2.0*M_PI;
00034 if ( res(1) <= -M_PI ) res(1) += 2.0*M_PI;
00035
00036 if (dimension == PhiTheta) {
00037 res(2) = atan2(pt1,p1(5)) - atan2(pt2,p2(5));
00038 if ( res(2) > M_PI ) res(2) -= 2.0*M_PI;
00039 if ( res(2) <= -M_PI ) res(2) += 2.0*M_PI;
00040 }
00041
00042
00043
00044 return res;
00045 }
00046
00047 AlgebraicMatrix ColinearityKinematicConstraint::parametersDerivative(const std::vector<KinematicState> states,
00048 const GlobalPoint& point) const
00049 {
00050 int n_st = states.size();
00051 if(n_st<2) throw VertexException("ColinearityKinematicConstraint::<2 states passed");
00052 AlgebraicMatrix res(size,n_st*7,0);
00053
00054 double a_1 = -states[0].particleCharge()*states[0].magneticField()->inInverseGeV(states[0].globalPosition()).z();
00055 double a_2 = -states[1].particleCharge()*states[1].magneticField()->inInverseGeV(states[1].globalPosition()).z();
00056
00057 AlgebraicVector7 p1 = states[0].kinematicParameters().vector();
00058 AlgebraicVector7 p2 = states[1].kinematicParameters().vector();
00059
00060 double p1vx = p1(3) - a_1*(point.y() - p1(1));
00061 double p1vy = p1(4) + a_1*(point.x() - p1(0));
00062 double k1 = 1.0/(p1vx*p1vx + p1vy*p1vy);
00063 double pt1 = sqrt(p1(3)*p1(3)+p1(4)*p1(4));
00064 double pTot1 = sqrt(p1(3)*p1(3)+p1(4)*p1(4)+p1(5)*p1(5));
00065
00066 double p2vx = p2(3) - a_2*(point.y() - p2(1));
00067 double p2vy = p2(4) + a_2*(point.x() - p2(0));
00068 double k2 = 1.0/(p2vx*p2vx + p2vy*p2vy);
00069 double pt2 = sqrt(p2(3)*p2(3)+p2(4)*p2(4));
00070 double pTot2 = sqrt(p2(3)*p2(3)+p2(4)*p2(4)+p2(5)*p2(5));
00071
00072
00073
00074
00075 res(1,1) = -k1*a_1*p1vx;
00076 res(1,8) = k2*a_2*p2vx;
00077
00078
00079 res(1,2) = -k1*a_1*p1vy;
00080 res(1,9) = k2*a_2*p2vy;
00081
00082
00083 res(1,3) = 0.; res(1,10) = 0.;
00084
00085
00086 res(1,4) = -k1*p1vy;
00087 res(1,11) = k2*p2vy;
00088
00089
00090 res(1,5) = k1*p1vx;
00091 res(1,12) = -k2*p2vx;
00092
00093
00094
00095 res(1,6) = 0.; res(1,13) = 0.;
00096
00097 res(1,7) = 0.; res(1,14) = 0.;
00098
00099 if (dimension == PhiTheta) {
00100
00101
00102 res(2,1) = 0.; res(2,8) = 0.;
00103
00104
00105 res(2,2) = 0.; res(2,9) = 0.;
00106
00107
00108 res(2,3) = 0.; res(2,10) = 0.;
00109
00110 res(2,4) = p1(5)*p1(3) / (pTot1*pTot1*pt1);
00111 res(2,11) = - p2(5)*p2(3) / (pTot2*pTot2*pt2);
00112
00113
00114 res(2,5) = p1(5)*p1(4) / (pTot1*pTot1*pt1);
00115 res(2,12) = - p2(5)*p2(4) / (pTot2*pTot2*pt2);
00116
00117
00118 res(2,6) = - pt1/(pTot1*pTot1);
00119 res(2,13) = pt2/(pTot2*pTot2);
00120
00121 res(2,7) = 0.; res(2,14) = 0.;
00122 }
00123
00124 return res;
00125 }
00126
00127 AlgebraicMatrix ColinearityKinematicConstraint::positionDerivative(const std::vector<KinematicState> states,
00128 const GlobalPoint& point) const
00129 {
00130 AlgebraicMatrix res(size,3,0);
00131 if(states.size()<2) throw VertexException("ColinearityKinematicConstraint::<2 states passed");
00132
00133 double a_1 = -states[0].particleCharge() * states[0].magneticField()->inInverseGeV(states[0].globalPosition()).z();
00134 double a_2 = -states[1].particleCharge() * states[1].magneticField()->inInverseGeV(states[1].globalPosition()).z();
00135
00136 AlgebraicVector7 p1 = states[0].kinematicParameters().vector();
00137 AlgebraicVector7 p2 = states[1].kinematicParameters().vector();
00138
00139 double p1vx = p1(3) - a_1*(point.y() - p1(1));
00140 double p1vy = p1(4) + a_1*(point.x() - p1(0));
00141 double k1 = 1.0/(p1vx*p1vx + p1vy*p1vy);
00142
00143
00144 double p2vx = p2(3) - a_2*(point.y() - p2(1));
00145 double p2vy = p2(4) + a_2*(point.x() - p2(0));
00146 double k2 = 1.0/(p2vx*p2vx + p2vy*p2vy);
00147
00148
00149
00150
00151
00152 res(1,1) = k1*a_1*p1vx - k2*a_2*p2vx;
00153
00154
00155 res(1,2) = k1*a_1*p1vy - k2*a_2*p2vy;
00156
00157
00158 res(1,3) = 0.;
00159
00160
00161 if (dimension == PhiTheta) {
00162 res(2,1) = 0.;
00163 res(2,2) = 0.;
00164 res(2,3) = 0.;
00165 }
00166
00167 return res;
00168 }