1 // @(#) $Id: AliHLTTPCCATrackletConstructor.cxx 27042 2008-07-02 12:06:02Z richterm $
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. *
17 //***************************************************************************
19 #include "AliHLTTPCCATracker.h"
20 #include "AliHLTTPCCATrackParam.h"
21 #include "AliHLTTPCCATrackParam1.h"
22 #include "AliHLTTPCCAGrid.h"
23 #include "AliHLTTPCCAHitArea.h"
24 #include "AliHLTTPCCAMath.h"
25 #include "AliHLTTPCCADef.h"
26 #include "AliHLTTPCCATrackletConstructor.h"
28 //GPUd() void myprintf1(int i, int j){
29 //printf("fwd: iS=%d, iRow=%d\n",i,j);
31 //GPUd() void myprintf2(int i, int j){
32 //printf("bck: iS=%d, iRow=%d\n",i,j);
36 GPUd() void AliHLTTPCCATrackletConstructor::Step0
37 ( Int_t nBlocks, Int_t /*nThreads*/, Int_t iBlock, Int_t iThread, Int_t /*iSync*/,
38 AliHLTTPCCASharedMemory &s, AliHLTTPCCAThreadMemory &r, AliHLTTPCCATracker &tracker, AliHLTTPCCATrackParam1 &/*tParam*/ )
40 // reconstruction of tracklets, step 0
42 const Int_t kNMemThreads = 128;
44 r.fIsMemThread = ( iThread<kNMemThreads );
46 int nTracks = tracker.StartHits()[0];
47 if(iBlock==0) *tracker.Tracklets() = nTracks;
48 int nTrPerBlock = nTracks/nBlocks+1;
49 s.fNRows = tracker.Param().NRows();
50 s.fItr0 = nTrPerBlock*iBlock;
51 s.fItr1 = s.fItr0 + nTrPerBlock;
52 if( s.fItr1> nTracks ) s.fItr1 = nTracks;
53 s.fUsedHits = tracker.HitIsUsed();
58 s.fMinStartRow32[iThread] = 158;
59 s.fMaxStartRow32[iThread] = 0;
64 GPUd() void AliHLTTPCCATrackletConstructor::Step1
65 ( Int_t /*nBlocks*/, Int_t /*nThreads*/, Int_t /*iBlock*/, Int_t iThread, Int_t /*iSync*/,
66 AliHLTTPCCASharedMemory &s, AliHLTTPCCAThreadMemory &r, AliHLTTPCCATracker &tracker, AliHLTTPCCATrackParam1 &tParam )
68 // reconstruction of tracklets, step 1
70 const Int_t kNMemThreads = 128;
72 r.fItr= s.fItr0 + ( iThread - kNMemThreads );
73 r.fGo = (!r.fIsMemThread) && ( r.fItr<s.fItr1 );
81 r.fTrackStoreOffset = 1 + r.fItr*(5+ sizeof(AliHLTTPCCATrackParam)/4 + 160 );
82 r.fHitStoreOffset = r.fTrackStoreOffset + 5+ sizeof(AliHLTTPCCATrackParam)/4 ;
84 int *hitstore = tracker.Tracklets() +r.fHitStoreOffset;
86 UInt_t kThread = iThread %32;//& 00000020;
87 if( SAVE() ) for( int i=0; i<160; i++ ) hitstore[i] = -1;
89 int id = tracker.StartHits()[1 + r.fItr];
90 r.fFirstRow = AliHLTTPCCATracker::ID2IRow(id);
91 r.fCurrIH = AliHLTTPCCATracker::ID2IHit(id);
92 CAMath::atomicMin( &s.fMinStartRow32[kThread], r.fFirstRow);
93 CAMath::atomicMax( &s.fMaxStartRow32[kThread], r.fFirstRow);
104 tParam.Cov()[13] = 0;
107 tParam.Cov()[5] = 1.;
109 tParam.Cov()[9] = 1.;
110 tParam.Cov()[10] = 0;
111 tParam.Cov()[12] = 0;
112 tParam.Cov()[14] = 1.;
113 r.fLastRow = r.fFirstRow;
116 GPUd() void AliHLTTPCCATrackletConstructor::Step2
117 ( Int_t /*nBlocks*/, Int_t /*nThreads*/, Int_t /*iBlock*/, Int_t iThread, Int_t /*iSync*/,
118 AliHLTTPCCASharedMemory &s, AliHLTTPCCAThreadMemory &/*r*/, AliHLTTPCCATracker &/*tracker*/, AliHLTTPCCATrackParam1 &/*tParam*/ )
120 // reconstruction of tracklets, step 2
122 //CAMath::atomicMinGPU(&s.fMinRow, s.fMinRow32[iThread]);
123 int minStartRow = 158;
125 for( int i=0; i<32; i++ ){
126 if( s.fMinStartRow32[i]<minStartRow ) minStartRow = s.fMinStartRow32[i];
127 if( s.fMaxStartRow32[i]>maxStartRow ) maxStartRow = s.fMaxStartRow32[i];
129 s.fMinStartRow = minStartRow;
130 s.fMaxStartRow = maxStartRow;
134 GPUd() void AliHLTTPCCATrackletConstructor::ReadData
135 ( Int_t iThread, AliHLTTPCCASharedMemory &s, AliHLTTPCCAThreadMemory &r, AliHLTTPCCATracker &tracker, Int_t iRow )
138 // reconstruction of tracklets, read data step
139 const Int_t kNMemThreads = 128;
140 if( r.fIsMemThread ){
141 AliHLTTPCCARow &row = tracker.Rows()[iRow];
142 bool jr = !r.fCurrentData;
143 Int_t n = row.FullSize();
144 uint4* gMem = tracker.TexHitsFullData() + row.FullOffset();
145 uint4 *sMem = s.fData[jr];
146 for( int i=iThread; i<n; i+=kNMemThreads ) sMem[i] = gMem[i];
151 GPUd() void AliHLTTPCCATrackletConstructor::UnpackGrid
152 ( Int_t /*nBlocks*/, Int_t nThreads, Int_t /*iBlock*/, Int_t iThread, Int_t /*iSync*/,
153 AliHLTTPCCASharedMemory &s, AliHLTTPCCAThreadMemory &r, AliHLTTPCCATracker &tracker, AliHLTTPCCATrackParam1 &/*tParam*/,Int_t iRow )
155 // reconstruction of tracklets, grid unpacking step
157 AliHLTTPCCARow &row = tracker.Rows()[iRow];
158 int n = row.Grid().N()+1;
159 int nY = row.Grid().Ny();
160 uint4 *tmpint4 = s.fData[r.fCurrentData];
161 UShort_t *sGridP = (reinterpret_cast<UShort_t*>(tmpint4)) + row.FullGridOffset();
163 UInt_t *sGrid = s.fGridContent1;
165 for( int i=iThread; i<n; i+=nThreads ){
166 UInt_t s0 = sGridP[i];
167 UInt_t e0 = sGridP[i+2];
168 UInt_t s1 = sGridP[i+nY];
169 UInt_t e1 = sGridP[i+nY+2];
172 sGrid[i] = (nh1<<26)+(s1<<16)+( nh0<<10 ) + s0;
177 GPUd() void AliHLTTPCCATrackletConstructor::StoreTracklet
178 ( Int_t /*nBlocks*/, Int_t /*nThreads*/, Int_t /*iBlock*/, Int_t /*iThread*/, Int_t /*iSync*/,
179 AliHLTTPCCASharedMemory &/*s*/, AliHLTTPCCAThreadMemory &r, AliHLTTPCCATracker &tracker, AliHLTTPCCATrackParam1 &tParam )
181 // reconstruction of tracklets, tracklet store step
183 if( !r.fSave ) return;
193 Float_t *c = tParam.Cov();
194 for( int i=0; i<15; i++ ) ok = ok && CAMath::Finite(c[i]);
195 for( int i=0; i<5; i++ ) ok = ok && CAMath::Finite(tParam.Par()[i]);
196 ok = ok && (tParam.X()>50);
198 if( c[0]<=0 || c[2]<=0 || c[5]<=0 || c[9]<=0 || c[14]<=0 ) ok = 0;
207 if( !SAVE() ) return;
209 int *store = tracker.Tracklets() + r.fTrackStoreOffset;
210 int *hitstore = tracker.Tracklets() +r.fHitStoreOffset;
214 store[3] = r.fFirstRow;
215 store[4] = r.fLastRow;
216 if( CAMath::Abs(tParam.Par()[4])<1.e-8 ) tParam.Par()[4] = 1.e-8;
217 *((AliHLTTPCCATrackParam1*)(store+5)) = tParam;
218 int w = (r.fNHits<<16)+r.fItr;
219 for( int iRow=0; iRow<160; iRow++ ){
220 Int_t ih = hitstore[iRow];
222 int ihTot = tracker.Rows()[iRow].FirstHit() + ih;
223 CAMath::atomicMax( tracker.HitIsUsed() + ihTot, w );
229 GPUd() void AliHLTTPCCATrackletConstructor::UpdateTracklet
230 ( Int_t /*nBlocks*/, Int_t /*nThreads*/, Int_t /*iBlock*/, Int_t /*iThread*/, Int_t /*iSync*/,
231 AliHLTTPCCASharedMemory &s, AliHLTTPCCAThreadMemory &r, AliHLTTPCCATracker &tracker, AliHLTTPCCATrackParam1 &tParam,Int_t iRow )
233 // reconstruction of tracklets, tracklets update step
237 const Int_t kMaxRowGap = 5;
239 int *hitstore = tracker.Tracklets() +r.fHitStoreOffset;
241 AliHLTTPCCARow &row = tracker.Rows()[iRow];
243 float y0 = row.Grid().YMin();
244 float stepY = row.HstepY();
245 float z0 = row.Grid().ZMin();
246 float stepZ = row.HstepZ();
247 float stepYi = row.HstepYi();
248 float stepZi = row.HstepZi();
250 if( r.fStage == 0 ){ // fitting part
253 if( iRow<r.fFirstRow || r.fCurrIH<0 ) break;
255 uint4 *tmpint4 = s.fData[r.fCurrentData];
256 ushort2 hh = reinterpret_cast<ushort2*>(tmpint4)[r.fCurrIH];
258 Int_t oldIH = r.fCurrIH;
259 r.fCurrIH = reinterpret_cast<Short_t*>(tmpint4)[row.FullLinkOffset() + r.fCurrIH];
262 float y = y0 + hh.x*stepY;
263 float z = z0 + hh.y*stepZ;
265 if( iRow==r.fFirstRow ){
270 tracker.GetErrors2( iRow, tParam, err2Y, err2Z );
271 tParam.Cov()[0] = err2Y;
272 tParam.Cov()[2] = err2Z;
274 if( !tParam.TransportToX0( x, .95 ) ){
275 if( SAVE() ) hitstore[iRow] = -1;
279 tracker.GetErrors2( iRow, *((AliHLTTPCCATrackParam*)&tParam), err2Y, err2Z );
280 if( !tParam.Filter2( y, z, err2Y, err2Z, .95 ) ) {
281 if( SAVE() ) hitstore[iRow] = -1;
285 if( SAVE() ) hitstore[iRow] = oldIH;
290 if( r.fNHits<3 ){ r.fNHits=0; r.fGo = 0;}
295 else // forward/backward searching part
298 if( r.fStage == 2 && iRow>=r.fFirstRow ) break;
299 if( r.fNMissed>kMaxRowGap ){
308 if( !tParam.TransportToX0( x, .95 ) ) break;
309 uint4 *tmpint4 = s.fData[r.fCurrentData];
311 ushort2 *hits = reinterpret_cast<ushort2*>(tmpint4);
312 UInt_t *gridContent1 = ((UInt_t*)(s.fGridContent1));
314 float fY = tParam.GetY();
315 float fZ = tParam.GetZ();
318 { // search for the closest hit
321 Int_t fY0 = (Int_t) ((fY - y0)*stepYi);
322 Int_t fZ0 = (Int_t) ((fZ - z0)*stepZi);
323 Int_t ds0 = ( ((int)1)<<30);
327 UInt_t fHitYfst=1, fHitYlst=0, fHitYfst1=1, fHitYlst1=0;
329 fIndYmin = row.Grid().GetBin( (float)(fY-1.), (float)(fZ-1.) );
330 UInt_t c = gridContent1[fIndYmin];
331 fHitYfst = c & 0x000003FF;
332 fHitYlst = fHitYfst + ((c & 0x0000FC00)>>10);
333 fHitYfst1 = ( c & 0x03FF0000 )>>16;
334 fHitYlst1 = fHitYfst1 + ((c & 0xFC000000)>>26);
336 for( UInt_t fIh = fHitYfst; fIh<fHitYlst; fIh++ ){
337 ushort2 hh = hits[fIh];
338 Int_t ddy = (Int_t)(hh.x) - fY0;
339 Int_t ddz = (Int_t)(hh.y) - fZ0;
340 Int_t dds = CAMath::mul24(ddy,ddy) + CAMath::mul24(ddz,ddz);
347 for( UInt_t fIh = fHitYfst1; fIh<fHitYlst1; fIh++ ){
348 ushort2 hh = hits[fIh];
349 Int_t ddy = (Int_t)(hh.x) - fY0;
350 Int_t ddz = (Int_t)(hh.y) - fZ0;
351 Int_t dds = CAMath::mul24(ddy,ddy) + CAMath::mul24(ddz,ddz);
357 }// end of search for the closest hit
361 ushort2 hh = hits[best];
363 tracker.GetErrors2( iRow, *((AliHLTTPCCATrackParam*)&tParam), err2Y, err2Z );
365 float y = y0 + hh.x*stepY;
366 float z = z0 + hh.y*stepZ;
370 const Float_t kFactor = 3.5*3.5;
371 Float_t sy2 = kFactor*( tParam.GetErr2Y() + err2Y );
372 Float_t sz2 = kFactor*( tParam.GetErr2Z() + err2Z );
373 if( sy2 > 1. ) sy2 = 1.;
374 if( sz2 > 1. ) sz2 = 1.;
375 if( iRow==63 || iRow==64 || iRow==65 ){
376 if( sy2 < 4. ) sy2 = 4.;
377 if( sz2 < 4. ) sz2 = 4.;
381 if( CAMath::fmul_rz(dy,dy)>sy2 || CAMath::fmul_rz(dz,dz)>sz2 ) break;
383 if( !tParam.Filter2( y, z, err2Y, err2Z, .95 ) ) break;
385 if( SAVE() ) hitstore[ iRow ] = best;
394 GPUd() void AliHLTTPCCATrackletConstructor::Thread
395 ( Int_t nBlocks, Int_t nThreads, Int_t iBlock, Int_t iThread, Int_t iSync,
396 AliHLTTPCCASharedMemory &s, AliHLTTPCCAThreadMemory &r, AliHLTTPCCATracker &tracker, AliHLTTPCCATrackParam1 &tParam )
399 // reconstruction of tracklets
402 Step0( nBlocks, nThreads, iBlock, iThread, iSync, s, r, tracker, tParam );
406 Step1( nBlocks, nThreads, iBlock, iThread, iSync, s, r, tracker, tParam );
410 Step2( nBlocks, nThreads, iBlock, iThread, iSync, s, r, tracker, tParam );
417 ReadData( iThread, s, r, tracker, s.fMinStartRow );
421 else if( iSync==3+159*2+1 )//322
425 Int_t nextRow = s.fMaxStartRow-1;
426 if( nextRow<0 ) nextRow = 0;
427 ReadData( iThread, s, r, tracker, nextRow );
433 else if( iSync<=3+159*2+1+159*2 )
437 if( iSync<=3+159*2 ){
439 //if( iBlock==0 && iThread==0 ) myprintf1(iSync,iRow);
440 if( iRow < s.fMinStartRow ) return;
442 if( nextRow>158 ) nextRow = 158;
444 iRow = 158 - (iSync - 4-159*2-1)/2;
445 //if( iBlock==0 && iThread==0 ) myprintf2(iSync,iRow);
446 if( iRow >= s.fMaxStartRow ) return;
448 if( nextRow<0 ) nextRow = 0;
452 UnpackGrid( nBlocks, nThreads, iBlock, iThread, iSync,
453 s, r, tracker, tParam, iRow );
455 if( r.fIsMemThread ){
456 ReadData( iThread, s, r, tracker, nextRow );
458 UpdateTracklet( nBlocks, nThreads, iBlock, iThread, iSync,
459 s, r, tracker, tParam, iRow );
461 r.fCurrentData = !r.fCurrentData;
465 else if( iSync== 4+159*4 +1+1 ) // 642
468 StoreTracklet( nBlocks, nThreads, iBlock, iThread, iSync, //SG!!!
469 s, r, tracker, tParam );