26 #include "FtfBaseTrack.h"
28 #include "FtfGeneral.h"
33 void ftfMatrixDiagonal (
double *h,
double &h11,
double &h22,
double &h33 ) ;
38 FtfBaseTrack::FtfBaseTrack ( ){
45 int FtfBaseTrack::fitHelix ( )
72 int FtfBaseTrack::fitCircle ( )
80 for ( startLoop() ; done() ; nextHit() ) {
83 cHit->wxy = 1.0F/ (double)(cHit->dx*cHit->dx + cHit->dy*cHit->dy) ;
85 xav += cHit->wxy * cHit->x ;
86 yav += cHit->wxy * cHit->y ;
88 if ( getPara()->vertexConstrainedFit ) {
89 wsum += getPara()->xyWeightVertex ;
90 xav += getPara()->xVertex ;
91 yav += getPara()->yVertex ;
103 for ( startLoop() ; done() ; nextHit() ) {
107 xxav += xi * xi * cHit->wxy ;
108 xyav += xi * yi * cHit->wxy ;
109 yyav += yi * yi * cHit->wxy ;
111 if ( getPara()->vertexConstrainedFit ) {
112 xi = getPara()->xVertex - xav ;
113 yi = getPara()->yVertex - yav ;
114 xxav += xi * xi * getPara()->xyWeightVertex ;
115 xyav += xi * yi * getPara()->xyWeightVertex ;
116 yyav += yi * yi * getPara()->xyWeightVertex ;
128 double a = fabs( xxav - yyav ) ;
129 double b = 4.0 * xyav * xyav ;
131 double asqpb = a * a + b ;
132 double rasqpb = sqrt ( asqpb) ;
134 double splus = 1.0 + a / rasqpb ;
135 double sminus = b / (asqpb * splus) ;
137 splus = sqrt (0.5 * splus ) ;
138 sminus = sqrt (0.5 * sminus) ;
142 double sinrot, cosrot ;
143 if ( xxav <= yyav ) {
154 if ( xyav < 0.0 ) sinrot = - sinrot ;
163 if ( cosrot*xav+sinrot*yav < 0.0 ) {
170 double rrav = xxav + yyav ;
171 double rscale = sqrt(rrav) ;
178 double rrrrav = 0.0 ;
180 double xixi, yiyi, riri, wiriri, xold, yold ;
181 for ( startLoop() ; done() ; nextHit() ) {
183 xold = cHit->x - xav ;
184 yold = cHit->y - yav ;
188 xi = ( cosrot * xold + sinrot * yold ) / rscale ;
189 yi = ( -sinrot * xold + cosrot * yold ) / rscale ;
194 wiriri = cHit->wxy * riri ;
196 xyav += cHit->wxy * xi * yi ;
197 xxav += cHit->wxy * xixi ;
198 yyav += cHit->wxy * yiyi ;
200 xrrav += wiriri * xi ;
201 yrrav += wiriri * yi ;
202 rrrrav += wiriri * riri ;
207 if ( getPara()->vertexConstrainedFit ) {
208 xold = getPara()->xVertex - xav ;
209 yold = getPara()->yVertex - yav ;
213 xi = ( cosrot * xold + sinrot * yold ) / rscale ;
214 yi = ( -sinrot * xold + cosrot * yold ) / rscale ;
219 wiriri = getPara()->xyWeightVertex * riri ;
221 xyav += getPara()->xyWeightVertex * xi * yi ;
222 xxav += getPara()->xyWeightVertex * xixi ;
223 yyav += getPara()->xyWeightVertex * yiyi ;
225 xrrav += wiriri * xi ;
226 yrrav += wiriri * yi ;
227 rrrrav += wiriri * riri ;
236 xrrav = xrrav / wsum ;
237 yrrav = yrrav / wsum ;
238 rrrrav = rrrrav / wsum ;
246 double xrrxrr = xrrav * xrrav ;
247 double yrryrr = yrrav * yrrav ;
248 double rrrrm1 = rrrrav - 1.0 ;
249 double xxyy = xxav * yyav ;
251 double c0 = rrrrm1*xxyy - xrrxrr*yyav - yrryrr*xxav ;
252 double c1 = - rrrrm1 + xrrxrr + yrryrr - 4.0*xxyy ;
253 double c2 = 4.0 + rrrrm1 - 4.0*xxyy ;
258 double c2d = 2.0 * c2 ;
259 double c4d = 4.0 * c4 ;
265 double dlamda = 0.0 ;
267 double chiscl = wsum * rscale * rscale ;
268 double dlamax = 0.001 / chiscl ;
271 for (
int itry = 1 ; itry <= ntry ; itry++ ) {
272 p = c0 + lamda * (c1 + lamda * (c2 + lamda * lamda * c4 )) ;
273 pd = (c1 + lamda * (c2d + lamda * lamda * c4d)) ;
275 lamda = lamda + dlamda ;
276 if (fabs(dlamda)< dlamax)
break ;
279 chi2[0] = (double)(chiscl * lamda) ;
284 double h11 = xxav - lamda ;
286 double h22 = yyav - lamda ;
288 double h34 = 1.0 + 2.0*lamda ;
289 if ( h11 == 0.0 || h22 == 0.0 ){
293 double rootsq = (h14*h14)/(h11*h11) + 4.0*h34 ;
295 double ratio, kappa, beta ;
296 if ( fabs(h22) > fabs(h24) ) {
298 rootsq = ratio * ratio + rootsq ;
299 kappa = 1.0 / sqrt(rootsq) ;
300 beta = - ratio * kappa ;
304 rootsq = 1.0 + ratio * ratio * rootsq ;
305 beta = 1.0 / sqrt(rootsq) ;
306 if ( h24 > 0 ) beta = - beta ;
307 kappa = -ratio * beta ;
309 double alph = - (h14/h11) * kappa ;
314 double kappa1 = kappa / rscale ;
315 double dbro = 0.5 / kappa1 ;
319 double alphr = (cosrot * alph - sinrot * beta)* dbro ;
320 double betar = (sinrot * alph + cosrot * beta)* dbro ;
324 double acent = (double)(xav - alphr) ;
325 double bcent = (double)(yav - betar ) ;
326 double radius = (double)dbro ;
331 q = ( ( yrrav < 0 ) ? 1 : -1 ) * getPara()->bFieldPolarity ;
332 pt = (double)fabs(2.9979e-3 * getPara()->bField * radius ) ;
337 if ( getPara()->vertexConstrainedFit ) {
339 x0 = getPara()->xVertex ;
340 y0 = getPara()->yVertex ;
341 phi0 = getPara()->phiVertex ;
342 r0 = getPara()->rVertex ;
343 psi = (double)atan2(bcent-y0,acent-x0) ;
344 psi = psi + getPara()->bFieldPolarity*q * 0.5F * pi ;
345 if ( psi < 0 ) psi = psi + twoPi ;
350 psi = (double)atan2(bcent-(lHit->y),acent-(lHit->x)) ;
351 x0 = acent - radius * cos(psi);
352 y0 = bcent - radius * sin(psi);
353 psi = psi + getPara()->bFieldPolarity*q * 0.5F * pi ;
355 if ( phi0 < 0 ) phi0 += twoPi ;
356 r0 = sqrt ( x0 * x0 + y0 * y0 ) ;
362 if ( getPara()->getErrors ) getErrorsCircleFit ( acent, bcent, radius ) ;
372 int FtfBaseTrack::fitLine ( )
386 double radius = (double)fabs(pt / ( 2.9979e-3 * getPara()->bField ) ) ;
387 if ( getPara()->vertexConstrainedFit ) {
388 dx = ((
FtfBaseHit *)firstHit)->x - getPara()->xVertex ;
389 dy = ((
FtfBaseHit *)firstHit)->y - getPara()->yVertex ;
395 double localPsi = 0.5F * sqrt ( dx*dx + dy*dy ) / radius ;
396 if ( localPsi > 1. ) localPsi = 1. ;
399 length = 2.0F * radius * asin ( localPsi ) ;
403 for ( startLoop() ; done() ; nextHit() ) {
405 if ( currentHit != firstHit ) {
406 dx = cHit->x - previousHit->x ;
407 dy = cHit->y - previousHit->y ;
408 dpsi = 0.5F * (double)sqrt ( dx*dx + dy*dy ) / radius ;
413 cHit->s = previousHit->s - 2.0F * radius * (double)asin ( dpsi ) ;
419 ss += cHit->wz * cHit->s ;
420 sz += cHit->wz * cHit->z ;
421 sss += cHit->wz * cHit->s * cHit->s ;
422 ssz += cHit->wz * cHit->s * cHit->z ;
426 double det = sum * sss - ss * ss;
427 if ( fabs(det) < 1e-20){
434 tanl = (double)((sum * ssz - ss * sz ) / det );
435 z0 = (double)((sz * sss - ssz * ss ) / det );
441 for ( startLoop() ; done() ; nextHit() ) {
443 r1 = cHit->z - tanl * cHit->s - z0 ;
444 chi2[1] += (double) ( (
double)cHit->wz * (r1 * r1) );
453 dtanl = (double) ( sum / det );
454 dz0 = (double) ( sss / det );
477 int FtfBaseTrack::getErrorsCircleFit (
double a,
double b,
double r ) {
479 double h[9] = { 0. };
481 double h11, h22, h33 ;
483 static double ratio, c1, s1;
487 for (j = 0; j < 9; j++ ) {
495 if ( pt < getPara()->ptMinHelixFit ) {
496 for ( startLoop() ; done() ; nextHit() ) {
499 cHit->wxy = 1.0F/ (double)(cHit->dx*cHit->dx + cHit->dy*cHit->dy) ;
505 for ( startLoop() ; done() ; nextHit() ) {
509 hyp = (double)sqrt( dx * dx + dy * dy );
513 h[0] += cHit->wxy * (ratio * (s1 * s1 - 1) + 1);
514 h[1] += cHit->wxy * ratio * s1 * c1;
515 h[2] += cHit->wxy * s1;
516 h[4] += cHit->wxy * (ratio * (c1 * c1 - 1) + 1);
517 h[5] += cHit->wxy * c1;
524 ftfMatrixDiagonal ( h, h11, h22, h33 ) ;
528 dpt = (double)fabs(2.9979e-3 * getPara()->bField * h33 );
532 if ( getPara()->vertexConstrainedFit ) {
541 dpsi = (double)(( 1. / ( 1. + w*w ) ) * ( h22 / dx - dy * h11 / ( dx*dx ) )) ;
549 void FtfBaseTrack::Print (
int level )
557 pmom = (double)sqrt ( pz * pz + pt * pt ) ;
558 LOG(NOTE,
" =======> Track %d <========\n",
id ) ;
559 LOG(NOTE,
"p, pt, q %7.2f %7.2f %2d \n", pmom, pt, q ) ;
562 LOG(NOTE,
"r0, z0, nHits %7.2f %7.2f %d \n", r0, z0, nHits ) ;
563 LOG(NOTE,
"phi0, psi, tanl %7.2f %7.2f %7.2f \n", phi0, psi, tanl ) ;
567 LOG(NOTE,
"chi2 (s,z) %6.2e %6.2e \n", chi2[0], chi2[1] ) ;
571 if ( fmod((
double)level,10.) > 0 ) {
572 LOG(NOTE,
"*** Clusters in this track *** " ) ;
574 for ( startLoop() ; done() ; nextHit() ) {
589 Ftf3DHit FtfBaseTrack::closestApproach (
double xBeam,
double yBeam ) {
591 return getClosest ( xBeam, yBeam, rc, xc, yc ) ;
605 Ftf3DHit FtfBaseTrack::getClosest (
double xBeam,
double yBeam,
606 double &rc,
double &xc,
double &yc ) {
615 double tPhi0 = psi + double(q)*getPara()->bFieldPolarity * 0.5 * M_PI / fabs((
double)q) ;
617 double x0 = r0 * cos(phi0) ;
618 double y0 = r0 * sin(phi0) ;
619 rc = pt / fabs( bFactor * getPara()->bField ) ;
620 xc = x0 - rc * cos(tPhi0) ;
621 yc = y0 - rc * sin(tPhi0) ;
627 getClosest ( xBeam, yBeam, rc, xc, yc, xp, yp ) ;
632 double angle = atan2 ( (yp-yc), (xp-xc) ) ;
633 if ( angle < 0. ) angle = angle + 2.0 * M_PI ;
635 double dangle = angle - tPhi0 ;
637 if ( fabs(dangle) < 1.e-4 ) dangle = 0 ;
638 dangle = fmod ( dangle, 2.0 * M_PI ) ;
639 if ( (
float(q)*getPara()->bFieldPolarity * dangle) < 0 )
640 dangle = dangle + getPara()->bFieldPolarity*float(q) * 2. * M_PI ;
642 double stot = fabs(dangle) * rc ;
643 zp = z0 - stot * tanl ;
660 int FtfBaseTrack::getClosest (
double xBeam,
double yBeam,
661 double rc,
double xc,
double yc,
662 double& xClosest,
double& yClosest ) {
666 double dx = xc - xBeam ;
667 double dy = yc - yBeam ;
671 double fact = rc / sqrt ( dx * dx + dy * dy ) ;
672 double f1 = 1. + fact ;
673 double f2 = 1. - fact ;
675 double dx1 = dx * f1 ;
676 double dy1 = dy * f1 ;
677 double d1 = sqrt ( dx1 * dx1 + dy1 * dy1 ) ;
679 double dx2 = dx * f2 ;
680 double dy2 = dy * f2 ;
681 double d2 = sqrt ( dx2 * dx2 + dy2 * dy2 ) ;
686 xClosest = dx1 + xBeam ;
687 yClosest = dy1 + yBeam ;
690 xClosest = dx2 + xBeam ;
691 yClosest = dy2 + yBeam ;
710 Ftf3DHit FtfBaseTrack::extraRadius (
double r ) {
715 double x, y, z, rc, xc, yc ;
721 if ( extraRCyl ( r, phi, z, rc, xc, yc ) )
return tHit ;
747 int FtfBaseTrack::extraRCyl (
double &r,
double &phi,
double &z,
748 double &rc,
double &xc,
double &yc ) {
751 double fac1,sfac, fac2 ;
757 double tPhi0 = psi + getPara()->bFieldPolarity*double(q) * 0.5 * M_PI / fabs((
double)q) ;
758 double x0 = r0 * cos(phi0) ;
759 double y0 = r0 * sin(phi0) ;
760 rc = fabs(pt / ( bFactor * getPara()->bField )) ;
761 xc = x0 - rc * cos(tPhi0) ;
762 yc = y0 - rc * sin(tPhi0) ;
766 fac1 = xc*xc + yc*yc ;
767 sfac = sqrt( fac1 ) ;
774 if ( fabs(sfac-rc) > r || fabs(sfac+rc) < r ) {
781 fac2 = ( r*r + fac1 - rc*rc) / (2.00 * r * sfac ) ;
782 phi = atan2(yc,xc) + getPara()->bFieldPolarity*float(q)*acos(fac2) ;
783 td = atan2(r*sin(phi) - yc,r*cos(phi) - xc) ;
786 if ( td < 0 ) td = td + 2. * M_PI ;
787 double dangle = tPhi0 - td ;
788 dangle = fmod ( dangle, 2.0 * M_PI ) ;
789 if ( r < r0 ) dangle *= -1 ;
791 if ( (getPara()->bFieldPolarity*
float(q) * dangle) < 0 )
792 dangle = dangle + getPara()->bFieldPolarity*float(q) * 2. * M_PI ;
794 double stot = fabs(dangle) * rc ;
796 if ( r > r0 ) z = z0 + stot * tanl ;
797 else z = z0 - stot * tanl ;
824 int FtfBaseTrack::intersectorZLine (
double a,
double b,
Ftf3DHit& cross ) {
827 if (0 != intersectorZLine(a, b, cross1, cross2))
830 double r1sq = cross1.x*cross1.x + cross1.y*cross1.y;
831 double r2sq = cross2.x*cross2.x + cross2.y*cross2.y;
842 int FtfBaseTrack::intersectorZLine (
double a,
double b,
847 double x0 = r0 * cos(phi0) ;
848 double y0 = r0 * sin(phi0) ;
850 double trackPhi0 = psi + getPara()->bFieldPolarity*q * 0.5 * M_PI / fabs((
double)q) ;
851 double rc = pt / fabs( bFactor * getPara()->bField ) ;
852 double xc = x0 - rc * cos(trackPhi0) ;
853 double yc = y0 - rc * sin(trackPhi0) ;
855 double ycPrime = yc - b ;
856 double aa = ( 1. + a * a ) ;
857 double bb = -2. * ( xc + a * ycPrime ) ;
858 double cc = ( xc * xc + ycPrime * ycPrime - rc * rc ) ;
860 double racine = bb * bb - 4. * aa * cc ;
866 double rootRacine = sqrt(racine) ;
868 double oneOverA = 1./aa;
872 double x1 = 0.5 * oneOverA * ( -1. * bb + rootRacine ) ;
873 double y1 = a * x1 + b ;
877 double x2 = 0.5 * oneOverA * ( -1. * bb - rootRacine ) ;
878 double y2 = a * x2 + b ;
884 double angle, dangle, stot;
886 angle = atan2 ( (y1-yc), (x1-xc) ) ;
887 if ( angle < 0. ) angle = angle + 2.0 * M_PI ;
889 dangle = angle - trackPhi0 ;
890 dangle = fmod ( dangle, 2.0 * M_PI ) ;
892 if ( (getPara()->bFieldPolarity*q * dangle) > 0 )
893 dangle = dangle - getPara()->bFieldPolarity*q * 2. * M_PI ;
895 stot = fabs(dangle) * rc ;
896 double z1 = z0 + stot * tanl ;
898 cross1.set ( x1, y1, z1 ) ;
904 angle = atan2 ( (y2-yc), (x2-xc) ) ;
905 if ( angle < 0. ) angle = angle + 2.0 * M_PI ;
907 dangle = angle - trackPhi0 ;
908 dangle = fmod ( dangle, 2.0 * M_PI ) ;
910 if ( (getPara()->bFieldPolarity*q * dangle) > 0 )
911 dangle = dangle - getPara()->bFieldPolarity*q * 2. * M_PI ;
913 stot = fabs(dangle) * rc ;
914 double z2 = z0 + stot * tanl ;
916 cross2.set ( x2, y2, z2 ) ;
936 int FtfBaseTrack::intersectorYCteLine (
double a,
Ftf3DHit& cross ) {
940 double x0 = r0*cos(phi0);
941 double y0 = r0*sin(phi0);
943 double trackPhi0= psi + getPara()->bFieldPolarity*q*0.5*M_PI/fabs((
float)q);
944 double rcoc = pt / fabs( bFactor * getPara()->bField ) ;
945 double xcoc = x0 - (rcoc*cos(trackPhi0));
946 double ycoc = y0 - (rcoc*sin(trackPhi0));
952 double f1 = (xHit-xcoc)*(xHit-xcoc);
953 double r2 = rcoc*rcoc;
958 double sf2 = sqrt(r2-f1);
959 double y1 = ycoc + sf2;
960 double y2 = ycoc - sf2;
962 if ( fabs(y2) < fabs(y1) ) yHit=y2;
965 double angle = atan2 ( (yHit-ycoc), (xHit-xcoc) ) ;
966 if ( angle < 0. ) angle = angle + 2.0 * M_PI ;
968 double dangle = angle - trackPhi0 ;
969 dangle = fmod ( dangle, 2.0 * M_PI ) ;
970 if ( (getPara()->bFieldPolarity*q * dangle) > 0 )
971 dangle = dangle - getPara()->bFieldPolarity*q * 2. * M_PI ;
973 double stot = fabs(dangle) * rcoc ;
974 double zHit = z0 + stot * tanl;
976 cross.set(xHit,yHit,zHit);
994 double FtfBaseTrack::arcLength (
double x1,
double y1,
double x2,
double y2 )
996 double x0, y0, xc, yc, rc ;
997 double angle_1, angle_2, d_angle, sleng_xy, sleng ;
1002 x0 = r0 * cos(phi0) ;
1003 y0 = r0 * sin(phi0) ;
1004 rc = pt / fabs( bFactor * getPara()->bField ) ;
1006 double tPhi0 = psi + getPara()->bFieldPolarity*double(q) * 0.5 * M_PI / fabs((
double)q) ;
1007 xc = x0 - rc * cos(tPhi0) ;
1008 yc = y0 - rc * sin(tPhi0) ;
1012 angle_1 = atan2 ( (y1-yc), (x1-xc) ) ;
1013 if ( angle_1 < 0 ) angle_1 = angle_1 + 2. * M_PI ;
1014 angle_2 = atan2 ( (y2-yc), (x2-xc) ) ;
1015 if ( angle_2 < 0 ) angle_2 = angle_2 + 2. * M_PI ;
1016 d_angle = getPara()->bFieldPolarity*double(q) * ( angle_1 - angle_2 ) ;
1017 d_angle = fmod ( d_angle, 2. * M_PI ) ;
1018 if ( d_angle < 0 ) d_angle = d_angle + 2. * M_PI ;
1022 sleng_xy = fabs ( rc ) * d_angle ;
1023 sleng = sleng_xy * sqrt ( 1.0 + tanl * tanl ) ;
1037 int FtfBaseTrack::phiRotate (
double deltaPhi ) {
1039 if ( phi0 > 2. * M_PI ) phi0 -= 2. * M_PI ;
1040 if ( phi0 < 0 ) phi0 += 2. * M_PI ;
1042 if ( psi > 2. * M_PI ) psi -= 2. * M_PI ;
1043 if ( psi < 0 ) psi += 2. * M_PI ;
1050 int FtfBaseTrack::refitHelix (
int mod,
int modEqual,
int rowMin,
int rowMax ) {
1053 if ( nHits < 1 || nHits > 500 ) {
1054 LOG(ERR,
"FtfBaseTrack:refitHelix: nHits %d out of range \n", nHits ) ;
1058 hitPointer* hitP =
new hitPointer[nHits];
1059 int nHitsOrig = nHits ;
1062 for ( startLoop() ; done() ; nextHit() ) {
1071 for (
int i = 0 ; i < nHitsOrig ; i++ ) {
1072 row = hitP[i]->row ;
1073 hitP[i]->nextTrackHit = 0 ;
1074 if ( row%mod != modEqual ) continue ;
1075 if ( row < rowMin || row > rowMax ) continue ;
1077 if ( firstHit == 0 ) firstHit = hitP[i] ;
1079 ((
FtfBaseHit *)lastHit)->nextTrackHit = (
void *)hitP[i] ;
1080 lastHit = (
void *)hitP[i] ;
1086 if ( nHits > 5 ) fitHelix ( ) ;
1092 for (
int i = 0 ; i < nHitsOrig ; i++ ) {
1093 row = hitP[i]->row ;
1094 if ( firstHit == 0 ) firstHit = hitP[i] ;
1096 ((
FtfBaseHit *)lastHit)->nextTrackHit = (
void *)hitP[i] ;
1097 lastHit = (
void *)hitP[i] ;
1117 void FtfBaseTrack::updateToRadius (
double radius ) {
1119 double phiExtra, zExtra, rCircle, xCircleCenter, yCircleCenter ;
1121 int ok = extraRCyl ( radius, phiExtra, zExtra, rCircle, xCircleCenter, yCircleCenter ) ;
1134 double xExtra = radius * cos(phiExtra) ;
1135 double yExtra = radius * sin(phiExtra) ;
1137 double tPhi = atan2(yExtra-yCircleCenter,xExtra-xCircleCenter);
1141 if ( phiExtra < 0 ) phiExtra += 2 * M_PI ;
1143 double tPsi = tPhi - getPara()->bFieldPolarity * double(q) * 0.5 * M_PI / fabs((
double)q) ;
1144 if ( tPsi > 2. * M_PI ) tPsi -= 2. * M_PI ;
1145 if ( tPsi < 0. ) tPsi += 2. * M_PI ;
1166 void FtfBaseTrack::updateToClosestApproach (
double xBeam,
double yBeam,
double rMax ) {
1168 Ftf3DHit closest = getClosest ( xBeam, yBeam, rc, xc, yc ) ;
1172 double radius = sqrt(closest.x*closest.x+closest.y*closest.y);
1173 if ( radius > rMax ) return ;
1175 double tPhi = atan2(closest.y-yc,closest.x-xc);
1180 double tPsi = tPhi - getPara()->bFieldPolarity*double(q) * 0.5 * M_PI / fabs((
double)q) ;
1181 if ( tPsi > 2. * M_PI ) tPsi -= 2. * M_PI ;
1182 if ( tPsi < 0. ) tPsi += 2. * M_PI ;
1187 phi0 = atan2(closest.y,closest.x) ;
1188 if ( phi0 < 0 ) phi0 += 2. * M_PI ;
1207 Ftf3DHit FtfBaseTrack::extrapolate2PathLength(
double pathlength)
1212 double Bfield=fabs(getPara()->bField) * getPara()->bFieldPolarity * 0.01;
1214 double lambda=atan(tanl);
1215 double kapa=(c*q*Bfield)/pt;
1216 double heli=-((q*Bfield)/fabs(q*Bfield));
1217 double phi=psi-heli*M_PI/2;
1219 double x0=r0*cos(phi0);
1220 double y0=r0*sin(phi0);
1223 CoordOfExtrapol.x = x0 + (1/kapa)*(cos(phi+heli*pathlength*kapa*cos(lambda))-cos(phi));
1224 CoordOfExtrapol.y = y0 + (1/kapa)*(sin(phi+heli*pathlength*kapa*cos(lambda))-sin(phi));
1225 CoordOfExtrapol.z = z0 + pathlength*sin(lambda);
1233 return CoordOfExtrapol;
1249 double FtfBaseTrack::getRadius()
1251 double radius=pt / fabs( bFactor * getPara()->bField );
1269 double FtfBaseTrack::getXCenter() {
1271 double tPhi0 = psi + getPara()->bFieldPolarity*double(q) * 0.5 * M_PI / fabs((
double)q) ;
1273 double x0=r0*cos(phi0);
1275 return ( x0- getRadius() * cos(tPhi0) );
1290 double FtfBaseTrack::getYCenter()
1293 double tPhi0 = psi + getPara()->bFieldPolarity*double(q) * 0.5 * M_PI / fabs((
double)q) ;
1295 double y0=r0*sin(phi0);
1297 return ( y0 - getRadius() * sin(tPhi0) );
1322 double FtfBaseTrack::pathLength(
double Rx,
double Ry,
double Rz,
double Nx,
double Ny,
double Nz )
1327 double Bfield=fabs(getPara()->bField) * getPara()->bFieldPolarity * 0.01;
1330 int heli= (int) -((q*Bfield)/fabs(q*Bfield));
1331 int H = (heli>=0) ? 1 : -1;
1334 double x0=r0*cos(phi0);
1335 double y0=r0*sin(phi0);
1339 double DipAngle = atan(tanl);
1340 double CosDipAngle = cos(DipAngle);
1341 double SinDipAngle = sin(DipAngle);
1344 double Phase = psi-heli*M_PI/2;
1345 double CosPhase = cos(Phase);
1346 double SinPhase = sin(Phase);
1347 if (fabs(Phase) > M_PI) Phase = atan2(SinPhase, CosPhase);
1350 double Curvature = (0.3*q*Bfield)/pt;
1354 const double NoSolution = LONG_MAX ;
1355 const double MaxPrecisionNeeded = 0.0001;
1356 const int MaxIterations = 20;
1358 double A = Curvature*( (x0*Nx+y0*Ny+z0*Nz) - (Rx*Nx+Ry*Ny+Rz*Nz) ) -
1361 double t = H*Curvature*CosDipAngle;
1364 double sOld = s = 0;
1366 for (i=0; i<MaxIterations; i++)
1372 Nz*Curvature*SinDipAngle*s;
1376 Nz*Curvature*SinDipAngle;
1378 if (fabs(sOld-s) < MaxPrecisionNeeded)
break;
1382 if (i == MaxIterations) s = NoSolution;