Esempio n. 1
0
    def _set_constraint_limits(self, data, subset_constraint):
        """
        Identify and set the constraint limits by:
        * parsing anything that needs parsing (datetimes)
        * ordering them always

        :param data:
        :param subset_constraint:
        :return:
        """
        for coord in data.coords():
            # Match user-specified limits with dimensions found in data.
            guessed_axis = guess_coord_axis(coord)
            limit = None
            if coord.name() in self._limits:
                limit = self._limits[coord.name()]
            elif guessed_axis is not None:
                if guessed_axis in self._limits:
                    limit = self._limits[guessed_axis]
                elif guessed_axis.lower() in self._limits:
                    limit = self._limits[guessed_axis.lower()]

            if limit is not None:
                wrapped = False
                if limit.is_time or guessed_axis == 'T':
                    # Ensure that the limits are date/times.
                    dt = parse_datetime.convert_datetime_components_to_datetime(limit.start, True)
                    limit_start = self._convert_datetime_to_coord_unit(coord, dt)
                    dt = parse_datetime.convert_datetime_components_to_datetime(limit.end, False)
                    limit_end = self._convert_datetime_to_coord_unit(coord, dt)
                else:
                    # Assume to be a non-time axis.
                    (limit_start, limit_end) = self._fix_non_circular_limits(float(limit.start), float(limit.end))
                subset_constraint.set_limit(coord, limit_start, limit_end)
Esempio n. 2
0
    def get_grid(self, coord):

        grid = None
        guessed_axis = guess_coord_axis(coord)
        if coord.name() in self._grid:
            grid = self._grid.pop(coord.name())
        elif coord.standard_name in self._grid:
            grid = self._grid.pop(coord.standard_name)
        elif coord.long_name in self._grid:
            grid = self._grid.pop(coord.long_name)
        elif guessed_axis is not None:
            if guessed_axis in self._grid:
                grid = self._grid.pop(guessed_axis)
            elif guessed_axis.lower() in self._grid:
                grid = self._grid.pop(guessed_axis.lower())

        return grid, guessed_axis
Esempio n. 3
0
    def _create_data_for_subset(self, data):
        """
        Produce a copy of the data so that the original is not altered,
        with longitudes mapped onto the right domain for the requested limits
        :param data: Data being subsetted
        :return:
        """
        # We need a copy with new data and coordinates
        data = data.copy()
        for coord in data.coords():
            # Match user-specified limits with dimensions found in data.
            if coord.name() in self._limits:
                guessed_axis = guess_coord_axis(coord)
                if guessed_axis == 'X':
                    lon_limits = self._limits[coord.name()]
                    lon_coord = coord
                    if isinstance(lon_coord, iris.coords.Coord):
                        coord_min = lon_coord.points.min()
                        coord_max = lon_coord.points.max()
                    else:
                        coord_min = lon_coord.data.min()
                        coord_max = lon_coord.data.max()
                    data_below_zero = coord_min < 0
                    data_above_180 = coord_max > 180
                    limits_below_zero = lon_limits.start < 0 or lon_limits.end < 0
                    limits_above_180 = lon_limits.start > 180 or lon_limits.end > 180

                    if data_below_zero and not data_above_180:
                        # i.e. data is in the range -180 -> 180
                        # Only convert the data if the limits are above 180:
                        if limits_above_180 and not limits_below_zero:
                            # Convert data from -180 -> 180 to 0 -> 360
                            range_start = 0
                            coord.set_longitude_range(range_start)
                    elif data_above_180 and not data_below_zero:
                        # i.e. data is in the range 0 -> 360
                        if limits_below_zero and not limits_above_180:
                            # Convert data from 0 -> 360 to -180 -> 180
                            range_start = -180
                            coord.set_longitude_range(range_start)
                # Ensure the limits also have the new longitude coordinate
                self._limits[coord.name()].coord.data = coord.data
        return data
Esempio n. 4
0
    def _set_constraint_limits(self, data, subset_constraint):
        """
        Identify and set the constraint limits on the subset_constraint object using the coordinates from the data
        object

        :param data: The data object containing the coordinates to subset
        :param subset_constraint: The constraint object on to which to apply the limits
        """

        for coord in data.coords(dim_coords=True):
            # Match user-specified limits with dimensions found in data.
            guessed_axis = guess_coord_axis(coord)
            limit = None
            if coord.name() in self._limits:
                limit = self._limits.pop(coord.name())
            elif hasattr(coord, 'var_name') and coord.var_name in self._limits:
                limit = self._limits.pop(coord.var_name)
            elif coord.standard_name in self._limits:
                limit = self._limits.pop(coord.standard_name)
            elif coord.long_name in self._limits:
                limit = self._limits.pop(coord.long_name)
            elif guessed_axis is not None:
                if guessed_axis in self._limits:
                    limit = self._limits.pop(guessed_axis)
                elif guessed_axis.lower() in self._limits:
                    limit = self._limits.pop(guessed_axis.lower())

            if limit is not None:
                wrapped = False
                if limit.is_time or guessed_axis == 'T':
                    # Ensure that the limits are date/times.
                    dt = parse_datetime.convert_datetime_components_to_datetime(limit.start, True)
                    limit_start = self._convert_datetime_to_coord_unit(coord, dt)
                    dt = parse_datetime.convert_datetime_components_to_datetime(limit.end, False)
                    limit_end = self._convert_datetime_to_coord_unit(coord, dt)
                else:
                    # Assume to be a non-time axis.
                    (limit_start, limit_end) = self._fix_non_circular_limits(float(limit.start), float(limit.end))
                # Apply the limit to the constraint object
                subset_constraint.set_limit(coord, limit_start, limit_end)