You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@climate.apache.org by jo...@apache.org on 2015/03/31 16:59:20 UTC
[01/13] climate git commit: CLIMATE-581 - Add dataset output
formatting for config writing.
Repository: climate
Updated Branches:
refs/heads/master e4cbce78e -> 531661c5d
CLIMATE-581 - Add dataset output formatting for config writing.
Project: http://git-wip-us.apache.org/repos/asf/climate/repo
Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/0c2a9313
Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/0c2a9313
Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/0c2a9313
Branch: refs/heads/master
Commit: 0c2a931311c1777cf81aed4537137ad28d717b57
Parents: 9a2be2e
Author: Michael Joyce <jo...@apache.org>
Authored: Tue Mar 24 15:21:11 2015 -0700
Committer: Michael Joyce <jo...@apache.org>
Committed: Tue Mar 24 15:21:11 2015 -0700
----------------------------------------------------------------------
ocw-config-runner/configuration_writer.py | 116 +++++++++++++++++++++++++
1 file changed, 116 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/climate/blob/0c2a9313/ocw-config-runner/configuration_writer.py
----------------------------------------------------------------------
diff --git a/ocw-config-runner/configuration_writer.py b/ocw-config-runner/configuration_writer.py
new file mode 100644
index 0000000..ad14a91
--- /dev/null
+++ b/ocw-config-runner/configuration_writer.py
@@ -0,0 +1,116 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import logging
+
+logging.basicConfig()
+logger = logging.getLogger(__name__)
+
+def generate_dataset_information(dataset):
+ ''' Generates a dict of dataset information for export.
+
+ :param dataset: The dataset from which to extract configuration
+ information.
+ :type dataset: :class:`dataset.Dataset`
+
+ :returns: :func:`dict` containing necessary information for
+ dataset to be saved into a configuration object.
+
+ :raises AttributeError: If dataset does not contain expected source data.
+ '''
+ dataset_source = dataset.origin['source']
+
+ if dataset_source == 'local':
+ info = _extract_local_dataset_info(dataset)
+ elif dataset_source == 'rcmed':
+ info = _extract_rcmed_dataset_info(dataset)
+ elif dataset_source == 'esgf':
+ info = _extract_esgf_dataset_info(dataset)
+ elif dataset_source == 'dap':
+ info = _extract_dap_dataset_info(dataset)
+ else:
+ err = (
+ "Unexpected source in dataset origin information."
+ "Found {}."
+ ).format(dataset_source)
+ logger.error(err)
+ raise AttributeError(err)
+
+ info['optional_args']['name'] = dataset.name
+ info['optional_args']['units'] = dataset.units
+
+ return info
+
+def _extract_local_dataset_info(dataset):
+ ''''''
+ dataset_info = {'optional_args': {}}
+
+ dataset_info['data_source'] = 'local'
+ dataset_info['file_count'] = 1
+ dataset_info['path'] = dataset.origin['path']
+ dataset_info['variable'] = dataset.variable
+
+ dataset_info['optional_args']['lat_name'] = dataset.origin['lat_name']
+ dataset_info['optional_args']['lon_name'] = dataset.origin['lon_name']
+ dataset_info['optional_args']['time_name'] = dataset.origin['time_name']
+
+ if 'elevation_index' in dataset.origin:
+ elev = dataset.origin['elevation_index']
+ dataset_info['optional_args']['elevation_index'] = elev
+
+ return dataset_info
+
+def _extract_rcmed_dataset_info(dataset):
+ ''''''
+ dataset_info = {'optional_args': {}}
+
+ min_lat, max_lat, min_lon, max_lon = dataset.spatial_boundaries()
+ start_time, end_time = dataset.time_range()
+
+ dataset_info['data_source'] = 'rcmed'
+ dataset_info['dataset_id'] = dataset.origin['dataset_id']
+ dataset_info['parameter_id'] = dataset.origin['parameter_id']
+ dataset_info['min_lat'] = min_lat
+ dataset_info['max_lat'] = max_lat
+ dataset_info['min_lon'] = min_lon
+ dataset_info['max_lon'] = max_lon
+ dataset_info['start_time'] = str(start_time)
+ dataset_info['end_time'] = str(end_time)
+
+ return dataset_info
+
+def _extract_esgf_dataset_info(dataset):
+ ''''''
+ dataset_info = {'optional_args': {}}
+
+ dataset_info['data_source'] = 'esgf'
+ dataset_info['dataset_id'] = dataset.origin['dataset_id']
+ dataset_info['variable'] = dataset.origin['variable']
+ dataset_info['esgf_username'] = 'Put your ESGF Username here'
+ dataset_info['esgf_password'] = 'Put your ESGF Password here'
+
+ return dataset_info
+
+def _extract_dap_dataset_info(dataset):
+ ''''''
+ dataset_info = {'optional_args': {}}
+
+ dataset_info['data_source'] = 'dap'
+ dataset_info['url'] = dataset.origin['url']
+ dataset_info['variable'] = dataset.variable
+
+ return dataset_info
[05/13] climate git commit: CLIMATE-581 - Add support for exporting
evaluation settings
Posted by jo...@apache.org.
CLIMATE-581 - Add support for exporting evaluation settings
Project: http://git-wip-us.apache.org/repos/asf/climate/repo
Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/7e0973f3
Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/7e0973f3
Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/7e0973f3
Branch: refs/heads/master
Commit: 7e0973f38e2e14ebf1bba6edcfb519f7f556cf95
Parents: e3dcace
Author: Michael Joyce <jo...@apache.org>
Authored: Tue Mar 24 18:12:57 2015 -0700
Committer: Michael Joyce <jo...@apache.org>
Committed: Tue Mar 24 18:12:57 2015 -0700
----------------------------------------------------------------------
ocw-config-runner/configuration_writer.py | 109 +++++++++++++++++++++++++
1 file changed, 109 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/climate/blob/7e0973f3/ocw-config-runner/configuration_writer.py
----------------------------------------------------------------------
diff --git a/ocw-config-runner/configuration_writer.py b/ocw-config-runner/configuration_writer.py
index bf1b8a0..9e02a4a 100644
--- a/ocw-config-runner/configuration_writer.py
+++ b/ocw-config-runner/configuration_writer.py
@@ -15,6 +15,7 @@
# specific language governing permissions and limitations
# under the License.
+import datetime as dt
import logging
logging.basicConfig()
@@ -70,6 +71,51 @@ def generate_metric_information(evaluation):
return unary_metrics + binary_metrics
+def generate_evaluation_information(evaluation):
+ ''' Generate evaluation-related config file output.
+
+ Attempts to parse out temporal and spatial rebinning/regridding information
+ from the supplied evaluation object. If no datasets can be found, values
+ are defaulted to sane defaults or (potentially) excluded entirely.
+
+ It's important to note that this function does its best to extrapolate the
+ configuration information. It's possible that you will encounter a scenario
+ where the guessed values are not what you want/expect. Please double
+ check the output before blinding trusting what this generates.
+
+ :param evaluation: The evaluation object from which to extract metrics.
+ :type evaluation: :class:`evaluation.Evaluation`
+
+ :returns: A dictionary of valid `evaluation` section settings for export
+ to a configuration file.
+ :rtype: :func:`dict`
+ '''
+ eval_config = {
+ 'temporal_time_delta': 999,
+ 'spatial_regrid_lats': (-90, 90, 1),
+ 'spatial_regrid_lons': (-180, 180, 1),
+ 'subset': [-90, 90, -180, 180, "1500-01-01", "2500-01-01"],
+ }
+
+ datasets = []
+
+ if evaluation.ref_dataset:
+ datasets.append(evaluation.ref_dataset)
+
+ if evaluation.target_datasets:
+ datasets += evaluation.target_datasets
+
+ if len(datasets) > 0:
+ eval_config['temporal_time_delta'] = _calc_temporal_bin_size(datasets)
+
+ lats, lons = _calc_spatial_lat_lon_grid(datasets)
+ eval_config['spatial_regrid_lats'] = lats
+ eval_config['spatial_regrid_lons'] = lons
+
+ eval_config['subset'] = _calc_subset_config(datasets)
+
+ return eval_config
+
def _extract_local_dataset_info(dataset):
''''''
dataset_info = {'optional_args': {}}
@@ -129,3 +175,66 @@ def _extract_dap_dataset_info(dataset):
dataset_info['variable'] = dataset.variable
return dataset_info
+
+def _calc_temporal_bin_size(datasets):
+ ''''''
+ times = datasets[0].times
+ time_delta = times[1] - times[0]
+
+ if time_delta.days == 0:
+ return 1
+ elif time_delta.days <= 31:
+ return 31
+ elif time_delta.days <= 366:
+ return 366
+ else:
+ return 999
+
+def _calc_spatial_lat_lon_grid(datasets):
+ ''''''
+ lat_min, lat_max, lon_min, lon_max = datasets[0].spatial_boundaries()
+
+ lats = datasets[0].lats
+ lons = datasets[0].lons
+ lat_step = abs(lats[1] - lats[0])
+ lon_step = abs(lons[1] - lons[0])
+
+ # We need to add an extra step value onto the end so when we generate a
+ # range with these values we don't lose one that we're expecting.
+ if lat_max != 90: lat_max += lat_step
+ if lon_max != 180: lon_max += lon_step
+
+ return ((lat_min, lat_max, lat_step), (lon_min, lon_max, lon_step))
+
+def _calc_subset_config(datasets):
+ ''''''
+ lat_min = 90
+ lat_max = -90
+ lon_min = 180
+ lon_max = -180
+ start = dt.datetime(2500, 1, 1)
+ end = dt.datetime(1500, 1, 1)
+
+ for ds in datasets:
+ ds_lat_min, ds_lat_max, ds_lon_min, ds_lon_max = ds.spatial_boundaries()
+ ds_start, ds_end = ds.time_range()
+
+ if ds_lat_min < lat_min:
+ lat_min = ds_lat_min
+
+ if ds_lat_max > lat_max:
+ lat_max = ds_lat_max
+
+ if ds_lon_min < lon_min:
+ lon_min = ds_lon_min
+
+ if ds_lon_max > lon_max:
+ lon_max = ds_lon_max
+
+ if ds_start < start:
+ start = ds_start
+
+ if ds_end > end:
+ end = ds_end
+
+ return [lat_min, lat_max, lon_min, lon_max, str(start), str(end)]
[02/13] climate git commit: CLIMATE-581 - Add tests for dataset
output writer
Posted by jo...@apache.org.
CLIMATE-581 - Add tests for dataset output writer
Project: http://git-wip-us.apache.org/repos/asf/climate/repo
Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/41879f9d
Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/41879f9d
Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/41879f9d
Branch: refs/heads/master
Commit: 41879f9d880ed8b76be5dcb393a60d6238b21742
Parents: 0c2a931
Author: Michael Joyce <jo...@apache.org>
Authored: Tue Mar 24 15:22:18 2015 -0700
Committer: Michael Joyce <jo...@apache.org>
Committed: Tue Mar 24 15:22:18 2015 -0700
----------------------------------------------------------------------
ocw-config-runner/tests/test_config_writer.py | 270 +++++++++++++++++++++
1 file changed, 270 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/climate/blob/41879f9d/ocw-config-runner/tests/test_config_writer.py
----------------------------------------------------------------------
diff --git a/ocw-config-runner/tests/test_config_writer.py b/ocw-config-runner/tests/test_config_writer.py
new file mode 100644
index 0000000..ebae0de
--- /dev/null
+++ b/ocw-config-runner/tests/test_config_writer.py
@@ -0,0 +1,270 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from mock import patch
+import unittest
+
+from ocw.dataset import Dataset
+import configuration_writer as writer
+
+import datetime as dt
+import numpy as np
+import yaml
+
+
+class TestLocalDatasetExportGeneration(unittest.TestCase):
+ @classmethod
+ def setUpClass(self):
+ self.lats = np.array([10, 12, 14, 16, 18])
+ self.lons = np.array([100, 102, 104, 106, 108])
+ self.times = np.array([dt.datetime(2000, x, 1) for x in range(1, 13)])
+ flat_array = np.array(range(300))
+ self.values = flat_array.reshape(12, 5, 5)
+ self.variable = 'var'
+ self.units = 'units'
+ self.origin = {
+ 'source': 'local',
+ 'path': '/a/fake/path.nc',
+ 'lat_name': 'a lat name',
+ 'lon_name': 'a lon name',
+ 'time_name': 'a time name',
+ 'elevation_index': 2
+ }
+ self.name = 'name'
+
+ self.dataset = Dataset(
+ self.lats,
+ self.lons,
+ self.times,
+ self.values,
+ variable=self.variable,
+ units=self.units,
+ origin=self.origin,
+ name=self.name
+ )
+
+ self.exported_info = writer.generate_dataset_information(self.dataset)
+
+ def test_proper_data_source_export(self):
+ self.assertTrue('data_source' in self.exported_info)
+ self.assertEqual(self.exported_info['data_source'],
+ self.origin['source'])
+
+ def test_proper_path_export(self):
+ self.assertEqual(self.exported_info['path'], self.origin['path'])
+
+ def test_proper_variable_name_export(self):
+ self.assertEqual(self.exported_info['variable'], self.variable)
+
+ def test_proper_units_name_export(self):
+ self.assertEqual(self.exported_info['optional_args']['units'],
+ self.units)
+
+ def test_proper_lats_name_export(self):
+ self.assertEqual(self.exported_info['optional_args']['lat_name'],
+ self.origin['lat_name'])
+
+ def test_proper_lons_name_export(self):
+ self.assertEqual(self.exported_info['optional_args']['lon_name'],
+ self.origin['lon_name'])
+
+ def test_proper_times_name_export(self):
+ self.assertEqual(self.exported_info['optional_args']['time_name'],
+ self.origin['time_name'])
+
+ def test_proper_dataset_name_export(self):
+ self.assertEqual(self.exported_info['optional_args']['name'],
+ self.name)
+
+ def test_proper_elevation_index_export(self):
+ self.assertEqual(self.exported_info['optional_args']['elevation_index'],
+ self.origin['elevation_index'])
+
+
+class TestRCMEDDatasetExportGeneration(unittest.TestCase):
+ @classmethod
+ def setUpClass(self):
+ self.lats = np.array([10, 12, 14, 16, 18])
+ self.lons = np.array([100, 102, 104, 106, 108])
+ self.times = np.array([dt.datetime(2000, x, 1) for x in range(1, 13)])
+ flat_array = np.array(range(300))
+ self.values = flat_array.reshape(12, 5, 5)
+ self.variable = 'var'
+ self.units = 'units'
+ self.origin = {
+ 'source': 'rcmed',
+ 'dataset_id': 4,
+ 'parameter_id': 14
+ }
+ self.name = 'name'
+
+ self.dataset = Dataset(
+ self.lats,
+ self.lons,
+ self.times,
+ self.values,
+ variable=self.variable,
+ units=self.units,
+ origin=self.origin,
+ name=self.name
+ )
+
+ self.exported_info = writer.generate_dataset_information(self.dataset)
+
+ def test_proper_data_source_export(self):
+ self.assertTrue('data_source' in self.exported_info)
+ self.assertEqual(self.exported_info['data_source'],
+ self.origin['source'])
+
+ def test_proper_dataset_id_export(self):
+ self.assertEqual(self.exported_info['dataset_id'],
+ self.origin['dataset_id'])
+
+ def test_proper_parameter_id_export(self):
+ self.assertEqual(self.exported_info['parameter_id'],
+ self.origin['parameter_id'])
+
+ def test_proper_min_lat_export(self):
+ self.assertEqual(self.exported_info['min_lat'], min(self.lats))
+
+ def test_proper_max_lat_export(self):
+ self.assertEqual(self.exported_info['max_lat'], max(self.lats))
+
+ def test_proper_min_lon_export(self):
+ self.assertEqual(self.exported_info['min_lon'], min(self.lons))
+
+ def test_proper_max_lon_export(self):
+ self.assertEqual(self.exported_info['max_lon'], max(self.lons))
+
+ def test_proper_min_time_export(self):
+ self.assertEqual(self.exported_info['start_time'], str(min(self.times)))
+
+ def test_proper_max_time_export(self):
+ self.assertEqual(self.exported_info['end_time'], str(max(self.times)))
+
+ def test_proper_dataset_name_export(self):
+ self.assertEqual(self.exported_info['optional_args']['name'],
+ self.name)
+
+ def test_proper_units_name_export(self):
+ self.assertEqual(self.exported_info['optional_args']['units'],
+ self.units)
+
+
+class TestESGFDatasetExportGeneration(unittest.TestCase):
+ @classmethod
+ def setUpClass(self):
+ self.lats = np.array([10, 12, 14, 16, 18])
+ self.lons = np.array([100, 102, 104, 106, 108])
+ self.times = np.array([dt.datetime(2000, x, 1) for x in range(1, 13)])
+ flat_array = np.array(range(300))
+ self.values = flat_array.reshape(12, 5, 5)
+ self.variable = 'var'
+ self.units = 'units'
+ self.origin = {
+ 'source': 'esgf',
+ 'dataset_id': 'esgf dataset id',
+ 'variable': 'var'
+ }
+ self.name = 'name'
+
+ self.dataset = Dataset(
+ self.lats,
+ self.lons,
+ self.times,
+ self.values,
+ variable=self.variable,
+ units=self.units,
+ origin=self.origin,
+ name=self.name
+ )
+
+ self.exported_info = writer.generate_dataset_information(self.dataset)
+
+ def test_proper_data_source_export(self):
+ self.assertTrue('data_source' in self.exported_info)
+ self.assertEqual(self.exported_info['data_source'],
+ self.origin['source'])
+
+ def test_proper_dataset_id_export(self):
+ self.assertEqual(self.exported_info['dataset_id'],
+ self.origin['dataset_id'])
+
+ def test_proper_variable_export(self):
+ self.assertEqual(self.exported_info['variable'],
+ self.origin['variable'])
+
+ def test_proper_dummy_username_export(self):
+ self.assertTrue('esgf_username' in self.exported_info)
+
+ def test_proper_dummy_password_export(self):
+ self.assertTrue('esgf_password' in self.exported_info)
+
+ def test_proper_dataset_name_export(self):
+ self.assertEqual(self.exported_info['optional_args']['name'],
+ self.name)
+
+ def test_proper_units_name_export(self):
+ self.assertEqual(self.exported_info['optional_args']['units'],
+ self.units)
+
+
+class TestDAPDatasetExportGeneration(unittest.TestCase):
+ @classmethod
+ def setUpClass(self):
+ self.lats = np.array([10, 12, 14, 16, 18])
+ self.lons = np.array([100, 102, 104, 106, 108])
+ self.times = np.array([dt.datetime(2000, x, 1) for x in range(1, 13)])
+ flat_array = np.array(range(300))
+ self.values = flat_array.reshape(12, 5, 5)
+ self.variable = 'var'
+ self.units = 'units'
+ self.origin = {
+ 'source': 'dap',
+ 'url': 'a fake url',
+ }
+ self.name = 'name'
+
+ self.dataset = Dataset(
+ self.lats,
+ self.lons,
+ self.times,
+ self.values,
+ variable=self.variable,
+ units=self.units,
+ origin=self.origin,
+ name=self.name
+ )
+
+ self.exported_info = writer.generate_dataset_information(self.dataset)
+
+ def test_proper_data_source_export(self):
+ self.assertTrue('data_source' in self.exported_info)
+ self.assertEqual(self.exported_info['data_source'],
+ self.origin['source'])
+
+ def test_proper_url_export(self):
+ self.assertEqual(self.exported_info['url'],
+ self.origin['url'])
+
+ def test_proper_dataset_name_export(self):
+ self.assertEqual(self.exported_info['optional_args']['name'],
+ self.name)
+
+ def test_proper_units_name_export(self):
+ self.assertEqual(self.exported_info['optional_args']['units'],
+ self.units)
[06/13] climate git commit: CLIMATE-581 - Add tests for evaluation
settings export
Posted by jo...@apache.org.
CLIMATE-581 - Add tests for evaluation settings export
Project: http://git-wip-us.apache.org/repos/asf/climate/repo
Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/5a5f10e5
Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/5a5f10e5
Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/5a5f10e5
Branch: refs/heads/master
Commit: 5a5f10e582781e5474573d44b3a96eb8846281dc
Parents: 7e0973f
Author: Michael Joyce <jo...@apache.org>
Authored: Tue Mar 24 18:14:09 2015 -0700
Committer: Michael Joyce <jo...@apache.org>
Committed: Tue Mar 24 18:14:09 2015 -0700
----------------------------------------------------------------------
ocw-config-runner/tests/test_config_writer.py | 149 +++++++++++++++++++++
1 file changed, 149 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/climate/blob/5a5f10e5/ocw-config-runner/tests/test_config_writer.py
----------------------------------------------------------------------
diff --git a/ocw-config-runner/tests/test_config_writer.py b/ocw-config-runner/tests/test_config_writer.py
index b76b0b7..6e7ffe4 100644
--- a/ocw-config-runner/tests/test_config_writer.py
+++ b/ocw-config-runner/tests/test_config_writer.py
@@ -301,3 +301,152 @@ class TestMetricExportGeneration(unittest.TestCase):
self.assertTrue(type(out) == type(list()))
self.assertTrue(len(out) == 0)
+
+
+class TestEvaluationSettingsGeneration(unittest.TestCase):
+ @classmethod
+ def setUpClass(self):
+ self.lats = np.array(range(-10, 10, 1))
+ self.lons = np.array(range(-20, 20, 1))
+ self.times = np.array([dt.datetime(2000, x, 1) for x in range(1, 13)])
+ flat_array = np.array(range(9600))
+ self.values = flat_array.reshape(12, 20, 40)
+
+ self.dataset = Dataset(
+ self.lats,
+ self.lons,
+ self.times,
+ self.values,
+ )
+
+ self.evaluation = Evaluation(self.dataset, [], [])
+
+ def test_default_data_return(self):
+ new_eval = Evaluation(None, [], [])
+ default_output = {
+ 'temporal_time_delta': 999,
+ 'spatial_regrid_lats': (-90, 90, 1),
+ 'spatial_regrid_lons': (-180, 180, 1),
+ 'subset': [-90, 90, -180, 180, "1500-01-01", "2500-01-01"],
+ }
+
+ out = writer.generate_evaluation_information(new_eval)
+
+ self.assertEquals(default_output, out)
+
+ def test_handles_only_reference_dataset(self):
+ new_eval = Evaluation(self.dataset, [], [])
+
+ default_output = {
+ 'temporal_time_delta': 999,
+ 'spatial_regrid_lats': (-90, 90, 1),
+ 'spatial_regrid_lons': (-180, 180, 1),
+ 'subset': [-90, 90, -180, 180, "1500-01-01", "2500-01-01"],
+ }
+
+ out = writer.generate_evaluation_information(new_eval)
+
+ self.assertNotEquals(default_output, out)
+
+ def test_handles_only_target_dataset(self):
+ new_eval = Evaluation(None, [self.dataset], [])
+
+ default_output = {
+ 'temporal_time_delta': 999,
+ 'spatial_regrid_lats': (-90, 90, 1),
+ 'spatial_regrid_lons': (-180, 180, 1),
+ 'subset': [-90, 90, -180, 180, "1500-01-01", "2500-01-01"],
+ }
+
+ out = writer.generate_evaluation_information(new_eval)
+
+ self.assertNotEquals(default_output, out)
+
+ def test_daily_temporal_bin(self):
+ new_times = np.array([dt.datetime(2000, 1, 1, x) for x in range(1, 13)])
+
+ dataset = Dataset(
+ self.lats,
+ self.lons,
+ new_times,
+ self.values,
+ )
+ new_eval = Evaluation(dataset, [], [])
+
+ out = writer.generate_evaluation_information(new_eval)
+
+ self.assertEquals(out['temporal_time_delta'], 1)
+
+ def test_monthly_temporal_bin(self):
+ out = writer.generate_evaluation_information(self.evaluation)
+
+ self.assertEquals(out['temporal_time_delta'], 31)
+
+ def test_yearly_temporal_bin(self):
+ new_times = np.array([dt.datetime(2000 + x, 1, 1) for x in range(1, 13)])
+
+ dataset = Dataset(
+ self.lats,
+ self.lons,
+ new_times,
+ self.values,
+ )
+ new_eval = Evaluation(dataset, [], [])
+
+ out = writer.generate_evaluation_information(new_eval)
+
+ self.assertEquals(out['temporal_time_delta'], 366)
+
+ def test_spatial_regrid_lats(self):
+ out = writer.generate_evaluation_information(self.evaluation)
+
+ lats = out['spatial_regrid_lats']
+ lat_range = np.arange(lats[0], lats[1], lats[2])
+
+ self.assertTrue(np.array_equal(lat_range, self.lats))
+
+ def test_spatial_regrid_lons(self):
+ out = writer.generate_evaluation_information(self.evaluation)
+
+ lons = out['spatial_regrid_lons']
+ lat_range = np.arange(lons[0], lons[1], lons[2])
+
+ self.assertTrue(np.array_equal(lat_range, self.lons))
+
+ def test_subset_with_single_dataset(self):
+ out = writer.generate_evaluation_information(self.evaluation)
+ subset = out['subset']
+
+ ds_lat_min, ds_lat_max, ds_lon_min, ds_lon_max = self.dataset.spatial_boundaries()
+ start, end = self.dataset.time_range()
+
+ self.assertEqual(ds_lat_min, subset[0])
+ self.assertEqual(ds_lat_max, subset[1])
+ self.assertEqual(ds_lon_min, subset[2])
+ self.assertEqual(ds_lon_max, subset[3])
+ self.assertEquals(str(start), subset[4])
+ self.assertEquals(str(end), subset[5])
+
+ def test_subset_with_multiple_datasets(self):
+ new_ds = Dataset(
+ np.arange(0, 20, 1),
+ self.lons,
+ self.times,
+ self.values
+ )
+ new_eval = Evaluation(self.dataset, [new_ds], [])
+
+ out = writer.generate_evaluation_information(new_eval)
+ subset = out['subset']
+
+ ds_lat_min, ds_lat_max, ds_lon_min, ds_lon_max = self.dataset.spatial_boundaries()
+ start, end = self.dataset.time_range()
+
+ self.assertEqual(ds_lat_min, subset[0])
+ # Check that we actually used the different max lat value that we
+ # created by adding 'new_ds'.
+ self.assertEqual(max(new_ds.lats), subset[1])
+ self.assertEqual(ds_lon_min, subset[2])
+ self.assertEqual(ds_lon_max, subset[3])
+ self.assertEquals(str(start), subset[4])
+ self.assertEquals(str(end), subset[5])
[13/13] climate git commit: Resolve CLIMATE-581. Merge PR #185.
Posted by jo...@apache.org.
Resolve CLIMATE-581. Merge PR #185.
Project: http://git-wip-us.apache.org/repos/asf/climate/repo
Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/531661c5
Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/531661c5
Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/531661c5
Branch: refs/heads/master
Commit: 531661c5d99c9778f7048b4a36b0d49c469c4163
Parents: e4cbce7 acce351
Author: Michael Joyce <jo...@apache.org>
Authored: Tue Mar 31 07:58:31 2015 -0700
Committer: Michael Joyce <jo...@apache.org>
Committed: Tue Mar 31 07:58:31 2015 -0700
----------------------------------------------------------------------
docs/source/config/config_overview.rst | 5 +
docs/source/config/config_writer.rst | 5 +
ocw-config-runner/configuration_writer.py | 285 ++++++++
ocw-config-runner/tests/test_config_writer.py | 735 +++++++++++++++++++++
4 files changed, 1030 insertions(+)
----------------------------------------------------------------------
[11/13] climate git commit: CLIMATE-581 - Fix minor trailing/leading
whitespace issues
Posted by jo...@apache.org.
CLIMATE-581 - Fix minor trailing/leading whitespace issues
Project: http://git-wip-us.apache.org/repos/asf/climate/repo
Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/9167f1a5
Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/9167f1a5
Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/9167f1a5
Branch: refs/heads/master
Commit: 9167f1a5c8366ecda77693a61c49f345ce2c41d8
Parents: f83e4be
Author: Michael Joyce <jo...@apache.org>
Authored: Wed Mar 25 11:33:22 2015 -0700
Committer: Michael Joyce <jo...@apache.org>
Committed: Wed Mar 25 11:33:22 2015 -0700
----------------------------------------------------------------------
ocw-config-runner/configuration_writer.py | 6 +++---
ocw-config-runner/tests/test_config_writer.py | 12 ++++++------
2 files changed, 9 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/climate/blob/9167f1a5/ocw-config-runner/configuration_writer.py
----------------------------------------------------------------------
diff --git a/ocw-config-runner/configuration_writer.py b/ocw-config-runner/configuration_writer.py
index c78f46f..f7fb1c9 100644
--- a/ocw-config-runner/configuration_writer.py
+++ b/ocw-config-runner/configuration_writer.py
@@ -25,7 +25,7 @@ logger = logging.getLogger(__name__)
def export_evaluation_to_config(evaluation, file_path='./exported_eval.yaml'):
''' Export an evaluation to a config file
-
+
:param evaluation: The evaluation object to export.
:type evaluation: :class:`evaluation.Evaluation`
@@ -42,7 +42,7 @@ def export_evaluation_to_config(evaluation, file_path='./exported_eval.yaml'):
def generate_dataset_information(evaluation):
''' Generate dataset config file output for a given Evaluation object.
-
+
:param evaluation: The evaluation object from which to extract metrics.
:type evaluation: :class:`evaluation.Evaluation`
@@ -124,7 +124,7 @@ def generate_evaluation_information(evaluation):
configuration information. It's possible that you will encounter a scenario
where the guessed values are not what you want/expect. Please double
check the output before blinding trusting what this generates.
-
+
:param evaluation: The evaluation object from which to extract metrics.
:type evaluation: :class:`evaluation.Evaluation`
http://git-wip-us.apache.org/repos/asf/climate/blob/9167f1a5/ocw-config-runner/tests/test_config_writer.py
----------------------------------------------------------------------
diff --git a/ocw-config-runner/tests/test_config_writer.py b/ocw-config-runner/tests/test_config_writer.py
index 2d6a9f6..97b7e01 100644
--- a/ocw-config-runner/tests/test_config_writer.py
+++ b/ocw-config-runner/tests/test_config_writer.py
@@ -293,7 +293,7 @@ class TestDatasetExportFromEvaluation(unittest.TestCase):
'time_name': 'a time name',
'elevation_index': 2
}
-
+
self.rcmed_origin = {
'source': 'rcmed',
'dataset_id': 4,
@@ -332,7 +332,7 @@ class TestDatasetExportFromEvaluation(unittest.TestCase):
name=self.name,
origin=self.rcmed_origin
)
-
+
self.esgf_ds = Dataset(
self.lats,
self.lons,
@@ -589,7 +589,7 @@ class FullExportTest(unittest.TestCase):
'time_name': 'a time name',
'elevation_index': 2
}
-
+
self.rcmed_origin = {
'source': 'rcmed',
'dataset_id': 4,
@@ -628,7 +628,7 @@ class FullExportTest(unittest.TestCase):
name=self.name,
origin=self.rcmed_origin
)
-
+
self.esgf_ds = Dataset(
self.lats,
self.lons,
@@ -690,7 +690,7 @@ class FullExportTest(unittest.TestCase):
self.assertTrue(metric.__class__.__name__ in data['metrics'])
total_eval_metrics = (
- len(self.evaluation.metrics) +
+ len(self.evaluation.metrics) +
len(self.evaluation.unary_metrics)
)
@@ -710,7 +710,7 @@ class FullExportTest(unittest.TestCase):
self.assertTrue('targets' in data['datasets'])
self.assertAlmostEqual(
- writer.generate_dataset_information(self.evaluation),
+ writer.generate_dataset_information(self.evaluation),
data['datasets']
)
[07/13] climate git commit: CLIMATE-581 - Minor whitespace clean up
in tests
Posted by jo...@apache.org.
CLIMATE-581 - Minor whitespace clean up in tests
Project: http://git-wip-us.apache.org/repos/asf/climate/repo
Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/33b36be4
Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/33b36be4
Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/33b36be4
Branch: refs/heads/master
Commit: 33b36be4dc23a367f9442462253b42c7b7c0591a
Parents: 5a5f10e
Author: Michael Joyce <jo...@apache.org>
Authored: Tue Mar 24 18:14:50 2015 -0700
Committer: Michael Joyce <jo...@apache.org>
Committed: Tue Mar 24 18:14:50 2015 -0700
----------------------------------------------------------------------
ocw-config-runner/tests/test_config_writer.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/climate/blob/33b36be4/ocw-config-runner/tests/test_config_writer.py
----------------------------------------------------------------------
diff --git a/ocw-config-runner/tests/test_config_writer.py b/ocw-config-runner/tests/test_config_writer.py
index 6e7ffe4..1518d96 100644
--- a/ocw-config-runner/tests/test_config_writer.py
+++ b/ocw-config-runner/tests/test_config_writer.py
@@ -328,7 +328,7 @@ class TestEvaluationSettingsGeneration(unittest.TestCase):
'spatial_regrid_lats': (-90, 90, 1),
'spatial_regrid_lons': (-180, 180, 1),
'subset': [-90, 90, -180, 180, "1500-01-01", "2500-01-01"],
- }
+ }
out = writer.generate_evaluation_information(new_eval)
@@ -342,7 +342,7 @@ class TestEvaluationSettingsGeneration(unittest.TestCase):
'spatial_regrid_lats': (-90, 90, 1),
'spatial_regrid_lons': (-180, 180, 1),
'subset': [-90, 90, -180, 180, "1500-01-01", "2500-01-01"],
- }
+ }
out = writer.generate_evaluation_information(new_eval)
@@ -356,7 +356,7 @@ class TestEvaluationSettingsGeneration(unittest.TestCase):
'spatial_regrid_lats': (-90, 90, 1),
'spatial_regrid_lons': (-180, 180, 1),
'subset': [-90, 90, -180, 180, "1500-01-01", "2500-01-01"],
- }
+ }
out = writer.generate_evaluation_information(new_eval)
[09/13] climate git commit: CLIMATE-581 - Add API for evaluation
export to config file
Posted by jo...@apache.org.
CLIMATE-581 - Add API for evaluation export to config file
- Add export_evaluation_to_config for exporting an Evaluation object to
a YAML configuration file that can be parsed by OCW.
- Add explicit cast of spatial lat/lon grid step values to floats to
ensure that PyYAML doesn't encounter a Numpy data type and choke on
export.
Project: http://git-wip-us.apache.org/repos/asf/climate/repo
Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/9d242b27
Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/9d242b27
Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/9d242b27
Branch: refs/heads/master
Commit: 9d242b273a65d4021d54f047659a6a7349611158
Parents: b0e7b40
Author: Michael Joyce <jo...@apache.org>
Authored: Wed Mar 25 11:29:26 2015 -0700
Committer: Michael Joyce <jo...@apache.org>
Committed: Wed Mar 25 11:29:26 2015 -0700
----------------------------------------------------------------------
ocw-config-runner/configuration_writer.py | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/climate/blob/9d242b27/ocw-config-runner/configuration_writer.py
----------------------------------------------------------------------
diff --git a/ocw-config-runner/configuration_writer.py b/ocw-config-runner/configuration_writer.py
index 497c7db..c78f46f 100644
--- a/ocw-config-runner/configuration_writer.py
+++ b/ocw-config-runner/configuration_writer.py
@@ -18,9 +18,28 @@
import datetime as dt
import logging
+import yaml
+
logging.basicConfig()
logger = logging.getLogger(__name__)
+def export_evaluation_to_config(evaluation, file_path='./exported_eval.yaml'):
+ ''' Export an evaluation to a config file
+
+ :param evaluation: The evaluation object to export.
+ :type evaluation: :class:`evaluation.Evaluation`
+
+ :param file_path: Optional file path where the config file should be saved.
+ :type file_path: :mod:`string`
+ '''
+ config = {}
+
+ config['evaluation'] = generate_evaluation_information(evaluation)
+ config['datasets'] = generate_dataset_information(evaluation)
+ config['metrics'] = generate_metric_information(evaluation)
+
+ yaml.dump(config, file(file_path, 'w'))
+
def generate_dataset_information(evaluation):
''' Generate dataset config file output for a given Evaluation object.
@@ -219,8 +238,11 @@ def _calc_spatial_lat_lon_grid(datasets):
lats = datasets[0].lats
lons = datasets[0].lons
- lat_step = abs(lats[1] - lats[0])
- lon_step = abs(lons[1] - lons[0])
+ # These explicit float casts are needed to ensure that the type of the
+ # lat/lon steps are not numpy values. PyYAML will choke on export if it
+ # encounters a Numpy value.
+ lat_step = float(abs(lats[1] - lats[0]))
+ lon_step = float(abs(lons[1] - lons[0]))
# We need to add an extra step value onto the end so when we generate a
# range with these values we don't lose one that we're expecting.
[08/13] climate git commit: CLIMATE-581 - Add dataset export from
evaluation object
Posted by jo...@apache.org.
CLIMATE-581 - Add dataset export from evaluation object
- Add a helper for exporting all dataset configuration information from
an Evaluation object.
- Rename the existing single dataset export function so functions that
export from an Evaluation object can share consistent naming.
- Update tests with new dataset export function name.
- Add tests for full dataset export from an Evaluation object.
Project: http://git-wip-us.apache.org/repos/asf/climate/repo
Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/b0e7b40c
Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/b0e7b40c
Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/b0e7b40c
Branch: refs/heads/master
Commit: b0e7b40c7ae49247c960de7c10f0532274402964
Parents: 33b36be
Author: Michael Joyce <jo...@apache.org>
Authored: Wed Mar 25 10:24:00 2015 -0700
Committer: Michael Joyce <jo...@apache.org>
Committed: Wed Mar 25 10:24:00 2015 -0700
----------------------------------------------------------------------
ocw-config-runner/configuration_writer.py | 27 ++++-
ocw-config-runner/tests/test_config_writer.py | 133 ++++++++++++++++++++-
2 files changed, 154 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/climate/blob/b0e7b40c/ocw-config-runner/configuration_writer.py
----------------------------------------------------------------------
diff --git a/ocw-config-runner/configuration_writer.py b/ocw-config-runner/configuration_writer.py
index 9e02a4a..497c7db 100644
--- a/ocw-config-runner/configuration_writer.py
+++ b/ocw-config-runner/configuration_writer.py
@@ -21,8 +21,31 @@ import logging
logging.basicConfig()
logger = logging.getLogger(__name__)
-def generate_dataset_information(dataset):
- ''' Generates a dict of dataset information for export.
+def generate_dataset_information(evaluation):
+ ''' Generate dataset config file output for a given Evaluation object.
+
+ :param evaluation: The evaluation object from which to extract metrics.
+ :type evaluation: :class:`evaluation.Evaluation`
+
+ :returns: A :func:`dict` of dataset configuration information for export
+ to a configuration file.
+ :rtype: :func:`dict`
+ '''
+ datasets = {}
+
+ if evaluation.ref_dataset:
+ datasets['reference'] = generate_dataset_config(evaluation.ref_dataset)
+
+ if len(evaluation.target_datasets) > 0:
+ datasets['targets'] = [
+ generate_dataset_config(target)
+ for target in evaluation.target_datasets
+ ]
+
+ return datasets
+
+def generate_dataset_config(dataset):
+ ''' Generate dataset config file output for a given Dataset object.
:param dataset: The dataset from which to extract configuration
information.
http://git-wip-us.apache.org/repos/asf/climate/blob/b0e7b40c/ocw-config-runner/tests/test_config_writer.py
----------------------------------------------------------------------
diff --git a/ocw-config-runner/tests/test_config_writer.py b/ocw-config-runner/tests/test_config_writer.py
index 1518d96..da1657d 100644
--- a/ocw-config-runner/tests/test_config_writer.py
+++ b/ocw-config-runner/tests/test_config_writer.py
@@ -59,7 +59,7 @@ class TestLocalDatasetExportGeneration(unittest.TestCase):
name=self.name
)
- self.exported_info = writer.generate_dataset_information(self.dataset)
+ self.exported_info = writer.generate_dataset_config(self.dataset)
def test_proper_data_source_export(self):
self.assertTrue('data_source' in self.exported_info)
@@ -125,7 +125,7 @@ class TestRCMEDDatasetExportGeneration(unittest.TestCase):
name=self.name
)
- self.exported_info = writer.generate_dataset_information(self.dataset)
+ self.exported_info = writer.generate_dataset_config(self.dataset)
def test_proper_data_source_export(self):
self.assertTrue('data_source' in self.exported_info)
@@ -195,7 +195,7 @@ class TestESGFDatasetExportGeneration(unittest.TestCase):
name=self.name
)
- self.exported_info = writer.generate_dataset_information(self.dataset)
+ self.exported_info = writer.generate_dataset_config(self.dataset)
def test_proper_data_source_export(self):
self.assertTrue('data_source' in self.exported_info)
@@ -252,7 +252,7 @@ class TestDAPDatasetExportGeneration(unittest.TestCase):
name=self.name
)
- self.exported_info = writer.generate_dataset_information(self.dataset)
+ self.exported_info = writer.generate_dataset_config(self.dataset)
def test_proper_data_source_export(self):
self.assertTrue('data_source' in self.exported_info)
@@ -272,6 +272,122 @@ class TestDAPDatasetExportGeneration(unittest.TestCase):
self.units)
+class TestDatasetExportFromEvaluation(unittest.TestCase):
+ @classmethod
+ def setUpClass(self):
+ self.lats = np.array([10, 12, 14, 16, 18])
+ self.lons = np.array([100, 102, 104, 106, 108])
+ self.times = np.array([dt.datetime(2000, x, 1) for x in range(1, 13)])
+ flat_array = np.array(range(300))
+ self.values = flat_array.reshape(12, 5, 5)
+ self.variable = 'var'
+ self.units = 'units'
+ self.name = 'name'
+
+ self.local_origin = {
+ 'source': 'local',
+ 'path': '/a/fake/path.nc',
+ 'lat_name': 'a lat name',
+ 'lon_name': 'a lon name',
+ 'time_name': 'a time name',
+ 'elevation_index': 2
+ }
+
+ self.rcmed_origin = {
+ 'source': 'rcmed',
+ 'dataset_id': 4,
+ 'parameter_id': 14
+ }
+
+ self.esgf_origin = {
+ 'source': 'esgf',
+ 'dataset_id': 'esgf dataset id',
+ 'variable': 'var'
+ }
+
+ self.dap_origin = {
+ 'source': 'dap',
+ 'url': 'a fake url',
+ }
+
+ self.local_ds = Dataset(
+ self.lats,
+ self.lons,
+ self.times,
+ self.values,
+ variable=self.variable,
+ units=self.units,
+ name=self.name,
+ origin=self.local_origin
+ )
+
+ self.rcmed_ds = Dataset(
+ self.lats,
+ self.lons,
+ self.times,
+ self.values,
+ variable=self.variable,
+ units=self.units,
+ name=self.name,
+ origin=self.rcmed_origin
+ )
+
+ self.esgf_ds = Dataset(
+ self.lats,
+ self.lons,
+ self.times,
+ self.values,
+ variable=self.variable,
+ units=self.units,
+ name=self.name,
+ origin=self.esgf_origin
+ )
+
+ self.dap_ds = Dataset(
+ self.lats,
+ self.lons,
+ self.times,
+ self.values,
+ variable=self.variable,
+ units=self.units,
+ name=self.name,
+ origin=self.dap_origin
+ )
+
+ self.evaluation = Evaluation(
+ self.local_ds,
+ [self.rcmed_ds, self.esgf_ds, self.dap_ds],
+ []
+ )
+
+ def test_contains_only_reference_dataset(self):
+ new_eval = Evaluation(self.local_ds, [], [])
+ out = writer.generate_dataset_information(new_eval)
+
+ self.assertTrue('reference' in out)
+ self.assertTrue('targets' not in out)
+
+ def test_contains_only_target_datasets(self):
+ new_eval = Evaluation(None, [self.local_ds], [])
+ out = writer.generate_dataset_information(new_eval)
+
+ self.assertTrue('reference' not in out)
+ self.assertTrue('targets' in out)
+
+ def test_proper_reference_dataset_export(self):
+ out = writer.generate_dataset_information(self.evaluation)
+
+ self.assertTrue('reference' in out)
+ self.assertTrue(out['reference']['data_source'] == 'local')
+
+ def test_proper_target_datasets_export(self):
+ out = writer.generate_dataset_information(self.evaluation)
+
+ self.assertTrue('targets' in out)
+ self.assertTrue(type(out['targets']) == type(list()))
+ self.assertTrue(len(out['targets']) == 3)
+
+
class TestMetricExportGeneration(unittest.TestCase):
@classmethod
def setUpClass(self):
@@ -450,3 +566,12 @@ class TestEvaluationSettingsGeneration(unittest.TestCase):
self.assertEqual(ds_lon_max, subset[3])
self.assertEquals(str(start), subset[4])
self.assertEquals(str(end), subset[5])
+
+
+class FullExportTest(unittest.TestCase):
+ @classmethod
+ def setUpClass(self):
+ pass
+
+ def test_full_export(self):
+ pass
[10/13] climate git commit: CLIMATE-581 - Add API tests for exporting
an evaluation to config
Posted by jo...@apache.org.
CLIMATE-581 - Add API tests for exporting an evaluation to config
Project: http://git-wip-us.apache.org/repos/asf/climate/repo
Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/f83e4bef
Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/f83e4bef
Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/f83e4bef
Branch: refs/heads/master
Commit: f83e4bef2c47c093547dd86aa3e302e55359afb3
Parents: 9d242b2
Author: Michael Joyce <jo...@apache.org>
Authored: Wed Mar 25 11:30:46 2015 -0700
Committer: Michael Joyce <jo...@apache.org>
Committed: Wed Mar 25 11:30:46 2015 -0700
----------------------------------------------------------------------
ocw-config-runner/tests/test_config_writer.py | 162 ++++++++++++++++++++-
1 file changed, 160 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/climate/blob/f83e4bef/ocw-config-runner/tests/test_config_writer.py
----------------------------------------------------------------------
diff --git a/ocw-config-runner/tests/test_config_writer.py b/ocw-config-runner/tests/test_config_writer.py
index da1657d..2d6a9f6 100644
--- a/ocw-config-runner/tests/test_config_writer.py
+++ b/ocw-config-runner/tests/test_config_writer.py
@@ -16,6 +16,7 @@
# under the License.
from mock import patch
+import os
import unittest
from ocw.dataset import Dataset
@@ -571,7 +572,164 @@ class TestEvaluationSettingsGeneration(unittest.TestCase):
class FullExportTest(unittest.TestCase):
@classmethod
def setUpClass(self):
- pass
+ self.lats = np.array([10, 12, 14, 16, 18])
+ self.lons = np.array([100, 102, 104, 106, 108])
+ self.times = np.array([dt.datetime(2000, x, 1) for x in range(1, 13)])
+ flat_array = np.array(range(300))
+ self.values = flat_array.reshape(12, 5, 5)
+ self.variable = 'var'
+ self.units = 'units'
+ self.name = 'name'
+
+ self.local_origin = {
+ 'source': 'local',
+ 'path': '/a/fake/path.nc',
+ 'lat_name': 'a lat name',
+ 'lon_name': 'a lon name',
+ 'time_name': 'a time name',
+ 'elevation_index': 2
+ }
+
+ self.rcmed_origin = {
+ 'source': 'rcmed',
+ 'dataset_id': 4,
+ 'parameter_id': 14
+ }
+
+ self.esgf_origin = {
+ 'source': 'esgf',
+ 'dataset_id': 'esgf dataset id',
+ 'variable': 'var'
+ }
+
+ self.dap_origin = {
+ 'source': 'dap',
+ 'url': 'a fake url',
+ }
+
+ self.local_ds = Dataset(
+ self.lats,
+ self.lons,
+ self.times,
+ self.values,
+ variable=self.variable,
+ units=self.units,
+ name=self.name,
+ origin=self.local_origin
+ )
+
+ self.rcmed_ds = Dataset(
+ self.lats,
+ self.lons,
+ self.times,
+ self.values,
+ variable=self.variable,
+ units=self.units,
+ name=self.name,
+ origin=self.rcmed_origin
+ )
+
+ self.esgf_ds = Dataset(
+ self.lats,
+ self.lons,
+ self.times,
+ self.values,
+ variable=self.variable,
+ units=self.units,
+ name=self.name,
+ origin=self.esgf_origin
+ )
+
+ self.dap_ds = Dataset(
+ self.lats,
+ self.lons,
+ self.times,
+ self.values,
+ variable=self.variable,
+ units=self.units,
+ name=self.name,
+ origin=self.dap_origin
+ )
+
+ self.evaluation = Evaluation(
+ self.local_ds,
+ [self.rcmed_ds, self.esgf_ds, self.dap_ds],
+ [metrics.Bias(), metrics.TemporalStdDev()]
+ )
+
+ @classmethod
+ def tearDownClass(self):
+ if os.path.isfile('/tmp/test_config.yaml'):
+ os.remove('/tmp/test_config.yaml')
def test_full_export(self):
- pass
+ file_path = '/tmp/test_config.yaml'
+ writer.export_evaluation_to_config(
+ self.evaluation,
+ file_path=file_path
+ )
+
+ self.assertTrue(os.path.isfile(file_path))
+
+ def test_proper_metric_export(self):
+ file_path = '/tmp/test_config.yaml'
+ writer.export_evaluation_to_config(
+ self.evaluation,
+ file_path=file_path
+ )
+
+ data = yaml.load(open(file_path, 'r'))
+
+ self.assertTrue('metrics' in data)
+ self.assertTrue(type(data['metrics']) == type(list()))
+
+ for metric in self.evaluation.metrics:
+ self.assertTrue(metric.__class__.__name__ in data['metrics'])
+
+ for metric in self.evaluation.unary_metrics:
+ self.assertTrue(metric.__class__.__name__ in data['metrics'])
+
+ total_eval_metrics = (
+ len(self.evaluation.metrics) +
+ len(self.evaluation.unary_metrics)
+ )
+
+ self.assertTrue(total_eval_metrics, len(data['metrics']))
+
+ def test_proper_dataset_export(self):
+ file_path = '/tmp/test_config.yaml'
+ writer.export_evaluation_to_config(
+ self.evaluation,
+ file_path=file_path
+ )
+
+ data = yaml.load(open(file_path, 'r'))
+
+ self.assertTrue('datasets' in data)
+ self.assertTrue('reference' in data['datasets'])
+ self.assertTrue('targets' in data['datasets'])
+
+ self.assertAlmostEqual(
+ writer.generate_dataset_information(self.evaluation),
+ data['datasets']
+ )
+
+ def test_proper_evaluation_setting_export(self):
+ file_path = '/tmp/test_config.yaml'
+ writer.export_evaluation_to_config(
+ self.evaluation,
+ file_path=file_path
+ )
+
+ data = yaml.load(open(file_path, 'r'))
+
+ self.assertTrue('evaluation' in data)
+ self.assertTrue('temporal_time_delta' in data['evaluation'])
+ self.assertTrue('spatial_regrid_lats' in data['evaluation'])
+ self.assertTrue('spatial_regrid_lons' in data['evaluation'])
+ self.assertTrue('subset' in data['evaluation'])
+
+ self.assertAlmostEqual(
+ writer.generate_evaluation_information(self.evaluation),
+ data['evaluation']
+ )
[12/13] climate git commit: CLIMATE-581 - Add API level docs for
config writer to Sphinx build
Posted by jo...@apache.org.
CLIMATE-581 - Add API level docs for config writer to Sphinx build
Project: http://git-wip-us.apache.org/repos/asf/climate/repo
Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/acce351a
Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/acce351a
Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/acce351a
Branch: refs/heads/master
Commit: acce351a8abc11d1215e627e297da1fe16ef4703
Parents: 9167f1a
Author: Michael Joyce <jo...@apache.org>
Authored: Wed Mar 25 11:36:12 2015 -0700
Committer: Michael Joyce <jo...@apache.org>
Committed: Wed Mar 25 11:36:12 2015 -0700
----------------------------------------------------------------------
docs/source/config/config_overview.rst | 5 +++++
docs/source/config/config_writer.rst | 5 +++++
2 files changed, 10 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/climate/blob/acce351a/docs/source/config/config_overview.rst
----------------------------------------------------------------------
diff --git a/docs/source/config/config_overview.rst b/docs/source/config/config_overview.rst
index aa2953b..d3141f4 100644
--- a/docs/source/config/config_overview.rst
+++ b/docs/source/config/config_overview.rst
@@ -78,3 +78,8 @@ If you have tried the **simple_model_to_model_bias.py** example in the primary t
.. note::
If you haven't run the previous example which downloads the necessary datasets this evaluation will fail. The necessary local files will not have been downloaded!
+
+Writing a Config File
+---------------------
+
+You can export an :class:`evaluation.Evaluation` object to a configuration file for easily repeatable evaluations. Checkout the documentation on the :doc:`configuration file writer API <config_writer>` for additional information.
http://git-wip-us.apache.org/repos/asf/climate/blob/acce351a/docs/source/config/config_writer.rst
----------------------------------------------------------------------
diff --git a/docs/source/config/config_writer.rst b/docs/source/config/config_writer.rst
new file mode 100644
index 0000000..eb9bb38
--- /dev/null
+++ b/docs/source/config/config_writer.rst
@@ -0,0 +1,5 @@
+Configuration File Writer API
+=============================
+
+.. automodule:: configuration_writer
+ :members:
[04/13] climate git commit: CLIMATE-581 - Add tests for metric config
output API
Posted by jo...@apache.org.
CLIMATE-581 - Add tests for metric config output API
Project: http://git-wip-us.apache.org/repos/asf/climate/repo
Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/e3dcace6
Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/e3dcace6
Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/e3dcace6
Branch: refs/heads/master
Commit: e3dcace61db9840adf6312754b67633971915dca
Parents: 0df1546
Author: Michael Joyce <jo...@apache.org>
Authored: Tue Mar 24 16:03:42 2015 -0700
Committer: Michael Joyce <jo...@apache.org>
Committed: Tue Mar 24 16:03:42 2015 -0700
----------------------------------------------------------------------
ocw-config-runner/tests/test_config_writer.py | 33 ++++++++++++++++++++++
1 file changed, 33 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/climate/blob/e3dcace6/ocw-config-runner/tests/test_config_writer.py
----------------------------------------------------------------------
diff --git a/ocw-config-runner/tests/test_config_writer.py b/ocw-config-runner/tests/test_config_writer.py
index ebae0de..b76b0b7 100644
--- a/ocw-config-runner/tests/test_config_writer.py
+++ b/ocw-config-runner/tests/test_config_writer.py
@@ -19,6 +19,8 @@ from mock import patch
import unittest
from ocw.dataset import Dataset
+from ocw.evaluation import Evaluation
+import ocw.metrics as metrics
import configuration_writer as writer
import datetime as dt
@@ -268,3 +270,34 @@ class TestDAPDatasetExportGeneration(unittest.TestCase):
def test_proper_units_name_export(self):
self.assertEqual(self.exported_info['optional_args']['units'],
self.units)
+
+
+class TestMetricExportGeneration(unittest.TestCase):
+ @classmethod
+ def setUpClass(self):
+ self.bias = metrics.Bias()
+ self.tmp_std_dev = metrics.TemporalStdDev()
+ loaded_metrics = [self.bias, self.tmp_std_dev]
+
+ self.evaluation = Evaluation(None, [], loaded_metrics)
+
+ def test_proper_export_format(self):
+ out = writer.generate_metric_information(self.evaluation)
+
+ self.assertTrue(type(out) == type(list()))
+
+ for name in out:
+ self.assertTrue(type(name) == type(str()))
+
+ def test_proper_metric_name_export(self):
+ out = writer.generate_metric_information(self.evaluation)
+
+ self.assertTrue(self.bias.__class__.__name__ in out)
+ self.assertTrue(self.tmp_std_dev.__class__.__name__ in out)
+
+ def test_empty_metrics_in_evaluation(self):
+ new_eval = Evaluation(None, [], [])
+ out = writer.generate_metric_information(new_eval)
+
+ self.assertTrue(type(out) == type(list()))
+ self.assertTrue(len(out) == 0)
[03/13] climate git commit: CLIMATE-581 - Add API for metric export
from Evaluation
Posted by jo...@apache.org.
CLIMATE-581 - Add API for metric export from Evaluation
Project: http://git-wip-us.apache.org/repos/asf/climate/repo
Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/0df15460
Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/0df15460
Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/0df15460
Branch: refs/heads/master
Commit: 0df15460b27c756ab20a761560b80a79a7b78db8
Parents: 41879f9
Author: Michael Joyce <jo...@apache.org>
Authored: Tue Mar 24 16:00:18 2015 -0700
Committer: Michael Joyce <jo...@apache.org>
Committed: Tue Mar 24 16:00:18 2015 -0700
----------------------------------------------------------------------
ocw-config-runner/configuration_writer.py | 15 +++++++++++++++
1 file changed, 15 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/climate/blob/0df15460/ocw-config-runner/configuration_writer.py
----------------------------------------------------------------------
diff --git a/ocw-config-runner/configuration_writer.py b/ocw-config-runner/configuration_writer.py
index ad14a91..bf1b8a0 100644
--- a/ocw-config-runner/configuration_writer.py
+++ b/ocw-config-runner/configuration_writer.py
@@ -55,6 +55,21 @@ def generate_dataset_information(dataset):
return info
+def generate_metric_information(evaluation):
+ ''' Generate metric config file output from a given Evaluation object.
+
+ :param evaluation: The evaluation object from which to extract metrics.
+ :type evaluation: :class:`evaluation.Evaluation`
+
+ :returns: A :func:`list` of :mod:`metrics` object names for output into
+ a configuration file.
+ :rtype: :func:`list` of :mod:`metrics`
+ '''
+ unary_metrics = [x.__class__.__name__ for x in evaluation.unary_metrics]
+ binary_metrics = [x.__class__.__name__ for x in evaluation.metrics]
+
+ return unary_metrics + binary_metrics
+
def _extract_local_dataset_info(dataset):
''''''
dataset_info = {'optional_args': {}}