ISIS Core Library 0.7.2 (api 3.0.0)

/scr/tee1/isis/lib/Core/DataStorage/ndimensional.hpp

Go to the documentation of this file.
00001 //
00002 // C++ Interface: ndimensional
00003 //
00004 // Description:
00005 //
00006 //
00007 // Author: Enrico Reimer<reimer@cbs.mpg.de>, (C) 2009
00008 //
00009 // Copyright: See COPYING file that comes with this distribution
00010 //
00011 //
00012 
00013 #ifndef NDIMENSIONAL_H
00014 #define NDIMENSIONAL_H
00015 
00016 #define __need_size_t
00017 #include <stddef.h>
00018 #include <algorithm>
00019 #include <boost/static_assert.hpp>
00020 #include <string>
00021 #include "common.hpp"
00022 #include "../CoreUtils/vector.hpp"
00023 
00024 namespace isis
00025 {
00026 namespace data
00027 {
00028 namespace _internal
00029 {
00031 
00032 template<unsigned short DIM> size_t __dimStride( const size_t dim[] )
00033 {
00034     return __dimStride < DIM - 1 > ( dim ) * dim[DIM - 1];
00035 }
00036 
00037 template<unsigned short DIM> size_t __dim2index( const size_t d[], const size_t dim[] )
00038 {
00039     return d[DIM] * __dimStride<DIM>( dim ) + __dim2index < DIM - 1 > ( d, dim );
00040 }
00041 
00042 template<unsigned short DIM> void __index2dim( const size_t index, size_t d[], const size_t dim[], size_t vol )
00043 {
00044     d[DIM] = index / vol;
00045     __index2dim < DIM - 1 > ( index % vol, d, dim, vol / dim[DIM - 1] );
00046 }
00047 
00048 template<unsigned short DIM> bool __rangeCheck( const size_t d[], const size_t dim[] )
00049 {
00050     return ( d[DIM] < dim[DIM] ) && __rangeCheck < DIM - 1 > ( d, dim );
00051 }
00052 
00053 template<> inline size_t __dimStride<0>( const size_t[] /*dim*/ ) {return 1;}
00054 template<> inline size_t __dim2index<0>( const size_t d[], const size_t dim[] ) {return d[0] * __dimStride<0>( dim );}
00055 template<> inline void __index2dim<0>( const size_t index, size_t d[], const size_t[], size_t /*vol*/ ) {d[0] = index;}
00056 template<> inline bool   __rangeCheck<0>( const size_t d[], const size_t dim[] ) {return d[0] < dim[0];}
00057 
00059 
00061 template<unsigned short DIMS> class NDimensional
00062 {
00063     size_t m_dim[DIMS];
00064 protected:
00065     NDimensional() {}
00066 public:
00067     static const size_t dims = DIMS;
00073     void init( const size_t d[DIMS] ) {
00074         std::copy( d, d + DIMS, m_dim );
00075         LOG_IF( getVolume() == 0, Runtime, error ) << "Creating object with volume of 0";
00076     }
00077     void init( const util::FixedVector<size_t, DIMS>& d ) {
00078         d.copyTo( m_dim );
00079         LOG_IF( getVolume() == 0, Runtime, error ) << "Creating object with volume of 0";
00080     }
00081     NDimensional( const NDimensional &src ) {//@todo default copier should do the job
00082         init( src.m_dim );
00083     }
00088     size_t getLinearIndex( const size_t d[DIMS] )const {
00089         return __dim2index < DIMS - 1 > ( d, m_dim );
00090     }
00092     size_t getLinearIndex( const util::FixedVector<size_t, DIMS> &d )const {
00093         return __dim2index < DIMS - 1 > ( &d[0], m_dim );
00094     }
00100     void getCoordsFromLinIndex( const size_t index, size_t d[DIMS] )const {
00101         __index2dim < DIMS - 1 > ( index, d, m_dim, getVolume() / m_dim[DIMS - 1] );
00102     }
00108     bool isInRange( const size_t d[DIMS] )const {
00109         return __rangeCheck < DIMS - 1 > ( d, m_dim );
00110     }
00115     size_t getVolume()const {
00116         return __dimStride<DIMS>( m_dim );
00117     }
00119     size_t getDimSize( size_t idx )const {
00120         return m_dim[idx];
00121     }
00122 
00124     std::string getSizeAsString( std::string delim = "x" )const {
00125         return util::listToString( m_dim, m_dim + DIMS, delim, "", "" );
00126     }
00127 
00129     util::FixedVector<size_t, DIMS> getSizeAsVector()const {
00130         return util::FixedVector<size_t, DIMS>( m_dim );
00131     }
00132 
00137     size_t getRelevantDims()const {
00138         size_t ret = 0;
00139 
00140         for ( unsigned short i = DIMS; i; i-- ) {
00141             if ( m_dim[i - 1] > 1 ) {
00142                 ret = i;
00143                 break;
00144             }
00145         }
00146 
00147         return ret;
00148     }
00149     util::FixedVector<float, DIMS> getFoV( const util::FixedVector<float, DIMS> &voxelSize, const util::FixedVector<float, DIMS> &voxelGap )const {
00150         LOG_IF( getVolume() == 0, DataLog, warning ) << "Calculating FoV of empty data";
00151         const util::FixedVector<size_t, DIMS> voxels = getSizeAsVector();
00152         const util::FixedVector<float, DIMS> gapSize = voxelGap * ( voxels - 1 );
00153         return voxelSize * voxels + gapSize;
00154     }
00155 };
00156 
00157 }
00158 }
00159 }
00160 
00161 #endif // NDIMENSIONAL_H