# -*- coding: utf-8 -*-
"""
GeophPy.datasetbase
-------------------
DataSet base Object constructor and methods.
:copyright: Copyright 2014-2020 L. Darras, P. Marty, Q. Vitale and contributors, see AUTHORS.
:license: GNU GPL v3.
"""
from __future__ import absolute_import
import os
import geophpy.filesmanaging.files as iofiles
import geophpy.geopositioning.general as gengeopositioning
import geophpy.geopositioning.kml as kml
import geophpy.geopositioning.raster as raster
# import geophpy.filesmanaging as io
import geophpy.geoposset as geopos
import geophpy.operation.general as genop
#import geophpy.plotting.colormap as colormap
import geophpy.plotting.correlation as correlation
import geophpy.plotting.destriping as destriping
import geophpy.plotting.histo as histo
import geophpy.plotting.plot as plot
import geophpy.plotting.spectral as spectral
#import geophpy.processing.general as genproc
#import geophpy.processing.magnetism as magproc
from geophpy.filesmanaging.files import FILE_FORMAT_DICT, FORMAT_LIST
# ---------------------------------------------------------------------------#
# Information about DataSet Object #
# ---------------------------------------------------------------------------#
[docs]class Info:
""" Class to store grid information.
Attributes
----------
x_min : float
Grid minimum x values.
x_max : float
Grid maximum x values.
y_min : float
Grid minimum y values.
y_max : float
Grid maximum y values.
z_min : float
Grid minimum z values.
z_max : float
Grid maximum z values.
x_gridding_delta : float
Grid stepsize in the x_direction.
y_gridding_delta : float
Grid stepsize in the y_direction.
gridding_interpolation : str
Interpolation method used for gridding.
plottype : str
Grid plot type.
cmapname : str
Grid plot colormap name.
"""
## def __init__(self, xmin=None, xmax=None, ymin=None, ymax=None, zmin=None ,zmax=None, dx=None, dy=None,
## interp=None, plottype ='2D-SURFACE', cmap='Greys'):
## self.x_min = xmin
## self.x_max = xmax
## self.y_min = ymin
## self.y_max = ymax
## self.z_min = zmin
## self.z_max = zmax
## self.x_gridding_delta = dx
## self.y_gridding_delta = dy
## self.gridding_interpolation = interp
## self.plottype = plottype
## self.cmapname = cmap
x_min = None
x_max = None
y_min = None
y_max = None
z_min = None
z_max = None
x_gridding_delta = None
y_gridding_delta = None
gridding_interpolation = None
plottype = (plot.gettypelist())[0]
cmapname = 'Greys'
# ---------------------------------------------------------------------------#
# Fields names and values about DataSet Object #
# ---------------------------------------------------------------------------#
[docs]class Data:
""" Class to store data.
Parameters
----------
fields : list of str
Field names corresponding to the data values ('x', 'y', 'vgrad').
values : array-like
Ungridded data values.
east : array-like
Ungridded data east values.
north : array-like
Ungridded data north values.
z_image : 2-D array-like.
Gridded data values.
easting_image :2-D array-like.
Gridded data easting values.
northing_image :2-D array-like.
Gridded data northing values.
Attributes
----------
fields : list of str
Field names corresponding to the data values ('x', 'y', 'vgrad').
x : array-like
Ungridded data local x-coordinates.
y : array-like
Ungridded data local y-coordinates.
values : array-like
Ungridded data values.
east : array-like
Ungridded data east values.
north : array-like
Ungridded data north values.
tracks : array-like
Ungridded data track number for each data value.
z_image : 2-D array-like.
Gridded data values.
easting_image :2-D array-like.
Gridded data easting values.
northing_image :2-D array-like.
Gridded data northing values.
"""
def __init__(self,
fields=None,
x=None,
y=None,
values=None,
east=None,
north=None,
long=None,
lat=None,
track=None,
z_image=None,
easting_image=None,
northing_image=None):
self.fields = fields
self.x = x
self.y = y
self.values = values
self.east = east
self.north = north
self.long = long
self.long = lat
self.track = track
self.z_image = z_image
self.easting_image = easting_image
self.northing_image = northing_image
# ---------------------------------------------------------------------------#
# Coordinates Object in local and utm referencing #
# ---------------------------------------------------------------------------#
class GeoRefPoint:
def __init__(self, easting=None, northing=None):
self.utm_easting = easting
self.utm_northing = northing
# ---------------------------------------------------------------------------#
# Georeferencing System Object between local and geographic positions #
# ---------------------------------------------------------------------------#
class GeoRefSystem:
active = False # data set georeferencing status
refsystem = None # 'UTM', 'WGS84', ...
utm_zoneletter = None # E -> X
utm_zonenumber = None # 1 -> 60
points_list = [] # list of points, [[num1, lon1 or eastern1, lat1 or northern1, x, y], ...]
# ---------------------------------------------------------------------------#
# DataSet Object #
# ---------------------------------------------------------------------------#
class DataSetBase:
r"""
Base class to create a DataSet Object to process and display data.
Parameters
----------
info : :obj:`~geophpy.datasetbase.Info`
Class containing dataset basic information.
See :obj:`~geophpy.datasetbase.Info`.
data : :obj:`~geophpy.datasetbase.Data`
Class containing dataset data.
See :obj:`~geophpy.datasetbase.Data`.
georef : :obj:`~geophpy.datasetbase.GeoRefSystem`
Class containing georeferencing information.
See :obj:`~geophpy.datasetbase.GeoRefSystem`.
name : None or str
Name of the dataset.
Attributes
----------
info : :obj:`~geophpy.datasetbase.Info`
Class containing dataset basic information.
See :obj:`~geophpy.datasetbase.Info`.
data : :obj:`~geophpy.datasetbase.Data`
Class containing dataset data.
See :obj:`~geophpy.datasetbase.Data`.
georef : :obj:`~geophpy.datasetbase.GeoRefSystem`
Class containing georeferencing information.
See :obj:`~geophpy.datasetbase.GeoRefSystem`.
name : None or str
Name of the dataset.
"""
def __init__(self,
info=Info(),
data=Data(),
georef=GeoRefSystem(),
name=None):
self.info = info
self.data = data
self.georef = georef
self.name = name
# ??? Method to delete int he future ???
@classmethod
def _new(cls):
""" New empty dataset. """
return cls()
@property
def is_georef(self):
""" Return True is dataset has easting and northing values. """
return self.data.east is not None and self.data.north is not None
# ---------------------------------------------------------------------------#
# DataSet file management #
# ---------------------------------------------------------------------------#
@classmethod
def from_file(cls,
filenameslist,
fileformat=None,
delimiter=None,
x_colnum=1,
y_colnum=2,
z_colnum=3,
skipinitialspace=True,
skip_rows=0,
fields_row=1,
verbose=False):
""" Build a DataSet Object from a file.
Parameters:
:filenameslist: list of files to open
['file1.xyz', 'file2.xyz' ...]
or
['file*.xyz'] to open all files with filename beginning by "file" and ending by ".xyz"
:fileformat: format of files to open (None by default implies automatic determination from filename extension)
Note: all files must have the same format
:delimiter: pattern delimiting fields within one line (e.g. '\t', ',', ';' ...)
:x_colnum: column number of the X coordinate of the profile (1 by default)
:y_colnum: column number of the Y coordinate inside the profile (2 by default)
:z_colnum: column number of the measurement profile (3 by default)
:skipinitialspace: if True, several contiguous delimiters are equivalent to one
:skip_rows: number of rows to skip at the beginning of the file, i.e. total number of header rows (1 by default)
:fields_row: row number where to read the field names ; if -1 then default field names will be "X", "Y" and "Z"
Returns:
:success: true if DataSet Object built, false if not
:dataset: DataSet Object build from file(s) (empty if any error)
Example:
success, dataset = DataSet.from_file("file.csv")
"""
# Conversion to list for eventual single file name
if isinstance(filenameslist, str):
filenameslist = [filenameslist]
# Dispatch method
class From:
@staticmethod
def ascii():
return iofiles.from_ascii(dataset,
filenameslist,
delimiter=delimiter,
x_colnum=x_colnum,
y_colnum=y_colnum,
z_colnum=z_colnum,
skipinitialspace=skipinitialspace,
skip_rows=skip_rows,
fields_row=fields_row)
@staticmethod
def netcdf():
return iofiles.from_netcdf(dataset,
filenameslist,
x_colnum=x_colnum,
y_colnum=y_colnum,
z_colnum=z_colnum)
@staticmethod
def surfer():
return iofiles.from_grd(dataset,
filenameslist,
gridtype=None)
@staticmethod
def uxo():
return iofiles.from_uxo(dataset,
filenameslist)
dataset = cls()
# Format from file extension
if fileformat is None:
ext = os.path.splitext(filenameslist[0])[1]
fileformat = 'ascii' # default format
if verbose:
print('Determining file format from extension "{}" ...'.format(ext))
if ext in FILE_FORMAT_DICT:
fileformat = FILE_FORMAT_DICT[ext][1]
if verbose:
print('{0} format found for extension "{1}" ...'.format(fileformat, ext))
# Read the data from input file
if fileformat in FORMAT_LIST:
if verbose:
print('... Reading file using "{}" file format'.format(fileformat))
readfile = getattr(From, fileformat)
error = readfile()
else:
if verbose:
print('Undefined file format'.format(fileformat))
# Undefined file format
# ...TBD... raise an error here !
error = 1
# Error code
print()
success = not bool(error)
return success, dataset
def to_file(self,
filename,
fileformat=None,
delimiter='\t',
description=None,
gridtype='surfer7bin',
verbose=False,
ignore_nodata=True):
""" Save a DataSet Object to a file.
Parameters
----------
filename : str
Name of file to save.
fileformat : {"ascii", "netcdf", "surfer", "uxo", "cmd"}
Format for the output file.
If None (by default), the fileformat will automatically by determined from filename extension.
delimiter : {"\t", ",", ";"}, optional
Delimiter of the output file when fileformat is 'ascii'.
By default "\t".
gridtype : {'surfer7bin', 'surfer6bin', 'surfer6ascii'}, optional
Format for the surfer grid file when fileformat is 'surfer'.
By default 'surfer7bin'.
description : str
Description of the output file when fileformat is 'netcdf'.
By default 'None'.
ignore_nodata : bool, optional
Flag to ignore when saving the file. Default is True.
Returns
-------
success : bool
True if the file was written successfully, False otherwise.
"""
# Dispatch method
class To:
@staticmethod
def ascii():
return iofiles.to_ascii(self,
filename,
delimiter=delimiter,
ignore_nodata=ignore_nodata)
@staticmethod
def netcdf():
return iofiles.to_netcdf(self,
filename,
description=description)
@staticmethod
def surfer():
return iofiles.to_grd(self,
filename,
gridtype=gridtype)
@staticmethod
def uxo():
return iofiles.to_uxo(self, filename)
# Choose the dataset format
if fileformat is None:
# Format from file extension
ext = os.path.splitext(filename)[1]
if verbose:
print('Determining file format from extension "{}" ...'.format(ext))
if ext in FILE_FORMAT_DICT:
fileformat = FILE_FORMAT_DICT[ext][1]
else:
fileformat = None
if verbose:
print('{0} format found for extension "{1}" ...'.format(fileformat, ext))
# Write the dataset to file
if fileformat in FORMAT_LIST:
if verbose:
print('writting file using "{}" format " ...'.format(fileformat))
writefile = getattr(To, fileformat)
error = writefile()
else:
# Undefined file format
# ...TBD... raise an error here !
error = 1
# Return error code
if error == 0:
return True
return False
def to_dict(self):
''' Return dataset data as a dictionary. '''
dic = vars(self.data).copy()
dic['name'] = self.name
dic['crs'] = self.georef.refsystem
#dic['values'] = self.data.values[:, -1]
return dic
# ---------------------------------------------------------------------------#
# DataSet Plotting #
# ---------------------------------------------------------------------------#
def plot(self,
plottype='2D-SCATTER',
cmapname=None,
creversed=False,
fig=None,
filename=None,
cmmin=None,
cmmax=None,
interpolation='bilinear',
levels=100,
cmapdisplay=True,
axisdisplay=True,
labeldisplay=True,
pointsdisplay=False,
dpi=None,
transparent=False,
logscale=False,
rects=None,
points=None,
marker='+',
markersize=None): # replacing with **kwargs
""" 2D representation of the dataset.
Parameters
----------
plottype : str, {'2D-SCATTER', '2D-SURFACE', '2D-CONTOUR', '2D-CONTOURF', '2D-POSTMAP'}
Plot type for the data representation.
Plot type can be
``2D-SCATTER``
(by default) ungridded data values are dispay in a scatter plot.
Plot type 'SCATTER', 'SCAT' and 'SC' are also recognised.
``2D-SURFACE``
Gridded data values are dispay in a surface (image) plot.
Plot type 'SURFACE', 'SURF' and 'SF' are also recognised.
``2D-CONTOUR``
Gridded data values are dispay in a UNFILLED contour plot.
If this plot type is used, you can specify the number of
contours used with the ``levels`` keyword.
Plot type 'CONTOUR', 'CONT' and 'CT' are also recognised.
``2D-CONTOURF``
Gridded data values are dispay in a FILLED contour plot.
If this plot type is used, you can specify the number of
contours used with the ``levels`` keyword.
Plot type 'CONTOURF', 'CONTF' and 'CF' are also recognised.
``2D-POSTMAP``
Ungridded data position are dispay in a scatter plot.
It is different from the '2D-SCATTER' plot because
the data value is not represented (all point have the same color).
Plot type 'POSTMAP', 'POST' and 'PM' are also recognised.
cmapname : str
Name of the color map to be used 'gray' for example.
To use a reversed colormap, add '_r' at the end of the colormap name ('gray_r')
or set ``creversed`` to ``True``.
creversed : bool
Flag to add '_r' at the end of the color map name to reverse it.
fig : Matplotlib figure object
Figure to plot, None by default to create a new figure.
If a figure object is provided, it wiil be cleared before displaying the current data.
filename : str or None
Name of file to save the figure, None (by default).
cmmin : scalar
Minimal value to display in the color map range.
cmmax : scalar
Maximal value to display in the color map range.
interpolation : str,
Interpolation method used for the pixel interpolation ('bilinear' by default).
If interpolation is 'none', then no interpolation is performed for the display.
Supported values are 'none', 'nearest', 'bilinear', 'bicubic',
'spline16', 'spline36', 'hanning', 'hamming', 'hermite', 'kaiser',
'quadric', 'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc', 'lanczos'.
levels : (int or array-like)
Determines the number and positions of the contour lines / regions.
If an int n, use n data intervals; i.e. draw n+1 contour lines. The level heights are automatically chosen.
If array-like, draw contour lines at the specified levels. The values must be in increasing order.
cmapdisplay : bool
True to display colorbar, False to hide the colorbar.
axisdisplay : bool
True to display axis (and their labels), False to hide axis (and labels).
labeldisplay : bool
True to display labels on axis, False to hide labels on axis.
pointsdisplay : bool
True to display grid points.
dpi : int or None
Definition ('dot per inch') to use when saving the figure into a file (None by default).
transparent : bool
Flag to manage transparency when saving the figure into a file (False by default).
logscale : bool
Flag to use a logarithmic color scale.
rects: None or array_like
Coordinates of additional rectanngles to display:
[[x0, y0, w0, h0], [x1, y1, w1, h1], ...].
None by default.
points: None or array_like
Coordinates of additional points to display:
[[x0, y0], [x1, y1], ...]. None by default.
marker: str
Matplotlib marker style for data point display.
markersize: scalar
Size for the marker for data point display.
Returns
-------
fig : Matplotlib Figure Object
Dataset map figure.
cmap : Matplotlib ColorBar Object
Colorbar associated with the figure if ``cmapdisplay`` is ``True``, ``None`` otherwise.
"""
# Updating dataset colormap name
if cmapname is None:
cmapname = self.info.cmapname
self.info.cmapname = cmapname
return plot.plot(self, plottype, cmapname, creversed=creversed, fig=fig, filename=filename, cmmin=cmmin,
cmmax=cmmax, interpolation=interpolation, levels=levels, cmapdisplay=cmapdisplay,
axisdisplay=axisdisplay, labeldisplay=labeldisplay, pointsdisplay=pointsdisplay, dpi=dpi,
transparent=transparent, logscale=logscale, rects=rects, points=points, marker=marker,
markersize=markersize)
def plot_surface(self,):
""" 2D representation of the dataset. """
def plot_scatter(self, **kwargs):
""" 2D representation of the ungridded data values in a scatter plot.
Parameters
----------
**kwargs :
Additional keyword arguments for display options.
see :meth:`~geophpy.dataset.DataSet.plot` for details.
Returns
-------
fig : Matplotlib Figure Object
Dataset map figure.
cmap : Matplotlib ColorBar Object
Colorbar associated with the figure if ``cmapdisplay`` is ``True``, ``None`` otherwise.
"""
return plot.plot(self, '2D-SCATTER', kwargs.get('cmapname', 'Greys'), **kwargs)
def plot_postmap(self,):
""" 2D representation of the dataset. """
def plot_contour(self,):
""" 2D representation of the dataset. """
def plot_contourf(self,):
""" 2D representation of the dataset. """
def histo_getlimits(self, valfilt=False):
""" Return the data min and max values.
Parameters
----------
valfilt : bool
If True, min and max are taken from data values.
Otherxise, min and max are taken from data z_image.
Returns
-------
zmin, zmax : float
Data min and max values.
"""
return histo.getlimits(self, valfilt=valfilt)
###
###
##
# TO IMPLEMENT in the next version
##
###
## def histo_fit(self):
## ''' '''
## return
### Change name to plot_histo
def histo_plot(self, fig=None, filename=None, zmin=None, zmax=None, cmapname=None, creversed=False, cmapdisplay=False,
coloredhisto=True, showtitle=True, dpi=None, transparent=False, valfilt=False):
""" Plot the dataset histogram.
Parameters
----------
fig : Matplotlib figure object
Figure to use for the plot, None (by default) to create a new figure.
filename : str or None
Name of file to save the figure, None (by default).
zmin, zmax : float or None
Minimal and maximal values to represent.
cmapname : str
Name of the color map to be used 'gray' for example.
To use a reversed colormap, add '_r' at the end of the colormap name ('gray_r')
or set ``creversed`` to ``True``.
creversed : bool
Flag to add '_r' at the end of the color map name to reverse it.
cmapdisplay : bool
Flag to display a color bar (True by default).
coloredhisto : bool
Flag to color the histogram using the given colormap (True by default). If False, black will be used.
showtitle : bool
Flag to display the dataset name as title (True by default).
dpi : int or None
Definition ('dot per inch') to use when saving the figure into a file (None by default).
transparent : bool
Flag to manage transparency when saving the figure into a file (False by default).
valfilt : bool
If set to True, the :func:`~geophpy.dataset.DataSet.data.values`
are filtered instead of the :func:`~geophpy.dataset.DataSet.data.z_image`
(False By default).
Returns
-------
fig : Matplotlib Figure Object
Dataset histogram figure.
cmap : Matplotlib ColorBar Object
Colorbar associated with the figure if ``cmapdisplay`` is ``True``, ``None`` otherwise.
"""
# Updating dataset colormap name
if cmapname is None:
cmapname = self.info.cmapname
self.info.cmapname = cmapname
return histo.plot(self, fig=fig, filename=filename, zmin=zmin, zmax=zmax, cmapname=cmapname, creversed=creversed,
cmapdisplay=cmapdisplay, coloredhisto=coloredhisto, showtitle=showtitle, dpi=dpi, transparent=transparent,
valfilt=valfilt)
### Change name to plot_corrmap
def correlation_plotmap(self, method="Crosscorr", cmapname='jet',
fig=None, filename=None, dpi=None, transparent=False, showenvelope=False, cmapdisplay=True):
""" Plot profile-to-profile correlation map.
Parameters
----------
method : str, {'Crosscorr', 'Pearson', 'Spearman' or 'Kendall'}
Correlation method.
cmapname : str or None
Name of the color map to be used, 'gray_r' for example.
fig : Matplotlib figure object
Figure to use for the plot, None (by default) to create a new figure.
filename : str or None
Name of the file to save the figure, None (by default).
dpi : int or None
Definition ('dot per inch') to use when saving the figure into a file (None by default).
transparent : bool
Flag to manage transparency when saving the figure into a file (False by default).
showenvelope : bool
Flag to display the correlation map envelope.
cmapdisplay : bool
Flag to display a color bar (True by default).
Returns
-------
fig : Matplotlib Figure Object
Dataset profile-to-profile correlation map.
"""
return correlation.plotmap(self, method=method, cmapname=cmapname, fig=fig, filename=filename,
dpi=dpi, transparent=transparent, showenvelope=showenvelope)
### Change name to plot_corrsum
def correlation_plotsum(self, fig=None, filename=None, method='Crosscorr', dpi=None, transparent=False,
showenvelope=False, showfit=False):
"""
Plot correlation sum.
Parameters
----------
fig : Matplotlib figure object
Figure to use for the plot, None (by default) to create a new figure.
filename : str or None
Name of the file to save the figure, None (by default).
method : str, {'Crosscorr', 'Pearson', 'Spearman' or 'Kendall'}
Correlation method.
transparent : bool
Flag to manage transparency when saving the figure into a file (False by default).
(False By default).
showenvelope : bool
Flag to display the curve envelope.
showfit : bool
Flag to display the curve gausian beest fit.
Returns
-------
fig : Matplotlib Figure Object
Dataset profile-to-profile correlation sum.
"""
return correlation.plotsum(self, fig=fig, filename=filename,
method=method, dpi=dpi, transparent=transparent,
showenvelope=showenvelope, showfit=showfit)
### Change name to plot_meantrack
def meantrack_plot(self, fig=None, filename=None, Nprof=0, setmin=None, setmax=None,
method='additive', reference='mean', config='mono', Ndeg=None,
plotflag='raw', dpi=None, transparent=False):
"""
Plot the dataset mean cross-track profile before and after destriping.
Parameters :
:fig: figure to plot, None by default to create a new figure. `matplotlib.figure.Figure`
:filename: Name of the histogram file to save, None if no file to save.
:Nprof: number of profiles to compute the reference mean
:setmin: float, While computing the mean, do not take into account data values lower than *setmin*.
:setmax: float, While computing the mean, do not take into account data values greater than *setmax*.
:method: destriping method (additive or multiplicative)
:reference: destriping reference (mean and standard deviation or median and interquartile range)
:config: destriping configuration ('mono' sensor: only offset matching (mean / median), 'multi' sensor: both offset and gain (standard deviation/interquartile range))
:plotflag: str, {'raw', 'destriped', 'both'} to plot raw, destriped or both data
:Ndeg: polynomial degree of the curve to fit
:transparent: True to manage the transparency.
Returns :
:fig: Figure Object
Note
----
The mean cross-track profile is the profile composed the mean of each
profile in the dataset.
"""
return destriping.plot_mean_track(self, fig=fig, filename=filename, Nprof=Nprof, setmin=setmin, setmax=setmax,
method=method, reference=reference, config=config, Ndeg=Ndeg, plotflag=plotflag,
dpi=dpi, transparent=transparent)
def plot_track(self,n='all', fig=None, filename=None, prof=0, setmin=None, setmax=None, dpi=None, transparent=False):
""" Plot the dataset track n.
"""
return spectral.plotmap(self, fig=fig, filename=filename, dpi=dpi, plottype=plottype, logscale=logscale,
cmapdisplay=cmapdisplay, axisdisplay=axisdisplay, lines=lines)
### Change name to plot_sprectum
def spectral_plotmap(self, fig=None, filename=None, dpi=None, plottype='magnitude', logscale=False, cmapdisplay=True,
axisdisplay=True, lines=None):
"""
Plot the dataset 2-D Fourier Transform.
Paramters
---------
fig : figure to plot,
Figure used for the plot. None by default to create a new figure.
filename : str
Name of the file to save the figure. None (default) if no file to save.
dpi : int
'dot per inch' definition of the picture file if filename is not None.
plottype : str {'magnitude' or 'amplitude','power',phase','real','imag'}
Spectrum composante to plot.
logscale : bool
True for a plot with a logarithmic colorscale.
cmapdisplay : bool
True to display a colorbar.
axisdisplay : bool
True to display axis, False to hide the axis.
"""
return spectral.plotmap(self, fig=fig, filename=filename, dpi=dpi, plottype=plottype, logscale=logscale,
cmapdisplay=cmapdisplay, axisdisplay=axisdisplay, lines=lines)
def plot_directional_filter(self, cmapname=None, creversed=False, fig=None, filename=None, dpi=None, cmapdisplay=True,
axisdisplay=True, paramdisplay=False, cutoff=100, azimuth=0, width=2):
"""
Plot the dataset 2-D directional filter.
Paramters
---------
cmapname : str
Name of the color map to be used, 'gray_r' for example.
creversed : bool
True to reverse the color map (add '_r' at the cmapname).
fig : figure to plot,
Figure used for the plot. None by default to create a new figure.
filename : str
Name of the file to save the figure. None (default) if no file to save.
dpi : int
'dot per inch' definition of the picture file if filename is not None.
cmapdisplay : bool
True to display colorbar, False to hide the colorbar.
axisdisplay : bool
True to display axis, False to hide the axis.
axisdisplay : bool
True to display filter parameter in the title.
shape : tuple
Filter shape.
cutoff : ndarray
Input array to filter.
azimuth : scalar
Directional filter azimuth angle in degree.
width : integer
Gaussian filter cutoff frequency.
Returns
-------
fig : Matplotlib Figure Object
cmap : Matplotlib ColorMap Object
"""
return spectral.plot_directional_filter(self, cmapname=cmapname, creversed=creversed, fig=fig, filename=filename,
dpi=dpi, cmapdisplay=cmapdisplay, axisdisplay=axisdisplay,
paramdisplay=paramdisplay,
cutoff=cutoff, azimuth=azimuth, width=width)
# ---------------------------------------------------------------------------#
# DataSet Operations #
# ---------------------------------------------------------------------------#
def copy(self):
"""
To duplicate a DataSet Object.
Parameters:
:dataset: DataSet Object to duplicate
Returns:
:newdataset: duplicated DataSet Object
"""
return genop.copy(self)
def interpolate(self, interpolation='none', x_step=None, y_step=None, x_prec=2, y_prec=2, x_frame_factor=0.,
y_frame_factor=0.):
""" Dataset gridding.
Parameters
----------
interpolation : str {'none', 'nearest', 'linear', 'cubic'}
Method used to grid the dataset. Can be:
``none``
(by default) simply projects raw data on a regular grid without interpolation.
Holes are filled with NaNs and values falling in the same grid cell are averaged.
``nearest``
return the value at the data point closest to
the point of interpolation.
``linear``
tesselate the input point set to n-dimensional
simplices, and interpolate linearly on each simplex.
``cubic``
return the value determined from a
piecewise cubic, continuously differentiable (C1), and
approximately curvature-minimizing polynomial surface.
x_step, y_step : float or None
Gridding step in the x and y direction.
Use None (by default) to estimate the median x- and y-step from data values.
x_prec, y_prec : int or None
Decimal precision to keep for the grid computation.
None (by default) to use the maximal number of decimal present in the data values coordinates.
x_frame_factor :
Frame extension coefficient along x axis (e.g. 0.1 means xlength +10% on each side, i.e. xlength +20% in total) ; pixels within extended borders will be filled with "nan"
y_frame_factor :
Frame extension coefficient along y axis (e.g. 0.45 means yheight +45% top and bottom, i.e. yheight +90% in total) ; pixels within extended borders will be filled with "nan"
Returns
-------
Gridded DataSet object.
"""
return genop.interpolate(self, interpolation=interpolation, x_step=x_step, y_step=y_step, x_prec=x_prec,
y_prec=y_prec, x_frame_factor=x_frame_factor, y_frame_factor=y_frame_factor)
def sample(self):
""" Re-sample data at ungridded sample position from gridded Z_image.
Re-sample ungridded values from gridded Z_image using a
cubic spline spline interpolation.
"""
return genop.sample(self)
def regrid(self, x_step=None, y_step=None, method='cubic'):
""" Dataset re-gridding.
During regridding, a copy of the dataset is re-sampled
(see :meth:`~geophpy.dataset.DataSet.sample`)
and interpolated with the given x and y-steps.
Parameters
----------
x_step, y_step : float or None
Gridding step in the x and y direction.
Use None (by default) to resample current grid by a factor 2 (step_new = step_old*0.5).
method : str {'cubic', 'nearest', 'linear'}
Method used to re-grid the dataset. see :meth:`~geophpy.dataset.DataSet.interpolate`
Returns
-------
Re-gridded DataSet object.
Note
----
Only the grid is affected and the ungriddedd data values are kept unchanged.
to propagate a change in the ungriddedd data values,
you may want to use the filters ``valfilt`` keyword or the association of
:meth:`~geophpy.dataset.DataSet.sample` and
:meth:`~geophpy.dataset.DataSet.sample`.
See Also
--------
sample, interpolate
"""
return genop.regrid(self, x_step=None, y_step=None, method='cubic')
def stats(self, valfilt=True, valmin=None, valmax=None):
"""
Computes the dataset basic statistics.
Parameters:
:dataset: DataSet Object from which to compute stats.
:valfilt: if set to True, computes on data.values instead of data.z_image.
:valmin, valmax: Consider only data values between valmin and valmax.
Returns:
:mean, std, median: array arithmetic mean, standard deviation and median.
:Q1, Q3: dataset 1st and 3rd quartiles (25th and 75th percentiles).
:IQR: dataset interquartile range (Q3 - Q1).
"""
return genop.stats(self, valfilt=valfilt, valmin=valmin, valmax=valmax)
def add(self, val=0, valfilt=True, zimfilt=True):
"""
Add a constant to the dataset Values and Z_image.
Parameters:
:val: constant to add.
:valfilt: flag to add constant on dataset values.
:zimfilt: flag to add constant on dataset z_image.
"""
return genop.add_constant(self, constant=val, valfilt=valfilt, zimfilt=zimfilt)
def times(self, val=1, valfilt=True, zimfilt=True):
"""
Multiply by a constant the dataset Values and Z_image
Parameters:
:val: constant to multiply by.
:valfilt: flag to add constant on dataset values.
:zimfilt: flag to add constant on dataset z_image.
"""
return genop.times_constant(self, constant=val, valfilt=valfilt, zimfilt=zimfilt)
def setmedian(self, median=None, method='additive'):
"""
Set the dataset values and Z_image to a given value
(for instance zero for zero median surveys).
Parameters:
:median: target value to set the dataset median to.
:method: method used to set the median ('additive' or 'multiplicative').
:profilefilter: ...TBD... True: set each survey profiles median to 'median'.
False: set the global survey median to 'median'.
"""
return genop.setmedian(self, median=median, method=method)
def setmean(self, mean=None, method='additive'):
"""
Set the dataset values and Z_image to a given value
(for instance zero for zero median surveys).
Parameters:
:mean: value to set the dataset mean to.
:method: method used to set the mean ('additive' or 'multiplicative').
:profilefilter: ...TBD... True: set each survey profiles mean to 'mean'.
False: set the global survey mean to 'mean'.
"""
return genop.setmean(self, mean=mean, method=method)
def translate(self, shiftx=0, shifty=0):
"""
Dataset translation.
Parameters:
:shiftx: Constant to apply to the x-abscisse.
:shifty: Constant to apply to the y-abscisse.
Returns:
Translated DataSet object.
"""
return genop.translate(self, shiftx=shiftx, shifty=shifty)
def rotate(self, angle=0, center=None):
"""
Dataset rotation (clockwise).
Parameters
----------
angle: float
Rotation angle (in °).
center: str {None, 'BL', 'BR', 'TL, 'TR'}
Center of rotation: 'BL', 'BR', 'TL and 'TR' for bottom left,
bottom rght, top left and top right corner.
If None, the dataset centroid will be used.
Returns:
Rotated DataSet object.
"""
return genop.rotate(self, angle=angle, center=center)
## def matchedges(self, datasets, matchmethod='equalmedian', setmed=None, valfilt=True, setmethod='additive'):
## '''
## '''
## return genop.matchedges(datasets, matchmethod=matchmethod, setmed=setmed, valfilt=valfilt, setmethod=setmethod)
# staticmethod
# def merge(datasetlist, matchmethod=None, setval=None, setmethod='additive', meanrange=None):
def merge(self, datasets, matchmethod=None, setval=None, setmethod='additive', meanrange=None):
"""
Merge datasets together.
Parameters
----------
datasetlist : tuple or list.
Sequence of datasets to merge. Each DataSet Object must have the same coordinates system.
matchmethod :
setmethod : {'additive', 'multiplicative'}
Method used to merge the datasets ## TODO Complete docstring.
setval :
meanrange :
Returns
-------
merged : new DataSet Object.
"""
# Empty Merge DataSet
datasetout = DataSetBase._new()
genop.merge(datasetout, datasets, matchmethod=matchmethod, setval=setval, setmethod=setmethod, meanrange=meanrange)
return datasetout
# ---------------------------------------------------------------------------#
# DataSet Coordinates/values #
# ---------------------------------------------------------------------------#
def get_xgrid(self):
""" Return dataset x-coordinate matrix of the Z_image. """
return genop.get_xgrid(self)
def get_ygrid(self):
""" Return dataset y-coordinate matrix of the Z_image. """
return genop.get_ygrid(self)
def get_xygrid(self):
""" Return dataset x- and y-coordinate matrices of the Z_image. """
return genop.get_xygrid(self)
def get_grid_values(self):
""" Return dataset Z_image. """
return self.data.z_image
def get_gridcorners(self):
""" Return dataset grid corners coordinates.
Returns ``None`` if no interpolation was made.
Use :meth:~geophpy.dataset.DataSet.get_boundingbox`
to get the ungridded data values' bounding box.
"""
return genop.get_gridcorners(self)
def get_gridextent(self):
""" Return dataset grid extent. """
return genop.get_gridextent(self)
def get_xvect(self):
""" Return dataset x-coordinate vector of the Z_image. """
return genop.get_xvect(self)
def get_yvect(self):
""" Return dataset y-coordinate vector of the Z_image. """
return genop.get_yvect(self)
def get_xyvect(self):
""" Return dataset x- and y-coordinate vectors of the Z_image. """
return genop.get_xyvect(self)
def get_xvalues(self):
""" Return the x-coordinates from the dataset values. """
return genop.get_xvalues(self)
def get_yvalues(self):
""" Return the y-coordinates from the dataset values. """
return genop.get_yvalues(self)
def get_values(self):
""" Return the dataset values. """
return genop.get_values(self)
def get_xyvalues(self):
""" Return the x- and y-coordinates from the dataset values. """
return genop.get_xyvalues(self)
def get_xyzvalues(self):
""" Return both the x, y-coordinates and dataset ungridded values. """
return genop.get_xyzvalues(self)
def get_boundingbox(self):
""" Return the coordinates (BL, BR, TL, TR) of the box bouding the data values. """
return genop.get_boundingbox(self)
def get_median_xstep(self, prec=2):
""" Return the median step between two distinct x values rounded to the given precision. """
return genop.get_median_xstep(self, prec=prec)
def get_median_ystep(self, prec=2):
""" Return the median step between two distinct y values rounded to the given precision. """
return genop.get_median_ystep(self, prec=prec)
def get_median_xystep(self, x_prec=2, y_prec=2):
""" Return the median steps between two distinct x and y values rounded to the given precisions. """
return genop.get_median_xystep(self, x_prec=x_prec, y_prec=y_prec)
def get_georef_xvalues(self):
""" Return the easting coordinates from the dataset values. """
return self.data.easting
def get_georef_yvalues(self):
""" Return the northing coordinates from the dataset values. """
return self.data.northing
def get_georef_xyvalues(self):
""" Return the easting and northing coordinates from the dataset values. """
return self.data.easting, self.data.northing
def get_georef_xgrid(self):
""" Return the easting coordinates matrices of the Z_image. """
return self.data.easting_image
def get_georef_ygrid(self):
""" Return the northing coordinates matrices of the Z_image. """
return self.data.northing_image
def get_georef_xygrid(self):
""" Return the easting and northing coordinates matrices of the Z_image. """
return self.data.easting_image, self.data.northing_image
def get_track(self, num, attr='values'):
''' Return the dataset attribtue corresponding to the track number. '''
return genop.get_track(self, num, attr=attr)
# ---------------------------------------------------------------------------#
# DataSet Geopositioning #
# ---------------------------------------------------------------------------#
def to_kml(self, plottype, cmapname, kmlfilename, creversed=False, picturefilename="image.png", cmmin=None, cmmax=None,
interpolation='bilinear', dpi=100):
"""
Plot in 2D dimensions the cartography representation to export in google earth.
Parameters :
:plottype: plotting type, '2D-SURFACE', '2D-CONTOUR', ...xyz
:cmapname: name of the color map used.
:kmlfilename: name of the kml file to create
:creversed: True to add '_r' at the cmname to reverse the color map
:picturefilename: name of the picture file to save, None if no file to save.
:cmmin: minimal value to display in the color map range.
:cmmax: maximal value to display in the color map range.
:interpolation: interpolation mode to display DataSet Image ('bilinear', 'nearest', 'bicubic'), 'bilinear' by default.
:cmapdisplay: True to display color map bar, False to hide the color map bar.
:axisdisplay: True to display axis and labels, False to hide axis and labels
:dpi: 'dot per inch' definition of the picture file if filename != None
Returns:
:success: True if success, False if not.
"""
# calculation of the 4 points utm coordinates
success, [blcorner, brcorner, urcorner, ulcorner] = self.getquadcoords()
if success:
# utm to wgs84 conversion
blcorner_wgs84_lat, blcorner_wgs84_lon = geopos.utm_to_wgs84(blcorner.utm_easting, blcorner.utm_northing,
self.georef.utm_zonenumber,
self.georef.utm_zoneletter)
brcorner_wgs84_lat, brcorner_wgs84_lon = geopos.utm_to_wgs84(brcorner.utm_easting, brcorner.utm_northing,
self.georef.utm_zonenumber,
self.georef.utm_zoneletter)
urcorner_wgs84_lat, urcorner_wgs84_lon = geopos.utm_to_wgs84(urcorner.utm_easting, urcorner.utm_northing,
self.georef.utm_zonenumber,
self.georef.utm_zoneletter)
ulcorner_wgs84_lat, ulcorner_wgs84_lon = geopos.utm_to_wgs84(ulcorner.utm_easting, ulcorner.utm_northing,
self.georef.utm_zonenumber,
self.georef.utm_zoneletter)
quadcoords = [(blcorner_wgs84_lon, blcorner_wgs84_lat), (brcorner_wgs84_lon, brcorner_wgs84_lat),
(urcorner_wgs84_lon, urcorner_wgs84_lat), (ulcorner_wgs84_lon, ulcorner_wgs84_lat)]
# creation of the picture file to overlay
self.plot(plottype, cmapname, creversed, fig=None, filename=picturefilename, cmmin=cmmin, cmmax=cmmax,
interpolation=interpolation, cmapdisplay=False, axisdisplay=False, dpi=dpi, transparent=True)
# creation of the kml file
kml.picture_to_kml(picturefilename, quadcoords, kmlfilename)
return success
def to_raster(self, plottype, cmapname, picturefilename, creversed=False, cmmin=None, cmmax=None,
interpolation='bilinear', dpi=100):
"""
Plot in 2D dimensions the cartography representation with the world file associated, to using in a SIG application.
Parameters:
:plottype: plotting type, '2D-SURFACE', '2D-CONTOUR', ...xyz
:cmapname: name of the color map used.
:picturefilename: name of the picture file to save (.jpg, .jpeg, .tif, .tiff, .png) , None if no file to save.
:creversed: True to add '_r' at the cmname to reverse the color map
:cmmin: minimal value to display in the color map range.
:cmmax: maximal value to display in the color map range.
:interpolation: interpolation mode to display DataSet Image ('bilinear', 'nearest', 'bicubic'), 'bilinear' by default.
:dpi: 'dot per inch' definition of the picture file
Returns:
:success: True if success, False if not.
"""
# calculation of the 4 points utm coordinates
success, [blcorner, brcorner, urcorner, ulcorner] = self.getquadcoords()
if success:
# tests if picture format available for raster
success = raster.israsterformat(picturefilename)
if success:
quadcoords = [(blcorner.utm_easting, blcorner.utm_northing), (brcorner.utm_easting, brcorner.utm_northing),
(urcorner.utm_easting, urcorner.utm_northing), (ulcorner.utm_easting, ulcorner.utm_northing)]
# creation of the picture file to overlay
self.plot(plottype, cmapname, creversed, fig=None, filename=picturefilename, cmmin=cmmin, cmmax=cmmax,
interpolation=interpolation, cmapdisplay=False, axisdisplay=False, dpi=dpi, transparent=True)
# creation of the world file
success = raster.picture_to_worldfile(picturefilename, quadcoords)
return success
def setgeoref(self, refsystem, points_list, utm_zoneletter=None, utm_zonenumber=None, valfilt=False):
""" Georeferencing dataset using 2-D linear interpolation.
Dataset is georeferenced using a list of Ground Control Points (GCPs).
The geographic positions are linearly interpolated in 2-D at the dataset position.
As no extrapolation is available yet, there must GCPs that spatially includes
the dataset positions (typically grid nodes).
Parameters
----------
refsystem : str or None
Geographic reference system ('UTM', 'WGS84', ...) or pyproj crs string ('EPSG:4326').
points_list : list
List of GCPs points. ex:
[[num1, lat1, lon1, x1, y1], ..., [numN, latN, lonN, xN, yN]].
utm_zoneletter : str or None
UTM zone letter if `refsystem` is 'UTM'.
utm_zonenumber : int or None
UTM zone number if `refsystem` is 'UTM'.
valfilt : bool
If True, the ungridded dataset value (class:`~values`) are used instead
of the gridded (class:`~z_images`).
Then, the georeferenced coordinates will be stored in :obj:`eatsing` and :obj:`northing`
instead of :obj:`easting_image` and :obj:`northing_image`.
Returns
-------
error : {0, -1, -2}
Error code.
0 if no error occured.
-1 if there are not enough points.
-2 if an error occured during georeferenincg,
probably the dataset are unconsistent with the GCPs area.
Georeferenced dataset object
"""
return gengeopositioning.setgeoref(self, refsystem, points_list,
utm_zoneletter=utm_zoneletter,
utm_zonenumber=utm_zonenumber,
valfilt=valfilt)
def getquadcoords(self):
"""
Calculates the utm coordinates of the DataSet Image corners.
Returns:
:success: True if coordinates getted, False if not
:bottomleft: utm coordinates of the bottom left corner
:bottomright: utm coordinates of the bottom right corner
:upright: utm coordinates of the up right corner
:upleft: utm coordinates of the up left corner
"""
bottomleft = None
bottomright = None
upright = None
upleft = None
if self.georef.active:
bottomleft = GeoRefPoint()
bottomright = GeoRefPoint()
upright = GeoRefPoint()
upleft = GeoRefPoint()
bottomleft.utm_easting, bottomleft.utm_northing = self.data.easting_image[0][0], self.data.northing_image[0][0]
bottomright.utm_easting, bottomright.utm_northing = self.data.easting_image[0][-1], self.data.northing_image[0][
-1]
upleft.utm_easting, upleft.utm_northing = self.data.easting_image[-1][0], self.data.northing_image[-1][0]
upright.utm_easting, upright.utm_northing = self.data.easting_image[-1][-1], self.data.northing_image[-1][-1]
return self.georef.active, [bottomleft, bottomright, upright, upleft]