QGpCoreTools/IrregularGrid2DData.h
Go to the documentation of this file.
00001 /***************************************************************************
00002 **
00003 **  This file is part of QGpCoreTools.
00004 **
00005 **  This library is free software; you can redistribute it and/or
00006 **  modify it under the terms of the GNU Lesser General Public
00007 **  License as published by the Free Software Foundation; either
00008 **  version 2.1 of the License, or (at your option) any later version.
00009 **
00010 **  This file is distributed in the hope that it will be useful, but WITHOUT
00011 **  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 **  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
00013 **  License for more details.
00014 **
00015 **  You should have received a copy of the GNU Lesser General Public
00016 **  License along with this library; if not, write to the Free Software
00017 **  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00018 **
00019 **  See http://www.geopsy.org for more information.
00020 **
00021 **  Created : 2008-07-15
00022 **  Authors :
00023 **    Marc Wathelet
00024 **    Marc Wathelet (LGIT, Grenoble, France)
00025 **
00026 ***************************************************************************/
00027 
00028 #ifndef IRREGULARGRID2DDATA_H
00029 #define IRREGULARGRID2DDATA_H
00030 
00031 #include "Point2D.h"
00032 #include "Curve.h"
00033 #include "Segment2D.h"
00034 
00035 namespace QGpCoreTools {
00036 
00037 class GridSearch;
00038 
00039 class QGPCORETOOLS_EXPORT IrregularGrid2DData : public QSharedData
00040 {
00041   TRANSLATIONS( "IrregularGrid2DData" );
00042 public:
00043   IrregularGrid2DData();
00044   IrregularGrid2DData(int nx, int ny);
00045   IrregularGrid2DData(const IrregularGrid2DData& o);
00046   ~IrregularGrid2DData();
00047 
00048   void operator=(const IrregularGrid2DData& o);
00049   void operator=(const GridSearch& o);
00050   void operator+=(const IrregularGrid2DData& o);
00051 
00052   int nx() const {return _nx;}
00053   int ny() const {return _ny;}
00054   void clear();
00055   void init(int nx, int ny);
00056   void init(double value=0.0);
00057   inline void init(int nx, int ny, double value);
00058   bool isLike(IrregularGrid2DData& o) const;
00059   // Function to set _x and _y values
00060   void setLinear(AxisType axis,double min, double max);
00061   void setLog(AxisType axis,double min, double max);
00062   // Resample the grid at x defined by xModel (e.g. from another curve)
00063   void resample(AxisType axis, const QVector<double>& xModel, SamplingOptions options);
00064   void resample(AxisType axis, int n, double min, double max, SamplingOptions options);
00065   // Cut function between two x values
00066   void cut (AxisType axis, double min, double max, SamplingOptions options);
00067   void inverse(AxisType axis);
00068   void log10(AxisType axis);
00069   void log10();
00070   void pow10(AxisType axis);
00071   void pow10();
00072   void multiplyCoordinates(AxisType axis, double fac);
00073   void multiplyValues(AxisType along, int index, double fac);
00074   void multiplyValues(double fac);
00075   const double * axisData(AxisType axis) const {int n; return getAxis(axis,n);}
00076   // Function to acces the grid
00077   inline double value(int ix, int iy) const;
00078   inline void setValue(int ix, int iy, double val);
00079 
00080   double x(int ix) const {return _x[ix];}
00081   double y(int iy) const {return _y[iy];}
00082   void setX(int ix, double val) {_x[ix]=val;}
00083   void setY(int iy, double val) {_y[iy]=val;}
00084   QVector<double> x() const;
00085   QVector<double> y() const;
00086   inline double * valuePointer(int ix, int iy);
00087   inline const double * valuePointer(int ix, int iy) const;
00088   const double * xPointer() const {return _x;}
00089   double * xPointer() {return _x;}
00090   const double * yPointer() const {return _y;}
00091   double * yPointer() {return _y;}
00092   inline Point2D coordinates(int ix, int iy) const;
00093   int indexOfX(double x) const {return indexOf(_x, _nx, _n2x, x);}
00094   int indexOfY(double y) const {return indexOf(_y, _ny, _n2y, y);}
00095 
00096   double minimumValue() const;
00097   double maximumValue() const;
00098   double minimumValue(int& ix, int& iy) const;
00099   double maximumValue(int& ix, int& iy) const;
00100   double minimumAxis(AxisType axis) const;
00101   double maximumAxis(AxisType axis) const;
00102   double sum(AxisType along, int index) const;
00103   double mean(AxisType along, int index) const;
00104   double median(AxisType along, int index) const;
00105   double mode(AxisType along, int index) const;
00106   double variance(AxisType along, int index) const;
00107   double variance(AxisType along, int index, double average) const;
00108   double normalize(AxisType along, int index);
00109   void smooth(AxisType along, int index);
00110   double smoothInvalidCells(AxisType along, int index,
00111                             double invalidValue, double sigma2,
00112                             double RVal, bool modify);
00113   void printValues(AxisType along, int index);
00114   double * iterator(AxisType along, int index, int &di, int& n) const;
00115   /* Get values of a row or a column of the grid as a Curve object
00116       Return a row if along X_Axis, a column if along YAxis **/
00117   Curve<Point2D> crossSection(AxisType axis, int ixy) const;
00118   Curve<Point2D> crossSection(Segment2D seg, double deltaX=0) const;
00119   Curve<Point2D> crossSection(const Curve<Point2D>& path, double deltaX=0) const;
00120   Curve<Point2D> integralCrossSection(AxisType axis,int index) const;
00121   template <class CurveClass, class PointClass> CurveClass followMaximumX() const;
00122   template <class CurveClass, class PointClass> CurveClass followMaximumX(int ixMin, int ixMax, int iyMax) const;
00123   template <class CurveClass, class PointClass> void followMaximumX(CurveClass& curve, double min, double max) const;
00124   template <class CurveClass, class PointClass> CurveClass followMaximumY() const;
00125   template <class CurveClass, class PointClass> CurveClass followMaximumY(int iyMin, int iyMax, int ixMax) const;
00126   template <class CurveClass, class PointClass> void followMaximumY(CurveClass& curve, double min, double max) const;
00127   // Geometries of cells
00128   double width(int ix) const {return widthOrHeight(_x, _nx,ix);}
00129   double height(int iy) const {return widthOrHeight(_y, _ny,iy);}
00130   double left(int ix) const {return leftOrBottom(_x, _nx,ix);}
00131   double right(int ix) const {return rightOrTop(_x, _nx,ix);}
00132   double bottom(int iy) const {return leftOrBottom(_y, _ny,iy);}
00133   double top(int iy) const {return rightOrTop(_y, _ny,iy);}
00134 private:
00135   // Init number of cells rounded to power of 2
00136   void initLookup();
00137   int indexOf(double * axis, int n, int n2, double xory) const;
00138   // Convert an axis type into its pointer and number of values
00139   double * getAxis(AxisType axis, int& n) const;
00140   // General geometries of cells
00141   double leftOrBottom(double * axis, int n, int ival) const;
00142   double rightOrTop(double * axis, int n, int ival) const;
00143   double widthOrHeight(double * axis, int n, int ival) const;
00144 
00145   // Values at each grid node
00146   double *_values;
00147   // Vector of x coordinades of nodes
00148   double * _x;
00149   // Vector of y coordinades of nodes
00150   double * _y;
00151   // Number of cells in Y direction
00152   int _ny;
00153   // Number of cells in X direction
00154   int _nx;
00155   // Number of cells in Y direction rounded to next power of 2, used for fast lookup
00156   int _n2y;
00157   // Number of cells in X direction rounded to next power of 2, used for fast lookup
00158   int _n2x;
00159 };
00160 
00161 inline double IrregularGrid2DData::value(int ix, int iy) const
00162 {
00163   return(_values[iy*_nx+ix]);
00164 }
00165 
00166 inline void IrregularGrid2DData::setValue(int ix, int iy, double val)
00167 {
00168   _values[iy*_nx+ix]=val;
00169 }
00170 
00171 inline const double * IrregularGrid2DData::valuePointer(int ix, int iy) const
00172 {
00173   return _values+(iy*_nx+ix);
00174 }
00175 
00176 inline double * IrregularGrid2DData::valuePointer(int ix, int iy)
00177 {
00178   return _values+(iy*_nx+ix);
00179 }
00180 
00181 inline Point2D IrregularGrid2DData::coordinates(int ix, int iy) const
00182 {
00183   return Point2D(_x[ix],_y[iy]);
00184 }
00185 
00186 inline void IrregularGrid2DData::init(int nx, int ny, double value)
00187 {
00188   init(nx, ny);
00189   init(value);
00190 }
00191 
00192 template <class CurveClass, class PointClass>
00193 CurveClass IrregularGrid2DData::followMaximumX() const
00194 {
00195   TRACE;
00196   CurveClass curve;
00197   if(_nx==0 || _ny==0) return curve;
00198   // Search the maximum value of grid
00199   int ix, iy;
00200   maximumValue(ix, iy);
00201   curve.append(followMaximumX<CurveClass,PointClass>(ix, _nx-1, iy));
00202   curve.append(followMaximumX<CurveClass,PointClass>(ix, 0, iy));
00203   curve.setFunction();
00204   return curve;
00205 }
00206 
00207 template <class CurveClass, class PointClass>
00208 CurveClass IrregularGrid2DData::followMaximumX(int ixMin, int ixMax, int iyMax) const
00209 {
00210   TRACE;
00211   CurveClass curve;
00212   curve.append(PointClass(x(ixMin), y(iyMax)));
00213   int dx=ixMin<ixMax ? 1 : -1;
00214   ixMax+=dx;
00215   for(int i=ixMin;i!=ixMax;i+=dx) {
00216     Curve<Point2D> cs=crossSection(YAxis, i);
00217     iyMax=cs.closestMax(iyMax);
00218     curve.append(PointClass(x(i), y(iyMax)));
00219     curve.last().setValid(true);
00220   }
00221   return curve;
00222 }
00223 
00224 template <class CurveClass, class PointClass>
00225 void IrregularGrid2DData::followMaximumX(CurveClass& curve, double min, double max) const
00226 {
00227   TRACE;
00228   ASSERT(nx()>1); // Needed by Curve::indexAfter()
00229   ASSERT(ny()>1); // Needed by Curve::indexAfter()
00230   curve.resample(x(), Function);
00231   for(int i=0;i<_nx;i++ ) {
00232     if(min<=x(i) && x(i)<=max) {
00233       int curveIndex=curve.indexAfter(x(i));
00234       PointClass& p=curve[curveIndex];
00235       Curve<Point2D> cs=crossSection(YAxis, i);
00236       int iMax=cs.closestMax(cs.indexAfter(p.y()));
00237       p.setY(y(iMax));
00238       p.setValid(true);
00239     }
00240   }
00241 }
00242 
00243 template <class CurveClass, class PointClass> CurveClass IrregularGrid2DData::followMaximumY() const
00244 {
00245   CurveClass curve;
00246   if(_nx==0 || _ny==0) return curve;
00247   // Search the maximum value of grid
00248   int ix, iy;
00249   maximumValue(ix, iy);
00250   curve.append(followMaximumY<CurveClass,PointClass>(iy, _ny-1, ix));
00251   curve.append(followMaximumY<CurveClass,PointClass>(iy, 0, ix));
00252   curve.setFunction();
00253   return curve;
00254 }
00255 
00256 template <class CurveClass, class PointClass> CurveClass IrregularGrid2DData::followMaximumY(int iyMin, int iyMax, int ixMax) const
00257 {
00258   CurveClass curve;
00259   curve.append(PointClass(y(iyMin), x(ixMax)));
00260   int dy=iyMin<iyMax ? 1 : -1;
00261   iyMax+=dy;
00262   for(int i=iyMin;i!=iyMax;i+=dy) {
00263     Curve<Point2D> cs=crossSection(XAxis, i);
00264     ixMax=cs.closestMax(ixMax);
00265     curve.append(PointClass(y(i), x(ixMax)));
00266     curve.last().setValid(true);
00267   }
00268   return curve;
00269 }
00270 
00271 template <class CurveClass, class PointClass> void IrregularGrid2DData::followMaximumY(CurveClass& curve, double min, double max) const
00272 {
00273   ASSERT(nx()>1); // Needed by Curve::indexAfter()
00274   ASSERT(ny()>1); // Needed by Curve::indexAfter()
00275   curve.resample(y(), Function);
00276   for(int i=0;i<_ny;i++ ) {
00277     if(min<=y(i) && y(i)<=max) {
00278       int curveIndex=curve.indexAfter(y(i));
00279       PointClass& p=curve[curveIndex];
00280       Curve<Point2D> cs=crossSection(XAxis, i);
00281       int iMax=cs.closestMax(cs.indexAfter(p.y()));
00282       p.setY(x(iMax));
00283       p.setValid(true);
00284     }
00285   }
00286 }
00287 
00288 } // namespace QGpCoreTools
00289 
00290 Q_DECLARE_OPERATORS_FOR_FLAGS(QGpCoreTools::AxisTypes)
00291 
00292 #endif // IRREGULARGRID2DDATA.H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines