diff --git a/doc/source/new.rst b/doc/source/new.rst index 5583732..653f240 100644 --- a/doc/source/new.rst +++ b/doc/source/new.rst @@ -4,6 +4,14 @@ What's New Releases ------------- +v1.0.4 +^^^^^^^^^^^^^^ + +- Release 1.0.4 +- Fix warnings with continuous integration tests which was caused by fill + values being written as NaN to the NetCDF result file. +- Added the __eq__ operator to the WrfProj projection base class. + v1.0.3 ^^^^^^^^^^^^^^ diff --git a/src/wrf/projection.py b/src/wrf/projection.py index 58e8b59..f8b95d5 100644 --- a/src/wrf/projection.py +++ b/src/wrf/projection.py @@ -2,6 +2,7 @@ from __future__ import (absolute_import, division, print_function, unicode_literals) import numpy as np import math +from decimal import Decimal, Context, ROUND_HALF_UP from .config import basemap_enabled, cartopy_enabled, pyngl_enabled from .constants import Constants, ProjectionTypes @@ -176,6 +177,73 @@ class WrfProj(object): if self.stand_lon is None: self.stand_lon = self._cen_lon + + + @staticmethod + def _context_equal(x, y, ctx): + """Return True if both objects are equal based on the provided context. + + Args: + + x (numeric): A numeric value. + + y (numeric): A numeric value. + + ctx (:class:`decimal.Context`): A decimal Context object. + + Returns: + + :obj:`bool`: True if the values are equal based on the provided + context, False otherwise. + + """ + if x is not None: + if y is None: + return False + + # Note: The float conversion is because these may come in as + # numpy.float32 or numpy.float64, which Decimal does not know + # how to handle. + if (Decimal(float(x)).normalize(ctx) != + Decimal(float(y)).normalize(ctx)): + return False + else: + if y is not None: + return False + + return True + + + def __eq__(self, other): + """Return True if this projection object is the same as *other*. + + Note: WRF can use either floats or doubles, so only going to + guarantee floating point precision equivalence, in case the different + types are ever compared (or a projection is hand constructed). For WRF + domains, 7-digit equivalence should be good enough. + + """ + + if self.map_proj is not None: + if self.map_proj != other.map_proj: + return False + else: + if other.map_proj is not None: + return False + + # Only checking for floating point equal. + ctx = Context(prec=7, rounding=ROUND_HALF_UP) + + return (WrfProj._context_equal(self.truelat1, other.truelat1, ctx) and + WrfProj._context_equal(self.truelat2, other.truelat2, ctx) and + WrfProj._context_equal(self.moad_cen_lat, other.moad_cen_lat, + ctx) and + WrfProj._context_equal(self.stand_lon, other.stand_lon, + ctx) and + WrfProj._context_equal(self.pole_lat, other.pole_lat, ctx) and + WrfProj._context_equal(self.pole_lon, other.pole_lon, ctx) and + WrfProj._context_equal(self.dx, other.dx, ctx) and + WrfProj._context_equal(self.dy, other.dy, ctx)) def _basemap(self, geobounds, **kwargs): @@ -291,7 +359,7 @@ class WrfProj(object): """Return a :class:`matplotlib.mpl_toolkits.basemap.Basemap` object for the map projection. - Arguments: + Args: geobounds (:class:`wrf.GeoBounds`, optional): The geobounds to get the extents. If set to None and using the *var* parameter, diff --git a/test/ci_tests/ci_result_file.nc b/test/ci_tests/ci_result_file.nc index 1dfbe74..a5c275e 100644 Binary files a/test/ci_tests/ci_result_file.nc and b/test/ci_tests/ci_result_file.nc differ diff --git a/test/ci_tests/ci_test_file.nc b/test/ci_tests/ci_test_file.nc index 1dbbf4c..2b7c188 100644 Binary files a/test/ci_tests/ci_test_file.nc and b/test/ci_tests/ci_test_file.nc differ diff --git a/test/ci_tests/make_test_file.py b/test/ci_tests/make_test_file.py index 147d8b9..48e8e89 100644 --- a/test/ci_tests/make_test_file.py +++ b/test/ci_tests/make_test_file.py @@ -7,7 +7,7 @@ import numpy as np from netCDF4 import Dataset from wrf import (getvar, interplevel, interpline, vertcross, vinterp, py2round, - CoordPair, ll_to_xy, xy_to_ll) + CoordPair, ll_to_xy, xy_to_ll, to_np) VARS_TO_KEEP = ("XLAT", "XLONG", "XLAT_U", "XLAT_V", "XLONG_U", "XLONG_V", "U", "V", "W", "PH", "PHB", "T", "P", "PB", "Q2", "T2", @@ -15,7 +15,7 @@ VARS_TO_KEEP = ("XLAT", "XLONG", "XLAT_U", "XLAT_V", "XLONG_U", "XLONG_V", "QGRAUP", "QRAIN", "QSNOW", "MAPFAC_M", "MAPFAC_U", "MAPFAC_V", "F", "HGT", "RAINC", "RAINSH", "RAINNC") -DIMS_TO_TRIM = ("west_east", "south_north", "bottom_top", "bottom_top_stag", +DIMS_TO_TRIM = ("west_east", "south_north", #"bottom_top", "bottom_top_stag", "west_east_stag", "south_north_stag") WRF_DIAGS = ["avo", "eth", "cape_2d", "cape_3d", "ctt", "dbz", "mdbz", @@ -81,7 +81,9 @@ def add_to_ncfile(outfile, var, varname): ncvar = outfile.createVariable(varname, var.dtype, var.dims, zlib=True, fill_value=fill_value) - ncvar[:] = var[:] + + var_vals = to_np(var) + ncvar[:] = var_vals[:] def make_result_file(opts):