StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
FtfFinder.cxx
1 //:>------------------------------------------------------------------
2 //: FILE: FtfFinder.cxx
3 //: HISTORY:
4 //: 28oct1996 version 1.00
5 //: 03jun1999 ppy para.fillTracks included. Merging only when tracks filled
6 //: 03jun1999 ppy add a function for real time, clock gives cpu time
7 //: 06may1999 ppy getTracks returns 1 for error
8 //: 10aug1999 ppy nHitsForSegment set to at least 3 for
9 //: secondary search.
10 //: 23aug1999 ppy ClassImp added with ROOT flag
11 //: 21dec1999 ppy printf replaced by fprintf(stderr,...
12 //: 26jan2000 ppy malloc replaced with new, destructor function added
13 //: 27jan2000 ppy refHit replaced by xRefHit and yRefHit
14 //: 28jan2000 ppy track id from 1 to N
15 //: 1feb2000 ppy track id starting at 1
16 //: 11feb2000 ppy timeout added, variables initialCpuTime and
17 //: initialRealTime added
18 //: 10apr2000 ppy deleteCandidate added when track is merged
19 //: 21aug2000 ppy replace prints with ftfLog
20 //:<------------------------------------------------------------------
21 //:>------------------------------------------------------------------
22 //: CLASS: FtfFinder, steers track finding
23 //: DESCRIPTION: Functions associated with this class
24 //: AUTHOR: ppy - Pablo Yepes, yepes@physics.rice.edu
25 //:>------------------------------------------------------------------
26 #include "Stiostream.h"
27 #include "Stl3Util/ftf/FtfFinder.h"
28 
29 
30 //*********************************************************************
31 // Initializes the package
32 //*********************************************************************
33 FtfFinder::FtfFinder ( )
34 {
35 //
36  hit = 0 ;
37  track = 0 ;
38  mcTrack = 0 ;
39  trackC = 0 ;
40  volumeC = 0 ;
41  rowC = 0 ;
42  nHitsOutOfRange = 0 ;
43 }
44 //*********************************************************************
45 // Initializes the package
46 //*********************************************************************
47 FtfFinder::~FtfFinder ( )
48 {
49 //
50  if ( mcTrack ) delete[] mcTrack ;
51  if ( volumeC ) delete[] volumeC ;
52  if ( rowC ) delete[] rowC ;
53  if ( trackC ) delete[] trackC ;
54 }
55 //*********************************************************************
56 // Steers the tracking
57 //*********************************************************************
58 double FtfFinder::process ( ) {
59  //--------------------------------------------------------
60  // Make sure there is something to work with
61  //--------------------------------------------------------
62  if ( nHits <= 0 ) {
63  if ( para.infoLevel > 2 )
64  ftfLog ( "fft: Hit structure is empty \n " ) ;
65  return 1 ;
66  }
67 
68  initialCpuTime = CpuTime ( );
69  initialRealTime = RealTime ( );
70 
71  // General initialization
72  if ( para.init == 0 ) {
73  if ( reset ( ) ) return 1 ;
74  }
75 
76  // Event reset and set pointers
77  if ( para.eventReset && setPointers ( ) ) return 1 ;
78 
79  // Build primary tracks now
80  short i ;
81  para.primaries = 1 ;
82  for ( i = 0 ; i < para.nPrimaryPasses ; i++ )
83  if ( getTracks ( ) ) break ;
84 
85  // Look for secondaries
86  para.primaries = 0 ;
87  for ( i = 0 ; i < para.nSecondaryPasses ; i++ )
88  if ( getTracks ( ) ) break ;
89 
90  // if ( para.dEdx ) dEdx ( ) ;
91 
92  cpuTime = CpuTime ( ) - initialCpuTime ;
93  realTime = RealTime ( ) - initialRealTime ;
94 #ifdef DEBUG
95  if ( para.infoLevel > 0 )
96  ftfLog ( "FtfFinder::process: cpu %7.3f real %f7.2 \n", cpuTime, realTime ) ;
97 #endif
98  return cpuTime ;
99 }
100 
101 
102 //********************************************************************
103 // Calculates deposited Energy
104 //********************************************************************
105 void FtfFinder::dEdx ( ) {
106  for ( int i = 0 ; i<nTracks ; i++ ){
107  track[i].dEdx( ) ;
108  }
109 }
110 
111 //**********************************************************************
112 // Recontruct primary tracks
113 //**********************************************************************
114 int FtfFinder::getTracks ( ) {
115 //
116 // Set conformal coordinates if we are working with primaries
117 //
118  int nHitsSegment = (short)para.nHitsForSegment;
119  if ( para.primaries ) {
120  setConformalCoordinates ( ) ;
121  para.minHitsForFit = 1 ;
122  para.nHitsForSegment = max(2,nHitsSegment);
123  }
124  else {
125  para.minHitsForFit = 2 ;
126  para.nHitsForSegment = max(3,nHitsSegment);
127  }
128 //
129 // Loop over rows
130 //
131  for ( int ir = para.nRowsPlusOne - 1 ; ir>=para.minHitsPerTrack ; ir--) {
132 //
133 // Loop over hits in this particular row
134 //
135  if ( rowC[ir].first && (((FtfHit *)rowC[ir].first)->row) < para.rowEnd ) break ;
136 // if ( (((FtfHit *)rowC[ir].first)->row) < para.rowEnd ) break ;
137  for ( FtfHit *firstHit = (FtfHit *)rowC[ir].first ;
138  firstHit != 0 ;
139  firstHit = (FtfHit *)(firstHit->nextRowHit) ) {
140 //
141 // Check hit was not used before
142 //
143  if ( firstHit->track != 0 ) continue ;
144 //
145 // One more track
146 //
147  nTracks++ ;
148 //
149 //
150  if ( nTracks > maxTracks ){
151  ftfLog( "\n FtfFinder::getTracks: Max nr tracks reached !") ;
152  nTracks = maxTracks ;
153  return 1 ;
154  }
155 //
156 // Initialize variables before going into track hit loop
157 //
158  FtfTrack *thisTrack = &track[nTracks-1];
159  thisTrack->para = &para ;
160  thisTrack->id = nTracks ;
161  thisTrack->firstHit = thisTrack->lastHit = firstHit ;
162  thisTrack->innerMostRow = thisTrack->outerMostRow = firstHit->row ;
163  thisTrack->xRefHit = firstHit->x ;
164  thisTrack->yRefHit = firstHit->y ;
165  thisTrack->xLastHit = firstHit->x ;
166  thisTrack->yLastHit = firstHit->y ;
167 #ifdef TRDEBUG
168  thisTrack->debugNew ( ) ;
169 #endif
170 //
171 // Set fit parameters to zero
172 //
173  thisTrack->reset ( ) ;
174 //
175 // Go into hit looking loop
176 //
177  if ( thisTrack->buildTrack ( firstHit, volumeC ) ) {
178 //
179 // Merge Tracks if requested
180 //
181  if ( para.primaries &&
182  para.mergePrimaries == 1 &&
183  para.fillTracks &&
184  thisTrack->mergePrimary( trackC ) ) {
185  nTracks-- ;
186  thisTrack->deleteCandidate ( ) ;
187  }
188  }
189  else{
190 //
191 // If track was not built delete candidate
192 //
193  thisTrack->deleteCandidate ( ) ;
194  nTracks-- ;
195  }
196  //
197  // End loop over hits inside row
198  //
199  }
200  // End loop over rows
201  //
202  // Check time
203  //
204  if ( CpuTime() - initialCpuTime > para.maxTime ) {
205  ftfLog ( "FtfFinder::getTracks: tracker time out after %f\n",
206  CpuTime() - initialCpuTime ) ;
207  break ;
208  }
209  }
210 //
211  para.nHitsForSegment = nHitsSegment ;
212 //
213  return 0 ;
214 }
215 //********************************************************************
216 //
217 void FtfFinder::mergePrimaryTracks ( ) {
218 //
219 // Reset area keeping track pointers
220 //
221  memset ( trackC, 0, para.nPhiTrackPlusOne*para.nEtaTrackPlusOne*sizeof(FtfContainer) ) ;
222 //
223 // Loop over tracks
224 //
225 
226  for ( int i = 0 ; i < nTracks ; i++ ) {
227  currentTrack = &(track[i]);
228  if ( currentTrack->flag < 0 ) continue ;
229 //
230 // reset link to following track
231 //
232  currentTrack->nxatrk = 0 ;
233 //
234 // Try to merge this track
235 // if track is not merged is added
236 // to the track volume (area)
237 //
238  if ( currentTrack->mergePrimary ( trackC ) ) {
239  currentTrack->flag = -1 ;
240  }
241  }
242 }
243 //********************************************************************
244 // Resets program
245 //*********************************************************************
246 int FtfFinder::reset (void) {
247 
248  double phiDiff ;
249 
250  // Initialization flag in principle assume failure
251  para.init = 0 ;
252 
253  //-------------------------------------------------------------------
254  // Allocate volumes
255  //-------------------------------------------------------------------
256  para.nRowsPlusOne = (para.rowOuterMost-para.rowInnerMost) / para.modRow + 2;
257  if ( para.nRowsPlusOne < 1 ) {
258  ftfLog ( " =====> Error <===== \n" ) ;
259  ftfLog ( " Rows: Outer Most Inner Most %d % d \n",
260  para.rowOuterMost, para.rowInnerMost ) ;
261  return 1 ;
262  }
263  para.nPhiPlusOne = para.nPhi + 1 ;
264  para.nEtaPlusOne = para.nEta + 1 ;
265  para.nPhiEtaPlusOne = para.nPhiPlusOne * para.nEtaPlusOne ;
266  if ( para.mergePrimaries ) {
267  para.nPhiTrackPlusOne = para.nPhiTrack + 1 ;
268  para.nEtaTrackPlusOne = para.nEtaTrack + 1 ;
269  }
270 
271  //--> Allocate volume memory
272  if (volumeC != NULL) delete []volumeC;
273 #ifdef TRDEBUG
274  ftfLog ( "Allocating %d bytes of memory for volume\n",
275  para.nRowsPlusOne*
276  para.nPhiPlusOne*
277  para.nEtaPlusOne*sizeof(VOLUME));
278 #endif
279  int nVolumes = para.nRowsPlusOne*para.nPhiPlusOne *
280  para.nEtaPlusOne ;
281  volumeC = new FtfContainer[nVolumes];
282 
283  // Allocate row memory
284  if ( rowC != NULL ) delete[] rowC ;
285 #ifdef TRDEBUG
286  ftfLog ( "Allocating %d bytes of memory for rowC\n",
287  para.nRowsPlusOne*sizeof(ROW));
288 #endif
289  rowC = new FtfContainer[para.nRowsPlusOne];
290 
291  // Allocate track area memory
292  if ( para.mergePrimaries ) {
293  if (trackC != NULL) delete []trackC ;
294 #ifdef TRDEBUG
295  ftfLog (stderr, "Allocating %d bytes of memory for track_area\n",
296  para.nPhiTrackPlusOne*
297  para.nEtaTrackPlusOne*sizeof(AREA));
298 #endif
299  int nTrackVolumes = para.nPhiTrackPlusOne*
300  para.nEtaTrackPlusOne ; if(nTrackVolumes){}
301  trackC = new FtfContainer[para.nPhiTrackPlusOne*para.nEtaTrackPlusOne];
302  }
303  /*---------------------------------------------------------------------
304  Look whether the phi range is closed (< 5 degrees )
305  --------------------------------------------------------------------- */
306  phiDiff = para.phiMax - para.phiMin ;
307  if ( phiDiff > 2. * pi + 0.1 ) {
308  ftfLog ( "FtfFinder::reset: Wrong phi range %f, %f ",
309  para.phiMin*toDeg, para.phiMax*toDeg ) ;
310  return 1 ;
311  }
312  if ( fabs(phiDiff-twoPi ) < pi / 36. ) para.phiClosed = 1 ;
313  else
314  para.phiClosed = 0 ;
315  //--------------------------------------------------------------------
316  // Calculate volume dimensions
317  // -------------------------------------------------------------------
318  para.phiSlice = (para.phiMax - para.phiMin)/para.nPhi ;
319  para.etaSlice = (para.etaMax - para.etaMin)/para.nEta ;
320  // --------------------------------------------------------------------
321  // If needed calculate track area dimensions
322  // --------------------------------------------------------------------
323  para.phiSliceTrack = (para.phiMaxTrack - para.phiMinTrack)/para.nPhiTrack;
324  para.etaSliceTrack = (para.etaMaxTrack - para.etaMinTrack)/para.nEtaTrack;
325  //
326  // Set vertex parameters
327  //
328  if ( para.xVertex != 0 || para.yVertex != 0 ) {
329  para.rVertex = (double)sqrt (para.xVertex*para.xVertex +
330  para.yVertex*para.yVertex) ;
331  para.phiVertex = (double)atan2(para.yVertex,para.xVertex);
332  }
333  else {
334  para.rVertex = 0.F ;
335  para.phiVertex = 0.F ;
336  }
337 
338  if ( para.dxVertex != 0 || para.dyVertex != 0 )
339  para.xyWeightVertex = 1. / ::sqrt(para.dxVertex*para.dxVertex+
340  para.dyVertex*para.dyVertex) ;
341  else para.xyWeightVertex = 1.0F ;
342  //
343  // Set # hits & tracks to zero
344  //
345  // nHits = 0 ;
346  // nTracks = 0 ;
347  //
348  // Set initialization flag to true
349  //
350  para.init = 1 ;
351  return 0 ;
352 }
353 
354 //*********************************************************************
355 // Set hit pointers
356 //*********************************************************************
357 int FtfFinder::setConformalCoordinates ( )
358 {
359 /*-------------------------------------------------------------------------
360  Loop over hits
361 -------------------------------------------------------------------------*/
362  FtfHit* thisHit ;
363  double x, y, r2, invR2 ;
364  for ( int ihit = 0 ; ihit<nHits ; ihit++ )
365  {
366 /*-------------------------------------------------------------------------
367  Transform coordinates
368 -------------------------------------------------------------------------*/
369  thisHit = &(hit[ihit]) ;
370 
371  x = thisHit->x - para.xVertex ;
372  y = thisHit->y - para.yVertex ;
373  r2 = x * x + y * y ;
374  invR2 = 1.F / r2 ;
375 
376  thisHit->xp = x * invR2 ;
377  thisHit->yp = - y * invR2 ;
378  thisHit->wxy = r2 * r2 / ( square(para.xyErrorScale)
379  * ( square(thisHit->dx) + square(thisHit->dy) ) ) ;
380  }
381 
382  return 0 ;
383 }
384 //********************************************************************
385 // Set hit pointers
386 //********************************************************************
387 int FtfFinder::setPointers ( )
388 {
389  int ihit, localRow ;
390  register int volumeIndex;
391  double r, r2, phi, eta ;
392  FtfHit *thisHit ;
393 
394  nHitsOutOfRange = 0 ;
395 
396  // Set volumes to zero
397  memset ( rowC, 0, para.nRowsPlusOne*sizeof(FtfContainer) ) ;
398  int n = para.nRowsPlusOne*para.nEtaPlusOne*para.nPhiPlusOne ;
399  memset ( volumeC, 0, n*sizeof(FtfContainer) ) ;
400  if ( para.mergePrimaries ){
401  memset ( trackC, 0, para.nPhiTrackPlusOne*
402  para.nEtaTrackPlusOne*sizeof(FtfContainer) ) ;
403  }
404 
405 
406 
407 
408 /*-------------------------------------------------------------------------
409  Loop over hits
410 -------------------------------------------------------------------------*/
411  for ( ihit = 0 ; ihit<nHits ; ihit++ )
412  {
413 /*-------------------------------------------------------------------------
414  Check whether row is to be considered
415 -------------------------------------------------------------------------*/
416  thisHit = &(hit[ihit]) ;
417  localRow = thisHit->row - para.rowInnerMost ;
418  if ( fmod((double)localRow,(double)para.modRow) != 0 ) continue ;
419 
420  if ( thisHit->row < para.rowInnerMost ) continue ;
421  if ( thisHit->row > para.rowOuterMost ) continue ;
422 /*
423  *-> Get "renormalized" index
424  */
425  localRow = localRow / para.modRow + 1 ;
426 
427 /*-------------------------------------------------------------------------
428  Transform coordinates
429 -------------------------------------------------------------------------*/
430  if (0) // compile time switch
431  {
432  cout << "SECTOR" << "," << thisHit->row << ","
433  << (thisHit->buffer1>>6) << "," << (thisHit->buffer2>>6) << " --> "
434  << "( " << thisHit->x << "/ " << thisHit->y << "/ "
435  << thisHit->z << " )" << endl;
436  }
437 
438 
439  r2 = thisHit->x * thisHit->x + thisHit->y * thisHit->y ;
440  r = (double)sqrt ( r2 ) ;
441  phi = (double)atan2(thisHit->y,thisHit->x) + para.phiShift ;
442  if ( phi < 0 ) phi = phi + twoPi ;
443  // ftfLog("r: %f, z: %f\n",r, thisHit->z);
444  eta = (double)seta(r,thisHit->z) ;
445 
446  if ( para.szFitFlag ) {
447  thisHit->s = 0.F ;
448  thisHit->wz = (double)(1./ square ( para.szErrorScale * thisHit->dz ));
449  }
450 
451  thisHit->r = r ;
452  thisHit->phi = phi ;
453  thisHit->eta = eta ;
454 /*-------------------------------------------------------------------------
455  Set pointers
456 -------------------------------------------------------------------------*/
457  thisHit->nextVolumeHit =
458  thisHit->nextRowHit = 0 ;
459 /*-------------------------------------------------------------------------
460  Get phi index for hit
461 -------------------------------------------------------------------------*/
462 
463  thisHit->phiIndex = (int)( (thisHit->phi-para.phiMin)/para.phiSlice + 1.);
464  if ( thisHit->phiIndex < 1 || thisHit->phiIndex > para.nPhi ) {
465  if ( para.infoLevel > 2 ) {
466  ftfLog ( " === > Hit %d has Phi = %f \n", (int)thisHit->id,
467  thisHit->phi*toDeg ) ;
468  ftfLog ( " Phi index %d out of range \n", thisHit->phiIndex ) ;
469  }
470  nHitsOutOfRange++ ;
471  continue ;
472  }
473 
474 /*-------------------------------------------------------------------------
475  Get eta index for hit
476 -------------------------------------------------------------------------*/
477 
478  thisHit->etaIndex = (int)((thisHit->eta - para.etaMin)/para.etaSlice + 1.);
479  if ( thisHit->etaIndex < 1 || thisHit->etaIndex > para.nEta ) {
480  if ( para.infoLevel > 2 ) {
481  ftfLog(" \n === > Hit %d has Eta = %f z %f ",
482  (int)thisHit->id, thisHit->eta, thisHit->z ) ;
483  ftfLog ( " \n Eta min/max %f %f ", para.etaMin, para.etaMax ) ;
484  ftfLog ( " \n Eta slice %f ", para.etaSlice ) ;
485  ftfLog ( " \n Eta index %d out of range ", thisHit->etaIndex ) ;
486  }
487  nHitsOutOfRange++ ;
488  continue ;
489  }
490 //
491 // Reset track assigment
492 //
493  thisHit->nextTrackHit = 0 ;
494  thisHit->track = 0 ;
495 /* -------------------------------------------------------------------------
496  Increase nr. of hits in small volume WARNING! C-arrays go from 0
497  Set Id of first hit in this vol. and link to next hit in previous
498  hit in the same volume
499 -------------------------------------------------------------------------*/
500  volumeIndex = localRow * para.nPhiEtaPlusOne +
501  thisHit->phiIndex * para.nEtaPlusOne + thisHit->etaIndex ;
502 
503 
504  if (volumeC[volumeIndex].first == 0 )
505  volumeC[volumeIndex].first = (void *)thisHit ;
506  else
507  ((FtfHit *)(volumeC[volumeIndex].last))->nextVolumeHit = thisHit ;
508  volumeC[volumeIndex].last = (void *)thisHit ;
509 
510 /*-------------------------------------------------------------------------
511  Set row pointers
512 -------------------------------------------------------------------------*/
513 
514  if ( rowC[localRow].first == NULL ){
515  rowC [localRow].first = (void *)thisHit ;
516  }
517  else
518  ((FtfHit *)(rowC[localRow].last))->nextRowHit = thisHit ;
519  rowC[localRow].last = (void *)thisHit ;
520  }
521  return 0 ;
522 }
523 //***********************************************************************
524 // For timing
525 //***********************************************************************
526 #include <stdio.h>
527 #include <stdlib.h>
528 #include <time.h>
529 
530 double FtfFinder::CpuTime( void ) {
531  return (double)(clock()) / CLOCKS_PER_SEC;
532 }
533 
534 //
535 #ifdef __i386__
536 double FtfFinder::RealTime (void) {
537  const long nClicks = 400000000 ;
538  unsigned long eax, edx;
539  asm volatile("rdtsc":"=a" (eax), "=d" (edx));
540  double realTime = (double)(eax)/ nClicks;
541  return realTime;
542 }
543 #else
544 double FtfFinder::RealTime (void) {
545  return 1. ;
546 }
547 #endif
Definition: FtfHit.h:16