Skip to content

Commit 230d6d1

Browse files
committed
Add a method to get mean of grid inside a contour
Add docstrings
1 parent 775b28f commit 230d6d1

File tree

12 files changed

+386
-79
lines changed

12 files changed

+386
-79
lines changed

doc/autodoc/featured_tracking.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ Featured tracking
44
.. automodule:: py_eddy_tracker.featured_tracking.old_tracker_reference
55
:members:
66
:undoc-members:
7-
:show-inheritance:
7+
:show-inheritance:

doc/autodoc/generic.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Generic function
2+
================
3+
4+
.. automodule:: py_eddy_tracker.generic
5+
:members:
6+
:undoc-members:
7+
:show-inheritance:

doc/conf.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# import sys
1616
# import os
1717
import sphinx_rtd_theme
18-
18+
import py_eddy_tracker
1919

2020
# If extensions (or modules to document with autodoc) are in another directory,
2121
# add these directories to sys.path here. If the directory is relative to the
@@ -82,9 +82,9 @@
8282
# built documents.
8383
#
8484
# The short X.Y version.
85-
version = u"3.0"
85+
version = py_eddy_tracker.__version__
8686
# The full version, including alpha/beta/rc tags.
87-
release = u"3.0"
87+
release = py_eddy_tracker.__version__
8888

8989
# The language for content autogenerated by Sphinx. Refer to documentation
9090
# for a list of supported languages.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""
2+
Get mean of grid in each eddies
3+
===============================
4+
5+
"""
6+
7+
from matplotlib import pyplot as plt
8+
from py_eddy_tracker.dataset.grid import RegularGridDataset
9+
from py_eddy_tracker.observations.observation import EddiesObservations
10+
from py_eddy_tracker import data
11+
12+
13+
# %%
14+
def start_axes(title):
15+
fig = plt.figure(figsize=(13, 5))
16+
ax = fig.add_axes([0.03, 0.03, 0.90, 0.94])
17+
ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)
18+
ax.set_aspect("equal")
19+
ax.set_title(title)
20+
return ax
21+
22+
23+
def update_axes(ax, mappable=None):
24+
ax.grid()
25+
ax.legend()
26+
if mappable:
27+
plt.colorbar(m, cax=ax.figure.add_axes([0.95, 0.05, 0.01, 0.9]))
28+
29+
30+
# %%
31+
# Load detection files and data to interp
32+
a = EddiesObservations.load_file(data.get_path("Anticyclonic_20160515.nc"))
33+
c = EddiesObservations.load_file(data.get_path("Cyclonic_20160515.nc"))
34+
35+
aviso_map = RegularGridDataset(
36+
data.get_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), "longitude", "latitude"
37+
)
38+
aviso_map.add_uv("adt")
39+
40+
# %%
41+
# Compute and store eke in cm²/s²
42+
aviso_map.add_grid(
43+
"eke", (aviso_map.grid("u") ** 2 + aviso_map.grid("v") ** 2) * 0.5 * (100 ** 2)
44+
)
45+
46+
eke_kwargs = dict(vmin=1, vmax=1000, cmap="magma_r")
47+
48+
ax = start_axes("EKE (cm²/s²)")
49+
m = aviso_map.display(ax, "eke", **eke_kwargs)
50+
a.display(ax, color="r", linewidth=0.5, label="Anticyclonic", ref=-10)
51+
c.display(ax, color="b", linewidth=0.5, label="Cyclonic", ref=-10)
52+
update_axes(ax, m)
53+
54+
# %%
55+
# Get mean of eke in each effective contour
56+
57+
ax = start_axes("EKE (cm²/s²)")
58+
a.display(ax, color="r", linewidth=0.5, label="Anticyclonic", ref=-10)
59+
c.display(ax, color="b", linewidth=0.5, label="Cyclonic", ref=-10)
60+
eke = a.interp_grid(aviso_map, "eke", method="mean", intern=False)
61+
m = ax.scatter((a.longitude + 10) % 360 - 10, a.latitude, c=eke, **eke_kwargs)
62+
eke = c.interp_grid(aviso_map, "eke", method="mean", intern=False)
63+
m = ax.scatter((c.longitude + 10) % 360 - 10, c.latitude, c=eke, **eke_kwargs)
64+
update_axes(ax, m)

examples/10_tracking_diagnostics/pet_propagation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""
22
Propagation Histogram
3-
===================
3+
=====================
44
55
"""
66
from matplotlib import pyplot as plt
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {
7+
"collapsed": false
8+
},
9+
"outputs": [],
10+
"source": [
11+
"%matplotlib inline"
12+
]
13+
},
14+
{
15+
"cell_type": "markdown",
16+
"metadata": {},
17+
"source": [
18+
"\n# Get mean of grid in each eddies\n"
19+
]
20+
},
21+
{
22+
"cell_type": "code",
23+
"execution_count": null,
24+
"metadata": {
25+
"collapsed": false
26+
},
27+
"outputs": [],
28+
"source": [
29+
"from matplotlib import pyplot as plt\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\nfrom py_eddy_tracker.observations.observation import EddiesObservations\nfrom py_eddy_tracker import data"
30+
]
31+
},
32+
{
33+
"cell_type": "code",
34+
"execution_count": null,
35+
"metadata": {
36+
"collapsed": false
37+
},
38+
"outputs": [],
39+
"source": [
40+
"def start_axes(title):\n fig = plt.figure(figsize=(13, 5))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94])\n ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\n ax.set_aspect(\"equal\")\n ax.set_title(title)\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid()\n ax.legend()\n if mappable:\n plt.colorbar(m, cax=ax.figure.add_axes([0.95, 0.05, 0.01, 0.9]))"
41+
]
42+
},
43+
{
44+
"cell_type": "markdown",
45+
"metadata": {},
46+
"source": [
47+
"Load detection files and data to interp\n\n"
48+
]
49+
},
50+
{
51+
"cell_type": "code",
52+
"execution_count": null,
53+
"metadata": {
54+
"collapsed": false
55+
},
56+
"outputs": [],
57+
"source": [
58+
"a = EddiesObservations.load_file(data.get_path(\"Anticyclonic_20160515.nc\"))\nc = EddiesObservations.load_file(data.get_path(\"Cyclonic_20160515.nc\"))\n\naviso_map = RegularGridDataset(\n data.get_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\n# aviso_map.add_uv(\"adt\")\naviso_map.add_uv(\"sla\")"
59+
]
60+
},
61+
{
62+
"cell_type": "markdown",
63+
"metadata": {},
64+
"source": [
65+
"Compute and store eke in cm\u00b2/s\u00b2\n\n"
66+
]
67+
},
68+
{
69+
"cell_type": "code",
70+
"execution_count": null,
71+
"metadata": {
72+
"collapsed": false
73+
},
74+
"outputs": [],
75+
"source": [
76+
"aviso_map.add_grid(\n \"eke\", (aviso_map.grid(\"u\") ** 2 + aviso_map.grid(\"v\") ** 2) * 0.5 * (100 ** 2)\n)\n\neke_kwargs = dict(vmin=1, vmax=1000, cmap=\"magma_r\")\n\nax = start_axes(\"EKE (cm\u00b2/s\u00b2)\")\nm = aviso_map.display(ax, \"eke\", **eke_kwargs)\na.display(ax, color=\"r\", linewidth=0.5, label=\"Anticyclonic\", ref=-10)\nc.display(ax, color=\"b\", linewidth=0.5, label=\"Cyclonic\", ref=-10)\nupdate_axes(ax, m)"
77+
]
78+
},
79+
{
80+
"cell_type": "markdown",
81+
"metadata": {},
82+
"source": [
83+
"Get mean of eke in each effective contour\n\n"
84+
]
85+
},
86+
{
87+
"cell_type": "code",
88+
"execution_count": null,
89+
"metadata": {
90+
"collapsed": false
91+
},
92+
"outputs": [],
93+
"source": [
94+
"ax = start_axes(\"EKE (cm\u00b2/s\u00b2)\")\na.display(ax, color=\"r\", linewidth=0.5, label=\"Anticyclonic\", ref=-10)\nc.display(ax, color=\"b\", linewidth=0.5, label=\"Cyclonic\", ref=-10)\neke = a.interp_grid(aviso_map, \"eke\", method=\"mean\", intern=False)\nm = ax.scatter((a.longitude + 10) % 360 - 10, a.latitude, c=eke, **eke_kwargs)\neke = c.interp_grid(aviso_map, \"eke\", method=\"mean\", intern=False)\nm = ax.scatter((c.longitude + 10) % 360 - 10, c.latitude, c=eke, **eke_kwargs)\nupdate_axes(ax, m)"
95+
]
96+
}
97+
],
98+
"metadata": {
99+
"kernelspec": {
100+
"display_name": "Python 3",
101+
"language": "python",
102+
"name": "python3"
103+
},
104+
"language_info": {
105+
"codemirror_mode": {
106+
"name": "ipython",
107+
"version": 3
108+
},
109+
"file_extension": ".py",
110+
"mimetype": "text/x-python",
111+
"name": "python",
112+
"nbconvert_exporter": "python",
113+
"pygments_lexer": "ipython3",
114+
"version": "3.7.0"
115+
}
116+
},
117+
"nbformat": 4,
118+
"nbformat_minor": 0
119+
}
106 KB
Binary file not shown.
107 KB
Binary file not shown.

src/py_eddy_tracker/data/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
nrt_global_allsat_phy_l4_20190223_20190226.nc \
44
20190223 adt ugos vgos longitude latitude . \
55
--cut 800 --fil 1
6+
EddyId \
7+
dt_med_allsat_phy_l4_20160515_20190101.nc \
8+
20160515 adt None None longitude latitude . \
9+
--cut 800 --fil 1
610
"""
711
from os import path
812
import requests

src/py_eddy_tracker/dataset/grid.py

Lines changed: 15 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,12 @@
5454
uniform_resample,
5555
coordinates_to_local,
5656
local_to_coordinates,
57+
get_pixel_in_regular,
58+
nearest_grd_indice,
59+
bbox_indice_regular,
5760
)
5861
from ..poly import (
5962
poly_contain_poly,
60-
winding_number_grid_in_poly,
6163
winding_number_poly,
6264
create_vertice,
6365
poly_area,
@@ -174,36 +176,6 @@ def _fit_circle_path(vertice):
174176
return centlon, centlat, eddy_radius, err
175177

176178

177-
@njit(cache=True, fastmath=True)
178-
def _get_pixel_in_regular(vertices, x_c, y_c, x_start, x_stop, y_start, y_stop):
179-
if x_stop < x_start:
180-
x_ref = vertices[0, 0]
181-
x_array = (
182-
(concatenate((x_c[x_start:], x_c[:x_stop])) - x_ref + 180) % 360
183-
+ x_ref
184-
- 180
185-
)
186-
return winding_number_grid_in_poly(
187-
x_array,
188-
y_c[y_start:y_stop],
189-
x_start,
190-
x_stop,
191-
x_c.shape[0],
192-
y_start,
193-
vertices,
194-
)
195-
else:
196-
return winding_number_grid_in_poly(
197-
x_c[x_start:x_stop],
198-
y_c[y_start:y_stop],
199-
x_start,
200-
x_stop,
201-
x_c.shape[0],
202-
y_start,
203-
vertices,
204-
)
205-
206-
207179
@njit(cache=True, fastmath=True)
208180
def _get_pixel_in_unregular(vertices, x_c, y_c, x_start, x_stop, y_start, y_stop):
209181
nb_x, nb_y = x_stop - x_start, y_stop - y_start
@@ -454,6 +426,7 @@ def is_circular(self):
454426
return False
455427

456428
def units(self, varname):
429+
"""Get unit from variable"""
457430
stored_units = self.variables_description[varname]["attrs"].get("units", None)
458431
if stored_units is not None:
459432
return stored_units
@@ -479,6 +452,15 @@ def copy(self, grid_in, grid_out):
479452
)
480453
self.vars[grid_out] = self.grid(grid_in).copy()
481454

455+
def add_grid(self, varname, grid):
456+
"""
457+
Add a grid in handler
458+
459+
:param str varname: name of future grid
460+
:param array grid: grid array
461+
"""
462+
self.vars[varname] = grid
463+
482464
def grid(self, varname, indexs=None):
483465
"""give grid required
484466
"""
@@ -1180,15 +1162,15 @@ def bbox_indice(self, vertices):
11801162

11811163
def get_pixels_in(self, contour):
11821164
(x_start, x_stop), (y_start, y_stop) = contour.bbox_slice
1183-
return _get_pixel_in_regular(
1165+
return get_pixel_in_regular(
11841166
contour.vertices, self.x_c, self.y_c, x_start, x_stop, y_start, y_stop
11851167
)
11861168

11871169
def normalize_x_indice(self, indices):
11881170
return indices % self.x_size
11891171

11901172
def nearest_grd_indice(self, x, y):
1191-
return _nearest_grd_indice(
1173+
return nearest_grd_indice(
11921174
x, y, self.x_bounds, self.y_bounds, self.xstep, self.ystep
11931175
)
11941176

@@ -1846,29 +1828,6 @@ def compute_pixel_path(x0, y0, x1, y1, x_ori, y_ori, x_step, y_step, nb_x):
18461828
return i_g, j_g, d_max
18471829

18481830

1849-
@njit(cache=True)
1850-
def bbox_indice_regular(vertices, x0, y0, xstep, ystep, N, circular, x_size):
1851-
lon, lat = vertices[:, 0], vertices[:, 1]
1852-
lon_min, lon_max = lon.min(), lon.max()
1853-
lat_min, lat_max = lat.min(), lat.max()
1854-
i_x0, i_y0 = _nearest_grd_indice(lon_min, lat_min, x0, y0, xstep, ystep)
1855-
i_x1, i_y1 = _nearest_grd_indice(lon_max, lat_max, x0, y0, xstep, ystep)
1856-
if circular:
1857-
slice_x = (i_x0 - N) % x_size, (i_x1 + N + 1) % x_size
1858-
else:
1859-
slice_x = max(i_x0 - N, 0), i_x1 + N + 1
1860-
slice_y = i_y0 - N, i_y1 + N + 1
1861-
return slice_x, slice_y
1862-
1863-
1864-
@njit(cache=True, fastmath=True)
1865-
def _nearest_grd_indice(x, y, x0, y0, xstep, ystep):
1866-
return (
1867-
numba_types.int32(round(((x - x0[0]) % 360.0) / xstep)),
1868-
numba_types.int32(round((y - y0[0]) / ystep)),
1869-
)
1870-
1871-
18721831
@njit(cache=True)
18731832
def has_masked_value(grid, i_x, i_y):
18741833
for i, j in zip(i_x, i_y):

0 commit comments

Comments
 (0)