diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 043cd2e1963..c6423ac75a2 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -98,7 +98,7 @@ jobs: - name: Enable linkchecker for PRs if: ${{ github.event_name == 'pull_request' && matrix.check-links == true }} - run: echo "::set-env name=LINKCHECKER::linkcheck" + run: echo "LINKCHECKER=linkcheck" >> $GITHUB_ENV - name: Build docs run: | @@ -120,7 +120,7 @@ jobs: # branch that's not master (which is confined to n.nn.x above) or on a tag. - name: Set doc version if: ${{ github.event_name != 'push' || !contains(github.ref, 'master') }} - run: echo "::set-env name=DOC_VERSION::v$(python -c 'import metpy; print(metpy.__version__.rsplit(".", maxsplit=2)[0])')" + run: echo "DOC_VERSION=v$(python -c 'import metpy; print(metpy.__version__.rsplit(".", maxsplit=2)[0])')" >> $GITHUB_ENV - name: Upload to GitHub Pages if: ${{ github.event_name != 'pull_request' && matrix.experimental == false }} diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index aea49d47d98..a69ae81dfbc 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -25,7 +25,7 @@ jobs: curl -sfL \ https://github.com/reviewdog/reviewdog/raw/master/install.sh | \ sh -s -- -b $HOME/bin - echo ::add-path::$HOME/bin + echo "$HOME/bin" >> $GITHUB_PATH - name: Run flake8 env: diff --git a/.github/workflows/tests-conda.yml b/.github/workflows/tests-conda.yml index 3d55e1638c2..dc125e5db94 100644 --- a/.github/workflows/tests-conda.yml +++ b/.github/workflows/tests-conda.yml @@ -108,6 +108,7 @@ jobs: path: test_output/ - name: Upload coverage + if: ${{ always() }} uses: codecov/codecov-action@v1 with: name: conda-${{ matrix.python-version }}-${{ runner.os }} diff --git a/.github/workflows/tests-pypi.yml b/.github/workflows/tests-pypi.yml index 567a420e56c..b07b5907395 100644 --- a/.github/workflows/tests-pypi.yml +++ b/.github/workflows/tests-pypi.yml @@ -126,6 +126,7 @@ jobs: path: test_output/ - name: Upload coverage + if: ${{ always() }} uses: codecov/codecov-action@v1 with: name: pypi-${{ matrix.python-version }}-${{ matrix.dep-versions }}-${{ matrix.no-extras }}-${{ runner.os }} diff --git a/.travis.yml b/.travis.yml index 09842197af3..66127843027 100644 --- a/.travis.yml +++ b/.travis.yml @@ -88,7 +88,7 @@ script: fi after_script: - - if [[ $TASK != "coverage" ]]; then + - if [[ $TASK == "coverage" ]]; then pip install codecov codacy-coverage; coverage xml; codecov -X gcov -f coverage.xml -e TRAVIS_PYTHON_VERSION; diff --git a/ci/Current.txt b/ci/Current.txt index 01f4829a9f5..46a88ad682a 100644 --- a/ci/Current.txt +++ b/ci/Current.txt @@ -1,10 +1,11 @@ +importlib_metadata==2.0.0 +importlib_resources==3.0.0 matplotlib==3.3.2 numpy==1.19.1 -scipy==1.5.2 +pandas==1.1.3 +pooch==1.2.0 pint==0.16.1 -xarray==0.16.1 +pyproj==2.6.1.post1 +scipy==1.5.2 traitlets==4.3.3 -pooch==1.2.0 -pandas==1.1.3 -importlib_metadata==2.0.0 -importlib_resources==3.0.0 +xarray==0.16.1 diff --git a/ci/Minimum b/ci/Minimum index 44178b76dfc..b9597a41476 100644 --- a/ci/Minimum +++ b/ci/Minimum @@ -1,10 +1,11 @@ +importlib_metadata==1.0.0 +importlib_resources==1.3.0 matplotlib==2.1.0 numpy==1.16.0 -scipy==1.0.0 +pandas==0.22.0 pint==0.10.1 -xarray==0.14.1 -traitlets==4.3.0 pooch==0.1 -pandas==0.22.0 -importlib_metadata==1.0.0 -importlib_resources==1.3.0 +pyproj==2.3.0 +scipy==1.0.0 +traitlets==4.3.0 +xarray==0.14.1 diff --git a/ci/Prerelease b/ci/Prerelease index ff280af5fe0..ce2178a214c 100644 --- a/ci/Prerelease +++ b/ci/Prerelease @@ -1,6 +1,7 @@ matplotlib>=0.0.dev0 numpy>=0.0.dev0 -scipy>=0.0.dev0 -traitlets>=0.0.dev0 pooch>=0.0.dev0 pandas>=0.0.dev0 +pyproj>=0.0.dev0 +scipy>=0.0.dev0 +traitlets>=0.0.dev0 diff --git a/ci/extra_requirements.txt b/ci/extra_requirements.txt index e2080645e89..e4e75c6d077 100644 --- a/ci/extra_requirements.txt +++ b/ci/extra_requirements.txt @@ -1,2 +1 @@ cartopy==0.18.0 -pyproj==2.6.1.post1 diff --git a/conftest.py b/conftest.py index 42d2d9e386f..204a1e61987 100644 --- a/conftest.py +++ b/conftest.py @@ -10,6 +10,7 @@ import numpy import pandas import pooch +import pyproj import pytest import scipy import traitlets @@ -25,10 +26,10 @@ def pytest_report_header(config, startdir): """Add dependency information to pytest output.""" return (f'Dep Versions: Matplotlib {matplotlib.__version__}, ' - f'NumPy {numpy.__version__}, SciPy {scipy.__version__}, ' - f'Xarray {xarray.__version__}, Pint {pint.__version__}, ' - f'Pandas {pandas.__version__}, Traitlets {traitlets.__version__}, ' - f'Pooch {pooch.version.full_version}') + f'NumPy {numpy.__version__}, Pandas {pandas.__version__}, ' + f'Pint {pint.__version__}, Pooch {pooch.version.full_version}\n' + f'\tPyProj {pyproj.__version__}, SciPy {scipy.__version__}, ' + f'Traitlets {traitlets.__version__}, Xarray {xarray.__version__}') @pytest.fixture(autouse=True) @@ -45,6 +46,7 @@ def ccrs(): Any testing function/fixture that needs access to ``cartopy.crs`` can simply add this to their parameter list. + """ return pytest.importorskip('cartopy.crs') @@ -55,6 +57,7 @@ def cfeature(): Any testing function/fixture that needs access to ``cartopy.feature`` can simply add this to their parameter list. + """ return pytest.importorskip('cartopy.feature') @@ -62,8 +65,6 @@ def cfeature(): @pytest.fixture() def test_da_lonlat(): """Return a DataArray with a lon/lat grid and no time coordinate for use in tests.""" - pytest.importorskip('cartopy') - data = numpy.linspace(300, 250, 3 * 4 * 4).reshape((3, 4, 4)) ds = xarray.Dataset( {'temperature': (['isobaric', 'lat', 'lon'], data)}, @@ -96,8 +97,6 @@ def test_da_lonlat(): @pytest.fixture() def test_da_xy(): """Return a DataArray with a x/y grid and a time coordinate for use in tests.""" - pytest.importorskip('cartopy') - data = numpy.linspace(300, 250, 3 * 3 * 4 * 4).reshape((3, 3, 4, 4)) ds = xarray.Dataset( {'temperature': (['time', 'isobaric', 'y', 'x'], data), diff --git a/docs/installguide.rst b/docs/installguide.rst index 601d3bc5e37..e8462869ba6 100644 --- a/docs/installguide.rst +++ b/docs/installguide.rst @@ -10,12 +10,13 @@ years. For Python itself, that means supporting the last two minor releases. * matplotlib >= 2.1.0 * numpy >= 1.16.0 -* scipy >= 1.0.0 -* pint >= 0.10.1 * pandas >= 0.22.0 -* xarray >= 0.14.1 -* traitlets >= 4.3.0 +* pint >= 0.10.1 * pooch >= 0.1 +* pyproj >= 2.3.0 +* scipy >= 1.0.0 +* traitlets >= 4.3.0 +* xarray >= 0.14.1 ------------ Installation diff --git a/setup.cfg b/setup.cfg index ecdec2cf20d..1a568d8c7a1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -39,16 +39,17 @@ include_package_data = True setup_requires = setuptools_scm python_requires = >=3.6 install_requires = + importlib_metadata>=1.0.0; python_version < '3.8' + importlib_resources>=1.3.0; python_version < '3.9' matplotlib>=2.1.0 numpy>=1.16.0 - scipy>=1.0 + pandas>=0.22.0 pint>=0.10.1 - xarray>=0.14.1 pooch>=0.1 + pyproj>=2.3.0,<3.0 + scipy>=1.0 traitlets>=4.3.0 - pandas>=0.22.0 - importlib_metadata>=1.0.0; python_version < '3.8' - importlib_resources>=1.3.0; python_version < '3.9' + xarray>=0.14.1 [options.packages.find] where = src diff --git a/src/metpy/calc/cross_sections.py b/src/metpy/calc/cross_sections.py index bbae1520762..590f263edf5 100644 --- a/src/metpy/calc/cross_sections.py +++ b/src/metpy/calc/cross_sections.py @@ -36,9 +36,7 @@ def distances_from_cross_section(cross): """ if check_axis(cross.metpy.x, 'longitude') and check_axis(cross.metpy.y, 'latitude'): # Use pyproj to obtain x and y distances - from pyproj import Geod - - g = Geod(cross.metpy.cartopy_crs.proj4_init) + g = cross.metpy.pyproj_crs.get_geod() lon = cross.metpy.x lat = cross.metpy.y @@ -83,10 +81,13 @@ def latitude_from_cross_section(cross): if check_axis(y, 'latitude'): return y else: - import cartopy.crs as ccrs - latitude = ccrs.Geodetic().transform_points(cross.metpy.cartopy_crs, - cross.metpy.x.values, - y.values)[..., 1] + from pyproj import Proj + latitude = Proj(cross.metpy.pyproj_crs)( + cross.metpy.x.values, + y.values, + inverse=True, + radians=False + )[1] latitude = xr.DataArray(latitude * units.degrees_north, coords=y.coords, dims=y.dims) return latitude diff --git a/src/metpy/calc/tools.py b/src/metpy/calc/tools.py index 049316746cb..15ed2069369 100644 --- a/src/metpy/calc/tools.py +++ b/src/metpy/calc/tools.py @@ -8,6 +8,7 @@ import numpy as np from numpy.core.numeric import normalize_axis_index import numpy.ma as ma +from pyproj import Geod from scipy.spatial import cKDTree import xarray as xr @@ -763,7 +764,7 @@ def take(indexer): @exporter.export @preprocess_and_wrap() -def lat_lon_grid_deltas(longitude, latitude, x_dim=-1, y_dim=-2, **kwargs): +def lat_lon_grid_deltas(longitude, latitude, x_dim=-1, y_dim=-2, geod=None): r"""Calculate the actual delta between grid points that are in latitude/longitude format. Parameters @@ -778,8 +779,9 @@ def lat_lon_grid_deltas(longitude, latitude, x_dim=-1, y_dim=-2, **kwargs): axis number for the x dimension, defaults to -1. y_dim : int axis number for the y dimesion, defaults to -2. - kwargs - Other keyword arguments to pass to :class:`~pyproj.Geod` + geod : `pyproj.Geod` or ``None`` + PyProj Geod to use for forward azimuth and distance calculations. If ``None``, use a + default spherical ellipsoid. Returns ------- @@ -797,8 +799,6 @@ def lat_lon_grid_deltas(longitude, latitude, x_dim=-1, y_dim=-2, **kwargs): array-like type). It will also "densify" your data if using Dask or lazy-loading. """ - from pyproj import Geod - # Inputs must be the same number of dimensions if latitude.ndim != longitude.ndim: raise ValueError('Latitude and longitude must have the same number of dimensions.') @@ -819,11 +819,10 @@ def lat_lon_grid_deltas(longitude, latitude, x_dim=-1, y_dim=-2, **kwargs): take_y = make_take(latitude.ndim, y_dim) take_x = make_take(latitude.ndim, x_dim) - geod_args = {'ellps': 'sphere'} - if kwargs: - geod_args = kwargs - - g = Geod(**geod_args) + if geod is None: + g = Geod(ellps='sphere') + else: + g = geod forward_az, _, dy = g.inv(longitude[take_y(slice(None, -1))], latitude[take_y(slice(None, -1))], @@ -842,7 +841,7 @@ def lat_lon_grid_deltas(longitude, latitude, x_dim=-1, y_dim=-2, **kwargs): @exporter.export @preprocess_and_wrap() -def azimuth_range_to_lat_lon(azimuths, ranges, center_lon, center_lat, **kwargs): +def azimuth_range_to_lat_lon(azimuths, ranges, center_lon, center_lat, geod=None): """Convert azimuth and range locations in a polar coordinate system to lat/lon coordinates. Pole refers to the origin of the coordinate system. @@ -858,8 +857,9 @@ def azimuth_range_to_lat_lon(azimuths, ranges, center_lon, center_lat, **kwargs) The latitude of the pole in decimal degrees center_lon : float The longitude of the pole in decimal degrees - kwargs - arbitrary keyword arguments to pass to pyproj.Geod (e.g. 'ellps') + geod : `pyproj.Geod` or ``None`` + PyProj Geod to use for forward azimuth and distance calculations. If ``None``, use a + default spherical ellipsoid. Returns ------- @@ -870,12 +870,10 @@ def azimuth_range_to_lat_lon(azimuths, ranges, center_lon, center_lat, **kwargs) Credit to Brian Blaylock for the original implementation. """ - from pyproj import Geod - - geod_args = {'ellps': 'sphere'} - if kwargs: - geod_args = kwargs - g = Geod(**geod_args) + if geod is None: + g = Geod(ellps='sphere') + else: + g = geod rng2d, az2d = np.meshgrid(ranges, azimuths) lats = np.full(az2d.shape, center_lat) diff --git a/src/metpy/interpolate/slices.py b/src/metpy/interpolate/slices.py index 053644fb2ce..ca204b67530 100644 --- a/src/metpy/interpolate/slices.py +++ b/src/metpy/interpolate/slices.py @@ -74,8 +74,8 @@ def geodesic(crs, start, end, steps): Parameters ---------- - crs: `cartopy.crs` - Cartopy Coordinate Reference System to use for the output + crs: `pyproj.CRS` + PyProj Coordinate Reference System to use for the output start: (2, ) array_like A latitude-longitude pair designating the start point of the geodesic (units are degrees north and degrees east). @@ -96,18 +96,19 @@ def geodesic(crs, start, end, steps): cross_section """ - import cartopy.crs as ccrs - from pyproj import Geod + from pyproj import Proj + + g = crs.get_geod() + p = Proj(crs) # Geod.npts only gives points *in between* the start and end, and we want to include # the endpoints. - g = Geod(crs.proj4_init) geodesic = np.concatenate([ np.array(start[::-1])[None], np.array(g.npts(start[1], start[0], end[1], end[0], steps - 2)), np.array(end[::-1])[None] ]).transpose() - points = crs.transform_points(ccrs.Geodetic(), *geodesic)[:, :2] + points = np.stack(p(geodesic[0], geodesic[1], inverse=False, radians=False), axis=-1) return points @@ -162,7 +163,7 @@ def cross_section(data, start, end, steps=100, interp_type='linear'): # Get the projection and coordinates try: - crs_data = data.metpy.cartopy_crs + crs_data = data.metpy.pyproj_crs x = data.metpy.x except AttributeError: raise ValueError('Data missing required coordinate information. Verify that ' diff --git a/src/metpy/plots/mapping.py b/src/metpy/plots/mapping.py index d8cb9e4162e..9249098d194 100644 --- a/src/metpy/plots/mapping.py +++ b/src/metpy/plots/mapping.py @@ -77,6 +77,12 @@ def to_cartopy(self): return proj_handler(self._attrs, globe) + def to_pyproj(self): + """Convert to a PyProj CRS.""" + import pyproj + + return pyproj.CRS.from_cf(self._attrs) + def to_dict(self): """Get the dictionary of metadata attributes.""" return self._attrs.copy() diff --git a/src/metpy/testing.py b/src/metpy/testing.py index 103dc28febb..d1556e35411 100644 --- a/src/metpy/testing.py +++ b/src/metpy/testing.py @@ -34,19 +34,6 @@ def wrapped(*args, **kwargs): return wrapped -def needs_pyproj(test_func): - """Decorate a test function or fixture as requiring PyProj. - - Will skip the decorated test, or any test using the decorated fixture, if ``pyproj`` is - unable to be imported. - """ - @functools.wraps(test_func) - def wrapped(*args, **kwargs): - pytest.importorskip('pyproj') - return test_func(*args, **kwargs) - return wrapped - - def get_upper_air_data(date, station): """Get upper air observations from the test data cache. diff --git a/src/metpy/xarray.py b/src/metpy/xarray.py index 1d2cc5645a2..960ba3c5ea3 100644 --- a/src/metpy/xarray.py +++ b/src/metpy/xarray.py @@ -22,6 +22,7 @@ import warnings import numpy as np +from pyproj import Proj import xarray as xr from ._vendor.xarray import either_dict_or_kwargs, expanded_indexer, is_dict_like @@ -213,8 +214,8 @@ def dequantify(self): @property def crs(self): """Return the coordinate reference system (CRS) as a CFProjection object.""" - if 'crs' in self._data_array.coords: - return self._data_array.coords['crs'].item() + if 'metpy_crs' in self._data_array.coords: + return self._data_array.coords['metpy_crs'].item() raise AttributeError('crs attribute is not available.') @property @@ -232,6 +233,11 @@ def cartopy_geodetic(self): """Return the Geodetic CRS associated with the native CRS globe.""" return self.crs.cartopy_geodetic + @property + def pyproj_crs(self): + """Return the coordinate reference system (CRS) as a pyproj object.""" + return self.crs.to_pyproj() + def _fixup_coordinate_map(self, coord_map): """Ensure sure we have coordinate variables in map, not coordinate names.""" new_coord_map = {} @@ -571,7 +577,7 @@ def assign_latitude_longitude(self, force=False): Notes ----- - A valid CRS coordinate must be present. Cartopy is used for the coordinate + A valid CRS coordinate must be present. PyProj is used for the coordinate transformations. """ @@ -607,7 +613,7 @@ def assign_y_x(self, force=False, tolerance=None): Notes ----- - A valid CRS coordinate must be present. Cartopy is used for the coordinate + A valid CRS coordinate must be present. PyProj is used for the coordinate transformations. """ @@ -634,7 +640,7 @@ class MetPyDatasetAccessor: >>> import xarray as xr >>> from metpy.cbook import get_test_data >>> ds = xr.open_dataset(get_test_data('narr_example.nc', False)).metpy.parse_cf() - >>> print(ds['crs'].item()) + >>> print(ds['metpy_crs'].item()) Projection: lambert_conformal_conic """ @@ -676,6 +682,19 @@ def parse_cf(self, varname=None, coordinates=None): var = self._dataset[varname] + # Check for crs conflict + if varname == 'metpy_crs': + warnings.warn( + 'Attempting to parse metpy_crs as a data variable. Unexpected merge conflicts ' + 'may occur.' + ) + elif 'metpy_crs' in var.coords and (var.coords['metpy_crs'].size > 1 or not isinstance( + var.coords['metpy_crs'].item(), CFProjection)): + warnings.warn( + 'metpy_crs already present as a non-CFProjection coordinate. Unexpected ' + 'merge conflicts may occur.' + ) + # Assign coordinates if the coordinates argument is given if coordinates is not None: var = var.metpy.assign_coordinates(coordinates) @@ -710,7 +729,7 @@ def _has_coord(coord_type): # Rebuild the coordinates of the dataarray, and return quantified DataArray var = self._rebuild_coords(var, crs) if crs is not None: - var = var.assign_coords(coords={'crs': crs}) + var = var.assign_coords(coords={'metpy_crs': crs}) return var def _rebuild_coords(self, var, crs): @@ -796,7 +815,7 @@ def assign_latitude_longitude(self, force=False): Notes ----- - A valid CRS coordinate must be present. Cartopy is used for the coordinate + A valid CRS coordinate must be present. PyProj is used for the coordinate transformations. """ @@ -841,7 +860,7 @@ def assign_y_x(self, force=False, tolerance=None): Notes ----- - A valid CRS coordinate must be present. Cartopy is used for the coordinate + A valid CRS coordinate must be present. PyProj is used for the coordinate transformations. """ @@ -995,14 +1014,14 @@ def _assign_crs(xarray_object, cf_attributes, cf_kwargs): attrs = cf_attributes if cf_attributes is not None else cf_kwargs # Assign crs coordinate to xarray object - return xarray_object.assign_coords(crs=CFProjection(attrs)) + return xarray_object.assign_coords(metpy_crs=CFProjection(attrs)) def _build_latitude_longitude(da): """Build latitude/longitude coordinates from DataArray's y/x coordinates.""" y, x = da.metpy.coordinates('y', 'x') xx, yy = np.meshgrid(x.values, y.values) - lonlats = da.metpy.cartopy_geodetic.transform_points(da.metpy.cartopy_crs, xx, yy) + lonlats = np.stack(Proj(da.metpy.pyproj_crs)(xx, yy, inverse=True, radians=False), axis=-1) longitude = xr.DataArray(lonlats[..., 0], dims=(y.name, x.name), coords={y.name: y, x.name: x}, attrs={'units': 'degrees_east', 'standard_name': 'longitude'}) @@ -1023,9 +1042,12 @@ def _build_y_x(da, tolerance): 'must be 2D') # Convert to projected y/x - xxyy = da.metpy.cartopy_crs.transform_points(da.metpy.cartopy_geodetic, - longitude.values, - latitude.values) + xxyy = np.stack(Proj(da.metpy.pyproj_crs)( + longitude.values, + latitude.values, + inverse=False, + radians=False + ), axis=-1) # Handle tolerance tolerance = 1 if tolerance is None else tolerance.m_as('m') @@ -1052,7 +1074,7 @@ def _build_y_x(da, tolerance): else: raise ValueError('Projected y and x coordinates cannot be collapsed to 1D within ' 'tolerance. Verify that your latitude and longitude coordinates ' - 'correpsond to your CRS coordinate.') + 'correspond to your CRS coordinate.') def preprocess_and_wrap(broadcast=None, wrap_like=None, match_unit=False, to_magnitude=False): @@ -1293,7 +1315,7 @@ def grid_deltas_from_dataarray(f, kind='default'): (dx_var, dx_units), (dy_var, dy_units) = ( (xr.Variable(dims=latitude.dims, data=deltas.magnitude), deltas.units) for deltas in lat_lon_grid_deltas(longitude, latitude, x_dim=x_dim, y_dim=y_dim, - initstring=f.metpy.cartopy_crs.proj4_init)) + geod=f.metpy.pyproj_crs.get_geod())) else: # Obtain y/x coordinate differences y, x = f.metpy.coordinates('y', 'x') diff --git a/tests/calc/test_calc_tools.py b/tests/calc/test_calc_tools.py index 299ae865bcd..a3c9be72880 100644 --- a/tests/calc/test_calc_tools.py +++ b/tests/calc/test_calc_tools.py @@ -8,6 +8,7 @@ import numpy as np import numpy.ma as ma import pandas as pd +from pyproj import Geod import pytest import xarray as xr @@ -20,8 +21,7 @@ _greater_or_close, _less_or_close, _next_non_masked_element, _remove_nans, azimuth_range_to_lat_lon, BASE_DEGREE_MULTIPLIER, DIR_STRS, UND) -from metpy.testing import (assert_almost_equal, assert_array_almost_equal, assert_array_equal, - needs_pyproj) +from metpy.testing import (assert_almost_equal, assert_array_almost_equal, assert_array_equal) from metpy.units import units from metpy.xarray import grid_deltas_from_dataarray @@ -422,7 +422,6 @@ def test_get_layer_heights_agl_bottom_no_interp(): assert_array_almost_equal(data_true, data, 6) -@needs_pyproj def test_lat_lon_grid_deltas_1d(): """Test for lat_lon_grid_deltas for variable grid.""" lat = np.arange(40, 50, 2.5) @@ -440,7 +439,6 @@ def test_lat_lon_grid_deltas_1d(): @pytest.mark.parametrize('flip_order', [(False, True)]) -@needs_pyproj def test_lat_lon_grid_deltas_2d(flip_order): """Test for lat_lon_grid_deltas for variable grid with negative delta distances.""" lat = np.arange(40, 50, 2.5) @@ -464,7 +462,6 @@ def test_lat_lon_grid_deltas_2d(flip_order): assert_almost_equal(dy, dy_truth, 4) -@needs_pyproj def test_lat_lon_grid_deltas_extra_dimensions(): """Test for lat_lon_grid_deltas with extra leading dimensions.""" lon, lat = np.meshgrid(np.arange(-100, -90, 2.5), np.arange(40, 50, 2.5)) @@ -483,7 +480,6 @@ def test_lat_lon_grid_deltas_extra_dimensions(): assert_almost_equal(dy, dy_truth, 4) -@needs_pyproj def test_lat_lon_grid_deltas_mismatched_shape(): """Test for lat_lon_grid_deltas for variable grid.""" lat = np.arange(40, 50, 2.5) @@ -495,12 +491,11 @@ def test_lat_lon_grid_deltas_mismatched_shape(): lat_lon_grid_deltas(lon, lat) -@needs_pyproj def test_lat_lon_grid_deltas_geod_kwargs(): """Test that geod kwargs are overridden by users #774.""" lat = np.arange(40, 50, 2.5) lon = np.arange(-100, -90, 2.5) - dx, dy = lat_lon_grid_deltas(lon, lat, a=4370997) + dx, dy = lat_lon_grid_deltas(lon, lat, geod=Geod(a=4370997)) dx_truth = np.array([[146095.76101984, 146095.76101984, 146095.76101984], [140608.9751528, 140608.9751528, 140608.9751528], [134854.56713287, 134854.56713287, 134854.56713287], @@ -875,9 +870,8 @@ def test_angle_to_direction_level_1(): assert_array_equal(output_dirs, expected_dirs) -@needs_pyproj def test_azimuth_range_to_lat_lon(): - """Test converstion of azimuth and range to lat/lon grid.""" + """Test conversion of azimuth and range to lat/lon grid.""" az = [332.2403, 334.6765, 337.2528, 339.73846, 342.26257] rng = [2125., 64625., 127125., 189625., 252125., 314625.] clon = -89.98416666666667 @@ -907,15 +901,13 @@ def test_azimuth_range_to_lat_lon(): assert_array_almost_equal(output_lat, true_lat, 6) -@needs_pyproj def test_azimuth_range_to_lat_lon_diff_ellps(): - """Test converstion of azimuth and range to lat/lon grid.""" + """Test conversion of azimuth and range to lat/lon grid.""" az = [332.2403, 334.6765, 337.2528, 339.73846, 342.26257] rng = [2125., 64625., 127125., 189625., 252125., 314625.] clon = -89.98416666666667 clat = 32.27972222222222 - kwargs = {'ellps': 'WGS84'} - output_lon, output_lat = azimuth_range_to_lat_lon(az, rng, clon, clat, **kwargs) + output_lon, output_lat = azimuth_range_to_lat_lon(az, rng, clon, clat, Geod(ellps='WGS84')) true_lon = [[-89.9946749, -90.3055083, -90.6198256, -90.9377279, -91.2593193, -91.5847066], [-89.9938168, -90.279303, -90.5680603, -90.860187, -91.1557841, @@ -997,7 +989,7 @@ def test_first_derivative_xarray_lonlat(test_da_lonlat): coords=(('lat', test_da_lonlat['lat']),) ) _, truth = xr.broadcast(test_da_lonlat, partial) - truth.coords['crs'] = test_da_lonlat['crs'] + truth.coords['metpy_crs'] = test_da_lonlat['metpy_crs'] truth.attrs['units'] = 'kelvin / meter' truth = truth.metpy.quantify() @@ -1051,7 +1043,7 @@ def test_second_derivative_xarray_lonlat(test_da_lonlat): coords=(('lat', test_da_lonlat['lat']),) ) _, truth = xr.broadcast(test_da_lonlat, partial) - truth.coords['crs'] = test_da_lonlat['crs'] + truth.coords['metpy_crs'] = test_da_lonlat['metpy_crs'] truth.attrs['units'] = 'kelvin / meter^2' truth = truth.metpy.quantify() @@ -1079,7 +1071,7 @@ def test_gradient_xarray(test_da_xy): coords=(('isobaric', test_da_xy['isobaric']),) ) _, truth_p = xr.broadcast(test_da_xy, partial) - truth_p.coords['crs'] = test_da_xy['crs'] + truth_p.coords['metpy_crs'] = test_da_xy['metpy_crs'] truth_p.attrs['units'] = 'kelvin / hectopascal' truth_p = truth_p.metpy.quantify() @@ -1163,7 +1155,7 @@ def test_laplacian_xarray_lonlat(test_da_lonlat): coords=(('lat', test_da_lonlat['lat']),) ) _, truth = xr.broadcast(test_da_lonlat, partial) - truth.coords['crs'] = test_da_lonlat['crs'] + truth.coords['metpy_crs'] = test_da_lonlat['metpy_crs'] truth.attrs['units'] = 'kelvin / meter^2' truth = truth.metpy.quantify() diff --git a/tests/calc/test_cross_sections.py b/tests/calc/test_cross_sections.py index 259a25d59d3..c2b09f477d9 100644 --- a/tests/calc/test_cross_sections.py +++ b/tests/calc/test_cross_sections.py @@ -119,7 +119,7 @@ def test_distances_from_cross_section_given_lonlat(test_cross_lonlat): true_x = xr.DataArray( true_x_values * units.meters, coords={ - 'crs': test_cross_lonlat['crs'], + 'metpy_crs': test_cross_lonlat['metpy_crs'], 'lat': test_cross_lonlat['lat'], 'lon': test_cross_lonlat['lon'], 'index': index, @@ -129,7 +129,7 @@ def test_distances_from_cross_section_given_lonlat(test_cross_lonlat): true_y = xr.DataArray( true_y_values * units.meters, coords={ - 'crs': test_cross_lonlat['crs'], + 'metpy_crs': test_cross_lonlat['metpy_crs'], 'lat': test_cross_lonlat['lat'], 'lon': test_cross_lonlat['lon'], 'index': index, @@ -168,7 +168,7 @@ def test_latitude_from_cross_section_given_y(test_cross_xy): true_latitude = xr.DataArray( true_latitude_values * units.degrees_north, coords={ - 'crs': test_cross_xy['crs'], + 'metpy_crs': test_cross_xy['metpy_crs'], 'y': test_cross_xy['y'], 'x': test_cross_xy['x'], 'index': index, diff --git a/tests/calc/test_kinematics.py b/tests/calc/test_kinematics.py index 7ec51385da4..d3678ab4c76 100644 --- a/tests/calc/test_kinematics.py +++ b/tests/calc/test_kinematics.py @@ -16,7 +16,7 @@ total_deformation, vorticity, wind_components) from metpy.constants import g, Re from metpy.testing import (assert_almost_equal, assert_array_almost_equal, assert_array_equal, - get_test_data, needs_cartopy, needs_pyproj) + get_test_data) from metpy.units import concatenate, units @@ -466,7 +466,6 @@ def test_absolute_vorticity_asym(): @pytest.fixture -@needs_pyproj def pv_data(): """Test data for all PV testing.""" u = np.array([[[100, 90, 80, 70], @@ -582,7 +581,6 @@ def test_potential_vorticity_baroclinic_wrong_number_of_levels_axis_0(pv_data): pressure[:1, :, :]) -@needs_pyproj def test_potential_vorticity_baroclinic_isentropic_real_data(): """Test potential vorticity calculation with real isentropic data.""" isentlevs = [328, 330, 332] * units.K @@ -677,7 +675,6 @@ def test_potential_vorticity_baroclinic_isentropic_real_data(): assert_almost_equal(pvor, true_pv, 14) -@needs_pyproj def test_potential_vorticity_baroclinic_isobaric_real_data(): """Test potential vorticity calculation with real isentropic data.""" pres = [20000., 25000., 30000.] * units.Pa @@ -786,7 +783,6 @@ def test_potential_vorticity_barotropic(pv_data): assert_almost_equal(pv, truth, 10) -@needs_pyproj def test_inertial_advective_wind_diffluent(): """Test inertial advective wind with a diffluent flow.""" lats = np.array([[50., 50., 50., 50., 50., 50., 50., 50., 50., 50., 50.], @@ -978,7 +974,6 @@ def test_inertial_advective_wind_diffluent(): @pytest.fixture -@needs_pyproj def q_vector_data(): """Define data for use in Q-vector tests.""" speed = np.ones((4, 4)) * 50. * units('knots') @@ -1057,7 +1052,6 @@ def test_q_vector_with_static_stability(q_vector_data): @pytest.fixture -@needs_cartopy def data_4d(): """Define 4D data (extracted from Irma GFS example) for testing kinematics functions.""" data = xr.open_dataset(get_test_data('irma_gfs_example.nc', False)) @@ -1084,215 +1078,215 @@ def data_4d(): def test_vorticity_4d(data_4d): """Test vorticity on a 4D (time, pressure, y, x) grid.""" vort = vorticity(data_4d.u, data_4d.v) - truth = np.array([[[[-5.83650490e-05, 3.17327814e-05, 4.57268332e-05, 2.00732350e-05], - [2.14368312e-05, 1.95623237e-05, 4.15790182e-05, 6.90274641e-05], - [6.18610861e-05, 6.93600880e-05, 8.36201998e-05, 8.25922654e-05], - [-4.44038452e-05, 1.56487106e-04, 1.42605312e-04, -6.03981765e-05]], - [[-8.26772499e-07, 4.24638141e-05, -1.02560273e-05, 1.40379447e-05], - [1.16882545e-05, 1.06463071e-05, 2.84971990e-05, 6.22850560e-05], - [1.83850591e-05, 7.36387780e-06, 3.76622760e-05, 4.67188878e-05], - [3.19856719e-05, 2.80735317e-05, 3.73822586e-05, 5.40379931e-05]], - [[-2.84629423e-05, 3.82238141e-06, 3.96173636e-06, 5.13752737e-05], - [-2.18549443e-05, 5.28657636e-06, 2.00254459e-05, 3.38246076e-05], - [-1.97810827e-05, -2.51363102e-06, 2.87033130e-05, 3.01975044e-05], - [-2.34149501e-05, -1.82846160e-05, 2.95791089e-05, 3.41817364e-05]]], - [[[-3.66403309e-05, 2.45056689e-05, 8.30552352e-05, 2.42918324e-05], - [3.30814959e-05, 2.30523398e-05, 4.66571426e-05, 7.60789420e-05], - [7.65406561e-05, 4.98489001e-05, 6.61967180e-05, 9.90553670e-05], - [-3.83060455e-06, 8.82014475e-05, 1.11633279e-04, -4.43270102e-05]], - [[-2.47146999e-06, 3.95768075e-05, 3.76682359e-05, 3.79239346e-05], - [-4.60129429e-06, 2.05601660e-05, 2.89144970e-05, 3.01301961e-05], - [1.54778233e-05, 8.05069277e-06, 2.44051429e-05, 7.01730409e-05], - [2.07682219e-05, 2.16790897e-05, 3.38209456e-05, 9.11823021e-05]], - [[-7.12798691e-06, -2.81765143e-06, 1.93675069e-05, 6.21220857e-05], - [-1.80822794e-05, 7.10872010e-06, 1.40635809e-05, 1.80843580e-05], - [-3.01135264e-06, 2.56664766e-06, 2.25038301e-05, 3.69789825e-05], - [-1.48940627e-05, -6.28397440e-06, 3.66706625e-05, 1.13280233e-05]]], - [[[-2.13814161e-05, 3.10846718e-05, 9.42880991e-05, 6.20302960e-05], - [2.83685685e-05, 2.71376067e-05, 4.44470499e-05, 7.94154059e-05], - [7.29341555e-05, 3.07015029e-05, 3.70538789e-05, 7.75632608e-05], - [6.86595116e-05, 2.25094524e-05, 7.15703850e-05, 6.90873953e-05]], - [[-5.70566101e-07, 5.63627148e-05, 2.91960395e-05, 3.62726492e-05], - [-6.17247194e-06, 2.63672993e-05, 3.27525843e-05, 2.87151996e-05], - [8.82121811e-06, 6.46657237e-06, 2.03146030e-05, 4.99274322e-05], - [1.54560972e-05, 1.39161983e-06, -6.92832423e-06, 6.02698395e-05]], - [[3.01573325e-06, 2.95361596e-05, 3.30386503e-05, 4.50206712e-05], - [-3.44201203e-06, 7.98411843e-06, 1.31230998e-05, 1.82704434e-05], - [-5.97302093e-06, -6.76058488e-07, 5.89633276e-06, 1.82494546e-05], - [-2.96985363e-06, 3.86098537e-06, 5.24525482e-06, - 2.72933874e-05]]]]) * units('s^-1') + truth = np.array([[[[-5.84515167e-05, 3.17729585e-05, 4.58261458e-05, 2.01292844e-05], + [2.13352387e-05, 1.96004423e-05, 4.16486823e-05, 6.90445310e-05], + [6.19222139e-05, 6.93601354e-05, 8.36426564e-05, 8.27371956e-05], + [-4.43297956e-05, 1.56381845e-04, 1.42510285e-04, -6.03146997e-05]], + [[-8.68712685e-07, 4.24890902e-05, -1.01652245e-05, 1.40567079e-05], + [1.16955768e-05, 1.06772721e-05, 2.85536762e-05, 6.24020996e-05], + [1.83821861e-05, 7.39881835e-06, 3.76797354e-05, 4.67243318e-05], + [3.19572986e-05, 2.81106117e-05, 3.73957581e-05, 5.39673545e-05]], + [[-2.85395302e-05, 3.84435833e-06, 4.04684576e-06, 5.14302137e-05], + [-2.19027713e-05, 5.30196965e-06, 2.00825604e-05, 3.39049359e-05], + [-1.97989026e-05, -2.49143814e-06, 2.87381603e-05, 3.02743602e-05], + [-2.34066064e-05, -1.82455025e-05, 2.95918539e-05, 3.42233420e-05]]], + [[[-3.66558283e-05, 2.45520394e-05, 8.31163955e-05, 2.44003406e-05], + [3.30393774e-05, 2.30884339e-05, 4.67122293e-05, 7.61002310e-05], + [7.66048678e-05, 4.98785325e-05, 6.62382288e-05, 9.91998869e-05], + [-3.81435328e-06, 8.81953022e-05, 1.11601055e-04, -4.42546076e-05]], + [[-2.51779702e-06, 3.95852220e-05, 3.77219249e-05, 3.79808820e-05], + [-4.63231122e-06, 2.05995207e-05, 2.89780728e-05, 3.01707041e-05], + [1.54931892e-05, 8.07405448e-06, 2.44489167e-05, 7.02383317e-05], + [2.07687143e-05, 2.17030773e-05, 3.38485776e-05, 9.11533757e-05]], + [[-7.17079917e-06, -2.80615398e-06, 1.94218575e-05, 6.22111037e-05], + [-1.81300845e-05, 7.12699895e-06, 1.41049190e-05, 1.80915929e-05], + [-2.99278303e-06, 2.57606747e-06, 2.25304657e-05, 3.70860448e-05], + [-1.48782578e-05, -6.27503290e-06, 3.66662188e-05, 1.14265141e-05]]], + [[[-2.14099419e-05, 3.11255562e-05, 9.43465637e-05, 6.21369629e-05], + [2.83576779e-05, 2.71698609e-05, 4.45208755e-05, 7.95114352e-05], + [7.29890624e-05, 3.07600211e-05, 3.71063624e-05, 7.76394608e-05], + [6.87038548e-05, 2.25751156e-05, 7.15889230e-05, 6.91611419e-05]], + [[-5.87372735e-07, 5.63433054e-05, 2.92457668e-05, 3.63765486e-05], + [-6.20728063e-06, 2.63907904e-05, 3.27952358e-05, 2.87436180e-05], + [8.81938816e-06, 6.49991429e-06, 2.03676451e-05, 4.99729397e-05], + [1.54604020e-05, 1.42654642e-06, -6.85425498e-06, 6.03129247e-05]], + [[2.98152979e-06, 2.95129295e-05, 3.30665600e-05, 4.51175504e-05], + [-3.45169373e-06, 7.99863229e-06, 1.31503178e-05, 1.82983904e-05], + [-5.96640905e-06, -6.58389207e-07, 5.92924140e-06, 1.82929244e-05], + [-2.94758645e-06, 3.86196289e-06, 5.27851664e-06, + 2.73814460e-05]]]]) * units('s^-1') assert_array_almost_equal(vort.data, truth, 12) def test_divergence_4d(data_4d): """Test divergence on a 4D (time, pressure, y, x) grid.""" div = divergence(data_4d.u, data_4d.v) - truth = np.array([[[[-8.43705083e-06, -5.42243991e-06, 1.42553766e-05, 2.81311077e-05], - [2.95334911e-05, -8.91904163e-06, 1.18532270e-05, -6.26196756e-06], - [-4.63583096e-05, -2.10525265e-05, 1.32571075e-05, 4.76118929e-05], - [-3.36862002e-05, 1.49431136e-05, -4.23301144e-05, 3.93742169e-05]], - [[1.69160375e-05, 1.54447811e-06, 4.11350021e-05, -5.08238612e-05], - [2.27239404e-05, -3.97652811e-06, 5.32329400e-06, 1.75756955e-05], - [-6.16991733e-06, -1.77132521e-06, -1.46585782e-05, 2.66081211e-06], - [-3.06896618e-05, -8.23671871e-06, -2.56998533e-05, -2.79187158e-05]], - [[-1.47210200e-05, -2.26015888e-05, -2.10309987e-05, -3.88000930e-05], - [2.87880179e-06, -9.97852896e-06, -1.02741993e-06, 4.53302920e-06], - [1.48614763e-05, 3.64899207e-06, 5.07255670e-06, 5.85619901e-06], - [1.12477665e-05, 1.61231699e-05, 1.13583495e-05, 3.92603086e-06]]], - [[[-3.95659837e-06, -8.16293111e-06, 6.64912076e-06, 4.82899740e-05], - [2.29285761e-05, -7.41730432e-07, 4.88714205e-06, -3.26931553e-05], - [-3.27492305e-05, -9.30212918e-06, 1.79834485e-06, 2.53811573e-05], - [-7.03628352e-05, 1.59599812e-05, -5.03928715e-05, 3.02766722e-05]], - [[1.67050619e-05, 1.24336555e-05, -2.22683301e-05, -1.89873955e-05], - [1.75618966e-05, -1.79165561e-06, 4.00327550e-06, -5.57201491e-06], - [4.02631582e-06, -5.29814574e-06, 3.59245019e-06, 4.16299189e-06], - [-3.62032526e-06, 4.00602251e-06, -2.17495860e-05, 2.93910418e-05]], - [[-6.50182516e-06, -3.06444044e-07, -4.68103153e-05, 6.54271734e-06], - [-9.22409986e-07, -6.80509227e-06, 1.57428914e-06, 2.13528516e-06], - [5.77636627e-06, -2.32628120e-06, 1.63766780e-05, 1.30647979e-05], - [-3.84054963e-06, 1.81368329e-05, -2.12456769e-08, 1.39177255e-05]]], - [[[-3.09706856e-06, -1.58174014e-05, 1.11042898e-05, 1.01863872e-05], - [2.22554541e-05, -2.18115261e-06, 2.95538179e-06, -1.27314237e-05], - [-2.01806928e-06, -1.44611342e-05, -1.60090851e-06, 1.51875027e-05], - [-7.45883555e-05, -2.17664690e-05, -6.59935118e-06, -9.51280586e-06]], - [[-2.84262294e-06, 1.83370481e-05, -1.60080375e-05, 5.94414530e-06], - [2.21275530e-05, 2.08417698e-06, -8.62049532e-06, -4.83025078e-06], - [6.84132907e-06, -1.74271778e-06, 4.96579520e-06, -8.14051216e-06], - [-5.91652815e-06, -1.27122109e-06, 1.33424166e-05, 2.89090443e-05]], - [[3.56617289e-06, -3.61628942e-06, -2.14971623e-05, 9.09440121e-06], - [1.15504071e-05, -2.35438670e-07, -1.00682327e-05, -7.83169489e-06], - [1.74820166e-06, -4.85659616e-07, 6.34687163e-06, -9.27089944e-06], - [9.23766788e-07, -2.85241737e-06, 1.68475020e-05, - -5.70982211e-06]]]]) * units('s^-1') + truth = np.array([[[[-8.37608702e-06, -5.39336397e-06, 1.42603335e-05, 2.81027853e-05], + [2.95370985e-05, -8.88467654e-06, 1.18747200e-05, -6.20723902e-06], + [-4.64906358e-05, -2.10620465e-05, 1.33445184e-05, 4.77361610e-05], + [-3.35504768e-05, 1.49909469e-05, -4.22891356e-05, 3.92159433e-05]], + [[1.69393752e-05, 1.56905500e-06, 4.11012845e-05, -5.08416562e-05], + [2.27792270e-05, -3.97105867e-06, 5.31878772e-06, 1.75998805e-05], + [-6.17322438e-06, -1.74803086e-06, -1.46149939e-05, 2.66339797e-06], + [-3.07336112e-05, -8.20592276e-06, -2.56044746e-05, -2.78477951e-05]], + [[-1.46864164e-05, -2.25693290e-05, -2.10250150e-05, -3.88307255e-05], + [2.90827814e-06, -9.96431223e-06, -1.02191776e-06, 4.55537027e-06], + [1.48872763e-05, 3.66494030e-06, 5.06711902e-06, 5.82930016e-06], + [1.12436632e-05, 1.61499510e-05, 1.13636149e-05, 3.85414061e-06]]], + [[[-3.88892057e-06, -8.14255274e-06, 6.65050488e-06, 4.82691326e-05], + [2.29332150e-05, -6.95362743e-07, 4.90498323e-06, -3.27034929e-05], + [-3.28375966e-05, -9.30193297e-06, 1.89455614e-06, 2.55048066e-05], + [-7.03452094e-05, 1.59780333e-05, -5.02908248e-05, 3.01991417e-05]], + [[1.67133745e-05, 1.24417427e-05, -2.22432790e-05, -1.89957283e-05], + [1.76022853e-05, -1.76730982e-06, 3.99751017e-06, -5.57126626e-06], + [4.04526025e-06, -5.27586187e-06, 3.61323452e-06, 4.18352106e-06], + [-3.61713767e-06, 4.02190371e-06, -2.16650827e-05, 2.94848150e-05]], + [[-6.47746172e-06, -2.98975077e-07, -4.67842312e-05, 6.49628794e-06], + [-9.24534558e-07, -6.79275746e-06, 1.57736990e-06, 2.15325190e-06], + [5.79213453e-06, -2.31793357e-06, 1.63764017e-05, 1.30886984e-05], + [-3.81688990e-06, 1.81508167e-05, -1.74511070e-08, 1.38462853e-05]]], + [[[-3.04155688e-06, -1.57905256e-05, 1.11057616e-05, 1.02005872e-05], + [2.22682490e-05, -2.13398663e-06, 2.98041246e-06, -1.27487570e-05], + [-2.03870559e-06, -1.44407167e-05, -1.54275894e-06, 1.52970546e-05], + [-7.46492084e-05, -2.17403382e-05, -6.50948158e-06, -9.39708598e-06]], + [[-2.87798173e-06, 1.83342079e-05, -1.59741420e-05, 5.93365940e-06], + [2.21780902e-05, 2.10396122e-06, -8.61898987e-06, -4.81985056e-06], + [6.86376938e-06, -1.71394859e-06, 4.97940406e-06, -8.12845764e-06], + [-5.91535752e-06, -1.25897243e-06, 1.33746621e-05, 2.89926447e-05]], + [[3.56301627e-06, -3.60303780e-06, -2.14805401e-05, 9.05879471e-06], + [1.15765605e-05, -2.20007656e-07, -1.00689171e-05, -7.85316340e-06], + [1.76295477e-06, -4.68035973e-07, 6.34634343e-06, -9.26903305e-06], + [9.56906212e-07, -2.83017535e-06, 1.68342294e-05, + -5.69798533e-06]]]]) * units('s^-1') assert_array_almost_equal(div.data, truth, 12) def test_shearing_deformation_4d(data_4d): """Test shearing_deformation on a 4D (time, pressure, y, x) grid.""" shdef = shearing_deformation(data_4d.u, data_4d.v) - truth = np.array([[[[-2.32353766e-05, 3.38638896e-06, 2.68355706e-05, 1.06560395e-05], - [-6.40834716e-05, 1.01157390e-05, 1.72783215e-05, -2.41362735e-05], - [6.69848680e-07, -1.89007571e-05, -1.40877214e-05, 3.71581119e-05], - [6.36114984e-05, -1.08233745e-04, -9.64601102e-05, 7.32813538e-05]], - [[-2.42214688e-05, -1.01851671e-05, 5.54461375e-05, -3.51796268e-07], - [-2.71001778e-06, 9.30533079e-06, 2.03843188e-05, 3.34828205e-05], - [-7.27917172e-06, 1.72622100e-05, -5.55179147e-06, -1.31598103e-05], - [-2.51927242e-05, 9.17056498e-06, -2.24631811e-06, -5.35695138e-05]], - [[-2.57651839e-05, 1.01219942e-05, 4.53600390e-05, 5.28799494e-07], - [-1.55543764e-05, 6.18561775e-06, 2.36187660e-05, 2.52821250e-05], - [-2.67211842e-06, 1.14466225e-05, 7.99438411e-06, 3.06434113e-05], - [1.17029675e-05, 2.71857215e-05, -1.93883537e-06, 1.03237850e-05]]], - [[[5.36878109e-06, 1.03810936e-05, -1.74133759e-05, 3.67019082e-05], - [-3.68224309e-05, 8.02234002e-06, 2.97256283e-06, -2.41548002e-05], - [-1.03217116e-07, -3.55295991e-07, 1.04215491e-06, 3.06178781e-05], - [1.78849776e-05, -3.14217684e-05, -5.31904971e-05, 6.33706906e-05]], - [[-2.54172738e-05, -1.89184694e-05, 7.52187239e-06, 7.78263224e-06], - [-1.58491234e-05, 8.86850501e-06, 1.94682285e-05, 6.28154949e-06], - [2.87101909e-06, 1.02981542e-05, 1.49483081e-05, 1.11896135e-05], - [-6.24536223e-06, 5.02422684e-06, 3.65739211e-06, -4.43343790e-05]], - [[-1.97278534e-05, 7.98223535e-06, 1.93668724e-05, 1.17314603e-05], - [-1.80800662e-05, 7.10682312e-06, 1.58638789e-05, -7.11095379e-06], - [1.04957568e-05, 3.46915772e-06, 7.19233197e-06, 4.14864918e-05], - [1.30201499e-05, 7.22093417e-06, -1.46521398e-05, 5.00427528e-05]]], - [[[-8.31494391e-06, 2.74335132e-06, -2.40497584e-05, 1.75042968e-05], - [-1.88915366e-05, 3.28864180e-06, 1.34127052e-05, 1.23621458e-05], - [4.61243898e-07, 1.85506704e-05, 1.67855055e-05, 9.59377214e-06], - [6.06292303e-06, 2.92575008e-05, -1.44159217e-05, 2.17975694e-05]], - [[-1.00168319e-05, -4.57753168e-05, 8.50542316e-06, 3.44821467e-05], - [-1.65225222e-05, -4.66989095e-06, 6.65190573e-06, 1.71105129e-06], - [-4.23400810e-06, 1.50208950e-05, 1.80731201e-05, 5.36054473e-06], - [-2.10443897e-06, 1.80502669e-05, 4.39381815e-05, 5.78573040e-06]], - [[-2.08335492e-05, -3.03108476e-05, -3.85875023e-06, 2.70252773e-05], - [-4.78804481e-06, 1.24351472e-06, 6.82854110e-06, 5.67152289e-06], - [5.73158894e-06, 1.05747791e-05, 1.53497021e-05, 1.55510561e-05], - [1.23394357e-05, -1.98706807e-06, 1.56020711e-05, - 3.89964205e-05]]]]) * units('s^-1') + truth = np.array([[[[-2.33792381e-05, 3.44534094e-06, 2.69410760e-05, 1.06867281e-05], + [-6.40972431e-05, 1.01579031e-05, 1.73678734e-05, -2.40319045e-05], + [7.70545354e-07, -1.87702202e-05, -1.39302341e-05, 3.73230852e-05], + [6.35849225e-05, -1.08009221e-04, -9.62510298e-05, 7.32297192e-05]], + [[-2.42502310e-05, -1.01193319e-05, 5.54828905e-05, -3.31928326e-07], + [-2.69305297e-06, 9.32833730e-06, 2.04600718e-05, 3.36248400e-05], + [-7.24755760e-06, 1.72909996e-05, -5.48615182e-06, -1.30784063e-05], + [-2.51475614e-05, 9.22553765e-06, -2.17297542e-06, -5.34977173e-05]], + [[-2.58416628e-05, 1.01393773e-05, 4.54141476e-05, 6.20366322e-07], + [-1.56077459e-05, 6.20125807e-06, 2.36797141e-05, 2.53616873e-05], + [-2.71240538e-06, 1.14475474e-05, 8.05450723e-06, 3.07240065e-05], + [1.16656764e-05, 2.71686080e-05, -1.88326452e-06, 1.03921795e-05]]], + [[[5.29600994e-06, 1.04331961e-05, -1.72892524e-05, 3.67655639e-05], + [-3.67904320e-05, 8.07030650e-06, 3.05173020e-06, -2.40356283e-05], + [3.03845109e-08, -2.56843275e-07, 1.17465234e-06, 3.08089412e-05], + [1.79034632e-05, -3.12752861e-05, -5.30138255e-05, 6.33453564e-05]], + [[-2.54496668e-05, -1.88685727e-05, 7.59573914e-06, 7.85469836e-06], + [-1.58734272e-05, 8.90875832e-06, 1.95355336e-05, 6.33953947e-06], + [2.90313838e-06, 1.03222777e-05, 1.50063775e-05, 1.13348820e-05], + [-6.20995986e-06, 5.06623932e-06, 3.72239179e-06, -4.41896630e-05]], + [[-1.97608457e-05, 7.98531569e-06, 1.94218554e-05, 1.18509048e-05], + [-1.81300845e-05, 7.12699895e-06, 1.59034980e-05, -7.08850441e-06], + [1.04965562e-05, 3.47535804e-06, 7.24254745e-06, 4.15824912e-05], + [1.29997134e-05, 7.21430847e-06, -1.45932750e-05, 5.00959463e-05]]], + [[[-8.37024044e-06, 2.79795154e-06, -2.39099649e-05, 1.76221280e-05], + [-1.88550094e-05, 3.33869412e-06, 1.34953970e-05, 1.25143854e-05], + [5.96277806e-07, 1.86196124e-05, 1.68723536e-05, 9.74312685e-06], + [6.20326426e-06, 2.93197852e-05, -1.42931965e-05, 2.19484546e-05]], + [[-1.00299098e-05, -4.57260229e-05, 8.56211376e-06, 3.45779631e-05], + [-1.65491061e-05, -4.63468810e-06, 6.71584791e-06, 1.76493950e-06], + [-4.22030685e-06, 1.50431608e-05, 1.81194219e-05, 5.45811766e-06], + [-2.07574370e-06, 1.80633930e-05, 4.39555860e-05, 5.90590854e-06]], + [[-2.08496392e-05, -3.02898043e-05, -3.80429538e-06, 2.71317584e-05], + [-4.80062637e-06, 1.25396267e-06, 6.85529455e-06, 5.70834171e-06], + [5.72435226e-06, 1.05827268e-05, 1.53717763e-05, 1.55950591e-05], + [1.23403264e-05, -1.98341401e-06, 1.56203357e-05, + 3.90722041e-05]]]]) * units('s^-1') assert_array_almost_equal(shdef.data, truth, 12) def test_stretching_deformation_4d(data_4d): """Test stretching_deformation on a 4D (time, pressure, y, x) grid.""" stdef = stretching_deformation(data_4d.u, data_4d.v) - truth = np.array([[[[3.47764258e-05, 2.24655678e-05, -5.99204286e-06, -2.81311151e-05], - [-1.00806414e-05, 2.43815624e-05, 5.10566770e-06, 3.02039392e-05], - [-5.93889988e-05, 4.15227142e-06, 3.93751112e-05, 5.52382202e-05], - [8.92010023e-05, 1.85531529e-05, 3.60056433e-05, -1.03321628e-04]], - [[2.96761128e-06, 1.36910447e-05, -4.34590663e-05, 1.80287489e-05], - [1.86757141e-05, 5.47290208e-06, -9.06422655e-06, 8.11203944e-06], - [1.34111946e-07, 1.26357749e-05, 2.72130530e-05, -3.62654235e-06], - [-1.35816208e-05, 1.87775033e-05, 5.84933984e-05, 5.04057146e-05]], - [[2.89236233e-05, 3.31889843e-05, 1.58664147e-05, 5.74675794e-06], - [1.68234432e-05, 1.52158343e-05, 5.26714302e-06, 1.21764691e-05], - [8.55744700e-06, 7.69832273e-06, -4.83112472e-06, -1.57549242e-05], - [-5.86025733e-06, 8.47198887e-06, -3.49088418e-07, -3.92962147e-05]]], - [[[3.69582950e-05, 1.86470363e-05, -2.80150634e-06, -3.51977497e-05], - [-6.46847071e-06, 2.69781373e-05, 6.95914436e-06, 5.98289917e-06], - [-4.00667252e-05, 5.05292624e-06, 4.75021137e-05, 6.24518714e-05], - [3.67260262e-05, 2.68548943e-06, 7.10293796e-05, -5.79403685e-05]], - [[-5.34297827e-06, -1.07157183e-06, 2.58835391e-05, 7.10885516e-06], - [1.26149579e-05, 1.35132438e-05, -2.75629799e-06, 4.32503739e-06], - [8.52816121e-06, 1.49554343e-05, 6.30626925e-06, 9.11577765e-06], - [2.68336326e-06, 5.36356177e-06, 5.47773716e-05, 4.06465999e-05]], - [[1.73474509e-05, 5.98748586e-06, 4.13875024e-05, -2.90086556e-05], - [4.23620645e-07, 1.02966295e-05, 5.15938898e-06, 7.09234799e-06], - [5.32951540e-06, 6.67206038e-06, -7.92655166e-06, 1.03541254e-05], - [1.46155702e-05, 1.33856872e-07, 4.47179844e-06, -4.46031161e-05]]], - [[[3.02111317e-05, 2.69212573e-05, -4.64855995e-06, 2.98329788e-06], - [-2.05441981e-06, 2.88664710e-05, 1.15095603e-05, -3.72867092e-06], - [-1.41578887e-05, 1.61511593e-05, 3.08142052e-05, 5.12063542e-05], - [-4.81886157e-06, 1.96583134e-05, 4.92309570e-05, 6.43248731e-05]], - [[-1.85904008e-05, -1.13648603e-05, 2.94359552e-05, -8.00997936e-06], - [1.62793512e-05, 8.39043368e-06, 7.12412372e-06, 7.32420819e-06], - [9.09319575e-06, 1.67115147e-05, 5.41579051e-06, 1.03134035e-05], - [2.63717343e-06, 5.48753335e-06, 1.28924212e-05, 3.38671775e-05]], - [[-4.08263202e-06, 1.03302483e-05, 2.30465372e-05, -2.51046121e-05], - [8.40123079e-06, 9.21367536e-06, 6.57669664e-06, -9.62598559e-06], - [6.70192818e-06, 9.41865112e-06, -1.75966046e-06, 4.68368828e-06], - [1.75811596e-05, 1.24562416e-05, -1.28654291e-05, - 7.34949445e-06]]]]) * units('s^-1') + truth = np.array([[[[3.47898088e-05, 2.24845986e-05, -5.97367530e-06, -2.81027927e-05], + [-1.00316265e-05, 2.43890252e-05, 5.13005043e-06, 3.02139765e-05], + [-5.95303373e-05, 4.11805509e-06, 3.94239079e-05, 5.53801191e-05], + [8.92024896e-05, 1.85881092e-05, 3.59490328e-05, -1.03321407e-04]], + [[3.00039817e-06, 1.37094723e-05, -4.34319088e-05, 1.79539749e-05], + [1.87324184e-05, 5.47148050e-06, -9.06983993e-06, 8.15734277e-06], + [1.21798873e-07, 1.26405968e-05, 2.72019585e-05, -3.63162743e-06], + [-1.36470926e-05, 1.87727600e-05, 5.84790724e-05, 5.03903728e-05]], + [[2.89291086e-05, 3.31866090e-05, 1.58458533e-05, 5.68409251e-06], + [1.68472637e-05, 1.52157851e-05, 5.27310978e-06, 1.21993291e-05], + [8.59225306e-06, 7.71174035e-06, -4.82506223e-06, -1.57536424e-05], + [-5.84283826e-06, 8.50599727e-06, -3.27143224e-07, -3.93117456e-05]]], + [[[3.69837694e-05, 1.86562509e-05, -2.79203000e-06, -3.51399535e-05], + [-6.42858314e-06, 2.70027422e-05, 6.97334875e-06, 5.92098244e-06], + [-4.01668004e-05, 5.04173347e-06, 4.75334876e-05, 6.25555261e-05], + [3.66252634e-05, 2.71352154e-06, 7.09783382e-05, -5.79312118e-05]], + [[-5.31921974e-06, -1.04758793e-06, 2.58686924e-05, 7.08365906e-06], + [1.26562011e-05, 1.35206063e-05, -2.74715944e-06, 4.32091552e-06], + [8.54170666e-06, 1.49581427e-05, 6.31110194e-06, 9.12961275e-06], + [2.67785986e-06, 5.37083849e-06, 5.47744998e-05, 4.07259321e-05]], + [[1.73537008e-05, 5.99605247e-06, 4.13461116e-05, -2.90256397e-05], + [4.24395934e-07, 1.02937398e-05, 5.17452359e-06, 7.09934306e-06], + [5.34248818e-06, 6.67495925e-06, -7.90440717e-06, 1.03908310e-05], + [1.46185421e-05, 1.65031056e-07, 4.47900388e-06, -4.46075180e-05]]], + [[[3.02321534e-05, 2.69257238e-05, -4.63180943e-06, 3.00627122e-06], + [-2.01256850e-06, 2.88914919e-05, 1.15236589e-05, -3.75586415e-06], + [-1.41791143e-05, 1.61351154e-05, 3.08316570e-05, 5.12686237e-05], + [-4.95427192e-06, 1.96269721e-05, 4.92464559e-05, 6.43446270e-05]], + [[-1.86155399e-05, -1.13423401e-05, 2.94399620e-05, -8.00532458e-06], + [1.63327091e-05, 8.39898448e-06, 7.11857042e-06, 7.32055442e-06], + [9.11199258e-06, 1.67214834e-05, 5.42904828e-06, 1.03069722e-05], + [2.62789752e-06, 5.48570575e-06, 1.29250179e-05, 3.39387353e-05]], + [[-4.08093319e-06, 1.03359478e-05, 2.30342884e-05, -2.51141968e-05], + [8.42904887e-06, 9.22253152e-06, 6.56793595e-06, -9.65174212e-06], + [6.70904325e-06, 9.42414527e-06, -1.74726096e-06, 4.66995059e-06], + [1.75937571e-05, 1.24577364e-05, -1.28423144e-05, + 7.34171029e-06]]]]) * units('s^-1') assert_array_almost_equal(stdef.data, truth, 12) def test_total_deformation_4d(data_4d): """Test total_deformation on a 4D (time, pressure, y, x) grid.""" totdef = total_deformation(data_4d.u, data_4d.v) - truth = np.array([[[[4.18244250e-05, 2.27193611e-05, 2.74964075e-05, 3.00817356e-05], - [6.48714934e-05, 2.63967566e-05, 1.80168876e-05, 3.86631303e-05], - [5.93927763e-05, 1.93514851e-05, 4.18194127e-05, 6.65731647e-05], - [1.09559306e-04, 1.09812399e-04, 1.02960960e-04, 1.26670895e-04]], - [[2.44025874e-05, 1.70640656e-05, 7.04483116e-05, 1.80321809e-05], - [1.88713140e-05, 1.07954545e-05, 2.23087574e-05, 3.44514797e-05], - [7.28040706e-06, 2.13926787e-05, 2.77735961e-05, 1.36503632e-05], - [2.86205132e-05, 2.08972221e-05, 5.85365151e-05, 7.35556175e-05]], - [[3.87352641e-05, 3.46981764e-05, 4.80549296e-05, 5.77103594e-06], - [2.29121554e-05, 1.64250869e-05, 2.41989442e-05, 2.80615795e-05], - [8.96493815e-06, 1.37945402e-05, 9.34076781e-06, 3.44562954e-05], - [1.30882414e-05, 2.84752182e-05, 1.97001150e-06, 4.06297062e-05]]], - [[[3.73462098e-05, 2.13419556e-05, 1.76372928e-05, 5.08518598e-05], - [3.73862612e-05, 2.81456539e-05, 7.56741832e-06, 2.48847233e-05], - [4.00668582e-05, 5.06540214e-06, 4.75135443e-05, 6.95535096e-05], - [4.08493993e-05, 3.15363185e-05, 8.87378259e-05, 8.58657716e-05]], - [[2.59727785e-05, 1.89487929e-05, 2.69543347e-05, 1.05406445e-05], - [2.02566502e-05, 1.61634816e-05, 1.96623777e-05, 7.62652034e-06], - [8.99846010e-06, 1.81581110e-05, 1.62240854e-05, 1.44327701e-05], - [6.79742509e-06, 7.34919385e-06, 5.48993347e-05, 6.01471798e-05]], - [[2.62701780e-05, 9.97827981e-06, 4.56946507e-05, 3.12910413e-05], - [1.80850283e-05, 1.25110957e-05, 1.66817850e-05, 1.00432596e-05], - [1.17713485e-05, 7.52006948e-06, 1.07032640e-05, 4.27590565e-05], - [1.95739418e-05, 7.22217474e-06, 1.53193401e-05, 6.70351779e-05]]], - [[[3.13344980e-05, 2.70606739e-05, 2.44948972e-05, 1.77567021e-05], - [1.90029154e-05, 2.90531980e-05, 1.76740102e-05, 1.29122281e-05], - [1.41654000e-05, 2.45964900e-05, 3.50894348e-05, 5.20973241e-05], - [7.74470545e-06, 3.52484133e-05, 5.12982059e-05, 6.79177688e-05]], - [[2.11172897e-05, 4.71650260e-05, 3.06401319e-05, 3.54002572e-05], - [2.31950645e-05, 9.60246108e-06, 9.74684506e-06, 7.52141756e-06], - [1.00306048e-05, 2.24700247e-05, 1.88671263e-05, 1.16233270e-05], - [3.37392161e-06, 1.88659788e-05, 4.57905920e-05, 3.43578287e-05]], - [[2.12298059e-05, 3.20228280e-05, 2.33673454e-05, 3.68864089e-05], - [9.66985273e-06, 9.29721155e-06, 9.48060716e-06, 1.11725454e-05], - [8.81855731e-06, 1.41611066e-05, 1.54502349e-05, 1.62410677e-05], - [2.14792655e-05, 1.26137383e-05, 2.02223611e-05, - 3.96829419e-05]]]]) * units('s^-1') + truth = np.array([[[[4.19156244e-05, 2.27470339e-05, 2.75954049e-05, 3.00661456e-05], + [6.48775008e-05, 2.64198324e-05, 1.81096782e-05, 3.86059168e-05], + [5.95353239e-05, 1.92166476e-05, 4.18126289e-05, 6.67830089e-05], + [1.09545089e-04, 1.09597033e-04, 1.02745286e-04, 1.26640850e-04]], + [[2.44351405e-05, 1.70396746e-05, 7.04604984e-05, 1.79570429e-05], + [1.89250108e-05, 1.08145724e-05, 2.23802711e-05, 3.46001750e-05], + [7.24858097e-06, 2.14187617e-05, 2.77496740e-05, 1.35732616e-05], + [2.86119377e-05, 2.09171476e-05, 5.85194303e-05, 7.34928257e-05]], + [[3.87902676e-05, 3.47009797e-05, 4.80992294e-05, 5.71784592e-06], + [2.29658884e-05, 1.64309378e-05, 2.42597310e-05, 2.81431841e-05], + [9.01021396e-06, 1.38027998e-05, 9.38915929e-06, 3.45274069e-05], + [1.30470980e-05, 2.84690226e-05, 1.91146748e-06, 4.06621536e-05]]], + [[[3.73610348e-05, 2.13753895e-05, 1.75132430e-05, 5.08578708e-05], + [3.73478589e-05, 2.81829369e-05, 7.61187559e-06, 2.47541807e-05], + [4.01668119e-05, 5.04827148e-06, 4.75479995e-05, 6.97308017e-05], + [4.07669464e-05, 3.13927813e-05, 8.85911406e-05, 8.58408963e-05]], + [[2.59996085e-05, 1.88976315e-05, 2.69607956e-05, 1.05770748e-05], + [2.03013575e-05, 1.61917500e-05, 1.97277459e-05, 7.67203178e-06], + [9.02158329e-06, 1.81740323e-05, 1.62794771e-05, 1.45543595e-05], + [6.76273132e-06, 7.38327075e-06, 5.49008382e-05, 6.00943247e-05]], + [[2.62990866e-05, 9.98588563e-06, 4.56805146e-05, 3.13517416e-05], + [1.81350510e-05, 1.25201914e-05, 1.67241425e-05, 1.00323261e-05], + [1.17779401e-05, 7.52550294e-06, 1.07207344e-05, 4.28610889e-05], + [1.95625745e-05, 7.21619581e-06, 1.52651613e-05, 6.70778242e-05]]], + [[[3.13694760e-05, 2.70707062e-05, 2.43544673e-05, 1.78767184e-05], + [1.89621152e-05, 2.90837615e-05, 1.77459983e-05, 1.30658470e-05], + [1.41916465e-05, 2.46380177e-05, 3.51463709e-05, 5.21862079e-05], + [7.93884738e-06, 3.52826847e-05, 5.12787372e-05, 6.79850401e-05]], + [[2.11456240e-05, 4.71117592e-05, 3.06597644e-05, 3.54925451e-05], + [2.32514580e-05, 9.59287621e-06, 9.78655496e-06, 7.53030733e-06], + [1.00418822e-05, 2.24923252e-05, 1.89152853e-05, 1.16629638e-05], + [3.34881431e-06, 1.88780066e-05, 4.58164777e-05, 3.44487664e-05]], + [[2.12452693e-05, 3.20047506e-05, 2.33463296e-05, 3.69710047e-05], + [9.70025146e-06, 9.30739007e-06, 9.49383200e-06, 1.12134424e-05], + [8.81926698e-06, 1.41706959e-05, 1.54707604e-05, 1.62792600e-05], + [2.14900894e-05, 1.26146394e-05, 2.02217686e-05, + 3.97559787e-05]]]]) * units('s^-1') assert_array_almost_equal(totdef.data, truth, 12) @@ -1305,158 +1299,157 @@ def test_frontogenesis_4d(data_4d): 'latitude', 'longitude' ) - truth = np.array([[[[4.23682195e-10, -6.42818314e-12, -2.16491106e-10, -3.81845902e-10], - [-5.28632893e-10, -6.99413155e-12, -4.77775880e-11, 2.95949984e-10], - [7.82193227e-10, 3.55234312e-10, 2.14592821e-11, -5.20704165e-10], - [-3.51045184e-10, 2.06780694e-10, 1.68485199e-09, -1.46174872e-09]], - [[-7.24768625e-11, 1.07136516e-10, -1.33696585e-10, 3.43097590e-10], - [-5.01911031e-11, 2.14208730e-11, -4.73005145e-11, 9.54558115e-11], - [4.78125962e-11, 6.95838402e-11, 3.53993328e-10, -7.14986278e-11], - [6.14372837e-10, 1.41441177e-10, 8.45358549e-10, 1.36583089e-09]], - [[2.06344624e-11, 3.21877016e-10, 5.56930831e-10, 1.42479782e-10], - [9.85250671e-11, 1.06837011e-10, 5.71410578e-11, -4.75266666e-12], - [-6.42402291e-11, -2.11239598e-11, -1.21400141e-11, 2.11343115e-10], - [-6.98848390e-11, -4.11958693e-11, -1.75826411e-10, -1.78597026e-10]]], - [[[1.75135966e-10, -1.28928980e-11, -5.23466009e-11, -3.77702045e-10], - [-1.89751794e-10, -2.39181519e-11, 1.11100290e-11, 3.27299708e-10], - [5.03778532e-10, 6.01896046e-11, 2.52803022e-10, 2.63665975e-10], - [8.58126215e-10, -1.03984888e-10, 1.36888801e-09, -2.55913184e-11]], - [[-4.65433709e-11, -4.29058715e-11, 1.37345453e-10, 1.99587747e-10], - [-7.54157254e-11, 3.17296645e-11, 1.98329738e-11, 7.03907102e-11], - [2.07597572e-11, 9.76879251e-11, 3.64976958e-11, 9.05618888e-11], - [1.08070144e-10, 4.28175872e-12, 7.19436313e-10, -4.06647884e-10]], - [[3.53005192e-11, 6.97543696e-12, 7.69214961e-10, 1.72736149e-10], - [8.60386822e-11, 6.45426820e-11, 5.98938946e-11, -3.48393954e-11], - [-8.04261595e-11, 3.35202076e-11, -6.74886256e-11, 2.13321809e-10], - [3.19647867e-12, -1.19646868e-10, -3.89001592e-11, 2.32044147e-10]]], - [[[-1.06347076e-10, 1.43182380e-10, -1.67871828e-10, 7.55627348e-12], - [-2.10533376e-11, -1.36653603e-11, 5.14204938e-11, 4.52818256e-11], - [9.35607979e-11, -1.90340153e-11, 5.14752944e-11, 3.57906394e-10], - [1.47969288e-09, -6.40884777e-11, -2.00932232e-10, 3.79333810e-10]], - [[1.39959107e-10, -3.68301267e-10, 2.35651001e-10, 1.53240049e-10], - [-2.59723933e-10, 3.90319800e-11, 9.15095885e-11, 3.55206479e-11], - [6.07203827e-12, 8.14448434e-11, 2.37589779e-11, 1.56707972e-10], - [6.01077213e-11, 1.43024438e-11, 2.19842020e-10, 6.06611960e-12]], - [[5.76777660e-11, 1.50880981e-10, 9.80083831e-11, 1.37735770e-10], - [-5.69004435e-11, 1.61334326e-11, 8.32223545e-11, 1.07345248e-10], - [-5.82285173e-11, 1.03267739e-12, 9.19171693e-12, 1.73823741e-10], - [-2.33302976e-11, 1.01795295e-10, 4.19754683e-12, - 5.18286088e-10]]]]) * units('K/m/s') + truth = np.array([[[[4.23682388e-10, -6.60428594e-12, -2.16700227e-10, -3.80960666e-10], + [-5.28427593e-10, -7.11496293e-12, -4.77951513e-11, 2.94985981e-10], + [7.86953679e-10, 3.54196972e-10, 2.07842740e-11, -5.25487973e-10], + [-3.52111258e-10, 2.06421077e-10, 1.67986422e-09, -1.45950592e-09]], + [[-7.31728965e-11, 1.06892315e-10, -1.33453527e-10, 3.42647921e-10], + [-5.05805666e-11, 2.12238918e-11, -4.71306612e-11, 9.62250022e-11], + [4.76933273e-11, 6.94586917e-11, 3.53139630e-10, -7.14834221e-11], + [6.14587969e-10, 1.41091788e-10, 8.42714362e-10, 1.36031856e-09]], + [[2.05113794e-11, 3.21339794e-10, 5.56947831e-10, 1.43142115e-10], + [9.85782985e-11, 1.06721561e-10, 5.73106405e-11, -5.03368922e-12], + [-6.43122987e-11, -2.12772736e-11, -1.17352480e-11, 2.13297934e-10], + [-6.97155996e-11, -4.10739462e-11, -1.75156002e-10, -1.76167917e-10]]], + [[[1.74719456e-10, -1.35620544e-11, -5.23975776e-11, -3.77740716e-10], + [-1.89498320e-10, -2.40570704e-11, 1.09765802e-11, 3.26582884e-10], + [5.05760395e-10, 5.96930313e-11, 2.51806496e-10, 2.62326483e-10], + [8.55597272e-10, -1.03839677e-10, 1.36437001e-09, -2.55279252e-11]], + [[-4.68143046e-11, -4.29566800e-11, 1.37326379e-10, 2.00212822e-10], + [-7.60292021e-11, 3.13481943e-11, 2.02636812e-11, 7.07310188e-11], + [2.07073318e-11, 9.74536122e-11, 3.64495220e-11, 9.11599007e-11], + [1.07707226e-10, 4.27961436e-12, 7.17400120e-10, -4.07742791e-10]], + [[3.51033086e-11, 6.86914537e-12, 7.68630167e-10, 1.73824937e-10], + [8.63644951e-11, 6.43950959e-11, 6.01335884e-11, -3.49684748e-11], + [-8.06772168e-11, 3.34221310e-11, -6.70871076e-11, 2.13933933e-10], + [2.77857293e-12, -1.19419804e-10, -3.88340891e-11, 2.35051688e-10]]], + [[[-1.06920260e-10, 1.42163009e-10, -1.67670634e-10, 7.77738130e-12], + [-2.14431980e-11, -1.40383248e-11, 5.12326588e-11, 4.47136472e-11], + [9.29690678e-11, -1.91237280e-11, 5.11911088e-11, 3.57423744e-10], + [1.48172065e-09, -6.47936247e-11, -2.02021163e-10, 3.76309534e-10]], + [[1.40697485e-10, -3.68197137e-10, 2.35522920e-10, 1.53804948e-10], + [-2.61409796e-10, 3.88149869e-11, 9.17155132e-11, 3.56335985e-11], + [6.05095218e-12, 8.10937994e-11, 2.38586262e-11, 1.57114763e-10], + [5.98536934e-11, 1.42709122e-11, 2.20296991e-10, 6.13222348e-12]], + [[5.77582222e-11, 1.50846336e-10, 9.79419525e-11, 1.38512768e-10], + [-5.73091526e-11, 1.59416672e-11, 8.32303219e-11, 1.08035832e-10], + [-5.84859130e-11, 7.43545248e-13, 9.37957614e-12, 1.74102020e-10], + [-2.38469755e-11, 1.01414977e-10, 4.18826651e-12, + 5.18914848e-10]]]]) * units('K/m/s') assert_array_almost_equal(frnt.data, truth, 16) def test_geostrophic_wind_4d(data_4d): """Test geostrophic_wind on a 4D (time, pressure, y, x) grid.""" u_g, v_g = geostrophic_wind(data_4d.height) - u_g_truth = np.array([[[[4.40351577, 12.52087174, 20.6458988, 3.17057524], - [14.11461945, 17.13672114, 22.06686549, 28.28270102], - [24.47454294, 22.86342357, 31.74065923, 41.48130088], - [35.59988608, 29.85398309, 50.68045123, 41.40714946]], - [[7.36263117, 11.15525254, 15.36136167, 8.9043257], - [8.36777239, 12.52326604, 13.39382587, 14.3316852], - [10.38214971, 13.05048176, 16.57141998, 20.60619861], - [13.53264547, 12.63889256, 25.51465438, 27.85194657]], - [[5.7558101, 8.87403945, 12.12136937, 6.95914488], - [5.63469768, 9.23443489, 9.46733739, 9.64257854], - [5.15675792, 8.93121196, 10.1444189, 10.03116286], - [4.2776387, 7.88423455, 14.54891694, 7.85445617]]], - [[[2.56196227, 12.12574931, 18.89599304, 9.31367555], - [11.14381317, 16.08241758, 22.90372798, 23.24530036], - [21.19957068, 18.21200016, 27.48622742, 37.93750724], - [32.9424023, 18.30589852, 32.72832352, 53.53662491]], - [[5.89065665, 10.24260864, 13.9982738, 7.63017804], - [7.7319368, 12.49290588, 13.8820136, 12.98573492], - [9.40028538, 12.48920597, 15.31293349, 18.73778037], - [10.88139947, 9.96423153, 18.47901734, 24.95509777]], - [[5.3790145, 9.32173797, 9.01530817, 3.68853401], - [5.42563016, 8.9380796, 9.35289746, 9.01581846], - [4.95407268, 8.35221797, 9.30403934, 11.10242176], - [3.90093595, 7.537516, 8.82237876, 9.57266969]]], - [[[4.077062, 9.91350661, 14.63954845, 11.45133198], - [9.22655905, 15.4118828, 20.8655254, 20.36949692], - [17.30011986, 16.30232673, 23.25100815, 32.47299215], - [28.67482075, 12.0424244, 21.34996542, 48.18503321]], - [[4.67946573, 7.67735341, 7.67258169, 7.43729616], - [6.37289243, 10.60261239, 12.10568057, 11.53061917], - [7.78079442, 11.18649202, 14.92802562, 16.19084404], - [8.87459397, 9.15376375, 15.95950978, 21.50271574]], - [[4.07034519, 6.49914852, 4.9842596, 5.1120617], - [4.20250871, 6.7603074, 8.51019946, 8.51714298], - [3.85757805, 6.9373935, 9.8250342, 10.52736698], - [2.97756024, 7.02083208, 8.67190524, - 10.98516411]]]]) * units('m/s') - v_g_truth = np.array([[[[-2.34336304e+01, -1.93589800e+01, -7.42980465e+00, - 1.23538955e+01], - [-2.05343103e+01, -1.59281972e+01, -7.22778771e+00, - 5.56691831e+00], - [-2.12483061e+01, -1.50276890e+01, -1.26159708e+00, - 2.00499696e+01], - [-2.82673839e+01, -1.22322398e+01, 2.74929719e+00, - 1.66772271e+01]], - [[-2.11572490e+01, -1.57068398e+01, -7.16428821e+00, - 4.47040576e+00], - [-1.85233793e+01, -1.38641633e+01, -7.23745352e+00, - 1.35674995e+00], - [-1.48069287e+01, -1.29873005e+01, -6.19402168e+00, - 5.57290769e+00], - [-1.63708722e+01, -1.07203268e+01, -3.25405588e+00, - 6.02794043e+00]], - [[-1.83721994e+01, -1.51434535e+01, -8.30361332e+00, - 2.14732109e+00], - [-1.60334603e+01, -1.37004633e+01, -8.52272656e+00, - -5.00249972e-01], - [-1.25811419e+01, -1.30858045e+01, -8.11893604e+00, - 2.31946331e+00], - [-1.07972595e+01, -1.12050147e+01, -8.05482698e+00, - -1.34669618e+00]]], - [[[-2.47128002e+01, -2.06093912e+01, -7.53605837e+00, - 1.45071982e+01], - [-2.04618167e+01, -1.66379272e+01, -6.94777385e+00, - 8.60864325e+00], - [-2.03847527e+01, -1.41640171e+01, -3.58588785e+00, - 1.13496351e+01], - [-3.06442215e+01, -1.34818877e+01, 3.63145087e+00, - 2.06957942e+01]], - [[-2.20117576e+01, -1.60592509e+01, -6.79979611e+00, - 5.76660686e+00], - [-1.88926841e+01, -1.40452204e+01, -7.10711240e+00, - 1.92164004e+00], - [-1.49428085e+01, -1.27155409e+01, -6.56034626e+00, - 3.52277542e+00], - [-1.56847892e+01, -1.10535722e+01, -3.82991450e+00, - 5.98618380e+00]], - [[-1.89418619e+01, -1.48982095e+01, -8.32871820e+00, - 7.66612047e-01], - [-1.57997569e+01, -1.38337366e+01, -9.12720817e+00, - -1.68017155e+00], - [-1.34002412e+01, -1.27868867e+01, -8.32854573e+00, - -2.52183180e-02], - [-1.10305552e+01, -1.16852908e+01, -7.77451018e+00, - 7.01786569e-01]]], - [[[-2.87198561e+01, -2.07541862e+01, -7.39120444e+00, - 1.13690891e+01], - [-2.50727626e+01, -1.76277299e+01, -6.48428638e+00, - 8.35756789e+00], - [-2.15686958e+01, -1.43774917e+01, -4.66795064e+00, - 7.55992752e+00], - [-3.08303915e+01, -1.46678239e+01, 2.17589132e+00, - 1.97007540e+01]], - [[-2.14034948e+01, -1.55089179e+01, -7.19566930e+00, - 3.53625110e+00], - [-1.85643117e+01, -1.42866005e+01, -7.10227950e+00, - 2.98865138e+00], - [-1.52824784e+01, -1.23952994e+01, -6.71565437e+00, - 1.75645659e+00], - [-1.53343446e+01, -1.06296646e+01, -4.49885811e+00, - 3.05807491e+00]], - [[-1.62094234e+01, -1.41161427e+01, -9.20541452e+00, - -1.47723905e+00], - [-1.41272620e+01, -1.33895366e+01, -9.16198151e+00, - -1.44459685e+00], - [-1.29925870e+01, -1.17892453e+01, -8.27421454e+00, - -2.44749477e+00], - [-1.08991833e+01, -1.03581717e+01, -7.35501458e+00, - -1.88971184e+00]]]]) * units('m/s') + u_g_truth = np.array([[[[4.4048682, 12.51692258, 20.6372888, 3.17769076], + [14.10194272, 17.12263389, 22.04954728, 28.25627227], + [24.44520364, 22.83658626, 31.70185292, 41.43474924], + [35.55078527, 29.81195711, 50.61167797, 41.34530902]], + [[7.35972965, 11.1508039, 15.35393025, 8.90224418], + [8.36112058, 12.51333565, 13.38382857, 14.31961908], + [10.36996705, 13.0359012, 16.55131816, 20.5818523, ], + [13.51358869, 12.61987535, 25.47981594, 27.81300202]], + [[5.75323442, 8.87025383, 12.11513202, 6.9569899], + [5.63036347, 9.22723021, 9.46050042, 9.6346362], + [5.15111673, 8.92136198, 10.13229278, 10.02026762], + [4.27093343, 7.87208428, 14.5287988, 7.84193975]]], + [[[2.56374289, 12.12175071, 18.88903041, 9.31429628], + [11.13363838, 16.0692652, 22.88529273, 23.22479772], + [21.17380408, 18.19154086, 27.4544941, 37.89230504], + [32.89749307, 18.27860521, 32.68137119, 53.46237373]], + [[5.88868673, 10.23886093, 13.99207011, 7.62863328], + [7.72562462, 12.48283865, 13.87130247, 12.9747224], + [9.38948486, 12.47560991, 15.29521325, 18.71570391], + [10.86569379, 9.94843902, 18.45258217, 24.92010393]], + [[5.37666159, 9.31750301, 9.01145261, 3.6887154], + [5.42142711, 8.93123924, 9.34560535, 9.00788023], + [4.9486882, 8.34297898, 9.29367604, 11.09021549], + [3.89472979, 7.52596773, 8.80903347, 9.55782342]]], + [[[4.07701203, 9.91100477, 14.63521206, 11.44931207], + [9.21849021, 15.39896866, 20.84826281, 20.3521286], + [17.27879226, 16.28474129, 23.22522698, 32.4339051], + [28.63614846, 12.02289896, 21.31740279, 48.11881204]], + [[4.67797906, 7.67496412, 7.67070558, 7.4354085], + [6.3676578, 10.5938839, 12.09551605, 11.52096098], + [7.77187678, 11.17427574, 14.91109545, 16.17177845], + [8.86174332, 9.13936002, 15.93605997, 21.47254661]], + [[4.06859757, 6.49637507, 4.98325985, 5.1109647], + [4.19923572, 6.75503352, 8.50297947, 8.50993959], + [3.85339539, 6.92959206, 9.81419868, 10.5154729], + [2.97279544, 7.01038155, 8.65854052, 10.9689316]]]]) * units('m/s') + v_g_truth = np.array([[[[-2.34997753e+01, -1.94136235e+01, -7.45077637e+00, + 1.23887662e+01], + [-2.05898579e+01, -1.59712848e+01, -7.24733971e+00, + 5.58197747e+00], + [-2.13032949e+01, -1.50665793e+01, -1.26486198e+00, + 2.01018571e+01], + [-2.83372497e+01, -1.22624731e+01, 2.75609237e+00, + 1.67184466e+01]], + [[-2.12169685e+01, -1.57511747e+01, -7.18451047e+00, + 4.48302414e+00], + [-1.85734872e+01, -1.39016674e+01, -7.25703167e+00, + 1.36042011e+00], + [-1.48452478e+01, -1.30209105e+01, -6.21005126e+00, + 5.58732988e+00], + [-1.64113345e+01, -1.07468232e+01, -3.26209862e+00, + 6.04283912e+00]], + [[-1.84240576e+01, -1.51861981e+01, -8.32705150e+00, + 2.15338222e+00], + [-1.60768326e+01, -1.37375247e+01, -8.54578152e+00, + -5.01603207e-01], + [-1.26137008e+01, -1.31196694e+01, -8.13994713e+00, + 2.32546588e+00], + [-1.08239460e+01, -1.12327091e+01, -8.07473534e+00, + -1.35002468e+00]]], + [[[-2.47825558e+01, -2.06675642e+01, -7.55733001e+00, + 1.45481469e+01], + [-2.05171683e+01, -1.66829347e+01, -6.96656838e+00, + 8.63193062e+00], + [-2.04375067e+01, -1.42006723e+01, -3.59516781e+00, + 1.13790069e+01], + [-3.07199620e+01, -1.35152096e+01, 3.64042638e+00, + 2.07469460e+01]], + [[-2.20738890e+01, -1.61045805e+01, -6.81898954e+00, + 5.78288395e+00], + [-1.89437910e+01, -1.40832144e+01, -7.12633797e+00, + 1.92683830e+00], + [-1.49814792e+01, -1.27484476e+01, -6.57732385e+00, + 3.53189205e+00], + [-1.57235558e+01, -1.10808922e+01, -3.83938054e+00, + 6.00097928e+00]], + [[-1.89953281e+01, -1.49402619e+01, -8.35222723e+00, + 7.68775922e-01], + [-1.58424970e+01, -1.38711585e+01, -9.15189832e+00, + -1.68471661e+00], + [-1.34349198e+01, -1.28199780e+01, -8.35009927e+00, + -2.52835808e-02], + [-1.10578184e+01, -1.17141722e+01, -7.79372570e+00, + 7.03521108e-01]]], + [[[-2.88009221e+01, -2.08127679e+01, -7.41206720e+00, + 1.14011801e+01], + [-2.51405873e+01, -1.76754149e+01, -6.50182713e+00, + 8.38017608e+00], + [-2.16245136e+01, -1.44146994e+01, -4.68003089e+00, + 7.57949195e+00], + [-3.09065921e+01, -1.47040769e+01, 2.18126927e+00, + 1.97494465e+01]], + [[-2.14639093e+01, -1.55526942e+01, -7.21598014e+00, + 3.54623269e+00], + [-1.86145303e+01, -1.43252474e+01, -7.12149199e+00, + 2.99673603e+00], + [-1.53220281e+01, -1.24273773e+01, -6.73303389e+00, + 1.76100214e+00], + [-1.53722451e+01, -1.06559370e+01, -4.50997751e+00, + 3.06563326e+00]], + [[-1.62551769e+01, -1.41559875e+01, -9.23139816e+00, + -1.48140877e+00], + [-1.41654778e+01, -1.34257568e+01, -9.18676573e+00, + -1.44850466e+00], + [-1.30262107e+01, -1.18197548e+01, -8.29562748e+00, + -2.45382867e+00], + [-1.09261218e+01, -1.03837731e+01, -7.37319328e+00, + -1.89438246e+00]]]]) * units('m/s') assert_array_almost_equal(u_g.data, u_g_truth, 6) assert_array_almost_equal(v_g.data, v_g_truth, 6) @@ -1465,115 +1458,86 @@ def test_inertial_advective_wind_4d(data_4d): """Test inertial_advective_wind on a 4D (time, pressure, y, x) grid.""" u_g, v_g = geostrophic_wind(data_4d.height) u_i, v_i = inertial_advective_wind(u_g, v_g, u_g, v_g) - u_i_truth = np.array([[[[-4.74579332, -6.36486064, -7.20354171, -11.08307751], - [-1.88515129, -4.33855679, -6.82871465, -9.38096911], - [2.308649, -6.93391208, -14.06293133, -20.60786775], - [-0.92388354, -13.76737076, -17.9039117, -23.71419254]], - [[-2.60558413, -3.48755492, -3.62050089, -4.18871134], - [-3.36965812, -2.57689219, -2.66529828, -3.34582207], - [-0.56309499, -2.3322732, -4.37379768, -6.6663065], - [1.70092943, -3.59623514, -5.94640587, -7.50380432]], - [[-1.60508844, -2.30572073, -2.39044749, -2.59511279], - [-2.18854472, -1.47967397, -1.57319604, -2.24386278], - [-1.10582176, -1.24627092, -2.02075175, -3.314856], - [-0.25911941, -1.62294229, -1.75103256, -1.21885814]]], - [[[-6.69345313, -6.73506869, -7.9082287, -12.43972804], - [-2.21048835, -5.05651724, -7.72691754, -11.18333726], - [2.66904547, -4.81530785, -9.54984823, -12.89835729], - [8.55752862, -7.70089375, -12.37978952, -10.22208691]], - [[-3.17485999, -3.54021424, -3.54593593, -4.29515483], - [-3.68981249, -2.85516457, -2.76603925, -3.31604629], - [-1.16624451, -2.17242275, -3.57186768, -5.25444633], - [1.41851647, -2.44637201, -4.63693023, -6.09680756]], - [[-3.2219496, -1.90321215, -1.16750878, -1.08832287], - [-2.0239913, -1.38273223, -1.39926438, -1.92743159], - [-1.31353175, -1.15761322, -1.72857968, -2.81015813], - [-0.96137414, -0.94030556, -1.52657711, -2.56457651]]], - [[[-5.10794084, -5.32937859, -5.93090309, -8.05663994], - [-5.25295525, -6.02259284, -7.06582462, -9.0763472], - [0.32747247, -4.38931301, -7.24210551, -8.856658], - [11.82591067, -3.51482111, -8.18935835, -3.90270871]], - [[-2.9420404, -1.93269048, -1.78193608, -2.21710641], - [-2.96678921, -2.48380116, -2.64978243, -3.39496054], - [-1.42507824, -2.23090734, -3.01660858, -3.95003961], - [0.38000295, -2.10863221, -3.40584443, -4.06614801]], - [[-1.84525414, -0.73542408, -0.62568812, -1.18458192], - [-0.90497548, -1.10518325, -1.44073904, -1.95278103], - [-0.97196521, -1.22914653, -1.48019684, -1.79349709], - [-1.29544691, -0.9808466, -1.24778616, - -1.95945874]]]]) * units('m/s') - v_i_truth = np.array([[[[1.03108918e+01, 5.87304544e+00, -3.23865690e+00, - -1.88225987e+01], - [9.87187503e+00, 5.33610060e+00, 4.80874417e+00, - 3.92484555e-02], - [6.37856912e+00, 6.46296166e+00, 8.14267044e+00, - 4.37232518e+00], - [-1.30385124e+00, 1.01032585e+01, 4.20243238e+00, - -1.97934081e+01]], - [[1.10360108e+00, 2.30280536e+00, -1.82078930e+00, - -3.54284012e+00], - [2.43663102e+00, 1.35818636e+00, 4.92919838e-01, - -9.85544117e-03], - [2.33985677e+00, 1.03370035e+00, 3.28069921e+00, - 4.50046765e-01], - [2.93689077e-01, 1.43848430e+00, 6.69758269e+00, - -4.27897434e+00]], - [[4.77869846e-01, 1.14482717e+00, -1.82404796e+00, - -1.95731131e+00], - [5.19464097e-01, 4.52949199e-01, -3.26412809e-01, - 6.88744088e-02], - [2.51097720e-01, 1.43448773e-01, 1.08982754e+00, - -9.69963394e-02], - [-3.37860948e-01, 2.48187099e-01, 2.41935519e+00, - -2.84847302e+00]]], - [[[9.00342804e+00, 6.74193832e+00, 5.48141003e-01, - -1.25005172e+01], - [9.56628265e+00, 4.57654669e+00, 3.34479904e+00, - -7.13103555e+00], - [5.46655351e+00, 2.14241047e+00, 7.51934330e+00, - 2.43229680e+00], - [-5.48082957e+00, -6.46852260e-01, 1.34334674e+01, - 1.61485491e+01]], - [[2.49375451e+00, 3.34815514e+00, -7.09673457e-01, - -3.42185701e+00], - [2.69963182e+00, 1.64621317e+00, 2.91799176e-01, - -1.12584231e+00], - [1.83462164e+00, 1.71608154e-01, 1.87927013e+00, - 7.54482898e-01], - [-4.86175507e-01, -1.06374611e+00, 4.20283383e+00, - 1.54789418e+00]], - [[1.05175282e+00, 2.36715709e-01, -4.35406547e-01, - -9.39935118e-01], - [5.26821709e-01, 1.34167595e-01, 6.74485663e-02, - 1.18351992e-01], - [9.51152970e-02, 3.63519903e-02, 2.14587938e-01, - 6.10557463e-01], - [-2.42904366e-01, -5.80309556e-02, -3.63185957e-02, - 2.28010678e-01]]], - [[[5.18112516e+00, 8.23347995e+00, 2.85922078e+00, - -5.58457816e+00], - [8.85157651e+00, 4.70839103e+00, 2.51314815e+00, - -5.64246393e+00], - [7.54770787e+00, 8.21372199e-02, 4.70293099e+00, - 3.47174970e+00], - [-1.92174464e+00, -5.91657547e+00, 1.00629730e+01, - 2.62854305e+01]], - [[2.20347520e+00, 3.00714687e+00, 1.59377661e+00, - -6.41826692e-01], - [2.15604582e+00, 1.86128202e+00, 1.28260457e+00, - -1.03918888e+00], - [1.50501488e+00, 5.74547239e-01, 1.52092784e+00, - -3.94591487e-01], - [2.83614456e-02, -8.95222937e-01, 2.49176874e+00, - 1.81097696e+00]], - [[6.98668139e-01, 2.56635250e-01, 1.74332893e+00, - 3.79321436e-01], - [2.39593746e-01, 4.88748160e-01, 1.16884612e+00, - -7.54110131e-03], - [-6.40285805e-02, 5.82931602e-01, 4.67005716e-01, - 3.76288542e-02], - [-2.10896883e-01, 5.17706856e-01, -4.13562541e-01, - 6.96975860e-01]]]]) * units('m/s') + u_i_truth = np.array([[[[-4.77165787, -6.39928757, -7.24239774, -11.14139847], + [-1.8967587, -4.36028755, -6.86016435, -9.424228], + [2.31421679, -6.96263439, -14.11859275, -20.68976199], + [-0.92900951, -13.81722973, -17.96832023, -23.80435234]], + [[-2.62194257, -3.50676725, -3.63961746, -4.21059159], + [-3.38684408, -2.58995365, -2.67792148, -3.36122749], + [-0.56740802, -2.34244481, -4.39126012, -6.69284736], + [1.70715454, -3.60961021, -5.96780511, -7.53107716]], + [[-1.61558735, -2.31867093, -2.40316115, -2.60870259], + [-2.19984407, -1.48762908, -1.58089856, -2.2541336], + [-1.11136338, -1.25207315, -2.02918744, -3.32828099], + [-0.26028196, -1.62956357, -1.75756959, -1.22270124]]], + [[[-6.72938857, -6.77202159, -7.95073037, -12.50625533], + [-2.22377841, -5.0815521, -7.76259189, -11.23523285], + [2.67551814, -4.83617581, -9.58820051, -12.95106032], + [8.58739912, -7.72793742, -12.42304341, -10.25891257]], + [[-3.19431927, -3.55990592, -3.56474965, -4.31772693], + [-3.70858471, -2.86947801, -2.77907873, -3.331319], + [-1.17292465, -2.182095, -3.58631575, -5.27553824], + [1.4236791, -2.45544962, -4.65344893, -6.11853894]], + [[-3.24030343, -1.91423726, -1.1742268, -1.09439772], + [-2.03479751, -1.39015234, -1.40603089, -1.93610702], + [-1.31981448, -1.16318518, -1.73599486, -2.82161648], + [-0.96540565, -0.94432034, -1.53211138, -2.57328907]]], + [[[-5.13892702, -5.35990209, -5.96305829, -8.10039371], + [-5.28049715, -6.05189422, -7.09840362, -9.11834812], + [0.32358269, -4.40891596, -7.27141143, -8.89305721], + [11.86892255, -3.52631413, -8.21707342, -3.9149252]], + [[-2.95997348, -1.94436814, -1.79187921, -2.22918106], + [-2.98223302, -2.49621136, -2.66214712, -3.41052605], + [-1.43265094, -2.2408268, -3.02891598, -3.9658998], + [0.38112998, -2.11641585, -3.417963, -4.08044633]], + [[-1.85590971, -0.74052267, -0.62971895, -1.19099569], + [-0.91035149, -1.11111857, -1.44768616, -1.96172425], + [-0.97667565, -1.23489465, -1.48658447, -1.80074616], + [-1.30083552, -0.98479841, -1.25235639, + -1.96633294]]]]) * units('m/s') + v_i_truth = np.array([[[[1.03230312e+01, 5.87882109e+00, -3.24343027e+00, -1.88483470e+01], + [9.87647721e+00, 5.33706213e+00, 4.80929670e+00, 3.63063183e-02], + [6.37603821e+00, 6.45974507e+00, 8.14449487e+00, 4.38722620e+00], + [-1.31406689e+00, 1.00969188e+01, 4.19901525e+00, + -1.97739544e+01]], + [[1.10383561e+00, 2.30354462e+00, -1.82374723e+00, -3.54809094e+00], + [2.43631993e+00, 1.35723724e+00, 4.91193534e-01, -1.02997771e-02], + [2.33864366e+00, 1.03130947e+00, 3.27949769e+00, 4.52250225e-01], + [2.90865168e-01, 1.43496262e+00, 6.69604741e+00, -4.27768358e+00]], + [[4.77255548e-01, 1.14453826e+00, -1.82710412e+00, -1.96018490e+00], + [5.18797941e-01, 4.51757453e-01, -3.28462782e-01, 6.84789970e-02], + [2.50176678e-01, 1.41538500e-01, 1.08853845e+00, -9.62071225e-02], + [-3.39224824e-01, 2.45760327e-01, 2.41856776e+00, + -2.84808630e+00]]], + [[[9.01508187e+00, 6.74751069e+00, 5.47135566e-01, -1.25176087e+01], + [9.57125782e+00, 4.57776586e+00, 3.34524473e+00, -7.13601695e+00], + [5.46543202e+00, 2.13979774e+00, 7.51931363e+00, 2.43567533e+00], + [-5.48910344e+00, -6.52697336e-01, 1.34309575e+01, + 1.61565561e+01]], + [[2.49548039e+00, 3.34982501e+00, -7.11777553e-01, -3.42687086e+00], + [2.70007988e+00, 1.64584666e+00, 2.90292095e-01, -1.12712093e+00], + [1.83356146e+00, 1.69401994e-01, 1.87788933e+00, 7.55385123e-01], + [-4.89203395e-01, -1.06751808e+00, 4.20107093e+00, + 1.54893157e+00]], + [[1.05193589e+00, 2.35318468e-01, -4.37301952e-01, -9.41622628e-01], + [5.26337352e-01, 1.32572812e-01, 6.61575719e-02, 1.18009862e-01], + [9.40801497e-02, 3.45333939e-02, 2.13427873e-01, 6.10855423e-01], + [-2.44339907e-01, -6.01035575e-02, -3.78806842e-02, + 2.28008249e-01]]], + [[[5.18811867e+00, 8.23959428e+00, 2.86095202e+00, -5.59181418e+00], + [8.85485851e+00, 4.71028978e+00, 2.51387570e+00, -5.64507599e+00], + [7.54725519e+00, 7.98206363e-02, 4.70219106e+00, 3.47217441e+00], + [-1.92815930e+00, -5.92302637e+00, 1.00607869e+01, + 2.62899914e+01]], + [[2.20504999e+00, 3.00861548e+00, 1.59466025e+00, -6.42397860e-01], + [2.15641722e+00, 1.86132244e+00, 1.28263500e+00, -1.03958535e+00], + [1.50404596e+00, 5.72947187e-01, 1.51990698e+00, -3.94664336e-01], + [2.57832794e-02, -8.98652226e-01, 2.48959124e+00, 1.81170400e+00]], + [[6.98702092e-01, 2.55782733e-01, 1.74430100e+00, 3.79660759e-01], + [2.39131800e-01, 4.87869781e-01, 1.16903247e+00, -7.66523806e-03], + [-6.48734332e-02, 5.81810137e-01, 4.66189458e-01, 3.71854388e-02], + [-2.11996986e-01, 5.16093087e-01, -4.15633085e-01, + 6.96457035e-01]]]]) * units('m/s') assert_array_almost_equal(u_i.data, u_i_truth, 6) assert_array_almost_equal(v_i.data, v_i_truth, 6) @@ -1582,87 +1546,87 @@ def test_q_vector_4d(data_4d): """Test q_vector on a 4D (time, pressure, y, x) grid.""" u_g, v_g = geostrophic_wind(data_4d.height) q1, q2 = q_vector(u_g, v_g, data_4d.temperature, data_4d.pressure) - q1_truth = np.array([[[[-8.98245364e-13, 2.03803219e-13, 2.88874668e-12, 2.18043424e-12], - [4.37446820e-13, 1.21145200e-13, 1.51859353e-12, 3.82803347e-12], - [-1.20538030e-12, 2.27477298e-12, 3.47570178e-12, 3.03123012e-12], - [-1.51597275e-12, 8.02915408e-12, 7.71292472e-12, -2.22078527e-12]], - [[5.72960497e-13, 1.04264321e-12, -1.75695523e-13, 1.20745997e-12], - [2.94807953e-13, 5.80261767e-13, 6.23668595e-13, 7.31474131e-13], - [-4.04218965e-14, 3.24794013e-13, 1.39539675e-12, 2.82242029e-12], - [3.27509076e-13, 5.61307677e-13, 1.13454829e-12, 4.63551274e-12]], - [[2.23877015e-13, 5.77177907e-13, 1.62133659e-12, 5.43858376e-13], - [2.65333917e-13, 2.41006445e-13, 3.72510595e-13, 7.35822030e-13], - [6.56644633e-14, 1.99773842e-13, 5.20573457e-13, 1.69706608e-12], - [4.15915138e-14, 1.19910880e-13, 1.03632944e-12, 1.99561829e-12]]], - [[[-2.68870846e-13, 1.35977736e-12, 4.17548337e-12, 1.50465522e-12], - [4.62457018e-14, 1.25888111e-13, 2.15928418e-12, 4.70656495e-12], - [-1.25393137e-12, 9.54737370e-13, 1.48443002e-12, 2.12375621e-12], - [-2.93284658e-12, 6.06555344e-12, 4.21151397e-12, -2.12250513e-12]], - [[4.23461674e-13, 1.39393686e-13, 5.89509120e-13, 2.55041326e-12], - [5.73125714e-13, 5.60965341e-13, 7.65040451e-13, 9.49571939e-13], - [2.17153819e-14, 3.97023968e-13, 1.09194718e-12, 1.90731542e-12], - [1.45101233e-13, 1.79588608e-13, 1.03018848e-12, 3.62186462e-12]], - [[5.32674437e-13, 5.13465061e-13, 1.15582657e-12, 1.04827520e-12], - [2.77261345e-13, 2.33645555e-13, 4.59592371e-13, 5.34293340e-13], - [1.47376125e-13, 1.95746242e-13, 3.45854003e-13, 7.47741411e-13], - [-2.14078421e-14, 1.75226662e-13, 4.85424103e-13, 1.10808035e-12]]], - [[[6.41348753e-13, 1.88256910e-12, 5.21213092e-12, 2.07707653e-12], - [1.30753737e-12, 4.77125469e-13, 2.15204760e-12, 3.07374453e-12], - [-2.30546806e-13, 2.49929428e-13, 8.82215204e-14, 2.45990265e-12], - [-7.25812141e-12, 8.47072439e-13, -2.06762495e-12, - -4.40132129e-12]], - [[6.03705941e-13, -6.71320661e-13, 9.10543636e-13, 5.82480651e-13], - [9.54081741e-13, 6.11781160e-13, 6.95995265e-13, 8.67169047e-13], - [7.86580678e-14, 5.27405484e-13, 7.45800341e-13, 1.33965768e-12], - [2.22480631e-13, -1.98920384e-13, 8.56608245e-13, 1.59793218e-12]], - [[4.47195537e-13, 2.18235390e-13, 3.30926531e-13, -4.06675908e-14], - [1.70517246e-13, 2.18234962e-13, 3.78622612e-13, 5.03962144e-13], - [2.59462161e-13, 2.65626826e-13, 2.04642555e-13, 6.02812047e-13], - [1.69339642e-13, 2.91716502e-13, -1.20043003e-14, - 4.43770388e-13]]]]) * units('m^2 kg^-1 s^-1') - q2_truth = np.array([[[[3.33980776e-12, -1.32969763e-13, 1.01454470e-12, 6.02652581e-12], - [2.52898242e-13, -1.71069245e-13, -8.24708561e-13, 1.66384429e-13], - [-3.50646511e-12, -1.68929195e-12, 7.76215111e-13, 1.54486058e-12], - [-1.75492099e-12, -3.86524071e-12, -1.89368596e-12, - -5.14689517e-12]], - [[-2.09848775e-13, -6.25683634e-13, -1.40009292e-13, 1.08972893e-12], - [-2.58259284e-13, -2.67211578e-13, -6.41928957e-14, 5.90625597e-13], - [-2.73346325e-13, -2.28248227e-13, -4.76577835e-13, - -8.48559875e-13], - [1.21003124e-12, -5.10541546e-13, 6.35947149e-14, 2.44893915e-12]], - [[-6.72309334e-14, -3.56791270e-13, -4.13553842e-14, 3.81212108e-13], - [-3.55860413e-13, -1.22880634e-13, -3.19443665e-14, - -4.71232601e-14], - [-2.82289531e-13, -1.20965929e-13, 1.14160715e-13, -6.85113982e-14], - [5.17465531e-14, -4.61129211e-13, 5.33793701e-13, 1.28285338e-12]]], - [[[1.71894904e-12, -1.35675428e-12, 1.48328005e-13, 3.22454170e-12], - [-2.12666583e-13, -1.17551681e-13, -6.93968059e-13, 1.76659826e-12], - [-2.67906914e-12, -3.78250861e-13, -9.88730956e-13, 2.88200442e-12], - [1.48225123e-12, 2.15004833e-13, -4.84554577e-12, 2.77242999e-12]], - [[-3.09626209e-13, -2.52138997e-13, 4.58311589e-14, 2.03206766e-12], - [-3.95662347e-13, -2.99828956e-13, 1.08715446e-14, 1.06096030e-12], - [-2.46502471e-13, -2.43524217e-13, -3.81250581e-13, - -1.70270366e-13], - [8.12479206e-13, -1.38629628e-13, -8.05591138e-13, - -7.80286006e-13]], - [[-2.19626566e-13, -1.52852503e-13, 4.07706963e-13, 1.52323163e-12], - [-2.56235985e-13, -1.20817691e-13, 6.51260820e-15, 3.49591511e-13], - [-2.44063890e-13, -1.21871642e-13, -9.09798480e-14, - -1.59903476e-13], - [-2.47929201e-13, -1.77269110e-13, -1.12991330e-13, - -6.06795348e-13]]], - [[[-6.48288201e-13, -1.96951432e-12, -5.53508048e-13, 1.94507133e-12], - [-2.00769011e-12, -3.72469047e-13, -4.59116219e-13, 1.11322705e-13], - [-3.83507643e-12, 1.18054543e-13, -4.24001455e-13, -5.88688871e-13], - [-1.84528711e-12, 1.54974343e-12, -7.36123184e-13, 1.06256777e-13]], - [[-4.58487019e-13, -1.89124158e-13, 2.58416604e-13, 8.14652306e-13], - [-6.09664269e-13, -3.51509413e-13, 2.39576397e-13, 5.80539044e-13], - [-1.68850738e-13, -3.49553817e-13, -2.26470205e-13, 7.79989044e-13], - [2.23081718e-13, 1.20195366e-13, -1.01508013e-12, -2.15527487e-13]], - [[-1.68054338e-13, -5.06878852e-14, 2.77697698e-13, 8.37521961e-13], - [-1.39462599e-13, -1.36628363e-13, 3.13920124e-14, 4.55413406e-13], - [-1.06658890e-13, -2.19817426e-13, -8.35968065e-14, 1.88190788e-13], - [-2.27182863e-13, -2.74607819e-13, -1.10587309e-13, - -3.88915866e-13]]]]) * units('m^2 kg^-1 s^-1') + q1_truth = np.array([[[[-9.02684270e-13, 2.04906965e-13, 2.90366741e-12, 2.19304520e-12], + [4.39259469e-13, 1.21664810e-13, 1.52570637e-12, 3.84499568e-12], + [-1.20961682e-12, 2.28334568e-12, 3.48876764e-12, 3.04353683e-12], + [-1.52298016e-12, 8.05872598e-12, 7.74115167e-12, -2.23036948e-12]], + [[5.76052684e-13, 1.04797925e-12, -1.76250215e-13, 1.21374024e-12], + [2.96159390e-13, 5.82994320e-13, 6.26425486e-13, 7.35027599e-13], + [-4.05458639e-14, 3.26100111e-13, 1.40096964e-12, 2.83322883e-12], + [3.28501677e-13, 5.63278420e-13, 1.13853072e-12, 4.65264045e-12]], + [[2.25120252e-13, 5.80121595e-13, 1.62940948e-12, 5.46851323e-13], + [2.66540809e-13, 2.42144848e-13, 3.74380714e-13, 7.39064640e-13], + [6.59374356e-14, 2.00559760e-13, 5.22478916e-13, 1.70369853e-12], + [4.17124258e-14, 1.20339974e-13, 1.04017356e-12, 2.00285625e-12]]], + [[[-2.70235442e-13, 1.36656387e-12, 4.19692633e-12, 1.51457512e-12], + [4.64050107e-14, 1.26573416e-13, 2.16942269e-12, 4.72745728e-12], + [-1.25821951e-12, 9.58231778e-13, 1.49027307e-12, 2.13360636e-12], + [-2.94458687e-12, 6.08808030e-12, 4.22668460e-12, -2.13178006e-12]], + [[4.25758843e-13, 1.40346565e-13, 5.92764154e-13, 2.56329392e-12], + [5.75744868e-13, 5.63479482e-13, 7.68528359e-13, 9.54169673e-13], + [2.17989465e-14, 3.98672857e-13, 1.09630992e-12, 1.91458466e-12], + [1.45472393e-13, 1.80092943e-13, 1.03379050e-12, 3.63517612e-12]], + [[5.35452418e-13, 5.16110645e-13, 1.16167143e-12, 1.05362388e-12], + [2.78553810e-13, 2.34739333e-13, 4.61792157e-13, 5.36758839e-13], + [1.47975123e-13, 1.96526691e-13, 3.47222939e-13, 7.50706946e-13], + [-2.14929942e-14, 1.75848584e-13, 4.87164306e-13, 1.11205431e-12]]], + [[[6.44882146e-13, 1.89203548e-12, 5.23849406e-12, 2.08882463e-12], + [1.31350246e-12, 4.79492775e-13, 2.16235780e-12, 3.08756991e-12], + [-2.30468810e-13, 2.50903749e-13, 8.88048363e-14, 2.47021777e-12], + [-7.28610348e-12, 8.50128944e-13, -2.07551923e-12, + -4.41869472e-12]], + [[6.06909454e-13, -6.74302573e-13, 9.15261604e-13, 5.85674558e-13], + [9.58472982e-13, 6.14413858e-13, 6.99238896e-13, 8.71127400e-13], + [7.89621985e-14, 5.29651074e-13, 7.48742263e-13, 1.34494118e-12], + [2.23181345e-13, -1.99880485e-13, 8.59667557e-13, 1.60364542e-12]], + [[4.49485378e-13, 2.19403888e-13, 3.32682107e-13, -4.06788877e-14], + [1.71334107e-13, 2.19234639e-13, 3.80362792e-13, 5.06206489e-13], + [2.60485983e-13, 2.66689509e-13, 2.05507268e-13, 6.05236747e-13], + [1.69953806e-13, 2.92743451e-13, -1.21101740e-14, + 4.45255696e-13]]]]) * units('m^2 kg^-1 s^-1') + q2_truth = np.array([[[[3.34398414e-12, -1.32578962e-13, 1.01530245e-12, 6.03460412e-12], + [2.51655551e-13, -1.71080181e-13, -8.25450865e-13, 1.68941987e-13], + [-3.50610571e-12, -1.68900418e-12, 7.74142051e-13, 1.53842636e-12], + [-1.75486540e-12, -3.86629371e-12, -1.89184780e-12, + -5.15338594e-12]], + [[-2.09878631e-13, -6.26922694e-13, -1.40170277e-13, 1.09139148e-12], + [-2.58443408e-13, -2.67657189e-13, -6.44319215e-14, 5.90804763e-13], + [-2.73875193e-13, -2.28517322e-13, -4.76883863e-13, + -8.48746443e-13], + [1.21044640e-12, -5.10676858e-13, 6.32812733e-14, 2.44933519e-12]], + [[-6.72809694e-14, -3.57593424e-13, -4.18326571e-14, 3.81509257e-13], + [-3.56312152e-13, -1.23269564e-13, -3.21698576e-14, + -4.69401174e-14], + [-2.82461704e-13, -1.21007762e-13, 1.13823760e-13, -6.93485412e-14], + [5.19806694e-14, -4.61314808e-13, 5.33326094e-13, 1.28209513e-12]]], + [[[1.72127539e-12, -1.35818611e-12, 1.48111017e-13, 3.22882115e-12], + [-2.13631818e-13, -1.17550571e-13, -6.94644658e-13, 1.76893456e-12], + [-2.67966931e-12, -3.78148042e-13, -9.90360068e-13, 2.87997878e-12], + [1.48322304e-12, 2.15101840e-13, -4.84581616e-12, 2.77231259e-12]], + [[-3.09742331e-13, -2.52155554e-13, 4.57591777e-14, 2.03457093e-12], + [-3.95777463e-13, -3.00202455e-13, 1.05082591e-14, 1.06140347e-12], + [-2.46969363e-13, -2.43836368e-13, -3.81515859e-13, + -1.70412444e-13], + [8.12844940e-13, -1.38633850e-13, -8.06173908e-13, + -7.80955396e-13]], + [[-2.19923258e-13, -1.53282385e-13, 4.07809333e-13, 1.52462097e-12], + [-2.56567476e-13, -1.21124223e-13, 6.28491470e-15, 3.49835200e-13], + [-2.44172367e-13, -1.22026447e-13, -9.12989545e-14, + -1.60305594e-13], + [-2.47776092e-13, -1.77361553e-13, -1.13326400e-13, + -6.07726254e-13]]], + [[[-6.49332840e-13, -1.97186697e-12, -5.54805109e-13, 1.94760968e-12], + [-2.00917113e-12, -3.72825112e-13, -4.59780632e-13, 1.12445112e-13], + [-3.83584827e-12, 1.18455212e-13, -4.24969207e-13, -5.88484873e-13], + [-1.84313287e-12, 1.55136757e-12, -7.38157445e-13, 1.03689734e-13]], + [[-4.58924792e-13, -1.88627007e-13, 2.58408535e-13, 8.15237426e-13], + [-6.09787117e-13, -3.51901418e-13, 2.39399294e-13, 5.80646992e-13], + [-1.69168847e-13, -3.49955041e-13, -2.26671298e-13, 7.79694360e-13], + [2.23293556e-13, 1.20382150e-13, -1.01583327e-12, -2.16626822e-13]], + [[-1.68178414e-13, -5.08196191e-14, 2.77786052e-13, 8.38012650e-13], + [-1.39619960e-13, -1.36786251e-13, 3.12305194e-14, 4.55426142e-13], + [-1.06649917e-13, -2.19937033e-13, -8.38223242e-14, 1.87904895e-13], + [-2.27100932e-13, -2.74536001e-13, -1.10779552e-13, + -3.90314768e-13]]]]) * units('m^2 kg^-1 s^-1') assert_array_almost_equal(q1.data, q1_truth, 18) assert_array_almost_equal(q2.data, q2_truth, 18) diff --git a/tests/interpolate/test_slices.py b/tests/interpolate/test_slices.py index 5f51a9216a1..d992a928ff0 100644 --- a/tests/interpolate/test_slices.py +++ b/tests/interpolate/test_slices.py @@ -110,7 +110,7 @@ def test_interpolate_to_slice_against_selection(test_ds_lonlat): @needs_cartopy def test_geodesic(test_ds_xy): """Test the geodesic construction.""" - crs = test_ds_xy['temperature'].metpy.cartopy_crs + crs = test_ds_xy['temperature'].metpy.pyproj_crs path = geodesic(crs, (36.46, -112.45), (42.95, -68.74), 7) truth = np.array([[-4.99495719e+05, -1.49986599e+06], [9.84044354e+04, -1.26871737e+06], @@ -150,7 +150,7 @@ def test_cross_section_dataarray_and_linear_interp(test_ds_xy): truth_values_x, name='x', coords={ - 'crs': data['crs'], + 'metpy_crs': data['metpy_crs'], 'y': (['index'], truth_values_y), 'x': (['index'], truth_values_x), 'index': index, @@ -161,7 +161,7 @@ def test_cross_section_dataarray_and_linear_interp(test_ds_xy): truth_values_y, name='y', coords={ - 'crs': data['crs'], + 'metpy_crs': data['metpy_crs'], 'y': (['index'], truth_values_y), 'x': (['index'], truth_values_x), 'index': index, @@ -175,7 +175,7 @@ def test_cross_section_dataarray_and_linear_interp(test_ds_xy): 'time': data['time'], 'isobaric': data['isobaric'], 'index': index, - 'crs': data['crs'], + 'metpy_crs': data['metpy_crs'], 'y': data_truth_y, 'x': data_truth_x }, @@ -216,7 +216,7 @@ def test_cross_section_dataset_and_nearest_interp(test_ds_lonlat): coords={ 'isobaric': test_ds_lonlat['isobaric'], 'index': index, - 'crs': test_ds_lonlat['crs'], + 'metpy_crs': test_ds_lonlat['metpy_crs'], 'lat': (['index'], truth_values_lat), 'lon': (['index'], truth_values_lon) }, @@ -242,7 +242,7 @@ def test_cross_section_error_on_missing_coordinate(test_ds_lonlat): """Test that the proper error is raised with missing coordinate.""" # Use a variable with no crs coordinate data_bad = test_ds_lonlat['temperature'].copy() - del data_bad['crs'] + del data_bad['metpy_crs'] start, end = (30.5, 255.5), (44.5, 274.5) with pytest.raises(ValueError): diff --git a/tests/io/test_gini.py b/tests/io/test_gini.py index 34631853989..b70c333d0e3 100644 --- a/tests/io/test_gini.py +++ b/tests/io/test_gini.py @@ -14,7 +14,6 @@ from metpy.cbook import get_test_data from metpy.io import GiniFile from metpy.io.gini import GiniProjection -from metpy.testing import needs_pyproj logging.getLogger('metpy.io.gini').setLevel(logging.ERROR) @@ -98,7 +97,6 @@ def test_gini_bad_size(): @pytest.mark.parametrize('filename,bounds,data_var,proj_attrs,image,dt', gini_dataset_info, ids=['LCC', 'Stereographic', 'Mercator']) -@needs_pyproj def test_gini_xarray(filename, bounds, data_var, proj_attrs, image, dt): """Test that GINIFile can be passed to XArray as a datastore.""" f = GiniFile(get_test_data(filename)) @@ -134,7 +132,6 @@ def test_gini_xarray(filename, bounds, data_var, proj_attrs, image, dt): assert np.asarray(dt, dtype='datetime64[ms]') == ds.variables['time'] -@needs_pyproj def test_gini_mercator_upper_corner(): """Test that the upper corner of the Mercator coordinates is correct.""" f = GiniFile(get_test_data('HI-REGIONAL_4km_3.9_20160616_1715.gini')) diff --git a/tests/plots/test_declarative.py b/tests/plots/test_declarative.py index 3956ebf583a..186b3303f2c 100644 --- a/tests/plots/test_declarative.py +++ b/tests/plots/test_declarative.py @@ -20,7 +20,7 @@ from metpy.plots import (BarbPlot, ContourPlot, FilledContourPlot, ImagePlot, MapPanel, PanelContainer, PlotObs) # Fixtures to make sure we have the right backend -from metpy.testing import needs_cartopy, needs_pyproj, set_agg_backend # noqa: F401, I202 +from metpy.testing import needs_cartopy, set_agg_backend # noqa: F401, I202 from metpy.units import units @@ -28,7 +28,6 @@ @pytest.mark.mpl_image_compare(remove_text=True, tolerance=0.005) -@needs_pyproj @needs_cartopy def test_declarative_image(): """Test making an image plot.""" @@ -324,7 +323,6 @@ def test_colorfill_no_colorbar(cfeature): @pytest.mark.mpl_image_compare(remove_text=True, tolerance=1.23) -@needs_pyproj @needs_cartopy def test_global(): """Test that we can set global extent.""" diff --git a/tests/test_xarray.py b/tests/test_xarray.py index 6fa1537364d..0ef261b2b31 100644 --- a/tests/test_xarray.py +++ b/tests/test_xarray.py @@ -5,12 +5,13 @@ from collections import OrderedDict import numpy as np +import pyproj import pytest import xarray as xr from metpy.plots.mapping import CFProjection from metpy.testing import (assert_almost_equal, assert_array_almost_equal, assert_array_equal, - get_test_data, needs_cartopy) + get_test_data) from metpy.units import DimensionalityError, units from metpy.xarray import ( add_grid_arguments_from_xarray, @@ -63,11 +64,19 @@ def test_var_multidim_no_xy(test_var_multidim_full): def test_projection(test_var, ccrs): """Test getting the proper projection out of the variable.""" crs = test_var.metpy.crs - assert crs['grid_mapping_name'] == 'lambert_conformal_conic' + assert crs['grid_mapping_name'] == 'lambert_conformal_conic' assert isinstance(test_var.metpy.cartopy_crs, ccrs.LambertConformal) +def test_pyproj_projection(test_var): + """Test getting the proper pyproj projection out of the variable.""" + proj = test_var.metpy.pyproj_crs + + assert isinstance(proj, pyproj.CRS) + assert proj.coordinate_operation.method_name == 'Lambert Conic Conformal (1SP)' + + def test_no_projection(test_ds): """Test getting the crs attribute when not available produces a sensible error.""" var = test_ds.lat @@ -219,7 +228,7 @@ def test_missing_grid_mapping(): ds = xr.Dataset({'data': data}) data_var = ds.metpy.parse_cf('data') - assert 'crs' in data_var.coords + assert 'metpy_crs' in data_var.coords def test_missing_grid_mapping_var(caplog): @@ -239,6 +248,30 @@ def test_missing_grid_mapping_var(caplog): assert 'Could not find' in caplog.text +def test_parsecf_crs(): + """Test calling `parse_cf` with the metpy_crs variable.""" + ds = xr.Dataset({'metpy_crs': xr.DataArray(1)}) + + with pytest.warns(UserWarning, match='Attempting to parse metpy_crs'): + ds.metpy.parse_cf('metpy_crs') + + +def test_parsecf_existing_scalar_crs(): + """Test calling `parse_cf` on a variable with an existing scalar metpy_crs coordinate.""" + ds = xr.Dataset({'data': xr.DataArray(1, coords=dict(metpy_crs=1))}) + + with pytest.warns(UserWarning, match='metpy_crs already present'): + ds.metpy.parse_cf('data') + + +def test_parsecf_existing_vector_crs(): + """Test calling `parse_cf` on a variable with an existing vector metpy_crs coordinate.""" + ds = xr.Dataset({'data': xr.DataArray(1, dims=('metpy_crs',), coords=(np.ones(3),))}) + + with pytest.warns(UserWarning, match='metpy_crs already present'): + ds.metpy.parse_cf('data') + + def test_preprocess_and_wrap_only_preprocessing(): """Test xarray preprocessing and wrapping decorator for only preprocessing.""" data = xr.DataArray(np.ones(3), attrs={'units': 'km'}) @@ -782,7 +815,7 @@ def test_assign_crs_dataarray_by_argument(test_ds_generic, ccrs): da = test_ds_generic['test'] new_da = da.metpy.assign_crs(sample_cf_attrs) assert isinstance(new_da.metpy.cartopy_crs, ccrs.LambertConformal) - assert new_da['crs'] == CFProjection(sample_cf_attrs) + assert new_da['metpy_crs'] == CFProjection(sample_cf_attrs) def test_assign_crs_dataarray_by_kwargs(test_ds_generic, ccrs): @@ -790,21 +823,21 @@ def test_assign_crs_dataarray_by_kwargs(test_ds_generic, ccrs): da = test_ds_generic['test'] new_da = da.metpy.assign_crs(**sample_cf_attrs) assert isinstance(new_da.metpy.cartopy_crs, ccrs.LambertConformal) - assert new_da['crs'] == CFProjection(sample_cf_attrs) + assert new_da['metpy_crs'] == CFProjection(sample_cf_attrs) def test_assign_crs_dataset_by_argument(test_ds_generic, ccrs): """Test assigning CRS to Dataset by projection dict.""" new_ds = test_ds_generic.metpy.assign_crs(sample_cf_attrs) assert isinstance(new_ds['test'].metpy.cartopy_crs, ccrs.LambertConformal) - assert new_ds['crs'] == CFProjection(sample_cf_attrs) + assert new_ds['metpy_crs'] == CFProjection(sample_cf_attrs) def test_assign_crs_dataset_by_kwargs(test_ds_generic, ccrs): """Test assigning CRS to Dataset by projection kwargs.""" new_ds = test_ds_generic.metpy.assign_crs(**sample_cf_attrs) assert isinstance(new_ds['test'].metpy.cartopy_crs, ccrs.LambertConformal) - assert new_ds['crs'] == CFProjection(sample_cf_attrs) + assert new_ds['metpy_crs'] == CFProjection(sample_cf_attrs) def test_assign_crs_error_with_both_attrs(test_ds_generic): @@ -842,7 +875,7 @@ def test_coord_helper_da_yx(): dims=('y', 'x'), coords={'y': np.linspace(0, 1e5, 3), 'x': np.linspace(-1e5, 0, 3), - 'crs': CFProjection(sample_cf_attrs)}) + 'metpy_crs': CFProjection(sample_cf_attrs)}) @pytest.fixture @@ -874,7 +907,7 @@ def test_coord_helper_da_latlon(): ), dims=('y', 'x') ), - 'crs': CFProjection(sample_cf_attrs) + 'metpy_crs': CFProjection(sample_cf_attrs) } ) @@ -885,7 +918,6 @@ def test_coord_helper_da_dummy_yx(test_coord_helper_da_latlon): return test_coord_helper_da_latlon.assign_coords(y=range(3), x=range(3)) -@needs_cartopy def test_assign_latitude_longitude_basic_dataarray(test_coord_helper_da_yx, test_coord_helper_da_latlon): """Test assign_latitude_longitude in basic usage on DataArray.""" @@ -905,7 +937,6 @@ def test_assign_latitude_longitude_error_existing_dataarray( assert 'Latitude/longitude coordinate(s) are present' in str(exc) -@needs_cartopy def test_assign_latitude_longitude_force_existing_dataarray( test_coord_helper_da_dummy_latlon, test_coord_helper_da_latlon): """Test assign_latitude_longitude with existing coordinates forcing new.""" @@ -917,7 +948,6 @@ def test_assign_latitude_longitude_force_existing_dataarray( lon.values, 3) -@needs_cartopy def test_assign_latitude_longitude_basic_dataset(test_coord_helper_da_yx, test_coord_helper_da_latlon): """Test assign_latitude_longitude in basic usage on Dataset.""" @@ -929,7 +959,6 @@ def test_assign_latitude_longitude_basic_dataset(test_coord_helper_da_yx, lon.values, 3) -@needs_cartopy def test_assign_y_x_basic_dataarray(test_coord_helper_da_yx, test_coord_helper_da_latlon): """Test assign_y_x in basic usage on DataArray.""" new_da = test_coord_helper_da_latlon.metpy.assign_y_x() @@ -946,7 +975,6 @@ def test_assign_y_x_error_existing_dataarray( assert 'y/x coordinate(s) are present' in str(exc) -@needs_cartopy def test_assign_y_x_force_existing_dataarray( test_coord_helper_da_dummy_yx, test_coord_helper_da_yx): """Test assign_y_x with existing coordinates forcing new.""" @@ -956,7 +984,6 @@ def test_assign_y_x_force_existing_dataarray( np.testing.assert_array_almost_equal(test_coord_helper_da_yx['x'].values, x.values, 3) -@needs_cartopy def test_assign_y_x_dataarray_outside_tolerance(test_coord_helper_da_latlon): """Test assign_y_x raises ValueError when tolerance is exceeded on DataArray.""" with pytest.raises(ValueError) as exc: @@ -964,7 +991,6 @@ def test_assign_y_x_dataarray_outside_tolerance(test_coord_helper_da_latlon): assert 'cannot be collapsed to 1D within tolerance' in str(exc) -@needs_cartopy def test_assign_y_x_dataarray_transposed(test_coord_helper_da_yx, test_coord_helper_da_latlon): """Test assign_y_x on DataArray with transposed order.""" new_da = test_coord_helper_da_latlon.transpose(transpose_coords=True).metpy.assign_y_x() @@ -973,7 +999,6 @@ def test_assign_y_x_dataarray_transposed(test_coord_helper_da_yx, test_coord_hel np.testing.assert_array_almost_equal(test_coord_helper_da_yx['x'].values, x.values, 3) -@needs_cartopy def test_assign_y_x_dataset_assumed_order(test_coord_helper_da_yx, test_coord_helper_da_latlon): """Test assign_y_x on Dataset where order must be assumed.""" @@ -1318,25 +1343,27 @@ def test_grid_deltas_from_dataarray_actual_xy(test_da_xy, ccrs): """Test grid_deltas_from_dataarray with a xy grid and kind='actual'.""" # Construct lon/lat coordinates y, x = xr.broadcast(*test_da_xy.metpy.coordinates('y', 'x')) - lonlat = (ccrs.Geodetic(test_da_xy.metpy.cartopy_globe) - .transform_points(test_da_xy.metpy.cartopy_crs, x.values, y.values)) - lon = lonlat[..., 0] - lat = lonlat[..., 1] + lon, lat = pyproj.Proj(test_da_xy.metpy.pyproj_crs)( + x.values, + y.values, + inverse=True, + radians=False + ) test_da_xy = test_da_xy.assign_coords( longitude=xr.DataArray(lon, dims=('y', 'x'), attrs={'units': 'degrees_east'}), latitude=xr.DataArray(lat, dims=('y', 'x'), attrs={'units': 'degrees_north'})) # Actually test calculation dx, dy = grid_deltas_from_dataarray(test_da_xy, kind='actual') - true_dx = [[[[494426.3249766, 493977.6028005, 493044.0656467], - [498740.2046073, 498474.9771064, 497891.6588559], - [500276.2649627, 500256.3440237, 500139.9484845], - [498740.6956936, 499045.0391707, 499542.7244501]]]] * units.m - true_dy = [[[[496862.4106337, 496685.4729999, 496132.0732114, 495137.8882404], - [499774.9676486, 499706.3354977, 499467.5546773, 498965.2587818], - [499750.8962991, 499826.2263137, 500004.4977747, 500150.9897759]]]] * units.m - assert_array_almost_equal(dx, true_dx, 3) - assert_array_almost_equal(dy, true_dy, 3) + true_dx = [[[[494152.626, 493704.152, 492771.132], + [498464.118, 498199.037, 497616.042], + [499999.328, 499979.418, 499863.087], + [498464.608, 498768.783, 499266.193]]]] * units.m + true_dy = [[[[496587.363, 496410.523, 495857.430, 494863.795], + [499498.308, 499429.714, 499191.065, 498689.047], + [499474.250, 499549.538, 499727.711, 499874.122]]]] * units.m + assert_array_almost_equal(dx, true_dx, 2) + assert_array_almost_equal(dy, true_dy, 2) def test_grid_deltas_from_dataarray_nominal_lonlat(test_da_lonlat): @@ -1348,7 +1375,6 @@ def test_grid_deltas_from_dataarray_nominal_lonlat(test_da_lonlat): assert_array_almost_equal(dy, true_dy, 5) -@needs_cartopy def test_grid_deltas_from_dataarray_lonlat_assumed_order(): """Test grid_deltas_from_dataarray when dim order must be assumed.""" # Create test dataarray @@ -1384,7 +1410,6 @@ def test_grid_deltas_from_dataarray_invalid_kind(test_da_xy): grid_deltas_from_dataarray(test_da_xy, kind='invalid') -@needs_cartopy def test_add_grid_arguments_from_dataarray(): """Test the grid argument decorator for adding in arguments from xarray.""" @add_grid_arguments_from_xarray diff --git a/tutorials/xarray_tutorial.py b/tutorials/xarray_tutorial.py index 363eacadc33..2e6b85fbdf3 100644 --- a/tutorials/xarray_tutorial.py +++ b/tutorials/xarray_tutorial.py @@ -151,15 +151,21 @@ # Getting the cartopy coordinate reference system (CRS) of the projection of a DataArray is as # straightforward as using the ``data_var.metpy.cartopy_crs`` property: -data_crs = data['temperature'].metpy.cartopy_crs -print(data_crs) +cartopy_crs = data['temperature'].metpy.cartopy_crs +print(cartopy_crs) + +######################################################################### +# Likewise, the PyProj CRS can be obtained with the ``.pyproj_crs`` property: + +pyproj_crs = data['temperature'].metpy.pyproj_crs +print(pyproj_crs) ######################################################################### # The cartopy ``Globe`` can similarly be accessed via the ``data_var.metpy.cartopy_globe`` # property: -data_globe = data['temperature'].metpy.cartopy_globe -print(data_globe) +cartopy_globe = data['temperature'].metpy.cartopy_globe +print(cartopy_globe) ######################################################################### # Calculations @@ -179,7 +185,7 @@ # As an example, we calculate geostropic wind at 500 hPa below: lat, lon = xr.broadcast(y, x) -dx, dy = mpcalc.lat_lon_grid_deltas(lon, lat, initstring=data_crs.proj4_init) +dx, dy = mpcalc.lat_lon_grid_deltas(lon, lat, geod=pyproj_crs.get_geod()) heights = data['height'].metpy.loc[{'time': time[0], 'vertical': 500. * units.hPa}] u_geo, v_geo = mpcalc.geostrophic_wind(heights, dx, dy, lat) print(u_geo) @@ -242,7 +248,7 @@ # Let's add a projection and coastlines to it ax = plt.axes(projection=ccrs.LambertConformal()) data['height'].metpy.loc[{'time': time[0], - 'vertical': 500. * units.hPa}].plot(ax=ax, transform=data_crs) + 'vertical': 500. * units.hPa}].plot(ax=ax, transform=cartopy_crs) ax.coastlines() plt.show() @@ -254,7 +260,7 @@ data_level = data.metpy.loc[{time.name: time[0], vertical.name: 500. * units.hPa}] # Create the matplotlib figure and axis -fig, ax = plt.subplots(1, 1, figsize=(12, 8), subplot_kw={'projection': data_crs}) +fig, ax = plt.subplots(1, 1, figsize=(12, 8), subplot_kw={'projection': cartopy_crs}) # Plot RH as filled contours rh = ax.contourf(x, y, data_level['relative_humidity'], levels=[70, 80, 90, 100],