Skip to content

Commit 79aa804

Browse files
hetlandrabernat
authored andcommitted
Added ROMS ocean model example notebook (#3116)
* change name of test env to xarray-tests (#3110) * ROMS_ocean_model example added * Allow other tutorial filename extensions (#3121) * switching out examples to use nbsphinx * added jupyter_client to doc env * allow non netcdf tutorial files * Changed load to xr.tutorial.open_dataset(), and added some extra documentation. * change name of test env to xarray-tests (#3110) * ROMS_ocean_model example added * Changed load to xr.tutorial.open_dataset(), and added some extra documentation. * fixed colormap issues leftover from cmocean import * Added intro paragraph to ROMS example notebook, removed comments, and added citation in whats-new.
1 parent 5df8a42 commit 79aa804

File tree

12 files changed

+248
-16
lines changed

12 files changed

+248
-16
lines changed

azure-pipelines.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ jobs:
6464
steps:
6565
- template: ci/azure/install.yml
6666
- bash: |
67-
source activate test_env
67+
source activate xarray-tests
6868
mypy . || exit 0
6969
displayName: mypy type checks
7070
@@ -76,7 +76,7 @@ jobs:
7676
parameters:
7777
env_file: doc/environment.yml
7878
- bash: |
79-
source activate test_env
79+
source activate xarray-tests
8080
cd doc
8181
sphinx-build -n -j auto -b html -d _build/doctrees . _build/html
8282
displayName: Build HTML docs
@@ -89,6 +89,6 @@ jobs:
8989
steps:
9090
- template: ci/azure/install.yml
9191
- bash: |
92-
source activate test_env
92+
source activate xarray-tests
9393
pytest properties
9494
displayName: Property based tests

ci/azure/install.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ steps:
66
- template: add-conda-to-path.yml
77

88
- bash: |
9-
conda env create -n test_env --file ${{ parameters.env_file }}
9+
conda env create -n xarray-tests --file ${{ parameters.env_file }}
1010
displayName: Install conda dependencies
1111

1212
- bash: |
13-
source activate test_env
13+
source activate xarray-tests
1414
pip install -f https://7933911d6844c6c53a7d-47bd50c35cd79bd838daf386af554a83.ssl.cf2.rackcdn.com \
1515
--no-deps \
1616
--pre \
@@ -29,12 +29,12 @@ steps:
2929
displayName: Install upstream dev dependencies
3030

3131
- bash: |
32-
source activate test_env
32+
source activate xarray-tests
3333
pip install --no-deps -e .
3434
displayName: Install xarray
3535

3636
- bash: |
37-
source activate test_env
37+
source activate xarray-tests
3838
conda info -a
3939
conda list
4040
python xarray/util/print_versions.py

ci/azure/unit-tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ steps:
33
- template: install.yml
44

55
- bash: |
6-
source activate test_env
6+
source activate xarray-tests
77
python -OO -c "import xarray"
88
displayName: Import xarray
99

1010
# Work around for allowed test failures:
1111
# https://github.com/microsoft/azure-pipelines-tasks/issues/9302
1212
- bash: |
13-
source activate test_env
13+
source activate xarray-tests
1414
pytest xarray \
1515
--junitxml=junit/test-results.xml \
1616
--cov=xarray \

ci/requirements/py35-min.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: test_env
1+
name: xarray-tests
22
dependencies:
33
- python=3.5.0
44
- pytest

ci/requirements/py36-hypothesis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: test_env
1+
name: xarray-tests
22
channels:
33
- conda-forge
44
dependencies:

ci/requirements/py36.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: test_env
1+
name: xarray-tests
22
channels:
33
- conda-forge
44
dependencies:

ci/requirements/py37-windows.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: test_env
1+
name: xarray-tests
22
channels:
33
- conda-forge
44
dependencies:

ci/requirements/py37.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: test_env
1+
name: xarray-tests
22
channels:
33
- conda-forge
44
dependencies:

doc/contributing.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,10 @@ We'll now kick off a two-step process:
152152
153153
# Create and activate the build environment
154154
conda env create -f ci/requirements/py36.yml
155-
conda activate test_env
155+
conda activate xarray-tests
156156
157157
# or with older versions of Anaconda:
158-
source activate test_env
158+
source activate xarray-tests
159159
160160
# Build and install xarray
161161
pip install -e .

doc/examples.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ Examples
88
examples/monthly-means
99
examples/multidimensional-coords
1010
examples/visualization_gallery
11+
examples/ROMS_ocean_model

doc/examples/ROMS_ocean_model.ipynb

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# ROMS Ocean Model Example"
8+
]
9+
},
10+
{
11+
"cell_type": "markdown",
12+
"metadata": {},
13+
"source": [
14+
"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",
15+
"\n",
16+
"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."
17+
]
18+
},
19+
{
20+
"cell_type": "code",
21+
"execution_count": null,
22+
"metadata": {},
23+
"outputs": [],
24+
"source": [
25+
"import numpy as np\n",
26+
"import cartopy.crs as ccrs\n",
27+
"import cartopy.feature as cfeature\n",
28+
"import matplotlib.pyplot as plt\n",
29+
"%matplotlib inline\n",
30+
"\n",
31+
"import xarray as xr"
32+
]
33+
},
34+
{
35+
"cell_type": "markdown",
36+
"metadata": {},
37+
"source": [
38+
"Load a sample ROMS file. This is a subset of a full model available at \n",
39+
"\n",
40+
" http://barataria.tamu.edu/thredds/catalog.html?dataset=txla_hindcast_agg\n",
41+
" \n",
42+
"The subsetting was done using the following command on one of the output files:\n",
43+
"\n",
44+
" #open dataset\n",
45+
" ds = xr.open_dataset('/d2/shared/TXLA_ROMS/output_20yr_obc/2001/ocean_his_0015.nc')\n",
46+
" \n",
47+
" # Turn on chunking to activate dask and parallelize read/write.\n",
48+
" ds = ds.chunk({'ocean_time': 1})\n",
49+
" \n",
50+
" # Pick out some of the variables that will be included as coordinates\n",
51+
" ds = ds.set_coords(['Cs_r', 'Cs_w', 'hc', 'h', 'Vtransform'])\n",
52+
" \n",
53+
" # Select a a subset of variables. Salt will be visualized, zeta is used to \n",
54+
" # calculate the vertical coordinate\n",
55+
" variables = ['salt', 'zeta']\n",
56+
" ds[variables].isel(ocean_time=slice(47, None, 7*24), \n",
57+
" xi_rho=slice(300, None)).to_netcdf('ROMS_example.nc', mode='w')\n",
58+
"\n",
59+
"So, the `ROMS_example.nc` file contains a subset of the grid, one 3D variable, and two time steps."
60+
]
61+
},
62+
{
63+
"cell_type": "markdown",
64+
"metadata": {},
65+
"source": [
66+
"### Load in ROMS dataset as an xarray object"
67+
]
68+
},
69+
{
70+
"cell_type": "code",
71+
"execution_count": null,
72+
"metadata": {},
73+
"outputs": [],
74+
"source": [
75+
"# load in the file\n",
76+
"ds = xr.tutorial.open_dataset('ROMS_example.nc', chunks={'ocean_time': 1})\n",
77+
"\n",
78+
"# This is a way to turn on chunking and lazy evaluation. Opening with mfdataset, or \n",
79+
"# setting the chunking in the open_dataset would also achive this.\n",
80+
"ds"
81+
]
82+
},
83+
{
84+
"cell_type": "markdown",
85+
"metadata": {},
86+
"source": [
87+
"### Add a lazilly calculated vertical coordinates\n",
88+
"\n",
89+
"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",
90+
"\n",
91+
"In short, for `Vtransform==2` as used in this example, \n",
92+
"\n",
93+
"$Z_0 = (h_c \\, S + h \\,C) / (h_c + h)$\n",
94+
"\n",
95+
"$z = Z_0 (\\zeta + h) + \\zeta$\n",
96+
"\n",
97+
"where the variables are defined as in the link above."
98+
]
99+
},
100+
{
101+
"cell_type": "code",
102+
"execution_count": null,
103+
"metadata": {},
104+
"outputs": [],
105+
"source": [
106+
"if ds.Vtransform == 1:\n",
107+
" Zo_rho = ds.hc * (ds.s_rho - ds.Cs_r) + ds.Cs_r * ds.h\n",
108+
" z_rho = Zo_rho + ds.zeta * (1 + Zo_rho/ds.h)\n",
109+
"elif ds.Vtransform == 2:\n",
110+
" Zo_rho = (ds.hc * ds.s_rho + ds.Cs_r * ds.h) / (ds.hc + ds.h)\n",
111+
" z_rho = ds.zeta + (ds.zeta + ds.h) * Zo_rho\n",
112+
"\n",
113+
"ds.coords['z_rho'] = z_rho.transpose() # needing transpose seems to be an xarray bug\n",
114+
"ds.salt"
115+
]
116+
},
117+
{
118+
"cell_type": "markdown",
119+
"metadata": {},
120+
"source": [
121+
"### A naive vertical slice\n",
122+
"\n",
123+
"Create a slice using the s-coordinate as the vertical dimension is typically not very informative."
124+
]
125+
},
126+
{
127+
"cell_type": "code",
128+
"execution_count": null,
129+
"metadata": {
130+
"scrolled": false
131+
},
132+
"outputs": [],
133+
"source": [
134+
"ds.salt.isel(xi_rho=50, ocean_time=0).plot()"
135+
]
136+
},
137+
{
138+
"cell_type": "markdown",
139+
"metadata": {},
140+
"source": [
141+
"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."
142+
]
143+
},
144+
{
145+
"cell_type": "code",
146+
"execution_count": null,
147+
"metadata": {},
148+
"outputs": [],
149+
"source": [
150+
"section = ds.salt.isel(xi_rho=50, eta_rho=slice(0, 167), ocean_time=0)\n",
151+
"section.plot(x='lon_rho', y='z_rho', figsize=(15, 6), clim=(25, 35))\n",
152+
"plt.ylim([-100, 1]);"
153+
]
154+
},
155+
{
156+
"cell_type": "markdown",
157+
"metadata": {},
158+
"source": [
159+
"### A plan view\n",
160+
"\n",
161+
"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."
162+
]
163+
},
164+
{
165+
"cell_type": "code",
166+
"execution_count": null,
167+
"metadata": {},
168+
"outputs": [],
169+
"source": [
170+
"ds.salt.isel(s_rho=-1, ocean_time=0).plot(x='lon_rho', y='lat_rho')"
171+
]
172+
},
173+
{
174+
"cell_type": "markdown",
175+
"metadata": {},
176+
"source": [
177+
"And let's use a projection to make it nicer, and add a coast."
178+
]
179+
},
180+
{
181+
"cell_type": "code",
182+
"execution_count": null,
183+
"metadata": {},
184+
"outputs": [],
185+
"source": [
186+
"proj = ccrs.LambertConformal(central_longitude=-92, central_latitude=29)\n",
187+
"fig = plt.figure(figsize=(15, 5))\n",
188+
"ax = plt.axes(projection=proj)\n",
189+
"ds.salt.isel(s_rho=-1, ocean_time=0).plot(x='lon_rho', y='lat_rho', \n",
190+
" transform=ccrs.PlateCarree())\n",
191+
"\n",
192+
"coast_10m = cfeature.NaturalEarthFeature('physical', 'land', '10m',\n",
193+
" edgecolor='k', facecolor='0.8')\n",
194+
"ax.add_feature(coast_10m)"
195+
]
196+
},
197+
{
198+
"cell_type": "code",
199+
"execution_count": null,
200+
"metadata": {},
201+
"outputs": [],
202+
"source": []
203+
}
204+
],
205+
"metadata": {
206+
"kernelspec": {
207+
"display_name": "Python 3",
208+
"language": "python",
209+
"name": "python3"
210+
},
211+
"language_info": {
212+
"codemirror_mode": {
213+
"name": "ipython",
214+
"version": 3
215+
},
216+
"file_extension": ".py",
217+
"mimetype": "text/x-python",
218+
"name": "python",
219+
"nbconvert_exporter": "python",
220+
"pygments_lexer": "ipython3",
221+
"version": "3.6.7"
222+
}
223+
},
224+
"nbformat": 4,
225+
"nbformat_minor": 2
226+
}

doc/whats-new.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ New functions/methods
2424
Enhancements
2525
~~~~~~~~~~~~
2626

27+
- Added example notebook demonstrating use of xarray with Regional Ocean
28+
Modeling System (ROMS) ocean hydrodynamic model output.
29+
(:issue:`3116`).
30+
By `Robert Hetland <https://github.com/hetland>`
31+
2732
Bug fixes
2833
~~~~~~~~~
2934

0 commit comments

Comments
 (0)