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