Source code for gstools.variogram.binning

"""
GStools subpackage providing binning routines.

.. currentmodule:: gstools.variogram.binning

The following functions are provided

.. autosummary::
   standard_bins
"""
import numpy as np

from gstools.tools import RADIAN_SCALE
from gstools.tools.geometric import (
    chordal_to_great_circle,
    format_struct_pos_dim,
    generate_grid,
    latlon2pos,
)

__all__ = ["standard_bins"]


def _sturges(pnt_cnt):
    return int(np.ceil(2 * np.log2(pnt_cnt) + 1))


[docs]def standard_bins( pos=None, dim=2, latlon=False, mesh_type="unstructured", bin_no=None, max_dist=None, geo_scale=RADIAN_SCALE, ): r""" Get standard binning. Parameters ---------- pos : :class:`list`, optional the position tuple, containing either the point coordinates (x, y, ...) or the axes descriptions (for mesh_type='structured') dim : :class:`int`, optional Field dimension. latlon : :class:`bool`, optional Whether the data is representing 2D fields on earths surface described by latitude and longitude. When using this, the estimator will use great-circle distance for variogram estimation. Note, that only an isotropic variogram can be estimated and a ValueError will be raised, if a direction was specified. Bin edges need to be given in radians in this case. Default: False mesh_type : :class:`str`, optional 'structured' / 'unstructured', indicates whether the pos tuple describes the axis or the point coordinates. Default: `'unstructured'` bin_no: :class:`int`, optional number of bins to create. If None is given, will be determined by Sturges' rule from the number of points. Default: None max_dist: :class:`float`, optional Cut of length for the bins. If None is given, it will be set to one third of the box-diameter from the given points. Default: None geo_scale : :class:`float`, optional Geographic unit scaling in case of latlon coordinates to get a meaningful bins unit. By default, bins are assumed to be in radians with latlon=True. Can be set to :any:`KM_SCALE` to have bins in km or :any:`DEGREE_SCALE` to have bins in degrees. Default: :any:`RADIAN_SCALE` Returns ------- :class:`numpy.ndarray` The generated bin edges. Notes ----- Internally uses double precision and also returns doubles. """ dim = 2 if latlon else int(dim) if bin_no is None or max_dist is None: if pos is None: raise ValueError("standard_bins: no pos tuple given.") if mesh_type != "unstructured": pos = generate_grid(format_struct_pos_dim(pos, dim)[0]) else: pos = np.asarray(pos, dtype=np.double).reshape(dim, -1) pos = latlon2pos(pos, radius=geo_scale) if latlon else pos pnt_cnt = len(pos[0]) box = [] for axis in pos: box.append([np.min(axis), np.max(axis)]) box = np.asarray(box) diam = np.linalg.norm(box[:, 0] - box[:, 1]) # convert diameter to great-circle distance if using latlon diam = chordal_to_great_circle(diam, geo_scale) if latlon else diam bin_no = _sturges(pnt_cnt) if bin_no is None else int(bin_no) max_dist = diam / 3 if max_dist is None else float(max_dist) return np.linspace(0, max_dist, num=bin_no + 1, dtype=np.double)