Compare equatorial ocean metrics between obs and MOM6 run

  1. Thermocline depth, gradient, strength

  2. Compare cold tongue strength

  3. EUC MOM6 vs obs, strength, depth, gradient

Obs data: # Use something more current WOA18

  • /glade/p/cesm/omwg/obs_data/phc/PHC2_TEMP_tx0.66v1_34lev_ann_avg.nc

  • /glade/p/cesm/omwg/obs_data/phc/PHC2_SALT_tx0.66v1_34lev_ann_avg.nc

  • /glade/p/cesm/omwg/obs_data/johnson_pmel/meanfit_m.nc

Problems with this notebook:

  1. Actually the main problem is the use of zl and not e

  2. the directory is hardcoded, should do something like Gustavo did with yml file

  3. The units for U say they are different, but they are not different by 100. What is the issue with the EUC?

  4. the unified plot is just a draft, should think about that some more, how to summarize the equatorial region?

[1]:
# Frank's notebooks in MOM6-modeloutputanalysis/EquatorialPacific
# use the h files
# plot the model coordinates e
[2]:
# Load required modules
import warnings
warnings.filterwarnings("ignore") # I don't want any warnings (:

# the usual suspects
import numpy as np
from datetime import date
from matplotlib import pyplot as plt
import cartopy.crs as ccrs
import xarray as xr
import glob
import nc_time_axis # it says I need this to plot.. not sure

# dask helpers
from mom6_tools.jobqueue import get_cluster

# get mom6-tools
import mom6_tools
[3]:
parallel, cluster, client = get_cluster(
    30,
    cluster_class='PBSCluster',
    cores=4,
    processes=1,
    resource_spec='select=1:ncpus=1:mem=10GB',
)
client
Starting a dask cluster: PBSCluster

Requesting 30 workers...

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[3], line 1
----> 1 parallel, cluster, client = get_cluster(
      2     30,
      3     cluster_class='PBSCluster',
      4     cores=4,
      5     processes=1,
      6     resource_spec='select=1:ncpus=1:mem=10GB',
      7 )
      8 client

File ~/checkouts/readthedocs.org/user_builds/mom6-tools/envs/latest/lib/python3.10/site-packages/mom6_tools/jobqueue.py:300, in get_cluster(nw, cluster_class, args, config, **kwargs)
    297 print('Requesting {} workers... \n'.format(nw))
    298 if is_jobqueue_cluster:
    299   # dask.config.set({'distributed.dashboard.link': '/proxy/{port}/status'})
--> 300   cluster = cluster_class(**kwargs)
    301   cluster.scale(nw)
    302 else:

File ~/checkouts/readthedocs.org/user_builds/mom6-tools/envs/latest/lib/python3.10/site-packages/dask_jobqueue/core.py:661, in JobQueueCluster.__init__(self, n_workers, job_cls, loop, security, shared_temp_directory, silence_logs, name, asynchronous, dashboard_address, host, scheduler_options, scheduler_cls, interface, protocol, config_name, **job_kwargs)
    656 if "processes" in self._job_kwargs and self._job_kwargs["processes"] > 1:
    657     worker["group"] = [
    658         "-" + str(i) for i in range(self._job_kwargs["processes"])
    659     ]
--> 661 self._dummy_job  # trigger property to ensure that the job is valid
    663 super().__init__(
    664     scheduler=scheduler,
    665     worker=worker,
   (...)
    670     name=name,
    671 )
    673 if n_workers:

File ~/checkouts/readthedocs.org/user_builds/mom6-tools/envs/latest/lib/python3.10/site-packages/dask_jobqueue/core.py:690, in JobQueueCluster._dummy_job(self)
    688     address = "tcp://<insert-scheduler-address-here>:8786"
    689 try:
--> 690     return self.job_cls(
    691         address or "tcp://<insert-scheduler-address-here>:8786",
    692         # The 'name' parameter is replaced inside Job class by the
    693         # actual Dask worker name. Using 'dummy-name here' to make it
    694         # more clear that cluster.job_script() is similar to but not
    695         # exactly the same script as the script submitted for each Dask
    696         # worker
    697         name="dummy-name",
    698         **self._job_kwargs
    699     )
    700 except TypeError as exc:
    701     # Very likely this error happened in the self.job_cls constructor
    702     # because an unexpected parameter was used in the JobQueueCluster
    703     # constructor. The next few lines builds a more user-friendly error message.
    704     match = re.search("(unexpected keyword argument.+)", str(exc))

File ~/checkouts/readthedocs.org/user_builds/mom6-tools/envs/latest/lib/python3.10/site-packages/dask_jobqueue/pbs.py:55, in PBSJob.__init__(self, scheduler, name, queue, project, account, resource_spec, walltime, config_name, **base_class_kwargs)
     43 def __init__(
     44     self,
     45     scheduler=None,
   (...)
     53     **base_class_kwargs
     54 ):
---> 55     super().__init__(
     56         scheduler=scheduler, name=name, config_name=config_name, **base_class_kwargs
     57     )
     59     if queue is None:
     60         queue = dask.config.get("jobqueue.%s.queue" % self.config_name)

File ~/checkouts/readthedocs.org/user_builds/mom6-tools/envs/latest/lib/python3.10/site-packages/dask_jobqueue/core.py:202, in Job.__init__(self, scheduler, name, cores, memory, processes, nanny, protocol, security, interface, death_timeout, local_directory, extra, worker_command, worker_extra_args, job_extra, job_extra_directives, env_extra, job_script_prologue, header_skip, job_directives_skip, log_directory, shebang, python, job_name, config_name)
    200     job_class_name = self.__class__.__name__
    201     cluster_class_name = job_class_name.replace("Job", "Cluster")
--> 202     raise ValueError(
    203         "You must specify how much cores and memory per job you want to use, for example:\n"
    204         "cluster = {}(cores={}, memory={!r})".format(
    205             cluster_class_name, cores or 8, memory or "24GB"
    206         )
    207     )
    209 if python is None:
    210     python = dask.config.get("jobqueue.%s.python" % self.config_name)

ValueError: You must specify how much cores and memory per job you want to use, for example:
cluster = PBSCluster(cores=4, memory='24GB')
[4]:
# get the data from the coupled run
dirname = "/glade/scratch/gmarques/bmom.e23.f09_t061_zstar_N65.nuopc.GM_tuning.002/run"
static = xr.open_dataset(*glob.glob(f"{dirname}/*static*.nc"))
ds_coupled = xr.open_mfdataset(
    sorted(glob.glob(f"{dirname}/*.mom6.h_*.nc")),
    coords="minimal",
    data_vars="minimal",
    compat="override",
    use_cftime=True,
    parallel=True,
)
ds_coupled.coords.update(static.drop("time"))

# time averaging
thetao = ds_coupled.thetao.mean('time')
so = ds_coupled.so.mean('time')
uo = ds_coupled.uo.mean('time')
eta = ds_coupled.e.mean('time')

j = np.abs(ds_coupled.yh).argmin().values

thetao_eq_mom = thetao.isel(yh=slice(j-5,j+5)).mean('yh');
salt_eq_mom = so.isel(yh=slice(j-5,j+5)).mean('yh');
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[4], line 3
      1 # get the data from the coupled run 
      2 dirname = "/glade/scratch/gmarques/bmom.e23.f09_t061_zstar_N65.nuopc.GM_tuning.002/run"
----> 3 static = xr.open_dataset(*glob.glob(f"{dirname}/*static*.nc"))
      4 ds_coupled = xr.open_mfdataset(
      5     sorted(glob.glob(f"{dirname}/*.mom6.h_*.nc")),
      6     coords="minimal",
   (...)
     10     parallel=True,
     11 )
     12 ds_coupled.coords.update(static.drop("time"))

TypeError: open_dataset() missing 1 required positional argument: 'filename_or_obj'
[5]:
# load obs
phc_path = '/glade/p/cesm/omwg/obs_data/phc/'
phc_temp = xr.open_mfdataset(phc_path+'PHC2_TEMP_tx0.66v1_34lev_ann_avg.nc')
phc_salt = xr.open_mfdataset(phc_path+'PHC2_SALT_tx0.66v1_34lev_ann_avg.nc')
johnson = xr.open_dataset('/glade/p/cesm/omwg/obs_data/johnson_pmel/meanfit_m.nc')

# get theta and salt and rename coordinates to be the same as the model's
thetao_obs = phc_temp.TEMP.rename({'X': 'xh','Y': 'yh', 'depth': 'z_l'});
salt_obs = phc_salt.SALT.rename({'X': 'xh','Y': 'yh', 'depth': 'z_l'});

# set coordinates to the same as the model's
thetao_obs['xh'] = ds_coupled.xh; thetao_obs['yh'] = ds_coupled.yh;
salt_obs['xh'] = ds_coupled.xh; salt_obs['yh'] = ds_coupled.yh;

# get the equatorial zone +-5 degrees
thetao_eq_obs = thetao_obs.isel(yh=slice(j-5,j+5)).mean('yh');
salt_eq_obs = salt_obs.isel(yh=slice(j-5,j+5)).mean('yh')
---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
Cell In[5], line 3
      1 # load obs 
      2 phc_path = '/glade/p/cesm/omwg/obs_data/phc/'
----> 3 phc_temp = xr.open_mfdataset(phc_path+'PHC2_TEMP_tx0.66v1_34lev_ann_avg.nc')
      4 phc_salt = xr.open_mfdataset(phc_path+'PHC2_SALT_tx0.66v1_34lev_ann_avg.nc')
      5 johnson = xr.open_dataset('/glade/p/cesm/omwg/obs_data/johnson_pmel/meanfit_m.nc')

File ~/checkouts/readthedocs.org/user_builds/mom6-tools/envs/latest/lib/python3.10/site-packages/xarray/backends/api.py:1597, in open_mfdataset(paths, chunks, concat_dim, compat, preprocess, engine, data_vars, coords, combine, parallel, join, attrs_file, combine_attrs, **kwargs)
   1594 paths = _find_absolute_paths(paths, engine=engine, **kwargs)
   1596 if not paths:
-> 1597     raise OSError("no files to open")
   1599 paths1d: list[str | ReadBuffer]
   1600 if combine == "nested":

OSError: no files to open
[6]:
y = ds_coupled.yh.values
zz = ds_coupled.z_i.values
x = ds_coupled.xh.values
[X, Z] = np.meshgrid(x, zz)
z = 0.5 * ( Z[:-1] + Z[1:])
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[6], line 1
----> 1 y = ds_coupled.yh.values
      2 zz = ds_coupled.z_i.values
      3 x = ds_coupled.xh.values

NameError: name 'ds_coupled' is not defined
[7]:
fig, ax = plt.subplots(3, 1, figsize=(12, 14), sharex=True, sharey=True)
thetao_eq_obs.plot(y='z_l', ylim=(500,0), levels=np.arange(5,31,1), cmap='RdYlBu_r', extend='both', ax=ax[0])
ax[0].set_title('OBS')
ax[0].set_xlabel('')

thetao_eq_mom.plot(y='z_l', ylim=(500,0), levels=np.arange(5,31,1), cmap='RdYlBu_r',  extend='both', ax=ax[1])
ax[1].set_title('MOM6')
ax[1].set_xlabel('')

(thetao_eq_mom-thetao_eq_obs).plot(y='z_l', ylim=(500,0), levels=np.arange(-5,5.1,.1), cmap='RdYlBu_r', extend='both', ax=ax[2])
ax[2].set_title('MOM6-OBS')

ax[2].text(-170, 440, 'Pacific')
ax[2].text(-30, 440, 'Atlantic')
plt.savefig('Eq_temp_MOM6_obs.png', bbox_inches='tight')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[7], line 2
      1 fig, ax = plt.subplots(3, 1, figsize=(12, 14), sharex=True, sharey=True)
----> 2 thetao_eq_obs.plot(y='z_l', ylim=(500,0), levels=np.arange(5,31,1), cmap='RdYlBu_r', extend='both', ax=ax[0])
      3 ax[0].set_title('OBS')
      4 ax[0].set_xlabel('')

NameError: name 'thetao_eq_obs' is not defined
../_images/examples_EquatorialOceanMetrics_7_1.png
[8]:
tc_eq_mom = thetao_eq_mom.differentiate('z_l').fillna(0).argmin(dim='z_l')
tc_eq_obs = thetao_eq_obs.differentiate('z_l').fillna(0).argmin(dim='z_l')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[8], line 1
----> 1 tc_eq_mom = thetao_eq_mom.differentiate('z_l').fillna(0).argmin(dim='z_l')
      2 tc_eq_obs = thetao_eq_obs.differentiate('z_l').fillna(0).argmin(dim='z_l')

NameError: name 'thetao_eq_mom' is not defined
[9]:
# this is not going to work for hybrid -- the layers
# set up e_mid as the z coordinate then differentiate with respect to e_mid
[10]:
fig, ax = plt.subplots(3, 1, figsize=(12, 10), sharex=True, sharey=True)
thetao_eq_obs.differentiate('z_l').plot(y='z_l', ylim=(300,0), levels=np.arange(0,-0.35,-0.05),
                                                                        cmap='Blues', extend='both', ax=ax[0])
thetao_eq_obs['z_l'][thetao_eq_obs.differentiate('z_l').fillna(0).argmin(dim='z_l')].plot(label='Obs', ax=ax[0], c='k')
ax[0].set_title('OBS')
ax[0].set_xlabel('')

thetao_eq_mom.differentiate('z_l').plot(y='z_l', ylim=(300,0), levels=np.arange(0,-0.35,-0.05),
                                                                    cmap='Blues', extend='both', ax=ax[1])
thetao_eq_mom['z_l'][thetao_eq_mom.differentiate('z_l').fillna(0).argmin(dim='z_l')].plot(label='MOM6', ax=ax[1], c='red')
ax[1].set_title('MOM6')
ax[1].set_xlabel('')

(thetao_eq_mom-thetao_eq_obs).differentiate('z_l').plot(y='z_l', ylim=(300,0), levels=np.arange(-0.2,0.225,0.025),
                                                                                 cmap='RdYlBu_r', extend='both', ax=ax[2])
ax[2].set_title('MOM6-OBS')
thetao_eq_mom['z_l'][thetao_eq_mom.differentiate('z_l').fillna(0).argmin(dim='z_l')].plot(label='MOM6', ax=ax[2], c='red')
thetao_eq_obs['z_l'][thetao_eq_obs.differentiate('z_l').fillna(0).argmin(dim='z_l')].plot(label='Obs', ax=ax[2], c='k')
ax[2].legend()

ax[2].text(-170, 440, 'Pacific')
ax[2].text(-30, 440, 'Atlantic')
plt.savefig('Eq_diff_temp_MOM6_obs.png', bbox_inches='tight')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[10], line 2
      1 fig, ax = plt.subplots(3, 1, figsize=(12, 10), sharex=True, sharey=True)
----> 2 thetao_eq_obs.differentiate('z_l').plot(y='z_l', ylim=(300,0), levels=np.arange(0,-0.35,-0.05),
      3                                                                         cmap='Blues', extend='both', ax=ax[0])
      4 thetao_eq_obs['z_l'][thetao_eq_obs.differentiate('z_l').fillna(0).argmin(dim='z_l')].plot(label='Obs', ax=ax[0], c='k')
      5 ax[0].set_title('OBS')

NameError: name 'thetao_eq_obs' is not defined
../_images/examples_EquatorialOceanMetrics_10_1.png
[11]:
tc_depth_mom = thetao_eq_mom['z_l'][tc_eq_mom]
tc_depth_obs = thetao_eq_obs['z_l'][tc_eq_obs]
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[11], line 1
----> 1 tc_depth_mom = thetao_eq_mom['z_l'][tc_eq_mom]
      2 tc_depth_obs = thetao_eq_obs['z_l'][tc_eq_obs]

NameError: name 'thetao_eq_mom' is not defined
[12]:
%%time

fig, ax = plt.subplots(1, 1, figsize=(12, 3), sharex=True, sharey=True)

thetao_eq_mom['z_l'][tc_eq_mom].plot(label='MOM6', ax=ax, c='red')
thetao_eq_obs['z_l'][tc_eq_obs].plot(label='Obs', ax=ax, c='k', ylim=(200,0))
ax.legend()
ax.set_title('thermocline depth equator max gradient')

plt.savefig('thermocline_depth_mom6_obs_bias.png', bbox_inches='tight')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
File <timed exec>:3

NameError: name 'thetao_eq_mom' is not defined
../_images/examples_EquatorialOceanMetrics_12_1.png
[13]:
## get the gradient

xlonpacwest = -200
xlonpaceast = -100

xlonatlwest = -45
xlonatleast =  10

tc_gradient_pacific_obs = (tc_depth_obs.sel(xh=xlonpacwest, method='nearest').values
                           -
                           tc_depth_obs.sel(xh=xlonpaceast, method='nearest').values)

tc_gradient_atlantic_obs= (tc_depth_obs.sel(xh=xlonatlwest, method='nearest').values
                           -
                           tc_depth_obs.sel(xh=xlonatleast, method='nearest').values)

tc_gradient_pacific_mom = (tc_depth_mom.sel(xh=xlonpacwest, method='nearest').values
                           -
                           tc_depth_mom.sel(xh=xlonpaceast, method='nearest').values)

tc_gradient_atlantic_mom= (tc_depth_mom.sel(xh=xlonatlwest, method='nearest').values
                           -
                           tc_depth_mom.sel(xh=xlonatleast, method='nearest').values)

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[13], line 9
      6 xlonatlwest = -45
      7 xlonatleast =  10
----> 9 tc_gradient_pacific_obs = (tc_depth_obs.sel(xh=xlonpacwest, method='nearest').values
     10                            -
     11                            tc_depth_obs.sel(xh=xlonpaceast, method='nearest').values)
     13 tc_gradient_atlantic_obs= (tc_depth_obs.sel(xh=xlonatlwest, method='nearest').values
     14                            -
     15                            tc_depth_obs.sel(xh=xlonatleast, method='nearest').values)
     17 tc_gradient_pacific_mom = (tc_depth_mom.sel(xh=xlonpacwest, method='nearest').values
     18                            -
     19                            tc_depth_mom.sel(xh=xlonpaceast, method='nearest').values)

NameError: name 'tc_depth_obs' is not defined
[14]:
print('TC Pacific gradient obs:', tc_gradient_pacific_obs)
print('TC Pacific gradient mom:', tc_gradient_pacific_mom)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[14], line 1
----> 1 print('TC Pacific gradient obs:', tc_gradient_pacific_obs)
      2 print('TC Pacific gradient mom:', tc_gradient_pacific_mom)

NameError: name 'tc_gradient_pacific_obs' is not defined
[15]:
print('TC Atlantic gradient obs:', tc_gradient_atlantic_obs)
print('TC Atlantic gradient mom:', tc_gradient_atlantic_mom)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[15], line 1
----> 1 print('TC Atlantic gradient obs:', tc_gradient_atlantic_obs)
      2 print('TC Atlantic gradient mom:', tc_gradient_atlantic_mom)

NameError: name 'tc_gradient_atlantic_obs' is not defined
[16]:
# get a handle for the strenth of the tc
mom_tc = thetao_eq_mom.differentiate('z_l').fillna(0).min(dim='z_l')
obs_tc = thetao_eq_obs.differentiate('z_l').fillna(0).min(dim='z_l')

tcstr_mom_pac = mom_tc.sel(xh=slice(xlonpacwest, xlonpaceast)).mean('xh').values
tcstr_obs_pac = obs_tc.sel(xh=slice(xlonpacwest, xlonpaceast)).mean('xh').values

tcstr_mom_atl = mom_tc.sel(xh=slice(xlonatlwest, xlonatleast)).mean('xh').values
tcstr_obs_atl = obs_tc.sel(xh=slice(xlonatlwest, xlonatleast)).mean('xh').values
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[16], line 2
      1 # get a handle for the strenth of the tc
----> 2 mom_tc = thetao_eq_mom.differentiate('z_l').fillna(0).min(dim='z_l')
      3 obs_tc = thetao_eq_obs.differentiate('z_l').fillna(0).min(dim='z_l')
      5 tcstr_mom_pac = mom_tc.sel(xh=slice(xlonpacwest, xlonpaceast)).mean('xh').values

NameError: name 'thetao_eq_mom' is not defined
[17]:
print('ATL')
print('mom:', tcstr_mom_atl)
print('obs:', tcstr_obs_atl)

print('PAC')
print('mom:', tcstr_mom_pac)
print('obs:', tcstr_obs_pac)
ATL
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[17], line 2
      1 print('ATL')
----> 2 print('mom:', tcstr_mom_atl)
      3 print('obs:', tcstr_obs_atl)
      5 print('PAC')

NameError: name 'tcstr_mom_atl' is not defined

EUC

  • depth

  • strength

  • gradient

[18]:
u_eq_mom = uo.isel(yh=slice(j-5,j+5)).mean('yh');
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[18], line 1
----> 1 u_eq_mom = uo.isel(yh=slice(j-5,j+5)).mean('yh');

NameError: name 'uo' is not defined
[19]:
johnson['XLON'] = (johnson.XLON-360)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[19], line 1
----> 1 johnson['XLON'] = (johnson.XLON-360)

NameError: name 'johnson' is not defined
[20]:
%%time
fig, ax = plt.subplots(2, 1, figsize=(12, 5), sharex=True, sharey=True)
(johnson.UM).sel(YLAT11_101=slice(-5,5)).mean('YLAT11_101').plot(y='ZDEP1_50', ylim=(300,0), levels=np.arange(-0.8,0.85,0.05),
                                                                        cmap='RdYlBu_r', extend='both', ax=ax[0])
johnson['ZDEP1_50'][johnson.UM.sel(YLAT11_101=slice(-5,5)).mean('YLAT11_101').argmax(dim='ZDEP1_50')].plot(label='Obs', ax=ax[0], c='k')
ax[0].set_title('OBS')
ax[0].set_xlabel('')

(u_eq_mom).plot(y='z_l', ylim=(300,0), levels=np.arange(-0.8,0.85,0.05), cmap='RdYlBu_r', extend='both', ax=ax[1])
u_eq_mom['z_l'][u_eq_mom.fillna(0).argmax(dim='z_l')].plot(label='MOM6', ax=ax[1], c='red')
ax[1].set_title('MOM6')
ax[1].set_xlabel('')

ax[1].text(-170, 270, 'Pacific')
ax[1].text(-30, 270, 'Atlantic')

plt.savefig('Eq_U_MOM6_obs.png', bbox_inches='tight')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
File <timed exec>:2

NameError: name 'johnson' is not defined
../_images/examples_EquatorialOceanMetrics_21_1.png
[21]:
%%time

fig, ax = plt.subplots(1, 1, figsize=(12, 3), sharex=True, sharey=True)

johnson['ZDEP1_50'][johnson.UM.sel(YLAT11_101=slice(-5,5)).mean('YLAT11_101').argmax(dim='ZDEP1_50')].plot(label='Obs', ax=ax, c='k')
u_eq_mom['z_l'][u_eq_mom.fillna(0).argmax(dim='z_l')].plot(label='MOM6', ax=ax, c='red')
ax.legend()
ax.set_xlim(-200,-90)
ax.set_title('EUC depth')
ax.set_ylim(210,0)
ax.set_ylabel('Depth [m]')
ax.set_xlabel('Degrees East')
plt.savefig('EUC_johnson_mom6.png', bbox_inches='tight')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
File <timed exec>:3

NameError: name 'johnson' is not defined
../_images/examples_EquatorialOceanMetrics_22_1.png

Get the gradient of the EUC

[22]:
# xlon1 = johnson['ZDEP1_50'][johnson.UM.sel(YLAT11_101=slice(-5,5)).mean('YLAT11_101').argmax(dim='ZDEP1_50')].XLON[0].values
# xlonlast = johnson['ZDEP1_50'][johnson.UM.sel(YLAT11_101=slice(-5,5)).mean('YLAT11_101').argmax(dim='ZDEP1_50')].XLON[-1].values
# it's better to specify longitudes
xlon1=-200
xlon2=-100

depth_euc_obs = johnson['ZDEP1_50'][johnson.UM.sel(YLAT11_101=slice(-5,5)).mean('YLAT11_101').argmax(dim='ZDEP1_50')]
depth_euc_mom = u_eq_mom['z_l'][u_eq_mom.fillna(0).argmax(dim='z_l')]
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[22], line 7
      4 xlon1=-200
      5 xlon2=-100
----> 7 depth_euc_obs = johnson['ZDEP1_50'][johnson.UM.sel(YLAT11_101=slice(-5,5)).mean('YLAT11_101').argmax(dim='ZDEP1_50')]
      8 depth_euc_mom = u_eq_mom['z_l'][u_eq_mom.fillna(0).argmax(dim='z_l')]

NameError: name 'johnson' is not defined
[23]:
# get gradient:
grad_euc_obs = (depth_euc_obs.sel(XLON=xlon1, method='nearest').values - depth_euc_obs.sel(XLON=xlonlast, method='nearest').values)
grad_euc_mom = (depth_euc_mom.sel(xq=xlon1, method='nearest').values - depth_euc_mom.sel(xq=xlonlast, method='nearest').values)
print('EUC gradient obs:', grad_euc_obs)
print('EUC gradient mom:', grad_euc_mom)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[23], line 2
      1 # get gradient: 
----> 2 grad_euc_obs = (depth_euc_obs.sel(XLON=xlon1, method='nearest').values - depth_euc_obs.sel(XLON=xlonlast, method='nearest').values)
      3 grad_euc_mom = (depth_euc_mom.sel(xq=xlon1, method='nearest').values - depth_euc_mom.sel(xq=xlonlast, method='nearest').values)
      4 print('EUC gradient obs:', grad_euc_obs)

NameError: name 'depth_euc_obs' is not defined
[24]:
johnson.UM.sel(YLAT11_101=slice(-5,5)).mean('YLAT11_101').max(dim='ZDEP1_50').plot()
u_eq_mom.fillna(0).max(dim='z_l').plot()
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[24], line 1
----> 1 johnson.UM.sel(YLAT11_101=slice(-5,5)).mean('YLAT11_101').max(dim='ZDEP1_50').plot()
      2 u_eq_mom.fillna(0).max(dim='z_l').plot()

NameError: name 'johnson' is not defined
[25]:
# mean strength EUC
mean_euc_obs = johnson.UM.sel(YLAT11_101=slice(-5,5)).mean('YLAT11_101').max(dim='ZDEP1_50').sel(XLON=slice(xlon1,xlon2)).mean('XLON').values
mean_euc_mom = u_eq_mom.fillna(0).max(dim='z_l').sel(xq=slice(xlon1,xlon2)).mean('xq').values
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[25], line 2
      1 # mean strength EUC
----> 2 mean_euc_obs = johnson.UM.sel(YLAT11_101=slice(-5,5)).mean('YLAT11_101').max(dim='ZDEP1_50').sel(XLON=slice(xlon1,xlon2)).mean('XLON').values
      3 mean_euc_mom = u_eq_mom.fillna(0).max(dim='z_l').sel(xq=slice(xlon1,xlon2)).mean('xq').values

NameError: name 'johnson' is not defined

it looks like the metrics are different but the values actually line up??

[26]:
johnson.UM.attrs
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[26], line 1
----> 1 johnson.UM.attrs

NameError: name 'johnson' is not defined
[27]:
ds_coupled.uo.attrs
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[27], line 1
----> 1 ds_coupled.uo.attrs

NameError: name 'ds_coupled' is not defined

Cold tongue

[28]:
fig, ax = plt.subplots(3, 1, figsize=(12,8), sharex=True, sharey=True)
# look at the Benguela
thetao_obs.isel(z_l=0).sel(yh=slice(-12, 10)).plot(ax=ax[0], levels=np.arange(20,31,1), cmap='RdYlBu_r', xlim=(-200,20));
ax[0].set_xlabel('');
ax[0].set_title('OBS');

thetao.isel(z_l=0).sel(yh=slice(-12, 10)).plot(ax=ax[1], levels=np.arange(20,31,1), cmap='RdYlBu_r', xlim=(-200,20));
ax[1].set_title('MOM6');
ax[1].set_xlabel('');

(thetao-thetao_obs).isel(z_l=0).sel(yh=slice(-12, 10)).plot(ax=ax[2], levels=np.arange(-3,3.1,0.1), cmap='RdYlBu_r', xlim=(-200,20));
ax[2].set_title('MOM6-OBS');

plt.savefig('cold_tongues_obs_mom6.png', bbox_inches='tight');
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[28], line 3
      1 fig, ax = plt.subplots(3, 1, figsize=(12,8), sharex=True, sharey=True)
      2 # look at the Benguela
----> 3 thetao_obs.isel(z_l=0).sel(yh=slice(-12, 10)).plot(ax=ax[0], levels=np.arange(20,31,1), cmap='RdYlBu_r', xlim=(-200,20));
      4 ax[0].set_xlabel('');
      5 ax[0].set_title('OBS');

NameError: name 'thetao_obs' is not defined
../_images/examples_EquatorialOceanMetrics_32_1.png
[29]:
fig, ax = plt.subplots(3, 1, figsize=(12,8), sharex=True, sharey=True)
# look at the Benguela
thetao_obs.isel(z_l=0).sel(yh=slice(-25, 10)).plot(ax=ax[0], levels=np.arange(20,31,1), cmap='RdYlBu_r', xlim=(-200,20));
ax[0].set_xlabel('');
ax[0].set_title('OBS');

thetao.isel(z_l=0).sel(yh=slice(-25, 10)).plot(ax=ax[1], levels=np.arange(20,31,1), cmap='RdYlBu_r', xlim=(-200,20));
ax[1].set_title('MOM6');
ax[1].set_xlabel('');

(thetao-thetao_obs).isel(z_l=0).sel(yh=slice(-25, 10)).plot(ax=ax[2], levels=np.arange(-4,4.1,0.1), cmap='RdYlBu_r', xlim=(-200,20));
ax[2].set_title('MOM6-OBS');

plt.savefig('cold_tongues_obs_mom6.png', bbox_inches='tight');
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[29], line 3
      1 fig, ax = plt.subplots(3, 1, figsize=(12,8), sharex=True, sharey=True)
      2 # look at the Benguela
----> 3 thetao_obs.isel(z_l=0).sel(yh=slice(-25, 10)).plot(ax=ax[0], levels=np.arange(20,31,1), cmap='RdYlBu_r', xlim=(-200,20));
      4 ax[0].set_xlabel('');
      5 ax[0].set_title('OBS');

NameError: name 'thetao_obs' is not defined
../_images/examples_EquatorialOceanMetrics_33_1.png

Some things to look at:

  • winds? have a look at CESM2 and these runs ; Ghokan’s paper? std diagnostics

  • what about if you change the topography?

  • can we do high res atmosphere yet? ask Brian Medeiros and Julio (non leaky topo); Rich Neal add Cecile | send an email to Justin

  • stratocumulus

  • ITCZ –> where is it?

  • currents?

  • maybe SST variability?

[30]:
# get location and temperature of cold tongue minimum in the Pacific
ct_loc_obs = thetao_obs.isel(z_l=0).sel(yh=slice(-2, 2), xh=slice(-200,-80)).argmin(dim=['xh','yh'])#['xh'].values
ct_min_obs = thetao_obs.isel(z_l=0).sel(yh=slice(-2, 2)).min(dim=['xh','yh']).values

ct_loc_mom = ds_coupled.thetao.mean('time').isel(z_l=0).sel(yh=slice(-2, 2), xh=slice(-200,-80)).argmin(dim=['xh','yh'])#['xh'].values
ct_min_mom = ds_coupled.thetao.mean('time').isel(z_l=0).sel(yh=slice(-2, 2)).min(dim=['xh','yh']).values

# This is currently useless in the Atlantic since there is no cold tongue in MOM...
# talk to Justin. Something should really be done about this.
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[30], line 2
      1 # get location and temperature of cold tongue minimum in the Pacific
----> 2 ct_loc_obs = thetao_obs.isel(z_l=0).sel(yh=slice(-2, 2), xh=slice(-200,-80)).argmin(dim=['xh','yh'])#['xh'].values
      3 ct_min_obs = thetao_obs.isel(z_l=0).sel(yh=slice(-2, 2)).min(dim=['xh','yh']).values
      5 ct_loc_mom = ds_coupled.thetao.mean('time').isel(z_l=0).sel(yh=slice(-2, 2), xh=slice(-200,-80)).argmin(dim=['xh','yh'])#['xh'].values

NameError: name 'thetao_obs' is not defined

Unified plot

show:

  • tc strength and gradient per basin

  • euc strength and gradient

[31]:
%%time

# come up with a clever figure that shows this
# summary of the equatorial state --> should have some more info, or maybe be more of a schematic?
fig, ax = plt.subplots(1, 3, figsize=(10,2))

ax[0].scatter(tc_gradient_pacific_mom, tcstr_mom_pac, c='red', label='Pacific')
ax[0].scatter(tc_gradient_pacific_obs, tcstr_obs_pac, c='k')

ax[0].scatter(tc_gradient_atlantic_mom, tcstr_mom_atl, c='red', marker='d', label='Atlantic')
ax[0].scatter(tc_gradient_atlantic_obs, tcstr_obs_atl, c='k', marker='d')
ax[0].legend(loc='center right', frameon=True)


ax[1].scatter(grad_euc_mom, mean_euc_mom, c='red', label='MOM')
ax[1].scatter(grad_euc_obs, mean_euc_obs, c='k', label='OBS')
ax[1].legend(loc='lower right', frameon=True)
ax[0].set_title('Thermocline')
ax[1].set_title('EUC')

ax[0].set_xlabel('Gradient [m]')
ax[1].set_xlabel('Gradient [m]')

ax[0].set_ylabel(r'dT/dz [$^{\circ}$C]')
ax[1].set_ylabel(r'[]')

ax[2].scatter(thetao_obs.sel(yh=slice(-2, 2), xh=slice(-200,-80)).xh[ct_loc_obs['xh'].values],
              thetao_obs.sel(yh=slice(-2, 2), xh=slice(-200,-80)).yh[ct_loc_obs['yh'].values], c='black')
ax[2].text(thetao_obs.sel(yh=slice(-2, 2), xh=slice(-200,-80)).xh[ct_loc_obs['xh'].values],
              thetao_obs.sel(yh=slice(-2, 2), xh=slice(-200,-80)).yh[ct_loc_obs['yh'].values],
          '{:3.1f}'.format(ct_min_obs)+r'$^{\circ}$C', c='blue')
ax[2].scatter(ds_coupled.thetao.sel(yh=slice(-2, 2), xh=slice(-200,-80)).xh[ct_loc_mom['xh'].values],
              ds_coupled.thetao.sel(yh=slice(-2, 2), xh=slice(-200,-80)).yh[ct_loc_mom['yh'].values], c='red')
ax[2].text(ds_coupled.thetao.sel(yh=slice(-2, 2), xh=slice(-200,-80)).xh[ct_loc_mom['xh'].values],
              ds_coupled.thetao.sel(yh=slice(-2, 2), xh=slice(-200,-80)).yh[ct_loc_mom['yh'].values],
           '{:3.1f}'.format(ct_min_mom)+r'$^{\circ}$C', c='blue')

ax[2].set_ylabel(r'Latitude [$^{\circ}$N]')
ax[2].set_xlabel(r'Longitude [$^{\circ}$E]')

ax[2].set_title('Cold tongue Pacific')

plt.subplots_adjust(wspace=0.4)

plt.savefig('first_draft_of_unified_plot_EqBelt.png', bbox_inches='tight')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
File <timed exec>:5

NameError: name 'tc_gradient_pacific_mom' is not defined
../_images/examples_EquatorialOceanMetrics_37_1.png
[ ]: