You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@climate.apache.org by hu...@apache.org on 2016/08/03 15:40:07 UTC
[2/4] climate git commit: CLIMATE-827 - Adding spatial masking options
CLIMATE-827 - Adding spatial masking options
- new masking options, CORDEX, us_states, countires and user have been added
- dataset_processor.subset will be updated later.
Project: http://git-wip-us.apache.org/repos/asf/climate/repo
Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/02dfdec6
Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/02dfdec6
Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/02dfdec6
Branch: refs/heads/master
Commit: 02dfdec65adb81cdc659764008045e99f61bbf4d
Parents: 0cc4b1e
Author: huikyole <hu...@argo.jpl.nasa.gov>
Authored: Tue Aug 2 16:35:28 2016 -0700
Committer: huikyole <hu...@argo.jpl.nasa.gov>
Committed: Tue Aug 2 16:35:28 2016 -0700
----------------------------------------------------------------------
RCMES/cli_app.py | 2 +-
RCMES/run_RCMES.py | 2 +-
RCMES/test/test.py | 2 +-
examples/knmi_to_cru31_full_bias.py | 2 +-
examples/model_ensemble_to_rcmed.py | 2 +-
examples/multi_model_evaluation.py | 2 +-
examples/multi_model_taylor_diagram.py | 2 +-
examples/taylor_diagram_example.py | 2 +-
examples/time_series_with_regions.py | 2 +-
ocw/dataset.py | 176 +++++++--------------
ocw/dataset_processor.py | 113 ++++++-------
ocw/tests/test_dataset.py | 126 ++++-----------
ocw/tests/test_dataset_processor.py | 62 ++++----
ocw/tests/test_evaluation.py | 18 +--
ocw_config_runner/tests/test_config_writer.py | 4 +-
15 files changed, 201 insertions(+), 316 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/climate/blob/02dfdec6/RCMES/cli_app.py
----------------------------------------------------------------------
diff --git a/RCMES/cli_app.py b/RCMES/cli_app.py
index 9894a35..22572db 100644
--- a/RCMES/cli_app.py
+++ b/RCMES/cli_app.py
@@ -634,7 +634,7 @@ def run_screen(model_datasets, models_info, observations_info,
screen.addstr(4, 4, "--> Data retrieved.")
screen.refresh()
- EVAL_BOUNDS = Bounds(overlap_min_lat, overlap_max_lat, overlap_min_lon, overlap_max_lon, overlap_start_time, overlap_end_time)
+ EVAL_BOUNDS = Bounds(lat_min=overlap_min_lat, lat_max=overlap_max_lat, lon_min=overlap_min_lon, lon_max=overlap_max_lon, start=overlap_start_time, end=overlap_end_time)
screen.addstr(5, 4, "Temporally regridding...")
screen.refresh()
http://git-wip-us.apache.org/repos/asf/climate/blob/02dfdec6/RCMES/run_RCMES.py
----------------------------------------------------------------------
diff --git a/RCMES/run_RCMES.py b/RCMES/run_RCMES.py
index cd69bc4..d026ec3 100644
--- a/RCMES/run_RCMES.py
+++ b/RCMES/run_RCMES.py
@@ -144,7 +144,7 @@ if ref_data_info['data_source'] == 'rcmed':
max_lat = np.min([max_lat, ref_dataset.lats.max()])
min_lon = np.max([min_lon, ref_dataset.lons.min()])
max_lon = np.min([max_lon, ref_dataset.lons.max()])
-bounds = Bounds(min_lat, max_lat, min_lon, max_lon, start_time, end_time)
+bounds = Bounds(lat_min=min_lat, lat_max=max_lat, lon_min=min_lon, lon_max=max_lon, start=start_time, end=end_time)
ref_dataset = dsp.subset(ref_dataset, bounds)
if ref_dataset.temporal_resolution() != temporal_resolution:
http://git-wip-us.apache.org/repos/asf/climate/blob/02dfdec6/RCMES/test/test.py
----------------------------------------------------------------------
diff --git a/RCMES/test/test.py b/RCMES/test/test.py
index 677a13f..a62d781 100644
--- a/RCMES/test/test.py
+++ b/RCMES/test/test.py
@@ -111,7 +111,7 @@ print("KNMI_Dataset.values shape: (times, lats, lons) - %s" % (knmi_dataset.valu
print("Our two datasets have a mis-match in time. We will subset on time to %s years\n" % YEARS)
# Create a Bounds object to use for subsetting
-new_bounds = Bounds(min_lat, max_lat, min_lon, max_lon, start_time, end_time)
+new_bounds = Bounds(lat_min=min_lat, lat_max=max_lat, lon_min=min_lon, lon_max=max_lon, start=start_time, end=end_time)
knmi_dataset = dsp.subset(knmi_dataset, new_bounds)
print("CRU31_Dataset.values shape: (times, lats, lons) - %s" % (cru31_dataset.values.shape,))
http://git-wip-us.apache.org/repos/asf/climate/blob/02dfdec6/examples/knmi_to_cru31_full_bias.py
----------------------------------------------------------------------
diff --git a/examples/knmi_to_cru31_full_bias.py b/examples/knmi_to_cru31_full_bias.py
index 4c0abd9..dd70341 100644
--- a/examples/knmi_to_cru31_full_bias.py
+++ b/examples/knmi_to_cru31_full_bias.py
@@ -111,7 +111,7 @@ print("KNMI_Dataset.values shape: (times, lats, lons) - %s" % (knmi_dataset.valu
print("Our two datasets have a mis-match in time. We will subset on time to %s years\n" % YEARS)
# Create a Bounds object to use for subsetting
-new_bounds = Bounds(min_lat, max_lat, min_lon, max_lon, start_time, end_time)
+new_bounds = Bounds(lat_min=min_lat, lat_max=max_lat, lon_min=min_lon, lon_max=max_lon, start=start_time, end=end_time)
knmi_dataset = dsp.subset(knmi_dataset, new_bounds)
print("CRU31_Dataset.values shape: (times, lats, lons) - %s" % (cru31_dataset.values.shape,))
http://git-wip-us.apache.org/repos/asf/climate/blob/02dfdec6/examples/model_ensemble_to_rcmed.py
----------------------------------------------------------------------
diff --git a/examples/model_ensemble_to_rcmed.py b/examples/model_ensemble_to_rcmed.py
index fef1f9d..7b82197 100644
--- a/examples/model_ensemble_to_rcmed.py
+++ b/examples/model_ensemble_to_rcmed.py
@@ -128,7 +128,7 @@ cru31_dataset = dsp.temporal_rebin(cru31_dataset, temporal_resolution = 'annual'
# Running Temporal Rebin early helps negate the issue of datasets being on different
# days of the month (1st vs. 15th)
# Create a Bounds object to use for subsetting
-new_bounds = Bounds(min_lat, max_lat, min_lon, max_lon, start_time, end_time)
+new_bounds = Bounds(lat_min=min_lat, lat_max=max_lat, lon_min=min_lon, lon_max=max_lon, start=start_time, end=end_time)
# Subset our model datasets so they are the same size
knmi_dataset = dsp.subset(knmi_dataset, new_bounds)
http://git-wip-us.apache.org/repos/asf/climate/blob/02dfdec6/examples/multi_model_evaluation.py
----------------------------------------------------------------------
diff --git a/examples/multi_model_evaluation.py b/examples/multi_model_evaluation.py
index 0755279..97c96d9 100644
--- a/examples/multi_model_evaluation.py
+++ b/examples/multi_model_evaluation.py
@@ -50,7 +50,7 @@ LON_MIN = -24.0
LON_MAX = 60.0
START = datetime.datetime(2000, 1, 1)
END = datetime.datetime(2007, 12, 31)
-EVAL_BOUNDS = Bounds(LAT_MIN, LAT_MAX, LON_MIN, LON_MAX, START, END)
+EVAL_BOUNDS = Bounds(lat_min=LAT_MIN, lat_max=LAT_MAX, lon_min=LON_MIN, lon_max=LON_MAX, start=START, end=END)
#regridding parameters
gridLonStep=0.5
http://git-wip-us.apache.org/repos/asf/climate/blob/02dfdec6/examples/multi_model_taylor_diagram.py
----------------------------------------------------------------------
diff --git a/examples/multi_model_taylor_diagram.py b/examples/multi_model_taylor_diagram.py
index 9ba8746..b7daf61 100644
--- a/examples/multi_model_taylor_diagram.py
+++ b/examples/multi_model_taylor_diagram.py
@@ -34,7 +34,7 @@ LON_MIN = -24.0
LON_MAX = 60.0
START = datetime.datetime(2000, 01, 1)
END = datetime.datetime(2007, 12, 31)
-EVAL_BOUNDS = Bounds(LAT_MIN, LAT_MAX, LON_MIN, LON_MAX, START, END)
+EVAL_BOUNDS = Bounds(lat_min=LAT_MIN, lat_max=LAT_MAX, lon_min=LON_MIN, lon_max=LON_MAX, start=START, end=END)
#variable that we are analyzing
varName = 'pr'
http://git-wip-us.apache.org/repos/asf/climate/blob/02dfdec6/examples/taylor_diagram_example.py
----------------------------------------------------------------------
diff --git a/examples/taylor_diagram_example.py b/examples/taylor_diagram_example.py
index 66ca175..bae85be 100644
--- a/examples/taylor_diagram_example.py
+++ b/examples/taylor_diagram_example.py
@@ -61,7 +61,7 @@ wrf_dataset = dsp.normalize_dataset_datetimes(wrf_dataset, 'monthly')
# We're only going to run this evaluation over a years worth of data. We'll
# make a Bounds object and use it to subset our datasets.
################################################################################
-subset = Bounds(-45, 42, -24, 60, datetime.datetime(1989, 1, 1), datetime.datetime(1989, 12, 1))
+subset = Bounds(lat_min=-45, lat_max=42, lon_min=-24, lon_max=60, start=datetime.datetime(1989, 1, 1), end=datetime.datetime(1989, 12, 1))
knmi_dataset = dsp.subset(knmi_dataset, subset)
wrf_dataset = dsp.subset(wrf_dataset, subset)
http://git-wip-us.apache.org/repos/asf/climate/blob/02dfdec6/examples/time_series_with_regions.py
----------------------------------------------------------------------
diff --git a/examples/time_series_with_regions.py b/examples/time_series_with_regions.py
index 8d9e5c0..15e2ee2 100644
--- a/examples/time_series_with_regions.py
+++ b/examples/time_series_with_regions.py
@@ -32,7 +32,7 @@ LON_MAX = 60.0
START = datetime.datetime(2000, 01, 1)
END = datetime.datetime(2007, 12, 31)
-EVAL_BOUNDS = Bounds(LAT_MIN, LAT_MAX, LON_MIN, LON_MAX, START, END)
+EVAL_BOUNDS = Bounds(lat_min=LAT_MIN, lat_max=LAT_MAX, lon_min=LON_MIN, lon_max=LON_MAX, start=START, end=END)
varName = 'pr'
gridLonStep=0.44
http://git-wip-us.apache.org/repos/asf/climate/blob/02dfdec6/ocw/dataset.py
----------------------------------------------------------------------
diff --git a/ocw/dataset.py b/ocw/dataset.py
index 509c04a..52e610a 100644
--- a/ocw/dataset.py
+++ b/ocw/dataset.py
@@ -28,6 +28,7 @@ import datetime as dt
from mpl_toolkits.basemap import Basemap
import netCDF4
+import ocw
import ocw.utils as utils
logger = logging.getLogger(__name__)
@@ -295,32 +296,6 @@ class Bounds(object):
else:
self._end = None
- @property
- def start(self):
- return self._start
-
- @start.setter
- def start(self, value):
- if self._end:
- if not (type(value) is dt.datetime and value < self._end):
- error = "Attempted to set start to invalid value: %s" % (value)
- logger.error(error)
- raise ValueError(error)
-
- self._start = value
-
- @property
- def end(self):
- return self._end
-
- @end.setter
- def end(self, value):
- if self._start:
- if not (type(value) is dt.datetime and value > self._start):
- error = "Attempted to set end to invalid value: %s" % (value)
- logger.error(error)
- raise ValueError(error)
-
if boundary_type == 'us_states':
self.masked_regions = shapefile_boundary(boundary_type, us_states)
if boundary_type == 'countries':
@@ -331,91 +306,62 @@ class Bounds(object):
mask_longitude = file_object.variables[longitude_name][:]
mask_latitude = file_object.variables[latitude_name][:]
if mask_longitude.ndim == 1 and mask_latitude.ndim == 1:
- self.mask_longitude, self.mask_latitude = np.meshgrid(mask_longitude, mask_latitude)
+ self.mask_longitude, self.mask_latitude = numpy.meshgrid(mask_longitude, mask_latitude)
elif mask_longitude.ndim == 2 and mask_latitude.ndim == 2:
self.mask_longitude = mask_longitude
self.mask_latitude = mask_latitude
- if boundary_type == 'rectangular' or boundary_type[:6].upper() == 'CORDEX':
- if boundary_type == 'rectangular':
- self._lat_min = float(lat_min)
- self._lat_max = float(lat_max)
- self._lon_min = float(lon_min)
- self._lon_max = float(lon_max)
- if boundary_type[:6].upper() == 'CORDEX':
- self._lat_min, self._lat_max, self._lon_min, self._lon_max = CORDEX_boundary(boundary_type[6:].replace(" ","").lower())
-
-
- @property
- def lat_min(self):
- return self._lat_min
-
- @lat_min.setter
- def lat_min(self, value):
- if not (-90 <= value <= 90 and value < self._lat_max):
- error = "Attempted to set lat_min to invalid value: %s" % (value)
- logger.error(error)
- raise ValueError(error)
-
- self._lat_min = value
-
- @property
- def lat_max(self):
- return self._lat_max
-
- @lat_max.setter
- def lat_max(self, value):
- if not (-90 <= value <= 90 and value > self._lat_min):
- error = "Attempted to set lat_max to invalid value: %s" % (value)
- logger.error(error)
- raise ValueError(error)
-
- self._lat_max = value
-
- @property
- def lon_min(self):
- return self._lon_min
-
- @lon_min.setter
- def lon_min(self, value):
- if not (-180 <= value <= 180 and value < self._lon_max):
- error = "Attempted to set lon_min to invalid value: %s" % (value)
- logger.error(error)
- raise ValueError(error)
-
- self._lon_min = value
-
- @property
- def lon_max(self):
- return self._lon_max
-
- @lon_max.setter
- def lon_max(self, value):
- if not (-180 <= value <= 180 and value > self._lon_min):
- error = "Attempter to set lon_max to invalid value: %s" % (value)
- logger.error(error)
- raise ValueError(error)
-
- self._lon_max = value
-
-
- def __str__(self):
- lat_range = "({}, {})".format(self._lat_min, self._lat_max)
- lon_range = "({}, {})".format(self._lon_min, self._lon_max)
- temporal_boundaries = "({}, {})".format(self._start, self._end)
-
- formatted_repr = (
- "<Bounds - "
- "lat-range: {}, "
- "lon-range: {}, "
- "temporal_boundaries: {}> "
- )
-
- return formatted_repr.format(
- lat_range,
- lon_range,
- temporal_boundaries,
- )
-
+ if boundary_type == 'rectangular':
+ if not (-90 <= float(lat_min) <=90) or float(lat_min) > float(lat_max):
+ error = "Attempted to set lat_min to invalid value: %s" % (lat_min)
+ logger.error(error)
+ raise ValueError(error)
+ if not (-90 <= float(lat_max) <=90):
+ error = "Attempted to set lat_max to invalid value: %s" % (lat_max)
+ logger.error(error)
+ raise ValueError(error)
+ if not (-180 <= float(lon_min) <=180) or float(lon_min) > float(lon_max):
+ error = "Attempted to set lon_min to invalid value: %s" % (lon_min)
+ logger.error(error)
+ raise ValueError(error)
+ if not (-180 <= float(lon_max) <=180):
+ error = "Attempted to set lat_max to invalid value: %s" % (lon_max)
+ logger.error(error)
+ raise ValueError(error)
+
+ self.lat_min = float(lat_min)
+ self.lat_max = float(lat_max)
+ self.lon_min = float(lon_min)
+ self.lon_max = float(lon_max)
+ if boundary_type[:6].upper() == 'CORDEX':
+ self.lat_min, self.lat_max, self.lon_min, self.lon_max = CORDEX_boundary(boundary_type[6:].replace(" ","").lower())
+
+ @property
+ def start(self):
+ return self._start
+
+ @start.setter
+ def start(self, value):
+ if self._end:
+ if not (type(value) is dt.datetime and value < self._end):
+ error = "Attempted to set start to invalid value: %s" % (value)
+ logger.error(error)
+ raise ValueError(error)
+
+ self._start = value
+
+ @property
+ def end(self):
+ return self._end
+
+ @end.setter
+ def end(self, value):
+ if self._start:
+ if not (type(value) is dt.datetime and value > self._start):
+ error = "Attempted to set end to invalid value: %s" % (value)
+ logger.error(error)
+ raise ValueError(error)
+
+ self._end = value
def shapefile_boundary(boundary_type, region_names):
'''
@@ -426,22 +372,22 @@ def shapefile_boundary(boundary_type, region_names):
:type region_names: :mod:'list'
'''
- map_read = Basemap
+ map_read = Basemap()
regions =[]
if boundary_type == 'us_states':
- #map_read.readshapefile(ocw.__path__[0]+'/shape/usa_states','usa_states')
- map_read.readshapefile('/home/huikyole/climate/ocw'+'/shape/usa_states','usa_states')
+ map_read.readshapefile(ocw.__path__[0]+'/shape/usa_states','usa_states')
+ #map_read.readshapefile('/home/huikyole/climate/ocw'+'/shape/usa_states','usa_states')
for region_name in region_names:
for iregion, region_info in enumerate(map_read.usa_states_info):
if region_info['st'] == region_name:
- regions.append(np.array(map_read.usa_states[iregion]))
+ regions.append(numpy.array(map_read.usa_states[iregion]))
if boundary_type == 'countries':
- #map_read.readshapefile(ocw.__path__[0]+'/shape/countries','countries')
- map_read.readshapefile('/home/huikyole/climate/ocw'+'/shape/countries','countries')
+ map_read.readshapefile(ocw.__path__[0]+'/shape/countries','countries')
+ #map_read.readshapefile('/home/huikyole/climate/ocw'+'/shape/countries','countries')
for region_name in region_names:
for iregion, region_info in enumerate(map_read.countries_info):
if region_info['COUNTRY'] == region_name:
- regions.append(np.array(map_read.countries[iregion]))
+ regions.append(numpy.array(map_read.countries[iregion]))
return regions
def CORDEX_boundary(domain_name):
http://git-wip-us.apache.org/repos/asf/climate/blob/02dfdec6/ocw/dataset_processor.py
----------------------------------------------------------------------
diff --git a/ocw/dataset_processor.py b/ocw/dataset_processor.py
index 2b5dc9b..8b817a2 100755
--- a/ocw/dataset_processor.py
+++ b/ocw/dataset_processor.py
@@ -383,57 +383,58 @@ def subset(target_dataset, subregion, subregion_name=None):
if not subregion.start:
subregion.start = target_dataset.times[0]
subregion.end = target_dataset.times[-1]
-
- # Ensure that the subregion information is well formed
- _are_bounds_contained_by_dataset(target_dataset, subregion)
-
+
if not subregion_name:
subregion_name = target_dataset.name
- if target_dataset.lats.ndim == 2 and target_dataset.lons.ndim == 2:
- start_time_index = np.where(
- target_dataset.times == subregion.start)[0][0]
- end_time_index = np.where(target_dataset.times == subregion.end)[0][0]
- target_dataset = temporal_slice(
- target_dataset, start_time_index, end_time_index)
- nt, ny, nx = target_dataset.values.shape
- y_index, x_index = np.where(
- (target_dataset.lats >= subregion.lat_max) | (
- target_dataset.lats <= subregion.lat_min) |
- (target_dataset.lons >= subregion.lon_max) | (
- target_dataset.lons <= subregion.lon_min))
- for it in np.arange(nt):
- target_dataset.values[it, y_index, x_index] = 1.e+20
- target_dataset.values = ma.masked_equal(target_dataset.values, 1.e+20)
- return target_dataset
-
- elif target_dataset.lats.ndim == 1 and target_dataset.lons.ndim == 1:
- # Get subregion indices into subregion data
- dataset_slices = _get_subregion_slice_indices(target_dataset,
- subregion)
- # Slice the values array with our calculated slice indices
- if target_dataset.values.ndim == 2:
- subset_values = ma.zeros([len(target_dataset.values[
- dataset_slices["lat_start"]:dataset_slices["lat_end"]]),
- len(target_dataset.values[
- dataset_slices["lon_start"]:dataset_slices["lon_end"]])])
-
- subset_values = target_dataset.values[
- dataset_slices["lat_start"]:dataset_slices["lat_end"] + 1,
- dataset_slices["lon_start"]:dataset_slices["lon_end"] + 1]
-
- elif target_dataset.values.ndim == 3:
- subset_values = ma.zeros([len(target_dataset.values[
- dataset_slices["time_start"]:dataset_slices["time_end"]]),
- len(target_dataset.values[
+ if subregion.lat_min:
+ # If boundary_type is 'rectangular' or 'CORDEX ***', ensure that the subregion information is well formed
+ _are_bounds_contained_by_dataset(target_dataset, subregion)
+
+ if target_dataset.lats.ndim == 2 and target_dataset.lons.ndim == 2:
+ start_time_index = np.where(
+ target_dataset.times == subregion.start)[0][0]
+ end_time_index = np.where(target_dataset.times == subregion.end)[0][0]
+ target_dataset = temporal_slice(
+ target_dataset, start_time_index, end_time_index)
+ nt, ny, nx = target_dataset.values.shape
+ y_index, x_index = np.where(
+ (target_dataset.lats >= subregion.lat_max) | (
+ target_dataset.lats <= subregion.lat_min) |
+ (target_dataset.lons >= subregion.lon_max) | (
+ target_dataset.lons <= subregion.lon_min))
+ for it in np.arange(nt):
+ target_dataset.values[it, y_index, x_index] = 1.e+20
+ target_dataset.values = ma.masked_equal(target_dataset.values, 1.e+20)
+ return target_dataset
+
+ elif target_dataset.lats.ndim == 1 and target_dataset.lons.ndim == 1:
+ # Get subregion indices into subregion data
+ dataset_slices = _get_subregion_slice_indices(target_dataset,
+ subregion)
+ # Slice the values array with our calculated slice indices
+ if target_dataset.values.ndim == 2:
+ subset_values = ma.zeros([len(target_dataset.values[
dataset_slices["lat_start"]:dataset_slices["lat_end"]]),
- len(target_dataset.values[
- dataset_slices["lon_start"]:dataset_slices["lon_end"]])])
-
- subset_values = target_dataset.values[
- dataset_slices["time_start"]:dataset_slices["time_end"] + 1,
- dataset_slices["lat_start"]:dataset_slices["lat_end"] + 1,
- dataset_slices["lon_start"]:dataset_slices["lon_end"] + 1]
+ len(target_dataset.values[
+ dataset_slices["lon_start"]:dataset_slices["lon_end"]])])
+
+ subset_values = target_dataset.values[
+ dataset_slices["lat_start"]:dataset_slices["lat_end"] + 1,
+ dataset_slices["lon_start"]:dataset_slices["lon_end"] + 1]
+
+ elif target_dataset.values.ndim == 3:
+ subset_values = ma.zeros([len(target_dataset.values[
+ dataset_slices["time_start"]:dataset_slices["time_end"]]),
+ len(target_dataset.values[
+ dataset_slices["lat_start"]:dataset_slices["lat_end"]]),
+ len(target_dataset.values[
+ dataset_slices["lon_start"]:dataset_slices["lon_end"]])])
+
+ subset_values = target_dataset.values[
+ dataset_slices["time_start"]:dataset_slices["time_end"] + 1,
+ dataset_slices["lat_start"]:dataset_slices["lat_end"] + 1,
+ dataset_slices["lon_start"]:dataset_slices["lon_end"] + 1]
# Build new dataset with subset information
return ds.Dataset(
@@ -505,18 +506,18 @@ def safe_subset(target_dataset, subregion, subregion_name=None):
lat_min, lat_max, lon_min, lon_max = target_dataset.spatial_boundaries()
start, end = target_dataset.temporal_boundaries()
+ if subregion.lat_min:
+ if subregion.lat_min < lat_min:
+ subregion.lat_min = lat_min
- if subregion.lat_min < lat_min:
- subregion.lat_min = lat_min
-
- if subregion.lat_max > lat_max:
- subregion.lat_max = lat_max
+ if subregion.lat_max > lat_max:
+ subregion.lat_max = lat_max
- if subregion.lon_min < lon_min:
- subregion.lon_min = lon_min
+ if subregion.lon_min < lon_min:
+ subregion.lon_min = lon_min
- if subregion.lon_max > lon_max:
- subregion.lon_max = lon_max
+ if subregion.lon_max > lon_max:
+ subregion.lon_max = lon_max
if subregion.start:
if subregion.start < start:
http://git-wip-us.apache.org/repos/asf/climate/blob/02dfdec6/ocw/tests/test_dataset.py
----------------------------------------------------------------------
diff --git a/ocw/tests/test_dataset.py b/ocw/tests/test_dataset.py
index 8b666c1..9d77400 100644
--- a/ocw/tests/test_dataset.py
+++ b/ocw/tests/test_dataset.py
@@ -214,120 +214,58 @@ class TestDatasetFunctions(unittest.TestCase):
class TestBounds(unittest.TestCase):
def setUp(self):
- self.bounds = Bounds(-80, 80, # Lats
- -160, 160, # Lons
- dt.datetime(2000, 1, 1), # Start time
- dt.datetime(2002, 1, 1)) # End time
- self.another_bounds = Bounds(-80, 80, # Lats
- -160, 160)
-
- def test_setter_methods(self):
- self.bounds.lat_min = -10
- self.bounds.lat_max = 10
- self.bounds.lon_min = -120
- self.bounds.lon_max = 120
- self.bounds.start = dt.datetime(2000, 1, 2)
- self.bounds.end = dt.datetime(2002, 1, 4)
-
- self.assertEqual(self.bounds.lat_min, -10)
- self.assertEqual(self.bounds.lat_max, 10)
- self.assertEqual(self.bounds.lon_min, -120)
- self.assertEqual(self.bounds.lon_max, 120)
- self.assertEqual(self.bounds.start, dt.datetime(2000, 1, 2))
- self.assertEqual(self.bounds.end, dt.datetime(2002, 1, 4))
-
- # Latitude tests
- def test_inverted_min_max_lat(self):
- with self.assertRaises(ValueError):
- self.bounds.lat_min = 81
-
- with self.assertRaises(ValueError):
- self.bounds.lat_max = -81
-
- # Lat Min
- def test_out_of_bounds_lat_min(self):
- with self.assertRaises(ValueError):
- self.bounds.lat_min = -91
-
- with self.assertRaises(ValueError):
- self.bounds.lat_min = 91
-
- # Lat Max
- def test_out_of_bounds_lat_max(self):
- with self.assertRaises(ValueError):
- self.bounds.lat_max = -91
-
- with self.assertRaises(ValueError):
- self.bounds.lat_max = 91
-
- # Longitude tests
- def test_inverted_max_max_lon(self):
- with self.assertRaises(ValueError):
- self.bounds.lon_min = 161
-
- with self.assertRaises(ValueError):
- self.bounds.lon_max = -161
-
- # Lon Min
- def test_out_of_bounds_lon_min(self):
- with self.assertRaises(ValueError):
- self.bounds.lon_min = -181
-
- with self.assertRaises(ValueError):
- self.bounds.lon_min = 181
-
- # Lon Max
- def test_out_of_bounds_lon_max(self):
- with self.assertRaises(ValueError):
- self.bounds.lon_max = -181
-
- with self.assertRaises(ValueError):
- self.bounds.lon_max = 181
+ self.bounds_rectangular = Bounds(lat_min=-80, lat_max=80, # Lats
+ lon_min=-160, lon_max=160, # Lons
+ start=dt.datetime(2000, 1, 1), # Start time
+ end=dt.datetime(2002, 1, 1)) # End time
+ self.bounds_CORDEX = Bounds(boundary_type='CORDEX South Asia')
+ self.bounds_us_states = Bounds(boundary_type='us_states', us_states=['CA','NV','AZ'])
+ self.bounds_countries = Bounds(boundary_type='countries', countries=['United States','Canada','Mexico'])
+
+ def test_keywords(self):
+ self.assertEqual(self.bounds_rectangular.boundary_type, 'rectangular')
+ self.assertEqual(self.bounds_rectangular.lat_min, -80)
+ self.assertEqual(self.bounds_rectangular.lat_max, 80)
+ self.assertEqual(self.bounds_rectangular.lon_min, -160)
+ self.assertEqual(self.bounds_rectangular.lon_max, 160)
+ self.assertEqual(self.bounds_rectangular.start, dt.datetime(2000,1,1))
+ self.assertEqual(self.bounds_rectangular.end, dt.datetime(2002,1,1))
+
+ self.assertEqual(self.bounds_CORDEX.boundary_type, 'CORDEX South Asia')
+ self.assertEqual(self.bounds_CORDEX.lat_min, -15.23)
+ self.assertEqual(self.bounds_CORDEX.lat_max, 45.07)
+ self.assertEqual(self.bounds_CORDEX.lon_min, 19.88)
+ self.assertEqual(self.bounds_CORDEX.lon_max, 115.55)
+
+ self.assertEqual(self.bounds_us_states.boundary_type, 'us_states')
+
+ self.assertEqual(self.bounds_countries.boundary_type, 'countries')
# Temporal tests
def test_inverted_start_end_times(self):
with self.assertRaises(ValueError):
- self.bounds.start = dt.datetime(2003, 1, 1)
+ self.bounds_rectangular.start = dt.datetime(2003, 1, 1)
with self.assertRaises(ValueError):
- self.bounds.end = dt.datetime(1999, 1, 1)
+ self.bounds_rectangular.end = dt.datetime(1999, 1, 1)
# Start tests
def test_invalid_start(self):
with self.assertRaises(ValueError):
- self.bounds.start = "This is not a date time object"
+ self.bounds_rectangular.start = "This is not a date time object"
# End tests
def test_invalid_end(self):
with self.assertRaises(ValueError):
- self.bounds.end = "This is not a date time object"
+ self.bounds_rectangular.end = "This is not a date time object"
# Start tests
def test_none_value_start(self):
- self.assertEqual(self.another_bounds.start, None)
+ self.assertEqual(self.bounds_CORDEX.start, None)
# End tests
def test_none_value_end(self):
- self.assertEqual(self.another_bounds.end, None)
-
- def test__str__(self):
- lat_range = "({}, {})".format(self.bounds.lat_min, self.bounds.lat_max)
- lon_range = "({}, {})".format(self.bounds.lon_min, self.bounds.lon_max)
- temporal_boundaries = "({}, {})".format(self.bounds.start, self.bounds.end)
-
- formatted_repr = (
- "<Bounds - "
- "lat-range: {}, "
- "lon-range: {}, "
- "temporal_boundaries: {}> "
- )
-
- output = formatted_repr.format(
- lat_range,
- lon_range,
- temporal_boundaries,
- )
- self.assertEqual(str(self.bounds), output)
+ self.assertEqual(self.bounds_CORDEX.end, None)
if __name__ == '__main__':
unittest.main()
http://git-wip-us.apache.org/repos/asf/climate/blob/02dfdec6/ocw/tests/test_dataset_processor.py
----------------------------------------------------------------------
diff --git a/ocw/tests/test_dataset_processor.py b/ocw/tests/test_dataset_processor.py
index 627955a..0f8131e 100644
--- a/ocw/tests/test_dataset_processor.py
+++ b/ocw/tests/test_dataset_processor.py
@@ -431,22 +431,22 @@ class TestSubset(unittest.TestCase):
self.name = 'foo'
self.subregion = ds.Bounds(
- -81, 81,
- -161, 161,
- datetime.datetime(2001, 1, 1),
- datetime.datetime(2004, 1, 1)
+ lat_min=-81, lat_max=81,
+ lon_min=-161, lon_max=161,
+ start=datetime.datetime(2001, 1, 1),
+ end=datetime.datetime(2004, 1, 1)
)
self.non_exact_spatial_subregion = ds.Bounds(
- -80.25, 80.5,
- -160.25, 160.5,
- datetime.datetime(2001, 1, 1),
- datetime.datetime(2004, 1, 1)
+ lat_min=-80.25, lat_max=80.5,
+ lon_min=-160.25, lon_max=160.5,
+ start=datetime.datetime(2001, 1, 1),
+ end=datetime.datetime(2004, 1, 1)
)
self.non_exact_temporal_subregion = ds.Bounds(
- -80.25, 80.5,
- -160.25, 160.5,
- datetime.datetime(2001, 1, 15),
- datetime.datetime(2004, 2, 15)
+ lat_min=-80.25, lat_max=80.5,
+ lon_min=-160.25, lon_max=160.5,
+ start=datetime.datetime(2001, 1, 15),
+ end=datetime.datetime(2004, 2, 15)
)
def test_subset(self):
@@ -491,8 +491,8 @@ class TestSubset(unittest.TestCase):
def test_subset_without_start_index(self):
self.subregion = ds.Bounds(
- -81, 81,
- -161, 161,
+ lat_min=-81, lat_max=81,
+ lon_min=-161, lon_max=161,
)
subset = dp.subset(self.target_dataset, self.subregion)
times = np.array([datetime.datetime(year, month, 1)
@@ -524,24 +524,24 @@ class TestSafeSubset(unittest.TestCase):
name='foo')
self.spatial_out_of_bounds = ds.Bounds(
- -165, 165,
- -180, 180,
- datetime.datetime(2001, 1, 1),
- datetime.datetime(2004, 1, 1)
+ lat_min=-65, lat_max=65,
+ lon_min=-180, lon_max=180,
+ start=datetime.datetime(2001, 1, 1),
+ end=datetime.datetime(2004, 1, 1)
)
self.temporal_out_of_bounds = ds.Bounds(
- -40, 40,
- -160.25, 160.5,
- datetime.datetime(1999, 1, 15),
- datetime.datetime(2222, 2, 15)
+ lat_min=-40, lat_max=40,
+ lon_min=-160.25, lon_max=160.5,
+ start=datetime.datetime(1999, 1, 15),
+ end=datetime.datetime(2222, 2, 15)
)
self.everything_out_of_bounds = ds.Bounds(
- -165, 165,
- -180, 180,
- datetime.datetime(1999, 1, 15),
- datetime.datetime(2222, 2, 15)
+ lat_min=-65, lat_max=65,
+ lon_min=-180, lon_max=180,
+ start=datetime.datetime(1999, 1, 15),
+ end=datetime.datetime(2222, 2, 15)
)
def test_partial_spatial_overlap(self):
@@ -556,7 +556,7 @@ class TestSafeSubset(unittest.TestCase):
def test_partial_temporal_overlap(self):
'''Ensure that safe_subset can handle out of bounds temporal values'''
ds = dp.safe_subset(self.target_dataset, self.temporal_out_of_bounds)
- temporal_bounds = ds.time_range()
+ temporal_bounds = ds.temporal_boundaries()
start = datetime.datetime(2000, 1, 1)
end = datetime.datetime(2009, 12, 1)
@@ -585,10 +585,10 @@ class TestFailingSubset(unittest.TestCase):
self.target_dataset.lons = np.array(range(-179, 178, 2))
self.subregion = ds.Bounds(
- -81, 81,
- -161, 161,
- datetime.datetime(2001, 1, 1),
- datetime.datetime(2004, 1, 1)
+ lat_min=-81, lat_max=81,
+ lon_min=-161, lon_max=161,
+ start=datetime.datetime(2001, 1, 1),
+ end=datetime.datetime(2004, 1, 1)
)
def test_out_of_dataset_bounds_lat_min(self):
http://git-wip-us.apache.org/repos/asf/climate/blob/02dfdec6/ocw/tests/test_evaluation.py
----------------------------------------------------------------------
diff --git a/ocw/tests/test_evaluation.py b/ocw/tests/test_evaluation.py
index e348fd9..9053e52 100644
--- a/ocw/tests/test_evaluation.py
+++ b/ocw/tests/test_evaluation.py
@@ -98,9 +98,9 @@ class TestEvaluation(unittest.TestCase):
def test_valid_subregion(self):
bound = Bounds(
- -10, 10,
- -20, 20,
- dt.datetime(2000, 1, 1), dt.datetime(2001, 1, 1))
+ lat_min=-10, lat_max=10,
+ lon_min=-20, lon_max=20,
+ start=dt.datetime(2000, 1, 1), end=dt.datetime(2001, 1, 1))
self.eval.subregions = [bound, bound]
self.assertEquals(len(self.eval.subregions), 2)
@@ -198,9 +198,9 @@ class TestEvaluation(unittest.TestCase):
def test_subregion_result_shape(self):
bound = Bounds(
- 10, 18,
- 100, 108,
- dt.datetime(2000, 1, 1), dt.datetime(2000, 3, 1))
+ lat_min=10, lat_max=18,
+ lon_min=100, lon_max=108,
+ start=dt.datetime(2000, 1, 1), end=dt.datetime(2000, 3, 1))
bias_eval = Evaluation(
self.test_dataset,
@@ -223,9 +223,9 @@ class TestEvaluation(unittest.TestCase):
def test_subregion_unary_result_shape(self):
bound = Bounds(
- 10, 18,
- 100, 108,
- dt.datetime(2000, 1, 1), dt.datetime(2000, 3, 1))
+ lat_min=10, lat_max=18,
+ lon_min=100, lon_max=108,
+ start=dt.datetime(2000, 1, 1), end=dt.datetime(2000, 3, 1))
new_eval = Evaluation(
self.test_dataset,
http://git-wip-us.apache.org/repos/asf/climate/blob/02dfdec6/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 ed22417..ceaa2b1 100644
--- a/ocw_config_runner/tests/test_config_writer.py
+++ b/ocw_config_runner/tests/test_config_writer.py
@@ -652,8 +652,8 @@ class FullExportTest(unittest.TestCase):
)
self.subregions = [
- Bounds(-10, 10, -20, 20),
- Bounds(-5, 5, -15, 15)
+ Bounds(lat_min=-10, lat_max=10, lon_min=-20, lon_max=20),
+ Bounds(lat_min=-5, lat_max=5, lon_min=-15, lon_max=15)
]
self.evaluation = Evaluation(