# Source code for cate.ops.resampling

# Copyright (c) 2016, 2017 by the ESA CCI Toolbox development team and contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is furnished to do
# so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
Description
===========

Provides various resampling methods including up- and downsampling.

Components
==========
"""
# http://stackoverflow.com/questions/7075082/what-is-future-in-python-used-for-and-how-when-to-use-it-and-how-it-works
from __future__ import division

import numpy as np
from numba import jit

#: Interpolation method for upsampling: Take nearest source grid cell, even if it is invalid.
US_NEAREST = 10
#: Interpolation method for upsampling: Bi-linear interpolation between the 4 nearest source grid cells.
US_LINEAR = 11

#: Aggregation method for downsampling: Take first valid source grid cell, ignore contribution areas.
DS_FIRST = 50
#: Aggregation method for downsampling: Take last valid source grid cell, ignore contribution areas.
DS_LAST = 51
# DS_MIN = 52
# DS_MAX = 53
#: Aggregation method for downsampling: Compute average of all valid source grid cells,
#: with weights given by contribution area.
DS_MEAN = 54
# DS_MEDIAN = 55
#: Aggregation method for downsampling: Compute most frequently seen valid source grid cell,
#: with frequency given by contribution area. Note that this mode can use an additional keyword argument
#: *mode_rank* which can be used to generate the n-th mode. See :py:function:downsample_2d.
DS_MODE = 56
#: Aggregation method for downsampling: Compute the biased weighted estimator of variance
#: (see https://en.wikipedia.org/wiki/Mean_square_weighted_deviation), with weights given by contribution area.
DS_VAR = 57
#: Aggregation method for downsampling: Compute the corresponding standard deviation to the biased weighted estimator
#: of variance
#: (see https://en.wikipedia.org/wiki/Mean_square_weighted_deviation), with weights given by contribution area.
DS_STD = 58

#: Constant indicating an empty 2-D mask
[docs]def resample_2d(src, w, h, ds_method=DS_MEAN, us_method=US_LINEAR, fill_value=None, mode_rank=1, out=None): """ Resample a 2-D grid to a new resolution. :param src: 2-D *ndarray* :param w: *int* New grid width :param h: *int* New grid height :param ds_method: one of the *DS_* constants, optional Grid cell aggregation method for a possible downsampling :param us_method: one of the *US_* constants, optional Grid cell interpolation method for a possible upsampling :param fill_value: *scalar*, optional If None, it is taken from **src** if it is a masked array, otherwise from *out* if it is a masked array, otherwise numpy's default value is used. :param mode_rank: *scalar*, optional The rank of the frequency determined by the *ds_method* DS_MODE. One (the default) means most frequent value, zwo means second most frequent value, and so forth. :param out: 2-D *ndarray*, optional Alternate output array in which to place the result. The default is *None*; if provided, it must have the same shape as the expected output. :return: An resampled version of the *src* array. """ out = _get_out(out, src, (h, w)) if out is None: return src mask, use_mask = _get_mask(src) fill_value = _get_fill_value(fill_value, src, out) return _mask_or_not(_resample_2d(src, mask, use_mask, ds_method, us_method, fill_value, mode_rank, out), src, fill_value)
[docs]def upsample_2d(src, w, h, method=US_LINEAR, fill_value=None, out=None): """ Upsample a 2-D grid to a higher resolution by interpolating original grid cells. :param src: 2-D *ndarray* :param w: *int* Grid width, which must be greater than or equal to *src.shape[-1]* :param h: *int* Grid height, which must be greater than or equal to *src.shape[-2]* :param method: one of the *US_* constants, optional Grid cell interpolation method :param fill_value: *scalar*, optional If None, it is taken from **src** if it is a masked array, otherwise from *out* if it is a masked array, otherwise numpy's default value is used. :param out: 2-D *ndarray*, optional Alternate output array in which to place the result. The default is *None*; if provided, it must have the same shape as the expected output. :return: An upsampled version of the *src* array. """ out = _get_out(out, src, (h, w)) if out is None: return src mask, use_mask = _get_mask(src) fill_value = _get_fill_value(fill_value, src, out) return _mask_or_not(_upsample_2d(src, mask, use_mask, method, fill_value, out), src, fill_value)
[docs]def downsample_2d(src, w, h, method=DS_MEAN, fill_value=None, mode_rank=1, out=None): """ Downsample a 2-D grid to a lower resolution by aggregating original grid cells. :param src: 2-D *ndarray* :param w: *int* Grid width, which must be less than or equal to *src.shape[-1]* :param h: *int* Grid height, which must be less than or equal to *src.shape[-2]* :param method: one of the *DS_* constants, optional Grid cell aggregation method :param fill_value: *scalar*, optional If None, it is taken from **src** if it is a masked array, otherwise from *out* if it is a masked array, otherwise numpy's default value is used. :param mode_rank: *scalar*, optional The rank of the frequency determined by the *method* DS_MODE. One (the default) means most frequent value, zwo means second most frequent value, and so forth. :param out: 2-D *ndarray*, optional Alternate output array in which to place the result. The default is *None*; if provided, it must have the same shape as the expected output. :return: A downsampled version of the *src* array. """ if method == DS_MODE and mode_rank < 1: raise ValueError('mode_rank must be >= 1') out = _get_out(out, src, (h, w)) if out is None: return src mask, use_mask = _get_mask(src) fill_value = _get_fill_value(fill_value, src, out) return _mask_or_not(_downsample_2d(src, mask, use_mask, method, fill_value, mode_rank, out), src, fill_value)