00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <math.h>
00023 #include <cstring>
00024 #include "Stl3Util/ftf/FtfTrack.h"
00025 #include "Stl3Util/ftf/FtfHit.h"
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 void FtfTrack::add ( FtfHit *thisHit, int way )
00037 {
00038
00039
00040
00041 nHits++ ;
00042
00043
00044
00045 if ( way < 0 || nHits == 1 ) {
00046 if ( nHits > 1 ) ((FtfBaseHit *)lastHit)->nextTrackHit = thisHit ;
00047 lastHit = thisHit ;
00048 innerMostRow = ((FtfBaseHit *)lastHit)->row ;
00049 xLastHit = ((FtfBaseHit *)lastHit)->x ;
00050 yLastHit = ((FtfBaseHit *)lastHit)->y ;
00051 }
00052 else {
00053 ((FtfBaseHit *)thisHit)->nextTrackHit = firstHit ;
00054 firstHit = thisHit ;
00055 outerMostRow = ((FtfBaseHit *)firstHit)->row ;
00056 }
00057
00058
00059
00060 thisHit->setStatus ( this ) ;
00061
00062
00063
00064 if ( nHits < getPara()->minHitsForFit ) return ;
00065
00066
00067
00068
00069 s11Xy = s11Xy + thisHit->wxy ;
00070 s12Xy = s12Xy + thisHit->wxy * thisHit->xp ;
00071 s22Xy = s22Xy + thisHit->wxy * square(thisHit->xp) ;
00072 g1Xy = g1Xy + thisHit->wxy * thisHit->yp ;
00073 g2Xy = g2Xy + thisHit->wxy * thisHit->xp * thisHit->yp ;
00074
00075
00076 if ( nHits > getPara()->minHitsForFit )
00077 {
00078 ddXy = s11Xy * s22Xy - square ( s12Xy ) ;
00079 if ( ddXy != 0 ) {
00080 a1Xy = ( g1Xy * s22Xy - g2Xy * s12Xy ) / ddXy ;
00081 a2Xy = ( g2Xy * s11Xy - g1Xy * s12Xy ) / ddXy ;
00082 }
00083 else {
00084 if ( getPara()->infoLevel > 0 ) {
00085 ftfLog ( "FtfTrack:add: ddXy = 0 \n" ) ;
00086 }
00087 }
00088 }
00089
00090
00091
00092 if ( getPara()->szFitFlag ) {
00093 s11Sz = s11Sz + thisHit->wz ;
00094 s12Sz = s12Sz + thisHit->wz * thisHit->s ;
00095 s22Sz = s22Sz + thisHit->wz * thisHit->s * thisHit->s ;
00096 g1Sz = g1Sz + thisHit->wz * thisHit->z ;
00097 g2Sz = g2Sz + thisHit->wz * thisHit->s * thisHit->z ;
00098
00099 if ( nHits > getPara()->minHitsForFit ) {
00100
00101 ddSz = s11Sz * s22Sz - s12Sz * s12Sz ;
00102 if ( ddSz != 0 ) {
00103 a1Sz = ( g1Sz * s22Sz - g2Sz * s12Sz ) / ddSz ;
00104 a2Sz = ( g2Sz * s11Sz - g1Sz * s12Sz ) / ddSz ;
00105 }
00106 else
00107 {
00108 if ( getPara()->infoLevel > 0 ) {
00109 ftfLog ( "FtfTrack:add: ddSz = 0 \n" ) ;
00110 }
00111 }
00112 }
00113 }
00114 }
00115
00116
00117
00118 void FtfTrack::add ( FtfTrack *piece )
00119 {
00120
00121
00122
00123 s11Xy += piece->s11Xy ;
00124 s12Xy += piece->s12Xy ;
00125 s22Xy += piece->s22Xy ;
00126 g1Xy += piece->g1Xy ;
00127 g2Xy += piece->g2Xy ;
00128
00129 ddXy = s11Xy * s22Xy - square ( s12Xy ) ;
00130 a1Xy = ( g1Xy * s22Xy - g2Xy * s12Xy ) / ddXy ;
00131 a2Xy = ( g2Xy * s11Xy - g1Xy * s12Xy ) / ddXy ;
00132
00133
00134
00135 if ( getPara()->szFitFlag ) {
00136 double det1 = s11Sz * s22Sz - s12Sz * s12Sz ;
00137 dtanl = (double) ( s11Sz / det1 );
00138 dz0 = (double) ( s22Sz / det1 );
00139
00140 double det2 = piece->s11Sz * piece->s22Sz - piece->s12Sz * piece->s12Sz ;
00141 piece->dtanl = (double) ( piece->s11Sz / det2 );
00142 piece->dz0 = (double) ( piece->s22Sz / det2 );
00143
00144 double weight1 = 1./(dtanl*dtanl);
00145 double weight2 = 1./(piece->dtanl*piece->dtanl);
00146 double weight = (weight1+weight2);
00147 tanl = ( weight1 * tanl + weight2 * piece->tanl ) / weight ;
00148
00149 weight1 = 1./(dz0*dz0);
00150 weight2 = 1./(piece->dz0*piece->dz0);
00151 weight = (weight1+weight2);
00152 z0 = ( weight1 * z0 + weight2 * piece->z0 ) / weight ;
00153 }
00154
00155
00156
00157
00158 int counter ;
00159 if ( piece->outerMostRow < outerMostRow ){
00160 if ( lastHit != NULL ) {
00161 counter = 0 ;
00162 for ( currentHit = piece->firstHit ;
00163 currentHit != 0 && counter < piece->nHits ;
00164 currentHit = ((FtfBaseHit *)currentHit)->nextTrackHit ) {
00165 ((FtfBaseHit *)currentHit)->track = this ;
00166 counter++ ;
00167 }
00168 ((FtfBaseHit *)lastHit)->nextTrackHit = piece->firstHit ;
00169 lastHit = piece->lastHit ;
00170 }
00171 piece->firstHit = 0 ;
00172 innerMostRow = piece->innerMostRow ;
00173 xLastHit = piece->xLastHit ;
00174 yLastHit = piece->yLastHit ;
00175 }
00176 else {
00177 if ( piece->lastHit != NULL ) {
00178 counter = 0 ;
00179 for ( currentHit = (FtfHit *)piece->firstHit ;
00180 currentHit != 0 && counter < piece->nHits ;
00181 currentHit = ((FtfBaseHit *)currentHit)->nextTrackHit ) {
00182 ((FtfBaseHit *)currentHit)->track = this ;
00183 counter++;
00184 }
00185 ((FtfBaseHit *)piece->lastHit)->nextTrackHit = firstHit ;
00186 firstHit = piece->firstHit ;
00187 }
00188 outerMostRow = piece->outerMostRow ;
00189 piece->firstHit = 0 ;
00190 }
00191
00192
00193 nHits += piece->nHits ;
00194 chi2[0] += piece->chi2[0] ;
00195 chi2[1] += piece->chi2[1] ;
00196
00197
00198
00199
00200 getPara()->szFitFlag = 0 ;
00201 if ( getPara()->fillTracks ) fill ( ) ;
00202 getPara()->szFitFlag = 1 ;
00203
00204
00205
00206
00207 piece->flag = -1 ;
00208 }
00209
00210
00211
00212
00213 int FtfTrack::buildTrack ( FtfHit *frstHit, FtfContainer *volume ) {
00214
00215
00216
00217 add ( frstHit, GO_DOWN ) ;
00218
00219
00220
00221 if ( !segment ( volume, GO_DOWN ) ) return 0 ;
00222
00223
00224
00225 int rowToStop = getPara()->rowInnerMost ;
00226 if ( !follow ( volume, GO_DOWN, rowToStop ) ) return 0 ;
00227
00228
00229
00230 if ( getPara()->goBackwards ) follow ( volume, GO_UP, getPara()->rowOuterMost ) ;
00231
00232
00233
00234 if ( getPara()->fillTracks )
00235 fill ( ) ;
00236 #ifdef TRDEBUG
00237 debugFill ( ) ;
00238 #endif
00239
00240 return 1 ;
00241 }
00242
00243
00244
00245 void FtfTrack::dEdx ( ){
00246 int i, j ;
00247 FtfHit *nextHit ;
00248 int nTruncate = max(1,
00249 getPara()->dEdxNTruncate*nHits/100) ;
00250 nTruncate = min(nHits/2,nTruncate) ;
00251
00252
00253
00254 double *de = new double[nTruncate] ;
00255
00256
00257
00258 dedx = 0.F ;
00259 memset ( de, 0, nTruncate*sizeof(double) ) ;
00260
00261
00262
00263 for ( nextHit = (FtfHit *)firstHit ;
00264 nextHit != 0 ;
00265 nextHit = (FtfHit *)nextHit->nextTrackHit) {
00266
00267 dedx += nextHit->q ;
00268
00269 if ( nextHit->q < de[0] ) continue ;
00270
00271 for ( i = nTruncate-1 ; i>=0 ; i-- ){
00272 if ( nextHit->q > de[i] ){
00273 for ( j=0 ; j<i ; j++ ) de[j] = de[j+1] ;
00274 de[i] = nextHit->q ;
00275 break ;
00276 }
00277 }
00278 }
00279
00280
00281
00282 for ( i=0 ; i<nTruncate ; i++ ) dedx -= de[i] ;
00283 dedx = dedx / length ;
00284
00285
00286 }
00287
00288
00289
00290 void FtfTrack::deleteCandidate(void)
00291 {
00292 FtfHit *curentHit = (FtfHit *)firstHit ;
00293 FtfHit *nextHit ;
00294 #ifdef TRDEBUG
00295 debugDeleteCandidate ( ) ;
00296 #endif
00297 while ( curentHit != 0 )
00298 {
00299 nextHit = (FtfHit *)curentHit->nextTrackHit;
00300 curentHit->nextTrackHit = 0 ;
00301 curentHit->xyChi2 =
00302 curentHit->szChi2 =
00303 curentHit->s = 0.F ;
00304
00305 curentHit->setStatus ( 0 ) ;
00306 curentHit = nextHit;
00307 }
00308 }
00309
00310
00311
00312 void FtfTrack::fill ( ) {
00313
00314
00315
00316
00317 double xc, yc ;
00318
00319 double rc = sqrt ( a2Xy * a2Xy + 1 ) / ( 2 * fabs(a1Xy) ) ;
00320
00321 double field = getPara()->bField;
00322
00323
00324 pt = (double)(bFactor * field * 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
00407 if ( d_angle < -pi ) d_angle += twoPi ;
00408
00409 q = ( ( d_angle < 0 ) ? 1 : -1 ) ;
00410 r0 = ::sqrt(xPar*xPar+yPar*yPar) ;
00411 phi0 = atan2(yPar,xPar) ;
00412 if ( phi0 < 0 ) phi0 += 2. * M_PI ;
00413 psi = (double)(angle_vertex - q * 0.5F * pi) ;
00414 if ( psi < 0 ) psi = (double)(psi + twoPi );
00415 if ( psi > twoPi ) psi = (double)(psi - twoPi );
00416
00417
00418
00419 if ( getPara()->szFitFlag == 1 ){
00420 tanl = -(double)a2Sz ;
00421 z0 = (double)(a1Sz + a2Sz * ( length - rc * d_angle * q ) );
00422 }
00423 else if ( getPara()->szFitFlag == 2 ) {
00424 tanl = ((FtfBaseHit *)firstHit)->z /
00425 (double)sqrt ( ((FtfBaseHit *)firstHit)->x*((FtfBaseHit *)firstHit)->x +
00426 ((FtfBaseHit *)firstHit)->y*((FtfBaseHit *)firstHit)->y ) ;
00427 z0 = 0.F ;
00428 }
00429
00430
00431
00432 eta = seta(1.,tanl ) ;
00433
00434
00435
00436 flag = 1 ;
00437
00438 }
00439
00440
00441
00442
00443
00444 void FtfTrack::fillSecondary ( double &xc, double &yc,
00445 double xPar, double yPar )
00446 {
00447
00448
00449
00450 double dx1 = ((FtfBaseHit *)firstHit)->x - xc ;
00451 double dy1 = ((FtfBaseHit *)firstHit)->y - yc ;
00452 double angle1 = atan2 ( dy1, dx1 ) ;
00453 if ( angle1 < 0. ) angle1 = angle1 + twoPi ;
00454
00455 double dx2 = xLastHit - xc ;
00456 double dy2 = yLastHit - yc ;
00457 double angle2 = atan2 ( dy2, dx2 ) ;
00458 if ( angle2 < 0. ) angle2 = angle2 + twoPi ;
00459
00460
00461
00462 double dangle = angle2 - angle1 ;
00463
00464 if ( dangle < -pi ) dangle = dangle + twoPi ;
00465
00466 q = ( ( dangle > 0 ) ? 1 : -1 ) ;
00467 r0 = ((FtfHit *)lastHit)->r ;
00468 phi0 = ((FtfHit *)lastHit)->phi ;
00469 psi = (double)(angle2 - q * piHalf );
00470 if ( psi < 0 ) psi = (double)(psi + twoPi );
00471
00472
00473
00474 if ( getPara()->szFitFlag ){
00475 tanl = -(double)a2Sz ;
00476 z0 = (double)(a1Sz + a2Sz * length );
00477 }
00478 else{
00479 tanl = ((FtfBaseHit *)firstHit)->z /
00480 (double)sqrt ( ((FtfBaseHit *)firstHit)->x*((FtfBaseHit *)firstHit)->x +
00481 ((FtfBaseHit *)firstHit)->y*((FtfBaseHit *)firstHit)->y ) ;
00482 z0 = 0.F ;
00483 }
00484
00485
00486
00487 eta = seta(1., tanl ) ;
00488
00489
00490
00491 flag = 0 ;
00492 }
00493
00494
00495
00496
00497
00498
00499
00500 int FtfTrack::follow ( FtfContainer *volume, int way, int ir_stop ) {
00501
00502 FtfHit *nextHit ;
00503
00504 if ( way < 0 )
00505 nextHit = (FtfHit *)lastHit ;
00506 else
00507 nextHit = (FtfHit *)firstHit ;
00508 #ifdef TRDEBUG
00509 if ( getPara()->trackDebug && getPara()->debugLevel >= 2 )
00510 ftfLog ( "FtfTrack::follow: ===> Going into Track extension <===\n" );
00511 #endif
00512
00513
00514
00515 double xyChi2 = chi2[0] ;
00516 double szChi2 = chi2[1] ;
00517
00518
00519
00520
00521
00522 while ( way * nextHit->row < way * ir_stop ) {
00523
00524
00525
00526 chi2[0] = getPara()->hitChi2Cut ;
00527
00528 nextHit = seekNextHit ( volume, nextHit, way*getPara()->trackRowSearchRange, USE_FOLLOW ) ;
00529
00530 #ifdef TRDEBUG
00531 if ( getPara()->trackDebug && getPara()->debugLevel >= 1 ){
00532 if ( nextHit != 0 ){
00533 ftfLog ( "FtfTrack::follow: Search succesful, hit selected %d\n",
00534 nextHit->id );
00535
00536 }
00537 else{
00538 ftfLog ( "FtfTrack::follow: Search unsuccesful\n" );
00539 if ( chi2[0]+chi2[1] > getPara()->hitChi2Cut )
00540 ftfLog ( " hit chi2 %f larger than cut %f ", chi2[0]+chi2[1],
00541 getPara()->hitChi2Cut ) ;
00542 }
00543 debugAsk () ;
00544 }
00545 #endif
00546
00547
00548
00549 if ( nextHit == 0 ) break ;
00550
00551
00552
00553 double lxyChi2 = chi2[0]-chi2[1] ;
00554 xyChi2 += lxyChi2 ;
00555 nextHit->xyChi2 = lxyChi2 ;
00556
00557
00558
00559 if ( getPara()->szFitFlag ) {
00560 length = nextHit->s ;
00561 szChi2 += chi2[1] ;
00562 nextHit->szChi2 = chi2[1] ;
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 ){
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 = length + 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 if ( lchi2 < chi2[0] ) {
00660 chi2[0] = (double)lchi2 ;
00661 chi2[1] = (double)lszChi2 ;
00662
00663 if ( getPara()->szFitFlag ) candidateHit->s = (double)slocal ;
00664
00665
00666
00667 if ( lchi2 < getPara()->goodHitChi2 ) return 2 ;
00668
00669 return 1 ;
00670 }
00671
00672
00673
00674 return 0 ;
00675 }
00676
00677
00678
00679 int FtfTrack::mergePrimary ( FtfContainer *trackArea ){
00680 short track_merged ;
00681 register int areaIndex ;
00682 int i_phi, i_eta ;
00683 FtfTrack *i_track = 0 ;
00684 int ip, ie ;
00685 double delta_psi ;
00686
00687
00688
00689 if ( flag != 1 ) return 0 ;
00690
00691
00692
00693 i_phi = (int)(( psi - getPara()->phiMinTrack ) / getPara()->phiSliceTrack + 1 );
00694 if ( i_phi < 0 ) {
00695 ftfLog ( " Track phi index too low %d \n", i_phi ) ;
00696 i_phi = 1 ;
00697 }
00698 if ( i_phi >= getPara()->nPhiTrackPlusOne ) {
00699 ftfLog ( " Track phi index too high %d \n", i_phi ) ;
00700 i_phi = getPara()->nPhiTrack ;
00701 }
00702
00703
00704
00705 i_eta = (int)(( eta - getPara()->etaMinTrack ) / getPara()->etaSliceTrack + 1 );
00706 if ( i_eta <= 0 ) {
00707 ftfLog ( " Track eta index too low %d \n", i_eta ) ;
00708 i_eta = 1 ;
00709 }
00710 if ( i_eta >= getPara()->nEtaTrackPlusOne ) {
00711 ftfLog ( " Track eta index too high %d \n", i_eta ) ;
00712 i_eta = getPara()->nEtaTrack ;
00713 }
00714
00715
00716
00717 track_merged = 0 ;
00718 for ( ip = max(i_phi-1,1) ; ip < min(i_phi+2,getPara()->nPhiTrackPlusOne) ; ip++ ) {
00719 for ( ie = max(i_eta-1,1) ; ie < min(i_eta+2,getPara()->nEtaTrackPlusOne) ; ie++ ) {
00720 areaIndex = ip * getPara()->nEtaTrackPlusOne + ie ;
00721
00722
00723
00724 for ( i_track = (FtfTrack *)trackArea[areaIndex].first ;
00725 i_track != 0 ;
00726 i_track = i_track->getNextTrack() ) {
00727
00728
00729
00730 if ( i_track->flag < 0 ) continue ;
00731
00732
00733
00734
00735 short delta1 = i_track->outerMostRow - outerMostRow ;
00736 short delta2 = i_track->innerMostRow - innerMostRow ;
00737 if ( delta1 * delta2 <= 0 ) continue ;
00738
00739
00740
00741 if ( fabs(eta-i_track->eta) > getPara()->detaMerge ) continue ;
00742 delta_psi = (double)fabs(psi - i_track->psi) ;
00743 if ( delta_psi > getPara()->dphiMerge && delta_psi < twoPi - getPara()->dphiMerge ) continue ;
00744
00745 i_track->add ( this ) ;
00746 #ifdef TRDEBUG
00747 if ( getPara()->debugLevel > 1 )
00748 ftfLog ( " \n Track %d merge into %d ", this->id, i_track->id ) ;
00749 #endif
00750 track_merged = 1 ;
00751 break ;
00752 }
00753 }
00754 }
00755
00756
00757
00758 if ( track_merged == 0 ) {
00759 areaIndex = i_phi * getPara()->nEtaTrackPlusOne + i_eta ;
00760 if ( trackArea[areaIndex].first == 0 )
00761 trackArea[areaIndex].first =
00762 trackArea[areaIndex].last = (void *)this ;
00763 else {
00764 ((FtfTrack *)trackArea[areaIndex].last)->nxatrk = this ;
00765 trackArea[areaIndex].last = (void *)this ;
00766 }
00767 }
00768 return track_merged ;
00769 }
00770
00771
00772
00773 void FtfTrack::reset (void)
00774 {
00775
00776
00777
00778
00779 flag = getPara()->primaries ;
00780 nHits = 0 ;
00781 s11Xy =
00782 s12Xy =
00783 s22Xy =
00784 g1Xy =
00785 g2Xy =
00786 chi2[0] = 0.F ;
00787 nxatrk = 0 ;
00788 if ( getPara()->szFitFlag )
00789 {
00790 s11Sz =
00791 s12Sz =
00792 s22Sz =
00793 g1Sz =
00794 g2Sz =
00795 chi2[1] =
00796 length = 0.F ;
00797 }
00798 }
00799
00800
00801
00802
00803
00804
00805
00806
00807 FtfHit *FtfTrack::seekNextHit ( FtfContainer *volume,
00808 FtfHit *baseHit,
00809 int n_r_steps,
00810 int which_function ) {
00811 #define N_LOOP 9
00812 int loop_eta[N_LOOP] = { 0, 0, 0,-1,-1,-1, 1, 1, 1 } ;
00813 int loop_phi[N_LOOP] = { 0,-1, 1, 0,-1, 1, 0,-1, 1 };
00814
00815
00816 int ir, irp, ipp, itp, k;
00817 register int areaIndex ;
00818 int result ;
00819
00820
00821
00822
00823 int initialRow, way ;
00824 if ( n_r_steps < 0 ) {
00825 initialRow = max(1, (baseHit->row - getPara()->rowInnerMost)/getPara()->modRow);
00826 n_r_steps = min(initialRow,-n_r_steps ) ;
00827 way = -1 ;
00828 }
00829 else {
00830 initialRow = max(1, (baseHit->row - getPara()->rowInnerMost + 2)/getPara()->modRow);
00831 n_r_steps = min((getPara()->rowOuterMost-initialRow+1),n_r_steps) ;
00832 way = 1 ;
00833 }
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 ftfLog ( "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 ) ;
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 ftfLog ( "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 ftfLog ( "FtfTrack::segment: Search succesful, hit %d selected\n",
00950 nextHit->id );
00951
00952 }
00953 else
00954 ftfLog ( "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 ftfLog ( "FtfTrack::segmentHitSelection:\n");
01041 ftfLog ( "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 ftfLog ( "Best point, keep it !!!\n" );
01045 else{
01046 ftfLog ( "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 ftfLog ( "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 ftfLog ( "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 ftfLog ( "FtfTrack::debugDeleteCandidate: Track %d has %d hits <==\n"
01111 ,id, nHits );
01112 ftfLog ( "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 ftfLog ( "\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 ftfLog ( "FtfTrack::debugFollowCandidate ===> Extension in Follow <===\n" ) ;
01144
01145
01146 ftfLog ( "FtfTrack::debugFollowCandidate: Try hit %d\n", candidateHit->id ) ;
01147 candidateHit->print ( 11 ) ;
01148
01149
01150
01151 if ( candidateHit->track != 0 )
01152 {
01153 ftfLog ( "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 ftfLog ( " \n ------------------------------------- " ) ;
01177 if ( lchi2 < chi2_min ){
01178 ftfLog ( "FtfTrack::debugFollowSuccess: %f Best Chi2, keep point !!!\n",
01179 lchi2 );
01180 if ( lchi2 < getPara()->goodHitChi2 ){
01181 ftfLog ( "This Chi2 is better than the good cut %f\n",
01182 lchi2, getPara()->goodHitChi2 );
01183 ftfLog ( "Stop search !!! " );
01184 }
01185 }
01186 else{
01187 ftfLog ( "FtfTrack::debugFollowSuccess: Hit %d worse than previous, forget it !! ",
01188 candidateHit->id );
01189
01190 }
01191
01192
01193 ftfLog ( " \n ------------------------------------- " ) ;
01194
01195
01196
01197 if ( getPara()->debugLevel > 2 ) {
01198 ftfLog ( "FtfTrack::debugFollowSuccess:\n");
01199 ftfLog ( "dis_xy dis_sz %7.2e %7.2e\n ", dxy, dsz );
01200 ftfLog ( "Error xy sz %7.2e %7.2e\n ",
01201 candidateHit->wxy, candidateHit->wz );
01202 ftfLog ( "xy:a1,a2;sz:a1,a2 %7.2f %7.2f %7.2f %7.2f\n",
01203 a1Xy, a2Xy, a1Sz, a2Sz );
01204 ftfLog ( "ch2:xy sz tot min %7.2f %7.2f %7.2f %7.2f\n",
01205 lxyChi2,lszChi2, lchi2, chi2_min );
01206 }
01207 debugAsk() ;
01208
01209 }
01210
01211
01212
01213
01214 void FtfTrack::debugInVolume ( FtfHit *baseHit, FtfHit *candidateHit )
01215 {
01216
01217 if ( getPara()->trackDebug && getPara()->debugLevel >= 2 ) {
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229 if ( nHits > getPara()->nHitsForSegment+1 ) Print ( 31 ) ;
01230
01231 ftfLog ( "FtfTrack:debugInVolume: Try hit %d\n", candidateHit->id ) ;
01232 candidateHit->print ( 11 ) ;
01233
01234
01235
01236 if ( candidateHit->track != 0 ) {
01237 ftfLog ( "FtfTrack:debugInVolume: hit %d used in track %d\n",
01238 candidateHit->id, id+1 );
01239
01240 }
01241 else {
01242 double dphi = (double)fabs(baseHit->phi - candidateHit->phi) ;
01243 double deta ;
01244 if ( baseHit->dz < 1000 && candidateHit->dz < 1000 )
01245 deta = (double)fabs(baseHit->eta - candidateHit->eta) ;
01246 else
01247 deta = 0.F ;
01248
01249 if ( dphi > getPara()->dphi )
01250 ftfLog ( "FtfTrack:debugInVolume: Hits too far apart in phi: %f \n",
01251 dphi ) ;
01252 if ( deta > getPara()->deta )
01253 ftfLog ( "FtfTrack:debugInVolume: Hits too far apart in eta: %f \n",
01254 deta ) ;
01255 }
01256 debugAsk () ;
01257 }
01258 }
01259
01260
01261
01262 void FtfTrack::debugNew ( )
01263 {
01264
01265 if ( firstHit->id == getPara()->hitDebug ) getPara()->trackDebug = 1 ;
01266 if ( getPara()->trackDebug && getPara()->debugLevel >= 1 )
01267 {
01268 ftfLog ( "================================================ \n" );
01269 ftfLog ( "FtfTrack::debugNew:Starting track %d from point %d\n",
01270 id, firstHit->id );
01271 ftfLog ( "================================================ \n" );
01272
01273
01274 debugAsk () ;
01275 }
01276 }
01277 #endif