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