TrkPocaXY Class Reference

#include <TrkPocaXY.h>

Inheritance diagram for TrkPocaXY:

TrkPocaBase List of all members.

Public Member Functions

 TrkPocaXY (const Trajectory &traj, double flt, const HepPoint3D &pt, double precision=1.0e-4)
 TrkPocaXY (const Trajectory &traj1, double flt1, const Trajectory &traj2, double flt2, double precision=1.0e-4)
 ~TrkPocaXY ()
double docaXY () const
double fltl1 () const
double fltl2 () const
const TrkErrCodestatus () const
double flt1 () const
double flt2 () const
double precision ()

Protected Member Functions

void minimize (const Trajectory &traj1, double f1, const Trajectory &traj2, double f2)
void minimize (const Trajectory &traj1, double f1, const HepPoint3D &pt)
void stepTowardPoca (const Trajectory &traj1, const Trajectory &traj2)
void stepToPointPoca (const Trajectory &traj, const HepPoint3D &pt)

Protected Attributes

double _precision
double _flt1
double _flt2
TrkErrCode _status

Static Protected Attributes

static double _maxDist = 1.e7
static int _maxTry = 500
static double _extrapToler = 2.

Private Member Functions

void interLineCircle (const double &m, const double &q, const double &xc, const double &yc, const double &radius, double &xint1, double &yint1, double &xint2, double &yint2)
void interTwoLines (const double &m1, const double &q1, const double &m2, const double &q2, double &xint, double &yint)
void interTwoCircles (const double &xc1, const double &yc1, const double &r1, const double &xc2, const double &yc2, const double &r2, double &xint1, double &yint1, double &xint2, double &yint2)

Private Attributes

double _docaxy

Detailed Description

Definition at line 27 of file TrkPocaXY.h.


Constructor & Destructor Documentation

TrkPocaXY::TrkPocaXY ( const Trajectory traj,
double  flt,
const HepPoint3D pt,
double  precision = 1.0e-4 
)

Definition at line 23 of file TrkPocaXY.cxx.

References _docaxy, TrkPocaBase::_flt1, TrkPocaBase::_flt2, TrkPocaBase::_status, and TrkPocaBase::status().

00025   : TrkPocaBase(flt,prec) , _docaxy(-9999.0) {
00026 // construct a line trajectory through the given point
00027   Hep3Vector zaxis(0.0,0.0,1.0);
00028 // length is set to 200cm (shouldn't matter)
00029 //  TrkLineTraj zline(pt, zaxis, 200.0);//yzhang del
00030   TrkLineTraj zline(pt, zaxis, 2000.0);//yzhang change
00031 // create a 2-traj poca with this
00032   double zlen(pt.z());
00033   TrkPoca zlinepoca(traj,flt,zline,zlen,prec);
00034 // transfer over the data
00035   _status = zlinepoca.status();
00036   if(status().success()){
00037     _flt1 = zlinepoca.flt1();
00038     _flt2 = zlinepoca.flt2();
00039     _docaxy  = zlinepoca.doca(); // doca should be perpendicular to the zline so 2d by construction
00040   }
00041 }

TrkPocaXY::TrkPocaXY ( const Trajectory traj1,
double  flt1,
const Trajectory traj2,
double  flt2,
double  precision = 1.0e-4 
)

Definition at line 43 of file TrkPocaXY.cxx.

References _docaxy, TrkPocaBase::_flt1, TrkPocaBase::_flt2, TrkPocaBase::_status, Trajectory::curvature(), Trajectory::delDirect(), Trajectory::direction(), check_raw_filter::dist, TrkErrCode::failure(), TrkPocaBase::flt1(), interLineCircle(), interTwoCircles(), interTwoLines(), Trajectory::position(), q, TrkErrCode::setFailure(), TrkErrCode::setSuccess(), TrkPocaBase::status(), and TrkErrCode::success().

00046   : TrkPocaBase(flt1,flt2,prec) , _docaxy(-9999.0) {
00047 
00048   // this traj-traj version starts by approximating the trejectories as
00049   // either a line or a circle and treats separately the line-line, 
00050   // circle-circle, and line-circle cases.
00051 
00052   _flt1 = flt1;
00053   _flt2 = flt2;
00054   double delta1(10*prec);
00055   double delta2(10*prec);
00056   unsigned niter(0);
00057   static const unsigned maxiter(20);
00058   while(niter < maxiter && 
00059         ( delta1 > prec || delta2 > prec ) ){
00060     // get positions and directions
00061     HepPoint3D  pos1 = traj1.position(_flt1);
00062     HepPoint3D pos1b;
00063     if(niter == 0)  pos1b = pos1;
00064     HepPoint3D  pos2 = traj2.position(_flt2);
00065     Hep3Vector dir1 = traj1.direction(_flt1);
00066     Hep3Vector dir2 = traj2.direction(_flt2); 
00067     Hep3Vector dd1 = traj1.delDirect(_flt1);
00068     Hep3Vector dd2 = traj2.delDirect(_flt2);
00069     double curv1 = traj1.curvature(_flt1); 
00070     double curv2 = traj2.curvature(_flt2); 
00071     double m1, m2, q1, q2;
00072     double r1, r2, xc1,xc2,yc1,yc2,sr1,sr2;
00073     if(curv1 == 0) {
00074       // convert to m*x+q
00075       if(dir1[0] == 0){
00076         m1 = 1.0e12;
00077       }else{
00078         m1 = dir1[1]/dir1[0];
00079       }
00080       q1 = pos1.y()-pos1.x()*m1;
00081     }else{
00082     // get circle parameters
00083       r1 = (1- dir1[2]*dir1[2])/curv1;
00084       sr1=r1;
00085       if(dir1[0]*dd1[1] - dir1[1]*dd1[0] < 0) sr1 = -r1;
00086       double cosphi1 = dir1[0]/sqrt(dir1[0]*dir1[0]+dir1[1]*dir1[1]);
00087       double sinphi1 = cosphi1 * dir1[1]/dir1[0];
00088       xc1 = pos1.x() - sr1 * sinphi1;
00089       yc1 = pos1.y() + sr1 * cosphi1;
00090     }
00091     if(curv2 == 0) {
00092       if(dir2[0] == 0){
00093         m2 = 1.0e12;
00094       }else{ 
00095         m2 = dir2[1]/dir2[0];
00096       }
00097        q2 = pos2.y()-pos2.x()*m2;
00098     }else{
00099       r2 = (1-dir2[2]*dir2[2])/curv2;
00100       sr2 = r2;
00101       if(dir2[0]*dd2[1] - dir2[1]*dd2[0] < 0) sr2 = -r2;
00102       double cosphi2 = dir2[0]/sqrt(dir2[0]*dir2[0]+dir2[1]*dir2[1]);
00103       double sinphi2 = cosphi2 * dir2[1]/dir2[0];
00104       xc2 = pos2.x() - sr2 * sinphi2;
00105       yc2 = pos2.y() + sr2 * cosphi2;
00106     }
00107     double xint, yint, xint1, xint2, yint1, yint2, absdoca;
00108     _docaxy = 0;
00109     _status.setSuccess(3);
00110 
00111     // First the line-line case
00112 
00113     if(curv1==0 && curv2==0){
00114     // do the intersection in 2d
00115       interTwoLines(m1, q1, m2, q2, xint, yint);
00116     }
00117 
00118     //  next do the two circle case
00119 
00120     if(curv1 !=0 && curv2 !=0){
00121       //There are four cases
00122       double cdist = sqrt((xc1-xc2)*(xc1-xc2)+(yc1-yc2)*(yc1-yc2));
00123       // a - coincident centers
00124       if (fabs(cdist) < 1.e-12 ) {      
00125        //the algorithm fails because the points have all the same distance
00126         _status.setFailure(12, 
00127                   "TrkPocaXY:: the two circles have the same center...");
00128          return;
00129       }
00130      // b - Actual intersection
00131       if ( (fabs(r1-r2) < cdist) && (cdist < r1+r2 ) ) {      
00132         interTwoCircles(xc1,yc1,r1,xc2,yc2,r2,xint1,yint1,xint2,yint2);
00133         double dist1 = (xint1-pos1b.x())*(xint1-pos1b.x()) + 
00134                        (yint1-pos1b.y())*(yint1-pos1b.y());
00135         double dist2 = (xint2-pos1b.x())*(xint2-pos1b.x()) + 
00136                        (yint2-pos1b.y())*(yint2-pos1b.y());
00137 
00138         //choose closest to begining of track1
00139         if(dist1<dist2){
00140           xint = xint1;
00141           yint = yint1;
00142         } else {
00143           xint = xint2; 
00144           yint = yint2;
00145         }    
00146       }
00147 
00148     // c - nested circles and d - separated circles
00149 
00150       if ( (fabs(r1-r2) > cdist) ||  // nested circles
00151          (    cdist > (r1+r2) )) {   // separated circles
00152         // line going through the centers of the two circles
00153 
00154         double m = (yc1-yc2)/(xc1-xc2);  // y = m*x+q
00155         double q = yc1 - m*xc1;
00156 
00157         // intersection points between the line and the two circles
00158 
00159         double xint1, yint1, xint2, yint2, zOfDCrossT1;
00160 
00161         interLineCircle(m, q, xc1, yc1, r1, xint1, yint1, xint2, yint2);
00162 
00163         double xint3, yint3, xint4, yint4 ;
00164         interLineCircle(m, q, xc2, yc2, r2, xint3, yint3, xint4, yint4);
00165         if (fabs(r1-r2) > cdist) { // nested circles
00166           absdoca = fabs(r1-r2)-cdist;
00167 #ifdef MDCPATREC_DEBUG
00168           cout << "ErrMsg(debugging) doing nested circles in TrkPocaXY " << endl;
00169 #endif
00170 
00171           double dist1_3 = pow((xint1-xint3),2.) + pow((yint1-yint3),2.);
00172           double dist2_4 = pow((xint2-xint4),2.) + pow((yint2-yint4),2.);
00173 
00174           if(dist1_3<dist2_4) {
00175             xint = 0.5*(xint1+xint3);
00176             yint = 0.5*(yint1+yint3);
00177             zOfDCrossT1 = (xint3-xint1)*dir1[1]-(yint3-yint1)*dir1[0];
00178           } else {
00179             xint = 0.5*(xint2+xint4);
00180             yint = 0.5*(yint2+yint4);
00181             zOfDCrossT1 = (xint4-xint2)*dir1[1]-(yint4-yint2)*dir1[0];
00182           }  
00183           _docaxy = absdoca;
00184           if( zOfDCrossT1 > 0) _docaxy = -absdoca;   
00185         }
00186         if( cdist > (r1+r2) ) { //separated circles
00187           absdoca = cdist - (r1+r2);
00188 #ifdef MDCPATREC_DEBUG
00189           cout << "ErrMsg(debugging) doing separated circles in TrkPocaXY"<< endl;
00190 #endif
00191 
00192           double dist2_3 = pow((xint2-xint3),2.) + pow((yint2-yint3),2.);
00193           double dist1_4 = pow((xint1-xint4),2.) + pow((yint1-yint4),2.);
00194           if (dist2_3<dist1_4){
00195             xint = 0.5*(xint2+xint3);
00196             yint = 0.5*(yint2+yint3);
00197             zOfDCrossT1 = (xint3-xint1)*dir1[1]-(yint3-yint1)*dir1[0];
00198           } else {
00199             xint = 0.5*(xint1+xint4);
00200             yint = 0.5*(yint1+yint4);
00201             zOfDCrossT1 = (xint4-xint2)*dir1[1]-(yint4-yint2)*dir1[0];
00202           }
00203           _docaxy = absdoca;
00204           if( zOfDCrossT1 > 0) _docaxy = -absdoca;   
00205         }
00206       }
00207     }
00208 
00209     // Now do the line-circle case
00210 
00211     if((curv1 == 0 && curv2 !=0) || (curv1 != 0 && curv2 == 0)) {
00212   // distance between the line and the circle center
00213       HepVector dirT;
00214       double m,q,r,xc,yc, zOfDCrossT1;
00215       if(curv1==0) {m=m1; q=q1; r=r2; xc=xc2; yc=yc2; dirT=dir2;}
00216       else          {m=m2; q=q2; r=r1; xc=xc1; yc=yc1; dirT=dir1;}
00217 
00218       double dist = fabs((m*xc-yc+q)/sqrt(1+m*m));
00219       if(dist <= r) {
00220 
00221         // the intersection points
00222 
00223         interLineCircle(m,q,xc,yc,r, xint1, yint1, xint2, yint2);
00224         double dist1 = (xint1-pos1b.x())*(xint1-pos1b.x()) + 
00225                        (yint1-pos1b.y())*(yint1-pos1b.y());
00226         double dist2 = (xint2-pos1b.x())*(xint2-pos1b.x()) + 
00227                        (yint2-pos1b.y())*(yint2-pos1b.y());
00228         //choose closest to the beginning of track 1
00229         if(dist1<dist2){
00230           xint = xint1;
00231           yint = yint1;
00232         } else {
00233           xint = xint2;
00234           yint = yint2;
00235         }    
00236       } else { // no intersection points
00237 #ifdef MDCPATREC_DEBUG
00238         cout << "ErrMsg(debugging) doing separated line-circle in TrkPocaXY"<<endl;
00239 #endif
00240 
00241         // line going through the circle center and perpendicular to traj1
00242 
00243         double mperp = -1./m;
00244         double qperp = yc - mperp*xc;
00245 
00246         // intersection between this line and the two trajectories
00247 
00248         interLineCircle(mperp, qperp, xc, yc, r, xint1,yint1,xint2,yint2);
00249 
00250         double xint3,yint3;
00251         interTwoLines(m, q, mperp, qperp, xint3, yint3);
00252 
00253         double dist1_3 = pow((xint1-xint3),2.) + pow((yint1-yint3),2.);
00254         double dist2_3 = pow((xint2-xint3),2.) + pow((yint2-yint3),2.);
00255         if (dist1_3<dist2_3) {
00256           xint =  0.5*(xint3 + xint1);
00257           yint =  0.5*(yint3 + yint1);
00258           absdoca = sqrt((xint3-xint1)*(xint3-xint1)+
00259                          (yint3-yint1)*(yint3-yint1));
00260           zOfDCrossT1 = (xint3-xint1)*dirT[1]-(yint3-yint1)*dirT[0];
00261         }
00262         else {
00263           xint = 0.5*(xint3 + xint2);
00264           yint = 0.5*(yint3 + yint2);
00265           absdoca = sqrt((xint3-xint2)*(xint3-xint2)+
00266                          (yint3-yint2)*(yint3-yint2));
00267           zOfDCrossT1 = (xint3-xint2)*dirT[1]-(yint3-yint2)*dirT[0];
00268         }
00269          _docaxy = absdoca;
00270         if( zOfDCrossT1 > 0) _docaxy = -absdoca;   
00271       }
00272     }
00273 
00274     // get the flight lengths for the intersection point
00275 
00276     HepPoint3D intpt( xint, yint, 0.0);
00277     TrkPocaXY poca1(traj1,_flt1,intpt,prec);
00278     TrkPocaXY poca2(traj2,_flt2,intpt,prec);
00279     _status = poca2.status();
00280     if(poca1.status().success() && poca2.status().success()) {
00281        delta1 = fabs(_flt1 - poca1.flt1());
00282        delta2 = fabs(_flt2 - poca2.flt1());
00283        _flt1 = poca1.flt1();
00284        _flt2 = poca2.flt1(); 
00285     }else{
00286 #ifdef MDCPATREC_WARNING
00287       cout << "ErrMsg(warning)" << " poca fialure " << endl;
00288 #endif
00289       if(poca1.status().failure()) _status=poca1.status();
00290       break;
00291     }
00292     niter++;
00293   }
00294 #ifdef MDCPATREC_DEBUG
00295   cout <<"ErrMsg(debugging)" <<"TrkPocaXY iterations = " << niter-1 
00296        << "       flight lengths " << _flt1 <<" " << _flt2 << endl 
00297        << "       deltas " << delta1 <<"  " << delta2 << endl;
00298 #endif
00299   if(niter == maxiter){
00300 #ifdef MDCPATREC_ROUTINE
00301     cout << "ErrMsg(routine)" << "TrkPocaXY:: did not converge" << endl;
00302 #endif
00303     _status.setFailure(13, "TrkPocaXY:: did not converge"); 
00304   }
00305 }

TrkPocaXY::~TrkPocaXY (  )  [inline]

Definition at line 43 of file TrkPocaXY.h.

00043 {}


Member Function Documentation

double TrkPocaXY::docaXY (  )  const [inline]

Definition at line 73 of file TrkPocaXY.h.

References _docaxy.

00073 {return _docaxy;}

double TrkPocaBase::flt1 (  )  const [inline, inherited]

Definition at line 65 of file TrkPocaBase.h.

References TrkPocaBase::_flt1.

Referenced by TrkDifPieceTraj::append(), TrkPoca::calcDist(), TrkDifPoca::calcDist(), TrkSimpTraj::changePoint(), fltl1(), TrkSimpleRep::getAllWeights(), TrkCompTrk::getAllWeights(), TrkPocaBase::minimize(), TrkDifPieceTraj::prepend(), TrkPocaBase::stepToPointPoca(), TrkPocaBase::stepTowardPoca(), TrkPoca::TrkPoca(), TrkPocaXY(), and TrkHitOnTrk::updatePoca().

00065 {return _flt1;}

double TrkPocaBase::flt2 (  )  const [inline, inherited]

Definition at line 68 of file TrkPocaBase.h.

References TrkPocaBase::_flt2.

Referenced by TrkPoca::calcDist(), TrkDifPoca::calcDist(), MdcUtilitySvc::docaPatPar(), fltl2(), TrkPocaBase::minimize(), TrkPocaBase::stepTowardPoca(), and TrkHitOnTrk::updatePoca().

00068 {return _flt2;}

double TrkPocaXY::fltl1 (  )  const [inline]

Definition at line 49 of file TrkPocaXY.h.

References TrkPocaBase::flt1().

00049 { return flt1(); }

double TrkPocaXY::fltl2 (  )  const [inline]

Definition at line 50 of file TrkPocaXY.h.

References TrkPocaBase::flt2().

00050 { return flt2(); }

void TrkPocaXY::interLineCircle ( const double &  m,
const double &  q,
const double &  xc,
const double &  yc,
const double &  radius,
double &  xint1,
double &  yint1,
double &  xint2,
double &  yint2 
) [private]

Definition at line 308 of file TrkPocaXY.cxx.

References TrkPocaBase::_status, alpha, and TrkErrCode::setFailure().

Referenced by TrkPocaXY().

00313 {
00314 
00315  double alpha = 1 + m*m;
00316 
00317  double beta = -xc +m*(q-yc);
00318 
00319  double gamma = xc*xc + (q-yc)*(q-yc) -r*r;
00320 
00321  double Delta = beta*beta - alpha*gamma;
00322 
00323  if (Delta < 0) {
00324 
00325     _status.setFailure(14,
00326               "TrkPocaXY:: the line and the circle heve no intersections...");
00327     return;
00328 
00329   }
00330   else if (fabs(Delta) <1.e-12) {
00331 
00332   xint1 = -beta/alpha;
00333   xint2 = xint1;
00334 
00335   }
00336   else {
00337 
00338     double xPlus = -beta/alpha + sqrt(beta*beta - alpha*gamma)/alpha;
00339     double xMinus = -beta/alpha - sqrt(beta*beta - alpha*gamma)/alpha;
00340 
00341     if (xPlus > xMinus) {
00342       xint1 = xMinus;
00343       xint2 = xPlus;
00344     }
00345     else {
00346       xint1 = xPlus;
00347       xint2 = xMinus;
00348     }
00349   }
00350  yint1 = m*xint1 + q;
00351  yint2 = m*xint2 + q;
00352 
00353  return;
00354 }

void TrkPocaXY::interTwoCircles ( const double &  xc1,
const double &  yc1,
const double &  r1,
const double &  xc2,
const double &  yc2,
const double &  r2,
double &  xint1,
double &  yint1,
double &  xint2,
double &  yint2 
) [private]

Definition at line 358 of file TrkPocaXY.cxx.

References EvtCyclic3::A, alpha, EvtCyclic3::B, and EvtCyclic3::C.

Referenced by TrkPocaXY().

00362 {
00363 
00364   double A = (xc1*xc1 + yc1*yc1 - r1*r1) - (xc2*xc2 + yc2*yc2 - r2*r2);
00365 
00366   double B = -xc1 + xc2;
00367 
00368   double C = -yc1 + yc2;
00369 
00370   double alpha = 1 + (B*B)/(C*C);
00371 
00372   double beta = -xc1 + B/C*(yc1+A/(2*C));
00373 
00374   double gamma = xc1*xc1 + (yc1+A/(2*C))*(yc1+A/(2*C)) - r1*r1;
00375 
00376   double Delta = beta*beta - alpha*gamma;
00377 
00378   if (Delta < 0) {
00379 
00380     _status.setFailure(14, "TrkPocaXY:: the two circles have no intersections..\
00381 .");
00382     return;
00383 
00384   }
00385   else if (fabs(Delta) <1.e-12) {
00386 
00387     xint1 = -beta/alpha;
00388     xint2 = xint1;
00389 
00390   }
00391   else {
00392     double xPlus = -beta/alpha + sqrt(beta*beta - alpha*gamma)/alpha;
00393     double xMinus = -beta/alpha - sqrt(beta*beta - alpha*gamma)/alpha;
00394 
00395     if (xPlus > xMinus) {
00396       xint1 = xMinus;
00397       xint2 = xPlus;
00398     }
00399     else {
00400       xint1 = xPlus;
00401       xint2 = xMinus;
00402     }
00403 
00404   }
00405 
00406   yint1 = -(A+2*B*xint1)/(2*C);
00407   yint2 = -(A+2*B*xint2)/(2*C);
00408 
00409 
00410   return;
00411 }

void TrkPocaXY::interTwoLines ( const double &  m1,
const double &  q1,
const double &  m2,
const double &  q2,
double &  xint,
double &  yint 
) [private]

Definition at line 416 of file TrkPocaXY.cxx.

Referenced by TrkPocaXY().

00419 {
00420 
00421   if (fabs(m1-m2) < 1.e-12) {  // parallel lines
00422 
00423     //the algorithm fails because the points have all the same distance
00424 
00425     _status.setFailure(13, "TrkPocaXY:: the two lines are parallel...");
00426     return;
00427   }
00428   else { // the lines have an intersection point
00429 
00430     xint = (q2-q1)/(m1-m2);
00431     yint = m1*xint + q1;
00432   }
00433 
00434 return;
00435 }

void TrkPocaBase::minimize ( const Trajectory traj1,
double  f1,
const HepPoint3D pt 
) [protected, inherited]

Definition at line 120 of file TrkPocaBase.cxx.

References TrkPocaBase::_flt1, TrkPocaBase::_maxTry, TrkPocaBase::_status, Trajectory::distTo1stError(), TrkPocaBase::flt1(), genRecEmupikp::i, Trajectory::position(), TrkPocaBase::precision(), TrkErrCode::setFailure(), TrkPocaBase::status(), TrkPocaBase::stepToPointPoca(), and TrkErrCode::succeed.

00122 {
00123    _status=TrkErrCode::succeed;
00124   _flt1 = f1;
00125   int pathDir = 1;  // which way are we stepping (+/- 1)
00126 
00127   int nTinyStep = 0;  // number of consecutive tiny steps -- oscillation test
00128   int nOscills = 0;
00129   double fltLast = 0., fltBeforeLast = 0.; // another check for oscillation
00130   for (int i = 0; i < _maxTry; i++) {
00131     fltLast = flt1();
00132     stepToPointPoca(traj, pt);
00133     if (status().failure()) return;
00134     double step = flt1() - fltLast;
00135     pathDir = (step > 0.) ? 1 : -1;
00136     // Can we stop stepping?
00137     double distToErr = traj.distTo1stError(fltLast, precision(), pathDir);
00138     bool mustStep = (fabs(step) > distToErr && step != 0.);
00139     // Crude test for oscillation (around cusp point of piecewise traj, I hope)
00140     if (fabs(step) < 0.5 * precision()) {
00141       nTinyStep++;
00142     } else {
00143       nTinyStep = 0;
00144       if (i > 1) {
00145         if (fabs(step) >= fabs(fltBeforeLast-fltLast) &&
00146             fabs(fltBeforeLast-flt1()) <= fabs(step)) {
00147           nOscills++;
00148           double halfway = (fltBeforeLast + fltLast) / 2.;
00149           if ((traj.position(flt1()) - pt).mag() >
00150               (traj.position(halfway) - pt).mag()) _flt1 = halfway;
00151         }
00152       }
00153     }
00154     if (nTinyStep > 3) mustStep = false;
00155     if (nOscills > 2) {
00156       mustStep = false;
00157 #ifdef MDCPATREC_WARNING
00158       std::cout<<" ErrMsg(warning) "<< "Alleged oscillation detected. "
00159               << step << "  " << fltLast-fltBeforeLast
00160               << "  " << i << "  " << std::endl;
00161 #endif
00162     }
00163     if (!mustStep) return;
00164     fltBeforeLast = fltLast;
00165   }
00166   // Ran off the end of the loop
00167   _status.setFailure(2);
00168 }

void TrkPocaBase::minimize ( const Trajectory traj1,
double  f1,
const Trajectory traj2,
double  f2 
) [protected, inherited]

Definition at line 32 of file TrkPocaBase.cxx.

References TrkPocaBase::_flt1, TrkPocaBase::_flt2, TrkPocaBase::_maxTry, TrkPocaBase::_status, Trajectory::distTo1stError(), false, TrkPocaBase::flt1(), TrkPocaBase::flt2(), Trajectory::position(), TrkPocaBase::precision(), TrkErrCode::setFailure(), TrkErrCode::setSuccess(), TrkPocaBase::status(), TrkPocaBase::stepTowardPoca(), TrkErrCode::succeed, and true.

Referenced by TrkDifPoca::TrkDifPoca(), and TrkPoca::TrkPoca().

00034 {
00035   // Last revision: Jan 2003, WDH
00036   const int maxnOscillStep = 5 ;
00037   const int maxnDivergingStep = 5 ;
00038 
00039   // initialize
00040   _status = TrkErrCode::succeed;
00041   _flt1 = f1;
00042   _flt2 = f2;
00043   
00044   static HepPoint3D newPos1, newPos2 ;
00045   double delta(0), prevdelta(0) ;
00046   int nOscillStep(0) ;
00047   int nDivergingStep(0) ;
00048   bool finished = false ;
00049   int istep(0) ;
00050 
00051   for (istep=0; istep < _maxTry && !finished; ++istep) {
00052     double prevflt1  = flt1();
00053     double prevflt2  = flt2() ;
00054     double prevprevdelta = prevdelta ;
00055     prevdelta = delta;
00056     
00057     stepTowardPoca(traj1, traj2);
00058     if( status().failure() ) {
00059       // failure in stepTowardPoca
00060       finished=true ;
00061     } else {
00062       newPos1 = traj1.position(flt1());
00063       newPos2 = traj2.position(flt2());
00064       delta = (newPos1 - newPos2).mag();
00065       double step1 = flt1() - prevflt1;
00066       double step2 = flt2() - prevflt2;
00067       int pathDir1 = (step1 > 0.) ? 1 : -1;
00068       int pathDir2 = (step2 > 0.) ? 1 : -1;
00069       
00070       // Can we stop stepping?
00071       double distToErr1 = traj1.distTo1stError(prevflt1, precision(), pathDir1);
00072       double distToErr2 = traj2.distTo1stError(prevflt2, precision(), pathDir2);
00073       
00074       // converged if very small steps, or if parallel
00075       finished = 
00076         (fabs(step1) < distToErr1 && fabs(step2) < distToErr2 ) ||
00077         (status().success() == 3) ;
00078  
00079       // we have to catch some problematic cases
00080       if( !finished && istep>2 && delta > prevdelta) {
00081         if( prevdelta > prevprevdelta) {
00082           // diverging
00083           if(++nDivergingStep>maxnDivergingStep) { 
00084             _status.setFailure(2) ; // code for `Failed to converge'
00085             finished = true ;
00086           }
00087         } else {
00088           nDivergingStep=0;
00089           // oscillating
00090           if(++nOscillStep>maxnOscillStep) {
00091             // bail out of oscillation. since the previous step was
00092             // better, use that one.
00093             _flt1 = prevflt1 ;
00094             _flt2 = prevflt2 ;
00095             _status.setSuccess(21, "Oscillating poca.") ;
00096             finished = true ;
00097           } else {
00098             // we might be oscillating, but we could also just have
00099             // stepped over the minimum. choose a solution `in
00100             // between'.
00101             _flt1 = prevflt1 + 0.5*step1 ;
00102             _flt2 = prevflt2 + 0.5*step2 ;          
00103             newPos1 = traj1.position(_flt1) ;
00104             newPos2 = traj2.position(_flt2) ;
00105             delta = (newPos1 - newPos2).mag() ;
00106           }
00107         }
00108       } 
00109     }
00110   }
00111   if(!finished) _status.setSuccess(2) ; // code for 'not converged' (yet)
00112 }

double TrkPocaBase::precision (  )  [inline, inherited]

Definition at line 59 of file TrkPocaBase.h.

References TrkPocaBase::_precision.

Referenced by TrkDifPoca::calcDist(), TrkPocaBase::minimize(), and TrkPocaBase::stepToPointPoca().

00059 {return _precision;}

const TrkErrCode & TrkPocaBase::status (  )  const [inline, inherited]

Definition at line 62 of file TrkPocaBase.h.

References TrkPocaBase::_status.

Referenced by TrkDifPieceTraj::append(), TrkPoca::calcDist(), TrkDifPoca::calcDist(), TrkSimpTraj::changePoint(), MdcHitOnTrack::dcaToWire(), TrkHitOnTrk::getFitStuff(), TrkPocaBase::minimize(), TrkDifPieceTraj::prepend(), TrkDifPoca::TrkDifPoca(), TrkPoca::TrkPoca(), TrkPocaXY(), and TrkHitOnTrk::updatePoca().

00062 {return _status;}

void TrkPocaBase::stepToPointPoca ( const Trajectory traj,
const HepPoint3D pt 
) [protected, inherited]

Definition at line 250 of file TrkPocaBase.cxx.

References TrkPocaBase::_extrapToler, TrkPocaBase::_flt1, TrkPocaBase::_maxDist, TrkPocaBase::_status, Trajectory::distTo2ndError(), TrkPocaBase::flt1(), Trajectory::getInfo(), TrkPocaBase::precision(), and TrkErrCode::setFailure().

Referenced by TrkPocaBase::minimize().

00251 {
00252   // Unsightly uninitialized variables:
00253   static Hep3Vector dir, delDir;
00254   static HepPoint3D trajPos;
00255 
00256   traj.getInfo(flt1(), trajPos, dir, delDir);
00257   Hep3Vector delta = ((CLHEP::Hep3Vector)trajPos) - ((CLHEP::Hep3Vector)pt);
00258   double denom = 1. + delta.dot(delDir);
00259   if (fabs(denom)*_maxDist < 1. ) {
00260     _status.setFailure(11, "TrkPoca::ambiguous tight looper.");
00261     return;
00262   }
00263   double df = -delta.dot(dir) / fabs(denom);
00264   int pathDir = (df > 0.) ? 1 : -1;
00265 
00266   // Don't try going farther than worst parabolic approximation will allow:
00267   double distToErr = traj.distTo2ndError(flt1(), _extrapToler, pathDir);
00268   if (fabs(df)>distToErr) df = (df>0?distToErr:-distToErr);
00269   // Make the step slightly longer -- prevents quitting at kinks
00270   df += 0.001 * pathDir * precision();
00271   _flt1 += df;
00272 }

void TrkPocaBase::stepTowardPoca ( const Trajectory traj1,
const Trajectory traj2 
) [protected, inherited]

Definition at line 176 of file TrkPocaBase.cxx.

References TrkPocaBase::_extrapToler, TrkPocaBase::_flt1, TrkPocaBase::_flt2, TrkPocaBase::_maxDist, TrkPocaBase::_status, Trajectory::distTo2ndError(), TrkPocaBase::flt1(), TrkPocaBase::flt2(), Trajectory::getInfo(), and TrkErrCode::setSuccess().

Referenced by TrkPocaBase::minimize().

00177 { 
00178   // Last revision: Jan 2003, WDH
00179   
00180   // A bunch of unsightly uninitialized variables:
00181   static Hep3Vector dir1, dir2;
00182   static Hep3Vector delDir1, delDir2;
00183   static HepPoint3D pos1, pos2;
00184 
00185   traj1.getInfo(flt1(), pos1, dir1, delDir1);
00186   traj2.getInfo(flt2(), pos2, dir2, delDir2);
00187   Hep3Vector delta = ((CLHEP::Hep3Vector)pos1) - ((CLHEP::Hep3Vector)pos2);
00188   double ua = -delta.dot(dir1);
00189   double ub =  delta.dot(dir2);
00190   double caa = dir1.mag2() + delta.dot(delDir1);
00191   double cbb = dir2.mag2() - delta.dot(delDir2);
00192   double cab = -dir1.dot(dir2);
00193   double det = caa * cbb - cab * cab;
00194 
00195   if(det<0) {
00196     // get rid of second order terms
00197     caa = dir1.mag2() ;
00198     cbb = dir2.mag2() ;
00199     det = caa * cbb - cab * cab;
00200   }
00201           
00202   if ( det < 1.e-8) {
00203     // If they are parallel (in quadratic approximation) give up
00204     _status.setSuccess(3);
00205     return;
00206   }
00207 
00208   double df1 = (ua * cbb - ub * cab)/det;
00209   int pathDir1 = (df1 > 0) ? 1 : -1;
00210   double df2 = (ub * caa - ua * cab)/det;
00211   int pathDir2 = (df2 > 0) ? 1 : -1;
00212 
00213   // Don't try going farther than worst parabolic approximation will
00214   // allow: Since ` _extrapToler' is large, this cut effectively only
00215   // takes care that we don't make large jumps past the kink in a
00216   // piecewise trajectory.
00217 
00218   double distToErr1 = traj1.distTo2ndError(flt1(), _extrapToler, pathDir1);
00219   double distToErr2 = traj2.distTo2ndError(flt2(), _extrapToler, pathDir2);
00220 
00221   // Factor to push just over border of piecewise traj (essential!)
00222   const double smudge = 1.01 ; 
00223   if( fabs(df1) > smudge*distToErr1 ) {
00224     // choose solution for which df1 steps just over border
00225     df1 = smudge*distToErr1 * pathDir1 ;
00226     // now recalculate df2, given df1:
00227     df2 = (ub - df1*cab)/cbb ;
00228   }
00229 
00230   if( fabs(df2) > smudge*distToErr2 ) {
00231     // choose solution for which df2 steps just over border
00232     df2 = smudge*distToErr2 * pathDir2 ;
00233     // now recalculate df1, given df2:
00234     df1 = (ua - df2*cab)/cbb ;
00235     // if still not okay,
00236     if( fabs(df1) > smudge*distToErr1 ) {
00237       df1 = smudge*distToErr1 * pathDir1 ;
00238     }
00239   }
00240 
00241   _flt1 += df1;
00242   _flt2 += df2;
00243 
00244   // another check for parallel trajectories
00245   if (fabs(flt1()) > _maxDist && fabs(flt2()) > _maxDist) 
00246     _status.setSuccess(3) ;
00247 }


Member Data Documentation

double TrkPocaXY::_docaxy [private]

Definition at line 54 of file TrkPocaXY.h.

Referenced by docaXY(), and TrkPocaXY().

double TrkPocaBase::_extrapToler = 2. [static, protected, inherited]

Definition at line 54 of file TrkPocaBase.h.

Referenced by TrkPocaBase::stepToPointPoca(), and TrkPocaBase::stepTowardPoca().

double TrkPocaBase::_flt1 [protected, inherited]

Definition at line 40 of file TrkPocaBase.h.

Referenced by TrkPocaBase::flt1(), TrkPocaBase::minimize(), TrkPocaBase::stepToPointPoca(), TrkPocaBase::stepTowardPoca(), and TrkPocaXY().

double TrkPocaBase::_flt2 [protected, inherited]

Definition at line 41 of file TrkPocaBase.h.

Referenced by TrkPocaBase::flt2(), TrkPocaBase::minimize(), TrkPocaBase::stepTowardPoca(), and TrkPocaXY().

double TrkPocaBase::_maxDist = 1.e7 [static, protected, inherited]

Definition at line 52 of file TrkPocaBase.h.

Referenced by TrkPocaBase::stepToPointPoca(), and TrkPocaBase::stepTowardPoca().

int TrkPocaBase::_maxTry = 500 [static, protected, inherited]

Definition at line 53 of file TrkPocaBase.h.

Referenced by TrkPocaBase::minimize().

double TrkPocaBase::_precision [protected, inherited]

Definition at line 39 of file TrkPocaBase.h.

Referenced by TrkPocaBase::precision().

TrkErrCode TrkPocaBase::_status [protected, inherited]

Definition at line 42 of file TrkPocaBase.h.

Referenced by TrkDifPoca::calcDist(), interLineCircle(), TrkPocaBase::minimize(), TrkPocaBase::status(), TrkPocaBase::stepToPointPoca(), TrkPocaBase::stepTowardPoca(), and TrkPocaXY().


Generated on Tue Nov 29 23:36:15 2016 for BOSS_7.0.2 by  doxygen 1.4.7