Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members

JBLHelix.C

Go to the documentation of this file.
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     // We really have two helices, i.e. circles in (x, y)
00057     TwoVector cent0 = getCenterPoint();
00058     TwoVector cent1 = h1.getCenterPoint();
00059     // std::cout << "cent0=" << cent0 << ", cent1=" << cent1 << "\n";
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     // std::cout << "s0try1=" << s0try1 << "=>" << getTrajectoryPoint (s0try1)
00081     //           << ", s1try1=" << s1try1 << "=>" << h1.getTrajectoryPoint (s1try1) 
00082     //           << ". dz1 = " << dz1 << "\n";
00083     // std::cout << "s0try2=" << s0try2 << "=>" << getTrajectoryPoint (s0try2)
00084     //           << ", s1try2=" << s1try2 << "=>" << h1.getTrajectoryPoint (s1try2) 
00085     //           << ". dz2 = " << dz2 << "\n";
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     // If helix is almost a straight line,
00110     // treat it as straight line here.
00111     // Get point of closest approach to origin
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     // Get center of circle
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     // if (psi < -M_PI) psi += 2*M_PI;
00128     // else if (psi > M_PI) psi -= 2*M_PI;
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 }

Generated on Fri Sep 14 17:38:21 2007 for Kinfit by doxygen 1.3.2