00001
00009 #include "jbltools/kinfit/JBLHelix.h"
00010 #include "jbltools/kinfit/ThreeVector.h"
00011 #include "jbltools/kinfit/TwoVector.h"
00012
00013 #include <cassert>
00014 #include <cmath>
00015
00016 JBLHelix::JBLHelix (double kappa,
00017 double phi0,
00018 double theta,
00019 double dca,
00020 double z0
00021 ) {
00022 setPar (0, kappa);
00023 setPar (1, phi0);
00024 setPar (2, theta);
00025 setPar (3, dca);
00026 setPar (4, z0);
00027 }
00028
00029 JBLHelix::JBLHelix (double par_[]) {
00030 for (int i = 0; i < NPAR; i++) setPar (i, par_[i]);
00031 }
00032
00033 JBLHelix::~JBLHelix()
00034 {}
00035
00036
00037 double JBLHelix::getPar (int i) {
00038 assert (i >= 0 && i < NPAR);
00039 return par[i];
00040 }
00041
00042 JBLHelix& JBLHelix::setPar (int i, double par_) {
00043 assert (i >= 0 && i < NPAR);
00044 par[i] = par_;
00045 return *this;
00046 }
00047
00048 int JBLHelix::getClosestApproach (const JBLHelix& h1,
00049 double& s0,
00050 double& s1,
00051 double& s02nd,
00052 double& s12nd
00053 ) const {
00054 if (std::abs(par[0]) > 1E-7 &&
00055 std::abs(h1.par[0]) > 1E-7) {
00056
00057 TwoVector cent0 = getCenterPoint();
00058 TwoVector cent1 = h1.getCenterPoint();
00059
00060
00061 double dist2 = (cent0-cent1).getMag2();
00062 double dist = std::sqrt(dist2);
00063 double r0 = 1/par[0];
00064 double r1 = 1/h1.par[0];
00065 double r0a = std::abs(r0);
00066 double r1a = std::abs(r1);
00067 s0 = s02nd = getClosestS (cent1);
00068 s1 = s12nd = h1.getClosestS (cent0);
00069 if (dist > r0a+r1a) return 0;
00070 if (dist == r0a+r1a) return 1;
00071 double psi0 = std::acos((r0*r0 + dist2 - r1*r1)/(2*r0a*dist));
00072 double psi1 = std::acos((r1*r1 + dist2 - r0*r0)/(2*r1a*dist));
00073 double s0try1 = getNormalS(s0 + r0*psi0);
00074 double s1try1 = h1.getNormalS(s1 - r1*psi1);
00075 double dz1 = std::abs(getTrajectoryZ(s0try1) - h1.getTrajectoryZ(s1try1));
00076 double s0try2 = getNormalS(s0 - r0*psi0);
00077 double s1try2 = h1.getNormalS(s1 + r1*psi1);
00078 double dz2 = std::abs(getTrajectoryZ(s0try2) - h1.getTrajectoryZ(s1try2));
00079
00080
00081
00082
00083
00084
00085
00086
00087 if (dz1 < dz2) {
00088 s0 = s0try1;
00089 s1 = s1try1;
00090 s02nd = s0try2;
00091 s12nd = s1try2;
00092 }
00093 else {
00094 s0 = s0try2;
00095 s1 = s1try2;
00096 s02nd = s0try1;
00097 s12nd = s1try1;
00098 }
00099 return 2;
00100 }
00101 else {
00102 assert (0);
00103 }
00104 }
00105
00106
00107 double JBLHelix::getClosestS (const TwoVector& p) const {
00108 if (std::abs (par[0]) < 1.e-8) {
00109
00110
00111
00112 double sphi0 = std::sin(par[1]);
00113 double cphi0 = std::cos(par[1]);
00114 double xc = sphi0*par[3];
00115 double yc = -cphi0*par[3];
00116 return (p.getX()-xc)*cphi0 + (p.getY()-yc)*sphi0;
00117 }
00118 else {
00119
00120 double r = 1/par[0];
00121 double dcamir = par[3] - r;
00122 double xc = dcamir*std::sin(par[1]);
00123 double yc = -dcamir*std::cos(par[1]);
00124 double psi = (r > 0) ?
00125 std::atan2(p.getX()-xc, -p.getY()+yc) - par[1] :
00126 std::atan2(p.getX()-xc, p.getY()-yc) + par[1];
00127
00128
00129 return getNormalS (std::abs(r)*psi);
00130 }
00131 }
00132
00133 double JBLHelix::getClosestS (const ThreeVector& p) const {
00134 return getClosestS (TwoVector (p.getX(), p.getY()));
00135 }
00136
00137 void JBLHelix::getTrajectoryPointEx (double s, ThreeVector& p ) const {
00138 double sphi0 = std::sin(par[1]);
00139 double cphi0 = std::cos(par[1]);
00140 double kappas = par[0]*s;
00141 if (std::abs (kappas) < 1.e-6) {
00142 double dcamikssq = par[3] - 0.5*kappas*s;
00143 p.setValues ( sphi0*dcamikssq + cphi0*s,
00144 -cphi0*dcamikssq + sphi0*s,
00145 par[4] + s*std::cos(par[2])/std::sin(par[2]));
00146 }
00147 else {
00148 double phi0plkappas = par[1] + kappas;
00149 double r = 1/par[0];
00150 double dcamir = par[3] - r;
00151 p.setValues ( dcamir*sphi0 + r*sin(phi0plkappas),
00152 -dcamir*cphi0 - r*cos(phi0plkappas),
00153 par[4] + s*std::cos(par[2])/std::sin(par[2]));
00154 }
00155 }
00156 double JBLHelix::getTrajectoryZ (double s) const {
00157 return par[4] + s*std::cos(par[2])/std::sin(par[2]);
00158 }
00159
00160 ThreeVector JBLHelix::getTrajectoryPoint (double s) const {
00161 ThreeVector result;
00162 getTrajectoryPointEx (s, result);
00163 return result;
00164 }
00165
00166 void JBLHelix::getCenterPointEx (TwoVector& p) const {
00167 double r = 1/par[0];
00168 double dcamir = par[3] - r;
00169 p.setValues ( dcamir*std::sin(par[1]), -dcamir*std::cos(par[1]));
00170 }
00171 TwoVector JBLHelix::getCenterPoint () const {
00172 TwoVector result;
00173 getCenterPointEx (result);
00174 return result;
00175 }
00176
00177 double JBLHelix::getNormalS (double s) const {
00178 double kappas = par[0]*s;
00179 if (kappas >= -M_PI &&kappas < M_PI) return s;
00180 return std::atan2 (std::sin(kappas), std::cos (kappas))/par[0];
00181 }