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