]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/tracking-ca/AliHLTTPCCATracker.cxx
OpenCL version of the HLT tracker added (the new code is not used in standard compila...
[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 #include <cmath>
46 #endif
47
48 //#define DRAW1
49
50 #ifdef DRAW1
51 #include "AliHLTTPCCADisplay.h"
52 #endif //DRAW1
53
54 #ifdef HLTCA_INTERNAL_PERFORMANCE
55 //#include "AliHLTTPCCAPerformance.h"
56 #endif
57
58 ClassImp( AliHLTTPCCATracker )
59
60 #if !defined(__OPENCL__) || defined(HLTCA_HOSTCODE)
61
62 #if !defined(HLTCA_GPUCODE)
63
64 AliHLTTPCCATracker::~AliHLTTPCCATracker()
65 {
66         // destructor
67         if (!fIsGPUTracker)
68         {
69                 if (fCommonMem) delete fCommonMem;
70                 if (fHitMemory) delete[] fHitMemory;
71                 if (fTrackletMemory) delete[] fTrackletMemory;
72                 if (fTrackMemory) delete[] fTrackMemory;
73                 fCommonMem = NULL;
74                 fHitMemory = fTrackMemory = NULL;
75         }
76 #ifdef HLTCA_STANDALONE
77         if (fLinkTmpMemory) delete[] fLinkTmpMemory;
78 #endif
79 }
80
81 // ----------------------------------------------------------------------------------
82 void AliHLTTPCCATracker::Initialize( const AliHLTTPCCAParam &param )
83 {
84         // initialisation
85         fParam = param;
86         fParam.Update();
87         fData.InitializeRows( fParam );
88
89         StartEvent();
90 }
91
92 void AliHLTTPCCATracker::StartEvent()
93 {
94         // start new event and fresh the memory
95
96         SetupCommonMemory();
97 }
98
99 void AliHLTTPCCATracker::SetGPUTracker()
100 {
101         //Make this a GPU Tracker
102         fIsGPUTracker = true;
103         fData.SetGpuSliceData();
104 }
105
106 char* AliHLTTPCCATracker::SetGPUTrackerCommonMemory(char* const pGPUMemory)
107 {
108         //Set up common Memory Pointer for GPU Tracker
109         fCommonMem = (commonMemoryStruct*) pGPUMemory;
110         return(pGPUMemory + sizeof(commonMemoryStruct));
111 }
112
113
114 char* AliHLTTPCCATracker::SetGPUTrackerHitsMemory(char* pGPUMemory, int MaxNHits)
115 {
116         //Set up Hits Memory Pointers for GPU Tracker
117         fHitMemory = (char*) pGPUMemory;
118         SetPointersHits(MaxNHits);
119         pGPUMemory += fHitMemorySize;
120         AssignMemory(fTrackletTmpStartHits, pGPUMemory, NHitsTotal());
121         AssignMemory(fRowStartHitCountOffset, pGPUMemory, Param().NRows());
122
123         return(pGPUMemory);
124 }
125
126 char* AliHLTTPCCATracker::SetGPUTrackerTrackletsMemory(char* pGPUMemory, int MaxNTracks, int 
127 #ifndef HLTCA_GPU_ALTERNATIVE_SCHEDULER
128 constructorBlockCount
129 #endif
130 )
131 {
132         //Set up Tracklet Memory Pointers for GPU Tracker
133         fTrackletMemory = (char*) pGPUMemory;
134         SetPointersTracklets(MaxNTracks);
135         pGPUMemory += fTrackletMemorySize;
136 #ifndef HLTCA_GPU_ALTERNATIVE_SCHEDULER
137         AssignMemory(fGPUTrackletTemp, pGPUMemory, MaxNTracks);
138         AssignMemory(fRowBlockTracklets, pGPUMemory, MaxNTracks * 2 * (Param().NRows() / HLTCA_GPU_SCHED_ROW_STEP + 1));
139         AssignMemory(fRowBlockPos, pGPUMemory, 2 * (Param().NRows() / HLTCA_GPU_SCHED_ROW_STEP + 1));
140         AssignMemory(fBlockStartingTracklet, pGPUMemory, constructorBlockCount);
141 #endif
142
143         return(pGPUMemory);
144 }
145
146 char* AliHLTTPCCATracker::SetGPUTrackerTracksMemory(char* pGPUMemory, int MaxNTracks, int MaxNHits )
147 {
148         //Set up Tracks Memory Pointer for GPU Tracker
149         fTrackMemory = (char*) pGPUMemory;
150         SetPointersTracks(MaxNTracks, MaxNHits);
151         pGPUMemory += fTrackMemorySize;
152
153         return(pGPUMemory);
154 }
155
156 void AliHLTTPCCATracker::DumpOutput(FILE* out)
157 {
158         fprintf(out, "Slice %d\n", fParam.ISlice());
159         const AliHLTTPCCASliceOutTrack* track = (*(Output()))->GetFirstTrack();
160         for (int j = 0;j < (*(Output()))->NTracks();j++)
161         {
162                 fprintf(out, "Track %d (%d): ", j, track->NClusters());
163                 for (int k = 0;k < track->NClusters();k++)
164                 {
165                         fprintf(out, "(%2.3f,%2.3f,%2.4f) ", track->Cluster(k).GetX(), track->Cluster(k).GetY(), track->Cluster(k).GetZ());
166                 }
167                 fprintf(out, " - (%8.5f %8.5f %8.5f %8.5f %8.5f)", track->Param().Y(), track->Param().Z(), track->Param().SinPhi(), track->Param().DzDs(), track->Param().QPt());
168                 fprintf(out, "\n");
169                 track = track->GetNextTrack();
170         }
171 }
172
173 void AliHLTTPCCATracker::DumpSliceData(std::ostream &out)
174 {
175         //Dump Slice Input Data to File
176         out << "Slice Data (Slice" << Param().ISlice() << "):" << std::endl;
177         for (int i = 0;i < Param().NRows();i++)
178         {
179                 if (Row(i).NHits() == 0) continue;
180                 out << "Row: " << i << std::endl;
181                 for (int j = 0;j < Row(i).NHits();j++)
182                 {
183                         if (j && j % 16 == 0) out << std::endl;
184                         out << j << '-' << Data().HitDataY(Row(i), j) << '-' << Data().HitDataZ(Row(i), j) << ", ";
185                 }
186                 out << std::endl;
187         }
188 }
189
190 void AliHLTTPCCATracker::DumpLinks(std::ostream &out)
191 {
192         //Dump Links (after Neighbours Finder / Cleaner) to file
193         out << "Hit Links(Slice" << Param().ISlice() << "):" << std::endl;
194         for (int i = 0;i < Param().NRows();i++)
195         {
196                 if (Row(i).NHits() == 0) continue;
197                 out << "Row: " << i << std::endl;
198                 for (int j = 0;j < Row(i).NHits();j++)
199                 {
200                         if (j && j % 32 == 0) out << std::endl;
201                         out << HitLinkUpData(Row(i), j) << "/" << HitLinkDownData(Row(i), j) << ", ";
202                 }
203                 out << std::endl;
204         }
205 }
206
207 void AliHLTTPCCATracker::DumpHitWeights(std::ostream &out)
208 {
209         //dump hit weights to file
210         out << "Hit Weights(Slice" << Param().ISlice() << "):" << std::endl;
211         for (int i = 0;i < Param().NRows();i++)
212         {
213                 if (Row(i).NHits() == 0) continue;
214                 out << "Row: " << i << ":" << std::endl;
215                 for (int j = 0;j < Row(i).NHits();j++)
216                 {
217                         if (j && j % 32 == 0) out << std::endl;
218                         out << HitWeight(Row(i), j) << ", ";
219                 }
220                 out << std::endl;
221         }
222 }
223
224 int AliHLTTPCCATracker::StarthitSortComparison(const void*a, const void* b)
225 {
226         //qsort helper function to sort start hits
227         AliHLTTPCCAHitId* aa = (AliHLTTPCCAHitId*) a;
228         AliHLTTPCCAHitId* bb = (AliHLTTPCCAHitId*) b;
229
230         if (aa->RowIndex() != bb->RowIndex()) return(aa->RowIndex() - bb->RowIndex());
231         return(aa->HitIndex() - bb->HitIndex());
232 }
233
234 void AliHLTTPCCATracker::DumpStartHits(std::ostream &out)
235 {
236         //sort start hits and dump to file
237         out << "Start Hits: (Slice" << Param().ISlice() << ") (" << *NTracklets() << ")" << std::endl;
238 #ifdef HLTCA_GPU_SORT_DUMPDATA
239         qsort(TrackletStartHits(), *NTracklets(), sizeof(AliHLTTPCCAHitId), StarthitSortComparison);
240 #endif
241         for (int i = 0;i < *NTracklets();i++)
242         {
243                 out << TrackletStartHit(i).RowIndex() << "-" << TrackletStartHit(i).HitIndex() << std::endl;
244         }
245         out << std::endl;
246 }
247
248 void AliHLTTPCCATracker::DumpTrackHits(std::ostream &out)
249 {
250         //dump tracks to file
251         out << "Tracks: (Slice" << Param().ISlice() << ") (" << *NTracks() << ")" << std::endl;
252 #ifdef HLTCA_GPU_SORT_DUMPDATA
253         for (int k = 0;k < Param().NRows();k++)
254         {
255                 for (int l = 0;l < Row(k).NHits();l++)
256                 {
257 #endif
258                         for (int j = 0;j < *NTracks();j++)
259                         {
260                                 if (Tracks()[j].NHits() == 0 || !Tracks()[j].Alive()) continue;
261 #ifdef HLTCA_GPU_SORT_DUMPDATA
262                                 if (TrackHits()[Tracks()[j].FirstHitID()].RowIndex() == k && TrackHits()[Tracks()[j].FirstHitID()].HitIndex() == l)
263                                 {
264 #endif
265                                         for (int i = 0;i < Tracks()[j].NHits();i++)
266                                         {
267                                                 out << TrackHits()[Tracks()[j].FirstHitID() + i].RowIndex() << "-" << TrackHits()[Tracks()[j].FirstHitID() + i].HitIndex() << ", ";
268                                         }
269 #ifndef BITWISE_COMPATIBLE_DEBUG_OUTPUT
270                                         out << "(Track: " << j << ")";
271 #endif
272                                         out << std::endl;
273 #ifdef HLTCA_GPU_SORT_DUMPDATA
274                                 }
275                         }       
276 #endif
277                 }       
278 #ifdef HLTCA_GPU_SORT_DUMPDATA
279         }
280 #endif
281 }
282
283 void AliHLTTPCCATracker::DumpTrackletHits(std::ostream &out)
284 {
285         //dump tracklets to file
286         int nTracklets = *NTracklets();
287         if( nTracklets<0 ) nTracklets = 0;
288         if( nTracklets>HLTCA_GPU_MAX_TRACKLETS ) nTracklets = HLTCA_GPU_MAX_TRACKLETS;
289         out << "Tracklets: (Slice" << Param().ISlice() << ") (" << nTracklets << ")" << std::endl;
290 #ifdef HLTCA_GPU_SORT_DUMPDATA
291         AliHLTTPCCAHitId* tmpIds = new AliHLTTPCCAHitId[nTracklets];
292         AliHLTTPCCATracklet* tmpTracklets = new AliHLTTPCCATracklet[nTracklets];
293         memcpy(tmpIds, TrackletStartHits(), nTracklets * sizeof(AliHLTTPCCAHitId));
294         memcpy(tmpTracklets, Tracklets(), nTracklets * sizeof(AliHLTTPCCATracklet));
295 #ifdef EXTERN_ROW_HITS
296         int* tmpHits = new int[nTracklets * Param().NRows()];
297         memcpy(tmpHits, TrackletRowHits(), nTracklets * Param().NRows() * sizeof(int));
298 #endif
299         qsort(TrackletStartHits(), nTracklets, sizeof(AliHLTTPCCAHitId), StarthitSortComparison);
300         for (int i = 0;i < nTracklets; i++ ){
301                 for (int j = 0;j < nTracklets; j++ ){
302                         if (tmpIds[i].RowIndex() == TrackletStartHit(j).RowIndex() && tmpIds[i].HitIndex() == TrackletStartHit(j).HitIndex() ){
303                                 memcpy(&Tracklets()[j], &tmpTracklets[i], sizeof(AliHLTTPCCATracklet));
304 #ifdef EXTERN_ROW_HITS
305                                 if (tmpTracklets[i].NHits() ){
306                                         for (int k = tmpTracklets[i].FirstRow();k <= tmpTracklets[i].LastRow();k++){
307                                                 const int pos = k * nTracklets + j;
308                                                 if (pos < 0 || pos >= HLTCA_GPU_MAX_TRACKLETS * fParam.NRows()){
309                                                         printf("internal error\n");           
310                                                 } else {
311                                                         fTrackletRowHits[pos] = tmpHits[k * nTracklets + i];
312                                                 }
313                                         }
314                                 }
315 #endif
316                                 break;
317                         }
318                 }
319         }
320         delete[] tmpIds;
321         delete[] tmpTracklets;
322 #ifdef EXTERN_ROW_HITS
323         delete[] tmpHits;
324 #endif
325 #endif
326         for (int j = 0;j < nTracklets; j++ )
327         {
328                 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) << ") ";
329                 if (Tracklets()[j].NHits() == 0);
330                 else if (Tracklets()[j].LastRow() > Tracklets()[j].FirstRow() && (Tracklets()[j].FirstRow() >= Param().NRows() || Tracklets()[j].LastRow() >= Param().NRows()))
331                 {
332 #ifdef HLTCA_STANDALONE
333                         printf("\nError: Tracklet %d First %d Last %d Hits %d", j, Tracklets()[j].FirstRow(), Tracklets()[j].LastRow(), Tracklets()[j].NHits());
334                         out << " (Error: Tracklet " << j << " First " << Tracklets()[j].FirstRow() << " Last " << Tracklets()[j].LastRow() << " Hits " << Tracklets()[j].NHits() << ") ";
335                         for (int i = 0;i < Param().NRows();i++)
336                         {
337                                 //if (Tracklets()[j].RowHit(i) != -1)
338 #ifdef EXTERN_ROW_HITS
339                                 out << i << "-" << fTrackletRowHits[i * fCommonMem->fNTracklets + j] << ", ";
340 #else
341                                 out << i << "-" << Tracklets()[j].RowHit(i) << ", ";
342 #endif
343                         }
344 #endif
345                 }
346                 else if (Tracklets()[j].NHits() && Tracklets()[j].LastRow() > Tracklets()[j].FirstRow())
347                 {
348                         int nHits = 0;;
349                         for (int i = Tracklets()[j].FirstRow();i <= Tracklets()[j].LastRow();i++)
350                         {
351 #ifdef EXTERN_ROW_HITS
352                                 if (fTrackletRowHits[i * fCommonMem->fNTracklets + j] != -1)
353 #else
354                                 if (Tracklets()[j].RowHit(i) != -1)
355 #endif
356                                 {
357                                         nHits++;
358                                 }
359 #ifdef EXTERN_ROW_HITS
360                                 out << i << "-" << fTrackletRowHits[i * fCommonMem->fNTracklets + j] << ", ";
361 #else
362                                 out << i << "-" << Tracklets()[j].RowHit(i) << ", ";
363 #endif
364                         }
365                         if (nHits != Tracklets()[j].NHits())
366                         {
367                                 out << std::endl << "Wrong NHits!: Expected " << Tracklets()[j].NHits() << ", fount " << nHits;
368                         }
369                 }
370                 out << std::endl;
371         }
372 }
373
374
375 void AliHLTTPCCATracker::SetupCommonMemory()
376 {
377         // set up common memory
378
379         if (!fIsGPUTracker)
380         {
381                 if ( !fCommonMem ) {
382                         // the 1600 extra bytes are not used unless fCommonMemorySize increases with a later event
383                         //fCommonMemory = reinterpret_cast<char*> ( new uint4 [ fCommonMemorySize/sizeof( uint4 ) + 100] );
384                         fCommonMem = new commonMemoryStruct;
385                 }
386
387                 if (fHitMemory) delete[] fHitMemory;
388                 if (fTrackletMemory) delete[] fTrackletMemory;
389                 if (fTrackMemory) delete[] fTrackMemory;
390         }
391
392         fHitMemory = fTrackletMemory = fTrackMemory = 0;
393
394         fData.Clear();
395         fCommonMem->fNTracklets = 0;
396         fCommonMem->fNTracks = 0 ;
397         fCommonMem->fNTrackHits = 0;
398 }
399
400 void AliHLTTPCCATracker::ReadEvent( AliHLTTPCCAClusterData *clusterData )
401 {
402         // read event
403
404         fClusterData = clusterData;
405
406         StartEvent();
407
408         //* Convert input hits, create grids, etc.
409         fData.InitFromClusterData( *clusterData );
410         {
411                 if (!fIsGPUTracker)
412                 {
413                         SetPointersHits( fData.NumberOfHits() ); // to calculate the size
414                         fHitMemory = reinterpret_cast<char*> ( new uint4 [ fHitMemorySize/sizeof( uint4 ) + 100] );
415                 }
416                 SetPointersHits( fData.NumberOfHits() ); // set pointers for hits
417         }
418 }
419
420 GPUhd() void  AliHLTTPCCATracker::SetPointersHits( int MaxNHits )
421 {
422         // set all pointers to the event memory
423
424         char *mem = fHitMemory;
425
426         // extra arrays for tpc clusters
427
428 #ifdef HLTCA_GPU_SORT_STARTHITS_2
429         AssignMemory( fTrackletStartHits, mem, MaxNHits + 32);
430 #else
431         AssignMemory( fTrackletStartHits, mem, MaxNHits);
432 #endif
433
434         // calculate the size
435
436         fHitMemorySize = mem - fHitMemory;
437 }
438
439 GPUhd() void  AliHLTTPCCATracker::SetPointersTracklets( int MaxNTracklets )
440 {
441         // set all pointers to the tracklets memory
442         char *mem = fTrackletMemory;
443
444         // memory for tracklets
445
446         AssignMemory( fTracklets, mem, MaxNTracklets );
447 #ifdef EXTERN_ROW_HITS
448         AssignMemory( fTrackletRowHits, mem, MaxNTracklets * Param().NRows());
449 #endif
450
451         fTrackletMemorySize = mem - fTrackletMemory;
452 }
453
454
455 GPUhd() void  AliHLTTPCCATracker::SetPointersTracks( int MaxNTracks, int MaxNHits )
456 {
457         // set all pointers to the tracks memory
458         char *mem = fTrackMemory;
459
460         // memory for selected tracks
461
462         AssignMemory( fTracks, mem, MaxNTracks );
463         AssignMemory( fTrackHits, mem, 2 * MaxNHits );
464
465         // calculate the size
466
467         fTrackMemorySize = mem - fTrackMemory;
468 }
469
470 GPUh() int AliHLTTPCCATracker::CheckEmptySlice() const
471 {
472         //Check if the Slice is empty, if so set the output apropriate and tell the reconstuct procesdure to terminate
473         if ( NHitsTotal() < 1 ) {
474                 {
475                         AliHLTTPCCASliceOutput::Allocate(*fOutput, 0, 0, fOutputControl);
476                         AliHLTTPCCASliceOutput* useOutput = *fOutput;
477                         if (useOutput == NULL) return(1);
478                         useOutput->SetNTracks( 0 );
479                         useOutput->SetNTrackClusters( 0 );
480                 }
481
482                 return 1;
483         }
484         return 0;
485 }
486
487 void AliHLTTPCCATracker::RunNeighboursFinder()
488 {
489         //Run the CPU Neighbours Finder
490         AliHLTTPCCAProcess<AliHLTTPCCANeighboursFinder>( Param().NRows(), 1, *this );
491 }
492
493 void AliHLTTPCCATracker::RunNeighboursCleaner()
494 {
495         //Run the CPU Neighbours Cleaner
496         AliHLTTPCCAProcess<AliHLTTPCCANeighboursCleaner>( Param().NRows() - 2, 1, *this );
497 }
498
499 void AliHLTTPCCATracker::RunStartHitsFinder()
500 {
501         //Run the CPU Start Hits Finder
502         AliHLTTPCCAProcess<AliHLTTPCCAStartHitsFinder>( Param().NRows() - 4, 1, *this );
503 }
504
505 void AliHLTTPCCATracker::RunTrackletConstructor()
506 {
507         //Run CPU Tracklet Constructor
508         AliHLTTPCCATrackletConstructor::AliHLTTPCCATrackletConstructorCPU(*this);
509 }
510
511 void AliHLTTPCCATracker::RunTrackletSelector()
512 {
513         //Run CPU Tracklet Selector
514         AliHLTTPCCAProcess<AliHLTTPCCATrackletSelector>( 1, fCommonMem->fNTracklets, *this );
515 }
516
517 #ifdef HLTCA_STANDALONE
518 void AliHLTTPCCATracker::StandalonePerfTime(int i)
519 {
520         //Query Performance Timer for Standalone Version of Tracker
521         if (fGPUDebugLevel >= 1)
522         {
523                 StandaloneQueryTime(&fPerfTimers[i]);
524         }
525 }
526 #else
527 void AliHLTTPCCATracker::StandalonePerfTime(int /*i*/) {}
528 #endif
529
530 GPUh() void AliHLTTPCCATracker::DoTracking()
531 {
532         fCommonMem->fNTracklets = fCommonMem->fNTracks = fCommonMem->fNTrackHits = 0;
533
534         if (fGPUDebugLevel >= 6)
535         {
536 #ifndef BITWISE_COMPATIBLE_DEBUG_OUTPUT
537                 *fGPUDebugOut << std::endl << std::endl << "Slice: " << Param().ISlice() << std::endl;
538                 *fGPUDebugOut << "Slice Data:" << std::endl;
539 #endif
540                 DumpSliceData(*fGPUDebugOut);
541         }
542
543         StandalonePerfTime(1);
544
545         RunNeighboursFinder();
546
547         StandalonePerfTime(2);
548
549 #ifdef TRACKER_KEEP_TEMPDATA
550         if (fLinkTmpMemory) delete[] fLinkTmpMemory;
551         fLinkTmpMemory = new char[fData.MemorySize()];
552         memcpy(fLinkTmpMemory, fData.Memory(), fData.MemorySize());
553 #endif
554
555         if (fGPUDebugLevel >= 6) DumpLinks(*fGPUDebugOut);
556
557 #ifdef HLTCA_INTERNAL_PERFORMANCE
558         //if( Param().ISlice()<=2 )
559         //AliHLTTPCCAPerformance::Instance().LinkPerformance( Param().ISlice() );
560 #endif
561
562
563 #ifdef DRAW1
564         if ( NHitsTotal() > 0 ) {
565                 AliHLTTPCCADisplay::Instance().DrawSliceLinks( -1, -1, 1 );
566                 AliHLTTPCCADisplay::Instance().Ask();
567         }
568 #endif //DRAW1
569
570         RunNeighboursCleaner();
571
572         StandalonePerfTime(3);
573
574         if (fGPUDebugLevel >= 6) DumpLinks(*fGPUDebugOut);
575
576         RunStartHitsFinder();
577
578         StandalonePerfTime(4);
579         StandalonePerfTime(5);
580
581         if (fGPUDebugLevel >= 6) DumpStartHits(*fGPUDebugOut);
582
583         fData.ClearHitWeights();
584
585         if (!fIsGPUTracker)
586         {
587                 SetPointersTracklets( fCommonMem->fNTracklets * 2 ); // to calculate the size
588                 fTrackletMemory = reinterpret_cast<char*> ( new uint4 [ fTrackletMemorySize/sizeof( uint4 ) + 100] );
589                 SetPointersTracks( fCommonMem->fNTracklets * 2, NHitsTotal() ); // to calculate the size
590                 fTrackMemory = reinterpret_cast<char*> ( new uint4 [ fTrackMemorySize/sizeof( uint4 ) + 100] );
591         }
592
593         SetPointersTracklets( fCommonMem->fNTracklets * 2 ); // set pointers for hits
594         SetPointersTracks( fCommonMem->fNTracklets * 2, NHitsTotal() ); // set pointers for hits
595
596         StandalonePerfTime(6);
597         StandalonePerfTime(7);
598
599         RunTrackletConstructor();
600
601         StandalonePerfTime(8);
602
603         if (fGPUDebugLevel >= 6) DumpTrackletHits(*fGPUDebugOut);
604 #ifndef BITWISE_COMPATIBLE_DEBUG_OUTPUT
605         if (fGPUDebugLevel >= 6) DumpHitWeights(*fGPUDebugOut);
606 #endif
607
608         //std::cout<<"Slice "<<Param().ISlice()<<": NHits="<<NHitsTotal()<<", NTracklets="<<*NTracklets()<<std::endl;
609
610         RunTrackletSelector();
611
612         StandalonePerfTime(9);
613
614         //std::cout<<"Slice "<<Param().ISlice()<<": N start hits/tracklets/tracks = "<<nStartHits<<" "<<nStartHits<<" "<<*fNTracks<<std::endl;
615
616         if (fGPUDebugLevel >= 6) DumpTrackHits(*fGPUDebugOut);
617
618         //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;
619 }
620
621 GPUh() void AliHLTTPCCATracker::Reconstruct()
622 {
623         //* reconstruction of event
624         //std::cout<<"Reconstruct slice "<<fParam.ISlice()<<", nHits="<<NHitsTotal()<<std::endl;
625
626         fTimers[0] = 0; // find neighbours
627         fTimers[1] = 0; // construct tracklets
628         fTimers[2] = 0; // fit tracklets
629         fTimers[3] = 0; // prolongation of tracklets
630         fTimers[4] = 0; // selection
631         fTimers[5] = 0; // write output
632         fTimers[6] = 0;
633         fTimers[7] = 0;
634
635         //if( fParam.ISlice()<1 ) return; //SG!!!
636
637         TStopwatch timer0;
638
639         if (CheckEmptySlice()) return;
640
641 #ifdef DRAW1
642         //if( fParam.ISlice()==2 || fParam.ISlice()==3)
643         {
644                 AliHLTTPCCADisplay::Instance().ClearView();
645                 AliHLTTPCCADisplay::Instance().SetSliceView();
646                 AliHLTTPCCADisplay::Instance().SetCurrentSlice( this );
647                 AliHLTTPCCADisplay::Instance().DrawSlice( this, 1 );
648                 if ( NHitsTotal() > 0 ) {
649                         AliHLTTPCCADisplay::Instance().DrawSliceHits( kRed, .5 );
650                         AliHLTTPCCADisplay::Instance().Ask();
651                 }
652         }
653 #endif //DRAW1
654
655         DoTracking();
656         fTimers[0] = timer0.CpuTime() / 100.;
657 }
658
659 GPUh() void AliHLTTPCCATracker::ReconstructOutput()
660 {
661         TStopwatch timer0;
662         WriteOutputPrepare();
663         WriteOutput();
664
665         StandalonePerfTime(10);
666
667 #ifdef DRAW1
668         {
669                 AliHLTTPCCADisplay &disp = AliHLTTPCCADisplay::Instance();
670                 AliHLTTPCCATracker &slice = *this;
671                 std::cout << "N out tracks = " << slice.NOutTracks() << std::endl;
672                 AliHLTTPCCADisplay::Instance().SetSliceView();
673                 AliHLTTPCCADisplay::Instance().SetCurrentSlice( this );
674                 AliHLTTPCCADisplay::Instance().DrawSlice( this, 1 );
675                 disp.DrawSliceHits( kRed, .5 );
676                 disp.Ask();
677                 for ( int itr = 0; itr < slice.NOutTracks(); itr++ ) {
678                         std::cout << "track N " << itr << ", nhits=" << slice.OutTracks()[itr].NHits() << std::endl;
679                         disp.DrawSliceOutTrack( itr, kBlue );      
680                         //disp.Ask();
681                         //int id = slice.OutTracks()[itr].OrigTrackID();
682                         //AliHLTTPCCATrack &tr = Tracks()[id];
683                         //for( int ih=0; ih<tr.NHits(); ih++ ){
684                         //int ic = (fTrackHits[tr.FirstHitID()+ih]);
685                         //std::cout<<ih<<" "<<ID2IRow(ic)<<" "<<ID2IHit(ic)<<std::endl;
686                         //}
687                         //disp.DrawSliceTrack( id, kBlue );
688                         //disp.Ask();
689                 }
690                 disp.Ask();
691         }
692 #endif //DRAW1
693
694         timer0.Stop();
695         fTimers[0] += timer0.CpuTime() / 100.;
696 }
697
698 GPUh() void AliHLTTPCCATracker::WriteOutputPrepare()
699 {
700         if (fOutputControl == NULL) fOutputControl = new AliHLTTPCCASliceOutput::outputControlStruct;
701         AliHLTTPCCASliceOutput::Allocate(*fOutput, fCommonMem->fNTracks, fCommonMem->fNTrackHits, fOutputControl);
702 }
703
704 GPUh() int AliHLTTPCCATracker::SortComparison(const void* a, const void* b)
705 {
706         return(((trackSortData*) a)->fSortVal < ((trackSortData*) b)->fSortVal ? 1 : -1);
707 }
708
709 GPUh() void AliHLTTPCCATracker::WriteOutput()
710 {
711         // write output
712         AliHLTTPCCASliceOutput* useOutput = *fOutput;
713
714         TStopwatch timer;
715
716         //cout<<"output: nTracks = "<<*fNTracks<<", nHitsTotal="<<NHitsTotal()<<std::endl;
717
718         if (useOutput == NULL) return;
719
720         useOutput->SetNTracks( 0 );
721         useOutput->SetNTrackClusters( 0 );
722
723         int nStoredHits = 0;
724         int nStoredTracks = 0;
725         int nStoredLocalTracks = 0;
726
727         AliHLTTPCCASliceOutTrack *out = useOutput->FirstTrack();
728
729         trackSortData* trackOrder = new trackSortData[fCommonMem->fNTracks];
730         for (int i = 0;i < fCommonMem->fNTracks;i++)
731         {
732                 trackOrder[i].fTtrack = i;
733                 trackOrder[i].fSortVal = fTracks[trackOrder[i].fTtrack].NHits() / 1000.f + fTracks[trackOrder[i].fTtrack].Param().GetZ() * 100.f + fTracks[trackOrder[i].fTtrack].Param().GetY();
734         }
735         qsort(trackOrder, fCommonMem->fNLocalTracks, sizeof(trackSortData), SortComparison);
736         qsort(trackOrder + fCommonMem->fNLocalTracks, fCommonMem->fNTracks - fCommonMem->fNLocalTracks, sizeof(trackSortData), SortComparison);
737
738         for ( int iTrTmp = 0; iTrTmp < fCommonMem->fNTracks; iTrTmp++ ) {
739                 int iTr = trackOrder[iTrTmp].fTtrack;
740                 AliHLTTPCCATrack &iTrack = fTracks[iTr];    
741
742                 if( iTr < fCommonMem->fNLocalTracks && iTrack.NHits() < fParam.MinNTrackClusters() ) continue;
743                 if( CAMath::Abs(iTrack.Param().GetQPt())> fParam.MaxTrackQPt() ) continue;
744
745                 out->SetParam( iTrack.Param() );
746                 out->SetLocalTrackId( iTrack.LocalTrackId() );
747                 int nClu = 0;
748                 int iID = iTrack.FirstHitID();
749
750                 for ( int ith = 0; ith < iTrack.NHits(); ith++ ) {
751                         const AliHLTTPCCAHitId &ic = fTrackHits[iID + ith];
752                         int iRow = ic.RowIndex();
753                         int ih = ic.HitIndex();
754
755                         const AliHLTTPCCARow &row = fData.Row( iRow );
756
757                         int clusterIndex = fData.ClusterDataIndex( row, ih );
758
759                         float origX = fClusterData->X( clusterIndex );
760                         float origY = fClusterData->Y( clusterIndex );
761                         float origZ = fClusterData->Z( clusterIndex );      
762                         int id = fClusterData->Id( clusterIndex );
763                         AliHLTTPCCASliceOutCluster c;
764                         c.Set( id, iRow, origX, origY, origZ );
765                         out->SetCluster( nClu, c );
766                         nClu++;
767                 }
768
769                 nStoredTracks++;
770                 if (iTr < fCommonMem->fNLocalTracks) nStoredLocalTracks++;
771                 nStoredHits+=nClu; 
772                 out->SetNClusters( nClu );
773                 out = out->NextTrack();    
774         }
775         delete[] trackOrder;
776
777         useOutput->SetNTracks( nStoredTracks );
778         useOutput->SetNLocalTracks( nStoredLocalTracks );
779         useOutput->SetNTrackClusters( nStoredHits );
780
781         timer.Stop();
782         fTimers[5] += timer.CpuTime();
783 }
784
785 #endif
786
787 GPUh() void AliHLTTPCCATracker::FitTrackFull( const MEM_LG2(AliHLTTPCCATrack) &/**/, float * /**/ ) const
788 {
789         // fit track with material
790 #ifdef XXX
791         //* Fit the track
792         FitTrack( iTrack, tt0 );
793         if ( iTrack.NHits() <= 3 ) return;
794
795         AliHLTTPCCATrackParam &t = iTrack.Param();
796         AliHLTTPCCATrackParam t0 = t;
797
798         t.Chi2() = 0;
799         t.NDF() = -5;
800         bool first = 1;
801
802         int iID = iTrack.FirstHitID();
803         for ( int ih = 0; ih < iTrack.NHits(); ih++, iID++ ) {
804                 const AliHLTTPCCAHitId &ic = fTrackHits[iID];
805                 int iRow = ic.rowIndex();
806                 const AliHLTTPCCARow &row = fData.Row( iRow );
807                 if ( !t0.TransportToX( row.X() ) ) continue;
808                 float dy, dz;
809                 const AliHLTTPCCAHit &h = ic.hitIndex();
810
811                 // check for wrong hits
812                 if ( 0 ) {
813                         dy = t0.GetY() - h.Y();
814                         dz = t0.GetZ() - h.Z();
815
816                         //if( dy*dy > 3.5*3.5*(/*t0.GetErr2Y() + */h.ErrY()*h.ErrY() ) ) continue;//SG!!!
817                         //if( dz*dz > 3.5*3.5*(/*t0.GetErr2Z() + */h.ErrZ()*h.ErrZ() ) ) continue;
818                 }
819
820                 if ( !t.TransportToX( row.X() ) ) continue;
821
822                 //* Update the track
823
824                 if ( first ) {
825                         t.Cov()[ 0] = .5 * .5;
826                         t.Cov()[ 1] = 0;
827                         t.Cov()[ 2] = .5 * .5;
828                         t.Cov()[ 3] = 0;
829                         t.Cov()[ 4] = 0;
830                         t.Cov()[ 5] = .2 * .2;
831                         t.Cov()[ 6] = 0;
832                         t.Cov()[ 7] = 0;
833                         t.Cov()[ 8] = 0;
834                         t.Cov()[ 9] = .2 * .2;
835                         t.Cov()[10] = 0;
836                         t.Cov()[11] = 0;
837                         t.Cov()[12] = 0;
838                         t.Cov()[13] = 0;
839                         t.Cov()[14] = .2 * .2;
840                         t.Chi2() = 0;
841                         t.NDF() = -5;
842                 }
843                 float err2Y, err2Z;
844                 GetErrors2( iRow, t, err2Y, err2Z );
845
846                 if ( !t.Filter2( h.Y(), h.Z(), err2Y, err2Z ) ) continue;
847
848                 first = 0;
849         }
850         /*
851         float cosPhi = iTrack.Param().GetCosPhi();
852         p0.Param().TransportToX(ID2Row( iTrack.PointID()[0] ).X());
853         p2.Param().TransportToX(ID2Row( iTrack.PointID()[1] ).X());
854         if( p0.Param().GetCosPhi()*cosPhi<0 ){ // change direction
855         float *par = p0.Param().Par();
856         float *cov = p0.Param().Cov();
857         par[2] = -par[2]; // sin phi
858         par[3] = -par[3]; // DzDs
859         par[4] = -par[4]; // kappa
860         cov[3] = -cov[3];
861         cov[4] = -cov[4];
862         cov[6] = -cov[6];
863         cov[7] = -cov[7];
864         cov[10] = -cov[10];
865         cov[11] = -cov[11];
866         p0.Param().CosPhi() = -p0.Param().GetCosPhi();
867         }
868         */
869 #endif
870 }
871
872 GPUh() void AliHLTTPCCATracker::FitTrack( const AliHLTTPCCATrack &/*track*/, float * /*t0[]*/ ) const
873 {
874         //* Fit the track
875 #ifdef XXX
876         AliHLTTPCCAEndPoint &p2 = ID2Point( track.PointID()[1] );
877         const AliHLTTPCCAHit &c0 = ID2Hit( fTrackHits[p0.TrackHitID()].HitID() );
878         const AliHLTTPCCAHit &c1 = ID2Hit( fTrackHits[track.HitID()[1]].HitID() );
879         const AliHLTTPCCAHit &c2 = ID2Hit( fTrackHits[p2.TrackHitID()].HitID() );
880         const AliHLTTPCCARow &row0 = ID2Row( fTrackHits[p0.TrackHitID()].HitID() );
881         const AliHLTTPCCARow &row1 = ID2Row( fTrackHits[track.HitID()[1]].HitID() );
882         const AliHLTTPCCARow &row2 = ID2Row( fTrackHits[p2.TrackHitID()].HitID() );
883         float sp0[5] = {row0.X(), c0.Y(), c0.Z(), c0.ErrY(), c0.ErrZ() };
884         float sp1[5] = {row1.X(), c1.Y(), c1.Z(), c1.ErrY(), c1.ErrZ() };
885         float sp2[5] = {row2.X(), c2.Y(), c2.Z(), c2.ErrY(), c2.ErrZ() };
886         //std::cout<<"Fit track, points ="<<sp0[0]<<" "<<sp0[1]<<" / "<<sp1[0]<<" "<<sp1[1]<<" / "<<sp2[0]<<" "<<sp2[1]<<std::endl;
887         if ( track.NHits() >= 3 ) {
888                 p0.Param().ConstructXYZ3( sp0, sp1, sp2, p0.Param().CosPhi(), t0 );
889                 p2.Param().ConstructXYZ3( sp2, sp1, sp0, p2.Param().CosPhi(), t0 );
890                 //p2.Param() = p0.Param();
891                 //p2.Param().TransportToX(row2.X());
892                 //p2.Param().Par()[1] = -p2.Param().Par()[1];
893                 //p2.Param().Par()[4] = -p2.Param().Par()[4];
894         } else {
895                 p0.Param().X() = row0.X();
896                 p0.Param().Y() = c0.Y();
897                 p0.Param().Z() = c0.Z();
898                 p0.Param().Err2Y() = c0.ErrY() * c0.ErrY();
899                 p0.Param().Err2Z() = c0.ErrZ() * c0.ErrZ();
900                 p2.Param().X() = row2.X();
901                 p2.Param().Y() = c2.Y();
902                 p2.Param().Z() = c2.Z();
903                 p2.Param().Err2Y() = c2.ErrY() * c2.ErrY();
904                 p2.Param().Err2Z() = c2.ErrZ() * c2.ErrZ();
905         }
906 #endif
907 }
908
909 #if !defined(HLTCA_GPUCODE)
910
911 GPUh() void AliHLTTPCCATracker::WriteEvent( std::ostream &out )
912 {
913         // write event to the file
914         for ( int iRow = 0; iRow < fParam.NRows(); iRow++ ) {
915                 out << fData.Row( iRow ).HitNumberOffset() << " " << fData.Row( iRow ).NHits() << std::endl;
916         }
917         out << NHitsTotal() << std::endl;
918
919         AliHLTResizableArray<float> y( NHitsTotal() ), z( NHitsTotal() );
920
921         for ( int iRow = 0; iRow < fParam.NRows(); iRow++ ) {
922                 const AliHLTTPCCARow &row = Row( iRow );
923                 float y0 = row.Grid().YMin();
924                 float z0 = row.Grid().ZMin();
925                 float stepY = row.HstepY();
926                 float stepZ = row.HstepZ();
927                 for ( int ih = 0; ih < fData.Row( iRow ).NHits(); ih++ ) {
928                         int id = HitInputID( row, ih );
929                         y[id] = y0 + HitDataY( row, ih ) * stepY;
930                         z[id] = z0 + HitDataZ( row, ih ) * stepZ;
931                 }
932         }
933         for ( int ih = 0; ih < NHitsTotal(); ih++ ) {
934                 out << y[ih] << " " << z[ih] << std::endl;
935         }
936 }
937
938 GPUh() void AliHLTTPCCATracker::WriteTracks( std::ostream &/*out*/ )
939 {
940         //* Write tracks to file --- dummy
941 }
942
943 GPUh() void AliHLTTPCCATracker::ReadTracks( std::istream &/*in*/ )
944 {
945         //* Read tracks  from file -- dummy
946 }
947
948 GPUh() int AliHLTTPCCATracker::PerformGlobalTrackingRun(AliHLTTPCCATracker& sliceNeighbour, int iTrack, int rowIndex, float angle, int direction)
949 {
950         /*for (int j = 0;j < fTracks[j].NHits();j++)
951         {
952                 printf("Hit %3d: Row %3d: X %3.7lf Y %3.7lf\n", j, fTrackHits[fTracks[iTrack].FirstHitID() + j].RowIndex(), Row(fTrackHits[fTracks[iTrack].FirstHitID() + j].RowIndex()).X(),
953                 (float) Data().HitDataY(Row(fTrackHits[fTracks[iTrack].FirstHitID() + j].RowIndex()), fTrackHits[fTracks[iTrack].FirstHitID() + j].HitIndex()) * Row(fTrackHits[fTracks[iTrack].FirstHitID() + j].RowIndex()).HstepY() + Row(fTrackHits[fTracks[iTrack].FirstHitID() + j].RowIndex()).Grid().YMin());
954                 }*/
955
956         if (sliceNeighbour.fCommonMem->fNTracklets == 0) return(0);
957
958         AliHLTTPCCATrackParam tParam;
959         tParam.InitParam();
960         tParam.SetCov( 0, 0.05 );
961         tParam.SetCov( 2, 0.05 );
962         tParam.SetCov( 5, 0.001 );
963         tParam.SetCov( 9, 0.001 );
964         tParam.SetCov( 14, 0.05 );
965         tParam.SetParam(fTracks[iTrack].Param());
966
967         //printf("Parameters X %f Y %f Z %f SinPhi %f DzDs %f QPt %f SignCosPhi %f\n", tParam.X(), tParam.Y(), tParam.Z(), tParam.SinPhi(), tParam.DzDs(), tParam.QPt(), tParam.SignCosPhi());
968         if (!tParam.Rotate(angle, .999)) return(0);
969         //printf("Rotated X %f Y %f Z %f SinPhi %f DzDs %f QPt %f SignCosPhi %f\n", tParam.X(), tParam.Y(), tParam.Z(), tParam.SinPhi(), tParam.DzDs(), tParam.QPt(), tParam.SignCosPhi());
970
971         int maxRowGap = 6;
972         do
973         {
974                 rowIndex += direction;
975                 if (!tParam.TransportToX(sliceNeighbour.Row(rowIndex).X(), fParam.ConstBz(), .999)) {maxRowGap = 0;break;}
976                 //printf("Transported X %f Y %f Z %f SinPhi %f DzDs %f QPt %f SignCosPhi %f (MaxY %f)\n", tParam.X(), tParam.Y(), tParam.Z(), tParam.SinPhi(), tParam.DzDs(), tParam.QPt(), tParam.SignCosPhi(), sliceNeighbour.Row(rowIndex).MaxY());
977         } while (fabs(tParam.Y()) > sliceNeighbour.Row(rowIndex).MaxY() && --maxRowGap);
978         if (maxRowGap == 0) return(0);
979
980         int nHits = AliHLTTPCCATrackletConstructor::AliHLTTPCCATrackletConstructorGlobalTracking(sliceNeighbour, tParam, rowIndex, direction);
981         if (nHits >= GLOBAL_TRACKING_MIN_HITS)
982         {
983                 //printf("%d hits found\n", nHits);
984                 AliHLTTPCCATrack& track = sliceNeighbour.fTracks[sliceNeighbour.fCommonMem->fNTracks];
985                 if (direction == 1)
986                 {
987                         int i = 0;
988                         while (i < nHits)
989                         {
990                                 if (sliceNeighbour.fTrackletRowHits[rowIndex * sliceNeighbour.fCommonMem->fNTracklets] != -1)
991                                 {
992                                         //printf("New track: entry %d, row %d, hitindex %d\n", i, rowIndex, sliceNeighbour.fTrackletRowHits[rowIndex * sliceNeighbour.fCommonMem->fNTracklets]);
993                                         sliceNeighbour.fTrackHits[sliceNeighbour.fCommonMem->fNTrackHits + i].Set(rowIndex, sliceNeighbour.fTrackletRowHits[rowIndex * sliceNeighbour.fCommonMem->fNTracklets]);
994                                         if (i == 0) tParam.TransportToX(sliceNeighbour.Row(rowIndex).X(), fParam.ConstBz(), .999);
995                                         i++;
996                                 }
997                                 rowIndex ++;
998                         }
999                 }
1000                 else
1001                 {
1002                         int i = nHits - 1;
1003                         while (i >= 0)
1004                         {
1005                                 if (sliceNeighbour.fTrackletRowHits[rowIndex * sliceNeighbour.fCommonMem->fNTracklets] != -1)
1006                                 {
1007                                         //printf("New track: entry %d, row %d, hitindex %d\n", i, rowIndex, sliceNeighbour.fTrackletRowHits[rowIndex * sliceNeighbour.fCommonMem->fNTracklets]);
1008                                         sliceNeighbour.fTrackHits[sliceNeighbour.fCommonMem->fNTrackHits + i].Set(rowIndex, sliceNeighbour.fTrackletRowHits[rowIndex * sliceNeighbour.fCommonMem->fNTracklets]);
1009                                         i--;
1010                                 }
1011                                 rowIndex--;
1012                         }
1013                 }
1014                 track.SetAlive(1);
1015                 track.SetParam(tParam.GetParam());
1016                 track.SetNHits(nHits);
1017                 track.SetFirstHitID(sliceNeighbour.fCommonMem->fNTrackHits);
1018                 const int kMaxTrackIdInSlice = AliHLTTPCCASliceOutTrack::MaxTrackId();
1019                 track.SetLocalTrackId(fParam.ISlice() * kMaxTrackIdInSlice + fTracks[iTrack].LocalTrackId());
1020                 sliceNeighbour.fCommonMem->fNTracks++;
1021                 sliceNeighbour.fCommonMem->fNTrackHits += nHits;
1022                 return(1);
1023         }
1024         return(0);
1025 }
1026
1027 GPUh() void AliHLTTPCCATracker::PerformGlobalTracking(AliHLTTPCCATracker& sliceLeft, AliHLTTPCCATracker& sliceRight, int MaxTracks)
1028 {
1029         int ul = 0, ur = 0, ll = 0, lr = 0;
1030         for (int i = 0;i < fCommonMem->fNLocalTracks;i++)
1031         {
1032                 if (sliceLeft.fCommonMem->fNTracks >= MaxTracks || sliceRight.fCommonMem->fNTracks >= MaxTracks) return;
1033
1034                 {
1035                         const int tmpHit = fTracks[i].FirstHitID();
1036                         if (fTrackHits[tmpHit].RowIndex() >= GLOBAL_TRACKING_MIN_ROWS && fTrackHits[tmpHit].RowIndex() < GLOBAL_TRACKING_RANGE)
1037                         {
1038                                 int rowIndex = fTrackHits[tmpHit].RowIndex();
1039                                 const AliHLTTPCCARow& row = Row(rowIndex);
1040                                 float Y = (float) Data().HitDataY(row, fTrackHits[tmpHit].HitIndex()) * row.HstepY() + row.Grid().YMin();
1041                                 if (Y < -row.MaxY() * GLOBAL_TRACKING_Y_RANGE_LOWER_LEFT)
1042                                 {
1043                                         //printf("Track %d, lower row %d, left border (%f of %f)\n", i, fTrackHits[tmpHit].RowIndex(), Y, -row.MaxY());
1044                                         ll += PerformGlobalTrackingRun(sliceLeft, i, rowIndex, -fParam.DAlpha(), -1);
1045                                 }
1046                                 if (Y > row.MaxY() * GLOBAL_TRACKING_Y_RANGE_LOWER_RIGHT)
1047                                 {
1048                                         //printf("Track %d, lower row %d, right border (%f of %f)\n", i, fTrackHits[tmpHit].RowIndex(), Y, row.MaxY());
1049                                         lr += PerformGlobalTrackingRun(sliceRight, i, rowIndex, fParam.DAlpha(), -1);
1050                                 }
1051                         }
1052                 }
1053                 
1054                 {
1055                         const int tmpHit = fTracks[i].FirstHitID() + fTracks[i].NHits() - 1;
1056                         if (fTrackHits[tmpHit].RowIndex() < HLTCA_ROW_COUNT - GLOBAL_TRACKING_MIN_ROWS && fTrackHits[tmpHit].RowIndex() >= HLTCA_ROW_COUNT - GLOBAL_TRACKING_RANGE)
1057                         {
1058                                 int rowIndex = fTrackHits[tmpHit].RowIndex();
1059                                 const AliHLTTPCCARow& row = Row(rowIndex);
1060                                 float Y = (float) Data().HitDataY(row, fTrackHits[tmpHit].HitIndex()) * row.HstepY() + row.Grid().YMin();
1061                                 if (Y < -row.MaxY() * GLOBAL_TRACKING_Y_RANGE_UPPER_LEFT)
1062                                 {
1063                                         //printf("Track %d, upper row %d, left border (%f of %f)\n", i, fTrackHits[tmpHit].RowIndex(), Y, -row.MaxY());
1064                                         ul += PerformGlobalTrackingRun(sliceLeft, i, rowIndex, -fParam.DAlpha(), 1);
1065                                 }
1066                                 if (Y > row.MaxY() * GLOBAL_TRACKING_Y_RANGE_UPPER_RIGHT)
1067                                 {
1068                                         //printf("Track %d, upper row %d, right border (%f of %f)\n", i, fTrackHits[tmpHit].RowIndex(), Y, row.MaxY());
1069                                         ur += PerformGlobalTrackingRun(sliceRight, i, rowIndex, fParam.DAlpha(), 1);
1070                                 }
1071                         }
1072                 }
1073         }
1074         //printf("Global Tracking Result: Slide %2d: LL %3d LR %3d UL %3d UR %3d\n", fParam.ISlice(), ll, lr, ul, ur);
1075 }
1076
1077 #endif
1078 #endif