Beispiel #1
0
Dummy advection which use only static geostrophic current, which didn't solve the complex circulation of the ocean.
"""
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_path
from py_eddy_tracker.dataset.grid import RegularGridDataset
from py_eddy_tracker.observations.observation import EddiesObservations

# %%
# Load Input grid ADT
g = RegularGridDataset(get_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_path("Anticyclonic_20160515.nc"))
c = EddiesObservations.load_file(get_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)
Beispiel #2
0
            
    ax.set_extent(extent)
    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)
Beispiel #3
0
    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]))


# %%
# Load Input grid, ADT will be 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=-0.15, vmax=1)
# Draw line on the gulf stream front
great_current = Contours(g.x_c,
                         g.y_c,
                         g.grid("adt"),
Beispiel #4
0
from matplotlib.path import Path
from numpy import array, ma
from pytest import approx

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

G = RegularGridDataset(get_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()

Beispiel #5
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_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
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_path(
    f"dt_blacksea_allsat_phy_l4_{date:%Y%m%d}_20200801.nc")
filename_sst = data.get_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_path(filename_alt),
                          x_name="longitude",
                          y_name="latitude")
# We can use `Grid` tools to interpolate ADT on the sst grid
Beispiel #7
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_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
# ----------------------
Beispiel #8
0
        axes.set_xlim(270, 340), axes.set_ylim(20, 50)
    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_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)

# %%
Beispiel #9
0
import zarr
from netCDF4 import Dataset

from py_eddy_tracker.data import get_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_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)
Beispiel #10
0
import zarr

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

a_filename, c_filename = (
    get_path("Anticyclonic_20190223.nc"),
    get_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)))
Beispiel #11
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_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)
Beispiel #12
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 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)


# %%
n = NetworkObservations.load_file(get_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_path("dt_med_allsat_phy_l4_2005T2.nc"),
    "longitude",
    "latitude",
    "time",
    heigth="adt",
)

# %%
# Schema
# ------
fig = plt.figure(figsize=(12, 6))
Beispiel #13
0
from datetime import datetime

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

g = RegularGridDataset(get_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
Beispiel #14
0
Dummy advection which use only static geostrophic current, which didn't resolve the complex circulation of the ocean.
"""
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation

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

# %%
# Load Input grid, ADT is used to detect eddies
g = RegularGridDataset(
    data.get_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(data.get_path("Anticyclonic_20160515.nc"))
c = EddiesObservations.load_file(data.get_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 = np.meshgrid(g.x_c, g.y_c)
Beispiel #15
0
Network basic manipulation
==========================
"""

from matplotlib import pyplot as plt

import py_eddy_tracker.gui
from py_eddy_tracker import data
from py_eddy_tracker.observations.network import NetworkObservations
from py_eddy_tracker.observations.tracking import TrackEddiesObservations

# %%
# Load data
# ---------
# Load data where observations are put in same network but no segmentation
e = TrackEddiesObservations.load_file(data.get_path("c568803.nc"))
# FIXME : Must be rewrote
e.lon[:] = (e.lon + 180) % 360 - 180
e.contour_lon_e[:] = ((e.contour_lon_e.T - e.lon + 180) % 360 - 180 + e.lon).T
e.contour_lon_s[:] = ((e.contour_lon_s.T - e.lon + 180) % 360 - 180 + e.lon).T
# %%
# Do segmentation
# ---------------
# Segmentation based on maximum overlap, temporal window for candidates = 5 days
n = NetworkObservations.from_split_network(e, e.split_network(intern=False, window=5))

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

# %%
Beispiel #16
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(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
Beispiel #17
0
from matplotlib import pyplot as plt
from numba import njit
from numpy import arange, arctan2, empty, isnan, log2, ma, meshgrid, ones, pi, zeros

from py_eddy_tracker import start_logger
from py_eddy_tracker.data import get_path
from py_eddy_tracker.dataset.grid import GridCollection, RegularGridDataset

start_logger().setLevel("ERROR")


# %%
# ADT in med
# ----------
c = GridCollection.from_netcdf_cube(
    get_path("dt_med_allsat_phy_l4_2005T2.nc"),
    "longitude",
    "latitude",
    "time",
    # To create U/V variable
    heigth="adt",
)


# %%
# Methods to compute FSLE
# -----------------------
@njit(cache=True, fastmath=True)
def check_p(x, y, flse, theta, m_set, m, dt, dist_init=0.02, dist_max=0.6):
    """
    Check if distance between eastern or northern particle to center particle is bigger than `dist_max`
Beispiel #18
0
 - Circle

In the two case we use a least square algorithm
"""

from matplotlib import pyplot as plt
from numpy import cos, linspace, radians, sin

from py_eddy_tracker import data
from py_eddy_tracker.generic import coordinates_to_local, local_to_coordinates
from py_eddy_tracker.observations.observation import EddiesObservations
from py_eddy_tracker.poly import fit_circle_, fit_ellips

# %%
# Load example identification file
a = EddiesObservations.load_file(data.get_path("Anticyclonic_20190223.nc"))


# %%
# Function to draw circle or ellips from parameter
def build_circle(x0, y0, r):
    angle = radians(linspace(0, 360, 50))
    x_norm, y_norm = cos(angle), sin(angle)
    return local_to_coordinates(x_norm * r, y_norm * r, x0, y0)


def build_ellips(x0, y0, a, b, theta):
    angle = radians(linspace(0, 360, 50))
    x = a * cos(theta) * cos(angle) - b * sin(theta) * sin(angle)
    y = a * sin(theta) * cos(angle) + b * cos(theta) * sin(angle)
    return local_to_coordinates(x, y, x0, y0)
Beispiel #19
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_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)
update_axes(ax, mappable)

# %%
# Particles
# ---------