#include <TrkPocaXY.h>
Inheritance diagram for TrkPocaXY:
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 TrkErrCode & | status () 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 |
Definition at line 27 of file TrkPocaXY.h.
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] |
double TrkPocaXY::docaXY | ( | ) | const [inline] |
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] |
double TrkPocaXY::fltl2 | ( | ) | const [inline] |
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 }
double TrkPocaXY::_docaxy [private] |
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] |
double TrkPocaBase::_precision [protected, inherited] |
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().