1 // $Id: AliHLTTPCGMMerger.cxx 30732 2009-01-22 23:02:02Z sgorbuno $
2 // **************************************************************************
3 // This file is property of and copyright by the ALICE HLT Project *
4 // ALICE Experiment at CERN, All rights reserved. *
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. *
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. *
18 //***************************************************************************
21 #include "AliHLTTPCCASliceOutTrack.h"
22 #include "AliHLTTPCCATracker.h"
23 #include "AliHLTTPCCATrackParam.h"
24 #include "AliHLTTPCGMCluster.h"
26 #include "AliHLTTPCGMMerger.h"
28 #include "AliHLTTPCCAMath.h"
29 #include "TStopwatch.h"
31 #include "AliHLTTPCCATrackParam.h"
32 #include "AliHLTTPCCASliceOutput.h"
33 #include "AliHLTTPCGMMergedTrack.h"
34 #include "AliHLTTPCCADataCompressor.h"
35 #include "AliHLTTPCCAParam.h"
36 #include "AliHLTTPCCATrackLinearisation.h"
37 #include "AliHLTTPCCADataCompressor.h"
39 #include "AliHLTTPCGMTrackParam.h"
40 #include "AliHLTTPCGMTrackLinearisation.h"
41 #include "AliHLTTPCGMSliceTrack.h"
42 #include "AliHLTTPCGMBorderTrack.h"
47 #include "AliHLTTPCCAGPUConfig.h"
48 #include "MemoryAssignmentHelpers.h"
50 #define GLOBAL_TRACKS_SPECIAL_TREATMENT
52 AliHLTTPCGMMerger::AliHLTTPCGMMerger()
56 fNOutputTrackClusters( 0 ),
59 fSliceTrackInfos( 0 ),
67 fBorderRangeMemory(0),
74 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
75 fNextSliceInd[iSlice] = iSlice + 1;
76 fPrevSliceInd[iSlice] = iSlice - 1;
78 int mid = fgkNSlices / 2 - 1 ;
79 int last = fgkNSlices - 1 ;
80 fNextSliceInd[ mid ] = 0;
81 fPrevSliceInd[ 0 ] = mid; fNextSliceInd[ last ] = fgkNSlices / 2;
82 fPrevSliceInd[ fgkNSlices/2 ] = last;
84 const double kCLight = 0.000299792458;
85 double constBz = fSliceParam.BzkG() * kCLight;
87 fPolinomialFieldBz[0] = constBz * ( 0.999286 );
88 fPolinomialFieldBz[1] = constBz * ( -4.54386e-7 );
89 fPolinomialFieldBz[2] = constBz * ( 2.32950e-5 );
90 fPolinomialFieldBz[3] = constBz * ( -2.99912e-7 );
91 fPolinomialFieldBz[4] = constBz * ( -2.03442e-8 );
92 fPolinomialFieldBz[5] = constBz * ( 9.71402e-8 );
99 AliHLTTPCGMMerger::AliHLTTPCGMMerger(const AliHLTTPCGMMerger&)
103 fNOutputTrackClusters( 0 ),
105 fOutputClusterIds(0),
106 fSliceTrackInfos( 0 ),
114 fBorderRangeMemory(0),
120 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
121 fNextSliceInd[iSlice] = 0;
122 fPrevSliceInd[iSlice] = 0;
125 const double kCLight = 0.000299792458;
126 double constBz = fSliceParam.BzkG() * kCLight;
128 fPolinomialFieldBz[0] = constBz * ( 0.999286 );
129 fPolinomialFieldBz[1] = constBz * ( -4.54386e-7 );
130 fPolinomialFieldBz[2] = constBz * ( 2.32950e-5 );
131 fPolinomialFieldBz[3] = constBz * ( -2.99912e-7 );
132 fPolinomialFieldBz[4] = constBz * ( -2.03442e-8 );
133 fPolinomialFieldBz[5] = constBz * ( 9.71402e-8 );
138 const AliHLTTPCGMMerger &AliHLTTPCGMMerger::operator=(const AliHLTTPCGMMerger&) const
145 AliHLTTPCGMMerger::~AliHLTTPCGMMerger()
151 void AliHLTTPCGMMerger::Clear()
153 for ( int i = 0; i < fgkNSlices; ++i ) {
155 fSliceNTrackInfos[ i ] = 0;
156 fSliceTrackInfoStart[ i ] = 0;
162 void AliHLTTPCGMMerger::ClearMemory()
164 if (fOutputClusterIds) delete[] fOutputClusterIds;
165 if (fSliceTrackInfos) delete[] fSliceTrackInfos;
168 if (fOutputTracks) delete[] fOutputTracks;
169 if (fClusterX) delete[] fClusterX;
170 if (fClusterY) delete[] fClusterY;
171 if (fClusterZ) delete[] fClusterZ;
172 if (fClusterRowType) delete[] fClusterRowType;
173 if (fClusterAngle) delete[] fClusterAngle;
175 if (fBorderMemory) delete[] fBorderMemory;
176 if (fBorderRangeMemory) delete[] fBorderRangeMemory;
180 fOutputClusterIds = 0;
181 fSliceTrackInfos = 0;
189 fBorderRangeMemory = 0;
193 void AliHLTTPCGMMerger::SetSliceData( int index, const AliHLTTPCCASliceOutput *sliceData )
195 fkSlices[index] = sliceData;
199 bool AliHLTTPCGMMerger::Reconstruct()
201 //* main merging routine
204 const double kCLight = 0.000299792458;
205 double constBz = fSliceParam.BzkG() * kCLight;
207 fPolinomialFieldBz[0] = constBz * ( 0.999286 );
208 fPolinomialFieldBz[1] = constBz * ( -4.54386e-7 );
209 fPolinomialFieldBz[2] = constBz * ( 2.32950e-5 );
210 fPolinomialFieldBz[3] = constBz * ( -2.99912e-7 );
211 fPolinomialFieldBz[4] = constBz * ( -2.03442e-8 );
212 fPolinomialFieldBz[5] = constBz * ( 9.71402e-8 );
217 #ifdef HLTCA_STANDALONE
218 unsigned long long int a, b, c, d, e, f, g;
219 AliHLTTPCCATracker::StandaloneQueryFreq(&g);
221 //cout<<"Merger..."<<endl;
222 for( int iter=0; iter<nIter; iter++ ){
223 if( !AllocateMemory() ) return 0;
224 #ifdef HLTCA_STANDALONE
225 AliHLTTPCCATracker::StandaloneQueryTime(&a);
228 #ifdef HLTCA_STANDALONE
229 AliHLTTPCCATracker::StandaloneQueryTime(&b);
231 MergeWithingSlices();
232 #ifdef HLTCA_STANDALONE
233 AliHLTTPCCATracker::StandaloneQueryTime(&c);
236 #ifdef HLTCA_STANDALONE
237 AliHLTTPCCATracker::StandaloneQueryTime(&d);
239 CollectMergedTracks();
240 #ifdef HLTCA_STANDALONE
241 AliHLTTPCCATracker::StandaloneQueryTime(&e);
244 #ifdef HLTCA_STANDALONE
245 AliHLTTPCCATracker::StandaloneQueryTime(&f);
248 printf("Merge Time:\tUnpack Slices:\t%lld us\n", (b - a) * 1000000 / g);
249 printf("\t\tMerge Within:\t%lld us\n", (c - b) * 1000000 / g);
250 printf("\t\tMerge Slices:\t%lld us\n", (d - c) * 1000000 / g);
251 printf("\t\tCollect:\t%lld us\n", (e - d) * 1000000 / g);
252 printf("\t\tRefit:\t\t%lld us\n", (f - e) * 1000000 / g);
255 for (int i = 0;i < fNOutputTracks;i++) if (fOutputTracks[i].OK()) newTracks++;
256 printf("Output Tracks: %d\n", newTracks);
260 //cout<<"\nMerger time = "<<timer.CpuTime()*1.e3/nIter<<" ms\n"<<endl;
267 bool AliHLTTPCGMMerger::AllocateMemory()
269 //* memory allocation
277 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
278 if ( !fkSlices[iSlice] ) continue;
279 nTracks += fkSlices[iSlice]->NTracks();
280 fNClusters += fkSlices[iSlice]->NTrackClusters();
281 if( fMaxSliceTracks < fkSlices[iSlice]->NTracks() ) fMaxSliceTracks = fkSlices[iSlice]->NTracks();
284 //cout<<"\nMerger: input "<<nTracks<<" tracks, "<<nClusters<<" clusters"<<endl;
286 fOutputClusterIds = new UInt_t[fNClusters];
287 fSliceTrackInfos = new AliHLTTPCGMSliceTrack[nTracks];
290 char* basemem = fGPUTracker->MergerBaseMemory();
291 AssignMemory(fClusterX, basemem, fNClusters);
292 AssignMemory(fClusterY, basemem, fNClusters);
293 AssignMemory(fClusterZ, basemem, fNClusters);
294 AssignMemory(fClusterAngle, basemem, fNClusters);
295 AssignMemory(fClusterRowType, basemem, fNClusters);
296 AssignMemory(fOutputTracks, basemem, nTracks);
300 fOutputTracks = new AliHLTTPCGMMergedTrack[nTracks];
301 fClusterX = new float[fNClusters];
302 fClusterY = new float[fNClusters];
303 fClusterZ = new float[fNClusters];
304 fClusterRowType = new UInt_t[fNClusters];
305 fClusterAngle = new float[fNClusters];
307 fBorderMemory = new AliHLTTPCGMBorderTrack[fMaxSliceTracks*2];
308 fBorderRangeMemory = new AliHLTTPCGMBorderTrack::Range[fMaxSliceTracks*2];
310 return ( ( fOutputTracks!=NULL )
311 && ( fOutputClusterIds!=NULL )
312 && ( fSliceTrackInfos!=NULL )
313 && ( fClusterX!=NULL )
314 && ( fClusterY!=NULL )
315 && ( fClusterZ!=NULL )
316 && ( fClusterRowType!=NULL )
317 && ( fClusterAngle!=NULL )
318 && ( fBorderMemory!=NULL )
319 && ( fBorderRangeMemory!=NULL )
325 void AliHLTTPCGMMerger::UnpackSlices()
327 //* unpack the cluster information from the slice tracks and initialize track info array
329 int nTracksCurrent = 0;
331 const AliHLTTPCCASliceOutTrack* firstGlobalTracks[fgkNSlices];
333 for( int i=0; i<fgkNSlices; i++) firstGlobalTracks[i] = 0;
335 #ifdef GLOBAL_TRACKS_SPECIAL_TREATMENT
336 const int kMaxTrackIdInSlice = AliHLTTPCCASliceOutTrack::MaxTrackId();
337 int* TrackIds = (int*) malloc(kMaxTrackIdInSlice * fgkNSlices * sizeof(int));
338 for (int i = 0;i < kMaxTrackIdInSlice * fgkNSlices;i++) TrackIds[i] = -1;
341 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
343 fSliceTrackInfoStart[ iSlice ] = nTracksCurrent;
345 fSliceNTrackInfos[ iSlice ] = 0;
347 if ( !fkSlices[iSlice] ) continue;
349 float alpha = fSliceParam.Alpha( iSlice );
351 const AliHLTTPCCASliceOutput &slice = *( fkSlices[iSlice] );
352 const AliHLTTPCCASliceOutTrack *sliceTr = slice.GetFirstTrack();
354 #ifdef GLOBAL_TRACKS_SPECIAL_TREATMENT
355 for ( int itr = 0; itr < slice.NLocalTracks(); itr++, sliceTr = sliceTr->GetNextTrack() ) {
357 for ( int itr = 0; itr < slice.NTracks(); itr++, sliceTr = sliceTr->GetNextTrack() ) {
359 AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[nTracksCurrent];
360 track.Set( sliceTr, alpha );
361 if( !track.FilterErrors( fSliceParam, .999 ) ) continue;
362 track.SetPrevNeighbour( -1 );
363 track.SetNextNeighbour( -1 );
364 track.SetSliceNeighbour( -1 );
366 #ifdef GLOBAL_TRACKS_SPECIAL_TREATMENT
367 track.SetGlobalTrackId(0, -1);
368 track.SetGlobalTrackId(1, -1);
369 TrackIds[iSlice * kMaxTrackIdInSlice + sliceTr->LocalTrackId()] = nTracksCurrent;
372 fSliceNTrackInfos[ iSlice ]++;
374 firstGlobalTracks[iSlice] = sliceTr;
376 //std::cout<<"Unpack slice "<<iSlice<<": ntracks "<<slice.NTracks()<<"/"<<fSliceNTrackInfos[iSlice]<<std::endl;
378 #ifdef GLOBAL_TRACKS_SPECIAL_TREATMENT
379 for (int iSlice = 0;iSlice < fgkNSlices;iSlice++)
381 fSliceTrackGlobalInfoStart[iSlice] = nTracksCurrent;
382 fSliceNGlobalTrackInfos[iSlice] = 0;
384 if ( !fkSlices[iSlice] ) continue;
385 float alpha = fSliceParam.Alpha( iSlice );
387 const AliHLTTPCCASliceOutput &slice = *( fkSlices[iSlice] );
388 const AliHLTTPCCASliceOutTrack *sliceTr = firstGlobalTracks[iSlice];
389 for (int itr = slice.NLocalTracks();itr < slice.NTracks();itr++, sliceTr = sliceTr->GetNextTrack())
391 if (TrackIds[sliceTr->LocalTrackId()] == -1) continue;
392 AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[nTracksCurrent];
393 track.Set( sliceTr, alpha );
394 //if( !track.FilterErrors( fSliceParam, .999 ) ) continue;
395 track.SetPrevNeighbour( -1 );
396 track.SetNextNeighbour( -1 );
397 track.SetSliceNeighbour( -1 );
399 track.SetLocalTrackId(TrackIds[sliceTr->LocalTrackId()]);
401 fSliceNGlobalTrackInfos[ iSlice ]++;
413 void AliHLTTPCGMMerger::MakeBorderTracks( int iSlice, int iBorder, AliHLTTPCGMBorderTrack B[], int &nB )
415 //* prepare slice tracks for merging with next/previous/same sector
416 //* each track transported to the border line
418 float fieldBz = fSliceParam.ConstBz();
422 float dAlpha = fSliceParam.DAlpha() / 2;
425 if ( iBorder == 0 ) { // transport to the left age of the sector and rotate horisontally
426 dAlpha = dAlpha - CAMath::Pi() / 2 ;
427 } else if ( iBorder == 1 ) { // transport to the right age of the sector and rotate horisontally
428 dAlpha = -dAlpha - CAMath::Pi() / 2 ;
429 } else if ( iBorder == 2 ) { // transport to the left age of the sector and rotate vertically
431 x0 = fSliceParam.RowX( 63 );
432 } else if ( iBorder == 3 ) { // transport to the right age of the sector and rotate vertically
434 x0 = fSliceParam.RowX( 63 );
435 } else if ( iBorder == 4 ) { // transport to the middle of the sector, w/o rotation
437 x0 = fSliceParam.RowX( 63 );
440 const float maxSin = CAMath::Sin( 60. / 180.*CAMath::Pi() );
441 float cosAlpha = AliHLTTPCCAMath::Cos( dAlpha );
442 float sinAlpha = AliHLTTPCCAMath::Sin( dAlpha );
444 for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
446 AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[ fSliceTrackInfoStart[iSlice] + itr ];
448 if( track.Used() ) continue;
449 AliHLTTPCGMBorderTrack &b = B[nB];
451 if( track.TransportToXAlpha( x0, sinAlpha, cosAlpha, fieldBz, b, maxSin)){
453 b.SetNClusters( track.NClusters() );
454 for (int i = 0;i < 4;i++) if (fabs(b.Cov()[i]) >= 5.0) b.SetCov(i, 5.0);
455 if (fabs(b.Cov()[4]) >= 0.5) b.SetCov(4, 0.5);
462 void AliHLTTPCGMMerger::MergeBorderTracks ( int iSlice1, AliHLTTPCGMBorderTrack B1[], int N1,
463 int iSlice2, AliHLTTPCGMBorderTrack B2[], int N2 )
465 //* merge two sets of tracks
467 //std::cout<<" Merge slices "<<iSlice1<<"+"<<iSlice2<<": tracks "<<N1<<"+"<<N2<<std::endl;
468 int statAll=0, statMerged=0;
469 float factor2ys = 1.5;//1.5;//SG!!!
470 float factor2zt = 1.5;//1.5;//SG!!!
471 float factor2k = 2.0;//2.2;
473 factor2k = 3.5 * 3.5 * factor2k * factor2k;
474 factor2ys = 3.5 * 3.5 * factor2ys * factor2ys;
475 factor2zt = 3.5 * 3.5 * factor2zt * factor2zt;
477 int minNPartHits = 10;//SG!!!
478 int minNTotalHits = 20;
480 AliHLTTPCGMBorderTrack::Range *range1 = fBorderRangeMemory;
481 AliHLTTPCGMBorderTrack::Range *range2 = fBorderRangeMemory + N1;
483 bool sameSlice = (iSlice1 == iSlice2);
485 for ( int itr = 0; itr < N1; itr++ ){
486 AliHLTTPCGMBorderTrack &b = B1[itr];
487 // if( iSlice1==7 && iSlice2==8 ){
488 //cout<<b.TrackID()<<": "<<b.Cov()[0]<<" "<<b.Cov()[1]<<endl;
490 float d = 3.5*sqrt(b.Cov()[1]);
491 range1[itr].fId = itr;
492 range1[itr].fMin = b.Par()[1] - d;
493 range1[itr].fMax = b.Par()[1] + d;
495 std::sort(range1,range1+N1,AliHLTTPCGMBorderTrack::Range::CompMin);
497 for(int i=0; i<N1; i++) range2[i]= range1[i];
498 std::sort(range2,range2+N1,AliHLTTPCGMBorderTrack::Range::CompMax);
502 for ( int itr = 0; itr < N2; itr++ ){
503 AliHLTTPCGMBorderTrack &b = B2[itr];
504 float d = 3.5*sqrt(b.Cov()[1]);
505 range2[itr].fId = itr;
506 range2[itr].fMin = b.Par()[1] - d;
507 range2[itr].fMax = b.Par()[1] + d;
509 std::sort(range2,range2+N2,AliHLTTPCGMBorderTrack::Range::CompMax);
514 for ( int i1 = 0; i1 < N1; i1++ ) {
516 AliHLTTPCGMBorderTrack::Range r1 = range1[i1];
517 while( i2<N2 && range2[i2].fMax< r1.fMin ) i2++;
519 AliHLTTPCGMBorderTrack &b1 = B1[r1.fId];
520 if ( b1.NClusters() < minNPartHits ) continue;
524 for( int k2 = i2; k2<N2; k2++){
526 AliHLTTPCGMBorderTrack::Range r2 = range2[k2];
527 if( r2.fMin > r1.fMax ) break;
528 if( sameSlice && (r1.fId >= r2.fId) ) continue;
530 AliHLTTPCGMBorderTrack &b2 = B2[r2.fId];
531 if ( b2.NClusters() < lBest2 ) continue;
533 if( !b1.CheckChi2Y(b2, factor2ys ) ) continue;
534 //if( !b1.CheckChi2Z(b2, factor2zt ) ) continue;
535 if( !b1.CheckChi2QPt(b2, factor2k ) ) continue;
536 if( !b1.CheckChi2YS(b2, factor2ys ) ) continue;
537 if( !b1.CheckChi2ZT(b2, factor2zt ) ) continue;
538 if ( b2.NClusters() < minNPartHits ) continue;
539 if ( b1.NClusters() + b2.NClusters() < minNTotalHits ) continue;
541 lBest2 = b2.NClusters();
542 iBest2 = b2.TrackID();
545 if ( iBest2 < 0 ) continue;
547 AliHLTTPCGMSliceTrack &newTrack1 = fSliceTrackInfos[fSliceTrackInfoStart[iSlice1] + b1.TrackID() ];
548 AliHLTTPCGMSliceTrack &newTrack2 = fSliceTrackInfos[fSliceTrackInfoStart[iSlice2] + iBest2 ];
550 int old1 = newTrack2.PrevNeighbour();
553 AliHLTTPCGMSliceTrack &oldTrack1 = fSliceTrackInfos[fSliceTrackInfoStart[iSlice1] + old1];
554 if ( oldTrack1.NClusters() < newTrack1.NClusters() ) {
555 newTrack2.SetPrevNeighbour( -1 );
556 oldTrack1.SetNextNeighbour( -1 );
559 int old2 = newTrack1.NextNeighbour();
561 AliHLTTPCGMSliceTrack &oldTrack2 = fSliceTrackInfos[fSliceTrackInfoStart[iSlice2] + old2];
562 if ( oldTrack2.NClusters() < newTrack2.NClusters() ) {
563 oldTrack2.SetPrevNeighbour( -1 );
566 newTrack1.SetNextNeighbour( iBest2 );
567 newTrack2.SetPrevNeighbour( b1.TrackID() );
569 //cout<<"slices "<<iSlice1<<","<<iSlice2<<": all "<<statAll<<" merged "<<statMerged<<endl;
573 void AliHLTTPCGMMerger::MergeWithingSlices()
575 //* merge track segments withing one slice
577 float x0 = fSliceParam.RowX( 63 );
578 const float maxSin = CAMath::Sin( 60. / 180.*CAMath::Pi() );
580 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
583 for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
584 AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[ fSliceTrackInfoStart[iSlice] + itr ];
585 //track.SetPrevNeighbour( -1 );
586 //track.SetNextNeighbour( -1 );
587 //track.SetSliceNeighbour( -1 );
590 AliHLTTPCGMBorderTrack &b = fBorderMemory[nBord];
591 if( track.TransportToX( x0, fSliceParam.ConstBz(), b, maxSin) ){
593 b.SetNClusters( track.NClusters() );
598 MergeBorderTracks( iSlice, fBorderMemory, nBord, iSlice, fBorderMemory, nBord );
600 for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
601 AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[ fSliceTrackInfoStart[iSlice] + itr];
602 if( track.PrevNeighbour()>=0 || track.Used() ) continue;
603 int jtr = track.NextNeighbour();
604 track.SetSliceNeighbour( jtr );
605 track.SetNextNeighbour(-1);
607 AliHLTTPCGMSliceTrack &trackN = fSliceTrackInfos[ fSliceTrackInfoStart[iSlice] + jtr];
608 if( trackN.NClusters()>track.NClusters() ) track.CopyParamFrom(trackN);
610 jtr = trackN.NextNeighbour();
611 trackN.SetSliceNeighbour( jtr );
612 trackN.SetNextNeighbour(-1);
613 trackN.SetPrevNeighbour(-1);
622 void AliHLTTPCGMMerger::MergeSlices()
624 //* track merging between slices
626 //for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
627 //for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
628 //AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[ fSliceTrackInfoStart[iSlice] + itr ];
629 //track.SetPrevNeighbour( -1 );
630 //track.SetNextNeighbour( -1 );
634 AliHLTTPCGMBorderTrack
635 *bCurr = fBorderMemory,
636 *bNext = fBorderMemory + fMaxSliceTracks;
638 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
639 int jSlice = fNextSliceInd[iSlice];
640 int nCurr = 0, nNext = 0;
641 MakeBorderTracks( iSlice, 2, bCurr, nCurr );
642 MakeBorderTracks( jSlice, 3, bNext, nNext );
643 MergeBorderTracks( iSlice, bCurr, nCurr, jSlice, bNext, nNext );
644 MakeBorderTracks( iSlice, 0, bCurr, nCurr );
645 MakeBorderTracks( jSlice, 1, bNext, nNext );
646 MergeBorderTracks( iSlice, bCurr, nCurr, jSlice, bNext, nNext );
654 void AliHLTTPCGMMerger::CollectMergedTracks()
658 //for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
659 //for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
660 //AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[ fSliceTrackInfoStart[iSlice] + itr ];
661 //if( track.Used()!=2 ) track.SetUsed(0);
665 //Resolve connections for global tracks first
666 #ifdef GLOBAL_TRACKS_SPECIAL_TREATMENT
667 for (int iSlice = 0;iSlice < fgkNSlices;iSlice++)
669 for (int itr = 0;itr < fSliceNGlobalTrackInfos[iSlice];itr++)
671 AliHLTTPCGMSliceTrack &globalTrack = fSliceTrackInfos[fSliceTrackGlobalInfoStart[iSlice] + itr];
672 AliHLTTPCGMSliceTrack &localTrack = fSliceTrackInfos[globalTrack.LocalTrackId()];
673 localTrack.SetGlobalTrackId(localTrack.GlobalTrackId(0) != -1, fSliceTrackGlobalInfoStart[iSlice] + itr);
678 //Now collect the merged tracks
680 int nOutTrackClusters = 0;
681 const int kMaxParts = 400;
682 const int kMaxClusters = 1000;
684 const AliHLTTPCGMSliceTrack *trackParts[kMaxParts];
686 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
688 for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
690 AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[fSliceTrackInfoStart[iSlice] + itr];
692 if ( track.Used() ) continue;
693 if ( track.PrevNeighbour() >= 0 ) continue;
696 AliHLTTPCGMSliceTrack *trbase = &track, *tr = &track;
699 if( nParts >= kMaxParts ) break;
700 trackParts[nParts++] = tr;
701 #ifdef GLOBAL_TRACKS_SPECIAL_TREATMENT
702 for (int i = 0;i < 2;i++) if (tr->GlobalTrackId(i) != -1) trackParts[nParts++] = &fSliceTrackInfos[tr->GlobalTrackId(i)];
704 int jtr = tr->SliceNeighbour();
706 tr = &(fSliceTrackInfos[fSliceTrackInfoStart[jSlice] + jtr]);
710 jtr = trbase->NextNeighbour();
712 jSlice = fNextSliceInd[jSlice];
713 trbase = &(fSliceTrackInfos[fSliceTrackInfoStart[jSlice] + jtr]);
715 if( tr->Used() ) break;
722 // unpack and sort clusters
724 std::sort(trackParts, trackParts+nParts, CompareTrackParts );
726 AliHLTTPCCASliceOutCluster tmp[kMaxClusters];
727 int currCluster = nOutTrackClusters;
729 for( int ipart=0; ipart<nParts; ipart++ ){
730 const AliHLTTPCGMSliceTrack *t = trackParts[ipart];
731 int nTrackHits = t->NClusters();
732 if( nHits + nTrackHits >= kMaxClusters ) break;
733 const AliHLTTPCCASliceOutCluster *c= t->OrigTrack()->Clusters();
734 AliHLTTPCCASliceOutCluster *c2 = tmp+nHits + nTrackHits-1;
735 for( int i=0; i<nTrackHits; i++, c++, c2-- ) *c2 = *c;
736 float alpha = t->Alpha();
737 for( int i=0; i<nTrackHits; i++) fClusterAngle[currCluster++] = alpha;
741 if ( nHits < 30 ) continue;
743 float *clX = fClusterX + nOutTrackClusters;
744 clX[0] = tmp[0].GetX();
746 for( int i=1; i<nHits; i++ )
748 clX[i] = tmp[i].GetX();
749 if (clX[i] > clX[i - 1]) ordered = 0;
754 int2 tmpFilter[kMaxClusters];
755 for( int i = 0;i < nHits;i++)
758 tmpFilter[i].y = tmp[i].GetId();
760 qsort(tmpFilter, nHits, sizeof(int2), CompareClusterIds);
761 bool tmpHitsOk[kMaxClusters];
762 tmpHitsOk[tmpFilter[0].x] = true;
763 for (int i = 1;i < nHits;i++)
765 tmpHitsOk[tmpFilter[i].x] = (tmpFilter[i].y != tmpFilter[i - 1].y);
767 int nFilteredHits = 0;
768 float *clA = fClusterAngle + nOutTrackClusters;
769 for (int i = 0;i < nHits;i++)
773 if (nFilteredHits < i)
775 tmp[nFilteredHits] = tmp[i];
776 clA[nFilteredHits] = clA[i];
782 nHits = nFilteredHits;
783 for( int i=0; i<nHits; i++ ) clX[i] = tmp[i].GetX();
786 UInt_t *clId = fOutputClusterIds + nOutTrackClusters;
787 for( int i=0; i<nHits; i++ ) clId[i] = tmp[i].GetId();
789 UInt_t *clT = fClusterRowType + nOutTrackClusters;
790 for( int i=0; i<nHits; i++ ) clT[i] = tmp[i].GetRowType();
792 float *clY = fClusterY + nOutTrackClusters;
793 for( int i=0; i<nHits; i++ ) clY[i] = tmp[i].GetY();
795 float *clZ = fClusterZ + nOutTrackClusters;
796 for( int i=0; i<nHits; i++ ) clZ[i] = tmp[i].GetZ();
798 AliHLTTPCGMMergedTrack &mergedTrack = fOutputTracks[fNOutputTracks];
799 mergedTrack.SetOK(1);
800 mergedTrack.SetNClusters( nHits );
801 mergedTrack.SetFirstClusterRef( nOutTrackClusters );
802 AliHLTTPCGMTrackParam &p1 = mergedTrack.Param();
803 const AliHLTTPCGMSliceTrack &p2 = *(trackParts[0]);
808 p1.SinPhi() = p2.SinPhi();
809 p1.DzDs() = p2.DzDs();
811 mergedTrack.SetAlpha( p2.Alpha() );
814 nOutTrackClusters += nHits;
817 fNOutputTrackClusters = nOutTrackClusters;
820 void AliHLTTPCGMMerger::Refit()
823 #ifdef HLTCA_GPU_MERGER
826 fGPUTracker->RefitMergedTracks(this);
831 #ifdef HLTCA_STANDALONE
832 #pragma omp parallel for
834 for ( int itr = 0; itr < fNOutputTracks; itr++ ) {
836 AliHLTTPCGMMergedTrack &track = fOutputTracks[itr];
837 if( !track.OK() ) continue;
839 int nTrackHits = track.NClusters();
841 AliHLTTPCGMTrackParam t = track.Param();
842 float Alpha = track.Alpha();
844 t.Fit( fPolinomialFieldBz,
845 fClusterX+track.FirstClusterRef(),
846 fClusterY+track.FirstClusterRef(),
847 fClusterZ+track.FirstClusterRef(),
848 fClusterRowType+track.FirstClusterRef(),
849 fClusterAngle+track.FirstClusterRef(),
850 fSliceParam, nTrackHits, Alpha, 0 );
852 if ( fabs( t.QPt() ) < 1.e-4 ) t.QPt() = 1.e-4 ;
854 bool ok = nTrackHits >= 30 && t.CheckNumericalQuality() && fabs( t.SinPhi() ) <= .999;
860 track.SetNClusters( nTrackHits );
862 track.Alpha() = Alpha;
866 int ind = track.FirstClusterRef();
867 float alpha = fClusterAngle[ind];
868 float x = fClusterX[ind];
869 float y = fClusterY[ind];
870 float z = fClusterZ[ind];
871 float sinA = AliHLTTPCCAMath::Sin( alpha - track.Alpha());
872 float cosA = AliHLTTPCCAMath::Cos( alpha - track.Alpha());
873 track.SetLastX( x*cosA - y*sinA );
874 track.SetLastY( x*sinA + y*cosA );