00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "FtfFinder.h"
00027
00028 #include <stdlib.h>
00029
00030
00031
00032
00033
00034 FtfFinder::FtfFinder ( )
00035 {
00036
00037 hit = 0 ;
00038 track = 0 ;
00039 mcTrack = 0 ;
00040 trackC = 0 ;
00041 volumeC = 0 ;
00042 rowC = 0 ;
00043 nHitsOutOfRange = 0 ;
00044 }
00045
00046
00047
00048 FtfFinder::~FtfFinder ( )
00049 {
00050
00051 if ( mcTrack ) delete[] mcTrack ;
00052 if ( volumeC ) delete[] volumeC ;
00053 if ( rowC ) delete[] rowC ;
00054 if ( trackC ) delete[] trackC ;
00055 }
00056
00057
00058
00059 double FtfFinder::process ( ) {
00060
00061
00062
00063 if ( nHits <= 0 ) {
00064 if ( para.infoLevel > 2 ) LOG(ERR, "fft: Hit structure is empty \n " ) ;
00065 return 1 ;
00066 }
00067
00068 initialCpuTime = CpuTime ( );
00069 initialRealTime = RealTime ( );
00070
00071
00072
00073 if ( para.init == 0 ) {
00074 if ( reset ( ) ) return 1 ;
00075 }
00076
00077
00078
00079 if ( para.eventReset && setPointers ( ) ) return 1 ;
00080
00081
00082
00083 short i ;
00084 para.primaries = 1 ;
00085 for ( i = 0 ; i < para.nPrimaryPasses ; i++ )
00086 if ( getTracks ( ) ) break ;
00087
00088
00089
00090 para.primaries = 0 ;
00091 for ( i = 0 ; i < para.nSecondaryPasses ; i++ )
00092 if ( getTracks ( ) ) break ;
00093
00094
00095
00096 cpuTime = CpuTime ( ) - initialCpuTime ;
00097 realTime = RealTime ( ) - initialRealTime ;
00098 #ifdef DEBUG
00099 if ( para.infoLevel > 0 )
00100 LOG(ERR, "FtfFinder::process: cpu %7.3f real %f7.2 \n", cpuTime, realTime ) ;
00101 #endif
00102 return cpuTime ;
00103 }
00104
00105
00106
00107 void FtfFinder::dEdx ( ) {
00108 for ( int i = 0 ; i<nTracks ; i++ ){
00109 track[i].dEdx( ) ;
00110 }
00111 }
00112
00113
00114
00115
00116 int FtfFinder::getTracks ( ) {
00117
00118
00119
00120 int nHitsSegment = (short)para.nHitsForSegment;
00121 if ( para.primaries ) {
00122 setConformalCoordinates ( ) ;
00123 para.minHitsForFit = 1 ;
00124 para.nHitsForSegment = max(2,nHitsSegment);
00125 }
00126 else {
00127 para.minHitsForFit = 2 ;
00128 para.nHitsForSegment = max(3,nHitsSegment);
00129 }
00130
00131
00132
00133 for ( int ir = para.nRowsPlusOne - 1 ; ir>=para.minHitsPerTrack ; ir--) {
00134
00135
00136
00137 if ( rowC[ir].first && (((FtfHit *)rowC[ir].first)->row) < para.rowEnd )
00138 break ;
00139
00140 for ( FtfHit *firstHit = (FtfHit *)rowC[ir].first ;
00141 firstHit != 0 ;
00142 firstHit = (FtfHit *)(firstHit->nextRowHit) ) {
00143
00144
00145
00146 if ( firstHit->track != 0 ) continue ;
00147
00148
00149
00150 nTracks++ ;
00151
00152
00153 if ( nTracks > maxTracks ){
00154 LOG(ERR, "\n FtfFinder::getTracks: Max nr tracks reached !") ;
00155 nTracks = maxTracks ;
00156 return 1 ;
00157 }
00158
00159
00160
00161 FtfTrack *thisTrack = &track[nTracks-1];
00162 thisTrack->para = ¶ ;
00163 thisTrack->id = nTracks ;
00164 thisTrack->firstHit = thisTrack->lastHit = firstHit ;
00165 thisTrack->innerMostRow = thisTrack->outerMostRow = firstHit->row ;
00166 thisTrack->xRefHit = firstHit->x ;
00167 thisTrack->yRefHit = firstHit->y ;
00168 thisTrack->xLastHit = firstHit->x ;
00169 thisTrack->yLastHit = firstHit->y ;
00170 #ifdef TRDEBUG
00171 thisTrack->debugNew ( ) ;
00172 #endif
00173
00174
00175
00176 thisTrack->reset ( ) ;
00177
00178
00179
00180 if ( thisTrack->buildTrack ( firstHit, volumeC ) ) {
00181
00182
00183
00184 if ( para.primaries &&
00185 para.mergePrimaries == 1 &&
00186 para.fillTracks &&
00187 thisTrack->mergePrimary( trackC ) ) {
00188 nTracks-- ;
00189 thisTrack->deleteCandidate ( ) ;
00190 }
00191 }
00192 else{
00193
00194
00195
00196 thisTrack->deleteCandidate ( ) ;
00197 nTracks-- ;
00198 }
00199
00200
00201
00202 }
00203
00204
00205
00206
00207 if ( CpuTime() - initialCpuTime > para.maxTime ) {
00208 LOG(ERR, "FtfFinder::getTracks: tracker time out after %f\n",
00209 CpuTime() - initialCpuTime ) ;
00210 break ;
00211 }
00212 }
00213
00214 para.nHitsForSegment = nHitsSegment ;
00215
00216 return 0 ;
00217 }
00218
00219
00220 void FtfFinder::mergePrimaryTracks ( ) {
00221
00222
00223
00224 memset ( trackC, 0, para.nPhiTrackPlusOne*para.nEtaTrackPlusOne*sizeof(FtfContainer) ) ;
00225
00226
00227
00228
00229 for ( int i = 0 ; i < nTracks ; i++ ) {
00230 currentTrack = &(track[i]);
00231 if ( currentTrack->flag < 0 ) continue ;
00232
00233
00234
00235 currentTrack->nxatrk = 0 ;
00236
00237
00238
00239
00240
00241 if ( currentTrack->mergePrimary ( trackC ) ) {
00242 currentTrack->flag = -1 ;
00243 }
00244 }
00245 }
00246
00247
00248
00249 int FtfFinder::reset (void) {
00250 double phiDiff ;
00251
00252
00253
00254 para.init = 0 ;
00255
00256
00257
00258 para.nRowsPlusOne = ( para.rowOuterMost - para.rowInnerMost ) / para.modRow + 2 ;
00259 if ( para.nRowsPlusOne < 1 ) {
00260 LOG(ERR, " Rows: Outer Most Inner Most %d % d \n",
00261 para.rowOuterMost, para.rowInnerMost ) ;
00262 return 1 ;
00263 }
00264 para.nPhiPlusOne = para.nPhi + 1 ;
00265 para.nEtaPlusOne = para.nEta + 1 ;
00266 para.nPhiEtaPlusOne = para.nPhiPlusOne * para.nEtaPlusOne ;
00267 if ( para.mergePrimaries ) {
00268 para.nPhiTrackPlusOne = para.nPhiTrack + 1 ;
00269 para.nEtaTrackPlusOne = para.nEtaTrack + 1 ;
00270 }
00271
00272
00273
00274 if (volumeC != NULL) delete []volumeC;
00275 #ifdef TRDEBUG
00276 LOG(ERR, "Allocating %d bytes of memory for volume\n",
00277 para.nRowsPlusOne*
00278 para.nPhiPlusOne*
00279 para.nEtaPlusOne*sizeof(VOLUME));
00280 #endif
00281 int nVolumes = para.nRowsPlusOne*para.nPhiPlusOne *
00282 para.nEtaPlusOne ;
00283 volumeC = new FtfContainer[nVolumes];
00284 if(volumeC == NULL) {
00285 LOG(ERR, "Problem with memory allocation... exiting\n" ) ;
00286 return 1 ;
00287 }
00288
00289
00290
00291 if ( rowC != NULL ) delete[] rowC ;
00292 #ifdef TRDEBUG
00293 LOG(ERR, "Allocating %d bytes of memory for rowC\n",
00294 para.nRowsPlusOne*sizeof(ROW));
00295 #endif
00296 rowC = new FtfContainer[para.nRowsPlusOne];
00297 if ( rowC == NULL) {
00298 LOG(ERR, "Problem with memory allocation... exiting\n" ) ;
00299 exit(0);
00300 }
00301
00302
00303
00304 if ( para.mergePrimaries ) {
00305 if (trackC != NULL) delete []trackC ;
00306 #ifdef TRDEBUG
00307 LOG(ERR, "Allocating %d bytes of memory for track_area\n",
00308 para.nPhiTrackPlusOne*
00309 para.nEtaTrackPlusOne*sizeof(AREA));
00310 #endif
00311 int nTrackVolumes = para.nPhiTrackPlusOne*
00312 para.nEtaTrackPlusOne ;
00313 trackC = new FtfContainer[nTrackVolumes];
00314 if(trackC == NULL) {
00315 LOG(ERR, "Problem with memory allocation... exiting\n" ) ;
00316 return 1 ;
00317 }
00318 else{
00319
00320
00321
00322 if ( trackC == 0 ){
00323 LOG(ERR,"FtfFinder::reset: Merging option not available \n " ) ;
00324 LOG(ERR, " when option was not used the first time \n " ) ;
00325 return 1 ;
00326 }
00327 }
00328 }
00329
00330
00331
00332 phiDiff = para.phiMax - para.phiMin ;
00333 if ( phiDiff > 2. * pi + 0.1 ) {
00334 LOG(ERR, "FtfFinder::reset: Wrong phi range %f, %f ",
00335 para.phiMin*toDeg, para.phiMax*toDeg ) ;
00336 return 1 ;
00337 }
00338 if ( fabs(phiDiff-twoPi ) < pi / 36. ) para.phiClosed = 1 ;
00339 else
00340 para.phiClosed = 0 ;
00341
00342
00343
00344 para.phiSlice = (para.phiMax - para.phiMin)/para.nPhi ;
00345 para.etaSlice = (para.etaMax - para.etaMin)/para.nEta ;
00346
00347
00348
00349 para.phiSliceTrack = (para.phiMaxTrack - para.phiMinTrack)/para.nPhiTrack ;
00350 para.etaSliceTrack = (para.etaMaxTrack - para.etaMinTrack)/para.nEtaTrack ;
00351
00352
00353
00354 if ( para.xVertex != 0 || para.yVertex != 0 ) {
00355 para.rVertex = (double)sqrt (para.xVertex*para.xVertex +
00356 para.yVertex*para.yVertex) ;
00357 para.phiVertex = (double)atan2(para.yVertex,para.xVertex);
00358 }
00359 else {
00360 para.rVertex = 0.F ;
00361 para.phiVertex = 0.F ;
00362 }
00363
00364 if ( para.dxVertex != 0 || para.dyVertex != 0 )
00365 para.xyWeightVertex = 1.F / ((double)sqrt(para.dxVertex*para.dxVertex+
00366 para.dyVertex*para.dyVertex) ) ;
00367 else para.xyWeightVertex = 1.0F ;
00368
00369
00370
00371
00372
00373
00374
00375
00376 para.init = 1 ;
00377 return 0 ;
00378 }
00379
00380
00381
00382
00383 int FtfFinder::setConformalCoordinates ( )
00384 {
00385
00386
00387
00388 FtfHit* thisHit ;
00389 double x, y, r2, invR2 ;
00390 for ( int ihit = 0 ; ihit<nHits ; ihit++ )
00391 {
00392
00393
00394
00395 thisHit = &(hit[ihit]) ;
00396
00397 uint *v1 = (uint *)volumeC;
00398 uint *v2 = (uint *)&volumeC[20746];
00399 uint *h = (uint *)thisHit;
00400
00401 if((h>v1) && (h<v2)) {
00402 printf("hit: 0x%p v1=0x%p v2=0x%p ihit=%d nHits=%d hit=0x%p\n",
00403 h,v1,v2,ihit,nHits,hit);
00404 }
00405
00406
00407 x = thisHit->x - para.xVertex ;
00408 y = thisHit->y - para.yVertex ;
00409 r2 = x * x + y * y ;
00410 invR2 = 1.F / r2 ;
00411
00412 thisHit->xp = x * invR2 ;
00413 thisHit->yp = - y * invR2 ;
00414 thisHit->wxy = r2 * r2 / ( square(para.xyErrorScale)
00415 * ( square(thisHit->dx) + square(thisHit->dy) ) ) ;
00416 }
00417
00418 return 0 ;
00419 }
00420
00421
00422
00423 int FtfFinder::setPointers ( )
00424 {
00425 int ihit, localRow ;
00426 register int volumeIndex;
00427 double r, r2, phi, eta ;
00428 FtfHit *thisHit ;
00429
00430 nHitsOutOfRange = 0 ;
00431
00432
00433
00434 memset ( rowC, 0, para.nRowsPlusOne*sizeof(FtfContainer) ) ;
00435 int n = para.nRowsPlusOne*para.nEtaPlusOne*para.nPhiPlusOne ;
00436 memset ( volumeC, 0, n*sizeof(FtfContainer) ) ;
00437 if ( para.mergePrimaries ){
00438 memset ( trackC, 0, para.nPhiTrackPlusOne*para.nEtaTrackPlusOne*sizeof(FtfContainer) ) ;
00439 }
00440
00441
00442
00443 for ( ihit = 0 ; ihit<nHits ; ihit++ )
00444 {
00445
00446
00447
00448 thisHit = &(hit[ihit]) ;
00449 localRow = thisHit->row - para.rowInnerMost ;
00450 if ( fmod((double)localRow,(double)para.modRow) != 0 ) continue ;
00451
00452 if ( thisHit->row < para.rowInnerMost ) continue ;
00453 if ( thisHit->row > para.rowOuterMost ) continue ;
00454
00455
00456
00457 localRow = localRow / para.modRow + 1 ;
00458
00459
00460
00461
00462
00463 r2 = thisHit->x * thisHit->x + thisHit->y * thisHit->y ;
00464 r = (double)sqrt ( r2 ) ;
00465 phi = (double)atan2(thisHit->y,thisHit->x) + para.phiShift ;
00466 if ( phi < 0 ) phi = phi + twoPi ;
00467
00468 eta = (double)seta(r,thisHit->z) ;
00469
00470 if ( para.szFitFlag ) {
00471 thisHit->s = 0.F ;
00472 thisHit->wz = (double)(1./ square ( para.szErrorScale * thisHit->dz ));
00473 }
00474
00475 thisHit->r = r ;
00476 thisHit->phi = phi ;
00477 thisHit->eta = eta ;
00478
00479
00480
00481 thisHit->nextVolumeHit =
00482 thisHit->nextRowHit = 0 ;
00483
00484
00485
00486
00487 thisHit->phiIndex = (int)( (thisHit->phi-para.phiMin)/para.phiSlice + 1.);
00488 if ( thisHit->phiIndex < 1 || thisHit->phiIndex > para.nPhi ) {
00489 if ( para.infoLevel > 2 ) {
00490 LOG(ERR, " === > Hit %d has Phi = %f \n", (int)thisHit->id,
00491 thisHit->phi*toDeg ) ;
00492 LOG(ERR, " Phi index %d out of range \n", thisHit->phiIndex ) ;
00493 }
00494 nHitsOutOfRange++ ;
00495 continue ;
00496 }
00497
00498
00499
00500
00501
00502 thisHit->etaIndex = (int)((thisHit->eta - para.etaMin)/para.etaSlice + 1.);
00503 if ( thisHit->etaIndex < 1 || thisHit->etaIndex > para.nEta ) {
00504 if ( para.infoLevel > 2 ) {
00505 LOG(ERR, " \n === > Hit %d has Eta = %f z %f ", (int)thisHit->id,
00506 thisHit->eta, thisHit->z ) ;
00507 LOG(ERR, " \n Eta min/max %f %f ", para.etaMin, para.etaMax ) ;
00508 LOG(ERR, " \n Eta slice %f ", para.etaSlice ) ;
00509 LOG(ERR, " \n Eta index %d out of range ", thisHit->etaIndex ) ;
00510 }
00511 nHitsOutOfRange++ ;
00512 continue ;
00513 }
00514
00515
00516
00517 thisHit->nextTrackHit = 0 ;
00518 thisHit->track = 0 ;
00519
00520
00521
00522
00523
00524 volumeIndex = localRow * para.nPhiEtaPlusOne +
00525 thisHit->phiIndex * para.nEtaPlusOne + thisHit->etaIndex ;
00526
00527
00528 if (volumeC[volumeIndex].first == 0 )
00529 volumeC[volumeIndex].first = (void *)thisHit ;
00530 else
00531 ((FtfHit *)(volumeC[volumeIndex].last))->nextVolumeHit = thisHit ;
00532 volumeC[volumeIndex].last = (void *)thisHit ;
00533
00534
00535
00536
00537
00538 if ( rowC[localRow].first == NULL ){
00539 rowC [localRow].first = (void *)thisHit ;
00540 }
00541 else
00542 ((FtfHit *)(rowC[localRow].last))->nextRowHit = thisHit ;
00543 rowC[localRow].last = (void *)thisHit ;
00544 }
00545 return 0 ;
00546 }
00547
00548
00549
00550 #include <stdio.h>
00551 #include <stdlib.h>
00552 #include <time.h>
00553
00554 double FtfFinder::CpuTime( void ) {
00555 return (double)(clock()) / CLOCKS_PER_SEC;
00556 }
00557
00558
00559 #ifdef I386
00560 double FtfFinder::RealTime (void) {
00561 const long nClicks = 400000000 ;
00562 unsigned long eax, edx;
00563 asm volatile("rdtsc":"=a" (eax), "=d" (edx));
00564 double realTime = (double)(eax)/ nClicks;
00565 return realTime;
00566 }
00567 #else
00568 double FtfFinder::RealTime (void) {
00569 return 1. ;
00570 }
00571 #endif