// @(#) $Id: AliHLTTPCCATrackletConstructor.cxx 27042 2008-07-02 12:06:02Z richterm $ // ************************************************************************** // This file is property of and copyright by the ALICE HLT Project * // ALICE Experiment at CERN, All rights reserved. * // * // Primary Authors: Sergey Gorbunov * // Ivan Kisel * // for The ALICE HLT Project. * // * // Permission to use, copy, modify and distribute this software and its * // documentation strictly for non-commercial purposes is hereby granted * // without fee, provided that the above copyright notice appears in all * // copies and that both the copyright notice and this permission notice * // appear in the supporting documentation. The authors make no claims * // about the suitability of this software for any purpose. It is * // provided "as is" without express or implied warranty. * // * //*************************************************************************** #include "AliHLTTPCCATracker.h" #include "AliHLTTPCCATrackParam.h" #include "AliHLTTPCCATrackParam.h" #include "AliHLTTPCCAGrid.h" #include "AliHLTTPCCAHitArea.h" #include "AliHLTTPCCAMath.h" #include "AliHLTTPCCADef.h" #include "AliHLTTPCCATracklet.h" #include "AliHLTTPCCATrackletConstructor.h" //#include "AliHLTTPCCAPerformance.h" //#include "TH1D.h" //#define DRAW #ifdef DRAW #include "AliHLTTPCCADisplay.h" #endif GPUd() void AliHLTTPCCATrackletConstructor::Step0 ( int nBlocks, int /*nThreads*/, int iBlock, int iThread, AliHLTTPCCASharedMemory &s, AliHLTTPCCAThreadMemory &r, AliHLTTPCCATracker &tracker, AliHLTTPCCATrackParam &/*tParam*/ ) { // reconstruction of tracklets, step 0 r.fIsMemThread = ( iThread < TRACKLET_CONSTRUCTOR_NMEMTHREDS ); if ( iThread == 0 ) { int nTracks = *tracker.NTracklets(); int nTrPerBlock = nTracks / nBlocks + 1; s.fNRows = tracker.Param().NRows(); s.fItr0 = nTrPerBlock * iBlock; s.fItr1 = s.fItr0 + nTrPerBlock; if ( s.fItr1 > nTracks ) s.fItr1 = nTracks; s.fMinStartRow = 158; s.fMaxEndRow = 0; } if ( iThread < 32 ) { s.fMinStartRow32[iThread] = 158; } } GPUd() void AliHLTTPCCATrackletConstructor::Step1 ( int /*nBlocks*/, int /*nThreads*/, int /*iBlock*/, int iThread, AliHLTTPCCASharedMemory &s, AliHLTTPCCAThreadMemory &r, AliHLTTPCCATracker &tracker, AliHLTTPCCATrackParam &tParam ) { // reconstruction of tracklets, step 1 r.fItr = s.fItr0 + ( iThread - TRACKLET_CONSTRUCTOR_NMEMTHREDS ); r.fGo = ( !r.fIsMemThread ) && ( r.fItr < s.fItr1 ); r.fSave = r.fGo; r.fNHits = 0; if ( !r.fGo ) return; r.fStage = 0; AliHLTTPCCATracklet &tracklet = tracker.Tracklets()[r.fItr]; unsigned int kThread = iThread % 32;//& 00000020; if ( SAVE() ) for ( int i = 0; i < 160; i++ ) tracklet.SetRowHit( i, -1 ); AliHLTTPCCAHitId id = tracker.TrackletStartHits()[r.fItr]; r.fStartRow = id.RowIndex(); r.fEndRow = r.fStartRow; r.fFirstRow = r.fStartRow; r.fLastRow = r.fFirstRow; r.fCurrIH = id.HitIndex(); CAMath::AtomicMin( &s.fMinStartRow32[kThread], r.fStartRow ); tParam.SetSinPhi( 0 ); tParam.SetDzDs( 0 ); tParam.SetQPt( 0 ); tParam.SetSignCosPhi( 1 ); tParam.SetChi2( 0 ); tParam.SetNDF( -3 ); tParam.SetCov( 0, 1 ); tParam.SetCov( 1, 0 ); tParam.SetCov( 2, 1 ); tParam.SetCov( 3, 0 ); tParam.SetCov( 4, 0 ); tParam.SetCov( 5, 1 ); tParam.SetCov( 6, 0 ); tParam.SetCov( 7, 0 ); tParam.SetCov( 8, 0 ); tParam.SetCov( 9, 1 ); tParam.SetCov( 10, 0 ); tParam.SetCov( 11, 0 ); tParam.SetCov( 12, 0 ); tParam.SetCov( 13, 0 ); tParam.SetCov( 14, 10. ); } GPUd() void AliHLTTPCCATrackletConstructor::Step2 ( int /*nBlocks*/, int nThreads, int /*iBlock*/, int iThread, AliHLTTPCCASharedMemory &s, AliHLTTPCCAThreadMemory &/*r*/, AliHLTTPCCATracker &/*tracker*/, AliHLTTPCCATrackParam &/*tParam*/ ) { // reconstruction of tracklets, step 2 if ( iThread == 0 ) { //CAMath::AtomicMinGPU(&s.fMinRow, s.fMinRow32[iThread]); int minStartRow = 158; int n = ( nThreads > 32 ) ? 32 : nThreads; for ( int i = 0; i < n; i++ ) { if ( s.fMinStartRow32[i] < minStartRow ) minStartRow = s.fMinStartRow32[i]; } s.fMinStartRow = minStartRow; } } GPUd() void AliHLTTPCCATrackletConstructor::ReadData ( int iThread, AliHLTTPCCASharedMemory &s, AliHLTTPCCAThreadMemory &r, AliHLTTPCCATracker &tracker, int iRow ) { // reconstruction of tracklets, read data step if ( r.fIsMemThread ) { const AliHLTTPCCARow &row = tracker.Row( iRow ); bool jr = !r.fCurrentData; // copy hits, grid content and links // FIXME: inefficient copy const int numberOfHits = row.NHits(); ushort2 *sMem1 = reinterpret_cast( s.fData[jr] ); for ( int i = iThread; i < numberOfHits; i += TRACKLET_CONSTRUCTOR_NMEMTHREDS ) { sMem1[i].x = tracker.HitDataY( row, i ); sMem1[i].y = tracker.HitDataZ( row, i ); } short *sMem2 = reinterpret_cast( s.fData[jr] ) + 2 * numberOfHits; for ( int i = iThread; i < numberOfHits; i += TRACKLET_CONSTRUCTOR_NMEMTHREDS ) { sMem2[i] = tracker.HitLinkUpData( row, i ); } unsigned short *sMem3 = reinterpret_cast( s.fData[jr] ) + 3 * numberOfHits; const int n = row.FullSize(); // + grid content size for ( int i = iThread; i < n; i += TRACKLET_CONSTRUCTOR_NMEMTHREDS ) { sMem3[i] = tracker.FirstHitInBin( row, i ); } } } GPUd() void AliHLTTPCCATrackletConstructor::StoreTracklet ( int /*nBlocks*/, int /*nThreads*/, int /*iBlock*/, int /*iThread*/, AliHLTTPCCASharedMemory &/*s*/, AliHLTTPCCAThreadMemory &r, AliHLTTPCCATracker &tracker, AliHLTTPCCATrackParam &tParam ) { // reconstruction of tracklets, tracklet store step if ( !r.fSave ) return; //AliHLTTPCCAPerformance::Instance().HNHitsPerTrackCand()->Fill(r.fNHits); do { { //std::cout<<"tracklet to store: "<( tmpint4 )[r.fCurrIH]; int oldIH = r.fCurrIH; r.fCurrIH = reinterpret_cast( tmpint4 )[2 * row.NHits() + r.fCurrIH]; // read from linkup data float x = row.X(); float y = y0 + hh.x * stepY; float z = z0 + hh.y * stepZ; #ifdef DRAW if ( drawFit ) std::cout << " fit tracklet: new hit " << oldIH << ", xyz=" << x << " " << y << " " << z << std::endl; #endif if ( iRow == r.fStartRow ) { tParam.SetX( x ); tParam.SetY( y ); tParam.SetZ( z ); r.fLastY = y; r.fLastZ = z; #ifdef DRAW if ( drawFit ) std::cout << " fit tracklet " << r.fItr << ", row " << iRow << " first row" << std::endl; #endif } else { float err2Y, err2Z; float dx = x - tParam.X(); float dy = y - r.fLastY;//tParam.Y(); float dz = z - r.fLastZ;//tParam.Z(); r.fLastY = y; r.fLastZ = z; float ri = 1. / CAMath::Sqrt( dx * dx + dy * dy ); if ( iRow == r.fStartRow + 2 ) { //SG!!! important - thanks to Matthias tParam.SetSinPhi( dy*ri ); tParam.SetSignCosPhi( dx ); tParam.SetDzDs( dz*ri ); //std::cout << "Init. errors... " << r.fItr << std::endl; tracker.GetErrors2( iRow, tParam, err2Y, err2Z ); //std::cout << "Init. errors = " << err2Y << " " << err2Z << std::endl; tParam.SetCov( 0, err2Y ); tParam.SetCov( 2, err2Z ); } if ( drawFit ) { #ifdef DRAW std::cout << " fit tracklet " << r.fItr << ", row " << iRow << " transporting.." << std::endl; std::cout << " params before transport=" << std::endl; tParam.Print(); #endif } float sinPhi, cosPhi; if ( r.fNHits >= 10 && CAMath::Abs( tParam.SinPhi() ) < .99 ) { sinPhi = tParam.SinPhi(); cosPhi = CAMath::Sqrt( 1 - sinPhi * sinPhi ); } else { sinPhi = dy * ri; cosPhi = dx * ri; } #ifdef DRAW if ( drawFit ) std::cout << "sinPhi0 = " << sinPhi << ", cosPhi0 = " << cosPhi << std::endl; #endif if ( !tParam.TransportToX( x, sinPhi, cosPhi, tracker.Param().ConstBz(), -1 ) ) { #ifdef DRAW if ( drawFit ) std::cout << " tracklet " << r.fItr << ", row " << iRow << ": can not transport!!" << std::endl; #endif if ( SAVE() ) tracklet.SetRowHit( iRow, -1 ); break; } //std::cout<<"mark1 "<( tmpint4 ); float fY = tParam.GetY(); float fZ = tParam.GetZ(); int best = -1; { // search for the closest hit const int fIndYmin = row.Grid().GetBinBounded( fY - 1.f, fZ - 1.f ); assert( fIndYmin >= 0 ); int ds; int fY0 = ( int ) ( ( fY - y0 ) * stepYi ); int fZ0 = ( int ) ( ( fZ - z0 ) * stepZi ); int ds0 = ( ( ( int )1 ) << 30 ); ds = ds0; unsigned int fHitYfst = 1, fHitYlst = 0, fHitYfst1 = 1, fHitYlst1 = 0; if ( drawSearch ) { #ifdef DRAW std::cout << " tracklet " << r.fItr << ", row " << iRow << ": grid N=" << row.Grid().N() << std::endl; std::cout << " tracklet " << r.fItr << ", row " << iRow << ": minbin=" << fIndYmin << std::endl; #endif } { int nY = row.Grid().Ny(); unsigned short *sGridP = ( reinterpret_cast( tmpint4 ) ) + 3 * row.NHits(); fHitYfst = sGridP[fIndYmin]; fHitYlst = sGridP[fIndYmin+2]; fHitYfst1 = sGridP[fIndYmin+nY]; fHitYlst1 = sGridP[fIndYmin+nY+2]; assert( fHitYfst <= row.NHits() ); assert( fHitYlst <= row.NHits() ); assert( fHitYfst1 <= row.NHits() ); assert( fHitYlst1 <= row.NHits() ); if ( drawSearch ) { #ifdef DRAW std::cout << " Grid, row " << iRow << ": nHits=" << row.NHits() << ", grid n=" << row.Grid().N() << ", c[n]=" << sGridP[row.Grid().N()] << std::endl; std::cout << "hit steps = " << stepY << " " << stepZ << std::endl; std::cout << " Grid bins:" << std::endl; for ( unsigned int i = 0; i < row.Grid().N(); i++ ) { std::cout << " bin " << i << ": "; for ( int j = sGridP[i]; j < sGridP[i+1]; j++ ) { ushort2 hh = hits[j]; float y = y0 + hh.x * stepY; float z = z0 + hh.y * stepZ; std::cout << "[" << j << "|" << y << "," << z << "] "; } std::cout << std::endl; } #endif } if ( sGridP[row.Grid().N()] != row.NHits() ) { #ifdef DRAW std::cout << " grid, row " << iRow << ": nHits=" << row.NHits() << ", grid n=" << row.Grid().N() << ", c[n]=" << sGridP[row.Grid().N()] << std::endl; //exit(0); #endif } } if ( drawSearch ) { #ifdef DRAW std::cout << " tracklet " << r.fItr << ", row " << iRow << ", yz= " << fY << "," << fZ << ": search hits=" << fHitYfst << " " << fHitYlst << " / " << fHitYfst1 << " " << fHitYlst1 << std::endl; std::cout << " hit search :" << std::endl; #endif } for ( unsigned int fIh = fHitYfst; fIh < fHitYlst; fIh++ ) { assert( fIh < row.NHits() ); ushort2 hh = hits[fIh]; int ddy = ( int )( hh.x ) - fY0; int ddz = ( int )( hh.y ) - fZ0; int dds = CAMath::Abs( ddy ) + CAMath::Abs( ddz ); if ( drawSearch ) { #ifdef DRAW std::cout << fIh << ": hityz= " << hh.x << " " << hh.y << "(" << hh.x*stepY << " " << hh.y*stepZ << "), trackyz=" << fY0 << " " << fZ0 << "(" << fY0*stepY << " " << fZ0*stepZ << "), dy,dz,ds= " << ddy << " " << ddz << " " << dds << "(" << ddy*stepY << " " << ddz*stepZ << std::endl; #endif } if ( dds < ds ) { ds = dds; best = fIh; } } for ( unsigned int fIh = fHitYfst1; fIh < fHitYlst1; fIh++ ) { ushort2 hh = hits[fIh]; int ddy = ( int )( hh.x ) - fY0; int ddz = ( int )( hh.y ) - fZ0; int dds = CAMath::Abs( ddy ) + CAMath::Abs( ddz ); if ( drawSearch ) { #ifdef DRAW std::cout << fIh << ": hityz= " << hh.x << " " << hh.y << "(" << hh.x*stepY << " " << hh.y*stepZ << "), trackyz=" << fY0 << " " << fZ0 << "(" << fY0*stepY << " " << fZ0*stepZ << "), dy,dz,ds= " << ddy << " " << ddz << " " << dds << "(" << ddy*stepY << " " << ddz*stepZ << std::endl; #endif } if ( dds < ds ) { ds = dds; best = fIh; } } }// end of search for the closest hit if ( best < 0 ) break; if ( drawSearch ) { #ifdef DRAW std::cout << "hit search " << r.fItr << ", row " << iRow << " hit " << best << " found" << std::endl; AliHLTTPCCADisplay::Instance().DrawSliceHit( iRow, best, kRed, 1. ); AliHLTTPCCADisplay::Instance().Ask(); AliHLTTPCCADisplay::Instance().DrawSliceHit( iRow, best, kWhite, 1 ); AliHLTTPCCADisplay::Instance().DrawSliceHit( iRow, best ); #endif } ushort2 hh = hits[best]; //std::cout<<"mark 3, "< 2. ) sy2 = 2.; if ( sz2 > 2. ) sz2 = 2.; if ( drawSearch ) { #ifdef DRAW std::cout << "dy,sy= " << dy << " " << CAMath::Sqrt( sy2 ) << ", dz,sz= " << dz << " " << CAMath::Sqrt( sz2 ) << std::endl; std::cout << "dy,dz= " << dy << " " << dz << ", sy,sz= " << CAMath::Sqrt( sy2 ) << " " << CAMath::Sqrt( sz2 ) << ", sy,sz= " << CAMath::Sqrt( kFactor*( tParam.GetErr2Y() + err2Y ) ) << " " << CAMath::Sqrt( kFactor*( tParam.GetErr2Z() + err2Z ) ) << std::endl; #endif } if ( CAMath::FMulRZ( dy, dy ) > sy2 || CAMath::FMulRZ( dz, dz ) > sz2 ) { if ( drawSearch ) { #ifdef DRAW std::cout << "found hit is out of the chi2 window\n " << std::endl; #endif } break; } #ifdef DRAW //if( SAVE() ) hitstore[ iRow ] = best; //std::cout<<"hit search before filter: "< 158 ) nextRow = 158; } else { iRow = 158 - ( iSync - 4 - 159 - 1 ); if ( iRow > s.fMaxEndRow ) return; nextRow = iRow - 1; if ( nextRow < 0 ) nextRow = 0; } if ( r.fIsMemThread ) { ReadData( iThread, s, r, tracker, nextRow ); } else { UpdateTracklet( nBlocks, nThreads, iBlock, iThread, s, r, tracker, tParam, iRow ); } r.fCurrentData = !r.fCurrentData; } else if ( iSync == 4 + 159*2 + 1 + 1 ) { // StoreTracklet( nBlocks, nThreads, iBlock, iThread, s, r, tracker, tParam ); } }