StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
FtfTrack.cxx
1 //:>------------------------------------------------------------------
2 //: FILE: FtfTrack.cxx
3 //: HISTORY:
4 //: 28oct1996 version 1.00
5 //: 11aug1999 ppy primary flag fill in filling routines
6 //: 22aug1999 ppy fixing Debug routines (TRDEBUG flag on)
7 //: 23aug1999 ppy change loop order in seekNextHit
8 //: 29aug1999 ppy move fill tracks from follow to build
9 //: 19nov1999 ppy add maxChi2Primary to decide whether track is primary
10 //: 27jan2000 ppy refHit replaced by xRefHit and yRefHit
11 //: 27jan2000 VOLUME, ROW and AREA classes replaced by FtfContainer
12 //: 17feb2000 ddXy and ddSz trying to catch divisions by zero
13 //: 10Aug2001 Adding bFieldPolarity to handle negative bField
14 //: 4sep2001 Add way to followHitSelection to correct but
15 //: when extrapolating outwards
16 //:
17 //:<------------------------------------------------------------------
18 //:>------------------------------------------------------------------
19 //: CLASS: FtfTrack
20 //: DESCRIPTION: Functions associated with this class
21 //: AUTHOR: ppy - Pablo Yepes, yepes@physics.rice.edu
22 //:>------------------------------------------------------------------
23 //#include <memory.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <math.h>
27 #include "FtfTrack.h"
28 #include "FtfHit.h"
29 
30 //extern FtfFinder tracker ;
31 
32 
33 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
34 // Add hits to track
35 // Arguments:
36 // thisHit: hit pointer
37 // way : >0 add at beginning, <0 at end
38 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
39 void FtfTrack::add ( FtfHit *thisHit, int way )
40 {
41 //
42 // Increment # hits in this track
43 //
44  nHits++ ;
45 //
46 // Update pointers
47 //
48  if ( way < 0 || nHits == 1 ) {
49  if ( nHits > 1 ) ((FtfBaseHit *)lastHit)->nextTrackHit = thisHit ;
50  lastHit = thisHit ;
51  innerMostRow = ((FtfBaseHit *)lastHit)->row ;
52  xLastHit = ((FtfBaseHit *)lastHit)->x ;
53  yLastHit = ((FtfBaseHit *)lastHit)->y ;
54  }
55  else {
56  ((FtfBaseHit *)thisHit)->nextTrackHit = firstHit ;
57  firstHit = thisHit ;
58  outerMostRow = ((FtfBaseHit *)firstHit)->row ;
59  }
60 //
61 // Declare hit as used and fill chi2
62 //
63  thisHit->setStatus ( this ) ;
64 //
65 // Check whether a fit update is needed
66 //
67  if ( nHits < getPara()->minHitsForFit ) return ;
68 //
69 // Include hit in xy fit parameter calculation
70 //
71 
72  s11Xy = s11Xy + thisHit->wxy ;
73  s12Xy = s12Xy + thisHit->wxy * thisHit->xp ;
74  s22Xy = s22Xy + thisHit->wxy * square(thisHit->xp) ;
75  g1Xy = g1Xy + thisHit->wxy * thisHit->yp ;
76  g2Xy = g2Xy + thisHit->wxy * thisHit->xp * thisHit->yp ;
77 
78 
79  if ( nHits > getPara()->minHitsForFit )
80  {
81  ddXy = s11Xy * s22Xy - square ( s12Xy ) ;
82  if ( ddXy != 0 ) {
83  a1Xy = ( g1Xy * s22Xy - g2Xy * s12Xy ) / ddXy ;
84  a2Xy = ( g2Xy * s11Xy - g1Xy * s12Xy ) / ddXy ;
85  }
86  else {
87  if ( getPara()->infoLevel > 0 ) {
88  LOG(ERR, "FtfTrack:add: ddXy = 0 \n" ) ;
89  }
90  }
91  }
92 //
93 // Now in the sz plane
94 //
95  if ( getPara()->szFitFlag ) {
96  s11Sz = s11Sz + thisHit->wz ;
97  s12Sz = s12Sz + thisHit->wz * thisHit->s ;
98  s22Sz = s22Sz + thisHit->wz * thisHit->s * thisHit->s ;
99  g1Sz = g1Sz + thisHit->wz * thisHit->z ;
100  g2Sz = g2Sz + thisHit->wz * thisHit->s * thisHit->z ;
101 
102  if ( nHits > getPara()->minHitsForFit ) {
103 
104  ddSz = s11Sz * s22Sz - s12Sz * s12Sz ;
105  if ( ddSz != 0 ) {
106  a1Sz = ( g1Sz * s22Sz - g2Sz * s12Sz ) / ddSz ;
107  a2Sz = ( g2Sz * s11Sz - g1Sz * s12Sz ) / ddSz ;
108  }
109  else
110  {
111  if ( getPara()->infoLevel > 0 ) {
112  LOG(ERR, "FtfTrack:add: ddSz = 0 \n" ) ;
113  }
114  }
115  }
116  }
117 }
118 //****************************************************************************
119 // Fill track information tables
120 //****************************************************************************
121 void FtfTrack::add ( FtfTrack *piece )
122 {
123 //
124 // Get circle parameters
125 //
126  s11Xy += piece->s11Xy ;
127  s12Xy += piece->s12Xy ;
128  s22Xy += piece->s22Xy ;
129  g1Xy += piece->g1Xy ;
130  g2Xy += piece->g2Xy ;
131 
132  ddXy = s11Xy * s22Xy - square ( s12Xy ) ;
133  a1Xy = ( g1Xy * s22Xy - g2Xy * s12Xy ) / ddXy ;
134  a2Xy = ( g2Xy * s11Xy - g1Xy * s12Xy ) / ddXy ;
135 //
136 // Now in the sz plane
137 //
138  if ( getPara()->szFitFlag ) {
139  double det1 = s11Sz * s22Sz - s12Sz * s12Sz ;
140  dtanl = (double) ( s11Sz / det1 );
141  dz0 = (double) ( s22Sz / det1 );
142 
143  double det2 = piece->s11Sz * piece->s22Sz - piece->s12Sz * piece->s12Sz ;
144  piece->dtanl = (double) ( piece->s11Sz / det2 );
145  piece->dz0 = (double) ( piece->s22Sz / det2 );
146 
147  double weight1 = 1./(dtanl*dtanl);
148  double weight2 = 1./(piece->dtanl*piece->dtanl);
149  double weight = (weight1+weight2);
150  tanl = ( weight1 * tanl + weight2 * piece->tanl ) / weight ;
151 
152  weight1 = 1./(dz0*dz0);
153  weight2 = 1./(piece->dz0*piece->dz0);
154  weight = (weight1+weight2);
155  z0 = ( weight1 * z0 + weight2 * piece->z0 ) / weight ;
156  }
157 
158 //
159 // Add space points to first track
160 //
161  int counter ;
162  if ( piece->outerMostRow < outerMostRow ){
163  if ( lastHit != NULL ) {
164  counter = 0 ;
165  for ( currentHit = piece->firstHit ;
166  currentHit != 0 && counter < piece->nHits ;
167  currentHit = ((FtfBaseHit *)currentHit)->nextTrackHit ) {
168  ((FtfBaseHit *)currentHit)->track = this ;
169  counter++ ;
170  }
171  ((FtfBaseHit *)lastHit)->nextTrackHit = piece->firstHit ;
172  lastHit = piece->lastHit ;
173  }
174  piece->firstHit = 0 ;
175  innerMostRow = piece->innerMostRow ;
176  xLastHit = piece->xLastHit ;
177  yLastHit = piece->yLastHit ;
178  }
179  else {
180  if ( piece->lastHit != NULL ) {
181  counter = 0 ;
182  for ( currentHit = (FtfHit *)piece->firstHit ;
183  currentHit != 0 && counter < piece->nHits ;
184  currentHit = ((FtfBaseHit *)currentHit)->nextTrackHit ) {
185  ((FtfBaseHit *)currentHit)->track = this ;
186  counter++;
187  }
188  ((FtfBaseHit *)piece->lastHit)->nextTrackHit = firstHit ;
189  firstHit = piece->firstHit ;
190  }
191  outerMostRow = piece->outerMostRow ;
192  piece->firstHit = 0 ;
193  }
194 //
195 //
196  nHits += piece->nHits ;
197  chi2[0] += piece->chi2[0] ;
198  chi2[1] += piece->chi2[1] ;
199 //
200 // Update track parameters
201 //
202 //
203  getPara()->szFitFlag = 0 ;
204  if ( getPara()->fillTracks ) fill ( ) ;
205  getPara()->szFitFlag = 1 ;
206 //
207 //
208 // Declare track 2 not to be used
209 //
210  piece->flag = -1 ;
211 }
212 
213 //****************************************************************************
214 // Control how the track gets built
215 //****************************************************************************
216 int FtfTrack::buildTrack ( FtfHit *frstHit, FtfContainer *volume ) {
217 //
218 // Add first hit to track
219 //
220  add ( frstHit, GO_DOWN ) ;
221 //
222 // Try to build a segment first
223 //
224  if ( !segment ( volume, GO_DOWN ) ) return 0 ;
225 //
226 // If segment build go for a real track with a fit
227 //
228  int rowToStop = getPara()->rowInnerMost ;
229  if ( !follow ( volume, GO_DOWN, rowToStop ) ) return 0 ;
230 //
231 // Now to extent track the other direction if requested
232 //
233  if ( getPara()->goBackwards ) {
234  follow ( volume, GO_UP, getPara()->rowOuterMost ) ;
235  }
236 //
237 // Fill tracks
238 //
239  if ( getPara()->fillTracks )
240  fill ( ) ;
241 #ifdef TRDEBUG
242  debugFill ( ) ;
243 #endif
244 
245  return 1 ;
246 }
247 //***************************************************************************
248 // Calculates dEdx
249 //***************************************************************************
250 void FtfTrack::dEdx ( ){
251  int i, j ;
252  FtfHit *nextHit ;
253  int nTruncate = max(1,
254  getPara()->dEdxNTruncate*nHits/100) ;
255  nTruncate = min(nHits/2,nTruncate) ;
256 //
257 // Define array to keep largest de's
258 //
259  double *de = new double[nTruncate] ;
260 //
261 // Reset
262 //
263  dedx = 0.F ;
264  memset ( de, 0, nTruncate*sizeof(double) ) ;
265 //
266 //
267 //
268  for ( nextHit = (FtfHit *)firstHit ;
269  nextHit != 0 ;
270  nextHit = (FtfHit *)nextHit->nextTrackHit) {
271 
272  dedx += nextHit->q ;
273 
274  if ( nextHit->q < de[0] ) continue ;
275 
276  for ( i = nTruncate-1 ; i>=0 ; i-- ){
277  if ( nextHit->q > de[i] ){
278  for ( j=0 ; j<i ; j++ ) de[j] = de[j+1] ;
279  de[i] = nextHit->q ;
280  break ;
281  }
282  }
283  }
284 //
285 // Subtract largest de
286 //
287  for ( i=0 ; i<nTruncate ; i++ ) dedx -= de[i] ;
288  dedx = dedx / length ;
289 /* End track in required volume condition */
290 
291 }
292 //***********************************************************************
293 // Delete track candidate
294 //***********************************************************************
295 void FtfTrack::deleteCandidate(void)
296 {
297  FtfHit *curentHit = (FtfHit *)firstHit ;
298  FtfHit *nextHit ;
299 #ifdef TRDEBUG
300  debugDeleteCandidate ( ) ;
301 #endif
302  while ( curentHit != 0 )
303  {
304  nextHit = (FtfHit *)curentHit->nextTrackHit;
305  curentHit->nextTrackHit = 0 ;
306  curentHit->xyChi2 =
307  curentHit->szChi2 =
308  curentHit->s = 0.F ;
309 
310  curentHit->setStatus ( 0 ) ;
311  curentHit = nextHit;
312  }
313 }
314 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
315 // Fills track variables with or without fit
316 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
317 void FtfTrack::fill ( ) {
318 //
319 // Get circle parameters
320 //
321 
322  double xc, yc ;
323  double rc = sqrt ( a2Xy * a2Xy + 1 ) / ( 2 * fabs(a1Xy) ) ;
324  pt = (double)fabs(bFactor * getPara()->bField * rc );
325  double xParameters = 0.;
326  double yParameters = 0.;
327 //
328  if ( pt > getPara()->ptMinHelixFit ) {
329  double combinedChi2 = 0.5*(chi2[0]+chi2[1])/nHits ;
330  if ( getPara()->primaries && combinedChi2 < getPara()->maxChi2Primary )
331  getPara()->vertexConstrainedFit = 1 ;
332  else
333  getPara()->vertexConstrainedFit = 0 ;
334 
335  fitHelix ( ) ;
336 
337 // if ( id == 303) Print(31);
338  if ( getPara()->vertexConstrainedFit && getPara()->parameterLocation ){
339  updateToRadius ( sqrt(xLastHit*xLastHit+yLastHit*yLastHit) ) ;
340  }
341  else if ( !getPara()->vertexConstrainedFit && !getPara()->parameterLocation ) {
342  updateToClosestApproach ( getPara()->xVertex, getPara()->yVertex, 2000. ) ;
343  }
344 
345 // if ( id == 1 ) Print(30);
346  }
347  else{
348 
349  if ( getPara()->primaries ){
350  //cout << "." << flush;
351  fillPrimary ( xc, yc, rc, getPara()->xVertex, getPara()->yVertex ) ;
352  if ( getPara()->parameterLocation ) {// give track parameters at inner most point
353  updateToRadius ( sqrt(xLastHit*xLastHit+yLastHit*yLastHit) ) ;
354  }
355  }
356  else { // Secondaries now
357  xc = - a2Xy / ( 2. * a1Xy ) + xRefHit ;
358  yc = - 1. / ( 2. * a1Xy ) + yRefHit ;
359  if ( getPara()->parameterLocation ) { // give track parameters at inner most point
360  xParameters = xLastHit ;
361  yParameters = yLastHit ;
362  }
363  else { // give parameters at point of closest approach
364  getClosest ( getPara()->xVertex, getPara()->yVertex,
365  rc, xc, yc, xParameters, yParameters ) ;
366  }
367  fillSecondary ( xc, yc, xParameters, yParameters ) ;
368  }
369 //
370 // Get Errors
371 //
372  if ( getPara()->getErrors ) {
373  getErrorsCircleFit ( (double)xc, (double)yc, (double)rc ) ;
374  double det = s11Sz * s22Sz - s12Sz * s12Sz ;
375  dtanl = (double) ( s11Sz / det );
376  dz0 = (double) ( s22Sz / det );
377  }
378  }
379 }
380 //****************************************************************************
381 // Fill track information variables
382 //****************************************************************************
383 void FtfTrack::fillPrimary ( double &xc, double &yc, double &rc,
384  double xPar, double yPar ) {
385 //
386 // Get circle parameters
387 //
388  xc = getPara()->xVertex - a2Xy / ( 2. * a1Xy ) ;
389  yc = getPara()->yVertex - 1. / ( 2. * a1Xy ) ;
390 //
391 // Get track parameters
392 //
393  double angle_vertex = atan2 ( yPar-yc, xPar-xc ) ;
394  if ( angle_vertex < 0. ) angle_vertex = angle_vertex + twoPi ;
395 
396  double dx_last = xLastHit - xc ;
397  double dy_last = yLastHit - yc ;
398  double angle_last = atan2 ( dy_last, dx_last ) ;
399  if ( angle_last < 0. ) angle_last = angle_last + twoPi ;
400 //
401 // Get the rotation
402 //
403  double d_angle = angle_last - angle_vertex ;
404 
405 // if ( d_angle > pi ) d_angle -= twoPi ;
406  if ( d_angle < -pi ) d_angle += twoPi ;
407 
408  q = getPara()->bFieldPolarity * ( ( d_angle < 0 ) ? 1 : -1 ) ;
409  r0 = sqrt(xPar*xPar+yPar*yPar) ;
410  phi0 = atan2(yPar,xPar) ;
411  if ( phi0 < 0 ) phi0 += 2. * M_PI ;
412  psi = (double)(angle_vertex - getPara()->bFieldPolarity*q * 0.5F * pi) ;
413  if ( psi < 0 ) psi = (double)(psi + twoPi );
414  if ( psi > twoPi ) psi = (double)(psi - twoPi );
415 //
416 // Get z parameters if needed
417 //
418  if ( getPara()->szFitFlag == 1 ){
419  tanl = -(double)a2Sz ;
420  z0 = (double)(a1Sz + a2Sz * ( length - rc * d_angle * getPara()->bFieldPolarity*q ) );
421  }
422  else if ( getPara()->szFitFlag == 2 ) {
423  tanl = ((FtfBaseHit *)firstHit)->z /
424  (double)sqrt ( ((FtfBaseHit *)firstHit)->x*((FtfBaseHit *)firstHit)->x +
425  ((FtfBaseHit *)firstHit)->y*((FtfBaseHit *)firstHit)->y ) ;
426  z0 = 0.F ;
427  }
428 //
429 // Store some more track info
430 //
431  eta = seta(1.,tanl ) ;
432 //
433 // Set primary track
434 //
435  flag = 1 ;
436 
437 }
438 //****************************************************************************
439 //
440 // Fill track information tables
441 //
442 //****************************************************************************
443 void FtfTrack::fillSecondary ( double &xc, double &yc,
444  double xPar, double yPar )
445 {
446 /*--------------------------------------------------------------------------
447  Get angles for initial and final points
448 ------------------------------------------------------------------------------*/
449  double dx1 = ((FtfBaseHit *)firstHit)->x - xc ;
450  double dy1 = ((FtfBaseHit *)firstHit)->y - yc ;
451  double angle1 = atan2 ( dy1, dx1 ) ;
452  if ( angle1 < 0. ) angle1 = angle1 + twoPi ;
453 
454  double dx2 = xLastHit - xc ;
455  double dy2 = yLastHit - yc ;
456  double angle2 = atan2 ( dy2, dx2 ) ;
457  if ( angle2 < 0. ) angle2 = angle2 + twoPi ;
458 /*--------------------------------------------------------------------------
459  Get the rotation
460 ------------------------------------------------------------------------------*/
461  double dangle = angle2 - angle1 ;
462  // if ( dangle > pi ) dangle = dangle - twoPi ;
463  if ( dangle < -pi ) dangle = dangle + twoPi ;
464 
465  q = getPara()->bFieldPolarity * ( ( dangle > 0 ) ? 1 : -1 ) ;
466  r0 = ((FtfHit *)lastHit)->r ;
467  phi0 = ((FtfHit *)lastHit)->phi ;
468  psi = (double)(angle2 - getPara()->bFieldPolarity * q * piHalf );
469  if ( psi < 0 ) psi = (double)(psi + twoPi );
470 //
471 // Get z parameters if needed
472 //
473  if ( getPara()->szFitFlag ){
474  tanl = -(double)a2Sz ;
475  z0 = (double)(a1Sz + a2Sz * length );
476  }
477  else{
478  tanl = ((FtfBaseHit *)firstHit)->z /
479  (double)sqrt ( ((FtfBaseHit *)firstHit)->x*((FtfBaseHit *)firstHit)->x +
480  ((FtfBaseHit *)firstHit)->y*((FtfBaseHit *)firstHit)->y ) ;
481  z0 = 0.F ;
482  }
483 //
484 //--> Store some more track info
485 //
486  eta = seta(1., tanl ) ;
487 //
488 // Set primary track flag
489 //
490  flag = 0 ;
491 }
492 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
493 // Adds hits to a track chosing the closest to fit
494 // Arguments:
495 // volume: volume pointer
496 // way : which way to procede in r (negative or positive)
497 // row_to_stop: row index where to stop
498 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
499 int FtfTrack::follow ( FtfContainer *volume, int way, int ir_stop ) {
500 
501  FtfHit *nextHit ;
502 
503  if ( way < 0 )
504  nextHit = (FtfHit *)lastHit ;
505  else
506  nextHit = (FtfHit *)firstHit ;
507 #ifdef TRDEBUG
508  if ( getPara()->trackDebug && getPara()->debugLevel >= 2 )
509  LOG(ERR, "FtfTrack::follow: ===> Going into Track extension <===\n" );
510 #endif
511 //
512 // Define variables to keep total chi2
513 //
514  double xyChi2 = chi2[0] ;
515  double szChi2 = chi2[1] ;
516 
517 //
518 // Loop as long a a hit is found and the segment
519 // is shorter than n_hit_segm
520 //
521  while ( way * nextHit->row < way * ir_stop ) {
522 //
523 // Select next hit
524 //
525  chi2[0] = getPara()->hitChi2Cut ;
526 
527  nextHit = seekNextHit ( volume, nextHit, way*getPara()->trackRowSearchRange, USE_FOLLOW ) ;
528 
529 #ifdef TRDEBUG
530  if ( getPara()->trackDebug && getPara()->debugLevel >= 1 ){
531  if ( nextHit != 0 ){
532  LOG(ERR, "FtfTrack::follow: Search succesful, hit selected %d\n",
533  nextHit->id );
534 // nextHit->Show ( getPara()->color_track ) ;
535  }
536  else{
537  LOG(ERR, "FtfTrack::follow: Search unsuccesful\n" );
538  if ( chi2[0]+chi2[1] > getPara()->hitChi2Cut )
539  LOG(ERR, " hit chi2 %f larger than cut %f ", chi2[0]+chi2[1],
540  getPara()->hitChi2Cut ) ;
541  }
542  debugAsk () ;
543  }
544 #endif
545 //
546 // Stop if nothing found
547 //
548  if ( nextHit == 0 ) break ;
549 //
550 // Keep total chi2
551 //
552  double lxyChi2 = chi2[0]-chi2[1] ;
553  xyChi2 += lxyChi2 ;
554  nextHit->xyChi2 = lxyChi2 ;
555 //
556 // if sz fit update track length
557 //
558  if ( getPara()->szFitFlag ) {
559  length = nextHit->s ;
560  szChi2 += chi2[1] ;
561  nextHit->szChi2 = chi2[1] ;
562 
563  }
564 //
565 // Add hit to track
566 //
567  add ( nextHit, way ) ;
568 
569  } // End while
570 //
571 // Check # hits
572 //
573  if ( nHits < getPara()->minHitsPerTrack ) return 0 ;
574 //
575 // Store track chi2
576 //
577  chi2[0] = xyChi2 ;
578  chi2[1] = szChi2 ;
579 //
580 // Check total chi2
581 //
582  double normalized_chi2 = (chi2[0]+chi2[1])/nHits ;
583  if ( normalized_chi2 > getPara()->trackChi2Cut ) return 0 ;
584 //
585  return 1 ;
586 }
587 /*******************************************************************************
588  Reconstructs tracks
589 *********************************************************************************/
590 int FtfTrack::followHitSelection ( FtfHit *baseHit, FtfHit *candidateHit, int way ){
591 //
592  double lszChi2 = 0 ;
593  double lchi2 ;
594  double slocal=0, deta, dphi ;
595  double dx, dy, dxy, dsz, temp ;
596 //
597 // Check delta eta
598 //
599 // if ( baseHit->dz < 1000. && candidateHit->dz < 1000 ){
600  deta = fabs((baseHit->eta)-(candidateHit->eta)) ;
601  if ( deta > getPara()->deta ) return 0 ;
602 // }
603 // else deta = 0.F ;
604 //
605 // Check delta phi
606 //
607  dphi = fabs((baseHit->phi)-(candidateHit->phi)) ;
608  if ( dphi > getPara()->dphi && dphi < twoPi-getPara()->dphi ) return 0 ;
609 //
610 // If looking for secondaries calculate conformal coordinates
611 //
612  if ( getPara()->primaries == 0 ){
613  double xx = candidateHit->x - xRefHit ;
614  double yy = candidateHit->y - yRefHit ;
615  double rr = xx * xx + yy * yy ;
616  candidateHit->xp = xx / rr ;
617  candidateHit->yp = - yy / rr ;
618 
619  candidateHit->wxy = rr * rr /
620  ( square(getPara()->xyErrorScale) *
621  ( square(candidateHit->dx) + square(candidateHit->dy) ) ) ;
622  }
623 //
624 // Calculate distance in x and y
625 //
626  temp = (a2Xy * candidateHit->xp - candidateHit->yp + a1Xy) ;
627  dxy = temp * temp / ( a2Xy * a2Xy + 1.F ) ;
628 //
629 // Calculate chi2
630 //
631  lchi2 = (dxy * candidateHit->wxy) ;
632 
633  if ( lchi2 > chi2[0] ) return 0 ;
634 //
635 // Now in the sz plane
636 //
637  if ( getPara()->szFitFlag ){
638 //
639 // Get "s" and calculate distance hit-line
640 //
641  dx = baseHit->x - candidateHit->x ;
642  dy = baseHit->y - candidateHit->y ;
643  slocal = baseHit->s - way * sqrt ( dx * dx + dy * dy ) ;
644 
645  temp = (a2Sz * slocal - candidateHit->z + a1Sz) ;
646  dsz = temp * temp / ( a2Sz * a2Sz + 1 ) ;
647 //
648 // Calculate chi2
649 //
650  lszChi2 = dsz * candidateHit->wz ;
651  lchi2 += lszChi2 ;
652  }
653  else {
654  lszChi2 = 0.F ;
655  //slocal = 0;
656  }
657 //
658 // Check whether the chi2 square is better than previous one
659 //
660  if ( lchi2 < chi2[0] ) {
661  chi2[0] = (double)lchi2 ;
662  chi2[1] = (double)lszChi2 ;
663 
664  if ( getPara()->szFitFlag ) candidateHit->s = (double)slocal ;
665 //
666 // if a good chi2 is found let's stop here
667 //
668  if ( lchi2 < getPara()->goodHitChi2 ) return 2 ;
669 
670  return 1 ;
671  }
672 //
673 // Return the selected hit
674 //
675  return 0 ;
676 }
677 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
678 // Merges tracks
679 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
680 int FtfTrack::mergePrimary ( FtfContainer *trackArea ){
681  short track_merged ;
682  register int areaIndex ;
683  int i_phi, i_eta ;
684  FtfTrack *i_track = 0 ;
685  int ip, ie ;
686  double delta_psi ;
687 //
688 // Check Track is primary
689 //
690  if ( flag != 1 ) return 0 ;
691 //-
692 // Get track area
693 //
694  i_phi = (int)(( psi - getPara()->phiMinTrack ) / getPara()->phiSliceTrack + 1 );
695  if ( i_phi < 0 ) {
696  LOG(ERR, " Track phi index too low %d \n", i_phi ) ;
697  i_phi = 1 ;
698  }
699  if ( i_phi >= getPara()->nPhiTrackPlusOne ) {
700  LOG(ERR, " Track phi index too high %d \n", i_phi ) ;
701  i_phi = getPara()->nPhiTrack ;
702  }
703 //
704 // Now eta
705 //
706  i_eta = (int)(( eta - getPara()->etaMinTrack ) / getPara()->etaSliceTrack + 1 );
707  if ( i_eta <= 0 ) {
708  LOG(ERR, " Track eta index too low %d \n", i_eta ) ;
709  i_eta = 1 ;
710  }
711  if ( i_eta >= getPara()->nEtaTrackPlusOne ) {
712  LOG(ERR, " Track eta index too high %d \n", i_eta ) ;
713  i_eta = getPara()->nEtaTrack ;
714  }
715 //
716 // Loop around selected area
717 //
718  track_merged = 0 ;
719  for ( ip = max(i_phi-1,1) ; ip < min(i_phi+2,getPara()->nPhiTrackPlusOne) ; ip++ ) {
720  for ( ie = max(i_eta-1,1) ; ie < min(i_eta+2,getPara()->nEtaTrackPlusOne) ; ie++ ) {
721  areaIndex = ip * getPara()->nEtaTrackPlusOne + ie ;
722 //
723 // Loop over tracks
724 //
725  for ( i_track = (FtfTrack *)trackArea[areaIndex].first ;
726  i_track != 0 ;
727  i_track = i_track->getNextTrack() ) {
728 //
729 // Reject track if it is not good
730 //
731  if ( i_track->flag < 0 ) continue ;
732 //
733 // Compare both tracks
734 //
735 // No overlapping tracks
736  short delta1 = i_track->outerMostRow - outerMostRow ;
737  short delta2 = i_track->innerMostRow - innerMostRow ;
738  if ( delta1 * delta2 <= 0 ) continue ;
739 //
740 // Tracks close enough
741 //
742  if ( fabs(eta-i_track->eta) > getPara()->detaMerge ) continue ;
743  delta_psi = (double)fabs(psi - i_track->psi) ;
744  if ( delta_psi > getPara()->dphiMerge && delta_psi < twoPi - getPara()->dphiMerge ) continue ;
745 
746  i_track->add ( this ) ;
747 #ifdef TRDEBUG
748  if ( getPara()->debugLevel > 1 )
749  LOG(ERR, " \n Track %d merge into %d ", this->id, i_track->id ) ;
750 #endif
751  track_merged = 1 ;
752  break ;
753  }
754  }
755  }
756 //
757 //-> If track not matched add it
758 //
759  if ( track_merged == 0 ) {
760  areaIndex = i_phi * getPara()->nEtaTrackPlusOne + i_eta ;
761  if ( trackArea[areaIndex].first == 0 )
762  trackArea[areaIndex].first =
763  trackArea[areaIndex].last = (void *)this ;
764  else {
765  ((FtfTrack *)trackArea[areaIndex].last)->nxatrk = this ;
766  trackArea[areaIndex].last = (void *)this ;
767  }
768  }
769  return track_merged ;
770 }
771 /*************************************************************************
772  Recontruct primary tracks
773 *************************************************************************/
774 void FtfTrack::reset (void)
775 {
776 /*----------------------------------------------------------------------
777  Set fit parameters to zero
778 ----------------------------------------------------------------------*/
779 
780  flag = getPara()->primaries ;
781  nHits = 0 ;
782  s11Xy =
783  s12Xy =
784  s22Xy =
785  g1Xy =
786  g2Xy =
787  chi2[0] = 0.F ;
788  nxatrk = 0 ;
789  if ( getPara()->szFitFlag )
790  {
791  s11Sz =
792  s12Sz =
793  s22Sz =
794  g1Sz =
795  g2Sz =
796  chi2[1] =
797  length = 0.F ;
798  }
799 }
800 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
801 // Function to look for next hit
802 // Input: volume: Volume pointer
803 // baseHit: Last point in track
804 // n_r_steps: How many rows search and which way (up or down)
805 // which_function: Function to be used to decide whether the hit is good
806 // Returns: Selected hit
807 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
808 FtfHit *FtfTrack::seekNextHit ( FtfContainer *volume,
809  FtfHit *baseHit,
810  int n_r_steps,
811  int which_function ) {
812 #define N_LOOP 9
813  int loop_eta[N_LOOP] = { 0, 0, 0,-1,-1,-1, 1, 1, 1 } ;
814  int loop_phi[N_LOOP] = { 0,-1, 1, 0,-1, 1, 0,-1, 1 };
815 
816 
817  int ir, irp, ipp, itp, k;
818  register int areaIndex ;
819  int result ;
820 
821 //-------------------------------------------------------------------------------
822 // Calculate limits on the volume loop
823 //-----------------------------------------------------------------------------*/
824  int initialRow, way ;
825  if ( n_r_steps < 0 ) {
826  initialRow = max(1, (baseHit->row - getPara()->rowInnerMost)/getPara()->modRow);
827  n_r_steps = min(initialRow,-n_r_steps ) ;
828  way = -1 ;
829  }
830  else {
831  initialRow = max(1, (baseHit->row - getPara()->rowInnerMost + 2)/getPara()->modRow);
832  n_r_steps = min((getPara()->rowOuterMost-initialRow+1),n_r_steps) ;
833  way = 1 ;
834  }
835 
836  FtfHit *selected_hit = 0 ;
837 //
838 // Loop over modules
839 //
840  for ( ir = 0 ; ir < n_r_steps ; ir++ ){
841  irp = initialRow + way * ir ;
842  for ( k=0; k< N_LOOP; k++){
843  ipp = baseHit->phiIndex + loop_phi[k];
844 //
845 //-- Gymnastics if phi is closed
846 //
847  if ( ipp < 1 ) {
848  if ( getPara()->phiClosed )
849  ipp = getPara()->nPhi + ipp ;
850  else
851  continue ;
852  }
853  else if ( ipp > getPara()->nPhi ) {
854  if ( getPara()->phiClosed )
855  ipp = ipp - getPara()->nPhi ;
856  else
857  continue ;
858  }
859 //
860 // Now get eta index
861 //
862  itp = baseHit->etaIndex + loop_eta[k];
863  if ( itp < 1 ) continue ;
864  if ( itp > getPara()->nEta ) continue ;
865 //
866 #ifdef TRDEBUG
867  if ( getPara()->trackDebug && getPara()->debugLevel >= 4 )
868  LOG(ERR, "FtfTrack::seekNextHit: search in row %d \n",irp ) ;
869 #endif
870 //
871 // Now loop over hits in each volume
872 //
873  areaIndex = irp * getPara()->nPhiEtaPlusOne + ipp * getPara()->nEtaPlusOne + itp ;
874  for ( FtfHit *candidateHit = (FtfHit *)volume[areaIndex].first ;
875  candidateHit != 0 ;
876  candidateHit = (FtfHit *)candidateHit->nextVolumeHit ){
877 #ifdef TRDEBUG
878  debugInVolume ( baseHit, candidateHit ) ;
879 #endif
880 //----------------------------------------------------------------------------
881 // Check whether the hit was used before
882 //--------------------------------------------------------------------------*/
883  if ( candidateHit->track != 0 ) continue ;
884 //--------------------------------------------------------------------------
885 // If first points, just choose the closest hit
886 //-------------------------------------------------------------------------- */
887  if ( which_function == USE_SEGMENT )
888  result = segmentHitSelection ( baseHit, candidateHit ) ;
889  else
890  result = followHitSelection ( baseHit, candidateHit, way ) ;
891 //
892 // Check result
893 //
894  if ( result > 0 ) {
895  selected_hit = candidateHit ;
896  if ( result ==2 ) goto found ;
897  }
898 //
899 // End hit loop
900 //
901  }
902 //
903 // End row loop
904 //
905  }
906 //
907 // End volume loop inside cone
908 //
909  }
910 found: ;
911 
912  return selected_hit ;
913 }
914 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
915 // Forms segments
916 // Arguments:
917 // volume : volume pointer
918 // way : whether to go to negative or positive ir
919 // row_to_stop: row index where to stop
920 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
921 int FtfTrack::segment( FtfContainer *volume, int way ){
922 //
923 // Define some variables
924 //
925  double dx, dy, rr ;
926  FtfHit* nextHit ;
927 //
928 // Check which way to go
929 //
930  if ( way < 0 )
931  nextHit = (FtfHit *)lastHit ;
932  else
933  nextHit = (FtfHit *)firstHit ;
934 #ifdef TRDEBUG
935  if ( getPara()->trackDebug && getPara()->debugLevel >= 4 )
936  LOG(ERR, "FtfTrack:segment: **** Trying to form segment ****\n" );
937 #endif
938 //
939 // Loop as long a a hit is found and the segment
940 // is shorter than n_hit_segm
941 //
942  while ( nextHit != 0 && nHits < getPara()->nHitsForSegment ) {
943  chi2[0] = getPara()->maxDistanceSegment ; ;
944  nextHit = seekNextHit ( volume, nextHit, way*getPara()->segmentRowSearchRange,
945  USE_SEGMENT ) ;
946 #ifdef TRDEBUG
947  if ( getPara()->trackDebug && getPara()->debugLevel > 0 ) {
948  if ( nextHit != 0 ) {
949  LOG(ERR, "FtfTrack::segment: Search succesful, hit %d selected\n",
950  nextHit->id );
951 // nextHit->Show ( getPara()->color_track ) ;
952  }
953  else
954  LOG(ERR, "FtfTrack::segment: Search unsuccesful\n" );
955  debugAsk () ;
956  }
957 #endif
958 //
959 // If sz fit update s
960 //
961  if ( nextHit != 0 ){
962 //
963 // Calculate track length if sz plane considered
964 //
965  if ( getPara()->szFitFlag ){
966  dx = ((FtfBaseHit *)nextHit)->x - ((FtfBaseHit *)lastHit)->x ;
967  dy = ((FtfBaseHit *)nextHit)->y - ((FtfBaseHit *)lastHit)->y ;
968  length += (double)sqrt ( dx * dx + dy * dy ) ;
969  nextHit->s = length ;
970  }
971 //
972 // Calculate conformal coordinates
973 //
974  if ( getPara()->primaries == 0 ){
975  rr = square ( xRefHit - nextHit->x ) +
976  square ( yRefHit - nextHit->y ) ;
977 
978 
979  nextHit->xp = ( nextHit->x - xRefHit ) / rr ;
980  nextHit->yp = - ( nextHit->y - yRefHit ) / rr ;
981  nextHit->wxy = rr * rr / ( square(getPara()->xyErrorScale) *
982  square(nextHit->dx) + square(nextHit->dy) ) ;
983  }
984 //
985 // Add hit to track
986 //
987  add ( nextHit, way ) ;
988  }
989  } // End while ( lastHit ...
990 //
991 // If number of hits is as expected return 1
992 //
993  if ( nHits == getPara()->nHitsForSegment )
994  return 1 ;
995  else
996  return 0 ;
997 }
998 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
999 // Routine to look for segments.
1000 // Arguments:
1001 // baseHit: Hit from which track is being extrapolated
1002 // candidateHit: Hit being examined as a candidate to which extend track
1003 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1004 int FtfTrack::segmentHitSelection ( FtfHit *baseHit, FtfHit *candidateHit ){
1005 
1006  double dx, dy, dr, d3, dangle ;
1007  double dphi, deta ;
1008  double angle ;
1009 //
1010 // select hit with the
1011 // the smallest value of d3 (defined below)
1012 //
1013  dphi = (double)fabs((baseHit->phi) - (candidateHit->phi)) ;
1014  if ( dphi > pi ) dphi = (double)fabs( twoPi - dphi ) ;
1015  if ( dphi > getPara()->dphi && dphi < twoPi -getPara()->dphi ) return 0 ;
1016 //
1017 // Make sure we want to look at the difference in eta
1018 //
1019  if ( baseHit->dz < 1000. && candidateHit->dz < 1000. ){
1020  deta = (double)fabs((baseHit->eta) - (candidateHit->eta)) ;
1021  if ( deta > getPara()->deta ) return 0 ;
1022  }
1023  else deta = 0.F ;
1024 
1025  dr = (double)fabs((double)(baseHit->row - candidateHit->row));
1026  d3 = (double)(toDeg * dr * ( dphi + deta ) ) ;
1027 //
1028 // If initial segment is longer than 2 store angle info in
1029 // a1Xy and a1_sz
1030 //
1031  if ( getPara()->nHitsForSegment > 2 && nHits-1 < getPara()->nHitsForSegment ) {
1032  dx = candidateHit->x - baseHit->x ;
1033  dy = candidateHit->y - baseHit->y ;
1034  angle = (double)atan2 ( dy, dx ) ;
1035  if ( angle < 0 ) angle = angle + twoPi ;
1036  lastXyAngle = angle ;
1037  }
1038 #ifdef TRDEBUG
1039  if ( getPara()->trackDebug && getPara()->debugLevel >= 3 ) {
1040  LOG(ERR, "FtfTrack::segmentHitSelection:\n");
1041  LOG(ERR, "dr,dphi,deta,distance, Min distance %7.2f %7.2f %7.2f %7.2f %7.2f\n",
1042  dr,dphi,deta,d3,chi2[0] ) ;
1043  if ( d3 < chi2[0] )
1044  LOG(ERR, "Best point, keep it !!!\n" );
1045  else{
1046  LOG(ERR, "Worse than previous, reject !!\n" );
1047 // candidateHit->Show ( getPara()->color_transparent );
1048  }
1049  debugAsk() ;
1050  }
1051 #endif
1052  if ( d3 < chi2[0] ) {
1053 //
1054 // For second hit onwards check the difference in angle
1055 // between the last two track segments
1056 //
1057  if ( nHits > 1 ) {
1058  dx = candidateHit->x - baseHit->x ;
1059  dy = candidateHit->y - baseHit->y ;
1060  angle = (double)atan2 ( dy, dx ) ;
1061  if ( angle < 0 ) angle = angle + twoPi ;
1062  dangle = (double)fabs ( lastXyAngle - angle );
1063  lastXyAngle = angle ;
1064  if ( dangle > getPara()->segmentMaxAngle ) return 0 ;
1065  }
1066 //
1067 // Check whether this is the "closest" hit
1068 //
1069  chi2[0] = d3 ;
1070  if ( d3 < getPara()->goodDistance ) return 2 ;
1071  return 1 ;
1072  }
1073 //
1074 // If hit does not fulfill criterai return 0
1075 //
1076  return 0 ;
1077 }
1078 #ifdef TRDEBUG
1079 //*****************************************************************************
1080 // Ask for a character to keep going
1081 //******************************************************************************/
1082 void FtfTrack::debugAsk (void)
1083 {
1084  char cc;
1085 
1086  LOG(ERR, "stop(s), continue (any other key)\n" );
1087  cc = getchar();
1088  if ( cc == 's' ) getPara()->trackDebug = 0 ;
1089  if ( cc == '1' ) getPara()->debugLevel = 1 ;
1090  if ( cc == '2' ) getPara()->debugLevel = 2 ;
1091  if ( cc == '3' ) getPara()->debugLevel = 3 ;
1092  if ( cc == '4' ) getPara()->debugLevel = 4 ;
1093  if ( cc == '5' ) getPara()->debugLevel = 5 ;
1094  if ( cc == '6' ) getPara()->debugLevel = 6 ;
1095  if ( cc == '7' ) getPara()->debugLevel = 7 ;
1096 
1097  LOG(ERR, "FtfTrack::debugAsk: Debug Level %d\n", getPara()->debugLevel ) ;
1098 
1099 }
1100 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1101 // Debug Delete Candidate
1102 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1103 void FtfTrack::debugDeleteCandidate(void)
1104 {
1105  if ( getPara()->trackDebug == 0 || getPara()->debugLevel < 1 ) return ;
1106 
1107 // for ( startLoop() ; done() ; nextHit() ) {
1108 // currentHit->Show ( getPara()->color_back ) ;
1109 // }
1110  LOG(ERR, "FtfTrack::debugDeleteCandidate: Track %d has %d hits <==\n"
1111  ,id, nHits );
1112  LOG(ERR, "FtfTrack::debugDeleteCandidate: Minimum is %d, delete it \n",
1113  getPara()->minHitsPerTrack );
1114 // print ( 31 ) ;
1115  debugAsk () ;
1116 }
1117 /*****************************************************************************
1118  Fill track information tables
1119 ******************************************************************************/
1120 void FtfTrack::debugFill ( )
1121 {
1122  if ( getPara()->trackDebug && getPara()->debugLevel >= 1 ) {
1123  LOG(ERR, "\n ===> Track %d added <=== ",id+1 );
1124  Print ( 31 ) ;
1125  }
1126 }
1127 /*****************************************************************************
1128  Reconstructs tracks
1129 ******************************************************************************/
1130 void FtfTrack::debugFollowCandidate ( FtfHit* candidateHit )
1131 {
1132  if ( !getPara()->trackDebug || getPara()->debugLevel >= 4 ) return ;
1133 //
1134 // Show the whole track and fit
1135 //
1136 //for ( startLoop() ; done() ; nextHit() ) {
1137 // currentHit->Show ( getPara()->color_track ) ;
1138 //}
1139 // candidateHit->Show ( getPara()->color_candidate );
1140 //
1141 // Print relevant information
1142 //
1143  LOG(ERR, "FtfTrack::debugFollowCandidate ===> Extension in Follow <===\n" ) ;
1144  // print ( 31 ) ;
1145 
1146  LOG(ERR, "FtfTrack::debugFollowCandidate: Try hit %d\n", candidateHit->id ) ;
1147  candidateHit->print ( 11 ) ;
1148 //
1149 // If the hit already used say it and forget about it
1150 //
1151  if ( candidateHit->track != 0 )
1152  {
1153  LOG(ERR, "FtfTrack::debugFollowCandidate: hit %d used in track %d\n",
1154  candidateHit->id, id );
1155  debugAsk () ;
1156 // candidateHit->Show ( getPara()->color_candidate ) ;
1157  candidateHit->print ( 3 ) ;
1158  }
1159 }
1160 /*******************************************************************************
1161  Reconstructs tracks
1162 *********************************************************************************/
1163 void FtfTrack::debugFollowSuccess ( double dxy, double dsz, double lxyChi2,
1164  double lszChi2, double chi2_min,
1165  FtfHit *candidateHit ) {
1166 //
1167 // Check whether track needs to be debugged
1168 //
1169  if ( !getPara()->trackDebug ) return ;
1170  if ( getPara()->debugLevel < 2 ) return ;
1171 //
1172 // Show first level of info
1173 //
1174  double lchi2 = lxyChi2 + lszChi2 ;
1175 
1176  LOG(ERR, " \n ------------------------------------- " ) ;
1177  if ( lchi2 < chi2_min ){
1178  LOG(ERR, "FtfTrack::debugFollowSuccess: %f Best Chi2, keep point !!!\n",
1179  lchi2 );
1180  if ( lchi2 < getPara()->goodHitChi2 ){
1181  LOG(ERR, "This Chi2 is better than the good cut %f\n",
1182  lchi2, getPara()->goodHitChi2 );
1183  LOG(ERR, "Stop search !!! " );
1184  }
1185  }
1186  else{
1187  LOG(ERR, "FtfTrack::debugFollowSuccess: Hit %d worse than previous, forget it !! ",
1188  candidateHit->id );
1189 // candidateHit->Show ( getPara()->color_track ) ;
1190  }
1191 
1192 
1193 
1194 //
1195 // Show second level of info
1196 //
1197  LOG(DBG, "FtfTrack::debugFollowSuccess:\n");
1198  LOG(DBG, "dis_xy dis_sz %7.2e %7.2e\n ", dxy, dsz );
1199  LOG(DBG, "Error xy sz %7.2e %7.2e\n ",
1200  candidateHit->wxy, candidateHit->wz );
1201  LOG(DBG, "xy:a1,a2;sz:a1,a2 %7.2f %7.2f %7.2f %7.2f\n",
1202  a1Xy, a2Xy, a1Sz, a2Sz );
1203  LOG(DBG, "ch2:xy sz tot min %7.2f %7.2f %7.2f %7.2f\n",
1204  lxyChi2,lszChi2, lchi2, chi2_min );
1205  }
1206  debugAsk() ;
1207 // candidateHit->Show ( getPara()->color_transparent ) ;
1208 }
1209 /*********************************************************************************
1210  Routine to look for segments.
1211  Segments are track starting chains
1212 *******************************************************************************/
1213 void FtfTrack::debugInVolume ( FtfHit *baseHit, FtfHit *candidateHit )
1214 {
1215 
1216  if ( getPara()->trackDebug && getPara()->debugLevel >= 2 ) {
1217 /*----------------------------------------------------------------------------
1218  Show the whole segment
1219 ----------------------------------------------------------------------------*/
1220 // for ( startLoop() ; done() ; nextHit() ) {
1221 // currentHit->Show ( getPara()->color_track ) ;
1222 // }
1223 
1224 // candidateHit->Show ( getPara()->color_candidate ) ;
1225 /*----------------------------------------------------------------------------
1226  Print relevant information
1227 ----------------------------------------------------------------------------*/
1228  if ( nHits > getPara()->nHitsForSegment+1 ) Print ( 31 ) ;
1229 
1230  LOG(ERR, "FtfTrack:debugInVolume: Try hit %d\n", candidateHit->id ) ;
1231  candidateHit->print ( 11 ) ;
1232 /*----------------------------------------------------------------------------
1233  If the hit already used say it and forget about it
1234 ----------------------------------------------------------------------------*/
1235  if ( candidateHit->track != 0 ) {
1236  LOG(ERR, "FtfTrack:debugInVolume: hit %d used in track %d\n",
1237  candidateHit->id, id+1 );
1238 // candidateHit->Show ( 0 );
1239  }
1240  else {
1241  double dphi = (double)fabs(baseHit->phi - candidateHit->phi) ;
1242  double deta ;
1243  if ( baseHit->dz < 1000 && candidateHit->dz < 1000 )
1244  deta = (double)fabs(baseHit->eta - candidateHit->eta) ;
1245  else
1246  deta = 0.F ;
1247 
1248  if ( dphi > getPara()->dphi )
1249  LOG(ERR, "FtfTrack:debugInVolume: Hits too far apart in phi: %f \n",
1250  dphi ) ;
1251  if ( deta > getPara()->deta )
1252  LOG(ERR, "FtfTrack:debugInVolume: Hits too far apart in eta: %f \n",
1253  deta ) ;
1254  }
1255  debugAsk () ;
1256  }
1257 }
1258 /*****************************************************************************
1259  Fill track information tables
1260 ******************************************************************************/
1261 void FtfTrack::debugNew ( )
1262 {
1263 
1264  if ( firstHit->id == getPara()->hitDebug ) getPara()->trackDebug = 1 ;
1265  if ( getPara()->trackDebug && getPara()->debugLevel >= 1 )
1266  {
1267  LOG(DBG, "================================================ \n" );
1268  LOG(DBG, "FtfTrack::debugNew:Starting track %d from point %d\n",
1269  id, firstHit->id );
1270  LOG(DBG, "================================================ \n" );
1271 
1272 // firstHit->Show ( getPara()->color_track ) ;
1273  debugAsk () ;
1274  }
1275 }
1276 #endif
Definition: FtfHit.h:16