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