StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
FtfBaseTrack.cxx
1 //:>-----------------------------------------------------------------
2 //: FILE: FtfBaseTrack.cxx
3 //: HISTORY:
4 //: 28oct1996 version 1.00
5 //: 11aug1999 ppy primary flag in FtfPara replace with vertexConstrainedFit
6 //: 11aug1999 ppy primary flag in track filled now
7 //: 3sep1999 ppy fitLine, dpsi cannot be greater than 1. Check introduced
8 //: 5oct1999 ppy fitLine, bug corrected
9 //: 6oct1999 ppy Root switch added
10 //: 9mar2000 ppy extrapolation methods added
11 //: 9mar2000 ppy lots of changes to use void pointers
12 //: 28mar2000 ppy closestApproach split in two methods
13 //: 19jul2000 ppy fitHelix, for secondary tracks r0,phi0,z0
14 //: is given at a point on the helix close to
15 //: the inner most point. Previously it was given
16 //: exactly at the inner most point. Residuals
17 //: are slightly better with this change
18 //:<------------------------------------------------------------------
19 //:>------------------------------------------------------------------
20 //: CLASS: FtfBaseTrack
21 //: DESCRIPTION: Basic Description of a track P
22 //: AUTHOR: ppy - Pablo Yepes, yepes@rice.edu
23 //:>------------------------------------------------------------------
24 #include "Stl3Util/ftf/FtfBaseTrack.h"
25 
26 
27 
28 void ftfMatrixDiagonal ( double *h, double &h11, double &h22, double &h33 ) ;
29 
30 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
31 // Track Initialization
32 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
33 FtfBaseTrack::FtfBaseTrack ( ){
34  firstHit = 0 ;
35  lastHit = 0 ;
36 }
37 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
38 // Fit a circle
39 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
40 int FtfBaseTrack::fitHelix ( )
41 {
42  if ( fitCircle ( ) ){
43  ftfLog ( " Problem in Fit_Circle " ) ;
44  return 1 ;
45  }
46 //
47 // Fit line in s-z plane now
48 //
49  if ( fitLine ( )) {
50  ftfLog ( " Problem fitting a line " ) ;
51  return 1 ;
52  }
53  return 0 ;
54 }
55 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
56 // End of Fit Helix
57 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
58 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
59 //
60 // Fits circle parameters using algorithm
61 // described by ChErnov and Oskov in Computer Physics
62 // Communications.
63 //
64 // Written in FORTRAN by Jawluen Tang, Physics department , UT-Austin
65 // Moved to C by Pablo Yepes
66 //---------------------------------------------------------------
67 int FtfBaseTrack::fitCircle ( )
68 {
69  double wsum = 0.0 ;
70  double xav = 0.0 ;
71  double yav = 0.0 ;
72 //
73 // Loop over hits calculating average
74 //
75  for ( startLoop() ; done() ; nextHit() ) {
76 
77  FtfBaseHit* cHit = (FtfBaseHit *)currentHit ;
78  cHit->wxy = 1.0F/ (double)(cHit->dx*cHit->dx + cHit->dy*cHit->dy) ;
79  wsum += cHit->wxy ;
80  xav += cHit->wxy * cHit->x ;
81  yav += cHit->wxy * cHit->y ;
82  }
83  if ( getPara()->vertexConstrainedFit ) {
84  wsum += getPara()->xyWeightVertex ;
85  xav += getPara()->xVertex ;
86  yav += getPara()->yVertex ;
87  }
88  xav = xav / wsum ;
89  yav = yav / wsum ;
90 //
91 // CALCULATE <X**2>, <XY>, AND <Y**2> WITH <X> = 0, & <Y> = 0
92 //
93  double xxav = 0.0 ;
94  double xyav = 0.0 ;
95  double yyav = 0.0 ;
96  double xi, yi ;
97 
98  for ( startLoop() ; done() ; nextHit() ) {
99  FtfBaseHit* cHit = (FtfBaseHit *)currentHit ;
100  xi = cHit->x - xav ;
101  yi = cHit->y - yav ;
102  xxav += xi * xi * cHit->wxy ;
103  xyav += xi * yi * cHit->wxy ;
104  yyav += yi * yi * cHit->wxy ;
105  }
106  if ( getPara()->vertexConstrainedFit ) {
107  xi = getPara()->xVertex - xav ;
108  yi = getPara()->yVertex - yav ;
109  xxav += xi * xi * getPara()->xyWeightVertex ;
110  xyav += xi * yi * getPara()->xyWeightVertex ;
111  yyav += yi * yi * getPara()->xyWeightVertex ;
112  }
113  xxav = xxav / wsum ;
114  xyav = xyav / wsum ;
115  yyav = yyav / wsum ;
116 //
117 //--> ROTATE COORDINATES SO THAT <XY> = 0
118 //
119 //--> SIGN(C**2 - S**2) = SIGN(XXAV - YYAV) >
120 //--> & > ==> NEW : (XXAV-YYAV) > 0
121 //--> SIGN(S) = SIGN(XYAV) >
122 
123  double a = fabs( xxav - yyav ) ;
124  double b = 4.0 * xyav * xyav ;
125 
126  double asqpb = a * a + b ;
127  double rasqpb = sqrt ( asqpb) ;
128 
129  double splus = 1.0 + a / rasqpb ;
130  double sminus = b / (asqpb * splus) ;
131 
132  splus = sqrt (0.5 * splus ) ;
133  sminus = sqrt (0.5 * sminus) ;
134 //
135 //-> FIRST REQUIRE : SIGN(C**2 - S**2) = SIGN(XXAV - YYAV)
136 //
137  double sinrot, cosrot ;
138  if ( xxav <= yyav ) {
139  cosrot = sminus ;
140  sinrot = splus ;
141  }
142  else {
143  cosrot = splus ;
144  sinrot = sminus ;
145  }
146 //
147 //-> REQUIRE : SIGN(S) = SIGN(XYAV) * SIGN(C) (ASSUMING SIGN(C) > 0)
148 //
149  if ( xyav < 0.0 ) sinrot = - sinrot ;
150 //
151 //--> WE NOW HAVE THE SMALLEST ANGLE THAT GUARANTEES <X**2> > <Y**2>
152 //--> TO GET THE SIGN OF THE CHARGE RIGHT, THE NEW X-AXIS MUST POINT
153 //--> OUTWARD FROM THE ORGIN. WE ARE FREE TO CHANGE SIGNS OF BOTH
154 //--> COSROT AND SINROT SIMULTANEOUSLY TO ACCOMPLISH THIS.
155 //
156 //--> CHOOSE SIGN OF C WISELY TO BE ABLE TO GET THE SIGN OF THE CHARGE
157 //
158  if ( cosrot*xav+sinrot*yav < 0.0 ) {
159  cosrot = -cosrot ;
160  sinrot = -sinrot ;
161  }
162 //
163 //-> NOW GET <R**2> AND RSCALE= SQRT(<R**2>)
164 //
165  double rrav = xxav + yyav ;
166  double rscale = ::sqrt(rrav) ;
167 
168  xxav = 0.0 ;
169  yyav = 0.0 ;
170  xyav = 0.0 ;
171  double xrrav = 0.0 ;
172  double yrrav = 0.0 ;
173  double rrrrav = 0.0 ;
174 
175  double xixi, yiyi, riri, wiriri, xold, yold ;
176  for ( startLoop() ; done() ; nextHit() ) {
177  FtfBaseHit* cHit = (FtfBaseHit *)currentHit ;
178  xold = cHit->x - xav ;
179  yold = cHit->y - yav ;
180 //
181 //--> ROTATE SO THAT <XY> = 0 & DIVIDE BY RSCALE SO THAT <R**2> = 1
182 //
183  xi = ( cosrot * xold + sinrot * yold ) / rscale ;
184  yi = ( -sinrot * xold + cosrot * yold ) / rscale ;
185 
186  xixi = xi * xi ;
187  yiyi = yi * yi ;
188  riri = xixi + yiyi ;
189  wiriri = cHit->wxy * riri ;
190 
191  xyav += cHit->wxy * xi * yi ;
192  xxav += cHit->wxy * xixi ;
193  yyav += cHit->wxy * yiyi ;
194 
195  xrrav += wiriri * xi ;
196  yrrav += wiriri * yi ;
197  rrrrav += wiriri * riri ;
198  }
199 //
200 // Include vertex if required
201 //
202  if ( getPara()->vertexConstrainedFit ) {
203  xold = getPara()->xVertex - xav ;
204  yold = getPara()->yVertex - yav ;
205 //
206 //--> ROTATE SO THAT <XY> = 0 & DIVIDE BY RSCALE SO THAT <R**2> = 1
207 //
208  xi = ( cosrot * xold + sinrot * yold ) / rscale ;
209  yi = ( -sinrot * xold + cosrot * yold ) / rscale ;
210 
211  xixi = xi * xi ;
212  yiyi = yi * yi ;
213  riri = xixi + yiyi ;
214  wiriri = getPara()->xyWeightVertex * riri ;
215 
216  xyav += getPara()->xyWeightVertex * xi * yi ;
217  xxav += getPara()->xyWeightVertex * xixi ;
218  yyav += getPara()->xyWeightVertex * yiyi ;
219 
220  xrrav += wiriri * xi ;
221  yrrav += wiriri * yi ;
222  rrrrav += wiriri * riri ;
223  }
224 //
225 //
226 //
227 //--> DIVIDE BY WSUM TO MAKE AVERAGES
228 //
229  xxav = xxav / wsum ;
230  yyav = yyav / wsum ;
231  xrrav = xrrav / wsum ;
232  yrrav = yrrav / wsum ;
233  rrrrav = rrrrav / wsum ;
234  xyav = xyav / wsum ;
235 
236  int const ntry = 5 ;
237 //
238 //--> USE THESE TO GET THE COEFFICIENTS OF THE 4-TH ORDER POLYNIMIAL
239 //--> DON'T PANIC - THE THIRD ORDER TERM IS ZERO !
240 //
241  double xrrxrr = xrrav * xrrav ;
242  double yrryrr = yrrav * yrrav ;
243  double rrrrm1 = rrrrav - 1.0 ;
244  double xxyy = xxav * yyav ;
245 
246  double c0 = rrrrm1*xxyy - xrrxrr*yyav - yrryrr*xxav ;
247  double c1 = - rrrrm1 + xrrxrr + yrryrr - 4.0*xxyy ;
248  double c2 = 4.0 + rrrrm1 - 4.0*xxyy ;
249  double c4 = - 4.0 ;
250 //
251 //--> COEFFICIENTS OF THE DERIVATIVE - USED IN NEWTON-RAPHSON ITERATIONS
252 //
253  double c2d = 2.0 * c2 ;
254  double c4d = 4.0 * c4 ;
255 //
256 //--> 0'TH VALUE OF LAMDA - LINEAR INTERPOLATION BETWEEN P(0) & P(YYAV)
257 //
258 // LAMDA = YYAV * C0 / (C0 + YRRSQ * (XXAV-YYAV))
259  double lamda = 0.0 ;
260  double dlamda = 0.0 ;
261 //
262  double chiscl = wsum * rscale * rscale ;
263  double dlamax = 0.001 / chiscl ;
264 
265  double p, pd ;
266  for ( int itry = 1 ; itry <= ntry ; itry++ ) {
267  p = c0 + lamda * (c1 + lamda * (c2 + lamda * lamda * c4 )) ;
268  pd = (c1 + lamda * (c2d + lamda * lamda * c4d)) ;
269  dlamda = -p / pd ;
270  lamda = lamda + dlamda ;
271  if (fabs(dlamda)< dlamax) break ;
272  }
273 
274  chi2[0] = (double)(chiscl * lamda) ;
275  // double dchisq = chiscl * dlamda ;
276 //
277 //--> NOW CALCULATE THE MATRIX ELEMENTS FOR ALPHA, BETA & KAPPA
278 //
279  double h11 = xxav - lamda ;
280  double h14 = xrrav ;
281  double h22 = yyav - lamda ;
282  double h24 = yrrav ;
283  double h34 = 1.0 + 2.0*lamda ;
284  if ( h11 == 0.0 || h22 == 0.0 ){
285  ftfLog ( " Problems fitting a circle " ) ;
286  return 1 ;
287  }
288  double rootsq = (h14*h14)/(h11*h11) + 4.0*h34 ;
289 
290  double ratio, kappa, beta ;
291  if ( fabs(h22) > fabs(h24) ) {
292  ratio = h24 / h22 ;
293  rootsq = ratio * ratio + rootsq ;
294  kappa = 1.0 / ::sqrt(rootsq) ;
295  beta = - ratio * kappa ;
296  }
297  else {
298  ratio = h22 / h24 ;
299  rootsq = 1.0 + ratio * ratio * rootsq ;
300  beta = 1.0 / ::sqrt(rootsq) ;
301  if ( h24 > 0 ) beta = - beta ;
302  kappa = -ratio * beta ;
303  }
304  double alpha = - (h14/h11) * kappa ;
305 //
306 //--> transform these into the lab coordinate system
307 //--> first get kappa and back to real dimensions
308 //
309  double kappa1 = kappa / rscale ;
310  double dbro = 0.5 / kappa1 ;
311 //
312 //--> next rotate alpha and beta and scale
313 //
314  double alphar = (cosrot * alpha - sinrot * beta)* dbro ;
315  double betar = (sinrot * alpha + cosrot * beta)* dbro ;
316 //
317 //--> then translate by (xav,yav)
318 //
319  double acent = (double)(xav - alphar) ;
320  double bcent = (double)(yav - betar ) ;
321  double radius = (double)dbro ;
322 //
323 // Get charge
324 //
325  q = ( ( yrrav < 0 ) ? 1 : -1 ) ;
326  pt = (double)(2.9979e-3 * getPara()->bField * radius ) ;
327 //
328 // Get other track parameters
329 //
330  double x0, y0 ;
331  if ( getPara()->vertexConstrainedFit ) {
332  flag = 1 ; // primary track flag
333  x0 = getPara()->xVertex ;
334  y0 = getPara()->yVertex ;
335  phi0 = getPara()->phiVertex ;
336  r0 = getPara()->rVertex ;
337  psi = (double)atan2(bcent-y0,acent-x0) ;
338  psi = psi + q * 0.5F * pi ;
339  if ( psi < 0 ) psi = psi + twoPi ;
340  }
341  else {
342  FtfBaseHit* lHit = (FtfBaseHit *)lastHit ;
343  flag = 0 ; // primary track flag
344  psi = (double)atan2(bcent-(lHit->y),acent-(lHit->x)) ;
345  x0 = acent - radius * cos(psi);
346  y0 = bcent - radius * sin(psi);
347  psi = psi + q * 0.5F * pi ;
348  phi0 = atan2(y0,x0);
349  if ( phi0 < 0 ) phi0 += twoPi ;
350  r0 = sqrt ( x0 * x0 + y0 * y0 ) ;
351  }
352  //
353 //
354 // Get errors from fast fit
355 //
356  if ( getPara()->getErrors ) getErrorsCircleFit ( acent, bcent, radius ) ;
357 //
358  return 0 ;
359 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
360 // End Fit Circle
361 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
362 }
363 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
364 // Fit Line in s-z plane
365 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
366 int FtfBaseTrack::fitLine ( )
367 {
368 //
369 // initialization
370 //
371  double sum = 0.F ;
372  double ss = 0.F ;
373  double sz = 0.F ;
374  double sss = 0.F ;
375  double ssz = 0.F ;
376 //
377 // find sum , sums ,sumz, sumss
378 //
379  double dx, dy ;
380  double radius = (double)(pt / ( 2.9979e-3 * getPara()->bField ) ) ;
381  if ( getPara()->vertexConstrainedFit ) {
382  dx = ((FtfBaseHit *)firstHit)->x - getPara()->xVertex ;
383  dy = ((FtfBaseHit *)firstHit)->y - getPara()->yVertex ;
384  }
385  else {
386  dx = ((FtfBaseHit *)firstHit)->x - ((FtfBaseHit *)lastHit)->x ;
387  dy = ((FtfBaseHit *)firstHit)->y - ((FtfBaseHit *)lastHit)->y ;
388  }
389  double localPsi = 0.5F * sqrt ( dx*dx + dy*dy ) / radius ;
390  double total_s ;
391  if ( fabs(localPsi) < 1. ) {
392  total_s = 2.0F * radius * asin ( localPsi ) ;
393  }
394  else {
395 // ftfLog ( "FtfBaseTrack: fitLine: problem calculating s \n" ) ;
396  total_s = 2.0F * radius * M_PI ;
397  }
398 
399 //
400  FtfBaseHit *previousHit = 0 ;
401 
402  for ( startLoop() ; done() ; nextHit() ) {
403  FtfBaseHit* cHit = (FtfBaseHit *)currentHit ;
404  if ( currentHit != firstHit ) {
405  dx = cHit->x - previousHit->x ;
406  dy = cHit->y - previousHit->y ;
407  dpsi = 0.5F * (double)sqrt ( dx*dx + dy*dy ) / radius ;
408  if ( dpsi > 1.) {
409  //ftfLog ( "FtfBaseHit::fitLine(): dpsi=%f\n", dpsi);
410  dpsi = 1.;
411  }
412  cHit->s = previousHit->s - 2.0F * radius * (double)asin ( dpsi ) ;
413  }
414  else
415  cHit->s = total_s ;
416 
417  sum += cHit->wz ;
418  ss += cHit->wz * cHit->s ;
419  sz += cHit->wz * cHit->z ;
420  sss += cHit->wz * cHit->s * cHit->s ;
421  ssz += cHit->wz * cHit->s * cHit->z ;
422  previousHit = cHit ;
423  }
424 
425  double det = sum * sss - ss * ss;
426  if ( fabs(det) < 1e-20){
427  chi2[1] = 99999.F ;
428  return 0 ;
429  }
430 //
431 // compute the best fitted parameters A,B
432 //
433  tanl = (double)((sum * ssz - ss * sz ) / det );
434  z0 = (double)((sz * sss - ssz * ss ) / det );
435 //
436 // calculate chi-square
437 //
438  chi2[1] = 0.F ;
439  double r1 ;
440  for ( startLoop() ; done() ; nextHit() ) {
441  FtfBaseHit* cHit = (FtfBaseHit *)currentHit ;
442  r1 = cHit->z - tanl * cHit->s - z0 ;
443  chi2[1] += (double) ( (double)cHit->wz * (r1 * r1) );
444  }
445 //
446 // calculate estimated variance
447 // varsq=chi/(double(n)-2.)
448 // calculate covariance matrix
449 // siga=::sqrt(varsq*sxx/det)
450 // sigb=::sqrt(varsq*sum/det)
451 //
452  dtanl = (double) ( sum / det );
453  dz0 = (double) ( sss / det );
454 
455  return 0 ;
456 }
457 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
458 // End Fit Line
459 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
460 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
461 // CIRCOV - a covariance matrix calculation program for circle fitting
462 // DESCRIPTION:
463 // Compute the covariance matrix of an effective circle fitting algorithm
464 // The circle equation is (X(I)-A)**2 + (Y(I)-B)**2 = R**2.
465 // The functional minimum is W(I)*[(X(I)-A)**2+(Y(I)-B)**2-R*R]**2/(R*R)
466 // For details about the algorithm, see
467 // N.I. CHERNOV, G.A. OSOSKOV, COMPUT. PHYS. COMMUN. 33(1984) 329-333
468 // INPUT ARGUMENTS: */
469 // A - Best fitted circle center in X axis, REAL
470 // B - Best fitted circle center in Y axis, REAL
471 // R - Best fitted radius REAL
472 //
473 // From a routine written in Fortran by AUTHOR:
474 // Jawluen Tang, Physics department , UT-Austin
475 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
476 int FtfBaseTrack::getErrorsCircleFit ( double a, double b, double r ) {
477 
478  double h[9] = { 0. };
479  double dx, dy ;
480  double h11, h22, h33 ;
481  static int j ;
482  static double ratio, c1, s1;
483  static double hyp;
484 
485 
486  for (j = 0; j < 9; j++ ) {
487  h[j] = 0.;
488  }
489 //
490 // If circle fit was not used the
491 // errors in the real space need to
492 // be calculated
493 //
494  if ( pt < getPara()->ptMinHelixFit ) {
495  for ( startLoop() ; done() ; nextHit() ) {
496 
497  FtfBaseHit* cHit = (FtfBaseHit *)currentHit ;
498  cHit->wxy = 1.0F/ (double)(cHit->dx*cHit->dx + cHit->dy*cHit->dy) ;
499  }
500  }
501 //
502 // Loop over points in fit
503 //
504  for ( startLoop() ; done() ; nextHit() ) {
505  FtfBaseHit* cHit = (FtfBaseHit *)currentHit ;
506  dx = cHit->x - a;
507  dy = cHit->y - b;
508  hyp = (double)::sqrt( dx * dx + dy * dy );
509  s1 = dx / hyp;
510  c1 = dy / hyp;
511  ratio = r / hyp;
512  h[0] += cHit->wxy * (ratio * (s1 * s1 - 1) + 1);
513  h[1] += cHit->wxy * ratio * s1 * c1;
514  h[2] += cHit->wxy * s1;
515  h[4] += cHit->wxy * (ratio * (c1 * c1 - 1) + 1);
516  h[5] += cHit->wxy * c1;
517  h[8] += cHit->wxy ;
518  }
519  h[3] = h[1];
520  h[6] = h[2];
521  h[7] = h[5];
522 
523  ftfMatrixDiagonal ( h, h11, h22, h33 ) ;
524 //
525 // Calculate pt error now
526 //
527  dpt = (double)(2.9979e-3 * getPara()->bField * h33 );
528 //
529 // Get error in psi now
530 //
531  if ( getPara()->vertexConstrainedFit ) {
532  dx = a ;
533  dy = b ;
534  }
535  else {
536  dx = ((FtfBaseHit *)lastHit)->x + a - ((FtfBaseHit *)firstHit)->x ;
537  dy = ((FtfBaseHit *)lastHit)->y + b + ((FtfBaseHit *)firstHit)->y ;
538  }
539  double w = dy / dx ;
540  dpsi = (double)(( 1. / ( 1. + w*w ) ) * ( h22 / dx - dy * h11 / ( dx*dx ) )) ;
541 
542  return 0 ;
543 }
544 
545 //*************************************************************************
546 // Prints one track information
547 //*************************************************************************
548 void FtfBaseTrack::Print ( int level )
549 {
550  double pmom, pz;
551 /*
552 -----> Print info
553 */
554  if ( level > 9 ) {
555  pz = pt * tanl ;
556  pmom = (double)sqrt ( pz * pz + pt * pt ) ;
557  ftfLog ( " \n =======> Track %d <======== ", id ) ;
558  ftfLog ( " \n p, pt, q %7.2f %7.2f %2d ", pmom, pt, q ) ;
559  }
560  if ( level > 19 ) {
561  ftfLog ( " \n r0, z0, nHits %7.2f %7.2f %d ", r0, z0, nHits ) ;
562  ftfLog ( " \n phi0, psi, tanl %7.2f %7.2f %7.2f ", phi0, psi, tanl ) ;
563  }
564  else ftfLog ( "\n " ) ;
565 
566  if ( level > 29 ) {
567  ftfLog ( " \n chi2 (s,z) %6.2e %6.2e ", chi2[0],
568  chi2[1] ) ;
569  }
570  else ftfLog ( "\n " ) ;
571 
572 
573  if ( fmod((double)level,10.) > 0 ) {
574  ftfLog ( " \n *** Clusters in this track *** " ) ;
575  ((FtfBaseHit *)firstHit)->print ( 10 ) ;
576  for ( startLoop() ; done() ; nextHit() ) {
577  ((FtfBaseHit *)currentHit)->print ( 1 ) ;
578  }
579  }
580  ftfLog ( "\n " ) ;
581 }
582 /*:>--------------------------------------------------------------------
583 **: METHOD: Finds point of closest approach
584 **:
585 **: AUTHOR: ppy - P.P. Yepes, yepes@rice.edu
586 **: ARGUMENTS:
587 **: IN: xBeam, yBeam: beam position
588 **:
589 **: RETURNS:
590 **: tHit - Point closest approach to center
591 *:>------------------------------------------------------------------*/
592 Ftf3DHit FtfBaseTrack::closestApproach ( double xBeam, double yBeam ) {
593  double rc, xc, yc ;
594  return getClosest ( xBeam, yBeam, rc, xc, yc ) ;
595 }
596 /*:>--------------------------------------------------------------------
597 **: METHOD: Finds point of closest approach
598 **:
599 **: AUTHOR: ppy - P.P. Yepes, yepes@rice.edu
600 **: ARGUMENTS:
601 **: IN: xBeam, yBeam: beam position
602 **: OUT:
603 **: rc, xc, yc track circle radius and center
604 **:
605 **: RETURNS:
606 **: tHit - Point closest approach to center
607 *:>------------------------------------------------------------------*/
608 Ftf3DHit FtfBaseTrack::getClosest ( double xBeam, double yBeam,
609  double &rc, double &xc, double &yc ) {
610  double xp, yp, zp ;
611  xp = yp = 0. ;
612 //--------------------------------------------------------
613 // Get track parameters
614 //--------------------------------------------------------
615  double tPhi0 = psi + double(q) * 0.5 * M_PI / fabs((double)q) ;
616 
617  double x0 = r0 * cos(phi0) ;
618  double y0 = r0 * sin(phi0) ;
619  rc = pt / ( bFactor * getPara()->bField ) ;
620  xc = x0 - rc * cos(tPhi0) ;
621  yc = y0 - rc * sin(tPhi0) ;
622 
623  getClosest ( xBeam, yBeam, rc, xc, yc, xp, yp ) ;
624 
625 //-----------------------------------------------------------------
626 // Get the z coordinate
627 //-----------------------------------------------------------------
628  double angle = atan2 ( (yp-yc), (xp-xc) ) ;
629  if ( angle < 0. ) angle = angle + 2.0 * M_PI ;
630 
631  double dangle = angle - tPhi0 ;
632 
633  if ( fabs(dangle) < 1.e-4 ) dangle = 0 ; // Problems with -0.000 values
634  dangle = fmod ( dangle, 2.0 * M_PI ) ;
635  if ( (float(q) * dangle) < 0 )
636  dangle = dangle + float(q) * 2. * M_PI ;
637 
638  double stot = fabs(dangle) * rc ;
639  zp = z0 - stot * tanl ;
640 
641  Ftf3DHit tHit(xp,yp,zp) ;
642  return tHit ;
643 }
644 /*:>--------------------------------------------------------------------
645 **: METHOD: Finds point of closest approach
646 **:
647 **: AUTHOR: ppy - P.P. Yepes, yepes@rice.edu
648 **: ARGUMENTS:
649 **: IN: xBeam, yBeam: beam position
650 **: rc, xc, yc : track circle radius and center
651 **: OUT:
652 **: double xClosest, yClosest
653 **:
654 **: RETURNS: 0 if Ok
655 *:>------------------------------------------------------------------*/
656 int FtfBaseTrack::getClosest ( double xBeam, double yBeam,
657  double rc, double xc, double yc,
658  double& xClosest, double& yClosest ) {
659 //----------------------------------------------------------
660 // Shift center to respect beam axis
661 //----------------------------------------------------------
662  double dx = xc - xBeam ;
663  double dy = yc - yBeam ;
664 //----------------------------------------------------------
665 // Solve the equations
666 //----------------------------------------------------------
667  double fact = rc / sqrt ( dx * dx + dy * dy ) ;
668  double f1 = 1. + fact ;
669  double f2 = 1. - fact ;
670 
671  double dx1 = dx * f1 ;
672  double dy1 = dy * f1 ;
673  double d1 = sqrt ( dx1 * dx1 + dy1 * dy1 ) ;
674 
675  double dx2 = dx * f2 ;
676  double dy2 = dy * f2 ;
677  double d2 = sqrt ( dx2 * dx2 + dy2 * dy2 ) ;
678 //---------------------------------------------------------------
679 // Choose the closest
680 //---------------------------------------------------------------
681  if ( d1 < d2 ) {
682  xClosest = dx1 + xBeam ;
683  yClosest = dy1 + yBeam ;
684  }
685  else {
686  xClosest = dx2 + xBeam ;
687  yClosest = dy2 + yBeam ;
688  }
689  return 0 ;
690 }
691 /*:>--------------------------------------------------------------------
692 **: METHOD: Extrapolates track to cylinder with radius r
693 **:
694 **:
695 **: AUTHOR: ppy - P.P. Yepes, yepes@rice.edu
696 **: ARGUMENTS:
697 **: IN:
698 **: track - Global track pointer
699 **: r - Cylinder radius
700 **: OUT:
701 **: x,y,z - Extrapolated point
702 **: xc,yc,rr - Center and radius track circle in x-y plane
703 **:
704 **: RETURNS: 0=ok, <>0 error
705 **:>------------------------------------------------------------------*/
706 Ftf3DHit FtfBaseTrack::extraRadius ( double r ) {
707  double phi ;
708 //
709 // Default values
710 //
711  double x, y, z, rc, xc, yc ;
712  x = y = z = 0.F ;
713 //
714 // If error return with error
715 //
716  Ftf3DHit tHit(0,0,0) ;
717  if ( extraRCyl ( r, phi, z, rc, xc, yc ) ) return tHit ;
718 //
719 // Otherwise get point in cartesian coordinates
720 //
721  x = r * cos(phi) ;
722  y = r * sin(phi) ;
723  tHit.x = x ;
724  tHit.y = y ;
725  tHit.z = z ;
726 
727  return tHit ;
728 }
729 /*:>--------------------------------------------------------------------
730 **: METHOD: Extrapolates track to cylinder with radius r
731 **:
732 **:
733 **: AUTHOR: ppy - P.P. Yepes, yepes@rice.edu
734 **: ARGUMENTS:
735 **: IN:
736 **: r - Cylinder radius
737 **: OUT:
738 **: phi,z - Extrapolated point
739 **: xc,yc,rc - Center and radius track circle in x-y plane
740 **:
741 **: RETURNS: 0=ok, <>0 error
742 **:>------------------------------------------------------------------*/
743 int FtfBaseTrack::extraRCyl ( double &r, double &phi, double &z,
744  double &rc, double &xc, double &yc ) {
745 
746  double td ;
747  double fac1,sfac, fac2 ;
748 //--------------------------------------------------------
749 // Get track parameters
750 //--------------------------------------------------------
751  double tPhi0 = psi + double(q) * 0.5 * M_PI / fabs((double)q) ;
752  double x0 = r0 * cos(phi0) ;
753  double y0 = r0 * sin(phi0) ;
754  rc = fabs(pt) / ( bFactor * getPara()->bField ) ;
755  xc = x0 - rc * cos(tPhi0) ;
756  yc = y0 - rc * sin(tPhi0) ;
757 //
758 // Check helix and cylinder intersect
759 //
760  fac1 = xc*xc + yc*yc ;
761  sfac = ::sqrt( fac1 ) ;
762 //
763 // If they don't intersect return
764 // Trick to solve equation of intersection of two circles
765 // rotate coordinates to have both circles with centers on x axis
766 // pretty simple system of equations, then rotate back
767 //
768  if ( fabs(sfac-rc) > r || fabs(sfac+rc) < r ) {
769 // ftfLog ( "particle does not intersect \n" ) ;
770  return 1 ;
771  }
772 //
773 // Find intersection
774 //
775  fac2 = ( r*r + fac1 - rc*rc) / (2.00 * r * sfac ) ;
776  phi = atan2(yc,xc) + float(q)*acos(fac2) ;
777  td = atan2(r*sin(phi) - yc,r*cos(phi) - xc) ;
778 // Intersection in z
779 
780  if ( td < 0 ) td = td + 2. * M_PI ;
781  double dangle = tPhi0 - td ;
782  dangle = fmod ( dangle, 2.0 * M_PI ) ;
783  if ( r < r0 ) dangle *= -1 ;
784 // ftfLog ( "dangle %f q %d \n", dangle, q ) ;
785  if ( (float(q) * dangle) < 0 ) dangle = dangle + float(q) * 2. * M_PI ;
786 
787  double stot = fabs(dangle) * rc ;
788 // ftfLog ( "dangle %f z0 %f stot %f \n", dangle, z0, stot ) ;
789  if ( r > r0 ) z = z0 + stot * tanl ;
790  else z = z0 - stot * tanl ;
791 //
792 // That's it
793 //
794  return 0 ;
795 }
796 /*:>--------------------------------------------------------------------
797 **: METHOD: Calculates intersection of track with plane define by line
798 **: y = a x + b and the z
799 **:
800 **: AUTHOR: ppy - P.P. Yepes, yepes@rice.edu
801 **: ARGUMENTS:
802 **: IN:
803 **: a, b - Line parameters
804 **: OUT:
805 **: crossPoint - intersection point
806 **:
807 **: RETURNS: 0=ok, <>0 track does not cross the plane
808 **:>------------------------------------------------------------------*/
809 
810 //--------------------------------------------------------------------
811 // tom: split into two methods:
812 // one gets both intersections within one turn of the helix,
813 // the other selects the intersection closest to the origin.
814 // (Provided for compatibility with older programs.)
815 //--------------------------------------------------------------------
816 
817 int FtfBaseTrack::intersectorZLine ( double a, double b, Ftf3DHit& cross ) {
818  Ftf3DHit cross1, cross2;
819 
820  if (0 != intersectorZLine(a, b, cross1, cross2))
821  return 1;
822 
823  double r1sq = cross1.x*cross1.x + cross1.y*cross1.y;
824  double r2sq = cross2.x*cross2.x + cross2.y*cross2.y;
825 
826  if (r1sq < r2sq) { // cross 1 is closer to the beamline
827  cross = cross1;
828  } else {
829  cross = cross2;
830  }
831 
832  return 0;
833 }
834 
835 int FtfBaseTrack::intersectorZLine ( double a, double b,
836  Ftf3DHit& cross1, Ftf3DHit& cross2 ) {
837  //
838  // Calculate circle center and radius
839  //
840  double x0 = r0 * cos(phi0) ; // x first point on track
841  double y0 = r0 * sin(phi0) ; // y first point on track
842  double trackPhi0 = psi + q * 0.5 * M_PI / fabs((double)q) ;//
843  double rc = pt / ( bFactor * getPara()->bField ) ;
844  double xc = x0 - rc * cos(trackPhi0) ;
845  double yc = y0 - rc * sin(trackPhi0) ;
846 
847  double ycPrime = yc - b ;
848  double aa = ( 1. + a * a ) ;
849  double bb = -2. * ( xc + a * ycPrime ) ;
850  double cc = ( xc * xc + ycPrime * ycPrime - rc * rc ) ;
851 
852  double racine = bb * bb - 4. * aa * cc ;
853  if ( racine < 0 ) {
854  cross1.set(0,0,0);
855  cross2.set(0,0,0);
856  return 1 ;
857  }
858  double rootRacine = ::sqrt(racine) ;
859 
860  double oneOverA = 1./aa;
861  //
862  // First solution
863  //
864  double x1 = 0.5 * oneOverA * ( -1. * bb + rootRacine ) ;
865  double y1 = a * x1 + b ;
866  //
867  // Second solution
868  //
869  double x2 = 0.5 * oneOverA * ( -1. * bb - rootRacine ) ;
870  double y2 = a * x2 + b ;
871 
872 
873  //-------------------------------------------------------------------
874  // Get the first z coordinate
875  //-------------------------------------------------------------------
876  double angle, dangle, stot;
877 
878  angle = atan2 ( (y1-yc), (x1-xc) ) ;
879  if ( angle < 0. ) angle = angle + 2.0 * M_PI ;
880 
881  dangle = angle - trackPhi0 ;
882  dangle = fmod ( dangle, 2.0 * M_PI ) ;
883 
884  if ( (q * dangle) > 0 ) dangle = dangle - q * 2. * M_PI ;
885 
886  stot = fabs(dangle) * rc ;
887  double z1 = z0 + stot * tanl ;
888 
889  cross1.set ( x1, y1, z1 ) ;
890 
891 
892  //-------------------------------------------------------------------
893  // Get the second z coordinate
894  //-------------------------------------------------------------------
895  angle = atan2 ( (y2-yc), (x2-xc) ) ;
896  if ( angle < 0. ) angle = angle + 2.0 * M_PI ;
897 
898  dangle = angle - trackPhi0 ;
899  dangle = fmod ( dangle, 2.0 * M_PI ) ;
900 
901  if ( (q * dangle) > 0 ) dangle = dangle - q * 2. * M_PI ;
902 
903  stot = fabs(dangle) * rc ;
904  double z2 = z0 + stot * tanl ;
905 
906  cross2.set ( x2, y2, z2 ) ;
907 
908  return 0 ;
909 }
910 
911 
912 
913 /*:>--------------------------------------------------------------------
914 **: METHOD: Calculates intersection of track with plane define by line
915 **: x = a and the z
916 **:
917 **: AUTHOR: ppy - P.P. Yepes, yepes@rice.edu
918 **: ARGUMENTS:
919 **: IN:
920 **: a - Line parameter
921 **: OUT:
922 **: crossPoint - intersection point
923 **:
924 **: RETURNS: 0=ok, <>0 track does not cross the plane
925 **:>------------------------------------------------------------------*/
926 int FtfBaseTrack::intersectorYCteLine ( double a, Ftf3DHit& cross ) {
927 //
928 //calculate circle center and radius
929 //
930  double x0 = r0*cos(phi0);
931  double y0 = r0*sin(phi0);
932  double trackPhi0= psi + q*0.5*M_PI/fabs(q);
933  double rcoc = pt / ( bFactor * getPara()->bField ) ;
934  double xcoc = x0 - (rcoc*cos(trackPhi0));
935  double ycoc = y0 - (rcoc*sin(trackPhi0));
936 //
937 // Calculate circle center and radius
938 //
939  double xHit = a ;
940 
941  double f1 = (xHit-xcoc)*(xHit-xcoc);
942  double r2 = rcoc*rcoc;
943  if ( f1 > r2 ) {
944  return 1 ;
945  }
946 
947  double sf2 = ::sqrt(r2-f1);
948  double y1 = ycoc + sf2;
949  double y2 = ycoc - sf2;
950  double yHit = y1;
951  if ( fabs(y2) < fabs(y1) ) yHit=y2;
952 
953 //Get z coordinate:
954  double angle = atan2 ( (yHit-ycoc), (xHit-xcoc) ) ;
955  if ( angle < 0. ) angle = angle + 2.0 * M_PI ;
956 
957  double dangle = angle - trackPhi0 ;
958  dangle = fmod ( dangle, 2.0 * M_PI ) ;
959  if ( (q * dangle) > 0 ) dangle = dangle - q * 2. * M_PI ;
960 
961  double stot = fabs(dangle) * rcoc ;
962  double zHit = z0 + stot * tanl;
963 
964  cross.set(xHit,yHit,zHit);
965 //
966  return 0 ;
967 }
968 //
969 /*:>--------------------------------------------------------------------
970 **: METHOD: Calculates trajectory length between two points on a track
971 **:
972 **: AUTHOR: ppy - P.P. Yepes, yepes@rice.edu
973 **: ARGUMENTS:
974 **: IN:
975 **: track - Track pointer
976 **: x1, y1 - Point 1
977 **: x2, y2 - Point 2
978 **: OUT:
979 **:
980 **: RETURNS: 0=ok, <>0 error
981 **:>------------------------------------------------------------------*/
982 double FtfBaseTrack::arcLength ( double x1, double y1, double x2, double y2 )
983 {
984  double x0, y0, xc, yc, rc ;
985  double angle_1, angle_2, d_angle, sleng_xy, sleng ;
986 /*----------------------------------------------------------
987  Get track parameters
988 ----------------------------------------------------------*/
989 
990  x0 = r0 * cos(phi0) ;
991  y0 = r0 * sin(phi0) ;
992  rc = pt / ( bFactor * getPara()->bField ) ;
993  double tPhi0 = psi + double(q) * 0.5 * M_PI / fabs((double)q) ;
994  xc = x0 - rc * cos(tPhi0) ;
995  yc = y0 - rc * sin(tPhi0) ;
996 /*
997  Get angle difference
998 */
999  angle_1 = atan2 ( (y1-yc), (x1-xc) ) ;
1000  if ( angle_1 < 0 ) angle_1 = angle_1 + 2. * M_PI ;
1001  angle_2 = atan2 ( (y2-yc), (x2-xc) ) ;
1002  if ( angle_2 < 0 ) angle_2 = angle_2 + 2. * M_PI ;
1003  d_angle = double(q) * ( angle_1 - angle_2 ) ;
1004  d_angle = fmod ( d_angle, 2. * M_PI ) ;
1005  if ( d_angle < 0 ) d_angle = d_angle + 2. * M_PI ;
1006 /*----------------------------------------------------------
1007  Get total angle and total trajectory
1008 ----------------------------------------------------------*/
1009  sleng_xy = fabs ( rc ) * d_angle ;
1010  sleng = sleng_xy * sqrt ( 1.0 + tanl * tanl ) ;
1011  return sleng ;
1012 
1013 }
1014 /*:>--------------------------------------------------------------------
1015 **: METHOD: Phi rotates the track
1016 **:
1017 **: AUTHOR: ppy - P.P. Yepes, yepes@rice.edu
1018 **: ARGUMENTS:
1019 **: IN:
1020 **: deltaPhi - Angle to rotate in phi
1021 **:
1022 **: RETURNS: 0=ok, <>0 error
1023 **:>------------------------------------------------------------------*/
1024 int FtfBaseTrack::phiRotate ( double deltaPhi ) {
1025  phi0 += deltaPhi ;
1026  if ( phi0 > 2. * M_PI ) phi0 -= 2. * M_PI ;
1027  if ( phi0 < 0 ) phi0 += 2. * M_PI ;
1028  psi += deltaPhi ;
1029  if ( psi > 2. * M_PI ) psi -= 2. * M_PI ;
1030  if ( psi < 0 ) psi += 2. * M_PI ;
1031 
1032  return 0 ;
1033 }
1034 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1035 // Fit a circle
1036 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1037 int FtfBaseTrack::refitHelix ( int mod, int modEqual, int rowMin, int rowMax ) {
1038  typedef FtfBaseHit* hitPointer;
1039 
1040  if ( nHits < 1 || nHits > 500 ) {
1041  ftfLog ( "FtfBaseTrack:refitHelix: nHits %d out of range \n", nHits ) ;
1042  return 1 ;
1043  }
1044 //
1045  hitPointer* hitP = new hitPointer[nHits];
1046  int nHitsOrig = nHits ;
1047 
1048  int counter = 0 ;
1049  for ( startLoop() ; done() ; nextHit() ) {
1050  hitP[counter] = (FtfBaseHit *)currentHit ;
1051 // hitP[counter]->print(1);
1052  counter++ ;
1053  }
1054 
1055  int row ;
1056  firstHit = 0 ;
1057  counter = 0 ;
1058  for ( int i = 0 ; i < nHitsOrig ; i++ ) {
1059  row = hitP[i]->row ;
1060  hitP[i]->nextTrackHit = 0 ;
1061  if ( row%mod != modEqual ) continue ;
1062  if ( row < rowMin || row > rowMax ) continue ;
1063 
1064  if ( firstHit == 0 ) firstHit = hitP[i] ;
1065  else
1066  ((FtfBaseHit *)lastHit)->nextTrackHit = (void *)hitP[i] ;
1067  lastHit = (void *)hitP[i] ;
1068  counter++ ;
1069  }
1070  nHits = counter ;
1071 
1072  int problem = 0 ;
1073  if ( nHits > 5 ) fitHelix ( ) ;
1074  else problem = 1 ;
1075  //
1076  // Put hits back
1077  //
1078  firstHit = 0 ;
1079  for ( int i = 0 ; i < nHitsOrig ; i++ ) {
1080  row = hitP[i]->row ;
1081  if ( firstHit == 0 ) firstHit = hitP[i] ;
1082  else
1083  ((FtfBaseHit *)lastHit)->nextTrackHit = (void *)hitP[i] ;
1084  lastHit = (void *)hitP[i] ;
1085  }
1086  nHits = nHitsOrig ;
1087 
1088  delete []hitP ;
1089 
1090  return problem ;
1091 }
1092 /*:>--------------------------------------------------------------------
1093 **: METHOD: Updates track parameters to point of intersection with
1094 **: cylinder of radius r
1095 **:
1096 **:
1097 **: AUTHOR: ppy - P.P. Yepes, yepes@rice.edu
1098 **: ARGUMENTS:
1099 **: IN:
1100 **: radius - Cylinder radius to extrapolate track
1101 **: OUT:
1102 **:
1103 **:>------------------------------------------------------------------*/
1104 void FtfBaseTrack::updateToRadius ( double radius ) {
1105 
1106  double phiExtra, zExtra, rCircle, xCircleCenter, yCircleCenter ;
1107 
1108  int ok = extraRCyl ( radius, phiExtra, zExtra, rCircle, xCircleCenter, yCircleCenter ) ;
1109  if ( ok ) {
1110 // ftfLog ( "FtfBaseTrack::updateToRadius: track %d does not intersect radius %f\n",
1111 // id, radius ) ;
1112  return ;
1113  }
1114 //
1115 // Check extrapolation falls inside volume
1116 //
1117 // if ( fabs(zExtra) > getPara()->zMax ) {
1118 // ftfLog ( "problem extrapolating track \n" ) ;
1119 // return ;
1120 // }
1121  double xExtra = radius * cos(phiExtra) ;
1122  double yExtra = radius * sin(phiExtra) ;
1123 
1124  double tPhi = atan2(yExtra-yCircleCenter,xExtra-xCircleCenter);
1125 
1126 // if ( tPhi < 0 ) tPhi += 2. * M_PI ;
1127 
1128  double tPsi = tPhi - double(q) * 0.5 * M_PI / fabs((double)q) ;
1129  if ( tPsi > 2. * M_PI ) tPsi -= 2. * M_PI ;
1130  if ( tPsi < 0. ) tPsi += 2. * M_PI ;
1131 //
1132 // Update track parameters
1133 //
1134  r0 = radius ;
1135  phi0 = phiExtra ;
1136  z0 = zExtra ;
1137  psi = tPsi ;
1138 }
1139 /*:>--------------------------------------------------------------------
1140 **: METHOD: Updates track parameters to point of closest approach
1141 **:
1142 **:
1143 **: AUTHOR: ppy - P.P. Yepes, yepes@rice.edu
1144 **: ARGUMENTS:
1145 **: IN:
1146 **: xBeam - x Beam axis
1147 **: yBeam - y Beam axis
1148 **: rMax - radius of point of closest approach beyond which no update
1149 **:
1150 **:>------------------------------------------------------------------*/
1151 void FtfBaseTrack::updateToClosestApproach ( double xBeam, double yBeam, double rMax) {
1152  double rc, xc, yc ;
1153  Ftf3DHit closest = getClosest ( xBeam, yBeam, rc, xc, yc ) ;
1154 // ftfLog ( "FtfBaseTrack::updateClosestApproach: closest x y z %f %f %f \n",
1155 // closest.x, closest.y, closest.z ) ;
1156 
1157  double radius = ::sqrt(closest.x*closest.x+closest.y*closest.y);
1158  if ( radius > rMax ) return ;
1159 //
1160  double tPhi = atan2(closest.y-yc,closest.x-xc);
1161 
1162 // if ( tPhi < 0 ) tPhi += 2. * M_PI ;
1163 
1164  double tPsi = tPhi - double(q) * 0.5 * M_PI / fabs((double)q) ;
1165  if ( tPsi > 2. * M_PI ) tPsi -= 2. * M_PI ;
1166  if ( tPsi < 0. ) tPsi += 2. * M_PI ;
1167 //
1168 // Update track parameters
1169 //
1170  r0 = radius ;
1171  phi0 = atan2(closest.y,closest.x) ;
1172  if ( phi0 < 0 ) phi0 += 2. * M_PI ;
1173  z0 = closest.z ;
1174  psi = tPsi ;
1175 }
1176 
1177 
1178 /*:>--------------------------------------------------------------------
1179 **: METHOD: Extrapolation of a track to the given pathlenght
1180 **:
1181 **:
1182 **:
1183 **: AUTHOR: JB, Jens Berger, jberger@bnl.gov
1184 **: ARGUMENTS:
1185 **: IN:
1186 **: doubel pathlength: pathlength of the track, staring at x0,y0,z0
1187 **: OUT:
1188 **: one of pablos fancy Ftf3DHit
1189 **:
1190 **:>------------------------------------------------------------------*/
1191 Ftf3DHit FtfBaseTrack::extrapolate2PathLength(double pathlength)
1192 {
1193  // some helix para
1194 
1195  // BFilef scaled with 0.01
1196  double Bfield=getPara()->bField * 0.01;
1197  double c=0.3;
1198  double lambda=atan(tanl);
1199  double kapa=(c*q*Bfield)/pt;
1200  double heli=-((q*Bfield)/fabs(q*Bfield));
1201  double phi=psi-heli*M_PI/2;
1202  // staring point
1203  double x0=r0*cos(phi0);
1204  double y0=r0*sin(phi0);
1205 
1206  Ftf3DHit CoordOfExtrapol;
1207  CoordOfExtrapol.x = x0 + (1/kapa)*(cos(phi+heli*pathlength*kapa*cos(lambda))-cos(phi));
1208  CoordOfExtrapol.y = y0 + (1/kapa)*(sin(phi+heli*pathlength*kapa*cos(lambda))-sin(phi));
1209  CoordOfExtrapol.z = z0 + pathlength*sin(lambda);
1210 
1211  // debug
1212  //cout<<"x0:"<<x0<<" y0:"<<y0<<" z0:"<<" lambda:"<<lambda<<z0<<" phi:"<<phi<<" h:"<<heli<<" kapa:"<<kapa<<endl;
1213  //cout<<" xs:"<<CoordOfExtrapol.x<<" ys:"<<CoordOfExtrapol.y<<" zs:"<<CoordOfExtrapol.z<<endl;
1214 
1215 
1216  // return coord of extrapolation
1217  return CoordOfExtrapol;
1218 }
1219 
1220 /*:>--------------------------------------------------------------------
1221 **: METHOD: Get the Radius of the track, helix at X,Y center
1222 **:
1223 **:
1224 **:
1225 **: AUTHOR: JB, Jens Berger, jberger@bnl.gov
1226 **: ARGUMENTS:
1227 **: IN:
1228 **: nada
1229 **: OUT:
1230 **: radius
1231 **:
1232 **:>------------------------------------------------------------------*/
1233 double FtfBaseTrack::getRadius()
1234 {
1235  double radius=pt / ( bFactor * getPara()->bField );
1236 
1237  return radius;
1238 }
1239 
1240 /*:>--------------------------------------------------------------------
1241 **: METHOD: Get y center of the corresponding radius of the track, helix
1242 **:
1243 **:
1244 **:
1245 **: AUTHOR: JB, Jens Berger, jberger@bnl.gov
1246 **: ARGUMENTS:
1247 **: IN:
1248 **: nada
1249 **: OUT:
1250 **: x center
1251 **:
1252 **:>------------------------------------------------------------------*/
1253 double FtfBaseTrack::getXCenter()
1254 {
1255  double tPhi0 = psi + double(q) * 0.5 * M_PI / fabs((double)q) ;
1256  // staring point
1257  double x0=r0*cos(phi0);
1258 
1259  return ( x0- getRadius() * cos(tPhi0) );
1260  }
1261 /*:>--------------------------------------------------------------------
1262 **: METHOD: Get y center of the corresponding radius of the track, helix
1263 **:
1264 **:
1265 **:
1266 **: AUTHOR: JB, Jens Berger, jberger@bnl.gov
1267 **: ARGUMENTS:
1268 **: IN:
1269 **: nada
1270 **: OUT:
1271 **: y center
1272 **:
1273 **:>------------------------------------------------------------------*/
1274 double FtfBaseTrack::getYCenter()
1275 {
1276  double tPhi0 = psi + double(q) * 0.5 * M_PI / fabs((double)q) ;
1277  // staring point
1278  double y0=r0*sin(phi0);
1279 
1280  return ( y0 - getRadius() * sin(tPhi0) );
1281  }
1282 
1283 void FtfBaseTrack::startLoop( ){ currentHit = firstHit ; } ;
1284 int FtfBaseTrack::done ( ) { return currentHit != 0 ; } ;