5 #ifndef BALL_DATATYPE_REGULARDATA3D_H
6 #define BALL_DATATYPE_REGULARDATA3D_H
8 #ifndef BALL_MATHS_VECTOR3_H
12 #ifndef BALL_SYSTEM_FILE_H
16 #ifndef BALL_SYSTEM_BINARYFILEADAPTOR_H
20 #ifndef BALL_MATHS_COMMON_H
44 template <
typename ValueType>
76 typedef typename std::vector<ValueType>::iterator
Iterator;
84 typedef typename std::vector<ValueType>::iterator
iterator;
86 typedef typename std::vector<ValueType>::reference
reference;
88 typedef typename std::vector<ValueType>::pointer
pointer;
90 typedef typename std::vector<ValueType>::size_type
size_type;
121 (
const IndexType&
size,
132 virtual void clear();
196 const vector<ValueType>&
getData()
const;
202 const ValueType&
getData(
const IndexType& index)
const;
208 ValueType&
getData(
const IndexType& index);
364 void resize(
const IndexType& size);
378 void rescale(
const IndexType& new_size);
418 ValueType& llf, ValueType& rlf, ValueType& luf, ValueType& ruf,
419 ValueType& llb, ValueType& rlb, ValueType& lub, ValueType& rub)
const;
518 template <
class ValueType>
530 template <
class ValueType>
546 catch (std::bad_alloc&)
553 template <
class ValueType>
560 dimension_(dimension),
574 data_.resize(number_of_points);
576 catch (std::bad_alloc&)
579 throw Exception::OutOfMemory(__FILE__, __LINE__, number_of_points *
sizeof(ValueType));
584 template <
class ValueType>
586 (
const typename TRegularData3D<ValueType>::CoordinateType& origin,
587 const typename TRegularData3D<ValueType>::CoordinateType& dimension,
588 const typename TRegularData3D<ValueType>::CoordinateType& spacing)
591 dimension_(dimension),
607 catch (std::bad_alloc&)
610 throw Exception::OutOfMemory(__FILE__, __LINE__, size *
sizeof(ValueType));
619 template <
class ValueType>
621 (
const typename TRegularData3D<ValueType>::CoordinateType& origin,
622 const typename TRegularData3D<ValueType>::CoordinateType& x_axis,
623 const typename TRegularData3D<ValueType>::CoordinateType& y_axis,
624 const typename TRegularData3D<ValueType>::CoordinateType& z_axis,
625 const typename TRegularData3D<ValueType>::IndexType& new_size)
628 dimension_(x_axis+y_axis+z_axis),
631 is_orthogonal_(false)
634 spacing_.
x = x_axis.getLength() / (new_size.x - 1.);
635 spacing_.
y = y_axis.getLength() / (new_size.y - 1.);
636 spacing_.
z = z_axis.getLength() / (new_size.z - 1.);
643 catch (std::bad_alloc&)
646 throw Exception::OutOfMemory(__FILE__, __LINE__, size *
sizeof(ValueType));
665 double determinant = 1. / (a*(e*i - f*
h) - b*(d*i - f*g) + c*(d*h - e*g));
669 inverse_mapping_[2] = determinant * (b*f - c*e);
671 inverse_mapping_[3] = determinant * (f*g - d*i);
672 inverse_mapping_[4] = determinant * (a*i - c*g);
673 inverse_mapping_[5] = determinant * (c*d - a*f);
675 inverse_mapping_[6] = determinant * (d*h - e*g);
676 inverse_mapping_[7] = determinant * (b*g - a*
h);
677 inverse_mapping_[8] = determinant * (a*e - b*d);
680 template <
class ValueType>
685 template <
typename ValueType>
696 dimension_ = rhs.dimension_;
697 spacing_ = rhs.spacing_;
700 is_orthogonal_ = rhs.is_orthogonal_;
701 mapping_ = rhs.mapping_;
702 inverse_mapping_ = rhs.inverse_mapping_;
708 catch (std::bad_alloc&)
718 template <
typename ValueType>
724 if ((size.
x == size_.x) && (size_.y == size.
y) && (size_.z == size.
z))
730 if ((size.
x == 0) || (size.
y == 0) || (size.
z == 0))
733 dimension_.set(0.0, 0.0, 0.0);
743 std::vector<ValueType> old_data(data_);
746 data_.resize(new_size);
749 static ValueType default_value = (ValueType)0;
755 if ((x >= size_.x) || (y >= size_.y) || (z >= size_.z))
757 data_[i] = default_value;
761 data_[i] = old_data[x + y * size_.x + z * size_.x * size_.y];
766 if ((size_.x != 0) && (size_.y != 0) && (size_.z != 0))
768 dimension_.x *= (
double)size.
x / (
double)size_.x;
769 dimension_.y *= (
double)size.
y / (
double)size_.y;
770 dimension_.z *= (
double)size.
z / (
double)size_.z;
774 catch (std::bad_alloc&)
781 template <
typename ValueType>
787 if ((size.
x == size_.x) && (size_.y == size.
y) && (size_.z == size.
z))
793 if ((size.
x == 0) || (size.
y == 0) || (size.
z == 0))
810 data_.resize(new_size);
811 spacing_.x = dimension_.x / (
double)(size.
x - 1);
812 spacing_.y = dimension_.y / (
double)(size.
y - 1);
813 spacing_.z = dimension_.z / (
double)(size.
z - 1);
819 for (
size_type i = 0; i < data_.size(); i++)
831 catch (std::bad_alloc&)
838 template <
class ValueType>
844 return !((r.
x > (origin_.x + dimension_.x ))
845 || (r.
y > (origin_.y + dimension_.y))
846 || (r.
z > (origin_.z + dimension_.z))
847 || (r.
x < origin_.x) || (r.
y < origin_.y) || (r.
z < origin_.z));
857 return !( (ri.
x < 0) || (ri.
y < 0) || (ri.
z < 0)
858 || (ri.
x >= size_.x) || (ri.
y >= size_.y) || (ri.
z >= size_.z) );
862 template <
class ValueType>
867 size_type pos = index.
x + index.
y * size_.x + index.
z * size_.x * size_.y;
868 if (pos >= data_.size())
875 template <
class ValueType>
882 template <
typename ValueType>
887 size_type pos = index.
x + index.
y * size_.x + index.
z * size_.x * size_.y;
888 if (pos >= data_.size())
895 template <
class ValueType>
899 if (index >= data_.size())
906 template <
class ValueType>
910 if (index >= data_.size())
917 template <
class ValueType>
922 if ((index.
x >= size_.x) || (index.
y >= size_.y) || (index.
z >= size_.z))
929 CoordinateType r(origin_.x + index.
x * spacing_.x,
930 origin_.y + index.
y * spacing_.y,
931 origin_.z + index.
z * spacing_.z);
936 CoordinateType r(index.
x, index.
y, index.
z);
937 r = mapToCartesian_(r);
943 template <
class ValueType>
945 typename TRegularData3D<ValueType>::CoordinateType
948 if (position >= data_.size())
960 origin_.y + (
double)y * spacing_.y,
961 origin_.z + (
double)z * spacing_.z);
966 r = mapToCartesian_(r);
972 template <
typename ValueType>
989 position.
x = (
Position)((r.
x - origin_.x) / spacing_.x);
990 position.
y = (
Position)((r.
y - origin_.y) / spacing_.y);
991 position.
z = (
Position)((r.
z - origin_.z) / spacing_.z);
1003 llf = position.
x + size_.x * position.
y
1004 + size_.x * size_.y * position.
z;
1006 luf = llf + size_.x;
1008 llb = llf + size_.x * size_.y;
1010 lub = llb + size_.x;
1014 template <
typename ValueType>
1018 ValueType& llf, ValueType& rlf, ValueType& luf, ValueType& ruf,
1019 ValueType& llb, ValueType& rlb, ValueType& lub, ValueType& rub)
const
1027 Position llf_idx, rlf_idx, luf_idx, ruf_idx, llb_idx, rlb_idx, lub_idx, rub_idx;
1028 getEnclosingIndices(r, llf_idx, rlf_idx, luf_idx, ruf_idx, llb_idx, rlb_idx, lub_idx, rub_idx);
1031 llf = data_[llf_idx];
1032 rlf = data_[rlf_idx];
1033 luf = data_[luf_idx];
1034 ruf = data_[ruf_idx];
1035 llb = data_[llb_idx];
1036 rlb = data_[rlb_idx];
1037 lub = data_[lub_idx];
1038 rub = data_[rub_idx];
1041 template <
typename ValueType>
1050 return operator () (r);
1053 template <
typename ValueType>
1071 while (x >= (size_.x - 1)) x--;
1072 while (y >= (size_.y - 1)) y--;
1073 while (z >= (size_.z - 1)) z--;
1075 r_0.
x = origin_.x + x*spacing_.x;
1076 r_0.
y = origin_.y + y*spacing_.y;
1077 r_0.
z = origin_.z + z*spacing_.z;
1086 while (x >= (size_.x - 1)) x--;
1087 while (y >= (size_.y - 1)) y--;
1088 while (z >= (size_.z - 1)) z--;
1092 lower_pos = mapToCartesian_(lower_pos);
1093 r_0.
x = lower_pos.
x;
1094 r_0.
y = lower_pos.
y;
1095 r_0.
z = lower_pos.
z;
1102 double dx = 1. - ((
double)(r.
x - r_0.
x) / spacing_.x);
1103 double dy = 1. - ((
double)(r.
y - r_0.
y) / spacing_.y);
1104 double dz = 1. - ((
double)(r.
z - r_0.
z) / spacing_.z);
1106 return data_[l] * dx * dy * dz
1107 + data_[l + 1] * (1. - dx) * dy * dz
1108 + data_[l + Nx] * dx * (1. - dy) * dz
1109 + data_[l + Nx + 1] * (1. - dx) * (1. - dy) * dz
1110 + data_[l + Nxy] * dx * dy * (1. - dz)
1111 + data_[l + Nxy + 1] * (1. - dx) * dy * (1. - dz)
1112 + data_[l + Nxy + Nx] * dx * (1. - dy) * (1. - dz)
1113 + data_[l + Nxy + Nx + 1] * (1. - dx) * (1. - dy) * (1. - dz);
1116 template <
typename ValueType>
1130 position.
x = (
Position)((r.
x - origin_.x) / spacing_.x + 0.5);
1131 position.
y = (
Position)((r.
y - origin_.y) / spacing_.y + 0.5);
1132 position.
z = (
Position)((r.
z - origin_.z) / spacing_.z + 0.5);
1145 template <
typename ValueType>
1158 position.
x = (
Position)((r.
x - origin_.x) / spacing_.x);
1159 position.
y = (
Position)((r.
y - origin_.y) / spacing_.y);
1160 position.
z = (
Position)((r.
z - origin_.z) / spacing_.z);
1173 template <
typename ValueType>
1183 static IndexType position;
1187 position.x = (
Position)((r.
x - origin_.x) / spacing_.x + 0.5);
1188 position.y = (
Position)((r.
y - origin_.y) / spacing_.y + 0.5);
1189 position.z = (
Position)((r.
z - origin_.z) / spacing_.z + 0.5);
1193 static Vector3 pos = mapInverse_(r);
1199 return operator [] (position);
1202 template <
typename ValueType>
1205 (
const typename TRegularData3D<ValueType>::CoordinateType& r)
1209 throw Exception::OutOfGrid(__FILE__, __LINE__);
1212 static IndexType position;
1216 position.x = (
Position)((r.x - origin_.x) / spacing_.x + 0.5);
1217 position.y = (
Position)((r.y - origin_.y) / spacing_.y + 0.5);
1218 position.z = (
Position)((r.z - origin_.z) / spacing_.z + 0.5);
1222 static Vector3 pos = mapInverse_(r);
1229 return operator [] (position);
1232 template <
typename ValueType>
1236 Position data_points = (size_.x * size_.y * size_.z);
1238 for (
Position i = 0; i < data_points; i++)
1242 mean /= data_points;
1246 template <
typename ValueType>
1250 Position data_points = (size_.x * size_.y * size_.z);
1251 ValueType stddev = 0;
1252 ValueType mean = this->calculateMean();
1253 for (
Position i = 0; i < data_points; i++)
1255 stddev += (pow(data_[i]-mean,2));
1257 stddev /= (data_points-1);
1258 stddev = sqrt(stddev);
1262 template <
typename ValueType>
1268 dimension_.set(0.0);
1273 is_orthogonal_ =
true;
1277 template <
typename ValueType>
1280 return ((origin_ == grid.
origin_)
1282 && (size_.x == grid.
size_.x)
1283 && (size_.y == grid.
size_.y)
1284 && (size_.z == grid.
size_.z)
1285 && (data_ == grid.
data_)
1289 template <
typename ValueType>
1292 File outfile(filename, std::ios::out|std::ios::binary);
1304 adapt_size.
setData(data_.size());
1305 outfile << adapt_size;
1307 adapt_coordinate.
setData(origin_);
1308 outfile << adapt_coordinate;
1310 adapt_coordinate.
setData(dimension_);
1311 outfile << adapt_coordinate;
1313 adapt_coordinate.setData(spacing_);
1314 outfile << adapt_coordinate;
1318 outfile << adapt_index;
1321 Index window_pos = 0;
1323 while ( ((
int)data_.size() - (1024 + window_pos)) >= 0 )
1326 outfile << adapt_block;
1331 for (
Size i=window_pos; i<data_.size(); i++)
1333 adapt_single.
setData(data_[i]);
1334 outfile << adapt_single;
1341 template <
typename ValueType>
1344 File infile(filename, std::ios::in|std::ios::binary);
1356 infile >> adapt_size;
1357 Size new_size = adapt_size.getData();
1359 infile >> adapt_coordinate;
1360 origin_ = adapt_coordinate.
getData();
1362 infile >> adapt_coordinate;
1363 dimension_ = adapt_coordinate.getData();
1365 infile >> adapt_coordinate;
1366 spacing_ = adapt_coordinate.getData();
1369 infile >> adapt_index;
1370 size_ = adapt_index.
getData();
1372 data_.resize(new_size);
1375 Index window_pos = 0;
1377 while ( ((
int)data_.size() - (1024 + window_pos)) >= 0 )
1379 infile >> adapt_block;
1391 for (
Size i=window_pos; i<data_.size(); i++)
1393 infile >> adapt_single;
1394 data_[i] = adapt_single.
getData();
1403 template <
typename ValueType>
1405 std::ostream& operator << (std::ostream& os, const TRegularData3D<ValueType>& grid)
1408 os << grid.getOrigin().x <<
" " << grid.getOrigin().y <<
" " << grid.getOrigin().z
1410 << grid.getOrigin().x + grid.getDimension().x <<
" "
1411 << grid.getOrigin().y + grid.getDimension().y <<
" "
1412 << grid.getOrigin().z + grid.getDimension().z
1414 << grid.getSize().x - 1 <<
" " << grid.getSize().y - 1 <<
" " << grid.getSize().z - 1
1418 std::copy(grid.begin(), grid.end(), std::ostream_iterator<ValueType>(os,
"\n"));
1424 template <
typename ValueType>
1431 is >> origin.
x >> origin.
y >> origin.
z;
1432 is >> dimension.
x >> dimension.
y >> dimension.
z;
1433 is >> size.
x >> size.
y >> size.
z;
1435 dimension -= origin;
1443 std::copy(std::istream_iterator<ValueType>(is), std::istream_iterator<ValueType>(), grid.
begin());
1451 #endif // BALL_DATATYPE_REGULARDATA3D_H
BALL_INLINE size_type max_size() const
const ValueType & operator[](const IndexType &index) const
TRegularData3D & operator=(const TRegularData3D< ValueType > &data)
BALL_INLINE Iterator end()
void rescale(const IndexType &new_size)
void getEnclosingIndices(const CoordinateType &r, Position &llf, Position &rlf, Position &luf, Position &ruf, Position &llb, Position &rlb, Position &lub, Position &rub) const
#define BALL_CREATE(name)
const IndexType & getSize() const
BALL_INLINE void swap(TRegularData3D< ValueType > &grid)
std::vector< ValueType > VectorType
The type containing an STL vector of the appropriate type.
BALL_INLINE ConstIterator end() const
std::vector< ValueType >::const_reference const_reference
IndexType getClosestIndex(const CoordinateType &v) const
std::vector< ValueType >::const_iterator ConstIterator
A nonmutable iterator.
void setOrigin(const CoordinateType &origin)
std::istream & operator>>(std::istream &is, TRegularData1D< ValueType > &grid)
Input operator.
void getEnclosingValues(const CoordinateType &r, ValueType &llf, ValueType &rlf, ValueType &luf, ValueType &ruf, ValueType &llb, ValueType &rlb, ValueType &lub, ValueType &rub) const
std::vector< double > mapping_
mapping matrix and its inverse
IndexType(Position p, Position q, Position r)
CoordinateType dimension_
Dimension of the grid.
VectorType data_
The grid data.
ValueType getInterpolatedValue(const CoordinateType &x) const
std::vector< ValueType >::pointer pointer
void binaryWriteRaw(const String &filename) const
std::vector< ValueType >::iterator Iterator
A mutable iterator.
CoordinateType getCoordinates(const IndexType &index) const
BALL_EXTERN_VARIABLE const double h
TVector3< float > CoordinateType
The coordinate type.
BALL_INLINE ConstIterator begin() const
ValueType operator()(const CoordinateType &x) const
BALL_EXTERN_VARIABLE const double c
const CoordinateType mapToCartesian_(CoordinateType r) const
map indices to Cartesian coordinates
ValueType calculateSD() const
IndexType size_
The dimensions in grid points.
const ValueType & getClosestValue(const CoordinateType &x) const
TRegularData3D< float > RegularData3D
const CoordinateType & getDimension() const
BALL_INLINE Iterator begin()
TVector3< float > Vector3
void setData(const T &data)
void binaryWrite(const String &filename) const
BALL_INLINE size_type size() const
std::vector< ValueType >::const_iterator const_iterator
std::vector< ValueType >::difference_type difference_type
virtual ~TRegularData3D()
void binaryRead(const String &filename)
const vector< ValueType > & getData() const
Get the full data.
const CoordinateType mapInverse_(CoordinateType r) const
map Cartesian coordinates to indices (note: this does not yet convert the double values to Index) ...
BALL_INLINE bool empty() const
Empty predicate.
ValueType calculateMean() const
CoordinateType origin_
Origin of the grid (offset)
std::vector< double > inverse_mapping_
const T & getData() const
const CoordinateType & getOrigin() const
The block data type for reading and writing binary data.
BALL_INLINE bool operator!=(const TRegularData3D< ValueType > &grid) const
void setDimension(const CoordinateType &dimension)
BALL_INLINE bool isOrthogonal() const
State whether grid is orthogonal or not.
The index type used to refer to a specific element in the grid (x-, y-, and z-index) ...
const CoordinateType & getSpacing() const
void resize(const IndexType &size)
bool is_orthogonal_
A flag deciding whether the grid is orthogonal or not.
bool operator==(const TRegularData3D< ValueType > &grid) const
std::vector< ValueType >::size_type size_type
std::vector< ValueType >::iterator iterator
std::vector< ValueType >::reference reference
CoordinateType spacing_
Grid spacing.
IndexType getLowerIndex(const CoordinateType &v) const
bool isInside(const CoordinateType &r) const
Test if a given point is inside the grid.