# Source code for geophpy.dataset

    # -*- coding: utf-8 -*-
    '''
       GeophPy.dataset
       ---------------

       DataSet Object constructor and methods.

       :copyright: Copyright 2014 Lionel Darras, Philippe Marty and contributors, see AUTHORS.
       :license: GNU GPL v3.

    '''
    from __future__ import absolute_import
    import geophpy.plotting.plot as plot
    import geophpy.plotting.correlation as correlation
    import geophpy.plotting.colormap as colormap
    import geophpy.plotting.histo as histo
    import geophpy.operation.general as genoperation
    import geophpy.processing.general as genprocessing
    import geophpy.processing.magnetism as magprocessing
    import geophpy.filesmanaging.files as iofiles
    import geophpy.geoposset as geopos
    import geophpy.geopositioning.kml as kml
    import geophpy.geopositioning.raster as raster
    import geophpy.geopositioning.general as gengeopositioning
    import math, os

    #---------------------------------------------------------------------------#
    # Informations about DataSet Object                                         #
    #---------------------------------------------------------------------------#
    class Info:
       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                              #
    #---------------------------------------------------------------------------#
    class Data:
       fields = None
       values = None
       z_image = None
       easting_image = None    # easting array
       northing_image = None   # northing array

    #---------------------------------------------------------------------------#
    # Coordinates Object in local and utm referencing                           #
    #---------------------------------------------------------------------------#
    class GeoRefPoint:
       def __init__(self, easting=None, northing=None):
          self.utm_easting = easting
          self.utm_northing = northing

    #---------------------------------------------------------------------------#
    # Georeferencement System Object between local and geographics positions    #
    #---------------------------------------------------------------------------#
    class GeoRefSystem:
       active = False          # data set georeferencement 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 DataSet(object):
       '''
       Creates a DataSet Object to process and display data.

       info = Info()
       data = Data()
       georef = GeoRefSystem()
       '''

       def __init__(self):
          pass

       @classmethod
       def _new(cls):
          '''
          Creates a new empty data set

          '''
          dataset = cls()
          dataset.info = Info()
          dataset.data = Data()
          dataset.georef = GeoRefSystem()
          return dataset

       #---------------------------------------------------------------------------#
       # Data set files management                                                 #
       #---------------------------------------------------------------------------#
       @staticmethod
       def from_file(filenameslist, fileformat=None, delimiter='\t', x_colnum=1, y_colnum=2, z_colnum=3, skipinitialspace=True, skip_rows=1, fields_row=0):
          '''
          To 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 delimitting 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. to skip 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")

          '''
          # 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)

          # Create a new dataset #########################################
          dataset = DataSet._new()

          # Choose the input file format #################################
          if (fileformat == None):
             # ...TBD... Determine the format from file header
             pass

          if (fileformat == None):
             # Determine the format from filename extension
             file_extension = os.path.splitext(filenameslist[0])[1]
             fileformat = format_chooser.get(file_extension, None)

          # Read the dataset from input file #############################
          if (fileformat in fileformat_getlist()):
             readfile = getattr(From, fileformat)
             error    = readfile()
          else:
             # Undefined file format #####################################
             # ...TBD... raise an error here !
             error = 1

          # Return the dataset and error code ############################
          if (error == 0):
             success = True
          else:
             success = False
          return success, dataset

       def to_file(self, filename, fileformat=None, delimiter='\t', description=None):
          '''
          Save a DataSet Object to a file.

          Parameters :

          :filename: name of file to save.

          :fileformat: format of output file ...

          :delimiter: delimiter between fields in a line of the output file, '\t', ',', ';', ...

          Returns :

          :success: boolean

          '''
          # Dispatch method ##############################################
          class To():
             @staticmethod
             def ascii():
                return iofiles.to_ascii(self, filename, delimiter=delimiter)
             @staticmethod
             def netcdf():
                return iofiles.to_netcdf(self, filename, description=description)

          # Choose the dataset format ####################################
          if (fileformat == None):
             # Determine the format from filename extension
             file_extension = os.path.splitext(filename)[1]
             fileformat = format_chooser.get(file_extension, None)

          # Write the dataset to file ####################################
          if (fileformat in fileformat_getlist()):
             writefile = getattr(To, fileformat)
             error     = writefile()
          else:
             # Undefined file format #####################################
             # ...TBD... raise an error here !
             error = 1

          # Return the error code ########################################
          if (error == 0):
             success = True
          else:
             success = False
          return success

       #---------------------------------------------------------------------------#
       # DataSet Plotting                                                          #
       #---------------------------------------------------------------------------#
       def plot(self, plottype, cmapname, creversed=False, fig=None, filename=None, cmmin=None, cmmax=None, interpolation='bilinear', cmapdisplay=True, axisdisplay=True, pointsdisplay=False, dpi=None, transparent=False, logscale=False, rects=None, points=None):
          '''
          Plot in 2D or 3D dimensions the cartography representation.

          Parameters :

          :plottype: plotting type, '2D-SURFACE', '2D-CONTOUR', ...

          :cmapname: name of the color map used, 'gray_r' for example.

          :creversed: True to add '_r' at the cmname to reverse the color map

          :fig: figure to plot, None by default to create a new figure.

          :filename: 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', 'bicubic', 'spline16', ...), '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

          :pointsdisplay: True to display grid points, False to not display them.

          :dpi: 'dot per inch' definition of the picture file if filename != None

          :transparent: True to manage the transparency for the zones of lack of data

          :logscale: True to display with the log scale

          :rects: [[x0, y0, w0, h0], [x1, y1, w1, h1], ...], None if no selection rectangles to display

          Returns : fig, plt, cmap.   None, None, None if filename with a wrong picture format

          :fig: Figure Object

          :cmap: ColorMap Object

          '''
          dataset_todisplay = genoperation.copy(self)
          return plot.plot(dataset_todisplay, plottype, cmapname, creversed, fig, filename, cmmin=cmmin, cmmax=cmmax, interpolation=interpolation, cmapdisplay=cmapdisplay, axisdisplay=axisdisplay, pointsdisplay=pointsdisplay, dpi=dpi, transparent=transparent, logscale=logscale, rects=rects, points=points)

       def histo_plot(self, fig=None, filename=None, zmin=None, zmax=None, dpi=None, transparent=False):
          '''
          Plot histogram.

          Parameters :

          :fig: figure to plot, None by default to create a new figure.

          :filename: Name of the histogram file to save, None if no file to save.

          :zmin: Minimal Z value to represent.

          :zmax: Maximal Z value to represent.

          :dpi: 'dot per inch' definition of the picture file if filename != None

          :transparent: True to manage the transparency.

          Returns :

          :fig: Figure Object

          '''
          return histo.plot(self, fig, filename, zmin, zmax, dpi, transparent)

       def correlation_plotmap(self, fig=None, filename=None, method="Pearson", dpi=None, transparent=False):
          '''
          Plot correlation map.

          Parameters :

          :fig: figure to plot, None by default to create a new figure.

          :filename: Name of the histogram file to save, None if no file to save.

          :method: Correlation method

          :transparent: True to manage the transparency.

          Returns :

          :fig: Figure Object

          '''
          return correlation.plotmap(self, fig, filename, method, dpi, transparent)

       def correlation_plotsum(self, fig=None, filename=None, method="Pearson", dpi=None, transparent=False):
          '''
          Plot correlation sum.

          Parameters :

          :fig: figure to plot, None by default to create a new figure.

          :filename: Name of the histogram file to save, None if no file to save.

          :method: Correlation method

          :transparent: True to manage the transparency.

          Returns :

          :fig: Figure Object

          '''
          return correlation.plotsum(self, fig, filename, method, dpi, transparent)

       def histo_getlimits(self):
          '''
          Get the limits values.

          Returns : zmin, zmax

          '''
          return histo.getlimits(self)

       #---------------------------------------------------------------------------#
       # DataSet Operations                                                        #
       #---------------------------------------------------------------------------#
       def copy(self):
          '''
          To duplicate a DataSet Object.

          Parameters:

          :dataset: DataSet Object to duplicate

          Returns:

          :newdataset: duplicated DataSet Object

          '''
          #newdataset = DataSet._new()
          #newdataset = genoperation.copy(self, newdataset)
          #return newdataset
          return genoperation.copy(self)

       def interpolate(self, interpolation="none", x_delta=None, y_delta=None, x_decimal_maxnb=2, y_decimal_maxnb=2, x_frame_factor=0., y_frame_factor=0.):
          '''
          To interpolate raw values into z_image

          Parameters:

          :dataset: DataSet Object to interpolate

          :interpolation: gridding interpolation method to use (from griddinginterpolation_getlist()) ; "none" default value means to simply project raw data on the grid without interpolation (holes will be filled with "nan") ; otherwise "cubic" should be recommended (but currently doesn't handle nans correctly ...)

          :x_delta: gridding delta x ; None default value means to calculate it

          :y_delta: gridding delta y ; None default value means to calculate it

          :x_decimal_maxnb: decimal precision (e.g. 2 means 10^-2) to compute x_delta

          :y_decimal_maxnb: decimal precision (e.g. 1 means 10^-1) to compute y_delta

          :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:

          fills the z_image data field and adjusts info meta data

          '''
          return genoperation.interpolate(self, interpolation=interpolation, x_delta=x_delta, y_delta=y_delta, x_decimal_maxnb=x_decimal_maxnb, y_decimal_maxnb=y_decimal_maxnb, x_frame_factor=x_frame_factor, y_frame_factor=y_frame_factor)

       def sample(self):
          '''
          To rebuild the Values from a Z_image
          '''
          return genoperation.sample(self)

       #---------------------------------------------------------------------------#
       # 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 == True):
             # 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 == True):
             # tests if picture format available for raster
             success = raster.israsterformat(picturefilename)

             if (success == True):
                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):
          '''
          Sets georeferencement of data set

          Parameters :

          :refsystem: Reference system, 'UTM', 'WGS84', ...

          :points_list: list of points tu use for the georeferencement, [[num1, lat1, lon1, x1, y1], ..., [numN, latN, lonN, xN, yN]]

          :utm_zoneletter: UTM Letter, E->X, None if not 'UTM' ref system

          :utm_zonenumber: UTM number, 1->60, None if not 'UTM' ref system

          Returns :

          :error: error number, 0 if no error, -1 if no enough points, -2 if dataset zone greater than points list zone

          '''

          return gengeopositioning.setgeoref(self, refsystem, points_list, utm_zoneletter, utm_zonenumber)

       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 == True):
             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]

       #---------------------------------------------------------------------------#
       # DataSet Processing                                                        #
       #---------------------------------------------------------------------------#
       def peakfilt(self, setmin=None, setmax=None, setmed=False, setnan=False, valfilt=False):
          '''
          To eliminate peaks from a DataSet Object.

          Parameters:

          :dataset: DataSet Object to eliminate peaks from

          :setmin: minimal threshold value

          :setmax: maximal threshold value

          :setmed: if set to True, then values beyond threshold are replaced by a median instead of the threshold value ; the median is computed ...TBD...

          :setnan: if set to True, then values beyond thresholds are replaced by nan instead of the threshold value

          Note: if both "setnan" and "setmed" are True at the same time, then "nan" prevails

          :valfilt: if set to True, then filters data.values instead of data.zimage

          '''
          return genprocessing.peakfilt(self, setmin=setmin, setmax=setmax, setmed=setmed, setnan=setnan, valfilt=valfilt)

       def medianfilt(self, nx=3, ny=3, percent=0, gap=0, valfilt=False):
          '''
          To process a DataSet Object with a median filter

          Parameters:

          :dataset: Dataset Object to process

          :nx: filter size in x coordinate

          :ny: filter size in y coordinate

          :percent: deviation (in percents) from the median value (for absolute field measurements)

          :gap: deviation (in raw units) from the median value (for relative anomaly measurements)

          :valfilt: if set to True, then filters data.values instead of data.zimage

          '''
          return genprocessing.medianfilt(self, nx=nx, ny=ny, percent=percent, gap=gap, valfilt=valfilt)

       def festoonfilt(self, method='Pearson', shift=0, valfilt=False):
          '''
          To filter festoon-like artefacts out of DataSet Object

          Parameters:

          :dataset: DataSet Object to be filtered

          :method: correlation method to use (from festooncorrelation_getlist())

          :shift: systematic shift value (in pixels) to apply ; if shift=0 then the shift value will be determined for each profile by correlation with neighbours

          :valfilt: if set to True, then filters data.values instead of data.zimage

          Returns:

          :shift: shift value, modified if shift=0 in input parameter

          '''
          return genprocessing.festoonfilt(self, method=method, shift=shift, valfilt=valfilt)

       def destripecon(self, Nprof=0, setmin=None, setmax=None, method="add", valfilt=False):
          '''
          To destripe a DataSet Object by a constant (Zero Mean Traverse)

          Parameters:

          :dataset: DataSet Object to be destriped

          :Nprof: number of profiles over which to compute the mean of reference ; if set to 0 (default), compute the mean over the whole data

          :setmin: while computing the mean, do not take into account data values lower than setmin

          :setmax: while computing the mean, do not take into account data values greater than setmax

          :method: if set to "add" (default), destriping is done additively ; if set to "mult", it is done multiplicatively

          :valfilt: if set to True, then filters data.values instead of data.zimage

          '''
          return genprocessing.destripecon(self, Nprof=Nprof, setmin=setmin, setmax=setmax, method=method, valfilt=valfilt)

       def destripecub(self, Nprof=0, setmin=None, setmax=None, Ndeg=3, valfilt=False):
          '''
          To destripe a DataSet Object by a cubic curvilinear regression (chi squared)

          Parameters:

          :dataset: DataSet Object to be destriped

          :Nprof: number of profiles over which to compute the polynomial reference ; if set to 0 (default), compute the mean over the whole data

          :setmin: while fitting the polynomial curve, do not take into account data values lower than setmin

          :setmax: while fitting the polynomail curve, do not take into account data values greater than setmax

          :Ndeg: polynomial degree of the curve to fit

          :valfilt: if set to True, then filters data.values instead of data.zimage

          '''
          return genprocessing.destripecub(self, Nprof=Nprof, setmin=setmin, setmax=setmax, Ndeg=Ndeg, valfilt=valfilt)

       def regtrend(self, nx=3, ny=3, method="rel", component="loc", valfilt=False):
          '''
          To filter a DataSet Object from its regional trend

          Parameters:

          :dataset: DataSet Object to be filtered

          :nx: filter size in x coordinate

          :ny: filter size in y coordinate

          :method: set to "rel" to filter by relative value (resistivity) or to "abs" to filter by absolute value (magnetic field)

          :component: set to "loc" to keep the local variations or to "reg" to keep regional variations

          :valfilt: if set to True, then filters data.values instead of data.zimage

          '''
          return genprocessing.regtrend(self, nx=nx, ny=ny, method=method, component=component, valfilt=valfilt)

       def wallisfilt(self, nx=3, ny=3, setmean=None, setstdev=None, setgain=None, limit=None, edgefactor=None, valfilt=False):
          '''
          To apply Wallis filter to a DataSet Object

          Parameters:

          :dataset: DataSet Object to be filtered

          :nx: filter size in x coordinate

          :ny: filter size in y coordinate

          :setmean: ...TBD... float

          :setstdev: ...TBD... float

          :setgain: ...TBD... float

          :limit: ...TBD... float

          :edgefactor: ...TBD... float{0..1}

          :valfilt: if set to True, then filters data.values instead of data.zimage

          '''
          return genprocessing.wallisfilt(self, nx=nx, ny=ny, setmean=setmean, setstdev=setstdev, setgain=setgain, limit=limit, edgefactor=edgefactor, valfilt=valfilt)

       def ploughfilt(self, nx=3, ny=3, apod=0, angle=None, cutoff=None, valfilt=False):
          '''
          To apply anti-ploughing filter to a DataSet Object

          Parameters:

          :dataset: DataSet Object to be filtered

          :nx: filter size in x coordinate

          :ny: filter size in y coordinate

          :apod: apodisation factor (percent)

          :angle: ...TBD... float/degrees

          :cutoff: ...TBD... float/frequency

          :valfilt: if set to True, then filters data.values instead of data.zimage

          '''
          return genprocessing.ploughfilt(self, nx=nx, ny=ny, apod=apod, angle=angle, cutoff=cutoff, valfilt=valfilt)

       def logtransform(self, multfactor=0):
          '''
          To transform the data in logarihtmics values

          Parameters:

          :dataset: DataSet Object to be treated

          :multfactor: multiply factor

          '''
          return magprocessing.logtransform(self, multfactor)

       def polereduction(self, apod=0, inclineangle=65, alphaangle=0):
          '''
          To do a reduction at the pole of DataSet Object

          Parameters:

          :apod: apodisation factor, to limit side effects

          :inclineangle: magnetic field incline

          :alphaangle: magnetic field alpha angle

          '''
          return magprocessing.polereduction(self, apod, inclineangle, alphaangle)

       def continuation(self, prosptech, apod=0, downsensoraltitude=0.3, upsensoraltitude=1.0, continuationflag=False, continuationvalue=0.0):
          '''
          Continuation of the magnetic field

          Parameters :

          :prosptech: Prospection technical

          :apod: apodisation factor, to limit side effects

          :downsensoraltitude: Altitude of the down magnetic sensor

          :upsensoraltitude: Altitude of the upper magnetic sensor

          :continuationflag: Continuation flag, False if not continuation

          :continuationaltitude: Continuation altitude, greater than 0 if upper earth ground, lower than 0 else

          '''
          return magprocessing.continuation(self, prosptech, apod, downsensoraltitude, upsensoraltitude, continuationflag, continuationvalue)

       def eulerdeconvolution(self, xmin, xmax, ymin, ymax, apod=0, nflag=False, nvalue=0):
          '''
          To calculate the euler deconvolution

          Parameters :

          :xmin: minimal x value of the zone treated

          :xmax: maximal x value of the zone treated

          :ymin: minimal y value of the zone treated

          :ymax: maximal y value of the zone treated

          :apod: apodisation factor, to limit side effects

          :nflag: structural index flag, False is not selected

          :nvalue: structural index value, 0 if automatic calcultation, 1 for a sheet-like body, 2 for a circular section cylinder, 3 for a sphere

          Returns : x, y, depth

          :nvalue: structural index value, calculated if 0 in input, or else, the same than in input

          :x: x value of the point where the depth has been estimated.

          :y: y value of the point where the depth has been estimated.

          :depth: depth estimated.

          :xnearestmin: minimal x value of the zone treated found in the array

          :xnearestmax: maximal x value of the zone treated found in the array

          :ynearestmin: minimal y value of the zone treated found in the array

          :ynearestmax: maximal y value of the zone treated found in the array

          '''
          return magprocessing.eulerdeconvolution(self, xmin, xmax, ymin, ymax, apod, nflag, nvalue)

       def analyticsignal(self, apod=0):
          '''
          Analytic signal conversion

          Parameters :

          :apod: apodisation factor, to limit side effects

          '''
          return magprocessing.analyticsignal(self, apod)

       def gradmagfieldconversion(self, prosptechused, prosptechsim, apod=0, downsensoraltused = 0.3, upsensoraltused = 1.0, downsensoraltsim = 0.3, upsensoraltsim = 1.0, inclineangle = 65, alphaangle = 0):
          '''
          Conversion between gradient and magnetic field values

          Parameters :

          :prosptechused: Prospection technical used

          :prosptechsim: Prospection technical simulated

          :apod: apodisation factor, to limit side effects

          :downsensoraltused: Altitude of the down magnetic sensor used

          :upsensoraltused: Altitude of the upper magnetic sensor used

          :downsensoraltsim: Altitude of the down magnetic sensor simulated

          :upsensoraltsim: Altitude of the upper magnetic sensor simulated

          :inclineangle: magnetic field incline

          :alphaangle: magnetic field alpha angle

          '''
          return magprocessing.gradmagfieldconversion(self, prosptechused, prosptechsim, apod, downsensoraltused, upsensoraltused, downsensoraltsim, upsensoraltsim, inclineangle, alphaangle)

       def susceptibility(self, prosptech, apod=0, downsensoraltitude = 0.3, upsensoraltitude = 1.0, calculationdepth=.0, stratumthickness=1.0, inclineangle = 65, alphaangle = 0):
          '''
          Calcultation of an equivalent stratum of magnetic susceptibility

          Parameters :

          :prosptech: Prospection technical

          :apod: apodisation factor, to limit side effects

          :downsensoraltitude: Altitude of the down magnetic sensor

          :upsensoraltitude: Altitude of the upper magnetic sensor

          :calculationdepth: Depth(m) to do the calculation

          :stratumthickness: Thickness of the equivalent stratim

          :inclineangle: magnetic field incline

          :alphaangle: magnetic field alpha angle

          '''
          return magprocessing.susceptibility(self, prosptech, apod, downsensoraltitude, upsensoraltitude, calculationdepth, stratumthickness, inclineangle, alphaangle)

    #===========================================================================#

    #---------------------------------------------------------------------------#
    # General DataSet Environment functions                                     #
    #---------------------------------------------------------------------------#
    format_chooser = {
       ".dat" : "ascii",
       ".txt" : "ascii",
       ".nc"  : "netcdf",
       ".cdf" : "netcdf",
       ".pga" : "wumap",
       ".grd" : "surfer",
       ".mat" : "matrix",
       ".app" : "profile",
       ".rt"  : "electric",
    }

    def getlinesfrom_file(filename, fileformat=None, delimiter='\t', skipinitialspace=True, skiprowsnb=0, rowsnb=1):
       '''
       Reads lines in a file.

       Parameters :

       :fileformat: file format

       :filename: file name with extension to read, "test.dat" for example.

       :delimiter: delimiter between fields, tabulation by default.

       :skipinitialspace: if True, considers severals delimiters as only one : "\t\t" as '\t'.

       :skiprowsnb: number of rows to skip to get lines.

       :rowsnb: number of the rows to read, 1 by default.

       Returns:

       :colsnb: number of columns in all rows, 0 if rows have different number of columns

       :rows: rows.

       '''
       # Dispatch method ##############################################
       class From():
          @staticmethod
          def ascii():
             return iofiles.getlinesfrom_ascii(filename, delimiter, skipinitialspace, skiprowsnb, rowsnb)
          @staticmethod
          def netcdf():
             return iofiles.getlinesfrom_netcdf(filename)

       # Choose the input file format #################################
       if (fileformat == None):
          # ...TBD... Determine the format from file header
          pass

       if (fileformat == None):
          # Determine the format from filename extension
          file_extension = os.path.splitext(filenameslist[0])[1]
          fileformat = format_chooser.get(file_extension, None)

       # Read the dataset from input file #############################
       if (fileformat in fileformat_getlist()):
          readfile = getattr(From, fileformat)
          return readfile()
       else:
          # Undefined file format #####################################
          # ...TBD... raise an error here !
          return None, None

    def fileformat_getlist():
       '''
       Get list of format files availables

       Returns: list of file formats availables, ['ascii', ...]

       '''
       return iofiles.fileformat_getlist()

    def pictureformat_getlist():
       '''
       Get list of pictures format availables

       Returns: list of picture formats availables, ['jpg', 'png', ...]

       '''
       return plot.getpictureformatlist()

    def rasterformat_getlist():
       '''
       Get list of raster format files availables

       Returns : list of raster file formats availables, ['jpg', 'png', ...]

       '''
       return raster.getrasterformatlist()

    def plottype_getlist():
       '''
       Get list of plot type availables

       Returns : list of plot type availables, ['2D_SURFACE', '2D_CONTOUR', ...]

       '''
       return plot.gettypelist()

    def festooncorrelation_getlist():
       '''
       To get the list of available festoon correlation methods.

       '''
       return genprocessing.getfestooncorrelationlist()

    def destriping_getlist():
       '''
       To get the list of available destriping methods.

       '''
       return genprocessing.getdestripinglist()

    def regtrendmethod_getlist():
       '''
       To get the list of available destriping methods.

       '''
       return genprocessing.getregtrendmethodlist()

    def regtrendcomp_getlist():
       '''
       To get the list of available destriping methods.

       '''
       return genprocessing.getregtrendcomplist()

    def griddinginterpolation_getlist():
       '''
       To get the list of available gridding interpolation methods.

       '''
       return genoperation.getgriddinginterpolationlist()

    def interpolation_getlist():
       '''
       Get list of interpolation methods availables

       Returns : list of interpolation methods availables, ['bilinear', 'bicubic', ...]

       '''
       return plot.getinterpolationlist()

    def prosptech_getlist():
       '''
       Get list of prospection technicals availables

       Returns : list of prospection technicals

       '''
       return magprocessing.getprosptechlist()

    def colormap_getlist():
       '''
       Getting the colormap list.

       Returns : list of colormap availables, ['gray', ...]

       '''
       return colormap.getlist()

    def colormap_plot(cmname, creversed=None, fig=None, filename=None, dpi=None, transparent=False):
       '''
       Plots the colormap.

       Parameters :

       :cmname: Name of the colormap, 'gray_r' for example.

       :creversed: True to add '_r' at the cmname to reverse the color map

       :fig: figure to plot, None by default to create a new figure.

       :filename: Name of the color map file to save, None if no file to save.

       :dpi: 'dot per inch' definition of the picture file if filename != None

       :transparent: True to manage the transparency.

       Returns:

       :fig: Figure Object

       '''
       return colormap.plot(cmname, creversed, fig, filename, dpi, transparent)

    def correlmap(dataset, method):
       '''
       To compute the correlation map from an image :
          * each profile (from the input list) is incrementally shifted and correlation coefficient computed against neighbouring profiles for each shift value
          * profiles are considered to be vertical, and the shift performed along the profile (hence vertically)
          * the correlation map size is then "twice the image vertical size" (shift may vary from -ymax to +ymax) by "number of profiles" (correlation is computed for each column listed in input)

       Parameters:

       :dataset: DataSet Object containing the Z-image to be correl-mapped

       :cols: column numbers (1D array) of the image profiles to be correlated

       :method: correlation method to use (from festooncorrelation_getlist())

       Returns:

       :cor1: correlation map (shape = (2*zimg.shape[0]-1 , cols.size))

       :pva1: weight map (see correlation functions description)

       '''
       return genprocessing.correlmap(dataset, method)

    def correlshift(cor1, pva1, apod=None, output=None):
       '''
       To compute the best shift to re-align festooned profiles

       Parameters:

       :cor1: correlation map (shape = (2*zimg.shape[0]-1 , cols.size))

       :pva1: weight map (see correlation functions description)

       :apod: apodisation threshold (in percent of the max correl coef)

       :output: correlation profile computed as a weighted mean across the correlation map ; the best shift value is found at this profile's maximum

       Returns:

       :shift: number of pixels to shift along the profile

       '''
       return genprocessing.correlshift(cor1, pva1, apod=apod, output=output)

    help_path = os.path.join(os.path.dirname(__file__), 'help')
    htmlhelp_filename = os.path.abspath(os.path.join(help_path, 'html', 'index.html'))
    pdfhelp_filename = os.path.abspath(os.path.join(help_path, 'pdf', 'GeophPy.pdf'))

    def getgeophpyhelp(viewer='none', type='html'):
       '''
       To get help documentation of GeophPy module

       Parameters:

       :type: type of help needed, 'html' or 'pdf'.

       Returns:

       :helpcommand: application to start followed by pathname and filename of the 'html' or 'pdf' help document.

       '''

       if (type == 'pdf'):
          pathfilename = pdfhelp_filename
       else :
          pathfilename = htmlhelp_filename

       if (viewer == 'none'):           # start automatically the best application
           helpcommand = pathfilename
       else :
           helpcommand = viewer + " " + pathfilename
       return helpcommand