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