]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/TPCLib/tracking-ca/AliHLTTPCCAMerger.cxx
too much memory was allocated for temp. arrays
[u/mrichter/AliRoot.git] / HLT / TPCLib / tracking-ca / AliHLTTPCCAMerger.cxx
CommitLineData
63d8b79d 1// $Id: AliHLTTPCCAMerger.cxx 30732 2009-01-22 23:02:02Z sgorbuno $
2// **************************************************************************
fbb9b71b 3// This file is property of and copyright by the ALICE HLT Project *
63d8b79d 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
7be9b0d7 20#include <stdio.h>
63d8b79d 21#include "AliHLTTPCCASliceTrack.h"
22#include "AliHLTTPCCATracker.h"
63d8b79d 23#include "AliHLTTPCCATrackParam.h"
24
25#include "AliHLTTPCCAMerger.h"
26
27#include "AliHLTTPCCAMath.h"
28#include "TStopwatch.h"
29
30#include "AliHLTTPCCATrackParam.h"
31#include "AliHLTTPCCASliceTrack.h"
32#include "AliHLTTPCCASliceOutput.h"
33#include "AliHLTTPCCAMergedTrack.h"
34#include "AliHLTTPCCAMergerOutput.h"
35#include "AliHLTTPCCADataCompressor.h"
36#include "AliHLTTPCCAParam.h"
15d2e9cf 37#include "AliHLTTPCCATrackLinearisation.h"
63d8b79d 38
e1f2d1c3 39
e1f2d1c3 40class AliHLTTPCCAMerger::AliHLTTPCCASliceTrackInfo
41{
42
fbb9b71b 43 public:
44
45 const AliHLTTPCCATrackParam &InnerParam() const { return fInnerParam; }
46 const AliHLTTPCCATrackParam &OuterParam() const { return fOuterParam; }
47 float InnerAlpha() const { return fInnerAlpha; }
48 float OuterAlpha() const { return fOuterAlpha; }
49 int NClusters() const { return fNClusters; }
50 int FirstClusterRef() const { return fFirstClusterRef; }
51 int PrevNeighbour() const { return fPrevNeighbour; }
52 int NextNeighbour() const { return fNextNeighbour; }
53 bool Used() const { return fUsed; }
54
55 void SetInnerParam( const AliHLTTPCCATrackParam &v ) { fInnerParam = v; }
56 void SetOuterParam( const AliHLTTPCCATrackParam &v ) { fOuterParam = v; }
57 void SetInnerAlpha( float v ) { fInnerAlpha = v; }
58 void SetOuterAlpha( float v ) { fOuterAlpha = v; }
59 void SetNClusters ( int v ) { fNClusters = v; }
60 void SetFirstClusterRef( int v ) { fFirstClusterRef = v; }
61 void SetPrevNeighbour( int v ) { fPrevNeighbour = v; }
62 void SetNextNeighbour( int v ) { fNextNeighbour = v; }
63 void SetUsed( bool v ) { fUsed = v; }
64
65 private:
66
67 AliHLTTPCCATrackParam fInnerParam; // inner parameters
68 AliHLTTPCCATrackParam fOuterParam; // outer parameters
69 float fInnerAlpha; // alpha angle for inner parameters
70 float fOuterAlpha; // alpha angle for outer parameters
71 int fNClusters; // N clusters
72 int fFirstClusterRef; // index of the first track cluster in the global cluster array
73 int fPrevNeighbour; // neighbour in the previous slise
74 int fNextNeighbour; // neighbour in the next slise
75 bool fUsed; // is the slice track already merged
e1f2d1c3 76
77};
78
79
80class AliHLTTPCCAMerger::AliHLTTPCCABorderTrack
81{
82
fbb9b71b 83 public:
84
85 const AliHLTTPCCATrackParam &Param() const { return fParam; }
86 int TrackID() const { return fTrackID; }
87 int NClusters() const { return fNClusters; }
88 int IRow() const { return fIRow; }
89 float X() const { return fX; }
90 bool OK() const { return fOK; }
91
92 void SetParam ( const AliHLTTPCCATrackParam &v ) { fParam = v; }
93 void SetTrackID ( int v ) { fTrackID = v; }
94 void SetNClusters ( int v ) { fNClusters = v; }
95 void SetIRow ( int v ) { fIRow = v; }
96 void SetX ( float v ) { fX = v; }
97 void SetOK ( bool v ) { fOK = v; }
98
99 private:
100
101 AliHLTTPCCATrackParam fParam; // track parameters at the border
102 int fTrackID; // track index
103 int fNClusters; // n clusters
104 int fIRow; // row number of the closest cluster
105 float fX; // X coordinate of the closest cluster
106 bool fOK; // is the track rotated and extrapolated correctly
e1f2d1c3 107
108};
109
110
111
63d8b79d 112AliHLTTPCCAMerger::AliHLTTPCCAMerger()
fbb9b71b 113 :
114 fSliceParam(),
115 fOutput( 0 ),
116 fTrackInfos( 0 ),
117 fMaxTrackInfos( 0 ),
118 fClusterInfos( 0 ),
119 fMaxClusterInfos( 0 )
63d8b79d 120{
121 //* constructor
e1f2d1c3 122 Clear();
63d8b79d 123}
124
e1f2d1c3 125/*
63d8b79d 126AliHLTTPCCAMerger::AliHLTTPCCAMerger(const AliHLTTPCCAMerger&)
fbb9b71b 127 :
63d8b79d 128 fSliceParam(),
129 fkSlices(0),
fbb9b71b 130 fOutput(0),
63d8b79d 131 fTrackInfos(0),
132 fMaxTrackInfos(0),
133 fClusterInfos(0),
134 fMaxClusterInfos(0)
135{
63d8b79d 136}
137
138const AliHLTTPCCAMerger &AliHLTTPCCAMerger::operator=(const AliHLTTPCCAMerger&) const
139{
63d8b79d 140 return *this;
141}
e1f2d1c3 142*/
63d8b79d 143
144AliHLTTPCCAMerger::~AliHLTTPCCAMerger()
145{
146 //* destructor
fbb9b71b 147 if ( fTrackInfos ) delete[] fTrackInfos;
148 if ( fClusterInfos ) delete[] fClusterInfos;
149 if ( fOutput ) delete[] ( ( char* )( fOutput ) );
63d8b79d 150}
151
e1f2d1c3 152void AliHLTTPCCAMerger::Clear()
153{
154 for ( int i = 0; i < fgkNSlices; ++i ) {
155 fkSlices[i] = 0;
156 }
157}
158
63d8b79d 159
e1f2d1c3 160void AliHLTTPCCAMerger::SetSliceData( int index, const AliHLTTPCCASliceOutput *SliceData )
161{
162 fkSlices[index] = SliceData;
163}
164
165void AliHLTTPCCAMerger::Reconstruct()
63d8b79d 166{
167 //* main merging routine
168
63d8b79d 169 UnpackSlices();
170 Merging();
171}
172
173void AliHLTTPCCAMerger::UnpackSlices()
174{
175 //* unpack the cluster information from the slice tracks and initialize track info array
176
177 // get N tracks and N clusters in event
fbb9b71b 178
179 int nTracksTotal = 0;
180 int nTrackClustersTotal = 0;
181 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
182 if ( !fkSlices[iSlice] ) continue;
183 nTracksTotal += fkSlices[iSlice]->NTracks();
184 nTrackClustersTotal += fkSlices[iSlice]->NTrackClusters();
63d8b79d 185 }
186
187 // book/clean memory if necessary
188 {
fbb9b71b 189 if ( nTracksTotal > fMaxTrackInfos || ( fMaxTrackInfos > 100 && nTracksTotal < 0.5*fMaxTrackInfos ) ) {
190 if ( fTrackInfos ) delete[] fTrackInfos;
191 fMaxTrackInfos = ( int ) ( nTracksTotal * 1.2 );
63d8b79d 192 fTrackInfos = new AliHLTTPCCASliceTrackInfo[fMaxTrackInfos];
193 }
194
fbb9b71b 195 if ( nTrackClustersTotal > fMaxClusterInfos || ( fMaxClusterInfos > 1000 && nTrackClustersTotal < 0.5*fMaxClusterInfos ) ) {
196 if ( fClusterInfos ) delete[] fClusterInfos;
197 fMaxClusterInfos = ( int ) ( nTrackClustersTotal * 1.2 );
63d8b79d 198 fClusterInfos = new AliHLTTPCCAClusterInfo [fMaxClusterInfos];
199 }
200
fbb9b71b 201 if ( fOutput ) delete[] ( ( char* )( fOutput ) );
202 int size = fOutput->EstimateSize( nTracksTotal, nTrackClustersTotal );
203 fOutput = ( AliHLTTPCCAMergerOutput* )( new float2[size/sizeof( float2 )+1] );
63d8b79d 204 }
205
206 // unpack track and cluster information
63d8b79d 207
fbb9b71b 208 int nTracksCurrent = 0;
209 int nClustersCurrent = 0;
210
211 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
63d8b79d 212
63d8b79d 213 fSliceTrackInfoStart[ iSlice ] = nTracksCurrent;
214 fSliceNTrackInfos[ iSlice ] = 0;
e1f2d1c3 215
fbb9b71b 216 if ( !fkSlices[iSlice] ) continue;
63d8b79d 217
fbb9b71b 218 const AliHLTTPCCASliceOutput &slice = *( fkSlices[iSlice] );
219
220 for ( int itr = 0; itr < slice.NTracks(); itr++ ) {
15d2e9cf 221
63d8b79d 222 const AliHLTTPCCASliceTrack &sTrack = slice.Track( itr );
73a33d2e 223 AliHLTTPCCATrackParam t0;
224 t0.InitParam();
225 t0.SetParam(sTrack.Param());
fbb9b71b 226 int nCluNew = 0;
227
228 for ( int iTrClu = 0; iTrClu < sTrack.NClusters(); iTrClu++ ) {
229
230 // unpack cluster information
231
232 AliHLTTPCCAClusterInfo &clu = fClusterInfos[nClustersCurrent + nCluNew];
233 int ic = sTrack.FirstClusterRef() + iTrClu;
234
235 clu.SetISlice( iSlice );
6de2bc40 236 clu.SetIRow( slice.ClusterRow( ic ) );
237 clu.SetId( slice.ClusterId( ic ) );
73a33d2e 238 clu.SetPackedAmp( 0 );
fbb9b71b 239 float2 yz = slice.ClusterUnpackedYZ( ic );
240 clu.SetX( slice.ClusterUnpackedX( ic ) );
241 clu.SetY( yz.x );
242 clu.SetZ( yz.y );
243
6de2bc40 244 if ( !t0.TransportToX( clu.X(), fSliceParam.GetBz( t0 ), .999 ) ) continue;
fbb9b71b 245
246 float err2Y, err2Z;
247 fSliceParam.GetClusterErrors2( clu.IRow(), clu.Z(), t0.SinPhi(), t0.GetCosPhi(), t0.DzDs(), err2Y, err2Z );
248
249 clu.SetErr2Y( err2Y );
250 clu.SetErr2Z( err2Z );
251 nCluNew++ ;
63d8b79d 252 }
e1f2d1c3 253
fbb9b71b 254 if ( nCluNew < .8*sTrack.NClusters() ) continue;
255
256 // refit the track
257
258 int hits[1000];
259 int nHits = nCluNew;
260 for ( int i = 0; i < nHits; i++ ) hits[i] = nClustersCurrent + i;
63d8b79d 261
73a33d2e 262 AliHLTTPCCATrackParam startPoint;
263 startPoint.InitParam();
264 startPoint.SetParam(sTrack.Param());
63d8b79d 265 AliHLTTPCCATrackParam endPoint = startPoint;
fbb9b71b 266 float startAlpha = fSliceParam.Alpha( iSlice );
267 float endAlpha = startAlpha;
268
269 if ( !FitTrack( endPoint, endAlpha, startPoint, startAlpha, hits, nHits, 0 ) ) continue;
15d2e9cf 270
63d8b79d 271 startPoint = endPoint;
272 startAlpha = endAlpha;
fbb9b71b 273 if ( !FitTrack( startPoint, startAlpha, endPoint, endAlpha, hits, nHits, 1 ) ) continue;
15d2e9cf 274
fbb9b71b 275 if ( nHits < .8*sTrack.NClusters() ) continue;
63d8b79d 276
277 // store the track
fbb9b71b 278
279 AliHLTTPCCASliceTrackInfo &track = fTrackInfos[nTracksCurrent];
e1f2d1c3 280
281 track.SetInnerParam( startPoint );
282 track.SetInnerAlpha( startAlpha );
283 track.SetOuterParam( endPoint );
284 track.SetOuterAlpha( endAlpha );
285 track.SetFirstClusterRef( nClustersCurrent );
286 track.SetNClusters( nHits );
287 track.SetPrevNeighbour( -1 );
288 track.SetNextNeighbour( -1 );
289 track.SetUsed( 0 );
fbb9b71b 290
291 for ( int i = 0; i < nHits; i++ )
292 fClusterInfos[nClustersCurrent + i] = fClusterInfos[hits[i]];
63d8b79d 293 nTracksCurrent++;
294 fSliceNTrackInfos[ iSlice ]++;
fbb9b71b 295 nClustersCurrent += nHits;
63d8b79d 296 }
15d2e9cf 297 //std::cout<<"Unpack slice "<<iSlice<<": ntracks "<<slice.NTracks()<<"/"<<fSliceNTrackInfos[iSlice]<<std::endl;
63d8b79d 298 }
299}
300
301
302
fbb9b71b 303bool AliHLTTPCCAMerger::FitTrack( AliHLTTPCCATrackParam &T, float &Alpha,
4acc2401 304 AliHLTTPCCATrackParam t0, float Alpha0,
f0fb467d 305 int hits[], int &NTrackHits, bool dir, bool final,
b8139972 306 AliHLTTPCCAClusterInfo *infoArray )
63d8b79d 307{
308 // Fit the track
309
310 AliHLTTPCCATrackParam::AliHLTTPCCATrackFitParam fitPar;
311 AliHLTTPCCATrackParam t = t0;
fbb9b71b 312 AliHLTTPCCATrackLinearisation l( t0 );
313
b8139972 314 bool first = 1;
6de2bc40 315 bool doErrors = 1;
b8139972 316 if ( !infoArray ) {
6de2bc40 317 infoArray = fClusterInfos;
318 doErrors = 0;
319 }
15d2e9cf 320
15d2e9cf 321 t.CalculateFitParameters( fitPar );
63d8b79d 322
fbb9b71b 323 int hitsNew[1000];
324 int nHitsNew = 0;
325
326 for ( int ihit = 0; ihit < NTrackHits; ihit++ ) {
63d8b79d 327
fbb9b71b 328 int jhit = dir ? ( NTrackHits - 1 - ihit ) : ihit;
6de2bc40 329 AliHLTTPCCAClusterInfo &h = infoArray[hits[jhit]];
e1f2d1c3 330
fbb9b71b 331 int iSlice = h.ISlice();
63d8b79d 332
fbb9b71b 333 float sliceAlpha = fSliceParam.Alpha( iSlice );
63d8b79d 334
fbb9b71b 335 if ( CAMath::Abs( sliceAlpha - Alpha0 ) > 1.e-4 ) {
336 if ( ! t.Rotate( sliceAlpha - Alpha0, l, .999 ) ) continue;
63d8b79d 337 Alpha0 = sliceAlpha;
338 }
339
fbb9b71b 340 //float x = fSliceParam.RowX( h.IRow() );
341 float x = h.X();
342
343 if ( !t.TransportToXWithMaterial( x, l, fitPar, fSliceParam.GetBz( t ) ) ) continue;
344
345 if ( first ) {
63d8b79d 346 t.SetCov( 0, 10 );
347 t.SetCov( 1, 0 );
348 t.SetCov( 2, 10 );
349 t.SetCov( 3, 0 );
350 t.SetCov( 4, 0 );
351 t.SetCov( 5, 1 );
352 t.SetCov( 6, 0 );
353 t.SetCov( 7, 0 );
354 t.SetCov( 8, 0 );
355 t.SetCov( 9, 1 );
fbb9b71b 356 t.SetCov( 10, 0 );
357 t.SetCov( 11, 0 );
358 t.SetCov( 12, 0 );
359 t.SetCov( 13, 0 );
360 t.SetCov( 14, 10 );
63d8b79d 361 t.SetChi2( 0 );
362 t.SetNDF( -5 );
15d2e9cf 363 t.CalculateFitParameters( fitPar );
63d8b79d 364 }
fbb9b71b 365
6de2bc40 366 float err2Y = h.Err2Y();
367 float err2Z = h.Err2Z();
b8139972 368 if ( doErrors ) fSliceParam.GetClusterErrors2( h.IRow(), h.Z(), l.SinPhi(), l.CosPhi(), l.DzDs(), err2Y, err2Z );
f0fb467d 369 if( !final ){
370 err2Y*= fSliceParam.ClusterError2CorrectionY();
371 err2Z*= fSliceParam.ClusterError2CorrectionZ();
372 }
373
b8139972 374 if ( !t.Filter( h.Y(), h.Z(), err2Y, err2Z ) ) continue;
15d2e9cf 375
63d8b79d 376 first = 0;
377
378 hitsNew[nHitsNew++] = hits[jhit];
379 }
fbb9b71b 380
91794c67 381 if ( CAMath::Abs( t.QPt() ) < 1.e-4 ) t.SetQPt( 1.e-4 );
fbb9b71b 382
91794c67 383 bool ok = t.CheckNumericalQuality();
fbb9b71b 384
385 if ( CAMath::Abs( t.SinPhi() ) > .99 ) ok = 0;
386 else if ( l.CosPhi() >= 0 ) t.SetSignCosPhi( 1 );
15d2e9cf 387 else t.SetSignCosPhi( -1 );
63d8b79d 388
fbb9b71b 389 if ( ok ) {
63d8b79d 390 T = t;
391 Alpha = Alpha0;
392 NTrackHits = nHitsNew;
fbb9b71b 393 for ( int i = 0; i < NTrackHits; i++ ) {
394 hits[dir ?( NTrackHits-1-i ) :i] = hitsNew[i];
63d8b79d 395 }
396 }
397 return ok;
398}
399
400
fbb9b71b 401float AliHLTTPCCAMerger::GetChi2( float x1, float y1, float a00, float a10, float a11,
4acc2401 402 float x2, float y2, float b00, float b10, float b11 )
63d8b79d 403{
fbb9b71b 404 //* Calculate Chi2/ndf deviation
405
406 float d[2] = { x1 - x2, y1 - y2 };
63d8b79d 407
fbb9b71b 408 float mSi[3] = { a00 + b00, a10 + b10, a11 + b11 };
63d8b79d 409
fbb9b71b 410 float s = ( mSi[0] * mSi[2] - mSi[1] * mSi[1] );
63d8b79d 411
fbb9b71b 412 if ( s < 1.E-10 ) return 10000.;
63d8b79d 413
fbb9b71b 414 float mS[3] = { mSi[2], -mSi[1], mSi[0] };
63d8b79d 415
7be9b0d7 416 return AliHLTTPCCAMath::Abs( ( ( mS[0]*d[0] + mS[1]*d[1] )*d[0]
fbb9b71b 417 + ( mS[1]*d[0] + mS[2]*d[1] )*d[1] ) / s / 2 );
63d8b79d 418
419}
420
63d8b79d 421
fbb9b71b 422
423void AliHLTTPCCAMerger::MakeBorderTracks( int iSlice, int iBorder, AliHLTTPCCABorderTrack B[], int &nB )
63d8b79d 424{
425 //* prepare slice tracks for merging with next/previous/same sector
fbb9b71b 426 //* each track transported to the border line,
427 //* in some cases both inner and outer parameters of the track are transported
428
429 static int statAll = 0, statOK = 0;
430 nB = 0;
431 float dAlpha = fSliceParam.DAlpha() / 2;
432 float x0 = 0;
433
434 if ( iBorder == 0 ) { // transport to the left age of the sector and rotate horisontally
435 dAlpha = dAlpha - CAMath::Pi() / 2 ;
436 } else if ( iBorder == 1 ) { // transport to the right age of the sector and rotate horisontally
437 dAlpha = -dAlpha - CAMath::Pi() / 2 ;
438 } else if ( iBorder == 2 ) { // transport to the left age of the sector and rotate vertically
63d8b79d 439 dAlpha = dAlpha;
440 x0 = fSliceParam.RowX( 63 );
fbb9b71b 441 } else if ( iBorder == 3 ) { // transport to the right age of the sector and rotate vertically
63d8b79d 442 dAlpha = -dAlpha;
443 x0 = fSliceParam.RowX( 63 );
fbb9b71b 444 } else if ( iBorder == 4 ) { // transport to the middle of the sector, w/o rotation
63d8b79d 445 dAlpha = 0;
fbb9b71b 446 x0 = fSliceParam.RowX( 63 );
63d8b79d 447 }
448
fbb9b71b 449 for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
63d8b79d 450
e1f2d1c3 451 const AliHLTTPCCASliceTrackInfo &track = fTrackInfos[ fSliceTrackInfoStart[iSlice] + itr ];
63d8b79d 452
e1f2d1c3 453 AliHLTTPCCATrackParam t0 = track.InnerParam();
454 AliHLTTPCCATrackParam t1 = track.OuterParam();
63d8b79d 455
fbb9b71b 456 const float maxSin = CAMath::Sin( 60. / 180.*CAMath::Pi() );
457
458 bool ok0 = t0.Rotate( dAlpha, maxSin );
459 bool ok1 = t1.Rotate( dAlpha, maxSin );
63d8b79d 460
fbb9b71b 461 bool do0 = ok0;
462 bool do1 = ok1 && ( !ok0 || t1.SignCosPhi() * t0.SignCosPhi() < 0 );
463
464 if ( ok0 && !do1 && ok1 && ( t1.X() < t0.X() ) ) {
63d8b79d 465 do0 = 0;
466 do1 = 1;
467 }
468
fbb9b71b 469 if ( do0 ) {
63d8b79d 470 AliHLTTPCCABorderTrack &b = B[nB];
e1f2d1c3 471 b.SetX( t0.GetX() );
f0fb467d 472
fbb9b71b 473 if ( t0.TransportToX( x0, fSliceParam.GetBz( t0 ), maxSin ) ) {
474 b.SetOK( 1 );
475 b.SetTrackID( itr );
476 b.SetNClusters( track.NClusters() );
477 b.SetIRow( fClusterInfos[ track.FirstClusterRef() + 0 ].IRow() );
478 b.SetParam( t0 );
479 nB++;
e1f2d1c3 480 }
63d8b79d 481 }
fbb9b71b 482 if ( do1 ) {
63d8b79d 483 AliHLTTPCCABorderTrack &b = B[nB];
e1f2d1c3 484 b.SetX( t1.GetX() );
f0fb467d 485
fbb9b71b 486 if ( t1.TransportToX( x0, fSliceParam.GetBz( t1 ), maxSin ) ) {
487 b.SetOK( 1 );
488 b.SetTrackID( itr );
489 b.SetNClusters( track.NClusters() );
490 b.SetIRow( fClusterInfos[ track.FirstClusterRef() + track.NClusters()-1 ].IRow() );
491 b.SetParam( t1 );
492 nB++;
e1f2d1c3 493 }
63d8b79d 494 }
fbb9b71b 495 if ( do0 || do1 ) statOK++;
63d8b79d 496 statAll++;
497 }
498}
499
500
501
f0fb467d 502void AliHLTTPCCAMerger::MergeBorderTracks( int iSlice1, AliHLTTPCCABorderTrack B1[], int N1,
fbb9b71b 503 int iSlice2, AliHLTTPCCABorderTrack B2[], int N2
504 )
63d8b79d 505{
f0fb467d 506 //* merge two sets of tracks
63d8b79d 507
f0fb467d 508 //std::cout<<" Merge slices "<<iSlice1<<"+"<<iSlice2<<": tracks "<<N1<<"+"<<N2<<std::endl;
509
fbb9b71b 510 float factor2ys = 1.;//1.5;//SG!!!
511 float factor2zt = 1.;//1.5;//SG!!!
512 float factor2k = 2.0;//2.2;
63d8b79d 513
fbb9b71b 514 factor2k = 3.5 * 3.5 * factor2k * factor2k;
515 factor2ys = 3.5 * 3.5 * factor2ys * factor2ys;
516 factor2zt = 3.5 * 3.5 * factor2zt * factor2zt;
63d8b79d 517
fbb9b71b 518 int minNPartHits = 10;//SG!!!
519 int minNTotalHits = 20;
63d8b79d 520
fbb9b71b 521 //float maxDX = fSliceParam.RowX(40) - fSliceParam.RowX(0);
63d8b79d 522
fbb9b71b 523 for ( int i1 = 0; i1 < N1; i1++ ) {
63d8b79d 524 AliHLTTPCCABorderTrack &b1 = B1[i1];
fbb9b71b 525 if ( !b1.OK() ) continue;
526 if ( b1.NClusters() < minNPartHits ) continue;
e1f2d1c3 527 const AliHLTTPCCATrackParam &t1 = b1.Param();
fbb9b71b 528 int iBest2 = -1;
529 int lBest2 = 0;
530 int start2 = ( iSlice1 != iSlice2 ) ? 0 : i1 + 1;
531 for ( int i2 = start2; i2 < N2; i2++ ) {
63d8b79d 532 AliHLTTPCCABorderTrack &b2 = B2[i2];
fbb9b71b 533 if ( !b2.OK() ) continue;
534 if ( b2.NClusters() < minNPartHits ) continue;
535 if ( b2.NClusters() < lBest2 ) continue;
536 if ( b1.NClusters() + b2.NClusters() < minNTotalHits ) continue;
63d8b79d 537
538 //if( TMath::Abs(b1.fX - b2.fX)>maxDX ) continue;
539
e1f2d1c3 540 const AliHLTTPCCATrackParam &t2 = b2.Param();
63d8b79d 541
fbb9b71b 542 float c = t2.SignCosPhi() * t1.SignCosPhi() >= 0 ? 1 : -1;
543 float dk = t2.QPt() - c * t1.QPt();
544 float s2k = t2.Err2QPt() + t1.Err2QPt();
f0fb467d 545 //std::cout<<" check 1.. "<<dk/sqrt(factor2k)<<std::endl;
fbb9b71b 546 if ( dk*dk > factor2k*s2k ) continue;
547
548
549 float chi2ys = GetChi2( t1.Y(), c * t1.SinPhi(), t1.Cov()[0], c * t1.Cov()[3], t1.Cov()[5],
4acc2401 550 t2.Y(), t2.SinPhi(), t2.Cov()[0], t2.Cov()[3], t2.Cov()[5] );
63d8b79d 551
f0fb467d 552 //std::cout<<" check 2.. "<<sqrt(chi2ys/factor2ys)<<std::endl;
fbb9b71b 553 if ( chi2ys > factor2ys ) continue;
f0fb467d 554
63d8b79d 555
fbb9b71b 556 float chi2zt = GetChi2( t1.Z(), c * t1.DzDs(), t1.Cov()[2], c * t1.Cov()[7], t1.Cov()[9],
4acc2401 557 t2.Z(), t2.DzDs(), t2.Cov()[2], t2.Cov()[7], t2.Cov()[9] );
63d8b79d 558
f0fb467d 559 //std::cout<<" check 3.. "<<sqrt(chi2zt/factor2zt)<<std::endl;
fbb9b71b 560 if ( chi2zt > factor2zt ) continue;
63d8b79d 561
e1f2d1c3 562 lBest2 = b2.NClusters();
563 iBest2 = b2.TrackID();
63d8b79d 564 }
fbb9b71b 565
566 if ( iBest2 < 0 ) continue;
567
f0fb467d 568 //std::cout<<"Neighbour found for "<<i1<<": "<<iBest2<<std::endl;
fbb9b71b 569 AliHLTTPCCASliceTrackInfo &newTrack1 = fTrackInfos[fSliceTrackInfoStart[iSlice1] + b1.TrackID() ];
570 AliHLTTPCCASliceTrackInfo &newTrack2 = fTrackInfos[fSliceTrackInfoStart[iSlice2] + iBest2 ];
571
572 int old1 = newTrack2.PrevNeighbour();
573
574 if ( old1 >= 0 ) {
575 AliHLTTPCCASliceTrackInfo &oldTrack1 = fTrackInfos[fSliceTrackInfoStart[iSlice1] + old1];
576 if ( oldTrack1.NClusters() < newTrack1.NClusters() ) {
577 newTrack2.SetPrevNeighbour( -1 );
578 oldTrack1.SetNextNeighbour( -1 );
63d8b79d 579 } else continue;
580 }
fbb9b71b 581 int old2 = newTrack1.NextNeighbour();
582 if ( old2 >= 0 ) {
583 AliHLTTPCCASliceTrackInfo &oldTrack2 = fTrackInfos[fSliceTrackInfoStart[iSlice2] + old2];
584 if ( oldTrack2.NClusters() < newTrack2.NClusters() ) {
585 oldTrack2.SetPrevNeighbour( -1 );
63d8b79d 586 } else continue;
587 }
fbb9b71b 588 newTrack1.SetNextNeighbour( iBest2 );
589 newTrack2.SetPrevNeighbour( b1.TrackID() );
f0fb467d 590 //std::cout<<"Neighbourhood is set"<<std::endl;
fbb9b71b 591 }
592
63d8b79d 593}
594
595
596void AliHLTTPCCAMerger::Merging()
597{
598 //* track merging between slices
599
e1f2d1c3 600 fOutput->SetNTracks( 0 );
601 fOutput->SetNTrackClusters( 0 );
602 fOutput->SetPointers();
603
63d8b79d 604
605 // for each slice set number of the next neighbouring slice
63d8b79d 606
fbb9b71b 607 int nextSlice[100], prevSlice[100];
608
609 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
63d8b79d 610 nextSlice[iSlice] = iSlice + 1;
611 prevSlice[iSlice] = iSlice - 1;
612 }
fbb9b71b 613 int mid = fgkNSlices / 2 - 1 ;
614 int last = fgkNSlices - 1 ;
615 if ( mid < 0 ) mid = 0; // to avoid compiler warning
616 if ( last < 0 ) last = 0; //
63d8b79d 617 nextSlice[ mid ] = 0;
618 prevSlice[ 0 ] = mid;
fbb9b71b 619 nextSlice[ last ] = fgkNSlices / 2;
63d8b79d 620 prevSlice[ fgkNSlices/2 ] = last;
fbb9b71b 621
622 int maxNSliceTracks = 0;
623 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
624 if ( maxNSliceTracks < fSliceNTrackInfos[iSlice] ) maxNSliceTracks = fSliceNTrackInfos[iSlice];
63d8b79d 625 }
fbb9b71b 626
627 if ( 1 ) {// merging track segments withing one slice
628
fdb75fd8 629 AliHLTResizableArray<AliHLTTPCCABorderTrack> bord( maxNSliceTracks*2 );
fbb9b71b 630
63d8b79d 631 AliHLTTPCCASliceTrackInfo *tmpT = new AliHLTTPCCASliceTrackInfo[maxNSliceTracks];
632 AliHLTTPCCAClusterInfo *tmpH = new AliHLTTPCCAClusterInfo[fMaxClusterInfos];
633
fbb9b71b 634 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
635
636 int nBord = 0;
4acc2401 637 MakeBorderTracks( iSlice, 4, bord.Data(), nBord );
f0fb467d 638 MergeBorderTracks( iSlice, bord.Data(), nBord, iSlice, bord.Data(), nBord );
fbb9b71b 639
640 int nTr = 0, nH = 0;
641 int sliceFirstClusterRef = 0;
642 for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
643 AliHLTTPCCASliceTrackInfo &track = fTrackInfos[ fSliceTrackInfoStart[iSlice] + itr];
644 if ( itr == 0 ) sliceFirstClusterRef = track.FirstClusterRef();
645 track.SetPrevNeighbour( -1 );
646 if ( track.NextNeighbour() == -2 ) {
647 track.SetNextNeighbour( -1 );
648 continue;
649 }
650 AliHLTTPCCASliceTrackInfo &trackNew = tmpT[nTr];
651 trackNew = track;
652 trackNew.SetFirstClusterRef( sliceFirstClusterRef + nH );
653
654 for ( int ih = 0; ih < track.NClusters(); ih++ ) tmpH[nH+ih] = fClusterInfos[track.FirstClusterRef()+ih];
655 nTr++;
656 nH += track.NClusters();
657
658 int jtr = track.NextNeighbour();
659
660 if ( jtr < 0 ) continue;
661 AliHLTTPCCASliceTrackInfo &neighTrack = fTrackInfos[ fSliceTrackInfoStart[iSlice] + jtr];
662
663 track.SetNextNeighbour( -1 );
664 neighTrack.SetNextNeighbour( -2 );
665
666 for ( int ih = 0; ih < neighTrack.NClusters(); ih++ )
667 tmpH[nH+ih] = fClusterInfos[neighTrack.FirstClusterRef()+ih];
668
669 trackNew.SetNClusters( trackNew.NClusters() + neighTrack.NClusters() );
670 trackNew.SetNextNeighbour( -1 );
671 nH += neighTrack.NClusters();
672 if ( neighTrack.InnerParam().X() < track.InnerParam().X() ) trackNew.SetInnerParam( neighTrack.InnerParam() );
673 if ( neighTrack.OuterParam().X() > track.OuterParam().X() ) trackNew.SetOuterParam( neighTrack.OuterParam() );
63d8b79d 674 }
fbb9b71b 675
63d8b79d 676 fSliceNTrackInfos[iSlice] = nTr;
fbb9b71b 677 for ( int itr = 0; itr < nTr; itr++ ) fTrackInfos[ fSliceTrackInfoStart[iSlice] + itr] = tmpT[itr];
678 for ( int ih = 0; ih < nH; ih++ ) fClusterInfos[sliceFirstClusterRef + ih] = tmpH[ih];
63d8b79d 679
680 }
681 delete[] tmpT;
682 delete[] tmpH;
683 }
684
685
fbb9b71b 686 //* merging tracks between slices
687
63d8b79d 688
63d8b79d 689 // arrays for the rotated track parameters
690
fbb9b71b 691 AliHLTTPCCABorderTrack
fdb75fd8 692 *bCurr0 = new AliHLTTPCCABorderTrack[maxNSliceTracks*2],
693 *bNext0 = new AliHLTTPCCABorderTrack[maxNSliceTracks*2],
694 *bCurr = new AliHLTTPCCABorderTrack[maxNSliceTracks*2],
695 *bNext = new AliHLTTPCCABorderTrack[maxNSliceTracks*2];
fbb9b71b 696
697 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
63d8b79d 698
fbb9b71b 699 int jSlice = nextSlice[iSlice];
700
701 int nCurr0 = 0, nNext0 = 0;
702 int nCurr = 0, nNext = 0;
63d8b79d 703
704 MakeBorderTracks( iSlice, 0, bCurr, nCurr );
705 MakeBorderTracks( jSlice, 1, bNext, nNext );
706 MakeBorderTracks( iSlice, 2, bCurr0, nCurr0 );
707 MakeBorderTracks( jSlice, 3, bNext0, nNext0 );
fbb9b71b 708
f0fb467d 709 MergeBorderTracks( iSlice, bCurr0, nCurr0, jSlice, bNext0, nNext0 );
710 MergeBorderTracks( iSlice, bCurr, nCurr, jSlice, bNext, nNext );
63d8b79d 711 }
712
fbb9b71b 713 if ( bCurr0 ) delete[] bCurr0;
714 if ( bNext0 ) delete[] bNext0;
715 if ( bCurr ) delete[] bCurr;
716 if ( bNext ) delete[] bNext;
63d8b79d 717
718
fbb9b71b 719 //static int nRejected = 0;
720
721 int nOutTracks = 0;
722 int nOutTrackClusters = 0;
63d8b79d 723
724 AliHLTTPCCAMergedTrack *outTracks = new AliHLTTPCCAMergedTrack[fMaxTrackInfos];
6de2bc40 725 unsigned int *outClusterId = new unsigned int [fMaxClusterInfos];
63d8b79d 726 UChar_t *outClusterPackedAmp = new UChar_t [fMaxClusterInfos];
63d8b79d 727
fbb9b71b 728 for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
729
730 for ( int itr = 0; itr < fSliceNTrackInfos[iSlice]; itr++ ) {
63d8b79d 731
fbb9b71b 732 AliHLTTPCCASliceTrackInfo &track = fTrackInfos[fSliceTrackInfoStart[iSlice] + itr];
63d8b79d 733
fbb9b71b 734 if ( track.Used() ) continue;
735 if ( track.PrevNeighbour() >= 0 ) continue;
f0fb467d 736 //std::cout<<"Merged track candidate, nhits "<<track.NClusters()<<std::endl;
e1f2d1c3 737 AliHLTTPCCATrackParam startPoint = track.InnerParam(), endPoint = track.OuterParam();
fbb9b71b 738 float startAlpha = track.InnerAlpha(), endAlpha = track.OuterAlpha();
63d8b79d 739
fbb9b71b 740 int hits[2000];
741 int firstHit = 1000;
742 int nHits = 0;
743 int jSlice = iSlice;
744 int jtr = itr;
63d8b79d 745
746 {
fbb9b71b 747 track.SetUsed( 1 );
748 for ( int jhit = 0; jhit < track.NClusters(); jhit++ ) {
749 int id = track.FirstClusterRef() + jhit;
750 hits[firstHit+jhit] = id;
751 }
752 nHits = track.NClusters();
753 jtr = track.NextNeighbour();
754 jSlice = nextSlice[iSlice];
63d8b79d 755 }
756
fbb9b71b 757 while ( jtr >= 0 ) {
758 AliHLTTPCCASliceTrackInfo &segment = fTrackInfos[fSliceTrackInfoStart[jSlice] + jtr];
759 if ( segment.Used() ) break;
760 segment.SetUsed( 1 );
761 bool dir = 0;
762 int startHit = firstHit + nHits;
763 float d00 = startPoint.GetDistXZ2( segment.InnerParam() );
764 float d01 = startPoint.GetDistXZ2( segment.OuterParam() );
765 float d10 = endPoint.GetDistXZ2( segment.InnerParam() );
766 float d11 = endPoint.GetDistXZ2( segment.OuterParam() );
767 if ( d00 <= d01 && d00 <= d10 && d00 <= d11 ) {
768 startPoint = segment.OuterParam();
769 startAlpha = segment.OuterAlpha();
770 dir = 1;
771 firstHit -= segment.NClusters();
772 startHit = firstHit;
773 } else if ( d01 <= d10 && d01 <= d11 ) {
774 startPoint = segment.InnerParam();
775 startAlpha = segment.InnerAlpha();
776 dir = 0;
777 firstHit -= segment.NClusters();
778 startHit = firstHit;
779 } else if ( d10 <= d11 ) {
780 endPoint = segment.OuterParam();
781 endAlpha = segment.OuterAlpha();
782 dir = 0;
783 } else {
784 endPoint = segment.InnerParam();
785 endAlpha = segment.InnerAlpha();
786 dir = 1;
787 }
788
789 for ( int jhit = 0; jhit < segment.NClusters(); jhit++ ) {
790 int id = segment.FirstClusterRef() + jhit;
791 hits[startHit+( dir ?( segment.NClusters()-1-jhit ) :jhit )] = id;
792 }
793 nHits += segment.NClusters();
794 jtr = segment.NextNeighbour();
795 jSlice = nextSlice[jSlice];
63d8b79d 796 }
797
fbb9b71b 798 if ( endPoint.X() < startPoint.X() ) { // swap
799 for ( int i = 0; i < nHits; i++ ) hits[i] = hits[firstHit+nHits-1-i];
800 firstHit = 0;
63d8b79d 801 }
63d8b79d 802
fbb9b71b 803 if ( nHits < 30 ) continue; //SG!!!
804
805 // refit
63d8b79d 806
807 // need best t0!!!SG
808
809 endPoint = startPoint;
fbb9b71b 810
f0fb467d 811 if ( !FitTrack( endPoint, endAlpha, startPoint, startAlpha, hits + firstHit, nHits, 0,1 ) ) continue;
812 if ( !FitTrack( startPoint, startAlpha, endPoint, endAlpha, hits + firstHit, nHits, 1,1 ) ) continue;
fbb9b71b 813 if ( nHits < 30 ) continue; //SG!!!
63d8b79d 814
f0fb467d 815 AliHLTTPCCATrackParam p = startPoint;
5dc6c74b 816
817 if(0){
fbb9b71b 818 double xTPC = 83.65; //SG!!!
040db2fa 819 double dAlpha = 0.349066;
820 double ymax = 2.* xTPC * CAMath::Tan( dAlpha / 2. );
821
822 double dRot = 0;
823 if ( p.TransportToXWithMaterial( xTPC, fSliceParam.GetBz( p ) ) ) {
fbb9b71b 824 double y = p.GetY();
040db2fa 825 if ( y > ymax ) {
826 if ( p.Rotate( dAlpha ) ){
827 dRot = dAlpha;
828 p.TransportToXWithMaterial( xTPC, fSliceParam.GetBz( p ) );
829 }
830 } else if( y< -ymax ){
831 if ( p.Rotate( -dAlpha ) ){
832 dRot = -dAlpha;
833 p.TransportToXWithMaterial( xTPC, fSliceParam.GetBz( p ) );
834 }
835 }
fbb9b71b 836 }
040db2fa 837
838 if ( -ymax <= p.GetY() && p.GetY() <= ymax && p.CheckNumericalQuality() ){
839 startPoint = p;
840 startAlpha+=dRot;
841 }
63d8b79d 842 }
fbb9b71b 843
f0fb467d 844 if ( !startPoint.CheckNumericalQuality() ) continue;
63d8b79d 845
846 AliHLTTPCCAMergedTrack &mergedTrack = outTracks[nOutTracks];
fbb9b71b 847 mergedTrack.SetNClusters( nHits );
848 mergedTrack.SetFirstClusterRef( nOutTrackClusters );
849 mergedTrack.SetInnerParam( startPoint );
850 mergedTrack.SetInnerAlpha( startAlpha );
851 mergedTrack.SetOuterParam( endPoint );
852 mergedTrack.SetOuterAlpha( endAlpha );
853
854 for ( int i = 0; i < nHits; i++ ) {
855 AliHLTTPCCAClusterInfo &clu = fClusterInfos[hits[firstHit+i]];
6de2bc40 856 outClusterId[nOutTrackClusters+i] = clu.Id();
fbb9b71b 857 outClusterPackedAmp[nOutTrackClusters+i] = clu.PackedAmp();
63d8b79d 858 }
fbb9b71b 859
63d8b79d 860 nOutTracks++;
fbb9b71b 861 nOutTrackClusters += nHits;
63d8b79d 862 }
863 }
864
865 fOutput->SetNTracks( nOutTracks );
b22af1bf 866 #ifdef HLTCA_STANDALONE
7be9b0d7 867 printf("Tracks Output: %d\n", nOutTracks);
b22af1bf 868 #endif
63d8b79d 869 fOutput->SetNTrackClusters( nOutTrackClusters );
870 fOutput->SetPointers();
871
fbb9b71b 872 for ( int itr = 0; itr < nOutTracks; itr++ ) fOutput->SetTrack( itr, outTracks[itr] );
63d8b79d 873
fbb9b71b 874 for ( int ic = 0; ic < nOutTrackClusters; ic++ ) {
6de2bc40 875 fOutput->SetClusterId( ic, outClusterId[ic] );
63d8b79d 876 fOutput->SetClusterPackedAmp( ic, outClusterPackedAmp[ic] );
877 }
fbb9b71b 878
63d8b79d 879 delete[] outTracks;
6de2bc40 880 delete[] outClusterId;
63d8b79d 881 delete[] outClusterPackedAmp;
882}