MOM6/CESM Ocean Model AnalysisΒΆ

This notebook shows how to load and analyze ocean data from an out-of-the-box MOM6/CESM G-case simulation (coupled ocean ocean/sea ice).

NOTE: MOM6/CESM is not ready to be used for research.

[1]:
%matplotlib inline

import numpy as np
import xarray as xr
import matplotlib.pyplot as plt
import holoviews as hv
import datashader
from holoviews.operation.datashader import regrid, shade, datashade

hv.extension('bokeh', width=100)

Load MOM6/CESM DataΒΆ

This data is stored in xarray-zarr format in Google Cloud Storage. This format is optimized for parallel distributed reads from within the cloud environment.

The full data catalog is located here: https://pangeo-data.github.io/pangeo-datastore/master/ocean.html

[2]:
import intake
cat = intake.open_catalog("https://raw.githubusercontent.com/pangeo-data/pangeo-datastore/master/intake-catalogs/ocean.yaml")
ds = cat["cesm_mom6_example"].to_dask()
ds
/srv/conda/envs/notebook/lib/python3.9/site-packages/xarray/coding/times.py:527: SerializationWarning: Unable to decode time axis into full numpy.datetime64 objects, continuing using cftime.datetime objects instead, reason: dates out of range
  dtype = _decode_cf_datetime_dtype(data, units, calendar, self.use_cftime)
[2]:
<xarray.Dataset>
Dimensions:       (time: 24, z_l: 34, yh: 458, xh: 540, yq: 458, xq: 540, lath: 458, latq: 458, lonh: 540, lonq: 540, nv: 2, scalar_axis: 1, z_i: 35)
Coordinates: (12/17)
    geolat        (yh, xh) float64 dask.array<chunksize=(458, 540), meta=np.ndarray>
    geolatb       (yq, xq) float64 dask.array<chunksize=(458, 540), meta=np.ndarray>
    geolon        (yh, xh) float64 dask.array<chunksize=(458, 540), meta=np.ndarray>
    geolonb       (yq, xq) float64 dask.array<chunksize=(458, 540), meta=np.ndarray>
  * lath          (lath) float64 -79.2 -79.08 -78.95 ... 87.64 87.71 87.74
  * latq          (latq) float64 -79.14 -79.01 -78.89 ... 87.68 87.73 87.74
    ...            ...
  * xh            (xh) float64 -286.7 -286.0 -285.3 -284.7 ... 71.33 72.0 72.67
  * xq            (xq) float64 -286.3 -285.7 -285.0 -284.3 ... 71.67 72.33 73.0
  * yh            (yh) float64 -79.2 -79.08 -78.95 -78.82 ... 87.64 87.71 87.74
  * yq            (yq) float64 -79.14 -79.01 -78.89 -78.76 ... 87.68 87.73 87.74
  * z_i           (z_i) float64 0.0 5.0 15.0 25.0 ... 5.25e+03 5.75e+03 6.25e+03
  * z_l           (z_l) float64 2.5 10.0 20.0 32.5 ... 5e+03 5.5e+03 6e+03
Data variables: (12/23)
    KE            (time, z_l, yh, xh) float64 dask.array<chunksize=(1, 34, 458, 540), meta=np.ndarray>
    KPP_OBLdepth  (time, yh, xh) float64 dask.array<chunksize=(1, 458, 540), meta=np.ndarray>
    MLD_0125      (time, yh, xh) float64 dask.array<chunksize=(1, 458, 540), meta=np.ndarray>
    SSH           (time, yh, xh) float64 dask.array<chunksize=(1, 458, 540), meta=np.ndarray>
    SSS           (time, yh, xh) float64 dask.array<chunksize=(1, 458, 540), meta=np.ndarray>
    SST           (time, yh, xh) float64 dask.array<chunksize=(1, 458, 540), meta=np.ndarray>
    ...            ...
    tauy          (time, yq, xh) float64 dask.array<chunksize=(1, 458, 540), meta=np.ndarray>
    temp          (time, z_l, yh, xh) float64 dask.array<chunksize=(1, 34, 458, 540), meta=np.ndarray>
    thetaoga      (time, scalar_axis) float64 dask.array<chunksize=(1, 1), meta=np.ndarray>
    time_bnds     (time, nv) timedelta64[ns] dask.array<chunksize=(1, 2), meta=np.ndarray>
    u             (time, z_l, yh, xq) float64 dask.array<chunksize=(1, 34, 458, 540), meta=np.ndarray>
    v             (time, z_l, yq, xh) float64 dask.array<chunksize=(1, 34, 458, 540), meta=np.ndarray>
Attributes:
    associated_files:  area_t: g.c2b6.GNYF.T62_t061.melt_potential.003.mom6.s...
    filename:          g.c2b6.GNYF.T62_t061.melt_potential.003.mom6.h_0001_01.nc
    grid_tile:         N/A
    grid_type:         regular
    title:             MOM6 g.c2b6.GNYF.T62_t061.melt_potential.003 Experiment

Visualize SST Data with Holoviews and DatashaderΒΆ

The cells below show how to interactively explore the dataset.

[3]:
sst_ds = hv.Dataset(ds['SST'], kdims=['time', 'geolon', 'geolat'])
sst = sst_ds.to(hv.QuadMesh, kdims=["geolon", "geolat"], dynamic=True)
%opts RGB [width=900 height=600]
datashade(sst, precompute=True, cmap=plt.cm.RdBu_r)
[3]:

Visualize SSS Data with Holoviews and DatashaderΒΆ

[4]:
sss_ds = hv.Dataset(ds['SSS'], kdims=['time', 'geolon', 'geolat'])
sss = sst_ds.to(hv.QuadMesh, kdims=["geolon", "geolat"], dynamic=True)
%opts RGB [width=900 height=600]
datashade(sss, precompute=True, cmap=plt.cm.Spectral_r)
[4]:

Create and Connect to Dask Distributed ClusterΒΆ

This will launch a cluster of virtual machines in the cloud.

[5]:
from dask.distributed import Client
from dask_gateway import GatewayCluster
cluster = GatewayCluster()
cluster.adapt(minimum=1, maximum=10)
cluster
/srv/conda/envs/notebook/lib/python3.9/site-packages/dask_gateway/client.py:21: FutureWarning: format_bytes is deprecated and will be removed in a future release. Please use dask.utils.format_bytes instead.
  from distributed.utils import LoopRunner, format_bytes

πŸ‘† Don’t forget to click this link to get the cluster dashboard

[6]:
client = Client(cluster)
client
[6]:

Client

Client-6754ce0c-3289-11ec-81c4-c90a8b0f0827

Connection method: Cluster object Cluster type: dask_gateway.GatewayCluster
Dashboard: https://hub.binder.pangeo.io/services/dask-gateway/clusters/prod.94141fd55bf241a9859a77e0989273b3/status

Cluster Info

GatewayCluster

Data reductionΒΆ

Here we make a data reduction by taking the time of SST and SSS. This demonstrates how the cluster distributes the reads from storage.

[7]:
SST_mean = ds.SST.mean(dim=('time'))
SST_mean
[7]:
<xarray.DataArray 'SST' (yh: 458, xh: 540)>
dask.array<mean_agg-aggregate, shape=(458, 540), dtype=float64, chunksize=(458, 540), chunktype=numpy.ndarray>
Coordinates:
    geolat   (yh, xh) float64 dask.array<chunksize=(458, 540), meta=np.ndarray>
    geolon   (yh, xh) float64 dask.array<chunksize=(458, 540), meta=np.ndarray>
  * xh       (xh) float64 -286.7 -286.0 -285.3 -284.7 ... 70.67 71.33 72.0 72.67
  * yh       (yh) float64 -79.2 -79.08 -78.95 -78.82 ... 87.55 87.64 87.71 87.74
[8]:
SSS_mean = ds.SSS.mean(dim=('time'))
SSS_mean
[8]:
<xarray.DataArray 'SSS' (yh: 458, xh: 540)>
dask.array<mean_agg-aggregate, shape=(458, 540), dtype=float64, chunksize=(458, 540), chunktype=numpy.ndarray>
Coordinates:
    geolat   (yh, xh) float64 dask.array<chunksize=(458, 540), meta=np.ndarray>
    geolon   (yh, xh) float64 dask.array<chunksize=(458, 540), meta=np.ndarray>
  * xh       (xh) float64 -286.7 -286.0 -285.3 -284.7 ... 70.67 71.33 72.0 72.67
  * yh       (yh) float64 -79.2 -79.08 -78.95 -78.82 ... 87.55 87.64 87.71 87.74
[9]:
%time SST_mean.load()
CPU times: user 270 ms, sys: 126 ms, total: 395 ms
Wall time: 10.2 s
[9]:
<xarray.DataArray 'SST' (yh: 458, xh: 540)>
array([[nan, nan, nan, ..., nan, nan, nan],
       [nan, nan, nan, ..., nan, nan, nan],
       [nan, nan, nan, ..., nan, nan, nan],
       ...,
       [nan, nan, nan, ..., nan, nan, nan],
       [nan, nan, nan, ..., nan, nan, nan],
       [nan, nan, nan, ..., nan, nan, nan]])
Coordinates:
    geolat   (yh, xh) float64 -79.2 -79.2 -79.2 -79.2 ... 50.27 50.11 49.99
    geolon   (yh, xh) float64 -286.7 -286.0 -285.3 -284.7 ... 72.97 72.98 73.0
  * xh       (xh) float64 -286.7 -286.0 -285.3 -284.7 ... 70.67 71.33 72.0 72.67
  * yh       (yh) float64 -79.2 -79.08 -78.95 -78.82 ... 87.55 87.64 87.71 87.74
[10]:
# plot mean SST
qm = hv.QuadMesh((ds.geolon.values, ds.geolat.values, SST_mean))
datashade(qm, precompute=True, cmap=plt.cm.RdBu_r)
[10]:
[11]:
%time SSS_mean.load()
CPU times: user 19.9 ms, sys: 6.11 ms, total: 26 ms
Wall time: 1.37 s
[11]:
<xarray.DataArray 'SSS' (yh: 458, xh: 540)>
array([[nan, nan, nan, ..., nan, nan, nan],
       [nan, nan, nan, ..., nan, nan, nan],
       [nan, nan, nan, ..., nan, nan, nan],
       ...,
       [nan, nan, nan, ..., nan, nan, nan],
       [nan, nan, nan, ..., nan, nan, nan],
       [nan, nan, nan, ..., nan, nan, nan]])
Coordinates:
    geolat   (yh, xh) float64 -79.2 -79.2 -79.2 -79.2 ... 50.27 50.11 49.99
    geolon   (yh, xh) float64 -286.7 -286.0 -285.3 -284.7 ... 72.97 72.98 73.0
  * xh       (xh) float64 -286.7 -286.0 -285.3 -284.7 ... 70.67 71.33 72.0 72.67
  * yh       (yh) float64 -79.2 -79.08 -78.95 -78.82 ... 87.55 87.64 87.71 87.74
[12]:
# plot mean SSS
qm = hv.QuadMesh((ds.geolon.values, ds.geolat.values, SSS_mean))
datashade(qm, precompute=True, cmap=plt.cm.Spectral_r)
[12]:
[ ]: