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)
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
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
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)