"""
Display contour & circle
========================

"""

from matplotlib import pyplot as plt

from py_eddy_tracker import data
from py_eddy_tracker.observations.observation import EddiesObservations

# %%
# Load detection files
a = EddiesObservations.load_file(data.get_demo_path("Anticyclonic_20190223.nc"))

# %%
# Plot the speed and effective (dashed) contours
fig = plt.figure(figsize=(15, 8))
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)
a.display(ax, label="Anticyclonic contour", color="r", lw=1)

# Replace contours by circles using center and radius (effective is dashed)
a.circle_contour()
a.display(ax, label="Anticyclonic circle", color="g", lw=1)
_ = ax.legend(loc="upper right")
Пример #2
0
        content = self.to_html5_video()
        return re.sub(r'width="[0-9]*"\sheight="[0-9]*"',
                      'width="100%" height="100%"', content)

    def save(self, *args, **kwargs):
        if args[0].endswith("gif"):
            # In this case gif is used to create thumbnail which is not used but consume same time than video
            # So we create an empty file, to save time
            with open(args[0], "w") as _:
                pass
            return
        return super().save(*args, **kwargs)


# %%
n = NetworkObservations.load_file(get_demo_path("network_med.nc")).network(651)
n = n.extract_with_mask((n.time >= 20180) * (n.time <= 20269))
n = n.remove_dead_end(nobs=0, ndays=10)
n.numbering_segment()
c = GridCollection.from_netcdf_cube(
    get_demo_path("dt_med_allsat_phy_l4_2005T2.nc"),
    "longitude",
    "latitude",
    "time",
    heigth="adt",
)

# %%
# Schema
# ------
fig = plt.figure(figsize=(12, 6))
Пример #3
0
import zarr
from netCDF4 import Dataset

from py_eddy_tracker.data import get_demo_path
from py_eddy_tracker.featured_tracking.area_tracker import AreaTracker
from py_eddy_tracker.observations.observation import EddiesObservations
from py_eddy_tracker.tracking import Correspondances

filename = get_demo_path("Anticyclonic_20190223.nc")
a0 = EddiesObservations.load_file(filename)
a1 = a0.copy()


def test_area_tracking_parameter():
    delta = 0.2
    # All eddies will be shift of delta in longitude and latitude
    for k in (
            "lon",
            "lon_max",
            "contour_lon_s",
            "contour_lon_e",
            "lat",
            "lat_max",
            "contour_lat_s",
            "contour_lat_e",
    ):
        a1[k][:] -= delta
    a1.time[:] += 1
    # wrote in memory a0 and a1
    h0, h1 = zarr.group(), zarr.group()
    a0.to_zarr(h0), a1.to_zarr(h1)
Пример #4
0
from matplotlib.path import Path
from numpy import arange, array, isnan, ma, nan, ones, zeros
from pytest import approx

from py_eddy_tracker.data import get_demo_path
from py_eddy_tracker.dataset.grid import RegularGridDataset

G = RegularGridDataset(get_demo_path("mask_1_60.nc"), "lon", "lat")
X = 0.025
contour = Path((
    (-X, 0),
    (X, 0),
    (X, X),
    (-X, X),
    (-X, 0),
))


# contour
def test_contour_lon():
    assert (contour.lon == (-X, X, X, -X, -X)).all()


def test_contour_lat():
    assert (contour.lat == (0, 0, X, X, 0)).all()


def test_contour_mean():
    assert (contour.mean_coordinates == (0, X / 2)).all()

Пример #5
0
    def save(self, *args, **kwargs):
        if args[0].endswith("gif"):
            # In this case gif is use to create thumbnail which are not use but consume same time than video
            # So we create an empty file, to save time
            with open(args[0], "w") as _:
                pass
            return
        return super().save(*args, **kwargs)


# %%
# Data
# ----
# Load Input time grid ADT
c = GridCollection.from_netcdf_cube(
    get_demo_path("dt_med_allsat_phy_l4_2005T2.nc"),
    "longitude",
    "latitude",
    "time",
    # To create U/V variable
    heigth="adt",
)

# %%
# Anim
# ----
# Particles setup
step_p = 1 / 8
x, y = meshgrid(arange(13, 36, step_p), arange(28, 40, step_p))
x, y = x.reshape(-1), y.reshape(-1)
# Remove all original position that we can't advect at first place
Script will use py-eddy-tracker methods to upload external data (sea surface temperature, SST)
in a common structure with altimetry.

Figures higlights the different steps.
"""

from datetime import datetime

from matplotlib import pyplot as plt

from py_eddy_tracker import data
from py_eddy_tracker.dataset.grid import RegularGridDataset

date = datetime(2016, 7, 7)

filename_alt = data.get_demo_path(
    f"dt_blacksea_allsat_phy_l4_{date:%Y%m%d}_20200801.nc")
filename_sst = data.get_demo_path(
    f"{date:%Y%m%d}000000-GOS-L4_GHRSST-SSTfnd-OISST_HR_REP-BLK-v02.0-fv01.0.nc"
)
var_name_sst = "analysed_sst"

extent = [27, 42, 40.5, 47]

# %%
# Loading data
# ------------
sst = RegularGridDataset(filename=filename_sst, x_name="lon", y_name="lat")
alti = RegularGridDataset(data.get_demo_path(filename_alt),
                          x_name="longitude",
                          y_name="latitude")
# We can use `Grid` tools to interpolate ADT on the sst grid
Пример #7
0
            with open(args[0], "w") as _:
                pass
            return
        return super().save(*args, **kwargs)


# %%
# Data
# ----
# 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_demo_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
Пример #8
0
from py_eddy_tracker.observations.observation import EddiesObservations, Table
from py_eddy_tracker.observations.tracking import TrackEddiesObservations

# %%
# Eddies can be stored in 2 formats with the same structure:
#
# - zarr (https://zarr.readthedocs.io/en/stable/), which allow efficiency in IO,...
# - NetCDF4 (https://unidata.github.io/netcdf4-python/), well-known format
#
# Each field are stored in column, each row corresponds at 1 observation,
# array field like contour/profile are 2D column.

# %%
# Eddies files (zarr or netcdf) can be loaded with ```load_file``` method:
eddies_collections = EddiesObservations.load_file(
    get_demo_path("Cyclonic_20160515.nc"))
eddies_collections.field_table()
# offset and scale_factor are used only when data is stored in zarr or netCDF4

# %%
# Field access
# ------------
# To access the total field, here ```amplitude```
eddies_collections.amplitude

# To access only a specific part of the field
eddies_collections.amplitude[4:15]

# %%
# Data matrix is a numpy ndarray
eddies_collections.obs
Пример #9
0
from datetime import datetime

from py_eddy_tracker.data import get_demo_path
from py_eddy_tracker.dataset.grid import RegularGridDataset

g = RegularGridDataset(
    get_demo_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), "longitude",
    "latitude")


def test_id():
    g.add_uv("adt")
    a, c = g.eddy_identification("adt", "u", "v", datetime(2019, 2, 23))
    assert len(a) == 36
    assert len(c) == 36
Пример #10
0
Network basic manipulation
==========================
"""
from matplotlib import pyplot as plt
from numpy import where

from py_eddy_tracker import data
from py_eddy_tracker.gui import GUI_AXES
from py_eddy_tracker.observations.network import NetworkObservations

# %%
# Load data
# ---------
# Load data where observations are put in same network but no segmentation
n = NetworkObservations.load_file(
    data.get_demo_path("network_med.nc")).network(651)
i = where((n.lat > 33) * (n.lat < 34) * (n.lon > 22) * (n.lon < 23) *
          (n.time > 20630) * (n.time < 20650))[0][0]
# For event use
n2 = n.relative(i, order=2)
n = n.relative(i, order=4)
n.numbering_segment()

# %%
# Timeline
# --------

# %%
# Display timeline with events
# A segment generated by a splitting is marked with a star
#
Пример #11
0
        lines_u[i].set_data(x_, y_)
    scores_v = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_v,
                               y_v) * 100.0
    scores_u = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_u,
                               y_u) * 100.0
    for i, (s_v, s_u) in enumerate(zip(scores_v, scores_u)):
        texts[i].set_text(
            f"Score uniform {s_u:.1f} %\nScore visvalingam {s_v:.1f} %")
    title.set_text(f"{nb} points by contour in place of 50")
    return (title, *lines_u, *lines_v, *texts)


# %%
# Load detection files
a = EddiesObservations.load_file(
    data.get_demo_path("Anticyclonic_20190223.nc"))
a = a.extract_with_mask((abs(a.lat) < 66) * (abs(a.radius_e) > 80e3))

nb_pt = 10
x_v, y_v = visvalingam_polys(a.contour_lon_e, a.contour_lat_e, nb_pt)
x_u, y_u = uniform_resample_polys(a.contour_lon_e, a.contour_lat_e, nb_pt)
scores_v = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_v, y_v) * 100.0
scores_u = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_u, y_u) * 100.0
d_6 = scores_v - scores_u
nb_pt = 18
x_v, y_v = visvalingam_polys(a.contour_lon_e, a.contour_lat_e, nb_pt)
x_u, y_u = uniform_resample_polys(a.contour_lon_e, a.contour_lat_e, nb_pt)
scores_v = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_v, y_v) * 100.0
scores_u = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_u, y_u) * 100.0
d_12 = scores_v - scores_u
a = a.index(array((d_6.argmin(), d_6.argmax(), d_12.argmin(), d_12.argmax())))
Пример #12
0
import zarr

from py_eddy_tracker.data import get_demo_path
from py_eddy_tracker.observations.observation import EddiesObservations

a_filename, c_filename = (
    get_demo_path("Anticyclonic_20190223.nc"),
    get_demo_path("Cyclonic_20190223.nc"),
)
a = EddiesObservations.load_file(a_filename)
a_raw = EddiesObservations.load_file(a_filename, raw_data=True)
memory_store = zarr.group()
# Dataset was raw loaded from netcdf and save in zarr
a_raw.to_zarr(memory_store, chunck_size=100000)
# We load zarr data without raw option
a_zarr = EddiesObservations.load_from_zarr(memory_store)
c = EddiesObservations.load_file(c_filename)


def test_merge():
    new = a.merge(c)
    assert len(new) == len(a) + len(c)


def test_zarr_raw():
    assert a == a_zarr


def test_index():
    a_nc_subset = EddiesObservations.load_file(
        a_filename, indexs=dict(obs=slice(500, 1000))
"""

from matplotlib import pyplot as plt
from matplotlib.path import Path
from numpy import ones

from py_eddy_tracker import data
from py_eddy_tracker.dataset.grid import RegularGridDataset
from py_eddy_tracker.observations.observation import EddiesObservations
from py_eddy_tracker.poly import create_vertice

# %%
# Load an eddy file which contains contours
a = EddiesObservations.load_file(
    data.get_demo_path("Anticyclonic_20190223.nc"))

# %%
# Load a grid where we want found pixels in eddies or out
g = RegularGridDataset(
    data.get_demo_path("nrt_global_allsat_phy_l4_20190223_20190226.nc"),
    "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)
Пример #14
0
    ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)
    ax.set_aspect("equal")
    ax.set_title(title)
    return ax


def update_axes(ax, mappable=None):
    ax.grid()
    if mappable:
        plt.colorbar(mappable, cax=ax.figure.add_axes([0.95, 0.05, 0.01, 0.9]))


# %%
# All information will be for regular grid
g = RegularGridDataset(
    data.get_demo_path("dt_med_allsat_phy_l4_20160515_20190101.nc"),
    "longitude",
    "latitude",
)
# %%
# Kernel
# ------
# Shape of kernel will increase in x, when latitude increase
fig = plt.figure(figsize=(12, 8))
for i, latitude in enumerate((15, 35, 55, 75)):
    k = g.kernel_bessel(latitude, 500, order=3).T
    ax0 = fig.add_subplot(
        2,
        2,
        i + 1,
        title=f"Kernel at {latitude}° of latitude\nfor 1/8° grid, shape : {k.shape}",
Пример #15
0
                # Merge of group, ref over etu
                for i_, j_ in zip(ii[m], ij[m]):
                    g0, g1 = gr_i[i_], gr_j[j_]
                    apply_replace(gr, g0, g1)
            NETWORK_GROUPS.append((i, j, gr.copy()))
        return gr


# %%
# Movie period
t0 = (datetime(2005, 5, 1) - datetime(1950, 1, 1)).days
t1 = (datetime(2005, 6, 1) - datetime(1950, 1, 1)).days

# %%
# Get data from period and area
e = EddiesObservations.load_file(data.get_demo_path("network_med.nc"))
e = e.extract_with_mask((e.time >= t0) * (e.time < t1)).extract_with_area(
    dict(llcrnrlon=25, urcrnrlon=35, llcrnrlat=31, urcrnrlat=37.5))
# %%
# Reproduce individual daily identification(for demonstration)
EDDIES_BY_DAYS = list()
for i, b0, b1 in e.iter_on("time"):
    EDDIES_BY_DAYS.append(e.index(i))
# need for display
e = EddiesObservations.concatenate(EDDIES_BY_DAYS)

# %%
# Run network building group to intercept every step
n = MyNetwork.from_eddiesobservations(EDDIES_BY_DAYS, window=7)
_ = n.group_observations(minimal_area=True)
Пример #16
0
"""
import re

from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
from numpy import arange, isnan, meshgrid, ones

import py_eddy_tracker.gui
from py_eddy_tracker.data import get_demo_path
from py_eddy_tracker.dataset.grid import RegularGridDataset
from py_eddy_tracker.observations.observation import EddiesObservations

# %%
# Load Input grid ADT
g = RegularGridDataset(
    get_demo_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), "longitude",
    "latitude")
# Compute u/v from height
g.add_uv("adt")

# %%
# Load detection files
a = EddiesObservations.load_file(get_demo_path("Anticyclonic_20160515.nc"))
c = EddiesObservations.load_file(get_demo_path("Cyclonic_20160515.nc"))

# %%
# Quiver from u/v with eddies
fig = plt.figure(figsize=(10, 5))
ax = fig.add_axes([0, 0, 1, 1], projection="full_axes")
ax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid()
x, y = meshgrid(g.x_c, g.y_c)
Пример #17
0
    axes.set_aspect("equal")
    axes.set_title(title)
    return axes


def update_axes(axes, mappable=None):
    axes.grid()
    if mappable:
        plt.colorbar(mappable,
                     cax=axes.figure.add_axes([0.94, 0.05, 0.01, 0.9]))


# %%
# Load detection files
a = EddiesObservations.load_file(
    data.get_demo_path("Anticyclonic_20190223.nc"))
c = EddiesObservations.load_file(data.get_demo_path("Cyclonic_20190223.nc"))

# %%
# Load Input grid, ADT will be used to detect eddies
g = RegularGridDataset(
    data.get_demo_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)

# %%
Пример #18
0
                i_next_ = -1
            else:
                ids["previous_obs"][i_next_] = i_next
            i_next = i_next_


def get_obs(dataset):
    "Function to isolate a specific obs"
    return where((dataset.lat > 33) * (dataset.lat < 34) * (dataset.lon > 22) *
                 (dataset.lon < 23) * (dataset.time > 20630) *
                 (dataset.time < 20650))[0][0]


# %%
# Get original network, we will isolate only relative at order *2*
n = NetworkObservations.load_file(get_demo_path("network_med.nc")).network(651)
n_ = n.relative(get_obs(n), order=2)

# %%
# Display the default segmentation
ax = start_axes(n_.infos())
n_.plot(ax, color_cycle=n.COLORS)
update_axes(ax)
fig = plt.figure(figsize=(15, 5))
ax = fig.add_axes([0.04, 0.05, 0.92, 0.92])
ax.xaxis.set_major_formatter(formatter), ax.grid()
_ = n_.display_timeline(ax)

# %%
# Run a new segmentation
# ----------------------
Пример #19
0
        plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))


# %%
# Load eddies dataset
cyclonic_eddies = TrackEddiesObservations.load_file(
    py_eddy_tracker_sample.get_demo_path(
        "eddies_med_adt_allsat_dt2018/Cyclonic.zarr"))
anticyclonic_eddies = TrackEddiesObservations.load_file(
    py_eddy_tracker_sample.get_demo_path(
        "eddies_med_adt_allsat_dt2018/Anticyclonic.zarr"))

# %%
# Load loopers dataset
loopers_med = TrackEddiesObservations.load_file(
    data.get_demo_path("loopers_lumpkin_med.nc"))

# %%
# Global view
# ===========
ax = start_axes("All drifters available in Med from Lumpkin dataset")
loopers_med.plot(ax, lw=0.5, color="r", ref=-10)
update_axes(ax)

# %%
# One segment of drifter
# ======================
#
# Get a drifter segment (the indexes used have no correspondance with the original dataset).
looper = loopers_med.extract_ids((3588, ))
fig = plt.figure(figsize=(16, 6))
Пример #20
0
            ax.set_xlabel(ax.get_xlabel(),
                          fontsize=labelsize,
                          fontweight=labelweight)
        if ax.get_title() != "":
            ax.set_title(ax.get_title(),
                         fontsize=labelsize,
                         fontweight=labelweight)
        ax.tick_params(labelsize=ticklabelsize)


# %%
# Load Input grid, ADT is used to detect eddies
margin = 30

kw_data = dict(
    filename=data.get_demo_path(
        "nrt_global_allsat_phy_l4_20190223_20190226.nc"),
    x_name="longitude",
    y_name="latitude",
    # Manual area subset
    indexs=dict(
        latitude=slice(100 - margin, 220 + margin),
        longitude=slice(0, 230 + margin),
    ),
)
g_raw = RegularGridDataset(**kw_data)
g_raw.add_uv("adt")
g = RegularGridDataset(**kw_data)
g.copy("adt", "adt_low")
g.bessel_high_filter("adt", 700)
g.bessel_low_filter("adt_low", 700)
g.add_uv("adt")
Пример #21
0
from py_eddy_tracker.observations.observation import EddiesObservations, Table
from py_eddy_tracker.observations.tracking import TrackEddiesObservations

# %%
# Eddies can be stored in 2 formats with the same structure:
#
# - zarr (https://zarr.readthedocs.io/en/stable/), which allow efficiency in IO,...
# - NetCDF4 (https://unidata.github.io/netcdf4-python/), well-known format
#
# Each field are stored in column, each row corresponds at 1 observation,
# array field like contour/profile are 2D column.

# %%
# Eddies files (zarr or netcdf) could be loaded with ```load_file``` method:
eddies_collections = EddiesObservations.load_file(
    get_demo_path("Cyclonic_20160515.nc"))
eddies_collections.field_table()
# offset and scale_factor are used only when data is stored in zarr or netCDF4

# %%
# Field access
# ------------
# To access the total field, here ```amplitude```
eddies_collections.amplitude

# To access only a specific part of the field
eddies_collections.amplitude[4:15]

# %%
# Data matrix is a numpy ndarray
eddies_collections.obs