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