import xarray as xr
import numpy as np
import dask
import intake
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
from pathlib import Path
import os
Run the cell below if the notebook is running on a supercomputer with a PBS Scheduler.
If the notebook is running on a different parallel computing environment, you will need
to replace the usage of PBSCluster
with a similar object from dask_jobqueue
or dask_gateway
.
from dask_jobqueue import PBSCluster
num_jobs = 20
walltime = '0:20:00'
memory='10GB'
cluster = PBSCluster(cores=1, processes=1, walltime=walltime, memory=memory, queue='casper',
resource_spec='select=1:ncpus=1:mem=10GB',)
cluster.scale(jobs=num_jobs)
from distributed import Client
client = Client(cluster)
cluster
# Define the catalog description file location
catalog_url = "https://ncar-dart-cam6.s3-us-west-2.amazonaws.com/catalogs/aws-dart-cam6.json"
# Open the catalog
col = intake.open_esm_datastore(catalog_url)
col
aws-dart-cam6 catalog with 11 dataset(s) from 11 asset(s):
unique | |
---|---|
variable | 11 |
long_name | 11 |
units | 6 |
standard_name | 10 |
vertical_levels | 2 |
component | 2 |
spatial_domain | 1 |
start_time | 2 |
end_time | 2 |
frequency | 2 |
path | 11 |
# Produce a catalog content summary.
import pprint
uniques = col.unique(
columns=["variable"]
)
pprint.pprint(uniques, compact=True, indent=4)
{ 'variable': { 'count': 11, 'values': [ 'HR', 'PS', 'TSA', 'EFLX_LH_TOT', 'CLDLIQ', 'US', 'ER', 'VS', 'T', 'Q', 'CLDICE']}}
data_var = 'PS'
col_subset = col.search(variable=data_var)
col_subset
aws-dart-cam6 catalog with 1 dataset(s) from 1 asset(s):
unique | |
---|---|
variable | 1 |
long_name | 1 |
units | 1 |
standard_name | 1 |
vertical_levels | 1 |
component | 1 |
spatial_domain | 1 |
start_time | 1 |
end_time | 1 |
frequency | 1 |
path | 1 |
col_subset.df
variable | long_name | units | standard_name | vertical_levels | component | spatial_domain | start_time | end_time | frequency | path | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | PS | Surface pressure | Pa | surface_air_pressure | 1 | atm | global | 2011-01-03T00:00:00 | 2019-12-30T00:00:00 | weekly | s3://ncar-dart-cam6/weekly/PS.zarr |
dsets = col_subset.to_dataset_dict(
zarr_kwargs={"consolidated": True}, storage_options={"anon": True}
)
print(f"\nDataset dictionary keys:\n {dsets.keys()}")
# Load the first dataset and display a summary.
dataset_key = list(dsets.keys())[0]
ds = dsets[dataset_key]
ds
--> The keys in the returned dictionary of datasets are constructed as follows: 'variable.frequency.component.vertical_levels'
Dataset dictionary keys: dict_keys(['PS.weekly.atm.1'])
<xarray.Dataset> Dimensions: (member_id: 80, time: 471, lat: 192, lon: 288, ilev: 33, lev: 32, slat: 191, slon: 288) Coordinates: * ilev (ilev) float32 2.255 5.032 10.16 18.56 ... 967.5 985.1 1e+03 * lat (lat) float32 -90.0 -89.06 -88.12 -87.17 ... 88.12 89.06 90.0 * lev (lev) float32 3.643 7.595 14.36 24.61 ... 936.2 957.5 976.3 992.6 * lon (lon) float32 0.0 1.25 2.5 3.75 5.0 ... 355.0 356.2 357.5 358.8 * member_id (member_id) int64 1 2 3 4 5 6 7 8 9 ... 73 74 75 76 77 78 79 80 * slat (slat) float32 -89.53 -88.59 -87.64 -86.7 ... 87.64 88.59 89.53 * slon (slon) float32 -0.625 0.625 1.875 3.125 ... 355.6 356.9 358.1 * time (time) datetime64[ns] 2011-01-03 2011-01-10 ... 2019-12-30 Data variables: PS (member_id, time, lat, lon) float64 dask.array<chunksize=(80, 80, 32, 32), meta=np.ndarray> Attributes: (12/16) DART_creation_date: YYYY MM DD HH MM SS = 2019 07 10 01 31 17 DART_revdate: $Date: 2019-03-26 09:18:06 -0600 (Tue, 26 Mar 20... DART_revision: $Revision: 13074 $ DART_source: $URL: https://svn-dares-dart.cgd.ucar.edu/DART/b... creation_date: YYYY MM DD HH MM SS = 2019 07 10 01 31 17 dataset-zarr-version: 1.0 ... ... model: CAM model_revdate: $Date: 2019-03-26 09:18:06 -0600 (Tue, 26 Mar 20... model_revision: $Revision: 13074 $ model_source: $URL: https://svn-dares-dart.cgd.ucar.edu/DART/b... intake_esm_varname: ['PS'] intake_esm_dataset_key: PS.weekly.atm.1
array([ 2.255239, 5.031692, 10.157948, 18.555317, 29.734676, 39.273003, 47.1145 , 56.240498, 66.8005 , 80.701416, 94.94104 , 111.693214, 131.40128 , 154.5868 , 181.86336 , 213.95282 , 251.70442 , 296.11722 , 348.36658 , 409.8352 , 482.14993 , 567.2244 , 652.33295 , 730.44586 , 796.3631 , 845.35364 , 873.7159 , 900.32465 , 924.9645 , 947.4323 , 967.53864 , 985.1122 , 1000. ], dtype=float32)
array([-90. , -89.057594, -88.11518 , -87.172775, -86.23037 , -85.28796 , -84.34555 , -83.403145, -82.46073 , -81.518326, -80.57591 , -79.63351 , -78.6911 , -77.74869 , -76.80628 , -75.86388 , -74.92146 , -73.97906 , -73.03665 , -72.09424 , -71.15183 , -70.20943 , -69.26701 , -68.32461 , -67.3822 , -66.43979 , -65.49738 , -64.55498 , -63.612564, -62.67016 , -61.72775 , -60.78534 , -59.842934, -58.900524, -57.958115, -57.015705, -56.0733 , -55.13089 , -54.18848 , -53.246075, -52.303665, -51.361256, -50.41885 , -49.47644 , -48.53403 , -47.59162 , -46.649216, -45.706806, -44.764397, -43.82199 , -42.87958 , -41.937172, -40.994766, -40.052357, -39.109947, -38.167538, -37.225132, -36.282722, -35.340313, -34.397907, -33.455498, -32.51309 , -31.57068 , -30.628273, -29.685863, -28.743456, -27.801046, -26.858639, -25.916231, -24.973822, -24.031414, -23.089005, -22.146597, -21.20419 , -20.26178 , -19.319372, -18.376963, -17.434555, -16.492147, -15.549738, -14.607329, -13.664922, -12.722513, -11.780105, -10.837696, -9.895288, -8.95288 , -8.010471, -7.068063, -6.125654, -5.183246, -4.240838, -3.298429, -2.356021, -1.413613, -0.471204, 0.471204, 1.413613, 2.356021, 3.298429, 4.240838, 5.183246, 6.125654, 7.068063, 8.010471, 8.95288 , 9.895288, 10.837696, 11.780105, 12.722513, 13.664922, 14.607329, 15.549738, 16.492147, 17.434555, 18.376963, 19.319372, 20.26178 , 21.20419 , 22.146597, 23.089005, 24.031414, 24.973822, 25.916231, 26.858639, 27.801046, 28.743456, 29.685863, 30.628273, 31.57068 , 32.51309 , 33.455498, 34.397907, 35.340313, 36.282722, 37.225132, 38.167538, 39.109947, 40.052357, 40.994766, 41.937172, 42.87958 , 43.82199 , 44.764397, 45.706806, 46.649216, 47.59162 , 48.53403 , 49.47644 , 50.41885 , 51.361256, 52.303665, 53.246075, 54.18848 , 55.13089 , 56.0733 , 57.015705, 57.958115, 58.900524, 59.842934, 60.78534 , 61.72775 , 62.67016 , 63.612564, 64.55498 , 65.49738 , 66.43979 , 67.3822 , 68.32461 , 69.26701 , 70.20943 , 71.15183 , 72.09424 , 73.03665 , 73.97906 , 74.92146 , 75.86388 , 76.80628 , 77.74869 , 78.6911 , 79.63351 , 80.57591 , 81.518326, 82.46073 , 83.403145, 84.34555 , 85.28796 , 86.23037 , 87.172775, 88.11518 , 89.057594, 90. ], dtype=float32)
array([ 3.643466, 7.59482 , 14.356632, 24.61222 , 35.92325 , 43.19375 , 51.677498, 61.520496, 73.75096 , 87.82123 , 103.31712 , 121.54724 , 142.99403 , 168.22508 , 197.90808 , 232.82861 , 273.91083 , 322.2419 , 379.1009 , 445.99258 , 524.6872 , 609.7787 , 691.3894 , 763.4045 , 820.8584 , 859.5348 , 887.02026 , 912.64453 , 936.1984 , 957.4855 , 976.3254 , 992.5561 ], dtype=float32)
array([ 0. , 1.25, 2.5 , ..., 356.25, 357.5 , 358.75], dtype=float32)
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80])
array([-89.52879 , -88.58639 , -87.64398 , -86.70157 , -85.75916 , -84.81676 , -83.874344, -82.93194 , -81.98953 , -81.04712 , -80.10471 , -79.1623 , -78.219894, -77.27749 , -76.335075, -75.39267 , -74.450264, -73.50785 , -72.565445, -71.62304 , -70.680626, -69.73822 , -68.795815, -67.8534 , -66.910995, -65.96859 , -65.02618 , -64.08377 , -63.14136 , -62.19895 , -61.256546, -60.314137, -59.371727, -58.429317, -57.48691 , -56.544502, -55.602093, -54.659687, -53.717278, -52.774868, -51.832462, -50.890053, -49.947643, -49.005234, -48.062828, -47.12042 , -46.17801 , -45.235603, -44.293194, -43.350784, -42.40838 , -41.46597 , -40.52356 , -39.58115 , -38.638744, -37.696335, -36.753925, -35.81152 , -34.86911 , -33.9267 , -32.984295, -32.041885, -31.099476, -30.157068, -29.214659, -28.272251, -27.329844, -26.387434, -25.445026, -24.502617, -23.56021 , -22.617802, -21.675392, -20.732985, -19.790575, -18.848167, -17.90576 , -16.96335 , -16.020943, -15.078534, -14.136126, -13.193717, -12.251308, -11.308901, -10.366492, -9.424084, -8.481675, -7.539267, -6.596859, -5.65445 , -4.712042, -3.769634, -2.827225, -1.884817, -0.942408, 0. , 0.942408, 1.884817, 2.827225, 3.769634, 4.712042, 5.65445 , 6.596859, 7.539267, 8.481675, 9.424084, 10.366492, 11.308901, 12.251308, 13.193717, 14.136126, 15.078534, 16.020943, 16.96335 , 17.90576 , 18.848167, 19.790575, 20.732985, 21.675392, 22.617802, 23.56021 , 24.502617, 25.445026, 26.387434, 27.329844, 28.272251, 29.214659, 30.157068, 31.099476, 32.041885, 32.984295, 33.9267 , 34.86911 , 35.81152 , 36.753925, 37.696335, 38.638744, 39.58115 , 40.52356 , 41.46597 , 42.40838 , 43.350784, 44.293194, 45.235603, 46.17801 , 47.12042 , 48.062828, 49.005234, 49.947643, 50.890053, 51.832462, 52.774868, 53.717278, 54.659687, 55.602093, 56.544502, 57.48691 , 58.429317, 59.371727, 60.314137, 61.256546, 62.19895 , 63.14136 , 64.08377 , 65.02618 , 65.96859 , 66.910995, 67.8534 , 68.795815, 69.73822 , 70.680626, 71.62304 , 72.565445, 73.50785 , 74.450264, 75.39267 , 76.335075, 77.27749 , 78.219894, 79.1623 , 80.10471 , 81.04712 , 81.98953 , 82.93194 , 83.874344, 84.81676 , 85.75916 , 86.70157 , 87.64398 , 88.58639 , 89.52879 ], dtype=float32)
array([ -0.625, 0.625, 1.875, ..., 355.625, 356.875, 358.125], dtype=float32)
array(['2011-01-03T00:00:00.000000000', '2011-01-10T00:00:00.000000000', '2011-01-17T00:00:00.000000000', ..., '2019-12-16T00:00:00.000000000', '2019-12-23T00:00:00.000000000', '2019-12-30T00:00:00.000000000'], dtype='datetime64[ns]')
|
def getSlice(ds, data_var):
'''If the data has vertical levels, choose the level closest
to the Earth's surface for 2-D diagnostic plots.
'''
data_slice = ds[data_var]
if 'lev' in data_slice.dims:
lastLevel = ds.lev.values[-1]
data_slice = data_slice.sel(lev = lastLevel)
data_slice = data_slice.squeeze()
return data_slice
def getSpatialDimensionNames(data_slice):
'''Get the spatial dimension names for this data slice.
'''
# Determine lat/lon conventions for this slice.
lat_dim = 'lat' if 'lat' in data_slice.dims else 'slat'
lon_dim = 'lon' if 'lon' in data_slice.dims else 'slon'
return [lat_dim, lon_dim]
def plot_timeseries(ds, data_var, store_name):
'''Create a spaghetti plot for a given variable.
'''
figWidth = 25
figHeight = 20
linewidth = 0.5
numPlotsPerPage = 3
numPlotCols = 1
# Plot the aggregate statistics across time.
fig, axs = plt.subplots(3, 1, figsize=(figWidth, figHeight))
data_slice = getSlice(ds, data_var)
spatial_dims = getSpatialDimensionNames(data_slice)
unit_string = ds[data_var].attrs['units']
# Persist the slice so it's read from disk only once.
# This is faster when data values are reused many times.
data_slice = data_slice.persist()
max_vals = data_slice.max(dim = spatial_dims).transpose()
mean_vals = data_slice.mean(dim = spatial_dims).transpose()
min_vals = data_slice.min(dim = spatial_dims).transpose()
rangeMaxs = max_vals.max(dim = 'member_id')
rangeMins = max_vals.min(dim = 'member_id')
axs[0].set_facecolor('lightgrey')
axs[0].fill_between(ds.time, rangeMins, rangeMaxs, linewidth=linewidth, color='white')
axs[0].plot(ds.time, max_vals, linewidth=linewidth, color='red', alpha=0.1)
axs[0].set_title('Ensemble Member Maxima Over Time', fontsize=20)
axs[0].set_ylabel(unit_string)
rangeMaxs = mean_vals.max(dim = 'member_id')
rangeMins = mean_vals.min(dim = 'member_id')
axs[1].set_facecolor('lightgrey')
axs[1].fill_between(ds.time, rangeMins, rangeMaxs, linewidth=linewidth, color='white')
axs[1].plot(ds.time, mean_vals, linewidth=linewidth, color='red', alpha=0.1)
axs[1].set_title('Ensemble Member Means Over Time', fontsize=20)
axs[1].set_ylabel(unit_string)
rangeMaxs = min_vals.max(dim = 'member_id')
rangeMins = min_vals.min(dim = 'member_id')
axs[2].set_facecolor('lightgrey')
axs[2].fill_between(ds.time, rangeMins, rangeMaxs, linewidth=linewidth, color='white')
axs[2].plot(ds.time, min_vals, linewidth=linewidth, color='red', alpha=0.1)
axs[2].set_title('Ensemble Member Minima Over Time', fontsize=20)
axs[2].set_ylabel(unit_string)
plt.suptitle(store_name, fontsize=25)
return fig
%%time
store_name = f'{data_var}.zarr'
fig = plot_timeseries(ds, data_var, store_name)
CPU times: user 8.08 s, sys: 230 ms, total: 8.31 s Wall time: 34.4 s
To download the figure plot file:
fig.savefig(f'{data_var}.zarr.pdf', facecolor='white', dpi=200)
cluster.close()