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