00001
00002
00003
00004
00005
00006
00007 #ifndef BALL_DATATYPE_REGULARDATA2D_H
00008 #define BALL_DATATYPE_REGULARDATA2D_H
00009
00010 #ifndef BALL_MATHS_VECTOR2_H
00011 # include <BALL/MATHS/vector2.h>
00012 #endif
00013
00014 #ifndef BALL_SYSTEM_FILE_H
00015 # include <BALL/SYSTEM/file.h>
00016 #endif
00017
00018 #include <iostream>
00019 #include <fstream>
00020 #include <iterator>
00021 #include <algorithm>
00022
00023 namespace BALL
00024 {
00034 template <typename ValueType>
00035 class TRegularData2D
00036 {
00037 public:
00038
00039 BALL_CREATE(TRegularData2D<ValueType>)
00040
00041
00044
00046 class IndexType
00047 {
00048 public:
00049 inline IndexType() : x(0), y(0) {}
00050 inline IndexType(Position p) : x(p), y(p) {}
00051 inline IndexType(Position p, Position q) : x(p), y(q) {}
00052
00054 Position x;
00056 Position y;
00057
00058 };
00059
00061 typedef std::vector<ValueType> VectorType;
00063 typedef TVector2<float> CoordinateType;
00065 typedef typename std::vector<ValueType>::iterator Iterator;
00067 typedef typename std::vector<ValueType>::const_iterator ConstIterator;
00069
00070
00071
00072 typedef ValueType value_type;
00073 typedef typename std::vector<ValueType>::iterator iterator;
00074 typedef typename std::vector<ValueType>::const_iterator const_iterator;
00075 typedef typename std::vector<ValueType>::reference reference;
00076 typedef typename std::vector<ValueType>::const_reference const_reference;
00077 typedef typename std::vector<ValueType>::pointer pointer;
00078 typedef typename std::vector<ValueType>::difference_type difference_type;
00079 typedef typename std::vector<ValueType>::size_type size_type;
00080
00084
00088 TRegularData2D();
00089
00091 TRegularData2D(const TRegularData2D<ValueType>& data)
00092 throw(Exception::OutOfMemory);
00093
00100 TRegularData2D(const CoordinateType& origin, const CoordinateType& dimension, const CoordinateType& spacing)
00101 throw(Exception::OutOfMemory);
00102
00103
00104
00105
00106
00107
00108 TRegularData2D(const IndexType& size,
00109 const CoordinateType& origin = CoordinateType(0.0),
00110 const CoordinateType& dimension = CoordinateType(1.0))
00111 throw(Exception::OutOfMemory);
00112
00115 virtual ~TRegularData2D();
00116
00120 virtual void clear();
00122
00126
00130 TRegularData2D& operator = (const TRegularData2D<ValueType>& data)
00131 throw(Exception::OutOfMemory);
00133
00134
00138
00143 bool operator == (const TRegularData2D<ValueType>& data) const;
00144
00146 BALL_INLINE bool operator != (const TRegularData2D<ValueType>& data) const { return !this->operator == (data); }
00147
00149 BALL_INLINE bool empty() const { return data_.empty(); }
00150
00152 bool isInside(const CoordinateType& x) const;
00154
00158
00159 BALL_INLINE ConstIterator begin() const { return data_.begin(); }
00161 BALL_INLINE ConstIterator end() const { return data_.end(); }
00163 BALL_INLINE Iterator begin() { return data_.begin(); }
00165 BALL_INLINE Iterator end() { return data_.end(); }
00167
00171
00172 BALL_INLINE size_type size() const { return data_.size(); }
00173 BALL_INLINE size_type max_size() const { return data_.max_size(); }
00174 BALL_INLINE void swap(TRegularData2D<ValueType>& data) { std::swap(*this, data); }
00175
00176
00180 const ValueType& getData(const IndexType& index) const
00181 throw(Exception::OutOfGrid);
00182
00186 ValueType& getData(const IndexType& index)
00187 throw(Exception::OutOfGrid);
00188
00192 const ValueType& getData(Position index) const
00193 throw(Exception::OutOfGrid);
00194
00198 ValueType& getData(Position index)
00199 throw(Exception::OutOfGrid);
00200
00205 const ValueType& operator [] (const IndexType& index) const { return data_[index.x + size_.x * index.y]; }
00206
00211 ValueType& operator [] (const IndexType& index) { return data_[index.x + size_.x * index.y]; }
00212
00217 const ValueType& operator [] (Position index) const { return data_[index]; }
00218
00223 ValueType& operator [] (Position index) { return data_[index]; }
00224
00233 ValueType operator () (const CoordinateType& x) const;
00234
00240 ValueType getInterpolatedValue(const CoordinateType& x) const
00241 throw(Exception::OutOfGrid);
00242
00248 const ValueType& getClosestValue(const CoordinateType& x) const
00249 throw(Exception::OutOfGrid);
00250
00256 ValueType& getClosestValue(const CoordinateType& x)
00257 throw(Exception::OutOfGrid);
00258
00262 IndexType getLowerIndex(const CoordinateType& v) const
00263 throw(Exception::OutOfGrid);
00264
00270 IndexType getClosestIndex(const CoordinateType& v) const
00271 throw(Exception::OutOfGrid);
00272
00278 inline const IndexType& getSize() const { return size_; }
00279
00284 inline const CoordinateType& getOrigin() const { return origin_; }
00285
00290 const CoordinateType& getSpacing() const { return spacing_; }
00291
00294 void setOrigin(const CoordinateType& origin);
00295
00301 const CoordinateType& getDimension() const { return dimension_; }
00302
00308 void setDimension(const CoordinateType& dimension) { dimension_ = dimension; }
00309
00321 void resize(const IndexType& new_size)
00322 throw(Exception::OutOfMemory);
00323
00332 void rescale(const IndexType& new_size)
00333 throw(Exception::OutOfMemory);
00334
00339 CoordinateType getCoordinates(const IndexType& index) const
00340 throw(Exception::OutOfGrid);
00341
00346 CoordinateType getCoordinates(Position index) const
00347 throw(Exception::OutOfGrid);
00348
00361 void getEnclosingIndices
00362 (const CoordinateType& r, Position& ll, Position& lr, Position& ul, Position& ur) const
00363 throw(Exception::OutOfGrid);
00364
00368 void getEnclosingValues
00369 (const CoordinateType& r, ValueType& ll, ValueType& lr, ValueType& ul, ValueType& ur) const
00370 throw(Exception::OutOfGrid);
00371
00375 ValueType calculateMean() const;
00376
00380 ValueType calculateSD() const;
00381
00386 void binaryWrite(const String& filename) const
00387 throw(Exception::FileNotFound);
00388
00392 void binaryRead(const String& filename)
00393 throw(Exception::FileNotFound);
00395
00396
00397 protected:
00398
00400 VectorType data_;
00401
00403 CoordinateType origin_;
00404
00406 CoordinateType dimension_;
00407
00409 CoordinateType spacing_;
00410
00412 IndexType size_;
00413
00415 typedef struct { ValueType bt[1024]; } BlockValueType;
00416 };
00417
00420 typedef TRegularData2D<float> RegularData2D;
00421
00422
00423 template <class ValueType>
00424 TRegularData2D<ValueType>::TRegularData2D()
00425 : data_(),
00426 origin_(0.0),
00427 dimension_(0.0),
00428 spacing_(1.0),
00429 size_(0)
00430 {
00431 }
00432
00433
00434 template <class ValueType>
00435 TRegularData2D<ValueType>::TRegularData2D(const TRegularData2D<ValueType>& data)
00436 throw(Exception::OutOfMemory)
00437 : data_(),
00438 origin_(data.origin_),
00439 dimension_(data.dimension_),
00440 spacing_(data.spacing_),
00441 size_(data.size_)
00442 {
00443 try
00444 {
00445 data_ = data.data_;
00446 }
00447 catch (std::bad_alloc&)
00448 {
00449 data_.resize(0);
00450 throw Exception::OutOfMemory(__FILE__, __LINE__, data.data_.size() * sizeof(ValueType));
00451 }
00452 }
00453
00454 template <class ValueType>
00455 TRegularData2D<ValueType>::TRegularData2D
00456 (const typename TRegularData2D<ValueType>::IndexType& size,
00457 const typename TRegularData2D<ValueType>::CoordinateType& origin,
00458 const typename TRegularData2D<ValueType>::CoordinateType& dimension)
00459 throw(Exception::OutOfMemory)
00460 : data_(),
00461 origin_(origin),
00462 dimension_(dimension),
00463 spacing_(0.0, 0.0),
00464 size_(size)
00465 {
00466
00467 spacing_.x = dimension_.x / (double)(size_.x - 1);
00468 spacing_.y = dimension_.y / (double)(size_.y - 1);
00469
00470
00471 size_type number_of_points = size_.x * size_.y;
00472 try
00473 {
00474 data_.resize(number_of_points);
00475 }
00476 catch (std::bad_alloc&)
00477 {
00478 data_.resize(0);
00479 throw Exception::OutOfMemory(__FILE__, __LINE__, number_of_points * sizeof(ValueType));
00480 }
00481 }
00482
00483 template <class ValueType>
00484 TRegularData2D<ValueType>::TRegularData2D
00485 (const typename TRegularData2D<ValueType>::CoordinateType& origin,
00486 const typename TRegularData2D<ValueType>::CoordinateType& dimension,
00487 const typename TRegularData2D<ValueType>::CoordinateType& spacing)
00488 throw(Exception::OutOfMemory)
00489 : data_(),
00490 origin_(origin),
00491 dimension_(dimension),
00492 spacing_(spacing),
00493 size_(0)
00494 {
00495
00496 size_.x = (Size)(dimension_.x / spacing_.x + 0.5) + 1;
00497 size_.y = (Size)(dimension_.y / spacing_.y + 0.5) + 1;
00498
00499
00500 size_type size = size_.x * size_.y;
00501 try
00502 {
00503 data_ .resize(size);
00504 }
00505 catch (std::bad_alloc&)
00506 {
00507 data_.resize(0);
00508 throw Exception::OutOfMemory(__FILE__, __LINE__, size * sizeof(ValueType));
00509 }
00510
00511
00512 spacing_.x = dimension_.x / (double)(size_.x - 1);
00513 spacing_.y = dimension_.y / (double)(size_.y - 1);
00514 }
00515
00516 template <class ValueType>
00517 TRegularData2D<ValueType>::~TRegularData2D()
00518 {
00519 }
00520
00521
00522 template <typename ValueType>
00523 BALL_INLINE
00524 TRegularData2D<ValueType>& TRegularData2D<ValueType>::operator =
00525 (const TRegularData2D<ValueType>& rhs)
00526 throw(Exception::OutOfMemory)
00527 {
00528
00529 if (&rhs != this)
00530 {
00531
00532
00533 origin_ = rhs.origin_;
00534 dimension_ = rhs.dimension_;
00535 spacing_ = rhs.spacing_;
00536 size_ = rhs.size_;
00537
00538
00539 try
00540 {
00541 data_ = rhs.data_;
00542 }
00543 catch (std::bad_alloc&)
00544 {
00545 data_.resize(0);
00546 throw Exception::OutOfMemory(__FILE__, __LINE__, rhs.data_.size() * sizeof(ValueType));
00547 }
00548 }
00549
00550 return *this;
00551 }
00552
00553 template <typename ValueType>
00554 void TRegularData2D<ValueType>::rescale(const typename TRegularData2D<ValueType>::IndexType& size)
00555 throw(Exception::OutOfMemory)
00556 {
00557
00558 if ((size.x == size_.x) && (size_.y == size.y))
00559 {
00560 return;
00561 }
00562
00563
00564 if ((size.x == 0) || (size.y == 0))
00565 {
00566 data_.resize(0);
00567 dimension_.set(0.0);
00568 return;
00569 }
00570
00571
00572 size_type new_size = (size_type)(size.x * size.y);
00573
00574
00575 try
00576 {
00577
00578 TRegularData2D<ValueType> old_data(*this);
00579
00580
00581 data_.resize(new_size);
00582 spacing_.x = dimension_.x / (double)(size.x - 1);
00583 spacing_.y = dimension_.y / (double)(size.y - 1);
00584
00585
00586 CoordinateType v;
00587 for (size_type i = 0; i < new_size; i++)
00588 {
00589 Position x = i % size.x;
00590 Position y = i / size.x;
00591 v.x = origin_.x + x * spacing_.x;
00592 v.y = origin_.y + y * spacing_.y;
00593 data_[i] = old_data(v);
00594 }
00595
00596
00597 size_ = size;
00598 }
00599 catch (std::bad_alloc&)
00600 {
00601 throw Exception::OutOfMemory(__FILE__, __LINE__, new_size * (Size)sizeof(ValueType));
00602 }
00603 }
00604
00605 template <typename ValueType>
00606 void TRegularData2D<ValueType>::resize(const typename TRegularData2D<ValueType>::IndexType& size)
00607 throw(Exception::OutOfMemory)
00608 {
00609
00610 if (size.x == size_.x && size_.y == size.y)
00611 {
00612 return;
00613 }
00614
00615
00616 if ((size.x == 0) || (size.y == 0))
00617 {
00618 data_.resize(0);
00619 dimension_.set(0.0, 0.0);
00620 return;
00621 }
00622
00623
00624 size_type new_size = (size_type)(size.x * size.y);
00625
00626
00627 try
00628 {
00629
00630 std::vector<ValueType> old_data(data_);
00631
00632
00633 data_.resize(new_size);
00634
00635
00636 static ValueType default_value = (ValueType)0;
00637 for (size_type i = 0; i < new_size; i++)
00638 {
00639 size_type x = i % size.x;
00640 size_type y = i / size.x;
00641 if (x >= size_.x || y >= size_.y)
00642 {
00643 data_[i] = default_value;
00644 }
00645 else
00646 {
00647 data_[i] = old_data[x + y * size_.x];
00648 }
00649 }
00650
00651
00652 dimension_.x *= (double)size.x / (double)size_.x;
00653 dimension_.y *= (double)size.y / (double)size_.y;
00654 size_ = size;
00655 }
00656 catch (std::bad_alloc&)
00657 {
00658 throw Exception::OutOfMemory(__FILE__, __LINE__, new_size * (Size)sizeof(ValueType));
00659 }
00660 }
00661
00662 template <class ValueType>
00663 void TRegularData2D<ValueType>::setOrigin(const typename TRegularData2D<ValueType>::CoordinateType& origin)
00664 {
00665 origin_ = origin;
00666 }
00667
00668 template <class ValueType>
00669 BALL_INLINE
00670 bool TRegularData2D<ValueType>::isInside(const typename TRegularData2D<ValueType>::CoordinateType& r) const
00671 {
00672 return ((r.x >= origin_.x) && (r.x <= (origin_.x + dimension_.x))
00673 && (r.y >= origin_.y) && (r.y <= (origin_.y + dimension_.y)));
00674 }
00675
00676 template <class ValueType>
00677 BALL_INLINE
00678 const ValueType& TRegularData2D<ValueType>::getData
00679 (const typename TRegularData2D<ValueType>::IndexType& index) const
00680 throw(Exception::OutOfGrid)
00681 {
00682 size_type pos = index.x + index.y * size_.x;
00683 if (pos >= data_.size())
00684 {
00685 throw Exception::OutOfGrid(__FILE__, __LINE__);
00686 }
00687 return data_[pos];
00688 }
00689
00690 template <class ValueType>
00691 BALL_INLINE
00692 ValueType& TRegularData2D<ValueType>::getData(const typename TRegularData2D<ValueType>::IndexType& index)
00693 throw(Exception::OutOfGrid)
00694 {
00695 size_type pos = index.x + index.y * size_.x;
00696 if (pos >= data_.size())
00697 {
00698 throw Exception::OutOfGrid(__FILE__, __LINE__);
00699 }
00700 return data_[pos];
00701 }
00702
00703 template <class ValueType>
00704 BALL_INLINE
00705 const ValueType& TRegularData2D<ValueType>::getData(Position index) const
00706 throw(Exception::OutOfGrid)
00707 {
00708 if (index >= data_.size())
00709 {
00710 throw Exception::OutOfGrid(__FILE__, __LINE__);
00711 }
00712 return data_[index];
00713 }
00714
00715 template <class ValueType>
00716 BALL_INLINE
00717 ValueType& TRegularData2D<ValueType>::getData(Position index)
00718 throw(Exception::OutOfGrid)
00719 {
00720 if (index >= data_.size())
00721 {
00722 throw Exception::OutOfGrid(__FILE__, __LINE__);
00723 }
00724 return data_[index];
00725 }
00726
00727 template <class ValueType>
00728 BALL_INLINE
00729 typename TRegularData2D<ValueType>::CoordinateType TRegularData2D<ValueType>::getCoordinates
00730 (const typename TRegularData2D<ValueType>::IndexType& index) const
00731 throw(Exception::OutOfGrid)
00732 {
00733 if ((index.x >= size_.x) || (index.y >= size_.y))
00734 {
00735 throw Exception::OutOfGrid(__FILE__, __LINE__);
00736 }
00737
00738 CoordinateType r(origin_.x + index.x * spacing_.x,
00739 origin_.y + index.y * spacing_.y);
00740
00741 return r;
00742 }
00743
00744 template <class ValueType>
00745 BALL_INLINE
00746 typename TRegularData2D<ValueType>::CoordinateType
00747 TRegularData2D<ValueType>::getCoordinates(Position position) const
00748 throw(Exception::OutOfGrid)
00749 {
00750 if (position >= data_.size())
00751 {
00752 throw Exception::OutOfGrid(__FILE__, __LINE__);
00753 }
00754
00755 Position x = (Position)(position % size_.x);
00756 Position y = (Position)(position / size_.x);
00757
00758 return CoordinateType(origin_.x + (double)x * spacing_.x,
00759 origin_.y + (double)y * spacing_.y);
00760 }
00761
00762 template <typename ValueType>
00763 BALL_INLINE
00764 void TRegularData2D<ValueType>::getEnclosingIndices
00765 (const typename TRegularData2D<ValueType>::CoordinateType& r,
00766 Position& ll, Position& lr, Position& ul, Position& ur) const
00767 throw(Exception::OutOfGrid)
00768 {
00769 if (!isInside(r))
00770 {
00771 throw Exception::OutOfGrid(__FILE__, __LINE__);
00772 }
00773
00774
00775
00776 IndexType position;
00777 position.x = (Position)((r.x - origin_.x) / spacing_.x);
00778 position.y = (Position)((r.y - origin_.y) / spacing_.y);
00779
00780
00781 ll = position.x + size_.x * position.y;
00782 lr = ll + 1;
00783 ul = ll + size_.x;
00784 ur = ul + 1;
00785 }
00786
00787 template <typename ValueType>
00788 BALL_INLINE
00789 void TRegularData2D<ValueType>::getEnclosingValues
00790 (const typename TRegularData2D<ValueType>::CoordinateType& r,
00791 ValueType& ll, ValueType& lr, ValueType& ul, ValueType& ur) const
00792 throw(Exception::OutOfGrid)
00793 {
00794 if (!isInside(r))
00795 {
00796 throw Exception::OutOfGrid(__FILE__, __LINE__);
00797 }
00798
00799
00800 Position ll_id, lr_id, ul_id, ur_id;
00801 getEnclosingIndices(r, ll_id, lr_id, ul_id, ur_id);
00802
00803
00804 ll = data_[ll_id];
00805 lr = data_[lr_id];
00806 ul = data_[ul_id];
00807 ur = data_[ur_id];
00808 }
00809
00810 template <typename ValueType>
00811 BALL_INLINE
00812 ValueType TRegularData2D<ValueType>::getInterpolatedValue
00813 (const typename TRegularData2D<ValueType>::CoordinateType& r) const
00814 throw(Exception::OutOfGrid)
00815 {
00816 if (!isInside(r))
00817 {
00818 throw Exception::OutOfGrid(__FILE__, __LINE__);
00819 }
00820
00821 return this->operator () (r);
00822 }
00823
00824 template <typename ValueType>
00825 BALL_INLINE
00826 ValueType TRegularData2D<ValueType>::operator ()
00827 (const typename TRegularData2D<ValueType>::CoordinateType& r) const
00828 {
00829 CoordinateType h(r - origin_);
00830 Position x = (Position)(h.x / spacing_.x);
00831 Position y = (Position)(h.y / spacing_.y);
00832
00833
00834 if (x >= (size_.x - 1))
00835 {
00836 x = size_.x - 2;
00837 }
00838 if (y >= (size_.y - 1))
00839 {
00840 y = size_.y - 2;
00841 }
00842
00843 Size l = x + size_.x * y;
00844 CoordinateType r_0(origin_.x + (double)x * spacing_.x,
00845 origin_.y + (double)y * spacing_.y);
00846
00847 double dx = 1.0 - ((r.x - r_0.x) / spacing_.x);
00848 double dy = 1.0 - ((r.y - r_0.y) / spacing_.y);
00849
00850 return data_[l] * dx * dy
00851 + data_[l + 1] * (1.0 - dx) * dy
00852 + data_[l + size_.x] * dx * (1.0 - dy)
00853 + data_[l + size_.x + 1] * (1.0 - dx) * (1.0 - dy);
00854 }
00855
00856 template <typename ValueType>
00857 BALL_INLINE
00858 typename TRegularData2D<ValueType>::IndexType TRegularData2D<ValueType>::getLowerIndex
00859 (const typename TRegularData2D<ValueType>::CoordinateType& r) const
00860 throw(Exception::OutOfGrid)
00861 {
00862 if (!isInside(r))
00863 {
00864 throw Exception::OutOfGrid(__FILE__, __LINE__);
00865 }
00866
00867 static IndexType position;
00868 position.x = (Position)((r.x - origin_.x) / spacing_.x);
00869 position.y = (Position)((r.y - origin_.y) / spacing_.y);
00870
00871 return position;
00872 }
00873
00874 template <typename ValueType>
00875 BALL_INLINE
00876 typename TRegularData2D<ValueType>::IndexType TRegularData2D<ValueType>::getClosestIndex
00877 (const typename TRegularData2D<ValueType>::CoordinateType& r) const
00878 throw(Exception::OutOfGrid)
00879 {
00880 if (!isInside(r))
00881 {
00882 throw Exception::OutOfGrid(__FILE__, __LINE__);
00883 }
00884
00885 static IndexType position;
00886 position.x = (Position)((r.x - origin_.x) / spacing_.x + 0.5);
00887 position.y = (Position)((r.y - origin_.y) / spacing_.y + 0.5);
00888
00889 return position;
00890 }
00891
00892 template <typename ValueType>
00893 BALL_INLINE
00894 const ValueType& TRegularData2D<ValueType>::getClosestValue
00895 (const typename TRegularData2D<ValueType>::CoordinateType& r) const
00896 throw(Exception::OutOfGrid)
00897 {
00898 if (!isInside(r))
00899 {
00900 throw Exception::OutOfGrid(__FILE__, __LINE__);
00901 }
00902
00903 static IndexType position;
00904 position.x = (Position)((r.x - origin_.x) / spacing_.x + 0.5);
00905 position.y = (Position)((r.y - origin_.y) / spacing_.y + 0.5);
00906
00907 return operator [] (position);
00908 }
00909
00910 template <typename ValueType>
00911 BALL_INLINE
00912 ValueType& TRegularData2D<ValueType>::getClosestValue
00913 (const typename TRegularData2D<ValueType>::CoordinateType& r)
00914 throw(Exception::OutOfGrid)
00915 {
00916 if (!isInside(r))
00917 {
00918 throw Exception::OutOfGrid(__FILE__, __LINE__);
00919 }
00920
00921 static IndexType position;
00922 position.x = (Position)((r.x - origin_.x) / spacing_.x + 0.5);
00923 position.y = (Position)((r.y - origin_.y) / spacing_.y + 0.5);
00924
00925 return operator [] (position);
00926 }
00927
00928 template <typename ValueType>
00929 BALL_INLINE
00930 ValueType TRegularData2D<ValueType>::calculateMean() const
00931 {
00932 Position data_points = (size_.x * size_.y);
00933 ValueType mean = 0;
00934 for (Position i = 0; i < data_points; i++)
00935 {
00936 mean += data_[i];
00937 }
00938 mean /= data_points;
00939 return mean;
00940 }
00941
00942 template <typename ValueType>
00943 BALL_INLINE
00944 ValueType TRegularData2D<ValueType>::calculateSD() const
00945 {
00946 Position data_points = (size_.x * size_.y);
00947 ValueType stddev = 0;
00948 ValueType mean = this->calculateMean();
00949 for (Position i = 0; i < data_points; i++)
00950 {
00951 stddev += (pow(data_(i)-mean,2));
00952 }
00953 stddev /= (data_points-1);
00954 stddev = sqrt(stddev);
00955 return stddev;
00956 }
00957
00958 template <typename ValueType>
00959 void TRegularData2D<ValueType>::clear()
00960 {
00961 data_.resize(0);
00962
00963 origin_.set(0.0);
00964 dimension_.set(0.0, 0.0);
00965 size_.x = 0;
00966 size_.y = 0;
00967 spacing_.set(1.0, 1.0);
00968 }
00969
00970 template <typename ValueType>
00971 bool TRegularData2D<ValueType>::operator == (const TRegularData2D<ValueType>& data) const
00972 {
00973 return ((origin_ == data.origin_)
00974 && (dimension_ == data.dimension_)
00975 && (size_.x == data.size_.x)
00976 && (size_.y == data.size_.y)
00977 && (data_ == data.data_));
00978 }
00979
00980
00983
00984 template <typename ValueType>
00985 std::ostream& operator << (std::ostream& os, const TRegularData2D<ValueType>& data)
00986 {
00987
00988 os << data.getOrigin().x << " " << data.getOrigin().y
00989 << std::endl
00990 << data.getOrigin().x + data.getDimension().x << " "
00991 << data.getOrigin().y + data.getDimension().y
00992 << std::endl
00993 << data.getSize().x - 1 << " " << data.getSize().y - 1
00994 << std::endl;
00995
00996
00997 std::copy(data.begin(), data.end(), std::ostream_iterator<ValueType>(os, "\n"));
00998 return os;
00999 }
01000
01002 template <typename ValueType>
01003 std::istream& operator >> (std::istream& is, TRegularData2D<ValueType>& grid)
01004 {
01005 typename TRegularData2D<ValueType>::CoordinateType origin;
01006 typename TRegularData2D<ValueType>::CoordinateType dimension;
01007 typename TRegularData2D<ValueType>::IndexType size;
01008
01009 is >> origin.x >> origin.y;
01010 is >> dimension.x >> dimension.y;
01011 is >> size.x >> size.y;
01012
01013 dimension -= origin;
01014 size.x++;
01015 size.y++;
01016
01017 grid.resize(size);
01018 grid.setOrigin(origin);
01019 grid.setDimension(dimension);
01020
01021 std::copy(std::istream_iterator<ValueType>(is),
01022 std::istream_iterator<ValueType>(),
01023 grid.begin());
01024
01025
01026 return is;
01027 }
01029
01030 template <typename ValueType>
01031 void TRegularData2D<ValueType>::binaryWrite(const String& filename) const
01032 throw(Exception::FileNotFound)
01033 {
01034 File outfile(filename.c_str(), std::ios::out|std::ios::binary);
01035 if (!outfile.isValid())
01036 throw Exception::FileNotFound(__FILE__, __LINE__, filename);
01037
01038
01039 BinaryFileAdaptor<BlockValueType> adapt_block;
01040 BinaryFileAdaptor<ValueType> adapt_single;
01041 BinaryFileAdaptor<float> adapt_float;
01042
01043 BinaryFileAdaptor<Size> adapt_size;
01044
01045 adapt_size.setData(data_.size());
01046 outfile << adapt_size;
01047
01048
01049
01050
01051
01052
01053
01054
01055 adapt_float.setData(origin_.x);
01056 outfile << adapt_float;
01057 adapt_float.setData(origin_.y);
01058 outfile << adapt_float;
01059
01060 adapt_float.setData(dimension_.x);
01061 outfile << adapt_float;
01062 adapt_float.setData(dimension_.y);
01063 outfile << adapt_float;
01064
01065 adapt_float.setData(spacing_.x);
01066 outfile << adapt_float;
01067 adapt_float.setData(spacing_.y);
01068 outfile << adapt_float;
01069
01070 BinaryFileAdaptor<IndexType> adapt_index;
01071 adapt_index.setData(size_);
01072 outfile << adapt_index;
01073
01074
01075 const int BLOCK_SIZE = 1024;
01076 Index window_pos = 0;
01077
01078 while (((int)data_.size() - (BLOCK_SIZE + window_pos)) >= 0)
01079 {
01080 adapt_block.setData(* (BlockValueType*)&(data_[window_pos]));
01081 outfile << adapt_block;
01082 window_pos += BLOCK_SIZE;
01083 }
01084
01085
01086 for (Size i = window_pos; i < data_.size(); i++)
01087 {
01088 adapt_single.setData(data_[i]);
01089 outfile << adapt_single;
01090 }
01091
01092
01093 outfile.close();
01094 }
01095
01096 template <typename ValueType>
01097 void TRegularData2D<ValueType>::binaryRead(const String& filename)
01098 throw(Exception::FileNotFound)
01099 {
01100 File infile(filename, std::ios::in|std::ios::binary);
01101 if (!infile.isValid())
01102 {
01103 throw Exception::FileNotFound(__FILE__, __LINE__, filename);
01104 }
01105
01106 BinaryFileAdaptor< BlockValueType > adapt_block;
01107 BinaryFileAdaptor< ValueType > adapt_single;
01108
01109
01110 BinaryFileAdaptor<Size> adapt_size;
01111 BinaryFileAdaptor<float> adapt_float;
01112
01113 infile >> adapt_size;
01114 Size new_size = adapt_size.getData();
01115
01116 infile >> adapt_float;
01117 origin_.x = adapt_float.getData();
01118 infile >> adapt_float;
01119 origin_.y = adapt_float.getData();
01120
01121 infile >> adapt_float;
01122 dimension_.x = adapt_float.getData();
01123 infile >> adapt_float;
01124 dimension_.y = adapt_float.getData();
01125
01126 infile >> adapt_float;
01127 spacing_.x = adapt_float.getData();
01128 infile >> adapt_float;
01129 spacing_.y = adapt_float.getData();
01130
01131 BinaryFileAdaptor<IndexType> adapt_index;
01132 infile >> adapt_index;
01133 size_ = adapt_index.getData();
01134
01135 data_.resize(new_size);
01136
01137
01138 Index window_pos = 0;
01139
01140 while ( ((int)data_.size() - (1024 + window_pos)) >= 0 )
01141 {
01142 infile >> adapt_block;
01143 *(BlockValueType*)(&(data_[window_pos])) = adapt_block.getData();
01144
01145
01146
01147
01148
01149
01150 window_pos+=1024;
01151 }
01152
01153
01154 for (Size i=window_pos; i<data_.size(); i++)
01155 {
01156 infile >> adapt_single;
01157 data_[i] = adapt_single.getData();
01158 }
01159
01160
01161 infile.close();
01162 }
01163 }
01164
01165 #endif // BALL_DATATYPE_TREGULARDATA2D_H