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 <[email protected]> Authored: Tue Mar 24 18:12:57 2015 -0700 Committer: Michael Joyce <[email protected]> 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)]
