<commit_before># This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from abc import abstractmethod
from ..backend import Backend

from ....plots import BandsPlot


class BandsBackend(Backend):
    """Draws the bands provided by a `BandsPlot`

    The workflow implemented by it is as follows:
        First, `self.draw_bands` draws all bands like:
            for band in bands:
                if (spin texture needs to be drawn):
                    `self._draw_spin_textured_band()`, NO GENERIC IMPLEMENTATION (optional) 
                else:
                    `self._draw_band()`, generic implementation that calls `self._draw_line`
        Once all bands are drawn, `self.draw_gaps` loops through all the gaps to be drawn:
            for gap in gaps:
                `self.draw_gap()`, MUST BE IMPLEMENTED!
    """

    def draw(self, backend_info):
        self.draw_bands(**backend_info["draw_bands"])

        self._draw_gaps(backend_info["gaps"])

    def draw_bands(self, filtered_bands, line, spindown_line, spin, spin_texture, add_band_data):
        """
        Manages the flow of drawing all the bands

        Parameters
        -----------
        filtered_bands: xarray.DataArray
            The bands values, with only those bands that need to be plotted.
        line: dict
            The line style of the bands, as with plotly standards.
        spindown_line: dict
            Special styles for spin down bands. All styles not specified will be taken
            from `line`.
        spin: Spin
            The spin class associated to the bands calculation
        spin_texture: dict
            Containing the keys:
                - "show": bool, whether spin texture needs to be displayed
                - "values": xarray.DataArray, the spin texture values that have to be displayed.
                - "colorscale": str, the colorscale to use for the spin texture values.
        """
        if spin_texture["show"]:
            draw_band_func = self._draw_spin_textured_band
            spin_moments = spin_texture["values"]
        else:
            draw_band_func = self._draw_band

        if "spin" not in filtered_bands.coords:
            filtered_bands = filtered_bands.expand_dims("spin")

        # Now loop through all bands to draw them
        for ispin, spin_bands in enumerate(filtered_bands.transpose('spin', 'band', 'k')):
            line_style = line
            if ispin == 1:
                line_style.update(spindown_line)
            for band in spin_bands:
                # Get the xy values for the band
                x = band.k.values
                y = band.values
                kwargs = {
                    "name": "{} spin {}".format(band.band.values, ["up", "down"][ispin]) if spin.is_polarized else str(band.band.values),
                    "line": line_style,
                    **add_band_data(band, self._plot)
                }

                # And plot it differently depending on whether we need to display spin texture or not.
                if not spin_texture["show"]:
                    draw_band_func(x, y, **kwargs)
                else:
                    spin_texture_vals = spin_moments.sel(band=band.band.values).values
                    draw_band_func(x, y, spin_texture_vals=spin_texture_vals, **kwargs)

    def _draw_band(self, *args, **kwargs):
        return self.draw_line(*args, **kwargs)

    def _draw_spin_textured_band(self, *args, **kwargs):
        return NotImplementedError(f"{self.__class__.__name__} doesn't implement plotting spin_textured bands.")

    def _draw_gaps(self, gaps_info):
        """Iterates over all gaps to draw them"""<commit_msg>bug: fixed spin index in bands<commit_after># This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from abc import abstractmethod
from ..backend import Backend

from ....plots import BandsPlot


class BandsBackend(Backend):
    """Draws the bands provided by a `BandsPlot`

    The workflow implemented by it is as follows:
        First, `self.draw_bands` draws all bands like:
            for band in bands:
                if (spin texture needs to be drawn):
                    `self._draw_spin_textured_band()`, NO GENERIC IMPLEMENTATION (optional) 
                else:
                    `self._draw_band()`, generic implementation that calls `self._draw_line`
        Once all bands are drawn, `self.draw_gaps` loops through all the gaps to be drawn:
            for gap in gaps:
                `self.draw_gap()`, MUST BE IMPLEMENTED!
    """

    def draw(self, backend_info):
        self.draw_bands(**backend_info["draw_bands"])

        self._draw_gaps(backend_info["gaps"])

    def draw_bands(self, filtered_bands, line, spindown_line, spin, spin_texture, add_band_data):
        """
        Manages the flow of drawing all the bands

        Parameters
        -----------
        filtered_bands: xarray.DataArray
            The bands values, with only those bands that need to be plotted.
        line: dict
            The line style of the bands, as with plotly standards.
        spindown_line: dict
            Special styles for spin down bands. All styles not specified will be taken
            from `line`.
        spin: Spin
            The spin class associated to the bands calculation
        spin_texture: dict
            Containing the keys:
                - "show": bool, whether spin texture needs to be displayed
                - "values": xarray.DataArray, the spin texture values that have to be displayed.
                - "colorscale": str, the colorscale to use for the spin texture values.
        """
        if spin_texture["show"]:
            draw_band_func = self._draw_spin_textured_band
            spin_moments = spin_texture["values"]
        else:
            draw_band_func = self._draw_band

        if "spin" not in filtered_bands.coords:
            filtered_bands = filtered_bands.expand_dims("spin")

        # Now loop through all bands to draw them
        for spin_bands in filtered_bands.transpose('spin', 'band', 'k'):
            ispin = int(spin_bands.spin)
            line_style = line
            if ispin == 1:
                line_style.update(spindown_line)
            for band in spin_bands:
                # Get the xy values for the band
                x = band.k.values
                y = band.values
                kwargs = {
                    "name": "{} spin {}".format(band.band.values, ["up", "down"][ispin]) if spin.is_polarized else str(band.band.values),
                    "line": line_style,
                    **add_band_data(band, self._plot)
                }

                # And plot it differently depending on whether we need to display spin texture or not.
                if not spin_texture["show"]:
                    draw_band_func(x, y, **kwargs)
                else:
                    spin_texture_vals = spin_moments.sel(band=band.band.values).values
                    draw_band_func(x, y, spin_texture_vals=spin_texture_vals, **kwargs)

    def _draw_band(self, *args, **kwargs):
        return self.draw_line(*args, **kwargs)

    def _draw_spin_textured_band(self, *args, **kwargs):
        return NotImplementedError(f"{self.__class__.__name__} doesn't implement plotting spin_textured bands.")

    def _draw_gaps(self, gaps_info):
        """Iterates over all gaps to draw them"""
{'fraction_non_alphanumeric': 0.08581116327595201, 'fraction_numerical': 0.0013041210224308817, 'mean_word_length': 2.049304174950298, 'pattern_counts': {'":': 10, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '402886', 'n_tokens_mistral': 2124, 'n_tokens_neox': 2013, 'n_words': 701}