]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCTrackArray.cxx
speeding up the loop over track clusters; masking a false error message
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCTrackArray.cxx
1 // @(#) $Id$
2 // Original: AliHLTTrackArray.cxx,v 1.21 2005/06/14 10:55:21 cvetan 
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: Uli Frankenfeld, 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   AliHLTTPCTrackArray.cxx
22     @author Uli Frankenfeld, maintained by Matthias Richter
23     @date   
24     @brief  Array of AliHLTTPCTracks */
25
26 #include "AliLog.h"
27 #include "TClass.h"
28 #include "AliHLTTPCLogging.h"
29 #include "AliHLTTPCTrackArray.h"
30 // Matthias 17.10.2007 the hough code has been disabled for the moment
31 //#define INCLUDE_TPC_HOUGH
32 #ifdef INCLUDE_TPC_HOUGH
33 #include "AliHLTTPCHoughTrack.h"
34 #endif
35 #include "AliHLTTPCModelTrack.h"
36 #include "AliHLTTPCConfMapTrack.h"
37 #include "AliHLTTPCTrackSegmentData.h"
38 #include "AliHLTTPCTransform.h"
39 #include "AliHLTTPCConfMapPoint.h"
40 #include "AliHLTExternalTrackParam.h"
41
42 #if __GNUC__ >= 3
43 using namespace std;
44 #endif
45
46 ClassImp(AliHLTTPCTrackArray)
47
48 AliHLTTPCTrackArray::AliHLTTPCTrackArray()
49   :
50   fTrackType('t'),
51   fSize(0),
52   fIsPresent(NULL),
53   fNAbsent(0),
54   fTrack(NULL),
55   fNTracks(0)
56 {
57   //Default constructor
58   SetSize();
59 }
60
61
62 AliHLTTPCTrackArray::AliHLTTPCTrackArray(Int_t ntrack)
63   :
64   fTrackType('t'),
65   fSize(0),
66   fIsPresent(NULL),
67   fNAbsent(0),
68   fTrack(NULL),
69   fNTracks(0)
70 {
71   //Constructor.
72   SetSize(ntrack);
73 }
74
75 AliHLTTPCTrackArray::AliHLTTPCTrackArray(const char* tracktype,Int_t ntrack)
76   :
77   fTrackType('t'),
78   fSize(0),
79   fIsPresent(NULL),
80   fNAbsent(0),
81   fTrack(NULL),
82   fNTracks(0)
83 {
84   //Constructor.
85   if(strcmp(tracktype,"AliHLTTPCTrack")==0) fTrackType='t';
86   if(strcmp(tracktype,"AliHLTTPCConfMapTrack")==0) fTrackType='c';
87 #ifdef INCLUDE_TPC_HOUGH
88   if(strcmp(tracktype,"AliHLTTPCHoughTrack")==0) fTrackType='h';
89 #endif
90   if(strcmp(tracktype,"AliHLTTPCModelTrack")==0) fTrackType='m';
91   SetSize(ntrack);
92 }
93
94 AliHLTTPCTrackArray::AliHLTTPCTrackArray(const char* tracktype)
95   :
96   fTrackType('t'),
97   fSize(0),
98   fIsPresent(NULL),
99   fNAbsent(0),
100   fTrack(NULL),
101   fNTracks(0)
102 {
103   //Constructor.
104   if(strcmp(tracktype,"AliHLTTPCTrack")==0) fTrackType='t';
105   if(strcmp(tracktype,"AliHLTTPCConfMapTrack")==0) fTrackType='c';
106 #ifdef INCLUDE_TPC_HOUGH
107   if(strcmp(tracktype,"AliHLTTPCHoughTrack")==0) fTrackType='h';
108 #endif
109   if(strcmp(tracktype,"AliHLTTPCModelTrack")==0) fTrackType='m';
110   SetSize();
111 }
112
113 AliHLTTPCTrackArray::~AliHLTTPCTrackArray()
114 {
115   //Destructor
116   DeleteArray();
117 }
118
119
120 AliHLTTPCTrack *AliHLTTPCTrackArray::NextTrack()
121 {
122   //next track in array
123   if(fNTracks<fSize) return fTrack[fNTracks++];
124   SetSize(fSize+100);
125    return fTrack[fNTracks++]; 
126 }
127
128 void AliHLTTPCTrackArray::DeleteArray()
129 {
130   //delete array
131   for(Int_t i=0; i<fSize;i++)
132     delete fTrack[i];
133   delete[] fIsPresent;
134   delete[] fTrack;
135   fSize=0;
136 }
137
138 Bool_t AliHLTTPCTrackArray::SetSize(Int_t newsize)
139 {
140   //set size
141   if(newsize<=fSize) return kFALSE; //shrink comes later!! 
142   if(!fSize){
143     fSize = newsize;
144     fTrack = new AliHLTTPCTrack*[fSize];
145     fIsPresent = new Bool_t[fSize];
146     switch(fTrackType){
147       case 't':
148         for(Int_t i=0;i<fSize;i++){
149           fTrack[i]   = new AliHLTTPCTrack();
150           fIsPresent[i] = kTRUE;
151         }
152         break;
153       case 'c':  
154         for(Int_t i=0;i<fSize;i++){
155           fTrack[i]   = new AliHLTTPCConfMapTrack();
156           fIsPresent[i] = kTRUE;
157         }
158         break;
159 #ifdef INCLUDE_TPC_HOUGH
160       case 'h':
161         for(Int_t i=0;i<fSize;i++){
162           fTrack[i]   = new AliHLTTPCHoughTrack();
163           fIsPresent[i] = kTRUE;
164         }
165         break;
166 #endif
167        case 'm':
168         for(Int_t i=0;i<fSize;i++){
169           fTrack[i]   = new AliHLTTPCModelTrack();
170           fIsPresent[i] = kTRUE;
171         }
172         break;
173       default: 
174         return kFALSE;
175     }
176     return kTRUE;
177   }
178   AliHLTTPCTrack **tmp = new AliHLTTPCTrack*[fSize];
179   Bool_t *pre = new Bool_t[fSize];
180   for(Int_t i=0; i<fSize;i++){
181     tmp[i] = fTrack[i];
182     pre[i] = fIsPresent[i];
183   }
184   delete[]  fTrack;
185   delete[] fIsPresent;
186   fTrack =  new AliHLTTPCTrack*[newsize];
187   fIsPresent = new Bool_t[newsize];
188   for(Int_t i=0; i<fSize;i++){
189     fTrack[i]   = tmp[i];
190     fIsPresent[i] = pre[i];
191   }
192   delete[] tmp;
193   delete[] pre;
194   switch(fTrackType){
195     case 't':
196       for(Int_t i=fSize;i<newsize;i++){
197         fTrack[i]   = new AliHLTTPCTrack();
198         fIsPresent[i] = kTRUE;
199       }
200       break;
201     case 'c':  
202       for(Int_t i=fSize;i<newsize;i++){
203         fTrack[i]   = new AliHLTTPCConfMapTrack();
204         fIsPresent[i] = kTRUE;
205       }
206       break;
207 #ifdef INCLUDE_TPC_HOUGH
208     case 'h':
209       for(Int_t i=fSize;i<newsize;i++){
210         fTrack[i]   = new AliHLTTPCHoughTrack();
211         fIsPresent[i] = kTRUE;
212       }
213       break;
214 #endif
215     case 'm':
216       for(Int_t i=fSize;i<newsize;i++){
217         fTrack[i]   = new AliHLTTPCModelTrack();
218         fIsPresent[i] = kTRUE;
219       }
220       break;
221     default: 
222       return kFALSE;
223   }
224   fSize = newsize;
225   return kTRUE;
226 }
227
228 void AliHLTTPCTrackArray::Reset()
229 {
230   //reset
231   fNTracks=0;
232   fNAbsent=0;
233   for(Int_t i=0; i<fSize;i++)
234     fIsPresent[i] = kTRUE; 
235 }
236
237 void AliHLTTPCTrackArray::Remove(Int_t track)
238 {
239   //remove track
240   if(fIsPresent[track]){
241     fIsPresent[track]=kFALSE;
242     fNAbsent++;
243   }
244 }
245
246 int AliHLTTPCTrackArray::FillTracks(Int_t ntracks, AliHLTTPCTrackSegmentData* tr, Int_t slice, Int_t bTransform)
247 {
248   //Read tracks from shared memory (or memory)
249   return FillTracksChecked(tr, ntracks, 0, slice, bTransform);
250 }
251
252 int AliHLTTPCTrackArray::FillTracksChecked(AliHLTExternalTrackParam* tr, Int_t ntracks, unsigned int sizeInByte, Int_t slice, Int_t bTransform)
253 {
254   int iResult=0;
255   AliHLTExternalTrackParam *trs = tr;
256   
257   for(Int_t i=0; i<ntracks; i++){
258     if (sizeInByte>0 && 
259         (((AliHLTUInt8_t*)trs)+sizeof(AliHLTExternalTrackParam)>((AliHLTUInt8_t*)tr)+sizeInByte ||
260          ((AliHLTUInt8_t*)trs)+sizeof(AliHLTExternalTrackParam)+trs->fNPoints*sizeof(UInt_t)>((AliHLTUInt8_t*)tr)+sizeInByte)) {
261       iResult=-EDOM;
262       break;
263     }
264     AliHLTTPCTrack *track = NextTrack(); 
265     track->SetId( i );
266     track->SetPt(trs->fq1Pt);
267     track->SetPterr(trs->fC[14]);
268     Float_t psi[1];
269     psi[0]=trs->fSinPsi;
270     if (slice>=0 && bTransform!=0)  {
271       AliHLTTPCTransform::Local2GlobalAngle(psi,slice);
272     }
273     //cout << "psi " << psi[0] << endl;
274     track->SetPsi(psi[0]);
275     track->SetTgl(trs->fTgl);
276     track->SetPsierr(trs->fC[5]);
277     track->SetTglerr(trs->fC[9]);
278     track->SetY0err(trs->fC[0]);
279     track->SetZ0err(trs->fC[2]);
280     track->SetNHits(trs->fNPoints);
281     //track->SetCharge(trs->fCharge);
282     Float_t first[3];
283     first[0]=trs->fX;first[1]=trs->fY;first[2]=trs->fZ;
284     if (slice>=0 && bTransform!=0)  {
285       AliHLTTPCTransform::Local2Global(first,slice);
286     }
287     //cout << "first point: " << first[0] << " " << first[1] << " " << first[3] << endl;
288     track->SetFirstPoint(first[0],first[1],first[2]);
289     Float_t last[3];
290     last[0]=trs->fLastX;last[1]=trs->fLastY;last[2]=trs->fLastZ;
291     if (slice>=0 && bTransform!=0)  {
292       AliHLTTPCTransform::Local2Global(last,slice);
293     }
294     //cout << "last point: " << last[0] << " " << last[1] << " " << last[3] << endl;
295     track->SetLastPoint(last[0],last[1],last[2]);
296     track->SetHits( trs->fNPoints, trs->fPointIDs );
297
298     //if (slice>=0 && bTransform!=0)  {
299       // Matthias Feb07: as everything is now in global coordinates, sector should
300       // be set to 0. But as the display does a check on the sector, we have to set
301       // it to the slice no. I suspect, that the transformation is done twice.
302       //track->SetSector(0);
303     
304       track->SetSector(slice);
305     
306     //} else {
307       // the parameters are in local coordinates, set the sector no
308       //#ifndef INCLUDE_TPC_HOUGH
309       //if (slice<0) track->SetSector(0);
310       //else track->SetSector(slice);
311       //#else 
312       // Matthias Feb 2007: this is some kind of legacy ...
313       // the INCLUDE_TPC_HOUGH has never been switched on in the new TPCLib
314       // and this line was below in the corresponding block. As the slice
315       // parameter is very useful but not available if the define is off
316       // we distinguish the two cases here. Should be cleaned up.
317       // Matthias April 2007: update, try to integrate Cvetans Hough tracker
318       // so we need the support for the AliHLTTPCHoughTrack. I dont have the
319       // full control of this code (should we use slice or trs->fSector?)
320       // But the FillTracks method is never called from the hough code, so we
321       // take 'slice'
322       if (GetTrackType()=='h') {
323         AliErrorClassStream() << "FillTracks was never used with AliHLTTPCHoughTrack:" 
324                            << " CHECK THIS CODE!!!" << endl;
325       }
326       //track->SetSector(trs->fSector);
327       //#endif // INCLUDE_TPC_HOUGH
328       //}
329
330     // this is currently a quick hack for straight lines of the first version 
331     // of the CA tracker.
332     // we have to think about a more general way of treating straight and curved
333     // tracks
334     if ( trs->fq1Pt == -9876.0 ||  trs->fq1Pt == -1.0) {
335       track->SetPhi0(atan2(first[1],first[0]));
336       track->SetKappa(1.0);
337       track->SetRadius(999999.0);
338     } else {
339       // Matthias Feb07: just tried to take this away, but this causes the tracks
340       // in the display not to be drawn. But we still have to tink about this.
341       track->CalculateHelix();
342     }
343
344 #ifdef INCLUDE_TPC_HOUGH
345 #ifdef ROWHOUGHPARAMS
346     if(GetTrackType()=='h') {
347       ((AliHLTTPCHoughTrack *)track)->SetWeight(trs->fWeight);
348       ((AliHLTTPCHoughTrack *)track)->SetBinXY(trs->fBinX,trs->fBinY,trs->fBinXSize,trs->fBinYSize);
349     }
350     track->SetMCid(trs->fTrackID);
351     track->SetRowRange(trs->fRowRange1,trs->fRowRange2);
352     track->SetPID(trs->fPID);
353 #endif
354 #endif // INCLUDE_TPC_HOUGH
355     track->CheckConsistency();
356
357     UChar_t *tmpP = (UChar_t*)trs;
358     tmpP += sizeof(AliHLTExternalTrackParam)+trs->fNPoints*sizeof(UInt_t);
359     trs = (AliHLTExternalTrackParam*)tmpP;
360   }
361   return iResult;
362 }
363
364 int AliHLTTPCTrackArray::FillTracksChecked(AliHLTTPCTrackSegmentData* tr, Int_t ntracks, unsigned int sizeInByte, Int_t slice, Int_t bTransform)
365 {
366   //Read tracks from shared memory (or memory)
367   int iResult=0;
368   AliHLTTPCTrackSegmentData *trs = tr;
369   for(Int_t i=0; i<ntracks; i++){
370     if (sizeInByte>0 && 
371         (((AliHLTUInt8_t*)trs)+sizeof(AliHLTTPCTrackSegmentData)>((AliHLTUInt8_t*)tr)+sizeInByte ||
372          ((AliHLTUInt8_t*)trs)+sizeof(AliHLTTPCTrackSegmentData)+trs->fNPoints*sizeof(UInt_t)>((AliHLTUInt8_t*)tr)+sizeInByte)) {
373       iResult=-EDOM;
374       break;
375     }
376     AliHLTTPCTrack *track = NextTrack(); 
377     track->SetId( i );
378     track->SetPt(trs->fPt);
379     track->SetPterr(trs->fPterr);
380     Float_t psi[1];
381     psi[0]=trs->fPsi;
382     if (slice>=0 && bTransform!=0)  {
383       AliHLTTPCTransform::Local2GlobalAngle(psi,slice);
384     }
385     //cout << "psi " << psi[0] << endl;
386     track->SetPsi(psi[0]);
387     track->SetTgl(trs->fTgl);
388     track->SetPsierr(trs->fPsierr);
389     track->SetTglerr(trs->fTglerr);
390     track->SetY0err(trs->fY0err);
391     track->SetZ0err(trs->fZ0err);
392     track->SetNHits(trs->fNPoints);
393     track->SetCharge(trs->fCharge);
394     Float_t first[3];
395     first[0]=trs->fX;first[1]=trs->fY;first[2]=trs->fZ;
396     if (slice>=0 && bTransform!=0)  {
397       AliHLTTPCTransform::Local2Global(first,slice);
398     }
399     //cout << "first point: " << first[0] << " " << first[1] << " " << first[3] << endl;
400     track->SetFirstPoint(first[0],first[1],first[2]);
401     Float_t last[3];
402     last[0]=trs->fLastX;last[1]=trs->fLastY;last[2]=trs->fLastZ;
403     if (slice>=0 && bTransform!=0)  {
404       AliHLTTPCTransform::Local2Global(last,slice);
405     }
406     //cout << "last point: " << last[0] << " " << last[1] << " " << last[3] << endl;
407     track->SetLastPoint(last[0],last[1],last[2]);
408     track->SetHits( trs->fNPoints, trs->fPointIDs );
409
410     //if (slice>=0 && bTransform!=0)  {
411       // Matthias Feb07: as everything is now in global coordinates, sector should
412       // be set to 0. But as the display does a check on the sector, we have to set
413       // it to the slice no. I suspect, that the transformation is done twice.
414       //track->SetSector(0);
415       track->SetSector(slice);
416     //} else {
417       // the parameters are in local coordinates, set the sector no
418       //#ifndef INCLUDE_TPC_HOUGH
419       //if (slice<0) track->SetSector(0);
420       //else track->SetSector(slice);
421       //#else 
422       // Matthias Feb 2007: this is some kind of legacy ...
423       // the INCLUDE_TPC_HOUGH has never been switched on in the new TPCLib
424       // and this line was below in the corresponding block. As the slice
425       // parameter is very useful but not available if the define is off
426       // we distinguish the two cases here. Should be cleaned up.
427       // Matthias April 2007: update, try to integrate Cvetans Hough tracker
428       // so we need the support for the AliHLTTPCHoughTrack. I dont have the
429       // full control of this code (should we use slice or trs->fSector?)
430       // But the FillTracks method is never called from the hough code, so we
431       // take 'slice'
432       if (GetTrackType()=='h') {
433         AliErrorClassStream() << "FillTracks was never used with AliHLTTPCHoughTrack:" 
434                            << " CHECK THIS CODE!!!" << endl;
435       }
436       //track->SetSector(trs->fSector);
437       //#endif // INCLUDE_TPC_HOUGH
438       //}
439
440     // this is currently a quick hack for straight lines of the first version 
441     // of the CA tracker.
442     // we have to think about a more general way of treating straight and curved
443     // tracks
444     if ( trs->fPt == -9876.0 ||  trs->fPt == -1.0) {
445       track->SetPhi0(atan2(first[1],first[0]));
446       track->SetKappa(1.0);
447       track->SetRadius(999999.0);
448     } else {
449       // Matthias Feb07: just tried to take this away, but this causes the tracks
450       // in the display not to be drawn. But we still have to tink about this.
451       track->CalculateHelix();
452     }
453
454 #ifdef INCLUDE_TPC_HOUGH
455 #ifdef ROWHOUGHPARAMS
456     if(GetTrackType()=='h') {
457       ((AliHLTTPCHoughTrack *)track)->SetWeight(trs->fWeight);
458       ((AliHLTTPCHoughTrack *)track)->SetBinXY(trs->fBinX,trs->fBinY,trs->fBinXSize,trs->fBinYSize);
459     }
460     track->SetMCid(trs->fTrackID);
461     track->SetRowRange(trs->fRowRange1,trs->fRowRange2);
462     track->SetPID(trs->fPID);
463 #endif
464 #endif // INCLUDE_TPC_HOUGH
465     track->CheckConsistency();
466
467     UChar_t *tmpP = (UChar_t*)trs;
468     tmpP += sizeof(AliHLTTPCTrackSegmentData)+trs->fNPoints*sizeof(UInt_t);
469     trs = (AliHLTTPCTrackSegmentData*)tmpP;
470   }
471
472   if (iResult==-EDOM) {
473     // try to recover the version 1 struct
474     Reset();
475     if ((iResult=FillTracksVersion1((AliHLTTPCTrackSegmentDataV1*)tr, ntracks, sizeInByte, slice, bTransform))>=0) {
476       LOG(AliHLTTPCLog::kWarning,"AliHLTTPCTrackArray::FillTracks","") << "version 1 track array recoverd (deprecated since r27415)" << ENDLOG;
477     }
478   }
479   if (iResult==-EDOM) {
480     Reset();
481     LOG(AliHLTTPCLog::kError,"AliHLTTPCTrackArray::FillTracks","") << "corrupted input data array" << ENDLOG;
482   }
483
484   return iResult;
485 }
486
487 int AliHLTTPCTrackArray::FillTracksVersion1(AliHLTTPCTrackSegmentDataV1* tr, Int_t ntracks, unsigned int sizeInByte, Int_t slice, Int_t bTransform)
488 {
489   //Read tracks from shared memory (or memory)
490   int iResult=0;
491   AliHLTTPCTrackSegmentDataV1 *trs = tr;
492   for(Int_t i=0; i<ntracks; i++){
493     if (sizeInByte>0 && 
494         (((AliHLTUInt8_t*)trs)+sizeof(AliHLTTPCTrackSegmentDataV1)>((AliHLTUInt8_t*)tr)+sizeInByte ||
495          ((AliHLTUInt8_t*)trs)+sizeof(AliHLTTPCTrackSegmentDataV1)+trs->fNPoints*sizeof(UInt_t)>((AliHLTUInt8_t*)tr)+sizeInByte)) {
496       iResult=-EDOM;
497       break;
498     }
499     AliHLTTPCTrack *track = NextTrack(); 
500     track->SetPt(trs->fPt);
501     track->SetPterr(trs->fPterr);
502     Float_t psi[1];
503     psi[0]=trs->fPsi;
504     if (slice>=0 && bTransform!=0)  {
505       AliHLTTPCTransform::Local2GlobalAngle(psi,slice);
506     }
507     track->SetPsi(psi[0]);
508     track->SetTgl(trs->fTgl);
509     track->SetPsierr(trs->fPsierr);
510     track->SetTglerr(trs->fTglerr);
511     track->SetNHits(trs->fNPoints);
512     track->SetCharge(trs->fCharge);
513     Float_t first[3];
514     first[0]=trs->fX;first[1]=trs->fY;first[2]=trs->fZ;
515     if (slice>=0 && bTransform!=0)  {
516       AliHLTTPCTransform::Local2Global(first,slice);
517     }
518     track->SetFirstPoint(first[0],first[1],first[2]);
519     Float_t last[3];
520     last[0]=trs->fLastX;last[1]=trs->fLastY;last[2]=trs->fLastZ;
521     if (slice>=0 && bTransform!=0)  {
522       AliHLTTPCTransform::Local2Global(last,slice);
523     }
524     track->SetLastPoint(last[0],last[1],last[2]);
525     track->SetHits( trs->fNPoints, trs->fPointIDs );
526
527     track->SetSector(slice);
528     if ( trs->fPt == -9876.0 ||  trs->fPt == -1.0) {
529       track->SetPhi0(atan2(first[1],first[0]));
530       track->SetKappa(1.0);
531       track->SetRadius(999999.0);
532     } else {
533       track->CalculateHelix();
534     }
535
536     UChar_t *tmpP = (UChar_t*)trs;
537     tmpP += sizeof(AliHLTTPCTrackSegmentDataV1)+trs->fNPoints*sizeof(UInt_t);
538     trs = (AliHLTTPCTrackSegmentDataV1*)tmpP;
539   }
540   return iResult;
541 }
542
543 UInt_t AliHLTTPCTrackArray::GetOutSize()
544 {
545   //get size for IO
546   UInt_t count = GetOutCount();   //use only present tracks
547   UInt_t tHits = 0;
548   for(Int_t i=0;i<fNTracks;i++){  //loop over all tracks
549     AliHLTTPCTrack *track = GetCheckedTrack(i);  //use only present tracks
550     if(track)                                       //use only present tracks
551       tHits += track->GetNHits();
552   }
553
554   //calculate size of track
555   return count*sizeof(AliHLTTPCTrackSegmentData)+sizeof(UInt_t)*tHits;
556 }
557
558 UInt_t AliHLTTPCTrackArray::WriteTracks(UInt_t & ntracks,AliHLTTPCTrackSegmentData* tr)
559 {
560   //write tracks
561   ntracks = GetOutCount();
562   return WriteTracks(tr);
563 }
564
565 UInt_t AliHLTTPCTrackArray::WriteTracks(AliHLTTPCTrackSegmentData* tr)
566 {
567   //if(GetTrackType()=='c') return WriteConfMapTracks(tr);
568   AliHLTTPCTrackSegmentData *tP = tr;
569   UInt_t *pP;
570   UInt_t size = 0;
571   for(Int_t i=0; i<fNTracks; i++){  //loop over all tracks
572     AliHLTTPCTrack *track = GetCheckedTrack(i); //use only present tracks
573     if(!track) continue;                           //use only present tracks
574     tP->fX = track->GetFirstPointX();
575     tP->fY = track->GetFirstPointY();
576     tP->fZ = track->GetFirstPointZ();
577     tP->fPt = track->GetPt();
578     tP->fPterr = track->GetPterr();
579     tP->fLastX = track->GetLastPointX();
580     tP->fLastY = track->GetLastPointY();
581     tP->fLastZ = track->GetLastPointZ();
582     tP->fPsi = track->GetPsi();
583     tP->fTgl = track->GetTgl();
584     tP->fPsierr = track->GetPsierr();
585     tP->fTglerr = track->GetTglerr();
586     tP->fY0err = track->GetY0err();
587     tP->fZ0err = track->GetZ0err();
588     tP->fCharge = track->GetCharge();
589     tP->fNPoints = track->GetNHits();
590 #ifdef INCLUDE_TPC_HOUGH
591 #ifdef ROWHOUGHPARAMS
592     if(GetTrackType()=='h') {
593       tP->fWeight = ((AliHLTTPCHoughTrack *)track)->GetWeight();
594       tP->fBinX = ((AliHLTTPCHoughTrack *)track)->GetBinX();
595       tP->fBinY = ((AliHLTTPCHoughTrack *)track)->GetBinY();
596       tP->fBinXSize = ((AliHLTTPCHoughTrack *)track)->GetSizeX();
597       tP->fBinYSize = ((AliHLTTPCHoughTrack *)track)->GetSizeY();
598     }
599     tP->fTrackID = track->GetMCid();
600     tP->fRowRange1 = track->GetFirstRow();
601     tP->fRowRange2 = track->GetLastRow();
602     tP->fSector = track->GetSector();
603     tP->fPID = track->GetPID();
604 #endif
605 #endif // INCLUDE_TPC_HOUGH
606     pP = (UInt_t*)track->GetHitNumbers();
607     for (UInt_t j=0;j<tP->fNPoints;j++){
608       tP->fPointIDs[j] = pP[j];
609     }
610     Byte_t *tmpP = (Byte_t *)tP;
611     tmpP += sizeof(AliHLTTPCTrackSegmentData)+tP->fNPoints*sizeof(UInt_t);
612     size += sizeof(AliHLTTPCTrackSegmentData)+tP->fNPoints*sizeof(UInt_t);
613     tP = (AliHLTTPCTrackSegmentData*)tmpP;
614
615 //    LOG(AliHLTTPCLog::kError,"AliHLTTPCTrackArray::WriteTracks","TRACKPARAMETER") <<ENDLOG;
616 //    track->Rotate(0,kFALSE);
617 //    track->Print();
618
619   }
620   return size;
621 }
622
623 UInt_t AliHLTTPCTrackArray::WriteConfMapTracks(AliHLTTPCTrackSegmentData* tr)
624 {
625   // use first and last point objects
626   AliHLTTPCTrackSegmentData *tP = tr;
627   UInt_t *pP;
628   UInt_t size = 0;
629   for(Int_t i=0; i<fNTracks; i++){  //loop over all tracks
630     AliHLTTPCConfMapTrack *track =(AliHLTTPCConfMapTrack *) GetCheckedTrack(i); //use only present tracks
631     if(!track) continue;                           //use only present tracks
632     AliHLTTPCConfMapPoint *hit = (AliHLTTPCConfMapPoint*)track->GetLastHit();
633     AliHLTTPCConfMapPoint *lastHit = (AliHLTTPCConfMapPoint*)track->GetFirstHit();
634     tP->fX = hit->GetX();
635     tP->fY = hit->GetY();
636     tP->fZ = hit->GetZ();
637     tP->fLastX = lastHit->GetX();
638     tP->fLastY = lastHit->GetY();
639     tP->fLastZ = lastHit->GetZ();
640    
641 //    tP->fX = track->GetFirstPointX();
642 //    tP->fY = track->GetFirstPointY();
643 //    tP->fZ = track->GetFirstPointZ();
644     tP->fPt = track->GetPt();
645     tP->fPterr = track->GetPterr();
646 //    tP->fLastX = track->GetLastPointX();
647 //    tP->fLastY = track->GetLastPointY();
648 //    tP->fLastZ = track->GetLastPointZ();
649     tP->fPsi = track->GetPsi();
650     tP->fTgl = track->GetTgl();
651     tP->fPsierr = track->GetPsierr();
652     tP->fTglerr = track->GetTglerr();
653     tP->fY0err = track->GetY0err();
654     tP->fZ0err = track->GetZ0err();
655     tP->fCharge = track->GetCharge();
656 #ifdef INCLUDE_TPC_HOUGH
657 #ifdef ROWHOUGHPARAMS
658     tP->fTrackID = track->GetMCid();
659     tP->fRowRange1 = track->GetFirstRow();
660     tP->fRowRange2 = track->GetLastRow();
661     tP->fSector = track->GetSector();
662     tP->fPID = track->GetPID();
663 #endif
664 #endif // INCLUDE_TPC_HOUGH
665     tP->fNPoints = track->GetNHits();
666     pP = (UInt_t*)track->GetHitNumbers();
667     for (UInt_t j=0;j<tP->fNPoints;j++){
668       tP->fPointIDs[j] = pP[j];
669     }
670     Byte_t *tmpP = (Byte_t *)tP;
671     tmpP += sizeof(AliHLTTPCTrackSegmentData)+tP->fNPoints*sizeof(UInt_t);
672     size +=sizeof(AliHLTTPCTrackSegmentData)+tP->fNPoints*sizeof(UInt_t);
673     tP = (AliHLTTPCTrackSegmentData*)tmpP;
674   }
675   return size;
676 }
677
678 void AliHLTTPCTrackArray::AddLast(AliHLTTPCTrack *track)
679 {
680   //add track to last position
681   AliHLTTPCTrack *tpt = NextTrack();
682   tpt->Copy(track);
683   
684 }
685
686 void AliHLTTPCTrackArray::AddTracks(AliHLTTPCTrackArray *newtrack,Bool_t remove_old,Int_t slice)
687 {
688   //add tracks
689   if(GetTrackType() != newtrack->GetTrackType() && GetTrackType()!='t')
690     {
691       LOG(AliHLTTPCLog::kError,"AliHLTTPCTrackArray::AddTracks","Track types")
692         <<"Bad idea to add tracks of different types"<<ENDLOG;
693       return;
694     }
695   if(fSize < fNTracks+newtrack->GetNPresent())
696     SetSize(fSize+newtrack->GetSize());
697   for(Int_t i =0;i<newtrack->GetNTracks();i++){
698     AliHLTTPCTrack *tpt = newtrack->GetCheckedTrack(i);
699     if(!tpt) continue;
700     if(remove_old)
701       newtrack->Remove(i);
702     AliHLTTPCTrack *track = NextTrack();
703     track->Copy(tpt);
704     if(slice>=0)
705       track->Rotate(slice); //Rotate track to global coordinates
706     /*
707       AliHLTTPCTrack *track;
708 #ifdef INCLUDE_TPC_HOUGH
709       if(GetTrackType()=='h')
710       track = (AliHLTTPCHoughTrack*)NextTrack();
711       else
712 #endif
713       track = NextTrack();
714       track->Copy(tpt);
715     */
716   }
717 }
718
719 void AliHLTTPCTrackArray::Compress()
720 {
721   //compress array
722   if(GetNPresent()==GetNTracks()) return;
723   AliHLTTPCTrack **tmp =  new AliHLTTPCTrack *[fNTracks];
724   Int_t present=0;
725   Int_t absent=GetNPresent();
726   for(Int_t i=0;i<GetNTracks();i++){
727     if(fIsPresent[i]) tmp[present++] = fTrack[i];
728     else tmp[absent++] = fTrack[i];
729   }
730   for(Int_t i=0;i<GetNTracks();i++)
731     fIsPresent[i]=kTRUE;
732
733   //Copy pointers back
734   for(Int_t i=0; i<GetNTracks();i++){
735     fTrack[i]=tmp[i];
736   }
737
738   delete[] tmp;
739
740   fNTracks = GetNPresent();
741   fNAbsent = 0;
742 }
743
744 void AliHLTTPCTrackArray::QSort()
745 {
746   // compress and sort
747   Compress();
748   QSort(fTrack,0,fNTracks);
749 }
750
751 void AliHLTTPCTrackArray::QSort( AliHLTTPCTrack **a, Int_t first, Int_t last)
752 {
753    // Sort array of AliHLTTPCTrack pointers using a quicksort algorithm.
754    // Uses TrackCompare() to compare objects.
755    // Thanks to Root! 
756
757    static AliHLTTPCTrack *tmp;
758    static int i;           // "static" to save stack space
759    int j;
760
761    while (last - first > 1) {
762       i = first;
763       j = last;
764       for (;;) {
765         while (++i < last && TrackCompare(a[i], a[first]) < 0)
766           ;
767         while (--j > first && TrackCompare(a[j], a[first]) > 0)
768           ;
769          if (i >= j)
770             break;
771
772          tmp  = a[i];
773          a[i] = a[j];
774          a[j] = tmp;
775       }
776       if (j == first) {
777          ++first;
778          continue;
779       }
780       tmp = a[first];
781       a[first] = a[j];
782       a[j] = tmp;
783       if (j - first < last - (j + 1)) {
784          QSort(a, first, j);
785          first = j + 1;   // QSort(j + 1, last);
786       } else {
787          QSort(a, j + 1, last);
788          last = j;        // QSort(first, j);
789       }
790    }
791 }
792
793 Int_t AliHLTTPCTrackArray::TrackCompare(AliHLTTPCTrack *a, AliHLTTPCTrack *b) const
794 {
795    // Compare the two tracks.
796   
797   return b->Compare(a);
798   
799   /*
800 #ifdef INCLUDE_TPC_HOUGH
801     if(fTrackType=='h')
802     {
803     AliHLTTPCHoughTrack *tra = (AliHLTTPCHoughTrack*)a;
804     AliHLTTPCHoughTrack *trb = (AliHLTTPCHoughTrack*)b;
805     if(tra->GetWeight() < trb->GetWeight()) return 1;
806     if(tra->GetWeight() > trb->GetWeight()) return -1;
807     }
808     else
809 #endif
810     {
811     if(a->GetNHits() < b->GetNHits()) return 1;
812     if(a->GetNHits() > b->GetNHits()) return -1;
813     }
814     
815     return 0;
816   */
817 }
818
819 AliHLTTPCTrack* AliHLTTPCTrackArray::operator[](int index)
820 {
821   // access operator
822   if (index<fNTracks) return fTrack[index];
823   return NULL;
824 }