Repository: climate Updated Branches: refs/heads/master 9e9ca1a91 -> 14d7f6e89
CLIMATE-349 Adding a function in utils which reshapes monthly data to annually shape with unittest Project: http://git-wip-us.apache.org/repos/asf/climate/repo Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/4e671d1a Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/4e671d1a Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/4e671d1a Branch: refs/heads/master Commit: 4e671d1a1feca313658df69d21eaf1ac2d523cb4 Parents: 5313dd7 Author: Maziyar Boustani <[email protected]> Authored: Wed May 21 13:56:08 2014 -0700 Committer: Maziyar Boustani <[email protected]> Committed: Wed May 21 13:56:08 2014 -0700 ---------------------------------------------------------------------- ocw/tests/test_utils.py | 32 ++++++++++++++++++++++++++++++-- ocw/utils.py | 39 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/climate/blob/4e671d1a/ocw/tests/test_utils.py ---------------------------------------------------------------------- diff --git a/ocw/tests/test_utils.py b/ocw/tests/test_utils.py index 849687f..f775b76 100644 --- a/ocw/tests/test_utils.py +++ b/ocw/tests/test_utils.py @@ -19,10 +19,12 @@ import unittest import urllib import os import datetime +from dateutil.relativedelta import relativedelta import netCDF4 import numpy as np +from ocw.dataset import Dataset import ocw.utils as utils class TestDecodeTimes(unittest.TestCase): @@ -104,7 +106,7 @@ class TestNormalizeLatLonValues(unittest.TestCase): np.testing.assert_array_equal(lons, np.arange(-180, 180)) def test_lats_reversed(self): - lons2 = np.arange(-180, 180) + lons2 = np.arange(-180, 180) lats, lons, values = utils.normalize_lat_lon_values(self.lats[::-1], lons2, self.values[:, ::-1, :]) @@ -142,6 +144,32 @@ class TestNormalizeLatLonValues(unittest.TestCase): self.lats2, self.lons_unsorted, self.values2) - + +class TestReshapeMonthlyToAnnually(unittest.TestCase): + ''' Testing function 'reshape_monthly_to_annually' from ocw.utils.py ''' + + def setUp(self): + self.lat = np.array([10, 12, 14, 16, 18]) + self.lon = np.array([100, 102, 104, 106, 108]) + self.time = np.array([datetime.datetime(2000, 1, 1) + relativedelta(months = x) for x in range(24)]) + flat_array = np.array(range(600)) + self.value = flat_array.reshape(24, 5, 5) + self.variable = 'prec' + self.test_dataset = Dataset(self.lat, self.lon, self.time, + self.value, self.variable) + + def test_reshape_full_year(self): + new_values = self.value.reshape(2,12,5,5) + np.testing.assert_array_equal( + utils.reshape_monthly_to_annually(self.test_dataset), new_values) + + def test_reshape_not_full_year(self): + new_time = np.array([datetime.datetime(2000, 1, 1) + relativedelta(months = x) for x in range(26)]) + flat_array = np.array(range(650)) + value = flat_array.reshape(26, 5, 5) + bad_dataset = Dataset(self.lat, self.lon, new_time, value, self.variable) + + self.assertRaises(ValueError,utils.reshape_monthly_to_annually,bad_dataset) + if __name__ == '__main__': unittest.main() http://git-wip-us.apache.org/repos/asf/climate/blob/4e671d1a/ocw/utils.py ---------------------------------------------------------------------- diff --git a/ocw/utils.py b/ocw/utils.py index 7c35422..0fc0b30 100644 --- a/ocw/utils.py +++ b/ocw/utils.py @@ -23,6 +23,7 @@ import numpy as np from mpl_toolkits.basemap import shiftgrid + def decode_time_values(dataset, time_var_name): ''' Decode NetCDF time values into Python datetime objects. @@ -61,8 +62,8 @@ def decode_time_values(dataset, time_var_name): def parse_time_units(time_format): ''' Parse units value from time units string. - The only units that are supported are: seconds, minutes, hours, days, - months, or years. + The only units that are supported are: seconds, minutes, hours, days, + months, or years. :param time_format: The time data units string from the dataset being processed. The string should be of the format @@ -214,3 +215,37 @@ def normalize_lat_lon_values(lats, lons, values): data_out, lons_out = shiftgrid(180, data_out, lons_out, start=False) return lats_out, lons_out, data_out + + +def reshape_monthly_to_annually(dataset): + ''' Reshaping 3D array dataset with shape (num_month, num_lat, num_lon) + to 4D array with shape (num_year, 12, num_lat, num_lon) + e.g. (24, 90, 180) to (2, 12, 90, 180) + + :param dataset: Dataset object with full-year format + :type dataset: Open Climate Workbench Dataset Object + + :returns: Dataset object with shape (num_year, num_month, num_lat, num_lon) + :rtype: Open Climate Workbench Dataset Object + ''' + + # Get dataset values + values = dataset.values + # Get values shape + data_shape = values.shape + # Get number of month in dataset + num_total_month = data_shape[0] + # Calculate number of years + num_year = num_total_month/12 + # Having each year as 12 months + num_month = 12 + # Create a new shape (number of year, number of month) + year_month_shape = num_year, num_month + # Get lat and lon shape + lat_lon_shape = data_shape[1:] + # Make new shape + new_shape = tuple(year_month_shape + lat_lon_shape) + # Reshape data with new shape (num_year, num_month, num_lat, num_lon) + values.shape = new_shape + + return values
