ACCESS-OM3 and ACCESS-OM2 horizontal mean temperature and salinity Hovmollers: drift from initial condition, vs depth and time¶
Related issue: https://github.com/ACCESS-Community-Hub/access-om3-25km-paper-1/issues/8
Run with a lot of cores (say, 28).
In [1]:
Copied!
# These first two cells must be in all notebooks!
# It allows us to run all the notebooks at once, this cell has a tag "parameters" which allows us to pass in
# arguments externally using papermill (see mkfigs.sh for details)
# Set esm_file to the datastore for the main experiment of interest
esm_file = "/g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf+wombatlite-test3v2-00532b88/datastore.json"
#esm_file = "/g/data/zv30/non-cmip/ACCESS-CM3/cm3-run-03-06-2026/cm3-datastore/cm3-datastore.json"
# papermill settings. *No need to modify these if running interactively.*
papermill = False # `cwd` and `nbname` will be populated by papermill.
cwd = None # current working directory
nbname = None # notebook name
# These first two cells must be in all notebooks!
# It allows us to run all the notebooks at once, this cell has a tag "parameters" which allows us to pass in
# arguments externally using papermill (see mkfigs.sh for details)
# Set esm_file to the datastore for the main experiment of interest
esm_file = "/g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf+wombatlite-test3v2-00532b88/datastore.json"
#esm_file = "/g/data/zv30/non-cmip/ACCESS-CM3/cm3-run-03-06-2026/cm3-datastore/cm3-datastore.json"
# papermill settings. *No need to modify these if running interactively.*
papermill = False # `cwd` and `nbname` will be populated by papermill.
cwd = None # current working directory
nbname = None # notebook name
In [2]:
Copied!
# Parameters
esm_file = "/g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/datastore.json"
papermill = True
cwd = "/g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/"
nbname = "temp-salt-vs-depth-time.ipynb"
# Parameters
esm_file = "/g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/datastore.json"
papermill = True
cwd = "/g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/"
nbname = "temp-salt-vs-depth-time.ipynb"
In [3]:
Copied!
import os
if not papermill:
import nci_ipynb # requires conda/analysis3-26.03 or later
cwd = nci_ipynb.dir()
nbname = nci_ipynb.name()
os.chdir(cwd)
import mkfigs_bootstrap # noqa: adds external/access-model-mkfigs/src to sys.path (stop-gap)
from mkfigs import MkmdWriter
mkmd = MkmdWriter(esm_file, nbname, str(cwd), pm=papermill)
from exptdata_access import guess_experiment_from_esm_file
# Infer model information from the datastore path
expt_key, info = guess_experiment_from_esm_file(esm_file)
model_name = info["model"] # OM3 or CM3
print(f"Running notebook for model: {model_name}")
print("ESM datastore path:", esm_file)
import os
if not papermill:
import nci_ipynb # requires conda/analysis3-26.03 or later
cwd = nci_ipynb.dir()
nbname = nci_ipynb.name()
os.chdir(cwd)
import mkfigs_bootstrap # noqa: adds external/access-model-mkfigs/src to sys.path (stop-gap)
from mkfigs import MkmdWriter
mkmd = MkmdWriter(esm_file, nbname, str(cwd), pm=papermill)
from exptdata_access import guess_experiment_from_esm_file
# Infer model information from the datastore path
expt_key, info = guess_experiment_from_esm_file(esm_file)
model_name = info["model"] # OM3 or CM3
print(f"Running notebook for model: {model_name}")
print("ESM datastore path:", esm_file)
Running notebook for model: ACCESS-OM3 ESM datastore path: /g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/datastore.json
In [4]:
Copied!
IAF = esm_file.find('iaf') > 0
IAF
IAF = esm_file.find('iaf') > 0
IAF
Out[4]:
True
In [5]:
Copied!
import os
import numpy as np
import xarray as xr
import cftime
import cf_xarray as cfxr
import cf_xarray.units
import pint_xarray
from pint import application_registry as ureg
import intake
import matplotlib.pyplot as plt
from matplotlib.patches import Patch
import matplotlib as mpl
from distributed import Client
import cmocean as cm
import cartopy.crs as ccrs
import cartopy.feature as cft
from shapely import geometry
from textwrap import wrap
from tqdm.notebook import tqdm
xr.set_options(keep_attrs=True); # cf_xarray works best when xarray keeps attributes by default
import os
import numpy as np
import xarray as xr
import cftime
import cf_xarray as cfxr
import cf_xarray.units
import pint_xarray
from pint import application_registry as ureg
import intake
import matplotlib.pyplot as plt
from matplotlib.patches import Patch
import matplotlib as mpl
from distributed import Client
import cmocean as cm
import cartopy.crs as ccrs
import cartopy.feature as cft
from shapely import geometry
from textwrap import wrap
from tqdm.notebook import tqdm
xr.set_options(keep_attrs=True); # cf_xarray works best when xarray keeps attributes by default
In [6]:
Copied!
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
In [7]:
Copied!
from model_agnostic import patch_broken_conda_env, patch_dask_workers
patch_broken_conda_env() # no-op on healthy conda envs
client = Client(threads_per_worker=1)
patch_dask_workers(client) # patch the dask workers too
client
from model_agnostic import patch_broken_conda_env, patch_dask_workers
patch_broken_conda_env() # no-op on healthy conda envs
client = Client(threads_per_worker=1)
patch_dask_workers(client) # patch the dask workers too
client
Out[7]:
Client
Client-d371c23d-8667-11f1-b8b6-000001f7fe80
| Connection method: Cluster object | Cluster type: distributed.LocalCluster |
| Dashboard: http://127.0.0.1:8787/status |
Cluster Info
LocalCluster
926bd067
| Dashboard: http://127.0.0.1:8787/status | Workers: 16 |
| Total threads: 16 | Total memory: 188.56 GiB |
| Status: running | Using processes: True |
Scheduler Info
Scheduler
Scheduler-8581573f-6e28-499f-b5d3-faaaf25e2651
| Comm: tcp://127.0.0.1:41047 | Workers: 0 |
| Dashboard: http://127.0.0.1:8787/status | Total threads: 0 |
| Started: Just now | Total memory: 0 B |
Workers
Worker: 0
| Comm: tcp://127.0.0.1:42901 | Total threads: 1 |
| Dashboard: http://127.0.0.1:35847/status | Memory: 11.78 GiB |
| Nanny: tcp://127.0.0.1:43001 | |
| Local directory: /jobfs/174557274.gadi-pbs/dask-scratch-space/worker-35r_2ipn | |
Worker: 1
| Comm: tcp://127.0.0.1:42287 | Total threads: 1 |
| Dashboard: http://127.0.0.1:46871/status | Memory: 11.78 GiB |
| Nanny: tcp://127.0.0.1:44845 | |
| Local directory: /jobfs/174557274.gadi-pbs/dask-scratch-space/worker-e4lrm1k1 | |
Worker: 2
| Comm: tcp://127.0.0.1:43233 | Total threads: 1 |
| Dashboard: http://127.0.0.1:41315/status | Memory: 11.78 GiB |
| Nanny: tcp://127.0.0.1:34387 | |
| Local directory: /jobfs/174557274.gadi-pbs/dask-scratch-space/worker-jee_pr2a | |
Worker: 3
| Comm: tcp://127.0.0.1:41551 | Total threads: 1 |
| Dashboard: http://127.0.0.1:41983/status | Memory: 11.78 GiB |
| Nanny: tcp://127.0.0.1:44339 | |
| Local directory: /jobfs/174557274.gadi-pbs/dask-scratch-space/worker-d7_8k50m | |
Worker: 4
| Comm: tcp://127.0.0.1:36907 | Total threads: 1 |
| Dashboard: http://127.0.0.1:45181/status | Memory: 11.78 GiB |
| Nanny: tcp://127.0.0.1:39629 | |
| Local directory: /jobfs/174557274.gadi-pbs/dask-scratch-space/worker-qy0n2t7t | |
Worker: 5
| Comm: tcp://127.0.0.1:38987 | Total threads: 1 |
| Dashboard: http://127.0.0.1:36269/status | Memory: 11.78 GiB |
| Nanny: tcp://127.0.0.1:40433 | |
| Local directory: /jobfs/174557274.gadi-pbs/dask-scratch-space/worker-86ro9wrc | |
Worker: 6
| Comm: tcp://127.0.0.1:36423 | Total threads: 1 |
| Dashboard: http://127.0.0.1:40927/status | Memory: 11.78 GiB |
| Nanny: tcp://127.0.0.1:38521 | |
| Local directory: /jobfs/174557274.gadi-pbs/dask-scratch-space/worker-9jz0tx2_ | |
Worker: 7
| Comm: tcp://127.0.0.1:40475 | Total threads: 1 |
| Dashboard: http://127.0.0.1:42173/status | Memory: 11.78 GiB |
| Nanny: tcp://127.0.0.1:38819 | |
| Local directory: /jobfs/174557274.gadi-pbs/dask-scratch-space/worker-124b6lz9 | |
Worker: 8
| Comm: tcp://127.0.0.1:33967 | Total threads: 1 |
| Dashboard: http://127.0.0.1:36811/status | Memory: 11.78 GiB |
| Nanny: tcp://127.0.0.1:40309 | |
| Local directory: /jobfs/174557274.gadi-pbs/dask-scratch-space/worker-fi2c6ibt | |
Worker: 9
| Comm: tcp://127.0.0.1:36673 | Total threads: 1 |
| Dashboard: http://127.0.0.1:37369/status | Memory: 11.78 GiB |
| Nanny: tcp://127.0.0.1:37211 | |
| Local directory: /jobfs/174557274.gadi-pbs/dask-scratch-space/worker-df99zbj8 | |
Worker: 10
| Comm: tcp://127.0.0.1:40125 | Total threads: 1 |
| Dashboard: http://127.0.0.1:42753/status | Memory: 11.78 GiB |
| Nanny: tcp://127.0.0.1:36581 | |
| Local directory: /jobfs/174557274.gadi-pbs/dask-scratch-space/worker-8nbkwgcx | |
Worker: 11
| Comm: tcp://127.0.0.1:44735 | Total threads: 1 |
| Dashboard: http://127.0.0.1:36289/status | Memory: 11.78 GiB |
| Nanny: tcp://127.0.0.1:34883 | |
| Local directory: /jobfs/174557274.gadi-pbs/dask-scratch-space/worker-z8wvvyd9 | |
Worker: 12
| Comm: tcp://127.0.0.1:36197 | Total threads: 1 |
| Dashboard: http://127.0.0.1:42325/status | Memory: 11.78 GiB |
| Nanny: tcp://127.0.0.1:41249 | |
| Local directory: /jobfs/174557274.gadi-pbs/dask-scratch-space/worker-om26wogj | |
Worker: 13
| Comm: tcp://127.0.0.1:37761 | Total threads: 1 |
| Dashboard: http://127.0.0.1:35897/status | Memory: 11.78 GiB |
| Nanny: tcp://127.0.0.1:38999 | |
| Local directory: /jobfs/174557274.gadi-pbs/dask-scratch-space/worker-sqnsh6sw | |
Worker: 14
| Comm: tcp://127.0.0.1:44277 | Total threads: 1 |
| Dashboard: http://127.0.0.1:43951/status | Memory: 11.78 GiB |
| Nanny: tcp://127.0.0.1:41845 | |
| Local directory: /jobfs/174557274.gadi-pbs/dask-scratch-space/worker-wmva7mhk | |
Worker: 15
| Comm: tcp://127.0.0.1:42615 | Total threads: 1 |
| Dashboard: http://127.0.0.1:36633/status | Memory: 11.78 GiB |
| Nanny: tcp://127.0.0.1:39605 | |
| Local directory: /jobfs/174557274.gadi-pbs/dask-scratch-space/worker-1ktwkozh | |
Define regions¶
In [8]:
Copied!
regions = { # [minx, maxx, miny, maxy], using model longitude range (-280 to 80)
"Global": [-280, 80, -90, 90],
# "Arctic": [-280, 80, 65, 90],
# "Southern Ocean": [-280, 80, -82, -63],
# "ACC": [-280, 80, -63, -45],
# "Southern Pacific": [-210, -70, -45, -20],
# "Tropical Pacific": [-240, -100, -20, 20],
# "North Pacific": [-240, -100, 20, 65],
# "South Atlantic": [-60, 20, -45, -20],
# "Tropical Atlantic": [-70, 20, -20, 20],
"North Atlantic": [-100, 0, 20, 65],
# "Indian": [30, 120, -45, 20],
# "Aegean Sea": [18, 27.5, 34, 44],
"Black Sea": [27.5, 43, 40.5, 48],
# "Baltic Sea": [13, 30, 53, 58],
# "Mediterranean Sea": [0, 35, 31, 41],
# "Red Sea": [33, 44, 12, 29],
# "Persian Gulf": [47, 56, 24, 31],
# "White Sea": [31, 41, 63, 68],
}
regions = {k: dict(zip(["minx", "maxx", "miny", "maxy"], v)) for k, v in regions.items()} # convert to dicts
for r, d in regions.items():
for k, x in d.items():
if k in ["minx", "maxx"] and x != max(-280, min(x, 80)):
raise ValueError(f"{r} {k} = {x} is outside the range -280 to 80")
fig = plt.figure(figsize=(10, 4))
colors = mpl.color_sequences['tab20']
try: # set Global color to white
colors[list(regions.keys()).index("Global")] = (1, 1, 1)
except ValueError:
pass
ax = plt.axes(position=[0.05,0.05,0.7,0.9], projection=ccrs.Robinson())
ax.coastlines(resolution="110m")
ax.gridlines(draw_labels=False)
legend_elements = []
for i, (region, limits) in enumerate(regions.items()):
ax.add_geometries([geometry.box(**limits)], crs=ccrs.PlateCarree(), color=colors[i], alpha=0.3)
legend_elements.append(Patch(color=colors[i], alpha=0.3, label=region))
ax.legend(handles=legend_elements, bbox_to_anchor=(1.2, 1.00))
plt.title("Regions (BUG: incorrect shapes north of 65°N)")
regions = { # [minx, maxx, miny, maxy], using model longitude range (-280 to 80)
"Global": [-280, 80, -90, 90],
# "Arctic": [-280, 80, 65, 90],
# "Southern Ocean": [-280, 80, -82, -63],
# "ACC": [-280, 80, -63, -45],
# "Southern Pacific": [-210, -70, -45, -20],
# "Tropical Pacific": [-240, -100, -20, 20],
# "North Pacific": [-240, -100, 20, 65],
# "South Atlantic": [-60, 20, -45, -20],
# "Tropical Atlantic": [-70, 20, -20, 20],
"North Atlantic": [-100, 0, 20, 65],
# "Indian": [30, 120, -45, 20],
# "Aegean Sea": [18, 27.5, 34, 44],
"Black Sea": [27.5, 43, 40.5, 48],
# "Baltic Sea": [13, 30, 53, 58],
# "Mediterranean Sea": [0, 35, 31, 41],
# "Red Sea": [33, 44, 12, 29],
# "Persian Gulf": [47, 56, 24, 31],
# "White Sea": [31, 41, 63, 68],
}
regions = {k: dict(zip(["minx", "maxx", "miny", "maxy"], v)) for k, v in regions.items()} # convert to dicts
for r, d in regions.items():
for k, x in d.items():
if k in ["minx", "maxx"] and x != max(-280, min(x, 80)):
raise ValueError(f"{r} {k} = {x} is outside the range -280 to 80")
fig = plt.figure(figsize=(10, 4))
colors = mpl.color_sequences['tab20']
try: # set Global color to white
colors[list(regions.keys()).index("Global")] = (1, 1, 1)
except ValueError:
pass
ax = plt.axes(position=[0.05,0.05,0.7,0.9], projection=ccrs.Robinson())
ax.coastlines(resolution="110m")
ax.gridlines(draw_labels=False)
legend_elements = []
for i, (region, limits) in enumerate(regions.items()):
ax.add_geometries([geometry.box(**limits)], crs=ccrs.PlateCarree(), color=colors[i], alpha=0.3)
legend_elements.append(Patch(color=colors[i], alpha=0.3, label=region))
ax.legend(handles=legend_elements, bbox_to_anchor=(1.2, 1.00))
plt.title("Regions (BUG: incorrect shapes north of 65°N)")
Out[8]:
Text(0.5, 1.0, 'Regions (BUG: incorrect shapes north of 65°N)')
Load data from ACCESS-OM3¶
In [9]:
Copied!
if model_name == "ACCESS-CM3":
catalogs = [esm_file]
else:
catalogs = [
'/g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf-1.0-beta-5165c0f8/datastore.json',
esm_file,
# '/g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf-1.0-beta-gm1-d968c801/datastore.json',
# '/g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf-1.0-beta-gm2-5dc49da6/datastore.json',
# '/g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf-1.0-beta-gm3-da330542/datastore.json',
# '/g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf-1.0-beta-gm4-9fd08880/datastore.json',
# '/g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf-1.0-beta-gm5-9b5dbfa9/datastore.json',
# '/g/data/ol01/access-om3-output/access-om3-025/25km-iaf-test-for-AK-expt-7df5ef4c/datastore.json',
]
catalogs
if model_name == "ACCESS-CM3":
catalogs = [esm_file]
else:
catalogs = [
'/g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf-1.0-beta-5165c0f8/datastore.json',
esm_file,
# '/g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf-1.0-beta-gm1-d968c801/datastore.json',
# '/g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf-1.0-beta-gm2-5dc49da6/datastore.json',
# '/g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf-1.0-beta-gm3-da330542/datastore.json',
# '/g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf-1.0-beta-gm4-9fd08880/datastore.json',
# '/g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf-1.0-beta-gm5-9b5dbfa9/datastore.json',
# '/g/data/ol01/access-om3-output/access-om3-025/25km-iaf-test-for-AK-expt-7df5ef4c/datastore.json',
]
catalogs
Out[9]:
['/g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf-1.0-beta-5165c0f8/datastore.json', '/g/data/ol01/outputs/access-om3-25km/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/datastore.json']
In [10]:
Copied!
om3datastores = { os.path.normpath(c).split(os.sep)[-2]:
intake.open_esm_datastore(c,
columns_with_iterables=[
"variable",
"variable_long_name",
"variable_standard_name",
"variable_cell_methods",
"variable_units"]
)
for c in catalogs }
om3datastores
om3datastores = { os.path.normpath(c).split(os.sep)[-2]:
intake.open_esm_datastore(c,
columns_with_iterables=[
"variable",
"variable_long_name",
"variable_standard_name",
"variable_cell_methods",
"variable_units"]
)
for c in catalogs }
om3datastores
Out[10]:
{'MC_25km_jra_iaf-1.0-beta-5165c0f8': <datastore catalog with 22 dataset(s) from 6042 asset(s)>,
'MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36': <datastore catalog with 16 dataset(s) from 2190 asset(s)>}
In [11]:
Copied!
om3varnames = [ 'thetao', 'so' ]
om3chunks = {"xh": -1, "yh": -1, "z_l": -1} # remove "yh": -1 for resolution finer than 25km
if model_name == "ACCESS-CM3":
om3chunks["time"] = 1 # CM3 stores yearly files; avoid ~6 GB chunks
om3vars = {
vname: {expt: ds.search(variable=vname).to_dask(
xarray_open_kwargs = dict(
chunks=om3chunks,
decode_timedelta=True
)
)[vname]
for expt, ds in om3datastores.items()
}
for vname in om3varnames
}
# omit latitudes with grid bug in this run https://github.com/ACCESS-NRI/ocean_model_grid_generator/issues/7
for vname, d in om3vars.items():
try:
d['25km-iaf-test-for-AK-expt-7df5ef4c'] = d['25km-iaf-test-for-AK-expt-7df5ef4c'].isel(yh=slice(10, None))
except ValueError:
d['25km-iaf-test-for-AK-expt-7df5ef4c'] = d['25km-iaf-test-for-AK-expt-7df5ef4c'].isel(yq=slice(10, None))
except KeyError:
pass
if IAF:
for vname, d in om3vars.items():
for expt in d:
try:
d[expt] = d[expt].convert_calendar("proleptic_gregorian", use_cftime=True)
except KeyError:
pass
om3varnames = [ 'thetao', 'so' ]
om3chunks = {"xh": -1, "yh": -1, "z_l": -1} # remove "yh": -1 for resolution finer than 25km
if model_name == "ACCESS-CM3":
om3chunks["time"] = 1 # CM3 stores yearly files; avoid ~6 GB chunks
om3vars = {
vname: {expt: ds.search(variable=vname).to_dask(
xarray_open_kwargs = dict(
chunks=om3chunks,
decode_timedelta=True
)
)[vname]
for expt, ds in om3datastores.items()
}
for vname in om3varnames
}
# omit latitudes with grid bug in this run https://github.com/ACCESS-NRI/ocean_model_grid_generator/issues/7
for vname, d in om3vars.items():
try:
d['25km-iaf-test-for-AK-expt-7df5ef4c'] = d['25km-iaf-test-for-AK-expt-7df5ef4c'].isel(yh=slice(10, None))
except ValueError:
d['25km-iaf-test-for-AK-expt-7df5ef4c'] = d['25km-iaf-test-for-AK-expt-7df5ef4c'].isel(yq=slice(10, None))
except KeyError:
pass
if IAF:
for vname, d in om3vars.items():
for expt in d:
try:
d[expt] = d[expt].convert_calendar("proleptic_gregorian", use_cftime=True)
except KeyError:
pass
Load data from ACCESS-OM2¶
use control - see https://forum.access-hive.org.au/t/access-om2-control-experiments/258#p-747-ryf-7
In [12]:
Copied!
if model_name == "ACCESS-CM3":
data_name = 'ACCESS-CM2'
om2exptname = 'cj877' # CM2 control archive on /g/data/p73 (same reference as pPV.ipynb)
else:
data_name = 'ACCESS-OM2'
if IAF:
om2exptname = '025deg_jra55_iaf_omip2_cycle1'
else:
om2exptname = '025deg_jra55_ryf9091_gadi' # monthly temp only for 1900-1903, and 2300-, with annual data in the gap
om2datastores = {om2exptname: intake.cat.access_nri[om2exptname]}
if model_name == "ACCESS-CM3":
data_name = 'ACCESS-CM2'
om2exptname = 'cj877' # CM2 control archive on /g/data/p73 (same reference as pPV.ipynb)
else:
data_name = 'ACCESS-OM2'
if IAF:
om2exptname = '025deg_jra55_iaf_omip2_cycle1'
else:
om2exptname = '025deg_jra55_ryf9091_gadi' # monthly temp only for 1900-1903, and 2300-, with annual data in the gap
om2datastores = {om2exptname: intake.cat.access_nri[om2exptname]}
In [13]:
Copied!
om2varnames = [ 'temp', 'salt' ]
if model_name == "ACCESS-CM3":
# Reference: ACCESS-CM2 cj877 control archive (same source as pPV.ipynb and
# Overturning_in_ACCESS_OM3.ipynb). Limit to the last 600 months to match
# the CM3 record length; each cj877 file holds 6 months.
from pathlib import Path
cm2_dir = Path("/g/data/p73/archive/non-CMIP/ACCESS-CM2/cj877/history/ocn")
n_months = 600
def _load_cm2(varname):
files = sorted(cm2_dir.glob(f"ocean-3d-{varname}-1-monthly-mean-ym_*.nc"))
if not files:
raise FileNotFoundError(f"No cj877 monthly files found for {varname!r}")
files = files[-((n_months + 5) // 6):]
ds = xr.open_mfdataset(
files,
combine="by_coords",
parallel=True,
chunks={"time": 1, "xt_ocean": -1, "yt_ocean": -1, "st_ocean": -1},
decode_timedelta=True,
use_cftime=True, # cj877 model years (~453-503) can't be datetime64
data_vars="minimal", coords="minimal", compat="override",
)
return ds[varname]
om2vars = { vname: {om2exptname: _load_cm2(vname)} for vname in om2varnames }
# Relabel the CM2 control-run times onto the CM3 time axis so the panels can
# share the x-axis (same approach as Overturning_in_ACCESS_OM3.ipynb) — this
# also avoids mixing cftime and datetime64 axes, which matplotlib can't share.
cm3_time = next(iter(om3vars[om3varnames[0]].values())).time
for vname, dd in om2vars.items():
for expt, da in dd.items():
n = min(da.sizes["time"], cm3_time.sizes["time"])
if da.sizes["time"] != cm3_time.sizes["time"]:
print(f"Aligning {expt} {vname} with last {n} time steps")
dd[expt] = (da.isel(time=slice(-n, None))
.assign_coords(time=("time", cm3_time.isel(time=slice(-n, None)).values)))
else:
om2vars = {
vname: {expt: ds.search(variable=vname, frequency="1mon").to_dask(
xarray_open_kwargs = dict(
chunks={"xt_ocean": -1, "yt_ocean": -1, "st_ocean" : -1}, # remove "yt_ocean": -1 for resolution finer than 25km
decode_timedelta=True
)
)[vname]
for expt, ds in om2datastores.items()
}
for vname in om2varnames
}
if IAF:
for vname, d in om2vars.items():
for expt in d:
try:
d[expt] = d[expt].convert_calendar("proleptic_gregorian", use_cftime=True)
except KeyError:
pass
om2varnames = [ 'temp', 'salt' ]
if model_name == "ACCESS-CM3":
# Reference: ACCESS-CM2 cj877 control archive (same source as pPV.ipynb and
# Overturning_in_ACCESS_OM3.ipynb). Limit to the last 600 months to match
# the CM3 record length; each cj877 file holds 6 months.
from pathlib import Path
cm2_dir = Path("/g/data/p73/archive/non-CMIP/ACCESS-CM2/cj877/history/ocn")
n_months = 600
def _load_cm2(varname):
files = sorted(cm2_dir.glob(f"ocean-3d-{varname}-1-monthly-mean-ym_*.nc"))
if not files:
raise FileNotFoundError(f"No cj877 monthly files found for {varname!r}")
files = files[-((n_months + 5) // 6):]
ds = xr.open_mfdataset(
files,
combine="by_coords",
parallel=True,
chunks={"time": 1, "xt_ocean": -1, "yt_ocean": -1, "st_ocean": -1},
decode_timedelta=True,
use_cftime=True, # cj877 model years (~453-503) can't be datetime64
data_vars="minimal", coords="minimal", compat="override",
)
return ds[varname]
om2vars = { vname: {om2exptname: _load_cm2(vname)} for vname in om2varnames }
# Relabel the CM2 control-run times onto the CM3 time axis so the panels can
# share the x-axis (same approach as Overturning_in_ACCESS_OM3.ipynb) — this
# also avoids mixing cftime and datetime64 axes, which matplotlib can't share.
cm3_time = next(iter(om3vars[om3varnames[0]].values())).time
for vname, dd in om2vars.items():
for expt, da in dd.items():
n = min(da.sizes["time"], cm3_time.sizes["time"])
if da.sizes["time"] != cm3_time.sizes["time"]:
print(f"Aligning {expt} {vname} with last {n} time steps")
dd[expt] = (da.isel(time=slice(-n, None))
.assign_coords(time=("time", cm3_time.isel(time=slice(-n, None)).values)))
else:
om2vars = {
vname: {expt: ds.search(variable=vname, frequency="1mon").to_dask(
xarray_open_kwargs = dict(
chunks={"xt_ocean": -1, "yt_ocean": -1, "st_ocean" : -1}, # remove "yt_ocean": -1 for resolution finer than 25km
decode_timedelta=True
)
)[vname]
for expt, ds in om2datastores.items()
}
for vname in om2varnames
}
if IAF:
for vname, d in om2vars.items():
for expt in d:
try:
d[expt] = d[expt].convert_calendar("proleptic_gregorian", use_cftime=True)
except KeyError:
pass
Calculate Hovmollers for each region - SLOW!¶
BUG: horizontal mean needs to be area-weighted - use xgcm?¶
In [14]:
Copied!
%%time
om3vars_hov = {
region:
{
vname: {
expt: da.sel(yh=slice(b['miny'], b['maxy']))\
.sel(xh=slice(b['minx'], b['maxx']))\
.mean('yh').mean('xh').load()
for expt, da in tqdm(vdatadict.items(), desc=f' {vname} experiments', )
}
for vname, vdatadict in tqdm(om3vars.items(), desc=f' {region} variables')
}
for region, b in tqdm(regions.items(), desc='regions')
}
%%time
om3vars_hov = {
region:
{
vname: {
expt: da.sel(yh=slice(b['miny'], b['maxy']))\
.sel(xh=slice(b['minx'], b['maxx']))\
.mean('yh').mean('xh').load()
for expt, da in tqdm(vdatadict.items(), desc=f' {vname} experiments', )
}
for vname, vdatadict in tqdm(om3vars.items(), desc=f' {region} variables')
}
for region, b in tqdm(regions.items(), desc='regions')
}
CPU times: user 5min 46s, sys: 2min 14s, total: 8min Wall time: 27min 44s
BUG: horizontal mean needs to be area-weighted - use xgcm?¶
In [15]:
Copied!
%%time
om2vars_hov = {
region:
{
vname: {
expt: da.sel(yt_ocean=slice(b['miny'], b['maxy']))\
.sel(xt_ocean=slice(b['minx'], b['maxx']))\
.mean('yt_ocean').mean('xt_ocean').load()
for expt, da in tqdm(vdatadict.items(), desc=f' {vname} experiments', )
}
for vname, vdatadict in tqdm(om2vars.items(), desc=f' {region} variables')
}
for region, b in tqdm(regions.items(), desc='regions')
}
%%time
om2vars_hov = {
region:
{
vname: {
expt: da.sel(yt_ocean=slice(b['miny'], b['maxy']))\
.sel(xt_ocean=slice(b['minx'], b['maxx']))\
.mean('yt_ocean').mean('xt_ocean').load()
for expt, da in tqdm(vdatadict.items(), desc=f' {vname} experiments', )
}
for vname, vdatadict in tqdm(om2vars.items(), desc=f' {region} variables')
}
for region, b in tqdm(regions.items(), desc='regions')
}
CPU times: user 1min 48s, sys: 38.4 s, total: 2min 26s Wall time: 10min 15s
Plot Hovmollers for each region¶
In [16]:
Copied!
def doplots(om3variable = "thetao",
om2variable = "temp",
vmax = None, mkmdfig=True):
for region, d in om3vars_hov.items():
npanels = len(d[om3variable]) + len(om2vars_hov[region][om2variable])
nrows = (npanels+1)//2
fig, axs = plt.subplots(nrows, 2,
figsize=(9, 3*nrows),
sharex=True, sharey=True)
fig.suptitle(f'{region} depth-time Hovmollers (BUG: not weighted by cell area)')
if vmax == None: # calculate max abs over all panels (different for each region)
vmax = 0
for i, (expt, da) in enumerate(d[om3variable].items(), start=1):
if i == 1:
ref = da.isel(time=0) # use the same reference state for all om3 expts in this region
vmax = max(vmax, abs(da - ref).max().data)
for i2, (expt, da) in enumerate(om2vars_hov[region][om2variable].items(), start=i+1):
if i2 == i+1:
ref = da.isel(time=0) # use the same reference state for all om2 expts in this region
vmax = max(vmax, abs(da - ref).max().data)
# ACCESS-OM3 (or ACCESS-CM3)
for i, (expt, da) in enumerate(d[om3variable].items(), start=1):
plt.subplot(nrows, 2, i)
if i == 1:
ref = da.isel(time=0) # use the same reference state for all om3 expts in this region
p = (da - ref).transpose().plot.contourf(
levels=101, vmin=-vmax, vmax=vmax, extend="both", cmap="seismic", add_colorbar=False,
)
(da - ref).transpose().plot.contour(
levels=25, vmin=-vmax, vmax=vmax, add_colorbar=False, colors=["k"], linewidths=[0.2], linestyles=["-"]
)
try:
zmax = da["z_l"][np.where(np.isnan(da.isel(time=0)))[0][0] - 1]
plt.gca().set_ylim([0, zmax]) # crop to deepest wet cell
except IndexError:
plt.gca().set_ylim([0, None]) # no dry cells so show all
plt.gca().invert_yaxis()
plt.title(f"{model_name} {expt} {om3variable}", fontsize=8)
plt.ylabel('Depth [m]')
label = f"{model_name}: {da.attrs['long_name']} ({om3variable}) difference [{da.attrs['units']}]"
# ACCESS-OM2 (or ACCESS-CM2)
for i2, (expt, da) in enumerate(om2vars_hov[region][om2variable].items(), start=i+1):
plt.subplot(nrows, 2, i2)
if i2 == i+1:
ref = da.isel(time=0) # use the same reference state for all om2 expts in this region
(da - ref).transpose().plot.contourf(
levels=101, vmin=-vmax, vmax=vmax, extend="both", cmap="seismic", add_colorbar=False,
)
(da - ref).transpose().plot.contour(
levels=25, vmin=-vmax, vmax=vmax, add_colorbar=False, colors=["k"], linewidths=[0.2], linestyles=["-"]
)
try:
zmax = da["st_ocean"][np.where(np.isnan(da.isel(time=0)))[0][0] - 1]
plt.gca().set_ylim([0, zmax]) # crop to deepest wet cell
except IndexError:
plt.gca().set_ylim([0, None]) # no dry cells so show all
plt.gca().invert_yaxis()
plt.title(f"{data_name} {expt} {om2variable}", fontsize=8)
plt.ylabel('Depth [m]')
label += f"\n{data_name}: {da.attrs['long_name']} ({om2variable}) difference [{da.attrs['units']}]"
try: # drop empty subfigs (if any)
fig.delaxes(axs.flatten()[i2])
except IndexError:
pass
for ax in fig.get_axes():
ax.label_outer()
plt.tight_layout()
fig.colorbar(p, ax=axs, orientation='horizontal',
fraction=.1, shrink=0.7, aspect=40,
label=label)
if mkmdfig:
mkmd.savefig(fig, f"Horizontal mean temperature and salinity Hovmollers: {region} ({om3variable})",
f"{model_name} and {data_name} horizontal mean "+om3variable+" Hovmollers: drift from initial condition, vs depth and time. [GitHub issue: Hovmoller temperature anomaly (depth-time)](https://github.com/ACCESS-Community-Hub/access-om3-paper-1/issues/8)")
def doplots(om3variable = "thetao",
om2variable = "temp",
vmax = None, mkmdfig=True):
for region, d in om3vars_hov.items():
npanels = len(d[om3variable]) + len(om2vars_hov[region][om2variable])
nrows = (npanels+1)//2
fig, axs = plt.subplots(nrows, 2,
figsize=(9, 3*nrows),
sharex=True, sharey=True)
fig.suptitle(f'{region} depth-time Hovmollers (BUG: not weighted by cell area)')
if vmax == None: # calculate max abs over all panels (different for each region)
vmax = 0
for i, (expt, da) in enumerate(d[om3variable].items(), start=1):
if i == 1:
ref = da.isel(time=0) # use the same reference state for all om3 expts in this region
vmax = max(vmax, abs(da - ref).max().data)
for i2, (expt, da) in enumerate(om2vars_hov[region][om2variable].items(), start=i+1):
if i2 == i+1:
ref = da.isel(time=0) # use the same reference state for all om2 expts in this region
vmax = max(vmax, abs(da - ref).max().data)
# ACCESS-OM3 (or ACCESS-CM3)
for i, (expt, da) in enumerate(d[om3variable].items(), start=1):
plt.subplot(nrows, 2, i)
if i == 1:
ref = da.isel(time=0) # use the same reference state for all om3 expts in this region
p = (da - ref).transpose().plot.contourf(
levels=101, vmin=-vmax, vmax=vmax, extend="both", cmap="seismic", add_colorbar=False,
)
(da - ref).transpose().plot.contour(
levels=25, vmin=-vmax, vmax=vmax, add_colorbar=False, colors=["k"], linewidths=[0.2], linestyles=["-"]
)
try:
zmax = da["z_l"][np.where(np.isnan(da.isel(time=0)))[0][0] - 1]
plt.gca().set_ylim([0, zmax]) # crop to deepest wet cell
except IndexError:
plt.gca().set_ylim([0, None]) # no dry cells so show all
plt.gca().invert_yaxis()
plt.title(f"{model_name} {expt} {om3variable}", fontsize=8)
plt.ylabel('Depth [m]')
label = f"{model_name}: {da.attrs['long_name']} ({om3variable}) difference [{da.attrs['units']}]"
# ACCESS-OM2 (or ACCESS-CM2)
for i2, (expt, da) in enumerate(om2vars_hov[region][om2variable].items(), start=i+1):
plt.subplot(nrows, 2, i2)
if i2 == i+1:
ref = da.isel(time=0) # use the same reference state for all om2 expts in this region
(da - ref).transpose().plot.contourf(
levels=101, vmin=-vmax, vmax=vmax, extend="both", cmap="seismic", add_colorbar=False,
)
(da - ref).transpose().plot.contour(
levels=25, vmin=-vmax, vmax=vmax, add_colorbar=False, colors=["k"], linewidths=[0.2], linestyles=["-"]
)
try:
zmax = da["st_ocean"][np.where(np.isnan(da.isel(time=0)))[0][0] - 1]
plt.gca().set_ylim([0, zmax]) # crop to deepest wet cell
except IndexError:
plt.gca().set_ylim([0, None]) # no dry cells so show all
plt.gca().invert_yaxis()
plt.title(f"{data_name} {expt} {om2variable}", fontsize=8)
plt.ylabel('Depth [m]')
label += f"\n{data_name}: {da.attrs['long_name']} ({om2variable}) difference [{da.attrs['units']}]"
try: # drop empty subfigs (if any)
fig.delaxes(axs.flatten()[i2])
except IndexError:
pass
for ax in fig.get_axes():
ax.label_outer()
plt.tight_layout()
fig.colorbar(p, ax=axs, orientation='horizontal',
fraction=.1, shrink=0.7, aspect=40,
label=label)
if mkmdfig:
mkmd.savefig(fig, f"Horizontal mean temperature and salinity Hovmollers: {region} ({om3variable})",
f"{model_name} and {data_name} horizontal mean "+om3variable+" Hovmollers: drift from initial condition, vs depth and time. [GitHub issue: Hovmoller temperature anomaly (depth-time)](https://github.com/ACCESS-Community-Hub/access-om3-paper-1/issues/8)")
In [17]:
Copied!
doplots(om3variable = "thetao",
om2variable = "temp",
mkmdfig=True)
doplots(om3variable = "thetao",
om2variable = "temp",
mkmdfig=True)
Saved /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time_01.png Adding entry to per-notebook markdown: /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md
Lines appended to /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md successfully.
Saved /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time_02.png Adding entry to per-notebook markdown: /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md Lines appended to /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md successfully.
Saved /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time_03.png Adding entry to per-notebook markdown: /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md Lines appended to /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md successfully.
In [18]:
Copied!
#cb: only exporting the one with a vmax specified -- temp
doplots(om3variable = "thetao",
om2variable = "temp",
vmax = 1)
#cb: only exporting the one with a vmax specified -- temp
doplots(om3variable = "thetao",
om2variable = "temp",
vmax = 1)
Saved /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time_04.png Adding entry to per-notebook markdown: /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md This title already exists in the notebook markdown – appending an additional figure. Lines appended to /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md successfully.
Saved /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time_05.png Adding entry to per-notebook markdown: /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md This title already exists in the notebook markdown – appending an additional figure. Lines appended to /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md successfully.
Saved /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time_06.png Adding entry to per-notebook markdown: /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md This title already exists in the notebook markdown – appending an additional figure. Lines appended to /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md successfully.
In [19]:
Copied!
doplots(om3variable = "so",
om2variable = "salt",
mkmdfig=True)
doplots(om3variable = "so",
om2variable = "salt",
mkmdfig=True)
Saved /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time_07.png Adding entry to per-notebook markdown: /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md Lines appended to /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md successfully.
Saved /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time_08.png Adding entry to per-notebook markdown: /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md Lines appended to /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md successfully.
Saved /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time_09.png Adding entry to per-notebook markdown: /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md Lines appended to /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md successfully.
In [20]:
Copied!
#cb: only exporting the one with a vmax specified -- salinity
doplots(om3variable = "so",
om2variable = "salt",
vmax = 0.2)
#cb: only exporting the one with a vmax specified -- salinity
doplots(om3variable = "so",
om2variable = "salt",
vmax = 0.2)
Saved /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time_10.png Adding entry to per-notebook markdown: /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md This title already exists in the notebook markdown – appending an additional figure. Lines appended to /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md successfully.
Saved /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time_11.png Adding entry to per-notebook markdown: /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md This title already exists in the notebook markdown – appending an additional figure. Lines appended to /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md successfully.
Saved /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time_12.png Adding entry to per-notebook markdown: /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md This title already exists in the notebook markdown – appending an additional figure. Lines appended to /g/data/tm70/cyb561/access-om3-paper-1-runs/MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/notebooks/mkfigs_output_MC_25km_jra_iaf+wombatlite_bs2-mpudig-backscat2-0578cc36/mkmd/temp-salt-vs-depth-time.md successfully.
In [21]:
Copied!
client.close()
client.close()