invert4geom.synthetic
=====================

.. py:module:: invert4geom.synthetic


Attributes
----------

.. autoapisummary::

   invert4geom.synthetic.xesmf


Functions
---------

.. autoapisummary::

   invert4geom.synthetic.load_synthetic_model
   invert4geom.synthetic.contaminate_with_long_wavelength_noise
   invert4geom.synthetic.load_bishop_model
   invert4geom.synthetic.gaussian2d
   invert4geom.synthetic.synthetic_topography_simple
   invert4geom.synthetic.synthetic_topography_regional
   invert4geom.synthetic.contaminate


Module Contents
---------------

.. py:data:: xesmf
   :value: None


.. py:function:: load_synthetic_model(spacing = 1000.0, region = (0, 40000, 0, 30000), buffer = 0, topography_coarsen_factor = 2, topography_percent_noise = None, number_of_constraints = None, density_contrast = None, zref = None, gravity_obs_height = 1000, gravity_noise = 0.2, resample_for_cv = False, plot_topography = False, plot_topography_diff = True, plot_gravity = True)

   Function to perform all necessary steps to create a synthetic model for the examples
   in the documentation.

   :param spacing: spacing of the grid and gravity, by default 1e3
   :type spacing: float, optional
   :param region: bounding region for the grid, by default (0, 40000, 0, 30000)
   :type region: tuple[float, float, float, float], optional
   :param buffer: buffer to add around the region, by default 0. Buffer region used for creating
                  topography and prisms, while inner region used for extent of gravity and
                  constraints.
   :type buffer: float, optional
   :param topography_coarsen_factor: factor to coarsen the topography data by for adding noise, by default 2
   :type topography_coarsen_factor: float, optional
   :param topography_percent_noise: noise decimal percent to add to topography data, by default None
   :type topography_percent_noise: float | None, optional
   :param number_of_constraints: number of random constraints to use, by default None
   :type number_of_constraints: int | None, optional
   :param density_contrast: density contrast to use, by default None
   :type density_contrast: float | None, optional
   :param zref: reference level to use, by default None
   :type zref: float | None, optional
   :param gravity_obs_height: gravity observation height to use, by default 1000
   :type gravity_obs_height: float, optional
   :param gravity_noise: decimal percentage noise level to add to gravity data, by default 0.2
   :type gravity_noise: float | None, optional
   :param resample_for_cv: resample gravity data at half spacing to create train and test sets, by default
                           False
   :type resample_for_cv: bool, optional
   :param plot_topography: plot the topography, by default False
   :type plot_topography: bool, optional
   :param plot_topography_diff: plot the difference between the true and starting topography, by default True
   :type plot_topography_diff: bool, optional
   :param plot_gravity: plot the gravity data, by default True
   :type plot_gravity: bool, optional

   :returns: * **true_topography** (*xarray.DataArray*) -- the true topography
             * **starting_topography** (*xarray.DataArray*) -- the starting topography
             * **constraint_points** (*pandas.DataFrame*) -- the constraint points
             * **grav_df** (*pandas.DataFrame*) -- the gravity data


.. py:function:: contaminate_with_long_wavelength_noise(grid, noise, coarsen_factor = None, spacing = None, noise_as_percent = True, seed = 1)

   Contaminate a grid with long wavelength noise.

   :param grid: Grid to contaminate
   :type grid: xarray.DataArray
   :param noise: noise to add to the data, can be either absolute or percent of max value of
                 data
   :type noise: float
   :param coarsen_factor: Factor to coarsen the data by, by default None
   :type coarsen_factor: float | None, optional
   :param spacing: Spacing for the long wavelength noise, by default None
   :type spacing: float | None, optional
   :param noise_as_percent: if True, the value given to `noise` is treated as a percentage of the max value
                            of the data.
   :type noise_as_percent: bool, optional
   :param seed: seed to use for the random number generator, by default 1
   :type seed: int, optional

   :returns: Contaminated grid
   :rtype: xarray.DataArray


.. py:function:: load_bishop_model(coarsen_factor = None)

   Download and return a dataset of the Bishop model which contains basement
   topography, moho topography, and synthetically generated forward gravity of
   both topographies. See https://wiki.seg.org/wiki/Bishop_Model for more info on the
   derivation of this dataset.

   :param coarsen_factor: Factor to coarsen the data by. Data originally at 200m resolution, by default
                          None
   :type coarsen_factor: float, optional

   :returns: Dataset with variables "basement_topo", "moho_topo", and "gravity".
   :rtype: xarray.Dataset


.. py:function:: gaussian2d(x, y, sigma_x, sigma_y, x0 = 0, y0 = 0, angle = 0.0)

   Non-normalized 2D Gaussian function for creating synthetic topography.

   :param x: Coordinates at which to calculate the Gaussian function
   :type x: numpy.ndarray
   :param y: Coordinates at which to calculate the Gaussian function
   :type y: numpy.ndarray
   :param sigma_x: Standard deviation in the x and y directions
   :type sigma_x: float
   :param sigma_y: Standard deviation in the x and y directions
   :type sigma_y: float
   :param x0: Coordinates of the center of the distribution, by default 0
   :type x0: float, optional
   :param y0: Coordinates of the center of the distribution, by default 0
   :type y0: float, optional
   :param angle: Rotation angle of the gaussian measure from the x axis (north) growing positive
                 to the east (positive y axis), by default 0.0
   :type angle: float, optional

   :returns: Gaussian function evaluated at *x*, *y*
   :rtype: numpy.ndarray

   .. rubric:: Notes

   This function was adapted from the Fatiando-Legacy function
   gaussian2d: https://legacy.fatiando.org/api/utils.html?highlight=gaussian#fatiando.utils.gaussian2d


.. py:function:: synthetic_topography_simple(spacing, region, registration = 'g', scale = 1, yoffset = 0)

   Create a synthetic topography dataset with a few features.

   :param spacing: grid spacing in meters
   :type spacing: float
   :param region: bounding edges of the grid in meters in format (xmin, xmax, ymin, ymax)
   :type region: tuple[float, float, float, float]
   :param registration: grid registration type, either "g" for gridline or "p" for pixel, by default "g"
   :type registration: str, optional
   :param scale: value to scale the topography by, by default 1
   :type scale: float, optional
   :param yoffset: value to offset the topography by, by default 0
   :type yoffset: float, optional

   :returns: synthetic topography dataset
   :rtype: xarray.Dataset


.. py:function:: synthetic_topography_regional(spacing, region, registration = 'g', scale = 1, yoffset = 0)

   Create a synthetic topography dataset with a few features which represent the
   surface responsible for the regional component of gravity.

   :param spacing: grid spacing in meters
   :type spacing: float
   :param region: bounding edges of the grid in meters in format (xmin, xmax, ymin, ymax)
   :type region: tuple[float, float, float, float]
   :param registration: grid registration type, either "g" for gridline or "p" for pixel, by default "g"
   :type registration: str, optional
   :param scale: value to scale the topography by, by default 1
   :type scale: float, optional
   :param yoffset: value to offset the topography by, by default 0
   :type yoffset: float, optional

   :returns: synthetic topography dataset
   :rtype: xarray.Dataset


.. py:function:: contaminate(data, stddev, percent = False, percent_as_max_abs = True, seed = 0)

   Add pseudorandom gaussian noise to an array.
   Noise added is normally distributed with zero mean and a standard deviation from
   *stddev*.

   :param data: data to contaminate, can be a single array, or a list of arrays.
   :type data: numpy.ndarray | list[numpy.ndarray]
   :param stddev: standard deviation of the Gaussian noise that will be added to
                  *data*. Length must be the same as *data* if *data* is a list.
   :type stddev: float | list[float]
   :param percent: If ``True``, will consider *stddev* as a decimal percentage of the **data** and
                   the standard deviation of the Gaussian noise will be calculated with this, by
                   default False
   :type percent: bool, optional
   :param percent_as_max_abs: If ``True``, and **percent** is ``True``, the *stddev* used as the standard
                              deviation of the Gaussian noise will be the max absolute value of the **data**.
                              If ``False``, and **percent** is ``True``, the *stddev* will be calculated on a
                              point-by-point basis, so each **data** points' noise will be the same
                              percentage, by default True
   :type percent_as_max_abs: bool, optional
   :param seed: seed to use for the random number generator, by default 0
   :type seed: float, optional

   :returns: * **contam** (*numpy.ndarray | list[numpy.ndarray]*) -- contaminated data. If *data* is a list, will return a list of arrays.
             * **stddev** (*float | list[float]*) -- standard deviation of the Gaussian noise added to the data. If *stddev* is a
               list, will return a list of floats.

   .. rubric:: Notes

   This function was adapted from the Fatiando-Legacy function
   gaussian2d: https://legacy.fatiando.org/api/utils.html?highlight=gaussian#fatiando.utils.contaminate

   .. rubric:: Examples

   >>> import numpy as np
   >>> data = np.ones(5)
   >>> noisy, std = contaminate(data, 0.05, seed=0, percent=True)
   >>> print(std)
   0.05
   >>> print(noisy)
   array([1.00425372, 0.99136197, 1.02998834, 1.00321222, 0.97118374])
   >>> data = [np.zeros(5), np.ones(3)]
   >>> noisy = contaminate(data, [0.1, 0.2], seed=0)
   >>> print(noisy[0])
   array([ 0.00850745, -0.01727606,  0.05997669,  0.00642444, -0.05763251])
   >>> print(noisy[1])
   array([0.89814061, 1.0866216 , 1.01523779])


