From 49631107eb8f4a30c39836a0386d8544a84e7c46 Mon Sep 17 00:00:00 2001 From: Zach Griffith Date: Sat, 13 Jul 2019 12:11:51 -0500 Subject: [PATCH 1/9] change name of test env to xarray-tests (#3110) --- azure-pipelines.yml | 6 +++--- ci/azure/install.yml | 8 ++++---- ci/azure/unit-tests.yml | 4 ++-- ci/requirements/py35-min.yml | 2 +- ci/requirements/py36-hypothesis.yml | 2 +- ci/requirements/py36.yml | 2 +- ci/requirements/py37-windows.yml | 2 +- ci/requirements/py37.yml | 2 +- doc/contributing.rst | 4 ++-- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 2132fe980dc..ccf8392c5a7 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -64,7 +64,7 @@ jobs: steps: - template: ci/azure/install.yml - bash: | - source activate test_env + source activate xarray-tests mypy . || exit 0 displayName: mypy type checks @@ -76,7 +76,7 @@ jobs: parameters: env_file: doc/environment.yml - bash: | - source activate test_env + source activate xarray-tests cd doc sphinx-build -n -j auto -b html -d _build/doctrees . _build/html displayName: Build HTML docs @@ -89,6 +89,6 @@ jobs: steps: - template: ci/azure/install.yml - bash: | - source activate test_env + source activate xarray-tests pytest properties displayName: Property based tests diff --git a/ci/azure/install.yml b/ci/azure/install.yml index 164d29436b6..8d72ffce124 100644 --- a/ci/azure/install.yml +++ b/ci/azure/install.yml @@ -6,11 +6,11 @@ steps: - template: add-conda-to-path.yml - bash: | - conda env create -n test_env --file ${{ parameters.env_file }} + conda env create -n xarray-tests --file ${{ parameters.env_file }} displayName: Install conda dependencies - bash: | - source activate test_env + source activate xarray-tests pip install -f https://7933911d6844c6c53a7d-47bd50c35cd79bd838daf386af554a83.ssl.cf2.rackcdn.com \ --no-deps \ --pre \ @@ -29,12 +29,12 @@ steps: displayName: Install upstream dev dependencies - bash: | - source activate test_env + source activate xarray-tests pip install --no-deps -e . displayName: Install xarray - bash: | - source activate test_env + source activate xarray-tests conda info -a conda list python xarray/util/print_versions.py diff --git a/ci/azure/unit-tests.yml b/ci/azure/unit-tests.yml index 526d159b406..7023d3119b8 100644 --- a/ci/azure/unit-tests.yml +++ b/ci/azure/unit-tests.yml @@ -3,14 +3,14 @@ steps: - template: install.yml - bash: | - source activate test_env + source activate xarray-tests python -OO -c "import xarray" displayName: Import xarray # Work around for allowed test failures: # https://github.com/microsoft/azure-pipelines-tasks/issues/9302 - bash: | - source activate test_env + source activate xarray-tests pytest xarray \ --junitxml=junit/test-results.xml \ --cov=xarray \ diff --git a/ci/requirements/py35-min.yml b/ci/requirements/py35-min.yml index 01b819d46f9..31e05a15359 100644 --- a/ci/requirements/py35-min.yml +++ b/ci/requirements/py35-min.yml @@ -1,4 +1,4 @@ -name: test_env +name: xarray-tests dependencies: - python=3.5.0 - pytest diff --git a/ci/requirements/py36-hypothesis.yml b/ci/requirements/py36-hypothesis.yml index 992c1792a44..f1aad7b39e0 100644 --- a/ci/requirements/py36-hypothesis.yml +++ b/ci/requirements/py36-hypothesis.yml @@ -1,4 +1,4 @@ -name: test_env +name: xarray-tests channels: - conda-forge dependencies: diff --git a/ci/requirements/py36.yml b/ci/requirements/py36.yml index 59ce883d454..ffdd33fc5ba 100644 --- a/ci/requirements/py36.yml +++ b/ci/requirements/py36.yml @@ -1,4 +1,4 @@ -name: test_env +name: xarray-tests channels: - conda-forge dependencies: diff --git a/ci/requirements/py37-windows.yml b/ci/requirements/py37-windows.yml index d1275ab8247..748546c75b3 100644 --- a/ci/requirements/py37-windows.yml +++ b/ci/requirements/py37-windows.yml @@ -1,4 +1,4 @@ -name: test_env +name: xarray-tests channels: - conda-forge dependencies: diff --git a/ci/requirements/py37.yml b/ci/requirements/py37.yml index 087a2cc8983..de7fa3abdc6 100644 --- a/ci/requirements/py37.yml +++ b/ci/requirements/py37.yml @@ -1,4 +1,4 @@ -name: test_env +name: xarray-tests channels: - conda-forge dependencies: diff --git a/doc/contributing.rst b/doc/contributing.rst index 429c282a95f..9017c3dde7c 100644 --- a/doc/contributing.rst +++ b/doc/contributing.rst @@ -152,10 +152,10 @@ We'll now kick off a two-step process: # Create and activate the build environment conda env create -f ci/requirements/py36.yml - conda activate test_env + conda activate xarray-tests # or with older versions of Anaconda: - source activate test_env + source activate xarray-tests # Build and install xarray pip install -e . From 7630d6d7153b6cdc83627bc71b641afe04d254a4 Mon Sep 17 00:00:00 2001 From: hetland Date: Sat, 13 Jul 2019 16:26:20 -0500 Subject: [PATCH 2/9] ROMS_ocean_model example added --- doc/examples.rst | 1 + doc/examples/ROMS_ocean_model.ipynb | 197 ++++++++++++++++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 doc/examples/ROMS_ocean_model.ipynb diff --git a/doc/examples.rst b/doc/examples.rst index 87fea9e8a6a..52acc95b51e 100644 --- a/doc/examples.rst +++ b/doc/examples.rst @@ -8,3 +8,4 @@ Examples examples/monthly-means examples/multidimensional-coords examples/visualization_gallery + examples/ROMS_ocean_model diff --git a/doc/examples/ROMS_ocean_model.ipynb b/doc/examples/ROMS_ocean_model.ipynb new file mode 100644 index 00000000000..8a614b4e9fc --- /dev/null +++ b/doc/examples/ROMS_ocean_model.ipynb @@ -0,0 +1,197 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ROMS Ocean Model Example" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import cartopy.crs as ccrs\n", + "import cartopy.feature as cfeature\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline\n", + "import cmocean\n", + "\n", + "import xarray as xr" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load a sample ROMS file. This is a subset of a full model available at \n", + "\n", + " http://barataria.tamu.edu/thredds/catalog.html?dataset=txla_hindcast_agg\n", + " \n", + "The subsetting was done using the following command on one of the output files:\n", + "\n", + " ds = xr.open_dataset('/d2/shared/TXLA_ROMS/output_20yr_obc/2001/ocean_his_0015.nc')\n", + " ds.isel(ocean_time=slice(47, None, 3*24), xi_rho=slice(200, None), xi_u=slice(200, None),\n", + " xi_v=slice(200, None), xi_psi=slice(200, None)).to_netcdf('ROMS_example.nc')\n", + "\n", + "The `ROMS_example.nc` file contains a subset of the grid, and five time steps." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### How to load in a ROMS netcdf file in a way consistent with xarray and xgcm" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# load in the file\n", + "ds = xr.open_dataset('ROMS_example.nc', chunks={'ocean_time': 1})\n", + "\n", + "# This is a way to turn on chunking and lazy evaluation. Opening with mfdataset, or \n", + "# setting the chunking in the open_dataset would also achive this.\n", + "ds" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Add a lazilly calculated vertical coordinates\n", + "\n", + "Write equations to calculate the vertical coordinate. These will be only evaluated when data is requested." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if ds.Vtransform == 1:\n", + " Zo_rho = ds.hc * (ds.s_rho - ds.Cs_r) + ds.Cs_r * ds.h\n", + " z_rho = Zo_rho + ds.zeta * (1 + Zo_rho/ds.h)\n", + "# Zo_w = ds.hc * (ds.s_w - ds.Cs_w) + ds.Cs_w * ds.h\n", + "# z_w = Zo_w + ds.zeta * (1 + Zo_w/ds.h)\n", + "elif ds.Vtransform == 2:\n", + " Zo_rho = (ds.hc * ds.s_rho + ds.Cs_r * ds.h) / (ds.hc + ds.h)\n", + " z_rho = ds.zeta + (ds.zeta + ds.h) * Zo_rho\n", + "# Zo_w = (ds.hc * ds.s_w + ds.Cs_w * ds.h) / (ds.hc + ds.h)\n", + "# z_w = ds.zeta + (ds.zeta + ds.h) * Zo_w\n", + "\n", + "ds.coords['z_rho'] = z_rho.transpose() # needing transpose seems to be an xarray bug\n", + "# ds.coords['z_w'] = z_w.transpose()\n", + "ds.salt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### A naive vertical slice\n", + "\n", + "Create a slice using the s-coordinate as the vertical dimension is typically not very informative." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "ds.salt.isel(xi_rho=50, ocean_time=0).plot()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "section = ds.salt.isel(xi_rho=50, eta_rho=slice(0, 167), ocean_time=0)\n", + "section.plot(x='lon_rho', y='z_rho', figsize=(15, 6), cmap=cmocean.cm.haline, clim=(25, 35))\n", + "plt.ylim([-100, 1]);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### A plan view\n", + "\n", + "Now make a naive plan view, without any projection information, just using lon/lat as x/y." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ds.salt.isel(s_rho=-1, ocean_time=0).plot(x='lon_rho', y='lat_rho')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And let's use a projection to make it nicer, and add a coast." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "proj = ccrs.LambertConformal(central_longitude=-92, central_latitude=29)\n", + "fig = plt.figure(figsize=(15, 5))\n", + "ax = plt.axes(projection=proj)\n", + "ds.salt.isel(s_rho=-1, ocean_time=0).plot(x='lon_rho', y='lat_rho', \n", + " cmap=cmocean.cm.haline, transform=ccrs.PlateCarree())\n", + "\n", + "coast_10m = cfeature.NaturalEarthFeature('physical', 'land', '10m',\n", + " edgecolor='k', facecolor='0.8')\n", + "ax.add_feature(coast_10m)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 5df8a428d36a3909395777bc9bc36e2d56b7422c Mon Sep 17 00:00:00 2001 From: Ryan Abernathey Date: Sat, 13 Jul 2019 20:07:50 -0500 Subject: [PATCH 3/9] Allow other tutorial filename extensions (#3121) * switching out examples to use nbsphinx * added jupyter_client to doc env * allow non netcdf tutorial files --- xarray/tutorial.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/xarray/tutorial.py b/xarray/tutorial.py index 01d4f181d7f..8b4f8490d59 100644 --- a/xarray/tutorial.py +++ b/xarray/tutorial.py @@ -33,8 +33,9 @@ def open_dataset(name, cache=True, cache_dir=_default_cache_dir, Parameters ---------- name : str - Name of the netcdf file containing the dataset - ie. 'air_temperature' + Name of the file containing the dataset. If no suffix is given, assumed + to be netCDF ('.nc' is appended) + e.g. 'air_temperature' cache_dir : string, optional The directory in which to search for and write cached data. cache : boolean, optional @@ -51,10 +52,13 @@ def open_dataset(name, cache=True, cache_dir=_default_cache_dir, xarray.open_dataset """ + root, ext = _os.path.splitext(name) + if not ext: + ext = '.nc' + fullname = root + ext longdir = _os.path.expanduser(cache_dir) - fullname = name + '.nc' localfile = _os.sep.join((longdir, fullname)) - md5name = name + '.md5' + md5name = fullname + '.md5' md5file = _os.sep.join((longdir, md5name)) if not _os.path.exists(localfile): From 925476970b3127959eebdaa945df2c9b7f149d09 Mon Sep 17 00:00:00 2001 From: hetland Date: Mon, 15 Jul 2019 14:21:50 -0500 Subject: [PATCH 4/9] Changed load to xr.tutorial.open_dataset(), and added some extra documentation. --- doc/examples/ROMS_ocean_model.ipynb | 44 +++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/doc/examples/ROMS_ocean_model.ipynb b/doc/examples/ROMS_ocean_model.ipynb index 8a614b4e9fc..d53b2bb80e5 100644 --- a/doc/examples/ROMS_ocean_model.ipynb +++ b/doc/examples/ROMS_ocean_model.ipynb @@ -18,7 +18,7 @@ "import cartopy.feature as cfeature\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline\n", - "import cmocean\n", + "# import cmocean # TODO: Add this dependency to the docs\n", "\n", "import xarray as xr" ] @@ -33,18 +33,29 @@ " \n", "The subsetting was done using the following command on one of the output files:\n", "\n", + " #open dataset\n", " ds = xr.open_dataset('/d2/shared/TXLA_ROMS/output_20yr_obc/2001/ocean_his_0015.nc')\n", - " ds.isel(ocean_time=slice(47, None, 3*24), xi_rho=slice(200, None), xi_u=slice(200, None),\n", - " xi_v=slice(200, None), xi_psi=slice(200, None)).to_netcdf('ROMS_example.nc')\n", + " \n", + " # Turn on chunking to activate dask and parallelize read/write.\n", + " ds = ds.chunk({'ocean_time': 1})\n", + " \n", + " # Pick out some of the variables that will be included as coordinates\n", + " ds = ds.set_coords(['Cs_r', 'Cs_w', 'hc', 'h', 'Vtransform'])\n", + " \n", + " # Select a a subset of variables. Salt will be visualized, zeta is used to \n", + " # calculate the vertical coordinate\n", + " variables = ['salt', 'zeta']\n", + " ds[variables].isel(ocean_time=slice(47, None, 7*24), \n", + " xi_rho=slice(300, None)).to_netcdf('ROMS_example.nc', mode='w')\n", "\n", - "The `ROMS_example.nc` file contains a subset of the grid, and five time steps." + "So, the `ROMS_example.nc` file contains a subset of the grid, one 3D variable, and two time steps." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### How to load in a ROMS netcdf file in a way consistent with xarray and xgcm" + "### Load in ROMS dataset as an xarray object" ] }, { @@ -54,7 +65,7 @@ "outputs": [], "source": [ "# load in the file\n", - "ds = xr.open_dataset('ROMS_example.nc', chunks={'ocean_time': 1})\n", + "ds = xr.tutorial.open_dataset('ROMS_example.nc', chunks={'ocean_time': 1})\n", "\n", "# This is a way to turn on chunking and lazy evaluation. Opening with mfdataset, or \n", "# setting the chunking in the open_dataset would also achive this.\n", @@ -67,7 +78,15 @@ "source": [ "### Add a lazilly calculated vertical coordinates\n", "\n", - "Write equations to calculate the vertical coordinate. These will be only evaluated when data is requested." + "Write equations to calculate the vertical coordinate. These will be only evaluated when data is requested. Information about the ROMS vertical coordinate can be found (here)[https://www.myroms.org/wiki/Vertical_S-coordinate]\n", + "\n", + "In short, for `Vtransform==2` as used in this example, \n", + "\n", + "$Z_0 = (h_c \\, S + h \\,C) / (h_c + h)$\n", + "\n", + "$z = Z_0 (\\zeta + h) + \\zeta$\n", + "\n", + "where the variables are defined as in the link above." ] }, { @@ -112,6 +131,13 @@ "ds.salt.isel(xi_rho=50, ocean_time=0).plot()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can feed coordinate information to the plot method to give a more informative cross-section that uses the depths. Note that we did not need to slice the depth or longitude information separately, this was done automatically as the variable was sliced." + ] + }, { "cell_type": "code", "execution_count": null, @@ -129,7 +155,7 @@ "source": [ "### A plan view\n", "\n", - "Now make a naive plan view, without any projection information, just using lon/lat as x/y." + "Now make a naive plan view, without any projection information, just using lon/lat as x/y. This looks OK, but will appear compressed because lon and lat do not have an aspect constrained by the projection." ] }, { @@ -189,7 +215,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.6.7" } }, "nbformat": 4, From 057f1008f8866fd9d416f4712eaa87d2fcf6bba0 Mon Sep 17 00:00:00 2001 From: Zach Griffith Date: Sat, 13 Jul 2019 12:11:51 -0500 Subject: [PATCH 5/9] change name of test env to xarray-tests (#3110) --- azure-pipelines.yml | 6 +++--- ci/azure/install.yml | 8 ++++---- ci/azure/unit-tests.yml | 4 ++-- ci/requirements/py35-min.yml | 2 +- ci/requirements/py36-hypothesis.yml | 2 +- ci/requirements/py36.yml | 2 +- ci/requirements/py37-windows.yml | 2 +- ci/requirements/py37.yml | 2 +- doc/contributing.rst | 4 ++-- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 2132fe980dc..ccf8392c5a7 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -64,7 +64,7 @@ jobs: steps: - template: ci/azure/install.yml - bash: | - source activate test_env + source activate xarray-tests mypy . || exit 0 displayName: mypy type checks @@ -76,7 +76,7 @@ jobs: parameters: env_file: doc/environment.yml - bash: | - source activate test_env + source activate xarray-tests cd doc sphinx-build -n -j auto -b html -d _build/doctrees . _build/html displayName: Build HTML docs @@ -89,6 +89,6 @@ jobs: steps: - template: ci/azure/install.yml - bash: | - source activate test_env + source activate xarray-tests pytest properties displayName: Property based tests diff --git a/ci/azure/install.yml b/ci/azure/install.yml index 164d29436b6..8d72ffce124 100644 --- a/ci/azure/install.yml +++ b/ci/azure/install.yml @@ -6,11 +6,11 @@ steps: - template: add-conda-to-path.yml - bash: | - conda env create -n test_env --file ${{ parameters.env_file }} + conda env create -n xarray-tests --file ${{ parameters.env_file }} displayName: Install conda dependencies - bash: | - source activate test_env + source activate xarray-tests pip install -f https://7933911d6844c6c53a7d-47bd50c35cd79bd838daf386af554a83.ssl.cf2.rackcdn.com \ --no-deps \ --pre \ @@ -29,12 +29,12 @@ steps: displayName: Install upstream dev dependencies - bash: | - source activate test_env + source activate xarray-tests pip install --no-deps -e . displayName: Install xarray - bash: | - source activate test_env + source activate xarray-tests conda info -a conda list python xarray/util/print_versions.py diff --git a/ci/azure/unit-tests.yml b/ci/azure/unit-tests.yml index 526d159b406..7023d3119b8 100644 --- a/ci/azure/unit-tests.yml +++ b/ci/azure/unit-tests.yml @@ -3,14 +3,14 @@ steps: - template: install.yml - bash: | - source activate test_env + source activate xarray-tests python -OO -c "import xarray" displayName: Import xarray # Work around for allowed test failures: # https://github.com/microsoft/azure-pipelines-tasks/issues/9302 - bash: | - source activate test_env + source activate xarray-tests pytest xarray \ --junitxml=junit/test-results.xml \ --cov=xarray \ diff --git a/ci/requirements/py35-min.yml b/ci/requirements/py35-min.yml index 01b819d46f9..31e05a15359 100644 --- a/ci/requirements/py35-min.yml +++ b/ci/requirements/py35-min.yml @@ -1,4 +1,4 @@ -name: test_env +name: xarray-tests dependencies: - python=3.5.0 - pytest diff --git a/ci/requirements/py36-hypothesis.yml b/ci/requirements/py36-hypothesis.yml index 992c1792a44..f1aad7b39e0 100644 --- a/ci/requirements/py36-hypothesis.yml +++ b/ci/requirements/py36-hypothesis.yml @@ -1,4 +1,4 @@ -name: test_env +name: xarray-tests channels: - conda-forge dependencies: diff --git a/ci/requirements/py36.yml b/ci/requirements/py36.yml index 59ce883d454..ffdd33fc5ba 100644 --- a/ci/requirements/py36.yml +++ b/ci/requirements/py36.yml @@ -1,4 +1,4 @@ -name: test_env +name: xarray-tests channels: - conda-forge dependencies: diff --git a/ci/requirements/py37-windows.yml b/ci/requirements/py37-windows.yml index d1275ab8247..748546c75b3 100644 --- a/ci/requirements/py37-windows.yml +++ b/ci/requirements/py37-windows.yml @@ -1,4 +1,4 @@ -name: test_env +name: xarray-tests channels: - conda-forge dependencies: diff --git a/ci/requirements/py37.yml b/ci/requirements/py37.yml index 087a2cc8983..de7fa3abdc6 100644 --- a/ci/requirements/py37.yml +++ b/ci/requirements/py37.yml @@ -1,4 +1,4 @@ -name: test_env +name: xarray-tests channels: - conda-forge dependencies: diff --git a/doc/contributing.rst b/doc/contributing.rst index 429c282a95f..9017c3dde7c 100644 --- a/doc/contributing.rst +++ b/doc/contributing.rst @@ -152,10 +152,10 @@ We'll now kick off a two-step process: # Create and activate the build environment conda env create -f ci/requirements/py36.yml - conda activate test_env + conda activate xarray-tests # or with older versions of Anaconda: - source activate test_env + source activate xarray-tests # Build and install xarray pip install -e . From 41ee209644480805763127454a2723eb48974d63 Mon Sep 17 00:00:00 2001 From: hetland Date: Sat, 13 Jul 2019 16:26:20 -0500 Subject: [PATCH 6/9] ROMS_ocean_model example added --- doc/examples.rst | 1 + doc/examples/ROMS_ocean_model.ipynb | 197 ++++++++++++++++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 doc/examples/ROMS_ocean_model.ipynb diff --git a/doc/examples.rst b/doc/examples.rst index 87fea9e8a6a..52acc95b51e 100644 --- a/doc/examples.rst +++ b/doc/examples.rst @@ -8,3 +8,4 @@ Examples examples/monthly-means examples/multidimensional-coords examples/visualization_gallery + examples/ROMS_ocean_model diff --git a/doc/examples/ROMS_ocean_model.ipynb b/doc/examples/ROMS_ocean_model.ipynb new file mode 100644 index 00000000000..8a614b4e9fc --- /dev/null +++ b/doc/examples/ROMS_ocean_model.ipynb @@ -0,0 +1,197 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ROMS Ocean Model Example" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import cartopy.crs as ccrs\n", + "import cartopy.feature as cfeature\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline\n", + "import cmocean\n", + "\n", + "import xarray as xr" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load a sample ROMS file. This is a subset of a full model available at \n", + "\n", + " http://barataria.tamu.edu/thredds/catalog.html?dataset=txla_hindcast_agg\n", + " \n", + "The subsetting was done using the following command on one of the output files:\n", + "\n", + " ds = xr.open_dataset('/d2/shared/TXLA_ROMS/output_20yr_obc/2001/ocean_his_0015.nc')\n", + " ds.isel(ocean_time=slice(47, None, 3*24), xi_rho=slice(200, None), xi_u=slice(200, None),\n", + " xi_v=slice(200, None), xi_psi=slice(200, None)).to_netcdf('ROMS_example.nc')\n", + "\n", + "The `ROMS_example.nc` file contains a subset of the grid, and five time steps." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### How to load in a ROMS netcdf file in a way consistent with xarray and xgcm" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# load in the file\n", + "ds = xr.open_dataset('ROMS_example.nc', chunks={'ocean_time': 1})\n", + "\n", + "# This is a way to turn on chunking and lazy evaluation. Opening with mfdataset, or \n", + "# setting the chunking in the open_dataset would also achive this.\n", + "ds" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Add a lazilly calculated vertical coordinates\n", + "\n", + "Write equations to calculate the vertical coordinate. These will be only evaluated when data is requested." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if ds.Vtransform == 1:\n", + " Zo_rho = ds.hc * (ds.s_rho - ds.Cs_r) + ds.Cs_r * ds.h\n", + " z_rho = Zo_rho + ds.zeta * (1 + Zo_rho/ds.h)\n", + "# Zo_w = ds.hc * (ds.s_w - ds.Cs_w) + ds.Cs_w * ds.h\n", + "# z_w = Zo_w + ds.zeta * (1 + Zo_w/ds.h)\n", + "elif ds.Vtransform == 2:\n", + " Zo_rho = (ds.hc * ds.s_rho + ds.Cs_r * ds.h) / (ds.hc + ds.h)\n", + " z_rho = ds.zeta + (ds.zeta + ds.h) * Zo_rho\n", + "# Zo_w = (ds.hc * ds.s_w + ds.Cs_w * ds.h) / (ds.hc + ds.h)\n", + "# z_w = ds.zeta + (ds.zeta + ds.h) * Zo_w\n", + "\n", + "ds.coords['z_rho'] = z_rho.transpose() # needing transpose seems to be an xarray bug\n", + "# ds.coords['z_w'] = z_w.transpose()\n", + "ds.salt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### A naive vertical slice\n", + "\n", + "Create a slice using the s-coordinate as the vertical dimension is typically not very informative." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "ds.salt.isel(xi_rho=50, ocean_time=0).plot()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "section = ds.salt.isel(xi_rho=50, eta_rho=slice(0, 167), ocean_time=0)\n", + "section.plot(x='lon_rho', y='z_rho', figsize=(15, 6), cmap=cmocean.cm.haline, clim=(25, 35))\n", + "plt.ylim([-100, 1]);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### A plan view\n", + "\n", + "Now make a naive plan view, without any projection information, just using lon/lat as x/y." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ds.salt.isel(s_rho=-1, ocean_time=0).plot(x='lon_rho', y='lat_rho')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And let's use a projection to make it nicer, and add a coast." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "proj = ccrs.LambertConformal(central_longitude=-92, central_latitude=29)\n", + "fig = plt.figure(figsize=(15, 5))\n", + "ax = plt.axes(projection=proj)\n", + "ds.salt.isel(s_rho=-1, ocean_time=0).plot(x='lon_rho', y='lat_rho', \n", + " cmap=cmocean.cm.haline, transform=ccrs.PlateCarree())\n", + "\n", + "coast_10m = cfeature.NaturalEarthFeature('physical', 'land', '10m',\n", + " edgecolor='k', facecolor='0.8')\n", + "ax.add_feature(coast_10m)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From e2960dd429a48271a88ba031bed7c11629de7f7c Mon Sep 17 00:00:00 2001 From: hetland Date: Mon, 15 Jul 2019 14:21:50 -0500 Subject: [PATCH 7/9] Changed load to xr.tutorial.open_dataset(), and added some extra documentation. --- doc/examples/ROMS_ocean_model.ipynb | 44 +++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/doc/examples/ROMS_ocean_model.ipynb b/doc/examples/ROMS_ocean_model.ipynb index 8a614b4e9fc..d53b2bb80e5 100644 --- a/doc/examples/ROMS_ocean_model.ipynb +++ b/doc/examples/ROMS_ocean_model.ipynb @@ -18,7 +18,7 @@ "import cartopy.feature as cfeature\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline\n", - "import cmocean\n", + "# import cmocean # TODO: Add this dependency to the docs\n", "\n", "import xarray as xr" ] @@ -33,18 +33,29 @@ " \n", "The subsetting was done using the following command on one of the output files:\n", "\n", + " #open dataset\n", " ds = xr.open_dataset('/d2/shared/TXLA_ROMS/output_20yr_obc/2001/ocean_his_0015.nc')\n", - " ds.isel(ocean_time=slice(47, None, 3*24), xi_rho=slice(200, None), xi_u=slice(200, None),\n", - " xi_v=slice(200, None), xi_psi=slice(200, None)).to_netcdf('ROMS_example.nc')\n", + " \n", + " # Turn on chunking to activate dask and parallelize read/write.\n", + " ds = ds.chunk({'ocean_time': 1})\n", + " \n", + " # Pick out some of the variables that will be included as coordinates\n", + " ds = ds.set_coords(['Cs_r', 'Cs_w', 'hc', 'h', 'Vtransform'])\n", + " \n", + " # Select a a subset of variables. Salt will be visualized, zeta is used to \n", + " # calculate the vertical coordinate\n", + " variables = ['salt', 'zeta']\n", + " ds[variables].isel(ocean_time=slice(47, None, 7*24), \n", + " xi_rho=slice(300, None)).to_netcdf('ROMS_example.nc', mode='w')\n", "\n", - "The `ROMS_example.nc` file contains a subset of the grid, and five time steps." + "So, the `ROMS_example.nc` file contains a subset of the grid, one 3D variable, and two time steps." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### How to load in a ROMS netcdf file in a way consistent with xarray and xgcm" + "### Load in ROMS dataset as an xarray object" ] }, { @@ -54,7 +65,7 @@ "outputs": [], "source": [ "# load in the file\n", - "ds = xr.open_dataset('ROMS_example.nc', chunks={'ocean_time': 1})\n", + "ds = xr.tutorial.open_dataset('ROMS_example.nc', chunks={'ocean_time': 1})\n", "\n", "# This is a way to turn on chunking and lazy evaluation. Opening with mfdataset, or \n", "# setting the chunking in the open_dataset would also achive this.\n", @@ -67,7 +78,15 @@ "source": [ "### Add a lazilly calculated vertical coordinates\n", "\n", - "Write equations to calculate the vertical coordinate. These will be only evaluated when data is requested." + "Write equations to calculate the vertical coordinate. These will be only evaluated when data is requested. Information about the ROMS vertical coordinate can be found (here)[https://www.myroms.org/wiki/Vertical_S-coordinate]\n", + "\n", + "In short, for `Vtransform==2` as used in this example, \n", + "\n", + "$Z_0 = (h_c \\, S + h \\,C) / (h_c + h)$\n", + "\n", + "$z = Z_0 (\\zeta + h) + \\zeta$\n", + "\n", + "where the variables are defined as in the link above." ] }, { @@ -112,6 +131,13 @@ "ds.salt.isel(xi_rho=50, ocean_time=0).plot()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can feed coordinate information to the plot method to give a more informative cross-section that uses the depths. Note that we did not need to slice the depth or longitude information separately, this was done automatically as the variable was sliced." + ] + }, { "cell_type": "code", "execution_count": null, @@ -129,7 +155,7 @@ "source": [ "### A plan view\n", "\n", - "Now make a naive plan view, without any projection information, just using lon/lat as x/y." + "Now make a naive plan view, without any projection information, just using lon/lat as x/y. This looks OK, but will appear compressed because lon and lat do not have an aspect constrained by the projection." ] }, { @@ -189,7 +215,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.6.7" } }, "nbformat": 4, From cec02411be51181cbd750899ba08712ee763d991 Mon Sep 17 00:00:00 2001 From: hetland Date: Tue, 30 Jul 2019 14:55:26 -0500 Subject: [PATCH 8/9] fixed colormap issues leftover from cmocean import --- doc/examples/ROMS_ocean_model.ipynb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/doc/examples/ROMS_ocean_model.ipynb b/doc/examples/ROMS_ocean_model.ipynb index d53b2bb80e5..fa8192f4f59 100644 --- a/doc/examples/ROMS_ocean_model.ipynb +++ b/doc/examples/ROMS_ocean_model.ipynb @@ -18,7 +18,6 @@ "import cartopy.feature as cfeature\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline\n", - "# import cmocean # TODO: Add this dependency to the docs\n", "\n", "import xarray as xr" ] @@ -145,7 +144,7 @@ "outputs": [], "source": [ "section = ds.salt.isel(xi_rho=50, eta_rho=slice(0, 167), ocean_time=0)\n", - "section.plot(x='lon_rho', y='z_rho', figsize=(15, 6), cmap=cmocean.cm.haline, clim=(25, 35))\n", + "section.plot(x='lon_rho', y='z_rho', figsize=(15, 6), clim=(25, 35))\n", "plt.ylim([-100, 1]);" ] }, @@ -184,7 +183,7 @@ "fig = plt.figure(figsize=(15, 5))\n", "ax = plt.axes(projection=proj)\n", "ds.salt.isel(s_rho=-1, ocean_time=0).plot(x='lon_rho', y='lat_rho', \n", - " cmap=cmocean.cm.haline, transform=ccrs.PlateCarree())\n", + " transform=ccrs.PlateCarree())\n", "\n", "coast_10m = cfeature.NaturalEarthFeature('physical', 'land', '10m',\n", " edgecolor='k', facecolor='0.8')\n", From 37cbae75e5f60734fc90269f8d2f5a962e4f9170 Mon Sep 17 00:00:00 2001 From: hetland Date: Fri, 2 Aug 2019 14:27:07 -0500 Subject: [PATCH 9/9] Added intro paragraph to ROMS example notebook, removed comments, and added citation in whats-new. --- doc/examples/ROMS_ocean_model.ipynb | 14 +++++++++----- doc/whats-new.rst | 5 +++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/doc/examples/ROMS_ocean_model.ipynb b/doc/examples/ROMS_ocean_model.ipynb index fa8192f4f59..74536bbe28f 100644 --- a/doc/examples/ROMS_ocean_model.ipynb +++ b/doc/examples/ROMS_ocean_model.ipynb @@ -7,6 +7,15 @@ "# ROMS Ocean Model Example" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The Regional Ocean Modeling System ([ROMS](http://myroms.org)) is an open source hydrodynamic model that is used for simulating currents and water properties in coastal and estuarine regions. ROMS is one of a few standard ocean models, and it has an active user community.\n", + "\n", + "ROMS uses a regular C-Grid in the horizontal, similar to other structured grid ocean and atmospheric models, and a stretched vertical coordinate (see [the ROMS documentation](https://www.myroms.org/wiki/Vertical_S-coordinate) for more details). Both of these require special treatment when using `xarray` to analyze ROMS ocean model output. This example notebook shows how to create a lazily evaluated vertical coordinate, and make some basic plots. The `xgcm` package is required to do analysis that is aware of the horizontal C-Grid." + ] + }, { "cell_type": "code", "execution_count": null, @@ -97,16 +106,11 @@ "if ds.Vtransform == 1:\n", " Zo_rho = ds.hc * (ds.s_rho - ds.Cs_r) + ds.Cs_r * ds.h\n", " z_rho = Zo_rho + ds.zeta * (1 + Zo_rho/ds.h)\n", - "# Zo_w = ds.hc * (ds.s_w - ds.Cs_w) + ds.Cs_w * ds.h\n", - "# z_w = Zo_w + ds.zeta * (1 + Zo_w/ds.h)\n", "elif ds.Vtransform == 2:\n", " Zo_rho = (ds.hc * ds.s_rho + ds.Cs_r * ds.h) / (ds.hc + ds.h)\n", " z_rho = ds.zeta + (ds.zeta + ds.h) * Zo_rho\n", - "# Zo_w = (ds.hc * ds.s_w + ds.Cs_w * ds.h) / (ds.hc + ds.h)\n", - "# z_w = ds.zeta + (ds.zeta + ds.h) * Zo_w\n", "\n", "ds.coords['z_rho'] = z_rho.transpose() # needing transpose seems to be an xarray bug\n", - "# ds.coords['z_w'] = z_w.transpose()\n", "ds.salt" ] }, diff --git a/doc/whats-new.rst b/doc/whats-new.rst index a1b3e5416ca..93cc0fa8d91 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -24,6 +24,11 @@ New functions/methods Enhancements ~~~~~~~~~~~~ +- Added example notebook demonstrating use of xarray with Regional Ocean + Modeling System (ROMS) ocean hydrodynamic model output. + (:issue:`3116`). + By `Robert Hetland ` + Bug fixes ~~~~~~~~~