Age at the Bottom of the Ocean¶
This notebook shows a simple example of plotting ocean Ideal Age. Ideal Age is a fictitious tracer which is set to zero in the surface grid-cell every timestep, and is aged by 1 year per year otherwise. It is a useful proxy for nutrients, such as carbon or oxygen (but not an exact analogue).
One of the interesting aspects of age is that we can use it to show pathways of the densest water in the ocean by plotting a map of age in the lowest grid cell. This plot requires a couple of tricks to extract information from the lowest cell.
Requirements: COSIMA Cookbook, preferably installed via the
conda/analysis3
conda installation on NCI.
Firstly, get all the standard preliminaries out of the way.
import cosima_cookbook as cc
import matplotlib.pyplot as plt
import xarray as xr
import cartopy.crs as ccrs
import cmocean as cm
import glob
import logging
logging.captureWarnings(True)
logging.getLogger('py.warnings').setLevel(logging.ERROR)
from dask.distributed import Client
Load some stuff to help with plotting
import cartopy.feature as cft
land_50m = cft.NaturalEarthFeature('physical', 'land', '50m',
edgecolor='face',
facecolor=cft.COLORS['land'])
client = Client(n_workers=4)
client
Client
|
Cluster
|
Add a database session. No database file has been specified so it will use the default database that indexes a number of COSIMA datasets
session = cc.database.create_session()
Now, let’s set the experiment and time interval, and average ideal age over a year.
expt = '01deg_jra55v13_ryf9091'
variable = 'age_global'
start_time = '2099-01-01'
end_time = '2099-12-31'
age = cc.querying.getvar(expt, variable, session, ncfile='ocean.nc',
start_time=start_time, end_time=end_time).sel(time=slice(start_time, end_time))
age
<xarray.DataArray 'age_global' (time: 12, st_ocean: 75, yt_ocean: 2700, xt_ocean: 3600)> dask.array<getitem, shape=(12, 75, 2700, 3600), dtype=float32, chunksize=(1, 7, 300, 400), chunktype=numpy.ndarray> Coordinates: * xt_ocean (xt_ocean) float64 -279.9 -279.8 -279.7 ... 79.75 79.85 79.95 * yt_ocean (yt_ocean) float64 -81.11 -81.07 -81.02 ... 89.89 89.94 89.98 * st_ocean (st_ocean) float64 0.5413 1.681 2.94 ... 5.511e+03 5.709e+03 * time (time) object 2099-01-16 12:00:00 ... 2099-12-16 12:00:00 Attributes: long_name: Age (global) units: yr valid_range: [0.e+00 1.e+20] cell_methods: time: mean time_avg_info: average_T1,average_T2,average_DT coordinates: geolon_t geolat_t standard_name: sea_water_age_since_surface_contact time_bounds: <xarray.DataArray 'time_bounds' (time: 15, nv: 2)>\ndask....
- time: 12
- st_ocean: 75
- yt_ocean: 2700
- xt_ocean: 3600
- dask.array<chunksize=(1, 7, 300, 400), meta=np.ndarray>
Array Chunk Bytes 32.59 GiB 3.20 MiB Shape (12, 75, 2700, 3600) (1, 7, 300, 400) Count 37427 Tasks 10692 Chunks Type float32 numpy.ndarray - xt_ocean(xt_ocean)float64-279.9 -279.8 ... 79.85 79.95
- long_name :
- tcell longitude
- units :
- degrees_E
- cartesian_axis :
- X
array([-279.95, -279.85, -279.75, ..., 79.75, 79.85, 79.95])
- yt_ocean(yt_ocean)float64-81.11 -81.07 ... 89.94 89.98
- long_name :
- tcell latitude
- units :
- degrees_N
- cartesian_axis :
- Y
array([-81.108632, -81.066392, -81.024153, ..., 89.894417, 89.936657, 89.978896])
- st_ocean(st_ocean)float640.5413 1.681 ... 5.709e+03
- long_name :
- tcell zstar depth
- units :
- meters
- cartesian_axis :
- Z
- positive :
- down
- edges :
- st_edges_ocean
array([5.412808e-01, 1.680735e+00, 2.939953e+00, 4.331521e+00, 5.869350e+00, 7.568810e+00, 9.446885e+00, 1.152234e+01, 1.381593e+01, 1.635055e+01, 1.915154e+01, 2.224687e+01, 2.566746e+01, 2.944746e+01, 3.362460e+01, 3.824057e+01, 4.334140e+01, 4.897796e+01, 5.520640e+01, 6.208874e+01, 6.969342e+01, 7.809601e+01, 8.737988e+01, 9.763700e+01, 1.089687e+02, 1.214869e+02, 1.353144e+02, 1.505868e+02, 1.674530e+02, 1.860765e+02, 2.066365e+02, 2.293296e+02, 2.543701e+02, 2.819920e+02, 3.124492e+02, 3.460166e+02, 3.829906e+02, 4.236883e+02, 4.684475e+02, 5.176242e+02, 5.715899e+02, 6.307275e+02, 6.954248e+02, 7.660668e+02, 8.430255e+02, 9.266482e+02, 1.017244e+03, 1.115068e+03, 1.220309e+03, 1.333076e+03, 1.453384e+03, 1.581154e+03, 1.716205e+03, 1.858264e+03, 2.006975e+03, 2.161913e+03, 2.322601e+03, 2.488533e+03, 2.659189e+03, 2.834054e+03, 3.012631e+03, 3.194453e+03, 3.379089e+03, 3.566145e+03, 3.755274e+03, 3.946166e+03, 4.138551e+03, 4.332197e+03, 4.526903e+03, 4.722497e+03, 4.918835e+03, 5.115794e+03, 5.313270e+03, 5.511177e+03, 5.709443e+03])
- time(time)object2099-01-16 12:00:00 ... 2099-12-...
- long_name :
- time
- cartesian_axis :
- T
- calendar_type :
- NOLEAP
- bounds :
- time_bounds
array([cftime.DatetimeNoLeap(2099, 1, 16, 12, 0, 0, 0), cftime.DatetimeNoLeap(2099, 2, 15, 0, 0, 0, 0), cftime.DatetimeNoLeap(2099, 3, 16, 12, 0, 0, 0), cftime.DatetimeNoLeap(2099, 4, 16, 0, 0, 0, 0), cftime.DatetimeNoLeap(2099, 5, 16, 12, 0, 0, 0), cftime.DatetimeNoLeap(2099, 6, 16, 0, 0, 0, 0), cftime.DatetimeNoLeap(2099, 7, 16, 12, 0, 0, 0), cftime.DatetimeNoLeap(2099, 8, 16, 12, 0, 0, 0), cftime.DatetimeNoLeap(2099, 9, 16, 0, 0, 0, 0), cftime.DatetimeNoLeap(2099, 10, 16, 12, 0, 0, 0), cftime.DatetimeNoLeap(2099, 11, 16, 0, 0, 0, 0), cftime.DatetimeNoLeap(2099, 12, 16, 12, 0, 0, 0)], dtype=object)
- long_name :
- Age (global)
- units :
- yr
- valid_range :
- [0.e+00 1.e+20]
- cell_methods :
- time: mean
- time_avg_info :
- average_T1,average_T2,average_DT
- coordinates :
- geolon_t geolat_t
- standard_name :
- sea_water_age_since_surface_contact
- time_bounds :
- <xarray.DataArray 'time_bounds' (time: 15, nv: 2)> dask.array<concatenate, shape=(15, 2), dtype=timedelta64[ns], chunksize=(1, 2), chunktype=numpy.ndarray> Coordinates: * time (time) object 2098-10-16 12:00:00 ... 2099-12-16 12:00:00 * nv (nv) float64 1.0 2.0 Attributes: long_name: time axis boundaries calendar: NOLEAP
age_mean = age.mean(dim='time').compute()
CPU times: user 31.8 s, sys: 6.47 s, total: 38.2 s
Wall time: 54.3 s
The age variable is a 3D variable. There are a number of ways to extract the value at the bottom of the ocean. This notebook outlines two ways this can be achieved: (i) using masking and using (ii) indexing.
In this case masking is much slower than indexing, but for some use cases this has been the opposite. The masking approach has the benefit of not requiring the depth grid information.
I. Masking approach¶
Create a mask of all the bottom cells. Can achieve this by taking the data, shift it up one cell in the vertical grid, find all non-NAN cells, and then negate this mask. Then mask the same data with with this mask, which will select out only the lowest level of non-NAN values in the data.
In a second step turn it into a boolean array for neatness.
bot_mask = age_mean.where(~xr.ufuncs.isfinite(age_mean.shift({'st_ocean':-1})))
bot_mask = ~xr.ufuncs.isnan(bot_mask)
bot_mask
<xarray.DataArray 'age_global' (st_ocean: 75, yt_ocean: 2700, xt_ocean: 3600)> array([[[False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], ..., [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False]], [[False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], ..., [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False]], [[False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], ..., ... ..., [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False]], [[False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], ..., [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False]], [[False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], ..., [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False]]]) Coordinates: * xt_ocean (xt_ocean) float64 -279.9 -279.8 -279.7 ... 79.75 79.85 79.95 * yt_ocean (yt_ocean) float64 -81.11 -81.07 -81.02 ... 89.89 89.94 89.98 * st_ocean (st_ocean) float64 0.5413 1.681 2.94 ... 5.511e+03 5.709e+03
- st_ocean: 75
- yt_ocean: 2700
- xt_ocean: 3600
- False False False False False False ... False False False False False
array([[[False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], ..., [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False]], [[False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], ..., [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False]], [[False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], ..., ... ..., [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False]], [[False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], ..., [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False]], [[False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], ..., [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False]]])
- xt_ocean(xt_ocean)float64-279.9 -279.8 ... 79.85 79.95
- long_name :
- tcell longitude
- units :
- degrees_E
- cartesian_axis :
- X
array([-279.95, -279.85, -279.75, ..., 79.75, 79.85, 79.95])
- yt_ocean(yt_ocean)float64-81.11 -81.07 ... 89.94 89.98
- long_name :
- tcell latitude
- units :
- degrees_N
- cartesian_axis :
- Y
array([-81.108632, -81.066392, -81.024153, ..., 89.894417, 89.936657, 89.978896])
- st_ocean(st_ocean)float640.5413 1.681 ... 5.709e+03
- long_name :
- tcell zstar depth
- units :
- meters
- cartesian_axis :
- Z
- positive :
- down
- edges :
- st_edges_ocean
array([5.412808e-01, 1.680735e+00, 2.939953e+00, 4.331521e+00, 5.869350e+00, 7.568810e+00, 9.446885e+00, 1.152234e+01, 1.381593e+01, 1.635055e+01, 1.915154e+01, 2.224687e+01, 2.566746e+01, 2.944746e+01, 3.362460e+01, 3.824057e+01, 4.334140e+01, 4.897796e+01, 5.520640e+01, 6.208874e+01, 6.969342e+01, 7.809601e+01, 8.737988e+01, 9.763700e+01, 1.089687e+02, 1.214869e+02, 1.353144e+02, 1.505868e+02, 1.674530e+02, 1.860765e+02, 2.066365e+02, 2.293296e+02, 2.543701e+02, 2.819920e+02, 3.124492e+02, 3.460166e+02, 3.829906e+02, 4.236883e+02, 4.684475e+02, 5.176242e+02, 5.715899e+02, 6.307275e+02, 6.954248e+02, 7.660668e+02, 8.430255e+02, 9.266482e+02, 1.017244e+03, 1.115068e+03, 1.220309e+03, 1.333076e+03, 1.453384e+03, 1.581154e+03, 1.716205e+03, 1.858264e+03, 2.006975e+03, 2.161913e+03, 2.322601e+03, 2.488533e+03, 2.659189e+03, 2.834054e+03, 3.012631e+03, 3.194453e+03, 3.379089e+03, 3.566145e+03, 3.755274e+03, 3.946166e+03, 4.138551e+03, 4.332197e+03, 4.526903e+03, 4.722497e+03, 4.918835e+03, 5.115794e+03, 5.313270e+03, 5.511177e+03, 5.709443e+03])
bottom_age = age_mean.where(bot_mask).sum(dim='st_ocean').compute()
CPU times: user 2.2 s, sys: 1.43 s, total: 3.64 s
Wall time: 3.43 s
bottom_age
<xarray.DataArray 'age_global' (yt_ocean: 2700, xt_ocean: 3600)> array([[0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], ..., [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.]], dtype=float32) Coordinates: * xt_ocean (xt_ocean) float64 -279.9 -279.8 -279.7 ... 79.75 79.85 79.95 * yt_ocean (yt_ocean) float64 -81.11 -81.07 -81.02 ... 89.89 89.94 89.98
- yt_ocean: 2700
- xt_ocean: 3600
- 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
array([[0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], ..., [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.]], dtype=float32)
- xt_ocean(xt_ocean)float64-279.9 -279.8 ... 79.85 79.95
- long_name :
- tcell longitude
- units :
- degrees_E
- cartesian_axis :
- X
array([-279.95, -279.85, -279.75, ..., 79.75, 79.85, 79.95])
- yt_ocean(yt_ocean)float64-81.11 -81.07 ... 89.94 89.98
- long_name :
- tcell latitude
- units :
- degrees_N
- cartesian_axis :
- Y
array([-81.108632, -81.066392, -81.024153, ..., 89.894417, 89.936657, 89.978896])
grid = xr.open_dataset('/g/data/ik11/grids/ocean_grid_01.nc')
geolon_t = grid.geolon_t
geolat_t = grid.geolat_t
fig = plt.figure(figsize=(10, 6))
ax = plt.axes(projection=ccrs.Robinson(central_longitude=-100))
ax.coastlines(resolution='50m')
ax.add_feature(land_50m, color='gray')
gl = ax.gridlines(draw_labels=False)
p1 = ax.pcolormesh(geolon_t, geolat_t, bottom_age, transform=ccrs.PlateCarree(),
cmap=cm.cm.matter, vmin=60, vmax=200)
plt.title('Ocean Bottom Age')
ax_cb = plt.axes([0.92, 0.25, 0.015, 0.5])
cb = plt.colorbar(p1, cax=ax_cb, orientation='vertical')
cb.ax.set_ylabel('Age (yrs)');

II. Indexing approach¶
Here we grab the kmt
variable out of ocean_grid.nc
. Note that
this is a static variable, so we just look for the last file (give
n=-1
as keyword argument to getvar()
below). The kmt
variable tells us the lowest cell which is active at each \((x, y)\)
location.
variable='kmt'
kmt = cc.querying.getvar(expt, variable, session, ncfile='ocean_grid.nc', n=-1).fillna(1.0).astype(int) - 1
kmt.load()
<xarray.DataArray 'kmt' (yt_ocean: 2700, xt_ocean: 3600)> array([[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]]) Coordinates: * xt_ocean (xt_ocean) float64 -279.9 -279.8 -279.7 ... 79.75 79.85 79.95 * yt_ocean (yt_ocean) float64 -81.11 -81.07 -81.02 ... 89.89 89.94 89.98 geolon_t (yt_ocean, xt_ocean) float32 nan nan nan nan ... nan nan nan nan geolat_t (yt_ocean, xt_ocean) float32 nan nan nan nan ... nan nan nan nan
- yt_ocean: 2700
- xt_ocean: 3600
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
array([[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]])
- xt_ocean(xt_ocean)float64-279.9 -279.8 ... 79.85 79.95
- long_name :
- tcell longitude
- units :
- degrees_E
- cartesian_axis :
- X
array([-279.95, -279.85, -279.75, ..., 79.75, 79.85, 79.95])
- yt_ocean(yt_ocean)float64-81.11 -81.07 ... 89.94 89.98
- long_name :
- tcell latitude
- units :
- degrees_N
- cartesian_axis :
- Y
array([-81.108632, -81.066392, -81.024153, ..., 89.894417, 89.936657, 89.978896])
- geolon_t(yt_ocean, xt_ocean)float32nan nan nan nan ... nan nan nan nan
- long_name :
- tracer longitude
- units :
- degrees_E
- valid_range :
- [-281. 361.]
- cell_methods :
- time: point
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]], dtype=float32)
- geolat_t(yt_ocean, xt_ocean)float32nan nan nan nan ... nan nan nan nan
- long_name :
- tracer latitude
- units :
- degrees_N
- valid_range :
- [-91. 91.]
- cell_methods :
- time: point
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]], dtype=float32)
Provided that kmt
is loaded, xarray
is smart enough to figure
out what this line means, and extracts a 2-D field of bottom age for us.
bottom_age = age_mean.isel(st_ocean=kmt).compute()
CPU times: user 124 ms, sys: 20.8 ms, total: 145 ms
Wall time: 137 ms
And here is the plot:
fig = plt.figure(figsize=(10, 6))
ax = plt.axes(projection=ccrs.Robinson(central_longitude=-100))
ax.coastlines(resolution='50m')
ax.add_feature(land_50m,color='gray')
gl = ax.gridlines(draw_labels=False)
p1 = ax.pcolormesh(geolon_t, geolat_t, bottom_age, transform=ccrs.PlateCarree(),
cmap=cm.cm.matter, vmin=60, vmax=200)
plt.title('Ocean Bottom Age')
ax_cb = plt.axes([0.92, 0.25, 0.015, 0.5])
cb = plt.colorbar(p1, cax=ax_cb, orientation='vertical')
cb.ax.set_ylabel('Age (yrs)');

Some remarks¶
A few things to note here: * The continental shelves are all young - this is just because they are shallow. * The North Atlantic is also relatively young, due to formation of NADW. Note that both the Deep Western Boundary Currents and the Mid-Atlantic Ridge both sustain southward transport of this young water. * A signal following AABW pathways (northwards at the western boundaries) shows slightly younger water in these regions, but it has mixed somewhat with older water above. * Even after 200 years, the water in the NE Pacific has not experienced any ventilation…
Notes on performance¶
The indexing method requires the data to be loaded into memory and appears faster than it actually is if this isn’t factored in. Calculations with large datasets that do not fit within memory will struggle in this case.
The indexing method does not perform well in a dask
workflow where
lazy loading is being used.
The masking approach does not suffer from these limitations and when in doubt should be the preferred method. It also has the advantage of not requiring the grid data ing
To illustrate this: a single month of bottom age from the original data using masking
age.isel(time=1).where(bot_mask).sum(dim='st_ocean').compute()
CPU times: user 3.45 s, sys: 775 ms, total: 4.22 s
Wall time: 6.43 s
<xarray.DataArray 'age_global' (yt_ocean: 2700, xt_ocean: 3600)> array([[0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], ..., [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.]], dtype=float32) Coordinates: * xt_ocean (xt_ocean) float64 -279.9 -279.8 -279.7 ... 79.75 79.85 79.95 * yt_ocean (yt_ocean) float64 -81.11 -81.07 -81.02 ... 89.89 89.94 89.98 time object 2099-02-15 00:00:00
- yt_ocean: 2700
- xt_ocean: 3600
- 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
array([[0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], ..., [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.]], dtype=float32)
- xt_ocean(xt_ocean)float64-279.9 -279.8 ... 79.85 79.95
- long_name :
- tcell longitude
- units :
- degrees_E
- cartesian_axis :
- X
array([-279.95, -279.85, -279.75, ..., 79.75, 79.85, 79.95])
- yt_ocean(yt_ocean)float64-81.11 -81.07 ... 89.94 89.98
- long_name :
- tcell latitude
- units :
- degrees_N
- cartesian_axis :
- Y
array([-81.108632, -81.066392, -81.024153, ..., 89.894417, 89.936657, 89.978896])
- time()object2099-02-15 00:00:00
- long_name :
- time
- cartesian_axis :
- T
- calendar_type :
- NOLEAP
- bounds :
- time_bounds
array(cftime.DatetimeNoLeap(2099, 2, 15, 0, 0, 0, 0), dtype=object)
The same with indexing (different month to ensure no caching effects) is significantly slower
age.isel(time=3).isel(st_ocean=kmt).compute()
distributed.utils_perf - WARNING - full garbage collections took 14% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 14% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 15% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 16% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 16% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 16% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 19% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 27% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 54% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 59% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 63% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 69% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 76% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 83% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 96% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 95% CPU time recently (threshold: 10%)
distributed.utils_perf - WARNING - full garbage collections took 85% CPU time recently (threshold: 10%)
<xarray.DataArray 'age_global' (yt_ocean: 2700, xt_ocean: 3600)> 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]], dtype=float32) Coordinates: * xt_ocean (xt_ocean) float64 -279.9 -279.8 -279.7 ... 79.75 79.85 79.95 * yt_ocean (yt_ocean) float64 -81.11 -81.07 -81.02 ... 89.89 89.94 89.98 st_ocean (yt_ocean, xt_ocean) float64 0.5413 0.5413 ... 0.5413 0.5413 time object 2099-04-16 00:00:00 geolon_t (yt_ocean, xt_ocean) float32 nan nan nan nan ... nan nan nan nan geolat_t (yt_ocean, xt_ocean) float32 nan nan nan nan ... nan nan nan nan Attributes: long_name: Age (global) units: yr valid_range: [0.e+00 1.e+20] cell_methods: time: mean time_avg_info: average_T1,average_T2,average_DT coordinates: geolon_t geolat_t standard_name: sea_water_age_since_surface_contact time_bounds: <xarray.DataArray 'time_bounds' (time: 15, nv: 2)>\ndask....
- yt_ocean: 2700
- xt_ocean: 3600
- nan nan nan nan nan nan nan nan ... nan nan nan nan nan nan nan nan
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]], dtype=float32)
- xt_ocean(xt_ocean)float64-279.9 -279.8 ... 79.85 79.95
- long_name :
- tcell longitude
- units :
- degrees_E
- cartesian_axis :
- X
array([-279.95, -279.85, -279.75, ..., 79.75, 79.85, 79.95])
- yt_ocean(yt_ocean)float64-81.11 -81.07 ... 89.94 89.98
- long_name :
- tcell latitude
- units :
- degrees_N
- cartesian_axis :
- Y
array([-81.108632, -81.066392, -81.024153, ..., 89.894417, 89.936657, 89.978896])
- st_ocean(yt_ocean, xt_ocean)float640.5413 0.5413 ... 0.5413 0.5413
- long_name :
- tcell zstar depth
- units :
- meters
- cartesian_axis :
- Z
- positive :
- down
- edges :
- st_edges_ocean
array([[0.54128077, 0.54128077, 0.54128077, ..., 0.54128077, 0.54128077, 0.54128077], [0.54128077, 0.54128077, 0.54128077, ..., 0.54128077, 0.54128077, 0.54128077], [0.54128077, 0.54128077, 0.54128077, ..., 0.54128077, 0.54128077, 0.54128077], ..., [0.54128077, 0.54128077, 0.54128077, ..., 0.54128077, 0.54128077, 0.54128077], [0.54128077, 0.54128077, 0.54128077, ..., 0.54128077, 0.54128077, 0.54128077], [0.54128077, 0.54128077, 0.54128077, ..., 0.54128077, 0.54128077, 0.54128077]])
- time()object2099-04-16 00:00:00
- long_name :
- time
- cartesian_axis :
- T
- calendar_type :
- NOLEAP
- bounds :
- time_bounds
array(cftime.DatetimeNoLeap(2099, 4, 16, 0, 0, 0, 0), dtype=object)
- geolon_t(yt_ocean, xt_ocean)float32nan nan nan nan ... nan nan nan nan
- long_name :
- tracer longitude
- units :
- degrees_E
- valid_range :
- [-281. 361.]
- cell_methods :
- time: point
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]], dtype=float32)
- geolat_t(yt_ocean, xt_ocean)float32nan nan nan nan ... nan nan nan nan
- long_name :
- tracer latitude
- units :
- degrees_N
- valid_range :
- [-91. 91.]
- cell_methods :
- time: point
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]], dtype=float32)
- long_name :
- Age (global)
- units :
- yr
- valid_range :
- [0.e+00 1.e+20]
- cell_methods :
- time: mean
- time_avg_info :
- average_T1,average_T2,average_DT
- coordinates :
- geolon_t geolat_t
- standard_name :
- sea_water_age_since_surface_contact
- time_bounds :
- <xarray.DataArray 'time_bounds' (time: 15, nv: 2)> dask.array<concatenate, shape=(15, 2), dtype=timedelta64[ns], chunksize=(1, 2), chunktype=numpy.ndarray> Coordinates: * time (time) object 2098-10-16 12:00:00 ... 2099-12-16 12:00:00 * nv (nv) float64 1.0 2.0 Attributes: long_name: time axis boundaries calendar: NOLEAP
It is much faster to preload the data and then index it, but this does rely on their being sufficient memory
myage = age.isel(time=4).load()
distributed.utils_perf - WARNING - full garbage collections took 85% CPU time recently (threshold: 10%)
CPU times: user 3.61 s, sys: 4.9 s, total: 8.51 s
Wall time: 10.4 s
myage.isel(st_ocean=kmt).compute()
CPU times: user 138 ms, sys: 602 µs, total: 139 ms
Wall time: 131 ms
<xarray.DataArray 'age_global' (yt_ocean: 2700, xt_ocean: 3600)> 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]], dtype=float32) Coordinates: * xt_ocean (xt_ocean) float64 -279.9 -279.8 -279.7 ... 79.75 79.85 79.95 * yt_ocean (yt_ocean) float64 -81.11 -81.07 -81.02 ... 89.89 89.94 89.98 st_ocean (yt_ocean, xt_ocean) float64 0.5413 0.5413 ... 0.5413 0.5413 time object 2099-05-16 12:00:00 geolon_t (yt_ocean, xt_ocean) float32 nan nan nan nan ... nan nan nan nan geolat_t (yt_ocean, xt_ocean) float32 nan nan nan nan ... nan nan nan nan Attributes: long_name: Age (global) units: yr valid_range: [0.e+00 1.e+20] cell_methods: time: mean time_avg_info: average_T1,average_T2,average_DT coordinates: geolon_t geolat_t standard_name: sea_water_age_since_surface_contact time_bounds: <xarray.DataArray 'time_bounds' (time: 15, nv: 2)>\ndask....
- yt_ocean: 2700
- xt_ocean: 3600
- nan nan nan nan nan nan nan nan ... nan nan nan nan nan nan nan nan
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]], dtype=float32)
- xt_ocean(xt_ocean)float64-279.9 -279.8 ... 79.85 79.95
- long_name :
- tcell longitude
- units :
- degrees_E
- cartesian_axis :
- X
array([-279.95, -279.85, -279.75, ..., 79.75, 79.85, 79.95])
- yt_ocean(yt_ocean)float64-81.11 -81.07 ... 89.94 89.98
- long_name :
- tcell latitude
- units :
- degrees_N
- cartesian_axis :
- Y
array([-81.108632, -81.066392, -81.024153, ..., 89.894417, 89.936657, 89.978896])
- st_ocean(yt_ocean, xt_ocean)float640.5413 0.5413 ... 0.5413 0.5413
- long_name :
- tcell zstar depth
- units :
- meters
- cartesian_axis :
- Z
- positive :
- down
- edges :
- st_edges_ocean
array([[0.54128077, 0.54128077, 0.54128077, ..., 0.54128077, 0.54128077, 0.54128077], [0.54128077, 0.54128077, 0.54128077, ..., 0.54128077, 0.54128077, 0.54128077], [0.54128077, 0.54128077, 0.54128077, ..., 0.54128077, 0.54128077, 0.54128077], ..., [0.54128077, 0.54128077, 0.54128077, ..., 0.54128077, 0.54128077, 0.54128077], [0.54128077, 0.54128077, 0.54128077, ..., 0.54128077, 0.54128077, 0.54128077], [0.54128077, 0.54128077, 0.54128077, ..., 0.54128077, 0.54128077, 0.54128077]])
- time()object2099-05-16 12:00:00
- long_name :
- time
- cartesian_axis :
- T
- calendar_type :
- NOLEAP
- bounds :
- time_bounds
array(cftime.DatetimeNoLeap(2099, 5, 16, 12, 0, 0, 0), dtype=object)
- geolon_t(yt_ocean, xt_ocean)float32nan nan nan nan ... nan nan nan nan
- long_name :
- tracer longitude
- units :
- degrees_E
- valid_range :
- [-281. 361.]
- cell_methods :
- time: point
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]], dtype=float32)
- geolat_t(yt_ocean, xt_ocean)float32nan nan nan nan ... nan nan nan nan
- long_name :
- tracer latitude
- units :
- degrees_N
- valid_range :
- [-91. 91.]
- cell_methods :
- time: point
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]], dtype=float32)
- long_name :
- Age (global)
- units :
- yr
- valid_range :
- [0.e+00 1.e+20]
- cell_methods :
- time: mean
- time_avg_info :
- average_T1,average_T2,average_DT
- coordinates :
- geolon_t geolat_t
- standard_name :
- sea_water_age_since_surface_contact
- time_bounds :
- <xarray.DataArray 'time_bounds' (time: 15, nv: 2)> dask.array<concatenate, shape=(15, 2), dtype=timedelta64[ns], chunksize=(1, 2), chunktype=numpy.ndarray> Coordinates: * time (time) object 2098-10-16 12:00:00 ... 2099-12-16 12:00:00 * nv (nv) float64 1.0 2.0 Attributes: long_name: time axis boundaries calendar: NOLEAP
Download python script: Age_at_the_Bottom.py
Download Jupyter notebook: Age_at_the_Bottom.ipynb