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 AliHLTTPCGMMerger::AliHLTTPCGMMerger()
54 fNOutputTrackClusters( 0 ),
57 fSliceTrackInfos( 0 ),
65 fBorderRangeMemory(0),
72 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
73 fNextSliceInd[iSlice] = iSlice + 1;
74 fPrevSliceInd[iSlice] = iSlice - 1;
76 int mid = fgkNSlices / 2 - 1 ;
77 int last = fgkNSlices - 1 ;
78 fNextSliceInd[ mid ] = 0;
79 fPrevSliceInd[ 0 ] = mid; fNextSliceInd[ last ] = fgkNSlices / 2;
80 fPrevSliceInd[ fgkNSlices/2 ] = last;
86 AliHLTTPCGMMerger::AliHLTTPCGMMerger(const AliHLTTPCGMMerger&)
90 fNOutputTrackClusters( 0 ),
93 fSliceTrackInfos( 0 ),
101 fBorderRangeMemory(0),
107 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
108 fNextSliceInd[iSlice] = 0;
109 fPrevSliceInd[iSlice] = 0;
114 const AliHLTTPCGMMerger &AliHLTTPCGMMerger::operator=(const AliHLTTPCGMMerger&) const
121 AliHLTTPCGMMerger::~AliHLTTPCGMMerger()
127 void AliHLTTPCGMMerger::Clear()
129 for ( int i = 0; i < fgkNSlices; ++i ) {
131 fSliceNTrackInfos[ i ] = 0;
132 fSliceTrackInfoStart[ i ] = 0;
138 void AliHLTTPCGMMerger::ClearMemory()
140 delete[] fOutputClusterIds;
141 delete[] fSliceTrackInfos;
144 delete[] fOutputTracks;
148 delete[] fClusterRowType;
149 delete[] fClusterAngle;
151 delete[] fBorderMemory;
152 delete[] fBorderRangeMemory;
156 fOutputClusterIds = 0;
157 fSliceTrackInfos = 0;
165 fBorderRangeMemory = 0;
169 void AliHLTTPCGMMerger::SetSliceData( int index, const AliHLTTPCCASliceOutput *sliceData )
171 fkSlices[index] = sliceData;
175 bool AliHLTTPCGMMerger::Reconstruct()
177 //* main merging routine
180 const double kCLight = 0.000299792458;
181 double constBz = fSliceParam.BzkG() * kCLight;
183 fPolinomialFieldBz[0] = constBz * ( 0.999286 );
184 fPolinomialFieldBz[1] = constBz * ( -4.54386e-7 );
185 fPolinomialFieldBz[2] = constBz * ( 2.32950e-5 );
186 fPolinomialFieldBz[3] = constBz * ( -2.99912e-7 );
187 fPolinomialFieldBz[4] = constBz * ( -2.03442e-8 );
188 fPolinomialFieldBz[5] = constBz * ( 9.71402e-8 );
193 #ifdef HLTCA_STANDALONE
194 unsigned long long int a, b, c, d, e, f, g;
195 AliHLTTPCCATracker::StandaloneQueryFreq(&g);
197 //cout<<"Merger..."<<endl;
198 for( int iter=0; iter<nIter; iter++ ){
199 if( !AllocateMemory() ) return 0;
200 #ifdef HLTCA_STANDALONE
201 AliHLTTPCCATracker::StandaloneQueryTime(&a);
204 #ifdef HLTCA_STANDALONE
205 AliHLTTPCCATracker::StandaloneQueryTime(&b);
207 MergeWithingSlices();
208 #ifdef HLTCA_STANDALONE
209 AliHLTTPCCATracker::StandaloneQueryTime(&c);
212 #ifdef HLTCA_STANDALONE
213 AliHLTTPCCATracker::StandaloneQueryTime(&d);
215 CollectMergedTracks();
216 #ifdef HLTCA_STANDALONE
217 AliHLTTPCCATracker::StandaloneQueryTime(&e);
220 #ifdef HLTCA_STANDALONE
221 AliHLTTPCCATracker::StandaloneQueryTime(&f);
224 printf("Merge Time:\tUnpack Slices:\t%lld us\n", (b - a) * 1000000 / g);
225 printf("\t\tMerge Within:\t%lld us\n", (c - b) * 1000000 / g);
226 printf("\t\tMerge Slices:\t%lld us\n", (d - c) * 1000000 / g);
227 printf("\t\tCollect:\t%lld us\n", (e - d) * 1000000 / g);
228 printf("\t\tRefit:\t\t%lld us\n", (f - e) * 1000000 / g);
231 for (int i = 0;i < fNOutputTracks;i++) if (fOutputTracks[i].OK()) newTracks++;
232 printf("Output Tracks: %d\n", newTracks);
236 //cout<<"\nMerger time = "<<timer.CpuTime()*1.e3/nIter<<" ms\n"<<endl;
243 bool AliHLTTPCGMMerger::AllocateMemory()
245 //* memory allocation
253 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
254 if ( !fkSlices[iSlice] ) continue;
255 nTracks += fkSlices[iSlice]->NTracks();
256 fNClusters += fkSlices[iSlice]->NTrackClusters();
257 if( fMaxSliceTracks < fkSlices[iSlice]->NTracks() ) fMaxSliceTracks = fkSlices[iSlice]->NTracks();
260 //cout<<"\nMerger: input "<<nTracks<<" tracks, "<<nClusters<<" clusters"<<endl;
262 fOutputClusterIds = new UInt_t[fNClusters];
263 fSliceTrackInfos = new AliHLTTPCGMSliceTrack[nTracks];
266 char* basemem = fGPUTracker->MergerBaseMemory();
267 AssignMemory(fClusterX, basemem, fNClusters);
268 AssignMemory(fClusterY, basemem, fNClusters);
269 AssignMemory(fClusterZ, basemem, fNClusters);
270 AssignMemory(fClusterAngle, basemem, fNClusters);
271 AssignMemory(fClusterRowType, basemem, fNClusters);
272 AssignMemory(fOutputTracks, basemem, nTracks);
276 fOutputTracks = new AliHLTTPCGMMergedTrack[nTracks];
277 fClusterX = new float[fNClusters];
278 fClusterY = new float[fNClusters];
279 fClusterZ = new float[fNClusters];
280 fClusterRowType = new UInt_t[fNClusters];
281 fClusterAngle = new float[fNClusters];
283 fBorderMemory = new AliHLTTPCGMBorderTrack[fMaxSliceTracks*2];
284 fBorderRangeMemory = new AliHLTTPCGMBorderTrack::Range[fMaxSliceTracks*2];
286 return ( ( fOutputTracks!=NULL )
287 && ( fOutputClusterIds!=NULL )
288 && ( fSliceTrackInfos!=NULL )
289 && ( fClusterX!=NULL )
290 && ( fClusterY!=NULL )
291 && ( fClusterZ!=NULL )
292 && ( fClusterRowType!=NULL )
293 && ( fClusterAngle!=NULL )
294 && ( fBorderMemory!=NULL )
295 && ( fBorderRangeMemory!=NULL )
301 void AliHLTTPCGMMerger::UnpackSlices()
303 //* unpack the cluster information from the slice tracks and initialize track info array
305 int nTracksCurrent = 0;
306 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
308 fSliceTrackInfoStart[ iSlice ] = nTracksCurrent;
310 fSliceNTrackInfos[ iSlice ] = 0;
312 if ( !fkSlices[iSlice] ) continue;
314 float alpha = fSliceParam.Alpha( iSlice );
316 const AliHLTTPCCASliceOutput &slice = *( fkSlices[iSlice] );
317 const AliHLTTPCCASliceOutTrack *sliceTr = slice.GetFirstTrack();
319 for ( int itr = 0; itr < slice.NTracks(); itr++, sliceTr = sliceTr->GetNextTrack() ) {
320 AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[nTracksCurrent];
321 track.Set( sliceTr, alpha );
322 if( !track.FilterErrors( fSliceParam, .999 ) ) continue;
323 track.SetPrevNeighbour( -1 );
324 track.SetNextNeighbour( -1 );
325 track.SetSliceNeighbour( -1 );
328 fSliceNTrackInfos[ iSlice ]++;
331 //std::cout<<"Unpack slice "<<iSlice<<": ntracks "<<slice.NTracks()<<"/"<<fSliceNTrackInfos[iSlice]<<std::endl;
339 void AliHLTTPCGMMerger::MakeBorderTracks( int iSlice, int iBorder, AliHLTTPCGMBorderTrack B[], int &nB )
341 //* prepare slice tracks for merging with next/previous/same sector
342 //* each track transported to the border line
344 float fieldBz = fSliceParam.ConstBz();
348 float dAlpha = fSliceParam.DAlpha() / 2;
351 if ( iBorder == 0 ) { // transport to the left age of the sector and rotate horisontally
352 dAlpha = dAlpha - CAMath::Pi() / 2 ;
353 } else if ( iBorder == 1 ) { // transport to the right age of the sector and rotate horisontally
354 dAlpha = -dAlpha - CAMath::Pi() / 2 ;
355 } else if ( iBorder == 2 ) { // transport to the left age of the sector and rotate vertically
357 x0 = fSliceParam.RowX( 63 );
358 } else if ( iBorder == 3 ) { // transport to the right age of the sector and rotate vertically
360 x0 = fSliceParam.RowX( 63 );
361 } else if ( iBorder == 4 ) { // transport to the middle of the sector, w/o rotation
363 x0 = fSliceParam.RowX( 63 );
366 const float maxSin = CAMath::Sin( 60. / 180.*CAMath::Pi() );
367 float cosAlpha = AliHLTTPCCAMath::Cos( dAlpha );
368 float sinAlpha = AliHLTTPCCAMath::Sin( dAlpha );
370 for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
372 AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[ fSliceTrackInfoStart[iSlice] + itr ];
374 if( track.Used() ) continue;
375 AliHLTTPCGMBorderTrack &b = B[nB];
377 if( track.TransportToXAlpha( x0, sinAlpha, cosAlpha, fieldBz, b, maxSin)){
379 b.SetNClusters( track.NClusters() );
386 void AliHLTTPCGMMerger::MergeBorderTracks ( int iSlice1, AliHLTTPCGMBorderTrack B1[], int N1,
387 int iSlice2, AliHLTTPCGMBorderTrack B2[], int N2 )
389 //* merge two sets of tracks
391 //std::cout<<" Merge slices "<<iSlice1<<"+"<<iSlice2<<": tracks "<<N1<<"+"<<N2<<std::endl;
392 int statAll=0, statMerged=0;
393 float factor2ys = 1.5;//1.5;//SG!!!
394 float factor2zt = 1.5;//1.5;//SG!!!
395 float factor2k = 2.0;//2.2;
397 factor2k = 3.5 * 3.5 * factor2k * factor2k;
398 factor2ys = 3.5 * 3.5 * factor2ys * factor2ys;
399 factor2zt = 3.5 * 3.5 * factor2zt * factor2zt;
401 int minNPartHits = 10;//SG!!!
402 int minNTotalHits = 20;
404 AliHLTTPCGMBorderTrack::Range *range1 = fBorderRangeMemory;
405 AliHLTTPCGMBorderTrack::Range *range2 = fBorderRangeMemory + N1;
407 bool sameSlice = (iSlice1 == iSlice2);
409 for ( int itr = 0; itr < N1; itr++ ){
410 AliHLTTPCGMBorderTrack &b = B1[itr];
411 // if( iSlice1==7 && iSlice2==8 ){
412 //cout<<b.TrackID()<<": "<<b.Cov()[0]<<" "<<b.Cov()[1]<<endl;
414 float d = 3.5*sqrt(b.Cov()[1]);
415 range1[itr].fId = itr;
416 range1[itr].fMin = b.Par()[1] - d;
417 range1[itr].fMax = b.Par()[1] + d;
419 std::sort(range1,range1+N1,AliHLTTPCGMBorderTrack::Range::CompMin);
421 for(int i=0; i<N1; i++) range2[i]= range1[i];
422 std::sort(range2,range2+N1,AliHLTTPCGMBorderTrack::Range::CompMax);
426 for ( int itr = 0; itr < N2; itr++ ){
427 AliHLTTPCGMBorderTrack &b = B2[itr];
428 float d = 3.5*sqrt(b.Cov()[1]);
429 range2[itr].fId = itr;
430 range2[itr].fMin = b.Par()[1] - d;
431 range2[itr].fMax = b.Par()[1] + d;
433 std::sort(range2,range2+N2,AliHLTTPCGMBorderTrack::Range::CompMax);
438 for ( int i1 = 0; i1 < N1; i1++ ) {
440 AliHLTTPCGMBorderTrack::Range r1 = range1[i1];
441 while( i2<N2 && range2[i2].fMax< r1.fMin ) i2++;
443 AliHLTTPCGMBorderTrack &b1 = B1[r1.fId];
444 if ( b1.NClusters() < minNPartHits ) continue;
448 for( int k2 = i2; k2<N2; k2++){
450 AliHLTTPCGMBorderTrack::Range r2 = range2[k2];
451 if( r2.fMin > r1.fMax ) break;
452 if( sameSlice && (r1.fId >= r2.fId) ) continue;
454 AliHLTTPCGMBorderTrack &b2 = B2[r2.fId];
455 if ( b2.NClusters() < lBest2 ) continue;
457 if( !b1.CheckChi2Y(b2, factor2ys ) ) continue;
458 //if( !b1.CheckChi2Z(b2, factor2zt ) ) continue;
459 if( !b1.CheckChi2QPt(b2, factor2k ) ) continue;
460 if( !b1.CheckChi2YS(b2, factor2ys ) ) continue;
461 if( !b1.CheckChi2ZT(b2, factor2zt ) ) continue;
462 if ( b2.NClusters() < minNPartHits ) continue;
463 if ( b1.NClusters() + b2.NClusters() < minNTotalHits ) continue;
465 lBest2 = b2.NClusters();
466 iBest2 = b2.TrackID();
469 if ( iBest2 < 0 ) continue;
471 AliHLTTPCGMSliceTrack &newTrack1 = fSliceTrackInfos[fSliceTrackInfoStart[iSlice1] + b1.TrackID() ];
472 AliHLTTPCGMSliceTrack &newTrack2 = fSliceTrackInfos[fSliceTrackInfoStart[iSlice2] + iBest2 ];
474 int old1 = newTrack2.PrevNeighbour();
477 AliHLTTPCGMSliceTrack &oldTrack1 = fSliceTrackInfos[fSliceTrackInfoStart[iSlice1] + old1];
478 if ( oldTrack1.NClusters() < newTrack1.NClusters() ) {
479 newTrack2.SetPrevNeighbour( -1 );
480 oldTrack1.SetNextNeighbour( -1 );
483 int old2 = newTrack1.NextNeighbour();
485 AliHLTTPCGMSliceTrack &oldTrack2 = fSliceTrackInfos[fSliceTrackInfoStart[iSlice2] + old2];
486 if ( oldTrack2.NClusters() < newTrack2.NClusters() ) {
487 oldTrack2.SetPrevNeighbour( -1 );
490 newTrack1.SetNextNeighbour( iBest2 );
491 newTrack2.SetPrevNeighbour( b1.TrackID() );
493 //cout<<"slices "<<iSlice1<<","<<iSlice2<<": all "<<statAll<<" merged "<<statMerged<<endl;
497 void AliHLTTPCGMMerger::MergeWithingSlices()
499 //* merge track segments withing one slice
501 float x0 = fSliceParam.RowX( 63 );
502 const float maxSin = CAMath::Sin( 60. / 180.*CAMath::Pi() );
504 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
507 for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
508 AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[ fSliceTrackInfoStart[iSlice] + itr ];
509 //track.SetPrevNeighbour( -1 );
510 //track.SetNextNeighbour( -1 );
511 //track.SetSliceNeighbour( -1 );
514 AliHLTTPCGMBorderTrack &b = fBorderMemory[nBord];
515 if( track.TransportToX( x0, fSliceParam.ConstBz(), b, maxSin) ){
517 b.SetNClusters( track.NClusters() );
522 MergeBorderTracks( iSlice, fBorderMemory, nBord, iSlice, fBorderMemory, nBord );
524 for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
525 AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[ fSliceTrackInfoStart[iSlice] + itr];
526 if( track.PrevNeighbour()>=0 || track.Used() ) continue;
527 int jtr = track.NextNeighbour();
528 track.SetSliceNeighbour( jtr );
529 track.SetNextNeighbour(-1);
531 AliHLTTPCGMSliceTrack &trackN = fSliceTrackInfos[ fSliceTrackInfoStart[iSlice] + jtr];
532 if( trackN.NClusters()>track.NClusters() ) track.CopyParamFrom(trackN);
534 jtr = trackN.NextNeighbour();
535 trackN.SetSliceNeighbour( jtr );
536 trackN.SetNextNeighbour(-1);
537 trackN.SetPrevNeighbour(-1);
546 void AliHLTTPCGMMerger::MergeSlices()
548 //* track merging between slices
550 //for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
551 //for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
552 //AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[ fSliceTrackInfoStart[iSlice] + itr ];
553 //track.SetPrevNeighbour( -1 );
554 //track.SetNextNeighbour( -1 );
558 AliHLTTPCGMBorderTrack
559 *bCurr = fBorderMemory,
560 *bNext = fBorderMemory + fMaxSliceTracks;
562 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
563 int jSlice = fNextSliceInd[iSlice];
564 int nCurr = 0, nNext = 0;
565 MakeBorderTracks( iSlice, 2, bCurr, nCurr );
566 MakeBorderTracks( jSlice, 3, bNext, nNext );
567 MergeBorderTracks( iSlice, bCurr, nCurr, jSlice, bNext, nNext );
568 MakeBorderTracks( iSlice, 0, bCurr, nCurr );
569 MakeBorderTracks( jSlice, 1, bNext, nNext );
570 MergeBorderTracks( iSlice, bCurr, nCurr, jSlice, bNext, nNext );
578 void AliHLTTPCGMMerger::CollectMergedTracks()
582 //for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
583 //for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
584 //AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[ fSliceTrackInfoStart[iSlice] + itr ];
585 //if( track.Used()!=2 ) track.SetUsed(0);
590 int nOutTrackClusters = 0;
591 const int kMaxParts = 400;
592 const int kMaxClusters = 1000;
594 const AliHLTTPCGMSliceTrack *trackParts[kMaxParts];
596 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
598 for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
600 AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[fSliceTrackInfoStart[iSlice] + itr];
602 if ( track.Used() ) continue;
603 if ( track.PrevNeighbour() >= 0 ) continue;
606 AliHLTTPCGMSliceTrack *trbase = &track, *tr = &track;
609 if( nParts >= kMaxParts ) break;
610 trackParts[nParts++] = tr;
611 int jtr = tr->SliceNeighbour();
613 tr = &(fSliceTrackInfos[fSliceTrackInfoStart[jSlice] + jtr]);
617 jtr = trbase->NextNeighbour();
619 jSlice = fNextSliceInd[jSlice];
620 trbase = &(fSliceTrackInfos[fSliceTrackInfoStart[jSlice] + jtr]);
622 if( tr->Used() ) break;
629 // unpack and sort clusters
631 std::sort(trackParts, trackParts+nParts, CompareTrackParts );
633 AliHLTTPCCASliceOutCluster tmp[kMaxClusters];
634 int currCluster = nOutTrackClusters;
636 for( int ipart=0; ipart<nParts; ipart++ ){
637 const AliHLTTPCGMSliceTrack *t = trackParts[ipart];
638 int nTrackHits = t->NClusters();
639 if( nHits + nTrackHits >= kMaxClusters ) break;
640 const AliHLTTPCCASliceOutCluster *c= t->OrigTrack()->Clusters();
641 AliHLTTPCCASliceOutCluster *c2 = tmp+nHits + nTrackHits-1;
642 for( int i=0; i<nTrackHits; i++, c++, c2-- ) *c2 = *c;
643 float alpha = t->Alpha();
644 for( int i=0; i<nTrackHits; i++) fClusterAngle[currCluster++] = alpha;
648 UInt_t *clId = fOutputClusterIds + nOutTrackClusters;
649 for( int i=0; i<nHits; i++ ) clId[i] = tmp[i].GetId();
651 UInt_t *clT = fClusterRowType + nOutTrackClusters;
652 for( int i=0; i<nHits; i++ ) clT[i] = tmp[i].GetRowType();
654 float *clX = fClusterX + nOutTrackClusters;
655 for( int i=0; i<nHits; i++ ) clX[i] = tmp[i].GetX();
657 float *clY = fClusterY + nOutTrackClusters;
658 for( int i=0; i<nHits; i++ ) clY[i] = tmp[i].GetY();
660 float *clZ = fClusterZ + nOutTrackClusters;
661 for( int i=0; i<nHits; i++ ) clZ[i] = tmp[i].GetZ();
663 if ( nHits < 30 ) continue;
665 AliHLTTPCGMMergedTrack &mergedTrack = fOutputTracks[fNOutputTracks];
666 mergedTrack.SetOK(1);
667 mergedTrack.SetNClusters( nHits );
668 mergedTrack.SetFirstClusterRef( nOutTrackClusters );
669 AliHLTTPCGMTrackParam &p1 = mergedTrack.Param();
670 const AliHLTTPCGMSliceTrack &p2 = *(trackParts[0]);
675 p1.SinPhi() = p2.SinPhi();
676 p1.DzDs() = p2.DzDs();
678 mergedTrack.SetAlpha( p2.Alpha() );
681 nOutTrackClusters += nHits;
684 fNOutputTrackClusters = nOutTrackClusters;
687 void AliHLTTPCGMMerger::Refit()
690 #ifdef HLTCA_GPU_MERGER
693 fGPUTracker->RefitMergedTracks(this);
698 #ifdef HLTCA_STANDALONE
699 #pragma omp parallel for
701 for ( int itr = 0; itr < fNOutputTracks; itr++ ) {
702 AliHLTTPCGMMergedTrack &track = fOutputTracks[itr];
703 if( !track.OK() ) continue;
705 int nTrackHits = track.NClusters();
707 AliHLTTPCGMTrackParam t = track.Param();
708 float Alpha = track.Alpha();
710 t.Fit( fPolinomialFieldBz,
711 fClusterX+track.FirstClusterRef(),
712 fClusterY+track.FirstClusterRef(),
713 fClusterZ+track.FirstClusterRef(),
714 fClusterRowType+track.FirstClusterRef(),
715 fClusterAngle+track.FirstClusterRef(),
716 fSliceParam, nTrackHits, Alpha, 0 );
718 if ( fabs( t.QPt() ) < 1.e-4 ) t.QPt() = 1.e-4 ;
720 bool ok = nTrackHits >= 30 && t.CheckNumericalQuality() && fabs( t.SinPhi() ) <= .999;
725 track.SetNClusters( nTrackHits );
727 track.Alpha() = Alpha;
731 int ind = track.FirstClusterRef();
732 float alpha = fClusterAngle[ind];
733 float x = fClusterX[ind];
734 float y = fClusterY[ind];
735 float z = fClusterZ[ind];
736 float sinA = AliHLTTPCCAMath::Sin( alpha - track.Alpha());
737 float cosA = AliHLTTPCCAMath::Cos( alpha - track.Alpha());
738 track.SetLastX( x*cosA - y*sinA );
739 track.SetLastY( x*sinA + y*cosA );