1 /**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * All rights reserved. *
6 * Copyright 2009 Matthias Kretz <kretz@kde.org> *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
17 #include "AliHLTTPCCASliceData.h"
18 #include "AliHLTTPCCAClusterData.h"
19 #include "AliHLTTPCCAMath.h"
20 #include "AliHLTArray.h"
21 #include "AliHLTTPCCAHit.h"
22 #include "AliHLTTPCCAParam.h"
23 #include "MemoryAssignmentHelpers.h"
26 // calculates an approximation for 1/sqrt(x)
27 // Google for 0x5f3759df :)
28 static inline float fastInvSqrt( float _x )
30 union { float f; int i; } x = { _x };
31 const float xhalf = 0.5f * x.f;
32 x.i = 0x5f3759df - ( x.i >> 1 );
33 x.f = x.f * ( 1.5f - xhalf * x.f * x.f );
37 inline void AliHLTTPCCASliceData::createGrid( AliHLTTPCCARow *row, const AliHLTTPCCAClusterData &data )
39 if ( row->NHits() <= 0 ) { // no hits or invalid data
40 // grid coordinates don't matter, since there are no hits
41 row->fGrid.CreateEmpty();
49 for ( int i = row->fHitNumberOffset; i < row->fHitNumberOffset + row->fNHits; ++i ) {
50 const float y = data.Y( i );
51 const float z = data.Z( i );
52 if ( yMax < y ) yMax = y;
53 if ( yMin > y ) yMin = y;
54 if ( zMax < z ) zMax = z;
55 if ( zMin > z ) zMin = z;
58 const float norm = fastInvSqrt( row->fNHits );
59 row->fGrid.Create( yMin, yMax, zMin, zMax,
60 CAMath::Max( ( yMax - yMin ) * norm, 2.f ),
61 CAMath::Max( ( zMax - zMin ) * norm, 2.f ) );
64 inline void AliHLTTPCCASliceData::PackHitData( AliHLTTPCCARow *row, const AliHLTArray<AliHLTTPCCAHit> &binSortedHits )
66 static const float shortPackingConstant = 1.f / 65535.f;
67 const float y0 = row->fGrid.YMin();
68 const float z0 = row->fGrid.ZMin();
69 const float stepY = ( row->fGrid.YMax() - y0 ) * shortPackingConstant;
70 const float stepZ = ( row->fGrid.ZMax() - z0 ) * shortPackingConstant;
71 const float stepYi = 1.f / stepY;
72 const float stepZi = 1.f / stepZ;
78 row->fHstepYi = stepYi;
79 row->fHstepZi = stepZi;
81 for ( int hitIndex = 0; hitIndex < row->fNHits; ++hitIndex ) {
83 const int globalHitIndex = row->fHitNumberOffset + hitIndex;
84 const AliHLTTPCCAHit &hh = binSortedHits[globalHitIndex];
85 const float xx = ( ( hh.Y() - y0 ) * stepYi ) + .5 ;
86 const float yy = ( ( hh.Z() - z0 ) * stepZi ) + .5 ;
87 if ( xx < 0 || yy < 0 || xx >= 65536 || yy >= 65536 ) {
88 std::cout << "!!!! hit packing error!!! " << xx << " " << yy << " " << std::endl;
90 // HitData is bin sorted
91 fHitDataY[row->fHitNumberOffset + hitIndex] = xx;
92 fHitDataZ[row->fHitNumberOffset + hitIndex] = yy;
96 void AliHLTTPCCASliceData::Clear()
101 void AliHLTTPCCASliceData::InitializeRows( const AliHLTTPCCAParam &p )
103 for ( int i = 0; i < p.NRows(); ++i ) {
104 fRows[i].fX = p.RowX( i );
105 fRows[i].fMaxY = CAMath::Tan( p.DAlpha() / 2. ) * fRows[i].fX;
109 void AliHLTTPCCASliceData::InitFromClusterData( const AliHLTTPCCAClusterData &data )
111 ////////////////////////////////////
113 ////////////////////////////////////
115 fNumberOfHits = data.NumberOfClusters();
117 /* TODO Vectorization
118 for ( int rowIndex = data.FirstRow(); rowIndex <= data.LastRow(); ++rowIndex ) {
119 int NumberOfClusters( int rowIndex ) const;
121 const int memorySize = fNumberOfHits * sizeof( short_v::Type )
123 const int numberOfRows = data.LastRow() - data.FirstRow();
124 enum { VectorAlignment = sizeof( int ) };
125 const int numberOfHitsPlusAlignment = NextMultipleOf < VectorAlignment / sizeof( int ) > ( fNumberOfHits );
126 const int memorySize =
128 numberOfHitsPlusAlignment * 4 * sizeof( short ) +
130 NextMultipleOf<VectorAlignment>( ( 23 * numberOfRows + 4 * fNumberOfHits ) * sizeof( int ) ) +
131 // HitWeights, ClusterDataIndex
132 numberOfHitsPlusAlignment * 2 * sizeof( int );
134 if ( fMemorySize < memorySize ) {
135 fMemorySize = memorySize;
137 fMemory = new char[fMemorySize + 4];// VectorAlignment];
141 AssignMemory( fLinkUpData, mem, numberOfHitsPlusAlignment );
142 AssignMemory( fLinkDownData, mem, numberOfHitsPlusAlignment );
143 AssignMemory( fHitDataY, mem, numberOfHitsPlusAlignment );
144 AssignMemory( fHitDataZ, mem, numberOfHitsPlusAlignment );
145 AssignMemory( fFirstHitInBin, mem, 23 * numberOfRows + 4 * fNumberOfHits );
146 AssignMemory( fHitWeights, mem, numberOfHitsPlusAlignment );
147 AssignMemory( fClusterDataIndex, mem, numberOfHitsPlusAlignment );
149 ////////////////////////////////////
150 // 2. fill HitData and FirstHitInBin
151 ////////////////////////////////////
153 for ( int rowIndex = 0; rowIndex < data.FirstRow(); ++rowIndex ) {
154 AliHLTTPCCARow &row = fRows[rowIndex];
155 row.fGrid.CreateEmpty();
158 row.fHitNumberOffset = 0;
159 row.fFirstHitInBinOffset = 0;
168 for ( int rowIndex = data.LastRow() + 1; rowIndex < 160; ++rowIndex ) {
169 AliHLTTPCCARow &row = fRows[rowIndex];
170 row.fGrid.CreateEmpty();
173 row.fHitNumberOffset = 0;
174 row.fFirstHitInBinOffset = 0;
184 AliHLTResizableArray<AliHLTTPCCAHit> binSortedHits( fNumberOfHits );
186 int gridContentOffset = 0;
188 int binCreationMemorySize = 103 * 2 + fNumberOfHits;
189 AliHLTResizableArray<unsigned short> binCreationMemory( binCreationMemorySize );
191 for ( int rowIndex = data.FirstRow(); rowIndex <= data.LastRow(); ++rowIndex ) {
192 AliHLTTPCCARow &row = fRows[rowIndex];
194 row.fNHits = data.NumberOfClusters( rowIndex );
195 assert( row.fNHits < ( 1 << sizeof( unsigned short ) * 8 ) );
196 row.fHitNumberOffset = data.RowOffset( rowIndex );
197 row.fFirstHitInBinOffset = gridContentOffset;
199 createGrid( &row, data );
200 const AliHLTTPCCAGrid &grid = row.fGrid;
201 const int numberOfBins = grid.N();
203 int binCreationMemorySizeNew;
204 if ( ( binCreationMemorySizeNew = numberOfBins * 2 + 6 + row.fNHits ) > binCreationMemorySize ) {
205 binCreationMemorySize = binCreationMemorySizeNew;
206 binCreationMemory.Resize( binCreationMemorySize );
209 AliHLTArray<unsigned short> c = binCreationMemory; // number of hits in all previous bins
210 AliHLTArray<unsigned short> bins = c + ( numberOfBins + 3 ); // cache for the bin index for every hit in this row
211 AliHLTArray<unsigned short> filled = bins + row.fNHits; // counts how many hits there are per bin
213 for ( unsigned int bin = 0; bin < row.fGrid.N() + 3; ++bin ) {
214 filled[bin] = 0; // initialize filled[] to 0
217 for ( int hitIndex = 0; hitIndex < row.fNHits; ++hitIndex ) {
218 const int globalHitIndex = row.fHitNumberOffset + hitIndex;
219 const unsigned short bin = row.fGrid.GetBin( data.Y( globalHitIndex ), data.Z( globalHitIndex ) );
220 bins[hitIndex] = bin;
224 unsigned short n = 0;
225 for ( int bin = 0; bin < numberOfBins + 3; ++bin ) {
230 for ( int hitIndex = 0; hitIndex < row.fNHits; ++hitIndex ) {
231 const unsigned short bin = bins[hitIndex];
233 const unsigned short ind = c[bin] + filled[bin]; // generate an index for this hit that is >= c[bin] and < c[bin + 1]
234 const int globalBinsortedIndex = row.fHitNumberOffset + ind;
235 const int globalHitIndex = row.fHitNumberOffset + hitIndex;
237 // allows to find the global hit index / coordinates from a global bin sorted hit index
238 fClusterDataIndex[globalBinsortedIndex] = globalHitIndex;
239 binSortedHits[globalBinsortedIndex].SetY( data.Y( globalHitIndex ) );
240 binSortedHits[globalBinsortedIndex].SetZ( data.Z( globalHitIndex ) );
243 PackHitData( &row, binSortedHits );
245 for ( int i = 0; i < numberOfBins; ++i ) {
246 fFirstHitInBin[row.fFirstHitInBinOffset + i] = c[i]; // global bin-sorted hit index
248 const unsigned short a = c[numberOfBins];
249 // grid.N is <= row.fNHits
250 const int nn = numberOfBins + grid.Ny() + 3;
251 for ( int i = numberOfBins; i < nn; ++i ) {
252 assert( row.fFirstHitInBinOffset + i < 23 * numberOfRows + 4 * fNumberOfHits );
253 fFirstHitInBin[row.fFirstHitInBinOffset + i] = a;
257 gridContentOffset += nn;
261 //SG cell finder - test code
263 if ( fTmpHitInputIDs ) delete[] fTmpHitInputIDs;
264 fTmpHitInputIDs = new int [NHits];
265 const float areaY = .5;
266 const float areaZ = .5;
267 int newRowNHitsTotal = 0;
268 bool *usedHits = new bool [NHits];
269 for ( int iHit = 0; iHit < NHits; iHit++ ) usedHits[iHit] = 0;
270 for ( int iRow = 0; iRow < fParam.NRows(); iRow++ ) {
271 rowHeaders[iRow*2 ] = newRowNHitsTotal; // new first hit
272 rowHeaders[iRow*2+1] = 0; // new N hits
274 int oldRowFirstHit = RowFirstHit[iRow];
275 int oldRowLastHit = oldRowFirstHit + RowNHits[iRow];
276 for ( int iHit = oldRowFirstHit; iHit < oldRowLastHit; iHit++ ) {
277 if ( usedHits[iHit] ) continue;
286 if ( 0 ) for ( int jHit = iHit + 1; jHit < oldRowLastHit; jHit++ ) {//SG!!!
287 //if( usedHits[jHit] ) continue;
288 float dy = Y[jHit] - y0;
289 float dz = Z[jHit] - z0;
290 if ( CAMath::Abs( dy ) < areaY && CAMath::Abs( dz ) < areaZ ) {
298 int id = newRowNHitsTotal + newRowNHits;
299 hitsXYZ[id*3+0 ] = cx / nclu;
300 hitsXYZ[id*3+1 ] = cy / nclu;
301 hitsXYZ[id*3+2 ] = cz / nclu;
302 fTmpHitInputIDs[id] = iHit;
305 rowHeaders[iRow*2+1] = newRowNHits;
306 newRowNHitsTotal += newRowNHits;
308 NHitsTotal() = newRowNHitsTotal;
309 reinterpret_cast<int*>( fInputEvent )[1+fParam.NRows()*2] = newRowNHitsTotal;
315 void AliHLTTPCCASliceData::ClearHitWeights()
317 #ifdef ENABLE_VECTORIZATION
318 const int_v v0( Zero );
319 const int *const end = fHitWeights + fNumberOfHits;
320 for ( int *mem = fHitWeights; mem < end; mem += v0.Size ) {
324 for ( int i = 0; i < fNumberOfHits; ++i ) {
330 void AliHLTTPCCASliceData::ClearLinks()
332 #ifdef ENABLE_VECTORIZATION
333 const short_v v0( -1 );
334 const short *const end1 = fLinkUpData + fNumberOfHits;
335 for ( short *mem = fLinkUpData; mem < end; mem += v0.Size ) {
338 const short *const end2 = fLinkDownData + fNumberOfHits;
339 for ( short *mem = fLinkDownData; mem < end; mem += v0.Size ) {
343 for ( int i = 0; i < fNumberOfHits; ++i ) {
346 for ( int i = 0; i < fNumberOfHits; ++i ) {
347 fLinkDownData[i] = -1;