ISIS Core Library 0.7.2 (api 3.0.0)
|
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