]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/TPCLib/merger-ca/AliHLTTPCGMMerger.cxx
Revert previous commit
[u/mrichter/AliRoot.git] / HLT / TPCLib / merger-ca / AliHLTTPCGMMerger.cxx
CommitLineData
6d869045 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. *
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 <stdio.h>
21#include "AliHLTTPCCASliceOutTrack.h"
22#include "AliHLTTPCCATracker.h"
23#include "AliHLTTPCCATrackParam.h"
24#include "AliHLTTPCGMCluster.h"
25
26#include "AliHLTTPCGMMerger.h"
27
28#include "AliHLTTPCCAMath.h"
29#include "TStopwatch.h"
30
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"
38
39#include "AliHLTTPCGMTrackParam.h"
40#include "AliHLTTPCGMTrackLinearisation.h"
41#include "AliHLTTPCGMSliceTrack.h"
42#include "AliHLTTPCGMBorderTrack.h"
b0a6cd38 43#include <cmath>
6d869045 44
45
46
47AliHLTTPCGMMerger::AliHLTTPCGMMerger()
48 :
49 fSliceParam(),
50 fNOutputTracks( 0 ),
51 fOutputTracks( 0 ),
52 fOutputClusterIds(0),
53 fSliceTrackInfos( 0 ),
54 fMaxSliceTracks(0),
55 fClusterX(0),
56 fClusterY(0),
57 fClusterZ(0),
58 fClusterRowType(0),
59 fClusterAngle(0),
60 fBorderMemory(0),
61 fBorderRangeMemory(0)
62{
63 //* constructor
64
65 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
66 fNextSliceInd[iSlice] = iSlice + 1;
67 fPrevSliceInd[iSlice] = iSlice - 1;
68 }
69 int mid = fgkNSlices / 2 - 1 ;
70 int last = fgkNSlices - 1 ;
71 if ( mid < 0 ) mid = 0; // to avoid compiler warning
72 if ( last < 0 ) last = 0; //
73 fNextSliceInd[ mid ] = 0;
74 fPrevSliceInd[ 0 ] = mid; fNextSliceInd[ last ] = fgkNSlices / 2;
75 fPrevSliceInd[ fgkNSlices/2 ] = last;
76
77 Clear();
78}
79
80
81AliHLTTPCGMMerger::AliHLTTPCGMMerger(const AliHLTTPCGMMerger&)
82 :
83 fSliceParam(),
84 fNOutputTracks( 0 ),
85 fOutputTracks( 0 ),
86 fOutputClusterIds(0),
87 fSliceTrackInfos( 0 ),
88 fMaxSliceTracks(0),
89 fClusterX(0),
90 fClusterY(0),
91 fClusterZ(0),
92 fClusterRowType(0),
93 fClusterAngle(0),
94 fBorderMemory(0),
95 fBorderRangeMemory(0)
96{
97 //* dummy
98}
99
100const AliHLTTPCGMMerger &AliHLTTPCGMMerger::operator=(const AliHLTTPCGMMerger&) const
101{
102 //* dummy
103 return *this;
104}
105
106
107AliHLTTPCGMMerger::~AliHLTTPCGMMerger()
108{
109 //* destructor
110 ClearMemory();
111}
112
113void AliHLTTPCGMMerger::Clear()
114{
115 for ( int i = 0; i < fgkNSlices; ++i ) {
116 fkSlices[i] = 0;
117 fSliceNTrackInfos[ i ] = 0;
118 fSliceTrackInfoStart[ i ] = 0;
119 }
120 ClearMemory();
121}
122
123
124void AliHLTTPCGMMerger::ClearMemory()
125{
126 delete[] fOutputTracks;
127 delete[] fOutputClusterIds;
128 delete[] fSliceTrackInfos;
129 delete[] fClusterX;
130 delete[] fClusterY;
131 delete[] fClusterZ;
132 delete[] fClusterRowType;
133 delete[] fClusterAngle;
134 delete[] fBorderMemory;
135 delete[] fBorderRangeMemory;
136
137 fNOutputTracks = 0;
138 fOutputTracks = 0;
139 fOutputClusterIds = 0;
140 fSliceTrackInfos = 0;
141 fMaxSliceTracks = 0;
142 fClusterX = 0;
143 fClusterY = 0;
144 fClusterZ = 0;
145 fClusterRowType = 0;
146 fClusterAngle = 0;
147 fBorderMemory = 0;
148 fBorderRangeMemory = 0;
149}
150
151
152void AliHLTTPCGMMerger::SetSliceData( int index, const AliHLTTPCCASliceOutput *sliceData )
153{
154 fkSlices[index] = sliceData;
155}
156
157
158bool AliHLTTPCGMMerger::Reconstruct()
159{
160 //* main merging routine
161
162 {
163 const double kCLight = 0.000299792458;
164 double constBz = fSliceParam.BzkG() * kCLight;
165
166 AliHLTTPCGMTrackParam::fPolinomialFieldBz[0] = constBz * ( 0.999286 );
167 AliHLTTPCGMTrackParam::fPolinomialFieldBz[1] = constBz * ( -4.54386e-7 );
168 AliHLTTPCGMTrackParam::fPolinomialFieldBz[2] = constBz * ( 2.32950e-5 );
169 AliHLTTPCGMTrackParam::fPolinomialFieldBz[3] = constBz * ( -2.99912e-7 );
170 AliHLTTPCGMTrackParam::fPolinomialFieldBz[4] = constBz * ( -2.03442e-8 );
171 AliHLTTPCGMTrackParam::fPolinomialFieldBz[5] = constBz * ( 9.71402e-8 );
172 }
173
2d15d6ff 174 int nIter = 1;
6d869045 175 TStopwatch timer;
2d15d6ff 176 //cout<<"Merger..."<<endl;
6d869045 177 for( int iter=0; iter<nIter; iter++ ){
178 if( !AllocateMemory() ) return 0;
179 UnpackSlices();
180 MergeWithingSlices();
181 MergeSlices();
182 CollectMergedTracks();
183 Refit();
184 }
185 timer.Stop();
2d15d6ff 186 //cout<<"\nMerger time = "<<timer.CpuTime()*1.e3/nIter<<" ms\n"<<endl;
6d869045 187
188 return 1;
189}
190
191
192
193bool AliHLTTPCGMMerger::AllocateMemory()
194{
195 //* memory allocation
196
197 ClearMemory();
198
199 int nTracks = 0;
200 int nClusters = 0;
201 fMaxSliceTracks = 0;
202
203 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
204 if ( !fkSlices[iSlice] ) continue;
205 nTracks += fkSlices[iSlice]->NTracks();
206 nClusters += fkSlices[iSlice]->NTrackClusters();
207 if( fMaxSliceTracks < fkSlices[iSlice]->NTracks() ) fMaxSliceTracks = fkSlices[iSlice]->NTracks();
208 }
209
210 //cout<<"\nMerger: input "<<nTracks<<" tracks, "<<nClusters<<" clusters"<<endl;
211
212 fOutputTracks = new AliHLTTPCGMMergedTrack[nTracks];
213 fOutputClusterIds = new UInt_t[nClusters];
214 fSliceTrackInfos = new AliHLTTPCGMSliceTrack[nTracks];
215 fClusterX = new float[nClusters];
216 fClusterY = new float[nClusters];
217 fClusterZ = new float[nClusters];
218 fClusterRowType = new UInt_t[nClusters];
219 fClusterAngle = new float[nClusters];
220 fBorderMemory = new AliHLTTPCGMBorderTrack[fMaxSliceTracks*2];
221 fBorderRangeMemory = new AliHLTTPCGMBorderTrack::Range[fMaxSliceTracks*2];
222
223 return ( ( fOutputTracks!=NULL )
224 && ( fOutputClusterIds!=NULL )
225 && ( fSliceTrackInfos!=NULL )
226 && ( fClusterX!=NULL )
227 && ( fClusterY!=NULL )
228 && ( fClusterZ!=NULL )
229 && ( fClusterRowType!=NULL )
230 && ( fClusterAngle!=NULL )
231 && ( fBorderMemory!=NULL )
232 && ( fBorderRangeMemory!=NULL )
233 );
234}
235
236
237
238void AliHLTTPCGMMerger::UnpackSlices()
239{
240 //* unpack the cluster information from the slice tracks and initialize track info array
241
242 int nTracksCurrent = 0;
243 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
244
245 fSliceTrackInfoStart[ iSlice ] = nTracksCurrent;
246
247 fSliceNTrackInfos[ iSlice ] = 0;
248
249 if ( !fkSlices[iSlice] ) continue;
250
251 float alpha = fSliceParam.Alpha( iSlice );
252
253 const AliHLTTPCCASliceOutput &slice = *( fkSlices[iSlice] );
254 const AliHLTTPCCASliceOutTrack *sliceTr = slice.GetFirstTrack();
255
256 for ( int itr = 0; itr < slice.NTracks(); itr++, sliceTr = sliceTr->GetNextTrack() ) {
257 AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[nTracksCurrent];
258 track.Set( sliceTr, alpha );
259 if( !track.FilterErrors( fSliceParam, .999 ) ) continue;
260 track.SetPrevNeighbour( -1 );
261 track.SetNextNeighbour( -1 );
262 track.SetSliceNeighbour( -1 );
263 track.SetUsed( 0 );
264 nTracksCurrent++;
265 fSliceNTrackInfos[ iSlice ]++;
266 }
267
268 //std::cout<<"Unpack slice "<<iSlice<<": ntracks "<<slice.NTracks()<<"/"<<fSliceNTrackInfos[iSlice]<<std::endl;
269 }
270}
271
272
273
274
275
276void AliHLTTPCGMMerger::MakeBorderTracks( int iSlice, int iBorder, AliHLTTPCGMBorderTrack B[], int &nB )
277{
278 //* prepare slice tracks for merging with next/previous/same sector
279 //* each track transported to the border line
280
281 float fieldBz = fSliceParam.ConstBz();
282
283 nB = 0;
284
285 float dAlpha = fSliceParam.DAlpha() / 2;
286 float x0 = 0;
287
288 if ( iBorder == 0 ) { // transport to the left age of the sector and rotate horisontally
289 dAlpha = dAlpha - CAMath::Pi() / 2 ;
290 } else if ( iBorder == 1 ) { // transport to the right age of the sector and rotate horisontally
291 dAlpha = -dAlpha - CAMath::Pi() / 2 ;
292 } else if ( iBorder == 2 ) { // transport to the left age of the sector and rotate vertically
293 dAlpha = dAlpha;
294 x0 = fSliceParam.RowX( 63 );
295 } else if ( iBorder == 3 ) { // transport to the right age of the sector and rotate vertically
296 dAlpha = -dAlpha;
297 x0 = fSliceParam.RowX( 63 );
298 } else if ( iBorder == 4 ) { // transport to the middle of the sector, w/o rotation
299 dAlpha = 0;
300 x0 = fSliceParam.RowX( 63 );
301 }
302
303 const float maxSin = CAMath::Sin( 60. / 180.*CAMath::Pi() );
304 float cosAlpha = TMath::Cos( dAlpha );
305 float sinAlpha = TMath::Sin( dAlpha );
306
307 for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
308
309 AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[ fSliceTrackInfoStart[iSlice] + itr ];
310
311 if( track.Used() ) continue;
312 AliHLTTPCGMBorderTrack &b = B[nB];
313
314 if( track.TransportToXAlpha( x0, sinAlpha, cosAlpha, fieldBz, b, maxSin)){
315 b.SetTrackID( itr );
316 b.SetNClusters( track.NClusters() );
317 nB++;
318 }
319 }
320}
321
322
323void AliHLTTPCGMMerger::MergeBorderTracks ( int iSlice1, AliHLTTPCGMBorderTrack B1[], int N1,
324 int iSlice2, AliHLTTPCGMBorderTrack B2[], int N2 )
325{
326 //* merge two sets of tracks
327
328 //std::cout<<" Merge slices "<<iSlice1<<"+"<<iSlice2<<": tracks "<<N1<<"+"<<N2<<std::endl;
329 int statAll=0, statMerged=0;
330 float factor2ys = 1.5;//1.5;//SG!!!
331 float factor2zt = 1.5;//1.5;//SG!!!
332 float factor2k = 2.0;//2.2;
333
334 factor2k = 3.5 * 3.5 * factor2k * factor2k;
335 factor2ys = 3.5 * 3.5 * factor2ys * factor2ys;
336 factor2zt = 3.5 * 3.5 * factor2zt * factor2zt;
337
338 int minNPartHits = 10;//SG!!!
339 int minNTotalHits = 20;
340
341 AliHLTTPCGMBorderTrack::Range *range1 = fBorderRangeMemory;
342 AliHLTTPCGMBorderTrack::Range *range2 = fBorderRangeMemory + N1;
343
344 bool sameSlice = (iSlice1 == iSlice2);
345 {
346 for ( int itr = 0; itr < N1; itr++ ){
347 AliHLTTPCGMBorderTrack &b = B1[itr];
348 // if( iSlice1==7 && iSlice2==8 ){
349 //cout<<b.TrackID()<<": "<<b.Cov()[0]<<" "<<b.Cov()[1]<<endl;
350 //}
351 float d = 3.5*sqrt(b.Cov()[1]);
352 range1[itr].fId = itr;
353 range1[itr].fMin = b.Par()[1] - d;
354 range1[itr].fMax = b.Par()[1] + d;
355 }
356 std::sort(range1,range1+N1,AliHLTTPCGMBorderTrack::Range::CompMin);
357 if( sameSlice ){
358 for(int i=0; i<N1; i++) range2[i]= range1[i];
359 std::sort(range2,range2+N1,AliHLTTPCGMBorderTrack::Range::CompMax);
360 N2 = N1;
361 B2 = B1;
362 }else{
363 for ( int itr = 0; itr < N2; itr++ ){
364 AliHLTTPCGMBorderTrack &b = B2[itr];
365 float d = 3.5*sqrt(b.Cov()[1]);
366 range2[itr].fId = itr;
367 range2[itr].fMin = b.Par()[1] - d;
368 range2[itr].fMax = b.Par()[1] + d;
369 }
370 std::sort(range2,range2+N2,AliHLTTPCGMBorderTrack::Range::CompMax);
371 }
372 }
373
374 int i2 = 0;
375 for ( int i1 = 0; i1 < N1; i1++ ) {
376
377 AliHLTTPCGMBorderTrack::Range r1 = range1[i1];
378 while( i2<N2 && range2[i2].fMax< r1.fMin ) i2++;
379
380 AliHLTTPCGMBorderTrack &b1 = B1[r1.fId];
381 if ( b1.NClusters() < minNPartHits ) continue;
382 int iBest2 = -1;
383 int lBest2 = 0;
384 statAll++;
385 for( int k2 = i2; k2<N2; k2++){
386
387 AliHLTTPCGMBorderTrack::Range r2 = range2[k2];
388 if( r2.fMin > r1.fMax ) break;
389 if( sameSlice && (r1.fId >= r2.fId) ) continue;
390 // do check
391 AliHLTTPCGMBorderTrack &b2 = B2[r2.fId];
392 if ( b2.NClusters() < lBest2 ) continue;
393
394 if( !b1.CheckChi2Y(b2, factor2ys ) ) continue;
395 //if( !b1.CheckChi2Z(b2, factor2zt ) ) continue;
396 if( !b1.CheckChi2QPt(b2, factor2k ) ) continue;
397 if( !b1.CheckChi2YS(b2, factor2ys ) ) continue;
398 if( !b1.CheckChi2ZT(b2, factor2zt ) ) continue;
399 if ( b2.NClusters() < minNPartHits ) continue;
400 if ( b1.NClusters() + b2.NClusters() < minNTotalHits ) continue;
401
402 lBest2 = b2.NClusters();
403 iBest2 = b2.TrackID();
404 }
405
406 if ( iBest2 < 0 ) continue;
407 statMerged++;
408 AliHLTTPCGMSliceTrack &newTrack1 = fSliceTrackInfos[fSliceTrackInfoStart[iSlice1] + b1.TrackID() ];
409 AliHLTTPCGMSliceTrack &newTrack2 = fSliceTrackInfos[fSliceTrackInfoStart[iSlice2] + iBest2 ];
410
411 int old1 = newTrack2.PrevNeighbour();
412
413 if ( old1 >= 0 ) {
414 AliHLTTPCGMSliceTrack &oldTrack1 = fSliceTrackInfos[fSliceTrackInfoStart[iSlice1] + old1];
415 if ( oldTrack1.NClusters() < newTrack1.NClusters() ) {
416 newTrack2.SetPrevNeighbour( -1 );
417 oldTrack1.SetNextNeighbour( -1 );
418 } else continue;
419 }
420 int old2 = newTrack1.NextNeighbour();
421 if ( old2 >= 0 ) {
422 AliHLTTPCGMSliceTrack &oldTrack2 = fSliceTrackInfos[fSliceTrackInfoStart[iSlice2] + old2];
423 if ( oldTrack2.NClusters() < newTrack2.NClusters() ) {
424 oldTrack2.SetPrevNeighbour( -1 );
425 } else continue;
426 }
427 newTrack1.SetNextNeighbour( iBest2 );
428 newTrack2.SetPrevNeighbour( b1.TrackID() );
429 }
430 //cout<<"slices "<<iSlice1<<","<<iSlice2<<": all "<<statAll<<" merged "<<statMerged<<endl;
431}
432
433
434void AliHLTTPCGMMerger::MergeWithingSlices()
435{
436 //* merge track segments withing one slice
437
438 float x0 = fSliceParam.RowX( 63 );
439 const float maxSin = CAMath::Sin( 60. / 180.*CAMath::Pi() );
440
441 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
442
443 int nBord = 0;
444 for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
445 AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[ fSliceTrackInfoStart[iSlice] + itr ];
446 //track.SetPrevNeighbour( -1 );
447 //track.SetNextNeighbour( -1 );
448 //track.SetSliceNeighbour( -1 );
449 //track.SetUsed(0);
450
451 AliHLTTPCGMBorderTrack &b = fBorderMemory[nBord];
452 if( track.TransportToX( x0, fSliceParam.ConstBz(), b, maxSin) ){
453 b.SetTrackID( itr );
454 b.SetNClusters( track.NClusters() );
455 nBord++;
456 }
457 }
458
459 MergeBorderTracks( iSlice, fBorderMemory, nBord, iSlice, fBorderMemory, nBord );
460
461 for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
462 AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[ fSliceTrackInfoStart[iSlice] + itr];
463 if( track.PrevNeighbour()>=0 || track.Used() ) continue;
464 int jtr = track.NextNeighbour();
465 track.SetSliceNeighbour( jtr );
466 track.SetNextNeighbour(-1);
467 while( jtr>=0 ){
468 AliHLTTPCGMSliceTrack &trackN = fSliceTrackInfos[ fSliceTrackInfoStart[iSlice] + jtr];
469 if( trackN.NClusters()>track.NClusters() ) track.CopyParamFrom(trackN);
470 trackN.SetUsed(2);
471 jtr = trackN.NextNeighbour();
472 trackN.SetSliceNeighbour( jtr );
473 trackN.SetNextNeighbour(-1);
474 trackN.SetPrevNeighbour(-1);
475 }
476 }
477 }
478}
479
480
481
482
483void AliHLTTPCGMMerger::MergeSlices()
484{
485 //* track merging between slices
486
487 //for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
488 //for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
489 //AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[ fSliceTrackInfoStart[iSlice] + itr ];
490 //track.SetPrevNeighbour( -1 );
491 //track.SetNextNeighbour( -1 );
492 //}
493 //}
494
495 AliHLTTPCGMBorderTrack
496 *bCurr = fBorderMemory,
497 *bNext = fBorderMemory + fMaxSliceTracks;
498
499 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
500 int jSlice = fNextSliceInd[iSlice];
501 int nCurr = 0, nNext = 0;
502 MakeBorderTracks( iSlice, 2, bCurr, nCurr );
503 MakeBorderTracks( jSlice, 3, bNext, nNext );
504 MergeBorderTracks( iSlice, bCurr, nCurr, jSlice, bNext, nNext );
505 MakeBorderTracks( iSlice, 0, bCurr, nCurr );
506 MakeBorderTracks( jSlice, 1, bNext, nNext );
507 MergeBorderTracks( iSlice, bCurr, nCurr, jSlice, bNext, nNext );
508 }
509}
510
511
512
513
514
515void AliHLTTPCGMMerger::CollectMergedTracks()
516{
517 //*
518
519 //for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
520 //for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
521 //AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[ fSliceTrackInfoStart[iSlice] + itr ];
522 //if( track.Used()!=2 ) track.SetUsed(0);
523 //}
524 //}
525
526 fNOutputTracks = 0;
527 int nOutTrackClusters = 0;
528
529 const AliHLTTPCGMSliceTrack *trackParts[100];
530
531 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
532
533 for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
534
535 AliHLTTPCGMSliceTrack &track = fSliceTrackInfos[fSliceTrackInfoStart[iSlice] + itr];
536
537 if ( track.Used() ) continue;
538 if ( track.PrevNeighbour() >= 0 ) continue;
539 int nParts = 0;
540 int jSlice = iSlice;
541 AliHLTTPCGMSliceTrack *trbase = &track, *tr = &track;
542 tr->SetUsed( 1 );
543 do{
544 trackParts[nParts++] = tr;
545 int jtr = tr->SliceNeighbour();
546 if( jtr >= 0 ) {
547 tr = &(fSliceTrackInfos[fSliceTrackInfoStart[jSlice] + jtr]);
548 tr->SetUsed( 2 );
549 continue;
550 }
551 jtr = trbase->NextNeighbour();
552 if( jtr>=0 ){
553 jSlice = fNextSliceInd[jSlice];
554 trbase = &(fSliceTrackInfos[fSliceTrackInfoStart[jSlice] + jtr]);
555 tr = trbase;
556 if( tr->Used() ) break;
557 tr->SetUsed( 1 );
558 continue;
559 }
560 break;
561 }while(1);
562
563 // unpack and sort clusters
564
565 sort(trackParts, trackParts+nParts, CompareTrackParts );
566
567 AliHLTTPCCASliceOutCluster tmp[400];
568 int currCluster = nOutTrackClusters;
569 int nHits = 0;
570 for( int ipart=0; ipart<nParts; ipart++ ){
571 const AliHLTTPCGMSliceTrack *t = trackParts[ipart];
572 int nTrackHits = t->NClusters();
573 const AliHLTTPCCASliceOutCluster *c= t->OrigTrack()->Clusters();
574 AliHLTTPCCASliceOutCluster *c2 = tmp+nHits + nTrackHits-1;
575 for( int i=0; i<nTrackHits; i++, c++, c2-- ) *c2 = *c;
576 float alpha = t->Alpha();
577 for( int i=0; i<nTrackHits; i++) fClusterAngle[currCluster++] = alpha;
578 nHits+=nTrackHits;
579 }
580
581 UInt_t *clId = fOutputClusterIds + nOutTrackClusters;
582 for( int i=0; i<nHits; i++ ) clId[i] = tmp[i].GetId();
583
584 UInt_t *clT = fClusterRowType + nOutTrackClusters;
585 for( int i=0; i<nHits; i++ ) clT[i] = tmp[i].GetRowType();
586
587 float *clX = fClusterX + nOutTrackClusters;
588 for( int i=0; i<nHits; i++ ) clX[i] = tmp[i].GetX();
589
590 float *clY = fClusterY + nOutTrackClusters;
591 for( int i=0; i<nHits; i++ ) clY[i] = tmp[i].GetY();
592
593 float *clZ = fClusterZ + nOutTrackClusters;
594 for( int i=0; i<nHits; i++ ) clZ[i] = tmp[i].GetZ();
595
596 if ( nHits < 30 ) continue;
597
598 AliHLTTPCGMMergedTrack &mergedTrack = fOutputTracks[fNOutputTracks];
599 mergedTrack.SetOK(1);
600 mergedTrack.SetNClusters( nHits );
601 mergedTrack.SetFirstClusterRef( nOutTrackClusters );
602 AliHLTTPCGMTrackParam &p1 = mergedTrack.Param();
603 const AliHLTTPCGMSliceTrack &p2 = *(trackParts[0]);
604
605 p1.X() = p2.X();
606 p1.Y() = p2.Y();
607 p1.Z() = p2.Z();
608 p1.SinPhi() = p2.SinPhi();
609 p1.DzDs() = p2.DzDs();
610 p1.QPt() = p2.QPt();
611 mergedTrack.SetAlpha( p2.Alpha() );
612
613 fNOutputTracks++;
614 nOutTrackClusters += nHits;
615 }
616 }
617}
618
619
620
621void AliHLTTPCGMMerger::Refit()
622{
623 //* final refit
624
625 for ( int itr = 0; itr < fNOutputTracks; itr++ ) {
626 AliHLTTPCGMMergedTrack &track = fOutputTracks[itr];
627 if( !track.OK() ) continue;
628 track.SetOK(0);
629
630 int nTrackHits = track.NClusters();
631
632 AliHLTTPCGMTrackParam t = track.Param();
633 float Alpha = track.Alpha();
634
635 t.Fit( fClusterX+track.FirstClusterRef(),
636 fClusterY+track.FirstClusterRef(),
637 fClusterZ+track.FirstClusterRef(),
638 fClusterRowType+track.FirstClusterRef(),
639 fClusterAngle+track.FirstClusterRef(),
640 fSliceParam, nTrackHits, Alpha, 0 );
641
642 if ( nTrackHits < 30 ) continue; //SG!!!
643
644 if ( fabs( t.QPt() ) < 1.e-4 ) t.QPt() = 1.e-4 ;
645
646 bool ok = t.CheckNumericalQuality();
647
648 if ( fabs( t.SinPhi() ) > .999 ) ok = 0;
649
650 if( !ok ) continue;
651
652 if( 1 ){//SG!!!
653 track.SetNClusters( nTrackHits );
654 track.Param() = t;
655 track.Alpha() = Alpha;
656 }
657
658 track.SetOK(1);
659
660 {
661 int ind = track.FirstClusterRef();
662 float alpha = fClusterAngle[ind];
663 float x = fClusterX[ind];
664 float y = fClusterY[ind];
665 float z = fClusterZ[ind];
666 float sinA = TMath::Sin( alpha - track.Alpha());
667 float cosA = TMath::Cos( alpha - track.Alpha());
668 track.SetLastX( x*cosA - y*sinA );
669 track.SetLastY( x*sinA + y*cosA );
670 track.SetLastZ( z );
671 }
672 }
673}
674