<commit_before>from matplotlib import pyplot as plt
import numpy as np

import param

from ..core import Dimension, ViewOperation, Overlay
from ..view import ItemTable, Matrix, VectorField, Contours


class chain(ViewOperation):
    """
    Definining a viewoperation chain is an easy way to define a new
    ViewOperation from a series of existing ones. The single argument
    is a callable that accepts an input view and returns a list of
    output views. To create the custom ViewOperation, you will need to
    supply this argument to a new instance of chain. For example:

    chain.instance(chain=lambda x: [cmap2rgb(operator(x).N, cmap='jet')])

    This is now a ViewOperation that sums the data in the input
    overlay and turns it into an RGB Matrix with the 'jet'
    colormap.
    """

    chain = param.Callable(doc="""A chain of existing ViewOperations.""")

    def _process(self, view, key=None):
        return self.p.chain(view)


class operator(ViewOperation):
    """
    Applies any arbitrary operator on the data (currently only
    supports SheetViews) and returns the result.
    """

    operator = param.Callable(np.add, doc="""
        The binary operator to apply between the data attributes of
        the supplied Views. By default, performs elementwise addition
        across the Matrix arrays.""")

    label = param.String(default='Operation', doc="""
        The label for the result after having applied the operator.""")

    def _process(self, overlay, key=None):

        if not isinstance(overlay, Overlay):
            raise Exception("Operation requires an Overlay as input")

        new_data = self.p.operator(*[el.data for el in overlay])
        return [Matrix(new_data, bounds=overlay[0].bounds, label=self.p.label,
                            roi_bounds=overlay[0].roi_bounds)]


class convolve(ViewOperation):
    """
    Apply a convolution to an overlay using the top layer as the
    kernel used to convolve the bottom layer. Both input Matrix
    elements in the overlay should be single-channel.
    """

    label = param.String(default='Convolution', doc="""
        The label to identify the output of the Convolution.""")

    kernel_roi = param.NumericTuple(default=(0,0,0,0), length=4, doc="""
        A 2-dimensional slice of the kernel layer to use in the
        convolution in lbrt (left, bottom, right, top) format. By
        default, no slicing is applied.""")

    def _process(self, view, key=None):

        if len(view) != 2:
            raise Exception("Overlay of two layers required.")

        [target, kernel] = view[0], view[1]

        if len(target.data.shape) != 2:
            raise Exception("Convolve requires monochrome inputs.")

        xslice = slice(self.p.kernel_roi[0], self.p.kernel_roi[2])
        yslice = slice(self.p.kernel_roi[1], self.p.kernel_roi[3])

        k = kernel.data if self.p.kernel_roi == (0,0,0,0) else kernel[xslice, yslice].data

        fft1 = np.fft.fft2(target.data)
        fft2 = np.fft.fft2(k, s= target.data.shape)
        convolved_raw = np.fft.ifft2(fft1 * fft2).real

        k_rows, k_cols = k.shape
        rolled = np.roll(np.roll(convolved_raw, -(k_cols//2), axis=-1), -(k_rows//2), axis=-2)
        convolved = rolled / float(k.sum())

        return [Matrix(convolved, bounds=target.bounds)]


class contours(ViewOperation):
    """
    Given a Matrix with a single channel, annotate it with contour
    lines for a given set of contour levels.

    The return is a overlay with a Contours layer for each given
    level, overlaid on top of the input Matrix.
    """

    levels = param.NumericTuple(default=(0.5,), doc="""
         A list of scalar values used to specify the contour levels.""")

    label = param.String(default='Level', doc="""
      The label suffix used to label the resulting contour curves
      where the suffix is added to the label of the  input Matrix""")

    def _process(self, sheetview, key=None):

        figure_handle = plt.figure()
        (l, b, r, t) = sheetview.bounds.lbrt()
        contour_set = plt.contour(sheetview.data, extent=(l, r, t, b),
                                  levels=self.p.levels)

        contours = []
        for level, cset in zip(self.p.levels, contour_set.collections):
            paths = cset.get_paths()
            lines = [path.vertices for path in paths]
            contours.append(Contours(lines, label=sheetview.label + ' ' + self.p.label))

        plt.close(figure_handle)

        if len(contours) == 1:
            return [(sheetview * contours[0])]
        else:
            return [sheetview * Overlay(contours, sheetview.bounds)]


class vectorfield(ViewOperation):
    """
    Given a Matrix with a single channel, convert it to a
    VectorField object at a given spatial sampling interval. The
    values in the Matrix are assumed to correspond to the vector
    angle in radians and the value is assumed to be cyclic.

    If supplied with an overlay, the second sheetview in the overlay
    will be interpreted as the third vector dimension.
    """

    rows = param.Integer(default=10, doc="""
         Number of rows in the vector field.""")

    cols = param.Integer(default=10, doc="""<commit_msg>Fixed leftover bounds on Overlay<commit_after>from matplotlib import pyplot as plt
import numpy as np

import param

from ..core import Dimension, ViewOperation, Overlay
from ..view import ItemTable, Matrix, VectorField, Contours


class chain(ViewOperation):
    """
    Definining a viewoperation chain is an easy way to define a new
    ViewOperation from a series of existing ones. The single argument
    is a callable that accepts an input view and returns a list of
    output views. To create the custom ViewOperation, you will need to
    supply this argument to a new instance of chain. For example:

    chain.instance(chain=lambda x: [cmap2rgb(operator(x).N, cmap='jet')])

    This is now a ViewOperation that sums the data in the input
    overlay and turns it into an RGB Matrix with the 'jet'
    colormap.
    """

    chain = param.Callable(doc="""A chain of existing ViewOperations.""")

    def _process(self, view, key=None):
        return self.p.chain(view)


class operator(ViewOperation):
    """
    Applies any arbitrary operator on the data (currently only
    supports SheetViews) and returns the result.
    """

    operator = param.Callable(np.add, doc="""
        The binary operator to apply between the data attributes of
        the supplied Views. By default, performs elementwise addition
        across the Matrix arrays.""")

    label = param.String(default='Operation', doc="""
        The label for the result after having applied the operator.""")

    def _process(self, overlay, key=None):

        if not isinstance(overlay, Overlay):
            raise Exception("Operation requires an Overlay as input")

        new_data = self.p.operator(*[el.data for el in overlay])
        return [Matrix(new_data, bounds=overlay[0].bounds, label=self.p.label,
                            roi_bounds=overlay[0].roi_bounds)]


class convolve(ViewOperation):
    """
    Apply a convolution to an overlay using the top layer as the
    kernel used to convolve the bottom layer. Both input Matrix
    elements in the overlay should be single-channel.
    """

    label = param.String(default='Convolution', doc="""
        The label to identify the output of the Convolution.""")

    kernel_roi = param.NumericTuple(default=(0,0,0,0), length=4, doc="""
        A 2-dimensional slice of the kernel layer to use in the
        convolution in lbrt (left, bottom, right, top) format. By
        default, no slicing is applied.""")

    def _process(self, view, key=None):

        if len(view) != 2:
            raise Exception("Overlay of two layers required.")

        [target, kernel] = view[0], view[1]

        if len(target.data.shape) != 2:
            raise Exception("Convolve requires monochrome inputs.")

        xslice = slice(self.p.kernel_roi[0], self.p.kernel_roi[2])
        yslice = slice(self.p.kernel_roi[1], self.p.kernel_roi[3])

        k = kernel.data if self.p.kernel_roi == (0,0,0,0) else kernel[xslice, yslice].data

        fft1 = np.fft.fft2(target.data)
        fft2 = np.fft.fft2(k, s= target.data.shape)
        convolved_raw = np.fft.ifft2(fft1 * fft2).real

        k_rows, k_cols = k.shape
        rolled = np.roll(np.roll(convolved_raw, -(k_cols//2), axis=-1), -(k_rows//2), axis=-2)
        convolved = rolled / float(k.sum())

        return [Matrix(convolved, bounds=target.bounds)]


class contours(ViewOperation):
    """
    Given a Matrix with a single channel, annotate it with contour
    lines for a given set of contour levels.

    The return is a overlay with a Contours layer for each given
    level, overlaid on top of the input Matrix.
    """

    levels = param.NumericTuple(default=(0.5,), doc="""
         A list of scalar values used to specify the contour levels.""")

    label = param.String(default='Level', doc="""
      The label suffix used to label the resulting contour curves
      where the suffix is added to the label of the  input Matrix""")

    def _process(self, sheetview, key=None):

        figure_handle = plt.figure()
        (l, b, r, t) = sheetview.lbrt
        contour_set = plt.contour(sheetview.data, extent=(l, r, t, b),
                                  levels=self.p.levels)

        contours = []
        for level, cset in zip(self.p.levels, contour_set.collections):
            paths = cset.get_paths()
            lines = [path.vertices for path in paths]
            contours.append(Contours(lines, label=sheetview.label + ' ' + self.p.label))

        plt.close(figure_handle)

        if len(contours) == 1:
            return [(sheetview * contours[0])]
        else:
            return [sheetview * Overlay(contours)]


class vectorfield(ViewOperation):
    """
    Given a Matrix with a single channel, convert it to a
    VectorField object at a given spatial sampling interval. The
    values in the Matrix are assumed to correspond to the vector
    angle in radians and the value is assumed to be cyclic.

    If supplied with an overlay, the second sheetview in the overlay
    will be interpreted as the third vector dimension.
    """

    rows = param.Integer(default=10, doc="""
         Number of rows in the vector field.""")

    cols = param.Integer(default=10, doc="""
{'fraction_non_alphanumeric': 0.09996166379145102, 'fraction_numerical': 0.007667241709794902, 'mean_word_length': 2.769869942196532, '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': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7191598', 'n_tokens_mistral': 3097, 'n_tokens_neox': 2940, 'n_words': 1090}