]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCConfMapper.cxx
736e0405c9509bfe3cb4c699bd455c51f1dbf1a0
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCConfMapper.cxx
1 // @(#) $Id$
2 // Original: AliL3ConfMapper.cxx,v 1.26 2005/06/14 10:55:21 cvetan Exp $
3
4 /** \class AliHLTTPCConfMapper
5 <pre>
6 //_____________________________________________________________
7 // AliHLTTPCConfMapper
8 //
9 // Conformal mapping base class
10 //
11 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
12 // Copyright &copy ALICE HLT Group
13 </pre>
14 */
15
16 #include <sys/time.h>
17  
18 #include "AliHLTTPCRootTypes.h"
19 #include "AliHLTTPCSpacePointData.h"
20 #include "AliHLTTPCLogging.h" 
21 #include "AliHLTTPCVertex.h"
22 #include "AliHLTTPCConfMapTrack.h"
23 #include "AliHLTTPCConfMapPoint.h"
24 #include "AliHLTTPCTrackArray.h"
25 #include "AliHLTTPCTransform.h"
26 #include "AliHLTTPCConfMapper.h"
27
28 #if __GNUC__ >= 3
29 using namespace std;
30 #endif
31
32 ClassImp(AliHLTTPCConfMapper)
33
34 AliHLTTPCConfMapper::AliHLTTPCConfMapper()
35 {
36   //Default constructor
37   fVertex = NULL;
38   fTrack = NULL;
39   fHit = NULL;
40   fVolume = NULL;
41   fRow = NULL;
42   fBench = (Bool_t)true;
43   fVertexConstraint = (Bool_t)true;
44   fParamSet[0]=0;
45   fParamSet[1]=0;
46 }
47
48
49 AliHLTTPCConfMapper::~AliHLTTPCConfMapper()
50 {
51   // Destructor.
52   if(fVolume) {
53     delete [] fVolume;
54   }
55   if(fRow) {
56     delete [] fRow;
57   }
58   if(fHit) {
59     delete [] fHit;
60   }
61   if(fTrack) {
62     delete fTrack;
63   }
64 }
65  
66 void AliHLTTPCConfMapper::InitVolumes()
67 {
68   //Data organization.
69   //Allocate volumes, set conformal coordinates and pointers.
70   
71   //Should be done after setting the track parameters
72   
73   fNumRowSegmentPlusOne = AliHLTTPCTransform::GetNRows();//NumRows[0]; //Maximum 32.
74   fNumPhiSegmentPlusOne = fNumPhiSegment+1;
75   fNumEtaSegmentPlusOne = fNumEtaSegment+1;
76   fNumPhiEtaSegmentPlusOne = fNumPhiSegmentPlusOne*fNumEtaSegmentPlusOne;
77   fBounds = fNumRowSegmentPlusOne * fNumPhiSegmentPlusOne * fNumEtaSegmentPlusOne;
78   
79   //Allocate volumes:
80   if(fVolume) delete [] fVolume;
81   if(fRow) delete [] fRow;
82   
83   LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::InitVolumes","Memory")<<AliHLTTPCLog::kDec<<
84     "Allocating "<<fBounds*sizeof(AliHLTTPCConfMapContainer)<<" Bytes to fVolume"<<ENDLOG;
85   LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::InitVolumes","Memory")<<AliHLTTPCLog::kDec<<
86     "Allocating "<<fNumRowSegmentPlusOne*sizeof(AliHLTTPCConfMapContainer)<<" Bytes to fRow"<<ENDLOG;
87   
88   fVolume = new AliHLTTPCConfMapContainer[fBounds];
89   fRow = new AliHLTTPCConfMapContainer[fNumRowSegmentPlusOne];
90   
91   memset(fVolume,0,fBounds*sizeof(AliHLTTPCConfMapContainer));
92   memset(fRow,0,fNumRowSegmentPlusOne*sizeof(AliHLTTPCConfMapContainer));
93   
94   Int_t maxnumoftracks = 2000;
95   Int_t maxnumofhits = 120000;
96   
97   if(fHit)
98     delete [] fHit;
99   if(fTrack)
100     delete fTrack;
101     
102   fHit = new AliHLTTPCConfMapPoint[maxnumofhits];
103   fTrack = new AliHLTTPCTrackArray("AliHLTTPCConfMapTrack",maxnumoftracks);
104 }
105
106 void AliHLTTPCConfMapper::InitSector(Int_t sector,Int_t *rowrange,Float_t *etarange)
107 { //sector means slice here
108   //Initialize tracker for tracking in a given sector.
109   //Resets track and hit arrays.
110   //Here it is also possible to specify a subsector, by defining
111   //rowrange[0]=innermost row;
112   //rowrange[1]=outermostrow;
113   //Finally you can specify etaslices to save time (assuming a good seed from TRD...)
114     
115   //Define tracking area:
116   if(rowrange)
117     {
118       fRowMin = rowrange[0];
119       fRowMax = rowrange[1];
120     }
121   else //complete sector
122     {
123       fRowMin = 0;
124       fRowMax = AliHLTTPCTransform::GetNRows() - 1;
125     }
126   if(etarange)
127     {
128       fEtaMin = etarange[0];
129       fEtaMax = sector < 18 ? etarange[1] : -etarange[1];
130     }
131   else
132     {
133       fEtaMin = 0;
134       fEtaMax = sector < 18 ? 0.9 : -0.9;
135     }
136   
137   //Set the angles to sector 2:
138   fPhiMin = -10*AliHLTTPCTransform::ToRad();//fParam->GetAngle(sector) - 10/todeg;
139   fPhiMax =  10*AliHLTTPCTransform::ToRad();//fParam->GetAngle(sector) + 10/todeg;
140
141   fNTracks=0;
142   fMainVertexTracks = 0;
143   fClustersUnused = 0;
144   fEtaHitsOutOfRange=0;
145   fPhiHitsOutOfRange=0;
146   
147   fNumRowSegment = fRowMax - fRowMin; //number of rows to be considered by tracker
148   LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::InitSector","B-field")
149     <<"Tracker initializing with a magnetic field of "<<AliHLTTPCTransform::GetBField()<<ENDLOG;
150   
151   fTrack->Reset();
152 }
153
154 Bool_t AliHLTTPCConfMapper::ReadHits(UInt_t count, AliHLTTPCSpacePointData* hits )
155 {
156   //read hits
157   Int_t nhit=(Int_t)count; 
158   for (Int_t i=0;i<nhit;i++)
159     {   
160       fHit[i+fClustersUnused].Reset();
161       fHit[i+fClustersUnused].ReadHits(&(hits[i]));
162     }
163   fClustersUnused += nhit;
164
165   LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::ReadHits","#hits")
166     <<AliHLTTPCLog::kDec<<"hit_counter: "<<nhit<<" count: "<<count<<ENDLOG;
167   
168   return true;
169 }
170
171 void AliHLTTPCConfMapper::SetPointers()
172 {
173   //Check if there are not enough clusters to make a track in this sector
174   //Can happen in pp events.
175
176   if(fClustersUnused < fMinPoints[fVertexConstraint])
177     return;
178   
179   //Reset detector volumes
180   memset(fVolume,0,fBounds*sizeof(AliHLTTPCConfMapContainer));
181   memset(fRow,0,fNumRowSegmentPlusOne*sizeof(AliHLTTPCConfMapContainer));
182   
183   Float_t phiSlice = (fPhiMax-fPhiMin)/fNumPhiSegment;
184   Float_t etaSlice = (fEtaMax-fEtaMin)/fNumEtaSegment;
185
186   Int_t volumeIndex;
187   Int_t localcounter=0;
188   for(Int_t j=0; j<fClustersUnused; j++)
189     {
190       //AliHLTTPCConfMapPoint *thisHit = (AliHLTTPCConfMapPoint*)fHit->At(j);
191       AliHLTTPCConfMapPoint *thisHit = &(fHit[j]);
192
193       thisHit->Setup(fVertex);
194       
195       Int_t localrow = thisHit->GetPadRow();
196       
197       if(localrow < fRowMin || localrow > fRowMax)
198         continue;
199
200       //Get indexes:
201       thisHit->SetPhiIndex((Int_t)((thisHit->GetPhi()-fPhiMin)/phiSlice +1));
202       
203       if(thisHit->GetPhiIndex()<1 || thisHit->GetPhiIndex()>fNumPhiSegment)
204         {
205           //cout << "Phiindex: " << thisHit->phiIndex << " " << thisHit->GetPhi() << endl;
206           fPhiHitsOutOfRange++;
207           continue;
208         }
209       
210       thisHit->SetEtaIndex((Int_t)((thisHit->GetEta()-fEtaMin)/etaSlice + 1));
211       if(thisHit->GetEtaIndex()<1 || thisHit->GetEtaIndex()>fNumEtaSegment)
212         {
213           //cout << "Etaindex: " << thisHit->etaIndex << " " << thisHit->GetEta() << endl;
214           fEtaHitsOutOfRange++;
215           continue;
216         }
217       localcounter++;
218       
219       volumeIndex = (localrow-fRowMin)*fNumPhiEtaSegmentPlusOne + 
220                     thisHit->GetPhiIndex()*fNumEtaSegmentPlusOne+thisHit->GetEtaIndex();
221       
222       if(fVolume[volumeIndex].first == NULL)
223         fVolume[volumeIndex].first = (void *)thisHit;
224       else
225         ((AliHLTTPCConfMapPoint *)fVolume[volumeIndex].last)->SetNextVolumeHit(thisHit);
226       fVolume[volumeIndex].last = (void *)thisHit;
227       
228       
229       //set row pointers
230       if(fRow[(localrow-fRowMin)].first == NULL)
231         fRow[(localrow-fRowMin)].first = (void *)thisHit;
232       else
233         ((AliHLTTPCConfMapPoint *)(fRow[(localrow-fRowMin)].last))->SetNextRowHit(thisHit);
234         fRow[(localrow-fRowMin)].last = (void *)thisHit;
235     }
236   
237   if(fClustersUnused>0 && localcounter==0)
238     LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::SetPointers","Parameters")
239       <<AliHLTTPCLog::kDec<<"No points passed to track finder, hits out of range: "
240       <<fEtaHitsOutOfRange+fPhiHitsOutOfRange<<ENDLOG;
241
242   Int_t hits_accepted=fClustersUnused-(fEtaHitsOutOfRange+fPhiHitsOutOfRange);
243   LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::SetPointers","Setup")
244     <<"Setup finished, hits out of range: "<<fEtaHitsOutOfRange+fPhiHitsOutOfRange
245     <<" hits accepted "<<hits_accepted<<ENDLOG;
246 }
247
248 void AliHLTTPCConfMapper::MainVertexTracking_a()
249 {
250   //Tracking with vertex constraint.
251
252   if(!fParamSet[(Int_t)kTRUE])
253     {
254       LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::MainVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
255         "Tracking parameters not set!"<<ENDLOG;
256       return;
257     }
258
259   Double_t initCpuTime,cpuTime;
260   initCpuTime = CpuTime();
261
262   SetPointers();
263   SetVertexConstraint(true);
264   cpuTime = CpuTime() - initCpuTime;
265   if(fBench)
266     LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::MainVertexTracking_a","Timing")
267       <<AliHLTTPCLog::kDec<<"Setup finished in "<<cpuTime*1000<<" ms"<<ENDLOG;
268   
269 }
270
271 void AliHLTTPCConfMapper::MainVertexTracking_b()
272 {
273   //Tracking with vertex constraint.
274
275   if(!fParamSet[(Int_t)kTRUE])
276     {
277       LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::MainVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
278         "Tracking parameters not set!"<<ENDLOG;
279       return;
280     }
281   Double_t initCpuTime,cpuTime;
282   initCpuTime = CpuTime();
283   
284   ClusterLoop();
285  
286   cpuTime = CpuTime() - initCpuTime;
287   if(fBench)
288     LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::MainVertexTracking_b","Timing")
289       <<AliHLTTPCLog::kDec<<"Main Tracking finished in "<<cpuTime*1000<<" ms"<<ENDLOG;
290 }
291
292 void AliHLTTPCConfMapper::MainVertexTracking()
293 {
294   //Tracking with vertex constraint.
295
296   if(!fParamSet[(Int_t)kTRUE])
297     {
298       LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::MainVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
299         "Tracking parameters not set!"<<ENDLOG;
300       return;
301     }
302
303   Double_t initCpuTime,cpuTime;
304   initCpuTime = CpuTime();
305 // END ################################################# MODIFIY JMT
306 #if 0
307   SetPointers(); // moved to Component
308 #endif
309 // END ################################################# MODIFIY JMT
310   SetVertexConstraint(true);
311       
312   ClusterLoop();
313
314   cpuTime = CpuTime() - initCpuTime;
315   if(fBench)
316     LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::MainVertexTracking","Timing")<<AliHLTTPCLog::kDec<<
317       "Tracking finished in "<<cpuTime*1000<<" ms"<<ENDLOG;
318   
319   return;
320 }
321
322 void AliHLTTPCConfMapper::NonVertexTracking()
323 {
324   //Tracking with no vertex constraint. This should be called after doing MainVertexTracking,
325   //in order to do tracking on the remaining clusters.
326   //The conformal mapping is now done with respect to the first cluster
327   //assosciated with this track.
328   
329   if(!fParamSet[(Int_t)kFALSE])
330     {
331       LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::NonVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
332         "Tracking parameters not set!"<<ENDLOG;
333       return;
334     }
335   
336   SetVertexConstraint(false);
337   ClusterLoop();
338   LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::NonVertexTracking","ntracks")<<AliHLTTPCLog::kDec<<
339     "Number of nonvertex tracks found: "<<(fNTracks-fMainVertexTracks)<<ENDLOG;
340   return;
341 }
342
343 void AliHLTTPCConfMapper::MainVertexSettings(Int_t trackletlength, Int_t tracklength,
344                                          Int_t rowscopetracklet, Int_t rowscopetrack,
345                                          Double_t maxphi,Double_t maxeta)
346 {
347   //Settings for main vertex tracking. The cuts are:
348   //TrackletLength:      #hits on segment, before trying to build a track
349   //TrackLength:         Minimum hits on a track
350   //RowScopeTracklet:    Row search range for segments
351   //RowScopeTrack:       Row search range for tracks
352   
353   SetTrackletLength(trackletlength,(Bool_t)true);
354   SetRowScopeTracklet(rowscopetracklet, (Bool_t) true);
355   SetRowScopeTrack(rowscopetrack, (Bool_t) true);
356   SetMinPoints(tracklength,(Bool_t)true);
357   fMaxPhi=maxphi;
358   fMaxEta=maxeta;
359   SetParamDone(kTRUE);
360 }
361
362 void AliHLTTPCConfMapper::NonVertexSettings(Int_t trackletlength, Int_t tracklength,
363                                         Int_t rowscopetracklet, Int_t rowscopetrack)
364 {
365   //set parameters for non-vertex tracking
366   SetTrackletLength(trackletlength,(Bool_t)false);
367   SetRowScopeTracklet(rowscopetracklet, (Bool_t)false);
368   SetRowScopeTrack(rowscopetrack, (Bool_t)false);
369   SetMinPoints(tracklength,(Bool_t)false);
370   SetParamDone(kFALSE);
371 }
372
373 void AliHLTTPCConfMapper::SetTrackCuts(Double_t hitChi2Cut, Double_t goodHitChi2, Double_t trackChi2Cut,Int_t maxdist,Bool_t vertexconstraint)
374 {
375   //Settings for tracks. The cuts are:
376   //HitChi2Cut:     Maximum hit chi2
377   //goodHitChi2:    Chi2 to stop look for next hit
378   //trackChi2Cut:   Maximum track chi2
379   //maxdist:        Maximum distance between two clusters when forming segments
380   
381   SetHitChi2Cut(hitChi2Cut,vertexconstraint);
382   SetGoodHitChi2(goodHitChi2,vertexconstraint);
383   SetTrackChi2Cut(trackChi2Cut,vertexconstraint);
384   SetMaxDist(maxdist,vertexconstraint);
385 }
386
387 void AliHLTTPCConfMapper::SetTrackletCuts(Double_t maxangle,Double_t goodDist, Bool_t vc)
388 {
389   //Sets cuts of tracklets. Right now this is only:
390   //maxangle:  Maximum angle when forming segments (if trackletlength > 2)
391  
392   fGoodDist=goodDist;
393   SetMaxAngleTracklet(maxangle, vc);
394 }
395
396 void AliHLTTPCConfMapper::ClusterLoop()
397 {
398   //Loop over hits, starting at outermost padrow, and trying to build segments.
399   
400   //Check if there are not enough clusters to make a track in this sector
401   //Can happen in pp events.
402   if(fClustersUnused < fMinPoints[fVertexConstraint])
403     return;
404   
405   Int_t rowsegm,lastrow = fRowMin + fMinPoints[fVertexConstraint];
406   AliHLTTPCConfMapPoint *hit;
407   
408   //Loop over rows, and try to create tracks from the hits.
409   //Starts at the outermost row, and loops as long as a track can be build, due to length.
410   
411   for(rowsegm = fRowMax; rowsegm >= lastrow; rowsegm--)
412     {
413       if(fRow[(rowsegm-fRowMin)].first && ((AliHLTTPCConfMapPoint*)fRow[(rowsegm-fRowMin)].first)->GetPadRow() < fRowMin + 1)
414         break;
415
416       for(hit = (AliHLTTPCConfMapPoint*)fRow[(rowsegm-fRowMin)].first; hit!=0; hit=hit->GetNextRowHit())
417         {
418           if(hit->GetUsage() == true)
419             continue;
420           else
421             CreateTrack(hit);
422         }
423     }
424   
425   return;
426 }
427
428
429 void AliHLTTPCConfMapper::CreateTrack(AliHLTTPCConfMapPoint *hit)
430 {
431   //Tries to create a track from the initial hit given by ClusterLoop()
432
433   AliHLTTPCConfMapPoint *closesthit = NULL;
434   AliHLTTPCConfMapTrack *track = NULL;
435   
436   Int_t point;
437   Int_t tracks = fNTracks;
438   fNTracks++;
439
440   track = (AliHLTTPCConfMapTrack*)fTrack->NextTrack();
441
442   //reset hit parameters:
443   track->Reset();
444   
445   UInt_t *trackhitnumber = track->GetHitNumbers();
446     
447   //set conformal coordinates if we are looking for non vertex tracks
448   if(!fVertexConstraint) 
449     {
450       hit->SetAllCoord(hit);
451     }
452   
453   //fill fit parameters of initial track:
454   track->UpdateParam(hit); //here the number of hits is incremented.
455   trackhitnumber[track->GetNumberOfPoints()-1] = hit->GetHitNumber();
456   
457   Double_t dx,dy;
458   //create tracklets:
459   
460   for(point=1; point<fTrackletLength[fVertexConstraint]; point++)
461     {
462       if((closesthit = GetNextNeighbor(hit)))
463         {//closest hit exist
464           
465           //   Calculate track length in sz plane
466           dx = ((AliHLTTPCConfMapPoint*)closesthit)->GetX() - ((AliHLTTPCConfMapPoint*)hit)->GetX();
467           dy = ((AliHLTTPCConfMapPoint*)closesthit)->GetY() - ((AliHLTTPCConfMapPoint*)hit)->GetY();
468           //track->fLength += (Double_t)sqrt ( dx * dx + dy * dy ) ;
469           Double_t length = track->GetLength()+(Double_t)sqrt ( dx * dx + dy * dy );
470           track->SetLength(length);
471
472           //closesthit->SetS(track->fLength);
473           closesthit->SetS(track->GetLength());
474
475           //update fit parameters
476           track->UpdateParam(closesthit);
477           trackhitnumber[track->GetNumberOfPoints()-1] = closesthit->GetHitNumber();
478         
479           hit = closesthit;
480         }
481       else
482         {
483           //closest hit does not exist:
484           track->DeleteCandidate();
485           fTrack->RemoveLast();
486           fNTracks--;
487           point = fTrackletLength[fVertexConstraint];
488         }
489     }
490   
491   //tracklet is long enough to be extended to a track
492   if(track->GetNumberOfPoints() == fTrackletLength[fVertexConstraint])
493     {
494       
495       track->SetProperties(true);
496             
497       if(TrackletAngle(track) > fMaxAngleTracklet[fVertexConstraint])
498         {//proof if the first points seem to be a beginning of a track
499           track->SetProperties(false);
500           track->DeleteCandidate();
501           fTrack->RemoveLast();
502           fNTracks--;
503         }
504       
505       else//good tracklet ->proceed, follow the trackfit
506         {
507           tracks++;
508                                   
509           //define variables to keep the total chi:
510           Double_t xyChi2 = track->GetChiSq1();
511           Double_t szChi2 = track->GetChiSq2();
512           
513           for(point = fTrackletLength[fVertexConstraint]; point <= fNumRowSegment; point++)
514             {
515               track->SetChiSq1(fHitChi2Cut[fVertexConstraint]);
516               closesthit = GetNextNeighbor((AliHLTTPCConfMapPoint*)track->GetLastHit(),track);
517               
518               if(closesthit)
519                 {
520                   //keep total chi:
521                   Double_t lxyChi2 = track->GetChiSq1()-track->GetChiSq2();
522                   xyChi2 += lxyChi2;
523                   closesthit->SetXYChi2(lxyChi2);
524                                   
525                   //update track length:
526                   track->SetLength(closesthit->GetS());
527                   szChi2 += track->GetChiSq2();
528                   closesthit->SetSZChi2(track->GetChiSq2());
529                   
530                   track->UpdateParam(closesthit);
531                   trackhitnumber[track->GetNumberOfPoints()-1] = closesthit->GetHitNumber();
532                   
533                   //add closest hit to track
534                   closesthit->SetUsage(true);
535                   closesthit->SetTrackNumber(tracks-1);
536                   
537                 }//closesthit
538               
539               else
540                 {
541                   //closest hit does not exist
542                   point = fNumRowSegment; //continue with next hit in segment
543                 }//else
544               
545             }//create tracks
546           
547           //store track chi2:
548           track->SetChiSq1(xyChi2);
549           track->SetChiSq2(szChi2);
550           Double_t normalizedchi2 = (track->GetChiSq1()+track->GetChiSq2())/track->GetNumberOfPoints();
551           
552           //remove tracks with not enough points already now
553           if(track->GetNumberOfPoints() < fMinPoints[fVertexConstraint] || normalizedchi2 > fTrackChi2Cut[fVertexConstraint])
554             {
555               track->SetProperties(false);
556               fNTracks--;
557               track->DeleteCandidate();
558               fTrack->RemoveLast();
559               tracks--;
560             }
561           
562           else
563             {
564               fClustersUnused -= track->GetNumberOfPoints();
565               track->ComesFromMainVertex(fVertexConstraint);
566               //mark track as main vertex track or not
567               track->SetSector(2); //only needed for testing purposes.
568               track->SetRowRange(fRowMin,fRowMax);
569
570               if(fVertexConstraint) 
571                 fMainVertexTracks++;
572             }
573      
574         }//good tracklet
575       
576     }
577   
578   return;
579 }
580
581 AliHLTTPCConfMapPoint *AliHLTTPCConfMapper::GetNextNeighbor(AliHLTTPCConfMapPoint *starthit,
582                                           AliHLTTPCConfMapTrack *track)
583 {
584   //When forming segments: Finds closest hit to input hit
585   //When forming tracks: Find closest hit to track fit.
586   
587   Double_t dist,closestdist = fMaxDist[fVertexConstraint];
588   
589   AliHLTTPCConfMapPoint *hit = NULL;
590   AliHLTTPCConfMapPoint *closesthit = NULL;
591     
592   Int_t subrowsegm;
593   Int_t subphisegm;
594   Int_t subetasegm;
595   Int_t volumeIndex;
596   Int_t testhit;
597
598   Int_t maxrow = starthit->GetPadRow()-1;
599   Int_t minrow;
600
601   if(track) //finding hit close to trackfit
602     {
603       minrow = starthit->GetPadRow()-fRowScopeTrack[fVertexConstraint];
604     }
605   else
606     {
607       minrow = starthit->GetPadRow()-fRowScopeTracklet[fVertexConstraint];
608     }
609
610   //make a smart loop
611   Int_t loopeta[25] = {0,0,0,-1,-1,-1,1,1,1, 0,0,-1,-1,1,1,-2,-2,-2,-2,-2,2,2,2,2,2};
612   Int_t loopphi[25] = {0,-1,1,0,-1,1,0,-1,1, -2,2,-2,2,-2,2,-2,-1,0,1,2,-2,-1,0,1,2};
613   
614   if(minrow < fRowMin)
615     minrow = fRowMin;
616   if(maxrow < fRowMin)
617     return 0;  //reached the last padrow under consideration
618
619   else
620     {
621       //loop over sub rows
622       for(subrowsegm=maxrow; subrowsegm>=minrow; subrowsegm--)
623         {
624           //loop over subsegments, in the order defined above.
625           for(Int_t i=0; i<9; i++)  
626             {
627               subphisegm = starthit->GetPhiIndex() + loopphi[i];
628               
629               if(subphisegm < 0 || subphisegm >= fNumPhiSegment)
630                 continue;
631               /*
632                 if(subphisegm<0)
633                 subphisegm += fNumPhiSegment;
634                 
635                 else if(subphisegm >=fNumPhiSegment)
636                 subphisegm -= fNumPhiSegment;
637               */
638               //loop over sub eta segments
639               
640               subetasegm = starthit->GetEtaIndex() + loopeta[i];
641               
642               if(subetasegm < 0 || subetasegm >=fNumEtaSegment)
643                 continue;//segment exceeds bounds->skip it
644               
645               //loop over hits in this sub segment:
646               volumeIndex=(subrowsegm-fRowMin)*fNumPhiEtaSegmentPlusOne +
647                 subphisegm*fNumEtaSegmentPlusOne + subetasegm;
648               
649               if(volumeIndex<0)
650                 {//debugging
651                   LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::GetNextNeighbor","Memory")<<AliHLTTPCLog::kDec<<
652                     "VolumeIndex error "<<volumeIndex<<ENDLOG;
653                 }
654               
655               for(hit = (AliHLTTPCConfMapPoint*)fVolume[volumeIndex].first;
656                   hit!=0; hit = hit->GetNextVolumeHit())
657                 {
658                   
659                   if(!hit->GetUsage())
660                     {//hit was not used before
661                       
662                       //set conformal mapping if looking for nonvertex tracks:
663                       if(!fVertexConstraint)
664                         {
665                           hit->SetAllCoord(starthit);
666                         }
667                      
668                       if(track)//track search - look for nearest neighbor to extrapolated track
669                         {
670 // BEGINN ############################################## MODIFIY JMT
671 #if 1
672                             if (fVertexConstraint) {   
673                                 if(!VerifyRange(starthit,hit))
674                                     continue;
675                             }
676 #else
677                           if(!VerifyRange(starthit,hit))
678                             continue;
679 #endif
680 // END ################################################# MODIFIY JMT                      
681                           testhit = EvaluateHit(starthit,hit,track);
682                           
683                           if(testhit == 0)//chi2 not good enough, keep looking
684                             continue;
685                           else if(testhit==2)//chi2 good enough, return it
686                             return hit;
687                           else
688                             closesthit = hit;//chi2 acceptable, but keep looking
689                           
690                         }//track search
691                       
692                       else //tracklet search, look for nearest neighbor
693                         {
694                           
695                           if((dist=CalcDistance(starthit,hit)) < closestdist)
696                             {
697 // BEGINN ############################################## MODIFIY JMT
698 #if 1
699                             if (fVertexConstraint) {   
700                                 if(!VerifyRange(starthit,hit))
701                                     continue;
702                             }
703 #else
704                           if(!VerifyRange(starthit,hit))
705                             continue;
706 #endif
707 // END ################################################# MODIFIY JMT    
708                               closestdist = dist;
709                               closesthit = hit;
710                          
711                               //if this hit is good enough, return it:
712                               if(closestdist < fGoodDist)
713                                 return closesthit;
714                             }
715                           else
716                             continue;//sub hit was farther away than a hit before
717                           
718                         }//tracklet search
719                       
720                     }//hit not used before
721                   
722                   else continue; //sub hit was used before
723                   
724                 }//loop over hits in sub segment
725                       
726             }//loop over sub segments
727                   
728         }//loop over subrows
729       
730     }//else
731
732   //closest hit found:
733   if(closesthit)// && closestdist < mMaxDist)
734     return closesthit;
735   else
736     return 0;
737 }
738
739 Int_t AliHLTTPCConfMapper::EvaluateHit(AliHLTTPCConfMapPoint *starthit,AliHLTTPCConfMapPoint *hit,AliHLTTPCConfMapTrack *track) 
740 {
741   //Check if space point gives a fit with acceptable chi2.
742   
743   Double_t temp,dxy,lchi2,dx,dy,slocal,dsz,lszChi2;
744   temp = (track->GetA2Xy()*hit->GetXprime()-hit->GetYprime()+track->GetA1Xy());
745   dxy = temp*temp/(track->GetA2Xy()*track->GetA2Xy() + 1.);
746   
747   //Calculate chi2
748   lchi2 = (dxy*hit->GetXYWeight());
749   
750   if(lchi2 > track->GetChiSq1())//chi2 was worse than before.
751     return 0;
752     
753   //calculate s and the distance hit-line
754   dx = starthit->GetX()-hit->GetX();
755   dy = starthit->GetY()-hit->GetY();
756   //slocal = track->fLength+sqrt(dx*dx+dy*dy);
757   slocal = track->GetLength()+sqrt(dx*dx+dy*dy);
758   
759   temp = (track->GetA2Sz()*slocal-hit->GetZ()+track->GetA1Sz());
760   dsz = temp*temp/(track->GetA2Sz()*track->GetA2Sz()+1);
761   
762   //calculate chi2
763   lszChi2 = dsz*hit->GetZWeight();
764   lchi2 += lszChi2;
765   
766     
767   //check whether chi2 is better than previous one:
768   if(lchi2 < track->GetChiSq1())
769     {
770       track->SetChiSq1(lchi2);
771       track->SetChiSq2(lszChi2);
772     
773       hit->SetS(slocal);
774   
775       //if chi2 good enough, stop here:
776       if(lchi2 < fGoodHitChi2[fVertexConstraint]) 
777         return 2;
778       
779       return 1;
780     }
781   
782   return 0;
783   
784 }
785
786 Double_t AliHLTTPCConfMapper::CalcDistance(const AliHLTTPCConfMapPoint *hit1,const AliHLTTPCConfMapPoint *hit2) const
787 {
788   //Return distance between two clusters, defined by Pablo
789   
790   Double_t phidiff = fabs( hit1->GetPhi() - hit2->GetPhi() );
791   if (phidiff > AliHLTTPCTransform::Pi()) phidiff = AliHLTTPCTransform::TwoPi() - phidiff;
792   
793   return AliHLTTPCTransform::ToDeg()*fabs((Float_t)((hit1->GetPadRow() - hit2->GetPadRow()) * 
794          (phidiff + fabs( hit1->GetEta() - hit2->GetEta()))));
795 }
796
797 Bool_t AliHLTTPCConfMapper::VerifyRange(const AliHLTTPCConfMapPoint *hit1,const AliHLTTPCConfMapPoint *hit2) const
798 {
799   //Check if the hit are within reasonable range in phi and eta
800   Double_t dphi,deta;//maxphi=0.1,maxeta=0.1;
801   dphi = fabs(hit1->GetPhi() - hit2->GetPhi());
802   if(dphi > AliHLTTPCTransform::Pi()) dphi = fabs(AliHLTTPCTransform::TwoPi() - dphi);
803   if(dphi > fMaxPhi) return false;
804   
805   deta = fabs(hit1->GetEta() - hit2->GetEta());
806   if(deta > fMaxEta) return false;
807
808   return true;
809
810 }
811
812 Double_t AliHLTTPCConfMapper::TrackletAngle(AliHLTTPCConfMapTrack *track,Int_t n) const
813 {
814   // Returns the angle 'between' the last three points (started at point number n) on this track.
815   
816   if(n > track->GetNumberOfPoints())
817     n = track->GetNumberOfPoints();
818   
819   if(n<3)
820     return 0;
821   
822   Double_t x1[2];
823   Double_t x2[2];
824   Double_t x3[2];
825   Double_t angle1,angle2;
826   Int_t counter=0;
827   for(track->StartLoop(); track->LoopDone(); track->GetNextHit())
828     {
829       AliHLTTPCConfMapPoint *p = (AliHLTTPCConfMapPoint*)track->GetCurrentHit();
830       if( (n-1) == counter)
831         {
832           x1[0] = p->GetX();
833           x1[1] = p->GetY();
834         }
835       else if( (n-2) == counter)
836         {
837           x2[0] = p->GetX();
838           x2[1] = p->GetY();
839         }
840       else if( (n-3) == counter)
841         {
842           x3[0] = p->GetX();
843           x3[1] = p->GetY();
844         }
845       counter++;
846     }
847   
848   angle1 = atan2(x2[1]-x3[1],x2[0]-x3[0]);
849   angle2 = atan2(x1[1]-x2[1],x1[0]-x2[0]);
850   
851   return fabs(angle1-angle2);
852   
853   /*
854     Double_t x1[2];
855   Double_t x2[2];
856   Double_t angle1,angle2;
857   TObjArray *hits = track->GetHits();
858   
859   if (n > track->GetNumberOfPoints()) {
860     n = track->GetNumberOfPoints();
861   }
862
863   if (n<3) 
864     return 0;
865   
866
867   x1[0] = ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetX() - ((AliHLTTPCConfMapPoint *)hits->At(n-3))->GetX();
868   x1[1] = ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetY() - ((AliHLTTPCConfMapPoint *)hits->At(n-3))->GetY();
869
870   x2[0] = ((AliHLTTPCConfMapPoint *)hits->At(n-1))->GetX() - ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetX();
871   x2[1] = ((AliHLTTPCConfMapPoint *)hits->At(n-1))->GetY() - ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetY();
872   
873   angle1 = atan2(x1[1],x1[0]);
874   angle2 = atan2(x2[1],x1[0]);
875   return fabs(angle1-angle2);
876   */
877 }
878
879 Int_t AliHLTTPCConfMapper::FillTracks()
880 {
881   //Fill track parameters. Which basically means do a fit of helix in real space,
882   //which should be done in order to get nice tracks.
883   
884   Int_t numoftracks = fNTracks;
885   if(fNTracks == 0)
886     {
887       LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::FillTracks","fNTracks")<<AliHLTTPCLog::kDec<<
888         "No tracks found!!"<<ENDLOG;
889       return 0;
890     }
891
892   LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::FillTracks","fNTracks")<<AliHLTTPCLog::kDec<<
893     "Number of found tracks: "<<fNTracks<<ENDLOG;
894   
895   //  fTrack->Sort();
896   for(Int_t i=0; i<numoftracks; i++)
897     {
898       AliHLTTPCConfMapTrack *track = (AliHLTTPCConfMapTrack*)fTrack->GetTrack(i);
899       track->Fill(fVertex,fMaxDca);
900     }
901   return 1;
902 }
903
904 Double_t AliHLTTPCConfMapper::CpuTime()
905 {
906   //Return the Cputime in seconds.
907  struct timeval tv;
908  gettimeofday( &tv, NULL );
909  return tv.tv_sec+(((Double_t)tv.tv_usec)/1000000.);
910 }