Skip to content

Commit bf21838

Browse files
committed
Merge branch 'master' into FW_budget
2 parents cec735f + 2ade3cf commit bf21838

18 files changed

Lines changed: 10492 additions & 57 deletions

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ _templates
44
*.ipynb_checkpoints*
55
/Tutorials_as_Jupyter_Notebooks/.ipynb_checkpoints/*
66
.README.md.swp
7+
/ECCO-ACCESS/Downloading_ECCO_Datasets_from_PODAAC/~/
8+
*.pyc

ECCO-ACCESS/Downloading_ECCO_datasets_from_PODAAC/Tutorial_Python3_Jupyter_Notebook_Downloading_ECCO_Datasets_from_PODAAC.ipynb

Lines changed: 124 additions & 52 deletions
Large diffs are not rendered by default.

ECCO-ACCESS/Downloading_ECCO_datasets_from_PODAAC/Tutorial_wget_Command_Line_HTTPS_Downloading_ECCO_Datasets_from_PODAAC.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Tutorial: Using Command Line _wget_ to Download ECCO Datasets from PO.DAAC
1+
# Using _wget_ to Download ECCO Datasets from PO.DAAC
22

33
Version 1.0 2021-06-25
44

@@ -91,4 +91,4 @@ $wget --no-verbose \
9191
--no-clobber \
9292
--continue \
9393
-i 5237392644-download.txt -P data/
94-
```
94+
```

Intro_to_PO_Tutorials/Geostrophic_balance.ipynb

Lines changed: 7599 additions & 0 deletions
Large diffs are not rendered by default.

Intro_to_PO_Tutorials/Steric_height.ipynb

Lines changed: 1563 additions & 0 deletions
Large diffs are not rendered by default.

Intro_to_PO_Tutorials/Thermal_wind.ipynb

Lines changed: 1040 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../ECCO-ACCESS/Downloading_ECCO_datasets_from_PODAAC/ecco_download.py
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
def cmap_zerocent_scale(plot,scale_factor):
2+
"""
3+
Center colormap at zero and scale relative to existing |maximum| value,
4+
given plot object and scale_factor, a number of type float.
5+
Returns new colormap limits as new_clim.
6+
"""
7+
curr_clim = plot.get_clim()
8+
new_clim = (scale_factor*np.max(np.abs(curr_clim)))*np.array([-1,1])
9+
plot.set_clim(new_clim)
10+
return new_clim
11+
12+
13+
14+
def plot_mask(*args,ax=None,color):
15+
"""
16+
Plot mask, given input parameters:
17+
- X, Y: (optional) coordinates as 1-D or 2-D NumPy arrays or xarray DataArrays
18+
- mask: 2-D array of boolean values (True/False or 1/0), NumPy or xarray
19+
- axes: axes to plot on, defaults to current axes
20+
- color: a string indicating a color in Matplotlib, or a 3-element tuple or NumPy array indicating RGB color values
21+
22+
Returns plot_obj, the plot object of the mask
23+
"""
24+
if len(args) == 1:
25+
mask = args[0]
26+
else:
27+
X = args[0]
28+
Y = args[1]
29+
mask = args[2]
30+
# set alpha values to 1 where mask is plotted, 0 otherwise
31+
if str(type(mask))[0:5] == 'xarray':
32+
mask = mask.values
33+
# get color for mask
34+
if isinstance(color,str):
35+
import matplotlib.colors as mcolors
36+
color_rgb = mcolors.to_rgb(color)
37+
elif (isinstance(color,tuple)) and (len(color) == 3):
38+
color_rgb = np.asarray(color)
39+
elif (isinstance(color,np.ndarray)) and (len(color) == 3):
40+
color_rgb = color
41+
else:
42+
raise TypeError("input parameter 'color' has incorrect type or number of elements")
43+
# create a colormap using a 2x4 array with two RGBA entries
44+
# the RGB entries are the same in each row
45+
# in the 1st row alpha=0, in the 2nd row alpha=1
46+
cmap_array = np.hstack((np.tile(color_rgb,(2,1)),np.array([[0],[1]])))
47+
from matplotlib.colors import ListedColormap
48+
colormap = ListedColormap(cmap_array)
49+
# get axis limits of existing plot
50+
if ax is None:
51+
ax = plt.gca()
52+
existing_xlim = ax.get_xlim()
53+
existing_ylim = ax.get_ylim()
54+
# plot mask using colormap just created, with alpha=1 where mask=1 or True
55+
if len(args) == 1:
56+
plot_obj = ax.pcolormesh(mask,cmap=colormap,vmin=0.,vmax=1.,zorder=50)
57+
else:
58+
plot_obj = ax.pcolormesh(X,Y,mask,cmap=colormap,vmin=0.,vmax=1.,zorder=50)
59+
# set axis limits of mask to axis limits of existing plot
60+
ax.set_xlim(existing_xlim)
61+
ax.set_ylim(existing_ylim)
62+
63+
return plot_obj
64+
65+
66+
67+
def geos_vel_compute(dens_press_filename,grid_filename="~/Downloads/ECCO_V4r4_PODAAC/ECCO_L4_GEOMETRY_LLC0090GRID_V4R4/GRID_GEOMETRY_ECCO_V4r4_native_llc0090.nc",fc_filename="llc_13tile_fc.txt"):
68+
"""
69+
This routine computes geostrophic velocities from an input netCDF file containing ECCO v4r4 density and pressure anomalies on the native llc90 grid.
70+
71+
Parameters
72+
----------
73+
dens_press_filename: the name (including path if not in current directory) of the netCDF file containing the density and pressure anomalies
74+
75+
grid_filename: the name (including path if not in current directory) of the netCDF file containing the latitudes ('YC') and grid parameters ('dxC','dyC') needed to compute horizontal derivatives
76+
77+
fc_filename: text file containing a Python dictionary specifying the tile/face connections in the ECCO llc90 grid
78+
"""
79+
80+
import numpy as np
81+
import xarray as xr
82+
import json
83+
import xgcm
84+
85+
# load file into workspace
86+
ds_denspress = xr.open_dataset(dens_press_filename, data_vars='minimal',\
87+
coords='minimal', compat='override')
88+
89+
densanom = ds_denspress.RHOAnoma
90+
91+
rhoConst = 1029.
92+
dens = rhoConst + densanom
93+
94+
pressanom = ds_denspress.PHIHYDcR
95+
96+
97+
# load grid parameters file
98+
ds_grid = xr.open_dataset(grid_filename)
99+
100+
101+
# load face_connections dictionary
102+
103+
# read in as string
104+
with open(fc_filename) as fc:
105+
data = fc.read()
106+
# convert string to dictionary
107+
face_connections = json.loads(data)
108+
109+
110+
# create xgcm Grid object
111+
grid = xgcm.Grid(ds_grid,periodic=False,face_connections=face_connections)
112+
113+
# compute derivatives of pressure in x and y
114+
d_press_dx = (grid.diff(rhoConst*pressanom,axis="X",boundary='extend'))/ds_grid.dxC
115+
d_press_dy = (grid.diff(rhoConst*pressanom,axis="Y",boundary='extend'))/ds_grid.dyC
116+
117+
# interpolate (vector) gradient values to center of grid cells
118+
press_grads_interp = grid.interp_2d_vector({'X':d_press_dx,'Y':d_press_dy},boundary='extend')
119+
dp_dx = press_grads_interp['X']
120+
dp_dy = press_grads_interp['Y']
121+
122+
# compute f from latitude of grid cell centers
123+
lat = ds_grid.YC
124+
Omega = (2*np.pi)/86164
125+
lat_rad = (np.pi/180)*lat # convert latitude from degrees to radians
126+
f = 2*Omega*np.sin(lat_rad)
127+
128+
# compute geostrophic velocities
129+
v_g = dp_dx/(f*dens)
130+
u_g = -dp_dy/(f*dens)
131+
132+
# assign attributes to DataArrays (names) and units
133+
u_g.name = 'u_g'
134+
u_g.attrs.update({'long_name': 'Geostrophic velocity in model-x direction',\
135+
'units': 'm s-1'})
136+
v_g.name = 'v_g'
137+
v_g.attrs.update({'long_name': 'Geostrophic velocity in model-y direction',\
138+
'units': 'm s-1'})
139+
140+
# create xarray Dataset containing geostrophic velocities
141+
ds_geos_vel = u_g.to_dataset(name='u_g',promote_attrs=True)
142+
ds_geos_vel['v_g'] = v_g
143+
144+
return ds_geos_vel

0 commit comments

Comments
 (0)