Skip to content

Commit 22b10ad

Browse files
authored
Gallery example on data collocation (AntSimi#25)
1 parent 50979e0 commit 22b10ad

File tree

3 files changed

+143
-0
lines changed

3 files changed

+143
-0
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
"""
2+
Collocating external data
3+
==========================
4+
5+
Script will use py-eddy-tracker methods to upload external data (sea surface temperature, SST) in a common structure with altimetry.
6+
7+
Figures higlights the different steps.
8+
9+
"""
10+
11+
from matplotlib import pyplot as plt
12+
from py_eddy_tracker.dataset.grid import RegularGridDataset
13+
from py_eddy_tracker import data
14+
import cartopy.crs as ccrs
15+
from datetime import datetime
16+
from numpy import ma, meshgrid
17+
18+
datest = '20160707'
19+
20+
filename_alt = "../l4_cmems/dt_blacksea_allsat_phy_l4_"+datest+"_20200801.nc"
21+
lon_name_alt = 'longitude'
22+
lat_name_alt = 'latitude'
23+
24+
filename_sst = "../SST/"+datest+"000000-GOS-L4_GHRSST-SSTfnd-OISST_HR_REP-BLK-v02.0-fv01.0.nc4"
25+
lon_name_sst = 'lon'
26+
lat_name_sst = 'lat'
27+
var_name_sst = 'analysed_sst'
28+
29+
extent = [27, 42, 40.5, 47]
30+
31+
# %%
32+
# Functions to initiate figure axes
33+
def start_axes(title, extent=extent, fig=None, sp=None):
34+
if fig is None:
35+
fig = plt.figure(figsize=(13, 5))
36+
ax = fig.add_axes([0.03, 0.03, 0.90, 0.94],projection=ccrs.PlateCarree())
37+
else:
38+
ax = fig.add_subplot(sp,projection=ccrs.PlateCarree())
39+
40+
ax.set_extent(extent)
41+
ax.gridlines()
42+
ax.coastlines(resolution='50m')
43+
ax.set_title(title)
44+
return ax
45+
46+
def update_axes(ax, mappable=None, unit=''):
47+
ax.grid()
48+
if mappable:
49+
plt.colorbar(mappable, cax=ax.figure.add_axes([0.95, 0.05, 0.01, 0.9],title=unit))
50+
51+
# %%
52+
# Loading SLA and first display
53+
# -----------------------------
54+
g = RegularGridDataset(data.get_path(filename_alt), lon_name_alt,lat_name_alt)
55+
ax = start_axes("SLA", extent=extent)
56+
m = g.display(ax, "sla", vmin=0.05, vmax=0.35)
57+
u,v = g.grid("ugosa").T,g.grid("vgosa").T
58+
ax.quiver(g.x_c, g.y_c, u, v, scale=10)
59+
update_axes(ax, m, unit='[m]')
60+
61+
# %%
62+
# Loading SST and first display
63+
# -----------------------------
64+
t = RegularGridDataset(filename=data.get_path(filename_sst),
65+
x_name=lon_name_sst,
66+
y_name=lat_name_sst)
67+
68+
# The following now load the corresponding variables from the SST netcdf (it's not needed to load it beforehand, so not executed.)
69+
# t.grid(var_name_sst)
70+
71+
# %%
72+
# We can now plot SST from `t`
73+
ax = start_axes("SST title")
74+
m = t.display(ax, 'analysed_sst', vmin=295, vmax=300)
75+
update_axes(ax, m, unit='[°K]')
76+
77+
# %%
78+
# Including SST in the Altimetry grid
79+
# -----------------------------------
80+
# We can use `Grid` tools to interpolate SST on the altimetry grid
81+
82+
lons, lats = meshgrid(g.x_c, g.y_c)
83+
shape = lats.shape
84+
85+
# flat grid before interp
86+
lons, lats = lons.reshape(-1), lats.reshape(-1)
87+
88+
# interp and reshape
89+
ti = t.interp('analysed_sst', lons, lats).reshape(shape).T
90+
ti = ma.masked_invalid(ti)
91+
92+
# %%
93+
# and add it to `g`
94+
g.add_grid('sst',ti)
95+
96+
# %%
97+
ax = start_axes("SST")
98+
m = g.display(ax, "sst", vmin=295, vmax=300)
99+
u,v = g.grid("ugosa").T,g.grid("vgosa").T
100+
ax.quiver(g.x_c, g.y_c, u, v, scale=10)
101+
update_axes(ax, m, unit='[°K]')
102+
103+
# %%
104+
# Now, with eddy contours, and displaying SST anomaly
105+
# ! lazy patch since add_grid isn't currently completing g.variables_description
106+
g.variables_description['sst'] = t.variables_description[var_name_sst]
107+
g.copy("sst", "sst_high")
108+
g.bessel_high_filter('sst_high',200)
109+
110+
# %%
111+
# Eddy detection
112+
date = datetime.strptime(datest,'%Y%m%d')
113+
a, c = g.eddy_identification("sla", "ugosa", "vgosa", date, 0.002)
114+
115+
# %%
116+
kwargs_a = dict(lw=2, label="Anticyclonic", ref=-10, color="b")
117+
kwargs_c = dict(lw=2, label="Cyclonic", ref=-10, color="r")
118+
ax = start_axes("SST anomaly")
119+
m = g.display(ax, "sst_high", vmin=-1, vmax=1)
120+
ax.quiver(g.x_c, g.y_c, u, v, scale=20)
121+
a.display(ax, **kwargs_a), c.display(ax, **kwargs_c)
122+
update_axes(ax, m, unit='[°K]')
123+
124+
# %%
125+
# Example of post-processing
126+
# --------------------------
127+
# Get mean of sst anomaly_high in each internal contour
128+
anom_a = a.interp_grid(g, "sst_high", method="mean", intern=True)
129+
anom_c = c.interp_grid(g, "sst_high", method="mean", intern=True)
130+
131+
# %%
132+
# Are cyclonic (resp. anticyclonic) eddies generally associated with positive (resp. negative) SST anomaly ?
133+
fig = plt.figure(figsize=(5, 5))
134+
ax = fig.add_axes([0.03, 0.03, 0.90, 0.90])
135+
ax.set_xlabel("SST anomaly")
136+
ax.set_xlim([-1,1])
137+
ax.set_title('Histograms of SST anomalies')
138+
ax.hist(anom_a,5, alpha=0.5, label = 'Anticyclonic (mean:%s)'%(anom_a.mean()))
139+
ax.hist(anom_c,5, alpha=0.5, label = 'Cyclonic (mean:%s)'%(anom_c.mean()))
140+
ax.legend()
141+
142+
# %%
143+
# Not clearly so in that case ..
107 KB
Binary file not shown.
127 KB
Binary file not shown.

0 commit comments

Comments
 (0)