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