<commit_before>""" Classes for basic grid types """

import sys
import copy
from math import sqrt
import numpy as np
from . import _aai          # Contains the ascread driver
from ..crs import crsreg

try:
    from . import _gtiff
    HAS_GDAL = True
except ImportError:
    HAS_GDAL = False

try:
    from .fill_sinks import fill_sinks
except ImportError:
    sys.stderr.write("Compiled fill_sinks not available. Falling back to "
                     "Python version\n")
    from .raster import fill_sinks

class Grid(object):
    """ Grid baseclass. Don't use this directly except to implement subclasses.
    The primary attributes defined by all Grid-derived classed are _hdr and
    data.
    """

    def __len__(self):
        # Number of bands
        return self.nbands

    def clipz(self, bounds):
        """ Clip the z-range in place to bounds = [min, max]. """
        self.Z = self.Z.clip(bounds[0], bounds[1])
        return

    def max(self):
        """ Return the maximum non-nan in self.data. """
        return np.nanmax(self.Z)

    def min(self):
        """ Return the minimum non-nan in self.data. """
        return np.nanmin(self.Z)

    def minmax(self):
        """ Return the minimum and maximum value of data array. """
        return (self.min(), self.max())

    def copy(self):
        """ Return a copy. """
        return copy.deepcopy(self)


class RegularGrid(Grid):
    """ Regular (structured) grid class. A RegularGrid contains a fixed number
    of rows and columns with a constant spacing and a scalar or vector field
    defined as `Z`.

    Positions on a RegularGrid are referenced using an affine transform such
    that
    
    X = a + j * c + i * e
    Y = b + i * d + j * f

    in which (a,b) define the grid origin, (c,d) define the resolution in the
    horizontal and vertical directions, and (e,f) can be used to define a
    rotation. In the usual case of an orthogonal grid with north "up", e = f =
    0.
    """
    def __init__(self, transform, Z=None, nbands=None, crs=None):
        """ Create a RegularGrid instance with cells referenced according to *transform*, which is an iterable or dictionary consisting of
        (xllcenter, yllcenter, dx, dy, xrot, yrot).

        Optional parameters:
        --------------------
        Z : grid data (nrows x ncols x nbands) [default NaN]
        nband : number of grid layers [default 1]
        """
        if hasattr(transform, "keys"):
            self._transform = tuple([transform[f] for f in
                            ("xllcenter", "yllcenter", "dx", "dy", "xskew", "yskew")])
        elif len(transform) == 6:
            self._transform = tuple(transform)
        elif len(transform) == 4:
            self._transform = (transform[0], transform[1],
                               transform[2], transform[3], 0, 0)
        else:
            raise GridError("RegularGrid must be initialized with a transform iterable or dictionary")

        if Z is not None:
            self.Z = np.atleast_3d(Z)
        else:
            self.Z = np.atleast_3d([np.nan] * nbands)

        self.nbands = self.Z.shape[2]

        if crs is None:
            self._crs = crsreg.CARTESIAN
        else:
            self._crs = crs

        return

    def __add__(self, other):
        if self._equivalent_structure(other):
            return RegularGrid(copy.copy(self.transform),
                               Z=self.Z+other.Z,
                               nbands=self.nbands)
        else:
            raise NonEquivalentGridError(self, other)

    def __sub__(self, other):
        if self._equivalent_structure(other):
            return RegularGrid(copy.copy(self.transform),
                               Z=self.Z-other.Z,
                               nbands=self.nbands)
        else:
            raise NonEquivalentGridError(self, other)

    def _equivalent_structure(self, other):
        return (self._transform == other._transform) and \
               (self.Z.shape == other.Z.shape) and \
               (self.nbands == other.nbands)

    @property
    def transform(self):
        return self._transform

    @property
    def shape(self):
        return self.Z.shape[:2]

    def center_llref(self):
        """ Return the 'lower-left' reference in terms of a center coordinate.
        """
        return self._transform[0], self._transform[1]

    def corner_llref(self):
        """ Return the 'lower-left' reference in terms of a center coordinate.
        """
        xllcorner = self._transform[0] - 0.5 * self._transform[2]
        yllcorner = self._transform[1] - 0.5 * self._transform[3]
        return (xllcorner, yllcorner)

    def coordmesh(self, *args, **kwargs):
        """ Alias for center_coords() """
        return self.center_coords(*args, **kwargs)

    def center_coords(self):
        """ Return the cell-center coordinates. """
        ii, jj = np.meshgrid(np.arange(self.Z.shape[0]),
                             np.arange(self.Z.shape[1]))
        t = self._transform
        return (t[0] + ii * t[2] + jj * t[4],
                t[1] + jj * t[3] + jj * t[5])

    def vertex_coords(self):
        """ Return the coordinates of vertices. """
        xllcorner, yllcorner = self.corner_llref()
        t = self._transform
        ny, nx = self.Z.shape[:2]
        xurcorner = xllcorner + (nx+1) * t[2] + (ny+1) * t[4]<commit_msg>add layers attribute and fix coordmesh<commit_after>""" Classes for basic grid types """

import sys
import copy
from math import sqrt
import numpy as np
from . import _aai          # Contains the ascread driver
from ..crs import crsreg

try:
    from . import _gtiff
    HAS_GDAL = True
except ImportError:
    HAS_GDAL = False

try:
    from .fill_sinks import fill_sinks
except ImportError:
    sys.stderr.write("Compiled fill_sinks not available. Falling back to "
                     "Python version\n")
    from .raster import fill_sinks

class Grid(object):
    """ Grid baseclass. Don't use this directly except to implement subclasses.
    The primary attributes defined by all Grid-derived classed are _hdr and
    data.
    """

    def __len__(self):
        # Number of bands
        return self.nbands

    def clipz(self, bounds):
        """ Clip the z-range in place to bounds = [min, max]. """
        self.Z = self.Z.clip(bounds[0], bounds[1])
        return

    def max(self):
        """ Return the maximum non-nan in self.data. """
        return np.nanmax(self.Z)

    def min(self):
        """ Return the minimum non-nan in self.data. """
        return np.nanmin(self.Z)

    def minmax(self):
        """ Return the minimum and maximum value of data array. """
        return (self.min(), self.max())

    def copy(self):
        """ Return a copy. """
        return copy.deepcopy(self)


class RegularGrid(Grid):
    """ Regular (structured) grid class. A RegularGrid contains a fixed number
    of rows and columns with a constant spacing and a scalar or vector field
    defined as `Z`.

    Positions on a RegularGrid are referenced using an affine transform such
    that
    
    X = a + j * c + i * e
    Y = b + i * d + j * f

    in which (a,b) define the grid origin, (c,d) define the resolution in the
    horizontal and vertical directions, and (e,f) can be used to define a
    rotation. In the usual case of an orthogonal grid with north "up", e = f =
    0.
    """
    def __init__(self, transform, Z=None, nbands=None, crs=None):
        """ Create a RegularGrid instance with cells referenced according to *transform*, which is an iterable or dictionary consisting of
        (xllcenter, yllcenter, dx, dy, xrot, yrot).

        Optional parameters:
        --------------------
        Z : grid data (nrows x ncols x nbands) [default NaN]
        nband : number of grid layers [default 1]
        """
        if hasattr(transform, "keys"):
            self._transform = tuple([transform[f] for f in
                            ("xllcenter", "yllcenter", "dx", "dy", "xskew", "yskew")])
        elif len(transform) == 6:
            self._transform = tuple(transform)
        elif len(transform) == 4:
            self._transform = (transform[0], transform[1],
                               transform[2], transform[3], 0, 0)
        else:
            raise GridError("RegularGrid must be initialized with a transform iterable or dictionary")

        if Z is not None:
            self.Z = np.atleast_3d(Z)
        else:
            self.Z = np.atleast_3d([np.nan] * nbands)

        self.nbands = self.Z.shape[2]

        if crs is None:
            self._crs = crsreg.CARTESIAN
        else:
            self._crs = crs

        return

    def __add__(self, other):
        if self._equivalent_structure(other):
            return RegularGrid(copy.copy(self.transform),
                               Z=self.Z+other.Z,
                               nbands=self.nbands)
        else:
            raise NonEquivalentGridError(self, other)

    def __sub__(self, other):
        if self._equivalent_structure(other):
            return RegularGrid(copy.copy(self.transform),
                               Z=self.Z-other.Z,
                               nbands=self.nbands)
        else:
            raise NonEquivalentGridError(self, other)

    def _equivalent_structure(self, other):
        return (self._transform == other._transform) and \
               (self.Z.shape == other.Z.shape) and \
               (self.nbands == other.nbands)

    @property
    def transform(self):
        return self._transform

    @property
    def shape(self):
        return self.Z.shape[:2]

    @property
    def layers(self):
        return tuple(self.Z[:,:,i] for i in range(self.nbands))

    def center_llref(self):
        """ Return the 'lower-left' reference in terms of a center coordinate.
        """
        return self._transform[0], self._transform[1]

    def corner_llref(self):
        """ Return the 'lower-left' reference in terms of a center coordinate.
        """
        xllcorner = self._transform[0] - 0.5 * self._transform[2]
        yllcorner = self._transform[1] - 0.5 * self._transform[3]
        return (xllcorner, yllcorner)

    def coordmesh(self, *args, **kwargs):
        """ Alias for center_coords() """
        return self.center_coords(*args, **kwargs)

    def center_coords(self):
        """ Return the cell-center coordinates. """
        ii, jj = np.meshgrid(np.arange(self.Z.shape[1]),
                             np.arange(self.Z.shape[0]))
        t = self._transform
        return (t[0] + ii * t[2] + jj[::-1] * t[4],
                t[1] + jj[::-1] * t[3] + ii * t[5])

    def vertex_coords(self):
        """ Return the coordinates of vertices. """
        xllcorner, yllcorner = self.corner_llref()
        t = self._transform
        ny, nx = self.Z.shape[:2]
        xurcorner = xllcorner + (nx+1) * t[2] + (ny+1) * t[4]
{'fraction_non_alphanumeric': 0.11339449541284403, 'fraction_numerical': 0.007339449541284404, 'mean_word_length': 2.0129906025428412, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1637827', 'n_tokens_mistral': 3278, 'n_tokens_neox': 3151, 'n_words': 999}