Transport across sections
mom6_tools.section_transports collection of functions for computing and plotting time-series of transports across pre-defined vertical sections.
The goal of this notebook is the following:
server as an example on how to post-process the CESM/MOM6 vertical sections defined in diag_table. The location of the current vertical sections computed online can be found at the end of this notebook;
evaluate model experiments by comparing transports against observed estimates;
[1]:
%load_ext autoreload
%autoreload 2
[2]:
%matplotlib inline
import warnings
warnings.filterwarnings("ignore")
from mom6_tools.section_transports import Transport, options
import matplotlib.pyplot as plt
from mom6_tools.m6toolbox import cime_xmlquery
import xarray as xr
import yaml, os, numpy
[3]:
# Read in the yaml file
diag_config_yml_path = "diag_config.yml"
diag_config_yml = yaml.load(open(diag_config_yml_path,'r'), Loader=yaml.Loader)
[4]:
# create an empty class object
class args:
pass
[5]:
caseroot = diag_config_yml['Case']['CASEROOT']
args.casename = cime_xmlquery(caseroot, 'CASE')
DOUT_S = cime_xmlquery(caseroot, 'DOUT_S')
if DOUT_S:
OUTDIR = cime_xmlquery(caseroot, 'DOUT_S_ROOT')+'/ocn/hist/'
else:
OUTDIR = cime_xmlquery(caseroot, 'RUNDIR')
print('Output directory is:', OUTDIR)
print('Casename is:', args.casename)
Output directory is: /glade/derecho/scratch/gmarques/archive/g.e30_a03c.GJRAv4.TL319_t232_wgx3_hycom1_N75.2024.079/ocn/hist/
Casename is: g.e30_a03c.GJRAv4.TL319_t232_wgx3_hycom1_N75.2024.079
[6]:
# load sections where transports are computed online
sections = diag_config_yml['Transports']['sections']
Define the arguments expected by class “Transport”. These have been hard-coded here fow now…
[7]:
args.infile = OUTDIR
# set avg dates
avg = diag_config_yml['Avg']
args.start_date = '0001-01-01' # override start date
args.end_date = avg['end_date']
args.label = ''
args.parallel = False
args.debug = False
Observed flows, more options can be added here
Griffies et al., 2016: OMIP contribution to CMIP6: experimental and diagnostic protocol for the physical component of the Ocean Model Intercomparison Project. Geosci. Model. Dev., 9, 3231-3296. doi:10.5194/gmd-9-3231-2016
Below we define a function for plotting transport time series. Note the following:
green = mean transport is within observed values
red = mean transport is not within observed values
gray = either there isn’t observed values to compare with or just a mean value is available (not a range)
[8]:
def plotPanel(section,observedFlows=None,colorCode=True):
plt.figure(figsize=(7,3))
ax = plt.subplot(1,1,1,)
color = '#c3c3c3'; obsLabel = None
if section.label in observedFlows.keys():
if isinstance(observedFlows[section.label][1:],list) and isinstance(observedFlows[section.label][1:][0],float):
if colorCode == True:
if min(observedFlows[section.label][1:]) <= section.data.mean() <= max(observedFlows[section.label][1:]):
color = '#90ee90'
else: color = '#f26161';
obsLabel = str(min(observedFlows[section.label][1:])) + ' to ' + str(max(observedFlows[section.label][1:]))
else: obsLabel = str(observedFlows[section.label][1:]);
plt.plot(section.time,section.data,color=color)
plt.title(section.label,fontsize=14)
plt.text(0.04,0.11,'Mean = '+'{0:.2f}'.format(section.data.mean()),transform=ax.transAxes,fontsize=14)
if obsLabel is not None: plt.text(0.04,0.04,'Obs. = '+obsLabel,transform=ax.transAxes,fontsize=14)
if section.ylim is not None: plt.ylim(section.ylim)
plt.ylabel('Transport (Sv)',fontsize=14); plt.xlabel('Time since beginning of run (yr)',fontsize=14)
plt.grid()
return
Plot section transports in alphabetical order
Agulhas Section
[9]:
ds = []
agulhas = Transport(args,sections,'h.Agulhas_Section',debug=False); ds.append(agulhas)
plotPanel(agulhas, observedFlows=sections)
ERROR 1: PROJ: proj_create_from_database: Open of /glade/work/gmarques/conda-envs/mom6-tools/share/proj failed
Bering Strait
[10]:
bering = Transport(args, sections, 'h.Bering_Strait'); ds.append(bering)
plotPanel(bering, observedFlows=sections)
Barents opening
[11]:
barents = Transport(args, sections, 'h.Barents_Opening'); ds.append(barents)
plotPanel(barents, observedFlows=sections)
Davis Strait
[12]:
davis = Transport(args, sections,'h.Davis_Strait'); ds.append(davis)
plotPanel(davis, observedFlows=sections)
Denmark Strait
[13]:
denmark = Transport(args, sections,'h.Denmark_Strait'); ds.append(denmark)
plotPanel(denmark, observedFlows=sections)
Drake Passage
[14]:
drake = Transport(args, sections,'h.Drake_Passage'); ds.append(drake)
plotPanel(drake, observedFlows=sections)
English Channel
[15]:
english = Transport(args, sections, 'h.English_Channel'); ds.append(english)
plotPanel(english, observedFlows=sections)
Fram Strait
[16]:
fram = Transport(args, sections, 'h.Fram_Strait'); ds.append(fram)
plotPanel(fram, observedFlows=sections)
Florida Bahamas
[17]:
#florida1 = Transport(args, sections, 'h.Florida_Bahamas', debug=True); ds.append(florida1)
#plotPanel(florida1, observedFlows=sections)
Florida Bahamas extended
[18]:
florida2 = Transport(args, sections, 'h.Florida_Bahamas_extended'); ds.append(florida2)
plotPanel(florida2, observedFlows=sections)
Florida Cuba
[19]:
florida3 = Transport(args, sections, 'h.Florida_Cuba'); ds.append(florida3)
plotPanel(florida3, observedFlows=sections)
Gibraltar Strait
[20]:
gibraltar = Transport(args, sections, 'h.Gibraltar_Strait'); ds.append(gibraltar)
plotPanel(gibraltar, observedFlows=sections)
Iceland Norway
[21]:
#iceland = Transport(args, sections, 'h.Iceland_Norway', debug=True); ds.append(iceland)
#plotPanel(iceland, observedFlows=sections)
Indonesian Throughflow
[22]:
indo = Transport(args, sections, 'h.Indonesian_Throughflow'); ds.append(indo)
plotPanel(indo, observedFlows=sections)
Mozambique Channel
[23]:
mozambique = Transport(args, sections, 'h.Mozambique_Channel'); ds.append(mozambique)
plotPanel(mozambique, observedFlows=sections)
Pacific undercurrent
[24]:
euc = Transport(args, sections, 'h.Pacific_undercurrent'); ds.append(euc)
plotPanel(euc, observedFlows=sections)
Taiwan Luzon
[25]:
taiwan = Transport(args, sections, 'h.Taiwan_Luzon'); ds.append(taiwan)
plotPanel(taiwan, observedFlows=sections)
Windward Passage
[26]:
windward = Transport(args, sections, 'h.Windward_Passage'); ds.append(windward)
plotPanel(windward, observedFlows=sections)
Robeson_Channel
[27]:
roberson = Transport(args, sections, 'h.Robeson_Channel'); ds.append(roberson)
plotPanel(roberson, observedFlows=sections)
Yucatan_Channel
[28]:
yucatan = Transport(args, sections, 'h.Yucatan_Channel'); ds.append(yucatan)
plotPanel(yucatan, observedFlows=sections)
Bosporus_Strait
[31]:
#bosporus = Transport(args, sections, 'h.Bosporus_Strait', debug=True); ds.append(bosporus)
#plotPanel(bosporus, observedFlows=sections)
Save netcdf
[34]:
print('Saving netCDF file with transports...\n')
if not os.path.isdir('ncfiles'):
os.system('mkdir -p ncfiles')
# create a dataaray
labels = [];
for n in range(len(ds)): labels.append(ds[n].label)
var = numpy.zeros((len(ds),len(ds[0].time)))
ds_out = xr.Dataset(data_vars={ 'transport' : (('sections', 'time'), var)},
coords={'sections': labels,
'time': ds[0].time})
for n in range(len(ds)):
ds_out.transport.values[n,:] = ds[n].data
ds_out.to_netcdf('ncfiles/'+args.casename+'_section_transports.nc')
Saving netCDF file with transports...