new configuration parameters introduced for CASliceTracker --- minNTrackClusters...
[u/mrichter/AliRoot.git] / HLT / TPCLib / tracking-ca / AliHLTTPCCATracker.cxx
1 // @(#) $Id$
2 // **************************************************************************
3 // This file is property of and copyright by the ALICE HLT Project          *
4 // ALICE Experiment at CERN, All rights reserved.                           *
5 //                                                                          *
6 // Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
7 //                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
8 //                  for The ALICE HLT Project.                              *
9 //                                                                          *
10 // Permission to use, copy, modify and distribute this software and its     *
11 // documentation strictly for non-commercial purposes is hereby granted     *
12 // without fee, provided that the above copyright notice appears in all     *
13 // copies and that both the copyright notice and this permission notice     *
14 // appear in the supporting documentation. The authors make no claims       *
15 // about the suitability of this software for any purpose. It is            *
16 // provided "as is" without express or implied warranty.                    *
17 //                                                                          *
18 //***************************************************************************
19
20 #include "AliHLTTPCCATracker.h"
21 #include "AliHLTTPCCARow.h"
22 #include "AliHLTTPCCATrack.h"
23 #include "AliHLTTPCCATracklet.h"
24 #include "AliHLTTPCCAMath.h"
25 #include "MemoryAssignmentHelpers.h"
26
27 #include "TStopwatch.h"
28 #include "AliHLTTPCCAHitArea.h"
29 #include "AliHLTTPCCANeighboursFinder.h"
30 #include "AliHLTTPCCANeighboursCleaner.h"
31 #include "AliHLTTPCCAStartHitsFinder.h"
32 #include "AliHLTTPCCATrackletConstructor.h"
33 #include "AliHLTTPCCATrackletSelector.h"
34 #include "AliHLTTPCCAProcess.h"
35 #include "AliHLTTPCCAClusterData.h"
36
37 #include "AliHLTTPCCATrackParam.h"
38
39 #include "AliHLTTPCCAGPUConfig.h"
40
41 #if !defined(HLTCA_GPUCODE)
42 #include <iostream>
43 #include <iomanip>
44 #include <string.h>
45 #endif
46
47 //#define DRAW1
48
49 #ifdef DRAW1
50 #include "AliHLTTPCCADisplay.h"
51 #endif //DRAW1
52
53 #ifdef HLTCA_INTERNAL_PERFORMANCE
54 //#include "AliHLTTPCCAPerformance.h"
55 #endif
56
57 #ifdef HLTCA_STANDALONE
58 #include "AliHLTTPCCAStandaloneFramework.h"
59 #endif
60
61 ClassImp( AliHLTTPCCATracker )
62
63
64 #if !defined(HLTCA_GPUCODE)
65
66 AliHLTTPCCATracker::~AliHLTTPCCATracker()
67 {
68   // destructor
69         if (!fIsGPUTracker)
70         {
71                 if (fCommonMem) delete fCommonMem;
72                 if (fHitMemory) delete[] fHitMemory;
73                 if (fTrackletMemory) delete[] fTrackletMemory;
74                 if (fTrackMemory) delete[] fTrackMemory;
75                 fCommonMem = NULL;
76                 fHitMemory = fTrackMemory = NULL;
77         }
78 }
79
80 // ----------------------------------------------------------------------------------
81 void AliHLTTPCCATracker::Initialize( const AliHLTTPCCAParam &param )
82 {
83   // initialisation
84   fParam = param;
85   fParam.Update();
86   fData.InitializeRows( fParam );
87
88   StartEvent();
89 }
90
91 void AliHLTTPCCATracker::StartEvent()
92 {
93   // start new event and fresh the memory
94
95   SetupCommonMemory();
96 }
97
98 void AliHLTTPCCATracker::SetGPUTracker()
99 {
100         //Make this a GPU Tracker
101         fIsGPUTracker = true;
102         fData.SetGpuSliceData();
103 }
104
105 char* AliHLTTPCCATracker::SetGPUTrackerCommonMemory(char* const pGPUMemory)
106 {
107         //Set up common Memory Pointer for GPU Tracker
108   fCommonMem = (commonMemoryStruct*) pGPUMemory;
109   return(pGPUMemory + sizeof(commonMemoryStruct));
110 }
111
112
113 char* AliHLTTPCCATracker::SetGPUTrackerHitsMemory(char* pGPUMemory, int MaxNHits)
114 {
115         //Set up Hits Memory Pointers for GPU Tracker
116         fHitMemory = (char*) pGPUMemory;
117         SetPointersHits(MaxNHits);
118         pGPUMemory += fHitMemorySize;
119         AssignMemory(fTrackletTmpStartHits, pGPUMemory, NHitsTotal());
120         AssignMemory(fRowStartHitCountOffset, pGPUMemory, Param().NRows());
121
122         return(pGPUMemory);
123 }
124
125 char* AliHLTTPCCATracker::SetGPUTrackerTrackletsMemory(char* pGPUMemory, int MaxNTracks)
126 {
127         //Set up Tracklet Memory Pointers for GPU Tracker
128         fTrackletMemory = (char*) pGPUMemory;
129         SetPointersTracklets(MaxNTracks);
130         pGPUMemory += fTrackletMemorySize;
131         AssignMemory(fGPUTrackletTemp, pGPUMemory, MaxNTracks);
132         AssignMemory(fRowBlockTracklets, pGPUMemory, MaxNTracks * 2 * (Param().NRows() / HLTCA_GPU_SCHED_ROW_STEP + 1));
133         AssignMemory(fRowBlockPos, pGPUMemory, 2 * (Param().NRows() / HLTCA_GPU_SCHED_ROW_STEP + 1));
134         AssignMemory(fBlockStartingTracklet, pGPUMemory, HLTCA_GPU_BLOCK_COUNT);
135
136         return(pGPUMemory);
137 }
138
139 char* AliHLTTPCCATracker::SetGPUTrackerTracksMemory(char* pGPUMemory, int MaxNTracks, int MaxNHits )
140 {
141         //Set up Tracks Memory Pointer for GPU Tracker
142         fTrackMemory = (char*) pGPUMemory;
143         SetPointersTracks(MaxNTracks, MaxNHits);
144         pGPUMemory += fTrackMemorySize;
145
146         return(pGPUMemory);
147 }
148
149 void AliHLTTPCCATracker::DumpSliceData(std::ostream &out)
150 {
151         //Dump Slice Input Data to File
152         out << "Slice Data (Slice" << Param().ISlice() << "):" << std::endl;
153         for (int i = 0;i < Param().NRows();i++)
154         {
155                 out << "Row: " << i << std::endl;
156                 for (int j = 0;j < Row(i).NHits();j++)
157                 {
158                         if (j && j % 16 == 0) out << std::endl;
159                         out << j << '-' << Data().HitDataY(Row(i), j) << '-' << Data().HitDataZ(Row(i), j) << ", ";
160                 }
161                 out << std::endl;
162         }
163 }
164
165 void AliHLTTPCCATracker::DumpLinks(std::ostream &out)
166 {
167         //Dump Links (after Neighbours Finder / Cleaner) to file
168         out << "Hit Links(Slice" << Param().ISlice() << "):" << std::endl;
169         for (int i = 0;i < Param().NRows();i++)
170         {
171                 out << "Row: " << i << std::endl;
172                 for (int j = 0;j < Row(i).NHits();j++)
173                 {
174                         if (j && j % 32 == 0) out << std::endl;
175                         out << HitLinkUpData(Row(i), j) << "/" << HitLinkDownData(Row(i), j) << ", ";
176                 }
177                 out << std::endl;
178         }
179 }
180
181 void AliHLTTPCCATracker::DumpHitWeights(std::ostream &out)
182 {
183         //dump hit weights to file
184     out << "Hit Weights(Slice" << Param().ISlice() << "):" << std::endl;
185     for (int i = 0;i < Param().NRows();i++)
186     {
187         out << "Row: " << i << ":" << std::endl;
188         for (int j = 0;j < Row(i).NHits();j++)
189         {
190             if (j && j % 32 == 0) out << std::endl;
191             out << HitWeight(Row(i), j) << ", ";
192         }
193         out << std::endl;
194     }
195 }
196
197 int AliHLTTPCCATracker::StarthitSortComparison(const void*a, const void* b)
198 {
199         //qsort helper function to sort start hits
200         AliHLTTPCCAHitId* aa = (AliHLTTPCCAHitId*) a;
201         AliHLTTPCCAHitId* bb = (AliHLTTPCCAHitId*) b;
202
203         if (aa->RowIndex() != bb->RowIndex()) return(aa->RowIndex() - bb->RowIndex());
204         return(aa->HitIndex() - bb->HitIndex());
205 }
206
207 void AliHLTTPCCATracker::DumpStartHits(std::ostream &out)
208 {
209         //sort start hits and dump to file
210         out << "Start Hits: (Slice" << Param().ISlice() << ") (" << *NTracklets() << ")" << std::endl;
211 #ifdef HLTCA_GPU_SORT_DUMPDATA
212         qsort(TrackletStartHits(), *NTracklets(), sizeof(AliHLTTPCCAHitId), StarthitSortComparison);
213 #endif
214         for (int i = 0;i < *NTracklets();i++)
215         {
216                 out << TrackletStartHit(i).RowIndex() << "-" << TrackletStartHit(i).HitIndex() << std::endl;
217         }
218         out << std::endl;
219 }
220
221 void AliHLTTPCCATracker::DumpTrackHits(std::ostream &out)
222 {
223         //dump tracks to file
224         out << "Tracks: (Slice" << Param().ISlice() << ") (" << *NTracks() << ")" << std::endl;
225 #ifdef HLTCA_GPU_SORT_DUMPDATA
226         for (int k = 0;k < Param().NRows();k++)
227         {
228                 for (int l = 0;l < Row(k).NHits();l++)
229                 {
230 #endif
231                         for (int j = 0;j < *NTracks();j++)
232                         {
233                                 if (Tracks()[j].NHits() == 0 || !Tracks()[j].Alive()) continue;
234 #ifdef HLTCA_GPU_SORT_DUMPDATA
235                                 if (TrackHits()[Tracks()[j].FirstHitID()].RowIndex() == k && TrackHits()[Tracks()[j].FirstHitID()].HitIndex() == l)
236                                 {
237 #endif
238                                         for (int i = 0;i < Tracks()[j].NHits();i++)
239                                         {
240                                                 out << TrackHits()[Tracks()[j].FirstHitID() + i].RowIndex() << "-" << TrackHits()[Tracks()[j].FirstHitID() + i].HitIndex() << ", ";
241                                         }
242                                         out << "(Track: " << j << ")" << std::endl;
243 #ifdef HLTCA_GPU_SORT_DUMPDATA
244                                 }
245                         }       
246 #endif
247                 }       
248 #ifdef HLTCA_GPU_SORT_DUMPDATA
249         }
250 #endif
251 }
252
253 void AliHLTTPCCATracker::DumpTrackletHits(std::ostream &out)
254 {
255         //dump tracklets to file
256         out << "Tracklets: (Slice" << Param().ISlice() << ") (" << *NTracklets() << ")" << std::endl;
257 #ifdef HLTCA_GPU_SORT_DUMPDATA
258         AliHLTTPCCAHitId* tmpIds = new AliHLTTPCCAHitId[*NTracklets()];
259         AliHLTTPCCATracklet* tmpTracklets = new AliHLTTPCCATracklet[*NTracklets()];
260         memcpy(tmpIds, TrackletStartHits(), *NTracklets() * sizeof(AliHLTTPCCAHitId));
261         memcpy(tmpTracklets, Tracklets(), *NTracklets() * sizeof(AliHLTTPCCATracklet));
262 #ifdef EXTERN_ROW_HITS
263         int* tmpHits = new int[*NTracklets() * Param().NRows()];
264         memcpy(tmpHits, TrackletRowHits(), *NTracklets() * Param().NRows() * sizeof(int));
265 #endif
266         qsort(TrackletStartHits(), *NTracklets(), sizeof(AliHLTTPCCAHitId), StarthitSortComparison);
267         for (int i = 0;i < *NTracklets();i++)
268         {
269                 for (int j = 0;j < *NTracklets();j++)
270                 {
271                         if (tmpIds[i].RowIndex() == TrackletStartHit(j).RowIndex() && tmpIds[i].HitIndex() == TrackletStartHit(j).HitIndex())
272                         {
273                                 memcpy(&Tracklets()[j], &tmpTracklets[i], sizeof(AliHLTTPCCATracklet));
274 #ifdef EXTERN_ROW_HITS
275                                 if (tmpTracklets[i].NHits())
276                                 {
277                                         for (int k = tmpTracklets[i].FirstRow();k <= tmpTracklets[i].LastRow();k++)
278                                         {
279                                                 fTrackletRowHits[k * *NTracklets() + j] = tmpHits[k * *NTracklets() + i];
280                                         }
281                                 }
282 #endif
283                                 break;
284                         }
285                 }
286         }
287         delete[] tmpIds;
288         delete[] tmpTracklets;
289 #ifdef EXTERN_ROW_HITS
290         delete[] tmpHits;
291 #endif
292 #endif
293         for (int j = 0;j < *NTracklets();j++)
294         {
295                 out << "Tracklet " << std::setw(4) << j << " (Hits: " << std::setw(3) << Tracklets()[j].NHits() << ", Start: " << std::setw(3) << TrackletStartHit(j).RowIndex() << "-" << std::setw(3) << TrackletStartHit(j).HitIndex() << ", Rows: " << (Tracklets()[j].NHits() ? Tracklets()[j].FirstRow() : -1) << " - " << (Tracklets()[j].NHits() ? Tracklets()[j].LastRow() : -1) << ") ";
296                 if (Tracklets()[j].NHits() == 0);
297                 else if (Tracklets()[j].LastRow() > Tracklets()[j].FirstRow() && (Tracklets()[j].FirstRow() >= Param().NRows() || Tracklets()[j].LastRow() >= Param().NRows()))
298                 {
299 #ifdef HLTCA_STANDALONE
300                         printf("\nError: Tracklet %d First %d Last %d Hits %d", j, Tracklets()[j].FirstRow(), Tracklets()[j].LastRow(), Tracklets()[j].NHits());
301                         out << " (Error: Tracklet " << j << " First " << Tracklets()[j].FirstRow() << " Last " << Tracklets()[j].LastRow() << " Hits " << Tracklets()[j].NHits() << ") ";
302                         for (int i = 0;i < Param().NRows();i++)
303                         {
304                                 //if (Tracklets()[j].RowHit(i) != -1)
305 #ifdef EXTERN_ROW_HITS
306                                         out << i << "-" << fTrackletRowHits[i * fCommonMem->fNTracklets + j] << ", ";
307 #else
308                                         out << i << "-" << Tracklets()[j].RowHit(i) << ", ";
309 #endif
310                         }
311 #endif
312                 }
313                 else if (Tracklets()[j].NHits() && Tracklets()[j].LastRow() > Tracklets()[j].FirstRow())
314                 {
315                         for (int i = Tracklets()[j].FirstRow();i <= Tracklets()[j].LastRow();i++)
316                         {
317                                 //if (Tracklets()[j].RowHit(i) != -1)
318 #ifdef EXTERN_ROW_HITS
319                                         out << i << "-" << fTrackletRowHits[i * fCommonMem->fNTracklets + j] << ", ";
320 #else
321                                         out << i << "-" << Tracklets()[j].RowHit(i) << ", ";
322 #endif
323                         }
324                 }
325                 out << std::endl;
326         }
327 }
328
329
330 void AliHLTTPCCATracker::SetupCommonMemory()
331 {
332   // set up common memory
333
334   if (!fIsGPUTracker)
335   {
336     if ( !fCommonMem ) {
337       // the 1600 extra bytes are not used unless fCommonMemorySize increases with a later event
338       //fCommonMemory = reinterpret_cast<char*> ( new uint4 [ fCommonMemorySize/sizeof( uint4 ) + 100] );
339           fCommonMem = new commonMemoryStruct;
340     }
341
342         if (fHitMemory) delete[] fHitMemory;
343         if (fTrackletMemory) delete[] fTrackletMemory;
344         if (fTrackMemory) delete[] fTrackMemory;
345   }
346
347   fHitMemory = fTrackletMemory = fTrackMemory = 0;
348
349   fData.Clear();
350   fCommonMem->fNTracklets = 0;
351   fCommonMem->fNTracks = 0 ;
352   fCommonMem->fNTrackHits = 0;
353 }
354
355 void AliHLTTPCCATracker::ReadEvent( AliHLTTPCCAClusterData *clusterData )
356 {
357   // read event
358
359   fClusterData = clusterData;
360
361   StartEvent();
362
363   //* Convert input hits, create grids, etc.
364   fData.InitFromClusterData( *clusterData );
365   {
366     if (!fIsGPUTracker)
367         {
368                 SetPointersHits( fData.NumberOfHits() ); // to calculate the size
369                 fHitMemory = reinterpret_cast<char*> ( new uint4 [ fHitMemorySize/sizeof( uint4 ) + 100] );
370         }
371     SetPointersHits( fData.NumberOfHits() ); // set pointers for hits
372   }
373 }
374
375 GPUhd() void  AliHLTTPCCATracker::SetPointersHits( int MaxNHits )
376 {
377   // set all pointers to the event memory
378
379   char *mem = fHitMemory;
380
381   // extra arrays for tpc clusters
382
383 #ifdef HLTCA_GPU_SORT_STARTHITS_2
384   AssignMemory( fTrackletStartHits, mem, MaxNHits + 32);
385 #else
386   AssignMemory( fTrackletStartHits, mem, MaxNHits);
387 #endif
388
389   // calculate the size
390
391   fHitMemorySize = mem - fHitMemory;
392 }
393
394 GPUhd() void  AliHLTTPCCATracker::SetPointersTracklets( int MaxNTracklets )
395 {
396   // set all pointers to the tracklets memory
397   char *mem = fTrackletMemory;
398
399   // memory for tracklets
400
401   AssignMemory( fTracklets, mem, MaxNTracklets );
402 #ifdef EXTERN_ROW_HITS
403   AssignMemory( fTrackletRowHits, mem, MaxNTracklets * Param().NRows());
404 #endif
405
406   fTrackletMemorySize = mem - fTrackletMemory;
407 }
408
409
410 GPUhd() void  AliHLTTPCCATracker::SetPointersTracks( int MaxNTracks, int MaxNHits )
411 {
412   // set all pointers to the tracks memory
413   char *mem = fTrackMemory;
414
415   // memory for selected tracks
416
417   AssignMemory( fTracks, mem, MaxNTracks );
418   AssignMemory( fTrackHits, mem, 2 * MaxNHits );
419
420   // calculate the size
421
422   fTrackMemorySize = mem - fTrackMemory;
423 }
424
425 GPUh() int AliHLTTPCCATracker::CheckEmptySlice() const
426 {
427         //Check if the Slice is empty, if so set the output apropriate and tell the reconstuct procesdure to terminate
428   if ( NHitsTotal() < 1 ) {
429     {
430       AliHLTTPCCASliceOutput::Allocate(*fOutput, 0, 0, fOutputControl);
431       AliHLTTPCCASliceOutput* useOutput = *fOutput;
432       if (useOutput == NULL) return(1);
433       useOutput->SetNTracks( 0 );
434       useOutput->SetNTrackClusters( 0 );
435     }
436
437     return 1;
438   }
439   return 0;
440 }
441
442 void AliHLTTPCCATracker::RunNeighboursFinder()
443 {
444         //Run the CPU Neighbours Finder
445         AliHLTTPCCAProcess<AliHLTTPCCANeighboursFinder>( Param().NRows(), 1, *this );
446 }
447
448 void AliHLTTPCCATracker::RunNeighboursCleaner()
449 {
450         //Run the CPU Neighbours Cleaner
451         AliHLTTPCCAProcess<AliHLTTPCCANeighboursCleaner>( Param().NRows() - 2, 1, *this );
452 }
453
454 void AliHLTTPCCATracker::RunStartHitsFinder()
455 {
456         //Run the CPU Start Hits Finder
457         AliHLTTPCCAProcess<AliHLTTPCCAStartHitsFinder>( Param().NRows() - 4, 1, *this );
458 }
459
460 void AliHLTTPCCATracker::RunTrackletConstructor()
461 {
462         //Run CPU Tracklet Constructor
463   AliHLTTPCCATrackletConstructor::AliHLTTPCCATrackletConstructorCPU(*this);
464 }
465
466 void AliHLTTPCCATracker::RunTrackletSelector()
467 {
468         //Run CPU Tracklet Selector
469   AliHLTTPCCAProcess<AliHLTTPCCATrackletSelector>( 1, fCommonMem->fNTracklets, *this );
470 }
471
472 #ifdef HLTCA_STANDALONE
473 void AliHLTTPCCATracker::StandalonePerfTime(int i)
474 {
475   //Query Performance Timer for Standalone Version of Tracker
476   if (fGPUDebugLevel >= 1)
477   {
478     AliHLTTPCCAStandaloneFramework::StandaloneQueryTime(&fPerfTimers[i]);
479   }
480 }
481 #else
482 void AliHLTTPCCATracker::StandalonePerfTime(int /*i*/) {}
483 #endif
484
485 GPUh() void AliHLTTPCCATracker::Reconstruct()
486 {
487   //* reconstruction of event
488   //std::cout<<"Reconstruct slice "<<fParam.ISlice()<<", nHits="<<NHitsTotal()<<std::endl;
489
490   fTimers[0] = 0; // find neighbours
491   fTimers[1] = 0; // construct tracklets
492   fTimers[2] = 0; // fit tracklets
493   fTimers[3] = 0; // prolongation of tracklets
494   fTimers[4] = 0; // selection
495   fTimers[5] = 0; // write output
496   fTimers[6] = 0;
497   fTimers[7] = 0;
498
499   //if( fParam.ISlice()<1 ) return; //SG!!!
500
501   TStopwatch timer0;
502
503   StandalonePerfTime(0);
504
505   if (CheckEmptySlice()) return;
506
507 #ifdef DRAW1
508   //if( fParam.ISlice()==2 || fParam.ISlice()==3)
509     {
510   AliHLTTPCCADisplay::Instance().ClearView();
511   AliHLTTPCCADisplay::Instance().SetSliceView();
512   AliHLTTPCCADisplay::Instance().SetCurrentSlice( this );
513   AliHLTTPCCADisplay::Instance().DrawSlice( this, 1 );
514   if ( NHitsTotal() > 0 ) {
515     AliHLTTPCCADisplay::Instance().DrawSliceHits( kRed, .5 );
516     AliHLTTPCCADisplay::Instance().Ask();
517   }
518   }
519 #endif //DRAW1
520
521         fCommonMem->fNTracklets = fCommonMem->fNTracks = fCommonMem->fNTrackHits = 0;
522
523 #if !defined(HLTCA_GPUCODE)
524
525   if (fGPUDebugLevel >= 6)
526   {
527           *fGPUDebugOut << std::endl << std::endl << "Slice: " << Param().ISlice() << std::endl;
528           *fGPUDebugOut << "Slice Data:" << std::endl;
529           DumpSliceData(*fGPUDebugOut);
530   }
531
532   StandalonePerfTime(1);
533
534   RunNeighboursFinder();
535
536   StandalonePerfTime(2);
537
538 #ifdef TRACKER_KEEP_TEMPDATA
539   if (fLinkTmpMemory) delete[] fLinkTmpMemory;
540   fLinkTmpMemory = new char[fData.MemorySize()];
541   memcpy(fLinkTmpMemory, fData.Memory(), fData.MemorySize());
542 #endif
543
544   if (fGPUDebugLevel >= 6) DumpLinks(*fGPUDebugOut);
545   
546 #ifdef HLTCA_INTERNAL_PERFORMANCE
547   //if( Param().ISlice()<=2 )
548   //AliHLTTPCCAPerformance::Instance().LinkPerformance( Param().ISlice() );
549 #endif
550
551
552 #ifdef DRAW1
553   if ( NHitsTotal() > 0 ) {
554     AliHLTTPCCADisplay::Instance().DrawSliceLinks( -1, -1, 1 );
555     AliHLTTPCCADisplay::Instance().Ask();
556   }
557 #endif //DRAW1
558
559   RunNeighboursCleaner();
560
561   StandalonePerfTime(3);
562
563   if (fGPUDebugLevel >= 6) DumpLinks(*fGPUDebugOut);
564
565   RunStartHitsFinder();
566
567   StandalonePerfTime(4);
568   StandalonePerfTime(5);
569
570   if (fGPUDebugLevel >= 6) DumpStartHits(*fGPUDebugOut);
571   
572   fData.ClearHitWeights();
573
574   SetPointersTracklets( fCommonMem->fNTracklets * 2 ); // to calculate the size
575   fTrackletMemory = reinterpret_cast<char*> ( new uint4 [ fTrackletMemorySize/sizeof( uint4 ) + 100] );
576   SetPointersTracklets( fCommonMem->fNTracklets * 2 ); // set pointers for hits
577
578   SetPointersTracks( fCommonMem->fNTracklets * 2, NHitsTotal() ); // to calculate the size
579   fTrackMemory = reinterpret_cast<char*> ( new uint4 [ fTrackMemorySize/sizeof( uint4 ) + 100] );
580   SetPointersTracks( fCommonMem->fNTracklets * 2, NHitsTotal() ); // set pointers for hits
581
582   StandalonePerfTime(6);
583   StandalonePerfTime(7);
584
585   RunTrackletConstructor();
586
587   StandalonePerfTime(8);
588
589   if (fGPUDebugLevel >= 6) DumpTrackletHits(*fGPUDebugOut);
590   if (fGPUDebugLevel >= 6) DumpHitWeights(*fGPUDebugOut);
591
592   //std::cout<<"Slice "<<Param().ISlice()<<": NHits="<<NHitsTotal()<<", NTracklets="<<*NTracklets()<<std::endl;
593
594   RunTrackletSelector();
595
596   StandalonePerfTime(9);
597
598   //std::cout<<"Slice "<<Param().ISlice()<<": N start hits/tracklets/tracks = "<<nStartHits<<" "<<nStartHits<<" "<<*fNTracks<<std::endl;
599
600   if (fGPUDebugLevel >= 6) DumpTrackHits(*fGPUDebugOut);
601
602   //std::cout<<"Memory used for slice "<<fParam.ISlice()<<" : "<<fCommonMemorySize/1024./1024.<<" + "<<fHitMemorySize/1024./1024.<<" + "<<fTrackMemorySize/1024./1024.<<" = "<<( fCommonMemorySize+fHitMemorySize+fTrackMemorySize )/1024./1024.<<" Mb "<<std::endl;
603
604   WriteOutput();
605
606   StandalonePerfTime(10);
607
608 #endif
609
610 #ifdef DRAW1
611   {
612     AliHLTTPCCADisplay &disp = AliHLTTPCCADisplay::Instance();
613     AliHLTTPCCATracker &slice = *this;
614     std::cout << "N out tracks = " << slice.NOutTracks() << std::endl;
615     AliHLTTPCCADisplay::Instance().SetSliceView();
616     AliHLTTPCCADisplay::Instance().SetCurrentSlice( this );
617     AliHLTTPCCADisplay::Instance().DrawSlice( this, 1 );
618     disp.DrawSliceHits( kRed, .5 );
619     disp.Ask();
620     for ( int itr = 0; itr < slice.NOutTracks(); itr++ ) {
621       std::cout << "track N " << itr << ", nhits=" << slice.OutTracks()[itr].NHits() << std::endl;
622       disp.DrawSliceOutTrack( itr, kBlue );      
623       //disp.Ask();
624       //int id = slice.OutTracks()[itr].OrigTrackID();
625       //AliHLTTPCCATrack &tr = Tracks()[id];
626       //for( int ih=0; ih<tr.NHits(); ih++ ){
627       //int ic = (fTrackHits[tr.FirstHitID()+ih]);
628       //std::cout<<ih<<" "<<ID2IRow(ic)<<" "<<ID2IHit(ic)<<std::endl;
629       //}
630       //disp.DrawSliceTrack( id, kBlue );
631       //disp.Ask();
632     }
633     disp.Ask();
634   }
635 #endif //DRAW1
636
637   timer0.Stop();
638   fTimers[0] = timer0.CpuTime() / 100.;
639
640 }
641
642 GPUh() void AliHLTTPCCATracker::WriteOutput()
643 {
644   // write output
645
646   TStopwatch timer;
647
648   //cout<<"output: nTracks = "<<*fNTracks<<", nHitsTotal="<<NHitsTotal()<<std::endl;
649   
650   if (fOutputControl == NULL) fOutputControl = new AliHLTTPCCASliceOutput::outputControlStruct;
651   AliHLTTPCCASliceOutput::Allocate(*fOutput, fCommonMem->fNTracks, fCommonMem->fNTrackHits, fOutputControl);
652   AliHLTTPCCASliceOutput* useOutput = *fOutput;
653   if (useOutput == NULL) return;
654
655   useOutput->SetNTracks( 0 );
656   useOutput->SetNTrackClusters( 0 );
657
658   int nStoredHits = 0;
659   int nStoredTracks = 0;
660
661   AliHLTTPCCASliceOutTrack *out = useOutput->FirstTrack();
662
663   for ( int iTr = 0; iTr < fCommonMem->fNTracks; iTr++ ) {
664     AliHLTTPCCATrack &iTrack = fTracks[iTr];    
665     
666     if( iTrack.NHits() < fParam.MinNTrackClusters() ) continue;
667     if( CAMath::Abs(iTrack.Param().GetQPt())> fParam.MaxTrackQPt() ) continue;
668
669     out->SetParam( iTrack.Param() );
670     int nClu = 0;
671     int iID = iTrack.FirstHitID();
672
673     for ( int ith = 0; ith < iTrack.NHits(); ith++ ) {
674       const AliHLTTPCCAHitId &ic = fTrackHits[iID + ith];
675       int iRow = ic.RowIndex();
676       int ih = ic.HitIndex();
677       
678       const AliHLTTPCCARow &row = fData.Row( iRow );
679       
680       int clusterIndex = fData.ClusterDataIndex( row, ih );
681       int clusterRowIndex = clusterIndex - fClusterData->RowOffset( iRow );
682       
683       if ( clusterIndex < 0 || clusterIndex >= fClusterData->NumberOfClusters() ) {
684         //std::cout << inpIDtot << ", " << fClusterData->NumberOfClusters()
685         //<< "; " << inpID << ", " << fClusterData->NumberOfClusters( iRow ) << std::endl;
686         //abort();
687         continue;
688       }
689       if ( clusterRowIndex < 0 || clusterRowIndex >= fClusterData->NumberOfClusters( iRow ) ) {
690         //std::cout << inpIDtot << ", " << fClusterData->NumberOfClusters()
691         //<< "; " << inpID << ", " << fClusterData->NumberOfClusters( iRow ) << std::endl;
692         //abort();
693         continue;
694       }
695       
696       float origX = fClusterData->X( clusterIndex );
697       float origY = fClusterData->Y( clusterIndex );
698       float origZ = fClusterData->Z( clusterIndex );      
699       int id = fClusterData->Id( clusterIndex );
700       AliHLTTPCCASliceOutCluster c;
701       c.Set( id, iRow, origX, origY, origZ );
702       out->SetCluster( nClu, c );
703       nClu++;
704     }
705
706     nStoredTracks++;
707     nStoredHits+=nClu; 
708     out->SetNClusters( nClu );
709     out = out->NextTrack();    
710   }
711
712   useOutput->SetNTracks( nStoredTracks );
713   useOutput->SetNTrackClusters( nStoredHits );
714
715   timer.Stop();
716   fTimers[5] += timer.CpuTime();
717 }
718
719 #endif
720
721 GPUh() void AliHLTTPCCATracker::FitTrackFull( const AliHLTTPCCATrack &/**/, float * /**/ ) const
722 {
723   // fit track with material
724 #ifdef XXX
725   //* Fit the track
726   FitTrack( iTrack, tt0 );
727   if ( iTrack.NHits() <= 3 ) return;
728
729   AliHLTTPCCATrackParam &t = iTrack.Param();
730   AliHLTTPCCATrackParam t0 = t;
731
732   t.Chi2() = 0;
733   t.NDF() = -5;
734   bool first = 1;
735
736   int iID = iTrack.FirstHitID();
737   for ( int ih = 0; ih < iTrack.NHits(); ih++, iID++ ) {
738     const AliHLTTPCCAHitId &ic = fTrackHits[iID];
739     int iRow = ic.rowIndex();
740     const AliHLTTPCCARow &row = fData.Row( iRow );
741     if ( !t0.TransportToX( row.X() ) ) continue;
742     float dy, dz;
743     const AliHLTTPCCAHit &h = ic.hitIndex();
744
745     // check for wrong hits
746     if ( 0 ) {
747       dy = t0.GetY() - h.Y();
748       dz = t0.GetZ() - h.Z();
749
750       //if( dy*dy > 3.5*3.5*(/*t0.GetErr2Y() + */h.ErrY()*h.ErrY() ) ) continue;//SG!!!
751       //if( dz*dz > 3.5*3.5*(/*t0.GetErr2Z() + */h.ErrZ()*h.ErrZ() ) ) continue;
752     }
753
754     if ( !t.TransportToX( row.X() ) ) continue;
755
756     //* Update the track
757
758     if ( first ) {
759       t.Cov()[ 0] = .5 * .5;
760       t.Cov()[ 1] = 0;
761       t.Cov()[ 2] = .5 * .5;
762       t.Cov()[ 3] = 0;
763       t.Cov()[ 4] = 0;
764       t.Cov()[ 5] = .2 * .2;
765       t.Cov()[ 6] = 0;
766       t.Cov()[ 7] = 0;
767       t.Cov()[ 8] = 0;
768       t.Cov()[ 9] = .2 * .2;
769       t.Cov()[10] = 0;
770       t.Cov()[11] = 0;
771       t.Cov()[12] = 0;
772       t.Cov()[13] = 0;
773       t.Cov()[14] = .2 * .2;
774       t.Chi2() = 0;
775       t.NDF() = -5;
776     }
777     float err2Y, err2Z;
778     GetErrors2( iRow, t, err2Y, err2Z );
779
780     if ( !t.Filter2( h.Y(), h.Z(), err2Y, err2Z ) ) continue;
781
782     first = 0;
783   }
784   /*
785   float cosPhi = iTrack.Param().GetCosPhi();
786   p0.Param().TransportToX(ID2Row( iTrack.PointID()[0] ).X());
787   p2.Param().TransportToX(ID2Row( iTrack.PointID()[1] ).X());
788   if( p0.Param().GetCosPhi()*cosPhi<0 ){ // change direction
789   float *par = p0.Param().Par();
790   float *cov = p0.Param().Cov();
791   par[2] = -par[2]; // sin phi
792   par[3] = -par[3]; // DzDs
793     par[4] = -par[4]; // kappa
794     cov[3] = -cov[3];
795     cov[4] = -cov[4];
796     cov[6] = -cov[6];
797     cov[7] = -cov[7];
798     cov[10] = -cov[10];
799     cov[11] = -cov[11];
800     p0.Param().CosPhi() = -p0.Param().GetCosPhi();
801   }
802   */
803 #endif
804 }
805
806 GPUh() void AliHLTTPCCATracker::FitTrack( const AliHLTTPCCATrack &/*track*/, float * /*t0[]*/ ) const
807 {
808   //* Fit the track
809 #ifdef XXX
810   AliHLTTPCCAEndPoint &p2 = ID2Point( track.PointID()[1] );
811   const AliHLTTPCCAHit &c0 = ID2Hit( fTrackHits[p0.TrackHitID()].HitID() );
812   const AliHLTTPCCAHit &c1 = ID2Hit( fTrackHits[track.HitID()[1]].HitID() );
813   const AliHLTTPCCAHit &c2 = ID2Hit( fTrackHits[p2.TrackHitID()].HitID() );
814   const AliHLTTPCCARow &row0 = ID2Row( fTrackHits[p0.TrackHitID()].HitID() );
815   const AliHLTTPCCARow &row1 = ID2Row( fTrackHits[track.HitID()[1]].HitID() );
816   const AliHLTTPCCARow &row2 = ID2Row( fTrackHits[p2.TrackHitID()].HitID() );
817   float sp0[5] = {row0.X(), c0.Y(), c0.Z(), c0.ErrY(), c0.ErrZ() };
818   float sp1[5] = {row1.X(), c1.Y(), c1.Z(), c1.ErrY(), c1.ErrZ() };
819   float sp2[5] = {row2.X(), c2.Y(), c2.Z(), c2.ErrY(), c2.ErrZ() };
820   //std::cout<<"Fit track, points ="<<sp0[0]<<" "<<sp0[1]<<" / "<<sp1[0]<<" "<<sp1[1]<<" / "<<sp2[0]<<" "<<sp2[1]<<std::endl;
821   if ( track.NHits() >= 3 ) {
822     p0.Param().ConstructXYZ3( sp0, sp1, sp2, p0.Param().CosPhi(), t0 );
823     p2.Param().ConstructXYZ3( sp2, sp1, sp0, p2.Param().CosPhi(), t0 );
824     //p2.Param() = p0.Param();
825     //p2.Param().TransportToX(row2.X());
826     //p2.Param().Par()[1] = -p2.Param().Par()[1];
827     //p2.Param().Par()[4] = -p2.Param().Par()[4];
828   } else {
829     p0.Param().X() = row0.X();
830     p0.Param().Y() = c0.Y();
831     p0.Param().Z() = c0.Z();
832     p0.Param().Err2Y() = c0.ErrY() * c0.ErrY();
833     p0.Param().Err2Z() = c0.ErrZ() * c0.ErrZ();
834     p2.Param().X() = row2.X();
835     p2.Param().Y() = c2.Y();
836     p2.Param().Z() = c2.Z();
837     p2.Param().Err2Y() = c2.ErrY() * c2.ErrY();
838     p2.Param().Err2Z() = c2.ErrZ() * c2.ErrZ();
839   }
840 #endif
841 }
842
843
844 GPUdi() void AliHLTTPCCATracker::GetErrors2( int iRow, float z, float sinPhi, float cosPhi, float DzDs, float &Err2Y, float &Err2Z ) const
845 {
846   //
847   // Use calibrated cluster error from OCDB
848   //
849
850   fParam.GetClusterErrors2( iRow, z, sinPhi, cosPhi, DzDs, Err2Y, Err2Z );
851   Err2Y*=fParam.ClusterError2CorrectionY();
852   Err2Z*=fParam.ClusterError2CorrectionZ();
853 }
854
855 GPUdi() void AliHLTTPCCATracker::GetErrors2( int iRow, const AliHLTTPCCATrackParam &t, float &Err2Y, float &Err2Z ) const
856 {
857   //
858   // Use calibrated cluster error from OCDB
859   //
860
861   fParam.GetClusterErrors2( iRow, t.GetZ(), t.SinPhi(), t.GetCosPhi(), t.DzDs(), Err2Y, Err2Z );
862 }
863
864
865 #if !defined(HLTCA_GPUCODE)
866
867 GPUh() void AliHLTTPCCATracker::WriteEvent( std::ostream &out )
868 {
869   // write event to the file
870   for ( int iRow = 0; iRow < fParam.NRows(); iRow++ ) {
871     out << fData.Row( iRow ).HitNumberOffset() << " " << fData.Row( iRow ).NHits() << std::endl;
872   }
873   out << NHitsTotal() << std::endl;
874
875   AliHLTResizableArray<float> y( NHitsTotal() ), z( NHitsTotal() );
876
877   for ( int iRow = 0; iRow < fParam.NRows(); iRow++ ) {
878     const AliHLTTPCCARow &row = Row( iRow );
879     float y0 = row.Grid().YMin();
880     float z0 = row.Grid().ZMin();
881     float stepY = row.HstepY();
882     float stepZ = row.HstepZ();
883     for ( int ih = 0; ih < fData.Row( iRow ).NHits(); ih++ ) {
884       int id = HitInputID( row, ih );
885       y[id] = y0 + HitDataY( row, ih ) * stepY;
886       z[id] = z0 + HitDataZ( row, ih ) * stepZ;
887     }
888   }
889   for ( int ih = 0; ih < NHitsTotal(); ih++ ) {
890     out << y[ih] << " " << z[ih] << std::endl;
891   }
892 }
893
894 GPUh() void AliHLTTPCCATracker::WriteTracks( std::ostream &/*out*/ )
895 {
896   //* Write tracks to file --- dummy
897 }
898
899 GPUh() void AliHLTTPCCATracker::ReadTracks( std::istream &/*in*/ )
900 {
901   //* Read tracks  from file -- dummy
902 }
903 #endif