regularData1D.h

Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 // $Id: regularData1D.h,v 1.45 2004/04/22 10:08:20 oliver Exp $
00005 //
00006 
00007 #ifndef BALL_DATATYPE_REGULARDATA1D_H
00008 #define BALL_DATATYPE_REGULARDATA1D_H
00009 
00010 #ifndef BALL_COMMON_H
00011 # include <BALL/common.h>
00012 #endif
00013 
00014 #ifndef BALL_SYSTEM_FILE_H
00015 # include <BALL/SYSTEM/file.h>
00016 #endif
00017 
00018 #include <vector>
00019 #include <iostream>
00020 #include <fstream>
00021 #include <iterator>
00022 #include <algorithm>
00023 
00024 namespace BALL
00025 {
00037   template <typename ValueType>
00038   class TRegularData1D
00039   {
00040     public:
00041       
00042     BALL_CREATE(TRegularData1D<ValueType>)
00043 
00044     
00047 
00049     typedef Position IndexType;
00051     typedef std::vector<ValueType>  VectorType;
00053     typedef double CoordinateType;
00055     typedef typename std::vector<ValueType>::iterator Iterator;
00057     typedef typename std::vector<ValueType>::const_iterator ConstIterator;
00059 
00060     //  STL compatibility types
00061     //
00062     typedef ValueType value_type;
00063     typedef typename std::vector<ValueType>::iterator iterator;
00064     typedef typename std::vector<ValueType>::const_iterator const_iterator;
00065     typedef typename std::vector<ValueType>::reference reference;
00066     typedef typename std::vector<ValueType>::const_reference const_reference;
00067     typedef typename std::vector<ValueType>::pointer pointer;
00068     typedef typename std::vector<ValueType>::difference_type difference_type;
00069     typedef typename std::vector<ValueType>::size_type size_type;
00070 
00074       
00076     TRegularData1D();
00077 
00079     TRegularData1D(const TRegularData1D& data)
00080       throw(Exception::OutOfMemory);
00081   
00083     TRegularData1D(const CoordinateType& origin, const CoordinateType& dimension, const CoordinateType& spacing)
00084       throw(Exception::OutOfMemory);
00085 
00087     TRegularData1D(const IndexType& size)
00088       throw(Exception::OutOfMemory);
00089 
00091     TRegularData1D(const VectorType& data, const CoordinateType& origin = 0.0, const CoordinateType& dimension = 1.0)
00092       throw(Exception::OutOfMemory);
00093 
00095     virtual ~TRegularData1D();
00096 
00098     virtual void clear();
00100 
00101 
00105 
00109     TRegularData1D& operator = (const TRegularData1D<ValueType>& data)
00110       throw(Exception::OutOfMemory);
00111 
00115     TRegularData1D& operator = (const VectorType& data)
00116       throw(Exception::OutOfMemory);
00117 
00119 
00123 
00124     bool operator == (const TRegularData1D& data) const;
00125 
00127     BALL_INLINE bool operator != (const TRegularData1D& data) const { return !this->operator == (data); }
00128 
00130     BALL_INLINE bool empty() const { return data_.empty(); }
00131 
00133     bool isInside(const CoordinateType& x) const;
00135 
00139 
00140     BALL_INLINE ConstIterator begin() const { return data_.begin(); }
00142     BALL_INLINE ConstIterator end() const { return data_.end(); }
00144     BALL_INLINE Iterator begin() { return data_.begin(); }
00146     BALL_INLINE Iterator end() { return data_.end(); }
00148 
00152     
00153     // STL compatibility
00154     BALL_INLINE size_type size() const { return data_.size(); }
00155     BALL_INLINE size_type max_size() const { return data_.max_size(); }
00156     BALL_INLINE void swap(TRegularData1D<ValueType>& data) { std::swap(*this, data); }
00157 
00161     const ValueType& getData(const IndexType& index) const
00162       throw(Exception::OutOfGrid);
00163 
00167     ValueType& getData(const IndexType& index)
00168       throw(Exception::OutOfGrid);
00169 
00174     const ValueType& operator [] (const IndexType& index) const { return data_[index]; }
00175       
00180     ValueType& operator [] (const IndexType& index) { return data_[index]; }
00181     
00190     ValueType operator () (const CoordinateType& x) const;
00191 
00197     ValueType getInterpolatedValue(const CoordinateType& x) const
00198       throw(Exception::OutOfGrid);
00199       
00206     void getEnclosingIndices(const CoordinateType& x, Position& lower, Position& upper) const
00207       throw(Exception::OutOfGrid);
00208 
00209 
00213     void getEnclosingValues(const CoordinateType& x, ValueType& lower, ValueType& upper) const
00214       throw(Exception::OutOfGrid);
00215 
00220     CoordinateType getCoordinates(const IndexType& index) const
00221       throw(Exception::OutOfGrid);
00222 
00228     IndexType getClosestIndex(const CoordinateType& x) const
00229       throw(Exception::OutOfGrid);
00230       
00236     IndexType getLowerIndex(const CoordinateType& x) const
00237       throw(Exception::OutOfGrid);
00238       
00244     const ValueType& getClosestValue(const CoordinateType& x) const
00245       throw(Exception::OutOfGrid);
00246       
00252     ValueType& getClosestValue(const CoordinateType& x)
00253       throw(Exception::OutOfGrid);
00254       
00256     BALL_INLINE IndexType getSize() const { return (IndexType)data_.size(); }
00257 
00262     BALL_INLINE const CoordinateType& getOrigin() const { return origin_; }
00263     
00268     BALL_INLINE const CoordinateType& getSpacing() const {  return spacing_; }
00269           
00272     BALL_INLINE void setOrigin(const CoordinateType& origin) { origin_ = origin; }
00273 
00279     BALL_INLINE const CoordinateType& getDimension() const { return dimension_; }
00280 
00286     BALL_INLINE void setDimension(const CoordinateType& dimension) { dimension_ = dimension; }
00287 
00299     void resize(const IndexType& size)
00300       throw(Exception::OutOfMemory);
00301 
00310     void rescale(const IndexType& new_size)
00311       throw(Exception::OutOfMemory);
00312 
00316     void binaryWrite(const String& filename) const
00317       throw(Exception::FileNotFound);
00318 
00322     void binaryRead(const String& filename)
00323       throw(Exception::FileNotFound);
00325   
00326     protected:
00328     CoordinateType  origin_;
00329 
00331     CoordinateType  dimension_;
00332 
00334     CoordinateType  spacing_;
00335 
00337     VectorType      data_;
00338 
00340     typedef struct { ValueType bt[1024]; } BlockValueType;
00341   };
00342 
00345   typedef TRegularData1D<float> RegularData1D;
00346   
00347   template <typename ValueType>
00348   TRegularData1D<ValueType>::TRegularData1D()
00349     : origin_(0.0),
00350       dimension_(0.0),
00351       spacing_(1.0),
00352       data_()
00353   {
00354   }
00355 
00356   template <typename ValueType>
00357   TRegularData1D<ValueType>::~TRegularData1D()
00358   {
00359   }
00360 
00361   template <typename ValueType>
00362   TRegularData1D<ValueType>::TRegularData1D(const TRegularData1D<ValueType>& data)
00363     throw(Exception::OutOfMemory)
00364     : origin_(data.origin_),
00365       dimension_(data.dimension_),
00366       spacing_(data.spacing_),
00367       data_()
00368   {
00369     // Try to catch allocation errors and rethrow them as OutOfMemory
00370     try
00371     {
00372       data_ = data.data_;
00373     }
00374     catch (std::bad_alloc&)
00375     {
00376       throw Exception::OutOfMemory(__FILE__, __LINE__, data.size() * sizeof(ValueType));
00377     }
00378   }
00379 
00380   template <typename ValueType>
00381   TRegularData1D<ValueType>::TRegularData1D
00382     (const typename TRegularData1D<ValueType>::CoordinateType& origin, 
00383      const typename TRegularData1D<ValueType>::CoordinateType& dimension, 
00384      const typename TRegularData1D<ValueType>::CoordinateType& spacing)
00385     throw(Exception::OutOfMemory)
00386     : origin_(origin),
00387       dimension_(dimension),
00388       spacing_(spacing),
00389       data_()
00390   {
00391     // Determine the size of the vector
00392     size_type size = (size_type)(dimension_ / spacing_ + 1.0);
00393 
00394     // Try to catch allocation errors and rethrow them as OutOfMemory
00395     try
00396     {
00397       data_.resize(size);
00398     }
00399     catch (std::bad_alloc&)
00400     {
00401       throw Exception::OutOfMemory(__FILE__, __LINE__, size * sizeof(ValueType));
00402     }
00403   }
00404       
00405   template <typename ValueType>
00406   TRegularData1D<ValueType>::TRegularData1D
00407     (const typename TRegularData1D<ValueType>::VectorType& data, 
00408      const typename TRegularData1D<ValueType>::CoordinateType& origin, 
00409      const typename TRegularData1D<ValueType>::CoordinateType& dimension)
00410     throw(Exception::OutOfMemory)
00411     : origin_(origin),
00412       dimension_(dimension),
00413       spacing_(dimension / ((double)data.size()-1)),
00414       data_()
00415   {
00416     // Try to catch allocation errors and rethrow them as OutOfMemory
00417     try
00418     {
00419       data_ = data;
00420     }
00421     catch (std::bad_alloc&)
00422     {
00423       throw Exception::OutOfMemory(__FILE__, __LINE__, data.size() * sizeof(ValueType));
00424     }
00425   }
00426 
00427 
00428   template <class ValueType>
00429   TRegularData1D<ValueType>::TRegularData1D
00430     (const typename TRegularData1D<ValueType>::IndexType& size)
00431     throw(Exception::OutOfMemory)
00432     : origin_(0.0),
00433       dimension_(1.0),
00434       data_()
00435   {
00436     // Compute the grid spacing
00437     spacing_ = dimension_ / (double)(size - 1);
00438 
00439     try
00440     {
00441       data_.resize(size);
00442     }
00443     catch (std::bad_alloc&)
00444     {
00445       data_.resize(0);
00446       throw Exception::OutOfMemory(__FILE__, __LINE__, size * sizeof(ValueType));
00447     }
00448   }
00449 
00450   template <typename ValueType>
00451   void TRegularData1D<ValueType>::clear()
00452   {
00453     // iterate over the data and reset all values to their default
00454     // boundaries and vector size remain unchanged
00455     static ValueType default_value = ValueType();
00456     std::fill(data_.begin(), data_.end(), default_value);
00457   }
00458 
00459   template <typename ValueType>
00460   TRegularData1D<ValueType>& TRegularData1D<ValueType>::operator = (const TRegularData1D<ValueType>& rhs)
00461     throw(Exception::OutOfMemory)
00462   {
00463     // copy all members...
00464     origin_ = rhs.origin_;
00465     dimension_ = rhs.dimension_;
00466     spacing_ = rhs.spacing_;
00467     try 
00468     {
00469       data_ = rhs.data_;
00470     }
00471     catch (std::bad_alloc&)
00472     {
00473       data_.resize(0);
00474       throw Exception::OutOfMemory(__FILE__, __LINE__, rhs.size() * sizeof(ValueType));
00475     }
00476 
00477     return *this;
00478   }
00479 
00480   template <typename ValueType>
00481   TRegularData1D<ValueType>& TRegularData1D<ValueType>::operator = (const VectorType& rhs)
00482     throw(Exception::OutOfMemory)
00483   {
00484     // Copy the data. The boundaries remain unchanged.
00485     try 
00486     {
00487       data_ = rhs;
00488     }
00489     catch (std::bad_alloc&)
00490     {
00491       data_.resize(0);
00492       throw Exception::OutOfMemory(__FILE__, __LINE__, rhs.size() * sizeof(ValueType));
00493     }
00494     
00495     return *this;
00496   }
00497 
00498   template <typename ValueType>
00499   bool TRegularData1D<ValueType>::operator == (const TRegularData1D<ValueType>& data) const
00500   {
00501     return (origin_ == data.origin_ 
00502             && dimension_ == data.dimension_ 
00503             && data_ == data.data_);
00504   }
00505 
00506   template <class ValueType>
00507   BALL_INLINE
00508   bool TRegularData1D<ValueType>::isInside(const typename TRegularData1D<ValueType>::CoordinateType& r) const
00509   {
00510     return ((r >= origin_) && (r <= (origin_ + dimension_)));
00511   }
00512 
00513   template <typename ValueType>
00514   BALL_INLINE
00515   const ValueType& TRegularData1D<ValueType>::getData(const IndexType& index) const
00516     throw(Exception::OutOfGrid)
00517   {
00518     if (index >= data_.size())
00519     {
00520       throw Exception::OutOfGrid(__FILE__, __LINE__);
00521     }
00522     return data_[index];
00523   }
00524     
00525   template <typename ValueType>
00526   BALL_INLINE
00527   ValueType& TRegularData1D<ValueType>::getData(const IndexType& index)
00528     throw(Exception::OutOfGrid)
00529   {
00530     if (index >= data_.size())
00531     {
00532       throw Exception::OutOfGrid(__FILE__, __LINE__);
00533     }
00534     return data_[index];
00535   }
00536     
00537   template <typename ValueType>
00538   void TRegularData1D<ValueType>::getEnclosingIndices
00539     (const typename TRegularData1D<ValueType>::CoordinateType& x,
00540      Position& lower, Position& upper) const
00541     throw(Exception::OutOfGrid)
00542   {
00543     if (!isInside(x) || (data_.size() < 2))
00544     {
00545       throw Exception::OutOfGrid(__FILE__, __LINE__);
00546     }
00547     lower = (Position)floor((x - origin_) / spacing_);
00548     if (lower == data_.size() - 1)
00549     {
00550       // If we are on the right most data point, we cannot interpolate to the right!
00551       lower = data_.size() - 2;
00552     }
00553     upper = lower + 1;
00554   }
00555 
00556   template <typename ValueType>
00557   void TRegularData1D<ValueType>::getEnclosingValues
00558     (const typename TRegularData1D<ValueType>::CoordinateType& x,
00559      ValueType& lower, ValueType& upper) const
00560     throw(Exception::OutOfGrid)
00561   {
00562     Position lower_index;
00563     Position upper_index;
00564     getEnclosingIndices(x, lower_index, upper_index);
00565     lower = data_[lower_index];
00566     upper = data_[upper_index];
00567   }
00568 
00569   template <typename ValueType>
00570   BALL_INLINE
00571   ValueType TRegularData1D<ValueType>::getInterpolatedValue(const CoordinateType& x) const
00572     throw(Exception::OutOfGrid)
00573   {
00574     if (!isInside(x))
00575     {
00576       throw Exception::OutOfGrid(__FILE__, __LINE__);
00577     }
00578     return operator () (x);
00579   }
00580       
00581   template <typename ValueType>
00582   BALL_INLINE
00583   typename TRegularData1D<ValueType>::CoordinateType TRegularData1D<ValueType>::getCoordinates
00584     (const typename TRegularData1D<ValueType>::IndexType& index) const
00585     throw(Exception::OutOfGrid)
00586   {
00587     if ((index >= data_.size()) || (data_.size() == 0))
00588     {
00589       throw Exception::OutOfGrid(__FILE__, __LINE__);
00590     }
00591 
00592     return (CoordinateType)(origin_ + (double)index / ((double)data_.size()-1) * dimension_);
00593   }
00594 
00595   template <typename ValueType>
00596   BALL_INLINE
00597   typename TRegularData1D<ValueType>::IndexType TRegularData1D<ValueType>::getClosestIndex(const CoordinateType& x) const
00598     throw(Exception::OutOfGrid)
00599   {
00600     if ((x < origin_) || (x > (origin_ + dimension_)))
00601     {
00602       throw Exception::OutOfGrid(__FILE__, __LINE__);
00603     }
00604 
00605     return (IndexType)(size_type)floor((x - origin_) / spacing_ + 0.5);
00606   }
00607       
00608   template <typename ValueType>
00609   BALL_INLINE
00610   typename TRegularData1D<ValueType>::IndexType TRegularData1D<ValueType>::getLowerIndex(const CoordinateType& x) const
00611     throw(Exception::OutOfGrid)
00612   {
00613     if ((x < origin_) || (x > (origin_ + dimension_)))
00614     {
00615       throw Exception::OutOfGrid(__FILE__, __LINE__);
00616     }
00617 
00618     return (IndexType)(size_type)floor((x - origin_) / spacing_);
00619   }
00620       
00621   template <typename ValueType>
00622   BALL_INLINE
00623   const ValueType& TRegularData1D<ValueType>::getClosestValue(const CoordinateType& x) const
00624     throw(Exception::OutOfGrid)
00625   {
00626     if ((x < origin_) || (x > (origin_ + dimension_)))
00627     {
00628       throw Exception::OutOfGrid(__FILE__, __LINE__);
00629     }
00630     
00631     // Round to the closest data point.
00632     size_type index = (size_type)floor((x - origin_) / spacing_ + 0.5);
00633     return data_[index];
00634   }
00635       
00636   template <typename ValueType>
00637   BALL_INLINE
00638   ValueType& TRegularData1D<ValueType>::getClosestValue(const CoordinateType& x)
00639     throw(Exception::OutOfGrid)
00640   {
00641     if ((x < origin_) || (x > (origin_ + dimension_)))
00642     {
00643       throw Exception::OutOfGrid(__FILE__, __LINE__);
00644     }
00645     
00646     // Round to the closest data point.
00647     size_type index = (size_type)floor((x - origin_) / spacing_ + 0.5);
00648     return data_[index];
00649   }
00650       
00651   template <typename ValueType>
00652   BALL_INLINE
00653   ValueType TRegularData1D<ValueType>::operator () (const CoordinateType& x) const
00654   {
00655     size_type left_index = (size_type)floor((x - origin_) / spacing_);
00656     if (left_index == data_.size() - 1)
00657     {
00658       // If we are on the right most data point, we cannot interpolate to the right!
00659       return data_[data_.size() - 1];
00660     }
00661     
00662     // Interpolate between the point to the left and the point to the right.
00663     double d = 1.0 - (((x - origin_) - (double)left_index * spacing_) / spacing_);
00664     return data_[left_index] * d + (1.0 - d) * data_[left_index + 1];
00665   }
00666       
00667   template <typename ValueType>
00668   void TRegularData1D<ValueType>::resize
00669     (const typename TRegularData1D<ValueType>::IndexType& new_size)
00670     throw(Exception::OutOfMemory)
00671   {
00672     // Rescale dimension to the new size.
00673     if (data_.size() > 0)
00674     {
00675       dimension_ *= (double)new_size / (double)data_.size();
00676     }
00677 
00678     // Try to resize the vactor and rethrow any bad_allocs.
00679     try
00680     {
00681       data_.resize(new_size);
00682     }
00683     catch (std::bad_alloc&)
00684     {
00685       // The resulting vector is empty and thus well-defined.
00686       data_.resize(0);
00687       throw Exception::OutOfMemory(__FILE__, __LINE__, new_size * sizeof(ValueType));
00688     }
00689   }
00690     
00691   template <typename ValueType>
00692   void TRegularData1D<ValueType>::rescale
00693     (const typename TRegularData1D<ValueType>::IndexType& new_size)
00694     throw(Exception::OutOfMemory)
00695   {
00696     // if the new and the old size coincide: done.
00697     if (new_size == (IndexType)data_.size())
00698     {
00699       return;
00700     }
00701 
00702     // Catch any bad_allocs throw by vector::resize
00703     try
00704     {
00705       // if the data set is empty...
00706       if (data_.size() == 0)
00707       {
00708         // ...there's nothing to do: a resize was requested
00709         data_.resize(new_size);
00710         return;
00711       }
00712       
00713       // if the data set contains only a single value,
00714       // we fill everything with this value
00715       if ((data_.size() == 1) && (new_size > 1))
00716       {
00717         ValueType old_value = data_[0];
00718         data_.resize(new_size);
00719         for (IndexType i = 1; i < new_size; i++)
00720         {
00721           data_[i] = old_value;
00722         }
00723 
00724         return;
00725       }
00726 
00727       // that's the default case: use linear interpolation
00728       // to determine the values at the new positions
00729       VectorType new_data(new_size);
00730       CoordinateType factor1 = (CoordinateType)data_.size() / (CoordinateType)new_size;
00731       CoordinateType factor2 = (CoordinateType)(data_.size() - 1) / (new_size - 1);
00732 
00733       for (Size i = 0; i < new_size; i++)
00734       {
00735         // determine the interval of the old data set we are currently in
00736         // ([old_idx, old_idx + 1])
00737         IndexType old_idx = (IndexType)((CoordinateType)i * factor1);
00738 
00739         // consider numerical inaccuracies...
00740         if (old_idx >= (data_.size() - 1))
00741         {
00742           old_idx = data_.size() - 2;
00743         }
00744         CoordinateType factor3 = (CoordinateType)i * factor2 - (CoordinateType)old_idx;
00745         new_data[i] = data_[old_idx] * (1 - factor3) + factor3 * data_[old_idx + 1];
00746       }
00747 
00748       // assign the new data
00749       data_ = new_data;
00750     }
00751     catch (std::bad_alloc&)
00752     {
00753       // Make sure we are in a well-defined state.
00754       data_.resize(0);
00755       throw Exception::OutOfMemory(__FILE__, __LINE__, new_size * sizeof(ValueType));     
00756     }
00757   }
00758 
00761 
00762   template <typename ValueType>
00763   std::ostream& operator << (std::ostream& os, const TRegularData1D<ValueType>& data)
00764   {
00765     // Write the grid origin, dimension, and number of grid points
00766     os << data.getOrigin() << std::endl
00767        << data.getOrigin() + data.getDimension() << std::endl
00768        << data.getSize() - 1 << std::endl;
00769 
00770     // Write the array contents.
00771     std::copy(data.begin(), data.end(), std::ostream_iterator<ValueType>(os, "\n"));
00772     return os;
00773   }
00774 
00776   template <typename ValueType>
00777   std::istream& operator >> (std::istream& is, TRegularData1D<ValueType>& grid)
00778   {
00779     typename TRegularData1D<ValueType>::CoordinateType origin;
00780     typename TRegularData1D<ValueType>::CoordinateType dimension;
00781     typename TRegularData1D<ValueType>::IndexType size;
00782 
00783     is >> origin;
00784     is >> dimension;
00785     is >> size;
00786     
00787     dimension -= origin;
00788     size++;
00789 
00790     grid.resize(size);
00791     grid.setOrigin(origin);
00792     grid.setDimension(dimension);
00793 
00794     std::copy(std::istream_iterator<ValueType>(is), 
00795               std::istream_iterator<ValueType>(), 
00796               grid.begin());
00797     //    std::copy_n(std::istream_iterator<ValueType>(is), grid.size(), grid.begin());
00798     
00799     return is;
00800   }
00801 
00802   template <typename ValueType>
00803   void TRegularData1D<ValueType>::binaryWrite(const String& filename) const
00804     throw(Exception::FileNotFound)
00805   {
00806     File outfile(filename, std::ios::out|std::ios::binary);
00807     if (!outfile.isValid()) 
00808     {
00809       throw Exception::FileNotFound(__FILE__, __LINE__, filename);
00810     }
00811 
00812     BinaryFileAdaptor<BlockValueType> adapt_block;
00813     BinaryFileAdaptor<ValueType>      adapt_single;
00814     
00815     // write all information we need to recreate the grid
00816     BinaryFileAdaptor<CoordinateType> adapt_coordinate;
00817     BinaryFileAdaptor<Size>           adapt_size;
00818 
00819     adapt_size.setData(data_.size());
00820     outfile << adapt_size;
00821     
00822     adapt_coordinate.setData(origin_);
00823     outfile << adapt_coordinate;
00824 
00825     adapt_coordinate.setData(dimension_);
00826     outfile << adapt_coordinate;
00827 
00828     adapt_coordinate.setData(spacing_);
00829     outfile << adapt_coordinate;
00830 
00831     // we slide a window of size 1024 over our data
00832     Index window_pos = 0;
00833     while (((int)data_.size() - (1024 + window_pos)) >= 0 )
00834     {
00835       adapt_block.setData(*(BlockValueType*)&(data_[window_pos]));
00836       outfile << adapt_block;
00837       window_pos += 1024;
00838     }
00839 
00840     // now we have to write the remaining data one by one
00841     for (Size i = window_pos; i < data_.size(); i++)
00842     {
00843       adapt_single.setData(data_[i]);
00844       outfile << adapt_single;
00845     }
00846 
00847     // that's it. I hope...
00848     outfile.close();
00849   }
00850 
00851   template <typename ValueType>
00852   void TRegularData1D<ValueType>::binaryRead(const String& filename)
00853     throw(Exception::FileNotFound)
00854   {
00855     File infile(filename, std::ios::in|std::ios::binary);
00856     if (!infile.isValid()) throw Exception::FileNotFound(__FILE__, __LINE__, filename);
00857     
00858     BinaryFileAdaptor<BlockValueType> adapt_block;
00859     BinaryFileAdaptor<ValueType>      adapt_single;
00860     
00861     // read all information we need to recreate the grid
00862     BinaryFileAdaptor<CoordinateType> adapt_coordinate;
00863     BinaryFileAdaptor<Size>           adapt_size;
00864 
00865     infile >> adapt_size;
00866     Size new_size = adapt_size.getData();
00867   
00868     infile >> adapt_coordinate;
00869     origin_ = adapt_coordinate.getData();
00870 
00871     infile >> adapt_coordinate;
00872     dimension_ = adapt_coordinate.getData();
00873 
00874     infile >> adapt_coordinate;
00875     spacing_ = adapt_coordinate.getData();
00876 
00877     data_.resize(new_size);
00878 
00879     // we slide a window of size 1024 over our data
00880     Index window_pos = 0;
00881     
00882     while ( ((int)data_.size() - (1024 + window_pos)) >= 0 )
00883     {
00884       infile >> adapt_block;
00885       *(BlockValueType*)(&(data_[window_pos])) = adapt_block.getData();
00886       /*
00887       for (Size i=0; i<1024; i++)
00888       {
00889         data_[i+window_pos] = adapt_block.getData().bt[i];
00890       }
00891       */
00892       window_pos+=1024;
00893     }
00894 
00895     // now we have to read the remaining data one by one
00896     for (Size i=window_pos; i<data_.size(); i++)
00897     {
00898       infile >> adapt_single;
00899       data_[i] = adapt_single.getData();
00900     }
00901 
00902     // that's it. I hope...
00903     infile.close();
00904   }
00905 } // namespace BALL
00906 
00907 #endif // BALL_DATATYPE_REGULARDATA1D_H