You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@climate.apache.org by go...@apache.org on 2013/08/13 03:51:58 UTC

svn commit: r1513316 - in /incubator/climate/branches/RefactorInput/ocw: dataset_processor.py tests/test_dataset_processor.py

Author: goodale
Date: Tue Aug 13 01:51:57 2013
New Revision: 1513316

URL: http://svn.apache.org/r1513316
Log:
CLIMATE-236:  Added the ensemble functionality with unit tests.

Modified:
    incubator/climate/branches/RefactorInput/ocw/dataset_processor.py
    incubator/climate/branches/RefactorInput/ocw/tests/test_dataset_processor.py

Modified: incubator/climate/branches/RefactorInput/ocw/dataset_processor.py
URL: http://svn.apache.org/viewvc/incubator/climate/branches/RefactorInput/ocw/dataset_processor.py?rev=1513316&r1=1513315&r2=1513316&view=diff
==============================================================================
--- incubator/climate/branches/RefactorInput/ocw/dataset_processor.py (original)
+++ incubator/climate/branches/RefactorInput/ocw/dataset_processor.py Tue Aug 13 01:51:57 2013
@@ -110,7 +110,28 @@ def spatial_regrid(target_dataset, new_l
     return regridded_dataset
 
 def ensemble(datasets):
-    pass
+    """
+    Generate a single dataset which is the mean of the input datasets
+    
+    :param datasets: Datasets to be used to compose the ensemble dataset from.
+    Note - All Datasets must be the same shape
+    :type datasets: List of OCW Dataset Objects
+    
+    :returns: New Dataset with a name of 'Dataset Ensemble'
+    :rtype: OCW Dataset Object
+    """
+    _check_dataset_shapes(datasets)
+    dataset_values = [dataset.values for dataset in datasets]
+    ensemble_values = np.mean(dataset_values, axis=0)
+    
+    # Build new dataset object from the input datasets and the ensemble values and return it
+    ensemble_dataset = ds.Dataset(datasets[0].lats, 
+                                  datasets[0].lons, 
+                                  datasets[0].times,
+                                  ensemble_values,
+                                  name="Dataset Ensemble")
+    
+    return ensemble_dataset
 
 def _rcmes_spatial_regrid(spatial_values, lat, lon, lat2, lon2, order=1):
     '''
@@ -468,6 +489,25 @@ def _congrid(a, newdims, method='linear'
               "and \'spline\' are supported."
         return None
 
+def _check_dataset_shapes(datasets):
+    """ If the  datasets are not the same shape throw a ValueError Exception
+    
+    :param datasets: OCW Datasets to check for a consistent shape
+    :type datasets: List of OCW Dataset Objects
+    
+    :raises: ValueError
+    """
+    dataset_shape = None
+    for dataset in datasets:
+        if dataset_shape == None:
+            dataset_shape = dataset.values.shape
+        else:
+            if dataset.values.shape != dataset_shape:
+                raise ValueError("Input datasets must be the same shape for an ensemble")
+            else:
+                pass
+
+
 def _congrid_neighbor(values, new_dims, minus_one, offset):
     """ Use the nearest neighbor to create a new array
     

Modified: incubator/climate/branches/RefactorInput/ocw/tests/test_dataset_processor.py
URL: http://svn.apache.org/viewvc/incubator/climate/branches/RefactorInput/ocw/tests/test_dataset_processor.py?rev=1513316&r1=1513315&r2=1513316&view=diff
==============================================================================
--- incubator/climate/branches/RefactorInput/ocw/tests/test_dataset_processor.py (original)
+++ incubator/climate/branches/RefactorInput/ocw/tests/test_dataset_processor.py Tue Aug 13 01:51:57 2013
@@ -27,6 +27,36 @@ class CustomAssertions:
     def assert1DArraysEqual(self, array1, array2):
         self.assertSequenceEqual(tuple(array1), tuple(array2))
 
+class TestEnsemble(unittest.TestCase, CustomAssertions):
+    
+    def test_unequal_dataset_shapes(self):
+        self.ten_year_dataset = ten_year_monthly_dataset()
+        self.two_year_dataset = two_year_daily_dataset()
+        with self.assertRaises(ValueError):
+            self.ensemble_dataset = dp.ensemble([self.ten_year_dataset, self.two_year_dataset])
+    
+    def test_ensemble_logic(self):
+        self.datasets = []
+        self.datasets.append(build_ten_cube_dataset(1))
+        self.datasets.append(build_ten_cube_dataset(2))
+        self.three = build_ten_cube_dataset(3)
+        self.datasets.append(self.three)
+        self.datasets.append(build_ten_cube_dataset(4))
+        self.datasets.append(build_ten_cube_dataset(5))
+        self.ensemble = dp.ensemble(self.datasets)
+        self.ensemble_flat = self.ensemble.values.flatten()
+        self.three_flat = self.three.values.flatten()
+        self.assert1DArraysEqual(self.ensemble_flat, self.three_flat)
+    
+    def test_ensemble_name(self):
+        self.ensemble_dataset_name = "Dataset Ensemble"
+        self.datasets = []
+        self.datasets.append(build_ten_cube_dataset(1))
+        self.datasets.append(build_ten_cube_dataset(2))
+        self.ensemble = dp.ensemble(self.datasets)
+        self.assertEquals(self.ensemble.name, self.ensemble_dataset_name)
+        
+
 class TestTemporalRebin(unittest.TestCase, CustomAssertions):
     
     def setUp(self):
@@ -67,7 +97,6 @@ class TestTemporalRebin(unittest.TestCas
         self.assert1DArraysEqual(monthly_dataset.times, good_times)
 
 
-
 class TestRcmesSpatialRegrid(unittest.TestCase):
 
     def test_return_array_shape(self):
@@ -131,6 +160,15 @@ def two_year_daily_dataset():
     dataset = ds.Dataset(lats, lons, times, values, variable='random data')
     return dataset    
 
+def build_ten_cube_dataset(value):
+    lats = np.array(range(-89, 90, 18))
+    lons = np.array(range(-179, 180, 36))
+    times = np.array([datetime.datetime(year, 1, 1) for year in range(2000, 2010)])
+    values = np.ones([len(times), len(lats), len(lons)])
+    values = values * value
+    dataset = ds.Dataset(lats, lons, times, values)
+    return dataset
+    
 
 
 if __name__ == '__main__':