date = datetime(2016, 5, 15) kw_ident = dict(date=date, step=0.002, shape_error=70, sampling=30, uname="u", vname="v") a, c = g.eddy_identification("adt", **kw_ident) a_, c_ = g_raw.eddy_identification("adt", **kw_ident) # %% # Figures # ------- kw_adt = dict(vmin=-1.5, vmax=1.5, cmap=plt.get_cmap("RdBu_r", 30)) fig, axs = quad_axes("General properties field") g_raw.display(axs[0], "adt", **kw_adt) axs[0].set_title("Total ADT (m)") m = g.display(axs[1], "adt_low", **kw_adt) axs[1].set_title("ADT (m) large scale, cutoff at 700 km") m2 = g.display(axs[2], "adt", cmap=plt.get_cmap("RdBu_r", 20), vmin=-0.5, vmax=0.5) axs[2].set_title("ADT (m) high-pass filtered, a cutoff at 700 km") cb = plt.colorbar(m, cax=axs[0].figure.add_axes(pos_cb), orientation="horizontal") cb.set_label("ADT (m)", labelpad=0) cb2 = plt.colorbar(m2, cax=axs[2].figure.add_axes(pos_cb2),
# %% # Load detection files a = EddiesObservations.load_file(data.get_path("Anticyclonic_20190223.nc")) c = EddiesObservations.load_file(data.get_path("Cyclonic_20190223.nc")) # %% # Load Input grid, ADT will be used to detect eddies g = RegularGridDataset( data.get_path("nrt_global_allsat_phy_l4_20190223_20190226.nc"), "longitude", "latitude", ) ax = start_axes("ADT (cm)") m = g.display(ax, "adt", vmin=-120, vmax=120, factor=100) update_axes(ax, m) # %% # Get parameter for ow u_x = g.compute_stencil(g.grid("ugos")) u_y = g.compute_stencil(g.grid("ugos"), vertical=True) v_x = g.compute_stencil(g.grid("vgos")) v_y = g.compute_stencil(g.grid("vgos"), vertical=True) ow = g.vars["ow"] = (u_x - v_y)**2 + (v_x + u_y)**2 - (v_x - u_y)**2 ax = start_axes("Okubo weis") m = g.display(ax, "ow", vmin=-1e-10, vmax=1e-10, cmap="bwr") update_axes(ax, m) # %%
"longitude", "latitude", ) # %% # For each contours, we will get pixels indice in contour. fig = plt.figure(figsize=(12, 6)) ax = fig.add_axes((0.05, 0.05, 0.9, 0.9)) ax.set_aspect("equal") ax.set_xlim(10, 70) ax.set_ylim(-50, -25) # We will used the outter contour x_name, y_name = a.intern(False) adt = g.grid("adt") mask = ones(adt.shape, dtype='bool') for eddy in a: i, j = Path(create_vertice(eddy[x_name], eddy[y_name])).pixels_in(g) mask[i, j] = False adt.mask[:] += ~mask g.display(ax, "adt") a.display(ax, label="Anticyclonic", color="g", lw=1, extern_only=True) # %% fig = plt.figure(figsize=(12, 6)) ax = fig.add_axes((0.05, 0.05, 0.9, 0.9)) ax.set_aspect("equal") ax.set_xlim(10, 70) ax.set_ylim(-50, -25) adt.mask[:] = mask g.display(ax, "adt") a.display(ax, label="Anticyclonic", color="g", lw=1, extern_only=True)
def update_axes(ax, mappable=None): ax.grid() if mappable: plt.colorbar(m, cax=ax.figure.add_axes([0.95, 0.05, 0.01, 0.9])) # %% # Load Input grid, ADT will be used to detect eddies g = RegularGridDataset( data.get_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), "longitude", "latitude") ax = start_axes("ADT (m)") m = g.display(ax, "adt", vmin=-0.15, vmax=0.15) update_axes(ax, m) # %% # Get u/v # ------- # U/V are deduced from ADT, this algortihm are not usable around equator (~+- 2°) g.add_uv("adt") ax = start_axes("U/V deduce from ADT (m)") ax.set_xlim(2.5, 9), ax.set_ylim(37.5, 40) m = g.display(ax, "adt", vmin=-0.15, vmax=0.15) u, v = g.grid("u").T, g.grid("v").T ax.quiver(g.x_c, g.y_c, u, v, scale=10) update_axes(ax, m) # %%
from matplotlib import pyplot as plt from py_eddy_tracker.dataset.grid import RegularGridDataset grid_name, lon_name, lat_name = 'nrt_global_allsat_phy_l4_20190223_20190226.nc', 'longitude', 'latitude' if False: h = RegularGridDataset(grid_name, lon_name, lat_name) fig = plt.figure(figsize=(14, 12)) ax = fig.add_axes([.02, .51, .9, .45]) ax.set_title('ADT (m)') ax.set_ylim(-75, 75) ax.set_aspect('equal') m = h.display(ax, name='adt', vmin=-1, vmax=1) ax.grid(True) plt.colorbar(m, cax=fig.add_axes([.94, .51, .01, .45])) h = RegularGridDataset(grid_name, lon_name, lat_name) h.bessel_high_filter('adt', 500, order=3) ax = fig.add_axes([.02, .02, .9, .45]) ax.set_title('ADT Filtered (m)') ax.set_aspect('equal') ax.set_ylim(-75, 75) m = h.display(ax, name='adt', vmin=-.1, vmax=.1) ax.grid(True) plt.colorbar(m, cax=fig.add_axes([.94, .02, .01, .45])) fig.savefig('png/filter.png') if True: import logging logging.getLogger().setLevel( 'DEBUG') # Values: ERROR, WARNING, INFO, DEBUG from datetime import datetime
ax.gridlines() ax.coastlines(resolution='50m') ax.set_title(title) return ax def update_axes(ax, mappable=None, unit=''): ax.grid() if mappable: plt.colorbar(mappable, cax=ax.figure.add_axes([0.95, 0.05, 0.01, 0.9],title=unit)) # %% # Loading SLA and first display # ----------------------------- g = RegularGridDataset(data.get_path(filename_alt), lon_name_alt,lat_name_alt) ax = start_axes("SLA", extent=extent) m = g.display(ax, "sla", vmin=0.05, vmax=0.35) u,v = g.grid("ugosa").T,g.grid("vgosa").T ax.quiver(g.x_c, g.y_c, u, v, scale=10) update_axes(ax, m, unit='[m]') # %% # Loading SST and first display # ----------------------------- t = RegularGridDataset(filename=data.get_path(filename_sst), x_name=lon_name_sst, y_name=lat_name_sst) # The following now load the corresponding variables from the SST netcdf (it's not needed to load it beforehand, so not executed.) # t.grid(var_name_sst) # %%
def update_axes(ax, mappable=None): ax.grid() if mappable: plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9])) # %% # Load Input grid, ADT is used to detect eddies g = RegularGridDataset( data.get_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), "longitude", "latitude") ax = start_axes("ADT (m)") m = g.display(ax, "adt", vmin=-0.15, vmax=0.15, cmap="RdBu_r") update_axes(ax, m) # %% # Get geostrophic speed u,v # ------------------------- # U/V are deduced from ADT, this algortihm is not ok near the equator (~+- 2°) g.add_uv("adt") ax = start_axes("U/V deduce from ADT (m)") ax.set_xlim(2.5, 9), ax.set_ylim(37.5, 40) m = g.display(ax, "adt", vmin=-0.15, vmax=0.15, cmap="RdBu_r") u, v = g.grid("u").T, g.grid("v").T ax.quiver(g.x_c, g.y_c, u, v, scale=10) update_axes(ax, m) # %%
# To compute vorticity (:math:`\omega`) we compute u/v field with a stencil and apply the following equation with stencil # method : # # .. math:: # \omega = \frac{\partial v}{\partial x} - \frac{\partial u}{\partial y} g = RegularGridDataset(get_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), "longitude", "latitude") g.add_uv("adt") u_y = g.compute_stencil(g.grid("u"), vertical=True) v_x = g.compute_stencil(g.grid("v")) g.vars["vort"] = v_x - u_y # %% # Display vorticity field fig, ax, _ = start_ax() mappable = g.display(ax, abs(g.grid("vort")), **kw_vorticity) cb = update_axes(ax, mappable) cb.set_label("Vorticity") # %% # Particles # --------- # Particles specification step = 1 / 32 x_g, y_g = arange(0, 36, step), arange(28, 46, step) x, y = meshgrid(x_g, y_g) original_shape = x.shape x, y = x.reshape(-1), y.reshape(-1) print(f"{len(x)} particles advected") # A frame every 8h step_by_day = 3
wavelength = 800 g.bessel_high_filter("adt_high", wavelength) date = datetime(2016, 5, 15) # %% # Run the detection for the total grid and the filtered grid a_filtered, c_filtered = g.eddy_identification("adt_high", "u", "v", date, 0.002) merge_f = a_filtered.merge(c_filtered) a_tot, c_tot = g.eddy_identification("adt", "u", "v", date, 0.002) merge_t = a_tot.merge(c_tot) # %% # Display the two detections ax = start_axes("Eddies detected over ADT") m = g.display(ax, "adt", vmin=-0.15, vmax=0.15) merge_f.display( ax, lw=0.75, label="Eddies in the filtered grid ({nb_obs} eddies)", ref=-10, color="k", ) merge_t.display(ax, lw=0.75, label="Eddies without filter ({nb_obs} eddies)", ref=-10, color="r") ax.legend() update_axes(ax, m)
k = g.kernel_bessel(0, 500, order=3) k_lat = k[k.shape[0] // 2 + 1] nb = k_lat.shape[0] // 2 ax.plot(arange(-nb * g.xstep, (nb + 0.5) * g.xstep, g.xstep), k_lat, label="Bessel kernel") ax.legend() ax.grid() # %% # Kernel applying # --------------- # Original grid ax = start_axes("ADT") m = g.display(ax, "adt", vmin=-0.15, vmax=0.15) update_axes(ax, m) # %% # We will select wavelength of 300 km # # Low frequency ax = start_axes("ADT low frequency") g.copy("adt", "adt_low_300") g.bessel_low_filter("adt_low_300", 300, order=3) m = g.display(ax, "adt_low_300", vmin=-0.15, vmax=0.15) update_axes(ax, m) # %% # High frequency ax = start_axes("ADT high frequency")
ax.set_aspect("equal") return ax def update_axes(ax, mappable=None, unit=""): ax.grid() if mappable: cax = ax.figure.add_axes([0.93, 0.05, 0.01, 0.9], title=unit) plt.colorbar(mappable, cax=cax) # %% # ADT first display # ----------------- ax = start_axes("SLA", extent=extent) m = sst.display(ax, "sla", vmin=0.05, vmax=0.35) update_axes(ax, m, unit="[m]") # %% # SST first display # ----------------- # %% # We can now plot SST from `sst` ax = start_axes("SST") m = sst.display(ax, "analysed_sst", vmin=295, vmax=300) update_axes(ax, m, unit="[°K]") # %% ax = start_axes("SST") m = sst.display(ax, "analysed_sst", vmin=295, vmax=300)
# %% # Load Input grid, ADT is used to detect eddies margin = 30 g = RegularGridDataset( data.get_path("nrt_global_allsat_phy_l4_20190223_20190226.nc"), "longitude", "latitude", # Manual area subset indexs=dict( longitude=slice(1116 - margin, 1216 + margin), latitude=slice(476 - margin, 536 + margin), ), ) ax = start_axes("ADT (m)") m = g.display(ax, "adt", vmin=-1, vmax=1, cmap="RdBu_r") # Draw line on the gulf stream front great_current = Contours(g.x_c, g.y_c, g.grid("adt"), levels=(0.35,), keep_unclose=True) great_current.display(ax, color="k") update_axes(ax, m) # %% # Get geostrophic speed u,v # ------------------------- # U/V are deduced from ADT, this algortihm is not ok near the equator (~+- 2°) g.add_uv("adt") # %% # Pre-processings # --------------- # Apply a high-pass filter to remove the large scale and highlight the mesoscale
ref=-10, color="g") kwargs_c_sla = dict(lw=0.5, label="Cyclonic SLA ({nb_obs} eddies)", ref=-10, color="b") # %% # Run algorithm of detection a_adt, c_adt = g.eddy_identification("adt", "ugos", "vgos", date, 0.002) a_sla, c_sla = g.eddy_identification("sla", "ugosa", "vgosa", date, 0.002) # %% # over filtered ax = start_axes(f"ADT (m) filtered ({wavelength}km)") m = g.display(ax, "adt", vmin=-0.15, vmax=0.15) a_adt.display(ax, **kwargs_a_adt), c_adt.display(ax, **kwargs_c_adt) ax.legend(), update_axes(ax, m) ax = start_axes(f"SLA (m) filtered ({wavelength}km)") m = g.display(ax, "sla", vmin=-0.15, vmax=0.15) a_sla.display(ax, **kwargs_a_sla), c_sla.display(ax, **kwargs_c_sla) ax.legend(), update_axes(ax, m) # %% # over raw ax = start_axes("ADT (m)") m = g.display(ax, "adt_raw", vmin=-0.15, vmax=0.15) a_adt.display(ax, **kwargs_a_adt), c_adt.display(ax, **kwargs_c_adt) ax.legend(), update_axes(ax, m)
import logging grid_name, lon_name, lat_name = ( "nrt_global_allsat_phy_l4_20190223_20190226.nc", "longitude", "latitude", ) h = RegularGridDataset(grid_name, lon_name, lat_name) fig = plt.figure(figsize=(14, 12)) ax = fig.add_axes([0.02, 0.51, 0.9, 0.45]) ax.set_title("ADT (m)") ax.set_ylim(-75, 75) ax.set_aspect("equal") m = h.display(ax, name="adt", vmin=-1, vmax=1) ax.grid(True) plt.colorbar(m, cax=fig.add_axes([0.94, 0.51, 0.01, 0.45])) h = RegularGridDataset(grid_name, lon_name, lat_name) h.bessel_high_filter("adt", 500, order=3) ax = fig.add_axes([0.02, 0.02, 0.9, 0.45]) ax.set_title("ADT Filtered (m)") ax.set_aspect("equal") ax.set_ylim(-75, 75) m = h.display(ax, name="adt", vmin=-0.1, vmax=0.1) ax.grid(True) plt.colorbar(m, cax=fig.add_axes([0.94, 0.02, 0.01, 0.45])) fig.savefig("png/filter.png") logging.getLogger().setLevel("DEBUG") # Values: ERROR, WARNING, INFO, DEBUG
c = EddiesObservations.load_file(data.get_path("Cyclonic_20160515.nc")) aviso_map = RegularGridDataset( data.get_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), "longitude", "latitude") aviso_map.add_uv("adt") # %% # Compute and store eke in cm²/s² aviso_map.add_grid("eke", (aviso_map.grid("u")**2 + aviso_map.grid("v")**2) * 0.5 * (100**2)) eke_kwargs = dict(vmin=1, vmax=1000, cmap="magma_r") ax = start_axes("EKE (cm²/s²)") m = aviso_map.display(ax, "eke", **eke_kwargs) a.display(ax, color="r", linewidth=0.5, label="Anticyclonic", ref=-10) c.display(ax, color="b", linewidth=0.5, label="Cyclonic", ref=-10) update_axes(ax, m) # %% # Get mean of eke in each effective contour ax = start_axes("EKE (cm²/s²)") a.display(ax, color="r", linewidth=0.5, label="Anticyclonic", ref=-10) c.display(ax, color="b", linewidth=0.5, label="Cyclonic", ref=-10) eke = a.interp_grid(aviso_map, "eke", method="mean", intern=False) ax.scatter((a.longitude + 10) % 360 - 10, a.latitude, c=eke, **eke_kwargs) eke = c.interp_grid(aviso_map, "eke", method="mean", intern=False) m = ax.scatter((c.longitude + 10) % 360 - 10, c.latitude, c=eke, **eke_kwargs) update_axes(ax, m)