3 #ifndef ALIHLTINDEXGRID_H
4 #define ALIHLTINDEXGRID_H
5 //* This file is property of and copyright by the ALICE HLT Project *
6 //* ALICE Experiment at CERN, All rights reserved. *
7 //* See cxx source for full Copyright notice *
9 /// @file AliHLTIndexGrid.h
10 /// @author Matthias Richter
12 /// @brief Index grid for 3 dimensional coordinates
15 #include "AliHLTDataTypes.h"
21 template <typename T, typename V>
22 class AliHLTIndexGrid {
24 AliHLTIndexGrid(T maxX, T stepX,
27 int initialDataSize=-1)
40 , fDataDimension(initialDataSize)
46 if (fMaxX>0. && fMaxY>0. && fMaxZ>0 &&
47 fStepX>0. && fStepY>0. && fStepZ>0) {
48 fDimX=(int)ceil(fMaxX/fStepX);
49 fDimY=(int)ceil(fMaxY/fStepY);
50 fDimZ=(int)ceil(fMaxZ/fStepZ);
52 fCellDimension=fDimX*fDimY*fDimZ;
53 fCells=new AliHLTIndexGridCell[fCellDimension];
54 if (fDataDimension<0) fDataDimension=fgkDefaultDataSize;
55 fData=new V[fDataDimension];
60 virtual ~AliHLTIndexGrid() {
62 if (fData) delete [] fData;
63 if (fCells) delete [] fCells;
66 // for now array of spacepoint ids
69 int GetDimensionX() const {return fDimX;}
70 int GetDimensionY() const {return fDimY;}
71 int GetDimensionZ() const {return fDimZ;}
72 int GetXIndex(T x) const {
73 if (x>fMaxX) return fDimX-1;
75 return (int)(x/fStepX);
77 int GetYIndex(T y) const {
78 if (y>fMaxY) return fDimY-1;
80 return (int)(y/fStepY);
82 int GetZIndex(T z) const {
83 if (z>fMaxZ) return fDimZ-1;
85 return (int)(z/fStepZ);
87 T GetLowerBoundX(int cell) const {
88 if (fDimX==0 || fDimY==0 ||fDimZ==0) return 0.;
89 int index=cell/(fDimY*fDimZ);
92 T GetLowerBoundY(int cell) const {
93 if (fDimX==0 || fDimY==0 ||fDimZ==0) return 0.;
94 int index=cell%(fDimY*fDimZ); index/=fDimZ;
97 T GetLowerBoundZ(int cell) const {
98 if (fDimX==0 || fDimY==0 ||fDimZ==0) return 0.;
99 int index=cell%(fDimY*fDimZ); index%=fDimZ;
102 int GetCellIndex(T x, T y, T z) const {
103 return GetXIndex(x)*fDimY*fDimZ + (y<0?0:GetYIndex(y))*fDimZ + (z<0?0:GetZIndex(z));
105 int GetNumberOfSpacePoints(int index, int endIndex) const {
106 if (!fCells) return 0;
108 for (int cell=index; cell<endIndex && cell<fCellDimension && count<fCount; cell++) if (fCells[cell].fCount>0) count+=fCells[cell].fCount;
112 // increment counter of the cell where the spacepoint is
113 int CountSpacePoint(T x, T y, T z) {
114 // increment counter of the cell where the spacepoint is
115 int cell=GetCellIndex(x, y, z);
116 if (cell<0 || !fCells || cell>=fCellDimension) return -EFAULT;
117 if (fCells[cell].fCount<0) fCells[cell].fCount=1;
118 else fCells[cell].fCount++;
123 // add spacepoint, all spacepoints must have been counted before
124 int AddSpacePoint(ValueType t, T x, T y, T z) {
125 // add spacepoint, all spacepoints must have been counted before
126 int cell=GetCellIndex(x, y, z);
127 if (cell<0 || !fCells || cell>=fCellDimension) return -EFAULT;
128 if (fCells[cell].fFilled==fCells[cell].fCount) return -ENOSPC;
129 if (fCells[cell].fStartIndex<0 && IndexCells()<0) return -EACCES;
130 int offset=fCells[cell].fStartIndex+fCells[cell].fFilled;
132 fCells[cell].fFilled++;
137 void Clear(const char* /*option*/="") {
138 // clear internal data
139 if (fCells) memset(fCells, 0xff, fCellDimension*sizeof(AliHLTIndexGridCell));
140 if (fData) memset(fData, 0, fDataDimension*sizeof(V));
144 void Print(const char* /*option*/="") {
146 bool bPrintEmpty=false;
147 std::stringstream str;
148 str << "AliHLTIndexGrid: " << (fCells?fCellDimension:0) << " cells" << endl;
149 str << " x: " << fDimX << " [0," << fMaxX << "]" << endl;
150 str << " y: " << fDimY << " [0," << fMaxY << "]" << endl;
151 str << " z: " << fDimZ << " [0," << fMaxZ << "]" << endl;
152 str << " " << GetNumberOfSpacePoints(0, fCellDimension) << " point(s)" << endl;
154 for (int i=0; i<fCellDimension; i++) {
155 if (!bPrintEmpty && fCells[i].fCount<=0) continue;
156 str << " " << setfill(' ') << setw(7) << setprecision(0) << i << " ("
157 << " " << setw(3) << GetLowerBoundX(i)
158 << " " << setw(3) << GetLowerBoundY(i)
159 << " " << setw(4) << GetLowerBoundZ(i)
161 str << setw(3) << fCells[i].fCount << " entries, " << setw(3) << fCells[i].fFilled << " filled";
162 str << " start index " << setw(5) << fCells[i].fStartIndex;
164 if (fCells[i].fCount>0) {
166 for (iterator id=begin(GetLowerBoundX(i), GetLowerBoundY(i), GetLowerBoundZ(i));
168 str << " 0x" << hex << setw(8) << setfill('0') << id.Data();
182 iterator(ValueType* pData)
184 iterator(const iterator& i)
186 iterator& operator=(const iterator& i)
187 { fData=i.fData; return *this;}
188 ~iterator() {fData=NULL;}
190 bool operator==(const iterator& i) const {return (fData!=NULL) && (fData==i.fData);}
191 bool operator!=(const iterator& i) const {return (fData!=NULL) && (fData!=i.fData);}
193 iterator& operator++() {fData++; return *this;}
194 iterator& operator--() {fData--; return *this;}
196 iterator operator++(int) {iterator i(*this); fData++; return i;}
197 iterator operator--(int) {iterator i(*this); fData--; return i;}
199 iterator& operator+=(int step) {fData+=step; return *this;}
201 const ValueType& Data() const {return *fData;}
202 ValueType& Data() {return *fData;}
206 ValueType* fData; //! data
209 // prepare iterator and end marker
210 iterator& begin(T x=(T)-1, T y=(T)-1, T z=(T)-1) {
211 fIterator.~iterator();
212 fIteratorEnd.~iterator();
218 new (&fIterator) iterator(fData);
219 fIteratorEnd=fIterator;
220 fIteratorEnd+=fCount;
225 // only search for the start index if specific x selected
226 int cell=GetCellIndex(x, y, z);
227 if (cell<0 || !fCells || cell>=fCellDimension) return fIterator;
228 // get the index of the cell
229 startIndex=fCells[cell].fStartIndex;
230 if (startIndex<0 || !fData || startIndex>=fDataDimension) return fIterator;
232 // get the range end position
234 if (x<0) endCell=fCellDimension;
235 else if (y<0) endCell=GetCellIndex(x+fStepX, -1., -1.); // all entries for fixed x
236 else if (z<0) endCell=GetCellIndex(x, y+fStepY, -1.); // all entries for fixed x and y
238 // cell index returned is never outside the array
239 // so this is a special case where we get to the bounds of the array
240 endCell=fCellDimension;
243 new (&fIterator) iterator(fData+startIndex);
244 fIteratorEnd=fIterator;
245 fIteratorEnd+=GetNumberOfSpacePoints(cell, endCell);
249 // get loop end marker
254 struct AliHLTIndexGridCell {
262 // standard constructor prohibited
264 // copy constructor prohibited
265 AliHLTIndexGrid(const AliHLTIndexGrid&);
266 // assignment operator prohibited
267 AliHLTIndexGrid& operator=(const AliHLTIndexGrid&);
270 // set the start index for data of every cell based on the counts
271 if (!fCells || fCellDimension<=0) return -ENOBUFS;
274 for (; cell<fCellDimension; cell++) {
275 if (fCells[cell].fCount<0) continue;
276 fCells[cell].fStartIndex=offset;
277 offset+=fCells[cell].fCount;
278 fCells[cell].fFilled=0;
281 if (offset>fDataDimension) {
282 // grow the data array
283 auto_ptr<V> newArray(new V[offset]);
284 if (newArray.get()) {
285 memcpy(newArray.get(), fData, fDataDimension);
286 memset(newArray.get()+fDataDimension, 0, (offset-fDataDimension)*sizeof(V));
288 fData=newArray.release();
289 fDataDimension=offset;
291 for (cell=0; cell<fCellDimension; cell++) {
292 fCells[cell].fStartIndex=-1;
311 AliHLTIndexGridCell* fCells; //! cell array
312 int fCellDimension; //! size of cell array
313 ValueType* fData; //! spacepoint data
314 int fDataDimension; //! size of spacepoint data
317 iterator fIterator; //! iterator
318 iterator fIteratorEnd; //! end marker iterator
320 static const int fgkDefaultDataSize=10000; //! the default data size
322 ClassDef(AliHLTIndexGrid, 0)