LCOV - code coverage report
Current view: top level - HLT/BASE - AliHLTIndexGrid.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 193 0.5 %
Date: 2016-06-14 17:26:59 Functions: 3 141 2.1 %

          Line data    Source code
       1             : //-*- Mode: C++ -*-
       2             : // $Id$
       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                               *
       8             : 
       9             : /// @file   AliHLTIndexGrid.h
      10             : /// @author Matthias Richter
      11             : /// @date   2011-08-14
      12             : /// @brief  Index grid for 3 dimensional coordinates
      13             : ///
      14             : 
      15             : #include "AliHLTDataTypes.h"
      16             : #include <iostream>
      17             : #include <iomanip>
      18             : #include <memory>
      19             : #include <cerrno>
      20             : #include <cmath>
      21             : 
      22             : template <typename T, typename V>
      23             : class AliHLTIndexGrid {
      24             :  public:
      25             :   AliHLTIndexGrid(T maxX, T stepX,
      26             :                   T maxY, T stepY,
      27             :                   T maxZ, T stepZ,
      28             :                   int initialDataSize=-1)
      29           0 :     : fMaxX(maxX)
      30           0 :     , fStepX(stepX)
      31           0 :     , fMaxY(maxY)
      32           0 :     , fStepY(stepY)
      33           0 :     , fMaxZ(maxZ)
      34           0 :     , fStepZ(stepZ)
      35           0 :     , fDimX(0)
      36           0 :     , fDimY(0)
      37           0 :     , fDimZ(0)
      38           0 :     , fCells(NULL)
      39           0 :     , fCellDimension(0)
      40           0 :     , fData(NULL)
      41           0 :     , fDataDimension(initialDataSize)
      42           0 :     , fCount(0)
      43           0 :     , fIterator()
      44           0 :     , fIteratorEnd()
      45           0 :   {
      46             :     // constructor
      47           0 :     if (fMaxX>0. && fMaxY>0. && fMaxZ>0 &&
      48           0 :         fStepX>0. && fStepY>0. && fStepZ>0) {
      49           0 :       fDimX=(int)ceil(fMaxX/fStepX);
      50           0 :       fDimY=(int)ceil(fMaxY/fStepY);
      51           0 :       fDimZ=(int)ceil(fMaxZ/fStepZ);
      52             : 
      53           0 :       fCellDimension=fDimX*fDimY*fDimZ;
      54           0 :       fCells=new AliHLTIndexGridCell[fCellDimension];
      55           0 :       if (fDataDimension<0) fDataDimension=fgkDefaultDataSize;
      56           0 :       fData=new V[fDataDimension];
      57           0 :       Clear();
      58           0 :     }
      59           0 :   }
      60             : 
      61           0 :   virtual ~AliHLTIndexGrid() {
      62             :     // destructor
      63           0 :     if (fData) delete [] fData;
      64           0 :     if (fCells) delete [] fCells;
      65           0 :   }
      66             : 
      67             :   // for now array of spacepoint ids
      68             :   typedef V ValueType;
      69             : 
      70           0 :   int GetDimensionX() const {return fDimX;}
      71           0 :   int GetDimensionY() const {return fDimY;}
      72           0 :   int GetDimensionZ() const {return fDimZ;}
      73             :   int GetXIndex(T x) const {
      74           0 :     if (x>fMaxX) return fDimX-1;
      75           0 :     if (x<0) return 0;
      76           0 :     return (int)(x/fStepX);
      77           0 :   }
      78             :   int GetYIndex(T y) const {
      79           0 :     if (y>fMaxY) return fDimY-1;
      80           0 :     if (y<0) return 0;
      81           0 :     return (int)(y/fStepY);
      82           0 :   }
      83             :   int GetZIndex(T z) const {
      84           0 :     if (z>fMaxZ) return fDimZ-1;
      85           0 :     if (z<0) return 0;
      86           0 :     return (int)(z/fStepZ);
      87           0 :   }
      88             :   int Index(int xindex, int yindex, int zindex) {
      89           0 :     return xindex*fDimY*fDimZ + yindex*fDimZ + zindex;
      90             :   }
      91             :   T GetLowerBoundX(int cell) const {
      92           0 :     if (fDimX==0 || fDimY==0 ||fDimZ==0) return (T)0;
      93           0 :     int index=cell/(fDimY*fDimZ);
      94           0 :     return index*fStepX;
      95           0 :   }
      96             :   T GetCenterX(int cell) const {
      97           0 :     if (fDimX==0 || fDimY==0 ||fDimZ==0) return (T)0;
      98           0 :     return GetLowerBoundX(cell)+fStepX/2;
      99           0 :   }
     100             :   T GetLowerBoundY(int cell) const {
     101           0 :     if (fDimX==0 || fDimY==0 ||fDimZ==0) return (T)0;
     102           0 :     int index=cell%(fDimY*fDimZ); index/=fDimZ;
     103           0 :     return index*fStepY;
     104           0 :   }
     105             :   T GetCenterY(int cell) const {
     106           0 :     if (fDimX==0 || fDimY==0 ||fDimZ==0) return (T)0;
     107           0 :     return GetLowerBoundY(cell)+fStepY/2;
     108           0 :   }
     109             :   T GetLowerBoundZ(int cell) const {
     110           0 :     if (fDimX==0 || fDimY==0 ||fDimZ==0) return (T)0;
     111           0 :     int index=cell%(fDimY*fDimZ); index%=fDimZ;
     112           0 :     return index*fStepZ;
     113           0 :   }
     114             :   T GetCenterZ(int cell) const {
     115           0 :     if (fDimX==0 || fDimY==0 ||fDimZ==0) return (T)0;
     116           0 :     return GetLowerBoundZ(cell)+fStepZ/2;
     117           0 :   }
     118             :   int GetCellIndex(T x, T y, T z) const {
     119           0 :     return GetXIndex(x)*fDimY*fDimZ + (y<0?0:GetYIndex(y))*fDimZ + (z<0?0:GetZIndex(z));
     120             :   }
     121             :   int GetNumberOfSpacePoints(int index=0, int endIndex=-1) const {
     122           0 :     if (!fCells) return 0;
     123           0 :     if (endIndex<0) endIndex=fCellDimension;
     124             :     int count=0;
     125           0 :     for (int cell=index; cell<endIndex && cell<fCellDimension && count<fCount; cell++) if (fCells[cell].fCount>0) count+=fCells[cell].fCount;
     126             :     return count;
     127           0 :   }
     128             : 
     129             :   // increment counter of the cell where the spacepoint is
     130             :   int CountSpacePoint(T x, T y, T z) {
     131             :     // increment counter of the cell where the spacepoint is
     132           0 :     int cell=GetCellIndex(x, y, z);
     133           0 :     if (cell<0 || !fCells || cell>=fCellDimension) return -EFAULT;
     134           0 :     if (fCells[cell].fCount<0) fCells[cell].fCount=1;
     135           0 :     else fCells[cell].fCount++;
     136           0 :     return 0;
     137           0 :   }
     138             : 
     139             : 
     140             :   // add spacepoint, all spacepoints must have been counted before
     141             :   int AddSpacePoint(ValueType t, T x, T y, T z) {
     142             :     // add spacepoint, all spacepoints must have been counted before
     143           0 :     int cell=GetCellIndex(x, y, z);
     144           0 :     if (cell<0 || !fCells || cell>=fCellDimension) return -EFAULT;
     145           0 :     if (fCells[cell].fFilled==fCells[cell].fCount) return -ENOSPC;
     146           0 :     if (fCells[cell].fStartIndex<0 && IndexCells()<0) return -EACCES;
     147           0 :     int offset=fCells[cell].fStartIndex+fCells[cell].fFilled;
     148           0 :     fData[offset]=t;
     149           0 :     fCells[cell].fFilled++;
     150           0 :     fCount++;
     151             :     return 0;
     152           0 :   }
     153             : 
     154             :   void Clear(const char* /*option*/="") {
     155             :     // clear internal data
     156           0 :     if (fCells) memset(fCells, 0xff, fCellDimension*sizeof(AliHLTIndexGridCell));
     157           0 :     if (fData) memset(fData, 0, fDataDimension*sizeof(V));
     158           0 :     fCount=0;
     159           0 :   }
     160             : 
     161             :   void Print(const char* /*option*/="") {
     162             :   // print info
     163             :   bool bPrintEmpty=false;
     164           0 :   ios::fmtflags coutflags=cout.flags(); // backup cout status flags
     165           0 :   cout << "AliHLTIndexGrid: " << (fCells?fCellDimension:0) << " cells" << endl;
     166           0 :   cout << "   x: " << fDimX << " [0," << fMaxX << "]" << endl;
     167           0 :   cout << "   y: " << fDimY << " [0," << fMaxY << "]" << endl;
     168           0 :   cout << "   z: " << fDimZ << " [0," << fMaxZ << "]" << endl;
     169           0 :   cout << "   " << GetNumberOfSpacePoints(0, fCellDimension) << " point(s)" << endl;
     170           0 :   if (fCells) {
     171           0 :     for (int i=0; i<fCellDimension; i++) {
     172           0 :       if (!bPrintEmpty && fCells[i].fCount<=0) continue;
     173           0 :       cout << "     " << setfill(' ') << setw(7) << fixed << setprecision(0) << i << " (" 
     174           0 :           << " " << setw(3) << GetLowerBoundX(i)
     175           0 :           << " " << setw(3) << GetLowerBoundY(i)
     176           0 :           << " " << setw(4) << GetLowerBoundZ(i)
     177           0 :           << "): ";
     178           0 :       cout << setw(3) << fCells[i].fCount << " entries, " << setw(3) << fCells[i].fFilled << " filled";
     179           0 :       cout << "  start index " << setw(5) << fCells[i].fStartIndex;
     180           0 :       cout << endl;
     181           0 :       if (fCells[i].fCount>0) {
     182           0 :         cout << "          ";
     183           0 :         for (iterator id=begin(GetLowerBoundX(i), GetLowerBoundY(i), GetLowerBoundZ(i));
     184           0 :              id!=end(); id++) {
     185           0 :           cout << " 0x" << hex << setw(8) << setfill('0') << id.Data();
     186             :         }
     187           0 :         cout  << endl;
     188           0 :       }
     189             :     }
     190           0 :   }
     191           0 :   cout.flags(coutflags); // restore the original flags
     192           0 : }
     193             : 
     194             : 
     195             :   class iterator {
     196             :   public:
     197             :   iterator()
     198           0 :     : fData(NULL) {}
     199             :   iterator(ValueType* pData)
     200           0 :     : fData(pData) {}
     201             :   iterator(const iterator& i)
     202           0 :     : fData(i.fData) {}
     203             :     iterator& operator=(const iterator& i)
     204           0 :       { if (this!=&i) {fData=i.fData;} return *this;}
     205           0 :     ~iterator() {fData=NULL;}
     206             : 
     207             :     bool operator==(const iterator& i) const  {return (fData!=NULL) && (fData==i.fData);}
     208           0 :     bool operator!=(const iterator& i) const  {return (fData!=NULL) && (fData!=i.fData);}
     209             :     // prefix operators
     210             :     iterator& operator++() {fData++; return *this;}
     211             :     iterator& operator--() {fData--; return *this;}
     212             :     // postfix operators
     213           0 :     iterator operator++(int) {iterator i(*this); fData++; return i;}
     214             :     iterator operator--(int) {iterator i(*this); fData--; return i;}
     215             : 
     216           0 :     iterator& operator+=(int step) {fData+=step; return *this;}
     217             : 
     218             :     const ValueType& Data() const {return *fData;}
     219           0 :     ValueType& Data() {return *fData;}
     220             : 
     221             :     ValueType operator*() {return *fData;}
     222             : 
     223             :   protected:
     224             :   private:
     225             :     ValueType* fData; //! data
     226             :   };
     227             : 
     228             :   // prepare iterator and end marker
     229             :   iterator& begin(T x=(T)-1, T y=(T)-1, T z=(T)-1) {
     230           0 :     fIterator.~iterator();
     231           0 :     fIteratorEnd.~iterator();
     232             : 
     233             :     int startIndex=0;
     234           0 :     if (x<0) {
     235             :       // get all data
     236           0 :       if (fData) {
     237           0 :         new (&fIterator) iterator(fData);
     238           0 :         fIteratorEnd=fIterator;
     239           0 :         fIteratorEnd+=fCount;
     240           0 :       }
     241           0 :       return fIterator;
     242             :     }
     243             : 
     244             :     // only search for the start index if specific x selected
     245           0 :     int cell=GetCellIndex(x, y, z);
     246           0 :     if (cell<0 || !fCells || cell>=fCellDimension) return fIterator;
     247             :     // get the index of the cell
     248           0 :     startIndex=fCells[cell].fStartIndex;
     249           0 :     if (!fData || startIndex>=fDataDimension) return fIterator;
     250             : 
     251             :     // get the range end position
     252           0 :     int endCell=cell+1;
     253           0 :     if (x<0) endCell=fCellDimension;
     254           0 :     else if (y<0) endCell=GetCellIndex(x+fStepX, (T)-1, (T)-1); // all entries for fixed x
     255           0 :     else if (z<0) endCell=GetCellIndex(x, y+fStepY, (T)-1); // all entries for fixed x and y
     256           0 :     if (endCell<=cell) {
     257             :       // cell index returned is never outside the array
     258             :       // so this is a special case where we get to the bounds of the array
     259           0 :       endCell=fCellDimension;
     260           0 :     }
     261             : 
     262             :     // find the first cell with content in the range 
     263           0 :     for (; startIndex<0 && cell<endCell;) {
     264           0 :       startIndex=fCells[++cell].fStartIndex;
     265             :     }
     266           0 :     if (startIndex<0) return fIterator;
     267             : 
     268           0 :     new (&fIterator) iterator(fData+startIndex);
     269           0 :     fIteratorEnd=fIterator;
     270           0 :     fIteratorEnd+=GetNumberOfSpacePoints(cell, endCell);
     271           0 :     return fIterator;
     272           0 :   }
     273             : 
     274             :   // get loop end marker
     275             :   iterator& end() {
     276           0 :     return fIteratorEnd;
     277             :   }
     278             : 
     279             :   iterator& find(ValueType v) {
     280           0 :     for (iterator i=begin(); i!=end(); i++) {
     281           0 :       if (i.Data()==v) {
     282           0 :         fIterator=i;
     283           0 :         return fIterator;
     284             :       }
     285             :     }
     286           0 :     return end();
     287           0 :   }
     288             : 
     289             :   // find cell of entry
     290             :   int FindCell(ValueType v) const {
     291           0 :     if (!fCells) return -1;
     292           0 :     for (int cell=0; cell<fCellDimension; cell++)
     293           0 :       for (int count=0; count<fCells[cell].fCount; count++)
     294           0 :         if (fData[fCells[cell].fStartIndex+count]==v)
     295           0 :           return cell;
     296           0 :     return -1;
     297           0 :   }
     298             : 
     299             :   struct AliHLTIndexGridCell {
     300             :     int fCount;
     301             :     int fFilled;
     302             :     int fStartIndex;
     303             :   };
     304             : 
     305             :  protected:
     306             :  private:
     307             :   // standard constructor prohibited
     308             :   AliHLTIndexGrid();
     309             :   // copy constructor prohibited
     310             :   AliHLTIndexGrid(const AliHLTIndexGrid&);
     311             :   // assignment operator prohibited
     312             :   AliHLTIndexGrid& operator=(const AliHLTIndexGrid&);
     313             : 
     314             :   int IndexCells() {
     315             :     // set the start index for data of every cell based on the counts
     316           0 :     if (!fCells || fCellDimension<=0) return -ENOBUFS;
     317             :     int offset=0;
     318             :     int cell=0;
     319           0 :     for (; cell<fCellDimension; cell++) {
     320           0 :       if (fCells[cell].fCount<0) continue;
     321           0 :       fCells[cell].fStartIndex=offset;
     322           0 :       offset+=fCells[cell].fCount;
     323           0 :       fCells[cell].fFilled=0;
     324           0 :     }
     325             : 
     326           0 :     if (offset>fDataDimension) {
     327             :       // grow the data array
     328           0 :       auto_ptr<V> newArray(new V[offset]);
     329           0 :       if (newArray.get()) {
     330           0 :         memcpy(newArray.get(), fData, fDataDimension);
     331           0 :         memset(newArray.get()+fDataDimension, 0, (offset-fDataDimension)*sizeof(V));
     332           0 :         delete fData;
     333           0 :         fData=newArray.release();
     334           0 :         fDataDimension=offset;
     335           0 :       } else {
     336           0 :         for (cell=0; cell<fCellDimension; cell++) {
     337           0 :           fCells[cell].fStartIndex=-1;
     338             :         }
     339             :       }
     340           0 :     }
     341             :     return 0;
     342           0 :   }
     343             : 
     344             : 
     345             :   T fMaxX;
     346             :   T fStepX;
     347             :   T fMaxY;
     348             :   T fStepY;
     349             :   T fMaxZ;
     350             :   T fStepZ;
     351             : 
     352             :   int fDimX;
     353             :   int fDimY;
     354             :   int fDimZ;
     355             : 
     356             :   AliHLTIndexGridCell* fCells; //! cell array
     357             :   int fCellDimension; //! size of cell array
     358             :   ValueType* fData; //! spacepoint data
     359             :   int fDataDimension; //! size of spacepoint data
     360             :   int fCount;
     361             : 
     362             :   iterator fIterator; //! iterator
     363             :   iterator fIteratorEnd; //! end marker iterator
     364             : 
     365             :   static const int fgkDefaultDataSize=10000; //! the default data size
     366             : 
     367         378 :   ClassDef(AliHLTIndexGrid, 0)
     368             : };
     369             : 
     370             : #endif

Generated by: LCOV version 1.11