Created by Ivan Lima on Mon Apr 30 2018 14:13:07 -0400
%matplotlib notebook
import pandas as pd
import xarray as xr
import numpy as np
import matplotlib.pyplot as plt
import os, gsw
from matplotlib import colors
from cesm_utils import da2ma, fixtime, spd, dpm
from he3_inventory import *
from cases import *
from datetime import datetime
print('Last updated on %s'%datetime.now().ctime())
plt.rcParams['xtick.minor.bottom'] = False # fix strange minor ticks in time series plots
case = 'tr3he.GIAF.06'
print(case,':',case_info[case])
def get_lat_band(df, latmin, latmax, zsurf=-10):
""" extract obs at given latitude bands """
band = df[(df.tritium_flag==2) | (df.tritium_flag==6)] # only valid measurements
band = band[band.latitude <= latmax]
band = band[band.latitude > latmin]
if zsurf:
band = band[band.depth > zsurf]
band = band[['stadate','latitude','longitude','depth','tritium','tritium_error','tritium_flag']]
return band.sort_values('stadate') # sort by date
def lat_band_mean(ds, latmin, latmax, vname='TRITIUM'):
""" compute min, max & area weighted averages for model """
da = ds[vname].where((ds.TLAT>latmin) & (ds.TLAT<=latmax))
area = ds.TAREA.where((ds.TLAT>latmin) & (ds.TLAT<=latmax))
vmean = (da * area).sum(dim=['nlat','nlon']) / area.sum(dim=['nlat','nlon'])
vstd = np.sqrt(((da - vmean)**2 * area).sum(dim=['nlat','nlon']) / area.sum(dim=['nlat','nlon']))
vmin, vmax = vmean - 1.96 * vstd, vmean + 1.96 * vstd # 95% confidence interval
vmin[vmin<0] = 0
return pd.DataFrame({'model':vmean.to_series(), 'vmin': vmin.to_series(), 'vmax':vmax.to_series()})
lat_bands = ((-90,-60), (-60,-45), (-45,-5), (-5,15), (15,45), (45,60), (60,90))
zbins2 = np.array([-4000, -3500, -3000, -2500, -2000, -1500, -1000, -500, -400, -300, -250, -200, -150, -100, -50, 0])
def dyear2date(strn_list, yr0=1950): # convert decimal year to date objects
ndays = [np.round((np.float(x)-yr0) * 365.2425) for x in strn_list] # number of days since 1950-01-01
return pd.to_datetime(ndays, unit='D',origin='%d-01-01'%yr0)
database = pd.read_csv('../data/tritium-helium_database/tritium_helium_all_revised.csv', index_col=0, na_values=-999,
parse_dates=[6], date_parser=dyear2date, low_memory=False)
database['depth'] = gsw.z_from_p(np.abs(database.pressure), database.latitude) # compute depth from pressure
ds_model = xr.open_dataset('/home/ivan/Data/Postproc/Tritium-3H/surface.%s.nc'%case, decode_times=False)
ds_model = fixtime(ds_model, 1824)
ds_model = ds_model.squeeze(dim='z_t')
ds_model = ds_model.drop(['z_t'])
ds_model['TAREA'] = ds_model.TAREA.where(ds_model.REGION_MASK>0) # mask land & marginal seas
ds_model['TRITIUM'] = ds_model.TRITIUM.where(ds_model.REGION_MASK>0)
ds_model['TRITIUM'] = xr.where(ds_model.TRITIUM<0, 0, ds_model.TRITIUM) # remove negative values
ds_model['time'] = ds_model.time.to_index().to_datetimeindex()
Shaded area corresponds to 95% confidence interval for model mean.
fig, axs = plt.subplots(len(lat_bands),1,sharex=True,figsize=(6.4,10))
fig.subplots_adjust(top=0.95,hspace=0.3)
for ax, band in zip(axs.ravel(), lat_bands[::-1]):
df_obs = get_lat_band(database, *band)
df_obs['tritium'] = df_obs.tritium * 0.10995 # TU -> pmol/m^3
df_obs.rename({'tritium': 'observations'}, axis='columns', inplace=True)
df_mod = lat_band_mean(ds_model,*band)
_ = df_obs.plot(x='stadate', y='observations', style='.', ax=ax, legend=False, markersize=2)
_ = df_mod['model'].plot(ax=ax, style='-', legend=False)
_ = ax.fill_between(df_mod.index, df_mod.vmin, df_mod.vmax, facecolor='C1', alpha=0.3)
_ = ax.set_title('lat: {} to {}'.format(*band), fontsize=10)
_ = ax.legend(loc='best')
ax.autoscale(axis='x',tight=True)
_ = fig.text(0.05,0.575,'surface tritium (pmol m$^{-3}$)',ha='center',va='center',rotation=90)
ds_model_inv = xr.open_dataset('/home/ivan/Data/Postproc/Tritium-3H/tritium.%s.nc'%case)
ds_model_inv['TAREA'] = ds_model_inv.TAREA.where(ds_model_inv.REGION_MASK>0) # mask land & marginal seas
ds_model_inv['time'] = ds_model_inv.time.to_index().to_datetimeindex()
Shaded area corresponds to 95% confidence interval for model mean.
fig, axs = plt.subplots(len(lat_bands),1,sharex=True,figsize=(6.4,10))
fig.subplots_adjust(top=0.95,hspace=0.3)
for ax, band in zip(axs.ravel(), lat_bands[::-1]):
df_obs = get_lat_band(database, *band, zsurf=None)
profile, x, y = get_profile(df_obs, zb=zbins2)
inventory = get_inventory(profile,nn=11,zb=zbins2)
df_mod = lat_band_mean(ds_model_inv,*band,'TRITIUM_inventory')
_ = inventory.plot(style='.', ax=ax, legend=False, markersize=2)
_ = df_mod['model'].plot(ax=ax, style='-', legend=False)
_ = ax.fill_between(df_mod.index, df_mod.vmin, df_mod.vmax, facecolor='C1', alpha=0.3)
_ = ax.set_title('lat: {} to {}'.format(*band), fontsize=10)
_ = ax.legend(loc='best')
ax.autoscale(axis='x',tight=True)
_ = fig.text(0.05,0.575,'tritium inventory (pmol m$^{-2}$)',ha='center',va='center',rotation=90)
from scipy.interpolate import griddata
from ccsm_utils import grid_area
from ipyparallel import Client
cl = Client()
nprocs = len(cl.ids)
if nprocs > 0: print('running on %d cores'%nprocs)
dview = cl[:]
dview.block = True
dview.execute('import numpy as np')
dview.execute('from scipy.interpolate import griddata')
lview = cl.load_balanced_view()
lview.block = True
def pregrid(data):
work1 = np.array(data.tolist(),copy=False)
work2 = griddata((lonold,latold),work1,(lonnew,latnew),method='linear')
work3 = np.ma.masked_where(np.isnan(work2),work2)
return np.ma.average(work3, axis=1, weights=area)
lon, lat = np.arange(-97,19,1), np.arange(-33.5,69,0.5)
ulon, ulat = np.hstack([lon - 0.5, lon[-1] + 0.5]), np.hstack([lat - 0.25, lat[-1] + 0.25])
lon_new, lat_new = np.meshgrid(lon, lat)
area = grid_area(ulon,ulat)
tlon = xr.where(ds_model_inv.TLONG>180,ds_model_inv.TLONG-360,ds_model_inv.TLONG).values
tlat = ds_model_inv.TLAT.values
data = ds_model_inv.TRITIUM_inventory.where(ds_model_inv.REGION_MASK==6).values
dview.push(dict(lonold=tlon.ravel(),latold=tlat.ravel(),lonnew=lon_new,latnew=lat_new,area=area))
ntime = ds_model_inv.TRITIUM_inventory.shape[0]
arglist = [data[t,...].ravel() for t in range(ntime)]
result = lview.map_sync(pregrid,arglist)
zavg_atl = np.ma.array(result)
# nlon, nlat = lon.shape[0], lat.shape[0]
# zavg_atl = np.ma.masked_all((ntime,nlat),dtype=np.float)
# for n in range(ntime):
# work = griddata((tlon.data.ravel(),tlat.data.ravel()),data[n,...].data.ravel(),(lon_new,lat_new),method='linear')
# work = np.ma.masked_where(np.isnan(work),work)
# zavg_atl[n,...] = np.ma.average(work, axis=1, weights=area)
fig, ax = plt.subplots()
pm = ax.pcolormesh(ds_model_inv.time, lat, zavg_atl.transpose(),cmap=plt.cm.plasma)
_ = ax.set(xlabel='time', ylabel='latitude', title='Atlantic tritium inventory zonal average')
cb = fig.colorbar(pm,ax=ax)
cb.set_label('pmol m$^{-2}$')
lon, lat = np.arange(100,291,1), np.arange(-33.5,67,0.5)
ulon, ulat = np.hstack([lon - 0.5, lon[-1] + 0.5]), np.hstack([lat - 0.25, lat[-1] + 0.25])
lon_new, lat_new = np.meshgrid(lon, lat)
area = grid_area(ulon,ulat)
tlon = ds_model_inv.TLONG.values
tlat = ds_model_inv.TLAT.values
data = ds_model_inv.TRITIUM_inventory.where(ds_model_inv.REGION_MASK==2).values
dview.push(dict(lonold=tlon.ravel(),latold=tlat.ravel(),lonnew=lon_new,latnew=lat_new,area=area))
ntime = ds_model_inv.TRITIUM_inventory.shape[0]
arglist = [data[t,...].ravel() for t in range(ntime)]
result = lview.map_sync(pregrid,arglist)
zavg_pac = np.ma.array(result)
# nlon, nlat = lon.shape[0], lat.shape[0]
# zavg_pac = np.ma.masked_all((ntime,nlat),dtype=np.float)
# for n in range(ntime):
# work = griddata((tlon.data.ravel(),tlat.data.ravel()),data[n,...].data.ravel(),(lon_new,lat_new),method='linear')
# work = np.ma.masked_where(np.isnan(work),work)
# zavg_pac[n,...] = np.ma.average(work, axis=1, weights=area)
fig, ax = plt.subplots()
pm = ax.pcolormesh(ds_model_inv.time, lat, zavg_pac.transpose(),cmap=plt.cm.plasma)
_ = ax.set(xlabel='time', ylabel='latitude', title='Pacific tritium inventory zonal average')
cb = fig.colorbar(pm,ax=ax)
cb.set_label('pmol m$^{-2}$')