00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdio.h>
00025 #include <string.h>
00026 #include <math.h>
00027 #include "FtfTrack.h"
00028 #include "FtfHit.h"
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 void FtfTrack::add ( FtfHit *thisHit, int way )
00040 {
00041
00042
00043
00044 nHits++ ;
00045
00046
00047
00048 if ( way < 0 || nHits == 1 ) {
00049 if ( nHits > 1 ) ((FtfBaseHit *)lastHit)->nextTrackHit = thisHit ;
00050 lastHit = thisHit ;
00051 innerMostRow = ((FtfBaseHit *)lastHit)->row ;
00052 xLastHit = ((FtfBaseHit *)lastHit)->x ;
00053 yLastHit = ((FtfBaseHit *)lastHit)->y ;
00054 }
00055 else {
00056 ((FtfBaseHit *)thisHit)->nextTrackHit = firstHit ;
00057 firstHit = thisHit ;
00058 outerMostRow = ((FtfBaseHit *)firstHit)->row ;
00059 }
00060
00061
00062
00063 thisHit->setStatus ( this ) ;
00064
00065
00066
00067 if ( nHits < getPara()->minHitsForFit ) return ;
00068
00069
00070
00071
00072 s11Xy = s11Xy + thisHit->wxy ;
00073 s12Xy = s12Xy + thisHit->wxy * thisHit->xp ;
00074 s22Xy = s22Xy + thisHit->wxy * square(thisHit->xp) ;
00075 g1Xy = g1Xy + thisHit->wxy * thisHit->yp ;
00076 g2Xy = g2Xy + thisHit->wxy * thisHit->xp * thisHit->yp ;
00077
00078
00079 if ( nHits > getPara()->minHitsForFit )
00080 {
00081 ddXy = s11Xy * s22Xy - square ( s12Xy ) ;
00082 if ( ddXy != 0 ) {
00083 a1Xy = ( g1Xy * s22Xy - g2Xy * s12Xy ) / ddXy ;
00084 a2Xy = ( g2Xy * s11Xy - g1Xy * s12Xy ) / ddXy ;
00085 }
00086 else {
00087 if ( getPara()->infoLevel > 0 ) {
00088 LOG(ERR, "FtfTrack:add: ddXy = 0 \n" ) ;
00089 }
00090 }
00091 }
00092
00093
00094
00095 if ( getPara()->szFitFlag ) {
00096 s11Sz = s11Sz + thisHit->wz ;
00097 s12Sz = s12Sz + thisHit->wz * thisHit->s ;
00098 s22Sz = s22Sz + thisHit->wz * thisHit->s * thisHit->s ;
00099 g1Sz = g1Sz + thisHit->wz * thisHit->z ;
00100 g2Sz = g2Sz + thisHit->wz * thisHit->s * thisHit->z ;
00101
00102 if ( nHits > getPara()->minHitsForFit ) {
00103
00104 ddSz = s11Sz * s22Sz - s12Sz * s12Sz ;
00105 if ( ddSz != 0 ) {
00106 a1Sz = ( g1Sz * s22Sz - g2Sz * s12Sz ) / ddSz ;
00107 a2Sz = ( g2Sz * s11Sz - g1Sz * s12Sz ) / ddSz ;
00108 }
00109 else
00110 {
00111 if ( getPara()->infoLevel > 0 ) {
00112 LOG(ERR, "FtfTrack:add: ddSz = 0 \n" ) ;
00113 }
00114 }
00115 }
00116 }
00117 }
00118
00119
00120
00121 void FtfTrack::add ( FtfTrack *piece )
00122 {
00123
00124
00125
00126 s11Xy += piece->s11Xy ;
00127 s12Xy += piece->s12Xy ;
00128 s22Xy += piece->s22Xy ;
00129 g1Xy += piece->g1Xy ;
00130 g2Xy += piece->g2Xy ;
00131
00132 ddXy = s11Xy * s22Xy - square ( s12Xy ) ;
00133 a1Xy = ( g1Xy * s22Xy - g2Xy * s12Xy ) / ddXy ;
00134 a2Xy = ( g2Xy * s11Xy - g1Xy * s12Xy ) / ddXy ;
00135
00136
00137
00138 if ( getPara()->szFitFlag ) {
00139 double det1 = s11Sz * s22Sz - s12Sz * s12Sz ;
00140 dtanl = (double) ( s11Sz / det1 );
00141 dz0 = (double) ( s22Sz / det1 );
00142
00143 double det2 = piece->s11Sz * piece->s22Sz - piece->s12Sz * piece->s12Sz ;
00144 piece->dtanl = (double) ( piece->s11Sz / det2 );
00145 piece->dz0 = (double) ( piece->s22Sz / det2 );
00146
00147 double weight1 = 1./(dtanl*dtanl);
00148 double weight2 = 1./(piece->dtanl*piece->dtanl);
00149 double weight = (weight1+weight2);
00150 tanl = ( weight1 * tanl + weight2 * piece->tanl ) / weight ;
00151
00152 weight1 = 1./(dz0*dz0);
00153 weight2 = 1./(piece->dz0*piece->dz0);
00154 weight = (weight1+weight2);
00155 z0 = ( weight1 * z0 + weight2 * piece->z0 ) / weight ;
00156 }
00157
00158
00159
00160
00161 int counter ;
00162 if ( piece->outerMostRow < outerMostRow ){
00163 if ( lastHit != NULL ) {
00164 counter = 0 ;
00165 for ( currentHit = piece->firstHit ;
00166 currentHit != 0 && counter < piece->nHits ;
00167 currentHit = ((FtfBaseHit *)currentHit)->nextTrackHit ) {
00168 ((FtfBaseHit *)currentHit)->track = this ;
00169 counter++ ;
00170 }
00171 ((FtfBaseHit *)lastHit)->nextTrackHit = piece->firstHit ;
00172 lastHit = piece->lastHit ;
00173 }
00174 piece->firstHit = 0 ;
00175 innerMostRow = piece->innerMostRow ;
00176 xLastHit = piece->xLastHit ;
00177 yLastHit = piece->yLastHit ;
00178 }
00179 else {
00180 if ( piece->lastHit != NULL ) {
00181 counter = 0 ;
00182 for ( currentHit = (FtfHit *)piece->firstHit ;
00183 currentHit != 0 && counter < piece->nHits ;
00184 currentHit = ((FtfBaseHit *)currentHit)->nextTrackHit ) {
00185 ((FtfBaseHit *)currentHit)->track = this ;
00186 counter++;
00187 }
00188 ((FtfBaseHit *)piece->lastHit)->nextTrackHit = firstHit ;
00189 firstHit = piece->firstHit ;
00190 }
00191 outerMostRow = piece->outerMostRow ;
00192 piece->firstHit = 0 ;
00193 }
00194
00195
00196 nHits += piece->nHits ;
00197 chi2[0] += piece->chi2[0] ;
00198 chi2[1] += piece->chi2[1] ;
00199
00200
00201
00202
00203 getPara()->szFitFlag = 0 ;
00204 if ( getPara()->fillTracks ) fill ( ) ;
00205 getPara()->szFitFlag = 1 ;
00206
00207
00208
00209
00210 piece->flag = -1 ;
00211 }
00212
00213
00214
00215
00216 int FtfTrack::buildTrack ( FtfHit *frstHit, FtfContainer *volume ) {
00217
00218
00219
00220 add ( frstHit, GO_DOWN ) ;
00221
00222
00223
00224 if ( !segment ( volume, GO_DOWN ) ) return 0 ;
00225
00226
00227
00228 int rowToStop = getPara()->rowInnerMost ;
00229 if ( !follow ( volume, GO_DOWN, rowToStop ) ) return 0 ;
00230
00231
00232
00233 if ( getPara()->goBackwards ) {
00234 follow ( volume, GO_UP, getPara()->rowOuterMost ) ;
00235 }
00236
00237
00238
00239 if ( getPara()->fillTracks )
00240 fill ( ) ;
00241 #ifdef TRDEBUG
00242 debugFill ( ) ;
00243 #endif
00244
00245 return 1 ;
00246 }
00247
00248
00249
00250 void FtfTrack::dEdx ( ){
00251 int i, j ;
00252 FtfHit *nextHit ;
00253 int nTruncate = max(1,
00254 getPara()->dEdxNTruncate*nHits/100) ;
00255 nTruncate = min(nHits/2,nTruncate) ;
00256
00257
00258
00259 double *de = new double[nTruncate] ;
00260
00261
00262
00263 dedx = 0.F ;
00264 memset ( de, 0, nTruncate*sizeof(double) ) ;
00265
00266
00267
00268 for ( nextHit = (FtfHit *)firstHit ;
00269 nextHit != 0 ;
00270 nextHit = (FtfHit *)nextHit->nextTrackHit) {
00271
00272 dedx += nextHit->q ;
00273
00274 if ( nextHit->q < de[0] ) continue ;
00275
00276 for ( i = nTruncate-1 ; i>=0 ; i-- ){
00277 if ( nextHit->q > de[i] ){
00278 for ( j=0 ; j<i ; j++ ) de[j] = de[j+1] ;
00279 de[i] = nextHit->q ;
00280 break ;
00281 }
00282 }
00283 }
00284
00285
00286
00287 for ( i=0 ; i<nTruncate ; i++ ) dedx -= de[i] ;
00288 dedx = dedx / length ;
00289
00290
00291 }
00292
00293
00294
00295 void FtfTrack::deleteCandidate(void)
00296 {
00297 FtfHit *curentHit = (FtfHit *)firstHit ;
00298 FtfHit *nextHit ;
00299 #ifdef TRDEBUG
00300 debugDeleteCandidate ( ) ;
00301 #endif
00302 while ( curentHit != 0 )
00303 {
00304 nextHit = (FtfHit *)curentHit->nextTrackHit;
00305 curentHit->nextTrackHit = 0 ;
00306 curentHit->xyChi2 =
00307 curentHit->szChi2 =
00308 curentHit->s = 0.F ;
00309
00310 curentHit->setStatus ( 0 ) ;
00311 curentHit = nextHit;
00312 }
00313 }
00314
00315
00316
00317 void FtfTrack::fill ( ) {
00318
00319
00320
00321
00322 double xc, yc ;
00323 double rc = sqrt ( a2Xy * a2Xy + 1 ) / ( 2 * fabs(a1Xy) ) ;
00324 pt = (double)fabs(bFactor * getPara()->bField * rc );
00325 double xParameters = 0.;
00326 double yParameters = 0.;
00327
00328 if ( pt > getPara()->ptMinHelixFit ) {
00329 double combinedChi2 = 0.5*(chi2[0]+chi2[1])/nHits ;
00330 if ( getPara()->primaries && combinedChi2 < getPara()->maxChi2Primary )
00331 getPara()->vertexConstrainedFit = 1 ;
00332 else
00333 getPara()->vertexConstrainedFit = 0 ;
00334
00335 fitHelix ( ) ;
00336
00337
00338 if ( getPara()->vertexConstrainedFit && getPara()->parameterLocation ){
00339 updateToRadius ( sqrt(xLastHit*xLastHit+yLastHit*yLastHit) ) ;
00340 }
00341 else if ( !getPara()->vertexConstrainedFit && !getPara()->parameterLocation ) {
00342 updateToClosestApproach ( getPara()->xVertex, getPara()->yVertex, 2000. ) ;
00343 }
00344
00345
00346 }
00347 else{
00348
00349 if ( getPara()->primaries ){
00350
00351 fillPrimary ( xc, yc, rc, getPara()->xVertex, getPara()->yVertex ) ;
00352 if ( getPara()->parameterLocation ) {
00353 updateToRadius ( sqrt(xLastHit*xLastHit+yLastHit*yLastHit) ) ;
00354 }
00355 }
00356 else {
00357 xc = - a2Xy / ( 2. * a1Xy ) + xRefHit ;
00358 yc = - 1. / ( 2. * a1Xy ) + yRefHit ;
00359 if ( getPara()->parameterLocation ) {
00360 xParameters = xLastHit ;
00361 yParameters = yLastHit ;
00362 }
00363 else {
00364 getClosest ( getPara()->xVertex, getPara()->yVertex,
00365 rc, xc, yc, xParameters, yParameters ) ;
00366 }
00367 fillSecondary ( xc, yc, xParameters, yParameters ) ;
00368 }
00369
00370
00371
00372 if ( getPara()->getErrors ) {
00373 getErrorsCircleFit ( (double)xc, (double)yc, (double)rc ) ;
00374 double det = s11Sz * s22Sz - s12Sz * s12Sz ;
00375 dtanl = (double) ( s11Sz / det );
00376 dz0 = (double) ( s22Sz / det );
00377 }
00378 }
00379 }
00380
00381
00382
00383 void FtfTrack::fillPrimary ( double &xc, double &yc, double &rc,
00384 double xPar, double yPar ) {
00385
00386
00387
00388 xc = getPara()->xVertex - a2Xy / ( 2. * a1Xy ) ;
00389 yc = getPara()->yVertex - 1. / ( 2. * a1Xy ) ;
00390
00391
00392
00393 double angle_vertex = atan2 ( yPar-yc, xPar-xc ) ;
00394 if ( angle_vertex < 0. ) angle_vertex = angle_vertex + twoPi ;
00395
00396 double dx_last = xLastHit - xc ;
00397 double dy_last = yLastHit - yc ;
00398 double angle_last = atan2 ( dy_last, dx_last ) ;
00399 if ( angle_last < 0. ) angle_last = angle_last + twoPi ;
00400
00401
00402
00403 double d_angle = angle_last - angle_vertex ;
00404
00405
00406 if ( d_angle < -pi ) d_angle += twoPi ;
00407
00408 q = getPara()->bFieldPolarity * ( ( d_angle < 0 ) ? 1 : -1 ) ;
00409 r0 = sqrt(xPar*xPar+yPar*yPar) ;
00410 phi0 = atan2(yPar,xPar) ;
00411 if ( phi0 < 0 ) phi0 += 2. * M_PI ;
00412 psi = (double)(angle_vertex - getPara()->bFieldPolarity*q * 0.5F * pi) ;
00413 if ( psi < 0 ) psi = (double)(psi + twoPi );
00414 if ( psi > twoPi ) psi = (double)(psi - twoPi );
00415
00416
00417
00418 if ( getPara()->szFitFlag == 1 ){
00419 tanl = -(double)a2Sz ;
00420 z0 = (double)(a1Sz + a2Sz * ( length - rc * d_angle * getPara()->bFieldPolarity*q ) );
00421 }
00422 else if ( getPara()->szFitFlag == 2 ) {
00423 tanl = ((FtfBaseHit *)firstHit)->z /
00424 (double)sqrt ( ((FtfBaseHit *)firstHit)->x*((FtfBaseHit *)firstHit)->x +
00425 ((FtfBaseHit *)firstHit)->y*((FtfBaseHit *)firstHit)->y ) ;
00426 z0 = 0.F ;
00427 }
00428
00429
00430
00431 eta = seta(1.,tanl ) ;
00432
00433
00434
00435 flag = 1 ;
00436
00437 }
00438
00439
00440
00441
00442
00443 void FtfTrack::fillSecondary ( double &xc, double &yc,
00444 double xPar, double yPar )
00445 {
00446
00447
00448
00449 double dx1 = ((FtfBaseHit *)firstHit)->x - xc ;
00450 double dy1 = ((FtfBaseHit *)firstHit)->y - yc ;
00451 double angle1 = atan2 ( dy1, dx1 ) ;
00452 if ( angle1 < 0. ) angle1 = angle1 + twoPi ;
00453
00454 double dx2 = xLastHit - xc ;
00455 double dy2 = yLastHit - yc ;
00456 double angle2 = atan2 ( dy2, dx2 ) ;
00457 if ( angle2 < 0. ) angle2 = angle2 + twoPi ;
00458
00459
00460
00461 double dangle = angle2 - angle1 ;
00462
00463 if ( dangle < -pi ) dangle = dangle + twoPi ;
00464
00465 q = getPara()->bFieldPolarity * ( ( dangle > 0 ) ? 1 : -1 ) ;
00466 r0 = ((FtfHit *)lastHit)->r ;
00467 phi0 = ((FtfHit *)lastHit)->phi ;
00468 psi = (double)(angle2 - getPara()->bFieldPolarity * q * piHalf );
00469 if ( psi < 0 ) psi = (double)(psi + twoPi );
00470
00471
00472
00473 if ( getPara()->szFitFlag ){
00474 tanl = -(double)a2Sz ;
00475 z0 = (double)(a1Sz + a2Sz * length );
00476 }
00477 else{
00478 tanl = ((FtfBaseHit *)firstHit)->z /
00479 (double)sqrt ( ((FtfBaseHit *)firstHit)->x*((FtfBaseHit *)firstHit)->x +
00480 ((FtfBaseHit *)firstHit)->y*((FtfBaseHit *)firstHit)->y ) ;
00481 z0 = 0.F ;
00482 }
00483
00484
00485
00486 eta = seta(1., tanl ) ;
00487
00488
00489
00490 flag = 0 ;
00491 }
00492
00493
00494
00495
00496
00497
00498
00499 int FtfTrack::follow ( FtfContainer *volume, int way, int ir_stop ) {
00500
00501 FtfHit *nextHit ;
00502
00503 if ( way < 0 )
00504 nextHit = (FtfHit *)lastHit ;
00505 else
00506 nextHit = (FtfHit *)firstHit ;
00507 #ifdef TRDEBUG
00508 if ( getPara()->trackDebug && getPara()->debugLevel >= 2 )
00509 LOG(ERR, "FtfTrack::follow: ===> Going into Track extension <===\n" );
00510 #endif
00511
00512
00513
00514 double xyChi2 = chi2[0] ;
00515 double szChi2 = chi2[1] ;
00516
00517
00518
00519
00520
00521 while ( way * nextHit->row < way * ir_stop ) {
00522
00523
00524
00525 chi2[0] = getPara()->hitChi2Cut ;
00526
00527 nextHit = seekNextHit ( volume, nextHit, way*getPara()->trackRowSearchRange, USE_FOLLOW ) ;
00528
00529 #ifdef TRDEBUG
00530 if ( getPara()->trackDebug && getPara()->debugLevel >= 1 ){
00531 if ( nextHit != 0 ){
00532 LOG(ERR, "FtfTrack::follow: Search succesful, hit selected %d\n",
00533 nextHit->id );
00534
00535 }
00536 else{
00537 LOG(ERR, "FtfTrack::follow: Search unsuccesful\n" );
00538 if ( chi2[0]+chi2[1] > getPara()->hitChi2Cut )
00539 LOG(ERR, " hit chi2 %f larger than cut %f ", chi2[0]+chi2[1],
00540 getPara()->hitChi2Cut ) ;
00541 }
00542 debugAsk () ;
00543 }
00544 #endif
00545
00546
00547
00548 if ( nextHit == 0 ) break ;
00549
00550
00551
00552 double lxyChi2 = chi2[0]-chi2[1] ;
00553 xyChi2 += lxyChi2 ;
00554 nextHit->xyChi2 = lxyChi2 ;
00555
00556
00557
00558 if ( getPara()->szFitFlag ) {
00559 length = nextHit->s ;
00560 szChi2 += chi2[1] ;
00561 nextHit->szChi2 = chi2[1] ;
00562
00563 }
00564
00565
00566
00567 add ( nextHit, way ) ;
00568
00569 }
00570
00571
00572
00573 if ( nHits < getPara()->minHitsPerTrack ) return 0 ;
00574
00575
00576
00577 chi2[0] = xyChi2 ;
00578 chi2[1] = szChi2 ;
00579
00580
00581
00582 double normalized_chi2 = (chi2[0]+chi2[1])/nHits ;
00583 if ( normalized_chi2 > getPara()->trackChi2Cut ) return 0 ;
00584
00585 return 1 ;
00586 }
00587
00588
00589
00590 int FtfTrack::followHitSelection ( FtfHit *baseHit, FtfHit *candidateHit, int way ){
00591
00592 double lszChi2 = 0 ;
00593 double lchi2 ;
00594 double slocal=0, deta, dphi ;
00595 double dx, dy, dxy, dsz, temp ;
00596
00597
00598
00599
00600 deta = fabs((baseHit->eta)-(candidateHit->eta)) ;
00601 if ( deta > getPara()->deta ) return 0 ;
00602
00603
00604
00605
00606
00607 dphi = fabs((baseHit->phi)-(candidateHit->phi)) ;
00608 if ( dphi > getPara()->dphi && dphi < twoPi-getPara()->dphi ) return 0 ;
00609
00610
00611
00612 if ( getPara()->primaries == 0 ){
00613 double xx = candidateHit->x - xRefHit ;
00614 double yy = candidateHit->y - yRefHit ;
00615 double rr = xx * xx + yy * yy ;
00616 candidateHit->xp = xx / rr ;
00617 candidateHit->yp = - yy / rr ;
00618
00619 candidateHit->wxy = rr * rr /
00620 ( square(getPara()->xyErrorScale) *
00621 ( square(candidateHit->dx) + square(candidateHit->dy) ) ) ;
00622 }
00623
00624
00625
00626 temp = (a2Xy * candidateHit->xp - candidateHit->yp + a1Xy) ;
00627 dxy = temp * temp / ( a2Xy * a2Xy + 1.F ) ;
00628
00629
00630
00631 lchi2 = (dxy * candidateHit->wxy) ;
00632
00633 if ( lchi2 > chi2[0] ) return 0 ;
00634
00635
00636
00637 if ( getPara()->szFitFlag ){
00638
00639
00640
00641 dx = baseHit->x - candidateHit->x ;
00642 dy = baseHit->y - candidateHit->y ;
00643 slocal = baseHit->s - way * sqrt ( dx * dx + dy * dy ) ;
00644
00645 temp = (a2Sz * slocal - candidateHit->z + a1Sz) ;
00646 dsz = temp * temp / ( a2Sz * a2Sz + 1 ) ;
00647
00648
00649
00650 lszChi2 = dsz * candidateHit->wz ;
00651 lchi2 += lszChi2 ;
00652 }
00653 else {
00654 lszChi2 = 0.F ;
00655
00656 }
00657
00658
00659
00660 if ( lchi2 < chi2[0] ) {
00661 chi2[0] = (double)lchi2 ;
00662 chi2[1] = (double)lszChi2 ;
00663
00664 if ( getPara()->szFitFlag ) candidateHit->s = (double)slocal ;
00665
00666
00667
00668 if ( lchi2 < getPara()->goodHitChi2 ) return 2 ;
00669
00670 return 1 ;
00671 }
00672
00673
00674
00675 return 0 ;
00676 }
00677
00678
00679
00680 int FtfTrack::mergePrimary ( FtfContainer *trackArea ){
00681 short track_merged ;
00682 register int areaIndex ;
00683 int i_phi, i_eta ;
00684 FtfTrack *i_track = 0 ;
00685 int ip, ie ;
00686 double delta_psi ;
00687
00688
00689
00690 if ( flag != 1 ) return 0 ;
00691
00692
00693
00694 i_phi = (int)(( psi - getPara()->phiMinTrack ) / getPara()->phiSliceTrack + 1 );
00695 if ( i_phi < 0 ) {
00696 LOG(ERR, " Track phi index too low %d \n", i_phi ) ;
00697 i_phi = 1 ;
00698 }
00699 if ( i_phi >= getPara()->nPhiTrackPlusOne ) {
00700 LOG(ERR, " Track phi index too high %d \n", i_phi ) ;
00701 i_phi = getPara()->nPhiTrack ;
00702 }
00703
00704
00705
00706 i_eta = (int)(( eta - getPara()->etaMinTrack ) / getPara()->etaSliceTrack + 1 );
00707 if ( i_eta <= 0 ) {
00708 LOG(ERR, " Track eta index too low %d \n", i_eta ) ;
00709 i_eta = 1 ;
00710 }
00711 if ( i_eta >= getPara()->nEtaTrackPlusOne ) {
00712 LOG(ERR, " Track eta index too high %d \n", i_eta ) ;
00713 i_eta = getPara()->nEtaTrack ;
00714 }
00715
00716
00717
00718 track_merged = 0 ;
00719 for ( ip = max(i_phi-1,1) ; ip < min(i_phi+2,getPara()->nPhiTrackPlusOne) ; ip++ ) {
00720 for ( ie = max(i_eta-1,1) ; ie < min(i_eta+2,getPara()->nEtaTrackPlusOne) ; ie++ ) {
00721 areaIndex = ip * getPara()->nEtaTrackPlusOne + ie ;
00722
00723
00724
00725 for ( i_track = (FtfTrack *)trackArea[areaIndex].first ;
00726 i_track != 0 ;
00727 i_track = i_track->getNextTrack() ) {
00728
00729
00730
00731 if ( i_track->flag < 0 ) continue ;
00732
00733
00734
00735
00736 short delta1 = i_track->outerMostRow - outerMostRow ;
00737 short delta2 = i_track->innerMostRow - innerMostRow ;
00738 if ( delta1 * delta2 <= 0 ) continue ;
00739
00740
00741
00742 if ( fabs(eta-i_track->eta) > getPara()->detaMerge ) continue ;
00743 delta_psi = (double)fabs(psi - i_track->psi) ;
00744 if ( delta_psi > getPara()->dphiMerge && delta_psi < twoPi - getPara()->dphiMerge ) continue ;
00745
00746 i_track->add ( this ) ;
00747 #ifdef TRDEBUG
00748 if ( getPara()->debugLevel > 1 )
00749 LOG(ERR, " \n Track %d merge into %d ", this->id, i_track->id ) ;
00750 #endif
00751 track_merged = 1 ;
00752 break ;
00753 }
00754 }
00755 }
00756
00757
00758
00759 if ( track_merged == 0 ) {
00760 areaIndex = i_phi * getPara()->nEtaTrackPlusOne + i_eta ;
00761 if ( trackArea[areaIndex].first == 0 )
00762 trackArea[areaIndex].first =
00763 trackArea[areaIndex].last = (void *)this ;
00764 else {
00765 ((FtfTrack *)trackArea[areaIndex].last)->nxatrk = this ;
00766 trackArea[areaIndex].last = (void *)this ;
00767 }
00768 }
00769 return track_merged ;
00770 }
00771
00772
00773
00774 void FtfTrack::reset (void)
00775 {
00776
00777
00778
00779
00780 flag = getPara()->primaries ;
00781 nHits = 0 ;
00782 s11Xy =
00783 s12Xy =
00784 s22Xy =
00785 g1Xy =
00786 g2Xy =
00787 chi2[0] = 0.F ;
00788 nxatrk = 0 ;
00789 if ( getPara()->szFitFlag )
00790 {
00791 s11Sz =
00792 s12Sz =
00793 s22Sz =
00794 g1Sz =
00795 g2Sz =
00796 chi2[1] =
00797 length = 0.F ;
00798 }
00799 }
00800
00801
00802
00803
00804
00805
00806
00807
00808 FtfHit *FtfTrack::seekNextHit ( FtfContainer *volume,
00809 FtfHit *baseHit,
00810 int n_r_steps,
00811 int which_function ) {
00812 #define N_LOOP 9
00813 int loop_eta[N_LOOP] = { 0, 0, 0,-1,-1,-1, 1, 1, 1 } ;
00814 int loop_phi[N_LOOP] = { 0,-1, 1, 0,-1, 1, 0,-1, 1 };
00815
00816
00817 int ir, irp, ipp, itp, k;
00818 register int areaIndex ;
00819 int result ;
00820
00821
00822
00823
00824 int initialRow, way ;
00825 if ( n_r_steps < 0 ) {
00826 initialRow = max(1, (baseHit->row - getPara()->rowInnerMost)/getPara()->modRow);
00827 n_r_steps = min(initialRow,-n_r_steps ) ;
00828 way = -1 ;
00829 }
00830 else {
00831 initialRow = max(1, (baseHit->row - getPara()->rowInnerMost + 2)/getPara()->modRow);
00832 n_r_steps = min((getPara()->rowOuterMost-initialRow+1),n_r_steps) ;
00833 way = 1 ;
00834 }
00835
00836 FtfHit *selected_hit = 0 ;
00837
00838
00839
00840 for ( ir = 0 ; ir < n_r_steps ; ir++ ){
00841 irp = initialRow + way * ir ;
00842 for ( k=0; k< N_LOOP; k++){
00843 ipp = baseHit->phiIndex + loop_phi[k];
00844
00845
00846
00847 if ( ipp < 1 ) {
00848 if ( getPara()->phiClosed )
00849 ipp = getPara()->nPhi + ipp ;
00850 else
00851 continue ;
00852 }
00853 else if ( ipp > getPara()->nPhi ) {
00854 if ( getPara()->phiClosed )
00855 ipp = ipp - getPara()->nPhi ;
00856 else
00857 continue ;
00858 }
00859
00860
00861
00862 itp = baseHit->etaIndex + loop_eta[k];
00863 if ( itp < 1 ) continue ;
00864 if ( itp > getPara()->nEta ) continue ;
00865
00866 #ifdef TRDEBUG
00867 if ( getPara()->trackDebug && getPara()->debugLevel >= 4 )
00868 LOG(ERR, "FtfTrack::seekNextHit: search in row %d \n",irp ) ;
00869 #endif
00870
00871
00872
00873 areaIndex = irp * getPara()->nPhiEtaPlusOne + ipp * getPara()->nEtaPlusOne + itp ;
00874 for ( FtfHit *candidateHit = (FtfHit *)volume[areaIndex].first ;
00875 candidateHit != 0 ;
00876 candidateHit = (FtfHit *)candidateHit->nextVolumeHit ){
00877 #ifdef TRDEBUG
00878 debugInVolume ( baseHit, candidateHit ) ;
00879 #endif
00880
00881
00882
00883 if ( candidateHit->track != 0 ) continue ;
00884
00885
00886
00887 if ( which_function == USE_SEGMENT )
00888 result = segmentHitSelection ( baseHit, candidateHit ) ;
00889 else
00890 result = followHitSelection ( baseHit, candidateHit, way ) ;
00891
00892
00893
00894 if ( result > 0 ) {
00895 selected_hit = candidateHit ;
00896 if ( result ==2 ) goto found ;
00897 }
00898
00899
00900
00901 }
00902
00903
00904
00905 }
00906
00907
00908
00909 }
00910 found: ;
00911
00912 return selected_hit ;
00913 }
00914
00915
00916
00917
00918
00919
00920
00921 int FtfTrack::segment( FtfContainer *volume, int way ){
00922
00923
00924
00925 double dx, dy, rr ;
00926 FtfHit* nextHit ;
00927
00928
00929
00930 if ( way < 0 )
00931 nextHit = (FtfHit *)lastHit ;
00932 else
00933 nextHit = (FtfHit *)firstHit ;
00934 #ifdef TRDEBUG
00935 if ( getPara()->trackDebug && getPara()->debugLevel >= 4 )
00936 LOG(ERR, "FtfTrack:segment: **** Trying to form segment ****\n" );
00937 #endif
00938
00939
00940
00941
00942 while ( nextHit != 0 && nHits < getPara()->nHitsForSegment ) {
00943 chi2[0] = getPara()->maxDistanceSegment ; ;
00944 nextHit = seekNextHit ( volume, nextHit, way*getPara()->segmentRowSearchRange,
00945 USE_SEGMENT ) ;
00946 #ifdef TRDEBUG
00947 if ( getPara()->trackDebug && getPara()->debugLevel > 0 ) {
00948 if ( nextHit != 0 ) {
00949 LOG(ERR, "FtfTrack::segment: Search succesful, hit %d selected\n",
00950 nextHit->id );
00951
00952 }
00953 else
00954 LOG(ERR, "FtfTrack::segment: Search unsuccesful\n" );
00955 debugAsk () ;
00956 }
00957 #endif
00958
00959
00960
00961 if ( nextHit != 0 ){
00962
00963
00964
00965 if ( getPara()->szFitFlag ){
00966 dx = ((FtfBaseHit *)nextHit)->x - ((FtfBaseHit *)lastHit)->x ;
00967 dy = ((FtfBaseHit *)nextHit)->y - ((FtfBaseHit *)lastHit)->y ;
00968 length += (double)sqrt ( dx * dx + dy * dy ) ;
00969 nextHit->s = length ;
00970 }
00971
00972
00973
00974 if ( getPara()->primaries == 0 ){
00975 rr = square ( xRefHit - nextHit->x ) +
00976 square ( yRefHit - nextHit->y ) ;
00977
00978
00979 nextHit->xp = ( nextHit->x - xRefHit ) / rr ;
00980 nextHit->yp = - ( nextHit->y - yRefHit ) / rr ;
00981 nextHit->wxy = rr * rr / ( square(getPara()->xyErrorScale) *
00982 square(nextHit->dx) + square(nextHit->dy) ) ;
00983 }
00984
00985
00986
00987 add ( nextHit, way ) ;
00988 }
00989 }
00990
00991
00992
00993 if ( nHits == getPara()->nHitsForSegment )
00994 return 1 ;
00995 else
00996 return 0 ;
00997 }
00998
00999
01000
01001
01002
01003
01004 int FtfTrack::segmentHitSelection ( FtfHit *baseHit, FtfHit *candidateHit ){
01005
01006 double dx, dy, dr, d3, dangle ;
01007 double dphi, deta ;
01008 double angle ;
01009
01010
01011
01012
01013 dphi = (double)fabs((baseHit->phi) - (candidateHit->phi)) ;
01014 if ( dphi > pi ) dphi = (double)fabs( twoPi - dphi ) ;
01015 if ( dphi > getPara()->dphi && dphi < twoPi -getPara()->dphi ) return 0 ;
01016
01017
01018
01019 if ( baseHit->dz < 1000. && candidateHit->dz < 1000. ){
01020 deta = (double)fabs((baseHit->eta) - (candidateHit->eta)) ;
01021 if ( deta > getPara()->deta ) return 0 ;
01022 }
01023 else deta = 0.F ;
01024
01025 dr = (double)fabs((double)(baseHit->row - candidateHit->row));
01026 d3 = (double)(toDeg * dr * ( dphi + deta ) ) ;
01027
01028
01029
01030
01031 if ( getPara()->nHitsForSegment > 2 && nHits-1 < getPara()->nHitsForSegment ) {
01032 dx = candidateHit->x - baseHit->x ;
01033 dy = candidateHit->y - baseHit->y ;
01034 angle = (double)atan2 ( dy, dx ) ;
01035 if ( angle < 0 ) angle = angle + twoPi ;
01036 lastXyAngle = angle ;
01037 }
01038 #ifdef TRDEBUG
01039 if ( getPara()->trackDebug && getPara()->debugLevel >= 3 ) {
01040 LOG(ERR, "FtfTrack::segmentHitSelection:\n");
01041 LOG(ERR, "dr,dphi,deta,distance, Min distance %7.2f %7.2f %7.2f %7.2f %7.2f\n",
01042 dr,dphi,deta,d3,chi2[0] ) ;
01043 if ( d3 < chi2[0] )
01044 LOG(ERR, "Best point, keep it !!!\n" );
01045 else{
01046 LOG(ERR, "Worse than previous, reject !!\n" );
01047
01048 }
01049 debugAsk() ;
01050 }
01051 #endif
01052 if ( d3 < chi2[0] ) {
01053
01054
01055
01056
01057 if ( nHits > 1 ) {
01058 dx = candidateHit->x - baseHit->x ;
01059 dy = candidateHit->y - baseHit->y ;
01060 angle = (double)atan2 ( dy, dx ) ;
01061 if ( angle < 0 ) angle = angle + twoPi ;
01062 dangle = (double)fabs ( lastXyAngle - angle );
01063 lastXyAngle = angle ;
01064 if ( dangle > getPara()->segmentMaxAngle ) return 0 ;
01065 }
01066
01067
01068
01069 chi2[0] = d3 ;
01070 if ( d3 < getPara()->goodDistance ) return 2 ;
01071 return 1 ;
01072 }
01073
01074
01075
01076 return 0 ;
01077 }
01078 #ifdef TRDEBUG
01079
01080
01081
01082 void FtfTrack::debugAsk (void)
01083 {
01084 char cc;
01085
01086 LOG(ERR, "stop(s), continue (any other key)\n" );
01087 cc = getchar();
01088 if ( cc == 's' ) getPara()->trackDebug = 0 ;
01089 if ( cc == '1' ) getPara()->debugLevel = 1 ;
01090 if ( cc == '2' ) getPara()->debugLevel = 2 ;
01091 if ( cc == '3' ) getPara()->debugLevel = 3 ;
01092 if ( cc == '4' ) getPara()->debugLevel = 4 ;
01093 if ( cc == '5' ) getPara()->debugLevel = 5 ;
01094 if ( cc == '6' ) getPara()->debugLevel = 6 ;
01095 if ( cc == '7' ) getPara()->debugLevel = 7 ;
01096
01097 LOG(ERR, "FtfTrack::debugAsk: Debug Level %d\n", getPara()->debugLevel ) ;
01098
01099 }
01100
01101
01102
01103 void FtfTrack::debugDeleteCandidate(void)
01104 {
01105 if ( getPara()->trackDebug == 0 || getPara()->debugLevel < 1 ) return ;
01106
01107
01108
01109
01110 LOG(ERR, "FtfTrack::debugDeleteCandidate: Track %d has %d hits <==\n"
01111 ,id, nHits );
01112 LOG(ERR, "FtfTrack::debugDeleteCandidate: Minimum is %d, delete it \n",
01113 getPara()->minHitsPerTrack );
01114
01115 debugAsk () ;
01116 }
01117
01118
01119
01120 void FtfTrack::debugFill ( )
01121 {
01122 if ( getPara()->trackDebug && getPara()->debugLevel >= 1 ) {
01123 LOG(ERR, "\n ===> Track %d added <=== ",id+1 );
01124 Print ( 31 ) ;
01125 }
01126 }
01127
01128
01129
01130 void FtfTrack::debugFollowCandidate ( FtfHit* candidateHit )
01131 {
01132 if ( !getPara()->trackDebug || getPara()->debugLevel >= 4 ) return ;
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143 LOG(ERR, "FtfTrack::debugFollowCandidate ===> Extension in Follow <===\n" ) ;
01144
01145
01146 LOG(ERR, "FtfTrack::debugFollowCandidate: Try hit %d\n", candidateHit->id ) ;
01147 candidateHit->print ( 11 ) ;
01148
01149
01150
01151 if ( candidateHit->track != 0 )
01152 {
01153 LOG(ERR, "FtfTrack::debugFollowCandidate: hit %d used in track %d\n",
01154 candidateHit->id, id );
01155 debugAsk () ;
01156
01157 candidateHit->print ( 3 ) ;
01158 }
01159 }
01160
01161
01162
01163 void FtfTrack::debugFollowSuccess ( double dxy, double dsz, double lxyChi2,
01164 double lszChi2, double chi2_min,
01165 FtfHit *candidateHit ) {
01166
01167
01168
01169 if ( !getPara()->trackDebug ) return ;
01170 if ( getPara()->debugLevel < 2 ) return ;
01171
01172
01173
01174 double lchi2 = lxyChi2 + lszChi2 ;
01175
01176 LOG(ERR, " \n ------------------------------------- " ) ;
01177 if ( lchi2 < chi2_min ){
01178 LOG(ERR, "FtfTrack::debugFollowSuccess: %f Best Chi2, keep point !!!\n",
01179 lchi2 );
01180 if ( lchi2 < getPara()->goodHitChi2 ){
01181 LOG(ERR, "This Chi2 is better than the good cut %f\n",
01182 lchi2, getPara()->goodHitChi2 );
01183 LOG(ERR, "Stop search !!! " );
01184 }
01185 }
01186 else{
01187 LOG(ERR, "FtfTrack::debugFollowSuccess: Hit %d worse than previous, forget it !! ",
01188 candidateHit->id );
01189
01190 }
01191
01192
01193
01194
01195
01196
01197 LOG(DBG, "FtfTrack::debugFollowSuccess:\n");
01198 LOG(DBG, "dis_xy dis_sz %7.2e %7.2e\n ", dxy, dsz );
01199 LOG(DBG, "Error xy sz %7.2e %7.2e\n ",
01200 candidateHit->wxy, candidateHit->wz );
01201 LOG(DBG, "xy:a1,a2;sz:a1,a2 %7.2f %7.2f %7.2f %7.2f\n",
01202 a1Xy, a2Xy, a1Sz, a2Sz );
01203 LOG(DBG, "ch2:xy sz tot min %7.2f %7.2f %7.2f %7.2f\n",
01204 lxyChi2,lszChi2, lchi2, chi2_min );
01205 }
01206 debugAsk() ;
01207
01208 }
01209
01210
01211
01212
01213 void FtfTrack::debugInVolume ( FtfHit *baseHit, FtfHit *candidateHit )
01214 {
01215
01216 if ( getPara()->trackDebug && getPara()->debugLevel >= 2 ) {
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228 if ( nHits > getPara()->nHitsForSegment+1 ) Print ( 31 ) ;
01229
01230 LOG(ERR, "FtfTrack:debugInVolume: Try hit %d\n", candidateHit->id ) ;
01231 candidateHit->print ( 11 ) ;
01232
01233
01234
01235 if ( candidateHit->track != 0 ) {
01236 LOG(ERR, "FtfTrack:debugInVolume: hit %d used in track %d\n",
01237 candidateHit->id, id+1 );
01238
01239 }
01240 else {
01241 double dphi = (double)fabs(baseHit->phi - candidateHit->phi) ;
01242 double deta ;
01243 if ( baseHit->dz < 1000 && candidateHit->dz < 1000 )
01244 deta = (double)fabs(baseHit->eta - candidateHit->eta) ;
01245 else
01246 deta = 0.F ;
01247
01248 if ( dphi > getPara()->dphi )
01249 LOG(ERR, "FtfTrack:debugInVolume: Hits too far apart in phi: %f \n",
01250 dphi ) ;
01251 if ( deta > getPara()->deta )
01252 LOG(ERR, "FtfTrack:debugInVolume: Hits too far apart in eta: %f \n",
01253 deta ) ;
01254 }
01255 debugAsk () ;
01256 }
01257 }
01258
01259
01260
01261 void FtfTrack::debugNew ( )
01262 {
01263
01264 if ( firstHit->id == getPara()->hitDebug ) getPara()->trackDebug = 1 ;
01265 if ( getPara()->trackDebug && getPara()->debugLevel >= 1 )
01266 {
01267 LOG(DBG, "================================================ \n" );
01268 LOG(DBG, "FtfTrack::debugNew:Starting track %d from point %d\n",
01269 id, firstHit->id );
01270 LOG(DBG, "================================================ \n" );
01271
01272
01273 debugAsk () ;
01274 }
01275 }
01276 #endif