<commit_before>import json
import math
import os
from statistics import mean

import numpy
from django.conf import settings
from django.contrib.gis.geos import Polygon
from django.core.management import BaseCommand
from django.db import transaction
from ncdjango.models import Service, SERVICE_DATA_ROOT, Variable
from netCDF4 import Dataset
from pyproj import Proj
from rasterio.features import rasterize
from seedsource_core.django.seedsource.models import TransferLimit, Region, ZoneSource
from trefoil.geometry.bbox import BBox
from trefoil.netcdf.crs import set_crs
from trefoil.netcdf.variable import SpatialCoordinateVariables
from trefoil.render.renderers.stretched import StretchedRenderer
from trefoil.utilities.color import Color
from trefoil.utilities.window import Window

from ..utils import ZoneConfig

VARIABLES = (
    'MAT', 'MWMT', 'MCMT', 'TD', 'MAP', 'MSP', 'AHM', 'SHM', 'DD_0', 'DD5', 'FFP', 'PAS', 'EMT', 'EXT', 'Eref', 'CMD'
)


class Command(BaseCommand):
    help = 'Calculates default variable transfer limits for each available seed zone'

    def __init__(self, *args, **kwargs):
        self.transfers_by_source = {}

        super().__init__(*args, **kwargs)

    def add_arguments(self, parser):
        parser.add_argument('source_name', nargs='?', type=str, default='all', help='Accepts zone name or all')

    def _get_subsets(self, elevation, data, coords: SpatialCoordinateVariables, bbox):
        """ Returns subsets of elevation, data, and coords, clipped to the given bounds """

        x_slice = slice(*coords.x.indices_for_range(bbox.xmin, bbox.xmax))
        y_slice = slice(*coords.y.indices_for_range(bbox.ymin, bbox.ymax))

        return elevation[y_slice, x_slice], data[y_slice, x_slice], coords.slice_by_window(Window(y_slice, x_slice))

    def _write_limit(self, variable, time_period, zone, masked_data, low=None, high=None, label=None):
        min_value = numpy.nanmin(masked_data)
        max_value = numpy.nanmax(masked_data)
        transfer = (max_value - min_value) / 2.0
        center = max_value - transfer

        if numpy.isnan(transfer) or hasattr(transfer, 'mask'):
            self.stdout.write('WARNING: Transfer limit is NaN for {}, zone {}, band {}-{}'.format(
                zone.zone_source.name, zone.zone_id, low, high
            ))
            return

        tl = TransferLimit.objects.create(
            variable=variable, time_period=time_period, zone=zone, transfer=transfer, center=center, low=low,
            high=high, label=label
        )<commit_msg>Work  around bug with small coordinate ranges<commit_after>import json
import math
import os
from statistics import mean

import numpy
from django.conf import settings
from django.contrib.gis.geos import Polygon
from django.core.management import BaseCommand
from django.db import transaction
from ncdjango.models import Service, SERVICE_DATA_ROOT, Variable
from netCDF4 import Dataset
from pyproj import Proj
from rasterio.features import rasterize
from seedsource_core.django.seedsource.models import TransferLimit, Region, ZoneSource
from trefoil.geometry.bbox import BBox
from trefoil.netcdf.crs import set_crs
from trefoil.netcdf.variable import SpatialCoordinateVariables, SpatialCoordinateVariable
from trefoil.render.renderers.stretched import StretchedRenderer
from trefoil.utilities.color import Color
from trefoil.utilities.window import Window

from ..utils import ZoneConfig

VARIABLES = (
    'MAT', 'MWMT', 'MCMT', 'TD', 'MAP', 'MSP', 'AHM', 'SHM', 'DD_0', 'DD5', 'FFP', 'PAS', 'EMT', 'EXT', 'Eref', 'CMD'
)


class Command(BaseCommand):
    help = 'Calculates default variable transfer limits for each available seed zone'

    def __init__(self, *args, **kwargs):
        self.transfers_by_source = {}

        super().__init__(*args, **kwargs)

    def add_arguments(self, parser):
        parser.add_argument('source_name', nargs='?', type=str, default='all', help='Accepts zone name or all')

    def _get_subsets(self, elevation, data, coords: SpatialCoordinateVariables, bbox):
        """ Returns subsets of elevation, data, and coords, clipped to the given bounds """

        x_slice = slice(*coords.x.indices_for_range(bbox.xmin, bbox.xmax))
        y_slice = slice(*coords.y.indices_for_range(bbox.ymin, bbox.ymax))

        if x_slice.stop - x_slice.start < 2:
            x_slice = slice(x_slice.start, x_slice.start + 2)
        if y_slice.stop - y_slice.start < 2:
            y_slice = slice(y_slice.start, y_slice.start + 2)

        return elevation[y_slice, x_slice], data[y_slice, x_slice], coords.slice_by_window(Window(y_slice, x_slice))

    def _write_limit(self, variable, time_period, zone, masked_data, low=None, high=None, label=None):
        min_value = numpy.nanmin(masked_data)
        max_value = numpy.nanmax(masked_data)
        transfer = (max_value - min_value) / 2.0
        center = max_value - transfer

        if numpy.isnan(transfer) or hasattr(transfer, 'mask'):
            self.stdout.write('WARNING: Transfer limit is NaN for {}, zone {}, band {}-{}'.format(
                zone.zone_source.name, zone.zone_id, low, high
            ))
            return

        tl = TransferLimit.objects.create(
            variable=variable, time_period=time_period, zone=zone, transfer=transfer, center=center, low=low,
            high=high, label=label
        )
{'fraction_non_alphanumeric': 0.10652985074626865, 'fraction_numerical': 0.0026119402985074628, 'mean_word_length': 3.838447653429603, 'pattern_counts': {'":': 0, '<': 5, '<?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': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '379602', 'n_tokens_mistral': 1694, 'n_tokens_neox': 1640, 'n_words': 443}