<commit_before>from __future__ import absolute_import

import datetime
from itertools import product

import iris
from iris.util import guess_coord_axis

import numpy as np

from .interface import Interface
from .grid import GridInterface
from ..ndmapping import (NdMapping, item_check, sorted_context)
from ..spaces import HoloMap, DynamicMap
from .. import util

from holoviews.core.dimension import Dimension


def get_date_format(coord):
    def date_formatter(val, pos=None):
        date = coord.units.num2date(val)
        date_format = Dimension.type_formatters.get(datetime.datetime, None)
        if date_format:
            return date.strftime(date_format)
        else:
            return date

    return date_formatter


def coord_to_dimension(coord):
    """
    Converts an iris coordinate to a HoloViews dimension.
    """
    kwargs = {}
    if coord.units.is_time_reference():
        kwargs['value_format'] = get_date_format(coord)
    else:
        kwargs['unit'] = str(coord.units)
    return Dimension(coord.name(), **kwargs)


def sort_coords(coord):
    """
    Sorts a list of DimCoords trying to ensure that
    dates and pressure levels appear first and the
    longitude and latitude appear last in the correct
    order.
    """
    order = {'T': -2, 'Z': -1, 'X': 1, 'Y': 2}
    axis = guess_coord_axis(coord)
    return (order.get(axis, 0), coord and coord.name())



class CubeInterface(GridInterface):
    """
    The CubeInterface provides allows HoloViews to interact with iris
    Cube data. When passing an iris Cube to a HoloViews Element the
    init method will infer the dimensions of the Cube from its
    coordinates. Currently the interface only provides the basic
    methods required for HoloViews to work with an object.
    """

    types = (iris.cube.Cube,)

    datatype = 'cube'

    @classmethod
    def init(cls, eltype, data, kdims, vdims):
        if kdims:
            kdim_names = [kd.name if isinstance(kd, Dimension) else kd for kd in kdims]
        else:
            kdim_names = [kd.name for kd in eltype.kdims]

        if not isinstance(data, iris.cube.Cube):
            ndims = len(kdim_names)
            kdims = [kd if isinstance(kd, Dimension) else Dimension(kd)
                     for kd in kdims]
            vdim = vdims[0].name if isinstance(vdims[0], Dimension) else vdims[0]
            if isinstance(data, tuple):
                value_array = data[-1]
                data = {d: vals for d, vals in zip(kdim_names + [vdim], data)}
            elif isinstance(data, dict):
                value_array = data[vdim]
            coords = [(iris.coords.DimCoord(data[kd.name], long_name=kd.name,
                                            units=kd.unit), ndims-n-1)
                      for n, kd in enumerate(kdims)]
            try:
                data = iris.cube.Cube(value_array, long_name=vdim,
                                      dim_coords_and_dims=coords)
            except:
                pass
            if not isinstance(data, iris.cube.Cube):
                raise TypeError('Data must be be an iris dataset type.')

        if kdims:
            coords = []
            for kd in kdims:
                coord = data.coords(kd.name if isinstance(kd, Dimension) else kd)
                if len(coord) == 0:
                    raise ValueError('Key dimension %s not found in '
                                     'Iris cube.' % kd)
                coords.append(coord[0])
        else:
            coords = data.dim_coords
            coords = sorted(coords, key=sort_coords)
        kdims = [coord_to_dimension(crd) for crd in coords]
        if vdims is None:
            vdims = [Dimension(data.name(), unit=str(data.units))]

        return data, {'kdims':kdims, 'vdims':vdims}, {'group':data.name()}


    @classmethod
    def validate(cls, dataset):
        pass


    @classmethod
    def values(cls, dataset, dim, expanded=True, flat=True):
        """
        Returns an array of the values along the supplied dimension.
        """
        dim = dataset.get_dimension(dim)
        if dim in dataset.vdims:
            data = dataset.data.copy().data
            coord_names = [c.name() for c in dataset.data.dim_coords
                           if c.name() in dataset.kdims]
            dim_inds = [coord_names.index(d.name) for d in dataset.kdims]
            dim_inds += [i for i in range(len(dataset.data.dim_coords))
                         if i not in dim_inds]
            data = data.transpose(dim_inds[::-1])
        elif expanded:
            idx = dataset.get_dimension_index(dim)
            data = util.cartesian_product([dataset.data.coords(d.name)[0].points
                                           for d in dataset.kdims])[idx]
        else:
            data = dataset.data.coords(dim.name)[0].points
        return data.flatten() if flat else data


    @classmethod
    def reindex(cls, dataset, kdims=None, vdims=None):
        """
        Since cubes are never indexed directly the data itself
        does not need to be reindexed, the Element can simply
        reorder its key dimensions.
        """
        return dataset.data

<commit_msg>Implemented dropping static dimensions using iris reindex<commit_after>from __future__ import absolute_import

import datetime
from itertools import product

import iris
from iris.util import guess_coord_axis

import numpy as np

from .interface import Interface
from .grid import GridInterface
from ..ndmapping import (NdMapping, item_check, sorted_context)
from ..spaces import HoloMap, DynamicMap
from .. import util

from holoviews.core.dimension import Dimension


def get_date_format(coord):
    def date_formatter(val, pos=None):
        date = coord.units.num2date(val)
        date_format = Dimension.type_formatters.get(datetime.datetime, None)
        if date_format:
            return date.strftime(date_format)
        else:
            return date

    return date_formatter


def coord_to_dimension(coord):
    """
    Converts an iris coordinate to a HoloViews dimension.
    """
    kwargs = {}
    if coord.units.is_time_reference():
        kwargs['value_format'] = get_date_format(coord)
    else:
        kwargs['unit'] = str(coord.units)
    return Dimension(coord.name(), **kwargs)


def sort_coords(coord):
    """
    Sorts a list of DimCoords trying to ensure that
    dates and pressure levels appear first and the
    longitude and latitude appear last in the correct
    order.
    """
    order = {'T': -2, 'Z': -1, 'X': 1, 'Y': 2}
    axis = guess_coord_axis(coord)
    return (order.get(axis, 0), coord and coord.name())



class CubeInterface(GridInterface):
    """
    The CubeInterface provides allows HoloViews to interact with iris
    Cube data. When passing an iris Cube to a HoloViews Element the
    init method will infer the dimensions of the Cube from its
    coordinates. Currently the interface only provides the basic
    methods required for HoloViews to work with an object.
    """

    types = (iris.cube.Cube,)

    datatype = 'cube'

    @classmethod
    def init(cls, eltype, data, kdims, vdims):
        if kdims:
            kdim_names = [kd.name if isinstance(kd, Dimension) else kd for kd in kdims]
        else:
            kdim_names = [kd.name for kd in eltype.kdims]

        if not isinstance(data, iris.cube.Cube):
            ndims = len(kdim_names)
            kdims = [kd if isinstance(kd, Dimension) else Dimension(kd)
                     for kd in kdims]
            vdim = vdims[0].name if isinstance(vdims[0], Dimension) else vdims[0]
            if isinstance(data, tuple):
                value_array = data[-1]
                data = {d: vals for d, vals in zip(kdim_names + [vdim], data)}
            elif isinstance(data, dict):
                value_array = data[vdim]
            coords = [(iris.coords.DimCoord(data[kd.name], long_name=kd.name,
                                            units=kd.unit), ndims-n-1)
                      for n, kd in enumerate(kdims)]
            try:
                data = iris.cube.Cube(value_array, long_name=vdim,
                                      dim_coords_and_dims=coords)
            except:
                pass
            if not isinstance(data, iris.cube.Cube):
                raise TypeError('Data must be be an iris dataset type.')

        if kdims:
            coords = []
            for kd in kdims:
                coord = data.coords(kd.name if isinstance(kd, Dimension) else kd)
                if len(coord) == 0:
                    raise ValueError('Key dimension %s not found in '
                                     'Iris cube.' % kd)
                coords.append(coord[0])
        else:
            coords = data.dim_coords
            coords = sorted(coords, key=sort_coords)
        kdims = [coord_to_dimension(crd) for crd in coords]
        if vdims is None:
            vdims = [Dimension(data.name(), unit=str(data.units))]

        return data, {'kdims':kdims, 'vdims':vdims}, {'group':data.name()}


    @classmethod
    def validate(cls, dataset):
        pass


    @classmethod
    def values(cls, dataset, dim, expanded=True, flat=True):
        """
        Returns an array of the values along the supplied dimension.
        """
        dim = dataset.get_dimension(dim)
        if dim in dataset.vdims:
            data = dataset.data.copy().data
            coord_names = [c.name() for c in dataset.data.dim_coords
                           if c.name() in dataset.kdims]
            dim_inds = [coord_names.index(d.name) for d in dataset.kdims]
            dim_inds += [i for i in range(len(dataset.data.dim_coords))
                         if i not in dim_inds]
            data = data.transpose(dim_inds[::-1])
        elif expanded:
            idx = dataset.get_dimension_index(dim)
            data = util.cartesian_product([dataset.data.coords(d.name)[0].points
                                           for d in dataset.kdims])[idx]
        else:
            data = dataset.data.coords(dim.name)[0].points
        return data.flatten() if flat else data


    @classmethod
    def reindex(cls, dataset, kdims=None, vdims=None):
        """
        Since cubes are never indexed directly the data itself
        does not need to be reindexed, the Element can simply
        reorder its key dimensions.
        """
        if kdims and len(kdims) != dataset.ndims:
            drop_dims = [kd for kd in dataset.kdims if kd not in kdims]
            constraints = {}
            for d in drop_dims:
                vals = cls.values(dataset, d, False)
                if len(vals):
                    constraints[d.name] = vals[0]
            return dataset.data.extract(iris.Constraint(**constraints))
        return dataset.data


{'fraction_non_alphanumeric': 0.09183673469387756, 'fraction_numerical': 0.003061224489795918, 'mean_word_length': 1.9905686546463246, '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': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '488915', 'n_tokens_mistral': 3205, 'n_tokens_neox': 3163, 'n_words': 933}