From 50bc33adb7c58514ecef2379ccdeb57428430bc7 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Fri, 4 Dec 2020 09:39:00 +0100 Subject: [PATCH 001/249] Propagate cmin value in areatracker --- examples/10_tracking_diagnostics/pet_center_count.py | 3 ++- examples/10_tracking_diagnostics/pet_pixel_used.py | 3 ++- src/py_eddy_tracker/featured_tracking/area_tracker.py | 5 +++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/examples/10_tracking_diagnostics/pet_center_count.py b/examples/10_tracking_diagnostics/pet_center_count.py index 295299cd..4533b72f 100644 --- a/examples/10_tracking_diagnostics/pet_center_count.py +++ b/examples/10_tracking_diagnostics/pet_center_count.py @@ -2,7 +2,8 @@ Count center ============ -Do Geo stat with center and compare with frequency method show: :ref:`sphx_glr_python_module_10_tracking_diagnostics_pet_pixel_used.py` +Do Geo stat with center and compare with frequency method +show: :ref:`sphx_glr_python_module_10_tracking_diagnostics_pet_pixel_used.py` """ import py_eddy_tracker_sample from matplotlib import pyplot as plt diff --git a/examples/10_tracking_diagnostics/pet_pixel_used.py b/examples/10_tracking_diagnostics/pet_pixel_used.py index 43e59d68..6241bf9f 100644 --- a/examples/10_tracking_diagnostics/pet_pixel_used.py +++ b/examples/10_tracking_diagnostics/pet_pixel_used.py @@ -2,7 +2,8 @@ Count pixel used ================ -Do Geo stat with frequency and compare with center count method: :ref:`sphx_glr_python_module_10_tracking_diagnostics_pet_center_count.py` +Do Geo stat with frequency and compare with center count +method: :ref:`sphx_glr_python_module_10_tracking_diagnostics_pet_center_count.py` """ import py_eddy_tracker_sample from matplotlib import pyplot as plt diff --git a/src/py_eddy_tracker/featured_tracking/area_tracker.py b/src/py_eddy_tracker/featured_tracking/area_tracker.py index 5aa8e43c..4abc0299 100644 --- a/src/py_eddy_tracker/featured_tracking/area_tracker.py +++ b/src/py_eddy_tracker/featured_tracking/area_tracker.py @@ -15,6 +15,11 @@ def __init__(self, *args, cmin=0.2, **kwargs): super().__init__(*args, **kwargs) self.cmin = cmin + def merge(self, *args, **kwargs): + eddies = super().merge(*args, **kwargs) + eddies.cmin = self.cmin + return eddies + @classmethod def needed_variable(cls): vars = ["longitude", "latitude"] From c48382758904a433a68109c163500abace0fe5b1 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Wed, 9 Dec 2020 17:38:45 +0100 Subject: [PATCH 002/249] example of visvalingam use --- examples/14_generic_tools/README.rst | 3 + examples/14_generic_tools/pet_visvalingam.py | 95 +++++++++++++++++++ .../14_generic_tools/pet_visvalingam.ipynb | 83 ++++++++++++++++ src/py_eddy_tracker/appli/grid.py | 15 +++ src/py_eddy_tracker/dataset/grid.py | 8 +- src/py_eddy_tracker/poly.py | 13 +-- 6 files changed, 209 insertions(+), 8 deletions(-) create mode 100644 examples/14_generic_tools/README.rst create mode 100644 examples/14_generic_tools/pet_visvalingam.py create mode 100644 notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb diff --git a/examples/14_generic_tools/README.rst b/examples/14_generic_tools/README.rst new file mode 100644 index 00000000..0f949ec4 --- /dev/null +++ b/examples/14_generic_tools/README.rst @@ -0,0 +1,3 @@ +Polygon tools +============= + diff --git a/examples/14_generic_tools/pet_visvalingam.py b/examples/14_generic_tools/pet_visvalingam.py new file mode 100644 index 00000000..6ad59c29 --- /dev/null +++ b/examples/14_generic_tools/pet_visvalingam.py @@ -0,0 +1,95 @@ +""" +Visvalingam algorithm +===================== +""" +import matplotlib.animation as animation +from matplotlib import pyplot as plt +from numba import njit +from numpy import array, empty + +from py_eddy_tracker import data +from py_eddy_tracker.generic import uniform_resample +from py_eddy_tracker.observations.observation import EddiesObservations +from py_eddy_tracker.poly import vertice_overlap, visvalingam + + +@njit(cache=True) +def visvalingam_polys(x, y, nb_pt): + nb = x.shape[0] + x_new = empty((nb, nb_pt), dtype=x.dtype) + y_new = empty((nb, nb_pt), dtype=y.dtype) + for i in range(nb): + x_new[i], y_new[i] = visvalingam(x[i], y[i], nb_pt) + return x_new, y_new + + +@njit(cache=True) +def uniform_resample_polys(x, y, nb_pt): + nb = x.shape[0] + x_new = empty((nb, nb_pt), dtype=x.dtype) + y_new = empty((nb, nb_pt), dtype=y.dtype) + for i in range(nb): + x_new[i], y_new[i] = uniform_resample(x[i], y[i], fixed_size=nb_pt) + return x_new, y_new + + +def update_line(num): + nb = 50 - num - 20 + x_v, y_v = visvalingam_polys(a.contour_lon_e, a.contour_lat_e, nb) + for i, (x_, y_) in enumerate(zip(x_v, y_v)): + lines_v[i].set_data(x_, y_) + x_u, y_u = uniform_resample_polys(a.contour_lon_e, a.contour_lat_e, nb) + for i, (x_, y_) in enumerate(zip(x_u, y_u)): + 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_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()))) + + +# %% +fig = plt.figure() +axs = [ + fig.add_subplot(221), + fig.add_subplot(222), + fig.add_subplot(223), + fig.add_subplot(224), +] +lines_u, lines_v, texts, score_text = list(), list(), list(), list() +for i, obs in enumerate(a): + axs[i].set_aspect("equal") + axs[i].grid() + axs[i].set_xticklabels([]), axs[i].set_yticklabels([]) + axs[i].plot( + obs["contour_lon_e"], obs["contour_lat_e"], "r", lw=6, label="Original contour" + ) + lines_v.append(axs[i].plot([], [], color="limegreen", lw=4, label="visvalingam")[0]) + lines_u.append( + axs[i].plot([], [], color="black", lw=2, label="uniform resampling")[0] + ) + texts.append(axs[i].set_title("", fontsize=8)) +axs[0].legend(fontsize=8) +title = fig.suptitle("") +ani = animation.FuncAnimation(fig, update_line, 27) diff --git a/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb b/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb new file mode 100644 index 00000000..aee1f340 --- /dev/null +++ b/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb @@ -0,0 +1,83 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Visvalingam algorithm\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import matplotlib.animation as animation\nfrom matplotlib import pyplot as plt\nfrom numba import njit\nfrom numpy import array, empty\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.generic import uniform_resample\nfrom py_eddy_tracker.observations.observation import EddiesObservations\nfrom py_eddy_tracker.poly import vertice_overlap, visvalingam\n\n\n@njit(cache=True)\ndef visvalingam_polys(x, y, nb_pt):\n nb = x.shape[0]\n x_new = empty((nb, nb_pt), dtype=x.dtype)\n y_new = empty((nb, nb_pt), dtype=y.dtype)\n for i in range(nb):\n x_new[i], y_new[i] = visvalingam(x[i], y[i], nb_pt)\n return x_new, y_new\n\n\n@njit(cache=True)\ndef uniform_resample_polys(x, y, nb_pt):\n nb = x.shape[0]\n x_new = empty((nb, nb_pt), dtype=x.dtype)\n y_new = empty((nb, nb_pt), dtype=y.dtype)\n for i in range(nb):\n x_new[i], y_new[i] = uniform_resample(x[i], y[i], fixed_size=nb_pt)\n return x_new, y_new\n\n\ndef update_line(num):\n nb = 50 - num - 20\n x_v, y_v = visvalingam_polys(a.contour_lon_e, a.contour_lat_e, nb)\n for i, (x_, y_) in enumerate(zip(x_v, y_v)):\n lines_v[i].set_data(x_, y_)\n x_u, y_u = uniform_resample_polys(a.contour_lon_e, a.contour_lat_e, nb)\n for i, (x_, y_) in enumerate(zip(x_u, y_u)):\n lines_u[i].set_data(x_, y_)\n scores_v = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_v, y_v) * 100.0\n scores_u = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_u, y_u) * 100.0\n for i, (s_v, s_u) in enumerate(zip(scores_v, scores_u)):\n texts[i].set_text(f\"Score uniform {s_u:.1f} %\\nScore visvalingam {s_v:.1f} %\")\n title.set_text(f\"{nb} points by contour in place of 50\")\n return (title, *lines_u, *lines_v, *texts)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load detection files\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "a = EddiesObservations.load_file(data.get_path(\"Anticyclonic_20190223.nc\"))\na = a.extract_with_mask((abs(a.lat) < 66) * (abs(a.radius_e) > 80e3))\n\nnb_pt = 10\nx_v, y_v = visvalingam_polys(a.contour_lon_e, a.contour_lat_e, nb_pt)\nx_u, y_u = uniform_resample_polys(a.contour_lon_e, a.contour_lat_e, nb_pt)\nscores_v = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_v, y_v) * 100.0\nscores_u = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_u, y_u) * 100.0\nd_6 = scores_v - scores_u\nnb_pt = 18\nx_v, y_v = visvalingam_polys(a.contour_lon_e, a.contour_lat_e, nb_pt)\nx_u, y_u = uniform_resample_polys(a.contour_lon_e, a.contour_lat_e, nb_pt)\nscores_v = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_v, y_v) * 100.0\nscores_u = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_u, y_u) * 100.0\nd_12 = scores_v - scores_u\na = a.index(array((d_6.argmin(), d_6.argmax(), d_12.argmin(), d_12.argmax())))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure()\naxs = [\n fig.add_subplot(221),\n fig.add_subplot(222),\n fig.add_subplot(223),\n fig.add_subplot(224),\n]\nlines_u, lines_v, texts, score_text = list(), list(), list(), list()\nfor i, obs in enumerate(a):\n axs[i].set_aspect(\"equal\")\n axs[i].grid()\n axs[i].set_xticklabels([]), axs[i].set_yticklabels([])\n axs[i].plot(\n obs[\"contour_lon_e\"], obs[\"contour_lat_e\"], \"r\", lw=6, label=\"Original contour\"\n )\n lines_v.append(axs[i].plot([], [], color=\"limegreen\", lw=4, label=\"visvalingam\")[0])\n lines_u.append(\n axs[i].plot([], [], color=\"black\", lw=2, label=\"uniform resampling\")[0]\n )\n texts.append(axs[i].set_title(\"\", fontsize=8))\naxs[0].legend(fontsize=8)\ntitle = fig.suptitle(\"\")\nani = animation.FuncAnimation(fig, update_line, 27)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/src/py_eddy_tracker/appli/grid.py b/src/py_eddy_tracker/appli/grid.py index 39456643..f5fadf9c 100644 --- a/src/py_eddy_tracker/appli/grid.py +++ b/src/py_eddy_tracker/appli/grid.py @@ -79,6 +79,19 @@ def eddy_id(args=None): parser.add_argument("--height_unit", default=None, help="Force height unit") parser.add_argument("--speed_unit", default=None, help="Force speed unit") parser.add_argument("--unregular", action="store_true", help="if grid is unregular") + parser.add_argument( + "--sampling", + default=50, + type=int, + help="Array size used to build contour, first and last point will be the same", + ) + parser.add_argument( + "--sampling_method", + default="visvalingam", + type=str, + choices=("visvalingam", "uniform"), + help="Method to resample contour", + ) help = "Output will be wrote in zarr" parser.add_argument("--zarr", action="store_true", help=help) help = "Indexs to select grid : --indexs time=2, will select third step along time dimensions" @@ -109,6 +122,8 @@ def eddy_id(args=None): cut_wavelength=args.cut_wavelength, filter_order=args.filter_order, indexs=args.indexs, + sampling=args.sampling, + sampling_method=args.sampling_method, **kwargs, ) out_name = date.strftime("%(path)s/%(sign_type)s_%Y%m%d.nc") diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 3fd48f89..52f8201c 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -68,6 +68,7 @@ get_pixel_in_regular, poly_area, poly_contain_poly, + visvalingam, winding_number_poly, ) @@ -602,6 +603,7 @@ def eddy_identification( step=0.005, shape_error=55, sampling=50, + sampling_method="visvalingam", pixel_limit=None, precision=None, force_height_unit=None, @@ -618,6 +620,7 @@ def eddy_identification( :param float,int step: Height between two layers in m :param float,int shape_error: Maximal error allowed for outter contour in % :param int sampling: Number of points to store contours and speed profile + :param str sampling_method: Method to resample 'uniform' or 'visvalingam' :param (int,int),None pixel_limit: Min and max number of pixels inside the inner and the outer contour to be considered as an eddy :param float,None precision: Truncate values at the defined precision in m @@ -693,6 +696,7 @@ def eddy_identification( self.contours = Contours(x, y, data, levels, wrap_x=self.is_circular()) out_sampling = dict(fixed_size=sampling) + resample = visvalingam if sampling_method == "visvalingam" else uniform_resample track_extra_variables = [ "height_max_speed_contour", "height_external_contour", @@ -832,10 +836,10 @@ def eddy_identification( obs.amplitude[:] = amp.amplitude obs.speed_average[:] = max_average_speed obs.num_point_e[:] = contour.lon.shape[0] - xy_e = uniform_resample(contour.lon, contour.lat, **out_sampling) + xy_e = resample(contour.lon, contour.lat, **out_sampling) obs.contour_lon_e[:], obs.contour_lat_e[:] = xy_e obs.num_point_s[:] = speed_contour.lon.shape[0] - xy_s = uniform_resample( + xy_s = resample( speed_contour.lon, speed_contour.lat, **out_sampling ) obs.contour_lon_s[:], obs.contour_lat_s[:] = xy_s diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index 08792241..eb601dca 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -671,12 +671,12 @@ def tri_area2(x, y, i0, i1, i2): @njit(cache=True) -def visvalingam(x, y, nb_pt=18): +def visvalingam(x, y, fixed_size=18): """Polygon simplification with visvalingam algorithm :param array x: :param array y: - :param int nb_pt: array size of out + :param int fixed_size: array size of out :return: New (x, y) array :rtype: array,array """ @@ -696,7 +696,7 @@ def visvalingam(x, y, nb_pt=18): i0 = i1 i1 = i # we continue until we are equal to nb_pt - while len(h) >= nb_pt: + while len(h) >= fixed_size: # We pop lower area _, (i0, i1, i2) = heapq.heappop(h) # We check if triangle is valid(i0 or i2 not removed) @@ -714,13 +714,14 @@ def visvalingam(x, y, nb_pt=18): # in this case we replace two point i0, i2 = i_p, i_n heapq.heappush(h, (tri_area2(x, y, i0, i1, i2), (i0, i1, i2))) - x_new, y_new = empty(nb_pt, dtype=x.dtype), empty(nb_pt, dtype=y.dtype) + x_new, y_new = empty(fixed_size, dtype=x.dtype), empty(fixed_size, dtype=y.dtype) j = 0 for i, i_n in enumerate(i_next): if i_n == -1: x_new[j] = x[i] y_new[j] = y[i] j += 1 - x_new[j] = x_new[0] - y_new[j] = y_new[0] + # we copy first value to fill array end + x_new[j:] = x_new[0] + y_new[j:] = y_new[0] return x_new, y_new From 3ae57d393e24228962f4db76a840c465e0e71b4b Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Wed, 9 Dec 2020 18:29:20 +0100 Subject: [PATCH 003/249] Try to have working animation example --- doc/conf.py | 2 +- examples/14_generic_tools/pet_visvalingam.py | 3 +++ .../python_module/14_generic_tools/pet_visvalingam.ipynb | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index add04862..12c732f8 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -54,7 +54,7 @@ sphinx_gallery_conf = { "examples_dirs": "../examples", # path to your example scripts "gallery_dirs": "python_module", - "capture_repr": ("_repr_html_",), + "capture_repr": ("_repr_html_", "__repr__"), "backreferences_dir": "gen_modules/backreferences", "doc_module": ("py_eddy_tracker",), "reference_url": { diff --git a/examples/14_generic_tools/pet_visvalingam.py b/examples/14_generic_tools/pet_visvalingam.py index 6ad59c29..1e969ddd 100644 --- a/examples/14_generic_tools/pet_visvalingam.py +++ b/examples/14_generic_tools/pet_visvalingam.py @@ -4,6 +4,7 @@ """ import matplotlib.animation as animation from matplotlib import pyplot as plt +from matplotlib import rc from numba import njit from numpy import array, empty @@ -12,6 +13,8 @@ from py_eddy_tracker.observations.observation import EddiesObservations from py_eddy_tracker.poly import vertice_overlap, visvalingam +rc("animation", html="jshtml") + @njit(cache=True) def visvalingam_polys(x, y, nb_pt): diff --git a/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb b/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb index aee1f340..f27ba8c3 100644 --- a/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb +++ b/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import matplotlib.animation as animation\nfrom matplotlib import pyplot as plt\nfrom numba import njit\nfrom numpy import array, empty\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.generic import uniform_resample\nfrom py_eddy_tracker.observations.observation import EddiesObservations\nfrom py_eddy_tracker.poly import vertice_overlap, visvalingam\n\n\n@njit(cache=True)\ndef visvalingam_polys(x, y, nb_pt):\n nb = x.shape[0]\n x_new = empty((nb, nb_pt), dtype=x.dtype)\n y_new = empty((nb, nb_pt), dtype=y.dtype)\n for i in range(nb):\n x_new[i], y_new[i] = visvalingam(x[i], y[i], nb_pt)\n return x_new, y_new\n\n\n@njit(cache=True)\ndef uniform_resample_polys(x, y, nb_pt):\n nb = x.shape[0]\n x_new = empty((nb, nb_pt), dtype=x.dtype)\n y_new = empty((nb, nb_pt), dtype=y.dtype)\n for i in range(nb):\n x_new[i], y_new[i] = uniform_resample(x[i], y[i], fixed_size=nb_pt)\n return x_new, y_new\n\n\ndef update_line(num):\n nb = 50 - num - 20\n x_v, y_v = visvalingam_polys(a.contour_lon_e, a.contour_lat_e, nb)\n for i, (x_, y_) in enumerate(zip(x_v, y_v)):\n lines_v[i].set_data(x_, y_)\n x_u, y_u = uniform_resample_polys(a.contour_lon_e, a.contour_lat_e, nb)\n for i, (x_, y_) in enumerate(zip(x_u, y_u)):\n lines_u[i].set_data(x_, y_)\n scores_v = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_v, y_v) * 100.0\n scores_u = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_u, y_u) * 100.0\n for i, (s_v, s_u) in enumerate(zip(scores_v, scores_u)):\n texts[i].set_text(f\"Score uniform {s_u:.1f} %\\nScore visvalingam {s_v:.1f} %\")\n title.set_text(f\"{nb} points by contour in place of 50\")\n return (title, *lines_u, *lines_v, *texts)" + "import matplotlib.animation as animation\nfrom matplotlib import pyplot as plt, rc\nfrom numba import njit\nfrom numpy import array, empty\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.generic import uniform_resample\nfrom py_eddy_tracker.observations.observation import EddiesObservations\nfrom py_eddy_tracker.poly import vertice_overlap, visvalingam\n\nrc('animation', html='jshtml')\n\n@njit(cache=True)\ndef visvalingam_polys(x, y, nb_pt):\n nb = x.shape[0]\n x_new = empty((nb, nb_pt), dtype=x.dtype)\n y_new = empty((nb, nb_pt), dtype=y.dtype)\n for i in range(nb):\n x_new[i], y_new[i] = visvalingam(x[i], y[i], nb_pt)\n return x_new, y_new\n\n\n@njit(cache=True)\ndef uniform_resample_polys(x, y, nb_pt):\n nb = x.shape[0]\n x_new = empty((nb, nb_pt), dtype=x.dtype)\n y_new = empty((nb, nb_pt), dtype=y.dtype)\n for i in range(nb):\n x_new[i], y_new[i] = uniform_resample(x[i], y[i], fixed_size=nb_pt)\n return x_new, y_new\n\n\ndef update_line(num):\n nb = 50 - num - 20\n x_v, y_v = visvalingam_polys(a.contour_lon_e, a.contour_lat_e, nb)\n for i, (x_, y_) in enumerate(zip(x_v, y_v)):\n lines_v[i].set_data(x_, y_)\n x_u, y_u = uniform_resample_polys(a.contour_lon_e, a.contour_lat_e, nb)\n for i, (x_, y_) in enumerate(zip(x_u, y_u)):\n lines_u[i].set_data(x_, y_)\n scores_v = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_v, y_v) * 100.0\n scores_u = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_u, y_u) * 100.0\n for i, (s_v, s_u) in enumerate(zip(scores_v, scores_u)):\n texts[i].set_text(f\"Score uniform {s_u:.1f} %\\nScore visvalingam {s_v:.1f} %\")\n title.set_text(f\"{nb} points by contour in place of 50\")\n return (title, *lines_u, *lines_v, *texts)" ] }, { @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure()\naxs = [\n fig.add_subplot(221),\n fig.add_subplot(222),\n fig.add_subplot(223),\n fig.add_subplot(224),\n]\nlines_u, lines_v, texts, score_text = list(), list(), list(), list()\nfor i, obs in enumerate(a):\n axs[i].set_aspect(\"equal\")\n axs[i].grid()\n axs[i].set_xticklabels([]), axs[i].set_yticklabels([])\n axs[i].plot(\n obs[\"contour_lon_e\"], obs[\"contour_lat_e\"], \"r\", lw=6, label=\"Original contour\"\n )\n lines_v.append(axs[i].plot([], [], color=\"limegreen\", lw=4, label=\"visvalingam\")[0])\n lines_u.append(\n axs[i].plot([], [], color=\"black\", lw=2, label=\"uniform resampling\")[0]\n )\n texts.append(axs[i].set_title(\"\", fontsize=8))\naxs[0].legend(fontsize=8)\ntitle = fig.suptitle(\"\")\nani = animation.FuncAnimation(fig, update_line, 27)" + "fig = plt.figure()\naxs = [\n fig.add_subplot(221),\n fig.add_subplot(222),\n fig.add_subplot(223),\n fig.add_subplot(224),\n]\nlines_u, lines_v, texts, score_text = list(), list(), list(), list()\nfor i, obs in enumerate(a):\n axs[i].set_aspect(\"equal\")\n axs[i].grid()\n axs[i].set_xticklabels([]), axs[i].set_yticklabels([])\n axs[i].plot(\n obs[\"contour_lon_e\"], obs[\"contour_lat_e\"], \"r\", lw=6, label=\"Original contour\"\n )\n lines_v.append(axs[i].plot([], [], color=\"limegreen\", lw=4, label=\"visvalingam\")[0])\n lines_u.append(\n axs[i].plot([], [], color=\"black\", lw=2, label=\"uniform resampling\")[0]\n )\n texts.append(axs[i].set_title(\"\", fontsize=8))\naxs[0].legend(fontsize=8)\ntitle = fig.suptitle(\"\")\nani = animation.FuncAnimation(fig, update_line, 27)\n\n# ani" ] } ], From 40ce202feefa349b65aac0d2d5fe56fad1fc7f82 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Wed, 9 Dec 2020 19:02:14 +0100 Subject: [PATCH 004/249] second anim test --- examples/14_generic_tools/pet_visvalingam.py | 6 ++---- .../python_module/14_generic_tools/pet_visvalingam.ipynb | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/examples/14_generic_tools/pet_visvalingam.py b/examples/14_generic_tools/pet_visvalingam.py index 1e969ddd..b946a9db 100644 --- a/examples/14_generic_tools/pet_visvalingam.py +++ b/examples/14_generic_tools/pet_visvalingam.py @@ -4,7 +4,6 @@ """ import matplotlib.animation as animation from matplotlib import pyplot as plt -from matplotlib import rc from numba import njit from numpy import array, empty @@ -13,8 +12,6 @@ from py_eddy_tracker.observations.observation import EddiesObservations from py_eddy_tracker.poly import vertice_overlap, visvalingam -rc("animation", html="jshtml") - @njit(cache=True) def visvalingam_polys(x, y, nb_pt): @@ -95,4 +92,5 @@ def update_line(num): texts.append(axs[i].set_title("", fontsize=8)) axs[0].legend(fontsize=8) title = fig.suptitle("") -ani = animation.FuncAnimation(fig, update_line, 27) +anim = animation.FuncAnimation(fig, update_line, 27) +anim diff --git a/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb b/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb index f27ba8c3..20215604 100644 --- a/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb +++ b/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import matplotlib.animation as animation\nfrom matplotlib import pyplot as plt, rc\nfrom numba import njit\nfrom numpy import array, empty\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.generic import uniform_resample\nfrom py_eddy_tracker.observations.observation import EddiesObservations\nfrom py_eddy_tracker.poly import vertice_overlap, visvalingam\n\nrc('animation', html='jshtml')\n\n@njit(cache=True)\ndef visvalingam_polys(x, y, nb_pt):\n nb = x.shape[0]\n x_new = empty((nb, nb_pt), dtype=x.dtype)\n y_new = empty((nb, nb_pt), dtype=y.dtype)\n for i in range(nb):\n x_new[i], y_new[i] = visvalingam(x[i], y[i], nb_pt)\n return x_new, y_new\n\n\n@njit(cache=True)\ndef uniform_resample_polys(x, y, nb_pt):\n nb = x.shape[0]\n x_new = empty((nb, nb_pt), dtype=x.dtype)\n y_new = empty((nb, nb_pt), dtype=y.dtype)\n for i in range(nb):\n x_new[i], y_new[i] = uniform_resample(x[i], y[i], fixed_size=nb_pt)\n return x_new, y_new\n\n\ndef update_line(num):\n nb = 50 - num - 20\n x_v, y_v = visvalingam_polys(a.contour_lon_e, a.contour_lat_e, nb)\n for i, (x_, y_) in enumerate(zip(x_v, y_v)):\n lines_v[i].set_data(x_, y_)\n x_u, y_u = uniform_resample_polys(a.contour_lon_e, a.contour_lat_e, nb)\n for i, (x_, y_) in enumerate(zip(x_u, y_u)):\n lines_u[i].set_data(x_, y_)\n scores_v = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_v, y_v) * 100.0\n scores_u = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_u, y_u) * 100.0\n for i, (s_v, s_u) in enumerate(zip(scores_v, scores_u)):\n texts[i].set_text(f\"Score uniform {s_u:.1f} %\\nScore visvalingam {s_v:.1f} %\")\n title.set_text(f\"{nb} points by contour in place of 50\")\n return (title, *lines_u, *lines_v, *texts)" + "import matplotlib.animation as animation\nfrom matplotlib import pyplot as plt\nfrom matplotlib import rc\nfrom numba import njit\nfrom numpy import array, empty\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.generic import uniform_resample\nfrom py_eddy_tracker.observations.observation import EddiesObservations\nfrom py_eddy_tracker.poly import vertice_overlap, visvalingam\n\n\n@njit(cache=True)\ndef visvalingam_polys(x, y, nb_pt):\n nb = x.shape[0]\n x_new = empty((nb, nb_pt), dtype=x.dtype)\n y_new = empty((nb, nb_pt), dtype=y.dtype)\n for i in range(nb):\n x_new[i], y_new[i] = visvalingam(x[i], y[i], nb_pt)\n return x_new, y_new\n\n\n@njit(cache=True)\ndef uniform_resample_polys(x, y, nb_pt):\n nb = x.shape[0]\n x_new = empty((nb, nb_pt), dtype=x.dtype)\n y_new = empty((nb, nb_pt), dtype=y.dtype)\n for i in range(nb):\n x_new[i], y_new[i] = uniform_resample(x[i], y[i], fixed_size=nb_pt)\n return x_new, y_new\n\n\ndef update_line(num):\n nb = 50 - num - 20\n x_v, y_v = visvalingam_polys(a.contour_lon_e, a.contour_lat_e, nb)\n for i, (x_, y_) in enumerate(zip(x_v, y_v)):\n lines_v[i].set_data(x_, y_)\n x_u, y_u = uniform_resample_polys(a.contour_lon_e, a.contour_lat_e, nb)\n for i, (x_, y_) in enumerate(zip(x_u, y_u)):\n lines_u[i].set_data(x_, y_)\n scores_v = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_v, y_v) * 100.0\n scores_u = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_u, y_u) * 100.0\n for i, (s_v, s_u) in enumerate(zip(scores_v, scores_u)):\n texts[i].set_text(f\"Score uniform {s_u:.1f} %\\nScore visvalingam {s_v:.1f} %\")\n title.set_text(f\"{nb} points by contour in place of 50\")\n return (title, *lines_u, *lines_v, *texts)" ] }, { @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure()\naxs = [\n fig.add_subplot(221),\n fig.add_subplot(222),\n fig.add_subplot(223),\n fig.add_subplot(224),\n]\nlines_u, lines_v, texts, score_text = list(), list(), list(), list()\nfor i, obs in enumerate(a):\n axs[i].set_aspect(\"equal\")\n axs[i].grid()\n axs[i].set_xticklabels([]), axs[i].set_yticklabels([])\n axs[i].plot(\n obs[\"contour_lon_e\"], obs[\"contour_lat_e\"], \"r\", lw=6, label=\"Original contour\"\n )\n lines_v.append(axs[i].plot([], [], color=\"limegreen\", lw=4, label=\"visvalingam\")[0])\n lines_u.append(\n axs[i].plot([], [], color=\"black\", lw=2, label=\"uniform resampling\")[0]\n )\n texts.append(axs[i].set_title(\"\", fontsize=8))\naxs[0].legend(fontsize=8)\ntitle = fig.suptitle(\"\")\nani = animation.FuncAnimation(fig, update_line, 27)\n\n# ani" + "fig = plt.figure()\naxs = [\n fig.add_subplot(221),\n fig.add_subplot(222),\n fig.add_subplot(223),\n fig.add_subplot(224),\n]\nlines_u, lines_v, texts, score_text = list(), list(), list(), list()\nfor i, obs in enumerate(a):\n axs[i].set_aspect(\"equal\")\n axs[i].grid()\n axs[i].set_xticklabels([]), axs[i].set_yticklabels([])\n axs[i].plot(\n obs[\"contour_lon_e\"], obs[\"contour_lat_e\"], \"r\", lw=6, label=\"Original contour\"\n )\n lines_v.append(axs[i].plot([], [], color=\"limegreen\", lw=4, label=\"visvalingam\")[0])\n lines_u.append(\n axs[i].plot([], [], color=\"black\", lw=2, label=\"uniform resampling\")[0]\n )\n texts.append(axs[i].set_title(\"\", fontsize=8))\naxs[0].legend(fontsize=8)\ntitle = fig.suptitle(\"\")\nanim = animation.FuncAnimation(fig, update_line, 27)\nanim" ] } ], From eaef32b0427805c8369f7cc7aea9c52284dd849b Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Fri, 11 Dec 2020 13:55:43 +0100 Subject: [PATCH 005/249] add method to check if variable is an array or field name --- .../observations/observation.py | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 005de056..23d6bf55 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -4,6 +4,7 @@ """ import logging from datetime import datetime +from io import BufferedReader from tarfile import ExFileObject from tokenize import TokenError @@ -200,11 +201,14 @@ def _repr_html_(self): infos = self.get_infos() return f"""{infos['nb_obs']} observations from {infos['t0']} to {infos['t1']} """ + def parse_varname(self, name): + return self[name] if isinstance(name, str) else name + def hist(self, varname, x, bins, percent=False, mean=False, nb=False): """Build histograms. - :param str varname: variable to use to compute stat - :param str x: variable to use to know in which bins + :param str,array varname: variable to use to compute stat + :param str,array x: variable to use to know in which bins :param array bins: :param bool percent: normalize by sum of all bins :param bool mean: compute mean by bins @@ -212,14 +216,15 @@ def hist(self, varname, x, bins, percent=False, mean=False, nb=False): :return: value by bins :rtype: array """ + x = self.parse_varname(x) if nb: - v = hist_numba(self[x], bins=bins)[0] + v = hist_numba(x, bins=bins)[0] else: - v = histogram(self[x], bins=bins, weights=self[varname])[0] + v = histogram(x, bins=bins, weights=self.parse_varname(varname))[0] if percent: v = v.astype("f4") / v.sum() * 100 elif mean: - v /= hist_numba(self[x], bins=bins)[0] + v /= hist_numba(x, bins=bins)[0] return v @staticmethod @@ -777,7 +782,7 @@ def load_from_netcdf( array_dim = "NbSample" if isinstance(filename, bytes): filename = filename.astype(str) - if isinstance(filename, ExFileObject): + if isinstance(filename, (ExFileObject, BufferedReader)): filename.seek(0) args, kwargs = ("in-mem-file",), dict(memory=filename.read()) else: @@ -1626,7 +1631,7 @@ def scatter(self, ax, name=None, ref=None, factor=1, **kwargs): x = (x - ref) % 360 + ref kwargs = kwargs.copy() if name is not None and "c" not in kwargs: - v = self[name] if isinstance(name, str) else name + v = self.parse_varname(name) kwargs["c"] = v * factor return ax.scatter(x, self.latitude, **kwargs) @@ -1671,7 +1676,7 @@ def filled( if "facecolors" not in kwargs: kwargs = kwargs.copy() cmap = get_cmap(cmap, lut) - v = (self[varname] if isinstance(varname, str) else varname) * factor + v = self.parse_varname(varname) * factor if vmin is None: vmin = v.min() if vmax is None: @@ -1783,7 +1788,7 @@ def bins_stat(self, xname, bins=None, yname=None, method=None, mask=None): .. minigallery:: py_eddy_tracker.EddiesObservations.bins_stat """ - v = self[xname] if isinstance(xname, str) else xname + v = self.parse_varname(xname) mask = self.merge_filters(mask) v = v[mask] if bins is None: @@ -1791,7 +1796,7 @@ def bins_stat(self, xname, bins=None, yname=None, method=None, mask=None): y, x = hist_numba(v, bins=bins) x = (x[1:] + x[:-1]) / 2 if method == "mean": - y_v = self[yname] if isinstance(yname, str) else yname + y_v = self.parse_varname(yname) y_v = y_v[mask] y_, _ = histogram(v, bins=bins, weights=y_v) with errstate(divide="ignore", invalid="ignore"): @@ -1948,10 +1953,10 @@ def grid_count(self, bins, intern=False, center=False, filter=slice(None)): def grid_box_stat(self, bins, varname, method=50, data=None, filter=slice(None)): """ - Compute mean of eddies in each bin + Get percentile of eddies in each bin :param (numpy.array,numpy.array) bins: bins (grid) to count - :param str varname: variable to apply the method + :param str varname: variable to apply the method if data is None and will be output name :param str,float method: method to apply. If float, use ? :param array data: Array used to compute stat if defined :param array,mask,slice filter: keep the data selected with the filter @@ -1999,7 +2004,7 @@ def grid_stat(self, bins, varname, data=None): Return the mean of the eddies' variable in each bin :param (numpy.array,numpy.array) bins: bins (grid) to compute the mean on - :param str varname: name of variable to compute the mean on + :param str varname: name of variable to compute the mean on and output grid_name :param array data: Array used to compute stat if defined :return: return the gridde mean variable :rtype: py_eddy_tracker.dataset.grid.RegularGridDataset From a91a226b3d570342784d5e40a46310c0a91d3629 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Mon, 4 Jan 2021 13:28:36 +0100 Subject: [PATCH 006/249] - Add option to load netcdf in memory before to be open - Use of safe_load for yaml - replace some numpy operation by numba equivalent --- .../pet_eddy_detection.py | 2 +- .../pet_eddy_detection.ipynb | 2 +- setup.py | 2 +- src/py_eddy_tracker/__init__.py | 7 + src/py_eddy_tracker/appli/eddies.py | 254 +++++++++++++++- src/py_eddy_tracker/appli/network.py | 9 +- .../featured_tracking/area_tracker.py | 20 +- src/py_eddy_tracker/generic.py | 2 +- src/py_eddy_tracker/observations/network.py | 97 +++++-- .../observations/observation.py | 65 ++++- src/py_eddy_tracker/poly.py | 2 +- src/py_eddy_tracker/tracking.py | 61 ++-- src/scripts/EddyTracking | 274 ------------------ 13 files changed, 429 insertions(+), 368 deletions(-) delete mode 100644 src/scripts/EddyTracking diff --git a/examples/02_eddy_identification/pet_eddy_detection.py b/examples/02_eddy_identification/pet_eddy_detection.py index d158e870..522ad4a0 100644 --- a/examples/02_eddy_identification/pet_eddy_detection.py +++ b/examples/02_eddy_identification/pet_eddy_detection.py @@ -91,7 +91,7 @@ def update_axes(ax, mappable=None): update_axes(ax) # %% -# Creteria for rejecting a contour +# Criteria for rejecting a contour # 0. - Accepted (green) # 1. - Rejection for shape error (red) # 2. - Masked value within contour (blue) diff --git a/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb b/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb index 72604a63..ee17f905 100644 --- a/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb @@ -235,7 +235,7 @@ }, "outputs": [], "source": [ - "ax = start_axes(\"Detected Eddies\")\na.display(ax, color=\"r\", linewidth=0.75, label=\"Anticyclonic ({nb_obs} eddies)\", ref=-10)\nc.display(ax, color=\"b\", linewidth=0.75, label=\"Cyclonic ({nb_obs} eddies)\", ref=-10)\nax.legend()\nupdate_axes(ax)" + "ax = start_axes(\"Detected Eddies\")\na.display(\n ax, color=\"r\", linewidth=0.75, label=\"Anticyclonic ({nb_obs} eddies)\", ref=-10\n)\nc.display(ax, color=\"b\", linewidth=0.75, label=\"Cyclonic ({nb_obs} eddies)\", ref=-10)\nax.legend()\nupdate_axes(ax)" ] }, { diff --git a/setup.py b/setup.py index d3f5d1bd..366ab160 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,6 @@ scripts=[ "src/scripts/EddySubSetter", "src/scripts/EddyTranslate", - "src/scripts/EddyTracking", "src/scripts/EddyFinalTracking", "src/scripts/EddyMergeCorrespondances", ], @@ -43,6 +42,7 @@ "EddyFrequency = py_eddy_tracker.appli.eddies:get_frequency_grid", "EddyInfos = py_eddy_tracker.appli.eddies:display_infos", "EddyCircle = py_eddy_tracker.appli.eddies:eddies_add_circle", + "EddyTracking = py_eddy_tracker.appli.eddies:eddies_tracking", # network "EddyNetworkGroup = py_eddy_tracker.appli.network:build_network", "EddyNetworkBuildPath = py_eddy_tracker.appli.network:divide_network", diff --git a/src/py_eddy_tracker/__init__.py b/src/py_eddy_tracker/__init__.py index 9be2d280..1fa57c7e 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -85,6 +85,13 @@ def add_base_argument(self): help="Levels : DEBUG, INFO, WARNING," " ERROR, CRITICAL", ) + def memory_arg(self): + self.add_argument( + "--memory", + action="store_true", + help="Load file in memory before to read with netCDF library", + ) + def parse_args(self, *args, **kwargs): logger = start_logger() # Parsing diff --git a/src/py_eddy_tracker/appli/eddies.py b/src/py_eddy_tracker/appli/eddies.py index f59eab90..2f78510f 100644 --- a/src/py_eddy_tracker/appli/eddies.py +++ b/src/py_eddy_tracker/appli/eddies.py @@ -3,12 +3,24 @@ Applications on detection and tracking files """ import argparse +import logging +from datetime import datetime +from glob import glob +from os import mkdir +from os.path import basename, dirname, exists +from os.path import join as join_path +from re import compile as re_compile from netCDF4 import Dataset +from numpy import bytes_, empty, unique +from yaml import safe_load from .. import EddyParser from ..observations.observation import EddiesObservations from ..observations.tracking import TrackEddiesObservations +from ..tracking import Correspondances + +logger = logging.getLogger("pet") def eddies_add_circle(): @@ -41,24 +53,22 @@ def merge_eddies(): parser.add_argument( "--include_var", nargs="+", type=str, help="use only listed variable" ) + parser.memory_arg() args = parser.parse_args() if args.include_var is None: with Dataset(args.filename[0]) as h: args.include_var = h.variables.keys() - obs = TrackEddiesObservations.load_file( - args.filename[0], raw_data=True, include_vars=args.include_var - ) - if args.add_rotation_variable: - obs = obs.add_rotation_type() - for filename in args.filename[1:]: - other = TrackEddiesObservations.load_file( + obs = list() + for filename in args.filename: + e = TrackEddiesObservations.load_file( filename, raw_data=True, include_vars=args.include_var ) if args.add_rotation_variable: - other = other.add_rotation_type() - obs = obs.merge(other) + e = e.add_rotation_type() + obs.append(e) + obs = TrackEddiesObservations.concatenate(obs) obs.write_file(filename=args.out) @@ -141,3 +151,229 @@ def display_infos(): ) e = e.extract_with_area(area) print(e) + + +def eddies_tracking(): + parser = EddyParser("Tool to use identification step to compute tracking") + parser.add_argument("yaml_file", help="Yaml file to configure py-eddy-tracker") + parser.add_argument("--correspondance_in", help="Filename of saved correspondance") + parser.add_argument("--correspondance_out", help="Filename to save correspondance") + parser.add_argument( + "--save_correspondance_and_stop", + action="store_true", + help="Stop tracking after correspondance computation," + " merging can be done with EddyFinalTracking", + ) + parser.add_argument( + "--zarr", action="store_true", help="Output will be wrote in zarr" + ) + parser.add_argument("--unraw", action="store_true", help="Load unraw data") + parser.add_argument( + "--blank_period", + type=int, + default=0, + help="Nb of detection which will not use at the end of the period", + ) + parser.memory_arg() + args = parser.parse_args() + + # Read yaml configuration file + with open(args.yaml_file, "r") as stream: + config = safe_load(stream) + + if "CLASS" in config: + classname = config["CLASS"]["CLASS"] + obs_class = dict( + class_method=getattr( + __import__(config["CLASS"]["MODULE"], globals(), locals(), classname), + classname, + ), + class_kw=config["CLASS"].get("OPTIONS", dict()), + ) + else: + obs_class = dict() + + c_in, c_out = args.correspondance_in, args.correspondance_out + if c_in is None: + c_in = config["PATHS"].get("CORRESPONDANCES_IN", None) + y_c_out = config["PATHS"].get( + "CORRESPONDANCES_OUT", "{path}/{sign_type}_correspondances.nc" + ) + if c_out is None: + c_out = y_c_out + + # Create ouput folder if necessary + save_dir = config["PATHS"].get("SAVE_DIR", None) + if save_dir is not None and not exists(save_dir): + mkdir(save_dir) + + track( + pattern=config["PATHS"]["FILES_PATTERN"], + output_dir=save_dir, + c_out=c_out, + **obs_class, + virtual=int(config.get("VIRTUAL_LENGTH_MAX", 0)), + previous_correspondance=c_in, + memory=args.memory, + correspondances_only=args.save_correspondance_and_stop, + raw=not args.unraw, + zarr=args.zarr, + nb_obs_min=int(config.get("TRACK_DURATION_MIN", 10)), + blank_period=args.blank_period, + ) + + +def browse_dataset_in( + data_dir, + files_model, + date_regexp, + date_model, + start_date=None, + end_date=None, + sub_sampling_step=1, + files=None, +): + pattern_regexp = re_compile(".*/" + date_regexp) + if files is not None: + filenames = bytes_(files) + else: + full_path = join_path(data_dir, files_model) + logger.info("Search files : %s", full_path) + filenames = bytes_(glob(full_path)) + + dataset_list = empty( + len(filenames), + dtype=[ + ("filename", "S500"), + ("date", "datetime64[D]"), + ], + ) + dataset_list["filename"] = filenames + + logger.info("%s grids available", dataset_list.shape[0]) + mode_attrs = False + if "(" not in date_regexp: + logger.debug("Attrs date : %s", date_regexp) + mode_attrs = date_regexp.strip().split(":") + else: + logger.debug("Pattern date : %s", date_regexp) + + for item in dataset_list: + str_date = None + if mode_attrs: + with Dataset(item["filename"].decode("utf-8")) as h: + if len(mode_attrs) == 1: + str_date = getattr(h, mode_attrs[0]) + else: + str_date = getattr(h.variables[mode_attrs[0]], mode_attrs[1]) + else: + result = pattern_regexp.match(str(item["filename"])) + if result: + str_date = result.groups()[0] + + if str_date is not None: + item["date"] = datetime.strptime(str_date, date_model).date() + + dataset_list.sort(order=["date", "filename"]) + + steps = unique(dataset_list["date"][1:] - dataset_list["date"][:-1]) + if len(steps) > 1: + raise Exception("Several days steps in grid dataset %s" % steps) + + if sub_sampling_step != 1: + logger.info("Grid subsampling %d", sub_sampling_step) + dataset_list = dataset_list[::sub_sampling_step] + + if start_date is not None or end_date is not None: + logger.info( + "Available grid from %s to %s", + dataset_list[0]["date"], + dataset_list[-1]["date"], + ) + logger.info("Filtering grid by time %s, %s", start_date, end_date) + mask = (dataset_list["date"] >= start_date) * (dataset_list["date"] <= end_date) + + dataset_list = dataset_list[mask] + return dataset_list + + +def track( + pattern, + output_dir, + c_out, + nb_obs_min=10, + raw=True, + zarr=False, + blank_period=0, + correspondances_only=False, + **kw_c, +): + kw = dict(date_regexp=".*_([0-9]*?).[nz].*", date_model="%Y%m%d") + if isinstance(pattern, list): + kw.update(dict(data_dir=None, files_model=None, files=pattern)) + else: + kw.update(dict(data_dir=dirname(pattern), files_model=basename(pattern))) + datasets = browse_dataset_in(**kw) + if blank_period > 0: + datasets = datasets[:-blank_period] + logger.info("Last %d files will be pop", blank_period) + + if nb_obs_min > len(datasets): + raise Exception( + "Input file number (%s) is shorter than TRACK_DURATION_MIN (%s)." + % (len(datasets), nb_obs_min) + ) + + c = Correspondances(datasets=datasets["filename"], **kw_c) + c.track() + logger.info("Track finish") + t0, t1 = c.period + kw_save = dict( + date_start=t0, + date_stop=t1, + date_prod=datetime.now(), + path=output_dir, + sign_type=c.current_obs.sign_legend, + ) + + c.save(c_out, kw_save) + if correspondances_only: + return + + logger.info("Start merging") + c.prepare_merging() + logger.info("Longer track saved have %d obs", c.nb_obs_by_tracks.max()) + logger.info( + "The mean length is %d observations for all tracks", c.nb_obs_by_tracks.mean() + ) + + kw_write = dict(path=output_dir, zarr_flag=zarr) + + c.get_unused_data(raw_data=raw).write_file( + filename="%(path)s/%(sign_type)s_untracked.nc", **kw_write + ) + + short_c = c._copy() + short_c.shorter_than(size_max=nb_obs_min) + c.longer_than(size_min=nb_obs_min) + + long_track = c.merge(raw_data=raw) + short_track = short_c.merge(raw_data=raw) + + # We flag obs + if c.virtual: + long_track["virtual"][:] = long_track["time"] == 0 + long_track.filled_by_interpolation(long_track["virtual"] == 1) + short_track["virtual"][:] = short_track["time"] == 0 + short_track.filled_by_interpolation(short_track["virtual"] == 1) + + logger.info("Longer track saved have %d obs", c.nb_obs_by_tracks.max()) + logger.info( + "The mean length is %d observations for long track", + c.nb_obs_by_tracks.mean(), + ) + + long_track.write_file(**kw_write) + short_track.write_file( + filename="%(path)s/%(sign_type)s_track_too_short.nc", **kw_write + ) diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index c92f1d3d..dfdf6fbb 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -32,9 +32,16 @@ def build_network(): action="store_true", help="Use intern contour instead of outter contour", ) + + parser.memory_arg() args = parser.parse_args() - n = Network(args.identification_regex, window=args.window, intern=args.intern) + n = Network( + args.identification_regex, + window=args.window, + intern=args.intern, + memory=args.memory, + ) group = n.group_observations(minimal_area=True) n.build_dataset(group).write_file(filename=args.out) diff --git a/src/py_eddy_tracker/featured_tracking/area_tracker.py b/src/py_eddy_tracker/featured_tracking/area_tracker.py index 4abc0299..1b8a2dbb 100644 --- a/src/py_eddy_tracker/featured_tracking/area_tracker.py +++ b/src/py_eddy_tracker/featured_tracking/area_tracker.py @@ -1,6 +1,7 @@ import logging -from numpy import ma +from numba import njit +from numpy import empty, ma, ones from ..observations.observation import EddiesObservations as Model @@ -29,11 +30,8 @@ def needed_variable(cls): def tracking(self, other): shape = (self.shape[0], other.shape[0]) i, j, c = self.match(other, intern=False) - cost_mat = ma.empty(shape, dtype="f4") - cost_mat.mask = ma.ones(shape, dtype="bool") - m = c > self.cmin - i, j, c = i[m], j[m], c[m] - cost_mat[i, j] = 1 - c + cost_mat = ma.array(empty(shape, dtype="f4"), mask=ones(shape, dtype="bool")) + mask_cmin(i, j, c, self.cmin, cost_mat.data, cost_mat.mask) i_self, i_other = self.solve_function(cost_mat) i_self, i_other = self.post_process_link(other, i_self, i_other) @@ -55,3 +53,13 @@ def propagate( if nb_virtual_extend > 0: virtual[key][nb_dead:] = obs_to_extend[key] return virtual + + +@njit(cache=True) +def mask_cmin(i, j, c, cmin, cost_mat, mask): + for k in range(c.shape[0]): + c_ = c[k] + if c_ > cmin: + i_, j_ = i[k], j[k] + cost_mat[i_, j_] = 1 - c_ + mask[i_, j_] = False diff --git a/src/py_eddy_tracker/generic.py b/src/py_eddy_tracker/generic.py index a1da6b46..ce3bb787 100644 --- a/src/py_eddy_tracker/generic.py +++ b/src/py_eddy_tracker/generic.py @@ -83,7 +83,7 @@ def build_index(groups): first_index[group - i0 + 1 : next_group - i0 + 1] = i + 1 last_index = zeros(amplitude, dtype=numba_types.int_) last_index[:-1] = first_index[1:] - last_index[-1] = i + 2 + last_index[-1] = i + 1 return first_index, last_index, i0 diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 16577bf4..33fe6469 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -15,38 +15,81 @@ logger = logging.getLogger("pet") -class Network: - __slots__ = ("window", "filenames", "contour_name", "nb_input", "xname", "yname") - # To be used like a buffer +class Singleton(type): + _instances = {} + + def __call__(cls, *args, **kwargs): + if cls not in cls._instances: + cls._instances[cls] = super().__call__(*args, **kwargs) + return cls._instances[cls] + + +class Buffer(metaclass=Singleton): + __slots__ = ( + "buffersize", + "contour_name", + "xname", + "yname", + "memory", + ) DATA = dict() FLIST = list() - NOGROUP = TrackEddiesObservations.NOGROUP - def __init__(self, input_regex, window=5, intern=False): - self.window = window + def __init__(self, buffersize, intern=False, memory=False): + self.buffersize = buffersize self.contour_name = EddiesObservations.intern(intern, public_label=True) self.xname, self.yname = EddiesObservations.intern(intern) - self.filenames = glob(input_regex) - self.filenames.sort() - self.nb_input = len(self.filenames) + self.memory = memory def load_contour(self, filename): if filename not in self.DATA: - if len(self.FLIST) > self.window: + if len(self.FLIST) > self.buffersize: self.DATA.pop(self.FLIST.pop(0)) - e = EddiesObservations.load_file(filename, include_vars=self.contour_name) + if self.memory: + # Only if netcdf + with open(filename, "rb") as h: + e = EddiesObservations.load_file(h, include_vars=self.contour_name) + else: + e = EddiesObservations.load_file( + filename, include_vars=self.contour_name + ) + self.FLIST.append(filename) self.DATA[filename] = e[self.xname], e[self.yname] return self.DATA[filename] + +class Network: + __slots__ = ( + "window", + "filenames", + "nb_input", + "buffer", + "memory", + ) + + NOGROUP = TrackEddiesObservations.NOGROUP + + def __init__(self, input_regex, window=5, intern=False, memory=False): + """ + Class to group observations by network + """ + self.window = window + self.buffer = Buffer(window, intern, memory) + self.filenames = glob(input_regex) + self.filenames.sort() + self.nb_input = len(self.filenames) + self.memory = memory + def get_group_array(self, results, nb_obs): """With a loop on all pair of index, we will label each obs with a group number """ - nb_obs = array(nb_obs) + nb_obs = array(nb_obs, dtype="u4") day_start = nb_obs.cumsum() - nb_obs gr = empty(nb_obs.sum(), dtype="u4") gr[:] = self.NOGROUP + merge_id = list() id_free = 1 for i, j, ii, ij in results: gr_i = gr[slice(day_start[i], day_start[i] + nb_obs[i])] @@ -66,9 +109,14 @@ def get_group_array(self, results, nb_obs): if m.any(): # Merge of group, ref over etu for i_, j_ in zip(ii[m], ij[m]): - gr_i_, gr_j_ = gr_i[i_], gr_j[j_] - gr[gr == gr_i_] = gr_j_ - return gr + merge_id.append((gr_i[i_], gr_j[j_])) + + gr_transfer = arange(id_free, dtype="u4") + for i, j in merge_id: + gr_i, gr_j = gr_transfer[i], gr_transfer[j] + if gr_i != gr_j: + apply_replace(gr_transfer, gr_i, gr_j) + return gr_transfer[gr] def group_observations(self, **kwargs): results, nb_obs = list(), list() @@ -78,11 +126,11 @@ def group_observations(self, **kwargs): if display_iteration: print(f"{filename} compared to {self.window} next", end="\r") # Load observations with function to buffered observations - xi, yi = self.load_contour(filename) + xi, yi = self.buffer.load_contour(filename) # Append number of observations by filename nb_obs.append(xi.shape[0]) for j in range(i + 1, min(self.window + i + 1, self.nb_input)): - xj, yj = self.load_contour(self.filenames[j]) + xj, yj = self.buffer.load_contour(self.filenames[j]) ii, ij = bbox_intersection(xi, yi, xj, yj) m = vertice_overlap(xi[ii], yi[ii], xj[ij], yj[ij], **kwargs) > 0.2 results.append((i, j, ii[m], ij[m])) @@ -109,7 +157,12 @@ def build_dataset(self, group): for filename in self.filenames: if display_iteration: print(f"Load {filename} to copy", end="\r") - e = EddiesObservations.load_file(filename, raw_data=True) + if self.memory: + # Only if netcdf + with open(filename, "rb") as h: + e = EddiesObservations.load_file(h, raw_data=True) + else: + e = EddiesObservations.load_file(filename, raw_data=True) stop = i + len(e) sl = slice(i, stop) for element in elements: @@ -132,3 +185,11 @@ def get_next_index(gr): new_index[i] = i_gr[g] i_gr[g] += 1 return new_index + + +@njit(cache=True) +def apply_replace(x, x0, x1): + nb = x.shape[0] + for i in range(nb): + if x[i] == x0: + x[i] = x1 diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 23d6bf55..54383b47 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -33,6 +33,7 @@ isnan, linspace, ma, + nan, ndarray, ones, percentile, @@ -615,8 +616,12 @@ def load_file(cls, filename, **kwargs): ) if isinstance(filename, zarr.storage.MutableMapping): return cls.load_from_zarr(filename, **kwargs) - end = b".zarr" if isinstance(filename_, bytes) else ".zarr" - if filename_.endswith(end): + if isinstance(filename, (bytes, str)): + end = b".zarr" if isinstance(filename_, bytes) else ".zarr" + zarr_file = filename_.endswith(end) + else: + zarr_file = False + if zarr_file: return cls.load_from_zarr(filename, **kwargs) else: return cls.load_from_netcdf(filename, **kwargs) @@ -644,8 +649,8 @@ def load_from_zarr( :return: Obsevations selected :return type: class """ - # FIXME must be investigate, in zarr no dimensions name (or could be add in attr) - array_dim = 50 + # FIXME + array_dim = -1 if isinstance(filename, zarr.storage.MutableMapping): h_zarr = filename else: @@ -655,6 +660,10 @@ def load_from_zarr( var_list = cls.build_var_list(list(h_zarr.keys()), remove_vars, include_vars) nb_obs = getattr(h_zarr, var_list[0]).shape[0] + dims = list(cls.zarr_dimension(filename)) + if len(dims) == 2 and nb_obs in dims: + # FIXME must be investigate, in zarr no dimensions name (or could be add in attr) + array_dim = dims[1] if nb_obs == dims[0] else dims[0] if indexs is not None and "obs" in indexs: sl = indexs["obs"] sl = slice(sl.start, min(sl.stop, nb_obs)) @@ -667,7 +676,7 @@ def load_from_zarr( logger.warning("step of slice won't be use") logger.debug("%d observations will be load", nb_obs) kwargs = dict() - dims = cls.zarr_dimension(filename) + if array_dim in dims: kwargs["track_array_variables"] = array_dim kwargs["array_variables"] = list() @@ -1197,8 +1206,7 @@ def solve_simultaneous(cost): """Write something (TODO)""" mask = ~cost.mask # Count number of link by self obs and other obs - self_links = mask.sum(axis=1) - other_links = mask.sum(axis=0) + self_links, other_links = sum_row_column(mask) max_links = max(self_links.max(), other_links.max()) if max_links > 5: logger.warning("One observation have %d links", max_links) @@ -1299,7 +1307,7 @@ def solve_first(cost, multiple_link=False): return mask def solve_function(self, cost_matrix): - return where(self.solve_simultaneous(cost_matrix)) + return numba_where(self.solve_simultaneous(cost_matrix)) def post_process_link(self, other, i_self, i_other): if unique(i_other).shape[0] != i_other.shape[0]: @@ -1594,11 +1602,6 @@ def extract_with_mask(self, mask): :return: same object with selected observations :rtype: self """ - # ça n'existe plus ça?? - # full_path=False, - # remove_incomplete=False, - # compress_id=False, - # reject_virtual=False nb_obs = mask.sum() new = self.__class__.new_like(self, nb_obs) @@ -2228,7 +2231,6 @@ def grid_box_stat(x_c, y_c, grid, mask, x, y, value, circular=False, method=50): if i_ != i0 or j_ != j0: # apply method and store result grid[i_, j_] = percentile(values, method) - # grid[i_, j_] = len(values) mask[i_, j_] = False # start new group i0, j0 = i_, j_ @@ -2251,12 +2253,14 @@ def grid_stat(x_c, y_c, grid, x, y, result, circular=False, method="mean"): :param bool circular: True if grid is wrappable :param str method: 'mean', 'max' """ + # FIXME : how does it work on grid bound nb = result.shape[0] xstep, ystep = x_c[1] - x_c[0], y_c[1] - y_c[0] x0, y0 = x_c - xstep / 2.0, y_c - ystep / 2.0 nb_x = x_c.shape[0] max_method = "max" == method mean_method = "mean" == method + count_method = "count" == method for elt in range(nb): v = create_vertice(x[elt], y[elt]) (x_start, x_stop), (y_start, y_stop) = bbox_indice_regular( @@ -2264,11 +2268,18 @@ def grid_stat(x_c, y_c, grid, x, y, result, circular=False, method="mean"): ) i, j = get_pixel_in_regular(v, x_c, y_c, x_start, x_stop, y_start, y_stop) - if mean_method: + if count_method: + result[elt] = i.shape[0] + elif mean_method: v_sum = 0 for i_, j_ in zip(i, j): v_sum += grid[i_, j_] - result[elt] = v_sum / i.shape[0] + nb_ = i.shape[0] + # FIXME : how does it work on grid bound, + if nb_ == 0: + result[elt] = nan + else: + result[elt] = v_sum / nb_ elif max_method: v_max = -1e40 for i_, j_ in zip(i, j): @@ -2286,3 +2297,25 @@ def elements(self): elements = super().elements elements.extend(["track", "segment_size", "dlon", "dlat"]) return list(set(elements)) + + +@njit(cache=True) +def numba_where(mask): + """Usefull when mask is close to be empty""" + return where(mask) + + +@njit(cache=True) +def sum_row_column(mask): + """ + Compute sum on row and column at same time + """ + nb_x, nb_y = mask.shape + row_sum = zeros(nb_x, dtype=numba_types.int32) + column_sum = zeros(nb_y, dtype=numba_types.int32) + for i in range(nb_x): + for j in range(nb_y): + if mask[i, j]: + row_sum[i] += 1 + column_sum[j] += 1 + return row_sum, column_sum diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index eb601dca..4677e3bf 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -321,7 +321,7 @@ def bbox_intersection(x0, y0, x1, y1): continue i.append(i0) j.append(i1) - return array(i), array(j) + return array(i, dtype=numba_types.int32), array(j, dtype=numba_types.int32) @njit(cache=True) diff --git a/src/py_eddy_tracker/tracking.py b/src/py_eddy_tracker/tracking.py index ae0a2524..cba9985e 100644 --- a/src/py_eddy_tracker/tracking.py +++ b/src/py_eddy_tracker/tracking.py @@ -67,6 +67,7 @@ def __init__( class_method=None, class_kw=None, previous_correspondance=None, + memory=False, ): """Initiate tracking @@ -74,6 +75,7 @@ def __init__( :param class class_method: A class which tell how to track :param dict class_kw: keyword argument to setup class :param Correspondances previous_correspondance: A previous correspondance object if you want continue tracking + :param bool memory: identification file are load in memory before to be open with netcdf """ super().__init__() # Correspondance dtype @@ -88,6 +90,7 @@ def __init__( else: self.class_method = class_method self.class_kw = dict() if class_kw is None else class_kw + self.memory = memory # To count ID self.current_id = 0 @@ -171,7 +174,11 @@ def swap_dataset(self, dataset, *args, **kwargs): self.previous_obs = self.current_obs kwargs = kwargs.copy() kwargs.update(self.class_kw) - self.current_obs = self.class_method.load_file(dataset, *args, **kwargs) + if self.memory: + with open(dataset, "rb") as h: + self.current_obs = self.class_method.load_file(h, *args, **kwargs) + else: + self.current_obs = self.class_method.load_file(dataset, *args, **kwargs) def merge_correspondance(self, other): # Verify compliance of file @@ -712,53 +719,29 @@ def get_unused_data(self, raw_data=False): Returns: Unused Eddies """ - self.reset_dataset_cache() - self.swap_dataset(self.datasets[0], raw_data=raw_data) - nb_dataset = len(self.datasets) - # Get the number of obs unused - nb_obs = 0 - list_mask = list() has_virtual = "virtual" in self[0].dtype.names - logger.debug("Count unused data ...") - for i, filename in enumerate(self.datasets): + eddies = list() + for i, dataset in enumerate(self.datasets): last_dataset = i == (nb_dataset - 1) if has_virtual and not last_dataset: m_in = ~self[i]["virtual"] else: m_in = slice(None) if i == 0: - eddies_used = self[i]["in"] + index_used = self[i]["in"] elif last_dataset: - eddies_used = self[i - 1]["out"] + index_used = self[i - 1]["out"] else: - eddies_used = unique( + index_used = unique( concatenate((self[i - 1]["out"], self[i]["in"][m_in])) ) - if not isinstance(filename, str): - filename = filename.astype(str) - with Dataset(filename) as h: - nb_obs_day = len(h.dimensions["obs"]) - m = ones(nb_obs_day, dtype="bool") - m[eddies_used] = False - list_mask.append(m) - nb_obs += m.sum() - logger.debug("Count unused data OK") - eddies = EddiesObservations( - size=nb_obs, - track_extra_variables=self.current_obs.track_extra_variables, - track_array_variables=self.current_obs.track_array_variables, - array_variables=self.current_obs.array_variables, - raw_data=raw_data, - ) - j = 0 - for i, dataset in enumerate(self.datasets): - logger.debug("Loaf file : (%d) %s", i, dataset) - current_obs = self.class_method.load_file(dataset, raw_data=raw_data) - if i == 0: - eddies.sign_type = current_obs.sign_type - unused_obs = current_obs.obs[list_mask[i]] - nb = unused_obs.shape[0] - eddies.obs[j : j + nb] = unused_obs - j += nb - return eddies + + logger.debug("Load file : %s", dataset) + if self.memory: + with open(dataset, "rb") as h: + current_obs = self.class_method.load_file(h, raw_data=raw_data) + else: + current_obs = self.class_method.load_file(dataset, raw_data=raw_data) + eddies.append(current_obs.index(index_used, reverse=True)) + return EddiesObservations.concatenate(eddies) diff --git a/src/scripts/EddyTracking b/src/scripts/EddyTracking deleted file mode 100644 index 28c946fa..00000000 --- a/src/scripts/EddyTracking +++ /dev/null @@ -1,274 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" -Track eddy with Identification file produce with EddyIdentification -""" -import logging -from datetime import datetime -from glob import glob -from os import mkdir -from os.path import basename, dirname, exists -from os.path import join as join_path -from re import compile as re_compile - -from netCDF4 import Dataset -from numpy import bytes_, empty, unique -from yaml import load as yaml_load - -from py_eddy_tracker import EddyParser -from py_eddy_tracker.tracking import Correspondances - -logger = logging.getLogger("pet") - - -def browse_dataset_in( - data_dir, - files_model, - date_regexp, - date_model, - start_date=None, - end_date=None, - sub_sampling_step=1, - files=None, -): - pattern_regexp = re_compile(".*/" + date_regexp) - if files is not None: - filenames = bytes_(files) - else: - full_path = join_path(data_dir, files_model) - logger.info("Search files : %s", full_path) - filenames = bytes_(glob(full_path)) - - dataset_list = empty( - len(filenames), dtype=[("filename", "S500"), ("date", "datetime64[D]"),] - ) - dataset_list["filename"] = filenames - - logger.info("%s grids available", dataset_list.shape[0]) - mode_attrs = False - if "(" not in date_regexp: - logger.debug("Attrs date : %s", date_regexp) - mode_attrs = date_regexp.strip().split(":") - else: - logger.debug("Pattern date : %s", date_regexp) - - for item in dataset_list: - str_date = None - if mode_attrs: - with Dataset(item["filename"].decode("utf-8")) as h: - if len(mode_attrs) == 1: - str_date = getattr(h, mode_attrs[0]) - else: - str_date = getattr(h.variables[mode_attrs[0]], mode_attrs[1]) - else: - result = pattern_regexp.match(str(item["filename"])) - if result: - str_date = result.groups()[0] - - if str_date is not None: - item["date"] = datetime.strptime(str_date, date_model).date() - - dataset_list.sort(order=["date", "filename"]) - - steps = unique(dataset_list["date"][1:] - dataset_list["date"][:-1]) - if len(steps) > 1: - raise Exception("Several days steps in grid dataset %s" % steps) - - if sub_sampling_step != 1: - logger.info("Grid subsampling %d", sub_sampling_step) - dataset_list = dataset_list[::sub_sampling_step] - - if start_date is not None or end_date is not None: - logger.info( - "Available grid from %s to %s", - dataset_list[0]["date"], - dataset_list[-1]["date"], - ) - logger.info("Filtering grid by time %s, %s", start_date, end_date) - mask = (dataset_list["date"] >= start_date) * (dataset_list["date"] <= end_date) - - dataset_list = dataset_list[mask] - return dataset_list - - -def usage(): - """Usage - """ - # Run using: - parser = EddyParser("Tool to use identification step to compute tracking") - parser.add_argument("yaml_file", help="Yaml file to configure py-eddy-tracker") - parser.add_argument("--correspondance_in", help="Filename of saved correspondance") - parser.add_argument("--correspondance_out", help="Filename to save correspondance") - parser.add_argument( - "--save_correspondance_and_stop", - action="store_true", - help="Stop tracking after correspondance computation," - " merging can be done with EddyFinalTracking", - ) - parser.add_argument( - "--zarr", action="store_true", help="Output will be wrote in zarr" - ) - parser.add_argument("--unraw", action="store_true", help="Load unraw data") - parser.add_argument( - "--blank_period", - type=int, - default=0, - help="Nb of detection which will not use at the end of the period", - ) - args = parser.parse_args() - - # Read yaml configuration file - with open(args.yaml_file, "r") as stream: - config = yaml_load(stream) - if args.correspondance_in is not None and not exists(args.correspondance_in): - args.correspondance_in = None - return ( - config, - args.save_correspondance_and_stop, - args.correspondance_in, - args.correspondance_out, - args.blank_period, - args.zarr, - not args.unraw, - ) - - -if __name__ == "__main__": - ( - CONFIG, - SAVE_STOP, - CORRESPONDANCES_IN, - CORRESPONDANCES_OUT, - BLANK_PERIOD, - ZARR, - RAW, - ) = usage() - # Create output directory - SAVE_DIR = CONFIG["PATHS"].get("SAVE_DIR", None) - if SAVE_DIR is not None and not exists(SAVE_DIR): - mkdir(SAVE_DIR) - - YAML_CORRESPONDANCES_OUT = CONFIG["PATHS"].get("CORRESPONDANCES_OUT", None) - if CORRESPONDANCES_IN is None: - CORRESPONDANCES_IN = CONFIG["PATHS"].get("CORRESPONDANCES_IN", None) - if CORRESPONDANCES_OUT is None: - CORRESPONDANCES_OUT = YAML_CORRESPONDANCES_OUT - if YAML_CORRESPONDANCES_OUT is None and CORRESPONDANCES_OUT is None: - CORRESPONDANCES_OUT = "{path}/{sign_type}_correspondances.nc" - - CLASS = None - CLASS_KW = dict() - if "CLASS" in CONFIG: - CLASSNAME = CONFIG["CLASS"]["CLASS"] - CLASS = getattr( - __import__(CONFIG["CLASS"]["MODULE"], globals(), locals(), CLASSNAME), - CLASSNAME, - ) - CLASS_KW = CONFIG["CLASS"].get("OPTIONS", dict()) - - NB_VIRTUAL_OBS_MAX_BY_SEGMENT = int(CONFIG.get("VIRTUAL_LENGTH_MAX", 0)) - - if isinstance(CONFIG["PATHS"]["FILES_PATTERN"], list): - DATASET_LIST = browse_dataset_in( - data_dir=None, - files_model=None, - files=CONFIG["PATHS"]["FILES_PATTERN"], - date_regexp=".*_([0-9]*?).[nz].*", - date_model="%Y%m%d", - ) - else: - DATASET_LIST = browse_dataset_in( - data_dir=dirname(CONFIG["PATHS"]["FILES_PATTERN"]), - files_model=basename(CONFIG["PATHS"]["FILES_PATTERN"]), - date_regexp=".*_([0-9]*?).[nz].*", - date_model="%Y%m%d", - ) - - if BLANK_PERIOD > 0: - DATASET_LIST = DATASET_LIST[:-BLANK_PERIOD] - logger.info("Last %d files will be pop", BLANK_PERIOD) - - START_TIME = datetime.now() - logger.info("Start tracking on %d files", len(DATASET_LIST)) - - NB_OBS_MIN = int(CONFIG.get("TRACK_DURATION_MIN", 14)) - if NB_OBS_MIN > len(DATASET_LIST): - raise Exception( - "Input file number (%s) is shorter than TRACK_DURATION_MIN (%s)." - % (len(DATASET_LIST), NB_OBS_MIN) - ) - - CORRESPONDANCES = Correspondances( - datasets=DATASET_LIST["filename"], - virtual=NB_VIRTUAL_OBS_MAX_BY_SEGMENT, - class_method=CLASS, - class_kw=CLASS_KW, - previous_correspondance=CORRESPONDANCES_IN, - ) - CORRESPONDANCES.track() - logger.info("Track finish") - - logger.info("Start merging") - DATE_START, DATE_STOP = CORRESPONDANCES.period - DICT_COMPLETION = dict( - date_start=DATE_START, - date_stop=DATE_STOP, - date_prod=START_TIME, - path=SAVE_DIR, - sign_type=CORRESPONDANCES.current_obs.sign_legend, - ) - - CORRESPONDANCES.save(CORRESPONDANCES_OUT, DICT_COMPLETION) - if SAVE_STOP: - exit() - - # Merge correspondance, only do if we stop and store just after compute of correspondance - CORRESPONDANCES.prepare_merging() - - logger.info( - "Longer track saved have %d obs", CORRESPONDANCES.nb_obs_by_tracks.max() - ) - logger.info( - "The mean length is %d observations before filtering", - CORRESPONDANCES.nb_obs_by_tracks.mean(), - ) - - CORRESPONDANCES.get_unused_data(raw_data=RAW).write_file( - path=SAVE_DIR, filename="%(path)s/%(sign_type)s_untracked.nc", zarr_flag=ZARR - ) - - SHORT_CORRESPONDANCES = CORRESPONDANCES._copy() - SHORT_CORRESPONDANCES.shorter_than(size_max=NB_OBS_MIN) - - CORRESPONDANCES.longer_than(size_min=NB_OBS_MIN) - - FINAL_EDDIES = CORRESPONDANCES.merge(raw_data=RAW) - SHORT_TRACK = SHORT_CORRESPONDANCES.merge(raw_data=RAW) - - # We flag obs - if CORRESPONDANCES.virtual: - FINAL_EDDIES["virtual"][:] = FINAL_EDDIES["time"] == 0 - FINAL_EDDIES.filled_by_interpolation(FINAL_EDDIES["virtual"] == 1) - SHORT_TRACK["virtual"][:] = SHORT_TRACK["time"] == 0 - SHORT_TRACK.filled_by_interpolation(SHORT_TRACK["virtual"] == 1) - - # Total running time - FULL_TIME = datetime.now() - START_TIME - logger.info("Mean duration by loop : %s", FULL_TIME / (len(DATASET_LIST) - 1)) - logger.info("Duration : %s", FULL_TIME) - - logger.info( - "Longer track saved have %d obs", CORRESPONDANCES.nb_obs_by_tracks.max() - ) - logger.info( - "The mean length is %d observations after filtering", - CORRESPONDANCES.nb_obs_by_tracks.mean(), - ) - - FINAL_EDDIES.write_file(path=SAVE_DIR, zarr_flag=ZARR) - SHORT_TRACK.write_file( - filename="%(path)s/%(sign_type)s_track_too_short.nc", - path=SAVE_DIR, - zarr_flag=ZARR, - ) - From 5cbc1165b3e2ac469763e72d1e4018982bce7bfd Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 5 Jan 2021 14:34:33 +0100 Subject: [PATCH 007/249] add a intern option in common parser --- src/py_eddy_tracker/__init__.py | 7 +++++++ src/py_eddy_tracker/appli/eddies.py | 6 +----- src/py_eddy_tracker/appli/gui.py | 6 +----- src/py_eddy_tracker/appli/network.py | 12 ++---------- 4 files changed, 11 insertions(+), 20 deletions(-) diff --git a/src/py_eddy_tracker/__init__.py b/src/py_eddy_tracker/__init__.py index 1fa57c7e..d184d551 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -92,6 +92,13 @@ def memory_arg(self): help="Load file in memory before to read with netCDF library", ) + def contour_intern_arg(self): + self.add_argument( + "--intern", + action="store_true", + help="Use intern contour instead of outter contour", + ) + def parse_args(self, *args, **kwargs): logger = start_logger() # Parsing diff --git a/src/py_eddy_tracker/appli/eddies.py b/src/py_eddy_tracker/appli/eddies.py index 2f78510f..245a176f 100644 --- a/src/py_eddy_tracker/appli/eddies.py +++ b/src/py_eddy_tracker/appli/eddies.py @@ -76,11 +76,7 @@ def get_frequency_grid(): parser = EddyParser("Compute eddy frequency") parser.add_argument("observations", help="Input observations to compute frequency") parser.add_argument("out", help="Grid output file") - parser.add_argument( - "--intern", - help="Use speed contour instead of effective contour", - action="store_true", - ) + parser.contour_intern_arg() parser.add_argument( "--xrange", nargs="+", type=float, help="Horizontal range : START,STOP,STEP" ) diff --git a/src/py_eddy_tracker/appli/gui.py b/src/py_eddy_tracker/appli/gui.py index ec843400..01009437 100644 --- a/src/py_eddy_tracker/appli/gui.py +++ b/src/py_eddy_tracker/appli/gui.py @@ -177,11 +177,7 @@ def anim(): ) parser.add_argument("filename", help="eddy atlas") parser.add_argument("id", help="Track id to anim", type=int, nargs="*") - parser.add_argument( - "--intern", - action="store_true", - help="display intern contour inplace of outter contour", - ) + parser.contour_intern_arg() parser.add_argument( "--keep_step", default=25, help="number maximal of step displayed", type=int ) diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index dfdf6fbb..aa560624 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -27,11 +27,7 @@ def build_network(): parser.add_argument( "--window", "-w", type=int, help="Half time window to search eddy", default=1 ) - parser.add_argument( - "--intern", - action="store_true", - help="Use intern contour instead of outter contour", - ) + parser.contour_intern_arg() parser.memory_arg() args = parser.parse_args() @@ -50,11 +46,7 @@ def divide_network(): parser = EddyParser("Separate path for a same group") parser.add_argument("input", help="input network file") parser.add_argument("out", help="output file") - parser.add_argument( - "--intern", - action="store_true", - help="Use intern contour instead of outter contour", - ) + parser.contour_intern_arg() parser.add_argument( "--window", "-w", type=int, help="Half time window to search eddy", default=1 ) From a1515bdb1dfd7ea9466b2692a45b50948b751705 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 5 Jan 2021 15:45:56 +0100 Subject: [PATCH 008/249] Add a low pass filter option to remove noisy data to answer at #42 --- CHANGELOG.rst | 10 +++++++++ src/py_eddy_tracker/appli/grid.py | 34 +++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 72b204c1..249ab401 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -9,6 +9,16 @@ and this project adheres to `Semantic Versioning 2 or nb_cw == 0: + raise Exception("You must specify 1 or 2 values for cut wavelength.") + elif nb_cw == 1: + cut_wavelength = [0, *cut_wavelength] + inf_bnds, upper_bnds = cut_wavelength + date = datetime.strptime(args.datetime, "%Y%m%d") kwargs = dict( step=args.isoline_step, @@ -109,7 +126,9 @@ def eddy_id(args=None): pixel_limit=(5, 2000), force_height_unit=args.height_unit, force_speed_unit=args.speed_unit, + nb_step_to_be_mle=0, ) + a, c = identification( args.filename, args.longitude, @@ -119,7 +138,9 @@ def eddy_id(args=None): args.u, args.v, unregular=args.unregular, - cut_wavelength=args.cut_wavelength, + cut_wavelength=upper_bnds, + cut_highwavelength=inf_bnds, + lat_max=args.lat_max, filter_order=args.filter_order, indexs=args.indexs, sampling=args.sampling, @@ -141,6 +162,8 @@ def identification( v="None", unregular=False, cut_wavelength=500, + cut_highwavelength=0, + lat_max=85, filter_order=1, indexs=None, **kwargs @@ -150,6 +173,9 @@ def identification( if u == "None" and v == "None": grid.add_uv(h) u, v = "u", "v" + kw_filter = dict(order=filter_order, lat_max=lat_max) + if cut_highwavelength != 0: + grid.bessel_low_filter(h, cut_highwavelength, **kw_filter) if cut_wavelength != 0: - grid.bessel_high_filter(h, cut_wavelength, order=filter_order) + grid.bessel_high_filter(h, cut_wavelength, **kw_filter) return grid.eddy_identification(h, u, v, date, **kwargs) From bc44b6596b38adf858f3833a3942499f984e4936 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 5 Jan 2021 15:48:32 +0100 Subject: [PATCH 009/249] Add a tools to get an easy comparison between several identification datasets --- CHANGELOG.rst | 1 + setup.py | 1 + src/py_eddy_tracker/appli/eddies.py | 138 +++++++++++++++++++++++++++- 3 files changed, 138 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 249ab401..256aed80 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -18,6 +18,7 @@ Added - Identification file could be load in memory before to be read with netcdf library to get speed up in case of slow disk - Add a filter option in EddyId to be able to remove fine scale (like noise) with same filter order than high scale filter +- Add **EddyQuickCompare** to have few figures about several datasets in comparison based on match function [3.3.0] - 2020-12-03 -------------------- diff --git a/setup.py b/setup.py index 366ab160..497ec90b 100644 --- a/setup.py +++ b/setup.py @@ -43,6 +43,7 @@ "EddyInfos = py_eddy_tracker.appli.eddies:display_infos", "EddyCircle = py_eddy_tracker.appli.eddies:eddies_add_circle", "EddyTracking = py_eddy_tracker.appli.eddies:eddies_tracking", + "EddyQuickCompare = py_eddy_tracker.appli.eddies:quick_compare", # network "EddyNetworkGroup = py_eddy_tracker.appli.network:build_network", "EddyNetworkBuildPath = py_eddy_tracker.appli.network:divide_network", diff --git a/src/py_eddy_tracker/appli/eddies.py b/src/py_eddy_tracker/appli/eddies.py index 245a176f..23243165 100644 --- a/src/py_eddy_tracker/appli/eddies.py +++ b/src/py_eddy_tracker/appli/eddies.py @@ -12,11 +12,11 @@ from re import compile as re_compile from netCDF4 import Dataset -from numpy import bytes_, empty, unique +from numpy import bincount, bytes_, empty, in1d, unique from yaml import safe_load from .. import EddyParser -from ..observations.observation import EddiesObservations +from ..observations.observation import EddiesObservations, reverse_index from ..observations.tracking import TrackEddiesObservations from ..tracking import Correspondances @@ -373,3 +373,137 @@ def track( short_track.write_file( filename="%(path)s/%(sign_type)s_track_too_short.nc", **kw_write ) + + +def get_group( + dataset1, + dataset2, + index1, + index2, + score, + invalid=2, + low=10, + high=60, +): + group1, group2 = dict(), dict() + m_valid = (score * 100) >= invalid + i1, i2, score = index1[m_valid], index2[m_valid], score[m_valid] * 100 + # Eddies with no association & scores < invalid + group1["nomatch"] = reverse_index(i1, len(dataset1)) + group2["nomatch"] = reverse_index(i2, len(dataset2)) + # Select all eddies involved in multiple associations + i1_, nb1 = unique(i1, return_counts=True) + i2_, nb2 = unique(i2, return_counts=True) + i1_multi = i1_[nb1 >= 2] + i2_multi = i2_[nb2 >= 2] + m_multi = in1d(i1, i1_multi) + in1d(i2, i2_multi) + group1["multi_match"] = unique(i1[m_multi]) + group2["multi_match"] = unique(i2[m_multi]) + + # Low scores + m_low = score <= low + m_low *= ~m_multi + group1["low"] = i1[m_low] + group2["low"] = i2[m_low] + # Intermediate scores + m_i = (score > low) * (score <= high) + m_i *= ~m_multi + group1["intermediate"] = i1[m_i] + group2["intermediate"] = i2[m_i] + # High scores + m_high = score > high + m_high *= ~m_multi + group1["high"] = i1[m_high] + group2["high"] = i2[m_high] + + def get_twin(j2, j1): + # True only if j1 is used only one + m = bincount(j1)[j1] == 1 + # We keep only link of this mask j1 have exactly one parent + j2_ = j2[m] + # We count parent times + m_ = (bincount(j2_)[j2_] == 2) * (bincount(j2)[j2_] == 2) + # we fill first mask with second one + m[m] = m_ + return m + + m1 = get_twin(i1, i2) + m2 = get_twin(i2, i1) + group1["parent"] = unique(i1[m1]) + group2["parent"] = unique(i2[m2]) + group1["twin"] = i1[m2] + group2["twin"] = i2[m1] + + m = ~m1 * ~m2 * m_multi + group1["complex"] = unique(i1[m]) + group2["complex"] = unique(i2[m]) + + return group1, group2 + + +def quick_compare(): + parser = EddyParser( + "Tool to have a quick comparison between several identification" + ) + parser.add_argument("ref", help="Identification file of reference") + parser.add_argument("others", nargs="+", help="Identifications files to compare") + parser.add_argument("--high", default=40, type=float) + parser.add_argument("--low", default=20, type=float) + parser.add_argument("--invalid", default=5, type=float) + parser.contour_intern_arg() + args = parser.parse_args() + + kw = dict( + include_vars=[ + "longitude", + *EddiesObservations.intern(args.intern, public_label=True), + ] + ) + + ref = EddiesObservations.load_file(args.ref, **kw) + print(f"[ref] {args.ref} -> {len(ref)} obs") + groups_ref, groups_other = dict(), dict() + others = {other: EddiesObservations.load_file(other, **kw) for other in args.others} + for i, other_ in enumerate(args.others): + other = others[other_] + print(f"[{i}] {other_} -> {len(other)} obs") + gr1, gr2 = get_group( + ref, + other, + *ref.match(other, intern=args.intern), + invalid=args.invalid, + low=args.low, + high=args.high, + ) + groups_ref[other_] = gr1 + groups_other[other_] = gr2 + + def display(value, ref=None): + outs = list() + for v in value: + if ref: + outs.append(f"{v/ref * 100:.1f}% ({v})") + else: + outs.append(v) + return "".join([f"{v:^15}" for v in outs]) + + keys = list(gr1.keys()) + print(" ", display(keys)) + for i, v in enumerate(groups_ref.values()): + print( + f"[{i:2}] ", + display( + (v_.sum() if v_.dtype == "bool" else v_.shape[0] for v_ in v.values()), + ref=len(ref), + ), + ) + + print(display(keys)) + for i, (k, v) in enumerate(groups_other.items()): + print( + f"[{i:2}] ", + display( + (v_.sum() if v_.dtype == "bool" else v_.shape[0] for v_ in v.values()), + ref=len(others[k]), + ), + ) From d123d37c56beb2c63a745e640cb2153273a74088 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Mon, 11 Jan 2021 14:20:46 +0100 Subject: [PATCH 010/249] modification of network cost function --- src/py_eddy_tracker/observations/tracking.py | 48 +++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index c67d130a..b80097a4 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -626,27 +626,6 @@ def split_network(self, intern=True, **kwargs): m = local_ids["next_obs"] == -1 local_ids["next_obs"][m] += i_s return ids - # ids_sort = ids[new_i] - # # To be able to follow indices sorting - # reverse_sort = empty(new_i.shape[0], dtype="u4") - # reverse_sort[new_i] = arange(new_i.shape[0]) - # # Redirect indices - # m = ids_sort["next_obs"] != -1 - # ids_sort["next_obs"][m] = reverse_sort[ - # ids_sort["next_obs"][m] - # ] - # m = ids_sort["previous_obs"] != -1 - # ids_sort["previous_obs"][m] = reverse_sort[ - # ids_sort["previous_obs"][m] - # ] - # # print(ids_sort) - # display_network( - # x[new_i], - # y[new_i], - # ids_sort["track"], - # ids_sort["time"], - # ids_sort["next_cost"], - # ) def set_tracks(self, x, y, ids, window): """ @@ -670,6 +649,8 @@ def set_tracks(self, x, y, ids, window): continue self.follow_obs(i, track_id, used, ids, polygons, *time_index, window) track_id += 1 + # Search a possible ancestor + self.previous_obs(i, ids, polygons, *time_index, window) @classmethod def follow_obs(cls, i_next, track_id, used, ids, *args): @@ -694,6 +675,29 @@ def follow_obs(cls, i_next, track_id, used, ids, *args): ids["previous_obs"][i_next_] = i_next i_next = i_next_ + @staticmethod + def previous_obs(i_current, ids, polygons, time_s, time_e, time_ref, window): + time_cur = ids["time"][i_current] + t0, t1 = time_cur - 1 - time_ref, max(time_cur - window - time_ref, 0) + for t_step in range(t0, t1 - 1, -1): + i0, i1 = time_s[t_step], time_e[t_step] + # No observation at the time step + if i0 == i1: + continue + # Intersection / union, to be able to separte in case of multiple inside + c = polygon_overlap(polygons[i_current], polygons[i0:i1], minimal_area=True) + # We remove low overlap + c[c < 0.1] = 0 + # We get index of maximal overlap + i = c.argmax() + c_i = c[i] + # No overlap found + if c_i == 0: + continue + ids["previous_cost"][i_current] = c_i + ids["previous_obs"][i_current] = i0 + i + break + @staticmethod def next_obs(i_current, ids, polygons, time_s, time_e, time_ref, window): time_max = time_e.shape[0] - 1 @@ -707,7 +711,7 @@ def next_obs(i_current, ids, polygons, time_s, time_e, time_ref, window): if i0 == i1: continue # Intersection / union, to be able to separte in case of multiple inside - c = polygon_overlap(polygons[i_current], polygons[i0:i1]) + c = polygon_overlap(polygons[i_current], polygons[i0:i1], minimal_area=True) # We remove low overlap c[c < 0.1] = 0 # We get index of maximal overlap From 2c78c226252c2354d6203093cd569da48f11e05d Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Mon, 11 Jan 2021 14:22:12 +0100 Subject: [PATCH 011/249] - Allow to hide path in GUIEddy - Iter obs on intern field or outter array --- src/py_eddy_tracker/appli/gui.py | 17 ++++++++++++++++- src/py_eddy_tracker/appli/network.py | 6 +++--- src/py_eddy_tracker/dataset/grid.py | 3 +++ src/py_eddy_tracker/gui.py | 5 +++++ src/py_eddy_tracker/observations/observation.py | 6 +++--- 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/py_eddy_tracker/appli/gui.py b/src/py_eddy_tracker/appli/gui.py index 01009437..a5b58b30 100644 --- a/src/py_eddy_tracker/appli/gui.py +++ b/src/py_eddy_tracker/appli/gui.py @@ -44,7 +44,7 @@ def setup(self, cmap="jet", nb_step=25, figsize=(8, 6), **kwargs): self.fig = pyplot.figure(figsize=figsize, **kwargs) t0, t1 = self.period self.fig.suptitle(f"{t0} -> {t1}") - self.ax = self.fig.add_axes((0.05, 0.05, 0.9, 0.9)) + self.ax = self.fig.add_axes((0.05, 0.05, 0.9, 0.9), projection="full_axes") self.ax.set_xlim(x_min, x_max), self.ax.set_ylim(y_min, y_max) self.ax.set_aspect("equal") self.ax.grid() @@ -192,6 +192,11 @@ def anim(): parser.add_argument( "--infinity_loop", action="store_true", help="Press Escape key to stop loop" ) + parser.add_argument( + "--first_centered", + action="store_true", + help="Longitude will be centered on first obs, if there are only one group.", + ) args = parser.parse_args() variables = ["time", "track", "longitude", "latitude"] variables.extend(TrackEddiesObservations.intern(args.intern, public_label=True)) @@ -203,6 +208,14 @@ def anim(): "You need to specify id to display or ask explicity all with --all option" ) eddies = eddies.extract_ids(args.id) + if args.first_centered: + # TODO: include observatin class + x0 = eddies.lon[0] + eddies.lon[:] = (eddies.lon - x0 + 180) % 360 + x0 - 180 + eddies.contour_lon_e[:] = ( + (eddies.contour_lon_e.T - eddies.lon + 180) % 360 + eddies.lon - 180 + ).T + a = Anim( eddies, intern=args.intern, @@ -217,6 +230,7 @@ def gui_parser(): parser = EddyParser("Eddy atlas GUI") parser.add_argument("atlas", nargs="+") parser.add_argument("--med", action="store_true") + parser.add_argument("--nopath", action="store_true", help="Don't draw path") return parser.parse_args() @@ -228,4 +242,5 @@ def guieddy(): g = GUI(**atlas) if args.med: g.med() + g.hide_path(not args.nopath) g.show() diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index aa560624..4eef0942 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -53,10 +53,10 @@ def divide_network(): args = parser.parse_args() contour_name = TrackEddiesObservations.intern(args.intern, public_label=True) e = TrackEddiesObservations.load_file( - args.input, include_vars=("time", "track", *contour_name) + args.input, + include_vars=("time", "track", "latitude", "longitude", *contour_name), ) - e.split_network(intern=args.intern, window=args.window) - # split_network(args.input, args.out) + ids = e.split_network(intern=args.intern, window=args.window) def split_network(input, output): diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 52f8201c..e07e32a0 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -1163,6 +1163,9 @@ def setup_coordinates(self): @classmethod def with_array(cls, coordinates, datas, variables_description=None, **kwargs): + """ + Geo matrix data must be ordered like this (X,Y) and masked with numpy.ma.array + """ vd = dict() if variables_description is None else variables_description x_name, y_name = coordinates[0], coordinates[1] obj = cls("array", x_name, y_name, unset=True, **kwargs) diff --git a/src/py_eddy_tracker/gui.py b/src/py_eddy_tracker/gui.py index 1485c08c..423ff306 100644 --- a/src/py_eddy_tracker/gui.py +++ b/src/py_eddy_tracker/gui.py @@ -146,6 +146,11 @@ def setup(self): # param self.param_ax = self.figure.add_axes((0, 0, 1, 0.15), facecolor="0.2") + def hide_path(self, state): + for name in self.datasets: + self.m[name]["path_previous"].set_visible(state) + self.m[name]["path_future"].set_visible(state) + def draw(self): self.m["mini_ax"] = self.figure.add_axes((0.3, 0.85, 0.4, 0.15), zorder=80) self.m["mini_ax"].grid() diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 54383b47..ee9301d0 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -456,16 +456,16 @@ def __iter__(self): for obs in self.obs: yield obs - def iter_on(self, xname: str, bins=None): + def iter_on(self, xname, bins=None): """ Yield observation group for each bin. - :param str xname: + :param str,array xname: :param array bins: bounds of each bin , :return: Group observations :rtype: self.__class__ """ - x = self[xname] + x = self[xname] if isinstance(xname, str) else xname d = x[1:] - x[:-1] if bins is None: bins = arange(x.min(), x.max() + 2) From 25df7b613820b59e28df9abe092ee1c6db306ea9 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 12 Jan 2021 15:03:05 +0100 Subject: [PATCH 012/249] Use last obs of network, manage wrapping of network around 0 --- .../12_external_data/pet_SST_collocation.py | 6 +- src/py_eddy_tracker/appli/network.py | 252 +----------------- src/py_eddy_tracker/generic.py | 3 +- src/py_eddy_tracker/observations/tracking.py | 26 +- 4 files changed, 25 insertions(+), 262 deletions(-) diff --git a/examples/12_external_data/pet_SST_collocation.py b/examples/12_external_data/pet_SST_collocation.py index e6337754..0855f631 100644 --- a/examples/12_external_data/pet_SST_collocation.py +++ b/examples/12_external_data/pet_SST_collocation.py @@ -27,7 +27,7 @@ # %% # 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" @@ -58,14 +58,14 @@ def update_axes(ax, mappable=None, unit=""): # %% # 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` diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index 4eef0942..c692262e 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -5,15 +5,9 @@ import logging -from netCDF4 import Dataset -from numpy import arange, empty, zeros -from Polygon import Polygon - from .. import EddyParser -from ..generic import build_index from ..observations.network import Network from ..observations.tracking import TrackEddiesObservations -from ..poly import create_vertice_from_2darray, polygon_overlap logger = logging.getLogger("pet") @@ -57,246 +51,6 @@ def divide_network(): include_vars=("time", "track", "latitude", "longitude", *contour_name), ) ids = e.split_network(intern=args.intern, window=args.window) - - -def split_network(input, output): - """Divide each group in track""" - sl = slice(None) - with Dataset(input) as h: - group = h.variables["track"][sl] - track_s, track_e, track_ref = build_index(group) - # nb = track_e - track_s - # m = nb > 1500 - # print(group[track_s[m]]) - - track_id = 12003 - sls = [slice(track_s[track_id - track_ref], track_e[track_id - track_ref], None)] - for sl in sls: - - print(sl) - with Dataset(input) as h: - time = h.variables["time"][sl] - group = h.variables["track"][sl] - x = h.variables["effective_contour_longitude"][sl] - y = h.variables["effective_contour_latitude"][sl] - print(group[0]) - ids = empty( - time.shape, - dtype=[ - ("group", group.dtype), - ("time", time.dtype), - ("track", "u2"), - ("previous_cost", "f4"), - ("next_cost", "f4"), - ("previous_observation", "i4"), - ("next_observation", "i4"), - ], - ) - ids["group"] = group - ids["time"] = time - # To store id track - ids["track"] = 0 - ids["previous_cost"] = 0 - ids["next_cost"] = 0 - ids["previous_observation"] = -1 - ids["next_observation"] = -1 - # Cost with previous - track_start, track_end, track_ref = build_index(group) - for i0, i1 in zip(track_start, track_end): - if (i1 - i0) == 0 or group[i0] == Network.NOGROUP: - continue - sl_group = slice(i0, i1) - set_tracks( - x[sl_group], - y[sl_group], - time[sl_group], - i0, - ids["track"][sl_group], - ids["previous_cost"][sl_group], - ids["next_cost"][sl_group], - ids["previous_observation"][sl_group], - ids["next_observation"][sl_group], - window=5, - ) - - new_i = ids.argsort(order=("group", "track", "time")) - ids_sort = ids[new_i] - # To be able to follow indices sorting - reverse_sort = empty(new_i.shape[0], dtype="u4") - reverse_sort[new_i] = arange(new_i.shape[0]) - # Redirect indices - m = ids_sort["next_observation"] != -1 - ids_sort["next_observation"][m] = reverse_sort[ids_sort["next_observation"][m]] - m = ids_sort["previous_observation"] != -1 - ids_sort["previous_observation"][m] = reverse_sort[ - ids_sort["previous_observation"][m] - ] - # print(ids_sort) - display_network( - x[new_i], - y[new_i], - ids_sort["track"], - ids_sort["time"], - ids_sort["next_cost"], - ) - - -def next_obs( - i_current, next_cost, previous_cost, polygons, t, t_start, t_end, t_ref, window -): - t_max = t_end.shape[0] - 1 - t_cur = t[i_current] - t0, t1 = t_cur + 1 - t_ref, t_cur + window - t_ref - if t0 > t_max: - return -1 - t1 = min(t1, t_max) - for t_step in range(t0, t1 + 1): - i0, i1 = t_start[t_step], t_end[t_step] - # No observation at the time step ! - if i0 == i1: - continue - sl = slice(i0, i1) - # Intersection / union, to be able to separte in case of multiple inside - c = polygon_overlap(polygons[i_current], polygons[sl]) - # We remove low overlap - if (c > 0.1).sum() > 1: - print(c) - c[c < 0.1] = 0 - # We get index of maximal overlap - i = c.argmax() - c_i = c[i] - # No overlap found - if c_i == 0: - continue - target = i0 + i - # Check if candidate is already used - c_target = previous_cost[target] - if (c_target != 0 and c_target < c_i) or c_target == 0: - previous_cost[target] = c_i - next_cost[i_current] = c_i - return target - return -1 - - -def set_tracks( - x, - y, - t, - ref_index, - track, - previous_cost, - next_cost, - previous_observation, - next_observation, - window, -): - # Will split one group in tracks - t_start, t_end, t_ref = build_index(t) - nb = x.shape[0] - used = zeros(nb, dtype="bool") - current_track = 1 - # build all polygon (need to check if wrap is needed) - polygons = list() - for i in range(nb): - polygons.append(Polygon(create_vertice_from_2darray(x, y, i))) - - for i in range(nb): - # If observation already in one track, we go to the next one - if used[i]: - continue - build_track( - i, - current_track, - used, - track, - previous_observation, - next_observation, - ref_index, - next_cost, - previous_cost, - polygons, - t, - t_start, - t_end, - t_ref, - window, - ) - current_track += 1 - - -def build_track( - first_index, - track_id, - used, - track, - previous_observation, - next_observation, - ref_index, - next_cost, - previous_cost, - *args, -): - i_next = first_index - while i_next != -1: - # Flag - used[i_next] = True - # Assign id - track[i_next] = track_id - # Search next - i_next_ = next_obs(i_next, next_cost, previous_cost, *args) - if i_next_ == -1: - break - next_observation[i_next] = i_next_ + ref_index - if not used[i_next_]: - previous_observation[i_next_] = i_next + ref_index - # Target was previously used - if used[i_next_]: - if next_cost[i_next] == previous_cost[i_next_]: - m = track[i_next_:] == track[i_next_] - track[i_next_:][m] = track_id - previous_observation[i_next_] = i_next + ref_index - i_next_ = -1 - i_next = i_next_ - - -def display_network(x, y, tr, t, c): - tr0, tr1, t_ref = build_index(tr) - import matplotlib.pyplot as plt - - cmap = plt.get_cmap("jet") - from ..generic import flatten_line_matrix - - fig = plt.figure(figsize=(20, 10)) - ax = fig.add_subplot(121, aspect="equal") - ax.grid() - ax_time = fig.add_subplot(122) - ax_time.grid() - i = 0 - for s, e in zip(tr0, tr1): - if s == e: - continue - sl = slice(s, e) - color = cmap((tr[s] - tr[tr0[0]]) / (tr[tr0[-1]] - tr[tr0[0]])) - ax.plot( - flatten_line_matrix(x[sl]), - flatten_line_matrix(y[sl]), - color=color, - label=f"{tr[s]} - {e-s} obs from {t[s]} to {t[e-1]}", - ) - i += 1 - ax_time.plot( - t[sl], - tr[s].repeat(e - s) + c[sl], - color=color, - label=f"{tr[s]} - {e-s} obs", - lw=0.5, - ) - ax_time.plot(t[sl], tr[s].repeat(e - s), color=color, lw=1, marker="+") - ax_time.text(t[s], tr[s] + 0.15, f"{x[s].mean():.2f}, {y[s].mean():.2f}") - ax_time.axvline(t[s], color=".75", lw=0.5, ls="--", zorder=-10) - ax_time.text( - t[e - 1], tr[e - 1] - 0.25, f"{x[e-1].mean():.2f}, {y[e-1].mean():.2f}" - ) - ax.legend() - ax_time.legend() - plt.show() + e = e.add_fields(("sub_track",)) + e.sub_track[:] = ids["track"] + e.write_file(filename=args.out) diff --git a/src/py_eddy_tracker/generic.py b/src/py_eddy_tracker/generic.py index ce3bb787..24b3cc22 100644 --- a/src/py_eddy_tracker/generic.py +++ b/src/py_eddy_tracker/generic.py @@ -83,7 +83,8 @@ def build_index(groups): first_index[group - i0 + 1 : next_group - i0 + 1] = i + 1 last_index = zeros(amplitude, dtype=numba_types.int_) last_index[:-1] = first_index[1:] - last_index[-1] = i + 1 + # + 2 because we iterate only until -2 and we want upper bound ( 1 + 1) + last_index[-1] = i + 2 return first_index, last_index, i0 diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index b80097a4..55c67f74 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -26,11 +26,10 @@ where, zeros, ) -from Polygon import Polygon from .. import VAR_DESCR_inv, __version__ from ..generic import build_index, cumsum_by_track, distance, split_line, wrap_longitude -from ..poly import create_vertice_from_2darray, merge, polygon_overlap +from ..poly import bbox_intersection, merge, vertice_overlap from .observation import EddiesObservations logger = logging.getLogger("pet") @@ -642,15 +641,14 @@ def set_tracks(self, x, y, ids, window): used = zeros(nb, dtype="bool") track_id = 1 # build all polygon (need to check if wrap is needed) - polygons = [Polygon(create_vertice_from_2darray(x, y, i)) for i in range(nb)] for i in range(nb): # If observation already in one track, we go to the next one if used[i]: continue - self.follow_obs(i, track_id, used, ids, polygons, *time_index, window) + self.follow_obs(i, track_id, used, ids, x, y, *time_index, window) track_id += 1 # Search a possible ancestor - self.previous_obs(i, ids, polygons, *time_index, window) + self.previous_obs(i, ids, x, y, *time_index, window) @classmethod def follow_obs(cls, i_next, track_id, used, ids, *args): @@ -676,7 +674,7 @@ def follow_obs(cls, i_next, track_id, used, ids, *args): i_next = i_next_ @staticmethod - def previous_obs(i_current, ids, polygons, time_s, time_e, time_ref, window): + def previous_obs(i_current, ids, x, y, time_s, time_e, time_ref, window): time_cur = ids["time"][i_current] t0, t1 = time_cur - 1 - time_ref, max(time_cur - window - time_ref, 0) for t_step in range(t0, t1 - 1, -1): @@ -685,7 +683,12 @@ def previous_obs(i_current, ids, polygons, time_s, time_e, time_ref, window): if i0 == i1: continue # Intersection / union, to be able to separte in case of multiple inside - c = polygon_overlap(polygons[i_current], polygons[i0:i1], minimal_area=True) + xi, yi, xj, yj = x[[i_current]], y[[i_current]], x[i0:i1], y[i0:i1] + ii, ij = bbox_intersection(xi, yi, xj, yj) + if len(ii) == 0: + continue + c = zeros(len(xj)) + c[ij] = vertice_overlap(xi[ii], yi[ii], xj[ij], yj[ij], minimal_area=True) # We remove low overlap c[c < 0.1] = 0 # We get index of maximal overlap @@ -699,7 +702,7 @@ def previous_obs(i_current, ids, polygons, time_s, time_e, time_ref, window): break @staticmethod - def next_obs(i_current, ids, polygons, time_s, time_e, time_ref, window): + def next_obs(i_current, ids, x, y, time_s, time_e, time_ref, window): time_max = time_e.shape[0] - 1 time_cur = ids["time"][i_current] t0, t1 = time_cur + 1 - time_ref, min(time_cur + window - time_ref, time_max) @@ -711,7 +714,12 @@ def next_obs(i_current, ids, polygons, time_s, time_e, time_ref, window): if i0 == i1: continue # Intersection / union, to be able to separte in case of multiple inside - c = polygon_overlap(polygons[i_current], polygons[i0:i1], minimal_area=True) + xi, yi, xj, yj = x[[i_current]], y[[i_current]], x[i0:i1], y[i0:i1] + ii, ij = bbox_intersection(xi, yi, xj, yj) + if len(ii) == 0: + continue + c = zeros(len(xj)) + c[ij] = vertice_overlap(xi[ii], yi[ii], xj[ij], yj[ij], minimal_area=True) # We remove low overlap c[c < 0.1] = 0 # We get index of maximal overlap From 0a0b061f15bc1a421bd67c03a91cd7f059726994 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 12 Jan 2021 15:03:46 +0100 Subject: [PATCH 013/249] Allow eddyAnim to display field in color --- CHANGELOG.rst | 1 + src/py_eddy_tracker/appli/gui.py | 100 ++++++++++++++++++++++++++----- 2 files changed, 86 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 256aed80..70260234 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -19,6 +19,7 @@ Added - Add a filter option in EddyId to be able to remove fine scale (like noise) with same filter order than high scale filter - Add **EddyQuickCompare** to have few figures about several datasets in comparison based on match function +- Color field for contour in **EddyAnim** could be choose [3.3.0] - 2020-12-03 -------------------- diff --git a/src/py_eddy_tracker/appli/gui.py b/src/py_eddy_tracker/appli/gui.py index a5b58b30..85dc6577 100644 --- a/src/py_eddy_tracker/appli/gui.py +++ b/src/py_eddy_tracker/appli/gui.py @@ -3,20 +3,24 @@ Entry point of graphic user interface """ +import logging from datetime import datetime +from itertools import chain from matplotlib import pyplot from matplotlib.collections import LineCollection -from numpy import arange, empty, where +from numpy import where from .. import EddyParser -from ..generic import flatten_line_matrix from ..gui import GUI from ..observations.tracking import TrackEddiesObservations from ..poly import create_vertice +logger = logging.getLogger("pet") + class Anim: + def __init__( self, eddy, intern=False, sleep_event=0.1, graphic_information=False, **kwargs ): @@ -29,11 +33,32 @@ def __init__( self.period = self.eddy.period self.sleep_event = sleep_event self.mappables = list() + self.field_color = None + self.time_field = False self.setup(**kwargs) - def setup(self, cmap="jet", nb_step=25, figsize=(8, 6), **kwargs): - cmap = pyplot.get_cmap(cmap) - self.colors = cmap(arange(nb_step + 1) / nb_step) + def setup( + self, + cmap="jet", + lut=None, + field_color="time", + range_color=(None, None), + nb_step=25, + figsize=(8, 6), + **kwargs, + ): + self.field_color = self.eddy[field_color].astype("f4") + rg = range_color + if rg[0] is None and rg[1] is None and field_color == "time": + self.time_field = True + else: + rg = ( + self.field_color.min() if rg[0] is None else rg[0], + self.field_color.max() if rg[1] is None else rg[1], + ) + self.field_color = (self.field_color - rg[0]) / (rg[1] - rg[0]) + + self.colors = pyplot.get_cmap(cmap, lut=lut) self.nb_step = nb_step x_min, x_max = self.x_core.min() - 2, self.x_core.max() + 2 @@ -51,6 +76,8 @@ def setup(self, cmap="jet", nb_step=25, figsize=(8, 6), **kwargs): # init mappable self.txt = self.ax.text(x_min + 0.05 * d_x, y_min + 0.05 * d_y, "", zorder=10) self.segs = list() + self.t_segs = list() + self.c_segs = list() self.contour = LineCollection([], zorder=1) self.ax.add_collection(self.contour) @@ -89,8 +116,9 @@ def show(self, infinity_loop=False): if dt < 0: # self.sleep_event = dt_draw * 1.01 dt = 1e-10 + if dt == 0: + dt = 1e-10 self.fig.canvas.start_event_loop(dt) - if self.now > t1: break if infinity_loop: @@ -118,20 +146,41 @@ def func_animation(self, frame): def update(self): m = self.t == self.now if m.sum(): - self.segs.append( - create_vertice( - flatten_line_matrix(self.x[m]), flatten_line_matrix(self.y[m]) + segs = list() + t = list() + c = list() + for i in where(m)[0]: + segs.append(create_vertice(self.x[i], self.y[i])) + c.append(self.field_color[i]) + t.append(self.now) + self.segs.append(segs) + self.c_segs.append(c) + self.t_segs.append(t) + self.contour.set_paths(chain(*self.segs)) + if self.time_field: + self.contour.set_color( + self.colors( + [ + (self.nb_step - self.now + i) / self.nb_step + for i in chain(*self.c_segs) + ] ) ) else: - self.segs.append(empty((0, 2))) - self.contour.set_paths(self.segs) - self.contour.set_color(self.colors[-len(self.segs) :]) - self.contour.set_lw(arange(len(self.segs)) / len(self.segs) * 2.5) + self.contour.set_color(self.colors(list(chain(*self.c_segs)))) + # linewidth will be link to time delay + self.contour.set_lw( + [ + (1 - (self.now - i) / self.nb_step) * 2.5 if i <= self.now else 0 + for i in chain(*self.t_segs) + ] + ) + # Update date txt and info txt = f"{self.now}" if self.graphic_informations: txt += f"- {1/self.sleep_event:.0f} frame/s" self.txt.set_text(txt) + # Update id txt for i in where(m)[0]: mappable = self.ax.text( self.x_core[i], self.y_core[i], self.track[i], fontsize=8 @@ -143,6 +192,8 @@ def update(self): # Remove first segment to keep only T contour if len(self.segs) > self.nb_step: self.segs.pop(0) + self.t_segs.pop(0) + self.c_segs.pop(0) def draw_contour(self): # select contour for this time step @@ -165,8 +216,13 @@ def keyboard(self, event): elif event.key == "right" and self.pause: self.next() elif event.key == "left" and self.pause: + # we remove 2 step to add 1 so we rewind of only one self.segs.pop(-1) self.segs.pop(-1) + self.t_segs.pop(-1) + self.t_segs.pop(-1) + self.c_segs.pop(-1) + self.c_segs.pop(-1) self.prev() @@ -197,11 +253,22 @@ def anim(): action="store_true", help="Longitude will be centered on first obs, if there are only one group.", ) + parser.add_argument( + "--field", default="time", help="Field use to color contour instead of time" + ) + parser.add_argument( + "--vmin", default=None, type=float, help="Inferior bound to color contour" + ) + parser.add_argument( + "--vmax", default=None, type=float, help="Upper bound to color contour" + ) args = parser.parse_args() - variables = ["time", "track", "longitude", "latitude"] + variables = ["time", "track", "longitude", "latitude", args.field] variables.extend(TrackEddiesObservations.intern(args.intern, public_label=True)) - eddies = TrackEddiesObservations.load_file(args.filename, include_vars=variables) + eddies = TrackEddiesObservations.load_file( + args.filename, include_vars=set(variables) + ) if not args.all: if len(args.id) == 0: raise Exception( @@ -222,6 +289,9 @@ def anim(): sleep_event=args.time_sleep, cmap=args.cmap, nb_step=args.keep_step, + field_color=args.field, + range_color=(args.vmin, args.vmax), + graphic_information=logger.getEffectiveLevel() == logging.DEBUG, ) a.show(infinity_loop=args.infinity_loop) From 16438f2dfc6ca3e48c420670e4260b76714e575e Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 12 Jan 2021 17:04:15 +0100 Subject: [PATCH 014/249] Option for network segmentation --- src/py_eddy_tracker/appli/network.py | 2 +- src/py_eddy_tracker/observations/tracking.py | 22 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index c692262e..6b0927bd 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -50,7 +50,7 @@ def divide_network(): args.input, include_vars=("time", "track", "latitude", "longitude", *contour_name), ) - ids = e.split_network(intern=args.intern, window=args.window) + ids = e.split_network(intern=args.intern, window=args.window, minimal_area=False) e = e.add_fields(("sub_track",)) e.sub_track[:] = ids["track"] e.write_file(filename=args.out) diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index 55c67f74..b30b3d05 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -626,7 +626,7 @@ def split_network(self, intern=True, **kwargs): local_ids["next_obs"][m] += i_s return ids - def set_tracks(self, x, y, ids, window): + def set_tracks(self, x, y, ids, window, **kwargs): """ Will split one group in tracks @@ -645,20 +645,20 @@ def set_tracks(self, x, y, ids, window): # If observation already in one track, we go to the next one if used[i]: continue - self.follow_obs(i, track_id, used, ids, x, y, *time_index, window) + self.follow_obs(i, track_id, used, ids, x, y, *time_index, window, **kwargs) track_id += 1 # Search a possible ancestor - self.previous_obs(i, ids, x, y, *time_index, window) + self.previous_obs(i, ids, x, y, *time_index, window, **kwargs) @classmethod - def follow_obs(cls, i_next, track_id, used, ids, *args): + def follow_obs(cls, i_next, track_id, used, ids, *args, **kwargs): while i_next != -1: # Flag used[i_next] = True # Assign id ids["track"][i_next] = track_id # Search next - i_next_ = cls.next_obs(i_next, ids, *args) + i_next_ = cls.next_obs(i_next, ids, *args, **kwargs) if i_next_ == -1: break ids["next_obs"][i_next] = i_next_ @@ -674,7 +674,7 @@ def follow_obs(cls, i_next, track_id, used, ids, *args): i_next = i_next_ @staticmethod - def previous_obs(i_current, ids, x, y, time_s, time_e, time_ref, window): + def previous_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs): time_cur = ids["time"][i_current] t0, t1 = time_cur - 1 - time_ref, max(time_cur - window - time_ref, 0) for t_step in range(t0, t1 - 1, -1): @@ -688,9 +688,9 @@ def previous_obs(i_current, ids, x, y, time_s, time_e, time_ref, window): if len(ii) == 0: continue c = zeros(len(xj)) - c[ij] = vertice_overlap(xi[ii], yi[ii], xj[ij], yj[ij], minimal_area=True) + c[ij] = vertice_overlap(xi[ii], yi[ii], xj[ij], yj[ij], **kwargs) # We remove low overlap - c[c < 0.1] = 0 + c[c < 0.01] = 0 # We get index of maximal overlap i = c.argmax() c_i = c[i] @@ -702,7 +702,7 @@ def previous_obs(i_current, ids, x, y, time_s, time_e, time_ref, window): break @staticmethod - def next_obs(i_current, ids, x, y, time_s, time_e, time_ref, window): + def next_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs): time_max = time_e.shape[0] - 1 time_cur = ids["time"][i_current] t0, t1 = time_cur + 1 - time_ref, min(time_cur + window - time_ref, time_max) @@ -719,9 +719,9 @@ def next_obs(i_current, ids, x, y, time_s, time_e, time_ref, window): if len(ii) == 0: continue c = zeros(len(xj)) - c[ij] = vertice_overlap(xi[ii], yi[ii], xj[ij], yj[ij], minimal_area=True) + c[ij] = vertice_overlap(xi[ii], yi[ii], xj[ij], yj[ij], **kwargs) # We remove low overlap - c[c < 0.1] = 0 + c[c < 0.01] = 0 # We get index of maximal overlap i = c.argmax() c_i = c[i] From d5b460d8eed5b1d752e1a8ccfb09f4336eb66d32 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 12 Jan 2021 17:16:03 +0100 Subject: [PATCH 015/249] Save anim in video --- CHANGELOG.rst | 1 + src/py_eddy_tracker/appli/gui.py | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 70260234..c25d1765 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -20,6 +20,7 @@ Added filter - Add **EddyQuickCompare** to have few figures about several datasets in comparison based on match function - Color field for contour in **EddyAnim** could be choose +- Save EddyAnim in mp4 [3.3.0] - 2020-12-03 -------------------- diff --git a/src/py_eddy_tracker/appli/gui.py b/src/py_eddy_tracker/appli/gui.py index 85dc6577..16b7274c 100644 --- a/src/py_eddy_tracker/appli/gui.py +++ b/src/py_eddy_tracker/appli/gui.py @@ -8,8 +8,9 @@ from itertools import chain from matplotlib import pyplot +from matplotlib.animation import FuncAnimation from matplotlib.collections import LineCollection -from numpy import where +from numpy import arange, where from .. import EddyParser from ..gui import GUI @@ -20,7 +21,6 @@ class Anim: - def __init__( self, eddy, intern=False, sleep_event=0.1, graphic_information=False, **kwargs ): @@ -262,6 +262,7 @@ def anim(): parser.add_argument( "--vmax", default=None, type=float, help="Upper bound to color contour" ) + parser.add_argument("--avi", help="Filename to save animation (avi)") args = parser.parse_args() variables = ["time", "track", "longitude", "latitude", args.field] variables.extend(TrackEddiesObservations.intern(args.intern, public_label=True)) @@ -293,7 +294,12 @@ def anim(): range_color=(args.vmin, args.vmax), graphic_information=logger.getEffectiveLevel() == logging.DEBUG, ) - a.show(infinity_loop=args.infinity_loop) + if args.avi is None: + a.show(infinity_loop=args.infinity_loop) + else: + kwargs = dict(frames=arange(*a.period), interval=50) + ani = FuncAnimation(a.fig, a.func_animation, **kwargs) + ani.save(args.avi, fps=30, extra_args=["-vcodec", "libx264"]) def gui_parser(): From ee5de9e3bd2a510509ebf0c80afb1a493128ab05 Mon Sep 17 00:00:00 2001 From: CoriPegliasco <66008544+CoriPegliasco@users.noreply.github.com> Date: Wed, 13 Jan 2021 16:18:42 +0100 Subject: [PATCH 016/249] add comments (#46) * Correction of global indexation, Add comments * Add comments --- src/py_eddy_tracker/__init__.py | 4 +- src/py_eddy_tracker/observations/tracking.py | 92 +++++++++++--------- src/py_eddy_tracker/poly.py | 6 +- 3 files changed, 58 insertions(+), 44 deletions(-) diff --git a/src/py_eddy_tracker/__init__.py b/src/py_eddy_tracker/__init__.py index d184d551..19e76f61 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -197,7 +197,7 @@ def parse_args(self, *args, **kwargs): nc_attr=dict( units="degrees_east", axis="X", - comment="Longitude center of the fitted circle", + comment="Longitude center of the fit circle", long_name="Eddy Center Longitude", standard_name="longitude", ), @@ -214,7 +214,7 @@ def parse_args(self, *args, **kwargs): axis="Y", long_name="Eddy Center Latitude", standard_name="latitude", - comment="Latitude center of the fitted circle", + comment="Latitude center of the fit circle", ), ), lon_max=dict( diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index b30b3d05..7113c324 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Class to manage observations gathered in track +Class to manage observations gathered in trajectories """ import logging from datetime import datetime, timedelta @@ -123,7 +123,7 @@ def __repr__(self): return content def add_distance(self): - """Add a field of distance (m) between to consecutive observation, 0 for the last observation of each track""" + """Add a field of distance (m) between two consecutive observations, 0 for the last observation of each track""" if "distance_next" in self.observations.dtype.descr: return self new = self.add_fields(("distance_next",)) @@ -181,7 +181,7 @@ def filled_by_interpolation(self, mask): ) def extract_longer_eddies(self, nb_min, nb_obs, compress_id=True): - """Select eddies which are longer than nb_min""" + """Select the trajectories longer than nb_min""" mask = nb_obs >= nb_min nb_obs_select = mask.sum() logger.info("Selection of %d observations", nb_obs_select) @@ -226,9 +226,9 @@ def set_global_attr_netcdf(self, h_nc): def extract_with_period(self, period, **kwargs): """ - Extract with a period + Extract within a time period - :param (int,int) period: two date to define period, must be specify from 1/1/1950 + :param (int,int) period: two dates to define the period, must be specify from 1/1/1950 :param dict kwargs: look at :py:meth:`extract_with_mask` :return: Return all eddy tracks which are in bounds :rtype: TrackEddiesObservations @@ -251,9 +251,9 @@ def extract_with_period(self, period, **kwargs): def get_azimuth(self, equatorward=False): """ - Return azimuth for each tracks. + Return azimuth for each track. - Azimuth is compute with first and last observation + Azimuth is computed with first and last observation :param bool equatorward: If True, Poleward are positive and equatorward negative :rtype: array @@ -285,7 +285,7 @@ def compute_index(self): """ if self.__first_index_of_track is None: s = self.tracks.max() + 1 - # Doesn't work => core dump with numba, maybe he wait i8 instead of u4 + # Doesn't work => core dump with numba, maybe he wants i8 instead of u4 # self.__first_index_of_track = -ones(s, self.tracks.dtype) # self.__obs_by_track = zeros(s, self.observation_number.dtype) self.__first_index_of_track = -ones(s, "i8") @@ -333,12 +333,12 @@ def nb_obs_by_track(self): @property def lifetime(self): - """Return for each observation lifetime""" + """Return lifetime for each observation""" return self.nb_obs_by_track.repeat(self.nb_obs_by_track) @property def age(self): - """Return for each observation age in %, will be [0:100]""" + """Return age in % for each observation, will be [0:100]""" return self.n.astype("f4") / (self.lifetime - 1) * 100.0 def extract_ids(self, tracks): @@ -347,10 +347,10 @@ def extract_ids(self, tracks): def extract_toward_direction(self, west=True, delta_lon=None): """ - Get eddy which go in same direction + Get trajectories going in the same direction - :param bool west: Only eastward eddy if True return westward - :param None,float delta_lon: Only eddy with more than delta_lon span in longitude + :param bool west: Only eastward eddies if True return westward + :param None,float delta_lon: Only eddies with more than delta_lon span in longitude :return: Only eastern eddy :rtype: __class__ @@ -397,10 +397,10 @@ def extract_in_direction(self, direction, value=0): def extract_with_length(self, bounds): """ - Return all observations in [b0:b1] + Return the observations within trajectories lasting between [b0:b1] - :param (int,int) bounds: length min and max of selected eddies, if use of -1 this bound is not used - :return: Return all eddy tracks which have length between bounds + :param (int,int) bounds: length min and max of the desired trajectories, if -1 this bound is not used + :return: Return all trajectories having length between bounds :rtype: TrackEddiesObservations .. minigallery:: py_eddy_tracker.TrackEddiesObservations.extract_with_length @@ -460,11 +460,11 @@ def extract_with_mask( Extract a subset of observations :param array(bool) mask: mask to select observations - :param bool full_path: extract full path if only one part is selected - :param bool remove_incomplete: delete path which are not fully selected - :param bool compress_id: resample track number to use a little range - :param bool reject_virtual: if track are only virtual in selection we remove track - :return: same object with selected observations + :param bool full_path: extract the full trajectory if only one part is selected + :param bool remove_incomplete: delete trajectory if not fully selected + :param bool compress_id: resample trajectory number to use a smaller range + :param bool reject_virtual: if only virtual are selected, the trajectory is removed + :return: same object with the selected observations :rtype: self.__class__ """ if full_path and remove_incomplete: @@ -509,7 +509,9 @@ def re_reference_index(index, ref): def shape_polygon(self, intern=False): """ - Get polygons which enclosed each track + Get the polygon enclosing each trajectory. + + The polygon merges the non-overlapping bounds of the specified contours :param bool intern: If True use speed contour instead of effective contour :rtype: list(array, array) @@ -519,9 +521,9 @@ def shape_polygon(self, intern=False): def display_shape(self, ax, ref=None, intern=False, **kwargs): """ - This function will draw shape of each track + This function will draw the shape of each trajectory - :param matplotlib.axes.Axes ax: ax where drawed + :param matplotlib.axes.Axes ax: ax to draw :param float,int ref: if defined all coordinates will be wrapped with ref like west boundary :param bool intern: If True use speed contour instead of effective contour :param dict kwargs: keyword arguments for Axes.plot @@ -546,10 +548,10 @@ def display_shape(self, ax, ref=None, intern=False, **kwargs): def close_tracks(self, other, nb_obs_min=10, **kwargs): """ - Get close from another atlas. + Get close trajectories from another atlas. :param self other: Atlas to compare - :param int nb_obs_min: Minimal number of overlap for one track + :param int nb_obs_min: Minimal number of overlap for one trajectory :param dict kwargs: keyword arguments for match function :return: return other atlas reduce to common track with self @@ -576,10 +578,10 @@ def format_label(self, label): def plot(self, ax, ref=None, **kwargs): """ - This function will draw path of each track + This function will draw path of each trajectory - :param matplotlib.axes.Axes ax: ax where drawed - :param float,int ref: if defined all coordinates will be wrapped with ref like west boundary + :param matplotlib.axes.Axes ax: ax to draw + :param float,int ref: if defined, all coordinates will be wrapped with ref like west boundary :param dict kwargs: keyword arguments for Axes.plot :return: matplotlib mappable """ @@ -594,7 +596,7 @@ def plot(self, ax, ref=None, **kwargs): return ax.plot(x, y, **kwargs) def split_network(self, intern=True, **kwargs): - """Divide each group in track""" + """Return each group (network) divided in segments""" track_s, track_e, track_ref = build_index(self.tracks) ids = empty( len(self), @@ -609,9 +611,13 @@ def split_network(self, intern=True, **kwargs): ], ) ids["group"], ids["time"] = self.tracks, self.time - # To store id track + # Initialisation + # To store the id of the segments, the backward and forward cost associations ids["track"], ids["previous_cost"], ids["next_cost"] = 0, 0, 0 + # To store the indexes of the backward and forward observations associated ids["previous_obs"], ids["next_obs"] = -1, -1 + # At the end, ids["previous_obs"] == -1 means the start of a non-split segment + # and ids["next_obs"] == -1 means the end of a non-merged segment xname, yname = self.intern(intern) for i_s, i_e in zip(track_s, track_e): @@ -619,16 +625,18 @@ def split_network(self, intern=True, **kwargs): continue sl = slice(i_s, i_e) local_ids = ids[sl] + # built segments with local indices self.set_tracks(self[xname][sl], self[yname][sl], local_ids, **kwargs) - m = local_ids["previous_obs"] == -1 + # shift the local indices to the total indexation for the used observations + m = local_ids["previous_obs"] != -1 local_ids["previous_obs"][m] += i_s - m = local_ids["next_obs"] == -1 + m = local_ids["next_obs"] != -1 local_ids["next_obs"][m] += i_s return ids def set_tracks(self, x, y, ids, window, **kwargs): """ - Will split one group in tracks + Will split one group (network) in segments :param array x: coordinates of group :param array y: coordinates of group @@ -640,18 +648,21 @@ def set_tracks(self, x, y, ids, window, **kwargs): nb = x.shape[0] used = zeros(nb, dtype="bool") track_id = 1 - # build all polygon (need to check if wrap is needed) + # build all polygons (need to check if wrap is needed) for i in range(nb): - # If observation already in one track, we go to the next one + # If the observation is already in one track, we go to the next one if used[i]: continue + # Search a possible continuation (forward) self.follow_obs(i, track_id, used, ids, x, y, *time_index, window, **kwargs) track_id += 1 - # Search a possible ancestor + # Search a possible ancestor (backward) self.previous_obs(i, ids, x, y, *time_index, window, **kwargs) @classmethod def follow_obs(cls, i_next, track_id, used, ids, *args, **kwargs): + """Associate the observations to the segments""" + while i_next != -1: # Flag used[i_next] = True @@ -675,6 +686,8 @@ def follow_obs(cls, i_next, track_id, used, ids, *args, **kwargs): @staticmethod def previous_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs): + """Backward association of observations to the segments""" + time_cur = ids["time"][i_current] t0, t1 = time_cur - 1 - time_ref, max(time_cur - window - time_ref, 0) for t_step in range(t0, t1 - 1, -1): @@ -682,7 +695,7 @@ def previous_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwarg # No observation at the time step if i0 == i1: continue - # Intersection / union, to be able to separte in case of multiple inside + # Search for overlaps xi, yi, xj, yj = x[[i_current]], y[[i_current]], x[i0:i1], y[i0:i1] ii, ij = bbox_intersection(xi, yi, xj, yj) if len(ii) == 0: @@ -703,6 +716,7 @@ def previous_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwarg @staticmethod def next_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs): + """Forward association of observations to the segments""" time_max = time_e.shape[0] - 1 time_cur = ids["time"][i_current] t0, t1 = time_cur + 1 - time_ref, min(time_cur + window - time_ref, time_max) @@ -713,7 +727,7 @@ def next_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs): # No observation at the time step if i0 == i1: continue - # Intersection / union, to be able to separte in case of multiple inside + # Search for overlaps xi, yi, xj, yj = x[[i_current]], y[[i_current]], x[i0:i1], y[i0:i1] ii, ij = bbox_intersection(xi, yi, xj, yj) if len(ii) == 0: diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index 4677e3bf..da39d707 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -452,7 +452,7 @@ def polygon_overlap(p0, p1, minimal_area=False): :param list(Polygon) p0: List of polygon to compare with p1 list :param list(Polygon) p1: List of polygon to compare with p0 list - :param bool minimal_area: If True, function will compute intersection/little polygon, else intersection/union + :param bool minimal_area: If True, function will compute intersection/smaller polygon, else intersection/union :return: Result of cost function :rtype: array """ @@ -462,10 +462,10 @@ def polygon_overlap(p0, p1, minimal_area=False): p_ = p1[i] # Area of intersection intersection = (p0 & p_).area() - # we divide intersection with the little one result from 0 to 1 + # we divide the intersection by the smaller area, result from 0 to 1 if minimal_area: cost[i] = intersection / min(p0.area(), p_.area()) - # we divide intersection with polygon merging result from 0 to 1 + # we divide the intersection by the merged polygons area, result from 0 to 1 else: cost[i] = intersection / (p0 + p_).area() return cost From ac9c14289b3ea19777fcd4d284d005ef80319b74 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Wed, 13 Jan 2021 18:00:30 +0100 Subject: [PATCH 017/249] Start basic tools for network manipulation --- examples/16_network/pet_relative.py | 40 ++++++++ src/py_eddy_tracker/__init__.py | 24 ++++- src/py_eddy_tracker/appli/network.py | 4 +- src/py_eddy_tracker/observations/network.py | 93 ++++++++++++++++++- .../observations/observation.py | 27 +++++- src/py_eddy_tracker/observations/tracking.py | 4 +- 6 files changed, 182 insertions(+), 10 deletions(-) create mode 100644 examples/16_network/pet_relative.py diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py new file mode 100644 index 00000000..32f87b77 --- /dev/null +++ b/examples/16_network/pet_relative.py @@ -0,0 +1,40 @@ +""" +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")) +n = NetworkObservations.from_split_network(e, e.split_network(intern=False, window=5)) + +# %% +# Timeline +# -------- + +# %% +# Display timeline +fig = plt.figure(figsize=(15, 8)) +ax = fig.add_axes([0.04, 0.04, 0.92, 0.92]) +n.display_timeline(ax) + +# %% +# Display timeline with event +fig = plt.figure(figsize=(15, 8)) +ax = fig.add_axes([0.04, 0.04, 0.92, 0.92]) +n.display_timeline(ax, event=True) +plt.show() + +# %% +# Keep close relative +# ------------------- +# First choose an observation in the network diff --git a/src/py_eddy_tracker/__init__.py b/src/py_eddy_tracker/__init__.py index d184d551..514f4f46 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -374,15 +374,35 @@ def parse_args(self, *args, **kwargs): long_name="Trajectory number", comment="Trajectory identification number" ), ), - sub_track=dict( + segment=dict( attr_name=None, - nc_name="sub_track", + nc_name="segment", nc_type="uint32", nc_dims=("obs",), nc_attr=dict( long_name="Segment Number", comment="Segment number inside a group" ), ), + previous_obs=dict( + attr_name=None, + nc_name="previous_obs", + nc_type="int32", + nc_dims=("obs",), + nc_attr=dict( + long_name="Previous obs index", + comment="Index of previous obs, if there are a spliting", + ), + ), + next_obs=dict( + attr_name=None, + nc_name="next_obs", + nc_type="int32", + nc_dims=("obs",), + nc_attr=dict( + long_name="Next obs index", + comment="Index of next obs, if there are a merging", + ), + ), n=dict( attr_name=None, nc_name="observation_number", diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index 6b0927bd..8ac8582f 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -51,6 +51,6 @@ def divide_network(): include_vars=("time", "track", "latitude", "longitude", *contour_name), ) ids = e.split_network(intern=args.intern, window=args.window, minimal_area=False) - e = e.add_fields(("sub_track",)) - e.sub_track[:] = ids["track"] + e = e.add_fields(("segment",)) + e.segment[:] = ids["track"] e.write_file(filename=args.out) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 33fe6469..0a1d023d 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -6,7 +6,7 @@ from glob import glob from numba import njit -from numpy import arange, array, bincount, empty, uint32, unique +from numpy import arange, array, bincount, empty, ones, uint32, unique from ..poly import bbox_intersection, vertice_overlap from .observation import EddiesObservations @@ -58,6 +58,97 @@ def load_contour(self, filename): return self.DATA[filename] +class NetworkObservations(EddiesObservations): + + __slots__ = tuple() + + NOGROUP = 0 + + @property + def elements(self): + elements = super().elements + elements.extend(["track", "segment", "next_obs", "previous_obs"]) + return list(set(elements)) + + @classmethod + def from_split_network(cls, group_dataset, indexs, **kwargs): + """ + Build a NetworkObservations object with Group dataset and indexs + + :param TrackEddiesObservations group_dataset: Group dataset + :param indexs: result from split_network + return NetworkObservations + """ + index_order = indexs.argsort(order=("group", "track", "time")) + network = cls.new_like(group_dataset, len(group_dataset), **kwargs) + network.sign_type = group_dataset.sign_type + for field in group_dataset.elements: + if field not in network.elements: + continue + network[field][:] = group_dataset[field][index_order] + network.segment[:] = indexs["track"][index_order] + # n & p must be re-index + n, p = indexs["next_obs"][index_order], indexs["previous_obs"][index_order] + translate = empty(index_order.max() + 1, dtype="i4") + translate[index_order] = arange(index_order.shape[0]) + m = n != -1 + n[m] = translate[n[m]] + m = p != -1 + p[m] = translate[p[m]] + network.next_obs[:] = n + network.previous_obs[:] = p + return network + + def relative(self, i_obs, order=2, direct=True, only_past=False, only_future=False): + pass + + def only_one_network(self): + """ + Raise a warning or error? + if there are more than one network + """ + # TODO + pass + + def display_timeline(self, ax, event=False): + """ + Must be call on only one network + """ + self.only_one_network() + j = 0 + line_kw = dict( + ls="-", + marker=".", + markersize=6, + zorder=1, + lw=3, + ) + for i, b0, b1 in self.iter_on("segment"): + x = self.time[i] + if x.shape[0] == 0: + continue + y = b0 * ones(x.shape) + line = ax.plot(x, y, **line_kw, color=self.COLORS[j % self.NB_COLORS])[0] + if event: + event_kw = dict(color=line.get_color(), ls="-", zorder=1) + i_n, i_p = ( + self.next_obs[i.stop - 1], + self.previous_obs[i.start], + ) + if i_n != -1: + ax.plot( + (x[-1], self.time[i_n]), (b0, self.segment[i_n]), **event_kw + ) + ax.plot(x[-1], b0, color="k", marker=">", markersize=10, zorder=-1) + if i_p != -1: + ax.plot((x[0], self.time[i_p]), (b0, self.segment[i_p]), **event_kw) + ax.plot(x[0], b0, color="k", marker="*", markersize=12, zorder=-1) + j += 1 + + def insert_virtual(self): + pass + + class Network: __slots__ = ( "window", diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index ee9301d0..25efc744 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -144,6 +144,27 @@ class EddiesObservations(object): "height_inner_contour", ] + COLORS = [ + "sienna", + "red", + "darkorange", + "gold", + "palegreen", + "limegreen", + "forestgreen", + "mediumblue", + "dodgerblue", + "lightskyblue", + "violet", + "blueviolet", + "darkmagenta", + "darkgrey", + "dimgrey", + "steelblue", + ] + + NB_COLORS = len(COLORS) + def __init__( self, size=0, @@ -553,9 +574,9 @@ def __copy__(self): def copy(self): return self.__copy__() - @staticmethod - def new_like(eddies, new_size: int): - return eddies.__class__( + @classmethod + def new_like(cls, eddies, new_size: int): + return cls( new_size, track_extra_variables=eddies.track_extra_variables, track_array_variables=eddies.track_array_variables, diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index b30b3d05..d9f64da9 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -620,9 +620,9 @@ def split_network(self, intern=True, **kwargs): sl = slice(i_s, i_e) local_ids = ids[sl] self.set_tracks(self[xname][sl], self[yname][sl], local_ids, **kwargs) - m = local_ids["previous_obs"] == -1 + m = local_ids["previous_obs"] != -1 local_ids["previous_obs"][m] += i_s - m = local_ids["next_obs"] == -1 + m = local_ids["next_obs"] != -1 local_ids["next_obs"][m] += i_s return ids From 16691a26faa770c1cace7f32f9ed0d347f9c7086 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Fri, 15 Jan 2021 16:50:14 +0100 Subject: [PATCH 018/249] Add tools for network Add option for EddyAnim to make video --- examples/16_network/pet_relative.py | 100 ++++++++- src/py_eddy_tracker/appli/gui.py | 15 +- src/py_eddy_tracker/appli/network.py | 16 +- src/py_eddy_tracker/observations/network.py | 212 +++++++++++++++++--- 4 files changed, 305 insertions(+), 38 deletions(-) diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index 32f87b77..8ef7e661 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -23,18 +23,108 @@ # %% # Display timeline -fig = plt.figure(figsize=(15, 8)) +fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.04, 0.92, 0.92]) n.display_timeline(ax) # %% -# Display timeline with event -fig = plt.figure(figsize=(15, 8)) +# Display timeline without event +fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.04, 0.92, 0.92]) -n.display_timeline(ax, event=True) -plt.show() +n.display_timeline(ax, event=False) + +# %% +# Parameters timeline +# ------------------- +kw = dict(s=25, cmap="Spectral_r", zorder=10) +fig = plt.figure(figsize=(15, 8)) +ax = fig.add_axes([0.04, 0.54, 0.90, 0.44]) +m = n.scatter_timeline(ax, "radius_e", factor=1e-3, vmin=50, vmax=150, **kw) +cb = plt.colorbar( + m["scatter"], cax=fig.add_axes([0.95, 0.54, 0.01, 0.44]), orientation="vertical" +) +cb.set_label("Effective radius (km)") + +ax = fig.add_axes([0.04, 0.04, 0.90, 0.44]) +m = n.scatter_timeline(ax, "amplitude", factor=100, vmin=0, vmax=15, **kw) +cb = plt.colorbar( + m["scatter"], cax=fig.add_axes([0.95, 0.04, 0.01, 0.44]), orientation="vertical" +) +cb.set_label("Amplitude (cm)") + +# %% +fig = plt.figure(figsize=(15, 5)) +ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) +m = n.scatter_timeline(ax, "speed_average", factor=100, vmin=0, vmax=40, **kw) +cb = plt.colorbar( + m["scatter"], cax=fig.add_axes([0.95, 0.04, 0.01, 0.92]), orientation="vertical" +) +cb.set_label("Maximum speed (cm/s)") + +# %% +fig = plt.figure(figsize=(15, 5)) +ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) +m = n.scatter_timeline(ax, "radius_s", factor=1e-3, vmin=20, vmax=100, **kw) +cb = plt.colorbar( + m["scatter"], cax=fig.add_axes([0.95, 0.04, 0.01, 0.92]), orientation="vertical" +) +cb.set_label("Speed radius (km)") + +# %% +# Remove dead branch +# ------------------ +# Remove all tiny segment with less than N obs which didn't join two segments +# +# .. warning:: +# Must be explore, no solution to solve all the case + +n_clean = n.remove_dead_branch(nobs=51) +fig = plt.figure(figsize=(15, 8)) +ax = fig.add_axes([0.04, 0.54, 0.90, 0.40]) +ax.set_title(f"Original network ({n.infos()})") +n.display_timeline(ax) +ax = fig.add_axes([0.04, 0.04, 0.90, 0.40]) +ax.set_title(f"Clean network ({n_clean.infos()})") +_ = n_clean.display_timeline(ax) # %% # Keep close relative # ------------------- # First choose an observation in the network +fig = plt.figure(figsize=(15, 5)) +ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) +n.display_timeline(ax) +i = 1100 +obs_args = n.time[i], n.segment[i] +obs_kw = dict(color="black", markersize=30, marker=".") +_ = ax.plot(*obs_args, **obs_kw) + +# %% +fig = plt.figure(figsize=(15, 5)) +ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) +m = n.scatter_timeline( + ax, n.obs_relative_order(i), vmin=-1.5, vmax=6.5, cmap=plt.get_cmap("jet", 8), s=10 +) +ax.plot(*obs_args, **obs_kw) +cb = plt.colorbar( + m["scatter"], cax=fig.add_axes([0.95, 0.04, 0.01, 0.92]), orientation="vertical" +) +cb.set_label("Relative order") +# %% +fig = plt.figure(figsize=(15, 5)) +ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) +close_to_i = n.relative(i, order=1) +ax.set_title(f"Close segments ({close_to_i.infos()})") +_ = close_to_i.display_timeline(ax) +# %% +fig = plt.figure(figsize=(15, 5)) +ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) +close_to_i = n.relative(i, order=2) +ax.set_title(f"Close segments ({close_to_i.infos()})") +_ = close_to_i.display_timeline(ax) +# %% +fig = plt.figure(figsize=(15, 5)) +ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) +close_to_i = n.relative(i, order=3) +ax.set_title(f"Close segments ({close_to_i.infos()})") +_ = close_to_i.display_timeline(ax) diff --git a/src/py_eddy_tracker/appli/gui.py b/src/py_eddy_tracker/appli/gui.py index 16b7274c..9d09b57f 100644 --- a/src/py_eddy_tracker/appli/gui.py +++ b/src/py_eddy_tracker/appli/gui.py @@ -4,7 +4,7 @@ """ import logging -from datetime import datetime +from datetime import datetime, timedelta from itertools import chain from matplotlib import pyplot @@ -176,7 +176,7 @@ def update(self): ] ) # Update date txt and info - txt = f"{self.now}" + txt = f"{(timedelta(int(self.now)) + datetime(1950,1,1)).strftime('%Y/%m/%d')}" if self.graphic_informations: txt += f"- {1/self.sleep_event:.0f} frame/s" self.txt.set_text(txt) @@ -262,7 +262,7 @@ def anim(): parser.add_argument( "--vmax", default=None, type=float, help="Upper bound to color contour" ) - parser.add_argument("--avi", help="Filename to save animation (avi)") + parser.add_argument("--mp4", help="Filename to save animation (mp4)") args = parser.parse_args() variables = ["time", "track", "longitude", "latitude", args.field] variables.extend(TrackEddiesObservations.intern(args.intern, public_label=True)) @@ -284,6 +284,10 @@ def anim(): (eddies.contour_lon_e.T - eddies.lon + 180) % 360 + eddies.lon - 180 ).T + kw = dict() + if args.mp4: + kw["figsize"] = (16, 9) + kw["dpi"] = 120 a = Anim( eddies, intern=args.intern, @@ -293,13 +297,14 @@ def anim(): field_color=args.field, range_color=(args.vmin, args.vmax), graphic_information=logger.getEffectiveLevel() == logging.DEBUG, + **kw, ) - if args.avi is None: + if args.mp4 is None: a.show(infinity_loop=args.infinity_loop) else: kwargs = dict(frames=arange(*a.period), interval=50) ani = FuncAnimation(a.fig, a.func_animation, **kwargs) - ani.save(args.avi, fps=30, extra_args=["-vcodec", "libx264"]) + ani.save(args.mp4, fps=30, extra_args=["-vcodec", "libx264"]) def gui_parser(): diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index 8ac8582f..aa4a09cc 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -6,7 +6,7 @@ import logging from .. import EddyParser -from ..observations.network import Network +from ..observations.network import Network, NetworkObservations from ..observations.tracking import TrackEddiesObservations logger = logging.getLogger("pet") @@ -50,7 +50,13 @@ def divide_network(): args.input, include_vars=("time", "track", "latitude", "longitude", *contour_name), ) - ids = e.split_network(intern=args.intern, window=args.window, minimal_area=False) - e = e.add_fields(("segment",)) - e.segment[:] = ids["track"] - e.write_file(filename=args.out) + n = NetworkObservations.from_split_network( + e, e.split_network(intern=args.intern, window=args.window) + ) + n.write_file(filename=args.out) + + +def subsample_network(): + parser = EddyParser("Sub sample") + parser.add_argument("input", help="input network file") + parser.add_argument("out", help="output file") diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 0a1d023d..62a04ab2 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -8,6 +8,7 @@ from numba import njit from numpy import arange, array, bincount, empty, ones, uint32, unique +from ..generic import build_index from ..poly import bbox_intersection, vertice_overlap from .observation import EddiesObservations from .tracking import TrackEddiesObservations @@ -89,18 +90,75 @@ def from_split_network(cls, group_dataset, indexs, **kwargs): network.segment[:] = indexs["track"][index_order] # n & p must be re-index n, p = indexs["next_obs"][index_order], indexs["previous_obs"][index_order] - translate = empty(index_order.max() + 1, dtype="i4") + # we add 2 for -1 index return index -1 + translate = -ones(index_order.max() + 2, dtype="i4") translate[index_order] = arange(index_order.shape[0]) - m = n != -1 - n[m] = translate[n[m]] - m = p != -1 - p[m] = translate[p[m]] - network.next_obs[:] = n - network.previous_obs[:] = p + network.next_obs[:] = translate[n] + network.previous_obs[:] = translate[p] return network + def infos(self, label=""): + return f"{len(self)} obs {unique(self.segment).shape[0]} segments" + + def obs_relative_order(self, i_obs): + self.only_one_network() + return self.segment_relative_order(self.segment[i_obs]) + + def connexions(self): + self.only_one_network() + segments_connexion = dict() + + def add_seg(father, child): + if father not in segments_connexion: + segments_connexion[father] = list() + segments_connexion[father].append(child) + + for i, seg, _ in self.iter_on("segment"): + if i.start == i.stop: + continue + i_p, i_n = self.previous_obs[i.start], self.next_obs[i.stop - 1] + # segment of interaction + p_seg, n_seg = self.segment[i_p], self.segment[i_n] + # Where segment are called + if i_p != -1: + add_seg(p_seg, seg) + add_seg(seg, p_seg) + if i_n != -1: + add_seg(n_seg, seg) + add_seg(seg, n_seg) + return segments_connexion + + @classmethod + def __close_segment(cls, father, shift, connexions, distance): + i_father = father - shift + if distance[i_father] == -1: + distance[i_father] = 0 + d_target = distance[i_father] + 1 + for son in connexions.get(father, list()): + i_son = son - shift + d_son = distance[i_son] + if d_son == -1 or d_son > d_target: + distance[i_son] = d_target + else: + continue + cls.__close_segment(son, shift, connexions, distance) + + def segment_relative_order(self, seg_origine): + i_s, i_e, i_ref = build_index(self.segment) + segment_connexions = self.connexions() + relative_tr = -ones(i_s.shape, dtype="i4") + self.__close_segment(seg_origine, i_ref, segment_connexions, relative_tr) + d = -ones(self.shape) + for i0, i1, v in zip(i_s, i_e, relative_tr): + if i0 == i1: + continue + d[i0:i1] = v + return d + def relative(self, i_obs, order=2, direct=True, only_past=False, only_future=False): - pass + d = self.segment_relative_order(self.segment[i_obs]) + m = (d <= order) * (d != -1) + return self.extract_with_mask(m) def only_one_network(self): """ @@ -110,7 +168,7 @@ def only_one_network(self): # TODO pass - def display_timeline(self, ax, event=False): + def display_timeline(self, ax, event=True): """ Must be call on only one network """ @@ -123,31 +181,139 @@ def display_timeline(self, ax, event=False): zorder=1, lw=3, ) + mappables = dict(lines=list()) + if event: + mappables.update(self.event_timeline(ax)) for i, b0, b1 in self.iter_on("segment"): x = self.time[i] if x.shape[0] == 0: continue y = b0 * ones(x.shape) line = ax.plot(x, y, **line_kw, color=self.COLORS[j % self.NB_COLORS])[0] - if event: - event_kw = dict(color=line.get_color(), ls="-", zorder=1) - i_n, i_p = ( - self.next_obs[i.stop - 1], - self.previous_obs[i.start], - ) - if i_n != -1: - ax.plot( - (x[-1], self.time[i_n]), (b0, self.segment[i_n]), **event_kw - ) - ax.plot(x[-1], b0, color="k", marker=">", markersize=10, zorder=-1) - if i_p != -1: - ax.plot((x[0], self.time[i_p]), (b0, self.segment[i_p]), **event_kw) - ax.plot(x[0], b0, color="k", marker="*", markersize=12, zorder=-1) + mappables["lines"].append(line) + j += 1 + + return mappables + + def event_timeline(self, ax): + j = 0 + # TODO : fill mappables dict + mappables = dict() + for i, b0, b1 in self.iter_on("segment"): + x = self.time[i] + if x.shape[0] == 0: + continue + event_kw = dict(color=self.COLORS[j % self.NB_COLORS], ls="-", zorder=1) + i_n, i_p = ( + self.next_obs[i.stop - 1], + self.previous_obs[i.start], + ) + if i_n != -1: + ax.plot((x[-1], self.time[i_n]), (b0, self.segment[i_n]), **event_kw) + ax.plot(x[-1], b0, color="k", marker=">", markersize=10, zorder=-1) + if i_p != -1: + ax.plot((x[0], self.time[i_p]), (b0, self.segment[i_p]), **event_kw) + ax.plot(x[0], b0, color="k", marker="*", markersize=12, zorder=-1) j += 1 + return mappables + + def scatter_timeline(self, ax, name, factor=1, event=True, **kwargs): + """ + Must be call on only one network + """ + self.only_one_network() + mappables = dict() + if event: + mappables.update(self.event_timeline(ax)) + if "c" not in kwargs: + v = self.parse_varname(name) + kwargs["c"] = v * factor + mappables["scatter"] = ax.scatter(self.time, self.segment, **kwargs) + return mappables def insert_virtual(self): pass + def merging_event(self): + pass + + def spliting_event(self): + pass + + def fully_connected(self): + self.only_one_network() + + def remove_dead_branch(self, nobs=3): + """""" + # TODO: bug when spliting + self.only_one_network() + + segments_keep = list() + interaction_segments = dict() + segments_connexion = dict() + for i, b0, b1 in self.iter_on("segment"): + nb = i.stop - i.start + i_p, i_n = self.previous_obs[i.start], self.next_obs[i.stop - 1] + seg = self.segment[i.start] + # segment of interaction + p_seg, n_seg = self.segment[i_p], self.segment[i_n] + if nb >= nobs: + segments_keep.append(seg) + else: + interaction_segments[seg] = ( + p_seg if i_p != -1 else -1, + n_seg if i_n != -1 else -1, + ) + # Where segment are called + if i_p != -1: + if p_seg not in segments_connexion: + segments_connexion[p_seg] = list() + segments_connexion[p_seg].append(seg) + if i_n != -1: + if n_seg not in segments_connexion: + segments_connexion[n_seg] = list() + segments_connexion[n_seg].append(seg) + print(interaction_segments) + print(segments_connexion) + print(segments_keep) + return self.extract_segment(tuple(segments_keep)) + + def extract_segment(self, segments): + mask = ones(self.shape, dtype="bool") + for i, b0, b1 in self.iter_on("segment"): + if b0 not in segments: + mask[i] = False + return self.extract_with_mask(mask) + + def extract_with_mask(self, mask): + """ + Extract a subset of observations. + + :param array(bool) mask: mask to select observations + :return: same object with selected observations + :rtype: self + """ + nb_obs = mask.sum() + new = self.__class__.new_like(self, nb_obs) + new.sign_type = self.sign_type + if nb_obs == 0: + logger.warning("Empty dataset will be created") + else: + for field in self.obs.dtype.descr: + if field in ("next_obs", "previous_obs"): + continue + logger.debug("Copy of field %s ...", field) + var = field[0] + new.obs[var] = self.obs[var][mask] + # n & p must be re-index + n, p = self.next_obs[mask], self.previous_obs[mask] + # we add 2 for -1 index return index -1 + translate = -ones(len(self) + 1, dtype="i4") + translate[:-1][mask] = arange(nb_obs) + new.next_obs[:] = translate[n] + new.previous_obs[:] = translate[p] + return new + class Network: __slots__ = ( From 3df15b9e552273e71638b55133bf1f427db38627 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Mon, 18 Jan 2021 12:01:39 +0100 Subject: [PATCH 019/249] Add method to list merging/spliting event from network --- examples/16_network/pet_relative.py | 51 +++++++++++--- src/py_eddy_tracker/observations/network.py | 74 ++++++++++++++++++++- 2 files changed, 113 insertions(+), 12 deletions(-) diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index 8ef7e661..51402ba4 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -15,6 +15,11 @@ # --------- # 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 +############## n = NetworkObservations.from_split_network(e, e.split_network(intern=False, window=5)) # %% @@ -113,18 +118,46 @@ # %% fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) -close_to_i = n.relative(i, order=1) -ax.set_title(f"Close segments ({close_to_i.infos()})") -_ = close_to_i.display_timeline(ax) +close_to_i1 = n.relative(i, order=1) +ax.set_title(f"Close segments ({close_to_i1.infos()})") +_ = close_to_i1.display_timeline(ax) # %% fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) -close_to_i = n.relative(i, order=2) -ax.set_title(f"Close segments ({close_to_i.infos()})") -_ = close_to_i.display_timeline(ax) +close_to_i2 = n.relative(i, order=2) +ax.set_title(f"Close segments ({close_to_i2.infos()})") +_ = close_to_i2.display_timeline(ax) # %% fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) -close_to_i = n.relative(i, order=3) -ax.set_title(f"Close segments ({close_to_i.infos()})") -_ = close_to_i.display_timeline(ax) +close_to_i3 = n.relative(i, order=3) +ax.set_title(f"Close segments ({close_to_i3.infos()})") +_ = close_to_i3.display_timeline(ax) + +# %% +# Display track on map +# -------------------- +fig = plt.figure(figsize=(15, 8)) +ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") +close_to_i2.plot(ax) +_ = ax.set_xlim(-10, 20), ax.set_ylim(-37, -21), ax.grid() + +# %% +# Get merging event +# ----------------- +fig = plt.figure(figsize=(15, 8)) +ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") +merging = close_to_i2.merging_event() +merging.display(ax) +ax.set_xlim(-10, 20), ax.set_ylim(-37, -21), ax.grid() +merging + +# %% +# Get spliting event +# ------------------ +fig = plt.figure(figsize=(15, 8)) +ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") +spliting = close_to_i2.spliting_event() +spliting.display(ax) +ax.set_xlim(-10, 20), ax.set_ylim(-37, -21), ax.grid() +spliting diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 62a04ab2..b23bf0d3 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -8,7 +8,7 @@ from numba import njit from numpy import arange, array, bincount, empty, ones, uint32, unique -from ..generic import build_index +from ..generic import build_index, wrap_longitude from ..poly import bbox_intersection, vertice_overlap from .observation import EddiesObservations from .tracking import TrackEddiesObservations @@ -232,16 +232,84 @@ def scatter_timeline(self, ax, name, factor=1, event=True, **kwargs): return mappables def insert_virtual(self): + # TODO pass def merging_event(self): - pass + indices = list() + for i, b0, b1 in self.iter_on("segment"): + nb = i.stop - i.start + if nb == 0: + continue + i_n = self.next_obs[i.stop - 1] + if i_n != -1: + indices.append(i.stop - 1) + indices = list(set(indices)) + nb = len(indices) + new = EddiesObservations( + nb, + track_extra_variables=self.track_extra_variables, + track_array_variables=self.track_array_variables, + array_variables=self.array_variables, + only_variables=self.only_variables, + raw_data=self.raw_data, + ) + + for k in new.obs.dtype.names: + new[k][:] = self[k][indices] + new.sign_type = self.sign_type + return new def spliting_event(self): - pass + indices = list() + for i, b0, b1 in self.iter_on("segment"): + nb = i.stop - i.start + if nb == 0: + continue + i_p = self.previous_obs[i.start] + if i_p != -1: + indices.append(i.start) + indices = list(set(indices)) + nb = len(indices) + new = EddiesObservations( + nb, + track_extra_variables=self.track_extra_variables, + track_array_variables=self.track_array_variables, + array_variables=self.array_variables, + only_variables=self.only_variables, + raw_data=self.raw_data, + ) + + for k in new.obs.dtype.names: + new[k][:] = self[k][indices] + new.sign_type = self.sign_type + return new def fully_connected(self): self.only_one_network() + # TODO + + def plot(self, ax, ref=None, **kwargs): + """ + This function will draw path of each trajectory + + :param matplotlib.axes.Axes ax: ax to draw + :param float,int ref: if defined, all coordinates will be wrapped with ref like west boundary + :param dict kwargs: keyword arguments for Axes.plot + :return: a list of matplotlib mappables + """ + mappables = list() + if "label" in kwargs: + kwargs["label"] = self.format_label(kwargs["label"]) + for i, b0, b1 in self.iter_on("segment"): + nb = i.stop - i.start + if nb == 0: + continue + x, y = self.lon[i], self.lat[i] + if ref is not None: + x, y = wrap_longitude(x, y, ref, cut=True) + mappables.append(ax.plot(x, y, **kwargs)[0]) + return mappables def remove_dead_branch(self, nobs=3): """""" From 493aed8c367e53c430095bf0d784500d1041db8e Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 19 Jan 2021 15:16:55 +0100 Subject: [PATCH 020/249] add new method for network --- examples/16_network/pet_relative.py | 62 +++++++- src/py_eddy_tracker/observations/network.py | 154 ++++++++++++++----- src/py_eddy_tracker/observations/tracking.py | 15 +- 3 files changed, 182 insertions(+), 49 deletions(-) diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index 51402ba4..d48c4f03 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -4,9 +4,12 @@ """ from matplotlib import pyplot as plt +from matplotlib.animation import FuncAnimation +from numpy import arange import py_eddy_tracker.gui from py_eddy_tracker import data +from py_eddy_tracker.appli.gui import Anim from py_eddy_tracker.observations.network import NetworkObservations from py_eddy_tracker.observations.tracking import TrackEddiesObservations @@ -30,13 +33,41 @@ # Display timeline fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.04, 0.92, 0.92]) -n.display_timeline(ax) +_ = n.display_timeline(ax) # %% # Display timeline without event fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.04, 0.92, 0.92]) -n.display_timeline(ax, event=False) +_ = n.display_timeline(ax, event=False) + +# %% +# Timeline by latitude mean +# ------------------------- +fig = plt.figure(figsize=(15, 5)) +ax = fig.add_axes([0.04, 0.04, 0.92, 0.92]) +_ = n.display_timeline(ax, field="latitude") + +# %% +# Timeline by radius mean +# ----------------------- +fig = plt.figure(figsize=(15, 5)) +ax = fig.add_axes([0.04, 0.04, 0.92, 0.92]) +_ = n.display_timeline(ax, field="radius_e") + +# %% +# Timeline by latitude +# -------------------- +fig = plt.figure(figsize=(15, 5)) +ax = fig.add_axes([0.04, 0.05, 0.92, 0.92]) +_ = n.display_timeline(ax, field="lat", method="all") + +# %% +fig = plt.figure(figsize=(15, 5)) +ax = fig.add_axes([0.04, 0.05, 0.92, 0.92]) +n_copy = n.copy() +n_copy.median_filter(15, "time", "latitude") +_ = n_copy.display_timeline(ax, field="lat", method="all") # %% # Parameters timeline @@ -138,9 +169,12 @@ # Display track on map # -------------------- fig = plt.figure(figsize=(15, 8)) -ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") +ax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection="full_axes") close_to_i2.plot(ax) -_ = ax.set_xlim(-10, 20), ax.set_ylim(-37, -21), ax.grid() +ax.set_xlim(-13, 20), ax.set_ylim(-36.5, -20), ax.grid() +ax = fig.add_axes([0.08, 0.67, 0.55, 0.3]) +_ = close_to_i2.display_timeline(ax, field="latitude") + # %% # Get merging event @@ -161,3 +195,23 @@ spliting.display(ax) ax.set_xlim(-10, 20), ax.set_ylim(-37, -21), ax.grid() spliting + +# %% +# Get birth event +# ------------------ +fig = plt.figure(figsize=(15, 8)) +ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") +birth = close_to_i2.birth_event() +birth.display(ax) +ax.set_xlim(-10, 20), ax.set_ylim(-37, -21), ax.grid() +birth + +# %% +# Get death event +# ------------------ +fig = plt.figure(figsize=(15, 8)) +ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") +death = close_to_i2.death_event() +death.display(ax) +ax.set_xlim(-10, 20), ax.set_ylim(-37, -21), ax.grid() +death diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index b23bf0d3..c97dd92d 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -11,7 +11,7 @@ from ..generic import build_index, wrap_longitude from ..poly import bbox_intersection, vertice_overlap from .observation import EddiesObservations -from .tracking import TrackEddiesObservations +from .tracking import TrackEddiesObservations, track_median_filter logger = logging.getLogger("pet") @@ -168,7 +168,17 @@ def only_one_network(self): # TODO pass - def display_timeline(self, ax, event=True): + def median_filter(self, half_window, xfield, yfield, inplace=True): + # FIXME: segments is not enough with several network + result = track_median_filter( + half_window, self[xfield], self[yfield], self.segment + ) + if inplace: + self[yfield][:] = result + return self + return result + + def display_timeline(self, ax, event=True, field=None, method=None): """ Must be call on only one network """ @@ -183,21 +193,33 @@ def display_timeline(self, ax, event=True): ) mappables = dict(lines=list()) if event: - mappables.update(self.event_timeline(ax)) + mappables.update(self.event_timeline(ax, field=field, method=method)) for i, b0, b1 in self.iter_on("segment"): x = self.time[i] if x.shape[0] == 0: continue - y = b0 * ones(x.shape) + if field is None: + y = b0 * ones(x.shape) + else: + if method == "all": + y = self[field][i] + else: + y = self[field][i].mean() * ones(x.shape) line = ax.plot(x, y, **line_kw, color=self.COLORS[j % self.NB_COLORS])[0] mappables["lines"].append(line) j += 1 return mappables - def event_timeline(self, ax): + def event_timeline(self, ax, field=None, method=None): j = 0 # TODO : fill mappables dict + y_seg = dict() + if field is not None and method != "all": + for i, b0, _ in self.iter_on("segment"): + y = self[field][i] + if y.shape[0] != 0: + y_seg[b0] = y.mean() mappables = dict() for i, b0, b1 in self.iter_on("segment"): x = self.time[i] @@ -208,12 +230,33 @@ def event_timeline(self, ax): self.next_obs[i.stop - 1], self.previous_obs[i.start], ) + if field is None: + y0 = b0 + else: + if method == "all": + y0 = self[field][i.stop - 1] + else: + y0 = y_seg[b0] if i_n != -1: - ax.plot((x[-1], self.time[i_n]), (b0, self.segment[i_n]), **event_kw) - ax.plot(x[-1], b0, color="k", marker=">", markersize=10, zorder=-1) + seg_next = self.segment[i_n] + y1 = ( + seg_next + if field is None + else (self[field][i_n] if method == "all" else y_seg[seg_next]) + ) + ax.plot((x[-1], self.time[i_n]), (y0, y1), **event_kw)[0] + ax.plot(x[-1], y0, color="k", marker=">", markersize=10, zorder=-1)[0] if i_p != -1: - ax.plot((x[0], self.time[i_p]), (b0, self.segment[i_p]), **event_kw) - ax.plot(x[0], b0, color="k", marker="*", markersize=12, zorder=-1) + seg_previous = self.segment[i_p] + if field is not None and method == "all": + y0 = self[field][i.start] + y1 = ( + seg_previous + if field is None + else (self[field][i_p] if method == "all" else y_seg[seg_previous]) + ) + ax.plot((x[0], self.time[i_p]), (y0, y1), **event_kw)[0] + ax.plot(x[0], y0, color="k", marker="*", markersize=12, zorder=-1)[0] j += 1 return mappables @@ -235,16 +278,7 @@ def insert_virtual(self): # TODO pass - def merging_event(self): - indices = list() - for i, b0, b1 in self.iter_on("segment"): - nb = i.stop - i.start - if nb == 0: - continue - i_n = self.next_obs[i.stop - 1] - if i_n != -1: - indices.append(i.stop - 1) - indices = list(set(indices)) + def extract_event(self, indices): nb = len(indices) new = EddiesObservations( nb, @@ -260,30 +294,54 @@ def merging_event(self): new.sign_type = self.sign_type return new + def segment_track_array(self): + return build_unique_array(self.segment, self.track) + + def birth_event(self): + # FIXME how to manage group 0 + indices = list() + for i, b0, b1 in self.iter_on(self.segment_track_array()): + nb = i.stop - i.start + if nb == 0: + continue + i_p = self.previous_obs[i.start] + if i_p == -1: + indices.append(i.start) + return self.extract_event(list(set(indices))) + + def death_event(self): + # FIXME how to manage group 0 + indices = list() + for i, b0, b1 in self.iter_on(self.segment_track_array()): + nb = i.stop - i.start + if nb == 0: + continue + i_n = self.next_obs[i.stop - 1] + if i_n == -1: + indices.append(i.stop - 1) + return self.extract_event(list(set(indices))) + + def merging_event(self): + indices = list() + for i, b0, b1 in self.iter_on(self.segment_track_array()): + nb = i.stop - i.start + if nb == 0: + continue + i_n = self.next_obs[i.stop - 1] + if i_n != -1: + indices.append(i.stop - 1) + return self.extract_event(list(set(indices))) + def spliting_event(self): indices = list() - for i, b0, b1 in self.iter_on("segment"): + for i, b0, b1 in self.iter_on(self.segment_track_array()): nb = i.stop - i.start if nb == 0: continue i_p = self.previous_obs[i.start] if i_p != -1: indices.append(i.start) - indices = list(set(indices)) - nb = len(indices) - new = EddiesObservations( - nb, - track_extra_variables=self.track_extra_variables, - track_array_variables=self.track_array_variables, - array_variables=self.array_variables, - only_variables=self.only_variables, - raw_data=self.raw_data, - ) - - for k in new.obs.dtype.names: - new[k][:] = self[k][indices] - new.sign_type = self.sign_type - return new + return self.extract_event(list(set(indices))) def fully_connected(self): self.only_one_network() @@ -463,14 +521,16 @@ def group_observations(self, **kwargs): print() gr = self.get_group_array(results, nb_obs) + nb_alone, nb_obs, nb_gr = (gr == self.NOGROUP).sum(), len(gr), len(unique(gr)) logger.info( - f"{(gr == self.NOGROUP).sum()} alone / {len(gr)} obs, {len(unique(gr))} groups" + f"{nb_alone} alone / {nb_obs} obs, {nb_gr} groups, " + f"{nb_alone *100./nb_obs:.2f} % alone, {(nb_obs - nb_alone) / (nb_gr - 1):.1f} obs/group" ) return gr def build_dataset(self, group): nb_obs = group.shape[0] - model = EddiesObservations.load_file(self.filenames[-1], raw_data=True) + model = TrackEddiesObservations.load_file(self.filenames[-1], raw_data=True) eddies = TrackEddiesObservations.new_like(model, nb_obs) eddies.sign_type = model.sign_type # Get new index to re-order observation by group @@ -485,9 +545,9 @@ def build_dataset(self, group): if self.memory: # Only if netcdf with open(filename, "rb") as h: - e = EddiesObservations.load_file(h, raw_data=True) + e = TrackEddiesObservations.load_file(h, raw_data=True) else: - e = EddiesObservations.load_file(filename, raw_data=True) + e = TrackEddiesObservations.load_file(filename, raw_data=True) stop = i + len(e) sl = slice(i, stop) for element in elements: @@ -495,7 +555,6 @@ def build_dataset(self, group): i = stop if display_iteration: print() - eddies = eddies.add_fields(("track",)) eddies.track[new_i] = group return eddies @@ -518,3 +577,18 @@ def apply_replace(x, x0, x1): for i in range(nb): if x[i] == x0: x[i] = x1 + + +@njit(cache=True) +def build_unique_array(id1, id2): + k = 0 + new_id = empty(id1.shape, dtype=id1.dtype) + id1_previous = id1[0] + id2_previous = id2[0] + for i in range(id1.shape[0]): + id1_, id2_ = id1[i], id2[i] + if id1_ != id1_previous or id2_ != id2_previous: + k += 1 + new_id[i] = k + id1_previous, id2_previous = id1_, id2_ + return new_id diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index 7113c324..c7d61659 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -432,13 +432,13 @@ def loess_filter(self, half_window, xfield, yfield, inplace=True): return self def median_filter(self, half_window, xfield, yfield, inplace=True): - track = self.track - x = self.obs[xfield] - y = self.obs[yfield] - result = track_median_filter(half_window, x, y, track) + result = track_median_filter( + half_window, self[xfield], self[yfield], self.track + ) if inplace: - self.obs[yfield] = result + self[yfield][:] = result return self + return result def position_filter(self, median_half_window, loess_half_window): self.median_filter(median_half_window, "time", "lon").loess_filter( @@ -620,9 +620,12 @@ def split_network(self, intern=True, **kwargs): # and ids["next_obs"] == -1 means the end of a non-merged segment xname, yname = self.intern(intern) + display_iteration = logger.getEffectiveLevel() == logging.INFO for i_s, i_e in zip(track_s, track_e): if i_s == i_e or self.tracks[i_s] == self.NOGROUP: continue + if display_iteration: + print(f"Network obs from {i_s} to {i_e} on {track_e[-1]}", end="\r") sl = slice(i_s, i_e) local_ids = ids[sl] # built segments with local indices @@ -632,6 +635,8 @@ def split_network(self, intern=True, **kwargs): local_ids["previous_obs"][m] += i_s m = local_ids["next_obs"] != -1 local_ids["next_obs"][m] += i_s + if display_iteration: + print() return ids def set_tracks(self, x, y, ids, window, **kwargs): From 8499085c701806a72406379b7926a32356271e67 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Thu, 21 Jan 2021 18:15:38 +0100 Subject: [PATCH 021/249] Remove unused property --- src/py_eddy_tracker/dataset/grid.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index e07e32a0..4f427d63 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -249,8 +249,6 @@ class GridDataset(object): "x_bounds", "y_bounds", "centered", - "xinterp", - "yinterp", "x_dim", "y_dim", "coordinates", @@ -293,8 +291,6 @@ def __init__( self.y_dim = None self.centered = centered self.contours = None - self.xinterp = None - self.yinterp = None self.filename = filename self.coordinates = x_name, y_name self.vars = dict() @@ -399,7 +395,6 @@ def load(self): self.vars[y_name] = h.variables[y_name][sl_y] self.setup_coordinates() - self.init_pos_interpolator() @staticmethod def c_to_bounds(c): @@ -1189,11 +1184,6 @@ def with_array(cls, coordinates, datas, variables_description=None, **kwargs): obj.setup_coordinates() return obj - def init_pos_interpolator(self): - """Create function to have a quick index interpolator""" - self.xinterp = arange(self.x_bounds.shape[0]) - self.yinterp = arange(self.y_bounds.shape[0]) - def bbox_indice(self, vertices): return bbox_indice_regular( vertices, From 977236f868773523d4252fd6cca26ce7018a354f Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Thu, 21 Jan 2021 18:21:10 +0100 Subject: [PATCH 022/249] Add method to get contour which contains x,y observations --- CHANGELOG.rst | 1 + .../observations/observation.py | 42 ++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c25d1765..edc8eed7 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -21,6 +21,7 @@ Added - Add **EddyQuickCompare** to have few figures about several datasets in comparison based on match function - Color field for contour in **EddyAnim** could be choose - Save EddyAnim in mp4 +- Add method to get eddy contour which enclosed obs defined with (x,y) coordinates [3.3.0] - 2020-12-03 -------------------- diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 25efc744..c376dc5e 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -363,7 +363,7 @@ def add_fields(self, fields=list(), array_fields=list()): def add_rotation_type(self): new = self.add_fields(("type_cyc",)) - new.type_cyc = self.sign_type + new.type_cyc[:] = self.sign_type return new def circle_contour(self, only_virtual=False): @@ -1905,6 +1905,19 @@ def is_convex(self, intern=False): xname, yname = self.intern(intern) return convexs(self[xname], self[yname]) + def contains(self, x, y, intern=False): + """ + Return index of contour which contain (x,y) + + :param array x: longitude + :param array y: latitude + :param bool intern: If true use speed contour instead of effective contour + :return: indexs, -1 if no index + :rtype: array[int32] + """ + xname, yname = self.intern(intern) + return poly_indexs(x, y, self[xname], self[yname]) + def inside(self, x, y, intern=False): """ True for each point inside the effective contour of an eddy @@ -2181,6 +2194,33 @@ def grid_count_pixel_in( grid_count_(grid, i, j) +@njit(cache=True) +def poly_indexs(x_p, y_p, x_c, y_c): + """ + index of contour for each postion inside a contour, -1 in case of no contour + + :param array x_p: longitude to test + :param array y_p: latitude to test + :param array x_c: longitude of contours + :param array y_c: latitude of contours + """ + nb_p = x_p.shape[0] + nb_c = x_c.shape[0] + indexs = -ones(nb_p, dtype=numba_types.int32) + for i in range(nb_c): + x_c_min, y_c_min = x_c[i].min(), y_c[i].min() + x_c_max, y_c_max = x_c[i].max(), y_c[i].max() + v = create_vertice(x_c[i], y_c[i]) + for j in range(nb_p): + if indexs[j] != -1: + continue + x, y = x_p[j], y_p[j] + if x > x_c_min and x < x_c_max and y > y_c_min and y < y_c_max: + if winding_number_poly(x, y, v) != 0: + indexs[j] = i + return indexs + + @njit(cache=True) def insidepoly(x_p, y_p, x_c, y_c): """ From 23a5ccade9c1b9ff7d622594e0e1f3ca89b6c660 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Fri, 22 Jan 2021 18:11:54 +0100 Subject: [PATCH 023/249] Change how to normalize longitude after tracking --- CHANGELOG.rst | 5 +++ src/py_eddy_tracker/appli/eddies.py | 2 ++ src/py_eddy_tracker/observations/tracking.py | 36 ++++++++++++++------ 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index edc8eed7..f0cfcda0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -9,6 +9,11 @@ and this project adheres to `Semantic Versioning = nb_min From edc832bf4a09ec1cd9da6e147dfdd7f687892f72 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 26 Jan 2021 21:45:28 +0100 Subject: [PATCH 024/249] Minor correction --- .../02_eddy_identification/pet_eddy_detection.py | 12 ++++++------ examples/16_network/pet_relative.py | 4 ---- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/examples/02_eddy_identification/pet_eddy_detection.py b/examples/02_eddy_identification/pet_eddy_detection.py index 522ad4a0..d4f7848a 100644 --- a/examples/02_eddy_identification/pet_eddy_detection.py +++ b/examples/02_eddy_identification/pet_eddy_detection.py @@ -91,12 +91,12 @@ def update_axes(ax, mappable=None): update_axes(ax) # %% -# Criteria for rejecting a contour -# 0. - Accepted (green) -# 1. - Rejection for shape error (red) -# 2. - Masked value within contour (blue) -# 3. - Under or over the pixel limit bounds (black) -# 4. - Amplitude criterion (yellow) +# Criteria for rejecting a contour: +# 0. - Accepted (green) +# 1. - Rejection for shape error (red) +# 2. - Masked value within contour (blue) +# 3. - Under or over the pixel limit bounds (black) +# 4. - Amplitude criterion (yellow) ax = start_axes("Contours' rejection criteria") g.contours.display(ax, only_unused=True, lw=0.5, display_criterion=True) update_axes(ax) diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index d48c4f03..e4b72875 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -4,12 +4,8 @@ """ from matplotlib import pyplot as plt -from matplotlib.animation import FuncAnimation -from numpy import arange -import py_eddy_tracker.gui from py_eddy_tracker import data -from py_eddy_tracker.appli.gui import Anim from py_eddy_tracker.observations.network import NetworkObservations from py_eddy_tracker.observations.tracking import TrackEddiesObservations From cbf1267e6351b62139d781d436772f906c1b2ff9 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 26 Jan 2021 21:47:25 +0100 Subject: [PATCH 025/249] Choose txt field for anim --- src/py_eddy_tracker/appli/gui.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/py_eddy_tracker/appli/gui.py b/src/py_eddy_tracker/appli/gui.py index 9d09b57f..bbe5067c 100644 --- a/src/py_eddy_tracker/appli/gui.py +++ b/src/py_eddy_tracker/appli/gui.py @@ -34,6 +34,7 @@ def __init__( self.sleep_event = sleep_event self.mappables = list() self.field_color = None + self.field_txt = None self.time_field = False self.setup(**kwargs) @@ -42,12 +43,14 @@ def setup( cmap="jet", lut=None, field_color="time", + field_txt="track", range_color=(None, None), nb_step=25, figsize=(8, 6), **kwargs, ): self.field_color = self.eddy[field_color].astype("f4") + self.field_txt = self.eddy[field_txt] rg = range_color if rg[0] is None and rg[1] is None and field_color == "time": self.time_field = True @@ -183,7 +186,7 @@ def update(self): # Update id txt for i in where(m)[0]: mappable = self.ax.text( - self.x_core[i], self.y_core[i], self.track[i], fontsize=8 + self.x_core[i], self.y_core[i], self.field_txt[i], fontsize=8 ) self.mappables.append(mappable) self.ax.draw_artist(mappable) From 1a2dcb40423dc279cbae5982ceae44223f701bb2 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 26 Jan 2021 21:47:54 +0100 Subject: [PATCH 026/249] Add a subsetter for network --- setup.py | 1 + src/py_eddy_tracker/appli/network.py | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 497ec90b..06432bd1 100644 --- a/setup.py +++ b/setup.py @@ -47,6 +47,7 @@ # network "EddyNetworkGroup = py_eddy_tracker.appli.network:build_network", "EddyNetworkBuildPath = py_eddy_tracker.appli.network:divide_network", + "EddyNetworkSubSetter = py_eddy_tracker.appli.network:subset_network", # anim/gui "EddyAnim = py_eddy_tracker.appli.gui:anim", "GUIEddy = py_eddy_tracker.appli.gui:guieddy", diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index aa4a09cc..4236875c 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -56,7 +56,24 @@ def divide_network(): n.write_file(filename=args.out) -def subsample_network(): - parser = EddyParser("Sub sample") +def subset_network(): + parser = EddyParser("Subset network") parser.add_argument("input", help="input network file") parser.add_argument("out", help="output file") + parser.add_argument( + "--inverse_selection", + action="store_true", + help="Extract the inverse of selection", + ) + parser.add_argument( + "-l", + "--length", + nargs=2, + type=int, + help="Nb of day which must be cover by network, first minimum number of day and last maximum number of day," + "if value is negative, this bound won't be used", + ) + args = parser.parse_args() + n = NetworkObservations.load_file(args.input) + n = n.longer_than(*args.length) + n.write_file(filename=args.out) From 196d431ce65eec1aba8b605bba68194af883d83c Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 26 Jan 2021 21:48:32 +0100 Subject: [PATCH 027/249] Segmentation of network will provide a full dataset --- CHANGELOG.rst | 2 +- src/py_eddy_tracker/appli/network.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f0cfcda0..41ad93a2 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -24,7 +24,7 @@ Added - Add a filter option in EddyId to be able to remove fine scale (like noise) with same filter order than high scale filter - Add **EddyQuickCompare** to have few figures about several datasets in comparison based on match function -- Color field for contour in **EddyAnim** could be choose +- Color and text field for contour in **EddyAnim** could be choose - Save EddyAnim in mp4 - Add method to get eddy contour which enclosed obs defined with (x,y) coordinates diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index 4236875c..35c86c45 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -51,7 +51,8 @@ def divide_network(): include_vars=("time", "track", "latitude", "longitude", *contour_name), ) n = NetworkObservations.from_split_network( - e, e.split_network(intern=args.intern, window=args.window) + TrackEddiesObservations.load_file(args.input, raw_data=True), + e.split_network(intern=args.intern, window=args.window), ) n.write_file(filename=args.out) From 9eea12019303e4a79ad1ca4f12d9e8bef9454054 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 26 Jan 2021 21:50:48 +0100 Subject: [PATCH 028/249] - filter on each segment of network - factor could be apply on timeline - new numbering of segment - extract network greater than X days --- CHANGELOG.rst | 1 + src/py_eddy_tracker/observations/network.py | 107 ++++++++++++++++---- 2 files changed, 90 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 41ad93a2..0b1a100c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -27,6 +27,7 @@ Added - Color and text field for contour in **EddyAnim** could be choose - Save EddyAnim in mp4 - Add method to get eddy contour which enclosed obs defined with (x,y) coordinates +- Add **EddyNetworkSubSetter** to subset network which need special tool and operation after subset [3.3.0] - 2020-12-03 -------------------- diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index c97dd92d..8b7e4e2b 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -6,12 +6,12 @@ from glob import glob from numba import njit -from numpy import arange, array, bincount, empty, ones, uint32, unique +from numpy import arange, array, bincount, empty, ones, uint32, unique, zeros from ..generic import build_index, wrap_longitude from ..poly import bbox_intersection, vertice_overlap from .observation import EddiesObservations -from .tracking import TrackEddiesObservations, track_median_filter +from .tracking import TrackEddiesObservations, track_loess_filter, track_median_filter logger = logging.getLogger("pet") @@ -71,6 +71,26 @@ def elements(self): elements.extend(["track", "segment", "next_obs", "previous_obs"]) return list(set(elements)) + def longer_than(self, nb_day_min=-1, nb_day_max=-1): + """ + Select network on time duration + + :param int nb_day_min: Minimal number of day which must be covered by one network, if negative -> not used + :param int nb_day_max: Maximal number of day which must be covered by one network, if negative -> not used + """ + if nb_day_max < 0: + nb_day_max = 1000000000000 + mask = zeros(self.shape, dtype="bool") + for i, b0, b1 in self.iter_on(self.segment_track_array()): + nb = i.stop - i.start + if nb == 0: + continue + t = self.time[i] + dt = t.max() - t.min() + if nb_day_min <= dt <= nb_day_max: + mask[i] = True + return self.extract_with_mask(mask) + @classmethod def from_split_network(cls, group_dataset, indexs, **kwargs): """ @@ -160,6 +180,13 @@ def relative(self, i_obs, order=2, direct=True, only_past=False, only_future=Fal m = (d <= order) * (d != -1) return self.extract_with_mask(m) + def numbering_segment(self): + """ + New numbering of segment + """ + for i, _, _ in self.iter_on("track"): + new_numbering(self.segment[i]) + def only_one_network(self): """ Raise a warning or error? @@ -168,17 +195,35 @@ def only_one_network(self): # TODO pass + def position_filter(self, median_half_window, loess_half_window): + self.median_filter(median_half_window, "time", "lon").loess_filter( + loess_half_window, "time", "lon" + ) + self.median_filter(median_half_window, "time", "lat").loess_filter( + loess_half_window, "time", "lat" + ) + + def loess_filter(self, half_window, xfield, yfield, inplace=True): + result = track_loess_filter( + half_window, self.obs[xfield], self.obs[yfield], self.segment_track_array() + ) + if inplace: + self.obs[yfield] = result + return self + return result + def median_filter(self, half_window, xfield, yfield, inplace=True): - # FIXME: segments is not enough with several network result = track_median_filter( - half_window, self[xfield], self[yfield], self.segment + half_window, self[xfield], self[yfield], self.segment_track_array() ) if inplace: self[yfield][:] = result return self return result - def display_timeline(self, ax, event=True, field=None, method=None): + def display_timeline( + self, ax, event=True, field=None, method=None, factor=1, **kwargs + ): """ Must be call on only one network """ @@ -191,9 +236,12 @@ def display_timeline(self, ax, event=True, field=None, method=None): zorder=1, lw=3, ) + line_kw.update(kwargs) mappables = dict(lines=list()) if event: - mappables.update(self.event_timeline(ax, field=field, method=method)) + mappables.update( + self.event_timeline(ax, field=field, method=method, factor=factor) + ) for i, b0, b1 in self.iter_on("segment"): x = self.time[i] if x.shape[0] == 0: @@ -202,16 +250,16 @@ def display_timeline(self, ax, event=True, field=None, method=None): y = b0 * ones(x.shape) else: if method == "all": - y = self[field][i] + y = self[field][i] * factor else: - y = self[field][i].mean() * ones(x.shape) + y = self[field][i].mean() * ones(x.shape) * factor line = ax.plot(x, y, **line_kw, color=self.COLORS[j % self.NB_COLORS])[0] mappables["lines"].append(line) j += 1 return mappables - def event_timeline(self, ax, field=None, method=None): + def event_timeline(self, ax, field=None, method=None, factor=1): j = 0 # TODO : fill mappables dict y_seg = dict() @@ -219,7 +267,7 @@ def event_timeline(self, ax, field=None, method=None): for i, b0, _ in self.iter_on("segment"): y = self[field][i] if y.shape[0] != 0: - y_seg[b0] = y.mean() + y_seg[b0] = y.mean() * factor mappables = dict() for i, b0, b1 in self.iter_on("segment"): x = self.time[i] @@ -234,7 +282,7 @@ def event_timeline(self, ax, field=None, method=None): y0 = b0 else: if method == "all": - y0 = self[field][i.stop - 1] + y0 = self[field][i.stop - 1] * factor else: y0 = y_seg[b0] if i_n != -1: @@ -242,18 +290,26 @@ def event_timeline(self, ax, field=None, method=None): y1 = ( seg_next if field is None - else (self[field][i_n] if method == "all" else y_seg[seg_next]) + else ( + self[field][i_n] * factor + if method == "all" + else y_seg[seg_next] + ) ) ax.plot((x[-1], self.time[i_n]), (y0, y1), **event_kw)[0] ax.plot(x[-1], y0, color="k", marker=">", markersize=10, zorder=-1)[0] if i_p != -1: seg_previous = self.segment[i_p] if field is not None and method == "all": - y0 = self[field][i.start] + y0 = self[field][i.start] * factor y1 = ( seg_previous if field is None - else (self[field][i_p] if method == "all" else y_seg[seg_previous]) + else ( + self[field][i_p] * factor + if method == "all" + else y_seg[seg_previous] + ) ) ax.plot((x[0], self.time[i_p]), (y0, y1), **event_kw)[0] ax.plot(x[0], y0, color="k", marker="*", markersize=12, zorder=-1)[0] @@ -300,7 +356,7 @@ def segment_track_array(self): def birth_event(self): # FIXME how to manage group 0 indices = list() - for i, b0, b1 in self.iter_on(self.segment_track_array()): + for i, _, _ in self.iter_on(self.segment_track_array()): nb = i.stop - i.start if nb == 0: continue @@ -312,7 +368,7 @@ def birth_event(self): def death_event(self): # FIXME how to manage group 0 indices = list() - for i, b0, b1 in self.iter_on(self.segment_track_array()): + for i, _, _ in self.iter_on(self.segment_track_array()): nb = i.stop - i.start if nb == 0: continue @@ -323,7 +379,7 @@ def death_event(self): def merging_event(self): indices = list() - for i, b0, b1 in self.iter_on(self.segment_track_array()): + for i, _, _ in self.iter_on(self.segment_track_array()): nb = i.stop - i.start if nb == 0: continue @@ -334,7 +390,7 @@ def merging_event(self): def spliting_event(self): indices = list() - for i, b0, b1 in self.iter_on(self.segment_track_array()): + for i, _, _ in self.iter_on(self.segment_track_array()): nb = i.stop - i.start if nb == 0: continue @@ -425,6 +481,9 @@ def extract_with_mask(self, mask): if nb_obs == 0: logger.warning("Empty dataset will be created") else: + logger.info( + f"{nb_obs} observations will be extract ({nb_obs * 100. / self.shape[0]}%)" + ) for field in self.obs.dtype.descr: if field in ("next_obs", "previous_obs"): continue @@ -592,3 +651,15 @@ def build_unique_array(id1, id2): new_id[i] = k id1_previous, id2_previous = id1_, id2_ return new_id + + +@njit(cache=True) +def new_numbering(segs): + nb = len(segs) + s0 = segs[0] + j = 0 + for i in range(nb): + if segs[i] != s0: + s0 = segs[i] + j += 1 + segs[i] = j From 7977d6d5b1c94c30ff155a382f2e00e975581daa Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 26 Jan 2021 21:58:59 +0100 Subject: [PATCH 029/249] Add new example for network --- examples/16_network/pet_atlas.py | 144 +++++++++++++++ examples/16_network/pet_ioannou_2017_case.py | 174 +++++++++++++++++++ 2 files changed, 318 insertions(+) create mode 100644 examples/16_network/pet_atlas.py create mode 100644 examples/16_network/pet_ioannou_2017_case.py diff --git a/examples/16_network/pet_atlas.py b/examples/16_network/pet_atlas.py new file mode 100644 index 00000000..7fb3afd1 --- /dev/null +++ b/examples/16_network/pet_atlas.py @@ -0,0 +1,144 @@ +""" +Network analyse +=============== +""" +from matplotlib import pyplot as plt +from numpy import ma + +import py_eddy_tracker.gui +from py_eddy_tracker.observations.network import NetworkObservations + +n = NetworkObservations.load_file( + "/data/adelepoulle/work/Eddies/20201217_network_build/tracking/med/Anticyclonic_seg.nc" +) + +# %% +# Parameters +step = 1 / 10.0 +bins = ((-10, 37, step), (30, 46, step)) +kw_time = dict(cmap="terrain_r", factor=100.0 / n.nb_days, name="count") +kw_ratio = dict(cmap=plt.get_cmap("coolwarm_r", 10)) + +# %% +# Function +def start_axes(title): + fig = plt.figure(figsize=(13, 5)) + ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection="full_axes") + ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46) + ax.set_aspect("equal") + ax.set_title(title, weight="bold") + return ax + +def update_axes(ax, mappable=None): + ax.grid() + ax.update_env() + if mappable: + return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9])) + +# %% +# All +# --- +ax = start_axes("") +g_all = n.grid_count(bins) +m = g_all.display(ax, **kw_time, vmin=0, vmax=75) +update_axes(ax, m).set_label("Pixel used in % of time") + +# %% +# Network longer than 10 days +# --------------------------- +ax = start_axes("") +n10 = n.longer_than(10) +g_10 = n10.grid_count(bins) +m = g_10.display(ax, **kw_time, vmin=0, vmax=75) +update_axes(ax, m).set_label("Pixel used in % of time") + +ax = start_axes("") +m = g_10.display( + ax, + **kw_ratio, + vmin=50, + vmax=100, + name=g_10.vars["count"] * 100.0 / g_all.vars["count"] +) +update_axes(ax, m).set_label("Pixel used in % all atlas") +# %% +# Network longer than 20 days +# --------------------------- +ax = start_axes("") +n20 = n.longer_than(20) +g_20 = n20.grid_count(bins) +m = g_20.display(ax, **kw_time, vmin=0, vmax=75) +update_axes(ax, m).set_label("Pixel used in % of time") + +ax = start_axes("") +m = g_20.display( + ax, + **kw_ratio, + vmin=50, + vmax=100, + name=g_20.vars["count"] * 100.0 / g_all.vars["count"] +) +update_axes(ax, m).set_label("Pixel used in % all atlas") +ax = start_axes("") +m = g_20.display( + ax, + **kw_ratio, + vmin=50, + vmax=100, + name=ma.array( + g_20.vars["count"] * 100.0 / g_all.vars["count"], mask=g_all.vars["count"] < 365 + ) +) +update_axes(ax, m).set_label("Pixel used in % all atlas") +ax = start_axes("") +m = g_20.display( + ax, + **kw_ratio, + vmin=50, + vmax=100, + name=ma.array( + g_20.vars["count"] * 100.0 / g_all.vars["count"], + mask=g_all.vars["count"] >= 365, + ) +) +update_axes(ax, m).set_label("Pixel used in % all atlas") + + +# %% +# All merging +# ----------- +ax = start_axes("") +g_all_merging = n.merging_event().grid_count(bins) +m = g_all_merging.display(ax, **kw_time, vmin=0, vmax=0.2) +update_axes(ax, m).set_label("Pixel used in % of time") +# %% +ax = start_axes("") +m = g_all_merging.display( + ax, + **kw_ratio, + vmin=0, + vmax=1, + name=g_all_merging.vars["count"] * 100.0 / g_all.vars["count"] +) +update_axes(ax, m).set_label("Pixel used in % all atlas") + +# %% +# Merging in network longer than 10 days +# -------------------------------------- +ax = start_axes("") +g_10_merging = n10.merging_event().grid_count(bins) +m = g_10_merging.display(ax, **kw_time, vmin=0, vmax=0.2) +update_axes(ax, m).set_label("Pixel used in % of time") +# %% +ax = start_axes("") +m = g_10_merging.display( + ax, + **kw_ratio, + vmin=0, + vmax=0.5, + name=ma.array( + g_10_merging.vars["count"] * 100.0 / g_10.vars["count"], + mask=g_10.vars["count"] < 365, + ) +) +update_axes(ax, m).set_label("Pixel used in % all atlas") diff --git a/examples/16_network/pet_ioannou_2017_case.py b/examples/16_network/pet_ioannou_2017_case.py new file mode 100644 index 00000000..72f55b2e --- /dev/null +++ b/examples/16_network/pet_ioannou_2017_case.py @@ -0,0 +1,174 @@ +""" +Ioannou case +============ +Figure 10 from https://doi.org/10.1002/2017JC013158 + +""" +from datetime import datetime, timedelta + +import numpy as np +from matplotlib import pyplot as plt +from matplotlib.animation import FuncAnimation +from matplotlib.ticker import FuncFormatter + +import py_eddy_tracker.gui +from py_eddy_tracker.appli.gui import Anim +from py_eddy_tracker.observations.network import NetworkObservations + + +# %% +class VideoAnimation(FuncAnimation): + def _repr_html_(self, *args, **kwargs): + return self.to_html5_video() + + def save(self, *args, **kwargs): + if args[0].endswith("gif"): + return + return super().save(*args, **kwargs) + + +@FuncFormatter +def formatter(x, pos): + return (timedelta(x) + datetime(1950, 1, 1)).strftime("%d/%m/%Y") + + +def start_axes(title=""): + fig = plt.figure(figsize=(13, 6)) + ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection="full_axes") + ax.set_xlim(19, 29), ax.set_ylim(31, 35.5) + ax.set_aspect("equal") + ax.set_title(title, weight="bold") + ax.update_env() + return ax + + +def timeline_axes(title=""): + fig = plt.figure(figsize=(15, 5)) + ax = fig.add_axes([0.03, 0.06, 0.90, 0.88]) + ax.set_title(title, weight="bold") + ax.xaxis.set_major_formatter(formatter), ax.grid() + return ax + + +def update_axes(ax, mappable=None): + ax.grid(True) + if mappable: + return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9])) + + +# %% +n = NetworkObservations.load_file( + "med/Anticyclonic_seg.nc" +) +i = np.where( + (n.lat > 33) + * (n.lat < 34) + * (n.lon > 22) + * (n.lon < 23) + * (n.time > 20630) + * (n.time < 20650) +)[0][0] +ioannou_case = n.extract_with_mask(n.track == n.track[i]) +print(ioannou_case.infos()) + +# %% +ax = start_axes() +ioannou_case.plot(ax) +update_axes(ax) + +# %% +# Full Timeline +# ------------- +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() +_ = ioannou_case.display_timeline(ax) + + +# %% +# Sub network and new numbering +# ----------------------------- +i = np.where( + (ioannou_case.lat > 33) + * (ioannou_case.lat < 34) + * (ioannou_case.lon > 22) + * (ioannou_case.lon < 23) + * (ioannou_case.time > 20630) + * (ioannou_case.time < 20650) +)[0][0] +close_to_i3 = ioannou_case.relative(i, order=3) +close_to_i3.numbering_segment() + +# %% +# Anim +# ---- +a = Anim( + close_to_i3, + figsize=(12, 4), + cmap="Spectral_r", + nb_step=7, + dpi=55, + field_color="segment", + field_txt="segment", +) +a.ax.set_xlim(19, 30), a.ax.set_ylim(32, 35.25) +a.ax.update_env() +a.txt.set_position((21.5, 32.7)) +kwargs = dict(frames=np.arange(*a.period), interval=100, blit=True) +ani = VideoAnimation(a.fig, a.func_animation, **kwargs) + +# %% +# Classic display +# --------------- +ax = timeline_axes() +_ = close_to_i3.display_timeline(ax) + +# %% +ax = start_axes("") +n_copy = close_to_i3.copy() +n_copy.position_filter(2, 4) +n_copy.plot(ax) +update_axes(ax) + +# %% +# Local Timeline +# -------------- +ax = timeline_axes(f"Close segments ({close_to_i3.infos()})") +n_copy = close_to_i3.copy() +n_copy.median_filter(15, "time", "latitude") +_ = n_copy.display_timeline(ax, field="lat", method="all") + +# %% +# Local radius timeline +# --------------------- +n_copy.median_filter(2, "time", "radius_e") +n_copy.median_filter(2, "time", "radius_s") +for b0, b1 in [ + (datetime(i, 1, 1), datetime(i, 12, 31)) for i in (2004, 2005, 2006, 2007) +]: + b0_, b1_ = (b0 - datetime(1950, 1, 1)).days - 10, ( + b1 - datetime(1950, 1, 1) + ).days + 10 + ax = timeline_axes() + ax.set_xlim(b0_, b1_) + ax.set_ylim(10, 115) + n_copy.display_timeline( + ax, field="radius_e", method="all", lw=4, markersize=8, factor=1e-3 + ) + n_copy.display_timeline( + ax, field="radius_s", method="all", lw=1, markersize=3, factor=1e-3 + ) + +# %% +# Parameter timeline +# ------------------ +kw = dict(s=35, cmap=plt.get_cmap("Spectral_r", 8), zorder=10) +ax = timeline_axes() +m = close_to_i3.scatter_timeline(ax, "radius_e", factor=1e-3, vmin=20, vmax=100, **kw) +cb = update_axes(ax, m["scatter"]) +cb.set_label("Effective radius (km)") +# %% +ax = timeline_axes() +m = close_to_i3.scatter_timeline(ax, "shape_error_e", vmin=14, vmax=70, **kw) +cb = update_axes(ax, m["scatter"]) +cb.set_label("Effective shape error") From e5977923b89090d6d29efc0ab6bc494ed105d132 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 26 Jan 2021 23:28:45 +0100 Subject: [PATCH 030/249] Correction --- examples/16_network/pet_atlas.py | 2 ++ examples/16_network/pet_ioannou_2017_case.py | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/examples/16_network/pet_atlas.py b/examples/16_network/pet_atlas.py index 7fb3afd1..c890caef 100644 --- a/examples/16_network/pet_atlas.py +++ b/examples/16_network/pet_atlas.py @@ -29,12 +29,14 @@ def start_axes(title): ax.set_title(title, weight="bold") return ax + def update_axes(ax, mappable=None): ax.grid() ax.update_env() if mappable: return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9])) + # %% # All # --- diff --git a/examples/16_network/pet_ioannou_2017_case.py b/examples/16_network/pet_ioannou_2017_case.py index 72f55b2e..d0729c08 100644 --- a/examples/16_network/pet_ioannou_2017_case.py +++ b/examples/16_network/pet_ioannou_2017_case.py @@ -19,10 +19,15 @@ # %% class VideoAnimation(FuncAnimation): def _repr_html_(self, *args, **kwargs): + """To get video in html and have a player""" return self.to_html5_video() 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 h: + pass return return super().save(*args, **kwargs) @@ -114,7 +119,7 @@ def update_axes(ax, mappable=None): a.ax.set_xlim(19, 30), a.ax.set_ylim(32, 35.25) a.ax.update_env() a.txt.set_position((21.5, 32.7)) -kwargs = dict(frames=np.arange(*a.period), interval=100, blit=True) +kwargs = dict(frames=np.arange(*a.period), interval=100) ani = VideoAnimation(a.fig, a.func_animation, **kwargs) # %% From 482b7fdd2aaa23bb802443a3f0612e619fdcdc36 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Fri, 29 Jan 2021 10:55:11 +0100 Subject: [PATCH 031/249] Update examples --- examples/16_network/pet_atlas.py | 1 + examples/16_network/pet_ioannou_2017_case.py | 14 ++++++++------ examples/16_network/pet_relative.py | 2 +- .../pet_eddy_detection.ipynb | 2 +- .../pet_eddy_detection_gulf_stream.ipynb | 2 +- .../pet_filter_and_detection.ipynb | 2 +- .../02_eddy_identification/pet_sla_and_adt.ipynb | 2 +- .../pet_select_track_across_area.ipynb | 2 +- .../10_tracking_diagnostics/pet_center_count.ipynb | 2 +- .../10_tracking_diagnostics/pet_pixel_used.ipynb | 2 +- .../14_generic_tools/pet_visvalingam.ipynb | 2 +- 11 files changed, 18 insertions(+), 15 deletions(-) diff --git a/examples/16_network/pet_atlas.py b/examples/16_network/pet_atlas.py index c890caef..687e5d24 100644 --- a/examples/16_network/pet_atlas.py +++ b/examples/16_network/pet_atlas.py @@ -19,6 +19,7 @@ kw_time = dict(cmap="terrain_r", factor=100.0 / n.nb_days, name="count") kw_ratio = dict(cmap=plt.get_cmap("coolwarm_r", 10)) + # %% # Function def start_axes(title): diff --git a/examples/16_network/pet_ioannou_2017_case.py b/examples/16_network/pet_ioannou_2017_case.py index d0729c08..906b90eb 100644 --- a/examples/16_network/pet_ioannou_2017_case.py +++ b/examples/16_network/pet_ioannou_2017_case.py @@ -26,7 +26,7 @@ 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 h: + with open(args[0], "w") as _: pass return return super().save(*args, **kwargs) @@ -132,7 +132,7 @@ def update_axes(ax, mappable=None): ax = start_axes("") n_copy = close_to_i3.copy() n_copy.position_filter(2, 4) -n_copy.plot(ax) +n_copy.plot(ax, color_cycle=n_copy.COLORS) update_axes(ax) # %% @@ -151,12 +151,14 @@ def update_axes(ax, mappable=None): for b0, b1 in [ (datetime(i, 1, 1), datetime(i, 12, 31)) for i in (2004, 2005, 2006, 2007) ]: - b0_, b1_ = (b0 - datetime(1950, 1, 1)).days - 10, ( - b1 - datetime(1950, 1, 1) - ).days + 10 + ref, delta = datetime(1950, 1, 1), 20 + b0_, b1_ = (b0 - ref).days, (b1 - ref).days ax = timeline_axes() - ax.set_xlim(b0_, b1_) + ax.set_xlim(b0_ - delta, b1_ + delta) ax.set_ylim(10, 115) + ax.axvline(b0_, color="k", lw=1.5, ls="--"), ax.axvline( + b1_, color="k", lw=1.5, ls="--" + ) n_copy.display_timeline( ax, field="radius_e", method="all", lw=4, markersize=8, factor=1e-3 ) diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index e4b72875..5fac0fc2 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -166,7 +166,7 @@ # -------------------- fig = plt.figure(figsize=(15, 8)) ax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection="full_axes") -close_to_i2.plot(ax) +close_to_i2.plot(ax, color_cycle=close_to_i2.COLORS) ax.set_xlim(-13, 20), ax.set_ylim(-36.5, -20), ax.grid() ax = fig.add_axes([0.08, 0.67, 0.55, 0.3]) _ = close_to_i2.display_timeline(ax, field="latitude") diff --git a/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb b/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb index ee17f905..8c4d4752 100644 --- a/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb @@ -170,7 +170,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Creteria for rejecting a contour\n0. - Accepted (green)\n1. - Rejection for shape error (red)\n2. - Masked value within contour (blue)\n3. - Under or over the pixel limit bounds (black)\n4. - Amplitude criterion (yellow)\n\n" + "Criteria for rejecting a contour:\n 0. - Accepted (green)\n 1. - Rejection for shape error (red)\n 2. - Masked value within contour (blue)\n 3. - Under or over the pixel limit bounds (black)\n 4. - Amplitude criterion (yellow)\n\n" ] }, { diff --git a/notebooks/python_module/02_eddy_identification/pet_eddy_detection_gulf_stream.ipynb b/notebooks/python_module/02_eddy_identification/pet_eddy_detection_gulf_stream.ipynb index 3e7567d8..cf357d7b 100644 --- a/notebooks/python_module/02_eddy_identification/pet_eddy_detection_gulf_stream.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_eddy_detection_gulf_stream.ipynb @@ -235,7 +235,7 @@ }, "outputs": [], "source": [ - "ax = start_axes(\"Eddies detected\")\na.display(ax, color=\"r\", linewidth=0.75, label=\"Anticyclonic ({nb_obs} eddies)\", ref=-10)\nc.display(ax, color=\"b\", linewidth=0.75, label=\"Cyclonic ({nb_obs} eddies)\", ref=-10)\nax.legend()\ngreat_current.display(ax, color=\"k\")\nupdate_axes(ax)" + "ax = start_axes(\"Eddies detected\")\na.display(\n ax, color=\"r\", linewidth=0.75, label=\"Anticyclonic ({nb_obs} eddies)\", ref=-10\n)\nc.display(ax, color=\"b\", linewidth=0.75, label=\"Cyclonic ({nb_obs} eddies)\", ref=-10)\nax.legend()\ngreat_current.display(ax, color=\"k\")\nupdate_axes(ax)" ] }, { diff --git a/notebooks/python_module/02_eddy_identification/pet_filter_and_detection.ipynb b/notebooks/python_module/02_eddy_identification/pet_filter_and_detection.ipynb index 06d65865..4dec3709 100644 --- a/notebooks/python_module/02_eddy_identification/pet_filter_and_detection.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_filter_and_detection.ipynb @@ -91,7 +91,7 @@ }, "outputs": [], "source": [ - "ax = start_axes(\"Eddies detected over ADT\")\nm = g.display(ax, \"adt\", vmin=-0.15, vmax=0.15)\nmerge_f.display(ax, lw=0.75, label=\"Eddies in the filtered grid ({nb_obs} eddies)\", ref=-10, color=\"k\")\nmerge_t.display(ax, lw=0.75, label=\"Eddies without filter ({nb_obs} eddies)\", ref=-10, color=\"r\")\nax.legend()\nupdate_axes(ax, m)" + "ax = start_axes(\"Eddies detected over ADT\")\nm = g.display(ax, \"adt\", vmin=-0.15, vmax=0.15)\nmerge_f.display(\n ax,\n lw=0.75,\n label=\"Eddies in the filtered grid ({nb_obs} eddies)\",\n ref=-10,\n color=\"k\",\n)\nmerge_t.display(\n ax, lw=0.75, label=\"Eddies without filter ({nb_obs} eddies)\", ref=-10, color=\"r\"\n)\nax.legend()\nupdate_axes(ax, m)" ] }, { diff --git a/notebooks/python_module/02_eddy_identification/pet_sla_and_adt.ipynb b/notebooks/python_module/02_eddy_identification/pet_sla_and_adt.ipynb index a7ff8efe..083a5a5a 100644 --- a/notebooks/python_module/02_eddy_identification/pet_sla_and_adt.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_sla_and_adt.ipynb @@ -66,7 +66,7 @@ }, "outputs": [], "source": [ - "kwargs_a_adt = dict(lw=0.5, label=\"Anticyclonic ADT ({nb_obs} eddies)\", ref=-10, color=\"k\")\nkwargs_c_adt = dict(lw=0.5, label=\"Cyclonic ADT ({nb_obs} eddies)\", ref=-10, color=\"r\")\nkwargs_a_sla = dict(lw=0.5, label=\"Anticyclonic SLA ({nb_obs} eddies)\", ref=-10, color=\"g\")\nkwargs_c_sla = dict(lw=0.5, label=\"Cyclonic SLA ({nb_obs} eddies)\", ref=-10, color=\"b\")" + "kwargs_a_adt = dict(\n lw=0.5, label=\"Anticyclonic ADT ({nb_obs} eddies)\", ref=-10, color=\"k\"\n)\nkwargs_c_adt = dict(lw=0.5, label=\"Cyclonic ADT ({nb_obs} eddies)\", ref=-10, color=\"r\")\nkwargs_a_sla = dict(\n lw=0.5, label=\"Anticyclonic SLA ({nb_obs} eddies)\", ref=-10, color=\"g\"\n)\nkwargs_c_sla = dict(lw=0.5, label=\"Cyclonic SLA ({nb_obs} eddies)\", ref=-10, color=\"b\")" ] }, { diff --git a/notebooks/python_module/08_tracking_manipulation/pet_select_track_across_area.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_select_track_across_area.ipynb index 36b2adc1..df79f8ea 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_select_track_across_area.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_select_track_across_area.ipynb @@ -80,7 +80,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(12, 5))\nax = fig.add_axes((0.05, 0.05, 0.9, 0.9))\nax.set_xlim(-1, 9)\nax.set_ylim(36, 40)\nax.set_aspect(\"equal\")\nax.grid()\nc.plot(ax, color=\"gray\", lw=0.1, ref=-10, label=\"All tracks ({nb_tracks} tracks)\")\nc_subset.plot(ax, color=\"red\", lw=0.2, ref=-10, label=\"selected tracks ({nb_tracks} tracks)\")\nax.plot(\n (x0, x0, x1, x1, x0),\n (y0, y1, y1, y0, y0),\n color=\"green\",\n lw=1.5,\n label=\"Box of selection\",\n)\nax.legend()" + "fig = plt.figure(figsize=(12, 5))\nax = fig.add_axes((0.05, 0.05, 0.9, 0.9))\nax.set_xlim(-1, 9)\nax.set_ylim(36, 40)\nax.set_aspect(\"equal\")\nax.grid()\nc.plot(ax, color=\"gray\", lw=0.1, ref=-10, label=\"All tracks ({nb_tracks} tracks)\")\nc_subset.plot(\n ax, color=\"red\", lw=0.2, ref=-10, label=\"selected tracks ({nb_tracks} tracks)\"\n)\nax.plot(\n (x0, x0, x1, x1, x0),\n (y0, y1, y1, y0, y0),\n color=\"green\",\n lw=1.5,\n label=\"Box of selection\",\n)\nax.legend()" ] } ], diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb index 77e739bf..15a4362b 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# Count center\n\nDo Geo stat with center and compare with frequency method show: `sphx_glr_python_module_10_tracking_diagnostics_pet_pixel_used.py`\n" + "\n# Count center\n\nDo Geo stat with center and compare with frequency method\nshow: `sphx_glr_python_module_10_tracking_diagnostics_pet_pixel_used.py`\n" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb index e15daf26..902ed654 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# Count pixel used\n\nDo Geo stat with frequency and compare with center count method: `sphx_glr_python_module_10_tracking_diagnostics_pet_center_count.py`\n" + "\n# Count pixel used\n\nDo Geo stat with frequency and compare with center count\nmethod: `sphx_glr_python_module_10_tracking_diagnostics_pet_center_count.py`\n" ] }, { diff --git a/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb b/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb index 20215604..b593f21b 100644 --- a/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb +++ b/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import matplotlib.animation as animation\nfrom matplotlib import pyplot as plt\nfrom matplotlib import rc\nfrom numba import njit\nfrom numpy import array, empty\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.generic import uniform_resample\nfrom py_eddy_tracker.observations.observation import EddiesObservations\nfrom py_eddy_tracker.poly import vertice_overlap, visvalingam\n\n\n@njit(cache=True)\ndef visvalingam_polys(x, y, nb_pt):\n nb = x.shape[0]\n x_new = empty((nb, nb_pt), dtype=x.dtype)\n y_new = empty((nb, nb_pt), dtype=y.dtype)\n for i in range(nb):\n x_new[i], y_new[i] = visvalingam(x[i], y[i], nb_pt)\n return x_new, y_new\n\n\n@njit(cache=True)\ndef uniform_resample_polys(x, y, nb_pt):\n nb = x.shape[0]\n x_new = empty((nb, nb_pt), dtype=x.dtype)\n y_new = empty((nb, nb_pt), dtype=y.dtype)\n for i in range(nb):\n x_new[i], y_new[i] = uniform_resample(x[i], y[i], fixed_size=nb_pt)\n return x_new, y_new\n\n\ndef update_line(num):\n nb = 50 - num - 20\n x_v, y_v = visvalingam_polys(a.contour_lon_e, a.contour_lat_e, nb)\n for i, (x_, y_) in enumerate(zip(x_v, y_v)):\n lines_v[i].set_data(x_, y_)\n x_u, y_u = uniform_resample_polys(a.contour_lon_e, a.contour_lat_e, nb)\n for i, (x_, y_) in enumerate(zip(x_u, y_u)):\n lines_u[i].set_data(x_, y_)\n scores_v = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_v, y_v) * 100.0\n scores_u = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_u, y_u) * 100.0\n for i, (s_v, s_u) in enumerate(zip(scores_v, scores_u)):\n texts[i].set_text(f\"Score uniform {s_u:.1f} %\\nScore visvalingam {s_v:.1f} %\")\n title.set_text(f\"{nb} points by contour in place of 50\")\n return (title, *lines_u, *lines_v, *texts)" + "import matplotlib.animation as animation\nfrom matplotlib import pyplot as plt\nfrom numba import njit\nfrom numpy import array, empty\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.generic import uniform_resample\nfrom py_eddy_tracker.observations.observation import EddiesObservations\nfrom py_eddy_tracker.poly import vertice_overlap, visvalingam\n\n\n@njit(cache=True)\ndef visvalingam_polys(x, y, nb_pt):\n nb = x.shape[0]\n x_new = empty((nb, nb_pt), dtype=x.dtype)\n y_new = empty((nb, nb_pt), dtype=y.dtype)\n for i in range(nb):\n x_new[i], y_new[i] = visvalingam(x[i], y[i], nb_pt)\n return x_new, y_new\n\n\n@njit(cache=True)\ndef uniform_resample_polys(x, y, nb_pt):\n nb = x.shape[0]\n x_new = empty((nb, nb_pt), dtype=x.dtype)\n y_new = empty((nb, nb_pt), dtype=y.dtype)\n for i in range(nb):\n x_new[i], y_new[i] = uniform_resample(x[i], y[i], fixed_size=nb_pt)\n return x_new, y_new\n\n\ndef update_line(num):\n nb = 50 - num - 20\n x_v, y_v = visvalingam_polys(a.contour_lon_e, a.contour_lat_e, nb)\n for i, (x_, y_) in enumerate(zip(x_v, y_v)):\n lines_v[i].set_data(x_, y_)\n x_u, y_u = uniform_resample_polys(a.contour_lon_e, a.contour_lat_e, nb)\n for i, (x_, y_) in enumerate(zip(x_u, y_u)):\n lines_u[i].set_data(x_, y_)\n scores_v = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_v, y_v) * 100.0\n scores_u = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_u, y_u) * 100.0\n for i, (s_v, s_u) in enumerate(zip(scores_v, scores_u)):\n texts[i].set_text(f\"Score uniform {s_u:.1f} %\\nScore visvalingam {s_v:.1f} %\")\n title.set_text(f\"{nb} points by contour in place of 50\")\n return (title, *lines_u, *lines_v, *texts)" ] }, { From 5f5a62205477763ac4963f38694215bcb93e2e6a Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Fri, 29 Jan 2021 10:57:43 +0100 Subject: [PATCH 032/249] - add method to map method on segment - allow to appy color_cycle on map - add next_cost and previous_cost in variable --- src/py_eddy_tracker/__init__.py | 20 ++++ src/py_eddy_tracker/observations/network.py | 96 +++++++++++++++++--- src/py_eddy_tracker/observations/tracking.py | 10 +- 3 files changed, 109 insertions(+), 17 deletions(-) diff --git a/src/py_eddy_tracker/__init__.py b/src/py_eddy_tracker/__init__.py index a8f92db5..a4e0d8d6 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -403,6 +403,26 @@ def parse_args(self, *args, **kwargs): comment="Index of next obs, if there are a merging", ), ), + previous_cost=dict( + attr_name=None, + nc_name="previous_cost", + nc_type="float32", + nc_dims=("obs",), + nc_attr=dict( + long_name="Previous cost for previous obs", + comment="", + ), + ), + next_cost=dict( + attr_name=None, + nc_name="next_cost", + nc_type="float32", + nc_dims=("obs",), + nc_attr=dict( + long_name="Next cost for next obs", + comment="", + ), + ), n=dict( attr_name=None, nc_name="observation_number", diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 8b7e4e2b..d9a185de 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -68,9 +68,27 @@ class NetworkObservations(EddiesObservations): @property def elements(self): elements = super().elements - elements.extend(["track", "segment", "next_obs", "previous_obs"]) + elements.extend( + [ + "track", + "segment", + "next_obs", + "previous_obs", + "next_cost", + "previous_cost", + ] + ) return list(set(elements)) + def astype(self, cls): + new = cls.new_like(self, self.shape) + print() + for k in new.obs.dtype.names: + if k in self.obs.dtype.names: + new[k][:] = self[k][:] + new.sign_type = self.sign_type + return new + def longer_than(self, nb_day_min=-1, nb_day_max=-1): """ Select network on time duration @@ -81,7 +99,7 @@ def longer_than(self, nb_day_min=-1, nb_day_max=-1): if nb_day_max < 0: nb_day_max = 1000000000000 mask = zeros(self.shape, dtype="bool") - for i, b0, b1 in self.iter_on(self.segment_track_array()): + for i, b0, b1 in self.iter_on(self.segment_track_array): nb = i.stop - i.start if nb == 0: continue @@ -115,6 +133,8 @@ def from_split_network(cls, group_dataset, indexs, **kwargs): translate[index_order] = arange(index_order.shape[0]) network.next_obs[:] = translate[n] network.previous_obs[:] = translate[p] + network.next_cost[:] = indexs["next_cost"][index_order] + network.previous_cost[:] = indexs["previous_cost"][index_order] return network def infos(self, label=""): @@ -205,7 +225,7 @@ def position_filter(self, median_half_window, loess_half_window): def loess_filter(self, half_window, xfield, yfield, inplace=True): result = track_loess_filter( - half_window, self.obs[xfield], self.obs[yfield], self.segment_track_array() + half_window, self.obs[xfield], self.obs[yfield], self.segment_track_array ) if inplace: self.obs[yfield] = result @@ -214,7 +234,7 @@ def loess_filter(self, half_window, xfield, yfield, inplace=True): def median_filter(self, half_window, xfield, yfield, inplace=True): result = track_median_filter( - half_window, self[xfield], self[yfield], self.segment_track_array() + half_window, self[xfield], self[yfield], self.segment_track_array ) if inplace: self[yfield][:] = result @@ -316,18 +336,59 @@ def event_timeline(self, ax, field=None, method=None, factor=1): j += 1 return mappables - def scatter_timeline(self, ax, name, factor=1, event=True, **kwargs): + def mean_by_segment(self, y, **kw): + kw["dtype"] = y.dtype + return self.map_segment(lambda x: x.mean(), y, **kw) + + def map_segment(self, method, y, same=True, **kw): + if same: + out = empty(y.shape, **kw) + else: + out = list() + for i, b0, b1 in self.iter_on(self.segment_track_array): + res = method(y[i]) + if same: + out[i] = res + else: + if isinstance(i, slice): + if i.start == i.stop: + continue + elif len(i) == 0: + continue + out.append(res) + if not same: + out = array(out) + return out + + def scatter_timeline( + self, + ax, + name, + factor=1, + event=True, + yfield=None, + yfactor=1, + method=None, + **kwargs, + ): """ Must be call on only one network """ self.only_one_network() + y = (self.segment if yfield is None else self[yfield]) * yfactor + if method == "all": + pass + else: + y = self.mean_by_segment(y) mappables = dict() if event: - mappables.update(self.event_timeline(ax)) + mappables.update( + self.event_timeline(ax, field=yfield, method=method, factor=yfactor) + ) if "c" not in kwargs: v = self.parse_varname(name) kwargs["c"] = v * factor - mappables["scatter"] = ax.scatter(self.time, self.segment, **kwargs) + mappables["scatter"] = ax.scatter(self.time, y, **kwargs) return mappables def insert_virtual(self): @@ -350,13 +411,14 @@ def extract_event(self, indices): new.sign_type = self.sign_type return new + @property def segment_track_array(self): return build_unique_array(self.segment, self.track) def birth_event(self): # FIXME how to manage group 0 indices = list() - for i, _, _ in self.iter_on(self.segment_track_array()): + for i, _, _ in self.iter_on(self.segment_track_array): nb = i.stop - i.start if nb == 0: continue @@ -368,7 +430,7 @@ def birth_event(self): def death_event(self): # FIXME how to manage group 0 indices = list() - for i, _, _ in self.iter_on(self.segment_track_array()): + for i, _, _ in self.iter_on(self.segment_track_array): nb = i.stop - i.start if nb == 0: continue @@ -379,7 +441,7 @@ def death_event(self): def merging_event(self): indices = list() - for i, _, _ in self.iter_on(self.segment_track_array()): + for i, _, _ in self.iter_on(self.segment_track_array): nb = i.stop - i.start if nb == 0: continue @@ -390,7 +452,7 @@ def merging_event(self): def spliting_event(self): indices = list() - for i, _, _ in self.iter_on(self.segment_track_array()): + for i, _, _ in self.iter_on(self.segment_track_array): nb = i.stop - i.start if nb == 0: continue @@ -403,7 +465,7 @@ def fully_connected(self): self.only_one_network() # TODO - def plot(self, ax, ref=None, **kwargs): + def plot(self, ax, ref=None, color_cycle=None, **kwargs): """ This function will draw path of each trajectory @@ -412,17 +474,25 @@ def plot(self, ax, ref=None, **kwargs): :param dict kwargs: keyword arguments for Axes.plot :return: a list of matplotlib mappables """ + nb_colors = 0 + if color_cycle is not None: + kwargs = kwargs.copy() + nb_colors = len(color_cycle) mappables = list() if "label" in kwargs: kwargs["label"] = self.format_label(kwargs["label"]) - for i, b0, b1 in self.iter_on("segment"): + j = 0 + for i, _, _ in self.iter_on("segment"): nb = i.stop - i.start if nb == 0: continue + if nb_colors: + kwargs["color"] = color_cycle[j % nb_colors] x, y = self.lon[i], self.lat[i] if ref is not None: x, y = wrap_longitude(x, y, ref, cut=True) mappables.append(ax.plot(x, y, **kwargs)[0]) + j += 1 return mappables def remove_dead_branch(self, nobs=3): diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index 076d2975..2b989910 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -678,7 +678,7 @@ def set_tracks(self, x, y, ids, window, **kwargs): self.follow_obs(i, track_id, used, ids, x, y, *time_index, window, **kwargs) track_id += 1 # Search a possible ancestor (backward) - self.previous_obs(i, ids, x, y, *time_index, window, **kwargs) + self.get_previous_obs(i, ids, x, y, *time_index, window, **kwargs) @classmethod def follow_obs(cls, i_next, track_id, used, ids, *args, **kwargs): @@ -690,7 +690,7 @@ def follow_obs(cls, i_next, track_id, used, ids, *args, **kwargs): # Assign id ids["track"][i_next] = track_id # Search next - i_next_ = cls.next_obs(i_next, ids, *args, **kwargs) + i_next_ = cls.get_next_obs(i_next, ids, *args, **kwargs) if i_next_ == -1: break ids["next_obs"][i_next] = i_next_ @@ -706,7 +706,9 @@ def follow_obs(cls, i_next, track_id, used, ids, *args, **kwargs): i_next = i_next_ @staticmethod - def previous_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs): + def get_previous_obs( + i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs + ): """Backward association of observations to the segments""" time_cur = ids["time"][i_current] @@ -736,7 +738,7 @@ def previous_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwarg break @staticmethod - def next_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs): + def get_next_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs): """Forward association of observations to the segments""" time_max = time_e.shape[0] - 1 time_cur = ids["time"][i_current] From 9746a7a3c19cfce997d3fff3789fe635a9756394 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Fri, 29 Jan 2021 23:26:15 +0100 Subject: [PATCH 033/249] first version to fit an ellips --- .../pet_eddy_detection.py | 11 ++-- examples/14_generic_tools/pet_fit_contour.py | 0 .../pet_eddy_detection.ipynb | 4 +- src/py_eddy_tracker/observations/tracking.py | 2 +- src/py_eddy_tracker/poly.py | 59 ++++++++++++++++++- 5 files changed, 65 insertions(+), 11 deletions(-) create mode 100644 examples/14_generic_tools/pet_fit_contour.py diff --git a/examples/02_eddy_identification/pet_eddy_detection.py b/examples/02_eddy_identification/pet_eddy_detection.py index d4f7848a..bf73bae2 100644 --- a/examples/02_eddy_identification/pet_eddy_detection.py +++ b/examples/02_eddy_identification/pet_eddy_detection.py @@ -143,10 +143,9 @@ def update_axes(ax, mappable=None): # %% # Display the speed radius of the detected eddies ax = start_axes("Speed Radius (km)") -a.scatter(ax, "radius_s", vmin=10, vmax=50, s=80, ref=-10, cmap="magma_r", factor=0.001) -m = c.scatter( - ax, "radius_s", vmin=10, vmax=50, s=80, ref=-10, cmap="magma_r", factor=0.001 -) +kwargs = dict(vmin=10, vmax=50, s=80, ref=-10, cmap="magma_r", factor=0.001) +a.scatter(ax, "radius_s", **kwargs) +m = c.scatter(ax, "radius_s", **kwargs) update_axes(ax, m) # %% @@ -154,7 +153,5 @@ def update_axes(ax, mappable=None): ax = start_axes("Effective Radius (km)") kwargs = dict(vmin=10, vmax=80, cmap="magma_r", factor=0.001, lut=14, ref=-10) a.filled(ax, "effective_radius", **kwargs) -m = c.filled( - ax, "radius_e", vmin=10, vmax=80, cmap="magma_r", factor=0.001, lut=14, ref=-10 -) +m = c.filled(ax, "radius_e", **kwargs) update_axes(ax, m) diff --git a/examples/14_generic_tools/pet_fit_contour.py b/examples/14_generic_tools/pet_fit_contour.py new file mode 100644 index 00000000..e69de29b diff --git a/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb b/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb index 8c4d4752..938ec054 100644 --- a/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb @@ -253,7 +253,7 @@ }, "outputs": [], "source": [ - "ax = start_axes(\"Speed Radius (km)\")\na.scatter(ax, \"radius_s\", vmin=10, vmax=50, s=80, ref=-10, cmap=\"magma_r\", factor=0.001)\nm = c.scatter(\n ax, \"radius_s\", vmin=10, vmax=50, s=80, ref=-10, cmap=\"magma_r\", factor=0.001\n)\nupdate_axes(ax, m)" + "ax = start_axes(\"Speed Radius (km)\")\nkwargs = dict(vmin=10, vmax=50, s=80, ref=-10, cmap=\"magma_r\", factor=0.001)\na.scatter(ax, \"radius_s\", **kwargs)\nm = c.scatter(\n ax, \"radius_s\", **kwargs\n)\nupdate_axes(ax, m)" ] }, { @@ -271,7 +271,7 @@ }, "outputs": [], "source": [ - "ax = start_axes(\"Effective Radius (km)\")\nkwargs = dict(vmin=10, vmax=80, cmap=\"magma_r\", factor=0.001, lut=14, ref=-10)\na.filled(ax, \"effective_radius\", **kwargs)\nm = c.filled(\n ax, \"radius_e\", vmin=10, vmax=80, cmap=\"magma_r\", factor=0.001, lut=14, ref=-10\n)\nupdate_axes(ax, m)" + "ax = start_axes(\"Effective Radius (km)\")\nkwargs = dict(vmin=10, vmax=80, cmap=\"magma_r\", factor=0.001, lut=14, ref=-10)\na.filled(ax, \"effective_radius\", **kwargs)\nm = c.filled(\n ax, \"radius_e\", **kwargs\n)\nupdate_axes(ax, m)" ] } ], diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index 2b989910..685b1427 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -619,7 +619,7 @@ def split_network(self, intern=True, **kwargs): dtype=[ ("group", self.tracks.dtype), ("time", self.time.dtype), - ("track", "u2"), + ("track", "u4"), ("previous_cost", "f4"), ("next_cost", "f4"), ("previous_obs", "i4"), diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index da39d707..2ca8b109 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -7,7 +7,7 @@ from numba import njit, prange from numba import types as numba_types -from numpy import array, concatenate, empty, nan, ones, pi, where +from numpy import arctan, array, concatenate, empty, nan, ones, pi, where from numpy.linalg import lstsq from Polygon import Polygon @@ -471,6 +471,7 @@ def polygon_overlap(p0, p1, minimal_area=False): return cost +# FIXME: only one function are needed @njit(cache=True) def fit_circle(x, y): """ @@ -517,6 +518,62 @@ def fit_circle(x, y): return x0, y0, radius, err +@njit(cache=True) +def fit_ellips(x, y): + r""" + From a polygon, function will fit an ellips. + + Must be call with local coordinates (in m, to get a radius in m). + + .. math:: (\frac{x - x_0}{a})^2 + (\frac{y - y_0}{b})^2 = 1 + + .. math:: (\frac{x^2 - 2 * x * x_0 + x_0 ^2}{a^2}) + \frac{y^2 - 2 * y * y_0 + y_0 ^2}{b^2}) = 1 + + In case of angle + https://en.wikipedia.org/wiki/Ellipse + + """ + # x,y = x[1:],y[1:] + nb = x.shape[0] + datas = ones((nb, 5), dtype=x.dtype) + datas[:, 0] = x ** 2 + datas[:, 1] = x * y + datas[:, 2] = y ** 2 + datas[:, 3] = x + datas[:, 4] = y + (a, b, c, d, e), _, _, _ = lstsq(datas, ones(nb, dtype=x.dtype)) + det = b ** 2 - 4 * a * c + if det > 0: + print(det) + x0 = (2 * c * d - b * e) / det + y0 = (2 * a * e - b * d) / det + + A = ( + -( + ( + 2 + * (a * e ** 2 + c * d ** 2 - b * d * e - det) + * (a + c + ((a - c) ** 2 + b ** 2) ** 0.5) + ) + ** 0.5 + ) + / det + ) + B = ( + -( + ( + 2 + * (a * e ** 2 + c * d ** 2 - b * d * e - det) + * (a + c - ((a - c) ** 2 + b ** 2) ** 0.5) + ) + ** 0.5 + ) + / det + ) + theta = arctan((c - a - ((a - c) ** 2 + b ** 2) ** 0.5) / b) + return x0, y0, A, B, theta + + @njit(cache=True) def fit_circle_(x, y): r""" From 9653441a9e54d5e26a42c041c6a38dae8a058257 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Mon, 1 Feb 2021 12:06:06 +0100 Subject: [PATCH 034/249] full example fit contour --- examples/14_generic_tools/pet_fit_contour.py | 61 +++++++++++++++++ .../14_generic_tools/pet_fit_contour.ipynb | 65 +++++++++++++++++++ src/py_eddy_tracker/poly.py | 29 ++------- 3 files changed, 132 insertions(+), 23 deletions(-) create mode 100644 notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb diff --git a/examples/14_generic_tools/pet_fit_contour.py b/examples/14_generic_tools/pet_fit_contour.py index e69de29b..34cda453 100644 --- a/examples/14_generic_tools/pet_fit_contour.py +++ b/examples/14_generic_tools/pet_fit_contour.py @@ -0,0 +1,61 @@ +""" +Contour fit +=========== + +Two type of fit : + - Ellipse + - 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) + + +# %% +# Plot fitted circle or ellips on stored contour +xs, ys = a.contour_lon_s, a.contour_lat_s + +fig = plt.figure(figsize=(15, 15)) + +j = 1 +for i in range(0, 800, 30): + x, y = xs[i], ys[i] + x0_, y0_ = x.mean(), y.mean() + x_, y_ = coordinates_to_local(x, y, x0_, y0_) + ax = fig.add_subplot(4, 4, j) + ax.grid(), ax.set_aspect("equal") + ax.plot(x, y, label="store", color="black") + x0, y0, a, b, theta = fit_ellips(x_, y_) + x0, y0 = local_to_coordinates(x0, y0, x0_, y0_) + ax.plot(*build_ellips(x0, y0, a, b, theta), label="ellips", color="green") + x0, y0, radius, shape_error = fit_circle_(x_, y_) + x0, y0 = local_to_coordinates(x0, y0, x0_, y0_) + ax.plot(*build_circle(x0, y0, radius), label="circle", color="red", lw=0.5) + if j == 16: + break + j += 1 diff --git a/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb b/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb new file mode 100644 index 00000000..9a211723 --- /dev/null +++ b/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb @@ -0,0 +1,65 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Contour fit\n\nTwo type of fit :\n - Ellipse\n - Circle\n\nIn the two case we use a least square algorithm\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from py_eddy_tracker.poly import fit_circle_, fit_ellips, fit_circle\nfrom py_eddy_tracker.generic import local_to_coordinates, coordinates_to_local\nfrom matplotlib import pyplot as plt\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.observations.observation import EddiesObservations\nfrom numpy import radians, linspace, cos, sin\n\na = EddiesObservations.load_file(data.get_path(\"Anticyclonic_20190223.nc\"))\n\n\ndef build_circle(x0, y0, r):\n angle = radians(linspace(0, 360, 50))\n x_norm, y_norm = cos(angle), sin(angle)\n return local_to_coordinates(x_norm * r, y_norm * r, x0, y0)\n\ndef build_ellips(x0, y0, a, b, theta):\n angle = radians(linspace(0, 360, 50))\n x = a * cos(theta) * cos(angle) - b * sin(theta) * sin(angle)\n y = a * sin(theta) * cos(angle) + b * cos(theta) * sin(angle)\n return local_to_coordinates(x, y, x0, y0)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "xs,ys=a.contour_lon_s,a.contour_lat_s\n\nfor i in range(20):\n x, y = xs[i], ys[i]\n x0_, y0_ = x.mean(), y.mean()\n x_, y_ = coordinates_to_local(x,y, x0_, y0_)\n fig = plt.figure()\n ax = fig.add_subplot(111)\n ax.grid(), ax.set_aspect('equal')\n ax.plot(x, y, label='store')\n x0, y0, a,b, theta = fit_ellips(x_,y_)\n x0, y0 = local_to_coordinates(x0, y0, x0_, y0_)\n ax.plot(*build_ellips(x0, y0, a,b, theta), label='ellips')\n x0, y0, radius, shape_error = fit_circle_(x_,y_)\n x0,y0 = local_to_coordinates(x0,y0, x0_, y0_)\n ax.plot(*build_circle(x0,y0, radius), label='circle')\n ax.legend()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index 2ca8b109..d1bf5fb8 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -548,29 +548,12 @@ def fit_ellips(x, y): x0 = (2 * c * d - b * e) / det y0 = (2 * a * e - b * d) / det - A = ( - -( - ( - 2 - * (a * e ** 2 + c * d ** 2 - b * d * e - det) - * (a + c + ((a - c) ** 2 + b ** 2) ** 0.5) - ) - ** 0.5 - ) - / det - ) - B = ( - -( - ( - 2 - * (a * e ** 2 + c * d ** 2 - b * d * e - det) - * (a + c - ((a - c) ** 2 + b ** 2) ** 0.5) - ) - ** 0.5 - ) - / det - ) - theta = arctan((c - a - ((a - c) ** 2 + b ** 2) ** 0.5) / b) + AB1 = 2 * (a * e ** 2 + c * d ** 2 - b * d * e - det) + AB2 = a + c + AB3 = ((a - c) ** 2 + b ** 2) ** 0.5 + A = -((AB1 * (AB2 + AB3)) ** 0.5) / det + B = -((AB1 * (AB2 - AB3)) ** 0.5) / det + theta = arctan((c - a - AB3) / b) return x0, y0, A, B, theta From aa8e774d3820496061441708288f115e84ce2789 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 2 Feb 2021 14:37:52 +0100 Subject: [PATCH 035/249] advection function rk4 and euler --- src/py_eddy_tracker/dataset/grid.py | 126 ++++++++++++++++++++++++++-- 1 file changed, 120 insertions(+), 6 deletions(-) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 4f427d63..9356e67b 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -8,7 +8,7 @@ from cv2 import filter2D from matplotlib.path import Path as BasePath from netCDF4 import Dataset -from numba import njit +from numba import njit, prange from numba import types as numba_types from numpy import ( arange, @@ -21,6 +21,7 @@ errstate, exp, float_, + floor, histogram2d, int8, int_, @@ -37,6 +38,7 @@ ones, percentile, pi, + radians, round_, sin, sinc, @@ -242,8 +244,6 @@ class GridDataset(object): """ __slots__ = ( - "_x_var", - "_y_var", "x_c", "y_c", "x_bounds", @@ -258,8 +258,6 @@ class GridDataset(object): "variables_description", "global_attrs", "vars", - "interpolators", - "speed_coef", "contours", ) @@ -295,7 +293,6 @@ def __init__( self.coordinates = x_name, y_name self.vars = dict() self.indexs = dict() if indexs is None else indexs - self.interpolators = dict() if centered is None: logger.warning( "We assume pixel position of grid is center for %s", filename @@ -1956,6 +1953,123 @@ def interp(self, grid_name, lons, lats, method="bilinear"): self.x_c, self.y_c, g, m, lons, lats, nearest=method == "nearest" ) + def uv_for_advection(self, u_name, v_name, time_step=600, backward=False): + """ + Get U,V to be used in degrees with precomputed time step + + :param str,array u_name: U field to advect obs + :param str,array v_name: V field to advect obs + :param int time_step: Number of second for each advection + """ + u = (self.grid(u_name) if isinstance(u_name, str) else u_name).copy() + v = (self.grid(v_name) if isinstance(v_name, str) else v_name).copy() + # N seconds / 1 degrees in m + coef = time_step * 180 / pi / self.EARTH_RADIUS + u *= coef / cos(radians(self.y_c)) + v *= coef + if backward: + u = -u + v = -v + m = u.mask + v.mask + return u, v, m + +@njit(cache=True) +def advect_rk4(x_g, y_g, u_g, v_g, m_g, x, y, nb_step): + # Grid coordinates + x_ref, y_ref = x_g[0], y_g[0] + x_step, y_step = x_g[1] - x_ref, y_g[1] - y_ref + # On each particule + for i in prange(x.size): + # If particule are not valid => continue + if isnan(x[i]) or isnan(y[i]): + continue + # Iterate on whole steps + for _ in range(nb_step): + # k1, slope at origin + u1, v1 = get_uv(x_ref, y_ref, x_step, y_step, u_g, v_g, m_g, x[i], y[i]) + if isnan(u1) or isnan(v1): + x[i], y[i] = nan, nan + break + # k2, slope at middle with first guess position + x1, y1 = x[i] + u1*.5, y[i] + v1*.5 + u2, v2 = get_uv(x_ref, y_ref, x_step, y_step, u_g, v_g, m_g, x1, y1) + if isnan(u2) or isnan(v2): + x[i], y[i] = nan, nan + break + # k3, slope at middle with update guess position + x2, y2 = x[i] + u2 * .5, y[i] + v2 * .5 + u3, v3 = get_uv(x_ref, y_ref, x_step, y_step, u_g, v_g, m_g, x2, y2) + if isnan(u3) or isnan(v3): + x[i], y[i] = nan, nan + break + # k4, slope at end with update guess position + x3, y3 = x2 + u3, y2 + v3 + u4, v4 = get_uv(x_ref, y_ref, x_step, y_step, u_g, v_g, m_g, x3, y3) + if isnan(u4) or isnan(v4): + x[i], y[i] = nan, nan + break + dx = (u1 + 2 * u2 + 2 * u3 + u4) / 6 + dy = (v1 + 2 * v2 + 2 * v3 + v4) / 6 + # # Compute new x,y + x[i] += dx + y[i] += dy + + +@njit(cache=True) +def get_uv(x0, y0, x_step, y_step, u,v, m, x,y): + i, j = (x - x0) / x_step, (y - y0) / y_step + i0, j0 = int(floor(i)), int(floor(j)) + i1, j1 = i0 + 1, j0 + 1 + if m[i0, j0] or m[i0, j1] or m[i1, j0] or m[i1, j1]: + return nan, nan + # Extract value for u and v + u00, u01, u10, u11 = u[i0, j0], u[i0, j1], u[i1, j0], u[i1, j1] + v00, v01, v10, v11 = v[i0, j0], v[i0, j1], v[i1, j0], v[i1, j1] + xd, yd = i - i0, j - j0 + xd_i, yd_i = 1 - xd, 1 - yd + u = (u00 * xd_i + u10 * xd) * yd_i + (u01 * xd_i + u11 * xd) * yd + v = (v00 * xd_i + v10 * xd) * yd_i + (v01 * xd_i + v11 * xd) * yd + return u, v + +@njit(cache=True) +def advect(x_g, y_g, u_g, v_g, m_g, x, y, nb_step): + # Grid coordinates + x_ref, y_ref = x_g[0], y_g[0] + x_step, y_step = x_g[1] - x_ref, y_g[1] - y_ref + # Indices which should be never exist + i0_old, j0_old = -100000, -100000 + # On each particule + for i in prange(x.size): + # If particule are not valid => continue + if isnan(x[i]) or isnan(y[i]): + continue + # Iterate on whole steps + for _ in range(nb_step): + # Compute coordinates in indice referentiel + x_, y_ = (x[i] - x_ref) / x_step, (y[i] - y_ref) / y_step + # corner bottom left Indice + i0_, j0_ = int(floor(x_)), int(floor(y_)) + i0, j0 = i0_, j0_ + i1 = i0 + 1 + # corner are the same need only a new xd and yd + if i0 != i0_old or j0 != j0_old: + j1 = j0 + 1 + # If one of nearest pixel is invalid + if m_g[i0, j0] or m_g[i0, j1] or m_g[i1, j0] or m_g[i1, j1]: + x[i], y[i] = nan, nan + break + # Extract value for u and v + u00, u01, u10, u11 = u_g[i0, j0], u_g[i0, j1], u_g[i1, j0], u_g[i1, j1] + v00, v01, v10, v11 = v_g[i0, j0], v_g[i0, j1], v_g[i1, j0], v_g[i1, j1] + # Need to be store only on change + i0_old, j0_old = i0, j0 + # Compute distance + xd, yd = x_ - i0_, y_ - j0_ + xd_i, yd_i = 1 - xd, 1 - yd + # Compute new x,y + x[i] += (u00 * xd_i + u10 * xd) * yd_i + (u01 * xd_i + u11 * xd) * yd + y[i] += (v00 * xd_i + v10 * xd) * yd_i + (v01 * xd_i + v11 * xd) * yd + @njit(cache=True, fastmath=True) def compute_pixel_path(x0, y0, x1, y1, x_ori, y_ori, x_step, y_step, nb_x): From 9f626f1e33e65262e5a39ed28c6b76887ae663f7 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Wed, 3 Feb 2021 15:56:56 +0100 Subject: [PATCH 036/249] method to advect obs with current --- src/py_eddy_tracker/dataset/grid.py | 377 ++++++++++++++++++++++++++-- 1 file changed, 361 insertions(+), 16 deletions(-) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 9356e67b..d9d0fced 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -1973,6 +1973,64 @@ def uv_for_advection(self, u_name, v_name, time_step=600, backward=False): m = u.mask + v.mask return u, v, m + def advect(self, x, y, u_name, v_name, nb_step=10, rk4=False, **kw): + """ + At each call it will update position in place with u & v field + + It's a dummy advection which use only one layer of current + :param array x: Longitude of obs to move + :param array y: Latitude of obs to move + :param str,array u_name: U field to advect obs + :param str,array v_name: V field to advect obs + :param int nb_step: Number of iteration before to release data + :param int time_step: Number of second for each advection + """ + u, v, m = self.uv_for_advection(u_name, v_name, **kw) + advect_ = advect_rk4 if rk4 else advect + while True: + advect_(self.x_c, self.y_c, u, v, m, x, y, nb_step) + yield x, y + + def filament( + self, x, y, u_name, v_name, nb_step=10, filament_size=6, rk4=False, **kw + ): + """ + Produce filament with concatenation of advection + + It's a dummy advection which use only one layer of current + :param array x: Longitude of obs to move + :param array y: Latitude of obs to move + :param str,array u_name: U field to advect obs + :param str,array v_name: V field to advect obs + :param int nb_step: Number of iteration before to release data + :param int time_step: Number of second for each advection + :param int filament_size: Number of point by filament + :return: x,y for a line + """ + u, v, m = self.uv_for_advection(u_name, v_name, **kw) + x, y = x.copy(), y.copy() + nb = x.shape[0] + filament_size_ = filament_size + 1 + f_x = empty(nb * filament_size_, dtype="f4") + f_y = empty(nb * filament_size_, dtype="f4") + f_x[:] = nan + f_y[:] = nan + f_x[::filament_size_] = x + f_y[::filament_size_] = y + advect_ = advect_rk4 if rk4 else advect + while True: + # Shift position + f_x[1:] = f_x[:-1] + f_y[1:] = f_y[:-1] + # Remove last position + f_x[filament_size::filament_size_] = nan + f_y[filament_size::filament_size_] = nan + advect_(self.x_c, self.y_c, u, v, m, x, y, nb_step) + f_x[::filament_size_] = x + f_y[::filament_size_] = y + yield f_x, f_y + + @njit(cache=True) def advect_rk4(x_g, y_g, u_g, v_g, m_g, x, y, nb_step): # Grid coordinates @@ -1981,42 +2039,64 @@ def advect_rk4(x_g, y_g, u_g, v_g, m_g, x, y, nb_step): # On each particule for i in prange(x.size): # If particule are not valid => continue - if isnan(x[i]) or isnan(y[i]): + x_, y_ = x[i], y[i] + if isnan(x_) or isnan(y_): continue # Iterate on whole steps for _ in range(nb_step): # k1, slope at origin - u1, v1 = get_uv(x_ref, y_ref, x_step, y_step, u_g, v_g, m_g, x[i], y[i]) + u1, v1 = get_uv(x_ref, y_ref, x_step, y_step, u_g, v_g, m_g, x_, y_) if isnan(u1) or isnan(v1): - x[i], y[i] = nan, nan + x_, y_ = nan, nan break # k2, slope at middle with first guess position - x1, y1 = x[i] + u1*.5, y[i] + v1*.5 - u2, v2 = get_uv(x_ref, y_ref, x_step, y_step, u_g, v_g, m_g, x1, y1) + u2, v2 = get_uv( + x_ref, + y_ref, + x_step, + y_step, + u_g, + v_g, + m_g, + x_ + u1 * 0.5, + y_ + v1 * 0.5, + ) if isnan(u2) or isnan(v2): - x[i], y[i] = nan, nan + x_, y_ = nan, nan break # k3, slope at middle with update guess position - x2, y2 = x[i] + u2 * .5, y[i] + v2 * .5 - u3, v3 = get_uv(x_ref, y_ref, x_step, y_step, u_g, v_g, m_g, x2, y2) + u3, v3 = get_uv( + x_ref, + y_ref, + x_step, + y_step, + u_g, + v_g, + m_g, + x_ + u2 * 0.5, + y_ + v2 * 0.5, + ) if isnan(u3) or isnan(v3): - x[i], y[i] = nan, nan + x_, y_ = nan, nan break # k4, slope at end with update guess position - x3, y3 = x2 + u3, y2 + v3 - u4, v4 = get_uv(x_ref, y_ref, x_step, y_step, u_g, v_g, m_g, x3, y3) + u4, v4 = get_uv( + x_ref, y_ref, x_step, y_step, u_g, v_g, m_g, x_ + u3, y_ + v3 + ) if isnan(u4) or isnan(v4): - x[i], y[i] = nan, nan + x_, y_ = nan, nan break dx = (u1 + 2 * u2 + 2 * u3 + u4) / 6 dy = (v1 + 2 * v2 + 2 * v3 + v4) / 6 - # # Compute new x,y - x[i] += dx - y[i] += dy + # Compute new x,y + x_ += dx + y_ += dy + x[i] = x_ + y[i] = y_ @njit(cache=True) -def get_uv(x0, y0, x_step, y_step, u,v, m, x,y): +def get_uv(x0, y0, x_step, y_step, u, v, m, x, y): i, j = (x - x0) / x_step, (y - y0) / y_step i0, j0 = int(floor(i)), int(floor(j)) i1, j1 = i0 + 1, j0 + 1 @@ -2031,6 +2111,7 @@ def get_uv(x0, y0, x_step, y_step, u,v, m, x,y): v = (v00 * xd_i + v10 * xd) * yd_i + (v01 * xd_i + v11 * xd) * yd return u, v + @njit(cache=True) def advect(x_g, y_g, u_g, v_g, m_g, x, y, nb_step): # Grid coordinates @@ -2158,3 +2239,267 @@ def has_value(grid, i_x, i_y, value, below=False): if grid[i, j] > value: return True return False + + +class GridCollection: + def __init__(self): + self.datasets = list() + + @classmethod + def from_netcdf_cube(cls, filename, x_name, y_name, t_name): + new = cls() + with Dataset(filename) as h: + for i, t in enumerate(h.variables[t_name][:]): + d = RegularGridDataset(filename, x_name, y_name, indexs={t_name: i}) + d.add_uv("adt") + new.datasets.append((t, d)) + return new + + def filament( + self, + x, + y, + u_name, + v_name, + t_init, + nb_step=10, + time_step=600, + filament_size=6, + rk4=False, + **kw, + ): + """ + Produce filament with concatenation of advection + + It's a dummy advection which use only one layer of current + :param array x: Longitude of obs to move + :param array y: Latitude of obs to move + :param str,array u_name: U field to advect obs + :param str,array v_name: V field to advect obs + :param int nb_step: Number of iteration before to release data + :param int time_step: Number of second for each advection + :param int filament_size: Number of point by filament + :return: x,y for a line + """ + x, y = x.copy(), y.copy() + nb = x.shape[0] + filament_size_ = filament_size + 1 + f_x = empty(nb * filament_size_, dtype="f4") + f_y = empty(nb * filament_size_, dtype="f4") + f_x[:] = nan + f_y[:] = nan + f_x[::filament_size_] = x + f_y[::filament_size_] = y + + backward = kw.get("backward", False) + if backward: + generator = self.get_previous_time_step(t_init) + dt = -nb_step * time_step + t_step = -time_step + else: + generator = self.get_next_time_step(t_init) + dt = nb_step * time_step + t_step = time_step + t0, d0 = generator.__next__() + u0, v0, m0 = d0.uv_for_advection(u_name, v_name, time_step, **kw) + t1, d1 = generator.__next__() + u1, v1, m1 = d1.uv_for_advection(u_name, v_name, time_step, **kw) + t0 = t0 * 86400 + t1 = t1 * 86400 + t = t_init * 86400 + advect_ = advect_t_rk4 if rk4 else advect_t + while True: + # Shift position + f_x[1:] = f_x[:-1] + f_y[1:] = f_y[:-1] + # Remove last position + f_x[filament_size::filament_size_] = nan + f_y[filament_size::filament_size_] = nan + + if (backward and t <= t1) or (not backward and t >= t1): + t0, u0, v0, m0 = t1, u1, v1, m1 + t1, d1 = generator.__next__() + t1 = t1 * 86400 + u1, v1, m1 = d1.uv_for_advection(u_name, v_name, time_step, **kw) + w = 1 - (arange(t, t + dt, t_step) - t0) / (t1 - t0) + half_w = t_step / 2.0 / (t1 - t0) + advect_(d0.x_c, d0.y_c, u0, v0, m0, u1, v1, m1, x, y, w, half_w=half_w) + f_x[::filament_size_] = x + f_y[::filament_size_] = y + t += dt + yield t, f_x, f_y + + def advect( + self, + x, + y, + u_name, + v_name, + t_init, + nb_step=10, + time_step=600, + rk4=False, + **kw, + ): + backward = kw.get("backward", False) + if backward: + generator = self.get_previous_time_step(t_init) + dt = -nb_step * time_step + t_step = -time_step + else: + generator = self.get_next_time_step(t_init) + dt = nb_step * time_step + t_step = time_step + t0, d0 = generator.__next__() + u0, v0, m0 = d0.uv_for_advection(u_name, v_name, time_step, **kw) + t1, d1 = generator.__next__() + u1, v1, m1 = d1.uv_for_advection(u_name, v_name, time_step, **kw) + t0 = t0 * 86400 + t1 = t1 * 86400 + t = t_init * 86400 + advect_ = advect_t_rk4 if rk4 else advect_t + while True: + if (backward and t <= t1) or (not backward and t >= t1): + t0, u0, v0, m0 = t1, u1, v1, m1 + t1, d1 = generator.__next__() + t1 = t1 * 86400 + u1, v1, m1 = d1.uv_for_advection(u_name, v_name, time_step, **kw) + w = 1 - (arange(t, t + dt, t_step) - t0) / (t1 - t0) + half_w = t_step / 2.0 / (t1 - t0) + advect_(d0.x_c, d0.y_c, u0, v0, m0, u1, v1, m1, x, y, w, half_w=half_w) + t += dt + yield t, x, y + + def get_next_time_step(self, t_init): + first = True + for i, (t, dataset) in enumerate(self.datasets): + if t < t_init: + continue + if first: + first = False + yield self.datasets[i - 1] + yield t, dataset + + def get_previous_time_step(self, t_init): + first = True + i = len(self.datasets) + for t, dataset in reversed(self.datasets): + i -= 1 + if t > t_init: + continue + if first: + first = False + yield self.datasets[i + 1] + yield t, dataset + + +@njit(cache=True) +def advect_t(x_g, y_g, u_g0, v_g0, m_g0, u_g1, v_g1, m_g1, x, y, weigths, half_w=0): + # Grid coordinates + x_ref, y_ref = x_g[0], y_g[0] + x_step, y_step = x_g[1] - x_ref, y_g[1] - y_ref + # Indices which should be never exist + i0_old, j0_old = -100000, -100000 + # On each particule + for i in prange(x.size): + # If particule are not valid => continue + if isnan(x[i]) or isnan(y[i]): + continue + # Iterate on whole steps + for w in weigths: + # Compute coordinates in indice referentiel + x_, y_ = (x[i] - x_ref) / x_step, (y[i] - y_ref) / y_step + # corner bottom left Indice + i0_, j0_ = int(floor(x_)), int(floor(y_)) + i0, j0 = i0_, j0_ + i1 = i0 + 1 + # corner are the same need only a new xd and yd + if i0 != i0_old or j0 != j0_old: + j1 = j0 + 1 + # If one of nearest pixel is invalid + if ( + m_g0[i0, j0] + or m_g0[i0, j1] + or m_g0[i1, j0] + or m_g0[i1, j1] + or m_g1[i0, j0] + or m_g1[i0, j1] + or m_g1[i1, j0] + or m_g1[i1, j1] + ): + x[i], y[i] = nan, nan + break + # Extract value for u and v + u000, u001 = u_g0[i0, j0], u_g0[i0, j1] + u010, u011 = u_g0[i1, j0], u_g0[i1, j1] + v000, v001 = v_g0[i0, j0], v_g0[i0, j1] + v010, v011 = v_g0[i1, j0], v_g0[i1, j1] + u100, u101 = u_g1[i0, j0], u_g1[i0, j1] + u110, u111 = u_g1[i1, j0], u_g1[i1, j1] + v100, v101 = v_g1[i0, j0], v_g1[i0, j1] + v110, v111 = v_g1[i1, j0], v_g1[i1, j1] + # Need to be store only on change + i0_old, j0_old = i0, j0 + # Compute distance + xd, yd = x_ - i0_, y_ - j0_ + xd_i, yd_i = 1 - xd, 1 - yd + # Compute new x,y + dx0 = (u000 * xd_i + u010 * xd) * yd_i + (u001 * xd_i + u011 * xd) * yd + dx1 = (u100 * xd_i + u110 * xd) * yd_i + (u101 * xd_i + u111 * xd) * yd + dy0 = (v000 * xd_i + v010 * xd) * yd_i + (v001 * xd_i + v011 * xd) * yd + dy1 = (v100 * xd_i + v110 * xd) * yd_i + (v101 * xd_i + v111 * xd) * yd + x[i] += dx0 * w + dx1 * (1 - w) + y[i] += dy0 * w + dy1 * (1 - w) + + +@njit(cache=True) +def advect_t_rk4(x_g, y_g, u_g0, v_g0, m_g0, u_g1, v_g1, m_g1, x, y, weigths, half_w): + # Grid coordinates + x_ref, y_ref = x_g[0], y_g[0] + x_step, y_step = x_g[1] - x_ref, y_g[1] - y_ref + # On each particule + for i in prange(x.size): + # If particule are not valid => continue + x_, y_ = x[i], y[i] + if isnan(x_) or isnan(y_): + continue + # Iterate on whole steps + for w in weigths: + # k1, slope at origin + u0_, v0_ = get_uv(x_ref, y_ref, x_step, y_step, u_g0, v_g0, m_g0, x_, y_) + u1_, v1_ = get_uv(x_ref, y_ref, x_step, y_step, u_g1, v_g1, m_g1, x_, y_) + u1, v1 = u0_ * w + u1_ * (1 - w), v0_ * w + v1_ * (1 - w) + if isnan(u1) or isnan(v1): + x_, y_ = nan, nan + break + # k2, slope at middle with first guess position + x1, y1 = x_ + u1 * 0.5, y_ + v1 * 0.5 + u0_, v0_ = get_uv(x_ref, y_ref, x_step, y_step, u_g0, v_g0, m_g0, x1, y1) + u1_, v1_ = get_uv(x_ref, y_ref, x_step, y_step, u_g1, v_g1, m_g1, x1, y1) + w_ = w - half_w + u2, v2 = u0_ * w_ + u1_ * (1 - w_), v0_ * w_ + v1_ * (1 - w_) + if isnan(u2) or isnan(v2): + x_, y_ = nan, nan + break + # k3, slope at middle with update guess position + x2, y2 = x_ + u2 * 0.5, y_ + v2 * 0.5 + u0_, v0_ = get_uv(x_ref, y_ref, x_step, y_step, u_g0, v_g0, m_g0, x2, y2) + u1_, v1_ = get_uv(x_ref, y_ref, x_step, y_step, u_g1, v_g1, m_g1, x2, y2) + u3, v3 = u0_ * w_ + u1_ * (1 - w_), v0_ * w_ + v1_ * (1 - w_) + if isnan(u3) or isnan(v3): + x_, y_ = nan, nan + break + # k4, slope at end with update guess position + x3, y3 = x_ + u3, y_ + v3 + u0_, v0_ = get_uv(x_ref, y_ref, x_step, y_step, u_g0, v_g0, m_g0, x3, y3) + u1_, v1_ = get_uv(x_ref, y_ref, x_step, y_step, u_g1, v_g1, m_g1, x3, y3) + w_ -= half_w + u4, v4 = u0_ * w_ + u1_ * (1 - w_), v0_ * w_ + v1_ * (1 - w_) + if isnan(u4) or isnan(v4): + x_, y_ = nan, nan + break + dx = (u1 + 2 * u2 + 2 * u3 + u4) / 6 + dy = (v1 + 2 * v2 + 2 * v3 + v4) / 6 + x_ += dx + y_ += dy + x[i], y[i] = x_, y_ From 3c92d8287b553a6eb02c585c7f2115df576c5abb Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Wed, 3 Feb 2021 16:06:29 +0100 Subject: [PATCH 037/249] Example how to run again a segmentation --- .../16_network/pet_replay_segmentation.py | 210 ++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 examples/16_network/pet_replay_segmentation.py diff --git a/examples/16_network/pet_replay_segmentation.py b/examples/16_network/pet_replay_segmentation.py new file mode 100644 index 00000000..67c89127 --- /dev/null +++ b/examples/16_network/pet_replay_segmentation.py @@ -0,0 +1,210 @@ +""" +Replay segmentation +=================== +Case from figure 10 from https://doi.org/10.1002/2017JC013158 + +""" +from datetime import datetime, timedelta + +import numpy as np +from matplotlib import pyplot as plt +from matplotlib.animation import FuncAnimation +from matplotlib.ticker import FuncFormatter + +import py_eddy_tracker.gui +from py_eddy_tracker.appli.gui import Anim +from py_eddy_tracker.observations.network import NetworkObservations +from py_eddy_tracker.observations.tracking import TrackEddiesObservations + + +# %% +# Function used to do quick display +class VideoAnimation(FuncAnimation): + def _repr_html_(self, *args, **kwargs): + """To get video in html and have a player""" + return self.to_html5_video() + + 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 h: + pass + return + return super().save(*args, **kwargs) + + +@FuncFormatter +def formatter(x, pos): + return (timedelta(x) + datetime(1950, 1, 1)).strftime("%d/%m/%Y") + + +def start_axes(title=""): + fig = plt.figure(figsize=(13, 6)) + ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection="full_axes") + ax.set_xlim(19, 29), ax.set_ylim(31, 35.5) + ax.set_aspect("equal") + ax.set_title(title, weight="bold") + ax.update_env() + return ax + + +def timeline_axes(title=""): + fig = plt.figure(figsize=(15, 5)) + ax = fig.add_axes([0.04, 0.06, 0.89, 0.88]) + ax.set_title(title, weight="bold") + ax.xaxis.set_major_formatter(formatter), ax.grid() + return ax + + +def update_axes(ax, mappable=None): + ax.grid(True) + if mappable: + return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9])) + + +# %% +# Class for new_segmentation +# -------------------------- +# The oldest win +class MyTrackEddiesObservations(TrackEddiesObservations): + __slots__ = tuple() + + @classmethod + def follow_obs(cls, i_next, track_id, used, ids, *args, **kwargs): + """ + Method to overwrite behaviour in merging. + + We will give the point to the older one + """ + while i_next != -1: + # Flag + used[i_next] = True + # Assign id + ids["track"][i_next] = track_id + # Search next + i_next_ = cls.get_next_obs(i_next, ids, *args, **kwargs) + if i_next_ == -1: + break + ids["next_obs"][i_next] = i_next_ + # Target was previously used + if used[i_next_]: + # if ids["next_cost"][i_next] == ids["previous_cost"][i_next_]: + # print(ids[i_next]) + # print(ids[i_next_]) + # m = ids["track"][i_next_:] == ids["track"][i_next_] + # ids["track"][i_next_:][m] = track_id + # ids["previous_obs"][i_next_] = i_next + 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 np.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( + "/tmp/Anticyclonic_seg.nc" + # "/data/adelepoulle/work/Eddies/20201217_network_build/tracking/med/Anticyclonic_seg.nc" +) + +n = n.extract_with_mask(n.track == n.track[get_obs(n)]) +n_ = n.relative(get_obs(n), order=2) + +# %% +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 +# ---------------------- +e = n.astype(MyTrackEddiesObservations) +e.obs.sort(order=("track", "time"), kind="stable") +split_matrix = e.split_network(intern=False, window=7) +n_ = NetworkObservations.from_split_network(e, split_matrix) +n_ = n_.relative(get_obs(n_), order=2) +n_.numbering_segment() + +# %% +# New version +# ----------- +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) + +# %% +# Parameter timeline +# ------------------ +kw = dict(s=35, cmap=plt.get_cmap("Spectral_r", 8), zorder=10) +ax = timeline_axes() +n_.median_filter(15, "time", "latitude") +m = n_.scatter_timeline(ax, "shape_error_e", vmin=14, vmax=70, **kw, yfield="lat") +cb = update_axes(ax, m["scatter"]) +cb.set_label("Effective shape error") + +ax = timeline_axes() +n_.median_filter(15, "time", "latitude") +m = n_.scatter_timeline( + ax, "shape_error_e", vmin=14, vmax=70, **kw, yfield="lat", method="all" +) +cb = update_axes(ax, m["scatter"]) +cb.set_label("Effective shape error") +ax.set_ylabel("Latitude") + +ax = timeline_axes() +n_.median_filter(15, "time", "latitude") +kw["s"] = (n_.radius_e * 1e-3) ** 2 / 30 ** 2 * 20 +m = n_.scatter_timeline( + ax, + "shape_error_e", + vmin=14, + vmax=70, + **kw, + yfield="lon", + method="all", +) +ax.set_ylabel("Longitude") +cb = update_axes(ax, m["scatter"]) +cb.set_label("Effective shape error") + +# %% +# Cost association plot +# --------------------- +n_copy = n_.copy() +n_copy.median_filter(2, "time", "next_cost") +for b0, b1 in [ + (datetime(i, 1, 1), datetime(i, 12, 31)) for i in (2004, 2005, 2006, 2007, 2008) +]: + + ref, delta = datetime(1950, 1, 1), 20 + b0_, b1_ = (b0 - ref).days, (b1 - ref).days + ax = timeline_axes() + ax.set_xlim(b0_ - delta, b1_ + delta) + ax.set_ylim(0, 1) + ax.axvline(b0_, color="k", lw=1.5, ls="--"), ax.axvline( + b1_, color="k", lw=1.5, ls="--" + ) + n_copy.display_timeline(ax, field="next_cost", method="all", lw=4, markersize=8) + + n_.display_timeline(ax, field="next_cost", method="all", lw=0.5, markersize=0) From e50d3faeeeb3a786444e0f9140b1c4dc807d1919 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Wed, 3 Feb 2021 18:49:10 +0100 Subject: [PATCH 038/249] - allow to dissociate network which group several - add method to know if a network is fully connected --- src/py_eddy_tracker/observations/network.py | 72 ++++++++++++++++++++- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index d9a185de..f1e0a9a9 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -61,10 +61,26 @@ def load_contour(self, filename): class NetworkObservations(EddiesObservations): - __slots__ = tuple() + __slots__ = ("_index_network",) NOGROUP = 0 + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._index_network = None + + def network_slice(self, id_network): + """ + Return slice for one network + + :param int id_network: id to identify network + """ + if self._index_network is None: + self._index_network = build_index(self.track) + i = id_network - self._index_network[2] + i_start, i_stop = self._index_network[0][i], self._index_network[1][i] + return slice(i_start, i_stop) + @property def elements(self): elements = super().elements @@ -461,9 +477,56 @@ def spliting_event(self): indices.append(i.start) return self.extract_event(list(set(indices))) + def dissociate_network(self): + """ + Dissociate network with no known interaction (spliting/merging) + """ + self.only_one_network() + tags = self.tag_segment() + # FIXME : Ok if only one network + self.track[:] = tags[self.segment - 1] + + self.obs.sort(order=("track", "segment", "time")) + self._index_network = None + + # FIXME + # n & p must be re-index + # n, p = self.next_obs[mask], self.previous_obs[mask] + # we add 2 for -1 index return index -1 + # translate = -ones(len(self) + 1, dtype="i4") + # translate[:-1][mask] = arange(nb_obs) + # new.next_obs[:] = translate[n] + # new.previous_obs[:] = translate[p] + + def network(self, id_network): + return self.extract_with_mask(self.network_slice(id_network)) + + @classmethod + def __tag_segment(cls, seg, tag, groups, connexions): + if groups[seg] != 0: + return + groups[seg] = tag + segs = connexions.get(seg + 1, None) + if segs is not None: + for seg in segs: + cls.__tag_segment(seg - 1, tag, groups, connexions) + + def tag_segment(self): + self.only_one_network() + nb = self.segment.max() + sub_group = zeros(nb, dtype="u4") + c = self.connexions() + j = 1 + for i in range(nb): + if sub_group[i] != 0: + continue + self.__tag_segment(i, j, sub_group, c) + j += 1 + return sub_group + def fully_connected(self): self.only_one_network() - # TODO + return self.tag_segment().shape[0] == 1 def plot(self, ax, ref=None, color_cycle=None, **kwargs): """ @@ -545,7 +608,10 @@ def extract_with_mask(self, mask): :return: same object with selected observations :rtype: self """ - nb_obs = mask.sum() + if isinstance(mask, slice): + nb_obs = mask.stop - mask.start + else: + nb_obs = mask.sum() new = self.__class__.new_like(self, nb_obs) new.sign_type = self.sign_type if nb_obs == 0: From 403fbbbcfe7d1648efc6c0395bf6024841ed1bc0 Mon Sep 17 00:00:00 2001 From: CoriPegliasco <66008544+CoriPegliasco@users.noreply.github.com> Date: Fri, 5 Feb 2021 10:50:56 +0100 Subject: [PATCH 039/249] Display scattered maps (#49) add method for display network --- src/py_eddy_tracker/observations/network.py | 82 +++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index f1e0a9a9..2babaf9e 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -407,6 +407,88 @@ def scatter_timeline( mappables["scatter"] = ax.scatter(self.time, y, **kwargs) return mappables + def event_map(self, ax, **kwargs): + """Add the merging and splitting events """ + j = 0 + mappables = dict() + symbol_kw = dict( + markersize=10, + color="k", + ) + symbol_kw.update(kwargs) + symbol_kw_split = symbol_kw.copy() + symbol_kw_split["markersize"] += 5 + for i, b0, b1 in self.iter_on("segment"): + nb = i.stop - i.start + if nb == 0: + continue + event_kw = dict(color=self.COLORS[j % self.NB_COLORS], ls="-", **kwargs) + i_n, i_p = ( + self.next_obs[i.stop - 1], + self.previous_obs[i.start], + ) + + if i_n != -1: + y0, y1 = self.lat[i.stop - 1], self.lat[i_n] + x0, x1 = self.lon[i.stop - 1], self.lon[i_n] + ax.plot((x0, x1), (y0, y1), **event_kw)[0] + ax.plot(x0, y0, marker="s", **symbol_kw)[0] + if i_p != -1: + y0, y1 = self.lat[i.start], self.lat[i_p] + x0, x1 = self.lon[i.start], self.lon[i_p] + ax.plot((x0, x1), (y0, y1), **event_kw)[0] + ax.plot(x0, y0, marker="*", **symbol_kw_split)[0] + + j += 1 + return mappables + + def scatter( + self, + ax, + name="time", + factor=1, + ref=None, + edgecolor_cycle=None, + **kwargs, + ): + """ + This function will scatter the path of each network, with the merging and splitting events + + :param matplotlib.axes.Axes ax: matplotlib axe used to draw + :param str,array,None name: + variable used to fill the contour, if None all elements have the same color + :param float,None ref: if define use like west bound + :param float factor: multiply value by + :param list edgecolor_cycle: list of colors + :param dict kwargs: look at :py:meth:`matplotlib.axes.Axes.scatter` + :return: a dict of scattered mappables + """ + mappables = dict() + nb_colors = len(edgecolor_cycle) if edgecolor_cycle else None + x = self.longitude + if ref is not None: + x = (x - ref) % 360 + ref + kwargs = kwargs.copy() + if nb_colors: + edgecolors = list() + seg_previous = self.segment[0] + j = 0 + for seg in self.segment: + if seg != seg_previous: + j += 1 + edgecolors.append(edgecolor_cycle[j % nb_colors]) + seg_previous = seg + mappables["edges"] = ax.scatter( + x, self.latitude, edgecolor=edgecolors, **kwargs + ) + kwargs.pop("linewidths", None) + kwargs["lw"] = 0 + if name is not None and "c" not in kwargs: + v = self.parse_varname(name) + kwargs["c"] = v * factor + mappables["scatter"] = ax.scatter(x, self.latitude, **kwargs) + return mappables + def insert_virtual(self): # TODO pass From 97caffa9e5502b8ed2cd029703cceaf6406ca1c1 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Fri, 5 Feb 2021 18:36:17 +0100 Subject: [PATCH 040/249] Add method to remove dead end --- examples/16_network/pet_relative.py | 6 +- src/py_eddy_tracker/observations/network.py | 80 ++++++++++----------- 2 files changed, 39 insertions(+), 47 deletions(-) diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index 5fac0fc2..20e5a7d4 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -5,6 +5,7 @@ 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 @@ -106,11 +107,8 @@ # Remove dead branch # ------------------ # Remove all tiny segment with less than N obs which didn't join two segments -# -# .. warning:: -# Must be explore, no solution to solve all the case -n_clean = n.remove_dead_branch(nobs=51) +n_clean = n.remove_dead_end(nobs=10) fig = plt.figure(figsize=(15, 8)) ax = fig.add_axes([0.04, 0.54, 0.90, 0.40]) ax.set_title(f"Original network ({n.infos()})") diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 2babaf9e..887fb30f 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -69,16 +69,20 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._index_network = None + @property + def index_network(self): + if self._index_network is None: + self._index_network = build_index(self.track) + return self._index_network + def network_slice(self, id_network): """ Return slice for one network :param int id_network: id to identify network """ - if self._index_network is None: - self._index_network = build_index(self.track) - i = id_network - self._index_network[2] - i_start, i_stop = self._index_network[0][i], self._index_network[1][i] + i = id_network - self.index_network[2] + i_start, i_stop = self.index_network[0][i], self.index_network[1][i] return slice(i_start, i_stop) @property @@ -228,8 +232,9 @@ def only_one_network(self): Raise a warning or error? if there are more than one network """ - # TODO - pass + _, i_start, _ = self.index_network + if len(i_start) > 1: + raise Exception("Several network") def position_filter(self, median_half_window, loess_half_window): self.median_filter(median_half_window, "time", "lon").loess_filter( @@ -568,17 +573,19 @@ def dissociate_network(self): # FIXME : Ok if only one network self.track[:] = tags[self.segment - 1] - self.obs.sort(order=("track", "segment", "time")) + i_sort = self.obs.argsort(order=("track", "segment", "time"), kind="mergesort") + # Sort directly obs, with hope to save memory + self.obs.sort(order=("track", "segment", "time"), kind="mergesort") self._index_network = None - # FIXME # n & p must be re-index - # n, p = self.next_obs[mask], self.previous_obs[mask] + n, p = self.next_obs, self.previous_obs # we add 2 for -1 index return index -1 - # translate = -ones(len(self) + 1, dtype="i4") - # translate[:-1][mask] = arange(nb_obs) - # new.next_obs[:] = translate[n] - # new.previous_obs[:] = translate[p] + nb_obs = len(self) + translate = -ones(nb_obs + 1, dtype="i4") + translate[:-1][i_sort] = arange(nb_obs) + self.next_obs[:] = translate[n] + self.previous_obs[:] = translate[p] def network(self, id_network): return self.extract_with_mask(self.network_slice(id_network)) @@ -640,40 +647,27 @@ def plot(self, ax, ref=None, color_cycle=None, **kwargs): j += 1 return mappables - def remove_dead_branch(self, nobs=3): - """""" - # TODO: bug when spliting + def remove_dead_end(self, nobs=3, recursive=0, mask=None): + """ + .. warning:: + It will remove short segment which splits than merges with same segment + """ self.only_one_network() - segments_keep = list() - interaction_segments = dict() - segments_connexion = dict() + connexions = self.connexions() for i, b0, b1 in self.iter_on("segment"): nb = i.stop - i.start - i_p, i_n = self.previous_obs[i.start], self.next_obs[i.stop - 1] - seg = self.segment[i.start] - # segment of interaction - p_seg, n_seg = self.segment[i_p], self.segment[i_n] - if nb >= nobs: - segments_keep.append(seg) - else: - interaction_segments[seg] = ( - p_seg if i_p != -1 else -1, - n_seg if i_n != -1 else -1, - ) - # Where segment are called - if i_p != -1: - if p_seg not in segments_connexion: - segments_connexion[p_seg] = list() - segments_connexion[p_seg].append(seg) - if i_n != -1: - if n_seg not in segments_connexion: - segments_connexion[n_seg] = list() - segments_connexion[n_seg].append(seg) - print(interaction_segments) - print(segments_connexion) - print(segments_keep) - return self.extract_segment(tuple(segments_keep)) + if mask and mask[i].any(): + segments_keep.append(b0) + continue + if nb < nobs and len(connexions.get(b0, tuple())) < 2: + continue + segments_keep.append(b0) + if recursive > 0: + return self.extract_segment(segments_keep).remove_dead_end( + nobs, recursive - 1 + ) + return self.extract_segment(segments_keep) def extract_segment(self, segments): mask = ones(self.shape, dtype="bool") From 4149342900132d45e2e5bf0d1a2b88f6f1033462 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Fri, 5 Feb 2021 22:37:01 +0100 Subject: [PATCH 041/249] Add example of simple advection --- examples/06_grid_manipulation/pet_advect.py | 112 ++++++++++ .../06_grid_manipulation/pet_advect.ipynb | 191 ++++++++++++++++++ src/py_eddy_tracker/dataset/grid.py | 58 +++--- 3 files changed, 331 insertions(+), 30 deletions(-) create mode 100644 examples/06_grid_manipulation/pet_advect.py create mode 100644 notebooks/python_module/06_grid_manipulation/pet_advect.ipynb diff --git a/examples/06_grid_manipulation/pet_advect.py b/examples/06_grid_manipulation/pet_advect.py new file mode 100644 index 00000000..5b7a5ee4 --- /dev/null +++ b/examples/06_grid_manipulation/pet_advect.py @@ -0,0 +1,112 @@ +""" +Grid advection +============== + +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) +a.filled(ax, facecolors="r", alpha=0.1), c.filled(ax, facecolors="b", alpha=0.1) +_ = ax.quiver(x.T, y.T, g.grid("u"), g.grid("v"), scale=20) + + +# %% +class VideoAnimation(FuncAnimation): + def _repr_html_(self, *args, **kwargs): + """To get video in html and have a player""" + return self.to_html5_video() + + 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) + + +# %% +# Anim +# ---- +# Particules positions +x, y = np.meshgrid(np.arange(13, 36, 0.125), np.arange(28, 40, 0.125)) +x, y = x.reshape(-1), y.reshape(-1) +# Remove all original position that we can't advect at first place +m = ~np.isnan(g.interp("u", x, y)) +x, y = x[m], y[m] + +# Movie properties +kwargs = dict(frames=np.arange(51), interval=90) +kw_p = dict(nb_step=2, time_step=21600) +frame_t = kw_p["nb_step"] * kw_p["time_step"] / 86400.0 + + +def anim_ax(generator, **kw): + t = 0 + for _ in range(4): + generator.__next__() + t += frame_t + + fig = plt.figure(figsize=(10, 5), dpi=64) + ax = fig.add_axes([0, 0, 1, 1], projection="full_axes") + ax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid() + a.filled(ax, facecolors="r", alpha=0.1), c.filled(ax, facecolors="b", alpha=0.1) + return fig, ax.text(21, 32.1, ""), ax.plot([], [], "k", **kw)[0], t + + +def update(i_frame, t_step): + global t + x, y = p.__next__() + t += t_step + l.set_data(x, y) + txt.set_text(f"T0 + {t:.1f} days") + + +# %% +# Filament forward +# ^^^^^^^^^^^^^^^^ +p = g.filament(x, y, "u", "v", **kw_p, filament_size=4, rk4=True) +fig, txt, l, t = anim_ax(p, lw=0.5) +ani = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,)) + +# %% +# Filament backward +# ^^^^^^^^^^^^^^^^^ +p = g.filament(x, y, "u", "v", **kw_p, filament_size=4, backward=True, rk4=True) +fig, txt, l, t = anim_ax(p, lw=0.5) +ani = VideoAnimation(fig, update, **kwargs, fargs=(-frame_t,)) + +# %% +# Particule forward +# ^^^^^^^^^^^^^^^^^ +p = g.advect(x, y, "u", "v", **kw_p, rk4=True) +fig, txt, l, t = anim_ax(p, ls="", marker=".", markersize=1) +ani = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,)) diff --git a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb new file mode 100644 index 00000000..363ac76d --- /dev/null +++ b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb @@ -0,0 +1,191 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Grid advection\n\nDummy advection which use only static geostrophic current, which didn't resolve the complex circulation of the ocean.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\nfrom py_eddy_tracker.observations.observation import EddiesObservations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load Input grid, ADT is used to detect eddies\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "g = RegularGridDataset(\n data.get_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\n# Compute u/v from height\ng.add_uv(\"adt\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load detection files\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "a = EddiesObservations.load_file(data.get_path(\"Anticyclonic_20160515.nc\"))\nc = EddiesObservations.load_file(data.get_path(\"Cyclonic_20160515.nc\"))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Quiver from u/v with eddies\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(10, 5))\nax = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\nax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid()\nx, y = np.meshgrid(g.x_c, g.y_c)\na.filled(ax, facecolors=\"r\", alpha=0.1), c.filled(ax, facecolors=\"b\", alpha=0.1)\n_ = ax.quiver(x.T, y.T, g.grid(\"u\"), g.grid(\"v\"), scale=20)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n return self.to_html5_video()\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Anim\nParticules positions\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x, y = np.meshgrid(np.arange(13, 36, 0.125), np.arange(28, 40, 0.125))\nx, y = x.reshape(-1), y.reshape(-1)\n# Remove all original position that we can't advect at first place\nm = ~np.isnan(g.interp(\"u\", x, y))\nx, y = x[m], y[m]\n\n# Movie properties\nkwargs = dict(frames=np.arange(51), interval=90)\nkw_p = dict(nb_step=2, time_step=21600)\nframe_t = kw_p[\"nb_step\"] * kw_p[\"time_step\"] / 86400.0\n\n\ndef anim_ax(generator, **kw):\n t = 0\n for _ in range(4):\n generator.__next__()\n t += frame_t\n\n fig = plt.figure(figsize=(10, 5), dpi=64)\n ax = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\n ax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid()\n a.filled(ax, facecolors=\"r\", alpha=0.1), c.filled(ax, facecolors=\"b\", alpha=0.1)\n return fig, ax.text(21, 32.1, \"\"), ax.plot([], [], \"k\", **kw)[0], t\n\n\ndef update(i_frame, t_step):\n global t\n x, y = p.__next__()\n t += t_step\n l.set_data(x, y)\n txt.set_text(f\"T0 + {t:.1f} days\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Filament forward\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "p = g.filament(x, y, \"u\", \"v\", **kw_p, filament_size=4, rk4=True)\nfig, txt, l, t = anim_ax(p, lw=0.5)\nani = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Filament backward\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "p = g.filament(x, y, \"u\", \"v\", **kw_p, filament_size=4, backward=True, rk4=True)\nfig, txt, l, t = anim_ax(p, lw=0.5)\nani = VideoAnimation(fig, update, **kwargs, fargs=(-frame_t,))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Particule forward\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "p = g.advect(x, y, \"u\", \"v\", **kw_p, rk4=True)\nfig, txt, l, t = anim_ax(p, ls=\"\", marker=\".\", markersize=1)\nani = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index d9d0fced..f3dcb173 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -1953,7 +1953,7 @@ def interp(self, grid_name, lons, lats, method="bilinear"): self.x_c, self.y_c, g, m, lons, lats, nearest=method == "nearest" ) - def uv_for_advection(self, u_name, v_name, time_step=600, backward=False): + def uv_for_advection(self, u_name, v_name, time_step=600, backward=False, factor=1): """ Get U,V to be used in degrees with precomputed time step @@ -1961,8 +1961,8 @@ def uv_for_advection(self, u_name, v_name, time_step=600, backward=False): :param str,array v_name: V field to advect obs :param int time_step: Number of second for each advection """ - u = (self.grid(u_name) if isinstance(u_name, str) else u_name).copy() - v = (self.grid(v_name) if isinstance(v_name, str) else v_name).copy() + u = (self.grid(u_name) if isinstance(u_name, str) else u_name).copy() * factor + v = (self.grid(v_name) if isinstance(v_name, str) else v_name).copy() * factor # N seconds / 1 degrees in m coef = time_step * 180 / pi / self.EARTH_RADIUS u *= coef / cos(radians(self.y_c)) @@ -2050,39 +2050,20 @@ def advect_rk4(x_g, y_g, u_g, v_g, m_g, x, y, nb_step): x_, y_ = nan, nan break # k2, slope at middle with first guess position - u2, v2 = get_uv( - x_ref, - y_ref, - x_step, - y_step, - u_g, - v_g, - m_g, - x_ + u1 * 0.5, - y_ + v1 * 0.5, - ) + x1, y1 = x_ + u1 * 0.5, y_ + v1 * 0.5 + u2, v2 = get_uv(x_ref, y_ref, x_step, y_step, u_g, v_g, m_g, x1, y1) if isnan(u2) or isnan(v2): x_, y_ = nan, nan break # k3, slope at middle with update guess position - u3, v3 = get_uv( - x_ref, - y_ref, - x_step, - y_step, - u_g, - v_g, - m_g, - x_ + u2 * 0.5, - y_ + v2 * 0.5, - ) + x2, y2 = x_ + u2 * 0.5, y_ + v2 * 0.5 + u3, v3 = get_uv(x_ref, y_ref, x_step, y_step, u_g, v_g, m_g, x2, y2) if isnan(u3) or isnan(v3): x_, y_ = nan, nan break # k4, slope at end with update guess position - u4, v4 = get_uv( - x_ref, y_ref, x_step, y_step, u_g, v_g, m_g, x_ + u3, y_ + v3 - ) + x3, y3 = x_ + u3, y_ + v3 + u4, v4 = get_uv(x_ref, y_ref, x_step, y_step, u_g, v_g, m_g, x3, y3) if isnan(u4) or isnan(v4): x_, y_ = nan, nan break @@ -2246,15 +2227,32 @@ def __init__(self): self.datasets = list() @classmethod - def from_netcdf_cube(cls, filename, x_name, y_name, t_name): + def from_netcdf_cube(cls, filename, x_name, y_name, t_name, heigth=None): new = cls() with Dataset(filename) as h: for i, t in enumerate(h.variables[t_name][:]): d = RegularGridDataset(filename, x_name, y_name, indexs={t_name: i}) - d.add_uv("adt") + if heigth is not None: + d.add_uv(heigth) new.datasets.append((t, d)) return new + @classmethod + def from_netcdf_list(cls, filenames, t, x_name, y_name, indexs=None, heigth=None): + new = cls() + for i, t in enumerate(t): + d = RegularGridDataset(filenames[i], x_name, y_name, indexs=indexs) + if heigth is not None: + d.add_uv(heigth) + new.datasets.append((t, d)) + return new + + def __getitem__(self, item): + for t, d in self.datasets: + if t == item: + return d + raise KeyError(item) + def filament( self, x, From dbd44c1f1b4e01cddbcf7f8ad735e55a9993d97b Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Fri, 5 Feb 2021 23:08:55 +0100 Subject: [PATCH 042/249] setup readthedocs with conda --- .readthedocs.yml | 18 ++++++++++++++++++ doc/environment.yml | 21 +++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 .readthedocs.yml create mode 100644 doc/environment.yml diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 00000000..26b93108 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,18 @@ +version: 2 + +conda: + environment: docs/environment.yml + +build: + image: latest + +# This part is necessary otherwise the project is not built +python: + version: 3.7 + install: + - method: pip + path: . + +# By default readthedocs does not checkout git submodules +submodules: + include: all \ No newline at end of file diff --git a/doc/environment.yml b/doc/environment.yml new file mode 100644 index 00000000..d543a598 --- /dev/null +++ b/doc/environment.yml @@ -0,0 +1,21 @@ +channels: + - conda-forge +dependencies: + - python=3.7 + - ffmpeg + - matplotlib + - netCDF4 + - numba + - numpy + - opencv-python + - pint + - polygon3 + - pyyaml + - requests + - scipy + - zarr + - sphinx-gallery + - pyeddytrackersample + - sphinx_rtd_theme + - sphinx>=3.1 + From ab226ce7e6494579037076522384a46735ca453c Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Fri, 5 Feb 2021 23:10:28 +0100 Subject: [PATCH 043/249] Update .readthedocs.yml --- .readthedocs.yml | 14 +------------- doc/environment.yml | 25 ++++++------------------- 2 files changed, 7 insertions(+), 32 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 26b93108..14acf7e7 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,18 +1,6 @@ version: 2 -conda: - environment: docs/environment.yml - -build: - image: latest - -# This part is necessary otherwise the project is not built python: version: 3.7 install: - - method: pip - path: . - -# By default readthedocs does not checkout git submodules -submodules: - include: all \ No newline at end of file + - requirements: requirements_doc.txt diff --git a/doc/environment.yml b/doc/environment.yml index d543a598..ec163adc 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -1,21 +1,8 @@ -channels: - - conda-forge dependencies: - python=3.7 - - ffmpeg - - matplotlib - - netCDF4 - - numba - - numpy - - opencv-python - - pint - - polygon3 - - pyyaml - - requests - - scipy - - zarr - - sphinx-gallery - - pyeddytrackersample - - sphinx_rtd_theme - - sphinx>=3.1 - + - conda-forge::ffmpeg + - conda-forge::opencv + - pip: + - sphinx-gallery + - sphinx_rtd_theme + - sphinx>=3.1 From 581a637e8ff017d8577b0aa7d5ab7be907fdd344 Mon Sep 17 00:00:00 2001 From: CoriPegliasco <66008544+CoriPegliasco@users.noreply.github.com> Date: Tue, 9 Feb 2021 12:20:41 +0100 Subject: [PATCH 044/249] Change segment color in video and add comments (#50) - add scatter and event_map, change marker for event - Add documentation in examples --- examples/16_network/pet_atlas.py | 32 ++++++++++++--- examples/16_network/pet_ioannou_2017_case.py | 28 ++++++++++--- examples/16_network/pet_relative.py | 41 ++++++++++++++++--- .../16_network/pet_replay_segmentation.py | 20 +++++---- src/py_eddy_tracker/appli/gui.py | 6 ++- src/py_eddy_tracker/observations/network.py | 6 +-- 6 files changed, 106 insertions(+), 27 deletions(-) diff --git a/examples/16_network/pet_atlas.py b/examples/16_network/pet_atlas.py index 687e5d24..83dac5b1 100644 --- a/examples/16_network/pet_atlas.py +++ b/examples/16_network/pet_atlas.py @@ -1,6 +1,6 @@ """ -Network analyse -=============== +Network Analysis +================ """ from matplotlib import pyplot as plt from numpy import ma @@ -21,7 +21,7 @@ # %% -# Function +# Functions def start_axes(title): fig = plt.figure(figsize=(13, 5)) ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection="full_axes") @@ -41,6 +41,7 @@ def update_axes(ax, mappable=None): # %% # All # --- +# Display the % of time each pixel (1/10°) is within an anticyclonic network ax = start_axes("") g_all = n.grid_count(bins) m = g_all.display(ax, **kw_time, vmin=0, vmax=75) @@ -49,12 +50,16 @@ def update_axes(ax, mappable=None): # %% # Network longer than 10 days # --------------------------- +# Display the % of time each pixel (1/10°) is within an anticyclonic network +# which total lifetime in longer than 10 days ax = start_axes("") n10 = n.longer_than(10) g_10 = n10.grid_count(bins) m = g_10.display(ax, **kw_time, vmin=0, vmax=75) update_axes(ax, m).set_label("Pixel used in % of time") +# Display the ratio between the short and total presence. +# Red = mostly short networks ax = start_axes("") m = g_10.display( ax, @@ -67,12 +72,17 @@ def update_axes(ax, mappable=None): # %% # Network longer than 20 days # --------------------------- +# Display the % of time each pixel (1/10°) is within an anticyclonic network +# which total lifetime in longer than 20 days ax = start_axes("") n20 = n.longer_than(20) g_20 = n20.grid_count(bins) m = g_20.display(ax, **kw_time, vmin=0, vmax=75) update_axes(ax, m).set_label("Pixel used in % of time") +# %% +# Display the ratio between the short and total presence. +# Red = mostly short networks ax = start_axes("") m = g_20.display( ax, @@ -82,6 +92,11 @@ def update_axes(ax, mappable=None): name=g_20.vars["count"] * 100.0 / g_all.vars["count"] ) update_axes(ax, m).set_label("Pixel used in % all atlas") + +# %% +# Display the ratio between the short and total presence. +# Red = mostly short networks +# Networks shorter than 365 days are masked ax = start_axes("") m = g_20.display( ax, @@ -93,6 +108,11 @@ def update_axes(ax, mappable=None): ) ) update_axes(ax, m).set_label("Pixel used in % all atlas") +# %% +# Display the ratio between the short and total presence. +# Red = mostly short networks +# Networks longer than 365 days are masked +# -> Coastal areas are mostly populated by short networks ax = start_axes("") m = g_20.display( ax, @@ -110,11 +130,13 @@ def update_axes(ax, mappable=None): # %% # All merging # ----------- +# Display the occurence of merging events ax = start_axes("") g_all_merging = n.merging_event().grid_count(bins) m = g_all_merging.display(ax, **kw_time, vmin=0, vmax=0.2) update_axes(ax, m).set_label("Pixel used in % of time") # %% +# Ratio merging events / eddy presence ax = start_axes("") m = g_all_merging.display( ax, @@ -126,8 +148,8 @@ def update_axes(ax, mappable=None): update_axes(ax, m).set_label("Pixel used in % all atlas") # %% -# Merging in network longer than 10 days -# -------------------------------------- +# Merging in networks longer than 10 days +# --------------------------------------- ax = start_axes("") g_10_merging = n10.merging_event().grid_count(bins) m = g_10_merging.display(ax, **kw_time, vmin=0, vmax=0.2) diff --git a/examples/16_network/pet_ioannou_2017_case.py b/examples/16_network/pet_ioannou_2017_case.py index 906b90eb..93e0b4ef 100644 --- a/examples/16_network/pet_ioannou_2017_case.py +++ b/examples/16_network/pet_ioannou_2017_case.py @@ -4,12 +4,18 @@ Figure 10 from https://doi.org/10.1002/2017JC013158 """ + +# %% +# We want to find the Ierapetra Eddy described above in the networks + +# %% from datetime import datetime, timedelta import numpy as np from matplotlib import pyplot as plt from matplotlib.animation import FuncAnimation from matplotlib.ticker import FuncFormatter +from matplotlib import colors import py_eddy_tracker.gui from py_eddy_tracker.appli.gui import Anim @@ -62,6 +68,8 @@ def update_axes(ax, mappable=None): # %% +# We know the position and the time of a specific eddy +# `n.extract_with_mask` give us the corresponding network n = NetworkObservations.load_file( "med/Anticyclonic_seg.nc" ) @@ -77,6 +85,7 @@ def update_axes(ax, mappable=None): print(ioannou_case.infos()) # %% +# It seems that this network is huge! Our case is in purple... ax = start_axes() ioannou_case.plot(ax) update_axes(ax) @@ -84,6 +93,7 @@ def update_axes(ax, mappable=None): # %% # Full Timeline # ------------- +# The network span for many years... How to cut the interesting part? 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() @@ -93,6 +103,7 @@ def update_axes(ax, mappable=None): # %% # Sub network and new numbering # ----------------------------- +# Here we chose to keep only the order 3 segments relatives to our chosen eddy i = np.where( (ioannou_case.lat > 33) * (ioannou_case.lat < 34) @@ -107,10 +118,14 @@ def update_axes(ax, mappable=None): # %% # Anim # ---- +# Quick movie to see better! +cmap = colors.ListedColormap( + list(close_to_i3.COLORS), name="from_list", N=close_to_i3.segment.max() +) a = Anim( close_to_i3, figsize=(12, 4), - cmap="Spectral_r", + cmap=cmap, nb_step=7, dpi=55, field_color="segment", @@ -136,8 +151,8 @@ def update_axes(ax, mappable=None): update_axes(ax) # %% -# Local Timeline -# -------------- +# Latitude Timeline +# ----------------- ax = timeline_axes(f"Close segments ({close_to_i3.infos()})") n_copy = close_to_i3.copy() n_copy.median_filter(15, "time", "latitude") @@ -146,6 +161,7 @@ def update_axes(ax, mappable=None): # %% # Local radius timeline # --------------------- +# Effective (bold) and Speed (thin) Radius together n_copy.median_filter(2, "time", "radius_e") n_copy.median_filter(2, "time", "radius_s") for b0, b1 in [ @@ -167,14 +183,16 @@ def update_axes(ax, mappable=None): ) # %% -# Parameter timeline -# ------------------ +# Parameters timeline +# ------------------- +# Effective Radius kw = dict(s=35, cmap=plt.get_cmap("Spectral_r", 8), zorder=10) ax = timeline_axes() m = close_to_i3.scatter_timeline(ax, "radius_e", factor=1e-3, vmin=20, vmax=100, **kw) cb = update_axes(ax, m["scatter"]) cb.set_label("Effective radius (km)") # %% +# Shape error ax = timeline_axes() m = close_to_i3.scatter_timeline(ax, "shape_error_e", vmin=14, vmax=70, **kw) cb = update_axes(ax, m["scatter"]) diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index 20e5a7d4..7b6a96f4 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -19,7 +19,10 @@ 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)) # %% @@ -27,7 +30,9 @@ # -------- # %% -# Display timeline +# Display timeline with events +# A segment generated by a splitting is marked with a star +# A segment merging in another is marked with an exagon fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.04, 0.92, 0.92]) _ = n.display_timeline(ax) @@ -39,27 +44,34 @@ _ = n.display_timeline(ax, event=False) # %% -# Timeline by latitude mean +# Timeline by mean latitude # ------------------------- +# Display timeline with the mean latitude of the segments in yaxis fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.04, 0.92, 0.92]) +ax.set_ylabel("Latitude") _ = n.display_timeline(ax, field="latitude") # %% -# Timeline by radius mean +# Timeline by mean Effective Radius # ----------------------- +# The factor argument is applied on the chosen field fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.04, 0.92, 0.92]) -_ = n.display_timeline(ax, field="radius_e") +ax.set_ylabel("Effective Radius (km)") +_ = n.display_timeline(ax, field="radius_e", factor=1e-3) # %% # Timeline by latitude # -------------------- +# Use `method="all"` to display the consecutive values of the field fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.05, 0.92, 0.92]) +ax.set_ylabel("Latitude") _ = n.display_timeline(ax, field="lat", method="all") # %% +# You can filter the data, here with a time window of 15 days fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.05, 0.92, 0.92]) n_copy = n.copy() @@ -69,6 +81,8 @@ # %% # Parameters timeline # ------------------- +# Scatter is usefull to display the parameters' temporal evolution +# Effective Radius and Amplitude kw = dict(s=25, cmap="Spectral_r", zorder=10) fig = plt.figure(figsize=(15, 8)) ax = fig.add_axes([0.04, 0.54, 0.90, 0.44]) @@ -86,6 +100,7 @@ cb.set_label("Amplitude (cm)") # %% +# Speed fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) m = n.scatter_timeline(ax, "speed_average", factor=100, vmin=0, vmax=40, **kw) @@ -95,6 +110,7 @@ cb.set_label("Maximum speed (cm/s)") # %% +# Speed Radius fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) m = n.scatter_timeline(ax, "radius_s", factor=1e-3, vmin=20, vmax=100, **kw) @@ -106,7 +122,10 @@ # %% # Remove dead branch # ------------------ -# Remove all tiny segment with less than N obs which didn't join two segments +# Remove all tiny segments with less than N obs which didn't join two segments +# +# .. warning:: +# Must be explore, no solution to solve all the case n_clean = n.remove_dead_end(nobs=10) fig = plt.figure(figsize=(15, 8)) @@ -120,6 +139,7 @@ # %% # Keep close relative # ------------------- +# When you want to investigate one particular observation and select only the closest segments # First choose an observation in the network fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) @@ -130,6 +150,7 @@ _ = ax.plot(*obs_args, **obs_kw) # %% +# Colors show the relative order of the segment with regards to the chosen one fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) m = n.scatter_timeline( @@ -141,18 +162,21 @@ ) cb.set_label("Relative order") # %% +# You want to keep only the segments at the order 1 fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) close_to_i1 = n.relative(i, order=1) ax.set_title(f"Close segments ({close_to_i1.infos()})") _ = close_to_i1.display_timeline(ax) # %% +# You want to keep the segments until order 2 fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) close_to_i2 = n.relative(i, order=2) ax.set_title(f"Close segments ({close_to_i2.infos()})") _ = close_to_i2.display_timeline(ax) # %% +# You want to keep the segments until order 3 fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) close_to_i3 = n.relative(i, order=3) @@ -162,6 +186,7 @@ # %% # Display track on map # -------------------- +# Only a map can be tricky to understand, with a timeline it's easier! fig = plt.figure(figsize=(15, 8)) ax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection="full_axes") close_to_i2.plot(ax, color_cycle=close_to_i2.COLORS) @@ -173,6 +198,7 @@ # %% # Get merging event # ----------------- +# Display the position of the eddies after a merging fig = plt.figure(figsize=(15, 8)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") merging = close_to_i2.merging_event() @@ -183,6 +209,7 @@ # %% # Get spliting event # ------------------ +# Display the position of the eddies before a splitting fig = plt.figure(figsize=(15, 8)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") spliting = close_to_i2.spliting_event() @@ -193,6 +220,7 @@ # %% # Get birth event # ------------------ +# Display the starting position of non-splitted eddies fig = plt.figure(figsize=(15, 8)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") birth = close_to_i2.birth_event() @@ -203,6 +231,7 @@ # %% # Get death event # ------------------ +# Display the last position of non-merged eddies fig = plt.figure(figsize=(15, 8)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") death = close_to_i2.death_event() diff --git a/examples/16_network/pet_replay_segmentation.py b/examples/16_network/pet_replay_segmentation.py index 67c89127..c90fca9d 100644 --- a/examples/16_network/pet_replay_segmentation.py +++ b/examples/16_network/pet_replay_segmentation.py @@ -4,12 +4,17 @@ Case from figure 10 from https://doi.org/10.1002/2017JC013158 """ + +# %% +# Again with the Ierapetra Eddy + from datetime import datetime, timedelta import numpy as np from matplotlib import pyplot as plt from matplotlib.animation import FuncAnimation from matplotlib.ticker import FuncFormatter +from matplotlib import colors import py_eddy_tracker.gui from py_eddy_tracker.appli.gui import Anim @@ -75,7 +80,7 @@ def follow_obs(cls, i_next, track_id, used, ids, *args, **kwargs): """ Method to overwrite behaviour in merging. - We will give the point to the older one + We will give the point to the older one instead of the maximum overlap ratio """ while i_next != -1: # Flag @@ -116,14 +121,14 @@ def get_obs(dataset): # %% # Get original network, we will isolate only relative at order *2* n = NetworkObservations.load_file( - "/tmp/Anticyclonic_seg.nc" - # "/data/adelepoulle/work/Eddies/20201217_network_build/tracking/med/Anticyclonic_seg.nc" + "/data/adelepoulle/work/Eddies/20201217_network_build/tracking/med/Anticyclonic_seg.nc" ) n = n.extract_with_mask(n.track == n.track[get_obs(n)]) 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) @@ -143,8 +148,9 @@ def get_obs(dataset): n_.numbering_segment() # %% -# New version -# ----------- +# New segmentation +# ---------------- +# "The oldest wins" method produce a very long segment ax = start_axes(n_.infos()) n_.plot(ax, color_cycle=n_.COLORS) update_axes(ax) @@ -154,8 +160,8 @@ def get_obs(dataset): _ = n_.display_timeline(ax) # %% -# Parameter timeline -# ------------------ +# Parameters timeline +# ------------------- kw = dict(s=35, cmap=plt.get_cmap("Spectral_r", 8), zorder=10) ax = timeline_axes() n_.median_filter(15, "time", "latitude") diff --git a/src/py_eddy_tracker/appli/gui.py b/src/py_eddy_tracker/appli/gui.py index bbe5067c..e9ff7f7a 100644 --- a/src/py_eddy_tracker/appli/gui.py +++ b/src/py_eddy_tracker/appli/gui.py @@ -186,7 +186,11 @@ def update(self): # Update id txt for i in where(m)[0]: mappable = self.ax.text( - self.x_core[i], self.y_core[i], self.field_txt[i], fontsize=8 + self.x_core[i], + self.y_core[i], + self.field_txt[i], + fontsize=12, + fontweight="demibold", ) self.mappables.append(mappable) self.ax.draw_artist(mappable) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 887fb30f..74bec98d 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -338,7 +338,7 @@ def event_timeline(self, ax, field=None, method=None, factor=1): ) ) ax.plot((x[-1], self.time[i_n]), (y0, y1), **event_kw)[0] - ax.plot(x[-1], y0, color="k", marker=">", markersize=10, zorder=-1)[0] + ax.plot(x[-1], y0, color="k", marker="H", markersize=10, zorder=-1)[0] if i_p != -1: seg_previous = self.segment[i_p] if field is not None and method == "all": @@ -422,7 +422,7 @@ def event_map(self, ax, **kwargs): ) symbol_kw.update(kwargs) symbol_kw_split = symbol_kw.copy() - symbol_kw_split["markersize"] += 5 + symbol_kw_split["markersize"] += 4 for i, b0, b1 in self.iter_on("segment"): nb = i.stop - i.start if nb == 0: @@ -437,7 +437,7 @@ def event_map(self, ax, **kwargs): y0, y1 = self.lat[i.stop - 1], self.lat[i_n] x0, x1 = self.lon[i.stop - 1], self.lon[i_n] ax.plot((x0, x1), (y0, y1), **event_kw)[0] - ax.plot(x0, y0, marker="s", **symbol_kw)[0] + ax.plot(x0, y0, marker="H", **symbol_kw)[0] if i_p != -1: y0, y1 = self.lat[i.start], self.lat[i_p] x0, x1 = self.lon[i.start], self.lon[i_p] From e7f25c025d2ddb1930ea6d708b2015ebc573e809 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 9 Feb 2021 15:58:19 +0100 Subject: [PATCH 045/249] update doc installation --- .readthedocs.yml | 7 ++++--- doc/environment.yml | 7 +++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 14acf7e7..1299f38e 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,6 +1,7 @@ version: 2 - +conda: + environment: doc/environment.yml python: - version: 3.7 install: - - requirements: requirements_doc.txt + - method: setuptools + path: . diff --git a/doc/environment.yml b/doc/environment.yml index ec163adc..db50b528 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -1,8 +1,11 @@ +channels: + - conda-forge + - defaults dependencies: - python=3.7 - - conda-forge::ffmpeg - - conda-forge::opencv + - ffmpeg - pip: - sphinx-gallery - sphinx_rtd_theme - sphinx>=3.1 + - pyeddytrackersample From 401f1ab638e5d426e79c229143682e57e7e2da51 Mon Sep 17 00:00:00 2001 From: CoriPegliasco <66008544+CoriPegliasco@users.noreply.github.com> Date: Wed, 10 Feb 2021 10:17:13 +0100 Subject: [PATCH 046/249] add merging and splitting triplets (#51) add triplet in merging and splitting --- examples/16_network/pet_atlas.py | 27 ++++--- examples/16_network/pet_ioannou_2017_case.py | 1 + examples/16_network/pet_relative.py | 32 ++++++-- src/py_eddy_tracker/observations/network.py | 82 ++++++++++++++++---- 4 files changed, 111 insertions(+), 31 deletions(-) diff --git a/examples/16_network/pet_atlas.py b/examples/16_network/pet_atlas.py index 83dac5b1..cbb7b3e9 100644 --- a/examples/16_network/pet_atlas.py +++ b/examples/16_network/pet_atlas.py @@ -17,7 +17,7 @@ step = 1 / 10.0 bins = ((-10, 37, step), (30, 46, step)) kw_time = dict(cmap="terrain_r", factor=100.0 / n.nb_days, name="count") -kw_ratio = dict(cmap=plt.get_cmap("coolwarm_r", 10)) +kw_ratio = dict(cmap=plt.get_cmap("magma_r", 10)) # %% @@ -58,8 +58,10 @@ def update_axes(ax, mappable=None): m = g_10.display(ax, **kw_time, vmin=0, vmax=75) update_axes(ax, m).set_label("Pixel used in % of time") +# %% # Display the ratio between the short and total presence. -# Red = mostly short networks +# +# Light = mostly short networks ax = start_axes("") m = g_10.display( ax, @@ -73,7 +75,7 @@ def update_axes(ax, mappable=None): # Network longer than 20 days # --------------------------- # Display the % of time each pixel (1/10°) is within an anticyclonic network -# which total lifetime in longer than 20 days +# which total lifetime is longer than 20 days ax = start_axes("") n20 = n.longer_than(20) g_20 = n20.grid_count(bins) @@ -82,7 +84,8 @@ def update_axes(ax, mappable=None): # %% # Display the ratio between the short and total presence. -# Red = mostly short networks +# +# Light = mostly short networks ax = start_axes("") m = g_20.display( ax, @@ -95,7 +98,9 @@ def update_axes(ax, mappable=None): # %% # Display the ratio between the short and total presence. -# Red = mostly short networks +# +# Light = mostly short networks +# # Networks shorter than 365 days are masked ax = start_axes("") m = g_20.display( @@ -110,9 +115,10 @@ def update_axes(ax, mappable=None): update_axes(ax, m).set_label("Pixel used in % all atlas") # %% # Display the ratio between the short and total presence. -# Red = mostly short networks +# # Networks longer than 365 days are masked -# -> Coastal areas are mostly populated by short networks +# +# # -> Coastal areas are mostly populated by short networks ax = start_axes("") m = g_20.display( ax, @@ -133,8 +139,9 @@ def update_axes(ax, mappable=None): # Display the occurence of merging events ax = start_axes("") g_all_merging = n.merging_event().grid_count(bins) -m = g_all_merging.display(ax, **kw_time, vmin=0, vmax=0.2) +m = g_all_merging.display(ax, **kw_time, vmin=0, vmax=1) update_axes(ax, m).set_label("Pixel used in % of time") + # %% # Ratio merging events / eddy presence ax = start_axes("") @@ -152,7 +159,7 @@ def update_axes(ax, mappable=None): # --------------------------------------- ax = start_axes("") g_10_merging = n10.merging_event().grid_count(bins) -m = g_10_merging.display(ax, **kw_time, vmin=0, vmax=0.2) +m = g_10_merging.display(ax, **kw_time, vmin=0, vmax=1) update_axes(ax, m).set_label("Pixel used in % of time") # %% ax = start_axes("") @@ -160,7 +167,7 @@ def update_axes(ax, mappable=None): ax, **kw_ratio, vmin=0, - vmax=0.5, + vmax=2, name=ma.array( g_10_merging.vars["count"] * 100.0 / g_10.vars["count"], mask=g_10.vars["count"] < 365, diff --git a/examples/16_network/pet_ioannou_2017_case.py b/examples/16_network/pet_ioannou_2017_case.py index 93e0b4ef..2e7f807e 100644 --- a/examples/16_network/pet_ioannou_2017_case.py +++ b/examples/16_network/pet_ioannou_2017_case.py @@ -69,6 +69,7 @@ def update_axes(ax, mappable=None): # %% # We know the position and the time of a specific eddy +# # `n.extract_with_mask` give us the corresponding network n = NetworkObservations.load_file( "med/Anticyclonic_seg.nc" diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index 7b6a96f4..f743d3b4 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -32,6 +32,7 @@ # %% # Display timeline with events # A segment generated by a splitting is marked with a star +# # A segment merging in another is marked with an exagon fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.04, 0.92, 0.92]) @@ -82,6 +83,7 @@ # Parameters timeline # ------------------- # Scatter is usefull to display the parameters' temporal evolution +# # Effective Radius and Amplitude kw = dict(s=25, cmap="Spectral_r", zorder=10) fig = plt.figure(figsize=(15, 8)) @@ -125,7 +127,7 @@ # Remove all tiny segments with less than N obs which didn't join two segments # # .. warning:: -# Must be explore, no solution to solve all the case +# Must be explore, no solution to solve all cases n_clean = n.remove_dead_end(nobs=10) fig = plt.figure(figsize=(15, 8)) @@ -140,6 +142,7 @@ # Keep close relative # ------------------- # When you want to investigate one particular observation and select only the closest segments +# # First choose an observation in the network fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) @@ -201,10 +204,18 @@ # Display the position of the eddies after a merging fig = plt.figure(figsize=(15, 8)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") -merging = close_to_i2.merging_event() -merging.display(ax) +close_to_i2.plot(ax, color_cycle=close_to_i2.COLORS) +m1, m0, m0_stop = close_to_i2.merging_event(triplet=True) +m1.display(ax, color="violet", lw=2, label="Eddies after merging") +m0.display(ax, color="blueviolet", lw=2, label="Eddies before merging") +m0_stop.display(ax, color="black", lw=2, label="Eddies stopped by merging") +ax.plot(m1.lon, m1.lat, marker=".", color="purple", ls="") +ax.plot(m0.lon, m0.lat, marker=".", color="blueviolet", ls="") +ax.plot(m0_stop.lon, m0_stop.lat, marker=".", color="black", ls="") +ax.legend() ax.set_xlim(-10, 20), ax.set_ylim(-37, -21), ax.grid() -merging +m1 + # %% # Get spliting event @@ -212,10 +223,17 @@ # Display the position of the eddies before a splitting fig = plt.figure(figsize=(15, 8)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") -spliting = close_to_i2.spliting_event() -spliting.display(ax) +close_to_i2.plot(ax, color_cycle=close_to_i2.COLORS) +s0, s1, s1_start = close_to_i2.spliting_event(triplet=True) +s0.display(ax, color="violet", lw=2, label="Eddies before splitting") +s1.display(ax, color="blueviolet", lw=2, label="Eddies after splitting") +s1_start.display(ax, color="black", lw=2, label="Eddies starting by splitting") +ax.plot(s0.lon, s0.lat, marker=".", color="purple", ls="") +ax.plot(s1.lon, s1.lat, marker=".", color="blueviolet", ls="") +ax.plot(s1_start.lon, s1_start.lat, marker=".", color="black", ls="") +ax.legend() ax.set_xlim(-10, 20), ax.set_ylim(-37, -21), ax.grid() -spliting +s1 # %% # Get birth event diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 74bec98d..34a47c3a 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -113,8 +113,8 @@ def longer_than(self, nb_day_min=-1, nb_day_max=-1): """ Select network on time duration - :param int nb_day_min: Minimal number of day which must be covered by one network, if negative -> not used - :param int nb_day_max: Maximal number of day which must be covered by one network, if negative -> not used + :param int nb_day_min: Minimal number of day covered by one network, if negative -> not used + :param int nb_day_max: Maximal number of day covered by one network, if negative -> not used """ if nb_day_max < 0: nb_day_max = 1000000000000 @@ -132,7 +132,7 @@ def longer_than(self, nb_day_min=-1, nb_day_max=-1): @classmethod def from_split_network(cls, group_dataset, indexs, **kwargs): """ - Build a NetworkObservations object with Group dataset and indexs + Build a NetworkObservations object with Group dataset and indexes :param TrackEddiesObservations group_dataset: Group dataset :param indexs: result from split_network @@ -204,6 +204,9 @@ def __close_segment(cls, father, shift, connexions, distance): cls.__close_segment(son, shift, connexions, distance) def segment_relative_order(self, seg_origine): + """ + Compute the relative order of each segment to the chosen segment + """ i_s, i_e, i_ref = build_index(self.segment) segment_connexions = self.connexions() relative_tr = -ones(i_s.shape, dtype="i4") @@ -216,6 +219,9 @@ def segment_relative_order(self, seg_origine): return d def relative(self, i_obs, order=2, direct=True, only_past=False, only_future=False): + """ + Extract the segments at a certain order. + """ d = self.segment_relative_order(self.segment[i_obs]) m = (d <= order) * (d != -1) return self.extract_with_mask(m) @@ -234,7 +240,7 @@ def only_one_network(self): """ _, i_start, _ = self.index_network if len(i_start) > 1: - raise Exception("Several network") + raise Exception("Several networks") def position_filter(self, median_half_window, loess_half_window): self.median_filter(median_half_window, "time", "lon").loess_filter( @@ -266,7 +272,15 @@ def display_timeline( self, ax, event=True, field=None, method=None, factor=1, **kwargs ): """ - Must be call on only one network + Plot a timeline of a network. + Must be called on only one network. + + :param matplotlib.axes.Axes ax: matplotlib axe used to draw + :param bool event: if True, draw the splitting and merging events + :param str,array field: yaxis values, if None, segments are used + :param str method: if None, mean values are used + :param float factor: to multiply field + :return: plot mappable """ self.only_one_network() j = 0 @@ -516,6 +530,7 @@ def extract_event(self, indices): @property def segment_track_array(self): + """Return a unique segment id when multiple networks are considered""" return build_unique_array(self.segment, self.track) def birth_event(self): @@ -542,27 +557,65 @@ def death_event(self): indices.append(i.stop - 1) return self.extract_event(list(set(indices))) - def merging_event(self): - indices = list() + def merging_event(self, triplet=False): + """Return observation after a merging event. + + If `triplet=True` return the eddy after a merging event, the eddy before the merging event, + and the eddy stopped due to merging. + """ + idx_m1 = list() + if triplet: + idx_m0_stop = list() + idx_m0 = list() + for i, _, _ in self.iter_on(self.segment_track_array): nb = i.stop - i.start if nb == 0: continue i_n = self.next_obs[i.stop - 1] if i_n != -1: - indices.append(i.stop - 1) - return self.extract_event(list(set(indices))) + if triplet: + idx_m0_stop.append(i.stop - 1) + idx_m0.append(self.previous_obs[i_n]) + idx_m1.append(i_n) + + if triplet: + return ( + self.extract_event(list(idx_m1)), + self.extract_event(list(idx_m0)), + self.extract_event(list(idx_m0_stop)), + ) + else: + return self.extract_event(list(set(idx_m1))) - def spliting_event(self): - indices = list() + def spliting_event(self, triplet=False): + """Return observation before a splitting event. + + If `triplet=True` return the eddy before a splitting event, the eddy after the splitting event, + and the eddy starting due to splitting. + """ + idx_s0 = list() + if triplet: + idx_s1_start = list() + idx_s1 = list() for i, _, _ in self.iter_on(self.segment_track_array): nb = i.stop - i.start if nb == 0: continue i_p = self.previous_obs[i.start] if i_p != -1: - indices.append(i.start) - return self.extract_event(list(set(indices))) + if triplet: + idx_s1_start.append(i.start) + idx_s1.append(self.next_obs[i_p]) + idx_s0.append(i_p) + if triplet: + return ( + self.extract_event(list(idx_s0)), + self.extract_event(list(idx_s1)), + self.extract_event(list(idx_s1_start)), + ) + else: + return self.extract_event(list(set(idx_s0))) def dissociate_network(self): """ @@ -655,7 +708,7 @@ def remove_dead_end(self, nobs=3, recursive=0, mask=None): self.only_one_network() segments_keep = list() connexions = self.connexions() - for i, b0, b1 in self.iter_on("segment"): + for i, b0, _ in self.iter_on("segment"): nb = i.stop - i.start if mask and mask[i].any(): segments_keep.append(b0) @@ -852,6 +905,7 @@ def apply_replace(x, x0, x1): @njit(cache=True) def build_unique_array(id1, id2): + """Give a unique id for each (id1, id2) with id1 and id2 increasing monotonically""" k = 0 new_id = empty(id1.shape, dtype=id1.dtype) id1_previous = id1[0] From aa82bbc087a32019facd67ff3a067b7d723f0705 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Fri, 12 Feb 2021 10:03:02 +0100 Subject: [PATCH 047/249] Add an example about LAVD --- examples/06_grid_manipulation/pet_lavd.py | 174 +++++++++++++++ .../06_grid_manipulation/pet_lavd.ipynb | 209 ++++++++++++++++++ .../14_generic_tools/pet_fit_contour.ipynb | 47 +++- requirements_doc.txt | 1 + 4 files changed, 429 insertions(+), 2 deletions(-) create mode 100644 examples/06_grid_manipulation/pet_lavd.py create mode 100644 notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb diff --git a/examples/06_grid_manipulation/pet_lavd.py b/examples/06_grid_manipulation/pet_lavd.py new file mode 100644 index 00000000..1c662ec9 --- /dev/null +++ b/examples/06_grid_manipulation/pet_lavd.py @@ -0,0 +1,174 @@ +""" +LAVD experiment +=============== + +Naive method to reproduce LAVD(Lagrangian-Averaged Vorticity deviation) method with a static velocity field. +In the current example we didn't remove a mean vorticity. + +Method are described here: + + - `Transport by Lagrangian Vortices in the Eastern Pacific `_ + - `Transport by Coherent Lagrangian Vortices`_ + +.. _Transport by Coherent Lagrangian Vortices: + https://usclivar.org/sites/default/files/meetings/2019/presentations/Aberernathey_CLIVAR.pdf + +""" +import re + +from matplotlib import pyplot as plt +from matplotlib.animation import FuncAnimation +from numpy import arange, meshgrid, zeros + +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.network import NetworkObservations + + +# %% +def start_ax(title="", dpi=90): + fig = plt.figure(figsize=(16, 9), dpi=dpi) + ax = fig.add_axes([0, 0, 1, 1], projection="full_axes") + ax.set_xlim(0, 32), ax.set_ylim(28, 46), ax.update_env() + ax.set_title(title) + return fig, ax, ax.text(3, 32, "", fontsize=20) + + +def update_axes(ax, mappable=None): + ax.grid() + if mappable: + cb = plt.colorbar( + mappable, + cax=ax.figure.add_axes([0.05, 0.1, 0.9, 0.01]), + orientation="horizontal", + ) + cb.set_label("Vorticity integration along trajectory at initial position") + + +kw_vorticity = dict(vmin=0, vmax=2e-5, cmap="viridis") + + +# %% +class VideoAnimation(FuncAnimation): + def _repr_html_(self, *args, **kwargs): + """To get video in html and have a player""" + content = self.to_html5_video() + return re.sub( + r'width="[0-9]*"\sheight="[0-9]*"', 'width="100%" height="100%"', content + ) + + return + + 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 +# ---- +# 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 +# --------- +# 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 +# Compute step of advection every 4h +nb_step = 2 +kw_p = dict(nb_step=nb_step, time_step=86400 / step_by_day / nb_step) +# Start a generator which at each iteration return new position at next time step +particule = g.advect(x, y, "u", "v", **kw_p, rk4=True) + +# %% +# LAVD +# ---- +lavd = zeros(original_shape) +# Advection time +nb_days = 8 +# Nb frame +nb_time = step_by_day * nb_days +i = 0.0 + + +# %% +# Anim +# ^^^^ +# Movie of LAVD integration at each integration time step. +def update(i_frame): + global lavd, i + i += 1 + x, y = particule.__next__() + # Interp vorticity on new_position + lavd += abs(g.interp("vort", x, y).reshape(original_shape) * 1 / nb_time) + txt.set_text(f"T0 + {i / step_by_day:.2f} days of advection") + pcolormesh.set_array(lavd / i * nb_time) + return pcolormesh, txt + + +kw_video = dict(frames=arange(nb_time), interval=1000.0 / step_by_day / 2, blit=True) +fig, ax, txt = start_ax(dpi=60) +x_g_, y_g_ = arange(0 - step / 2, 36 + step / 2, step), arange( + 28 - step / 2, 46 + step / 2, step +) +# pcolorfast will be faster than pcolormesh, we could use pcolorfast due to x and y are regular +pcolormesh = ax.pcolorfast(x_g_, y_g_, lavd, **kw_vorticity) +update_axes(ax, pcolormesh) +ani = VideoAnimation(ax.figure, update, **kw_video) + +# %% +# Final LAVD +# ^^^^^^^^^^ + +# %% +# Format LAVD data +lavd = RegularGridDataset.with_array( + coordinates=("lon", "lat"), + datas=dict( + lavd=lavd.T, + lon=x_g, + lat=y_g, + ), + centered=True, +) + +# %% +# Display final LAVD with py eddy tracker detection. +# Period used for LAVD integration(8 days) is too short for a real use, but choose for example efficiency. +fig, ax, _ = start_ax() +mappable = lavd.display(ax, "lavd", **kw_vorticity) +NetworkObservations.load_file(get_path("Anticyclonic_20160515.nc")).display( + ax, color="k" +) +NetworkObservations.load_file(get_path("Cyclonic_20160515.nc")).display(ax, color="k") +update_axes(ax, mappable) diff --git a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb new file mode 100644 index 00000000..3d925a53 --- /dev/null +++ b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb @@ -0,0 +1,209 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# LAVD experiment\n\nNaive method to reproduce LAVD(Lagrangian-Averaged Vorticity deviation) method with a static velocity field.\nIn the current example we didn't remove a mean vorticity.\n\nMethod are described here:\n\n - `Transport by Lagrangian Vortices in the Eastern Pacific `_\n - `Transport by Coherent Lagrangian Vortices`_\n\n https://usclivar.org/sites/default/files/meetings/2019/presentations/Aberernathey_CLIVAR.pdf\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, meshgrid, zeros\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\nfrom py_eddy_tracker.observations.network import NetworkObservations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def start_ax(title=\"\", dpi=90):\n fig = plt.figure(figsize=(16, 9), dpi=dpi)\n ax = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\n ax.set_xlim(0, 32), ax.set_ylim(28, 46), ax.update_env()\n ax.set_title(title)\n return fig, ax, ax.text(3, 32, \"\", fontsize=20)\n\n\ndef update_axes(ax, mappable=None):\n ax.grid()\n if mappable:\n cb = plt.colorbar(\n mappable,\n cax=ax.figure.add_axes([0.05, 0.1, 0.9, 0.01]),\n orientation=\"horizontal\",\n )\n cb.set_label(\"Vorticity integration along trajectory at initial position\")\n\n\nkw_vorticity = dict(vmin=0, vmax=2e-5, cmap=\"viridis\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n return\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Data\nTo compute vorticity($\\omega$) we compute u/v field with a stencil and apply the following equation with stencil\nmethod :\n\n\\begin{align}\\omega = \\frac{\\partial v}{\\partial x} - \\frac{\\partial u}{\\partial y}\\end{align}\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "g = RegularGridDataset(\n get_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\ng.add_uv(\"adt\")\nu_y = g.compute_stencil(g.grid(\"u\"), vertical=True)\nv_x = g.compute_stencil(g.grid(\"v\"))\ng.vars[\"vort\"] = v_x - u_y" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Display vorticity field\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig, ax, _ = start_ax()\nmappable = g.display(ax, abs(g.grid(\"vort\")), **kw_vorticity)\nupdate_axes(ax, mappable)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Particles\nParticles specification\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "step = 1 / 32\nx_g, y_g = arange(0, 36, step), arange(28, 46, step)\nx, y = meshgrid(x_g, y_g)\noriginal_shape = x.shape\nx, y = x.reshape(-1), y.reshape(-1)\nprint(f\"{len(x)} particles advected\")\n# A frame every 8h\nstep_by_day = 3\n# Compute step of advection every 4h\nnb_step = 2\nkw_p = dict(nb_step=nb_step, time_step=86400 / step_by_day / nb_step)\n# Start a generator which at each iteration return new position at next time step\nparticule = g.advect(x, y, \"u\", \"v\", **kw_p, rk4=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## LAVD\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "lavd = zeros(original_shape)\n# Advection time\nnb_days = 8\n# Nb frame\nnb_time = step_by_day * nb_days\ni = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Anim\nMovie of LAVD integration at each integration time step.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def update(i_frame):\n global lavd, i\n i += 1\n x, y = particule.__next__()\n # Interp vorticity on new_position\n lavd += abs(g.interp(\"vort\", x, y).reshape(original_shape) * 1 / nb_time)\n txt.set_text(f\"T0 + {i / step_by_day:.2f} days of advection\")\n pcolormesh.set_array(lavd / i * nb_time)\n return pcolormesh, txt\n\n\nkw_video = dict(frames=arange(nb_time), interval=1000.0 / step_by_day / 2, blit=True)\nfig, ax, txt = start_ax(dpi=60)\nx_g_, y_g_ = arange(0 - step / 2, 36 + step / 2, step), arange(\n 28 - step / 2, 46 + step / 2, step\n)\n# pcolorfast will be faster than pcolormesh, we could use pcolorfast due to x and y are regular\npcolormesh = ax.pcolorfast(x_g_, y_g_, lavd, **kw_vorticity)\nupdate_axes(ax, pcolormesh)\nani = VideoAnimation(ax.figure, update, **kw_video)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Final LAVD\n\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Format LAVD data\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "lavd = RegularGridDataset.with_array(\n coordinates=(\"lon\", \"lat\"),\n datas=dict(\n lavd=lavd.T,\n lon=x_g,\n lat=y_g,\n ),\n centered=True,\n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Display final LAVD with py eddy tracker detection.\nPeriod used for LAVD integration(8 days) is too short for a real use, but choose for example efficiency.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig, ax, _ = start_ax()\nmappable = lavd.display(ax, \"lavd\", **kw_vorticity)\nNetworkObservations.load_file(get_path(\"Anticyclonic_20160515.nc\")).display(\n ax, color=\"k\"\n)\nNetworkObservations.load_file(get_path(\"Cyclonic_20160515.nc\")).display(ax, color=\"k\")\nupdate_axes(ax, mappable)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb b/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb index 9a211723..9f5bbc84 100644 --- a/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb +++ b/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb @@ -26,7 +26,50 @@ }, "outputs": [], "source": [ - "from py_eddy_tracker.poly import fit_circle_, fit_ellips, fit_circle\nfrom py_eddy_tracker.generic import local_to_coordinates, coordinates_to_local\nfrom matplotlib import pyplot as plt\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.observations.observation import EddiesObservations\nfrom numpy import radians, linspace, cos, sin\n\na = EddiesObservations.load_file(data.get_path(\"Anticyclonic_20190223.nc\"))\n\n\ndef build_circle(x0, y0, r):\n angle = radians(linspace(0, 360, 50))\n x_norm, y_norm = cos(angle), sin(angle)\n return local_to_coordinates(x_norm * r, y_norm * r, x0, y0)\n\ndef build_ellips(x0, y0, a, b, theta):\n angle = radians(linspace(0, 360, 50))\n x = a * cos(theta) * cos(angle) - b * sin(theta) * sin(angle)\n y = a * sin(theta) * cos(angle) + b * cos(theta) * sin(angle)\n return local_to_coordinates(x, y, x0, y0)" + "from matplotlib import pyplot as plt\nfrom numpy import cos, linspace, radians, sin\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.generic import coordinates_to_local, local_to_coordinates\nfrom py_eddy_tracker.observations.observation import EddiesObservations\nfrom py_eddy_tracker.poly import fit_circle_, fit_ellips" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load example identification file\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "a = EddiesObservations.load_file(data.get_path(\"Anticyclonic_20190223.nc\"))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Function to draw circle or ellips from parameter\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def build_circle(x0, y0, r):\n angle = radians(linspace(0, 360, 50))\n x_norm, y_norm = cos(angle), sin(angle)\n return local_to_coordinates(x_norm * r, y_norm * r, x0, y0)\n\n\ndef build_ellips(x0, y0, a, b, theta):\n angle = radians(linspace(0, 360, 50))\n x = a * cos(theta) * cos(angle) - b * sin(theta) * sin(angle)\n y = a * sin(theta) * cos(angle) + b * cos(theta) * sin(angle)\n return local_to_coordinates(x, y, x0, y0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Plot fitted circle or ellips on stored contour\n\n" ] }, { @@ -37,7 +80,7 @@ }, "outputs": [], "source": [ - "xs,ys=a.contour_lon_s,a.contour_lat_s\n\nfor i in range(20):\n x, y = xs[i], ys[i]\n x0_, y0_ = x.mean(), y.mean()\n x_, y_ = coordinates_to_local(x,y, x0_, y0_)\n fig = plt.figure()\n ax = fig.add_subplot(111)\n ax.grid(), ax.set_aspect('equal')\n ax.plot(x, y, label='store')\n x0, y0, a,b, theta = fit_ellips(x_,y_)\n x0, y0 = local_to_coordinates(x0, y0, x0_, y0_)\n ax.plot(*build_ellips(x0, y0, a,b, theta), label='ellips')\n x0, y0, radius, shape_error = fit_circle_(x_,y_)\n x0,y0 = local_to_coordinates(x0,y0, x0_, y0_)\n ax.plot(*build_circle(x0,y0, radius), label='circle')\n ax.legend()" + "xs, ys = a.contour_lon_s, a.contour_lat_s\n\nfig = plt.figure(figsize=(15, 15))\n\nj = 1\nfor i in range(0, 800, 30):\n x, y = xs[i], ys[i]\n x0_, y0_ = x.mean(), y.mean()\n x_, y_ = coordinates_to_local(x, y, x0_, y0_)\n ax = fig.add_subplot(4, 4, j)\n ax.grid(), ax.set_aspect(\"equal\")\n ax.plot(x, y, label=\"store\", color=\"black\")\n x0, y0, a, b, theta = fit_ellips(x_, y_)\n x0, y0 = local_to_coordinates(x0, y0, x0_, y0_)\n ax.plot(*build_ellips(x0, y0, a, b, theta), label=\"ellips\", color=\"green\")\n x0, y0, radius, shape_error = fit_circle_(x_, y_)\n x0, y0 = local_to_coordinates(x0, y0, x0_, y0_)\n ax.plot(*build_circle(x0, y0, radius), label=\"circle\", color=\"red\", lw=0.5)\n if j == 16:\n break\n j += 1" ] } ], diff --git a/requirements_doc.txt b/requirements_doc.txt index 6a4a2937..0d926b32 100644 --- a/requirements_doc.txt +++ b/requirements_doc.txt @@ -6,6 +6,7 @@ opencv-python pint polygon3 pyyaml +requests scipy zarr # doc From 96436979faf960865f7bed9bdc6069c74c390c28 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Fri, 12 Feb 2021 10:19:51 +0100 Subject: [PATCH 048/249] remove unknown method --- examples/06_grid_manipulation/pet_lavd.py | 2 +- notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/06_grid_manipulation/pet_lavd.py b/examples/06_grid_manipulation/pet_lavd.py index 1c662ec9..c67d6b1b 100644 --- a/examples/06_grid_manipulation/pet_lavd.py +++ b/examples/06_grid_manipulation/pet_lavd.py @@ -30,7 +30,7 @@ def start_ax(title="", dpi=90): fig = plt.figure(figsize=(16, 9), dpi=dpi) ax = fig.add_axes([0, 0, 1, 1], projection="full_axes") - ax.set_xlim(0, 32), ax.set_ylim(28, 46), ax.update_env() + ax.set_xlim(0, 32), ax.set_ylim(28, 46) ax.set_title(title) return fig, ax, ax.text(3, 32, "", fontsize=20) diff --git a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb index 3d925a53..ea21cdc2 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb @@ -37,7 +37,7 @@ }, "outputs": [], "source": [ - "def start_ax(title=\"\", dpi=90):\n fig = plt.figure(figsize=(16, 9), dpi=dpi)\n ax = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\n ax.set_xlim(0, 32), ax.set_ylim(28, 46), ax.update_env()\n ax.set_title(title)\n return fig, ax, ax.text(3, 32, \"\", fontsize=20)\n\n\ndef update_axes(ax, mappable=None):\n ax.grid()\n if mappable:\n cb = plt.colorbar(\n mappable,\n cax=ax.figure.add_axes([0.05, 0.1, 0.9, 0.01]),\n orientation=\"horizontal\",\n )\n cb.set_label(\"Vorticity integration along trajectory at initial position\")\n\n\nkw_vorticity = dict(vmin=0, vmax=2e-5, cmap=\"viridis\")" + "def start_ax(title=\"\", dpi=90):\n fig = plt.figure(figsize=(16, 9), dpi=dpi)\n ax = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\n ax.set_xlim(0, 32), ax.set_ylim(28, 46)\n ax.set_title(title)\n return fig, ax, ax.text(3, 32, \"\", fontsize=20)\n\n\ndef update_axes(ax, mappable=None):\n ax.grid()\n if mappable:\n cb = plt.colorbar(\n mappable,\n cax=ax.figure.add_axes([0.05, 0.1, 0.9, 0.01]),\n orientation=\"horizontal\",\n )\n cb.set_label(\"Vorticity integration along trajectory at initial position\")\n\n\nkw_vorticity = dict(vmin=0, vmax=2e-5, cmap=\"viridis\")" ] }, { From 745fe4969c77d308d1f2c22f302fdbd1050cdbc2 Mon Sep 17 00:00:00 2001 From: Charles Troupin Date: Fri, 12 Feb 2021 14:18:13 +0100 Subject: [PATCH 049/249] typos (#53) Co-authored-by: Troupin Charles --- doc/custom_tracking.rst | 3 +-- doc/grid_identification.rst | 10 +++++----- doc/run_tracking.rst | 28 ++++++++++++++-------------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/doc/custom_tracking.rst b/doc/custom_tracking.rst index f75ad2c5..f72f3e72 100644 --- a/doc/custom_tracking.rst +++ b/doc/custom_tracking.rst @@ -6,7 +6,6 @@ Customize tracking Code my own tracking ******************** -To use your own tracking method, you just need to create a class which inherit +To use your own tracking method, you just need to create a class which inherits from :meth:`py_eddy_tracker.observations.observation.EddiesObservations` and set this class in yaml file like we see in the previous topic. - diff --git a/doc/grid_identification.rst b/doc/grid_identification.rst index 4d681252..c645f80c 100644 --- a/doc/grid_identification.rst +++ b/doc/grid_identification.rst @@ -8,7 +8,7 @@ Run the identification process for a single day Shell/bash command ****************** -Bash command will allow to process one grid, it will apply a filter and an identification. +Bash command will allow you to process one grid, it will apply a filter and an identification. .. code-block:: bash @@ -18,14 +18,14 @@ Bash command will allow to process one grid, it will apply a filter and an ident out_directory -v DEBUG -Filter could be modify with options *--cut_wavelength* and *--filter_order*. You could also defined height between two isolines with *--isoline_step*, which could +Filter could be modified with options *--cut_wavelength* and *--filter_order*. You could also define height between two isolines with *--isoline_step*, which could improve speed profile quality and detect accurately tiny eddies. You could also use *--fit_errmax* to manage acceptable shape of eddies. An eddy identification will produce two files in the output directory, one for anticyclonic eddies and the other one for cyclonic. -In regional area which are away from the equator, current could be deduce from height, juste write *None None* inplace of *ugos vgos* +In regional areas which are away from the Equator, current could be deduced from height, just write *None None* in place of *ugos vgos* -In case of **datacube**, you need to specify index for each layer (time, depth, ...) wiht *--indexs* option like: +In case of **datacube**, you need to specify index for each layer (time, depth, ...) with *--indexs* option like: .. code-block:: bash @@ -40,7 +40,7 @@ In case of **datacube**, you need to specify index for each layer (time, depth, Python code *********** -If we want customize eddies identification, python module is here. +If we want to customize eddies identification, the Python module is here. Activate verbose diff --git a/doc/run_tracking.rst b/doc/run_tracking.rst index 95fa45f4..0760d7bb 100644 --- a/doc/run_tracking.rst +++ b/doc/run_tracking.rst @@ -5,9 +5,9 @@ Tracking Requirements ************ -Before to run tracking, you will need to run identification on every time step of the period(Period of your study). +Before to run tracking, you will need to run identification on every time step of the period (period of your study). -**Advice** : Before to run tracking, display some identification file allow to learn a lot +**Advice** : Before to run tracking, displaying some identification file allows one to learn a lot Default method ************** @@ -35,24 +35,24 @@ To run: EddyTracking conf.yaml -v DEBUG -It will use default tracker: +It will use the default tracker: -- No travel longer than 125 km between two observation -- Amplitude and speed radius must be close to previous observation -- In case of several candidate only closest is kept +- No travel longer than 125 km between two observations +- Amplitude and speed radius must be close to the previous observation +- In case of several candidates only the closest is kept It will produce 4 files by run: -- A file of correspondances which will contains all the information to merge all identifications file -- A file which will contains all the observations which are alone -- A file which will contains all the short track which are shorter than **TRACK_DURATION_MIN** -- A file which will contains all the long track which are longer than **TRACK_DURATION_MIN** +- A file of correspondences which will contain all the information to merge all identifications file +- A file which will contain all the observations which are alone +- A file which will contain all the short tracks which are shorter than **TRACK_DURATION_MIN** +- A file which will contain all the long tracks which are longer than **TRACK_DURATION_MIN** -Use python module +Use Python module ***************** -An example of tracking with python module is available in the gallery: +An example of tracking with the Python module is available in the gallery: :ref:`sphx_glr_python_module_08_tracking_manipulation_pet_run_a_tracking.py` Choose a tracker @@ -67,7 +67,7 @@ With yaml you could also select another tracker: FILES_PATTERN: MY/IDENTIFICATION_PATH/Anticyclonic*.nc SAVE_DIR: MY_OUTPUT_PATH - # Number of timestep for missing detection + # Number of timesteps for missing detection VIRTUAL_LENGTH_MAX: 3 # Minimal time to consider as a full track TRACK_DURATION_MIN: 10 @@ -80,5 +80,5 @@ With yaml you could also select another tracker: # py_eddy_tracker.observations.observation.EddiesObservations CLASS: CheltonTracker -This tracker is like described in CHELTON11[https://doi.org/10.1016/j.pocean.2011.01.002]. +This tracker is like the one described in CHELTON11[https://doi.org/10.1016/j.pocean.2011.01.002]. Code is here :meth:`py_eddy_tracker.featured_tracking.old_tracker_reference` From 85cc6fabc7b493ab5be32d71c4fccf3ec9f757d9 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Fri, 12 Feb 2021 18:28:52 +0100 Subject: [PATCH 050/249] speed up /generalize some network method --- examples/06_grid_manipulation/pet_lavd.py | 4 +- .../pet_eddy_detection.ipynb | 4 +- .../06_grid_manipulation/pet_lavd.ipynb | 4 +- src/py_eddy_tracker/observations/network.py | 98 +++++++++++++------ 4 files changed, 75 insertions(+), 35 deletions(-) diff --git a/examples/06_grid_manipulation/pet_lavd.py b/examples/06_grid_manipulation/pet_lavd.py index c67d6b1b..dd35c5ea 100644 --- a/examples/06_grid_manipulation/pet_lavd.py +++ b/examples/06_grid_manipulation/pet_lavd.py @@ -44,6 +44,7 @@ def update_axes(ax, mappable=None): orientation="horizontal", ) cb.set_label("Vorticity integration along trajectory at initial position") + return cb kw_vorticity = dict(vmin=0, vmax=2e-5, cmap="viridis") @@ -90,7 +91,8 @@ def save(self, *args, **kwargs): # Display vorticity field fig, ax, _ = start_ax() mappable = g.display(ax, abs(g.grid("vort")), **kw_vorticity) -update_axes(ax, mappable) +cb = update_axes(ax, mappable) +cb.set_label("Vorticity") # %% # Particles diff --git a/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb b/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb index 938ec054..d63797ae 100644 --- a/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb @@ -253,7 +253,7 @@ }, "outputs": [], "source": [ - "ax = start_axes(\"Speed Radius (km)\")\nkwargs = dict(vmin=10, vmax=50, s=80, ref=-10, cmap=\"magma_r\", factor=0.001)\na.scatter(ax, \"radius_s\", **kwargs)\nm = c.scatter(\n ax, \"radius_s\", **kwargs\n)\nupdate_axes(ax, m)" + "ax = start_axes(\"Speed Radius (km)\")\nkwargs = dict(vmin=10, vmax=50, s=80, ref=-10, cmap=\"magma_r\", factor=0.001)\na.scatter(ax, \"radius_s\", **kwargs)\nm = c.scatter(ax, \"radius_s\", **kwargs)\nupdate_axes(ax, m)" ] }, { @@ -271,7 +271,7 @@ }, "outputs": [], "source": [ - "ax = start_axes(\"Effective Radius (km)\")\nkwargs = dict(vmin=10, vmax=80, cmap=\"magma_r\", factor=0.001, lut=14, ref=-10)\na.filled(ax, \"effective_radius\", **kwargs)\nm = c.filled(\n ax, \"radius_e\", **kwargs\n)\nupdate_axes(ax, m)" + "ax = start_axes(\"Effective Radius (km)\")\nkwargs = dict(vmin=10, vmax=80, cmap=\"magma_r\", factor=0.001, lut=14, ref=-10)\na.filled(ax, \"effective_radius\", **kwargs)\nm = c.filled(ax, \"radius_e\", **kwargs)\nupdate_axes(ax, m)" ] } ], diff --git a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb index ea21cdc2..55cfbeec 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb @@ -37,7 +37,7 @@ }, "outputs": [], "source": [ - "def start_ax(title=\"\", dpi=90):\n fig = plt.figure(figsize=(16, 9), dpi=dpi)\n ax = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\n ax.set_xlim(0, 32), ax.set_ylim(28, 46)\n ax.set_title(title)\n return fig, ax, ax.text(3, 32, \"\", fontsize=20)\n\n\ndef update_axes(ax, mappable=None):\n ax.grid()\n if mappable:\n cb = plt.colorbar(\n mappable,\n cax=ax.figure.add_axes([0.05, 0.1, 0.9, 0.01]),\n orientation=\"horizontal\",\n )\n cb.set_label(\"Vorticity integration along trajectory at initial position\")\n\n\nkw_vorticity = dict(vmin=0, vmax=2e-5, cmap=\"viridis\")" + "def start_ax(title=\"\", dpi=90):\n fig = plt.figure(figsize=(16, 9), dpi=dpi)\n ax = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\n ax.set_xlim(0, 32), ax.set_ylim(28, 46)\n ax.set_title(title)\n return fig, ax, ax.text(3, 32, \"\", fontsize=20)\n\n\ndef update_axes(ax, mappable=None):\n ax.grid()\n if mappable:\n cb = plt.colorbar(\n mappable,\n cax=ax.figure.add_axes([0.05, 0.1, 0.9, 0.01]),\n orientation=\"horizontal\",\n )\n cb.set_label(\"Vorticity integration along trajectory at initial position\")\n return cb\n\n\nkw_vorticity = dict(vmin=0, vmax=2e-5, cmap=\"viridis\")" ] }, { @@ -84,7 +84,7 @@ }, "outputs": [], "source": [ - "fig, ax, _ = start_ax()\nmappable = g.display(ax, abs(g.grid(\"vort\")), **kw_vorticity)\nupdate_axes(ax, mappable)" + "fig, ax, _ = start_ax()\nmappable = g.display(ax, abs(g.grid(\"vort\")), **kw_vorticity)\ncb = update_axes(ax, mappable)\ncb.set_label(\"Vorticity\")" ] }, { diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 34a47c3a..522a34c6 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -6,7 +6,7 @@ from glob import glob from numba import njit -from numpy import arange, array, bincount, empty, ones, uint32, unique, zeros +from numpy import arange, array, bincount, empty, in1d, ones, uint32, unique, zeros from ..generic import build_index, wrap_longitude from ..poly import bbox_intersection, vertice_overlap @@ -119,13 +119,12 @@ def longer_than(self, nb_day_min=-1, nb_day_max=-1): if nb_day_max < 0: nb_day_max = 1000000000000 mask = zeros(self.shape, dtype="bool") - for i, b0, b1 in self.iter_on(self.segment_track_array): + t = self.time + for i, b0, b1 in self.iter_on(self.track): nb = i.stop - i.start if nb == 0: continue - t = self.time[i] - dt = t.max() - t.min() - if nb_day_min <= dt <= nb_day_max: + if nb_day_min <= ptp(t[i]) <= nb_day_max: mask[i] = True return self.extract_with_mask(mask) @@ -164,8 +163,12 @@ def obs_relative_order(self, i_obs): self.only_one_network() return self.segment_relative_order(self.segment[i_obs]) - def connexions(self): - self.only_one_network() + def connexions(self, multi_network=False): + if multi_network: + segment = self.segment_track_array + else: + self.only_one_network() + segment = self.segment segments_connexion = dict() def add_seg(father, child): @@ -173,12 +176,13 @@ def add_seg(father, child): segments_connexion[father] = list() segments_connexion[father].append(child) - for i, seg, _ in self.iter_on("segment"): + previous_obs, next_obs = self.previous_obs, self.next_obs + for i, seg, _ in self.iter_on(segment): if i.start == i.stop: continue - i_p, i_n = self.previous_obs[i.start], self.next_obs[i.stop - 1] + i_p, i_n = previous_obs[i.start], next_obs[i.stop - 1] # segment of interaction - p_seg, n_seg = self.segment[i_p], self.segment[i_n] + p_seg, n_seg = segment[i_p], segment[i_n] # Where segment are called if i_p != -1: add_seg(p_seg, seg) @@ -395,6 +399,26 @@ def map_segment(self, method, y, same=True, **kw): out = array(out) return out + def map_network(self, method, y, same=True, **kw): + if same: + out = empty(y.shape, **kw) + else: + out = list() + for i, b0, b1 in self.iter_on(self.track): + res = method(y[i]) + if same: + out[i] = res + else: + if isinstance(i, slice): + if i.start == i.stop: + continue + elif len(i) == 0: + continue + out.append(res) + if not same: + out = array(out) + return out + def scatter_timeline( self, ax, @@ -410,7 +434,7 @@ def scatter_timeline( Must be call on only one network """ self.only_one_network() - y = (self.segment if yfield is None else self[yfield]) * yfactor + y = (self.segment if yfield is None else self.parse_varname(yfield)) * yfactor if method == "all": pass else: @@ -536,11 +560,12 @@ def segment_track_array(self): def birth_event(self): # FIXME how to manage group 0 indices = list() + previous_obs = self.previous_obs for i, _, _ in self.iter_on(self.segment_track_array): nb = i.stop - i.start if nb == 0: continue - i_p = self.previous_obs[i.start] + i_p = previous_obs[i.start] if i_p == -1: indices.append(i.start) return self.extract_event(list(set(indices))) @@ -548,11 +573,12 @@ def birth_event(self): def death_event(self): # FIXME how to manage group 0 indices = list() + next_obs = self.next_obs for i, _, _ in self.iter_on(self.segment_track_array): nb = i.stop - i.start if nb == 0: continue - i_n = self.next_obs[i.stop - 1] + i_n = next_obs[i.stop - 1] if i_n == -1: indices.append(i.stop - 1) return self.extract_event(list(set(indices))) @@ -567,16 +593,16 @@ def merging_event(self, triplet=False): if triplet: idx_m0_stop = list() idx_m0 = list() - + next_obs, previous_obs = self.next_obs, self.previous_obs for i, _, _ in self.iter_on(self.segment_track_array): nb = i.stop - i.start if nb == 0: continue - i_n = self.next_obs[i.stop - 1] + i_n = next_obs[i.stop - 1] if i_n != -1: if triplet: idx_m0_stop.append(i.stop - 1) - idx_m0.append(self.previous_obs[i_n]) + idx_m0.append(previous_obs[i_n]) idx_m1.append(i_n) if triplet: @@ -598,15 +624,16 @@ def spliting_event(self, triplet=False): if triplet: idx_s1_start = list() idx_s1 = list() + next_obs, previous_obs = self.next_obs, self.previous_obs for i, _, _ in self.iter_on(self.segment_track_array): nb = i.stop - i.start if nb == 0: continue - i_p = self.previous_obs[i.start] + i_p = previous_obs[i.start] if i_p != -1: if triplet: idx_s1_start.append(i.start) - idx_s1.append(self.next_obs[i_p]) + idx_s1.append(next_obs[i_p]) idx_s0.append(i_p) if triplet: return ( @@ -700,32 +727,38 @@ def plot(self, ax, ref=None, color_cycle=None, **kwargs): j += 1 return mappables - def remove_dead_end(self, nobs=3, recursive=0, mask=None): + def remove_dead_end(self, nobs=3, ndays=0, recursive=0, mask=None): """ .. warning:: It will remove short segment which splits than merges with same segment """ - self.only_one_network() segments_keep = list() - connexions = self.connexions() - for i, b0, _ in self.iter_on("segment"): - nb = i.stop - i.start + connexions = self.connexions(multi_network=True) + t = self.time + for i, b0, _ in self.iter_on(self.segment_track_array): if mask and mask[i].any(): segments_keep.append(b0) continue - if nb < nobs and len(connexions.get(b0, tuple())) < 2: + nb = i.stop - i.start + dt = t[i.stop - 1] - t[i.start] + if (nb < nobs or dt < ndays) and len(connexions.get(b0, tuple())) < 2: continue segments_keep.append(b0) if recursive > 0: - return self.extract_segment(segments_keep).remove_dead_end( - nobs, recursive - 1 + return self.extract_segment(segments_keep, absolute=True).remove_dead_end( + nobs, ndays, recursive - 1 ) - return self.extract_segment(segments_keep) + return self.extract_segment(segments_keep, absolute=True) - def extract_segment(self, segments): + def extract_segment(self, segments, absolute=False): mask = ones(self.shape, dtype="bool") - for i, b0, b1 in self.iter_on("segment"): - if b0 not in segments: + segments = array(segments) + values = self.segment_track_array if absolute else "segment" + keep = ones(values.max() + 1, dtype="bool") + v = unique(values) + keep[v] = in1d(v, segments) + for i, b0, b1 in self.iter_on(values): + if not keep[b0]: mask[i] = False return self.extract_with_mask(mask) @@ -929,3 +962,8 @@ def new_numbering(segs): s0 = segs[i] j += 1 segs[i] = j + + +@njit(cache=True) +def ptp(values): + return values.max() - values.min() From cd58812124d2346f6c11ed0c7fbb3dfac409b9a4 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 16 Feb 2021 10:49:57 +0100 Subject: [PATCH 051/249] update reference of lavd example --- examples/06_grid_manipulation/pet_advect.py | 3 ++- examples/06_grid_manipulation/pet_lavd.py | 10 +++++----- .../06_grid_manipulation/pet_advect.ipynb | 2 +- .../python_module/06_grid_manipulation/pet_lavd.ipynb | 8 ++++---- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/examples/06_grid_manipulation/pet_advect.py b/examples/06_grid_manipulation/pet_advect.py index 5b7a5ee4..838a2511 100644 --- a/examples/06_grid_manipulation/pet_advect.py +++ b/examples/06_grid_manipulation/pet_advect.py @@ -79,7 +79,8 @@ def anim_ax(generator, **kw): ax = fig.add_axes([0, 0, 1, 1], projection="full_axes") ax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid() a.filled(ax, facecolors="r", alpha=0.1), c.filled(ax, facecolors="b", alpha=0.1) - return fig, ax.text(21, 32.1, ""), ax.plot([], [], "k", **kw)[0], t + line = ax.plot([], [], "k", **kw)[0] + return fig, ax.text(21, 32.1, ""), line, t def update(i_frame, t_step): diff --git a/examples/06_grid_manipulation/pet_lavd.py b/examples/06_grid_manipulation/pet_lavd.py index dd35c5ea..4c4e394c 100644 --- a/examples/06_grid_manipulation/pet_lavd.py +++ b/examples/06_grid_manipulation/pet_lavd.py @@ -7,8 +7,8 @@ Method are described here: - - `Transport by Lagrangian Vortices in the Eastern Pacific `_ - - `Transport by Coherent Lagrangian Vortices`_ + - Abernathey, Ryan, and George Haller. " Transport by Lagrangian Vortices in the Eastern Pacific", Journal of Physical Oceanography 48, 3 (2018): 667-685, accessed Feb 16, 2021, https://doi.org/10.1175/JPO-D-17-0102.1 + - `Transport by Coherent Lagrangian Vortices`_, R. Abernathey, Sinha A., Tarshish N., Liu T., Zhang C., Haller G., 2019, Talk a t the Sources and Sinks of Ocean Mesoscale Eddy Energy CLIVAR Workshop .. _Transport by Coherent Lagrangian Vortices: https://usclivar.org/sites/default/files/meetings/2019/presentations/Aberernathey_CLIVAR.pdf @@ -74,7 +74,7 @@ def save(self, *args, **kwargs): # %% # Data # ---- -# To compute vorticity(:math:`\omega`) we compute u/v field with a stencil and apply the following equation with stencil +# To compute vorticity (:math:`\omega`) we compute u/v field with a stencil and apply the following equation with stencil # method : # # .. math:: @@ -166,11 +166,11 @@ def update(i_frame): # %% # Display final LAVD with py eddy tracker detection. -# Period used for LAVD integration(8 days) is too short for a real use, but choose for example efficiency. +# Period used for LAVD integration (8 days) is too short for a real use, but choose for example efficiency. fig, ax, _ = start_ax() mappable = lavd.display(ax, "lavd", **kw_vorticity) NetworkObservations.load_file(get_path("Anticyclonic_20160515.nc")).display( ax, color="k" ) NetworkObservations.load_file(get_path("Cyclonic_20160515.nc")).display(ax, color="k") -update_axes(ax, mappable) +_ = update_axes(ax, mappable) diff --git a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb index 363ac76d..62b3e0a9 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb @@ -109,7 +109,7 @@ }, "outputs": [], "source": [ - "x, y = np.meshgrid(np.arange(13, 36, 0.125), np.arange(28, 40, 0.125))\nx, y = x.reshape(-1), y.reshape(-1)\n# Remove all original position that we can't advect at first place\nm = ~np.isnan(g.interp(\"u\", x, y))\nx, y = x[m], y[m]\n\n# Movie properties\nkwargs = dict(frames=np.arange(51), interval=90)\nkw_p = dict(nb_step=2, time_step=21600)\nframe_t = kw_p[\"nb_step\"] * kw_p[\"time_step\"] / 86400.0\n\n\ndef anim_ax(generator, **kw):\n t = 0\n for _ in range(4):\n generator.__next__()\n t += frame_t\n\n fig = plt.figure(figsize=(10, 5), dpi=64)\n ax = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\n ax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid()\n a.filled(ax, facecolors=\"r\", alpha=0.1), c.filled(ax, facecolors=\"b\", alpha=0.1)\n return fig, ax.text(21, 32.1, \"\"), ax.plot([], [], \"k\", **kw)[0], t\n\n\ndef update(i_frame, t_step):\n global t\n x, y = p.__next__()\n t += t_step\n l.set_data(x, y)\n txt.set_text(f\"T0 + {t:.1f} days\")" + "x, y = np.meshgrid(np.arange(13, 36, 0.125), np.arange(28, 40, 0.125))\nx, y = x.reshape(-1), y.reshape(-1)\n# Remove all original position that we can't advect at first place\nm = ~np.isnan(g.interp(\"u\", x, y))\nx, y = x[m], y[m]\n\n# Movie properties\nkwargs = dict(frames=np.arange(51), interval=90)\nkw_p = dict(nb_step=2, time_step=21600)\nframe_t = kw_p[\"nb_step\"] * kw_p[\"time_step\"] / 86400.0\n\n\ndef anim_ax(generator, **kw):\n t = 0\n for _ in range(4):\n generator.__next__()\n t += frame_t\n\n fig = plt.figure(figsize=(10, 5), dpi=64)\n ax = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\n ax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid()\n a.filled(ax, facecolors=\"r\", alpha=0.1), c.filled(ax, facecolors=\"b\", alpha=0.1)\n line = ax.plot([], [], \"k\", **kw)[0]\n return fig, ax.text(21, 32.1, \"\"), line, t\n\n\ndef update(i_frame, t_step):\n global t\n x, y = p.__next__()\n t += t_step\n l.set_data(x, y)\n txt.set_text(f\"T0 + {t:.1f} days\")" ] }, { diff --git a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb index 55cfbeec..5241f6bc 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# LAVD experiment\n\nNaive method to reproduce LAVD(Lagrangian-Averaged Vorticity deviation) method with a static velocity field.\nIn the current example we didn't remove a mean vorticity.\n\nMethod are described here:\n\n - `Transport by Lagrangian Vortices in the Eastern Pacific `_\n - `Transport by Coherent Lagrangian Vortices`_\n\n https://usclivar.org/sites/default/files/meetings/2019/presentations/Aberernathey_CLIVAR.pdf\n" + "\n# LAVD experiment\n\nNaive method to reproduce LAVD(Lagrangian-Averaged Vorticity deviation) method with a static velocity field.\nIn the current example we didn't remove a mean vorticity.\n\nMethod are described here:\n\n - Abernathey, Ryan, and George Haller. \" Transport by Lagrangian Vortices in the Eastern Pacific\", Journal of Physical Oceanography 48, 3 (2018): 667-685, accessed Feb 16, 2021, https://doi.org/10.1175/JPO-D-17-0102.1\n - `Transport by Coherent Lagrangian Vortices`_, R. Abernathey, Sinha A., Tarshish N., Liu T., Zhang C., Haller G., 2019, Talk a t the Sources and Sinks of Ocean Mesoscale Eddy Energy CLIVAR Workshop\n\n https://usclivar.org/sites/default/files/meetings/2019/presentations/Aberernathey_CLIVAR.pdf\n" ] }, { @@ -55,7 +55,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Data\nTo compute vorticity($\\omega$) we compute u/v field with a stencil and apply the following equation with stencil\nmethod :\n\n\\begin{align}\\omega = \\frac{\\partial v}{\\partial x} - \\frac{\\partial u}{\\partial y}\\end{align}\n\n" + "## Data\nTo compute vorticity ($\\omega$) we compute u/v field with a stencil and apply the following equation with stencil\nmethod :\n\n\\begin{align}\\omega = \\frac{\\partial v}{\\partial x} - \\frac{\\partial u}{\\partial y}\\end{align}\n\n" ] }, { @@ -170,7 +170,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Display final LAVD with py eddy tracker detection.\nPeriod used for LAVD integration(8 days) is too short for a real use, but choose for example efficiency.\n\n" + "Display final LAVD with py eddy tracker detection.\nPeriod used for LAVD integration (8 days) is too short for a real use, but choose for example efficiency.\n\n" ] }, { @@ -181,7 +181,7 @@ }, "outputs": [], "source": [ - "fig, ax, _ = start_ax()\nmappable = lavd.display(ax, \"lavd\", **kw_vorticity)\nNetworkObservations.load_file(get_path(\"Anticyclonic_20160515.nc\")).display(\n ax, color=\"k\"\n)\nNetworkObservations.load_file(get_path(\"Cyclonic_20160515.nc\")).display(ax, color=\"k\")\nupdate_axes(ax, mappable)" + "fig, ax, _ = start_ax()\nmappable = lavd.display(ax, \"lavd\", **kw_vorticity)\nNetworkObservations.load_file(get_path(\"Anticyclonic_20160515.nc\")).display(\n ax, color=\"k\"\n)\nNetworkObservations.load_file(get_path(\"Cyclonic_20160515.nc\")).display(ax, color=\"k\")\n_ = update_axes(ax, mappable)" ] } ], From 351d86c5b5479397f38fe5c7d0345064670ddc84 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Tue, 16 Feb 2021 17:01:31 +0100 Subject: [PATCH 052/249] Add animation of segmentation --- examples/16_network/pet_segmentation_anim.py | 90 ++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 examples/16_network/pet_segmentation_anim.py diff --git a/examples/16_network/pet_segmentation_anim.py b/examples/16_network/pet_segmentation_anim.py new file mode 100644 index 00000000..cc0dc23c --- /dev/null +++ b/examples/16_network/pet_segmentation_anim.py @@ -0,0 +1,90 @@ +""" +Network segmentation process +============================ +""" + +import re + +from matplotlib import pyplot as plt +from matplotlib.animation import FuncAnimation +from matplotlib.colors import ListedColormap +from numpy import ones + +import py_eddy_tracker.gui +from py_eddy_tracker import data +from py_eddy_tracker.observations.tracking import TrackEddiesObservations + + +# %% +class VideoAnimation(FuncAnimation): + def _repr_html_(self, *args, **kwargs): + """To get video in html and have a player""" + content = self.to_html5_video() + return re.sub( + '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) + + +# %% +# Overlaod of class to pick up +TRACKS = list() + + +class MyTrack(TrackEddiesObservations): + @staticmethod + def get_next_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs): + TRACKS.append(ids["track"].copy()) + return TrackEddiesObservations.get_next_obs( + i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs + ) + + +# %% +# Load data +# --------- +# Load data where observations are put in same network but no segmentation +e = MyTrack.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 +matrix = e.split_network(intern=False, window=5) + + +# %% +# Anim +# ---- +def update(i_frame): + tr = TRACKS[i_frame] + mappable_tracks.set_array(tr) + s = 80 * ones(tr.shape) + s[tr == 0] = 4 + mappable_tracks.set_sizes(s) + return (mappable_tracks,) + + +fig = plt.figure(figsize=(15, 8), dpi=60) +ax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection="full_axes") +ax.set_title(f"{len(e)} observations to segment") +ax.set_xlim(-13, 20), ax.set_ylim(-36.5, -20), ax.grid() +vmax = TRACKS[-1].max() +cmap = ListedColormap(["gray", *e.COLORS[:-1]], name="from_list", N=vmax) +mappable_tracks = ax.scatter( + e.lon, e.lat, c=TRACKS[0], cmap=cmap, vmin=0, vmax=vmax, s=20 +) +ani = VideoAnimation( + fig, update, frames=range(1, len(TRACKS), 4), interval=125, blit=True +) From 1f57fe13f5ae154c0c458b92ead1237b2043efc8 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Mon, 22 Feb 2021 11:35:33 +0100 Subject: [PATCH 053/249] Add exception if grid have coordinates with 2D shape --- src/py_eddy_tracker/dataset/grid.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index f3dcb173..4ae63495 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -1150,6 +1150,10 @@ def __init__(self, *args, **kwargs): def setup_coordinates(self): super().setup_coordinates() self.x_size = self.x_c.shape[0] + if len(self.x_c.shape) != 1: + raise Exception( + "Coordinates in RegularGridDataset must be 1D array, or think to use UnRegularGridDataset" + ) self._x_step = (self.x_c[1:] - self.x_c[:-1]).mean() self._y_step = (self.y_c[1:] - self.y_c[:-1]).mean() From 332e016fb3cedb6211fc6f99271ccb4a2eef27b0 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Mon, 22 Feb 2021 11:38:31 +0100 Subject: [PATCH 054/249] - Add cache for interpolation - Add cache for rk4 advection --- src/py_eddy_tracker/dataset/grid.py | 280 ++++++++++++++++++++++------ src/py_eddy_tracker/generic.py | 116 ++++++++---- tests/test_grid.py | 12 +- 3 files changed, 315 insertions(+), 93 deletions(-) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 4ae63495..bdbe2ea3 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -1937,6 +1937,14 @@ def regrid(self, other, grid_name, new_name=None): # self.variables_description[new_name]['infos'] = False # self.variables_description[new_name]['kwargs']['dimensions'] = ... + @staticmethod + def get_mask(a): + if len(a.mask.shape): + m = a.mask + else: + m = ones(a.shape) if a.mask else zeros(a.shape) + return m + def interp(self, grid_name, lons, lats, method="bilinear"): """ Compute z over lons, lats @@ -1949,10 +1957,7 @@ def interp(self, grid_name, lons, lats, method="bilinear"): :return: new z """ g = self.grid(grid_name) - if len(g.mask.shape): - m = g.mask - else: - m = ones(g.shape) if g.mask else zeros(g.shape) + m = self.get_mask(g) return interp2d_geo( self.x_c, self.y_c, g, m, lons, lats, nearest=method == "nearest" ) @@ -1977,11 +1982,12 @@ def uv_for_advection(self, u_name, v_name, time_step=600, backward=False, factor m = u.mask + v.mask return u, v, m - def advect(self, x, y, u_name, v_name, nb_step=10, rk4=False, **kw): + def advect(self, x, y, u_name, v_name, nb_step=10, rk4=True, **kw): """ At each call it will update position in place with u & v field It's a dummy advection which use only one layer of current + :param array x: Longitude of obs to move :param array y: Latitude of obs to move :param str,array u_name: U field to advect obs @@ -1990,13 +1996,14 @@ def advect(self, x, y, u_name, v_name, nb_step=10, rk4=False, **kw): :param int time_step: Number of second for each advection """ u, v, m = self.uv_for_advection(u_name, v_name, **kw) + m_p = isnan(x) + isnan(y) advect_ = advect_rk4 if rk4 else advect while True: - advect_(self.x_c, self.y_c, u, v, m, x, y, nb_step) + advect_(self.x_c, self.y_c, u, v, m, x, y, m_p, nb_step) yield x, y def filament( - self, x, y, u_name, v_name, nb_step=10, filament_size=6, rk4=False, **kw + self, x, y, u_name, v_name, nb_step=10, filament_size=6, rk4=True, **kw ): """ Produce filament with concatenation of advection @@ -2021,6 +2028,7 @@ def filament( f_y[:] = nan f_x[::filament_size_] = x f_y[::filament_size_] = y + mp = isnan(x) + isnan(y) advect_ = advect_rk4 if rk4 else advect while True: # Shift position @@ -2029,48 +2037,87 @@ def filament( # Remove last position f_x[filament_size::filament_size_] = nan f_y[filament_size::filament_size_] = nan - advect_(self.x_c, self.y_c, u, v, m, x, y, nb_step) + advect_(self.x_c, self.y_c, u, v, m, x, y, mp, nb_step) f_x[::filament_size_] = x f_y[::filament_size_] = y yield f_x, f_y @njit(cache=True) -def advect_rk4(x_g, y_g, u_g, v_g, m_g, x, y, nb_step): +def advect_rk4(x_g, y_g, u_g, v_g, m_g, x, y, m, nb_step): # Grid coordinates x_ref, y_ref = x_g[0], y_g[0] x_step, y_step = x_g[1] - x_ref, y_g[1] - y_ref - # On each particule + # cache + i_cache, j_cache = -1000000, -1000000 + masked = False + u00, u01, u10, u11 = 0.0, 0.0, 0.0, 0.0 + v00, v01, v10, v11 = 0.0, 0.0, 0.0, 0.0 + # On each particle for i in prange(x.size): - # If particule are not valid => continue - x_, y_ = x[i], y[i] - if isnan(x_) or isnan(y_): + # If particle are not valid => continue + if m[i]: continue + x_, y_ = x[i], y[i] # Iterate on whole steps for _ in range(nb_step): # k1, slope at origin - u1, v1 = get_uv(x_ref, y_ref, x_step, y_step, u_g, v_g, m_g, x_, y_) - if isnan(u1) or isnan(v1): + ii_, jj_, ii, jj = get_grid_indices(x_ref, y_ref, x_step, y_step, x_, y_) + if ii_ != i_cache or jj_ != j_cache: + masked, u00, u01, u10, u11, v00, v01, v10, v11 = get_uv_quad( + ii_, jj_, u_g, v_g, m_g + ) + i_cache, j_cache = ii_, jj_ + # The 3 following could be in cache operation but this one must be test in any case + if masked: x_, y_ = nan, nan + m[i] = True break + xd, yd = ii - ii_, jj - jj_ + u1, v1 = interp_uv(xd, yd, u00, u01, u10, u11, v00, v01, v10, v11) # k2, slope at middle with first guess position x1, y1 = x_ + u1 * 0.5, y_ + v1 * 0.5 - u2, v2 = get_uv(x_ref, y_ref, x_step, y_step, u_g, v_g, m_g, x1, y1) - if isnan(u2) or isnan(v2): - x_, y_ = nan, nan - break + ii_, jj_, ii, jj = get_grid_indices(x_ref, y_ref, x_step, y_step, x1, y1) + if ii_ != i_cache or jj_ != j_cache: + masked, u00, u01, u10, u11, v00, v01, v10, v11 = get_uv_quad( + ii_, jj_, u_g, v_g, m_g + ) + i_cache, j_cache = ii_, jj_ + if masked: + x_, y_ = nan, nan + m[i] = True + break + xd, yd = ii - ii_, jj - jj_ + u2, v2 = interp_uv(xd, yd, u00, u01, u10, u11, v00, v01, v10, v11) # k3, slope at middle with update guess position x2, y2 = x_ + u2 * 0.5, y_ + v2 * 0.5 - u3, v3 = get_uv(x_ref, y_ref, x_step, y_step, u_g, v_g, m_g, x2, y2) - if isnan(u3) or isnan(v3): - x_, y_ = nan, nan - break + ii_, jj_, ii, jj = get_grid_indices(x_ref, y_ref, x_step, y_step, x2, y2) + if ii_ != i_cache or jj_ != j_cache: + masked, u00, u01, u10, u11, v00, v01, v10, v11 = get_uv_quad( + ii_, jj_, u_g, v_g, m_g + ) + i_cache, j_cache = ii_, jj_ + if masked: + x_, y_ = nan, nan + m[i] = True + break + xd, yd = ii - ii_, jj - jj_ + u3, v3 = interp_uv(xd, yd, u00, u01, u10, u11, v00, v01, v10, v11) # k4, slope at end with update guess position x3, y3 = x_ + u3, y_ + v3 - u4, v4 = get_uv(x_ref, y_ref, x_step, y_step, u_g, v_g, m_g, x3, y3) - if isnan(u4) or isnan(v4): - x_, y_ = nan, nan - break + ii_, jj_, ii, jj = get_grid_indices(x_ref, y_ref, x_step, y_step, x3, y3) + if ii_ != i_cache or jj_ != j_cache: + masked, u00, u01, u10, u11, v00, v01, v10, v11 = get_uv_quad( + ii_, jj_, u_g, v_g, m_g + ) + i_cache, j_cache = ii_, jj_ + if masked: + x_, y_ = nan, nan + m[i] = True + break + xd, yd = ii - ii_, jj - jj_ + u4, v4 = interp_uv(xd, yd, u00, u01, u10, u11, v00, v01, v10, v11) + # RK4 compute dx = (u1 + 2 * u2 + 2 * u3 + u4) / 6 dy = (v1 + 2 * v2 + 2 * v3 + v4) / 6 # Compute new x,y @@ -2098,7 +2145,7 @@ def get_uv(x0, y0, x_step, y_step, u, v, m, x, y): @njit(cache=True) -def advect(x_g, y_g, u_g, v_g, m_g, x, y, nb_step): +def advect(x_g, y_g, u_g, v_g, m_g, x, y, m, nb_step): # Grid coordinates x_ref, y_ref = x_g[0], y_g[0] x_step, y_step = x_g[1] - x_ref, y_g[1] - y_ref @@ -2107,7 +2154,7 @@ def advect(x_g, y_g, u_g, v_g, m_g, x, y, nb_step): # On each particule for i in prange(x.size): # If particule are not valid => continue - if isnan(x[i]) or isnan(y[i]): + if m[i]: continue # Iterate on whole steps for _ in range(nb_step): @@ -2123,6 +2170,7 @@ def advect(x_g, y_g, u_g, v_g, m_g, x, y, nb_step): # If one of nearest pixel is invalid if m_g[i0, j0] or m_g[i0, j1] or m_g[i1, j0] or m_g[i1, j1]: x[i], y[i] = nan, nan + m[i] = True break # Extract value for u and v u00, u01, u10, u11 = u_g[i0, j0], u_g[i0, j1], u_g[i1, j0], u_g[i1, j1] @@ -2251,6 +2299,34 @@ def from_netcdf_list(cls, filenames, t, x_name, y_name, indexs=None, heigth=None new.datasets.append((t, d)) return new + def interp(self, grid_name, t, lons, lats, method="bilinear"): + """ + Compute z over lons, lats + + :param str grid_name: Grid to be interpolated + :param float, t: time for interpolation + :param lons: new x + :param lats: new y + :param str method: Could be 'bilinear' or 'nearest' + + :return: new z + """ + # FIXME: we do assumption on time step + t0 = int(t) + t1 = t0 + 1 + h0, h1 = self[t0], self[t1] + g0, g1 = h0.grid(grid_name), h1.grid(grid_name) + m0, m1 = h0.get_mask(g0), h0.get_mask(g1) + kw = dict(x=lons, y=lats, nearest=method == "nearest") + v0 = interp2d_geo(h0.x_c, h0.y_c, g0, m0, **kw) + v1 = interp2d_geo(h1.x_c, h1.y_c, g1, m1, **kw) + w = (t - t0) / (t1 - t0) + return v1 * w + v0 * (1 - w) + + def __iter__(self): + for _, d in self.datasets: + yield d + def __getitem__(self, item): for t, d in self.datasets: if t == item: @@ -2267,7 +2343,7 @@ def filament( nb_step=10, time_step=600, filament_size=6, - rk4=False, + rk4=True, **kw, ): """ @@ -2309,6 +2385,7 @@ def filament( t0 = t0 * 86400 t1 = t1 * 86400 t = t_init * 86400 + mp = isnan(x) + isnan(y) advect_ = advect_t_rk4 if rk4 else advect_t while True: # Shift position @@ -2325,7 +2402,7 @@ def filament( u1, v1, m1 = d1.uv_for_advection(u_name, v_name, time_step, **kw) w = 1 - (arange(t, t + dt, t_step) - t0) / (t1 - t0) half_w = t_step / 2.0 / (t1 - t0) - advect_(d0.x_c, d0.y_c, u0, v0, m0, u1, v1, m1, x, y, w, half_w=half_w) + advect_(d0.x_c, d0.y_c, u0, v0, m0, u1, v1, m1, x, y, mp, w, half_w=half_w) f_x[::filament_size_] = x f_y[::filament_size_] = y t += dt @@ -2340,7 +2417,7 @@ def advect( t_init, nb_step=10, time_step=600, - rk4=False, + rk4=True, **kw, ): backward = kw.get("backward", False) @@ -2360,6 +2437,7 @@ def advect( t1 = t1 * 86400 t = t_init * 86400 advect_ = advect_t_rk4 if rk4 else advect_t + mp = isnan(x) + isnan(y) while True: if (backward and t <= t1) or (not backward and t >= t1): t0, u0, v0, m0 = t1, u1, v1, m1 @@ -2368,7 +2446,7 @@ def advect( u1, v1, m1 = d1.uv_for_advection(u_name, v_name, time_step, **kw) w = 1 - (arange(t, t + dt, t_step) - t0) / (t1 - t0) half_w = t_step / 2.0 / (t1 - t0) - advect_(d0.x_c, d0.y_c, u0, v0, m0, u1, v1, m1, x, y, w, half_w=half_w) + advect_(d0.x_c, d0.y_c, u0, v0, m0, u1, v1, m1, x, y, mp, w, half_w=half_w) t += dt yield t, x, y @@ -2396,7 +2474,7 @@ def get_previous_time_step(self, t_init): @njit(cache=True) -def advect_t(x_g, y_g, u_g0, v_g0, m_g0, u_g1, v_g1, m_g1, x, y, weigths, half_w=0): +def advect_t(x_g, y_g, u_g0, v_g0, m_g0, u_g1, v_g1, m_g1, x, y, m, weigths, half_w=0): # Grid coordinates x_ref, y_ref = x_g[0], y_g[0] x_step, y_step = x_g[1] - x_ref, y_g[1] - y_ref @@ -2405,7 +2483,7 @@ def advect_t(x_g, y_g, u_g0, v_g0, m_g0, u_g1, v_g1, m_g1, x, y, weigths, half_w # On each particule for i in prange(x.size): # If particule are not valid => continue - if isnan(x[i]) or isnan(y[i]): + if m[i]: continue # Iterate on whole steps for w in weigths: @@ -2430,6 +2508,7 @@ def advect_t(x_g, y_g, u_g0, v_g0, m_g0, u_g1, v_g1, m_g1, x, y, weigths, half_w or m_g1[i1, j1] ): x[i], y[i] = nan, nan + m[i] = True break # Extract value for u and v u000, u001 = u_g0[i0, j0], u_g0[i0, j1] @@ -2454,52 +2533,133 @@ def advect_t(x_g, y_g, u_g0, v_g0, m_g0, u_g1, v_g1, m_g1, x, y, weigths, half_w y[i] += dy0 * w + dy1 * (1 - w) -@njit(cache=True) -def advect_t_rk4(x_g, y_g, u_g0, v_g0, m_g0, u_g1, v_g1, m_g1, x, y, weigths, half_w): +@njit(cache=True, fastmath=True) +def get_uv_quad(i0, j0, u, v, m): + i1, j1 = i0 + 1, j0 + 1 + if m[i0, j0] or m[i0, j1] or m[i1, j0] or m[i1, j1]: + return True, nan, nan, nan, nan, nan, nan, nan, nan + # Extract value for u and v + u00, u01, u10, u11 = u[i0, j0], u[i0, j1], u[i1, j0], u[i1, j1] + v00, v01, v10, v11 = v[i0, j0], v[i0, j1], v[i1, j0], v[i1, j1] + return False, u00, u01, u10, u11, v00, v01, v10, v11 + + +@njit(cache=True, fastmath=True) +def get_grid_indices(x0, y0, x_step, y_step, x, y): + i, j = (x - x0) / x_step, (y - y0) / y_step + i0, j0 = int(floor(i)), int(floor(j)) + return i0, j0, i, j + + +@njit(cache=True, fastmath=True) +def interp_uv(xd, yd, u00, u01, u10, u11, v00, v01, v10, v11): + xd_i, yd_i = 1 - xd, 1 - yd + u = (u00 * xd_i + u10 * xd) * yd_i + (u01 * xd_i + u11 * xd) * yd + v = (v00 * xd_i + v10 * xd) * yd_i + (v01 * xd_i + v11 * xd) * yd + return u, v + + +@njit(cache=True, fastmath=True) +def advect_t_rk4( + x_g, y_g, u_g0, v_g0, m_g0, u_g1, v_g1, m_g1, x, y, m, weigths, half_w +): # Grid coordinates x_ref, y_ref = x_g[0], y_g[0] x_step, y_step = x_g[1] - x_ref, y_g[1] - y_ref - # On each particule + # cache + i_cache, j_cache = -1000000, -1000000 + masked0, masked1 = False, False + u000, u001, u010, u011 = 0.0, 0.0, 0.0, 0.0 + v000, v001, v010, v011 = 0.0, 0.0, 0.0, 0.0 + u100, u101, u110, u111 = 0.0, 0.0, 0.0, 0.0 + v100, v101, v110, v111 = 0.0, 0.0, 0.0, 0.0 + # On each particle for i in prange(x.size): - # If particule are not valid => continue - x_, y_ = x[i], y[i] - if isnan(x_) or isnan(y_): + # If particle are not valid => continue + if m[i]: continue + x_, y_ = x[i], y[i] # Iterate on whole steps for w in weigths: # k1, slope at origin - u0_, v0_ = get_uv(x_ref, y_ref, x_step, y_step, u_g0, v_g0, m_g0, x_, y_) - u1_, v1_ = get_uv(x_ref, y_ref, x_step, y_step, u_g1, v_g1, m_g1, x_, y_) - u1, v1 = u0_ * w + u1_ * (1 - w), v0_ * w + v1_ * (1 - w) - if isnan(u1) or isnan(v1): + ii_, jj_, ii, jj = get_grid_indices(x_ref, y_ref, x_step, y_step, x_, y_) + if ii_ != i_cache or jj_ != j_cache: + masked0, u000, u001, u010, u011, v000, v001, v010, v011 = get_uv_quad( + ii_, jj_, u_g0, v_g0, m_g0 + ) + masked1, u100, u101, u110, u111, v100, v101, v110, v111 = get_uv_quad( + ii_, jj_, u_g1, v_g1, m_g1 + ) + i_cache, j_cache = ii_, jj_ + # The 3 following could be in cache operation but this one must be test in any case + if masked0 or masked1: x_, y_ = nan, nan + m[i] = True break + xd, yd = ii - ii_, jj - jj_ + u0_, v0_ = interp_uv(xd, yd, u000, u001, u010, u011, v000, v001, v010, v011) + u1_, v1_ = interp_uv(xd, yd, u100, u101, u110, u111, v100, v101, v110, v111) + u1, v1 = u0_ * w + u1_ * (1 - w), v0_ * w + v1_ * (1 - w) # k2, slope at middle with first guess position x1, y1 = x_ + u1 * 0.5, y_ + v1 * 0.5 - u0_, v0_ = get_uv(x_ref, y_ref, x_step, y_step, u_g0, v_g0, m_g0, x1, y1) - u1_, v1_ = get_uv(x_ref, y_ref, x_step, y_step, u_g1, v_g1, m_g1, x1, y1) + ii_, jj_, ii, jj = get_grid_indices(x_ref, y_ref, x_step, y_step, x1, y1) + if ii_ != i_cache or jj_ != j_cache: + masked0, u000, u001, u010, u011, v000, v001, v010, v011 = get_uv_quad( + ii_, jj_, u_g0, v_g0, m_g0 + ) + masked1, u100, u101, u110, u111, v100, v101, v110, v111 = get_uv_quad( + ii_, jj_, u_g1, v_g1, m_g1 + ) + i_cache, j_cache = ii_, jj_ + if masked0 or masked1: + x_, y_ = nan, nan + m[i] = True + break + xd, yd = ii - ii_, jj - jj_ + u0_, v0_ = interp_uv(xd, yd, u000, u001, u010, u011, v000, v001, v010, v011) + u1_, v1_ = interp_uv(xd, yd, u100, u101, u110, u111, v100, v101, v110, v111) w_ = w - half_w u2, v2 = u0_ * w_ + u1_ * (1 - w_), v0_ * w_ + v1_ * (1 - w_) - if isnan(u2) or isnan(v2): - x_, y_ = nan, nan - break # k3, slope at middle with update guess position x2, y2 = x_ + u2 * 0.5, y_ + v2 * 0.5 - u0_, v0_ = get_uv(x_ref, y_ref, x_step, y_step, u_g0, v_g0, m_g0, x2, y2) - u1_, v1_ = get_uv(x_ref, y_ref, x_step, y_step, u_g1, v_g1, m_g1, x2, y2) + ii_, jj_, ii, jj = get_grid_indices(x_ref, y_ref, x_step, y_step, x2, y2) + if ii_ != i_cache or jj_ != j_cache: + masked0, u000, u001, u010, u011, v000, v001, v010, v011 = get_uv_quad( + ii_, jj_, u_g0, v_g0, m_g0 + ) + masked1, u100, u101, u110, u111, v100, v101, v110, v111 = get_uv_quad( + ii_, jj_, u_g1, v_g1, m_g1 + ) + i_cache, j_cache = ii_, jj_ + if masked0 or masked1: + x_, y_ = nan, nan + m[i] = True + break + xd, yd = ii - ii_, jj - jj_ + u0_, v0_ = interp_uv(xd, yd, u000, u001, u010, u011, v000, v001, v010, v011) + u1_, v1_ = interp_uv(xd, yd, u100, u101, u110, u111, v100, v101, v110, v111) u3, v3 = u0_ * w_ + u1_ * (1 - w_), v0_ * w_ + v1_ * (1 - w_) - if isnan(u3) or isnan(v3): - x_, y_ = nan, nan - break # k4, slope at end with update guess position x3, y3 = x_ + u3, y_ + v3 - u0_, v0_ = get_uv(x_ref, y_ref, x_step, y_step, u_g0, v_g0, m_g0, x3, y3) - u1_, v1_ = get_uv(x_ref, y_ref, x_step, y_step, u_g1, v_g1, m_g1, x3, y3) + ii_, jj_, ii, jj = get_grid_indices(x_ref, y_ref, x_step, y_step, x3, y3) + if ii_ != i_cache or jj_ != j_cache: + masked0, u000, u001, u010, u011, v000, v001, v010, v011 = get_uv_quad( + ii_, jj_, u_g0, v_g0, m_g0 + ) + masked1, u100, u101, u110, u111, v100, v101, v110, v111 = get_uv_quad( + ii_, jj_, u_g1, v_g1, m_g1 + ) + i_cache, j_cache = ii_, jj_ + if masked0 or masked1: + x_, y_ = nan, nan + m[i] = True + break + xd, yd = ii - ii_, jj - jj_ + u0_, v0_ = interp_uv(xd, yd, u000, u001, u010, u011, v000, v001, v010, v011) + u1_, v1_ = interp_uv(xd, yd, u100, u101, u110, u111, v100, v101, v110, v111) w_ -= half_w u4, v4 = u0_ * w_ + u1_ * (1 - w_), v0_ * w_ + v1_ * (1 - w_) - if isnan(u4) or isnan(v4): - x_, y_ = nan, nan - break + # RK4 compute dx = (u1 + 2 * u2 + 2 * u3 + u4) / 6 dy = (v1 + 2 * v2 + 2 * v3 + v4) / 6 x_ += dx diff --git a/src/py_eddy_tracker/generic.py b/src/py_eddy_tracker/generic.py index 24b3cc22..d6915088 100644 --- a/src/py_eddy_tracker/generic.py +++ b/src/py_eddy_tracker/generic.py @@ -191,7 +191,25 @@ def interp2d_geo(x_g, y_g, z_g, m_g, x, y, nearest=False): :return: z interpolated :rtype: array """ - # TODO : Maybe test if we are out of bounds + if nearest: + return interp2d_nearest(x_g, y_g, z_g, x, y) + else: + return interp2d_bilinear(x_g, y_g, z_g, m_g, x, y) + + +@njit(cache=True, fastmath=True) +def interp2d_nearest(x_g, y_g, z_g, x, y): + """ + Nearest interpolation with wrapping if circular + + :param array x_g: coordinates of grid + :param array y_g: coordinates of grid + :param array z_g: Grid value + :param array x: coordinate where interpolate z + :param array y: coordinate where interpolate z + :return: z interpolated + :rtype: array + """ x_ref = x_g[0] y_ref = y_g[0] x_step = x_g[1] - x_ref @@ -200,45 +218,79 @@ def interp2d_geo(x_g, y_g, z_g, m_g, x, y, nearest=False): nb_y = y_g.shape[0] is_circular = abs(x_g[-1] % 360 - (x_g[0] - x_step) % 360) < 1e-5 z = empty(x.shape, dtype=z_g.dtype) + for i in prange(x.size): + i0 = int(round((x[i] - x_ref) / x_step)) + j0 = int(round((y[i] - y_ref) / y_step)) + if is_circular: + i0 %= nb_x + if i0 >= nb_x or i0 < 0 or j0 < 0 or j0 >= nb_y: + z[i] = nan + continue + z[i] = z_g[i0, j0] + return z + + +@njit(cache=True, fastmath=True) +def interp2d_bilinear(x_g, y_g, z_g, m_g, x, y): + """ + Bilinear interpolation with wrapping if circular + + :param array x_g: coordinates of grid + :param array y_g: coordinates of grid + :param array z_g: Grid value + :param array m_g: Boolean grid, True if value is masked + :param array x: coordinate where interpolate z + :param array y: coordinate where interpolate z + :return: z interpolated + :rtype: array + """ + x_ref = x_g[0] + y_ref = y_g[0] + x_step = x_g[1] - x_ref + y_step = y_g[1] - y_ref + nb_x = x_g.shape[0] + nb_y = y_g.shape[0] + is_circular = abs(x_g[-1] % 360 - (x_g[0] - x_step) % 360) < 1e-5 + # Indices which should be never exist + i0_old, j0_old, masked = -100000000, -10000000, False + z = empty(x.shape, dtype=z_g.dtype) for i in prange(x.size): x_ = (x[i] - x_ref) / x_step y_ = (y[i] - y_ref) / y_step i0 = int(floor(x_)) - i1 = i0 + 1 - xd = x_ - i0 j0 = int(floor(y_)) - j1 = j0 + 1 - if is_circular: - i0 %= nb_x - i1 %= nb_x - else: + # corner are the same need only a new xd and yd + if i0 != i0_old or j0 != j0_old: + i1 = i0 + 1 + j1 = j0 + 1 + if is_circular: + i0 %= nb_x + i1 %= nb_x if i1 >= nb_x or i0 < 0 or j0 < 0 or j1 >= nb_y: - z[i] = nan - continue - - yd = y_ - j0 - z00 = z_g[i0, j0] - z01 = z_g[i0, j1] - z10 = z_g[i1, j0] - z11 = z_g[i1, j1] - if m_g[i0, j0] or m_g[i0, j1] or m_g[i1, j0] or m_g[i1, j1]: + masked = True + else: + masked = False + if not masked: + if m_g[i0, j0] or m_g[i0, j1] or m_g[i1, j0] or m_g[i1, j1]: + masked = True + else: + z00, z01, z10, z11 = ( + z_g[i0, j0], + z_g[i0, j1], + z_g[i1, j0], + z_g[i1, j1], + ) + masked = False + # Need to be store only on change + i0_old, j0_old = i0, j0 + if masked: z[i] = nan else: - if nearest: - if xd <= 0.5: - if yd <= 0.5: - z[i] = z00 - else: - z[i] = z01 - else: - if yd <= 0.5: - z[i] = z10 - else: - z[i] = z11 - else: - z[i] = (z00 * (1 - xd) + (z10 * xd)) * (1 - yd) + ( - z01 * (1 - xd) + z11 * xd - ) * yd + xd = x_ - i0 + yd = y_ - j0 + z[i] = (z00 * (1 - xd) + (z10 * xd)) * (1 - yd) + ( + z01 * (1 - xd) + z11 * xd + ) * yd return z diff --git a/tests/test_grid.py b/tests/test_grid.py index 5da5390e..a7de8f8b 100644 --- a/tests/test_grid.py +++ b/tests/test_grid.py @@ -1,5 +1,5 @@ from matplotlib.path import Path -from numpy import array, ma +from numpy import array, isnan, ma from pytest import approx from py_eddy_tracker.data import get_path @@ -69,9 +69,19 @@ def test_interp(): ) x0, y0 = array((10,)), array((5,)) x1, y1 = array((15,)), array((5,)) + # outside but usable with nearest + x2, y2 = array((25,)), array((5,)) + # Outside for any interpolation + x3, y3 = array((25,)), array((16,)) + x4, y4 = array((55,)), array((25,)) # Interp nearest assert g.interp("z", x0, y0, method="nearest") == 0 assert g.interp("z", x1, y1, method="nearest") == 2 + assert isnan(g.interp("z", x4, y4, method="nearest")) + assert g.interp("z", x2, y2, method="nearest") == 2 + assert isnan(g.interp("z", x3, y3, method="nearest")) + # Interp bilinear assert g.interp("z", x0, y0) == 1.5 assert g.interp("z", x1, y1) == 2 + assert isnan(g.interp("z", x2, y2)) From 7b62de8505876471783bab58a92507dff3a30069 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Mon, 22 Feb 2021 11:39:41 +0100 Subject: [PATCH 055/249] speed up of iter_on with numba on digitize --- .../observations/observation.py | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index c376dc5e..0d0db782 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -491,7 +491,7 @@ def iter_on(self, xname, bins=None): if bins is None: bins = arange(x.min(), x.max() + 2) nb_bins = len(bins) - 1 - i = digitize(x, bins) - 1 + i = numba_digitize(x, bins) - 1 # Not monotonous if (d < 0).any(): i_sort = i.argsort() @@ -2380,3 +2380,30 @@ def sum_row_column(mask): row_sum[i] += 1 column_sum[j] += 1 return row_sum, column_sum + + +@njit(cache=True) +def numba_digitize(values, bins): + # Check if bins are regular + nb_bins = bins.shape[0] + step = bins[1] - bins[0] + bin_previous = bins[1] + for i in range(2, nb_bins): + bin_current = bins[i] + if step != (bin_current - bin_previous): + # If bins are not regular + return digitize(values, bins) + bin_previous = bin_current + nb_values = values.shape[0] + out = empty(nb_values, dtype=numba_types.int64) + up, down = bins[0], bins[-1] + for i in range(nb_values): + v_ = values[i] + if v_ >= down: + out[i] = nb_bins + continue + if v_ < up: + out[i] = 0 + continue + out[i] = (v_ - bins[0]) / step + 1 + return out From 4f7fbc44dac65b2879e48fa29dfee4559bba569e Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Mon, 22 Feb 2021 11:42:34 +0100 Subject: [PATCH 056/249] update examples --- examples/06_grid_manipulation/pet_advect.py | 108 ++++++++++++++---- examples/06_grid_manipulation/pet_lavd.py | 8 +- .../pet_center_count.py | 2 +- .../10_tracking_diagnostics/pet_pixel_used.py | 2 +- examples/14_generic_tools/pet_fit_contour.py | 1 + examples/16_network/pet_atlas.py | 66 +++++++++-- examples/16_network/pet_ioannou_2017_case.py | 7 +- examples/16_network/pet_relative.py | 6 +- .../16_network/pet_replay_segmentation.py | 7 +- .../06_grid_manipulation/pet_advect.ipynb | 101 ++++++++++++++-- .../06_grid_manipulation/pet_lavd.ipynb | 2 +- .../pet_center_count.ipynb | 2 +- .../pet_pixel_used.ipynb | 2 +- 13 files changed, 253 insertions(+), 61 deletions(-) diff --git a/examples/06_grid_manipulation/pet_advect.py b/examples/06_grid_manipulation/pet_advect.py index 838a2511..57ee3bf3 100644 --- a/examples/06_grid_manipulation/pet_advect.py +++ b/examples/06_grid_manipulation/pet_advect.py @@ -4,9 +4,11 @@ Dummy advection which use only static geostrophic current, which didn't resolve the complex circulation of the ocean. """ -import numpy as np +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 import data @@ -32,7 +34,7 @@ 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) +x, y = meshgrid(g.x_c, g.y_c) a.filled(ax, facecolors="r", alpha=0.1), c.filled(ax, facecolors="b", alpha=0.1) _ = ax.quiver(x.T, y.T, g.grid("u"), g.grid("v"), scale=20) @@ -41,7 +43,10 @@ class VideoAnimation(FuncAnimation): def _repr_html_(self, *args, **kwargs): """To get video in html and have a player""" - return self.to_html5_video() + 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"): @@ -56,26 +61,27 @@ def save(self, *args, **kwargs): # %% # Anim # ---- -# Particules positions -x, y = np.meshgrid(np.arange(13, 36, 0.125), np.arange(28, 40, 0.125)) +# 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 -m = ~np.isnan(g.interp("u", x, y)) -x, y = x[m], y[m] +m = ~isnan(g.interp("u", x, y)) +x0, y0 = x[m], y[m] +x, y = x0.copy(), y0.copy() +# %% # Movie properties -kwargs = dict(frames=np.arange(51), interval=90) +kwargs = dict(frames=arange(51), interval=100) kw_p = dict(nb_step=2, time_step=21600) frame_t = kw_p["nb_step"] * kw_p["time_step"] / 86400.0 -def anim_ax(generator, **kw): +# %% +# Method +def anim_ax(**kw): t = 0 - for _ in range(4): - generator.__next__() - t += frame_t - - fig = plt.figure(figsize=(10, 5), dpi=64) + fig = plt.figure(figsize=(10, 5), dpi=55) ax = fig.add_axes([0, 0, 1, 1], projection="full_axes") ax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid() a.filled(ax, facecolors="r", alpha=0.1), c.filled(ax, facecolors="b", alpha=0.1) @@ -94,20 +100,74 @@ def update(i_frame, t_step): # %% # Filament forward # ^^^^^^^^^^^^^^^^ -p = g.filament(x, y, "u", "v", **kw_p, filament_size=4, rk4=True) -fig, txt, l, t = anim_ax(p, lw=0.5) +# Draw 3 last position in one path for each particles., +# it could be run backward with `backward=True` option in filament method +p = g.filament(x, y, "u", "v", **kw_p, filament_size=3) +fig, txt, l, t = anim_ax(lw=0.5) ani = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,)) # %% -# Filament backward +# Particle forward # ^^^^^^^^^^^^^^^^^ -p = g.filament(x, y, "u", "v", **kw_p, filament_size=4, backward=True, rk4=True) -fig, txt, l, t = anim_ax(p, lw=0.5) +# Forward advection of particles +p = g.advect(x, y, "u", "v", **kw_p) +fig, txt, l, t = anim_ax(ls="", marker=".", markersize=1) +ani = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,)) + +# %% +# We get last position and run backward until original position +p = g.advect(x, y, "u", "v", **kw_p, backward=True) +fig, txt, l, _ = anim_ax(ls="", marker=".", markersize=1) ani = VideoAnimation(fig, update, **kwargs, fargs=(-frame_t,)) # %% -# Particule forward -# ^^^^^^^^^^^^^^^^^ -p = g.advect(x, y, "u", "v", **kw_p, rk4=True) -fig, txt, l, t = anim_ax(p, ls="", marker=".", markersize=1) -ani = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,)) +# Particles stat +# -------------- + +# %% +# Time_step settings +# ^^^^^^^^^^^^^^^^^^ +# Dummy experiment to test advection precision, we run particles 50 days forward and backward ad different time step +# and we measure distance between new positions and original positions. +fig = plt.figure() +ax = fig.add_subplot(111) +ax.grid() +kw = dict( + bins=arange(0, 50, 0.001), + cumulative=True, + weights=ones(x0.shape) / x0.shape[0] * 100.0, + histtype="step", +) +for time_step in (10800, 21600, 43200, 86400): + x, y = x0.copy(), y0.copy() + kw_advect = dict(nb_step=int(50 * 86400 / time_step), time_step=time_step) + g.advect(x, y, "u", "v", **kw_advect).__next__() + g.advect(x, y, "u", "v", **kw_advect, backward=True).__next__() + d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5 + ax.hist(d, **kw, label=f"{86400. / time_step:.0f} time step by day") +ax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc="lower right") +ax.set_title("Distance after 50 days forward and 50 days backward") +ax.set_xlabel("Distance between original position and final position (in degrees)") +_ = ax.set_ylabel("Percent of particles with distance lesser than") + +# %% +# Time duration +# ^^^^^^^^^^^^^ +# We keep same time_step but change time duration +fig = plt.figure() +ax = fig.add_subplot(111) +ax.grid() +time_step = 10800 +for duration in (5, 50, 100): + x, y = x0.copy(), y0.copy() + kw_advect = dict(nb_step=int(duration * 86400 / time_step), time_step=time_step) + g.advect(x, y, "u", "v", **kw_advect).__next__() + g.advect(x, y, "u", "v", **kw_advect, backward=True).__next__() + d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5 + ax.hist(d, **kw, label=f"Time duration {duration} days") +ax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc="lower right") +ax.set_title( + "Distance after N days forward and N days backward\nwith a time step of 1/8 days" +) +ax.set_xlabel("Distance between original position and final position (in degrees)") +_ = ax.set_ylabel("Percent of particles with distance lesser than ") diff --git a/examples/06_grid_manipulation/pet_lavd.py b/examples/06_grid_manipulation/pet_lavd.py index 4c4e394c..f3254450 100644 --- a/examples/06_grid_manipulation/pet_lavd.py +++ b/examples/06_grid_manipulation/pet_lavd.py @@ -7,8 +7,12 @@ Method are described here: - - Abernathey, Ryan, and George Haller. " Transport by Lagrangian Vortices in the Eastern Pacific", Journal of Physical Oceanography 48, 3 (2018): 667-685, accessed Feb 16, 2021, https://doi.org/10.1175/JPO-D-17-0102.1 - - `Transport by Coherent Lagrangian Vortices`_, R. Abernathey, Sinha A., Tarshish N., Liu T., Zhang C., Haller G., 2019, Talk a t the Sources and Sinks of Ocean Mesoscale Eddy Energy CLIVAR Workshop + - Abernathey, Ryan, and George Haller. "Transport by Lagrangian Vortices in the Eastern Pacific", + Journal of Physical Oceanography 48, 3 (2018): 667-685, accessed Feb 16, 2021, + https://doi.org/10.1175/JPO-D-17-0102.1 + - `Transport by Coherent Lagrangian Vortices`_, + R. Abernathey, Sinha A., Tarshish N., Liu T., Zhang C., Haller G., 2019, + Talk a t the Sources and Sinks of Ocean Mesoscale Eddy Energy CLIVAR Workshop .. _Transport by Coherent Lagrangian Vortices: https://usclivar.org/sites/default/files/meetings/2019/presentations/Aberernathey_CLIVAR.pdf diff --git a/examples/10_tracking_diagnostics/pet_center_count.py b/examples/10_tracking_diagnostics/pet_center_count.py index 4533b72f..01c27a0f 100644 --- a/examples/10_tracking_diagnostics/pet_center_count.py +++ b/examples/10_tracking_diagnostics/pet_center_count.py @@ -62,7 +62,7 @@ g_c.vars["count"] = ratio m = g_c.display( - ax_ratio, name="count", vmin=0.1, vmax=10, norm=LogNorm(), cmap="coolwarm_r" + ax_ratio, name="count", norm=LogNorm(vmin=0.1, vmax=10), cmap="coolwarm_r" ) plt.colorbar(m, cax=fig.add_axes([0.94, 0.02, 0.01, 0.2])) diff --git a/examples/10_tracking_diagnostics/pet_pixel_used.py b/examples/10_tracking_diagnostics/pet_pixel_used.py index 6241bf9f..63a466c9 100644 --- a/examples/10_tracking_diagnostics/pet_pixel_used.py +++ b/examples/10_tracking_diagnostics/pet_pixel_used.py @@ -61,7 +61,7 @@ g_c.vars["count"] = ratio m = g_c.display( - ax_ratio, name="count", vmin=0.1, vmax=10, norm=LogNorm(), cmap="coolwarm_r" + ax_ratio, name="count", norm=LogNorm(vmin=0.1, vmax=10), cmap="coolwarm_r" ) plt.colorbar(m, cax=fig.add_axes([0.95, 0.02, 0.01, 0.2])) diff --git a/examples/14_generic_tools/pet_fit_contour.py b/examples/14_generic_tools/pet_fit_contour.py index 34cda453..ca472e34 100644 --- a/examples/14_generic_tools/pet_fit_contour.py +++ b/examples/14_generic_tools/pet_fit_contour.py @@ -21,6 +21,7 @@ # 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): diff --git a/examples/16_network/pet_atlas.py b/examples/16_network/pet_atlas.py index cbb7b3e9..dcb15042 100644 --- a/examples/16_network/pet_atlas.py +++ b/examples/16_network/pet_atlas.py @@ -6,18 +6,16 @@ from numpy import ma import py_eddy_tracker.gui +from py_eddy_tracker.data import get_path from py_eddy_tracker.observations.network import NetworkObservations -n = NetworkObservations.load_file( - "/data/adelepoulle/work/Eddies/20201217_network_build/tracking/med/Anticyclonic_seg.nc" -) - +n = NetworkObservations.load_file(get_path("Anticyclonic_seg.nc")) # %% # Parameters step = 1 / 10.0 bins = ((-10, 37, step), (30, 46, step)) kw_time = dict(cmap="terrain_r", factor=100.0 / n.nb_days, name="count") -kw_ratio = dict(cmap=plt.get_cmap("magma_r", 10)) +kw_ratio = dict(cmap=plt.get_cmap("viridis", 10)) # %% @@ -149,16 +147,26 @@ def update_axes(ax, mappable=None): ax, **kw_ratio, vmin=0, - vmax=1, + vmax=5, name=g_all_merging.vars["count"] * 100.0 / g_all.vars["count"] ) update_axes(ax, m).set_label("Pixel used in % all atlas") +# %% +# Merging in networks longer than 10 days, with dead end remove (shorter than 5 days) +# ----------------------------------------------------------------------------------- +ax = start_axes("") +merger = n10.remove_dead_end(nobs=10).merging_event() +g_10_merging = merger.grid_count(bins) +m = g_10_merging.display(ax, **kw_time, vmin=0, vmax=1) +update_axes(ax, m).set_label("Pixel used in % of time") + # %% # Merging in networks longer than 10 days # --------------------------------------- ax = start_axes("") -g_10_merging = n10.merging_event().grid_count(bins) +merger = n10.merging_event() +g_10_merging = merger.grid_count(bins) m = g_10_merging.display(ax, **kw_time, vmin=0, vmax=1) update_axes(ax, m).set_label("Pixel used in % of time") # %% @@ -167,10 +175,52 @@ def update_axes(ax, mappable=None): ax, **kw_ratio, vmin=0, - vmax=2, + vmax=5, name=ma.array( g_10_merging.vars["count"] * 100.0 / g_10.vars["count"], mask=g_10.vars["count"] < 365, ) ) update_axes(ax, m).set_label("Pixel used in % all atlas") + +# %% +# All Spliting +# ------------ +# Display the occurence of spliting events +ax = start_axes("") +g_all_spliting = n.spliting_event().grid_count(bins) +m = g_all_spliting.display(ax, **kw_time, vmin=0, vmax=1) +update_axes(ax, m).set_label("Pixel used in % of time") + +# %% +# Ratio merging events / eddy presence +ax = start_axes("") +m = g_all_spliting.display( + ax, + **kw_ratio, + vmin=0, + vmax=5, + name=g_all_spliting.vars["count"] * 100.0 / g_all.vars["count"] +) +update_axes(ax, m).set_label("Pixel used in % all atlas") + +# %% +# Spliting in networks longer than 10 days +# ---------------------------------------- +ax = start_axes("") +g_10_spliting = n10.spliting_event().grid_count(bins) +m = g_10_spliting.display(ax, **kw_time, vmin=0, vmax=1) +update_axes(ax, m).set_label("Pixel used in % of time") +# %% +ax = start_axes("") +m = g_10_spliting.display( + ax, + **kw_ratio, + vmin=0, + vmax=5, + name=ma.array( + g_10_spliting.vars["count"] * 100.0 / g_10.vars["count"], + mask=g_10.vars["count"] < 365, + ) +) +update_axes(ax, m).set_label("Pixel used in % all atlas") diff --git a/examples/16_network/pet_ioannou_2017_case.py b/examples/16_network/pet_ioannou_2017_case.py index 2e7f807e..ff72c22a 100644 --- a/examples/16_network/pet_ioannou_2017_case.py +++ b/examples/16_network/pet_ioannou_2017_case.py @@ -12,13 +12,14 @@ from datetime import datetime, timedelta import numpy as np +from matplotlib import colors from matplotlib import pyplot as plt from matplotlib.animation import FuncAnimation from matplotlib.ticker import FuncFormatter -from matplotlib import colors import py_eddy_tracker.gui from py_eddy_tracker.appli.gui import Anim +from py_eddy_tracker.data import get_path from py_eddy_tracker.observations.network import NetworkObservations @@ -71,9 +72,7 @@ def update_axes(ax, mappable=None): # We know the position and the time of a specific eddy # # `n.extract_with_mask` give us the corresponding network -n = NetworkObservations.load_file( - "med/Anticyclonic_seg.nc" -) +n = NetworkObservations.load_file(get_path("Anticyclonic_seg.nc")) i = np.where( (n.lat > 33) * (n.lat < 34) diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index f743d3b4..4a57062a 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -55,7 +55,7 @@ # %% # Timeline by mean Effective Radius -# ----------------------- +# --------------------------------- # The factor argument is applied on the chosen field fig = plt.figure(figsize=(15, 5)) ax = fig.add_axes([0.04, 0.04, 0.92, 0.92]) @@ -237,7 +237,7 @@ # %% # Get birth event -# ------------------ +# --------------- # Display the starting position of non-splitted eddies fig = plt.figure(figsize=(15, 8)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") @@ -248,7 +248,7 @@ # %% # Get death event -# ------------------ +# --------------- # Display the last position of non-merged eddies fig = plt.figure(figsize=(15, 8)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") diff --git a/examples/16_network/pet_replay_segmentation.py b/examples/16_network/pet_replay_segmentation.py index c90fca9d..c88226dd 100644 --- a/examples/16_network/pet_replay_segmentation.py +++ b/examples/16_network/pet_replay_segmentation.py @@ -11,13 +11,14 @@ from datetime import datetime, timedelta import numpy as np +from matplotlib import colors from matplotlib import pyplot as plt from matplotlib.animation import FuncAnimation from matplotlib.ticker import FuncFormatter -from matplotlib import colors import py_eddy_tracker.gui from py_eddy_tracker.appli.gui import Anim +from py_eddy_tracker.data import get_path from py_eddy_tracker.observations.network import NetworkObservations from py_eddy_tracker.observations.tracking import TrackEddiesObservations @@ -120,9 +121,7 @@ def get_obs(dataset): # %% # Get original network, we will isolate only relative at order *2* -n = NetworkObservations.load_file( - "/data/adelepoulle/work/Eddies/20201217_network_build/tracking/med/Anticyclonic_seg.nc" -) +n = NetworkObservations.load_file(get_path("Anticyclonic_seg.nc")) n = n.extract_with_mask(n.track == n.track[get_obs(n)]) n_ = n.relative(get_obs(n), order=2) diff --git a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb index 62b3e0a9..fea60cd1 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import numpy as np\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\nfrom py_eddy_tracker.observations.observation import EddiesObservations" + "import re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, isnan, meshgrid, ones\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\nfrom py_eddy_tracker.observations.observation import EddiesObservations" ] }, { @@ -80,7 +80,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(10, 5))\nax = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\nax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid()\nx, y = np.meshgrid(g.x_c, g.y_c)\na.filled(ax, facecolors=\"r\", alpha=0.1), c.filled(ax, facecolors=\"b\", alpha=0.1)\n_ = ax.quiver(x.T, y.T, g.grid(\"u\"), g.grid(\"v\"), scale=20)" + "fig = plt.figure(figsize=(10, 5))\nax = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\nax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid()\nx, y = meshgrid(g.x_c, g.y_c)\na.filled(ax, facecolors=\"r\", alpha=0.1), c.filled(ax, facecolors=\"b\", alpha=0.1)\n_ = ax.quiver(x.T, y.T, g.grid(\"u\"), g.grid(\"v\"), scale=20)" ] }, { @@ -91,14 +91,14 @@ }, "outputs": [], "source": [ - "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n return self.to_html5_video()\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Anim\nParticules positions\n\n" + "## Anim\nParticles setup\n\n" ] }, { @@ -109,14 +109,14 @@ }, "outputs": [], "source": [ - "x, y = np.meshgrid(np.arange(13, 36, 0.125), np.arange(28, 40, 0.125))\nx, y = x.reshape(-1), y.reshape(-1)\n# Remove all original position that we can't advect at first place\nm = ~np.isnan(g.interp(\"u\", x, y))\nx, y = x[m], y[m]\n\n# Movie properties\nkwargs = dict(frames=np.arange(51), interval=90)\nkw_p = dict(nb_step=2, time_step=21600)\nframe_t = kw_p[\"nb_step\"] * kw_p[\"time_step\"] / 86400.0\n\n\ndef anim_ax(generator, **kw):\n t = 0\n for _ in range(4):\n generator.__next__()\n t += frame_t\n\n fig = plt.figure(figsize=(10, 5), dpi=64)\n ax = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\n ax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid()\n a.filled(ax, facecolors=\"r\", alpha=0.1), c.filled(ax, facecolors=\"b\", alpha=0.1)\n line = ax.plot([], [], \"k\", **kw)[0]\n return fig, ax.text(21, 32.1, \"\"), line, t\n\n\ndef update(i_frame, t_step):\n global t\n x, y = p.__next__()\n t += t_step\n l.set_data(x, y)\n txt.set_text(f\"T0 + {t:.1f} days\")" + "step_p = 1 / 8\nx, y = meshgrid(arange(13, 36, step_p), arange(28, 40, step_p))\nx, y = x.reshape(-1), y.reshape(-1)\n# Remove all original position that we can't advect at first place\nm = ~isnan(g.interp(\"u\", x, y))\nx0, y0 = x[m], y[m]\nx, y = x0.copy(), y0.copy()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Filament forward\n\n" + "Movie properties\n\n" ] }, { @@ -127,14 +127,14 @@ }, "outputs": [], "source": [ - "p = g.filament(x, y, \"u\", \"v\", **kw_p, filament_size=4, rk4=True)\nfig, txt, l, t = anim_ax(p, lw=0.5)\nani = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,))" + "kwargs = dict(frames=arange(51), interval=100)\nkw_p = dict(nb_step=2, time_step=21600)\nframe_t = kw_p[\"nb_step\"] * kw_p[\"time_step\"] / 86400.0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Filament backward\n\n" + "Method\n\n" ] }, { @@ -145,14 +145,14 @@ }, "outputs": [], "source": [ - "p = g.filament(x, y, \"u\", \"v\", **kw_p, filament_size=4, backward=True, rk4=True)\nfig, txt, l, t = anim_ax(p, lw=0.5)\nani = VideoAnimation(fig, update, **kwargs, fargs=(-frame_t,))" + "def anim_ax(**kw):\n t = 0\n fig = plt.figure(figsize=(10, 5), dpi=55)\n ax = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\n ax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid()\n a.filled(ax, facecolors=\"r\", alpha=0.1), c.filled(ax, facecolors=\"b\", alpha=0.1)\n line = ax.plot([], [], \"k\", **kw)[0]\n return fig, ax.text(21, 32.1, \"\"), line, t\n\n\ndef update(i_frame, t_step):\n global t\n x, y = p.__next__()\n t += t_step\n l.set_data(x, y)\n txt.set_text(f\"T0 + {t:.1f} days\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Particule forward\n\n" + "### Filament forward\nDraw 3 last position in one path for each particles.,\nit could be run backward with `backward=True` option in filament method\n\n" ] }, { @@ -163,7 +163,86 @@ }, "outputs": [], "source": [ - "p = g.advect(x, y, \"u\", \"v\", **kw_p, rk4=True)\nfig, txt, l, t = anim_ax(p, ls=\"\", marker=\".\", markersize=1)\nani = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,))" + "p = g.filament(x, y, \"u\", \"v\", **kw_p, filament_size=3)\nfig, txt, l, t = anim_ax(lw=0.5)\nani = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Particle forward\nForward advection of particles\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "p = g.advect(x, y, \"u\", \"v\", **kw_p)\nfig, txt, l, t = anim_ax(ls=\"\", marker=\".\", markersize=1)\nani = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We get last position and run backward until original position\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "p = g.advect(x, y, \"u\", \"v\", **kw_p, backward=True)\nfig, txt, l, _ = anim_ax(ls=\"\", marker=\".\", markersize=1)\nani = VideoAnimation(fig, update, **kwargs, fargs=(-frame_t,))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Particles stat\n\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Time_step settings\nDummy experiment to test advection precision, we run particles 50 days forward and backward ad different time step\nand we measure distance between new positions and original positions.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure()\nax = fig.add_subplot(111)\nax.grid()\nkw = dict(\n bins=arange(0, 50, 0.001),\n cumulative=True,\n weights=ones(x0.shape) / x0.shape[0] * 100.0,\n histtype=\"step\",\n)\nfor time_step in (10800, 21600, 43200, 86400):\n x, y = x0.copy(), y0.copy()\n kw_advect = dict(nb_step=int(50 * 86400 / time_step), time_step=time_step)\n g.advect(x, y, \"u\", \"v\", **kw_advect).__next__()\n g.advect(x, y, \"u\", \"v\", **kw_advect, backward=True).__next__()\n d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5\n ax.hist(d, **kw, label=f\"{86400. / time_step:.0f} time step by day\")\nax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc=\"lower right\")\nax.set_title(\"Distance after 50 days forward and 50 days backward\")\nax.set_xlabel(\"Distance between original position and final position (in degrees)\")\n_ = ax.set_ylabel(\"Percent of particles with distance lesser than\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Time duration\nWe keep same time_step but change time duration\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure()\nax = fig.add_subplot(111)\nax.grid()\ntime_step = 10800\nfor duration in (5, 50, 100):\n x, y = x0.copy(), y0.copy()\n kw_advect = dict(nb_step=int(duration * 86400 / time_step), time_step=time_step)\n g.advect(x, y, \"u\", \"v\", **kw_advect).__next__()\n g.advect(x, y, \"u\", \"v\", **kw_advect, backward=True).__next__()\n d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5\n ax.hist(d, **kw, label=f\"Time duration {duration} days\")\nax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc=\"lower right\")\nax.set_title(\n \"Distance after N days forward and N days backward\\nwith a time step of 1/8 days\"\n)\nax.set_xlabel(\"Distance between original position and final position (in degrees)\")\n_ = ax.set_ylabel(\"Percent of particles with distance lesser than \")" ] } ], diff --git a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb index 5241f6bc..82933787 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# LAVD experiment\n\nNaive method to reproduce LAVD(Lagrangian-Averaged Vorticity deviation) method with a static velocity field.\nIn the current example we didn't remove a mean vorticity.\n\nMethod are described here:\n\n - Abernathey, Ryan, and George Haller. \" Transport by Lagrangian Vortices in the Eastern Pacific\", Journal of Physical Oceanography 48, 3 (2018): 667-685, accessed Feb 16, 2021, https://doi.org/10.1175/JPO-D-17-0102.1\n - `Transport by Coherent Lagrangian Vortices`_, R. Abernathey, Sinha A., Tarshish N., Liu T., Zhang C., Haller G., 2019, Talk a t the Sources and Sinks of Ocean Mesoscale Eddy Energy CLIVAR Workshop\n\n https://usclivar.org/sites/default/files/meetings/2019/presentations/Aberernathey_CLIVAR.pdf\n" + "\n# LAVD experiment\n\nNaive method to reproduce LAVD(Lagrangian-Averaged Vorticity deviation) method with a static velocity field.\nIn the current example we didn't remove a mean vorticity.\n\nMethod are described here:\n\n - Abernathey, Ryan, and George Haller. \"Transport by Lagrangian Vortices in the Eastern Pacific\",\n Journal of Physical Oceanography 48, 3 (2018): 667-685, accessed Feb 16, 2021,\n https://doi.org/10.1175/JPO-D-17-0102.1\n - `Transport by Coherent Lagrangian Vortices`_,\n R. Abernathey, Sinha A., Tarshish N., Liu T., Zhang C., Haller G., 2019,\n Talk a t the Sources and Sinks of Ocean Mesoscale Eddy Energy CLIVAR Workshop\n\n https://usclivar.org/sites/default/files/meetings/2019/presentations/Aberernathey_CLIVAR.pdf\n" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb index 15a4362b..023b9178 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb @@ -80,7 +80,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(12, 18.5))\nax_a = fig.add_axes([0.03, 0.75, 0.90, 0.25])\nax_a.set_title(\"Anticyclonic center frequency\")\nax_c = fig.add_axes([0.03, 0.5, 0.90, 0.25])\nax_c.set_title(\"Cyclonic center frequency\")\nax_all = fig.add_axes([0.03, 0.25, 0.90, 0.25])\nax_all.set_title(\"All eddies center frequency\")\nax_ratio = fig.add_axes([0.03, 0.0, 0.90, 0.25])\nax_ratio.set_title(\"Ratio cyclonic / Anticyclonic\")\n\n# Count pixel used for each center\ng_a = a.grid_count(bins, intern=True, center=True)\ng_a.display(ax_a, **kwargs_pcolormesh)\ng_c = c.grid_count(bins, intern=True, center=True)\ng_c.display(ax_c, **kwargs_pcolormesh)\n# Compute a ratio Cyclonic / Anticyclonic\nratio = g_c.vars[\"count\"] / g_a.vars[\"count\"]\n\n# Mask manipulation to be able to sum the 2 grids\nm_c = g_c.vars[\"count\"].mask\nm = m_c & g_a.vars[\"count\"].mask\ng_c.vars[\"count\"][m_c] = 0\ng_c.vars[\"count\"] += g_a.vars[\"count\"]\ng_c.vars[\"count\"].mask = m\n\nm = g_c.display(ax_all, **kwargs_pcolormesh)\ncb = plt.colorbar(m, cax=fig.add_axes([0.94, 0.27, 0.01, 0.7]))\ncb.set_label(\"Eddies by 1\u00b0^2 by day\")\n\ng_c.vars[\"count\"] = ratio\nm = g_c.display(\n ax_ratio, name=\"count\", vmin=0.1, vmax=10, norm=LogNorm(), cmap=\"coolwarm_r\"\n)\nplt.colorbar(m, cax=fig.add_axes([0.94, 0.02, 0.01, 0.2]))\n\nfor ax in (ax_a, ax_c, ax_all, ax_ratio):\n ax.set_aspect(\"equal\")\n ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\n ax.grid()" + "fig = plt.figure(figsize=(12, 18.5))\nax_a = fig.add_axes([0.03, 0.75, 0.90, 0.25])\nax_a.set_title(\"Anticyclonic center frequency\")\nax_c = fig.add_axes([0.03, 0.5, 0.90, 0.25])\nax_c.set_title(\"Cyclonic center frequency\")\nax_all = fig.add_axes([0.03, 0.25, 0.90, 0.25])\nax_all.set_title(\"All eddies center frequency\")\nax_ratio = fig.add_axes([0.03, 0.0, 0.90, 0.25])\nax_ratio.set_title(\"Ratio cyclonic / Anticyclonic\")\n\n# Count pixel used for each center\ng_a = a.grid_count(bins, intern=True, center=True)\ng_a.display(ax_a, **kwargs_pcolormesh)\ng_c = c.grid_count(bins, intern=True, center=True)\ng_c.display(ax_c, **kwargs_pcolormesh)\n# Compute a ratio Cyclonic / Anticyclonic\nratio = g_c.vars[\"count\"] / g_a.vars[\"count\"]\n\n# Mask manipulation to be able to sum the 2 grids\nm_c = g_c.vars[\"count\"].mask\nm = m_c & g_a.vars[\"count\"].mask\ng_c.vars[\"count\"][m_c] = 0\ng_c.vars[\"count\"] += g_a.vars[\"count\"]\ng_c.vars[\"count\"].mask = m\n\nm = g_c.display(ax_all, **kwargs_pcolormesh)\ncb = plt.colorbar(m, cax=fig.add_axes([0.94, 0.27, 0.01, 0.7]))\ncb.set_label(\"Eddies by 1\u00b0^2 by day\")\n\ng_c.vars[\"count\"] = ratio\nm = g_c.display(\n ax_ratio, name=\"count\", norm=LogNorm(vmin=0.1, vmax=10), cmap=\"coolwarm_r\"\n)\nplt.colorbar(m, cax=fig.add_axes([0.94, 0.02, 0.01, 0.2]))\n\nfor ax in (ax_a, ax_c, ax_all, ax_ratio):\n ax.set_aspect(\"equal\")\n ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\n ax.grid()" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb index 902ed654..14141cd1 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb @@ -80,7 +80,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(12, 18.5))\nax_a = fig.add_axes([0.03, 0.75, 0.90, 0.25])\nax_a.set_title(\"Anticyclonic frequency\")\nax_c = fig.add_axes([0.03, 0.5, 0.90, 0.25])\nax_c.set_title(\"Cyclonic frequency\")\nax_all = fig.add_axes([0.03, 0.25, 0.90, 0.25])\nax_all.set_title(\"All eddies frequency\")\nax_ratio = fig.add_axes([0.03, 0.0, 0.90, 0.25])\nax_ratio.set_title(\"Ratio cyclonic / Anticyclonic\")\n\n# Count pixel used for each contour\ng_a = a.grid_count(bins, intern=True)\ng_a.display(ax_a, **kwargs_pcolormesh)\ng_c = c.grid_count(bins, intern=True)\ng_c.display(ax_c, **kwargs_pcolormesh)\n# Compute a ratio Cyclonic / Anticyclonic\nratio = g_c.vars[\"count\"] / g_a.vars[\"count\"]\n\n# Mask manipulation to be able to sum the 2 grids\nm_c = g_c.vars[\"count\"].mask\nm = m_c & g_a.vars[\"count\"].mask\ng_c.vars[\"count\"][m_c] = 0\ng_c.vars[\"count\"] += g_a.vars[\"count\"]\ng_c.vars[\"count\"].mask = m\n\nm = g_c.display(ax_all, **kwargs_pcolormesh)\nplt.colorbar(m, cax=fig.add_axes([0.95, 0.27, 0.01, 0.7]))\n\ng_c.vars[\"count\"] = ratio\nm = g_c.display(\n ax_ratio, name=\"count\", vmin=0.1, vmax=10, norm=LogNorm(), cmap=\"coolwarm_r\"\n)\nplt.colorbar(m, cax=fig.add_axes([0.95, 0.02, 0.01, 0.2]))\n\nfor ax in (ax_a, ax_c, ax_all, ax_ratio):\n ax.set_aspect(\"equal\")\n ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\n ax.grid()" + "fig = plt.figure(figsize=(12, 18.5))\nax_a = fig.add_axes([0.03, 0.75, 0.90, 0.25])\nax_a.set_title(\"Anticyclonic frequency\")\nax_c = fig.add_axes([0.03, 0.5, 0.90, 0.25])\nax_c.set_title(\"Cyclonic frequency\")\nax_all = fig.add_axes([0.03, 0.25, 0.90, 0.25])\nax_all.set_title(\"All eddies frequency\")\nax_ratio = fig.add_axes([0.03, 0.0, 0.90, 0.25])\nax_ratio.set_title(\"Ratio cyclonic / Anticyclonic\")\n\n# Count pixel used for each contour\ng_a = a.grid_count(bins, intern=True)\ng_a.display(ax_a, **kwargs_pcolormesh)\ng_c = c.grid_count(bins, intern=True)\ng_c.display(ax_c, **kwargs_pcolormesh)\n# Compute a ratio Cyclonic / Anticyclonic\nratio = g_c.vars[\"count\"] / g_a.vars[\"count\"]\n\n# Mask manipulation to be able to sum the 2 grids\nm_c = g_c.vars[\"count\"].mask\nm = m_c & g_a.vars[\"count\"].mask\ng_c.vars[\"count\"][m_c] = 0\ng_c.vars[\"count\"] += g_a.vars[\"count\"]\ng_c.vars[\"count\"].mask = m\n\nm = g_c.display(ax_all, **kwargs_pcolormesh)\nplt.colorbar(m, cax=fig.add_axes([0.95, 0.27, 0.01, 0.7]))\n\ng_c.vars[\"count\"] = ratio\nm = g_c.display(\n ax_ratio, name=\"count\", norm=LogNorm(vmin=0.1, vmax=10), cmap=\"coolwarm_r\"\n)\nplt.colorbar(m, cax=fig.add_axes([0.95, 0.02, 0.01, 0.2]))\n\nfor ax in (ax_a, ax_c, ax_all, ax_ratio):\n ax.set_aspect(\"equal\")\n ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\n ax.grid()" ] }, { From b075e2bd672f868965a8cd36715e6caf413f309a Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Mon, 22 Feb 2021 16:21:24 +0100 Subject: [PATCH 057/249] add option to increase circle size by a factor --- src/py_eddy_tracker/observations/observation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 0d0db782..5885500f 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -366,7 +366,7 @@ def add_rotation_type(self): new.type_cyc[:] = self.sign_type return new - def circle_contour(self, only_virtual=False): + def circle_contour(self, only_virtual=False, factor=1): """ Set contours as a circles from radius and center data. @@ -381,12 +381,12 @@ def circle_contour(self, only_virtual=False): continue x, y = obs["lon"], obs["lat"] if radius_s: - r_s = obs["radius_s"] + r_s = obs["radius_s"] * factor obs["contour_lon_s"], obs["contour_lat_s"] = local_to_coordinates( x_norm * r_s, y_norm * r_s, x, y ) if radius_e: - r_e = obs["radius_e"] + r_e = obs["radius_e"] * factor obs["contour_lon_e"], obs["contour_lat_e"] = local_to_coordinates( x_norm * r_e, y_norm * r_e, x, y ) From 0f32a116cdca8212ecb1a42871602cd18e804d93 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Mon, 22 Feb 2021 16:21:47 +0100 Subject: [PATCH 058/249] replace list by set for connexions information --- src/py_eddy_tracker/observations/network.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 522a34c6..d8c339cf 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -173,8 +173,8 @@ def connexions(self, multi_network=False): def add_seg(father, child): if father not in segments_connexion: - segments_connexion[father] = list() - segments_connexion[father].append(child) + segments_connexion[father] = set() + segments_connexion[father].add(child) previous_obs, next_obs = self.previous_obs, self.next_obs for i, seg, _ in self.iter_on(segment): From 19b2b4f994f488bfbc7f60f5ba5359cf1ef789cc Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Thu, 25 Feb 2021 13:05:21 +0100 Subject: [PATCH 059/249] minor fix --- examples/06_grid_manipulation/pet_lavd.py | 8 ++++---- examples/16_network/pet_replay_segmentation.py | 4 +--- examples/16_network/pet_segmentation_anim.py | 4 +--- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/examples/06_grid_manipulation/pet_lavd.py b/examples/06_grid_manipulation/pet_lavd.py index f3254450..8d29db9b 100644 --- a/examples/06_grid_manipulation/pet_lavd.py +++ b/examples/06_grid_manipulation/pet_lavd.py @@ -8,11 +8,11 @@ Method are described here: - Abernathey, Ryan, and George Haller. "Transport by Lagrangian Vortices in the Eastern Pacific", - Journal of Physical Oceanography 48, 3 (2018): 667-685, accessed Feb 16, 2021, - https://doi.org/10.1175/JPO-D-17-0102.1 + Journal of Physical Oceanography 48, 3 (2018): 667-685, accessed Feb 16, 2021, + https://doi.org/10.1175/JPO-D-17-0102.1 - `Transport by Coherent Lagrangian Vortices`_, - R. Abernathey, Sinha A., Tarshish N., Liu T., Zhang C., Haller G., 2019, - Talk a t the Sources and Sinks of Ocean Mesoscale Eddy Energy CLIVAR Workshop + R. Abernathey, Sinha A., Tarshish N., Liu T., Zhang C., Haller G., 2019, + Talk a t the Sources and Sinks of Ocean Mesoscale Eddy Energy CLIVAR Workshop .. _Transport by Coherent Lagrangian Vortices: https://usclivar.org/sites/default/files/meetings/2019/presentations/Aberernathey_CLIVAR.pdf diff --git a/examples/16_network/pet_replay_segmentation.py b/examples/16_network/pet_replay_segmentation.py index c88226dd..92b448b4 100644 --- a/examples/16_network/pet_replay_segmentation.py +++ b/examples/16_network/pet_replay_segmentation.py @@ -11,13 +11,11 @@ from datetime import datetime, timedelta import numpy as np -from matplotlib import colors from matplotlib import pyplot as plt from matplotlib.animation import FuncAnimation from matplotlib.ticker import FuncFormatter import py_eddy_tracker.gui -from py_eddy_tracker.appli.gui import Anim from py_eddy_tracker.data import get_path from py_eddy_tracker.observations.network import NetworkObservations from py_eddy_tracker.observations.tracking import TrackEddiesObservations @@ -34,7 +32,7 @@ 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 h: + with open(args[0], "w") as _: pass return return super().save(*args, **kwargs) diff --git a/examples/16_network/pet_segmentation_anim.py b/examples/16_network/pet_segmentation_anim.py index cc0dc23c..922600f5 100644 --- a/examples/16_network/pet_segmentation_anim.py +++ b/examples/16_network/pet_segmentation_anim.py @@ -85,6 +85,4 @@ def update(i_frame): mappable_tracks = ax.scatter( e.lon, e.lat, c=TRACKS[0], cmap=cmap, vmin=0, vmax=vmax, s=20 ) -ani = VideoAnimation( - fig, update, frames=range(1, len(TRACKS), 4), interval=125, blit=True -) +ani = VideoAnimation(fig, update, frames=range(1, len(TRACKS), 4), interval=125) From 2ecca8369a53238a04ed0139924eb4d5c112cf92 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Thu, 25 Feb 2021 13:06:07 +0100 Subject: [PATCH 060/249] remove repeated point in contour to speed up computation --- .../observations/observation.py | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 5885500f..408272b8 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -2194,6 +2194,26 @@ def grid_count_pixel_in( grid_count_(grid, i, j) +@njit(cache=True) +def reduce_size(x, y): + """ + Reduce array size if last position is repeated, in order to save compute time + + :param array x: longitude + :param array y: latitude + + :return: reduce arrays x,y + :rtype: ndarray,ndarray + """ + i = x.shape[0] + x0, y0 = x[0], y[0] + while True: + i -= 1 + if x[i] != x0 or y[i] != y0: + i += 1 + return x[:i], y[:i] + + @njit(cache=True) def poly_indexs(x_p, y_p, x_c, y_c): """ @@ -2208,9 +2228,10 @@ def poly_indexs(x_p, y_p, x_c, y_c): nb_c = x_c.shape[0] indexs = -ones(nb_p, dtype=numba_types.int32) for i in range(nb_c): - x_c_min, y_c_min = x_c[i].min(), y_c[i].min() - x_c_max, y_c_max = x_c[i].max(), y_c[i].max() - v = create_vertice(x_c[i], y_c[i]) + x_, y_ = reduce_size(x_c[i], y_c[i]) + x_c_min, y_c_min = x_.min(), y_.min() + x_c_max, y_c_max = x_.max(), y_.max() + v = create_vertice(x_, y_) for j in range(nb_p): if indexs[j] != -1: continue @@ -2235,9 +2256,10 @@ def insidepoly(x_p, y_p, x_c, y_c): nb_c = x_c.shape[0] flag = zeros(nb_p, dtype=numba_types.bool_) for i in range(nb_c): - x_c_min, y_c_min = x_c[i].min(), y_c[i].min() - x_c_max, y_c_max = x_c[i].max(), y_c[i].max() - v = create_vertice(x_c[i], y_c[i]) + x_, y_ = reduce_size(x_c[i], y_c[i]) + x_c_min, y_c_min = x_.min(), y_.min() + x_c_max, y_c_max = x_.max(), y_.max() + v = create_vertice(x_, y_) for j in range(nb_p): if flag[j]: continue From 98b19f73a24035aa19c5a58d7b5322f6f8d90f3d Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle Date: Thu, 25 Feb 2021 13:10:46 +0100 Subject: [PATCH 061/249] - Add example to illustrate grouping step: - add feature to group with in-memory object Simplification of transfer method when 2 network are joined --- examples/16_network/pet_group_anim.py | 150 ++++++++++++++++++ src/py_eddy_tracker/observations/network.py | 19 ++- .../observations/observation.py | 6 +- 3 files changed, 171 insertions(+), 4 deletions(-) create mode 100644 examples/16_network/pet_group_anim.py diff --git a/examples/16_network/pet_group_anim.py b/examples/16_network/pet_group_anim.py new file mode 100644 index 00000000..151366c2 --- /dev/null +++ b/examples/16_network/pet_group_anim.py @@ -0,0 +1,150 @@ +""" +Network group process +===================== +""" + +import re +from datetime import datetime + +from matplotlib import pyplot as plt +from matplotlib.animation import FuncAnimation +from matplotlib.colors import ListedColormap +from numba import njit +from numpy import arange, array, empty, ones + +from py_eddy_tracker import data +from py_eddy_tracker.generic import flatten_line_matrix +from py_eddy_tracker.observations.network import Network +from py_eddy_tracker.observations.observation import EddiesObservations + + +# %% +class VideoAnimation(FuncAnimation): + def _repr_html_(self, *args, **kwargs): + """To get video in html and have a player""" + content = self.to_html5_video() + return re.sub( + '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) + + +# %% +NETWORK_GROUPS = list() + + +@njit(cache=True) +def apply_replace(x, x0, x1): + nb = x.shape[0] + for i in range(nb): + if x[i] == x0: + x[i] = x1 + + +# %% +# Modified class to catch group process at each step in order to illustrate processing +class MyNetwork(Network): + def get_group_array(self, results, nb_obs): + """With a loop on all pair of index, we will label each obs with a group + number + """ + nb_obs = array(nb_obs, dtype="u4") + day_start = nb_obs.cumsum() - nb_obs + gr = empty(nb_obs.sum(), dtype="u4") + gr[:] = self.NOGROUP + + id_free = 1 + for i, j, ii, ij in results: + gr_i = gr[slice(day_start[i], day_start[i] + nb_obs[i])] + gr_j = gr[slice(day_start[j], day_start[j] + nb_obs[j])] + # obs with no groups + m = (gr_i[ii] == self.NOGROUP) * (gr_j[ij] == self.NOGROUP) + nb_new = m.sum() + gr_i[ii[m]] = gr_j[ij[m]] = arange(id_free, id_free + nb_new) + id_free += nb_new + # associate obs with no group with obs with group + m = (gr_i[ii] != self.NOGROUP) * (gr_j[ij] == self.NOGROUP) + gr_j[ij[m]] = gr_i[ii[m]] + m = (gr_i[ii] == self.NOGROUP) * (gr_j[ij] != self.NOGROUP) + gr_i[ii[m]] = gr_j[ij[m]] + # case where 2 obs have a different group + m = gr_i[ii] != gr_j[ij] + if m.any(): + # 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("Anticyclonic_seg.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) + + +# %% +def update(frame): + i_current, i_match, gr = NETWORK_GROUPS[frame] + current = EDDIES_BY_DAYS[i_current] + x = flatten_line_matrix(current.contour_lon_e) + y = flatten_line_matrix(current.contour_lat_e) + current_contour.set_data(x, y) + match = EDDIES_BY_DAYS[i_match] + x = flatten_line_matrix(match.contour_lon_e) + y = flatten_line_matrix(match.contour_lat_e) + matched_contour.set_data(x, y) + groups.set_array(gr) + txt.set_text(f"Day {i_current} match with day {i_match}") + s = 80 * ones(gr.shape) + s[gr == 0] = 4 + groups.set_sizes(s) + + +# %% +# Anim +# ---- +fig = plt.figure(figsize=(16, 9), dpi=50) +ax = fig.add_axes([0, 0, 1, 1]) +ax.set_aspect("equal"), ax.grid(), ax.set_xlim(26, 34), ax.set_ylim(32, 36.5) +groups = ax.scatter( + e.lon, + e.lat, + c=NETWORK_GROUPS[0][2], + cmap=ListedColormap(["gray", *e.COLORS[:-1]], name="from_list", N=30), + vmin=0, + vmax=30, +) +current_contour = ax.plot([], [], "k", lw=2, label="Current contour")[0] +matched_contour = ax.plot([], [], "r", lw=1, ls="--", label="Candidate contour")[0] +txt = ax.text(31.5, 35.5, "", fontsize=25) +ax.legend(fontsize=25) +ani = VideoAnimation(fig, update, frames=len(NETWORK_GROUPS), interval=220) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index d8c339cf..973989e3 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -43,6 +43,8 @@ def __init__(self, buffersize, intern=False, memory=False): self.memory = memory def load_contour(self, filename): + if isinstance(filename, EddiesObservations): + return filename[self.xname], filename[self.yname] if filename not in self.DATA: if len(self.FLIST) > self.buffersize: self.DATA.pop(self.FLIST.pop(0)) @@ -815,10 +817,18 @@ def __init__(self, input_regex, window=5, intern=False, memory=False): """ self.window = window self.buffer = Buffer(window, intern, memory) + self.memory = memory + self.filenames = glob(input_regex) self.filenames.sort() self.nb_input = len(self.filenames) - self.memory = memory + + @classmethod + def from_eddiesobservations(cls, observations, *args, **kwargs): + new = cls("", *args, **kwargs) + new.filenames = observations + new.nb_input = len(new.filenames) + return new def get_group_array(self, results, nb_obs): """With a loop on all pair of index, we will label each obs with a group @@ -849,10 +859,13 @@ def get_group_array(self, results, nb_obs): if m.any(): # Merge of group, ref over etu for i_, j_ in zip(ii[m], ij[m]): - merge_id.append((gr_i[i_], gr_j[j_])) + g0, g1 = gr_i[i_], gr_j[j_] + if g0 > g1: + g0, g1 = g1, g0 + merge_id.append((g0, g1)) gr_transfer = arange(id_free, dtype="u4") - for i, j in merge_id: + for i, j in set(merge_id): gr_i, gr_j = gr_transfer[i], gr_transfer[j] if gr_i != gr_j: apply_replace(gr_transfer, gr_i, gr_j) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 408272b8..4e671147 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -490,6 +490,8 @@ def iter_on(self, xname, bins=None): d = x[1:] - x[:-1] if bins is None: bins = arange(x.min(), x.max() + 2) + elif not isinstance(bins, ndarray): + bins = array(bins) nb_bins = len(bins) - 1 i = numba_digitize(x, bins) - 1 # Not monotonous @@ -1609,7 +1611,9 @@ def extract_with_area(self, area, **kwargs): .. minigallery:: py_eddy_tracker.EddiesObservations.extract_with_area """ - mask = (self.latitude > area["llcrnrlat"]) * (self.latitude < area["urcrnrlat"]) + lat0 = area.get("llcrnrlat", -90) + lat1 = area.get("urcrnrlat", 90) + mask = (self.latitude > lat0) * (self.latitude < lat1) lon0 = area["llcrnrlon"] lon = (self.longitude - lon0) % 360 + lon0 mask *= (lon > lon0) * (lon < area["urcrnrlon"]) From d7656c30a8c13d591013828fa445feefe7aeb702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Thu, 25 Feb 2021 14:00:07 +0100 Subject: [PATCH 062/249] Modification dissociate (#56) * update animation example * dissociate_network for multiple networks --- examples/16_network/pet_segmentation_anim.py | 14 ++++++- src/py_eddy_tracker/observations/network.py | 42 +++++++++++++++----- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/examples/16_network/pet_segmentation_anim.py b/examples/16_network/pet_segmentation_anim.py index 922600f5..360ccedf 100644 --- a/examples/16_network/pet_segmentation_anim.py +++ b/examples/16_network/pet_segmentation_anim.py @@ -37,12 +37,14 @@ def save(self, *args, **kwargs): # %% # Overlaod of class to pick up TRACKS = list() +INDICES = list() class MyTrack(TrackEddiesObservations): @staticmethod def get_next_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs): TRACKS.append(ids["track"].copy()) + INDICES.append(i_current) return TrackEddiesObservations.get_next_obs( i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs ) @@ -70,9 +72,16 @@ def get_next_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwarg def update(i_frame): tr = TRACKS[i_frame] mappable_tracks.set_array(tr) - s = 80 * ones(tr.shape) + s = 40 * ones(tr.shape) s[tr == 0] = 4 mappable_tracks.set_sizes(s) + + indices_frames = INDICES[i_frame] + mappable_CONTOUR.set_data( + e.contour_lon_e[indices_frames], + e.contour_lat_e[indices_frames], + ) + mappable_CONTOUR.set_color(cmap.colors[tr[indices_frames] % len(cmap.colors)]) return (mappable_tracks,) @@ -85,4 +94,7 @@ def update(i_frame): mappable_tracks = ax.scatter( e.lon, e.lat, c=TRACKS[0], cmap=cmap, vmin=0, vmax=vmax, s=20 ) +mappable_CONTOUR = ax.plot( + e.contour_lon_e[INDICES[0]], e.contour_lat_e[INDICES[0]], color=cmap.colors[0] +)[0] ani = VideoAnimation(fig, update, frames=range(1, len(TRACKS), 4), interval=125) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 973989e3..33b857ca 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -166,6 +166,9 @@ def obs_relative_order(self, i_obs): return self.segment_relative_order(self.segment[i_obs]) def connexions(self, multi_network=False): + """ + create dictionnary for each segments, gives the segments which interact with + """ if multi_network: segment = self.segment_track_array else: @@ -650,10 +653,12 @@ def dissociate_network(self): """ Dissociate network with no known interaction (spliting/merging) """ - self.only_one_network() - tags = self.tag_segment() - # FIXME : Ok if only one network - self.track[:] = tags[self.segment - 1] + + tags = self.tag_segment(multi_network=True) + if self.track[0] == 0: + tags -= 1 + + self.track[:] = tags[self.segment_track_array] i_sort = self.obs.argsort(order=("track", "segment", "time"), kind="mergesort") # Sort directly obs, with hope to save memory @@ -674,23 +679,40 @@ def network(self, id_network): @classmethod def __tag_segment(cls, seg, tag, groups, connexions): + """ + Will set same temporary ID for each connected segment. + + :param int seg: current ID of seg + :param ing tag: temporary ID to set for seg and its connexion + :param array[int] groups: array where tag will be stored + :param dict connexions: gives for one ID of seg all seg connected + """ + # If seg are already used we stop recursivity if groups[seg] != 0: return + # We set tag for this seg groups[seg] = tag - segs = connexions.get(seg + 1, None) + # Get all connexions of this seg + segs = connexions.get(seg, None) if segs is not None: for seg in segs: - cls.__tag_segment(seg - 1, tag, groups, connexions) + # For each connexion we apply same function + cls.__tag_segment(seg, tag, groups, connexions) - def tag_segment(self): - self.only_one_network() - nb = self.segment.max() + def tag_segment(self, multi_network=False): + if multi_network: + nb = self.segment_track_array[-1] + 1 + else: + nb = self.segment.max() + 1 sub_group = zeros(nb, dtype="u4") - c = self.connexions() + c = self.connexions(multi_network=multi_network) j = 1 + # for each available id for i in range(nb): + # Skip if already set if sub_group[i] != 0: continue + # we tag an unset segments and explore all connexions self.__tag_segment(i, j, sub_group, c) j += 1 return sub_group From 24dbe92a50400af9dfed9084f8ba33349129d2f2 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Fri, 26 Feb 2021 13:03:01 +0100 Subject: [PATCH 063/249] Use numba to compute stencil --- doc/run_tracking.rst | 2 +- src/py_eddy_tracker/dataset/grid.py | 218 +++++++++++++++++++--------- 2 files changed, 148 insertions(+), 72 deletions(-) diff --git a/doc/run_tracking.rst b/doc/run_tracking.rst index 0760d7bb..0a03848d 100644 --- a/doc/run_tracking.rst +++ b/doc/run_tracking.rst @@ -7,7 +7,7 @@ Requirements Before to run tracking, you will need to run identification on every time step of the period (period of your study). -**Advice** : Before to run tracking, displaying some identification file allows one to learn a lot +**Advice** : Before to run tracking, displaying some identification file allows to learn a lot Default method ************** diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index bdbe2ea3..96abbea7 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -23,7 +23,6 @@ float_, floor, histogram2d, - int8, int_, interp, isnan, @@ -47,7 +46,7 @@ ) from pint import UnitRegistry from scipy.interpolate import RectBivariateSpline, interp1d -from scipy.ndimage import convolve, gaussian_filter +from scipy.ndimage import gaussian_filter from scipy.signal import welch from scipy.spatial import cKDTree from scipy.special import j1 @@ -1677,77 +1676,19 @@ def compute_stencil( ... - """ stencil_halfwidth = max(min(int(stencil_halfwidth), 4), 1) logger.debug("Stencil half width apply : %d", stencil_halfwidth) - # output - grad = None - - weights = [ - array((3, -32, 168, -672, 0, 672, -168, 32, -3)) / 840.0, - array((-1, 9, -45, 0, 45, -9, 1)) / 60.0, - array((1, -8, 0, 8, -1)) / 12.0, - array((-1, 0, 1)) / 2.0, - # uncentered kernel - # like array((0, -1, 1)) but left value could be default value - array((-1, 1)), - # like array((-1, 1, 0)) but right value could be default value - (1, array((-1, 1))), - ] - # reduce to stencil selected - weights = weights[4 - stencil_halfwidth :] - if vertical: - data = data.T - # Iteration from larger stencil to smaller (to fill matrix) - for weight in weights: - if isinstance(weight, tuple): - # In the case of unbalanced diff - shift, weight = weight - data_ = data.copy() - data_[shift:] = data[:-shift] - if not vertical: - data_[:shift] = data[-shift:] - else: - data_ = data - # Delta h - d_h = convolve(data_, weights=weight.reshape((-1, 1)), mode=mode) - mask = convolve( - int8(data_.mask), weights=ones(weight.shape).reshape((-1, 1)), mode=mode - ) - d_h = ma.array(d_h, mask=mask != 0) - - # Delta d - if vertical: - d_h = d_h.T - d = self.EARTH_RADIUS * 2 * pi / 360 * convolve(self.y_c, weight) - else: - if mode == "wrap": - # Along x axis, we need to close - # we will compute in two part - x = self.x_c % 360 - d_degrees = convolve(x, weight, mode=mode) - d_degrees_180 = convolve((x + 180) % 360 - 180, weight, mode=mode) - # Arbitrary, to be sure to be far far away of bound - m = (x < 90) + (x > 270) - d_degrees[m] = d_degrees_180[m] - else: - d_degrees = convolve(self.x_c, weight, mode=mode) - d = ( - self.EARTH_RADIUS - * 2 - * pi - / 360 - * d_degrees.reshape((-1, 1)) - * cos(deg2rad(self.y_c)) - ) - if grad is None: - # First Gradient - grad = d_h / d - else: - # Fill hole - grad[grad.mask] = (d_h / d)[grad.mask] - return grad + g, m = compute_stencil( + self.x_c, + self.y_c, + data.data, + data.mask, + self.EARTH_RADIUS, + vertical=vertical, + stencil_halfwidth=stencil_halfwidth, + ) + return ma.array(g, mask=m) def add_uv_lagerloef(self, grid_height, uname="u", vname="v", schema=15): self.add_uv(grid_height, uname, vname) @@ -1804,13 +1745,26 @@ def add_uv_lagerloef(self, grid_height, uname="u", vname="v", schema=15): self.vars[uname][:, sl] = self.vars[uname][:, sl] * w + u_lagerloef * (1 - w) def add_uv(self, grid_height, uname="u", vname="v", stencil_halfwidth=4): - """Compute a u and v grid + r"""Compute a u and v grid :param str grid_height: grid name where the funtion will apply stencil method :param str uname: future name of u :param str vname: future name of v :param int stencil_halfwidth: largest stencil could be apply (max: 4) + .. math:: + u = \frac{g}{f} \frac{dh}{dy} + + v = -\frac{g}{f} \frac{dh}{dx} + + where + + .. math:: + g = gravity + + f = 2 \Omega sin(\phi) + + .. minigallery:: py_eddy_tracker.RegularGridDataset.add_uv """ logger.info("Add u/v variable with stencil method") @@ -2665,3 +2619,125 @@ def advect_t_rk4( x_ += dx y_ += dy x[i], y[i] = x_, y_ + + +@njit( + [ + "Tuple((f8[:,:],b1[:,:]))(f8[:],f8[:],f8[:,:],b1[:,:],f8,b1,i1)", + "Tuple((f4[:,:],b1[:,:]))(f8[:],f8[:],f4[:,:],b1[:,:],f8,b1,i1)", + ], + cache=True, + fastmath=True, +) +def compute_stencil(x, y, h, m, earth_radius, vertical=False, stencil_halfwidth=4): + """ + Compute stencil on RegularGrid + + :param array x: longitude coordinates + :param array y: latitude coordinates + :param array h: 2D array to derivate + :param array m: mask associate to h to know where are invalid data + :param float earth_radius: Earth radius in m + :param bool vertical: if True stencil will be vertical (along y) + :param int stencil_halfwidth: from 1 to 4 to specify maximal kernel usable + + + stencil_halfwidth: + + - (1) : + + - (-1, 1, 0) + - (0, -1, 1) + - (-1, 0, 1) / 2 + + - (2) : (1, -8, 0, 8, 1) / 12 + - (3) : (-1, 9, -45, 0, 45, -9, 1) / 60 + - (4) : (3, -32, 168, -672, 0, 672, -168, 32, 3) / 840 + """ + if vertical: + # If vertical we transpose matrix and inverse coordinates + h = h.T + m = m.T + x, y = y, x + shape = h.shape + nb_x, nb_y = shape + # Out array + m_out = empty(shape, dtype=numba_types.bool_) + grad = empty(shape, dtype=h.dtype) + # Distance step in degrees + d_step = x[1] - x[0] + if vertical: + is_circular = False + else: + # Test if matrix is circular + is_circular = abs(x[-1] % 360 - (x[0] - d_step) % 360) < 1e-5 + + # Compute caracteristic distance, constant when vertical + d_ = 360 / (d_step * pi * 2 * earth_radius) + for j in range(nb_y): + # Buffer of maximal size of stencil (9) + if is_circular: + h_3, h_2, h_1, h0 = h[-4, j], h[-3, j], h[-2, j], h[-1, j] + m_3, m_2, m_1, m0 = m[-4, j], m[-3, j], m[-2, j], m[-1, j] + else: + m_3, m_2, m_1, m0 = False, False, False, False + h1, h2, h3, h4 = h[0, j], h[1, j], h[2, j], h[3, j] + m1, m2, m3, m4 = m[0, j], m[1, j], m[2, j], m[3, j] + for i in range(nb_x): + # Roll value and only last + h_4, h_3, h_2, h_1, h0, h1, h2, h3 = h_3, h_2, h_1, h0, h1, h2, h3, h4 + m_4, m_3, m_2, m_1, m0, m1, m2, m3 = m_3, m_2, m_1, m0, m1, m2, m3, m4 + i_ = i + 4 + if i_ >= nb_x: + if is_circular: + i_ = i_ % nb_x + m4 = m[i_, j] + h4 = h[i_, j] + else: + # When we are out + m4 = False + else: + m4 = m[i_, j] + h4 = h[i_, j] + + # Current value not defined + if m0: + m_out[i, j] = True + continue + if not vertical: + # For each row we compute distance + d_ = 360 / (d_step * cos(deg2rad(y[j])) * pi * 2 * earth_radius) + if m1 ^ m_1: + # unbalanced kernel + if m_1: + grad[i, j] = (h1 - h0) * d_ + m_out[i, j] = False + continue + if m1: + grad[i, j] = (h0 - h_1) * d_ + m_out[i, j] = False + continue + continue + if m2 or m_2 or stencil_halfwidth == 1: + grad[i, j] = (h1 - h_1) / 2 * d_ + m_out[i, j] = False + continue + if m3 or m_3 or stencil_halfwidth == 2: + grad[i, j] = (h_2 - h2 + 8 * (h1 - h_1)) / 12 * d_ + m_out[i, j] = False + continue + if m4 or m_4 or stencil_halfwidth == 3: + grad[i, j] = (h3 - h_3 + 9 * (h_2 - h2) + 45 * (h1 - h_1)) / 60 * d_ + m_out[i, j] = False + continue + # If all value of buffer are available + grad[i, j] = ( + (3 * (h_4 - h4) + 32 * (h3 - h_3) + 168 * (h_2 - h2) + 672 * (h1 - h_1)) + / 840 + * d_ + ) + m_out[i, j] = False + if vertical: + return grad.T, m_out.T + else: + return grad, m_out From da2fbe28d7bf7208577d5b220e191326852969cd Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Fri, 26 Feb 2021 15:50:09 +0100 Subject: [PATCH 064/249] Label will be expand in filled observation method --- src/py_eddy_tracker/observations/observation.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 4e671147..938cb905 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -1712,6 +1712,8 @@ def filled( v = (v - vmin) / (vmax - vmin) colors = [cmap(v_) for v_ in v] kwargs["facecolors"] = colors + if "label" in kwargs: + kwargs["label"] = self.format_label(kwargs["label"]) c = PolyCollection(verts, **kwargs) ax.add_collection(c) c.cmap = cmap From 61190bd6dd148638c9d8c91b28ec4215f738201f Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Tue, 2 Mar 2021 11:13:54 +0100 Subject: [PATCH 065/249] Add doc --- doc/installation.rst | 8 +++++++- examples/02_eddy_identification/README.rst | 2 ++ examples/06_grid_manipulation/README.rst | 2 +- examples/08_tracking_manipulation/README.rst | 2 ++ examples/10_tracking_diagnostics/README.rst | 2 ++ examples/12_external_data/README.rst | 2 ++ examples/14_generic_tools/README.rst | 1 + 7 files changed, 17 insertions(+), 2 deletions(-) diff --git a/doc/installation.rst b/doc/installation.rst index 40ce9ad5..b2bcb45c 100644 --- a/doc/installation.rst +++ b/doc/installation.rst @@ -2,7 +2,13 @@ How do I get set up ? ===================== -Source are available on github https://github.com/AntSimi/py-eddy-tracker +You could install stable version with pip + +.. code-block:: bash + + pip install pyEddyTracker + +Or with source which are available on github https://github.com/AntSimi/py-eddy-tracker Use python3. To avoid problems with installation, use of the virtualenv Python virtual environment is recommended or conda. diff --git a/examples/02_eddy_identification/README.rst b/examples/02_eddy_identification/README.rst index 30d23e5b..07ef8f44 100644 --- a/examples/02_eddy_identification/README.rst +++ b/examples/02_eddy_identification/README.rst @@ -1,2 +1,4 @@ Eddy detection ============== + +Method to detect eddies from grid and display, with various parameters. diff --git a/examples/06_grid_manipulation/README.rst b/examples/06_grid_manipulation/README.rst index 7a300f82..a885d867 100644 --- a/examples/06_grid_manipulation/README.rst +++ b/examples/06_grid_manipulation/README.rst @@ -1,2 +1,2 @@ Grid Manipulation -================= \ No newline at end of file +================= diff --git a/examples/08_tracking_manipulation/README.rst b/examples/08_tracking_manipulation/README.rst index 2626f19d..a971049f 100644 --- a/examples/08_tracking_manipulation/README.rst +++ b/examples/08_tracking_manipulation/README.rst @@ -1,2 +1,4 @@ Tracking Manipulation ===================== + +Method to subset and display atlas. \ No newline at end of file diff --git a/examples/10_tracking_diagnostics/README.rst b/examples/10_tracking_diagnostics/README.rst index 1c4e690a..2030c0cc 100644 --- a/examples/10_tracking_diagnostics/README.rst +++ b/examples/10_tracking_diagnostics/README.rst @@ -1,2 +1,4 @@ Tracking diagnostics ==================== + +Method to produce statistics with eddies atlas. \ No newline at end of file diff --git a/examples/12_external_data/README.rst b/examples/12_external_data/README.rst index cc9d4e2f..7ecbe30b 100644 --- a/examples/12_external_data/README.rst +++ b/examples/12_external_data/README.rst @@ -1,2 +1,4 @@ External data ============= + +Eddies comparison with external data diff --git a/examples/14_generic_tools/README.rst b/examples/14_generic_tools/README.rst index 0f949ec4..295d55fe 100644 --- a/examples/14_generic_tools/README.rst +++ b/examples/14_generic_tools/README.rst @@ -1,3 +1,4 @@ Polygon tools ============= +Method to work with contour \ No newline at end of file From 4a572e81e88dda67a308b90126e0304d008d44f8 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Tue, 2 Mar 2021 11:14:31 +0100 Subject: [PATCH 066/249] move method --- src/py_eddy_tracker/observations/network.py | 1 + .../observations/observation.py | 21 +------------------ src/py_eddy_tracker/poly.py | 20 ++++++++++++++++++ 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 33b857ca..8989c01f 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -886,6 +886,7 @@ def get_group_array(self, results, nb_obs): g0, g1 = g1, g0 merge_id.append((g0, g1)) + # FIXME: how it's work when several merge ? like (0,1), (0,2), (1,3) gr_transfer = arange(id_free, dtype="u4") for i, j in set(merge_id): gr_i, gr_j = gr_transfer[i], gr_transfer[j] diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 938cb905..6920659e 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -65,6 +65,7 @@ convexs, create_vertice, get_pixel_in_regular, + reduce_size, vertice_overlap, winding_number_poly, ) @@ -2200,26 +2201,6 @@ def grid_count_pixel_in( grid_count_(grid, i, j) -@njit(cache=True) -def reduce_size(x, y): - """ - Reduce array size if last position is repeated, in order to save compute time - - :param array x: longitude - :param array y: latitude - - :return: reduce arrays x,y - :rtype: ndarray,ndarray - """ - i = x.shape[0] - x0, y0 = x[0], y[0] - while True: - i -= 1 - if x[i] != x0 or y[i] != y0: - i += 1 - return x[:i], y[:i] - - @njit(cache=True) def poly_indexs(x_p, y_p, x_c, y_c): """ diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index d1bf5fb8..7790b3ec 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -765,3 +765,23 @@ def visvalingam(x, y, fixed_size=18): x_new[j:] = x_new[0] y_new[j:] = y_new[0] return x_new, y_new + + +@njit(cache=True) +def reduce_size(x, y): + """ + Reduce array size if last position is repeated, in order to save compute time + + :param array x: longitude + :param array y: latitude + + :return: reduce arrays x,y + :rtype: ndarray,ndarray + """ + i = x.shape[0] + x0, y0 = x[0], y[0] + while True: + i -= 1 + if x[i] != x0 or y[i] != y0: + i += 1 + return x[:i], y[:i] From 1bfd5c0fd232cd47f68357bbf00c8fe89ba77952 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Tue, 2 Mar 2021 11:15:45 +0100 Subject: [PATCH 067/249] Add data cube over med for example --- .../data/dt_med_allsat_phy_l4_2005T2.nc | Bin 0 -> 2051901 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/py_eddy_tracker/data/dt_med_allsat_phy_l4_2005T2.nc diff --git a/src/py_eddy_tracker/data/dt_med_allsat_phy_l4_2005T2.nc b/src/py_eddy_tracker/data/dt_med_allsat_phy_l4_2005T2.nc new file mode 100644 index 0000000000000000000000000000000000000000..cff2e2c7efe556e455c38ea346a59427ef5eae64 GIT binary patch literal 2051901 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

gaodXY8%6Uw693BJp;`&tR1A3Yb zSL=5C!_8M9nd?^Ky^W~~7lxl6NAU;pcsd0Dz{U~m06`18zC*Z~49lN`S4cmUP95I8 z1|`LB$6;d^2;d+x>EK%uc2-Bc0Fj??eiehK>Eh6}UT14iz`;Iu24CvY%gwZU%LfMK32Ckm%TfMByO zDn+oqwz+MW@KTWcqjhE=!0xH$(&DIy$5}9DnD1`X=x5m(!+Y*G zi-P*09rD<47VPjlE#`2gt$(zTKVaqJus;<5poYCWdAWyGAicipj?dqtQ1Tf=wyj$u zHY`pRDsIZHd#Ws-B+8^n=>Hg`W4Y={JuN$Mx8h$D#ddWnh)5(;#c1Ie$aXYEzrBiU zZtUL6z^O2^>z_P?Yu$H;frbRyS87KG4JXn>!1Y|FhTLk2luN(!H6))Mdv*(2bVhY= z7%auXTAGx*Odh;maiCp(LSh%l0Cc=q)f<+}VI{xy5!Y>=NMDD8f?20q?;sej00_Do zOfMHMTbh?UjEx9-Kl+)`ts=9Mnz%$7h-l{hm=$gv2xZFVVwD;(!PoZjUJpY)mRg5gsXDR<%vr!#<$!-gA zRm`dd#Y2w-k1d?`ddcG z4aRU_AzmfDbKUu_rC{2P5coUca;#ia7XE>6o3pM!&{OR{v1LHV0>DQjI5C+ssrNhG z&ymNGv1N*I$*Fj(Bc5Ui`>^f47=HYt#rz&x1@kQlmRyhn{#?M@b2;|L&SlpqL}bug z`Tm^9G<9BXbOP7q%yDa!Lk%Z-Fkvm3@~3`YU(#IAq7td0c;#v?L#j?GlsNowgMd#6-RAL@<#=+B+~&%D?CWdo=pxGv9H}gEu23C& zYp`vs`3^Mh4+t*)s#%Woz{FFvtd>FUHq(Ex;5T0e{ zGIgNi2Haa#xqP8Plma`(PpO@@1=|E~|H;pSe;e!*{LN*lp;oeu-T;n9b3EMpFy#3d zFGj-2N;R#I8tZ-f3yi?3;IvS%G`4(?Upja`N$>>0wa6P#7a+<?7e(9v>ot07!Zq64^1jbvJ7|{BvQciwc67*O|QS`i6HA~GTm^` zanf7bL0kc>=sE66W%IO^>)rixV67!T&b=Qs*8Z`GvQpzC+;=7G^I%{0rZb`J*7uuq_N0yj*x6? zFpfa8Pp`~K(U<*ply=7!sWkO;G_@6I*1aiL%HGAdf*UrSUQ@}2-1t^HY+O-JW@kf2 zY<p{xVE{@`?Qot?HdsAM{D^59`}Gj;di>?jX7RMvRZaPFrf#_ zZHSvJ!H%TvvUEPJrSmLX>{qtG3WC#8dDcHvhrT{S;ZqSM+01k0LqUbxEi-`b{xEIl zZNO)Ga59Bnq^pThK)Zg+6VtvpIo_J0c^%7eR1j9Wf}-ZK>_&cq1p3?o)*-TanoXCA0<&hQ|E0;k_ zk&Uw-bd-ewHIfj!J5boDSBF#|Gs768(!$+c{%9?KK-(BJ_Vq%Qn*ivisjbt4%^q)g zq~k6-TwsRrcfi^vGFO?TDSB$r0H5`zj|jfYl2Aw6Kt!Z4(AUS96ynaNeDju2`-F?V zPF(LcDzauop&$-2*pcbWU&P(b*q&SD91r`5(mGHb z?9o$Rf-E!e`xCL=u@n-;OLKB_kxQ6m9gAn}?FZ7pUml->GP)c_(Kejl&D195f4t&} z8$U$=z|b!pZ{qL{-l~`2=~CH?_(s>Bx`&St~)#C~;Cq5mTw_|H?(Qm;PcrRL-Xn5k0U6j?J)_)@Bz z_NVhY%AfdbYLU@cA2=@Umcxlg-NwhIR26y{TUX%bC_Q-3m7|OJ!whec+AnRzjo+G+ z!D1rJH^UWMpquJ$lUQ^x?+x{@u*DpkrrHDKtD_y=T>~B8lA|E0;J19LB&Rx#L1+rf zTwsdWt1*QbFGz~YXdM2sJ=$l+=4wu;Q?pIMr`rau-d%KK3nx!^-E7S+{DPv`H{>4^0|f)# zMkjv+Xd}StkJ5WzzO|x?xv@N2I;B(l>!xgg$oFToTTwVAp(YNUW6kltIyifcO`~Ur zyK`0V4LzEqinicR2D8g%F%1T3{2I?-Wm}*5OuwJ^x}$wqJ!Y9UK|!+@H#gfqE_A!M zqfh`LM~U$FIf$6;pv`!iBu|G;f=eqd&Vo4m?!$@D+1JeChixVHy^yDT?YEgP`p$yI zkopjd(>PpOXlVj?RISC6OPii~>V8_h=H2O0Zlrfp4J8#0s&8mwMRY}IoZuzjNMx^@ z#yq>CC4WUh*G0_1d(TJo!<~hnHo~FjZ5dzBR;9L-6~Bc9J_P_4THMt1J9JRuK4th) zgAkDkMBbP*93ZjVm#rTo5#pHqPX~T2%gQZQhiQfoGNqkE9%L1DlR=@V!%L>q>V|lDofxp_i0C_^hVI#Q^_wGb*U(?mHv|c|h z(|Al5B4W^X^gwpna<$Ex!6mv&AYc60DTsohqmNqTw>4dxw`e6pez67+P)1(QP?W0< zY{@e12rnKy({B*dD?CmUaku*MoK7~fjWSveQ85!)6X+6>qnfJ0JX`jsGZ3J?S_7jJ zMVws=ccGiE4~BVEaRxHb`y7bZ~v%_zWF%{k6O|?-UzaN&z5mF49Rj9he^)c8L z8O!yfs8*#<;rf4YZ2BjO^fD9x%a1P|xj{#TfPRUg9%1hnW0Y?epJDa!(Kh9HZcxJB zD|bOpbX4=m{`!V|*Mp1>1)Ro*WW6$0C?yP4)-dU2;Y4TGuYET7Qg|VEDp2pWH{3h4sv$Z@*u7nqn7fhmFFQ2)v}i|f##^M zxwEmpZIIwowD3N^k(97S`q-cw)#*sJ36Da#or^3?L+$h*v^lYvccog;ms2U?G0) zj!5pGJ2;+f>DU!@69qPD$T- zGj55L4l9ZnvnJ9N_a&5lmc#rjZ#ZIJGHflacTsh2StQ;8r7S<)bzTf}^v&>`4R%0z zde4yCnz!n0fD{uu4PbnVVb(H_j^Mi9xbrKfaDyV$*R!p~MWpv)4~uSNKs1I~W4ocm z<@#7t@lo-ss&fYY=y+R|(Ha7#JuvEpg_*#+YosB4J99bV&dWtVEUTf($Eu0@lR}33 z3cqgm-ZLKkv@!{JG@u|!dO6gM{*A+(A3v)7Z>KFE9{~je!9-DTaB6C#tBk&-78TfF zj1D(3y=HJ(s$16!DtN#CMVo;b4fyzn#1Hjzr7B?at=*aSHc_)o5s={%5a??T=y{=& zt`yZ&JSS2y5Agx(44xlq2IrU7dk3-EtZdhkb}KsPOj0EqP&AWp~5?YfHYsm=C>szx61u;1b`ptM=YoN#*a;==MI4=Us!W(9B$x|UV56poT zpur;i6f@kphy>_s8bwy)`+$CxpH}Ao1P>D_3mX+N_)=c1o(LVx<5#GQ+r5+LgW0~y zve>A&_6-F1^$@5UGa>B#-s+-?%FmO@()*`->o0)Ay-jc!vgj)=bqVZEUypWyIlbI6 z`(?tqcgE49+b8!36#70H^|MGCl^Un~AhQ|lfp20y?lKq*W-w=y_KR(m3OB-Hp?5{?kiJN<+B-*J!CqRX1;cgwuJYUU3Asd^c3@fa) zjPA-?vPlE421xMQkHb^Jp1pcJ82>?G!;7^TEI44|hVNZ+=z`9ui9R9BPShZM zSCWSh(ABJgnuHWCLZR{MdZ|sR`OC)I?#K63T}IbIEac>>2cyetK@-nl1MJaAkGB$0 z&N@`x>T@~Xg#b{BDrOZ3;uXO|_q#2M{N_O@K+~l-5>szcvPFb9BlrM0o@a_ zeqLTdacSu{-DCU9hw7146f$}2t1u$gSxKBe6Tsf94p}~u*p(97dm9J_+cs-Yr1+)@ z5Bh}T_zJPVuCRV1VAR|K2n~t|7Y~%e(ux!tI!{Gu!Mb9^OthM@Ed%9UK^Md+!pty> zO$(pb?or{faIW^i6#XYgBMAG0oMM(_lG{$mIF!7??Pb`3TSA%d#^=UYp#?m9(9Ao> z+ZE`!zbXe#ak2^oKvaM2IP1$qtva8f{a&Fj~iH7=oq7ArjdISJw6N24{ zW|K4#W&fPp1t%MzU80oh{t8~Ai0OJf7~uyt9-Ql?mg0PDFbH4wpD5f{cp_UmHolN;bIWEay1_C; z4CY4Ii6fj{83QSJGZ7$2f2n=j)WfYnhpbP;?1NXxyBB871vkzB!#)GP`l(yW#AOCe=#0`u$ZL$g}?{%ChjVU~ib!mt5{m&lWz5HJc``U6j&pqafg%<+%&=wpf*J_dpFPPqs7T3$8TbXVc;;ou7t~Lh1M;;kkDgIN*}gN>@x)( zGBcx3PZC&Vc6Tf+wgcYvbOI2?yx2WI!^?6bclb)uIQEF-Z-Bq#idc)$or5AveyM7Q zHy_gI`7V>RovqgF_)N<0CC4)(3WlTEKoa`XxoeW1?_N;-={uNL%)g-4y$T(G!$Enh z%vIv<-MnV`>k`I6CtZiA()Ka)Vk2`@GBeQqAVQ+DHms=K0dXrWp54Ej`6AKk3DXJL zME?RifUZfj@4kiz&pE3*uWL4gkfP6pp%h9k`EhJU3(_6c>9a)q=`t=TL`t=4c+J8C zcm`IKrJ}ed2=zJyWiwHTBvD3jWwW3Vqc`&gNN-Ggu;SQCFV+qkLmTyWN9|Dn8{?$CSdg0qc!q)8PL!A?7 zKU;y--+l<{R=DT3XAcsIpGYe}I zUEkY5+OvEL1~B$kLg~&ujzTXnf5AiwANfADQc|8HI{4bZ~yc2kI4p6ctzjG9b*Y`E@J1}T5>W$wZ;XK#@+|HtD3%TDt{HqDOC!<>2bEx$ ziuFGaU+FU}+B;MUA-;g}<|0_6*Y!_B=qy`|5ip>QSb@1RG5G=<8mQS|`r79vQ8OX(J}ysYT2VTSZBtacp!=T(N4 zn5P@n?1iKAl|WajBAx+jGJc;E z+dH>A17Bl7*b&3$u1rh#wYv9?g&T^a#Ev#fe~F(6UdXrjAt=^_4HXmp)k=S?1?JJ0 zo|f{Q00s2#y_yFE>byo1&iyz7F5~3R-;N(At6oK3CGKV^^|Zc9&L}BOem~q$-uuWI zJ4KL(g)Je;Yj7_3_tm7BiM+@Jd?|}r=4u3r+ErC`Bv!75$bo<`j)yoguyg3o>;peA z(EshxIdun7A*;3#fP;V4D?e_;&0x`?_tfjUOhmKixJ_&Q&}>U}y$vcJJ$XV%Z@S`4 z7@A-QlX&Azaz*wYIS#u;agUf_(i1P6WbUK=alJGltx6gHsO$`y9&;KvfnXJ)kmZpy z;^bmeO{8~7c4eG8RBe!ZpnH&l^!4|h8zFl&$WbJ+uVLS?v9m&^y-sDMdB4M23U#wm zS~LpAqbg4|9~1mxn8JAcL8AEd^y2VLi`?pO_u1-nH%Yws%3fm#`>9#BRA~#V9e5s{ z%VC-)jszp6K1#QjsIoOwzpt(UCQca+r~oataQw^;lL=K!QtguGU^q!rYZGBW8P9RP ziNMS9#M~=1absm6qkbcT@G1)^mtAc*T&s1v8JRE1>|%m1EkRiM3KW-i$F8`H{wIY3 zX$@_g^bP9cC*`E-0Vz+}+8V?VSmXx&G0{r*HgX!u@3g)#@IOCmuu<{o#gbML<&)%l z)x_VOSaL%7?!!V=MfoPJv8NZ!l$TNLkX#omOL)z~U_thj9rfS4s;qrI0RTCj4sv6@ z=P&r4JB4XwbQX2dR2Z;DRD-!*Dx74hKfa~;?RhFx`t;0O*IL6$v+64%U|ujsXIh?P zt@HY{z*&wF1LFQ*bZ8eC3-i2phO~sMc&f(>!s+uxUm?lZD(g2-jTzSS%_o{CnrcdjvSegV6hwTq*#Wa?HM2Cp23Q%QZVP@0xcNaNI zv*pA*nLT>GI9=b^exef+!#|n>^VnAmO^aeFLTM=N!U=vVeuU zb5ydLjpW$Hgqj|Das@TA05vHB3Ii;Tppo)a0y9#bltHBZ&RWoV!-EmmpYrl{~j-XCp$nO#}9 z#O81*D#&q>v&g*?&)XqFUgq|>Dy#U6C(ZTNCftzmtQWGYZ%F|j>eF_RaS_hAd{T@{ z#H!T>BV<_HD$e3?(~NlT`5Q%ZjxkS+pK)aVQkdD6TOB9~vNL%A_IlNc^06v!0+iCR zpWLOlufYO%wWadZ62FMqq+lO_bXH$^{%wHV8Yq8&6dC;zwO{O~*X3uKH87=|q)pfr z7RraBJ!ikQem@6`1d@|9)0*iz8glR3IbFzRTdc_vO93p<%dIm2F}p=UQ*~)YNM;AA z@p=%1EMA7IZ8GG=`8_C_o};A*;-!pQ13V%eJIJlz!91?Z8ZiZfM!&+qm+0w@b9n** z-D2XbOA<*%`qK{EpLv#Gx!pCsS?sg`Y0WR3-x>&_KhBLTT}RTZCGgDZNmj)_>l&kO z5`>K3C3-_JZu06U44;;V000^!Sa;-37q}#XW*f6<7w8p@oh%Jm6-15yf0||em;dq~ z1QpW5O8ySUz5oi8VGXrh9+;(^LP7G&W>Q9(!>i!ntyRuU9Cz<7vBx1{J#g!|->^w8d-S0=A(9#U#iF|CM^-{tx6bS8*@p zWiMcRk6u2XuJlySy{IkaduyT>H!`A^YVari^Sx=-P;K%9cFe1lDIIXe6I3i%h*S>w zI}rEZ%$Zr8s1(}_QpMSaB%!4t!AAU@r=k5O;OvEf*013oN0Q0oK?L%(gq z%U4{|a{(VTc=aX9?w^aSk=u_b0Y4J$irp12|JJ4*$1O5$aGm1g7Uc2YZZRGK+W^2> zha*7_QWVQvjCbb9888B+&9C*B@{dD>d(~vq0D5-t1Y5zuCaT~}`!i`o_1Y4N@g#*q zG!gGrUbXKp4(7|e7yYLrEhDv+=e$OFXJk6wS($}-dh6yV)gQ)Sokw?GyPsJ-k|Mzj zL`gEE0P5NOCpMq2tL1hB3G*qF5qn~?hrd!N1YLXn%NY;+KfyXhc4y4-+J3Gj)v81$8qr4Eb6_ReQ=m>)ei3*Yc3=$>oqo$ z-b``ci_<5xcZUvee!JM*gCp&2 z-YL>zKP*gO)P{;t&BEUr@}JD!W)uL`@K=DuAz8PxyM5^X7#ER{-aByu1_d$}ECsX{ zBJmu2?S!&<0>R|Fq;MQe_}kU|d%z_P9C~0%%v>NitCeX-*&zdofd2-0Z>lscymT3i zS(zJs)!*_ThxrTMDz{#EaICTcev!sJpz#I`ksj%d0ozr;sgRb+FBk9F7ZjTibW31d z*0?7?PFK59s%pAhOJa3#kK4^jHgbd(Tqy3BI@gFCPtrwqm43^ze`~-FZhQ1b^%>-6 zg9WzhE^0KXBIff3TTseE)=4|S#hHpJu=_6~J+HYo)eVVbj}u`B(| z&p4JP)rvnKfFI^=JclwF{ppdB52li)MnQfuG(3f0bqD+ixnX}5@3U5&l#qHmZnlEw zE2?;?_cM^<)d$>zf=SCzum>&iQRZqq!gAVyAV_#ktvCJU;2zpoU(7S#eci0qO1wHdZt zC>MB{v{SqWvd8Y!CyQGTTz1Ksae_4}lx#kG8m%2Q{uOpVeG6MDFp-$1+IhQ z3MCTd9b&pHJ(7vbV*_rWl#dE|xb2n*~W9)c3E zrQ$O@-&Ue}K6S)1$Q9`zhH!jA7dHBRHHoxem6*mP>0Bx#$eK^gmw4rm*5tp9M1Hx( zAf)7OURd9|Zy&v+TcHcH$4Nb=kcG@DQLHm6+iNF}PBUQiRw@t3B4<}J7>+`E?ga`8 zer|<@8g@#gRGkvIMRB)!h10vCCR?3urm5!E6fyma(M@o`Ro0x~ipB7Zw5Ct@~JJ(9jqtCET?QN$27y1LAJ2Wws%qZXX^3vOVsAr5H76^!pmEU!%PHOMD)CmbHPi2 z^JIn=?hO_x%Ld+hk^#EoPQ~srfi0%9u#n}%ydN{T;c9g9_?%gvkU1`!L_DTdEFZVo zyMfhIJ1}u2;F1;X6Bs4btA6?P3=h11fi7=nPBhNlOjs5@{*ij(H~}icxTO`NMxdyG znef`K55Vd*jut@kN~Y)hNanOaGtMDU6VJ$8Ss?tss zv;%6F3qsT_HpoBXqicF5J2SBuw4jsrn5wQwS>Q~mrf0ngCry{y zwZlaG9M$)U$W{XcI$jY)jSJg2YULw9Jg&Vg9*z&7*R}m(Fl7DaTDt#$-8W8~ zK-CuX?eUTEm2*;VIX%~+UJNBUup0IbWsob5XXrkC%EU%^heCtROQr^3S^!JXlfLiLIrDYqe3|I6K(C%H-J( zg(oSlVj_O-cI)*TWtu><8#)!Zgr20VmP0sd4e!`{@U4u$16eDTt=5uE+OBi_627C8 zc+jF-G@Qz>^4Z>PO&{ub^NmnQ+cC2V%ni2%n)qSZPY`Uxmc056in{P@ow|Y+n#`Zp zZ;z6GVP$4?(&v#q3nUSVVT(U%P#p!wX8&WYSwFb5=sUaV?>e<$R18FTm>85cs~$AN zPP;v{pq;+{7j5YId1;9rf7W@3Q{|DNRY=C>z&6C^H#lUhfp^-~ho^v}$#zc!=TZ86 zav;7&lUH57IrW$E3FS)yhF#rRrq4Aj*>s0{8%!=lQ)&)yl|?o?I<{lXJn%uNEe)o&I;F+G_J8+|hkbw7L!;iyj&DnLWJ1<;v4kb*|naKg>%h#+3o5{9d+w{@+b!`Gvw2<{>5?+JlbSmH6v*VsOXj3q?t9{`Z^|c6%fk`|?Unz7*@Y*&loEe^w zuY|f^dyY$$GrBg^K5)`W)nx)xRaX*fWB~l}lhEWgfH0@C@j4&&6-dOk=>ZBE^5tNC zYIx^`{8M<8$fQ^wSFaUmhmS98|g+1p5%Nd)137C%v;2KJc?6V(8$H7V>9^ z*?K6D|KqZ9drGs{{4=IDa*r|)+IQyZAwkcIKVar zwaGdj*pePM1q0u4>?ZI&=x|cAnoZfig|k${;0@rZl`xhv3kxUnu~1$WoJjcmXeocn zowS>a97-Ep82MORRenlCNnKZ>Pi*%q1)F(5FNoHrX=kPH8M~lih765FKT|!nIQ43F z%4sYowAsv_b5*bcBb^(A7zL?l${LcA0uzsPsU#-#E|fs~nK8EeJCi0D-SqLBgVlU> zf+3Ih3`Q$V?yg2EawJzNh-tLMK?Yxx7dlUPPC0h2{P=~{+~qa>AWKOi7RreGbUECS z)_{+^a$z{FE(Xqt+*>FjtK#LTVEJ41VHbUmD8BoI)e&Z^6JU^sGQl475gN6kApdAF zf5MiutA`SCmt-f+N<)5>pRKw>by?Zu`RmHu_}~^=swRF;s{Wf{} zN}S!Sqc~_lf!D@jTcq=$i>?kI0GL@W_D(;cG|9dedceS-C*~E&aWEjc8D z5h;lTQ&%B2mFh~?wZ@)))Y^EDr}7MaUw-Ib`*x9r9R~lD-DT zIXO;G+J_cs^vvz2@nxc^g2WuDhqa~?>OPsq?<*=OxS1q4pF?$d{n&Mi&e7qCX|bOw z6$B{{zm7ww?%P&&?i1@faQ7k$WxZEP*U?iwUPGR1MF2BCk+cy!3zU9mQ$4l2eszqk z*PmqXAegB;w~OV+<^2{(HOTVrA%gIHg=8S*BUt@j_BJ?Y5CWNIWL?J=jmM3~u-x09 zYE=u0Tbcu^o`2K;Wv0C&##%!s_nMXw@>`<`TE5Wxg)iep^W&EM7u2zm3TY^50H_YZ zY@!WB&-Xjb$dQYutX{CgQ)Bg__g$F@fUQbpEr{5|j0N}ulZ4K<*u+Ixaz;WD!t+6M z?9-W&yfM-!e6x)D2@r+YSQf{;vuOWx-aYGTy|SXATDpZ)5^^+?E}qH3+YL1S95|a( zsfS9v?F-jKVlOyQfiY*keOiiDSIE+YeqTPkZazz@j8}mYRo(P&M_VgLPjaJ9D67K1 z`gH6c0t&=Vw(w!NH0;T2eUiId@gp|o&049*sOIC2JU-rmfhoyE28O4wTs(cw<$czZ zbg!piDt5wAms%VCXYTvik@^hjhy2JQ4GPRX==hO!bxPzl*ITu{-V06(XDe+LNxW`- z*zss>!+d~A56~?Xj{2~YhhpD%j=`)fB#)jcza_lxUhK&-*Dkxhd%4Lkab*Q3atGQg zpOJH?&IVN`xO$q)9=-&L49xU8;Law-@4GV&%atGX+I?4FOH5maz<(L->Y&?f@_$n> z{!?`<28`#}F+HZavJpNF7W#)(%%889`lGj-B9dUF-s zSv|C;&Ei?B@HCszB2Vot)r9HXCA*IW1X?MY?S5pxU1tXS=)~wtXKq8dIJd1^g17o`e*v>9AHvHKER++28o0hSf ztig}g@@E9eQa;pp8?qyAmzEWG^jBqC2t!`Ycn{U{ezh5Os5FYtY`He5o^W|-Eu0DjJ7JT@KpA;Ch4ngI z6zB8?T`i%&PXw+p)qBSHm7Q{#r$ImEkN?G(%oj@HH z#Md7!<xxHwl@xFqm8ZP}8lg^zapBUStb z9$we89MEP`Yz?$+)Hyhym+I}<<^rWm9{TenqkL!@84HED&8FXHw8b&_%`q>uHg&g_ zXzAu{x>9y&l?MYP1K{VUX~L$ieA_n#A0B~ro3pO{-%YdAJKS4zrQu_ZK_82}aI~Mkql|zQW|!kc7N(XCDUuGzQ^Yyu?D3M?rs`uihqlc}wcI zV+Iznzdk&5N&olD+kX2tnqrC}Z=B;^ljNwE*dRk%C_TR7*zLwHf5asEkK_b9@oZ1u zMtToH@F|(ap(GQ!DaV!^EJ8jbLCi-mCvqS|u`6&Mn~ViHH*AqoBBb-~_gpIA6Dpb# zR>z(_EiXSOnF*ktfD3cI4R{hlJAH`u7ATgDELb-gwGJA9OA(FHN%%Xji1#h=B+Psw zvK;c?%dtL*jB2kxKYOTLrUXJdOm_8wv2c=hX#WpwLj~DZvY$N8? zED-9~SLywi0iS7d;o4~~@0{MfM`sg8jz`uQl?KDl)2GYv;M` zuxM&a|DY4tHdfJG)zX&`R&qvU5+9vutr?bo$LqStAs{+H-#Dq&fuIwT9h`Znx5oVQ ztZvv9&IdRUqrr+jE0?g8Gava>l3j0AkLJ_4Q{fghsn&jXU5kQj*|s91tNQjpQE{Ok zOBE*g+O;_}`aeAy*A%(y$^)f}f=>5F&@~5Gd5yvIkso>C;b7xRR)`Ti^_q0l5`2o7 zq>pSG2cXe1{%%39kp!w6(np-it4%~gS)v0OI9tkxhAeP z8c3wgl=n7~YX-IC-9ISK`K_?BHd7$JDDjDI7(d#Zn;r5Hy7R&9{~Xf<>$8qYfd~Qq zxM+d6;BFv+G?nQa{rTHjz5YXIQC?pAjrn<=U?a2=^$@x3LdRQ~;gN{}5Rc8SgZ=dv z5(zsu=O8EaTLxt@rrmf)(&)RsNiAg4#L&_z%Y8qoYjtLPBCO@2D#SMVkniX9vD|sf zND>v|D3^VM-9679+&Ar}y_au%CC_(DIy;dp`=wd+ZvlXS8OYncVk;>gqecL)OGMao zUdf9^PIa^h8CA*O)DvxVYs)vtfVoZOBJ{!dwHD;W$qWQ5F0uD`$U=1_%FueOn_%B~ z{eCCOMTHo6_~^E(LZd?BlU!9k8HyrYw+5>)}Y2vEJ1Je|CSx&tNtw4l{|ii^#5XTN~RZwH$Ckpt@JSnTLq zhXs~@)e62zc9g=D;*bT(;wYRCh7B9S08dR>ppOkJsksROeRCT|PaI=p4ogBOmpo*EbF>o?PWB-tCNh zom^gLbrJH!bN~9-ZHOrjoUeX}FOLq3gssTZm;c zgK$Y6M^Wuf5v+SZ&2WEvfsDZy);4y>s;-y0)~YerA=`-Ia-IK)L-k^J4of*Jx;JrtNe>~e0^Pspo&GU@@H=+HEPvx`XXRFX&qE+eqRr8d=;rTy9U<}lt# zH}Fbl4MTriXxNv?NyzP}dCh^rDTGgU0?_S}GX*AJu=E1W{XYsxX#6a*9JjtovH3}j zZi-D-n`Tx^ly`*FRkcsoGhfEi1-|NHJ>!?!VNIz{p!-49s{ZC}rck*QJzCqB`=X@w z%01OSsjEql0*&N0?OmVDm&V1GjW2FBM4>re=DRE5Lhj?z8@ssc=qoAM#1`~d`SOBy z7j+(D8kFrm0quj*D;Y$E>!U{FtxT>%@Yp8TtmBvkhVsf#>nNGQ^!0S_U+#hnJm>g# z+gv`(#9T%=R}8_ZM^tO)b@Fn=Vn)?`1^^tr(7QcIzBi>=Hii{bsY;)$oPa){I@;P-| z@aoAEQv)THL)$pg*@O|8)oe$7?MplnGG_;?S|cc0dSKfKjg8^#}M z6;GEc95Puih1)6VrM6ETOieX+)pa$tUUS*m34t}0R+gQR`L}}zgw>zilxkdkF%@N^ z0bH%NPJ(GIa)*u&tZ$JXlCp=ht8bv$mS^~zD1dIQ39N|(G85rQ?YG&rj*z~`MU=&7 zwtb9~*zz<~gx#!5G@$-z|5w8!a~3)li!PlVSFn$N6MODq2~uXoGA_4*=6h;!>R+lW z6d~r+=Z(#MY4?$LhDw;rYc`LurjLEp=hd6=3^S?;dPBHAlbF999)dI zwzk*hH>{Ca2WAFqaw?Ewu_ce(uz2K+C$Ud?%Tw~}hPl|hdqWg1L$oSB7&`!bxdj7@ z;}Ckl@?N?;?hMoCN7NqH%S;MPlSbS&$q7xVs94kD(c3Y;3Bc+@QVX@wen)=p@ssGN zK8+XDLC6iNeWOXO`n%ZU<-zZ;#kCyG#EDq5Fn%dJn7(L44o(+IkX^DY)xoRFkG$$T9B2b{`dyWI@&Lm9YL{l5o;bZsciJk9%XY0!qtImI-|Le_g zqe73KS{6>fT33HGru`UKwZwuhJ~S4eiGv*alj|ZwoFJiYDRuoB3_1)FBKq^>Dw0y- z;2Sjs*j%uvs83Db6QuynH}%`m%~NKFNn%Qf%F;_wubQrdqbYz^b`PKnTL)F6_y`AM zJN+Xoo<^ZiZujDG0J#J${te`v;8JB1xJIAUzx=LDIoTdAEUEqJ`47MsxwIL7#aG3j@I{FzYNH%n_F*cxwJ|Az%(#9hvVEy3Z`jak;o^~G2c9tWJZj#C_fp!Wc zkc(eDc$k<`fll+qwwzYn|GM;M%Oe*xcSmJ60foI~zhcItnU5O)FnRw+ch;SvL0#})zus@w+pyoZI|&s+xxZH0or7jlC$dBmWn-ZC`JN)jtC)Tu znl^ZXYEaMCN~OvM$P@jdhR*JKVZCFGCS#$*cGhkLd0J&9hBn_`HhiTsP3)s1|F8B7 zNIDe`3+;7DUJjvd%UQ|@-U-k+0nufcat`z%2vQBOK ziJaAl_vhvjxePz@qn>v5jDkrQE?}hX-NG{o>K*@Nu=BSuDe$dBpbv>!%xrI*((!4@ z#Cr1B8y{BvrO~q-Xi!9+)Te&&ne+R>GOVybg;|%NPeOsdV7P5bk161FIpj%NjLZg` z3;RC&wbYLIaN~)?^XtJiu1u}?o|HPB6^f+k)&*ifRSswfw-kQx=eU#+K9jT{gLCaBp_~6K&4F58PV2 ztdK;x$2Cn|XtK88g7EGbtj3p2X|Uwj3SqzMOg5#V6Aj2g`(t$l5YQP&kk*F!)KTV5 z`h7FRB^I?mRX<|3@^%mhWboW3DlmW#wzTb{(1>#J$W-!eXz8)d@=x-UAZU$POxWLg zAdpe7B&faR=#YH#1M#30i~U|e;v65A{$K$X*A{{%;~szEO?21QxDKnIQvcNp(pACH zJl=`*=Rsfqf3??eoDvA=D@jdoVtw>~9NPm{iSMefO$_PBv&rz}nhUdvz0zGG<_>Kg z>WNPoG-nF`_q#Fa2>}3Vq0$Ey%;8ReextW*Fbq?eA0ZM-lk7o%lDnp;@sH^LN^u&^ z!f&-OSjtSX==tuQZE^#;T6&s?Jn>4d9xWTI83=J-3P zw?Xk3@kh|Ve~xftE({L7aNA{MMpRU%XoCfEkfX6!#1&@eH$kg>PKf7R2=n;-5{qDy z)rW#K>}E2eb;R@UHxvBJ0V^rfO``%Ec0AFHGY5{?Sxiizu}l1Y7vK&{ZWc0j?>|t_ zpAlzG27X~?q0K=@f=M9k=Ae9)U@Zl=F*d!s(cRbBeTFK?jI%%T^r4sNlZz9>0M%%G zCs^Q}R8)C(Lp;aPmrnSISL~vh4w5I@d?C=9&9(^FT8_DQ8i)FYP!?y2<-1_KRme7e z!T`C2UvzJ8&d16wsbQ@zE@kTH7ld9WhyVP>AmE(Yd%_)(^CdudH@~otY20KShTF&O zPK-St>~AfY6hF8e?^fkHfgfiGZdD1VfUH{`Y`oA;w)SsS#N~tYE zlRae6jz;tJfpQhekJ=i#M@L%Qht}|vy#w6UxgHo6-{hZXk z!loDnL9iSb{X6D>lO46KJq6S^Y~La{dr(Etw;ENZUE`9xppTt{K5qSwi%L zGsC=`A06EvBGB_2I~eO5Xc#9R$&Y&AS_>3}28E$-9TL!M8ineRuFo>CWxgzQPb9|Q z)s$T8j3E(X^Hs2wtwe7>6Zy;P8rNdP9kSTO2P)F6j{UNK=|^xo=(kNz;^X-V0OUjf z&sJ6RD1gF=xF|L6bn|M|UvKkdmc_+cI0|JMS${2liPj0mGXTqKKWUT7T$b)9x{6ke8pACvkN!Yo{sJ(^tM{LRGGl2d{C4G63r128dwk_+yaO&o5h^YX=A+IIk%D5~-lCIo*56beUeorA*->R%_*-+*iz;%pg&FY6OiT^gR^WA-#Q^er!)4wqc z{PgMzJ3e;}e>A_86X4U(c8W@RKbiNz^4A(u!R=PNJpjN;*?eNBJq&Hfe_5O_Q;JZD zC#@1!oZ983TG5zg{@h2EK50}s+*+OO9iCQIk{qB2yOjF@aV4CqUlVe5Wb&2T`6iTN z`aeEJdIIAQti~%%Rfu8fP1_+ zIHPGei1RtxGGf>0QIesXJ{|v7!K&z%2vV1jr5MiLeZ3jyG85Y;>lWQ%&oUL$HYCFg z7nhj`e5t#-FhP&1-;QD4g5YSfxn>lUyGdv*?AJ_>{?lR>=_`EdKn%uuP-pqd51Oz+ zT&P6HCL|&A4g++*We!E)<1kfJ;XkhS0eoUZ+)Bre0N#Ma##%7|PL_SQ5ayS}j-all zJLA8LVt*}Te7~_T)h+}pu!|o{9CpTRH3+Re#OPbSvGgU{&{~EIkBm^%L>Ib2^uPi0 zWT?4h^pr%enX6q3@keat{#M)~f)4w#L0$9o`?0s4Rni9lWtdsJ*7hxYYYk!D>c1C? zg)=E%j?10><=Zsft$U0*gV^qZA^~wU1pdG8_)q^4CN55p3u@Kl#Pi)OtrA`mSX7<#qGm)Es}}#$wqdf zzudC8P47A@O}h_Ba$}v;&YZXdD^em*A#w+8a6^iZP+;c0EzN{;11qsCP8LF%u@57! zH%0mmW&9Q##XB^R)5Rrvt6)ndb%Ui_kTObVsm%s3g{+$?T*`(vmLO1}D{?mAbmGq~jc z+zJOhLO*Yg0AL~nt@m>ao@q`%5D#E5A!a{Hduz|-*vEe^byxP@$Z)foNCvE&ex&p< zrw&|?Ah>tQpJCJu?T)t3?E3wC!lT{^6t%`JQs5Sw52}W4fu)IhguU(-jm|2=KSrJZ z4BE^nG-_dg`2clWV^@4*9wF0>rhi>rdY}IBn(0-^amztozlt~o*y%NaM9)%3TwOtE zR>1$IZ4+6=N}dJ^?@p%=hgX&PnC7n~*GFo3;U0$Y`mK~ukK4^DMLUwdwSgvJrJ~C< zJ9^MT;S@Q%EMvPq@T)N3vZBy>`pnz4*>|Z<-b28qRpETC3YVpgSgj5)YG%s#x4<-U zpvuvap2qf($(ingJ@mn#-MzHuYpHNQQnFt`dDus^(UF$dPe#%N1I|Y7&8U_VS4v}Q zM4$rGfh^fxM~4pzck5I+l(lyF<5D4R##FEyWwM=b7E-3cDfOu_-_+8OnhAphJ^MR1 zC>x3fm%v&4(tI5)Oo)=Y$5Fh%^GbxclBK+~*WZOBg~BU(ntilz$~#vpd%~d?_9^bF)%|*N4(rFQ zKAAO={_aN$_a7o*ALxu(CQnbm<4`o0W3J5Y+yEoSb?giOS&PG9*bX^075ouM=VqTZ zmAJDj3B}8kkH5eBGcp4c^3K%=nR{wm=&HI4@22t@u|6#+$)yYzAGii`LH?EOMxkFjxG0dL!F)uy4lZ90Frt7vV%onAO1<)LarM zxO)UvHJ>wRH!*#st;Ii+7sgr1#hrui%ulu?Z~D>d{UhQX+%liU`QK!!0%E?F6%SK} zc0ZzX2*|S|)be$Hg73;5mVHZF3z&g&p~Lg~Uafl_xrm9lVY|hsm-rG)55Sj6XuIQ| zx|4%(ts*odGRmGZwO`dm*q;XiXI8OI=z+JvNZtbMce}G~C9_<3pMwbB(7wD&y{qWJ z8O3fuBEE*fCPXg+D1JUx{06(Gm<668AQcPgR;8ITE{F~Ok9De{y;000weka_lBUS=PC}MuIti_mS@y-_7N)m@+VMDkE+eI_AWutg2TgC$-G|A8&qzY1|cvt6ePO& z4DmnRKLQ6k6#yWYF#D5U>NGY^N41}TQPweS;Ie3ZS^3Be@VVa&7M^5%m|Mwh0BP}L zy*UYhCvB>sz+k8hKbq~$oFnt|X|S0e;?g7xkz9&cyw!g)Fz&^4!B+s=0+ zq?_yK{-NnhbU9mJm^#KdD0h;pBEKR<2RzD0A`XQ$xpwDfE1$C29X!=qk!7u6JX)AA zAtb(Z+8!n&R=Y0N%dS0WY9IIyfj;)m1(1Gk{-7bZTrA&c+?tRg^&~xaMZGPl*`TAYOE^U)8)R!l$ws?mX4T>)0!T*dB zV>rk*8Dh!_IiaqQj1{E2cu~Vi&Vx6$=yAel%x?y5Pdf_I2hv_p3>qE0B z6rAI3c@Uivp-~;`aK}B_hX!;h5gJSyv;8Rca=8&0)L}}a2AoE1HokOy5k7)gEWckr ztL_irR>I1d^Dg~F?=H&O%gQt%Bmi7MqrX1wlT|?34j74+ees_0mcwAJ;|`gUe~roq zrz6`9k=xLiFp!vjNqgFvKgF(O#^dJ!azD4HNBQX|Eq48Z|^ zI?&4aM)RAWbpLO#A!l#(9;BEg=`qdQ>Z802r&xq9mA_i#~?x9HuAG2RN99*xOse5YW zK7PKTlhm{@S3;Xh@xncwSSLt?l?_Rr8t9G2cU>}L*7<%X6DsJMYqXw0f0gM>Y*$S^uNO{0X~kmexYwQwT$`3caj!1t{StYzt?_*PbaqJf_SqHp`q^1VwI6hDWa{A*i+ zYP5Xl92gr3DIxfFx+ERKU}H0c?(&C_f-y)oS>o~)^k6Nmaz_LH@ou1+nEqP!Dmcp5 zLUt4^t)$Vhk&)JI&}2%{_ec%_Amp+MhE7*bIHibKGg`;>N!KY3vaoq)W#Aa1$qY2A zUb(3Y(%n#$6vl}Z_aF;FMn2EsC-}MkIvs>^A+7C!q0*;w zPe~xPQBR*r_!wB|VfK{s^h_SGQ9M-d+1W+J`jp!7AwBGwvYgkhYIQwgzuC-bG}zSf zJL=ksYYIUn7Ak`63T2?}aUb6noCsJAtI*1ICTATWey63dTa^0x#WJdm_GyQX*>|8NChxjo)@GisuI0)v)9>_^lsb`_DGMD06xH- z0i>V5);FMzF6HVqi`aBPiOn1+{dvP|4)77QFuk%RQ4;EFN*6y7?gd=JV6PMw*kwF~ z!Bf|FMb8jN6Ge8&66xb&H(t5q`wu0X$9tFZnS`1w?GJp@g+*X7Gv~fNP*wrQncf1i zv~hhzl^NFd>7(zuc-yqU>E?{)$_(%><(0gZI$~$_S2|o}Sy^{{Ao|MFzfozhsef9N z({~4P*4)}mJe{RIPR^kEqqY1QeO_`f{SK_4J6%zx@+M*Br4_zDGB6`XU?*IQxu)BX zd*SaUOxSTXtMLL-Ooqt4!O9AD_yc_<9&KP7a;q|m?1T@qT_z(EJwMC!G<7x@ z0KW?`ZUW{c+%I(_*bd;j9i0GwXYXZAc~t7;T&=sw@qU0JO)dc3DN|xjGS|~}GUy$& z7F88;o}R^7Y5IJCJT`N*s{yTj*+Y%8y>P<0BcLjN-P%Y8FAU0YDVEkXyA8 zrn-g}pZNLnS=P$X8DYOqcmHT9f6mjvSfZf-#9*$ASE#M23?1(Gq0#^wn90XroUV7) z7J`cohaRfh^$hJ#V-c^)k>CSW%?nH2CDnC!4$IK!H&IBDj0PLtq~$X#)NrCpy(7Ir z94wA+zJ1H3^bc5)Sy~VYjzs z<^5?khpQ&u?a{=KRPh)1Hd1TL`%-Q$$0sY!iw6rlnQp^#7OQ3k+*zYpk*T^NKVeLz zQceE3DUd94Q3>{TYi*}Gz$j`=k-lHp#_fnH82jp;FK6>6ynl#pX>xkDFl^coBV%`3 zJ{>9uVXU~k{ZTv@mX+t}=*KmXVAJ{cvDyw_*}sRH=K<;7S-;FB+( za|*r=U7zpl_tgzQ!_W#4W4?-eU8$8JS!C4DV&~05{J*H3HNvDwP#5QMbGU(`YXg~3 z{(P(3wei}R1D@}&;jmG@qruz^CaGQ;tb|o4X?v=VHycbc=Ls^YHxheVU)f*zk^^yS z=n^&PD7a2KhlffGjcWuK9!eh{!P8+kNq0yig8|ltE`mQ%OaOPj5gL!Hqf={FK*<(t z0wy`Luoq83INkrvX*9qibc&_gaMSP|J5|lh-cs9VF3^#-zR~U5<(?>)qATUnt(B%| zi{PqT?glE?v11a85#6w#jVSQr0VYUo>A2Tza$6p+VDb}gXNZ>V2d(J+$I1iMLd`AB3lZ?U_{+))l-(JdWfxu-vH zkp!BB)^yuvN+%U$G@wq6Bw7;9^%Qt$k!&omJ))rWpclwR5zl#j+QGT&)JK`? zby67;L-`{favJcEUFKBlwGETa-+)MHIL{5TCTXXZ!~Ba%*r}HS5ke_1*Fh=CYY|-; zr3!CUY$Oj&QE%rs;i;4@S&CC2h|o|Z`g6^xpsD$U0FBC5huX}>7JP2lX36_jr;*ir z#N|?s>h6E%^>`%F8-w*PFU>@JtA23H(~Fz6Ht@Y|(}z>Np8id=%RyvBr^Ug(`Gwse z_DuteR}h?eTNrn_Jb|_DEu%2%L0)413F1S^cCphb*FtU?A*TtCuc{>N3|Fb1fi%fQ-=!m zlL2q!UkX!^7vX9`=}jD9N;w1SGua!-a8Fm@w9yyYL#jDDzs3sGkree>K}T(-Efm0Z z7uOd#d=DLs6Qu+;P@dCG<>yW^}aFD-Ix?=hUtwIudf4q2*%-N0WUGW15cG9rmc11xv7f zOIb2OWDJ9xVs^C`|E8NsBi~0F5_6E`9Y-0jb}-qTM_%3PFo5psb(?COn$(-_V>nrZFUMXAgKo2WvH z3ae71#f>uXaX9OpSJ4a~K6e699oUXpFK&cl5HotCWUwaQYPXA`BnK9c2>aLODF6c; z*MZn)7ax5A;NEIkgwDhW>?EToKpsSm)m4@3H-!poaEHVm>%@jVEQTmDh_+> zISBGXm@dO)sAbF?ZP2&Vm&Y^U8z>&XWj-fkGdZ#Yu|Wb={SV}?l8t|plu;^JIdG{B zeQGF4dLyN0)Yqf2g2f_urI8RNm~y;~D%ASlxu8Q=%RmTsGsil(X5sd7v%lV#elHlU z`?GI7Mj@g&A1=h^w>**87FSI*p8c;0(OElBy;iupE8WGDWEsrG!eb;n$bGz-*eCCH z(+Tu#4=CQ(sCk|yArY_$iyBzs-*V}GU_Fa>A`Q5|-?4=TE=!VgvrQWPNv_aAM1 zjZq{f)~@|dp{Zxt=HS1g>J}i4aRKX*^z*cwtpufqTp2U3Vs96?=4cp6E+a3?OxIYO z?8P7keIQS1$JE~@n45n$SqU-W2q}>Eiy}he3R8XTjO~TUZmVti@W8ko2JSB!M!%hn zd!d(_v(i(-pUls#?rqJvqHoq#W`!rzyx6U=ei*)Efol?d+TlKk#5J*dLRM+Ea^1j` zFx6B1;2-%p@fw;>qDiMVuwz>{L!=*9+y4t}_Cs|fyavSbGvpN%p53%^?bhSQVV8K* zo1`CN@h7_P^9%H+)Ad#e0rlJDj&1E85IT?H>@Qc$IWmut&qSbKm*3J8o`v=d*Y^q+n;7 z>-##E7dN){%07`00xmWd7I&ZUxHU4Di9R^0(X6k~)+h|)J{yftCF@$0bg%cdj*Np6 zOPfTFq1oYlf%?{)$mEI>-MB}f-Cr!S>3XGywEIfV_91`&8#1qgl2&;v=eI7sMOweB zv=79RM=SdaS%`uc5J;;(*l2^6; zT+r4V?`NoPp{Hi7%1@0AJ=+h>6)^>lxifLj612jj!rjW0&d;rERNGfoP}TcDFD+%T zi(|kT-ML?vuT#V2ZOlkg&1n1nRO4EaPeSTr)&!vdpxWHhI``)61ptHHC{+#?El4AC zd$r$S(lEC^vHE}5JIjDLlWgzPxVyW%yK8W_;O=h0-3b=l-2w!+1PSiJ-7UDg6W;Y5 zy)(NvlbOBm{ysGQq3YDBe|PiLQ%{|9nq#ETQ}JhWvXVND1Q;-4OV>Me{7<|>b9Y7c z2|(iTO5CNhkTg8B6@{r-zrXSF8by+9AuNdjkWS&hBRhds(;bJgn9|i4;aDF2;}nmvrvx1{RTgxv}> za}ONib9eanXI7Z!*#9UB608c9y9&b;7$<0K;gQ?@f`{buNo#`O3q_wQ%rZhPhtM7f zpIv!?TFMU-`28;d(Ma7wL%w}Sdp zR#`T40S|t527o6P;B)mXdSe9FpH`AF1uWw`h%aK^I5t}I<^>>L=(eM&;nNwpM3*m? zIqAi9p#s5QD?^_%vH>olk(>OC3@T{q6c9UEzPFlpd_|!-Sdg_$Bc-UW&WZ8EZI@Uo zHf?tp?uCS*>KE5XLq4#bVH&i@C+m^XZgwv3cP~(Mt9KSBs>(N^(2aWp`(&o&ziK^d zyEa%khO=;p#%;Qgbx?vs`zxb4KZW}OGqpq@v+{{z_I^U`RyS)Wukx0W?T)6}hW5Ul z(I*DOR|1rKtK(C%nAT<6?9M}QsQs3p?E!kUctGt(PPUYBU(OX3hsF8NdxbX7u)b(eaF2(s7MD3 zuNZ(UVlt)24_q$+DW&W`!&3K-h)u9jM*pdO7kmom6!Xq8qP`#*4$oyeO=}0S!}&}8 z@Kd9T?!IatX>uq?gbQF`0x8eE{Exr@5-2f9Nk){fA}j(BE@&h28?92z8peoX^JAf? zOK-L@LmE2mW>N!9s)#TAanC(NchuqIM>qT3AG>;nCkAfl?UIV#<+8*E|$5o}uSyV7A-VMN1{=htdjkHv&pV;YwjcRkV2)3v^(H;j zN8ZfY|Nf_DNBFQR;h-ES^11uK0@Zivcr8sDRB*}}I-5k-hUyK=Y_y>W3MdHJ)iv4j zg%eRxJ`BzaKzEM>qn(4~k8GvlC@66K#27!rc1xLXi-l4UM5S=c$3QTHYTy9!8a}`k z6pMSH8WzC1gT!5g-Mdfs69@qf6)`D3+A}z(Q~d@OhaCA)v?zyt)$X&H5ao$JE`tJ8X|349)O}jcmEz zzldSJr1$4*a>m*Iz`M6)-z}V>3}MS9lCUZ>^V7Z;`s?V~rv3R{%Psv+H~Ai06|Vpi zQ>kuPZAu?j2K9R&qHvnclvG{JUcJUbNpWD6Xv!YXkP|64^Ju^S(SE{)Y3G$HH?6VFn3Zv3w?_d3?**^V&ht^yd zv#ZBHpK!DNA4v~(1b>CDf5Bx~jrOXV)7yeRZI3-*$C&q}u5Dbw1$?H9Kor9GObi(? zRb5DG|GnjwjI%W-5w_k(LcawL3tuC+909fnfS>>t0D!eh$ZzuJKG=OW%q_P6O;9-r{yi92axP!J0*tDYfr{Sn3-ZZtBd(I?h&~F+Vj7SGB0hT;*h!Z z<*0izZ8kxERy;93AEV3@v@c$vmTtf?@Ym|`)u2l9lgFxGJ6ct$IAF-5UFpk@EoxRV zUQ&Ugsna(i=xjRE2bt~LknCaeicKo$1bua^Ts(C&=ep)gO6&J*(69{z+&J|tDongu z7o=cJ27Z1;X&T|L|IY#ZDpGTdi?oAw5pcS^&}Rg_fng`K$e8o)J@o8fR_j+0UqKRM)iu`k31b zGj9_jrSTuXdk-??OHZJ>Kw_4;4-a0B@3~)61o5g9M~)7Bs%08Y#Vgu@;dFNVkl3+h zSt@k$0G^2C<(}z3dxKADe3@Q4XEo(S1pNesVQyh|DynkVCpiDwCXs&!R&ziyQkKwG9XqmACWbO^4vz6f? zC5Q@9;o878Z|ZKv>$gEEPE6Qvy*b zs(dHG0#HM9ar!En>Ahcd>G&%EL3kl4_3$>b1|wtR4QMbU1EFXw&nU8pqb}WMoWOdd zDhJST&AZQVtjuK8?B35APhe-+1Vx1V`#h~`A7P9-5$%)8Eh*+BF88ytMPab4K%mN;vxkRNPCeG^2`J}8+5&Al&VW0^JNq7g7CI_7i^ zaS%jk2s5Oh0a_bw%1!B-o*k+4j~`Q-;xN%>>SQXib)GgI6%JZKQcoN8V_a!?R~{od z#^lW^pNrh0-#OtU#a}NC7gH8`&uUN)ndxt<-i?=rz{`5Bk)n@=s{bP&j5w|*KR%GT zBrJ(N!f@ftORZ5|eKu6HHFiL2LqE%GHtunu%p5No0D-Fbvq97#}%JK9^lWQ(VMO!h(Zfb<<^Xg0C5@ssRslq5>;PrTJ}NmQZ-^mIwW8*@Mt&Bt zsKIQ+PzDk!U`&&3PY68Ill@TdZD8=rd@A$NsJ z!G{HDMJ->28=6X_w-V0_41)XP%7ovDJhf=Vm7slGEk{{An9u#GD);`v3>W>wi_43> z@0!c!(L^;=sF84FlWw#J(Ws{dqfq9i!C1KI$q5xG$GzAC6qFbPkiLxKd>Uq|as?to z-rnaP(CBM+=tR)RSg&eEcArqnogeUE?9BP;@o{?!IxEZlq%hDa1$9keLdB6jRBTWL zwLS1Byl-nPltWk@KnsA+;_}SD2B0rSCH^S!XjSc{7vP?pWgb~mtMb@)tz%pMCfIRT z>mbwaNqOSy+&KOl)MaT_aijSoyq;WmXF9GATB@*D5+uWliV1mjy?2L>&mlrhNJPn} zRYTNh0V;#(;1t-QOhCe@t7Yg(HwM*8h^c#IFDP>La9V$CVQ~lmV7$2vKqxZ5k02fKOM+++feI%WiL}unv-~z?NB_%z z`7gg2TfJqG-cG;V?!Wv?z%`|Zx|_?ee)UHg|6d~j@gc(B%h^eZ{N&RwxBf4`5_ag0 zq*sye7barpKF7xV-roElA(Zp6J<2Ds9mlz*M0rXygz4YRqxT~c{*NSd{I{r*-HwoC z74-p%W2xV76-<6R#bo-+y?zDG)>eM6oYKFFt^YI%qx@L%xbNl;6`zLQ1rbTDpg{wn za{jL`T?oQ7deu*C63T)?T7_T3&;Jx`NsrEPEt_DFp^sA8_7^XeuI7e2@;M~(6FFfp zSpOHf0&7@$H1SVn(`y@%z0SDAF`qCEUB-W+UAnIX>{ zSluXeg~7rr*g}q#L+c}Dd$x}TOh)Q?8Pilf9nrsS8cAT%0BNZsME!++BBa;Gm#wi4 zFx6Lq6+eg~94qsIPL&}#?E%IlLA*U!Fa2q2|54mFC{1$Js**C9S06!7Jar}E5O28Qa zFqkIr;J)jCJCGFL{Q2Z!?}$w0Yt8O=17C-(M;;0l5@J z$J!x3?_B{}q~m+$7h9Z>s?2T!F(Y6aQkv#~X?S(YN#%aK8GjSV7=YXkO(FK6_$(?a zVpJJuJg*$r2`M?mZPSNQ7;sykZ>Up#{px7Z5xdb*_=@p`oKx*O6pN&1-4&I2L@bX} z(Ltzv+??qwk=2$;2ZCdUy($I#&68l>10Oe|0L_w@C`^kJLMTYGjD$&4;|@hUPSPJK zj{Dz$jc&_&Nec$WVnZ>#!Q-wr?Cph2(%aNTcc+k&_UZn5=^^>uUmcfL9FLn$0Qq=? zO@xoj%&p{F#nUc1E~-JA>T7M(6_$hCW;jV*29S!|WE0a?U}Y9Fs44rnyFK(;8hpM; zmwd$RK9Un3?}bsyoYb-@_HQ}s-yUMZd9@Gx;5=RS=h~j)OBN@UP3tfSTYWJe)*)H# z>o>zWuXuj-u0Q?BYs9kmOJE$zB4`^Q%NKPR?z_UE$VS0x^br|WK09b3r<{sK%#ytt z(2Xb#4|A4x4tx{otBp98X3BZn=0(`=EQAgLfv1>w5k`6Vbr#LP6HjM{H6+QHU;>LN z>SK_j3U$!M{{Ehh=AxL#GYbQU;%25%6%7NwR0h`kOM$1WQ-GfaPOS#3_JqzJ)3bdW z6ENM#*d_?ZFlcTK_ppNQ{+crCm{Rr-hCv>JPx7O}cRt;6YD?`t|1iKSuyaum z_7={H2d#`9zR(Fa@7RXiU@dMbJ`y0XQ)GIct9be;FZ}c7$~3ZHo>@QL{i55R5u<}b zErS$O{Iw@q>}G)M8;|@G%%anB7V?TY#9 zicd}NifYR<{2asLyP$_sG_oh#sMk>xf16yu9%{?N)f zHEtq&hAAsxj4D~BC9Kh(&Dp{ZY?k^Jhsfq{kbcUF^|2k{ZVa5`PWcFxsozVo7OCqm zPU^Zg=!70MpY^G`DAwAv#e-BT2cl5zmKFuTg(sbFjXN%`yOO!KbGvUH<~g{rPA+am zN0! zShQ-;ma7Io5v?RTh76mpnltttNCST&;{eh*(N)~9gM-7urKs0L}_ z#&pL)R{lHDy6bZasqj~77(VDbF769;tm+h#qN9Z~uBnI4bcO4;NqnDO$!_s0WxG(Z z@0VsTX`PNSu+i3|{2ZbSgVSQn$$IQfJ0pUie;;-J71VHU3Hkn4xC+VP$?+nW!ZpFo!_8Q9g4z0@cJNkMpBwt@?jxc5^fLkU z0;12~3=Z)H**R$g$wVQH)TO$rnRhanN4%2R_a*4-xUjvI7oDLTZeWwXd7p`jWNQE) z>MQZwRXt-WrS}dH*jua6EqYw`0is%I44sM!FD4@PT}`_g^N4H#LC>H# z3wrxEJ~a0)6CWV{*pOeaDJIJUR;?vsnzBm`oDCjG35}#O6@wpa+B|k6J>3oWnxsq# zx?4H_V~QsqWCf3JrzX9OZE}7{#1OyJit`Q^l4@z=Doe|UuCY57vk-edOL+*V`(zjI zkYE$PCNLKMqg-&Shuq`^gIj&`4dt5=NwIzd+`j$LaQh8TpTL4OTqlA{M1JF<5VH8= z(svi`F!pn3eDdlqO`=u=bMDEMol57<$8|=5Fxiq+jKNnhek%Wl|VKHH0*`A18itbs}`h#NS~41}SI$ubdDs)hMn z%C4@Fwd&npJvE6~T{OnCB5Q9B)MYJUli=N5!n5Ga=T}Vkk1o{KeVT*2aapByhdKmv zXLz=-T4Ye!gxxoTe9z9fPfD~Cn5c&@%(<# z9H>lNl$JdTvx=Oyq-#%Xxdq0HZ00p{GqMovX4ne7SwDBPlIpt$VXsQuO&l#A{(9Rq z(vXG7O4`-(Ait#4^3DY?CXI+)zIZQJRXosx&5>+4@2G8uB+RwpAt8m5cu^JV+H=z* zIYSs}bxqsAB9~o}47%H)9t3+N3Aqm>zq-IRDW0diL9qe%NLVM`6bv7<_B+#oUzoWA zA(pX>Dg!k;wP{}LNt3~w4j^5%S!Hskwr6)N*zvZ=6R(wBg+00@A;zvHv`T4z@vhbb zIt*bZID3lEw?-kdi5rPp?%n;%+*N2CR5C0Hol%;>0Qfw_U0(+=Jah+QQ;4c)8P0>> zTfd(nK!qM%{u2%Jw9ITwX8Yu|<_K&0%EkF+YdCV?uF6fhuYL+_ouIejs^Dm1=8gq? zzS5IUVkAvs-OS*HA1xh%vWB9vNqNphy1g)gp!PhqQ5ZH)gC@}V+O@3utI)I|yf|c| zhNbp2w&|CHykqtcE?2w3@v!OOjR_wFy%9K&jL!r~J{KtvP6RyNba(Jcz3>YTqf! zLS>Xs6*GZvwQ+lj^1FrHzpR;Sdyf-_fN5vKzD9N$Kby+56R@i#FL@%Jdwe!Q2S;L( zkEZwTJG?l2U=N-%xhmkRm?>g*jp=<1uqe`IWIyiK{&8g2?~IxP2LRwWWkN;&vg-OE zKS&dg%dr>QevsNL;`N6)xCMib#a-(1{O$v?GV%O{_nHsON3h^m%M}c(h&Li6hXdaY!0j*;~Iw1ID7c|;o;$MqrdIrr+ZQ%uG2∈{MO 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≥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 z z=#i2U;Y~YCBuR_-w_VXhz!#wV*L~ckuq!H#evb<^UE$z6r_%U@_%;x%SMaLa^p#43 zS)dj}U{1bMy?cIVaso&r>t`0kuAyPCnh^r$FYC}tYXtTS_GZ^%=>!8_!P1MX2?3gS zzrSN~nhEX2aCY4s2sshVM!v!TaWv*=ODo}M7-Rjx2c@$>QosqKu%{lT+n$T5*BFZ+ z70AM5zE{n=Y@N3Z04qg3W8igEN;_T5r*{38duKchBZLd@hRN0tVUg**YZ8Hpe|@JVX1zkB$h5#&}Z>7dksZl9D>1d&+y^q`8nH zE^RDzCwf<55N`KG zR7ncJ+q#e$A(VWCA{Kx~?!l2b?ZF0Kg{hbn^zHZdf5l@rWCuS;&#phmV8U6faD>c& z3nDr>MzML;6}ao+!{JQt%u0+)<>JOdf++EhJ{TNpHLbvMM8?KOdPKgR0LsXx zWEFmnpfgHDVd9yAJh5fja$xPVQhWD^RST^1I=LlS)dt}uD#{z>28vLqu721EAg#2z zjvN~~N-|cbJ)?rX-7)alaq5Jjx&AQU^askHmQ^x-;T}_HK40`X7#6Kl$;S+b)%n2@ zJ`8Cv%S8t55SH1kPw3g4`FE4`!-v7|Fi#7g+xMOx=0B&py?>}TzRGhj4nK4}7m=kQ zg&IhZgPbYLD(elD23wg~M|th^5u-+C5!Ci?*+*fd(TbRx@2aSnq--OQ#2n+WUCN8C zLNRfcCHlU0bvQi0r{Wa{y(r9*1Zbx!x>?EzPCY-3^lMBZJiLQ?9O@cfdL~j)Ql;V~ zxonUxx~9n>o9<{hjnp-h2995VG5kzv9jyG3KJr_#1Xnfxieg}1jVE?K{mHS=sBqiX zO0qWO5|!VF-n!hJPV}E`7pIAN=`754TwKlPBHjJyRADf~+-E!}xaGqlp%U~N;%WB) zUJ2?Nw!KQfb%YKyoXQ zkAjF03k4Ylk({3cs5e)Shf_v7Anj98Ud8Awm3d4?_Mv$8CGdR_g86<&<|jB>jH8bM z8b&(CexE?tbF4ArVr$mZ4qdB5c~F>h=7!Re)3`DC6%3VC{ewl}Pe;o>LP0D)?bqIM z1~1A(!r0R>N=id3C8svcUcREh)Uh_{;2k}>pv)NMba$JbnQa6FAE<4yL2qQ6GQe}W z^_*O8Qb;;_8T_QMRxEGWejj_m2?f2bM0NU>obuqxtc*pojp&p2nRC*_kPuW(Bg*vR z3S@UYL%+GKc0?~E;bXY(Mei1y;`JG5u^DLy&YMe;TvWsiLNiXpT)o&fqF`gVzqX_l zb*y}OMxy6al&1%u2sSn{bBzfwGd8qqSjE!`t_9__sAwuzp3+;R4UV>( zT|z{J_fI!$HZ%va5NR;z%M+e?B32dfJibmNDc|}o6DQ`HKZlKgn|J?gUDiyN?i*8xZKeKq(f#K zdL64Uwg9T;I+`={s{%EJ&UUWuvDB`!>nBI|5N z45{r5qfNN#VQ*U9G9Hht6xOf z8nsZi0Fgj@Y#MIZ5jU$*@MI!o@4#+YPhX*?xdtS6-&4_X;*)S$#>EB+U=eUQb$tCc z6UIxx>eogScFPwONtViR)E;6ejRFpVD&{pn>)d}yDk`7}AbBDjU9hyeXOyJ6PSwDs ztC5@}VxYw_FYczS&3Z&TYCH)D>0|k9NZFI*CdrJ4Jm>)Tqx|^cSFUMy^Ry3GjHjiOyAv!=*Uc9ZG1IH{SrF8vkkPI zW2;>XCd2}LZ~*53Jh|Yku#dsoM`ZMyD4XRwIchzOzW|aZb#4-FIev{PGoC}x7*YxF zx-qcfh+G5Z?oS_u&|70SQIqA@a10Bxq99`P8pqMnBWhwgg|r+(iP)i&hV|QbBSS>y zlo#NlCYFf#ZZU)+tK|gf<)OVaxY*JP-{xjyJ8SXNGF#A_rz2t@H?wolGk_e|3)XtHXK4 zC8UW{+V}0R9BEC~m8w?eRi?~?c!-`-A1ReMmm(2|in8=s_ZGe|Cjbq9+&G(X|2D-R z7%_+LvhDPXSo_rCJpUIDey7i$Tslx!Kq7>%;^L&6KXmO1&-rqp5*zlBnkwSnO2iIe zKI1yCN0WONbvF)9ZM55QN_jM2sU#<`l_4~?QHCBV$4zz0ggi&PyH*0Ui>jLgazRY$ zuAr3NO#nkHI{?4&o2U=>l$tu1<<>@_TPCAd*C#t5P%uIDSDNe*j59&p!08hUH4W|H^Mj+_PbTPqaKcNG_U*Z#=B? z9_N4x?09+Q0Ik=dAuWe%qSL$g2zH5`lPGZp6l0PRvrW1GIQLnK;jFv!QX=>N5dUw4 zUH|2=5bT8avBu6T;xrO1@Lgo@jE%&IRC%AtUMug+gTF4=m{7D@nqDC z5d=}qu?LNdbwfP!y=ot00|*`;lShbu0kaCpHey-MIuvS-_b; z2BlS0!v_%in7m`Sbs)!&R`5VCr4j=y z5j7pV2(Zcp_cip}J}Z`yd`Q;Cp2!kdQnW}vB7aUJ- zPofaeFR*4CbfHlN`WH@+n{W8eKn^`9IG|6I22KFgzuy71AQ-ZfiP_rQs=Bg!=>ej? zu9Vs^U&LA_S7k{IhAM0Rt9txq4ElO9gylQ&upi{V>2&E_SGj3v7-!zr?&+SveY$9e zfA5xE+=09eWjF^(OMwpbN@B6bm$`jDYWd{rf7=&^Yh|D^GqDb#(TQp|dA(W_!TQ+( z`?~%|j`D519R!T0GF^>iM2!H7%$| z_0(pYJYk&)9{(s#najL%V!SyTuU`wEAb41Pj8E^HLajSo>SZ{Eciw!RBuNkh9OiO$ zI-431XQjl6mt^qA58-+gZu0}i6j$Y&cP67ijK|o9)?Yakf?Jnn=I6mxa=t)(%L=tm zZ~sET&dEuE39+<%*EwgHLBi+`}Ff8}GVS7BNEw-k|de~tABX*t&hxPY%bmfDKcXJyX3$AR#% zY^VSbR5ElNBHa=+{eY~Yr4&AJ5Y>4e8^?+VlO56bFjZ2(hvS(-*D2O4kmNByrk3(> zVDcl1&2MP;hc+%YA#(7f9z1sl0?RE|dBa zXa)<_QI2z>AY*2lf(k|n?H7Nbo<9M1h;7X*G(ne(h*gkNvtVqYI@nAE_u@l)w&p{t z1v3gf9^pGsRN4F+nK3d~Z_b&}zzPO`MSeboI1mxR*COfvkG;2ysw>OZzd5)&1PvZs zf=h6BcXxMp3-0a`+&#Dl_u%dj+?@dby7zYXEq$xr?y5@l9sTeTbO`I7>P#T+zc?VpZCO+k`r+>oS;R{#`Op5FA^G$OegaV+G>LC)D4368!fDrN4aBBw-R-!r7b??qDRxRp@?q zw`ZxMAk={$c_BZ@!c z$tgVte4X1FY+D=DK`-2vR_YuyUm}$K$MG}H7!;@|&xe10d`tN0@&J1^UK%|iX#IYPjTK|ddU(?|DldO^uqdon9qjqxQ*hXuqvgTsLLN$x znPN+B1}RUZRP0VaWHX$QUeK&8FoXBPfHqe#u!(-qV1m5mI@PUprxC-0b>x?YDA9o50v|^SU$(gFmg21tl)+nA zr8(%a>{q@|zDuQuUI!*2b2VT`|7ir8SKm$6%U=e}ZnFp{V;GNjQ~+uEn|{XFlNjuh z|8a`@5C7rcoE&!%Y=ocxz55UUJeAtaD9_Kw2RGk3k^fWNW-Fk)JVR4a!X5q}akcwP zuooi$vHQZ{ksYsw{`p&U&G^5FE%t&JBiL7R|1)V<6R?oSijChXut(zW6zJa(bBty) zyp8E+<;@7@xM0yGcDwPF-zBiRnx3Qohrik;;Xelw#4m-y`<20=bCzsq7tt-|Q&i5S zk6-@PutF+Ij-Ag;DxP79mFvGpp8qbSYlAzV?)Kqa8GB?sxC5(K34MV1o zI{zl8_@iB`sb z!Y5#n`H`8Myo4&=Oz%uX+Su$=l^G+<{{>HDrmH-q^E`VihxCTBa3|NunkfpG$5<)s zNr$;z?-E@~+K`BUvdxPW%|saM?jEK_Y)ni{Gq}zqr-=gEQPsl1#P#FfuX!uN3IMz{O3Q(zY6@IrF;)1QIR>-^)-<)w0ucm-h09oIK}kU==5Mo zLnXl#Vxqq}m@QB;?ecejfpH8PQTS;wnoQrq5*cM@D@)LddykPNudd9M{t^|@9ve+AZ=Ug|eT+c!A!SJq^Ys9B|n*u`dJcymA8y0E(#f;(L{ ze8ZBA6Ik6=TU1>8^7Zj#eP(v&idD~8mq$~S2pR$x`fj}?T2n~ICMeR|zYIeE;nzp| zE8`=$?t-?p4R1XPiN9O$4h|qvBbZpx*jimx($Wyh*vm5)ApV=zt22#n{D~oGB!kLU z?)a1UnL`gjcE<6xM19>h-t5YkwyR-UV0JLVm5(RZQCO)mSy*)^t3=Y|B&FP$NPHec~ zxo>_*y<&UBX=ro_P5Z5oL8ENP7evz;08B7R`A} zWdP*!jD|2hU z@i{pSy;Na$d*aoq6Z;WESoyk338X6fVSO7~8Go(#V` zD>G3DRVET*C9*JiPnc(3kaJx%J%<;Eqg5%I@bg(k9nbQi)mbdXKW%LI-$aomz9drR zaeQek9og%*rP-R=*HrL{bFIYqI)#oH8V=4X$9YG2@DA@w%kq;EHkMj1rhL+~ZqCY1 zx4>KQ`wdJX)7X9xRAMT;Id_zHV-~bWBrf+J90euQsMD-JyIJz@M7W)8;QP!#**7=c zISHRR$7LhSBH0hdCbkLLEW;a{vZZE>Z};KUYDcS>ro;(<+_wCG&_Ce|xDRCnKAzmZ zry<@gqHYhl0pW3Up3)ITdb1{`bdmIx9>?6cW6tlTL0`VcvlAyDLO2uNq_SCluElv6x8RvZUXXR)2Q^ugfQZJR_Lf>rmkOWAoAdX1EAc0D-Rz*i!LP$BZ0sMdgs^bR z7&3cBLI(o$ipRF)5Jx(wIu65PRGVBdXcnXy)%k1Z$kxwA**BlXFpn7(@jY5WS~8E=}J3UaNNoxqT}AJD8@@+C8sUZYxJORol1)YzQiFff^VA0a=+M?vIg zOi8DTxqAZZ6%MbKl?yT!l+>;pcR7cOzP%D;lP`lCFC^;WKa3I;#|huZ=+pA%9!szA zR3oIjuUT?RnLSyT8{Gnx7+O&9ffRhdUP*a$SU)=eM!%4m%+Ildb3WjO8vkphWWB#z z{RX3X*&}Dk1`e|r;zG8ynp-2ZVSIBsM;B99;)thW&(CN7SArd4;|$`zS~S%pv+tk3 zkfROCVjh2a!4YVYZQrP8Pr#e3Dq3cUys*7+yc4t3)iozQlr~7fg`+l0iJquyE3*K0aBIn$=bw5p}(@ zH9Tg3U%2RoI|{%O2iG664IQahY}!^_C9LI|UNz)^)~a_Gg(+u%=3;G$oa!VBqy!q zjyX`Z9&G02{ct#IJCi|Jzp{2r`#$hl?-UHKh`Ff?|xIp`f0872X}fE@H-b+Il+ zr#9Q+DYi&tKN<)Ba~Vk**&RXX2``D3PK;PV4JY=+sG0OgTP#8F&f^IpozE+PMEC{V zGDiu`J(zCQF(jR;QxlwW-X@+>$|@vs)QdWRI{2HVL0C zyvOOhdTvNuE~P#$FQ?#%mjJ?*c_gJ@Gbxa~v}YCc52twRIZ4Yn##D@Hk1~Ae_yZaEBe(<=3<;ef-+^;aih|h z7j}rVZK9fpC^<6hr_JfnnSFRN`Ka+*Fc2&h47%43Q{IFLfXdD%#Y(VI0S%YKK3-PG zL2!mMei04L&>o=6z9gQTLSsf!*j9s8*|YgK4#OA3lDcUpZ{(teWtL^y4)Fty`NHG} zx)W>~b!-;}3J+BWf4#nM!%@vRu;JKdK8!Br!&gj%x1Qq!Tw?lcNDa6tU?WdDgY<4Q z^rn`C-aW)MUY7~Rih>mVbV4XOD-i1!OyS7GT~}%g255T^k06UGVj9GSnlPa6-(EJx z+Ss_cd58JLwgBu$2<6?JG!%(9L*$SKG_QtlHLhdG_-_babHr))YQc>cS!4NGnc_hN%o?tBS)F~TYx1#BKtq8=6GC-WJ1o- zbZ3W{NF5u?K8h<_SVWxqict{oI@FSn^uUQl#PgDnm!P|zE>N%bXTEoLjEPN7i_aQ_ zl&wA%u=G$wt|hAwgS=WF8s`{k$n&^8l_3Azgi`$RNV;0S6H6>;p6M!y!nG6pyf;dl z9_vIYpx_;%oae`m8=c(M7aIEkp#kB33im07&^&{o^Bd+51t2!#@LJPuf6Z+n+Rw!{ zaZ7qrOBNJgtJ)7<%Y1~@iTn_0X@)gTZcxYdWf#x(#PBis1iTi>dM|B~2X>+{fj8c^ zX|^+G6uqbV^Wx;r-~v#zZumTx69x=f=4-=j^(IeE1FyW6*~R14uKala@&ksb)%#w> z@mE&h%SX_h0pQhxuQb>!8hwEiJ^Gz|TY&^3+P;#CroHKRMCwMwh59nL3bJaHJwX4A z`$}Hv{U>O7hr}7mdgeZZT12}UJZ2EH*jD2F#C_{sts#L)*>5f3k0Amq0RTzx9ZAi* zY7J$E{3PJWqRIQ59#y?Fo$D)|0ia6OgX+A_bCT^!JKE9moz%@vNuX8U639`x)I2~v z_19^M2P9_Rj$A0fB=u=G;{Hrr+3)g}35M`6V9?p3KVQB;-*@Xm4799s^b#7fOmigz z#T&dYnRsRVf>Wzqe4+>)yOh=Mp7kteq0fl-z>%`Af0K^o9@M>y<S0w13_dsrg)TyWV=l4KY2gEXiy9hX;4ko7e8% zFxr}Nb5q07xJ+Of`Q^6tuc8Xr@b%-$Wnjz_1V3tRD&>@@f0jPm$Ie$nS}-rsjh4D^ zTroFIJ(0_+uS?@uAAxM@oL||(ZFg+Ga<^C?oZo>{=)MCbISv9g2id&Qx(*x6)&r#S zT}-r978bOTFl=whlnO!%xv(cWx3bu%qfC5EnIU!VdNIwcy%uZMgK8vvv1%p@e}}gH z`9-04;NXHH0%^eJNN(ztRbFi{n6Tfp6}9$4Yr4gj@jl$I7yIWSp{MwIEQq;UWVyF@ z*P(nSI(?IOclTSU7nJq{)hz$!>y4M^jpzox$L^eH#|kSaJ$o>XRtU z#t!ZKF`%=xW0Fih@VvLZRH~K=7ztNgCBoqFfri?=n|xWMmCc9`{>TBNJS*!5?eW4JeMm?f+Vmf8S=eLhky^S^R(S_~^ zI`|JH;b@D-FVNm8xED4ibHLBT1e;43eB|pMM3y;@4J(?-i-1pPV{kEyncj z!*EXv^5p;G@)T}TV_kT5VfM0Z1t<81!X`S3r6#D7HWQePcsE^*))Yyo4vyfx?dB=E z3(ns1Dns4@+uiv_DrWf=4#Kz%zSP$tuWd}X6`am;V3cq#=9eC>%8Dg)N1w2FAy4fa z6>?G>ko<}L4?j7`-82L7N?4J%=EmA$bkI;ljf=o)RdL=&Z!}=z0{SrRX#aPkNlZ4y_|G)PFK3 zO5klLL~la#Rw+6*(Z$57)=#S1?|>)NaahlpeGEgWBOo-$gb529rpM#S@7+ek`|?Bi zAqwLvP@`TTz`iF`96i3stSgi-j*2*Yxcjo*F~N@Uq74a+vi~BqifwRoud|U`G?OKv z)5y6x3Yu6eLsaEQ8~FZ`iKIZwX=7PL|ND}NcpFtb^ykwu`32E~B!2biamJ(_ zP_E!92K|cqJb^~uJIrR?V+F_sYl#4|1TtYYH$GAVYwMna=7ah=6n-fP&hv`@-8Bp7S*U%g6{;Cw4w^$_QLn z0j}AcXgWoW4vUHj8G>~poBf`k)?Liuat;W4DomAt3=IY_G18c(h1R2WQQ9yIFKc3~ zuB#}(#MzA#JLgY5RfDr=^+DLb2fw}sx=?lpZcb-V^6PLxY~vMWHctGleqUvvJpNK< zq;Gufqv14w`Yi?!4r|tJ9J==sAfu?rjSqRLI5@`FPD&(n*$YfsTGVf7;#*7kLkR9N zZ47Ol;z}!v69msnwV5F{*Vgx{Jkl2#s@YOThl2?c0dbB&3nJ-lCHz&Wv4-)`hIw&z zR&t8Q{OlZ52#{+rX%A*AT9G*L2T(zwwLM*KYHH%VgpY%fx~3FQ9q#m~6v_MWK+8qJ zPR4rHxxk|GR_wrlkI-^1aOT@;K-ZF=L~GA`mFGhADS&}+rIHQ=B9<|znNd#WGHr}) zV>hv!hRAq$Xe3SZ;cNe%v~F#R!mEp^&AwJd^{dePSNDC5GpFBD#h>B2HO|7t(JekI zEs*0dRSj{XI5sI>hFU%guU9H(piFu}U^>*P>6nHWV^ICXj8m@mD-S0n8j868nO=U+ zY^>;RkPw!*&+vW7z{jgVv*?nF!cQaTCxhNZ)#2`Hg0H~VR$gR7N~qYep^sR$FTx@iO`$kSPyPmQ6 zB!spA8-L>Y->j#L?2(pd#-5zvqC|!_nk{&dzny}=z(}FDiH4SzvZ)Z>T!O+wU4SkV zaBcIG=d1as@riVbc<^MKq&-Tm1L+Y%4pzN1U|}`vlTV+ZgEeTEL^Q}MP@`l(D9D~ABX;@fb^hO0|f7%=|I`_LK~;6!=QBiR{~k<-yon902!LvA{`d3Vh>IAa zCJG*8UCe2xQF4Myp$l4+VXHcMX4zlWYeSAwfYJI>fWCC?%LyXXZ5v5=tYO zoAuDy4u>1{4kP&}U}>(hQmBS@1lKjwSVxR%Q!YCuF*jp$8T#UL7Kcu4GQ#m-vJT1Z z`qZ**?T4tj=kLCjjadlRbGkNQB@=5?e2)6cof*k~WN2FwWG^|Dtw25rHD-)d>%)TjA`nQ`Cc(Klel6BiPK!o(U zu&9;fe^OW!Z6!tY2+MG6jp(q!vOQ%+vWB975AEFJ^qBY`FDu|B$5NCY^$Ha8@^iiy z)x(JUof};1AX;aJ^SjJK!7;j0E?VPd(q|p3Ntbx=K!A>mlc0- zvszk^tr8y%!f8v4>AnjeEFL^hLY!DmM1I?R27h61_G6rO8ry2 zq2HaUYL#qY1$cp+Q;mks(YQutMyEEOwuH(%% zLtl+G^+iYgdmGcwY8^00U;DyLN)Vk#pEynUWImFM&WQ9<#(aJ}xM8x)==xz*vlEd1 zCr^uxp>%IP*9}0%I~&1PtolP0MJS&@PY*}F{PBl!BUE`0M~Vlb$%GWBHoS2i7Q`15 z5_2#b9q`gO>I|O3SY93|v@@zi3gF`n{kB+T*q~SX%i=nS>m5+bAjxP-2t1ye%ll~c z^D;$>o&uO?!^BB5m-c%6B!$igdKQ*psZevgVgaa#1nIqdB{|teg{5`92_7QIfe-T! z5}&SIA>3c*sK1$W*wy?Jt|V-d3E}|LBHqew6TD||z)N=`{*i7nOi}$KMa=wHM9`B% zaFw*luUz@_!(Cpcc%jfvm7m8t8h2oRRFpKEQv1NP_X@ZA=U6ro_e!`1LJ@!2eLQEh z`AB4gif*Jdgg;hQ8V1>Sc;|T^dI1aylIQjMt5PEp_tQhy@{b?r{oUmuy4?6cHh?i@ zP1uX+`@@5pkGew4L{!xb()Qm)oU?@t50<&V8P08j$$B9G&V`k4Fcpe_(*cPEdHlJ* zLzUJxBQrfhjOJM5Y!52-{-oW|v$4zDFV*lJ;p}{`wJfvyA|5a=d_#FC|EX#Vyvt*q zt$*582q)^8^){i|iuQvb`!KnE7w2khJwi0JR#IJOPLRE#oPHjB*cc+=SN{0}hVYi= zj?(H5!XI@9UqN`+HFLfs^M<2+{l$6{iO*l8o+UQ8Yt4cM3kLj@UM2d@2*&b{+l16o z*#-9s=3=H=N^>x1ylqXO&fYK^j`@}9ar{tz(0;FKRChxPa}T^xOc!)kFmBFvX~ zl)h!#km09gH_&XL8|Ow(g2G69xBg`n0-v9b4+Ed*vQD!RN+6MLsj3^jIyTJmP24=C z%etVcEs9+WZUh$!OO5y!@tE>LU&>kmL`17IgE_p{GX-4m@4OoO`vyCn#2tTFmqs)B zSW|O6Gv6NTeUdT{ zrIq!C8z@1Q__XFH$&3v!hzfX(oBHStC~g7r!)z~W6@d_pRccLEmCxqG+Q=MD6u z+_00Mp(D7qjIuf_%-2=6!V+(7_qe#Jm#Xy{#4H-mu0dXD$Cvp1ps-EyP@qa%Jp)Jr z5<8BaTJq-bmE48)u3c`KL~lE#seB5=6)p| zR}*U^V4XU32nLP)B$-Qo{fOvf5erB*1U0Dwu|kE?BO``9bR1~w9jU9#@{@q9v^6kw z9#hAt6!hT28WapTwh0+xODT&K*)1_Mc;AdAZmpeIR99B*`N>#>&srm{ocAVKi?BYZ{x7yJ-26u1_mZI zFZ5+=zCP-X79?X-D+5yUF(zM@$v|z3))G;)$Y^X^0jF1%V251HOp8scZptYP(6@~_ zX3+^9Ar@9;p&__R!iv^Wv59TJeOT?SnLXSqsr1gP{U}SSY}s154E$UGS~8`!uUcK7 zp5(QmR`R*2ijm+_p3G*8U&{ypINVXbO(JV_jJmK8=m0d0I0mE^Rr@fVRQcymVK~8! ziYMm%BXK@~+9I3hP^*vvIM=cD;ql3drXN-|ske)2i{oj^#($QL>zYRI+=4uz{LE1kSUyOuRX*|MtY;g2? z7_=R{0VbAqTqYp=9d&)+_Wv4G=T8_ZAyP*^$fU{MN0EEskDJAZK>hyFcL8eKX7q+A z$1^df37CMEgN{|!H6hiC9pkk~#Ml%3U90{ZHoHEos0AhirBe^=`KDYm34C~TN{z%F za?7d{D55ta>o2?5T_f6h2gDE;9|JjoP?O2ak#UJg>_2a-4%T2$-F|wBPuY;!_r~9f z3+AUM2kp1}zMB!*Q)4p_s&YJxed7hmAj*8A$!ISx^92bh1KhEonU za|el=Z$5!$D?=8qmOsJai8s1Kr|TwfsvWDDG6k*y7(OP=LF?`dn0eUBI|qJ<)**c@ z5V%UFZo@jo`}CmHjGi_Fhq|lODMLp1N<>*%LtNgy6VKrjG^4Nv;KM7xwD87&O87h} z*{l9gQzPvm-Ub|0TpTmIunk46R}e-bNbZEwQsw+lOr!d^4;I{nDi zhIMqubUH9|5}%qSMig$$c|@i&G<6<`nV{ZO>AEp@QY0 z;c3XOm+J8)xr~leu2x|kaBlToqt#unJRA2eDAZ&DMNQ)XrH<9Ox))XvsqTCP;CLclij!?qk)bIxX2oqf(%m8KzpKb!F+Pr~37WvG<^!V0o@ z)KX_;<#%cJ#8v$KC#Wf<4A`FW+CAmUi0 zof0aY$KS47t=jjH`T7Ae)x!wgu6AYI8(suefrRHua2>l@wt}8}l`XUc@G+ znrl#2C;ETQez5=N=8M61%O67WS06v+eAY~IJC&_S)C6qQDGKRFL@FbmlfBb6_;KNX zFgl;YG2G3m_G&{p!K>JtB_En>*l5LTBq&w#Ds^*9rB}uMy^THhJ}m%eK$yQ!xO6Xq zgW?F}Jb-ga(p;p8;qWyX??EZ(X2sgc(u-)tUCQ}}JBjSO!+ppY#|&xy+cSx+fpc;} zDqiyNqr$2W^TXlPYJn{mWSb!kRQrd(@8wY}fk0Jd0TXtC0a*(#9(L2QMB>$p&Gr_p zJ?|r$cFFSIcuQsVd%KY8%7F`n7ieU%aK-cgy?bXNj&5&aACn#K|Fp9C58>Y%%>}Z)W{uM z+r3D;dPnBivid@(nRZ4h%E|%0BBdn?7OE;bkx{V)0|8M0y^v`i~lw0`&)Gv9G(jz=T+wgt48NS zAyvAmCs$w?blo~G_ntN}HM6#$Px36BA__*KIPlmQ$-eegEM!*c{o^rxb$#=L4ilqT zbgSb#>>XDm0bSX^eP&xJ9X&%uHPfWRK%YVgYQLW;{*Pq+kzSanO&Nn$Gq>CwyHg3` z;*vQYsgSr3n}?lnIfWo@pEmG5D>}Y?_K{FJbdJd_p}EpR@}_STHy=?we2;1;b9%e@ z&3K$^aG<6rVvpIIi?>m`M8eK{F~E8$kv3c~;+N;w{WqR9>*r9bf1#T7y1O3Q{ z7ysK#VCT#o07!SK1$%p$>KVO6#VjK1)7@C38rfYNrSBe5-kml7Emo+D>TH%C_Kt0y zm8Fro!gRz;^I>!ruvz6~nK0LiwZMJO4X^S7JOcd#k{eM}s{qpeb4#iG;Cqr4P!we5 zd2(>3MrfG~YaNXdYG{i=3b?O5&$S$6DDdS6C39DAkpN3IT)DWVa^mjCRHoWelXR1< zZR0=5f#JS{4+y{%ybg*(1wIpk8N&y=aYo{}ujSf>!lI`1?zT{zPOo2Q8Uh05^`<#2 zn8(|5oqyb%^Ix6WN+%&ravcZ`y9hkFSP&IvvwTcSgm8x39ZkLCQpUd7CLonHw0t^m z2R$-qq*qvi?>|iyMA|B|Vm}`NZtUii9tb z%i*pBo2E%eN(NLX@iJW*8riRZg0W~p3dUOY`hD}x)6JYaOnta<=!I$h$Z{3U&%Z=B zW;zUH$3o4|{11nx~LIp^;(9EQ^J4T&|t>b2*!IPd~j(zJ<{oM53E`H5Zj z#wok!L`$(BVeHJl_sM`9D5}nNaGmsMpexHNEc!RIG~;cK?NLgZ0pnHSCs=K%^Rr+A zy;vWe?I=z+qg*R6dq)UYon z#kqzB&KnGj$Aufndqg72N{amHKl_M#-xN?sq)l`Ig!U$Yfqop|`3~O~ptA%$MiiSh ze_BQ~xgqeXqDf)eN9$^^^4p!noT?L(NxfAZz&Dh{u9e;P7l0XU-#j^3AL}d5aU!|s zi?hI6n}wxMp_xw6f>Z_d>UsNu8alWX`R;KfnB;l~(s-8D=-sq71MruP7v_}acvUlvKx28}lB<29EJ%-Gd-%lbrh25_DwLavnc(ot?LXo-lw?)Ye*+q&Moelq_&F!1L5ZKPntNz~w$&qwmz5y(T& zrOtze*4H~@btGiWto6AWbebUlxQhQ2lxcR|i8jaA zA<5{;kUPB;e7>06ST=7Eo7CMB5Dw@J9}%W1{Ps4%t>QZ&Dw>vU6Pvi^T|jt*V5^zo zB{^>76(PZc@T%2B{%v(}c8YS51+{I>r6GRF3m^!Oz+_@ztGoC2H`_zmwmL=uNip%E zjR5<9^J!kJ^u7n?msKR=mV5NCWlAK3dZVh1y(qa{bLa@^BZEWiV*WI>3|^-chNQ$`SP6AJ*tD!ixI7x*;^KgQ-NOQ!q=f zTe(3eeM<=m3cfMhIdJ(xhXgn{|MIyt&tHxb8~d$tM8nw|y>`CzKeFsUnhZylDyll? zl;_WWDB9*Ib$no#08%pWnG_ks&4vDn(VC>X=`ZkxzY+yf#3i31AsO3lB-1zkqf{wlyXqhQvic@>H?uy*wd?G-i^?Dd!0%KF9yFnA2`r<=tR zM-{Sz*3#VCbt=c97q&nkt3O46KL~A|J(KkSd96=z%9q*}IAy|5E1y@6CaWA7F!$Rd zV=HQE&PffOxqmr8B78En7J+@SZrfWZJ&eGdjm?S1!UAS)7VD zOY}Lb^9Wup?DLap*%k@{%vfE5tgxwRV&5e;1|kmRtj`6Iz(%|MUz01HsOAR1;1bgtqrHy zDZS!Lv653XzSr%{0fWKS+p|71e#=h)s;IKH$g3>PyN0&M%JT}5T(?qNP^TYNDE*ix z>-41BnHzZH07WCb`Vx_bTky@8@>8}P_T4_2>W2qO2XmLCs|ucwHNkL9Q#;1G} zQHbu$%n5}x+47z&-u1Tb1q5!3g!HNesV!~jHBjlqazDyOS~!fKjlo)W&eACW@nxuS z@)#U!p+NX%Q%yg)H4iZ*R7eFUqMEIjM1nFh1DbTs{Ar>2v1**O@_;`TA!KUSAEDV^ z*QWzPK6DFR!PbO-$Lt^k9}HS3VFpGkAXto;)CzC^PZs2N;qIfawxgc5u8K|cdvUOd z9TxxTM_g*y3ut`x%vmr#-@ITX^J!yJCd<F67`8 zYI5PmVo%7TDAT5*P09YKZo`FgsLK->_{N&L3rY48G(6|lY+W@2NHr^sJo4=W5W8t7 zkZ}*VfWE%sg9BKSwZ}&YqlSB&vv%J7KCm+PKUtE09d2o&l^`KHHY#*Hv%$9#NJZlC zFw`%FW^_lmp1HUy!&AkCVZss_n=0}u&am; zT_D;4B_DHyX07!)W8LJ+^z=A%HE?waf%k0mci~zPw$*ZW9ql_?ko@pN_Th=qu8ZHC zPA^>1TGf*Up3sU&y#v(RGBBGBP={Aw{_cIt(R~ zsJM2*LS@6>0y=f%WLPT_bz1D|9L<98r#;976nM*T*`TiD*QkS_#QB=^tq;hk=$bA! zyb+OJ9(BER<73Fva$8p(#DVIwr#Wc;IQWDtpp}KF*LIK1B*e|eh)e3WX*7?5+whF9 zIqB6(HpvzHEhYO6Xi5;z1ZqnMO`q=9iES6h#@9tNcIMYlk;;`Ig#o_>w$Dc|)UqkY zNFc9MfAa4BT<`z75L)DYnT)Vo`RdDN^T%^|JQh-n^&l5|=ob(MMFBQ3>9fm z>p1((6jf3-(UCpZRWweB|w{3~k>kEro*y%b1i9IKjckUeZPPCSX`(?E+eZ|JO&t%V{ z+FJ(|jc?;I*Df~yJi|F7-TTe3U{_a;Fa_x9p?T<0o+7Lz0V7!DJc#jFWj zGH(gX|C%Md?u@q-*DD%df((qQEx8oUukWwC7>p*JvWar6P{acH6`D~yxvDJP(cj5Z zd{zJP>0R|Jo9Q=Bna-dFbp%7LuUq1^I1!7G1&O*T6db)P_jnKXWZD_WwKrpxfSi+c zdrz8^Qm#_HOT!%WrAhDmE--oZ{U*?fsRbpu`BX))H{Ubm^Fv^;x$Oc9Ajr&@*7?tl-(qGr7w2 z&lmbk#x-nndvzei{Ca)gh{Zz)=Y@-Q1QX=VuZQ52KI14Pi1?@N7IQpx5q*5+0OMf- zNqto7Iijj+u*!Hx1)5<-9h$0@FGu5~84L>t^Qyd2B0%(}w)ctpPuA zpIy`6g@4{(jq*ztiN#7{!xW0JRSlSOdixQc{f6WUU-SxXz&ykXi#WGleZh@LaP^I3 z|F@R!7eJrSs6H~-x=qKRyf-8`2F3BzL zN=2ZVIEQLCG}}47e*^~IB#g)sJ8JOG&}6yn=5Rcigq=Bd@(?+!BI?qRyZxfjfRk;?sKLk zI_i?}sN`UjcPVPURHy+W@;r=Mt^y@W#1JoaD z(h{~U_jlg2KUC$8K`B-|a9Y^wsN(H73}G64$x7T-?$>`#enIRe^E+=mkcHjs$dZqD z7}@WuZpY{=Y27=&e+C!H4sW_J@IYJzirf>6607rwbP1t6te|q=u z0Ykln=mbhW9mp5?2}g-H0eFylHvhm<+kKkQwe5)6W!xTWMC--VKo@i3Y+>3gW04vA z4TqX$;0%LdSn)Df3sd*osB`^MVxb%N+Fka6Dy#xXrCPFj{BJGckJ%e2006?U`x;vy z>_0WwOHw|*h5zN1t_$-vBu5kytuTW& zIqL(Hr%Bz0M7hfqi!kza2d|qtEko96B-lu>X}u4>`vh@PCN8jOgkyV7a$gur)i~MM z$hiy~kHN?sX3d_%Ze*)p`<);y3Z-`7*5oYdA7;M_hjXd@^-}*t@S$hol>q>AsH2TF z2w{H@Iayjr#=r?8Bj3n~oZeM*Mv%B$ew)3fd#h9XO_kgX)iL3tBZ5+S;C|f_(O^Tw zgL@~7A~2Kop`mKSgV~ps@~ZZzSu2rx+^Q_3jqXWwlUY=*cQ>KWWD1wK|1>-_mk=f7U=p9a1#GoZ^Jtws2G zb?pcM3VFP`KDA3`9-3OypIkD=u^)V~+o09`u1;0R{?n_#3?E#Z3fK*-irhSBXwGw_ zIb9M>65g_XBuY(F_lBBqhO5O>rMp=UB2@vvlN{dmm%V2aX%}1Eap{lLv)%KUVUR}c zG|2;VHSTax$R##ey1ol{9)i>fk}19sT)?*tQ!!2W=oFzfQvhdO;KZt{!^k zU7sWjQj6KI;Fo((_;FvJrgZw9lPQ6?$URC*KkK}s!+?H*MFn4Wy2*Vz92nIJ>2fGk zN!|)dhPzH zKsi39R?}jBSUkK&Ktv&UgFNYoN7)o@%iv0ac@Jn9t8hm z<^-tpHA0f>Wa?TeJnl~h7m8HLVdmqtz&>-&pm~%-z8+Px_*yY_VJ*869;IdSepF6L zOQvrLL_fR={O(7UYHOHqdUK|hUXAOE7g1M~M_68_n}zR)B0@JPr!3UB7V`&SY=m$x zdNAV7~$V&-yna#12m~%8;!sYOYmgH zn%}lW5Gp__Y;0(*E@(JW9>Ij@nivmtgviPcnS}5mAV7x+9O8NN%U_S$UkR?&##5 zv)5k)Grr(Ufu<1l13IlIQt&mL)@m-KZ(~M_q?h>48-q=QMksu4Z5{$31aDS2{FZW|SDs@*diOaVkI!1{j9>r&UCl~R@8;$+{A(DMJ z(#+JgsCRK=DANG7D^i!2nv8 zx`K#=Mgw!~Vxs6=3*qL6nfKkN%p2>pl>$YVBVo6p+@P~fUAL^EC~jYjV!JBrg|BMD ztQ^wM%{NJSCApCi=|diZAw1>*AB#fdSrCqzQ**L&%;nuqTo4sB_$BrJVhzra_CELq zCghJCJX{VN<9Ar_!kq$xBYYWcTY~lh@%S{D$k$FV;1zKuSKMFD6}M_85&~h99&e{9 zENP&^Mo0G+bFHO~I2Ob?5s4P|Z9&}F%5-6ry&600e6@?EIqPGcIXA&O->I9!<&q#r zulN3ip#0YQEDtXgudVam`AsXplR9jO*WY~hMyd;!V8$d?iaMe4+JK{di*-Ga=c8w2 z(DFJ7R?pGaz`&>LKJ@QNYbW|kzrJ1^8fkdZS&KvFMqchHZTXfe{tQ=L`C)-6b<=a( zT~>(o#`sHxG5uND>INCNzPOGh6`H5kP^}eR&$KL;B?2P~h|*aP%>0C~$b>d0B2gXV z>1sgZ^4wO%N7t1zOYk34bN6qruMr@II5m7)O(h(~~m-%1A!Q)Tm5~FP`xvCW*09oVaSli8IJ7K-xu{hZv_}6&*oh z+>TWc-*}88S9>`<=nPXVg!;13(>HsI0LO0QZw@<_9s6Nu8gL&Ec&cBrVZi858i@4(>6z^9U?D#tH2=p$-2 z_(&uw`Bjdk(XSU;I0*WN<^Qqw)=_n3+1fV;cXxsZcY*|WcL?qpJh%sUch}$=++Bie zaCdiizV3VLty`6C4#zIsm_#u4 zKrE%IlXr!-x1TPC0#_#$Z4gPwtNHZPMhH6v4+Ye@ahGSt(4g z<^o(c=}2u|hTZ)3bsaKQrG>c##$=afLT*q%NQQTSYfnzu3zLIwz+>2UxUnb4S1GvO z&<Y-sXnVlYU*A4mp13@S#!BL+mYWH+Tw@Tuj+F<@ z$GSWF6@hRc_s0L1C%uN^7&}eB`j*Cu>R|p3wo3%P1U7WBY&3HkbUcVL@8?Wa<$(5A z=Cdl3ym?E{d{Hy=&6@a=Ne=RSR;w2CgzR^%;jSZ`xi5_GLya9avH89V_DEFjAR$7F zx;B5KGI&c()*|9*-hbn%Kkwt(rEh2{ib&M2uw3Q|^y&ut+2?;bo%1VEZ^{S0JGO%_ z<>nxK=m()%Oi&!48~qT@e-$#?WQCe60uRLC(>LxiMOxvJbSrBpfp)MuT)QT_5klWW zrOsVJ5eD(O?(mI8Y8-1eQj*k%{%Ga7M~LwtR?^|~D^C15Ew%ZVBJ4Ar@AMth~NQ z74P?i(I^Z*LNPomGT2esAWS*>jTMUpHQh`FpGH=%SmZrq;Ai!BOw3 z#JO#OL~y5DStJc8w&U?MD162W(vizZETXo>h= z8(Od%vtu9%$IP8WTZ`f6-MF9o@No$j`h=APy6)bf&9@}__EzeP&;A@laEuc^K`lP zM~Pu*7Xf9M@JZY#LrEVwF-)N4f9h^NhJQx#7!mH*Lo<&w@e4>e$|@V0Zg}&pWaPh& zJ?;~f*#se*B;@5%iJgv?$){9z36P=M#1G1jaXom(IoT$db(GOeTTOY*GiTRGT&niI z#*}xJ5#GUxJ?G~O6T^c8x0u3axuB}5jw!yvy|R1ZWpl?kl-TFP9=b;MDmwcNDK3{{ z*&c3IU9V_1g5Q|T(p#kjyUBRbu)G^H7$wyELb5pg7mp*FIcv*JuE`fsY4lrfjC_3v72QSZ9hY;-~K4G zu67%!HRK+6!V$Ix#pPy8@A(lT8T}Gh?;Da}pa9;&XU>d5a}=nY$}2L4`(OQVGT-*r zwcZ2`7wtoROng{e=M@6jcDNY)R;H<>dgu~YROCn24YeGYmHS%&3BfWv)6Z*W8+^I#(k5WK3A8Uvgq1$ zx9(hDB|+qT;c9u4(NUCJjOkam*Yuf!_)3K*6rg06004a50*U1y>P{*H(`Lv3gaw$n zI0VE<@0I!(_!R>=ffc+m&iFoX8Rd~e^;1Vhx9Bs=uN$}UCSw(X8HoV_^2tIn2Rx3H(1G=(^3=G0$e zLRt^mLy{Vz*?M%rKQUeoPT}}~tD6dgrXAq;2~#8AgV1ss+9uYmquv~)+K8z{H=l#t z4kVcxhqS>6rEkA}2iaWiBZ=FuNPtgap4f79fhnYJV)9mr)Y!0;JC@&M1$uq+v-WdY z3)`ep(e*tfU+tN3q#eLS^p-s*Z3-e zI#~dUAqpw^_BEu>^gUgHdqisMISGS^fV9QOlr$SUbbRHar#Bqfb6#8$E^TOPJ@CAI zlL~;|>Of;|7D_@oo5pJfor2LNAYl5h7l)WtEi&>`P(are?mSOWVR*>^QU>0nb7-IK z876jOV9Nb{syNJKrrXA7Zbqip`%&aSh;P3yEN|n9)aP2KWXAPQ1H)gV}IJtwbS*ec?F7DaC ze=+q)Eal65&T6P>{q3cc>;b=Lv<}B_4H4}F%KvfNyTsLo7>f<{e zmDYIQ``H`21*iEbkz&ckpNj-1h|G)LKB_hYn>SoTjMCzN+s|dEq@u>ugr<3FzgJib zrc-}>A9Uv&fIpR|+!QJc5;0FQE@KTBG6aoDlJL06`;|{mx%KdTim9; zF8@H!I*>F|$0^R|34Idc-Y;JL6|DnA`TRTMTTGR&l$c)@82n2?SDpl>quElwu8b|r zbq5J>O1sSBI+w=qS3r5hKshc`n#D(>z3(@XbQ*#2D>|EQY9tP?*xthzVh5xZHULDc zXMM7_@cFoIGWBh}7Ntw4IvUo{i5XnGYv6gpF*j~0bPA#VdZGLBh6v>X1Ud5u!MWg# zJkS}WAOBpl>|e-ThGAwl|LZ$)wO`Wb^p^{EfVnO5`J%}#w<7nF)`szcF?6ndaNUzc z$*aDa!P8NPz1d_`qs(>5Bd=+4NmIrDQG1Q)Nm0P3e3v`&_ubT!*8Jr)U2E-uVd+3) zF5~Go;sW@ULbn!1wXdQDC;glc1vRaTu_a+Vb zMowXIQN5sV-*nNHs*0%v4}7OG36J~jpoTy#!FP61U4Ju!kKcc2NO=B&y8aiPY&ghu zOxilk2ZnnJ)l})cguHr%vrvLd%@-UJ*b$|67^WfK@uv;L_)5jqMdCDU))jam`|8Rh zz!pf*7H9f)9socMC!bNmUqwTwyJJNrRbGlM@qXZ;NDL^xA7GG(#_UP-6_hn>@U!X{ zVk@vfzWWMWB{i?Qwf|mr5~h;+mh_>NTU7|F0IN`tge7cCK5Mw>ZNORE8e2buU2v%3 znbJf_*S^WBRp&MG{Sy$IHGt;-321oU8B)E~4)lI6=fvYL31Qyd!Ham?<`~wod7MeS z`uWG-JAV&SRrznVT^R0~Y%o5-haGuIu}}!8Ik$0+VjH&)TaE81K?QlyeY@< zV{q*E>z3Lorr{QEMilRo)JXSQ%@y8Yzqa^pU0>Fom&#KHniSc(So*;SA@fEG_pe}E zUZ9`TW++1r(P_v*TZAEiao+?iv75PtCDcLu^={~QIu8r=>_aKxNrRhJ5u@t)5s0d} zo}z&MIDJXSjJ8nW*RrkC*B%} zKL^$2J34e&c#lBp1%2t;12vz45K*S7r)tkyG=g^gD$!2j!_SR_{KjZXF(f|H@;scN zJa>*Zehm7*?b}(WOdKzTY-93#+%<&m`#L#X9?Alnr;fOq?yU2JII5J9nd)3%eO6#W z%D_YeFWXj`e1>5K1qgP#x-sO7x3-7dI@29xynWN!4$vQ+E7 z$g-(jn|l?y7dA-bHV^6K9S81Z&DZIQ1Rz^IvDoq5)DgG~30{eAMu^*h5r1*)C5QMQ zL^0)qSRX#4y~vt2Qse@s-Os)?k1Qx?-+l;;ii~fcJ$?K&-rU+fw)_Mi9h0B=a-w7@ zCSU9O=@(4{QyJzWVxj?=W;7TZ0W5|I7D)$e&We`SPEPKjpIfSjkEHFhe&4zRMlTt~ zDQbm)t_f}3dE?}^2gWyO&e!)biRscLobPzgx5-xr+n zq%ScfJYJUz-mF0eG;W;{N75DG5^m|gl>0fV2#{Q48Bmg0tZMmxl$8w{)5&N)TKzgX zpz}qz&rHvw5|M}(J?W`Dz2v9!LPbHF#Gfxn9DC0}kwK<{P{Rb_S5`5sR|LFzA=sp( zInL9C=~eOt>R}Lx8ITKTQG+f1WWMd|n~SH1hyg+Aw}eeGY(V&UIMW^?gR%N0%D0t!1#Qij0hK=F-zmI zgy)Kf73+847^JDdMn6T^D3Lr}A090>HD#+^q^ZDM9DMHab4$H*zY39>(2bFAV@D(K z?U{(7hI>MQI{K_>pcxeBVNSeS7N{W`c3_$Lk#Mng9z(r!a^wCP`Z(L(FLjdjV?{%t zKR?aS`**|ZO*2ywVkDtpVw0ln7g;Yd@obhVm(M5jtf?)uXPI{9vpg)N4z8IV21q|1 zA^+sC6vQL08^HaD;YKAV6asmKVqt?1zq(X@H#r99`3UC^6A>8bQc^4dGwXumZt(Ro*nWIy>5&U~j~WI+AS7xEzz%O3%8(A9%cf|4B-ftoXTAmehkpVSj45wk0^+yX zh#x-18G~99Q~gSY-&_4khW;HfBx?2Jd)Wb&Uh{k96KPFewJRm~s~DE%WR);-AN*Bp z{k!oN^|4dusWl;USqE;dLOMcY*XoADhv8o}YhtNrSHFo$`G#LwKkV0t^WTM?fvU>7 z#@5zPAJ{I7ZQg$zRHZ|Q806ub#8m4B)_eWW8=m*E)Q_lM+&V^vJ4~mMn_IqOvkGNRT_|Gy^7Gi?MK1b zS4e-~#^2z976<>WkzYt?{)5Afab%1sH_FmrYyHMIBR20qzy^~XJd7kPt@K4mA@?T# z#f<(8uz(N7NTKe`tzVu_7o~p6Xx}HWI|<~v$rBDMmh>``3xGWMC$%ll`c&aJhE5sH zb%o^ZCwV#`_8mnN<{sDidjGc0#NiiP zYkyC=KRug#c6?6b(RK-UKOFI1Lt6}g)cT!n_KWU-QpI3rtQsSxps{PH<9kg->CpVD zn$|7I%gLd!FFiHMAr8(SzTtr`4*7`A|K^u@0Ww$KxTibNIu+X>N5v{s^fp^&4PRzw zmo~S~S4$MWzS~Z-u=%CN%tT&FKRRdD?B9VC>UTm)__bF!h@zyyMx#ug(`4Qnz&d6I zyW7YK`&X8Ae@={ya(A^i^DQ0NSsR<0YVT;OFH22INGh-B+d$Rr`JD$&{@VBmFYD~I zejzL8EV>_!qC4(epwSNxFz3hG?yE}*He%Um%L)C(%J|?Ti8^W?7Y)73J#4zOsSiD@y2sd{NH-cfu-@8#;Ucf-eivU zt%DC|yD8rB_6yiTQGhrd^k!97bA8=cn)l|af7^id?)!@&4-R|+3L4_2#L#k33!>Fb z44(Xc*j7M6X{AaVlCU&@i_&n?9KKUJzBrIWQr$mq@(Ldl2Og-~ zj{2ZJGB~k%^p?w`|Ats~*zEB4E5ol2BUAxhhoh+epe{ld6bWbo>)HI+$o}rpWOv2~ zmc81JVSu=8xC7Pn$MwhJH{bt=`o3o#NSc6#_o{k~%Pl0!mDhZ-tp1yNTwPSfByt1(kf$Xm2Z~8$hdG9EG2SIm#8gw zr4~MbcXNw9cZV^WAn5?Sgs8{aI`xnt?UF{kW7q%G{Vee1jQ))zaEcrI0&AH11OErZC zJ}v#g;*cU3$EAHp%!lyXrudWGtc zsCii_040c$sjm?6L@h0GOC;_eVMtlIxYg3EJ-##O)m|%#hmH8f?ZO2Ol*+LQ?L%~e z70;L{GKkbcI2>VGjN8a)kG^AA+)4|xsv6L3B&;tvYp}M*u6WnY=1`czn~Sa)Oit~P zUMk-qcm_@tNfu%(I=55%RVXP5qYwbwUhK#rovaSH5)V1VTH01zM*tu}(0bVftLgNcy zSKrssW56vHsU9!rk1pK*%HS0~*`U%~x<~3Zk|M=glCHe099WUEpm^+&Zab;(@JThL z&7?j)yVrfDJp6>kGBIYqdM5&*rq8T<>@08eE~b7rMMzVnJ)-KzFZ}2X^5OY0@ugOj z1Em#vD0tW?J6-itOOF^lOmM|gMdF}9Fa~8`)dG#f>0`Z+yVX0k3)$_H-_vvn&nk@u z%8_Hi!S*^lM!&&fO$M-Vvl+zBlNxm_vPS`lM)sU>d;)#%Oz!Ba;c?ks0&Uas>&#R8 zZJ>M?z5q5Wp3jR63Ph<9l2e$Zr6NKHmPa()f}ad*K1OF0XmF=ehc&bPcDl$>7_ER@ ziFJ+FK-;<+%^087X-;_45otC_rm;ZZ*NzjNs3YE|skVadGqLhQVWv$-aDItG7K};j~hLxX)I_ zq>4NPiS|HHT&c{bm%K&=_sIW&-J%lY{WPY8N0`D^2-`uG(JW(!cgifTWY_?vOVcUD zo8V3JZQ1ZCBIlvwZr;G$4fVHjE}^MCG&O&8{r(1&TiyLILAMvRI7O-)GMcgTR2~gq zn`7SY`E2sUveLRNnJ+4KuzA^o>hy@>S|W@Tx$5G?#Ig7Ue~|IptM{;QE*v3>mNTq4 zz{XJrS~gpg&a%6mpZK!8uzq!Ub$Yf3c;hp~nzwu08^_v!+h!&wFRojP(eBQ_a^n)M zN~trO>Gp*kI2}VM^hocrlHe1Mry60I0@6|ul1w@S6_;<}Fr3pOgOXSA9(NN<=D9#V z+B?U0vkYF>LBZ9xa1fMnY|DRi1%DQO%+1yjjMU4^Fb z+7v;_q*rB9NA3qNrNmxzz1hn`Q$1-{3R+pR+gRbA^a*c`Zm5tr46{GX!F`_Dh2 zdY14dnK{LEpF+N(=cPe9F9|QaF*tkYpnR!Qv2V=GZQFt5ayK{!1?hHi5KgcJ&>)n_ zfUq5h;|e$lX1ppBuP*f#Apt%a){1JQM}>Z^Zy9tflhiZ?Cf>#0PyKO9vKmbgHyO?Y zp(uY6MNl;dq*(lqF5$P-N7(}aeym@6_LxK0C*8CpA@LpCffXIS0s=jJT;%S&Cjhbo z4KKcESwgcCCitlYJvklJqu%TnUg@l+LO`3SHLcIW3E5e$3LNrFW2hW-qi2eoji_?h zB4oG>#x+2c0@{Kv(a4>x(9Q_aV?A1fbWT@o{r4OJgZy~524$$6+#ovbGWd|BvH+5lNQO|`9;Y2vj{dzolnv~ z&7P2YpOA{kaCYMc6WVYGMFAUF}~9P!+}!wq?3a-zLrnH4&Te!uGCV z*4#n6#DQG{brvMX$2qtjuWxLz6=v$QrjO~oC)=yg?_4zGZ!Q5tTi;{&?c zcY1~}lxxAr!FusS7j-xV^5|RfnDssEr3kj;R3XakKiO`k!p|>$#tP(Yi)sbJ=na*P zy)|CumgB_Uo&z}W@i0A`X^qp{F8a%%Ka)jlLgJAKM?!wUPhm{~7qRrxzjt5Pgl^4+ zEKgHDdN%=o|M%1V-GIP`ob(sDT@J#9MWmvC%Yt$W{)j3S**8A6-1B*eY{b61&X2D{ z__HvZaTlpopz$S_+jTE;e`U1tIo1@|yfcS0pH3YBgU`l4xT(#F@T#%yxkf*~@EY-+ zFn|{0@DN1AGbfnxNOFW@qkRCz_e{BhyzcORF6&J*MTMykp=#V*jJ73g!<=tuR9A}u z7&K4Io8+05S{;a)(c}wic zVDko1l$|Jmc1rx;Pxp5N9Ru^U#sILDh6s=GR#1TMcx3*CLeRj=$65-0>hc2}NNRP7 zuf(SEd{#v50jGiJ5tnU+nim<9B7J!SIn7~WDm{zK3K$Cd2`YW;+HO|BwXv=LUjW|KSsr7K4_Oqm4HqFkp zW!Q+|y5AWr4$KF{^9_q9?;Zcq#rz>;$fq5SD6KKd1QbS*VIN*!or4k)P%`rp&nuwf z7y4@BS_S*M%U6MC=)bcohoHZW+X9xuh)ftQqr|he5E6Ewlk%HdnV70fJ4=_yGaP}E zz!ok)81+05Z*Wyr7RN`R#uyGpj^aJ?)v-w2(dnm3#mh!#5k&nW(5#A&7RfNdAkaO% z$8?M7SiU@2r$ckQ{{$}|F|aVW1lty0>QAqOrPBZ4$jfV(4j0_km1fO@Yx;%^(8jFD za2iQEmXXpivoKiM`#P4s`5NaH+#g-cAMr41k2~(+!mpb+x=?M)jtLF}vH5u2pmtwX zNHLydc*7(t%u;fodE7EZ5dDC4V(1XK4?McPp(l{hFa;eW#;cuBob727y;T)UL2MD? zxHG*APSkI89H#PK^bIr?^hu%Yki={x7afnsJol$Pkp?Wg{;Sggt!d5Mdspn_ub(c7 z3@(?^BViPj35(PTu1E5E35?s$={w|sGtmqL4&_?K##?UGX6P-$qUA`TU_S7P;k83T zEqjnpMd+C%cCGftdSpR`W2xGO#Pt8swfqqix`?LC9rcc71J+_}*Y22tvFB0 z{0BIDKR~)S4;Sz!ZyV#0+JlGhY}+PBc6r{NpBoDfk^90GDv)9^SXsW~GQAjym)DzV zjjlISGWQTZ2vU-eM7~~J++T=gX%_4d;h~p_UPqVrsYhV4=>=moMl0l82juZ*PgsZj>1&x zr{@ndgFysbXeht|zuA!K=jST~{#gzpr?O#>f|Fmu+{j$tvJWF|`;!jn7SE-7qgli%olGm-MFG!|zU0!0k;o1}iy*j?mT;e29$ma7&tp`F_%QLPNF* z#l_<038G#-+a!mcAnfD)#UEM4pJBGWFe$!u5t51>vRC>#hU2awD%L^{6I->6X;G=H zE0KF#33Outn3?i0jIxO07}ItFg9h#T8B%pqp=9A@zfcP`$Huew7O`Rfn4{(M0wx;? z4gOx75p=D)l?D$t0nEx0kU?rguF`YYA-aqpCn_$!aoAARJ1HV9;y6CAw&F=DkLkrS z2O+Yj-asdph)#Hg_>PI`x!IffuCkbvQEaCT$&|0Nn|nC+Uw)uavYl`BIK2M&wuo*h zj7Si?-T${x7yH*}$oF>-YCM2_TuJ7;2qkQ^mPS7+ifh9vkOb0?k5^eX17EpAWFc*b zi(*H7A$Oc2V}tEai|mu2LYvdEx4X7GkX#P*Ob_IW*%MnB0HH8SIosRGQ=inwxLayy zZ<@VAc_s5P+zjJOLh|Q{ec11uf&k2Yf*mDUmhs9i>AFo=jbJJ{=I6LWuJGMXfC;v$Fu0he2L5&3~=q*+0TEIMGJMAZ5G%Ms+QGS zl?OUq@4-cg@?+0YW_tYi;FZp_yPsL<;wk|{JdP@R+Or-H>UE^N)f@Iq@2W!yC(Z%$U> zrKzwkPNvj7jLr6c`?3PMoQfXJ_ z&tDVNr8%W_EyJhf1|^*I7o5NA~?{l{G%8-cYk}CQb47*jx;4IrK(GSF=>hNt@p6Vgs;Bg zuog_W?Fsz2JE$u?iDuu;gJ(5RLdK0h5Et=DtTN6LP@=BB1ZsSTZ5I%$H3SO8YRA}G zDD7ONMIu69#vPwDNCNj_u|5->;&8x_-PIjRDItFbN&Q^<6a`V=3LlvFieb7_fq?@swnwG~RW+p`Xh)? zYHMud{^oTJvgUxDJAfDWPD|Cj`2dhkc#5-`^bT^F}R_Mg(Gwox4iDlxy*B zht}{>rH8v+>IHTIt$w#5YcJMKlLAuOvqSOT*NVEHuGT&Nxz+9f6KgM?55z-4Rz32V zoZ^#P902+1$v>^xz{aeCPf-Q1NREU{0J|EBoQb613{Pdt4yj|Lk;f&%ml_Q z)1Eg$Bg`E{T=3a2CKE;kkAn5W?GH30RESI;W+?T%J78H@a9SNq>M1^!ty~j`2M>Rf zR4b?|i*TTb+7)={Is3uJV?+Q`E&4r^Sjc{|_<=o~(1^ird}2;kR7;HS)fF&`q-TUZ z*{I1HM-hJ8r-E_jCY8N+4yHVpneU*l(fEREY##J>b0YfJCTc%gyG0jWDMjC^=Jmi_ z=Beydmk(n{U+m8$VX5xqrZ2hT*v15^5^P1D<{iJ$i*b~qo)cR5`fSiNlqtreZNQ@& z6{#vq_-ZZL%hq>`03ZxM)KM(9salO}yd7^7K0r0(BzA7{pqLIwLFNJ&*Y0r^=`b0t zgyVi}9@`im-&i>ZWzTxyceLWLrXVuwIstjjW|R*7O>@!&e-xibu-Qm_9kJE}9Fu%A zzuZdUP>FN+OsHFEAF$jav+t=z&)<;c`W4t-U&G~LMhC#M@{>_OH5NJ`L@*3~lzQjU zNuTme^7@?$>7YHzeDmNXAw-h`%Eb8}W>Kc#gGp4bG7Bs0PXSR1F$RS8Xg-+XxLoSvxIOTzGKw zXG%;GOe}h&LGhe{XRGJ=*;A?QuA=wPk;{CU_;yZW^@l{J>*Wa>@siIrxqZ_m7MQ)M zDaRJevLOyQ^FDI^eV}A4vL7b+zmd=C)k}~fhCgODd@*P786;B9t`#ERGg)v+oSTAj zpdY4p@Ji`m+gb|`F_>}s4ayp3s-3lf%+3mV1rD^|obDIuAr9YcB#eWE#^_wSg=QUW z$+B&F;m*%4YGNSIiI2}L!~0O~D8nfivq`V0uOllaD#*vG<5hpF7t=k{?2KabJY2E{ z!fGTd3OSl%DJ`gye5k|sDj_~4Tqa*i@%7Ev0gHwLr-`kWQC!=`YF4%$8~c2nQl$m{ z)Yq}HHW??JMqVR=S@T;zN(`OTQ<1P>9<^^5}}!x)ftHH}X}8JK-ywZ;y1{}R?zHZsOF-oSl1^T80ChKc z7}aP-TFuhw3p}f)r@sx!OuU&*!VEGC9qiTW;oTE~klv>UaXA$w1JV)6gCx&S-8Wds z8x64^BRv!~Z+I%h?_>)-e64$-Xtz8__{(1SKiC@R`z|3-2vEOS!gqLCJizmdt_Lu! zTh9|k)4{ySv=u|>(Jbt49vN?m=N`8uog29%juoXC5q6d&-?A!2iuknpeiME(8mC!H z#_0=ZWZe*jP37c|zYnxt^{F9ZPM6PDV`VdVvF;KKfn_~DT^Ct=*$^Gqg$O!k3(1q5 zDyCzNS_N5&{k7}*4t(-Lt`5*zh-dypvIO6RWWy?x8&eo<|p9CBQmle=4gciyt}}sUvx{Ek_%CC1c?W0PyqG zD!`6pCAMOEzVQQio9o&+7{AA9wvi=c_t-Os>!1#Z`#$h7hqI+HtjKp}0c+Zwo9F`W z=Cx-o_7Eo?7S@kJ9bs;>rE;&H9-wLCbo`J%B{`oY-+#tli+1l0|x85YCDj- zmgZl#un$X6ZlKzJg6q-#6*s(g{cDBF_d$Y7{xp#2%qavKj>fok8yL1!gfGX>^xVdd zNyGQpw`*a>;^rmyZ^ft&KL>>8^gSvCeZitQ%d*lE2g;BqL#0;oDD0en#1_@mWmTbd zG|uA>V36s#THUD72Bc-6S1?8IUBHOfLRh4EfZGW}60Osjln@*f0{~TFwswrbqrnp2 z>AV7g0(2N*<`xegrH{;~_#$gte;E3#2W6NMvup0)9R2IlZ9+8`JR; z1m)}K#uRhCkzKc>rliLl1ofhkBCklHJyt*|vh2O%KTShpvoa}qC1ywJ5n-}AP4W8q zh@W@~YQ+sWW&m*F;LZgENp^^~7toVHlF5e)=r0a{;a9VMcnvX@Xk`}Dbfz>SoV0xU zP3#{pXPXB}QhFh882wzgGI8Djb72%#4(npL*~d?%d;KnlY~!oym+k7gJ#(!d z%r`f(?ck7G<1;J7CBBX*m!7R_4U#3lN@djw@OTCvs7n_<(8E^Ub>We7$L&EtgCAB5!D0SyYy zyzMHZ5&A&%gign{sq?Xg>GnpL zoeMyg9@zSvae|sAhsS#JY~RrEdf$kod>zoN1arwnh}@*pb~A&LNtUD6Z6Ngh3JbmQ zz!NcW2h6Lj0_g7g0+1{IVjnk-$IB0tZE52-#gpIN-Y}2HYg4#8MX!@ab_7gs9Q*j! zC)KAUG&mR}Oh4=*e0Nb*euQgONcr=z?~w^=Iwt@1U1i6_FUZw`ivb|7LHIIevW~<> z*)KLGyXg*8=;>DcBou!iuWzLyf)Y^`C%wuSc%XkF_|euKzVm;6L}nkTw_#*USO317 zN{qjLDorFm!IKxH;ZC`O9QjS%psICfBGrEUSoKlDYx%qZ6VqGuwTdFCf{S@FF5BvwpQ*t!xzBuii2Uv#5VxwT|MjpQ{9sQ!#0F3 zQ{eO}^7PNIqFnDK6BAWzBQgqhX{^+iWP40RH6w?<`|=4*@~!k+q&foyn^N-M%wYTb zeU!A8 zVeX;G=H9x2z9EAu7ri()M)FL{0|1gaC}q9n{$lLBH%ewwAELq->jxeh3_;T803~yH z@H}&cwH#4hvGkuwJa!$W08Q>@hSBBU-8x#db9ZSy!url z3Ak%rxQD|lAxaNLY$&A>SZghI842p{g-$;hU@P{WmyegKuU|_zyBjJvOGfDd3>x!< z;LaMna^?V7BWm!YzyGn|RB4_EC1uRTQuXH$V6Csty!6zZ29Cve)4N1epy?McE8b0U zs&bz!V@EKB4FouN6G5!UQRJL<)i2Wf#Ge8d6bmZhRyNO=6Q06u8DBp)YF&gAgH-?E zhfkKz+I*Bf2Dsd1Dv%`+mi6^x9#Ghi)*?RXOxBV>!chBeT~p$gpVDp6B{57ri`TLi zvwkIU`r`dX0nteFJazI8F*P&xsNn4d5~J~@w4zO5PyxnY72Ut<=UV>E(H?E?TRvTo z_0=>j5KJV@lmbv4rlTD(u+icp=^9i0d-q_`2Fi|8q0eN#7kqA%92D42^Vj5J7LGfP zwG9sCYeyx)p1dBgF->B5qxBU;RM9H;Ub1l$`_;8KXqiJh=ZZ`TZN-BDF5nax$M{IC zI5#H{sf@3;@kya>m-xT!r-lx~VNkRn;nGM|3-6Bi3@=wiYTjpQzzzf({ZRk4Nck0W zrxS$b=+(5xF>}Dv@D6v@3bLZ)TbQX`45RYRi`mZZ&qg}V>As^FVBpKQpq66m|Fe5; z)C+H_sc{48Wa=nuryq;=b}}n6VVrs$`hhNYy&lCW}md#mh}}d=%n8G8J+!Qu6xL*R9mD| zz<8o8RO|N*0)J)P0lDVWit-?VeL}GEo@l4w<2A9Ic6!wTG6@2OQ^DfVe2#;gPh|5s z0y-fZ`sGC3MozYN`v2SA**lY|`i7WT%|n(HWzCaJ%}3g87EX!M$k5h5t9I&gZ5P_c zEa~^HE8xot5gl?a-{TI1qyh1i58cz=F|lepZ9Zx8A~Z4Pp3B1SEr$AG@7N=sZRRez z`?IJ|cA+&*zn6l?nQ7S>=Sl&JrMKX$x1glDyPKczW;QQ4PuitY9+W4f>%dr^1vN0l zRy2sq2xP9dx}E!Qo=tahR8^V$H$lJvwTMGqBH47~@o_M2Byfxxu(M;s(1i`biw73Y z-9dtEMX9`VECTzGn43}>sQ-mmsMh#K|E&5k4>MwagodF-;tH012Lzp{k_N|70iI+2feGaP z!1xj}tz12+=Qx`4HQ)=y$fvKoS)GlCS{rdoOPREt9yT_HDqLXwPIOd;3x=V7#-6qC z=H)FtV{;3Gjz=H1HDxrC2H_D8?bH~c&KI&d+R(8h%EUW16SkE6Jw@uN^>l^8%PWP6GLQvH|*4-m9$IC?uW#C;XLW&gm z#T^VZrfA~1;bA0oQiJK7&4(&5C^~!$0-=J5uZ~3Po!!l4aUbYTdZJxx=)b})2a7Q& zXC4vpc{NNfWe98p3rmH9DR^tKC*l6Ado#8TTf*BjL=p+Z!ty*HfHTfOOwt%fIc?*O zppBQm9%QAJtmm;OsF`VcMK*S@`<2+Y7W&p`bc+)c{X{yh9&=u;>jJ&VP3Tq|?l;wk zU!!sSVZ-1RcdNHeI-jWc3|J0(Q(TPR(H@+`B0kJjMpC!f5!`e~+sLvj=(b~g5$8I7 zA1d7<#2_4hfmH5DI=@;Pq)Umm|apGWzrWJ+W#6%r&{FP;f~(I9o8vXG6V(&EjC=Of(0?*ggZ zGg?Lg$^^KyKbf?0vJYbp&=?{*S1b3yrkh{*d}*Y9u9Kd5Hd zLGIa$!%emB1e+j@uv}WQG&S5@AEL+z-;(MlbDOLv?D*B053DnWTph@DCo}pyx7!^? z^D|zhi<4{Y1ev;Du!b1YaOJmoqhKIaX}wcPr~#iIlrJwt+2F8Lu1{8LWasY#BESEF-~UdE)l3@sTaeO@F3K z7X26isP(^YN@cq?K^c?UZ6R!vAla_ZvSBwVYrXsF`v34B{=>f$@CVfn(m&rH{~!K& z$PQYfoaOoGNdD+R{!bwUGmsPOW^HPyz)AW?$MSy&(z#4y4V%<~)vVJRFFG4r)@2~kkizDGzPbsuVT)W#e5<6!V!ghE^qhG}^ z4=Dk+zTdaUg8u)33>DNDJ;b@1-Um0*t+wbYo@3V+8v(Mhmv3=6~=M7H;hNiV2JwszNIggXe z8Y*!zbKpz<%sMA;U3MtI#t91b!(qX1epKEI zfwx50XGeSgVn%-kSdh1B%vf;nU(@5?Oq6^X-T+XVuLTG`<@3Ac3j3Q`kH|5w|8tg? zqS5CHGiJzi-s`_ly3t=%iOT&bzY$_4#3}v#-A0_`{J(rmgnh8(dYm86_pmlMRplXP zaOn7zlKbO88&A`uf&_zsf(E}FPw|f1W=}mADkdqB?Ls5G@o%gfp&tI_CvgmkcBcQ@ z+JcG3=RbcuU(B*yS=M)t1+=_@sMpDng~*5p$bZj(iAJR?Bgsw)2hhnH1}CGHc>{ZS zzB$qyZ!ONnE5OZ$iy%>T`*(f)x#8tpcBj7EdwRtrC`5MKQ8B?^Li(|3pDXm7QG#tw zZ~B$YYTPf^)vdK=16qITxVyc=c4%8WoKAiB1{3mZAp9+#b}5qWra{9|(x_>U=fq$3~6`)}3{T(E;x(%qi zPWKOX1<0OFJzvf)0Lbt!gYRD)Av?T2{!(LVOd#EnX%n}gATU%`9iVTuleAx*#1og% zkLJw@=FRAWyiW=Y@HUWf3JHu4u{M1#BT9qE^C6|PtDvsxUj=^=~SAu%++Ov%U8L}$?gG)x7y#fvJ`T1yT)H{%&s>olgUUNQL7Lr(U zNUmvTs{cLXu7{? zpfNi((8JEvJvbtU39?lmGO4wJ+8h zbBynKw6^wKb9{rGg^lpGB|?RV6z1t+X|QE!2T1v!L?Jku>FfWR9BH8GoHI)ndLwC# zUatIc(3$TB8!-1(q;Q{nDx#xdgyQqU5v*8v@8&HS4lL|KMY4;fcSv6A($(JiUR#in z6h1gSA~m1Fml-_Wyd&e@KSY4vi9n+xja45J`{R0Rbe90JQ(r2`chA==eaXfmII!bQ ztE1h=lm=$1|2P2unEF~Lm36HLMx{8sDm4#CLQ>j27`&)bM`FLC$8I42~%>Ip9<*t!W$CFD`M z3kL5vS>S%;p4z?U8kI*{ffb`kbTUMgUfMr%j?$oNX6pNq681ly-Tg03U_k!p%xTRh zaqyAsj7!Z8!`#jyCDeXz%8L63NN>HI0@8_^A<3FdG#E!;9B5^(4)zkgmp;$c?>TYEeDxyo_RIU zs~W|+cneS6^YcfBE|yMpf)BE}$PW3la~%-|u1miE#b3$4F12y?wl2{L0dA2s>E`q| z@A$%(!6?b!PA@P;yh;y=^xQ4MO}1PpxV8NAE$6g$>L!2je5k^?M((bme)tL+m#mB+ zA>49)#TR-KqQa6_i}^C*~SjZLADs);C1BE`?* zUjBi`YHziUF<1vvIgtImRdcOgMH=LXA_`aR@RoGV@P;dMq##VGgh6XGYU)ylAJHzJ z`8_(3+@^_)TnzZ21ZQqLuHz7R1l<`!IBW`cT@Y39{MT z8OnBdafi<#V{u|PcG5}_M1FI8jjdJ%_VFuq>K+O`GaW<|41+t~yZ0hS(!lj6jFt~4C133RQH_;6Xs%>K5fr-ndv z43vS+=4uQ^A-(2EY%D;pbnbPl&Yu2p@tVRksOpG6YaN|gP*{tD0F}YxArwqm8&c6M zWZu7kdRH;$M@sf95MxIg|74;NyT7+orF~uGZEk?n^vNr4hSvBSY3>{Pic|t|PioRU zSF7y2&az=bbG`?5A-udrn}SZ<)H5FV_S)$&8r*ygO=YTc*+f7^>MHet!` z>TnZjNvZXFXyPhdi%tiz3c6YNLEi%_EX;3IoS|?JZNV=SN(wdd%OZknp(Ct}z00OY zd_?Zjo$M}Hwk$hJ< zt&XU>CX_^8$q=T(cy70*Mioj&wC_VTubE6BaJvdokgp={F~gX3J|x3hwVy&1^KE>W zU3(!@@yZc%XIa#kCI0pLO8xE#O+9C{hMUkLM`I{Os ziFE!8n17zL8?1!nV9twENe;brs1ec^lrNZ>hPnbo;A=%%mo|i#7;di&wEX7rE972% zr>xlsvME)ERMF2mUL0P&#-67Y2?NYF3qM-A{{kJKrU$f5;Zg-^JR)AX#KOElJ=U9< zeD%H5Mz}FOv-{ zf{oOr7O~G1BOww@+FCw0Cg(;OKwFT*(+>72f{sL0!RZnDh#W87t?P1C1fHL7# zoj<&YT&;s*b2=>i_cthiXT(2HNEH9+sS40Qd&R^fqVpQMdt4i_#~I@96lD4Q6jE6bXE8{uL1Y`Ua_~4s&N@7iYW$V?Jdbw=KsjUR3xyfu3r5;1WL){*3T&bQl&+K$$>lg(X9tRiu0|pp@ zeAqhwH$+PG1t$<2h^l0FW4jiZLQAHZ*QhWv3dK58ja1Z`7$A}K7cV4QW?xT~ay#(ySD<9(X0QqK-N zIUXr%L!KA}Ad^UuFvO$3(ifgp!H-a@k$I&#Grxjn=^bqb2-Xgqg4a0GLKSUM|C$ zyVEppDR^4P?;p%#Q{tSp_4V=QBvXf;BR{QKz-F<3qgRAZLhP#==UxjE0dfhW&|!Pp z0?Vp>(aviv4v|;)xVa+M6IdS>ATIn6@WE73ML%Mm#Kt8hfVGEzeHJsAwh{g!1;MhD z?(hmzF=mDpOmau!C@qJ?7Xvw3F&#iAB%xD;=)9-{+M`^MR2br%eovVPr!(WoM@@yo zoOr=4VbO*ki|F4;XFGYP9mzq}p}8X(670rM)|4j0ruDp7Kr1T?*q2dV*KxPZP`3g-Qq&Ope@1?(6{c zxTq0|sO^p3X2qMWo16$MX>isZ%pP0X_x8-s2wa&^O2H|H?^FvpAeqvIxB2Oi>!sh~ zCCEt7K_TSOLM@N0KE;B|-Cq`Ufb&p+ZQzLaa;NXneQo zoY{d@vkykZHaWZCYrPZZdW3&9|2ZK+>FO13ktPEk(g)q_z9x07;8UfY=IQq?Tk;iD zO#nRDDWg@ne#-zT9GB{VkOnJiq3QJM>X9gF=?DbRRXnQaRu@w4w$e+2D=o!AAm#*q zg8doHs1q_F9v0zToFO-ek41~iGZp%$F@!6LHnrkNkC{+95r5y!`s2uM8tuwRv&26y z_qR4PmScL^yT=f;^R1~X@W5Mp@#J|*EeqCSoK{~iFX#dAm`g7(n%5inGw>J-G*u9h z@5X1~6Pm1J@Tv+6sn(wXcPYf+zSuqrFpu&1k6Ft}NN{ng8_5uTWt-ER_j7635-o)a zz*&}Yv!`h#PsAJi%DB5Zz=W>JNSgU?cJbs*Edq~0PKQzV5B*05n% zev}jSpyP4)z5|JQe@)o#lw~t`&%BMKY43}Zk6U7Fs;i|SEhGG{iM!SeGFinkb6u_u zF_N%_R9jEr;NzkN;+yKv8fwiqCdiD?AJ5iQ*NV< zGg({PHnlMs#Eef43k8peFs6D{nuf8Msy2fyrXo3u;e)h!!jc1tac>eDwtq9Qx2qwL z(l-1)PLEr`uXKK{aTs|y=L4!?fYo|W|NM3)Q@e}0wwk^mJ2l3%4UtB$m8;3#$2 zj%XJ{{2?0ZmHUk)@R`<=*J=@wQY9-Kb@(2=DCuUo7boEGmBaGeCQBagir1A0&yiBD z$n6@gSr3}9Yn->SqIp|{2m27_+n^7{aO1$cxE}uftzlWT+`%J7U6{;REq2iOsADW1j5aK?&6JgvH_WOF0wh;hk%1 zz+~%@?B`h<`*h6Kgp?7F+d&fLCcE~CArMf4SA-~VW8Xi{O}158Q%yKweP234;!>2; zwQzKC4w}MmeB4Xmg*STe$q=f2c7%ghYiFq38EcVw&5*-+1Ae2n+%w#DYHi9fr@m^= zuyp;35)Z3vr>ic^r(KLuOqX&Gm>+8h(_*~usc7kMttpsc&Bm6~(DjJv|It$Z92UBl zxvrkc7kUv+@(J?~qv5jf?;cT_EG?~*-zvGsFiF?#cZ?n(=xm#pzA6Sa!d`Os$fQKu zeUw(zR5!N>%B{2}LYD2oO;4ob7x1G2Mx{pE>`bvB1MK$}Ci-xL%w$^W*?fP(xS6fV zOiGRmt$R{8i+0x5eI=4s2htqY#@9%?P;G+PD^j_u3;Zamq->i4ZZipjj108fn-a<= zo3tuWO%;}t`6VcR0OJ2_1eDe$$>Gnp4Nh(IHB+|;I~$OqprQRp6@LNT=ZWIPvK>rD zDf&Zuf_8KG&X~dsCwd;GXs|qv-0is-h9-S3auIQkt8A(gntcST2_kyT*LTR8vpQu* zpfBIOdHXW*x?vz&pAb!up{UfHgjKm=$3H85*zRd_(4@r$2BY+A9xv4bo4BG-5#vBY zqj4*{?z7iMqdEG_`PklYPwhW{+!!Uyg}9j$;^mnzk7t?F)H^&hI@MI}5!&@3^i`+! z^kjJl+%EqoUryceD$AuEi&zOHL&@AW)LTXWdeh~%s=cfNrf|6gXl6agYFNKHh@*h- z4jz&uGY*ORmbwyl>aYo^X|oRE=ZT;KQ#)?ZuprMS27gy#fp3-mWQP$B=KZdxu_%SN z8zhJkUC5()`VDcv-GZ>wU6cE5Y;YHxh|@SB#tC;eGp%lI3-T|EVgl5ZjpPZ?Hk*6P zdvB(?<9$7h7*|RHlA7Q-v>fAVmtGK9C50J?xI@RtT+5fPu%&ZwE%iKpns=wMeFu64 z| z#?FpyO6GD4Ue203stmklp2+z`#_c0$wFZePJ{~_mkeUUs-k<*MTq$xw`l|D^{NYtBO zeM7IP>*m`|VO2YQ2L*bwviD4;9a=t)8wFvS9Hv7);|TGWn=_@rHl#{yW_<{Qiz7aY z{ep)<%j9;^E?PKC{UCd(Gy5}IR)4$-3EH4nW%57ri}_8-wbeB?b}Ag6%eR86m%K?K z3__S`S!DsPt@#{Bxl1xX1&*<;o51MtbqQ-Q zO64Nj#*Sd6AvI;o`rNT^c{u_ii4QJT)G=vMZgM*M?;Awnb`!LKFu9~ctQxq}w|opg z&(sItcT_fBVshw3bdv{xX{HQA(}33*F_NE0FzWz-RxW8Ed8rd6~gQVc3|2fsvWi&D!JXtD8=_EiJG`UziP$2R5*R{xA zM-~ZN);>DZ4X;#e-*AL+&_l!Zzy`HiZWHdtA1Rm|PP!5TJ9~w_y9?vXH75g5c>voT zNo8=PE!*IE<_4;4qB0Ez?7_oPy$*DH%Z=gtSswQ=rY^JFM6wr9w#XNe$Nv9#x2IY1 z#g>m)BPhSUz0`-kQRIcry~bWEaE`<5q3`5&H4U@zvuo8kL)3vqlRQb$u8Ss8hXf0e)S29_3&t&;pLUC4eJ6BSv&&K;?JPIiXoiOB_B#8aw)sLihCN=uK#4(tQ$5&`d{;mp( zD!V;9a;L4-X7)78CNK5`*sNYh9F+NyX#k8Dg!sBKZ)**8Q;(wh>R366Mv7-buX_SF z%nY(zjhB2I+$`$B5Vy2B{u=2qwNB=+7nfBw!DH<)L|?M)MWQUhaXfhy1xc4SO7Dv9 zduA1Jf=OSiW+wlJ^-~n_puctBnVo+AvcPv@&Ck)K;I>y#FQUM+AjxCzly&TaKW$6l zNM1?(`>Og;Qi1^);^tMvGA=2JX4rU`ChGk_M*T8Y8ci3ik+&0Gnczjw8kTKc6iyg& z=huywtNQ3q8C9K#e)IITTHjNq{<)Ia|S|B45rKR29XNu!n63%WaXS>~liQVH}Ayu=lCOa@<8{w93{$w1#Sq`?^PjG2=@H3(G<{5-vnSVGwsC z;X8YOPlWcek^RX&vIE+yetM#eG6{FQbyuky2pn`HTj|nQ(7WJ)|Kh}2B>zU-?>a)Wjr*tL4gQ3LuRx;;_?V ziR+5#Coev(b$5DTHC6eUd^vet8?BOYtlZQl=kj>2iu4rQQ~6wS$-w(uMd`9CeFH1f z8zh65z4~_AC9~&C!|eayzBG};_Yf;>opHn&T74#$KmGHe>ug6>eJlg1-c<5Z@=enc z3w$E=+Wuxnc*le?O)7}Jf^LNsCFxxpwDS7)(7(MSbcPHbreQO%fGQQj!(Mkm{qV)k zaH=ZF*>G-JX8AOV)!=%I&W>OnVRu1d-O4orseDLko+r)17b~0ObwUL-E((m>S6~JX z&CERcdGGW^GYvfn8|AZ*erDx%&k28mgLM z8z@v9~IEUQak4Mu9l+cze;agSv11ODpQ`@ z@YDo&z z>ykj;=l0aJnsbq|xy3~0=r*97kNl)Ec11mBIFgR3X6y$!)-IJ7RNCT9uY2>~PoWvL z@(v#MJ4e2z8eD|a;1H9G==i1NcCA9beI3sk?l}n4G&5|idnSg@fi7&qj(9bUNUm%m zOPs$PETzCcq9G30k+l9(X+SSl?>Cw<3b#4q*qs4NF2?S@cB%)V0CG$f_RmIA0Vq~Hz3itj;R#Uwe<7KZZP{1WO{D;2Py?S*xb%kTv&%Cr51$A@cAj+ zPwd#cIMWxGwW2Opinlb4gf=I$i+@{TVYZQtfi0qCce5i~S2(^bT(w#~X4_%rN~7Z_ zCL)?-CMd1L;aHJFJRY9E=P>lEI>ljx8H+R(ah)JCx8MhBNv|1MgJRZ6JUH!gP~c?% z&e494MSzUUY@5^#!sXz^rz;v6I4PIHC)IJicHU@#)L4sKLK!i#0U=orY@6whuFrl9 zeZg*0fw_kZ0C-C=bECekmKaR^M{=iU0JfX*aQDJ)s%Dur)$DKMKTUlnnA}InJd3do zh(Sx$Gq&JwDm(Noc;ErFn5!?zs&PvwF~e>3m1D5R*Bp18Sz@gV#0?xTxE<*V4OgYm z1%H1);R+f1Ew^w%1l=F}#xv;?2t-oIdX$qQh+|H;dOqGH%Na%@6@zeN#-0OEL-qVa ziZ-s1xJCW4TI$1$u~4|upq-nFjb1_xK6Pwi3;DF|&Rf3Lq!!26>#B-!ajE#E9}`$* zbnf4f&%>hd%nm7wc0+>S4J4={BDlQxtN@|&mH?Avz}*W8f-YcfFXE(trcuqxT{R8N z9ZVGb^gv>&JT{}cMGktCc=7h--{c;Czu3`=5_C_>FD)XVXY)&6Km85COL81te8(B4 zBJTB@gEQfKgcGa!aQ!;%Qv)e-_oZ16w%>+J^Gj+TZPbO9+eH&b3qJlf8;)|7_$(Vl zVzrBwY%g`IEocl99`^w^NzS?Zc9*((L|zj+?@QzQUu3%Q`7IrSk~8D2xxn#^XO!Ck zXP-9sLD2(Nh_!=jN^EvyL2h4hHSN8Ezj!81B5DQ~?w{iWye^)0WcCIXZCg$3XesF!SsA=XXyor#z`$6?DtF6smjl`sPzGbvF#6|r`&K@@Qq{GTS9L(s`ekA^r?Z= z1o}9LzE*|Bb)uw;qrM03{!DBx{#+?NqTP)5cd@J&sZjobVbd=mUsC}}LLL*0aXtAd zPa-8gW(fZ)$IR3sO#+G>-DMAnQQThtAydCA#izdAsnz~Mz4u_O{*M}UFSj0Tw*l2O ziBKGt0U7|wN;M9%9!meA%a@65H0PYD18i0bKzUUQz;t9ixOj_DPzIsVFDU*%q_nGh z{E$*RbOioM$+nvI@e0o*`jq`onRL8ECnn+It@%lEEc5>ENmDou&%d1eGl!z3d)S{p zeeM4>u125qWdOdec<(Phy~2^fR*}|{Zkog&*R{Y5?90VNg2a9W3DFV{;~-@olIE&!u? zbnblAKus8;IBPEJ`iOVri#h9nRtb-KO2Z#i zxoAj1QvAii6;KzlmuwCldX)uoY^j8bx|ijd;PS@t=R}q@Vm!5>!I(J`UCJTU^~eAImg_J22unUn?wdp z%j;XKi{m-A`tF`30C>17bi8DPpLn;=b$cN8q{fZj&33NlUMy1U%KFWn_*eTYdF84wC40dujkjK)AnCLgK!?4+W|*dh}R7|DF5r-L(|it5|A%9 z>}n)W_jAtlW@!q}-$8X)wY4l_nno{>?n#ARJ^pBmhNcN%SfDt{!=-B~2GD9N!rSWy z0#9Hn~P_h_|kXQs?b)?X0@hyk( z5K?JGq$F{j!6Q2z z)NHzybwpktxN^oiG`Eb2AWAWj1(^3*jJ9>hVGG9&j#k^XM_P)!>tgn?`18|Skkm$W&55pq-3a6@u^l``O7wy2>zbZ?Jq8$ zru`I#|8@mJCTy5lR~LljhQ5@Qvno{gK5-UHM9WketkKdn`XK;W%EUbzJoj%S zG&Voe7~9xr(i9#aR+3&DJ)W|D6%A6|9hfb8p_ln#!?lesx*y$^@T6?56hW2~-L?5} zo*!Ug?>eh(0pWNP1&*qG#F&>DW;;H3_yI&Xhr}Z48u_zj53|?Kgcv!i*PUESHA>T)Q`sMWtxyO^8by;y>kO?`Z zMP~UR2cu)hvFjLuHyIQio%HY*61?+KYd(BVAMXQr+Xuw|UFXm8*fuvnEc10iAlHaa zaE`RGA^eXdpo9nMc4pp8b> z7$6nWw9uwKuaD1ri&V|uIRl3cDl7X1gR$zV4md)z_(wNW#&!(A*Q2Y@GNdEtWF*oMbSZ!6DjXF2M zkIv=)B1q1g6F)~54J~))x$?{W^XvbYUqJ-Nd7-ziuKy@=Sm75{4DVS(0h;qZR|H5_FHj?xJKzT*`%1n3CKc3F_ zZ-u!S{8DpkdtZHwJv;8j_u{MxoE#~>yE+0}wzdt7805OYAB6O4*}_0&cdc01y+<&d z6OU|c$g?F}PmA=d`5Qm3xf|etSSu5j2k5uEgO#P7#s6VN{|eyYoU}w3D5vHfq3(Hi!CYmSX;L)3M0j_4&RCGqU&PB#P1*Qdeb z)&1)=D+cZWfU=yJB;MP~aDlsyf)pDg8m;@lZ&lq71AQgUMx2_El$w$n_qwC17f7S{ zRjP`pRlNrmZPvbXXkP{T*9XgwQ~>#NR}eRaO4Q8B*C6C18>P_Jt@)8d>d0%GRa!X~ zgeE=0(|crAP8tNDc>sZtciY(s((X|0Kwo!Xo|hCe9T5TA+YN8t{_j@s9|ITbK>!of z3oNU!f~E-8*&(uSA3@;2HE#llm@MbE^%#i*ptNAz5xMwC9vv$W0O=Pnh)X`WSt8QS>nq$wgI+Ch>vuWWm3_z3iL9R7Q+Tx zUA?7J3Hsz3nVDQ(Ra#lu(p6nrQP=$-P(b$2m-|e%C)=?_Zac zG@%lrrl=CijYQJSd^7kwZC)}iPQrJy>1NUl$gs$lvjca>AiDn~iXbZV?Nm){xQ%`0 zE@ALKwW%}Fd{!e|nd0(ZXJ;~sMI+W!QOCp*j8o?fs(kX|*6BN-m*?T)WOW&7HP4i$ ziQ%F7Z$YX;gcukUyo!3cXY5YZ&xS*PhycG6(e}5B3t{>}5Z#}t;`5wQk|eQS9`07Z z;t14Lh;{e<_G$%7f9uoQzOrV_w-E7~4Hm&!$rB~$^^Y={1M$sfQ z;NXhD*b_;%LfA;C1$5$Pa6G5q;ZPw=rx^&bOS;DO?tsCbUmjHHz|ZBSX4Eb~vm|fQ zXn0qGh5YT5`F|(WiNel|7^;sbWG*l0*7cjocyfINdfE zE~3iDyf_Yj;Cw1m0zZJ1%4j>l=a-XXf-fU#vScNdis*teDLjG%M@4s|{Pi~U|56l{ zjBjqgjbxc24|jHhc>vqjj8vE)TpnJdFl$986r`$MeqnkCAl3*m!Dw?((fGv}drBc4 z+Ak`4;BP7dl_Q3YqqFD@XOr%EM`b$@kt2=b`(xDk{{qhAA{^nL z=iRh6S^&R{bp;ATfgmzz+9aKNuN{|?hO!fq*rw{mZe(Z0ilaJM%6Bfgf6`2HE=Q(BSoNa zf6b)*6wl<~TeIFZG)=9+(W$DDeK%S9tmfFJG=VX-UF2}j$i6mJAUiPOQ(YyP7-VN% ze3t3zo>W@vD~J2mR-H3IWZ)5*)pW_1b%?DVGja@!z!VG=3@*i3UgPgnBOz8z9}oPa zh5Ijo6i^m9R5~6=YQ4l2LFa@*znjP zuTs1Uj+qyRk#eHC89Pp;yqG&v{ z656q`(XJA7j~#ww-@@uqim*Lq!Rb^vca=wVsY(4%*QyN&zfo8#zsY#JMs=YC@(4tO z7K(3n`tVLZ*SzevIR<7CQd{?&Y~Nqk_)0ODH36~P6*SMx?riQ3d`&dGPlHO=*9u%F zS0#-M64L=OmA6YD0!M41)fZ*Npn|!&00k^(3qi-ienFoqtH3a8JV26*T%&faTq68( zYus^8pq71ya}(S@v&}M5QQy6X?GOK>)%!<`q(|o+v5}3Dx-hUaADh zBFZ7 zC3^^54d8sYT$OXB0G%num>&MbF7|rb@euU|$>nq4dJn@$X8rAMp%9%Mxg^o{`@=gA zBxEci$|BN|Ts*qjPu8o<20SR0f?s*B#_B>pe?u&@uwm8mI|p4FJQgLd2e`0f!?BVd4_7~i{R;`F^n3$AA~m`%q$;+pjwV}p%->kBj# zl-le6;7!Hv2*X&irFq)31a-Ru#o59GquTG4&_dM27A-5L9rE5dba=uaHfu*z$ ziDZyGb+Ruj>1;vzOLJ`*b#Q|d(4-7XLYm#;EY8E2i#Q$QF%*#lwq-%7wI`G^4spqD z8Y~Z;(;q^p@^*V&)@fXJ^GZfe86s~ozRs?QEKhqpEl#q(LvulG#1b`6qnnA>L#e?c z1bkwDS6~LLQb%=r1;MA6^*-_fM_4yvN3;lr#d}Ao<#qVj7uz+Z5 zK9S!JW?fZtg5`L>KLK6X2xgRDlIU(^l7-Et6(HUcjfS=Nanvr?NX0hgPS~%Yy-03N z>SUHIM|_EsVpTZvLL2LYpjqvu0Gz@&?RaD)nKKrgr&7i(ueD#*Ds%wjcRS3a^`o=Z ziRtCV&>QU*O%h@vV(uzL758Q!%MM20x-F7m=-`cE*AwOSg6vLA%K`i#@Q|AyE#%K| zHIWez1pt^2Mmy@Nd(QWZ%FQJmCRw}&`l=#qO_RQN1`v7|>>4l^GxTeWk&B^saL(7P z@C};*@?pivJv6Y-U_X1b5+(JYkJo8GK;Vt!JJEjM_;x*8YVX!#NkOUIN8?}K9*bx< zY=F;`C3a(^$-L$cUuCW+#l?i9gX6B!7ZDIm?14sF)q@}*DMFfrJ0pq+-(KfKMo0ardE71mbVzE)xe&VZ9s~a_CNo0rs%G6sa7Gt z|C#>2L3^DPBO~7c0oqwM=ZrsTZMmZ(9<48Rf}=(2o&_?rX9J+KY($5rm~T9POVz5U|;DlWEs^V-nW(=0^pTN1V1pn>BG~jzPfJQ zZcn8rQHcp^!=-R>Q~;XsG?RJSBu>bpbjBg6SqrqfHf-RXBmUluznP62NF6%8``*vc_Z=EIo}P z+FlLO(a~VA2+=xMA%mksEeJnlx(Gq0!((FNFhmCQK0s5VJ%+n4;ZHDk*fbI#*N$m74* zqx{3E>|R-HNeeRN#JV5vtBW!C07F78XdKeMxZWvw4d=^zV-pghDsXLb(_TM~rQo2p z!0O)P94{nmEK*sHgu0fJ_JK@qo6gkR-R<-I8FT@G*5fdJ?b>P{NB%{mos*WRjFH!8 zg#}l{G^E~?x>cU!Ghf0H`G`2BP32bB!9c~f!Gv^m)b+FIhBP|g^NZ5JjQFskA8mIOw;*L|Txn(Z zxBX}_f6CbA;lNm$vnd+ZYtBFfXmfntic&-VAo%HU<$fcoI>8jgyD9o}QjQ z?ViPX3fE|KVD7R|E=VXz7mJIRHBt<)Kf(-lqb#B!rJLWFy=r7i?C1KK`K9sU>cKgr z_xK`GoyKyMON7rl#m`RWI_`CFPTen%2vFb(r!^)^_*mC1CK$6N<-;on-^zNJT2z*R z9ydCFw3t6*bEv%}-ByJN4gh>Jo~$fF%S}tlN_pl5H(7<-?Zh*NFK=)2EYYPvfvwby zAc7TBk=)jb7|72q8aD$BcL1ae(}sI5=V&q+9v)NR`~F+7oRO)Hgp?r5 zOCf!!_}&*Y>&RuIFT1j{Lb<@~?65^hfq-e6ez)(w?R%vSF1K6>a?_XO*T~4h|+7=t`lB06EsxZfAxmSfP6kMy~L8&7QlLDmmCU=3Uhn! zYFB2GbF*s0nBbl18Q?VO;auc9TKlg+UJjk(NmZ|Mbk&4 zrzNK4lJujc{5f*^%<$(MmuURT=F%YX?Dw6a3Y3)OBd#*aetRJ#T_i%7-Q>;c5+9Ry zZbx;~8j$Ac`<0V3T#OA2tsGn&V`^uLjU>F6n1Ve(NCh+Ka9PBu0UdG1A3#s%s>}1N zdBCRAJU-nLvx6RVHk6lFrF6f^f6gcjOQ2-e)H zTg49S-#^};>B>vAajVBOUNfzp?yZT>n??UW-Jul~Ng~J-^`k5IbZL@fdU2jSDDW>o zQpI0@9r3U@wQY@D#mfr2P5!1t0%3ZhJA#9l!*taSEA9I3t08Fdr;m#m2?_%Pe)T%s;%`QNKH*KH>O7jSsI><{d9*k>4*(#@VRwQjjW_ z^&ZsPqiuk4*vK%TpbG{M;oJs0;SjHDvz|3|0EuS8P~43L@x0$@jEjxQ8$TvB@{h}} zC~9u}*76lpp^Z8J1QY$~8qc--Csq|-{aJhCt4HBusYZ$vf@SaPesiy;|1qo8&c@yi z06Ya@oGO7+C*ay3C5rpwV-h>Wqz?gQQKBc&R$f6KIyXYyO2kl%o<|f?1dCZoOBytY z!;-fC6eXNFqz}CnJ`6d~@uJeU@lzYu8%+@=1dCqYf)Ml5&zPJF{#8YxOlze%9h;|r zJ;o&iP?6P^#D+T^9~nL-dOV#=cGYHk>MN}oe}E?z*7GfyIYZ=D)KYTnf>cXhy+UNS zZNXE}5Bh1|`C_`I82LnZorW=LcVBgGw5|=^to?gLPRBU gF8&=m%aZhLbK1X_2YG!eM5H(XU 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

ljn_O5{{>7Dt%|=s}yBq&yvrO=7iyw>OdblsfRq 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

1)g9YZLgOfNCsOzW*g01 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

QCSTIZk{ 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ⅆVciXYz`HK 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

wdC-lMw1wR{BF$ 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�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

  • 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%0D9m+XdJM10 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 z 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�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Ý=h? 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°OMFvM_|g4;jP!XX43crGBhfUPFhom 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 z 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

    Tz*I5OBRNS!^@>g)c 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 j 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%0AN-R)RjnEH>D3*jcMpII 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 z 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

    q*6fr7H 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%0A5SwUo~rgf|N>+&5Fv>+S1fOfYVJ< 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 vio1TC#HaT4+)A=zZRG*!LXf1ZR2Wt!gYK=6 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 TL9_7D{6GJa-{2HKH3a`ZaxpNv literal 0 HcmV?d00001 From fa09c06830e6d697b2b9f1a48b668c68e8ac3bd5 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Tue, 2 Mar 2021 11:36:20 +0100 Subject: [PATCH 068/249] typos --- examples/06_grid_manipulation/pet_advect.py | 6 +++--- examples/06_grid_manipulation/pet_lavd.py | 10 ++++------ .../06_grid_manipulation/pet_advect.ipynb | 6 +++--- .../python_module/06_grid_manipulation/pet_lavd.ipynb | 10 +++++----- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/examples/06_grid_manipulation/pet_advect.py b/examples/06_grid_manipulation/pet_advect.py index 57ee3bf3..a1df860f 100644 --- a/examples/06_grid_manipulation/pet_advect.py +++ b/examples/06_grid_manipulation/pet_advect.py @@ -104,7 +104,7 @@ def update(i_frame, t_step): # it could be run backward with `backward=True` option in filament method p = g.filament(x, y, "u", "v", **kw_p, filament_size=3) fig, txt, l, t = anim_ax(lw=0.5) -ani = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,)) +_ = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,)) # %% # Particle forward @@ -112,13 +112,13 @@ def update(i_frame, t_step): # Forward advection of particles p = g.advect(x, y, "u", "v", **kw_p) fig, txt, l, t = anim_ax(ls="", marker=".", markersize=1) -ani = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,)) +_ = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,)) # %% # We get last position and run backward until original position p = g.advect(x, y, "u", "v", **kw_p, backward=True) fig, txt, l, _ = anim_ax(ls="", marker=".", markersize=1) -ani = VideoAnimation(fig, update, **kwargs, fargs=(-frame_t,)) +_ = VideoAnimation(fig, update, **kwargs, fargs=(-frame_t,)) # %% # Particles stat diff --git a/examples/06_grid_manipulation/pet_lavd.py b/examples/06_grid_manipulation/pet_lavd.py index 8d29db9b..6e86933d 100644 --- a/examples/06_grid_manipulation/pet_lavd.py +++ b/examples/06_grid_manipulation/pet_lavd.py @@ -27,7 +27,7 @@ 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.network import NetworkObservations +from py_eddy_tracker.observations.observation import EddiesObservations # %% @@ -63,8 +63,6 @@ def _repr_html_(self, *args, **kwargs): r'width="[0-9]*"\sheight="[0-9]*"', 'width="100%" height="100%"', content ) - return - 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 @@ -150,7 +148,7 @@ def update(i_frame): # pcolorfast will be faster than pcolormesh, we could use pcolorfast due to x and y are regular pcolormesh = ax.pcolorfast(x_g_, y_g_, lavd, **kw_vorticity) update_axes(ax, pcolormesh) -ani = VideoAnimation(ax.figure, update, **kw_video) +_ = VideoAnimation(ax.figure, update, **kw_video) # %% # Final LAVD @@ -173,8 +171,8 @@ def update(i_frame): # Period used for LAVD integration (8 days) is too short for a real use, but choose for example efficiency. fig, ax, _ = start_ax() mappable = lavd.display(ax, "lavd", **kw_vorticity) -NetworkObservations.load_file(get_path("Anticyclonic_20160515.nc")).display( +EddiesObservations.load_file(get_path("Anticyclonic_20160515.nc")).display( ax, color="k" ) -NetworkObservations.load_file(get_path("Cyclonic_20160515.nc")).display(ax, color="k") +EddiesObservations.load_file(get_path("Cyclonic_20160515.nc")).display(ax, color="k") _ = update_axes(ax, mappable) diff --git a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb index fea60cd1..34a72c94 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb @@ -163,7 +163,7 @@ }, "outputs": [], "source": [ - "p = g.filament(x, y, \"u\", \"v\", **kw_p, filament_size=3)\nfig, txt, l, t = anim_ax(lw=0.5)\nani = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,))" + "p = g.filament(x, y, \"u\", \"v\", **kw_p, filament_size=3)\nfig, txt, l, t = anim_ax(lw=0.5)\n_ = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,))" ] }, { @@ -181,7 +181,7 @@ }, "outputs": [], "source": [ - "p = g.advect(x, y, \"u\", \"v\", **kw_p)\nfig, txt, l, t = anim_ax(ls=\"\", marker=\".\", markersize=1)\nani = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,))" + "p = g.advect(x, y, \"u\", \"v\", **kw_p)\nfig, txt, l, t = anim_ax(ls=\"\", marker=\".\", markersize=1)\n_ = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,))" ] }, { @@ -199,7 +199,7 @@ }, "outputs": [], "source": [ - "p = g.advect(x, y, \"u\", \"v\", **kw_p, backward=True)\nfig, txt, l, _ = anim_ax(ls=\"\", marker=\".\", markersize=1)\nani = VideoAnimation(fig, update, **kwargs, fargs=(-frame_t,))" + "p = g.advect(x, y, \"u\", \"v\", **kw_p, backward=True)\nfig, txt, l, _ = anim_ax(ls=\"\", marker=\".\", markersize=1)\n_ = VideoAnimation(fig, update, **kwargs, fargs=(-frame_t,))" ] }, { diff --git a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb index 82933787..be1a9c78 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# LAVD experiment\n\nNaive method to reproduce LAVD(Lagrangian-Averaged Vorticity deviation) method with a static velocity field.\nIn the current example we didn't remove a mean vorticity.\n\nMethod are described here:\n\n - Abernathey, Ryan, and George Haller. \"Transport by Lagrangian Vortices in the Eastern Pacific\",\n Journal of Physical Oceanography 48, 3 (2018): 667-685, accessed Feb 16, 2021,\n https://doi.org/10.1175/JPO-D-17-0102.1\n - `Transport by Coherent Lagrangian Vortices`_,\n R. Abernathey, Sinha A., Tarshish N., Liu T., Zhang C., Haller G., 2019,\n Talk a t the Sources and Sinks of Ocean Mesoscale Eddy Energy CLIVAR Workshop\n\n https://usclivar.org/sites/default/files/meetings/2019/presentations/Aberernathey_CLIVAR.pdf\n" + "\n# LAVD experiment\n\nNaive method to reproduce LAVD(Lagrangian-Averaged Vorticity deviation) method with a static velocity field.\nIn the current example we didn't remove a mean vorticity.\n\nMethod are described here:\n\n - Abernathey, Ryan, and George Haller. \"Transport by Lagrangian Vortices in the Eastern Pacific\",\n Journal of Physical Oceanography 48, 3 (2018): 667-685, accessed Feb 16, 2021,\n https://doi.org/10.1175/JPO-D-17-0102.1\n - `Transport by Coherent Lagrangian Vortices`_,\n R. Abernathey, Sinha A., Tarshish N., Liu T., Zhang C., Haller G., 2019,\n Talk a t the Sources and Sinks of Ocean Mesoscale Eddy Energy CLIVAR Workshop\n\n https://usclivar.org/sites/default/files/meetings/2019/presentations/Aberernathey_CLIVAR.pdf\n" ] }, { @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, meshgrid, zeros\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\nfrom py_eddy_tracker.observations.network import NetworkObservations" + "import re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, meshgrid, zeros\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\nfrom py_eddy_tracker.observations.observation import EddiesObservations" ] }, { @@ -48,7 +48,7 @@ }, "outputs": [], "source": [ - "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n return\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" ] }, { @@ -138,7 +138,7 @@ }, "outputs": [], "source": [ - "def update(i_frame):\n global lavd, i\n i += 1\n x, y = particule.__next__()\n # Interp vorticity on new_position\n lavd += abs(g.interp(\"vort\", x, y).reshape(original_shape) * 1 / nb_time)\n txt.set_text(f\"T0 + {i / step_by_day:.2f} days of advection\")\n pcolormesh.set_array(lavd / i * nb_time)\n return pcolormesh, txt\n\n\nkw_video = dict(frames=arange(nb_time), interval=1000.0 / step_by_day / 2, blit=True)\nfig, ax, txt = start_ax(dpi=60)\nx_g_, y_g_ = arange(0 - step / 2, 36 + step / 2, step), arange(\n 28 - step / 2, 46 + step / 2, step\n)\n# pcolorfast will be faster than pcolormesh, we could use pcolorfast due to x and y are regular\npcolormesh = ax.pcolorfast(x_g_, y_g_, lavd, **kw_vorticity)\nupdate_axes(ax, pcolormesh)\nani = VideoAnimation(ax.figure, update, **kw_video)" + "def update(i_frame):\n global lavd, i\n i += 1\n x, y = particule.__next__()\n # Interp vorticity on new_position\n lavd += abs(g.interp(\"vort\", x, y).reshape(original_shape) * 1 / nb_time)\n txt.set_text(f\"T0 + {i / step_by_day:.2f} days of advection\")\n pcolormesh.set_array(lavd / i * nb_time)\n return pcolormesh, txt\n\n\nkw_video = dict(frames=arange(nb_time), interval=1000.0 / step_by_day / 2, blit=True)\nfig, ax, txt = start_ax(dpi=60)\nx_g_, y_g_ = arange(0 - step / 2, 36 + step / 2, step), arange(\n 28 - step / 2, 46 + step / 2, step\n)\n# pcolorfast will be faster than pcolormesh, we could use pcolorfast due to x and y are regular\npcolormesh = ax.pcolorfast(x_g_, y_g_, lavd, **kw_vorticity)\nupdate_axes(ax, pcolormesh)\n_ = VideoAnimation(ax.figure, update, **kw_video)" ] }, { @@ -181,7 +181,7 @@ }, "outputs": [], "source": [ - "fig, ax, _ = start_ax()\nmappable = lavd.display(ax, \"lavd\", **kw_vorticity)\nNetworkObservations.load_file(get_path(\"Anticyclonic_20160515.nc\")).display(\n ax, color=\"k\"\n)\nNetworkObservations.load_file(get_path(\"Cyclonic_20160515.nc\")).display(ax, color=\"k\")\n_ = update_axes(ax, mappable)" + "fig, ax, _ = start_ax()\nmappable = lavd.display(ax, \"lavd\", **kw_vorticity)\nEddiesObservations.load_file(get_path(\"Anticyclonic_20160515.nc\")).display(\n ax, color=\"k\"\n)\nEddiesObservations.load_file(get_path(\"Cyclonic_20160515.nc\")).display(ax, color=\"k\")\n_ = update_axes(ax, mappable)" ] } ], From 3975a22e0d964b514d886b556af2eaec7b2ecccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Tue, 2 Mar 2021 14:29:35 +0100 Subject: [PATCH 069/249] add find_segments_relative (#59) * correction of repr when EddiesObservation is empty * fix play_timeline and event_timeline to sync colors, and one plot for event * add find_segments_relative --- CHANGELOG.rst | 4 + examples/16_network/pet_relative.py | 41 ++++ src/py_eddy_tracker/observations/network.py | 189 ++++++++++++++++-- .../observations/observation.py | 11 +- 4 files changed, 225 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 0b1a100c..dc599b80 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -17,6 +17,9 @@ Changed Fixed ^^^^^ - Use `safe_load` for yaml load +- repr of EddiesObservation when the collection is empty (time attribute empty array) +- display_timeline and event_timeline can now use colors according to 'y' values. +- event_timeline now plot all merging event in one plot, instead of one plot per merging. Same for splitting. (avoid bad legend) Added ^^^^^ @@ -28,6 +31,7 @@ Added - Save EddyAnim in mp4 - Add method to get eddy contour which enclosed obs defined with (x,y) coordinates - Add **EddyNetworkSubSetter** to subset network which need special tool and operation after subset +- Add functions to find relatives segments [3.3.0] - 2020-12-03 -------------------- diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index 4a57062a..affdf44b 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -3,7 +3,10 @@ ========================== """ +import datetime + from matplotlib import pyplot as plt +from matplotlib.ticker import FuncFormatter import py_eddy_tracker.gui from py_eddy_tracker import data @@ -186,6 +189,44 @@ ax.set_title(f"Close segments ({close_to_i3.infos()})") _ = close_to_i3.display_timeline(ax) +# %% +# Keep relatives to an event +# -------------------------- +# When you want to investigate one particular event and select only the closest segments +# +# First choose an event in the network +after, before, stopped = n.merging_event(triplet=True, only_index=True) +i_event = 5 +# %% +# then see some order of relatives +@FuncFormatter +def formatter(x, pos): + return (datetime.timedelta(x) + datetime.datetime(1950, 1, 1)).strftime("%d/%m/%Y") + + +max_order = 2 +fig, axs = plt.subplots( + max_order + 2, 1, sharex=True, figsize=(15, 5 * (max_order + 2)) +) + +axs[0].set_title(f"full network", weight="bold") +axs[0].xaxis.set_major_formatter(formatter), axs[0].grid() +mappables = n.display_timeline(axs[0], colors_mode="y") +axs[0].legend() + +for k in range(0, max_order + 1): + + ax = axs[k + 1] + sub_network = n.find_segments_relative(after[i_event], stopped[i_event], order=k) + + ax.set_title(f"relatives order={k}", weight="bold") + ax.xaxis.set_major_formatter(formatter), ax.grid() + + mappables = sub_network.display_timeline(ax, colors_mode="y") + ax.legend() + _ = ax.set_ylim(axs[0].get_ylim()) + + # %% # Display track on map # -------------------- diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 8989c01f..486f454f 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -6,7 +6,18 @@ from glob import glob from numba import njit -from numpy import arange, array, bincount, empty, in1d, ones, uint32, unique, zeros +from numpy import ( + arange, + array, + bincount, + empty, + in1d, + ones, + uint32, + unique, + where, + zeros, +) from ..generic import build_index, wrap_longitude from ..poly import bbox_intersection, vertice_overlap @@ -71,6 +82,32 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._index_network = None + def find_segments_relative(self, obs, stopped=None, order=1): + """ + find all relative segments within an event from an order. + + :param int obs: indice of event after the event + :param int stopped: indice of event before the event + :param int order: order of relatives accepted + + :return: all segments relatives + :rtype: EddiesObservations + """ + + # extraction of network where the event is + network_id = self.tracks[obs] + nw = self.network(network_id) + + # indice of observation in new subnetwork + i_obs = where(nw.segment == self.segment[obs])[0][0] + + if stopped is None: + return nw.relatives(i_obs, order=order) + + else: + i_stopped = where(nw.segment == self.segment[stopped])[0][0] + return nw.relatives([i_obs, i_stopped], order=order) + @property def index_network(self): if self._index_network is None: @@ -229,12 +266,38 @@ def segment_relative_order(self, seg_origine): def relative(self, i_obs, order=2, direct=True, only_past=False, only_future=False): """ - Extract the segments at a certain order. + Extract the segments at a certain order from one observation. + + :param list obs: indice of observation for relative computation + :param int order: order of relatives wanted. 0 means only observations in obs, 1 means direct relatives, ... + + :return: all segments relatives + :rtype: EddiesObservations """ + d = self.segment_relative_order(self.segment[i_obs]) m = (d <= order) * (d != -1) return self.extract_with_mask(m) + def relatives(self, obs, order=2, direct=True, only_past=False, only_future=False): + """ + Extract the segments at a certain order from multiple observations. + + :param list obs: indices of observation for relatives computation + :param int order: order of relatives wanted. 0 means only observations in obs, 1 means direct relatives, ... + + :return: all segments relatives + :rtype: EddiesObservations + """ + + mask = zeros(self.segment.shape, dtype=bool) + + for i_obs in obs: + d = self.segment_relative_order(self.segment[i_obs]) + mask += (d <= order) * (d != -1) + + return self.extract_with_mask(mask) + def numbering_segment(self): """ New numbering of segment @@ -278,7 +341,14 @@ def median_filter(self, half_window, xfield, yfield, inplace=True): return result def display_timeline( - self, ax, event=True, field=None, method=None, factor=1, **kwargs + self, + ax, + event=True, + field=None, + method=None, + factor=1, + colors_mode="roll", + **kwargs, ): """ Plot a timeline of a network. @@ -289,6 +359,7 @@ def display_timeline( :param str,array field: yaxis values, if None, segments are used :param str method: if None, mean values are used :param float factor: to multiply field + :param str colors_mode: color of lines. "roll" means looping through colors, "y" means color adapt the y values (for matching color plots) :return: plot mappable """ self.only_one_network() @@ -302,9 +373,16 @@ def display_timeline( ) line_kw.update(kwargs) mappables = dict(lines=list()) + if event: mappables.update( - self.event_timeline(ax, field=field, method=method, factor=factor) + self.event_timeline( + ax, + field=field, + method=method, + factor=factor, + colors_mode=colors_mode, + ) ) for i, b0, b1 in self.iter_on("segment"): x = self.time[i] @@ -317,14 +395,25 @@ def display_timeline( y = self[field][i] * factor else: y = self[field][i].mean() * ones(x.shape) * factor - line = ax.plot(x, y, **line_kw, color=self.COLORS[j % self.NB_COLORS])[0] + + if colors_mode == "roll": + _color = self.get_color(j) + elif colors_mode == "y": + _color = self.get_color(b0 - 1) + else: + raise NotImplementedError(f"colors_mode '{colors_mode}' not defined") + + line = ax.plot(x, y, **line_kw, color=_color)[0] mappables["lines"].append(line) j += 1 return mappables - def event_timeline(self, ax, field=None, method=None, factor=1): + def event_timeline(self, ax, field=None, method=None, factor=1, colors_mode="roll"): + """mark events in plot""" j = 0 + events = dict(spliting=[], merging=[]) + # TODO : fill mappables dict y_seg = dict() if field is not None and method != "all": @@ -337,7 +426,16 @@ def event_timeline(self, ax, field=None, method=None, factor=1): x = self.time[i] if x.shape[0] == 0: continue - event_kw = dict(color=self.COLORS[j % self.NB_COLORS], ls="-", zorder=1) + + if colors_mode == "roll": + _color = self.get_color(j) + elif colors_mode == "y": + _color = self.get_color(b0 - 1) + else: + raise NotImplementedError(f"colors_mode '{colors_mode}' not defined") + + event_kw = dict(color=_color, ls="-", zorder=1) + i_n, i_p = ( self.next_obs[i.stop - 1], self.previous_obs[i.start], @@ -361,7 +459,8 @@ def event_timeline(self, ax, field=None, method=None, factor=1): ) ) ax.plot((x[-1], self.time[i_n]), (y0, y1), **event_kw)[0] - ax.plot(x[-1], y0, color="k", marker="H", markersize=10, zorder=-1)[0] + events["merging"].append((x[-1], y0)) + if i_p != -1: seg_previous = self.segment[i_p] if field is not None and method == "all": @@ -376,8 +475,25 @@ def event_timeline(self, ax, field=None, method=None, factor=1): ) ) ax.plot((x[0], self.time[i_p]), (y0, y1), **event_kw)[0] - ax.plot(x[0], y0, color="k", marker="*", markersize=12, zorder=-1)[0] + events["spliting"].append((x[0], y0)) + j += 1 + + kwargs = dict(color="k", zorder=-1, linestyle=" ") + if len(events["spliting"]) > 0: + X, Y = list(zip(*events["spliting"])) + ref = ax.plot( + X, Y, marker="*", markersize=12, label="spliting events", **kwargs + )[0] + mappables.setdefault("events", []).append(ref) + + if len(events["merging"]) > 0: + X, Y = list(zip(*events["merging"])) + ref = ax.plot( + X, Y, marker="H", markersize=10, label="merging events", **kwargs + )[0] + mappables.setdefault("events", []).append(ref) + return mappables def mean_by_segment(self, y, **kw): @@ -404,15 +520,40 @@ def map_segment(self, method, y, same=True, **kw): out = array(out) return out - def map_network(self, method, y, same=True, **kw): + def map_network(self, method, y, same=True, return_dict=False, **kw): + """ + transform data `y` with method `method` for each track. + + :param Callable method: method to apply on each tracks + :param np.array y: data where to apply method + :param bool same: if True, return array same size from y. else, return list with track edited + :param bool return_dict: if None, mean values are used + :param float kw: to multiply field + :return: array or dict of result from method for each network + """ + + if same and return_dict: + raise NotImplementedError( + "both condition 'same' and 'return_dict' should no be true" + ) + if same: out = empty(y.shape, **kw) + + elif return_dict: + out = dict() + else: out = list() + for i, b0, b1 in self.iter_on(self.track): res = method(y[i]) if same: out[i] = res + + elif return_dict: + out[b0] = res + else: if isinstance(i, slice): if i.start == i.stop: @@ -420,7 +561,8 @@ def map_network(self, method, y, same=True, **kw): elif len(i) == 0: continue out.append(res) - if not same: + + if not same and not return_dict: out = array(out) return out @@ -588,7 +730,7 @@ def death_event(self): indices.append(i.stop - 1) return self.extract_event(list(set(indices))) - def merging_event(self, triplet=False): + def merging_event(self, triplet=False, only_index=False): """Return observation after a merging event. If `triplet=True` return the eddy after a merging event, the eddy before the merging event, @@ -611,13 +753,24 @@ def merging_event(self, triplet=False): idx_m1.append(i_n) if triplet: - return ( - self.extract_event(list(idx_m1)), - self.extract_event(list(idx_m0)), - self.extract_event(list(idx_m0_stop)), - ) + if only_index: + return ( + idx_m1, + idx_m0, + idx_m0_stop, + ) + + else: + return ( + self.extract_event(idx_m1), + self.extract_event(idx_m0), + self.extract_event(idx_m0_stop), + ) else: - return self.extract_event(list(set(idx_m1))) + if only_index: + return self.extract_event(set(idx_m1)) + else: + return list(set(idx_m1)) def spliting_event(self, triplet=False): """Return observation before a splitting event. diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 6920659e..3def4464 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -200,6 +200,10 @@ def __eq__(self, other): return False return array_equal(self.obs, other.obs) + ### colors methods + def get_color(self, i): + return self.COLORS[i % self.NB_COLORS] + @property def sign_legend(self): return "Cyclonic" if self.sign_type != 1 else "Anticyclonic" @@ -2120,13 +2124,16 @@ def interp_grid( @property def period(self): """ - Give the time coverage + Give the time coverage. If collection is empty, return nan,nan :return: first and last date :rtype: (int,int) """ if self.period_ is None: - self.period_ = self.time.min(), self.time.max() + if self.time.size < 1: + self.period_ = nan, nan + else: + self.period_ = self.time.min(), self.time.max() return self.period_ @property From faba22c273069ba1ed8f823649b83c518a672c11 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Thu, 4 Mar 2021 11:01:16 +0100 Subject: [PATCH 070/249] =?UTF-8?q?Add=20option=20to=20EddyQuickCompare=20?= =?UTF-8?q?to=20have=20information=20in=20Mkm=C2=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/py_eddy_tracker/appli/eddies.py | 73 ++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 23 deletions(-) diff --git a/src/py_eddy_tracker/appli/eddies.py b/src/py_eddy_tracker/appli/eddies.py index 603183d4..445145d4 100644 --- a/src/py_eddy_tracker/appli/eddies.py +++ b/src/py_eddy_tracker/appli/eddies.py @@ -399,25 +399,27 @@ def get_group( i1_multi = i1_[nb1 >= 2] i2_multi = i2_[nb2 >= 2] m_multi = in1d(i1, i1_multi) + in1d(i2, i2_multi) - group1["multi_match"] = unique(i1[m_multi]) - group2["multi_match"] = unique(i2[m_multi]) # Low scores - m_low = score <= low + m_low = score < low m_low *= ~m_multi group1["low"] = i1[m_low] group2["low"] = i2[m_low] # Intermediate scores - m_i = (score > low) * (score <= high) + m_i = (score >= low) * (score < high) m_i *= ~m_multi group1["intermediate"] = i1[m_i] group2["intermediate"] = i2[m_i] # High scores - m_high = score > high + m_high = score >= high m_high *= ~m_multi group1["high"] = i1[m_high] group2["high"] = i2[m_high] + # Here for a nice display order + group1["multi_match"] = unique(i1[m_multi]) + group2["multi_match"] = unique(i2[m_multi]) + def get_twin(j2, j1): # True only if j1 is used only one m = bincount(j1)[j1] == 1 @@ -449,6 +451,11 @@ def quick_compare(): ) parser.add_argument("ref", help="Identification file of reference") parser.add_argument("others", nargs="+", help="Identifications files to compare") + parser.add_argument( + "--area", + action="store_true", + help="Display in percent of area instead percent of observation", + ) parser.add_argument("--high", default=40, type=float) parser.add_argument("--low", default=20, type=float) parser.add_argument("--invalid", default=5, type=float) @@ -461,6 +468,8 @@ def quick_compare(): *EddiesObservations.intern(args.intern, public_label=True), ] ) + if args.area: + kw["include_vars"].append("speed_area" if args.intern else "effective_area") ref = EddiesObservations.load_file(args.ref, **kw) print(f"[ref] {args.ref} -> {len(ref)} obs") @@ -484,28 +493,46 @@ def display(value, ref=None): outs = list() for v in value: if ref: - outs.append(f"{v/ref * 100:.1f}% ({v})") + if args.area: + outs.append(f"{v / ref * 100:.1f}% ({v:.1f}Mkm²)") + else: + outs.append(f"{v/ref * 100:.1f}% ({v})") else: outs.append(v) - return "".join([f"{v:^15}" for v in outs]) + if args.area: + return "".join([f"{v:^16}" for v in outs]) + else: + return "".join([f"{v:^15}" for v in outs]) - keys = list(gr1.keys()) + def get_values(v, dataset): + if args.area: + area = dataset["speed_area" if args.intern else "effective_area"] + return [area[v_].sum() / 1e12 for v_ in v.values()] + else: + return [ + v_.sum() if v_.dtype == "bool" else v_.shape[0] for v_ in v.values() + ] + + labels = dict( + high=f"{args.high:0.0f} <= high", + low=f"{args.invalid:0.0f} <= low < {args.low:0.0f}", + ) + + keys = [labels.get(key, key) for key in gr1.keys()] print(" ", display(keys)) + if args.area: + ref_ = ref["speed_area" if args.intern else "effective_area"].sum() / 1e12 + else: + ref_ = len(ref) for i, v in enumerate(groups_ref.values()): - print( - f"[{i:2}] ", - display( - (v_.sum() if v_.dtype == "bool" else v_.shape[0] for v_ in v.values()), - ref=len(ref), - ), - ) + print(f"[{i:2}] ", display(get_values(v, ref), ref=ref_)) - print(display(keys)) + print(" Point of view of study dataset") + print(" ", display(keys)) for i, (k, v) in enumerate(groups_other.items()): - print( - f"[{i:2}] ", - display( - (v_.sum() if v_.dtype == "bool" else v_.shape[0] for v_ in v.values()), - ref=len(others[k]), - ), - ) + other = others[k] + if args.area: + ref_ = other["speed_area" if args.intern else "effective_area"].sum() / 1e12 + else: + ref_ = len(other) + print(f"[{i:2}] ", display(get_values(v, other), ref=ref_)) From 215fc9c17b2a579d3f5188bf5b4081181a1797d4 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Thu, 4 Mar 2021 11:03:47 +0100 Subject: [PATCH 071/249] Get close network in another atlas --- CHANGELOG.rst | 4 ++- src/py_eddy_tracker/observations/network.py | 29 ++++++++++++++++++- .../observations/observation.py | 17 ++++++++++- src/py_eddy_tracker/observations/tracking.py | 7 ----- 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index dc599b80..56f773e1 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -31,7 +31,9 @@ Added - Save EddyAnim in mp4 - Add method to get eddy contour which enclosed obs defined with (x,y) coordinates - Add **EddyNetworkSubSetter** to subset network which need special tool and operation after subset -- Add functions to find relatives segments +- Network: + - Add method to find relatives segments + - Add method to get cloase network in an other atlas [3.3.0] - 2020-12-03 -------------------- diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 486f454f..346bbf9f 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -10,6 +10,7 @@ arange, array, bincount, + concatenate, empty, in1d, ones, @@ -298,6 +299,30 @@ def relatives(self, obs, order=2, direct=True, only_past=False, only_future=Fals return self.extract_with_mask(mask) + def close_network(self, other, nb_obs_min=10, **kwargs): + """ + Get close network from another atlas. + + :param self other: Atlas to compare + :param int nb_obs_min: Minimal number of overlap for one trajectory + :param dict kwargs: keyword arguments for match function + :return: return other atlas reduce to common track with self + + .. warning:: + It could be a costly operation for huge dataset + """ + p0, p1 = self.period + indexs = list() + for i_self, i_other, t0, t1 in self.align_on(other, bins=range(p0, p1 + 2)): + i, j, s = self.index(i_self).match(other.index(i_other), **kwargs) + indexs.append(other.re_reference_index(j, i_other)) + indexs = concatenate(indexs) + tr, nb = unique(other.track[indexs], return_counts=True) + m = zeros(other.track.shape, dtype=bool) + for i in tr[nb >= nb_obs_min]: + m[other.network_slice(i)] = True + return other.extract_with_mask(m) + def numbering_segment(self): """ New numbering of segment @@ -359,7 +384,9 @@ def display_timeline( :param str,array field: yaxis values, if None, segments are used :param str method: if None, mean values are used :param float factor: to multiply field - :param str colors_mode: color of lines. "roll" means looping through colors, "y" means color adapt the y values (for matching color plots) + :param str colors_mode: + color of lines. "roll" means looping through colors, + "y" means color adapt the y values (for matching color plots) :return: plot mappable """ self.only_one_network() diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 3def4464..7d2bad50 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -200,8 +200,8 @@ def __eq__(self, other): return False return array_equal(self.obs, other.obs) - ### colors methods def get_color(self, i): + """Return colors like a cyclic list""" return self.COLORS[i % self.NB_COLORS] @property @@ -1076,6 +1076,21 @@ def match(self, other, method="overlap", intern=False, cmin=0, **kwargs): m = c >= cmin # ajout >= pour garder la cmin dans la sélection return i[m], j[m], c[m] + @staticmethod + def re_reference_index(index, ref): + """ + Shift index with ref + + :param array,int index: local index to re ref + :param slice,array ref: + reference could be a slice in this case we juste add start to index + or could be indexs and in this case we need to translate + """ + if isinstance(ref, slice): + return index + ref.start + else: + return ref[index] + @classmethod def cost_function_common_area(cls, xy_in, xy_out, distance, intern=False): """How does it work on x bound ? diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index 685b1427..f20d4250 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -516,13 +516,6 @@ def extract_with_mask( new.track = id_translate[new.track] return new - @staticmethod - def re_reference_index(index, ref): - if isinstance(ref, slice): - return index + ref.start - else: - return ref[index] - def shape_polygon(self, intern=False): """ Get the polygon enclosing each trajectory. From 9fc061f02f9409a1f096d59ffa2bd8febe694f4a Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Thu, 4 Mar 2021 11:13:22 +0100 Subject: [PATCH 072/249] Give acces at txt option in EddyAnim --- src/py_eddy_tracker/appli/gui.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/py_eddy_tracker/appli/gui.py b/src/py_eddy_tracker/appli/gui.py index e9ff7f7a..a0b00468 100644 --- a/src/py_eddy_tracker/appli/gui.py +++ b/src/py_eddy_tracker/appli/gui.py @@ -263,6 +263,7 @@ def anim(): parser.add_argument( "--field", default="time", help="Field use to color contour instead of time" ) + parser.add_argument("--txt_field", default="track", help="Field use to text eddy") parser.add_argument( "--vmin", default=None, type=float, help="Inferior bound to color contour" ) @@ -271,7 +272,9 @@ def anim(): ) parser.add_argument("--mp4", help="Filename to save animation (mp4)") args = parser.parse_args() - variables = ["time", "track", "longitude", "latitude", args.field] + variables = list( + set(["time", "track", "longitude", "latitude", args.field, args.txt_field]) + ) variables.extend(TrackEddiesObservations.intern(args.intern, public_label=True)) eddies = TrackEddiesObservations.load_file( @@ -302,6 +305,7 @@ def anim(): cmap=args.cmap, nb_step=args.keep_step, field_color=args.field, + field_txt=args.txt_field, range_color=(args.vmin, args.vmax), graphic_information=logger.getEffectiveLevel() == logging.DEBUG, **kw, From 938e279cc51e1b8acc95bc341955f277ef4b6ad7 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Thu, 4 Mar 2021 14:18:14 +0100 Subject: [PATCH 073/249] method change to speed up close track research --- src/py_eddy_tracker/observations/network.py | 2 +- .../observations/observation.py | 102 +++++++++++++----- src/py_eddy_tracker/observations/tracking.py | 2 +- 3 files changed, 79 insertions(+), 27 deletions(-) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 346bbf9f..6bba78bf 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -314,7 +314,7 @@ def close_network(self, other, nb_obs_min=10, **kwargs): p0, p1 = self.period indexs = list() for i_self, i_other, t0, t1 in self.align_on(other, bins=range(p0, p1 + 2)): - i, j, s = self.index(i_self).match(other.index(i_other), **kwargs) + i, j, s = self.match(other, i_self=i_self, i_other=i_other, **kwargs) indexs.append(other.re_reference_index(j, i_other)) indexs = concatenate(indexs) tr, nb = unique(other.track[indexs], return_counts=True) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 7d2bad50..351952b5 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -488,8 +488,7 @@ def iter_on(self, xname, bins=None): :param str,array xname: :param array bins: bounds of each bin , - :return: Group observations - :rtype: self.__class__ + :return: index or mask, bound low, bound up """ x = self[xname] if isinstance(xname, str) else xname d = x[1:] - x[:-1] @@ -498,10 +497,18 @@ def iter_on(self, xname, bins=None): elif not isinstance(bins, ndarray): bins = array(bins) nb_bins = len(bins) - 1 - i = numba_digitize(x, bins) - 1 + # Not monotonous if (d < 0).any(): + # If bins cover a small part of value + test, translate, x = iter_mode_reduce(x, bins) + # convert value in bins number + i = numba_digitize(x, bins) - 1 + # Order by bins i_sort = i.argsort() + # If in reduce mode we will translate i_sort in full array index + i_sort_ = translate[i_sort] if test else i_sort + # Bound for each bins in sorting view i0, i1, _ = build_index(i[i_sort]) m = ~(i0 == i1) i0, i1 = i0[m], i1[m] @@ -509,8 +516,9 @@ def iter_on(self, xname, bins=None): i_bins = i[i_sort[i0_]] if i_bins == -1 or i_bins == nb_bins: continue - yield i_sort[i0_:i1_], bins[i_bins], bins[i_bins + 1] + yield i_sort_[i0_:i1_], bins[i_bins], bins[i_bins + 1] else: + i = numba_digitize(x, bins) - 1 i0, i1, _ = build_index(i) m = ~(i0 == i1) i0, i1 = i0[m], i1[m] @@ -522,10 +530,8 @@ def align_on(self, other, var_name="time", **kwargs): """ Align the time indexes of two datasets. """ - iter_self, iter_other = ( - self.iter_on(var_name, **kwargs), - other.iter_on(var_name, **kwargs), - ) + iter_self = self.iter_on(var_name, **kwargs) + iter_other = other.iter_on(var_name, **kwargs) indexs_other, b0_other, b1_other = iter_other.__next__() for indexs_self, b0_self, b1_self in iter_self: if b0_self > b0_other: @@ -1038,10 +1044,23 @@ def intern(flag, public_label=False): labels = [VAR_DESCR[label]["nc_name"] for label in labels] return labels - def match(self, other, method="overlap", intern=False, cmin=0, **kwargs): + def match( + self, + other, + i_self=None, + i_other=None, + method="overlap", + intern=False, + cmin=0, + **kwargs, + ): """Return index and score computed on the effective contour. :param EddiesObservations other: Observations to compare + :param array[bool,int],None i_self: + Index or mask to subset observations, it could avoid to build a specific dataset. + :param array[bool,int],None i_other: + Index or mask to subset observations, it could avoid to build a specific dataset. :param str method: - "overlap": the score is computed with contours; - "circle": circles are computed and used for score (TODO) @@ -1054,25 +1073,20 @@ def match(self, other, method="overlap", intern=False, cmin=0, **kwargs): .. minigallery:: py_eddy_tracker.EddiesObservations.match """ - # if method is "overlap" method will use contour to compute score, - # if method is "circle" method will apply a formula of circle overlap x_name, y_name = self.intern(intern) + if i_self is None: + i_self = slice(None) + if i_other is None: + i_other = slice(None) if method == "overlap": - i, j = bbox_intersection( - self[x_name], self[y_name], other[x_name], other[y_name] - ) - c = vertice_overlap( - self[x_name][i], - self[y_name][i], - other[x_name][j], - other[y_name][j], - **kwargs, - ) + x0, y0 = self[x_name][i_self], self[y_name][i_self] + x1, y1 = other[x_name][i_other], other[y_name][i_other] + i, j = bbox_intersection(x0, y0, x1, y1) + c = vertice_overlap(x0[i], y0[i], x1[j], y1[j], **kwargs) elif method == "close_center": - i, j, c = close_center( - self.latitude, self.longitude, other.latitude, other.longitude, **kwargs - ) - + x0, y0 = self.longitude[i_self], self.latitude[i_self] + x1, y1 = other.longitude[i_other], other.latitude[i_other] + i, j, c = close_center(x0, y0, x1, y1, **kwargs) m = c >= cmin # ajout >= pour garder la cmin dans la sélection return i[m], j[m], c[m] @@ -2438,3 +2452,41 @@ def numba_digitize(values, bins): continue out[i] = (v_ - bins[0]) / step + 1 return out + + +@njit(cache=True) +def iter_mode_reduce(x, bins): + """ + Test if we could use a reduce mode + + :param array x: array to divide in group + :param array bins: array which defined bounds between each group + :return: If reduce mode, translator, and reduce x + """ + nb = x.shape[0] + # If we use less than half value + limit = nb // 2 + # low and up + x0, x1 = bins[0], bins[-1] + m = empty(nb, dtype=numba_types.bool_) + # To count number of value cover by bins + c = 0 + for i in range(nb): + x_ = x[i] + test = (x_ >= x0) * (x_ <= x1) + m[i] = test + if test: + c += 1 + # If number value exceed limit + if c > limit: + return False, empty(0, dtype=numba_types.int_), x + # Indices to be able to translate in full index array + indices = empty(c, dtype=numba_types.int_) + x_ = empty(c, dtype=x.dtype) + j = 0 + for i in range(nb): + if m[i]: + indices[j] = i + x_[j] = x[i] + j += 1 + return True, indices, x_ diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index f20d4250..6a716622 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -570,7 +570,7 @@ def close_tracks(self, other, nb_obs_min=10, **kwargs): p0, p1 = self.period indexs = list() for i_self, i_other, t0, t1 in self.align_on(other, bins=range(p0, p1 + 2)): - i, j, s = self.index(i_self).match(other.index(i_other), **kwargs) + i, j, s = self.match(other, i_self=i_self, i_other=i_other, **kwargs) indexs.append(other.re_reference_index(j, i_other)) indexs = concatenate(indexs) tr, nb = unique(other.track[indexs], return_counts=True) From 64b92c0f2cf1664bd37ba60de8b7e5c51220ceb4 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Thu, 4 Mar 2021 14:23:51 +0100 Subject: [PATCH 074/249] Could specify mask to be able to inactiv some particle --- src/py_eddy_tracker/dataset/grid.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 96abbea7..c0c70325 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -2369,6 +2369,7 @@ def advect( u_name, v_name, t_init, + mask_particule=None, nb_step=10, time_step=600, rk4=True, @@ -2391,7 +2392,10 @@ def advect( t1 = t1 * 86400 t = t_init * 86400 advect_ = advect_t_rk4 if rk4 else advect_t - mp = isnan(x) + isnan(y) + if mask_particule is None: + mask_particule = isnan(x) + isnan(y) + else: + mask_particule += isnan(x) + isnan(y) while True: if (backward and t <= t1) or (not backward and t >= t1): t0, u0, v0, m0 = t1, u1, v1, m1 @@ -2400,7 +2404,21 @@ def advect( u1, v1, m1 = d1.uv_for_advection(u_name, v_name, time_step, **kw) w = 1 - (arange(t, t + dt, t_step) - t0) / (t1 - t0) half_w = t_step / 2.0 / (t1 - t0) - advect_(d0.x_c, d0.y_c, u0, v0, m0, u1, v1, m1, x, y, mp, w, half_w=half_w) + advect_( + d0.x_c, + d0.y_c, + u0, + v0, + m0, + u1, + v1, + m1, + x, + y, + mask_particule, + w, + half_w=half_w, + ) t += dt yield t, x, y From 90537462e1c89ea207523e0b4c7ae4e49a19f99b Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Fri, 5 Mar 2021 09:30:04 +0100 Subject: [PATCH 075/249] update gui to allow more custom drawing --- src/py_eddy_tracker/appli/gui.py | 131 ++++++++++++++++++------------- 1 file changed, 78 insertions(+), 53 deletions(-) diff --git a/src/py_eddy_tracker/appli/gui.py b/src/py_eddy_tracker/appli/gui.py index a0b00468..d4d9d542 100644 --- a/src/py_eddy_tracker/appli/gui.py +++ b/src/py_eddy_tracker/appli/gui.py @@ -9,6 +9,7 @@ from matplotlib import pyplot from matplotlib.animation import FuncAnimation +from matplotlib.axes import Axes from matplotlib.collections import LineCollection from numpy import arange, where @@ -36,6 +37,8 @@ def __init__( self.field_color = None self.field_txt = None self.time_field = False + self.txt = None + self.ax = None self.setup(**kwargs) def setup( @@ -47,41 +50,55 @@ def setup( range_color=(None, None), nb_step=25, figsize=(8, 6), + position=(0.05, 0.05, 0.9, 0.9), **kwargs, ): - self.field_color = self.eddy[field_color].astype("f4") - self.field_txt = self.eddy[field_txt] - rg = range_color - if rg[0] is None and rg[1] is None and field_color == "time": - self.time_field = True - else: - rg = ( - self.field_color.min() if rg[0] is None else rg[0], - self.field_color.max() if rg[1] is None else rg[1], - ) - self.field_color = (self.field_color - rg[0]) / (rg[1] - rg[0]) - - self.colors = pyplot.get_cmap(cmap, lut=lut) + # To text each visible eddy + if field_txt: + self.field_txt = self.eddy[field_txt] + if field_color: + # To color each visible eddy + self.field_color = self.eddy[field_color].astype("f4") + rg = range_color + if rg[0] is None and rg[1] is None and field_color == "time": + self.time_field = True + else: + rg = ( + self.field_color.min() if rg[0] is None else rg[0], + self.field_color.max() if rg[1] is None else rg[1], + ) + self.field_color = (self.field_color - rg[0]) / (rg[1] - rg[0]) + self.colors = pyplot.get_cmap(cmap, lut=lut) self.nb_step = nb_step - x_min, x_max = self.x_core.min() - 2, self.x_core.max() + 2 - d_x = x_max - x_min - y_min, y_max = self.y_core.min() - 2, self.y_core.max() + 2 - d_y = y_max - y_min # plot - self.fig = pyplot.figure(figsize=figsize, **kwargs) + if "figure" in kwargs: + self.fig = kwargs.pop("figure") + else: + self.fig = pyplot.figure(figsize=figsize, **kwargs) t0, t1 = self.period self.fig.suptitle(f"{t0} -> {t1}") - self.ax = self.fig.add_axes((0.05, 0.05, 0.9, 0.9), projection="full_axes") - self.ax.set_xlim(x_min, x_max), self.ax.set_ylim(y_min, y_max) - self.ax.set_aspect("equal") - self.ax.grid() - # init mappable - self.txt = self.ax.text(x_min + 0.05 * d_x, y_min + 0.05 * d_y, "", zorder=10) + if isinstance(position, Axes): + self.ax = position + else: + x_min, x_max = self.x_core.min() - 2, self.x_core.max() + 2 + d_x = x_max - x_min + y_min, y_max = self.y_core.min() - 2, self.y_core.max() + 2 + d_y = y_max - y_min + self.ax = self.fig.add_axes(position, projection="full_axes") + self.ax.set_xlim(x_min, x_max), self.ax.set_ylim(y_min, y_max) + self.ax.set_aspect("equal") + self.ax.grid() + self.txt = self.ax.text( + x_min + 0.05 * d_x, y_min + 0.05 * d_y, "", zorder=10 + ) self.segs = list() self.t_segs = list() self.c_segs = list() - self.contour = LineCollection([], zorder=1) + if field_color is None: + self.contour = LineCollection([], zorder=1, color="gray") + else: + self.contour = LineCollection([], zorder=1) self.ax.add_collection(self.contour) self.fig.canvas.draw() @@ -148,29 +165,33 @@ def func_animation(self, frame): def update(self): m = self.t == self.now + color = self.field_color is not None if m.sum(): segs = list() t = list() c = list() for i in where(m)[0]: segs.append(create_vertice(self.x[i], self.y[i])) - c.append(self.field_color[i]) + if color: + c.append(self.field_color[i]) t.append(self.now) self.segs.append(segs) - self.c_segs.append(c) + if color: + self.c_segs.append(c) self.t_segs.append(t) self.contour.set_paths(chain(*self.segs)) - if self.time_field: - self.contour.set_color( - self.colors( - [ - (self.nb_step - self.now + i) / self.nb_step - for i in chain(*self.c_segs) - ] + if color: + if self.time_field: + self.contour.set_color( + self.colors( + [ + (self.nb_step - self.now + i) / self.nb_step + for i in chain(*self.c_segs) + ] + ) ) - ) - else: - self.contour.set_color(self.colors(list(chain(*self.c_segs)))) + else: + self.contour.set_color(self.colors(list(chain(*self.c_segs)))) # linewidth will be link to time delay self.contour.set_lw( [ @@ -179,28 +200,32 @@ def update(self): ] ) # Update date txt and info - txt = f"{(timedelta(int(self.now)) + datetime(1950,1,1)).strftime('%Y/%m/%d')}" - if self.graphic_informations: - txt += f"- {1/self.sleep_event:.0f} frame/s" - self.txt.set_text(txt) + if self.txt is not None: + txt = f"{(timedelta(int(self.now)) + datetime(1950,1,1)).strftime('%Y/%m/%d')}" + if self.graphic_informations: + txt += f"- {1/self.sleep_event:.0f} frame/s" + self.txt.set_text(txt) + self.ax.draw_artist(self.txt) # Update id txt - for i in where(m)[0]: - mappable = self.ax.text( - self.x_core[i], - self.y_core[i], - self.field_txt[i], - fontsize=12, - fontweight="demibold", - ) - self.mappables.append(mappable) - self.ax.draw_artist(mappable) + if self.field_txt is not None: + for i in where(m)[0]: + mappable = self.ax.text( + self.x_core[i], + self.y_core[i], + self.field_txt[i], + fontsize=12, + fontweight="demibold", + ) + self.mappables.append(mappable) + self.ax.draw_artist(mappable) self.ax.draw_artist(self.contour) - self.ax.draw_artist(self.txt) + # Remove first segment to keep only T contour if len(self.segs) > self.nb_step: self.segs.pop(0) self.t_segs.pop(0) - self.c_segs.pop(0) + if color: + self.c_segs.pop(0) def draw_contour(self): # select contour for this time step From f50a9ae358b478e3716b510fb55b3d19dc375ab8 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Fri, 5 Mar 2021 09:31:55 +0100 Subject: [PATCH 076/249] Add method to a re numbering of network like segment --- src/py_eddy_tracker/observations/network.py | 12 +++++++++--- src/py_eddy_tracker/observations/observation.py | 8 ++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 6bba78bf..dd6e9857 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -323,13 +323,19 @@ def close_network(self, other, nb_obs_min=10, **kwargs): m[other.network_slice(i)] = True return other.extract_with_mask(m) - def numbering_segment(self): + def numbering_segment(self, start=0): """ New numbering of segment """ for i, _, _ in self.iter_on("track"): new_numbering(self.segment[i]) + def numbering_network(self, start=1): + """ + New numbering of network + """ + new_numbering(self.track, start) + def only_one_network(self): """ Raise a warning or error? @@ -1169,10 +1175,10 @@ def build_unique_array(id1, id2): @njit(cache=True) -def new_numbering(segs): +def new_numbering(segs, start=0): nb = len(segs) s0 = segs[0] - j = 0 + j = start for i in range(nb): if segs[i] != s0: s0 = segs[i] diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 351952b5..d1edf4b0 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -777,10 +777,10 @@ def copy_data_to_zarr( :param zarr_dataset handler_zarr: :param array handler_eddies: :param slice zarr_dataset sl_obs: - :param int zarr_dataset buffer_size: - :param float zarr_dataset factor: - :param bool zarr_dataset raw_data: - :param None,float zarr_dataset scale_factor: + :param int buffer_size: + :param float factor: + :param bool raw_data: + :param None,float scale_factor: :param None,float add_offset: """ i_start, i_stop = sl_obs.start, sl_obs.stop From b7aa15ee75ee5f28495afac42b8b6288799d2ce0 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Fri, 5 Mar 2021 19:26:29 +0100 Subject: [PATCH 077/249] Change to get remote data for network example --- examples/16_network/pet_ioannou_2017_case.py | 21 +- examples/16_network/pet_relative.py | 1 - .../16_network/pet_ioannou_2017_case.ipynb | 274 ++++++++++++++++++ src/py_eddy_tracker/data/__init__.py | 20 +- src/py_eddy_tracker/observations/network.py | 20 +- .../observations/observation.py | 4 +- 6 files changed, 313 insertions(+), 27 deletions(-) create mode 100644 notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb diff --git a/examples/16_network/pet_ioannou_2017_case.py b/examples/16_network/pet_ioannou_2017_case.py index ff72c22a..6ff0b173 100644 --- a/examples/16_network/pet_ioannou_2017_case.py +++ b/examples/16_network/pet_ioannou_2017_case.py @@ -8,6 +8,8 @@ # %% # We want to find the Ierapetra Eddy described above in the networks +import re + # %% from datetime import datetime, timedelta @@ -19,7 +21,7 @@ import py_eddy_tracker.gui from py_eddy_tracker.appli.gui import Anim -from py_eddy_tracker.data import get_path +from py_eddy_tracker.data import get_remote_sample from py_eddy_tracker.observations.network import NetworkObservations @@ -27,7 +29,10 @@ class VideoAnimation(FuncAnimation): def _repr_html_(self, *args, **kwargs): """To get video in html and have a player""" - return self.to_html5_video() + 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"): @@ -72,7 +77,11 @@ def update_axes(ax, mappable=None): # We know the position and the time of a specific eddy # # `n.extract_with_mask` give us the corresponding network -n = NetworkObservations.load_file(get_path("Anticyclonic_seg.nc")) +n = NetworkObservations.load_file( + get_remote_sample( + "eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc" + ) +) i = np.where( (n.lat > 33) * (n.lat < 34) @@ -85,9 +94,9 @@ def update_axes(ax, mappable=None): print(ioannou_case.infos()) # %% -# It seems that this network is huge! Our case is in purple... +# It seems that this network is huge! Our case is visible at 22E 33.5N ax = start_axes() -ioannou_case.plot(ax) +ioannou_case.plot(ax, color_cycle=ioannou_case.COLORS) update_axes(ax) # %% @@ -127,7 +136,7 @@ def update_axes(ax, mappable=None): figsize=(12, 4), cmap=cmap, nb_step=7, - dpi=55, + dpi=80, field_color="segment", field_txt="segment", ) diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index affdf44b..f18d79a0 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -215,7 +215,6 @@ def formatter(x, pos): axs[0].legend() for k in range(0, max_order + 1): - ax = axs[k + 1] sub_network = n.find_segments_relative(after[i_event], stopped[i_event], order=k) diff --git a/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb b/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb new file mode 100644 index 00000000..9855fc85 --- /dev/null +++ b/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb @@ -0,0 +1,274 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Ioannou case\nFigure 10 from https://doi.org/10.1002/2017JC013158\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We want to find the Ierapetra Eddy described above in the networks\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import re" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from datetime import datetime, timedelta\n\nimport numpy as np\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.ticker import FuncFormatter\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_remote_sample\nfrom py_eddy_tracker.observations.network import NetworkObservations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)\n\n\n@FuncFormatter\ndef formatter(x, pos):\n return (timedelta(x) + datetime(1950, 1, 1)).strftime(\"%d/%m/%Y\")\n\n\ndef start_axes(title=\"\"):\n fig = plt.figure(figsize=(13, 6))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=\"full_axes\")\n ax.set_xlim(19, 29), ax.set_ylim(31, 35.5)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n ax.update_env()\n return ax\n\n\ndef timeline_axes(title=\"\"):\n fig = plt.figure(figsize=(15, 5))\n ax = fig.add_axes([0.03, 0.06, 0.90, 0.88])\n ax.set_title(title, weight=\"bold\")\n ax.xaxis.set_major_formatter(formatter), ax.grid()\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid(True)\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We know the position and the time of a specific eddy\n\n`n.extract_with_mask` give us the corresponding network\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "n = NetworkObservations.load_file(\n get_remote_sample(\n \"eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc\"\n )\n)\ni = np.where(\n (n.lat > 33)\n * (n.lat < 34)\n * (n.lon > 22)\n * (n.lon < 23)\n * (n.time > 20630)\n * (n.time < 20650)\n)[0][0]\nioannou_case = n.extract_with_mask(n.track == n.track[i])\nprint(ioannou_case.infos())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It seems that this network is huge! Our case is visible at 22E 33.5N\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes()\nioannou_case.plot(ax, color_cycle=ioannou_case.COLORS)\nupdate_axes(ax)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Full Timeline\nThe network span for many years... How to cut the interesting part?\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 5))\nax = fig.add_axes([0.04, 0.05, 0.92, 0.92])\nax.xaxis.set_major_formatter(formatter), ax.grid()\n_ = ioannou_case.display_timeline(ax)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sub network and new numbering\nHere we chose to keep only the order 3 segments relatives to our chosen eddy\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "i = np.where(\n (ioannou_case.lat > 33)\n * (ioannou_case.lat < 34)\n * (ioannou_case.lon > 22)\n * (ioannou_case.lon < 23)\n * (ioannou_case.time > 20630)\n * (ioannou_case.time < 20650)\n)[0][0]\nclose_to_i3 = ioannou_case.relative(i, order=3)\nclose_to_i3.numbering_segment()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Anim\nQuick movie to see better!\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "cmap = colors.ListedColormap(\n list(close_to_i3.COLORS), name=\"from_list\", N=close_to_i3.segment.max()\n)\na = Anim(\n close_to_i3,\n figsize=(12, 4),\n cmap=cmap,\n nb_step=7,\n dpi=80,\n field_color=\"segment\",\n field_txt=\"segment\",\n)\na.ax.set_xlim(19, 30), a.ax.set_ylim(32, 35.25)\na.ax.update_env()\na.txt.set_position((21.5, 32.7))\nkwargs = dict(frames=np.arange(*a.period), interval=100)\nani = VideoAnimation(a.fig, a.func_animation, **kwargs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Classic display\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = timeline_axes()\n_ = close_to_i3.display_timeline(ax)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(\"\")\nn_copy = close_to_i3.copy()\nn_copy.position_filter(2, 4)\nn_copy.plot(ax, color_cycle=n_copy.COLORS)\nupdate_axes(ax)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Latitude Timeline\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = timeline_axes(f\"Close segments ({close_to_i3.infos()})\")\nn_copy = close_to_i3.copy()\nn_copy.median_filter(15, \"time\", \"latitude\")\n_ = n_copy.display_timeline(ax, field=\"lat\", method=\"all\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Local radius timeline\nEffective (bold) and Speed (thin) Radius together\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "n_copy.median_filter(2, \"time\", \"radius_e\")\nn_copy.median_filter(2, \"time\", \"radius_s\")\nfor b0, b1 in [\n (datetime(i, 1, 1), datetime(i, 12, 31)) for i in (2004, 2005, 2006, 2007)\n]:\n ref, delta = datetime(1950, 1, 1), 20\n b0_, b1_ = (b0 - ref).days, (b1 - ref).days\n ax = timeline_axes()\n ax.set_xlim(b0_ - delta, b1_ + delta)\n ax.set_ylim(10, 115)\n ax.axvline(b0_, color=\"k\", lw=1.5, ls=\"--\"), ax.axvline(\n b1_, color=\"k\", lw=1.5, ls=\"--\"\n )\n n_copy.display_timeline(\n ax, field=\"radius_e\", method=\"all\", lw=4, markersize=8, factor=1e-3\n )\n n_copy.display_timeline(\n ax, field=\"radius_s\", method=\"all\", lw=1, markersize=3, factor=1e-3\n )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Parameters timeline\nEffective Radius\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "kw = dict(s=35, cmap=plt.get_cmap(\"Spectral_r\", 8), zorder=10)\nax = timeline_axes()\nm = close_to_i3.scatter_timeline(ax, \"radius_e\", factor=1e-3, vmin=20, vmax=100, **kw)\ncb = update_axes(ax, m[\"scatter\"])\ncb.set_label(\"Effective radius (km)\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Shape error\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = timeline_axes()\nm = close_to_i3.scatter_timeline(ax, \"shape_error_e\", vmin=14, vmax=70, **kw)\ncb = update_axes(ax, m[\"scatter\"])\ncb.set_label(\"Effective shape error\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/src/py_eddy_tracker/data/__init__.py b/src/py_eddy_tracker/data/__init__.py index 644cf95d..59df8a0f 100644 --- a/src/py_eddy_tracker/data/__init__.py +++ b/src/py_eddy_tracker/data/__init__.py @@ -21,13 +21,21 @@ def get_path(name): def get_remote_sample(path): - url = ( - f"https://github.com/AntSimi/py-eddy-tracker-sample-id/raw/master/{path}.tar.xz" - ) + if path.startswith("/") or path.startswith("."): + content = open(path, "rb").read() + if path.endswith(".nc"): + return io.BytesIO(content) + else: + if path.endswith(".nc"): + content = requests.get( + f"https://github.com/AntSimi/py-eddy-tracker-sample-id/raw/master/{path}" + ).content + return io.BytesIO(content) + content = requests.get( + f"https://github.com/AntSimi/py-eddy-tracker-sample-id/raw/master/{path}.tar.xz" + ).content - content = requests.get(url).content - - # Tar module could manage lzma tar, but it will apply un compress for each extractfile + # Tar module could manage lzma tar, but it will apply uncompress for each extractfile tar = tarfile.open(mode="r", fileobj=io.BytesIO(lzma.decompress(content))) # tar = tarfile.open(mode="r:xz", fileobj=io.BytesIO(content)) files_content = list() diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index dd6e9857..72f86d4b 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -787,12 +787,7 @@ def merging_event(self, triplet=False, only_index=False): if triplet: if only_index: - return ( - idx_m1, - idx_m0, - idx_m0_stop, - ) - + return (idx_m1, idx_m0, idx_m0_stop) else: return ( self.extract_event(idx_m1), @@ -800,10 +795,11 @@ def merging_event(self, triplet=False, only_index=False): self.extract_event(idx_m0_stop), ) else: + idx_m1 = list(set(idx_m1)) if only_index: - return self.extract_event(set(idx_m1)) + return idx_m1 else: - return list(set(idx_m1)) + return self.extract_event(idx_m1) def spliting_event(self, triplet=False): """Return observation before a splitting event. @@ -1107,9 +1103,9 @@ def group_observations(self, **kwargs): ) return gr - def build_dataset(self, group): + def build_dataset(self, group, raw_data=True): nb_obs = group.shape[0] - model = TrackEddiesObservations.load_file(self.filenames[-1], raw_data=True) + model = TrackEddiesObservations.load_file(self.filenames[-1], raw_data=raw_data) eddies = TrackEddiesObservations.new_like(model, nb_obs) eddies.sign_type = model.sign_type # Get new index to re-order observation by group @@ -1124,9 +1120,9 @@ def build_dataset(self, group): if self.memory: # Only if netcdf with open(filename, "rb") as h: - e = TrackEddiesObservations.load_file(h, raw_data=True) + e = TrackEddiesObservations.load_file(h, raw_data=raw_data) else: - e = TrackEddiesObservations.load_file(filename, raw_data=True) + e = TrackEddiesObservations.load_file(filename, raw_data=raw_data) stop = i + len(e) sl = slice(i, stop) for element in elements: diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index d1edf4b0..ab60cf7f 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -4,7 +4,7 @@ """ import logging from datetime import datetime -from io import BufferedReader +from io import BufferedReader, BytesIO from tarfile import ExFileObject from tokenize import TokenError @@ -825,7 +825,7 @@ def load_from_netcdf( array_dim = "NbSample" if isinstance(filename, bytes): filename = filename.astype(str) - if isinstance(filename, (ExFileObject, BufferedReader)): + if isinstance(filename, (ExFileObject, BufferedReader, BytesIO)): filename.seek(0) args, kwargs = ("in-mem-file",), dict(memory=filename.read()) else: From f9c3061ec4b0ed1544de6dd77efad90bb3e5028d Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Fri, 5 Mar 2021 19:26:50 +0100 Subject: [PATCH 078/249] Allow to change more paremeter in GUI --- src/py_eddy_tracker/appli/gui.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/py_eddy_tracker/appli/gui.py b/src/py_eddy_tracker/appli/gui.py index d4d9d542..6e989f31 100644 --- a/src/py_eddy_tracker/appli/gui.py +++ b/src/py_eddy_tracker/appli/gui.py @@ -39,6 +39,7 @@ def __init__( self.time_field = False self.txt = None self.ax = None + self.kw_label = dict() self.setup(**kwargs) def setup( @@ -53,6 +54,8 @@ def setup( position=(0.05, 0.05, 0.9, 0.9), **kwargs, ): + self.kw_label["fontsize"] = kwargs.pop("fontsize", 12) + self.kw_label["fontweight"] = kwargs.pop("fontweight", "demibold") # To text each visible eddy if field_txt: self.field_txt = self.eddy[field_txt] @@ -210,11 +213,7 @@ def update(self): if self.field_txt is not None: for i in where(m)[0]: mappable = self.ax.text( - self.x_core[i], - self.y_core[i], - self.field_txt[i], - fontsize=12, - fontweight="demibold", + self.x_core[i], self.y_core[i], self.field_txt[i], **self.kw_label ) self.mappables.append(mappable) self.ax.draw_artist(mappable) From ed41832b762eb06333e0bb88a52f387f0237bb36 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Tue, 9 Mar 2021 09:15:33 +0100 Subject: [PATCH 079/249] reduce vertices in case of point duplication --- src/py_eddy_tracker/observations/observation.py | 2 +- src/py_eddy_tracker/poly.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index ab60cf7f..8a3e5588 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -2221,6 +2221,7 @@ def grid_count_pixel_in( for i_ in range(nb): x_, y_, x_ref_ = x[i_], y[i_], x_ref[i_] x_ = (x_ - x_ref_) % 360 + x_ref_ + x_, y_ = reduce_size(x_, y_) v = create_vertice(x_, y_) (x_start, x_stop), (y_start, y_stop) = bbox_indice_regular( v, @@ -2232,7 +2233,6 @@ def grid_count_pixel_in( is_circular, x_size, ) - i, j = get_pixel_in_regular(v, x_c, y_c, x_start, x_stop, y_start, y_stop) grid_count_(grid, i, j) diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index 7790b3ec..4a6d11e5 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -209,6 +209,7 @@ def winding_number_poly(x, y, xy_poly): # loop through all edges of the polygon for i_elt in range(nb_elt): if i_elt + 1 == nb_elt: + # We close polygon with first value (no need to duplicate first value) x_next = xy_poly[0, 0] y_next = xy_poly[0, 1] else: From f5c0f0bdddfef7202e4cbd31187aa3aced4dfc1c Mon Sep 17 00:00:00 2001 From: CoriPegliasco <66008544+CoriPegliasco@users.noreply.github.com> Date: Tue, 9 Mar 2021 18:15:41 +0100 Subject: [PATCH 080/249] changes in netcdf variables attributes (#62) * minor changes in netcdf variables attributes * change longname in long_name --- src/py_eddy_tracker/__init__.py | 45 ++++++++++++++++----------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/py_eddy_tracker/__init__.py b/src/py_eddy_tracker/__init__.py index a4e0d8d6..8e93c7aa 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -132,7 +132,7 @@ def parse_args(self, *args, **kwargs): nc_dims=("obs",), nc_attr=dict( long_name="Rotating sense of the eddy", - comment="Cyclonic -1; Anti-cyclonic +1", + comment="Cyclonic -1; Anticyclonic +1", ), ), segment_size=dict( @@ -197,7 +197,7 @@ def parse_args(self, *args, **kwargs): nc_attr=dict( units="degrees_east", axis="X", - comment="Longitude center of the fit circle", + comment="Longitude center of the best fit circle", long_name="Eddy Center Longitude", standard_name="longitude", ), @@ -214,7 +214,7 @@ def parse_args(self, *args, **kwargs): axis="Y", long_name="Eddy Center Latitude", standard_name="latitude", - comment="Latitude center of the fit circle", + comment="Latitude center of the best fit circle", ), ), lon_max=dict( @@ -268,7 +268,7 @@ def parse_args(self, *args, **kwargs): nc_attr=dict( long_name="Speed area", units="m^2", - comment="Area enclosed by speed contour in m^2", + comment="Area enclosed by the speed contour in m^2", ), ), effective_area=dict( @@ -279,7 +279,7 @@ def parse_args(self, *args, **kwargs): nc_attr=dict( long_name="Effective area", units="m^2", - comment="Area enclosed by effective contour in m^2", + comment="Area enclosed by the effective contour in m^2", ), ), speed_average=dict( @@ -307,7 +307,7 @@ def parse_args(self, *args, **kwargs): nc_attr=dict( long_name="Radial Speed Profile", units="m/s", - comment="Speed average values from effective contour inwards to smallest contour, evenly spaced points", + comment="Speed averaged values from the effective contour inwards to the smallest contour, evenly spaced points", ), ), i=dict( @@ -346,7 +346,7 @@ def parse_args(self, *args, **kwargs): nc_attr=dict( long_name="Effective Radius", units="m", - comment="Radius of a circle whose area is equal to that enclosed by the effective contour", + comment="Radius of the best fit circle corresponding to the effective contour", ), ), radius_s=dict( @@ -360,8 +360,7 @@ def parse_args(self, *args, **kwargs): nc_attr=dict( long_name="Speed Radius", units="m", - comment="Radius of a circle whose area is equal to that " - "enclosed by the contour of maximum circum-average speed", + comment="Radius of the best fit circle corresponding to the contour of maximum circum-average speed", ), ), track=dict( @@ -389,8 +388,8 @@ def parse_args(self, *args, **kwargs): nc_type="int32", nc_dims=("obs",), nc_attr=dict( - long_name="Previous obs index", - comment="Index of previous obs, if there are a spliting", + long_name="Previous observation index", + comment="Index of previous observation in a spliting case", ), ), next_obs=dict( @@ -399,8 +398,8 @@ def parse_args(self, *args, **kwargs): nc_type="int32", nc_dims=("obs",), nc_attr=dict( - long_name="Next obs index", - comment="Index of next obs, if there are a merging", + long_name="Next observation index", + comment="Index of next observation in a merging case", ), ), previous_cost=dict( @@ -409,7 +408,7 @@ def parse_args(self, *args, **kwargs): nc_type="float32", nc_dims=("obs",), nc_attr=dict( - long_name="Previous cost for previous obs", + long_name="Previous cost for previous observation", comment="", ), ), @@ -419,7 +418,7 @@ def parse_args(self, *args, **kwargs): nc_type="float32", nc_dims=("obs",), nc_attr=dict( - long_name="Next cost for next obs", + long_name="Next cost for next observation", comment="", ), ), @@ -473,9 +472,9 @@ def parse_args(self, *args, **kwargs): nc_type="u2", nc_dims=("obs",), nc_attr=dict( - longname="number of point for effective contour", + long_name="number of points for effective contour", units="ordinal", - description="Number of point for effective contour, if greater than NbSample, there is a resampling", + description="Number of point for effective contour before resampling", ), ), contour_lon_s=dict( @@ -517,9 +516,9 @@ def parse_args(self, *args, **kwargs): nc_type="u2", nc_dims=("obs",), nc_attr=dict( - longname="number of point for speed contour", + long_name="number of point for speed contour", units="ordinal", - description="Number of point for speed contour, if greater than NbSample, there is a resampling", + description="Number of point for speed contour before resampling", ), ), shape_error_e=dict( @@ -532,8 +531,8 @@ def parse_args(self, *args, **kwargs): nc_dims=("obs",), nc_attr=dict( units="%", - comment="Error criterion between the effective contour and its fit with the circle of same effective radius", - long_name="Effective Contour Error", + comment="Error criterion between the effective contour and its best fit circle", + long_name="Effective Contour Shape Error", ), ), score=dict( @@ -566,8 +565,8 @@ def parse_args(self, *args, **kwargs): nc_dims=("obs",), nc_attr=dict( units="%", - comment="Error criterion between the speed contour and its fit with the circle of same speed radius", - long_name="Speed Contour Error", + comment="Error criterion between the speed contour and its best fit circle", + long_name="Speed Contour Shape Error", ), ), height_max_speed_contour=dict( From 4c5584288209ee87d978c51024449b8b1a5e04de Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Tue, 9 Mar 2021 18:17:39 +0100 Subject: [PATCH 081/249] Add option to quick compare to compare with area or with another cost function --- src/py_eddy_tracker/appli/eddies.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/py_eddy_tracker/appli/eddies.py b/src/py_eddy_tracker/appli/eddies.py index 445145d4..818e825f 100644 --- a/src/py_eddy_tracker/appli/eddies.py +++ b/src/py_eddy_tracker/appli/eddies.py @@ -451,16 +451,20 @@ def quick_compare(): ) parser.add_argument("ref", help="Identification file of reference") parser.add_argument("others", nargs="+", help="Identifications files to compare") - parser.add_argument( - "--area", - action="store_true", - help="Display in percent of area instead percent of observation", - ) + help = "Display in percent of area instead percent of observation" + parser.add_argument("--area", action="store_true", help=help) + help = "Use minimal cost function" + parser.add_argument("--minimal_area", action="store_true", help=help) parser.add_argument("--high", default=40, type=float) parser.add_argument("--low", default=20, type=float) parser.add_argument("--invalid", default=5, type=float) + parser.add_argument( + "--path_out", default=None, help="Save each group in separate file" + ) parser.contour_intern_arg() args = parser.parse_args() + if args.path_out is not None and not exists(args.path_out): + mkdir(args.path_out) kw = dict( include_vars=[ @@ -481,7 +485,7 @@ def quick_compare(): gr1, gr2 = get_group( ref, other, - *ref.match(other, intern=args.intern), + *ref.match(other, intern=args.intern, minimal_area=args.minimal_area), invalid=args.invalid, low=args.low, high=args.high, From 30a311080deb5c000deeaaba80d2cd09f6ae4165 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Tue, 9 Mar 2021 18:19:34 +0100 Subject: [PATCH 082/249] Give access at several options for EddyId --- src/py_eddy_tracker/appli/grid.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/py_eddy_tracker/appli/grid.py b/src/py_eddy_tracker/appli/grid.py index 7faac7ec..7f2b9610 100644 --- a/src/py_eddy_tracker/appli/grid.py +++ b/src/py_eddy_tracker/appli/grid.py @@ -87,12 +87,8 @@ def eddy_id(args=None): parser.add_argument("--height_unit", default=None, help="Force height unit") parser.add_argument("--speed_unit", default=None, help="Force speed unit") parser.add_argument("--unregular", action="store_true", help="if grid is unregular") - parser.add_argument( - "--sampling", - default=50, - type=int, - help="Array size used to build contour, first and last point will be the same", - ) + help = "Array size used to build contour, first and last point will be the same" + parser.add_argument("--sampling", default=50, type=int, help=help) parser.add_argument( "--sampling_method", default="visvalingam", @@ -103,14 +99,20 @@ def eddy_id(args=None): help = "Output will be wrote in zarr" parser.add_argument("--zarr", action="store_true", help=help) help = "Indexs to select grid : --indexs time=2, will select third step along time dimensions" + parser.add_argument("--indexs", nargs="*", help=help, action=DictAction) + help = "Number of pixel of grid detection which could be in an eddies, you must specify MIN and MAX." parser.add_argument( - "--indexs", - nargs="*", - help=help, - action=DictAction, + "--pixel_limit", nargs="+", default=(5, 2000), type=int, help=help ) + help = "Minimal number of amplitude in number of step" + parser.add_argument("--nb_step_min", default=2, type=int, help=help) args = parser.parse_args(args) if args else parser.parse_args() + if len(args.pixel_limit) != 2: + raise Exception( + "You must define two value minimal number of pixel and maximal number of pixel" + ) + cut_wavelength = args.cut_wavelength nb_cw = len(cut_wavelength) if nb_cw > 2 or nb_cw == 0: @@ -123,10 +125,11 @@ def eddy_id(args=None): kwargs = dict( step=args.isoline_step, shape_error=args.fit_errmax, - pixel_limit=(5, 2000), + pixel_limit=args.pixel_limit, force_height_unit=args.height_unit, force_speed_unit=args.speed_unit, nb_step_to_be_mle=0, + nb_step_min=args.nb_step_min, ) a, c = identification( From fe3b0bf861a2f965237fa07f19805462946fb6a1 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Wed, 10 Mar 2021 09:10:14 +0100 Subject: [PATCH 083/249] In case of contour filled with fake value --- TODOLIST.md | 0 src/py_eddy_tracker/poly.py | 2 ++ 2 files changed, 2 insertions(+) create mode 100644 TODOLIST.md diff --git a/TODOLIST.md b/TODOLIST.md new file mode 100644 index 00000000..e69de29b diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index 4a6d11e5..64eb50f8 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -785,4 +785,6 @@ def reduce_size(x, y): i -= 1 if x[i] != x0 or y[i] != y0: i += 1 + # In case of virtual obs all value could be fill with same value, to avoid empty array + i = max(3, i) return x[:i], y[:i] From 1b2207a1417ce3ace7edc4e94feaf285ba6863a4 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Wed, 10 Mar 2021 11:23:30 +0100 Subject: [PATCH 084/249] add time sub sampling on atlas --- src/py_eddy_tracker/observations/observation.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 8a3e5588..c2513e57 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -1653,6 +1653,16 @@ def extract_with_area(self, area, **kwargs): mask *= (lon > lon0) * (lon < area["urcrnrlon"]) return self.extract_with_mask(mask, **kwargs) + def time_sub_sample(self, t0, time_step): + """ + Time sub sampling + + :param int,float t0: reference time which will be keep + :param int,float time_step: keep every observation spaced by time_step + """ + mask = (self.time - t0) % time_step == 0 + return self.extract_with_mask(mask) + def extract_with_mask(self, mask): """ Extract a subset of observations. From 58d8f02259b1bd0f9bce733d41d4cc9ea50e01f2 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Wed, 10 Mar 2021 14:20:40 +0100 Subject: [PATCH 085/249] Add time cube example with FSLE --- CHANGELOG.rst | 1 + examples/07_cube_manipulation/README.rst | 6 + examples/07_cube_manipulation/pet_fsle_med.py | 152 ++++++++++++++++++ .../07_cube_manipulation/pet_fsle_med.ipynb | 144 +++++++++++++++++ 4 files changed, 303 insertions(+) create mode 100644 examples/07_cube_manipulation/README.rst create mode 100644 examples/07_cube_manipulation/pet_fsle_med.py create mode 100644 notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 56f773e1..b974e3bd 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -34,6 +34,7 @@ Added - Network: - Add method to find relatives segments - Add method to get cloase network in an other atlas +- Management of time cube data for advection [3.3.0] - 2020-12-03 -------------------- diff --git a/examples/07_cube_manipulation/README.rst b/examples/07_cube_manipulation/README.rst new file mode 100644 index 00000000..147ce3f3 --- /dev/null +++ b/examples/07_cube_manipulation/README.rst @@ -0,0 +1,6 @@ +Time grid computation +===================== + +.. warning:: + + Time grid is under development, API could move quickly! diff --git a/examples/07_cube_manipulation/pet_fsle_med.py b/examples/07_cube_manipulation/pet_fsle_med.py new file mode 100644 index 00000000..3a8e7dcc --- /dev/null +++ b/examples/07_cube_manipulation/pet_fsle_med.py @@ -0,0 +1,152 @@ +""" +FSLE experiment in med +====================== + +Example to build FSLE, parameter values must be adapted for your case. + +Example use a method similar to `AVISO flse`_ + +.. _AVISO flse: + https://www.aviso.altimetry.fr/en/data/products/value-added-products/ + fsle-finite-size-lyapunov-exponents/fsle-description.html + +""" + +from matplotlib import pyplot as plt +from numba import njit +from numpy import arange, empty, isnan, log2, ma, meshgrid, 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", + heigth="adt", +) + + +# %% +# Methods to compute fsle +# ----------------------- +@njit(cache=True, fastmath=True) +def check_p(x, y, g, 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` + """ + nb_p = x.shape[0] // 3 + delta = dist_max ** 2 + for i in range(nb_p): + i0 = i * 3 + i_n = i0 + 1 + i_e = i0 + 2 + # If particle already set, we skip + if m[i0] or m[i_n] or m[i_e]: + continue + # Distance with north + dxn, dyn = x[i0] - x[i_n], y[i0] - y[i_n] + dn = dxn ** 2 + dyn ** 2 + # Distance with east + dxe, dye = x[i0] - x[i_e], y[i0] - y[i_e] + de = dxe ** 2 + dye ** 2 + + if dn >= delta or de >= delta: + s1 = dxe ** 2 + dxn ** 2 + dye ** 2 + dyn ** 2 + s2 = ((dxn + dye) ** 2 + (dxe - dyn) ** 2) * ( + (dxn - dye) ** 2 + (dxe + dyn) ** 2 + ) + g[i] = 1 / (2 * dt) * log2(1 / (2 * dist_init ** 2) * (s1 + s2 ** 0.5)) + m[i0], m[i_n], m[i_e] = True, True, True + + +@njit(cache=True) +def build_triplet(x, y, step=0.02): + """ + Triplet building for each position we add east and north point with defined step + """ + nb_x = x.shape[0] + x_ = empty(nb_x * 3, dtype=x.dtype) + y_ = empty(nb_x * 3, dtype=y.dtype) + for i in range(nb_x): + i0 = i * 3 + i_n, i_e = i0 + 1, i0 + 2 + x__, y__ = x[i], y[i] + x_[i0], y_[i0] = x__, y__ + x_[i_n], y_[i_n] = x__, y__ + step + x_[i_e], y_[i_e] = x__ + step, y__ + return x_, y_ + + +# %% +# Particles +# --------- +step = 0.02 +t0 = 20268 +x0_, y0_ = -5, 30 +lon_p, lat_p = arange(x0_, x0_ + 43, step), arange(y0_, y0_ + 16, step) +x0, y0 = meshgrid(lon_p, lat_p) +grid_shape = x0.shape +x0, y0 = x0.reshape(-1), y0.reshape(-1) +# Identify all particle not on land +m = ~isnan(c[t0].interp("adt", x0, y0)) +x0, y0 = x0[m], y0[m] + +# %% +# FSLE +# ---- +time_step_by_days = 5 +# Array to compute fsle +fsle = zeros(x0.shape[0], dtype="f4") +x, y = build_triplet(x0, y0) +used = zeros(x.shape[0], dtype="bool") + +# advection generator +kw = dict(t_init=t0, nb_step=1, backward=True, mask_particule=used) +p = c.advect(x, y, "u", "v", time_step=86400 / time_step_by_days, **kw) + +nb_days = 85 +# We check at each step of advection if particle distance is over `dist_max` +for i in range(time_step_by_days * nb_days): + t, xt, yt = p.__next__() + dt = t / 86400.0 - t0 + check_p(xt, yt, fsle, used, dt, dist_max=0.2, dist_init=step) + +# Get index with original_position +i = ((x0 - x0_) / step).astype("i4") +j = ((y0 - y0_) / step).astype("i4") +fsle_ = empty(grid_shape, dtype="f4") +used_ = zeros(grid_shape, dtype="bool") +fsle_[j, i] = fsle +used_[j, i] = used[::3] +# Create a grid object +fsle_custom = RegularGridDataset.with_array( + coordinates=("lon", "lat"), + datas=dict( + fsle=ma.array(fsle_.T, mask=~used_.T), + lon=lon_p, + lat=lat_p, + ), + centered=True, +) + +# %% +# Display FSLE +# ------------ +fig = plt.figure(figsize=(13, 5), dpi=150) +ax = fig.add_axes([0.03, 0.03, 0.90, 0.94]) +ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46) +ax.set_aspect("equal") +ax.set_title("Finite size lyapunov exponent", weight="bold") +kw = dict(cmap="viridis_r", vmin=-15, vmax=0) +m = fsle_custom.display(ax, 1 / fsle_custom.grid("fsle"), **kw) +ax.grid() +cb = plt.colorbar(m, cax=fig.add_axes([0.94, 0.05, 0.01, 0.9])) diff --git a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb new file mode 100644 index 00000000..fd3aaff3 --- /dev/null +++ b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb @@ -0,0 +1,144 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# FSLE experiment in med\n\nExample to build FSLE, parameter values must be adapted for your case.\n\nExample use a method similar to `AVISO flse`_\n\n https://www.aviso.altimetry.fr/en/data/products/value-added-products/\n fsle-finite-size-lyapunov-exponents/fsle-description.html\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from matplotlib import pyplot as plt\nfrom numba import njit\nfrom numpy import arange, empty, isnan, log2, ma, meshgrid, zeros\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.dataset.grid import GridCollection, RegularGridDataset\n\nstart_logger().setLevel(\"ERROR\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## ADT in med\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "c = GridCollection.from_netcdf_cube(\n get_path(\"dt_med_allsat_phy_l4_2005T2.nc\"),\n \"longitude\",\n \"latitude\",\n \"time\",\n heigth=\"adt\",\n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Methods to compute fsle\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "@njit(cache=True, fastmath=True)\ndef check_p(x, y, g, m, dt, dist_init=0.02, dist_max=0.6):\n \"\"\"\n Check if distance between eastern or northern particle to center particle is bigger than `dist_max`\n \"\"\"\n nb_p = x.shape[0] // 3\n delta = dist_max ** 2\n for i in range(nb_p):\n i0 = i * 3\n i_n = i0 + 1\n i_e = i0 + 2\n # If particle already set, we skip\n if m[i0] or m[i_n] or m[i_e]:\n continue\n # Distance with north\n dxn, dyn = x[i0] - x[i_n], y[i0] - y[i_n]\n dn = dxn ** 2 + dyn ** 2\n # Distance with east\n dxe, dye = x[i0] - x[i_e], y[i0] - y[i_e]\n de = dxe ** 2 + dye ** 2\n\n if dn >= delta or de >= delta:\n s1 = dxe ** 2 + dxn ** 2 + dye ** 2 + dyn ** 2\n s2 = ((dxn + dye) ** 2 + (dxe - dyn) ** 2) * (\n (dxn - dye) ** 2 + (dxe + dyn) ** 2\n )\n g[i] = 1 / (2 * dt) * log2(1 / (2 * dist_init ** 2) * (s1 + s2 ** 0.5))\n m[i0], m[i_n], m[i_e] = True, True, True\n\n\n@njit(cache=True)\ndef build_triplet(x, y, step=0.02):\n \"\"\"\n Triplet building for each position we add east and north point with defined step\n \"\"\"\n nb_x = x.shape[0]\n x_ = empty(nb_x * 3, dtype=x.dtype)\n y_ = empty(nb_x * 3, dtype=y.dtype)\n for i in range(nb_x):\n i0 = i * 3\n i_n, i_e = i0 + 1, i0 + 2\n x__, y__ = x[i], y[i]\n x_[i0], y_[i0] = x__, y__\n x_[i_n], y_[i_n] = x__, y__ + step\n x_[i_e], y_[i_e] = x__ + step, y__\n return x_, y_" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Particles\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "step = 0.02\nt0 = 20268\nx0_, y0_ = -5, 30\nlon_p, lat_p = arange(x0_, x0_ + 43, step), arange(y0_, y0_ + 16, step)\nx0, y0 = meshgrid(lon_p, lat_p)\ngrid_shape = x0.shape\nx0, y0 = x0.reshape(-1), y0.reshape(-1)\n# Identify all particle not on land\nm = ~isnan(c[t0].interp(\"adt\", x0, y0))\nx0, y0 = x0[m], y0[m]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## FSLE\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "time_step_by_days = 5\n# Array to compute fsle\nfsle = zeros(x0.shape[0], dtype=\"f4\")\nx, y = build_triplet(x0, y0)\nused = zeros(x.shape[0], dtype=\"bool\")\n\n# advection generator\nkw = dict(t_init=t0, nb_step=1, backward=True, mask_particule=used)\np = c.advect(x, y, \"u\", \"v\", time_step=86400 / time_step_by_days, **kw)\n\nnb_days = 85\n# We check at each step of advection if particle distance is over `dist_max`\nfor i in range(time_step_by_days * nb_days):\n t, xt, yt = p.__next__()\n dt = t / 86400.0 - t0\n check_p(xt, yt, fsle, used, dt, dist_max=0.2, dist_init=step)\n\n# Get index with original_position\ni = ((x0 - x0_) / step).astype(\"i4\")\nj = ((y0 - y0_) / step).astype(\"i4\")\nfsle_ = empty(grid_shape, dtype=\"f4\")\nused_ = zeros(grid_shape, dtype=\"bool\")\nfsle_[j, i] = fsle\nused_[j, i] = used[::3]\n# Create a grid object\nfsle_custom = RegularGridDataset.with_array(\n coordinates=(\"lon\", \"lat\"),\n datas=dict(\n fsle=ma.array(fsle_.T, mask=~used_.T),\n lon=lon_p,\n lat=lat_p,\n ),\n centered=True,\n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Display FSLE\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(13, 5), dpi=150)\nax = fig.add_axes([0.03, 0.03, 0.90, 0.94])\nax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\nax.set_aspect(\"equal\")\nax.set_title(\"Finite size lyapunov exponent\", weight=\"bold\")\nkw = dict(cmap=\"viridis_r\", vmin=-15, vmax=0)\nm = fsle_custom.display(ax, 1 / fsle_custom.grid(\"fsle\"), **kw)\nax.grid()\ncb = plt.colorbar(m, cax=fig.add_axes([0.94, 0.05, 0.01, 0.9]))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file From c8000417b4f0465d16b49b94677d82078560b3b3 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Wed, 10 Mar 2021 14:34:08 +0100 Subject: [PATCH 086/249] for binder env --- apt.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 apt.txt diff --git a/apt.txt b/apt.txt new file mode 100644 index 00000000..a72c3b87 --- /dev/null +++ b/apt.txt @@ -0,0 +1 @@ +libgl1-mesa-glx \ No newline at end of file From d746166119c81924083724be8aaa53b9229a5264 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Wed, 10 Mar 2021 14:51:30 +0100 Subject: [PATCH 087/249] change binder requirement --- doc/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/conf.py b/doc/conf.py index 12c732f8..ccf26e4e 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -69,7 +69,7 @@ "repo": "py-eddy-tracker", "branch": "master", "binderhub_url": "https://mybinder.org", - "dependencies": ["../requirements.txt"], + "dependencies": ["environment.yml"], # Optional keys "use_jupyter_lab": True, }, From 7565ca1d2832389da869337667e1e2e28a4e83be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Wed, 10 Mar 2021 15:46:49 +0100 Subject: [PATCH 088/249] add function insert_virtual and class GroupEddiesCollection --- examples/16_network/pet_relative.py | 4 +- src/py_eddy_tracker/observations/groups.py | 131 +++++++++++++++++++ src/py_eddy_tracker/observations/network.py | 47 ++++++- src/py_eddy_tracker/observations/tracking.py | 49 ++++--- 4 files changed, 198 insertions(+), 33 deletions(-) create mode 100644 src/py_eddy_tracker/observations/groups.py diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index f18d79a0..9993104c 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -199,6 +199,8 @@ i_event = 5 # %% # then see some order of relatives + + @FuncFormatter def formatter(x, pos): return (datetime.timedelta(x) + datetime.datetime(1950, 1, 1)).strftime("%d/%m/%Y") @@ -209,7 +211,7 @@ def formatter(x, pos): max_order + 2, 1, sharex=True, figsize=(15, 5 * (max_order + 2)) ) -axs[0].set_title(f"full network", weight="bold") +axs[0].set_title("full network", weight="bold") axs[0].xaxis.set_major_formatter(formatter), axs[0].grid() mappables = n.display_timeline(axs[0], colors_mode="y") axs[0].legend() diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py new file mode 100644 index 00000000..b5534964 --- /dev/null +++ b/src/py_eddy_tracker/observations/groups.py @@ -0,0 +1,131 @@ +import logging +from abc import ABC, abstractmethod + +from numba import njit +from numpy import arange, int32, interp, median, zeros + +from .observation import EddiesObservations + +logger = logging.getLogger("pet") + + +@njit(cache=True) +def get_missing_indices( + array_time, array_track, dt=1, flag_untrack=True, indice_untrack=0 +): + """return indices where it misses values + + :param np.array(int) array_time : array of strictly increasing int representing time + :param np.array(int) array_track: N° track where observation belong + :param int,float dt: theorical timedelta between 2 observation + :param bool flag_untrack: if True, ignore observations where n°track equal `indice_untrack` + :param int indice_untrack: n° representing where observations are untrack + + + ex : array_time = np.array([67, 68, 70, 71, 74, 75]) + array_track= np.array([ 1, 1, 1, 1, 1, 1]) + return : np.array([2, 4, 4]) + """ + + t0 = array_time[0] + t1 = t0 + + tr0 = array_track[0] + tr1 = tr0 + + nbr_step = zeros(array_time.shape, dtype=int32) + + for i in range(array_time.size - 1): + t0 = t1 + tr0 = tr1 + + t1 = array_time[i + 1] + tr1 = array_track[i + 1] + + if flag_untrack & (tr1 == indice_untrack): + continue + + if tr1 != tr0: + continue + + diff = t1 - t0 + if diff > dt: + nbr_step[i] = int(diff / dt) - 1 + + indices = zeros(nbr_step.sum(), dtype=int32) + + j = 0 + for i in range(array_time.size - 1): + nbr_missing = nbr_step[i] + + if nbr_missing != 0: + for k in range(nbr_missing): + indices[j] = i + 1 + j += 1 + return indices + + +class GroupEddiesObservations(EddiesObservations, ABC): + @abstractmethod + def fix_next_previous_obs(self): + pass + + @abstractmethod + def get_missing_indices(self, dt): + "find indices where observations is missing" + pass + + def filled_by_interpolation(self, mask): + """Filled selected values by interpolation + + :param array(bool) mask: True if must be filled by interpolation + + .. minigallery:: py_eddy_tracker.TrackEddiesObservations.filled_by_interpolation + """ + + nb_filled = mask.sum() + logger.info("%d obs will be filled (unobserved)", nb_filled) + + nb_obs = len(self) + index = arange(nb_obs) + + for field in self.obs.dtype.descr: + # print(f"field : {field}") + var = field[0] + if ( + var in ["n", "virtual", "track", "cost_association"] + or var in self.array_variables + ): + continue + self.obs[var][mask] = interp( + index[mask], index[~mask], self.obs[var][~mask] + ) + + def insert_virtual(self): + + dt_theorical = median(self.time[1:] - self.time[:-1]) + indices = self.get_missing_indices(dt_theorical) + + logger.info("%d virtual observation will be added", indices.size) + + # new observation size + size_obs_corrected = self.time.size + indices.size + + # correction of indices for new size + indices_corrected = indices + arange(indices.size) + + # creating mask with indices + mask = zeros(size_obs_corrected, dtype=bool) + mask[indices_corrected] = 1 + + # time2 = np.empty(n.time.size+indices.size, dtype=n.time.dtype) + # time2[mask] = -1 + # time2[~mask] = n.time + + # new_TEO = TrackEddiesObservations.new_like(n, size_obs_corrected) + new_TEO = self.new_like(self, size_obs_corrected) + new_TEO.obs[~mask] = self.obs + new_TEO.filled_by_interpolation(mask) + new_TEO.virtual[:] = mask + new_TEO.fix_next_previous_obs() + return new_TEO diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 72f86d4b..edbab2e4 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -22,6 +22,7 @@ from ..generic import build_index, wrap_longitude from ..poly import bbox_intersection, vertice_overlap +from .groups import GroupEddiesObservations, get_missing_indices from .observation import EddiesObservations from .tracking import TrackEddiesObservations, track_loess_filter, track_median_filter @@ -73,7 +74,28 @@ def load_contour(self, filename): return self.DATA[filename] -class NetworkObservations(EddiesObservations): +@njit(cache=True) +def fix_next_previous_obs(next_obs, previous_obs, flag_virtual): + """when an observation is virtual, we have to fix the previous and next obs + + :param np.array(int) next_obs : indice of next observation from network + :param np.array(int previous_obs: indice of previous observation from network + :param np.array(bool) flag_virtual: if observation is virtual or not + """ + + for i_o in range(next_obs.size): + if not flag_virtual[i_o]: + continue + + # if there is many virtual side by side, there is some values writted multiple times. + # but it should not be slow + next_obs[i_o - 1] = i_o + next_obs[i_o] = i_o + 1 + previous_obs[i_o] = i_o - 1 + previous_obs[i_o + 1] = i_o + + +class NetworkObservations(GroupEddiesObservations): __slots__ = ("_index_network",) @@ -109,6 +131,25 @@ def find_segments_relative(self, obs, stopped=None, order=1): i_stopped = where(nw.segment == self.segment[stopped])[0][0] return nw.relatives([i_obs, i_stopped], order=order) + def get_missing_indices(self, dt): + """find indices where observations is missing. + + As network have all untrack observation in tracknumber `self.NOGROUP`, + we don't compute them + + :param int,float dt: theorical delta time between 2 observations + """ + return get_missing_indices( + self.time, self.track, dt=dt, flag_untrack=True, indice_untrack=self.NOGROUP + ) + + def fix_next_previous_obs(self): + """function used after 'insert_virtual', to correct next_obs and + previous obs. + """ + + fix_next_previous_obs(self.next_obs, self.previous_obs, self.virtual) + @property def index_network(self): if self._index_network is None: @@ -712,10 +753,6 @@ def scatter( mappables["scatter"] = ax.scatter(x, self.latitude, **kwargs) return mappables - def insert_virtual(self): - # TODO - pass - def extract_event(self, indices): nb = len(indices) new = EddiesObservations( diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index 6a716622..5902462d 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -16,7 +16,6 @@ degrees, empty, histogram, - interp, median, nan, ones, @@ -29,12 +28,12 @@ from .. import VAR_DESCR_inv, __version__ from ..generic import build_index, cumsum_by_track, distance, split_line, wrap_longitude from ..poly import bbox_intersection, merge, vertice_overlap -from .observation import EddiesObservations +from .groups import GroupEddiesObservations, get_missing_indices logger = logging.getLogger("pet") -class TrackEddiesObservations(EddiesObservations): +class TrackEddiesObservations(GroupEddiesObservations): """Class to practice Tracking on observations""" __slots__ = ("__obs_by_track", "__first_index_of_track", "__nb_track") @@ -77,6 +76,26 @@ def iter_track(self): continue yield self.index(slice(i0, i0 + nb)) + def get_missing_indices(self, dt): + """find indices where observations is missing. + + :param int,float dt: theorical delta time between 2 observations + """ + return get_missing_indices( + self.time, + self.track, + dt=dt, + flag_untrack=False, + indice_untrack=self.NOGROUP, + ) + + def fix_next_previous_obs(self): + """function used after 'insert_virtual', to correct next_obs and + previous obs. + """ + + pass + @property def nb_tracks(self): """ @@ -146,30 +165,6 @@ def distance_to_next(self): d_[-1] = 0 return d_ - def filled_by_interpolation(self, mask): - """Filled selected values by interpolation - - :param array(bool) mask: True if must be filled by interpolation - - .. minigallery:: py_eddy_tracker.TrackEddiesObservations.filled_by_interpolation - """ - nb_filled = mask.sum() - logger.info("%d obs will be filled (unobserved)", nb_filled) - - nb_obs = len(self) - index = arange(nb_obs) - - for field in self.obs.dtype.descr: - var = field[0] - if ( - var in ["n", "virtual", "track", "cost_association"] - or var in self.array_variables - ): - continue - self.obs[var][mask] = interp( - index[mask], index[~mask], self.obs[var][~mask] - ) - def normalize_longitude(self): """Normalize all longitude From cb87f3d68802bcceadb7fdc41190b72b75cb40fa Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Wed, 10 Mar 2021 17:44:32 +0100 Subject: [PATCH 089/249] Add circum polar example --- .../pet_eddy_detection_ACC.py | 168 ++++++++++++++++++ .../pet_eddy_detection_ACC.ipynb | 148 +++++++++++++++ 2 files changed, 316 insertions(+) create mode 100644 examples/02_eddy_identification/pet_eddy_detection_ACC.py create mode 100644 notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb diff --git a/examples/02_eddy_identification/pet_eddy_detection_ACC.py b/examples/02_eddy_identification/pet_eddy_detection_ACC.py new file mode 100644 index 00000000..4f8e7557 --- /dev/null +++ b/examples/02_eddy_identification/pet_eddy_detection_ACC.py @@ -0,0 +1,168 @@ +""" +Eddy detection : Antartic circum polar +====================================== + +Script will detect eddies on adt field, and compute u,v with method add_uv(which could use, only if equator is avoid) + +Two ones with filtering adt and another without + +""" +from datetime import datetime + +from matplotlib import pyplot as plt + +from py_eddy_tracker import data +from py_eddy_tracker.dataset.grid import RegularGridDataset + + +def quad_axes(title): + fig = plt.figure(figsize=(13, 8.5)) + fig.suptitle(title, weight="bold") + axes = list() + for position in ( + [0.05, 0.53, 0.44, 0.44], + [0.53, 0.53, 0.44, 0.44], + [0.05, 0.03, 0.44, 0.44], + [0.53, 0.03, 0.44, 0.44], + ): + ax = fig.add_axes(position) + ax.set_xlim(5, 45), ax.set_ylim(-60, -37) + ax.set_aspect("equal"), ax.grid(True) + axes.append(ax) + return axes + + +# %% +# Load Input grid, ADT is used to detect eddies +margin = 30 + +kw_data = dict( + filename=data.get_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") + +# %% +# Identification +# ^^^^^^^^^^^^^^ +# Run the identification step with slices of 2 mm +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 +# ------- +axs = quad_axes("General properties field") +m = g_raw.display(axs[0], "adt", vmin=-1, vmax=1, cmap="RdBu_r") +axs[0].set_title("ADT(m)") +m = g.display(axs[1], "adt_low", vmin=-1, vmax=1, cmap="RdBu_r") +axs[1].set_title("ADT (m) large scale with cut at 700 km") +m = g.display(axs[2], "adt", vmin=-1, vmax=1, cmap="RdBu_r") +axs[2].set_title("ADT (m) high scale with cut at 700 km") +cb = plt.colorbar( + m, cax=axs[0].figure.add_axes([0.03, 0.51, 0.94, 0.01]), orientation="horizontal" +) +cb.set_label("ADT(m)", labelpad=-2) + +# %% +axs = quad_axes("") +axs[0].set_title("Without filter") +axs[0].set_ylabel("Contours used in eddies") +axs[1].set_title("With filter") +axs[2].set_ylabel("Closed contours but not used") +g_raw.contours.display(axs[0], lw=0.5, only_used=True) +g.contours.display(axs[1], lw=0.5, only_used=True) +g_raw.contours.display(axs[2], lw=0.5, only_unused=True) +g.contours.display(axs[3], lw=0.5, only_unused=True) + +# %% +kw = dict(ref=-10, linewidth=0.75) +kw_a = dict(color="r", label="Anticyclonic ({nb_obs} eddies)") +kw_c = dict(color="b", label="Cyclonic ({nb_obs} eddies)") +kw_filled = dict(vmin=0, vmax=100, cmap="Spectral_r", lut=20, intern=True, factor=100) +axs = quad_axes("Comparison between two detection") +# Match with intern/inner contour +i_a, j_a, s_a = a_.match(a, intern=True, cmin=0.15) +i_c, j_c, s_c = c_.match(c, intern=True, cmin=0.15) + +a_.index(i_a).filled(axs[0], s_a, **kw_filled) +a.index(j_a).filled(axs[1], s_a, **kw_filled) +c_.index(i_c).filled(axs[0], s_c, **kw_filled) +m = c.index(j_c).filled(axs[1], s_c, **kw_filled) + +cb = plt.colorbar( + m, cax=axs[0].figure.add_axes([0.03, 0.51, 0.94, 0.01]), orientation="horizontal" +) +cb.set_label("Similarity index", labelpad=-5) +a_.display(axs[0], **kw, **kw_a), c_.display(axs[0], **kw, **kw_c) +a.display(axs[1], **kw, **kw_a), c.display(axs[1], **kw, **kw_c) + +axs[0].set_title("Without filter") +axs[0].set_ylabel("Detection") +axs[1].set_title("With filter") +axs[2].set_ylabel("Contours' rejection criteria") + +g_raw.contours.display(axs[2], lw=0.5, only_unused=True, display_criterion=True) +g.contours.display(axs[3], lw=0.5, only_unused=True, display_criterion=True) + +for ax in axs: + ax.legend() +# %% +# Criteria for rejecting a contour : +# 0. Accepted (green) +# 1. Rejection for shape error (red) +# 2. Masked value within contour (blue) +# 3. Under or over the pixel limit bounds (black) +# 4. Amplitude criterion (yellow) + +# %% +i_a, j_a = i_a[s_a >= 0.4], j_a[s_a >= 0.4] +i_c, j_c = i_c[s_c >= 0.4], j_c[s_c >= 0.4] +fig = plt.figure(figsize=(12, 12)) +fig.suptitle(f"Scatter plot (A : {i_a.shape[0]}, C : {i_c.shape[0]} matches)") + +for i, (label, field, factor, stop) in enumerate( + ( + ("speed radius (km)", "radius_s", 0.001, 120), + ("outter radius (km)", "radius_e", 0.001, 120), + ("amplitude (cm)", "amplitude", 100, 25), + ("speed max (cm/s)", "speed_average", 100, 25), + ) +): + ax = fig.add_subplot(2, 2, i + 1, title=label) + ax.set_xlabel("Without filter") + ax.set_ylabel("With filter") + + ax.plot( + a_[field][i_a] * factor, + a[field][j_a] * factor, + "r.", + label="Anticyclonic", + ) + ax.plot( + c_[field][i_c] * factor, + c[field][j_c] * factor, + "b.", + label="Cyclonic", + ) + ax.set_aspect("equal"), ax.grid() + ax.plot((0, 1000), (0, 1000), "g") + ax.set_xlim(0, stop), ax.set_ylim(0, stop) + ax.legend() diff --git a/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb b/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb new file mode 100644 index 00000000..540f9393 --- /dev/null +++ b/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb @@ -0,0 +1,148 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Eddy detection : Antartic circum polar\n\nScript will detect eddies on adt field, and compute u,v with method add_uv(which could use, only if equator is avoid)\n\nTwo ones with filtering adt and another without\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from datetime import datetime\n\nfrom matplotlib import pyplot as plt\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\n\n\ndef quad_axes(title):\n fig = plt.figure(figsize=(13, 8.5))\n fig.suptitle(title, weight=\"bold\")\n axes = list()\n for position in (\n [0.05, 0.53, 0.44, 0.44],\n [0.53, 0.53, 0.44, 0.44],\n [0.05, 0.03, 0.44, 0.44],\n [0.53, 0.03, 0.44, 0.44],\n ):\n ax = fig.add_axes(position)\n ax.set_xlim(5, 45), ax.set_ylim(-60, -37)\n ax.set_aspect(\"equal\"), ax.grid(True)\n axes.append(ax)\n return axes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load Input grid, ADT is used to detect eddies\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "margin = 30\n\nkw_data = dict(\n filename=data.get_path(\"nrt_global_allsat_phy_l4_20190223_20190226.nc\"),\n x_name=\"longitude\",\n y_name=\"latitude\",\n # Manual area subset\n indexs=dict(\n latitude=slice(100 - margin, 220 + margin),\n longitude=slice(0, 230 + margin),\n ),\n)\ng_raw = RegularGridDataset(**kw_data)\ng_raw.add_uv(\"adt\")\ng = RegularGridDataset(**kw_data)\ng.copy(\"adt\", \"adt_low\")\ng.bessel_high_filter(\"adt\", 700)\ng.bessel_low_filter(\"adt_low\", 700)\ng.add_uv(\"adt\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Identification\nRun the identification step with slices of 2 mm\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "date = datetime(2016, 5, 15)\nkw_ident = dict(\n date=date, step=0.002, shape_error=70, sampling=30, uname=\"u\", vname=\"v\"\n)\na, c = g.eddy_identification(\"adt\", **kw_ident)\na_, c_ = g_raw.eddy_identification(\"adt\", **kw_ident)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Figures\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "axs = quad_axes(\"General properties field\")\nm = g_raw.display(axs[0], \"adt\", vmin=-1, vmax=1, cmap=\"RdBu_r\")\naxs[0].set_title(\"ADT(m)\")\nm = g.display(axs[1], \"adt_low\", vmin=-1, vmax=1, cmap=\"RdBu_r\")\naxs[1].set_title(\"ADT (m) large scale with cut at 700 km\")\nm = g.display(axs[2], \"adt\", vmin=-1, vmax=1, cmap=\"RdBu_r\")\naxs[2].set_title(\"ADT (m) high scale with cut at 700 km\")\ncb = plt.colorbar(\n m, cax=axs[0].figure.add_axes([0.03, 0.51, 0.94, 0.01]), orientation=\"horizontal\"\n)\ncb.set_label(\"ADT(m)\", labelpad=-2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "axs = quad_axes(\"\")\naxs[0].set_title(\"Without filter\")\naxs[0].set_ylabel(\"Contours used in eddies\")\naxs[1].set_title(\"With filter\")\naxs[2].set_ylabel(\"Closed contours but not used\")\ng_raw.contours.display(axs[0], lw=0.5, only_used=True)\ng.contours.display(axs[1], lw=0.5, only_used=True)\ng_raw.contours.display(axs[2], lw=0.5, only_unused=True)\ng.contours.display(axs[3], lw=0.5, only_unused=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "kw = dict(ref=-10, linewidth=0.75)\nkw_a = dict(color=\"r\", label=\"Anticyclonic ({nb_obs} eddies)\")\nkw_c = dict(color=\"b\", label=\"Cyclonic ({nb_obs} eddies)\")\nkw_filled = dict(vmin=0, vmax=100, cmap=\"Spectral_r\", lut=20, intern=True, factor=100)\naxs = quad_axes(\"Comparison between two detection\")\n# Match with intern/inner contour\ni_a, j_a, s_a = a_.match(a, intern=True, cmin=0.15)\ni_c, j_c, s_c = c_.match(c, intern=True, cmin=0.15)\n\na_.index(i_a).filled(axs[0], s_a, **kw_filled)\na.index(j_a).filled(axs[1], s_a, **kw_filled)\nc_.index(i_c).filled(axs[0], s_c, **kw_filled)\nm = c.index(j_c).filled(axs[1], s_c, **kw_filled)\n\ncb = plt.colorbar(\n m, cax=axs[0].figure.add_axes([0.03, 0.51, 0.94, 0.01]), orientation=\"horizontal\"\n)\ncb.set_label(\"Similarity index\", labelpad=-5)\na_.display(axs[0], **kw, **kw_a), c_.display(axs[0], **kw, **kw_c)\na.display(axs[1], **kw, **kw_a), c.display(axs[1], **kw, **kw_c)\n\naxs[0].set_title(\"Without filter\")\naxs[0].set_ylabel(\"Detection\")\naxs[1].set_title(\"With filter\")\naxs[2].set_ylabel(\"Contours' rejection criteria\")\n\ng_raw.contours.display(axs[2], lw=0.5, only_unused=True, display_criterion=True)\ng.contours.display(axs[3], lw=0.5, only_unused=True, display_criterion=True)\n\nfor ax in axs:\n ax.legend()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Criteria for rejecting a contour :\n 0. Accepted (green)\n 1. Rejection for shape error (red)\n 2. Masked value within contour (blue)\n 3. Under or over the pixel limit bounds (black)\n 4. Amplitude criterion (yellow)\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "i_a, j_a = i_a[s_a >= 0.4], j_a[s_a >= 0.4]\ni_c, j_c = i_c[s_c >= 0.4], j_c[s_c >= 0.4]\nfig = plt.figure(figsize=(12, 12))\nfig.suptitle(f\"Scatter plot (A : {i_a.shape[0]}, C : {i_c.shape[0]} matches)\")\n\nfor i, (label, field, factor, stop) in enumerate(\n (\n (\"speed radius (km)\", \"radius_s\", 0.001, 120),\n (\"outter radius (km)\", \"radius_e\", 0.001, 120),\n (\"amplitude (cm)\", \"amplitude\", 100, 25),\n (\"speed max (cm/s)\", \"speed_average\", 100, 25),\n )\n):\n ax = fig.add_subplot(2, 2, i + 1, title=label)\n ax.set_xlabel(\"Without filter\")\n ax.set_ylabel(\"With filter\")\n\n ax.plot(\n a_[field][i_a] * factor,\n a[field][j_a] * factor,\n \"r.\",\n label=\"Anticyclonic\",\n )\n ax.plot(\n c_[field][i_c] * factor,\n c[field][j_c] * factor,\n \"b.\",\n label=\"Cyclonic\",\n )\n ax.set_aspect(\"equal\"), ax.grid()\n ax.plot((0, 1000), (0, 1000), \"g\")\n ax.set_xlim(0, stop), ax.set_ylim(0, stop)\n ax.legend()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file From c6265288ed44f63b820a051d79f251a2f4827c1a Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Thu, 11 Mar 2021 10:11:50 +0100 Subject: [PATCH 090/249] add test for network --- src/py_eddy_tracker/observations/network.py | 26 ++++++++++++++++----- tests/test_network.py | 15 ++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 tests/test_network.py diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index edbab2e4..7b76fd2e 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -1104,14 +1104,28 @@ def get_group_array(self, results, nb_obs): if g0 > g1: g0, g1 = g1, g0 merge_id.append((g0, g1)) + gr_transfer = self.group_translator(id_free, set(merge_id)) + return gr_transfer[gr] + + @staticmethod + def group_translator(nb, duos): + """ + Create a translator with all duos - # FIXME: how it's work when several merge ? like (0,1), (0,2), (1,3) - gr_transfer = arange(id_free, dtype="u4") - for i, j in set(merge_id): - gr_i, gr_j = gr_transfer[i], gr_transfer[j] + :param int nb: size of translator + :param set((int, int)) duos: set of all group which must be join + + Examples + -------- + >>> NetworkObservations.group_translator(5, ((0, 1), (0, 2), (1, 3))) + [3, 3, 3, 3, 5] + """ + translate = arange(nb, dtype="u4") + for i, j in sorted(duos): + gr_i, gr_j = translate[i], translate[j] if gr_i != gr_j: - apply_replace(gr_transfer, gr_i, gr_j) - return gr_transfer[gr] + apply_replace(translate, gr_i, gr_j) + return translate def group_observations(self, **kwargs): results, nb_obs = list(), list() diff --git a/tests/test_network.py b/tests/test_network.py new file mode 100644 index 00000000..5cd9b4cd --- /dev/null +++ b/tests/test_network.py @@ -0,0 +1,15 @@ +from py_eddy_tracker.observations.network import Network + + +def test_group_translate(): + translate = Network.group_translator(5, ((0, 1), (0, 2), (1, 3))) + assert (translate == [3, 3, 3, 3, 4]).all() + + translate = Network.group_translator(5, ((1, 3), (0, 1), (0, 2))) + assert (translate == [3, 3, 3, 3, 4]).all() + + translate = Network.group_translator(8, ((1, 3), (2, 3), (2, 4), (5, 6), (4, 5))) + assert (translate == [0, 6, 6, 6, 6, 6, 6, 7]).all() + + translate = Network.group_translator(6, ((0, 1), (0, 2), (1, 3), (4, 5))) + assert (translate == [3, 3, 3, 3, 5, 5]).all() From 1f3d119d25a0b9b7d0ef4c70956455a5ee52f283 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Thu, 11 Mar 2021 14:42:23 +0100 Subject: [PATCH 091/249] Example about storage and access --- TODOLIST.md | 0 examples/01_general_things/README.rst | 3 + examples/01_general_things/pet_storage.py | 105 ++++++++++ .../01_general_things/pet_storage.ipynb | 180 ++++++++++++++++++ .../observations/observation.py | 41 ++++ 5 files changed, 329 insertions(+) delete mode 100644 TODOLIST.md create mode 100644 examples/01_general_things/README.rst create mode 100644 examples/01_general_things/pet_storage.py create mode 100644 notebooks/python_module/01_general_things/pet_storage.ipynb diff --git a/TODOLIST.md b/TODOLIST.md deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/01_general_things/README.rst b/examples/01_general_things/README.rst new file mode 100644 index 00000000..5876c1b6 --- /dev/null +++ b/examples/01_general_things/README.rst @@ -0,0 +1,3 @@ +General features +================ + diff --git a/examples/01_general_things/pet_storage.py b/examples/01_general_things/pet_storage.py new file mode 100644 index 00000000..423053cf --- /dev/null +++ b/examples/01_general_things/pet_storage.py @@ -0,0 +1,105 @@ +""" +How data is stored +================== + +General information about eddies storage. + +All eddies files have same structure with more or less field and a way of ordering. + +There are 3 class of files: + +- Eddies collections which contains a list of eddies without link between observations +- Track eddies collections which manage eddies when there are merged in trajectory + (track field allow to separate each track) +- Network eddies collections which manage eddies when there are merged in network + (track/segment field allow to separate observations) +""" + +import py_eddy_tracker_sample + +from py_eddy_tracker.data import get_path, get_remote_sample +from py_eddy_tracker.observations.network import NetworkObservations +from py_eddy_tracker.observations.observation import EddiesObservations, Table +from py_eddy_tracker.observations.tracking import TrackEddiesObservations + +# %% +# Eddies could be store in 2 formats with same structures: +# +# - 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 +# ------------ +eddies_collections.amplitude + +# %% +# Data matrix is a numpy ndarray +eddies_collections.obs +# %% +eddies_collections.obs.dtype + + +# %% +# Contour storage +# --------------- +# Contour are stored to fixed size for all, contour are resample with an algorithm before to be store in object + + +# %% +# Tracks +# ------ +# Tracks add several field like: +# +# - track : ID which allow to identify path +# - observation_flag : True if it's an observation to filled a missing detection +# - observation_number : Age of eddies +# - cost_association : result of cost function which allow to associate the observation with eddy path +eddies_tracks = TrackEddiesObservations.load_file( + py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") +) +# In this example some field are removed like effective_contour_longitude, ... in order to save time for doc building +eddies_tracks.field_table() + +# %% +# Network +# ------- +# Network files use some specific field: +# +# - track : ID of network (ID 0 are for lonely eddies/trash) +# - segment : ID of path in network (from 0 to N) +# - previous_obs : Index of the previous observation in the full dataset, if -1 there are no previous observation +# - next_obs : Index of the next observation in the full dataset, if -1 there are no next observation +# - previous_cost : Result of cost_function (1 good <> 0 bad) with previous observation +# - next_cost : Result of cost_function (1 good <> 0 bad) with next observation +eddies_network = NetworkObservations.load_file( + get_remote_sample( + "eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc" + ) +) +eddies_network.field_table() + +# %% +sl = slice(70, 100) +Table( + eddies_network.network(651).obs[sl][ + [ + "time", + "track", + "segment", + "previous_obs", + "previous_cost", + "next_obs", + "next_cost", + ] + ] +) diff --git a/notebooks/python_module/01_general_things/pet_storage.ipynb b/notebooks/python_module/01_general_things/pet_storage.ipynb new file mode 100644 index 00000000..a4f9ddce --- /dev/null +++ b/notebooks/python_module/01_general_things/pet_storage.ipynb @@ -0,0 +1,180 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# How data is stored\n\nGeneral information about eddies storage.\n\nAll eddies files have same structure with more or less field and a way of ordering.\n\nThere are 3 class of files:\n\n- Eddies collections which contains a list of eddies without link between observations\n- Track eddies collections which manage eddies when there are merged in trajectory\n (track field allow to separate each track)\n- Network eddies collections which manage eddies when there are merged in network\n (track/segment field allow to separate observations)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import py_eddy_tracker_sample\n\nfrom py_eddy_tracker.data import get_path, get_remote_sample\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.observation import EddiesObservations, Table\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Eddies could be store in 2 formats with same structures:\n\n- zarr (https://zarr.readthedocs.io/en/stable/), which allow efficiency in IO,...\n- NetCDF4 (https://unidata.github.io/netcdf4-python/), well-known format\n\nEach field are stored in column, each row corresponds at 1 observation,\narray field like contour/profile are 2D column.\n\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Eddies files (zarr or netcdf) could be loaded with `load_file` method:\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "eddies_collections = EddiesObservations.load_file(get_path(\"Cyclonic_20160515.nc\"))\neddies_collections.field_table()\n# offset and scale_factor are used only when data is stored in zarr or netCDF4" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Field access\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "eddies_collections.amplitude" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Data matrix is a numpy ndarray\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "eddies_collections.obs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "eddies_collections.obs.dtype" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Contour storage\nContour are stored to fixed size for all, contour are resample with an algorithm before to be store in object\n\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Tracks\nTracks add several field like:\n\n- track : ID which allow to identify path\n- observation_flag : True if it's an observation to filled a missing detection\n- observation_number : Age of eddies\n- cost_association : result of cost function which allow to associate the observation with eddy path\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "eddies_tracks = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\n# In this example some field are removed like effective_contour_longitude, ... in order to save time for doc building\neddies_tracks.field_table()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Network\nNetwork files use some specific field:\n\n- track : ID of network (ID 0 are for lonely eddies/trash)\n- segment : ID of path in network (from 0 to N)\n- previous_obs : Index of the previous observation in the full dataset, if -1 there are no previous observation\n- next_obs : Index of the next observation in the full dataset, if -1 there are no next observation\n- previous_cost : Result of cost_function (1 good <> 0 bad) with previous observation\n- next_cost : Result of cost_function (1 good <> 0 bad) with next observation\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "eddies_network = NetworkObservations.load_file(\n get_remote_sample(\n \"eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc\"\n )\n)\neddies_network.field_table()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "sl = slice(70, 100)\nTable(\n eddies_network.network(651).obs[sl][\n [\n \"time\",\n \"track\",\n \"segment\",\n \"previous_obs\",\n \"previous_cost\",\n \"next_obs\",\n \"next_cost\",\n ]\n ]\n)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index c2513e57..edda8373 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -109,6 +109,28 @@ def shifted_ellipsoid_degrees_mask2(lon0, lat0, lon1, lat1, minor=1.5, major=1.5 return m +class Table(object): + def __init__(self, values): + self.values = values + + def _repr_html_(self): + rows = list() + if isinstance(self.values, ndarray): + row = "\n".join([f"{v}" for v in self.values.dtype.names]) + rows.append(f"{row}") + for row in self.values: + row = "\n".join([f"{v}" for v in row]) + rows.append(f"{row}") + rows = "\n".join(rows) + return ( + f'' + f'' + f"{rows}" + f"
    " + f"
    " + ) + + class EddiesObservations(object): """ Class to store eddy observations. @@ -259,6 +281,25 @@ def box_display(value): """Return value evenly spaced with few numbers""" return "".join([f"{v_:10.2f}" for v_ in value]) + def field_table(self): + """ + Produce description table of field available in this object + """ + rows = [("Name(Unit)", "Long name", "Scale factor", "Offset")] + names = list(self.obs.dtype.names) + names.sort() + for field in names: + infos = VAR_DESCR[field] + rows.append( + ( + f"{infos.get('nc_name', field).capitalize()} ({infos['nc_attr'].get('units', '')})", + infos["nc_attr"].get("long_name", "").capitalize(), + infos.get("scale_factor", ""), + infos.get("add_offset", ""), + ) + ) + return Table(rows) + def __repr__(self): """ Return general informations on dataset as strings. From e9d42a1b9371e64e5ab945c104bc6e8451a00c1b Mon Sep 17 00:00:00 2001 From: Cori Pegliasco Date: Thu, 11 Mar 2021 14:36:08 +0100 Subject: [PATCH 092/249] fancy figures in ACC detection --- .../pet_eddy_detection_ACC.py | 107 ++++++++++++------ 1 file changed, 73 insertions(+), 34 deletions(-) diff --git a/examples/02_eddy_identification/pet_eddy_detection_ACC.py b/examples/02_eddy_identification/pet_eddy_detection_ACC.py index 4f8e7557..5354b1c9 100644 --- a/examples/02_eddy_identification/pet_eddy_detection_ACC.py +++ b/examples/02_eddy_identification/pet_eddy_detection_ACC.py @@ -1,35 +1,58 @@ """ -Eddy detection : Antartic circum polar -====================================== +Eddy detection : Antartic Circumpolar Current +============================================= -Script will detect eddies on adt field, and compute u,v with method add_uv(which could use, only if equator is avoid) +This script detect eddies on the ADT field, and compute u,v with the method add_uv (use it only if the Equator is avoided) -Two ones with filtering adt and another without +Two detections are provided : with a filtered ADT and without filtering """ from datetime import datetime from matplotlib import pyplot as plt +from matplotlib import style from py_eddy_tracker import data from py_eddy_tracker.dataset.grid import RegularGridDataset +pos_cb = [0.1, 0.52, 0.83, 0.015] +pos_cb2 = [0.1, 0.07, 0.4, 0.015] + def quad_axes(title): - fig = plt.figure(figsize=(13, 8.5)) - fig.suptitle(title, weight="bold") + style.use("default") + fig = plt.figure(figsize=(13, 10)) + fig.suptitle(title, weight="bold", fontsize=14) axes = list() - for position in ( - [0.05, 0.53, 0.44, 0.44], - [0.53, 0.53, 0.44, 0.44], - [0.05, 0.03, 0.44, 0.44], - [0.53, 0.03, 0.44, 0.44], - ): + + ax_pos = dict( + topleft=[0.1, 0.54, 0.4, 0.38], + topright=[0.53, 0.54, 0.4, 0.38], + botleft=[0.1, 0.09, 0.4, 0.38], + botright=[0.53, 0.09, 0.4, 0.38], + ) + + for key, position in ax_pos.items(): ax = fig.add_axes(position) ax.set_xlim(5, 45), ax.set_ylim(-60, -37) ax.set_aspect("equal"), ax.grid(True) axes.append(ax) - return axes + if "right" in key: + ax.set_yticklabels("") + return fig, axes + + +def set_fancy_labels(fig, ticklabelsize=14, labelsize=14, labelweight="semibold"): + for ax in fig.get_axes(): + ax.grid() + ax.grid(which="major", linestyle="-", linewidth="0.5", color="black") + if ax.get_ylabel() != "": + ax.set_ylabel(ax.get_ylabel(), fontsize=labelsize, fontweight=labelweight) + if ax.get_xlabel() != "": + 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) # %% @@ -69,20 +92,25 @@ def quad_axes(title): # %% # Figures # ------- -axs = quad_axes("General properties field") -m = g_raw.display(axs[0], "adt", vmin=-1, vmax=1, cmap="RdBu_r") -axs[0].set_title("ADT(m)") -m = g.display(axs[1], "adt_low", vmin=-1, vmax=1, cmap="RdBu_r") -axs[1].set_title("ADT (m) large scale with cut at 700 km") -m = g.display(axs[2], "adt", vmin=-1, vmax=1, cmap="RdBu_r") -axs[2].set_title("ADT (m) high scale with cut at 700 km") -cb = plt.colorbar( - m, cax=axs[0].figure.add_axes([0.03, 0.51, 0.94, 0.01]), orientation="horizontal" -) -cb.set_label("ADT(m)", labelpad=-2) +kw_adt = dict(vmin=-1.5, vmax=1.5, cmap=plt.get_cmap("RdBu_r", 30)) +fig, axs = quad_axes("General properties field") +m = 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), orientation="horizontal") +cb2.set_label("ADT (m)", labelpad=0) +set_fancy_labels(fig) + +# %% +# The large-scale North-South gradient is removed by the filtering step. # %% -axs = quad_axes("") +fig, axs = quad_axes("") axs[0].set_title("Without filter") axs[0].set_ylabel("Contours used in eddies") axs[1].set_title("With filter") @@ -91,13 +119,18 @@ def quad_axes(title): g.contours.display(axs[1], lw=0.5, only_used=True) g_raw.contours.display(axs[2], lw=0.5, only_unused=True) g.contours.display(axs[3], lw=0.5, only_unused=True) +set_fancy_labels(fig) + +# %% +# Removing the large-scale North-South gradient reveals closed contours in the +# South-Western corner of the ewample region. # %% kw = dict(ref=-10, linewidth=0.75) kw_a = dict(color="r", label="Anticyclonic ({nb_obs} eddies)") kw_c = dict(color="b", label="Cyclonic ({nb_obs} eddies)") kw_filled = dict(vmin=0, vmax=100, cmap="Spectral_r", lut=20, intern=True, factor=100) -axs = quad_axes("Comparison between two detection") +fig, axs = quad_axes("Comparison between two detections") # Match with intern/inner contour i_a, j_a, s_a = a_.match(a, intern=True, cmin=0.15) i_c, j_c, s_c = c_.match(c, intern=True, cmin=0.15) @@ -107,10 +140,8 @@ def quad_axes(title): c_.index(i_c).filled(axs[0], s_c, **kw_filled) m = c.index(j_c).filled(axs[1], s_c, **kw_filled) -cb = plt.colorbar( - m, cax=axs[0].figure.add_axes([0.03, 0.51, 0.94, 0.01]), orientation="horizontal" -) -cb.set_label("Similarity index", labelpad=-5) +cb = plt.colorbar(m, cax=axs[0].figure.add_axes(pos_cb), orientation="horizontal") +cb.set_label("Similarity index (%)", labelpad=-5) a_.display(axs[0], **kw, **kw_a), c_.display(axs[0], **kw, **kw_c) a.display(axs[1], **kw, **kw_a), c.display(axs[1], **kw, **kw_c) @@ -124,6 +155,12 @@ def quad_axes(title): for ax in axs: ax.legend() + +set_fancy_labels(fig) + +# %% +# Very similar eddies have Similarity Indexes >= 40% + # %% # Criteria for rejecting a contour : # 0. Accepted (green) @@ -140,10 +177,10 @@ def quad_axes(title): for i, (label, field, factor, stop) in enumerate( ( - ("speed radius (km)", "radius_s", 0.001, 120), - ("outter radius (km)", "radius_e", 0.001, 120), - ("amplitude (cm)", "amplitude", 100, 25), - ("speed max (cm/s)", "speed_average", 100, 25), + ("Speed radius (km)", "radius_s", 0.001, 120), + ("Effective radius (km)", "radius_e", 0.001, 120), + ("Amplitude (cm)", "amplitude", 100, 25), + ("Speed max (cm/s)", "speed_average", 100, 25), ) ): ax = fig.add_subplot(2, 2, i + 1, title=label) @@ -166,3 +203,5 @@ def quad_axes(title): ax.plot((0, 1000), (0, 1000), "g") ax.set_xlim(0, stop), ax.set_ylim(0, stop) ax.legend() + +set_fancy_labels(fig) From dac07825058fd0ed7e988ee4f3dae14063b2f835 Mon Sep 17 00:00:00 2001 From: CoriPegliasco <66008544+CoriPegliasco@users.noreply.github.com> Date: Thu, 11 Mar 2021 17:51:27 +0100 Subject: [PATCH 093/249] - pet_storage complements (#67) - orthograph in __init__ - no capitals field_table to get same field name as in .nc --- examples/01_general_things/pet_storage.py | 59 ++++++++++--------- src/py_eddy_tracker/__init__.py | 6 +- .../observations/observation.py | 6 +- 3 files changed, 38 insertions(+), 33 deletions(-) diff --git a/examples/01_general_things/pet_storage.py b/examples/01_general_things/pet_storage.py index 423053cf..facf1884 100644 --- a/examples/01_general_things/pet_storage.py +++ b/examples/01_general_things/pet_storage.py @@ -4,15 +4,13 @@ General information about eddies storage. -All eddies files have same structure with more or less field and a way of ordering. +All files have the same structure, with more or less fields and possible different order. There are 3 class of files: -- Eddies collections which contains a list of eddies without link between observations -- Track eddies collections which manage eddies when there are merged in trajectory - (track field allow to separate each track) -- Network eddies collections which manage eddies when there are merged in network - (track/segment field allow to separate observations) +- **Eddies collections** : contain a list of eddies without link between them +- **Track eddies collections** : manage eddies associated in trajectories, the ```track``` field allows to separate each trajectory +- **Network eddies collections** : manage eddies associated in networks, the ```track``` and ```segment``` fields allow to separate observations """ import py_eddy_tracker_sample @@ -23,7 +21,7 @@ from py_eddy_tracker.observations.tracking import TrackEddiesObservations # %% -# Eddies could be store in 2 formats with same structures: +# 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 @@ -32,7 +30,7 @@ # array field like contour/profile are 2D column. # %% -# Eddies files (zarr or netcdf) could be loaded with `load_file` method: +# 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 @@ -40,8 +38,12 @@ # %% # 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 @@ -52,35 +54,34 @@ # %% # Contour storage # --------------- -# Contour are stored to fixed size for all, contour are resample with an algorithm before to be store in object - +# All contours are stored on the same number of points, and are resampled if needed with an algorithm to be stored as objects # %% -# Tracks -# ------ -# Tracks add several field like: +# Trajectories +# ------------ +# Tracks eddies collections add several fields : # -# - track : ID which allow to identify path -# - observation_flag : True if it's an observation to filled a missing detection -# - observation_number : Age of eddies -# - cost_association : result of cost function which allow to associate the observation with eddy path +# - **track** : Trajectory number +# - **observation_flag** : Flag indicating if the value is interpolated between two observations or not (0: observed eddy, 1: interpolated eddy)" +# - **observation_number** : Eddy temporal index in a trajectory, days starting at the eddy first detection +# - **cost_association** : result of the cost function to associate the eddy with the next observation eddies_tracks = TrackEddiesObservations.load_file( py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") ) -# In this example some field are removed like effective_contour_longitude, ... in order to save time for doc building +# In this example some fields are removed (effective_contour_longitude,...) in order to save time for doc building eddies_tracks.field_table() # %% -# Network -# ------- -# Network files use some specific field: +# Networks +# -------- +# Network files use some specific fields : # -# - track : ID of network (ID 0 are for lonely eddies/trash) -# - segment : ID of path in network (from 0 to N) -# - previous_obs : Index of the previous observation in the full dataset, if -1 there are no previous observation -# - next_obs : Index of the next observation in the full dataset, if -1 there are no next observation -# - previous_cost : Result of cost_function (1 good <> 0 bad) with previous observation -# - next_cost : Result of cost_function (1 good <> 0 bad) with next observation +# - track : ID of network (ID 0 correspond to lonely eddies) +# - segment : ID of a segment within a network (from 1 to N) +# - previous_obs : Index of the previous observation in the full dataset, if -1 there are no previous observation (the segment starts) +# - next_obs : Index of the next observation in the full dataset, if -1 there are no next observation (the segment ends) +# - previous_cost : Result of the cost function (1 is a good association, 0 is bad) with previous observation +# - next_cost : Result of the cost function (1 is a good association, 0 is bad) with next observation eddies_network = NetworkObservations.load_file( get_remote_sample( "eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc" @@ -103,3 +104,7 @@ ] ] ) + +# %% +# Networks are ordered by increasing network number (`track`), then increasing segment number, then increasing time + diff --git a/src/py_eddy_tracker/__init__.py b/src/py_eddy_tracker/__init__.py index 8e93c7aa..44944f73 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -474,7 +474,7 @@ def parse_args(self, *args, **kwargs): nc_attr=dict( long_name="number of points for effective contour", units="ordinal", - description="Number of point for effective contour before resampling", + description="Number of points for effective contour before resampling", ), ), contour_lon_s=dict( @@ -516,9 +516,9 @@ def parse_args(self, *args, **kwargs): nc_type="u2", nc_dims=("obs",), nc_attr=dict( - long_name="number of point for speed contour", + long_name="number of points for speed contour", units="ordinal", - description="Number of point for speed contour before resampling", + description="Number of points for speed contour before resampling", ), ), shape_error_e=dict( diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index edda8373..7d6ab314 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -283,16 +283,16 @@ def box_display(value): def field_table(self): """ - Produce description table of field available in this object + Produce description table of the fields available in this object """ - rows = [("Name(Unit)", "Long name", "Scale factor", "Offset")] + rows = [("Name (Unit)", "Long name", "Scale factor", "Offset")] names = list(self.obs.dtype.names) names.sort() for field in names: infos = VAR_DESCR[field] rows.append( ( - f"{infos.get('nc_name', field).capitalize()} ({infos['nc_attr'].get('units', '')})", + f"{infos.get('nc_name', field)} ({infos['nc_attr'].get('units', '')})", infos["nc_attr"].get("long_name", "").capitalize(), infos.get("scale_factor", ""), infos.get("add_offset", ""), From f66bfdeaa930f6ed7968d5538f7d8aa3ad6da236 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Fri, 12 Mar 2021 10:08:36 +0100 Subject: [PATCH 094/249] update example for binder --- .../01_general_things/pet_storage.ipynb | 25 +++++++++----- .../pet_eddy_detection_ACC.ipynb | 33 +++++++++++++++---- src/py_eddy_tracker/dataset/grid.py | 1 - 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/notebooks/python_module/01_general_things/pet_storage.ipynb b/notebooks/python_module/01_general_things/pet_storage.ipynb index a4f9ddce..35a07dfd 100644 --- a/notebooks/python_module/01_general_things/pet_storage.ipynb +++ b/notebooks/python_module/01_general_things/pet_storage.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# How data is stored\n\nGeneral information about eddies storage.\n\nAll eddies files have same structure with more or less field and a way of ordering.\n\nThere are 3 class of files:\n\n- Eddies collections which contains a list of eddies without link between observations\n- Track eddies collections which manage eddies when there are merged in trajectory\n (track field allow to separate each track)\n- Network eddies collections which manage eddies when there are merged in network\n (track/segment field allow to separate observations)\n" + "\n# How data is stored\n\nGeneral information about eddies storage.\n\nAll files have the same structure, with more or less fields and possible different order.\n\nThere are 3 class of files:\n\n- **Eddies collections** : contain a list of eddies without link between them\n- **Track eddies collections** : manage eddies associated in trajectories, the ```track``` field allows to separate each trajectory\n- **Network eddies collections** : manage eddies associated in networks, the ```track``` and ```segment``` fields allow to separate observations\n" ] }, { @@ -33,14 +33,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Eddies could be store in 2 formats with same structures:\n\n- zarr (https://zarr.readthedocs.io/en/stable/), which allow efficiency in IO,...\n- NetCDF4 (https://unidata.github.io/netcdf4-python/), well-known format\n\nEach field are stored in column, each row corresponds at 1 observation,\narray field like contour/profile are 2D column.\n\n" + "Eddies can be stored in 2 formats with the same structure:\n\n- zarr (https://zarr.readthedocs.io/en/stable/), which allow efficiency in IO,...\n- NetCDF4 (https://unidata.github.io/netcdf4-python/), well-known format\n\nEach field are stored in column, each row corresponds at 1 observation,\narray field like contour/profile are 2D column.\n\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Eddies files (zarr or netcdf) could be loaded with `load_file` method:\n\n" + "Eddies files (zarr or netcdf) could be loaded with ```load_file``` method:\n\n" ] }, { @@ -58,7 +58,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Field access\n\n" + "## Field access\nTo access the total field, here ```amplitude```\n\n" ] }, { @@ -69,7 +69,7 @@ }, "outputs": [], "source": [ - "eddies_collections.amplitude" + "eddies_collections.amplitude\n\n# To access only a specific part of the field\neddies_collections.amplitude[4:15]" ] }, { @@ -105,14 +105,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Contour storage\nContour are stored to fixed size for all, contour are resample with an algorithm before to be store in object\n\n" + "## Contour storage\nAll contours are stored on the same number of points, and are resampled if needed with an algorithm to be stored as objects\n\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Tracks\nTracks add several field like:\n\n- track : ID which allow to identify path\n- observation_flag : True if it's an observation to filled a missing detection\n- observation_number : Age of eddies\n- cost_association : result of cost function which allow to associate the observation with eddy path\n\n" + "## Trajectories\nTracks eddies collections add several fields :\n\n- **track** : Trajectory number\n- **observation_flag** : Flag indicating if the value is interpolated between two observations or not (0: observed eddy, 1: interpolated eddy)\"\n- **observation_number** : Eddy temporal index in a trajectory, days starting at the eddy first detection\n- **cost_association** : result of the cost function to associate the eddy with the next observation\n\n" ] }, { @@ -123,14 +123,14 @@ }, "outputs": [], "source": [ - "eddies_tracks = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\n# In this example some field are removed like effective_contour_longitude, ... in order to save time for doc building\neddies_tracks.field_table()" + "eddies_tracks = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\n# In this example some fields are removed (effective_contour_longitude,...) in order to save time for doc building\neddies_tracks.field_table()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Network\nNetwork files use some specific field:\n\n- track : ID of network (ID 0 are for lonely eddies/trash)\n- segment : ID of path in network (from 0 to N)\n- previous_obs : Index of the previous observation in the full dataset, if -1 there are no previous observation\n- next_obs : Index of the next observation in the full dataset, if -1 there are no next observation\n- previous_cost : Result of cost_function (1 good <> 0 bad) with previous observation\n- next_cost : Result of cost_function (1 good <> 0 bad) with next observation\n\n" + "## Networks\nNetwork files use some specific fields :\n\n- track : ID of network (ID 0 correspond to lonely eddies)\n- segment : ID of a segment within a network (from 1 to N)\n- previous_obs : Index of the previous observation in the full dataset, if -1 there are no previous observation (the segment starts)\n- next_obs : Index of the next observation in the full dataset, if -1 there are no next observation (the segment ends)\n- previous_cost : Result of the cost function (1 is a good association, 0 is bad) with previous observation\n- next_cost : Result of the cost function (1 is a good association, 0 is bad) with next observation\n\n" ] }, { @@ -154,6 +154,13 @@ "source": [ "sl = slice(70, 100)\nTable(\n eddies_network.network(651).obs[sl][\n [\n \"time\",\n \"track\",\n \"segment\",\n \"previous_obs\",\n \"previous_cost\",\n \"next_obs\",\n \"next_cost\",\n ]\n ]\n)" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Networks are ordered by increasing network number (`track`), then increasing segment number, then increasing time\n\n" + ] } ], "metadata": { diff --git a/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb b/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb index 540f9393..689f532b 100644 --- a/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# Eddy detection : Antartic circum polar\n\nScript will detect eddies on adt field, and compute u,v with method add_uv(which could use, only if equator is avoid)\n\nTwo ones with filtering adt and another without\n" + "\n# Eddy detection : Antartic Circumpolar Current\n\nThis script detect eddies on the ADT field, and compute u,v with the method add_uv (use it only if the Equator is avoided)\n\nTwo detections are provided : with a filtered ADT and without filtering\n" ] }, { @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "from datetime import datetime\n\nfrom matplotlib import pyplot as plt\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\n\n\ndef quad_axes(title):\n fig = plt.figure(figsize=(13, 8.5))\n fig.suptitle(title, weight=\"bold\")\n axes = list()\n for position in (\n [0.05, 0.53, 0.44, 0.44],\n [0.53, 0.53, 0.44, 0.44],\n [0.05, 0.03, 0.44, 0.44],\n [0.53, 0.03, 0.44, 0.44],\n ):\n ax = fig.add_axes(position)\n ax.set_xlim(5, 45), ax.set_ylim(-60, -37)\n ax.set_aspect(\"equal\"), ax.grid(True)\n axes.append(ax)\n return axes" + "from datetime import datetime\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib import style\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\n\npos_cb = [0.1, 0.52, 0.83, 0.015]\npos_cb2 = [0.1, 0.07, 0.4, 0.015]\n\n\ndef quad_axes(title):\n style.use(\"default\")\n fig = plt.figure(figsize=(13, 10))\n fig.suptitle(title, weight=\"bold\", fontsize=14)\n axes = list()\n\n ax_pos = dict(\n topleft=[0.1, 0.54, 0.4, 0.38],\n topright=[0.53, 0.54, 0.4, 0.38],\n botleft=[0.1, 0.09, 0.4, 0.38],\n botright=[0.53, 0.09, 0.4, 0.38],\n )\n\n for key, position in ax_pos.items():\n ax = fig.add_axes(position)\n ax.set_xlim(5, 45), ax.set_ylim(-60, -37)\n ax.set_aspect(\"equal\"), ax.grid(True)\n axes.append(ax)\n if \"right\" in key:\n ax.set_yticklabels(\"\")\n return fig, axes\n\n\ndef set_fancy_labels(fig, ticklabelsize=14, labelsize=14, labelweight=\"semibold\"):\n for ax in fig.get_axes():\n ax.grid()\n ax.grid(which=\"major\", linestyle=\"-\", linewidth=\"0.5\", color=\"black\")\n if ax.get_ylabel() != \"\":\n ax.set_ylabel(ax.get_ylabel(), fontsize=labelsize, fontweight=labelweight)\n if ax.get_xlabel() != \"\":\n ax.set_xlabel(ax.get_xlabel(), fontsize=labelsize, fontweight=labelweight)\n if ax.get_title() != \"\":\n ax.set_title(ax.get_title(), fontsize=labelsize, fontweight=labelweight)\n ax.tick_params(labelsize=ticklabelsize)" ] }, { @@ -80,7 +80,14 @@ }, "outputs": [], "source": [ - "axs = quad_axes(\"General properties field\")\nm = g_raw.display(axs[0], \"adt\", vmin=-1, vmax=1, cmap=\"RdBu_r\")\naxs[0].set_title(\"ADT(m)\")\nm = g.display(axs[1], \"adt_low\", vmin=-1, vmax=1, cmap=\"RdBu_r\")\naxs[1].set_title(\"ADT (m) large scale with cut at 700 km\")\nm = g.display(axs[2], \"adt\", vmin=-1, vmax=1, cmap=\"RdBu_r\")\naxs[2].set_title(\"ADT (m) high scale with cut at 700 km\")\ncb = plt.colorbar(\n m, cax=axs[0].figure.add_axes([0.03, 0.51, 0.94, 0.01]), orientation=\"horizontal\"\n)\ncb.set_label(\"ADT(m)\", labelpad=-2)" + "kw_adt = dict(vmin=-1.5, vmax=1.5, cmap=plt.get_cmap(\"RdBu_r\", 30))\nfig, axs = quad_axes(\"General properties field\")\nm = g_raw.display(axs[0], \"adt\", **kw_adt)\naxs[0].set_title(\"Total ADT (m)\")\nm = g.display(axs[1], \"adt_low\", **kw_adt)\naxs[1].set_title(\"ADT (m) large scale, cutoff at 700 km\")\nm2 = g.display(axs[2], \"adt\", cmap=plt.get_cmap(\"RdBu_r\", 20), vmin=-0.5, vmax=0.5)\naxs[2].set_title(\"ADT (m) high-pass filtered, a cutoff at 700 km\")\ncb = plt.colorbar(m, cax=axs[0].figure.add_axes(pos_cb), orientation=\"horizontal\")\ncb.set_label(\"ADT (m)\", labelpad=0)\ncb2 = plt.colorbar(m2, cax=axs[2].figure.add_axes(pos_cb2), orientation=\"horizontal\")\ncb2.set_label(\"ADT (m)\", labelpad=0)\nset_fancy_labels(fig)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The large-scale North-South gradient is removed by the filtering step.\n\n" ] }, { @@ -91,7 +98,14 @@ }, "outputs": [], "source": [ - "axs = quad_axes(\"\")\naxs[0].set_title(\"Without filter\")\naxs[0].set_ylabel(\"Contours used in eddies\")\naxs[1].set_title(\"With filter\")\naxs[2].set_ylabel(\"Closed contours but not used\")\ng_raw.contours.display(axs[0], lw=0.5, only_used=True)\ng.contours.display(axs[1], lw=0.5, only_used=True)\ng_raw.contours.display(axs[2], lw=0.5, only_unused=True)\ng.contours.display(axs[3], lw=0.5, only_unused=True)" + "fig, axs = quad_axes(\"\")\naxs[0].set_title(\"Without filter\")\naxs[0].set_ylabel(\"Contours used in eddies\")\naxs[1].set_title(\"With filter\")\naxs[2].set_ylabel(\"Closed contours but not used\")\ng_raw.contours.display(axs[0], lw=0.5, only_used=True)\ng.contours.display(axs[1], lw=0.5, only_used=True)\ng_raw.contours.display(axs[2], lw=0.5, only_unused=True)\ng.contours.display(axs[3], lw=0.5, only_unused=True)\nset_fancy_labels(fig)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Removing the large-scale North-South gradient reveals closed contours in the\nSouth-Western corner of the ewample region.\n\n" ] }, { @@ -102,7 +116,14 @@ }, "outputs": [], "source": [ - "kw = dict(ref=-10, linewidth=0.75)\nkw_a = dict(color=\"r\", label=\"Anticyclonic ({nb_obs} eddies)\")\nkw_c = dict(color=\"b\", label=\"Cyclonic ({nb_obs} eddies)\")\nkw_filled = dict(vmin=0, vmax=100, cmap=\"Spectral_r\", lut=20, intern=True, factor=100)\naxs = quad_axes(\"Comparison between two detection\")\n# Match with intern/inner contour\ni_a, j_a, s_a = a_.match(a, intern=True, cmin=0.15)\ni_c, j_c, s_c = c_.match(c, intern=True, cmin=0.15)\n\na_.index(i_a).filled(axs[0], s_a, **kw_filled)\na.index(j_a).filled(axs[1], s_a, **kw_filled)\nc_.index(i_c).filled(axs[0], s_c, **kw_filled)\nm = c.index(j_c).filled(axs[1], s_c, **kw_filled)\n\ncb = plt.colorbar(\n m, cax=axs[0].figure.add_axes([0.03, 0.51, 0.94, 0.01]), orientation=\"horizontal\"\n)\ncb.set_label(\"Similarity index\", labelpad=-5)\na_.display(axs[0], **kw, **kw_a), c_.display(axs[0], **kw, **kw_c)\na.display(axs[1], **kw, **kw_a), c.display(axs[1], **kw, **kw_c)\n\naxs[0].set_title(\"Without filter\")\naxs[0].set_ylabel(\"Detection\")\naxs[1].set_title(\"With filter\")\naxs[2].set_ylabel(\"Contours' rejection criteria\")\n\ng_raw.contours.display(axs[2], lw=0.5, only_unused=True, display_criterion=True)\ng.contours.display(axs[3], lw=0.5, only_unused=True, display_criterion=True)\n\nfor ax in axs:\n ax.legend()" + "kw = dict(ref=-10, linewidth=0.75)\nkw_a = dict(color=\"r\", label=\"Anticyclonic ({nb_obs} eddies)\")\nkw_c = dict(color=\"b\", label=\"Cyclonic ({nb_obs} eddies)\")\nkw_filled = dict(vmin=0, vmax=100, cmap=\"Spectral_r\", lut=20, intern=True, factor=100)\nfig, axs = quad_axes(\"Comparison between two detections\")\n# Match with intern/inner contour\ni_a, j_a, s_a = a_.match(a, intern=True, cmin=0.15)\ni_c, j_c, s_c = c_.match(c, intern=True, cmin=0.15)\n\na_.index(i_a).filled(axs[0], s_a, **kw_filled)\na.index(j_a).filled(axs[1], s_a, **kw_filled)\nc_.index(i_c).filled(axs[0], s_c, **kw_filled)\nm = c.index(j_c).filled(axs[1], s_c, **kw_filled)\n\ncb = plt.colorbar(m, cax=axs[0].figure.add_axes(pos_cb), orientation=\"horizontal\")\ncb.set_label(\"Similarity index (%)\", labelpad=-5)\na_.display(axs[0], **kw, **kw_a), c_.display(axs[0], **kw, **kw_c)\na.display(axs[1], **kw, **kw_a), c.display(axs[1], **kw, **kw_c)\n\naxs[0].set_title(\"Without filter\")\naxs[0].set_ylabel(\"Detection\")\naxs[1].set_title(\"With filter\")\naxs[2].set_ylabel(\"Contours' rejection criteria\")\n\ng_raw.contours.display(axs[2], lw=0.5, only_unused=True, display_criterion=True)\ng.contours.display(axs[3], lw=0.5, only_unused=True, display_criterion=True)\n\nfor ax in axs:\n ax.legend()\n\nset_fancy_labels(fig)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Very similar eddies have Similarity Indexes >= 40%\n\n" ] }, { @@ -120,7 +141,7 @@ }, "outputs": [], "source": [ - "i_a, j_a = i_a[s_a >= 0.4], j_a[s_a >= 0.4]\ni_c, j_c = i_c[s_c >= 0.4], j_c[s_c >= 0.4]\nfig = plt.figure(figsize=(12, 12))\nfig.suptitle(f\"Scatter plot (A : {i_a.shape[0]}, C : {i_c.shape[0]} matches)\")\n\nfor i, (label, field, factor, stop) in enumerate(\n (\n (\"speed radius (km)\", \"radius_s\", 0.001, 120),\n (\"outter radius (km)\", \"radius_e\", 0.001, 120),\n (\"amplitude (cm)\", \"amplitude\", 100, 25),\n (\"speed max (cm/s)\", \"speed_average\", 100, 25),\n )\n):\n ax = fig.add_subplot(2, 2, i + 1, title=label)\n ax.set_xlabel(\"Without filter\")\n ax.set_ylabel(\"With filter\")\n\n ax.plot(\n a_[field][i_a] * factor,\n a[field][j_a] * factor,\n \"r.\",\n label=\"Anticyclonic\",\n )\n ax.plot(\n c_[field][i_c] * factor,\n c[field][j_c] * factor,\n \"b.\",\n label=\"Cyclonic\",\n )\n ax.set_aspect(\"equal\"), ax.grid()\n ax.plot((0, 1000), (0, 1000), \"g\")\n ax.set_xlim(0, stop), ax.set_ylim(0, stop)\n ax.legend()" + "i_a, j_a = i_a[s_a >= 0.4], j_a[s_a >= 0.4]\ni_c, j_c = i_c[s_c >= 0.4], j_c[s_c >= 0.4]\nfig = plt.figure(figsize=(12, 12))\nfig.suptitle(f\"Scatter plot (A : {i_a.shape[0]}, C : {i_c.shape[0]} matches)\")\n\nfor i, (label, field, factor, stop) in enumerate(\n (\n (\"Speed radius (km)\", \"radius_s\", 0.001, 120),\n (\"Effective radius (km)\", \"radius_e\", 0.001, 120),\n (\"Amplitude (cm)\", \"amplitude\", 100, 25),\n (\"Speed max (cm/s)\", \"speed_average\", 100, 25),\n )\n):\n ax = fig.add_subplot(2, 2, i + 1, title=label)\n ax.set_xlabel(\"Without filter\")\n ax.set_ylabel(\"With filter\")\n\n ax.plot(\n a_[field][i_a] * factor,\n a[field][j_a] * factor,\n \"r.\",\n label=\"Anticyclonic\",\n )\n ax.plot(\n c_[field][i_c] * factor,\n c[field][j_c] * factor,\n \"b.\",\n label=\"Cyclonic\",\n )\n ax.set_aspect(\"equal\"), ax.grid()\n ax.plot((0, 1000), (0, 1000), \"g\")\n ax.set_xlim(0, stop), ax.set_ylim(0, stop)\n ax.legend()\n\nset_fancy_labels(fig)" ] } ], diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index c0c70325..06cdfac1 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -634,7 +634,6 @@ def eddy_identification( self.init_speed_coef(uname, vname) # Get unit of h grid - h_units = ( self.units(grid_height) if force_height_unit is None else force_height_unit ) From a63344ff330054a838b16d76f16601356698b74a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Thu, 11 Mar 2021 12:53:52 +0100 Subject: [PATCH 095/249] add new file for apidoc, change spliting_event, adding comment change spliting_event to reflext what merging_event do --- doc/api.rst | 1 + src/py_eddy_tracker/observations/groups.py | 8 ++----- src/py_eddy_tracker/observations/network.py | 23 ++++++++++++++------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/doc/api.rst b/doc/api.rst index c463c7d0..866704f8 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -14,6 +14,7 @@ API reference py_eddy_tracker.observations.network py_eddy_tracker.observations.observation py_eddy_tracker.observations.tracking + py_eddy_tracker.observations.groups py_eddy_tracker.eddy_feature py_eddy_tracker.generic py_eddy_tracker.gui diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index b5534964..01ff112a 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -102,6 +102,7 @@ def filled_by_interpolation(self, mask): ) def insert_virtual(self): + """insert virtual observation on segments where observations were not found""" dt_theorical = median(self.time[1:] - self.time[:-1]) indices = self.get_missing_indices(dt_theorical) @@ -118,14 +119,9 @@ def insert_virtual(self): mask = zeros(size_obs_corrected, dtype=bool) mask[indices_corrected] = 1 - # time2 = np.empty(n.time.size+indices.size, dtype=n.time.dtype) - # time2[mask] = -1 - # time2[~mask] = n.time - - # new_TEO = TrackEddiesObservations.new_like(n, size_obs_corrected) new_TEO = self.new_like(self, size_obs_corrected) new_TEO.obs[~mask] = self.obs new_TEO.filled_by_interpolation(mask) new_TEO.virtual[:] = mask new_TEO.fix_next_previous_obs() - return new_TEO + return new_TEO \ No newline at end of file diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 7b76fd2e..b474eaeb 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -838,7 +838,7 @@ def merging_event(self, triplet=False, only_index=False): else: return self.extract_event(idx_m1) - def spliting_event(self, triplet=False): + def spliting_event(self, triplet=False, only_index=False): """Return observation before a splitting event. If `triplet=True` return the eddy before a splitting event, the eddy after the splitting event, @@ -859,14 +859,23 @@ def spliting_event(self, triplet=False): idx_s1_start.append(i.start) idx_s1.append(next_obs[i_p]) idx_s0.append(i_p) + if triplet: - return ( - self.extract_event(list(idx_s0)), - self.extract_event(list(idx_s1)), - self.extract_event(list(idx_s1_start)), - ) + if only_index: + return (idx_s0, idx_s1, idx_s1_start) + else: + return ( + self.extract_event(list(idx_s0)), + self.extract_event(list(idx_s1)), + self.extract_event(list(idx_s1_start)), + ) + else: - return self.extract_event(list(set(idx_s0))) + idx_s0 = list(set(idx_s0)) + if only_index: + return idx_s0 + else: + return self.extract_event(idx_s0) def dissociate_network(self): """ From 89e6488b920787bf9a6a01a6cdce83be9294b2ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Thu, 11 Mar 2021 12:55:11 +0100 Subject: [PATCH 096/249] adding function keep_tracks_by_date --- src/py_eddy_tracker/observations/groups.py | 27 +++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index 01ff112a..68047371 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -124,4 +124,29 @@ def insert_virtual(self): new_TEO.filled_by_interpolation(mask) new_TEO.virtual[:] = mask new_TEO.fix_next_previous_obs() - return new_TEO \ No newline at end of file + return new_TEO + + def keep_tracks_by_date(self, date, nb_days): + """ + find tracks which exist at date `date` and lasted at least `nb_days` after. + + if nb_days is negative, it search a tracks which exist at the date, + but existed at least `nb_days` before the date + + + :param int,float date : date where the tracks must exist + :param int,float nb_days: number of time where the tracks must exist. Can be negative + + """ + + time = self.time + + mask = zeros(time.shape, dtype=bool) + + for i, b0, b1 in self.iter_on(self.tracks): + _time = time[i] + + if date in _time and (date + nb_days) in _time: + mask[i] = True + + return self.extract_with_mask(mask) From 0930741271ade1bffe2bb94ab921f34bd117dec6 Mon Sep 17 00:00:00 2001 From: Cori Pegliasco Date: Fri, 12 Mar 2021 18:46:11 +0100 Subject: [PATCH 097/249] - precisions on lon/lat max - full colors for contour rejection --- examples/01_general_things/pet_storage.py | 1 - src/py_eddy_tracker/__init__.py | 2 ++ src/py_eddy_tracker/eddy_feature.py | 8 +++++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/examples/01_general_things/pet_storage.py b/examples/01_general_things/pet_storage.py index facf1884..ffad7d4d 100644 --- a/examples/01_general_things/pet_storage.py +++ b/examples/01_general_things/pet_storage.py @@ -107,4 +107,3 @@ # %% # Networks are ordered by increasing network number (`track`), then increasing segment number, then increasing time - diff --git a/src/py_eddy_tracker/__init__.py b/src/py_eddy_tracker/__init__.py index 44944f73..46946e77 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -229,6 +229,7 @@ def parse_args(self, *args, **kwargs): axis="X", long_name="Longitude of the SSH maximum", standard_name="longitude", + comment="Longitude of the inner contour", ), ), lat_max=dict( @@ -243,6 +244,7 @@ def parse_args(self, *args, **kwargs): axis="Y", long_name="Latitude of the SSH maximum", standard_name="latitude", + comment="Latitude of the inner contour", ), ), amplitude=dict( diff --git a/src/py_eddy_tracker/eddy_feature.py b/src/py_eddy_tracker/eddy_feature.py index 6d929ea0..48b6f2d7 100644 --- a/src/py_eddy_tracker/eddy_feature.py +++ b/src/py_eddy_tracker/eddy_feature.py @@ -651,7 +651,13 @@ def display( if not overide_color: ax.add_collection(LineCollection(paths, **local_kwargs)) if display_criterion: - colors = {0: "g", 1: "r", 2: "b", 3: "k", 4: "y"} + colors = { + 0: "limegreen", + 1: "red", + 2: "mediumblue", + 3: "black", + 4: "gold", + } for k, v in paths.items(): local_kwargs = kwargs.copy() local_kwargs.pop("label", None) From 77ff344af82562a2de842ae397f40616369566bb Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Sat, 13 Mar 2021 14:59:13 +0100 Subject: [PATCH 098/249] coarser resolution in FSLE example --- examples/07_cube_manipulation/pet_fsle_med.py | 45 +++++++++++++------ .../07_cube_manipulation/pet_fsle_med.ipynb | 26 +++++++++-- 2 files changed, 54 insertions(+), 17 deletions(-) diff --git a/examples/07_cube_manipulation/pet_fsle_med.py b/examples/07_cube_manipulation/pet_fsle_med.py index 3a8e7dcc..59e3c8de 100644 --- a/examples/07_cube_manipulation/pet_fsle_med.py +++ b/examples/07_cube_manipulation/pet_fsle_med.py @@ -2,7 +2,7 @@ FSLE experiment in med ====================== -Example to build FSLE, parameter values must be adapted for your case. +Example to build Finite Size Lyapunov Exponents, parameter values must be adapted for your case. Example use a method similar to `AVISO flse`_ @@ -25,7 +25,7 @@ # %% # ADT in med -# --------------------- +# ---------- c = GridCollection.from_netcdf_cube( get_path("dt_med_allsat_phy_l4_2005T2.nc"), "longitude", @@ -36,7 +36,7 @@ # %% -# Methods to compute fsle +# Methods to compute FSLE # ----------------------- @njit(cache=True, fastmath=True) def check_p(x, y, g, m, dt, dist_init=0.02, dist_max=0.6): @@ -86,13 +86,33 @@ def build_triplet(x, y, step=0.02): return x_, y_ +# %% +# Settings +# -------- + +# Step in degrees for ouput +step_grid_out = 1 / 25.0 +# Initial separation in degrees +dist_init = 1 / 50.0 +# Final separation in degrees +dist_max = 1 / 5.0 +# Time of start +t0 = 20268 +# Number of time step by days +time_step_by_days = 5 +# Maximal time of advection +# Here we limit because our data cube cover only 3 month +nb_days = 85 +# Backward or forward +backward = True + # %% # Particles # --------- -step = 0.02 -t0 = 20268 x0_, y0_ = -5, 30 -lon_p, lat_p = arange(x0_, x0_ + 43, step), arange(y0_, y0_ + 16, step) +lon_p, lat_p = arange(x0_, x0_ + 43, step_grid_out), arange( + y0_, y0_ + 16, step_grid_out +) x0, y0 = meshgrid(lon_p, lat_p) grid_shape = x0.shape x0, y0 = x0.reshape(-1), y0.reshape(-1) @@ -103,26 +123,25 @@ def build_triplet(x, y, step=0.02): # %% # FSLE # ---- -time_step_by_days = 5 + # Array to compute fsle fsle = zeros(x0.shape[0], dtype="f4") -x, y = build_triplet(x0, y0) +x, y = build_triplet(x0, y0, dist_init) used = zeros(x.shape[0], dtype="bool") # advection generator -kw = dict(t_init=t0, nb_step=1, backward=True, mask_particule=used) +kw = dict(t_init=t0, nb_step=1, backward=backward, mask_particule=used) p = c.advect(x, y, "u", "v", time_step=86400 / time_step_by_days, **kw) -nb_days = 85 # We check at each step of advection if particle distance is over `dist_max` for i in range(time_step_by_days * nb_days): t, xt, yt = p.__next__() dt = t / 86400.0 - t0 - check_p(xt, yt, fsle, used, dt, dist_max=0.2, dist_init=step) + check_p(xt, yt, fsle, used, dt, dist_max=dist_max, dist_init=dist_init) # Get index with original_position -i = ((x0 - x0_) / step).astype("i4") -j = ((y0 - y0_) / step).astype("i4") +i = ((x0 - x0_) / step_grid_out).astype("i4") +j = ((y0 - y0_) / step_grid_out).astype("i4") fsle_ = empty(grid_shape, dtype="f4") used_ = zeros(grid_shape, dtype="bool") fsle_[j, i] = fsle diff --git a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb index fd3aaff3..fdc67b90 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# FSLE experiment in med\n\nExample to build FSLE, parameter values must be adapted for your case.\n\nExample use a method similar to `AVISO flse`_\n\n https://www.aviso.altimetry.fr/en/data/products/value-added-products/\n fsle-finite-size-lyapunov-exponents/fsle-description.html\n" + "\n# FSLE experiment in med\n\nExample to build Finite Size Lyapunov Exponents, parameter values must be adapted for your case.\n\nExample use a method similar to `AVISO flse`_\n\n https://www.aviso.altimetry.fr/en/data/products/value-added-products/\n fsle-finite-size-lyapunov-exponents/fsle-description.html\n" ] }, { @@ -51,7 +51,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Methods to compute fsle\n\n" + "## Methods to compute FSLE\n\n" ] }, { @@ -65,6 +65,24 @@ "@njit(cache=True, fastmath=True)\ndef check_p(x, y, g, m, dt, dist_init=0.02, dist_max=0.6):\n \"\"\"\n Check if distance between eastern or northern particle to center particle is bigger than `dist_max`\n \"\"\"\n nb_p = x.shape[0] // 3\n delta = dist_max ** 2\n for i in range(nb_p):\n i0 = i * 3\n i_n = i0 + 1\n i_e = i0 + 2\n # If particle already set, we skip\n if m[i0] or m[i_n] or m[i_e]:\n continue\n # Distance with north\n dxn, dyn = x[i0] - x[i_n], y[i0] - y[i_n]\n dn = dxn ** 2 + dyn ** 2\n # Distance with east\n dxe, dye = x[i0] - x[i_e], y[i0] - y[i_e]\n de = dxe ** 2 + dye ** 2\n\n if dn >= delta or de >= delta:\n s1 = dxe ** 2 + dxn ** 2 + dye ** 2 + dyn ** 2\n s2 = ((dxn + dye) ** 2 + (dxe - dyn) ** 2) * (\n (dxn - dye) ** 2 + (dxe + dyn) ** 2\n )\n g[i] = 1 / (2 * dt) * log2(1 / (2 * dist_init ** 2) * (s1 + s2 ** 0.5))\n m[i0], m[i_n], m[i_e] = True, True, True\n\n\n@njit(cache=True)\ndef build_triplet(x, y, step=0.02):\n \"\"\"\n Triplet building for each position we add east and north point with defined step\n \"\"\"\n nb_x = x.shape[0]\n x_ = empty(nb_x * 3, dtype=x.dtype)\n y_ = empty(nb_x * 3, dtype=y.dtype)\n for i in range(nb_x):\n i0 = i * 3\n i_n, i_e = i0 + 1, i0 + 2\n x__, y__ = x[i], y[i]\n x_[i0], y_[i0] = x__, y__\n x_[i_n], y_[i_n] = x__, y__ + step\n x_[i_e], y_[i_e] = x__ + step, y__\n return x_, y_" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Settings\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Step in degrees for ouput\nstep_grid_out = 1/25.\n# Initial separation in degrees\ndist_init = 1/50.\n# Final separation in degrees\ndist_max = 1/5.\n# Time of start\nt0 = 20268\n# Number of time step by days\ntime_step_by_days = 5\n# Maximal time of advection\n# Here we limit because our data cube cover only 3 month\nnb_days = 85\n# Backward or forward\nbackward=True" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -80,7 +98,7 @@ }, "outputs": [], "source": [ - "step = 0.02\nt0 = 20268\nx0_, y0_ = -5, 30\nlon_p, lat_p = arange(x0_, x0_ + 43, step), arange(y0_, y0_ + 16, step)\nx0, y0 = meshgrid(lon_p, lat_p)\ngrid_shape = x0.shape\nx0, y0 = x0.reshape(-1), y0.reshape(-1)\n# Identify all particle not on land\nm = ~isnan(c[t0].interp(\"adt\", x0, y0))\nx0, y0 = x0[m], y0[m]" + "x0_, y0_ = -5, 30\nlon_p, lat_p = arange(x0_, x0_ + 43, step_grid_out), arange(y0_, y0_ + 16, step_grid_out)\nx0, y0 = meshgrid(lon_p, lat_p)\ngrid_shape = x0.shape\nx0, y0 = x0.reshape(-1), y0.reshape(-1)\n# Identify all particle not on land\nm = ~isnan(c[t0].interp(\"adt\", x0, y0))\nx0, y0 = x0[m], y0[m]" ] }, { @@ -98,7 +116,7 @@ }, "outputs": [], "source": [ - "time_step_by_days = 5\n# Array to compute fsle\nfsle = zeros(x0.shape[0], dtype=\"f4\")\nx, y = build_triplet(x0, y0)\nused = zeros(x.shape[0], dtype=\"bool\")\n\n# advection generator\nkw = dict(t_init=t0, nb_step=1, backward=True, mask_particule=used)\np = c.advect(x, y, \"u\", \"v\", time_step=86400 / time_step_by_days, **kw)\n\nnb_days = 85\n# We check at each step of advection if particle distance is over `dist_max`\nfor i in range(time_step_by_days * nb_days):\n t, xt, yt = p.__next__()\n dt = t / 86400.0 - t0\n check_p(xt, yt, fsle, used, dt, dist_max=0.2, dist_init=step)\n\n# Get index with original_position\ni = ((x0 - x0_) / step).astype(\"i4\")\nj = ((y0 - y0_) / step).astype(\"i4\")\nfsle_ = empty(grid_shape, dtype=\"f4\")\nused_ = zeros(grid_shape, dtype=\"bool\")\nfsle_[j, i] = fsle\nused_[j, i] = used[::3]\n# Create a grid object\nfsle_custom = RegularGridDataset.with_array(\n coordinates=(\"lon\", \"lat\"),\n datas=dict(\n fsle=ma.array(fsle_.T, mask=~used_.T),\n lon=lon_p,\n lat=lat_p,\n ),\n centered=True,\n)" + "# Array to compute fsle\nfsle = zeros(x0.shape[0], dtype=\"f4\")\nx, y = build_triplet(x0, y0, dist_init)\nused = zeros(x.shape[0], dtype=\"bool\")\n\n# advection generator\nkw = dict(t_init=t0, nb_step=1, backward=backward, mask_particule=used)\np = c.advect(x, y, \"u\", \"v\", time_step=86400 / time_step_by_days, **kw)\n\n# We check at each step of advection if particle distance is over `dist_max`\nfor i in range(time_step_by_days * nb_days):\n t, xt, yt = p.__next__()\n dt = t / 86400.0 - t0\n check_p(xt, yt, fsle, used, dt, dist_max=dist_max, dist_init=dist_init)\n\n# Get index with original_position\ni = ((x0 - x0_) / step_grid_out).astype(\"i4\")\nj = ((y0 - y0_) / step_grid_out).astype(\"i4\")\nfsle_ = empty(grid_shape, dtype=\"f4\")\nused_ = zeros(grid_shape, dtype=\"bool\")\nfsle_[j, i] = fsle\nused_[j, i] = used[::3]\n# Create a grid object\nfsle_custom = RegularGridDataset.with_array(\n coordinates=(\"lon\", \"lat\"),\n datas=dict(\n fsle=ma.array(fsle_.T, mask=~used_.T),\n lon=lon_p,\n lat=lat_p,\n ),\n centered=True,\n)" ] }, { From 9f43829cb63f9678acfaa80797601429c6e6a19f Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Mon, 15 Mar 2021 09:56:26 +0100 Subject: [PATCH 099/249] add theta to fsle example --- examples/07_cube_manipulation/pet_fsle_med.py | 48 ++++++++++++++----- .../07_cube_manipulation/pet_fsle_med.ipynb | 28 +++++++++-- 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/examples/07_cube_manipulation/pet_fsle_med.py b/examples/07_cube_manipulation/pet_fsle_med.py index 59e3c8de..5ce36b85 100644 --- a/examples/07_cube_manipulation/pet_fsle_med.py +++ b/examples/07_cube_manipulation/pet_fsle_med.py @@ -14,7 +14,7 @@ from matplotlib import pyplot as plt from numba import njit -from numpy import arange, empty, isnan, log2, ma, meshgrid, zeros +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 @@ -39,7 +39,7 @@ # Methods to compute FSLE # ----------------------- @njit(cache=True, fastmath=True) -def check_p(x, y, g, m, dt, dist_init=0.02, dist_max=0.6): +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` """ @@ -60,11 +60,17 @@ def check_p(x, y, g, m, dt, dist_init=0.02, dist_max=0.6): de = dxe ** 2 + dye ** 2 if dn >= delta or de >= delta: - s1 = dxe ** 2 + dxn ** 2 + dye ** 2 + dyn ** 2 + s1 = dn + de + at1 = 2 * (dxe * dxn + dye * dyn) + at2 = de - dn s2 = ((dxn + dye) ** 2 + (dxe - dyn) ** 2) * ( (dxn - dye) ** 2 + (dxe + dyn) ** 2 ) - g[i] = 1 / (2 * dt) * log2(1 / (2 * dist_init ** 2) * (s1 + s2 ** 0.5)) + flse[i] = 1 / (2 * dt) * log2(1 / (2 * dist_init ** 2) * (s1 + s2 ** 0.5)) + theta[i] = arctan2(at1, at2 + s2) * 180 / pi + # To know where value are set + m_set[i] = False + # To stop partcile advection m[i0], m[i_n], m[i_e] = True, True, True @@ -110,10 +116,9 @@ def build_triplet(x, y, step=0.02): # Particles # --------- x0_, y0_ = -5, 30 -lon_p, lat_p = arange(x0_, x0_ + 43, step_grid_out), arange( - y0_, y0_ + 16, step_grid_out -) -x0, y0 = meshgrid(lon_p, lat_p) +lon_p = arange(x0_, x0_ + 43, step_grid_out) +lat_p = arange(y0_, y0_ + 16, step_grid_out) +y0, x0 = meshgrid(lat_p, lon_p) grid_shape = x0.shape x0, y0 = x0.reshape(-1), y0.reshape(-1) # Identify all particle not on land @@ -126,6 +131,8 @@ def build_triplet(x, y, step=0.02): # Array to compute fsle fsle = zeros(x0.shape[0], dtype="f4") +theta = zeros(x0.shape[0], dtype="f4") +mask = ones(x0.shape[0], dtype="f4") x, y = build_triplet(x0, y0, dist_init) used = zeros(x.shape[0], dtype="bool") @@ -137,20 +144,23 @@ def build_triplet(x, y, step=0.02): for i in range(time_step_by_days * nb_days): t, xt, yt = p.__next__() dt = t / 86400.0 - t0 - check_p(xt, yt, fsle, used, dt, dist_max=dist_max, dist_init=dist_init) + check_p(xt, yt, fsle, theta, mask, used, dt, dist_max=dist_max, dist_init=dist_init) # Get index with original_position i = ((x0 - x0_) / step_grid_out).astype("i4") j = ((y0 - y0_) / step_grid_out).astype("i4") fsle_ = empty(grid_shape, dtype="f4") -used_ = zeros(grid_shape, dtype="bool") -fsle_[j, i] = fsle -used_[j, i] = used[::3] +theta_ = empty(grid_shape, dtype="f4") +mask_ = ones(grid_shape, dtype="bool") +fsle_[i, j] = fsle +theta_[i, j] = theta +mask_[i, j] = mask # Create a grid object fsle_custom = RegularGridDataset.with_array( coordinates=("lon", "lat"), datas=dict( - fsle=ma.array(fsle_.T, mask=~used_.T), + fsle=ma.array(fsle_, mask=mask_), + theta=ma.array(theta_, mask=mask_), lon=lon_p, lat=lat_p, ), @@ -169,3 +179,15 @@ def build_triplet(x, y, step=0.02): m = fsle_custom.display(ax, 1 / fsle_custom.grid("fsle"), **kw) ax.grid() cb = plt.colorbar(m, cax=fig.add_axes([0.94, 0.05, 0.01, 0.9])) +# %% +# Display Theta +# ------------- +fig = plt.figure(figsize=(13, 5), dpi=150) +ax = fig.add_axes([0.03, 0.03, 0.90, 0.94]) +ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46) +ax.set_aspect("equal") +ax.set_title("Theta from finite size lyapunov exponent", weight="bold") +kw = dict(cmap="Spectral_r", vmin=-180, vmax=180) +m = fsle_custom.display(ax, fsle_custom.grid("theta"), **kw) +ax.grid() +cb = plt.colorbar(m, cax=fig.add_axes([0.94, 0.05, 0.01, 0.9])) diff --git a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb index fdc67b90..2dcba12d 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "from matplotlib import pyplot as plt\nfrom numba import njit\nfrom numpy import arange, empty, isnan, log2, ma, meshgrid, zeros\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.dataset.grid import GridCollection, RegularGridDataset\n\nstart_logger().setLevel(\"ERROR\")" + "from matplotlib import pyplot as plt\nfrom numba import njit\nfrom numpy import arange, arctan2, empty, isnan, log2, ma, meshgrid, ones, pi, zeros\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.dataset.grid import GridCollection, RegularGridDataset\n\nstart_logger().setLevel(\"ERROR\")" ] }, { @@ -62,7 +62,7 @@ }, "outputs": [], "source": [ - "@njit(cache=True, fastmath=True)\ndef check_p(x, y, g, m, dt, dist_init=0.02, dist_max=0.6):\n \"\"\"\n Check if distance between eastern or northern particle to center particle is bigger than `dist_max`\n \"\"\"\n nb_p = x.shape[0] // 3\n delta = dist_max ** 2\n for i in range(nb_p):\n i0 = i * 3\n i_n = i0 + 1\n i_e = i0 + 2\n # If particle already set, we skip\n if m[i0] or m[i_n] or m[i_e]:\n continue\n # Distance with north\n dxn, dyn = x[i0] - x[i_n], y[i0] - y[i_n]\n dn = dxn ** 2 + dyn ** 2\n # Distance with east\n dxe, dye = x[i0] - x[i_e], y[i0] - y[i_e]\n de = dxe ** 2 + dye ** 2\n\n if dn >= delta or de >= delta:\n s1 = dxe ** 2 + dxn ** 2 + dye ** 2 + dyn ** 2\n s2 = ((dxn + dye) ** 2 + (dxe - dyn) ** 2) * (\n (dxn - dye) ** 2 + (dxe + dyn) ** 2\n )\n g[i] = 1 / (2 * dt) * log2(1 / (2 * dist_init ** 2) * (s1 + s2 ** 0.5))\n m[i0], m[i_n], m[i_e] = True, True, True\n\n\n@njit(cache=True)\ndef build_triplet(x, y, step=0.02):\n \"\"\"\n Triplet building for each position we add east and north point with defined step\n \"\"\"\n nb_x = x.shape[0]\n x_ = empty(nb_x * 3, dtype=x.dtype)\n y_ = empty(nb_x * 3, dtype=y.dtype)\n for i in range(nb_x):\n i0 = i * 3\n i_n, i_e = i0 + 1, i0 + 2\n x__, y__ = x[i], y[i]\n x_[i0], y_[i0] = x__, y__\n x_[i_n], y_[i_n] = x__, y__ + step\n x_[i_e], y_[i_e] = x__ + step, y__\n return x_, y_" + "@njit(cache=True, fastmath=True)\ndef check_p(x, y, flse, theta, m_set, m, dt, dist_init=0.02, dist_max=0.6):\n \"\"\"\n Check if distance between eastern or northern particle to center particle is bigger than `dist_max`\n \"\"\"\n nb_p = x.shape[0] // 3\n delta = dist_max ** 2\n for i in range(nb_p):\n i0 = i * 3\n i_n = i0 + 1\n i_e = i0 + 2\n # If particle already set, we skip\n if m[i0] or m[i_n] or m[i_e]:\n continue\n # Distance with north\n dxn, dyn = x[i0] - x[i_n], y[i0] - y[i_n]\n dn = dxn ** 2 + dyn ** 2\n # Distance with east\n dxe, dye = x[i0] - x[i_e], y[i0] - y[i_e]\n de = dxe ** 2 + dye ** 2\n\n if dn >= delta or de >= delta:\n s1 = dn + de\n at1 = 2 * (dxe * dxn + dye * dyn)\n at2 = de - dn\n s2 = ((dxn + dye) ** 2 + (dxe - dyn) ** 2) * (\n (dxn - dye) ** 2 + (dxe + dyn) ** 2\n )\n flse[i] = 1 / (2 * dt) * log2(1 / (2 * dist_init ** 2) * (s1 + s2 ** 0.5))\n theta[i] = arctan2(at1, at2 + s2) * 180 / pi\n # To know where value are set\n m_set[i] = False\n # To stop partcile advection\n m[i0], m[i_n], m[i_e] = True, True, True\n\n\n@njit(cache=True)\ndef build_triplet(x, y, step=0.02):\n \"\"\"\n Triplet building for each position we add east and north point with defined step\n \"\"\"\n nb_x = x.shape[0]\n x_ = empty(nb_x * 3, dtype=x.dtype)\n y_ = empty(nb_x * 3, dtype=y.dtype)\n for i in range(nb_x):\n i0 = i * 3\n i_n, i_e = i0 + 1, i0 + 2\n x__, y__ = x[i], y[i]\n x_[i0], y_[i0] = x__, y__\n x_[i_n], y_[i_n] = x__, y__ + step\n x_[i_e], y_[i_e] = x__ + step, y__\n return x_, y_" ] }, { @@ -80,7 +80,7 @@ }, "outputs": [], "source": [ - "# Step in degrees for ouput\nstep_grid_out = 1/25.\n# Initial separation in degrees\ndist_init = 1/50.\n# Final separation in degrees\ndist_max = 1/5.\n# Time of start\nt0 = 20268\n# Number of time step by days\ntime_step_by_days = 5\n# Maximal time of advection\n# Here we limit because our data cube cover only 3 month\nnb_days = 85\n# Backward or forward\nbackward=True" + "# Step in degrees for ouput\nstep_grid_out = 1 / 25.0\n# Initial separation in degrees\ndist_init = 1 / 50.0\n# Final separation in degrees\ndist_max = 1 / 5.0\n# Time of start\nt0 = 20268\n# Number of time step by days\ntime_step_by_days = 5\n# Maximal time of advection\n# Here we limit because our data cube cover only 3 month\nnb_days = 85\n# Backward or forward\nbackward = True" ] }, { @@ -98,7 +98,7 @@ }, "outputs": [], "source": [ - "x0_, y0_ = -5, 30\nlon_p, lat_p = arange(x0_, x0_ + 43, step_grid_out), arange(y0_, y0_ + 16, step_grid_out)\nx0, y0 = meshgrid(lon_p, lat_p)\ngrid_shape = x0.shape\nx0, y0 = x0.reshape(-1), y0.reshape(-1)\n# Identify all particle not on land\nm = ~isnan(c[t0].interp(\"adt\", x0, y0))\nx0, y0 = x0[m], y0[m]" + "x0_, y0_ = -5, 30\nlon_p = arange(x0_, x0_ + 43, step_grid_out)\nlat_p = arange(y0_, y0_ + 16, step_grid_out)\ny0, x0 = meshgrid(lat_p, lon_p)\ngrid_shape = x0.shape\nx0, y0 = x0.reshape(-1), y0.reshape(-1)\n# Identify all particle not on land\nm = ~isnan(c[t0].interp(\"adt\", x0, y0))\nx0, y0 = x0[m], y0[m]" ] }, { @@ -116,7 +116,7 @@ }, "outputs": [], "source": [ - "# Array to compute fsle\nfsle = zeros(x0.shape[0], dtype=\"f4\")\nx, y = build_triplet(x0, y0, dist_init)\nused = zeros(x.shape[0], dtype=\"bool\")\n\n# advection generator\nkw = dict(t_init=t0, nb_step=1, backward=backward, mask_particule=used)\np = c.advect(x, y, \"u\", \"v\", time_step=86400 / time_step_by_days, **kw)\n\n# We check at each step of advection if particle distance is over `dist_max`\nfor i in range(time_step_by_days * nb_days):\n t, xt, yt = p.__next__()\n dt = t / 86400.0 - t0\n check_p(xt, yt, fsle, used, dt, dist_max=dist_max, dist_init=dist_init)\n\n# Get index with original_position\ni = ((x0 - x0_) / step_grid_out).astype(\"i4\")\nj = ((y0 - y0_) / step_grid_out).astype(\"i4\")\nfsle_ = empty(grid_shape, dtype=\"f4\")\nused_ = zeros(grid_shape, dtype=\"bool\")\nfsle_[j, i] = fsle\nused_[j, i] = used[::3]\n# Create a grid object\nfsle_custom = RegularGridDataset.with_array(\n coordinates=(\"lon\", \"lat\"),\n datas=dict(\n fsle=ma.array(fsle_.T, mask=~used_.T),\n lon=lon_p,\n lat=lat_p,\n ),\n centered=True,\n)" + "# Array to compute fsle\nfsle = zeros(x0.shape[0], dtype=\"f4\")\ntheta = zeros(x0.shape[0], dtype=\"f4\")\nmask = ones(x0.shape[0], dtype=\"f4\")\nx, y = build_triplet(x0, y0, dist_init)\nused = zeros(x.shape[0], dtype=\"bool\")\n\n# advection generator\nkw = dict(t_init=t0, nb_step=1, backward=backward, mask_particule=used)\np = c.advect(x, y, \"u\", \"v\", time_step=86400 / time_step_by_days, **kw)\n\n# We check at each step of advection if particle distance is over `dist_max`\nfor i in range(time_step_by_days * nb_days):\n t, xt, yt = p.__next__()\n dt = t / 86400.0 - t0\n check_p(xt, yt, fsle, theta, mask, used, dt, dist_max=dist_max, dist_init=dist_init)\n\n# Get index with original_position\ni = ((x0 - x0_) / step_grid_out).astype(\"i4\")\nj = ((y0 - y0_) / step_grid_out).astype(\"i4\")\nfsle_ = empty(grid_shape, dtype=\"f4\")\ntheta_ = empty(grid_shape, dtype=\"f4\")\nmask_ = ones(grid_shape, dtype=\"bool\")\nfsle_[i, j] = fsle\ntheta_[i, j] = theta\nmask_[i, j] = mask\n# Create a grid object\nfsle_custom = RegularGridDataset.with_array(\n coordinates=(\"lon\", \"lat\"),\n datas=dict(\n fsle=ma.array(fsle_, mask=mask_),\n theta=ma.array(theta_, mask=mask_),\n lon=lon_p,\n lat=lat_p,\n ),\n centered=True,\n)" ] }, { @@ -136,6 +136,24 @@ "source": [ "fig = plt.figure(figsize=(13, 5), dpi=150)\nax = fig.add_axes([0.03, 0.03, 0.90, 0.94])\nax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\nax.set_aspect(\"equal\")\nax.set_title(\"Finite size lyapunov exponent\", weight=\"bold\")\nkw = dict(cmap=\"viridis_r\", vmin=-15, vmax=0)\nm = fsle_custom.display(ax, 1 / fsle_custom.grid(\"fsle\"), **kw)\nax.grid()\ncb = plt.colorbar(m, cax=fig.add_axes([0.94, 0.05, 0.01, 0.9]))" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Display Theta\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(13, 5), dpi=150)\nax = fig.add_axes([0.03, 0.03, 0.90, 0.94])\nax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\nax.set_aspect(\"equal\")\nax.set_title(\"Theta from finite size lyapunov exponent\", weight=\"bold\")\nkw = dict(cmap=\"Spectral_r\", vmin=-180, vmax=180)\nm = fsle_custom.display(ax, fsle_custom.grid(\"theta\"), **kw)\nax.grid()\ncb = plt.colorbar(m, cax=fig.add_axes([0.94, 0.05, 0.01, 0.9]))" + ] } ], "metadata": { From bdabfe618753cc8698991d4310bb7efaeb4d34c1 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Mon, 15 Mar 2021 15:12:36 +0100 Subject: [PATCH 100/249] update network example to be build remotely --- examples/01_general_things/pet_storage.py | 12 +- examples/07_cube_manipulation/pet_fsle_med.py | 2 +- examples/16_network/pet_atlas.py | 140 ++--- examples/16_network/pet_group_anim.py | 8 +- examples/16_network/pet_ioannou_2017_case.py | 42 +- examples/16_network/pet_relative.py | 126 +++-- .../16_network/pet_replay_segmentation.py | 37 +- examples/16_network/pet_segmentation_anim.py | 38 +- .../01_general_things/pet_storage.ipynb | 6 +- .../07_cube_manipulation/pet_fsle_med.ipynb | 2 +- .../python_module/16_network/pet_atlas.ipynb | 371 +++++++++++++ .../16_network/pet_group_anim.ipynb | 195 +++++++ .../16_network/pet_ioannou_2017_case.ipynb | 30 +- .../16_network/pet_relative.ipynb | 511 ++++++++++++++++++ .../16_network/pet_replay_segmentation.ipynb | 180 ++++++ .../16_network/pet_segmentation_anim.ipynb | 137 +++++ src/py_eddy_tracker/data/network_med.nc | Bin 0 -> 1243290 bytes src/py_eddy_tracker/observations/network.py | 13 + 18 files changed, 1585 insertions(+), 265 deletions(-) create mode 100644 notebooks/python_module/16_network/pet_atlas.ipynb create mode 100644 notebooks/python_module/16_network/pet_group_anim.ipynb create mode 100644 notebooks/python_module/16_network/pet_relative.ipynb create mode 100644 notebooks/python_module/16_network/pet_replay_segmentation.ipynb create mode 100644 notebooks/python_module/16_network/pet_segmentation_anim.ipynb create mode 100644 src/py_eddy_tracker/data/network_med.nc diff --git a/examples/01_general_things/pet_storage.py b/examples/01_general_things/pet_storage.py index ffad7d4d..b22981a4 100644 --- a/examples/01_general_things/pet_storage.py +++ b/examples/01_general_things/pet_storage.py @@ -9,8 +9,10 @@ There are 3 class of files: - **Eddies collections** : contain a list of eddies without link between them -- **Track eddies collections** : manage eddies associated in trajectories, the ```track``` field allows to separate each trajectory -- **Network eddies collections** : manage eddies associated in networks, the ```track``` and ```segment``` fields allow to separate observations +- **Track eddies collections** : + manage eddies associated in trajectories, the ```track``` field allows to separate each trajectory +- **Network eddies collections** : + manage eddies associated in networks, the ```track``` and ```segment``` fields allow to separate observations """ import py_eddy_tracker_sample @@ -62,7 +64,8 @@ # Tracks eddies collections add several fields : # # - **track** : Trajectory number -# - **observation_flag** : Flag indicating if the value is interpolated between two observations or not (0: observed eddy, 1: interpolated eddy)" +# - **observation_flag** : Flag indicating if the value is interpolated between two observations or not +# (0: observed eddy, 1: interpolated eddy)" # - **observation_number** : Eddy temporal index in a trajectory, days starting at the eddy first detection # - **cost_association** : result of the cost function to associate the eddy with the next observation eddies_tracks = TrackEddiesObservations.load_file( @@ -78,7 +81,8 @@ # # - track : ID of network (ID 0 correspond to lonely eddies) # - segment : ID of a segment within a network (from 1 to N) -# - previous_obs : Index of the previous observation in the full dataset, if -1 there are no previous observation (the segment starts) +# - previous_obs : Index of the previous observation in the full dataset, +# if -1 there are no previous observation (the segment starts) # - next_obs : Index of the next observation in the full dataset, if -1 there are no next observation (the segment ends) # - previous_cost : Result of the cost function (1 is a good association, 0 is bad) with previous observation # - next_cost : Result of the cost function (1 is a good association, 0 is bad) with next observation diff --git a/examples/07_cube_manipulation/pet_fsle_med.py b/examples/07_cube_manipulation/pet_fsle_med.py index 5ce36b85..49b44144 100644 --- a/examples/07_cube_manipulation/pet_fsle_med.py +++ b/examples/07_cube_manipulation/pet_fsle_med.py @@ -70,7 +70,7 @@ def check_p(x, y, flse, theta, m_set, m, dt, dist_init=0.02, dist_max=0.6): theta[i] = arctan2(at1, at2 + s2) * 180 / pi # To know where value are set m_set[i] = False - # To stop partcile advection + # To stop particle advection m[i0], m[i_n], m[i_e] = True, True, True diff --git a/examples/16_network/pet_atlas.py b/examples/16_network/pet_atlas.py index dcb15042..f233e70f 100644 --- a/examples/16_network/pet_atlas.py +++ b/examples/16_network/pet_atlas.py @@ -6,16 +6,20 @@ from numpy import ma import py_eddy_tracker.gui -from py_eddy_tracker.data import get_path +from py_eddy_tracker.data import get_remote_sample from py_eddy_tracker.observations.network import NetworkObservations -n = NetworkObservations.load_file(get_path("Anticyclonic_seg.nc")) +n = NetworkObservations.load_file( + get_remote_sample( + "eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc" + ) +) # %% # Parameters step = 1 / 10.0 bins = ((-10, 37, step), (30, 46, step)) kw_time = dict(cmap="terrain_r", factor=100.0 / n.nb_days, name="count") -kw_ratio = dict(cmap=plt.get_cmap("viridis", 10)) +kw_ratio = dict(cmap=plt.get_cmap("YlGnBu_r", 10)) # %% @@ -57,19 +61,17 @@ def update_axes(ax, mappable=None): update_axes(ax, m).set_label("Pixel used in % of time") # %% -# Display the ratio between the short and total presence. -# -# Light = mostly short networks -ax = start_axes("") -m = g_10.display( - ax, - **kw_ratio, - vmin=50, - vmax=100, - name=g_10.vars["count"] * 100.0 / g_all.vars["count"] -) +# Ratio +# ^^^^^ +# Ratio between the longer and total presence +ax = start_axes("") +g_ = g_10.vars["count"] * 100.0 / g_all.vars["count"] +m = g_10.display(ax, **kw_ratio, vmin=50, vmax=100, name=g_) update_axes(ax, m).set_label("Pixel used in % all atlas") + # %% +# Blue = mostly short networks +# # Network longer than 20 days # --------------------------- # Display the % of time each pixel (1/10°) is within an anticyclonic network @@ -81,57 +83,34 @@ def update_axes(ax, mappable=None): update_axes(ax, m).set_label("Pixel used in % of time") # %% -# Display the ratio between the short and total presence. -# -# Light = mostly short networks -ax = start_axes("") -m = g_20.display( - ax, - **kw_ratio, - vmin=50, - vmax=100, - name=g_20.vars["count"] * 100.0 / g_all.vars["count"] -) +# Ratio +# ^^^^^ +# Ratio between the longer and total presence +ax = start_axes("") +g_ = g_20.vars["count"] * 100.0 / g_all.vars["count"] +m = g_20.display(ax, **kw_ratio, vmin=50, vmax=100, name=g_) update_axes(ax, m).set_label("Pixel used in % all atlas") # %% -# Display the ratio between the short and total presence. -# -# Light = mostly short networks -# -# Networks shorter than 365 days are masked -ax = start_axes("") -m = g_20.display( - ax, - **kw_ratio, - vmin=50, - vmax=100, - name=ma.array( - g_20.vars["count"] * 100.0 / g_all.vars["count"], mask=g_all.vars["count"] < 365 - ) +# Now we will hide pixel which are used less than 365 times +g_ = ma.array( + g_20.vars["count"] * 100.0 / g_all.vars["count"], mask=g_all.vars["count"] < 365 ) +ax = start_axes("") +m = g_20.display(ax, **kw_ratio, vmin=50, vmax=100, name=g_) update_axes(ax, m).set_label("Pixel used in % all atlas") # %% -# Display the ratio between the short and total presence. -# -# Networks longer than 365 days are masked -# -# # -> Coastal areas are mostly populated by short networks -ax = start_axes("") -m = g_20.display( - ax, - **kw_ratio, - vmin=50, - vmax=100, - name=ma.array( - g_20.vars["count"] * 100.0 / g_all.vars["count"], - mask=g_all.vars["count"] >= 365, - ) +# Now we will hide pixel which are used more than 365 times +ax = start_axes("") +g_ = ma.array( + g_20.vars["count"] * 100.0 / g_all.vars["count"], mask=g_all.vars["count"] >= 365 ) +m = g_20.display(ax, **kw_ratio, vmin=50, vmax=100, name=g_) update_axes(ax, m).set_label("Pixel used in % all atlas") - # %% +# Coastal areas are mostly populated by short networks +# # All merging # ----------- # Display the occurence of merging events @@ -143,18 +122,13 @@ def update_axes(ax, mappable=None): # %% # Ratio merging events / eddy presence ax = start_axes("") -m = g_all_merging.display( - ax, - **kw_ratio, - vmin=0, - vmax=5, - name=g_all_merging.vars["count"] * 100.0 / g_all.vars["count"] -) +g_ = g_all_merging.vars["count"] * 100.0 / g_all.vars["count"] +m = g_all_merging.display(ax, **kw_ratio, vmin=0, vmax=5, name=g_) update_axes(ax, m).set_label("Pixel used in % all atlas") # %% -# Merging in networks longer than 10 days, with dead end remove (shorter than 5 days) -# ----------------------------------------------------------------------------------- +# Merging in networks longer than 10 days, with dead end remove (shorter than 10 observations) +# -------------------------------------------------------------------------------------------- ax = start_axes("") merger = n10.remove_dead_end(nobs=10).merging_event() g_10_merging = merger.grid_count(bins) @@ -170,17 +144,13 @@ def update_axes(ax, mappable=None): m = g_10_merging.display(ax, **kw_time, vmin=0, vmax=1) update_axes(ax, m).set_label("Pixel used in % of time") # %% +# Ratio merging events / eddy presence ax = start_axes("") -m = g_10_merging.display( - ax, - **kw_ratio, - vmin=0, - vmax=5, - name=ma.array( - g_10_merging.vars["count"] * 100.0 / g_10.vars["count"], - mask=g_10.vars["count"] < 365, - ) +g_ = ma.array( + g_10_merging.vars["count"] * 100.0 / g_10.vars["count"], + mask=g_10.vars["count"] < 365, ) +m = g_10_merging.display(ax, **kw_ratio, vmin=0, vmax=5, name=g_) update_axes(ax, m).set_label("Pixel used in % all atlas") # %% @@ -193,15 +163,10 @@ def update_axes(ax, mappable=None): update_axes(ax, m).set_label("Pixel used in % of time") # %% -# Ratio merging events / eddy presence +# Ratio spliting events / eddy presence ax = start_axes("") -m = g_all_spliting.display( - ax, - **kw_ratio, - vmin=0, - vmax=5, - name=g_all_spliting.vars["count"] * 100.0 / g_all.vars["count"] -) +g_ = g_all_spliting.vars["count"] * 100.0 / g_all.vars["count"] +m = g_all_spliting.display(ax, **kw_ratio, vmin=0, vmax=5, name=g_) update_axes(ax, m).set_label("Pixel used in % all atlas") # %% @@ -213,14 +178,9 @@ def update_axes(ax, mappable=None): update_axes(ax, m).set_label("Pixel used in % of time") # %% ax = start_axes("") -m = g_10_spliting.display( - ax, - **kw_ratio, - vmin=0, - vmax=5, - name=ma.array( - g_10_spliting.vars["count"] * 100.0 / g_10.vars["count"], - mask=g_10.vars["count"] < 365, - ) +g_ = ma.array( + g_10_spliting.vars["count"] * 100.0 / g_10.vars["count"], + mask=g_10.vars["count"] < 365, ) +m = g_10_spliting.display(ax, **kw_ratio, vmin=0, vmax=5, name=g_) update_axes(ax, m).set_label("Pixel used in % all atlas") diff --git a/examples/16_network/pet_group_anim.py b/examples/16_network/pet_group_anim.py index 151366c2..581898d8 100644 --- a/examples/16_network/pet_group_anim.py +++ b/examples/16_network/pet_group_anim.py @@ -24,7 +24,7 @@ def _repr_html_(self, *args, **kwargs): """To get video in html and have a player""" content = self.to_html5_video() return re.sub( - 'width="[0-9]*"\sheight="[0-9]*"', 'width="100%" height="100%"', content + r'width="[0-9]*"\sheight="[0-9]*"', 'width="100%" height="100%"', content ) def save(self, *args, **kwargs): @@ -93,7 +93,7 @@ def get_group_array(self, results, nb_obs): # %% # Get data from period and area -e = EddiesObservations.load_file(data.get_path("Anticyclonic_seg.nc")) +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) ) @@ -134,7 +134,7 @@ def update(frame): # ---- fig = plt.figure(figsize=(16, 9), dpi=50) ax = fig.add_axes([0, 0, 1, 1]) -ax.set_aspect("equal"), ax.grid(), ax.set_xlim(26, 34), ax.set_ylim(32, 36.5) +ax.set_aspect("equal"), ax.grid(), ax.set_xlim(26, 34), ax.set_ylim(31, 35.5) groups = ax.scatter( e.lon, e.lat, @@ -145,6 +145,6 @@ def update(frame): ) current_contour = ax.plot([], [], "k", lw=2, label="Current contour")[0] matched_contour = ax.plot([], [], "r", lw=1, ls="--", label="Candidate contour")[0] -txt = ax.text(31.5, 35.5, "", fontsize=25) +txt = ax.text(29, 35, "", fontsize=25) ax.legend(fontsize=25) ani = VideoAnimation(fig, update, frames=len(NETWORK_GROUPS), interval=220) diff --git a/examples/16_network/pet_ioannou_2017_case.py b/examples/16_network/pet_ioannou_2017_case.py index 6ff0b173..f9ab7809 100644 --- a/examples/16_network/pet_ioannou_2017_case.py +++ b/examples/16_network/pet_ioannou_2017_case.py @@ -3,25 +3,22 @@ ============ Figure 10 from https://doi.org/10.1002/2017JC013158 +We want to find the Ierapetra Eddy described above in a network demonstration run. """ # %% -# We want to find the Ierapetra Eddy described above in the networks - import re - -# %% from datetime import datetime, timedelta -import numpy as np from matplotlib import colors from matplotlib import pyplot as plt from matplotlib.animation import FuncAnimation from matplotlib.ticker import FuncFormatter +from numpy import arange, where import py_eddy_tracker.gui from py_eddy_tracker.appli.gui import Anim -from py_eddy_tracker.data import get_remote_sample +from py_eddy_tracker.data import get_path from py_eddy_tracker.observations.network import NetworkObservations @@ -74,23 +71,8 @@ def update_axes(ax, mappable=None): # %% -# We know the position and the time of a specific eddy -# -# `n.extract_with_mask` give us the corresponding network -n = NetworkObservations.load_file( - get_remote_sample( - "eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc" - ) -) -i = np.where( - (n.lat > 33) - * (n.lat < 34) - * (n.lon > 22) - * (n.lon < 23) - * (n.time > 20630) - * (n.time < 20650) -)[0][0] -ioannou_case = n.extract_with_mask(n.track == n.track[i]) +# We know the network ID, we will get directly +ioannou_case = NetworkObservations.load_file(get_path("network_med.nc")).network(651) print(ioannou_case.infos()) # %% @@ -113,7 +95,7 @@ def update_axes(ax, mappable=None): # Sub network and new numbering # ----------------------------- # Here we chose to keep only the order 3 segments relatives to our chosen eddy -i = np.where( +i = where( (ioannou_case.lat > 33) * (ioannou_case.lat < 34) * (ioannou_case.lon > 22) @@ -128,22 +110,22 @@ def update_axes(ax, mappable=None): # Anim # ---- # Quick movie to see better! -cmap = colors.ListedColormap( - list(close_to_i3.COLORS), name="from_list", N=close_to_i3.segment.max() -) a = Anim( close_to_i3, figsize=(12, 4), - cmap=cmap, + cmap=colors.ListedColormap( + list(close_to_i3.COLORS), name="from_list", N=close_to_i3.segment.max() + 1 + ), nb_step=7, - dpi=80, + dpi=70, field_color="segment", field_txt="segment", ) a.ax.set_xlim(19, 30), a.ax.set_ylim(32, 35.25) a.ax.update_env() a.txt.set_position((21.5, 32.7)) -kwargs = dict(frames=np.arange(*a.period), interval=100) +# We display in video only from the 100th day to the 500th +kwargs = dict(frames=arange(*a.period)[100:501], interval=100) ani = VideoAnimation(a.fig, a.func_animation, **kwargs) # %% diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index 9993104c..4d62987f 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -2,31 +2,30 @@ Network basic manipulation ========================== """ - -import datetime - from matplotlib import pyplot as plt -from matplotlib.ticker import FuncFormatter +from numpy import where 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)) +n = NetworkObservations.load_file(data.get_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 @@ -37,13 +36,13 @@ # A segment generated by a splitting is marked with a star # # A segment merging in another is marked with an exagon -fig = plt.figure(figsize=(15, 5)) +fig = plt.figure(figsize=(15, 6)) ax = fig.add_axes([0.04, 0.04, 0.92, 0.92]) _ = n.display_timeline(ax) # %% # Display timeline without event -fig = plt.figure(figsize=(15, 5)) +fig = plt.figure(figsize=(15, 6)) ax = fig.add_axes([0.04, 0.04, 0.92, 0.92]) _ = n.display_timeline(ax, event=False) @@ -89,7 +88,7 @@ # # Effective Radius and Amplitude kw = dict(s=25, cmap="Spectral_r", zorder=10) -fig = plt.figure(figsize=(15, 8)) +fig = plt.figure(figsize=(15, 12)) ax = fig.add_axes([0.04, 0.54, 0.90, 0.44]) m = n.scatter_timeline(ax, "radius_e", factor=1e-3, vmin=50, vmax=150, **kw) cb = plt.colorbar( @@ -106,7 +105,7 @@ # %% # Speed -fig = plt.figure(figsize=(15, 5)) +fig = plt.figure(figsize=(15, 6)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) m = n.scatter_timeline(ax, "speed_average", factor=100, vmin=0, vmax=40, **kw) cb = plt.colorbar( @@ -116,7 +115,7 @@ # %% # Speed Radius -fig = plt.figure(figsize=(15, 5)) +fig = plt.figure(figsize=(15, 6)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) m = n.scatter_timeline(ax, "radius_s", factor=1e-3, vmin=20, vmax=100, **kw) cb = plt.colorbar( @@ -128,12 +127,8 @@ # Remove dead branch # ------------------ # Remove all tiny segments with less than N obs which didn't join two segments -# -# .. warning:: -# Must be explore, no solution to solve all cases - -n_clean = n.remove_dead_end(nobs=10) -fig = plt.figure(figsize=(15, 8)) +n_clean = n.remove_dead_end(nobs=5, ndays=10) +fig = plt.figure(figsize=(15, 12)) ax = fig.add_axes([0.04, 0.54, 0.90, 0.40]) ax.set_title(f"Original network ({n.infos()})") n.display_timeline(ax) @@ -141,23 +136,28 @@ ax.set_title(f"Clean network ({n_clean.infos()})") _ = n_clean.display_timeline(ax) +# %% +# For further figure we will use clean path +n = n_clean + # %% # Keep close relative # ------------------- # When you want to investigate one particular observation and select only the closest segments -# + # First choose an observation in the network -fig = plt.figure(figsize=(15, 5)) +i = 1100 + +fig = plt.figure(figsize=(15, 6)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) n.display_timeline(ax) -i = 1100 obs_args = n.time[i], n.segment[i] obs_kw = dict(color="black", markersize=30, marker=".") _ = ax.plot(*obs_args, **obs_kw) # %% # Colors show the relative order of the segment with regards to the chosen one -fig = plt.figure(figsize=(15, 5)) +fig = plt.figure(figsize=(15, 6)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88]) m = n.scatter_timeline( ax, n.obs_relative_order(i), vmin=-1.5, vmax=6.5, cmap=plt.get_cmap("jet", 8), s=10 @@ -194,50 +194,46 @@ # -------------------------- # When you want to investigate one particular event and select only the closest segments # -# First choose an event in the network +# First choose a merging event in the network after, before, stopped = n.merging_event(triplet=True, only_index=True) -i_event = 5 +i_event = 7 # %% # then see some order of relatives - -@FuncFormatter -def formatter(x, pos): - return (datetime.timedelta(x) + datetime.datetime(1950, 1, 1)).strftime("%d/%m/%Y") - - -max_order = 2 +max_order = 1 fig, axs = plt.subplots( max_order + 2, 1, sharex=True, figsize=(15, 5 * (max_order + 2)) ) - -axs[0].set_title("full network", weight="bold") -axs[0].xaxis.set_major_formatter(formatter), axs[0].grid() -mappables = n.display_timeline(axs[0], colors_mode="y") -axs[0].legend() +# Original network +ax = axs[0] +ax.set_title("Full network", weight="bold") +n.display_timeline(axs[0], colors_mode="y") +ax.grid(), ax.legend() for k in range(0, max_order + 1): ax = axs[k + 1] + ax.set_title(f"Relatives order={k}", weight="bold") + # Extract neighbours of event sub_network = n.find_segments_relative(after[i_event], stopped[i_event], order=k) - - ax.set_title(f"relatives order={k}", weight="bold") - ax.xaxis.set_major_formatter(formatter), ax.grid() - - mappables = sub_network.display_timeline(ax, colors_mode="y") - ax.legend() + sub_network.display_timeline(ax, colors_mode="y") + ax.legend(), ax.grid() _ = ax.set_ylim(axs[0].get_ylim()) - # %% # Display track on map # -------------------- + +# Get a simplified network +n = n2.remove_dead_end(nobs=50, recursive=1) +n.numbering_segment() +# %% # Only a map can be tricky to understand, with a timeline it's easier! fig = plt.figure(figsize=(15, 8)) ax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection="full_axes") -close_to_i2.plot(ax, color_cycle=close_to_i2.COLORS) -ax.set_xlim(-13, 20), ax.set_ylim(-36.5, -20), ax.grid() -ax = fig.add_axes([0.08, 0.67, 0.55, 0.3]) -_ = close_to_i2.display_timeline(ax, field="latitude") +n.plot(ax, color_cycle=n.COLORS) +ax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid() +ax = fig.add_axes([0.08, 0.7, 0.7, 0.3]) +_ = n.display_timeline(ax) # %% @@ -246,8 +242,8 @@ def formatter(x, pos): # Display the position of the eddies after a merging fig = plt.figure(figsize=(15, 8)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") -close_to_i2.plot(ax, color_cycle=close_to_i2.COLORS) -m1, m0, m0_stop = close_to_i2.merging_event(triplet=True) +n.plot(ax, color_cycle=n.COLORS) +m1, m0, m0_stop = n.merging_event(triplet=True) m1.display(ax, color="violet", lw=2, label="Eddies after merging") m0.display(ax, color="blueviolet", lw=2, label="Eddies before merging") m0_stop.display(ax, color="black", lw=2, label="Eddies stopped by merging") @@ -255,7 +251,7 @@ def formatter(x, pos): ax.plot(m0.lon, m0.lat, marker=".", color="blueviolet", ls="") ax.plot(m0_stop.lon, m0_stop.lat, marker=".", color="black", ls="") ax.legend() -ax.set_xlim(-10, 20), ax.set_ylim(-37, -21), ax.grid() +ax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid() m1 @@ -265,8 +261,8 @@ def formatter(x, pos): # Display the position of the eddies before a splitting fig = plt.figure(figsize=(15, 8)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") -close_to_i2.plot(ax, color_cycle=close_to_i2.COLORS) -s0, s1, s1_start = close_to_i2.spliting_event(triplet=True) +n.plot(ax, color_cycle=n.COLORS) +s0, s1, s1_start = n.spliting_event(triplet=True) s0.display(ax, color="violet", lw=2, label="Eddies before splitting") s1.display(ax, color="blueviolet", lw=2, label="Eddies after splitting") s1_start.display(ax, color="black", lw=2, label="Eddies starting by splitting") @@ -274,7 +270,7 @@ def formatter(x, pos): ax.plot(s1.lon, s1.lat, marker=".", color="blueviolet", ls="") ax.plot(s1_start.lon, s1_start.lat, marker=".", color="black", ls="") ax.legend() -ax.set_xlim(-10, 20), ax.set_ylim(-37, -21), ax.grid() +ax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid() s1 # %% @@ -283,9 +279,9 @@ def formatter(x, pos): # Display the starting position of non-splitted eddies fig = plt.figure(figsize=(15, 8)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") -birth = close_to_i2.birth_event() +birth = n.birth_event() birth.display(ax) -ax.set_xlim(-10, 20), ax.set_ylim(-37, -21), ax.grid() +ax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid() birth # %% @@ -294,7 +290,7 @@ def formatter(x, pos): # Display the last position of non-merged eddies fig = plt.figure(figsize=(15, 8)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") -death = close_to_i2.death_event() +death = n.death_event() death.display(ax) -ax.set_xlim(-10, 20), ax.set_ylim(-37, -21), ax.grid() +ax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid() death diff --git a/examples/16_network/pet_replay_segmentation.py b/examples/16_network/pet_replay_segmentation.py index 92b448b4..5f5dec45 100644 --- a/examples/16_network/pet_replay_segmentation.py +++ b/examples/16_network/pet_replay_segmentation.py @@ -3,17 +3,13 @@ =================== Case from figure 10 from https://doi.org/10.1002/2017JC013158 +Again with the Ierapetra Eddy """ - -# %% -# Again with the Ierapetra Eddy - from datetime import datetime, timedelta -import numpy as np from matplotlib import pyplot as plt -from matplotlib.animation import FuncAnimation from matplotlib.ticker import FuncFormatter +from numpy import where import py_eddy_tracker.gui from py_eddy_tracker.data import get_path @@ -21,23 +17,6 @@ from py_eddy_tracker.observations.tracking import TrackEddiesObservations -# %% -# Function used to do quick display -class VideoAnimation(FuncAnimation): - def _repr_html_(self, *args, **kwargs): - """To get video in html and have a player""" - return self.to_html5_video() - - 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) - - @FuncFormatter def formatter(x, pos): return (timedelta(x) + datetime(1950, 1, 1)).strftime("%d/%m/%Y") @@ -93,12 +72,6 @@ def follow_obs(cls, i_next, track_id, used, ids, *args, **kwargs): ids["next_obs"][i_next] = i_next_ # Target was previously used if used[i_next_]: - # if ids["next_cost"][i_next] == ids["previous_cost"][i_next_]: - # print(ids[i_next]) - # print(ids[i_next_]) - # m = ids["track"][i_next_:] == ids["track"][i_next_] - # ids["track"][i_next_:][m] = track_id - # ids["previous_obs"][i_next_] = i_next i_next_ = -1 else: ids["previous_obs"][i_next_] = i_next @@ -107,7 +80,7 @@ def follow_obs(cls, i_next, track_id, used, ids, *args, **kwargs): def get_obs(dataset): "Function to isolate a specific obs" - return np.where( + return where( (dataset.lat > 33) * (dataset.lat < 34) * (dataset.lon > 22) @@ -119,9 +92,7 @@ def get_obs(dataset): # %% # Get original network, we will isolate only relative at order *2* -n = NetworkObservations.load_file(get_path("Anticyclonic_seg.nc")) - -n = n.extract_with_mask(n.track == n.track[get_obs(n)]) +n = NetworkObservations.load_file(get_path("network_med.nc")).network(651) n_ = n.relative(get_obs(n), order=2) # %% diff --git a/examples/16_network/pet_segmentation_anim.py b/examples/16_network/pet_segmentation_anim.py index 360ccedf..652c6b4e 100644 --- a/examples/16_network/pet_segmentation_anim.py +++ b/examples/16_network/pet_segmentation_anim.py @@ -8,10 +8,11 @@ from matplotlib import pyplot as plt from matplotlib.animation import FuncAnimation from matplotlib.colors import ListedColormap -from numpy import ones +from numpy import ones, where import py_eddy_tracker.gui -from py_eddy_tracker import data +from py_eddy_tracker.data import get_path +from py_eddy_tracker.observations.network import NetworkObservations from py_eddy_tracker.observations.tracking import TrackEddiesObservations @@ -21,7 +22,7 @@ def _repr_html_(self, *args, **kwargs): """To get video in html and have a player""" content = self.to_html5_video() return re.sub( - 'width="[0-9]*"\sheight="[0-9]*"', 'width="100%" height="100%"', content + r'width="[0-9]*"\sheight="[0-9]*"', 'width="100%" height="100%"', content ) def save(self, *args, **kwargs): @@ -34,6 +35,18 @@ def save(self, *args, **kwargs): return super().save(*args, **kwargs) +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] + + # %% # Overlaod of class to pick up TRACKS = list() @@ -54,11 +67,16 @@ def get_next_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwarg # Load data # --------- # Load data where observations are put in same network but no segmentation -e = MyTrack.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 + +# Get a known network for the demonstration +n = NetworkObservations.load_file(get_path("network_med.nc")).network(651) +# We keep only some segment +n = n.relative(get_obs(n), order=2) +print(len(n)) +# We convert and order object like segmentation was never happen on observations +e = n.astype(MyTrack) +e.obs.sort(order=("track", "time"), kind="stable") + # %% # Do segmentation # --------------- @@ -85,10 +103,10 @@ def update(i_frame): return (mappable_tracks,) -fig = plt.figure(figsize=(15, 8), dpi=60) +fig = plt.figure(figsize=(16, 9), dpi=60) ax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection="full_axes") ax.set_title(f"{len(e)} observations to segment") -ax.set_xlim(-13, 20), ax.set_ylim(-36.5, -20), ax.grid() +ax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid() vmax = TRACKS[-1].max() cmap = ListedColormap(["gray", *e.COLORS[:-1]], name="from_list", N=vmax) mappable_tracks = ax.scatter( diff --git a/notebooks/python_module/01_general_things/pet_storage.ipynb b/notebooks/python_module/01_general_things/pet_storage.ipynb index 35a07dfd..697a8c25 100644 --- a/notebooks/python_module/01_general_things/pet_storage.ipynb +++ b/notebooks/python_module/01_general_things/pet_storage.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# How data is stored\n\nGeneral information about eddies storage.\n\nAll files have the same structure, with more or less fields and possible different order.\n\nThere are 3 class of files:\n\n- **Eddies collections** : contain a list of eddies without link between them\n- **Track eddies collections** : manage eddies associated in trajectories, the ```track``` field allows to separate each trajectory\n- **Network eddies collections** : manage eddies associated in networks, the ```track``` and ```segment``` fields allow to separate observations\n" + "\n# How data is stored\n\nGeneral information about eddies storage.\n\nAll files have the same structure, with more or less fields and possible different order.\n\nThere are 3 class of files:\n\n- **Eddies collections** : contain a list of eddies without link between them\n- **Track eddies collections** :\n manage eddies associated in trajectories, the ```track``` field allows to separate each trajectory\n- **Network eddies collections** :\n manage eddies associated in networks, the ```track``` and ```segment``` fields allow to separate observations\n" ] }, { @@ -112,7 +112,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Trajectories\nTracks eddies collections add several fields :\n\n- **track** : Trajectory number\n- **observation_flag** : Flag indicating if the value is interpolated between two observations or not (0: observed eddy, 1: interpolated eddy)\"\n- **observation_number** : Eddy temporal index in a trajectory, days starting at the eddy first detection\n- **cost_association** : result of the cost function to associate the eddy with the next observation\n\n" + "## Trajectories\nTracks eddies collections add several fields :\n\n- **track** : Trajectory number\n- **observation_flag** : Flag indicating if the value is interpolated between two observations or not\n (0: observed eddy, 1: interpolated eddy)\"\n- **observation_number** : Eddy temporal index in a trajectory, days starting at the eddy first detection\n- **cost_association** : result of the cost function to associate the eddy with the next observation\n\n" ] }, { @@ -130,7 +130,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Networks\nNetwork files use some specific fields :\n\n- track : ID of network (ID 0 correspond to lonely eddies)\n- segment : ID of a segment within a network (from 1 to N)\n- previous_obs : Index of the previous observation in the full dataset, if -1 there are no previous observation (the segment starts)\n- next_obs : Index of the next observation in the full dataset, if -1 there are no next observation (the segment ends)\n- previous_cost : Result of the cost function (1 is a good association, 0 is bad) with previous observation\n- next_cost : Result of the cost function (1 is a good association, 0 is bad) with next observation\n\n" + "## Networks\nNetwork files use some specific fields :\n\n- track : ID of network (ID 0 correspond to lonely eddies)\n- segment : ID of a segment within a network (from 1 to N)\n- previous_obs : Index of the previous observation in the full dataset,\n if -1 there are no previous observation (the segment starts)\n- next_obs : Index of the next observation in the full dataset, if -1 there are no next observation (the segment ends)\n- previous_cost : Result of the cost function (1 is a good association, 0 is bad) with previous observation\n- next_cost : Result of the cost function (1 is a good association, 0 is bad) with next observation\n\n" ] }, { diff --git a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb index 2dcba12d..09bb9df0 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb @@ -62,7 +62,7 @@ }, "outputs": [], "source": [ - "@njit(cache=True, fastmath=True)\ndef check_p(x, y, flse, theta, m_set, m, dt, dist_init=0.02, dist_max=0.6):\n \"\"\"\n Check if distance between eastern or northern particle to center particle is bigger than `dist_max`\n \"\"\"\n nb_p = x.shape[0] // 3\n delta = dist_max ** 2\n for i in range(nb_p):\n i0 = i * 3\n i_n = i0 + 1\n i_e = i0 + 2\n # If particle already set, we skip\n if m[i0] or m[i_n] or m[i_e]:\n continue\n # Distance with north\n dxn, dyn = x[i0] - x[i_n], y[i0] - y[i_n]\n dn = dxn ** 2 + dyn ** 2\n # Distance with east\n dxe, dye = x[i0] - x[i_e], y[i0] - y[i_e]\n de = dxe ** 2 + dye ** 2\n\n if dn >= delta or de >= delta:\n s1 = dn + de\n at1 = 2 * (dxe * dxn + dye * dyn)\n at2 = de - dn\n s2 = ((dxn + dye) ** 2 + (dxe - dyn) ** 2) * (\n (dxn - dye) ** 2 + (dxe + dyn) ** 2\n )\n flse[i] = 1 / (2 * dt) * log2(1 / (2 * dist_init ** 2) * (s1 + s2 ** 0.5))\n theta[i] = arctan2(at1, at2 + s2) * 180 / pi\n # To know where value are set\n m_set[i] = False\n # To stop partcile advection\n m[i0], m[i_n], m[i_e] = True, True, True\n\n\n@njit(cache=True)\ndef build_triplet(x, y, step=0.02):\n \"\"\"\n Triplet building for each position we add east and north point with defined step\n \"\"\"\n nb_x = x.shape[0]\n x_ = empty(nb_x * 3, dtype=x.dtype)\n y_ = empty(nb_x * 3, dtype=y.dtype)\n for i in range(nb_x):\n i0 = i * 3\n i_n, i_e = i0 + 1, i0 + 2\n x__, y__ = x[i], y[i]\n x_[i0], y_[i0] = x__, y__\n x_[i_n], y_[i_n] = x__, y__ + step\n x_[i_e], y_[i_e] = x__ + step, y__\n return x_, y_" + "@njit(cache=True, fastmath=True)\ndef check_p(x, y, flse, theta, m_set, m, dt, dist_init=0.02, dist_max=0.6):\n \"\"\"\n Check if distance between eastern or northern particle to center particle is bigger than `dist_max`\n \"\"\"\n nb_p = x.shape[0] // 3\n delta = dist_max ** 2\n for i in range(nb_p):\n i0 = i * 3\n i_n = i0 + 1\n i_e = i0 + 2\n # If particle already set, we skip\n if m[i0] or m[i_n] or m[i_e]:\n continue\n # Distance with north\n dxn, dyn = x[i0] - x[i_n], y[i0] - y[i_n]\n dn = dxn ** 2 + dyn ** 2\n # Distance with east\n dxe, dye = x[i0] - x[i_e], y[i0] - y[i_e]\n de = dxe ** 2 + dye ** 2\n\n if dn >= delta or de >= delta:\n s1 = dn + de\n at1 = 2 * (dxe * dxn + dye * dyn)\n at2 = de - dn\n s2 = ((dxn + dye) ** 2 + (dxe - dyn) ** 2) * (\n (dxn - dye) ** 2 + (dxe + dyn) ** 2\n )\n flse[i] = 1 / (2 * dt) * log2(1 / (2 * dist_init ** 2) * (s1 + s2 ** 0.5))\n theta[i] = arctan2(at1, at2 + s2) * 180 / pi\n # To know where value are set\n m_set[i] = False\n # To stop particle advection\n m[i0], m[i_n], m[i_e] = True, True, True\n\n\n@njit(cache=True)\ndef build_triplet(x, y, step=0.02):\n \"\"\"\n Triplet building for each position we add east and north point with defined step\n \"\"\"\n nb_x = x.shape[0]\n x_ = empty(nb_x * 3, dtype=x.dtype)\n y_ = empty(nb_x * 3, dtype=y.dtype)\n for i in range(nb_x):\n i0 = i * 3\n i_n, i_e = i0 + 1, i0 + 2\n x__, y__ = x[i], y[i]\n x_[i0], y_[i0] = x__, y__\n x_[i_n], y_[i_n] = x__, y__ + step\n x_[i_e], y_[i_e] = x__ + step, y__\n return x_, y_" ] }, { diff --git a/notebooks/python_module/16_network/pet_atlas.ipynb b/notebooks/python_module/16_network/pet_atlas.ipynb new file mode 100644 index 00000000..59a84a6f --- /dev/null +++ b/notebooks/python_module/16_network/pet_atlas.ipynb @@ -0,0 +1,371 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Network Analysis\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from matplotlib import pyplot as plt\nfrom numpy import ma\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_remote_sample\nfrom py_eddy_tracker.observations.network import NetworkObservations\n\nn = NetworkObservations.load_file(\n get_remote_sample(\n \"eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc\"\n )\n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Parameters\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "step = 1 / 10.0\nbins = ((-10, 37, step), (30, 46, step))\nkw_time = dict(cmap=\"terrain_r\", factor=100.0 / n.nb_days, name=\"count\")\nkw_ratio = dict(cmap=plt.get_cmap(\"YlGnBu_r\", 10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Functions\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def start_axes(title):\n fig = plt.figure(figsize=(13, 5))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=\"full_axes\")\n ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid()\n ax.update_env()\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## All\nDisplay the % of time each pixel (1/10\u00b0) is within an anticyclonic network\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(\"\")\ng_all = n.grid_count(bins)\nm = g_all.display(ax, **kw_time, vmin=0, vmax=75)\nupdate_axes(ax, m).set_label(\"Pixel used in % of time\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Network longer than 10 days\nDisplay the % of time each pixel (1/10\u00b0) is within an anticyclonic network\nwhich total lifetime in longer than 10 days\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(\"\")\nn10 = n.longer_than(10)\ng_10 = n10.grid_count(bins)\nm = g_10.display(ax, **kw_time, vmin=0, vmax=75)\nupdate_axes(ax, m).set_label(\"Pixel used in % of time\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Ratio\nRatio between the longer and total presence\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(\"\")\ng_ = g_10.vars[\"count\"] * 100.0 / g_all.vars[\"count\"]\nm = g_10.display(ax, **kw_ratio, vmin=50, vmax=100, name=g_)\nupdate_axes(ax, m).set_label(\"Pixel used in % all atlas\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Blue = mostly short networks\n\n## Network longer than 20 days\nDisplay the % of time each pixel (1/10\u00b0) is within an anticyclonic network\nwhich total lifetime is longer than 20 days\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(\"\")\nn20 = n.longer_than(20)\ng_20 = n20.grid_count(bins)\nm = g_20.display(ax, **kw_time, vmin=0, vmax=75)\nupdate_axes(ax, m).set_label(\"Pixel used in % of time\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Ratio\nRatio between the longer and total presence\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(\"\")\ng_ = g_20.vars[\"count\"] * 100.0 / g_all.vars[\"count\"]\nm = g_20.display(ax, **kw_ratio, vmin=50, vmax=100, name=g_)\nupdate_axes(ax, m).set_label(\"Pixel used in % all atlas\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we will hide pixel which are used less than 365 times\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "g_ = ma.array(\n g_20.vars[\"count\"] * 100.0 / g_all.vars[\"count\"], mask=g_all.vars[\"count\"] < 365\n)\nax = start_axes(\"\")\nm = g_20.display(ax, **kw_ratio, vmin=50, vmax=100, name=g_)\nupdate_axes(ax, m).set_label(\"Pixel used in % all atlas\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we will hide pixel which are used more than 365 times\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(\"\")\ng_ = ma.array(\n g_20.vars[\"count\"] * 100.0 / g_all.vars[\"count\"], mask=g_all.vars[\"count\"] >= 365\n)\nm = g_20.display(ax, **kw_ratio, vmin=50, vmax=100, name=g_)\nupdate_axes(ax, m).set_label(\"Pixel used in % all atlas\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Coastal areas are mostly populated by short networks\n\n## All merging\nDisplay the occurence of merging events\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(\"\")\ng_all_merging = n.merging_event().grid_count(bins)\nm = g_all_merging.display(ax, **kw_time, vmin=0, vmax=1)\nupdate_axes(ax, m).set_label(\"Pixel used in % of time\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ratio merging events / eddy presence\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(\"\")\ng_ = g_all_merging.vars[\"count\"] * 100.0 / g_all.vars[\"count\"]\nm = g_all_merging.display(ax, **kw_ratio, vmin=0, vmax=5, name=g_)\nupdate_axes(ax, m).set_label(\"Pixel used in % all atlas\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Merging in networks longer than 10 days, with dead end remove (shorter than 10 observations)\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(\"\")\nmerger = n10.remove_dead_end(nobs=10).merging_event()\ng_10_merging = merger.grid_count(bins)\nm = g_10_merging.display(ax, **kw_time, vmin=0, vmax=1)\nupdate_axes(ax, m).set_label(\"Pixel used in % of time\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Merging in networks longer than 10 days\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(\"\")\nmerger = n10.merging_event()\ng_10_merging = merger.grid_count(bins)\nm = g_10_merging.display(ax, **kw_time, vmin=0, vmax=1)\nupdate_axes(ax, m).set_label(\"Pixel used in % of time\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ratio merging events / eddy presence\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(\"\")\ng_ = ma.array(\n g_10_merging.vars[\"count\"] * 100.0 / g_10.vars[\"count\"],\n mask=g_10.vars[\"count\"] < 365,\n)\nm = g_10_merging.display(ax, **kw_ratio, vmin=0, vmax=5, name=g_)\nupdate_axes(ax, m).set_label(\"Pixel used in % all atlas\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## All Spliting\nDisplay the occurence of spliting events\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(\"\")\ng_all_spliting = n.spliting_event().grid_count(bins)\nm = g_all_spliting.display(ax, **kw_time, vmin=0, vmax=1)\nupdate_axes(ax, m).set_label(\"Pixel used in % of time\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ratio spliting events / eddy presence\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(\"\")\ng_ = g_all_spliting.vars[\"count\"] * 100.0 / g_all.vars[\"count\"]\nm = g_all_spliting.display(ax, **kw_ratio, vmin=0, vmax=5, name=g_)\nupdate_axes(ax, m).set_label(\"Pixel used in % all atlas\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Spliting in networks longer than 10 days\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(\"\")\ng_10_spliting = n10.spliting_event().grid_count(bins)\nm = g_10_spliting.display(ax, **kw_time, vmin=0, vmax=1)\nupdate_axes(ax, m).set_label(\"Pixel used in % of time\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(\"\")\ng_ = ma.array(\n g_10_spliting.vars[\"count\"] * 100.0 / g_10.vars[\"count\"],\n mask=g_10.vars[\"count\"] < 365,\n)\nm = g_10_spliting.display(ax, **kw_ratio, vmin=0, vmax=5, name=g_)\nupdate_axes(ax, m).set_label(\"Pixel used in % all atlas\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/notebooks/python_module/16_network/pet_group_anim.ipynb b/notebooks/python_module/16_network/pet_group_anim.ipynb new file mode 100644 index 00000000..1400da0e --- /dev/null +++ b/notebooks/python_module/16_network/pet_group_anim.ipynb @@ -0,0 +1,195 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Network group process\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import re\nfrom datetime import datetime\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.colors import ListedColormap\nfrom numba import njit\nfrom numpy import arange, array, empty, ones\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.generic import flatten_line_matrix\nfrom py_eddy_tracker.observations.network import Network\nfrom py_eddy_tracker.observations.observation import EddiesObservations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "NETWORK_GROUPS = list()\n\n\n@njit(cache=True)\ndef apply_replace(x, x0, x1):\n nb = x.shape[0]\n for i in range(nb):\n if x[i] == x0:\n x[i] = x1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Modified class to catch group process at each step in order to illustrate processing\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "class MyNetwork(Network):\n def get_group_array(self, results, nb_obs):\n \"\"\"With a loop on all pair of index, we will label each obs with a group\n number\n \"\"\"\n nb_obs = array(nb_obs, dtype=\"u4\")\n day_start = nb_obs.cumsum() - nb_obs\n gr = empty(nb_obs.sum(), dtype=\"u4\")\n gr[:] = self.NOGROUP\n\n id_free = 1\n for i, j, ii, ij in results:\n gr_i = gr[slice(day_start[i], day_start[i] + nb_obs[i])]\n gr_j = gr[slice(day_start[j], day_start[j] + nb_obs[j])]\n # obs with no groups\n m = (gr_i[ii] == self.NOGROUP) * (gr_j[ij] == self.NOGROUP)\n nb_new = m.sum()\n gr_i[ii[m]] = gr_j[ij[m]] = arange(id_free, id_free + nb_new)\n id_free += nb_new\n # associate obs with no group with obs with group\n m = (gr_i[ii] != self.NOGROUP) * (gr_j[ij] == self.NOGROUP)\n gr_j[ij[m]] = gr_i[ii[m]]\n m = (gr_i[ii] == self.NOGROUP) * (gr_j[ij] != self.NOGROUP)\n gr_i[ii[m]] = gr_j[ij[m]]\n # case where 2 obs have a different group\n m = gr_i[ii] != gr_j[ij]\n if m.any():\n # Merge of group, ref over etu\n for i_, j_ in zip(ii[m], ij[m]):\n g0, g1 = gr_i[i_], gr_j[j_]\n apply_replace(gr, g0, g1)\n NETWORK_GROUPS.append((i, j, gr.copy()))\n return gr" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Movie period\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "t0 = (datetime(2005, 5, 1) - datetime(1950, 1, 1)).days\nt1 = (datetime(2005, 6, 1) - datetime(1950, 1, 1)).days" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get data from period and area\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "e = EddiesObservations.load_file(data.get_path(\"network_med.nc\"))\ne = e.extract_with_mask((e.time >= t0) * (e.time < t1)).extract_with_area(\n dict(llcrnrlon=25, urcrnrlon=35, llcrnrlat=31, urcrnrlat=37.5)\n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Reproduce individual daily identification(for demonstration)\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "EDDIES_BY_DAYS = list()\nfor i, b0, b1 in e.iter_on(\"time\"):\n EDDIES_BY_DAYS.append(e.index(i))\n# need for display\ne = EddiesObservations.concatenate(EDDIES_BY_DAYS)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Run network building group to intercept every step\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "n = MyNetwork.from_eddiesobservations(EDDIES_BY_DAYS, window=7)\n_ = n.group_observations(minimal_area=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def update(frame):\n i_current, i_match, gr = NETWORK_GROUPS[frame]\n current = EDDIES_BY_DAYS[i_current]\n x = flatten_line_matrix(current.contour_lon_e)\n y = flatten_line_matrix(current.contour_lat_e)\n current_contour.set_data(x, y)\n match = EDDIES_BY_DAYS[i_match]\n x = flatten_line_matrix(match.contour_lon_e)\n y = flatten_line_matrix(match.contour_lat_e)\n matched_contour.set_data(x, y)\n groups.set_array(gr)\n txt.set_text(f\"Day {i_current} match with day {i_match}\")\n s = 80 * ones(gr.shape)\n s[gr == 0] = 4\n groups.set_sizes(s)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Anim\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(16, 9), dpi=50)\nax = fig.add_axes([0, 0, 1, 1])\nax.set_aspect(\"equal\"), ax.grid(), ax.set_xlim(26, 34), ax.set_ylim(31, 35.5)\ngroups = ax.scatter(\n e.lon,\n e.lat,\n c=NETWORK_GROUPS[0][2],\n cmap=ListedColormap([\"gray\", *e.COLORS[:-1]], name=\"from_list\", N=30),\n vmin=0,\n vmax=30,\n)\ncurrent_contour = ax.plot([], [], \"k\", lw=2, label=\"Current contour\")[0]\nmatched_contour = ax.plot([], [], \"r\", lw=1, ls=\"--\", label=\"Candidate contour\")[0]\ntxt = ax.text(29, 35, \"\", fontsize=25)\nax.legend(fontsize=25)\nani = VideoAnimation(fig, update, frames=len(NETWORK_GROUPS), interval=220)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb b/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb index 9855fc85..3cb3e6b6 100644 --- a/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb +++ b/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb @@ -15,25 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# Ioannou case\nFigure 10 from https://doi.org/10.1002/2017JC013158\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We want to find the Ierapetra Eddy described above in the networks\n\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "import re" + "\n# Ioannou case\nFigure 10 from https://doi.org/10.1002/2017JC013158\n\nWe want to find the Ierapetra Eddy described above in a network demonstration run.\n" ] }, { @@ -44,7 +26,7 @@ }, "outputs": [], "source": [ - "from datetime import datetime, timedelta\n\nimport numpy as np\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.ticker import FuncFormatter\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_remote_sample\nfrom py_eddy_tracker.observations.network import NetworkObservations" + "import re\nfrom datetime import datetime, timedelta\n\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.ticker import FuncFormatter\nfrom numpy import arange, where\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.observations.network import NetworkObservations" ] }, { @@ -62,7 +44,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We know the position and the time of a specific eddy\n\n`n.extract_with_mask` give us the corresponding network\n\n" + "We know the network ID, we will get directly\n\n" ] }, { @@ -73,7 +55,7 @@ }, "outputs": [], "source": [ - "n = NetworkObservations.load_file(\n get_remote_sample(\n \"eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc\"\n )\n)\ni = np.where(\n (n.lat > 33)\n * (n.lat < 34)\n * (n.lon > 22)\n * (n.lon < 23)\n * (n.time > 20630)\n * (n.time < 20650)\n)[0][0]\nioannou_case = n.extract_with_mask(n.track == n.track[i])\nprint(ioannou_case.infos())" + "ioannou_case = NetworkObservations.load_file(get_path(\"network_med.nc\")).network(651)\nprint(ioannou_case.infos())" ] }, { @@ -127,7 +109,7 @@ }, "outputs": [], "source": [ - "i = np.where(\n (ioannou_case.lat > 33)\n * (ioannou_case.lat < 34)\n * (ioannou_case.lon > 22)\n * (ioannou_case.lon < 23)\n * (ioannou_case.time > 20630)\n * (ioannou_case.time < 20650)\n)[0][0]\nclose_to_i3 = ioannou_case.relative(i, order=3)\nclose_to_i3.numbering_segment()" + "i = where(\n (ioannou_case.lat > 33)\n * (ioannou_case.lat < 34)\n * (ioannou_case.lon > 22)\n * (ioannou_case.lon < 23)\n * (ioannou_case.time > 20630)\n * (ioannou_case.time < 20650)\n)[0][0]\nclose_to_i3 = ioannou_case.relative(i, order=3)\nclose_to_i3.numbering_segment()" ] }, { @@ -145,7 +127,7 @@ }, "outputs": [], "source": [ - "cmap = colors.ListedColormap(\n list(close_to_i3.COLORS), name=\"from_list\", N=close_to_i3.segment.max()\n)\na = Anim(\n close_to_i3,\n figsize=(12, 4),\n cmap=cmap,\n nb_step=7,\n dpi=80,\n field_color=\"segment\",\n field_txt=\"segment\",\n)\na.ax.set_xlim(19, 30), a.ax.set_ylim(32, 35.25)\na.ax.update_env()\na.txt.set_position((21.5, 32.7))\nkwargs = dict(frames=np.arange(*a.period), interval=100)\nani = VideoAnimation(a.fig, a.func_animation, **kwargs)" + "a = Anim(\n close_to_i3,\n figsize=(12, 4),\n cmap=colors.ListedColormap(\n list(close_to_i3.COLORS), name=\"from_list\", N=close_to_i3.segment.max() + 1\n ),\n nb_step=7,\n dpi=70,\n field_color=\"segment\",\n field_txt=\"segment\",\n)\na.ax.set_xlim(19, 30), a.ax.set_ylim(32, 35.25)\na.ax.update_env()\na.txt.set_position((21.5, 32.7))\n# We display in video only from the 100th day to the 500th\nkwargs = dict(frames=arange(*a.period)[100:501], interval=100)\nani = VideoAnimation(a.fig, a.func_animation, **kwargs)" ] }, { diff --git a/notebooks/python_module/16_network/pet_relative.ipynb b/notebooks/python_module/16_network/pet_relative.ipynb new file mode 100644 index 00000000..e8252900 --- /dev/null +++ b/notebooks/python_module/16_network/pet_relative.ipynb @@ -0,0 +1,511 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Network basic manipulation\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from matplotlib import pyplot as plt\nfrom numpy import where\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.observations.network import NetworkObservations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load data\nLoad data where observations are put in same network but no segmentation\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "n = NetworkObservations.load_file(data.get_path(\"network_med.nc\")).network(651)\ni = where(\n (n.lat > 33)\n * (n.lat < 34)\n * (n.lon > 22)\n * (n.lon < 23)\n * (n.time > 20630)\n * (n.time < 20650)\n)[0][0]\n# For event use\nn2 = n.relative(i, order=2)\nn = n.relative(i, order=4)\nn.numbering_segment()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Timeline\n\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Display timeline with events\nA segment generated by a splitting is marked with a star\n\nA segment merging in another is marked with an exagon\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 6))\nax = fig.add_axes([0.04, 0.04, 0.92, 0.92])\n_ = n.display_timeline(ax)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Display timeline without event\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 6))\nax = fig.add_axes([0.04, 0.04, 0.92, 0.92])\n_ = n.display_timeline(ax, event=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Timeline by mean latitude\nDisplay timeline with the mean latitude of the segments in yaxis\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 5))\nax = fig.add_axes([0.04, 0.04, 0.92, 0.92])\nax.set_ylabel(\"Latitude\")\n_ = n.display_timeline(ax, field=\"latitude\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Timeline by mean Effective Radius\nThe factor argument is applied on the chosen field\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 5))\nax = fig.add_axes([0.04, 0.04, 0.92, 0.92])\nax.set_ylabel(\"Effective Radius (km)\")\n_ = n.display_timeline(ax, field=\"radius_e\", factor=1e-3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Timeline by latitude\nUse `method=\"all\"` to display the consecutive values of the field\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 5))\nax = fig.add_axes([0.04, 0.05, 0.92, 0.92])\nax.set_ylabel(\"Latitude\")\n_ = n.display_timeline(ax, field=\"lat\", method=\"all\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can filter the data, here with a time window of 15 days\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 5))\nax = fig.add_axes([0.04, 0.05, 0.92, 0.92])\nn_copy = n.copy()\nn_copy.median_filter(15, \"time\", \"latitude\")\n_ = n_copy.display_timeline(ax, field=\"lat\", method=\"all\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Parameters timeline\nScatter is usefull to display the parameters' temporal evolution\n\nEffective Radius and Amplitude\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "kw = dict(s=25, cmap=\"Spectral_r\", zorder=10)\nfig = plt.figure(figsize=(15, 12))\nax = fig.add_axes([0.04, 0.54, 0.90, 0.44])\nm = n.scatter_timeline(ax, \"radius_e\", factor=1e-3, vmin=50, vmax=150, **kw)\ncb = plt.colorbar(\n m[\"scatter\"], cax=fig.add_axes([0.95, 0.54, 0.01, 0.44]), orientation=\"vertical\"\n)\ncb.set_label(\"Effective radius (km)\")\n\nax = fig.add_axes([0.04, 0.04, 0.90, 0.44])\nm = n.scatter_timeline(ax, \"amplitude\", factor=100, vmin=0, vmax=15, **kw)\ncb = plt.colorbar(\n m[\"scatter\"], cax=fig.add_axes([0.95, 0.04, 0.01, 0.44]), orientation=\"vertical\"\n)\ncb.set_label(\"Amplitude (cm)\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Speed\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 6))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88])\nm = n.scatter_timeline(ax, \"speed_average\", factor=100, vmin=0, vmax=40, **kw)\ncb = plt.colorbar(\n m[\"scatter\"], cax=fig.add_axes([0.95, 0.04, 0.01, 0.92]), orientation=\"vertical\"\n)\ncb.set_label(\"Maximum speed (cm/s)\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Speed Radius\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 6))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88])\nm = n.scatter_timeline(ax, \"radius_s\", factor=1e-3, vmin=20, vmax=100, **kw)\ncb = plt.colorbar(\n m[\"scatter\"], cax=fig.add_axes([0.95, 0.04, 0.01, 0.92]), orientation=\"vertical\"\n)\ncb.set_label(\"Speed radius (km)\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Remove dead branch\nRemove all tiny segments with less than N obs which didn't join two segments\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "n_clean = n.remove_dead_end(nobs=5, ndays=10)\nfig = plt.figure(figsize=(15, 12))\nax = fig.add_axes([0.04, 0.54, 0.90, 0.40])\nax.set_title(f\"Original network ({n.infos()})\")\nn.display_timeline(ax)\nax = fig.add_axes([0.04, 0.04, 0.90, 0.40])\nax.set_title(f\"Clean network ({n_clean.infos()})\")\n_ = n_clean.display_timeline(ax)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For further figure we will use clean path\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "n = n_clean" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Keep close relative\nWhen you want to investigate one particular observation and select only the closest segments\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# First choose an observation in the network\ni = 1100\n\nfig = plt.figure(figsize=(15, 6))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88])\nn.display_timeline(ax)\nobs_args = n.time[i], n.segment[i]\nobs_kw = dict(color=\"black\", markersize=30, marker=\".\")\n_ = ax.plot(*obs_args, **obs_kw)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Colors show the relative order of the segment with regards to the chosen one\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 6))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88])\nm = n.scatter_timeline(\n ax, n.obs_relative_order(i), vmin=-1.5, vmax=6.5, cmap=plt.get_cmap(\"jet\", 8), s=10\n)\nax.plot(*obs_args, **obs_kw)\ncb = plt.colorbar(\n m[\"scatter\"], cax=fig.add_axes([0.95, 0.04, 0.01, 0.92]), orientation=\"vertical\"\n)\ncb.set_label(\"Relative order\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You want to keep only the segments at the order 1\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 5))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88])\nclose_to_i1 = n.relative(i, order=1)\nax.set_title(f\"Close segments ({close_to_i1.infos()})\")\n_ = close_to_i1.display_timeline(ax)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You want to keep the segments until order 2\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 5))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88])\nclose_to_i2 = n.relative(i, order=2)\nax.set_title(f\"Close segments ({close_to_i2.infos()})\")\n_ = close_to_i2.display_timeline(ax)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You want to keep the segments until order 3\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 5))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88])\nclose_to_i3 = n.relative(i, order=3)\nax.set_title(f\"Close segments ({close_to_i3.infos()})\")\n_ = close_to_i3.display_timeline(ax)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Keep relatives to an event\nWhen you want to investigate one particular event and select only the closest segments\n\nFirst choose a merging event in the network\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "after, before, stopped = n.merging_event(triplet=True, only_index=True)\ni_event = 7" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "then see some order of relatives\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "max_order = 1\nfig, axs = plt.subplots(\n max_order + 2, 1, sharex=True, figsize=(15, 5 * (max_order + 2))\n)\n# Original network\nax = axs[0]\nax.set_title(\"Full network\", weight=\"bold\")\nn.display_timeline(axs[0], colors_mode=\"y\")\nax.grid(), ax.legend()\n\nfor k in range(0, max_order + 1):\n ax = axs[k + 1]\n ax.set_title(f\"Relatives order={k}\", weight=\"bold\")\n # Extract neighbours of event\n sub_network = n.find_segments_relative(after[i_event], stopped[i_event], order=k)\n sub_network.display_timeline(ax, colors_mode=\"y\")\n ax.legend(), ax.grid()\n _ = ax.set_ylim(axs[0].get_ylim())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Display track on map\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Get a simplified network\nn = n2.remove_dead_end(nobs=50, recursive=1)\nn.numbering_segment()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Only a map can be tricky to understand, with a timeline it's easier!\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 8))\nax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=\"full_axes\")\nn.plot(ax, color_cycle=n.COLORS)\nax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid()\nax = fig.add_axes([0.08, 0.7, 0.7, 0.3])\n_ = n.display_timeline(ax)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Get merging event\nDisplay the position of the eddies after a merging\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 8))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection=\"full_axes\")\nn.plot(ax, color_cycle=n.COLORS)\nm1, m0, m0_stop = n.merging_event(triplet=True)\nm1.display(ax, color=\"violet\", lw=2, label=\"Eddies after merging\")\nm0.display(ax, color=\"blueviolet\", lw=2, label=\"Eddies before merging\")\nm0_stop.display(ax, color=\"black\", lw=2, label=\"Eddies stopped by merging\")\nax.plot(m1.lon, m1.lat, marker=\".\", color=\"purple\", ls=\"\")\nax.plot(m0.lon, m0.lat, marker=\".\", color=\"blueviolet\", ls=\"\")\nax.plot(m0_stop.lon, m0_stop.lat, marker=\".\", color=\"black\", ls=\"\")\nax.legend()\nax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid()\nm1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Get spliting event\nDisplay the position of the eddies before a splitting\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 8))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection=\"full_axes\")\nn.plot(ax, color_cycle=n.COLORS)\ns0, s1, s1_start = n.spliting_event(triplet=True)\ns0.display(ax, color=\"violet\", lw=2, label=\"Eddies before splitting\")\ns1.display(ax, color=\"blueviolet\", lw=2, label=\"Eddies after splitting\")\ns1_start.display(ax, color=\"black\", lw=2, label=\"Eddies starting by splitting\")\nax.plot(s0.lon, s0.lat, marker=\".\", color=\"purple\", ls=\"\")\nax.plot(s1.lon, s1.lat, marker=\".\", color=\"blueviolet\", ls=\"\")\nax.plot(s1_start.lon, s1_start.lat, marker=\".\", color=\"black\", ls=\"\")\nax.legend()\nax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid()\ns1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Get birth event\nDisplay the starting position of non-splitted eddies\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 8))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection=\"full_axes\")\nbirth = n.birth_event()\nbirth.display(ax)\nax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid()\nbirth" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Get death event\nDisplay the last position of non-merged eddies\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 8))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection=\"full_axes\")\ndeath = n.death_event()\ndeath.display(ax)\nax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid()\ndeath" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/notebooks/python_module/16_network/pet_replay_segmentation.ipynb b/notebooks/python_module/16_network/pet_replay_segmentation.ipynb new file mode 100644 index 00000000..5715f6e3 --- /dev/null +++ b/notebooks/python_module/16_network/pet_replay_segmentation.ipynb @@ -0,0 +1,180 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Replay segmentation\nCase from figure 10 from https://doi.org/10.1002/2017JC013158\n\nAgain with the Ierapetra Eddy\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from datetime import datetime, timedelta\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.ticker import FuncFormatter\nfrom numpy import where\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations\n\n\n@FuncFormatter\ndef formatter(x, pos):\n return (timedelta(x) + datetime(1950, 1, 1)).strftime(\"%d/%m/%Y\")\n\n\ndef start_axes(title=\"\"):\n fig = plt.figure(figsize=(13, 6))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=\"full_axes\")\n ax.set_xlim(19, 29), ax.set_ylim(31, 35.5)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n ax.update_env()\n return ax\n\n\ndef timeline_axes(title=\"\"):\n fig = plt.figure(figsize=(15, 5))\n ax = fig.add_axes([0.04, 0.06, 0.89, 0.88])\n ax.set_title(title, weight=\"bold\")\n ax.xaxis.set_major_formatter(formatter), ax.grid()\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid(True)\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Class for new_segmentation\nThe oldest win\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "class MyTrackEddiesObservations(TrackEddiesObservations):\n __slots__ = tuple()\n\n @classmethod\n def follow_obs(cls, i_next, track_id, used, ids, *args, **kwargs):\n \"\"\"\n Method to overwrite behaviour in merging.\n\n We will give the point to the older one instead of the maximum overlap ratio\n \"\"\"\n while i_next != -1:\n # Flag\n used[i_next] = True\n # Assign id\n ids[\"track\"][i_next] = track_id\n # Search next\n i_next_ = cls.get_next_obs(i_next, ids, *args, **kwargs)\n if i_next_ == -1:\n break\n ids[\"next_obs\"][i_next] = i_next_\n # Target was previously used\n if used[i_next_]:\n i_next_ = -1\n else:\n ids[\"previous_obs\"][i_next_] = i_next\n i_next = i_next_\n\n\ndef get_obs(dataset):\n \"Function to isolate a specific obs\"\n return where(\n (dataset.lat > 33)\n * (dataset.lat < 34)\n * (dataset.lon > 22)\n * (dataset.lon < 23)\n * (dataset.time > 20630)\n * (dataset.time < 20650)\n )[0][0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get original network, we will isolate only relative at order *2*\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "n = NetworkObservations.load_file(get_path(\"network_med.nc\")).network(651)\nn_ = n.relative(get_obs(n), order=2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Display the default segmentation\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(n_.infos())\nn_.plot(ax, color_cycle=n.COLORS)\nupdate_axes(ax)\nfig = plt.figure(figsize=(15, 5))\nax = fig.add_axes([0.04, 0.05, 0.92, 0.92])\nax.xaxis.set_major_formatter(formatter), ax.grid()\n_ = n_.display_timeline(ax)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Run a new segmentation\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "e = n.astype(MyTrackEddiesObservations)\ne.obs.sort(order=(\"track\", \"time\"), kind=\"stable\")\nsplit_matrix = e.split_network(intern=False, window=7)\nn_ = NetworkObservations.from_split_network(e, split_matrix)\nn_ = n_.relative(get_obs(n_), order=2)\nn_.numbering_segment()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## New segmentation\n\"The oldest wins\" method produce a very long segment\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(n_.infos())\nn_.plot(ax, color_cycle=n_.COLORS)\nupdate_axes(ax)\nfig = plt.figure(figsize=(15, 5))\nax = fig.add_axes([0.04, 0.05, 0.92, 0.92])\nax.xaxis.set_major_formatter(formatter), ax.grid()\n_ = n_.display_timeline(ax)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Parameters timeline\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "kw = dict(s=35, cmap=plt.get_cmap(\"Spectral_r\", 8), zorder=10)\nax = timeline_axes()\nn_.median_filter(15, \"time\", \"latitude\")\nm = n_.scatter_timeline(ax, \"shape_error_e\", vmin=14, vmax=70, **kw, yfield=\"lat\")\ncb = update_axes(ax, m[\"scatter\"])\ncb.set_label(\"Effective shape error\")\n\nax = timeline_axes()\nn_.median_filter(15, \"time\", \"latitude\")\nm = n_.scatter_timeline(\n ax, \"shape_error_e\", vmin=14, vmax=70, **kw, yfield=\"lat\", method=\"all\"\n)\ncb = update_axes(ax, m[\"scatter\"])\ncb.set_label(\"Effective shape error\")\nax.set_ylabel(\"Latitude\")\n\nax = timeline_axes()\nn_.median_filter(15, \"time\", \"latitude\")\nkw[\"s\"] = (n_.radius_e * 1e-3) ** 2 / 30 ** 2 * 20\nm = n_.scatter_timeline(\n ax,\n \"shape_error_e\",\n vmin=14,\n vmax=70,\n **kw,\n yfield=\"lon\",\n method=\"all\",\n)\nax.set_ylabel(\"Longitude\")\ncb = update_axes(ax, m[\"scatter\"])\ncb.set_label(\"Effective shape error\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Cost association plot\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "n_copy = n_.copy()\nn_copy.median_filter(2, \"time\", \"next_cost\")\nfor b0, b1 in [\n (datetime(i, 1, 1), datetime(i, 12, 31)) for i in (2004, 2005, 2006, 2007, 2008)\n]:\n\n ref, delta = datetime(1950, 1, 1), 20\n b0_, b1_ = (b0 - ref).days, (b1 - ref).days\n ax = timeline_axes()\n ax.set_xlim(b0_ - delta, b1_ + delta)\n ax.set_ylim(0, 1)\n ax.axvline(b0_, color=\"k\", lw=1.5, ls=\"--\"), ax.axvline(\n b1_, color=\"k\", lw=1.5, ls=\"--\"\n )\n n_copy.display_timeline(ax, field=\"next_cost\", method=\"all\", lw=4, markersize=8)\n\n n_.display_timeline(ax, field=\"next_cost\", method=\"all\", lw=0.5, markersize=0)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb new file mode 100644 index 00000000..443a1a8f --- /dev/null +++ b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb @@ -0,0 +1,137 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Network segmentation process\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.colors import ListedColormap\nfrom numpy import ones, where\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)\n\n\ndef get_obs(dataset):\n \"Function to isolate a specific obs\"\n return where(\n (dataset.lat > 33)\n * (dataset.lat < 34)\n * (dataset.lon > 22)\n * (dataset.lon < 23)\n * (dataset.time > 20630)\n * (dataset.time < 20650)\n )[0][0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Overlaod of class to pick up\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "TRACKS = list()\nINDICES = list()\n\n\nclass MyTrack(TrackEddiesObservations):\n @staticmethod\n def get_next_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs):\n TRACKS.append(ids[\"track\"].copy())\n INDICES.append(i_current)\n return TrackEddiesObservations.get_next_obs(\n i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs\n )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load data\nLoad data where observations are put in same network but no segmentation\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Get a known network for the demonstration\nn = NetworkObservations.load_file(get_path(\"network_med.nc\")).network(651)\n# We keep only some segment\nn = n.relative(get_obs(n), order=2)\nprint(len(n))\n# We convert and order object like segmentation was never happen on observations\ne = n.astype(MyTrack)\ne.obs.sort(order=(\"track\", \"time\"), kind=\"stable\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Do segmentation\nSegmentation based on maximum overlap, temporal window for candidates = 5 days\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "matrix = e.split_network(intern=False, window=5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Anim\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def update(i_frame):\n tr = TRACKS[i_frame]\n mappable_tracks.set_array(tr)\n s = 40 * ones(tr.shape)\n s[tr == 0] = 4\n mappable_tracks.set_sizes(s)\n\n indices_frames = INDICES[i_frame]\n mappable_CONTOUR.set_data(\n e.contour_lon_e[indices_frames],\n e.contour_lat_e[indices_frames],\n )\n mappable_CONTOUR.set_color(cmap.colors[tr[indices_frames] % len(cmap.colors)])\n return (mappable_tracks,)\n\n\nfig = plt.figure(figsize=(16, 9), dpi=60)\nax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=\"full_axes\")\nax.set_title(f\"{len(e)} observations to segment\")\nax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid()\nvmax = TRACKS[-1].max()\ncmap = ListedColormap([\"gray\", *e.COLORS[:-1]], name=\"from_list\", N=vmax)\nmappable_tracks = ax.scatter(\n e.lon, e.lat, c=TRACKS[0], cmap=cmap, vmin=0, vmax=vmax, s=20\n)\nmappable_CONTOUR = ax.plot(\n e.contour_lon_e[INDICES[0]], e.contour_lat_e[INDICES[0]], color=cmap.colors[0]\n)[0]\nani = VideoAnimation(fig, update, frames=range(1, len(TRACKS), 4), interval=125)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/src/py_eddy_tracker/data/network_med.nc b/src/py_eddy_tracker/data/network_med.nc new file mode 100644 index 0000000000000000000000000000000000000000..d695b09bf66cce15a2d4c2302de852274c0b7618 GIT binary patch literal 1243290 zcmeFZ1yo(jvM9Q6ch}(V9wfK~_u%dxJh;0Chv328-6d#{Ai+IYkU((zNZ99`efB=@ z-8=4ofBZMnu&CM9)zvjidiLzw@gf9`&jz^5dKOnR%tgW;SL+!x#p3Dyb0>XU20|7l58{*|d4FGtCAgB)-MQQLWb)ymXX$05agE>1|UAhLd7qwS>01Slqc+2=aXBKJzMJW z4xcFg{jb`ca=M6uf-per@TnV+9RLvi$Qb4=tjj-%`_~Tq#Br>5DqKcTOafNtL1rKT z*yG(u^GgXov_ISp-~H$LZWK*S?FjCFbqTBt?FEHI2n zFfcUs6XHRLhe4hve8|7`fv31*czOx|P@iP|6^)!kPuxB}0l*(7d8#+^ku(0;d@D@9OyAzr(U3sj+REPA!It1&n_UAG#VE7#qSeK1~_Wk22rS&&JwTx|W7dqCU$0;Ka{X;+Gn;34UGQUEN>7#-Rt#|eKmY>30ATOA>KYhmTN@eK8QMRx0wCVAeCGOq`8#e; z)BwPPj9~ZN5bix4^Pi@A$=3>s0Kmh#uZRFppCHJ0A9L@DJ1HL-{j*_$Tzg;h!Hff2RMX?ti04 z`Wrq^@&51QK2Ax0ArI=`@Im{9fBg&cI~v;R8XFSW*%%rcJV*OqhNG>nfvJNX!DE0B zta^QT?4kXHUG+-+#qW6u`{(<8@Xd$vXZ-V%>(BV-we~aq*}lJK-hbnR^Tht&@VI}% zKl8!+6aLvx@c#z?;&1Q-e}n&p2IN0G(lg>W{H=lC8u+b&-x~O>f!`YVt%2Vf_^pB8 z8u+b&|Bp2AxF;m^v{wQ8xC3Ho`n1`IMDXuh+7Ckh-R?r;mtZN_drlAg6u&s>IzQgk zf0fe@H6Xc{4xLbsyIznFJ8Tbc#Re4oAWxeG|JbzLDDs8#SCZ~llouBMtBlIY{m#)} z6;7&u#Xj#QKJRk;YwPdYZw>s`z;6xw*1&HK{MNw#4H|e{^@suPQ|f=LRsLA@{CDy_ zI*<7th<|YVW99Q-<96v`)@&d1mA4VaSmS>)|M_(M;4ju{V2_#6hdk)hs_D=T^zlH# zbL~IpLZ7G}@97{@wmhmO?#K|=bSb_*b~)1R`)`~ z6tI7O2QY$t8uK4i!nmmqNuoufXDOdxWaKg8A0hN0@_pL>N$Tgt{&Q;X&-GtN3htRc zy$<~ONCA-7KaLatdHv@wdgAb)ufGnX=V*ZfX#P^t@~;SJ{guaue9WAI0E4jpI&JnK z?t|!$tO=iP_USm%AJ}KfpBsCI*!i9;e1E3nvHSvmIM*}fpDir+D_{F;*=Lwhn1O1) z6VM&`q~abRp#LAJ*azmxch-NYwiD+`4S%TE3hv1T|3$^$o^|uj*r(a*x#i#B!$E`p zW_fspe)gLGCW~L)U}^rVhvr@=C~J$zi^)D_QGp-N6#U}#e8}s=FUQ%W{MGQJu&1g2 zpTvDm!~YZNFE8)AKXdryixl_JL;E>4{S4MIo;>$? z&(+vIWjd}zFzalQYYavX(hI<`L^NYDX(DqSIwB_yAfFaBDwj&{ygp@x*2?tLhY z>VCY${3=O=1k>AKyu5~R=A?<&Ode@F%eZ z^hT%(uO*pE66GaxW&6VPuuJOmgCxmgLPJCIolEP3G$e@>Occ%DA{7Mr zQIW-n^^jbDN-1zgD8ejzZ)zbg_m;5=(llxaiI|@EUUi+w7KxD&n{2q9loB&k+^6R?Dizoo5=`#s4;n@cDs(`0bP$$;7$%m4 z5h{{zbm*3IbcE9~NFrEmaQJXL6Qv}!GGq}$g*|6Qkp)>zkYr9}1>$!CbZBCo9RUqk z`ei0zYIPOAOdDG6j*ND3XPhKx2rpJ$*6-XkVqOP5!XNZFVbF-x((u_!wm_!lCmeBYtg&B>4{=Jf>jbL*~4ba@tdc!ix4-F&8ip;GlebTaNt|4McurwVSoPH10=;3CXG$;$YW_E-sabDkD7< zzA$0cHY(>L&|S8IX+2eKWqxA67b)c2c+z=jKz}p?F?>LWbt3ReWTGfiZTM@VG_kYiF9#D!G6FSD>jy7b5rk2%HS_G=<-;x zYFwKacT|W}6N2BIr@Axf}>Jo0?Iwz`YE#fHw~vwo-ypRSb|N zC{Ls%ixDSXtxV!sa#~tO=O?~Sd~iy{+sM>;N0Qt(Wvs5AjQze~Hd%-$tsNQzZSl5s(c7CiN5Oh^ps#tUp~`d3a|2gDc3TR-9aJa5*@8!VbOsU{_rWP3v}hBd5g z7p#`eszWX@A9UJ3Hi(Dw18CAF`36&gJ6ba@E-A zav2CgPL?|@B_kDHhK0Ws(R+pbBY9^aL?@qH7X9#ov#H4i+S1bDB>W=2_Ov$sTfn6v z9BhAtUk&NNE@)9EwPN^4_T`gH5Rba-i4BHrUqeHD{B&wWN}k({87zhs z>#{*3X3TJx21zP3sCOD^qx-g39}blQW4>Ca3>!?CE2#+vkAJ6t1H0bH3@Hqe6?SlF zCW|X9E0dVaU5hikJ<@rn+P+IkeGJx;Q;VFcoTCUCPA5Y!u9!YNnYUvgwd$tHBwY|8 zB8V2f<6K!$(&l92Twd11niBEmjS}d9FMeQ;(G-P&8=Y?up^dW*i ztD3BxE!@m(-HNlbt6FMG2#_T{;#tB4i?PIfo|s&tR!_G!9WYd9g1c~g<77?WDiRO~ zF)xLu>E6PV>Yv-I!4@;LfrE{+^QFJGSCVOQ0vFbK;T(b;G7h5RWtt6%JX&dCq1f~U z$?6Xk7G*r>JTv49%+JzNQkkVib-dW&)4fGS)B@46oY9ta_Ks)p@Zn+h)u^0DGX@T% z(xTjQ+S5_yR{P(-Z(Ep~6_-^dmeiX0wvbJaD{XD#;9}w3+gY0#@~l0dwW3f=|MLnB zV@jNvTsdwasfL_V%;)vB?OXw;H%sSR>tB;Ig9+VoV?MlA_UDmrkcSg34I#mS#?x#8 z;Sto*RxKEW`$XxWIwVpuw0p*!y=@`L{B3d}nEm7@LIivy?1=-LvDxa6osi0L`EF)U z2Cu+27Q~RrDfXJ`+FG`{8prCI+G;jdHa3jLt3VO(00{8LIa}6D`Km>oikUsOlpc%P zmpmNsAQ!DB6kMaG!H03ME?s^ECJ}-H3F^{j&z{`hpxtBZlT{7ed^c z=>;QXR7J?9LXE(VHBnNZu7P0J=p2ai)x@jKUZJRd2$21}{DZ@bug?IM69R}YYdpom z5p-AHy8T6150$D$g`{XV3~u#~Jsp+<*LUd{t&-T#Vn(|}2BXr72Ff?-ugR&_R*o2G z!t&AKLAf27jjSqEaoG|Uly;8J2dN9QS(R!EH0&hQ)m@Dh0y+*wvQ`WDc(gK58YRd?0w%`lXq_TfiVRVYc`W4h(!awbfI$DQ|AsG3sz-A5vY;XV%f}+ z@-b5x(Funy?JK>F^k>&DMu;8MPm51v))jD)TK>U>amGB8I^;EVW+rsD&qLjG@xTauvwXai7tGNNwGui44ZK zBxd`>8;!SMVWovcKFY{hoQ zD};}@2Q`AP4=moW0*j?ktZ>{^<8VHsjY=_Ycq19+#@q%q9UuV^IxY@6NN zN|?+BYm0^JTD+!OOZC|n_fJz&DaInRYa8(3w&nU~SKEmAMPF)H|qj-=F>6 z`&FtcoYqsj2>ya!*31K3IMuOj8+xbqGsniZ`&T+{)6z=QyfdT6GQC@a`}=47EnQ37 zer(ZpuWjwIFO@q?PnD=U(rSCINwF`wTzB_#fnQy6f?Myt9AB6mYpAca(=~E)vv0OG zuy9$sp2BlI{jNIOYJQiNgEv?A*)lOHMLiKqoq2qEY-&<&Ya7CCYwuv&Oj_wm+`U7V zLKeNWI6_qPeN9Y5W3qjw=R&SOt*ax={#RF>rFb3~yJI_M^?3O2OTqk?P0$5ynJ-gE zi~zn=%{h)u88uEf?T1?ceD@n3_Zxk8&7ZZcnMr#P5sNOL@Yr80)Ky!4N&|s_$LA<- zey8hUBqj64+Et${Vb~DhR=KT61CEIt+K&odAlrx0PTYq|6-tg2(k;L4R`g}_tnubm z!t|yfhy9FYt{BJiTg*v58;$c!acd_I_Z3+s%iLGt9GY6n-yDMdxzT-xSC0LWlREfx zAYyvH*|;J$a9h=ViIA$xqT#a?%&mGS&?@HV{$3oFvqX(dVMo$YFNLZwOKHP9BqT(Z zLjwt@Rp96(ISx8Uo)8Ht$F^ilk3B_73|A~kq=mmsj?x~P_As=JM&(=e+z@!GINdiU z3YKJ*Tvjza$0|8uq@%ah^%iU>$0!m#MEEfQ#DL<+PUJkuNsLsA+Msb?zB|5463)op z)y}*I4gB&=3xKE{&|CU4rgwjGf&wG?b`Z#Ib8JX5`Szee^)PwM7L0E>sQF4~BfiC? zpa}t5K4%iDueD-0D+O&cRFiT0u8Mdn{6~(y7wW?-KyvzJ>J;B zbVUnBEHf9MD?>~y-9c=uvR*AE%fvPP)I*ga$pR-EGw3zBx|CALrVW-gbJokJ#xAlr z*r&F4aBy;nv|sUas>W|4ZKFm%s{cS{NE1!Ks={$e@u{RYStVnnN$Lqhh(gJ?uRk-iip~C@rW8#rtl+@57 zg_(TUs^%OIW*Xe*u9t_lI(tiCTzf@xr^;~fEx4MEbbKyA6Jz?pDLU@mZHYRz#>(iAJ^aT~g*|u#DVnHC`=*VGA~bhE7YZb(z^l}d%zjvGgdXU);f!U9Q> z?O(m{JpYVSrqy&hf5z*4Qo^3@y7f~NW54bCyWNueS%bNC^Vv*7+tuESyPrJ?Z5In~ z+T5U2Kr^UM$vpqJQPQGTy&NE|dPseYF=S0+;9A zekU=4rrXaSqG_J{+vNDoo81>zBk8T1^X?e?ybcFB!<=dl);5Da3_x(lJ&x;iFp*mBJ4u^b&f5*tXNwNs zO4pV=4tJauZd3C$I$DaP~XeOccxP{&GXbgh)YVzRr zg1znL=!;C-B-&s?u%D9TQ>(SN8?3Ho>vR$%~!qV^sR^2=Dg=C>eekcHwSG$ zE_cgXP6vuc+J5e+zwr2ZoPP7O1>tVxll9H=NkV#)%a8Bjb@R@gXNs#zGmy~R!QFHSN0c2lX+?GE3;olntvjHJM4PXc07(_?SA-U=-|IIfK;EP^+iXM!;x}IZWS&lQzYNYReRVcI_rl{M z!SiacP0I-nO$a#ksKmOJKOTHRr{*i(O0s=1nHEloz~_O9X(15&&+l033 z?K5qRiV9%-jghmu4Qf4N9Od+=d;u!uWU!$jjfwb)>Fx)KXBV!N6c9@dvxUv ztJhl0wK%=-TD7eEKF8fwnpsg|ZS-Y)YT+tk;kb`Df$jr`+j9GGdmKC7D`)4;m5qjm zi;JWa7*}|_rmOEWYjyMXSE=MyZSPF4e#+kIWM-~qNT#rjs(`e@ zo`Ly+NIJ6Q4dtB)P%d{zEw2EDfMY|x>H%aySVIkSmZ zI6QB>UyM{osvx`r6&ejW7?T4)@iIOk7H7>+&BQCtm?KuOX&NLXo z3Na896q6I-Eqs%${ShI2NCA*C-D|-@z`s?Z+9AdzuytwcwI=tHgsK^%3G4zPR zJ;2^3Ifz7G-*BRIGlmmK6`@j*3ifY|B}tZNYDACk!qmfYtE)Ol73Pjx3-JeEThTCX z#Zt(HMU3mvC?r^$S(zX7g7kkJO)UAL-i?a=7PN;W1)D~eKnLjM8jvJ-V=~>!=*m&z zD`3#T;Y?;#8hG&wBJ@y!OC@~W7L{tJm=Ba2f%qjlN zIH<)(1@Q*AZc?^DkZ-cNvgUw64nPU;#Zd|QXYJ%SeWi6;bea31 zUzg5dH{Ag9ChgtYJP5-4-CmVb+vWHV<8-&32KD{=-D`h|gcsaSN8NaJ3${9@bGZ$c zu4j1MSM3EknuAwmypBiLU6DMe>u4XV1L-syFVABlH5-0z>Ay*LS&4h2B}C`G-D5uT z>atrufnM9=dM8H$LECM4KQtk&)p4&ULCgJO14G+=<03Du`FhJ2LHph5Y|M08gC9Hh zMR(k%vR6NTcAfED+)v&-=X-(sZJSma*A;>E+&@QqAP!nLhx)5F_jx=|e=clFr`8{M zH|_I5^VqM^vTL?A+kN>dd(ipKvV|CA4To)S-eZ?``e2Tey-oihei%M!>CVosIWl3M2(S?#&38FOC!`h_s3M7*FfyP@SjSTlHt4-Q+ly;ZwKsaHV5pI0z{L#+ z)dq${uMq*tEy+@Xn*jkP5vAZwL6l#%C*|S8hlJz&;0&2N@)BI!mR}bY4c-9R0;|+C zj4r|tK+LNFugg-+O)X3ZgG_Im5Box7GQJ-RvCRSQ(-sQ2k{!*>kWIohfSCYr2tYST z5_lCI`|IJ0c?yBJb?l8vw3Ep0WM2zF0B-_NAuD0gecwae_Mv!lDgbF_ck){xL4MT3 zPY|XyTK=Fz1JBo@QNo@KIZD4eKE||$2qCtTFFEB@Gdb-)K)rSn-Vm=?%_eWfN)3>D ztq~g!sf!EVV*q?opuEMZhBymdLaO-XYnu7~K7e^?lAXK3X8Cg!#)13t^^5|!HBYnW zQiLWK1lMfs3m(Tif9etUO)h%w+e4l_tEQ9hAQ;B%!{HW-4Q}VlXt$OE;otQWDJV)0G3HWW7>s9n^w+k|_Ziad9O7gep)7!2F%*&dOe4Q3O@A3{> z&K4sV>raRD5#~KtDmJxvPWIBT&x6V7cp^c5Of;Z4rSW*)UNo`!>_>eM`$e@3tEpNC!yZu~`|o_b_m^xi)vxi`J_H9@opC1;@tHxQnf8 z?fX2tWYeVZPVn$0bIn(yC+u|eRv*&THPjZ{oQ@YkTx%^cfvnk@O?Ssz7hF&G7r3~l z=Dx5pRn$9t+E1NhAO1XIy~y44PS-`x*2U4oQTM9U5(0jy-1zEy=lAOXhqW#cJSn&! zCWoZP5F3JIVDg!<#l_eVP@c3(9S-H_J|~1QY1o>L!g;j_m72A_{?Iq+?%Uz%Zr3w! z+V1YxhPNjeZRhL02kv*1Z?rr&yVCD=Ld!f(zHuGgu1=?Wo(_(*onMExF@j~RO%P%E zr~>2`H)$Q}C8+IE_02`5rH6~PdF$R1t0Z*XdauypOv7&|1TC^|{MZruSW{Z#YG7eo zU*)M|w0oK=5o)(90)xjRXdb}XG&^2k4?Zs{V=U^FSunb&ln*nbh?^tO<8-cBi!5l$ z5K&2_vCs6XPbgOs)#1nd-QgZFJ0$1iSAhuhq5%7nG=lBlQ|6DZE7 zZ+;v{@?Njs>*Vxk*Sh8GHZc7b{rqQ@cJtj2-s{7rGA;L`F=PBD`;mqwnRyRqQ>$u+ z{85FzQ%U-T>t(xpf7%I^;c?sly6q~1%T;f+lDj+dp=q-;<`ew>V&mH{_SzrGqRqB2 zlhahb%)S4fKWI=@;{N5B>lAOk&UkQCmJw_%=Pxab?xjEhnQ@yoCeezQ7vw=Z+jd#nn zf?N^n>aO5<>|SPSi&ajhgG1k1PuzbPXj)p*%zb@T>1ee#Tk|F6%a^7ptJ#L#Zwus+ z>6~`g%cbGw?8BCr^b^KkaibHrNPPW;(jx_Qvz3kQq8MgqQ1wVSLwmjfN!h%EK6F6G zP|=T4#Lue{q6IGVt(GA3rZurJJNUkflbo!^+v0ftuubBlCP0=VwM$LKOVzwt&c2+z z&yA>a%|Zdj;39a^Bm7(7e-`ajNzo4bPvyck0%iDB`ImNNju9RfwA|obOxd#~h%159 zfKy)@wCV`6Ecis$IicEatMr*q0*;_#v8yKc;1xw;;4U1SC&tF)Og^)Ij0qNkORSK6 z*D$RORQ>fUbXKi3WO#0xKqh5EX_?fd@hGgR#eoKMlf%2aXu&I|y~Qf`w{N?|-nbHX z9MrAPabD#*?#_bSjO{E=zC)QANogSqAk1n-F^(eR7-KO-0Y5N~FiMrKim zx@<*Wm?x;d$zf$_=7#1En%60sv1JHf)bgj zsY!NU*<|hc%4+?$Zyn*ZEWuzn#{a=XZHfvk!7i8>cwTaj zrj-itPGbb;#qd|lcY35x2bP9mTn8!V$rc8gw6FOr7~Vf0WA&N*J9ZG*y{h^3>zk}0 ztG|mGJMj*2a&t5|8m*Ca=e9ICStTu$d)OAYP^t%hHnz01%wmf+&oAqr@CBIr>er&q za*aBenp&D$0i{MZrxXu5A%si9N)-#E&Nn-3F1iQa@B6itlzC>nLOPsg!j!Bg`Xl823& zm@$3bQREWjLg8x^i<8n9YTc)gyoo>Ub2wb?b4jQ3cpl6&NiTR@Pt8Rxy-Swl^5DAa zySyv3!T4-^yfmjoJ=(I?a<=|$ z7dL)rj7eu$WGPk(wqV7$FCBUEi95*f4Ty;o5&A}@!;G7RtAy(tW7o`VjKwr-6TTF3 z#khV0`5%pv@@mnA=36vjVUBfEJ%hMvuVSFiM^=C&v(<@^p&LN8;f96{-$NGnhzJHq z@~e8U;uFZytR0csR=|QmXcNU3RFjI3M|^m(;EsbBBR~aY7z~{RVjB{CBlH^jW5j#E zPY~lIJD60#qgAMkGX!P}a3(n$I7~^iDoQLNpCPgRO{%7*lu1`J_6qrJ;%hJj4s6wp7hGUXmpyCGw{oeuEg(NBbM@ff4vEw|(9lzE=tCmfEv+%VgCm_b+Jg4myRL)CFr9m*&SgDy&=<0vf_Y zckAf)c$|O6r&u@a^+k8>veE5-t#RM&oEK@&zPaDQ=5*G%=v(OujKED>^4vO%F1XQe z>b>MV!&CWuFxTWh5`R$;d;*i-6}jMe40i>kt*SQLXsPSr=;(o>T;XA+XP;k}o!wF} z8e1|lF-2xh6hxmHwFGhW^}~Qeq~zzJ;SuQ(fjkB#1K(D#Oq4h)l91Zhjja_8HFeB$ zK5%Acdt2a28n5kzj!X7ZQ}>3M70d&!8o9U{IWI3E#=7yh0)hxtcNM_+YJ9z{4orMI zKNgJ6&Lb9SZ3k}dLTj1?ZC0{QPDblcC3S*DvEjs2n8i+ILb`k#E$q&k3|3^)LQufQyw1rX)Tl4yj5F;sl0E%6P;ABs@e#~Sg>HZbJGgfx z`-p;3-2xxd=!2s|u$I3IxOW&dGBg-3zdq%L-YdD0s7w^lSbl#H4&RG%NO)`og2p_8 zHQ7orIqnigu`Pr?3jB_m-R zJYNT^hQ4b0f&m%8C*t}6zDUd1_HvN;kZd_q1$57%c~}RSB`_Z}{Wz{M6|xfD21jQR zm1z`(I}P=Ovky92*6Uo_&nPjZW3@s>@)ZLXzX8Fm7n+ZX-x$m{rkW+el95XMVgf;mnl)7FLy%WLqcMqy)YAk$9WHgTJ@C>J5EQ* zg!?c7Rfl(?$*&LD4;We*-B)shp~0;YHMXfoO8|rcw8#h63rPi5F^EWrDGCl5hytE0 zHJC(51gwCM1X<$TfG}Z%sOp_Xv|{FX@))n;>r7Xm4oK=4Off8EN)l;Bdhlx&ffp~AsV zfTf8u;GL0hUw%i0*-YgC_+jbFL)#K}m?I8MpxqFG(mBKJ0@Xp)`Ol+@1QH=%@o#B? z;-a&GmGLtS$ouw7P5|+6hH*AP8h-#mPrXmi3~CEG19Rgi2K(uE>sI)E7HbAa?z-)# zb(KT;&Q)#hVf#+EYa+hKVSxu^EoQf_MDuGcn!|19>Ni>m35c`3uPltCbBwc-Gcz+O zW#$%C#p!7a99(s7U3;R|&9}X~)?aJP=k_l$12jes&wtKe&-Pc)0l!GdPL!^z<2SD{ z;#dM*P^izE2YajWW@!pf0w%Bym!sbLAgyK4HNnv;B^4Wg=KwD`ISt#t*%Vd2;kF|! zB0xx~eBvXaGJJ9rOl7~eDjro$IpUxfXS;r9sXaad4R=Z)`NtqzrdMwdL;K|dJ`LfZg(x{`UC6LKbuLxhjd?yBm1_aB}yf^zvfdOoY7I!P3H*8j!*sc}Q zqroDasFRQZ3i^gR#;gXsL_9B$WpKapCDe@};(Nlt&u|w6ghVtBY66)I<@8Zyb4JX> zX6E6NO^XITAE|J~r&I*^lM;jMgviSIMj%E_DmjYj>SA(Yv)t*{eddJ-1nN_Q(~8@jmB(3Hq@rB=H`Ox*&8= zxybdtnEv{xD;=U`;OOE}M&W9rRhA?4mD@uTqNI|Ktms52aip?4-|@40%qPV8cVKeF zX@DyUv!(@Cj^ELA^WX-=#q@MTBw+?aajN8wBk4lUzW5o}&THE(E@m6%Qlv^1%@Gcd z>RDkyr=AX(kW3J>8X9XW)XVP;6M3S%pB$N7 zmCjqmYCBR}&R`0|Vme4>svVXZohZJllSwK6+Nku=90A?=05T!ExL(GA96~^0p%-U2SX2qA3mCS46!~%%#m{rd zIB4LwK@in)1lHv22~!BW$a8b23m?!094H|lkGfAQl*F-JhVXXW$pKVs(^1w##>e?% zSnG`>>u-~0NeT*FGo0LjBe!eTIMVU)_1gtqJPk4e$PIn8 z7@2I*hI~$<|LIF{unBxGP&HB)cm~vH^q*?cA_YoZ;w_xU62Uym)32&Mx;oFrT8Ajq z7#Rj$cZ;$ek;=0Xzyl>MYv9tY`hqf{Im6EqIpdka2LtoC!b>NkyF0yn72po)Fl_Wz zNIt2oBtB26O@D-EijeG?c>GQMpi4riD6G=|W} zK?^Y@X%uxe;j)F^@0!V0%?4*?t`D=ZZ_4e6cJb5qA!>6dYoZ--NmK{LAXiN22Ks%% z3nOK|P_}SWLc2x-0;WjI;9^K3 z`;CoQ#%y^C_&YYzLXZ`1I|_d)PKk08Ibyf~39ih9zdYLH59ekgOqoDr#aBAUqyHV#wg`RK^T!{xm7;NLnG04wDNm>JDZgVQx0NbjM4(@U=va?D^ZimFeOY7 zAm+;*kOfW*UKEkiY;9;M!P8reUkpCMA&8x;(El{m<8R63bg+sml!sj+Qg6?jxT|>~yqx$$F;6VJQk|GV$%r%T0z>r%W}l*bb^*Oxh%+j9vM~#tG;WJkBRn}f zpid4~C)}-fg-VHY9WsdYZ95+#RFH)VEDJ;qi5I9WIMxPF*2~-8Jw%p96{5@xg@6FC zEH-$5)EPu@fFIv{9tusMKneTSXk;ukU}a2q!-pP%C4o|hEeZ4-Bry&`H5ijaMPHfk zoe^{5Prr5z+O__V9QLxQZ`(VUTM+?P-=S8i89CO~LD!DYjNqhkWng6ktmq-^)W?#M zq=mF}9TNpugeR%WwcYRu*zwwNY&o-Lf#wY>$2!MU@gTXsdCBZC3Q~m?*m|FS>^4mZ zE`P;ngKwXu)-6$z95hu=2Tc+yYJuITp~H-bkBaT3?As#?Op2FCEMyuS<=>mH(E)U| z77+B+j4-RD*9+9b>n_gc&^Ccn)9*VJvb%t8F)%AsZimb~b|ulQ5>bw?06!F2oVg8# zcLgX+$6m=_raaT#K=GA=fmAeo3xEG4LhI1&vQ03jD)N2{F=z_;2=45p%!CI}ngmIv>|X2FzHY1o|$*)q!9|AJ}j8JqdP7xOyw1Fw_|l zsJ}gWcs;ET2pV&H1t>p0jQ=cfi%wG~6fH#Ks2_SXNI{HzPR}qQAH7!Dr@f!`?i@>T zen(@Qr>ksW)DsrcvH{Tkl9ba}Lw+PFQSa|kc?D`gIO#+@;a>`Rp-i?OW|7%%!6Hx^Zel1RMtvNZr4)ze%{1?U{F$ZB(Fp-IEGz;Z zMAFIOo45Innf~Mtn^EJl*nBV+f7D4*nC86rlJQX!WI9{Obb30*%m{YuVGdlingI&p zQ>;lOWVY^Z`z)xiDnCism%$5b)DSGid_Y=0vk}C|Azo2qF22xEZhB(XgGLl zdIJtckxDSdYC4m^Md&Iu?S){*V5hP zR9#T|-3IgBM#0_n%pFU2TU+&|{vUjAuhf?hR9D*WIB)68mfJoK--)K5j~Ee%T2)D{e+8yZOYVe5-X+`=2HFk8<8Iqo1e8&?hqf-9L#qto_TcrU0}J{uTfHJ+VK& zu=20XziYoW@LL1FHSk*lzcuh%1OFFj!1?}vg7Y1<3HOLYC~5K`_?*d^`v2H3gyt$& z(7TexNY#1Ez;r4hp~@?{i>I=RIpyozSubeM)eklj4{2(cTE7Tq&}A6tO0LZ}zl+7= zhKReFycKGingD4wHYvW!+6C5Xg*8@|$2KGK9$jRF`nExGH4 z%hsLv;uMx@MuO@V&r50fs+}^xL(6IwOK)&4dR|U`=#_cklAdb0%}O@Wj@ugt(iBbO zuGP!z6KGOY{Nw(;*MfXELmbGdEiqadG?-QWEA(`fSDv>V(4FD#GQoSPC6ZQ!d~Zj` z+%B-_s_G};V(`Iyuopa~G3Z(tW|DH@j*9C$O}?JCkk9It!z+7WP#Wdm28J2ner-ig zQZ_yR4jL)za@rPw2deerTaE|3E5rMU`Io$VK(a;yU=?Jc6SlXFUYVmKhe#e#ru3vY zc=5>mv|HU;+$wI`()_gcDA(k&7U+0kd*tl+9jY^IgUySABLr-@qQhheb~gU2bdI0k z%CyWH6EFuD1h;*_m}X+ILhY&u1%*R-$jK{|QjOm8v}c#etJ;6WgG4)rK~g!ib4X?= zAM3=3&FBQpL(9-MqjG?3*f9+Y#tlE=fx3rl*2uN5& zWJ=1JUDdp1>_-FRH~W6xtN_)QVU}#KhfmRMBe7>ju3GZ7tX>jW&xWPf5MiP2=9Cnq zYV^BpMu2$Ml{OXfWn;)fPKOp5aCEh6mtEd~ch-h8d|dq@f*R~YU;y}*4F%!54{RID z`Z`IorRa2>{Pt6e41YDB)r$zqraMKYwe{UmYblR8&d+64D4Vo6d5YArgW%JMQa>AC zPpA+?cHI;ZAfyz0if^PdfUqHe9rlQU9Ux+6#bp=!#zCFVV32H3;8%)QLXUvKtrS26 zgm`sLwOGag25;B;3fo%Z zJ(@q|$0Gog`H2fCmXDc9xSxwGF^{&xaRp(4vslW0E({X0OuX1M^Xc-a&z(2rP4K>f z%`FZ z+*QCyzaiLmCZKDwSRSoeNNV_N$W9_RS>`iMd>Jm=WVF^6&`r!?JVZ-(HMz+Jhv}=5 z^7LaBz@FCvQgf>Fk6nvMCkgk;&(va=j;X*Jcq_wY9;U^`<6NRk!GZtr%xiocjxvnp z>@=z5_)`RZ-AN<_9;@-Ps_leZ<04|-C;GFwJEOuZDfphksw~!Kv}J-ZcSJKkwgc3V z;%f|ay5cp9e6~+Q%#0Z}^JH8+7BP$f+azJr7IzN=`#hwcFLs9VH{*e*5MjQ;rEg*( zchEld*(S0ay!M8gE`DA5rj!n7KOwo%w^^QAf{~%Ml>n{lz?}DoRisQYId6ZJ0zRrA zNxKaPZL|ne@y`_^$iaYRj@F%BQT>Bbr9Av@2mg08Y6Pf*fj1ol2n|)1dxIYA=(HpA z)ZrDN^B=vIu~|+hV~HKDn6IlE(1=ntr;bIg5GmM*`9$X@8$r}hKQH&f%yP815&PuU zXvLEq=1QT00Jdj!sX#Lp4( zv}Mf4Do=R7cfFIKi$F%QDSr5?}{N4BdS5?oeB=e%!!(K$v3TF+uRVs z+oomJPvqyj2}dCX=ZClzwCYLQdrkRja-`-Zts4nri@(;c*E$2HQx_LD?c(}FVa~Zw}drv6x=U9u{JeGGX|sPANFDs5IrcDo=3FwF8Uw`k^|fc zLSw8+y!)o><_N}JCg??!SE8@n{BmCWnO=w7Eu%oc*iXD~m-8WxQ9zx|lLMoi5!h;e zd0?1g{x|0K?Y_Of-P*6cu2}D?Ml5O9#=6alBhL-hnzs>Qwz8&aGu8<-Hr?2iory(t z1GxDd3(wfJmcTgg<0X$>WS@)sEl!7IUl{r++mTJil1>AJ8+c2b#RplQw>EjCsCy*l zvdoJ^k#s2C_opcwcsaGoY?F|0f{3GjUQH9f=fBDoUOIu$SjD$9U?)28{gjfw)6u%s zjsdK4GGugUEb2bX`JUGZAIt2@+rD?}{g*=YiAE*BaX_ByVul1WVW<}Mt4!VxKe|j_ zt8dhpo1PplX!ryhd!5LL=V5XgVS5yAY_!bKx%66a5ZkU7kMG<{mA({J+^(=Z&#L*H zj!~KWw)Y$5{zhmk+W7P>j0)>u&Lm_MJX-w)W`Pcg@U}OWMiBIkY5$NELLmOKBvC7@ zY(E^LK*E=yfRp{cN~pGAlhXH1!48}}z7q9~SKw6D7R zjye?&*OO}1OZGvx3~~BmV_>-I64SkTpqWu2@F+k40iJ8vG zV}W@}ZI5ZcO^)86THGW0ikJ1BglsDpanc?Mk-V8LM5Mg3Y> zTQj|8?&`Yl{Gw8AdX#+0^Q0~(h4{6vx%{V?Qo3gY6b954(W-Px?0G&t`Wrb~c7zRi zTY{6yF!Im-EIiSP_^epk{k>p1(ItbiG(&08^90!qrzVJ9#-DkyEwR2bOa5ovv91%{ zLLZzwMBHD3-y@h-QXYkhOo6346b=`!XSWdG{~xQeF@w8YCm-0#^%>E5)fU#ibF4lA zvQ6LwVSsE>m%|Cb*QTm}r|s00G=BGMHkss1y_bN?qsZ6^-Ir-d1RGVD$NyZKzT31xe6w;<>cZ)%LaBuIjD^QUU4sIJ^Q~e{Q{2yhL z2}Q=-i90Stzb&pH=)(&d)9jMu+A!MTg{XmA)py?oVj~27EngG<<?qP8n zA(iF(w$#6OrtRfoPK4-Y9@JZqvtV zbfm;f(8D*e?(NykoO3*ihwv4AI-Y14?vAGo5Z?d=mKNX9Y+07>4aL)kbDOQs#HMJ@ z!dqv;s20oW<^mF4LUDR)gjw#YZZCT5j&tv}pDjgs^>Pa!TXVI3XwrTVWGeIcljDt3Gh70?? ze)5$|oLp8zK<0iVb~73N?3Chd(P7#FuxvX2F6j9ZiY)Gec0N*S0+PRPS+W+X`J`hL zPrf`LD(rN^8J>I+_-(LN(o4-w!<_4`W+2}YQ%wj7hgUW@n3~_VV;)DIdc*@WSN5J5 z>WIf=m?Qq5Ff*6jCI<0iM(GOt86pz|*zce?T-e+jlU1OjPIjBEx;Zr>@BC7o$2oge zHcsop371N-7hTb(qR-|$NtP7ud*C)MNRF=xFHq5kmE}Sx|L%yF4syukEEs|7jMmSV zGtUtWb~&3`=1Q2tN9cpLlr_D!;S{oBgDtz9u@XF_fjv9?jlrI!6>lm_s3;*k5>4Jc zB|)^@S{#UTZvX7jAoD+^#xJ^Cb7}se#s+VHfvkvr)~pJ%EhLdXq_Cn1FQJg9@A7r% z9Z@vR^lZV%?s6IT)9@A4)ZBh`NPR0We5xAUfQ^>Do>$=Z4v1NX)fY;tM%hDV7-lq) zzxVv*(B&BAs`I#;MSetQ6-3FB?GfA-o>4v_;`Sw3&bI!DTxl*ZxYuPG?ibQSv5ArR zz;Qj$PjJ6k$;N__oHDk51edWH{F6c!{4Ho>|It$>A^n~oMY%g}6OG|I2PxPv*VlT? zb(~`^K9ai?sN5B&og9{A>PkYxKo8=61 zqYCIb=mrNMrD_y+d0%Uxj zkC}o)z(D|>i$qV%Q@TT(S)t`IBl8tO6ltoilE|l`fuK8R-Vh=ex`Hik!&cLyIPe9R zDD;=pH^Ego!OqKngF|Tt>)&%;)|-Vqfhyxnq%pzsQ1awzRAKm!Vi5 zDoM}&fe+;CoppWvlFLf;bj2>Y^X8|W)5Po7gE7MGny+v1D%jW`w4vKSw_f6MG|TwY z1GmcCH1o09eXCb5M_#?Ob=q^91oip(mjda0FgOjWeKsERa@Ucrb^dy}jmi1V7*lMq zNKEcs0X(5kl`5(W`I3NU$rt$c`-rn*&CnQCYeeq&gU~@tvNezRMjqh$ zc6))$sHb$kXYQ)FM3k$Y+8`aZpQ6E5P-(X+^1B(1!Y4usLOimCw5XDz3tfg6;Z11nOY#^`Z>Nnb>+1iHn=h z0!s@h(A_hzjjA%D#`f!So4maR(MIFII&cJjz0?FRDB8X1bXP}QjsOXu@|B#d#Q!#t zFXBZ6r;=p*`{}Us!jfIM^{zo>pX(JA-~P5$=dASAV~Z2QQBJ?n*Vp-x?%-GMBb_{7 zhG&#ANjDOSFPZ*clX!q~4h!5wt39{idD+!!Sm(%Vpst!z6lLFIo4I6A21+Jf9cdXT=Wyis0bSXEpY%%aU zRDCtE{_GglNithW6c;ejryDPzQ3By<9tIZRk>d4?09Lj=Y#8ppY7wFya_71qK*+|V zjUV(OBdEjLEn0#5ZHkk4dNU5(T%QslqJqhAwUgRj#Fe70$ih1$BDYOE&%ph&HoVD! zJn-xe>oS-}4^;eqnj3s}E81EQU@WO%6JDjXP)MLH5Sk}Ho*zqPvOsWLj&HCTd7~l2 zPNm#YLk%7JXtmN9!Vo|f@%bX3Rg=Nxru}()`ck8agn?ge&E7~L!8YH1qi9FgJb9Ab zmP$Evu@8Z;;IlGa3`;c2at8Z~Ea?GPWi+}$%z@zf^(oF9{8)>Lpao0=VFKeP;O|c} zbldMQq*FzTkw9-n_dl~!*vGzb4!CY@*||pj{BNE|=0s|wr|x3sm+jYX&vWSq>TbAJ z04zJLrmq*rM)|0pq(VweSPWP@ zMPdrLuzeLu4F}0ONBGi~A3N87%g04;BB|*fjz#yK(7C}>;P(aW6!R1OCqo~4Ttk#w zO+svzPz%xJUX1wFnr27hT2xLHi|2?+SFy5DPp96L>F}{U zxS)Gd@<2NKRf!t~v38iTfY6(RX0Hqhg5Xf`izwtN#BRO>ezoCdwh5ye?>=$_4NXnxsbjWVj`W-N)x-d9(*os%*%S-eKs%n0-8AqomABRnGR?w2177Di%@O zM56^!n`8>b0W>)_S3+utNY6!`RXO(LNyddH?>kI3zI{^u;i4e8t9q}7HCYUw&Y{?L zwZddk)n^N9h=*+Ua{%~#r6R!>P1X!U5Y`MQ5lU#_j}CLXw3hl4`SzI=5}o%6;b@d+ z*wi#6&ls_ulsJYa-K9@uP%)>&qDUs{%hB0SZ^kS^=_h#k^X1ssk#5Q+v@rZE1d#Q0 zpe6=T+SoIO@t*}|2ppycI9Uyn4Ef%}ARl>Vg;Kf`~^vpHZiH6%G)Ua3np7P}TH)m_W3= zD;+_20=EGj4@}k%I50jeiyO(jrN2Cj?Pt`I9$M9x=zYfyZ5`wkmNP7`RjE$i;(h;^Cn+JYYH#-Lu4|^@^zoUVF{-)t{+d?ls$)R zWKRTxKqq4*LFA?0LWLcE!>1B{cQ?1+%#1n#>z z&cnC(HlEJO`j!lC@h{XwZ+?;_zJio&W5T8j+TY$P?od&y|CD=6*>&)N3Xrmkuw*v7UAc4$j$}9TLpTD{Mc^`|dxC>? z0bL5+^=P6pk{;xtHt|7GcHb1a2KnZfnHV+ydavB)Lagh^ipZT;1DDCb=@0|c%W)P# zUOJpm5+{1J0<5pR6Mug>+2g;pA8|&a8`O3VLnQn<_Do1g3URF5-=`>M3rManUz91` zatrrhHRHzZy%Yg?@H*sqHHWR3**Zha$n% zA;38J_ZmGNcZeisz5WSTer0X2yL5CPC4A7$PoQ^Tp&m%~llC(265(r0?It2=i!}@RxdSP&3my%mRm8t#WAtXI$F9@d#jiR#k#r@9;M-B4-Dzzc&UTZo18b3Nl z;FQX2=SA0nW-NY`s_(mkL}+(#nlrx>p`MlLnrXY~G)=77Q96J3jYjR&6ewrruF`6K zQZ9jjeuj_ny5Bq6HxGmB5-i^9x2d5hf7_CDzXNI@(KdT4K)$d~?qlf1k8B6dh+UZ1 zI`GMZB46us4Bwv07o6LXUDrA<+tKFI7b_c>#qjo=&I4sEu{i5gdMa_!byM{DV-)c% z<;8HCj#H{-v%&eEVI5p;l&p1oYopAzijcom2}11;N3UhUGOw2etH$1WK2l1fF_Ot+ z0)|?_YsyBJzCukg-EkM|ACtB$d`JYcBG6@EZU~}%k!RR<+j6N(U|vuvr#X%48}qfz z?Q%5=7wQ{=YKug^hc-i=rZ8U3aWN2;f^Z50Vv^T&))$3Mrm+SJ*V@oK4dw>}?EV~P zEuawTahN4y04b=KzSoJ#GXO+shDkX_@M`~iK$CyJS@I+adLCtD#iyK9P?NlAY~(Tu zYK!T(Z}&=u*$@IA>9(Dl|5x>Oboz?Sru#B#L%d7(u3HxMDD05Im8Z0J6jV42JP{0a z@N9;4L|g9jClk2U3@1TfLW!mKYmoGOBCmNG0d>WbqH%GDXTzj@S1D5tZ6@{5hJ)8S z(fL(s(|aL7&{{_+i=Gzj^#$oj46VKN-<->v0BdhDuy|=95d#iyMd;bx=tP~b5P3JQ ztyJa{v9-rl1ug7ZBSNs2`zbZaDOazLg}?5rvR?xyozPN?)E_V_P0Vg1GWV7b^y$tY zN1D-KtU{T`oKi&iwZn$zyEWTvBpN>vJN@eCvnB)s2JjIB?euD5Li%_C($Kh7+t{gL zZE~we_}_?F2EmfJr*sdm(E`AK??!uBrjnU~a==|2Q|`%przF0npCD0sV(Ss{pUr}~ zBjtv5>F?g3#>zN}xOlyK{7rjM$9VcqX)rf=z1(zx=aV^wEcHa|FPs&UtQHf9zz)5!vPgIr{bnQ;D_ey$|HR zsVz}@Q-aRsHqjv<)X}Z=Pv65w8qyR!ro7!KzjWXg>$_cR+A-zW?2BS&+;q}1A<6Bo z9$G-H?`cY@Fc<=03dhqicGT?0eMK4n5mQV&>R46!_}8uumU0bzX7GW?3REcS)^tk| zRFCQ`Rd%m`TWwcPyRVJYwTWEdf_?Eu=_$m)YSHM)CS&9N>#1%HS}y14K!{r{sjv<} z8XCC#4Ai&;Zp^BBz6ETD{uS%^*);_4?kwc~FGEDLq(rVRj}@AE)O6>LlQ$#9e{bbt zYzJ-$ODhG#D|4}IflsM?brRnrR~9p^i&e>DW1B5Xr@Au)du=@9n_1}W3O!poIaf(_ zsur+gboK;uNU&$>u+~{sv&>!{a(GGGgznNw2?x1?_n#6|M!vuu3j44 z1qh_azyV$O;{{zDJe-p$?r}OmsSA}XpB8jNYAZNZj+P=Sv`b+8+qjb12=6M6m@_byF%TC=K!&T?g_-mL$HlPVUu@GZ8A4#b#afg zuwW-U^4U2xeo6zacijKBp5JR?ZyJ5`7n>YdD3VY)2>zSJr97KQxN-vgTY1xL80~J9 z5TNZ`d7AaP&lIgcSC4ngKn+bQIu@IZ9NTpgZd-ZyINI)M@rh6rkSo_?U{c024k*qnk=${R{&uCfQoDvHPNXnB zYt7#i{sLp78Up=Y6RdbF0>$FOHMhzFL8a~CxuFDlo&@i8Vv}k%m30MEi++64m{wG*aPBP-yt-Fy~h503#jnFGlu*m>#H&=?*1C9jsRWy)o{uAJgt zILTrwvKIai^%mf4bMmw7>U%Kh0bH_$o}03HkdQ3x_2#S0ZuDYfq82BJLugEy8|G^y z|I^}~p@QAduouc7bnA5X9x9lvXhaO6El>XNfeWLc+_-xo1l!h(3Py9bE3-rscQcxN z;%y=4qNX*i)Q3WIJ1+<0EOZm_2!gQ0M1|oQ17lIsrhTn%$Or?YaV|QIN|%k(l;g6n z@xj|uw-zt!lwBB4DQ^kQhqRPS)w2UD!|t;1BdD8SDg%QEb5kUl16`p@uO{2{lVq8v z1oeE)3<_!tZu3D2YJquB3yGO1e!uDbHs!vrkj$~m+G>3Y_|@|HRh*(i96u_??sAKT z;k##>@tZD=&e|!Yb({{%$MpxN@4b1spWdiCYG5(Ej-W!svS9oS^84bs>Idy}zGea} zcEIg6z>34^a%LmC|d|R7&T}29mDc5a{;~4DLoxmjEDD zSaFIfWQ9r7AYM0{D8N{FK)8FWKk%z>WH7ND)qy9{7<3c@R{8Q5!A2Tm|9g6{BGW^H zGwTUTDSABk9&FC_xHS*5;BtlC|C`q%E`NOIm8KP@Du)!2c<*2r9H~CYI2BUWxvP!< z)Lx|L61par2dUrTf169NJpI-Uc%50Ral{loGE>QZEM`u56|c=Kbnu2O=0K3m-y$_2 zF}C=L8Is0UaOl2thcVZGL5Jkual#N;J^-cXK~d>|DS#nZh-%LONWTztECF6sDfYDd z8dQNg$X0YArD<P|Rx zhe1KRv*PiY<0jijumBCAJ8-L>$Y~s4lT2{?oSa(@Ov+djQc74a6{2^IF*h7sGl2K< zZ{Klum=y#mss6r)){NqTy(ByE1+_!I(2)G||8UnI&{uALq&1fCEq-)`i!xLyn%r^pkzXJ3kqD!>z=k z`7jNRgByExGlMeh>JPdux}=^9wfvhXi|M3$?kqg-_I^IWGi*Iykq!L7ZCv&V{K?ht zePwPrTzH8-A8<%F`uQq7GLovjHf$4R7OR zEgJiS{R`7E{SQp3vK-l2Q(4l#aP_E@dKmMmlI~(bJ4CFGTw6MN|oXD?N{2F`oj~4_DSMQ zU)&4zTg&x_euiAXJ{IxZwk0=CODc6T#?WN-bGT2FO_-Otv#hH%pr?6S=*0ZT0q{L} zI-_s0CrAgz3TS>N!ym_w%*2AyPNAxV-Xz=-YD7;i9!f6Z6E*mh1kwBWceguP34z{C z9?m(udaN{FovBBy2 z1b6+~T^ur^k;d9)fGSUfQl+}OBQXzsPm6zoDDsTaSqm(h?f+2gs;voJ*dOW46X&iB z_}t@)kvz4eN1^@%A*%fB_1FBGUzMefdCSZA-*faZEy$>u{xF#lmS)BJ&PfddBE;Cs zV%1I+uSv3gp@m#7m$vG}=b>gbRreK-n@>;)|E(KaDS)Ej{%f>b zD%-Hg4G>~sxj*RH!9=`5wN`7yX z7%{}G#VX-@&6F>R=u@Km@O6a|>edS}5^+623Q`2Qo*lp5ngY5?z>~2q6-~B&@ z?D3}krx~$buYEox6fzggxowQ&z3;w&S)*3Ajkk~p4f$-ziTip5`hXEZRMZQt34|0o zDZ48065GegENK_lnX(~q#pbj*O*_FvpP>LF2QJ$-VC@4db5eNl^B?N#=?XDO(h^ST zryYV~MN<9LwYLGNsOV#gr!+qevO|Yx?;J@q01PBrkLEePWppXiUaf>cwO8D}hVA~( z`=a1@?~rXdk=1s*#HI?6ugkBJF`ZLxwErdH!ot$#-sV3lJKS-X)H0Xx17k_3N1IB9 z*P>~T>@BF@^qA6Laeh#wp3Hf;m~~0IT#@y7FyJJgMMF2k?h2k36JF4j;!KbDpd`YE zpNi>@Nfm7^*4k*)hdzUJxGT(SvB29f%n?ryya=iF)1yfrOOLMl+kDlWtHVIWGP3D7M!uRFIr5J>sO=LGTG4iYxjZ8 zHT>jf_$!1M2x;;kRfR?Ob?(|ui-HPUO2R=Flh?5W5ozk;KdFofh@QyP3Be8~y%*45DRI1(#YmPMsBvbjGz~v8P zFySTEHN?jI-H6uNd>-HYn}AoT^jC`E+57&PJ#L3!O*UYFiP2vAo4H*gcBeKWY)qZz z(a4H)^_1%rEAGoMw+ZcT^ZRKRQOt<*GOzBmV=ljPr}+(`saonmM2iLh^2%(G+$XLx z*TBa`WRGtAS;vUYfc1hrp9r!rx^G50O?*7w6pcT%htl6QdpXiQT&Z!`T8_qL6jY$jwsCf-y>wUhIe)XZqBw?U=;Kjv4f6&z zj!7L={?iO7kaWi_QrjupmKFxTudB^=?x(#WyO3byznkOjgu+iG5|ZOvSX(TBHOfh*8}}Z==8o zDb7OW%_b0J^E6!3;h1JD52e15mWkma-}dP#G^P}%)VSrhE0YPY)#vlV!w{jOd|~dO z#9&_uK+`SAUU+>rgVLP-K_F|@1y7CL46up+{}sQgM-gH8$EW+)R*kYIi-x(=B4&SM z#{>e^dq`KkiZciBiQ1_(j|kbg%_Af>6;Um*S56?cK=8-qTV85v3jh@Q{7D6D+arvz zETFFMIhlH(sHnz}qBSj5P>wbzdY2#b&w1FbWTH~}KCc2rv%Ax5fRv^uV6OZ;=I}F> z%o@Oh&+k*smnrVCW2aiLBH+JVFgxOy>iTD+F?fBnQFD!P_-`qNZBcR`2ZuI74hC|Q z#rS}el&6kFNdene9P=zMS#p4I$I+zT(f=`G%R)48zd-Mqw@w#6ryHOnL@=pGIW{Io zk$Gh~S*8EhtXr~`ngp=f23z5orY=1e8SyAQ`#_S1XA8SW2ssGSg2QL6u*qcM&%nf9 z+x}vvOl_}dw#+UY68Yo0*sDRJT-WpKl4Ky!UUCw)_9Ujyhht4|kHsPD{;->3s{GJ* z{adXg1i}*$$B60=&_ENWkUR_^Y>ezymeh!0SGPpwBhi*bGTD~sshvF+0@)A7)B}6X zy}IqPfX<$Q>i8?!&nl8^dn*#o974qA+241HnsP>nX;vH(7+DQ~!jWK|=OFx*l(*jY z^tePH2JwcijxE}EFnLAgGpW!XdXQ!w6^gGTb0JW5VzyP#R}{z~K39V>&LtL*MZ#J= zMb@QIJ|T1nesiFaz3+TDy(5u%ys<*Im@;f>=E0R(3_{=en1NUCX*%bjqR~GTEFZj# ztv|8{nOwa4ivyjsnajx%I6qNYpY&$S@kYjUDC_^I{M`IEf9Jvs@pe7o90Ejq%a=*k5gWfLUhkCm>Kl|Mc8 zKBy^<)i1h^!j?1g{3$ktP8)n>0`%yCle}kELhK~EgM!m56XGUp-;3|sC`)WS#0W75 z_N7j9gu#R=Q z(afRxPQNF5j|i=IY2XYOPUnKEKTa;lb|5}IZ09F5OTfF66g|!p{!_}ux{0zQg%$6a zZXU3Kbm@~@TvJQ>)wMU_LDnSlQ+j1G{R`BFLC2r{$-{)?TVQPZuxSdEK3j!KRp+~Y zNz5$R$Ao{eLa#~c$z=6=(x(sw-nPuA{OZcwsjP7~^!cHw>;~KKY^|QP2@OX#ElR-} zrApCSn&3XUio31)95Lv3Uc4F`|51LHw+^vaMF;Rye3D1_t&7hxDCDMD_o4gSY-}TX zrfZ8BKeZs`09;LNt93EgnPlU8*?1@Sk9GAfcUjIkt1e9B5IWTXLEjHQIqZfKH-B|Yl|$@I8(gMM-( zyu0kQP#~C&b`x9)zt=X;=`JHD2AxPQZ2DIy);z1Fn3^}&G}3P&DfIaqNnEa~#Je$f zCZ9)NkUg&NW6D%K3~g@{Tys66eVw68c{mZ#g8~4yuxTa?;Zb~xcmTZ(DJY4lfRK4@-8VX(J8?{p1*q>YrcQMJAx&y_oI_6 zO5y{|u&)x;)A^cM0i@^;X2BTw(Y7xm;^kwM;x{XNO=u;Jd-w$-iNTAcc3_GWnCh-{ zC1F@ZHXw=*wR5xLe%6vbGo%(mM0h5+fr9OE{!$kVCO>!MJ5g^HLaq4l_i=$BDob9r zWHW#52CLFB$jKcDuEx26hPlPS?)l{f&c#oFPkk3RLw92AqxQEZQB1;5OG?}3cMb)? z2R94Ssk!FF4a?w7(7FnL(s~#5YT`c`cfc-LlAfL=szOOvD|;iV1Cc1V%&0WY z=5L|aIOh@Qo`qMaUNpKb^3;~5iPNZb;<#{Rcev}Z1k)LER%n?*Vf#@Z-Xi{Ioz)F~ z#iF9351~j-UB>`M`xzO=L^%If00u?4EP8L7kE+g%Pvp(c$$+QjVeYvdoIRQIyp$gA z@&g8b0#IACh`Ei2-opr=5A8^p-L#D-Of|M3^drg-SToUH4h_U=3X|__)9SAueOy~M zN^NO7pp0aXxQehTX?Yxhp6M@RQn5|JP|`^!Gf<|>U6=XrVO`ei28CSpmY6q<;O~|w zHA-+wB`n-;s{C+QTm1QZEVr6s&^Ms!@gP)f@SMQ4!Sq~A?;`Px_^gkgRWw_o8B7&x*dEG5HDUm?+5nt?wFX4kh(myPLSuak(`poRi*Rxk>TX3G4Q&&s*8=6i322 z%lfv^+mAXe2Jf7%r29dG9`^-6uq!T~MpCIB!GzntzYnm@J)Qop>#iXKv<1!Ch5dDE zB8(Bm3k69p;vWC=!z;|E3|xJ5UKuc~493{jiC%f}E>9t~Eu}AHHBD)YB*+hJIepI5 zDQO=(x9p8i5aiB>zjvcgi=E*9v8$T%SJBOrOY{OJ_=dCE;87`%K@m&;n)!Vb>#Y0n zI!m#8lT5T|AmlK!1KwNf{n-L9$)?rJ^7A{i4eh4|rda6*wH)qa&-Z>BKn7)qL=i(D z#wK1XkP!dY8jf%+*Cjr|TN0Xc6GadyqF$CzuZUBH!NUDv-(8yc?j*F33VhW= zakFi)iMY(53*Ha?E%7C#tkU9gUhtr1o4=hYlzoR>yTzdfy$*u!0B(?dA;hl=@qN7L z+sfooJc$vbDz-rK|G~?^8MU(2{*3hJ2fpBy(iB-?a9!|;5Ms#^dqq%Y7mW|Iid^V* ziy30KuP4;4;IU}k><}eSSQ=@4=`UyN(;J7BVIQT_Q&2`IpR#2vg7f?f(0T%-vO8tl z2#zJf-n&A=H*N-f`q?=s>APTiE-!BjyBc=)X++1I3X z&_nMqw{<{Fm*CwZGlNZFt~HU7Mx8L?6RlX;?+h(*UMZmrq!1fn9wY&tHl5HnNM*!B zx0`i~K3K<9Nd^Nzbe)FfLszL)4+FQ8$0m}nDscAV1+{!s_B3zlg54UR_kJ~-S{*|iUL+Is_qcfK4+mZb`*=h7Kw~z;EBz$zWee3b6@-;p0^5_t{Sc4U?<6hw z`jFqmgor9^q7JSf1sxC8N1ZU9Q*M9N=vcNMR9IM88augP5P83yhbT=c9olgyE!R4` zUlyyY1RZOX{qAj}fpxJ@qZc~977_@JZMpHV6zV7LmP4*Lh2MHv58yf-ulN3;%1Ui4gA0BFewDQOf3{1qr9CMUw%tvL2 zrW$BwG)b-8V(%W(B9`E}C6=L(kjA)|8B=8wnRQ?R7QB7g(k@>Iy7n}prJwl&c^B~q zjxoizx!nesCNJuNJ8?iKj?7RUN`3{)7rK%!Cc^}O$Hn}VfU<12Bo$1M%aOf}o(_^q z&xFh?T=}war&>-WB1QVng0V`$@6Yb^>GEnBURd$iYI)C~)C1H>?C_|XRbd32PM`OM z;&pZ;5Gu8}D-79~I`k6~*1GMM8g}CiF90riJXTvF z@?^MRWKSI>_=p|CCm5n>sh17X0Pp$gu(!dR#k?PN88c02mts)rZYV9_eb@nGN)4&f zr~?n?e`KJ@HAAY%14P7xy@A$*g#%`hw*8uPV?Qv)XqDBH*zr~RNq4?+`VP@k;rfYT z)SdX3o$k75B}PK^Q})dC&5L0zM>@d3cMyFroW#ceR{tN@?=&!$evDEDm476x{)=|R zjS|5!Z_GbAbK>K6=<}F|g?B36p2Jag>1_7mpYKB?FBqG`@bixMqL*Eq3cV#3^l!MMmHg%TdnPr(`%ijxY zr*s&@r5cI0gH+iU#cZ~|!di{h_d#iA6%nLg?W_6+1%{(rsRPpb$9eNy7&wrz>VOGj zfUi)dm5V%K>l~#e&~f$RZp{`Is@?8#6!Qx!+7%o42n6?;RMlpym&NBx#tW+INxps@ zFq5#-USS){rp8*5Bnk&}@(dTA2#AR!Wv$1_xCnfmQL-%9a?vK?EZ(gCr&b3|Hk@

    Pc5LS>ItN;qliLWc|F+P7q3|zhA+$%1!Q~vK}9IqKHfA*>4YWJaz)y z3Wd=3y>0W$Wg5(oPo(Gm_Dy~hAai4G$_ec4}Ik+z+&9U{b#$} zFue_mWE2n-+5cF;h*ZfG{>&p*la6xEM8>@rhl829?S78tMDq3>b1mtdlTfg{#$1HYnaw#~4NUc~NM!aFm_yV+ zGFwgqvc*Oo zt;F89vE?U~i3$nnTki9hIV|h#G_rTLvvuLws&EYn0V;~ySS#{R?lg=7;hTS3Q}j|Q z49_Yi&zDwdw|SJbxGdmhw5E619%^}%TEBS#euim>B?M7{w{8bFL99OgN&^&J(L1b0vlJ1X&%Ac)(K;oAC;c=@m!5Go)Xt3 zqx2wguI=!<{k|G33N+yj6ELA?Lx$Or{p8(KfR=uS3hg75zx23bp)nSdQ5sH8A@Zj5 zA7!2hhCGh=et!~Yf^&=@hi5D(BD}<>SFYm?8-oT&{i~?ce$`GP$I7bivOP#L;Fo>s zrEK}W4`bLES7Z2<@V4MGAVL}F+?WvU(H5X+fayy-&Vi-i5X7_1OsYZ5M0U+J$R%pp zhq-q|*;!P!1)9jbselTGW(wGreO8$-`V&vwwfvnGiKp^u>wv4Qi5t2f&T{|h7dL>n zG_|F?P-iQ%ocm8mt8AhTQD*sJnM8*d672Eovwx-y`TK%MLuDgW?VHP(;80)eN>uu2 zccZmz+*#~zgylzp;;*6UbnYuIJF-#5ES*Uy-Fg~3R}L+h;~Mc`JzhM z$V+3PfT75JyoL$x+Y|K3NinoSZK{g)vo!%N&+T@U?}#~)vCz!2z@H zpp)(iiMR#{+Up_)145?C&tlS7D@ITDHzmyN(k8`T*t95&oz>aIFAbRJfJkK z4&pDZ^eN|Zll0TcV*^p5;%|_arKY18`r_tXD=tRD{f<6Y*YFuoPLA``5o2317dR~I zIA_x^sFmjg51wE{aYP+ubWe=H6z4G|&1eBF%F`}o4#GMsNV-gXIzM}}Rvk3}{{RyD zN}9HD(99tu{i66>U(IZ*8FrpS7~A=umtdt-S&AQ8P2xF>aCa-UG$K-lJyT<&=Q7{bK)F80IdwNz!uY8RP7na~i7HE(ozfteh_tCnEI{|JgL)+jVb zO==gvzhizPJi8*TDMok|Zd5uYg1i#Nv|MCmhcAi2W+e)PB3L#26+5j}ixKk0kQZMo zjBQF&eA{5eXw)K}LWOTVnj|q;e(ac(Q~#)t6&?hS9-BH{T;L5wUANnfV|Qp# zVcdp*tL<7b|I6T+9>EM!YowT#eG96J^7X+sJDFyxY(@O==IXWBt_D9VZb$(#Zl+P& zqYGUq>*P=iD*&skwQdRzMeP!Bukvv48gvo(YO8E`X$}n0MB~5*P~5a^&`JBq0-Z;r z`ur}e0k_pZ0iiB2DP9yRf^px6(W!?n9RAUDhAy;g{bba{i7$RXc?hjESp2!j7SMY9@IVS9k+`EkXOu==v)i z*A?-|FBEp&!N!>NX?6xn)Br<3yuU{?N=U(D5z$6ZK33X5n`iGELc&sJyMyUJ=(N%d ztObz_7O+jnp58-R1W!eETN7fo?$<|^uo-wufVTfHI)aXnKnB1=Y%JvgJKXk=F2%?Q zpvWPWU3MRWk0dPOghNvRVgt#}9)yN$p_<)9scPKdJPJa$u3CGU9_k^Q=#m)gwSuK^ zfF1n)`6kYtvxArM{r4k_A`nM!WDP8It4ONeOvglEPBw2|`vB-j zr{_q7fz`UNr#N)ZT9F@TkixCQ~0l5Hb+yH9{t{+k_*rWoOP z{Rrl=io;ul21J^+v$T=qRI?^F>6Whj_0j;sdG=JV-fH(dufzG9151ViLgE*=k;UX=!LH+1hl~~%!F1ZTO9Rmwo zfI}d)68)}{QF1vLNIPlTMjZmCa7BWg@#o8ijUJ-dZo@vAOqe=&4JhfC>LzC=-{52o zY)q6%&X*ZfzM4d$`S{d~V%eFW01)~HBR$W}bDyW-JkzVjBPf((}(;U&Hh zWb;~{lB!6n|Mt|hz_=#YfJY1&7SUWPSLrT{(wZ1oIG%Yd1WNLlo>UPwFm?D%V0p^s z)oPp%%8OtFLUVX1pi#rkNRJo3+|p#eZKVrp0wR`wrr>o8e-nLCyNAP=8i_X95nnVO zpMR{VH^dbGmc(hxh&=$iT`FhiM=^4xskJHBkBjywkO;QsyDaTt!T?-o-!eleRt8_0i=bHH7NmB#XE8{sKJABw{sds z+OI^gKTZfME0xVbfU*}2i#iJ1oE}{#^ARH<$=1PNg^pDfnBIg*1DFS$+UK4l%=wSj zATW5l$$-gJF5YWG1s_mN>I-?Dn9{NC!HbkhE34?Yugwh5)RO5iS@%sGym1bP7^{2 zoL-T4Wv74?fBqp`oJt&7vUE1m=fFkL1RSh}_y^%MJ7=+4$r*M@uLv)aid-59Vu(7R z)BxJFCF^=lC?-+~O(#(d6rW}KoqE>w$K}COyBpUwOQrK;q-_>73)O_8(CZBSVu|nN z{B{UMmYd+2{@cu|#~T9HWj~r{H#XCTM4G6BpgeaQ8^H7Pl(+d}CpL*)I1idb17lPD z2%T)9n(m94^xDO5<>U<8-A4y>ThqVC1-M0BSfTwrj>Hp27Amrhm0>$>AcUcb`7uDa z&!YAZ8S2fBl`r(m36LFHO?H=_5 z5Mt)^ysmi~d&XX^WaEZpJbkB4w)&4tD1|hLEa-WnZdWCtfH>Rj9j1;g%OtyX6Ay2C^tmvszVh%;=`8=^5qT8K78pBlSxEdjyp>N*W>_wQwRtw*wIaZ#J} z)UE8g+AF|8a1_9QFNM~A{xwXLd&;q?PyXWsYpzY(zX0NAkUzxSt#m>F}K}2nbF$XS*6j-N-6-udybB>R z9aNt2=e4BY#gFBxm#}+sdlhrhAgzdwR;$7IMm?Uk2bcTouLd{3&3pEp1l|->aEAIw znYF|no0;7FCUW7$VwAl;?9wHDzX=-k{PX>(FWTZzu-e^sslf?7?0@ znqU_PurUh26f)-55A;WCIj0M?{Ij<_rO62KlQ}N0%=c7B60ED*)fdmVWhSx~y@WuA zL+(n#x|a?I4lBHg{IS$|3nL{>(?!-Coyw#KZB~MqC4Phqt+fPqP%c_fwEf&e&!<3` zz-EanT?byWn9?cCO_qkJ<2bUu4d|FaDg5YjmuM;3Q*z`u9!}G&dDfYDyZL_ki1ai& zvDNfDg3F}!ngMQv6N4803h&JHn)o-5rBbXf=J6_Y#Guq*FZfd|O(IP8{q+N(+Hg;^ z(AI|2C0g`H^6daYQ$lXR8pOgtPebory+!hB{je`OA5HYs_tPi>TT{$gG6E>EJPVID ze`3_aYiW^BfD8u3Gn!X+a*Yho##|W>L(Abr)CNJvfLXBFbG82JK>P^tJ<@>&$YER% z+CXrIAX7sGW=5;E<{M2awqE8?vDUT@EM&|w;KAY@F;zp67gql;%2VYR(mtOk(AY8-iG|Y>q5i!y2y9%1mNg8(|Hq5Cf;?m-Vd?xWJB-fg zV8pBP7{15@4V@Z84iwZX?_3HkyVkCaM;dR@xIxJ5_JK2gT!0R_3KRGYQuH};?5l5^tT-QocUeGX`r{Y{bd-$=*( z0i=0;T`=)W@sr8bHUS5j`!ePAdwFg-vx-xy)_iXU+~*hsZG@%q(1Y5^f#iNUD*#qN zslRE;F&vx4&AdLaaGsqy=A9ELSm*?dETMeq4py6fD;=7>njMDJVwo`xfY2b_S43l- zq6YBL^7G3%1@y_u%t6TX|Kq1V2l(pemE@(I?~QsD&7Drgeejf|XDe4StnMrTc93n{ zViyfNLcW;59oR;i8r3`)$>ri42-Id{qH6EMeJM}AuHoT`Ku3YLS`oAAs;Q^vDlV-- z;TvNw@SXplUAkYqjoX*AIYmHsj^+1AtT|1|seq46wfnr@aEegTTb;(AiUSd#b^3wSiL}!4qWSrJB5T8{kXU-=C9-g{h&|L z3@Rthb-E@&FLzNg%(|+7DNYhU;}0IQkyOh3igkltpT8wSf)~if%T1?Os|&%pde3NK zo50VH4Oe{_VpbeM)g<^Ma?JU;@?(s|(VAfV3#p0&rNCfr=nz7khX9L1giYA`!)6ht zSnHD{ByD;$W>4E2S((Uj{jRU z_?Gy`MJp}jvT_8OzxQIW5*@v+WB^g=qG7vfhawSpKM8!b@32jlFW{y#^<-uNleQ|p z-F^pKFq(Vz{`ssdm`UyQD4R4sx`+s1`!ug0->E~oa?sBIRyLF@RCu(aHjcgd%DX9VL9_ZH!!VHEO|c%wmDa^H%g;({%?BG)nQ>deRzJ8_54 zx)VczoeSQxOfa;Lpy`Y#bQQ@jnC+h6n2_H}#oo4YI(y4xMC3rhoAio6F!XO{@f|DH zJmF$0XEtT)srSpQg+^3rWfCvb743E|dUL-*E@kM%o$ezpmRKW`VGHH^6FA{PwEi#p z&XaEw@zO8lGGUXXU|w&}sZmlbK*Dorte-~p(UDO$c!#lOI-Ru+J()q|uOwspB#wAi z#8wm%>#AKVwXj&Fpp;jns|MM_WKjA#V+~wGx&Cp|H(n$v38I;1TOb@=7$f4du|nn) zgHlve0~27bn}PFD2oVU<#!K;%H&Cu{(CS1wb`nn?_aq=7J;lg2gUnY^!oA3tjPG-U z(?TK)xIX<$XqVi^h;QbvYEyeyo3DQfb;}7Vf=z502UR0Lcq(N32JUf*=L3!s)sfKS_Zhk zkF-%wVuXAq;)NbxB}&|SwD58M$zZUH<^AJ1EP?$|zErZM%%vLCROv?_7e9n5O7Ip> za*ERw!*Z;hcTD+KMrZa*p9*#dK`AQyZ@S;^nSHOPC1mZ+sF+>YYR-&u{ubA%=R~6S zJd}?8%*j;Tx4A0g5cuxBjZp7dLDK9B*9>bE?ayxc>qhi#XH&Ica+JaQ1ceq(&nwqw z6w0I|lhSj+I}LQXf-P+u5gBz2RrX3FnEQ`woHl*@a*jebn>mXidQpyb)J^fsV;=B~ zJ0+kJHB^>Vw14|e>qN>qyUklYth(c;7I^y|?%ZO~B}VD@on<&_9v<{Ikp-D!qHHLd z=0hI8ny|*0pMXV5%4uSi$|I5~^G%J?dTtzOa&jN=_!}&A|Gp=_F<*(spUXsOvO$uf zk%`^f-xt6qb7kFUq|2E#8PXw$NgjQ4y`Fq^l3F~4h6?R86}k~_-FHC#lb?Dn^XDEb zB%&T>8G`cCfNOhG@}m@XAe^6CHfNij>-X^TTg!ut^iY7fy^WBN)}LlrY{uY7T>J3M z3H9LjR_5)(sO^@Dd8hWP^tQJq8&vde&Zkfl4Xp+-y@>&`d};3dPFtnNj*JknAD`{P zDI6t98&a~PfRF6Z=GyHeJ!Uu~%AUcU+83^Z3L5mvwfw7%#+2s#;?ftSGAzQBL~LP! zJXj;*-9q3F1X%jEsO_*c4NaofK3LT`v_04gRA49tw_XS z>e7g#AVv!?4C!5tVN9}_p*o|2(yQ5AUYOY~gT0at9c2CZqH={z-A!X^BN;Rc7DQA& zq1+HD_^L*|I>ATx}gU@&xsS|6ABRQ*;ZIP0{Qd^WdZ znd%>h2I@6Lr>m`B=WOi7&?Z0@yyOy0ksh0#Ej{2rj)ov9Wx=8U zcqo&gfdD9iEeWM&(MQ$#DSPjfYCs@gT87XSx9S9D#L3lwqFLGPKFW+88Ng2&kplc9=CgaM40HKsw+q0+kji$JATC2)Unq(aL z>e|}%fD5@Ie61f}LmhMGcadmH-x9YAQD4ScJqF>)1l!U(%x){As8jV$UxGbMf7u5 zr!3tAK;>Wz0NA0@aOtf#B{mwSBAxQ~h3|#SgSyD)SFHqEBr-H14^~Hgno*P5H+KQ# zQ6*1}(BzwyaaoHLiJR65wr@xokxAvV*{w*~W!r!=mW4MPyk7hYJWf z2OE{;`$ih)%0i<9eorLgux3WjJbv-toHzSI&gnBq5>lhbtO8as`!dDG*TVkp3fKS@ zFSyj^oGKI8$sw{OOPR|c7xT;9Nuv@m_yQlR^{gATVT=yD51y^}m(u6}Z4SFF)~S6( zi~}Qttl7@g$aezGPSdVgf(kAV$@f(|rF1Ky!*CT|lny}nT)%&%&iG7T??50O&I?}E zt_TqWv1$~&ZlDmWK-Wi7GTG|ve~JNTM5oj(E3or6=~VdWaiodxJoMoqA;Oy2t^@(qyQX(Hu{24;=>pV9>^_H4KMq-&SQA2>d2F; zz4SQ0nA3d`M#^+~a0JSMEJ1q%KC1i3?von9zXhkSDR8=eGvk0<7Z$mOBO82Z`~X~f z#rTHN;_P7Q6@A*l)S?|V!ULn-Myy7amFPIR{F1n`Pt#3A4%EkG)ru{x^$02!ItfLC z^5P9zpAP)a@KU<7qS^OlH-!ZoM>=y9fhExBB!}4LNP1lBc1~T#o$LL3mRfAIjV6aa}$$}Ai8pp5N z0=U3_6mx5C8q4zWV9fHFam`Mwh?JAu&;{wT6}acpVs{=0UmM0Ejj2(+-$MO#Uq25% zrWw|Icmzn%9!R9l!JjkeK1`VlRaUFvq`>S3z2A%R-KylKAw`rES_|@51hW4otjm?_ zh1t*4z7gz-W~U>naw_;l+O(2|hRU*b!*Wp3j>F{^(+Kp<>L;zcW!dqCkOT}OTcT@z zO=_+c%LrBRfE_#(r%|;xMdV`Hh!O{{G>nStM3Tv9wbP@jeYhe93+YX9NLrNa@%L5C zo9U}{!g%f#L;`NhnpXg*0ZMvH;8ljF+iUv7Gjc2qhGa&FvJHn8Q=;1>d|l0yHW-g( z0WcQV>1Sl36ar5W?Ni(U2Qu6FZms6Z17^arBd68DOG|w{(tRBuz&g2~j}x+!dl(;j zUGib4byE`e-d`iE^nQ85$3pJF(PqKytqv}N!j%h^Y#wfI_vZO1RR&3f&IMSWKy$0|k@}GN(i>ho|69N<4i-Z6o6memy-0)rL85|;? zjIEdZGJ5`d<~6{QM9>x5+*kXT4j}Bmv>LP8~t9QdtraBU{*pwSNk9B&V8tAK0--Tv*$hp@siWQ>Cc zFSTB)XKo?LC0|O$nt*Ishsz<^H*c%LGgm38if!+Q(E!`e<2ZL%oQLI6hH|ZX!UPyJ z`-W#dFD8gY2!`|%A@LJC4nS#BIp&m4N)vJqM$3A0&iu^O7MA()kx-tDdp~OPQW5E1 zPviK~-uiDD@5$O#AX&-8m|a99EeZ0lP(k$cWv+{pb+mLOK0bj1t9BGlEe=N`_!+9H}JVzh%MOE6({U zC6Yte0BZ*b{n0%m+E;AhoQ$nV)yt@Ke&USl+8a-!mRPSmW8{3H7P6(CrX&FxIER?;yIz9qCafceR;86M^Km?OC)WhRMV1r_8 z!jMJAp-o%TwzC81q3uBkr*oO)rsyd(QwYj44tcwW#C;xgs$qgk8hMult?Gt5cOnyh z=FSf0MKk+Vm#UC1aV`SfX$8Vq&FEhJmoU0CpigOyzv)T)wCZlOpZ^zH^D2w4*+{VQ zR1^)pb^|`$#UvD5#4bO98YbNNYh(2=Xdc9mhzfM;;e$36pD!sD*QH75R`JLP?wRNFE?u{p{T0!p$C)yVHrk~cN;*o(TWy8FZw9Dih3^l={Ty5g+SV)=p zq?SV=Y>H1%Fq2~%s8Y)01#+P}aY~I;hl?A%fgEKi`L_YpH24^) zisjFllI~XtNWMXJ$z;Gz3u;<^*4b-~!CW+LM5~)qFV)&2$|v5CovUp4s2MwAbc=*1 z0`9@z5?j-8p&jt=%ekI;fz10FAE23z=Pt7HFNCje9m>iBM@yFnSG5-nR|$PX94h)B;x{8{HVj?*&m7V- z05aV+se5s5Y`V+Gt4!bSh2h{_geAQeKD)-@Nd>#s54jKV({ZbG{mIpEu$c$c<28HA zEXKdY7~$YhZs@i>Q?7eo5WNZVdr_8r+&ScG$_D~6LTlF4w}DLoz@@`>gF@6lKt8|y zixonTd;QsD_J2_DlLRL6FmA0oU{ZFZSVG#?GV?TrO)JIIi`55G3AN9MIU-Mh=2Q%` zkg&_0cat~%uHWtowrVJaX4H;soLqtGL4K=KbU*i-)@Q5k=@0$pfhse)RJB_LH&H;h zT*d1W)ZnSu%=^iObMjkU-20V(cAZW%P)718*T}}kAdVTF2YN)+UVhOr1P$KT?zix z4N?U01NYtLXPGk8+?~sH-6)jwN$t~B&Nb$IYTGo-2yH)uhq4-(Mr{r_T&A}$6T>VK zZirLNr8AJ1Jdt5YIZ>=cI)(B-@-|n)$|NI)7XQMFa9%!8(1aVWOX=F04d3O-yWCPn z7@DlIhqVtE6PlWmg>Qgcv@o&Km?&`52+suY#J{6$$#4BPce}e1%?OPH(S-^^*Bb7= zAl!C-v*rS=n6&cAGIC;wcHVieS->qrn0Lm~^nF*I@zo`bYcD(O>`AKpGHs^>H6Ew! zkw_EbjCEHIZL>Z6p&91CpZ)%pJ$!^$lV=Iy?+d7FThr5r0oa3f>Hy--3L&Kdyi48# zma!3$chu*eRM+iJBp^pHeOM;bHKQ_M(p(cA>5H|ALzvg%2#qz97gn zbJ~%^u?XZVjV!XJy+Ps)8&cpgul(2eF|=>AOUf=nEsA|*{@Qh4MF1W6@GatCh)1M< zl+%RV>A&8APy*niqEej$kKgvY&3`dm?wCGf&>F%9gND@NW0)6;q1w-YWD{8sOyr}Z z!kz^by^-q>Srd0@Uxl)r?|d(Dy4xBBD~K^U>vu;n+0LAc{^*VudXU-`Rj*a6=?KAF?4`P>>It2Nc}3SJiN@w0)#_*xhfiy+iUfh6B9rhJLy2CwF=wN&fi zHk`qGC#e!Sw$xIW)LKz?0L2E&b57Kp;a2x_xY+P{7Vzlj$+=15F}7gRVMud&ry>)B zue;r5-B(I~RH6zNLg7~>ep9J-+i~chHuVsvUTRgy)6WDsM3reIevi)X$$=>6GcmW! zw0n$@>$sdbOF)iaGuy%7pbUiWBry9iV=(K2YUvX8b_UuMCZUAa4clq}4^#SKl#D17 zcfyt z7uNy$dm9&fEzojm*|Dd~z8eWqW|X_TtF`PzA28?`-)1pCAE~JN?9^OSL8Z*`>ooBf zBto{td+5-n7HB;UKzH8;%Hx7@&Q^nCE<=G=57CD0LHFJL5(4qfA%R5CT1%3Mpq%jG zcB>(OMW{A>f>7y0fvSwzq8MaNKD?}#w4YY3fIDI_lf6|c`Mselbw^TB>caA=y?x?T zJmGGo?ErPsVe^_f1wO)HYeL!(4q;~q8RX+PxSMvw*qU9!Oh9Bnwl92sIg=ofl>RGQ zc`S=tSgRK%F?=W|JLlhik3RGaG^HY{YldT&@P8@fvHD_TY9TCFaLw&nX2L&{$ev@1 z`H{gYn@L6i$Lda)O(XXTp3jGi)KzLhplvENa*jPIdYP}tR*DP2q^p8WWs+a&!Rqk? zYpw@o+Egf{CXB8gfAV=O*jxFQ*_;%__b4tMz0&QFX0;|jqTyXUVRMXznP#Q>ajwc<-Bwp2WHFH!-rIK3kSUg*uFSTp(fe(4KT zR|sJk1sswmw!!LrDPdnGY$TagHshQ98>U6)udssr6TAQ+KA81s^UoZYL&MAs-328U zt|{S!tFWPG(TShPV8``Krf7flp^2`sj|cKJ9*-iV_+#jebBABD#s5OEp0!j9wK&0; zOQsOyW;fwp>ZUkkTZebgRjB@7d~%^)d&@9R zIR=2-Q#hC(UbH`813Rdm%eZ8oiEY;=Sq&ZlH=^F}vmCB@_4t8rW=MbumN>2t*n?z> z(43A}dG?F$*l0Fqe-??vjJx~%y-5P(+M}QN2{Az_vN}qJ>@zv0@0p|+%h`ZtyV_ZQ zm_Wu)uSGM*oAY!&nMNHEY<&b(+u*|nRZpK*#W$YTex9C?O@J4vDUfw1brmoqfpWl@ z@(>queAbPZMP5GjJqw>BYfkt@9tfn)5LBw%$=ia^Urp7C;9 zHFE>l(Z5~yRgNI|e$)0(j4wyV=p;(mMqiVf6aI82z((oGvh&MWgIy1|)=pvK(`KXD z!KwzkcXMJ2X8rutidILGl}-m8z`?Se=>hXDL}zXA=;t1OAD5)f?Aa7zUREpDXp8#r zWfuu7D|X$Xv*rkV6sBM9Vv%Nhfi5LNlYn9CC>mH-3^Nt1~tQ3 zNyPEh4kUSIeoh&dKCv}u3!|U0ScF_(J&HlWH%uIHd4{l$1 zZw+x=fAj)vwNwwE_8|aBDEvE{;ahfnBNOB~!E?#qcTWe9IC|?W+a2ik7pPlva?k6? zdESy}=7}X-*E?qJJuFIcE;|aUNNBh&>%o75tqXdlyNYW~Z&-|@xzC54Y3AN=5{VVf}4fY5Uyw-fMm3PlRfF~Psp2=RYF({|x$Y-0zMN;()Vxg`#ufR{ARILB&+-vpnibjjF*3iNO9!n_OO?aUL$ta1 z>Xx4JW;s?E;#G|P!ZjI~+>cTilP@Y-5aBw;v9rfczK>ur#la%FN_7E5R5!B)R(L?^ z`hEDQB3WC_;zo!`kEo;gv3`dqm2lZ_omt-En1B9@kmK;YPfs`9{40Q@r%(YBdQF5= zXN4hB`8N_;_d;6ttSKE8bLc?xKP=+RR0jM8nTEy_6P*W8Hh8C(EpOOAvfVWa6=u~3 zMHU(z0Q?KI=(SQkijvF0JGBHwCS2yMBpyX@)bt-;``8*g<&SO7YdlS#<^b|BVh=~_ zVsER4l?u6{m?=Ncd||!C*JRX9-qKwpua&@hpVCkOlc$bG|MhVjcl#KHF}eA!-EYKA zjPui`>?cAg>p@dKw4}F$@O{5+*`){HJ(%d`|B#|J@Qps^!C!_EtY?OfCHnlWw zj@_E#bU$lw>3yxC|u;WG-GtaF2!Qc0^?glp3+Beq&kXCr&Do+8%>@}GJem+9_@Qg19+I@M+c2;n3V zBnM%ETqFPpO}UeBHW3sUn>6dhUevRMb-OfUGgqM6P%|Y zqsa%r3|Mr0gau#}rlbuiq01^C;_(7`8-@n{x4P+?Kjwa4)m{GYO}MKwq>&3mx(*9Y z>0Fx_>GShjK@jHEbZ5$HXE7VqUbcAi!qC;En&eX#!O`?A4GON1A^*LV{E0#hSfb`6 zv%2PP6Nr|>y(AYbux6Oe(5k#kg|(mMv5)6a?%AxgnoY`&IW*bXsxKG zy(J7~OyC0cKvB)VCF$e0J#68vHb>GDLaDEwLnw5_KpWq^4mOq?i^kXDk}p(<7c7P(kW5S4_#|=DBH& z&hf>5o9CJ`ZAkReNm5g(hSk5eDRIQ+1T&C>I&CxtdSn}osU}gg8Ls!@x{gL1J?S)S zMDuO{(^K`cwMLw-_^`AKYPe%jz0U+u z*A|_0uT}JeMS&38GCGD>!{k3LL;?0 z0^11$-3AtIGMcNW25Ykw8b)3k9cV3-jcp7AK($UXbDEToc5;}MMQQ1160b+o80P}Z zrZyP+-TjbIc9|ebI0)nqb8m-XZ~Ai&LIRUP`N8Kt=g%f`S{Lr(_(J{J%A=_hxtz*t zht)@#U(PN<^Zl0~f^1_s?wmpn%V66dq?#$~F;N*8nvI5kH-90anf(Y1) zFiUmHnlAg+wH*VXCcAXUiQuBQL2TtiXu@C@i#A6UqPjo!LEa8L!In(;I{!H2F5&9~ zZp1yJ47LF2urIeTsVJ47D^N|Q*OXFhfqCUV7}ig8hP_G5B9^Pd6OihPy_OqdFG0vM zzimH-?4>UXE|YBjCb16ONFE{td2As@Oeh-`lkw)TC+se#npCV$XT~@>FU2c-#`C3~ z0pB9&qz7EJz^7=wjVzYAe}6A^=_2P{UapN7eO_0X&eArkxVRLicMa*>b?X7Bnryg5 zC}~)8L~;-;Bd{{;Z%m6L0v>MF*#&{n5F-a87J&06)3Fm9O1Qx+zpgL zNH>gQh%L#>SRU2}QxQa|;8T#7h`jS?w5_z`P}zTvv1EynQxu(nn!sn?l<=c0Wf=Az z_g%4-F%!9nuAN`ljRy>uvEG_xM0fqDE43+`rSgC^8O-X~J2s##5P8$Q8&m)*+$VE9 zUlyv22)%-58grzn2ilQt?dvaDp+#JOJcis$uFLt-mJ=HRMNJSZO=CglX!t?&oCD|$ zXI~Hl75WwWfgmOC`!F^eEeRSc9RCo|4gKc?KNAHH1`-%c=}0(W5i(O)5ZnL$Hn=%8 z?HDTq3q2JJ3=miZ7zG9#3zN$3%?LaT+&|FqMjJc?NAOe@6%Q}(gcupj z)fp%^+y0gQ-4zaNe#|inRL4~6_Hw@+H|-jMj5!JSI7Z#34JtXA045j*3a%D9BM1~q zO%4w==_cz!8)8r!5E2*$WgiP3jgk66C_5T9coiw%7Yhb5s`)Pm)!Q}|X8;8`uo^8Z z7{(e374l3UyJbT(6$eHY0=)7>p6@3S6Dn6iDX9YAK@LU`2!hKEbw&*cB;CY7CP~-X z578Ox@?Vu4%`YN53!DdOXnZj7-lC0AQ}?OM+PQM@(MBx9u4~S5g`)?4=ei`6a$JSCq@q@IC%w8 zVHpHH5F8mtA0s=HN()@Ziz??8OaTJmhX&P4d;DcI4wDNVS{@TjH6IBVO`GO?Nkjzw z$3I&SDrO04;%W;Y)a6V6dptM{TrKkLDG3e$4@(0AEW=eG`RFGnNdgCmNDVag9qf4{ zOGyRmku?o9&*?C+8og*GGy@AC8Lc7k8fDBS2$)bG9wQvq0VyyXBnA%=S5b-xHUv{B zEZFlOMJGBJ3i>1{LIgrF_By%INbET~DNj2r&mnjv{NwyBQ3*3(8|Pe82vOAg6R1+> zM6p))4hA|b0~^yFZIEn1IO$P01`A0SOy$_^Oe(P{HV#l0%~BB&0TojK93l-rMhCJj z5f+y|5;P~tBw`Q^35j&ihA}+Sj6q+wRT}I24liipKzLg#>Tyl$8Tkb%J30$(SP}~T z6aK~o)=3y7J8(Yn3x`=W4&(<(fjZTGD<2Fzi!tvGDF-bHFT~qFGx-JBC>;qDSc2yn z-^DpFMJF&$u1OkSISe!%5Cbz7_1O&^@)!eQt2-DbAU*+Q=M`sSBYRLF$PgGrLNq44 z!M(k-ytTdG=kx�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

    8{JQ;6U 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 M=g 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

    FS^Py|hQG>Sakg;zr}E=)wI}=YIGk(3bSc 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≷I^X`C^0kJlhZ23z31ix6z+UiuTdkVRzemM$ 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≈$>iDw+9T47!ju` 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 z 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
      )I(MfNXCt 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%0A%5S--PHH@ z`%1N1ox-Mt#l;054e#)&THW_63vUz@aOd-(6R>TEKz#_qIA7IoF`}Pyuww@dHYq8| zaurlQ-N0hXB`lK;m69?I)bmWiI>?QUnkz_@CU873N;-nZe%43XuqKkirUA)i-w-Wr zy>o5m>5;{vfvN|?6`F-fkOP5l5L;vHO=l(^3tnws$y5GlNoxx^xf}KKm)k1^S%y@N zz_J#Pu}cW)L~w@Yw%|ksEjb3ySN#@USE*fX-j%LX`Vv$2DgL$WY+Ya7vSqLDTt{q(j_Gj0M993(w@bO)S5(m6I+?KIjxTBc_G)k>fucqscCT85&zMtOy znzyiT+L=Q|`=n3Wzf4*wxclXL`svDDR&N@^FGEs5iW=T!WJaL>K})mgDSIvN=V9|v zpF_E7rX%X64sSR^g(M!Z@%1_FOYJVc+>NNRqHJf{GD5p0KBdP?!waNzc{VlONGP08Es03+@4B z#Hnk|osZg7gcHA55mTtMEq+%NFN;DA`@uc=r&Nm+bHZq1Q9Y}N#ip0u&Cz(z%BRL>Fwh2%8HGAPt)<*Iz<75K^3(XA-FLu(KfmU z`=V>)OddBNB5j;uo!;~{1V?|IoM}0f8JSgEt5dLg1n`&^ie*LqhsJa2-GPGH+SUJleUr%_f_oPkB>a zoA`gPA>Q~&L`l`Dm-E2Ag^~|AL_shqsdC9MMwL39o(jvXI<^D#7#+3MjeWW;*8^8S z&4d;J^o%w72SAm6>p9!=aGt{VV96m-xZ7~?mhBFha;9Sp=4oqGx)A3pnO z7S0oVf^u~%)v3a)zCK>_dfQ!r>i{8A>C)_oM^FG0n!Pp*}HpGJ9|yfGQtzK zO6V~gGj992nnFcb)5;8YW{$07uJGID@OeLNuT~{bvCk{PZHG#c|L90jD>mZU8Q6p% zj-MBZqzGa`ts8wlpVv^JKM2>e!r8K7o^h5^85k`ROusf_W=9*HPX0dOiB`~24kC^7MktqiyeEs5w_Kt_vb;SL%R7`Y+slO z9TRM{RpD^GV~3<8T{cqt`eID5b`9_TX}7~dV|VZQT2UeHw6S6z?pD8cSDD70Q7+w7 zgf0|Y$r1M~Pmy6ndvGpdeoZee_ZUk$#Dyw?5T?G!*ilm_G;4ImDq$!hg;4(Ijud-f z5h4s2N|1l5ANO6I=t6UIon3Pa+kN0y2JMymTiaV28k&N))|Vm5;mFlFOADKvc(_4c2T%wB6p11n zI|$ExjecbD3eK&c3o_z=p^56{F)$OZkV=9tG%t4YN#wD#(VeX8tV5HJUll3LDj5N6 z^=+q)@6K%fKR!NNt9o>N`_35W?HlBW+oPaP!-vr*`of<=hrg7JlSxQ*{Gekc=k>CG zIi-7XuI1K+mnY9Nlt~8FVhHDF74S_U-ZgW&4)AC(H7F z;#lq7?bc%jFU(D-m(at-k*x7tFw+nG(ZtakZ~g6P-XimTyZd!J_Z@)QGxHP}Z^war z@f|4g?&$6Zn%SC2bJYm!y7Rc*KaQT@W#5zI5E>{1U!WQD7pd8CQio$=Oq<7NA9F6% zq{m>TE&pm1j2Y-}$MJdhS3}~k>Mv)?uI6H(NKg0irwb}Orr##8KdhFHmoJ0!ON$sK zm9Y@W`p7XsDG6AiXuusfO!8x=mICd&7o9AMqso7IUy`5MV23tz z3h~{D&hA@hc6*brWNBcSp(DvQu0^(;c#t%%zaU@YNkH$AFv$7Z+5*?n`R!hcDMitaXXFq< zF8^8)78{~yKFU`L5V?EpH@hrj5mA-ljkkqgHQZab?k+&3yE+6yOL4(rWOxsftxx1k zJUwxYm})|OQsz6P(7sLy(BIh>)E-bMKG*Dj3MK@#%ZPAKBh;W5qWEdj$(<`_N3n^C z+S3aBHH^j*4*nXlia#;=83B^jAHH>w{Z9L1{Q@GCaLi$(8WTfr8W9ma!-73V8tA1o zADl|$j>CfH!9N?iiy&|;pxa$@BPOssGZ z!EkRxbr2lz-$qsA!ITXCtB=nk=A*0{7twVsF-3b zi3m1QJ~(FjaaAI$P2{AaUbGoFQ8#C)2uOYCFIb)Gbm`_lqzhz0%nB~lc=PrvJzFs@ zJapQ_infzZw5gL->p2rgI8_s3#F(7tg>?E3#ibCzM&~U$S28Cl9p{eOX~fp*9Uz*L zO1MjBJ@&7!56yK)cDHD}hX%?5kabj{ZZ+2oTCbINHxEx+jgoNG2vS40CpU!}=^i&M zn=nBRVh$+0WG8SxpI_M%>GE*!9E54AFjcPN0-EJC0#L8cXY*SLga{#2+V#+t(+wde z+%&Z(6)7I;OVYNve!V)-AN;(a-h$~{-BMv9BQ`Ld3ovn4=v^kF#YqI>(F= zvj*-I0*e_CylP*76m_r&K3~QWTL585IHms-&`+&0T0&(Ur{qVNGHhbRlwHgTz{`;h ze=@Q{ppl@ZMD&ol9oX6_)1^0(fvC*aI*l^DKVSFtUYR;r#>Eq{CI8Wz)Ngc~m5fmr z6zEA$*~X2Z>S;JjP-L&Jz3<`B(eZraba!{A7`<6v&_kJ(0Y5ZL8c9?1^>l8#Ok*0M zlIeb7PX|z7j@!rE+_JrV>%I{u@`LZ5-U)+$K+@y84&z41;WWtfCsr*Y62gJXrq-_J zCNMo<_xW9DUk{QODL#C=un{pCX5BY;9X4pq7)W8Cd&mq#Gd)vNM*<0>VubeQ)vpzH zqkR0ehave|7h+R<-P#1Q9t{I8PQVU6&MZMZg?1?Kc10Ge_Ki8g)?djM`Ra_UvvvN) zGQ5#)qG0%2PJEd{O&Yip0xbE>teMFL*-FXE)PRnDROo2YpB@n#Hz!)$Jza}DKLQG^y_s$i}&a_xNhCX_Blq;w((m{W| zjPa7f5hE5%1f&!*PP{Ox?1Fp)n<@bSDgS3=zztUp?1@m#14Q$F=3*s$@0ksgDr7Rc z#!`K6P*oKuNU}%gJoP?Zx~R4A#ZrjW{xz7&AgKqLOi+)@%QOO$ychhNX|NUL$tAc> zm5+?5iR0{my`q z760}i&VYZLcek+Eyr^UQEV<;y!}yisV09=b4EFISdneB4>Yy*OInMBrh9j7GpN1so zYD^TY1Q)Yww3S<@UlnZK_mnH<#hwoyEHHkUx81&Ju_cSum*t~9S9=+k;Z0^f*-K9< zQW0Yt>0y^!0Ozkzf)T^wml4i!ahV`|87p;P6k;$s1s+Rg1e#xX4cuZ2D(5Fu5 z`=$4;x;6xIDbS_635sJ<3RYseJjyv96Aq#<29aqd8jXl)8sB{+Y~~o`F$&l0JiMNE z!^i@w3RLtY(e$`V(kU0Ph65M|O|yhP??8{CdUA^Bc~>0#*cw#9<2& zJ>oyCQ9m{MrTg3K%k}MGqvekDx1btySEy7Mh<32Md}8$Ch-l2<^vdK2IbS|(gvJDm z#g)Q78b{4aX#?_Fgb=0I@7J%f=j(jD+N*Cck`a5U0}+yOH|7m|9mhT#<1~aWR0k^; zcJ1jd)R|*DYA|prL*Ls1eURtuK+oA!+PgUe-)~+nZWd>6LuZ!f7h@Uj3D$gHueHc@ zcauw&*ehMCb82HJ&(4oj$sxJ~ic#A=om|(GCBhNs>*+a%^NBu-trRBQ!66VG3 zvD+)|dcA}){`dphV}!mGMsV07hntBTh{)8$q)F*_$C{O>RwjCT z%#}C8(e#x4xX?Y@g0F>Qp$6k$DG6{0b$)C;&_BEA6=Tuen`nIAl3i+eK$y{=M*AW(*f1G ziuj()V)aR4j5u=vwbQT%XE@AUC8D?w2>sg%C@;eNIJvnzHa~H_e5uFRj+?8q2F|l7 zLW!PwBUJ9@#F&kbUlOi3o}_PQ#LZrjK*wBcm7-9(ywgLFmr$QFDVJi4k!zV8;pnB+ zeK@)qV!bfRl*0YO1+0{Vmz|;ul(hXIQ zxwjNE0eSAH3X$%KcLq*i!^`$aXIz73=U}hdo}}u8MY}qyMwHeADb3`Qg|{I^Sie-7 z6eao{I(TFas@R4xYcL3{8g}*2#Qx|l%uRtu^{NGl=})JtW)-R)fehU7{X~aOrCQ~n zJa(Cx2n`Ds@rKOAO5^q!2kgfJ^U69!X4+kfgaCqi^`7>2IJilO;mGJ@=)k#n8UQsk zAw-jfBhNvTN481v%&=N1!n*Bb=xgHR^5bsRexs)~-T%im}fz8rT?Oa@DJjI$Yj!-SZR46*1Af+KfB( z#+fdTzjD0ZZZ<)F%nrn>{-h^W*-1p6N`-9$r;8@KVBW+Wr-qI4Ah56Qq{FyDoF?1Q z>_H~fC>yN^NdcZbY0Xz)qRZEjDr!@a7pAEP+A?4yN_Of96e*!M+&Zb!F-O|~4{uD9 z$8hTzKWX&P5VC|V0`xAv7g|`jn^e*&>P_=X0GG6rGMiYCuKUaaA`tEq3f+7;bZZQY z&@*pMim?lOZ4tHlKred2FG+r3lp3*+uG4*~m7#q(pxw@qFxudwyU9u(Q5-qG5`jR*i^HA2+C&LhDjAdSSK?=wjFpcG zj_NP3SUXoaQ7v7@S;RB#qAZy&F=RG5VO=B_pdWyFq37YkpO52lNF^cMoHdiMaR-jl{j z8?6pa$D2l@BBf%kXhRNE|DpCR!SK3V=qH8aHE8Jz z?UXN8g=B=~l!OpyBIXd`;O6BfV0RV>8ow80%L{*X=p714Db~AF(p}|2+J3{+gvgL; zxK%8ML?DCd6+uE9vJaVE35_ICwxcWEL($HX(P$3VCK86)CRKD8U`dcFre0fXJy(w) z+(D=K4v!p%_@Js^g&8PdsyPPoj*hr#$_fT4W(@C+4w?s5XEc0+N-KD5^VhVr>9oEOwVMe6lvJEyC z(`7rVk_Eywydt9N8fEnZjM5l$2++gnVT??;P;Rqk1UFExdv6Dsk(o17ZkX}71z=`Yw9uHL87V-V%Ciz<4#7PV^SNfF4o zc}#L@gG&*40>Xq|EQO4SLJoF*tilacu%9p3QkeAI6q|l{i{-{VCu&sE#@m;b;xlB6 z<<-xR;vTH7cfUJ3cJkoP$rK?K44WlRcVV(&`+_T~z^gG}Zz7_TsKoo1 z2G3LMW$+r=6X@EAz3LR&9A^lKwfH4=@-c(98z(PwY{RM1z|l5_ebEO5bHno+=*1BOOP0igHQrJ}-42HAq7 zN^U8;win>?PQnTDnK_^gE7}Wv0H!3$<))UIMPdd#E($CyCeIxUjHmz_@| zhqqTp8!tZ;W6sB@o|n7(?k@fuI`P1T8$DoJ0chQiin#Q=NWz&C;vfk6>^!qZXUHJg z__#=@TseDW8Cl*)j;yQ#)uGQC@)OIV?civ4yQ_Vn^78jnQ|D`)o<3adhjZ}ic#~dp z)}Q4)RyXsBnL{*$^JvMWC5$PMXd&q?ZA6(?0tF8g!{R80Gj&>Y*z?4Tf68R2?kFcj ziX)FeN8eaNrbMcsk&!w*h=jqmgE9%R{XvL+%HEZZ5h#2lc_j(^3xlKdUWa{q51})A8>^8f+ML^%GaF5YRM@Gs?uQ# z!>`uJ4)nD*Jg=-1$YlVWJlcW)f?dmJu6{o9404c#l8fmvpW8Gfn^bh=NaC`prs(+* zP$8J80`zjHekM0(97}lowoQ@E%rJAAM3x=1ski!FVK3g)HP_(8VmI3}g{IOz{S7@b za=UkRcmEzs*O6zO$SchNNX_IX5!|a#OvM^p-djy7&KHp9L>WOXMoN!4xKw~w`fT_1 z==2>|KFfq|y<$&vj!axc@IgIci;2lyVGIL%;>`@`=HdS4@ObC&Q&=-!$F}ctkTb+O z8AU*=>9xngf^(wuLubw6nHh4vWv(v*R{u8wD`tGPnG-sSYkj)fAmScH8xfhpE;B@X zX@2Es%y(aBj2O^- zqkZKg_}37MJK#p52Xh2Jvg@`tpkrA_aT9$CTP%wRa; zYtd}U7p{&<3s6xZbWvj4Vl=k`5m>r%O|f}@MFVWHNj<{e(piB95yTn>kqpF%{lGnKBc4CZ~nVFfHA!cS~W{e#(Gc&VgCfSaenMpA-vrL_w^PcJ3Gq>+_ z&&;P;uRf?$TUGT`{nxXlB~|_QhNLb&oz|&(yftS$BM7Cnj9)sBrYbRReRY4SRp;}2 zc)s)HDOZa=zMla-?oD4boF-zYh;JLrvehq@!G3~;vP{pGC!U42Vogpa@Sh(uwPWDI zBp?gONnr?2OAOVb^`|r!+i)#+SshBc;ygG+2~t5K-JI{~_ot83&u#nVaY%qr!r!*N zetU94C|zmPf*ujYr1%y@nx9^d&ieE1>1fE{J&6DH?&aQ2KE^G}GG2u+A=!~En9P)< ziRC*!!}nKt#)i~sWftA_!{pKV`jE%|=Ids?E*_v47<_R%IA7zp!Kk9nF zLd!s$3$Jj1i)%_<5WFyVb8G^1;?CO3t%GO{$ciTF6eympOAi}x^fb^u-zDJ_t<%j$ zlGOO}DX7ws$pYnQ_^9FP?Y&#mSlOS0_+S38ukSv7_z=qc_gVZuG~OQ)@6TEM&;R`_ z{{KU2^UvV#eklql*rkfdONc0bfXn^x{tu%2fAFaP(0~7wA7TGo{tq7TH=&B~4g&g* z<-^Ah@Bdid-ah?71pa#W?G1+G&+EV5_^Zd4-_`f;oXlNJO|4D-1LOL)-Ppv`+Q8Z5 zPnW+Qe^UtjRe#vuckh6IJ->U0it|^5f{$PRFGS-%WFxHSpQisAz^wU~{qKPk4U8>Z z{(_gC%}odlO`MzwOf8%Vj4T|DtWAES%#MyGPWE=T#um0_1kQE@e;OJ63swFNJlp&R zr)^wp{%Y=GLu=q_;%H!I@;3(!%kt;y{}l!OA8F>lDd@jv155Zvx&MrR{-eo1y4b+} zj?(b)clG}p^!aZ&BnAH5QlEa03iBJb#(4LC2A~nX{0%C|GF+L&)?E~`fCyYP|<(x z*S`a05d78d|7P-$4lY;!bs&$2e@#%D^k3KgCk)3w<-g4T?*e&jZvMTvckgD_hsyqT z(BGc*SDB%9SuMI+7MQ4$Y2A7Dm zs8Axr+0Bi3eSMu0cZM>TV7*iVil~U9G&H<0mx3z%N3Q<6SL(aqsF=woAc%9Z^|fq_ za}VQw2-E5mj&+!*Z2)n6Nvz4C2X|q)$3T!Z=|hL9cG8(+_(**Eg07+1%F)jbmO3Py zCPAv1OlbHIY)yCzKP4YKzsK)%IB#4A$5*b%ReJA3VDwtk+$4xh962cGwF9yM^QaNV zq)o8^#G9ER%p{rk}hU)Xw+*;mAp;busr zX!S`2=q(}vk?PEoW^wW&I(ZZZkrk)hAHU$jjvD(*vG?BEQ_mF7u1H__{5p#XOqdm& zoDmiqv<1ss1eF1wqy0PjaeNR)N)1m|Ru%O!ry!oFZvL4V<3|l*CtW_#$Wrb+fyl56H8bfBEMJDP;`zASt{zY*1&;v^_ajGgVAnqN!}!As4`HqikE+4*cCE0y<_!d^9^>d)4byh?@<#a9D)s4*ORva( zLT+9D0dCPnajZ;=A2eofC}EP7`xV|YgiA1SB!H9a^l0)sGq6T%q5m@{u)LUpl^*po zFWa4d{X6C@rD8_9cvYnDby)Fh8d%nyTX}WQ*=I7`m)2~}-jzN5%MD7q%0JXt0vsn+ z6?V!!pja$|7>+QD!?e%_Q?sQ2-L7#{i)Tz1b&JT0=%$8osN9>@6X=>2a%PGeXk-G! z+r9Yqclpufo$dk6d2MhdkXjur9pcd)ERwZwHL3!{Vaa?=ow|uF!Q`FokrjE-nz?vg zSrquKaab8G?l(>_5c?83w@kh&If}ni$k~$dD%s&?yrYpbwc>GkUjUo&sol7BhqY%K zmaWyu0JFk7eQ(TtKb3z<*cx*%UuC+SR_NgB>&5ReXVHTG(0Le7a{kq`6@Lcg^u#LJ=X`uU>&9<* zms?Lm_lf^a1bE8;giADalcMuo{kNa@Ru`1-kKj&-9V?R=EJE7dk! zE?n*kJUx|rcj+z`K>@y|vq{!Lv+Ymu;mI}`P@3D+#o323NbT~4y1wt+Sx#Y=iAMpS z&90P$;(WsOxJjturEpGt;atOb6u%~3PJ~sAD#H1KteV0Hp!3~{TWwqKxUybzJC)O= zUxfIKCd8KRX2-_w)8(SK$B4xVn4t{$u3A9)zD)K~!0QpDvU*H6k!MQikcSs08K69p zx~(SXRQ_h1_U!LMcrRy`0(3wBeByLw8GY%|IEf$Cd1Pb$+BvY&wbU$)hj8vV93k1S zqY_8GbGlHFGnuwzh@#D5tjhxznhfY&Ir?R;;E97pY$5a}CdSKMAtu3?{K05Z@TI=; zy8lBmL!_v>$z(}ipE z()HQY@K^)+v*h45R~O2)l05Z_*CWU4NCO(|q225;pC~~M;GR!nSm7er%fS-gZc~~Z zbmDXgOmgDih`TC@be?BdtO@XOO5DKGN--&qY!fE)Xr#Z_+ZSA(aQn}e$wh#vYb zu<}{$(J57%5i(2#)_fPA@9;2PRa)8p* z?!ui@)lz>|3SZqB{v8Bh$fdNna#1`S($0idCKl^xfIJ0+?FF_rk`(JcFUDNeV0$t{ zTEt^x;XNKZrdi9T&&5m2ut>$kJZ#$zzm>Fp9l591svlUIg9H)X4PRmgc(6zfFm`29 zsvmnZsZ#>3TrD#jgnikV2lkvyHGe7PN7eKyVlj_z!0vF!1-Mx>~z*{=t{lU^~w~Yg6 zXt=#?9IdnHX6+v}L{0T(jfo}E85bwO zIvCXB3{ATH57WANQDr8+HjiKL)fSFcsPNgeDURN16W7>(R6D9jLF$b(3S?&|NZtYC zwtIQsl!_q;y^{>dbGF=c$G=?PPpSM&Qkt}fk@d9XV>doP!Si_=W*n(MUn{T`i?La) zn6VlkNZjdHMOn~tR-~SF>U!b=`93bNdBUt(t7$C*<@rd;(v|R^&cw{gIt*k=%iyKi zpwjg{H64I?4AC0hBj*_*i9_+aOlt39&tCZm$qM5x$9hD;oZI2|X5<1L6`!UwX; zRA6QEn3nhnzip4<#PG(Dh!+9#IX`ZD4g6*SgqeG*ik6Xq=i;PQw8QIsaBu2I8{RM7 z0qWs0i78Ls6p$%5uWD5l5Q;e!GF#VdSGtj$UOLv_*5jz0kqpzGpV!9i*Ypi+lcP|^ z`(FagB*TO`5+W1pa?8Vq?*zV=m1)S5)Wqot$WGkXqA~|@|1j^vFHy~=FIxDKO`W$@ zJB4H8<$OqbKe0YXfDTKmc2eTNeqC;VzhP&@9Bvh%q!rmAb1=&uk*OUG#O8CnkJA3V z`B=MC)Pc!Dy`~qH<2zegnN$M+V=e?6J6MQaOD7;^mw{ZPT^eXdrQ4HrJW=b{tl!W{ zO-QE~`?+80h199e2z7%}{Lo1;F;lbdT;S{r>qqS9NzZFFNsw`zzFdaF)1WjRbY>cE zpV<=8P5zu5GBx_Omu+(Dp)0m3Lllc}Kk6o8qi-z@)Mo?|fz}NwO-J>e$c}o{Mh>@#*)yZWtBP|Hrn30WMy~!N*9S;lf zQnq@#k<`r=U37jZC+WeleT%Gr@0l3xw8lVfBXSce`)*UCpafL~F58Y{|L|67BA%O| zlj2FUt1;KwX>oOhY!vN#hEbY{>YCI5jhq2lQRD4C0J>}035HMB1HZm`V-0$UJ5@_M0ugr@?yfSZ~Ck4BoB z?g3X75i~FT5fUO(!NSH%a5f5Koq9T$aS#|BLvidrY%AEklk zKbh>A{zzXQ$?eZE-|jQzKTKR(GRa88IWbLFwx{mWh!;h1JN=!c&_@MuYq!b);#>25 zH~^1al>qY=7M`o?2IW(%)BzG|rr->i#nd|s615VpuA5{kduX0x{-&maW*(KbO#J2e zxXOOI2UEw(7e?6dGs>FuE(sqo+8YecVik0%@roOHLx1x*-(YA<5a0Fo)!PDS@1 zpX(;Zp@SNl8TL_msT&s)_j)Wqx^AH4ZE*DLp_F7qO1e(`2fcuNi-WWrlCh@@kgf_< z`R5buacS7(ow)u}zc&v|d8uJ42C}*q>jTYfB^`CimKrS~CjM*i{&`JETZL2gf;P3C z?ip}VHPg`CeVUqC;20&nvXK#`5<%HpB5vzlvo*|C~6eIlsS7$yD-NWUHm5V-({nZQSV=zC&u3(VoP zK;IQT7#VORYt%99E!^6#Mvo{+K$xO+p=CT_nBvT|)wMl4ipPbC>dNHenQyv;3(=Vn z(U1}PD8Ger7;PWP^g9SescX&C=$Fo^?J0qvoX%6hg0}R4HOcxJ5w95g zI?lYY_dyZ8tV*Ycf~*s@nq0+TiEdZ1$I*VmL*p{o@HcE;e`;x_5jq z9AuM=&+qH~bbO<))&qeL6PP?wmp@YOEx(Tu<=@vA;6HA+>A`8smc6jonfG1S*Xq2K zTlsj~ZV|<){)f|Wj6$lpX&s2J1Yp=T&`xkLWXx2Uo!ZV+ zbZ#KFSl;UO`fBSsfq3ehdJH7KCo3~ALJs`o~J#vJorI76=e99pA^N13UDC~r|t{ejZ-k#a5w)t|t2=P^7f`qWX z?a`jQ3 z!RET3*#}=2T_tR^y6r>ixs+Jt{2nFEZ6eQByjC`7dbv{%`6?i_7}M3a~;=iOrPf8AdBZl zoy1bv4aZ|4Uj+;sv$V97qs$kU>6v(VI%n5xPCR9#LX4_!X2G^}h6y>m+DJA=Wh9=_ z_YH_Cbpv5G(e+E`9Z1HFtT!y6&K%2DP0~z+sRer4#@F7GMAlk92sf+Jqg&!A+cmqd zIajEbDLUj~7KPC1pijh1KZ+v`Eknk?iewvF&Lv z+nXbL(g*V4>J$3;Q;eQ<=JUveEn#-_PX}Kz7En_*$cu-;(azAS&is8s%GJ(x^B@D1 z9!X1aaleVKjC?ax7Yc?Up@K$q*>GUfA!B-*N$Dc<7;I45PT3~Yu5u% z&Epq)r|UNf-xFYv$+}ZX4F$|AfsvNa%Pun804LJS^(&Z&Or$|CJL+zaOMxOt;e58$ z1<01Cx37;It)J4@E%?ThMvUxe(#EvF-E}*%>;2Y^IT6`((bIsvdHiu;)`Y3p^2pSa z`K9Cin5cW1Y$Fz)aCy8GQoz#)Ih;jp3h(12LagGZEjvioCO$OYbjNz>;qH{>=lV&y zh7dh1d!FhuqeX*@m{;>!dbyUH<{eT8$m_Nm=y&q6`rvb3HIlE)pHo=EeEvZ15jCBb zl#$vXWsZR|;Y<3^c%D5oxL{coujj}3wgy%AbDZXhmKYqo8ggYR{hZ)56k zdyk38NA-cn`PrzxMl28<>Wne1+ypYxk+0s%mV7$Mdp`U`$%W33zswc(xVq5y>DG*X zx{z~6xxOHtA92+}+S_u{XF9c2AqPe66t#kb?ss0Uxn7z6ic)JEL`1_aTeG10RHT!= z0eKK0mGp{|5*+L^ARiRFvN;*U4?LphqE}SoCA~Y|k4dimyf{?KOw8g0qNPIPr_4BN{eUyKgQo_PDj30P@L@^xBx|C$R!){2V*E4{y z$BaTuO4cpVZG_3&wcPFr0aDyr z%8TQ_TQp_IL1a~D`nk@o?@Mn7!R5VI2R0uMP)V1E2Xj|cmvB9BVH{9Xe33mEVbEB4 zIx?bJ2d>`jkX*iyU(T3X2I-$%gqDaXqp1SX0bO^pM_tf8at+tX(sY^{JD9D1fy(|JA(CrmqyvrJfoD7G&+GXDg%;g1kbY8x)aUU zU2i4Gjm95%%dx9|PAE|%&(2-B?x6@_5;8R5>|E5yF(ks;~kS#y+sMWvtJLs1p zk`Al2@>Te#FtG3B=xWBXVnw_JO^xrhkodtX;*&&nfW}VV8>-d`9Fo?4QJ<7Uoro9#eH%uy5$v zFmoREN6Tr;&q}Th1*MwF?hH>_XUphI+ z*7Od{5>uBs)zwUo6%!npVCmC99)2Jcinih9{AUpDMHl8KxLjqmA%E#QlO#LD5aE z%-7>%6K~#%4$DOyCy~#ol`|NE0)_|qNlfI5*X`KjWw~XU$Cf=Hmb$7ytsF{AL$+)z*jO?t3>zGD8@=`JLu3@O* z@`!4>j0a5}nT}cKX5KMKvoeNIgi{~PMz;ntxp?AZfw6a;QN0aen?~3b;W0lY7q9V5 z`tIiM?AAQlz&upE6$Lk^K# zlFD;;X5-QArQ;`XRCqJVbB-E%nQh|*9`XH!Q#~?sGSfG@mpC5o`-JfrP6>9Q`X%*6 zk~>Ewab*#AF*)On>SW50%B!Mh+H5k2yh{YXQK9Os!CqR%S5ZRbfij|Jp(9_9s@@oW z+L+tI6jab#zx|y8v|6f;Vs5KYBaU3VoSuc4;e>FFL`qZi63#>yk_~o_Paa+K@kZ6vpcPcG z=ZD=D`DC=kkJ%MIo2;~5kKSJrqEcj;f{s^v5=J-G6z5P{`MY>0^&FnYy4Q~vI})8w ziVDA!;J3@4!JVDaOomF~FcZxZQG3k00gDxL(6W-l-o{7CE2sk-m1vmm8s?5iubr4D zr$pE38hFAz)niu#kp(?8!!_qGywz))x)Op@Yy{$g30Xj~fULL!MhiS!lir)c4uOwK zPSmuxD&EZ^lES=;seMB|sXSll{mf9QRY=+3;XmSkgkP*c#Uy(lH(r%h_3?536^{}g z%+ZrjhMpZ$t6uq9IP*2Gw~!d~`G%B`cbJD}Y@G0?i0&ATqOs}1{-uc7;^}L=*EP47 z^z3Prq|Hl??fs&e*k1ZI$Ntv4oIMI3*n>}8t4N>10yDC!X=*CRonu0xCKGRdRSaXy zvlVezS_NO>c}dqj1nJ+8qn{Xc462H?nd#MJJ#^Id1d~hB6m9m_~(&i)G8J z2$K31=jLyEDh};pYI~2M#!GFa86I2CyylXw>3Rh=wsJ-Ioj6UxWu zHnW~FYTPoto6MP+uzIT)Kq^9*`8NfPs-iXwMLO_VHF>m5UnhE)#(=jN{; zwr3ZDn(uAb@qF4Jqg=k?qx<2Wo}9xC7`51?EF^=XYVO!lOmr@8VPLMDo!y#UZWLG< zw+Rgp8k)9IoxVEEDl?%YH4~68kqenExL!M4Mmt8-+5_Nu&apJSn6)IuRY8)Hpvmqs zR`PAb-+x9Jc?fU+j#qtC8()bxv$}Yra}0aZUYDS`H>l}zgd6|i<>l1yW^C=bw?i(I z1i>fn&7VC&T(MUnF3ETTE5lEFee4ttWIB%n?pc)Y0{B+$qAiyvL{>(b><__xj4HSU~4BXb!~?Fb8$IZqooFp z^@c;$X8I0I?~K}4CN^lmSKD?=5iP`4h5XI;Wpj<9us4-NN*P?-PA1c5Pe;cPKY%wR zyf45kc{<{&PODq9{H(`qDKHWAiSjcWEpAqQK5b&g`Qd&OSI(!@uXD6BU*x{Vydo7X zI5SAYM0}0i*j{)VJ};-17YY)Sm$y`=a_4+AlnHgNzuk}#Q*bbjthonEI7)g(}PVjq7X_k7r!^2^pJSPibsyNmWzIAZIhA)NH;NG09bd z$J9nB_^f{JlQz{AVryg8y;0y8TPg~z@bb$Vt!7ym<9AwFp`oAsBV;t>B)xK@y~E;@ z{s5N`AvgCLOq$x1lF75r?jTHggUYN1)^_u=(+mX7tt1`W_DmfMdY#0Sd;47lEhQTx ziF%r-lUC{_vncf&k_Lgs&8WuJ>H*tp)<7hgf8|eUIev>jxo?^)56JR z6`=njKx#l?G%Q?fxaangN#CU5LO;ZUVWn%Gy6?{)I4N%`16Wk<&-%C&wRjzmk4G>z zV`p5At>M)C5DT{CmZWBcJi3O0PQy;}a=u?0#0qQL%5n$VpBi~aMK!Y2q-h+29{@f` zpb^ls`3Oo`3w{^1lIJkSW4~Pcu$I^ISt4Z4LZ-0Ipe2n(=q$01%6mcc7nd+46VDnp&_W(t;sOI&+Nmlsg zGk8AhXG1oQsqS2C!=0f!-Hk|)!N9PP0~^g$_)d9EHn8am)6>_37~6{Y@E7+%)RnKQ z?g#63ngO9ivqNhU8J_Vm4F?H~DZVOOk58U#@b^I}{pDYj&TpdlI?B`1okGOsX$YtL zQmaWm<&3k$ROj-a8#=^7$-7=_g9fHXj*M~YEp3GDjuGZ3dCTPw-O6tOA%_7iFp_?U z?w~=f9$(Z~;^`SLf|LFUPHdpXvH!vWHdGYJ2r=<>!P6sp z-V-(%ueTn>HS`1uCncw0`7m2eNUuHU?tP5Kl{Z&Gs@uZ%xSHoE3!M+)gNK<)^H0W~ zKJveT$K%h=nxVzaBo_AUSe>$FE1J zI_qU~?giVj14YP8MaIlVW-@MihKuY0GTCEnaog)8gDfWo>yZ&$$5~dJChuywMaan8 ziF-R?4y*&IFNUZ^sZ}^@rZ<55b)>2*4&NbD?YLJymyfze`w%Sxs4{XgTeMF{2nh-0 z!Ow=3PyOJPYH1HtK`0O4uw)qNeQ^5disiKp5^?ysF}VjgE=s{9;oB#*}~{xcH1l`MbCO1xZY3LxAt_G5boVSr8rJOx&2}Br0?LV3SDbqwpAzk zELfM_=U`~@xo-#HN+z72P6Afdn+N&K$#b{cBW0x0rLOmm2rlap_l{8ckZ1+ty>3{F1ZQy3TKsqXagL2zF1(gg8B3P53&J zQAccawR#Orltr6QCtGu$rIXEzocWD2+2b(B$TD03sr zD37Xq7`bo9T}%cKLFV%!dtojgLa8X*D-r$$CM6&`=X;7m0%#TVUEjgyLtx}vZ{Hlt z>v=Q29cqeL0z`c#asNt$gH)Wt&J0({uf2qGWTbC%r)X4tZhAt@f^0R_GLws1G9T@F zT!I_I!ZHE|_y}x*?7a3DxfOY}=`AEv2u4#Aovn0TkUbT2Eoy#bS3A)q830sq6b#`5 zY&R*JQ`qFR-4OPic>?)_E?;O@z@}h*@AbKtvBxs6j}WLDO3kYU0q1;3c`3ZWA*w^9 zu7NljS-5jgc+Y?g-EfNpcbE24 zA<1LX4*=9%+M#-M*(p^gwr^?qaE}AFnMhzmz{PZ7YD}??ajc}}@(U0SugsV(spGl3 z-FeK~u~eyn*J`@iUGfM>zIMFdX7o?DNwwl$|+iY?4|ojSM(l#KMR8^dx`r#GGkJD zmHBYM{Oy~o>z;P5bb2&Z5osKJ_RCj|UyOvJO?+J6rly$cLgkb1_Amihy1RivjKehS z9S@s}9FS=r;`hW@d--qkLvKm>yl=la-zunCia&+9G~bMdrQfPWjRuVLWJU(ysc5MM zL(?2f4A?4b!W1rVT)Lg38XnU&e^Dy6n(Xf&W~<+LX(X)yG!}P|to|JOIdV4xncp$_7B?Kj4nJR9(~Vw*TF^Q*@YQxdP;7S7BbSp z7#MsrJM-5=NRY;Q{=9Zp*=py~YI?N^2JW#sa<}-Oe;3Z}S zzz*#k&R(e-Bd(jdgc(E}FpaSV z96KsTG9to0(QRT$YS>)?KU`f)iVplBEy`+UnU9DDzB$ClCtUm(2u?^3$cD@ajz)t4 zn_uv(_pH2gQp{d8ASjJC&fETF0_Zh6*l=O=f)A3FX)}t5 z5Oce4{gh+%@=fhrMF)RegE6Q)piBVWPmR~Jxik(4Axw#_1NoTih)?^u*IF;D0;3x9 zy=A#aAnP`zLp_;ORK80heE;;NrlxAQUR2tWogtHU7$pEUl04EqxL#wtruX@IcScJ_tm7VvR#kH_vz46{IeUFVW=q=1 zr@&2Fy>?hW*NqYy=wu{GC=F3aI8OXx@=M0fm$d;9$n(w}+^dLp2QApQGAL^lHa)!l zHDAO$64@yiQ#k6MTqIp`=H78$Nzz6;kCyhB6 z>vCkSDkh!ryi+V?T0fs>{#=FljGiS@gE?gW;vo{6*oEd&UrfV^e4hDsWgPL#vXm3F zI7}~<9BZ(`=a53qXD!3S6_q(WR7!A? zEsueqv66*njXiYiz5Hai$&dI%--^}kk9#+a@@C{};?l%xfNQfgY#RD?zcSsJ`x{A9 z)o{zis%n;`rTed+4v-o$x1JxrOYK>%9rVI_$!5RaUkyst!_@b$uo)*x4@_y)=bJ-N zN7v}gKN9+CYnGY09;_gkPLI1#R~AwejmD_mdZHy<1w{&k@Ns z&S$AvJuRB(4A{=lC$yd-yuIBoH4Q3S*~qWC@CaL@Z5#1c1GU&OJ~OXx+g6HoFid5) zup`!tGqjlQR;GZhwMOm~Gqe3u*9jU6!@`#eG_Pm zPOPua&oB5m2~t`W|bGB1m?$es!6v4Q^c8Nk(jg9+4RVb8THK!pIars3~#5}!nMH}ZH3UA zP-Q}U_b*9^$!I}bDTTbtp|(KD4$Vy6ob<#>h>oN^yUg4j-^+;7mbbx+FJ|VRKDfm~ zh{$FUpY?2l3_EXQXLj5mtvLzxB-`!0a-5h!bPC??)Pub4C44diD%5o<&a8djwernO z%`+nI9!!4rBne&>FUJKHa`{lEDSSxy?X1k)&B6c!Yeb&ghu-b!w4=C1y#Pl_*hf22 z&UGqDxG+TyVc93^@5Kq=k6&p?M>##?hWC0(sf!5XegKVxfO0^XdJY08yBF$#-f#f87z|O+c;YlMcz1?7^Ubj+Nz#%2nxlSWMQHhgQ z&aV9Yl5k@NK*CwocJC>@T(vq1m{mT$C3-{;xjZl#XOU$^8487>bXCQdo2={@dp$E}^} zq?Xa#ENCZBw#OGE5NDYWhmB#{h^a{dz-&Mq4|RxDpkt_>*_2#tU=WQ0)n9Q@=B&4ZW1b;G^;9 z^P|fo;C!*O`{Km#rLq*-j^4fNy1#L6!YM=FwW~GZ)~8OjGORIdcVTCx4Ip_64gbAP z3N;B?N2ll#FAUQYytgblocXowvlX`OjWT-rC`ORTKC5@8dkaIoLlwtGzRyZywa7em zjcL249lQ21a8@tn@#*n8G%Z+sT)HHuYQw_o?f2396kRb+26eT=6V9IPE=<}W3XN7M z)rFO-YVTA>peP}!z^Td6B+y5$2YxlZV^B?Cm5@h6bYoA`Nc4F&+5tVk`Eq5re=UZO zJwIuif2WT`1VV5C0;Yo zC0GWkg#D*xu$rolhCV3Q+8{^EqdP{#prLd8t|u($92p{I#I{Kub%%7xG@1$|AzK^O zact7uyNhC>UrJd?XSYpwYE^MggOP`~HuH=S`2D=Y&;1(wwBUTiGW$(Sk(_LSpo4y7 zXREOheLD!+IlOpjV;4ocipIOyDO!B)n^}SK{;!E$9WatH_ z6Vmow6C?ZhR3N~LiJ2QW2jmhn)FRx$QvB=Xq|7D;VD{{LP-|skfTQ zNVEYU7jZQgFZZjR%||DOjF=SFi#HBx9{&6LOVfLpI~l1FH-=ij$fr)8eQFI{?nHbW zUEudX`J-2thSvHXhQW#J<)uql8x<=ZCBuH?V7wPO#4}7x^eh}^Pb%pgIv`nkd6jpp zr*4G$#=EF>JvCJs?YMC50eW_F_L{<6EAP@%91S(6g7@;N@k)x`c51b-5*C%e*5>Ow9<^QH;=z81d44pM8s!d1K99h2-XU zPihQw`6Kke(k(^B>2aaUq&^Ex0LCV#iwo%Cqs(VX>2hCk8p$#6^~%gZ6|JHy6kqY` zcC(DfOC+YcyGMs{<8In=kjBG<$Sr19)GaEhN$Bcfs4`T1v^3>y*PcD)3}4zT`-Nns ziTj*XlI*e~uDs}`;4K8Gt!(X}VJ;k|b9|#N8{1K{v)H@DhxA9)?Pd5<)Xh+iE}~rM zLT%GegAO%KC*q#X{_zjAI-83uiA>UKD4*mFTX2w#e`lGyk>-&{XFG)|RdyruI_Ab^ zRvYqy5-rS8TWG2?=b!AfqUfof(JZafOqm#4j!W^3a}K0(*n^ET5bYRhWcnq4ooI|5 zWJAGK*acDVRn$kSx@MG>r_`6;={6k{c|{GLd60a>W%I48kC!4NMMPztV0^#AX#$xJ zwQ#q8nNBm-uWmfy$$<%3go0sZQGO+55h`8ZY*_7R1-J24h7KdV#nEI(N;&iG)$Vk5 zXV$B5Cvp3GUfd5WvFK=Z9sCX8t>^W^3d6-}h3%-FbRm!BoneAc`-dJBsG86lQ6o+) zxB!5|qmMI<@^B$95(^4_p@O|FBw9zwPOm~J!(iS+9oOQbBQrH)WxOz6^G$yVbrm9R zhjiSs(eW~+uhZiKu`{`_ko(%-u)FKNKmyUG5 zj$n#Hh0uEL$j|5|bQj@VY#vTr@Y6SNndhzseY3shr`hP5TdRP%Oj6s=i>T>MzC{?< zrJLOiSbEnaAy;P?Sk#|c&>^*Gva_%Twg>NJ23#QcV=>ZasIoD#Ul@MbN{9z3?0ys7 zDL#@?Cip2Tn9orL%!*Uk*u+zO?%Q~j0#L%iAFrmh?r}Odbd>){ZWq3%+utoB(X}0F zS5DQ<%v$sFM2c!@%-Olr*D>Xgm2>dxEFGO(pkw>By4p8#w2HLB)77d)WW9ej0V{*X zNe+==FVbmUQEogh8B;r>31{Ux8@t+SDu>YJ+q{L&Tu&ciJv@T-%6zx)Wye(@o?mxO zGlV)Hy8YRg!Di}~JeJ?15d@s1xIPRp3_A5SXmKQ6d7FfL@jHF2f zD(I%T%M{2&f3@r0qz z`c40WEr1G2;GIiL;N6Erv;)W?1Q~P#oDrH&5DHbx| zL%whrBoQGZY>!cw?GL%%5%u$J1()~;-sk$0#S)CYKlwfz z=xUA%(0R{TtAdz;mYi>`GxeqKM-}dAo+!lFJAdK#EaK*bkSIBCB!r9NG6Ie7*^ul* zgmwf!%YDUpFZun0d$c9m&O7qscVCc79b<#nZhuo?(C|9K5H7a`bRG{6voor**7V?l4XV4yr| zEq2^FqQJXvA76+qcD^_Wyx&p`k`Vc9@?*r`d}s8(wf7xRO*LEFCk;YR1Zh%2?+|)Z z2^|F?pr9f`D52L7Izs4(N>Ne3LRV}EqJoGJnu3A_5fDKGqJV%Rf*?}<6Oi}5y!X4` zdcU>q_pkNe-+`PtGqY#UoW19qOrDvuH`Do7ar(Srv{4ENDKoC1A9{+i?Lb(jju|(m zK>M~J>Qpgl`hbWk#gyQ)QmL)K)05$(VY3r}g5L#%kK{0r;496>riln+I79LlNh8?2 zvbQ4zLepka3-_b7QWW&7;lnf-kOS3(Piw`MqbZ1$l<&frqz)VpL?tS5rh&a;51xaS zr?l}LTV*WaeyR`ygqhKSmn8@zl8KHU6fuZ@Aa;P!J~q-Qh@F5F^c}lRMI?u9De5z2 zz;h6&^##KKYY9)E`hal#F(42XC!6?~iEA#<3&qv6y-0}0>RW)|>T$+Z@P6jFHx?_& z5)i}%wBRlj`)9>IpN423-wI%yf-(DkG5ATLTWE6@8NoobvRG~z zH~J$-0cDcHfJ8C#%wU4Xm_bib2KrR~6nAR{${WTd{Tcjsp=m6ohL)6mvID~OIe5g2 z@(6~mA+8{|qTyNvM)84+Un05_IGQ2y&{$7)S-=;{wAjE~$d&b4?EPx9Pz!^KQOisU zSDt|=#b6iP`9@YV;dsc+4=KpRStQKf0=dX@2)WZ2dY4hql8Xg48J-*6N-NO!x)qOV(!M0Ipd{ zT>7DPwft}+0s$CgMy^VU%^p~CeU}iL&cDn8L>7qVm!#UPs8b9Nr$V`zzAiC1{w#Q= z0sMR>&(6u%%YCnkvIBZ?NN@g;9xn!X>rf$S*31gu)`i1hCJT4LQQSf__77M@TI0OC zTY@1F#bum`8UdnD^CiZ8L^5w_QtKAJbR3I}*JtvD9~7K!PofI5Vxf2RP>qYoZG^*( z$!SJ~&LVvYPcsQ9_UpoJTE1pOBBQIP4eq3Qzkjz-ma`gfvcn){8umW$aSAjCdh6$@ zr1Qc^+VU}~upN65jg95Zk9XcDiU1|xaURAkH3>2=Nkh0neE>x``Tg>gE4w)0G>2l- z$))BpT&8(oX{Xp`1rmiKQaqL^@kkmWK7cXxJ|OY5A(NMCDh}T^FcGVdDW#w+pv0;; zafa)pw&iB1JWhqf12tFOB|0b=X&{@xl2o$#4N1dEiR^mz?ma3J8wa z;Z+ybNRb551S`yS=w~^uhJrhKeuWq1%!FS%3kmF?z*C zo`Ik(gGZ)mAJBxXk$&ErRp2+xIGLWDo}9$WtW(fdh8EkWNt5HDp_+cuu!*sYrjz_| zxOx^$L0T~pUSR!Q1F4^5)IF5XPEbuf_W|2wh}i;UV4#_eoMXkX4j{Zj#Ri?%$XS4- zviAD}bNTZ!z9XyGO+S|>_{~|Vwn?wb{78VwcL@vheS&Zf*byXf45E8lSmP;bMWT$r z0rnXYgc+wz@)WM4SO=HecmZ(`o|*df8N^7SXyx=uaC$t#tU}~wcz9^v>fZUx;P4|9 zh84}JcQXqd8Y>=*_#kvvLNZQj8X6a}qfD!gV7gtOB+e+Iae(7M=-4&Wz#q;iW;g-o zfJ*D4UgqOvZW@bgfYHo6Po+DSr7ZC)8qmNZ_6(qhjNI7%$w zb%LpYs5yRB35{bIVpn4-pR#_r>YR*=??-)dIy?THVN2==RdPl5tn@C?qU38V!l}(C zaT8F-AVw*~I2&<$VlkG(48OG}C3F!Yyo>53P?Q<%3Abn_jZj35&oDPazfsb8MMVfu z6@t+4q#z$g^Eljkx1qEw0K-Rx|*d5-H0{3ZkY z%$DMU`^H~18MabxEgag4KA<%bJK=1Mk2Hg*kl|rVuHfWAjkj&g3vHPvk;N!a$#?2@tn$^-VbZSYneh zb&jz`zJg-@z`UqE4dIOC;>81X!tw)pR1C~UAN4$N3{j9- zK6IMhCPA5YPTUhh5wu=(h1w(dPqI8qkI4r>_ellj(@%IRPR9-yW-`Hf92^VcJj+Bn zVXWPKVmc;n3yvB8w(Oqaf|%fK9HW-e5CCss6t+uc zL$FQPGp4btE!4zu9dPn=h3v*4+&Q$DRk3~2(x$s{A#Sh;Gk)GeAXAXU@EF}{jG<0& z;UEsvn#(i|h$J;HflVIT#pxz6T*QsCjfS%@!tAwt+bTppqL~Vqjlp}~5E?^cn06)- z7CkI5(At z@%h+u5bhx<#xag8i3M}H0*JMM;x=i6GfbDVLZILtXc#cdq8T_yX~>C-xg0+t$d@IN zxE=BW^0i1G0yt7H02S;uDXnJB)YLWxX3lb?SyQYYvzfJ^{#<+sRg5hh4imN=vW38a zVCap;WGY*7VDz+9v>D&@D?VPXF4gM{CP?YHB!jZ}XcR01Ky(%aW?g*_zpl|GSHXl6 zxcv%Wja8|E`DDIGU=L)fg{V@vN5<^q56*Om}b&%$!w9GL)rG)Yo{8nT9y#KjQMR>vC7Jh?jp6dzI z5Em4CL4QIp9$qinxO-YNE)!+XQ;}fD*l56qI!bVD=C&4JjZ3TpwgLkpc$zZ=?JF;*=4YWoHU^3kR|IH1XqY^~d9w<&&Om&D_?+cH0@?b%`KE;WK~&)@d<_ zk*G7H2^AKvbt}bYtQ!NT`Dp1xPf&XxI|uM8M%c`g&75op;*X1nKcCIu#i3`qDDMrO zDg9{xk6s~5wHU2gnd+jo;afz93b8W?iX?gCh*KsK+HEwg6aF}R?oJ<>*qiMf}u*S?V$uZxrH<8xkp@bC}mC zvbQ566A!}JWMg_K49sjn%Ha}Ut%>TLXK<*S!&k4;;<@W|cW zjY*lr4DIv!d8H|!EO1HuM632pb|ss7hwTt&z<0AjyQENa4oMchj(kF_jmQs9AmSvyU(20jIJ($_B?{>adqu5?XLU zF))WgX39ToggW^D#YQM-nv`y3_1|Zj6tiv~>z&25tMq1Bd7+>MReA$tFt#x^F}5+b zG&FXy*tK^b0C0o$Cg}!A-JHqJ!9?VS&HmCI&H*AEi=Q~?6ZX(dXv^mYX zeRI!k8#kxt>^ECYEomHd*g)mf41E0LiDD zg|lIkb@Pz=gZ%f&ZwdUCz;6lsmcVZb{FcCffCR!JQw|XXR*!7~=XY@orwN4I`79P< zG@W%)dW*j3+1q7yp7uB1jCv+LL?10F-zQVJo2yiM*!xp)5TkKP*F&_#LZ;4^PZo=H zUj}ql?^nGZoZOxNLoPJzIlUM%Hhm;(>!YQ8zvrs$ef^i* zp9AWKhF;ejrdSR}F8-WnVr63aqDOdM(3sV1a)M7+Stqi8HmC1i@Mx!%!#(f0{*Va` z-?w*{FLxjD8Xs@C*s-J_C->99^67^OP5SFc$_VGP4^W! zDCC;$edpqbd-AHi2YX&txtiX5df|R})KBtM&y6UKcRL}FIQ_=LAsE90VP)}|;-TV4 z8Tr%W9;b?nE?Hh!j3Cd>@+nu1J~dy8+|~8i_8K8$Tj=MvRjbrOG1Ck|-5}X-OG$FQ zW<~$!_I+s)1L3zpG@q@FAoU$^0`+EiuBduQiOV0T^L;%tqP{Jr z@0L2zP2LT~1auvay_1 zVC$sQRhv8Bcf8B}{r%@ag$&%zy&v^NxY zO=pQcI-aYg?cIO;U{KK4;Ex^VOQfM9V{^i(Yj(|IgEd|+KMGfuP7d7HRG12kTx{Qa zSw-dP;g0ru zq$DTJP4sf~OzMq2m}lhJw$r z)u%7L0Ry**j}%=jesaXOUh+7veJU4G<5(Xw?^xe_?53986}tzQst!%*gz#&455MiY zR+Zs&vjAI>-R3NuadBaMq+MCL@~aco|D)1@^QTYW7LDlCsTt|HAtNKB8(IRrNRXed zNzZ@UrgbXf`~2iL9;L%iJ0HaSd^&i4UU+Bp?Cf||5$S`RR^8H!T()fU`>T${m#V7H z9l8)X_o+9ayXGLvyq%EHR9#&y`RmuOG&XYIYUM_?90lB>940eZaqC*8!a)*~1QGS1Y(SsurrczR8_fK@+ z=)HZAMe9s#6_je_xICD5rzIk`4{1esVmD0_)D4?jIhxb__DJ`s#(|fO;xRiSn0-aR zRaYHsSj}Qf4pScO%CBg%{q(N-jJZ7?19Ovwl|0Nz2vJ~er12hIpZdJ8{}p{|8?!evuAGDSAX@KcwK%ZWtHq^!60yI zp~1;&)$zekIQ%;sGdmO81S7+nSSmH_=nu;47}Sp;)8?HkZVRbd#U>eix}O`~OIe&Z zif`sZvc07Gxw^ML>`b>>aA9wethfeh*?wtmONIP{bBxyrcw+U_xIDH%$Mz)5rQ0uO zTKlf%hB3cY-TzZj;=5~?p@#p2#!P1J)G0NyfrbTcf5NxB9z(T-%{7DOgNNRIJQ{WG z$^FjJH$9b+NzWyX?w(}vwfTU0 ze6<5K?54>Pv~@o`O}>wJ#hitu^;Q#B3HpM{wYWq3Q*cu&Tdzi*AWpzULO-w4cX?~~ zkl5lUIm7u1ud3_fs$}LD4i-oE`@SlvCJaX?I59pxTbCU+>R7Mlf3mH;J75M`gs0va z`L=x&hW{aRk%@f|b3@wq0;LyMD{kT0`@PkrgGiuXux;0qJ8!M(fbTj`{0o)JQMf{H z%j>nJW=MQC1AL`J8n)b|U(~%7U3Y}$ff1%!aj7R^^c?pSZX@*Vd9i`dQO$|_P&}v0 zu3;=vLzrM!;b_JB9MxDEvt#dWSf4p!CeB%cF=2u#&wDO1iE{Yyys$SvTOF-e_3d7c8>t9B=?}ll)pJu%Y~Gl4tJi_!__M5P zNm4QoCwSfgM4N6)O}|UT0!%S!NbsUUo5A&yk#$$K1wA#wwxEJIQ5_pBL;h=kmH5c*-u_P1EMc8#F)T`Gp%b zR-(~Q%Cd3k-4em$I<@23D3zBtPkQoGFZ zEoz2{Pwt^tXehO9yhqtdnElFM$r{gb#n%Gxo;fxg*B2Bj?j$q2)~AiMS{@9r-XV9! ztyZp4tF(OV)8q8WTPKq(#3o{xx26&E^85Ghcxm_1n5S@D4&`LmT~%3rGp2nU#df%bi2&F~c+FL2CV=3DHz-P!Ryp9$hrAMd07l6i`%U$2mlAi}(!ZaW>@7RY*m zgK*+;x`AAn3_8l|d8TDH?&;3|^ORh90^i3_!QFRA4#_BhX{!+^MIBFVS4)Or~0lC`Tup`E0p#2_PaV27b( zrGwMS<2mxfb&m4ga%b{Sif}Gh>E>PBE_m}w=ZRNTt`pT9e5E1@t%oQoCU%P>kBjJw6sjGcG1Ms*(KR=?`oQYzx5rJod$(MM%3HlDk1?@43PgOI}pr}-k%Scly)*3oaRGmn@J z3n-s_b=~N=vA6Pzm*K9oLEnJ|rc*ml@ zw{c3ZjenQVxXO)h!LqrjcE!Cj{)Q<=hQYS2B#E_HQ2{AI(K}a8?%-xSEj7A7k6f#0K}==npxkhWLVM(h+ol zT$>!|Jj+h*vh*ONircYA&p#-{of&Bk=gj5Go$X}i9UrK09kuEh5xsUPPh`O>@XOuE zDB{DB=&yl=O}<0B2l*^ij<;9SEPQ?*^t3;j(O{n36nT%{f zeBL#cDJ87){)T!;9=l4dId7cArGP#B_1RSh{kfQ`*RgKbj_?0knXBPg@+^mk7?S+b zGm(o#m=}uKVqHCo*>y|)qfzCIdJ*eF-(u&80^3!-E`3d%YClh?L*x9280}#R*NkKQ z)6;kBN)p^HK0WhF^1ovbzJtsnBJun>!izqaB03qyFvYv3b(ciXxUNXKef#Ft+e=O7ZwVN;hS-PT}-wu*YQ={`wvO7IZ=)XuuF1c4UK~CdVMus2UC&pCohc)Q?0)Ou@cQ=Stq$b8gdSJ7v71@< zO%JIY`_%ewdxV0x_^h8LTCmBo_yk43w`H4{xB3;d((#Ii4D+J=UtPa26tSaR?iF|D zNLaJYws7B#H8D2&d_=g%mz?L}GGx(`$%+!MoY)o4hGLg)f=3sfeSyBGa42`6Bv@(S zkjn0xLc0APoIS0FSQ~~CN_vi^8^30 zZ};w=lr{gpQ|*JH3z#ZyjWUIIqo0Rp%{ldVYt~l#J#N_ZI!9(=_?`~Zllf8Uf~ig* zO)nn?-(3k#m-7skZ_Hiss@=I#b{a$FPb(ah?t9trso2F!)4RZCWbAAnmP?Tn1*}?& z2tAX7wyG3$1)o%4it7RWJ5Iz)+@^l}6k{?FHXc;#GS$NW)_GYSoL$J*9!G2V$K^jh zzNapE(tL^LlunsD{Pt=X;RTNHhDTHF^z4^V)@$|>ijK8ttRglC&GMexJ;twNruAOE z?Nep0rRz&al(CgFf`@`5lG^vrWz6dPbnc<`-=$D$2ixi^liu8ki^?1-8il=jlN8*s zNAtw4L!}edi=qxPivnsa^~ADXigP0b8$ zz@iL;0s`n6y6f%=YfBa}05?5Dgnj^klm`ZyKnLA>9_Xl#zOGZ~zfBwHp%;NX=%{~N zxRMQ!`HO3g##|E$GLqhQmZv3#+z<^=J7>B@ey{W}sc zF*7m%8h)*x-vHij6fH#7|_Ei z+0zU3&gv3OB!xPY!BuYvz_iBL)!CQm@8(Qe;|3n+4Qw<*&kH04_!0xjUan3aB%((E z$;%n6%Dh(9H^AS+$=}(JNT&k>y&Cbulbz|UxNXq?m6p6l%dkcp z;_pQc{>6{(rF4Uzn{z}kCfLj0m55Q+R>vw}mBD`u7OS)N|L@#@AiUPN?q~QN{{NJ~zgp^--xwT!5exeB z@1_2~h~#(jw*-Dm;I{;ROW?Nz{^KP8F7>}@WCAcKSR(=P-LEv%nXPHZXTsfh?5emZ zj*v%1L!fXZ3WK8nfBQt5yGC@4eh1>xV8f&Y4s&ol{Xb&V3O%$&UvQaX&iA+5{vUPp zZxT~8s4xjDIcfSXVkG@12LOXYhd!)NoalQa=@WWZ5ITYX^OPMd`8(77ad7YPxLb-C zo%ufp6B{!;_?w0fw9xk`{|c+W0{ur0J(x}Zn#!#=xY6)>A$Z)p0r!vWe>wrHZ*cha zqe&W!^JX_Dik15B+)ehH83DjX%Nujcjd+749E5(t0ckL~UgATCqrk9jJ^CZ2Oevv$ z0aw%XA`mbFw_^jXu+L%ug?_dR0O+6-{MCrmI<(;groiB`;#OCz4&=+A^Z|CFh$sEk!q1FLhdVMSz; zv#XC2F&vDYLY+Z$%EkAOW0l52kq-d4wd216iZ-_J zL%^?wHHhyooc<~)*8qQVKnTf+-q&FHKc|TQNP*q{QyG{75xA{u?Dr7K&h&R=oD2i} zLqSo1LSMUG=*|2YWwZ77qLX1j;E?`44aUeT*fjuDNdzWTSrPkR!HpsyhYfY^4I#NZ zyAm-VZ0Hu^O4h~r5rYGQ=^!J9=;j6v0Xj@azgl+^2pon5kbIm%f{AYH<3jdNj6BKY zz+fFEB@ZvMXNZfUYk;4UzCU@dm!FqXV1xq5D?(vS0Ynl6*zy;SzXs5n^w&9qFPi?* z#ZXm6RYk0vGFC;=L)%?VRZB%%(anoQj(`AsYm7Ewl}@1nuFftYzRskGU;NgFu-Ts& zS`x{IMkW|TUoSs8*a`xj7?S`J(bYMajFC1pk-=<;9`g^;WA^?6L@}1295DOn9LI*}s+>DcPuMGrT0u+h)|OY#2!A`npO literal 0 HcmV?d00001 diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index b474eaeb..0f25ace4 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -905,6 +905,12 @@ def dissociate_network(self): def network(self, id_network): return self.extract_with_mask(self.network_slice(id_network)) + def networks(self, id_networks): + m = zeros(self.track.shape, dtype=bool) + for tr in id_networks: + m[self.network_slice(tr)] = True + return self.extract_with_mask(m) + @classmethod def __tag_segment(cls, seg, tag, groups, connexions): """ @@ -981,6 +987,13 @@ def plot(self, ax, ref=None, color_cycle=None, **kwargs): def remove_dead_end(self, nobs=3, ndays=0, recursive=0, mask=None): """ + Remove short segment which didn't connect several segment + + :param int nobs: Minimal number of observation to keep segment + :param int ndays: Minimal number of days to keep segment + :param int recursive: Run method N times more + :param int mask: if one or more observation of segment are select by mask, the segment is keep + .. warning:: It will remove short segment which splits than merges with same segment """ From 7e6017a76716ce9a24b46e688e47738003396ebb Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Mon, 15 Mar 2021 16:26:19 +0100 Subject: [PATCH 101/249] Instead of result eddyquickcompare could produce file for each group --- src/py_eddy_tracker/appli/eddies.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/py_eddy_tracker/appli/eddies.py b/src/py_eddy_tracker/appli/eddies.py index 818e825f..11442769 100644 --- a/src/py_eddy_tracker/appli/eddies.py +++ b/src/py_eddy_tracker/appli/eddies.py @@ -463,8 +463,6 @@ def quick_compare(): ) parser.contour_intern_arg() args = parser.parse_args() - if args.path_out is not None and not exists(args.path_out): - mkdir(args.path_out) kw = dict( include_vars=[ @@ -475,6 +473,9 @@ def quick_compare(): if args.area: kw["include_vars"].append("speed_area" if args.intern else "effective_area") + if args.path_out is not None: + kw = dict() + ref = EddiesObservations.load_file(args.ref, **kw) print(f"[ref] {args.ref} -> {len(ref)} obs") groups_ref, groups_other = dict(), dict() @@ -493,6 +494,21 @@ def quick_compare(): groups_ref[other_] = gr1 groups_other[other_] = gr2 + if args.path_out is not None: + if not exists(args.path_out): + mkdir(args.path_out) + for i, other_ in enumerate(args.others): + dirname_ = f"{args.path_out}/{other_.replace('/', '_')}/" + if not exists(dirname_): + mkdir(dirname_) + for k, v in groups_other[other_].items(): + basename_ = f"other_{k}.nc" + others[other_].index(v).write_file(filename=f"{dirname_}/{basename_}") + for k, v in groups_ref[other_].items(): + basename_ = f"ref_{k}.nc" + ref.index(v).write_file(filename=f"{dirname_}/{basename_}") + return + def display(value, ref=None): outs = list() for v in value: From 2024cdbb1282a05d0d1d8864cf5dffdd76db24c0 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Mon, 15 Mar 2021 16:26:53 +0100 Subject: [PATCH 102/249] Add method to remove field from obs --- .../observations/observation.py | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 7d6ab314..7535a7e4 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -383,6 +383,29 @@ def obs_dimension(cls, handler): if candidate in handler.dimensions.keys(): return candidate + def remove_fields(self, *fields): + """ + Copy with fields listed remove + """ + nb_obs = self.obs.shape[0] + fields = set(fields) + only_variables = set(self.obs.dtype.names) - fields + track_extra_variables = set(self.track_extra_variables) - fields + array_variables = set(self.array_variables) - fields + new = self.__class__( + size=nb_obs, + track_extra_variables=track_extra_variables, + track_array_variables=self.track_array_variables, + array_variables=array_variables, + only_variables=only_variables, + raw_data=self.raw_data, + ) + new.sign_type = self.sign_type + for name in new.obs.dtype.names: + logger.debug("Copy of field %s ...", name) + new.obs[name] = self.obs[name] + return new + def add_fields(self, fields=list(), array_fields=list()): """ Add a new field. @@ -401,10 +424,9 @@ def add_fields(self, fields=list(), array_fields=list()): raw_data=self.raw_data, ) new.sign_type = self.sign_type - for field in self.obs.dtype.descr: - logger.debug("Copy of field %s ...", field) - var = field[0] - new.obs[var] = self.obs[var] + for name in self.obs.dtype.names: + logger.debug("Copy of field %s ...", name) + new.obs[name] = self.obs[name] return new def add_rotation_type(self): From ff30b39c0ac347cc33cd802267c0df460187b97a Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Mon, 15 Mar 2021 16:34:30 +0100 Subject: [PATCH 103/249] Active network documentation --- examples/16_network/README.rst | 6 ++++++ src/py_eddy_tracker/appli/gui.py | 16 ++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 examples/16_network/README.rst diff --git a/examples/16_network/README.rst b/examples/16_network/README.rst new file mode 100644 index 00000000..49bdc3ab --- /dev/null +++ b/examples/16_network/README.rst @@ -0,0 +1,6 @@ +Network +======= + +.. warning:: + + Network is under development, API could move quickly! diff --git a/src/py_eddy_tracker/appli/gui.py b/src/py_eddy_tracker/appli/gui.py index 6e989f31..427db24b 100644 --- a/src/py_eddy_tracker/appli/gui.py +++ b/src/py_eddy_tracker/appli/gui.py @@ -282,7 +282,7 @@ def anim(): parser.add_argument( "--first_centered", action="store_true", - help="Longitude will be centered on first obs, if there are only one group.", + help="Longitude will be centered on first obs.", ) parser.add_argument( "--field", default="time", help="Field use to color contour instead of time" @@ -310,13 +310,13 @@ def anim(): "You need to specify id to display or ask explicity all with --all option" ) eddies = eddies.extract_ids(args.id) - if args.first_centered: - # TODO: include observatin class - x0 = eddies.lon[0] - eddies.lon[:] = (eddies.lon - x0 + 180) % 360 + x0 - 180 - eddies.contour_lon_e[:] = ( - (eddies.contour_lon_e.T - eddies.lon + 180) % 360 + eddies.lon - 180 - ).T + if args.first_centered: + # TODO: include to observation class + x0 = eddies.lon[0] + eddies.lon[:] = (eddies.lon - x0 + 180) % 360 + x0 - 180 + eddies.contour_lon_e[:] = ( + (eddies.contour_lon_e.T - eddies.lon + 180) % 360 + eddies.lon - 180 + ).T kw = dict() if args.mp4: From e754bcedeef82a991b3efcaa898bf469d4145cbe Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Mon, 15 Mar 2021 16:49:10 +0100 Subject: [PATCH 104/249] remove private method --- examples/01_general_things/pet_storage.py | 8 ++++---- examples/16_network/pet_atlas.py | 1 - examples/16_network/pet_ioannou_2017_case.py | 2 -- examples/16_network/pet_replay_segmentation.py | 1 - .../python_module/01_general_things/pet_storage.ipynb | 6 +++--- notebooks/python_module/16_network/pet_atlas.ipynb | 2 +- .../python_module/16_network/pet_ioannou_2017_case.ipynb | 4 ++-- .../16_network/pet_replay_segmentation.ipynb | 2 +- 8 files changed, 11 insertions(+), 15 deletions(-) diff --git a/examples/01_general_things/pet_storage.py b/examples/01_general_things/pet_storage.py index b22981a4..49b45627 100644 --- a/examples/01_general_things/pet_storage.py +++ b/examples/01_general_things/pet_storage.py @@ -10,9 +10,9 @@ - **Eddies collections** : contain a list of eddies without link between them - **Track eddies collections** : - manage eddies associated in trajectories, the ```track``` field allows to separate each trajectory + manage eddies associated in trajectories, the ```track``` field allows to separate each trajectory - **Network eddies collections** : - manage eddies associated in networks, the ```track``` and ```segment``` fields allow to separate observations + manage eddies associated in networks, the ```track``` and ```segment``` fields allow to separate observations """ import py_eddy_tracker_sample @@ -65,7 +65,7 @@ # # - **track** : Trajectory number # - **observation_flag** : Flag indicating if the value is interpolated between two observations or not -# (0: observed eddy, 1: interpolated eddy)" +# (0: observed eddy, 1: interpolated eddy)" # - **observation_number** : Eddy temporal index in a trajectory, days starting at the eddy first detection # - **cost_association** : result of the cost function to associate the eddy with the next observation eddies_tracks = TrackEddiesObservations.load_file( @@ -82,7 +82,7 @@ # - track : ID of network (ID 0 correspond to lonely eddies) # - segment : ID of a segment within a network (from 1 to N) # - previous_obs : Index of the previous observation in the full dataset, -# if -1 there are no previous observation (the segment starts) +# if -1 there are no previous observation (the segment starts) # - next_obs : Index of the next observation in the full dataset, if -1 there are no next observation (the segment ends) # - previous_cost : Result of the cost function (1 is a good association, 0 is bad) with previous observation # - next_cost : Result of the cost function (1 is a good association, 0 is bad) with next observation diff --git a/examples/16_network/pet_atlas.py b/examples/16_network/pet_atlas.py index f233e70f..d25d4429 100644 --- a/examples/16_network/pet_atlas.py +++ b/examples/16_network/pet_atlas.py @@ -35,7 +35,6 @@ def start_axes(title): def update_axes(ax, mappable=None): ax.grid() - ax.update_env() if mappable: return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9])) diff --git a/examples/16_network/pet_ioannou_2017_case.py b/examples/16_network/pet_ioannou_2017_case.py index f9ab7809..4ccf3501 100644 --- a/examples/16_network/pet_ioannou_2017_case.py +++ b/examples/16_network/pet_ioannou_2017_case.py @@ -52,7 +52,6 @@ def start_axes(title=""): ax.set_xlim(19, 29), ax.set_ylim(31, 35.5) ax.set_aspect("equal") ax.set_title(title, weight="bold") - ax.update_env() return ax @@ -122,7 +121,6 @@ def update_axes(ax, mappable=None): field_txt="segment", ) a.ax.set_xlim(19, 30), a.ax.set_ylim(32, 35.25) -a.ax.update_env() a.txt.set_position((21.5, 32.7)) # We display in video only from the 100th day to the 500th kwargs = dict(frames=arange(*a.period)[100:501], interval=100) diff --git a/examples/16_network/pet_replay_segmentation.py b/examples/16_network/pet_replay_segmentation.py index 5f5dec45..1a296dac 100644 --- a/examples/16_network/pet_replay_segmentation.py +++ b/examples/16_network/pet_replay_segmentation.py @@ -28,7 +28,6 @@ def start_axes(title=""): ax.set_xlim(19, 29), ax.set_ylim(31, 35.5) ax.set_aspect("equal") ax.set_title(title, weight="bold") - ax.update_env() return ax diff --git a/notebooks/python_module/01_general_things/pet_storage.ipynb b/notebooks/python_module/01_general_things/pet_storage.ipynb index 697a8c25..b24a8a17 100644 --- a/notebooks/python_module/01_general_things/pet_storage.ipynb +++ b/notebooks/python_module/01_general_things/pet_storage.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# How data is stored\n\nGeneral information about eddies storage.\n\nAll files have the same structure, with more or less fields and possible different order.\n\nThere are 3 class of files:\n\n- **Eddies collections** : contain a list of eddies without link between them\n- **Track eddies collections** :\n manage eddies associated in trajectories, the ```track``` field allows to separate each trajectory\n- **Network eddies collections** :\n manage eddies associated in networks, the ```track``` and ```segment``` fields allow to separate observations\n" + "\n# How data is stored\n\nGeneral information about eddies storage.\n\nAll files have the same structure, with more or less fields and possible different order.\n\nThere are 3 class of files:\n\n- **Eddies collections** : contain a list of eddies without link between them\n- **Track eddies collections** :\n manage eddies associated in trajectories, the ```track``` field allows to separate each trajectory\n- **Network eddies collections** :\n manage eddies associated in networks, the ```track``` and ```segment``` fields allow to separate observations\n" ] }, { @@ -112,7 +112,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Trajectories\nTracks eddies collections add several fields :\n\n- **track** : Trajectory number\n- **observation_flag** : Flag indicating if the value is interpolated between two observations or not\n (0: observed eddy, 1: interpolated eddy)\"\n- **observation_number** : Eddy temporal index in a trajectory, days starting at the eddy first detection\n- **cost_association** : result of the cost function to associate the eddy with the next observation\n\n" + "## Trajectories\nTracks eddies collections add several fields :\n\n- **track** : Trajectory number\n- **observation_flag** : Flag indicating if the value is interpolated between two observations or not\n (0: observed eddy, 1: interpolated eddy)\"\n- **observation_number** : Eddy temporal index in a trajectory, days starting at the eddy first detection\n- **cost_association** : result of the cost function to associate the eddy with the next observation\n\n" ] }, { @@ -130,7 +130,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Networks\nNetwork files use some specific fields :\n\n- track : ID of network (ID 0 correspond to lonely eddies)\n- segment : ID of a segment within a network (from 1 to N)\n- previous_obs : Index of the previous observation in the full dataset,\n if -1 there are no previous observation (the segment starts)\n- next_obs : Index of the next observation in the full dataset, if -1 there are no next observation (the segment ends)\n- previous_cost : Result of the cost function (1 is a good association, 0 is bad) with previous observation\n- next_cost : Result of the cost function (1 is a good association, 0 is bad) with next observation\n\n" + "## Networks\nNetwork files use some specific fields :\n\n- track : ID of network (ID 0 correspond to lonely eddies)\n- segment : ID of a segment within a network (from 1 to N)\n- previous_obs : Index of the previous observation in the full dataset,\n if -1 there are no previous observation (the segment starts)\n- next_obs : Index of the next observation in the full dataset, if -1 there are no next observation (the segment ends)\n- previous_cost : Result of the cost function (1 is a good association, 0 is bad) with previous observation\n- next_cost : Result of the cost function (1 is a good association, 0 is bad) with next observation\n\n" ] }, { diff --git a/notebooks/python_module/16_network/pet_atlas.ipynb b/notebooks/python_module/16_network/pet_atlas.ipynb index 59a84a6f..c53e4b23 100644 --- a/notebooks/python_module/16_network/pet_atlas.ipynb +++ b/notebooks/python_module/16_network/pet_atlas.ipynb @@ -62,7 +62,7 @@ }, "outputs": [], "source": [ - "def start_axes(title):\n fig = plt.figure(figsize=(13, 5))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=\"full_axes\")\n ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid()\n ax.update_env()\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" + "def start_axes(title):\n fig = plt.figure(figsize=(13, 5))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=\"full_axes\")\n ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid()\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" ] }, { diff --git a/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb b/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb index 3cb3e6b6..7019b1fa 100644 --- a/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb +++ b/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb @@ -37,7 +37,7 @@ }, "outputs": [], "source": [ - "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)\n\n\n@FuncFormatter\ndef formatter(x, pos):\n return (timedelta(x) + datetime(1950, 1, 1)).strftime(\"%d/%m/%Y\")\n\n\ndef start_axes(title=\"\"):\n fig = plt.figure(figsize=(13, 6))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=\"full_axes\")\n ax.set_xlim(19, 29), ax.set_ylim(31, 35.5)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n ax.update_env()\n return ax\n\n\ndef timeline_axes(title=\"\"):\n fig = plt.figure(figsize=(15, 5))\n ax = fig.add_axes([0.03, 0.06, 0.90, 0.88])\n ax.set_title(title, weight=\"bold\")\n ax.xaxis.set_major_formatter(formatter), ax.grid()\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid(True)\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)\n\n\n@FuncFormatter\ndef formatter(x, pos):\n return (timedelta(x) + datetime(1950, 1, 1)).strftime(\"%d/%m/%Y\")\n\n\ndef start_axes(title=\"\"):\n fig = plt.figure(figsize=(13, 6))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=\"full_axes\")\n ax.set_xlim(19, 29), ax.set_ylim(31, 35.5)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n return ax\n\n\ndef timeline_axes(title=\"\"):\n fig = plt.figure(figsize=(15, 5))\n ax = fig.add_axes([0.03, 0.06, 0.90, 0.88])\n ax.set_title(title, weight=\"bold\")\n ax.xaxis.set_major_formatter(formatter), ax.grid()\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid(True)\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" ] }, { @@ -127,7 +127,7 @@ }, "outputs": [], "source": [ - "a = Anim(\n close_to_i3,\n figsize=(12, 4),\n cmap=colors.ListedColormap(\n list(close_to_i3.COLORS), name=\"from_list\", N=close_to_i3.segment.max() + 1\n ),\n nb_step=7,\n dpi=70,\n field_color=\"segment\",\n field_txt=\"segment\",\n)\na.ax.set_xlim(19, 30), a.ax.set_ylim(32, 35.25)\na.ax.update_env()\na.txt.set_position((21.5, 32.7))\n# We display in video only from the 100th day to the 500th\nkwargs = dict(frames=arange(*a.period)[100:501], interval=100)\nani = VideoAnimation(a.fig, a.func_animation, **kwargs)" + "a = Anim(\n close_to_i3,\n figsize=(12, 4),\n cmap=colors.ListedColormap(\n list(close_to_i3.COLORS), name=\"from_list\", N=close_to_i3.segment.max() + 1\n ),\n nb_step=7,\n dpi=70,\n field_color=\"segment\",\n field_txt=\"segment\",\n)\na.ax.set_xlim(19, 30), a.ax.set_ylim(32, 35.25)\na.txt.set_position((21.5, 32.7))\n# We display in video only from the 100th day to the 500th\nkwargs = dict(frames=arange(*a.period)[100:501], interval=100)\nani = VideoAnimation(a.fig, a.func_animation, **kwargs)" ] }, { diff --git a/notebooks/python_module/16_network/pet_replay_segmentation.ipynb b/notebooks/python_module/16_network/pet_replay_segmentation.ipynb index 5715f6e3..01ddbcfc 100644 --- a/notebooks/python_module/16_network/pet_replay_segmentation.ipynb +++ b/notebooks/python_module/16_network/pet_replay_segmentation.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "from datetime import datetime, timedelta\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.ticker import FuncFormatter\nfrom numpy import where\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations\n\n\n@FuncFormatter\ndef formatter(x, pos):\n return (timedelta(x) + datetime(1950, 1, 1)).strftime(\"%d/%m/%Y\")\n\n\ndef start_axes(title=\"\"):\n fig = plt.figure(figsize=(13, 6))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=\"full_axes\")\n ax.set_xlim(19, 29), ax.set_ylim(31, 35.5)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n ax.update_env()\n return ax\n\n\ndef timeline_axes(title=\"\"):\n fig = plt.figure(figsize=(15, 5))\n ax = fig.add_axes([0.04, 0.06, 0.89, 0.88])\n ax.set_title(title, weight=\"bold\")\n ax.xaxis.set_major_formatter(formatter), ax.grid()\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid(True)\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" + "from datetime import datetime, timedelta\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.ticker import FuncFormatter\nfrom numpy import where\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations\n\n\n@FuncFormatter\ndef formatter(x, pos):\n return (timedelta(x) + datetime(1950, 1, 1)).strftime(\"%d/%m/%Y\")\n\n\ndef start_axes(title=\"\"):\n fig = plt.figure(figsize=(13, 6))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=\"full_axes\")\n ax.set_xlim(19, 29), ax.set_ylim(31, 35.5)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n return ax\n\n\ndef timeline_axes(title=\"\"):\n fig = plt.figure(figsize=(15, 5))\n ax = fig.add_axes([0.04, 0.06, 0.89, 0.88])\n ax.set_title(title, weight=\"bold\")\n ax.xaxis.set_major_formatter(formatter), ax.grid()\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid(True)\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" ] }, { From 8d1b95e7e3e680043630111ea7b3ca8ad5685c08 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Tue, 16 Mar 2021 10:31:04 +0100 Subject: [PATCH 105/249] update example to get thumbnail --- examples/16_network/pet_group_anim.py | 19 ++++++++++-------- examples/16_network/pet_segmentation_anim.py | 8 ++++++++ .../16_network/pet_group_anim.ipynb | 20 ++++++++++++++++++- .../16_network/pet_segmentation_anim.ipynb | 18 +++++++++++++++++ 4 files changed, 56 insertions(+), 9 deletions(-) diff --git a/examples/16_network/pet_group_anim.py b/examples/16_network/pet_group_anim.py index 581898d8..51b2bba3 100644 --- a/examples/16_network/pet_group_anim.py +++ b/examples/16_network/pet_group_anim.py @@ -135,16 +135,19 @@ def update(frame): fig = plt.figure(figsize=(16, 9), dpi=50) ax = fig.add_axes([0, 0, 1, 1]) ax.set_aspect("equal"), ax.grid(), ax.set_xlim(26, 34), ax.set_ylim(31, 35.5) -groups = ax.scatter( - e.lon, - e.lat, - c=NETWORK_GROUPS[0][2], - cmap=ListedColormap(["gray", *e.COLORS[:-1]], name="from_list", N=30), - vmin=0, - vmax=30, -) +cmap = ListedColormap(["gray", *e.COLORS[:-1]], name="from_list", N=30) +kw_s = dict(cmap=cmap, vmin=0, vmax=30) +groups = ax.scatter(e.lon, e.lat, c=NETWORK_GROUPS[0][2], **kw_s) current_contour = ax.plot([], [], "k", lw=2, label="Current contour")[0] matched_contour = ax.plot([], [], "r", lw=1, ls="--", label="Candidate contour")[0] txt = ax.text(29, 35, "", fontsize=25) ax.legend(fontsize=25) ani = VideoAnimation(fig, update, frames=len(NETWORK_GROUPS), interval=220) + +# %% +# Final Result +# ----------- +fig = plt.figure(figsize=(16, 9)) +ax = fig.add_axes([0, 0, 1, 1]) +ax.set_aspect("equal"), ax.grid(), ax.set_xlim(26, 34), ax.set_ylim(31, 35.5) +_ = ax.scatter(e.lon, e.lat, c=NETWORK_GROUPS[-1][2], **kw_s) diff --git a/examples/16_network/pet_segmentation_anim.py b/examples/16_network/pet_segmentation_anim.py index 652c6b4e..15d11c63 100644 --- a/examples/16_network/pet_segmentation_anim.py +++ b/examples/16_network/pet_segmentation_anim.py @@ -116,3 +116,11 @@ def update(i_frame): e.contour_lon_e[INDICES[0]], e.contour_lat_e[INDICES[0]], color=cmap.colors[0] )[0] ani = VideoAnimation(fig, update, frames=range(1, len(TRACKS), 4), interval=125) + +# %% +# Final Result +# ----------- +fig = plt.figure(figsize=(16, 9)) +ax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection="full_axes") +ax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid() +_ = ax.scatter(e.lon, e.lat, c=TRACKS[-1], cmap=cmap, vmin=0, vmax=vmax, s=20) diff --git a/notebooks/python_module/16_network/pet_group_anim.ipynb b/notebooks/python_module/16_network/pet_group_anim.ipynb index 1400da0e..a4038302 100644 --- a/notebooks/python_module/16_network/pet_group_anim.ipynb +++ b/notebooks/python_module/16_network/pet_group_anim.ipynb @@ -167,7 +167,25 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(16, 9), dpi=50)\nax = fig.add_axes([0, 0, 1, 1])\nax.set_aspect(\"equal\"), ax.grid(), ax.set_xlim(26, 34), ax.set_ylim(31, 35.5)\ngroups = ax.scatter(\n e.lon,\n e.lat,\n c=NETWORK_GROUPS[0][2],\n cmap=ListedColormap([\"gray\", *e.COLORS[:-1]], name=\"from_list\", N=30),\n vmin=0,\n vmax=30,\n)\ncurrent_contour = ax.plot([], [], \"k\", lw=2, label=\"Current contour\")[0]\nmatched_contour = ax.plot([], [], \"r\", lw=1, ls=\"--\", label=\"Candidate contour\")[0]\ntxt = ax.text(29, 35, \"\", fontsize=25)\nax.legend(fontsize=25)\nani = VideoAnimation(fig, update, frames=len(NETWORK_GROUPS), interval=220)" + "fig = plt.figure(figsize=(16, 9), dpi=50)\nax = fig.add_axes([0, 0, 1, 1])\nax.set_aspect(\"equal\"), ax.grid(), ax.set_xlim(26, 34), ax.set_ylim(31, 35.5)\ncmap = ListedColormap([\"gray\", *e.COLORS[:-1]], name=\"from_list\", N=30)\nkw_s = dict(cmap=cmap, vmin=0, vmax=30)\ngroups = ax.scatter(e.lon, e.lat, c=NETWORK_GROUPS[0][2], **kw_s)\ncurrent_contour = ax.plot([], [], \"k\", lw=2, label=\"Current contour\")[0]\nmatched_contour = ax.plot([], [], \"r\", lw=1, ls=\"--\", label=\"Candidate contour\")[0]\ntxt = ax.text(29, 35, \"\", fontsize=25)\nax.legend(fontsize=25)\nani = VideoAnimation(fig, update, frames=len(NETWORK_GROUPS), interval=220)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Final Result\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(16, 9))\nax = fig.add_axes([0, 0, 1, 1])\nax.set_aspect(\"equal\"), ax.grid(), ax.set_xlim(26, 34), ax.set_ylim(31, 35.5)\n_ = ax.scatter(e.lon, e.lat, c=NETWORK_GROUPS[-1][2], **kw_s)" ] } ], diff --git a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb index 443a1a8f..a0479a2a 100644 --- a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb +++ b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb @@ -111,6 +111,24 @@ "source": [ "def update(i_frame):\n tr = TRACKS[i_frame]\n mappable_tracks.set_array(tr)\n s = 40 * ones(tr.shape)\n s[tr == 0] = 4\n mappable_tracks.set_sizes(s)\n\n indices_frames = INDICES[i_frame]\n mappable_CONTOUR.set_data(\n e.contour_lon_e[indices_frames],\n e.contour_lat_e[indices_frames],\n )\n mappable_CONTOUR.set_color(cmap.colors[tr[indices_frames] % len(cmap.colors)])\n return (mappable_tracks,)\n\n\nfig = plt.figure(figsize=(16, 9), dpi=60)\nax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=\"full_axes\")\nax.set_title(f\"{len(e)} observations to segment\")\nax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid()\nvmax = TRACKS[-1].max()\ncmap = ListedColormap([\"gray\", *e.COLORS[:-1]], name=\"from_list\", N=vmax)\nmappable_tracks = ax.scatter(\n e.lon, e.lat, c=TRACKS[0], cmap=cmap, vmin=0, vmax=vmax, s=20\n)\nmappable_CONTOUR = ax.plot(\n e.contour_lon_e[INDICES[0]], e.contour_lat_e[INDICES[0]], color=cmap.colors[0]\n)[0]\nani = VideoAnimation(fig, update, frames=range(1, len(TRACKS), 4), interval=125)" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Final Result\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(16, 9))\nax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=\"full_axes\")\nax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid()\n_ = ax.scatter(e.lon, e.lat, c=TRACKS[-1], cmap=cmap, vmin=0, vmax=vmax, s=20)" + ] } ], "metadata": { From 9e1265c539610652b1f4012e3eb94325a88e9b31 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Tue, 16 Mar 2021 14:29:41 +0100 Subject: [PATCH 106/249] change thumbnail --- examples/16_network/pet_group_anim.py | 2 +- notebooks/python_module/16_network/pet_group_anim.ipynb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/16_network/pet_group_anim.py b/examples/16_network/pet_group_anim.py index 51b2bba3..09ab4954 100644 --- a/examples/16_network/pet_group_anim.py +++ b/examples/16_network/pet_group_anim.py @@ -2,7 +2,7 @@ Network group process ===================== """ - +# sphinx_gallery_thumbnail_number = 2 import re from datetime import datetime diff --git a/notebooks/python_module/16_network/pet_group_anim.ipynb b/notebooks/python_module/16_network/pet_group_anim.ipynb index a4038302..6983bd21 100644 --- a/notebooks/python_module/16_network/pet_group_anim.ipynb +++ b/notebooks/python_module/16_network/pet_group_anim.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import re\nfrom datetime import datetime\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.colors import ListedColormap\nfrom numba import njit\nfrom numpy import arange, array, empty, ones\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.generic import flatten_line_matrix\nfrom py_eddy_tracker.observations.network import Network\nfrom py_eddy_tracker.observations.observation import EddiesObservations" + "# sphinx_gallery_thumbnail_number = 2\nimport re\nfrom datetime import datetime\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.colors import ListedColormap\nfrom numba import njit\nfrom numpy import arange, array, empty, ones\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.generic import flatten_line_matrix\nfrom py_eddy_tracker.observations.network import Network\nfrom py_eddy_tracker.observations.observation import EddiesObservations" ] }, { From 827fda3249c1efa77f88634255d6213987f12275 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Tue, 16 Mar 2021 15:01:02 +0100 Subject: [PATCH 107/249] Correct thumbnail --- examples/16_network/pet_group_anim.py | 3 ++- examples/16_network/pet_segmentation_anim.py | 2 ++ notebooks/python_module/16_network/pet_group_anim.ipynb | 4 ++-- .../python_module/16_network/pet_segmentation_anim.ipynb | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/examples/16_network/pet_group_anim.py b/examples/16_network/pet_group_anim.py index 09ab4954..7ddf1bb0 100644 --- a/examples/16_network/pet_group_anim.py +++ b/examples/16_network/pet_group_anim.py @@ -2,7 +2,6 @@ Network group process ===================== """ -# sphinx_gallery_thumbnail_number = 2 import re from datetime import datetime @@ -147,6 +146,8 @@ def update(frame): # %% # Final Result # ----------- + +# sphinx_gallery_thumbnail_number = 2 fig = plt.figure(figsize=(16, 9)) ax = fig.add_axes([0, 0, 1, 1]) ax.set_aspect("equal"), ax.grid(), ax.set_xlim(26, 34), ax.set_ylim(31, 35.5) diff --git a/examples/16_network/pet_segmentation_anim.py b/examples/16_network/pet_segmentation_anim.py index 15d11c63..94393435 100644 --- a/examples/16_network/pet_segmentation_anim.py +++ b/examples/16_network/pet_segmentation_anim.py @@ -120,6 +120,8 @@ def update(i_frame): # %% # Final Result # ----------- + +# sphinx_gallery_thumbnail_number = 2 fig = plt.figure(figsize=(16, 9)) ax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection="full_axes") ax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid() diff --git a/notebooks/python_module/16_network/pet_group_anim.ipynb b/notebooks/python_module/16_network/pet_group_anim.ipynb index 6983bd21..1edcf5d8 100644 --- a/notebooks/python_module/16_network/pet_group_anim.ipynb +++ b/notebooks/python_module/16_network/pet_group_anim.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "# sphinx_gallery_thumbnail_number = 2\nimport re\nfrom datetime import datetime\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.colors import ListedColormap\nfrom numba import njit\nfrom numpy import arange, array, empty, ones\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.generic import flatten_line_matrix\nfrom py_eddy_tracker.observations.network import Network\nfrom py_eddy_tracker.observations.observation import EddiesObservations" + "import re\nfrom datetime import datetime\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.colors import ListedColormap\nfrom numba import njit\nfrom numpy import arange, array, empty, ones\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.generic import flatten_line_matrix\nfrom py_eddy_tracker.observations.network import Network\nfrom py_eddy_tracker.observations.observation import EddiesObservations" ] }, { @@ -185,7 +185,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(16, 9))\nax = fig.add_axes([0, 0, 1, 1])\nax.set_aspect(\"equal\"), ax.grid(), ax.set_xlim(26, 34), ax.set_ylim(31, 35.5)\n_ = ax.scatter(e.lon, e.lat, c=NETWORK_GROUPS[-1][2], **kw_s)" + "# sphinx_gallery_thumbnail_number = 2\nfig = plt.figure(figsize=(16, 9))\nax = fig.add_axes([0, 0, 1, 1])\nax.set_aspect(\"equal\"), ax.grid(), ax.set_xlim(26, 34), ax.set_ylim(31, 35.5)\n_ = ax.scatter(e.lon, e.lat, c=NETWORK_GROUPS[-1][2], **kw_s)" ] } ], diff --git a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb index a0479a2a..7a82a590 100644 --- a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb +++ b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb @@ -127,7 +127,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(16, 9))\nax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=\"full_axes\")\nax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid()\n_ = ax.scatter(e.lon, e.lat, c=TRACKS[-1], cmap=cmap, vmin=0, vmax=vmax, s=20)" + "# sphinx_gallery_thumbnail_number = 2\nfig = plt.figure(figsize=(16, 9))\nax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=\"full_axes\")\nax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid()\n_ = ax.scatter(e.lon, e.lat, c=TRACKS[-1], cmap=cmap, vmin=0, vmax=vmax, s=20)" ] } ], From b85fbf3aada06481e663f5b55795a1da1b4d0c91 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Tue, 16 Mar 2021 15:39:27 +0100 Subject: [PATCH 108/249] Use video instead jshtml for eddy animation --- .../pet_track_anim_matplotlib_animation.py | 32 ++++++++++++++++--- .../pet_track_anim_matplotlib_animation.ipynb | 15 +++++++-- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py b/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py index 3fb04450..9bf27382 100644 --- a/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py +++ b/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py @@ -5,6 +5,8 @@ Run in a terminal this script, which allow to watch eddy evolution """ +import re + import py_eddy_tracker_sample from matplotlib.animation import FuncAnimation from numpy import arange @@ -12,6 +14,28 @@ from py_eddy_tracker.appli.gui import Anim from py_eddy_tracker.observations.tracking import TrackEddiesObservations +# sphinx_gallery_thumbnail_path = '_static/no_image.png' + + +# %% +class VideoAnimation(FuncAnimation): + def _repr_html_(self, *args, **kwargs): + """To get video in html and have a player""" + 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) + + # %% # Load experimental atlas, and we select one eddy a = TrackEddiesObservations.load_file( @@ -21,14 +45,12 @@ # %% # Run animation -a = Anim(eddy, intern=True, figsize=(8, 3.5), cmap="magma_r", nb_step=6) +a = Anim(eddy, intern=True, figsize=(8, 3.5), cmap="magma_r", nb_step=5, dpi=50) a.txt.set_position((17, 34.6)) a.ax.set_xlim(16.5, 23) a.ax.set_ylim(34.5, 37) # arguments to get full animation -# kwargs = dict(frames=arange(*a.period), interval=50) -# arguments to reduce compute cost for doucmentation, we display only every 10 days -kwargs = dict(frames=arange(*a.period)[200:800:10], save_count=60, interval=200) +kwargs = dict(frames=arange(*a.period)[300:800], interval=90) -ani = FuncAnimation(a.fig, a.func_animation, **kwargs) +ani = VideoAnimation(a.fig, a.func_animation, **kwargs) diff --git a/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb index 259980a1..17668aed 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb @@ -26,7 +26,18 @@ }, "outputs": [], "source": [ - "import py_eddy_tracker_sample\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange\n\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations" + "import re\n\nimport py_eddy_tracker_sample\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange\n\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations\n# sphinx_gallery_thumbnail_path = '_static/no_image.png'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" ] }, { @@ -62,7 +73,7 @@ }, "outputs": [], "source": [ - "a = Anim(eddy, intern=True, figsize=(8, 3.5), cmap=\"magma_r\", nb_step=6)\na.txt.set_position((17, 34.6))\na.ax.set_xlim(16.5, 23)\na.ax.set_ylim(34.5, 37)\n\n# arguments to get full animation\n# kwargs = dict(frames=arange(*a.period), interval=50)\n# arguments to reduce compute cost for doucmentation, we display only every 10 days\nkwargs = dict(frames=arange(*a.period)[200:800:10], save_count=60, interval=200)\n\nani = FuncAnimation(a.fig, a.func_animation, **kwargs)" + "a = Anim(eddy, intern=True, figsize=(8, 3.5), cmap=\"magma_r\", nb_step=5, dpi=50)\na.txt.set_position((17, 34.6))\na.ax.set_xlim(16.5, 23)\na.ax.set_ylim(34.5, 37)\n\n# arguments to get full animation\n# arguments to reduce compute cost for doucmentation, we display only every 10 days\nkwargs = dict(frames=arange(*a.period)[300:800], interval=90)\n\nani = VideoAnimation(a.fig, a.func_animation, **kwargs)" ] } ], From 1bc768fb2f630b2b97a45c65c2c0d4b366ab7adb Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Wed, 17 Mar 2021 10:18:00 +0100 Subject: [PATCH 109/249] Management of grid bound in advection --- examples/06_grid_manipulation/pet_advect.py | 32 +- examples/07_cube_manipulation/pet_cube.py | 151 ++++++++ examples/07_cube_manipulation/pet_fsle_med.py | 1 + examples/16_network/pet_group_anim.py | 3 +- examples/16_network/pet_segmentation_anim.py | 4 +- .../06_grid_manipulation/pet_advect.ipynb | 20 +- .../07_cube_manipulation/pet_cube.ipynb | 166 +++++++++ .../07_cube_manipulation/pet_fsle_med.ipynb | 2 +- .../16_network/pet_group_anim.ipynb | 4 +- .../16_network/pet_segmentation_anim.ipynb | 4 +- src/py_eddy_tracker/dataset/grid.py | 345 +++++++++++------- 11 files changed, 562 insertions(+), 170 deletions(-) create mode 100644 examples/07_cube_manipulation/pet_cube.py create mode 100644 notebooks/python_module/07_cube_manipulation/pet_cube.ipynb diff --git a/examples/06_grid_manipulation/pet_advect.py b/examples/06_grid_manipulation/pet_advect.py index a1df860f..7c7f0959 100644 --- a/examples/06_grid_manipulation/pet_advect.py +++ b/examples/06_grid_manipulation/pet_advect.py @@ -2,7 +2,7 @@ Grid advection ============== -Dummy advection which use only static geostrophic current, which didn't resolve the complex circulation of the ocean. +Dummy advection which use only static geostrophic current, which didn't solve the complex circulation of the ocean. """ import re @@ -11,22 +11,22 @@ from numpy import arange, isnan, meshgrid, ones import py_eddy_tracker.gui -from py_eddy_tracker import data +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 is used to detect eddies +# Load Input grid ADT g = RegularGridDataset( - data.get_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), "longitude", "latitude" + 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")) +a = EddiesObservations.load_file(get_path("Anticyclonic_20160515.nc")) +c = EddiesObservations.load_file(get_path("Cyclonic_20160515.nc")) # %% @@ -78,15 +78,15 @@ def save(self, *args, **kwargs): # %% -# Method +# Function def anim_ax(**kw): t = 0 fig = plt.figure(figsize=(10, 5), dpi=55) - ax = fig.add_axes([0, 0, 1, 1], projection="full_axes") - ax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid() - a.filled(ax, facecolors="r", alpha=0.1), c.filled(ax, facecolors="b", alpha=0.1) - line = ax.plot([], [], "k", **kw)[0] - return fig, ax.text(21, 32.1, ""), line, t + axes = fig.add_axes([0, 0, 1, 1], projection="full_axes") + axes.set_xlim(19, 30), axes.set_ylim(31, 36.5), axes.grid() + a.filled(axes, facecolors="r", alpha=0.1), c.filled(axes, facecolors="b", alpha=0.1) + line = axes.plot([], [], "k", **kw)[0] + return fig, axes.text(21, 32.1, ""), line, t def update(i_frame, t_step): @@ -127,11 +127,10 @@ def update(i_frame, t_step): # %% # Time_step settings # ^^^^^^^^^^^^^^^^^^ -# Dummy experiment to test advection precision, we run particles 50 days forward and backward ad different time step +# Dummy experiment to test advection precision, we run particles 50 days forward and backward with different time step # and we measure distance between new positions and original positions. fig = plt.figure() ax = fig.add_subplot(111) -ax.grid() kw = dict( bins=arange(0, 50, 0.001), cumulative=True, @@ -145,7 +144,7 @@ def update(i_frame, t_step): g.advect(x, y, "u", "v", **kw_advect, backward=True).__next__() d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5 ax.hist(d, **kw, label=f"{86400. / time_step:.0f} time step by day") -ax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc="lower right") +ax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc="lower right"), ax.grid() ax.set_title("Distance after 50 days forward and 50 days backward") ax.set_xlabel("Distance between original position and final position (in degrees)") _ = ax.set_ylabel("Percent of particles with distance lesser than") @@ -156,7 +155,6 @@ def update(i_frame, t_step): # We keep same time_step but change time duration fig = plt.figure() ax = fig.add_subplot(111) -ax.grid() time_step = 10800 for duration in (5, 50, 100): x, y = x0.copy(), y0.copy() @@ -165,7 +163,7 @@ def update(i_frame, t_step): g.advect(x, y, "u", "v", **kw_advect, backward=True).__next__() d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5 ax.hist(d, **kw, label=f"Time duration {duration} days") -ax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc="lower right") +ax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc="lower right"), ax.grid() ax.set_title( "Distance after N days forward and N days backward\nwith a time step of 1/8 days" ) diff --git a/examples/07_cube_manipulation/pet_cube.py b/examples/07_cube_manipulation/pet_cube.py new file mode 100644 index 00000000..50431f58 --- /dev/null +++ b/examples/07_cube_manipulation/pet_cube.py @@ -0,0 +1,151 @@ +""" +Time advection +============== + +Example which use CMEMS surface current with a Runge-Kutta 4 algorithm to advect particles. +""" +# sphinx_gallery_thumbnail_number = 2 +import re +from datetime import datetime, timedelta + +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 import start_logger +from py_eddy_tracker.data import get_path +from py_eddy_tracker.dataset.grid import GridCollection + +start_logger().setLevel("ERROR") + + +# %% +class VideoAnimation(FuncAnimation): + def _repr_html_(self, *args, **kwargs): + """To get video in html and have a player""" + 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) + + +# %% +# Data +# ---- +# Load Input time grid ADT +c = GridCollection.from_netcdf_cube( + get_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 +t0 = 20181 +m = ~isnan(c[t0].interp("u", x, y)) +x0, y0 = x[m], y[m] +x, y = x0.copy(), y0.copy() + + +# %% +# Function +def anim_ax(**kw): + fig = plt.figure(figsize=(10, 5), dpi=55) + axes = fig.add_axes([0, 0, 1, 1], projection="full_axes") + axes.set_xlim(19, 30), axes.set_ylim(31, 36.5), axes.grid() + line = axes.plot([], [], "k", **kw)[0] + return fig, axes.text(21, 32.1, ""), line + + +def update(_): + tt, xt, yt = f.__next__() + mappable.set_data(xt, yt) + d = timedelta(tt / 86400.0) + datetime(1950, 1, 1) + txt.set_text(f"{d:%Y/%m/%d-%H}") + + +# %% +f = c.filament(x, y, "u", "v", t_init=t0, nb_step=2, time_step=21600, filament_size=3) +fig, txt, mappable = anim_ax(lw=0.5) +ani = VideoAnimation(fig, update, frames=arange(160), interval=100) + + +# %% +# Particules stat +# --------------- +# Time_step settings +# ^^^^^^^^^^^^^^^^^^ +# Dummy experiment to test advection precision, we run particles 50 days forward and backward with different time step +# and we measure distance between new positions and original positions. +fig = plt.figure() +ax = fig.add_subplot(111) +kw = dict( + bins=arange(0, 50, 0.002), + cumulative=True, + weights=ones(x0.shape) / x0.shape[0] * 100.0, + histtype="step", +) +kw_p = dict(u_name="u", v_name="v", nb_step=1) +for time_step in (10800, 21600, 43200, 86400): + x, y = x0.copy(), y0.copy() + nb = int(30 * 86400 / time_step) + # Go forward + p = c.advect(x, y, time_step=time_step, t_init=20181.5, **kw_p) + for i in range(nb): + t_, _, _ = p.__next__() + # Go backward + p = c.advect(x, y, time_step=time_step, backward=True, t_init=t_ / 86400.0, **kw_p) + for i in range(nb): + t_, _, _ = p.__next__() + d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5 + ax.hist(d, **kw, label=f"{86400. / time_step:.0f} time step by day") +ax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc="lower right"), ax.grid() +ax.set_title("Distance after 50 days forward and 50 days backward") +ax.set_xlabel("Distance between original position and final position (in degrees)") +_ = ax.set_ylabel("Percent of particles with distance lesser than") + +# %% +# Time duration +# ^^^^^^^^^^^^^ +# We keep same time_step but change time duration +fig = plt.figure() +ax = fig.add_subplot(111) +time_step = 10800 +for duration in (10, 40, 80): + x, y = x0.copy(), y0.copy() + nb = int(duration * 86400 / time_step) + # Go forward + p = c.advect(x, y, time_step=time_step, t_init=20181.5, **kw_p) + for i in range(nb): + t_, _, _ = p.__next__() + # Go backward + p = c.advect(x, y, time_step=time_step, backward=True, t_init=t_ / 86400.0, **kw_p) + for i in range(nb): + t_, _, _ = p.__next__() + d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5 + ax.hist(d, **kw, label=f"Time duration {duration} days") +ax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc="lower right"), ax.grid() +ax.set_title( + "Distance after N days forward and N days backward\nwith a time step of 1/8 days" +) +ax.set_xlabel("Distance between original position and final position (in degrees)") +_ = ax.set_ylabel("Percent of particles with distance lesser than ") diff --git a/examples/07_cube_manipulation/pet_fsle_med.py b/examples/07_cube_manipulation/pet_fsle_med.py index 49b44144..3857bb5a 100644 --- a/examples/07_cube_manipulation/pet_fsle_med.py +++ b/examples/07_cube_manipulation/pet_fsle_med.py @@ -31,6 +31,7 @@ "longitude", "latitude", "time", + # To create U/V variable heigth="adt", ) diff --git a/examples/16_network/pet_group_anim.py b/examples/16_network/pet_group_anim.py index 7ddf1bb0..09ab4954 100644 --- a/examples/16_network/pet_group_anim.py +++ b/examples/16_network/pet_group_anim.py @@ -2,6 +2,7 @@ Network group process ===================== """ +# sphinx_gallery_thumbnail_number = 2 import re from datetime import datetime @@ -146,8 +147,6 @@ def update(frame): # %% # Final Result # ----------- - -# sphinx_gallery_thumbnail_number = 2 fig = plt.figure(figsize=(16, 9)) ax = fig.add_axes([0, 0, 1, 1]) ax.set_aspect("equal"), ax.grid(), ax.set_xlim(26, 34), ax.set_ylim(31, 35.5) diff --git a/examples/16_network/pet_segmentation_anim.py b/examples/16_network/pet_segmentation_anim.py index 94393435..74a94e3c 100644 --- a/examples/16_network/pet_segmentation_anim.py +++ b/examples/16_network/pet_segmentation_anim.py @@ -2,7 +2,7 @@ Network segmentation process ============================ """ - +# sphinx_gallery_thumbnail_number = 2 import re from matplotlib import pyplot as plt @@ -120,8 +120,6 @@ def update(i_frame): # %% # Final Result # ----------- - -# sphinx_gallery_thumbnail_number = 2 fig = plt.figure(figsize=(16, 9)) ax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection="full_axes") ax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid() diff --git a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb index 34a72c94..5de7c46a 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# Grid advection\n\nDummy advection which use only static geostrophic current, which didn't resolve the complex circulation of the ocean.\n" + "\n# Grid advection\n\nDummy advection which use only static geostrophic current, which didn't solve the complex circulation of the ocean.\n" ] }, { @@ -26,14 +26,14 @@ }, "outputs": [], "source": [ - "import re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, isnan, meshgrid, ones\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\nfrom py_eddy_tracker.observations.observation import EddiesObservations" + "import re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, isnan, meshgrid, ones\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\nfrom py_eddy_tracker.observations.observation import EddiesObservations" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Load Input grid, ADT is used to detect eddies\n\n" + "Load Input grid ADT\n\n" ] }, { @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "g = RegularGridDataset(\n data.get_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\n# Compute u/v from height\ng.add_uv(\"adt\")" + "g = RegularGridDataset(\n get_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\n# Compute u/v from height\ng.add_uv(\"adt\")" ] }, { @@ -62,7 +62,7 @@ }, "outputs": [], "source": [ - "a = EddiesObservations.load_file(data.get_path(\"Anticyclonic_20160515.nc\"))\nc = EddiesObservations.load_file(data.get_path(\"Cyclonic_20160515.nc\"))" + "a = EddiesObservations.load_file(get_path(\"Anticyclonic_20160515.nc\"))\nc = EddiesObservations.load_file(get_path(\"Cyclonic_20160515.nc\"))" ] }, { @@ -134,7 +134,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Method\n\n" + "Function\n\n" ] }, { @@ -145,7 +145,7 @@ }, "outputs": [], "source": [ - "def anim_ax(**kw):\n t = 0\n fig = plt.figure(figsize=(10, 5), dpi=55)\n ax = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\n ax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid()\n a.filled(ax, facecolors=\"r\", alpha=0.1), c.filled(ax, facecolors=\"b\", alpha=0.1)\n line = ax.plot([], [], \"k\", **kw)[0]\n return fig, ax.text(21, 32.1, \"\"), line, t\n\n\ndef update(i_frame, t_step):\n global t\n x, y = p.__next__()\n t += t_step\n l.set_data(x, y)\n txt.set_text(f\"T0 + {t:.1f} days\")" + "def anim_ax(**kw):\n t = 0\n fig = plt.figure(figsize=(10, 5), dpi=55)\n axes = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\n axes.set_xlim(19, 30), axes.set_ylim(31, 36.5), axes.grid()\n a.filled(axes, facecolors=\"r\", alpha=0.1), c.filled(axes, facecolors=\"b\", alpha=0.1)\n line = axes.plot([], [], \"k\", **kw)[0]\n return fig, axes.text(21, 32.1, \"\"), line, t\n\n\ndef update(i_frame, t_step):\n global t\n x, y = p.__next__()\n t += t_step\n l.set_data(x, y)\n txt.set_text(f\"T0 + {t:.1f} days\")" ] }, { @@ -213,7 +213,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Time_step settings\nDummy experiment to test advection precision, we run particles 50 days forward and backward ad different time step\nand we measure distance between new positions and original positions.\n\n" + "### Time_step settings\nDummy experiment to test advection precision, we run particles 50 days forward and backward with different time step\nand we measure distance between new positions and original positions.\n\n" ] }, { @@ -224,7 +224,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure()\nax = fig.add_subplot(111)\nax.grid()\nkw = dict(\n bins=arange(0, 50, 0.001),\n cumulative=True,\n weights=ones(x0.shape) / x0.shape[0] * 100.0,\n histtype=\"step\",\n)\nfor time_step in (10800, 21600, 43200, 86400):\n x, y = x0.copy(), y0.copy()\n kw_advect = dict(nb_step=int(50 * 86400 / time_step), time_step=time_step)\n g.advect(x, y, \"u\", \"v\", **kw_advect).__next__()\n g.advect(x, y, \"u\", \"v\", **kw_advect, backward=True).__next__()\n d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5\n ax.hist(d, **kw, label=f\"{86400. / time_step:.0f} time step by day\")\nax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc=\"lower right\")\nax.set_title(\"Distance after 50 days forward and 50 days backward\")\nax.set_xlabel(\"Distance between original position and final position (in degrees)\")\n_ = ax.set_ylabel(\"Percent of particles with distance lesser than\")" + "fig = plt.figure()\nax = fig.add_subplot(111)\nkw = dict(\n bins=arange(0, 50, 0.001),\n cumulative=True,\n weights=ones(x0.shape) / x0.shape[0] * 100.0,\n histtype=\"step\",\n)\nfor time_step in (10800, 21600, 43200, 86400):\n x, y = x0.copy(), y0.copy()\n kw_advect = dict(nb_step=int(50 * 86400 / time_step), time_step=time_step)\n g.advect(x, y, \"u\", \"v\", **kw_advect).__next__()\n g.advect(x, y, \"u\", \"v\", **kw_advect, backward=True).__next__()\n d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5\n ax.hist(d, **kw, label=f\"{86400. / time_step:.0f} time step by day\")\nax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc=\"lower right\"), ax.grid()\nax.set_title(\"Distance after 50 days forward and 50 days backward\")\nax.set_xlabel(\"Distance between original position and final position (in degrees)\")\n_ = ax.set_ylabel(\"Percent of particles with distance lesser than\")" ] }, { @@ -242,7 +242,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure()\nax = fig.add_subplot(111)\nax.grid()\ntime_step = 10800\nfor duration in (5, 50, 100):\n x, y = x0.copy(), y0.copy()\n kw_advect = dict(nb_step=int(duration * 86400 / time_step), time_step=time_step)\n g.advect(x, y, \"u\", \"v\", **kw_advect).__next__()\n g.advect(x, y, \"u\", \"v\", **kw_advect, backward=True).__next__()\n d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5\n ax.hist(d, **kw, label=f\"Time duration {duration} days\")\nax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc=\"lower right\")\nax.set_title(\n \"Distance after N days forward and N days backward\\nwith a time step of 1/8 days\"\n)\nax.set_xlabel(\"Distance between original position and final position (in degrees)\")\n_ = ax.set_ylabel(\"Percent of particles with distance lesser than \")" + "fig = plt.figure()\nax = fig.add_subplot(111)\ntime_step = 10800\nfor duration in (5, 50, 100):\n x, y = x0.copy(), y0.copy()\n kw_advect = dict(nb_step=int(duration * 86400 / time_step), time_step=time_step)\n g.advect(x, y, \"u\", \"v\", **kw_advect).__next__()\n g.advect(x, y, \"u\", \"v\", **kw_advect, backward=True).__next__()\n d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5\n ax.hist(d, **kw, label=f\"Time duration {duration} days\")\nax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc=\"lower right\"), ax.grid()\nax.set_title(\n \"Distance after N days forward and N days backward\\nwith a time step of 1/8 days\"\n)\nax.set_xlabel(\"Distance between original position and final position (in degrees)\")\n_ = ax.set_ylabel(\"Percent of particles with distance lesser than \")" ] } ], diff --git a/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb b/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb new file mode 100644 index 00000000..aa9ad093 --- /dev/null +++ b/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb @@ -0,0 +1,166 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Time advection\n\nExample which use CMEMS surface current with a Runge-Kutta 4 algorithm to advect particles.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# sphinx_gallery_thumbnail_number = 2\nimport re\nfrom datetime import datetime, timedelta\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, isnan, meshgrid, ones\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.dataset.grid import GridCollection\n\nstart_logger().setLevel(\"ERROR\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Data\nLoad Input time grid ADT\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "c = GridCollection.from_netcdf_cube(\n get_path(\"dt_med_allsat_phy_l4_2005T2.nc\"),\n \"longitude\",\n \"latitude\",\n \"time\",\n # To create U/V variable\n heigth=\"adt\",\n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Anim\nParticles setup\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "step_p = 1 / 8\nx, y = meshgrid(arange(13, 36, step_p), arange(28, 40, step_p))\nx, y = x.reshape(-1), y.reshape(-1)\n# Remove all original position that we can't advect at first place\nt0 = 20181\nm = ~isnan(c[t0].interp(\"u\", x, y))\nx0, y0 = x[m], y[m]\nx, y = x0.copy(), y0.copy()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Function\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def anim_ax(**kw):\n fig = plt.figure(figsize=(10, 5), dpi=55)\n axes = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\n axes.set_xlim(19, 30), axes.set_ylim(31, 36.5), axes.grid()\n line = axes.plot([], [], \"k\", **kw)[0]\n return fig, axes.text(21, 32.1, \"\"), line\n\n\ndef update(_):\n tt, xt, yt = f.__next__()\n mappable.set_data(xt, yt)\n d = timedelta(tt / 86400.0) + datetime(1950, 1, 1)\n txt.set_text(f\"{d:%Y/%m/%d-%H}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "f = c.filament(x, y, \"u\", \"v\", t_init=t0, nb_step=2, time_step=21600, filament_size=3)\nfig, txt, mappable = anim_ax(lw=0.5)\nani = VideoAnimation(fig, update, frames=arange(160), interval=100)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Particules stat\nTime_step settings\n^^^^^^^^^^^^^^^^^^\nDummy experiment to test advection precision, we run particles 50 days forward and backward with different time step\nand we measure distance between new positions and original positions.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure()\nax = fig.add_subplot(111)\nkw = dict(\n bins=arange(0, 50, 0.002),\n cumulative=True,\n weights=ones(x0.shape) / x0.shape[0] * 100.0,\n histtype=\"step\",\n)\nkw_p = dict(u_name=\"u\", v_name=\"v\", nb_step=1)\nfor time_step in (10800, 21600, 43200, 86400):\n x, y = x0.copy(), y0.copy()\n nb = int(30 * 86400 / time_step)\n # Go forward\n p = c.advect(x, y, time_step=time_step, t_init=20181.5, **kw_p)\n for i in range(nb):\n t_, _, _ = p.__next__()\n # Go backward\n p = c.advect(x, y, time_step=time_step, backward=True, t_init=t_ / 86400.0, **kw_p)\n for i in range(nb):\n t_, _, _ = p.__next__()\n d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5\n ax.hist(d, **kw, label=f\"{86400. / time_step:.0f} time step by day\")\nax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc=\"lower right\"), ax.grid()\nax.set_title(\"Distance after 50 days forward and 50 days backward\")\nax.set_xlabel(\"Distance between original position and final position (in degrees)\")\n_ = ax.set_ylabel(\"Percent of particles with distance lesser than\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Time duration\nWe keep same time_step but change time duration\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure()\nax = fig.add_subplot(111)\ntime_step = 10800\nfor duration in (10, 40, 80):\n x, y = x0.copy(), y0.copy()\n nb = int(duration * 86400 / time_step)\n # Go forward\n p = c.advect(x, y, time_step=time_step, t_init=20181.5, **kw_p)\n for i in range(nb):\n t_, _, _ = p.__next__()\n # Go backward\n p = c.advect(x, y, time_step=time_step, backward=True, t_init=t_ / 86400.0, **kw_p)\n for i in range(nb):\n t_, _, _ = p.__next__()\n d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5\n ax.hist(d, **kw, label=f\"Time duration {duration} days\")\nax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc=\"lower right\"), ax.grid()\nax.set_title(\n \"Distance after N days forward and N days backward\\nwith a time step of 1/8 days\"\n)\nax.set_xlabel(\"Distance between original position and final position (in degrees)\")\n_ = ax.set_ylabel(\"Percent of particles with distance lesser than \")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb index 09bb9df0..00477940 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "c = GridCollection.from_netcdf_cube(\n get_path(\"dt_med_allsat_phy_l4_2005T2.nc\"),\n \"longitude\",\n \"latitude\",\n \"time\",\n heigth=\"adt\",\n)" + "c = GridCollection.from_netcdf_cube(\n get_path(\"dt_med_allsat_phy_l4_2005T2.nc\"),\n \"longitude\",\n \"latitude\",\n \"time\",\n # To create U/V variable\n heigth=\"adt\",\n)" ] }, { diff --git a/notebooks/python_module/16_network/pet_group_anim.ipynb b/notebooks/python_module/16_network/pet_group_anim.ipynb index 1edcf5d8..6983bd21 100644 --- a/notebooks/python_module/16_network/pet_group_anim.ipynb +++ b/notebooks/python_module/16_network/pet_group_anim.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import re\nfrom datetime import datetime\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.colors import ListedColormap\nfrom numba import njit\nfrom numpy import arange, array, empty, ones\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.generic import flatten_line_matrix\nfrom py_eddy_tracker.observations.network import Network\nfrom py_eddy_tracker.observations.observation import EddiesObservations" + "# sphinx_gallery_thumbnail_number = 2\nimport re\nfrom datetime import datetime\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.colors import ListedColormap\nfrom numba import njit\nfrom numpy import arange, array, empty, ones\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.generic import flatten_line_matrix\nfrom py_eddy_tracker.observations.network import Network\nfrom py_eddy_tracker.observations.observation import EddiesObservations" ] }, { @@ -185,7 +185,7 @@ }, "outputs": [], "source": [ - "# sphinx_gallery_thumbnail_number = 2\nfig = plt.figure(figsize=(16, 9))\nax = fig.add_axes([0, 0, 1, 1])\nax.set_aspect(\"equal\"), ax.grid(), ax.set_xlim(26, 34), ax.set_ylim(31, 35.5)\n_ = ax.scatter(e.lon, e.lat, c=NETWORK_GROUPS[-1][2], **kw_s)" + "fig = plt.figure(figsize=(16, 9))\nax = fig.add_axes([0, 0, 1, 1])\nax.set_aspect(\"equal\"), ax.grid(), ax.set_xlim(26, 34), ax.set_ylim(31, 35.5)\n_ = ax.scatter(e.lon, e.lat, c=NETWORK_GROUPS[-1][2], **kw_s)" ] } ], diff --git a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb index 7a82a590..c7372f42 100644 --- a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb +++ b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.colors import ListedColormap\nfrom numpy import ones, where\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations" + "# sphinx_gallery_thumbnail_number = 2\nimport re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.colors import ListedColormap\nfrom numpy import ones, where\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations" ] }, { @@ -127,7 +127,7 @@ }, "outputs": [], "source": [ - "# sphinx_gallery_thumbnail_number = 2\nfig = plt.figure(figsize=(16, 9))\nax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=\"full_axes\")\nax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid()\n_ = ax.scatter(e.lon, e.lat, c=TRACKS[-1], cmap=cmap, vmin=0, vmax=vmax, s=20)" + "fig = plt.figure(figsize=(16, 9))\nax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=\"full_axes\")\nax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid()\n_ = ax.scatter(e.lon, e.lat, c=TRACKS[-1], cmap=cmap, vmin=0, vmax=vmax, s=20)" ] } ], diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 06cdfac1..cf20f340 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -1946,7 +1946,8 @@ def advect(self, x, y, u_name, v_name, nb_step=10, rk4=True, **kw): :param str,array u_name: U field to advect obs :param str,array v_name: V field to advect obs :param int nb_step: Number of iteration before to release data - :param int time_step: Number of second for each advection + + .. minigallery:: py_eddy_tracker.GridDataset.advect """ u, v, m = self.uv_for_advection(u_name, v_name, **kw) m_p = isnan(x) + isnan(y) @@ -1967,9 +1968,10 @@ def filament( :param str,array u_name: U field to advect obs :param str,array v_name: V field to advect obs :param int nb_step: Number of iteration before to release data - :param int time_step: Number of second for each advection :param int filament_size: Number of point by filament :return: x,y for a line + + .. minigallery:: py_eddy_tracker.GridDataset.filament """ u, v, m = self.uv_for_advection(u_name, v_name, **kw) x, y = x.copy(), y.copy() @@ -2001,6 +2003,9 @@ def advect_rk4(x_g, y_g, u_g, v_g, m_g, x, y, m, nb_step): # Grid coordinates x_ref, y_ref = x_g[0], y_g[0] x_step, y_step = x_g[1] - x_ref, y_g[1] - y_ref + is_circular = abs(x_g[-1] % 360 - (x_g[0] - x_step) % 360) < 1e-5 + nb_x_ = x_g.size - 2 + nb_x = nb_x_ if is_circular else 0 # cache i_cache, j_cache = -1000000, -1000000 masked = False @@ -2015,60 +2020,76 @@ def advect_rk4(x_g, y_g, u_g, v_g, m_g, x, y, m, nb_step): # Iterate on whole steps for _ in range(nb_step): # k1, slope at origin - ii_, jj_, ii, jj = get_grid_indices(x_ref, y_ref, x_step, y_step, x_, y_) + ii_, jj_, xd, yd = get_grid_indices( + x_ref, y_ref, x_step, y_step, x_, y_, nb_x + ) if ii_ != i_cache or jj_ != j_cache: - masked, u00, u01, u10, u11, v00, v01, v10, v11 = get_uv_quad( - ii_, jj_, u_g, v_g, m_g - ) i_cache, j_cache = ii_, jj_ + if not is_circular and (ii_ < 0 or ii_ > nb_x_): + masked = True + else: + masked, u00, u01, u10, u11, v00, v01, v10, v11 = get_uv_quad( + ii_, jj_, u_g, v_g, m_g, nb_x + ) # The 3 following could be in cache operation but this one must be test in any case if masked: x_, y_ = nan, nan m[i] = True break - xd, yd = ii - ii_, jj - jj_ u1, v1 = interp_uv(xd, yd, u00, u01, u10, u11, v00, v01, v10, v11) # k2, slope at middle with first guess position x1, y1 = x_ + u1 * 0.5, y_ + v1 * 0.5 - ii_, jj_, ii, jj = get_grid_indices(x_ref, y_ref, x_step, y_step, x1, y1) + ii_, jj_, xd, yd = get_grid_indices( + x_ref, y_ref, x_step, y_step, x1, y1, nb_x + ) if ii_ != i_cache or jj_ != j_cache: - masked, u00, u01, u10, u11, v00, v01, v10, v11 = get_uv_quad( - ii_, jj_, u_g, v_g, m_g - ) i_cache, j_cache = ii_, jj_ + if not is_circular and (ii_ < 0 or ii_ > nb_x_): + masked = True + else: + masked, u00, u01, u10, u11, v00, v01, v10, v11 = get_uv_quad( + ii_, jj_, u_g, v_g, m_g, nb_x + ) if masked: x_, y_ = nan, nan m[i] = True break - xd, yd = ii - ii_, jj - jj_ u2, v2 = interp_uv(xd, yd, u00, u01, u10, u11, v00, v01, v10, v11) # k3, slope at middle with update guess position x2, y2 = x_ + u2 * 0.5, y_ + v2 * 0.5 - ii_, jj_, ii, jj = get_grid_indices(x_ref, y_ref, x_step, y_step, x2, y2) + ii_, jj_, xd, yd = get_grid_indices( + x_ref, y_ref, x_step, y_step, x2, y2, nb_x + ) if ii_ != i_cache or jj_ != j_cache: - masked, u00, u01, u10, u11, v00, v01, v10, v11 = get_uv_quad( - ii_, jj_, u_g, v_g, m_g - ) i_cache, j_cache = ii_, jj_ + if not is_circular and (ii_ < 0 or ii_ > nb_x_): + masked = True + else: + masked, u00, u01, u10, u11, v00, v01, v10, v11 = get_uv_quad( + ii_, jj_, u_g, v_g, m_g, nb_x + ) if masked: x_, y_ = nan, nan m[i] = True break - xd, yd = ii - ii_, jj - jj_ u3, v3 = interp_uv(xd, yd, u00, u01, u10, u11, v00, v01, v10, v11) # k4, slope at end with update guess position x3, y3 = x_ + u3, y_ + v3 - ii_, jj_, ii, jj = get_grid_indices(x_ref, y_ref, x_step, y_step, x3, y3) + ii_, jj_, xd, yd = get_grid_indices( + x_ref, y_ref, x_step, y_step, x3, y3, nb_x + ) if ii_ != i_cache or jj_ != j_cache: - masked, u00, u01, u10, u11, v00, v01, v10, v11 = get_uv_quad( - ii_, jj_, u_g, v_g, m_g - ) i_cache, j_cache = ii_, jj_ + if not is_circular and (ii_ < 0 or ii_ > nb_x_): + masked = True + else: + masked, u00, u01, u10, u11, v00, v01, v10, v11 = get_uv_quad( + ii_, jj_, u_g, v_g, m_g, nb_x + ) if masked: x_, y_ = nan, nan m[i] = True break - xd, yd = ii - ii_, jj - jj_ u4, v4 = interp_uv(xd, yd, u00, u01, u10, u11, v00, v01, v10, v11) # RK4 compute dx = (u1 + 2 * u2 + 2 * u3 + u4) / 6 @@ -2080,30 +2101,19 @@ def advect_rk4(x_g, y_g, u_g, v_g, m_g, x, y, m, nb_step): y[i] = y_ -@njit(cache=True) -def get_uv(x0, y0, x_step, y_step, u, v, m, x, y): - i, j = (x - x0) / x_step, (y - y0) / y_step - i0, j0 = int(floor(i)), int(floor(j)) - i1, j1 = i0 + 1, j0 + 1 - if m[i0, j0] or m[i0, j1] or m[i1, j0] or m[i1, j1]: - return nan, nan - # Extract value for u and v - u00, u01, u10, u11 = u[i0, j0], u[i0, j1], u[i1, j0], u[i1, j1] - v00, v01, v10, v11 = v[i0, j0], v[i0, j1], v[i1, j0], v[i1, j1] - xd, yd = i - i0, j - j0 - xd_i, yd_i = 1 - xd, 1 - yd - u = (u00 * xd_i + u10 * xd) * yd_i + (u01 * xd_i + u11 * xd) * yd - v = (v00 * xd_i + v10 * xd) * yd_i + (v01 * xd_i + v11 * xd) * yd - return u, v - - @njit(cache=True) def advect(x_g, y_g, u_g, v_g, m_g, x, y, m, nb_step): # Grid coordinates x_ref, y_ref = x_g[0], y_g[0] x_step, y_step = x_g[1] - x_ref, y_g[1] - y_ref + is_circular = abs(x_g[-1] % 360 - (x_g[0] - x_step) % 360) < 1e-5 + nb_x_ = x_g.size - 2 + nb_x = nb_x_ if is_circular else 0 # Indices which should be never exist i0_old, j0_old = -100000, -100000 + masked = False + u00, u01, u10, u11 = 0.0, 0.0, 0.0, 0.0 + v00, v01, v10, v11 = 0.0, 0.0, 0.0, 0.0 # On each particule for i in prange(x.size): # If particule are not valid => continue @@ -2111,31 +2121,27 @@ def advect(x_g, y_g, u_g, v_g, m_g, x, y, m, nb_step): continue # Iterate on whole steps for _ in range(nb_step): - # Compute coordinates in indice referentiel - x_, y_ = (x[i] - x_ref) / x_step, (y[i] - y_ref) / y_step - # corner bottom left Indice - i0_, j0_ = int(floor(x_)), int(floor(y_)) - i0, j0 = i0_, j0_ - i1 = i0 + 1 + i0, j0, xd, yd = get_grid_indices( + x_ref, y_ref, x_step, y_step, x[i], y[i], nb_x + ) # corner are the same need only a new xd and yd if i0 != i0_old or j0 != j0_old: - j1 = j0 + 1 - # If one of nearest pixel is invalid - if m_g[i0, j0] or m_g[i0, j1] or m_g[i1, j0] or m_g[i1, j1]: - x[i], y[i] = nan, nan - m[i] = True - break - # Extract value for u and v - u00, u01, u10, u11 = u_g[i0, j0], u_g[i0, j1], u_g[i1, j0], u_g[i1, j1] - v00, v01, v10, v11 = v_g[i0, j0], v_g[i0, j1], v_g[i1, j0], v_g[i1, j1] # Need to be store only on change i0_old, j0_old = i0, j0 - # Compute distance - xd, yd = x_ - i0_, y_ - j0_ - xd_i, yd_i = 1 - xd, 1 - yd + if not is_circular and (i0 < 0 or i0 > nb_x_): + masked = True + else: + masked, u00, u01, u10, u11, v00, v01, v10, v11 = get_uv_quad( + i0, j0, u_g, v_g, m_g, nb_x + ) + if masked: + x[i], y[i] = nan, nan + m[i] = True + break + u, v = interp_uv(xd, yd, u00, u01, u10, u11, v00, v01, v10, v11) # Compute new x,y - x[i] += (u00 * xd_i + u10 * xd) * yd_i + (u01 * xd_i + u11 * xd) * yd - y[i] += (v00 * xd_i + v10 * xd) * yd_i + (v01 * xd_i + v11 * xd) * yd + x[i] += u + y[i] += v @njit(cache=True, fastmath=True) @@ -2311,6 +2317,8 @@ def filament( :param int time_step: Number of second for each advection :param int filament_size: Number of point by filament :return: x,y for a line + + .. minigallery:: py_eddy_tracker.GridCollection.filament """ x, y = x.copy(), y.copy() nb = x.shape[0] @@ -2374,6 +2382,20 @@ def advect( rk4=True, **kw, ): + """ + At each call it will update position in place with u & v field + + :param array x: Longitude of obs to move + :param array y: Latitude of obs to move + :param str,array u_name: U field to advect obs + :param str,array v_name: V field to advect obs + :param int nb_step: Number of iteration before to release data + :param int time_step: Number of second for each advection + + :return: x,y position + + .. minigallery:: py_eddy_tracker.GridCollection.advect + """ backward = kw.get("backward", False) if backward: generator = self.get_previous_time_step(t_init) @@ -2449,51 +2471,43 @@ def advect_t(x_g, y_g, u_g0, v_g0, m_g0, u_g1, v_g1, m_g1, x, y, m, weigths, hal # Grid coordinates x_ref, y_ref = x_g[0], y_g[0] x_step, y_step = x_g[1] - x_ref, y_g[1] - y_ref + is_circular = abs(x_g[-1] % 360 - (x_g[0] - x_step) % 360) < 1e-5 + nb_x_ = x_g.size - 2 + nb_x = nb_x_ if is_circular else 0 # Indices which should be never exist i0_old, j0_old = -100000, -100000 - # On each particule + m0, m1 = False, False + u000, u001, u010, u011 = 0.0, 0.0, 0.0, 0.0 + v000, v001, v010, v011 = 0.0, 0.0, 0.0, 0.0 + u100, u101, u110, u111 = 0.0, 0.0, 0.0, 0.0 + v100, v101, v110, v111 = 0.0, 0.0, 0.0, 0.0 + # On each particle for i in prange(x.size): - # If particule are not valid => continue + # If particle are not valid => continue if m[i]: continue # Iterate on whole steps for w in weigths: - # Compute coordinates in indice referentiel - x_, y_ = (x[i] - x_ref) / x_step, (y[i] - y_ref) / y_step - # corner bottom left Indice - i0_, j0_ = int(floor(x_)), int(floor(y_)) - i0, j0 = i0_, j0_ - i1 = i0 + 1 - # corner are the same need only a new xd and yd + i0, j0, xd, yd = get_grid_indices( + x_ref, y_ref, x_step, y_step, x[i], y[i], nb_x + ) if i0 != i0_old or j0 != j0_old: - j1 = j0 + 1 - # If one of nearest pixel is invalid - if ( - m_g0[i0, j0] - or m_g0[i0, j1] - or m_g0[i1, j0] - or m_g0[i1, j1] - or m_g1[i0, j0] - or m_g1[i0, j1] - or m_g1[i1, j0] - or m_g1[i1, j1] - ): - x[i], y[i] = nan, nan - m[i] = True - break - # Extract value for u and v - u000, u001 = u_g0[i0, j0], u_g0[i0, j1] - u010, u011 = u_g0[i1, j0], u_g0[i1, j1] - v000, v001 = v_g0[i0, j0], v_g0[i0, j1] - v010, v011 = v_g0[i1, j0], v_g0[i1, j1] - u100, u101 = u_g1[i0, j0], u_g1[i0, j1] - u110, u111 = u_g1[i1, j0], u_g1[i1, j1] - v100, v101 = v_g1[i0, j0], v_g1[i0, j1] - v110, v111 = v_g1[i1, j0], v_g1[i1, j1] # Need to be store only on change i0_old, j0_old = i0, j0 + if not is_circular and (i0 < 0 or i0 > nb_x_): + m0, m1 = True, True + else: + (m0, u000, u001, u010, u011, v000, v001, v010, v011) = get_uv_quad( + i0, j0, u_g0, v_g0, m_g0, nb_x + ) + (m1, u100, u101, u110, u111, v100, v101, v110, v111) = get_uv_quad( + i0, j0, u_g1, v_g1, m_g1, nb_x + ) + if m0 or m1: + x[i], y[i] = nan, nan + m[i] = True + break # Compute distance - xd, yd = x_ - i0_, y_ - j0_ xd_i, yd_i = 1 - xd, 1 - yd # Compute new x,y dx0 = (u000 * xd_i + u010 * xd) * yd_i + (u001 * xd_i + u011 * xd) * yd @@ -2505,8 +2519,23 @@ def advect_t(x_g, y_g, u_g0, v_g0, m_g0, u_g1, v_g1, m_g1, x, y, m, weigths, hal @njit(cache=True, fastmath=True) -def get_uv_quad(i0, j0, u, v, m): +def get_uv_quad(i0, j0, u, v, m, nb_x=0): + """ + Return u/v for (i0, j0), (i1, j0), (i0, j1), (i1, j1) + + :param int i0: indices of longitude + :param int j0: indices of latitude + :param array[float] u: current along x axis + :param array[float] v: current along y axis + :param array[bool] m: flag to know if position is valid + :param int nb_x: If different of 0 we check if wrapping is needed + + :return: if cell is valid 4 u, 4 v + :rtype: bool,float,float,float,float,float,float,float,float + """ i1, j1 = i0 + 1, j0 + 1 + if nb_x != 0: + i1 %= nb_x if m[i0, j0] or m[i0, j1] or m[i1, j0] or m[i1, j1]: return True, nan, nan, nan, nan, nan, nan, nan, nan # Extract value for u and v @@ -2516,14 +2545,45 @@ def get_uv_quad(i0, j0, u, v, m): @njit(cache=True, fastmath=True) -def get_grid_indices(x0, y0, x_step, y_step, x, y): +def get_grid_indices(x0, y0, x_step, y_step, x, y, nb_x=0): + """ + Return grid indices and weight + + :param float x0: first longitude + :param float y0: first latitude + :param float x_step: longitude grid step + :param float y_step: latitude grid step + :param float x: longitude to interpolate + :param float y: latitude to interpolate + :param int nb_x: If different of 0 we check if wrapping is needed + + :return: indices and weight + :rtype: int,int,float,float + """ i, j = (x - x0) / x_step, (y - y0) / y_step i0, j0 = int(floor(i)), int(floor(j)) - return i0, j0, i, j + xd, yd = i - i0, j - j0 + if nb_x != 0: + i0 %= nb_x + return i0, j0, xd, yd @njit(cache=True, fastmath=True) def interp_uv(xd, yd, u00, u01, u10, u11, v00, v01, v10, v11): + """ + Return u/v interpolated in cell + + :param float xd: x weight + :param float yd: y weight + :param float u00: u lower left + :param float u01: u upper left + :param float u10: u lower right + :param float u11: u upper right + :param float v00: v lower left + :param float v01: v upper left + :param float v10: v lower right + :param float v11: v upper right + """ xd_i, yd_i = 1 - xd, 1 - yd u = (u00 * xd_i + u10 * xd) * yd_i + (u01 * xd_i + u11 * xd) * yd v = (v00 * xd_i + v10 * xd) * yd_i + (v01 * xd_i + v11 * xd) * yd @@ -2537,9 +2597,12 @@ def advect_t_rk4( # Grid coordinates x_ref, y_ref = x_g[0], y_g[0] x_step, y_step = x_g[1] - x_ref, y_g[1] - y_ref + is_circular = abs(x_g[-1] % 360 - (x_g[0] - x_step) % 360) < 1e-5 + nb_x_ = x_g.size - 2 + nb_x = nb_x_ if is_circular else 0 # cache i_cache, j_cache = -1000000, -1000000 - masked0, masked1 = False, False + m0, m1 = False, False u000, u001, u010, u011 = 0.0, 0.0, 0.0, 0.0 v000, v001, v010, v011 = 0.0, 0.0, 0.0, 0.0 u100, u101, u110, u111 = 0.0, 0.0, 0.0, 0.0 @@ -2553,79 +2616,95 @@ def advect_t_rk4( # Iterate on whole steps for w in weigths: # k1, slope at origin - ii_, jj_, ii, jj = get_grid_indices(x_ref, y_ref, x_step, y_step, x_, y_) + ii_, jj_, xd, yd = get_grid_indices( + x_ref, y_ref, x_step, y_step, x_, y_, nb_x + ) if ii_ != i_cache or jj_ != j_cache: - masked0, u000, u001, u010, u011, v000, v001, v010, v011 = get_uv_quad( - ii_, jj_, u_g0, v_g0, m_g0 - ) - masked1, u100, u101, u110, u111, v100, v101, v110, v111 = get_uv_quad( - ii_, jj_, u_g1, v_g1, m_g1 - ) i_cache, j_cache = ii_, jj_ + if not is_circular and (ii_ < 0 or ii_ > nb_x_): + m0, m1 = True, True + else: + (m0, u000, u001, u010, u011, v000, v001, v010, v011) = get_uv_quad( + ii_, jj_, u_g0, v_g0, m_g0, nb_x + ) + (m1, u100, u101, u110, u111, v100, v101, v110, v111) = get_uv_quad( + ii_, jj_, u_g1, v_g1, m_g1, nb_x + ) # The 3 following could be in cache operation but this one must be test in any case - if masked0 or masked1: + if m0 or m1: x_, y_ = nan, nan m[i] = True break - xd, yd = ii - ii_, jj - jj_ u0_, v0_ = interp_uv(xd, yd, u000, u001, u010, u011, v000, v001, v010, v011) u1_, v1_ = interp_uv(xd, yd, u100, u101, u110, u111, v100, v101, v110, v111) u1, v1 = u0_ * w + u1_ * (1 - w), v0_ * w + v1_ * (1 - w) # k2, slope at middle with first guess position x1, y1 = x_ + u1 * 0.5, y_ + v1 * 0.5 - ii_, jj_, ii, jj = get_grid_indices(x_ref, y_ref, x_step, y_step, x1, y1) + ii_, jj_, xd, yd = get_grid_indices( + x_ref, y_ref, x_step, y_step, x1, y1, nb_x + ) if ii_ != i_cache or jj_ != j_cache: - masked0, u000, u001, u010, u011, v000, v001, v010, v011 = get_uv_quad( - ii_, jj_, u_g0, v_g0, m_g0 - ) - masked1, u100, u101, u110, u111, v100, v101, v110, v111 = get_uv_quad( - ii_, jj_, u_g1, v_g1, m_g1 - ) i_cache, j_cache = ii_, jj_ - if masked0 or masked1: + if not is_circular and (ii_ < 0 or ii_ > nb_x_): + m0, m1 = True, True + else: + (m0, u000, u001, u010, u011, v000, v001, v010, v011) = get_uv_quad( + ii_, jj_, u_g0, v_g0, m_g0, nb_x + ) + (m1, u100, u101, u110, u111, v100, v101, v110, v111) = get_uv_quad( + ii_, jj_, u_g1, v_g1, m_g1, nb_x + ) + if m0 or m1: x_, y_ = nan, nan m[i] = True break - xd, yd = ii - ii_, jj - jj_ u0_, v0_ = interp_uv(xd, yd, u000, u001, u010, u011, v000, v001, v010, v011) u1_, v1_ = interp_uv(xd, yd, u100, u101, u110, u111, v100, v101, v110, v111) w_ = w - half_w u2, v2 = u0_ * w_ + u1_ * (1 - w_), v0_ * w_ + v1_ * (1 - w_) # k3, slope at middle with update guess position x2, y2 = x_ + u2 * 0.5, y_ + v2 * 0.5 - ii_, jj_, ii, jj = get_grid_indices(x_ref, y_ref, x_step, y_step, x2, y2) + ii_, jj_, xd, yd = get_grid_indices( + x_ref, y_ref, x_step, y_step, x2, y2, nb_x + ) if ii_ != i_cache or jj_ != j_cache: - masked0, u000, u001, u010, u011, v000, v001, v010, v011 = get_uv_quad( - ii_, jj_, u_g0, v_g0, m_g0 - ) - masked1, u100, u101, u110, u111, v100, v101, v110, v111 = get_uv_quad( - ii_, jj_, u_g1, v_g1, m_g1 - ) i_cache, j_cache = ii_, jj_ - if masked0 or masked1: + if not is_circular and (ii_ < 0 or ii_ > nb_x_): + m0, m1 = True, True + else: + (m0, u000, u001, u010, u011, v000, v001, v010, v011) = get_uv_quad( + ii_, jj_, u_g0, v_g0, m_g0, nb_x + ) + (m1, u100, u101, u110, u111, v100, v101, v110, v111) = get_uv_quad( + ii_, jj_, u_g1, v_g1, m_g1, nb_x + ) + if m0 or m1: x_, y_ = nan, nan m[i] = True break - xd, yd = ii - ii_, jj - jj_ u0_, v0_ = interp_uv(xd, yd, u000, u001, u010, u011, v000, v001, v010, v011) u1_, v1_ = interp_uv(xd, yd, u100, u101, u110, u111, v100, v101, v110, v111) u3, v3 = u0_ * w_ + u1_ * (1 - w_), v0_ * w_ + v1_ * (1 - w_) # k4, slope at end with update guess position x3, y3 = x_ + u3, y_ + v3 - ii_, jj_, ii, jj = get_grid_indices(x_ref, y_ref, x_step, y_step, x3, y3) + ii_, jj_, xd, yd = get_grid_indices( + x_ref, y_ref, x_step, y_step, x3, y3, nb_x + ) if ii_ != i_cache or jj_ != j_cache: - masked0, u000, u001, u010, u011, v000, v001, v010, v011 = get_uv_quad( - ii_, jj_, u_g0, v_g0, m_g0 - ) - masked1, u100, u101, u110, u111, v100, v101, v110, v111 = get_uv_quad( - ii_, jj_, u_g1, v_g1, m_g1 - ) i_cache, j_cache = ii_, jj_ - if masked0 or masked1: + if not is_circular and (ii_ < 0 or ii_ > nb_x_): + m0, m1 = True, True + else: + (m0, u000, u001, u010, u011, v000, v001, v010, v011) = get_uv_quad( + ii_, jj_, u_g0, v_g0, m_g0, nb_x + ) + (m1, u100, u101, u110, u111, v100, v101, v110, v111) = get_uv_quad( + ii_, jj_, u_g1, v_g1, m_g1, nb_x + ) + if m0 or m1: x_, y_ = nan, nan m[i] = True break - xd, yd = ii - ii_, jj - jj_ u0_, v0_ = interp_uv(xd, yd, u000, u001, u010, u011, v000, v001, v010, v011) u1_, v1_ = interp_uv(xd, yd, u100, u101, u110, u111, v100, v101, v110, v111) w_ -= half_w From 1be9be7d307228f15b0f3d5c834fd39126a4615a Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Thu, 18 Mar 2021 11:53:37 +0100 Subject: [PATCH 110/249] reformat some docstring --- examples/02_eddy_identification/pet_contour_circle.py | 2 +- .../02_eddy_identification/pet_eddy_detection_ACC.py | 2 +- examples/02_eddy_identification/pet_uv_profile.py | 0 examples/07_cube_manipulation/pet_fsle_med.py | 4 ++-- notebooks/README.md | 1 + .../02_eddy_identification/pet_contour_circle.ipynb | 2 +- .../pet_eddy_detection_ACC.ipynb | 2 +- .../07_cube_manipulation/pet_fsle_med.ipynb | 4 ++-- .../pet_track_anim_matplotlib_animation.ipynb | 4 ++-- src/py_eddy_tracker/dataset/grid.py | 2 +- src/py_eddy_tracker/observations/groups.py | 10 ++++------ src/py_eddy_tracker/observations/observation.py | 2 +- 12 files changed, 17 insertions(+), 18 deletions(-) create mode 100644 examples/02_eddy_identification/pet_uv_profile.py diff --git a/examples/02_eddy_identification/pet_contour_circle.py b/examples/02_eddy_identification/pet_contour_circle.py index 197ae357..173ca4da 100644 --- a/examples/02_eddy_identification/pet_contour_circle.py +++ b/examples/02_eddy_identification/pet_contour_circle.py @@ -25,4 +25,4 @@ # 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") +_ = ax.legend(loc="upper right") diff --git a/examples/02_eddy_identification/pet_eddy_detection_ACC.py b/examples/02_eddy_identification/pet_eddy_detection_ACC.py index 5354b1c9..415da9dd 100644 --- a/examples/02_eddy_identification/pet_eddy_detection_ACC.py +++ b/examples/02_eddy_identification/pet_eddy_detection_ACC.py @@ -94,7 +94,7 @@ def set_fancy_labels(fig, ticklabelsize=14, labelsize=14, labelweight="semibold" # ------- kw_adt = dict(vmin=-1.5, vmax=1.5, cmap=plt.get_cmap("RdBu_r", 30)) fig, axs = quad_axes("General properties field") -m = g_raw.display(axs[0], "adt", **kw_adt) +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") diff --git a/examples/02_eddy_identification/pet_uv_profile.py b/examples/02_eddy_identification/pet_uv_profile.py new file mode 100644 index 00000000..e69de29b diff --git a/examples/07_cube_manipulation/pet_fsle_med.py b/examples/07_cube_manipulation/pet_fsle_med.py index 3857bb5a..bbeb0007 100644 --- a/examples/07_cube_manipulation/pet_fsle_med.py +++ b/examples/07_cube_manipulation/pet_fsle_med.py @@ -179,7 +179,7 @@ def build_triplet(x, y, step=0.02): kw = dict(cmap="viridis_r", vmin=-15, vmax=0) m = fsle_custom.display(ax, 1 / fsle_custom.grid("fsle"), **kw) ax.grid() -cb = plt.colorbar(m, cax=fig.add_axes([0.94, 0.05, 0.01, 0.9])) +_ = plt.colorbar(m, cax=fig.add_axes([0.94, 0.05, 0.01, 0.9])) # %% # Display Theta # ------------- @@ -191,4 +191,4 @@ def build_triplet(x, y, step=0.02): kw = dict(cmap="Spectral_r", vmin=-180, vmax=180) m = fsle_custom.display(ax, fsle_custom.grid("theta"), **kw) ax.grid() -cb = plt.colorbar(m, cax=fig.add_axes([0.94, 0.05, 0.01, 0.9])) +_ = plt.colorbar(m, cax=fig.add_axes([0.94, 0.05, 0.01, 0.9])) diff --git a/notebooks/README.md b/notebooks/README.md index 27bee160..bbf88a8b 100644 --- a/notebooks/README.md +++ b/notebooks/README.md @@ -1,3 +1,4 @@ # rm build/sphinx/ doc/python_module/ doc/gen_modules/ -rf +# rm doc/_autosummary/ doc/gen_modules - rf python setup.py build_sphinx rsync -vrltp doc/python_module notebooks/. --include '*/' --include '*.ipynb' --exclude '*' --prune-empty-dirs diff --git a/notebooks/python_module/02_eddy_identification/pet_contour_circle.ipynb b/notebooks/python_module/02_eddy_identification/pet_contour_circle.ipynb index aab4e0f6..27bc522a 100644 --- a/notebooks/python_module/02_eddy_identification/pet_contour_circle.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_contour_circle.ipynb @@ -62,7 +62,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(15, 8))\nax = fig.add_axes((0.05, 0.05, 0.9, 0.9))\nax.set_aspect(\"equal\")\nax.set_xlim(10, 70)\nax.set_ylim(-50, -25)\na.display(ax, label=\"Anticyclonic contour\", color=\"r\", lw=1)\n\n# Replace contours by circles using center and radius (effective is dashed)\na.circle_contour()\na.display(ax, label=\"Anticyclonic circle\", color=\"g\", lw=1)\nax.legend(loc=\"upper right\")" + "fig = plt.figure(figsize=(15, 8))\nax = fig.add_axes((0.05, 0.05, 0.9, 0.9))\nax.set_aspect(\"equal\")\nax.set_xlim(10, 70)\nax.set_ylim(-50, -25)\na.display(ax, label=\"Anticyclonic contour\", color=\"r\", lw=1)\n\n# Replace contours by circles using center and radius (effective is dashed)\na.circle_contour()\na.display(ax, label=\"Anticyclonic circle\", color=\"g\", lw=1)\n_ = ax.legend(loc=\"upper right\")" ] } ], diff --git a/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb b/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb index 689f532b..d9417d22 100644 --- a/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb @@ -80,7 +80,7 @@ }, "outputs": [], "source": [ - "kw_adt = dict(vmin=-1.5, vmax=1.5, cmap=plt.get_cmap(\"RdBu_r\", 30))\nfig, axs = quad_axes(\"General properties field\")\nm = g_raw.display(axs[0], \"adt\", **kw_adt)\naxs[0].set_title(\"Total ADT (m)\")\nm = g.display(axs[1], \"adt_low\", **kw_adt)\naxs[1].set_title(\"ADT (m) large scale, cutoff at 700 km\")\nm2 = g.display(axs[2], \"adt\", cmap=plt.get_cmap(\"RdBu_r\", 20), vmin=-0.5, vmax=0.5)\naxs[2].set_title(\"ADT (m) high-pass filtered, a cutoff at 700 km\")\ncb = plt.colorbar(m, cax=axs[0].figure.add_axes(pos_cb), orientation=\"horizontal\")\ncb.set_label(\"ADT (m)\", labelpad=0)\ncb2 = plt.colorbar(m2, cax=axs[2].figure.add_axes(pos_cb2), orientation=\"horizontal\")\ncb2.set_label(\"ADT (m)\", labelpad=0)\nset_fancy_labels(fig)" + "kw_adt = dict(vmin=-1.5, vmax=1.5, cmap=plt.get_cmap(\"RdBu_r\", 30))\nfig, axs = quad_axes(\"General properties field\")\ng_raw.display(axs[0], \"adt\", **kw_adt)\naxs[0].set_title(\"Total ADT (m)\")\nm = g.display(axs[1], \"adt_low\", **kw_adt)\naxs[1].set_title(\"ADT (m) large scale, cutoff at 700 km\")\nm2 = g.display(axs[2], \"adt\", cmap=plt.get_cmap(\"RdBu_r\", 20), vmin=-0.5, vmax=0.5)\naxs[2].set_title(\"ADT (m) high-pass filtered, a cutoff at 700 km\")\ncb = plt.colorbar(m, cax=axs[0].figure.add_axes(pos_cb), orientation=\"horizontal\")\ncb.set_label(\"ADT (m)\", labelpad=0)\ncb2 = plt.colorbar(m2, cax=axs[2].figure.add_axes(pos_cb2), orientation=\"horizontal\")\ncb2.set_label(\"ADT (m)\", labelpad=0)\nset_fancy_labels(fig)" ] }, { diff --git a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb index 00477940..f42b3e43 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb @@ -134,7 +134,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(13, 5), dpi=150)\nax = fig.add_axes([0.03, 0.03, 0.90, 0.94])\nax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\nax.set_aspect(\"equal\")\nax.set_title(\"Finite size lyapunov exponent\", weight=\"bold\")\nkw = dict(cmap=\"viridis_r\", vmin=-15, vmax=0)\nm = fsle_custom.display(ax, 1 / fsle_custom.grid(\"fsle\"), **kw)\nax.grid()\ncb = plt.colorbar(m, cax=fig.add_axes([0.94, 0.05, 0.01, 0.9]))" + "fig = plt.figure(figsize=(13, 5), dpi=150)\nax = fig.add_axes([0.03, 0.03, 0.90, 0.94])\nax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\nax.set_aspect(\"equal\")\nax.set_title(\"Finite size lyapunov exponent\", weight=\"bold\")\nkw = dict(cmap=\"viridis_r\", vmin=-15, vmax=0)\nm = fsle_custom.display(ax, 1 / fsle_custom.grid(\"fsle\"), **kw)\nax.grid()\n_ = plt.colorbar(m, cax=fig.add_axes([0.94, 0.05, 0.01, 0.9]))" ] }, { @@ -152,7 +152,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(13, 5), dpi=150)\nax = fig.add_axes([0.03, 0.03, 0.90, 0.94])\nax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\nax.set_aspect(\"equal\")\nax.set_title(\"Theta from finite size lyapunov exponent\", weight=\"bold\")\nkw = dict(cmap=\"Spectral_r\", vmin=-180, vmax=180)\nm = fsle_custom.display(ax, fsle_custom.grid(\"theta\"), **kw)\nax.grid()\ncb = plt.colorbar(m, cax=fig.add_axes([0.94, 0.05, 0.01, 0.9]))" + "fig = plt.figure(figsize=(13, 5), dpi=150)\nax = fig.add_axes([0.03, 0.03, 0.90, 0.94])\nax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\nax.set_aspect(\"equal\")\nax.set_title(\"Theta from finite size lyapunov exponent\", weight=\"bold\")\nkw = dict(cmap=\"Spectral_r\", vmin=-180, vmax=180)\nm = fsle_custom.display(ax, fsle_custom.grid(\"theta\"), **kw)\nax.grid()\n_ = plt.colorbar(m, cax=fig.add_axes([0.94, 0.05, 0.01, 0.9]))" ] } ], diff --git a/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb index 17668aed..4b35ba38 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import re\n\nimport py_eddy_tracker_sample\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange\n\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations\n# sphinx_gallery_thumbnail_path = '_static/no_image.png'" + "import re\n\nimport py_eddy_tracker_sample\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange\n\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations\n\n# sphinx_gallery_thumbnail_path = '_static/no_image.png'" ] }, { @@ -73,7 +73,7 @@ }, "outputs": [], "source": [ - "a = Anim(eddy, intern=True, figsize=(8, 3.5), cmap=\"magma_r\", nb_step=5, dpi=50)\na.txt.set_position((17, 34.6))\na.ax.set_xlim(16.5, 23)\na.ax.set_ylim(34.5, 37)\n\n# arguments to get full animation\n# arguments to reduce compute cost for doucmentation, we display only every 10 days\nkwargs = dict(frames=arange(*a.period)[300:800], interval=90)\n\nani = VideoAnimation(a.fig, a.func_animation, **kwargs)" + "a = Anim(eddy, intern=True, figsize=(8, 3.5), cmap=\"magma_r\", nb_step=5, dpi=50)\na.txt.set_position((17, 34.6))\na.ax.set_xlim(16.5, 23)\na.ax.set_ylim(34.5, 37)\n\n# arguments to get full animation\nkwargs = dict(frames=arange(*a.period)[300:800], interval=90)\n\nani = VideoAnimation(a.fig, a.func_animation, **kwargs)" ] } ], diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index cf20f340..f782518e 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -1963,6 +1963,7 @@ def filament( Produce filament with concatenation of advection It's a dummy advection which use only one layer of current + :param array x: Longitude of obs to move :param array y: Latitude of obs to move :param str,array u_name: U field to advect obs @@ -2308,7 +2309,6 @@ def filament( """ Produce filament with concatenation of advection - It's a dummy advection which use only one layer of current :param array x: Longitude of obs to move :param array y: Latitude of obs to move :param str,array u_name: U field to advect obs diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index 68047371..5a01d452 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -128,15 +128,13 @@ def insert_virtual(self): def keep_tracks_by_date(self, date, nb_days): """ - find tracks which exist at date `date` and lasted at least `nb_days` after. + Find tracks which exist at date `date` and lasted at least `nb_days` after. - if nb_days is negative, it search a tracks which exist at the date, - but existed at least `nb_days` before the date - - - :param int,float date : date where the tracks must exist + :param int,float date: date where the tracks must exist :param int,float nb_days: number of time where the tracks must exist. Can be negative + If nb_days is negative, it search a tracks which exist at the date, + but existed at least `nb_days` before the date """ time = self.time diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 7535a7e4..0c43aac3 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -1666,7 +1666,7 @@ def write_file( filename = filename.replace(".nc", ".zarr") if filename.endswith(".zarr"): zarr_flag = True - logger.info("Store in %s", filename) + logger.info("Store in %s (%d observations)", filename, len(self)) if zarr_flag: handler = zarr.open(filename, "w") self.to_zarr(handler, **kwargs) From a3a47db76594e1edcda5516193a4fcce80cb0f50 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Thu, 18 Mar 2021 12:01:20 +0100 Subject: [PATCH 111/249] un index example --- examples/02_eddy_identification/pet_uv_profile.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 examples/02_eddy_identification/pet_uv_profile.py diff --git a/examples/02_eddy_identification/pet_uv_profile.py b/examples/02_eddy_identification/pet_uv_profile.py deleted file mode 100644 index e69de29b..00000000 From 1f0e2a004421b6274d3525df4eda99bcd8dbd327 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Thu, 18 Mar 2021 14:29:06 +0100 Subject: [PATCH 112/249] add some informations about area tracker --- README.md | 6 ++++++ examples/16_network/pet_group_anim.py | 2 +- examples/16_network/pet_segmentation_anim.py | 2 +- src/py_eddy_tracker/featured_tracking/area_tracker.py | 10 ++++++++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4f466b7e..95536d1d 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,12 @@ Method is used in : ### How do I get set up? ### +#### Short story #### +```bash +pip install pyeddytracker +``` +#### Long story #### + To avoid problems with installation, use of the virtualenv Python virtual environment is recommended. Then use pip to install all dependencies (numpy, scipy, matplotlib, netCDF4, ...), e.g.: diff --git a/examples/16_network/pet_group_anim.py b/examples/16_network/pet_group_anim.py index 09ab4954..9264282a 100644 --- a/examples/16_network/pet_group_anim.py +++ b/examples/16_network/pet_group_anim.py @@ -146,7 +146,7 @@ def update(frame): # %% # Final Result -# ----------- +# ------------ fig = plt.figure(figsize=(16, 9)) ax = fig.add_axes([0, 0, 1, 1]) ax.set_aspect("equal"), ax.grid(), ax.set_xlim(26, 34), ax.set_ylim(31, 35.5) diff --git a/examples/16_network/pet_segmentation_anim.py b/examples/16_network/pet_segmentation_anim.py index 74a94e3c..10f46b66 100644 --- a/examples/16_network/pet_segmentation_anim.py +++ b/examples/16_network/pet_segmentation_anim.py @@ -119,7 +119,7 @@ def update(i_frame): # %% # Final Result -# ----------- +# ------------ fig = plt.figure(figsize=(16, 9)) ax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection="full_axes") ax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid() diff --git a/src/py_eddy_tracker/featured_tracking/area_tracker.py b/src/py_eddy_tracker/featured_tracking/area_tracker.py index 1b8a2dbb..9e676fc1 100644 --- a/src/py_eddy_tracker/featured_tracking/area_tracker.py +++ b/src/py_eddy_tracker/featured_tracking/area_tracker.py @@ -9,6 +9,13 @@ class AreaTracker(Model): + """ + Area Tracker will used overlap to track eddy. + + This tracking will used :py:meth:`~py_eddy_tracker.observations.observation.EddiesObservations.match` method + to get a similarity index, which could be between [0:1]. + You could setup this class with `cmin` option to set a minimal value to valid an association. + """ __slots__ = ("cmin",) @@ -28,6 +35,9 @@ def needed_variable(cls): return vars def tracking(self, other): + """ + Core method to track + """ shape = (self.shape[0], other.shape[0]) i, j, c = self.match(other, intern=False) cost_mat = ma.array(empty(shape, dtype="f4"), mask=ones(shape, dtype="bool")) From a7fd059a917520796506ed6c57f0b4dbd8f92d57 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Thu, 18 Mar 2021 16:47:42 +0100 Subject: [PATCH 113/249] Modification of quick compare to be called in python --- src/py_eddy_tracker/appli/eddies.py | 144 ++++++++++++++++------------ 1 file changed, 82 insertions(+), 62 deletions(-) diff --git a/src/py_eddy_tracker/appli/eddies.py b/src/py_eddy_tracker/appli/eddies.py index 11442769..d5a727f9 100644 --- a/src/py_eddy_tracker/appli/eddies.py +++ b/src/py_eddy_tracker/appli/eddies.py @@ -445,6 +445,79 @@ def get_twin(j2, j1): return group1, group2 +def run_compare(ref, others, invalid=1, low=20, high=80, intern=False, **kwargs): + groups_ref, groups_other = dict(), dict() + for i, (k, other) in enumerate(others.items()): + print(f"[{i}] {k} -> {len(other)} obs") + gr1, gr2 = get_group( + ref, + other, + *ref.match(other, intern=intern, **kwargs), + invalid=invalid, + low=low, + high=high, + ) + groups_ref[k] = gr1 + groups_other[k] = gr2 + return groups_ref, groups_other + + +def display_compare( + ref, others, invalid=1, low=20, high=80, area=False, intern=False, **kwargs +): + gr_ref, gr_others = run_compare( + ref, others, invalid=invalid, low=low, high=high, intern=intern, **kwargs + ) + + def display(value, ref=None): + outs = list() + for v in value: + if ref: + if area: + outs.append(f"{v / ref * 100:.1f}% ({v:.1f}Mkm²)") + else: + outs.append(f"{v/ref * 100:.1f}% ({v})") + else: + outs.append(v) + if area: + return "".join([f"{v:^16}" for v in outs]) + else: + return "".join([f"{v:^15}" for v in outs]) + + def get_values(v, dataset): + if area: + area_ = dataset["speed_area" if intern else "effective_area"] + return [area_[v_].sum() / 1e12 for v_ in v.values()] + else: + return [ + v_.sum() if v_.dtype == "bool" else v_.shape[0] for v_ in v.values() + ] + + labels = dict( + high=f"{high:0.0f} <= high", + low=f"{invalid:0.0f} <= low < {low:0.0f}", + ) + + keys = [labels.get(key, key) for key in list(gr_ref.values())[0].keys()] + print(" ", display(keys)) + if area: + ref_ = ref["speed_area" if intern else "effective_area"].sum() / 1e12 + else: + ref_ = len(ref) + for i, v in enumerate(gr_ref.values()): + print(f"[{i:2}] ", display(get_values(v, ref), ref=ref_)) + + print(" Point of view of study dataset") + print(" ", display(keys)) + for i, (k, v) in enumerate(gr_others.items()): + other = others[k] + if area: + ref_ = other["speed_area" if intern else "effective_area"].sum() / 1e12 + else: + ref_ = len(other) + print(f"[{i:2}] ", display(get_values(v, other), ref=ref_)) + + def quick_compare(): parser = EddyParser( "Tool to have a quick comparison between several identification" @@ -478,23 +551,17 @@ def quick_compare(): ref = EddiesObservations.load_file(args.ref, **kw) print(f"[ref] {args.ref} -> {len(ref)} obs") - groups_ref, groups_other = dict(), dict() others = {other: EddiesObservations.load_file(other, **kw) for other in args.others} - for i, other_ in enumerate(args.others): - other = others[other_] - print(f"[{i}] {other_} -> {len(other)} obs") - gr1, gr2 = get_group( - ref, - other, - *ref.match(other, intern=args.intern, minimal_area=args.minimal_area), - invalid=args.invalid, - low=args.low, - high=args.high, - ) - groups_ref[other_] = gr1 - groups_other[other_] = gr2 + kwargs = dict( + invalid=args.invalid, + low=args.low, + high=args.high, + intern=args.intern, + minimal_area=args.minimal_area, + ) if args.path_out is not None: + groups_ref, groups_other = run_compare(ref, others, **kwargs) if not exists(args.path_out): mkdir(args.path_out) for i, other_ in enumerate(args.others): @@ -508,51 +575,4 @@ def quick_compare(): basename_ = f"ref_{k}.nc" ref.index(v).write_file(filename=f"{dirname_}/{basename_}") return - - def display(value, ref=None): - outs = list() - for v in value: - if ref: - if args.area: - outs.append(f"{v / ref * 100:.1f}% ({v:.1f}Mkm²)") - else: - outs.append(f"{v/ref * 100:.1f}% ({v})") - else: - outs.append(v) - if args.area: - return "".join([f"{v:^16}" for v in outs]) - else: - return "".join([f"{v:^15}" for v in outs]) - - def get_values(v, dataset): - if args.area: - area = dataset["speed_area" if args.intern else "effective_area"] - return [area[v_].sum() / 1e12 for v_ in v.values()] - else: - return [ - v_.sum() if v_.dtype == "bool" else v_.shape[0] for v_ in v.values() - ] - - labels = dict( - high=f"{args.high:0.0f} <= high", - low=f"{args.invalid:0.0f} <= low < {args.low:0.0f}", - ) - - keys = [labels.get(key, key) for key in gr1.keys()] - print(" ", display(keys)) - if args.area: - ref_ = ref["speed_area" if args.intern else "effective_area"].sum() / 1e12 - else: - ref_ = len(ref) - for i, v in enumerate(groups_ref.values()): - print(f"[{i:2}] ", display(get_values(v, ref), ref=ref_)) - - print(" Point of view of study dataset") - print(" ", display(keys)) - for i, (k, v) in enumerate(groups_other.items()): - other = others[k] - if args.area: - ref_ = other["speed_area" if args.intern else "effective_area"].sum() / 1e12 - else: - ref_ = len(other) - print(f"[{i:2}] ", display(get_values(v, other), ref=ref_)) + display_compare(ref, others, **kwargs, area=args.area) From 3d237a2a5756c634986014f06ec2302894813394 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Fri, 19 Mar 2021 12:31:29 +0100 Subject: [PATCH 114/249] Solve bug of interpolation around bound --- src/py_eddy_tracker/generic.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/py_eddy_tracker/generic.py b/src/py_eddy_tracker/generic.py index d6915088..62664481 100644 --- a/src/py_eddy_tracker/generic.py +++ b/src/py_eddy_tracker/generic.py @@ -258,6 +258,8 @@ def interp2d_bilinear(x_g, y_g, z_g, m_g, x, y): x_ = (x[i] - x_ref) / x_step y_ = (y[i] - y_ref) / y_step i0 = int(floor(x_)) + # To keep original value if wrapping apply to compute xd + i0_ = i0 j0 = int(floor(y_)) # corner are the same need only a new xd and yd if i0 != i0_old or j0 != j0_old: @@ -286,7 +288,7 @@ def interp2d_bilinear(x_g, y_g, z_g, m_g, x, y): if masked: z[i] = nan else: - xd = x_ - i0 + xd = x_ - i0_ yd = y_ - j0 z[i] = (z00 * (1 - xd) + (z10 * xd)) * (1 - yd) + ( z01 * (1 - xd) + z11 * xd From c4ad072c582d6b2efb487218f7ec85950fcb4c05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Tue, 16 Mar 2021 17:14:02 +0100 Subject: [PATCH 115/249] optimisation on time --- src/py_eddy_tracker/observations/network.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 0f25ace4..e8e9b265 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -490,6 +490,8 @@ def event_timeline(self, ax, field=None, method=None, factor=1, colors_mode="rol # TODO : fill mappables dict y_seg = dict() + _time = self.time + if field is not None and method != "all": for i, b0, _ in self.iter_on("segment"): y = self[field][i] @@ -497,7 +499,7 @@ def event_timeline(self, ax, field=None, method=None, factor=1, colors_mode="rol y_seg[b0] = y.mean() * factor mappables = dict() for i, b0, b1 in self.iter_on("segment"): - x = self.time[i] + x = _time[i] if x.shape[0] == 0: continue @@ -532,7 +534,7 @@ def event_timeline(self, ax, field=None, method=None, factor=1, colors_mode="rol else y_seg[seg_next] ) ) - ax.plot((x[-1], self.time[i_n]), (y0, y1), **event_kw)[0] + ax.plot((x[-1], _time[i_n]), (y0, y1), **event_kw)[0] events["merging"].append((x[-1], y0)) if i_p != -1: @@ -548,7 +550,7 @@ def event_timeline(self, ax, field=None, method=None, factor=1, colors_mode="rol else y_seg[seg_previous] ) ) - ax.plot((x[0], self.time[i_p]), (y0, y1), **event_kw)[0] + ax.plot((x[0], _time[i_p]), (y0, y1), **event_kw)[0] events["spliting"].append((x[0], y0)) j += 1 From b2e5291922da56a0f19a3796ffbe2bdd82dfb4e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Wed, 17 Mar 2021 09:23:51 +0100 Subject: [PATCH 116/249] add function correct_close_events --- src/py_eddy_tracker/observations/network.py | 53 +++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index e8e9b265..47c468a9 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -240,6 +240,59 @@ def from_split_network(cls, group_dataset, indexs, **kwargs): def infos(self, label=""): return f"{len(self)} obs {unique(self.segment).shape[0]} segments" + def correct_close_events(self, nb_days_max=20): + + _time = self.time + segment = self.segment.copy() + segments_connexion = dict() + + previous_obs, next_obs = self.previous_obs, self.next_obs + + # record for every segments, the slice, indice of next obs & indice of previous obs + for i, seg, _ in self.iter_on(self.segment): + if i.start == i.stop: + continue + + i_p, i_n = previous_obs[i.start], next_obs[i.stop - 1] + segments_connexion[seg] = [i, i_p, i_n] + + for seg in sorted(segments_connexion.keys()): + seg_slice, i_seg_p, i_seg_n = segments_connexion[seg] + n_seg = segment[i_seg_n] + + # if segment has splitting + if i_seg_n != -1: + seg2_slice, i2_seg_p, i2_seg_n = segments_connexion[n_seg] + p2_seg = segment[i2_seg_p] + + # if it merge on the first in a certain time + if (p2_seg == seg) and (_time[i_seg_n] - _time[i2_seg_p] < nb_days_max): + + segment[i_seg_n : seg2_slice.stop] = seg + previous_obs[i_seg_n] = seg_slice.stop - 1 + + self.segment[:] = segment + self.next_obs[:] = next_obs + self.previous_obs[:] = previous_obs + + self.sort() + + def sort(self, order=("track", "segment", "time")): + """ + sort observations + + :param tuple order: order or sorting. Passed to `np.argsort` + """ + + index_order = self.obs.argsort(order=order) + for field in self.elements: + self[field][:] = self[field][index_order] + + translate = -ones(index_order.max() + 2, dtype="i4") + translate[index_order] = arange(index_order.shape[0]) + self.next_obs[:] = translate[self.next_obs] + self.previous_obs[:] = translate[self.previous_obs] + def obs_relative_order(self, i_obs): self.only_one_network() return self.segment_relative_order(self.segment[i_obs]) From 6824ad7aeea7d7f1a78904e5e646de9fb7bbda6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Wed, 17 Mar 2021 13:48:38 +0100 Subject: [PATCH 117/249] correction correct_close_events, and add figure to python example using it --- examples/16_network/pet_relative.py | 15 ++++++++++++++ src/py_eddy_tracker/observations/network.py | 22 ++++++++++++++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index 4d62987f..6610b763 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -136,6 +136,21 @@ ax.set_title(f"Clean network ({n_clean.infos()})") _ = n_clean.display_timeline(ax) + +# %% +# change splittint-merging events +# ------------------ +# change event where seg A split to B, then A merge into B, to A split to B then B merge into A +fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(15, 12), dpi=120) + +ax1.set_title(f"Clean network ({n_clean.infos()})") +n_clean.display_timeline(ax1) + +clean_modified = n_clean.copy() +clean_modified.correct_close_events(100) +ax2.set_title(f"resplitted network ({clean_modified.infos()})") +_ = clean_modified.display_timeline(ax2) + # %% # For further figure we will use clean path n = n_clean diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 47c468a9..ff52c571 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -241,6 +241,15 @@ def infos(self, label=""): return f"{len(self)} obs {unique(self.segment).shape[0]} segments" def correct_close_events(self, nb_days_max=20): + """ + transform event where + segment A split to B, then A merge into B + to + segment A split to B, then B merge to A + these events are filtered with `nb_days_max`, which the event have to take place in less than `nb_days_max` + + :param float nb_days_max: maximum time to search for splitting-merging event + """ _time = self.time segment = self.segment.copy() @@ -258,6 +267,9 @@ def correct_close_events(self, nb_days_max=20): for seg in sorted(segments_connexion.keys()): seg_slice, i_seg_p, i_seg_n = segments_connexion[seg] + + # the segment ID has to be corrected, because we may have changed it since + seg_corrected = segment[seg_slice.stop - 1] n_seg = segment[i_seg_n] # if segment has splitting @@ -266,11 +278,15 @@ def correct_close_events(self, nb_days_max=20): p2_seg = segment[i2_seg_p] # if it merge on the first in a certain time - if (p2_seg == seg) and (_time[i_seg_n] - _time[i2_seg_p] < nb_days_max): - - segment[i_seg_n : seg2_slice.stop] = seg + if (p2_seg == seg_corrected) and ( + _time[i_seg_n] - _time[i2_seg_p] < nb_days_max + ): + my_slice = slice(i_seg_n, seg2_slice.stop) + segment[my_slice] = seg_corrected previous_obs[i_seg_n] = seg_slice.stop - 1 + segments_connexion[seg_corrected][0] = my_slice + self.segment[:] = segment self.next_obs[:] = next_obs self.previous_obs[:] = previous_obs From 14934f25f5e059dd6c59161e3bb3bae9e9d99314 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Fri, 19 Mar 2021 10:23:23 +0100 Subject: [PATCH 118/249] correction correct_close_events and percent floating correct_close_events used segments and could not work with multiple network. Now it use segment_track_array and keep a track of changes, then apply changes on segments. changed precision on masking floating percent --- src/py_eddy_tracker/observations/network.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index ff52c571..b6d5c359 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -252,13 +252,17 @@ def correct_close_events(self, nb_days_max=20): """ _time = self.time - segment = self.segment.copy() + # segment used to correct and track changes + segment = self.segment_track_array.copy() + # final segment used to copy into self.segment + segment_copy = self.segment + segments_connexion = dict() previous_obs, next_obs = self.previous_obs, self.next_obs # record for every segments, the slice, indice of next obs & indice of previous obs - for i, seg, _ in self.iter_on(self.segment): + for i, seg, _ in self.iter_on(segment): if i.start == i.stop: continue @@ -270,6 +274,10 @@ def correct_close_events(self, nb_days_max=20): # the segment ID has to be corrected, because we may have changed it since seg_corrected = segment[seg_slice.stop - 1] + + # we keep the real segment number + seg_corrected_copy = segment_copy[seg_slice.stop - 1] + n_seg = segment[i_seg_n] # if segment has splitting @@ -282,13 +290,15 @@ def correct_close_events(self, nb_days_max=20): _time[i_seg_n] - _time[i2_seg_p] < nb_days_max ): my_slice = slice(i_seg_n, seg2_slice.stop) + # correct the factice segment segment[my_slice] = seg_corrected + # correct the good segment + segment_copy[my_slice] = seg_corrected_copy previous_obs[i_seg_n] = seg_slice.stop - 1 segments_connexion[seg_corrected][0] = my_slice - self.segment[:] = segment - self.next_obs[:] = next_obs + self.segment[:] = segment_copy self.previous_obs[:] = previous_obs self.sort() @@ -1116,7 +1126,7 @@ def extract_with_mask(self, mask): logger.warning("Empty dataset will be created") else: logger.info( - f"{nb_obs} observations will be extract ({nb_obs * 100. / self.shape[0]}%)" + f"{nb_obs} observations will be extract ({nb_obs / self.shape[0]:.3%})" ) for field in self.obs.dtype.descr: if field in ("next_obs", "previous_obs"): From d41f06cf73ba3d257cda6e55f24c1042f9906fda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Fri, 19 Mar 2021 10:52:02 +0100 Subject: [PATCH 119/249] add find_link add function to search which observations is directly linked with observation choosen. --- examples/16_network/pet_relative.py | 30 +++++++ src/py_eddy_tracker/observations/network.py | 96 +++++++++++++++++++++ 2 files changed, 126 insertions(+) diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index 6610b763..ff8c353b 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -151,6 +151,36 @@ ax2.set_title(f"resplitted network ({clean_modified.infos()})") _ = clean_modified.display_timeline(ax2) + +# %% +# keep only observations where water could propagate from an observation +# ---------------------------------------------------------------------- + +fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(15, 12), dpi=120) +i_observation = 600 +only_linked = n_clean.find_link(i_observation) + +for ax, dataset in zip([ax1, ax2], [n_clean, only_linked]): + dataset.display_timeline( + ax, field="segment", marker="+", lw=2, markersize=5, colors_mode="y" + ) + ax.scatter( + n_clean.time[i_observation], + n_clean.segment[i_observation], + marker="s", + s=50, + color="black", + zorder=200, + label="observation start", + alpha=0.6, + ) + ax.legend() + +ax1.set_title(f"full example ({n_clean.infos()})") +ax2.set_title(f"only linked observations ({only_linked.infos()})") +ax2.set_xlim(ax1.get_xlim()) +ax2.set_ylim(ax1.get_ylim()) + # %% # For further figure we will use clean path n = n_clean diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index b6d5c359..0b4c2e41 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -323,6 +323,102 @@ def obs_relative_order(self, i_obs): self.only_one_network() return self.segment_relative_order(self.segment[i_obs]) + def find_link(self, i_observations, forward=True, backward=False): + """ + find all observations where obs `i_observation` could be + in future or past. + + if forward=True, search all observation where water + from obs "i_observation" could go + + if backward=True, search all observation + where water from obs `i_observation` could come from + + :param int, iterable(int) i_observation: + indices of observation. Can be + int, or iterable of int. + :param bool forward, backward: + if forward, search observations after obs. + else mode==backward search before obs + + """ + + i_obs = ( + [i_observations] + if not hasattr(i_observations, "__iter__") + else i_observations + ) + + segment = self.segment_track_array + previous_obs, next_obs = self.previous_obs, self.next_obs + + segments_connexion = dict() + + for i_slice, seg, _ in self.iter_on(segment): + if i_slice.start == i_slice.stop: + continue + + i_p, i_n = previous_obs[i_slice.start], next_obs[i_slice.stop - 1] + p_seg, n_seg = segment[i_p], segment[i_n] + + # dumping slice into dict + if seg not in segments_connexion: + segments_connexion[seg] = [i_slice, [], []] + else: + segments_connexion[seg][0] = i_slice + + if i_p != -1: + + if p_seg not in segments_connexion: + segments_connexion[p_seg] = [None, [], []] + + # backward + segments_connexion[seg][2].append((i_slice.start, i_p, p_seg)) + # forward + segments_connexion[p_seg][1].append((i_p, i_slice.start, seg)) + + if i_n != -1: + if n_seg not in segments_connexion: + segments_connexion[n_seg] = [None, [], []] + + # forward + segments_connexion[seg][1].append((i_slice.stop - 1, i_n, n_seg)) + # backward + segments_connexion[n_seg][2].append((i_n, i_slice.stop - 1, seg)) + + mask = zeros(segment.size, dtype=bool) + + def func_forward(seg, indice): + seg_slice, _forward, _ = segments_connexion[seg] + + mask[indice : seg_slice.stop] = True + for i_begin, i_end, seg2 in _forward: + if i_begin < indice: + continue + + if not mask[i_end]: + func_forward(seg2, i_end) + + def func_backward(seg, indice): + seg_slice, _, _backward = segments_connexion[seg] + + mask[seg_slice.start : indice + 1] = True + for i_begin, i_end, seg2 in _backward: + if i_begin > indice: + continue + + if not mask[i_end]: + func_backward(seg2, i_end) + + for indice in i_obs: + if forward: + func_forward(segment[indice], indice) + + if backward: + func_backward(segment[indice], indice) + + return self.extract_with_mask(mask) + def connexions(self, multi_network=False): """ create dictionnary for each segments, gives the segments which interact with From d01bb3f876f19d7c689db83f52c252d59c864e19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Fri, 19 Mar 2021 15:20:14 +0100 Subject: [PATCH 120/249] fix typo in doc --- src/py_eddy_tracker/observations/network.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 0b4c2e41..2caba5a0 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -243,9 +243,12 @@ def infos(self, label=""): def correct_close_events(self, nb_days_max=20): """ transform event where - segment A split to B, then A merge into B + segment A split to B, then A merge into B + to - segment A split to B, then B merge to A + + segment A split to B, then B merge to A + these events are filtered with `nb_days_max`, which the event have to take place in less than `nb_days_max` :param float nb_days_max: maximum time to search for splitting-merging event @@ -334,7 +337,7 @@ def find_link(self, i_observations, forward=True, backward=False): if backward=True, search all observation where water from obs `i_observation` could come from - :param int, iterable(int) i_observation: + :param int,iterable(int) i_observation: indices of observation. Can be int, or iterable of int. :param bool forward, backward: From fe26b6e6ebe6a1ffb92f17ba258c502aaaa10424 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Mon, 22 Mar 2021 15:43:56 +0100 Subject: [PATCH 121/249] Add option to subsample network --- notebooks/README.md | 2 +- src/py_eddy_tracker/appli/network.py | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/notebooks/README.md b/notebooks/README.md index bbf88a8b..023dd1e2 100644 --- a/notebooks/README.md +++ b/notebooks/README.md @@ -1,4 +1,4 @@ # rm build/sphinx/ doc/python_module/ doc/gen_modules/ -rf -# rm doc/_autosummary/ doc/gen_modules - rf +# rm doc/_autosummary/ doc/gen_modules -rf python setup.py build_sphinx rsync -vrltp doc/python_module notebooks/. --include '*/' --include '*.ipynb' --exclude '*' --prune-empty-dirs diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index 35c86c45..cf31506d 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -74,7 +74,16 @@ def subset_network(): help="Nb of day which must be cover by network, first minimum number of day and last maximum number of day," "if value is negative, this bound won't be used", ) + parser.add_argument( + "--remove_dead_end", + nargs=2, + type=int, + help="Remove short dead end, first is for minimal obs number and second for minimal segment time to keep", + ) args = parser.parse_args() n = NetworkObservations.load_file(args.input) - n = n.longer_than(*args.length) + if args.length is not None: + n = n.longer_than(*args.length) + if args.remove_dead_end is not None: + n = n.remove_dead_end(*args.remove_dead_end) n.write_file(filename=args.out) From 3b3d4b551cfc12011f58a2d5f2d86bf9bc72f2a9 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Mon, 22 Mar 2021 15:44:50 +0100 Subject: [PATCH 122/249] simplification to get u/v --- src/py_eddy_tracker/dataset/grid.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index f782518e..60e6ddcf 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -1923,10 +1923,10 @@ def uv_for_advection(self, u_name, v_name, time_step=600, backward=False, factor :param str,array v_name: V field to advect obs :param int time_step: Number of second for each advection """ - u = (self.grid(u_name) if isinstance(u_name, str) else u_name).copy() * factor - v = (self.grid(v_name) if isinstance(v_name, str) else v_name).copy() * factor + u = (self.grid(u_name) if isinstance(u_name, str) else u_name).copy() + v = (self.grid(v_name) if isinstance(v_name, str) else v_name).copy() # N seconds / 1 degrees in m - coef = time_step * 180 / pi / self.EARTH_RADIUS + coef = time_step * 180 / pi / self.EARTH_RADIUS * factor u *= coef / cos(radians(self.y_c)) v *= coef if backward: From 80624d200a1636ddc7be1ae020bf0efecd837973 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Mon, 22 Mar 2021 15:45:26 +0100 Subject: [PATCH 123/249] Get obs in a list of polygons --- .../observations/observation.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 0c43aac3..88397fc6 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -1693,6 +1693,26 @@ def set_global_attr_netcdf(self, h_nc): for key, item in self.global_attr.items(): h_nc.setncattr(key, item) + def mask_from_polygons(self, polygons): + """ + Return mask for all observation in one of polygons list + + :param list((array,array)) polygons: list of x/y array which be used to identify observations + """ + x, y = polygons[0] + m = insidepoly( + self.longitude, self.latitude, x.reshape((1, -1)), y.reshape((1, -1)) + ) + for x, y in polygons[1:]: + m_ = ~m + m[m_] = insidepoly( + self.longitude[m_], + self.latitude[m_], + x.reshape((1, -1)), + y.reshape((1, -1)), + ) + return m + def extract_with_area(self, area, **kwargs): """ Extract geographically with a bounding box. From 0e0b44f678c0693ed03dc0858ce1d4d01d8c1a0d Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Mon, 22 Mar 2021 18:40:12 +0100 Subject: [PATCH 124/249] add method to remove trash (id == 0) --- src/py_eddy_tracker/observations/network.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 2caba5a0..a02decb6 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -1135,6 +1135,9 @@ def fully_connected(self): self.only_one_network() return self.tag_segment().shape[0] == 1 + def remove_trash(self): + return self.extract_with_mask(self.track != 0) + def plot(self, ax, ref=None, color_cycle=None, **kwargs): """ This function will draw path of each trajectory @@ -1152,7 +1155,7 @@ def plot(self, ax, ref=None, color_cycle=None, **kwargs): if "label" in kwargs: kwargs["label"] = self.format_label(kwargs["label"]) j = 0 - for i, _, _ in self.iter_on("segment"): + for i, _, _ in self.iter_on(self.segment_track_array): nb = i.stop - i.start if nb == 0: continue From 790cc10ecd039a11a2d23f7f28629998e2d03068 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Tue, 23 Mar 2021 15:22:52 +0100 Subject: [PATCH 125/249] Add method to normalize longitude for network --- src/py_eddy_tracker/observations/network.py | 27 +++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index a02decb6..1daf100b 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -542,6 +542,33 @@ def close_network(self, other, nb_obs_min=10, **kwargs): m[other.network_slice(i)] = True return other.extract_with_mask(m) + def normalize_longitude(self): + """Normalize all longitude + + Normalize longitude field and in the same range : + - longitude_max + - contour_lon_e (how to do if in raw) + - contour_lon_s (how to do if in raw) + """ + i_start, i_stop, _ = self.index_network + lon0 = (self.lon[i_start] - 180).repeat(i_stop - i_start) + logger.debug("Normalize longitude") + self.lon[:] = (self.lon - lon0) % 360 + lon0 + if "lon_max" in self.obs.dtype.names: + logger.debug("Normalize longitude_max") + self.lon_max[:] = (self.lon_max - self.lon + 180) % 360 + self.lon - 180 + if not self.raw_data: + if "contour_lon_e" in self.obs.dtype.names: + logger.debug("Normalize effective contour longitude") + self.contour_lon_e[:] = ( + (self.contour_lon_e.T - self.lon + 180) % 360 + self.lon - 180 + ).T + if "contour_lon_s" in self.obs.dtype.names: + logger.debug("Normalize speed contour longitude") + self.contour_lon_s[:] = ( + (self.contour_lon_s.T - self.lon + 180) % 360 + self.lon - 180 + ).T + def numbering_segment(self, start=0): """ New numbering of segment From 9016b1177782070f52daaff97b1b91858d967656 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Tue, 23 Mar 2021 17:47:13 +0100 Subject: [PATCH 126/249] Bug correction in wrapping in advection --- src/py_eddy_tracker/dataset/grid.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 60e6ddcf..9bca18e6 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -2005,7 +2005,7 @@ def advect_rk4(x_g, y_g, u_g, v_g, m_g, x, y, m, nb_step): x_ref, y_ref = x_g[0], y_g[0] x_step, y_step = x_g[1] - x_ref, y_g[1] - y_ref is_circular = abs(x_g[-1] % 360 - (x_g[0] - x_step) % 360) < 1e-5 - nb_x_ = x_g.size - 2 + nb_x_ = x_g.size nb_x = nb_x_ if is_circular else 0 # cache i_cache, j_cache = -1000000, -1000000 @@ -2108,7 +2108,7 @@ def advect(x_g, y_g, u_g, v_g, m_g, x, y, m, nb_step): x_ref, y_ref = x_g[0], y_g[0] x_step, y_step = x_g[1] - x_ref, y_g[1] - y_ref is_circular = abs(x_g[-1] % 360 - (x_g[0] - x_step) % 360) < 1e-5 - nb_x_ = x_g.size - 2 + nb_x_ = x_g.size nb_x = nb_x_ if is_circular else 0 # Indices which should be never exist i0_old, j0_old = -100000, -100000 @@ -2472,7 +2472,7 @@ def advect_t(x_g, y_g, u_g0, v_g0, m_g0, u_g1, v_g1, m_g1, x, y, m, weigths, hal x_ref, y_ref = x_g[0], y_g[0] x_step, y_step = x_g[1] - x_ref, y_g[1] - y_ref is_circular = abs(x_g[-1] % 360 - (x_g[0] - x_step) % 360) < 1e-5 - nb_x_ = x_g.size - 2 + nb_x_ = x_g.size nb_x = nb_x_ if is_circular else 0 # Indices which should be never exist i0_old, j0_old = -100000, -100000 @@ -2598,7 +2598,7 @@ def advect_t_rk4( x_ref, y_ref = x_g[0], y_g[0] x_step, y_step = x_g[1] - x_ref, y_g[1] - y_ref is_circular = abs(x_g[-1] % 360 - (x_g[0] - x_step) % 360) < 1e-5 - nb_x_ = x_g.size - 2 + nb_x_ = x_g.size nb_x = nb_x_ if is_circular else 0 # cache i_cache, j_cache = -1000000, -1000000 From 930c9c6b6f8513c543408c5e6c19c6435851c72c Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Wed, 24 Mar 2021 14:23:44 +0100 Subject: [PATCH 127/249] Add another LAVD example --- .../pet_lavd_detection.py | 218 ++++++++++++++++++ examples/16_network/pet_relative.py | 65 +++--- notebooks/README.md | 3 +- .../pet_lavd_detection.ipynb | 202 ++++++++++++++++ .../16_network/pet_relative.ipynb | 36 +++ src/py_eddy_tracker/eddy_feature.py | 1 + src/py_eddy_tracker/observations/network.py | 2 +- 7 files changed, 487 insertions(+), 40 deletions(-) create mode 100644 examples/07_cube_manipulation/pet_lavd_detection.py create mode 100644 notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb diff --git a/examples/07_cube_manipulation/pet_lavd_detection.py b/examples/07_cube_manipulation/pet_lavd_detection.py new file mode 100644 index 00000000..4f46b78f --- /dev/null +++ b/examples/07_cube_manipulation/pet_lavd_detection.py @@ -0,0 +1,218 @@ +""" +LAVD detection and geometric detection +====================================== + +Naive method to reproduce LAVD(Lagrangian-Averaged Vorticity deviation). +In the current example we didn't remove a mean vorticity. + +Method are described here: + + - Abernathey, Ryan, and George Haller. "Transport by Lagrangian Vortices in the Eastern Pacific", + Journal of Physical Oceanography 48, 3 (2018): 667-685, accessed Feb 16, 2021, + https://doi.org/10.1175/JPO-D-17-0102.1 + - `Transport by Coherent Lagrangian Vortices`_, + R. Abernathey, Sinha A., Tarshish N., Liu T., Zhang C., Haller G., 2019, + Talk a t the Sources and Sinks of Ocean Mesoscale Eddy Energy CLIVAR Workshop + +.. _Transport by Coherent Lagrangian Vortices: + https://usclivar.org/sites/default/files/meetings/2019/presentations/Aberernathey_CLIVAR.pdf + +""" +from datetime import datetime + +from matplotlib import pyplot as plt +from numpy import arange, isnan, ma, meshgrid, zeros + +import py_eddy_tracker.gui +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") + + +# %% +class LAVDGrid(RegularGridDataset): + def init_speed_coef(self, uname="u", vname="v"): + """Hack to be able to identify eddy with LAVD field""" + self._speed_ev = self.grid("lavd") + + @classmethod + def from_(cls, x, y, z): + z.mask += isnan(z.data) + datas = dict(lavd=z, lon=x, lat=y) + return cls.with_array(coordinates=("lon", "lat"), datas=datas, centered=True) + + +# %% +def start_ax(title="", dpi=90): + fig = plt.figure(figsize=(12, 5), dpi=dpi) + ax = fig.add_axes([0.05, 0.08, 0.9, 0.9], projection="full_axes") + ax.set_xlim(-6, 36), ax.set_ylim(31, 45) + ax.set_title(title) + return fig, ax, ax.text(3, 32, "", fontsize=20) + + +def update_axes(ax, mappable=None): + ax.grid() + if mappable: + cb = plt.colorbar( + mappable, + cax=ax.figure.add_axes([0.05, 0.1, 0.9, 0.01]), + orientation="horizontal", + ) + cb.set_label("LAVD at initial position") + return cb + + +kw_lavd = dict(vmin=0, vmax=2e-5, cmap="viridis") + +# %% +# Data +# ---- + +# Load data cube of 3 month +c = GridCollection.from_netcdf_cube( + get_path("dt_med_allsat_phy_l4_2005T2.nc"), + "longitude", + "latitude", + "time", + heigth="adt", +) + +# Add vorticity at each time step +for g in c: + 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 + +# %% +# Particles +# --------- + +# Time properties, for example with advection only 25 days +nb_days, step_by_day = 25, 6 +nb_time = step_by_day * nb_days +kw_p = dict(nb_step=1, time_step=86400 / step_by_day) +t0 = 20236 +t0_grid = c[t0] +# Geographic properties, we use a coarser resolution for time consuming reasons +step = 1 / 32.0 +x_g, y_g = arange(-6, 36, step), arange(30, 46, step) +x0, y0 = meshgrid(x_g, y_g) +original_shape = x0.shape +x0, y0 = x0.reshape(-1), y0.reshape(-1) +# Get all particles in defined area +m = ~isnan(t0_grid.interp("vort", x0, y0)) +x0, y0 = x0[m], y0[m] +print(f"{x0.size} particles advected") +# Gridded mask +m = m.reshape(original_shape) + +# %% +# LAVD forward (dynamic field) +# ---------------------------- +lavd = zeros(original_shape) +lavd_ = lavd[m] +p = c.advect(x0.copy(), y0.copy(), "u", "v", t_init=t0, **kw_p) +for _ in range(nb_time): + t, x, y = p.__next__() + lavd_ += abs(c.interp("vort", t / 86400.0, x, y)) +lavd[m] = lavd_ / nb_time +# Put LAVD result in a standard py eddy tracker grid +lavd_forward = LAVDGrid.from_(x_g, y_g, ma.array(lavd, mask=~m).T) +# Display +fig, ax, _ = start_ax("LAVD with a forward advection") +mappable = lavd_forward.display(ax, "lavd", **kw_lavd) +_ = update_axes(ax, mappable) + +# %% +# LAVD backward (dynamic field) +# ----------------------------- +lavd = zeros(original_shape) +lavd_ = lavd[m] +p = c.advect(x0.copy(), y0.copy(), "u", "v", t_init=t0, backward=True, **kw_p) +for i in range(nb_time): + t, x, y = p.__next__() + lavd_ += abs(c.interp("vort", t / 86400.0, x, y)) +lavd[m] = lavd_ / nb_time +# Put LAVD result in a standard py eddy tracker grid +lavd_backward = LAVDGrid.from_(x_g, y_g, ma.array(lavd, mask=~m).T) +# Display +fig, ax, _ = start_ax("LAVD with a backward advection") +mappable = lavd_backward.display(ax, "lavd", **kw_lavd) +_ = update_axes(ax, mappable) + +# %% +# LAVD forward (static field) +# --------------------------- +lavd = zeros(original_shape) +lavd_ = lavd[m] +p = t0_grid.advect(x0.copy(), y0.copy(), "u", "v", **kw_p) +for _ in range(nb_time): + x, y = p.__next__() + lavd_ += abs(t0_grid.interp("vort", x, y)) +lavd[m] = lavd_ / nb_time +# Put LAVD result in a standard py eddy tracker grid +lavd_forward_static = LAVDGrid.from_(x_g, y_g, ma.array(lavd, mask=~m).T) +# Display +fig, ax, _ = start_ax("LAVD with a forward advection on a static velocity field") +mappable = lavd_forward_static.display(ax, "lavd", **kw_lavd) +_ = update_axes(ax, mappable) + +# %% +# LAVD backward (static field) +# ---------------------------- +lavd = zeros(original_shape) +lavd_ = lavd[m] +p = t0_grid.advect(x0.copy(), y0.copy(), "u", "v", backward=True, **kw_p) +for i in range(nb_time): + x, y = p.__next__() + lavd_ += abs(t0_grid.interp("vort", x, y)) +lavd[m] = lavd_ / nb_time +# Put LAVD result in a standard py eddy tracker grid +lavd_backward_static = LAVDGrid.from_(x_g, y_g, ma.array(lavd, mask=~m).T) +# Display +fig, ax, _ = start_ax("LAVD with a backward advection on a static velocity field") +mappable = lavd_backward_static.display(ax, "lavd", **kw_lavd) +_ = update_axes(ax, mappable) + +# %% +# Contourdetection +# ---------------- +# To extract contour from LAVD grid, we will used method design for SSH, with some hacks and adapted options. +# It will produce false amplitude and speed. +kw_ident = dict( + force_speed_unit="m/s", + force_height_unit="m", + pixel_limit=(40, 200000), + date=datetime(2005, 5, 18), + uname=None, + vname=None, + grid_height="lavd", + shape_error=70, + step=1e-6, +) +fig, ax, _ = start_ax("Detection of eddies with several method") +t0_grid.bessel_high_filter("adt", 700) +a, c = t0_grid.eddy_identification( + "adt", "u", "v", kw_ident["date"], step=0.002, shape_error=70 +) +kw_ed = dict(ax=ax, intern=True, ref=-10) +a.filled( + facecolors="#FFEFCD", label="Anticyclonic SSH detection {nb_obs} eddies", **kw_ed +) +c.filled(facecolors="#DEDEDE", label="Cyclonic SSH detection {nb_obs} eddies", **kw_ed) +kw_cont = dict(ax=ax, extern_only=True, ls="-", ref=-10) +forward, _ = lavd_forward.eddy_identification(**kw_ident) +forward.display(label="LAVD forward {nb_obs} eddies", color="g", **kw_cont) +backward, _ = lavd_backward.eddy_identification(**kw_ident) +backward.display(label="LAVD backward {nb_obs} eddies", color="r", **kw_cont) +forward, _ = lavd_forward_static.eddy_identification(**kw_ident) +forward.display(label="LAVD forward static {nb_obs} eddies", color="cyan", **kw_cont) +backward, _ = lavd_backward_static.eddy_identification(**kw_ident) +backward.display( + label="LAVD backward static {nb_obs} eddies", color="orange", **kw_cont +) +ax.legend() +update_axes(ax) diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index ff8c353b..456b008d 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -136,54 +136,46 @@ ax.set_title(f"Clean network ({n_clean.infos()})") _ = n_clean.display_timeline(ax) +# %% +# For further figure we will use clean path +n = n_clean # %% -# change splittint-merging events -# ------------------ +# Change splitting-merging events +# ------------------------------- # change event where seg A split to B, then A merge into B, to A split to B then B merge into A -fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(15, 12), dpi=120) - -ax1.set_title(f"Clean network ({n_clean.infos()})") -n_clean.display_timeline(ax1) +fig = plt.figure(figsize=(15, 12)) +ax = fig.add_axes([0.04, 0.54, 0.90, 0.40]) +ax.set_title(f"Clean network ({n.infos()})") +n.display_timeline(ax) -clean_modified = n_clean.copy() -clean_modified.correct_close_events(100) -ax2.set_title(f"resplitted network ({clean_modified.infos()})") -_ = clean_modified.display_timeline(ax2) +clean_modified = n.copy() +# If it's happen in less than 40 days +clean_modified.correct_close_events(40) +ax = fig.add_axes([0.04, 0.04, 0.90, 0.40]) +ax.set_title(f"resplitted network ({clean_modified.infos()})") +_ = clean_modified.display_timeline(ax) # %% -# keep only observations where water could propagate from an observation +# Keep only observations where water could propagate from an observation # ---------------------------------------------------------------------- - -fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(15, 12), dpi=120) i_observation = 600 -only_linked = n_clean.find_link(i_observation) - -for ax, dataset in zip([ax1, ax2], [n_clean, only_linked]): - dataset.display_timeline( - ax, field="segment", marker="+", lw=2, markersize=5, colors_mode="y" - ) - ax.scatter( - n_clean.time[i_observation], - n_clean.segment[i_observation], - marker="s", - s=50, - color="black", - zorder=200, - label="observation start", - alpha=0.6, - ) +only_linked = n.find_link(i_observation) + +fig = plt.figure(figsize=(15, 12)) +ax1 = fig.add_axes([0.04, 0.54, 0.90, 0.40]) +ax2 = fig.add_axes([0.04, 0.04, 0.90, 0.40]) + +kw = dict(marker="s", s=300, color="black", zorder=200, label="observation start") +for ax, dataset in zip([ax1, ax2], [n, only_linked]): + dataset.display_timeline(ax, field="segment", lw=2, markersize=5, colors_mode="y") + ax.scatter(n.time[i_observation], n.segment[i_observation], **kw) ax.legend() -ax1.set_title(f"full example ({n_clean.infos()})") +ax1.set_title(f"full example ({n.infos()})") ax2.set_title(f"only linked observations ({only_linked.infos()})") -ax2.set_xlim(ax1.get_xlim()) -ax2.set_ylim(ax1.get_ylim()) - -# %% -# For further figure we will use clean path -n = n_clean +_ = ax2.set_xlim(ax1.get_xlim()), ax2.set_ylim(ax1.get_ylim()) # %% # Keep close relative @@ -299,7 +291,6 @@ ax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid() m1 - # %% # Get spliting event # ------------------ diff --git a/notebooks/README.md b/notebooks/README.md index 023dd1e2..fd8971aa 100644 --- a/notebooks/README.md +++ b/notebooks/README.md @@ -1,4 +1,3 @@ -# rm build/sphinx/ doc/python_module/ doc/gen_modules/ -rf -# rm doc/_autosummary/ doc/gen_modules -rf +# rm build/sphinx/ doc/python_module/ doc/gen_modules/ doc/_autosummary/ -rf python setup.py build_sphinx rsync -vrltp doc/python_module notebooks/. --include '*/' --include '*.ipynb' --exclude '*' --prune-empty-dirs diff --git a/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb b/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb new file mode 100644 index 00000000..626dcada --- /dev/null +++ b/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb @@ -0,0 +1,202 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# LAVD detection and geometric detection\n\nNaive method to reproduce LAVD(Lagrangian-Averaged Vorticity deviation).\nIn the current example we didn't remove a mean vorticity.\n\nMethod are described here:\n\n - Abernathey, Ryan, and George Haller. \"Transport by Lagrangian Vortices in the Eastern Pacific\",\n Journal of Physical Oceanography 48, 3 (2018): 667-685, accessed Feb 16, 2021,\n https://doi.org/10.1175/JPO-D-17-0102.1\n - `Transport by Coherent Lagrangian Vortices`_,\n R. Abernathey, Sinha A., Tarshish N., Liu T., Zhang C., Haller G., 2019,\n Talk a t the Sources and Sinks of Ocean Mesoscale Eddy Energy CLIVAR Workshop\n\n https://usclivar.org/sites/default/files/meetings/2019/presentations/Aberernathey_CLIVAR.pdf\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from datetime import datetime\n\nfrom matplotlib import pyplot as plt\nfrom numpy import arange, isnan, ma, meshgrid, zeros\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.dataset.grid import GridCollection, RegularGridDataset\n\nstart_logger().setLevel(\"ERROR\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "class LAVDGrid(RegularGridDataset):\n def init_speed_coef(self, uname=\"u\", vname=\"v\"):\n \"\"\"Hack to be able to identify eddy with LAVD field\"\"\"\n self._speed_ev = self.grid(\"lavd\")\n\n @classmethod\n def from_(cls, x, y, z):\n z.mask += isnan(z.data)\n datas = dict(lavd=z, lon=x, lat=y)\n return cls.with_array(coordinates=(\"lon\", \"lat\"), datas=datas, centered=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def start_ax(title=\"\", dpi=90):\n fig = plt.figure(figsize=(12, 5), dpi=dpi)\n ax = fig.add_axes([0.05, 0.08, 0.9, 0.9], projection=\"full_axes\")\n ax.set_xlim(-6, 36), ax.set_ylim(31, 45)\n ax.set_title(title)\n return fig, ax, ax.text(3, 32, \"\", fontsize=20)\n\n\ndef update_axes(ax, mappable=None):\n ax.grid()\n if mappable:\n cb = plt.colorbar(\n mappable,\n cax=ax.figure.add_axes([0.05, 0.1, 0.9, 0.01]),\n orientation=\"horizontal\",\n )\n cb.set_label(\"LAVD at initial position\")\n return cb\n\n\nkw_lavd = dict(vmin=0, vmax=2e-5, cmap=\"viridis\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Data\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Load data cube of 3 month\nc = GridCollection.from_netcdf_cube(\n get_path(\"dt_med_allsat_phy_l4_2005T2.nc\"),\n \"longitude\",\n \"latitude\",\n \"time\",\n heigth=\"adt\",\n)\n\n# Add vorticity at each time step\nfor g in c:\n u_y = g.compute_stencil(g.grid(\"u\"), vertical=True)\n v_x = g.compute_stencil(g.grid(\"v\"))\n g.vars[\"vort\"] = v_x - u_y" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Particles\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Time properties, for example with advection only 25 days\nnb_days, step_by_day = 25, 6\nnb_time = step_by_day * nb_days\nkw_p = dict(nb_step=1, time_step=86400 / step_by_day)\nt0 = 20236\nt0_grid = c[t0]\n# Geographic properties, we use a coarser resolution for time consuming reasons\nstep = 1 / 32.0\nx_g, y_g = arange(-6, 36, step), arange(30, 46, step)\nx0, y0 = meshgrid(x_g, y_g)\noriginal_shape = x0.shape\nx0, y0 = x0.reshape(-1), y0.reshape(-1)\n# Get all particles in defined area\nm = ~isnan(t0_grid.interp(\"vort\", x0, y0))\nx0, y0 = x0[m], y0[m]\nprint(f\"{x0.size} particles advected\")\n# Gridded mask\nm = m.reshape(original_shape)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## LAVD forward (dynamic field)\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "lavd = zeros(original_shape)\nlavd_ = lavd[m]\np = c.advect(x0.copy(), y0.copy(), \"u\", \"v\", t_init=t0, **kw_p)\nfor _ in range(nb_time):\n t, x, y = p.__next__()\n lavd_ += abs(c.interp(\"vort\", t / 86400.0, x, y))\nlavd[m] = lavd_ / nb_time\n# Put LAVD result in a standard py eddy tracker grid\nlavd_forward = LAVDGrid.from_(x_g, y_g, ma.array(lavd, mask=~m).T)\n# Display\nfig, ax, _ = start_ax(\"LAVD with a forward advection\")\nmappable = lavd_forward.display(ax, \"lavd\", **kw_lavd)\n_ = update_axes(ax, mappable)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## LAVD backward (dynamic field)\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "lavd = zeros(original_shape)\nlavd_ = lavd[m]\np = c.advect(x0.copy(), y0.copy(), \"u\", \"v\", t_init=t0, backward=True, **kw_p)\nfor i in range(nb_time):\n t, x, y = p.__next__()\n lavd_ += abs(c.interp(\"vort\", t / 86400.0, x, y))\nlavd[m] = lavd_ / nb_time\n# Put LAVD result in a standard py eddy tracker grid\nlavd_backward = LAVDGrid.from_(x_g, y_g, ma.array(lavd, mask=~m).T)\n# Display\nfig, ax, _ = start_ax(\"LAVD with a backward advection\")\nmappable = lavd_backward.display(ax, \"lavd\", **kw_lavd)\n_ = update_axes(ax, mappable)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## LAVD forward (static field)\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "lavd = zeros(original_shape)\nlavd_ = lavd[m]\np = t0_grid.advect(x0.copy(), y0.copy(), \"u\", \"v\", **kw_p)\nfor _ in range(nb_time):\n x, y = p.__next__()\n lavd_ += abs(t0_grid.interp(\"vort\", x, y))\nlavd[m] = lavd_ / nb_time\n# Put LAVD result in a standard py eddy tracker grid\nlavd_forward_static = LAVDGrid.from_(x_g, y_g, ma.array(lavd, mask=~m).T)\n# Display\nfig, ax, _ = start_ax(\"LAVD with a forward advection on a static velocity field\")\nmappable = lavd_forward_static.display(ax, \"lavd\", **kw_lavd)\n_ = update_axes(ax, mappable)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## LAVD backward (static field)\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "lavd = zeros(original_shape)\nlavd_ = lavd[m]\np = t0_grid.advect(x0.copy(), y0.copy(), \"u\", \"v\", backward=True, **kw_p)\nfor i in range(nb_time):\n x, y = p.__next__()\n lavd_ += abs(t0_grid.interp(\"vort\", x, y))\nlavd[m] = lavd_ / nb_time\n# Put LAVD result in a standard py eddy tracker grid\nlavd_backward_static = LAVDGrid.from_(x_g, y_g, ma.array(lavd, mask=~m).T)\n# Display\nfig, ax, _ = start_ax(\"LAVD with a backward advection on a static velocity field\")\nmappable = lavd_backward_static.display(ax, \"lavd\", **kw_lavd)\n_ = update_axes(ax, mappable)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Contourdetection\nTo extract contour from LAVD grid, we will used method design for SSH, with some hacks and adapted options.\nIt will produce false amplitude and speed.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "kw_ident = dict(\n force_speed_unit=\"m/s\",\n force_height_unit=\"m\",\n pixel_limit=(40, 200000),\n date=datetime(2005, 5, 18),\n uname=None,\n vname=None,\n grid_height=\"lavd\",\n shape_error=70,\n step=1e-6,\n)\nfig, ax, _ = start_ax(\"Detection of eddies with several method\")\nt0_grid.bessel_high_filter(\"adt\", 700)\na, c = t0_grid.eddy_identification(\n \"adt\", \"u\", \"v\", kw_ident[\"date\"], step=0.002, shape_error=70\n)\nkw_ed = dict(ax=ax, intern=True, ref=-10)\na.filled(\n facecolors=\"#FFEFCD\", label=\"Anticyclonic SSH detection {nb_obs} eddies\", **kw_ed\n)\nc.filled(facecolors=\"#DEDEDE\", label=\"Cyclonic SSH detection {nb_obs} eddies\", **kw_ed)\nkw_cont = dict(ax=ax, extern_only=True, ls=\"-\", ref=-10)\nforward, _ = lavd_forward.eddy_identification(**kw_ident)\nforward.display(label=\"LAVD forward {nb_obs} eddies\", color=\"g\", **kw_cont)\nbackward, _ = lavd_backward.eddy_identification(**kw_ident)\nbackward.display(label=\"LAVD backward {nb_obs} eddies\", color=\"r\", **kw_cont)\nforward, _ = lavd_forward_static.eddy_identification(**kw_ident)\nforward.display(label=\"LAVD forward static {nb_obs} eddies\", color=\"cyan\", **kw_cont)\nbackward, _ = lavd_backward_static.eddy_identification(**kw_ident)\nbackward.display(\n label=\"LAVD backward static {nb_obs} eddies\", color=\"orange\", **kw_cont\n)\nax.legend()\nupdate_axes(ax)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/notebooks/python_module/16_network/pet_relative.ipynb b/notebooks/python_module/16_network/pet_relative.ipynb index e8252900..85744514 100644 --- a/notebooks/python_module/16_network/pet_relative.ipynb +++ b/notebooks/python_module/16_network/pet_relative.ipynb @@ -252,6 +252,42 @@ "n = n_clean" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Change splitting-merging events\nchange event where seg A split to B, then A merge into B, to A split to B then B merge into A\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(15, 12))\nax = fig.add_axes([0.04, 0.54, 0.90, 0.40])\nax.set_title(f\"Clean network ({n.infos()})\")\nn.display_timeline(ax)\n\nclean_modified = n.copy()\n# If it's happen in less than 40 days\nclean_modified.correct_close_events(40)\n\nax = fig.add_axes([0.04, 0.04, 0.90, 0.40])\nax.set_title(f\"resplitted network ({clean_modified.infos()})\")\n_ = clean_modified.display_timeline(ax)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Keep only observations where water could propagate from an observation\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "i_observation = 600\nonly_linked = n.find_link(i_observation)\n\nfig = plt.figure(figsize=(15, 12))\nax1 = fig.add_axes([0.04, 0.54, 0.90, 0.40])\nax2 = fig.add_axes([0.04, 0.04, 0.90, 0.40])\n\nkw = dict(marker=\"s\", s=300, color=\"black\", zorder=200, label=\"observation start\")\nfor ax, dataset in zip([ax1, ax2], [n, only_linked]):\n dataset.display_timeline(ax, field=\"segment\", lw=2, markersize=5, colors_mode=\"y\")\n ax.scatter(n.time[i_observation], n.segment[i_observation], **kw)\n ax.legend()\n\nax1.set_title(f\"full example ({n.infos()})\")\nax2.set_title(f\"only linked observations ({only_linked.infos()})\")\n_ = ax2.set_xlim(ax1.get_xlim()), ax2.set_ylim(ax1.get_ylim())" + ] + }, { "cell_type": "markdown", "metadata": {}, diff --git a/src/py_eddy_tracker/eddy_feature.py b/src/py_eddy_tracker/eddy_feature.py index 48b6f2d7..3e6c86ea 100644 --- a/src/py_eddy_tracker/eddy_feature.py +++ b/src/py_eddy_tracker/eddy_feature.py @@ -173,6 +173,7 @@ def all_pixels_above_h0(self, level): self.mle, -1, ) + # After we use grid.data because index are in contour and we check before than no pixel are hide nb = len(lmi_i) if nb == 0: logger.warning( diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 1daf100b..1955d5fb 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -645,7 +645,7 @@ def display_timeline( j = 0 line_kw = dict( ls="-", - marker=".", + marker="+", markersize=6, zorder=1, lw=3, From a792e21e4b2e50d340ec77b76277ee7f64ed81d4 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Thu, 25 Mar 2021 15:30:44 +0100 Subject: [PATCH 128/249] Add network example with particle --- .../pet_lavd_detection.py | 4 +- examples/16_network/pet_follow_particle.py | 251 ++++++++++++++++++ examples/16_network/pet_segmentation_anim.py | 2 +- .../pet_lavd_detection.ipynb | 2 +- .../16_network/pet_follow_particle.ipynb | 177 ++++++++++++ .../16_network/pet_segmentation_anim.ipynb | 2 +- src/py_eddy_tracker/appli/network.py | 2 +- src/py_eddy_tracker/dataset/grid.py | 2 +- 8 files changed, 435 insertions(+), 7 deletions(-) create mode 100644 examples/16_network/pet_follow_particle.py create mode 100644 notebooks/python_module/16_network/pet_follow_particle.ipynb diff --git a/examples/07_cube_manipulation/pet_lavd_detection.py b/examples/07_cube_manipulation/pet_lavd_detection.py index 4f46b78f..dad99498 100644 --- a/examples/07_cube_manipulation/pet_lavd_detection.py +++ b/examples/07_cube_manipulation/pet_lavd_detection.py @@ -178,8 +178,8 @@ def update_axes(ax, mappable=None): _ = update_axes(ax, mappable) # %% -# Contourdetection -# ---------------- +# Contour detection +# ----------------- # To extract contour from LAVD grid, we will used method design for SSH, with some hacks and adapted options. # It will produce false amplitude and speed. kw_ident = dict( diff --git a/examples/16_network/pet_follow_particle.py b/examples/16_network/pet_follow_particle.py new file mode 100644 index 00000000..dee3ab84 --- /dev/null +++ b/examples/16_network/pet_follow_particle.py @@ -0,0 +1,251 @@ +""" +Follow particle +=============== + +""" +import re + +from matplotlib import colors +from matplotlib import pyplot as plt +from matplotlib.animation import FuncAnimation +from numba import njit +from numba import types as nb_types +from numpy import arange, meshgrid, ones, unique, where, zeros + +from py_eddy_tracker import start_logger +from py_eddy_tracker.appli.gui import Anim +from py_eddy_tracker.data import get_path +from py_eddy_tracker.dataset.grid import GridCollection +from py_eddy_tracker.observations.network import NetworkObservations + +start_logger().setLevel("ERROR") + + +# %% +class VideoAnimation(FuncAnimation): + def _repr_html_(self, *args, **kwargs): + """To get video in html and have a player""" + 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)) +ax = fig.add_axes([0.05, 0.05, 0.9, 0.9]) +_ = n.display_timeline(ax, field="longitude", marker="+", lw=2, markersize=5) + +# %% +# Animation +# --------- +# Particle settings +t_snapshot = 20200 +step = 1 / 50.0 +x, y = meshgrid(arange(20, 36, step), arange(30, 46, step)) +N = 6 +x_f, y_f = x[::N, ::N].copy(), y[::N, ::N].copy() +x, y = x.reshape(-1), y.reshape(-1) +x_f, y_f = x_f.reshape(-1), y_f.reshape(-1) +n_ = n.extract_with_mask(n.time == t_snapshot) +index = n_.contains(x, y, intern=True) +m = index != -1 +index = n_.segment[index[m]] +index_ = unique(index) +x, y = x[m], y[m] +m = ~n_.inside(x_f, y_f, intern=True) +x_f, y_f = x_f[m], y_f[m] + +# %% +# Animation +cmap = colors.ListedColormap(list(n.COLORS), name="from_list", N=n.segment.max() + 1) +a = Anim( + n, + intern=False, + figsize=(12, 6), + nb_step=1, + dpi=60, + field_color="segment", + field_txt="segment", + cmap=cmap, +) +a.fig.suptitle(""), a.ax.set_xlim(24, 36), a.ax.set_ylim(30, 36) +a.txt.set_position((25, 31)) + +step = 0.25 +kw_p = dict(nb_step=2, time_step=86400 * step * 0.5, t_init=t_snapshot - 2 * step) + +mappables = dict() +particules = c.advect(x, y, "u", "v", **kw_p) +filament = c.filament(x_f, y_f, "u", "v", **kw_p, filament_size=3) +kw = dict(ls="", marker=".", markersize=0.25) +for k in index_: + m = k == index + mappables[k] = a.ax.plot([], [], color=cmap(k), **kw)[0] +m_filament = a.ax.plot([], [], lw=0.25, color="gray")[0] + + +def update(frame): + tt, xt, yt = particules.__next__() + for k, mappable in mappables.items(): + m = index == k + mappable.set_data(xt[m], yt[m]) + tt, xt, yt = filament.__next__() + m_filament.set_data(xt, yt) + if frame % 1 == 0: + a.func_animation(frame) + + +ani = VideoAnimation(a.fig, update, frames=arange(20200, 20269, step), interval=200) + + +# %% +# In which observations are the particle +# -------------------------------------- +def advect(x, y, c, t0, delta_t): + """ + Advect particle from t0 to t0 + delta_t, with data cube. + """ + kw = dict(nb_step=6, time_step=86400 / 6) + if delta_t < 0: + kw["backward"] = True + delta_t = -delta_t + p = c.advect(x, y, "u", "v", t_init=t0, **kw) + for _ in range(delta_t): + t, x, y = p.__next__() + return t, x, y + + +def particle_candidate(x, y, c, eddies, t_start, i_target, pct, **kwargs): + # Obs from initial time + m_start = eddies.time == t_start + e = eddies.extract_with_mask(m_start) + # to be able to get global index + translate_start = where(m_start)[0] + # Identify particle in eddies(only in core) + i_start = e.contains(x, y, intern=True) + m = i_start != -1 + x, y, i_start = x[m], y[m], i_start[m] + # Advect + t_end, x, y = advect(x, y, c, t_start, **kwargs) + # eddies at last date + m_end = eddies.time == t_end / 86400 + e_end = eddies.extract_with_mask(m_end) + # to be able to get global index + translate_end = where(m_end)[0] + # Id eddies for each alive particle(in core and extern) + i_end = e_end.contains(x, y) + # compute matrix and filled target array + get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct) + + +@njit(cache=True) +def get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct): + nb_start, nb_end = translate_start.size, translate_end.size + # Matrix which will store count for every couple + count = zeros((nb_start, nb_end), dtype=nb_types.int32) + # Number of particle in each origin observation + ref = zeros(nb_start, dtype=nb_types.int32) + # For each particle + for i in range(i_start.size): + i_end_ = i_end[i] + i_start_ = i_start[i] + if i_end_ != -1: + count[i_start_, i_end_] += 1 + ref[i_start_] += 1 + for i in range(nb_start): + for j in range(nb_end): + pct_ = count[i, j] + # If there are particle from i to j + if pct_ != 0: + # Get percent + pct_ = pct_ / ref[i] * 100.0 + # Get indices in full dataset + i_, j_ = translate_start[i], translate_end[j] + pct_0 = pct[i_, 0] + if pct_ > pct_0: + pct[i_, 1] = pct_0 + pct[i_, 0] = pct_ + i_target[i_, 1] = i_target[i_, 0] + i_target[i_, 0] = j_ + elif pct_ > pct[i_, 1]: + pct[i_, 1] = pct_ + i_target[i_, 1] = j_ + return i_target, pct + + +# %% +# Particle advection +# ^^^^^^^^^^^^^^^^^^ +step = 1 / 60.0 + +x, y = meshgrid(arange(20, 36, step), arange(30, 46, step)) +x0, y0 = x.reshape(-1), y.reshape(-1) +t_start, t_end = n.period +dt = 14 + +shape = (n.obs.size, 2) +# Forward run +i_target_f, pct_target_f = -ones(shape, dtype="i4"), zeros(shape, dtype="i1") +for t in range(t_start, t_end - dt): + particle_candidate(x0, y0, c, n, t, i_target_f, pct_target_f, delta_t=dt) + +# Backward run +i_target_b, pct_target_b = -ones(shape, dtype="i4"), zeros(shape, dtype="i1") +for t in range(t_start + dt, t_end): + particle_candidate(x0, y0, c, n, t, i_target_b, pct_target_b, delta_t=-dt) + +# %% +fig = plt.figure(figsize=(10, 10)) +ax_1st_b = fig.add_axes([0.05, 0.52, 0.45, 0.45]) +ax_2nd_b = fig.add_axes([0.05, 0.05, 0.45, 0.45]) +ax_1st_f = fig.add_axes([0.52, 0.52, 0.45, 0.45]) +ax_2nd_f = fig.add_axes([0.52, 0.05, 0.45, 0.45]) +ax_1st_b.set_title("Backward advection for each time step") +ax_1st_f.set_title("Forward advection for each time step") + + +def color_alpha(target, pct, vmin=5, vmax=80): + color = cmap(n.segment[target]) + # We will hide under 5 % and from 80% to 100 % it will be 1 + alpha = (pct - vmin) / (vmax - vmin) + alpha[alpha < 0] = 0 + alpha[alpha > 1] = 1 + color[:, 3] = alpha + return color + + +kw = dict( + name=None, yfield="longitude", event=False, zorder=-100, s=(n.speed_area / 20e6) +) +n.scatter_timeline(ax_1st_b, c=color_alpha(i_target_b.T[0], pct_target_b.T[0]), **kw) +n.scatter_timeline(ax_2nd_b, c=color_alpha(i_target_b.T[1], pct_target_b.T[1]), **kw) +n.scatter_timeline(ax_1st_f, c=color_alpha(i_target_f.T[0], pct_target_f.T[0]), **kw) +n.scatter_timeline(ax_2nd_f, c=color_alpha(i_target_f.T[1], pct_target_f.T[1]), **kw) +for ax in (ax_1st_b, ax_2nd_b, ax_1st_f, ax_2nd_f): + n.display_timeline(ax, field="longitude", marker="+", lw=2, markersize=5) + ax.grid() diff --git a/examples/16_network/pet_segmentation_anim.py b/examples/16_network/pet_segmentation_anim.py index 10f46b66..60dae443 100644 --- a/examples/16_network/pet_segmentation_anim.py +++ b/examples/16_network/pet_segmentation_anim.py @@ -48,7 +48,7 @@ def get_obs(dataset): # %% -# Overlaod of class to pick up +# Hack to pick up each step of segmentation TRACKS = list() INDICES = list() diff --git a/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb b/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb index 626dcada..afc17825 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb @@ -163,7 +163,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Contourdetection\nTo extract contour from LAVD grid, we will used method design for SSH, with some hacks and adapted options.\nIt will produce false amplitude and speed.\n\n" + "## Contour detection\nTo extract contour from LAVD grid, we will used method design for SSH, with some hacks and adapted options.\nIt will produce false amplitude and speed.\n\n" ] }, { diff --git a/notebooks/python_module/16_network/pet_follow_particle.ipynb b/notebooks/python_module/16_network/pet_follow_particle.ipynb new file mode 100644 index 00000000..69dcd438 --- /dev/null +++ b/notebooks/python_module/16_network/pet_follow_particle.ipynb @@ -0,0 +1,177 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Follow particle\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import re\n\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numba import njit\nfrom numba import types as nb_types\nfrom numpy import arange, meshgrid, ones, unique, where, zeros\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.dataset.grid import GridCollection\nfrom py_eddy_tracker.observations.network import NetworkObservations\n\nstart_logger().setLevel(\"ERROR\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "n = NetworkObservations.load_file(get_path(\"network_med.nc\")).network(651)\nn = n.extract_with_mask((n.time >= 20180) * (n.time <= 20269))\nn = n.remove_dead_end(nobs=0, ndays=10)\nn.numbering_segment()\nc = GridCollection.from_netcdf_cube(\n get_path(\"dt_med_allsat_phy_l4_2005T2.nc\"),\n \"longitude\",\n \"latitude\",\n \"time\",\n heigth=\"adt\",\n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Schema\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(12, 6))\nax = fig.add_axes([0.05, 0.05, 0.9, 0.9])\n_ = n.display_timeline(ax, field=\"longitude\", marker=\"+\", lw=2, markersize=5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Animation\nParticle settings\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "t_snapshot = 20200\nstep = 1 / 50.0\nx, y = meshgrid(arange(20, 36, step), arange(30, 46, step))\nN = 6\nx_f, y_f = x[::N, ::N].copy(), y[::N, ::N].copy()\nx, y = x.reshape(-1), y.reshape(-1)\nx_f, y_f = x_f.reshape(-1), y_f.reshape(-1)\nn_ = n.extract_with_mask(n.time == t_snapshot)\nindex = n_.contains(x, y, intern=True)\nm = index != -1\nindex = n_.segment[index[m]]\nindex_ = unique(index)\nx, y = x[m], y[m]\nm = ~n_.inside(x_f, y_f, intern=True)\nx_f, y_f = x_f[m], y_f[m]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Animation\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "cmap = colors.ListedColormap(list(n.COLORS), name=\"from_list\", N=n.segment.max() + 1)\na = Anim(\n n,\n intern=False,\n figsize=(12, 6),\n nb_step=1,\n dpi=60,\n field_color=\"segment\",\n field_txt=\"segment\",\n cmap=cmap,\n)\na.fig.suptitle(\"\"), a.ax.set_xlim(24, 36), a.ax.set_ylim(30, 36)\na.txt.set_position((25, 31))\n\nstep = 0.25\nkw_p = dict(nb_step=2, time_step=86400 * step * 0.5, t_init=t_snapshot - 2 * step)\n\nmappables = dict()\nparticules = c.advect(x, y, \"u\", \"v\", **kw_p)\nfilament = c.filament(x_f, y_f, \"u\", \"v\", **kw_p, filament_size=3)\nkw = dict(ls=\"\", marker=\".\", markersize=0.25)\nfor k in index_:\n m = k == index\n mappables[k] = a.ax.plot([], [], color=cmap(k), **kw)[0]\nm_filament = a.ax.plot([], [], lw=0.25, color=\"gray\")[0]\n\n\ndef update(frame):\n tt, xt, yt = particules.__next__()\n for k, mappable in mappables.items():\n m = index == k\n mappable.set_data(xt[m], yt[m])\n tt, xt, yt = filament.__next__()\n m_filament.set_data(xt, yt)\n if frame % 1 == 0:\n a.func_animation(frame)\n\n\nani = VideoAnimation(a.fig, update, frames=arange(20200, 20269, step), interval=200)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## In which observations are the particle\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def advect(x, y, c, t0, delta_t):\n \"\"\"\n Advect particle from t0 to t0 + delta_t, with data cube.\n \"\"\"\n kw = dict(nb_step=6, time_step=86400 / 6)\n if delta_t < 0:\n kw[\"backward\"] = True\n delta_t = -delta_t\n p = c.advect(x, y, \"u\", \"v\", t_init=t0, **kw)\n for _ in range(delta_t):\n t, x, y = p.__next__()\n return t, x, y\n\n\ndef particle_candidate(x, y, c, eddies, t_start, i_target, pct, **kwargs):\n # Obs from initial time\n m_start = eddies.time == t_start\n e = eddies.extract_with_mask(m_start)\n # to be able to get global index\n translate_start = where(m_start)[0]\n # Identify particle in eddies(only in core)\n i_start = e.contains(x, y, intern=True)\n m = i_start != -1\n x, y, i_start = x[m], y[m], i_start[m]\n # Advect\n t_end, x, y = advect(x, y, c, t_start, **kwargs)\n # eddies at last date\n m_end = eddies.time == t_end / 86400\n e_end = eddies.extract_with_mask(m_end)\n # to be able to get global index\n translate_end = where(m_end)[0]\n # Id eddies for each alive particle(in core and extern)\n i_end = e_end.contains(x, y)\n # compute matrix and filled target array\n get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct)\n\n\n@njit(cache=True)\ndef get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct):\n nb_start, nb_end = translate_start.size, translate_end.size\n # Matrix which will store count for every couple\n count = zeros((nb_start, nb_end), dtype=nb_types.int32)\n # Number of particle in each origin observation\n ref = zeros(nb_start, dtype=nb_types.int32)\n # For each particle\n for i in range(i_start.size):\n i_end_ = i_end[i]\n i_start_ = i_start[i]\n if i_end_ != -1:\n count[i_start_, i_end_] += 1\n ref[i_start_] += 1\n for i in range(nb_start):\n for j in range(nb_end):\n pct_ = count[i, j]\n # If there are particle from i to j\n if pct_ != 0:\n # Get percent\n pct_ = pct_ / ref[i] * 100.0\n # Get indices in full dataset\n i_, j_ = translate_start[i], translate_end[j]\n pct_0 = pct[i_, 0]\n if pct_ > pct_0:\n pct[i_, 1] = pct_0\n pct[i_, 0] = pct_\n i_target[i_, 1] = i_target[i_, 0]\n i_target[i_, 0] = j_\n elif pct_ > pct[i_, 1]:\n pct[i_, 1] = pct_\n i_target[i_, 1] = j_\n return i_target, pct" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Particle advection\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "step = 1 / 60.0\n\nx, y = meshgrid(arange(20, 36, step), arange(30, 46, step))\nx0, y0 = x.reshape(-1), y.reshape(-1)\nt_start, t_end = n.period\ndt = 14\n\nshape = (n.obs.size, 2)\n# Forward run\ni_target_f, pct_target_f = -ones(shape, dtype=\"i4\"), zeros(shape, dtype=\"i1\")\nfor t in range(t_start, t_end - dt):\n particle_candidate(x0, y0, c, n, t, i_target_f, pct_target_f, delta_t=dt)\n\n# Backward run\ni_target_b, pct_target_b = -ones(shape, dtype=\"i4\"), zeros(shape, dtype=\"i1\")\nfor t in range(t_start + dt, t_end):\n particle_candidate(x0, y0, c, n, t, i_target_b, pct_target_b, delta_t=-dt)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(10, 10))\nax_1st_b = fig.add_axes([0.05, 0.52, 0.45, 0.45])\nax_2nd_b = fig.add_axes([0.05, 0.05, 0.45, 0.45])\nax_1st_f = fig.add_axes([0.52, 0.52, 0.45, 0.45])\nax_2nd_f = fig.add_axes([0.52, 0.05, 0.45, 0.45])\nax_1st_b.set_title(\"Backward advection for each time step\")\nax_1st_f.set_title(\"Forward advection for each time step\")\n\n\ndef color_alpha(target, pct, vmin=5, vmax=80):\n color = cmap(n.segment[target])\n # We will hide under 5 % and from 80% to 100 % it will be 1\n alpha = (pct - vmin) / (vmax - vmin)\n alpha[alpha < 0] = 0\n alpha[alpha > 1] = 1\n color[:, 3] = alpha\n return color\n\n\nkw = dict(\n name=None, yfield=\"longitude\", event=False, zorder=-100, s=(n.speed_area / 20e6)\n)\nn.scatter_timeline(ax_1st_b, c=color_alpha(i_target_b.T[0], pct_target_b.T[0]), **kw)\nn.scatter_timeline(ax_2nd_b, c=color_alpha(i_target_b.T[1], pct_target_b.T[1]), **kw)\nn.scatter_timeline(ax_1st_f, c=color_alpha(i_target_f.T[0], pct_target_f.T[0]), **kw)\nn.scatter_timeline(ax_2nd_f, c=color_alpha(i_target_f.T[1], pct_target_f.T[1]), **kw)\nfor ax in (ax_1st_b, ax_2nd_b, ax_1st_f, ax_2nd_f):\n n.display_timeline(ax, field=\"longitude\", marker=\"+\", lw=2, markersize=5)\n ax.grid()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb index c7372f42..2095ad14 100644 --- a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb +++ b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb @@ -44,7 +44,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Overlaod of class to pick up\n\n" + "Hack to pick up each step of segmentation\n\n" ] }, { diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index cf31506d..34f019eb 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -37,7 +37,7 @@ def build_network(): def divide_network(): - parser = EddyParser("Separate path for a same group") + parser = EddyParser("Separate path for a same group(network)") parser.add_argument("input", help="input network file") parser.add_argument("out", help="output file") parser.contour_intern_arg() diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 9bca18e6..6a4624dd 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -602,7 +602,7 @@ def eddy_identification( **kwargs, ): """ - Compute eddy identification on the pecified grid + Compute eddy identification on the specified grid :param str grid_height: Grid name of Sea Surface Height :param str uname: Grid name of u speed component From ee83f00da11cb7a0f7beec1e5d45e7c8d790dbba Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Fri, 26 Mar 2021 15:21:22 +0100 Subject: [PATCH 129/249] Add method to extract period from network --- src/py_eddy_tracker/appli/network.py | 22 +++++++++++++----- src/py_eddy_tracker/generic.py | 7 +++++- src/py_eddy_tracker/observations/network.py | 25 +++++++++++++++++++++ src/scripts/EddySubSetter | 2 +- 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index 34f019eb..90450078 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -61,11 +61,6 @@ def subset_network(): parser = EddyParser("Subset network") parser.add_argument("input", help="input network file") parser.add_argument("out", help="output file") - parser.add_argument( - "--inverse_selection", - action="store_true", - help="Extract the inverse of selection", - ) parser.add_argument( "-l", "--length", @@ -80,10 +75,25 @@ def subset_network(): type=int, help="Remove short dead end, first is for minimal obs number and second for minimal segment time to keep", ) + parser.add_argument( + "--remove_trash", + action="store_true", + help="Remove trash (network id == 0)", + ) + parser.add_argument( + "-p", + "--period", + nargs=2, + type=int, + help="Start day and end day, if it's negative value we will add to day min and add to day max," + "if 0 it s not use", + ) args = parser.parse_args() - n = NetworkObservations.load_file(args.input) + n = NetworkObservations.load_file(args.input, raw_data=True) if args.length is not None: n = n.longer_than(*args.length) if args.remove_dead_end is not None: n = n.remove_dead_end(*args.remove_dead_end) + if args.period is not None: + n = n.extract_with_period(args.period) n.write_file(filename=args.out) diff --git a/src/py_eddy_tracker/generic.py b/src/py_eddy_tracker/generic.py index 62664481..35c23817 100644 --- a/src/py_eddy_tracker/generic.py +++ b/src/py_eddy_tracker/generic.py @@ -70,6 +70,11 @@ def build_index(groups): :param array groups: array which contain group to be separated :return: (first_index of each group, last_index of each group, value to shift group) :rtype: (array, array, int) + + Examples + -------- + >>> build_index(array((1, 1, 3, 4, 4))) + (array([0, 2, 2, 3]), array([2, 2, 3, 5]), 1) """ i0, i1 = groups.min(), groups.max() amplitude = i1 - i0 + 1 @@ -78,7 +83,7 @@ def build_index(groups): for i, group in enumerate(groups[:-1]): # Get next value to compare next_group = groups[i + 1] - # if different we need to set index + # if different we need to set index for all group between the 2 values if group != next_group: first_index[group - i0 + 1 : next_group - i0 + 1] = i + 1 last_index = zeros(amplitude, dtype=numba_types.int_) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 1955d5fb..53af9f30 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -10,6 +10,7 @@ arange, array, bincount, + bool_, concatenate, empty, in1d, @@ -1237,6 +1238,30 @@ def extract_segment(self, segments, absolute=False): mask[i] = False return self.extract_with_mask(mask) + def extract_with_period(self, period): + """ + Extract within a time period + + :param (int,int) period: two dates to define the period, must be specify from 1/1/1950 + :return: Return all eddy tracks which are in bounds + :rtype: NetworkObservations + + .. minigallery:: py_eddy_tracker.NetworkObservations.extract_with_period + """ + dataset_period = self.period + p_min, p_max = period + if p_min > 0: + mask = self.time >= p_min + elif p_min < 0: + mask = self.time >= (dataset_period[0] - p_min) + else: + mask = ones(self.time.shape, dtype=bool_) + if p_max > 0: + mask *= self.time <= p_max + elif p_max < 0: + mask *= self.time <= (dataset_period[1] + p_max) + return self.extract_with_mask(mask) + def extract_with_mask(self, mask): """ Extract a subset of observations. diff --git a/src/scripts/EddySubSetter b/src/scripts/EddySubSetter index 73250834..6cace388 100644 --- a/src/scripts/EddySubSetter +++ b/src/scripts/EddySubSetter @@ -22,7 +22,7 @@ def id_parser(): "--period", nargs=2, type=int, - help="Start day and end day, if it s negative value we will add to day min and add to day max, if 0 it s not use", + help="Start day and end day, if it's negative value we will add to day min and add to day max, if 0 it s not use", ) group.add_argument( "-l", From 1f5863a2a494d5bba3e2d62e7479bb7e1dd72b0d Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Fri, 26 Mar 2021 15:23:25 +0100 Subject: [PATCH 130/249] Manage wrapping in poly_index --- .../observations/observation.py | 60 +--------- src/py_eddy_tracker/poly.py | 111 +++++++++++++++++- 2 files changed, 113 insertions(+), 58 deletions(-) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 88397fc6..73df5734 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -65,9 +65,10 @@ convexs, create_vertice, get_pixel_in_regular, + insidepoly, + poly_indexs, reduce_size, vertice_overlap, - winding_number_poly, ) logger = logging.getLogger("pet") @@ -2062,6 +2063,7 @@ def inside(self, x, y, intern=False): :rtype: array[bool] """ xname, yname = self.intern(intern) + # FIXME: wrapping return insidepoly(x, y, self[xname], self[yname]) def grid_count(self, bins, intern=False, center=False, filter=slice(None)): @@ -2330,62 +2332,6 @@ def grid_count_pixel_in( grid_count_(grid, i, j) -@njit(cache=True) -def poly_indexs(x_p, y_p, x_c, y_c): - """ - index of contour for each postion inside a contour, -1 in case of no contour - - :param array x_p: longitude to test - :param array y_p: latitude to test - :param array x_c: longitude of contours - :param array y_c: latitude of contours - """ - nb_p = x_p.shape[0] - nb_c = x_c.shape[0] - indexs = -ones(nb_p, dtype=numba_types.int32) - for i in range(nb_c): - x_, y_ = reduce_size(x_c[i], y_c[i]) - x_c_min, y_c_min = x_.min(), y_.min() - x_c_max, y_c_max = x_.max(), y_.max() - v = create_vertice(x_, y_) - for j in range(nb_p): - if indexs[j] != -1: - continue - x, y = x_p[j], y_p[j] - if x > x_c_min and x < x_c_max and y > y_c_min and y < y_c_max: - if winding_number_poly(x, y, v) != 0: - indexs[j] = i - return indexs - - -@njit(cache=True) -def insidepoly(x_p, y_p, x_c, y_c): - """ - True for each postion inside a contour - - :param array x_p: longitude to test - :param array y_p: latitude to test - :param array x_c: longitude of contours - :param array y_c: latitude of contours - """ - nb_p = x_p.shape[0] - nb_c = x_c.shape[0] - flag = zeros(nb_p, dtype=numba_types.bool_) - for i in range(nb_c): - x_, y_ = reduce_size(x_c[i], y_c[i]) - x_c_min, y_c_min = x_.min(), y_.min() - x_c_max, y_c_max = x_.max(), y_.max() - v = create_vertice(x_, y_) - for j in range(nb_p): - if flag[j]: - continue - x, y = x_p[j], y_p[j] - if x > x_c_min and x < x_c_max and y > y_c_min and y < y_c_max: - if winding_number_poly(x, y, v) != 0: - flag[j] = True - return flag - - @njit(cache=True) def grid_box_stat(x_c, y_c, grid, mask, x, y, value, circular=False, method=50): """ diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index 64eb50f8..de747f87 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -7,10 +7,12 @@ from numba import njit, prange from numba import types as numba_types -from numpy import arctan, array, concatenate, empty, nan, ones, pi, where +from numpy import arctan, array, concatenate, empty, nan, ones, pi, where, zeros from numpy.linalg import lstsq from Polygon import Polygon +from .generic import build_index + @njit(cache=True) def is_left( @@ -788,3 +790,110 @@ def reduce_size(x, y): # In case of virtual obs all value could be fill with same value, to avoid empty array i = max(3, i) return x[:i], y[:i] + + +@njit(cache=True) +def group_obs(x, y, step, nb_x): + """Get index k_box for each box, and indexes to sort""" + nb = x.size + i = empty(nb, dtype=numba_types.uint32) + for k in range(nb): + i[k] = box_index(x[k], y[k], step, nb_x) + return i, i.argsort() + + +@njit(cache=True) +def box_index(x, y, step, nb_x): + """Return k_box index for each value""" + return numba_types.uint32((x % 360) // step + nb_x * ((y + 90) // step)) + + +@njit(cache=True) +def box_indexes(x, y, step): + """Return i_box,j_box index for each value""" + return numba_types.uint32((x % 360) // step), numba_types.uint32((y + 90) // step) + + +@njit(cache=True) +def poly_indexs(x_p, y_p, x_c, y_c): + """ + Index of contour for each postion inside a contour, -1 in case of no contour + + :param array x_p: longitude to test (must be define, no nan) + :param array y_p: latitude to test (must be define, no nan) + :param array x_c: longitude of contours + :param array y_c: latitude of contours + """ + i, i_order = group_obs(x_p, y_p, 1, 360) + nb_p = x_p.shape[0] + nb_c = x_c.shape[0] + indexs = -ones(nb_p, dtype=numba_types.int32) + # Adress table to get particle bloc + start_index, end_index, i_first = build_index(i[i_order]) + nb_bloc = end_index.size + for i_contour in range(nb_c): + # Build vertice and box included contour + x_, y_ = reduce_size(x_c[i_contour], y_c[i_contour]) + x_c_min, y_c_min = x_.min(), y_.min() + x_c_max, y_c_max = x_.max(), y_.max() + v = create_vertice(x_, y_) + i0, j0 = box_indexes(x_c_min, y_c_min, 1) + i1, j1 = box_indexes(x_c_max, y_c_max, 1) + # i0 could be greater than i1, (x_c is always continious) so you could have a contour over bound + if i0 > i1: + i1 += 360 + for i_x in range(i0, i1 + 1): + # we force i_x in 0 360 range + i_x %= 360 + for i_y in range(j0, j1 + 1): + # Get box indices + i_box = i_x + 360 * i_y - i_first + # Indice must be in table range + if i_box < 0 or i_box >= nb_bloc: + continue + for i_p_ordered in range(start_index[i_box], end_index[i_box]): + i_p = i_order[i_p_ordered] + if indexs[i_p] != -1: + continue + y = y_p[i_p] + if y > y_c_max: + continue + if y < y_c_min: + continue + x = (x_p[i_p] - x_c_min + 180) % 360 + x_c_min - 180 + if x > x_c_max: + continue + if x < x_c_min: + continue + if winding_number_poly(x, y, v) != 0: + indexs[i_p] = i_contour + return indexs + + +@njit(cache=True) +def insidepoly(x_p, y_p, x_c, y_c): + """ + True for each postion inside a contour + + :param array x_p: longitude to test + :param array y_p: latitude to test + :param array x_c: longitude of contours + :param array y_c: latitude of contours + """ + # TODO must be optimize like poly_index + nb_p = x_p.shape[0] + nb_c = x_c.shape[0] + flag = zeros(nb_p, dtype=numba_types.bool_) + for i in range(nb_c): + x_, y_ = reduce_size(x_c[i], y_c[i]) + x_c_min, y_c_min = x_.min(), y_.min() + x_c_max, y_c_max = x_.max(), y_.max() + v = create_vertice(x_, y_) + for j in range(nb_p): + if flag[j]: + continue + x, y = x_p[j], y_p[j] + if x > x_c_min and x < x_c_max and y > y_c_min and y < y_c_max: + if winding_number_poly(x, y, v) != 0: + flag[j] = True + return flag From 32f6b3606fc66696b924764d5ac069325df04e1e Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Sat, 27 Mar 2021 09:35:53 +0100 Subject: [PATCH 131/249] Use of mergesort to save time when array is alreay ordered --- examples/16_network/pet_follow_particle.py | 7 ++++++- .../16_network/pet_follow_particle.ipynb | 4 ++-- src/py_eddy_tracker/poly.py | 17 ++++++++++------- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/examples/16_network/pet_follow_particle.py b/examples/16_network/pet_follow_particle.py index dee3ab84..0a57d346 100644 --- a/examples/16_network/pet_follow_particle.py +++ b/examples/16_network/pet_follow_particle.py @@ -17,6 +17,7 @@ from py_eddy_tracker.data import get_path from py_eddy_tracker.dataset.grid import GridCollection from py_eddy_tracker.observations.network import NetworkObservations +from py_eddy_tracker.poly import group_obs start_logger().setLevel("ERROR") @@ -203,8 +204,12 @@ def get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct): # ^^^^^^^^^^^^^^^^^^ step = 1 / 60.0 -x, y = meshgrid(arange(20, 36, step), arange(30, 46, step)) +x, y = meshgrid(arange(24, 36, step), arange(31, 36, step)) x0, y0 = x.reshape(-1), y.reshape(-1) +# Pre-order to speed up +_, i = group_obs(x0, y0, 1, 360) +x0, y0 = x0[i], y0[i] + t_start, t_end = n.period dt = 14 diff --git a/notebooks/python_module/16_network/pet_follow_particle.ipynb b/notebooks/python_module/16_network/pet_follow_particle.ipynb index 69dcd438..580c848c 100644 --- a/notebooks/python_module/16_network/pet_follow_particle.ipynb +++ b/notebooks/python_module/16_network/pet_follow_particle.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import re\n\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numba import njit\nfrom numba import types as nb_types\nfrom numpy import arange, meshgrid, ones, unique, where, zeros\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.dataset.grid import GridCollection\nfrom py_eddy_tracker.observations.network import NetworkObservations\n\nstart_logger().setLevel(\"ERROR\")" + "import re\n\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numba import njit\nfrom numba import types as nb_types\nfrom numpy import arange, meshgrid, ones, unique, where, zeros\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.dataset.grid import GridCollection\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.poly import group_obs\n\nstart_logger().setLevel(\"ERROR\")" ] }, { @@ -138,7 +138,7 @@ }, "outputs": [], "source": [ - "step = 1 / 60.0\n\nx, y = meshgrid(arange(20, 36, step), arange(30, 46, step))\nx0, y0 = x.reshape(-1), y.reshape(-1)\nt_start, t_end = n.period\ndt = 14\n\nshape = (n.obs.size, 2)\n# Forward run\ni_target_f, pct_target_f = -ones(shape, dtype=\"i4\"), zeros(shape, dtype=\"i1\")\nfor t in range(t_start, t_end - dt):\n particle_candidate(x0, y0, c, n, t, i_target_f, pct_target_f, delta_t=dt)\n\n# Backward run\ni_target_b, pct_target_b = -ones(shape, dtype=\"i4\"), zeros(shape, dtype=\"i1\")\nfor t in range(t_start + dt, t_end):\n particle_candidate(x0, y0, c, n, t, i_target_b, pct_target_b, delta_t=-dt)" + "step = 1 / 60.0\n\nx, y = meshgrid(arange(24, 36, step), arange(31, 36, step))\nx0, y0 = x.reshape(-1), y.reshape(-1)\n# Pre-order to speed up\n_, i = group_obs(x0, y0, 1, 360)\nx0, y0 = x0[i], y0[i]\n\nt_start, t_end = n.period\ndt = 14\n\nshape = (n.obs.size, 2)\n# Forward run\ni_target_f, pct_target_f = -ones(shape, dtype=\"i4\"), zeros(shape, dtype=\"i1\")\nfor t in range(t_start, t_end - dt):\n particle_candidate(x0, y0, c, n, t, i_target_f, pct_target_f, delta_t=dt)\n\n# Backward run\ni_target_b, pct_target_b = -ones(shape, dtype=\"i4\"), zeros(shape, dtype=\"i1\")\nfor t in range(t_start + dt, t_end):\n particle_candidate(x0, y0, c, n, t, i_target_b, pct_target_b, delta_t=-dt)" ] }, { diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index de747f87..afca0f14 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -799,7 +799,7 @@ def group_obs(x, y, step, nb_x): i = empty(nb, dtype=numba_types.uint32) for k in range(nb): i[k] = box_index(x[k], y[k], step, nb_x) - return i, i.argsort() + return i, i.argsort(kind="mergesort") @njit(cache=True) @@ -824,7 +824,9 @@ def poly_indexs(x_p, y_p, x_c, y_c): :param array x_c: longitude of contours :param array y_c: latitude of contours """ - i, i_order = group_obs(x_p, y_p, 1, 360) + nb_x = 360 + step = 1.0 + i, i_order = group_obs(x_p, y_p, step, nb_x) nb_p = x_p.shape[0] nb_c = x_c.shape[0] indexs = -ones(nb_p, dtype=numba_types.int32) @@ -837,17 +839,17 @@ def poly_indexs(x_p, y_p, x_c, y_c): x_c_min, y_c_min = x_.min(), y_.min() x_c_max, y_c_max = x_.max(), y_.max() v = create_vertice(x_, y_) - i0, j0 = box_indexes(x_c_min, y_c_min, 1) - i1, j1 = box_indexes(x_c_max, y_c_max, 1) + i0, j0 = box_indexes(x_c_min, y_c_min, step) + i1, j1 = box_indexes(x_c_max, y_c_max, step) # i0 could be greater than i1, (x_c is always continious) so you could have a contour over bound if i0 > i1: - i1 += 360 + i1 += nb_x for i_x in range(i0, i1 + 1): # we force i_x in 0 360 range - i_x %= 360 + i_x %= nb_x for i_y in range(j0, j1 + 1): # Get box indices - i_box = i_x + 360 * i_y - i_first + i_box = i_x + nb_x * i_y - i_first # Indice must be in table range if i_box < 0 or i_box >= nb_bloc: continue @@ -860,6 +862,7 @@ def poly_indexs(x_p, y_p, x_c, y_c): continue if y < y_c_min: continue + # Normalize longitude at +-180° around x_c_min x = (x_p[i_p] - x_c_min + 180) % 360 + x_c_min - 180 if x > x_c_max: continue From 896694b886cb6c5a0e0c7017fc554e9cd765f026 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Sat, 27 Mar 2021 09:56:15 +0100 Subject: [PATCH 132/249] Reset of poly_indexs due to an unknown segmentation fault --- src/py_eddy_tracker/poly.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index afca0f14..2bf34509 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -815,7 +815,7 @@ def box_indexes(x, y, step): @njit(cache=True) -def poly_indexs(x_p, y_p, x_c, y_c): +def poly_indexs_(x_p, y_p, x_c, y_c): """ Index of contour for each postion inside a contour, -1 in case of no contour @@ -873,6 +873,34 @@ def poly_indexs(x_p, y_p, x_c, y_c): return indexs +@njit(cache=True) +def poly_indexs(x_p, y_p, x_c, y_c): + """ + index of contour for each postion inside a contour, -1 in case of no contour + + :param array x_p: longitude to test + :param array y_p: latitude to test + :param array x_c: longitude of contours + :param array y_c: latitude of contours + """ + nb_p = x_p.shape[0] + nb_c = x_c.shape[0] + indexs = -ones(nb_p, dtype=numba_types.int32) + for i in range(nb_c): + x_, y_ = reduce_size(x_c[i], y_c[i]) + x_c_min, y_c_min = x_.min(), y_.min() + x_c_max, y_c_max = x_.max(), y_.max() + v = create_vertice(x_, y_) + for j in range(nb_p): + if indexs[j] != -1: + continue + x, y = x_p[j], y_p[j] + if x > x_c_min and x < x_c_max and y > y_c_min and y < y_c_max: + if winding_number_poly(x, y, v) != 0: + indexs[j] = i + return indexs + + @njit(cache=True) def insidepoly(x_p, y_p, x_c, y_c): """ From f40cecbcabcaf8230f033aef72da862aae4076d1 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Mon, 29 Mar 2021 11:50:42 +0200 Subject: [PATCH 133/249] Change method name to get demo data, to be explicit --- examples/01_general_things/pet_storage.py | 8 ++++---- examples/02_eddy_identification/pet_contour_circle.py | 2 +- examples/02_eddy_identification/pet_display_id.py | 4 ++-- examples/02_eddy_identification/pet_eddy_detection.py | 4 +++- .../02_eddy_identification/pet_eddy_detection_ACC.py | 2 +- .../pet_eddy_detection_gulf_stream.py | 2 +- .../02_eddy_identification/pet_filter_and_detection.py | 4 +++- .../pet_interp_grid_on_dataset.py | 8 +++++--- examples/02_eddy_identification/pet_radius_vs_area.py | 2 +- examples/02_eddy_identification/pet_shape_gallery.py | 4 +++- examples/02_eddy_identification/pet_sla_and_adt.py | 4 +++- examples/06_grid_manipulation/pet_advect.py | 8 ++++---- examples/06_grid_manipulation/pet_filter.py | 4 +++- .../06_grid_manipulation/pet_hide_pixel_out_eddies.py | 4 ++-- examples/06_grid_manipulation/pet_lavd.py | 10 ++++++---- examples/06_grid_manipulation/pet_okubo_weiss.py | 6 +++--- examples/07_cube_manipulation/pet_cube.py | 4 ++-- examples/07_cube_manipulation/pet_fsle_med.py | 4 ++-- examples/07_cube_manipulation/pet_lavd_detection.py | 4 ++-- examples/08_tracking_manipulation/pet_display_field.py | 2 +- examples/08_tracking_manipulation/pet_display_track.py | 6 ++++-- examples/08_tracking_manipulation/pet_one_track.py | 4 +++- .../08_tracking_manipulation/pet_run_a_tracking.py | 6 +++--- .../pet_select_track_across_area.py | 2 +- examples/08_tracking_manipulation/pet_track_anim.py | 4 +++- .../pet_track_anim_matplotlib_animation.py | 4 +++- .../10_tracking_diagnostics/pet_birth_and_death.py | 6 ++++-- examples/10_tracking_diagnostics/pet_center_count.py | 6 ++++-- .../10_tracking_diagnostics/pet_geographic_stats.py | 6 ++++-- examples/10_tracking_diagnostics/pet_groups.py | 4 +++- examples/10_tracking_diagnostics/pet_histo.py | 6 ++++-- examples/10_tracking_diagnostics/pet_lifetime.py | 6 ++++-- examples/10_tracking_diagnostics/pet_pixel_used.py | 6 ++++-- examples/10_tracking_diagnostics/pet_propagation.py | 6 ++++-- examples/12_external_data/pet_SST_collocation.py | 8 +++++--- examples/14_generic_tools/pet_fit_contour.py | 2 +- examples/14_generic_tools/pet_visvalingam.py | 2 +- examples/16_network/pet_atlas.py | 4 ++-- examples/16_network/pet_follow_particle.py | 6 +++--- examples/16_network/pet_group_anim.py | 2 +- examples/16_network/pet_ioannou_2017_case.py | 6 ++++-- examples/16_network/pet_relative.py | 2 +- examples/16_network/pet_replay_segmentation.py | 4 ++-- examples/16_network/pet_segmentation_anim.py | 4 ++-- .../python_module/01_general_things/pet_storage.ipynb | 8 ++++---- .../02_eddy_identification/pet_contour_circle.ipynb | 2 +- .../02_eddy_identification/pet_display_id.ipynb | 2 +- .../02_eddy_identification/pet_eddy_detection.ipynb | 2 +- .../pet_eddy_detection_ACC.ipynb | 2 +- .../pet_eddy_detection_gulf_stream.ipynb | 2 +- .../pet_filter_and_detection.ipynb | 2 +- .../pet_interp_grid_on_dataset.ipynb | 2 +- .../02_eddy_identification/pet_radius_vs_area.ipynb | 2 +- .../02_eddy_identification/pet_shape_gallery.ipynb | 2 +- .../02_eddy_identification/pet_sla_and_adt.ipynb | 2 +- .../06_grid_manipulation/pet_advect.ipynb | 6 +++--- .../06_grid_manipulation/pet_filter.ipynb | 2 +- .../pet_hide_pixel_out_eddies.ipynb | 4 ++-- .../python_module/06_grid_manipulation/pet_lavd.ipynb | 6 +++--- .../06_grid_manipulation/pet_okubo_weiss.ipynb | 4 ++-- .../python_module/07_cube_manipulation/pet_cube.ipynb | 4 ++-- .../07_cube_manipulation/pet_fsle_med.ipynb | 4 ++-- .../07_cube_manipulation/pet_lavd_detection.ipynb | 4 ++-- .../08_tracking_manipulation/pet_display_field.ipynb | 2 +- .../08_tracking_manipulation/pet_display_track.ipynb | 2 +- .../08_tracking_manipulation/pet_one_track.ipynb | 2 +- .../08_tracking_manipulation/pet_run_a_tracking.ipynb | 6 +++--- .../pet_select_track_across_area.ipynb | 2 +- .../08_tracking_manipulation/pet_track_anim.ipynb | 2 +- .../pet_track_anim_matplotlib_animation.ipynb | 2 +- .../10_tracking_diagnostics/pet_birth_and_death.ipynb | 2 +- .../10_tracking_diagnostics/pet_center_count.ipynb | 2 +- .../10_tracking_diagnostics/pet_geographic_stats.ipynb | 2 +- .../10_tracking_diagnostics/pet_groups.ipynb | 2 +- .../10_tracking_diagnostics/pet_histo.ipynb | 2 +- .../10_tracking_diagnostics/pet_lifetime.ipynb | 2 +- .../10_tracking_diagnostics/pet_pixel_used.ipynb | 2 +- .../10_tracking_diagnostics/pet_propagation.ipynb | 2 +- .../12_external_data/pet_SST_collocation.ipynb | 4 ++-- .../14_generic_tools/pet_fit_contour.ipynb | 2 +- .../14_generic_tools/pet_visvalingam.ipynb | 2 +- notebooks/python_module/16_network/pet_atlas.ipynb | 2 +- .../python_module/16_network/pet_follow_particle.ipynb | 4 ++-- .../python_module/16_network/pet_group_anim.ipynb | 2 +- .../16_network/pet_ioannou_2017_case.ipynb | 4 ++-- notebooks/python_module/16_network/pet_relative.ipynb | 2 +- .../16_network/pet_replay_segmentation.ipynb | 4 ++-- .../16_network/pet_segmentation_anim.ipynb | 4 ++-- src/py_eddy_tracker/data/__init__.py | 4 ++-- tests/test_grid.py | 4 ++-- tests/test_id.py | 4 ++-- tests/test_obs.py | 6 +++--- tests/test_track.py | 4 ++-- 93 files changed, 196 insertions(+), 154 deletions(-) diff --git a/examples/01_general_things/pet_storage.py b/examples/01_general_things/pet_storage.py index 49b45627..28f0f76e 100644 --- a/examples/01_general_things/pet_storage.py +++ b/examples/01_general_things/pet_storage.py @@ -17,7 +17,7 @@ import py_eddy_tracker_sample -from py_eddy_tracker.data import get_path, get_remote_sample +from py_eddy_tracker.data import get_demo_path, get_remote_demo_sample from py_eddy_tracker.observations.network import NetworkObservations from py_eddy_tracker.observations.observation import EddiesObservations, Table from py_eddy_tracker.observations.tracking import TrackEddiesObservations @@ -33,7 +33,7 @@ # %% # Eddies files (zarr or netcdf) could be loaded with ```load_file``` method: -eddies_collections = EddiesObservations.load_file(get_path("Cyclonic_20160515.nc")) +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 @@ -69,7 +69,7 @@ # - **observation_number** : Eddy temporal index in a trajectory, days starting at the eddy first detection # - **cost_association** : result of the cost function to associate the eddy with the next observation eddies_tracks = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") + py_eddy_tracker_sample.get_demo_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") ) # In this example some fields are removed (effective_contour_longitude,...) in order to save time for doc building eddies_tracks.field_table() @@ -87,7 +87,7 @@ # - previous_cost : Result of the cost function (1 is a good association, 0 is bad) with previous observation # - next_cost : Result of the cost function (1 is a good association, 0 is bad) with next observation eddies_network = NetworkObservations.load_file( - get_remote_sample( + get_remote_demo_sample( "eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc" ) ) diff --git a/examples/02_eddy_identification/pet_contour_circle.py b/examples/02_eddy_identification/pet_contour_circle.py index 173ca4da..03332285 100644 --- a/examples/02_eddy_identification/pet_contour_circle.py +++ b/examples/02_eddy_identification/pet_contour_circle.py @@ -11,7 +11,7 @@ # %% # Load detection files -a = EddiesObservations.load_file(data.get_path("Anticyclonic_20190223.nc")) +a = EddiesObservations.load_file(data.get_demo_path("Anticyclonic_20190223.nc")) # %% # Plot the speed and effective (dashed) contours diff --git a/examples/02_eddy_identification/pet_display_id.py b/examples/02_eddy_identification/pet_display_id.py index 37c2b863..57c59bc2 100644 --- a/examples/02_eddy_identification/pet_display_id.py +++ b/examples/02_eddy_identification/pet_display_id.py @@ -11,8 +11,8 @@ # %% # Load detection files -a = EddiesObservations.load_file(data.get_path("Anticyclonic_20190223.nc")) -c = EddiesObservations.load_file(data.get_path("Cyclonic_20190223.nc")) +a = EddiesObservations.load_file(data.get_demo_path("Anticyclonic_20190223.nc")) +c = EddiesObservations.load_file(data.get_demo_path("Cyclonic_20190223.nc")) # %% # Fill effective contour with amplitude diff --git a/examples/02_eddy_identification/pet_eddy_detection.py b/examples/02_eddy_identification/pet_eddy_detection.py index bf73bae2..b1b2c1af 100644 --- a/examples/02_eddy_identification/pet_eddy_detection.py +++ b/examples/02_eddy_identification/pet_eddy_detection.py @@ -35,7 +35,9 @@ def update_axes(ax, mappable=None): # %% # Load Input grid, ADT is used to detect eddies g = RegularGridDataset( - data.get_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), "longitude", "latitude" + data.get_demo_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), + "longitude", + "latitude", ) ax = start_axes("ADT (m)") diff --git a/examples/02_eddy_identification/pet_eddy_detection_ACC.py b/examples/02_eddy_identification/pet_eddy_detection_ACC.py index 415da9dd..c799a45e 100644 --- a/examples/02_eddy_identification/pet_eddy_detection_ACC.py +++ b/examples/02_eddy_identification/pet_eddy_detection_ACC.py @@ -60,7 +60,7 @@ def set_fancy_labels(fig, ticklabelsize=14, labelsize=14, labelweight="semibold" margin = 30 kw_data = dict( - filename=data.get_path("nrt_global_allsat_phy_l4_20190223_20190226.nc"), + filename=data.get_demo_path("nrt_global_allsat_phy_l4_20190223_20190226.nc"), x_name="longitude", y_name="latitude", # Manual area subset diff --git a/examples/02_eddy_identification/pet_eddy_detection_gulf_stream.py b/examples/02_eddy_identification/pet_eddy_detection_gulf_stream.py index 27ea77ac..55267b76 100644 --- a/examples/02_eddy_identification/pet_eddy_detection_gulf_stream.py +++ b/examples/02_eddy_identification/pet_eddy_detection_gulf_stream.py @@ -37,7 +37,7 @@ def update_axes(ax, mappable=None): # Load Input grid, ADT is used to detect eddies margin = 30 g = RegularGridDataset( - data.get_path("nrt_global_allsat_phy_l4_20190223_20190226.nc"), + data.get_demo_path("nrt_global_allsat_phy_l4_20190223_20190226.nc"), "longitude", "latitude", # Manual area subset diff --git a/examples/02_eddy_identification/pet_filter_and_detection.py b/examples/02_eddy_identification/pet_filter_and_detection.py index 2feffc3e..ec02a28c 100644 --- a/examples/02_eddy_identification/pet_filter_and_detection.py +++ b/examples/02_eddy_identification/pet_filter_and_detection.py @@ -33,7 +33,9 @@ def update_axes(ax, mappable=None): # Add a new filed to store the high-pass filtered ADT g = RegularGridDataset( - data.get_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), "longitude", "latitude" + data.get_demo_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), + "longitude", + "latitude", ) g.add_uv("adt") g.copy("adt", "adt_high") diff --git a/examples/02_eddy_identification/pet_interp_grid_on_dataset.py b/examples/02_eddy_identification/pet_interp_grid_on_dataset.py index 4d9a67aa..f9e5d4c3 100644 --- a/examples/02_eddy_identification/pet_interp_grid_on_dataset.py +++ b/examples/02_eddy_identification/pet_interp_grid_on_dataset.py @@ -30,11 +30,13 @@ def update_axes(ax, mappable=None): # %% # Load detection files and data to interp -a = EddiesObservations.load_file(data.get_path("Anticyclonic_20160515.nc")) -c = EddiesObservations.load_file(data.get_path("Cyclonic_20160515.nc")) +a = EddiesObservations.load_file(data.get_demo_path("Anticyclonic_20160515.nc")) +c = EddiesObservations.load_file(data.get_demo_path("Cyclonic_20160515.nc")) aviso_map = RegularGridDataset( - data.get_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), "longitude", "latitude" + data.get_demo_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), + "longitude", + "latitude", ) aviso_map.add_uv("adt") diff --git a/examples/02_eddy_identification/pet_radius_vs_area.py b/examples/02_eddy_identification/pet_radius_vs_area.py index 0239ebe7..e34ad725 100644 --- a/examples/02_eddy_identification/pet_radius_vs_area.py +++ b/examples/02_eddy_identification/pet_radius_vs_area.py @@ -13,7 +13,7 @@ # %% # Load detection files -a = EddiesObservations.load_file(data.get_path("Anticyclonic_20190223.nc")) +a = EddiesObservations.load_file(data.get_demo_path("Anticyclonic_20190223.nc")) areas = list() # For each contour area will be compute in local reference for i in a: diff --git a/examples/02_eddy_identification/pet_shape_gallery.py b/examples/02_eddy_identification/pet_shape_gallery.py index 4e37d727..ed8df83d 100644 --- a/examples/02_eddy_identification/pet_shape_gallery.py +++ b/examples/02_eddy_identification/pet_shape_gallery.py @@ -25,7 +25,9 @@ def build_circle(x0, y0, r): # %% # We iterate over closed contours and sort with regards of shape error g = RegularGridDataset( - data.get_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), "longitude", "latitude" + data.get_demo_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), + "longitude", + "latitude", ) c = Contours(g.x_c, g.y_c, g.grid("adt") * 100, arange(-50, 50, 0.2)) contours = dict() diff --git a/examples/02_eddy_identification/pet_sla_and_adt.py b/examples/02_eddy_identification/pet_sla_and_adt.py index 307d8cca..29dcc0a7 100644 --- a/examples/02_eddy_identification/pet_sla_and_adt.py +++ b/examples/02_eddy_identification/pet_sla_and_adt.py @@ -31,7 +31,9 @@ def update_axes(ax, mappable=None): # 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" + data.get_demo_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), + "longitude", + "latitude", ) g.add_uv("adt", "ugos", "vgos") g.add_uv("sla", "ugosa", "vgosa") diff --git a/examples/06_grid_manipulation/pet_advect.py b/examples/06_grid_manipulation/pet_advect.py index 7c7f0959..13052af5 100644 --- a/examples/06_grid_manipulation/pet_advect.py +++ b/examples/06_grid_manipulation/pet_advect.py @@ -11,22 +11,22 @@ from numpy import arange, isnan, meshgrid, ones import py_eddy_tracker.gui -from py_eddy_tracker.data import get_path +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_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), "longitude", "latitude" + 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_path("Anticyclonic_20160515.nc")) -c = EddiesObservations.load_file(get_path("Cyclonic_20160515.nc")) +a = EddiesObservations.load_file(get_demo_path("Anticyclonic_20160515.nc")) +c = EddiesObservations.load_file(get_demo_path("Cyclonic_20160515.nc")) # %% diff --git a/examples/06_grid_manipulation/pet_filter.py b/examples/06_grid_manipulation/pet_filter.py index 2975325d..ae4356d7 100644 --- a/examples/06_grid_manipulation/pet_filter.py +++ b/examples/06_grid_manipulation/pet_filter.py @@ -32,7 +32,9 @@ def update_axes(ax, mappable=None): # %% # All information will be for regular grid g = RegularGridDataset( - data.get_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), "longitude", "latitude" + data.get_demo_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), + "longitude", + "latitude", ) # %% # Kernel diff --git a/examples/06_grid_manipulation/pet_hide_pixel_out_eddies.py b/examples/06_grid_manipulation/pet_hide_pixel_out_eddies.py index 58a31374..388c9c7f 100644 --- a/examples/06_grid_manipulation/pet_hide_pixel_out_eddies.py +++ b/examples/06_grid_manipulation/pet_hide_pixel_out_eddies.py @@ -15,12 +15,12 @@ # %% # Load an eddy file which contains contours -a = EddiesObservations.load_file(data.get_path("Anticyclonic_20190223.nc")) +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_path("nrt_global_allsat_phy_l4_20190223_20190226.nc"), + data.get_demo_path("nrt_global_allsat_phy_l4_20190223_20190226.nc"), "longitude", "latitude", ) diff --git a/examples/06_grid_manipulation/pet_lavd.py b/examples/06_grid_manipulation/pet_lavd.py index 6e86933d..e0dbbb54 100644 --- a/examples/06_grid_manipulation/pet_lavd.py +++ b/examples/06_grid_manipulation/pet_lavd.py @@ -25,7 +25,7 @@ from numpy import arange, meshgrid, zeros import py_eddy_tracker.gui -from py_eddy_tracker.data import get_path +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 @@ -82,7 +82,7 @@ def save(self, *args, **kwargs): # .. 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" + 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) @@ -171,8 +171,10 @@ def update(i_frame): # Period used for LAVD integration (8 days) is too short for a real use, but choose for example efficiency. fig, ax, _ = start_ax() mappable = lavd.display(ax, "lavd", **kw_vorticity) -EddiesObservations.load_file(get_path("Anticyclonic_20160515.nc")).display( +EddiesObservations.load_file(get_demo_path("Anticyclonic_20160515.nc")).display( + ax, color="k" +) +EddiesObservations.load_file(get_demo_path("Cyclonic_20160515.nc")).display( ax, color="k" ) -EddiesObservations.load_file(get_path("Cyclonic_20160515.nc")).display(ax, color="k") _ = update_axes(ax, mappable) diff --git a/examples/06_grid_manipulation/pet_okubo_weiss.py b/examples/06_grid_manipulation/pet_okubo_weiss.py index 577178c5..c60a92fb 100644 --- a/examples/06_grid_manipulation/pet_okubo_weiss.py +++ b/examples/06_grid_manipulation/pet_okubo_weiss.py @@ -40,13 +40,13 @@ def update_axes(axes, mappable=None): # %% # Load detection files -a = EddiesObservations.load_file(data.get_path("Anticyclonic_20190223.nc")) -c = EddiesObservations.load_file(data.get_path("Cyclonic_20190223.nc")) +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_path("nrt_global_allsat_phy_l4_20190223_20190226.nc"), + data.get_demo_path("nrt_global_allsat_phy_l4_20190223_20190226.nc"), "longitude", "latitude", ) diff --git a/examples/07_cube_manipulation/pet_cube.py b/examples/07_cube_manipulation/pet_cube.py index 50431f58..6c0db253 100644 --- a/examples/07_cube_manipulation/pet_cube.py +++ b/examples/07_cube_manipulation/pet_cube.py @@ -14,7 +14,7 @@ import py_eddy_tracker.gui from py_eddy_tracker import start_logger -from py_eddy_tracker.data import get_path +from py_eddy_tracker.data import get_demo_path from py_eddy_tracker.dataset.grid import GridCollection start_logger().setLevel("ERROR") @@ -44,7 +44,7 @@ def save(self, *args, **kwargs): # ---- # Load Input time grid ADT c = GridCollection.from_netcdf_cube( - get_path("dt_med_allsat_phy_l4_2005T2.nc"), + get_demo_path("dt_med_allsat_phy_l4_2005T2.nc"), "longitude", "latitude", "time", diff --git a/examples/07_cube_manipulation/pet_fsle_med.py b/examples/07_cube_manipulation/pet_fsle_med.py index bbeb0007..46c5fdcc 100644 --- a/examples/07_cube_manipulation/pet_fsle_med.py +++ b/examples/07_cube_manipulation/pet_fsle_med.py @@ -17,7 +17,7 @@ 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.data import get_demo_path from py_eddy_tracker.dataset.grid import GridCollection, RegularGridDataset start_logger().setLevel("ERROR") @@ -27,7 +27,7 @@ # ADT in med # ---------- c = GridCollection.from_netcdf_cube( - get_path("dt_med_allsat_phy_l4_2005T2.nc"), + get_demo_path("dt_med_allsat_phy_l4_2005T2.nc"), "longitude", "latitude", "time", diff --git a/examples/07_cube_manipulation/pet_lavd_detection.py b/examples/07_cube_manipulation/pet_lavd_detection.py index dad99498..dc3a83ff 100644 --- a/examples/07_cube_manipulation/pet_lavd_detection.py +++ b/examples/07_cube_manipulation/pet_lavd_detection.py @@ -25,7 +25,7 @@ import py_eddy_tracker.gui from py_eddy_tracker import start_logger -from py_eddy_tracker.data import get_path +from py_eddy_tracker.data import get_demo_path from py_eddy_tracker.dataset.grid import GridCollection, RegularGridDataset start_logger().setLevel("ERROR") @@ -73,7 +73,7 @@ def update_axes(ax, mappable=None): # Load data cube of 3 month c = GridCollection.from_netcdf_cube( - get_path("dt_med_allsat_phy_l4_2005T2.nc"), + get_demo_path("dt_med_allsat_phy_l4_2005T2.nc"), "longitude", "latitude", "time", diff --git a/examples/08_tracking_manipulation/pet_display_field.py b/examples/08_tracking_manipulation/pet_display_field.py index b1add536..30ad75a6 100644 --- a/examples/08_tracking_manipulation/pet_display_field.py +++ b/examples/08_tracking_manipulation/pet_display_field.py @@ -12,7 +12,7 @@ # %% # Load an experimental cyclonic atlas, we keep only eddies which are follow more than 180 days c = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") + py_eddy_tracker_sample.get_demo_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") ) c = c.extract_with_length((180, -1)) diff --git a/examples/08_tracking_manipulation/pet_display_track.py b/examples/08_tracking_manipulation/pet_display_track.py index 624395ac..13a8d3ad 100644 --- a/examples/08_tracking_manipulation/pet_display_track.py +++ b/examples/08_tracking_manipulation/pet_display_track.py @@ -12,10 +12,12 @@ # %% # Load experimental atlas a = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Anticyclonic.zarr") + py_eddy_tracker_sample.get_demo_path( + "eddies_med_adt_allsat_dt2018/Anticyclonic.zarr" + ) ) c = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") + py_eddy_tracker_sample.get_demo_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") ) print(a) diff --git a/examples/08_tracking_manipulation/pet_one_track.py b/examples/08_tracking_manipulation/pet_one_track.py index 710ab6cf..9f930281 100644 --- a/examples/08_tracking_manipulation/pet_one_track.py +++ b/examples/08_tracking_manipulation/pet_one_track.py @@ -10,7 +10,9 @@ # %% # Load experimental atlas, and we select one eddy a = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Anticyclonic.zarr") + py_eddy_tracker_sample.get_demo_path( + "eddies_med_adt_allsat_dt2018/Anticyclonic.zarr" + ) ) eddy = a.extract_ids([9672]) eddy_f = a.extract_ids([9672]) diff --git a/examples/08_tracking_manipulation/pet_run_a_tracking.py b/examples/08_tracking_manipulation/pet_run_a_tracking.py index f7ac5ca9..15d8b18b 100644 --- a/examples/08_tracking_manipulation/pet_run_a_tracking.py +++ b/examples/08_tracking_manipulation/pet_run_a_tracking.py @@ -7,16 +7,16 @@ # %% -from py_eddy_tracker.data import get_remote_sample +from py_eddy_tracker.data import get_remote_demo_sample from py_eddy_tracker.featured_tracking.area_tracker import AreaTracker from py_eddy_tracker.gui import GUI from py_eddy_tracker.tracking import Correspondances # %% # Get remote data, we will keep only 180 first days, -# `get_remote_sample` function is only to get demo dataset, in your own case give a list of identification filename +# `get_remote_demo_sample` function is only to get demo dataset, in your own case give a list of identification filename # and don't mix cyclonic and anticyclonic files. -file_objects = get_remote_sample( +file_objects = get_remote_demo_sample( "eddies_med_adt_allsat_dt2018/Anticyclonic_2010_2011_2012" )[:180] diff --git a/examples/08_tracking_manipulation/pet_select_track_across_area.py b/examples/08_tracking_manipulation/pet_select_track_across_area.py index bd18585d..b88f37e1 100644 --- a/examples/08_tracking_manipulation/pet_select_track_across_area.py +++ b/examples/08_tracking_manipulation/pet_select_track_across_area.py @@ -11,7 +11,7 @@ # %% # Load experimental atlas, we filter position to have nice display c = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") + py_eddy_tracker_sample.get_demo_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") ) c.position_filter(median_half_window=1, loess_half_window=5) diff --git a/examples/08_tracking_manipulation/pet_track_anim.py b/examples/08_tracking_manipulation/pet_track_anim.py index f65ad157..0c18a0ba 100644 --- a/examples/08_tracking_manipulation/pet_track_anim.py +++ b/examples/08_tracking_manipulation/pet_track_anim.py @@ -13,7 +13,9 @@ # %% # Load experimental atlas, and we select one eddy a = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Anticyclonic.zarr") + py_eddy_tracker_sample.get_demo_path( + "eddies_med_adt_allsat_dt2018/Anticyclonic.zarr" + ) ) # We get only 300 first step to save time of documentation builder eddy = a.extract_ids([9672]).index(slice(0, 300)) diff --git a/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py b/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py index 9bf27382..6776b47e 100644 --- a/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py +++ b/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py @@ -39,7 +39,9 @@ def save(self, *args, **kwargs): # %% # Load experimental atlas, and we select one eddy a = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Anticyclonic.zarr") + py_eddy_tracker_sample.get_demo_path( + "eddies_med_adt_allsat_dt2018/Anticyclonic.zarr" + ) ) eddy = a.extract_ids([9672]) diff --git a/examples/10_tracking_diagnostics/pet_birth_and_death.py b/examples/10_tracking_diagnostics/pet_birth_and_death.py index 612c32f7..d917efbd 100644 --- a/examples/10_tracking_diagnostics/pet_birth_and_death.py +++ b/examples/10_tracking_diagnostics/pet_birth_and_death.py @@ -41,10 +41,12 @@ def update_axes(ax, mappable=None): ) ) a = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Anticyclonic.zarr") + py_eddy_tracker_sample.get_demo_path( + "eddies_med_adt_allsat_dt2018/Anticyclonic.zarr" + ) ) c = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") + py_eddy_tracker_sample.get_demo_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") ) # %% diff --git a/examples/10_tracking_diagnostics/pet_center_count.py b/examples/10_tracking_diagnostics/pet_center_count.py index 01c27a0f..6d9fa417 100644 --- a/examples/10_tracking_diagnostics/pet_center_count.py +++ b/examples/10_tracking_diagnostics/pet_center_count.py @@ -14,10 +14,12 @@ # %% # Load an experimental med atlas over a period of 26 years (1993-2019) a = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Anticyclonic.zarr") + py_eddy_tracker_sample.get_demo_path( + "eddies_med_adt_allsat_dt2018/Anticyclonic.zarr" + ) ) c = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") + py_eddy_tracker_sample.get_demo_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") ) # %% diff --git a/examples/10_tracking_diagnostics/pet_geographic_stats.py b/examples/10_tracking_diagnostics/pet_geographic_stats.py index 137133b3..d2a7e90d 100644 --- a/examples/10_tracking_diagnostics/pet_geographic_stats.py +++ b/examples/10_tracking_diagnostics/pet_geographic_stats.py @@ -22,10 +22,12 @@ def start_axes(title): # %% # Load an experimental med atlas over a period of 26 years (1993-2019), we merge the 2 datasets a = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Anticyclonic.zarr") + py_eddy_tracker_sample.get_demo_path( + "eddies_med_adt_allsat_dt2018/Anticyclonic.zarr" + ) ) c = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") + py_eddy_tracker_sample.get_demo_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") ) a = a.merge(c) diff --git a/examples/10_tracking_diagnostics/pet_groups.py b/examples/10_tracking_diagnostics/pet_groups.py index e080310b..f6e800ae 100644 --- a/examples/10_tracking_diagnostics/pet_groups.py +++ b/examples/10_tracking_diagnostics/pet_groups.py @@ -12,7 +12,9 @@ # %% # Load an experimental med atlas over a period of 26 years (1993-2019) a = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Anticyclonic.zarr") + py_eddy_tracker_sample.get_demo_path( + "eddies_med_adt_allsat_dt2018/Anticyclonic.zarr" + ) ) # %% diff --git a/examples/10_tracking_diagnostics/pet_histo.py b/examples/10_tracking_diagnostics/pet_histo.py index cd7abf49..b2eff842 100644 --- a/examples/10_tracking_diagnostics/pet_histo.py +++ b/examples/10_tracking_diagnostics/pet_histo.py @@ -12,10 +12,12 @@ # %% # Load an experimental med atlas over a period of 26 years (1993-2019) a = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Anticyclonic.zarr") + py_eddy_tracker_sample.get_demo_path( + "eddies_med_adt_allsat_dt2018/Anticyclonic.zarr" + ) ) c = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") + py_eddy_tracker_sample.get_demo_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") ) kwargs_a = dict(label="Anticyclonic", color="r", histtype="step", density=True) kwargs_c = dict(label="Cyclonic", color="b", histtype="step", density=True) diff --git a/examples/10_tracking_diagnostics/pet_lifetime.py b/examples/10_tracking_diagnostics/pet_lifetime.py index 95f75718..9f84e790 100644 --- a/examples/10_tracking_diagnostics/pet_lifetime.py +++ b/examples/10_tracking_diagnostics/pet_lifetime.py @@ -12,10 +12,12 @@ # %% # Load an experimental med atlas over a period of 26 years (1993-2019) a = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Anticyclonic.zarr") + py_eddy_tracker_sample.get_demo_path( + "eddies_med_adt_allsat_dt2018/Anticyclonic.zarr" + ) ) c = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") + py_eddy_tracker_sample.get_demo_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") ) nb_year = (a.period[1] - a.period[0] + 1) / 365.25 diff --git a/examples/10_tracking_diagnostics/pet_pixel_used.py b/examples/10_tracking_diagnostics/pet_pixel_used.py index 63a466c9..3907ce19 100644 --- a/examples/10_tracking_diagnostics/pet_pixel_used.py +++ b/examples/10_tracking_diagnostics/pet_pixel_used.py @@ -14,10 +14,12 @@ # %% # Load an experimental med atlas over a period of 26 years (1993-2019) a = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Anticyclonic.zarr") + py_eddy_tracker_sample.get_demo_path( + "eddies_med_adt_allsat_dt2018/Anticyclonic.zarr" + ) ) c = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") + py_eddy_tracker_sample.get_demo_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") ) # %% diff --git a/examples/10_tracking_diagnostics/pet_propagation.py b/examples/10_tracking_diagnostics/pet_propagation.py index f13b03bb..6a65a212 100644 --- a/examples/10_tracking_diagnostics/pet_propagation.py +++ b/examples/10_tracking_diagnostics/pet_propagation.py @@ -13,10 +13,12 @@ # %% # Load an experimental med atlas over a period of 26 years (1993-2019) a = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Anticyclonic.zarr") + py_eddy_tracker_sample.get_demo_path( + "eddies_med_adt_allsat_dt2018/Anticyclonic.zarr" + ) ) c = TrackEddiesObservations.load_file( - py_eddy_tracker_sample.get_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") + py_eddy_tracker_sample.get_demo_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr") ) nb_year = (a.period[1] - a.period[0] + 1) / 365.25 diff --git a/examples/12_external_data/pet_SST_collocation.py b/examples/12_external_data/pet_SST_collocation.py index 0855f631..defe00df 100644 --- a/examples/12_external_data/pet_SST_collocation.py +++ b/examples/12_external_data/pet_SST_collocation.py @@ -17,8 +17,10 @@ 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( +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" @@ -30,7 +32,7 @@ # ------------ sst = RegularGridDataset(filename=filename_sst, x_name="lon", y_name="lat") alti = RegularGridDataset( - data.get_path(filename_alt), x_name="longitude", y_name="latitude" + data.get_demo_path(filename_alt), x_name="longitude", y_name="latitude" ) # We can use `Grid` tools to interpolate ADT on the sst grid sst.regrid(alti, "sla") diff --git a/examples/14_generic_tools/pet_fit_contour.py b/examples/14_generic_tools/pet_fit_contour.py index ca472e34..9c3f9183 100644 --- a/examples/14_generic_tools/pet_fit_contour.py +++ b/examples/14_generic_tools/pet_fit_contour.py @@ -19,7 +19,7 @@ # %% # Load example identification file -a = EddiesObservations.load_file(data.get_path("Anticyclonic_20190223.nc")) +a = EddiesObservations.load_file(data.get_demo_path("Anticyclonic_20190223.nc")) # %% diff --git a/examples/14_generic_tools/pet_visvalingam.py b/examples/14_generic_tools/pet_visvalingam.py index b946a9db..f7b29c10 100644 --- a/examples/14_generic_tools/pet_visvalingam.py +++ b/examples/14_generic_tools/pet_visvalingam.py @@ -51,7 +51,7 @@ def update_line(num): # %% # Load detection files -a = EddiesObservations.load_file(data.get_path("Anticyclonic_20190223.nc")) +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 diff --git a/examples/16_network/pet_atlas.py b/examples/16_network/pet_atlas.py index d25d4429..540d312d 100644 --- a/examples/16_network/pet_atlas.py +++ b/examples/16_network/pet_atlas.py @@ -6,11 +6,11 @@ from numpy import ma import py_eddy_tracker.gui -from py_eddy_tracker.data import get_remote_sample +from py_eddy_tracker.data import get_remote_demo_sample from py_eddy_tracker.observations.network import NetworkObservations n = NetworkObservations.load_file( - get_remote_sample( + get_remote_demo_sample( "eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc" ) ) diff --git a/examples/16_network/pet_follow_particle.py b/examples/16_network/pet_follow_particle.py index 0a57d346..65746015 100644 --- a/examples/16_network/pet_follow_particle.py +++ b/examples/16_network/pet_follow_particle.py @@ -14,7 +14,7 @@ from py_eddy_tracker import start_logger from py_eddy_tracker.appli.gui import Anim -from py_eddy_tracker.data import get_path +from py_eddy_tracker.data import get_demo_path from py_eddy_tracker.dataset.grid import GridCollection from py_eddy_tracker.observations.network import NetworkObservations from py_eddy_tracker.poly import group_obs @@ -42,12 +42,12 @@ def save(self, *args, **kwargs): # %% -n = NetworkObservations.load_file(get_path("network_med.nc")).network(651) +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_path("dt_med_allsat_phy_l4_2005T2.nc"), + get_demo_path("dt_med_allsat_phy_l4_2005T2.nc"), "longitude", "latitude", "time", diff --git a/examples/16_network/pet_group_anim.py b/examples/16_network/pet_group_anim.py index 9264282a..8ecee534 100644 --- a/examples/16_network/pet_group_anim.py +++ b/examples/16_network/pet_group_anim.py @@ -93,7 +93,7 @@ def get_group_array(self, results, nb_obs): # %% # Get data from period and area -e = EddiesObservations.load_file(data.get_path("network_med.nc")) +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) ) diff --git a/examples/16_network/pet_ioannou_2017_case.py b/examples/16_network/pet_ioannou_2017_case.py index 4ccf3501..7669b010 100644 --- a/examples/16_network/pet_ioannou_2017_case.py +++ b/examples/16_network/pet_ioannou_2017_case.py @@ -18,7 +18,7 @@ import py_eddy_tracker.gui from py_eddy_tracker.appli.gui import Anim -from py_eddy_tracker.data import get_path +from py_eddy_tracker.data import get_demo_path from py_eddy_tracker.observations.network import NetworkObservations @@ -71,7 +71,9 @@ def update_axes(ax, mappable=None): # %% # We know the network ID, we will get directly -ioannou_case = NetworkObservations.load_file(get_path("network_med.nc")).network(651) +ioannou_case = NetworkObservations.load_file(get_demo_path("network_med.nc")).network( + 651 +) print(ioannou_case.infos()) # %% diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index 456b008d..2759edb4 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -13,7 +13,7 @@ # Load data # --------- # Load data where observations are put in same network but no segmentation -n = NetworkObservations.load_file(data.get_path("network_med.nc")).network(651) +n = NetworkObservations.load_file(data.get_demo_path("network_med.nc")).network(651) i = where( (n.lat > 33) * (n.lat < 34) diff --git a/examples/16_network/pet_replay_segmentation.py b/examples/16_network/pet_replay_segmentation.py index 1a296dac..c33028fc 100644 --- a/examples/16_network/pet_replay_segmentation.py +++ b/examples/16_network/pet_replay_segmentation.py @@ -12,7 +12,7 @@ from numpy import where import py_eddy_tracker.gui -from py_eddy_tracker.data import get_path +from py_eddy_tracker.data import get_demo_path from py_eddy_tracker.observations.network import NetworkObservations from py_eddy_tracker.observations.tracking import TrackEddiesObservations @@ -91,7 +91,7 @@ def get_obs(dataset): # %% # Get original network, we will isolate only relative at order *2* -n = NetworkObservations.load_file(get_path("network_med.nc")).network(651) +n = NetworkObservations.load_file(get_demo_path("network_med.nc")).network(651) n_ = n.relative(get_obs(n), order=2) # %% diff --git a/examples/16_network/pet_segmentation_anim.py b/examples/16_network/pet_segmentation_anim.py index 60dae443..b2757809 100644 --- a/examples/16_network/pet_segmentation_anim.py +++ b/examples/16_network/pet_segmentation_anim.py @@ -11,7 +11,7 @@ from numpy import ones, where import py_eddy_tracker.gui -from py_eddy_tracker.data import get_path +from py_eddy_tracker.data import get_demo_path from py_eddy_tracker.observations.network import NetworkObservations from py_eddy_tracker.observations.tracking import TrackEddiesObservations @@ -69,7 +69,7 @@ def get_next_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwarg # Load data where observations are put in same network but no segmentation # Get a known network for the demonstration -n = NetworkObservations.load_file(get_path("network_med.nc")).network(651) +n = NetworkObservations.load_file(get_demo_path("network_med.nc")).network(651) # We keep only some segment n = n.relative(get_obs(n), order=2) print(len(n)) diff --git a/notebooks/python_module/01_general_things/pet_storage.ipynb b/notebooks/python_module/01_general_things/pet_storage.ipynb index b24a8a17..4b4a6630 100644 --- a/notebooks/python_module/01_general_things/pet_storage.ipynb +++ b/notebooks/python_module/01_general_things/pet_storage.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import py_eddy_tracker_sample\n\nfrom py_eddy_tracker.data import get_path, get_remote_sample\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.observation import EddiesObservations, Table\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations" + "import py_eddy_tracker_sample\n\nfrom py_eddy_tracker.data import get_demo_path, get_remote_demo_sample\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.observation import EddiesObservations, Table\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations" ] }, { @@ -51,7 +51,7 @@ }, "outputs": [], "source": [ - "eddies_collections = EddiesObservations.load_file(get_path(\"Cyclonic_20160515.nc\"))\neddies_collections.field_table()\n# offset and scale_factor are used only when data is stored in zarr or netCDF4" + "eddies_collections = EddiesObservations.load_file(get_demo_path(\"Cyclonic_20160515.nc\"))\neddies_collections.field_table()\n# offset and scale_factor are used only when data is stored in zarr or netCDF4" ] }, { @@ -123,7 +123,7 @@ }, "outputs": [], "source": [ - "eddies_tracks = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\n# In this example some fields are removed (effective_contour_longitude,...) in order to save time for doc building\neddies_tracks.field_table()" + "eddies_tracks = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\n# In this example some fields are removed (effective_contour_longitude,...) in order to save time for doc building\neddies_tracks.field_table()" ] }, { @@ -141,7 +141,7 @@ }, "outputs": [], "source": [ - "eddies_network = NetworkObservations.load_file(\n get_remote_sample(\n \"eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc\"\n )\n)\neddies_network.field_table()" + "eddies_network = NetworkObservations.load_file(\n get_remote_demo_sample(\n \"eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc\"\n )\n)\neddies_network.field_table()" ] }, { diff --git a/notebooks/python_module/02_eddy_identification/pet_contour_circle.ipynb b/notebooks/python_module/02_eddy_identification/pet_contour_circle.ipynb index 27bc522a..36989357 100644 --- a/notebooks/python_module/02_eddy_identification/pet_contour_circle.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_contour_circle.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = EddiesObservations.load_file(data.get_path(\"Anticyclonic_20190223.nc\"))" + "a = EddiesObservations.load_file(data.get_demo_path(\"Anticyclonic_20190223.nc\"))" ] }, { diff --git a/notebooks/python_module/02_eddy_identification/pet_display_id.ipynb b/notebooks/python_module/02_eddy_identification/pet_display_id.ipynb index 31abe783..6d40974f 100644 --- a/notebooks/python_module/02_eddy_identification/pet_display_id.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_display_id.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = EddiesObservations.load_file(data.get_path(\"Anticyclonic_20190223.nc\"))\nc = EddiesObservations.load_file(data.get_path(\"Cyclonic_20190223.nc\"))" + "a = EddiesObservations.load_file(data.get_demo_path(\"Anticyclonic_20190223.nc\"))\nc = EddiesObservations.load_file(data.get_demo_path(\"Cyclonic_20190223.nc\"))" ] }, { diff --git a/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb b/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb index d63797ae..679ad2a8 100644 --- a/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "g = RegularGridDataset(\n data.get_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\n\nax = start_axes(\"ADT (m)\")\nm = g.display(ax, \"adt\", vmin=-0.15, vmax=0.15, cmap=\"RdBu_r\")\nupdate_axes(ax, m)" + "g = RegularGridDataset(\n data.get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\n\nax = start_axes(\"ADT (m)\")\nm = g.display(ax, \"adt\", vmin=-0.15, vmax=0.15, cmap=\"RdBu_r\")\nupdate_axes(ax, m)" ] }, { diff --git a/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb b/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb index d9417d22..c2a3648d 100644 --- a/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "margin = 30\n\nkw_data = dict(\n filename=data.get_path(\"nrt_global_allsat_phy_l4_20190223_20190226.nc\"),\n x_name=\"longitude\",\n y_name=\"latitude\",\n # Manual area subset\n indexs=dict(\n latitude=slice(100 - margin, 220 + margin),\n longitude=slice(0, 230 + margin),\n ),\n)\ng_raw = RegularGridDataset(**kw_data)\ng_raw.add_uv(\"adt\")\ng = RegularGridDataset(**kw_data)\ng.copy(\"adt\", \"adt_low\")\ng.bessel_high_filter(\"adt\", 700)\ng.bessel_low_filter(\"adt_low\", 700)\ng.add_uv(\"adt\")" + "margin = 30\n\nkw_data = dict(\n filename=data.get_demo_path(\"nrt_global_allsat_phy_l4_20190223_20190226.nc\"),\n x_name=\"longitude\",\n y_name=\"latitude\",\n # Manual area subset\n indexs=dict(\n latitude=slice(100 - margin, 220 + margin),\n longitude=slice(0, 230 + margin),\n ),\n)\ng_raw = RegularGridDataset(**kw_data)\ng_raw.add_uv(\"adt\")\ng = RegularGridDataset(**kw_data)\ng.copy(\"adt\", \"adt_low\")\ng.bessel_high_filter(\"adt\", 700)\ng.bessel_low_filter(\"adt_low\", 700)\ng.add_uv(\"adt\")" ] }, { diff --git a/notebooks/python_module/02_eddy_identification/pet_eddy_detection_gulf_stream.ipynb b/notebooks/python_module/02_eddy_identification/pet_eddy_detection_gulf_stream.ipynb index cf357d7b..c39bc011 100644 --- a/notebooks/python_module/02_eddy_identification/pet_eddy_detection_gulf_stream.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_eddy_detection_gulf_stream.ipynb @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "margin = 30\ng = RegularGridDataset(\n data.get_path(\"nrt_global_allsat_phy_l4_20190223_20190226.nc\"),\n \"longitude\",\n \"latitude\",\n # Manual area subset\n indexs=dict(\n longitude=slice(1116 - margin, 1216 + margin),\n latitude=slice(476 - margin, 536 + margin),\n ),\n)\n\nax = start_axes(\"ADT (m)\")\nm = g.display(ax, \"adt\", vmin=-1, vmax=1, cmap=\"RdBu_r\")\n# Draw line on the gulf stream front\ngreat_current = Contours(g.x_c, g.y_c, g.grid(\"adt\"), levels=(0.35,), keep_unclose=True)\ngreat_current.display(ax, color=\"k\")\nupdate_axes(ax, m)" + "margin = 30\ng = RegularGridDataset(\n data.get_demo_path(\"nrt_global_allsat_phy_l4_20190223_20190226.nc\"),\n \"longitude\",\n \"latitude\",\n # Manual area subset\n indexs=dict(\n longitude=slice(1116 - margin, 1216 + margin),\n latitude=slice(476 - margin, 536 + margin),\n ),\n)\n\nax = start_axes(\"ADT (m)\")\nm = g.display(ax, \"adt\", vmin=-1, vmax=1, cmap=\"RdBu_r\")\n# Draw line on the gulf stream front\ngreat_current = Contours(g.x_c, g.y_c, g.grid(\"adt\"), levels=(0.35,), keep_unclose=True)\ngreat_current.display(ax, color=\"k\")\nupdate_axes(ax, m)" ] }, { diff --git a/notebooks/python_module/02_eddy_identification/pet_filter_and_detection.ipynb b/notebooks/python_module/02_eddy_identification/pet_filter_and_detection.ipynb index 4dec3709..2276317a 100644 --- a/notebooks/python_module/02_eddy_identification/pet_filter_and_detection.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_filter_and_detection.ipynb @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "g = RegularGridDataset(\n data.get_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\ng.add_uv(\"adt\")\ng.copy(\"adt\", \"adt_high\")\nwavelength = 800\ng.bessel_high_filter(\"adt_high\", wavelength)\ndate = datetime(2016, 5, 15)" + "g = RegularGridDataset(\n data.get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\ng.add_uv(\"adt\")\ng.copy(\"adt\", \"adt_high\")\nwavelength = 800\ng.bessel_high_filter(\"adt_high\", wavelength)\ndate = datetime(2016, 5, 15)" ] }, { diff --git a/notebooks/python_module/02_eddy_identification/pet_interp_grid_on_dataset.ipynb b/notebooks/python_module/02_eddy_identification/pet_interp_grid_on_dataset.ipynb index 8207f8d1..203a7362 100644 --- a/notebooks/python_module/02_eddy_identification/pet_interp_grid_on_dataset.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_interp_grid_on_dataset.ipynb @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "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)\naviso_map.add_uv(\"adt\")" + "a = EddiesObservations.load_file(data.get_demo_path(\"Anticyclonic_20160515.nc\"))\nc = EddiesObservations.load_file(data.get_demo_path(\"Cyclonic_20160515.nc\"))\n\naviso_map = RegularGridDataset(\n data.get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\naviso_map.add_uv(\"adt\")" ] }, { diff --git a/notebooks/python_module/02_eddy_identification/pet_radius_vs_area.ipynb b/notebooks/python_module/02_eddy_identification/pet_radius_vs_area.ipynb index 8ab39ebc..c70f7dd6 100644 --- a/notebooks/python_module/02_eddy_identification/pet_radius_vs_area.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_radius_vs_area.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = EddiesObservations.load_file(data.get_path(\"Anticyclonic_20190223.nc\"))\nareas = list()\n# For each contour area will be compute in local reference\nfor i in a:\n x, y = coordinates_to_local(\n i[\"contour_lon_s\"], i[\"contour_lat_s\"], i[\"lon\"], i[\"lat\"]\n )\n areas.append(poly_area(x, y))\nareas = array(areas)" + "a = EddiesObservations.load_file(data.get_demo_path(\"Anticyclonic_20190223.nc\"))\nareas = list()\n# For each contour area will be compute in local reference\nfor i in a:\n x, y = coordinates_to_local(\n i[\"contour_lon_s\"], i[\"contour_lat_s\"], i[\"lon\"], i[\"lat\"]\n )\n areas.append(poly_area(x, y))\nareas = array(areas)" ] }, { diff --git a/notebooks/python_module/02_eddy_identification/pet_shape_gallery.ipynb b/notebooks/python_module/02_eddy_identification/pet_shape_gallery.ipynb index f367d7e2..65091120 100644 --- a/notebooks/python_module/02_eddy_identification/pet_shape_gallery.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_shape_gallery.ipynb @@ -62,7 +62,7 @@ }, "outputs": [], "source": [ - "g = RegularGridDataset(\n data.get_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\nc = Contours(g.x_c, g.y_c, g.grid(\"adt\") * 100, arange(-50, 50, 0.2))\ncontours = dict()\nfor coll in c.iter():\n for current_contour in coll.get_paths():\n _, _, _, aerr = current_contour.fit_circle()\n i = int(aerr // 4) + 1\n if i not in contours:\n contours[i] = list()\n contours[i].append(current_contour)" + "g = RegularGridDataset(\n data.get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\nc = Contours(g.x_c, g.y_c, g.grid(\"adt\") * 100, arange(-50, 50, 0.2))\ncontours = dict()\nfor coll in c.iter():\n for current_contour in coll.get_paths():\n _, _, _, aerr = current_contour.fit_circle()\n i = int(aerr // 4) + 1\n if i not in contours:\n contours[i] = list()\n contours[i].append(current_contour)" ] }, { diff --git a/notebooks/python_module/02_eddy_identification/pet_sla_and_adt.ipynb b/notebooks/python_module/02_eddy_identification/pet_sla_and_adt.ipynb index 083a5a5a..3c40e49f 100644 --- a/notebooks/python_module/02_eddy_identification/pet_sla_and_adt.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_sla_and_adt.ipynb @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "g = RegularGridDataset(\n data.get_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\ng.add_uv(\"adt\", \"ugos\", \"vgos\")\ng.add_uv(\"sla\", \"ugosa\", \"vgosa\")\nwavelength = 400\ng.copy(\"adt\", \"adt_raw\")\ng.copy(\"sla\", \"sla_raw\")\ng.bessel_high_filter(\"adt\", wavelength)\ng.bessel_high_filter(\"sla\", wavelength)\ndate = datetime(2016, 5, 15)" + "g = RegularGridDataset(\n data.get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\ng.add_uv(\"adt\", \"ugos\", \"vgos\")\ng.add_uv(\"sla\", \"ugosa\", \"vgosa\")\nwavelength = 400\ng.copy(\"adt\", \"adt_raw\")\ng.copy(\"sla\", \"sla_raw\")\ng.bessel_high_filter(\"adt\", wavelength)\ng.bessel_high_filter(\"sla\", wavelength)\ndate = datetime(2016, 5, 15)" ] }, { diff --git a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb index 5de7c46a..53725a05 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, isnan, meshgrid, ones\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\nfrom py_eddy_tracker.observations.observation import EddiesObservations" + "import re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, isnan, meshgrid, ones\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\nfrom py_eddy_tracker.observations.observation import EddiesObservations" ] }, { @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "g = RegularGridDataset(\n get_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\n# Compute u/v from height\ng.add_uv(\"adt\")" + "g = RegularGridDataset(\n get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\n# Compute u/v from height\ng.add_uv(\"adt\")" ] }, { @@ -62,7 +62,7 @@ }, "outputs": [], "source": [ - "a = EddiesObservations.load_file(get_path(\"Anticyclonic_20160515.nc\"))\nc = EddiesObservations.load_file(get_path(\"Cyclonic_20160515.nc\"))" + "a = EddiesObservations.load_file(get_demo_path(\"Anticyclonic_20160515.nc\"))\nc = EddiesObservations.load_file(get_demo_path(\"Cyclonic_20160515.nc\"))" ] }, { diff --git a/notebooks/python_module/06_grid_manipulation/pet_filter.ipynb b/notebooks/python_module/06_grid_manipulation/pet_filter.ipynb index dcc9c0d3..abf4553e 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_filter.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_filter.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "g = RegularGridDataset(\n data.get_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)" + "g = RegularGridDataset(\n data.get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)" ] }, { diff --git a/notebooks/python_module/06_grid_manipulation/pet_hide_pixel_out_eddies.ipynb b/notebooks/python_module/06_grid_manipulation/pet_hide_pixel_out_eddies.ipynb index 9ef65cb5..c9bca31e 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_hide_pixel_out_eddies.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_hide_pixel_out_eddies.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = EddiesObservations.load_file(data.get_path(\"Anticyclonic_20190223.nc\"))" + "a = EddiesObservations.load_file(data.get_demo_path(\"Anticyclonic_20190223.nc\"))" ] }, { @@ -62,7 +62,7 @@ }, "outputs": [], "source": [ - "g = RegularGridDataset(\n data.get_path(\"nrt_global_allsat_phy_l4_20190223_20190226.nc\"),\n \"longitude\",\n \"latitude\",\n)" + "g = RegularGridDataset(\n data.get_demo_path(\"nrt_global_allsat_phy_l4_20190223_20190226.nc\"),\n \"longitude\",\n \"latitude\",\n)" ] }, { diff --git a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb index be1a9c78..fdd7768c 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, meshgrid, zeros\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\nfrom py_eddy_tracker.observations.observation import EddiesObservations" + "import re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, meshgrid, zeros\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\nfrom py_eddy_tracker.observations.observation import EddiesObservations" ] }, { @@ -66,7 +66,7 @@ }, "outputs": [], "source": [ - "g = RegularGridDataset(\n get_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\ng.add_uv(\"adt\")\nu_y = g.compute_stencil(g.grid(\"u\"), vertical=True)\nv_x = g.compute_stencil(g.grid(\"v\"))\ng.vars[\"vort\"] = v_x - u_y" + "g = RegularGridDataset(\n get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\ng.add_uv(\"adt\")\nu_y = g.compute_stencil(g.grid(\"u\"), vertical=True)\nv_x = g.compute_stencil(g.grid(\"v\"))\ng.vars[\"vort\"] = v_x - u_y" ] }, { @@ -181,7 +181,7 @@ }, "outputs": [], "source": [ - "fig, ax, _ = start_ax()\nmappable = lavd.display(ax, \"lavd\", **kw_vorticity)\nEddiesObservations.load_file(get_path(\"Anticyclonic_20160515.nc\")).display(\n ax, color=\"k\"\n)\nEddiesObservations.load_file(get_path(\"Cyclonic_20160515.nc\")).display(ax, color=\"k\")\n_ = update_axes(ax, mappable)" + "fig, ax, _ = start_ax()\nmappable = lavd.display(ax, \"lavd\", **kw_vorticity)\nEddiesObservations.load_file(get_demo_path(\"Anticyclonic_20160515.nc\")).display(\n ax, color=\"k\"\n)\nEddiesObservations.load_file(get_demo_path(\"Cyclonic_20160515.nc\")).display(ax, color=\"k\")\n_ = update_axes(ax, mappable)" ] } ], diff --git a/notebooks/python_module/06_grid_manipulation/pet_okubo_weiss.ipynb b/notebooks/python_module/06_grid_manipulation/pet_okubo_weiss.ipynb index 73abbcda..b410be0a 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_okubo_weiss.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_okubo_weiss.ipynb @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "a = EddiesObservations.load_file(data.get_path(\"Anticyclonic_20190223.nc\"))\nc = EddiesObservations.load_file(data.get_path(\"Cyclonic_20190223.nc\"))" + "a = EddiesObservations.load_file(data.get_demo_path(\"Anticyclonic_20190223.nc\"))\nc = EddiesObservations.load_file(data.get_demo_path(\"Cyclonic_20190223.nc\"))" ] }, { @@ -73,7 +73,7 @@ }, "outputs": [], "source": [ - "g = RegularGridDataset(\n data.get_path(\"nrt_global_allsat_phy_l4_20190223_20190226.nc\"),\n \"longitude\",\n \"latitude\",\n)\n\nax = start_axes(\"ADT (cm)\")\nm = g.display(ax, \"adt\", vmin=-120, vmax=120, factor=100)\nupdate_axes(ax, m)" + "g = RegularGridDataset(\n data.get_demo_path(\"nrt_global_allsat_phy_l4_20190223_20190226.nc\"),\n \"longitude\",\n \"latitude\",\n)\n\nax = start_axes(\"ADT (cm)\")\nm = g.display(ax, \"adt\", vmin=-120, vmax=120, factor=100)\nupdate_axes(ax, m)" ] }, { diff --git a/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb b/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb index aa9ad093..63cd36dc 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "# sphinx_gallery_thumbnail_number = 2\nimport re\nfrom datetime import datetime, timedelta\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, isnan, meshgrid, ones\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.dataset.grid import GridCollection\n\nstart_logger().setLevel(\"ERROR\")" + "# sphinx_gallery_thumbnail_number = 2\nimport re\nfrom datetime import datetime, timedelta\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, isnan, meshgrid, ones\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import GridCollection\n\nstart_logger().setLevel(\"ERROR\")" ] }, { @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "c = GridCollection.from_netcdf_cube(\n get_path(\"dt_med_allsat_phy_l4_2005T2.nc\"),\n \"longitude\",\n \"latitude\",\n \"time\",\n # To create U/V variable\n heigth=\"adt\",\n)" + "c = GridCollection.from_netcdf_cube(\n get_demo_path(\"dt_med_allsat_phy_l4_2005T2.nc\"),\n \"longitude\",\n \"latitude\",\n \"time\",\n # To create U/V variable\n heigth=\"adt\",\n)" ] }, { diff --git a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb index f42b3e43..e821df6d 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "from matplotlib import pyplot as plt\nfrom numba import njit\nfrom numpy import arange, arctan2, empty, isnan, log2, ma, meshgrid, ones, pi, zeros\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.dataset.grid import GridCollection, RegularGridDataset\n\nstart_logger().setLevel(\"ERROR\")" + "from matplotlib import pyplot as plt\nfrom numba import njit\nfrom numpy import arange, arctan2, empty, isnan, log2, ma, meshgrid, ones, pi, zeros\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import GridCollection, RegularGridDataset\n\nstart_logger().setLevel(\"ERROR\")" ] }, { @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "c = GridCollection.from_netcdf_cube(\n get_path(\"dt_med_allsat_phy_l4_2005T2.nc\"),\n \"longitude\",\n \"latitude\",\n \"time\",\n # To create U/V variable\n heigth=\"adt\",\n)" + "c = GridCollection.from_netcdf_cube(\n get_demo_path(\"dt_med_allsat_phy_l4_2005T2.nc\"),\n \"longitude\",\n \"latitude\",\n \"time\",\n # To create U/V variable\n heigth=\"adt\",\n)" ] }, { diff --git a/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb b/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb index afc17825..e123abe4 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "from datetime import datetime\n\nfrom matplotlib import pyplot as plt\nfrom numpy import arange, isnan, ma, meshgrid, zeros\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.dataset.grid import GridCollection, RegularGridDataset\n\nstart_logger().setLevel(\"ERROR\")" + "from datetime import datetime\n\nfrom matplotlib import pyplot as plt\nfrom numpy import arange, isnan, ma, meshgrid, zeros\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import GridCollection, RegularGridDataset\n\nstart_logger().setLevel(\"ERROR\")" ] }, { @@ -66,7 +66,7 @@ }, "outputs": [], "source": [ - "# Load data cube of 3 month\nc = GridCollection.from_netcdf_cube(\n get_path(\"dt_med_allsat_phy_l4_2005T2.nc\"),\n \"longitude\",\n \"latitude\",\n \"time\",\n heigth=\"adt\",\n)\n\n# Add vorticity at each time step\nfor g in c:\n u_y = g.compute_stencil(g.grid(\"u\"), vertical=True)\n v_x = g.compute_stencil(g.grid(\"v\"))\n g.vars[\"vort\"] = v_x - u_y" + "# Load data cube of 3 month\nc = GridCollection.from_netcdf_cube(\n get_demo_path(\"dt_med_allsat_phy_l4_2005T2.nc\"),\n \"longitude\",\n \"latitude\",\n \"time\",\n heigth=\"adt\",\n)\n\n# Add vorticity at each time step\nfor g in c:\n u_y = g.compute_stencil(g.grid(\"u\"), vertical=True)\n v_x = g.compute_stencil(g.grid(\"v\"))\n g.vars[\"vort\"] = v_x - u_y" ] }, { diff --git a/notebooks/python_module/08_tracking_manipulation/pet_display_field.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_display_field.ipynb index 58e4ff06..bf924b36 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_display_field.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_display_field.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "c = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nc = c.extract_with_length((180, -1))" + "c = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nc = c.extract_with_length((180, -1))" ] }, { diff --git a/notebooks/python_module/08_tracking_manipulation/pet_display_track.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_display_track.ipynb index edb20deb..2d7b600d 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_display_track.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_display_track.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nprint(a)" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nprint(a)" ] }, { diff --git a/notebooks/python_module/08_tracking_manipulation/pet_one_track.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_one_track.ipynb index 13d5a9a3..d1529e26 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_one_track.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_one_track.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\neddy = a.extract_ids([9672])\neddy_f = a.extract_ids([9672])\neddy_f.position_filter(median_half_window=1, loess_half_window=5)" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\neddy = a.extract_ids([9672])\neddy_f = a.extract_ids([9672])\neddy_f.position_filter(median_half_window=1, loess_half_window=5)" ] }, { diff --git a/notebooks/python_module/08_tracking_manipulation/pet_run_a_tracking.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_run_a_tracking.ipynb index 3b5cc8e5..e8871283 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_run_a_tracking.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_run_a_tracking.ipynb @@ -26,14 +26,14 @@ }, "outputs": [], "source": [ - "from py_eddy_tracker.data import get_remote_sample\nfrom py_eddy_tracker.featured_tracking.area_tracker import AreaTracker\nfrom py_eddy_tracker.gui import GUI\nfrom py_eddy_tracker.tracking import Correspondances" + "from py_eddy_tracker.data import get_remote_demo_sample\nfrom py_eddy_tracker.featured_tracking.area_tracker import AreaTracker\nfrom py_eddy_tracker.gui import GUI\nfrom py_eddy_tracker.tracking import Correspondances" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Get remote data, we will keep only 180 first days,\n`get_remote_sample` function is only to get demo dataset, in your own case give a list of identification filename\nand don't mix cyclonic and anticyclonic files.\n\n" + "Get remote data, we will keep only 180 first days,\n`get_remote_demo_sample` function is only to get demo dataset, in your own case give a list of identification filename\nand don't mix cyclonic and anticyclonic files.\n\n" ] }, { @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "file_objects = get_remote_sample(\n \"eddies_med_adt_allsat_dt2018/Anticyclonic_2010_2011_2012\"\n)[:180]" + "file_objects = get_remote_demo_sample(\n \"eddies_med_adt_allsat_dt2018/Anticyclonic_2010_2011_2012\"\n)[:180]" ] }, { diff --git a/notebooks/python_module/08_tracking_manipulation/pet_select_track_across_area.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_select_track_across_area.ipynb index df79f8ea..5ba0d481 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_select_track_across_area.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_select_track_across_area.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "c = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nc.position_filter(median_half_window=1, loess_half_window=5)" + "c = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nc.position_filter(median_half_window=1, loess_half_window=5)" ] }, { diff --git a/notebooks/python_module/08_tracking_manipulation/pet_track_anim.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_track_anim.ipynb index 9a2510b2..402eb6a4 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_track_anim.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_track_anim.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\n# We get only 300 first step to save time of documentation builder\neddy = a.extract_ids([9672]).index(slice(0, 300))" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\n# We get only 300 first step to save time of documentation builder\neddy = a.extract_ids([9672]).index(slice(0, 300))" ] }, { diff --git a/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb index 4b35ba38..eb028afa 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\neddy = a.extract_ids([9672])" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\neddy = a.extract_ids([9672])" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_birth_and_death.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_birth_and_death.ipynb index 739b907a..e1824f22 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_birth_and_death.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_birth_and_death.ipynb @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "kwargs_load = dict(\n include_vars=(\n \"longitude\",\n \"latitude\",\n \"observation_number\",\n \"track\",\n \"time\",\n \"speed_contour_longitude\",\n \"speed_contour_latitude\",\n )\n)\na = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)" + "kwargs_load = dict(\n include_vars=(\n \"longitude\",\n \"latitude\",\n \"observation_number\",\n \"track\",\n \"time\",\n \"speed_contour_longitude\",\n \"speed_contour_latitude\",\n )\n)\na = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb index 023b9178..1f2d5b6a 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_geographic_stats.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_geographic_stats.ipynb index 28bf4579..ff42b21d 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_geographic_stats.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_geographic_stats.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\na = a.merge(c)\n\nstep = 0.1" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\na = a.merge(c)\n\nstep = 0.1" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_groups.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_groups.ipynb index 944167fd..55d299d4 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_groups.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_groups.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_histo.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_histo.ipynb index c28ff02a..1d8251d1 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_histo.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_histo.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nkwargs_a = dict(label=\"Anticyclonic\", color=\"r\", histtype=\"step\", density=True)\nkwargs_c = dict(label=\"Cyclonic\", color=\"b\", histtype=\"step\", density=True)" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nkwargs_a = dict(label=\"Anticyclonic\", color=\"r\", histtype=\"step\", density=True)\nkwargs_c = dict(label=\"Cyclonic\", color=\"b\", histtype=\"step\", density=True)" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_lifetime.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_lifetime.ipynb index 40cc8e73..4aa3304f 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_lifetime.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_lifetime.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nnb_year = (a.period[1] - a.period[0] + 1) / 365.25" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nnb_year = (a.period[1] - a.period[0] + 1) / 365.25" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb index 14141cd1..43929105 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_propagation.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_propagation.ipynb index 3cfb6140..da8f0976 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_propagation.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_propagation.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nnb_year = (a.period[1] - a.period[0] + 1) / 365.25" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nnb_year = (a.period[1] - a.period[0] + 1) / 365.25" ] }, { diff --git a/notebooks/python_module/12_external_data/pet_SST_collocation.ipynb b/notebooks/python_module/12_external_data/pet_SST_collocation.ipynb index 025b62d0..1d22e1ef 100644 --- a/notebooks/python_module/12_external_data/pet_SST_collocation.ipynb +++ b/notebooks/python_module/12_external_data/pet_SST_collocation.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "from datetime import datetime\n\nfrom matplotlib import pyplot as plt\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\n\ndate = datetime(2016, 7, 7)\n\nfilename_alt = data.get_path(f\"dt_blacksea_allsat_phy_l4_{date:%Y%m%d}_20200801.nc\")\nfilename_sst = data.get_path(\n f\"{date:%Y%m%d}000000-GOS-L4_GHRSST-SSTfnd-OISST_HR_REP-BLK-v02.0-fv01.0.nc\"\n)\nvar_name_sst = \"analysed_sst\"\n\nextent = [27, 42, 40.5, 47]" + "from datetime import datetime\n\nfrom matplotlib import pyplot as plt\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\n\ndate = datetime(2016, 7, 7)\n\nfilename_alt = data.get_demo_path(f\"dt_blacksea_allsat_phy_l4_{date:%Y%m%d}_20200801.nc\")\nfilename_sst = data.get_demo_path(\n f\"{date:%Y%m%d}000000-GOS-L4_GHRSST-SSTfnd-OISST_HR_REP-BLK-v02.0-fv01.0.nc\"\n)\nvar_name_sst = \"analysed_sst\"\n\nextent = [27, 42, 40.5, 47]" ] }, { @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "sst = RegularGridDataset(filename=filename_sst, x_name=\"lon\", y_name=\"lat\")\nalti = RegularGridDataset(\n data.get_path(filename_alt), x_name=\"longitude\", y_name=\"latitude\"\n)\n# We can use `Grid` tools to interpolate ADT on the sst grid\nsst.regrid(alti, \"sla\")\nsst.add_uv(\"sla\")" + "sst = RegularGridDataset(filename=filename_sst, x_name=\"lon\", y_name=\"lat\")\nalti = RegularGridDataset(\n data.get_demo_path(filename_alt), x_name=\"longitude\", y_name=\"latitude\"\n)\n# We can use `Grid` tools to interpolate ADT on the sst grid\nsst.regrid(alti, \"sla\")\nsst.add_uv(\"sla\")" ] }, { diff --git a/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb b/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb index 9f5bbc84..4cec72b2 100644 --- a/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb +++ b/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = EddiesObservations.load_file(data.get_path(\"Anticyclonic_20190223.nc\"))" + "a = EddiesObservations.load_file(data.get_demo_path(\"Anticyclonic_20190223.nc\"))" ] }, { diff --git a/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb b/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb index b593f21b..0183abde 100644 --- a/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb +++ b/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = EddiesObservations.load_file(data.get_path(\"Anticyclonic_20190223.nc\"))\na = a.extract_with_mask((abs(a.lat) < 66) * (abs(a.radius_e) > 80e3))\n\nnb_pt = 10\nx_v, y_v = visvalingam_polys(a.contour_lon_e, a.contour_lat_e, nb_pt)\nx_u, y_u = uniform_resample_polys(a.contour_lon_e, a.contour_lat_e, nb_pt)\nscores_v = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_v, y_v) * 100.0\nscores_u = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_u, y_u) * 100.0\nd_6 = scores_v - scores_u\nnb_pt = 18\nx_v, y_v = visvalingam_polys(a.contour_lon_e, a.contour_lat_e, nb_pt)\nx_u, y_u = uniform_resample_polys(a.contour_lon_e, a.contour_lat_e, nb_pt)\nscores_v = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_v, y_v) * 100.0\nscores_u = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_u, y_u) * 100.0\nd_12 = scores_v - scores_u\na = a.index(array((d_6.argmin(), d_6.argmax(), d_12.argmin(), d_12.argmax())))" + "a = EddiesObservations.load_file(data.get_demo_path(\"Anticyclonic_20190223.nc\"))\na = a.extract_with_mask((abs(a.lat) < 66) * (abs(a.radius_e) > 80e3))\n\nnb_pt = 10\nx_v, y_v = visvalingam_polys(a.contour_lon_e, a.contour_lat_e, nb_pt)\nx_u, y_u = uniform_resample_polys(a.contour_lon_e, a.contour_lat_e, nb_pt)\nscores_v = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_v, y_v) * 100.0\nscores_u = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_u, y_u) * 100.0\nd_6 = scores_v - scores_u\nnb_pt = 18\nx_v, y_v = visvalingam_polys(a.contour_lon_e, a.contour_lat_e, nb_pt)\nx_u, y_u = uniform_resample_polys(a.contour_lon_e, a.contour_lat_e, nb_pt)\nscores_v = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_v, y_v) * 100.0\nscores_u = vertice_overlap(a.contour_lon_e, a.contour_lat_e, x_u, y_u) * 100.0\nd_12 = scores_v - scores_u\na = a.index(array((d_6.argmin(), d_6.argmax(), d_12.argmin(), d_12.argmax())))" ] }, { diff --git a/notebooks/python_module/16_network/pet_atlas.ipynb b/notebooks/python_module/16_network/pet_atlas.ipynb index c53e4b23..514317a6 100644 --- a/notebooks/python_module/16_network/pet_atlas.ipynb +++ b/notebooks/python_module/16_network/pet_atlas.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "from matplotlib import pyplot as plt\nfrom numpy import ma\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_remote_sample\nfrom py_eddy_tracker.observations.network import NetworkObservations\n\nn = NetworkObservations.load_file(\n get_remote_sample(\n \"eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc\"\n )\n)" + "from matplotlib import pyplot as plt\nfrom numpy import ma\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_remote_demo_sample\nfrom py_eddy_tracker.observations.network import NetworkObservations\n\nn = NetworkObservations.load_file(\n get_remote_demo_sample(\n \"eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc\"\n )\n)" ] }, { diff --git a/notebooks/python_module/16_network/pet_follow_particle.ipynb b/notebooks/python_module/16_network/pet_follow_particle.ipynb index 580c848c..30c85a49 100644 --- a/notebooks/python_module/16_network/pet_follow_particle.ipynb +++ b/notebooks/python_module/16_network/pet_follow_particle.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import re\n\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numba import njit\nfrom numba import types as nb_types\nfrom numpy import arange, meshgrid, ones, unique, where, zeros\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.dataset.grid import GridCollection\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.poly import group_obs\n\nstart_logger().setLevel(\"ERROR\")" + "import re\n\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numba import njit\nfrom numba import types as nb_types\nfrom numpy import arange, meshgrid, ones, unique, where, zeros\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import GridCollection\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.poly import group_obs\n\nstart_logger().setLevel(\"ERROR\")" ] }, { @@ -48,7 +48,7 @@ }, "outputs": [], "source": [ - "n = NetworkObservations.load_file(get_path(\"network_med.nc\")).network(651)\nn = n.extract_with_mask((n.time >= 20180) * (n.time <= 20269))\nn = n.remove_dead_end(nobs=0, ndays=10)\nn.numbering_segment()\nc = GridCollection.from_netcdf_cube(\n get_path(\"dt_med_allsat_phy_l4_2005T2.nc\"),\n \"longitude\",\n \"latitude\",\n \"time\",\n heigth=\"adt\",\n)" + "n = NetworkObservations.load_file(get_demo_path(\"network_med.nc\")).network(651)\nn = n.extract_with_mask((n.time >= 20180) * (n.time <= 20269))\nn = n.remove_dead_end(nobs=0, ndays=10)\nn.numbering_segment()\nc = GridCollection.from_netcdf_cube(\n get_demo_path(\"dt_med_allsat_phy_l4_2005T2.nc\"),\n \"longitude\",\n \"latitude\",\n \"time\",\n heigth=\"adt\",\n)" ] }, { diff --git a/notebooks/python_module/16_network/pet_group_anim.ipynb b/notebooks/python_module/16_network/pet_group_anim.ipynb index 6983bd21..ffb9dd17 100644 --- a/notebooks/python_module/16_network/pet_group_anim.ipynb +++ b/notebooks/python_module/16_network/pet_group_anim.ipynb @@ -102,7 +102,7 @@ }, "outputs": [], "source": [ - "e = EddiesObservations.load_file(data.get_path(\"network_med.nc\"))\ne = e.extract_with_mask((e.time >= t0) * (e.time < t1)).extract_with_area(\n dict(llcrnrlon=25, urcrnrlon=35, llcrnrlat=31, urcrnrlat=37.5)\n)" + "e = EddiesObservations.load_file(data.get_demo_path(\"network_med.nc\"))\ne = e.extract_with_mask((e.time >= t0) * (e.time < t1)).extract_with_area(\n dict(llcrnrlon=25, urcrnrlon=35, llcrnrlat=31, urcrnrlat=37.5)\n)" ] }, { diff --git a/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb b/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb index 7019b1fa..d4ef20f3 100644 --- a/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb +++ b/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import re\nfrom datetime import datetime, timedelta\n\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.ticker import FuncFormatter\nfrom numpy import arange, where\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.observations.network import NetworkObservations" + "import re\nfrom datetime import datetime, timedelta\n\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.ticker import FuncFormatter\nfrom numpy import arange, where\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.observations.network import NetworkObservations" ] }, { @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "ioannou_case = NetworkObservations.load_file(get_path(\"network_med.nc\")).network(651)\nprint(ioannou_case.infos())" + "ioannou_case = NetworkObservations.load_file(get_demo_path(\"network_med.nc\")).network(651)\nprint(ioannou_case.infos())" ] }, { diff --git a/notebooks/python_module/16_network/pet_relative.ipynb b/notebooks/python_module/16_network/pet_relative.ipynb index 85744514..23537375 100644 --- a/notebooks/python_module/16_network/pet_relative.ipynb +++ b/notebooks/python_module/16_network/pet_relative.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "n = NetworkObservations.load_file(data.get_path(\"network_med.nc\")).network(651)\ni = where(\n (n.lat > 33)\n * (n.lat < 34)\n * (n.lon > 22)\n * (n.lon < 23)\n * (n.time > 20630)\n * (n.time < 20650)\n)[0][0]\n# For event use\nn2 = n.relative(i, order=2)\nn = n.relative(i, order=4)\nn.numbering_segment()" + "n = NetworkObservations.load_file(data.get_demo_path(\"network_med.nc\")).network(651)\ni = where(\n (n.lat > 33)\n * (n.lat < 34)\n * (n.lon > 22)\n * (n.lon < 23)\n * (n.time > 20630)\n * (n.time < 20650)\n)[0][0]\n# For event use\nn2 = n.relative(i, order=2)\nn = n.relative(i, order=4)\nn.numbering_segment()" ] }, { diff --git a/notebooks/python_module/16_network/pet_replay_segmentation.ipynb b/notebooks/python_module/16_network/pet_replay_segmentation.ipynb index 01ddbcfc..7acb3f51 100644 --- a/notebooks/python_module/16_network/pet_replay_segmentation.ipynb +++ b/notebooks/python_module/16_network/pet_replay_segmentation.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "from datetime import datetime, timedelta\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.ticker import FuncFormatter\nfrom numpy import where\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations\n\n\n@FuncFormatter\ndef formatter(x, pos):\n return (timedelta(x) + datetime(1950, 1, 1)).strftime(\"%d/%m/%Y\")\n\n\ndef start_axes(title=\"\"):\n fig = plt.figure(figsize=(13, 6))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=\"full_axes\")\n ax.set_xlim(19, 29), ax.set_ylim(31, 35.5)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n return ax\n\n\ndef timeline_axes(title=\"\"):\n fig = plt.figure(figsize=(15, 5))\n ax = fig.add_axes([0.04, 0.06, 0.89, 0.88])\n ax.set_title(title, weight=\"bold\")\n ax.xaxis.set_major_formatter(formatter), ax.grid()\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid(True)\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" + "from datetime import datetime, timedelta\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.ticker import FuncFormatter\nfrom numpy import where\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations\n\n\n@FuncFormatter\ndef formatter(x, pos):\n return (timedelta(x) + datetime(1950, 1, 1)).strftime(\"%d/%m/%Y\")\n\n\ndef start_axes(title=\"\"):\n fig = plt.figure(figsize=(13, 6))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=\"full_axes\")\n ax.set_xlim(19, 29), ax.set_ylim(31, 35.5)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n return ax\n\n\ndef timeline_axes(title=\"\"):\n fig = plt.figure(figsize=(15, 5))\n ax = fig.add_axes([0.04, 0.06, 0.89, 0.88])\n ax.set_title(title, weight=\"bold\")\n ax.xaxis.set_major_formatter(formatter), ax.grid()\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid(True)\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" ] }, { @@ -62,7 +62,7 @@ }, "outputs": [], "source": [ - "n = NetworkObservations.load_file(get_path(\"network_med.nc\")).network(651)\nn_ = n.relative(get_obs(n), order=2)" + "n = NetworkObservations.load_file(get_demo_path(\"network_med.nc\")).network(651)\nn_ = n.relative(get_obs(n), order=2)" ] }, { diff --git a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb index 2095ad14..18da8478 100644 --- a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb +++ b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "# sphinx_gallery_thumbnail_number = 2\nimport re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.colors import ListedColormap\nfrom numpy import ones, where\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_path\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations" + "# sphinx_gallery_thumbnail_number = 2\nimport re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.colors import ListedColormap\nfrom numpy import ones, where\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations" ] }, { @@ -73,7 +73,7 @@ }, "outputs": [], "source": [ - "# Get a known network for the demonstration\nn = NetworkObservations.load_file(get_path(\"network_med.nc\")).network(651)\n# We keep only some segment\nn = n.relative(get_obs(n), order=2)\nprint(len(n))\n# We convert and order object like segmentation was never happen on observations\ne = n.astype(MyTrack)\ne.obs.sort(order=(\"track\", \"time\"), kind=\"stable\")" + "# Get a known network for the demonstration\nn = NetworkObservations.load_file(get_demo_path(\"network_med.nc\")).network(651)\n# We keep only some segment\nn = n.relative(get_obs(n), order=2)\nprint(len(n))\n# We convert and order object like segmentation was never happen on observations\ne = n.astype(MyTrack)\ne.obs.sort(order=(\"track\", \"time\"), kind=\"stable\")" ] }, { diff --git a/src/py_eddy_tracker/data/__init__.py b/src/py_eddy_tracker/data/__init__.py index 59df8a0f..4702af8f 100644 --- a/src/py_eddy_tracker/data/__init__.py +++ b/src/py_eddy_tracker/data/__init__.py @@ -16,11 +16,11 @@ import requests -def get_path(name): +def get_demo_path(name): return path.join(path.dirname(__file__), name) -def get_remote_sample(path): +def get_remote_demo_sample(path): if path.startswith("/") or path.startswith("."): content = open(path, "rb").read() if path.endswith(".nc"): diff --git a/tests/test_grid.py b/tests/test_grid.py index a7de8f8b..2c89550a 100644 --- a/tests/test_grid.py +++ b/tests/test_grid.py @@ -2,10 +2,10 @@ from numpy import array, isnan, ma from pytest import approx -from py_eddy_tracker.data import get_path +from py_eddy_tracker.data import get_demo_path from py_eddy_tracker.dataset.grid import RegularGridDataset -G = RegularGridDataset(get_path("mask_1_60.nc"), "lon", "lat") +G = RegularGridDataset(get_demo_path("mask_1_60.nc"), "lon", "lat") X = 0.025 contour = Path( ( diff --git a/tests/test_id.py b/tests/test_id.py index cedcdff8..c69a5a26 100644 --- a/tests/test_id.py +++ b/tests/test_id.py @@ -1,10 +1,10 @@ from datetime import datetime -from py_eddy_tracker.data import get_path +from py_eddy_tracker.data import get_demo_path from py_eddy_tracker.dataset.grid import RegularGridDataset g = RegularGridDataset( - get_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), "longitude", "latitude" + get_demo_path("dt_med_allsat_phy_l4_20160515_20190101.nc"), "longitude", "latitude" ) diff --git a/tests/test_obs.py b/tests/test_obs.py index 59a1edab..a912e06b 100644 --- a/tests/test_obs.py +++ b/tests/test_obs.py @@ -1,11 +1,11 @@ import zarr -from py_eddy_tracker.data import get_path +from py_eddy_tracker.data import get_demo_path from py_eddy_tracker.observations.observation import EddiesObservations a_filename, c_filename = ( - get_path("Anticyclonic_20190223.nc"), - get_path("Cyclonic_20190223.nc"), + 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) diff --git a/tests/test_track.py b/tests/test_track.py index f1d5903e..4f362a26 100644 --- a/tests/test_track.py +++ b/tests/test_track.py @@ -1,12 +1,12 @@ import zarr from netCDF4 import Dataset -from py_eddy_tracker.data import get_path +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_path("Anticyclonic_20190223.nc") +filename = get_demo_path("Anticyclonic_20190223.nc") a0 = EddiesObservations.load_file(filename) a1 = a0.copy() From 00e2454c0458b98d7743c779e5fa0472bbfbcb7e Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Mon, 29 Mar 2021 22:55:05 +0200 Subject: [PATCH 134/249] use of explicit get_demo_path --- .../02_eddy_identification/pet_eddy_detection.ipynb | 2 +- .../02_eddy_identification/pet_filter_and_detection.ipynb | 2 +- .../02_eddy_identification/pet_interp_grid_on_dataset.ipynb | 2 +- .../02_eddy_identification/pet_shape_gallery.ipynb | 2 +- .../python_module/02_eddy_identification/pet_sla_and_adt.ipynb | 2 +- notebooks/python_module/06_grid_manipulation/pet_filter.ipynb | 2 +- notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb | 2 +- .../08_tracking_manipulation/pet_display_track.ipynb | 2 +- .../python_module/08_tracking_manipulation/pet_one_track.ipynb | 2 +- .../python_module/08_tracking_manipulation/pet_track_anim.ipynb | 2 +- .../pet_track_anim_matplotlib_animation.ipynb | 2 +- .../10_tracking_diagnostics/pet_birth_and_death.ipynb | 2 +- .../10_tracking_diagnostics/pet_center_count.ipynb | 2 +- .../10_tracking_diagnostics/pet_geographic_stats.ipynb | 2 +- .../python_module/10_tracking_diagnostics/pet_groups.ipynb | 2 +- notebooks/python_module/10_tracking_diagnostics/pet_histo.ipynb | 2 +- .../python_module/10_tracking_diagnostics/pet_lifetime.ipynb | 2 +- .../python_module/10_tracking_diagnostics/pet_pixel_used.ipynb | 2 +- .../python_module/10_tracking_diagnostics/pet_propagation.ipynb | 2 +- .../python_module/12_external_data/pet_SST_collocation.ipynb | 2 +- notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb b/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb index 679ad2a8..fb6c17f8 100644 --- a/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "g = RegularGridDataset(\n data.get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\n\nax = start_axes(\"ADT (m)\")\nm = g.display(ax, \"adt\", vmin=-0.15, vmax=0.15, cmap=\"RdBu_r\")\nupdate_axes(ax, m)" + "g = RegularGridDataset(\n data.get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"),\n \"longitude\",\n \"latitude\",\n)\n\nax = start_axes(\"ADT (m)\")\nm = g.display(ax, \"adt\", vmin=-0.15, vmax=0.15, cmap=\"RdBu_r\")\nupdate_axes(ax, m)" ] }, { diff --git a/notebooks/python_module/02_eddy_identification/pet_filter_and_detection.ipynb b/notebooks/python_module/02_eddy_identification/pet_filter_and_detection.ipynb index 2276317a..63e763ff 100644 --- a/notebooks/python_module/02_eddy_identification/pet_filter_and_detection.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_filter_and_detection.ipynb @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "g = RegularGridDataset(\n data.get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\ng.add_uv(\"adt\")\ng.copy(\"adt\", \"adt_high\")\nwavelength = 800\ng.bessel_high_filter(\"adt_high\", wavelength)\ndate = datetime(2016, 5, 15)" + "g = RegularGridDataset(\n data.get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"),\n \"longitude\",\n \"latitude\",\n)\ng.add_uv(\"adt\")\ng.copy(\"adt\", \"adt_high\")\nwavelength = 800\ng.bessel_high_filter(\"adt_high\", wavelength)\ndate = datetime(2016, 5, 15)" ] }, { diff --git a/notebooks/python_module/02_eddy_identification/pet_interp_grid_on_dataset.ipynb b/notebooks/python_module/02_eddy_identification/pet_interp_grid_on_dataset.ipynb index 203a7362..94e61b30 100644 --- a/notebooks/python_module/02_eddy_identification/pet_interp_grid_on_dataset.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_interp_grid_on_dataset.ipynb @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "a = EddiesObservations.load_file(data.get_demo_path(\"Anticyclonic_20160515.nc\"))\nc = EddiesObservations.load_file(data.get_demo_path(\"Cyclonic_20160515.nc\"))\n\naviso_map = RegularGridDataset(\n data.get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\naviso_map.add_uv(\"adt\")" + "a = EddiesObservations.load_file(data.get_demo_path(\"Anticyclonic_20160515.nc\"))\nc = EddiesObservations.load_file(data.get_demo_path(\"Cyclonic_20160515.nc\"))\n\naviso_map = RegularGridDataset(\n data.get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"),\n \"longitude\",\n \"latitude\",\n)\naviso_map.add_uv(\"adt\")" ] }, { diff --git a/notebooks/python_module/02_eddy_identification/pet_shape_gallery.ipynb b/notebooks/python_module/02_eddy_identification/pet_shape_gallery.ipynb index 65091120..ffa58c1f 100644 --- a/notebooks/python_module/02_eddy_identification/pet_shape_gallery.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_shape_gallery.ipynb @@ -62,7 +62,7 @@ }, "outputs": [], "source": [ - "g = RegularGridDataset(\n data.get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\nc = Contours(g.x_c, g.y_c, g.grid(\"adt\") * 100, arange(-50, 50, 0.2))\ncontours = dict()\nfor coll in c.iter():\n for current_contour in coll.get_paths():\n _, _, _, aerr = current_contour.fit_circle()\n i = int(aerr // 4) + 1\n if i not in contours:\n contours[i] = list()\n contours[i].append(current_contour)" + "g = RegularGridDataset(\n data.get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"),\n \"longitude\",\n \"latitude\",\n)\nc = Contours(g.x_c, g.y_c, g.grid(\"adt\") * 100, arange(-50, 50, 0.2))\ncontours = dict()\nfor coll in c.iter():\n for current_contour in coll.get_paths():\n _, _, _, aerr = current_contour.fit_circle()\n i = int(aerr // 4) + 1\n if i not in contours:\n contours[i] = list()\n contours[i].append(current_contour)" ] }, { diff --git a/notebooks/python_module/02_eddy_identification/pet_sla_and_adt.ipynb b/notebooks/python_module/02_eddy_identification/pet_sla_and_adt.ipynb index 3c40e49f..efbfcc76 100644 --- a/notebooks/python_module/02_eddy_identification/pet_sla_and_adt.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_sla_and_adt.ipynb @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "g = RegularGridDataset(\n data.get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)\ng.add_uv(\"adt\", \"ugos\", \"vgos\")\ng.add_uv(\"sla\", \"ugosa\", \"vgosa\")\nwavelength = 400\ng.copy(\"adt\", \"adt_raw\")\ng.copy(\"sla\", \"sla_raw\")\ng.bessel_high_filter(\"adt\", wavelength)\ng.bessel_high_filter(\"sla\", wavelength)\ndate = datetime(2016, 5, 15)" + "g = RegularGridDataset(\n data.get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"),\n \"longitude\",\n \"latitude\",\n)\ng.add_uv(\"adt\", \"ugos\", \"vgos\")\ng.add_uv(\"sla\", \"ugosa\", \"vgosa\")\nwavelength = 400\ng.copy(\"adt\", \"adt_raw\")\ng.copy(\"sla\", \"sla_raw\")\ng.bessel_high_filter(\"adt\", wavelength)\ng.bessel_high_filter(\"sla\", wavelength)\ndate = datetime(2016, 5, 15)" ] }, { diff --git a/notebooks/python_module/06_grid_manipulation/pet_filter.ipynb b/notebooks/python_module/06_grid_manipulation/pet_filter.ipynb index abf4553e..74a266c2 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_filter.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_filter.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "g = RegularGridDataset(\n data.get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"), \"longitude\", \"latitude\"\n)" + "g = RegularGridDataset(\n data.get_demo_path(\"dt_med_allsat_phy_l4_20160515_20190101.nc\"),\n \"longitude\",\n \"latitude\",\n)" ] }, { diff --git a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb index fdd7768c..6cef91bc 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb @@ -181,7 +181,7 @@ }, "outputs": [], "source": [ - "fig, ax, _ = start_ax()\nmappable = lavd.display(ax, \"lavd\", **kw_vorticity)\nEddiesObservations.load_file(get_demo_path(\"Anticyclonic_20160515.nc\")).display(\n ax, color=\"k\"\n)\nEddiesObservations.load_file(get_demo_path(\"Cyclonic_20160515.nc\")).display(ax, color=\"k\")\n_ = update_axes(ax, mappable)" + "fig, ax, _ = start_ax()\nmappable = lavd.display(ax, \"lavd\", **kw_vorticity)\nEddiesObservations.load_file(get_demo_path(\"Anticyclonic_20160515.nc\")).display(\n ax, color=\"k\"\n)\nEddiesObservations.load_file(get_demo_path(\"Cyclonic_20160515.nc\")).display(\n ax, color=\"k\"\n)\n_ = update_axes(ax, mappable)" ] } ], diff --git a/notebooks/python_module/08_tracking_manipulation/pet_display_track.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_display_track.ipynb index 2d7b600d..1af7b49a 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_display_track.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_display_track.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nprint(a)" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\n \"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\"\n )\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nprint(a)" ] }, { diff --git a/notebooks/python_module/08_tracking_manipulation/pet_one_track.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_one_track.ipynb index d1529e26..2749f7e9 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_one_track.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_one_track.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\neddy = a.extract_ids([9672])\neddy_f = a.extract_ids([9672])\neddy_f.position_filter(median_half_window=1, loess_half_window=5)" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\n \"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\"\n )\n)\neddy = a.extract_ids([9672])\neddy_f = a.extract_ids([9672])\neddy_f.position_filter(median_half_window=1, loess_half_window=5)" ] }, { diff --git a/notebooks/python_module/08_tracking_manipulation/pet_track_anim.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_track_anim.ipynb index 402eb6a4..041c8987 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_track_anim.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_track_anim.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\n# We get only 300 first step to save time of documentation builder\neddy = a.extract_ids([9672]).index(slice(0, 300))" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\n \"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\"\n )\n)\n# We get only 300 first step to save time of documentation builder\neddy = a.extract_ids([9672]).index(slice(0, 300))" ] }, { diff --git a/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb index eb028afa..9f77dbae 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\neddy = a.extract_ids([9672])" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\n \"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\"\n )\n)\neddy = a.extract_ids([9672])" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_birth_and_death.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_birth_and_death.ipynb index e1824f22..d9a2ef2b 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_birth_and_death.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_birth_and_death.ipynb @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "kwargs_load = dict(\n include_vars=(\n \"longitude\",\n \"latitude\",\n \"observation_number\",\n \"track\",\n \"time\",\n \"speed_contour_longitude\",\n \"speed_contour_latitude\",\n )\n)\na = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)" + "kwargs_load = dict(\n include_vars=(\n \"longitude\",\n \"latitude\",\n \"observation_number\",\n \"track\",\n \"time\",\n \"speed_contour_longitude\",\n \"speed_contour_latitude\",\n )\n)\na = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\n \"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\"\n )\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb index 1f2d5b6a..b6bb15bd 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\n \"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\"\n )\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_geographic_stats.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_geographic_stats.ipynb index ff42b21d..3e884552 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_geographic_stats.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_geographic_stats.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\na = a.merge(c)\n\nstep = 0.1" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\n \"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\"\n )\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\na = a.merge(c)\n\nstep = 0.1" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_groups.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_groups.ipynb index 55d299d4..85e32c6a 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_groups.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_groups.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\n \"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\"\n )\n)" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_histo.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_histo.ipynb index 1d8251d1..851c6ca4 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_histo.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_histo.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nkwargs_a = dict(label=\"Anticyclonic\", color=\"r\", histtype=\"step\", density=True)\nkwargs_c = dict(label=\"Cyclonic\", color=\"b\", histtype=\"step\", density=True)" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\n \"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\"\n )\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nkwargs_a = dict(label=\"Anticyclonic\", color=\"r\", histtype=\"step\", density=True)\nkwargs_c = dict(label=\"Cyclonic\", color=\"b\", histtype=\"step\", density=True)" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_lifetime.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_lifetime.ipynb index 4aa3304f..4a3ff0af 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_lifetime.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_lifetime.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nnb_year = (a.period[1] - a.period[0] + 1) / 365.25" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\n \"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\"\n )\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nnb_year = (a.period[1] - a.period[0] + 1) / 365.25" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb index 43929105..81bed372 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\n \"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\"\n )\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)" ] }, { diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_propagation.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_propagation.ipynb index da8f0976..e0d1f2d2 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_propagation.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_propagation.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\")\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nnb_year = (a.period[1] - a.period[0] + 1) / 365.25" + "a = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\n \"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\"\n )\n)\nc = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nnb_year = (a.period[1] - a.period[0] + 1) / 365.25" ] }, { diff --git a/notebooks/python_module/12_external_data/pet_SST_collocation.ipynb b/notebooks/python_module/12_external_data/pet_SST_collocation.ipynb index 1d22e1ef..05b0413c 100644 --- a/notebooks/python_module/12_external_data/pet_SST_collocation.ipynb +++ b/notebooks/python_module/12_external_data/pet_SST_collocation.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "from datetime import datetime\n\nfrom matplotlib import pyplot as plt\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\n\ndate = datetime(2016, 7, 7)\n\nfilename_alt = data.get_demo_path(f\"dt_blacksea_allsat_phy_l4_{date:%Y%m%d}_20200801.nc\")\nfilename_sst = data.get_demo_path(\n f\"{date:%Y%m%d}000000-GOS-L4_GHRSST-SSTfnd-OISST_HR_REP-BLK-v02.0-fv01.0.nc\"\n)\nvar_name_sst = \"analysed_sst\"\n\nextent = [27, 42, 40.5, 47]" + "from datetime import datetime\n\nfrom matplotlib import pyplot as plt\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\n\ndate = datetime(2016, 7, 7)\n\nfilename_alt = data.get_demo_path(\n f\"dt_blacksea_allsat_phy_l4_{date:%Y%m%d}_20200801.nc\"\n)\nfilename_sst = data.get_demo_path(\n f\"{date:%Y%m%d}000000-GOS-L4_GHRSST-SSTfnd-OISST_HR_REP-BLK-v02.0-fv01.0.nc\"\n)\nvar_name_sst = \"analysed_sst\"\n\nextent = [27, 42, 40.5, 47]" ] }, { diff --git a/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb b/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb index d4ef20f3..e803df5f 100644 --- a/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb +++ b/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb @@ -55,7 +55,7 @@ }, "outputs": [], "source": [ - "ioannou_case = NetworkObservations.load_file(get_demo_path(\"network_med.nc\")).network(651)\nprint(ioannou_case.infos())" + "ioannou_case = NetworkObservations.load_file(get_demo_path(\"network_med.nc\")).network(\n 651\n)\nprint(ioannou_case.infos())" ] }, { From 8d131153bc2d8cb16eefa648f68119fb71e4acbd Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Tue, 30 Mar 2021 08:43:51 +0200 Subject: [PATCH 135/249] Add test badge --- .github/workflows/python-app.yml | 2 +- CHANGELOG.rst | 8 ++++++++ README.md | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 7c800b33..43fd6b2d 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -1,7 +1,7 @@ # This workflow will install Python dependencies, run tests and lint with a single version of Python # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions -name: Python application +name: Pytest & Flake8 on: push: diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b974e3bd..80def41c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,7 +8,15 @@ and this project adheres to `Semantic Versioning Date: Tue, 30 Mar 2021 15:02:26 +0200 Subject: [PATCH 136/249] Add example from Evan Mason about normalized lifetime --- .../pet_normalised_lifetime.py | 78 ++++++++++++ .../pet_normalised_lifetime.ipynb | 119 ++++++++++++++++++ ..._global_allsat_phy_l4_20190223_20190226.nc | 1 + src/py_eddy_tracker/observations/network.py | 2 +- 4 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 examples/10_tracking_diagnostics/pet_normalised_lifetime.py create mode 100644 notebooks/python_module/10_tracking_diagnostics/pet_normalised_lifetime.ipynb create mode 120000 share/nrt_global_allsat_phy_l4_20190223_20190226.nc diff --git a/examples/10_tracking_diagnostics/pet_normalised_lifetime.py b/examples/10_tracking_diagnostics/pet_normalised_lifetime.py new file mode 100644 index 00000000..372b66c0 --- /dev/null +++ b/examples/10_tracking_diagnostics/pet_normalised_lifetime.py @@ -0,0 +1,78 @@ +""" +Normalised Eddy Lifetimes +========================= + +Example from Evan Mason +""" +from matplotlib import pyplot as plt +from numba import njit +from numpy import interp, linspace, zeros +from py_eddy_tracker_sample import get_demo_path + +from py_eddy_tracker.observations.tracking import TrackEddiesObservations + + +# %% +@njit(cache=True) +def sum_profile(x_new, y, out): + """Will sum all interpolated given array""" + out += interp(x_new, linspace(0, 1, y.size), y) + + +class MyObs(TrackEddiesObservations): + def eddy_norm_lifetime(self, name, nb, factor=1): + """ + :param str,array name: Array or field name + :param int nb: size of output array + """ + y = self.parse_varname(name) + x = linspace(0, 1, nb) + out = zeros(nb, dtype=y.dtype) + nb_track = 0 + for i, b0, b1 in self.iter_on("track"): + y_ = y[i] + size_ = y_.size + if size_ == 0: + continue + sum_profile(x, y_, out) + nb_track += 1 + return x, out / nb_track * factor + + +# %% +# Load atlas +# ---------- +kw = dict(include_vars=("speed_radius", "amplitude", "track")) +a = MyObs.load_file( + get_demo_path("eddies_med_adt_allsat_dt2018/Anticyclonic.zarr"), **kw +) +c = MyObs.load_file(get_demo_path("eddies_med_adt_allsat_dt2018/Cyclonic.zarr"), **kw) + +nb_max_a = a.nb_obs_by_track.max() +nb_max_c = c.nb_obs_by_track.max() + +# %% +# Compute normalize lifetime +# -------------------------- + +# Radius +AC_radius = a.eddy_norm_lifetime("speed_radius", nb=nb_max_a, factor=1e-3) +CC_radius = c.eddy_norm_lifetime("speed_radius", nb=nb_max_c, factor=1e-3) +# Amplitude +AC_amplitude = a.eddy_norm_lifetime("amplitude", nb=nb_max_a, factor=1e2) +CC_amplitude = c.eddy_norm_lifetime("amplitude", nb=nb_max_c, factor=1e2) + +# %% +# Figure +# ------ +fig, axs = plt.subplots(nrows=2, figsize=(8, 6)) + +axs[0].set_title("Normalised Mean Radius") +axs[0].plot(*AC_radius), axs[0].plot(*CC_radius) +axs[0].set_ylabel("Radius (km)"), axs[0].grid() +axs[0].set_xlim(0, 1), axs[0].set_ylim(0, None) + +axs[1].set_title("Normalised Mean Amplitude") +axs[1].plot(*AC_amplitude, label="AC"), axs[1].plot(*CC_amplitude, label="CC") +axs[1].set_ylabel("Amplitude (cm)"), axs[1].grid(), axs[1].legend() +_ = axs[1].set_xlim(0, 1), axs[1].set_ylim(0, None) diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_normalised_lifetime.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_normalised_lifetime.ipynb new file mode 100644 index 00000000..6c98a1cf --- /dev/null +++ b/notebooks/python_module/10_tracking_diagnostics/pet_normalised_lifetime.ipynb @@ -0,0 +1,119 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Normalised Eddy Lifetimes\n\nExample from Evan Mason\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from matplotlib import pyplot as plt\nfrom numba import njit\nfrom numpy import interp, linspace, zeros\nfrom py_eddy_tracker_sample import get_demo_path\n\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "@njit(cache=True)\ndef sum_profile(x_new, y, out):\n \"\"\"Will sum all interpolated given array\"\"\"\n out += interp(x_new, linspace(0, 1, y.size), y)\n\n\nclass MyObs(TrackEddiesObservations):\n def eddy_norm_lifetime(self, name, nb, factor=1):\n \"\"\"\n :param str,array name: Array or field name\n :param int nb: size of output array\n \"\"\"\n y = self.parse_varname(name)\n x = linspace(0, 1, nb)\n out = zeros(nb, dtype=y.dtype)\n nb_track = 0\n for i, b0, b1 in self.iter_on(\"track\"):\n y_ = y[i]\n size_ = y_.size\n if size_ == 0:\n continue\n sum_profile(x, y_, out)\n nb_track += 1\n return x, out / nb_track * factor" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load atlas\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "kw = dict(include_vars=(\"speed_radius\", \"amplitude\", \"track\"))\na = MyObs.load_file(\n get_demo_path(\"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\"), **kw\n)\nc = MyObs.load_file(get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\"), **kw)\n\nnb_max_a = a.nb_obs_by_track.max()\nnb_max_c = c.nb_obs_by_track.max()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Compute normalize lifetime\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Radius\nAC_radius = a.eddy_norm_lifetime(\"speed_radius\", nb=nb_max_a, factor=1e-3)\nCC_radius = c.eddy_norm_lifetime(\"speed_radius\", nb=nb_max_c, factor=1e-3)\n# Amplitude\nAC_amplitude = a.eddy_norm_lifetime(\"amplitude\", nb=nb_max_a, factor=1e2)\nCC_amplitude = c.eddy_norm_lifetime(\"amplitude\", nb=nb_max_c, factor=1e2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Figure\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig, axs = plt.subplots(nrows=2, figsize=(8, 6))\n\naxs[0].set_title(\"Normalised Mean Radius\")\naxs[0].plot(*AC_radius), axs[0].plot(*CC_radius)\naxs[0].set_ylabel(\"Radius (km)\"), axs[0].grid()\naxs[0].set_xlim(0, 1), axs[0].set_ylim(0, None)\n\naxs[1].set_title(\"Normalised Mean Amplitude\")\naxs[1].plot(*AC_amplitude, label=\"AC\"), axs[1].plot(*CC_amplitude, label=\"CC\")\naxs[1].set_ylabel(\"Amplitude (cm)\"), axs[1].grid(), axs[1].legend()\n_ = axs[1].set_xlim(0, 1), axs[1].set_ylim(0, None)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/share/nrt_global_allsat_phy_l4_20190223_20190226.nc b/share/nrt_global_allsat_phy_l4_20190223_20190226.nc new file mode 120000 index 00000000..077ce7e6 --- /dev/null +++ b/share/nrt_global_allsat_phy_l4_20190223_20190226.nc @@ -0,0 +1 @@ +../src/py_eddy_tracker/data/nrt_global_allsat_phy_l4_20190223_20190226.nc \ No newline at end of file diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 53af9f30..6cd18d16 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -575,7 +575,7 @@ def numbering_segment(self, start=0): New numbering of segment """ for i, _, _ in self.iter_on("track"): - new_numbering(self.segment[i]) + new_numbering(self.segment[i], start) def numbering_network(self, start=1): """ From 415931732bc9d1f72bef58ec6cda1c2457ece562 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Wed, 31 Mar 2021 13:39:03 +0200 Subject: [PATCH 137/249] Add minigallery for interp_grid --- examples/10_tracking_diagnostics/pet_normalised_lifetime.py | 4 ++-- .../10_tracking_diagnostics/pet_normalised_lifetime.ipynb | 2 +- src/py_eddy_tracker/observations/observation.py | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/10_tracking_diagnostics/pet_normalised_lifetime.py b/examples/10_tracking_diagnostics/pet_normalised_lifetime.py index 372b66c0..73e5274e 100644 --- a/examples/10_tracking_diagnostics/pet_normalised_lifetime.py +++ b/examples/10_tracking_diagnostics/pet_normalised_lifetime.py @@ -52,8 +52,8 @@ def eddy_norm_lifetime(self, name, nb, factor=1): nb_max_c = c.nb_obs_by_track.max() # %% -# Compute normalize lifetime -# -------------------------- +# Compute normalised lifetime +# --------------------------- # Radius AC_radius = a.eddy_norm_lifetime("speed_radius", nb=nb_max_a, factor=1e-3) diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_normalised_lifetime.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_normalised_lifetime.ipynb index 6c98a1cf..867e081f 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_normalised_lifetime.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_normalised_lifetime.ipynb @@ -62,7 +62,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Compute normalize lifetime\n\n" + "## Compute normalised lifetime\n\n" ] }, { diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 73df5734..839dbca1 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -2220,6 +2220,8 @@ def interp_grid( :param str method: 'center', 'mean', 'max', 'min', 'nearest' :param str dtype: if None we use var dtype :param bool intern: Use extern or intern contour + + .. minigallery:: py_eddy_tracker.EddiesObservations.interp_grid """ if method in ("center", "nearest"): return grid_object.interp(varname, self.longitude, self.latitude, method) From e5bbf954bc4b6adb3d56331dbbcbb89fa7f2653f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Wed, 31 Mar 2021 16:24:08 +0200 Subject: [PATCH 138/249] optimisation function relatives --- src/py_eddy_tracker/observations/network.py | 79 +++++++++++++++------ 1 file changed, 59 insertions(+), 20 deletions(-) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 6cd18d16..7a57bbca 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -311,7 +311,7 @@ def sort(self, order=("track", "segment", "time")): """ sort observations - :param tuple order: order or sorting. Passed to `np.argsort` + :param tuple order: order or sorting. Passed to :func:`numpy.argsort` """ index_order = self.obs.argsort(order=order) @@ -485,39 +485,78 @@ def segment_relative_order(self, seg_origine): d[i0:i1] = v return d - def relative(self, i_obs, order=2, direct=True, only_past=False, only_future=False): + def relatives(self, obs, order=2): """ - Extract the segments at a certain order from one observation. + Extract the segments at a certain order from multiple observations. - :param list obs: indice of observation for relative computation + :param iterable,int obs: indices of observation for relatives computation. Can be one observation (int) or collection of observations (iterable(int)) :param int order: order of relatives wanted. 0 means only observations in obs, 1 means direct relatives, ... :return: all segments relatives :rtype: EddiesObservations """ + segment = self.segment_track_array + previous_obs, next_obs = self.previous_obs, self.next_obs - d = self.segment_relative_order(self.segment[i_obs]) - m = (d <= order) * (d != -1) - return self.extract_with_mask(m) + segments_connexion = dict() - def relatives(self, obs, order=2, direct=True, only_past=False, only_future=False): - """ - Extract the segments at a certain order from multiple observations. + for i_slice, seg, _ in self.iter_on(segment): + if i_slice.start == i_slice.stop: + continue - :param list obs: indices of observation for relatives computation - :param int order: order of relatives wanted. 0 means only observations in obs, 1 means direct relatives, ... + i_p, i_n = previous_obs[i_slice.start], next_obs[i_slice.stop - 1] + p_seg, n_seg = segment[i_p], segment[i_n] - :return: all segments relatives - :rtype: EddiesObservations - """ + # dumping slice into dict + if seg not in segments_connexion: + segments_connexion[seg] = [i_slice, []] + else: + segments_connexion[seg][0] = i_slice - mask = zeros(self.segment.shape, dtype=bool) - for i_obs in obs: - d = self.segment_relative_order(self.segment[i_obs]) - mask += (d <= order) * (d != -1) + if i_p != -1: - return self.extract_with_mask(mask) + if p_seg not in segments_connexion: + segments_connexion[p_seg] = [None, []] + + # backward + segments_connexion[seg][1].append(p_seg) + segments_connexion[p_seg][1].append(seg) + + if i_n != -1: + if n_seg not in segments_connexion: + segments_connexion[n_seg] = [None, []] + + # forward + segments_connexion[seg][1].append(n_seg) + segments_connexion[n_seg][1].append(seg) + + + i_obs = ( + [obs] + if not hasattr(obs, "__iter__") + else obs + ) + import numpy as np + + distance = zeros(segment.size, dtype=np.uint16) - 1 + + def loop(seg, dist=1): + i_slice, links = segments_connexion[seg] + d = distance[i_slice.start] + + if dist < d and dist <= order: + distance[i_slice] = dist + for _seg in links: + loop(_seg, dist + 1) + + for indice in i_obs: + loop(segment[indice], 0) + + return self.extract_with_mask(distance <= order) + + # keep old names, for backward compatibility + relative = relatives def close_network(self, other, nb_obs_min=10, **kwargs): """ From 74e9536003c7760732760f170b869cfd1268e717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Wed, 31 Mar 2021 16:25:26 +0200 Subject: [PATCH 139/249] optimisation poly_indexs and bug correction with np.nan casting --- src/py_eddy_tracker/observations/observation.py | 5 ++++- src/py_eddy_tracker/poly.py | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 839dbca1..f3e0ee75 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -2050,7 +2050,10 @@ def contains(self, x, y, intern=False): :rtype: array[int32] """ xname, yname = self.intern(intern) - return poly_indexs(x, y, self[xname], self[yname]) + m = ~ (isnan(x) + isnan(y)) + i = -ones(x.shape, dtype='i4') + i[m] = poly_indexs(x[m], y[m], self[xname], self[yname]) + return i def inside(self, x, y, intern=False): """ diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index 2bf34509..864607ff 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -815,7 +815,7 @@ def box_indexes(x, y, step): @njit(cache=True) -def poly_indexs_(x_p, y_p, x_c, y_c): +def poly_indexs(x_p, y_p, x_c, y_c): """ Index of contour for each postion inside a contour, -1 in case of no contour @@ -874,7 +874,7 @@ def poly_indexs_(x_p, y_p, x_c, y_c): @njit(cache=True) -def poly_indexs(x_p, y_p, x_c, y_c): +def poly_indexs_old(x_p, y_p, x_c, y_c): """ index of contour for each postion inside a contour, -1 in case of no contour From 64efe1b2fd802981be7806791806240d4b8424e0 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Wed, 31 Mar 2021 22:38:22 +0200 Subject: [PATCH 140/249] Add some mini gallery --- src/py_eddy_tracker/observations/observation.py | 4 ++++ src/py_eddy_tracker/poly.py | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index f3e0ee75..0d0f45b7 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -553,6 +553,8 @@ def iter_on(self, xname, bins=None): :param str,array xname: :param array bins: bounds of each bin , :return: index or mask, bound low, bound up + + .. minigallery:: py_eddy_tracker.EddiesObservations.iter_on """ x = self[xname] if isinstance(xname, str) else xname d = x[1:] - x[:-1] @@ -593,6 +595,8 @@ def iter_on(self, xname, bins=None): def align_on(self, other, var_name="time", **kwargs): """ Align the time indexes of two datasets. + + .. minigallery:: py_eddy_tracker.EddiesObservations.align_on """ iter_self = self.iter_on(var_name, **kwargs) iter_other = other.iter_on(var_name, **kwargs) diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index 864607ff..ad8fc148 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -536,7 +536,6 @@ def fit_ellips(x, y): https://en.wikipedia.org/wiki/Ellipse """ - # x,y = x[1:],y[1:] nb = x.shape[0] datas = ones((nb, 5), dtype=x.dtype) datas[:, 0] = x ** 2 From d81604d8bbedd833cf4a108028ea02033c6c9779 Mon Sep 17 00:00:00 2001 From: Cori Pegliasco Date: Thu, 1 Apr 2021 17:02:01 +0200 Subject: [PATCH 141/249] - add ellipse fit - minor english modifs --- examples/16_network/pet_ioannou_2017_case.py | 44 ++++++++++++++++++++ src/py_eddy_tracker/dataset/grid.py | 13 ++++-- src/py_eddy_tracker/eddy_feature.py | 26 ++++++------ src/py_eddy_tracker/poly.py | 10 ++--- 4 files changed, 72 insertions(+), 21 deletions(-) diff --git a/examples/16_network/pet_ioannou_2017_case.py b/examples/16_network/pet_ioannou_2017_case.py index 7669b010..54f124f7 100644 --- a/examples/16_network/pet_ioannou_2017_case.py +++ b/examples/16_network/pet_ioannou_2017_case.py @@ -188,3 +188,47 @@ def update_axes(ax, mappable=None): m = close_to_i3.scatter_timeline(ax, "shape_error_e", vmin=14, vmax=70, **kw) cb = update_axes(ax, m["scatter"]) cb.set_label("Effective shape error") + +# %% +# Rotation angle +# -------------- +from py_eddy_tracker.generic import coordinates_to_local, local_to_coordinates +from py_eddy_tracker.poly import fit_ellips +theta_ = list() +a_ = list() +b_ = list() +for obs in close_to_i3: + x, y = obs['contour_lon_s'], obs['contour_lat_s'] + x0_, y0_ = x.mean(), y.mean() + x_, y_ = coordinates_to_local(x, y, x0_, y0_) + x0, y0, a, b, theta = fit_ellips(x_, y_) + theta_.append(theta) + a_.append(a) + b_.append(b) +a_=array(a_) +b_=array(b_) + +# %% +# Theta +ax = timeline_axes() +m = close_to_i3.scatter_timeline(ax, theta_, vmin=-pi/2, vmax=pi/2, cmap='hsv') +cb = update_axes(ax, m["scatter"]) + +# %% +# A +ax = timeline_axes() +m = close_to_i3.scatter_timeline(ax, a_ * 1e-3, vmin=0, vmax=80, cmap='Spectral_r') +cb = update_axes(ax, m["scatter"]) + +# %% +# B +ax = timeline_axes() +m = close_to_i3.scatter_timeline(ax, b_ * 1e-3, vmin=0, vmax=80, cmap='Spectral_r') +cb = update_axes(ax, m["scatter"]) + +# %% +# A/B +ax = timeline_axes() +m = close_to_i3.scatter_timeline(ax, a_/b_, vmin=1, vmax=2, cmap='Spectral_r') +cb = update_axes(ax, m["scatter"]) + diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 6a4624dd..28dc8330 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -609,17 +609,17 @@ def eddy_identification( :param str vname: Grid name of v speed component :param datetime.datetime date: Date which will be stored in object to date data :param float,int step: Height between two layers in m - :param float,int shape_error: Maximal error allowed for outter contour in % + :param float,int shape_error: Maximal error allowed for outermost contour in % :param int sampling: Number of points to store contours and speed profile :param str sampling_method: Method to resample 'uniform' or 'visvalingam' :param (int,int),None pixel_limit: - Min and max number of pixels inside the inner and the outer contour to be considered as an eddy + Min and max number of pixels inside the inner and the outermost contour to be considered as an eddy :param float,None precision: Truncate values at the defined precision in m :param str force_height_unit: Unit used for height unit :param str force_speed_unit: Unit used for speed unit :param dict kwargs: Argument given to amplitude - :return: Return a list of 2 elements: Anticyclone and Cyclone + :return: Return a list of 2 elements: Anticyclones and Cyclones :rtype: py_eddy_tracker.observations.observation.EddiesObservations .. minigallery:: py_eddy_tracker.GridDataset.eddy_identification @@ -729,7 +729,8 @@ def eddy_identification( for contour in contour_paths: if contour.used: continue - # FIXME : center could be not in contour and fit on raw sampling + # FIXME : center could be outside the contour due to the fit + # FIXME : warning : the fit is made on raw sampling _, _, _, aerr = contour.fit_circle() # Filter for shape @@ -752,6 +753,7 @@ def eddy_identification( ): continue + # Test the number of pixels within the outermost contour # FIXME : Maybe limit max must be replace with a maximum of surface if ( contour.nb_pixel < pixel_limit[0] @@ -760,6 +762,9 @@ def eddy_identification( contour.reject = 3 continue + # Here the considered contour passed shape_error test, masked_pixels test, + # values strictly above (AEs) or below (CEs) the contour, number_pixels test) + # Compute amplitude reset_centroid, amp = self.get_amplitude( contour, diff --git a/src/py_eddy_tracker/eddy_feature.py b/src/py_eddy_tracker/eddy_feature.py index 3e6c86ea..037beb35 100644 --- a/src/py_eddy_tracker/eddy_feature.py +++ b/src/py_eddy_tracker/eddy_feature.py @@ -31,7 +31,7 @@ class Amplitude(object): """ Class to calculate *amplitude* and counts of *local maxima/minima* - within a closed region of a sea level anomaly field. + within a closed region of a sea surface height field. """ EPSILON = 1e-8 @@ -66,8 +66,8 @@ def __init__( :param array data: :param float interval: :param int mle: maximum number of local maxima in contour - :param int nb_step_min: number of interval to consider like an eddy - :param int nb_step_to_be_mle: number of interval to be consider like another maxima + :param int nb_step_min: number of intervals to consider an eddy + :param int nb_step_to_be_mle: number of intervals to be considered as an another maxima """ # Height of the contour @@ -102,8 +102,9 @@ def __init__( self.nb_pixel = i_x.shape[0] # Only pixel in contour + # FIXME : change sla by ssh as the grid can be adt? self.sla = data[contour.pixels_index] - # Amplitude which will be provide + # Amplitude which will be provided self.amplitude = 0 # Maximum local extrema accepted self.mle = mle @@ -115,9 +116,10 @@ def within_amplitude_limits(self): def all_pixels_below_h0(self, level): """ Check CSS11 criterion 1: The SSH values of all of the pixels - are below a given SSH threshold for cyclonic eddies. + are below (above) a given SSH threshold for cyclonic (anticyclonic) + eddies. """ - # In some case pixel value must be very near of contour bounds + # In some cases pixel value may be very close to the contour bounds if self.sla.mask.any() or ((self.sla.data - self.h_0) > self.EPSILON).any(): return False else: @@ -293,10 +295,10 @@ class Contours(object): Attributes: contour: - A matplotlib contour object of high-pass filtered SLA + A matplotlib contour object of high-pass filtered SSH eddy: - A tracklist object holding the SLA data + A tracklist object holding the SSH data grd: A grid object @@ -406,7 +408,7 @@ def __init__(self, x, y, z, levels, wrap_x=False, keep_unclose=False): fig = Figure() ax = fig.add_subplot(111) if wrap_x: - logger.debug("wrapping activate to compute contour") + logger.debug("wrapping activated to compute contour") x = concatenate((x, x[:1] + 360)) z = ma.concatenate((z, z[:1])) logger.debug("X shape : %s", x.shape) @@ -602,8 +604,8 @@ def display( Must be 'shape_error', 'x', 'y' or 'radius'. If define display_criterion is not use. bins argument must be define - :param array bins: bins use to colorize contour - :param str cmap: Name of cmap to use for field display + :param array bins: bins used to colorize contour + :param str cmap: Name of cmap for field display :param dict kwargs: look at :py:meth:`matplotlib.collections.LineCollection` .. minigallery:: py_eddy_tracker.Contours.display @@ -688,7 +690,7 @@ def display( ax.autoscale_view() def label_contour_unused_which_contain_eddies(self, eddies): - """Select contour which contain several eddies""" + """Select contour containing several eddies""" if eddies.sign_type == 1: # anticyclonic sl = slice(None, -1) diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index ad8fc148..af621423 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -474,13 +474,13 @@ def polygon_overlap(p0, p1, minimal_area=False): return cost -# FIXME: only one function are needed +# FIXME: only one function is needed @njit(cache=True) def fit_circle(x, y): """ From a polygon, function will fit a circle. - Must be call with local coordinates (in m, to get a radius in m). + Must be called with local coordinates (in m, to get a radius in m). :param array x: x of polygon :param array y: y of polygon @@ -510,11 +510,11 @@ def fit_circle(x, y): radius **= 0.5 x0 *= scale y0 *= scale - # radius of fitted circle + # radius of fit circle radius *= scale - # center X-position of fitted circle + # center X-position of fit circle x0 += x_mean - # center Y-position of fitted circle + # center Y-position of fit circle y0 += y_mean err = shape_error(x, y, x0, y0, radius) From 7c8fc736ed1ee37b7f627b14b0ff80565a245293 Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Sun, 4 Apr 2021 22:43:35 +0200 Subject: [PATCH 142/249] Add visvalingam test --- src/py_eddy_tracker/observations/network.py | 12 +++--------- src/py_eddy_tracker/observations/observation.py | 4 ++-- tests/test_poly.py | 16 +++++++++++++++- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 7a57bbca..115197de 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -16,6 +16,7 @@ in1d, ones, uint32, + uint16, unique, where, zeros, @@ -513,7 +514,6 @@ def relatives(self, obs, order=2): else: segments_connexion[seg][0] = i_slice - if i_p != -1: if p_seg not in segments_connexion: @@ -531,15 +531,9 @@ def relatives(self, obs, order=2): segments_connexion[seg][1].append(n_seg) segments_connexion[n_seg][1].append(seg) + i_obs = [obs] if not hasattr(obs, "__iter__") else obs - i_obs = ( - [obs] - if not hasattr(obs, "__iter__") - else obs - ) - import numpy as np - - distance = zeros(segment.size, dtype=np.uint16) - 1 + distance = zeros(segment.size, dtype=uint16) - 1 def loop(seg, dist=1): i_slice, links = segments_connexion[seg] diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 0d0f45b7..8decca58 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -2054,8 +2054,8 @@ def contains(self, x, y, intern=False): :rtype: array[int32] """ xname, yname = self.intern(intern) - m = ~ (isnan(x) + isnan(y)) - i = -ones(x.shape, dtype='i4') + m = ~(isnan(x) + isnan(y)) + i = -ones(x.shape, dtype="i4") i[m] = poly_indexs(x[m], y[m], self[xname], self[yname]) return i diff --git a/tests/test_poly.py b/tests/test_poly.py index b2aacb73..1a0edb6f 100644 --- a/tests/test_poly.py +++ b/tests/test_poly.py @@ -1,7 +1,13 @@ from numpy import array, pi from pytest import approx -from py_eddy_tracker.poly import convex, fit_circle, get_convex_hull, poly_area_vertice +from py_eddy_tracker.poly import ( + convex, + fit_circle, + get_convex_hull, + poly_area_vertice, + visvalingam, +) # Vertices for next test V = array(((2, 2, 3, 3, 2), (-10, -9, -9, -10, -10))) @@ -29,3 +35,11 @@ def test_convex(): def test_convex_hull(): assert convex(*get_convex_hull(*V_concave)) is True + + +def test_visvalingam(): + x = array([1, 2, 3, 4, 5, 6.75, 6, 1]) + y = array([-0.5, -1.5, -1, -1.75, -1, -1, -0.5, -0.5]) + x_, y_ = visvalingam(x, y, 6) + assert ([1, 2, 3, 4, 6, 1] == x_).all() + assert ([-0.5, -1.5, -1, -1.75, -0.5, -0.5] == y_).all() From caff46f62e80fd19bc911cae4eb4f0e51682e2cc Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Sun, 4 Apr 2021 22:47:36 +0200 Subject: [PATCH 143/249] Activate test for all branches --- .github/workflows/python-app.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 43fd6b2d..7fc9f385 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -3,11 +3,7 @@ name: Pytest & Flake8 -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] +on: [push, pull_request] jobs: build: From 1d81bc0732b81e945111d7e5cbba5933ef684ada Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Mon, 5 Apr 2021 16:46:56 +0200 Subject: [PATCH 144/249] Modify gui import --- examples/06_grid_manipulation/pet_advect.py | 6 +++--- examples/06_grid_manipulation/pet_lavd.py | 4 ++-- examples/07_cube_manipulation/pet_cube.py | 4 ++-- .../07_cube_manipulation/pet_lavd_detection.py | 4 ++-- examples/16_network/pet_atlas.py | 4 ++-- examples/16_network/pet_ioannou_2017_case.py | 4 ++-- examples/16_network/pet_relative.py | 12 ++++++------ examples/16_network/pet_replay_segmentation.py | 4 ++-- examples/16_network/pet_segmentation_anim.py | 6 +++--- .../06_grid_manipulation/pet_advect.ipynb | 8 ++++---- .../06_grid_manipulation/pet_lavd.ipynb | 6 +++--- .../07_cube_manipulation/pet_cube.ipynb | 6 +++--- .../07_cube_manipulation/pet_lavd_detection.ipynb | 6 +++--- notebooks/python_module/16_network/pet_atlas.ipynb | 6 +++--- .../16_network/pet_ioannou_2017_case.ipynb | 6 +++--- .../python_module/16_network/pet_relative.ipynb | 14 +++++++------- .../16_network/pet_replay_segmentation.ipynb | 4 ++-- .../16_network/pet_segmentation_anim.ipynb | 8 ++++---- src/py_eddy_tracker/gui.py | 7 +++++-- 19 files changed, 61 insertions(+), 58 deletions(-) diff --git a/examples/06_grid_manipulation/pet_advect.py b/examples/06_grid_manipulation/pet_advect.py index 13052af5..0e00697f 100644 --- a/examples/06_grid_manipulation/pet_advect.py +++ b/examples/06_grid_manipulation/pet_advect.py @@ -10,9 +10,9 @@ 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.gui import GUI_AXES from py_eddy_tracker.observations.observation import EddiesObservations # %% @@ -32,7 +32,7 @@ # %% # Quiver from u/v with eddies fig = plt.figure(figsize=(10, 5)) -ax = fig.add_axes([0, 0, 1, 1], projection="full_axes") +ax = fig.add_axes([0, 0, 1, 1], projection=GUI_AXES) ax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid() x, y = meshgrid(g.x_c, g.y_c) a.filled(ax, facecolors="r", alpha=0.1), c.filled(ax, facecolors="b", alpha=0.1) @@ -82,7 +82,7 @@ def save(self, *args, **kwargs): def anim_ax(**kw): t = 0 fig = plt.figure(figsize=(10, 5), dpi=55) - axes = fig.add_axes([0, 0, 1, 1], projection="full_axes") + axes = fig.add_axes([0, 0, 1, 1], projection=GUI_AXES) axes.set_xlim(19, 30), axes.set_ylim(31, 36.5), axes.grid() a.filled(axes, facecolors="r", alpha=0.1), c.filled(axes, facecolors="b", alpha=0.1) line = axes.plot([], [], "k", **kw)[0] diff --git a/examples/06_grid_manipulation/pet_lavd.py b/examples/06_grid_manipulation/pet_lavd.py index e0dbbb54..ed21738f 100644 --- a/examples/06_grid_manipulation/pet_lavd.py +++ b/examples/06_grid_manipulation/pet_lavd.py @@ -24,16 +24,16 @@ from matplotlib.animation import FuncAnimation from numpy import arange, meshgrid, zeros -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.gui import GUI_AXES from py_eddy_tracker.observations.observation import EddiesObservations # %% def start_ax(title="", dpi=90): fig = plt.figure(figsize=(16, 9), dpi=dpi) - ax = fig.add_axes([0, 0, 1, 1], projection="full_axes") + ax = fig.add_axes([0, 0, 1, 1], projection=GUI_AXES) ax.set_xlim(0, 32), ax.set_ylim(28, 46) ax.set_title(title) return fig, ax, ax.text(3, 32, "", fontsize=20) diff --git a/examples/07_cube_manipulation/pet_cube.py b/examples/07_cube_manipulation/pet_cube.py index 6c0db253..a674359d 100644 --- a/examples/07_cube_manipulation/pet_cube.py +++ b/examples/07_cube_manipulation/pet_cube.py @@ -12,10 +12,10 @@ from matplotlib.animation import FuncAnimation from numpy import arange, isnan, meshgrid, ones -import py_eddy_tracker.gui from py_eddy_tracker import start_logger from py_eddy_tracker.data import get_demo_path from py_eddy_tracker.dataset.grid import GridCollection +from py_eddy_tracker.gui import GUI_AXES start_logger().setLevel("ERROR") @@ -70,7 +70,7 @@ def save(self, *args, **kwargs): # Function def anim_ax(**kw): fig = plt.figure(figsize=(10, 5), dpi=55) - axes = fig.add_axes([0, 0, 1, 1], projection="full_axes") + axes = fig.add_axes([0, 0, 1, 1], projection=GUI_AXES) axes.set_xlim(19, 30), axes.set_ylim(31, 36.5), axes.grid() line = axes.plot([], [], "k", **kw)[0] return fig, axes.text(21, 32.1, ""), line diff --git a/examples/07_cube_manipulation/pet_lavd_detection.py b/examples/07_cube_manipulation/pet_lavd_detection.py index dc3a83ff..1fa4d60b 100644 --- a/examples/07_cube_manipulation/pet_lavd_detection.py +++ b/examples/07_cube_manipulation/pet_lavd_detection.py @@ -23,10 +23,10 @@ from matplotlib import pyplot as plt from numpy import arange, isnan, ma, meshgrid, zeros -import py_eddy_tracker.gui from py_eddy_tracker import start_logger from py_eddy_tracker.data import get_demo_path from py_eddy_tracker.dataset.grid import GridCollection, RegularGridDataset +from py_eddy_tracker.gui import GUI_AXES start_logger().setLevel("ERROR") @@ -47,7 +47,7 @@ def from_(cls, x, y, z): # %% def start_ax(title="", dpi=90): fig = plt.figure(figsize=(12, 5), dpi=dpi) - ax = fig.add_axes([0.05, 0.08, 0.9, 0.9], projection="full_axes") + ax = fig.add_axes([0.05, 0.08, 0.9, 0.9], projection=GUI_AXES) ax.set_xlim(-6, 36), ax.set_ylim(31, 45) ax.set_title(title) return fig, ax, ax.text(3, 32, "", fontsize=20) diff --git a/examples/16_network/pet_atlas.py b/examples/16_network/pet_atlas.py index 540d312d..7f86790a 100644 --- a/examples/16_network/pet_atlas.py +++ b/examples/16_network/pet_atlas.py @@ -5,8 +5,8 @@ from matplotlib import pyplot as plt from numpy import ma -import py_eddy_tracker.gui from py_eddy_tracker.data import get_remote_demo_sample +from py_eddy_tracker.gui import GUI_AXES from py_eddy_tracker.observations.network import NetworkObservations n = NetworkObservations.load_file( @@ -26,7 +26,7 @@ # Functions def start_axes(title): fig = plt.figure(figsize=(13, 5)) - ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection="full_axes") + ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=GUI_AXES) ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46) ax.set_aspect("equal") ax.set_title(title, weight="bold") diff --git a/examples/16_network/pet_ioannou_2017_case.py b/examples/16_network/pet_ioannou_2017_case.py index 7669b010..781514fe 100644 --- a/examples/16_network/pet_ioannou_2017_case.py +++ b/examples/16_network/pet_ioannou_2017_case.py @@ -16,9 +16,9 @@ from matplotlib.ticker import FuncFormatter from numpy import arange, where -import py_eddy_tracker.gui from py_eddy_tracker.appli.gui import Anim from py_eddy_tracker.data import get_demo_path +from py_eddy_tracker.gui import GUI_AXES from py_eddy_tracker.observations.network import NetworkObservations @@ -48,7 +48,7 @@ def formatter(x, pos): def start_axes(title=""): fig = plt.figure(figsize=(13, 6)) - ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection="full_axes") + ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=GUI_AXES) ax.set_xlim(19, 29), ax.set_ylim(31, 35.5) ax.set_aspect("equal") ax.set_title(title, weight="bold") diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index 2759edb4..c4989edb 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -5,8 +5,8 @@ from matplotlib import pyplot as plt from numpy import where -import py_eddy_tracker.gui from py_eddy_tracker import data +from py_eddy_tracker.gui import GUI_AXES from py_eddy_tracker.observations.network import NetworkObservations # %% @@ -266,7 +266,7 @@ # %% # Only a map can be tricky to understand, with a timeline it's easier! fig = plt.figure(figsize=(15, 8)) -ax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection="full_axes") +ax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=GUI_AXES) n.plot(ax, color_cycle=n.COLORS) ax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid() ax = fig.add_axes([0.08, 0.7, 0.7, 0.3]) @@ -278,7 +278,7 @@ # ----------------- # Display the position of the eddies after a merging fig = plt.figure(figsize=(15, 8)) -ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") +ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection=GUI_AXES) n.plot(ax, color_cycle=n.COLORS) m1, m0, m0_stop = n.merging_event(triplet=True) m1.display(ax, color="violet", lw=2, label="Eddies after merging") @@ -296,7 +296,7 @@ # ------------------ # Display the position of the eddies before a splitting fig = plt.figure(figsize=(15, 8)) -ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") +ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection=GUI_AXES) n.plot(ax, color_cycle=n.COLORS) s0, s1, s1_start = n.spliting_event(triplet=True) s0.display(ax, color="violet", lw=2, label="Eddies before splitting") @@ -314,7 +314,7 @@ # --------------- # Display the starting position of non-splitted eddies fig = plt.figure(figsize=(15, 8)) -ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") +ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection=GUI_AXES) birth = n.birth_event() birth.display(ax) ax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid() @@ -325,7 +325,7 @@ # --------------- # Display the last position of non-merged eddies fig = plt.figure(figsize=(15, 8)) -ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes") +ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection=GUI_AXES) death = n.death_event() death.display(ax) ax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid() diff --git a/examples/16_network/pet_replay_segmentation.py b/examples/16_network/pet_replay_segmentation.py index c33028fc..757854d5 100644 --- a/examples/16_network/pet_replay_segmentation.py +++ b/examples/16_network/pet_replay_segmentation.py @@ -11,8 +11,8 @@ from matplotlib.ticker import FuncFormatter from numpy import where -import py_eddy_tracker.gui from py_eddy_tracker.data import get_demo_path +from py_eddy_tracker.gui import GUI_AXES from py_eddy_tracker.observations.network import NetworkObservations from py_eddy_tracker.observations.tracking import TrackEddiesObservations @@ -24,7 +24,7 @@ def formatter(x, pos): def start_axes(title=""): fig = plt.figure(figsize=(13, 6)) - ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection="full_axes") + ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=GUI_AXES) ax.set_xlim(19, 29), ax.set_ylim(31, 35.5) ax.set_aspect("equal") ax.set_title(title, weight="bold") diff --git a/examples/16_network/pet_segmentation_anim.py b/examples/16_network/pet_segmentation_anim.py index b2757809..340163a1 100644 --- a/examples/16_network/pet_segmentation_anim.py +++ b/examples/16_network/pet_segmentation_anim.py @@ -10,8 +10,8 @@ from matplotlib.colors import ListedColormap from numpy import ones, where -import py_eddy_tracker.gui from py_eddy_tracker.data import get_demo_path +from py_eddy_tracker.gui import GUI_AXES from py_eddy_tracker.observations.network import NetworkObservations from py_eddy_tracker.observations.tracking import TrackEddiesObservations @@ -104,7 +104,7 @@ def update(i_frame): fig = plt.figure(figsize=(16, 9), dpi=60) -ax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection="full_axes") +ax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=GUI_AXES) ax.set_title(f"{len(e)} observations to segment") ax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid() vmax = TRACKS[-1].max() @@ -121,6 +121,6 @@ def update(i_frame): # Final Result # ------------ fig = plt.figure(figsize=(16, 9)) -ax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection="full_axes") +ax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=GUI_AXES) ax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid() _ = ax.scatter(e.lon, e.lat, c=TRACKS[-1], cmap=cmap, vmin=0, vmax=vmax, s=20) diff --git a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb index 53725a05..b660df52 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, isnan, meshgrid, ones\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\nfrom py_eddy_tracker.observations.observation import EddiesObservations" + "import re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, isnan, meshgrid, ones\n\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\nfrom py_eddy_tracker.gui import GUI_AXES\nfrom py_eddy_tracker.observations.observation import EddiesObservations" ] }, { @@ -80,7 +80,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(10, 5))\nax = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\nax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid()\nx, y = meshgrid(g.x_c, g.y_c)\na.filled(ax, facecolors=\"r\", alpha=0.1), c.filled(ax, facecolors=\"b\", alpha=0.1)\n_ = ax.quiver(x.T, y.T, g.grid(\"u\"), g.grid(\"v\"), scale=20)" + "fig = plt.figure(figsize=(10, 5))\nax = fig.add_axes([0, 0, 1, 1], projection=GUI_AXES)\nax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid()\nx, y = meshgrid(g.x_c, g.y_c)\na.filled(ax, facecolors=\"r\", alpha=0.1), c.filled(ax, facecolors=\"b\", alpha=0.1)\n_ = ax.quiver(x.T, y.T, g.grid(\"u\"), g.grid(\"v\"), scale=20)" ] }, { @@ -145,7 +145,7 @@ }, "outputs": [], "source": [ - "def anim_ax(**kw):\n t = 0\n fig = plt.figure(figsize=(10, 5), dpi=55)\n axes = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\n axes.set_xlim(19, 30), axes.set_ylim(31, 36.5), axes.grid()\n a.filled(axes, facecolors=\"r\", alpha=0.1), c.filled(axes, facecolors=\"b\", alpha=0.1)\n line = axes.plot([], [], \"k\", **kw)[0]\n return fig, axes.text(21, 32.1, \"\"), line, t\n\n\ndef update(i_frame, t_step):\n global t\n x, y = p.__next__()\n t += t_step\n l.set_data(x, y)\n txt.set_text(f\"T0 + {t:.1f} days\")" + "def anim_ax(**kw):\n t = 0\n fig = plt.figure(figsize=(10, 5), dpi=55)\n axes = fig.add_axes([0, 0, 1, 1], projection=GUI_AXES)\n axes.set_xlim(19, 30), axes.set_ylim(31, 36.5), axes.grid()\n a.filled(axes, facecolors=\"r\", alpha=0.1), c.filled(axes, facecolors=\"b\", alpha=0.1)\n line = axes.plot([], [], \"k\", **kw)[0]\n return fig, axes.text(21, 32.1, \"\"), line, t\n\n\ndef update(i_frame, t_step):\n global t\n x, y = p.__next__()\n t += t_step\n l.set_data(x, y)\n txt.set_text(f\"T0 + {t:.1f} days\")" ] }, { @@ -262,7 +262,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.9.2" } }, "nbformat": 4, diff --git a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb index 6cef91bc..67983cec 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, meshgrid, zeros\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\nfrom py_eddy_tracker.observations.observation import EddiesObservations" + "import re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, meshgrid, zeros\n\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import RegularGridDataset\nfrom py_eddy_tracker.gui import GUI_AXES\nfrom py_eddy_tracker.observations.observation import EddiesObservations" ] }, { @@ -37,7 +37,7 @@ }, "outputs": [], "source": [ - "def start_ax(title=\"\", dpi=90):\n fig = plt.figure(figsize=(16, 9), dpi=dpi)\n ax = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\n ax.set_xlim(0, 32), ax.set_ylim(28, 46)\n ax.set_title(title)\n return fig, ax, ax.text(3, 32, \"\", fontsize=20)\n\n\ndef update_axes(ax, mappable=None):\n ax.grid()\n if mappable:\n cb = plt.colorbar(\n mappable,\n cax=ax.figure.add_axes([0.05, 0.1, 0.9, 0.01]),\n orientation=\"horizontal\",\n )\n cb.set_label(\"Vorticity integration along trajectory at initial position\")\n return cb\n\n\nkw_vorticity = dict(vmin=0, vmax=2e-5, cmap=\"viridis\")" + "def start_ax(title=\"\", dpi=90):\n fig = plt.figure(figsize=(16, 9), dpi=dpi)\n ax = fig.add_axes([0, 0, 1, 1], projection=GUI_AXES)\n ax.set_xlim(0, 32), ax.set_ylim(28, 46)\n ax.set_title(title)\n return fig, ax, ax.text(3, 32, \"\", fontsize=20)\n\n\ndef update_axes(ax, mappable=None):\n ax.grid()\n if mappable:\n cb = plt.colorbar(\n mappable,\n cax=ax.figure.add_axes([0.05, 0.1, 0.9, 0.01]),\n orientation=\"horizontal\",\n )\n cb.set_label(\"Vorticity integration along trajectory at initial position\")\n return cb\n\n\nkw_vorticity = dict(vmin=0, vmax=2e-5, cmap=\"viridis\")" ] }, { @@ -201,7 +201,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.9.2" } }, "nbformat": 4, diff --git a/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb b/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb index 63cd36dc..a8ed7f1b 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "# sphinx_gallery_thumbnail_number = 2\nimport re\nfrom datetime import datetime, timedelta\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, isnan, meshgrid, ones\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import GridCollection\n\nstart_logger().setLevel(\"ERROR\")" + "# sphinx_gallery_thumbnail_number = 2\nimport re\nfrom datetime import datetime, timedelta\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, isnan, meshgrid, ones\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import GridCollection\nfrom py_eddy_tracker.gui import GUI_AXES\n\nstart_logger().setLevel(\"ERROR\")" ] }, { @@ -91,7 +91,7 @@ }, "outputs": [], "source": [ - "def anim_ax(**kw):\n fig = plt.figure(figsize=(10, 5), dpi=55)\n axes = fig.add_axes([0, 0, 1, 1], projection=\"full_axes\")\n axes.set_xlim(19, 30), axes.set_ylim(31, 36.5), axes.grid()\n line = axes.plot([], [], \"k\", **kw)[0]\n return fig, axes.text(21, 32.1, \"\"), line\n\n\ndef update(_):\n tt, xt, yt = f.__next__()\n mappable.set_data(xt, yt)\n d = timedelta(tt / 86400.0) + datetime(1950, 1, 1)\n txt.set_text(f\"{d:%Y/%m/%d-%H}\")" + "def anim_ax(**kw):\n fig = plt.figure(figsize=(10, 5), dpi=55)\n axes = fig.add_axes([0, 0, 1, 1], projection=GUI_AXES)\n axes.set_xlim(19, 30), axes.set_ylim(31, 36.5), axes.grid()\n line = axes.plot([], [], \"k\", **kw)[0]\n return fig, axes.text(21, 32.1, \"\"), line\n\n\ndef update(_):\n tt, xt, yt = f.__next__()\n mappable.set_data(xt, yt)\n d = timedelta(tt / 86400.0) + datetime(1950, 1, 1)\n txt.set_text(f\"{d:%Y/%m/%d-%H}\")" ] }, { @@ -158,7 +158,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.9.2" } }, "nbformat": 4, diff --git a/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb b/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb index e123abe4..f4e5f77e 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "from datetime import datetime\n\nfrom matplotlib import pyplot as plt\nfrom numpy import arange, isnan, ma, meshgrid, zeros\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import GridCollection, RegularGridDataset\n\nstart_logger().setLevel(\"ERROR\")" + "from datetime import datetime\n\nfrom matplotlib import pyplot as plt\nfrom numpy import arange, isnan, ma, meshgrid, zeros\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import GridCollection, RegularGridDataset\nfrom py_eddy_tracker.gui import GUI_AXES\n\nstart_logger().setLevel(\"ERROR\")" ] }, { @@ -48,7 +48,7 @@ }, "outputs": [], "source": [ - "def start_ax(title=\"\", dpi=90):\n fig = plt.figure(figsize=(12, 5), dpi=dpi)\n ax = fig.add_axes([0.05, 0.08, 0.9, 0.9], projection=\"full_axes\")\n ax.set_xlim(-6, 36), ax.set_ylim(31, 45)\n ax.set_title(title)\n return fig, ax, ax.text(3, 32, \"\", fontsize=20)\n\n\ndef update_axes(ax, mappable=None):\n ax.grid()\n if mappable:\n cb = plt.colorbar(\n mappable,\n cax=ax.figure.add_axes([0.05, 0.1, 0.9, 0.01]),\n orientation=\"horizontal\",\n )\n cb.set_label(\"LAVD at initial position\")\n return cb\n\n\nkw_lavd = dict(vmin=0, vmax=2e-5, cmap=\"viridis\")" + "def start_ax(title=\"\", dpi=90):\n fig = plt.figure(figsize=(12, 5), dpi=dpi)\n ax = fig.add_axes([0.05, 0.08, 0.9, 0.9], projection=GUI_AXES)\n ax.set_xlim(-6, 36), ax.set_ylim(31, 45)\n ax.set_title(title)\n return fig, ax, ax.text(3, 32, \"\", fontsize=20)\n\n\ndef update_axes(ax, mappable=None):\n ax.grid()\n if mappable:\n cb = plt.colorbar(\n mappable,\n cax=ax.figure.add_axes([0.05, 0.1, 0.9, 0.01]),\n orientation=\"horizontal\",\n )\n cb.set_label(\"LAVD at initial position\")\n return cb\n\n\nkw_lavd = dict(vmin=0, vmax=2e-5, cmap=\"viridis\")" ] }, { @@ -194,7 +194,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.9.2" } }, "nbformat": 4, diff --git a/notebooks/python_module/16_network/pet_atlas.ipynb b/notebooks/python_module/16_network/pet_atlas.ipynb index 514317a6..ee8f1934 100644 --- a/notebooks/python_module/16_network/pet_atlas.ipynb +++ b/notebooks/python_module/16_network/pet_atlas.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "from matplotlib import pyplot as plt\nfrom numpy import ma\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_remote_demo_sample\nfrom py_eddy_tracker.observations.network import NetworkObservations\n\nn = NetworkObservations.load_file(\n get_remote_demo_sample(\n \"eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc\"\n )\n)" + "from matplotlib import pyplot as plt\nfrom numpy import ma\n\nfrom py_eddy_tracker.data import get_remote_demo_sample\nfrom py_eddy_tracker.gui import GUI_AXES\nfrom py_eddy_tracker.observations.network import NetworkObservations\n\nn = NetworkObservations.load_file(\n get_remote_demo_sample(\n \"eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc\"\n )\n)" ] }, { @@ -62,7 +62,7 @@ }, "outputs": [], "source": [ - "def start_axes(title):\n fig = plt.figure(figsize=(13, 5))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=\"full_axes\")\n ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid()\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" + "def start_axes(title):\n fig = plt.figure(figsize=(13, 5))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=GUI_AXES)\n ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid()\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" ] }, { @@ -363,7 +363,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.9.2" } }, "nbformat": 4, diff --git a/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb b/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb index e803df5f..743b753f 100644 --- a/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb +++ b/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import re\nfrom datetime import datetime, timedelta\n\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.ticker import FuncFormatter\nfrom numpy import arange, where\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.observations.network import NetworkObservations" + "import re\nfrom datetime import datetime, timedelta\n\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.ticker import FuncFormatter\nfrom numpy import arange, where\n\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.gui import GUI_AXES\nfrom py_eddy_tracker.observations.network import NetworkObservations" ] }, { @@ -37,7 +37,7 @@ }, "outputs": [], "source": [ - "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)\n\n\n@FuncFormatter\ndef formatter(x, pos):\n return (timedelta(x) + datetime(1950, 1, 1)).strftime(\"%d/%m/%Y\")\n\n\ndef start_axes(title=\"\"):\n fig = plt.figure(figsize=(13, 6))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=\"full_axes\")\n ax.set_xlim(19, 29), ax.set_ylim(31, 35.5)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n return ax\n\n\ndef timeline_axes(title=\"\"):\n fig = plt.figure(figsize=(15, 5))\n ax = fig.add_axes([0.03, 0.06, 0.90, 0.88])\n ax.set_title(title, weight=\"bold\")\n ax.xaxis.set_major_formatter(formatter), ax.grid()\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid(True)\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)\n\n\n@FuncFormatter\ndef formatter(x, pos):\n return (timedelta(x) + datetime(1950, 1, 1)).strftime(\"%d/%m/%Y\")\n\n\ndef start_axes(title=\"\"):\n fig = plt.figure(figsize=(13, 6))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=GUI_AXES)\n ax.set_xlim(19, 29), ax.set_ylim(31, 35.5)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n return ax\n\n\ndef timeline_axes(title=\"\"):\n fig = plt.figure(figsize=(15, 5))\n ax = fig.add_axes([0.03, 0.06, 0.90, 0.88])\n ax.set_title(title, weight=\"bold\")\n ax.xaxis.set_major_formatter(formatter), ax.grid()\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid(True)\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" ] }, { @@ -248,7 +248,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.9.2" } }, "nbformat": 4, diff --git a/notebooks/python_module/16_network/pet_relative.ipynb b/notebooks/python_module/16_network/pet_relative.ipynb index 23537375..cee4010a 100644 --- a/notebooks/python_module/16_network/pet_relative.ipynb +++ b/notebooks/python_module/16_network/pet_relative.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "from matplotlib import pyplot as plt\nfrom numpy import where\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.observations.network import NetworkObservations" + "from matplotlib import pyplot as plt\nfrom numpy import where\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.gui import GUI_AXES\nfrom py_eddy_tracker.observations.network import NetworkObservations" ] }, { @@ -447,7 +447,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(15, 8))\nax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=\"full_axes\")\nn.plot(ax, color_cycle=n.COLORS)\nax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid()\nax = fig.add_axes([0.08, 0.7, 0.7, 0.3])\n_ = n.display_timeline(ax)" + "fig = plt.figure(figsize=(15, 8))\nax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=GUI_AXES)\nn.plot(ax, color_cycle=n.COLORS)\nax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid()\nax = fig.add_axes([0.08, 0.7, 0.7, 0.3])\n_ = n.display_timeline(ax)" ] }, { @@ -465,7 +465,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(15, 8))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection=\"full_axes\")\nn.plot(ax, color_cycle=n.COLORS)\nm1, m0, m0_stop = n.merging_event(triplet=True)\nm1.display(ax, color=\"violet\", lw=2, label=\"Eddies after merging\")\nm0.display(ax, color=\"blueviolet\", lw=2, label=\"Eddies before merging\")\nm0_stop.display(ax, color=\"black\", lw=2, label=\"Eddies stopped by merging\")\nax.plot(m1.lon, m1.lat, marker=\".\", color=\"purple\", ls=\"\")\nax.plot(m0.lon, m0.lat, marker=\".\", color=\"blueviolet\", ls=\"\")\nax.plot(m0_stop.lon, m0_stop.lat, marker=\".\", color=\"black\", ls=\"\")\nax.legend()\nax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid()\nm1" + "fig = plt.figure(figsize=(15, 8))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection=GUI_AXES)\nn.plot(ax, color_cycle=n.COLORS)\nm1, m0, m0_stop = n.merging_event(triplet=True)\nm1.display(ax, color=\"violet\", lw=2, label=\"Eddies after merging\")\nm0.display(ax, color=\"blueviolet\", lw=2, label=\"Eddies before merging\")\nm0_stop.display(ax, color=\"black\", lw=2, label=\"Eddies stopped by merging\")\nax.plot(m1.lon, m1.lat, marker=\".\", color=\"purple\", ls=\"\")\nax.plot(m0.lon, m0.lat, marker=\".\", color=\"blueviolet\", ls=\"\")\nax.plot(m0_stop.lon, m0_stop.lat, marker=\".\", color=\"black\", ls=\"\")\nax.legend()\nax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid()\nm1" ] }, { @@ -483,7 +483,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(15, 8))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection=\"full_axes\")\nn.plot(ax, color_cycle=n.COLORS)\ns0, s1, s1_start = n.spliting_event(triplet=True)\ns0.display(ax, color=\"violet\", lw=2, label=\"Eddies before splitting\")\ns1.display(ax, color=\"blueviolet\", lw=2, label=\"Eddies after splitting\")\ns1_start.display(ax, color=\"black\", lw=2, label=\"Eddies starting by splitting\")\nax.plot(s0.lon, s0.lat, marker=\".\", color=\"purple\", ls=\"\")\nax.plot(s1.lon, s1.lat, marker=\".\", color=\"blueviolet\", ls=\"\")\nax.plot(s1_start.lon, s1_start.lat, marker=\".\", color=\"black\", ls=\"\")\nax.legend()\nax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid()\ns1" + "fig = plt.figure(figsize=(15, 8))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection=GUI_AXES)\nn.plot(ax, color_cycle=n.COLORS)\ns0, s1, s1_start = n.spliting_event(triplet=True)\ns0.display(ax, color=\"violet\", lw=2, label=\"Eddies before splitting\")\ns1.display(ax, color=\"blueviolet\", lw=2, label=\"Eddies after splitting\")\ns1_start.display(ax, color=\"black\", lw=2, label=\"Eddies starting by splitting\")\nax.plot(s0.lon, s0.lat, marker=\".\", color=\"purple\", ls=\"\")\nax.plot(s1.lon, s1.lat, marker=\".\", color=\"blueviolet\", ls=\"\")\nax.plot(s1_start.lon, s1_start.lat, marker=\".\", color=\"black\", ls=\"\")\nax.legend()\nax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid()\ns1" ] }, { @@ -501,7 +501,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(15, 8))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection=\"full_axes\")\nbirth = n.birth_event()\nbirth.display(ax)\nax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid()\nbirth" + "fig = plt.figure(figsize=(15, 8))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection=GUI_AXES)\nbirth = n.birth_event()\nbirth.display(ax)\nax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid()\nbirth" ] }, { @@ -519,7 +519,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(15, 8))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection=\"full_axes\")\ndeath = n.death_event()\ndeath.display(ax)\nax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid()\ndeath" + "fig = plt.figure(figsize=(15, 8))\nax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection=GUI_AXES)\ndeath = n.death_event()\ndeath.display(ax)\nax.set_xlim(17.5, 27.5), ax.set_ylim(31, 36), ax.grid()\ndeath" ] } ], @@ -539,7 +539,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.9.2" } }, "nbformat": 4, diff --git a/notebooks/python_module/16_network/pet_replay_segmentation.ipynb b/notebooks/python_module/16_network/pet_replay_segmentation.ipynb index 7acb3f51..48f4955b 100644 --- a/notebooks/python_module/16_network/pet_replay_segmentation.ipynb +++ b/notebooks/python_module/16_network/pet_replay_segmentation.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "from datetime import datetime, timedelta\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.ticker import FuncFormatter\nfrom numpy import where\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations\n\n\n@FuncFormatter\ndef formatter(x, pos):\n return (timedelta(x) + datetime(1950, 1, 1)).strftime(\"%d/%m/%Y\")\n\n\ndef start_axes(title=\"\"):\n fig = plt.figure(figsize=(13, 6))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=\"full_axes\")\n ax.set_xlim(19, 29), ax.set_ylim(31, 35.5)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n return ax\n\n\ndef timeline_axes(title=\"\"):\n fig = plt.figure(figsize=(15, 5))\n ax = fig.add_axes([0.04, 0.06, 0.89, 0.88])\n ax.set_title(title, weight=\"bold\")\n ax.xaxis.set_major_formatter(formatter), ax.grid()\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid(True)\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" + "from datetime import datetime, timedelta\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.ticker import FuncFormatter\nfrom numpy import where\n\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.gui import GUI_AXES\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations\n\n\n@FuncFormatter\ndef formatter(x, pos):\n return (timedelta(x) + datetime(1950, 1, 1)).strftime(\"%d/%m/%Y\")\n\n\ndef start_axes(title=\"\"):\n fig = plt.figure(figsize=(13, 6))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=GUI_AXES)\n ax.set_xlim(19, 29), ax.set_ylim(31, 35.5)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n return ax\n\n\ndef timeline_axes(title=\"\"):\n fig = plt.figure(figsize=(15, 5))\n ax = fig.add_axes([0.04, 0.06, 0.89, 0.88])\n ax.set_title(title, weight=\"bold\")\n ax.xaxis.set_major_formatter(formatter), ax.grid()\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid(True)\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" ] }, { @@ -172,7 +172,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.9.2" } }, "nbformat": 4, diff --git a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb index 18da8478..ae36381c 100644 --- a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb +++ b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "# sphinx_gallery_thumbnail_number = 2\nimport re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.colors import ListedColormap\nfrom numpy import ones, where\n\nimport py_eddy_tracker.gui\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations" + "# sphinx_gallery_thumbnail_number = 2\nimport re\n\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.colors import ListedColormap\nfrom numpy import ones, where\n\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.gui import GUI_AXES\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations" ] }, { @@ -109,7 +109,7 @@ }, "outputs": [], "source": [ - "def update(i_frame):\n tr = TRACKS[i_frame]\n mappable_tracks.set_array(tr)\n s = 40 * ones(tr.shape)\n s[tr == 0] = 4\n mappable_tracks.set_sizes(s)\n\n indices_frames = INDICES[i_frame]\n mappable_CONTOUR.set_data(\n e.contour_lon_e[indices_frames],\n e.contour_lat_e[indices_frames],\n )\n mappable_CONTOUR.set_color(cmap.colors[tr[indices_frames] % len(cmap.colors)])\n return (mappable_tracks,)\n\n\nfig = plt.figure(figsize=(16, 9), dpi=60)\nax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=\"full_axes\")\nax.set_title(f\"{len(e)} observations to segment\")\nax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid()\nvmax = TRACKS[-1].max()\ncmap = ListedColormap([\"gray\", *e.COLORS[:-1]], name=\"from_list\", N=vmax)\nmappable_tracks = ax.scatter(\n e.lon, e.lat, c=TRACKS[0], cmap=cmap, vmin=0, vmax=vmax, s=20\n)\nmappable_CONTOUR = ax.plot(\n e.contour_lon_e[INDICES[0]], e.contour_lat_e[INDICES[0]], color=cmap.colors[0]\n)[0]\nani = VideoAnimation(fig, update, frames=range(1, len(TRACKS), 4), interval=125)" + "def update(i_frame):\n tr = TRACKS[i_frame]\n mappable_tracks.set_array(tr)\n s = 40 * ones(tr.shape)\n s[tr == 0] = 4\n mappable_tracks.set_sizes(s)\n\n indices_frames = INDICES[i_frame]\n mappable_CONTOUR.set_data(\n e.contour_lon_e[indices_frames],\n e.contour_lat_e[indices_frames],\n )\n mappable_CONTOUR.set_color(cmap.colors[tr[indices_frames] % len(cmap.colors)])\n return (mappable_tracks,)\n\n\nfig = plt.figure(figsize=(16, 9), dpi=60)\nax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=GUI_AXES)\nax.set_title(f\"{len(e)} observations to segment\")\nax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid()\nvmax = TRACKS[-1].max()\ncmap = ListedColormap([\"gray\", *e.COLORS[:-1]], name=\"from_list\", N=vmax)\nmappable_tracks = ax.scatter(\n e.lon, e.lat, c=TRACKS[0], cmap=cmap, vmin=0, vmax=vmax, s=20\n)\nmappable_CONTOUR = ax.plot(\n e.contour_lon_e[INDICES[0]], e.contour_lat_e[INDICES[0]], color=cmap.colors[0]\n)[0]\nani = VideoAnimation(fig, update, frames=range(1, len(TRACKS), 4), interval=125)" ] }, { @@ -127,7 +127,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(16, 9))\nax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=\"full_axes\")\nax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid()\n_ = ax.scatter(e.lon, e.lat, c=TRACKS[-1], cmap=cmap, vmin=0, vmax=vmax, s=20)" + "fig = plt.figure(figsize=(16, 9))\nax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=GUI_AXES)\nax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid()\n_ = ax.scatter(e.lon, e.lat, c=TRACKS[-1], cmap=cmap, vmin=0, vmax=vmax, s=20)" ] } ], @@ -147,7 +147,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.9.2" } }, "nbformat": 4, diff --git a/src/py_eddy_tracker/gui.py b/src/py_eddy_tracker/gui.py index 423ff306..1fe236dd 100644 --- a/src/py_eddy_tracker/gui.py +++ b/src/py_eddy_tracker/gui.py @@ -26,12 +26,15 @@ def __init__(self, *args, **kwargs): self.set_aspect("equal") +GUI_AXES = "full_axes" + + class GUIAxes(PlatCarreAxes): """ Axes which will use full space available """ - name = "full_axes" + name = GUI_AXES def end_pan(self, *args, **kwargs): (x0, x1), (y0, y1) = self.get_xlim(), self.get_ylim() @@ -125,7 +128,7 @@ def med(self): def setup(self): self.figure = plt.figure() # map - self.map = self.figure.add_axes((0, 0.25, 1, 0.75), projection="full_axes") + self.map = self.figure.add_axes((0, 0.25, 1, 0.75), projection=GUI_AXES) self.map.grid() self.map.tick_params("both", pad=-22) # self.map.tick_params("y", pad=-22) From 8de7284c08dbb6c4c425b40cb9b2e2d2f4dcdf0c Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Mon, 5 Apr 2021 16:47:34 +0200 Subject: [PATCH 145/249] Clean requirements --- requirements.txt | 2 -- requirements_dev.txt | 7 +++++++ requirements_doc.txt | 16 ---------------- 3 files changed, 7 insertions(+), 18 deletions(-) create mode 100644 requirements_dev.txt delete mode 100644 requirements_doc.txt diff --git a/requirements.txt b/requirements.txt index eae54426..9539c555 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,5 +9,3 @@ pyyaml requests scipy zarr -# for binder -pyeddytrackersample \ No newline at end of file diff --git a/requirements_dev.txt b/requirements_dev.txt new file mode 100644 index 00000000..a005c37d --- /dev/null +++ b/requirements_dev.txt @@ -0,0 +1,7 @@ +-r requirements.txt +isort +black +blackdoc +flake8 +pytest +pytest-cov \ No newline at end of file diff --git a/requirements_doc.txt b/requirements_doc.txt deleted file mode 100644 index 0d926b32..00000000 --- a/requirements_doc.txt +++ /dev/null @@ -1,16 +0,0 @@ -matplotlib -netCDF4 -numba -numpy -opencv-python -pint -polygon3 -pyyaml -requests -scipy -zarr -# doc -sphinx-gallery -pyeddytrackersample -sphinx_rtd_theme -sphinx>=3.1 From 872f65ad7a0bec68848d3d7dbff4567c9141e7f8 Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Mon, 5 Apr 2021 16:47:59 +0200 Subject: [PATCH 146/249] Add test for visvlingam --- tests/test_poly.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/test_poly.py b/tests/test_poly.py index 1a0edb6f..cca53635 100644 --- a/tests/test_poly.py +++ b/tests/test_poly.py @@ -1,4 +1,4 @@ -from numpy import array, pi +from numpy import array, pi, roll from pytest import approx from py_eddy_tracker.poly import ( @@ -40,6 +40,14 @@ def test_convex_hull(): def test_visvalingam(): x = array([1, 2, 3, 4, 5, 6.75, 6, 1]) y = array([-0.5, -1.5, -1, -1.75, -1, -1, -0.5, -0.5]) + x_target = [1, 2, 3, 4, 6, 1] + y_target = [-0.5, -1.5, -1, -1.75, -0.5, -0.5] x_, y_ = visvalingam(x, y, 6) - assert ([1, 2, 3, 4, 6, 1] == x_).all() - assert ([-0.5, -1.5, -1, -1.75, -0.5, -0.5] == y_).all() + assert (x_target == x_).all() + assert (y_target == y_).all() + x_, y_ = visvalingam(x[:-1], y[:-1], 6) + assert (x_target == x_).all() + assert (y_target == y_).all() + x_, y_ = visvalingam(roll(x, 2), roll(y, 2), 6) + assert (x_target[:-1] == x_[1:]).all() + assert (y_target[:-1] == y_[1:]).all() From 5ffc05adb3a160b939af4b24fda9436b19f69b99 Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Mon, 5 Apr 2021 23:44:44 +0200 Subject: [PATCH 147/249] Add documentation about visvalingam and a correction about point removed --- src/py_eddy_tracker/observations/network.py | 7 +- src/py_eddy_tracker/poly.py | 105 +++++++++++--------- 2 files changed, 60 insertions(+), 52 deletions(-) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 115197de..0758d940 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -15,8 +15,8 @@ empty, in1d, ones, - uint32, uint16, + uint32, unique, where, zeros, @@ -490,7 +490,9 @@ def relatives(self, obs, order=2): """ Extract the segments at a certain order from multiple observations. - :param iterable,int obs: indices of observation for relatives computation. Can be one observation (int) or collection of observations (iterable(int)) + :param iterable,int obs: + indices of observation for relatives computation. Can be one observation (int) + or collection of observations (iterable(int)) :param int order: order of relatives wanted. 0 means only observations in obs, 1 means direct relatives, ... :return: all segments relatives @@ -532,7 +534,6 @@ def relatives(self, obs, order=2): segments_connexion[n_seg][1].append(seg) i_obs = [obs] if not hasattr(obs, "__iter__") else obs - distance = zeros(segment.size, dtype=uint16) - 1 def loop(seg, dist=1): diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index ad8fc148..1d40cc84 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -716,50 +716,85 @@ def tri_area2(x, y, i0, i1, i2): def visvalingam(x, y, fixed_size=18): """Polygon simplification with visvalingam algorithm + X, Y are considered like a polygon, the next point after the last one is the first one :param array x: :param array y: :param int fixed_size: array size of out - :return: New (x, y) array + :return: + New (x, y) array, last position will be equal to first one, if array size is 6, + there is only 5 point. :rtype: array,array + + .. plot:: + + import matplotlib.pyplot as plt + import numpy as np + from py_eddy_tracker.poly import visvalingam + + x = np.array([1, 2, 3, 4, 5, 6.75, 6, 1]) + y = np.array([-0.5, -1.5, -1, -1.75, -1, -1, -0.5, -0.5]) + ax = plt.subplot(111) + ax.set_aspect("equal") + ax.grid(True), ax.set_ylim(-2, -.2) + ax.plot(x, y, "r", lw=5) + ax.plot(*visvalingam(x,y,6), "b", lw=2) + plt.show() """ + # TODO : in case of original size lesser than fixed size, jump at the end nb = x.shape[0] - i0, i1 = nb - 3, nb - 2 + nb_ori = nb + # Get indice of first triangle + i0, i1 = nb - 2, nb - 1 + # Init heap with first area and tiangle h = [(tri_area2(x, y, i0, i1, 0), (i0, i1, 0))] + # Roll index for next one i0 = i1 i1 = 0 - i_previous = empty(nb - 1, dtype=numba_types.int32) - i_next = empty(nb - 1, dtype=numba_types.int32) + # Index of previous valid point + i_previous = empty(nb, dtype=numba_types.int64) + # Index of next valid point + i_next = empty(nb, dtype=numba_types.int64) + # Mask of removed + removed = zeros(nb, dtype=numba_types.bool_) i_previous[0] = -1 i_next[0] = -1 - for i in range(1, nb - 1): + for i in range(1, nb): i_previous[i] = -1 i_next[i] = -1 + # We add triangle area for all triangle heapq.heappush(h, (tri_area2(x, y, i0, i1, i), (i0, i1, i))) i0 = i1 i1 = i # we continue until we are equal to nb_pt - while len(h) >= fixed_size: + while nb >= fixed_size: # We pop lower area _, (i0, i1, i2) = heapq.heappop(h) # We check if triangle is valid(i0 or i2 not removed) - i_p, i_n = i_previous[i0], i_next[i2] - if i_p == -1 and i_n == -1: - # We store reference of delete point - i_previous[i1] = i0 - i_next[i1] = i2 + if removed[i0] or removed[i2]: + # In this cas nothing to do continue - elif i_p == -1: - i2 = i_n - elif i_n == -1: - i0 = i_p - else: - # in this case we replace two point - i0, i2 = i_p, i_n - heapq.heappush(h, (tri_area2(x, y, i0, i1, i2), (i0, i1, i2))) + # Flag obs like removed + removed[i1] = True + # We count point still valid + nb -= 1 + # Modify index for the next and previous, we jump over i1 + i_previous[i2] = i0 + i_next[i0] = i2 + # We insert 2 triangles which are modified by the deleted point + # Previous triangle + i_1 = i_previous[i0] + if i_1 == -1: + i_1 = (i0 - 1) % nb_ori + heapq.heappush(h, (tri_area2(x, y, i_1, i0, i2), (i_1, i0, i2))) + # Previous triangle + i3 = i_next[i2] + if i3 == -1: + i3 = (i2 + 1) % nb_ori + heapq.heappush(h, (tri_area2(x, y, i0, i2, i3), (i0, i2, i3))) x_new, y_new = empty(fixed_size, dtype=x.dtype), empty(fixed_size, dtype=y.dtype) j = 0 - for i, i_n in enumerate(i_next): - if i_n == -1: + for i, flag in enumerate(removed): + if not flag: x_new[j] = x[i] y_new[j] = y[i] j += 1 @@ -872,34 +907,6 @@ def poly_indexs(x_p, y_p, x_c, y_c): return indexs -@njit(cache=True) -def poly_indexs_old(x_p, y_p, x_c, y_c): - """ - index of contour for each postion inside a contour, -1 in case of no contour - - :param array x_p: longitude to test - :param array y_p: latitude to test - :param array x_c: longitude of contours - :param array y_c: latitude of contours - """ - nb_p = x_p.shape[0] - nb_c = x_c.shape[0] - indexs = -ones(nb_p, dtype=numba_types.int32) - for i in range(nb_c): - x_, y_ = reduce_size(x_c[i], y_c[i]) - x_c_min, y_c_min = x_.min(), y_.min() - x_c_max, y_c_max = x_.max(), y_.max() - v = create_vertice(x_, y_) - for j in range(nb_p): - if indexs[j] != -1: - continue - x, y = x_p[j], y_p[j] - if x > x_c_min and x < x_c_max and y > y_c_min and y < y_c_max: - if winding_number_poly(x, y, v) != 0: - indexs[j] = i - return indexs - - @njit(cache=True) def insidepoly(x_p, y_p, x_c, y_c): """ From 8e6b5d47c006bc3c79a8836beb885c7db05056fd Mon Sep 17 00:00:00 2001 From: Cori Pegliasco Date: Tue, 6 Apr 2021 14:43:29 +0200 Subject: [PATCH 148/249] - minor english --- examples/01_general_things/pet_storage.py | 2 +- examples/14_generic_tools/pet_fit_contour.py | 12 +++---- examples/16_network/pet_follow_particle.py | 12 +++---- examples/16_network/pet_ioannou_2017_case.py | 34 +++++++++++--------- 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/examples/01_general_things/pet_storage.py b/examples/01_general_things/pet_storage.py index 28f0f76e..9f0ec61e 100644 --- a/examples/01_general_things/pet_storage.py +++ b/examples/01_general_things/pet_storage.py @@ -32,7 +32,7 @@ # array field like contour/profile are 2D column. # %% -# Eddies files (zarr or netcdf) could be loaded with ```load_file``` method: +# 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 diff --git a/examples/14_generic_tools/pet_fit_contour.py b/examples/14_generic_tools/pet_fit_contour.py index 9c3f9183..2d3b6dc9 100644 --- a/examples/14_generic_tools/pet_fit_contour.py +++ b/examples/14_generic_tools/pet_fit_contour.py @@ -15,7 +15,7 @@ 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 +from py_eddy_tracker.poly import fit_circle_, fit_ellipse # %% # Load example identification file @@ -23,14 +23,14 @@ # %% -# Function to draw circle or ellips from parameter +# Function to draw circle or ellipse 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): +def build_ellipse(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) @@ -38,7 +38,7 @@ def build_ellips(x0, y0, a, b, theta): # %% -# Plot fitted circle or ellips on stored contour +# Plot fitted circle or ellipse on stored contour xs, ys = a.contour_lon_s, a.contour_lat_s fig = plt.figure(figsize=(15, 15)) @@ -51,9 +51,9 @@ def build_ellips(x0, y0, a, b, theta): ax = fig.add_subplot(4, 4, j) ax.grid(), ax.set_aspect("equal") ax.plot(x, y, label="store", color="black") - x0, y0, a, b, theta = fit_ellips(x_, y_) + x0, y0, a, b, theta = fit_ellipse(x_, y_) x0, y0 = local_to_coordinates(x0, y0, x0_, y0_) - ax.plot(*build_ellips(x0, y0, a, b, theta), label="ellips", color="green") + ax.plot(*build_ellipse(x0, y0, a, b, theta), label="ellipse", color="green") x0, y0, radius, shape_error = fit_circle_(x_, y_) x0, y0 = local_to_coordinates(x0, y0, x0_, y0_) ax.plot(*build_circle(x0, y0, radius), label="circle", color="red", lw=0.5) diff --git a/examples/16_network/pet_follow_particle.py b/examples/16_network/pet_follow_particle.py index 65746015..0c4be55d 100644 --- a/examples/16_network/pet_follow_particle.py +++ b/examples/16_network/pet_follow_particle.py @@ -33,7 +33,7 @@ def _repr_html_(self, *args, **kwargs): 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 + # In this case gif is used to create thumbnail which are not used but consumes same time than video # So we create an empty file, to save time with open(args[0], "w") as _: pass @@ -147,7 +147,7 @@ def particle_candidate(x, y, c, eddies, t_start, i_target, pct, **kwargs): e = eddies.extract_with_mask(m_start) # to be able to get global index translate_start = where(m_start)[0] - # Identify particle in eddies(only in core) + # Identify particle in eddies (only in core) i_start = e.contains(x, y, intern=True) m = i_start != -1 x, y, i_start = x[m], y[m], i_start[m] @@ -158,9 +158,9 @@ def particle_candidate(x, y, c, eddies, t_start, i_target, pct, **kwargs): e_end = eddies.extract_with_mask(m_end) # to be able to get global index translate_end = where(m_end)[0] - # Id eddies for each alive particle(in core and extern) + # Id eddies for each alive particle (in core and extern) i_end = e_end.contains(x, y) - # compute matrix and filled target array + # compute matrix and fill target array get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct) @@ -169,7 +169,7 @@ def get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct): nb_start, nb_end = translate_start.size, translate_end.size # Matrix which will store count for every couple count = zeros((nb_start, nb_end), dtype=nb_types.int32) - # Number of particle in each origin observation + # Number of particles in each origin observation ref = zeros(nb_start, dtype=nb_types.int32) # For each particle for i in range(i_start.size): @@ -181,7 +181,7 @@ def get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct): for i in range(nb_start): for j in range(nb_end): pct_ = count[i, j] - # If there are particle from i to j + # If there are particles from i to j if pct_ != 0: # Get percent pct_ = pct_ / ref[i] * 100.0 diff --git a/examples/16_network/pet_ioannou_2017_case.py b/examples/16_network/pet_ioannou_2017_case.py index 54f124f7..237cfc57 100644 --- a/examples/16_network/pet_ioannou_2017_case.py +++ b/examples/16_network/pet_ioannou_2017_case.py @@ -14,15 +14,19 @@ from matplotlib import pyplot as plt from matplotlib.animation import FuncAnimation from matplotlib.ticker import FuncFormatter -from numpy import arange, where +from numpy import arange, where, array, pi import py_eddy_tracker.gui from py_eddy_tracker.appli.gui import Anim from py_eddy_tracker.data import get_demo_path from py_eddy_tracker.observations.network import NetworkObservations +from py_eddy_tracker.generic import coordinates_to_local, local_to_coordinates +from py_eddy_tracker.poly import fit_ellipse # %% + + class VideoAnimation(FuncAnimation): def _repr_html_(self, *args, **kwargs): """To get video in html and have a player""" @@ -192,43 +196,43 @@ def update_axes(ax, mappable=None): # %% # Rotation angle # -------------- -from py_eddy_tracker.generic import coordinates_to_local, local_to_coordinates -from py_eddy_tracker.poly import fit_ellips +# For each obs, fit an ellipse to the contour, with theta the angle from the x-axis, +# a the semi ax in x direction and b the semi ax in y dimension + theta_ = list() a_ = list() b_ = list() for obs in close_to_i3: - x, y = obs['contour_lon_s'], obs['contour_lat_s'] + x, y = obs["contour_lon_s"], obs["contour_lat_s"] x0_, y0_ = x.mean(), y.mean() x_, y_ = coordinates_to_local(x, y, x0_, y0_) - x0, y0, a, b, theta = fit_ellips(x_, y_) + x0, y0, a, b, theta = fit_ellipse(x_, y_) theta_.append(theta) a_.append(a) b_.append(b) -a_=array(a_) -b_=array(b_) +a_ = array(a_) +b_ = array(b_) # %% # Theta ax = timeline_axes() -m = close_to_i3.scatter_timeline(ax, theta_, vmin=-pi/2, vmax=pi/2, cmap='hsv') +m = close_to_i3.scatter_timeline(ax, theta_, vmin=-pi / 2, vmax=pi / 2, cmap="hsv") cb = update_axes(ax, m["scatter"]) # %% -# A +# a ax = timeline_axes() -m = close_to_i3.scatter_timeline(ax, a_ * 1e-3, vmin=0, vmax=80, cmap='Spectral_r') +m = close_to_i3.scatter_timeline(ax, a_ * 1e-3, vmin=0, vmax=80, cmap="Spectral_r") cb = update_axes(ax, m["scatter"]) # %% -# B +# b ax = timeline_axes() -m = close_to_i3.scatter_timeline(ax, b_ * 1e-3, vmin=0, vmax=80, cmap='Spectral_r') +m = close_to_i3.scatter_timeline(ax, b_ * 1e-3, vmin=0, vmax=80, cmap="Spectral_r") cb = update_axes(ax, m["scatter"]) # %% -# A/B +# a/b ax = timeline_axes() -m = close_to_i3.scatter_timeline(ax, a_/b_, vmin=1, vmax=2, cmap='Spectral_r') +m = close_to_i3.scatter_timeline(ax, a_ / b_, vmin=1, vmax=2, cmap="Spectral_r") cb = update_axes(ax, m["scatter"]) - From d883b484acf7677adc04c820078f6ede07f57a71 Mon Sep 17 00:00:00 2001 From: Cori Pegliasco Date: Tue, 6 Apr 2021 14:44:20 +0200 Subject: [PATCH 149/249] -minor english --- .../old_tracker_reference.py | 8 ++++---- src/py_eddy_tracker/observations/network.py | 8 +------- .../observations/observation.py | 20 +++++++++---------- src/py_eddy_tracker/poly.py | 4 ++-- 4 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/py_eddy_tracker/featured_tracking/old_tracker_reference.py b/src/py_eddy_tracker/featured_tracking/old_tracker_reference.py index 7baaffd3..41e02db9 100644 --- a/src/py_eddy_tracker/featured_tracking/old_tracker_reference.py +++ b/src/py_eddy_tracker/featured_tracking/old_tracker_reference.py @@ -21,13 +21,13 @@ def cost_function(records_in, records_out, distance): return distance def mask_function(self, other, distance): - """We mask link with ellips and ratio""" - # Compute Parameter of ellips + """We mask link with ellipse and ratio""" + # Compute Parameter of ellipse minor, major = 1.05, 1.5 - y = self.basic_formula_ellips_major_axis( + y = self.basic_formula_ellipse_major_axis( self.lat, degrees=True, c0=minor, cmin=minor, cmax=major, lat1=23, lat2=5 ) - # mask from ellips + # mask from ellipse mask = self.shifted_ellipsoid_degrees_mask( other, minor=minor, major=y # Minor can be bigger than major?? ) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 7a57bbca..91849955 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -513,7 +513,6 @@ def relatives(self, obs, order=2): else: segments_connexion[seg][0] = i_slice - if i_p != -1: if p_seg not in segments_connexion: @@ -531,12 +530,7 @@ def relatives(self, obs, order=2): segments_connexion[seg][1].append(n_seg) segments_connexion[n_seg][1].append(seg) - - i_obs = ( - [obs] - if not hasattr(obs, "__iter__") - else obs - ) + i_obs = [obs] if not hasattr(obs, "__iter__") else obs import numpy as np distance = zeros(segment.size, dtype=np.uint16) - 1 diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 0d0f45b7..5ee45a28 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -87,7 +87,7 @@ def shifted_ellipsoid_degrees_mask2(lon0, lat0, lon1, lat1, minor=1.5, major=1.5 # Focal f_right = lon0 f_left = f_right - (c - minor) - # Ellips center + # Ellipse center x_c = (f_left + f_right) * 0.5 nb_0, nb_1 = lat0.shape[0], lat1.shape[0] @@ -1248,7 +1248,7 @@ def shifted_ellipsoid_degrees_mask(self, other, minor=1.5, major=1.5): ) def fixed_ellipsoid_mask( - self, other, minor=50, major=100, only_east=False, shifted_ellips=False + self, other, minor=50, major=100, only_east=False, shifted_ellipse=False ): dist = self.distance(other).T accepted = dist < minor @@ -1272,13 +1272,13 @@ def fixed_ellipsoid_mask( ) lon_self = self.lon[index_self] - if shifted_ellips: - x_center_ellips = lon_self - (major - minor) / 2 + if shifted_ellipse: + x_center_ellipse = lon_self - (major - minor) / 2 else: - x_center_ellips = lon_self + x_center_ellipse = lon_self - lon_left_f = x_center_ellips - f_degree - lon_right_f = x_center_ellips + f_degree + lon_left_f = x_center_ellipse - f_degree + lon_right_f = x_center_ellipse + f_degree dist_left_f = distance( lon_left_f, @@ -1302,7 +1302,7 @@ def fixed_ellipsoid_mask( return accepted.T @staticmethod - def basic_formula_ellips_major_axis( + def basic_formula_ellipse_major_axis( lats, cmin=1.5, cmax=10.0, c0=1.5, lat1=13.5, lat2=5.0, degrees=False ): """Give major axis in km with a given latitude""" @@ -2054,8 +2054,8 @@ def contains(self, x, y, intern=False): :rtype: array[int32] """ xname, yname = self.intern(intern) - m = ~ (isnan(x) + isnan(y)) - i = -ones(x.shape, dtype='i4') + m = ~(isnan(x) + isnan(y)) + i = -ones(x.shape, dtype="i4") i[m] = poly_indexs(x[m], y[m], self[xname], self[yname]) return i diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index af621423..5e22e797 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -522,9 +522,9 @@ def fit_circle(x, y): @njit(cache=True) -def fit_ellips(x, y): +def fit_ellipse(x, y): r""" - From a polygon, function will fit an ellips. + From a polygon, function will fit an ellipse. Must be call with local coordinates (in m, to get a radius in m). From 93709e4bd26908aef17898754246b55d50a00924 Mon Sep 17 00:00:00 2001 From: CoriPegliasco <66008544+CoriPegliasco@users.noreply.github.com> Date: Wed, 7 Apr 2021 13:27:19 +0200 Subject: [PATCH 150/249] documentation english corrections (#79) documentation : english corrections --- src/py_eddy_tracker/appli/network.py | 8 +- src/py_eddy_tracker/dataset/grid.py | 128 ++++++++-------- src/py_eddy_tracker/generic.py | 48 +++--- src/py_eddy_tracker/gui.py | 2 +- src/py_eddy_tracker/observations/groups.py | 28 ++-- src/py_eddy_tracker/observations/network.py | 144 ++++++++++-------- .../observations/observation.py | 58 +++---- src/py_eddy_tracker/observations/tracking.py | 36 ++--- 8 files changed, 232 insertions(+), 220 deletions(-) diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index 90450078..5c4cdcaf 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -37,7 +37,7 @@ def build_network(): def divide_network(): - parser = EddyParser("Separate path for a same group(network)") + parser = EddyParser("Separate path for a same group (network)") parser.add_argument("input", help="input network file") parser.add_argument("out", help="output file") parser.contour_intern_arg() @@ -66,7 +66,7 @@ def subset_network(): "--length", nargs=2, type=int, - help="Nb of day which must be cover by network, first minimum number of day and last maximum number of day," + help="Nb of days that must be covered by the network, first minimum number of day and last maximum number of day," "if value is negative, this bound won't be used", ) parser.add_argument( @@ -85,8 +85,8 @@ def subset_network(): "--period", nargs=2, type=int, - help="Start day and end day, if it's negative value we will add to day min and add to day max," - "if 0 it s not use", + help="Start day and end day, if it's a negative value we will add to day min and add to day max," + "if 0 it is not used", ) args = parser.parse_args() n = NetworkObservations.load_file(args.input, raw_data=True) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 28dc8330..14fe9ae3 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -153,7 +153,7 @@ def _circle_from_equal_area(vertice): # last coordinates == first lon0, lat0 = lons[1:].mean(), lats[1:].mean() c_x, c_y = coordinates_to_local(lons, lats, lon0, lat0) - # Some time, edge is only a dot of few coordinates + # Sometimes, edge is only a dot of few coordinates d_lon = lons.max() - lons.min() d_lat = lats.max() - lats.min() if d_lon < 1e-7 and d_lat < 1e-7: @@ -239,7 +239,7 @@ def nb_pixel(self): class GridDataset(object): """ - Class to have basic tool on NetCDF Grid + Class for basic tools on NetCDF Grid """ __slots__ = ( @@ -274,7 +274,7 @@ def __init__( :param str x_name: Name of longitude coordinates :param str y_name: Name of latitude coordinates :param bool,None centered: Allow to know how coordinates could be used with pixel - :param dict indexs: A dictionary which set indexs to use for non-coordinate dimensions + :param dict indexs: A dictionary that sets indexes to use for non-coordinate dimensions :param bool unset: Set to True to create an empty grid object without file """ self.dimensions = None @@ -294,7 +294,7 @@ def __init__( self.indexs = dict() if indexs is None else indexs if centered is None: logger.warning( - "We assume pixel position of grid is center for %s", filename + "We assume pixel position of grid is centered for %s", filename ) if not unset: self.load_general_features() @@ -314,7 +314,7 @@ def is_centered(self): return self.centered def load_general_features(self): - """Load attrs to be stored in object""" + """Load attrs to be stored in object""" logger.debug( "Load general feature from %(filename)s", dict(filename=self.filename) ) @@ -395,9 +395,9 @@ def load(self): @staticmethod def c_to_bounds(c): """ - Centred coordinates to bounds coordinates + Centered coordinates to bounds coordinates - :param array c: centred coordinates to translate + :param array c: centered coordinates to translate :return: bounds coordinates """ bounds = concatenate((c, (2 * c[-1] - c[-2],))) @@ -558,7 +558,7 @@ def grid_tiles(self, varname, slice_x, slice_y): return data def high_filter(self, grid_name, w_cut, **kwargs): - """Return the grid high-pass filtered, by substracting to the grid the low-pass filter (default: order=1) + """Return the high-pass filtered grid, by substracting to the initial grid the low-pass filtered grid (default: order=1) :param grid_name: the name of the grid :param int, w_cut: the half-power wavelength cutoff (km) @@ -567,7 +567,7 @@ def high_filter(self, grid_name, w_cut, **kwargs): self.vars[grid_name] -= result def low_filter(self, grid_name, w_cut, **kwargs): - """Return the grid low-pass filtered (default: order=1) + """Return the low-pass filtered grid (default: order=1) :param grid_name: the name of the grid :param int, w_cut: the half-power wavelength cutoff (km) @@ -607,11 +607,11 @@ def eddy_identification( :param str grid_height: Grid name of Sea Surface Height :param str uname: Grid name of u speed component :param str vname: Grid name of v speed component - :param datetime.datetime date: Date which will be stored in object to date data + :param datetime.datetime date: Date to be stored in object to date data :param float,int step: Height between two layers in m :param float,int shape_error: Maximal error allowed for outermost contour in % :param int sampling: Number of points to store contours and speed profile - :param str sampling_method: Method to resample 'uniform' or 'visvalingam' + :param str sampling_method: Method to resample, 'uniform' or 'visvalingam' :param (int,int),None pixel_limit: Min and max number of pixels inside the inner and the outermost contour to be considered as an eddy :param float,None precision: Truncate values at the defined precision in m @@ -625,8 +625,8 @@ def eddy_identification( .. minigallery:: py_eddy_tracker.GridDataset.eddy_identification """ if not isinstance(date, datetime): - raise Exception("Date argument be a datetime object") - # The inf limit must be in pixel and sup limit in surface + raise Exception("Date argument must be a datetime object") + # The inf limit must be in pixel and sup limit in surface if pixel_limit is None: pixel_limit = (4, 1000) @@ -651,10 +651,10 @@ def eddy_identification( # Get ssh grid data = self.grid(grid_height).astype("f8") - # In case of a reduce mask + # In case of a reduced mask if len(data.mask.shape) == 0 and not data.mask: data.mask = zeros(data.shape, dtype="bool") - # we remove noisy information + # we remove noisy data if precision is not None: data = (data / precision).round() * precision # Compute levels for ssh @@ -754,7 +754,7 @@ def eddy_identification( continue # Test the number of pixels within the outermost contour - # FIXME : Maybe limit max must be replace with a maximum of surface + # FIXME : Maybe limit max must be replaced with a maximum of surface if ( contour.nb_pixel < pixel_limit[0] or contour.nb_pixel > pixel_limit[1] @@ -794,7 +794,7 @@ def eddy_identification( centlon_e = x[centi, centj] centlat_e = y[centi, centj] - # centlat_e and centlon_e must be index of maximum, we will loose some inner contour if it's not + # centlat_e and centlon_e must be indexes of maximum, we will loose some inner contour if it's not ( max_average_speed, speed_contour, @@ -812,7 +812,7 @@ def eddy_identification( pixel_min=pixel_limit[0], ) - # FIXME : Instantiate new EddyObservation object (high cost need to be reviewed) + # FIXME : Instantiate new EddyObservation object (high cost, need to be reviewed) obs = EddiesObservations( size=1, track_extra_variables=track_extra_variables, @@ -928,7 +928,7 @@ def get_uavg( pixel_min=3, ): """ - Calculate geostrophic speed around successive contours + Compute geostrophic speed around successive contours Returns the average """ # Init max speed to search maximum @@ -1040,7 +1040,7 @@ def load(self): @property def bounds(self): - """Give bound""" + """Give bounds""" return self.x_c.min(), self.x_c.max(), self.y_c.min(), self.y_c.max() def bbox_indice(self, vertices): @@ -1072,7 +1072,7 @@ def compute_pixel_path(self, x0, y0, x1, y1): pass def init_pos_interpolator(self): - logger.debug("Create a KdTree could be long ...") + logger.debug("Create a KdTree, could be long ...") self.index_interp = cKDTree( create_vertice(self.x_c.reshape(-1), self.y_c.reshape(-1)) ) @@ -1202,10 +1202,10 @@ def bbox_indice(self, vertices): def get_pixels_in(self, contour): """ - Get indices of pixels in contour. + Get indexes of pixels in contour. - :param vertice,Path contour: Contour which enclosed some pixels - :return: Indices of grid in contour + :param vertice,Path contour: Contour that encloses some pixels + :return: Indexes of grid in contour :rtype: array[int],array[int] """ if isinstance(contour, BasePath): @@ -1238,7 +1238,7 @@ def ystep(self): return self._y_step def compute_pixel_path(self, x0, y0, x1, y1): - """Give a series of indexes which describe the path between to position""" + """Give a series of indexes describing the path between two positions""" return compute_pixel_path( x0, y0, @@ -1481,13 +1481,13 @@ def bessel_high_filter(self, grid_name, wave_length, order=1, lat_max=85, **kwar :param str grid_name: grid to filter, data will replace original one :param float wave_length: in km :param int order: order to use, if > 1 negative values of the cardinal sinus are present in kernel - :param float lat_max: absolute latitude above no filtering apply + :param float lat_max: absolute latitude, no filtering above :param dict kwargs: look at :py:meth:`RegularGridDataset.convolve_filter_with_dynamic_kernel` .. minigallery:: py_eddy_tracker.RegularGridDataset.bessel_high_filter """ logger.debug( - "Run filtering with wave of %(wave_length)s km and order of %(order)s ...", + "Run filtering with wavelength of %(wave_length)s km and order of %(order)s ...", dict(wave_length=wave_length, order=order), ) data_out = self.convolve_filter_with_dynamic_kernel( @@ -1813,7 +1813,7 @@ def add_uv(self, grid_height, uname="u", vname="v", stencil_halfwidth=4): ) def speed_coef_mean(self, contour): - """Some nan can be computed over contour if we are near border, + """Some nan can be computed over contour if we are near borders, something to explore """ return mean_on_regular_contour( @@ -1831,10 +1831,10 @@ def init_speed_coef(self, uname="u", vname="v"): def display(self, ax, name, factor=1, ref=None, **kwargs): """ - :param matplotlib.axes.Axes ax: matplotlib axes use to draw + :param matplotlib.axes.Axes ax: matplotlib axes used to draw :param str,array name: variable to display, could be an array :param float factor: multiply grid by - :param float,None ref: if define use like west bound + :param float,None ref: if defined, all coordinates are wrapped with ref as western boundary :param dict kwargs: look at :py:meth:`matplotlib.axes.Axes.pcolormesh` .. minigallery:: py_eddy_tracker.RegularGridDataset.display @@ -1853,10 +1853,10 @@ def display(self, ax, name, factor=1, ref=None, **kwargs): def contour(self, ax, name, factor=1, ref=None, **kwargs): """ - :param matplotlib.axes.Axes ax: matplotlib axes use to draw + :param matplotlib.axes.Axes ax: matplotlib axes used to draw :param str,array name: variable to display, could be an array :param float factor: multiply grid by - :param float,None ref: if define use like west bound + :param float,None ref: if defined, all coordinates are wrapped with ref as western boundary :param dict kwargs: look at :py:meth:`matplotlib.axes.Axes.contour` .. minigallery:: py_eddy_tracker.RegularGridDataset.contour @@ -1944,13 +1944,13 @@ def advect(self, x, y, u_name, v_name, nb_step=10, rk4=True, **kw): """ At each call it will update position in place with u & v field - It's a dummy advection which use only one layer of current + It's a dummy advection using only one layer of current :param array x: Longitude of obs to move :param array y: Latitude of obs to move :param str,array u_name: U field to advect obs :param str,array v_name: V field to advect obs - :param int nb_step: Number of iteration before to release data + :param int nb_step: Number of iterations before releasing data .. minigallery:: py_eddy_tracker.GridDataset.advect """ @@ -1967,13 +1967,13 @@ def filament( """ Produce filament with concatenation of advection - It's a dummy advection which use only one layer of current + It's a dummy advection using only one layer of current :param array x: Longitude of obs to move :param array y: Latitude of obs to move :param str,array u_name: U field to advect obs :param str,array v_name: V field to advect obs - :param int nb_step: Number of iteration before to release data + :param int nb_step: Number of iteration before releasing data :param int filament_size: Number of point by filament :return: x,y for a line @@ -2019,7 +2019,7 @@ def advect_rk4(x_g, y_g, u_g, v_g, m_g, x, y, m, nb_step): v00, v01, v10, v11 = 0.0, 0.0, 0.0, 0.0 # On each particle for i in prange(x.size): - # If particle are not valid => continue + # If particle is not valid => continue if m[i]: continue x_, y_ = x[i], y[i] @@ -2037,7 +2037,7 @@ def advect_rk4(x_g, y_g, u_g, v_g, m_g, x, y, m, nb_step): masked, u00, u01, u10, u11, v00, v01, v10, v11 = get_uv_quad( ii_, jj_, u_g, v_g, m_g, nb_x ) - # The 3 following could be in cache operation but this one must be test in any case + # The 3 following could be in cache operation but this one must be tested in any case if masked: x_, y_ = nan, nan m[i] = True @@ -2061,7 +2061,7 @@ def advect_rk4(x_g, y_g, u_g, v_g, m_g, x, y, m, nb_step): m[i] = True break u2, v2 = interp_uv(xd, yd, u00, u01, u10, u11, v00, v01, v10, v11) - # k3, slope at middle with update guess position + # k3, slope at middle with updated guess position x2, y2 = x_ + u2 * 0.5, y_ + v2 * 0.5 ii_, jj_, xd, yd = get_grid_indices( x_ref, y_ref, x_step, y_step, x2, y2, nb_x @@ -2079,7 +2079,7 @@ def advect_rk4(x_g, y_g, u_g, v_g, m_g, x, y, m, nb_step): m[i] = True break u3, v3 = interp_uv(xd, yd, u00, u01, u10, u11, v00, v01, v10, v11) - # k4, slope at end with update guess position + # k4, slope at end with updated guess position x3, y3 = x_ + u3, y_ + v3 ii_, jj_, xd, yd = get_grid_indices( x_ref, y_ref, x_step, y_step, x3, y3, nb_x @@ -2115,14 +2115,14 @@ def advect(x_g, y_g, u_g, v_g, m_g, x, y, m, nb_step): is_circular = abs(x_g[-1] % 360 - (x_g[0] - x_step) % 360) < 1e-5 nb_x_ = x_g.size nb_x = nb_x_ if is_circular else 0 - # Indices which should be never exist + # Indexes which should be never exist i0_old, j0_old = -100000, -100000 masked = False u00, u01, u10, u11 = 0.0, 0.0, 0.0, 0.0 v00, v01, v10, v11 = 0.0, 0.0, 0.0, 0.0 # On each particule for i in prange(x.size): - # If particule are not valid => continue + # If particule is not valid => continue if m[i]: continue # Iterate on whole steps @@ -2130,9 +2130,9 @@ def advect(x_g, y_g, u_g, v_g, m_g, x, y, m, nb_step): i0, j0, xd, yd = get_grid_indices( x_ref, y_ref, x_step, y_step, x[i], y[i], nb_x ) - # corner are the same need only a new xd and yd + # corners are the same, need only a new xd and yd if i0 != i0_old or j0 != j0_old: - # Need to be store only on change + # Need to be stored only on change i0_old, j0_old = i0, j0 if not is_circular and (i0 < 0 or i0 > nb_x_): masked = True @@ -2152,7 +2152,7 @@ def advect(x_g, y_g, u_g, v_g, m_g, x, y, m, nb_step): @njit(cache=True, fastmath=True) def compute_pixel_path(x0, y0, x1, y1, x_ori, y_ori, x_step, y_step, nb_x): - """Give a serie of indexes describing the path between two position""" + """Give a serie of indexes describing the path between two positions""" # index nx = x0.shape[0] i_x0 = empty(nx, dtype=numba_types.int_) @@ -2171,23 +2171,23 @@ def compute_pixel_path(x0, y0, x1, y1, x_ori, y_ori, x_step, y_step, nb_x): i_x1 = i_x0 + d_x # Delta index of y d_y = i_y1 - i_y0 - # max and abs sum doesn't work on array? + # max and abs sum do not work on array? d_max = empty(nx, dtype=numba_types.int32) nb_value = 0 for i in range(nx): d_max[i] = max(abs(d_x[i]), abs(d_y[i])) - # Compute number of pixel which we go trought + # Compute number of pixel we go trought nb_value += d_max[i] + 1 - # Create an empty array to store value of pixel across the travel + # Create an empty array to store value of pixel across the path i_g = empty(nb_value, dtype=numba_types.int32) j_g = empty(nb_value, dtype=numba_types.int32) # Index to determine the position in the global array ii = 0 - # Iteration on each travel + # Iteration on each path for i, delta in enumerate(d_max): - # If the travel don't cross multiple pixel + # If the path doesn't cross multiple pixels if delta == 0: i_g[ii : ii + delta + 1] = i_x0[i] j_g[ii : ii + delta + 1] = i_y0[i] @@ -2201,7 +2201,7 @@ def compute_pixel_path(x0, y0, x1, y1, x_ori, y_ori, x_step, y_step, nb_x): sup = -1 if d_x[i] < 0 else 1 i_g[ii : ii + delta + 1] = arange(i_x0[i], i_x1[i] + sup, sup) j_g[ii : ii + delta + 1] = i_y0[i] - # In case of multiple direction + # In case of multiple directions else: a = (i_x1[i] - i_x0[i]) / float(i_y1[i] - i_y0[i]) if abs(d_x[i]) >= abs(d_y[i]): @@ -2479,7 +2479,7 @@ def advect_t(x_g, y_g, u_g0, v_g0, m_g0, u_g1, v_g1, m_g1, x, y, m, weigths, hal is_circular = abs(x_g[-1] % 360 - (x_g[0] - x_step) % 360) < 1e-5 nb_x_ = x_g.size nb_x = nb_x_ if is_circular else 0 - # Indices which should be never exist + # Indexes that should never exist i0_old, j0_old = -100000, -100000 m0, m1 = False, False u000, u001, u010, u011 = 0.0, 0.0, 0.0, 0.0 @@ -2488,7 +2488,7 @@ def advect_t(x_g, y_g, u_g0, v_g0, m_g0, u_g1, v_g1, m_g1, x, y, m, weigths, hal v100, v101, v110, v111 = 0.0, 0.0, 0.0, 0.0 # On each particle for i in prange(x.size): - # If particle are not valid => continue + # If particle is not valid => continue if m[i]: continue # Iterate on whole steps @@ -2497,7 +2497,7 @@ def advect_t(x_g, y_g, u_g0, v_g0, m_g0, u_g1, v_g1, m_g1, x, y, m, weigths, hal x_ref, y_ref, x_step, y_step, x[i], y[i], nb_x ) if i0 != i0_old or j0 != j0_old: - # Need to be store only on change + # Need to be stored only on change i0_old, j0_old = i0, j0 if not is_circular and (i0 < 0 or i0 > nb_x_): m0, m1 = True, True @@ -2528,8 +2528,8 @@ def get_uv_quad(i0, j0, u, v, m, nb_x=0): """ Return u/v for (i0, j0), (i1, j0), (i0, j1), (i1, j1) - :param int i0: indices of longitude - :param int j0: indices of latitude + :param int i0: indexes of longitude + :param int j0: indexes of latitude :param array[float] u: current along x axis :param array[float] v: current along y axis :param array[bool] m: flag to know if position is valid @@ -2552,7 +2552,7 @@ def get_uv_quad(i0, j0, u, v, m, nb_x=0): @njit(cache=True, fastmath=True) def get_grid_indices(x0, y0, x_step, y_step, x, y, nb_x=0): """ - Return grid indices and weight + Return grid indexes and weight :param float x0: first longitude :param float y0: first latitude @@ -2562,7 +2562,7 @@ def get_grid_indices(x0, y0, x_step, y_step, x, y, nb_x=0): :param float y: latitude to interpolate :param int nb_x: If different of 0 we check if wrapping is needed - :return: indices and weight + :return: indexes and weight :rtype: int,int,float,float """ i, j = (x - x0) / x_step, (y - y0) / y_step @@ -2614,7 +2614,7 @@ def advect_t_rk4( v100, v101, v110, v111 = 0.0, 0.0, 0.0, 0.0 # On each particle for i in prange(x.size): - # If particle are not valid => continue + # If particle is not valid => continue if m[i]: continue x_, y_ = x[i], y[i] @@ -2635,7 +2635,7 @@ def advect_t_rk4( (m1, u100, u101, u110, u111, v100, v101, v110, v111) = get_uv_quad( ii_, jj_, u_g1, v_g1, m_g1, nb_x ) - # The 3 following could be in cache operation but this one must be test in any case + # The 3 following could be in cache operation but this one must be tested in any case if m0 or m1: x_, y_ = nan, nan m[i] = True @@ -2667,7 +2667,7 @@ def advect_t_rk4( u1_, v1_ = interp_uv(xd, yd, u100, u101, u110, u111, v100, v101, v110, v111) w_ = w - half_w u2, v2 = u0_ * w_ + u1_ * (1 - w_), v0_ * w_ + v1_ * (1 - w_) - # k3, slope at middle with update guess position + # k3, slope at middle with updated guess position x2, y2 = x_ + u2 * 0.5, y_ + v2 * 0.5 ii_, jj_, xd, yd = get_grid_indices( x_ref, y_ref, x_step, y_step, x2, y2, nb_x @@ -2690,7 +2690,7 @@ def advect_t_rk4( u0_, v0_ = interp_uv(xd, yd, u000, u001, u010, u011, v000, v001, v010, v011) u1_, v1_ = interp_uv(xd, yd, u100, u101, u110, u111, v100, v101, v110, v111) u3, v3 = u0_ * w_ + u1_ * (1 - w_), v0_ * w_ + v1_ * (1 - w_) - # k4, slope at end with update guess position + # k4, slope at end with updated guess position x3, y3 = x_ + u3, y_ + v3 ii_, jj_, xd, yd = get_grid_indices( x_ref, y_ref, x_step, y_step, x3, y3, nb_x @@ -2737,7 +2737,7 @@ def compute_stencil(x, y, h, m, earth_radius, vertical=False, stencil_halfwidth= :param array x: longitude coordinates :param array y: latitude coordinates :param array h: 2D array to derivate - :param array m: mask associate to h to know where are invalid data + :param array m: mask associated to h to know where are invalid data :param float earth_radius: Earth radius in m :param bool vertical: if True stencil will be vertical (along y) :param int stencil_halfwidth: from 1 to 4 to specify maximal kernel usable @@ -2831,7 +2831,7 @@ def compute_stencil(x, y, h, m, earth_radius, vertical=False, stencil_halfwidth= grad[i, j] = (h3 - h_3 + 9 * (h_2 - h2) + 45 * (h1 - h_1)) / 60 * d_ m_out[i, j] = False continue - # If all value of buffer are available + # If all values of buffer are available grad[i, j] = ( (3 * (h_4 - h4) + 32 * (h3 - h_3) + 168 * (h_2 - h2) + 672 * (h1 - h_1)) / 840 diff --git a/src/py_eddy_tracker/generic.py b/src/py_eddy_tracker/generic.py index 35c23817..6689c8e5 100644 --- a/src/py_eddy_tracker/generic.py +++ b/src/py_eddy_tracker/generic.py @@ -30,7 +30,7 @@ @njit(cache=True) def count_consecutive(mask): """ - Count consecutive event every False flag count restart + Count consecutive events every False flag count restart :param array[bool] mask: event to count :return: count when consecutive event @@ -50,7 +50,7 @@ def count_consecutive(mask): @njit(cache=True) def reverse_index(index, nb): """ - Compute a list of index, which are not in index. + Compute a list of indexes, which are not in index. :param array index: index of group which will be set to False :param array nb: Count for each group @@ -65,17 +65,17 @@ def reverse_index(index, nb): @njit(cache=True) def build_index(groups): - """We expected that variable is monotonous, and return index for each step change. + """We expect that variable is monotonous, and return index for each step change. - :param array groups: array which contain group to be separated - :return: (first_index of each group, last_index of each group, value to shift group) + :param array groups: array that contains groups to be separated + :return: (first_index of each group, last_index of each group, value to shift groups) :rtype: (array, array, int) - Examples -------- >>> build_index(array((1, 1, 3, 4, 4))) (array([0, 2, 2, 3]), array([2, 2, 3, 5]), 1) """ + i0, i1 = groups.min(), groups.max() amplitude = i1 - i0 + 1 # Index of first observation for each group @@ -83,7 +83,7 @@ def build_index(groups): for i, group in enumerate(groups[:-1]): # Get next value to compare next_group = groups[i + 1] - # if different we need to set index for all group between the 2 values + # if different we need to set index for all groups between the 2 values if group != next_group: first_index[group - i0 + 1 : next_group - i0 + 1] = i + 1 last_index = zeros(amplitude, dtype=numba_types.int_) @@ -95,21 +95,21 @@ def build_index(groups): @njit(cache=True) def hist_numba(x, bins): - """Call numba histogram to speed up.""" + """Call numba histogram to speed up.""" return histogram(x, bins) @njit(cache=True, fastmath=True, parallel=False) def distance_grid(lon0, lat0, lon1, lat1): """ - Get distance for every couple of point. + Get distance for every couple of points. :param array lon0: :param array lat0: :param array lon1: :param array lat1: - :return: nan value for far away point, and km for other + :return: nan value for far away points, and km for other :rtype: array """ nb_0 = lon0.shape[0] @@ -164,7 +164,7 @@ def cumsum_by_track(field, track): Cumsum by track. :param array field: data to sum - :pram array(int) track: id of track to separate data + :pram array(int) track: id of trajectories to separate data :return: cumsum with a reset at each start of track :rtype: array """ @@ -192,7 +192,7 @@ def interp2d_geo(x_g, y_g, z_g, m_g, x, y, nearest=False): :param array m_g: Boolean grid, True if value is masked :param array x: coordinate where interpolate z :param array y: coordinate where interpolate z - :param bool nearest: if true we will take nearest pixel + :param bool nearest: if True we will take nearest pixel :return: z interpolated :rtype: array """ @@ -256,17 +256,17 @@ def interp2d_bilinear(x_g, y_g, z_g, m_g, x, y): nb_x = x_g.shape[0] nb_y = y_g.shape[0] is_circular = abs(x_g[-1] % 360 - (x_g[0] - x_step) % 360) < 1e-5 - # Indices which should be never exist + # Indexes that should never exist i0_old, j0_old, masked = -100000000, -10000000, False z = empty(x.shape, dtype=z_g.dtype) for i in prange(x.size): x_ = (x[i] - x_ref) / x_step y_ = (y[i] - y_ref) / y_step i0 = int(floor(x_)) - # To keep original value if wrapping apply to compute xd + # To keep original values if wrapping applied to compute xd i0_ = i0 j0 = int(floor(y_)) - # corner are the same need only a new xd and yd + # corners are the same need only a new xd and yd if i0 != i0_old or j0 != j0_old: i1 = i0 + 1 j1 = j0 + 1 @@ -288,7 +288,7 @@ def interp2d_bilinear(x_g, y_g, z_g, m_g, x, y): z_g[i1, j1], ) masked = False - # Need to be store only on change + # Need to be stored only on change i0_old, j0_old = i0, j0 if masked: z[i] = nan @@ -359,17 +359,17 @@ def flatten_line_matrix(l_matrix): @njit(cache=True) def simplify(x, y, precision=0.1): """ - Will remove all middle/end point which are closer than precision. + Will remove all middle/end points closer than precision. :param array x: :param array y: - :param float precision: if two points have distance inferior to precision with remove next point + :param float precision: if two points have distance inferior to precision we remove next point :return: (x,y) :rtype: (array,array) """ precision2 = precision ** 2 nb = x.shape[0] - # will be True for value keep + # will be True for kept values mask = ones(nb, dtype=bool_) for j in range(0, nb): x_previous, y_previous = x[j], y[j] @@ -423,7 +423,7 @@ def split_line(x, y, i): :param y: array :param i: array of int at each i change, we cut x, y - :return: x and y separate by nan at each i jump + :return: x and y separated by nan at each i jump """ nb_jump = len(where(i[1:] - i[:-1] != 0)[0]) nb_value = x.shape[0] @@ -445,11 +445,11 @@ def split_line(x, y, i): @njit(cache=True) def wrap_longitude(x, y, ref, cut=False): """ - Will wrap contiguous longitude with reference as west bound. + Will wrap contiguous longitude with reference as western boundary. :param array x: :param array y: - :param float ref: longitude of reference, all the new value will be between ref and ref + 360 + :param float ref: longitude of reference, all the new values will be between ref and ref + 360 :param bool cut: if True line will be cut at the bounds :return: lon,lat :rtype: (array,array) @@ -557,7 +557,7 @@ def local_to_coordinates(x, y, lon0, lat0): @njit(cache=True, fastmath=True) def nearest_grd_indice(x, y, x0, y0, xstep, ystep): """ - Get nearest grid indice from a position. + Get nearest grid index from a position. :param x: longitude :param y: latitude @@ -575,7 +575,7 @@ def nearest_grd_indice(x, y, x0, y0, xstep, ystep): @njit(cache=True) def bbox_indice_regular(vertices, x0, y0, xstep, ystep, N, circular, x_size): """ - Get bbox indice of a contour in a regular grid. + Get bbox index of a contour in a regular grid. :param vertices: vertice of contour :param float x0: first grid longitude diff --git a/src/py_eddy_tracker/gui.py b/src/py_eddy_tracker/gui.py index 423ff306..a90a29a6 100644 --- a/src/py_eddy_tracker/gui.py +++ b/src/py_eddy_tracker/gui.py @@ -28,7 +28,7 @@ def __init__(self, *args, **kwargs): class GUIAxes(PlatCarreAxes): """ - Axes which will use full space available + Axes that uses full space available """ name = "full_axes" diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index 5a01d452..bd8ac81d 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -13,17 +13,17 @@ def get_missing_indices( array_time, array_track, dt=1, flag_untrack=True, indice_untrack=0 ): - """return indices where it misses values + """Return indexes where values are missing :param np.array(int) array_time : array of strictly increasing int representing time - :param np.array(int) array_track: N° track where observation belong - :param int,float dt: theorical timedelta between 2 observation + :param np.array(int) array_track: N° track where observations belong + :param int,float dt: theorical timedelta between 2 observations :param bool flag_untrack: if True, ignore observations where n°track equal `indice_untrack` - :param int indice_untrack: n° representing where observations are untrack + :param int indice_untrack: n° representing where observations are untracked ex : array_time = np.array([67, 68, 70, 71, 74, 75]) - array_track= np.array([ 1, 1, 1, 1, 1, 1]) + array_track= np.array([ 1, 1, 1, 1, 1, 1]) return : np.array([2, 4, 4]) """ @@ -72,11 +72,11 @@ def fix_next_previous_obs(self): @abstractmethod def get_missing_indices(self, dt): - "find indices where observations is missing" + "Find indexes where observations are missing" pass def filled_by_interpolation(self, mask): - """Filled selected values by interpolation + """Fill selected values by interpolation :param array(bool) mask: True if must be filled by interpolation @@ -102,20 +102,20 @@ def filled_by_interpolation(self, mask): ) def insert_virtual(self): - """insert virtual observation on segments where observations were not found""" + """insert virtual observations on segments where observations are missing""" dt_theorical = median(self.time[1:] - self.time[:-1]) indices = self.get_missing_indices(dt_theorical) logger.info("%d virtual observation will be added", indices.size) - # new observation size + # new observations size size_obs_corrected = self.time.size + indices.size - # correction of indices for new size + # correction of indexes for new size indices_corrected = indices + arange(indices.size) - # creating mask with indices + # creating mask with indexes mask = zeros(size_obs_corrected, dtype=bool) mask[indices_corrected] = 1 @@ -128,12 +128,12 @@ def insert_virtual(self): def keep_tracks_by_date(self, date, nb_days): """ - Find tracks which exist at date `date` and lasted at least `nb_days` after. + Find tracks that exist at date `date` and lasted at least `nb_days` after. :param int,float date: date where the tracks must exist - :param int,float nb_days: number of time where the tracks must exist. Can be negative + :param int,float nb_days: number of times the tracks must exist. Can be negative - If nb_days is negative, it search a tracks which exist at the date, + If nb_days is negative, it searches a track that exists at the date, but existed at least `nb_days` before the date """ diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 91849955..c21659f0 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -77,10 +77,10 @@ def load_contour(self, filename): @njit(cache=True) def fix_next_previous_obs(next_obs, previous_obs, flag_virtual): - """when an observation is virtual, we have to fix the previous and next obs + """When an observation is virtual, we have to fix the previous and next obs - :param np.array(int) next_obs : indice of next observation from network - :param np.array(int previous_obs: indice of previous observation from network + :param np.array(int) next_obs : index of next observation from network + :param np.array(int previous_obs: index of previous observation from network :param np.array(bool) flag_virtual: if observation is virtual or not """ @@ -88,8 +88,8 @@ def fix_next_previous_obs(next_obs, previous_obs, flag_virtual): if not flag_virtual[i_o]: continue - # if there is many virtual side by side, there is some values writted multiple times. - # but it should not be slow + # if there are several consecutive virtuals, some values are written multiple times. + # but it should not be slow next_obs[i_o - 1] = i_o next_obs[i_o] = i_o + 1 previous_obs[i_o] = i_o - 1 @@ -108,16 +108,18 @@ def __init__(self, *args, **kwargs): def find_segments_relative(self, obs, stopped=None, order=1): """ - find all relative segments within an event from an order. + Find all relative segments linked with merging/splitting events at a specific order. - :param int obs: indice of event after the event - :param int stopped: indice of event before the event + :param int obs: index of event after the event + :param int stopped: index of event before the event :param int order: order of relatives accepted - :return: all segments relatives + :return: all relative segments :rtype: EddiesObservations """ + # FIXME : double "event" in the description, please clarify (event = chosen obs?) + # extraction of network where the event is network_id = self.tracks[obs] nw = self.network(network_id) @@ -133,9 +135,9 @@ def find_segments_relative(self, obs, stopped=None, order=1): return nw.relatives([i_obs, i_stopped], order=order) def get_missing_indices(self, dt): - """find indices where observations is missing. + """Find indexes where observations are missing. - As network have all untrack observation in tracknumber `self.NOGROUP`, + As network have all untracked observation in tracknumber `self.NOGROUP`, we don't compute them :param int,float dt: theorical delta time between 2 observations @@ -195,8 +197,8 @@ def longer_than(self, nb_day_min=-1, nb_day_max=-1): """ Select network on time duration - :param int nb_day_min: Minimal number of day covered by one network, if negative -> not used - :param int nb_day_max: Maximal number of day covered by one network, if negative -> not used + :param int nb_day_min: Minimal number of days covered by one network, if negative -> not used + :param int nb_day_max: Maximal number of days covered by one network, if negative -> not used """ if nb_day_max < 0: nb_day_max = 1000000000000 @@ -227,7 +229,7 @@ def from_split_network(cls, group_dataset, indexs, **kwargs): continue network[field][:] = group_dataset[field][index_order] network.segment[:] = indexs["track"][index_order] - # n & p must be re-index + # n & p must be re-indexed n, p = indexs["next_obs"][index_order], indexs["previous_obs"][index_order] # we add 2 for -1 index return index -1 translate = -ones(index_order.max() + 2, dtype="i4") @@ -243,7 +245,7 @@ def infos(self, label=""): def correct_close_events(self, nb_days_max=20): """ - transform event where + Transform event where segment A split to B, then A merge into B to @@ -255,6 +257,12 @@ def correct_close_events(self, nb_days_max=20): :param float nb_days_max: maximum time to search for splitting-merging event """ + # FIXME : we want to change + # segment A splits from segment B, then x days after segment B merges with A + # to + # segment A splits from segment B then x days after segement A merges with B (B will be longer) + # comments are in the wrong way but the example works as wanted + _time = self.time # segment used to correct and track changes segment = self.segment_track_array.copy() @@ -265,7 +273,7 @@ def correct_close_events(self, nb_days_max=20): previous_obs, next_obs = self.previous_obs, self.next_obs - # record for every segments, the slice, indice of next obs & indice of previous obs + # record for every segment the slice, index of next obs & index of previous obs for i, seg, _ in self.iter_on(segment): if i.start == i.stop: continue @@ -284,12 +292,12 @@ def correct_close_events(self, nb_days_max=20): n_seg = segment[i_seg_n] - # if segment has splitting + # if segment is split if i_seg_n != -1: seg2_slice, i2_seg_p, i2_seg_n = segments_connexion[n_seg] p2_seg = segment[i2_seg_p] - # if it merge on the first in a certain time + # if it merges on the first in a certain time if (p2_seg == seg_corrected) and ( _time[i_seg_n] - _time[i2_seg_p] < nb_days_max ): @@ -309,11 +317,10 @@ def correct_close_events(self, nb_days_max=20): def sort(self, order=("track", "segment", "time")): """ - sort observations + Sort observations - :param tuple order: order or sorting. Passed to :func:`numpy.argsort` + :param tuple order: order or sorting. Given to :func:`numpy.argsort` """ - index_order = self.obs.argsort(order=order) for field in self.elements: self[field][:] = self[field][index_order] @@ -329,17 +336,17 @@ def obs_relative_order(self, i_obs): def find_link(self, i_observations, forward=True, backward=False): """ - find all observations where obs `i_observation` could be + Find all observations where obs `i_observation` could be in future or past. - if forward=True, search all observation where water + If forward=True, search all observations where water from obs "i_observation" could go - if backward=True, search all observation + If backward=True, search all observation where water from obs `i_observation` could come from :param int,iterable(int) i_observation: - indices of observation. Can be + indexes of observation. Can be int, or iterable of int. :param bool forward, backward: if forward, search observations after obs. @@ -425,7 +432,7 @@ def func_backward(seg, indice): def connexions(self, multi_network=False): """ - create dictionnary for each segments, gives the segments which interact with + Create dictionnary for each segment, gives the segments in interaction with """ if multi_network: segment = self.segment_track_array @@ -444,7 +451,7 @@ def add_seg(father, child): if i.start == i.stop: continue i_p, i_n = previous_obs[i.start], next_obs[i.stop - 1] - # segment of interaction + # segment in interaction p_seg, n_seg = segment[i_p], segment[i_n] # Where segment are called if i_p != -1: @@ -489,10 +496,12 @@ def relatives(self, obs, order=2): """ Extract the segments at a certain order from multiple observations. - :param iterable,int obs: indices of observation for relatives computation. Can be one observation (int) or collection of observations (iterable(int)) - :param int order: order of relatives wanted. 0 means only observations in obs, 1 means direct relatives, ... + :param iterable,int obs: indexes of observation for relatives computation. + Can be one observation (int) or collection of observations (iterable(int)) + :param int order: order of relatives wanted. + 0 means only observations in obs, 1 means direct relatives (1 interaction event), ... - :return: all segments relatives + :return: all segments' relatives :rtype: EddiesObservations """ segment = self.segment_track_array @@ -559,7 +568,7 @@ def close_network(self, other, nb_obs_min=10, **kwargs): :param self other: Atlas to compare :param int nb_obs_min: Minimal number of overlap for one trajectory :param dict kwargs: keyword arguments for match function - :return: return other atlas reduce to common track with self + :return: return other atlas reduced to common tracks with self .. warning:: It could be a costly operation for huge dataset @@ -662,7 +671,7 @@ def display_timeline( **kwargs, ): """ - Plot a timeline of a network. + Plot the timeline of a network. Must be called on only one network. :param matplotlib.axes.Axes ax: matplotlib axe used to draw @@ -723,7 +732,7 @@ def display_timeline( return mappables def event_timeline(self, ax, field=None, method=None, factor=1, colors_mode="roll"): - """mark events in plot""" + """Mark events in plot""" j = 0 events = dict(spliting=[], merging=[]) @@ -837,11 +846,11 @@ def map_segment(self, method, y, same=True, **kw): def map_network(self, method, y, same=True, return_dict=False, **kw): """ - transform data `y` with method `method` for each track. + Transform data `y` with method `method` for each track. - :param Callable method: method to apply on each tracks + :param Callable method: method to apply on each track :param np.array y: data where to apply method - :param bool same: if True, return array same size from y. else, return list with track edited + :param bool same: if True, return an array with the same size than y. Else, return a list with the edited tracks :param bool return_dict: if None, mean values are used :param float kw: to multiply field :return: array or dict of result from method for each network @@ -849,7 +858,7 @@ def map_network(self, method, y, same=True, return_dict=False, **kw): if same and return_dict: raise NotImplementedError( - "both condition 'same' and 'return_dict' should no be true" + "both conditions 'same' and 'return_dict' should no be true" ) if same: @@ -893,7 +902,7 @@ def scatter_timeline( **kwargs, ): """ - Must be call on only one network + Must be called on only one network """ self.only_one_network() y = (self.segment if yfield is None else self.parse_varname(yfield)) * yfactor @@ -913,7 +922,7 @@ def scatter_timeline( return mappables def event_map(self, ax, **kwargs): - """Add the merging and splitting events """ + """Add the merging and splitting events to a map""" j = 0 mappables = dict() symbol_kw = dict( @@ -957,12 +966,12 @@ def scatter( **kwargs, ): """ - This function will scatter the path of each network, with the merging and splitting events + This function scatters the path of each network, with the merging and splitting events :param matplotlib.axes.Axes ax: matplotlib axe used to draw :param str,array,None name: - variable used to fill the contour, if None all elements have the same color - :param float,None ref: if define use like west bound + variable used to fill the contours, if None all elements have the same color + :param float,None ref: if defined, ref is used as western boundary :param float factor: multiply value by :param list edgecolor_cycle: list of colors :param dict kwargs: look at :py:meth:`matplotlib.axes.Axes.scatter` @@ -1120,7 +1129,7 @@ def spliting_event(self, triplet=False, only_index=False): def dissociate_network(self): """ - Dissociate network with no known interaction (spliting/merging) + Dissociate networks with no known interaction (spliting/merging) """ tags = self.tag_segment(multi_network=True) @@ -1134,7 +1143,7 @@ def dissociate_network(self): self.obs.sort(order=("track", "segment", "time"), kind="mergesort") self._index_network = None - # n & p must be re-index + # n & p must be re-indexed n, p = self.next_obs, self.previous_obs # we add 2 for -1 index return index -1 nb_obs = len(self) @@ -1157,17 +1166,17 @@ def __tag_segment(cls, seg, tag, groups, connexions): """ Will set same temporary ID for each connected segment. - :param int seg: current ID of seg - :param ing tag: temporary ID to set for seg and its connexion - :param array[int] groups: array where tag will be stored - :param dict connexions: gives for one ID of seg all seg connected + :param int seg: current ID of segment + :param ing tag: temporary ID to set for segment and its connexion + :param array[int] groups: array where tag is stored + :param dict connexions: gives for one ID of segment all connected segments """ - # If seg are already used we stop recursivity + # If segments are already used we stop recursivity if groups[seg] != 0: return - # We set tag for this seg + # We set tag for this segment groups[seg] = tag - # Get all connexions of this seg + # Get all connexions of this segment segs = connexions.get(seg, None) if segs is not None: for seg in segs: @@ -1197,14 +1206,17 @@ def fully_connected(self): return self.tag_segment().shape[0] == 1 def remove_trash(self): + """ + Remove the lonely eddies (only 1 obs in segment, associated segment number is 0) + """ return self.extract_with_mask(self.track != 0) def plot(self, ax, ref=None, color_cycle=None, **kwargs): """ - This function will draw path of each trajectory + This function draws the path of each trajectory :param matplotlib.axes.Axes ax: ax to draw - :param float,int ref: if defined, all coordinates will be wrapped with ref like west boundary + :param float,int ref: if defined, all coordinates are wrapped with ref as western boundary :param dict kwargs: keyword arguments for Axes.plot :return: a list of matplotlib mappables """ @@ -1231,15 +1243,15 @@ def plot(self, ax, ref=None, color_cycle=None, **kwargs): def remove_dead_end(self, nobs=3, ndays=0, recursive=0, mask=None): """ - Remove short segment which didn't connect several segment + Remove short segments that don't connect several segments - :param int nobs: Minimal number of observation to keep segment - :param int ndays: Minimal number of days to keep segment - :param int recursive: Run method N times more - :param int mask: if one or more observation of segment are select by mask, the segment is keep + :param int nobs: Minimal number of observation to keep a segment + :param int ndays: Minimal number of days to keep a segment + :param int recursive: Run method N times more + :param int mask: if one or more observation of the segment are selected by mask, the segment is kept .. warning:: - It will remove short segment which splits than merges with same segment + It will remove short segment that splits from then merges with the same segment """ segments_keep = list() connexions = self.connexions(multi_network=True) @@ -1275,8 +1287,8 @@ def extract_with_period(self, period): """ Extract within a time period - :param (int,int) period: two dates to define the period, must be specify from 1/1/1950 - :return: Return all eddy tracks which are in bounds + :param (int,int) period: two dates to define the period, must be specified from 1/1/1950 + :return: Return all eddy trajectories in period :rtype: NetworkObservations .. minigallery:: py_eddy_tracker.NetworkObservations.extract_with_period @@ -1313,7 +1325,7 @@ def extract_with_mask(self, mask): logger.warning("Empty dataset will be created") else: logger.info( - f"{nb_obs} observations will be extract ({nb_obs / self.shape[0]:.3%})" + f"{nb_obs} observations will be extracted ({nb_obs / self.shape[0]:.3%})" ) for field in self.obs.dtype.descr: if field in ("next_obs", "previous_obs"): @@ -1403,7 +1415,7 @@ def group_translator(nb, duos): Create a translator with all duos :param int nb: size of translator - :param set((int, int)) duos: set of all group which must be join + :param set((int, int)) duos: set of all groups that must be joined Examples -------- @@ -1424,7 +1436,7 @@ def group_observations(self, **kwargs): for i, filename in enumerate(self.filenames): if display_iteration: print(f"{filename} compared to {self.window} next", end="\r") - # Load observations with function to buffered observations + # Load observations with function to buffer observations xi, yi = self.buffer.load_contour(filename) # Append number of observations by filename nb_obs.append(xi.shape[0]) @@ -1449,7 +1461,7 @@ def build_dataset(self, group, raw_data=True): model = TrackEddiesObservations.load_file(self.filenames[-1], raw_data=raw_data) eddies = TrackEddiesObservations.new_like(model, nb_obs) eddies.sign_type = model.sign_type - # Get new index to re-order observation by group + # Get new index to re-order observations by groups new_i = get_next_index(group) display_iteration = logger.getEffectiveLevel() == logging.INFO elements = eddies.elements @@ -1477,7 +1489,7 @@ def build_dataset(self, group, raw_data=True): @njit(cache=True) def get_next_index(gr): - """Return for each obs index the new position to join all group""" + """Return for each obs index the new position to join all groups""" nb_obs_gr = bincount(gr) i_gr = nb_obs_gr.cumsum() - nb_obs_gr new_index = empty(gr.shape, dtype=uint32) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 5ee45a28..d6f3c899 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -224,7 +224,7 @@ def __eq__(self, other): return array_equal(self.obs, other.obs) def get_color(self, i): - """Return colors like a cyclic list""" + """Return colors as a cyclic list""" return self.COLORS[i % self.NB_COLORS] @property @@ -260,7 +260,7 @@ def hist(self, varname, x, bins, percent=False, mean=False, nb=False): :param str,array varname: variable to use to compute stat :param str,array x: variable to use to know in which bins :param array bins: - :param bool percent: normalize by sum of all bins + :param bool percent: normalized by sum of all bins :param bool mean: compute mean by bins :param bool nb: only count by bins :return: value by bins @@ -279,7 +279,7 @@ def hist(self, varname, x, bins, percent=False, mean=False, nb=False): @staticmethod def box_display(value): - """Return value evenly spaced with few numbers""" + """Return values evenly spaced with few numbers""" return "".join([f"{v_:10.2f}" for v_ in value]) def field_table(self): @@ -437,7 +437,7 @@ def add_rotation_type(self): def circle_contour(self, only_virtual=False, factor=1): """ - Set contours as a circles from radius and center data. + Set contours as circles from radius and center data. .. minigallery:: py_eddy_tracker.EddiesObservations.circle_contour """ @@ -572,7 +572,7 @@ def iter_on(self, xname, bins=None): i = numba_digitize(x, bins) - 1 # Order by bins i_sort = i.argsort() - # If in reduce mode we will translate i_sort in full array index + # If in reduced mode we will translate i_sort in full array index i_sort_ = translate[i_sort] if test else i_sort # Bound for each bins in sorting view i0, i1, _ = build_index(i[i_sort]) @@ -613,7 +613,7 @@ def align_on(self, other, var_name="time", **kwargs): yield indexs_self, indexs_other, b0_self, b1_self def insert_observations(self, other, index): - """Insert other obs in self at the index.""" + """Insert other obs in self at the given index.""" if not self.coherence(other): raise Exception("Observations with no coherence") insert_size = len(other.obs) @@ -742,10 +742,10 @@ def load_from_zarr( """Load data from zarr. :param str,store filename: path or store to load data - :param bool raw_data: If true load data without apply scale_factor and add_offset - :param None,list(str) remove_vars: List of variable name which will be not loaded + :param bool raw_data: If true load data without scale_factor and add_offset + :param None,list(str) remove_vars: List of variable name that will be not loaded :param None,list(str) include_vars: If defined only this variable will be loaded - :param None,dict indexs: Indexs to laad only a slice of data + :param None,dict indexs: Indexes to load only a slice of data :param int buffer_size: Size of buffer used to load zarr data :param class_kwargs: argument to set up observations class :return: Obsevations selected @@ -764,7 +764,7 @@ def load_from_zarr( nb_obs = getattr(h_zarr, var_list[0]).shape[0] dims = list(cls.zarr_dimension(filename)) if len(dims) == 2 and nb_obs in dims: - # FIXME must be investigate, in zarr no dimensions name (or could be add in attr) + # FIXME must be investigated, in zarr no dimensions name (or could be add in attr) array_dim = dims[1] if nb_obs == dims[0] else dims[0] if indexs is not None and "obs" in indexs: sl = indexs["obs"] @@ -885,7 +885,7 @@ def load_from_netcdf( :param bool raw_data: If true load data without apply scale_factor and add_offset :param None,list(str) remove_vars: List of variable name which will be not loaded :param None,list(str) include_vars: If defined only this variable will be loaded - :param None,dict indexs: Indexs to laad only a slice of data + :param None,dict indexs: Indexes to load only a slice of data :param class_kwargs: argument to set up observations class :return: Obsevations selected :return type: class @@ -1054,7 +1054,7 @@ def propagate( self, previous_obs, current_obs, obs_to_extend, dead_track, nb_next, model ): """ - Filled virtual obs (C). + Fill virtual obs (C). :param previous_obs: previous obs from current (A) :param current_obs: previous obs from virtual (B) @@ -1166,7 +1166,7 @@ def re_reference_index(index, ref): :param array,int index: local index to re ref :param slice,array ref: reference could be a slice in this case we juste add start to index - or could be indexs and in this case we need to translate + or could be indexes and in this case we need to translate """ if isinstance(ref, slice): return index + ref.start @@ -1330,18 +1330,18 @@ def solve_conflict(cost): def solve_simultaneous(cost): """Write something (TODO)""" mask = ~cost.mask - # Count number of link by self obs and other obs + # Count number of links by self obs and other obs self_links, other_links = sum_row_column(mask) max_links = max(self_links.max(), other_links.max()) if max_links > 5: logger.warning("One observation have %d links", max_links) - # If some obs have multiple link, we keep only one link by eddy + # If some obs have multiple links, we keep only one link by eddy eddies_separation = 1 < self_links eddies_merge = 1 < other_links test = eddies_separation.any() or eddies_merge.any() if test: - # We extract matrix which contains concflict + # We extract matrix that contains conflict obs_linking_to_self = mask[eddies_separation].any(axis=0) obs_linking_to_other = mask[:, eddies_merge].any(axis=1) i_self_keep = where(obs_linking_to_other + eddies_separation)[0] @@ -1364,13 +1364,13 @@ def solve_simultaneous(cost): security_increment = 0 while False in cost_reduce.mask: if security_increment > max_iteration: - # Maybe check if the size decrease if not rise an exception + # Maybe check if the size decreases if not rise an exception # x_i, y_i = where(-cost_reduce.mask) raise Exception("To many iteration: %d" % security_increment) security_increment += 1 i_min_value = cost_reduce.argmin() i, j = floor(i_min_value / shape[1]).astype(int), i_min_value % shape[1] - # Set to False all link + # Set to False all links mask[i_self_keep[i]] = False mask[:, i_other_keep[j]] = False cost_reduce.mask[i] = True @@ -1384,19 +1384,19 @@ def solve_simultaneous(cost): @staticmethod def solve_first(cost, multiple_link=False): mask = ~cost.mask - # Count number of link by self obs and other obs + # Count number of links by self obs and other obs self_links = mask.sum(axis=1) other_links = mask.sum(axis=0) max_links = max(self_links.max(), other_links.max()) if max_links > 5: logger.warning("One observation have %d links", max_links) - # If some obs have multiple link, we keep only one link by eddy + # If some obs have multiple links, we keep only one link by eddy eddies_separation = 1 < self_links eddies_merge = 1 < other_links test = eddies_separation.any() or eddies_merge.any() if test: - # We extract matrix which contains concflict + # We extract matrix that contains conflict obs_linking_to_self = mask[eddies_separation].any(axis=0) obs_linking_to_other = mask[:, eddies_merge].any(axis=1) i_self_keep = where(obs_linking_to_other + eddies_separation)[0] @@ -1700,7 +1700,7 @@ def set_global_attr_netcdf(self, h_nc): def mask_from_polygons(self, polygons): """ - Return mask for all observation in one of polygons list + Return mask for all observations in one of polygons list :param list((array,array)) polygons: list of x/y array which be used to identify observations """ @@ -1724,7 +1724,7 @@ def extract_with_area(self, area, **kwargs): :param dict area: 4 coordinates in a dictionary to specify bounding box (lower left corner and upper right corner) :param dict kwargs: look at :py:meth:`extract_with_mask` - :return: Return all eddy tracks which are in bounds + :return: Return all eddy trajetories in bounds :rtype: EddiesObservations .. code-block:: python @@ -1745,7 +1745,7 @@ def time_sub_sample(self, t0, time_step): """ Time sub sampling - :param int,float t0: reference time which will be keep + :param int,float t0: reference time that will be keep :param int,float time_step: keep every observation spaced by time_step """ mask = (self.time - t0) % time_step == 0 @@ -1779,7 +1779,7 @@ def scatter(self, ax, name=None, ref=None, factor=1, **kwargs): :param matplotlib.axes.Axes ax: matplotlib axe used to draw :param str,array,None name: variable used to fill the contour, if None all elements have the same color - :param float,None ref: if define use like west bound + :param float,None ref: if defined, all coordinates are wrapped with ref as western boundary :param float factor: multiply value by :param dict kwargs: look at :py:meth:`matplotlib.axes.Axes.scatter` :return: scatter mappable @@ -1811,7 +1811,7 @@ def filled( """ :param matplotlib.axes.Axes ax: matplotlib axe used to draw :param str,array,None varname: variable used to fill the contours, or an array of same size than obs - :param float,None ref: if define use like west bound? + :param float,None ref: if defined, all coordinates are wrapped with ref as western boundary :param bool intern: if True draw speed contours instead of effective contours :param str cmap: matplotlib colormap name :param int,None lut: Number of colors in the colormap @@ -2271,7 +2271,7 @@ def period(self): @property def nb_days(self): - """Return period days cover by dataset + """Return period in days covered by the dataset :return: Number of days :rtype: int @@ -2282,7 +2282,7 @@ def nb_days(self): @njit(cache=True) def grid_count_(grid, i, j): """ - Add one to each index + Add 1 to each index """ for i_, j_ in zip(i, j): grid[i_, j_] += 1 @@ -2305,7 +2305,7 @@ def grid_count_pixel_in( y_c, ): """ - Count how many time a pixel is used. + Count how many times a pixel is used. :param array grid: :param array x: x for all contour diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index 5902462d..ad1847d2 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -77,7 +77,7 @@ def iter_track(self): yield self.index(slice(i0, i0 + nb)) def get_missing_indices(self, dt): - """find indices where observations is missing. + """Find indexes where observations are missing. :param int,float dt: theorical delta time between 2 observations """ @@ -90,7 +90,7 @@ def get_missing_indices(self, dt): ) def fix_next_previous_obs(self): - """function used after 'insert_virtual', to correct next_obs and + """Function used after 'insert_virtual', to correct next_obs and previous obs. """ @@ -99,7 +99,7 @@ def fix_next_previous_obs(self): @property def nb_tracks(self): """ - Will count and send number of track + Count and return number of track """ if self.__nb_track is None: if len(self) == 0: @@ -150,7 +150,7 @@ def add_distance(self): def distance_to_next(self): """ - :return: array of distance in m, 0 when next obs if from another track + :return: array of distance in m, 0 when next obs is from another track :rtype: array """ d = distance( @@ -166,7 +166,7 @@ def distance_to_next(self): return d_ def normalize_longitude(self): - """Normalize all longitude + """Normalize all longitudes Normalize longitude field and in the same range : - longitude_max @@ -217,7 +217,7 @@ def elements(self): return list(set(elements)) def set_global_attr_netcdf(self, h_nc): - """Set global attr""" + """Set global attributes""" h_nc.title = "Cyclonic" if self.sign_type == -1 else "Anticyclonic" h_nc.Metadata_Conventions = "Unidata Dataset Discovery v1.0" h_nc.comment = "Surface product; mesoscale eddies" @@ -239,9 +239,9 @@ def extract_with_period(self, period, **kwargs): """ Extract within a time period - :param (int,int) period: two dates to define the period, must be specify from 1/1/1950 + :param (int,int) period: two dates to define the period, must be specified from 1/1/1950 :param dict kwargs: look at :py:meth:`extract_with_mask` - :return: Return all eddy tracks which are in bounds + :return: Return all eddy tracks in period :rtype: TrackEddiesObservations .. minigallery:: py_eddy_tracker.TrackEddiesObservations.extract_with_period @@ -264,9 +264,9 @@ def get_azimuth(self, equatorward=False): """ Return azimuth for each track. - Azimuth is computed with first and last observation + Azimuth is computed with first and last observations - :param bool equatorward: If True, Poleward are positive and equatorward negative + :param bool equatorward: If True, Poleward is positive and Equatorward negative :rtype: array """ i0, nb = self.index_from_track, self.nb_obs_by_track @@ -427,7 +427,7 @@ def extract_with_length(self, bounds): track_mask = self.nb_obs_by_track >= b0 else: logger.warning("No valid value for bounds") - raise Exception("One bounds must be positiv") + raise Exception("One bound must be positive") return self.extract_with_mask(track_mask.repeat(self.nb_obs_by_track)) def empty_dataset(self): @@ -474,7 +474,7 @@ def extract_with_mask( :param bool full_path: extract the full trajectory if only one part is selected :param bool remove_incomplete: delete trajectory if not fully selected :param bool compress_id: resample trajectory number to use a smaller range - :param bool reject_virtual: if only virtual are selected, the trajectory is removed + :param bool reject_virtual: if only virtuals are selected, the trajectory is removed :return: same object with the selected observations :rtype: self.__class__ """ @@ -525,10 +525,10 @@ def shape_polygon(self, intern=False): def display_shape(self, ax, ref=None, intern=False, **kwargs): """ - This function will draw the shape of each trajectory + This function draws the shape of each trajectory :param matplotlib.axes.Axes ax: ax to draw - :param float,int ref: if defined all coordinates will be wrapped with ref like west boundary + :param float,int ref: if defined, all coordinates are wrapped with ref as western boundary :param bool intern: If True use speed contour instead of effective contour :param dict kwargs: keyword arguments for Axes.plot :return: matplotlib mappable @@ -557,7 +557,7 @@ def close_tracks(self, other, nb_obs_min=10, **kwargs): :param self other: Atlas to compare :param int nb_obs_min: Minimal number of overlap for one trajectory :param dict kwargs: keyword arguments for match function - :return: return other atlas reduce to common track with self + :return: return other atlas reduced to common trajectories with self .. warning:: It could be a costly operation for huge dataset @@ -585,7 +585,7 @@ def plot(self, ax, ref=None, **kwargs): This function will draw path of each trajectory :param matplotlib.axes.Axes ax: ax to draw - :param float,int ref: if defined, all coordinates will be wrapped with ref like west boundary + :param float,int ref: if defined, all coordinates are wrapped with ref as western boundary :param dict kwargs: keyword arguments for Axes.plot :return: matplotlib mappable """ @@ -791,10 +791,10 @@ def track_loess_filter(half_window, x, y, track): """ Apply a loess filter on y field - :param int,float window: parameter of smoother + :param int,float half_window: parameter of smoother :param array_like x: must be growing for each track but could be irregular :param array_like y: field to smooth - :param array_like track: field which allow to separate path + :param array_like track: field that allows to separate path :return: Array smoothed :rtype: array_like From 08d7dc80d5b9ce4f7c1845846215d8e5bdc48fb5 Mon Sep 17 00:00:00 2001 From: CoriPegliasco <66008544+CoriPegliasco@users.noreply.github.com> Date: Wed, 7 Apr 2021 22:18:26 +0200 Subject: [PATCH 151/249] indexes -> indices (#80) --- src/py_eddy_tracker/dataset/grid.py | 2 +- src/py_eddy_tracker/generic.py | 2 +- src/py_eddy_tracker/observations/network.py | 8 ++++---- src/py_eddy_tracker/observations/observation.py | 6 +++--- src/py_eddy_tracker/observations/tracking.py | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 14fe9ae3..11227475 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -1275,7 +1275,7 @@ def get_step_in_km(self, lat, wave_length): min_wave_length = max(step_x_km, step_y_km) * 2 if wave_length < min_wave_length: logger.error( - "Wave_length too short for resolution, must be > %d km", + "wave_length too short for resolution, must be > %d km", ceil(min_wave_length), ) raise Exception() diff --git a/src/py_eddy_tracker/generic.py b/src/py_eddy_tracker/generic.py index 6689c8e5..530c2136 100644 --- a/src/py_eddy_tracker/generic.py +++ b/src/py_eddy_tracker/generic.py @@ -50,7 +50,7 @@ def count_consecutive(mask): @njit(cache=True) def reverse_index(index, nb): """ - Compute a list of indexes, which are not in index. + Compute a list of indices, which are not in index. :param array index: index of group which will be set to False :param array nb: Count for each group diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index c21659f0..a2fe8a0d 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -135,7 +135,7 @@ def find_segments_relative(self, obs, stopped=None, order=1): return nw.relatives([i_obs, i_stopped], order=order) def get_missing_indices(self, dt): - """Find indexes where observations are missing. + """Find indices where observations are missing. As network have all untracked observation in tracknumber `self.NOGROUP`, we don't compute them @@ -215,7 +215,7 @@ def longer_than(self, nb_day_min=-1, nb_day_max=-1): @classmethod def from_split_network(cls, group_dataset, indexs, **kwargs): """ - Build a NetworkObservations object with Group dataset and indexes + Build a NetworkObservations object with Group dataset and indices :param TrackEddiesObservations group_dataset: Group dataset :param indexs: result from split_network @@ -346,7 +346,7 @@ def find_link(self, i_observations, forward=True, backward=False): where water from obs `i_observation` could come from :param int,iterable(int) i_observation: - indexes of observation. Can be + indices of observation. Can be int, or iterable of int. :param bool forward, backward: if forward, search observations after obs. @@ -496,7 +496,7 @@ def relatives(self, obs, order=2): """ Extract the segments at a certain order from multiple observations. - :param iterable,int obs: indexes of observation for relatives computation. + :param iterable,int obs: indices of observation for relatives computation. Can be one observation (int) or collection of observations (iterable(int)) :param int order: order of relatives wanted. 0 means only observations in obs, 1 means direct relatives (1 interaction event), ... diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index d6f3c899..173f6c56 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -594,7 +594,7 @@ def iter_on(self, xname, bins=None): def align_on(self, other, var_name="time", **kwargs): """ - Align the time indexes of two datasets. + Align the time indices of two datasets. .. minigallery:: py_eddy_tracker.EddiesObservations.align_on """ @@ -1135,7 +1135,7 @@ def match( :param bool intern: if True, speed contour is used (default = effective contour) :param float cmin: 0 < cmin < 1, return only couples with score >= cmin :param dict kwargs: look at :py:meth:`vertice_overlap` - :return: return the indexes of the eddies in self coupled with eddies in + :return: return the indices of the eddies in self coupled with eddies in other and their associated score :rtype: (array(int), array(int), array(float)) @@ -1166,7 +1166,7 @@ def re_reference_index(index, ref): :param array,int index: local index to re ref :param slice,array ref: reference could be a slice in this case we juste add start to index - or could be indexes and in this case we need to translate + or could be indices and in this case we need to translate """ if isinstance(ref, slice): return index + ref.start diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index ad1847d2..b632270c 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -77,7 +77,7 @@ def iter_track(self): yield self.index(slice(i0, i0 + nb)) def get_missing_indices(self, dt): - """Find indexes where observations are missing. + """Find indices where observations are missing. :param int,float dt: theorical delta time between 2 observations """ @@ -618,7 +618,7 @@ def split_network(self, intern=True, **kwargs): # Initialisation # To store the id of the segments, the backward and forward cost associations ids["track"], ids["previous_cost"], ids["next_cost"] = 0, 0, 0 - # To store the indexes of the backward and forward observations associated + # To store the indices of the backward and forward observations associated ids["previous_obs"], ids["next_obs"] = -1, -1 # At the end, ids["previous_obs"] == -1 means the start of a non-split segment # and ids["next_obs"] == -1 means the end of a non-merged segment From 4bf81470ee01603612f6f23063ac498a7d1877fe Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Mon, 12 Apr 2021 23:31:40 +0200 Subject: [PATCH 152/249] Add informations about speed profile in an example --- examples/01_general_things/pet_storage.py | 57 +++++++++++++++++-- .../01_general_things/pet_storage.ipynb | 57 ++++++++++++++++++- 2 files changed, 105 insertions(+), 9 deletions(-) diff --git a/examples/01_general_things/pet_storage.py b/examples/01_general_things/pet_storage.py index 9f0ec61e..ccd01f1c 100644 --- a/examples/01_general_things/pet_storage.py +++ b/examples/01_general_things/pet_storage.py @@ -16,8 +16,10 @@ """ import py_eddy_tracker_sample +from matplotlib import pyplot as plt +from numpy import arange, outer -from py_eddy_tracker.data import get_demo_path, get_remote_demo_sample +from py_eddy_tracker.data import get_demo_path from py_eddy_tracker.observations.network import NetworkObservations from py_eddy_tracker.observations.observation import EddiesObservations, Table from py_eddy_tracker.observations.tracking import TrackEddiesObservations @@ -58,6 +60,53 @@ # --------------- # All contours are stored on the same number of points, and are resampled if needed with an algorithm to be stored as objects +# %% +# Speed profile storage +# --------------------- +# Speed profile is an interpolation of speed mean along each contour. +# For each contour included in eddy, we compute mean of speed along the contour, +# and after we interpolate speed mean array on a fixed size array. +# +# Several field are available to understand "uavg_profile" : +# 0. - num_contours : Number of contour in eddies, must be equal to amplitude divide by isoline step +# 1. - height_inner_contour : height of inner contour used +# 2. - height_max_speed_contour : height of max speed contour used +# 3. - height_external_contour : height of outter contour used +# +# Last value of "uavg_profile" is for inner contour and first value for outter contour. + +# Observations selection of "uavg_profile" with high number of contour(Eddy with high amplitude) +e = eddies_collections.extract_with_mask(eddies_collections.num_contours > 15) + +# %% + +# Raw display of profiles with more than 15 contours +ax = plt.subplot(111) +_ = ax.plot(e.uavg_profile.T, lw=0.5) + +# %% + +# Profile from inner to outter +ax = plt.subplot(111) +ax.plot(e.uavg_profile[:, ::-1].T, lw=0.5) +_ = ax.set_xlabel("From inner to outter contour"), ax.set_ylabel("Speed (m/s)") + +# %% + +# If we normalize indice of contour to set speed contour to 1 and inner contour to 0 +ax = plt.subplot(111) +h_in = e.height_inner_contour +h_s = e.height_max_speed_contour +h_e = e.height_external_contour +r = (h_e - h_in) / (h_s - h_in) +nb_pt = e.uavg_profile.shape[1] +# Create an x array for each profile +x = outer(arange(nb_pt) / nb_pt, r) + +ax.plot(x, e.uavg_profile[:, ::-1].T, lw=0.5) +_ = ax.set_xlabel("From inner to outter contour"), ax.set_ylabel("Speed (m/s)") + + # %% # Trajectories # ------------ @@ -86,11 +135,7 @@ # - next_obs : Index of the next observation in the full dataset, if -1 there are no next observation (the segment ends) # - previous_cost : Result of the cost function (1 is a good association, 0 is bad) with previous observation # - next_cost : Result of the cost function (1 is a good association, 0 is bad) with next observation -eddies_network = NetworkObservations.load_file( - get_remote_demo_sample( - "eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc" - ) -) +eddies_network = NetworkObservations.load_file(get_demo_path("network_med.nc")) eddies_network.field_table() # %% diff --git a/notebooks/python_module/01_general_things/pet_storage.ipynb b/notebooks/python_module/01_general_things/pet_storage.ipynb index 4b4a6630..250591ee 100644 --- a/notebooks/python_module/01_general_things/pet_storage.ipynb +++ b/notebooks/python_module/01_general_things/pet_storage.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import py_eddy_tracker_sample\n\nfrom py_eddy_tracker.data import get_demo_path, get_remote_demo_sample\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.observation import EddiesObservations, Table\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations" + "import py_eddy_tracker_sample\nfrom matplotlib import pyplot as plt\nfrom numpy import arange, outer\n\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.observations.observation import EddiesObservations, Table\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations" ] }, { @@ -108,6 +108,57 @@ "## Contour storage\nAll contours are stored on the same number of points, and are resampled if needed with an algorithm to be stored as objects\n\n" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Speed profile storage\nSpeed profile is an interpolation of speed mean along each contour.\nFor each contour included in eddy, we compute mean of speed along the contour,\nand after we interpolate speed mean array on a fixed size array.\n\nSeveral field are available to understand \"uavg_profile\" :\n 0. - num_contours : Number of contour in eddies, must be equal to amplitude divide by isoline step\n 1. - height_inner_contour : height of inner contour used\n 2. - height_max_speed_contour : height of max speed contour used\n 3. - height_external_contour : height of outter contour used\n\nLast value of \"uavg_profile\" is for inner contour and first value for outter contour.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Observations selection of \"uavg_profile\" with high number of contour(Eddy with high amplitude)\ne = eddies_collections.extract_with_mask(eddies_collections.num_contours > 15)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Raw display of profiles with more than 15 contours\nax = plt.subplot(111)\n_ = ax.plot(e.uavg_profile.T, lw=0.5)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Profile from inner to outter\nax = plt.subplot(111)\nax.plot(e.uavg_profile[:, ::-1].T, lw=0.5)\n_ = ax.set_xlabel(\"From inner to outter contour\"), ax.set_ylabel(\"Speed (m/s)\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# If we normalize indice of contour to set speed contour to 1 and inner contour to 0\nax = plt.subplot(111)\nh_in = e.height_inner_contour\nh_s = e.height_max_speed_contour\nh_e = e.height_external_contour\nr = (h_e - h_in) / (h_s - h_in)\nnb_pt = e.uavg_profile.shape[1]\n# Create an x array for each profile\nx = outer(arange(nb_pt) / nb_pt, r)\n\nax.plot(x, e.uavg_profile[:, ::-1].T, lw=0.5)\n_ = ax.set_xlabel(\"From inner to outter contour\"), ax.set_ylabel(\"Speed (m/s)\")" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -141,7 +192,7 @@ }, "outputs": [], "source": [ - "eddies_network = NetworkObservations.load_file(\n get_remote_demo_sample(\n \"eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc\"\n )\n)\neddies_network.field_table()" + "eddies_network = NetworkObservations.load_file(get_demo_path(\"network_med.nc\"))\neddies_network.field_table()" ] }, { @@ -179,7 +230,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.9.2" } }, "nbformat": 4, From b91c786b0045018115ff6596e05bf7329ccc3cf4 Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Wed, 28 Apr 2021 21:55:48 +0200 Subject: [PATCH 153/249] Add information about method --- examples/07_cube_manipulation/pet_fsle_med.py | 4 + examples/16_network/pet_ioannou_2017_case.py | 10 +- .../01_general_things/pet_storage.ipynb | 2 +- .../07_cube_manipulation/pet_fsle_med.ipynb | 4 +- .../14_generic_tools/pet_fit_contour.ipynb | 12 +-- .../16_network/pet_follow_particle.ipynb | 6 +- .../16_network/pet_ioannou_2017_case.ipynb | 92 ++++++++++++++++++- 7 files changed, 112 insertions(+), 18 deletions(-) diff --git a/examples/07_cube_manipulation/pet_fsle_med.py b/examples/07_cube_manipulation/pet_fsle_med.py index 46c5fdcc..b4a51265 100644 --- a/examples/07_cube_manipulation/pet_fsle_med.py +++ b/examples/07_cube_manipulation/pet_fsle_med.py @@ -26,6 +26,10 @@ # %% # ADT in med # ---------- +# :py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_cube` method is +# made for data stores in time cube, you could use also +# :py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_list` method to +# load data-cube from multiple file. c = GridCollection.from_netcdf_cube( get_demo_path("dt_med_allsat_phy_l4_2005T2.nc"), "longitude", diff --git a/examples/16_network/pet_ioannou_2017_case.py b/examples/16_network/pet_ioannou_2017_case.py index 2bffbb31..768f0c88 100644 --- a/examples/16_network/pet_ioannou_2017_case.py +++ b/examples/16_network/pet_ioannou_2017_case.py @@ -21,7 +21,7 @@ from py_eddy_tracker.gui import GUI_AXES from py_eddy_tracker.observations.network import NetworkObservations -from py_eddy_tracker.generic import coordinates_to_local, local_to_coordinates +from py_eddy_tracker.generic import coordinates_to_local from py_eddy_tracker.poly import fit_ellipse # %% @@ -217,22 +217,22 @@ def update_axes(ax, mappable=None): # Theta ax = timeline_axes() m = close_to_i3.scatter_timeline(ax, theta_, vmin=-pi / 2, vmax=pi / 2, cmap="hsv") -cb = update_axes(ax, m["scatter"]) +_ = update_axes(ax, m["scatter"]) # %% # a ax = timeline_axes() m = close_to_i3.scatter_timeline(ax, a_ * 1e-3, vmin=0, vmax=80, cmap="Spectral_r") -cb = update_axes(ax, m["scatter"]) +_ = update_axes(ax, m["scatter"]) # %% # b ax = timeline_axes() m = close_to_i3.scatter_timeline(ax, b_ * 1e-3, vmin=0, vmax=80, cmap="Spectral_r") -cb = update_axes(ax, m["scatter"]) +_ = update_axes(ax, m["scatter"]) # %% # a/b ax = timeline_axes() m = close_to_i3.scatter_timeline(ax, a_ / b_, vmin=1, vmax=2, cmap="Spectral_r") -cb = update_axes(ax, m["scatter"]) +_ = update_axes(ax, m["scatter"]) diff --git a/notebooks/python_module/01_general_things/pet_storage.ipynb b/notebooks/python_module/01_general_things/pet_storage.ipynb index 250591ee..fa8d1a55 100644 --- a/notebooks/python_module/01_general_things/pet_storage.ipynb +++ b/notebooks/python_module/01_general_things/pet_storage.ipynb @@ -40,7 +40,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Eddies files (zarr or netcdf) could be loaded with ```load_file``` method:\n\n" + "Eddies files (zarr or netcdf) can be loaded with ```load_file``` method:\n\n" ] }, { diff --git a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb index e821df6d..4f2e1467 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb @@ -33,7 +33,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## ADT in med\n\n" + "## ADT in med\n:py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_cube` method is\nmade for data stores in time cube, you could use also \n:py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_list` method to\nload data-cube from multiple file.\n\n" ] }, { @@ -172,7 +172,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.9.2" } }, "nbformat": 4, diff --git a/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb b/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb index 4cec72b2..5306fa0c 100644 --- a/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb +++ b/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "from matplotlib import pyplot as plt\nfrom numpy import cos, linspace, radians, sin\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.generic import coordinates_to_local, local_to_coordinates\nfrom py_eddy_tracker.observations.observation import EddiesObservations\nfrom py_eddy_tracker.poly import fit_circle_, fit_ellips" + "from matplotlib import pyplot as plt\nfrom numpy import cos, linspace, radians, sin\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.generic import coordinates_to_local, local_to_coordinates\nfrom py_eddy_tracker.observations.observation import EddiesObservations\nfrom py_eddy_tracker.poly import fit_circle_, fit_ellipse" ] }, { @@ -51,7 +51,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Function to draw circle or ellips from parameter\n\n" + "Function to draw circle or ellipse from parameter\n\n" ] }, { @@ -62,14 +62,14 @@ }, "outputs": [], "source": [ - "def build_circle(x0, y0, r):\n angle = radians(linspace(0, 360, 50))\n x_norm, y_norm = cos(angle), sin(angle)\n return local_to_coordinates(x_norm * r, y_norm * r, x0, y0)\n\n\ndef build_ellips(x0, y0, a, b, theta):\n angle = radians(linspace(0, 360, 50))\n x = a * cos(theta) * cos(angle) - b * sin(theta) * sin(angle)\n y = a * sin(theta) * cos(angle) + b * cos(theta) * sin(angle)\n return local_to_coordinates(x, y, x0, y0)" + "def build_circle(x0, y0, r):\n angle = radians(linspace(0, 360, 50))\n x_norm, y_norm = cos(angle), sin(angle)\n return local_to_coordinates(x_norm * r, y_norm * r, x0, y0)\n\n\ndef build_ellipse(x0, y0, a, b, theta):\n angle = radians(linspace(0, 360, 50))\n x = a * cos(theta) * cos(angle) - b * sin(theta) * sin(angle)\n y = a * sin(theta) * cos(angle) + b * cos(theta) * sin(angle)\n return local_to_coordinates(x, y, x0, y0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Plot fitted circle or ellips on stored contour\n\n" + "Plot fitted circle or ellipse on stored contour\n\n" ] }, { @@ -80,7 +80,7 @@ }, "outputs": [], "source": [ - "xs, ys = a.contour_lon_s, a.contour_lat_s\n\nfig = plt.figure(figsize=(15, 15))\n\nj = 1\nfor i in range(0, 800, 30):\n x, y = xs[i], ys[i]\n x0_, y0_ = x.mean(), y.mean()\n x_, y_ = coordinates_to_local(x, y, x0_, y0_)\n ax = fig.add_subplot(4, 4, j)\n ax.grid(), ax.set_aspect(\"equal\")\n ax.plot(x, y, label=\"store\", color=\"black\")\n x0, y0, a, b, theta = fit_ellips(x_, y_)\n x0, y0 = local_to_coordinates(x0, y0, x0_, y0_)\n ax.plot(*build_ellips(x0, y0, a, b, theta), label=\"ellips\", color=\"green\")\n x0, y0, radius, shape_error = fit_circle_(x_, y_)\n x0, y0 = local_to_coordinates(x0, y0, x0_, y0_)\n ax.plot(*build_circle(x0, y0, radius), label=\"circle\", color=\"red\", lw=0.5)\n if j == 16:\n break\n j += 1" + "xs, ys = a.contour_lon_s, a.contour_lat_s\n\nfig = plt.figure(figsize=(15, 15))\n\nj = 1\nfor i in range(0, 800, 30):\n x, y = xs[i], ys[i]\n x0_, y0_ = x.mean(), y.mean()\n x_, y_ = coordinates_to_local(x, y, x0_, y0_)\n ax = fig.add_subplot(4, 4, j)\n ax.grid(), ax.set_aspect(\"equal\")\n ax.plot(x, y, label=\"store\", color=\"black\")\n x0, y0, a, b, theta = fit_ellipse(x_, y_)\n x0, y0 = local_to_coordinates(x0, y0, x0_, y0_)\n ax.plot(*build_ellipse(x0, y0, a, b, theta), label=\"ellipse\", color=\"green\")\n x0, y0, radius, shape_error = fit_circle_(x_, y_)\n x0, y0 = local_to_coordinates(x0, y0, x0_, y0_)\n ax.plot(*build_circle(x0, y0, radius), label=\"circle\", color=\"red\", lw=0.5)\n if j == 16:\n break\n j += 1" ] } ], @@ -100,7 +100,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.9.2" } }, "nbformat": 4, diff --git a/notebooks/python_module/16_network/pet_follow_particle.ipynb b/notebooks/python_module/16_network/pet_follow_particle.ipynb index 30c85a49..28d0048d 100644 --- a/notebooks/python_module/16_network/pet_follow_particle.ipynb +++ b/notebooks/python_module/16_network/pet_follow_particle.ipynb @@ -37,7 +37,7 @@ }, "outputs": [], "source": [ - "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is used to create thumbnail which are not used but consumes same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" ] }, { @@ -120,7 +120,7 @@ }, "outputs": [], "source": [ - "def advect(x, y, c, t0, delta_t):\n \"\"\"\n Advect particle from t0 to t0 + delta_t, with data cube.\n \"\"\"\n kw = dict(nb_step=6, time_step=86400 / 6)\n if delta_t < 0:\n kw[\"backward\"] = True\n delta_t = -delta_t\n p = c.advect(x, y, \"u\", \"v\", t_init=t0, **kw)\n for _ in range(delta_t):\n t, x, y = p.__next__()\n return t, x, y\n\n\ndef particle_candidate(x, y, c, eddies, t_start, i_target, pct, **kwargs):\n # Obs from initial time\n m_start = eddies.time == t_start\n e = eddies.extract_with_mask(m_start)\n # to be able to get global index\n translate_start = where(m_start)[0]\n # Identify particle in eddies(only in core)\n i_start = e.contains(x, y, intern=True)\n m = i_start != -1\n x, y, i_start = x[m], y[m], i_start[m]\n # Advect\n t_end, x, y = advect(x, y, c, t_start, **kwargs)\n # eddies at last date\n m_end = eddies.time == t_end / 86400\n e_end = eddies.extract_with_mask(m_end)\n # to be able to get global index\n translate_end = where(m_end)[0]\n # Id eddies for each alive particle(in core and extern)\n i_end = e_end.contains(x, y)\n # compute matrix and filled target array\n get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct)\n\n\n@njit(cache=True)\ndef get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct):\n nb_start, nb_end = translate_start.size, translate_end.size\n # Matrix which will store count for every couple\n count = zeros((nb_start, nb_end), dtype=nb_types.int32)\n # Number of particle in each origin observation\n ref = zeros(nb_start, dtype=nb_types.int32)\n # For each particle\n for i in range(i_start.size):\n i_end_ = i_end[i]\n i_start_ = i_start[i]\n if i_end_ != -1:\n count[i_start_, i_end_] += 1\n ref[i_start_] += 1\n for i in range(nb_start):\n for j in range(nb_end):\n pct_ = count[i, j]\n # If there are particle from i to j\n if pct_ != 0:\n # Get percent\n pct_ = pct_ / ref[i] * 100.0\n # Get indices in full dataset\n i_, j_ = translate_start[i], translate_end[j]\n pct_0 = pct[i_, 0]\n if pct_ > pct_0:\n pct[i_, 1] = pct_0\n pct[i_, 0] = pct_\n i_target[i_, 1] = i_target[i_, 0]\n i_target[i_, 0] = j_\n elif pct_ > pct[i_, 1]:\n pct[i_, 1] = pct_\n i_target[i_, 1] = j_\n return i_target, pct" + "def advect(x, y, c, t0, delta_t):\n \"\"\"\n Advect particle from t0 to t0 + delta_t, with data cube.\n \"\"\"\n kw = dict(nb_step=6, time_step=86400 / 6)\n if delta_t < 0:\n kw[\"backward\"] = True\n delta_t = -delta_t\n p = c.advect(x, y, \"u\", \"v\", t_init=t0, **kw)\n for _ in range(delta_t):\n t, x, y = p.__next__()\n return t, x, y\n\n\ndef particle_candidate(x, y, c, eddies, t_start, i_target, pct, **kwargs):\n # Obs from initial time\n m_start = eddies.time == t_start\n e = eddies.extract_with_mask(m_start)\n # to be able to get global index\n translate_start = where(m_start)[0]\n # Identify particle in eddies (only in core)\n i_start = e.contains(x, y, intern=True)\n m = i_start != -1\n x, y, i_start = x[m], y[m], i_start[m]\n # Advect\n t_end, x, y = advect(x, y, c, t_start, **kwargs)\n # eddies at last date\n m_end = eddies.time == t_end / 86400\n e_end = eddies.extract_with_mask(m_end)\n # to be able to get global index\n translate_end = where(m_end)[0]\n # Id eddies for each alive particle (in core and extern)\n i_end = e_end.contains(x, y)\n # compute matrix and fill target array\n get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct)\n\n\n@njit(cache=True)\ndef get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct):\n nb_start, nb_end = translate_start.size, translate_end.size\n # Matrix which will store count for every couple\n count = zeros((nb_start, nb_end), dtype=nb_types.int32)\n # Number of particles in each origin observation\n ref = zeros(nb_start, dtype=nb_types.int32)\n # For each particle\n for i in range(i_start.size):\n i_end_ = i_end[i]\n i_start_ = i_start[i]\n if i_end_ != -1:\n count[i_start_, i_end_] += 1\n ref[i_start_] += 1\n for i in range(nb_start):\n for j in range(nb_end):\n pct_ = count[i, j]\n # If there are particles from i to j\n if pct_ != 0:\n # Get percent\n pct_ = pct_ / ref[i] * 100.0\n # Get indices in full dataset\n i_, j_ = translate_start[i], translate_end[j]\n pct_0 = pct[i_, 0]\n if pct_ > pct_0:\n pct[i_, 1] = pct_0\n pct[i_, 0] = pct_\n i_target[i_, 1] = i_target[i_, 0]\n i_target[i_, 0] = j_\n elif pct_ > pct[i_, 1]:\n pct[i_, 1] = pct_\n i_target[i_, 1] = j_\n return i_target, pct" ] }, { @@ -169,7 +169,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.9.2" } }, "nbformat": 4, diff --git a/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb b/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb index 743b753f..9b3d40d6 100644 --- a/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb +++ b/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import re\nfrom datetime import datetime, timedelta\n\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.ticker import FuncFormatter\nfrom numpy import arange, where\n\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.gui import GUI_AXES\nfrom py_eddy_tracker.observations.network import NetworkObservations" + "import re\nfrom datetime import datetime, timedelta\n\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.ticker import FuncFormatter\nfrom numpy import arange, where, array, pi\n\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.gui import GUI_AXES\nfrom py_eddy_tracker.observations.network import NetworkObservations\n\nfrom py_eddy_tracker.generic import coordinates_to_local\nfrom py_eddy_tracker.poly import fit_ellipse" ] }, { @@ -230,6 +230,96 @@ "source": [ "ax = timeline_axes()\nm = close_to_i3.scatter_timeline(ax, \"shape_error_e\", vmin=14, vmax=70, **kw)\ncb = update_axes(ax, m[\"scatter\"])\ncb.set_label(\"Effective shape error\")" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Rotation angle\nFor each obs, fit an ellipse to the contour, with theta the angle from the x-axis,\na the semi ax in x direction and b the semi ax in y dimension\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "theta_ = list()\na_ = list()\nb_ = list()\nfor obs in close_to_i3:\n x, y = obs[\"contour_lon_s\"], obs[\"contour_lat_s\"]\n x0_, y0_ = x.mean(), y.mean()\n x_, y_ = coordinates_to_local(x, y, x0_, y0_)\n x0, y0, a, b, theta = fit_ellipse(x_, y_)\n theta_.append(theta)\n a_.append(a)\n b_.append(b)\na_ = array(a_)\nb_ = array(b_)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Theta\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = timeline_axes()\nm = close_to_i3.scatter_timeline(ax, theta_, vmin=-pi / 2, vmax=pi / 2, cmap=\"hsv\")\n_ = update_axes(ax, m[\"scatter\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "a\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = timeline_axes()\nm = close_to_i3.scatter_timeline(ax, a_ * 1e-3, vmin=0, vmax=80, cmap=\"Spectral_r\")\n_ = update_axes(ax, m[\"scatter\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "b\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = timeline_axes()\nm = close_to_i3.scatter_timeline(ax, b_ * 1e-3, vmin=0, vmax=80, cmap=\"Spectral_r\")\n_ = update_axes(ax, m[\"scatter\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "a/b\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = timeline_axes()\nm = close_to_i3.scatter_timeline(ax, a_ / b_, vmin=1, vmax=2, cmap=\"Spectral_r\")\n_ = update_axes(ax, m[\"scatter\"])" + ] } ], "metadata": { From 81eaf1574cf0170527367cd21e887b3789b236c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Wed, 12 May 2021 14:30:40 +0200 Subject: [PATCH 154/249] add coherence function, and minor corrections add shift_files to GridCollection change heigth to height correct FIXME in function documentation correct tests --- src/py_eddy_tracker/dataset/grid.py | 10 + src/py_eddy_tracker/observations/network.py | 311 +++++++++++++++++- .../observations/observation.py | 2 +- 3 files changed, 308 insertions(+), 15 deletions(-) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 11227475..ea602cfa 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -2264,6 +2264,16 @@ def from_netcdf_list(cls, filenames, t, x_name, y_name, indexs=None, heigth=None new.datasets.append((t, d)) return new + def shift_files(self, t, filename, x_name, y_name, indexs, heigth): + """Add next file to the list and remove the oldest""" + + self.datasets = self.datasets[1:] + + d = RegularGridDataset(filename, x_name, y_name, indexs=indexs) + if heigth is not None: + d.add_uv(heigth) + self.datasets.append((t, d)) + def interp(self, grid_name, t, lons, lats, method="bilinear"): """ Compute z over lons, lats diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 58f926a1..5fe0727a 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -6,6 +6,7 @@ from glob import glob from numba import njit +from numba import types as nb_types from numpy import ( arange, array, @@ -20,13 +21,16 @@ unique, where, zeros, + meshgrid, ) +import zarr from ..generic import build_index, wrap_longitude -from ..poly import bbox_intersection, vertice_overlap +from ..poly import bbox_intersection, vertice_overlap, group_obs from .groups import GroupEddiesObservations, get_missing_indices from .observation import EddiesObservations from .tracking import TrackEddiesObservations, track_loess_filter, track_median_filter +from ..dataset.grid import GridCollection logger = logging.getLogger("pet") @@ -97,6 +101,109 @@ def fix_next_previous_obs(next_obs, previous_obs, flag_virtual): previous_obs[i_o + 1] = i_o +def advect(x, y, c, t0, delta_t): + """ + Advect particle from t0 to t0 + delta_t, with data cube. + + :param np.array(float) x: longitude of particles + :param np.array(float) y: latitude of particles + :param `~py_eddy_tracker.dataset.grid.GridCollection` c: GridCollection with speed for particles + :param int t0: julian day of advection start + :param int delta_t: number of days to advect + """ + + kw = dict(nb_step=6, time_step=86400 / 6) + if delta_t < 0: + kw["backward"] = True + delta_t = -delta_t + p = c.advect(x, y, "u", "v", t_init=t0, **kw) + for _ in range(delta_t): + t, x, y = p.__next__() + return t, x, y + + +def particle_candidate(x, y, c, eddies, t_start, i_target, pct, **kwargs): + """Select particles within eddies, advect them, return target observation and associated percentages + + :param np.array(float) x: longitude of particles + :param np.array(float) y: latitude of particles + :param `~py_eddy_tracker.dataset.grid.GridCollection` c: GridCollection with speed for particles + :param NetworkObservations eddies: NetworkObservations considered + :param int t_start: julian day of the advection + :param np.array(int) i_target: corresponding obs where particles are advected + :param np.array(int) pct: corresponding percentage of avected particles + :params dict kwargs: dict of params given to `advect` + """ + + # Obs from initial time + m_start = eddies.time == t_start + + e = eddies.extract_with_mask(m_start) + # to be able to get global index + translate_start = where(m_start)[0] + # Identify particle in eddies (only in core) + i_start = e.contains(x, y, intern=True) + m = i_start != -1 + + x, y, i_start = x[m], y[m], i_start[m] + # Advect + t_end, x, y = advect(x, y, c, t_start, **kwargs) + # eddies at last date + m_end = eddies.time == t_end / 86400 + e_end = eddies.extract_with_mask(m_end) + # to be able to get global index + translate_end = where(m_end)[0] + # Id eddies for each alive particle (in core and extern) + i_end = e_end.contains(x, y) + # compute matrix and fill target array + get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct) + + +@njit(cache=True) +def get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct): + """Compute target observation and associated percentages + + :param np.array(int) i_start: indices of associated contours at starting advection day + :param np.array(int) i_end: indices of associated contours after advection + :param np.array(int) translate_start: corresponding global indices at starting advection day + :param np.array(int) translate_end: corresponding global indices after advection + :param np.array(int) i_target: corresponding obs where particles are advected + :param np.array(int) pct: corresponding percentage of avected particles + """ + + nb_start, nb_end = translate_start.size, translate_end.size + # Matrix which will store count for every couple + count = zeros((nb_start, nb_end), dtype=nb_types.int32) + # Number of particles in each origin observation + ref = zeros(nb_start, dtype=nb_types.int32) + # For each particle + for i in range(i_start.size): + i_end_ = i_end[i] + i_start_ = i_start[i] + if i_end_ != -1: + count[i_start_, i_end_] += 1 + ref[i_start_] += 1 + for i in range(nb_start): + for j in range(nb_end): + pct_ = count[i, j] + # If there are particles from i to j + if pct_ != 0: + # Get percent + pct_ = pct_ / ref[i] * 100.0 + # Get indices in full dataset + i_, j_ = translate_start[i], translate_end[j] + pct_0 = pct[i_, 0] + if pct_ > pct_0: + pct[i_, 1] = pct_0 + pct[i_, 0] = pct_ + i_target[i_, 1] = i_target[i_, 0] + i_target[i_, 0] = j_ + elif pct_ > pct[i_, 1]: + pct[i_, 1] = pct_ + i_target[i_, 1] = j_ + return i_target, pct + + class NetworkObservations(GroupEddiesObservations): __slots__ = ("_index_network",) @@ -109,17 +216,16 @@ def __init__(self, *args, **kwargs): def find_segments_relative(self, obs, stopped=None, order=1): """ - Find all relative segments linked with merging/splitting events at a specific order. + Find all relative segments from obs linked with merging/splitting events at a specific order. - :param int obs: index of event after the event - :param int stopped: index of event before the event + :param int obs: index of observation after the event + :param int stopped: index of observation before the event :param int order: order of relatives accepted :return: all relative segments :rtype: EddiesObservations """ - # FIXME : double "event" in the description, please clarify (event = chosen obs?) # extraction of network where the event is network_id = self.tracks[obs] @@ -247,23 +353,17 @@ def infos(self, label=""): def correct_close_events(self, nb_days_max=20): """ Transform event where - segment A split to B, then A merge into B + segment A splits from segment B, then x days after segment B merges with A to - segment A split to B, then B merge to A + segment A splits from segment B then x days after segment A merges with B (B will be longer) - these events are filtered with `nb_days_max`, which the event have to take place in less than `nb_days_max` + These events have to last less than `nb_days_max` to be changed. :param float nb_days_max: maximum time to search for splitting-merging event """ - # FIXME : we want to change - # segment A splits from segment B, then x days after segment B merges with A - # to - # segment A splits from segment B then x days after segement A merges with B (B will be longer) - # comments are in the wrong way but the example works as wanted - _time = self.time # segment used to correct and track changes segment = self.segment_track_array.copy() @@ -1340,6 +1440,189 @@ def extract_with_mask(self, mask): new.previous_obs[:] = translate[p] return new + def analysis_coherence( + self, + date_function, + uv_params, + advection_mode="both", + dt_advect=14, + step_mesh=1.0 / 50, + output_name=None, + dissociate_network=False, + correct_close_events=0, + remove_dead_end=0, + ): + + """Global function to analyse segments coherence, with network preprocessing""" + + if dissociate_network: + self.dissociate_network() + + if correct_close_events > 0: + self.correct_close_events(nb_days_max=correct_close_events) + + if remove_dead_end > 0: + network_clean = self.remove_dead_end(nobs=0, ndays=remove_dead_end) + else: + network_clean = self + + res = network_clean.segment_coherence( + date_function=date_function, + uv_params=uv_params, + advection_mode=advection_mode, + output_name=output_name, + dt_advect=dt_advect, + step_mesh=step_mesh, + ) + + return network_clean, res + + def segment_coherence( + self, + date_function, + uv_params, + advection_mode="both", + dt_advect=14, + step_mesh=1.0 / 50, + output_name=None, + ): + + """ + Percentage of particules and their targets after forward or/and backward advection from a specific eddy. + + :param callable date_function: python function, takes as param `int` (julian day) and return + data filename associated to the date + ex: + def date2file(julian_day): + date = datetime.timedelta(days=julian_day) + datetime.datetime(1950, 1, 1) + + return f"/tmp/dt_global_allsat_phy_l4_{date.strftime('%Y%m%d')}.nc" + + :param dict uv_params: dict of parameters used by + :py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_list` + :param str advection_mode: "backward", "forward" or "both" + :param int dt_advect: days for advection + :param float step_mesh: step for particule mesh in degrees + :param str output_name: if not None, name of file saved in zarr. Else, data will not be saved + """ + + if advection_mode in ["both", "forward"]: + itf_final = -ones((self.obs.size, 2), dtype="i4") + ptf_final = zeros((self.obs.size, 2), dtype="i1") + + if advection_mode in ["both", "backward"]: + itb_final = -ones((self.obs.size, 2), dtype="i4") + ptb_final = zeros((self.obs.size, 2), dtype="i1") + + for slice_track, b0, _ in self.iter_on(self.track): + if b0 == 0: + continue + + sub_networks = self.network(b0) + + # find extremum to create a mesh of particles + lon = sub_networks.contour_lon_s + lonMin = lon.min() - 0.1 + lonMax = lon.max() + 0.1 + + lat = sub_networks.contour_lat_s + latMin = lat.min() - 0.1 + latMax = lat.max() + 0.1 + + x0, y0 = meshgrid( + arange(lonMin, lonMax, step_mesh), arange(latMin, latMax, step_mesh) + ) + x0, y0 = x0.reshape(-1), y0.reshape(-1) + _, i = group_obs(x0, y0, 1, 360) + x0, y0 = x0[i], y0[i] + + t_start, t_end = sub_networks.period + shape = (sub_networks.obs.size, 2) + + if advection_mode in ["both", "forward"]: + + # first dates to load. + dates = arange(t_start - 1, t_start + dt_advect + 2) + # files associated with dates + first_files = [date_function(x) for x in dates] + + c = GridCollection.from_netcdf_list(first_files, dates, **uv_params) + + i_target_f = -ones(shape, dtype="i4") + pct_target_f = zeros(shape, dtype="i1") + + for _t in range(t_start, t_end - dt_advect + 1): + t_shift = _t + dt_advect + 2 + + # add next date to GridCollection and delete last date + c.shift_files(t_shift, date_function(int(t_shift)), **uv_params) + particle_candidate( + x0, + y0, + c, + sub_networks, + _t, + i_target_f, + pct_target_f, + delta_t=dt_advect, + ) + + itf_final[slice_track] = i_target_f + ptf_final[slice_track] = pct_target_f + + if advection_mode in ["both", "backward"]: + + # first dates to load. + dates = arange(t_start - 1, t_start + dt_advect + 2) + # files associated with dates + first_files = [date_function(x) for x in dates] + + c = GridCollection.from_netcdf_list(first_files, dates, **uv_params) + + i_target_b = -ones(shape, dtype="i4") + pct_target_b = zeros(shape, dtype="i1") + + for _t in range(t_start + dt_advect + 1, t_end + 1): + t_shift = _t + 1 + + # add next date to GridCollection and delete last date + c.shift_files(t_shift, date_function(int(t_shift)), **uv_params) + particle_candidate( + x0, + y0, + c, + self, + _t, + i_target_b, + pct_target_b, + delta_t=-dt_advect, + ) + + itb_final[slice_track] = i_target_b + ptb_final[slice_track] = pct_target_b + + if output_name is not None: + zg = zarr.open(output_name, "w") + + # zarr compression parameters + params_seg = dict() + params_pct = dict() + + res = [] + if advection_mode in ["forward", "both"]: + res = res + [itf_final, ptf_final] + if output_name is not None: + zg.array("i_target_forward", itf_final, **params_seg) + zg.array("pct_target_forward", ptf_final, **params_pct) + + if advection_mode in ["backward", "both"]: + res = res + [itb_final, ptb_final] + if output_name is not None: + zg.array("i_target_backward", itb_final, **params_seg) + zg.array("pct_target_backward", ptb_final, **params_pct) + + return res + class Network: __slots__ = ( diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 173f6c56..3d91ad42 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -2045,7 +2045,7 @@ def is_convex(self, intern=False): def contains(self, x, y, intern=False): """ - Return index of contour which contain (x,y) + Return index of contour containing (x,y) :param array x: longitude :param array y: latitude From 13177b657e3f37b88e734a0aac1c8254d5547fca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Wed, 12 May 2021 14:31:29 +0200 Subject: [PATCH 155/249] correction bug problem when indices is on edge of datas --- src/py_eddy_tracker/dataset/grid.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index ea602cfa..6337e136 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -2551,6 +2551,11 @@ def get_uv_quad(i0, j0, u, v, m, nb_x=0): i1, j1 = i0 + 1, j0 + 1 if nb_x != 0: i1 %= nb_x + i_max, j_max = m.shape + + # if i1 >= i_max or j1 >= j_max: + # return True, nan, nan, nan, nan, nan, nan, nan, nan + if m[i0, j0] or m[i0, j1] or m[i1, j0] or m[i1, j1]: return True, nan, nan, nan, nan, nan, nan, nan, nan # Extract value for u and v From b5c31016a085bd47c7e281cdff5c2a7e0bc7e392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Fri, 14 May 2021 13:48:26 +0200 Subject: [PATCH 156/249] corrections for merge request move particle_candidate in groups add default values for shift_files mistake with get_uv_quad correction still in comments change delta_t to n_days correct whitespaces --- examples/16_network/pet_follow_particle.py | 80 +----------- src/py_eddy_tracker/dataset/grid.py | 6 +- src/py_eddy_tracker/observations/groups.py | 109 ++++++++++++++++- src/py_eddy_tracker/observations/network.py | 128 +++----------------- 4 files changed, 127 insertions(+), 196 deletions(-) diff --git a/examples/16_network/pet_follow_particle.py b/examples/16_network/pet_follow_particle.py index 0c4be55d..b4dfe343 100644 --- a/examples/16_network/pet_follow_particle.py +++ b/examples/16_network/pet_follow_particle.py @@ -17,6 +17,7 @@ from py_eddy_tracker.data import get_demo_path from py_eddy_tracker.dataset.grid import GridCollection from py_eddy_tracker.observations.network import NetworkObservations +from py_eddy_tracker.observations.groups import particle_candidate from py_eddy_tracker.poly import group_obs start_logger().setLevel("ERROR") @@ -124,81 +125,6 @@ def update(frame): ani = VideoAnimation(a.fig, update, frames=arange(20200, 20269, step), interval=200) -# %% -# In which observations are the particle -# -------------------------------------- -def advect(x, y, c, t0, delta_t): - """ - Advect particle from t0 to t0 + delta_t, with data cube. - """ - kw = dict(nb_step=6, time_step=86400 / 6) - if delta_t < 0: - kw["backward"] = True - delta_t = -delta_t - p = c.advect(x, y, "u", "v", t_init=t0, **kw) - for _ in range(delta_t): - t, x, y = p.__next__() - return t, x, y - - -def particle_candidate(x, y, c, eddies, t_start, i_target, pct, **kwargs): - # Obs from initial time - m_start = eddies.time == t_start - e = eddies.extract_with_mask(m_start) - # to be able to get global index - translate_start = where(m_start)[0] - # Identify particle in eddies (only in core) - i_start = e.contains(x, y, intern=True) - m = i_start != -1 - x, y, i_start = x[m], y[m], i_start[m] - # Advect - t_end, x, y = advect(x, y, c, t_start, **kwargs) - # eddies at last date - m_end = eddies.time == t_end / 86400 - e_end = eddies.extract_with_mask(m_end) - # to be able to get global index - translate_end = where(m_end)[0] - # Id eddies for each alive particle (in core and extern) - i_end = e_end.contains(x, y) - # compute matrix and fill target array - get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct) - - -@njit(cache=True) -def get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct): - nb_start, nb_end = translate_start.size, translate_end.size - # Matrix which will store count for every couple - count = zeros((nb_start, nb_end), dtype=nb_types.int32) - # Number of particles in each origin observation - ref = zeros(nb_start, dtype=nb_types.int32) - # For each particle - for i in range(i_start.size): - i_end_ = i_end[i] - i_start_ = i_start[i] - if i_end_ != -1: - count[i_start_, i_end_] += 1 - ref[i_start_] += 1 - for i in range(nb_start): - for j in range(nb_end): - pct_ = count[i, j] - # If there are particles from i to j - if pct_ != 0: - # Get percent - pct_ = pct_ / ref[i] * 100.0 - # Get indices in full dataset - i_, j_ = translate_start[i], translate_end[j] - pct_0 = pct[i_, 0] - if pct_ > pct_0: - pct[i_, 1] = pct_0 - pct[i_, 0] = pct_ - i_target[i_, 1] = i_target[i_, 0] - i_target[i_, 0] = j_ - elif pct_ > pct[i_, 1]: - pct[i_, 1] = pct_ - i_target[i_, 1] = j_ - return i_target, pct - - # %% # Particle advection # ^^^^^^^^^^^^^^^^^^ @@ -217,12 +143,12 @@ def get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct): # Forward run i_target_f, pct_target_f = -ones(shape, dtype="i4"), zeros(shape, dtype="i1") for t in range(t_start, t_end - dt): - particle_candidate(x0, y0, c, n, t, i_target_f, pct_target_f, delta_t=dt) + particle_candidate(x0, y0, c, n, t, i_target_f, pct_target_f, n_days=dt) # Backward run i_target_b, pct_target_b = -ones(shape, dtype="i4"), zeros(shape, dtype="i1") for t in range(t_start + dt, t_end): - particle_candidate(x0, y0, c, n, t, i_target_b, pct_target_b, delta_t=-dt) + particle_candidate(x0, y0, c, n, t, i_target_b, pct_target_b, n_days=-dt) # %% fig = plt.figure(figsize=(10, 10)) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 6337e136..28fa8526 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -2264,7 +2264,7 @@ def from_netcdf_list(cls, filenames, t, x_name, y_name, indexs=None, heigth=None new.datasets.append((t, d)) return new - def shift_files(self, t, filename, x_name, y_name, indexs, heigth): + def shift_files(self, t, filename, x_name, y_name, indexs=None, heigth=None): """Add next file to the list and remove the oldest""" self.datasets = self.datasets[1:] @@ -2553,8 +2553,8 @@ def get_uv_quad(i0, j0, u, v, m, nb_x=0): i1 %= nb_x i_max, j_max = m.shape - # if i1 >= i_max or j1 >= j_max: - # return True, nan, nan, nan, nan, nan, nan, nan, nan + if i1 >= i_max or j1 >= j_max: + return True, nan, nan, nan, nan, nan, nan, nan, nan if m[i0, j0] or m[i0, j1] or m[i1, j0] or m[i1, j1]: return True, nan, nan, nan, nan, nan, nan, nan, nan diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index bd8ac81d..835101ff 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -1,8 +1,8 @@ import logging from abc import ABC, abstractmethod -from numba import njit -from numpy import arange, int32, interp, median, zeros +from numba import njit, types as nb_types +from numpy import arange, int32, interp, median, zeros, where from .observation import EddiesObservations @@ -65,6 +65,111 @@ def get_missing_indices( return indices + +def advect(x, y, c, t0, n_days): + """ + Advect particle from t0 to t0 + n_days, with data cube. + + :param np.array(float) x: longitude of particles + :param np.array(float) y: latitude of particles + :param `~py_eddy_tracker.dataset.grid.GridCollection` c: GridCollection with speed for particles + :param int t0: julian day of advection start + :param int n_days: number of days to advect + """ + + kw = dict(nb_step=6, time_step=86400 / 6) + if n_days < 0: + kw["backward"] = True + n_days = -n_days + p = c.advect(x, y, "u", "v", t_init=t0, **kw) + for _ in range(n_days): + t, x, y = p.__next__() + return t, x, y + + +def particle_candidate(x, y, c, eddies, t_start, i_target, pct, **kwargs): + """Select particles within eddies, advect them, return target observation and associated percentages + + :param np.array(float) x: longitude of particles + :param np.array(float) y: latitude of particles + :param `~py_eddy_tracker.dataset.grid.GridCollection` c: GridCollection with speed for particles + :param GroupEddiesObservations eddies: GroupEddiesObservations considered + :param int t_start: julian day of the advection + :param np.array(int) i_target: corresponding obs where particles are advected + :param np.array(int) pct: corresponding percentage of avected particles + :params dict kwargs: dict of params given to `advect` + + """ + + # Obs from initial time + m_start = eddies.time == t_start + + e = eddies.extract_with_mask(m_start) + # to be able to get global index + translate_start = where(m_start)[0] + # Identify particle in eddies (only in core) + i_start = e.contains(x, y, intern=True) + m = i_start != -1 + + x, y, i_start = x[m], y[m], i_start[m] + # Advect + t_end, x, y = advect(x, y, c, t_start, **kwargs) + # eddies at last date + m_end = eddies.time == t_end / 86400 + e_end = eddies.extract_with_mask(m_end) + # to be able to get global index + translate_end = where(m_end)[0] + # Id eddies for each alive particle (in core and extern) + i_end = e_end.contains(x, y) + # compute matrix and fill target array + get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct) + + +@njit(cache=True) +def get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct): + """Compute target observation and associated percentages + + :param np.array(int) i_start: indices of associated contours at starting advection day + :param np.array(int) i_end: indices of associated contours after advection + :param np.array(int) translate_start: corresponding global indices at starting advection day + :param np.array(int) translate_end: corresponding global indices after advection + :param np.array(int) i_target: corresponding obs where particles are advected + :param np.array(int) pct: corresponding percentage of avected particles + """ + + nb_start, nb_end = translate_start.size, translate_end.size + # Matrix which will store count for every couple + count = zeros((nb_start, nb_end), dtype=nb_types.int32) + # Number of particles in each origin observation + ref = zeros(nb_start, dtype=nb_types.int32) + # For each particle + for i in range(i_start.size): + i_end_ = i_end[i] + i_start_ = i_start[i] + if i_end_ != -1: + count[i_start_, i_end_] += 1 + ref[i_start_] += 1 + for i in range(nb_start): + for j in range(nb_end): + pct_ = count[i, j] + # If there are particles from i to j + if pct_ != 0: + # Get percent + pct_ = pct_ / ref[i] * 100.0 + # Get indices in full dataset + i_, j_ = translate_start[i], translate_end[j] + pct_0 = pct[i_, 0] + if pct_ > pct_0: + pct[i_, 1] = pct_0 + pct[i_, 0] = pct_ + i_target[i_, 1] = i_target[i_, 0] + i_target[i_, 0] = j_ + elif pct_ > pct[i_, 1]: + pct[i_, 1] = pct_ + i_target[i_, 1] = j_ + return i_target, pct + + class GroupEddiesObservations(EddiesObservations, ABC): @abstractmethod def fix_next_previous_obs(self): diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 5fe0727a..7292e7c2 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -27,7 +27,7 @@ from ..generic import build_index, wrap_longitude from ..poly import bbox_intersection, vertice_overlap, group_obs -from .groups import GroupEddiesObservations, get_missing_indices +from .groups import GroupEddiesObservations, get_missing_indices, particle_candidate from .observation import EddiesObservations from .tracking import TrackEddiesObservations, track_loess_filter, track_median_filter from ..dataset.grid import GridCollection @@ -101,109 +101,6 @@ def fix_next_previous_obs(next_obs, previous_obs, flag_virtual): previous_obs[i_o + 1] = i_o -def advect(x, y, c, t0, delta_t): - """ - Advect particle from t0 to t0 + delta_t, with data cube. - - :param np.array(float) x: longitude of particles - :param np.array(float) y: latitude of particles - :param `~py_eddy_tracker.dataset.grid.GridCollection` c: GridCollection with speed for particles - :param int t0: julian day of advection start - :param int delta_t: number of days to advect - """ - - kw = dict(nb_step=6, time_step=86400 / 6) - if delta_t < 0: - kw["backward"] = True - delta_t = -delta_t - p = c.advect(x, y, "u", "v", t_init=t0, **kw) - for _ in range(delta_t): - t, x, y = p.__next__() - return t, x, y - - -def particle_candidate(x, y, c, eddies, t_start, i_target, pct, **kwargs): - """Select particles within eddies, advect them, return target observation and associated percentages - - :param np.array(float) x: longitude of particles - :param np.array(float) y: latitude of particles - :param `~py_eddy_tracker.dataset.grid.GridCollection` c: GridCollection with speed for particles - :param NetworkObservations eddies: NetworkObservations considered - :param int t_start: julian day of the advection - :param np.array(int) i_target: corresponding obs where particles are advected - :param np.array(int) pct: corresponding percentage of avected particles - :params dict kwargs: dict of params given to `advect` - """ - - # Obs from initial time - m_start = eddies.time == t_start - - e = eddies.extract_with_mask(m_start) - # to be able to get global index - translate_start = where(m_start)[0] - # Identify particle in eddies (only in core) - i_start = e.contains(x, y, intern=True) - m = i_start != -1 - - x, y, i_start = x[m], y[m], i_start[m] - # Advect - t_end, x, y = advect(x, y, c, t_start, **kwargs) - # eddies at last date - m_end = eddies.time == t_end / 86400 - e_end = eddies.extract_with_mask(m_end) - # to be able to get global index - translate_end = where(m_end)[0] - # Id eddies for each alive particle (in core and extern) - i_end = e_end.contains(x, y) - # compute matrix and fill target array - get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct) - - -@njit(cache=True) -def get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct): - """Compute target observation and associated percentages - - :param np.array(int) i_start: indices of associated contours at starting advection day - :param np.array(int) i_end: indices of associated contours after advection - :param np.array(int) translate_start: corresponding global indices at starting advection day - :param np.array(int) translate_end: corresponding global indices after advection - :param np.array(int) i_target: corresponding obs where particles are advected - :param np.array(int) pct: corresponding percentage of avected particles - """ - - nb_start, nb_end = translate_start.size, translate_end.size - # Matrix which will store count for every couple - count = zeros((nb_start, nb_end), dtype=nb_types.int32) - # Number of particles in each origin observation - ref = zeros(nb_start, dtype=nb_types.int32) - # For each particle - for i in range(i_start.size): - i_end_ = i_end[i] - i_start_ = i_start[i] - if i_end_ != -1: - count[i_start_, i_end_] += 1 - ref[i_start_] += 1 - for i in range(nb_start): - for j in range(nb_end): - pct_ = count[i, j] - # If there are particles from i to j - if pct_ != 0: - # Get percent - pct_ = pct_ / ref[i] * 100.0 - # Get indices in full dataset - i_, j_ = translate_start[i], translate_end[j] - pct_0 = pct[i_, 0] - if pct_ > pct_0: - pct[i_, 1] = pct_0 - pct[i_, 0] = pct_ - i_target[i_, 1] = i_target[i_, 0] - i_target[i_, 0] = j_ - elif pct_ > pct[i_, 1]: - pct[i_, 1] = pct_ - i_target[i_, 1] = j_ - return i_target, pct - - class NetworkObservations(GroupEddiesObservations): __slots__ = ("_index_network",) @@ -221,12 +118,10 @@ def find_segments_relative(self, obs, stopped=None, order=1): :param int obs: index of observation after the event :param int stopped: index of observation before the event :param int order: order of relatives accepted - :return: all relative segments :rtype: EddiesObservations """ - # extraction of network where the event is network_id = self.tracks[obs] nw = self.network(network_id) @@ -1491,19 +1386,24 @@ def segment_coherence( Percentage of particules and their targets after forward or/and backward advection from a specific eddy. :param callable date_function: python function, takes as param `int` (julian day) and return - data filename associated to the date - ex: - def date2file(julian_day): - date = datetime.timedelta(days=julian_day) + datetime.datetime(1950, 1, 1) - - return f"/tmp/dt_global_allsat_phy_l4_{date.strftime('%Y%m%d')}.nc" - + data filename associated to the date (see note) :param dict uv_params: dict of parameters used by :py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_list` :param str advection_mode: "backward", "forward" or "both" :param int dt_advect: days for advection :param float step_mesh: step for particule mesh in degrees :param str output_name: if not None, name of file saved in zarr. Else, data will not be saved + :return: list of 2 or 4 array (depending if forward, backward or both) with segment matchs, and percents + + .. note:: the param `date_function` should be something like : + + .. code-block:: python + + def date2file(julian_day): + date = datetime.timedelta(days=julian_day) + datetime.datetime(1950, 1, 1) + + return f"/tmp/dt_global_allsat_phy_l4_{date.strftime('%Y%m%d')}.nc" + """ if advection_mode in ["both", "forward"]: @@ -1591,7 +1491,7 @@ def date2file(julian_day): x0, y0, c, - self, + sub_networks, _t, i_target_b, pct_target_b, From 006adc5f0b300e93a84333198945f91d4fb2cb0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Fri, 14 May 2021 13:48:53 +0200 Subject: [PATCH 157/249] correction for documentation --- src/py_eddy_tracker/generic.py | 5 +++-- src/py_eddy_tracker/observations/network.py | 6 +++--- src/py_eddy_tracker/poly.py | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/py_eddy_tracker/generic.py b/src/py_eddy_tracker/generic.py index 530c2136..283b4b9e 100644 --- a/src/py_eddy_tracker/generic.py +++ b/src/py_eddy_tracker/generic.py @@ -70,8 +70,9 @@ def build_index(groups): :param array groups: array that contains groups to be separated :return: (first_index of each group, last_index of each group, value to shift groups) :rtype: (array, array, int) - Examples - -------- + + :Example: + >>> build_index(array((1, 1, 3, 4, 4))) (array([0, 2, 2, 3]), array([2, 2, 3, 5]), 1) """ diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 7292e7c2..685b3e42 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -221,7 +221,7 @@ def from_split_network(cls, group_dataset, indexs, **kwargs): :param TrackEddiesObservations group_dataset: Group dataset :param indexs: result from split_network - return NetworkObservations + :return: NetworkObservations """ index_order = indexs.argsort(order=("group", "track", "time")) network = cls.new_like(group_dataset, len(group_dataset), **kwargs) @@ -1598,8 +1598,8 @@ def group_translator(nb, duos): :param int nb: size of translator :param set((int, int)) duos: set of all groups that must be joined - Examples - -------- + :Example: + >>> NetworkObservations.group_translator(5, ((0, 1), (0, 2), (1, 3))) [3, 3, 3, 3, 5] """ diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index fd4ae9c4..fc36185b 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -717,6 +717,7 @@ def visvalingam(x, y, fixed_size=18): """Polygon simplification with visvalingam algorithm X, Y are considered like a polygon, the next point after the last one is the first one + :param array x: :param array y: :param int fixed_size: array size of out From b3f66bcf5faf2379e62c72cdfb5e07a62ddbf56e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Sun, 16 May 2021 15:34:43 +0200 Subject: [PATCH 158/249] minor corrections sorting imports adding notebooks for binder adding kwargs to shift_files correction of new warnings done --- examples/16_network/pet_follow_particle.py | 6 +- examples/16_network/pet_ioannou_2017_case.py | 5 +- .../01_general_things/pet_storage.ipynb | 2 +- .../pet_contour_circle.ipynb | 2 +- .../pet_display_id.ipynb | 2 +- .../pet_eddy_detection.ipynb | 2 +- .../pet_eddy_detection_ACC.ipynb | 2 +- .../pet_eddy_detection_gulf_stream.ipynb | 2 +- .../pet_filter_and_detection.ipynb | 2 +- .../pet_interp_grid_on_dataset.ipynb | 2 +- .../pet_radius_vs_area.ipynb | 2 +- .../pet_shape_gallery.ipynb | 2 +- .../pet_sla_and_adt.ipynb | 2 +- .../06_grid_manipulation/pet_advect.ipynb | 2 +- .../06_grid_manipulation/pet_filter.ipynb | 2 +- .../pet_hide_pixel_out_eddies.ipynb | 2 +- .../06_grid_manipulation/pet_lavd.ipynb | 2 +- .../pet_okubo_weiss.ipynb | 2 +- .../07_cube_manipulation/pet_cube.ipynb | 2 +- .../07_cube_manipulation/pet_fsle_med.ipynb | 4 +- .../pet_lavd_detection.ipynb | 2 +- .../pet_display_field.ipynb | 2 +- .../pet_display_track.ipynb | 2 +- .../pet_one_track.ipynb | 2 +- .../pet_run_a_tracking.ipynb | 2 +- .../pet_select_track_across_area.ipynb | 2 +- .../pet_track_anim.ipynb | 2 +- .../pet_track_anim_matplotlib_animation.ipynb | 2 +- .../pet_birth_and_death.ipynb | 2 +- .../pet_center_count.ipynb | 2 +- .../pet_geographic_stats.ipynb | 2 +- .../10_tracking_diagnostics/pet_groups.ipynb | 2 +- .../10_tracking_diagnostics/pet_histo.ipynb | 2 +- .../pet_lifetime.ipynb | 2 +- .../pet_normalised_lifetime.ipynb | 2 +- .../pet_pixel_used.ipynb | 2 +- .../pet_propagation.ipynb | 2 +- .../pet_SST_collocation.ipynb | 2 +- .../14_generic_tools/pet_fit_contour.ipynb | 2 +- .../14_generic_tools/pet_visvalingam.ipynb | 2 +- .../python_module/16_network/pet_atlas.ipynb | 2 +- .../16_network/pet_follow_particle.ipynb | 24 +------ .../16_network/pet_group_anim.ipynb | 2 +- .../16_network/pet_ioannou_2017_case.ipynb | 4 +- .../16_network/pet_relative.ipynb | 2 +- .../16_network/pet_replay_segmentation.ipynb | 2 +- .../16_network/pet_segmentation_anim.ipynb | 2 +- .../16_network/pet_something_cool.ipynb | 65 +++++++++++++++++++ src/py_eddy_tracker/dataset/grid.py | 4 +- src/py_eddy_tracker/observations/groups.py | 6 +- src/py_eddy_tracker/observations/network.py | 8 +-- 51 files changed, 127 insertions(+), 83 deletions(-) create mode 100644 notebooks/python_module/16_network/pet_something_cool.ipynb diff --git a/examples/16_network/pet_follow_particle.py b/examples/16_network/pet_follow_particle.py index b4dfe343..e5451daa 100644 --- a/examples/16_network/pet_follow_particle.py +++ b/examples/16_network/pet_follow_particle.py @@ -8,16 +8,14 @@ from matplotlib import colors from matplotlib import pyplot as plt from matplotlib.animation import FuncAnimation -from numba import njit -from numba import types as nb_types -from numpy import arange, meshgrid, ones, unique, where, zeros +from numpy import arange, meshgrid, ones, unique, zeros from py_eddy_tracker import start_logger from py_eddy_tracker.appli.gui import Anim from py_eddy_tracker.data import get_demo_path from py_eddy_tracker.dataset.grid import GridCollection -from py_eddy_tracker.observations.network import NetworkObservations from py_eddy_tracker.observations.groups import particle_candidate +from py_eddy_tracker.observations.network import NetworkObservations from py_eddy_tracker.poly import group_obs start_logger().setLevel("ERROR") diff --git a/examples/16_network/pet_ioannou_2017_case.py b/examples/16_network/pet_ioannou_2017_case.py index 768f0c88..bbe26e3f 100644 --- a/examples/16_network/pet_ioannou_2017_case.py +++ b/examples/16_network/pet_ioannou_2017_case.py @@ -14,14 +14,13 @@ from matplotlib import pyplot as plt from matplotlib.animation import FuncAnimation from matplotlib.ticker import FuncFormatter -from numpy import arange, where, array, pi +from numpy import arange, array, pi, where from py_eddy_tracker.appli.gui import Anim from py_eddy_tracker.data import get_demo_path +from py_eddy_tracker.generic import coordinates_to_local from py_eddy_tracker.gui import GUI_AXES from py_eddy_tracker.observations.network import NetworkObservations - -from py_eddy_tracker.generic import coordinates_to_local from py_eddy_tracker.poly import fit_ellipse # %% diff --git a/notebooks/python_module/01_general_things/pet_storage.ipynb b/notebooks/python_module/01_general_things/pet_storage.ipynb index fa8d1a55..a56e4def 100644 --- a/notebooks/python_module/01_general_things/pet_storage.ipynb +++ b/notebooks/python_module/01_general_things/pet_storage.ipynb @@ -230,7 +230,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.2" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/02_eddy_identification/pet_contour_circle.ipynb b/notebooks/python_module/02_eddy_identification/pet_contour_circle.ipynb index 36989357..2d924387 100644 --- a/notebooks/python_module/02_eddy_identification/pet_contour_circle.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_contour_circle.ipynb @@ -82,7 +82,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/02_eddy_identification/pet_display_id.ipynb b/notebooks/python_module/02_eddy_identification/pet_display_id.ipynb index 6d40974f..d59f9e15 100644 --- a/notebooks/python_module/02_eddy_identification/pet_display_id.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_display_id.ipynb @@ -129,7 +129,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb b/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb index fb6c17f8..7469b034 100644 --- a/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_eddy_detection.ipynb @@ -291,7 +291,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb b/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb index c2a3648d..6ac75cee 100644 --- a/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_eddy_detection_ACC.ipynb @@ -161,7 +161,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/02_eddy_identification/pet_eddy_detection_gulf_stream.ipynb b/notebooks/python_module/02_eddy_identification/pet_eddy_detection_gulf_stream.ipynb index c39bc011..49024327 100644 --- a/notebooks/python_module/02_eddy_identification/pet_eddy_detection_gulf_stream.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_eddy_detection_gulf_stream.ipynb @@ -273,7 +273,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/02_eddy_identification/pet_filter_and_detection.ipynb b/notebooks/python_module/02_eddy_identification/pet_filter_and_detection.ipynb index 63e763ff..381aa8f6 100644 --- a/notebooks/python_module/02_eddy_identification/pet_filter_and_detection.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_filter_and_detection.ipynb @@ -176,7 +176,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/02_eddy_identification/pet_interp_grid_on_dataset.ipynb b/notebooks/python_module/02_eddy_identification/pet_interp_grid_on_dataset.ipynb index 94e61b30..0cfdc9a8 100644 --- a/notebooks/python_module/02_eddy_identification/pet_interp_grid_on_dataset.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_interp_grid_on_dataset.ipynb @@ -111,7 +111,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/02_eddy_identification/pet_radius_vs_area.ipynb b/notebooks/python_module/02_eddy_identification/pet_radius_vs_area.ipynb index c70f7dd6..03eba8bf 100644 --- a/notebooks/python_module/02_eddy_identification/pet_radius_vs_area.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_radius_vs_area.ipynb @@ -107,7 +107,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/02_eddy_identification/pet_shape_gallery.ipynb b/notebooks/python_module/02_eddy_identification/pet_shape_gallery.ipynb index ffa58c1f..0ef03f6f 100644 --- a/notebooks/python_module/02_eddy_identification/pet_shape_gallery.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_shape_gallery.ipynb @@ -100,7 +100,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/02_eddy_identification/pet_sla_and_adt.ipynb b/notebooks/python_module/02_eddy_identification/pet_sla_and_adt.ipynb index efbfcc76..9b8b3951 100644 --- a/notebooks/python_module/02_eddy_identification/pet_sla_and_adt.ipynb +++ b/notebooks/python_module/02_eddy_identification/pet_sla_and_adt.ipynb @@ -223,7 +223,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb index b660df52..bceed074 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb @@ -262,7 +262,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.2" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/06_grid_manipulation/pet_filter.ipynb b/notebooks/python_module/06_grid_manipulation/pet_filter.ipynb index 74a266c2..2d6a7d3a 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_filter.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_filter.ipynb @@ -215,7 +215,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/06_grid_manipulation/pet_hide_pixel_out_eddies.ipynb b/notebooks/python_module/06_grid_manipulation/pet_hide_pixel_out_eddies.ipynb index c9bca31e..f30076fa 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_hide_pixel_out_eddies.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_hide_pixel_out_eddies.ipynb @@ -111,7 +111,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb index 67983cec..a5ca088c 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb @@ -201,7 +201,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.2" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/06_grid_manipulation/pet_okubo_weiss.ipynb b/notebooks/python_module/06_grid_manipulation/pet_okubo_weiss.ipynb index b410be0a..ca4998ee 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_okubo_weiss.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_okubo_weiss.ipynb @@ -201,7 +201,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb b/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb index a8ed7f1b..22cf3158 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb @@ -158,7 +158,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.2" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb index 4f2e1467..a90c3b9f 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb @@ -33,7 +33,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## ADT in med\n:py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_cube` method is\nmade for data stores in time cube, you could use also \n:py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_list` method to\nload data-cube from multiple file.\n\n" + "## ADT in med\n:py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_cube` method is\nmade for data stores in time cube, you could use also\n:py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_list` method to\nload data-cube from multiple file.\n\n" ] }, { @@ -172,7 +172,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.2" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb b/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb index f4e5f77e..bd197c57 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb @@ -194,7 +194,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.2" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/08_tracking_manipulation/pet_display_field.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_display_field.ipynb index bf924b36..6e43e9a4 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_display_field.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_display_field.ipynb @@ -82,7 +82,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/08_tracking_manipulation/pet_display_track.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_display_track.ipynb index 1af7b49a..c98e53f0 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_display_track.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_display_track.ipynb @@ -118,7 +118,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/08_tracking_manipulation/pet_one_track.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_one_track.ipynb index 2749f7e9..95595a7a 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_one_track.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_one_track.ipynb @@ -93,7 +93,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/08_tracking_manipulation/pet_run_a_tracking.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_run_a_tracking.ipynb index e8871283..d0a2e5b0 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_run_a_tracking.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_run_a_tracking.ipynb @@ -154,7 +154,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/08_tracking_manipulation/pet_select_track_across_area.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_select_track_across_area.ipynb index 5ba0d481..8e64b680 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_select_track_across_area.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_select_track_across_area.ipynb @@ -100,7 +100,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/08_tracking_manipulation/pet_track_anim.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_track_anim.ipynb index 041c8987..65768145 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_track_anim.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_track_anim.ipynb @@ -82,7 +82,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb index 9f77dbae..6d7fcc2e 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb @@ -93,7 +93,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_birth_and_death.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_birth_and_death.ipynb index d9a2ef2b..635c6b5a 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_birth_and_death.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_birth_and_death.ipynb @@ -144,7 +144,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb index b6bb15bd..753cd625 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb @@ -118,7 +118,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_geographic_stats.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_geographic_stats.ipynb index 3e884552..df495703 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_geographic_stats.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_geographic_stats.ipynb @@ -118,7 +118,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_groups.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_groups.ipynb index 85e32c6a..9f06e010 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_groups.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_groups.ipynb @@ -136,7 +136,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_histo.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_histo.ipynb index 851c6ca4..81809d8b 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_histo.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_histo.ipynb @@ -82,7 +82,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_lifetime.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_lifetime.ipynb index 4a3ff0af..ed8c0295 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_lifetime.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_lifetime.ipynb @@ -82,7 +82,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_normalised_lifetime.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_normalised_lifetime.ipynb index 867e081f..a53f2d3a 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_normalised_lifetime.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_normalised_lifetime.ipynb @@ -111,7 +111,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb index 81bed372..23f830d6 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb @@ -118,7 +118,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_propagation.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_propagation.ipynb index e0d1f2d2..9792f8f4 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_propagation.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_propagation.ipynb @@ -118,7 +118,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/12_external_data/pet_SST_collocation.ipynb b/notebooks/python_module/12_external_data/pet_SST_collocation.ipynb index 05b0413c..b30682a1 100644 --- a/notebooks/python_module/12_external_data/pet_SST_collocation.ipynb +++ b/notebooks/python_module/12_external_data/pet_SST_collocation.ipynb @@ -226,7 +226,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb b/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb index 5306fa0c..a46a7e22 100644 --- a/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb +++ b/notebooks/python_module/14_generic_tools/pet_fit_contour.ipynb @@ -100,7 +100,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.2" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb b/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb index 0183abde..69e49b57 100644 --- a/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb +++ b/notebooks/python_module/14_generic_tools/pet_visvalingam.ipynb @@ -75,7 +75,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/16_network/pet_atlas.ipynb b/notebooks/python_module/16_network/pet_atlas.ipynb index ee8f1934..31e3580f 100644 --- a/notebooks/python_module/16_network/pet_atlas.ipynb +++ b/notebooks/python_module/16_network/pet_atlas.ipynb @@ -363,7 +363,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.2" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/16_network/pet_follow_particle.ipynb b/notebooks/python_module/16_network/pet_follow_particle.ipynb index 28d0048d..6be13adf 100644 --- a/notebooks/python_module/16_network/pet_follow_particle.ipynb +++ b/notebooks/python_module/16_network/pet_follow_particle.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import re\n\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numba import njit\nfrom numba import types as nb_types\nfrom numpy import arange, meshgrid, ones, unique, where, zeros\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import GridCollection\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.poly import group_obs\n\nstart_logger().setLevel(\"ERROR\")" + "import re\n\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, meshgrid, ones, unique, zeros\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import GridCollection\nfrom py_eddy_tracker.observations.groups import particle_candidate\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.poly import group_obs\n\nstart_logger().setLevel(\"ERROR\")" ] }, { @@ -105,24 +105,6 @@ "cmap = colors.ListedColormap(list(n.COLORS), name=\"from_list\", N=n.segment.max() + 1)\na = Anim(\n n,\n intern=False,\n figsize=(12, 6),\n nb_step=1,\n dpi=60,\n field_color=\"segment\",\n field_txt=\"segment\",\n cmap=cmap,\n)\na.fig.suptitle(\"\"), a.ax.set_xlim(24, 36), a.ax.set_ylim(30, 36)\na.txt.set_position((25, 31))\n\nstep = 0.25\nkw_p = dict(nb_step=2, time_step=86400 * step * 0.5, t_init=t_snapshot - 2 * step)\n\nmappables = dict()\nparticules = c.advect(x, y, \"u\", \"v\", **kw_p)\nfilament = c.filament(x_f, y_f, \"u\", \"v\", **kw_p, filament_size=3)\nkw = dict(ls=\"\", marker=\".\", markersize=0.25)\nfor k in index_:\n m = k == index\n mappables[k] = a.ax.plot([], [], color=cmap(k), **kw)[0]\nm_filament = a.ax.plot([], [], lw=0.25, color=\"gray\")[0]\n\n\ndef update(frame):\n tt, xt, yt = particules.__next__()\n for k, mappable in mappables.items():\n m = index == k\n mappable.set_data(xt[m], yt[m])\n tt, xt, yt = filament.__next__()\n m_filament.set_data(xt, yt)\n if frame % 1 == 0:\n a.func_animation(frame)\n\n\nani = VideoAnimation(a.fig, update, frames=arange(20200, 20269, step), interval=200)" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## In which observations are the particle\n\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "def advect(x, y, c, t0, delta_t):\n \"\"\"\n Advect particle from t0 to t0 + delta_t, with data cube.\n \"\"\"\n kw = dict(nb_step=6, time_step=86400 / 6)\n if delta_t < 0:\n kw[\"backward\"] = True\n delta_t = -delta_t\n p = c.advect(x, y, \"u\", \"v\", t_init=t0, **kw)\n for _ in range(delta_t):\n t, x, y = p.__next__()\n return t, x, y\n\n\ndef particle_candidate(x, y, c, eddies, t_start, i_target, pct, **kwargs):\n # Obs from initial time\n m_start = eddies.time == t_start\n e = eddies.extract_with_mask(m_start)\n # to be able to get global index\n translate_start = where(m_start)[0]\n # Identify particle in eddies (only in core)\n i_start = e.contains(x, y, intern=True)\n m = i_start != -1\n x, y, i_start = x[m], y[m], i_start[m]\n # Advect\n t_end, x, y = advect(x, y, c, t_start, **kwargs)\n # eddies at last date\n m_end = eddies.time == t_end / 86400\n e_end = eddies.extract_with_mask(m_end)\n # to be able to get global index\n translate_end = where(m_end)[0]\n # Id eddies for each alive particle (in core and extern)\n i_end = e_end.contains(x, y)\n # compute matrix and fill target array\n get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct)\n\n\n@njit(cache=True)\ndef get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct):\n nb_start, nb_end = translate_start.size, translate_end.size\n # Matrix which will store count for every couple\n count = zeros((nb_start, nb_end), dtype=nb_types.int32)\n # Number of particles in each origin observation\n ref = zeros(nb_start, dtype=nb_types.int32)\n # For each particle\n for i in range(i_start.size):\n i_end_ = i_end[i]\n i_start_ = i_start[i]\n if i_end_ != -1:\n count[i_start_, i_end_] += 1\n ref[i_start_] += 1\n for i in range(nb_start):\n for j in range(nb_end):\n pct_ = count[i, j]\n # If there are particles from i to j\n if pct_ != 0:\n # Get percent\n pct_ = pct_ / ref[i] * 100.0\n # Get indices in full dataset\n i_, j_ = translate_start[i], translate_end[j]\n pct_0 = pct[i_, 0]\n if pct_ > pct_0:\n pct[i_, 1] = pct_0\n pct[i_, 0] = pct_\n i_target[i_, 1] = i_target[i_, 0]\n i_target[i_, 0] = j_\n elif pct_ > pct[i_, 1]:\n pct[i_, 1] = pct_\n i_target[i_, 1] = j_\n return i_target, pct" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -138,7 +120,7 @@ }, "outputs": [], "source": [ - "step = 1 / 60.0\n\nx, y = meshgrid(arange(24, 36, step), arange(31, 36, step))\nx0, y0 = x.reshape(-1), y.reshape(-1)\n# Pre-order to speed up\n_, i = group_obs(x0, y0, 1, 360)\nx0, y0 = x0[i], y0[i]\n\nt_start, t_end = n.period\ndt = 14\n\nshape = (n.obs.size, 2)\n# Forward run\ni_target_f, pct_target_f = -ones(shape, dtype=\"i4\"), zeros(shape, dtype=\"i1\")\nfor t in range(t_start, t_end - dt):\n particle_candidate(x0, y0, c, n, t, i_target_f, pct_target_f, delta_t=dt)\n\n# Backward run\ni_target_b, pct_target_b = -ones(shape, dtype=\"i4\"), zeros(shape, dtype=\"i1\")\nfor t in range(t_start + dt, t_end):\n particle_candidate(x0, y0, c, n, t, i_target_b, pct_target_b, delta_t=-dt)" + "step = 1 / 60.0\n\nx, y = meshgrid(arange(24, 36, step), arange(31, 36, step))\nx0, y0 = x.reshape(-1), y.reshape(-1)\n# Pre-order to speed up\n_, i = group_obs(x0, y0, 1, 360)\nx0, y0 = x0[i], y0[i]\n\nt_start, t_end = n.period\ndt = 14\n\nshape = (n.obs.size, 2)\n# Forward run\ni_target_f, pct_target_f = -ones(shape, dtype=\"i4\"), zeros(shape, dtype=\"i1\")\nfor t in range(t_start, t_end - dt):\n particle_candidate(x0, y0, c, n, t, i_target_f, pct_target_f, n_days=dt)\n\n# Backward run\ni_target_b, pct_target_b = -ones(shape, dtype=\"i4\"), zeros(shape, dtype=\"i1\")\nfor t in range(t_start + dt, t_end):\n particle_candidate(x0, y0, c, n, t, i_target_b, pct_target_b, n_days=-dt)" ] }, { @@ -169,7 +151,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.2" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/16_network/pet_group_anim.ipynb b/notebooks/python_module/16_network/pet_group_anim.ipynb index ffb9dd17..7129259c 100644 --- a/notebooks/python_module/16_network/pet_group_anim.ipynb +++ b/notebooks/python_module/16_network/pet_group_anim.ipynb @@ -205,7 +205,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb b/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb index 9b3d40d6..788e94ca 100644 --- a/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb +++ b/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import re\nfrom datetime import datetime, timedelta\n\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.ticker import FuncFormatter\nfrom numpy import arange, where, array, pi\n\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.gui import GUI_AXES\nfrom py_eddy_tracker.observations.network import NetworkObservations\n\nfrom py_eddy_tracker.generic import coordinates_to_local\nfrom py_eddy_tracker.poly import fit_ellipse" + "import re\nfrom datetime import datetime, timedelta\n\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom matplotlib.ticker import FuncFormatter\nfrom numpy import arange, array, pi, where\n\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.generic import coordinates_to_local\nfrom py_eddy_tracker.gui import GUI_AXES\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.poly import fit_ellipse" ] }, { @@ -338,7 +338,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.2" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/16_network/pet_relative.ipynb b/notebooks/python_module/16_network/pet_relative.ipynb index cee4010a..9f3fd3d9 100644 --- a/notebooks/python_module/16_network/pet_relative.ipynb +++ b/notebooks/python_module/16_network/pet_relative.ipynb @@ -539,7 +539,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.2" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/16_network/pet_replay_segmentation.ipynb b/notebooks/python_module/16_network/pet_replay_segmentation.ipynb index 48f4955b..7c632138 100644 --- a/notebooks/python_module/16_network/pet_replay_segmentation.ipynb +++ b/notebooks/python_module/16_network/pet_replay_segmentation.ipynb @@ -172,7 +172,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.2" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb index ae36381c..05c68873 100644 --- a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb +++ b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb @@ -147,7 +147,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.2" + "version": "3.7.9" } }, "nbformat": 4, diff --git a/notebooks/python_module/16_network/pet_something_cool.ipynb b/notebooks/python_module/16_network/pet_something_cool.ipynb new file mode 100644 index 00000000..158852f9 --- /dev/null +++ b/notebooks/python_module/16_network/pet_something_cool.ipynb @@ -0,0 +1,65 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# essai\n\non tente des trucs\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import cartopy.crs as ccrs\nimport cartopy.feature as cfeature\nimport numpy as np\nfrom matplotlib import pyplot as plt\n\nfrom py_eddy_tracker.observations.network import NetworkObservations\n\n\ndef rect_from_extent(extent):\n rect_lon = [extent[0], extent[1], extent[1], extent[0], extent[0]]\n rect_lat = [extent[2], extent[2], extent[3], extent[3], extent[2]]\n return rect_lon, rect_lat\n\n\ndef indice_from_extent(lon, lat, extent):\n mask = (lon > extent[0]) * (lon < extent[1]) * (lat > extent[2]) * (lat < extent[3])\n return np.where(mask)[0]\n\n\nfichier = \"/data/adelepoulle/work/Eddies/20201217_network_build/big_network.nc\"\nnetwork = NetworkObservations.load_file(fichier)\nsub_network = network.network(1078566)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# extent_begin = [0, 2, -50, -15]\n# extent_end = [-42, -35, -40, -10]\n\nextent_begin = [2, 22, -50, -30]\ni_obs_begin = indice_from_extent(\n sub_network.longitude, sub_network.latitude, extent_begin\n)\nnetwork_begin = sub_network.find_link(i_obs_begin)\ntime_mini = network_begin.time.min()\ntime_maxi = network_begin.time.max()\n\nextent_end = [-52, -45, -37, -33]\ni_obs_end = indice_from_extent(\n (network_begin.longitude + 180) % 360 - 180, network_begin.latitude, extent_end\n)\nnetwork_end = network_begin.find_link(i_obs_end, forward=False, backward=True)\n\n\ndatasets = [network_begin, network_end]\nextents = [extent_begin, extent_end]\nfig, (ax1, ax2) = plt.subplots(\n 2, 1, figsize=(10, 9), dpi=140, subplot_kw={\"projection\": ccrs.PlateCarree()}\n)\n\nfor ax, dataset, extent in zip([ax1, ax2], datasets, extents):\n sca = dataset.scatter(\n ax,\n name=\"time\",\n cmap=\"Spectral_r\",\n label=\"observation dans le temps\",\n vmin=time_mini,\n vmax=time_maxi,\n )\n\n x, y = rect_from_extent(extent)\n ax.fill(x, y, color=\"grey\", alpha=0.3, label=\"observations choisies\")\n # ax.plot(x, y, marker='o')\n\n ax.legend()\n\n gridlines = ax.gridlines(\n alpha=0.2, color=\"black\", linestyle=\"dotted\", draw_labels=True, dms=True\n )\n\n gridlines.left_labels = False\n gridlines.top_labels = False\n\n ax.coastlines()\n ax.add_feature(cfeature.LAND)\n ax.add_feature(cfeature.LAKES, zorder=10)\n ax.add_feature(cfeature.BORDERS, lw=0.25)\n ax.add_feature(cfeature.OCEAN, alpha=0.2)\n\n\nax1.set_title(\n \"Recherche du d\u00e9placement de l'eau dans les eddies \u00e0 travers les observations choisies\"\n)\nax2.set_title(\"Recherche de la provenance de l'eau \u00e0 travers les observations choisies\")\nax2.set_extent(ax1.get_extent(), ccrs.PlateCarree())\n\nfig.subplots_adjust(right=0.87, left=0.02)\ncbar_ax = fig.add_axes([0.90, 0.1, 0.02, 0.8])\ncbar = fig.colorbar(sca[\"scatter\"], cax=cbar_ax, orientation=\"vertical\")\n_ = cbar.set_label(\"time (jj)\", rotation=270, labelpad=-65)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.9" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 28fa8526..bd9e70d3 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -2264,12 +2264,12 @@ def from_netcdf_list(cls, filenames, t, x_name, y_name, indexs=None, heigth=None new.datasets.append((t, d)) return new - def shift_files(self, t, filename, x_name, y_name, indexs=None, heigth=None): + def shift_files(self, t, filename, heigth=None, **rgd_kwargs): """Add next file to the list and remove the oldest""" self.datasets = self.datasets[1:] - d = RegularGridDataset(filename, x_name, y_name, indexs=indexs) + d = RegularGridDataset(filename, **rgd_kwargs) if heigth is not None: d.add_uv(heigth) self.datasets.append((t, d)) diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index 835101ff..c0924cb3 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -1,8 +1,9 @@ import logging from abc import ABC, abstractmethod -from numba import njit, types as nb_types -from numpy import arange, int32, interp, median, zeros, where +from numba import njit +from numba import types as nb_types +from numpy import arange, int32, interp, median, where, zeros from .observation import EddiesObservations @@ -65,7 +66,6 @@ def get_missing_indices( return indices - def advect(x, y, c, t0, n_days): """ Advect particle from t0 to t0 + n_days, with data cube. diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 685b3e42..0e5b9576 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -5,6 +5,7 @@ import logging from glob import glob +import zarr from numba import njit from numba import types as nb_types from numpy import ( @@ -15,22 +16,21 @@ concatenate, empty, in1d, + meshgrid, ones, uint16, uint32, unique, where, zeros, - meshgrid, ) -import zarr +from ..dataset.grid import GridCollection from ..generic import build_index, wrap_longitude -from ..poly import bbox_intersection, vertice_overlap, group_obs +from ..poly import bbox_intersection, group_obs, vertice_overlap from .groups import GroupEddiesObservations, get_missing_indices, particle_candidate from .observation import EddiesObservations from .tracking import TrackEddiesObservations, track_loess_filter, track_median_filter -from ..dataset.grid import GridCollection logger = logging.getLogger("pet") From d76da6ac1af0a0d5ab37d9d2c11c5ebba2dfc71e Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Mon, 17 May 2021 21:20:17 +0200 Subject: [PATCH 159/249] Add test to solve one problem of #88 --- src/py_eddy_tracker/observations/observation.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 3d91ad42..0dc4ed69 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -2056,7 +2056,8 @@ def contains(self, x, y, intern=False): xname, yname = self.intern(intern) m = ~(isnan(x) + isnan(y)) i = -ones(x.shape, dtype="i4") - i[m] = poly_indexs(x[m], y[m], self[xname], self[yname]) + if x.size != 0: + i[m] = poly_indexs(x[m], y[m], self[xname], self[yname]) return i def inside(self, x, y, intern=False): From efb8faa9b6157b60f0017c4502f41de75e38a992 Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Thu, 20 May 2021 15:35:12 +0200 Subject: [PATCH 160/249] Solve issue #88 --- src/py_eddy_tracker/generic.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/py_eddy_tracker/generic.py b/src/py_eddy_tracker/generic.py index 283b4b9e..a48c0e2f 100644 --- a/src/py_eddy_tracker/generic.py +++ b/src/py_eddy_tracker/generic.py @@ -89,8 +89,7 @@ def build_index(groups): first_index[group - i0 + 1 : next_group - i0 + 1] = i + 1 last_index = zeros(amplitude, dtype=numba_types.int_) last_index[:-1] = first_index[1:] - # + 2 because we iterate only until -2 and we want upper bound ( 1 + 1) - last_index[-1] = i + 2 + last_index[-1] = len(groups) return first_index, last_index, i0 From 3d705bec3cc46969c62f6416b1ae64061d9b6da3 Mon Sep 17 00:00:00 2001 From: Cori Pegliasco Date: Wed, 26 May 2021 10:16:42 +0200 Subject: [PATCH 161/249] - change parameter in particle_candidate - add test for mask in contains - minor english --- src/py_eddy_tracker/observations/network.py | 4 ++-- src/py_eddy_tracker/observations/observation.py | 3 ++- src/py_eddy_tracker/poly.py | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 0e5b9576..4f9af0b3 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -1464,7 +1464,7 @@ def date2file(julian_day): _t, i_target_f, pct_target_f, - delta_t=dt_advect, + n_days=dt_advect, ) itf_final[slice_track] = i_target_f @@ -1495,7 +1495,7 @@ def date2file(julian_day): _t, i_target_b, pct_target_b, - delta_t=-dt_advect, + n_days=-dt_advect, ) itb_final[slice_track] = i_target_b diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 0dc4ed69..054ba81a 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -2056,7 +2056,8 @@ def contains(self, x, y, intern=False): xname, yname = self.intern(intern) m = ~(isnan(x) + isnan(y)) i = -ones(x.shape, dtype="i4") - if x.size != 0: + + if x.size != 0 and True in m: i[m] = poly_indexs(x[m], y[m], self[xname], self[yname]) return i diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index fc36185b..0f0271ee 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -854,8 +854,8 @@ def poly_indexs(x_p, y_p, x_c, y_c): """ Index of contour for each postion inside a contour, -1 in case of no contour - :param array x_p: longitude to test (must be define, no nan) - :param array y_p: latitude to test (must be define, no nan) + :param array x_p: longitude to test (must be defined, no nan) + :param array y_p: latitude to test (must be defined, no nan) :param array x_c: longitude of contours :param array y_c: latitude of contours """ From 918fbf2529e2aa87e6d68fce95745b4add3e6a42 Mon Sep 17 00:00:00 2001 From: Cori Pegliasco Date: Wed, 26 May 2021 11:17:41 +0200 Subject: [PATCH 162/249] correction pull request --- src/py_eddy_tracker/observations/observation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 054ba81a..557c0279 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -2057,7 +2057,7 @@ def contains(self, x, y, intern=False): m = ~(isnan(x) + isnan(y)) i = -ones(x.shape, dtype="i4") - if x.size != 0 and True in m: + if x.size != 0 and m.any(): i[m] = poly_indexs(x[m], y[m], self[xname], self[yname]) return i From 0d9980802a6e995284d4dc65608a8fc908a16988 Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Mon, 31 May 2021 22:01:28 +0200 Subject: [PATCH 163/249] replace log2 by log in fsle --- examples/07_cube_manipulation/pet_fsle_med.py | 6 ++--- .../07_cube_manipulation/pet_fsle_med.ipynb | 24 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/examples/07_cube_manipulation/pet_fsle_med.py b/examples/07_cube_manipulation/pet_fsle_med.py index b4a51265..cc221cf7 100644 --- a/examples/07_cube_manipulation/pet_fsle_med.py +++ b/examples/07_cube_manipulation/pet_fsle_med.py @@ -14,7 +14,7 @@ from matplotlib import pyplot as plt from numba import njit -from numpy import arange, arctan2, empty, isnan, log2, ma, meshgrid, ones, pi, zeros +from numpy import arange, arctan2, empty, isnan, log, ma, meshgrid, ones, pi, zeros from py_eddy_tracker import start_logger from py_eddy_tracker.data import get_demo_path @@ -71,7 +71,7 @@ def check_p(x, y, flse, theta, m_set, m, dt, dist_init=0.02, dist_max=0.6): s2 = ((dxn + dye) ** 2 + (dxe - dyn) ** 2) * ( (dxn - dye) ** 2 + (dxe + dyn) ** 2 ) - flse[i] = 1 / (2 * dt) * log2(1 / (2 * dist_init ** 2) * (s1 + s2 ** 0.5)) + flse[i] = 1 / (2 * dt) * log(1 / (2 * dist_init ** 2) * (s1 + s2 ** 0.5)) theta[i] = arctan2(at1, at2 + s2) * 180 / pi # To know where value are set m_set[i] = False @@ -180,7 +180,7 @@ def build_triplet(x, y, step=0.02): ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46) ax.set_aspect("equal") ax.set_title("Finite size lyapunov exponent", weight="bold") -kw = dict(cmap="viridis_r", vmin=-15, vmax=0) +kw = dict(cmap="viridis_r", vmin=-20, vmax=0) m = fsle_custom.display(ax, 1 / fsle_custom.grid("fsle"), **kw) ax.grid() _ = plt.colorbar(m, cax=fig.add_axes([0.94, 0.05, 0.01, 0.9])) diff --git a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb index a90c3b9f..8ee136b3 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# FSLE experiment in med\n\nExample to build Finite Size Lyapunov Exponents, parameter values must be adapted for your case.\n\nExample use a method similar to `AVISO flse`_\n\n https://www.aviso.altimetry.fr/en/data/products/value-added-products/\n fsle-finite-size-lyapunov-exponents/fsle-description.html\n" + "\nFSLE experiment in med\n======================\n\nExample to build Finite Size Lyapunov Exponents, parameter values must be adapted for your case.\n\nExample use a method similar to `AVISO flse`_\n\n https://www.aviso.altimetry.fr/en/data/products/value-added-products/\n fsle-finite-size-lyapunov-exponents/fsle-description.html\n" ] }, { @@ -26,14 +26,14 @@ }, "outputs": [], "source": [ - "from matplotlib import pyplot as plt\nfrom numba import njit\nfrom numpy import arange, arctan2, empty, isnan, log2, ma, meshgrid, ones, pi, zeros\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import GridCollection, RegularGridDataset\n\nstart_logger().setLevel(\"ERROR\")" + "from matplotlib import pyplot as plt\nfrom numba import njit\nfrom numpy import arange, arctan2, empty, isnan, log, ma, meshgrid, ones, pi, zeros\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import GridCollection, RegularGridDataset\n\nstart_logger().setLevel(\"ERROR\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## ADT in med\n:py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_cube` method is\nmade for data stores in time cube, you could use also\n:py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_list` method to\nload data-cube from multiple file.\n\n" + "ADT in med\n----------\n:py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_cube` method is\nmade for data stores in time cube, you could use also \n:py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_list` method to\nload data-cube from multiple file.\n\n" ] }, { @@ -51,7 +51,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Methods to compute FSLE\n\n" + "Methods to compute FSLE\n-----------------------\n\n" ] }, { @@ -62,14 +62,14 @@ }, "outputs": [], "source": [ - "@njit(cache=True, fastmath=True)\ndef check_p(x, y, flse, theta, m_set, m, dt, dist_init=0.02, dist_max=0.6):\n \"\"\"\n Check if distance between eastern or northern particle to center particle is bigger than `dist_max`\n \"\"\"\n nb_p = x.shape[0] // 3\n delta = dist_max ** 2\n for i in range(nb_p):\n i0 = i * 3\n i_n = i0 + 1\n i_e = i0 + 2\n # If particle already set, we skip\n if m[i0] or m[i_n] or m[i_e]:\n continue\n # Distance with north\n dxn, dyn = x[i0] - x[i_n], y[i0] - y[i_n]\n dn = dxn ** 2 + dyn ** 2\n # Distance with east\n dxe, dye = x[i0] - x[i_e], y[i0] - y[i_e]\n de = dxe ** 2 + dye ** 2\n\n if dn >= delta or de >= delta:\n s1 = dn + de\n at1 = 2 * (dxe * dxn + dye * dyn)\n at2 = de - dn\n s2 = ((dxn + dye) ** 2 + (dxe - dyn) ** 2) * (\n (dxn - dye) ** 2 + (dxe + dyn) ** 2\n )\n flse[i] = 1 / (2 * dt) * log2(1 / (2 * dist_init ** 2) * (s1 + s2 ** 0.5))\n theta[i] = arctan2(at1, at2 + s2) * 180 / pi\n # To know where value are set\n m_set[i] = False\n # To stop particle advection\n m[i0], m[i_n], m[i_e] = True, True, True\n\n\n@njit(cache=True)\ndef build_triplet(x, y, step=0.02):\n \"\"\"\n Triplet building for each position we add east and north point with defined step\n \"\"\"\n nb_x = x.shape[0]\n x_ = empty(nb_x * 3, dtype=x.dtype)\n y_ = empty(nb_x * 3, dtype=y.dtype)\n for i in range(nb_x):\n i0 = i * 3\n i_n, i_e = i0 + 1, i0 + 2\n x__, y__ = x[i], y[i]\n x_[i0], y_[i0] = x__, y__\n x_[i_n], y_[i_n] = x__, y__ + step\n x_[i_e], y_[i_e] = x__ + step, y__\n return x_, y_" + "@njit(cache=True, fastmath=True)\ndef check_p(x, y, flse, theta, m_set, m, dt, dist_init=0.02, dist_max=0.6):\n \"\"\"\n Check if distance between eastern or northern particle to center particle is bigger than `dist_max`\n \"\"\"\n nb_p = x.shape[0] // 3\n delta = dist_max ** 2\n for i in range(nb_p):\n i0 = i * 3\n i_n = i0 + 1\n i_e = i0 + 2\n # If particle already set, we skip\n if m[i0] or m[i_n] or m[i_e]:\n continue\n # Distance with north\n dxn, dyn = x[i0] - x[i_n], y[i0] - y[i_n]\n dn = dxn ** 2 + dyn ** 2\n # Distance with east\n dxe, dye = x[i0] - x[i_e], y[i0] - y[i_e]\n de = dxe ** 2 + dye ** 2\n\n if dn >= delta or de >= delta:\n s1 = dn + de\n at1 = 2 * (dxe * dxn + dye * dyn)\n at2 = de - dn\n s2 = ((dxn + dye) ** 2 + (dxe - dyn) ** 2) * (\n (dxn - dye) ** 2 + (dxe + dyn) ** 2\n )\n flse[i] = 1 / (2 * dt) * log(1 / (2 * dist_init ** 2) * (s1 + s2 ** 0.5))\n theta[i] = arctan2(at1, at2 + s2) * 180 / pi\n # To know where value are set\n m_set[i] = False\n # To stop particle advection\n m[i0], m[i_n], m[i_e] = True, True, True\n\n\n@njit(cache=True)\ndef build_triplet(x, y, step=0.02):\n \"\"\"\n Triplet building for each position we add east and north point with defined step\n \"\"\"\n nb_x = x.shape[0]\n x_ = empty(nb_x * 3, dtype=x.dtype)\n y_ = empty(nb_x * 3, dtype=y.dtype)\n for i in range(nb_x):\n i0 = i * 3\n i_n, i_e = i0 + 1, i0 + 2\n x__, y__ = x[i], y[i]\n x_[i0], y_[i0] = x__, y__\n x_[i_n], y_[i_n] = x__, y__ + step\n x_[i_e], y_[i_e] = x__ + step, y__\n return x_, y_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Settings\n\n" + "Settings\n--------\n\n" ] }, { @@ -87,7 +87,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Particles\n\n" + "Particles\n---------\n\n" ] }, { @@ -105,7 +105,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## FSLE\n\n" + "FSLE\n----\n\n" ] }, { @@ -123,7 +123,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Display FSLE\n\n" + "Display FSLE\n------------\n\n" ] }, { @@ -134,14 +134,14 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(13, 5), dpi=150)\nax = fig.add_axes([0.03, 0.03, 0.90, 0.94])\nax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\nax.set_aspect(\"equal\")\nax.set_title(\"Finite size lyapunov exponent\", weight=\"bold\")\nkw = dict(cmap=\"viridis_r\", vmin=-15, vmax=0)\nm = fsle_custom.display(ax, 1 / fsle_custom.grid(\"fsle\"), **kw)\nax.grid()\n_ = plt.colorbar(m, cax=fig.add_axes([0.94, 0.05, 0.01, 0.9]))" + "fig = plt.figure(figsize=(13, 5), dpi=150)\nax = fig.add_axes([0.03, 0.03, 0.90, 0.94])\nax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\nax.set_aspect(\"equal\")\nax.set_title(\"Finite size lyapunov exponent\", weight=\"bold\")\nkw = dict(cmap=\"viridis_r\", vmin=-20, vmax=0)\nm = fsle_custom.display(ax, 1 / fsle_custom.grid(\"fsle\"), **kw)\nax.grid()\n_ = plt.colorbar(m, cax=fig.add_axes([0.94, 0.05, 0.01, 0.9]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Display Theta\n\n" + "Display Theta\n-------------\n\n" ] }, { @@ -172,7 +172,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.9" + "version": "3.7.7" } }, "nbformat": 4, From 92c326230f7a9ca8c53147f78890a8c7321de8f5 Mon Sep 17 00:00:00 2001 From: CoriPegliasco <66008544+CoriPegliasco@users.noreply.github.com> Date: Thu, 17 Jun 2021 21:36:41 +0200 Subject: [PATCH 164/249] - add comments + english (#93) --- share/tracking.yaml | 6 +++--- src/py_eddy_tracker/dataset/grid.py | 5 ++++- src/py_eddy_tracker/eddy_feature.py | 2 +- src/py_eddy_tracker/generic.py | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/share/tracking.yaml b/share/tracking.yaml index 0f8766b8..b9c98488 100644 --- a/share/tracking.yaml +++ b/share/tracking.yaml @@ -8,6 +8,6 @@ PATHS: TRACK_DURATION_MIN: 4 VIRTUAL_LENGTH_MAX: 0 -#CLASS: -# MODULE: py_eddy_tracker.featured_tracking.old_tracker_reference -# CLASS: CheltonTracker +CLASS: + MODULE: py_eddy_tracker.featured_tracking.area_tracker + CLASS: AreaTracker diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index bd9e70d3..a2237c61 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -617,7 +617,10 @@ def eddy_identification( :param float,None precision: Truncate values at the defined precision in m :param str force_height_unit: Unit used for height unit :param str force_speed_unit: Unit used for speed unit - :param dict kwargs: Argument given to amplitude + :param dict kwargs: Arguments given to amplitude (mle, nb_step_min, nb_step_to_be_mle). + Look at :py:meth:`py_eddy_tracker.eddy_feature.Amplitude` + The amplitude threshold is given by `step*nb_step_min` + :return: Return a list of 2 elements: Anticyclones and Cyclones :rtype: py_eddy_tracker.observations.observation.EddiesObservations diff --git a/src/py_eddy_tracker/eddy_feature.py b/src/py_eddy_tracker/eddy_feature.py index 037beb35..f6db848b 100644 --- a/src/py_eddy_tracker/eddy_feature.py +++ b/src/py_eddy_tracker/eddy_feature.py @@ -65,7 +65,7 @@ def __init__( :param float contour_height: :param array data: :param float interval: - :param int mle: maximum number of local maxima in contour + :param int mle: maximum number of local extrema in contour :param int nb_step_min: number of intervals to consider an eddy :param int nb_step_to_be_mle: number of intervals to be considered as an another maxima """ diff --git a/src/py_eddy_tracker/generic.py b/src/py_eddy_tracker/generic.py index a48c0e2f..94cf321f 100644 --- a/src/py_eddy_tracker/generic.py +++ b/src/py_eddy_tracker/generic.py @@ -309,7 +309,7 @@ def uniform_resample(x_val, y_val, num_fac=2, fixed_size=None): :param array_like x_val: input x contour coordinates :param array_like y_val: input y contour coordinates :param int num_fac: factor to increase lengths of output coordinates - :param int,None fixed_size: if define, it will used to set sampling + :param int,None fixed_size: if defined, will be used to set sampling """ nb = x_val.shape[0] # Get distances From 6bce49abe40204aa5628e490bf288d66880e9dd6 Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Fri, 18 Jun 2021 09:12:13 +0200 Subject: [PATCH 165/249] typo and allow to choose netcdf format at output --- .../pet_eddy_detection_ACC.py | 13 +++------- examples/06_grid_manipulation/pet_lavd.py | 11 +++----- examples/07_cube_manipulation/pet_fsle_med.py | 2 +- .../16_network/pet_replay_segmentation.py | 8 +----- examples/16_network/pet_segmentation_anim.py | 3 +-- src/py_eddy_tracker/__init__.py | 13 +++------- src/py_eddy_tracker/appli/eddies.py | 15 +++-------- src/py_eddy_tracker/appli/network.py | 4 +-- src/py_eddy_tracker/observations/groups.py | 1 - src/py_eddy_tracker/observations/network.py | 25 +++++-------------- .../observations/observation.py | 24 ++++-------------- src/py_eddy_tracker/observations/tracking.py | 5 +--- tests/test_grid.py | 10 +------- 13 files changed, 30 insertions(+), 104 deletions(-) diff --git a/examples/02_eddy_identification/pet_eddy_detection_ACC.py b/examples/02_eddy_identification/pet_eddy_detection_ACC.py index c799a45e..e6c5e381 100644 --- a/examples/02_eddy_identification/pet_eddy_detection_ACC.py +++ b/examples/02_eddy_identification/pet_eddy_detection_ACC.py @@ -65,8 +65,7 @@ def set_fancy_labels(fig, ticklabelsize=14, labelsize=14, labelweight="semibold" y_name="latitude", # Manual area subset indexs=dict( - latitude=slice(100 - margin, 220 + margin), - longitude=slice(0, 230 + margin), + latitude=slice(100 - margin, 220 + margin), longitude=slice(0, 230 + margin), ), ) g_raw = RegularGridDataset(**kw_data) @@ -188,16 +187,10 @@ def set_fancy_labels(fig, ticklabelsize=14, labelsize=14, labelweight="semibold" ax.set_ylabel("With filter") ax.plot( - a_[field][i_a] * factor, - a[field][j_a] * factor, - "r.", - label="Anticyclonic", + a_[field][i_a] * factor, a[field][j_a] * factor, "r.", label="Anticyclonic", ) ax.plot( - c_[field][i_c] * factor, - c[field][j_c] * factor, - "b.", - label="Cyclonic", + c_[field][i_c] * factor, c[field][j_c] * factor, "b.", label="Cyclonic", ) ax.set_aspect("equal"), ax.grid() ax.plot((0, 1000), (0, 1000), "g") diff --git a/examples/06_grid_manipulation/pet_lavd.py b/examples/06_grid_manipulation/pet_lavd.py index ed21738f..d96c0b06 100644 --- a/examples/06_grid_manipulation/pet_lavd.py +++ b/examples/06_grid_manipulation/pet_lavd.py @@ -142,8 +142,9 @@ def update(i_frame): kw_video = dict(frames=arange(nb_time), interval=1000.0 / step_by_day / 2, blit=True) fig, ax, txt = start_ax(dpi=60) -x_g_, y_g_ = arange(0 - step / 2, 36 + step / 2, step), arange( - 28 - step / 2, 46 + step / 2, step +x_g_, y_g_ = ( + arange(0 - step / 2, 36 + step / 2, step), + arange(28 - step / 2, 46 + step / 2, step), ) # pcolorfast will be faster than pcolormesh, we could use pcolorfast due to x and y are regular pcolormesh = ax.pcolorfast(x_g_, y_g_, lavd, **kw_vorticity) @@ -158,11 +159,7 @@ def update(i_frame): # Format LAVD data lavd = RegularGridDataset.with_array( coordinates=("lon", "lat"), - datas=dict( - lavd=lavd.T, - lon=x_g, - lat=y_g, - ), + datas=dict(lavd=lavd.T, lon=x_g, lat=y_g,), centered=True, ) diff --git a/examples/07_cube_manipulation/pet_fsle_med.py b/examples/07_cube_manipulation/pet_fsle_med.py index cc221cf7..b128286a 100644 --- a/examples/07_cube_manipulation/pet_fsle_med.py +++ b/examples/07_cube_manipulation/pet_fsle_med.py @@ -27,7 +27,7 @@ # ADT in med # ---------- # :py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_cube` method is -# made for data stores in time cube, you could use also +# made for data stores in time cube, you could use also # :py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_list` method to # load data-cube from multiple file. c = GridCollection.from_netcdf_cube( diff --git a/examples/16_network/pet_replay_segmentation.py b/examples/16_network/pet_replay_segmentation.py index 757854d5..d6b4568b 100644 --- a/examples/16_network/pet_replay_segmentation.py +++ b/examples/16_network/pet_replay_segmentation.py @@ -149,13 +149,7 @@ def get_obs(dataset): n_.median_filter(15, "time", "latitude") kw["s"] = (n_.radius_e * 1e-3) ** 2 / 30 ** 2 * 20 m = n_.scatter_timeline( - ax, - "shape_error_e", - vmin=14, - vmax=70, - **kw, - yfield="lon", - method="all", + ax, "shape_error_e", vmin=14, vmax=70, **kw, yfield="lon", method="all", ) ax.set_ylabel("Longitude") cb = update_axes(ax, m["scatter"]) diff --git a/examples/16_network/pet_segmentation_anim.py b/examples/16_network/pet_segmentation_anim.py index 340163a1..503229e7 100644 --- a/examples/16_network/pet_segmentation_anim.py +++ b/examples/16_network/pet_segmentation_anim.py @@ -96,8 +96,7 @@ def update(i_frame): indices_frames = INDICES[i_frame] mappable_CONTOUR.set_data( - e.contour_lon_e[indices_frames], - e.contour_lat_e[indices_frames], + e.contour_lon_e[indices_frames], e.contour_lat_e[indices_frames], ) mappable_CONTOUR.set_color(cmap.colors[tr[indices_frames] % len(cmap.colors)]) return (mappable_tracks,) diff --git a/src/py_eddy_tracker/__init__.py b/src/py_eddy_tracker/__init__.py index 46946e77..d5db40f6 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -409,20 +409,14 @@ def parse_args(self, *args, **kwargs): nc_name="previous_cost", nc_type="float32", nc_dims=("obs",), - nc_attr=dict( - long_name="Previous cost for previous observation", - comment="", - ), + nc_attr=dict(long_name="Previous cost for previous observation", comment="",), ), next_cost=dict( attr_name=None, nc_name="next_cost", nc_type="float32", nc_dims=("obs",), - nc_attr=dict( - long_name="Next cost for next observation", - comment="", - ), + nc_attr=dict(long_name="Next cost for next observation", comment="",), ), n=dict( attr_name=None, @@ -633,8 +627,7 @@ def parse_args(self, *args, **kwargs): nc_type="f4", nc_dims=("obs",), nc_attr=dict( - long_name="Log base 10 background chlorophyll", - units="Log(Chl/[mg/m^3])", + long_name="Log base 10 background chlorophyll", units="Log(Chl/[mg/m^3])", ), ), year=dict( diff --git a/src/py_eddy_tracker/appli/eddies.py b/src/py_eddy_tracker/appli/eddies.py index d5a727f9..d30ef259 100644 --- a/src/py_eddy_tracker/appli/eddies.py +++ b/src/py_eddy_tracker/appli/eddies.py @@ -367,8 +367,7 @@ def track( logger.info("Longer track saved have %d obs", c.nb_obs_by_tracks.max()) logger.info( - "The mean length is %d observations for long track", - c.nb_obs_by_tracks.mean(), + "The mean length is %d observations for long track", c.nb_obs_by_tracks.mean(), ) long_track.write_file(**kw_write) @@ -378,14 +377,7 @@ def track( def get_group( - dataset1, - dataset2, - index1, - index2, - score, - invalid=2, - low=10, - high=60, + dataset1, dataset2, index1, index2, score, invalid=2, low=10, high=60, ): group1, group2 = dict(), dict() m_valid = (score * 100) >= invalid @@ -494,8 +486,7 @@ def get_values(v, dataset): ] labels = dict( - high=f"{high:0.0f} <= high", - low=f"{invalid:0.0f} <= low < {low:0.0f}", + high=f"{high:0.0f} <= high", low=f"{invalid:0.0f} <= low < {low:0.0f}", ) keys = [labels.get(key, key) for key in list(gr_ref.values())[0].keys()] diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index 5c4cdcaf..c1a752ee 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -76,9 +76,7 @@ def subset_network(): help="Remove short dead end, first is for minimal obs number and second for minimal segment time to keep", ) parser.add_argument( - "--remove_trash", - action="store_true", - help="Remove trash (network id == 0)", + "--remove_trash", action="store_true", help="Remove trash (network id == 0)", ) parser.add_argument( "-p", diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index c0924cb3..e77c81fe 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -100,7 +100,6 @@ def particle_candidate(x, y, c, eddies, t_start, i_target, pct, **kwargs): :params dict kwargs: dict of params given to `advect` """ - # Obs from initial time m_start = eddies.time == t_start diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 4f9af0b3..a8b1ebc0 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -679,13 +679,7 @@ def display_timeline( """ self.only_one_network() j = 0 - line_kw = dict( - ls="-", - marker="+", - markersize=6, - zorder=1, - lw=3, - ) + line_kw = dict(ls="-", marker="+", markersize=6, zorder=1, lw=3,) line_kw.update(kwargs) mappables = dict(lines=list()) @@ -918,10 +912,7 @@ def event_map(self, ax, **kwargs): """Add the merging and splitting events to a map""" j = 0 mappables = dict() - symbol_kw = dict( - markersize=10, - color="k", - ) + symbol_kw = dict(markersize=10, color="k",) symbol_kw.update(kwargs) symbol_kw_split = symbol_kw.copy() symbol_kw_split["markersize"] += 4 @@ -950,13 +941,7 @@ def event_map(self, ax, **kwargs): return mappables def scatter( - self, - ax, - name="time", - factor=1, - ref=None, - edgecolor_cycle=None, - **kwargs, + self, ax, name="time", factor=1, ref=None, edgecolor_cycle=None, **kwargs, ): """ This function scatters the path of each network, with the merging and splitting events @@ -1400,7 +1385,9 @@ def segment_coherence( .. code-block:: python def date2file(julian_day): - date = datetime.timedelta(days=julian_day) + datetime.datetime(1950, 1, 1) + date = datetime.timedelta(days=julian_day) + datetime.datetime( + 1950, 1, 1 + ) return f"/tmp/dt_global_allsat_phy_l4_{date.strftime('%Y%m%d')}.nc" diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 557c0279..0be29fe7 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -701,11 +701,7 @@ def load_file(cls, filename, **kwargs): .. code-block:: python kwargs_latlon_300 = dict( - include_vars=[ - "longitude", - "latitude", - ], - indexs=dict(obs=slice(0, 300)), + include_vars=["longitude", "latitude",], indexs=dict(obs=slice(0, 300)), ) small_dataset = TrackEddiesObservations.load_file( filename, **kwargs_latlon_300 @@ -1676,7 +1672,8 @@ def write_file( handler = zarr.open(filename, "w") self.to_zarr(handler, **kwargs) else: - with Dataset(filename, "w", format="NETCDF4") as handler: + nc_format = kwargs.pop("format", "NETCDF4") + with Dataset(filename, "w", format=nc_format) as handler: self.to_netcdf(handler, **kwargs) @property @@ -1967,11 +1964,7 @@ def bins_stat(self, xname, bins=None, yname=None, method=None, mask=None): def format_label(self, label): t0, t1 = self.period - return label.format( - t0=t0, - t1=t1, - nb_obs=len(self), - ) + return label.format(t0=t0, t1=t1, nb_obs=len(self),) def display(self, ax, ref=None, extern_only=False, intern_only=False, **kwargs): """Plot the speed and effective (dashed) contour of the eddies @@ -2330,14 +2323,7 @@ def grid_count_pixel_in( x_, y_ = reduce_size(x_, y_) v = create_vertice(x_, y_) (x_start, x_stop), (y_start, y_stop) = bbox_indice_regular( - v, - x_bounds, - y_bounds, - xstep, - ystep, - N, - is_circular, - x_size, + v, x_bounds, y_bounds, xstep, ystep, N, is_circular, x_size, ) i, j = get_pixel_in_regular(v, x_c, y_c, x_start, x_stop, y_start, y_stop) grid_count_(grid, i, j) diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index b632270c..58514eb2 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -574,10 +574,7 @@ def close_tracks(self, other, nb_obs_min=10, **kwargs): def format_label(self, label): t0, t1 = self.period return label.format( - t0=t0, - t1=t1, - nb_obs=len(self), - nb_tracks=(self.nb_obs_by_track != 0).sum(), + t0=t0, t1=t1, nb_obs=len(self), nb_tracks=(self.nb_obs_by_track != 0).sum(), ) def plot(self, ax, ref=None, **kwargs): diff --git a/tests/test_grid.py b/tests/test_grid.py index 2c89550a..34187357 100644 --- a/tests/test_grid.py +++ b/tests/test_grid.py @@ -7,15 +7,7 @@ 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 = Path(((-X, 0), (X, 0), (X, X), (-X, X), (-X, 0),)) # contour From 0834ed25301e0672957a0277f3e3f30e69fd6352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Fri, 18 Jun 2021 09:45:36 +0200 Subject: [PATCH 166/249] - changed log format, too many tabs - adding more logs - change generator time step on GridCollection, to work it needed more files than necessary. - added coherence computation --- CHANGELOG.rst | 3 + src/py_eddy_tracker/__init__.py | 4 +- src/py_eddy_tracker/dataset/grid.py | 22 +- src/py_eddy_tracker/observations/groups.py | 66 ++++- src/py_eddy_tracker/observations/network.py | 263 ++++++++++-------- .../observations/observation.py | 1 + 6 files changed, 213 insertions(+), 146 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 80def41c..87b5d870 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -12,9 +12,12 @@ Changed ^^^^^^^ Fixed ^^^^^ +- GridCollection get_next_time_step & get_previous_time_step needed more files to work in the dataset list. + The loop needed explicitly self.dataset[i+-1] even when i==0, therefore indice went out of range Added ^^^^^ + [3.4.0] - 2021-03-29 -------------------- Changed diff --git a/src/py_eddy_tracker/__init__.py b/src/py_eddy_tracker/__init__.py index 46946e77..e17d0e2f 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -32,9 +32,7 @@ def start_logger(): - FORMAT_LOG = ( - "%(levelname)-8s %(asctime)s %(module)s.%(funcName)s :\n\t\t\t\t\t%(message)s" - ) + FORMAT_LOG = "%(levelname)-8s %(asctime)s %(module)s.%(funcName)s :\n\t%(message)s" logger = logging.getLogger("pet") if len(logger.handlers) == 0: # set up logging to CONSOLE diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index bd9e70d3..41522d14 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -2257,11 +2257,13 @@ def from_netcdf_cube(cls, filename, x_name, y_name, t_name, heigth=None): @classmethod def from_netcdf_list(cls, filenames, t, x_name, y_name, indexs=None, heigth=None): new = cls() - for i, t in enumerate(t): - d = RegularGridDataset(filenames[i], x_name, y_name, indexs=indexs) + for i, _t in enumerate(t): + filename = filenames[i] + logger.debug(f"load file {i:02d}/{len(t)} t={_t} : {filename}") + d = RegularGridDataset(filename, x_name, y_name, indexs=indexs) if heigth is not None: d.add_uv(heigth) - new.datasets.append((t, d)) + new.datasets.append((_t, d)) return new def shift_files(self, t, filename, heigth=None, **rgd_kwargs): @@ -2273,6 +2275,7 @@ def shift_files(self, t, filename, heigth=None, **rgd_kwargs): if heigth is not None: d.add_uv(heigth) self.datasets.append((t, d)) + logger.debug(f"shift and adding i={len(self.datasets)} t={t} : {filename}") def interp(self, grid_name, t, lons, lats, method="bilinear"): """ @@ -2433,6 +2436,7 @@ def advect( else: mask_particule += isnan(x) + isnan(y) while True: + logger.debug(f"advect : t={t}") if (backward and t <= t1) or (not backward and t >= t1): t0, u0, v0, m0 = t1, u1, v1, m1 t1, d1 = generator.__next__() @@ -2459,25 +2463,21 @@ def advect( yield t, x, y def get_next_time_step(self, t_init): - first = True for i, (t, dataset) in enumerate(self.datasets): if t < t_init: continue - if first: - first = False - yield self.datasets[i - 1] + + logger.debug(f"i={i}, t={t}, dataset={dataset}") yield t, dataset def get_previous_time_step(self, t_init): - first = True i = len(self.datasets) for t, dataset in reversed(self.datasets): i -= 1 if t > t_init: continue - if first: - first = False - yield self.datasets[i + 1] + + logger.debug(f"i={i}, t={t}, dataset={dataset}") yield t, dataset diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index c0924cb3..98e085c0 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -3,9 +3,10 @@ from numba import njit from numba import types as nb_types -from numpy import arange, int32, interp, median, where, zeros +from numpy import arange, int32, interp, median, where, zeros, meshgrid, concatenate from .observation import EddiesObservations +from ..poly import group_obs logger = logging.getLogger("pet") @@ -87,7 +88,53 @@ def advect(x, y, c, t0, n_days): return t, x, y -def particle_candidate(x, y, c, eddies, t_start, i_target, pct, **kwargs): +def create_particles(eddies, step): + """create particles only inside speed contour. Avoir creating too large numpy arrays, only to me masked + + :param eddies: network where eddies are + :type eddies: network + :param step: step for particles + :type step: float + :return: lon, lat and indices of particles in contour speed + :rtype: tuple(np.array) + """ + + lon = eddies.contour_lon_s + lat = eddies.contour_lat_s + + # compute bounding boxes of each eddies + lonMins = lon.min(axis=1) + lonMins = lonMins - (lonMins % step) + lonMaxs = lon.max(axis=1) + lonMaxs = lonMaxs - (lonMaxs % step) + step * 2 + + latMins = lat.min(axis=1) + latMins = latMins - (latMins % step) + latMaxs = lat.max(axis=1) + latMaxs = latMaxs - (latMaxs % step) + step * 2 + + lon = [] + lat = [] + # for each eddies, create mesh with particles then concatenate + for lonMin, lonMax, latMin, latMax in zip(lonMins, lonMaxs, latMins, latMaxs): + x0, y0 = meshgrid(arange(lonMin, lonMax, step), arange(latMin, latMax, step)) + + x0, y0 = x0.reshape(-1), y0.reshape(-1) + lon.append(x0) + lat.append(y0) + + x = concatenate(lon) + y = concatenate(lat) + + _, i = group_obs(x, y, 1, 360) + x, y = x[i], y[i] + + i_start = eddies.contains(x, y, intern=True) + m = i_start != -1 + return x[m], y[m], i_start[m] + + +def particle_candidate(c, eddies, step_mesh, t_start, i_target, pct, **kwargs): """Select particles within eddies, advect them, return target observation and associated percentages :param np.array(float) x: longitude of particles @@ -100,27 +147,28 @@ def particle_candidate(x, y, c, eddies, t_start, i_target, pct, **kwargs): :params dict kwargs: dict of params given to `advect` """ - # Obs from initial time m_start = eddies.time == t_start - e = eddies.extract_with_mask(m_start) + # to be able to get global index translate_start = where(m_start)[0] - # Identify particle in eddies (only in core) - i_start = e.contains(x, y, intern=True) - m = i_start != -1 - x, y, i_start = x[m], y[m], i_start[m] - # Advect + x, y, i_start = create_particles(e, step_mesh) + + # Advection t_end, x, y = advect(x, y, c, t_start, **kwargs) + # eddies at last date m_end = eddies.time == t_end / 86400 e_end = eddies.extract_with_mask(m_end) + # to be able to get global index translate_end = where(m_end)[0] + # Id eddies for each alive particle (in core and extern) i_end = e_end.contains(x, y) + # compute matrix and fill target array get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 0e5b9576..747bd976 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -3,11 +3,10 @@ Class to create network of observations """ import logging +import time from glob import glob -import zarr from numba import njit -from numba import types as nb_types from numpy import ( arange, array, @@ -16,7 +15,6 @@ concatenate, empty, in1d, - meshgrid, ones, uint16, uint32, @@ -27,7 +25,7 @@ from ..dataset.grid import GridCollection from ..generic import build_index, wrap_longitude -from ..poly import bbox_intersection, group_obs, vertice_overlap +from ..poly import bbox_intersection, vertice_overlap from .groups import GroupEddiesObservations, get_missing_indices, particle_candidate from .observation import EddiesObservations from .tracking import TrackEddiesObservations, track_loess_filter, track_median_filter @@ -1276,15 +1274,14 @@ def extract_segment(self, segments, absolute=False): mask[i] = False return self.extract_with_mask(mask) - def extract_with_period(self, period): + def get_mask_with_period(self, period): """ - Extract within a time period + obtain mask within a time period :param (int,int) period: two dates to define the period, must be specified from 1/1/1950 - :return: Return all eddy trajectories in period - :rtype: NetworkObservations + :return: mask where period is defined + :rtype: np.array(bool) - .. minigallery:: py_eddy_tracker.NetworkObservations.extract_with_period """ dataset_period = self.period p_min, p_max = period @@ -1298,7 +1295,57 @@ def extract_with_period(self, period): mask *= self.time <= p_max elif p_max < 0: mask *= self.time <= (dataset_period[1] + p_max) - return self.extract_with_mask(mask) + return mask + + def extract_with_period(self, period): + """ + Extract within a time period + + :param (int,int) period: two dates to define the period, must be specified from 1/1/1950 + :return: Return all eddy trajectories in period + :rtype: NetworkObservations + + .. minigallery:: py_eddy_tracker.NetworkObservations.extract_with_period + """ + + return self.extract_with_mask(self.get_mask_with_period(period)) + + def extract_light_with_mask(self, mask): + """extract data with mask, but only with variables used for coherence, aka self.array_variables + + :param mask: mask used to extract + :type mask: np.array(bool) + :return: new EddiesObservation with data wanted + :rtype: self + """ + + if isinstance(mask, slice): + nb_obs = mask.stop - mask.start + else: + nb_obs = mask.sum() + + # only time & contour_lon/lat_e/s + variables = ["time"] + self.array_variables + new = self.__class__( + size=nb_obs, + track_extra_variables=[], + track_array_variables=self.track_array_variables, + array_variables=self.array_variables, + only_variables=variables, + raw_data=self.raw_data, + ) + new.sign_type = self.sign_type + if nb_obs == 0: + logger.warning("Empty dataset will be created") + else: + logger.info( + f"{nb_obs} observations will be extracted ({nb_obs / self.shape[0]:.3%})" + ) + + for field in variables: + logger.debug("Copy of field %s ...", field) + new.obs[field] = self.obs[field][mask] + return new def extract_with_mask(self, mask): """ @@ -1317,7 +1364,7 @@ def extract_with_mask(self, mask): if nb_obs == 0: logger.warning("Empty dataset will be created") else: - logger.info( + logger.debug( f"{nb_obs} observations will be extracted ({nb_obs / self.shape[0]:.3%})" ) for field in self.obs.dtype.descr: @@ -1372,156 +1419,126 @@ def analysis_coherence( return network_clean, res - def segment_coherence( - self, - date_function, - uv_params, - advection_mode="both", - dt_advect=14, - step_mesh=1.0 / 50, - output_name=None, + def segment_coherence_backward( + self, date_function, uv_params, n_days=14, step_mesh=1.0 / 50, output_name=None, ): """ - Percentage of particules and their targets after forward or/and backward advection from a specific eddy. + Percentage of particules and their targets after backward advection from a specific eddy. :param callable date_function: python function, takes as param `int` (julian day) and return data filename associated to the date (see note) :param dict uv_params: dict of parameters used by :py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_list` - :param str advection_mode: "backward", "forward" or "both" - :param int dt_advect: days for advection + :param int n_days: days for advection :param float step_mesh: step for particule mesh in degrees - :param str output_name: if not None, name of file saved in zarr. Else, data will not be saved - :return: list of 2 or 4 array (depending if forward, backward or both) with segment matchs, and percents + :return: observations matchs, and percents .. note:: the param `date_function` should be something like : .. code-block:: python def date2file(julian_day): - date = datetime.timedelta(days=julian_day) + datetime.datetime(1950, 1, 1) - - return f"/tmp/dt_global_allsat_phy_l4_{date.strftime('%Y%m%d')}.nc" + date = datetime.timedelta(days=julian_day) + datetime.datetime( + 1950, 1, 1 + ) + return f"/tmp/dt_global_{date.strftime('%Y%m%d')}.nc" """ - if advection_mode in ["both", "forward"]: - itf_final = -ones((self.obs.size, 2), dtype="i4") - ptf_final = zeros((self.obs.size, 2), dtype="i1") + itb_final = -ones((self.obs.size, 2), dtype="i4") + ptb_final = zeros((self.obs.size, 2), dtype="i1") - if advection_mode in ["both", "backward"]: - itb_final = -ones((self.obs.size, 2), dtype="i4") - ptb_final = zeros((self.obs.size, 2), dtype="i1") + t_start, t_end = self.period - for slice_track, b0, _ in self.iter_on(self.track): - if b0 == 0: - continue - - sub_networks = self.network(b0) + dates = arange(t_start, t_start + n_days + 1) + first_files = [date_function(x) for x in dates] - # find extremum to create a mesh of particles - lon = sub_networks.contour_lon_s - lonMin = lon.min() - 0.1 - lonMax = lon.max() + 0.1 + c = GridCollection.from_netcdf_list(first_files, dates, **uv_params) + first = True + range_start = t_start + n_days + range_end = t_end + 1 - lat = sub_networks.contour_lat_s - latMin = lat.min() - 0.1 - latMax = lat.max() + 0.1 + for _t in range(t_start + n_days, t_end + 1): + _timestamp = time.time() + t_shift = _t - x0, y0 = meshgrid( - arange(lonMin, lonMax, step_mesh), arange(latMin, latMax, step_mesh) + # skip first shift, because already included + if first: + first = False + else: + # add next date to GridCollection and delete last date + c.shift_files(t_shift, date_function(int(t_shift)), **uv_params) + particle_candidate( + c, self, step_mesh, _t, itb_final, ptb_final, n_days=-n_days + ) + logger.info( + f"coherence {_t} / {range_end-1} ({(_t - range_start) / (range_end - range_start-1):.1%}) : {time.time()-_timestamp:5.2f}s" ) - x0, y0 = x0.reshape(-1), y0.reshape(-1) - _, i = group_obs(x0, y0, 1, 360) - x0, y0 = x0[i], y0[i] - - t_start, t_end = sub_networks.period - shape = (sub_networks.obs.size, 2) - - if advection_mode in ["both", "forward"]: - - # first dates to load. - dates = arange(t_start - 1, t_start + dt_advect + 2) - # files associated with dates - first_files = [date_function(x) for x in dates] - - c = GridCollection.from_netcdf_list(first_files, dates, **uv_params) - - i_target_f = -ones(shape, dtype="i4") - pct_target_f = zeros(shape, dtype="i1") - - for _t in range(t_start, t_end - dt_advect + 1): - t_shift = _t + dt_advect + 2 - - # add next date to GridCollection and delete last date - c.shift_files(t_shift, date_function(int(t_shift)), **uv_params) - particle_candidate( - x0, - y0, - c, - sub_networks, - _t, - i_target_f, - pct_target_f, - delta_t=dt_advect, - ) - itf_final[slice_track] = i_target_f - ptf_final[slice_track] = pct_target_f + return itb_final, ptb_final - if advection_mode in ["both", "backward"]: + def segment_coherence_forward( + self, date_function, uv_params, n_days=14, step_mesh=1.0 / 50, + ): - # first dates to load. - dates = arange(t_start - 1, t_start + dt_advect + 2) - # files associated with dates - first_files = [date_function(x) for x in dates] + """ + Percentage of particules and their targets after forward advection from a specific eddy. - c = GridCollection.from_netcdf_list(first_files, dates, **uv_params) + :param callable date_function: python function, takes as param `int` (julian day) and return + data filename associated to the date (see note) + :param dict uv_params: dict of parameters used by + :py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_list` + :param int n_days: days for advection + :param float step_mesh: step for particule mesh in degrees + :return: observations matchs, and percents - i_target_b = -ones(shape, dtype="i4") - pct_target_b = zeros(shape, dtype="i1") + .. note:: the param `date_function` should be something like : - for _t in range(t_start + dt_advect + 1, t_end + 1): - t_shift = _t + 1 + .. code-block:: python - # add next date to GridCollection and delete last date - c.shift_files(t_shift, date_function(int(t_shift)), **uv_params) - particle_candidate( - x0, - y0, - c, - sub_networks, - _t, - i_target_b, - pct_target_b, - delta_t=-dt_advect, + def date2file(julian_day): + date = datetime.timedelta(days=julian_day) + datetime.datetime( + 1950, 1, 1 ) - itb_final[slice_track] = i_target_b - ptb_final[slice_track] = pct_target_b + return f"/tmp/dt_global_{date.strftime('%Y%m%d')}.nc" + """ + + itf_final = -ones((self.obs.size, 2), dtype="i4") + ptf_final = zeros((self.obs.size, 2), dtype="i1") - if output_name is not None: - zg = zarr.open(output_name, "w") + t_start, t_end = self.period + # if begin is not None and begin > t_start: + # t_start = begin + # if end is not None and end < t_end: + # t_end = end - # zarr compression parameters - params_seg = dict() - params_pct = dict() + dates = arange(t_start, t_start + n_days + 1) + first_files = [date_function(x) for x in dates] - res = [] - if advection_mode in ["forward", "both"]: - res = res + [itf_final, ptf_final] - if output_name is not None: - zg.array("i_target_forward", itf_final, **params_seg) - zg.array("pct_target_forward", ptf_final, **params_pct) + c = GridCollection.from_netcdf_list(first_files, dates, **uv_params) + first = True + range_start = t_start + range_end = t_end - n_days + 1 - if advection_mode in ["backward", "both"]: - res = res + [itb_final, ptb_final] - if output_name is not None: - zg.array("i_target_backward", itb_final, **params_seg) - zg.array("pct_target_backward", ptb_final, **params_pct) + for _t in range(range_start, range_end): + _timestamp = time.time() + t_shift = _t + n_days - return res + # skip first shift, because already included + if first: + first = False + else: + # add next date to GridCollection and delete last date + c.shift_files(t_shift, date_function(int(t_shift)), **uv_params) + particle_candidate( + c, self, step_mesh, _t, itf_final, ptf_final, n_days=n_days + ) + logger.info( + f"coherence {_t} / {range_end-1} ({(_t - range_start) / (range_end - range_start-1):.1%}) : {time.time()-_timestamp:5.2f}s" + ) + return itf_final, ptf_final class Network: diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 3d91ad42..e8998dd6 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -723,6 +723,7 @@ def load_file(cls, filename, **kwargs): zarr_file = filename_.endswith(end) else: zarr_file = False + logger.info(f"loading file '{filename}'") if zarr_file: return cls.load_from_zarr(filename, **kwargs) else: From fe79f1bad737e17aa4c5c5f5715c041dec91d4a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Fri, 18 Jun 2021 14:32:03 +0200 Subject: [PATCH 167/249] correction of example --- examples/16_network/pet_follow_particle.py | 10 ++-------- src/py_eddy_tracker/observations/groups.py | 2 -- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/examples/16_network/pet_follow_particle.py b/examples/16_network/pet_follow_particle.py index e5451daa..36639d3f 100644 --- a/examples/16_network/pet_follow_particle.py +++ b/examples/16_network/pet_follow_particle.py @@ -128,12 +128,6 @@ def update(frame): # ^^^^^^^^^^^^^^^^^^ step = 1 / 60.0 -x, y = meshgrid(arange(24, 36, step), arange(31, 36, step)) -x0, y0 = x.reshape(-1), y.reshape(-1) -# Pre-order to speed up -_, i = group_obs(x0, y0, 1, 360) -x0, y0 = x0[i], y0[i] - t_start, t_end = n.period dt = 14 @@ -141,12 +135,12 @@ def update(frame): # Forward run i_target_f, pct_target_f = -ones(shape, dtype="i4"), zeros(shape, dtype="i1") for t in range(t_start, t_end - dt): - particle_candidate(x0, y0, c, n, t, i_target_f, pct_target_f, n_days=dt) + particle_candidate(c, n, step, t, i_target_f, pct_target_f, n_days=dt) # Backward run i_target_b, pct_target_b = -ones(shape, dtype="i4"), zeros(shape, dtype="i1") for t in range(t_start + dt, t_end): - particle_candidate(x0, y0, c, n, t, i_target_b, pct_target_b, n_days=-dt) + particle_candidate(c, n, step, t, i_target_b, pct_target_b, n_days=-dt) # %% fig = plt.figure(figsize=(10, 10)) diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index 98e085c0..08053331 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -137,8 +137,6 @@ def create_particles(eddies, step): def particle_candidate(c, eddies, step_mesh, t_start, i_target, pct, **kwargs): """Select particles within eddies, advect them, return target observation and associated percentages - :param np.array(float) x: longitude of particles - :param np.array(float) y: latitude of particles :param `~py_eddy_tracker.dataset.grid.GridCollection` c: GridCollection with speed for particles :param GroupEddiesObservations eddies: GroupEddiesObservations considered :param int t_start: julian day of the advection From 57408b8f1cee5832e6a40c1ac77c7790de0220ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Mon, 21 Jun 2021 12:35:24 +0200 Subject: [PATCH 168/249] flake8 corrections --- src/py_eddy_tracker/observations/groups.py | 2 +- src/py_eddy_tracker/observations/network.py | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index 08053331..0ecfd515 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -89,7 +89,7 @@ def advect(x, y, c, t0, n_days): def create_particles(eddies, step): - """create particles only inside speed contour. Avoir creating too large numpy arrays, only to me masked + """create particles only inside speed contour. Avoid creating too large numpy arrays, only to me masked :param eddies: network where eddies are :type eddies: network diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 747bd976..8d9b40b9 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -1472,9 +1472,10 @@ def date2file(julian_day): particle_candidate( c, self, step_mesh, _t, itb_final, ptb_final, n_days=-n_days ) - logger.info( - f"coherence {_t} / {range_end-1} ({(_t - range_start) / (range_end - range_start-1):.1%}) : {time.time()-_timestamp:5.2f}s" - ) + logger.info(( + f"coherence {_t} / {range_end-1} ({(_t - range_start) / (range_end - range_start-1):.1%})" + f" : {time.time()-_timestamp:5.2f}s" + )) return itb_final, ptb_final @@ -1535,9 +1536,10 @@ def date2file(julian_day): particle_candidate( c, self, step_mesh, _t, itf_final, ptf_final, n_days=n_days ) - logger.info( - f"coherence {_t} / {range_end-1} ({(_t - range_start) / (range_end - range_start-1):.1%}) : {time.time()-_timestamp:5.2f}s" - ) + logger.info(( + f"coherence {_t} / {range_end-1} ({(_t - range_start) / (range_end - range_start-1):.1%})" + f" : {time.time()-_timestamp:5.2f}s" + )) return itf_final, ptf_final From 7b4aba66a4477bad9788844fddc2b29e4e6faa46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Mon, 21 Jun 2021 12:38:38 +0200 Subject: [PATCH 169/249] flake correction --- examples/16_network/pet_follow_particle.py | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/16_network/pet_follow_particle.py b/examples/16_network/pet_follow_particle.py index 36639d3f..a2e72d5a 100644 --- a/examples/16_network/pet_follow_particle.py +++ b/examples/16_network/pet_follow_particle.py @@ -16,7 +16,6 @@ from py_eddy_tracker.dataset.grid import GridCollection from py_eddy_tracker.observations.groups import particle_candidate from py_eddy_tracker.observations.network import NetworkObservations -from py_eddy_tracker.poly import group_obs start_logger().setLevel("ERROR") From 3a75c0157bc895f16dd8bfdb1a3af17b1e9a2c4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Mon, 21 Jun 2021 21:34:18 +0200 Subject: [PATCH 170/249] better create_particles --- requirements.txt | 2 +- src/py_eddy_tracker/observations/groups.py | 53 +++++++++------------- 2 files changed, 22 insertions(+), 33 deletions(-) diff --git a/requirements.txt b/requirements.txt index 9539c555..097e786a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ matplotlib netCDF4 -numba +numba>=0.53 numpy opencv-python pint diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index 0ecfd515..3d028e12 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -3,10 +3,10 @@ from numba import njit from numba import types as nb_types -from numpy import arange, int32, interp, median, where, zeros, meshgrid, concatenate +from numpy import arange, array, int32, interp, median, where, zeros +from ..poly import create_vertice, reduce_size, winding_number_poly from .observation import EddiesObservations -from ..poly import group_obs logger = logging.getLogger("pet") @@ -88,6 +88,24 @@ def advect(x, y, c, t0, n_days): return t, x, y +@njit(cache=True) +def _create_meshed_particles(lons, lats, step): + x_out, y_out, i_out = list(), list(), list() + for i, (lon, lat) in enumerate(zip(lons, lats)): + lon_min, lon_max = lon.min(), lon.max() + lat_min, lat_max = lat.min(), lat.max() + lon_min -= lon_min % step + lon_max -= lon_max % step - step * 2 + lat_min -= lat_min % step + lat_max -= lat_max % step - step * 2 + + for x in arange(lon_min, lon_max, step): + for y in arange(lat_min, lat_max, step): + if winding_number_poly(x, y, create_vertice(*reduce_size(lon, lat))): + x_out.append(x), y_out.append(y), i_out.append(i) + return array(x_out), array(y_out), array(i_out) + + def create_particles(eddies, step): """create particles only inside speed contour. Avoid creating too large numpy arrays, only to me masked @@ -102,36 +120,7 @@ def create_particles(eddies, step): lon = eddies.contour_lon_s lat = eddies.contour_lat_s - # compute bounding boxes of each eddies - lonMins = lon.min(axis=1) - lonMins = lonMins - (lonMins % step) - lonMaxs = lon.max(axis=1) - lonMaxs = lonMaxs - (lonMaxs % step) + step * 2 - - latMins = lat.min(axis=1) - latMins = latMins - (latMins % step) - latMaxs = lat.max(axis=1) - latMaxs = latMaxs - (latMaxs % step) + step * 2 - - lon = [] - lat = [] - # for each eddies, create mesh with particles then concatenate - for lonMin, lonMax, latMin, latMax in zip(lonMins, lonMaxs, latMins, latMaxs): - x0, y0 = meshgrid(arange(lonMin, lonMax, step), arange(latMin, latMax, step)) - - x0, y0 = x0.reshape(-1), y0.reshape(-1) - lon.append(x0) - lat.append(y0) - - x = concatenate(lon) - y = concatenate(lat) - - _, i = group_obs(x, y, 1, 360) - x, y = x[i], y[i] - - i_start = eddies.contains(x, y, intern=True) - m = i_start != -1 - return x[m], y[m], i_start[m] + return _create_meshed_particles(lon, lat, step) def particle_candidate(c, eddies, step_mesh, t_start, i_target, pct, **kwargs): From 2f20ca6b6774a9983afbb9e542dee3f5c5c97b93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Mon, 21 Jun 2021 22:04:59 +0200 Subject: [PATCH 171/249] create particles in class method --- src/py_eddy_tracker/observations/groups.py | 40 +------------------ .../observations/observation.py | 32 +++++++++++++++ 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index 3d028e12..64a81a36 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -3,9 +3,8 @@ from numba import njit from numba import types as nb_types -from numpy import arange, array, int32, interp, median, where, zeros +from numpy import arange, int32, interp, median, where, zeros -from ..poly import create_vertice, reduce_size, winding_number_poly from .observation import EddiesObservations logger = logging.getLogger("pet") @@ -88,41 +87,6 @@ def advect(x, y, c, t0, n_days): return t, x, y -@njit(cache=True) -def _create_meshed_particles(lons, lats, step): - x_out, y_out, i_out = list(), list(), list() - for i, (lon, lat) in enumerate(zip(lons, lats)): - lon_min, lon_max = lon.min(), lon.max() - lat_min, lat_max = lat.min(), lat.max() - lon_min -= lon_min % step - lon_max -= lon_max % step - step * 2 - lat_min -= lat_min % step - lat_max -= lat_max % step - step * 2 - - for x in arange(lon_min, lon_max, step): - for y in arange(lat_min, lat_max, step): - if winding_number_poly(x, y, create_vertice(*reduce_size(lon, lat))): - x_out.append(x), y_out.append(y), i_out.append(i) - return array(x_out), array(y_out), array(i_out) - - -def create_particles(eddies, step): - """create particles only inside speed contour. Avoid creating too large numpy arrays, only to me masked - - :param eddies: network where eddies are - :type eddies: network - :param step: step for particles - :type step: float - :return: lon, lat and indices of particles in contour speed - :rtype: tuple(np.array) - """ - - lon = eddies.contour_lon_s - lat = eddies.contour_lat_s - - return _create_meshed_particles(lon, lat, step) - - def particle_candidate(c, eddies, step_mesh, t_start, i_target, pct, **kwargs): """Select particles within eddies, advect them, return target observation and associated percentages @@ -141,7 +105,7 @@ def particle_candidate(c, eddies, step_mesh, t_start, i_target, pct, **kwargs): # to be able to get global index translate_start = where(m_start)[0] - x, y, i_start = create_particles(e, step_mesh) + x, y, i_start = e.create_particles(step_mesh) # Advection t_end, x, y = advect(x, y, c, t_start, **kwargs) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index aa73b28d..d969f800 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -69,6 +69,7 @@ poly_indexs, reduce_size, vertice_overlap, + winding_number_poly ) logger = logging.getLogger("pet") @@ -2274,6 +2275,19 @@ def nb_days(self): """ return self.period[1] - self.period[0] + 1 + def create_particles(self, step, intern=True): + """create particles only inside speed contour. Avoid creating too large numpy arrays, only to me masked + + :param step: step for particles + :type step: float + :param bool intern: If true use speed contour instead of effective contour + :return: lon, lat and indices of particles + :rtype: tuple(np.array) + """ + + xname, yname = self.intern(intern) + return _create_meshed_particles(self[xname], self[yname], step) + @njit(cache=True) def grid_count_(grid, i, j): @@ -2430,6 +2444,24 @@ def grid_stat(x_c, y_c, grid, x, y, result, circular=False, method="mean"): result[elt] = v_max +@njit(cache=True) +def _create_meshed_particles(lons, lats, step): + x_out, y_out, i_out = list(), list(), list() + for i, (lon, lat) in enumerate(zip(lons, lats)): + lon_min, lon_max = lon.min(), lon.max() + lat_min, lat_max = lat.min(), lat.max() + lon_min -= lon_min % step + lon_max -= lon_max % step - step * 2 + lat_min -= lat_min % step + lat_max -= lat_max % step - step * 2 + + for x in arange(lon_min, lon_max, step): + for y in arange(lat_min, lat_max, step): + if winding_number_poly(x, y, create_vertice(*reduce_size(lon, lat))): + x_out.append(x), y_out.append(y), i_out.append(i) + return array(x_out), array(y_out), array(i_out) + + class VirtualEddiesObservations(EddiesObservations): """Class to work with virtual obs""" From 1f21d33d49b5aea6f2c6a45852a406fe37fadf29 Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Wed, 16 Jun 2021 23:51:33 +0200 Subject: [PATCH 172/249] management of floating time --- CHANGELOG.rst | 4 ++ doc/run_tracking.rst | 4 +- .../06_grid_manipulation/pet_okubo_weiss.py | 2 +- examples/16_network/pet_follow_particle.py | 5 +++ .../16_network/pet_follow_particle.ipynb | 12 +++--- src/py_eddy_tracker/__init__.py | 7 ++- src/py_eddy_tracker/appli/eddies.py | 40 +++++++++++------- src/py_eddy_tracker/appli/grid.py | 15 +++++-- .../data/Anticyclonic_20190223.nc | Bin 907023 -> 908188 bytes src/py_eddy_tracker/gui.py | 4 +- src/py_eddy_tracker/observations/groups.py | 4 +- .../observations/observation.py | 2 + src/py_eddy_tracker/observations/tracking.py | 15 ++++--- src/py_eddy_tracker/tracking.py | 9 ++-- src/scripts/EddyTranslate | 9 ++-- 15 files changed, 86 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 87b5d870..d7da20d3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,6 +10,10 @@ and this project adheres to `Semantic Versioning First target\nLatitude") +ax_2nd_b.set_ylabel("Color -> Secondary target\nLatitude") +ax_2nd_b.set_xlabel("Julian days"), ax_2nd_f.set_xlabel("Julian days") +ax_1st_f.set_yticks([]), ax_2nd_f.set_yticks([]) +ax_1st_f.set_xticks([]), ax_1st_b.set_xticks([]) def color_alpha(target, pct, vmin=5, vmax=80): diff --git a/notebooks/python_module/16_network/pet_follow_particle.ipynb b/notebooks/python_module/16_network/pet_follow_particle.ipynb index 6be13adf..b6723a97 100644 --- a/notebooks/python_module/16_network/pet_follow_particle.ipynb +++ b/notebooks/python_module/16_network/pet_follow_particle.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# Follow particle\n" + "\nFollow particle\n===============\n" ] }, { @@ -55,7 +55,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Schema\n\n" + "Schema\n------\n\n" ] }, { @@ -73,7 +73,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Animation\nParticle settings\n\n" + "Animation\n---------\nParticle settings\n\n" ] }, { @@ -109,7 +109,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Particle advection\n\n" + "Particle advection\n^^^^^^^^^^^^^^^^^^\n\n" ] }, { @@ -131,7 +131,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure(figsize=(10, 10))\nax_1st_b = fig.add_axes([0.05, 0.52, 0.45, 0.45])\nax_2nd_b = fig.add_axes([0.05, 0.05, 0.45, 0.45])\nax_1st_f = fig.add_axes([0.52, 0.52, 0.45, 0.45])\nax_2nd_f = fig.add_axes([0.52, 0.05, 0.45, 0.45])\nax_1st_b.set_title(\"Backward advection for each time step\")\nax_1st_f.set_title(\"Forward advection for each time step\")\n\n\ndef color_alpha(target, pct, vmin=5, vmax=80):\n color = cmap(n.segment[target])\n # We will hide under 5 % and from 80% to 100 % it will be 1\n alpha = (pct - vmin) / (vmax - vmin)\n alpha[alpha < 0] = 0\n alpha[alpha > 1] = 1\n color[:, 3] = alpha\n return color\n\n\nkw = dict(\n name=None, yfield=\"longitude\", event=False, zorder=-100, s=(n.speed_area / 20e6)\n)\nn.scatter_timeline(ax_1st_b, c=color_alpha(i_target_b.T[0], pct_target_b.T[0]), **kw)\nn.scatter_timeline(ax_2nd_b, c=color_alpha(i_target_b.T[1], pct_target_b.T[1]), **kw)\nn.scatter_timeline(ax_1st_f, c=color_alpha(i_target_f.T[0], pct_target_f.T[0]), **kw)\nn.scatter_timeline(ax_2nd_f, c=color_alpha(i_target_f.T[1], pct_target_f.T[1]), **kw)\nfor ax in (ax_1st_b, ax_2nd_b, ax_1st_f, ax_2nd_f):\n n.display_timeline(ax, field=\"longitude\", marker=\"+\", lw=2, markersize=5)\n ax.grid()" + "fig = plt.figure(figsize=(10, 10))\nax_1st_b = fig.add_axes([0.05, 0.52, 0.45, 0.45])\nax_2nd_b = fig.add_axes([0.05, 0.05, 0.45, 0.45])\nax_1st_f = fig.add_axes([0.52, 0.52, 0.45, 0.45])\nax_2nd_f = fig.add_axes([0.52, 0.05, 0.45, 0.45])\nax_1st_b.set_title(\"Backward advection for each time step\")\nax_1st_f.set_title(\"Forward advection for each time step\")\nax_1st_b.set_ylabel(\"Color -> First target\\nLatitude\")\nax_2nd_b.set_ylabel(\"Color -> Secondary target\\nLatitude\")\nax_2nd_b.set_xlabel(\"Julian days\"), ax_2nd_f.set_xlabel(\"Julian days\")\nax_1st_f.set_yticks([]), ax_2nd_f.set_yticks([])\nax_1st_f.set_xticks([]), ax_1st_b.set_xticks([])\n\n\ndef color_alpha(target, pct, vmin=5, vmax=80):\n color = cmap(n.segment[target])\n # We will hide under 5 % and from 80% to 100 % it will be 1\n alpha = (pct - vmin) / (vmax - vmin)\n alpha[alpha < 0] = 0\n alpha[alpha > 1] = 1\n color[:, 3] = alpha\n return color\n\n\nkw = dict(\n name=None, yfield=\"longitude\", event=False, zorder=-100, s=(n.speed_area / 20e6)\n)\nn.scatter_timeline(ax_1st_b, c=color_alpha(i_target_b.T[0], pct_target_b.T[0]), **kw)\nn.scatter_timeline(ax_2nd_b, c=color_alpha(i_target_b.T[1], pct_target_b.T[1]), **kw)\nn.scatter_timeline(ax_1st_f, c=color_alpha(i_target_f.T[0], pct_target_f.T[0]), **kw)\nn.scatter_timeline(ax_2nd_f, c=color_alpha(i_target_f.T[1], pct_target_f.T[1]), **kw)\nfor ax in (ax_1st_b, ax_2nd_b, ax_1st_f, ax_2nd_f):\n n.display_timeline(ax, field=\"longitude\", marker=\"+\", lw=2, markersize=5)\n ax.grid()" ] } ], @@ -151,7 +151,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.9" + "version": "3.7.7" } }, "nbformat": 4, diff --git a/src/py_eddy_tracker/__init__.py b/src/py_eddy_tracker/__init__.py index 5cf0d59a..971914f8 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -106,12 +106,17 @@ def parse_args(self, *args, **kwargs): return opts +TIME_MODELS = ["%Y%m%d", "%Y%m%d%H%M%S", "%Y%m%dT%H%M%S"] + + VAR_DESCR = dict( time=dict( attr_name="time", nc_name="time", old_nc_name=["j1"], - nc_type="int32", + nc_type="float64", + output_type="uint32", + scale_factor=1 / 86400.0, nc_dims=("obs",), nc_attr=dict( standard_name="time", diff --git a/src/py_eddy_tracker/appli/eddies.py b/src/py_eddy_tracker/appli/eddies.py index d30ef259..9c57d818 100644 --- a/src/py_eddy_tracker/appli/eddies.py +++ b/src/py_eddy_tracker/appli/eddies.py @@ -15,7 +15,7 @@ from numpy import bincount, bytes_, empty, in1d, unique from yaml import safe_load -from .. import EddyParser +from .. import TIME_MODELS, EddyParser from ..observations.observation import EddiesObservations, reverse_index from ..observations.tracking import TrackEddiesObservations from ..tracking import Correspondances @@ -223,7 +223,7 @@ def browse_dataset_in( data_dir, files_model, date_regexp, - date_model, + date_model=None, start_date=None, end_date=None, sub_sampling_step=1, @@ -238,11 +238,7 @@ def browse_dataset_in( filenames = bytes_(glob(full_path)) dataset_list = empty( - len(filenames), - dtype=[ - ("filename", "S500"), - ("date", "datetime64[D]"), - ], + len(filenames), dtype=[("filename", "S500"), ("date", "datetime64[s]")], ) dataset_list["filename"] = filenames @@ -268,10 +264,21 @@ def browse_dataset_in( str_date = result.groups()[0] if str_date is not None: - item["date"] = datetime.strptime(str_date, date_model).date() + if date_model is None: + model_found = False + for model in TIME_MODELS: + try: + item["date"] = datetime.strptime(str_date, model) + model_found = True + break + except ValueError: + pass + if not model_found: + raise Exception("No time model found") + else: + item["date"] = datetime.strptime(str_date, date_model) dataset_list.sort(order=["date", "filename"]) - steps = unique(dataset_list["date"][1:] - dataset_list["date"][:-1]) if len(steps) > 1: raise Exception("Several days steps in grid dataset %s" % steps) @@ -304,7 +311,7 @@ def track( correspondances_only=False, **kw_c, ): - kw = dict(date_regexp=".*_([0-9]*?).[nz].*", date_model="%Y%m%d") + kw = dict(date_regexp=".*_([0-9]*?).[nz].*") if isinstance(pattern, list): kw.update(dict(data_dir=None, files_model=None, files=pattern)) else: @@ -323,10 +330,9 @@ def track( c = Correspondances(datasets=datasets["filename"], **kw_c) c.track() logger.info("Track finish") - t0, t1 = c.period kw_save = dict( - date_start=t0, - date_stop=t1, + date_start=datasets["date"][0], + date_stop=datasets["date"][-1], date_prod=datetime.now(), path=output_dir, sign_type=c.current_obs.sign_legend, @@ -351,11 +357,13 @@ def track( short_c = c._copy() short_c.shorter_than(size_max=nb_obs_min) - c.longer_than(size_min=nb_obs_min) - - long_track = c.merge(raw_data=raw) short_track = short_c.merge(raw_data=raw) + if c.longer_than(size_min=nb_obs_min) is False: + long_track = short_track.empty_dataset() + else: + long_track = c.merge(raw_data=raw) + # We flag obs if c.virtual: long_track["virtual"][:] = long_track["time"] == 0 diff --git a/src/py_eddy_tracker/appli/grid.py b/src/py_eddy_tracker/appli/grid.py index 7f2b9610..7a746a8f 100644 --- a/src/py_eddy_tracker/appli/grid.py +++ b/src/py_eddy_tracker/appli/grid.py @@ -5,7 +5,7 @@ from argparse import Action from datetime import datetime -from .. import EddyParser +from .. import TIME_MODELS, EddyParser from ..dataset.grid import RegularGridDataset, UnRegularGridDataset @@ -121,7 +121,16 @@ def eddy_id(args=None): cut_wavelength = [0, *cut_wavelength] inf_bnds, upper_bnds = cut_wavelength - date = datetime.strptime(args.datetime, "%Y%m%d") + model_found = False + for model in TIME_MODELS: + try: + date = datetime.strptime(args.datetime, model) + model_found = True + break + except ValueError: + pass + if not model_found: + raise Exception("No time model found") kwargs = dict( step=args.isoline_step, shape_error=args.fit_errmax, @@ -150,7 +159,7 @@ def eddy_id(args=None): sampling_method=args.sampling_method, **kwargs, ) - out_name = date.strftime("%(path)s/%(sign_type)s_%Y%m%d.nc") + out_name = date.strftime("%(path)s/%(sign_type)s_%Y%m%dT%H%M%S.nc") a.write_file(path=args.path_out, filename=out_name, zarr_flag=args.zarr) c.write_file(path=args.path_out, filename=out_name, zarr_flag=args.zarr) diff --git a/src/py_eddy_tracker/data/Anticyclonic_20190223.nc b/src/py_eddy_tracker/data/Anticyclonic_20190223.nc index ce48c8d60a4779176855f1c3108911b2f2d50c91..dc5fe0d3693f42f6165c4138e2e6ee8f30f74bf5 100644 GIT binary patch delta 11315 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 delta 10752 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 {t1}\n" txt += f" Tracks : {tr} {now['n']}/{nb} ({now['n'] / nb * 100:.2f} %)\n" diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index 64a81a36..544fd5f5 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -186,7 +186,8 @@ def filled_by_interpolation(self, mask): .. minigallery:: py_eddy_tracker.TrackEddiesObservations.filled_by_interpolation """ - + if self.track.size == 0: + return nb_filled = mask.sum() logger.info("%d obs will be filled (unobserved)", nb_filled) @@ -194,7 +195,6 @@ def filled_by_interpolation(self, mask): index = arange(nb_obs) for field in self.obs.dtype.descr: - # print(f"field : {field}") var = field[0] if ( var in ["n", "virtual", "track", "cost_association"] diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index d969f800..907c2417 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -1328,6 +1328,8 @@ def solve_conflict(cost): def solve_simultaneous(cost): """Write something (TODO)""" mask = ~cost.mask + if mask.size == 0: + return mask # Count number of links by self obs and other obs self_links, other_links = sum_row_column(mask) max_links = max(self_links.max(), other_links.max()) diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index 58514eb2..6d302c96 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -173,6 +173,8 @@ def normalize_longitude(self): - contour_lon_e (how to do if in raw) - contour_lon_s (how to do if in raw) """ + if self.lon.size == 0: + return lon0 = (self.lon[self.index_from_track] - 180).repeat(self.nb_obs_by_track) logger.debug("Normalize longitude") self.lon[:] = (self.lon - lon0) % 360 + lon0 @@ -228,12 +230,13 @@ def set_global_attr_netcdf(self, h_nc): ) h_nc.date_created = datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ") t = h_nc.variables[VAR_DESCR_inv["j1"]] - delta = t.max - t.min + 1 - h_nc.time_coverage_duration = "P%dD" % delta - d_start = datetime(1950, 1, 1) + timedelta(int(t.min)) - d_end = datetime(1950, 1, 1) + timedelta(int(t.max)) - h_nc.time_coverage_start = d_start.strftime("%Y-%m-%dT00:00:00Z") - h_nc.time_coverage_end = d_end.strftime("%Y-%m-%dT00:00:00Z") + if t.size: + delta = t.max - t.min + 1 + h_nc.time_coverage_duration = "P%dD" % delta + d_start = datetime(1950, 1, 1) + timedelta(int(t.min)) + d_end = datetime(1950, 1, 1) + timedelta(int(t.max)) + h_nc.time_coverage_start = d_start.strftime("%Y-%m-%dT00:00:00Z") + h_nc.time_coverage_end = d_end.strftime("%Y-%m-%dT00:00:00Z") def extract_with_period(self, period, **kwargs): """ diff --git a/src/py_eddy_tracker/tracking.py b/src/py_eddy_tracker/tracking.py index cba9985e..577496ff 100644 --- a/src/py_eddy_tracker/tracking.py +++ b/src/py_eddy_tracker/tracking.py @@ -161,10 +161,10 @@ def period(self): """ date_start = datetime(1950, 1, 1) + timedelta( - int(self.class_method.load_file(self.datasets[0]).time[0]) + self.class_method.load_file(self.datasets[0]).time[0] ) date_stop = datetime(1950, 1, 1) + timedelta( - int(self.class_method.load_file(self.datasets[-1]).time[0]) + self.class_method.load_file(self.datasets[-1]).time[0] ) return date_start, date_stop @@ -584,7 +584,10 @@ def prepare_merging(self): def longer_than(self, size_min): """Remove from correspondance table all association for shorter eddies than size_min""" # Identify eddies longer than - i_keep_track = where(self.nb_obs_by_tracks >= size_min)[0] + mask = self.nb_obs_by_tracks >= size_min + if not mask.any(): + return False + i_keep_track = where(mask)[0] # Reduce array self.nb_obs_by_tracks = self.nb_obs_by_tracks[i_keep_track] self.i_current_by_tracks = ( diff --git a/src/scripts/EddyTranslate b/src/scripts/EddyTranslate index 94142132..a710db0d 100644 --- a/src/scripts/EddyTranslate +++ b/src/scripts/EddyTranslate @@ -16,6 +16,7 @@ def id_parser(): ) parser.add_argument("filename_in") parser.add_argument("filename_out") + parser.add_argument("--unraw", action="store_true", help="Load unraw data") return parser @@ -32,10 +33,10 @@ def get_variable_name(filename): return list(h.keys()) -def get_variable(filename, varname): +def get_variable(filename, varname, raw=True): if is_nc(filename): dataset = EddiesObservations.load_from_netcdf( - filename, raw_data=True, include_vars=(varname,) + filename, raw_data=raw, include_vars=(varname,) ) else: dataset = EddiesObservations.load_from_zarr(filename, include_vars=(varname,)) @@ -49,8 +50,8 @@ if __name__ == "__main__": if not is_nc(args.filename_out): h = zarr.open(args.filename_out, "w") for varname in variables: - get_variable(args.filename_in, varname).to_zarr(h) + get_variable(args.filename_in, varname, raw=not args.unraw).to_zarr(h) else: with Dataset(args.filename_out, "w") as h: for varname in variables: - get_variable(args.filename_in, varname).to_netcdf(h) + get_variable(args.filename_in, varname, raw=not args.unraw).to_netcdf(h) From 7e72eff64f9a801de882f177d074b85ed32ce937 Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Fri, 18 Jun 2021 09:02:54 +0200 Subject: [PATCH 173/249] modify amplitude storage --- CHANGELOG.rst | 1 + share/tracking.yaml | 3 ++- src/py_eddy_tracker/__init__.py | 2 +- .../data/Anticyclonic_20190223.nc | Bin 908188 -> 909431 bytes 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d7da20d3..1555c223 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -13,6 +13,7 @@ Changed - Now time will be allow second precision in storage on uint32 from 01/01/1950 to 01/01/2086 new identification will be produce with this type, old file could be still loaded. If you use old identification to track use `--unraw` option to unpack old time and store in new format. +- Now amplitude is stored with .1 mm of precision, same advice than time. Fixed ^^^^^ diff --git a/share/tracking.yaml b/share/tracking.yaml index b9c98488..a77e9893 100644 --- a/share/tracking.yaml +++ b/share/tracking.yaml @@ -4,8 +4,9 @@ PATHS: # Path for saving of outputs SAVE_DIR: '/home/emason/toto/' -# Minimum number of observations to store eddy +# Minimal number of timesteps to consider as a long track TRACK_DURATION_MIN: 4 +# Number of timesteps for missing detection VIRTUAL_LENGTH_MAX: 0 CLASS: diff --git a/src/py_eddy_tracker/__init__.py b/src/py_eddy_tracker/__init__.py index 971914f8..e8e3c590 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -256,7 +256,7 @@ def parse_args(self, *args, **kwargs): old_nc_name=["A"], nc_type="float32", output_type="uint16", - scale_factor=0.001, + scale_factor=0.0001, nc_dims=("obs",), nc_attr=dict( long_name="Amplitude", diff --git a/src/py_eddy_tracker/data/Anticyclonic_20190223.nc b/src/py_eddy_tracker/data/Anticyclonic_20190223.nc index dc5fe0d3693f42f6165c4138e2e6ee8f30f74bf5..4ab8f2261e9e0a80f1f9825babf234cb3097f44e 100644 GIT binary patch delta 8452 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 delta 7210 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 Zyto+WgT6F@%MGGMOmotwKDI>k{{Z1EEUy3n From 700f91c57bef429f0af99a8eec448b3e8a7c48cf Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Mon, 21 Jun 2021 22:33:42 +0200 Subject: [PATCH 174/249] manage time in network --- examples/16_network/pet_follow_particle.py | 4 ++-- .../16_network/pet_follow_particle.ipynb | 2 +- .../16_network/pet_segmentation_anim.ipynb | 14 +++++++------- src/py_eddy_tracker/observations/tracking.py | 18 ++++++++++++------ 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/examples/16_network/pet_follow_particle.py b/examples/16_network/pet_follow_particle.py index 078d6fbf..a5a252e2 100644 --- a/examples/16_network/pet_follow_particle.py +++ b/examples/16_network/pet_follow_particle.py @@ -133,12 +133,12 @@ def update(frame): shape = (n.obs.size, 2) # Forward run i_target_f, pct_target_f = -ones(shape, dtype="i4"), zeros(shape, dtype="i1") -for t in range(t_start, t_end - dt): +for t in arange(t_start, t_end - dt): particle_candidate(c, n, step, t, i_target_f, pct_target_f, n_days=dt) # Backward run i_target_b, pct_target_b = -ones(shape, dtype="i4"), zeros(shape, dtype="i1") -for t in range(t_start + dt, t_end): +for t in arange(t_start + dt, t_end): particle_candidate(c, n, step, t, i_target_b, pct_target_b, n_days=-dt) # %% diff --git a/notebooks/python_module/16_network/pet_follow_particle.ipynb b/notebooks/python_module/16_network/pet_follow_particle.ipynb index b6723a97..15820ad3 100644 --- a/notebooks/python_module/16_network/pet_follow_particle.ipynb +++ b/notebooks/python_module/16_network/pet_follow_particle.ipynb @@ -120,7 +120,7 @@ }, "outputs": [], "source": [ - "step = 1 / 60.0\n\nx, y = meshgrid(arange(24, 36, step), arange(31, 36, step))\nx0, y0 = x.reshape(-1), y.reshape(-1)\n# Pre-order to speed up\n_, i = group_obs(x0, y0, 1, 360)\nx0, y0 = x0[i], y0[i]\n\nt_start, t_end = n.period\ndt = 14\n\nshape = (n.obs.size, 2)\n# Forward run\ni_target_f, pct_target_f = -ones(shape, dtype=\"i4\"), zeros(shape, dtype=\"i1\")\nfor t in range(t_start, t_end - dt):\n particle_candidate(x0, y0, c, n, t, i_target_f, pct_target_f, n_days=dt)\n\n# Backward run\ni_target_b, pct_target_b = -ones(shape, dtype=\"i4\"), zeros(shape, dtype=\"i1\")\nfor t in range(t_start + dt, t_end):\n particle_candidate(x0, y0, c, n, t, i_target_b, pct_target_b, n_days=-dt)" + "step = 1 / 60.0\n\nx, y = meshgrid(arange(24, 36, step), arange(31, 36, step))\nx0, y0 = x.reshape(-1), y.reshape(-1)\n# Pre-order to speed up\n_, i = group_obs(x0, y0, 1, 360)\nx0, y0 = x0[i], y0[i]\n\nt_start, t_end = n.period\ndt = 14\n\nshape = (n.obs.size, 2)\n# Forward run\ni_target_f, pct_target_f = -ones(shape, dtype=\"i4\"), zeros(shape, dtype=\"i1\")\nfor t in arange(t_start, t_end - dt):\n particle_candidate(x0, y0, c, n, t, i_target_f, pct_target_f, n_days=dt)\n\n# Backward run\ni_target_b, pct_target_b = -ones(shape, dtype=\"i4\"), zeros(shape, dtype=\"i1\")\nfor t in arange(t_start + dt, t_end):\n particle_candidate(x0, y0, c, n, t, i_target_b, pct_target_b, n_days=-dt)" ] }, { diff --git a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb index 05c68873..34047da4 100644 --- a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb +++ b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# Network segmentation process\n" + "\nNetwork segmentation process\n============================\n" ] }, { @@ -62,7 +62,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Load data\nLoad data where observations are put in same network but no segmentation\n\n" + "Load data\n---------\nLoad data where observations are put in same network but no segmentation\n\n" ] }, { @@ -80,7 +80,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Do segmentation\nSegmentation based on maximum overlap, temporal window for candidates = 5 days\n\n" + "Do segmentation\n---------------\nSegmentation based on maximum overlap, temporal window for candidates = 5 days\n\n" ] }, { @@ -98,7 +98,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Anim\n\n" + "Anim\n----\n\n" ] }, { @@ -109,14 +109,14 @@ }, "outputs": [], "source": [ - "def update(i_frame):\n tr = TRACKS[i_frame]\n mappable_tracks.set_array(tr)\n s = 40 * ones(tr.shape)\n s[tr == 0] = 4\n mappable_tracks.set_sizes(s)\n\n indices_frames = INDICES[i_frame]\n mappable_CONTOUR.set_data(\n e.contour_lon_e[indices_frames],\n e.contour_lat_e[indices_frames],\n )\n mappable_CONTOUR.set_color(cmap.colors[tr[indices_frames] % len(cmap.colors)])\n return (mappable_tracks,)\n\n\nfig = plt.figure(figsize=(16, 9), dpi=60)\nax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=GUI_AXES)\nax.set_title(f\"{len(e)} observations to segment\")\nax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid()\nvmax = TRACKS[-1].max()\ncmap = ListedColormap([\"gray\", *e.COLORS[:-1]], name=\"from_list\", N=vmax)\nmappable_tracks = ax.scatter(\n e.lon, e.lat, c=TRACKS[0], cmap=cmap, vmin=0, vmax=vmax, s=20\n)\nmappable_CONTOUR = ax.plot(\n e.contour_lon_e[INDICES[0]], e.contour_lat_e[INDICES[0]], color=cmap.colors[0]\n)[0]\nani = VideoAnimation(fig, update, frames=range(1, len(TRACKS), 4), interval=125)" + "def update(i_frame):\n tr = TRACKS[i_frame]\n mappable_tracks.set_array(tr)\n s = 40 * ones(tr.shape)\n s[tr == 0] = 4\n mappable_tracks.set_sizes(s)\n\n indices_frames = INDICES[i_frame]\n mappable_CONTOUR.set_data(\n e.contour_lon_e[indices_frames], e.contour_lat_e[indices_frames],\n )\n mappable_CONTOUR.set_color(cmap.colors[tr[indices_frames] % len(cmap.colors)])\n return (mappable_tracks,)\n\n\nfig = plt.figure(figsize=(16, 9), dpi=60)\nax = fig.add_axes([0.04, 0.06, 0.94, 0.88], projection=GUI_AXES)\nax.set_title(f\"{len(e)} observations to segment\")\nax.set_xlim(19, 29), ax.set_ylim(31, 35.5), ax.grid()\nvmax = TRACKS[-1].max()\ncmap = ListedColormap([\"gray\", *e.COLORS[:-1]], name=\"from_list\", N=vmax)\nmappable_tracks = ax.scatter(\n e.lon, e.lat, c=TRACKS[0], cmap=cmap, vmin=0, vmax=vmax, s=20\n)\nmappable_CONTOUR = ax.plot(\n e.contour_lon_e[INDICES[0]], e.contour_lat_e[INDICES[0]], color=cmap.colors[0]\n)[0]\nani = VideoAnimation(fig, update, frames=range(1, len(TRACKS), 4), interval=125)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Final Result\n\n" + "Final Result\n------------\n\n" ] }, { @@ -147,7 +147,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.9" + "version": "3.7.7" } }, "nbformat": 4, diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index 6d302c96..492842c7 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -16,6 +16,7 @@ degrees, empty, histogram, + int_, median, nan, ones, @@ -601,6 +602,12 @@ def plot(self, ax, ref=None, **kwargs): def split_network(self, intern=True, **kwargs): """Return each group (network) divided in segments""" + # Find timestep of dataset + # FIXME : how to know exact time sampling + t = unique(self.time) + dts = t[1:] - t[:-1] + timestep = median(dts) + track_s, track_e, track_ref = build_index(self.tracks) ids = empty( len(self), @@ -614,7 +621,7 @@ def split_network(self, intern=True, **kwargs): ("next_obs", "i4"), ], ) - ids["group"], ids["time"] = self.tracks, self.time + ids["group"], ids["time"] = self.tracks, int_(self.time / timestep) # Initialisation # To store the id of the segments, the backward and forward cost associations ids["track"], ids["previous_cost"], ids["next_cost"] = 0, 0, 0 @@ -641,6 +648,7 @@ def split_network(self, intern=True, **kwargs): local_ids["next_obs"][m] += i_s if display_iteration: print() + ids["time"] *= timestep return ids def set_tracks(self, x, y, ids, window, **kwargs): @@ -652,8 +660,7 @@ def set_tracks(self, x, y, ids, window, **kwargs): :param ndarray ids: several fields like time, group, ... :param int windows: number of days where observations could missed """ - - time_index = build_index(ids["time"]) + time_index = build_index((ids["time"]).astype("i4")) nb = x.shape[0] used = zeros(nb, dtype="bool") track_id = 1 @@ -698,8 +705,7 @@ def get_previous_obs( i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs ): """Backward association of observations to the segments""" - - time_cur = ids["time"][i_current] + time_cur = int_(ids["time"][i_current]) t0, t1 = time_cur - 1 - time_ref, max(time_cur - window - time_ref, 0) for t_step in range(t0, t1 - 1, -1): i0, i1 = time_s[t_step], time_e[t_step] @@ -729,7 +735,7 @@ def get_previous_obs( def get_next_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs): """Forward association of observations to the segments""" time_max = time_e.shape[0] - 1 - time_cur = ids["time"][i_current] + time_cur = int_(ids["time"][i_current]) t0, t1 = time_cur + 1 - time_ref, min(time_cur + window - time_ref, time_max) if t0 > time_max: return -1 From 2b1eb7fb447e8b8216f7115165540e7a631d7587 Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Fri, 25 Jun 2021 21:42:55 +0200 Subject: [PATCH 175/249] English corrections & missing changelog version --- CHANGELOG.rst | 19 +++++++++++++------ doc/run_tracking.rst | 14 +++++++------- share/tracking.yaml | 10 +++++----- src/py_eddy_tracker/appli/eddies.py | 2 +- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1555c223..f33f15dd 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,18 +10,25 @@ and this project adheres to `Semantic Versioning 1: - raise Exception("Several days steps in grid dataset %s" % steps) + raise Exception("Several timesteps in grid dataset %s" % steps) if sub_sampling_step != 1: logger.info("Grid subsampling %d", sub_sampling_step) From 8e262304ba8be2d0b91136f8294be0aaafc2519a Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Mon, 28 Jun 2021 21:48:57 +0200 Subject: [PATCH 176/249] create specific environement.yml for binder (#97) --- environment.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 environment.yml diff --git a/environment.yml b/environment.yml new file mode 100644 index 00000000..941bb7aa --- /dev/null +++ b/environment.yml @@ -0,0 +1,11 @@ +name: binder-pyeddytracker +channels: + - conda-forge + - defaults +dependencies: + - python=3.7 + - ffmpeg + - pip: + - -r file:requirements.txt + - pyeddytrackersample + - . From 43c2616bdc5f267bed21dc334de49631a5dda20b Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Mon, 28 Jun 2021 22:39:06 +0200 Subject: [PATCH 177/249] Add documentation and create method to detect time format --- src/py_eddy_tracker/__init__.py | 10 ++++++++++ src/py_eddy_tracker/appli/eddies.py | 20 ++++++++----------- src/py_eddy_tracker/appli/grid.py | 14 ++----------- .../observations/observation.py | 9 +++++++-- src/scripts/EddyTranslate | 3 ++- 5 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/py_eddy_tracker/__init__.py b/src/py_eddy_tracker/__init__.py index e8e3c590..fbeb1450 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -22,6 +22,7 @@ import logging from argparse import ArgumentParser +from datetime import datetime import zarr @@ -109,6 +110,15 @@ def parse_args(self, *args, **kwargs): TIME_MODELS = ["%Y%m%d", "%Y%m%d%H%M%S", "%Y%m%dT%H%M%S"] +def identify_time(str_date): + for model in TIME_MODELS: + try: + return datetime.strptime(str_date, model) + except ValueError: + pass + raise Exception("No time model found") + + VAR_DESCR = dict( time=dict( attr_name="time", diff --git a/src/py_eddy_tracker/appli/eddies.py b/src/py_eddy_tracker/appli/eddies.py index 701162a4..4809fddf 100644 --- a/src/py_eddy_tracker/appli/eddies.py +++ b/src/py_eddy_tracker/appli/eddies.py @@ -15,7 +15,7 @@ from numpy import bincount, bytes_, empty, in1d, unique from yaml import safe_load -from .. import TIME_MODELS, EddyParser +from .. import EddyParser, identify_time from ..observations.observation import EddiesObservations, reverse_index from ..observations.tracking import TrackEddiesObservations from ..tracking import Correspondances @@ -163,7 +163,12 @@ def eddies_tracking(): parser.add_argument( "--zarr", action="store_true", help="Output will be wrote in zarr" ) - parser.add_argument("--unraw", action="store_true", help="Load unraw data") + parser.add_argument( + "--unraw", + action="store_true", + help="Load unraw data, use only for netcdf." + "If unraw is active, netcdf is loaded without apply scalefactor and add_offset.", + ) parser.add_argument( "--blank_period", type=int, @@ -265,16 +270,7 @@ def browse_dataset_in( if str_date is not None: if date_model is None: - model_found = False - for model in TIME_MODELS: - try: - item["date"] = datetime.strptime(str_date, model) - model_found = True - break - except ValueError: - pass - if not model_found: - raise Exception("No time model found") + item["date"] = identify_time(str_date) else: item["date"] = datetime.strptime(str_date, date_model) diff --git a/src/py_eddy_tracker/appli/grid.py b/src/py_eddy_tracker/appli/grid.py index 7a746a8f..099465ee 100644 --- a/src/py_eddy_tracker/appli/grid.py +++ b/src/py_eddy_tracker/appli/grid.py @@ -3,9 +3,8 @@ All entry point to manipulate grid """ from argparse import Action -from datetime import datetime -from .. import TIME_MODELS, EddyParser +from .. import EddyParser, identify_time from ..dataset.grid import RegularGridDataset, UnRegularGridDataset @@ -121,16 +120,7 @@ def eddy_id(args=None): cut_wavelength = [0, *cut_wavelength] inf_bnds, upper_bnds = cut_wavelength - model_found = False - for model in TIME_MODELS: - try: - date = datetime.strptime(args.datetime, model) - model_found = True - break - except ValueError: - pass - if not model_found: - raise Exception("No time model found") + date = identify_time(args.datetime) kwargs = dict( step=args.isoline_step, shape_error=args.fit_errmax, diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 907c2417..db0c2a45 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -69,7 +69,7 @@ poly_indexs, reduce_size, vertice_overlap, - winding_number_poly + winding_number_poly, ) logger = logging.getLogger("pet") @@ -1326,7 +1326,12 @@ def solve_conflict(cost): @staticmethod def solve_simultaneous(cost): - """Write something (TODO)""" + """Deduce link from cost matrix. + + :param array(float) cost: Cost for each available link + :return: return a boolean mask array, True for each valid couple + :rtype: array(bool) + """ mask = ~cost.mask if mask.size == 0: return mask diff --git a/src/scripts/EddyTranslate b/src/scripts/EddyTranslate index a710db0d..26ab3a7b 100644 --- a/src/scripts/EddyTranslate +++ b/src/scripts/EddyTranslate @@ -16,7 +16,8 @@ def id_parser(): ) parser.add_argument("filename_in") parser.add_argument("filename_out") - parser.add_argument("--unraw", action="store_true", help="Load unraw data") + parser.add_argument("--unraw", action="store_true", help="Load unraw data, use only for netcdf." + "If unraw is active, netcdf is loaded without apply scalefactor and add_offset.") return parser From 08c2393a053ee9bffcf77957fd369ddc120a0d1a Mon Sep 17 00:00:00 2001 From: Cori Pegliasco Date: Tue, 17 Aug 2021 12:14:07 +0200 Subject: [PATCH 178/249] - Majuscules + orthographe - n.period in int for particle advection - mise en page --- .../pet_eddy_detection_ACC.py | 13 +- examples/06_grid_manipulation/pet_lavd.py | 6 +- examples/16_network/pet_atlas.py | 28 +-- examples/16_network/pet_follow_particle.py | 4 +- examples/16_network/pet_relative.py | 6 +- .../16_network/pet_replay_segmentation.py | 8 +- examples/16_network/pet_segmentation_anim.py | 3 +- src/py_eddy_tracker/__init__.py | 15 +- src/py_eddy_tracker/appli/eddies.py | 18 +- src/py_eddy_tracker/appli/network.py | 4 +- src/py_eddy_tracker/eddy_feature.py | 19 +- src/py_eddy_tracker/observations/groups.py | 37 +++- src/py_eddy_tracker/observations/network.py | 175 ++++++++++++++---- .../observations/observation.py | 23 ++- src/py_eddy_tracker/observations/tracking.py | 33 +++- tests/test_grid.py | 10 +- 16 files changed, 306 insertions(+), 96 deletions(-) diff --git a/examples/02_eddy_identification/pet_eddy_detection_ACC.py b/examples/02_eddy_identification/pet_eddy_detection_ACC.py index e6c5e381..c799a45e 100644 --- a/examples/02_eddy_identification/pet_eddy_detection_ACC.py +++ b/examples/02_eddy_identification/pet_eddy_detection_ACC.py @@ -65,7 +65,8 @@ def set_fancy_labels(fig, ticklabelsize=14, labelsize=14, labelweight="semibold" y_name="latitude", # Manual area subset indexs=dict( - latitude=slice(100 - margin, 220 + margin), longitude=slice(0, 230 + margin), + latitude=slice(100 - margin, 220 + margin), + longitude=slice(0, 230 + margin), ), ) g_raw = RegularGridDataset(**kw_data) @@ -187,10 +188,16 @@ def set_fancy_labels(fig, ticklabelsize=14, labelsize=14, labelweight="semibold" ax.set_ylabel("With filter") ax.plot( - a_[field][i_a] * factor, a[field][j_a] * factor, "r.", label="Anticyclonic", + a_[field][i_a] * factor, + a[field][j_a] * factor, + "r.", + label="Anticyclonic", ) ax.plot( - c_[field][i_c] * factor, c[field][j_c] * factor, "b.", label="Cyclonic", + c_[field][i_c] * factor, + c[field][j_c] * factor, + "b.", + label="Cyclonic", ) ax.set_aspect("equal"), ax.grid() ax.plot((0, 1000), (0, 1000), "g") diff --git a/examples/06_grid_manipulation/pet_lavd.py b/examples/06_grid_manipulation/pet_lavd.py index d96c0b06..e597821c 100644 --- a/examples/06_grid_manipulation/pet_lavd.py +++ b/examples/06_grid_manipulation/pet_lavd.py @@ -159,7 +159,11 @@ def update(i_frame): # Format LAVD data lavd = RegularGridDataset.with_array( coordinates=("lon", "lat"), - datas=dict(lavd=lavd.T, lon=x_g, lat=y_g,), + datas=dict( + lavd=lavd.T, + lon=x_g, + lat=y_g, + ), centered=True, ) diff --git a/examples/16_network/pet_atlas.py b/examples/16_network/pet_atlas.py index 7f86790a..6927f169 100644 --- a/examples/16_network/pet_atlas.py +++ b/examples/16_network/pet_atlas.py @@ -153,33 +153,33 @@ def update_axes(ax, mappable=None): update_axes(ax, m).set_label("Pixel used in % all atlas") # %% -# All Spliting -# ------------ -# Display the occurence of spliting events +# All splitting +# ------------- +# Display the occurence of splitting events ax = start_axes("") -g_all_spliting = n.spliting_event().grid_count(bins) -m = g_all_spliting.display(ax, **kw_time, vmin=0, vmax=1) +g_all_splitting = n.splitting_event().grid_count(bins) +m = g_all_splitting.display(ax, **kw_time, vmin=0, vmax=1) update_axes(ax, m).set_label("Pixel used in % of time") # %% -# Ratio spliting events / eddy presence +# Ratio splitting events / eddy presence ax = start_axes("") -g_ = g_all_spliting.vars["count"] * 100.0 / g_all.vars["count"] -m = g_all_spliting.display(ax, **kw_ratio, vmin=0, vmax=5, name=g_) +g_ = g_all_splitting.vars["count"] * 100.0 / g_all.vars["count"] +m = g_all_splitting.display(ax, **kw_ratio, vmin=0, vmax=5, name=g_) update_axes(ax, m).set_label("Pixel used in % all atlas") # %% -# Spliting in networks longer than 10 days -# ---------------------------------------- +# splitting in networks longer than 10 days +# ----------------------------------------- ax = start_axes("") -g_10_spliting = n10.spliting_event().grid_count(bins) -m = g_10_spliting.display(ax, **kw_time, vmin=0, vmax=1) +g_10_splitting = n10.splitting_event().grid_count(bins) +m = g_10_splitting.display(ax, **kw_time, vmin=0, vmax=1) update_axes(ax, m).set_label("Pixel used in % of time") # %% ax = start_axes("") g_ = ma.array( - g_10_spliting.vars["count"] * 100.0 / g_10.vars["count"], + g_10_splitting.vars["count"] * 100.0 / g_10.vars["count"], mask=g_10.vars["count"] < 365, ) -m = g_10_spliting.display(ax, **kw_ratio, vmin=0, vmax=5, name=g_) +m = g_10_splitting.display(ax, **kw_ratio, vmin=0, vmax=5, name=g_) update_axes(ax, m).set_label("Pixel used in % all atlas") diff --git a/examples/16_network/pet_follow_particle.py b/examples/16_network/pet_follow_particle.py index a5a252e2..1c858879 100644 --- a/examples/16_network/pet_follow_particle.py +++ b/examples/16_network/pet_follow_particle.py @@ -125,9 +125,11 @@ def update(frame): # %% # Particle advection # ^^^^^^^^^^^^^^^^^^ +# Advection from speed contour to speed contour (default) + step = 1 / 60.0 -t_start, t_end = n.period +t_start, t_end = int(n.period[0]), int(n.period[1]) dt = 14 shape = (n.obs.size, 2) diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index c4989edb..f5e8bc92 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -292,13 +292,13 @@ m1 # %% -# Get spliting event -# ------------------ +# Get splitting event +# ------------------- # Display the position of the eddies before a splitting fig = plt.figure(figsize=(15, 8)) ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection=GUI_AXES) n.plot(ax, color_cycle=n.COLORS) -s0, s1, s1_start = n.spliting_event(triplet=True) +s0, s1, s1_start = n.splitting_event(triplet=True) s0.display(ax, color="violet", lw=2, label="Eddies before splitting") s1.display(ax, color="blueviolet", lw=2, label="Eddies after splitting") s1_start.display(ax, color="black", lw=2, label="Eddies starting by splitting") diff --git a/examples/16_network/pet_replay_segmentation.py b/examples/16_network/pet_replay_segmentation.py index d6b4568b..757854d5 100644 --- a/examples/16_network/pet_replay_segmentation.py +++ b/examples/16_network/pet_replay_segmentation.py @@ -149,7 +149,13 @@ def get_obs(dataset): n_.median_filter(15, "time", "latitude") kw["s"] = (n_.radius_e * 1e-3) ** 2 / 30 ** 2 * 20 m = n_.scatter_timeline( - ax, "shape_error_e", vmin=14, vmax=70, **kw, yfield="lon", method="all", + ax, + "shape_error_e", + vmin=14, + vmax=70, + **kw, + yfield="lon", + method="all", ) ax.set_ylabel("Longitude") cb = update_axes(ax, m["scatter"]) diff --git a/examples/16_network/pet_segmentation_anim.py b/examples/16_network/pet_segmentation_anim.py index 503229e7..340163a1 100644 --- a/examples/16_network/pet_segmentation_anim.py +++ b/examples/16_network/pet_segmentation_anim.py @@ -96,7 +96,8 @@ def update(i_frame): indices_frames = INDICES[i_frame] mappable_CONTOUR.set_data( - e.contour_lon_e[indices_frames], e.contour_lat_e[indices_frames], + e.contour_lon_e[indices_frames], + e.contour_lat_e[indices_frames], ) mappable_CONTOUR.set_color(cmap.colors[tr[indices_frames] % len(cmap.colors)]) return (mappable_tracks,) diff --git a/src/py_eddy_tracker/__init__.py b/src/py_eddy_tracker/__init__.py index fbeb1450..f3ecec84 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -404,7 +404,7 @@ def identify_time(str_date): nc_dims=("obs",), nc_attr=dict( long_name="Previous observation index", - comment="Index of previous observation in a spliting case", + comment="Index of previous observation in a splitting case", ), ), next_obs=dict( @@ -422,14 +422,20 @@ def identify_time(str_date): nc_name="previous_cost", nc_type="float32", nc_dims=("obs",), - nc_attr=dict(long_name="Previous cost for previous observation", comment="",), + nc_attr=dict( + long_name="Previous cost for previous observation", + comment="", + ), ), next_cost=dict( attr_name=None, nc_name="next_cost", nc_type="float32", nc_dims=("obs",), - nc_attr=dict(long_name="Next cost for next observation", comment="",), + nc_attr=dict( + long_name="Next cost for next observation", + comment="", + ), ), n=dict( attr_name=None, @@ -640,7 +646,8 @@ def identify_time(str_date): nc_type="f4", nc_dims=("obs",), nc_attr=dict( - long_name="Log base 10 background chlorophyll", units="Log(Chl/[mg/m^3])", + long_name="Log base 10 background chlorophyll", + units="Log(Chl/[mg/m^3])", ), ), year=dict( diff --git a/src/py_eddy_tracker/appli/eddies.py b/src/py_eddy_tracker/appli/eddies.py index 4809fddf..df4e7d43 100644 --- a/src/py_eddy_tracker/appli/eddies.py +++ b/src/py_eddy_tracker/appli/eddies.py @@ -243,7 +243,8 @@ def browse_dataset_in( filenames = bytes_(glob(full_path)) dataset_list = empty( - len(filenames), dtype=[("filename", "S500"), ("date", "datetime64[s]")], + len(filenames), + dtype=[("filename", "S500"), ("date", "datetime64[s]")], ) dataset_list["filename"] = filenames @@ -371,7 +372,8 @@ def track( logger.info("Longer track saved have %d obs", c.nb_obs_by_tracks.max()) logger.info( - "The mean length is %d observations for long track", c.nb_obs_by_tracks.mean(), + "The mean length is %d observations for long track", + c.nb_obs_by_tracks.mean(), ) long_track.write_file(**kw_write) @@ -381,7 +383,14 @@ def track( def get_group( - dataset1, dataset2, index1, index2, score, invalid=2, low=10, high=60, + dataset1, + dataset2, + index1, + index2, + score, + invalid=2, + low=10, + high=60, ): group1, group2 = dict(), dict() m_valid = (score * 100) >= invalid @@ -490,7 +499,8 @@ def get_values(v, dataset): ] labels = dict( - high=f"{high:0.0f} <= high", low=f"{invalid:0.0f} <= low < {low:0.0f}", + high=f"{high:0.0f} <= high", + low=f"{invalid:0.0f} <= low < {low:0.0f}", ) keys = [labels.get(key, key) for key in list(gr_ref.values())[0].keys()] diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index c1a752ee..5c4cdcaf 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -76,7 +76,9 @@ def subset_network(): help="Remove short dead end, first is for minimal obs number and second for minimal segment time to keep", ) parser.add_argument( - "--remove_trash", action="store_true", help="Remove trash (network id == 0)", + "--remove_trash", + action="store_true", + help="Remove trash (network id == 0)", ) parser.add_argument( "-p", diff --git a/src/py_eddy_tracker/eddy_feature.py b/src/py_eddy_tracker/eddy_feature.py index f6db848b..59a042fe 100644 --- a/src/py_eddy_tracker/eddy_feature.py +++ b/src/py_eddy_tracker/eddy_feature.py @@ -61,13 +61,13 @@ def __init__( """ Create amplitude object - :param Contours contour: - :param float contour_height: - :param array data: - :param float interval: + :param Contours contour: usefull class defined below + :param float contour_height: field value of the contour + :param array data: grid + :param float interval: step between two contours :param int mle: maximum number of local extrema in contour - :param int nb_step_min: number of intervals to consider an eddy - :param int nb_step_to_be_mle: number of intervals to be considered as an another maxima + :param int nb_step_min: minimum number of intervals to consider the contour as an eddy + :param int nb_step_to_be_mle: number of intervals to be considered as another extrema """ # Height of the contour @@ -116,8 +116,7 @@ def within_amplitude_limits(self): def all_pixels_below_h0(self, level): """ Check CSS11 criterion 1: The SSH values of all of the pixels - are below (above) a given SSH threshold for cyclonic (anticyclonic) - eddies. + are below a given SSH threshold for cyclonic eddies. """ # In some cases pixel value may be very close to the contour bounds if self.sla.mask.any() or ((self.sla.data - self.h_0) > self.EPSILON).any(): @@ -602,8 +601,8 @@ def display( 4. - Amplitude criterion (yellow) :param str field: Must be 'shape_error', 'x', 'y' or 'radius'. - If define display_criterion is not use. - bins argument must be define + If defined display_criterion is not use. + bins argument must be defined :param array bins: bins used to colorize contour :param str cmap: Name of cmap for field display :param dict kwargs: look at :py:meth:`matplotlib.collections.LineCollection` diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index 544fd5f5..6fea0ace 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -68,7 +68,7 @@ def get_missing_indices( def advect(x, y, c, t0, n_days): """ - Advect particle from t0 to t0 + n_days, with data cube. + Advect particles from t0 to t0 + n_days, with data cube. :param np.array(float) x: longitude of particles :param np.array(float) y: latitude of particles @@ -87,7 +87,17 @@ def advect(x, y, c, t0, n_days): return t, x, y -def particle_candidate(c, eddies, step_mesh, t_start, i_target, pct, **kwargs): +def particle_candidate( + c, + eddies, + step_mesh, + t_start, + i_target, + pct, + contour_start="speed", + contour_end="effective", + **kwargs +): """Select particles within eddies, advect them, return target observation and associated percentages :param `~py_eddy_tracker.dataset.grid.GridCollection` c: GridCollection with speed for particles @@ -95,6 +105,8 @@ def particle_candidate(c, eddies, step_mesh, t_start, i_target, pct, **kwargs): :param int t_start: julian day of the advection :param np.array(int) i_target: corresponding obs where particles are advected :param np.array(int) pct: corresponding percentage of avected particles + :param str contour_start: contour where particles are injected + :param str contour_end: contour where particles are counted after advection :params dict kwargs: dict of params given to `advect` """ @@ -105,7 +117,14 @@ def particle_candidate(c, eddies, step_mesh, t_start, i_target, pct, **kwargs): # to be able to get global index translate_start = where(m_start)[0] - x, y, i_start = e.create_particles(step_mesh) + # Create particles in specified contour + if contour_start == "speed": + x, y, i_start = e.create_particles(step_mesh, intern=True) + elif contour_start == "effective": + x, y, i_start = e.create_particles(step_mesh, intern=False) + else: + x, y, i_start = e.create_particles(step_mesh, intern=True) + print("The contour_start was not correct, speed contour is used") # Advection t_end, x, y = advect(x, y, c, t_start, **kwargs) @@ -117,8 +136,14 @@ def particle_candidate(c, eddies, step_mesh, t_start, i_target, pct, **kwargs): # to be able to get global index translate_end = where(m_end)[0] - # Id eddies for each alive particle (in core and extern) - i_end = e_end.contains(x, y) + # Id eddies for each alive particle in specified contour + if contour_end == "speed": + i_end = e_end.contains(x, y, intern=True) + elif contour_end == "effective": + i_end = e_end.contains(x, y, intern=False) + else: + i_end = e_end.contains(x, y, intern=True) + print("The contour_end was not correct, speed contour is used") # compute matrix and fill target array get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct) @@ -206,7 +231,7 @@ def filled_by_interpolation(self, mask): ) def insert_virtual(self): - """insert virtual observations on segments where observations are missing""" + """Insert virtual observations on segments where observations are missing""" dt_theorical = median(self.time[1:] - self.time[:-1]) indices = self.get_missing_indices(dt_theorical) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index cb6d3986..0ae80634 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -23,6 +23,9 @@ zeros, ) +import netCDF4 +import zarr + from ..dataset.grid import GridCollection from ..generic import build_index, wrap_longitude from ..poly import bbox_intersection, vertice_overlap @@ -147,7 +150,7 @@ def get_missing_indices(self, dt): ) def fix_next_previous_obs(self): - """function used after 'insert_virtual', to correct next_obs and + """Function used after 'insert_virtual', to correct next_obs and previous obs. """ @@ -577,7 +580,7 @@ def close_network(self, other, nb_obs_min=10, **kwargs): return other.extract_with_mask(m) def normalize_longitude(self): - """Normalize all longitude + """Normalize all longitudes Normalize longitude field and in the same range : - longitude_max @@ -677,7 +680,13 @@ def display_timeline( """ self.only_one_network() j = 0 - line_kw = dict(ls="-", marker="+", markersize=6, zorder=1, lw=3,) + line_kw = dict( + ls="-", + marker="+", + markersize=6, + zorder=1, + lw=3, + ) line_kw.update(kwargs) mappables = dict(lines=list()) @@ -719,7 +728,7 @@ def display_timeline( def event_timeline(self, ax, field=None, method=None, factor=1, colors_mode="roll"): """Mark events in plot""" j = 0 - events = dict(spliting=[], merging=[]) + events = dict(splitting=[], merging=[]) # TODO : fill mappables dict y_seg = dict() @@ -784,15 +793,15 @@ def event_timeline(self, ax, field=None, method=None, factor=1, colors_mode="rol ) ) ax.plot((x[0], _time[i_p]), (y0, y1), **event_kw)[0] - events["spliting"].append((x[0], y0)) + events["splitting"].append((x[0], y0)) j += 1 kwargs = dict(color="k", zorder=-1, linestyle=" ") - if len(events["spliting"]) > 0: - X, Y = list(zip(*events["spliting"])) + if len(events["splitting"]) > 0: + X, Y = list(zip(*events["splitting"])) ref = ax.plot( - X, Y, marker="*", markersize=12, label="spliting events", **kwargs + X, Y, marker="*", markersize=12, label="splitting events", **kwargs )[0] mappables.setdefault("events", []).append(ref) @@ -910,7 +919,10 @@ def event_map(self, ax, **kwargs): """Add the merging and splitting events to a map""" j = 0 mappables = dict() - symbol_kw = dict(markersize=10, color="k",) + symbol_kw = dict( + markersize=10, + color="k", + ) symbol_kw.update(kwargs) symbol_kw_split = symbol_kw.copy() symbol_kw_split["markersize"] += 4 @@ -939,7 +951,13 @@ def event_map(self, ax, **kwargs): return mappables def scatter( - self, ax, name="time", factor=1, ref=None, edgecolor_cycle=None, **kwargs, + self, + ax, + name="time", + factor=1, + ref=None, + edgecolor_cycle=None, + **kwargs, ): """ This function scatters the path of each network, with the merging and splitting events @@ -1001,6 +1019,8 @@ def segment_track_array(self): return build_unique_array(self.segment, self.track) def birth_event(self): + """Extract birth events. + Advice : individual eddies (self.track == 0) should be removed before -> apply remove_trash.""" # FIXME how to manage group 0 indices = list() previous_obs = self.previous_obs @@ -1014,6 +1034,8 @@ def birth_event(self): return self.extract_event(list(set(indices))) def death_event(self): + """Extract death events. + Advice : individual eddies (self.track == 0) should be removed before -> apply remove_trash.""" # FIXME how to manage group 0 indices = list() next_obs = self.next_obs @@ -1064,7 +1086,7 @@ def merging_event(self, triplet=False, only_index=False): else: return self.extract_event(idx_m1) - def spliting_event(self, triplet=False, only_index=False): + def splitting_event(self, triplet=False, only_index=False): """Return observation before a splitting event. If `triplet=True` return the eddy before a splitting event, the eddy after the splitting event, @@ -1105,7 +1127,7 @@ def spliting_event(self, triplet=False, only_index=False): def dissociate_network(self): """ - Dissociate networks with no known interaction (spliting/merging) + Dissociate networks with no known interaction (splitting/merging) """ tags = self.tag_segment(multi_network=True) @@ -1183,7 +1205,7 @@ def fully_connected(self): def remove_trash(self): """ - Remove the lonely eddies (only 1 obs in segment, associated segment number is 0) + Remove the lonely eddies (only 1 obs in segment, associated network number is 0) """ return self.extract_with_mask(self.track != 0) @@ -1372,7 +1394,7 @@ def analysis_coherence( date_function, uv_params, advection_mode="both", - dt_advect=14, + n_days=14, step_mesh=1.0 / 50, output_name=None, dissociate_network=False, @@ -1380,7 +1402,26 @@ def analysis_coherence( remove_dead_end=0, ): - """Global function to analyse segments coherence, with network preprocessing""" + """Global function to analyse segments coherence, with network preprocessing. + :param callable date_function: python function, takes as param `int` (julian day) and return + data filename associated to the date + :param dict uv_params: dict of parameters used by + :py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_list` + :param int n_days: nuber of days for advection + :param float step_mesh: step for particule mesh in degrees + :param str output_name: path/name for the output (without extension) to store the clean + network in .nc and the coherence results in .zarr. Works only for advection_mode = "both" + :param bool dissociate_network: If True apply + :py:meth:`~py_eddy_tracker.observation.network.NetworkObservations.dissociate_network` + :param int correct_close_events: Number of days in + :py:meth:`~py_eddy_tracker.observation.network.NetworkObservations.correct_close_events` + :param int remove_dead_end: Number of days in + :py:meth:`~py_eddy_tracker.observation.network.NetworkObservations.remove_dead_end` + :return target_forward, target_bakward: 2D numpy.array with the eddy observation the + particles ended in after advection + :return target_forward, target_bakward: percentage of ending particles within the + eddy observation with regards to the starting number + """ if dissociate_network: self.dissociate_network() @@ -1393,19 +1434,53 @@ def analysis_coherence( else: network_clean = self - res = network_clean.segment_coherence( - date_function=date_function, - uv_params=uv_params, - advection_mode=advection_mode, - output_name=output_name, - dt_advect=dt_advect, - step_mesh=step_mesh, - ) + network_clean.numbering_segment() + + res = [] + if (advection_mode == "both") | (advection_mode == "forward"): + target_forward, pct_forward = network_clean.segment_coherence_forward( + date_function=date_function, + uv_params=uv_params, + n_days=n_days, + step_mesh=step_mesh, + ) + res = res + [target_forward, pct_forward] + + if (advection_mode == "both") | (advection_mode == "backward"): + target_backward, pct_backward = network_clean.segment_coherence_backward( + date_function=date_function, + uv_params=uv_params, + n_days=n_days, + step_mesh=step_mesh, + ) + res = res + [target_backward, pct_backward] + + if (output_name is not None) & (advection_mode == "both"): + # TODO : put some path verification? + # Save the clean network in netcdf + with netCDF4.Dataset(output_name + ".nc", "w") as fh: + network_clean.to_netcdf(fh) + # Save the results of particles advection in zarr + # zarr compression parameters + # TODO : check size? compression? + params_seg = dict() + params_pct = dict() + zg = zarr.open(output_name + ".zarr", mode="w") + zg.array("target_forward", target_forward, **params_seg) + zg.array("pct_forward", pct_forward, **params_pct) + zg.array("target_backward", target_backward, **params_seg) + zg.array("pct_backward", pct_backward, **params_pct) return network_clean, res def segment_coherence_backward( - self, date_function, uv_params, n_days=14, step_mesh=1.0 / 50, output_name=None, + self, + date_function, + uv_params, + n_days=14, + step_mesh=1.0 / 50, + contour_start="speed", + contour_end="speed", ): """ @@ -1434,7 +1509,7 @@ def date2file(julian_day): itb_final = -ones((self.obs.size, 2), dtype="i4") ptb_final = zeros((self.obs.size, 2), dtype="i1") - t_start, t_end = self.period + t_start, t_end = int(self.period[0]), int(self.period[1]) dates = arange(t_start, t_start + n_days + 1) first_files = [date_function(x) for x in dates] @@ -1455,17 +1530,33 @@ def date2file(julian_day): # add next date to GridCollection and delete last date c.shift_files(t_shift, date_function(int(t_shift)), **uv_params) particle_candidate( - c, self, step_mesh, _t, itb_final, ptb_final, n_days=-n_days + c, + self, + step_mesh, + _t, + itb_final, + ptb_final, + n_days=-n_days, + contour_start=contour_start, + contour_end=contour_end, + ) + logger.info( + ( + f"coherence {_t} / {range_end-1} ({(_t - range_start) / (range_end - range_start-1):.1%})" + f" : {time.time()-_timestamp:5.2f}s" + ) ) - logger.info(( - f"coherence {_t} / {range_end-1} ({(_t - range_start) / (range_end - range_start-1):.1%})" - f" : {time.time()-_timestamp:5.2f}s" - )) return itb_final, ptb_final def segment_coherence_forward( - self, date_function, uv_params, n_days=14, step_mesh=1.0 / 50, + self, + date_function, + uv_params, + n_days=14, + step_mesh=1.0 / 50, + contour_start="speed", + contour_end="speed", ): """ @@ -1494,7 +1585,7 @@ def date2file(julian_day): itf_final = -ones((self.obs.size, 2), dtype="i4") ptf_final = zeros((self.obs.size, 2), dtype="i1") - t_start, t_end = self.period + t_start, t_end = int(self.period[0]), int(self.period[1]) # if begin is not None and begin > t_start: # t_start = begin # if end is not None and end < t_end: @@ -1519,12 +1610,22 @@ def date2file(julian_day): # add next date to GridCollection and delete last date c.shift_files(t_shift, date_function(int(t_shift)), **uv_params) particle_candidate( - c, self, step_mesh, _t, itf_final, ptf_final, n_days=n_days + c, + self, + step_mesh, + _t, + itf_final, + ptf_final, + n_days=n_days, + contour_start=contour_start, + contour_end=contour_end, + ) + logger.info( + ( + f"coherence {_t} / {range_end-1} ({(_t - range_start) / (range_end - range_start-1):.1%})" + f" : {time.time()-_timestamp:5.2f}s" + ) ) - logger.info(( - f"coherence {_t} / {range_end-1} ({(_t - range_start) / (range_end - range_start-1):.1%})" - f" : {time.time()-_timestamp:5.2f}s" - )) return itf_final, ptf_final diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index db0c2a45..dec9a6b0 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -702,7 +702,11 @@ def load_file(cls, filename, **kwargs): .. code-block:: python kwargs_latlon_300 = dict( - include_vars=["longitude", "latitude",], indexs=dict(obs=slice(0, 300)), + include_vars=[ + "longitude", + "latitude", + ], + indexs=dict(obs=slice(0, 300)), ) small_dataset = TrackEddiesObservations.load_file( filename, **kwargs_latlon_300 @@ -1973,7 +1977,11 @@ def bins_stat(self, xname, bins=None, yname=None, method=None, mask=None): def format_label(self, label): t0, t1 = self.period - return label.format(t0=t0, t1=t1, nb_obs=len(self),) + return label.format( + t0=t0, + t1=t1, + nb_obs=len(self), + ) def display(self, ax, ref=None, extern_only=False, intern_only=False, **kwargs): """Plot the speed and effective (dashed) contour of the eddies @@ -2283,7 +2291,7 @@ def nb_days(self): return self.period[1] - self.period[0] + 1 def create_particles(self, step, intern=True): - """create particles only inside speed contour. Avoid creating too large numpy arrays, only to me masked + """Create particles inside contour (Default : speed contour). Avoid creating too large numpy arrays, only to be masked :param step: step for particles :type step: float @@ -2345,7 +2353,14 @@ def grid_count_pixel_in( x_, y_ = reduce_size(x_, y_) v = create_vertice(x_, y_) (x_start, x_stop), (y_start, y_stop) = bbox_indice_regular( - v, x_bounds, y_bounds, xstep, ystep, N, is_circular, x_size, + v, + x_bounds, + y_bounds, + xstep, + ystep, + N, + is_circular, + x_size, ) i, j = get_pixel_in_regular(v, x_c, y_c, x_start, x_stop, y_start, y_stop) grid_count_(grid, i, j) diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index 492842c7..3aa43387 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -578,7 +578,10 @@ def close_tracks(self, other, nb_obs_min=10, **kwargs): def format_label(self, label): t0, t1 = self.period return label.format( - t0=t0, t1=t1, nb_obs=len(self), nb_tracks=(self.nb_obs_by_track != 0).sum(), + t0=t0, + t1=t1, + nb_obs=len(self), + nb_tracks=(self.nb_obs_by_track != 0).sum(), ) def plot(self, ax, ref=None, **kwargs): @@ -702,7 +705,16 @@ def follow_obs(cls, i_next, track_id, used, ids, *args, **kwargs): @staticmethod def get_previous_obs( - i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs + i_current, + ids, + x, + y, + time_s, + time_e, + time_ref, + window, + min_overlap=0.01, + **kwargs, ): """Backward association of observations to the segments""" time_cur = int_(ids["time"][i_current]) @@ -720,7 +732,7 @@ def get_previous_obs( c = zeros(len(xj)) c[ij] = vertice_overlap(xi[ii], yi[ii], xj[ij], yj[ij], **kwargs) # We remove low overlap - c[c < 0.01] = 0 + c[c < min_overlap] = 0 # We get index of maximal overlap i = c.argmax() c_i = c[i] @@ -732,7 +744,18 @@ def get_previous_obs( break @staticmethod - def get_next_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwargs): + def get_next_obs( + i_current, + ids, + x, + y, + time_s, + time_e, + time_ref, + window, + min_overlap=0.01, + **kwargs, + ): """Forward association of observations to the segments""" time_max = time_e.shape[0] - 1 time_cur = int_(ids["time"][i_current]) @@ -752,7 +775,7 @@ def get_next_obs(i_current, ids, x, y, time_s, time_e, time_ref, window, **kwarg c = zeros(len(xj)) c[ij] = vertice_overlap(xi[ii], yi[ii], xj[ij], yj[ij], **kwargs) # We remove low overlap - c[c < 0.01] = 0 + c[c < min_overlap] = 0 # We get index of maximal overlap i = c.argmax() c_i = c[i] diff --git a/tests/test_grid.py b/tests/test_grid.py index 34187357..2c89550a 100644 --- a/tests/test_grid.py +++ b/tests/test_grid.py @@ -7,7 +7,15 @@ 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 = Path( + ( + (-X, 0), + (X, 0), + (X, X), + (-X, X), + (-X, 0), + ) +) # contour From 80c529a0981d3e56bc5efd4eddf0f165aa7c6a61 Mon Sep 17 00:00:00 2001 From: Cori Pegliasco Date: Tue, 17 Aug 2021 14:00:51 +0200 Subject: [PATCH 179/249] numba requires specific numpy version because doc compil finds error: numpy 1.21.2 is installed but numpy<1.21,>=1.17 is required by {'numba'} --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 097e786a..477cf32d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ matplotlib netCDF4 numba>=0.53 -numpy +numpy<1.21 opencv-python pint polygon3 From c63fea2adb614410dd0db4f969eac7ce0731fdec Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Thu, 16 Sep 2021 13:18:39 +0200 Subject: [PATCH 180/249] remove argument for conda setup --- environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment.yml b/environment.yml index 941bb7aa..cf1de6f6 100644 --- a/environment.yml +++ b/environment.yml @@ -6,6 +6,6 @@ dependencies: - python=3.7 - ffmpeg - pip: - - -r file:requirements.txt + - -r requirements.txt - pyeddytrackersample - . From 3afb70969397e9f8b25e4fe95a81c10bd1e73915 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Sun, 26 Sep 2021 18:27:08 +0200 Subject: [PATCH 181/249] add changelog infos --- CHANGELOG.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f33f15dd..6c37a82f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -19,6 +19,9 @@ Changed Fixed ^^^^^ +- Fix bug in convolution(filter), lowest rows was replace by zeros in convolution computation. + Important impact for tiny kernel + Added ^^^^^ From a7ef56e6ec60012e6bf6d036e1d5b3c01a35bede Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Fri, 17 Sep 2021 20:52:04 +0200 Subject: [PATCH 182/249] Github : Apply test on Ubuntu & Windows for python 37,38,39 --- .github/workflows/python-app.yml | 20 ++++++++++++++------ README.md | 2 ++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 7fc9f385..286d9d6c 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -7,19 +7,27 @@ on: [push, pull_request] jobs: build: - - runs-on: ubuntu-latest + strategy: + matrix: + # os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, windows-latest] + python_version: [3.7, 3.8, 3.9] + name: Run py eddy tracker build tests + runs-on: ${{ matrix.os }} + defaults: + run: + shell: bash -l {0} steps: - uses: actions/checkout@v2 - - name: Set up Python 3.7 + - name: Set up Python ${{ matrix.python_version }} uses: actions/setup-python@v2 with: - python-version: 3.7 + python-version: ${{ matrix.python_version }} - name: Install dependencies run: | python -m pip install --upgrade pip - pip install flake8 pytest + pip install flake8 pytest pytest-cov if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Install package run: | @@ -32,4 +40,4 @@ jobs: flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - name: Test with pytest run: | - pytest + pytest --cov src/py_eddy_tracker diff --git a/README.md b/README.md index 736bf9b7..e26e15ac 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ Method was described in : +[Pegliasco, C., Delepoulle, A., Morrow, R., Faugère, Y., and Dibarboure, G.: META3.1exp : A new Global Mesoscale Eddy Trajectories Atlas derived from altimetry, Earth Syst. Sci. Data Discuss.](https://doi.org/10.5194/essd-2021-300) + [Mason, E., A. Pascual, and J. C. McWilliams, 2014: A new sea surface height–based code for oceanic mesoscale eddy tracking.](https://doi.org/10.1175/JTECH-D-14-00019.1) ### Use case ### From 98161f3f531c23879b6394e07bbbe015c9732de0 Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Sat, 25 Sep 2021 16:14:49 +0200 Subject: [PATCH 183/249] Add dummy test on convolution => which detect an index error in original code(corrected) --- requirements.txt | 2 +- src/py_eddy_tracker/dataset/grid.py | 4 +- src/py_eddy_tracker/observations/network.py | 26 +++--------- tests/test_grid.py | 45 ++++++++++++++++----- 4 files changed, 44 insertions(+), 33 deletions(-) diff --git a/requirements.txt b/requirements.txt index 477cf32d..c4ff9c41 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -matplotlib +matplotlib<3.5 netCDF4 numba>=0.53 numpy<1.21 diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 6c8e332f..59cda040 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -680,6 +680,7 @@ def eddy_identification( ) z_min, z_max = z_min_p, z_max_p + logger.debug("Levels from %f to %f", z_min, z_max) levels = arange(z_min - z_min % step, z_max - z_max % step + 2 * step, step) # Get x and y values @@ -1404,7 +1405,8 @@ def convolve_filter_with_dynamic_kernel( tmp_matrix = ma.zeros((2 * d_lon + data.shape[0], k_shape[1])) tmp_matrix.mask = ones(tmp_matrix.shape, dtype=bool) # Slice to apply on input data - sl_lat_data = slice(max(0, i - d_lat), min(i + d_lat, data.shape[1])) + # +1 for upper bound, to take in acount this column + sl_lat_data = slice(max(0, i - d_lat), min(i + d_lat + 1, data.shape[1])) # slice to apply on temporary matrix to store input data sl_lat_in = slice( d_lat - (i - sl_lat_data.start), d_lat + (sl_lat_data.stop - i) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 0ae80634..90bf6b70 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -6,6 +6,8 @@ import time from glob import glob +import netCDF4 +import zarr from numba import njit from numpy import ( arange, @@ -23,9 +25,6 @@ zeros, ) -import netCDF4 -import zarr - from ..dataset.grid import GridCollection from ..generic import build_index, wrap_longitude from ..poly import bbox_intersection, vertice_overlap @@ -680,13 +679,7 @@ def display_timeline( """ self.only_one_network() j = 0 - line_kw = dict( - ls="-", - marker="+", - markersize=6, - zorder=1, - lw=3, - ) + line_kw = dict(ls="-", marker="+", markersize=6, zorder=1, lw=3,) line_kw.update(kwargs) mappables = dict(lines=list()) @@ -919,10 +912,7 @@ def event_map(self, ax, **kwargs): """Add the merging and splitting events to a map""" j = 0 mappables = dict() - symbol_kw = dict( - markersize=10, - color="k", - ) + symbol_kw = dict(markersize=10, color="k",) symbol_kw.update(kwargs) symbol_kw_split = symbol_kw.copy() symbol_kw_split["markersize"] += 4 @@ -951,13 +941,7 @@ def event_map(self, ax, **kwargs): return mappables def scatter( - self, - ax, - name="time", - factor=1, - ref=None, - edgecolor_cycle=None, - **kwargs, + self, ax, name="time", factor=1, ref=None, edgecolor_cycle=None, **kwargs, ): """ This function scatters the path of each network, with the merging and splitting events diff --git a/tests/test_grid.py b/tests/test_grid.py index 2c89550a..759a40e1 100644 --- a/tests/test_grid.py +++ b/tests/test_grid.py @@ -1,5 +1,5 @@ from matplotlib.path import Path -from numpy import array, isnan, ma +from numpy import arange, array, isnan, ma, nan, ones, zeros from pytest import approx from py_eddy_tracker.data import get_demo_path @@ -7,15 +7,7 @@ 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 = Path(((-X, 0), (X, 0), (X, X), (-X, X), (-X, 0),)) # contour @@ -85,3 +77,36 @@ def test_interp(): assert g.interp("z", x0, y0) == 1.5 assert g.interp("z", x1, y1) == 2 assert isnan(g.interp("z", x2, y2)) + + +def test_convolution(): + """ + Add some dummy check on convolution filter + """ + # Fake grid + z = ma.array( + arange(12).reshape((-1, 1)) * arange(10).reshape((1, -1)), + mask=zeros((12, 10), dtype="bool"), + dtype="f4", + ) + g = RegularGridDataset.with_array( + coordinates=("x", "y"), + datas=dict(z=z, x=arange(0, 6, 0.5), y=arange(0, 5, 0.5),), + centered=True, + ) + + def kernel_func(lat): + return ones((3, 3)) + + # After transpose we must get same result + d = g.convolve_filter_with_dynamic_kernel("z", kernel_func) + assert (d.T[:9, :9] == d[:9, :9]).all() + # We mask one value and check convolution result + z.mask[2, 2] = True + d = g.convolve_filter_with_dynamic_kernel("z", kernel_func) + assert d[1, 1] == z[:3, :3].sum() / 8 + # Add nan and check only nearest value is contaminate + z[2, 2] = nan + d = g.convolve_filter_with_dynamic_kernel("z", kernel_func) + assert not isnan(d[0, 0]) + assert isnan(d[1:4, 1:4]).all() From e49e1232bf5979791b341386d6dddc9d0b771043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Mon, 11 Oct 2021 15:53:44 +0200 Subject: [PATCH 184/249] change get_color() to get_edgecolor --- requirements.txt | 2 +- src/py_eddy_tracker/eddy_feature.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index c4ff9c41..477cf32d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -matplotlib<3.5 +matplotlib netCDF4 numba>=0.53 numpy<1.21 diff --git a/src/py_eddy_tracker/eddy_feature.py b/src/py_eddy_tracker/eddy_feature.py index 59a042fe..d2616957 100644 --- a/src/py_eddy_tracker/eddy_feature.py +++ b/src/py_eddy_tracker/eddy_feature.py @@ -646,7 +646,7 @@ def display( paths.append(i.vertices) local_kwargs = kwargs.copy() if "color" not in kwargs: - local_kwargs["color"] = collection.get_color() + local_kwargs["color"] = collection.get_edgecolor() local_kwargs.pop("label", None) elif j != 0: local_kwargs.pop("label", None) From 25bf0ee2f6287ddc68aa704e1d1f6343e03d3c1d Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Tue, 19 Oct 2021 22:13:12 +0200 Subject: [PATCH 185/249] Add option to manage issue #111 --- CHANGELOG.rst | 2 ++ src/py_eddy_tracker/dataset/grid.py | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6c37a82f..75cc2dd0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -25,6 +25,8 @@ Fixed Added ^^^^^ +- Allow to replace mask by isnan method to manage nan data instead of masked data + [3.5.0] - 2021-06-22 -------------------- diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 59cda040..2bb5b70d 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -258,6 +258,7 @@ class GridDataset(object): "global_attrs", "vars", "contours", + "nan_mask", ) GRAVITY = 9.807 @@ -267,7 +268,14 @@ class GridDataset(object): N = 1 def __init__( - self, filename, x_name, y_name, centered=None, indexs=None, unset=False + self, + filename, + x_name, + y_name, + centered=None, + indexs=None, + unset=False, + nan_masking=False, ): """ :param str filename: Filename to load @@ -276,6 +284,7 @@ def __init__( :param bool,None centered: Allow to know how coordinates could be used with pixel :param dict indexs: A dictionary that sets indexes to use for non-coordinate dimensions :param bool unset: Set to True to create an empty grid object without file + :param bool nan_masking: Set to True to replace data.mask with isnan method result """ self.dimensions = None self.variables_description = None @@ -286,6 +295,7 @@ def __init__( self.y_bounds = None self.x_dim = None self.y_dim = None + self.nan_mask = nan_masking self.centered = centered self.contours = None self.filename = filename @@ -519,6 +529,10 @@ def grid(self, varname, indexs=None): if i_x > i_y: self.variables_description[varname]["infos"]["transpose"] = True self.vars[varname] = self.vars[varname].T + if self.nan_mask: + self.vars[varname] = ma.array( + self.vars[varname], mask=isnan(self.vars[varname]), + ) if not hasattr(self.vars[varname], "mask"): self.vars[varname] = ma.array( self.vars[varname], From c7255e40ec96861c62635f7cc72f72ca7ff98554 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Tue, 26 Oct 2021 12:08:04 +0200 Subject: [PATCH 186/249] remove coverage --- .github/workflows/python-app.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 286d9d6c..a6fcceed 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -38,6 +38,3 @@ jobs: flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - - name: Test with pytest - run: | - pytest --cov src/py_eddy_tracker From c434372c3f8a05155eb4fdbe4b9996969f3b661e Mon Sep 17 00:00:00 2001 From: Cori Pegliasco Date: Tue, 23 Nov 2021 14:18:27 +0100 Subject: [PATCH 187/249] Resample contours in output form after fitting circles - add parameter presampling_multiplier to evenly over-resample before fitting circles - fit circles to get eddy parameters (radius, area, etc) - resample the contours with the output sampling --- src/py_eddy_tracker/dataset/grid.py | 66 +++++++++++++++++++---------- src/py_eddy_tracker/poly.py | 2 +- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 2bb5b70d..5b884b68 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -607,6 +607,7 @@ def eddy_identification( date, step=0.005, shape_error=55, + presampling_multiplier=10, sampling=50, sampling_method="visvalingam", pixel_limit=None, @@ -624,8 +625,10 @@ def eddy_identification( :param datetime.datetime date: Date to be stored in object to date data :param float,int step: Height between two layers in m :param float,int shape_error: Maximal error allowed for outermost contour in % + :param int presampling_multiplier: + Evenly oversample the initial number of points in the contour by nb_pts x presampling_multiplier to fit circles :param int sampling: Number of points to store contours and speed profile - :param str sampling_method: Method to resample, 'uniform' or 'visvalingam' + :param str sampling_method: Method to resample the stored contours, 'uniform' or 'visvalingam' :param (int,int),None pixel_limit: Min and max number of pixels inside the inner and the outermost contour to be considered as an eddy :param float,None precision: Truncate values at the defined precision in m @@ -849,42 +852,59 @@ def eddy_identification( obs.amplitude[:] = amp.amplitude obs.speed_average[:] = max_average_speed obs.num_point_e[:] = contour.lon.shape[0] - xy_e = resample(contour.lon, contour.lat, **out_sampling) - obs.contour_lon_e[:], obs.contour_lat_e[:] = xy_e obs.num_point_s[:] = speed_contour.lon.shape[0] - xy_s = resample( - speed_contour.lon, speed_contour.lat, **out_sampling - ) - obs.contour_lon_s[:], obs.contour_lat_s[:] = xy_s - # FIXME : we use a contour without resampling - # First, get position based on innermost contour - centlon_i, centlat_i, _, _ = _fit_circle_path( - create_vertice(inner_contour.lon, inner_contour.lat) + # Evenly resample contours with nb_pts = nb_pts_original x presampling_multiplier + xy_i = uniform_resample( + inner_contour.lon, + inner_contour.lat, + num_fac=presampling_multiplier + ) + xy_e = uniform_resample( + contour.lon, + contour.lat, + num_fac=presampling_multiplier, ) - # Second, get speed-based radius based on contour of max uavg + xy_s = uniform_resample( + speed_contour.lon, + speed_contour.lat, + num_fac=presampling_multiplier, + ) + + # First, get position of max SSH based on best fit circle with resampled innermost contour + centlon_i, centlat_i, _, _ = _fit_circle_path(create_vertice(*xy_i)) + obs.lon_max[:] = centlon_i + obs.lat_max[:] = centlat_i + + # Second, get speed-based radius, shape error, eddy center, area based on resampled contour of max uavg centlon_s, centlat_s, eddy_radius_s, aerr_s = _fit_circle_path( create_vertice(*xy_s) ) - # Compute again to use resampled contour - _, _, eddy_radius_e, aerr_e = _fit_circle_path( - create_vertice(*xy_e) - ) - obs.radius_s[:] = eddy_radius_s - obs.radius_e[:] = eddy_radius_e - obs.shape_error_e[:] = aerr_e obs.shape_error_s[:] = aerr_s obs.speed_area[:] = poly_area( *coordinates_to_local(*xy_s, lon0=centlon_s, lat0=centlat_s) ) + obs.lon[:] = centlon_s + obs.lat[:] = centlat_s + + # Third, compute effective radius, shape error, area from resampled effective contour + _, _, eddy_radius_e, aerr_e = _fit_circle_path( + create_vertice(*xy_e) + ) + obs.radius_e[:] = eddy_radius_e + obs.shape_error_e[:] = aerr_e obs.effective_area[:] = poly_area( *coordinates_to_local(*xy_e, lon0=centlon_s, lat0=centlat_s) ) - obs.lon[:] = centlon_s - obs.lat[:] = centlat_s - obs.lon_max[:] = centlon_i - obs.lat_max[:] = centlat_i + + # Finally, resample contours with output parameters + xy_e_f = resample(*xy_e, **out_sampling) + xy_s_f = resample(*xy_s, **out_sampling) + + obs.contour_lon_s[:], obs.contour_lat_s[:] = xy_s_f + obs.contour_lon_e[:], obs.contour_lat_e[:] = xy_e_f + if aerr > 99.9 or aerr_s > 99.9: logger.warning( "Strange shape at this step! shape_error : %f, %f", diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index 0f0271ee..56fb55e7 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -86,7 +86,7 @@ def poly_area_vertice(v): @njit(cache=True) def poly_area(x, y): """ - Must be call with local coordinates (in m, to get an area in m²). + Must be called with local coordinates (in m, to get an area in m²). :param array x: :param array y: From 573c4f5e6991a41004fd9bcbaa72d04fe5c0cbfa Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Thu, 2 Sep 2021 13:30:02 +0200 Subject: [PATCH 188/249] Add information about animation #102 --- examples/08_tracking_manipulation/pet_track_anim.py | 4 +++- .../pet_track_anim_matplotlib_animation.py | 4 +++- .../08_tracking_manipulation/pet_track_anim.ipynb | 4 ++-- .../pet_track_anim_matplotlib_animation.ipynb | 4 ++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/examples/08_tracking_manipulation/pet_track_anim.py b/examples/08_tracking_manipulation/pet_track_anim.py index 0c18a0ba..94e09ad3 100644 --- a/examples/08_tracking_manipulation/pet_track_anim.py +++ b/examples/08_tracking_manipulation/pet_track_anim.py @@ -2,7 +2,9 @@ Track animation =============== -Run in a terminal this script, which allow to watch eddy evolution +Run in a terminal this script, which allow to watch eddy evolution. + +You could use also *EddyAnim* script to display/save animation. """ import py_eddy_tracker_sample diff --git a/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py b/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py index 6776b47e..59b21527 100644 --- a/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py +++ b/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py @@ -2,7 +2,9 @@ Track animation with standard matplotlib ======================================== -Run in a terminal this script, which allow to watch eddy evolution +Run in a terminal this script, which allow to watch eddy evolution. + +You could use also *EddyAnim* script to display/save animation. """ import re diff --git a/notebooks/python_module/08_tracking_manipulation/pet_track_anim.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_track_anim.ipynb index 65768145..08364d16 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_track_anim.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_track_anim.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# Track animation\n\nRun in a terminal this script, which allow to watch eddy evolution\n" + "\nTrack animation\n===============\n\nRun in a terminal this script, which allow to watch eddy evolution.\n\nYou could use also *EddyAnim* script to display/save animation.\n" ] }, { @@ -82,7 +82,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.9" + "version": "3.7.7" } }, "nbformat": 4, diff --git a/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb index 6d7fcc2e..bcd4ba74 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# Track animation with standard matplotlib\n\nRun in a terminal this script, which allow to watch eddy evolution\n" + "\nTrack animation with standard matplotlib\n========================================\n\nRun in a terminal this script, which allow to watch eddy evolution.\n\nYou could use also *EddyAnim* script to display/save animation.\n" ] }, { @@ -93,7 +93,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.9" + "version": "3.7.7" } }, "nbformat": 4, From b357421817442f3e8637dc2736c27365e344c4bf Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Mon, 13 Dec 2021 11:11:30 +0100 Subject: [PATCH 189/249] Loopers (#118) * Add short example about loopers and eddies --- CHANGELOG.rst | 2 + examples/06_grid_manipulation/pet_advect.py | 2 +- examples/06_grid_manipulation/pet_lavd.py | 8 +- examples/07_cube_manipulation/pet_cube.py | 2 +- .../pet_track_anim_matplotlib_animation.py | 2 +- .../pet_normalised_lifetime.py | 18 +- .../12_external_data/pet_drifter_loopers.py | 153 ++++++++++++++ examples/16_network/pet_follow_particle.py | 2 +- examples/16_network/pet_group_anim.py | 2 +- examples/16_network/pet_ioannou_2017_case.py | 2 +- examples/16_network/pet_segmentation_anim.py | 5 +- .../06_grid_manipulation/pet_advect.ipynb | 18 +- .../06_grid_manipulation/pet_lavd.ipynb | 20 +- .../07_cube_manipulation/pet_cube.ipynb | 14 +- .../pet_track_anim_matplotlib_animation.ipynb | 4 +- .../pet_normalised_lifetime.ipynb | 12 +- .../pet_drifter_loopers.ipynb | 191 ++++++++++++++++++ .../16_network/pet_follow_particle.ipynb | 8 +- .../16_network/pet_group_anim.ipynb | 10 +- .../16_network/pet_ioannou_2017_case.ipynb | 22 +- .../16_network/pet_segmentation_anim.ipynb | 2 +- .../data/loopers_lumpkin_med.nc | Bin 0 -> 244130 bytes src/py_eddy_tracker/observations/network.py | 4 +- .../observations/observation.py | 3 +- src/py_eddy_tracker/observations/tracking.py | 13 +- src/py_eddy_tracker/poly.py | 20 +- 26 files changed, 432 insertions(+), 107 deletions(-) create mode 100644 examples/12_external_data/pet_drifter_loopers.py create mode 100644 notebooks/python_module/12_external_data/pet_drifter_loopers.ipynb create mode 100644 src/py_eddy_tracker/data/loopers_lumpkin_med.nc diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 75cc2dd0..c6ab4cac 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -21,11 +21,13 @@ Fixed - Fix bug in convolution(filter), lowest rows was replace by zeros in convolution computation. Important impact for tiny kernel +- Fix method of sampling before contour fitting Added ^^^^^ - Allow to replace mask by isnan method to manage nan data instead of masked data +- Add drifter colocation example [3.5.0] - 2021-06-22 -------------------- diff --git a/examples/06_grid_manipulation/pet_advect.py b/examples/06_grid_manipulation/pet_advect.py index 0e00697f..1a98536a 100644 --- a/examples/06_grid_manipulation/pet_advect.py +++ b/examples/06_grid_manipulation/pet_advect.py @@ -50,7 +50,7 @@ def _repr_html_(self, *args, **kwargs): 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 + # 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 diff --git a/examples/06_grid_manipulation/pet_lavd.py b/examples/06_grid_manipulation/pet_lavd.py index e597821c..89d64108 100644 --- a/examples/06_grid_manipulation/pet_lavd.py +++ b/examples/06_grid_manipulation/pet_lavd.py @@ -65,7 +65,7 @@ def _repr_html_(self, *args, **kwargs): 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 + # 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 @@ -159,11 +159,7 @@ def update(i_frame): # Format LAVD data lavd = RegularGridDataset.with_array( coordinates=("lon", "lat"), - datas=dict( - lavd=lavd.T, - lon=x_g, - lat=y_g, - ), + datas=dict(lavd=lavd.T, lon=x_g, lat=y_g,), centered=True, ) diff --git a/examples/07_cube_manipulation/pet_cube.py b/examples/07_cube_manipulation/pet_cube.py index a674359d..7f30c4e1 100644 --- a/examples/07_cube_manipulation/pet_cube.py +++ b/examples/07_cube_manipulation/pet_cube.py @@ -31,7 +31,7 @@ def _repr_html_(self, *args, **kwargs): 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 + # 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 diff --git a/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py b/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py index 59b21527..81e57e59 100644 --- a/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py +++ b/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py @@ -30,7 +30,7 @@ def _repr_html_(self, *args, **kwargs): 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 + # 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 diff --git a/examples/10_tracking_diagnostics/pet_normalised_lifetime.py b/examples/10_tracking_diagnostics/pet_normalised_lifetime.py index 73e5274e..1c84a8cc 100644 --- a/examples/10_tracking_diagnostics/pet_normalised_lifetime.py +++ b/examples/10_tracking_diagnostics/pet_normalised_lifetime.py @@ -65,14 +65,14 @@ def eddy_norm_lifetime(self, name, nb, factor=1): # %% # Figure # ------ -fig, axs = plt.subplots(nrows=2, figsize=(8, 6)) +fig, (ax0, ax1) = plt.subplots(nrows=2, figsize=(8, 6)) -axs[0].set_title("Normalised Mean Radius") -axs[0].plot(*AC_radius), axs[0].plot(*CC_radius) -axs[0].set_ylabel("Radius (km)"), axs[0].grid() -axs[0].set_xlim(0, 1), axs[0].set_ylim(0, None) +ax0.set_title("Normalised Mean Radius") +ax0.plot(*AC_radius), ax0.plot(*CC_radius) +ax0.set_ylabel("Radius (km)"), ax0.grid() +ax0.set_xlim(0, 1), ax0.set_ylim(0, None) -axs[1].set_title("Normalised Mean Amplitude") -axs[1].plot(*AC_amplitude, label="AC"), axs[1].plot(*CC_amplitude, label="CC") -axs[1].set_ylabel("Amplitude (cm)"), axs[1].grid(), axs[1].legend() -_ = axs[1].set_xlim(0, 1), axs[1].set_ylim(0, None) +ax1.set_title("Normalised Mean Amplitude") +ax1.plot(*AC_amplitude, label="AC"), ax1.plot(*CC_amplitude, label="CC") +ax1.set_ylabel("Amplitude (cm)"), ax1.grid(), ax1.legend() +_ = ax1.set_xlim(0, 1), ax1.set_ylim(0, None) diff --git a/examples/12_external_data/pet_drifter_loopers.py b/examples/12_external_data/pet_drifter_loopers.py new file mode 100644 index 00000000..92707906 --- /dev/null +++ b/examples/12_external_data/pet_drifter_loopers.py @@ -0,0 +1,153 @@ +""" +Colocate looper with eddy from altimetry +======================================== + +All loopers data used in this example are a subset from the dataset described in this article +[Lumpkin, R. : Global characteristics of coherent vortices from surface drifter trajectories](https://doi.org/10.1002/2015JC011435) +""" + +import re + +import numpy as np +import py_eddy_tracker_sample +from matplotlib import pyplot as plt +from matplotlib.animation import FuncAnimation + +from py_eddy_tracker import data +from py_eddy_tracker.appli.gui import Anim +from py_eddy_tracker.observations.tracking import TrackEddiesObservations + + +# %% +class VideoAnimation(FuncAnimation): + def _repr_html_(self, *args, **kwargs): + """To get video in html and have a player""" + 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) + + +def start_axes(title): + fig = plt.figure(figsize=(13, 5)) + ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], aspect="equal") + ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46) + ax.set_title(title, weight="bold") + return ax + + +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 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)) +ax = fig.add_subplot(111, aspect="equal") +looper.plot(ax, lw=0.5, label="Original position of drifter") +looper_filtered = looper.copy() +looper_filtered.position_filter(1, 13) +s = looper_filtered.scatter( + ax, + "time", + cmap=plt.get_cmap("Spectral_r", 20), + label="Filtered position of drifter", +) +plt.colorbar(s).set_label("time (days from 1/1/1950)") +ax.legend() +ax.grid() + +# %% +# Try to find a detected eddies with adt at same place. We used filtered track to simulate an eddy center +match = looper_filtered.close_tracks( + anticyclonic_eddies, method="close_center", delta=0.1, nb_obs_min=50 +) +fig = plt.figure(figsize=(16, 6)) +ax = fig.add_subplot(111, aspect="equal") +looper.plot(ax, lw=0.5, label="Original position of drifter") +looper_filtered.plot(ax, lw=1.5, label="Filtered position of drifter") +match.plot(ax, lw=1.5, label="Matched eddy") +ax.legend() +ax.grid() + +# %% +# Display radius of this 2 datasets. +fig = plt.figure(figsize=(20, 8)) +ax = fig.add_subplot(111) +ax.plot(looper.time, looper.radius_s / 1e3, label="loopers") +looper_radius = looper.copy() +looper_radius.median_filter(1, "time", "radius_s", inplace=True) +looper_radius.loess_filter(13, "time", "radius_s", inplace=True) +ax.plot( + looper_radius.time, + looper_radius.radius_s / 1e3, + label="loopers (filtered half window 13 days)", +) +ax.plot(match.time, match.radius_s / 1e3, label="altimetry") +match_radius = match.copy() +match_radius.median_filter(1, "time", "radius_s", inplace=True) +match_radius.loess_filter(13, "time", "radius_s", inplace=True) +ax.plot( + match_radius.time, + match_radius.radius_s / 1e3, + label="altimetry (filtered half window 13 days)", +) +ax.set_ylabel("radius(km)"), ax.set_ylim(0, 100) +ax.legend() +ax.set_title("Radius from loopers and altimeter") +ax.grid() + + +# %% +# Animation of a drifter and its colocated eddy +def update(frame): + # We display last 5 days of loopers trajectory + m = (looper.time < frame) * (looper.time > (frame - 5)) + anim.func_animation(frame) + line.set_data(looper.lon[m], looper.lat[m]) + + +anim = Anim(match, intern=True, figsize=(8, 8), cmap="magma_r", nb_step=10, dpi=75) +# mappable to show drifter in red +line = anim.ax.plot([], [], "r", lw=4, zorder=100)[0] +anim.fig.suptitle("") +_ = VideoAnimation(anim.fig, update, frames=np.arange(*anim.period, 1), interval=125) diff --git a/examples/16_network/pet_follow_particle.py b/examples/16_network/pet_follow_particle.py index 1c858879..dbe0753e 100644 --- a/examples/16_network/pet_follow_particle.py +++ b/examples/16_network/pet_follow_particle.py @@ -31,7 +31,7 @@ def _repr_html_(self, *args, **kwargs): def save(self, *args, **kwargs): if args[0].endswith("gif"): - # In this case gif is used to create thumbnail which are not used but consumes same time than video + # 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 diff --git a/examples/16_network/pet_group_anim.py b/examples/16_network/pet_group_anim.py index 8ecee534..047f5820 100644 --- a/examples/16_network/pet_group_anim.py +++ b/examples/16_network/pet_group_anim.py @@ -29,7 +29,7 @@ def _repr_html_(self, *args, **kwargs): 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 + # 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 diff --git a/examples/16_network/pet_ioannou_2017_case.py b/examples/16_network/pet_ioannou_2017_case.py index bbe26e3f..b02b846a 100644 --- a/examples/16_network/pet_ioannou_2017_case.py +++ b/examples/16_network/pet_ioannou_2017_case.py @@ -36,7 +36,7 @@ def _repr_html_(self, *args, **kwargs): 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 + # 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 diff --git a/examples/16_network/pet_segmentation_anim.py b/examples/16_network/pet_segmentation_anim.py index 340163a1..58f71188 100644 --- a/examples/16_network/pet_segmentation_anim.py +++ b/examples/16_network/pet_segmentation_anim.py @@ -27,7 +27,7 @@ def _repr_html_(self, *args, **kwargs): 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 + # 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 @@ -96,8 +96,7 @@ def update(i_frame): indices_frames = INDICES[i_frame] mappable_CONTOUR.set_data( - e.contour_lon_e[indices_frames], - e.contour_lat_e[indices_frames], + e.contour_lon_e[indices_frames], e.contour_lat_e[indices_frames], ) mappable_CONTOUR.set_color(cmap.colors[tr[indices_frames] % len(cmap.colors)]) return (mappable_tracks,) diff --git a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb index bceed074..79d69b0d 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# Grid advection\n\nDummy advection which use only static geostrophic current, which didn't solve the complex circulation of the ocean.\n" + "\nGrid advection\n==============\n\nDummy advection which use only static geostrophic current, which didn't solve the complex circulation of the ocean.\n" ] }, { @@ -91,14 +91,14 @@ }, "outputs": [], "source": [ - "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is used to create thumbnail which is not used but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Anim\nParticles setup\n\n" + "Anim\n----\nParticles setup\n\n" ] }, { @@ -152,7 +152,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Filament forward\nDraw 3 last position in one path for each particles.,\nit could be run backward with `backward=True` option in filament method\n\n" + "Filament forward\n^^^^^^^^^^^^^^^^\nDraw 3 last position in one path for each particles.,\nit could be run backward with `backward=True` option in filament method\n\n" ] }, { @@ -170,7 +170,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Particle forward\nForward advection of particles\n\n" + "Particle forward\n^^^^^^^^^^^^^^^^^\nForward advection of particles\n\n" ] }, { @@ -206,14 +206,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Particles stat\n\n" + "Particles stat\n--------------\n\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Time_step settings\nDummy experiment to test advection precision, we run particles 50 days forward and backward with different time step\nand we measure distance between new positions and original positions.\n\n" + "Time_step settings\n^^^^^^^^^^^^^^^^^^\nDummy experiment to test advection precision, we run particles 50 days forward and backward with different time step\nand we measure distance between new positions and original positions.\n\n" ] }, { @@ -231,7 +231,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Time duration\nWe keep same time_step but change time duration\n\n" + "Time duration\n^^^^^^^^^^^^^\nWe keep same time_step but change time duration\n\n" ] }, { @@ -262,7 +262,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.9" + "version": "3.7.7" } }, "nbformat": 4, diff --git a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb index a5ca088c..c4a4da84 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# LAVD experiment\n\nNaive method to reproduce LAVD(Lagrangian-Averaged Vorticity deviation) method with a static velocity field.\nIn the current example we didn't remove a mean vorticity.\n\nMethod are described here:\n\n - Abernathey, Ryan, and George Haller. \"Transport by Lagrangian Vortices in the Eastern Pacific\",\n Journal of Physical Oceanography 48, 3 (2018): 667-685, accessed Feb 16, 2021,\n https://doi.org/10.1175/JPO-D-17-0102.1\n - `Transport by Coherent Lagrangian Vortices`_,\n R. Abernathey, Sinha A., Tarshish N., Liu T., Zhang C., Haller G., 2019,\n Talk a t the Sources and Sinks of Ocean Mesoscale Eddy Energy CLIVAR Workshop\n\n https://usclivar.org/sites/default/files/meetings/2019/presentations/Aberernathey_CLIVAR.pdf\n" + "\nLAVD experiment\n===============\n\nNaive method to reproduce LAVD(Lagrangian-Averaged Vorticity deviation) method with a static velocity field.\nIn the current example we didn't remove a mean vorticity.\n\nMethod are described here:\n\n - Abernathey, Ryan, and George Haller. \"Transport by Lagrangian Vortices in the Eastern Pacific\",\n Journal of Physical Oceanography 48, 3 (2018): 667-685, accessed Feb 16, 2021,\n https://doi.org/10.1175/JPO-D-17-0102.1\n - `Transport by Coherent Lagrangian Vortices`_,\n R. Abernathey, Sinha A., Tarshish N., Liu T., Zhang C., Haller G., 2019,\n Talk a t the Sources and Sinks of Ocean Mesoscale Eddy Energy CLIVAR Workshop\n\n https://usclivar.org/sites/default/files/meetings/2019/presentations/Aberernathey_CLIVAR.pdf\n" ] }, { @@ -48,14 +48,14 @@ }, "outputs": [], "source": [ - "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is used to create thumbnail which is not used but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Data\nTo compute vorticity ($\\omega$) we compute u/v field with a stencil and apply the following equation with stencil\nmethod :\n\n\\begin{align}\\omega = \\frac{\\partial v}{\\partial x} - \\frac{\\partial u}{\\partial y}\\end{align}\n\n" + "Data\n----\nTo compute vorticity ($\\omega$) we compute u/v field with a stencil and apply the following equation with stencil\nmethod :\n\n\\begin{align}\\omega = \\frac{\\partial v}{\\partial x} - \\frac{\\partial u}{\\partial y}\\end{align}\n\n" ] }, { @@ -91,7 +91,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Particles\nParticles specification\n\n" + "Particles\n---------\nParticles specification\n\n" ] }, { @@ -109,7 +109,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## LAVD\n\n" + "LAVD\n----\n\n" ] }, { @@ -127,7 +127,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Anim\nMovie of LAVD integration at each integration time step.\n\n" + "Anim\n^^^^\nMovie of LAVD integration at each integration time step.\n\n" ] }, { @@ -138,14 +138,14 @@ }, "outputs": [], "source": [ - "def update(i_frame):\n global lavd, i\n i += 1\n x, y = particule.__next__()\n # Interp vorticity on new_position\n lavd += abs(g.interp(\"vort\", x, y).reshape(original_shape) * 1 / nb_time)\n txt.set_text(f\"T0 + {i / step_by_day:.2f} days of advection\")\n pcolormesh.set_array(lavd / i * nb_time)\n return pcolormesh, txt\n\n\nkw_video = dict(frames=arange(nb_time), interval=1000.0 / step_by_day / 2, blit=True)\nfig, ax, txt = start_ax(dpi=60)\nx_g_, y_g_ = arange(0 - step / 2, 36 + step / 2, step), arange(\n 28 - step / 2, 46 + step / 2, step\n)\n# pcolorfast will be faster than pcolormesh, we could use pcolorfast due to x and y are regular\npcolormesh = ax.pcolorfast(x_g_, y_g_, lavd, **kw_vorticity)\nupdate_axes(ax, pcolormesh)\n_ = VideoAnimation(ax.figure, update, **kw_video)" + "def update(i_frame):\n global lavd, i\n i += 1\n x, y = particule.__next__()\n # Interp vorticity on new_position\n lavd += abs(g.interp(\"vort\", x, y).reshape(original_shape) * 1 / nb_time)\n txt.set_text(f\"T0 + {i / step_by_day:.2f} days of advection\")\n pcolormesh.set_array(lavd / i * nb_time)\n return pcolormesh, txt\n\n\nkw_video = dict(frames=arange(nb_time), interval=1000.0 / step_by_day / 2, blit=True)\nfig, ax, txt = start_ax(dpi=60)\nx_g_, y_g_ = (\n arange(0 - step / 2, 36 + step / 2, step),\n arange(28 - step / 2, 46 + step / 2, step),\n)\n# pcolorfast will be faster than pcolormesh, we could use pcolorfast due to x and y are regular\npcolormesh = ax.pcolorfast(x_g_, y_g_, lavd, **kw_vorticity)\nupdate_axes(ax, pcolormesh)\n_ = VideoAnimation(ax.figure, update, **kw_video)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Final LAVD\n\n" + "Final LAVD\n^^^^^^^^^^\n\n" ] }, { @@ -163,7 +163,7 @@ }, "outputs": [], "source": [ - "lavd = RegularGridDataset.with_array(\n coordinates=(\"lon\", \"lat\"),\n datas=dict(\n lavd=lavd.T,\n lon=x_g,\n lat=y_g,\n ),\n centered=True,\n)" + "lavd = RegularGridDataset.with_array(\n coordinates=(\"lon\", \"lat\"),\n datas=dict(lavd=lavd.T, lon=x_g, lat=y_g,),\n centered=True,\n)" ] }, { @@ -201,7 +201,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.9" + "version": "3.7.7" } }, "nbformat": 4, diff --git a/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb b/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb index 22cf3158..d4cdb187 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_cube.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# Time advection\n\nExample which use CMEMS surface current with a Runge-Kutta 4 algorithm to advect particles.\n" + "\nTime advection\n==============\n\nExample which use CMEMS surface current with a Runge-Kutta 4 algorithm to advect particles.\n" ] }, { @@ -37,14 +37,14 @@ }, "outputs": [], "source": [ - "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is used to create thumbnail which is not used but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Data\nLoad Input time grid ADT\n\n" + "Data\n----\nLoad Input time grid ADT\n\n" ] }, { @@ -62,7 +62,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Anim\nParticles setup\n\n" + "Anim\n----\nParticles setup\n\n" ] }, { @@ -109,7 +109,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Particules stat\nTime_step settings\n^^^^^^^^^^^^^^^^^^\nDummy experiment to test advection precision, we run particles 50 days forward and backward with different time step\nand we measure distance between new positions and original positions.\n\n" + "Particules stat\n---------------\nTime_step settings\n^^^^^^^^^^^^^^^^^^\nDummy experiment to test advection precision, we run particles 50 days forward and backward with different time step\nand we measure distance between new positions and original positions.\n\n" ] }, { @@ -127,7 +127,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Time duration\nWe keep same time_step but change time duration\n\n" + "Time duration\n^^^^^^^^^^^^^\nWe keep same time_step but change time duration\n\n" ] }, { @@ -158,7 +158,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.9" + "version": "3.7.7" } }, "nbformat": 4, diff --git a/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb index bcd4ba74..1fc4d082 100644 --- a/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb +++ b/notebooks/python_module/08_tracking_manipulation/pet_track_anim_matplotlib_animation.ipynb @@ -37,7 +37,7 @@ }, "outputs": [], "source": [ - "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is used to create thumbnail which is not used but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" ] }, { @@ -98,4 +98,4 @@ }, "nbformat": 4, "nbformat_minor": 0 -} \ No newline at end of file +} diff --git a/notebooks/python_module/10_tracking_diagnostics/pet_normalised_lifetime.ipynb b/notebooks/python_module/10_tracking_diagnostics/pet_normalised_lifetime.ipynb index a53f2d3a..f9fb474f 100644 --- a/notebooks/python_module/10_tracking_diagnostics/pet_normalised_lifetime.ipynb +++ b/notebooks/python_module/10_tracking_diagnostics/pet_normalised_lifetime.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# Normalised Eddy Lifetimes\n\nExample from Evan Mason\n" + "\nNormalised Eddy Lifetimes\n=========================\n\nExample from Evan Mason\n" ] }, { @@ -44,7 +44,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Load atlas\n\n" + "Load atlas\n----------\n\n" ] }, { @@ -62,7 +62,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Compute normalised lifetime\n\n" + "Compute normalised lifetime\n---------------------------\n\n" ] }, { @@ -80,7 +80,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Figure\n\n" + "Figure\n------\n\n" ] }, { @@ -91,7 +91,7 @@ }, "outputs": [], "source": [ - "fig, axs = plt.subplots(nrows=2, figsize=(8, 6))\n\naxs[0].set_title(\"Normalised Mean Radius\")\naxs[0].plot(*AC_radius), axs[0].plot(*CC_radius)\naxs[0].set_ylabel(\"Radius (km)\"), axs[0].grid()\naxs[0].set_xlim(0, 1), axs[0].set_ylim(0, None)\n\naxs[1].set_title(\"Normalised Mean Amplitude\")\naxs[1].plot(*AC_amplitude, label=\"AC\"), axs[1].plot(*CC_amplitude, label=\"CC\")\naxs[1].set_ylabel(\"Amplitude (cm)\"), axs[1].grid(), axs[1].legend()\n_ = axs[1].set_xlim(0, 1), axs[1].set_ylim(0, None)" + "fig, (ax0, ax1) = plt.subplots(nrows=2, figsize=(8, 6))\n\nax0.set_title(\"Normalised Mean Radius\")\nax0.plot(*AC_radius), ax0.plot(*CC_radius)\nax0.set_ylabel(\"Radius (km)\"), ax0.grid()\nax0.set_xlim(0, 1), ax0.set_ylim(0, None)\n\nax1.set_title(\"Normalised Mean Amplitude\")\nax1.plot(*AC_amplitude, label=\"AC\"), ax1.plot(*CC_amplitude, label=\"CC\")\nax1.set_ylabel(\"Amplitude (cm)\"), ax1.grid(), ax1.legend()\n_ = ax1.set_xlim(0, 1), ax1.set_ylim(0, None)" ] } ], @@ -111,7 +111,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.9" + "version": "3.7.7" } }, "nbformat": 4, diff --git a/notebooks/python_module/12_external_data/pet_drifter_loopers.ipynb b/notebooks/python_module/12_external_data/pet_drifter_loopers.ipynb new file mode 100644 index 00000000..7ba30914 --- /dev/null +++ b/notebooks/python_module/12_external_data/pet_drifter_loopers.ipynb @@ -0,0 +1,191 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\nColocate looper with eddy from altimetry\n========================================\n\nAll loopers data used in this example are a subset from the dataset described in this article\n[Lumpkin, R. : Global characteristics of coherent vortices from surface drifter trajectories](https://doi.org/10.1002/2015JC011435)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import re\n\nimport numpy as np\nimport py_eddy_tracker_sample\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\n\nfrom py_eddy_tracker import data\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is used to create thumbnail which is not used but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)\n\n\ndef start_axes(title):\n fig = plt.figure(figsize=(13, 5))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], aspect=\"equal\")\n ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\n ax.set_title(title, weight=\"bold\")\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid()\n if mappable:\n plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load eddies dataset\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "cyclonic_eddies = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\"eddies_med_adt_allsat_dt2018/Cyclonic.zarr\")\n)\nanticyclonic_eddies = TrackEddiesObservations.load_file(\n py_eddy_tracker_sample.get_demo_path(\n \"eddies_med_adt_allsat_dt2018/Anticyclonic.zarr\"\n )\n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load loopers dataset\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "loopers_med = TrackEddiesObservations.load_file(\n data.get_demo_path(\"loopers_lumpkin_med.nc\")\n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Global view\n===========\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = start_axes(\"All drifters available in Med from Lumpkin dataset\")\nloopers_med.plot(ax, lw=0.5, color=\"r\", ref=-10)\nupdate_axes(ax)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One segment of drifter\n======================\n\nGet a drifter segment (the indexes used have no correspondance with the original dataset).\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "looper = loopers_med.extract_ids((3588,))\nfig = plt.figure(figsize=(16, 6))\nax = fig.add_subplot(111, aspect=\"equal\")\nlooper.plot(ax, lw=0.5, label=\"Original position of drifter\")\nlooper_filtered = looper.copy()\nlooper_filtered.position_filter(1, 13)\ns = looper_filtered.scatter(\n ax,\n \"time\",\n cmap=plt.get_cmap(\"Spectral_r\", 20),\n label=\"Filtered position of drifter\",\n)\nplt.colorbar(s).set_label(\"time (days from 1/1/1950)\")\nax.legend()\nax.grid()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Try to find a detected eddies with adt at same place. We used filtered track to simulate an eddy center\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "match = looper_filtered.close_tracks(\n anticyclonic_eddies, method=\"close_center\", delta=0.1, nb_obs_min=50\n)\nfig = plt.figure(figsize=(16, 6))\nax = fig.add_subplot(111, aspect=\"equal\")\nlooper.plot(ax, lw=0.5, label=\"Original position of drifter\")\nlooper_filtered.plot(ax, lw=1.5, label=\"Filtered position of drifter\")\nmatch.plot(ax, lw=1.5, label=\"Matched eddy\")\nax.legend()\nax.grid()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Display radius of this 2 datasets.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(20, 8))\nax = fig.add_subplot(111)\nax.plot(looper.time, looper.radius_s / 1e3, label=\"loopers\")\nlooper_radius = looper.copy()\nlooper_radius.median_filter(1, \"time\", \"radius_s\", inplace=True)\nlooper_radius.loess_filter(13, \"time\", \"radius_s\", inplace=True)\nax.plot(\n looper_radius.time,\n looper_radius.radius_s / 1e3,\n label=\"loopers (filtered half window 13 days)\",\n)\nax.plot(match.time, match.radius_s / 1e3, label=\"altimetry\")\nmatch_radius = match.copy()\nmatch_radius.median_filter(1, \"time\", \"radius_s\", inplace=True)\nmatch_radius.loess_filter(13, \"time\", \"radius_s\", inplace=True)\nax.plot(\n match_radius.time,\n match_radius.radius_s / 1e3,\n label=\"altimetry (filtered half window 13 days)\",\n)\nax.set_ylabel(\"radius(km)\"), ax.set_ylim(0, 100)\nax.legend()\nax.set_title(\"Radius from loopers and altimeter\")\nax.grid()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Animation of a drifter and its colocated eddy\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def update(frame):\n # We display last 5 days of loopers trajectory\n m = (looper.time < frame) * (looper.time > (frame - 5))\n anim.func_animation(frame)\n line.set_data(looper.lon[m], looper.lat[m])\n\n\nanim = Anim(match, intern=True, figsize=(8, 8), cmap=\"magma_r\", nb_step=10, dpi=75)\n# mappable to show drifter in red\nline = anim.ax.plot([], [], \"r\", lw=4, zorder=100)[0]\nanim.fig.suptitle(\"\")\n_ = VideoAnimation(anim.fig, update, frames=np.arange(*anim.period, 1), interval=125)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/notebooks/python_module/16_network/pet_follow_particle.ipynb b/notebooks/python_module/16_network/pet_follow_particle.ipynb index 15820ad3..a2a97944 100644 --- a/notebooks/python_module/16_network/pet_follow_particle.ipynb +++ b/notebooks/python_module/16_network/pet_follow_particle.ipynb @@ -26,7 +26,7 @@ }, "outputs": [], "source": [ - "import re\n\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, meshgrid, ones, unique, zeros\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import GridCollection\nfrom py_eddy_tracker.observations.groups import particle_candidate\nfrom py_eddy_tracker.observations.network import NetworkObservations\nfrom py_eddy_tracker.poly import group_obs\n\nstart_logger().setLevel(\"ERROR\")" + "import re\n\nfrom matplotlib import colors\nfrom matplotlib import pyplot as plt\nfrom matplotlib.animation import FuncAnimation\nfrom numpy import arange, meshgrid, ones, unique, zeros\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.appli.gui import Anim\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import GridCollection\nfrom py_eddy_tracker.observations.groups import particle_candidate\nfrom py_eddy_tracker.observations.network import NetworkObservations\n\nstart_logger().setLevel(\"ERROR\")" ] }, { @@ -37,7 +37,7 @@ }, "outputs": [], "source": [ - "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is used to create thumbnail which are not used but consumes same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is used to create thumbnail which is not used but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" ] }, { @@ -109,7 +109,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Particle advection\n^^^^^^^^^^^^^^^^^^\n\n" + "Particle advection\n^^^^^^^^^^^^^^^^^^\nAdvection from speed contour to speed contour (default)\n\n" ] }, { @@ -120,7 +120,7 @@ }, "outputs": [], "source": [ - "step = 1 / 60.0\n\nx, y = meshgrid(arange(24, 36, step), arange(31, 36, step))\nx0, y0 = x.reshape(-1), y.reshape(-1)\n# Pre-order to speed up\n_, i = group_obs(x0, y0, 1, 360)\nx0, y0 = x0[i], y0[i]\n\nt_start, t_end = n.period\ndt = 14\n\nshape = (n.obs.size, 2)\n# Forward run\ni_target_f, pct_target_f = -ones(shape, dtype=\"i4\"), zeros(shape, dtype=\"i1\")\nfor t in arange(t_start, t_end - dt):\n particle_candidate(x0, y0, c, n, t, i_target_f, pct_target_f, n_days=dt)\n\n# Backward run\ni_target_b, pct_target_b = -ones(shape, dtype=\"i4\"), zeros(shape, dtype=\"i1\")\nfor t in arange(t_start + dt, t_end):\n particle_candidate(x0, y0, c, n, t, i_target_b, pct_target_b, n_days=-dt)" + "step = 1 / 60.0\n\nt_start, t_end = int(n.period[0]), int(n.period[1])\ndt = 14\n\nshape = (n.obs.size, 2)\n# Forward run\ni_target_f, pct_target_f = -ones(shape, dtype=\"i4\"), zeros(shape, dtype=\"i1\")\nfor t in arange(t_start, t_end - dt):\n particle_candidate(c, n, step, t, i_target_f, pct_target_f, n_days=dt)\n\n# Backward run\ni_target_b, pct_target_b = -ones(shape, dtype=\"i4\"), zeros(shape, dtype=\"i1\")\nfor t in arange(t_start + dt, t_end):\n particle_candidate(c, n, step, t, i_target_b, pct_target_b, n_days=-dt)" ] }, { diff --git a/notebooks/python_module/16_network/pet_group_anim.ipynb b/notebooks/python_module/16_network/pet_group_anim.ipynb index 7129259c..090170ff 100644 --- a/notebooks/python_module/16_network/pet_group_anim.ipynb +++ b/notebooks/python_module/16_network/pet_group_anim.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# Network group process\n" + "\nNetwork group process\n=====================\n" ] }, { @@ -37,7 +37,7 @@ }, "outputs": [], "source": [ - "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is used to create thumbnail which is not used but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)" ] }, { @@ -156,7 +156,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Anim\n\n" + "Anim\n----\n\n" ] }, { @@ -174,7 +174,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Final Result\n\n" + "Final Result\n------------\n\n" ] }, { @@ -205,7 +205,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.9" + "version": "3.7.7" } }, "nbformat": 4, diff --git a/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb b/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb index 788e94ca..9d659597 100644 --- a/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb +++ b/notebooks/python_module/16_network/pet_ioannou_2017_case.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n# Ioannou case\nFigure 10 from https://doi.org/10.1002/2017JC013158\n\nWe want to find the Ierapetra Eddy described above in a network demonstration run.\n" + "\nIoannou case\n============\nFigure 10 from https://doi.org/10.1002/2017JC013158\n\nWe want to find the Ierapetra Eddy described above in a network demonstration run.\n" ] }, { @@ -37,7 +37,7 @@ }, "outputs": [], "source": [ - "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)\n\n\n@FuncFormatter\ndef formatter(x, pos):\n return (timedelta(x) + datetime(1950, 1, 1)).strftime(\"%d/%m/%Y\")\n\n\ndef start_axes(title=\"\"):\n fig = plt.figure(figsize=(13, 6))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=GUI_AXES)\n ax.set_xlim(19, 29), ax.set_ylim(31, 35.5)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n return ax\n\n\ndef timeline_axes(title=\"\"):\n fig = plt.figure(figsize=(15, 5))\n ax = fig.add_axes([0.03, 0.06, 0.90, 0.88])\n ax.set_title(title, weight=\"bold\")\n ax.xaxis.set_major_formatter(formatter), ax.grid()\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid(True)\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is used to create thumbnail which is not used but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)\n\n\n@FuncFormatter\ndef formatter(x, pos):\n return (timedelta(x) + datetime(1950, 1, 1)).strftime(\"%d/%m/%Y\")\n\n\ndef start_axes(title=\"\"):\n fig = plt.figure(figsize=(13, 6))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=GUI_AXES)\n ax.set_xlim(19, 29), ax.set_ylim(31, 35.5)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n return ax\n\n\ndef timeline_axes(title=\"\"):\n fig = plt.figure(figsize=(15, 5))\n ax = fig.add_axes([0.03, 0.06, 0.90, 0.88])\n ax.set_title(title, weight=\"bold\")\n ax.xaxis.set_major_formatter(formatter), ax.grid()\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid(True)\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))" ] }, { @@ -80,7 +80,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Full Timeline\nThe network span for many years... How to cut the interesting part?\n\n" + "Full Timeline\n-------------\nThe network span for many years... How to cut the interesting part?\n\n" ] }, { @@ -98,7 +98,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Sub network and new numbering\nHere we chose to keep only the order 3 segments relatives to our chosen eddy\n\n" + "Sub network and new numbering\n-----------------------------\nHere we chose to keep only the order 3 segments relatives to our chosen eddy\n\n" ] }, { @@ -116,7 +116,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Anim\nQuick movie to see better!\n\n" + "Anim\n----\nQuick movie to see better!\n\n" ] }, { @@ -134,7 +134,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Classic display\n\n" + "Classic display\n---------------\n\n" ] }, { @@ -163,7 +163,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Latitude Timeline\n\n" + "Latitude Timeline\n-----------------\n\n" ] }, { @@ -181,7 +181,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Local radius timeline\nEffective (bold) and Speed (thin) Radius together\n\n" + "Local radius timeline\n---------------------\nEffective (bold) and Speed (thin) Radius together\n\n" ] }, { @@ -199,7 +199,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Parameters timeline\nEffective Radius\n\n" + "Parameters timeline\n-------------------\nEffective Radius\n\n" ] }, { @@ -235,7 +235,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Rotation angle\nFor each obs, fit an ellipse to the contour, with theta the angle from the x-axis,\na the semi ax in x direction and b the semi ax in y dimension\n\n" + "Rotation angle\n--------------\nFor each obs, fit an ellipse to the contour, with theta the angle from the x-axis,\na the semi ax in x direction and b the semi ax in y dimension\n\n" ] }, { @@ -338,7 +338,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.9" + "version": "3.7.7" } }, "nbformat": 4, diff --git a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb index 34047da4..0a546832 100644 --- a/notebooks/python_module/16_network/pet_segmentation_anim.ipynb +++ b/notebooks/python_module/16_network/pet_segmentation_anim.ipynb @@ -37,7 +37,7 @@ }, "outputs": [], "source": [ - "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)\n\n\ndef get_obs(dataset):\n \"Function to isolate a specific obs\"\n return where(\n (dataset.lat > 33)\n * (dataset.lat < 34)\n * (dataset.lon > 22)\n * (dataset.lon < 23)\n * (dataset.time > 20630)\n * (dataset.time < 20650)\n )[0][0]" + "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is used to create thumbnail which is not used but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)\n\n\ndef get_obs(dataset):\n \"Function to isolate a specific obs\"\n return where(\n (dataset.lat > 33)\n * (dataset.lat < 34)\n * (dataset.lon > 22)\n * (dataset.lon < 23)\n * (dataset.time > 20630)\n * (dataset.time < 20650)\n )[0][0]" ] }, { diff --git a/src/py_eddy_tracker/data/loopers_lumpkin_med.nc b/src/py_eddy_tracker/data/loopers_lumpkin_med.nc new file mode 100644 index 0000000000000000000000000000000000000000..cf817424da673378c53f682e9ed781d6bd655d8c GIT binary patch literal 244130 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 H)A4@+r%wR= literal 0 HcmV?d00001 diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 90bf6b70..8f592056 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -1327,7 +1327,7 @@ def extract_light_with_mask(self, mask): ) new.sign_type = self.sign_type if nb_obs == 0: - logger.warning("Empty dataset will be created") + logger.info("Empty dataset will be created") else: logger.info( f"{nb_obs} observations will be extracted ({nb_obs / self.shape[0]:.3%})" @@ -1353,7 +1353,7 @@ def extract_with_mask(self, mask): new = self.__class__.new_like(self, nb_obs) new.sign_type = self.sign_type if nb_obs == 0: - logger.warning("Empty dataset will be created") + logger.info("Empty dataset will be created") else: logger.debug( f"{nb_obs} observations will be extracted ({nb_obs / self.shape[0]:.3%})" diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index dec9a6b0..56e0f67d 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -1987,7 +1987,7 @@ def display(self, ax, ref=None, extern_only=False, intern_only=False, **kwargs): """Plot the speed and effective (dashed) contour of the eddies :param matplotlib.axes.Axes ax: matplotlib axe used to draw - :param float,None ref: western longitude reference used + :param float,None ref: if defined, all coordinates are wrapped with ref as western boundary :param bool extern_only: if True, draw only the effective contour :param bool intern_only: if True, draw only the speed contour :param dict kwargs: look at :py:meth:`matplotlib.axes.Axes.plot` @@ -2082,7 +2082,6 @@ def inside(self, x, y, intern=False): :rtype: array[bool] """ xname, yname = self.intern(intern) - # FIXME: wrapping return insidepoly(x, y, self[xname], self[yname]) def grid_count(self, bins, intern=False, center=False, filter=slice(None)): diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index 3aa43387..2914df6b 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -445,6 +445,7 @@ def loess_filter(self, half_window, xfield, yfield, inplace=True): if inplace: self.obs[yfield] = result return self + return result def median_filter(self, half_window, xfield, yfield, inplace=True): result = track_median_filter( @@ -501,7 +502,7 @@ def extract_with_mask( new = self.__class__.new_like(self, nb_obs) new.sign_type = self.sign_type if nb_obs == 0: - logger.warning("Empty dataset will be created") + logger.info("Empty dataset will be created") else: for field in self.obs.dtype.descr: logger.debug("Copy of field %s ...", field) @@ -567,8 +568,11 @@ def close_tracks(self, other, nb_obs_min=10, **kwargs): It could be a costly operation for huge dataset """ p0, p1 = self.period + p0_other, p1_other = other.period + if p1_other < p0 or p1 < p0_other: + return other.__class__.new_like(other, 0) indexs = list() - for i_self, i_other, t0, t1 in self.align_on(other, bins=range(p0, p1 + 2)): + for i_self, i_other, t0, t1 in self.align_on(other, bins=arange(p0, p1 + 2)): i, j, s = self.match(other, i_self=i_self, i_other=i_other, **kwargs) indexs.append(other.re_reference_index(j, i_other)) indexs = concatenate(indexs) @@ -578,10 +582,7 @@ def close_tracks(self, other, nb_obs_min=10, **kwargs): def format_label(self, label): t0, t1 = self.period return label.format( - t0=t0, - t1=t1, - nb_obs=len(self), - nb_tracks=(self.nb_obs_by_track != 0).sum(), + t0=t0, t1=t1, nb_obs=len(self), nb_tracks=(self.nb_obs_by_track != 0).sum(), ) def plot(self, ax, ref=None, **kwargs): diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index 56fb55e7..abe8becb 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -865,7 +865,7 @@ def poly_indexs(x_p, y_p, x_c, y_c): nb_p = x_p.shape[0] nb_c = x_c.shape[0] indexs = -ones(nb_p, dtype=numba_types.int32) - # Adress table to get particle bloc + # Adress table to get test bloc start_index, end_index, i_first = build_index(i[i_order]) nb_bloc = end_index.size for i_contour in range(nb_c): @@ -918,20 +918,4 @@ def insidepoly(x_p, y_p, x_c, y_c): :param array x_c: longitude of contours :param array y_c: latitude of contours """ - # TODO must be optimize like poly_index - nb_p = x_p.shape[0] - nb_c = x_c.shape[0] - flag = zeros(nb_p, dtype=numba_types.bool_) - for i in range(nb_c): - x_, y_ = reduce_size(x_c[i], y_c[i]) - x_c_min, y_c_min = x_.min(), y_.min() - x_c_max, y_c_max = x_.max(), y_.max() - v = create_vertice(x_, y_) - for j in range(nb_p): - if flag[j]: - continue - x, y = x_p[j], y_p[j] - if x > x_c_min and x < x_c_max and y > y_c_min and y < y_c_max: - if winding_number_poly(x, y, v) != 0: - flag[j] = True - return flag + return poly_indexs(x_p, y_p, x_c, y_c) != -1 From 5f01ee9198568914d815ebef851fdf8e04cfee09 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Mon, 13 Dec 2021 16:17:58 +0100 Subject: [PATCH 190/249] update python version for doc --- doc/environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/environment.yml b/doc/environment.yml index db50b528..7dcb504d 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -2,7 +2,7 @@ channels: - conda-forge - defaults dependencies: - - python=3.7 + - python=3.8 - ffmpeg - pip: - sphinx-gallery From 4ffad53976d4ab4d54d256994da23dff1bb74b32 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Mon, 13 Dec 2021 16:20:15 +0100 Subject: [PATCH 191/249] env for binder minimal 3.8 --- environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment.yml b/environment.yml index cf1de6f6..4ea8f840 100644 --- a/environment.yml +++ b/environment.yml @@ -3,7 +3,7 @@ channels: - conda-forge - defaults dependencies: - - python=3.7 + - python=3.8 - ffmpeg - pip: - -r requirements.txt From af8e44363d9e166b8ef4e8dcd2c458654cb289e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Thu, 16 Dec 2021 09:42:05 +0100 Subject: [PATCH 192/249] Fixs (#121) - correction coherence forward & backward, when time needed is shorted than time available - bug when extracting zarr network which have same number of observation and number of contour - expose underlying parameters to users (min_overlapp, minimal_area) - correction of bug in zarr nb_obs & track_array_variables, if no vars with 2 dimensions was selected - bug when loading EddiesObservation, rotation_type was not loaded - bug in tracking, previous_virtual_obs was not loaded from VirtualEddiesObservations - warning when loading data with different py-eddy-tracker versions - changes of extract_light_with_mask - possibility to select extra variables to extract --- CHANGELOG.rst | 7 ++ .../pet_eddy_detection_ACC.py | 13 +-- .../16_network/pet_replay_segmentation.py | 8 +- src/py_eddy_tracker/__init__.py | 13 +-- src/py_eddy_tracker/appli/eddies.py | 18 +--- src/py_eddy_tracker/appli/network.py | 41 +++++++- src/py_eddy_tracker/dataset/grid.py | 8 +- src/py_eddy_tracker/eddy_feature.py | 4 +- src/py_eddy_tracker/observations/network.py | 53 +++++++--- .../observations/observation.py | 96 ++++++++++++------- src/py_eddy_tracker/observations/tracking.py | 20 ++-- src/py_eddy_tracker/tracking.py | 3 + 12 files changed, 175 insertions(+), 109 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c6ab4cac..110c6081 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,6 +15,10 @@ Changed New identifications are produced with this type, old files could still be loaded. If you use old identifications for tracking use the `--unraw` option to unpack old times and store data with the new format. - Now amplitude is stored with .1 mm of precision (instead of 1 mm), same advice as for time. +- expose more parameters to users for bash tools build_network & divide_network +- add warning when loading a file created from a previous version of py-eddy-tracker. + + Fixed ^^^^^ @@ -22,6 +26,9 @@ Fixed - Fix bug in convolution(filter), lowest rows was replace by zeros in convolution computation. Important impact for tiny kernel - Fix method of sampling before contour fitting +- Fix bug when loading dataset in zarr format, not all variables were correctly loaded +- Fix bug when zarr dataset has same size for number of observations and contour size +- Fix bug when tracking, previous_virtual_obs was not always loaded Added ^^^^^ diff --git a/examples/02_eddy_identification/pet_eddy_detection_ACC.py b/examples/02_eddy_identification/pet_eddy_detection_ACC.py index c799a45e..e6c5e381 100644 --- a/examples/02_eddy_identification/pet_eddy_detection_ACC.py +++ b/examples/02_eddy_identification/pet_eddy_detection_ACC.py @@ -65,8 +65,7 @@ def set_fancy_labels(fig, ticklabelsize=14, labelsize=14, labelweight="semibold" y_name="latitude", # Manual area subset indexs=dict( - latitude=slice(100 - margin, 220 + margin), - longitude=slice(0, 230 + margin), + latitude=slice(100 - margin, 220 + margin), longitude=slice(0, 230 + margin), ), ) g_raw = RegularGridDataset(**kw_data) @@ -188,16 +187,10 @@ def set_fancy_labels(fig, ticklabelsize=14, labelsize=14, labelweight="semibold" ax.set_ylabel("With filter") ax.plot( - a_[field][i_a] * factor, - a[field][j_a] * factor, - "r.", - label="Anticyclonic", + a_[field][i_a] * factor, a[field][j_a] * factor, "r.", label="Anticyclonic", ) ax.plot( - c_[field][i_c] * factor, - c[field][j_c] * factor, - "b.", - label="Cyclonic", + c_[field][i_c] * factor, c[field][j_c] * factor, "b.", label="Cyclonic", ) ax.set_aspect("equal"), ax.grid() ax.plot((0, 1000), (0, 1000), "g") diff --git a/examples/16_network/pet_replay_segmentation.py b/examples/16_network/pet_replay_segmentation.py index 757854d5..d6b4568b 100644 --- a/examples/16_network/pet_replay_segmentation.py +++ b/examples/16_network/pet_replay_segmentation.py @@ -149,13 +149,7 @@ def get_obs(dataset): n_.median_filter(15, "time", "latitude") kw["s"] = (n_.radius_e * 1e-3) ** 2 / 30 ** 2 * 20 m = n_.scatter_timeline( - ax, - "shape_error_e", - vmin=14, - vmax=70, - **kw, - yfield="lon", - method="all", + ax, "shape_error_e", vmin=14, vmax=70, **kw, yfield="lon", method="all", ) ax.set_ylabel("Longitude") cb = update_axes(ax, m["scatter"]) diff --git a/src/py_eddy_tracker/__init__.py b/src/py_eddy_tracker/__init__.py index f3ecec84..275bb795 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -422,20 +422,14 @@ def identify_time(str_date): nc_name="previous_cost", nc_type="float32", nc_dims=("obs",), - nc_attr=dict( - long_name="Previous cost for previous observation", - comment="", - ), + nc_attr=dict(long_name="Previous cost for previous observation", comment="",), ), next_cost=dict( attr_name=None, nc_name="next_cost", nc_type="float32", nc_dims=("obs",), - nc_attr=dict( - long_name="Next cost for next observation", - comment="", - ), + nc_attr=dict(long_name="Next cost for next observation", comment="",), ), n=dict( attr_name=None, @@ -646,8 +640,7 @@ def identify_time(str_date): nc_type="f4", nc_dims=("obs",), nc_attr=dict( - long_name="Log base 10 background chlorophyll", - units="Log(Chl/[mg/m^3])", + long_name="Log base 10 background chlorophyll", units="Log(Chl/[mg/m^3])", ), ), year=dict( diff --git a/src/py_eddy_tracker/appli/eddies.py b/src/py_eddy_tracker/appli/eddies.py index df4e7d43..4809fddf 100644 --- a/src/py_eddy_tracker/appli/eddies.py +++ b/src/py_eddy_tracker/appli/eddies.py @@ -243,8 +243,7 @@ def browse_dataset_in( filenames = bytes_(glob(full_path)) dataset_list = empty( - len(filenames), - dtype=[("filename", "S500"), ("date", "datetime64[s]")], + len(filenames), dtype=[("filename", "S500"), ("date", "datetime64[s]")], ) dataset_list["filename"] = filenames @@ -372,8 +371,7 @@ def track( logger.info("Longer track saved have %d obs", c.nb_obs_by_tracks.max()) logger.info( - "The mean length is %d observations for long track", - c.nb_obs_by_tracks.mean(), + "The mean length is %d observations for long track", c.nb_obs_by_tracks.mean(), ) long_track.write_file(**kw_write) @@ -383,14 +381,7 @@ def track( def get_group( - dataset1, - dataset2, - index1, - index2, - score, - invalid=2, - low=10, - high=60, + dataset1, dataset2, index1, index2, score, invalid=2, low=10, high=60, ): group1, group2 = dict(), dict() m_valid = (score * 100) >= invalid @@ -499,8 +490,7 @@ def get_values(v, dataset): ] labels = dict( - high=f"{high:0.0f} <= high", - low=f"{invalid:0.0f} <= low < {low:0.0f}", + high=f"{high:0.0f} <= high", low=f"{invalid:0.0f} <= low < {low:0.0f}", ) keys = [labels.get(key, key) for key in list(gr_ref.values())[0].keys()] diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index 5c4cdcaf..e9baa7be 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -21,6 +21,20 @@ def build_network(): parser.add_argument( "--window", "-w", type=int, help="Half time window to search eddy", default=1 ) + + parser.add_argument( + "--min-overlap", + "-p", + type=float, + help="minimum overlap area to associate observations", + default=0.2, + ) + parser.add_argument( + "--minimal-area", + action="store_true", + help="If True, use intersection/little polygon, else intersection/union", + ) + parser.contour_intern_arg() parser.memory_arg() @@ -32,7 +46,9 @@ def build_network(): intern=args.intern, memory=args.memory, ) - group = n.group_observations(minimal_area=True) + group = n.group_observations( + min_overlap=args.min_overlap, minimal_area=args.minimal_area + ) n.build_dataset(group).write_file(filename=args.out) @@ -44,6 +60,18 @@ def divide_network(): parser.add_argument( "--window", "-w", type=int, help="Half time window to search eddy", default=1 ) + parser.add_argument( + "--min-overlap", + "-p", + type=float, + help="minimum overlap area to associate observations", + default=0.2, + ) + parser.add_argument( + "--minimal-area", + action="store_true", + help="If True, use intersection/little polygon, else intersection/union", + ) args = parser.parse_args() contour_name = TrackEddiesObservations.intern(args.intern, public_label=True) e = TrackEddiesObservations.load_file( @@ -52,7 +80,12 @@ def divide_network(): ) n = NetworkObservations.from_split_network( TrackEddiesObservations.load_file(args.input, raw_data=True), - e.split_network(intern=args.intern, window=args.window), + e.split_network( + intern=args.intern, + window=args.window, + min_overlap=args.min_overlap, + minimal_area=args.minimal_area, + ), ) n.write_file(filename=args.out) @@ -76,9 +109,7 @@ def subset_network(): help="Remove short dead end, first is for minimal obs number and second for minimal segment time to keep", ) parser.add_argument( - "--remove_trash", - action="store_true", - help="Remove trash (network id == 0)", + "--remove_trash", action="store_true", help="Remove trash (network id == 0)", ) parser.add_argument( "-p", diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 5b884b68..091d2016 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -858,13 +858,11 @@ def eddy_identification( xy_i = uniform_resample( inner_contour.lon, inner_contour.lat, - num_fac=presampling_multiplier - ) - xy_e = uniform_resample( - contour.lon, - contour.lat, num_fac=presampling_multiplier, ) + xy_e = uniform_resample( + contour.lon, contour.lat, num_fac=presampling_multiplier, + ) xy_s = uniform_resample( speed_contour.lon, speed_contour.lat, diff --git a/src/py_eddy_tracker/eddy_feature.py b/src/py_eddy_tracker/eddy_feature.py index d2616957..3640b306 100644 --- a/src/py_eddy_tracker/eddy_feature.py +++ b/src/py_eddy_tracker/eddy_feature.py @@ -433,8 +433,8 @@ def __init__(self, x, y, z, levels, wrap_x=False, keep_unclose=False): closed_contours = 0 # Count level and contour for i, collection in enumerate(self.contours.collections): - collection.get_nearest_path_bbox_contain_pt = ( - lambda x, y, i=i: self.get_index_nearest_path_bbox_contain_pt(i, x, y) + collection.get_nearest_path_bbox_contain_pt = lambda x, y, i=i: self.get_index_nearest_path_bbox_contain_pt( + i, x, y ) nb_level += 1 diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 8f592056..1c078bf8 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -1301,7 +1301,7 @@ def extract_with_period(self, period): return self.extract_with_mask(self.get_mask_with_period(period)) - def extract_light_with_mask(self, mask): + def extract_light_with_mask(self, mask, track_extra_variables=[]): """extract data with mask, but only with variables used for coherence, aka self.array_variables :param mask: mask used to extract @@ -1319,7 +1319,7 @@ def extract_light_with_mask(self, mask): variables = ["time"] + self.array_variables new = self.__class__( size=nb_obs, - track_extra_variables=[], + track_extra_variables=track_extra_variables, track_array_variables=self.track_array_variables, array_variables=self.array_variables, only_variables=variables, @@ -1333,9 +1333,22 @@ def extract_light_with_mask(self, mask): f"{nb_obs} observations will be extracted ({nb_obs / self.shape[0]:.3%})" ) - for field in variables: + for field in variables + track_extra_variables: logger.debug("Copy of field %s ...", field) new.obs[field] = self.obs[field][mask] + + if ( + "previous_obs" in track_extra_variables + and "next_obs" in track_extra_variables + ): + # n & p must be re-index + n, p = self.next_obs[mask], self.previous_obs[mask] + # we add 2 for -1 index return index -1 + translate = -ones(len(self) + 1, dtype="i4") + translate[:-1][mask] = arange(nb_obs) + new.next_obs[:] = translate[n] + new.previous_obs[:] = translate[p] + return new def extract_with_mask(self, mask): @@ -1495,7 +1508,8 @@ def date2file(julian_day): t_start, t_end = int(self.period[0]), int(self.period[1]) - dates = arange(t_start, t_start + n_days + 1) + # dates = arange(t_start, t_start + n_days + 1) + dates = arange(t_start, min(t_start + n_days + 1, t_end + 1)) first_files = [date_function(x) for x in dates] c = GridCollection.from_netcdf_list(first_files, dates, **uv_params) @@ -1570,12 +1584,8 @@ def date2file(julian_day): ptf_final = zeros((self.obs.size, 2), dtype="i1") t_start, t_end = int(self.period[0]), int(self.period[1]) - # if begin is not None and begin > t_start: - # t_start = begin - # if end is not None and end < t_end: - # t_end = end - dates = arange(t_start, t_start + n_days + 1) + dates = arange(t_start, min(t_start + n_days + 1, t_end + 1)) first_files = [date_function(x) for x in dates] c = GridCollection.from_netcdf_list(first_files, dates, **uv_params) @@ -1699,7 +1709,23 @@ def group_translator(nb, duos): apply_replace(translate, gr_i, gr_j) return translate - def group_observations(self, **kwargs): + def group_observations(self, min_overlap=0.2, minimal_area=False): + """Store every interaction between identifications + + Parameters + ---------- + minimal_area : bool, optional + If True, function will compute intersection/little polygon, else intersection/union, by default False + + min_overlap : float, optional + minimum overlap area to associate observations, by default 0.2 + + Returns + ------- + TrackEddiesObservations + netcdf with interactions + """ + results, nb_obs = list(), list() # To display print only in INFO display_iteration = logger.getEffectiveLevel() == logging.INFO @@ -1713,7 +1739,12 @@ def group_observations(self, **kwargs): for j in range(i + 1, min(self.window + i + 1, self.nb_input)): xj, yj = self.buffer.load_contour(self.filenames[j]) ii, ij = bbox_intersection(xi, yi, xj, yj) - m = vertice_overlap(xi[ii], yi[ii], xj[ij], yj[ij], **kwargs) > 0.2 + m = ( + vertice_overlap( + xi[ii], yi[ii], xj[ij], yj[ij], minimal_area=minimal_area + ) + > min_overlap + ) results.append((i, j, ii[m], ij[m])) if display_iteration: print() diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 56e0f67d..3543caa7 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -8,6 +8,7 @@ from tarfile import ExFileObject from tokenize import TokenError +import packaging import zarr from matplotlib.cm import get_cmap from matplotlib.collections import PolyCollection @@ -74,6 +75,29 @@ logger = logging.getLogger("pet") +# keep only major and minor version number +_software_version_reduced = packaging.version.Version( + "{v.major}.{v.minor}".format(v=packaging.version.parse(__version__)) +) + + +def _check_versions(version): + """Check if version of py_eddy_tracker used to create the file is compatible with software version + + if not, warn user with both versions + + :param version: string version of software used to create the file. If None, version was not provided + :type version: str, None + """ + + file_version = packaging.version.parse(version) if version is not None else None + if file_version is None or file_version < _software_version_reduced: + logger.warning( + "File was created with py-eddy-tracker version '%s' but software version is '%s'", + file_version, + _software_version_reduced, + ) + @njit(cache=True, fastmath=True) def shifted_ellipsoid_degrees_mask2(lon0, lat0, lon1, lat1, minor=1.5, major=1.5): @@ -687,10 +711,13 @@ def zarr_dimension(filename): h = filename else: h = zarr.open(filename) + dims = list() for varname in h: - dims.extend(list(getattr(h, varname).shape)) - return set(dims) + shape = getattr(h, varname).shape + if len(shape) > len(dims): + dims = shape + return dims @classmethod def load_file(cls, filename, **kwargs): @@ -702,11 +729,7 @@ def load_file(cls, filename, **kwargs): .. code-block:: python kwargs_latlon_300 = dict( - include_vars=[ - "longitude", - "latitude", - ], - indexs=dict(obs=slice(0, 300)), + include_vars=["longitude", "latitude",], indexs=dict(obs=slice(0, 300)), ) small_dataset = TrackEddiesObservations.load_file( filename, **kwargs_latlon_300 @@ -754,20 +777,19 @@ def load_from_zarr( :return type: class """ # FIXME - array_dim = -1 if isinstance(filename, zarr.storage.MutableMapping): h_zarr = filename else: if not isinstance(filename, str): filename = filename.astype(str) h_zarr = zarr.open(filename) + + _check_versions(h_zarr.attrs.get("framework_version", None)) var_list = cls.build_var_list(list(h_zarr.keys()), remove_vars, include_vars) nb_obs = getattr(h_zarr, var_list[0]).shape[0] - dims = list(cls.zarr_dimension(filename)) - if len(dims) == 2 and nb_obs in dims: - # FIXME must be investigated, in zarr no dimensions name (or could be add in attr) - array_dim = dims[1] if nb_obs == dims[0] else dims[0] + track_array_variables = h_zarr.attrs["track_array_variables"] + if indexs is not None and "obs" in indexs: sl = indexs["obs"] sl = slice(sl.start, min(sl.stop, nb_obs)) @@ -781,28 +803,33 @@ def load_from_zarr( logger.debug("%d observations will be load", nb_obs) kwargs = dict() - if array_dim in dims: - kwargs["track_array_variables"] = array_dim - kwargs["array_variables"] = list() - for variable in var_list: - if array_dim in h_zarr[variable].shape: - var_inv = VAR_DESCR_inv[variable] - kwargs["array_variables"].append(var_inv) - array_variables = kwargs.get("array_variables", list()) - kwargs["track_extra_variables"] = [] + kwargs["track_array_variables"] = h_zarr.attrs.get( + "track_array_variables", track_array_variables + ) + + array_variables = list() + for variable in var_list: + if len(h_zarr[variable].shape) > 1: + var_inv = VAR_DESCR_inv[variable] + array_variables.append(var_inv) + kwargs["array_variables"] = array_variables + track_extra_variables = [] + for variable in var_list: var_inv = VAR_DESCR_inv[variable] if var_inv not in cls.ELEMENTS and var_inv not in array_variables: - kwargs["track_extra_variables"].append(var_inv) + track_extra_variables.append(var_inv) + kwargs["track_extra_variables"] = track_extra_variables kwargs["raw_data"] = raw_data kwargs["only_variables"] = ( None if include_vars is None else [VAR_DESCR_inv[i] for i in include_vars] ) kwargs.update(class_kwargs) eddies = cls(size=nb_obs, **kwargs) - for variable in var_list: + + for i_var, variable in enumerate(var_list): var_inv = VAR_DESCR_inv[variable] - logger.debug("%s will be loaded", variable) + logger.debug("%s will be loaded (%d/%d)", variable, i_var, len(var_list)) # find unit factor input_unit = h_zarr[variable].attrs.get("unit", None) if input_unit is None: @@ -858,6 +885,7 @@ def copy_data_to_zarr( i_start = 0 if i_stop is None: i_stop = handler_zarr.shape[0] + for i in range(i_start, i_stop, buffer_size): sl_in = slice(i, min(i + buffer_size, i_stop)) data = handler_zarr[sl_in] @@ -868,6 +896,7 @@ def copy_data_to_zarr( data -= add_offset if scale_factor is not None: data /= scale_factor + sl_out = slice(i - i_start, i - i_start + buffer_size) handler_eddies[sl_out] = data @@ -901,6 +930,8 @@ def load_from_netcdf( else: args, kwargs = (filename,), dict() with Dataset(*args, **kwargs) as h_nc: + _check_versions(getattr(h_nc, "framework_version", None)) + var_list = cls.build_var_list( list(h_nc.variables.keys()), remove_vars, include_vars ) @@ -1032,6 +1063,7 @@ def from_zarr(cls, handler): eddies.obs[variable] = handler.variables[variable][:] else: eddies.obs[VAR_DESCR_inv[variable]] = handler.variables[variable][:] + eddies.sign_type = handler.rotation_type return eddies @classmethod @@ -1050,6 +1082,7 @@ def from_netcdf(cls, handler): eddies.obs[variable] = handler.variables[variable][:] else: eddies.obs[VAR_DESCR_inv[variable]] = handler.variables[variable][:] + eddies.sign_type = handler.rotation_type return eddies def propagate( @@ -1977,11 +2010,7 @@ def bins_stat(self, xname, bins=None, yname=None, method=None, mask=None): def format_label(self, label): t0, t1 = self.period - return label.format( - t0=t0, - t1=t1, - nb_obs=len(self), - ) + return label.format(t0=t0, t1=t1, nb_obs=len(self),) def display(self, ax, ref=None, extern_only=False, intern_only=False, **kwargs): """Plot the speed and effective (dashed) contour of the eddies @@ -2352,14 +2381,7 @@ def grid_count_pixel_in( x_, y_ = reduce_size(x_, y_) v = create_vertice(x_, y_) (x_start, x_stop), (y_start, y_stop) = bbox_indice_regular( - v, - x_bounds, - y_bounds, - xstep, - ystep, - N, - is_circular, - x_size, + v, x_bounds, y_bounds, xstep, ystep, N, is_circular, x_size, ) i, j = get_pixel_in_regular(v, x_c, y_c, x_start, x_stop, y_start, y_stop) grid_count_(grid, i, j) diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index 2914df6b..6612c6d5 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -657,12 +657,12 @@ def split_network(self, intern=True, **kwargs): def set_tracks(self, x, y, ids, window, **kwargs): """ - Will split one group (network) in segments + Split one group (network) in segments :param array x: coordinates of group :param array y: coordinates of group :param ndarray ids: several fields like time, group, ... - :param int windows: number of days where observations could missed + :param int window: number of days where observations could missed """ time_index = build_index((ids["time"]).astype("i4")) nb = x.shape[0] @@ -714,8 +714,8 @@ def get_previous_obs( time_e, time_ref, window, - min_overlap=0.01, - **kwargs, + min_overlap=0.2, + minimal_area=False, ): """Backward association of observations to the segments""" time_cur = int_(ids["time"][i_current]) @@ -731,7 +731,9 @@ def get_previous_obs( if len(ii) == 0: continue c = zeros(len(xj)) - c[ij] = vertice_overlap(xi[ii], yi[ii], xj[ij], yj[ij], **kwargs) + c[ij] = vertice_overlap( + xi[ii], yi[ii], xj[ij], yj[ij], minimal_area=minimal_area + ) # We remove low overlap c[c < min_overlap] = 0 # We get index of maximal overlap @@ -754,8 +756,8 @@ def get_next_obs( time_e, time_ref, window, - min_overlap=0.01, - **kwargs, + min_overlap=0.2, + minimal_area=False, ): """Forward association of observations to the segments""" time_max = time_e.shape[0] - 1 @@ -774,7 +776,9 @@ def get_next_obs( if len(ii) == 0: continue c = zeros(len(xj)) - c[ij] = vertice_overlap(xi[ii], yi[ii], xj[ij], yj[ij], **kwargs) + c[ij] = vertice_overlap( + xi[ii], yi[ii], xj[ij], yj[ij], minimal_area=minimal_area + ) # We remove low overlap c[c < min_overlap] = 0 # We get index of maximal overlap diff --git a/src/py_eddy_tracker/tracking.py b/src/py_eddy_tracker/tracking.py index 577496ff..7543a4d3 100644 --- a/src/py_eddy_tracker/tracking.py +++ b/src/py_eddy_tracker/tracking.py @@ -350,6 +350,9 @@ def load_state(self): self.virtual_obs = VirtualEddiesObservations.from_netcdf( general_handler.groups["LastVirtualObs"] ) + self.previous_virtual_obs = VirtualEddiesObservations.from_netcdf( + general_handler.groups["LastPreviousVirtualObs"] + ) # Load and last previous virtual obs to be merge with current => will be previous2_obs # TODO : Need to rethink this line ?? self.current_obs = self.current_obs.merge( From 7a9baf42d85dbc91c012f81992f85ae6d0f3a154 Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Sun, 9 Jan 2022 22:17:18 +0100 Subject: [PATCH 193/249] example to compute statistics on raw identification --- README.md | 14 +- .../pet_statistics_on_identification.py | 105 +++++++++ .../pet_statistics_on_identification.ipynb | 202 ++++++++++++++++++ src/py_eddy_tracker/dataset/grid.py | 2 +- .../observations/observation.py | 2 +- src/py_eddy_tracker/poly.py | 10 +- 6 files changed, 330 insertions(+), 5 deletions(-) create mode 100644 examples/02_eddy_identification/pet_statistics_on_identification.py create mode 100644 notebooks/python_module/02_eddy_identification/pet_statistics_on_identification.ipynb diff --git a/README.md b/README.md index e26e15ac..c9e7690f 100644 --- a/README.md +++ b/README.md @@ -17,15 +17,17 @@ Method was described in : ### Use case ### Method is used in : - + [Mason, E., A. Pascual, P. Gaube, S.Ruiz, J. Pelegrí, A. Delepoulle, 2017: Subregional characterization of mesoscale eddies across the Brazil-Malvinas Confluence](https://doi.org/10.1002/2016JC012611) ### How do I get set up? ### #### Short story #### + ```bash pip install pyeddytracker ``` + #### Long story #### To avoid problems with installation, use of the virtualenv Python virtual environment is recommended. @@ -36,12 +38,20 @@ Then use pip to install all dependencies (numpy, scipy, matplotlib, netCDF4, ... pip install numpy scipy netCDF4 matplotlib opencv-python pyyaml pint polygon3 ``` -Then run the following to install the eddy tracker: +Clone : + +```bash +git clone https://github.com/AntSimi/py-eddy-tracker +``` + +Then run the following to install the eddy tracker : ```bash python setup.py install ``` + ### Tools gallery ### + Several examples based on py eddy tracker module are [here](https://py-eddy-tracker.readthedocs.io/en/latest/python_module/index.html). [![](https://py-eddy-tracker.readthedocs.io/en/latest/_static/logo.png)](https://py-eddy-tracker.readthedocs.io/en/latest/python_module/index.html) diff --git a/examples/02_eddy_identification/pet_statistics_on_identification.py b/examples/02_eddy_identification/pet_statistics_on_identification.py new file mode 100644 index 00000000..0e4d9b34 --- /dev/null +++ b/examples/02_eddy_identification/pet_statistics_on_identification.py @@ -0,0 +1,105 @@ +""" +Stastics on identification files +================================ + +Some statistics on raw identification without any tracking +""" +import numpy as np +from matplotlib import pyplot as plt +from matplotlib.dates import date2num + +from py_eddy_tracker import start_logger +from py_eddy_tracker.data import get_remote_demo_sample +from py_eddy_tracker.observations.observation import EddiesObservations + +start_logger().setLevel("ERROR") + + +# %% +def start_axes(title): + fig = plt.figure(figsize=(13, 5)) + ax = fig.add_axes([0.03, 0.03, 0.90, 0.94]) + 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])) + + +# %% +# We load demo sample and take only first year. +# +# Replace by a list of filename to apply on your own dataset. +file_objects = get_remote_demo_sample( + "eddies_med_adt_allsat_dt2018/Anticyclonic_2010_2011_2012" +)[:365] + +# %% +# Merge all identification dataset in one object +all_a = EddiesObservations.concatenate( + [EddiesObservations.load_file(i) for i in file_objects] +) + +# %% +# We define polygon bound +x0, x1, y0, y1 = 15, 20, 33, 38 +xs = np.array([[x0, x1, x1, x0, x0]], dtype="f8") +ys = np.array([[y0, y0, y1, y1, y0]], dtype="f8") +# Polygon object is create to be usable by match function. +polygon = dict(contour_lon_e=xs, contour_lat_e=ys, contour_lon_s=xs, contour_lat_s=ys) + +# %% +# Geographic frequency of eddies +step = 0.125 +ax = start_axes("") +# Count pixel used for each contour +g_a = all_a.grid_count(bins=((-10, 37, step), (30, 46, step)), intern=True) +m = g_a.display( + ax, cmap="terrain_r", vmin=0, vmax=0.75, factor=1 / all_a.nb_days, name="count" +) +ax.plot(polygon["contour_lon_e"][0], polygon["contour_lat_e"][0], "r") +update_axes(ax, m) + +# %% +# We use match function to count number of eddies which intersect the polygon defined previously. +# `p1_area` option allow to get in c_e/c_s output, precentage of area occupy by eddies in the polygon. +i_e, j_e, c_e = all_a.match(polygon, p1_area=True, intern=False) +i_s, j_s, c_s = all_a.match(polygon, p1_area=True, intern=True) + +# %% +dt = np.datetime64("1970-01-01") - np.datetime64("1950-01-01") +kw_hist = dict( + bins=date2num(np.arange(21900, 22300).astype("datetime64") - dt), histtype="step" +) +# translate julian day in datetime64 +t = all_a.time.astype("datetime64") - dt +# %% +# Count how many are in polygon +ax = plt.figure(figsize=(12, 6)).add_subplot(111) +ax.set_title("Different way to count eddies presence in a polygon") +ax.set_ylabel("Count") +m = all_a.mask_from_polygons(((xs, ys),)) +ax.hist(t[m], label="center in polygon", **kw_hist) +ax.hist(t[i_s[c_s > 0]], label="intersect speed contour with polygon", **kw_hist) +ax.hist(t[i_e[c_e > 0]], label="intersect extern contour with polygon", **kw_hist) +ax.legend() +ax.set_xlim(np.datetime64("2010"), np.datetime64("2011")) +ax.grid() + +# %% +# Percent of are of interest occupy by eddies +ax = plt.figure(figsize=(12, 6)).add_subplot(111) +ax.set_title("Percent of polygon occupy by an anticyclonic eddy") +ax.set_ylabel("Percent of polygon") +ax.hist(t[i_s[c_s > 0]], weights=c_s[c_s > 0] * 100.0, label="speed contour", **kw_hist) +ax.hist( + t[i_e[c_e > 0]], weights=c_e[c_e > 0] * 100.0, label="effective contour", **kw_hist +) +ax.legend(), ax.set_ylim(0, 25) +ax.set_xlim(np.datetime64("2010"), np.datetime64("2011")) +ax.grid() diff --git a/notebooks/python_module/02_eddy_identification/pet_statistics_on_identification.ipynb b/notebooks/python_module/02_eddy_identification/pet_statistics_on_identification.ipynb new file mode 100644 index 00000000..7fa04435 --- /dev/null +++ b/notebooks/python_module/02_eddy_identification/pet_statistics_on_identification.ipynb @@ -0,0 +1,202 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Stastics on identification files\n\nSome statistics on raw identification without any tracking\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import numpy as np\nfrom matplotlib import pyplot as plt\nfrom matplotlib.dates import date2num\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_remote_demo_sample\nfrom py_eddy_tracker.observations.observation import EddiesObservations\n\nstart_logger().setLevel(\"ERROR\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "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 if mappable:\n plt.colorbar(mappable, cax=ax.figure.add_axes([0.95, 0.05, 0.01, 0.9]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We load demo sample and take only first year.\n\nReplace by a list of filename to apply on your own dataset.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "file_objects = get_remote_demo_sample(\n \"eddies_med_adt_allsat_dt2018/Anticyclonic_2010_2011_2012\"\n)[:365]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Merge all identification dataset in one object\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "all_a = EddiesObservations.concatenate(\n [EddiesObservations.load_file(i) for i in file_objects]\n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We define polygon bound\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x0, x1, y0, y1 = 15, 20, 33, 38\nxs = np.array([[x0, x1, x1, x0, x0]], dtype=\"f8\")\nys = np.array([[y0, y0, y1, y1, y0]], dtype=\"f8\")\n# Polygon object is create to be usable by match function.\npolygon = dict(contour_lon_e=xs, contour_lat_e=ys, contour_lon_s=xs, contour_lat_s=ys)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Geographic frequency of eddies\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "step = 0.125\nax = start_axes(\"\")\n# Count pixel used for each contour\ng_a = all_a.grid_count(bins=((-10, 37, step), (30, 46, step)), intern=True)\nm = g_a.display(\n ax, cmap=\"terrain_r\", vmin=0, vmax=0.75, factor=1 / all_a.nb_days, name=\"count\"\n)\nax.plot(polygon[\"contour_lon_e\"][0], polygon[\"contour_lat_e\"][0], \"r\")\nupdate_axes(ax, m)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We use match function to count number of eddies which intersect the polygon defined previously.\n`p1_area` option allow to get in c_e/c_s output, precentage of area occupy by eddies in the polygon.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "i_e, j_e, c_e = all_a.match(polygon, p1_area=True, intern=False)\ni_s, j_s, c_s = all_a.match(polygon, p1_area=True, intern=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "dt = np.datetime64(\"1970-01-01\") - np.datetime64(\"1950-01-01\")\nkw_hist = dict(\n bins=date2num(np.arange(21900, 22300).astype(\"datetime64\") - dt), histtype=\"step\"\n)\n# translate julian day in datetime64\nt = all_a.time.astype(\"datetime64\") - dt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Count how many are in polygon\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = plt.figure(figsize=(12, 6)).add_subplot(111)\nax.set_title(\"Different way to count eddies presence in a polygon\")\nax.set_ylabel(\"Count\")\nm = all_a.mask_from_polygons(((xs, ys),))\nax.hist(t[m], label=\"center in polygon\", **kw_hist)\nax.hist(t[i_s[c_s > 0]], label=\"intersect speed contour with polygon\", **kw_hist)\nax.hist(t[i_e[c_e > 0]], label=\"intersect extern contour with polygon\", **kw_hist)\nax.legend()\nax.set_xlim(np.datetime64(\"2010\"), np.datetime64(\"2011\"))\nax.grid()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Percent of are of interest occupy by eddies\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = plt.figure(figsize=(12, 6)).add_subplot(111)\nax.set_title(\"Percent of polygon occupy by an anticyclonic eddy\")\nax.set_ylabel(\"Percent of polygon\")\nax.hist(t[i_s[c_s > 0]], weights=c_s[c_s > 0] * 100.0, label=\"speed contour\", **kw_hist)\nax.hist(t[i_e[c_e > 0]], weights=c_e[c_e > 0] * 100.0, label=\"effective contour\", **kw_hist)\nax.legend(), ax.set_ylim(0, 25)\nax.set_xlim(np.datetime64(\"2010\"), np.datetime64(\"2011\"))\nax.grid()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 091d2016..237577a4 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -807,7 +807,7 @@ def eddy_identification( else: centi = reset_centroid[0] centj = reset_centroid[1] - # To move in regular and unregular grid + # FIXME : To move in regular and unregular grid if len(x.shape) == 1: centlon_e = x[centi] centlat_e = y[centj] diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 3543caa7..3c8e1938 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -8,7 +8,7 @@ from tarfile import ExFileObject from tokenize import TokenError -import packaging +import packaging.version import zarr from matplotlib.cm import get_cmap from matplotlib.collections import PolyCollection diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index abe8becb..bb9ac79e 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -411,7 +411,7 @@ def merge(x, y): return concatenate(x), concatenate(y) -def vertice_overlap(x0, y0, x1, y1, minimal_area=False): +def vertice_overlap(x0, y0, x1, y1, minimal_area=False, p1_area=False): r""" Return percent of overlap for each item. @@ -420,6 +420,7 @@ def vertice_overlap(x0, y0, x1, y1, minimal_area=False): :param array x1: x for polygon list 1 :param array y1: y for polygon list 1 :param bool minimal_area: If True, function will compute intersection/little polygon, else intersection/union + :param bool p1_area: If True, function will compute intersection/p1 polygon, else intersection/union :return: Result of cost function :rtype: array @@ -430,6 +431,10 @@ def vertice_overlap(x0, y0, x1, y1, minimal_area=False): If minimal area: .. math:: Score = \frac{Intersection(P_0,P_1)_{area}}{min(P_{0 area},P_{1 area})} + + If P1 area: + + .. math:: Score = \frac{Intersection(P_0,P_1)_{area}}{P_{1 area}} """ nb = x0.shape[0] cost = empty(nb) @@ -443,6 +448,9 @@ def vertice_overlap(x0, y0, x1, y1, minimal_area=False): # we divide intersection with the little one result from 0 to 1 if minimal_area: cost[i] = intersection / min(p0.area(), p1.area()) + # we divide intersection with p1 + elif p1_area: + cost[i] = intersection / p1.area() # we divide intersection with polygon merging result from 0 to 1 else: cost[i] = intersection / (p0 + p1).area() From cc540c03c27ac40194d049e547b9ca1cc2307572 Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Tue, 11 Jan 2022 13:45:49 +0100 Subject: [PATCH 194/249] english correction --- .../pet_statistics_on_identification.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/02_eddy_identification/pet_statistics_on_identification.py b/examples/02_eddy_identification/pet_statistics_on_identification.py index 0e4d9b34..0c72262f 100644 --- a/examples/02_eddy_identification/pet_statistics_on_identification.py +++ b/examples/02_eddy_identification/pet_statistics_on_identification.py @@ -40,7 +40,7 @@ def update_axes(ax, mappable=None): )[:365] # %% -# Merge all identification dataset in one object +# Merge all identification datasets in one object all_a = EddiesObservations.concatenate( [EddiesObservations.load_file(i) for i in file_objects] ) @@ -50,14 +50,14 @@ def update_axes(ax, mappable=None): x0, x1, y0, y1 = 15, 20, 33, 38 xs = np.array([[x0, x1, x1, x0, x0]], dtype="f8") ys = np.array([[y0, y0, y1, y1, y0]], dtype="f8") -# Polygon object is create to be usable by match function. +# Polygon object created for the match function use. polygon = dict(contour_lon_e=xs, contour_lat_e=ys, contour_lon_s=xs, contour_lat_s=ys) # %% # Geographic frequency of eddies step = 0.125 ax = start_axes("") -# Count pixel used for each contour +# Count pixel encompassed in each contour g_a = all_a.grid_count(bins=((-10, 37, step), (30, 46, step)), intern=True) m = g_a.display( ax, cmap="terrain_r", vmin=0, vmax=0.75, factor=1 / all_a.nb_days, name="count" @@ -66,7 +66,7 @@ def update_axes(ax, mappable=None): update_axes(ax, m) # %% -# We use match function to count number of eddies which intersect the polygon defined previously. +# We use the match function to count the number of eddies that intersect the polygon defined previously # `p1_area` option allow to get in c_e/c_s output, precentage of area occupy by eddies in the polygon. i_e, j_e, c_e = all_a.match(polygon, p1_area=True, intern=False) i_s, j_s, c_s = all_a.match(polygon, p1_area=True, intern=True) @@ -79,22 +79,22 @@ def update_axes(ax, mappable=None): # translate julian day in datetime64 t = all_a.time.astype("datetime64") - dt # %% -# Count how many are in polygon +# Number of eddies within a polygon ax = plt.figure(figsize=(12, 6)).add_subplot(111) -ax.set_title("Different way to count eddies presence in a polygon") +ax.set_title("Different ways to count eddies within a polygon") ax.set_ylabel("Count") m = all_a.mask_from_polygons(((xs, ys),)) -ax.hist(t[m], label="center in polygon", **kw_hist) -ax.hist(t[i_s[c_s > 0]], label="intersect speed contour with polygon", **kw_hist) -ax.hist(t[i_e[c_e > 0]], label="intersect extern contour with polygon", **kw_hist) +ax.hist(t[m], label="Eddy Center in polygon", **kw_hist) +ax.hist(t[i_s[c_s > 0]], label="Intersection Speed contour and polygon", **kw_hist) +ax.hist(t[i_e[c_e > 0]], label="Intersection Effective contour and polygon", **kw_hist) ax.legend() ax.set_xlim(np.datetime64("2010"), np.datetime64("2011")) ax.grid() # %% -# Percent of are of interest occupy by eddies +# Percent of the area of interest occupied by eddies. ax = plt.figure(figsize=(12, 6)).add_subplot(111) -ax.set_title("Percent of polygon occupy by an anticyclonic eddy") +ax.set_title("Percent of polygon occupied by an anticyclonic eddy") ax.set_ylabel("Percent of polygon") ax.hist(t[i_s[c_s > 0]], weights=c_s[c_s > 0] * 100.0, label="speed contour", **kw_hist) ax.hist( From 574a5e4016c86ebe29badb85082582472e26262a Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Tue, 11 Jan 2022 15:57:14 +0100 Subject: [PATCH 195/249] Add example to get path of particle with velocity field --- examples/07_cube_manipulation/README.rst | 4 - .../pet_particles_drift.py | 46 +++++++ .../pet_particles_drift.ipynb | 126 ++++++++++++++++++ src/py_eddy_tracker/dataset/grid.py | 22 +++ 4 files changed, 194 insertions(+), 4 deletions(-) create mode 100644 examples/07_cube_manipulation/pet_particles_drift.py create mode 100644 notebooks/python_module/07_cube_manipulation/pet_particles_drift.ipynb diff --git a/examples/07_cube_manipulation/README.rst b/examples/07_cube_manipulation/README.rst index 147ce3f3..7cecfbd4 100644 --- a/examples/07_cube_manipulation/README.rst +++ b/examples/07_cube_manipulation/README.rst @@ -1,6 +1,2 @@ Time grid computation ===================== - -.. warning:: - - Time grid is under development, API could move quickly! diff --git a/examples/07_cube_manipulation/pet_particles_drift.py b/examples/07_cube_manipulation/pet_particles_drift.py new file mode 100644 index 00000000..f73216fc --- /dev/null +++ b/examples/07_cube_manipulation/pet_particles_drift.py @@ -0,0 +1,46 @@ +""" +Build path of particle drifting +=============================== + +""" + +from matplotlib import pyplot as plt +from numpy import arange, meshgrid + +from py_eddy_tracker import start_logger +from py_eddy_tracker.data import get_demo_path +from py_eddy_tracker.dataset.grid import GridCollection + +start_logger().setLevel("ERROR") + +# %% +# Load data cube +c = GridCollection.from_netcdf_cube( + get_demo_path("dt_med_allsat_phy_l4_2005T2.nc"), + "longitude", + "latitude", + "time", + heigth="adt", +) + +# %% +# Advection properties +nb_days, step_by_day = 10, 6 +nb_time = step_by_day * nb_days +kw_p = dict(nb_step=1, time_step=86400 / step_by_day) +t0 = 20210 + +# %% +# Get paths +x0, y0 = meshgrid(arange(32, 35, 0.5), arange(32.5, 34.5, 0.5)) +x0, y0 = x0.reshape(-1), y0.reshape(-1) +t, x, y = c.path(x0, y0, "u", "v", t_init=t0, **kw_p, nb_time=nb_time) + +# %% +# Plot paths +ax = plt.figure(figsize=(9, 6)).add_subplot(111, aspect="equal") +ax.plot(x0, y0, "k.", ms=20) +ax.plot(x, y, lw=3) +ax.set_title("10 days particle paths") +ax.set_xlim(31, 35), ax.set_ylim(32, 34.5) +ax.grid() diff --git a/notebooks/python_module/07_cube_manipulation/pet_particles_drift.ipynb b/notebooks/python_module/07_cube_manipulation/pet_particles_drift.ipynb new file mode 100644 index 00000000..53365ac7 --- /dev/null +++ b/notebooks/python_module/07_cube_manipulation/pet_particles_drift.ipynb @@ -0,0 +1,126 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Build path of particle drifting\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from matplotlib import pyplot as plt\nfrom numpy import arange, meshgrid\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_demo_path\nfrom py_eddy_tracker.dataset.grid import GridCollection\n\nstart_logger().setLevel(\"ERROR\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load data cube\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "c = GridCollection.from_netcdf_cube(\n get_demo_path(\"dt_med_allsat_phy_l4_2005T2.nc\"),\n \"longitude\",\n \"latitude\",\n \"time\",\n heigth=\"adt\",\n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Advection properties\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "nb_days, step_by_day = 10, 6\nnb_time = step_by_day * nb_days\nkw_p = dict(nb_step=1, time_step=86400 / step_by_day)\nt0 = 20210" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get paths\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x0, y0 = meshgrid(arange(32, 35, 0.5), arange(32.5, 34.5, 0.5))\nx0, y0 = x0.reshape(-1), y0.reshape(-1)\nt, x, y = c.path(x0, y0, \"u\", \"v\", t_init=t0, **kw_p, nb_time=nb_time)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Plot paths\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ax = plt.figure(figsize=(9, 6)).add_subplot(111, aspect=\"equal\")\nax.plot(x0, y0, \"k.\", ms=20)\nax.plot(x, y, lw=3)\nax.set_title(\"10 days particle paths\")\nax.set_xlim(31, 35), ax.set_ylim(32, 34.5)\nax.grid()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 237577a4..8e9b0ac3 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -2517,6 +2517,28 @@ def get_previous_time_step(self, t_init): logger.debug(f"i={i}, t={t}, dataset={dataset}") yield t, dataset + def path(self, x0, y0, *args, nb_time=2, **kwargs): + """ + At each call it will update position in place with u & v field + + :param array x0: Longitude of obs to move + :param array y0: Latitude of obs to move + :param int nb_time: Number of iteration for particle + :param dict kwargs: look at :py:meth:`GridCollection.advect` + + :return: t,x,y + + .. minigallery:: py_eddy_tracker.GridCollection.path + """ + particles = self.advect(x0.copy(), y0.copy(), *args, **kwargs) + t = empty(nb_time + 1, dtype="f8") + x = empty((nb_time + 1, x0.size), dtype=x0.dtype) + y = empty(x.shape, dtype=y0.dtype) + t[0], x[0], y[0] = kwargs.get("t_init"), x0, y0 + for i in range(nb_time): + t[i + 1], x[i + 1], y[i + 1] = particles.__next__() + return t, x, y + @njit(cache=True) def advect_t(x_g, y_g, u_g0, v_g0, m_g0, u_g1, v_g1, m_g1, x, y, m, weigths, half_w=0): From ab67c557040055976887275b96a01e62abdc5827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= <49512274+ludwigVonKoopa@users.noreply.github.com> Date: Tue, 11 Jan 2022 16:11:49 +0100 Subject: [PATCH 196/249] update changelog for v3.6.0 (#129) --- CHANGELOG.rst | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 110c6081..2ec35e4b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -7,7 +7,19 @@ The format is based on `Keep a Changelog `_ and this project adheres to `Semantic Versioning `_. [Unreleased] ------------- +------------- +Changed +^^^^^^^ + +Fixed +^^^^^ + +Added +^^^^^ + + +[3.6.0] - 2022-01-12 +-------------------- Changed ^^^^^^^ @@ -15,8 +27,8 @@ Changed New identifications are produced with this type, old files could still be loaded. If you use old identifications for tracking use the `--unraw` option to unpack old times and store data with the new format. - Now amplitude is stored with .1 mm of precision (instead of 1 mm), same advice as for time. -- expose more parameters to users for bash tools build_network & divide_network -- add warning when loading a file created from a previous version of py-eddy-tracker. +- Expose more parameters to users for bash tools build_network & divide_network +- Add warning when loading a file created from a previous version of py-eddy-tracker. From 2d982d5515ec487c0c850c29a2676b81959288c7 Mon Sep 17 00:00:00 2001 From: Antoine <36040805+AntSimi@users.noreply.github.com> Date: Tue, 8 Feb 2022 12:32:08 +0100 Subject: [PATCH 197/249] Create codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 70 +++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000..d9437d16 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,70 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ master ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ master ] + schedule: + - cron: '41 16 * * 4' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'python' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Learn more about CodeQL language support at https://git.io/codeql-language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From 334d4c124fd998010757479d527fcd72153dcea8 Mon Sep 17 00:00:00 2001 From: AntSimi <36040805+AntSimi@users.noreply.github.com> Date: Sun, 27 Feb 2022 21:54:49 +0100 Subject: [PATCH 198/249] check coordinates in regular grid #138 --- CHANGELOG.rst | 2 ++ src/py_eddy_tracker/dataset/grid.py | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2ec35e4b..57fd7551 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -14,6 +14,8 @@ Changed Fixed ^^^^^ +- Check strictly increasing coordinates for RegularGridDataset. + Added ^^^^^ diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 8e9b0ac3..797e0482 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -1193,6 +1193,10 @@ def setup_coordinates(self): raise Exception( "Coordinates in RegularGridDataset must be 1D array, or think to use UnRegularGridDataset" ) + dx = self.x_bounds[1:] - self.x_bounds[:-1] + dy = self.y_bounds[1:] - self.y_bounds[:-1] + if (dx < 0).any() or (dy < 0).any(): + raise Exception("Coordinates in RegularGridDataset must be strictly increasing") self._x_step = (self.x_c[1:] - self.x_c[:-1]).mean() self._y_step = (self.y_c[1:] - self.y_c[:-1]).mean() From 5b2f6ff84e4f545a37099061091aba9e1e80e5f0 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle <36040805+AntSimi@users.noreply.github.com> Date: Thu, 7 Jul 2022 12:11:05 +0200 Subject: [PATCH 199/249] check mask #145 (#150) * check mask #145 * update python version for doc * switch order in requirement * fix pint version --- .github/workflows/python-app.yml | 2 +- doc/environment.yml | 2 +- requirements.txt | 8 ++++---- src/py_eddy_tracker/dataset/grid.py | 18 +++++++++--------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index a6fcceed..bbc0662c 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -11,7 +11,7 @@ jobs: matrix: # os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, windows-latest] - python_version: [3.7, 3.8, 3.9] + python_version: [3.7, 3.8, 3.9, '3.10'] name: Run py eddy tracker build tests runs-on: ${{ matrix.os }} defaults: diff --git a/doc/environment.yml b/doc/environment.yml index 7dcb504d..9d882911 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -2,7 +2,7 @@ channels: - conda-forge - defaults dependencies: - - python=3.8 + - python=3.10 - ffmpeg - pip: - sphinx-gallery diff --git a/requirements.txt b/requirements.txt index 477cf32d..497344e6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,11 @@ matplotlib -netCDF4 -numba>=0.53 -numpy<1.21 opencv-python -pint +pint==0.18 polygon3 pyyaml requests scipy zarr +netCDF4<1.6 +numpy<1.23 +numba<0.56 \ No newline at end of file diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 797e0482..30cdd863 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -402,6 +402,14 @@ def load(self): self.setup_coordinates() + @staticmethod + def get_mask(a): + if len(a.mask.shape): + m = a.mask + else: + m = ones(a.shape, dtype='bool') if a.mask else zeros(a.shape, dtype='bool') + return m + @staticmethod def c_to_bounds(c): """ @@ -1126,7 +1134,7 @@ def _low_filter(self, grid_name, w_cut, factor=8.0): bins = (x_array, y_array) x_flat, y_flat, z_flat = x.reshape((-1,)), y.reshape((-1,)), data.reshape((-1,)) - m = ~z_flat.mask + m = ~self.get_mask(z_flat) x_flat, y_flat, z_flat = x_flat[m], y_flat[m], z_flat[m] nb_value, _, _ = histogram2d(x_flat, y_flat, bins=bins) @@ -1936,14 +1944,6 @@ def regrid(self, other, grid_name, new_name=None): # self.variables_description[new_name]['infos'] = False # self.variables_description[new_name]['kwargs']['dimensions'] = ... - @staticmethod - def get_mask(a): - if len(a.mask.shape): - m = a.mask - else: - m = ones(a.shape) if a.mask else zeros(a.shape) - return m - def interp(self, grid_name, lons, lats, method="bilinear"): """ Compute z over lons, lats From e43c5692f48bab7c242722391cb0cd654423664a Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Wed, 7 Sep 2022 17:40:28 +0200 Subject: [PATCH 200/249] Add method to create obs from array Nb obs by network get track slice --- README.md | 2 +- src/py_eddy_tracker/observations/groups.py | 7 ++-- src/py_eddy_tracker/observations/network.py | 31 +++++++++++++-- .../observations/observation.py | 38 ++++++++++++++++--- src/py_eddy_tracker/observations/tracking.py | 9 ++++- 5 files changed, 74 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index c9e7690f..98a16b62 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Method was described in : -[Pegliasco, C., Delepoulle, A., Morrow, R., Faugère, Y., and Dibarboure, G.: META3.1exp : A new Global Mesoscale Eddy Trajectories Atlas derived from altimetry, Earth Syst. Sci. Data Discuss.](https://doi.org/10.5194/essd-2021-300) +[Pegliasco, C., Delepoulle, A., Morrow, R., Faugère, Y., and Dibarboure, G.: META3.1exp : A new Global Mesoscale Eddy Trajectories Atlas derived from altimetry, Earth Syst. Sci. Data Discuss.](https://doi.org/10.5194/essd-14-1087-2022) [Mason, E., A. Pascual, and J. C. McWilliams, 2014: A new sea surface height–based code for oceanic mesoscale eddy tracking.](https://doi.org/10.1175/JTECH-D-14-00019.1) diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index 6fea0ace..fcb6733b 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -66,7 +66,7 @@ def get_missing_indices( return indices -def advect(x, y, c, t0, n_days): +def advect(x, y, c, t0, n_days, u_name='u', v_name='v'): """ Advect particles from t0 to t0 + n_days, with data cube. @@ -75,13 +75,15 @@ def advect(x, y, c, t0, n_days): :param `~py_eddy_tracker.dataset.grid.GridCollection` c: GridCollection with speed for particles :param int t0: julian day of advection start :param int n_days: number of days to advect + :param str u_name: variable name for u component + :param str v_name: variable name for v component """ kw = dict(nb_step=6, time_step=86400 / 6) if n_days < 0: kw["backward"] = True n_days = -n_days - p = c.advect(x, y, "u", "v", t_init=t0, **kw) + p = c.advect(x, y, u_name, v_name, t_init=t0, **kw) for _ in range(n_days): t, x, y = p.__next__() return t, x, y @@ -125,7 +127,6 @@ def particle_candidate( else: x, y, i_start = e.create_particles(step_mesh, intern=True) print("The contour_start was not correct, speed contour is used") - # Advection t_end, x, y = advect(x, y, c, t_start, **kwargs) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 1c078bf8..4a884705 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -161,6 +161,16 @@ def index_network(self): self._index_network = build_index(self.track) return self._index_network + def network_size(self, id_networks): + """ + Return size for specified network + + :param list,array id_networks: ids to identify network + """ + i = id_networks - self.index_network[2] + i_start, i_stop = self.index_network[0][i], self.index_network[1][i] + return i_stop - i_start + def network_slice(self, id_network): """ Return slice for one network @@ -679,7 +689,13 @@ def display_timeline( """ self.only_one_network() j = 0 - line_kw = dict(ls="-", marker="+", markersize=6, zorder=1, lw=3,) + line_kw = dict( + ls="-", + marker="+", + markersize=6, + zorder=1, + lw=3, + ) line_kw.update(kwargs) mappables = dict(lines=list()) @@ -912,7 +928,10 @@ def event_map(self, ax, **kwargs): """Add the merging and splitting events to a map""" j = 0 mappables = dict() - symbol_kw = dict(markersize=10, color="k",) + symbol_kw = dict( + markersize=10, + color="k", + ) symbol_kw.update(kwargs) symbol_kw_split = symbol_kw.copy() symbol_kw_split["markersize"] += 4 @@ -941,7 +960,13 @@ def event_map(self, ax, **kwargs): return mappables def scatter( - self, ax, name="time", factor=1, ref=None, edgecolor_cycle=None, **kwargs, + self, + ax, + name="time", + factor=1, + ref=None, + edgecolor_cycle=None, + **kwargs, ): """ This function scatters the path of each network, with the merging and splitting events diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 3c8e1938..043b504d 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -130,7 +130,7 @@ def shifted_ellipsoid_degrees_mask2(lon0, lat0, lon1, lat1, minor=1.5, major=1.5 if dx > major[j]: m[j, i] = False continue - d_normalize = dx ** 2 / major[j] ** 2 + dy ** 2 / minor ** 2 + d_normalize = dx**2 / major[j] ** 2 + dy**2 / minor**2 m[j, i] = d_normalize < 1.0 return m @@ -729,7 +729,11 @@ def load_file(cls, filename, **kwargs): .. code-block:: python kwargs_latlon_300 = dict( - include_vars=["longitude", "latitude",], indexs=dict(obs=slice(0, 300)), + include_vars=[ + "longitude", + "latitude", + ], + indexs=dict(obs=slice(0, 300)), ) small_dataset = TrackEddiesObservations.load_file( filename, **kwargs_latlon_300 @@ -1047,6 +1051,19 @@ def compare_units(input_unit, output_unit, name): output_unit, ) + @classmethod + def from_array(cls, arrays, **kwargs): + nb = arrays["time"].size + # if hasattr(handler, "track_array_variables"): + # kwargs["track_array_variables"] = handler.track_array_variables + # kwargs["array_variables"] = handler.array_variables.split(",") + # if len(handler.track_extra_variables) > 1: + # kwargs["track_extra_variables"] = handler.track_extra_variables.split(",") + eddies = cls(size=nb, **kwargs) + for k, v in arrays.items(): + eddies.obs[k] = v + return eddies + @classmethod def from_zarr(cls, handler): nb_obs = len(handler.dimensions[cls.obs_dimension(handler)]) @@ -1302,7 +1319,7 @@ def fixed_ellipsoid_mask( if isinstance(minor, ndarray): minor = minor[index_self] # focal distance - f_degree = ((major ** 2 - minor ** 2) ** 0.5) / ( + f_degree = ((major**2 - minor**2) ** 0.5) / ( 111.2 * cos(radians(self.lat[index_self])) ) @@ -2010,7 +2027,11 @@ def bins_stat(self, xname, bins=None, yname=None, method=None, mask=None): def format_label(self, label): t0, t1 = self.period - return label.format(t0=t0, t1=t1, nb_obs=len(self),) + return label.format( + t0=t0, + t1=t1, + nb_obs=len(self), + ) def display(self, ax, ref=None, extern_only=False, intern_only=False, **kwargs): """Plot the speed and effective (dashed) contour of the eddies @@ -2381,7 +2402,14 @@ def grid_count_pixel_in( x_, y_ = reduce_size(x_, y_) v = create_vertice(x_, y_) (x_start, x_stop), (y_start, y_stop) = bbox_indice_regular( - v, x_bounds, y_bounds, xstep, ystep, N, is_circular, x_size, + v, + x_bounds, + y_bounds, + xstep, + ystep, + N, + is_circular, + x_size, ) i, j = get_pixel_in_regular(v, x_c, y_c, x_start, x_stop, y_start, y_stop) grid_count_(grid, i, j) diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index 6612c6d5..7680961c 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -68,6 +68,10 @@ def __init__(self, *args, **kwargs): self.__obs_by_track = None self.__nb_track = None + def track_slice(self, track): + i0 = self.index_from_track[track] + return slice(i0, i0 + self.nb_obs_by_track[track]) + def iter_track(self): """ Yield track @@ -582,7 +586,10 @@ def close_tracks(self, other, nb_obs_min=10, **kwargs): def format_label(self, label): t0, t1 = self.period return label.format( - t0=t0, t1=t1, nb_obs=len(self), nb_tracks=(self.nb_obs_by_track != 0).sum(), + t0=t0, + t1=t1, + nb_obs=len(self), + nb_tracks=(self.nb_obs_by_track != 0).sum(), ) def plot(self, ax, ref=None, **kwargs): From 6dcbbc43812ac2f1a51983253ff779ae8020741b Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle <36040805+AntSimi@users.noreply.github.com> Date: Tue, 13 Sep 2022 12:20:31 +0200 Subject: [PATCH 201/249] Add log in GUI (#155) Give a factor in all case of unit --- check.sh | 2 +- src/py_eddy_tracker/dataset/grid.py | 2 +- src/py_eddy_tracker/gui.py | 5 ++++- src/py_eddy_tracker/observations/observation.py | 3 +++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/check.sh b/check.sh index ddafab69..b158028a 100644 --- a/check.sh +++ b/check.sh @@ -4,4 +4,4 @@ blackdoc src tests examples flake8 tests examples src --count --select=E9,F63,F7,F82 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 tests examples src --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics -pytest -vv --cov py_eddy_tracker --cov-report html +python -m pytest -vv --cov py_eddy_tracker --cov-report html diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 30cdd863..bf02a1b0 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -407,7 +407,7 @@ def get_mask(a): if len(a.mask.shape): m = a.mask else: - m = ones(a.shape, dtype='bool') if a.mask else zeros(a.shape, dtype='bool') + m = ones(a.shape, dtype="bool") if a.mask else zeros(a.shape, dtype="bool") return m @staticmethod diff --git a/src/py_eddy_tracker/gui.py b/src/py_eddy_tracker/gui.py index deeb6660..0f310467 100644 --- a/src/py_eddy_tracker/gui.py +++ b/src/py_eddy_tracker/gui.py @@ -3,6 +3,7 @@ GUI class """ +import logging from datetime import datetime, timedelta import matplotlib.pyplot as plt @@ -11,6 +12,8 @@ from .generic import flatten_line_matrix, split_line +logger = logging.getLogger("pet") + try: from pylook.axes import PlatCarreAxes except ImportError: @@ -91,7 +94,7 @@ def set_initial_values(self): for dataset in self.datasets.values(): t0_, t1_ = dataset.period t0, t1 = min(t0, t0_), max(t1, t1_) - + logger.debug("period detected %f -> %f", t0, t1) self.settings = dict(period=(t0, t1), now=t1) @property diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 043b504d..651aaa9a 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -1050,6 +1050,9 @@ def compare_units(input_unit, output_unit, name): input_unit, output_unit, ) + return factor + else: + return 1 @classmethod def from_array(cls, arrays, **kwargs): From 9e04d815e3120c55d4b6b2c82b130236373978a4 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Mon, 19 Sep 2022 10:11:51 +0200 Subject: [PATCH 202/249] - Add method to colorize contour with a field - Add option to force align on to return all step for reference dataset - Add method and property to network to easily select segment and network - Add method to found same track/segment/network in dataset - Rewrite particle candidate to be easily parallelize --- setup.cfg | 14 + setup.py | 1 + src/py_eddy_tracker/__init__.py | 13 +- src/py_eddy_tracker/appli/eddies.py | 18 +- src/py_eddy_tracker/appli/network.py | 133 +++++++++ src/py_eddy_tracker/dataset/grid.py | 38 ++- src/py_eddy_tracker/eddy_feature.py | 6 +- src/py_eddy_tracker/generic.py | 59 +++- src/py_eddy_tracker/misc.py | 19 ++ src/py_eddy_tracker/observations/groups.py | 136 ++++++++- src/py_eddy_tracker/observations/network.py | 277 ++++++++++++++++-- .../observations/observation.py | 73 +++-- src/py_eddy_tracker/poly.py | 41 ++- tests/test_grid.py | 16 +- tests/test_poly.py | 2 +- 15 files changed, 738 insertions(+), 108 deletions(-) create mode 100644 src/py_eddy_tracker/misc.py diff --git a/setup.cfg b/setup.cfg index dfed5c3b..66f3f495 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,8 +1,22 @@ [flake8] +max-line-length = 140 ignore = E203, # whitespace before ':' W503, # line break before binary operator +[isort] +combine_as_imports=True +force_grid_wrap=0 +force_sort_within_sections=True +force_to_top=typing +include_trailing_comma=True +line_length=140 +multi_line_output=3 +skip= + build + docs/source/conf.py + + [versioneer] VCS = git style = pep440 diff --git a/setup.py b/setup.py index 06432bd1..e0767c10 100644 --- a/setup.py +++ b/setup.py @@ -48,6 +48,7 @@ "EddyNetworkGroup = py_eddy_tracker.appli.network:build_network", "EddyNetworkBuildPath = py_eddy_tracker.appli.network:divide_network", "EddyNetworkSubSetter = py_eddy_tracker.appli.network:subset_network", + "EddyNetworkQuickCompare = py_eddy_tracker.appli.network:quick_compare", # anim/gui "EddyAnim = py_eddy_tracker.appli.gui:anim", "GUIEddy = py_eddy_tracker.appli.gui:guieddy", diff --git a/src/py_eddy_tracker/__init__.py b/src/py_eddy_tracker/__init__.py index 275bb795..f3ecec84 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -422,14 +422,20 @@ def identify_time(str_date): nc_name="previous_cost", nc_type="float32", nc_dims=("obs",), - nc_attr=dict(long_name="Previous cost for previous observation", comment="",), + nc_attr=dict( + long_name="Previous cost for previous observation", + comment="", + ), ), next_cost=dict( attr_name=None, nc_name="next_cost", nc_type="float32", nc_dims=("obs",), - nc_attr=dict(long_name="Next cost for next observation", comment="",), + nc_attr=dict( + long_name="Next cost for next observation", + comment="", + ), ), n=dict( attr_name=None, @@ -640,7 +646,8 @@ def identify_time(str_date): nc_type="f4", nc_dims=("obs",), nc_attr=dict( - long_name="Log base 10 background chlorophyll", units="Log(Chl/[mg/m^3])", + long_name="Log base 10 background chlorophyll", + units="Log(Chl/[mg/m^3])", ), ), year=dict( diff --git a/src/py_eddy_tracker/appli/eddies.py b/src/py_eddy_tracker/appli/eddies.py index 4809fddf..df4e7d43 100644 --- a/src/py_eddy_tracker/appli/eddies.py +++ b/src/py_eddy_tracker/appli/eddies.py @@ -243,7 +243,8 @@ def browse_dataset_in( filenames = bytes_(glob(full_path)) dataset_list = empty( - len(filenames), dtype=[("filename", "S500"), ("date", "datetime64[s]")], + len(filenames), + dtype=[("filename", "S500"), ("date", "datetime64[s]")], ) dataset_list["filename"] = filenames @@ -371,7 +372,8 @@ def track( logger.info("Longer track saved have %d obs", c.nb_obs_by_tracks.max()) logger.info( - "The mean length is %d observations for long track", c.nb_obs_by_tracks.mean(), + "The mean length is %d observations for long track", + c.nb_obs_by_tracks.mean(), ) long_track.write_file(**kw_write) @@ -381,7 +383,14 @@ def track( def get_group( - dataset1, dataset2, index1, index2, score, invalid=2, low=10, high=60, + dataset1, + dataset2, + index1, + index2, + score, + invalid=2, + low=10, + high=60, ): group1, group2 = dict(), dict() m_valid = (score * 100) >= invalid @@ -490,7 +499,8 @@ def get_values(v, dataset): ] labels = dict( - high=f"{high:0.0f} <= high", low=f"{invalid:0.0f} <= low < {low:0.0f}", + high=f"{high:0.0f} <= high", + low=f"{invalid:0.0f} <= low < {low:0.0f}", ) keys = [labels.get(key, key) for key in list(gr_ref.values())[0].keys()] diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index e9baa7be..bfe226cc 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -8,6 +8,7 @@ from .. import EddyParser from ..observations.network import Network, NetworkObservations from ..observations.tracking import TrackEddiesObservations +from numpy import in1d, zeros logger = logging.getLogger("pet") @@ -128,3 +129,135 @@ def subset_network(): if args.period is not None: n = n.extract_with_period(args.period) n.write_file(filename=args.out) + + +def quick_compare(): + parser = EddyParser( + """Tool to have a quick comparison between several network: + - N : network + - S : segment + - Obs : observations + """ + + ) + parser.add_argument("ref", help="Identification file of reference") + parser.add_argument("others", nargs="+", help="Identifications files to compare") + parser.add_argument( + "--path_out", default=None, help="Save each group in separate file" + ) + args = parser.parse_args() + + kw = dict( + include_vars=['longitude', 'latitude', 'time', 'track', 'segment', 'next_obs', 'previous_obs'] + ) + + if args.path_out is not None: + kw = dict() + + ref = NetworkObservations.load_file(args.ref, **kw) + print( + f"[ref] {args.ref} -> {ref.nb_network} network / {ref.nb_segment} segment / {len(ref)} obs " + f"-> {ref.network_size(0)} trash obs, " + f"{len(ref.merging_event())} merging, {len(ref.splitting_event())} spliting" + ) + others = {other: NetworkObservations.load_file(other, **kw) for other in args.others} + + if args.path_out is not None: + groups_ref, groups_other = run_compare(ref, others, **kwargs) + if not exists(args.path_out): + mkdir(args.path_out) + for i, other_ in enumerate(args.others): + dirname_ = f"{args.path_out}/{other_.replace('/', '_')}/" + if not exists(dirname_): + mkdir(dirname_) + for k, v in groups_other[other_].items(): + basename_ = f"other_{k}.nc" + others[other_].index(v).write_file(filename=f"{dirname_}/{basename_}") + for k, v in groups_ref[other_].items(): + basename_ = f"ref_{k}.nc" + ref.index(v).write_file(filename=f"{dirname_}/{basename_}") + return + display_compare(ref, others) + + +def run_compare(ref, others): + outs = dict() + for i, (k, other) in enumerate(others.items()): + out = dict() + print( + f"[{i}] {k} -> {other.nb_network} network / {other.nb_segment} segment / {len(other)} obs " + f"-> {other.network_size(0)} trash obs, " + f"{len(other.merging_event())} merging, {len(other.splitting_event())} spliting" + ) + ref_id, other_id = ref.identify_in(other, size_min=2) + m = other_id != -1 + ref_id, other_id = ref_id[m], other_id[m] + out['same N(N)'] = m.sum() + out['same N(Obs)'] = ref.network_size(ref_id).sum() + + # For network which have same obs + ref_, other_ = ref.networks(ref_id), other.networks(other_id) + ref_segu, other_segu = ref_.identify_in(other_, segment=True) + m = other_segu==-1 + ref_track_no_match, _ = ref_.unique_segment_to_id(ref_segu[m]) + ref_segu, other_segu = ref_segu[~m], other_segu[~m] + m = ~in1d(ref_id, ref_track_no_match) + out['same NS(N)'] = m.sum() + out['same NS(Obs)'] = ref.network_size(ref_id[m]).sum() + + # Check merge/split + def follow_obs(d, i_follow): + m = i_follow != -1 + i_follow = i_follow[m] + t, x, y = zeros(m.size, d.time.dtype), zeros(m.size, d.longitude.dtype), zeros(m.size, d.latitude.dtype) + t[m], x[m], y[m] = d.time[i_follow], d.longitude[i_follow], d.latitude[i_follow] + return t, x, y + def next_obs(d, i_seg): + last_i = d.index_segment_track[1][i_seg] - 1 + return follow_obs(d, d.next_obs[last_i]) + def previous_obs(d, i_seg): + first_i = d.index_segment_track[0][i_seg] + return follow_obs(d, d.previous_obs[first_i]) + + tref, xref, yref = next_obs(ref_, ref_segu) + tother, xother, yother = next_obs(other_, other_segu) + + m = (tref == tother) & (xref == xother) & (yref == yother) + print(m.sum(), m.size, ref_segu.size, ref_track_no_match.size) + + tref, xref, yref = previous_obs(ref_, ref_segu) + tother, xother, yother = previous_obs(other_, other_segu) + + m = (tref == tother) & (xref == xother) & (yref == yother) + print(m.sum(), m.size, ref_segu.size, ref_track_no_match.size) + + + + ref_segu, other_segu = ref.identify_in(other, segment=True) + m = other_segu != -1 + out['same S(S)'] = m.sum() + out['same S(Obs)'] = ref.segment_size()[ref_segu[m]].sum() + + outs[k] = out + return outs + +def display_compare(ref, others): + def display(value, ref=None): + if ref: + outs = [f"{v/ref[k] * 100:.1f}% ({v})" for k, v in value.items()] + else: + outs = value + return "".join([f"{v:^18}" for v in outs]) + + datas = run_compare(ref, others) + ref_ = { + 'same N(N)' : ref.nb_network, + "same N(Obs)": len(ref), + 'same NS(N)' : ref.nb_network, + 'same NS(Obs)' : len(ref), + 'same S(S)' : ref.nb_segment, + 'same S(Obs)' : len(ref), + } + print(" ", display(ref_.keys())) + for i, (_, v) in enumerate(datas.items()): + print(f"[{i:2}] ", display(v, ref=ref_)) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index bf02a1b0..24b1e25b 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -310,6 +310,11 @@ def __init__( self.load_general_features() self.load() + def populate(self): + if self.dimensions is None: + self.load_general_features() + self.load() + @property def is_centered(self): """Give True if pixel is described with its center's position or @@ -539,7 +544,8 @@ def grid(self, varname, indexs=None): self.vars[varname] = self.vars[varname].T if self.nan_mask: self.vars[varname] = ma.array( - self.vars[varname], mask=isnan(self.vars[varname]), + self.vars[varname], + mask=isnan(self.vars[varname]), ) if not hasattr(self.vars[varname], "mask"): self.vars[varname] = ma.array( @@ -869,7 +875,9 @@ def eddy_identification( num_fac=presampling_multiplier, ) xy_e = uniform_resample( - contour.lon, contour.lat, num_fac=presampling_multiplier, + contour.lon, + contour.lat, + num_fac=presampling_multiplier, ) xy_s = uniform_resample( speed_contour.lon, @@ -1204,7 +1212,9 @@ def setup_coordinates(self): dx = self.x_bounds[1:] - self.x_bounds[:-1] dy = self.y_bounds[1:] - self.y_bounds[:-1] if (dx < 0).any() or (dy < 0).any(): - raise Exception("Coordinates in RegularGridDataset must be strictly increasing") + raise Exception( + "Coordinates in RegularGridDataset must be strictly increasing" + ) self._x_step = (self.x_c[1:] - self.x_c[:-1]).mean() self._y_step = (self.y_c[1:] - self.y_c[:-1]).mean() @@ -1736,7 +1746,7 @@ def compute_stencil( self.x_c, self.y_c, data.data, - data.mask, + self.get_mask(data), self.EARTH_RADIUS, vertical=vertical, stencil_halfwidth=stencil_halfwidth, @@ -2285,23 +2295,23 @@ def __init__(self): self.datasets = list() @classmethod - def from_netcdf_cube(cls, filename, x_name, y_name, t_name, heigth=None): + def from_netcdf_cube(cls, filename, x_name, y_name, t_name, heigth=None, **kwargs): new = cls() with Dataset(filename) as h: for i, t in enumerate(h.variables[t_name][:]): - d = RegularGridDataset(filename, x_name, y_name, indexs={t_name: i}) + d = RegularGridDataset(filename, x_name, y_name, indexs={t_name: i}, **kwargs) if heigth is not None: d.add_uv(heigth) new.datasets.append((t, d)) return new @classmethod - def from_netcdf_list(cls, filenames, t, x_name, y_name, indexs=None, heigth=None): + def from_netcdf_list(cls, filenames, t, x_name, y_name, indexs=None, heigth=None, **kwargs): new = cls() for i, _t in enumerate(t): filename = filenames[i] logger.debug(f"load file {i:02d}/{len(t)} t={_t} : {filename}") - d = RegularGridDataset(filename, x_name, y_name, indexs=indexs) + d = RegularGridDataset(filename, x_name, y_name, indexs=indexs, **kwargs) if heigth is not None: d.add_uv(heigth) new.datasets.append((_t, d)) @@ -2349,6 +2359,7 @@ def __iter__(self): def __getitem__(self, item): for t, d in self.datasets: if t == item: + d.populate() return d raise KeyError(item) @@ -2448,10 +2459,13 @@ def advect( :param array y: Latitude of obs to move :param str,array u_name: U field to advect obs :param str,array v_name: V field to advect obs + :param float t_init: time to start advection + :param array,None mask_particule: advect only i mask is True :param int nb_step: Number of iteration before to release data :param int time_step: Number of second for each advection + :param bool rk4: Use rk4 algorithm instead of finite difference - :return: x,y position + :return: t,x,y position .. minigallery:: py_eddy_tracker.GridCollection.advect """ @@ -2477,7 +2491,7 @@ def advect( else: mask_particule += isnan(x) + isnan(y) while True: - logger.debug(f"advect : t={t}") + logger.debug(f"advect : t={t/86400}") if (backward and t <= t1) or (not backward and t >= t1): t0, u0, v0, m0 = t1, u1, v1, m1 t1, d1 = generator.__next__() @@ -2507,7 +2521,7 @@ def get_next_time_step(self, t_init): for i, (t, dataset) in enumerate(self.datasets): if t < t_init: continue - + dataset.populate() logger.debug(f"i={i}, t={t}, dataset={dataset}") yield t, dataset @@ -2517,7 +2531,7 @@ def get_previous_time_step(self, t_init): i -= 1 if t > t_init: continue - + dataset.populate() logger.debug(f"i={i}, t={t}, dataset={dataset}") yield t, dataset diff --git a/src/py_eddy_tracker/eddy_feature.py b/src/py_eddy_tracker/eddy_feature.py index 3640b306..0f13eb2a 100644 --- a/src/py_eddy_tracker/eddy_feature.py +++ b/src/py_eddy_tracker/eddy_feature.py @@ -433,8 +433,8 @@ def __init__(self, x, y, z, levels, wrap_x=False, keep_unclose=False): closed_contours = 0 # Count level and contour for i, collection in enumerate(self.contours.collections): - collection.get_nearest_path_bbox_contain_pt = lambda x, y, i=i: self.get_index_nearest_path_bbox_contain_pt( - i, x, y + collection.get_nearest_path_bbox_contain_pt = ( + lambda x, y, i=i: self.get_index_nearest_path_bbox_contain_pt(i, x, y) ) nb_level += 1 @@ -784,7 +784,7 @@ def index_from_nearest_path_with_pt_in_bbox_( d_x = x_value[i_elt_pt] - xpt_ if abs(d_x) > 180: d_x = (d_x + 180) % 360 - 180 - dist = d_x ** 2 + (y_value[i_elt_pt] - ypt) ** 2 + dist = d_x**2 + (y_value[i_elt_pt] - ypt) ** 2 if dist < dist_ref: dist_ref = dist i_ref = i_elt_c diff --git a/src/py_eddy_tracker/generic.py b/src/py_eddy_tracker/generic.py index 94cf321f..c2d7de8a 100644 --- a/src/py_eddy_tracker/generic.py +++ b/src/py_eddy_tracker/generic.py @@ -132,8 +132,8 @@ def distance_grid(lon0, lat0, lon1, lat1): sin_dlon = sin((dlon) * 0.5 * D2R) cos_lat1 = cos(lat0[i] * D2R) cos_lat2 = cos(lat1[j] * D2R) - a_val = sin_dlon ** 2 * cos_lat1 * cos_lat2 + sin_dlat ** 2 - dist[i, j] = 6370.997 * 2 * arctan2(a_val ** 0.5, (1 - a_val) ** 0.5) + a_val = sin_dlon**2 * cos_lat1 * cos_lat2 + sin_dlat**2 + dist[i, j] = 6370.997 * 2 * arctan2(a_val**0.5, (1 - a_val) ** 0.5) return dist @@ -154,8 +154,8 @@ def distance(lon0, lat0, lon1, lat1): sin_dlon = sin((lon1 - lon0) * 0.5 * D2R) cos_lat1 = cos(lat0 * D2R) cos_lat2 = cos(lat1 * D2R) - a_val = sin_dlon ** 2 * cos_lat1 * cos_lat2 + sin_dlat ** 2 - return 6370997.0 * 2 * arctan2(a_val ** 0.5, (1 - a_val) ** 0.5) + a_val = sin_dlon**2 * cos_lat1 * cos_lat2 + sin_dlat**2 + return 6370997.0 * 2 * arctan2(a_val**0.5, (1 - a_val) ** 0.5) @njit(cache=True) @@ -367,7 +367,7 @@ def simplify(x, y, precision=0.1): :return: (x,y) :rtype: (array,array) """ - precision2 = precision ** 2 + precision2 = precision**2 nb = x.shape[0] # will be True for kept values mask = ones(nb, dtype=bool_) @@ -399,7 +399,7 @@ def simplify(x, y, precision=0.1): if d_y > precision: x_previous, y_previous = x_, y_ continue - d2 = d_x ** 2 + d_y ** 2 + d2 = d_x**2 + d_y**2 if d2 > precision2: x_previous, y_previous = x_, y_ continue @@ -517,8 +517,8 @@ def coordinates_to_local(lon, lat, lon0, lat0): sin_dlon = sin(dlon * 0.5) cos_lat0 = cos(lat0 * D2R) cos_lat = cos(lat * D2R) - a_val = sin_dlon ** 2 * cos_lat0 * cos_lat + sin_dlat ** 2 - module = R * 2 * arctan2(a_val ** 0.5, (1 - a_val) ** 0.5) + a_val = sin_dlon**2 * cos_lat0 * cos_lat + sin_dlat**2 + module = R * 2 * arctan2(a_val**0.5, (1 - a_val) ** 0.5) azimuth = pi / 2 - arctan2( cos_lat * sin(dlon), @@ -541,7 +541,7 @@ def local_to_coordinates(x, y, lon0, lat0): """ D2R = pi / 180.0 R = 6370997 - d = (x ** 2 + y ** 2) ** 0.5 / R + d = (x**2 + y**2) ** 0.5 / R a = -(arctan2(y, x) - pi / 2) lat = arcsin(sin(lat0 * D2R) * cos(d) + cos(lat0 * D2R) * sin(d) * cos(a)) lon = ( @@ -612,3 +612,44 @@ def build_circle(x0, y0, r): angle = radians(linspace(0, 360, 50)) x_norm, y_norm = cos(angle), sin(angle) return x_norm * r + x0, y_norm * r + y0 + + +@njit(cache=True) +def window_index(x, x0, half_window=1): + """ + Give for a fixed half_window each start and end index for each x0, in + an unsorted array. + + :param array x: array of value + :param array x0: array of window center + :param float half_window: half window + """ + # Sort array, bounds will be sort also + i_ordered = x.argsort() + nb_x, nb_pt = x.size, x0.size + first_index = empty(nb_pt, dtype=i_ordered.dtype) + last_index = empty(nb_pt, dtype=i_ordered.dtype) + # First bound to find + j_min, j_max = 0, 0 + x_min = x0[j_min] - half_window + x_max = x0[j_max] + half_window + # We iterate on ordered x + for i, i_x in enumerate(i_ordered): + x_ = x[i_x] + # if x bigger than x_min , we found bound and search next one + while x_ > x_min and j_min < nb_pt: + first_index[j_min] = i + j_min += 1 + x_min = x0[j_min] - half_window + # if x bigger than x_max , we found bound and search next one + while x_ > x_max and j_max < nb_pt: + last_index[j_max] = i + j_max += 1 + x_max = x0[j_max] + half_window + if j_max == nb_pt: + break + for i in range(j_min, nb_pt): + first_index[i] = nb_x + for i in range(j_max, nb_pt): + last_index[i] = nb_x + return i_ordered, first_index, last_index diff --git a/src/py_eddy_tracker/misc.py b/src/py_eddy_tracker/misc.py new file mode 100644 index 00000000..eb0dc5d1 --- /dev/null +++ b/src/py_eddy_tracker/misc.py @@ -0,0 +1,19 @@ +import re +from matplotlib.animation import FuncAnimation + +class VideoAnimation(FuncAnimation): + def _repr_html_(self, *args, **kwargs): + """To get video in html and have a player""" + 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) \ No newline at end of file diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index fcb6733b..66574407 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -3,10 +3,13 @@ from numba import njit from numba import types as nb_types -from numpy import arange, int32, interp, median, where, zeros +from numpy import arange, int32, interp, median, where, zeros, full, isnan from .observation import EddiesObservations +from ..generic import window_index +from ..poly import create_meshed_particles, poly_indexs + logger = logging.getLogger("pet") @@ -89,6 +92,39 @@ def advect(x, y, c, t0, n_days, u_name='u', v_name='v'): return t, x, y +def particle_candidate_step(t_start, contours_start, contours_end, space_step, dt, c, **kwargs): + """Select particles within eddies, advect them, return target observation and associated percentages. + For one time step. + + :param int t_start: julian day of the advection + :param (np.array(float),np.array(float)) contours_start: origin contour + :param (np.array(float),np.array(float)) contours_end: destination contour + :param float space_step: step between 2 particles + :param int dt: duration of advection + :param `~py_eddy_tracker.dataset.grid.GridCollection` c: GridCollection with speed for particles + :params dict kwargs: dict of params given to advection + :return (np.array,np.array): return target index and percent associate + """ + # Create particles in start contour + x, y, i_start = create_meshed_particles(*contours_start, space_step) + # Advect particles + kw = dict(nb_step=6, time_step=86400 / 6) + p = c.advect(x, y, t_init=t_start, **kwargs, **kw) + for _ in range(dt): + _, x, y = p.__next__() + m = ~(isnan(x) + isnan(y)) + i_end = full(x.shape, -1, dtype="i4") + if m.any(): + # Id eddies for each alive particle in start contour + i_end[m] = poly_indexs(x[m], y[m], *contours_end) + shape = (contours_start[0].shape[0], 2) + # Get target for each contour + i_target, pct_target = full(shape, -1, dtype="i4"), zeros(shape, dtype="f8") + nb_end = contours_end[0].shape[0] + get_targets(i_start, i_end, i_target, pct_target, nb_end) + return i_target, pct_target.astype('i1') + + def particle_candidate( c, eddies, @@ -120,13 +156,8 @@ def particle_candidate( translate_start = where(m_start)[0] # Create particles in specified contour - if contour_start == "speed": - x, y, i_start = e.create_particles(step_mesh, intern=True) - elif contour_start == "effective": - x, y, i_start = e.create_particles(step_mesh, intern=False) - else: - x, y, i_start = e.create_particles(step_mesh, intern=True) - print("The contour_start was not correct, speed contour is used") + intern = False if contour_start == "effective" else True + x, y, i_start = e.create_particles(step_mesh, intern=intern) # Advection t_end, x, y = advect(x, y, c, t_start, **kwargs) @@ -138,18 +169,54 @@ def particle_candidate( translate_end = where(m_end)[0] # Id eddies for each alive particle in specified contour - if contour_end == "speed": - i_end = e_end.contains(x, y, intern=True) - elif contour_end == "effective": - i_end = e_end.contains(x, y, intern=False) - else: - i_end = e_end.contains(x, y, intern=True) - print("The contour_end was not correct, speed contour is used") + intern = False if contour_end == "effective" else True + i_end = e_end.contains(x, y, intern=intern) # compute matrix and fill target array get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct) +@njit(cache=True) +def get_targets(i_start, i_end, i_target, pct, nb_end): + """Compute target observation and associated percentages + + :param array(int) i_start: indices in time 0 + :param array(int) i_end: indices in time N + :param array(int) i_target: corresponding obs where particles are advected + :param array(int) pct: corresponding percentage of avected particles + :param int nb_end: number of contour at time N + """ + nb_start = i_target.shape[0] + # Matrix which will store count for every couple + counts = zeros((nb_start, nb_end), dtype=nb_types.int32) + # Number of particles in each origin observation + ref = zeros(nb_start, dtype=nb_types.int32) + # For each particle + for i in range(i_start.size): + i_end_ = i_end[i] + i_start_ = i_start[i] + ref[i_start_] += 1 + if i_end_ != -1: + counts[i_start_, i_end_] += 1 + # From i to j + for i in range(nb_start): + for j in range(nb_end): + count = counts[i, j] + if count == 0: + continue + pct_ = count / ref[i] * 100 + pct_0 = pct[i, 0] + # If percent is higher than previous stored in rank 0 + if pct_ > pct_0: + pct[i, 1] = pct_0 + pct[i, 0] = pct_ + i_target[i, 1] = i_target[i, 0] + i_target[i, 0] = j + # If percent is higher than previous stored in rank 1 + elif pct_ > pct[i, 1]: + pct[i, 1] = pct_ + i_target[i, 1] = j + @njit(cache=True) def get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct): """Compute target observation and associated percentages @@ -278,3 +345,42 @@ def keep_tracks_by_date(self, date, nb_days): mask[i] = True return self.extract_with_mask(mask) + + def particle_candidate_atlas(self, cube, space_step, dt, start_intern=False, end_intern=False, **kwargs): + """Select particles within eddies, advect them, return target observation and associated percentages + + :param `~py_eddy_tracker.dataset.grid.GridCollection` cube: GridCollection with speed for particles + :param float space_step: step between 2 particles + :param int dt: duration of advection + :param bool start_intern: Use intern or extern contour at injection, defaults to False + :param bool end_intern: Use intern or extern contour at end of advection, defaults to False + :params dict kwargs: dict of params given to advection + :return (np.array,np.array): return target index and percent associate + """ + t_start, t_end = int(self.period[0]), int(self.period[1]) + # Pre-compute to get time index + i_sort, i_start, i_end = window_index(self.time, arange(t_start, t_end + 1), .5) + # Out shape + shape = (len(self), 2) + i_target, pct = full(shape, -1, dtype="i4"), zeros(shape, dtype="i1") + # Backward or forward + times = arange(t_start, t_end - dt) if dt > 0 else arange(t_start + dt, t_end) + for t in times: + # Get index for origin + i = t - t_start + indexs0 = i_sort[i_start[i]:i_end[i]] + # Get index for end + i = t + dt - t_start + indexs1 = i_sort[i_start[i]:i_end[i]] + # Get contour data + contours0 = [self[label][indexs0] for label in self.intern(start_intern)] + contours1 = [self[label][indexs1] for label in self.intern(end_intern)] + # Get local result + i_target_, pct_ = particle_candidate_step(t, contours0, contours1, space_step, dt, cube, **kwargs) + # Merge result + m = i_target_ != -1 + i_target_[m] = indexs1[i_target_[m]] + i_target[indexs0] = i_target_ + pct[indexs0] = pct_ + return i_target, pct + \ No newline at end of file diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 4a884705..b633fc40 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -8,6 +8,7 @@ import netCDF4 import zarr +from numba.typed import List from numba import njit from numpy import ( arange, @@ -110,6 +111,8 @@ class NetworkObservations(GroupEddiesObservations): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._index_network = None + self._index_segment_track = None + self._segment_track_array = None def find_segments_relative(self, obs, stopped=None, order=1): """ @@ -161,16 +164,64 @@ def index_network(self): self._index_network = build_index(self.track) return self._index_network - def network_size(self, id_networks): + @property + def index_segment_track(self): + if self._index_segment_track is None: + self._index_segment_track = build_index(self.segment_track_array) + return self._index_segment_track + + def segment_size(self): + return self.index_segment_track[1] - self.index_segment_track[0] + + @property + def ref_segment_track_index(self): + return self.index_segment_track[2] + + @property + def ref_index(self): + return self.index_network[2] + + def network_segment_size(self, id_networks=None): + """Get number of segment by network + + :return array: + """ + i0, i1, ref = build_index(self.track[self.index_segment_track[0]]) + if id_networks is None: + return i1-i0 + else: + i = id_networks - ref + return i1[i] - i0[i] + + def network_size(self, id_networks=None): """ Return size for specified network - :param list,array id_networks: ids to identify network + :param list,array, None id_networks: ids to identify network """ - i = id_networks - self.index_network[2] - i_start, i_stop = self.index_network[0][i], self.index_network[1][i] - return i_stop - i_start + if id_networks is None: + return self.index_network[1] - self.index_network[0] + else: + i = id_networks - self.index_network[2] + return self.index_network[1][i] - self.index_network[0][i] + def unique_segment_to_id(self, id_unique): + """Return id network and id segment for a unique id + + :param array id_unique: + """ + i = self.index_segment_track[0][id_unique] - self.ref_segment_track_index + return self.track[i], self.segment[i] + + def segment_slice(self, id_network, id_segment): + """ + Return slice for one segment + + :param int id_network: id to identify network + :param int id_segment: id to identify segment + """ + raise Exception('need to be implemented') + def network_slice(self, id_network): """ Return slice for one network @@ -487,6 +538,7 @@ def segment_relative_order(self, seg_origine): """ Compute the relative order of each segment to the chosen segment """ + self.only_one_network() i_s, i_e, i_ref = build_index(self.segment) segment_connexions = self.connexions() relative_tr = -ones(i_s.shape, dtype="i4") @@ -634,7 +686,7 @@ def only_one_network(self): if there are more than one network """ _, i_start, _ = self.index_network - if len(i_start) > 1: + if i_start.size > 1: raise Exception("Several networks") def position_filter(self, median_half_window, loess_half_window): @@ -832,7 +884,7 @@ def map_segment(self, method, y, same=True, **kw): out = empty(y.shape, **kw) else: out = list() - for i, b0, b1 in self.iter_on(self.segment_track_array): + for i, _, _ in self.iter_on(self.segment_track_array): res = method(y[i]) if same: out[i] = res @@ -1025,7 +1077,9 @@ def extract_event(self, indices): @property def segment_track_array(self): """Return a unique segment id when multiple networks are considered""" - return build_unique_array(self.segment, self.track) + if self._segment_track_array is None: + self._segment_track_array = build_unique_array(self.segment, self.track) + return self._segment_track_array def birth_event(self): """Extract birth events. @@ -1081,7 +1135,7 @@ def merging_event(self, triplet=False, only_index=False): if triplet: if only_index: - return (idx_m1, idx_m0, idx_m0_stop) + return array(idx_m1), array(idx_m0), array(idx_m0_stop) else: return ( self.extract_event(idx_m1), @@ -1119,12 +1173,12 @@ def splitting_event(self, triplet=False, only_index=False): if triplet: if only_index: - return (idx_s0, idx_s1, idx_s1_start) + return array(idx_s0), array(idx_s1), array(idx_s1_start) else: return ( - self.extract_event(list(idx_s0)), - self.extract_event(list(idx_s1)), - self.extract_event(list(idx_s1_start)), + self.extract_event(idx_s0), + self.extract_event(idx_s1), + self.extract_event(idx_s1_start), ) else: @@ -1159,14 +1213,108 @@ def dissociate_network(self): self.next_obs[:] = translate[n] self.previous_obs[:] = translate[p] + def network_segment(self, id_network, id_segment): + return self.extract_with_mask(self.segment_slice(id_network, id_segment)) + def network(self, id_network): return self.extract_with_mask(self.network_slice(id_network)) + def networks_mask(self, id_networks, segment=False): + if segment: + return generate_mask_from_ids(id_networks, self.track.size, *self.index_segment_track) + else: + return generate_mask_from_ids(id_networks, self.track.size, *self.index_network) + def networks(self, id_networks): - m = zeros(self.track.shape, dtype=bool) - for tr in id_networks: - m[self.network_slice(tr)] = True - return self.extract_with_mask(m) + return self.extract_with_mask(generate_mask_from_ids(id_networks, self.track.size, *self.index_network)) + + @property + def nb_network(self): + """ + Count and return number of network + """ + return (self.network_size() != 0).sum() + + @property + def nb_segment(self): + """ + Count and return number of segment in all network + """ + return self.index_segment_track[0].size + + def identify_in(self, other, size_min=1, segment=False): + """ + Return couple of segment or network which are equal + + :param other: other atlas to compare + :param int size_min: number of observation in network/segment + :param bool segment: segment mode + """ + if segment: + counts = self.segment_size(), other.segment_size() + i_self_ref, i_other_ref = self.ref_segment_track_index, other.ref_segment_track_index + var_id = 'segment' + else: + counts = self.network_size(), other.network_size() + i_self_ref, i_other_ref = self.ref_index, other.ref_index + var_id = 'track' + # object to contain index of couple + in_self, in_other = list(), list() + # We iterate on item of same size + for i_self, i_other, i0, _ in self.align_on(other, counts, all_ref=True): + if i0 < size_min: + continue + if isinstance(i_other, slice): + i_other = arange(i_other.start, i_other.stop) + # All_ref will give all item of self, sometime there is no things to compare with other + if i_other.size == 0: + id_self = i_self + i_self_ref + in_self.append(id_self) + in_other.append(-ones(id_self.shape, dtype=id_self.dtype)) + continue + if isinstance(i_self, slice): + i_self = arange(i_self.start, i_self.stop) + # We get absolute id + id_self, id_other = i_self + i_self_ref, i_other + i_other_ref + # We compute mask to select data + m_self, m_other = self.networks_mask(id_self, segment), other.networks_mask(id_other, segment) + + # We extract obs + obs_self, obs_other = self.obs[m_self], other.obs[m_other] + x1, y1, t1 = obs_self['lon'], obs_self['lat'], obs_self['time'] + x2, y2, t2 = obs_other['lon'], obs_other['lat'], obs_other['time'] + + if segment: + ids1 = build_unique_array(obs_self['segment'], obs_self['track']) + ids2 = build_unique_array(obs_other['segment'], obs_other['track']) + label1 = self.segment_track_array[m_self] + label2 = other.segment_track_array[m_other] + else: + label1, label2 = ids1, ids2 = obs_self[var_id], obs_other[var_id] + # For each item we get index to sort + i01, indexs1, id1 = list(), List(), list() + for sl_self, id_, _ in self.iter_on(ids1): + i01.append(sl_self.start) + indexs1.append(obs_self[sl_self].argsort(order=['time', 'lon', 'lat'])) + id1.append(label1[sl_self.start]) + i02, indexs2, id2 = list(), List(), list() + for sl_other, _, _ in other.iter_on(ids2): + i02.append(sl_other.start) + indexs2.append(obs_other[sl_other].argsort(order=['time', 'lon', 'lat'])) + id2.append(label2[sl_other.start]) + + id1, id2 = array(id1), array(id2) + # We search item from self in item of others + i_local_target = same_position(x1, y1, t1, x2, y2, t2, array(i01), array(i02), indexs1, indexs2) + + # -1 => no item found in other dataset + m = i_local_target != -1 + in_self.append(id1) + track2_ = -ones(id1.shape, dtype='i4') + track2_[m] = id2[i_local_target[m]] + in_other.append(track2_) + + return concatenate(in_self), concatenate(in_other) @classmethod def __tag_segment(cls, seg, tag, groups, connexions): @@ -1647,6 +1795,27 @@ def date2file(julian_day): ) return itf_final, ptf_final + def mask_obs_close_event(self, merging=True, spliting=True, dt=3): + """Build a mask of close observation from event + + :param n: Network + :param bool merging: select merging event, defaults to True + :param bool spliting: select splitting event, defaults to True + :param int dt: delta of time max , defaults to 3 + :return array: mask + """ + m = zeros(len(self), dtype='bool') + if merging: + i_target, ip1, ip2 = self.merging_event(triplet=True, only_index=True) + mask_follow_obs(m, self.previous_obs, self.time, ip1, dt) + mask_follow_obs(m, self.previous_obs, self.time, ip2, dt) + mask_follow_obs(m, self.next_obs, self.time, i_target, dt) + if spliting: + i_target, in1, in2 = self.splitting_event(triplet=True, only_index=True) + mask_follow_obs(m, self.next_obs, self.time, in1, dt) + mask_follow_obs(m, self.next_obs, self.time, in2, dt) + mask_follow_obs(m, self.previous_obs, self.time, i_target, dt) + return m class Network: __slots__ = ( @@ -1864,3 +2033,77 @@ def new_numbering(segs, start=0): @njit(cache=True) def ptp(values): return values.max() - values.min() + +@njit(cache=True) +def generate_mask_from_ids(id_networks, nb, istart, iend, i0): + """From list of id, we generate a mask + + :param array id_networks: list of ids + :param int nb: size of mask + :param array istart: first index for each id from :py:meth:`~py_eddy_tracker.generic.build_index` + :param array iend: last index for each id from :py:meth:`~py_eddy_tracker.generic.build_index` + :param int i0: ref index from :py:meth:`~py_eddy_tracker.generic.build_index` + :return array: return a mask + """ + m = zeros(nb, dtype='bool') + for i in id_networks: + for j in range(istart[i-i0], iend[i-i0]): + m[j] = True + return m + +@njit(cache=True) +def same_position(x0, y0, t0, x1, y1, t1, i00, i01, i0, i1): + """Return index of track/segment found in other dataset + + :param array x0: + :param array y0: + :param array t0: + :param array x1: + :param array y1: + :param array t1: + :param array i00: First index of track/segment/network in dataset0 + :param array i01: First index of track/segment/network in dataset1 + :param List(array) i0: list of array which contain index to order dataset0 + :param List(array) i1: list of array which contain index to order dataset1 + :return array: index of dataset1 which match with dataset0, -1 => no match + """ + nb0, nb1 = i00.size, i01.size + i_target = -ones(nb0, dtype='i4') + # To avoid to compare multiple time, if already match + used1 = zeros(nb1, dtype='bool') + for j0 in range(nb0): + for j1 in range(nb1): + if used1[j1]: + continue + test = True + for i0_, i1_ in zip(i0[j0], i1[j1]): + i0_ += i00[j0] + i1_ += i01[j1] + if t0[i0_] != t1[i1_] or x0[i0_] != x1[i1_] or y0[i0_] != y1[i1_]: + test = False + break + if test: + i_target[j0] = j1 + used1[j1] = True + break + return i_target + +@njit(cache=True) +def mask_follow_obs(m, next_obs, time, indexs, dt=3): + """Generate a mask to select close obs in time from index + + :param array m: mask to fill with True + :param array next_obs: index of the next observation + :param array time: time of each obs + :param array indexs: index to start follow + :param int dt: delta of time max from index, defaults to 3 + """ + for i in indexs: + t0 = time[i] + m[i] = True + i_next = next_obs[i] + dt_ = abs(time[i_next] - t0) + while dt_ < dt and i_next != -1: + m[i_next] = True + i_next = next_obs[i_next] + dt_ = abs(time[i_next] - t0) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 651aaa9a..384f537f 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -11,6 +11,7 @@ import packaging.version import zarr from matplotlib.cm import get_cmap +from matplotlib.collections import LineCollection from matplotlib.collections import PolyCollection from matplotlib.colors import Normalize from netCDF4 import Dataset @@ -70,7 +71,7 @@ poly_indexs, reduce_size, vertice_overlap, - winding_number_poly, + create_meshed_particles, ) logger = logging.getLogger("pet") @@ -576,12 +577,12 @@ def iter_on(self, xname, bins=None): Yield observation group for each bin. :param str,array xname: - :param array bins: bounds of each bin , - :return: index or mask, bound low, bound up + :param array bins: bounds of each bin + :yield array,float,float: index in self, lower bound, upper bound .. minigallery:: py_eddy_tracker.EddiesObservations.iter_on """ - x = self[xname] if isinstance(xname, str) else xname + x = self.parse_varname(xname) d = x[1:] - x[:-1] if bins is None: bins = arange(x.min(), x.max() + 2) @@ -617,14 +618,23 @@ def iter_on(self, xname, bins=None): i_bins = i[i0_] yield slice(i0_, i1_), bins[i_bins], bins[i_bins + 1] - def align_on(self, other, var_name="time", **kwargs): + def align_on(self, other, var_name="time", all_ref=False, **kwargs): """ - Align the time indices of two datasets. + Align the variable indices of two datasets. + + :param other: other compare with self + :param str,tuple var_name: variable name to align or two array, defaults to "time" + :param bool all_ref: yield all value of ref, if false only common value, defaults to False + :yield array,array,float,float: index in self, index in other, lower bound, upper bound .. minigallery:: py_eddy_tracker.EddiesObservations.align_on """ - iter_self = self.iter_on(var_name, **kwargs) - iter_other = other.iter_on(var_name, **kwargs) + if isinstance(var_name, str): + iter_self = self.iter_on(var_name, **kwargs) + iter_other = other.iter_on(var_name, **kwargs) + else: + iter_self = self.iter_on(var_name[0], **kwargs) + iter_other = other.iter_on(var_name[1], **kwargs) indexs_other, b0_other, b1_other = iter_other.__next__() for indexs_self, b0_self, b1_self in iter_self: if b0_self > b0_other: @@ -634,6 +644,8 @@ def align_on(self, other, var_name="time", **kwargs): except StopIteration: break if b0_self < b0_other: + if all_ref: + yield indexs_self, empty(0, dtype=indexs_self.dtype), b0_self, b1_self continue yield indexs_self, indexs_other, b0_self, b1_self @@ -1057,11 +1069,6 @@ def compare_units(input_unit, output_unit, name): @classmethod def from_array(cls, arrays, **kwargs): nb = arrays["time"].size - # if hasattr(handler, "track_array_variables"): - # kwargs["track_array_variables"] = handler.track_array_variables - # kwargs["array_variables"] = handler.array_variables.split(",") - # if len(handler.track_extra_variables) > 1: - # kwargs["track_extra_variables"] = handler.track_extra_variables.split(",") eddies = cls(size=nb, **kwargs) for k, v in arrays.items(): eddies.obs[k] = v @@ -2036,6 +2043,26 @@ def format_label(self, label): nb_obs=len(self), ) + def display_color(self, ax, field, intern=False, **kwargs): + """Plot colored contour of eddies + + :param matplotlib.axes.Axes ax: matplotlib axe used to draw + :param str,array field: color field + :param bool intern: if True, draw the speed contour + :param dict kwargs: look at :py:meth:`matplotlib.collections.LineCollection` + + .. minigallery:: py_eddy_tracker.EddiesObservations.display_color + """ + xname, yname = self.intern(intern) + x, y = self[xname], self[yname] + c = self.parse_varname(field) + cmap = get_cmap(kwargs.pop('cmap', 'Spectral_r')) + cmin, cmax = kwargs.pop('vmin', c.min()), kwargs.pop('vmax', c.max()) + colors = cmap((c - cmin) / (cmax - cmin)) + lines = LineCollection([create_vertice(i,j) for i,j in zip(x,y)], colors=colors, **kwargs) + ax.add_collection(lines) + return lines + def display(self, ax, ref=None, extern_only=False, intern_only=False, **kwargs): """Plot the speed and effective (dashed) contour of the eddies @@ -2353,7 +2380,7 @@ def create_particles(self, step, intern=True): """ xname, yname = self.intern(intern) - return _create_meshed_particles(self[xname], self[yname], step) + return create_meshed_particles(self[xname], self[yname], step) @njit(cache=True) @@ -2518,24 +2545,6 @@ def grid_stat(x_c, y_c, grid, x, y, result, circular=False, method="mean"): result[elt] = v_max -@njit(cache=True) -def _create_meshed_particles(lons, lats, step): - x_out, y_out, i_out = list(), list(), list() - for i, (lon, lat) in enumerate(zip(lons, lats)): - lon_min, lon_max = lon.min(), lon.max() - lat_min, lat_max = lat.min(), lat.max() - lon_min -= lon_min % step - lon_max -= lon_max % step - step * 2 - lat_min -= lat_min % step - lat_max -= lat_max % step - step * 2 - - for x in arange(lon_min, lon_max, step): - for y in arange(lat_min, lat_max, step): - if winding_number_poly(x, y, create_vertice(*reduce_size(lon, lat))): - x_out.append(x), y_out.append(y), i_out.append(i) - return array(x_out), array(y_out), array(i_out) - - class VirtualEddiesObservations(EddiesObservations): """Class to work with virtual obs""" diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index bb9ac79e..6baf5ad8 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -287,6 +287,27 @@ def close_center(x0, y0, x1, y1, delta=0.1): return array(i), array(j), array(c) +@njit(cache=True) +def create_meshed_particles(lons, lats, step): + x_out, y_out, i_out = list(), list(), list() + nb = lons.shape[0] + for i in range(nb): + lon, lat = lons[i], lats[i] + vertice = create_vertice(*reduce_size(lon, lat)) + lon_min, lon_max = lon.min(), lon.max() + lat_min, lat_max = lat.min(), lat.max() + y0 = lat_min - lat_min % step + x = lon_min - lon_min % step + while x <= lon_max: + y = y0 + while y <= lat_max: + if winding_number_poly(x, y, vertice): + x_out.append(x), y_out.append(y), i_out.append(i) + y += step + x += step + return array(x_out), array(y_out), array(i_out) + + @njit(cache=True, fastmath=True) def bbox_intersection(x0, y0, x1, y1): """ @@ -503,7 +524,7 @@ def fit_circle(x, y): norme = (x[1:] - x_mean) ** 2 + (y[1:] - y_mean) ** 2 norme_max = norme.max() - scale = norme_max ** 0.5 + scale = norme_max**0.5 # Form matrix equation and solve it # Maybe put f4 @@ -514,7 +535,7 @@ def fit_circle(x, y): (x0, y0, radius), _, _, _ = lstsq(datas, norme / norme_max) # Unscale data and get circle variables - radius += x0 ** 2 + y0 ** 2 + radius += x0**2 + y0**2 radius **= 0.5 x0 *= scale y0 *= scale @@ -546,21 +567,21 @@ def fit_ellipse(x, y): """ nb = x.shape[0] datas = ones((nb, 5), dtype=x.dtype) - datas[:, 0] = x ** 2 + datas[:, 0] = x**2 datas[:, 1] = x * y - datas[:, 2] = y ** 2 + datas[:, 2] = y**2 datas[:, 3] = x datas[:, 4] = y (a, b, c, d, e), _, _, _ = lstsq(datas, ones(nb, dtype=x.dtype)) - det = b ** 2 - 4 * a * c + det = b**2 - 4 * a * c if det > 0: print(det) x0 = (2 * c * d - b * e) / det y0 = (2 * a * e - b * d) / det - AB1 = 2 * (a * e ** 2 + c * d ** 2 - b * d * e - det) + AB1 = 2 * (a * e**2 + c * d**2 - b * d * e - det) AB2 = a + c - AB3 = ((a - c) ** 2 + b ** 2) ** 0.5 + AB3 = ((a - c) ** 2 + b**2) ** 0.5 A = -((AB1 * (AB2 + AB3)) ** 0.5) / det B = -((AB1 * (AB2 - AB3)) ** 0.5) / det theta = arctan((c - a - AB3) / b) @@ -621,7 +642,7 @@ def fit_circle_(x, y): # Linear regression (a, b, c), _, _, _ = lstsq(datas, x[1:] ** 2 + y[1:] ** 2) x0, y0 = a / 2.0, b / 2.0 - radius = (c + x0 ** 2 + y0 ** 2) ** 0.5 + radius = (c + x0**2 + y0**2) ** 0.5 err = shape_error(x, y, x0, y0, radius) return x0, y0, radius, err @@ -646,14 +667,14 @@ def shape_error(x, y, x0, y0, r): :rtype: float """ # circle area - c_area = (r ** 2) * pi + c_area = (r**2) * pi p_area = poly_area(x, y) nb = x.shape[0] x, y = x.copy(), y.copy() # Find distance between circle center and polygon for i in range(nb): dx, dy = x[i] - x0, y[i] - y0 - rd = r / (dx ** 2 + dy ** 2) ** 0.5 + rd = r / (dx**2 + dy**2) ** 0.5 if rd < 1: x[i] = x0 + dx * rd y[i] = y0 + dy * rd diff --git a/tests/test_grid.py b/tests/test_grid.py index 759a40e1..0e6dd586 100644 --- a/tests/test_grid.py +++ b/tests/test_grid.py @@ -7,7 +7,15 @@ 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 = Path( + ( + (-X, 0), + (X, 0), + (X, X), + (-X, X), + (-X, 0), + ) +) # contour @@ -91,7 +99,11 @@ def test_convolution(): ) g = RegularGridDataset.with_array( coordinates=("x", "y"), - datas=dict(z=z, x=arange(0, 6, 0.5), y=arange(0, 5, 0.5),), + datas=dict( + z=z, + x=arange(0, 6, 0.5), + y=arange(0, 5, 0.5), + ), centered=True, ) diff --git a/tests/test_poly.py b/tests/test_poly.py index cca53635..a780f64d 100644 --- a/tests/test_poly.py +++ b/tests/test_poly.py @@ -22,7 +22,7 @@ def test_fit_circle(): x0, y0, r, err = fit_circle(*V) assert x0 == approx(2.5, rel=1e-10) assert y0 == approx(-9.5, rel=1e-10) - assert r == approx(2 ** 0.5 / 2, rel=1e-10) + assert r == approx(2**0.5 / 2, rel=1e-10) assert err == approx((1 - 2 / pi) * 100, rel=1e-10) From 1e6d4f4b28b81afd6bc159b496df7853f7b6f445 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Mon, 19 Sep 2022 10:15:47 +0200 Subject: [PATCH 203/249] update changelog --- CHANGELOG.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 57fd7551..b8cad2f4 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -11,6 +11,8 @@ and this project adheres to `Semantic Versioning Date: Mon, 19 Sep 2022 10:15:47 +0200 Subject: [PATCH 204/249] isort/black --- check.sh | 10 +- doc/grid_identification.rst | 43 +++---- doc/grid_load_display.rst | 34 +++--- doc/spectrum.rst | 61 ++++++---- examples/01_general_things/pet_storage.py | 2 +- .../pet_eddy_detection_ACC.py | 16 ++- .../pet_interp_grid_on_dataset.py | 2 +- .../pet_statistics_on_identification.py | 2 +- examples/06_grid_manipulation/pet_lavd.py | 4 +- examples/07_cube_manipulation/pet_cube.py | 3 +- examples/07_cube_manipulation/pet_fsle_med.py | 8 +- .../pet_display_field.py | 2 +- .../pet_display_track.py | 2 +- .../08_tracking_manipulation/pet_one_track.py | 2 +- .../pet_select_track_across_area.py | 2 +- .../pet_track_anim_matplotlib_animation.py | 2 +- .../pet_birth_and_death.py | 2 +- .../pet_center_count.py | 4 +- .../pet_geographic_stats.py | 2 +- .../10_tracking_diagnostics/pet_groups.py | 2 +- examples/10_tracking_diagnostics/pet_histo.py | 2 +- .../10_tracking_diagnostics/pet_lifetime.py | 2 +- .../10_tracking_diagnostics/pet_pixel_used.py | 2 +- .../pet_propagation.py | 2 +- .../12_external_data/pet_drifter_loopers.py | 4 +- examples/14_generic_tools/pet_visvalingam.py | 2 +- examples/16_network/pet_follow_particle.py | 3 +- examples/16_network/pet_group_anim.py | 3 +- examples/16_network/pet_ioannou_2017_case.py | 6 +- .../16_network/pet_replay_segmentation.py | 4 +- examples/16_network/pet_segmentation_anim.py | 2 +- setup.cfg | 15 ++- setup.py | 3 +- share/fig.py | 6 +- src/py_eddy_tracker/__init__.py | 2 +- src/py_eddy_tracker/appli/eddies.py | 5 +- src/py_eddy_tracker/appli/gui.py | 2 +- src/py_eddy_tracker/appli/network.py | 107 +++++++++++------- src/py_eddy_tracker/data/__init__.py | 2 +- src/py_eddy_tracker/dataset/grid.py | 17 +-- src/py_eddy_tracker/eddy_feature.py | 3 +- src/py_eddy_tracker/generic.py | 3 +- src/py_eddy_tracker/gui.py | 4 +- src/py_eddy_tracker/misc.py | 4 +- src/py_eddy_tracker/observations/groups.py | 40 ++++--- src/py_eddy_tracker/observations/network.py | 91 +++++++++------ .../observations/observation.py | 28 ++--- src/py_eddy_tracker/observations/tracking.py | 2 +- src/py_eddy_tracker/poly.py | 5 +- src/py_eddy_tracker/tracking.py | 5 +- src/scripts/EddyTranslate | 2 +- tests/test_track.py | 2 +- 52 files changed, 336 insertions(+), 249 deletions(-) diff --git a/check.sh b/check.sh index b158028a..a402bf52 100644 --- a/check.sh +++ b/check.sh @@ -1,7 +1,5 @@ -isort src tests examples -black src tests examples -blackdoc src tests examples -flake8 tests examples src --count --select=E9,F63,F7,F82 --show-source --statistics -# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide -flake8 tests examples src --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics +isort . +black . +blackdoc . +flake8 . python -m pytest -vv --cov py_eddy_tracker --cov-report html diff --git a/doc/grid_identification.rst b/doc/grid_identification.rst index c645f80c..2cc3fb52 100644 --- a/doc/grid_identification.rst +++ b/doc/grid_identification.rst @@ -47,38 +47,42 @@ Activate verbose .. code-block:: python from py_eddy_tracker import start_logger - start_logger().setLevel('DEBUG') # Available options: ERROR, WARNING, INFO, DEBUG + + start_logger().setLevel("DEBUG") # Available options: ERROR, WARNING, INFO, DEBUG Run identification .. code-block:: python from datetime import datetime + h = RegularGridDataset(grid_name, lon_name, lat_name) - h.bessel_high_filter('adt', 500, order=3) + h.bessel_high_filter("adt", 500, order=3) date = datetime(2019, 2, 23) a, c = h.eddy_identification( - 'adt', 'ugos', 'vgos', # Variables used for identification - date, # Date of identification - 0.002, # step between two isolines of detection (m) - pixel_limit=(5, 2000), # Min and max pixel count for valid contour - shape_error=55, # Error max (%) between ratio of circle fit and contour - ) + "adt", + "ugos", + "vgos", # Variables used for identification + date, # Date of identification + 0.002, # step between two isolines of detection (m) + pixel_limit=(5, 2000), # Min and max pixel count for valid contour + shape_error=55, # Error max (%) between ratio of circle fit and contour + ) Plot the resulting identification .. code-block:: python - fig = plt.figure(figsize=(15,7)) - ax = fig.add_axes([.03,.03,.94,.94]) - ax.set_title('Eddies detected -- Cyclonic(red) and Anticyclonic(blue)') - ax.set_ylim(-75,75) - ax.set_xlim(0,360) - ax.set_aspect('equal') - a.display(ax, color='b', linewidth=.5) - c.display(ax, color='r', linewidth=.5) + fig = plt.figure(figsize=(15, 7)) + ax = fig.add_axes([0.03, 0.03, 0.94, 0.94]) + ax.set_title("Eddies detected -- Cyclonic(red) and Anticyclonic(blue)") + ax.set_ylim(-75, 75) + ax.set_xlim(0, 360) + ax.set_aspect("equal") + a.display(ax, color="b", linewidth=0.5) + c.display(ax, color="r", linewidth=0.5) ax.grid() - fig.savefig('share/png/eddies.png') + fig.savefig("share/png/eddies.png") .. image:: ../share/png/eddies.png @@ -87,7 +91,8 @@ Save identification data .. code-block:: python from netCDF import Dataset - with Dataset(date.strftime('share/Anticyclonic_%Y%m%d.nc'), 'w') as h: + + with Dataset(date.strftime("share/Anticyclonic_%Y%m%d.nc"), "w") as h: a.to_netcdf(h) - with Dataset(date.strftime('share/Cyclonic_%Y%m%d.nc'), 'w') as h: + with Dataset(date.strftime("share/Cyclonic_%Y%m%d.nc"), "w") as h: c.to_netcdf(h) diff --git a/doc/grid_load_display.rst b/doc/grid_load_display.rst index 2e570274..2f0e3765 100644 --- a/doc/grid_load_display.rst +++ b/doc/grid_load_display.rst @@ -7,7 +7,12 @@ Loading grid .. code-block:: python from py_eddy_tracker.dataset.grid import RegularGridDataset - grid_name, lon_name, lat_name = 'share/nrt_global_allsat_phy_l4_20190223_20190226.nc', 'longitude', 'latitude' + + grid_name, lon_name, lat_name = ( + "share/nrt_global_allsat_phy_l4_20190223_20190226.nc", + "longitude", + "latitude", + ) h = RegularGridDataset(grid_name, lon_name, lat_name) Plotting grid @@ -15,14 +20,15 @@ Plotting grid .. code-block:: python from matplotlib import pyplot as plt + fig = plt.figure(figsize=(14, 12)) - ax = fig.add_axes([.02, .51, .9, .45]) - ax.set_title('ADT (m)') + 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.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])) + plt.colorbar(m, cax=fig.add_axes([0.94, 0.51, 0.01, 0.45])) Filtering @@ -30,27 +36,27 @@ Filtering .. code-block:: python h = RegularGridDataset(grid_name, lon_name, lat_name) - h.bessel_high_filter('adt', 500, order=3) + h.bessel_high_filter("adt", 500, order=3) Save grid .. code-block:: python - h.write('/tmp/grid.nc') + h.write("/tmp/grid.nc") Add second plot .. code-block:: python - ax = fig.add_axes([.02, .02, .9, .45]) - ax.set_title('ADT Filtered (m)') - ax.set_aspect('equal') + 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=-.1, vmax=.1) + m = h.display(ax, name="adt", vmin=-0.1, vmax=0.1) ax.grid(True) - plt.colorbar(m, cax=fig.add_axes([.94, .02, .01, .45])) - fig.savefig('share/png/filter.png') + plt.colorbar(m, cax=fig.add_axes([0.94, 0.02, 0.01, 0.45])) + fig.savefig("share/png/filter.png") .. image:: ../share/png/filter.png \ No newline at end of file diff --git a/doc/spectrum.rst b/doc/spectrum.rst index d751b909..5a42cbec 100644 --- a/doc/spectrum.rst +++ b/doc/spectrum.rst @@ -11,7 +11,7 @@ Load data raw = RegularGridDataset(grid_name, lon_name, lat_name) filtered = RegularGridDataset(grid_name, lon_name, lat_name) - filtered.bessel_low_filter('adt', 150, order=3) + filtered.bessel_low_filter("adt", 150, order=3) areas = dict( sud_pacific=dict(llcrnrlon=188, urcrnrlon=280, llcrnrlat=-64, urcrnrlat=-7), @@ -23,24 +23,34 @@ Compute and display spectrum .. code-block:: python - fig = plt.figure(figsize=(10,6)) + fig = plt.figure(figsize=(10, 6)) ax = fig.add_subplot(111) - ax.set_title('Spectrum') - ax.set_xlabel('km') + ax.set_title("Spectrum") + ax.set_xlabel("km") for name_area, area in areas.items(): - lon_spec, lat_spec = raw.spectrum_lonlat('adt', area=area) - mappable = ax.loglog(*lat_spec, label='lat %s raw' % name_area)[0] - ax.loglog(*lon_spec, label='lon %s raw' % name_area, color=mappable.get_color(), linestyle='--') - - lon_spec, lat_spec = filtered.spectrum_lonlat('adt', area=area) - mappable = ax.loglog(*lat_spec, label='lat %s high' % name_area)[0] - ax.loglog(*lon_spec, label='lon %s high' % name_area, color=mappable.get_color(), linestyle='--') - - ax.set_xscale('log') + lon_spec, lat_spec = raw.spectrum_lonlat("adt", area=area) + mappable = ax.loglog(*lat_spec, label="lat %s raw" % name_area)[0] + ax.loglog( + *lon_spec, + label="lon %s raw" % name_area, + color=mappable.get_color(), + linestyle="--" + ) + + lon_spec, lat_spec = filtered.spectrum_lonlat("adt", area=area) + mappable = ax.loglog(*lat_spec, label="lat %s high" % name_area)[0] + ax.loglog( + *lon_spec, + label="lon %s high" % name_area, + color=mappable.get_color(), + linestyle="--" + ) + + ax.set_xscale("log") ax.legend() ax.grid() - fig.savefig('share/png/spectrum.png') + fig.savefig("share/png/spectrum.png") .. image:: ../share/png/spectrum.png @@ -49,18 +59,23 @@ Compute and display spectrum ratio .. code-block:: python - fig = plt.figure(figsize=(10,6)) + fig = plt.figure(figsize=(10, 6)) ax = fig.add_subplot(111) - ax.set_title('Spectrum ratio') - ax.set_xlabel('km') + ax.set_title("Spectrum ratio") + ax.set_xlabel("km") for name_area, area in areas.items(): - lon_spec, lat_spec = filtered.spectrum_lonlat('adt', area=area, ref=raw) - mappable = ax.plot(*lat_spec, label='lat %s high' % name_area)[0] - ax.plot(*lon_spec, label='lon %s high' % name_area, color=mappable.get_color(), linestyle='--') - - ax.set_xscale('log') + lon_spec, lat_spec = filtered.spectrum_lonlat("adt", area=area, ref=raw) + mappable = ax.plot(*lat_spec, label="lat %s high" % name_area)[0] + ax.plot( + *lon_spec, + label="lon %s high" % name_area, + color=mappable.get_color(), + linestyle="--" + ) + + ax.set_xscale("log") ax.legend() ax.grid() - fig.savefig('share/png/spectrum_ratio.png') + fig.savefig("share/png/spectrum_ratio.png") .. image:: ../share/png/spectrum_ratio.png diff --git a/examples/01_general_things/pet_storage.py b/examples/01_general_things/pet_storage.py index ccd01f1c..918ebbee 100644 --- a/examples/01_general_things/pet_storage.py +++ b/examples/01_general_things/pet_storage.py @@ -15,9 +15,9 @@ manage eddies associated in networks, the ```track``` and ```segment``` fields allow to separate observations """ -import py_eddy_tracker_sample from matplotlib import pyplot as plt from numpy import arange, outer +import py_eddy_tracker_sample from py_eddy_tracker.data import get_demo_path from py_eddy_tracker.observations.network import NetworkObservations diff --git a/examples/02_eddy_identification/pet_eddy_detection_ACC.py b/examples/02_eddy_identification/pet_eddy_detection_ACC.py index e6c5e381..3d3d4ac1 100644 --- a/examples/02_eddy_identification/pet_eddy_detection_ACC.py +++ b/examples/02_eddy_identification/pet_eddy_detection_ACC.py @@ -9,8 +9,7 @@ """ from datetime import datetime -from matplotlib import pyplot as plt -from matplotlib import style +from matplotlib import pyplot as plt, style from py_eddy_tracker import data from py_eddy_tracker.dataset.grid import RegularGridDataset @@ -65,7 +64,8 @@ def set_fancy_labels(fig, ticklabelsize=14, labelsize=14, labelweight="semibold" y_name="latitude", # Manual area subset indexs=dict( - latitude=slice(100 - margin, 220 + margin), longitude=slice(0, 230 + margin), + latitude=slice(100 - margin, 220 + margin), + longitude=slice(0, 230 + margin), ), ) g_raw = RegularGridDataset(**kw_data) @@ -187,10 +187,16 @@ def set_fancy_labels(fig, ticklabelsize=14, labelsize=14, labelweight="semibold" ax.set_ylabel("With filter") ax.plot( - a_[field][i_a] * factor, a[field][j_a] * factor, "r.", label="Anticyclonic", + a_[field][i_a] * factor, + a[field][j_a] * factor, + "r.", + label="Anticyclonic", ) ax.plot( - c_[field][i_c] * factor, c[field][j_c] * factor, "b.", label="Cyclonic", + c_[field][i_c] * factor, + c[field][j_c] * factor, + "b.", + label="Cyclonic", ) ax.set_aspect("equal"), ax.grid() ax.plot((0, 1000), (0, 1000), "g") diff --git a/examples/02_eddy_identification/pet_interp_grid_on_dataset.py b/examples/02_eddy_identification/pet_interp_grid_on_dataset.py index f9e5d4c3..fa27a3d1 100644 --- a/examples/02_eddy_identification/pet_interp_grid_on_dataset.py +++ b/examples/02_eddy_identification/pet_interp_grid_on_dataset.py @@ -43,7 +43,7 @@ def update_axes(ax, mappable=None): # %% # 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", (aviso_map.grid("u") ** 2 + aviso_map.grid("v") ** 2) * 0.5 * (100**2) ) eke_kwargs = dict(vmin=1, vmax=1000, cmap="magma_r") diff --git a/examples/02_eddy_identification/pet_statistics_on_identification.py b/examples/02_eddy_identification/pet_statistics_on_identification.py index 0c72262f..dbd73c61 100644 --- a/examples/02_eddy_identification/pet_statistics_on_identification.py +++ b/examples/02_eddy_identification/pet_statistics_on_identification.py @@ -4,9 +4,9 @@ Some statistics on raw identification without any tracking """ -import numpy as np from matplotlib import pyplot as plt from matplotlib.dates import date2num +import numpy as np from py_eddy_tracker import start_logger from py_eddy_tracker.data import get_remote_demo_sample diff --git a/examples/06_grid_manipulation/pet_lavd.py b/examples/06_grid_manipulation/pet_lavd.py index 89d64108..331ace8a 100644 --- a/examples/06_grid_manipulation/pet_lavd.py +++ b/examples/06_grid_manipulation/pet_lavd.py @@ -158,9 +158,7 @@ def update(i_frame): # %% # Format LAVD data lavd = RegularGridDataset.with_array( - coordinates=("lon", "lat"), - datas=dict(lavd=lavd.T, lon=x_g, lat=y_g,), - centered=True, + coordinates=("lon", "lat"), datas=dict(lavd=lavd.T, lon=x_g, lat=y_g), centered=True ) # %% diff --git a/examples/07_cube_manipulation/pet_cube.py b/examples/07_cube_manipulation/pet_cube.py index 7f30c4e1..cba6c85b 100644 --- a/examples/07_cube_manipulation/pet_cube.py +++ b/examples/07_cube_manipulation/pet_cube.py @@ -4,9 +4,10 @@ Example which use CMEMS surface current with a Runge-Kutta 4 algorithm to advect particles. """ +from datetime import datetime, timedelta + # sphinx_gallery_thumbnail_number = 2 import re -from datetime import datetime, timedelta from matplotlib import pyplot as plt from matplotlib.animation import FuncAnimation diff --git a/examples/07_cube_manipulation/pet_fsle_med.py b/examples/07_cube_manipulation/pet_fsle_med.py index b128286a..ef777639 100644 --- a/examples/07_cube_manipulation/pet_fsle_med.py +++ b/examples/07_cube_manipulation/pet_fsle_med.py @@ -49,7 +49,7 @@ 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` """ nb_p = x.shape[0] // 3 - delta = dist_max ** 2 + delta = dist_max**2 for i in range(nb_p): i0 = i * 3 i_n = i0 + 1 @@ -59,10 +59,10 @@ def check_p(x, y, flse, theta, m_set, m, dt, dist_init=0.02, dist_max=0.6): continue # Distance with north dxn, dyn = x[i0] - x[i_n], y[i0] - y[i_n] - dn = dxn ** 2 + dyn ** 2 + dn = dxn**2 + dyn**2 # Distance with east dxe, dye = x[i0] - x[i_e], y[i0] - y[i_e] - de = dxe ** 2 + dye ** 2 + de = dxe**2 + dye**2 if dn >= delta or de >= delta: s1 = dn + de @@ -71,7 +71,7 @@ def check_p(x, y, flse, theta, m_set, m, dt, dist_init=0.02, dist_max=0.6): s2 = ((dxn + dye) ** 2 + (dxe - dyn) ** 2) * ( (dxn - dye) ** 2 + (dxe + dyn) ** 2 ) - flse[i] = 1 / (2 * dt) * log(1 / (2 * dist_init ** 2) * (s1 + s2 ** 0.5)) + flse[i] = 1 / (2 * dt) * log(1 / (2 * dist_init**2) * (s1 + s2**0.5)) theta[i] = arctan2(at1, at2 + s2) * 180 / pi # To know where value are set m_set[i] = False diff --git a/examples/08_tracking_manipulation/pet_display_field.py b/examples/08_tracking_manipulation/pet_display_field.py index 30ad75a6..b943a2ba 100644 --- a/examples/08_tracking_manipulation/pet_display_field.py +++ b/examples/08_tracking_manipulation/pet_display_field.py @@ -4,8 +4,8 @@ """ -import py_eddy_tracker_sample from matplotlib import pyplot as plt +import py_eddy_tracker_sample from py_eddy_tracker.observations.tracking import TrackEddiesObservations diff --git a/examples/08_tracking_manipulation/pet_display_track.py b/examples/08_tracking_manipulation/pet_display_track.py index 13a8d3ad..b15d51d7 100644 --- a/examples/08_tracking_manipulation/pet_display_track.py +++ b/examples/08_tracking_manipulation/pet_display_track.py @@ -4,8 +4,8 @@ """ -import py_eddy_tracker_sample from matplotlib import pyplot as plt +import py_eddy_tracker_sample from py_eddy_tracker.observations.tracking import TrackEddiesObservations diff --git a/examples/08_tracking_manipulation/pet_one_track.py b/examples/08_tracking_manipulation/pet_one_track.py index 9f930281..a2536c34 100644 --- a/examples/08_tracking_manipulation/pet_one_track.py +++ b/examples/08_tracking_manipulation/pet_one_track.py @@ -2,8 +2,8 @@ One Track =================== """ -import py_eddy_tracker_sample from matplotlib import pyplot as plt +import py_eddy_tracker_sample from py_eddy_tracker.observations.tracking import TrackEddiesObservations diff --git a/examples/08_tracking_manipulation/pet_select_track_across_area.py b/examples/08_tracking_manipulation/pet_select_track_across_area.py index b88f37e1..58184e1f 100644 --- a/examples/08_tracking_manipulation/pet_select_track_across_area.py +++ b/examples/08_tracking_manipulation/pet_select_track_across_area.py @@ -3,8 +3,8 @@ ============================ """ -import py_eddy_tracker_sample from matplotlib import pyplot as plt +import py_eddy_tracker_sample from py_eddy_tracker.observations.tracking import TrackEddiesObservations diff --git a/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py b/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py index 81e57e59..b686fd67 100644 --- a/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py +++ b/examples/08_tracking_manipulation/pet_track_anim_matplotlib_animation.py @@ -9,9 +9,9 @@ """ import re -import py_eddy_tracker_sample from matplotlib.animation import FuncAnimation from numpy import arange +import py_eddy_tracker_sample from py_eddy_tracker.appli.gui import Anim from py_eddy_tracker.observations.tracking import TrackEddiesObservations diff --git a/examples/10_tracking_diagnostics/pet_birth_and_death.py b/examples/10_tracking_diagnostics/pet_birth_and_death.py index d917efbd..b67993a2 100644 --- a/examples/10_tracking_diagnostics/pet_birth_and_death.py +++ b/examples/10_tracking_diagnostics/pet_birth_and_death.py @@ -5,8 +5,8 @@ Following figures are based on https://doi.org/10.1016/j.pocean.2011.01.002 """ -import py_eddy_tracker_sample from matplotlib import pyplot as plt +import py_eddy_tracker_sample from py_eddy_tracker.observations.tracking import TrackEddiesObservations diff --git a/examples/10_tracking_diagnostics/pet_center_count.py b/examples/10_tracking_diagnostics/pet_center_count.py index 6d9fa417..77a4dcda 100644 --- a/examples/10_tracking_diagnostics/pet_center_count.py +++ b/examples/10_tracking_diagnostics/pet_center_count.py @@ -5,9 +5,9 @@ Do Geo stat with center and compare with frequency method show: :ref:`sphx_glr_python_module_10_tracking_diagnostics_pet_pixel_used.py` """ -import py_eddy_tracker_sample from matplotlib import pyplot as plt from matplotlib.colors import LogNorm +import py_eddy_tracker_sample from py_eddy_tracker.observations.tracking import TrackEddiesObservations @@ -27,7 +27,7 @@ step = 0.125 bins = ((-10, 37, step), (30, 46, step)) kwargs_pcolormesh = dict( - cmap="terrain_r", vmin=0, vmax=2, factor=1 / (a.nb_days * step ** 2), name="count" + cmap="terrain_r", vmin=0, vmax=2, factor=1 / (a.nb_days * step**2), name="count" ) diff --git a/examples/10_tracking_diagnostics/pet_geographic_stats.py b/examples/10_tracking_diagnostics/pet_geographic_stats.py index d2a7e90d..a2e3f6b5 100644 --- a/examples/10_tracking_diagnostics/pet_geographic_stats.py +++ b/examples/10_tracking_diagnostics/pet_geographic_stats.py @@ -4,8 +4,8 @@ """ -import py_eddy_tracker_sample from matplotlib import pyplot as plt +import py_eddy_tracker_sample from py_eddy_tracker.observations.tracking import TrackEddiesObservations diff --git a/examples/10_tracking_diagnostics/pet_groups.py b/examples/10_tracking_diagnostics/pet_groups.py index f6e800ae..deedcc3f 100644 --- a/examples/10_tracking_diagnostics/pet_groups.py +++ b/examples/10_tracking_diagnostics/pet_groups.py @@ -3,9 +3,9 @@ =================== """ -import py_eddy_tracker_sample from matplotlib import pyplot as plt from numpy import arange, ones, percentile +import py_eddy_tracker_sample from py_eddy_tracker.observations.tracking import TrackEddiesObservations diff --git a/examples/10_tracking_diagnostics/pet_histo.py b/examples/10_tracking_diagnostics/pet_histo.py index b2eff842..abf97c38 100644 --- a/examples/10_tracking_diagnostics/pet_histo.py +++ b/examples/10_tracking_diagnostics/pet_histo.py @@ -3,9 +3,9 @@ =================== """ -import py_eddy_tracker_sample from matplotlib import pyplot as plt from numpy import arange +import py_eddy_tracker_sample from py_eddy_tracker.observations.tracking import TrackEddiesObservations diff --git a/examples/10_tracking_diagnostics/pet_lifetime.py b/examples/10_tracking_diagnostics/pet_lifetime.py index 9f84e790..4e2500fd 100644 --- a/examples/10_tracking_diagnostics/pet_lifetime.py +++ b/examples/10_tracking_diagnostics/pet_lifetime.py @@ -3,9 +3,9 @@ =================== """ -import py_eddy_tracker_sample from matplotlib import pyplot as plt from numpy import arange, ones +import py_eddy_tracker_sample from py_eddy_tracker.observations.tracking import TrackEddiesObservations diff --git a/examples/10_tracking_diagnostics/pet_pixel_used.py b/examples/10_tracking_diagnostics/pet_pixel_used.py index 3907ce19..75a826d6 100644 --- a/examples/10_tracking_diagnostics/pet_pixel_used.py +++ b/examples/10_tracking_diagnostics/pet_pixel_used.py @@ -5,9 +5,9 @@ Do Geo stat with frequency and compare with center count method: :ref:`sphx_glr_python_module_10_tracking_diagnostics_pet_center_count.py` """ -import py_eddy_tracker_sample from matplotlib import pyplot as plt from matplotlib.colors import LogNorm +import py_eddy_tracker_sample from py_eddy_tracker.observations.tracking import TrackEddiesObservations diff --git a/examples/10_tracking_diagnostics/pet_propagation.py b/examples/10_tracking_diagnostics/pet_propagation.py index 6a65a212..e6bc6c1b 100644 --- a/examples/10_tracking_diagnostics/pet_propagation.py +++ b/examples/10_tracking_diagnostics/pet_propagation.py @@ -3,9 +3,9 @@ ===================== """ -import py_eddy_tracker_sample from matplotlib import pyplot as plt from numpy import arange, ones +import py_eddy_tracker_sample from py_eddy_tracker.generic import cumsum_by_track from py_eddy_tracker.observations.tracking import TrackEddiesObservations diff --git a/examples/12_external_data/pet_drifter_loopers.py b/examples/12_external_data/pet_drifter_loopers.py index 92707906..5266db7b 100644 --- a/examples/12_external_data/pet_drifter_loopers.py +++ b/examples/12_external_data/pet_drifter_loopers.py @@ -8,10 +8,10 @@ import re -import numpy as np -import py_eddy_tracker_sample from matplotlib import pyplot as plt from matplotlib.animation import FuncAnimation +import numpy as np +import py_eddy_tracker_sample from py_eddy_tracker import data from py_eddy_tracker.appli.gui import Anim diff --git a/examples/14_generic_tools/pet_visvalingam.py b/examples/14_generic_tools/pet_visvalingam.py index f7b29c10..736e8852 100644 --- a/examples/14_generic_tools/pet_visvalingam.py +++ b/examples/14_generic_tools/pet_visvalingam.py @@ -2,8 +2,8 @@ Visvalingam algorithm ===================== """ -import matplotlib.animation as animation from matplotlib import pyplot as plt +import matplotlib.animation as animation from numba import njit from numpy import array, empty diff --git a/examples/16_network/pet_follow_particle.py b/examples/16_network/pet_follow_particle.py index dbe0753e..21592558 100644 --- a/examples/16_network/pet_follow_particle.py +++ b/examples/16_network/pet_follow_particle.py @@ -5,8 +5,7 @@ """ import re -from matplotlib import colors -from matplotlib import pyplot as plt +from matplotlib import colors, pyplot as plt from matplotlib.animation import FuncAnimation from numpy import arange, meshgrid, ones, unique, zeros diff --git a/examples/16_network/pet_group_anim.py b/examples/16_network/pet_group_anim.py index 047f5820..f2d439ed 100644 --- a/examples/16_network/pet_group_anim.py +++ b/examples/16_network/pet_group_anim.py @@ -2,9 +2,10 @@ Network group process ===================== """ +from datetime import datetime + # sphinx_gallery_thumbnail_number = 2 import re -from datetime import datetime from matplotlib import pyplot as plt from matplotlib.animation import FuncAnimation diff --git a/examples/16_network/pet_ioannou_2017_case.py b/examples/16_network/pet_ioannou_2017_case.py index b02b846a..56bec82e 100644 --- a/examples/16_network/pet_ioannou_2017_case.py +++ b/examples/16_network/pet_ioannou_2017_case.py @@ -6,12 +6,12 @@ We want to find the Ierapetra Eddy described above in a network demonstration run. """ +from datetime import datetime, timedelta + # %% import re -from datetime import datetime, timedelta -from matplotlib import colors -from matplotlib import pyplot as plt +from matplotlib import colors, pyplot as plt from matplotlib.animation import FuncAnimation from matplotlib.ticker import FuncFormatter from numpy import arange, array, pi, where diff --git a/examples/16_network/pet_replay_segmentation.py b/examples/16_network/pet_replay_segmentation.py index d6b4568b..ecb0970d 100644 --- a/examples/16_network/pet_replay_segmentation.py +++ b/examples/16_network/pet_replay_segmentation.py @@ -147,9 +147,9 @@ def get_obs(dataset): ax = timeline_axes() n_.median_filter(15, "time", "latitude") -kw["s"] = (n_.radius_e * 1e-3) ** 2 / 30 ** 2 * 20 +kw["s"] = (n_.radius_e * 1e-3) ** 2 / 30**2 * 20 m = n_.scatter_timeline( - ax, "shape_error_e", vmin=14, vmax=70, **kw, yfield="lon", method="all", + ax, "shape_error_e", vmin=14, vmax=70, **kw, yfield="lon", method="all" ) ax.set_ylabel("Longitude") cb = update_axes(ax, m["scatter"]) diff --git a/examples/16_network/pet_segmentation_anim.py b/examples/16_network/pet_segmentation_anim.py index 58f71188..1fcb9ae1 100644 --- a/examples/16_network/pet_segmentation_anim.py +++ b/examples/16_network/pet_segmentation_anim.py @@ -96,7 +96,7 @@ def update(i_frame): indices_frames = INDICES[i_frame] mappable_CONTOUR.set_data( - e.contour_lon_e[indices_frames], e.contour_lat_e[indices_frames], + e.contour_lon_e[indices_frames], e.contour_lat_e[indices_frames] ) mappable_CONTOUR.set_color(cmap.colors[tr[indices_frames] % len(cmap.colors)]) return (mappable_tracks,) diff --git a/setup.cfg b/setup.cfg index 66f3f495..eb88b6f9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,8 +1,16 @@ + +[yapf] +column_limit = 100 + [flake8] max-line-length = 140 ignore = E203, # whitespace before ':' - W503, # line break before binary operator + W503, # line break before binary operator +exclude= + build + doc + versioneer.py [isort] combine_as_imports=True @@ -14,7 +22,7 @@ line_length=140 multi_line_output=3 skip= build - docs/source/conf.py + doc/conf.py [versioneer] @@ -27,4 +35,5 @@ parentdir_prefix = [tool:pytest] filterwarnings= - ignore:tostring.*is deprecated \ No newline at end of file + ignore:tostring.*is deprecated + diff --git a/setup.py b/setup.py index e0767c10..6b18bcbb 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- +from setuptools import find_packages, setup + import versioneer -from setuptools import setup, find_packages with open("README.md", "r") as fh: long_description = fh.read() diff --git a/share/fig.py b/share/fig.py index 8640abcb..80c7f12b 100644 --- a/share/fig.py +++ b/share/fig.py @@ -1,8 +1,10 @@ -from matplotlib import pyplot as plt -from py_eddy_tracker.dataset.grid import RegularGridDataset from datetime import datetime import logging +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", diff --git a/src/py_eddy_tracker/__init__.py b/src/py_eddy_tracker/__init__.py index f3ecec84..0a98892d 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -20,9 +20,9 @@ """ -import logging from argparse import ArgumentParser from datetime import datetime +import logging import zarr diff --git a/src/py_eddy_tracker/appli/eddies.py b/src/py_eddy_tracker/appli/eddies.py index df4e7d43..c1c7a90d 100644 --- a/src/py_eddy_tracker/appli/eddies.py +++ b/src/py_eddy_tracker/appli/eddies.py @@ -3,12 +3,11 @@ Applications on detection and tracking files """ import argparse -import logging from datetime import datetime from glob import glob +import logging from os import mkdir -from os.path import basename, dirname, exists -from os.path import join as join_path +from os.path import basename, dirname, exists, join as join_path from re import compile as re_compile from netCDF4 import Dataset diff --git a/src/py_eddy_tracker/appli/gui.py b/src/py_eddy_tracker/appli/gui.py index 427db24b..4a8cdeb0 100644 --- a/src/py_eddy_tracker/appli/gui.py +++ b/src/py_eddy_tracker/appli/gui.py @@ -3,9 +3,9 @@ Entry point of graphic user interface """ -import logging from datetime import datetime, timedelta from itertools import chain +import logging from matplotlib import pyplot from matplotlib.animation import FuncAnimation diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index bfe226cc..03c5eb35 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -5,10 +5,11 @@ import logging +from numpy import in1d, zeros + from .. import EddyParser from ..observations.network import Network, NetworkObservations from ..observations.tracking import TrackEddiesObservations -from numpy import in1d, zeros logger = logging.getLogger("pet") @@ -110,7 +111,9 @@ def subset_network(): help="Remove short dead end, first is for minimal obs number and second for minimal segment time to keep", ) parser.add_argument( - "--remove_trash", action="store_true", help="Remove trash (network id == 0)", + "--remove_trash", + action="store_true", + help="Remove trash (network id == 0)", ) parser.add_argument( "-p", @@ -138,7 +141,6 @@ def quick_compare(): - S : segment - Obs : observations """ - ) parser.add_argument("ref", help="Identification file of reference") parser.add_argument("others", nargs="+", help="Identifications files to compare") @@ -148,7 +150,15 @@ def quick_compare(): args = parser.parse_args() kw = dict( - include_vars=['longitude', 'latitude', 'time', 'track', 'segment', 'next_obs', 'previous_obs'] + include_vars=[ + "longitude", + "latitude", + "time", + "track", + "segment", + "next_obs", + "previous_obs", + ] ) if args.path_out is not None: @@ -159,24 +169,26 @@ def quick_compare(): f"[ref] {args.ref} -> {ref.nb_network} network / {ref.nb_segment} segment / {len(ref)} obs " f"-> {ref.network_size(0)} trash obs, " f"{len(ref.merging_event())} merging, {len(ref.splitting_event())} spliting" - ) - others = {other: NetworkObservations.load_file(other, **kw) for other in args.others} - - if args.path_out is not None: - groups_ref, groups_other = run_compare(ref, others, **kwargs) - if not exists(args.path_out): - mkdir(args.path_out) - for i, other_ in enumerate(args.others): - dirname_ = f"{args.path_out}/{other_.replace('/', '_')}/" - if not exists(dirname_): - mkdir(dirname_) - for k, v in groups_other[other_].items(): - basename_ = f"other_{k}.nc" - others[other_].index(v).write_file(filename=f"{dirname_}/{basename_}") - for k, v in groups_ref[other_].items(): - basename_ = f"ref_{k}.nc" - ref.index(v).write_file(filename=f"{dirname_}/{basename_}") - return + ) + others = { + other: NetworkObservations.load_file(other, **kw) for other in args.others + } + + # if args.path_out is not None: + # groups_ref, groups_other = run_compare(ref, others, **kwargs) + # if not exists(args.path_out): + # mkdir(args.path_out) + # for i, other_ in enumerate(args.others): + # dirname_ = f"{args.path_out}/{other_.replace('/', '_')}/" + # if not exists(dirname_): + # mkdir(dirname_) + # for k, v in groups_other[other_].items(): + # basename_ = f"other_{k}.nc" + # others[other_].index(v).write_file(filename=f"{dirname_}/{basename_}") + # for k, v in groups_ref[other_].items(): + # basename_ = f"ref_{k}.nc" + # ref.index(v).write_file(filename=f"{dirname_}/{basename_}") + # return display_compare(ref, others) @@ -188,33 +200,43 @@ def run_compare(ref, others): f"[{i}] {k} -> {other.nb_network} network / {other.nb_segment} segment / {len(other)} obs " f"-> {other.network_size(0)} trash obs, " f"{len(other.merging_event())} merging, {len(other.splitting_event())} spliting" - ) + ) ref_id, other_id = ref.identify_in(other, size_min=2) m = other_id != -1 ref_id, other_id = ref_id[m], other_id[m] - out['same N(N)'] = m.sum() - out['same N(Obs)'] = ref.network_size(ref_id).sum() + out["same N(N)"] = m.sum() + out["same N(Obs)"] = ref.network_size(ref_id).sum() # For network which have same obs ref_, other_ = ref.networks(ref_id), other.networks(other_id) ref_segu, other_segu = ref_.identify_in(other_, segment=True) - m = other_segu==-1 + m = other_segu == -1 ref_track_no_match, _ = ref_.unique_segment_to_id(ref_segu[m]) ref_segu, other_segu = ref_segu[~m], other_segu[~m] m = ~in1d(ref_id, ref_track_no_match) - out['same NS(N)'] = m.sum() - out['same NS(Obs)'] = ref.network_size(ref_id[m]).sum() + out["same NS(N)"] = m.sum() + out["same NS(Obs)"] = ref.network_size(ref_id[m]).sum() # Check merge/split def follow_obs(d, i_follow): m = i_follow != -1 i_follow = i_follow[m] - t, x, y = zeros(m.size, d.time.dtype), zeros(m.size, d.longitude.dtype), zeros(m.size, d.latitude.dtype) - t[m], x[m], y[m] = d.time[i_follow], d.longitude[i_follow], d.latitude[i_follow] + t, x, y = ( + zeros(m.size, d.time.dtype), + zeros(m.size, d.longitude.dtype), + zeros(m.size, d.latitude.dtype), + ) + t[m], x[m], y[m] = ( + d.time[i_follow], + d.longitude[i_follow], + d.latitude[i_follow], + ) return t, x, y + def next_obs(d, i_seg): last_i = d.index_segment_track[1][i_seg] - 1 return follow_obs(d, d.next_obs[last_i]) + def previous_obs(d, i_seg): first_i = d.index_segment_track[0][i_seg] return follow_obs(d, d.previous_obs[first_i]) @@ -222,25 +244,24 @@ def previous_obs(d, i_seg): tref, xref, yref = next_obs(ref_, ref_segu) tother, xother, yother = next_obs(other_, other_segu) - m = (tref == tother) & (xref == xother) & (yref == yother) + m = (tref == tother) & (xref == xother) & (yref == yother) print(m.sum(), m.size, ref_segu.size, ref_track_no_match.size) tref, xref, yref = previous_obs(ref_, ref_segu) tother, xother, yother = previous_obs(other_, other_segu) - m = (tref == tother) & (xref == xother) & (yref == yother) + m = (tref == tother) & (xref == xother) & (yref == yother) print(m.sum(), m.size, ref_segu.size, ref_track_no_match.size) - - ref_segu, other_segu = ref.identify_in(other, segment=True) m = other_segu != -1 - out['same S(S)'] = m.sum() - out['same S(Obs)'] = ref.segment_size()[ref_segu[m]].sum() + out["same S(S)"] = m.sum() + out["same S(Obs)"] = ref.segment_size()[ref_segu[m]].sum() outs[k] = out return outs + def display_compare(ref, others): def display(value, ref=None): if ref: @@ -248,16 +269,16 @@ def display(value, ref=None): else: outs = value return "".join([f"{v:^18}" for v in outs]) - + datas = run_compare(ref, others) ref_ = { - 'same N(N)' : ref.nb_network, + "same N(N)": ref.nb_network, "same N(Obs)": len(ref), - 'same NS(N)' : ref.nb_network, - 'same NS(Obs)' : len(ref), - 'same S(S)' : ref.nb_segment, - 'same S(Obs)' : len(ref), - } + "same NS(N)": ref.nb_network, + "same NS(Obs)": len(ref), + "same S(S)": ref.nb_segment, + "same S(Obs)": len(ref), + } print(" ", display(ref_.keys())) for i, (_, v) in enumerate(datas.items()): print(f"[{i:2}] ", display(v, ref=ref_)) diff --git a/src/py_eddy_tracker/data/__init__.py b/src/py_eddy_tracker/data/__init__.py index 4702af8f..f14fee87 100644 --- a/src/py_eddy_tracker/data/__init__.py +++ b/src/py_eddy_tracker/data/__init__.py @@ -10,8 +10,8 @@ """ import io import lzma -import tarfile from os import path +import tarfile import requests diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 24b1e25b..1cf871a7 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -2,14 +2,13 @@ """ Class to load and manipulate RegularGrid and UnRegularGrid """ -import logging from datetime import datetime +import logging from cv2 import filter2D from matplotlib.path import Path as BasePath from netCDF4 import Dataset -from numba import njit, prange -from numba import types as numba_types +from numba import njit, prange, types as numba_types from numpy import ( arange, array, @@ -28,9 +27,7 @@ isnan, linspace, ma, -) -from numpy import mean as np_mean -from numpy import ( + mean as np_mean, meshgrid, nan, nanmean, @@ -2299,14 +2296,18 @@ def from_netcdf_cube(cls, filename, x_name, y_name, t_name, heigth=None, **kwarg new = cls() with Dataset(filename) as h: for i, t in enumerate(h.variables[t_name][:]): - d = RegularGridDataset(filename, x_name, y_name, indexs={t_name: i}, **kwargs) + d = RegularGridDataset( + filename, x_name, y_name, indexs={t_name: i}, **kwargs + ) if heigth is not None: d.add_uv(heigth) new.datasets.append((t, d)) return new @classmethod - def from_netcdf_list(cls, filenames, t, x_name, y_name, indexs=None, heigth=None, **kwargs): + def from_netcdf_list( + cls, filenames, t, x_name, y_name, indexs=None, heigth=None, **kwargs + ): new = cls() for i, _t in enumerate(t): filename = filenames[i] diff --git a/src/py_eddy_tracker/eddy_feature.py b/src/py_eddy_tracker/eddy_feature.py index 0f13eb2a..8bc139ab 100644 --- a/src/py_eddy_tracker/eddy_feature.py +++ b/src/py_eddy_tracker/eddy_feature.py @@ -8,8 +8,7 @@ from matplotlib.cm import get_cmap from matplotlib.colors import Normalize from matplotlib.figure import Figure -from numba import njit -from numba import types as numba_types +from numba import njit, types as numba_types from numpy import ( array, concatenate, diff --git a/src/py_eddy_tracker/generic.py b/src/py_eddy_tracker/generic.py index c2d7de8a..7dbbf3c3 100644 --- a/src/py_eddy_tracker/generic.py +++ b/src/py_eddy_tracker/generic.py @@ -3,8 +3,7 @@ Tool method which use mostly numba """ -from numba import njit, prange -from numba import types as numba_types +from numba import njit, prange, types as numba_types from numpy import ( absolute, arcsin, diff --git a/src/py_eddy_tracker/gui.py b/src/py_eddy_tracker/gui.py index 0f310467..a85e9c18 100644 --- a/src/py_eddy_tracker/gui.py +++ b/src/py_eddy_tracker/gui.py @@ -3,12 +3,12 @@ GUI class """ -import logging from datetime import datetime, timedelta +import logging +from matplotlib.projections import register_projection import matplotlib.pyplot as plt import numpy as np -from matplotlib.projections import register_projection from .generic import flatten_line_matrix, split_line diff --git a/src/py_eddy_tracker/misc.py b/src/py_eddy_tracker/misc.py index eb0dc5d1..647bfba3 100644 --- a/src/py_eddy_tracker/misc.py +++ b/src/py_eddy_tracker/misc.py @@ -1,6 +1,8 @@ import re + from matplotlib.animation import FuncAnimation + class VideoAnimation(FuncAnimation): def _repr_html_(self, *args, **kwargs): """To get video in html and have a player""" @@ -16,4 +18,4 @@ def save(self, *args, **kwargs): with open(args[0], "w") as _: pass return - return super().save(*args, **kwargs) \ No newline at end of file + return super().save(*args, **kwargs) diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index 66574407..121ffa29 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -1,14 +1,12 @@ -import logging from abc import ABC, abstractmethod +import logging -from numba import njit -from numba import types as nb_types -from numpy import arange, int32, interp, median, where, zeros, full, isnan - -from .observation import EddiesObservations +from numba import njit, types as nb_types +from numpy import arange, full, int32, interp, isnan, median, where, zeros from ..generic import window_index from ..poly import create_meshed_particles, poly_indexs +from .observation import EddiesObservations logger = logging.getLogger("pet") @@ -69,7 +67,7 @@ def get_missing_indices( return indices -def advect(x, y, c, t0, n_days, u_name='u', v_name='v'): +def advect(x, y, c, t0, n_days, u_name="u", v_name="v"): """ Advect particles from t0 to t0 + n_days, with data cube. @@ -92,7 +90,9 @@ def advect(x, y, c, t0, n_days, u_name='u', v_name='v'): return t, x, y -def particle_candidate_step(t_start, contours_start, contours_end, space_step, dt, c, **kwargs): +def particle_candidate_step( + t_start, contours_start, contours_end, space_step, dt, c, **kwargs +): """Select particles within eddies, advect them, return target observation and associated percentages. For one time step. @@ -122,7 +122,7 @@ def particle_candidate_step(t_start, contours_start, contours_end, space_step, d i_target, pct_target = full(shape, -1, dtype="i4"), zeros(shape, dtype="f8") nb_end = contours_end[0].shape[0] get_targets(i_start, i_end, i_target, pct_target, nb_end) - return i_target, pct_target.astype('i1') + return i_target, pct_target.astype("i1") def particle_candidate( @@ -217,6 +217,7 @@ def get_targets(i_start, i_end, i_target, pct, nb_end): pct[i, 1] = pct_ i_target[i, 1] = j + @njit(cache=True) def get_matrix(i_start, i_end, translate_start, translate_end, i_target, pct): """Compute target observation and associated percentages @@ -346,7 +347,9 @@ def keep_tracks_by_date(self, date, nb_days): return self.extract_with_mask(mask) - def particle_candidate_atlas(self, cube, space_step, dt, start_intern=False, end_intern=False, **kwargs): + def particle_candidate_atlas( + self, cube, space_step, dt, start_intern=False, end_intern=False, **kwargs + ): """Select particles within eddies, advect them, return target observation and associated percentages :param `~py_eddy_tracker.dataset.grid.GridCollection` cube: GridCollection with speed for particles @@ -359,7 +362,9 @@ def particle_candidate_atlas(self, cube, space_step, dt, start_intern=False, end """ t_start, t_end = int(self.period[0]), int(self.period[1]) # Pre-compute to get time index - i_sort, i_start, i_end = window_index(self.time, arange(t_start, t_end + 1), .5) + i_sort, i_start, i_end = window_index( + self.time, arange(t_start, t_end + 1), 0.5 + ) # Out shape shape = (len(self), 2) i_target, pct = full(shape, -1, dtype="i4"), zeros(shape, dtype="i1") @@ -368,19 +373,20 @@ def particle_candidate_atlas(self, cube, space_step, dt, start_intern=False, end for t in times: # Get index for origin i = t - t_start - indexs0 = i_sort[i_start[i]:i_end[i]] + indexs0 = i_sort[i_start[i] : i_end[i]] # Get index for end i = t + dt - t_start - indexs1 = i_sort[i_start[i]:i_end[i]] + indexs1 = i_sort[i_start[i] : i_end[i]] # Get contour data contours0 = [self[label][indexs0] for label in self.intern(start_intern)] contours1 = [self[label][indexs1] for label in self.intern(end_intern)] # Get local result - i_target_, pct_ = particle_candidate_step(t, contours0, contours1, space_step, dt, cube, **kwargs) + i_target_, pct_ = particle_candidate_step( + t, contours0, contours1, space_step, dt, cube, **kwargs + ) # Merge result m = i_target_ != -1 i_target_[m] = indexs1[i_target_[m]] - i_target[indexs0] = i_target_ - pct[indexs0] = pct_ + i_target[indexs0] = i_target_ + pct[indexs0] = pct_ return i_target, pct - \ No newline at end of file diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index b633fc40..661144e7 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -2,14 +2,13 @@ """ Class to create network of observations """ +from glob import glob import logging import time -from glob import glob import netCDF4 -import zarr -from numba.typed import List from numba import njit +from numba.typed import List from numpy import ( arange, array, @@ -25,6 +24,7 @@ where, zeros, ) +import zarr from ..dataset.grid import GridCollection from ..generic import build_index, wrap_longitude @@ -188,7 +188,7 @@ def network_segment_size(self, id_networks=None): """ i0, i1, ref = build_index(self.track[self.index_segment_track[0]]) if id_networks is None: - return i1-i0 + return i1 - i0 else: i = id_networks - ref return i1[i] - i0[i] @@ -204,7 +204,7 @@ def network_size(self, id_networks=None): else: i = id_networks - self.index_network[2] return self.index_network[1][i] - self.index_network[0][i] - + def unique_segment_to_id(self, id_unique): """Return id network and id segment for a unique id @@ -220,7 +220,7 @@ def segment_slice(self, id_network, id_segment): :param int id_network: id to identify network :param int id_segment: id to identify segment """ - raise Exception('need to be implemented') + raise Exception("need to be implemented") def network_slice(self, id_network): """ @@ -1221,12 +1221,18 @@ def network(self, id_network): def networks_mask(self, id_networks, segment=False): if segment: - return generate_mask_from_ids(id_networks, self.track.size, *self.index_segment_track) + return generate_mask_from_ids( + id_networks, self.track.size, *self.index_segment_track + ) else: - return generate_mask_from_ids(id_networks, self.track.size, *self.index_network) + return generate_mask_from_ids( + id_networks, self.track.size, *self.index_network + ) def networks(self, id_networks): - return self.extract_with_mask(generate_mask_from_ids(id_networks, self.track.size, *self.index_network)) + return self.extract_with_mask( + generate_mask_from_ids(id_networks, self.track.size, *self.index_network) + ) @property def nb_network(self): @@ -1234,7 +1240,7 @@ def nb_network(self): Count and return number of network """ return (self.network_size() != 0).sum() - + @property def nb_segment(self): """ @@ -1252,15 +1258,18 @@ def identify_in(self, other, size_min=1, segment=False): """ if segment: counts = self.segment_size(), other.segment_size() - i_self_ref, i_other_ref = self.ref_segment_track_index, other.ref_segment_track_index - var_id = 'segment' + i_self_ref, i_other_ref = ( + self.ref_segment_track_index, + other.ref_segment_track_index, + ) + var_id = "segment" else: counts = self.network_size(), other.network_size() i_self_ref, i_other_ref = self.ref_index, other.ref_index - var_id = 'track' + var_id = "track" # object to contain index of couple - in_self, in_other = list(), list() - # We iterate on item of same size + in_self, in_other = list(), list() + # We iterate on item of same size for i_self, i_other, i0, _ in self.align_on(other, counts, all_ref=True): if i0 < size_min: continue @@ -1277,16 +1286,18 @@ def identify_in(self, other, size_min=1, segment=False): # We get absolute id id_self, id_other = i_self + i_self_ref, i_other + i_other_ref # We compute mask to select data - m_self, m_other = self.networks_mask(id_self, segment), other.networks_mask(id_other, segment) + m_self, m_other = self.networks_mask(id_self, segment), other.networks_mask( + id_other, segment + ) # We extract obs obs_self, obs_other = self.obs[m_self], other.obs[m_other] - x1, y1, t1 = obs_self['lon'], obs_self['lat'], obs_self['time'] - x2, y2, t2 = obs_other['lon'], obs_other['lat'], obs_other['time'] + x1, y1, t1 = obs_self["lon"], obs_self["lat"], obs_self["time"] + x2, y2, t2 = obs_other["lon"], obs_other["lat"], obs_other["time"] if segment: - ids1 = build_unique_array(obs_self['segment'], obs_self['track']) - ids2 = build_unique_array(obs_other['segment'], obs_other['track']) + ids1 = build_unique_array(obs_self["segment"], obs_self["track"]) + ids2 = build_unique_array(obs_other["segment"], obs_other["track"]) label1 = self.segment_track_array[m_self] label2 = other.segment_track_array[m_other] else: @@ -1295,22 +1306,26 @@ def identify_in(self, other, size_min=1, segment=False): i01, indexs1, id1 = list(), List(), list() for sl_self, id_, _ in self.iter_on(ids1): i01.append(sl_self.start) - indexs1.append(obs_self[sl_self].argsort(order=['time', 'lon', 'lat'])) + indexs1.append(obs_self[sl_self].argsort(order=["time", "lon", "lat"])) id1.append(label1[sl_self.start]) i02, indexs2, id2 = list(), List(), list() for sl_other, _, _ in other.iter_on(ids2): i02.append(sl_other.start) - indexs2.append(obs_other[sl_other].argsort(order=['time', 'lon', 'lat'])) + indexs2.append( + obs_other[sl_other].argsort(order=["time", "lon", "lat"]) + ) id2.append(label2[sl_other.start]) id1, id2 = array(id1), array(id2) # We search item from self in item of others - i_local_target = same_position(x1, y1, t1, x2, y2, t2, array(i01), array(i02), indexs1, indexs2) + i_local_target = same_position( + x1, y1, t1, x2, y2, t2, array(i01), array(i02), indexs1, indexs2 + ) # -1 => no item found in other dataset m = i_local_target != -1 in_self.append(id1) - track2_ = -ones(id1.shape, dtype='i4') + track2_ = -ones(id1.shape, dtype="i4") track2_[m] = id2[i_local_target[m]] in_other.append(track2_) @@ -1804,7 +1819,7 @@ def mask_obs_close_event(self, merging=True, spliting=True, dt=3): :param int dt: delta of time max , defaults to 3 :return array: mask """ - m = zeros(len(self), dtype='bool') + m = zeros(len(self), dtype="bool") if merging: i_target, ip1, ip2 = self.merging_event(triplet=True, only_index=True) mask_follow_obs(m, self.previous_obs, self.time, ip1, dt) @@ -1817,6 +1832,7 @@ def mask_obs_close_event(self, merging=True, spliting=True, dt=3): mask_follow_obs(m, self.previous_obs, self.time, i_target, dt) return m + class Network: __slots__ = ( "window", @@ -2034,6 +2050,7 @@ def new_numbering(segs, start=0): def ptp(values): return values.max() - values.min() + @njit(cache=True) def generate_mask_from_ids(id_networks, nb, istart, iend, i0): """From list of id, we generate a mask @@ -2045,22 +2062,23 @@ def generate_mask_from_ids(id_networks, nb, istart, iend, i0): :param int i0: ref index from :py:meth:`~py_eddy_tracker.generic.build_index` :return array: return a mask """ - m = zeros(nb, dtype='bool') + m = zeros(nb, dtype="bool") for i in id_networks: - for j in range(istart[i-i0], iend[i-i0]): + for j in range(istart[i - i0], iend[i - i0]): m[j] = True return m + @njit(cache=True) def same_position(x0, y0, t0, x1, y1, t1, i00, i01, i0, i1): """Return index of track/segment found in other dataset - :param array x0: - :param array y0: - :param array t0: - :param array x1: - :param array y1: - :param array t1: + :param array x0: + :param array y0: + :param array t0: + :param array x1: + :param array y1: + :param array t1: :param array i00: First index of track/segment/network in dataset0 :param array i01: First index of track/segment/network in dataset1 :param List(array) i0: list of array which contain index to order dataset0 @@ -2068,9 +2086,9 @@ def same_position(x0, y0, t0, x1, y1, t1, i00, i01, i0, i1): :return array: index of dataset1 which match with dataset0, -1 => no match """ nb0, nb1 = i00.size, i01.size - i_target = -ones(nb0, dtype='i4') + i_target = -ones(nb0, dtype="i4") # To avoid to compare multiple time, if already match - used1 = zeros(nb1, dtype='bool') + used1 = zeros(nb1, dtype="bool") for j0 in range(nb0): for j1 in range(nb1): if used1[j1]: @@ -2085,9 +2103,10 @@ def same_position(x0, y0, t0, x1, y1, t1, i00, i01, i0, i1): if test: i_target[j0] = j1 used1[j1] = True - break + break return i_target + @njit(cache=True) def mask_follow_obs(m, next_obs, time, indexs, dt=3): """Generate a mask to select close obs in time from index diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 384f537f..c2ff4fdb 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -2,21 +2,18 @@ """ Base class to manage eddy observation """ -import logging from datetime import datetime from io import BufferedReader, BytesIO +import logging from tarfile import ExFileObject from tokenize import TokenError -import packaging.version -import zarr +from Polygon import Polygon from matplotlib.cm import get_cmap -from matplotlib.collections import LineCollection -from matplotlib.collections import PolyCollection +from matplotlib.collections import LineCollection, PolyCollection from matplotlib.colors import Normalize from netCDF4 import Dataset -from numba import njit -from numba import types as numba_types +from numba import njit, types as numba_types from numpy import ( absolute, arange, @@ -45,9 +42,10 @@ where, zeros, ) +import packaging.version from pint import UnitRegistry from pint.errors import UndefinedUnitError -from Polygon import Polygon +import zarr from .. import VAR_DESCR, VAR_DESCR_inv, __version__ from ..generic import ( @@ -65,13 +63,13 @@ bbox_intersection, close_center, convexs, + create_meshed_particles, create_vertice, get_pixel_in_regular, insidepoly, poly_indexs, reduce_size, vertice_overlap, - create_meshed_particles, ) logger = logging.getLogger("pet") @@ -645,7 +643,9 @@ def align_on(self, other, var_name="time", all_ref=False, **kwargs): break if b0_self < b0_other: if all_ref: - yield indexs_self, empty(0, dtype=indexs_self.dtype), b0_self, b1_self + yield indexs_self, empty( + 0, dtype=indexs_self.dtype + ), b0_self, b1_self continue yield indexs_self, indexs_other, b0_self, b1_self @@ -2056,10 +2056,12 @@ def display_color(self, ax, field, intern=False, **kwargs): xname, yname = self.intern(intern) x, y = self[xname], self[yname] c = self.parse_varname(field) - cmap = get_cmap(kwargs.pop('cmap', 'Spectral_r')) - cmin, cmax = kwargs.pop('vmin', c.min()), kwargs.pop('vmax', c.max()) + cmap = get_cmap(kwargs.pop("cmap", "Spectral_r")) + cmin, cmax = kwargs.pop("vmin", c.min()), kwargs.pop("vmax", c.max()) colors = cmap((c - cmin) / (cmax - cmin)) - lines = LineCollection([create_vertice(i,j) for i,j in zip(x,y)], colors=colors, **kwargs) + lines = LineCollection( + [create_vertice(i, j) for i, j in zip(x, y)], colors=colors, **kwargs + ) ax.add_collection(lines) return lines diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index 7680961c..993e30f9 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -2,8 +2,8 @@ """ Class to manage observations gathered in trajectories """ -import logging from datetime import datetime, timedelta +import logging from numba import njit from numpy import ( diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index 6baf5ad8..6adb02c1 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -5,11 +5,10 @@ import heapq -from numba import njit, prange -from numba import types as numba_types +from Polygon import Polygon +from numba import njit, prange, types as numba_types from numpy import arctan, array, concatenate, empty, nan, ones, pi, where, zeros from numpy.linalg import lstsq -from Polygon import Polygon from .generic import build_index diff --git a/src/py_eddy_tracker/tracking.py b/src/py_eddy_tracker/tracking.py index 7543a4d3..02068962 100644 --- a/src/py_eddy_tracker/tracking.py +++ b/src/py_eddy_tracker/tracking.py @@ -3,14 +3,13 @@ Class to store link between observations """ +from datetime import datetime, timedelta import json import logging import platform -from datetime import datetime, timedelta from netCDF4 import Dataset, default_fillvals -from numba import njit -from numba import types as numba_types +from numba import njit, types as numba_types from numpy import ( arange, array, diff --git a/src/scripts/EddyTranslate b/src/scripts/EddyTranslate index 26ab3a7b..a0060e9b 100644 --- a/src/scripts/EddyTranslate +++ b/src/scripts/EddyTranslate @@ -3,8 +3,8 @@ """ Translate eddy Dataset """ -import zarr from netCDF4 import Dataset +import zarr from py_eddy_tracker import EddyParser from py_eddy_tracker.observations.observation import EddiesObservations diff --git a/tests/test_track.py b/tests/test_track.py index 4f362a26..f7e83786 100644 --- a/tests/test_track.py +++ b/tests/test_track.py @@ -1,5 +1,5 @@ -import zarr from netCDF4 import Dataset +import zarr from py_eddy_tracker.data import get_demo_path from py_eddy_tracker.featured_tracking.area_tracker import AreaTracker From e31d0a73b56438df9c7fd990db91c1e930f392ca Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Mon, 26 Sep 2022 17:42:29 +0200 Subject: [PATCH 205/249] add option to choose time step in particle candidate --- src/py_eddy_tracker/observations/groups.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index 121ffa29..710557f7 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -91,7 +91,7 @@ def advect(x, y, c, t0, n_days, u_name="u", v_name="v"): def particle_candidate_step( - t_start, contours_start, contours_end, space_step, dt, c, **kwargs + t_start, contours_start, contours_end, space_step, dt, c, day_fraction=6, **kwargs ): """Select particles within eddies, advect them, return target observation and associated percentages. For one time step. @@ -102,13 +102,17 @@ def particle_candidate_step( :param float space_step: step between 2 particles :param int dt: duration of advection :param `~py_eddy_tracker.dataset.grid.GridCollection` c: GridCollection with speed for particles + :param int day_fraction: fraction of day :params dict kwargs: dict of params given to advection :return (np.array,np.array): return target index and percent associate """ + # In case of zarr array + contours_start = [i[:] for i in contours_start] + contours_end = [i[:] for i in contours_end] # Create particles in start contour x, y, i_start = create_meshed_particles(*contours_start, space_step) # Advect particles - kw = dict(nb_step=6, time_step=86400 / 6) + kw = dict(nb_step=day_fraction, time_step=86400 / day_fraction) p = c.advect(x, y, t_init=t_start, **kwargs, **kw) for _ in range(dt): _, x, y = p.__next__() From abd4433c895ec2aa712c8b41e996785bfc41ffa1 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Tue, 27 Sep 2022 10:32:17 +0200 Subject: [PATCH 206/249] -lazy cube management -event statistics --- src/py_eddy_tracker/dataset/grid.py | 59 +++++++++++---- src/py_eddy_tracker/observations/groups.py | 71 +++++++++++++++---- src/py_eddy_tracker/observations/network.py | 68 +++++++++++++++++- .../observations/observation.py | 25 +++++++ 4 files changed, 194 insertions(+), 29 deletions(-) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 1cf871a7..c73f99d9 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -304,14 +304,26 @@ def __init__( "We assume pixel position of grid is centered for %s", filename ) if not unset: - self.load_general_features() - self.load() + self.populate() def populate(self): if self.dimensions is None: self.load_general_features() self.load() + def clean(self): + self.dimensions = None + self.variables_description = None + self.global_attrs = None + self.x_c = None + self.y_c = None + self.x_bounds = None + self.y_bounds = None + self.x_dim = None + self.y_dim = None + self.contours = None + self.vars = dict() + @property def is_centered(self): """Give True if pixel is described with its center's position or @@ -429,7 +441,7 @@ def c_to_bounds(c): def setup_coordinates(self): x_name, y_name = self.coordinates if self.is_centered: - logger.info("Grid center") + # logger.info("Grid center") self.x_c = self.vars[x_name].astype("float64") self.y_c = self.vars[y_name].astype("float64") @@ -1968,14 +1980,21 @@ def interp(self, grid_name, lons, lats, method="bilinear"): self.x_c, self.y_c, g, m, lons, lats, nearest=method == "nearest" ) - def uv_for_advection(self, u_name, v_name, time_step=600, backward=False, factor=1): + def uv_for_advection(self, u_name=None, v_name=None, time_step=600, h_name=None, backward=False, factor=1): """ Get U,V to be used in degrees with precomputed time step - :param str,array u_name: U field to advect obs - :param str,array v_name: V field to advect obs + :param None,str,array u_name: U field to advect obs, if h_name is None + :param None,str,array v_name: V field to advect obs, if h_name is None + :param None,str,array h_name: H field to compute UV to advect obs, if u_name and v_name are None :param int time_step: Number of second for each advection """ + if h_name is not None: + u_name, v_name = 'u', 'v' + if u_name not in self.vars: + self.add_uv(h_name) + self.vars.pop(h_name, None) + u = (self.grid(u_name) if isinstance(u_name, str) else u_name).copy() v = (self.grid(v_name) if isinstance(v_name, str) else v_name).copy() # N seconds / 1 degrees in m @@ -2318,6 +2337,14 @@ def from_netcdf_list( new.datasets.append((_t, d)) return new + @property + def are_loaded(self): + return ~array([d.dimensions is None for _, d in self.datasets]) + + def __repr__(self): + nb_dataset = len(self.datasets) + return f"{self.are_loaded.sum()}/{nb_dataset} datasets loaded" + def shift_files(self, t, filename, heigth=None, **rgd_kwargs): """Add next file to the list and remove the oldest""" @@ -2440,17 +2467,23 @@ def filament( t += dt yield t, f_x, f_y + def reset_grids(self, N=None): + if N is not None: + m = self.are_loaded + if m.sum() > N: + for i in where(m)[0]: + self.datasets[i][1].clean() + def advect( self, x, y, - u_name, - v_name, t_init, mask_particule=None, nb_step=10, time_step=600, rk4=True, + reset_grid=None, **kw, ): """ @@ -2458,18 +2491,18 @@ def advect( :param array x: Longitude of obs to move :param array y: Latitude of obs to move - :param str,array u_name: U field to advect obs - :param str,array v_name: V field to advect obs :param float t_init: time to start advection :param array,None mask_particule: advect only i mask is True :param int nb_step: Number of iteration before to release data :param int time_step: Number of second for each advection :param bool rk4: Use rk4 algorithm instead of finite difference + :param int reset_grid: Delete all loaded data in cube if there are more than N grid loaded :return: t,x,y position .. minigallery:: py_eddy_tracker.GridCollection.advect """ + self.reset_grids(reset_grid) backward = kw.get("backward", False) if backward: generator = self.get_previous_time_step(t_init) @@ -2480,9 +2513,9 @@ def advect( dt = nb_step * time_step t_step = time_step t0, d0 = generator.__next__() - u0, v0, m0 = d0.uv_for_advection(u_name, v_name, time_step, **kw) + u0, v0, m0 = d0.uv_for_advection(time_step=time_step, **kw) t1, d1 = generator.__next__() - u1, v1, m1 = d1.uv_for_advection(u_name, v_name, time_step, **kw) + u1, v1, m1 = d1.uv_for_advection(time_step=time_step, **kw) t0 = t0 * 86400 t1 = t1 * 86400 t = t_init * 86400 @@ -2497,7 +2530,7 @@ def advect( t0, u0, v0, m0 = t1, u1, v1, m1 t1, d1 = generator.__next__() t1 = t1 * 86400 - u1, v1, m1 = d1.uv_for_advection(u_name, v_name, time_step, **kw) + u1, v1, m1 = d1.uv_for_advection(time_step=time_step, **kw) w = 1 - (arange(t, t + dt, t_step) - t0) / (t1 - t0) half_w = t_step / 2.0 / (t1 - t0) advect_( diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index 710557f7..ace889f7 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -114,7 +114,7 @@ def particle_candidate_step( # Advect particles kw = dict(nb_step=day_fraction, time_step=86400 / day_fraction) p = c.advect(x, y, t_init=t_start, **kwargs, **kw) - for _ in range(dt): + for _ in range(abs(dt)): _, x, y = p.__next__() m = ~(isnan(x) + isnan(y)) i_end = full(x.shape, -1, dtype="i4") @@ -352,7 +352,7 @@ def keep_tracks_by_date(self, date, nb_days): return self.extract_with_mask(mask) def particle_candidate_atlas( - self, cube, space_step, dt, start_intern=False, end_intern=False, **kwargs + self, cube, space_step, dt, start_intern=False, end_intern=False, callback_coherence=None, finalize_coherence=None, **kwargs ): """Select particles within eddies, advect them, return target observation and associated percentages @@ -361,7 +361,9 @@ def particle_candidate_atlas( :param int dt: duration of advection :param bool start_intern: Use intern or extern contour at injection, defaults to False :param bool end_intern: Use intern or extern contour at end of advection, defaults to False - :params dict kwargs: dict of params given to advection + :param dict kwargs: dict of params given to advection + :param func callback_coherence: if None we will use cls.fill_coherence + :param func finalize_coherence: to apply on results of callback_coherence :return (np.array,np.array): return target index and percent associate """ t_start, t_end = int(self.period[0]), int(self.period[1]) @@ -374,23 +376,62 @@ def particle_candidate_atlas( i_target, pct = full(shape, -1, dtype="i4"), zeros(shape, dtype="i1") # Backward or forward times = arange(t_start, t_end - dt) if dt > 0 else arange(t_start + dt, t_end) + + if callback_coherence is None: + callback_coherence = self.fill_coherence + indexs = dict() + results = list() + kw_coherence = dict(space_step=space_step, dt=dt, c=cube) + kw_coherence.update(kwargs) for t in times: + logger.info("Coherence for time step : %s in [%s:%s]", t, times[0], times[-1]) # Get index for origin i = t - t_start indexs0 = i_sort[i_start[i] : i_end[i]] # Get index for end i = t + dt - t_start indexs1 = i_sort[i_start[i] : i_end[i]] - # Get contour data - contours0 = [self[label][indexs0] for label in self.intern(start_intern)] - contours1 = [self[label][indexs1] for label in self.intern(end_intern)] - # Get local result - i_target_, pct_ = particle_candidate_step( - t, contours0, contours1, space_step, dt, cube, **kwargs - ) - # Merge result - m = i_target_ != -1 - i_target_[m] = indexs1[i_target_[m]] - i_target[indexs0] = i_target_ - pct[indexs0] = pct_ + if indexs0.size == 0 or indexs1.size == 0: + continue + + results.append(callback_coherence(self, i_target, pct, indexs0, indexs1, start_intern, end_intern, t_start=t, **kw_coherence)) + indexs[results[-1]] = indexs0, indexs1 + + if finalize_coherence is not None: + finalize_coherence(results, indexs, i_target, pct) return i_target, pct + + @classmethod + def fill_coherence(cls, network, i_targets, percents, i_origin, i_end, start_intern, end_intern, **kwargs): + """_summary_ + + :param array i_targets: global target + :param array percents: + :param array i_origin: indices of origins + :param array i_end: indices of ends + :param bool start_intern: Use intern or extern contour at injection + :param bool end_intern: Use intern or extern contour at end of advection + """ + # Get contour data + contours_start = [network[label][i_origin] for label in cls.intern(start_intern)] + contours_end = [network[label][i_end] for label in cls.intern(end_intern)] + # Compute local coherence + i_local_targets, local_percents = particle_candidate_step(contours_start=contours_start, contours_end=contours_end,**kwargs) + # Store + cls.merge_particle_result(i_targets, percents, i_local_targets, local_percents, i_origin, i_end) + + @staticmethod + def merge_particle_result(i_targets, percents, i_local_targets, local_percents, i_origin, i_end): + """Copy local result in merged result with global indexation + + :param array i_targets: global target + :param array percents: + :param array i_local_targets: local index target + :param array local_percents: + :param array i_origin: indices of origins + :param array i_end: indices of ends + """ + m = i_local_targets != -1 + i_local_targets[m] = i_end[i_local_targets[m]] + i_targets[i_origin] = i_local_targets + percents[i_origin] = local_percents diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 661144e7..146a87cc 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -7,7 +7,7 @@ import time import netCDF4 -from numba import njit +from numba import njit, types as nb_types from numba.typed import List from numpy import ( arange, @@ -23,6 +23,8 @@ unique, where, zeros, + percentile, + nan ) import zarr @@ -1743,6 +1745,7 @@ def segment_coherence_forward( step_mesh=1.0 / 50, contour_start="speed", contour_end="speed", + **kwargs, ): """ @@ -1801,6 +1804,7 @@ def date2file(julian_day): n_days=n_days, contour_start=contour_start, contour_end=contour_end, + **kwargs ) logger.info( ( @@ -1996,7 +2000,69 @@ def build_dataset(self, group, raw_data=True): print() eddies.track[new_i] = group return eddies + +@njit(cache=True) +def get_percentile_on_following_obs(i, indexs, percents, follow_obs, t, segment, i_target, window, q=50, nb_min=1): + """Get stat on a part of segment close of an event + + :param int i: index to follow + :param array indexs: indexs from coherence + :param array percents: percent from coherence + :param array[int] follow_obs: give index for the following observation + :param array t: time for each observation + :param array segment: segment for each observation + :param int i_target: index of target + :param int window: time window of search + :param int q: Percentile from 0 to 100, defaults to 50 + :param int nb_min: Number minimal of observation to provide statistics, defaults to 1 + :return float : return statistic + """ + last_t, segment_follow = t[i], segment[i] + segment_target = segment[i_target] + percent_target = empty(window, dtype=percents.dtype) + j = 0 + while abs(last_t - t[i]) < window and i != -1 and segment_follow == segment[i]: + # Iter on primary & secondary + for index, percent in zip(indexs[i], percents[i]): + if index != -1 and segment[index] == segment_target: + percent_target[j] = percent + j += 1 + i = follow_obs[i] + if j < nb_min: + return nan + return percentile(percent_target[:j], q) +@njit(cache=True) +def get_percentile_around_event(i, i1, i2, ind, pct, follow_obs, t, segment, window=10, follow_parent=False, q=50, nb_min=1): + """Get stat around event + + :param array[int] i: Indexs of target + :param array[int] i1: Indexs of primary origin + :param array[int] i2: Indexs of secondary origin + :param array ind: indexs from coherence + :param array pct: percent from coherence + :param array[int] follow_obs: give index for the following observation + :param array t: time for each observation + :param array segment: segment for each observation + :param int window: time window of search, defaults to 10 + :param bool follow_parent: Follow parent instead of child, defaults to False + :param int q: Percentile from 0 to 100, defaults to 50 + :param int nb_min: Number minimal of observation to provide statistics, defaults to 1 + :return (array,array) : statistic for each event + """ + stat1 = empty(i.size, dtype=nb_types.float32) + stat2 = empty(i.size, dtype=nb_types.float32) + # iter on event + for j, (i_, i1_, i2_) in enumerate(zip(i, i1, i2)): + if follow_parent: + # We follow parent + stat1[j] = get_percentile_on_following_obs(i_, ind, pct, follow_obs, t, segment, i1_, window, q, nb_min) + stat2[j] = get_percentile_on_following_obs(i_, ind, pct, follow_obs, t, segment, i2_, window, q, nb_min) + else: + # We follow child + stat1[j] = get_percentile_on_following_obs(i1_, ind, pct, follow_obs, t, segment, i_, window, q, nb_min) + stat2[j] = get_percentile_on_following_obs(i2_, ind, pct, follow_obs, t, segment, i_, window, q, nb_min) + return stat1, stat2 @njit(cache=True) def get_next_index(gr): diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index c2ff4fdb..7b1e0e45 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -1656,6 +1656,31 @@ def create_variable( except ValueError: logger.warning("Data is empty") + @staticmethod + def get_filters_zarr(name): + """Get filters to store in zarr for known variable + + :param str name: private variable name + :return list: filters list + """ + content = VAR_DESCR.get(name) + filters = list() + store_dtype = content["output_type"] + scale_factor, add_offset = content.get("scale_factor", None), content.get("add_offset", None) + if scale_factor is not None or add_offset is not None: + if add_offset is None: + add_offset = 0 + filters.append( + zarr.FixedScaleOffset( + offset=add_offset, + scale=1 / scale_factor, + dtype=content["nc_type"], + astype=store_dtype, + ) + ) + filters.extend(content.get("filters", [])) + return filters + def create_variable_zarr( self, handler_zarr, From 38b223a4b2dc07411c30dea71b6704f609fa3643 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Tue, 27 Sep 2022 14:59:00 +0200 Subject: [PATCH 207/249] dissociate return table to transfer old indice in new --- src/py_eddy_tracker/observations/groups.py | 2 +- src/py_eddy_tracker/observations/network.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index ace889f7..d363a5dd 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -375,7 +375,7 @@ def particle_candidate_atlas( shape = (len(self), 2) i_target, pct = full(shape, -1, dtype="i4"), zeros(shape, dtype="i1") # Backward or forward - times = arange(t_start, t_end - dt) if dt > 0 else arange(t_start + dt, t_end) + times = arange(t_start, t_end - dt) if dt > 0 else arange(t_start - dt, t_end) if callback_coherence is None: callback_coherence = self.fill_coherence diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 146a87cc..0285936f 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -1214,6 +1214,7 @@ def dissociate_network(self): translate[:-1][i_sort] = arange(nb_obs) self.next_obs[:] = translate[n] self.previous_obs[:] = translate[p] + return translate def network_segment(self, id_network, id_segment): return self.extract_with_mask(self.segment_slice(id_network, id_segment)) From f1260a09692958479a165cae0a636704ff9df649 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Wed, 28 Sep 2022 14:19:47 +0200 Subject: [PATCH 208/249] modify advect option --- examples/06_grid_manipulation/pet_advect.py | 20 +++++++++---------- examples/06_grid_manipulation/pet_lavd.py | 4 ++-- examples/07_cube_manipulation/pet_fsle_med.py | 4 ++-- .../pet_lavd_detection.py | 10 +++++----- examples/16_network/pet_follow_particle.py | 6 +++--- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/examples/06_grid_manipulation/pet_advect.py b/examples/06_grid_manipulation/pet_advect.py index 1a98536a..ab2a0e14 100644 --- a/examples/06_grid_manipulation/pet_advect.py +++ b/examples/06_grid_manipulation/pet_advect.py @@ -73,7 +73,7 @@ def save(self, *args, **kwargs): # %% # Movie properties kwargs = dict(frames=arange(51), interval=100) -kw_p = dict(nb_step=2, time_step=21600) +kw_p = dict(u_name="u", v_name="v", nb_step=2, time_step=21600) frame_t = kw_p["nb_step"] * kw_p["time_step"] / 86400.0 @@ -102,7 +102,7 @@ def update(i_frame, t_step): # ^^^^^^^^^^^^^^^^ # Draw 3 last position in one path for each particles., # it could be run backward with `backward=True` option in filament method -p = g.filament(x, y, "u", "v", **kw_p, filament_size=3) +p = g.filament(x, y, **kw_p, filament_size=3) fig, txt, l, t = anim_ax(lw=0.5) _ = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,)) @@ -110,13 +110,13 @@ def update(i_frame, t_step): # Particle forward # ^^^^^^^^^^^^^^^^^ # Forward advection of particles -p = g.advect(x, y, "u", "v", **kw_p) +p = g.advect(x, y, **kw_p) fig, txt, l, t = anim_ax(ls="", marker=".", markersize=1) _ = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,)) # %% # We get last position and run backward until original position -p = g.advect(x, y, "u", "v", **kw_p, backward=True) +p = g.advect(x, y, **kw_p, backward=True) fig, txt, l, _ = anim_ax(ls="", marker=".", markersize=1) _ = VideoAnimation(fig, update, **kwargs, fargs=(-frame_t,)) @@ -139,9 +139,9 @@ def update(i_frame, t_step): ) for time_step in (10800, 21600, 43200, 86400): x, y = x0.copy(), y0.copy() - kw_advect = dict(nb_step=int(50 * 86400 / time_step), time_step=time_step) - g.advect(x, y, "u", "v", **kw_advect).__next__() - g.advect(x, y, "u", "v", **kw_advect, backward=True).__next__() + kw_advect = dict(nb_step=int(50 * 86400 / time_step), time_step=time_step, u_name="u", v_name="v") + g.advect(x, y, **kw_advect).__next__() + g.advect(x, y, **kw_advect, backward=True).__next__() d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5 ax.hist(d, **kw, label=f"{86400. / time_step:.0f} time step by day") ax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc="lower right"), ax.grid() @@ -158,9 +158,9 @@ def update(i_frame, t_step): time_step = 10800 for duration in (5, 50, 100): x, y = x0.copy(), y0.copy() - kw_advect = dict(nb_step=int(duration * 86400 / time_step), time_step=time_step) - g.advect(x, y, "u", "v", **kw_advect).__next__() - g.advect(x, y, "u", "v", **kw_advect, backward=True).__next__() + kw_advect = dict(nb_step=int(duration * 86400 / time_step), time_step=time_step, u_name="u", v_name="v") + g.advect(x, y, **kw_advect).__next__() + g.advect(x, y, **kw_advect, backward=True).__next__() d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5 ax.hist(d, **kw, label=f"Time duration {duration} days") ax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc="lower right"), ax.grid() diff --git a/examples/06_grid_manipulation/pet_lavd.py b/examples/06_grid_manipulation/pet_lavd.py index 331ace8a..639db99e 100644 --- a/examples/06_grid_manipulation/pet_lavd.py +++ b/examples/06_grid_manipulation/pet_lavd.py @@ -110,9 +110,9 @@ def save(self, *args, **kwargs): step_by_day = 3 # Compute step of advection every 4h nb_step = 2 -kw_p = dict(nb_step=nb_step, time_step=86400 / step_by_day / nb_step) +kw_p = dict(nb_step=nb_step, time_step=86400 / step_by_day / nb_step, u_name="u", v_name="v") # Start a generator which at each iteration return new position at next time step -particule = g.advect(x, y, "u", "v", **kw_p, rk4=True) +particule = g.advect(x, y, **kw_p, rk4=True) # %% # LAVD diff --git a/examples/07_cube_manipulation/pet_fsle_med.py b/examples/07_cube_manipulation/pet_fsle_med.py index ef777639..a949ec77 100644 --- a/examples/07_cube_manipulation/pet_fsle_med.py +++ b/examples/07_cube_manipulation/pet_fsle_med.py @@ -142,8 +142,8 @@ def build_triplet(x, y, step=0.02): used = zeros(x.shape[0], dtype="bool") # advection generator -kw = dict(t_init=t0, nb_step=1, backward=backward, mask_particule=used) -p = c.advect(x, y, "u", "v", time_step=86400 / time_step_by_days, **kw) +kw = dict(t_init=t0, nb_step=1, backward=backward, mask_particule=used, u_name="u", v_name="v") +p = c.advect(x, y, time_step=86400 / time_step_by_days, **kw) # We check at each step of advection if particle distance is over `dist_max` for i in range(time_step_by_days * nb_days): diff --git a/examples/07_cube_manipulation/pet_lavd_detection.py b/examples/07_cube_manipulation/pet_lavd_detection.py index 1fa4d60b..4dace120 100644 --- a/examples/07_cube_manipulation/pet_lavd_detection.py +++ b/examples/07_cube_manipulation/pet_lavd_detection.py @@ -93,7 +93,7 @@ def update_axes(ax, mappable=None): # Time properties, for example with advection only 25 days nb_days, step_by_day = 25, 6 nb_time = step_by_day * nb_days -kw_p = dict(nb_step=1, time_step=86400 / step_by_day) +kw_p = dict(nb_step=1, time_step=86400 / step_by_day, u_name="u", v_name="v") t0 = 20236 t0_grid = c[t0] # Geographic properties, we use a coarser resolution for time consuming reasons @@ -114,7 +114,7 @@ def update_axes(ax, mappable=None): # ---------------------------- lavd = zeros(original_shape) lavd_ = lavd[m] -p = c.advect(x0.copy(), y0.copy(), "u", "v", t_init=t0, **kw_p) +p = c.advect(x0.copy(), y0.copy(), t_init=t0, **kw_p) for _ in range(nb_time): t, x, y = p.__next__() lavd_ += abs(c.interp("vort", t / 86400.0, x, y)) @@ -131,7 +131,7 @@ def update_axes(ax, mappable=None): # ----------------------------- lavd = zeros(original_shape) lavd_ = lavd[m] -p = c.advect(x0.copy(), y0.copy(), "u", "v", t_init=t0, backward=True, **kw_p) +p = c.advect(x0.copy(), y0.copy(), t_init=t0, backward=True, **kw_p) for i in range(nb_time): t, x, y = p.__next__() lavd_ += abs(c.interp("vort", t / 86400.0, x, y)) @@ -148,7 +148,7 @@ def update_axes(ax, mappable=None): # --------------------------- lavd = zeros(original_shape) lavd_ = lavd[m] -p = t0_grid.advect(x0.copy(), y0.copy(), "u", "v", **kw_p) +p = t0_grid.advect(x0.copy(), y0.copy(), **kw_p) for _ in range(nb_time): x, y = p.__next__() lavd_ += abs(t0_grid.interp("vort", x, y)) @@ -165,7 +165,7 @@ def update_axes(ax, mappable=None): # ---------------------------- lavd = zeros(original_shape) lavd_ = lavd[m] -p = t0_grid.advect(x0.copy(), y0.copy(), "u", "v", backward=True, **kw_p) +p = t0_grid.advect(x0.copy(), y0.copy(), backward=True, **kw_p) for i in range(nb_time): x, y = p.__next__() lavd_ += abs(t0_grid.interp("vort", x, y)) diff --git a/examples/16_network/pet_follow_particle.py b/examples/16_network/pet_follow_particle.py index 21592558..356c7da4 100644 --- a/examples/16_network/pet_follow_particle.py +++ b/examples/16_network/pet_follow_particle.py @@ -95,11 +95,11 @@ def save(self, *args, **kwargs): a.txt.set_position((25, 31)) step = 0.25 -kw_p = dict(nb_step=2, time_step=86400 * step * 0.5, t_init=t_snapshot - 2 * step) +kw_p = dict(nb_step=2, time_step=86400 * step * 0.5, t_init=t_snapshot - 2 * step, u_name="u", v_name="v") mappables = dict() -particules = c.advect(x, y, "u", "v", **kw_p) -filament = c.filament(x_f, y_f, "u", "v", **kw_p, filament_size=3) +particules = c.advect(x, y, **kw_p) +filament = c.filament(x_f, y_f, **kw_p, filament_size=3) kw = dict(ls="", marker=".", markersize=0.25) for k in index_: m = k == index From d54a743e61891ddbe913da7f2a25f5a389b09540 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Wed, 28 Sep 2022 14:24:03 +0200 Subject: [PATCH 209/249] return sorting argument --- src/py_eddy_tracker/observations/network.py | 53 ++++++++----------- .../observations/observation.py | 20 ++++--- src/py_eddy_tracker/observations/tracking.py | 6 +-- src/py_eddy_tracker/tracking.py | 4 +- 4 files changed, 38 insertions(+), 45 deletions(-) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 0285936f..604035e4 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -106,12 +106,14 @@ def fix_next_previous_obs(next_obs, previous_obs, flag_virtual): class NetworkObservations(GroupEddiesObservations): - __slots__ = ("_index_network",) - + __slots__ = ("_index_network", "_index_segment_track", "_segment_track_array") NOGROUP = 0 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + self.reset_index() + + def reset_index(self): self._index_network = None self._index_segment_track = None self._segment_track_array = None @@ -251,9 +253,8 @@ def elements(self): def astype(self, cls): new = cls.new_like(self, self.shape) - print() - for k in new.obs.dtype.names: - if k in self.obs.dtype.names: + for k in new.fields: + if k in self.fields: new[k][:] = self[k][:] new.sign_type = self.sign_type return new @@ -371,8 +372,7 @@ def correct_close_events(self, nb_days_max=20): self.segment[:] = segment_copy self.previous_obs[:] = previous_obs - - self.sort() + return self.sort() def sort(self, order=("track", "segment", "time")): """ @@ -380,14 +380,19 @@ def sort(self, order=("track", "segment", "time")): :param tuple order: order or sorting. Given to :func:`numpy.argsort` """ - index_order = self.obs.argsort(order=order) - for field in self.elements: + index_order = self.obs.argsort(order=order, kind="mergesort") + self.reset_index() + for field in self.fields: self[field][:] = self[field][index_order] - translate = -ones(index_order.max() + 2, dtype="i4") - translate[index_order] = arange(index_order.shape[0]) + nb_obs = len(self) + # we add 1 for -1 index return index -1 + translate = -ones(nb_obs + 1, dtype="i4") + translate[index_order] = arange(nb_obs) + # next & previous must be re-indexed self.next_obs[:] = translate[self.next_obs] self.previous_obs[:] = translate[self.previous_obs] + return index_order, translate def obs_relative_order(self, i_obs): self.only_one_network() @@ -654,16 +659,16 @@ def normalize_longitude(self): lon0 = (self.lon[i_start] - 180).repeat(i_stop - i_start) logger.debug("Normalize longitude") self.lon[:] = (self.lon - lon0) % 360 + lon0 - if "lon_max" in self.obs.dtype.names: + if "lon_max" in self.fields: logger.debug("Normalize longitude_max") self.lon_max[:] = (self.lon_max - self.lon + 180) % 360 + self.lon - 180 if not self.raw_data: - if "contour_lon_e" in self.obs.dtype.names: + if "contour_lon_e" in self.fields: logger.debug("Normalize effective contour longitude") self.contour_lon_e[:] = ( (self.contour_lon_e.T - self.lon + 180) % 360 + self.lon - 180 ).T - if "contour_lon_s" in self.obs.dtype.names: + if "contour_lon_s" in self.fields: logger.debug("Normalize speed contour longitude") self.contour_lon_s[:] = ( (self.contour_lon_s.T - self.lon + 180) % 360 + self.lon - 180 @@ -1071,7 +1076,7 @@ def extract_event(self, indices): raw_data=self.raw_data, ) - for k in new.obs.dtype.names: + for k in new.fields: new[k][:] = self[k][indices] new.sign_type = self.sign_type return new @@ -1194,27 +1199,11 @@ def dissociate_network(self): """ Dissociate networks with no known interaction (splitting/merging) """ - tags = self.tag_segment(multi_network=True) if self.track[0] == 0: tags -= 1 - self.track[:] = tags[self.segment_track_array] - - i_sort = self.obs.argsort(order=("track", "segment", "time"), kind="mergesort") - # Sort directly obs, with hope to save memory - self.obs.sort(order=("track", "segment", "time"), kind="mergesort") - self._index_network = None - - # n & p must be re-indexed - n, p = self.next_obs, self.previous_obs - # we add 2 for -1 index return index -1 - nb_obs = len(self) - translate = -ones(nb_obs + 1, dtype="i4") - translate[:-1][i_sort] = arange(nb_obs) - self.next_obs[:] = translate[n] - self.previous_obs[:] = translate[p] - return translate + return self.sort() def network_segment(self, id_network, id_segment): return self.extract_with_mask(self.segment_slice(id_network, id_segment)) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 7b1e0e45..ae95315e 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -306,12 +306,16 @@ def box_display(value): """Return values evenly spaced with few numbers""" return "".join([f"{v_:10.2f}" for v_ in value]) + @property + def fields(self): + return list(self.obs.dtype.names) + def field_table(self): """ Produce description table of the fields available in this object """ rows = [("Name (Unit)", "Long name", "Scale factor", "Offset")] - names = list(self.obs.dtype.names) + names = self.fields names.sort() for field in names: infos = VAR_DESCR[field] @@ -414,7 +418,7 @@ def remove_fields(self, *fields): """ nb_obs = self.obs.shape[0] fields = set(fields) - only_variables = set(self.obs.dtype.names) - fields + only_variables = set(self.fields) - fields track_extra_variables = set(self.track_extra_variables) - fields array_variables = set(self.array_variables) - fields new = self.__class__( @@ -426,7 +430,7 @@ def remove_fields(self, *fields): raw_data=self.raw_data, ) new.sign_type = self.sign_type - for name in new.obs.dtype.names: + for name in new.fields: logger.debug("Copy of field %s ...", name) new.obs[name] = self.obs[name] return new @@ -444,12 +448,12 @@ def add_fields(self, fields=list(), array_fields=list()): track_array_variables=self.track_array_variables, array_variables=list(concatenate((self.array_variables, array_fields))), only_variables=list( - concatenate((self.obs.dtype.names, fields, array_fields)) + concatenate((self.fields, fields, array_fields)) ), raw_data=self.raw_data, ) new.sign_type = self.sign_type - for name in self.obs.dtype.names: + for name in self.fields: logger.debug("Copy of field %s ...", name) new.obs[name] = self.obs[name] return new @@ -467,8 +471,8 @@ def circle_contour(self, only_virtual=False, factor=1): """ angle = radians(linspace(0, 360, self.track_array_variables)) x_norm, y_norm = cos(angle), sin(angle) - radius_s = "contour_lon_s" in self.obs.dtype.names - radius_e = "contour_lon_e" in self.obs.dtype.names + radius_s = "contour_lon_s" in self.fields + radius_e = "contour_lon_e" in self.fields for i, obs in enumerate(self): if only_virtual and not obs["virtual"]: continue @@ -684,7 +688,7 @@ def distance(self, other): def __copy__(self): eddies = self.new_like(self, len(self)) - for k in self.obs.dtype.names: + for k in self.fields: eddies[k][:] = self[k][:] eddies.sign_type = self.sign_type return eddies diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index 993e30f9..f1d2399b 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -183,16 +183,16 @@ def normalize_longitude(self): lon0 = (self.lon[self.index_from_track] - 180).repeat(self.nb_obs_by_track) logger.debug("Normalize longitude") self.lon[:] = (self.lon - lon0) % 360 + lon0 - if "lon_max" in self.obs.dtype.names: + if "lon_max" in self.fields: logger.debug("Normalize longitude_max") self.lon_max[:] = (self.lon_max - self.lon + 180) % 360 + self.lon - 180 if not self.raw_data: - if "contour_lon_e" in self.obs.dtype.names: + if "contour_lon_e" in self.fields: logger.debug("Normalize effective contour longitude") self.contour_lon_e[:] = ( (self.contour_lon_e.T - self.lon + 180) % 360 + self.lon - 180 ).T - if "contour_lon_s" in self.obs.dtype.names: + if "contour_lon_s" in self.fields: logger.debug("Normalize speed contour longitude") self.contour_lon_s[:] = ( (self.contour_lon_s.T - self.lon + 180) % 360 + self.lon - 180 diff --git a/src/py_eddy_tracker/tracking.py b/src/py_eddy_tracker/tracking.py index 02068962..16616d5a 100644 --- a/src/py_eddy_tracker/tracking.py +++ b/src/py_eddy_tracker/tracking.py @@ -658,7 +658,7 @@ def merge(self, until=-1, raw_data=True): # Set type of eddy with first file eddies.sign_type = self.current_obs.sign_type # Fields to copy - fields = self.current_obs.obs.dtype.names + fields = self.current_obs.fields # To know if the track start first_obs_save_in_tracks = zeros(self.i_current_by_tracks.shape, dtype=bool_) @@ -707,7 +707,7 @@ def merge(self, until=-1, raw_data=True): # Index in the current file index_current = self[i]["out"] - if "cost_association" in eddies.obs.dtype.names: + if "cost_association" in eddies.fields: eddies["cost_association"][index_final - 1] = self[i]["cost_value"] # Copy all variable for field in fields: From 2ba0d2af02d59dff8c6ed811ffcd5c5ff04e8189 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Wed, 28 Sep 2022 15:08:37 +0200 Subject: [PATCH 210/249] update example --- .../pet_particles_drift.py | 6 ++-- .../06_grid_manipulation/pet_advect.ipynb | 28 +++++++++---------- .../06_grid_manipulation/pet_lavd.ipynb | 18 ++++++------ .../07_cube_manipulation/pet_fsle_med.ipynb | 22 +++++++-------- .../pet_lavd_detection.ipynb | 12 ++++---- .../pet_particles_drift.ipynb | 6 ++-- src/py_eddy_tracker/observations/groups.py | 2 +- 7 files changed, 47 insertions(+), 47 deletions(-) diff --git a/examples/07_cube_manipulation/pet_particles_drift.py b/examples/07_cube_manipulation/pet_particles_drift.py index f73216fc..c61ced5b 100644 --- a/examples/07_cube_manipulation/pet_particles_drift.py +++ b/examples/07_cube_manipulation/pet_particles_drift.py @@ -20,7 +20,7 @@ "longitude", "latitude", "time", - heigth="adt", + unset=True ) # %% @@ -34,7 +34,7 @@ # Get paths x0, y0 = meshgrid(arange(32, 35, 0.5), arange(32.5, 34.5, 0.5)) x0, y0 = x0.reshape(-1), y0.reshape(-1) -t, x, y = c.path(x0, y0, "u", "v", t_init=t0, **kw_p, nb_time=nb_time) +t, x, y = c.path(x0, y0, h_name="adt", t_init=t0, **kw_p, nb_time=nb_time) # %% # Plot paths @@ -43,4 +43,4 @@ ax.plot(x, y, lw=3) ax.set_title("10 days particle paths") ax.set_xlim(31, 35), ax.set_ylim(32, 34.5) -ax.grid() +ax.grid() \ No newline at end of file diff --git a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb index 79d69b0d..90ee1722 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_advect.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\nGrid advection\n==============\n\nDummy advection which use only static geostrophic current, which didn't solve the complex circulation of the ocean.\n" + "\n# Grid advection\n\nDummy advection which use only static geostrophic current, which didn't solve the complex circulation of the ocean.\n" ] }, { @@ -98,7 +98,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Anim\n----\nParticles setup\n\n" + "## Anim\nParticles setup\n\n" ] }, { @@ -127,7 +127,7 @@ }, "outputs": [], "source": [ - "kwargs = dict(frames=arange(51), interval=100)\nkw_p = dict(nb_step=2, time_step=21600)\nframe_t = kw_p[\"nb_step\"] * kw_p[\"time_step\"] / 86400.0" + "kwargs = dict(frames=arange(51), interval=100)\nkw_p = dict(u_name=\"u\", v_name=\"v\", nb_step=2, time_step=21600)\nframe_t = kw_p[\"nb_step\"] * kw_p[\"time_step\"] / 86400.0" ] }, { @@ -152,7 +152,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Filament forward\n^^^^^^^^^^^^^^^^\nDraw 3 last position in one path for each particles.,\nit could be run backward with `backward=True` option in filament method\n\n" + "### Filament forward\nDraw 3 last position in one path for each particles.,\nit could be run backward with `backward=True` option in filament method\n\n" ] }, { @@ -163,14 +163,14 @@ }, "outputs": [], "source": [ - "p = g.filament(x, y, \"u\", \"v\", **kw_p, filament_size=3)\nfig, txt, l, t = anim_ax(lw=0.5)\n_ = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,))" + "p = g.filament(x, y, **kw_p, filament_size=3)\nfig, txt, l, t = anim_ax(lw=0.5)\n_ = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Particle forward\n^^^^^^^^^^^^^^^^^\nForward advection of particles\n\n" + "### Particle forward\nForward advection of particles\n\n" ] }, { @@ -181,7 +181,7 @@ }, "outputs": [], "source": [ - "p = g.advect(x, y, \"u\", \"v\", **kw_p)\nfig, txt, l, t = anim_ax(ls=\"\", marker=\".\", markersize=1)\n_ = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,))" + "p = g.advect(x, y, **kw_p)\nfig, txt, l, t = anim_ax(ls=\"\", marker=\".\", markersize=1)\n_ = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,))" ] }, { @@ -199,21 +199,21 @@ }, "outputs": [], "source": [ - "p = g.advect(x, y, \"u\", \"v\", **kw_p, backward=True)\nfig, txt, l, _ = anim_ax(ls=\"\", marker=\".\", markersize=1)\n_ = VideoAnimation(fig, update, **kwargs, fargs=(-frame_t,))" + "p = g.advect(x, y, **kw_p, backward=True)\nfig, txt, l, _ = anim_ax(ls=\"\", marker=\".\", markersize=1)\n_ = VideoAnimation(fig, update, **kwargs, fargs=(-frame_t,))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Particles stat\n--------------\n\n" + "## Particles stat\n\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Time_step settings\n^^^^^^^^^^^^^^^^^^\nDummy experiment to test advection precision, we run particles 50 days forward and backward with different time step\nand we measure distance between new positions and original positions.\n\n" + "### Time_step settings\nDummy experiment to test advection precision, we run particles 50 days forward and backward with different time step\nand we measure distance between new positions and original positions.\n\n" ] }, { @@ -224,14 +224,14 @@ }, "outputs": [], "source": [ - "fig = plt.figure()\nax = fig.add_subplot(111)\nkw = dict(\n bins=arange(0, 50, 0.001),\n cumulative=True,\n weights=ones(x0.shape) / x0.shape[0] * 100.0,\n histtype=\"step\",\n)\nfor time_step in (10800, 21600, 43200, 86400):\n x, y = x0.copy(), y0.copy()\n kw_advect = dict(nb_step=int(50 * 86400 / time_step), time_step=time_step)\n g.advect(x, y, \"u\", \"v\", **kw_advect).__next__()\n g.advect(x, y, \"u\", \"v\", **kw_advect, backward=True).__next__()\n d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5\n ax.hist(d, **kw, label=f\"{86400. / time_step:.0f} time step by day\")\nax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc=\"lower right\"), ax.grid()\nax.set_title(\"Distance after 50 days forward and 50 days backward\")\nax.set_xlabel(\"Distance between original position and final position (in degrees)\")\n_ = ax.set_ylabel(\"Percent of particles with distance lesser than\")" + "fig = plt.figure()\nax = fig.add_subplot(111)\nkw = dict(\n bins=arange(0, 50, 0.001),\n cumulative=True,\n weights=ones(x0.shape) / x0.shape[0] * 100.0,\n histtype=\"step\",\n)\nfor time_step in (10800, 21600, 43200, 86400):\n x, y = x0.copy(), y0.copy()\n kw_advect = dict(nb_step=int(50 * 86400 / time_step), time_step=time_step, u_name=\"u\", v_name=\"v\")\n g.advect(x, y, **kw_advect).__next__()\n g.advect(x, y, **kw_advect, backward=True).__next__()\n d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5\n ax.hist(d, **kw, label=f\"{86400. / time_step:.0f} time step by day\")\nax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc=\"lower right\"), ax.grid()\nax.set_title(\"Distance after 50 days forward and 50 days backward\")\nax.set_xlabel(\"Distance between original position and final position (in degrees)\")\n_ = ax.set_ylabel(\"Percent of particles with distance lesser than\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Time duration\n^^^^^^^^^^^^^\nWe keep same time_step but change time duration\n\n" + "### Time duration\nWe keep same time_step but change time duration\n\n" ] }, { @@ -242,7 +242,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure()\nax = fig.add_subplot(111)\ntime_step = 10800\nfor duration in (5, 50, 100):\n x, y = x0.copy(), y0.copy()\n kw_advect = dict(nb_step=int(duration * 86400 / time_step), time_step=time_step)\n g.advect(x, y, \"u\", \"v\", **kw_advect).__next__()\n g.advect(x, y, \"u\", \"v\", **kw_advect, backward=True).__next__()\n d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5\n ax.hist(d, **kw, label=f\"Time duration {duration} days\")\nax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc=\"lower right\"), ax.grid()\nax.set_title(\n \"Distance after N days forward and N days backward\\nwith a time step of 1/8 days\"\n)\nax.set_xlabel(\"Distance between original position and final position (in degrees)\")\n_ = ax.set_ylabel(\"Percent of particles with distance lesser than \")" + "fig = plt.figure()\nax = fig.add_subplot(111)\ntime_step = 10800\nfor duration in (5, 50, 100):\n x, y = x0.copy(), y0.copy()\n kw_advect = dict(nb_step=int(duration * 86400 / time_step), time_step=time_step, u_name=\"u\", v_name=\"v\")\n g.advect(x, y, **kw_advect).__next__()\n g.advect(x, y, **kw_advect, backward=True).__next__()\n d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5\n ax.hist(d, **kw, label=f\"Time duration {duration} days\")\nax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc=\"lower right\"), ax.grid()\nax.set_title(\n \"Distance after N days forward and N days backward\\nwith a time step of 1/8 days\"\n)\nax.set_xlabel(\"Distance between original position and final position (in degrees)\")\n_ = ax.set_ylabel(\"Percent of particles with distance lesser than \")" ] } ], @@ -262,7 +262,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.10.6" } }, "nbformat": 4, diff --git a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb index c4a4da84..cbe6de64 100644 --- a/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb +++ b/notebooks/python_module/06_grid_manipulation/pet_lavd.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\nLAVD experiment\n===============\n\nNaive method to reproduce LAVD(Lagrangian-Averaged Vorticity deviation) method with a static velocity field.\nIn the current example we didn't remove a mean vorticity.\n\nMethod are described here:\n\n - Abernathey, Ryan, and George Haller. \"Transport by Lagrangian Vortices in the Eastern Pacific\",\n Journal of Physical Oceanography 48, 3 (2018): 667-685, accessed Feb 16, 2021,\n https://doi.org/10.1175/JPO-D-17-0102.1\n - `Transport by Coherent Lagrangian Vortices`_,\n R. Abernathey, Sinha A., Tarshish N., Liu T., Zhang C., Haller G., 2019,\n Talk a t the Sources and Sinks of Ocean Mesoscale Eddy Energy CLIVAR Workshop\n\n https://usclivar.org/sites/default/files/meetings/2019/presentations/Aberernathey_CLIVAR.pdf\n" + "\n# LAVD experiment\n\nNaive method to reproduce LAVD(Lagrangian-Averaged Vorticity deviation) method with a static velocity field.\nIn the current example we didn't remove a mean vorticity.\n\nMethod are described here:\n\n - Abernathey, Ryan, and George Haller. \"Transport by Lagrangian Vortices in the Eastern Pacific\",\n Journal of Physical Oceanography 48, 3 (2018): 667-685, accessed Feb 16, 2021,\n https://doi.org/10.1175/JPO-D-17-0102.1\n - `Transport by Coherent Lagrangian Vortices`_,\n R. Abernathey, Sinha A., Tarshish N., Liu T., Zhang C., Haller G., 2019,\n Talk a t the Sources and Sinks of Ocean Mesoscale Eddy Energy CLIVAR Workshop\n\n https://usclivar.org/sites/default/files/meetings/2019/presentations/Aberernathey_CLIVAR.pdf\n" ] }, { @@ -55,7 +55,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Data\n----\nTo compute vorticity ($\\omega$) we compute u/v field with a stencil and apply the following equation with stencil\nmethod :\n\n\\begin{align}\\omega = \\frac{\\partial v}{\\partial x} - \\frac{\\partial u}{\\partial y}\\end{align}\n\n" + "## Data\nTo compute vorticity ($\\omega$) we compute u/v field with a stencil and apply the following equation with stencil\nmethod :\n\n\\begin{align}\\omega = \\frac{\\partial v}{\\partial x} - \\frac{\\partial u}{\\partial y}\\end{align}\n\n" ] }, { @@ -91,7 +91,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Particles\n---------\nParticles specification\n\n" + "## Particles\nParticles specification\n\n" ] }, { @@ -102,14 +102,14 @@ }, "outputs": [], "source": [ - "step = 1 / 32\nx_g, y_g = arange(0, 36, step), arange(28, 46, step)\nx, y = meshgrid(x_g, y_g)\noriginal_shape = x.shape\nx, y = x.reshape(-1), y.reshape(-1)\nprint(f\"{len(x)} particles advected\")\n# A frame every 8h\nstep_by_day = 3\n# Compute step of advection every 4h\nnb_step = 2\nkw_p = dict(nb_step=nb_step, time_step=86400 / step_by_day / nb_step)\n# Start a generator which at each iteration return new position at next time step\nparticule = g.advect(x, y, \"u\", \"v\", **kw_p, rk4=True)" + "step = 1 / 32\nx_g, y_g = arange(0, 36, step), arange(28, 46, step)\nx, y = meshgrid(x_g, y_g)\noriginal_shape = x.shape\nx, y = x.reshape(-1), y.reshape(-1)\nprint(f\"{len(x)} particles advected\")\n# A frame every 8h\nstep_by_day = 3\n# Compute step of advection every 4h\nnb_step = 2\nkw_p = dict(nb_step=nb_step, time_step=86400 / step_by_day / nb_step, u_name=\"u\", v_name=\"v\")\n# Start a generator which at each iteration return new position at next time step\nparticule = g.advect(x, y, **kw_p, rk4=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "LAVD\n----\n\n" + "## LAVD\n\n" ] }, { @@ -127,7 +127,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Anim\n^^^^\nMovie of LAVD integration at each integration time step.\n\n" + "### Anim\nMovie of LAVD integration at each integration time step.\n\n" ] }, { @@ -145,7 +145,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Final LAVD\n^^^^^^^^^^\n\n" + "### Final LAVD\n\n" ] }, { @@ -163,7 +163,7 @@ }, "outputs": [], "source": [ - "lavd = RegularGridDataset.with_array(\n coordinates=(\"lon\", \"lat\"),\n datas=dict(lavd=lavd.T, lon=x_g, lat=y_g,),\n centered=True,\n)" + "lavd = RegularGridDataset.with_array(\n coordinates=(\"lon\", \"lat\"), datas=dict(lavd=lavd.T, lon=x_g, lat=y_g), centered=True\n)" ] }, { @@ -201,7 +201,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.10.6" } }, "nbformat": 4, diff --git a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb index 8ee136b3..6f52e750 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_fsle_med.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\nFSLE experiment in med\n======================\n\nExample to build Finite Size Lyapunov Exponents, parameter values must be adapted for your case.\n\nExample use a method similar to `AVISO flse`_\n\n https://www.aviso.altimetry.fr/en/data/products/value-added-products/\n fsle-finite-size-lyapunov-exponents/fsle-description.html\n" + "\n# FSLE experiment in med\n\nExample to build Finite Size Lyapunov Exponents, parameter values must be adapted for your case.\n\nExample use a method similar to `AVISO flse`_\n\n https://www.aviso.altimetry.fr/en/data/products/value-added-products/\n fsle-finite-size-lyapunov-exponents/fsle-description.html\n" ] }, { @@ -33,7 +33,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "ADT in med\n----------\n:py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_cube` method is\nmade for data stores in time cube, you could use also \n:py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_list` method to\nload data-cube from multiple file.\n\n" + "## ADT in med\n:py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_cube` method is\nmade for data stores in time cube, you could use also\n:py:meth:`~py_eddy_tracker.dataset.grid.GridCollection.from_netcdf_list` method to\nload data-cube from multiple file.\n\n" ] }, { @@ -51,7 +51,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Methods to compute FSLE\n-----------------------\n\n" + "## Methods to compute FSLE\n\n" ] }, { @@ -62,14 +62,14 @@ }, "outputs": [], "source": [ - "@njit(cache=True, fastmath=True)\ndef check_p(x, y, flse, theta, m_set, m, dt, dist_init=0.02, dist_max=0.6):\n \"\"\"\n Check if distance between eastern or northern particle to center particle is bigger than `dist_max`\n \"\"\"\n nb_p = x.shape[0] // 3\n delta = dist_max ** 2\n for i in range(nb_p):\n i0 = i * 3\n i_n = i0 + 1\n i_e = i0 + 2\n # If particle already set, we skip\n if m[i0] or m[i_n] or m[i_e]:\n continue\n # Distance with north\n dxn, dyn = x[i0] - x[i_n], y[i0] - y[i_n]\n dn = dxn ** 2 + dyn ** 2\n # Distance with east\n dxe, dye = x[i0] - x[i_e], y[i0] - y[i_e]\n de = dxe ** 2 + dye ** 2\n\n if dn >= delta or de >= delta:\n s1 = dn + de\n at1 = 2 * (dxe * dxn + dye * dyn)\n at2 = de - dn\n s2 = ((dxn + dye) ** 2 + (dxe - dyn) ** 2) * (\n (dxn - dye) ** 2 + (dxe + dyn) ** 2\n )\n flse[i] = 1 / (2 * dt) * log(1 / (2 * dist_init ** 2) * (s1 + s2 ** 0.5))\n theta[i] = arctan2(at1, at2 + s2) * 180 / pi\n # To know where value are set\n m_set[i] = False\n # To stop particle advection\n m[i0], m[i_n], m[i_e] = True, True, True\n\n\n@njit(cache=True)\ndef build_triplet(x, y, step=0.02):\n \"\"\"\n Triplet building for each position we add east and north point with defined step\n \"\"\"\n nb_x = x.shape[0]\n x_ = empty(nb_x * 3, dtype=x.dtype)\n y_ = empty(nb_x * 3, dtype=y.dtype)\n for i in range(nb_x):\n i0 = i * 3\n i_n, i_e = i0 + 1, i0 + 2\n x__, y__ = x[i], y[i]\n x_[i0], y_[i0] = x__, y__\n x_[i_n], y_[i_n] = x__, y__ + step\n x_[i_e], y_[i_e] = x__ + step, y__\n return x_, y_" + "@njit(cache=True, fastmath=True)\ndef check_p(x, y, flse, theta, m_set, m, dt, dist_init=0.02, dist_max=0.6):\n \"\"\"\n Check if distance between eastern or northern particle to center particle is bigger than `dist_max`\n \"\"\"\n nb_p = x.shape[0] // 3\n delta = dist_max**2\n for i in range(nb_p):\n i0 = i * 3\n i_n = i0 + 1\n i_e = i0 + 2\n # If particle already set, we skip\n if m[i0] or m[i_n] or m[i_e]:\n continue\n # Distance with north\n dxn, dyn = x[i0] - x[i_n], y[i0] - y[i_n]\n dn = dxn**2 + dyn**2\n # Distance with east\n dxe, dye = x[i0] - x[i_e], y[i0] - y[i_e]\n de = dxe**2 + dye**2\n\n if dn >= delta or de >= delta:\n s1 = dn + de\n at1 = 2 * (dxe * dxn + dye * dyn)\n at2 = de - dn\n s2 = ((dxn + dye) ** 2 + (dxe - dyn) ** 2) * (\n (dxn - dye) ** 2 + (dxe + dyn) ** 2\n )\n flse[i] = 1 / (2 * dt) * log(1 / (2 * dist_init**2) * (s1 + s2**0.5))\n theta[i] = arctan2(at1, at2 + s2) * 180 / pi\n # To know where value are set\n m_set[i] = False\n # To stop particle advection\n m[i0], m[i_n], m[i_e] = True, True, True\n\n\n@njit(cache=True)\ndef build_triplet(x, y, step=0.02):\n \"\"\"\n Triplet building for each position we add east and north point with defined step\n \"\"\"\n nb_x = x.shape[0]\n x_ = empty(nb_x * 3, dtype=x.dtype)\n y_ = empty(nb_x * 3, dtype=y.dtype)\n for i in range(nb_x):\n i0 = i * 3\n i_n, i_e = i0 + 1, i0 + 2\n x__, y__ = x[i], y[i]\n x_[i0], y_[i0] = x__, y__\n x_[i_n], y_[i_n] = x__, y__ + step\n x_[i_e], y_[i_e] = x__ + step, y__\n return x_, y_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Settings\n--------\n\n" + "## Settings\n\n" ] }, { @@ -87,7 +87,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Particles\n---------\n\n" + "## Particles\n\n" ] }, { @@ -105,7 +105,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "FSLE\n----\n\n" + "## FSLE\n\n" ] }, { @@ -116,14 +116,14 @@ }, "outputs": [], "source": [ - "# Array to compute fsle\nfsle = zeros(x0.shape[0], dtype=\"f4\")\ntheta = zeros(x0.shape[0], dtype=\"f4\")\nmask = ones(x0.shape[0], dtype=\"f4\")\nx, y = build_triplet(x0, y0, dist_init)\nused = zeros(x.shape[0], dtype=\"bool\")\n\n# advection generator\nkw = dict(t_init=t0, nb_step=1, backward=backward, mask_particule=used)\np = c.advect(x, y, \"u\", \"v\", time_step=86400 / time_step_by_days, **kw)\n\n# We check at each step of advection if particle distance is over `dist_max`\nfor i in range(time_step_by_days * nb_days):\n t, xt, yt = p.__next__()\n dt = t / 86400.0 - t0\n check_p(xt, yt, fsle, theta, mask, used, dt, dist_max=dist_max, dist_init=dist_init)\n\n# Get index with original_position\ni = ((x0 - x0_) / step_grid_out).astype(\"i4\")\nj = ((y0 - y0_) / step_grid_out).astype(\"i4\")\nfsle_ = empty(grid_shape, dtype=\"f4\")\ntheta_ = empty(grid_shape, dtype=\"f4\")\nmask_ = ones(grid_shape, dtype=\"bool\")\nfsle_[i, j] = fsle\ntheta_[i, j] = theta\nmask_[i, j] = mask\n# Create a grid object\nfsle_custom = RegularGridDataset.with_array(\n coordinates=(\"lon\", \"lat\"),\n datas=dict(\n fsle=ma.array(fsle_, mask=mask_),\n theta=ma.array(theta_, mask=mask_),\n lon=lon_p,\n lat=lat_p,\n ),\n centered=True,\n)" + "# Array to compute fsle\nfsle = zeros(x0.shape[0], dtype=\"f4\")\ntheta = zeros(x0.shape[0], dtype=\"f4\")\nmask = ones(x0.shape[0], dtype=\"f4\")\nx, y = build_triplet(x0, y0, dist_init)\nused = zeros(x.shape[0], dtype=\"bool\")\n\n# advection generator\nkw = dict(t_init=t0, nb_step=1, backward=backward, mask_particule=used, u_name=\"u\", v_name=\"v\")\np = c.advect(x, y, time_step=86400 / time_step_by_days, **kw)\n\n# We check at each step of advection if particle distance is over `dist_max`\nfor i in range(time_step_by_days * nb_days):\n t, xt, yt = p.__next__()\n dt = t / 86400.0 - t0\n check_p(xt, yt, fsle, theta, mask, used, dt, dist_max=dist_max, dist_init=dist_init)\n\n# Get index with original_position\ni = ((x0 - x0_) / step_grid_out).astype(\"i4\")\nj = ((y0 - y0_) / step_grid_out).astype(\"i4\")\nfsle_ = empty(grid_shape, dtype=\"f4\")\ntheta_ = empty(grid_shape, dtype=\"f4\")\nmask_ = ones(grid_shape, dtype=\"bool\")\nfsle_[i, j] = fsle\ntheta_[i, j] = theta\nmask_[i, j] = mask\n# Create a grid object\nfsle_custom = RegularGridDataset.with_array(\n coordinates=(\"lon\", \"lat\"),\n datas=dict(\n fsle=ma.array(fsle_, mask=mask_),\n theta=ma.array(theta_, mask=mask_),\n lon=lon_p,\n lat=lat_p,\n ),\n centered=True,\n)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Display FSLE\n------------\n\n" + "## Display FSLE\n\n" ] }, { @@ -141,7 +141,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Display Theta\n-------------\n\n" + "## Display Theta\n\n" ] }, { @@ -172,7 +172,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.10.6" } }, "nbformat": 4, diff --git a/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb b/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb index bd197c57..708d7024 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_lavd_detection.ipynb @@ -84,7 +84,7 @@ }, "outputs": [], "source": [ - "# Time properties, for example with advection only 25 days\nnb_days, step_by_day = 25, 6\nnb_time = step_by_day * nb_days\nkw_p = dict(nb_step=1, time_step=86400 / step_by_day)\nt0 = 20236\nt0_grid = c[t0]\n# Geographic properties, we use a coarser resolution for time consuming reasons\nstep = 1 / 32.0\nx_g, y_g = arange(-6, 36, step), arange(30, 46, step)\nx0, y0 = meshgrid(x_g, y_g)\noriginal_shape = x0.shape\nx0, y0 = x0.reshape(-1), y0.reshape(-1)\n# Get all particles in defined area\nm = ~isnan(t0_grid.interp(\"vort\", x0, y0))\nx0, y0 = x0[m], y0[m]\nprint(f\"{x0.size} particles advected\")\n# Gridded mask\nm = m.reshape(original_shape)" + "# Time properties, for example with advection only 25 days\nnb_days, step_by_day = 25, 6\nnb_time = step_by_day * nb_days\nkw_p = dict(nb_step=1, time_step=86400 / step_by_day, u_name=\"u\", v_name=\"v\")\nt0 = 20236\nt0_grid = c[t0]\n# Geographic properties, we use a coarser resolution for time consuming reasons\nstep = 1 / 32.0\nx_g, y_g = arange(-6, 36, step), arange(30, 46, step)\nx0, y0 = meshgrid(x_g, y_g)\noriginal_shape = x0.shape\nx0, y0 = x0.reshape(-1), y0.reshape(-1)\n# Get all particles in defined area\nm = ~isnan(t0_grid.interp(\"vort\", x0, y0))\nx0, y0 = x0[m], y0[m]\nprint(f\"{x0.size} particles advected\")\n# Gridded mask\nm = m.reshape(original_shape)" ] }, { @@ -102,7 +102,7 @@ }, "outputs": [], "source": [ - "lavd = zeros(original_shape)\nlavd_ = lavd[m]\np = c.advect(x0.copy(), y0.copy(), \"u\", \"v\", t_init=t0, **kw_p)\nfor _ in range(nb_time):\n t, x, y = p.__next__()\n lavd_ += abs(c.interp(\"vort\", t / 86400.0, x, y))\nlavd[m] = lavd_ / nb_time\n# Put LAVD result in a standard py eddy tracker grid\nlavd_forward = LAVDGrid.from_(x_g, y_g, ma.array(lavd, mask=~m).T)\n# Display\nfig, ax, _ = start_ax(\"LAVD with a forward advection\")\nmappable = lavd_forward.display(ax, \"lavd\", **kw_lavd)\n_ = update_axes(ax, mappable)" + "lavd = zeros(original_shape)\nlavd_ = lavd[m]\np = c.advect(x0.copy(), y0.copy(), t_init=t0, **kw_p)\nfor _ in range(nb_time):\n t, x, y = p.__next__()\n lavd_ += abs(c.interp(\"vort\", t / 86400.0, x, y))\nlavd[m] = lavd_ / nb_time\n# Put LAVD result in a standard py eddy tracker grid\nlavd_forward = LAVDGrid.from_(x_g, y_g, ma.array(lavd, mask=~m).T)\n# Display\nfig, ax, _ = start_ax(\"LAVD with a forward advection\")\nmappable = lavd_forward.display(ax, \"lavd\", **kw_lavd)\n_ = update_axes(ax, mappable)" ] }, { @@ -120,7 +120,7 @@ }, "outputs": [], "source": [ - "lavd = zeros(original_shape)\nlavd_ = lavd[m]\np = c.advect(x0.copy(), y0.copy(), \"u\", \"v\", t_init=t0, backward=True, **kw_p)\nfor i in range(nb_time):\n t, x, y = p.__next__()\n lavd_ += abs(c.interp(\"vort\", t / 86400.0, x, y))\nlavd[m] = lavd_ / nb_time\n# Put LAVD result in a standard py eddy tracker grid\nlavd_backward = LAVDGrid.from_(x_g, y_g, ma.array(lavd, mask=~m).T)\n# Display\nfig, ax, _ = start_ax(\"LAVD with a backward advection\")\nmappable = lavd_backward.display(ax, \"lavd\", **kw_lavd)\n_ = update_axes(ax, mappable)" + "lavd = zeros(original_shape)\nlavd_ = lavd[m]\np = c.advect(x0.copy(), y0.copy(), t_init=t0, backward=True, **kw_p)\nfor i in range(nb_time):\n t, x, y = p.__next__()\n lavd_ += abs(c.interp(\"vort\", t / 86400.0, x, y))\nlavd[m] = lavd_ / nb_time\n# Put LAVD result in a standard py eddy tracker grid\nlavd_backward = LAVDGrid.from_(x_g, y_g, ma.array(lavd, mask=~m).T)\n# Display\nfig, ax, _ = start_ax(\"LAVD with a backward advection\")\nmappable = lavd_backward.display(ax, \"lavd\", **kw_lavd)\n_ = update_axes(ax, mappable)" ] }, { @@ -138,7 +138,7 @@ }, "outputs": [], "source": [ - "lavd = zeros(original_shape)\nlavd_ = lavd[m]\np = t0_grid.advect(x0.copy(), y0.copy(), \"u\", \"v\", **kw_p)\nfor _ in range(nb_time):\n x, y = p.__next__()\n lavd_ += abs(t0_grid.interp(\"vort\", x, y))\nlavd[m] = lavd_ / nb_time\n# Put LAVD result in a standard py eddy tracker grid\nlavd_forward_static = LAVDGrid.from_(x_g, y_g, ma.array(lavd, mask=~m).T)\n# Display\nfig, ax, _ = start_ax(\"LAVD with a forward advection on a static velocity field\")\nmappable = lavd_forward_static.display(ax, \"lavd\", **kw_lavd)\n_ = update_axes(ax, mappable)" + "lavd = zeros(original_shape)\nlavd_ = lavd[m]\np = t0_grid.advect(x0.copy(), y0.copy(), **kw_p)\nfor _ in range(nb_time):\n x, y = p.__next__()\n lavd_ += abs(t0_grid.interp(\"vort\", x, y))\nlavd[m] = lavd_ / nb_time\n# Put LAVD result in a standard py eddy tracker grid\nlavd_forward_static = LAVDGrid.from_(x_g, y_g, ma.array(lavd, mask=~m).T)\n# Display\nfig, ax, _ = start_ax(\"LAVD with a forward advection on a static velocity field\")\nmappable = lavd_forward_static.display(ax, \"lavd\", **kw_lavd)\n_ = update_axes(ax, mappable)" ] }, { @@ -156,7 +156,7 @@ }, "outputs": [], "source": [ - "lavd = zeros(original_shape)\nlavd_ = lavd[m]\np = t0_grid.advect(x0.copy(), y0.copy(), \"u\", \"v\", backward=True, **kw_p)\nfor i in range(nb_time):\n x, y = p.__next__()\n lavd_ += abs(t0_grid.interp(\"vort\", x, y))\nlavd[m] = lavd_ / nb_time\n# Put LAVD result in a standard py eddy tracker grid\nlavd_backward_static = LAVDGrid.from_(x_g, y_g, ma.array(lavd, mask=~m).T)\n# Display\nfig, ax, _ = start_ax(\"LAVD with a backward advection on a static velocity field\")\nmappable = lavd_backward_static.display(ax, \"lavd\", **kw_lavd)\n_ = update_axes(ax, mappable)" + "lavd = zeros(original_shape)\nlavd_ = lavd[m]\np = t0_grid.advect(x0.copy(), y0.copy(), backward=True, **kw_p)\nfor i in range(nb_time):\n x, y = p.__next__()\n lavd_ += abs(t0_grid.interp(\"vort\", x, y))\nlavd[m] = lavd_ / nb_time\n# Put LAVD result in a standard py eddy tracker grid\nlavd_backward_static = LAVDGrid.from_(x_g, y_g, ma.array(lavd, mask=~m).T)\n# Display\nfig, ax, _ = start_ax(\"LAVD with a backward advection on a static velocity field\")\nmappable = lavd_backward_static.display(ax, \"lavd\", **kw_lavd)\n_ = update_axes(ax, mappable)" ] }, { @@ -194,7 +194,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.9" + "version": "3.10.6" } }, "nbformat": 4, diff --git a/notebooks/python_module/07_cube_manipulation/pet_particles_drift.ipynb b/notebooks/python_module/07_cube_manipulation/pet_particles_drift.ipynb index 53365ac7..b92c4d21 100644 --- a/notebooks/python_module/07_cube_manipulation/pet_particles_drift.ipynb +++ b/notebooks/python_module/07_cube_manipulation/pet_particles_drift.ipynb @@ -44,7 +44,7 @@ }, "outputs": [], "source": [ - "c = GridCollection.from_netcdf_cube(\n get_demo_path(\"dt_med_allsat_phy_l4_2005T2.nc\"),\n \"longitude\",\n \"latitude\",\n \"time\",\n heigth=\"adt\",\n)" + "c = GridCollection.from_netcdf_cube(\n get_demo_path(\"dt_med_allsat_phy_l4_2005T2.nc\"),\n \"longitude\",\n \"latitude\",\n \"time\",\n unset=True\n)" ] }, { @@ -80,7 +80,7 @@ }, "outputs": [], "source": [ - "x0, y0 = meshgrid(arange(32, 35, 0.5), arange(32.5, 34.5, 0.5))\nx0, y0 = x0.reshape(-1), y0.reshape(-1)\nt, x, y = c.path(x0, y0, \"u\", \"v\", t_init=t0, **kw_p, nb_time=nb_time)" + "x0, y0 = meshgrid(arange(32, 35, 0.5), arange(32.5, 34.5, 0.5))\nx0, y0 = x0.reshape(-1), y0.reshape(-1)\nt, x, y = c.path(x0, y0, h_name=\"adt\", t_init=t0, **kw_p, nb_time=nb_time)" ] }, { @@ -118,7 +118,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.7" + "version": "3.10.6" } }, "nbformat": 4, diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index d363a5dd..b0bb7bbf 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -84,7 +84,7 @@ def advect(x, y, c, t0, n_days, u_name="u", v_name="v"): if n_days < 0: kw["backward"] = True n_days = -n_days - p = c.advect(x, y, u_name, v_name, t_init=t0, **kw) + p = c.advect(x, y, u_name=u_name, v_name=v_name, t_init=t0, **kw) for _ in range(n_days): t, x, y = p.__next__() return t, x, y From 1b2c4c78c572384042a16ddd86791e331727a8e2 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Thu, 13 Oct 2022 10:47:53 +0200 Subject: [PATCH 211/249] Add wrapping longitude test --- tests/test_generic.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tests/test_generic.py b/tests/test_generic.py index ab3832cc..29cb64b7 100644 --- a/tests/test_generic.py +++ b/tests/test_generic.py @@ -1,6 +1,6 @@ from numpy import arange, array, nan, ones, zeros -from py_eddy_tracker.generic import cumsum_by_track, simplify +from py_eddy_tracker.generic import cumsum_by_track, simplify, wrap_longitude def test_simplify(): @@ -30,3 +30,22 @@ def test_cumsum_by_track(): a = ones(10, dtype="i4") * 2 track = array([1, 1, 2, 2, 2, 2, 44, 44, 44, 48]) assert (cumsum_by_track(a, track) == [2, 4, 2, 4, 6, 8, 2, 4, 6, 2]).all() + + +def test_wrapping(): + y = x = arange(-5,5, dtype='f4') + x_, _ = wrap_longitude(x, y, ref=-10) + assert (x_ == x).all() + x_, _ = wrap_longitude(x, y, ref=1) + assert x.size == x_.size + assert (x_[6:] == x[6:]).all() + assert (x_[:6] == x[:6] + 360).all() + x_, _ = wrap_longitude(x, y, ref=1, cut=True) + assert x.size + 3 == x_.size + assert (x_[6 + 3:] == x[6:]).all() + assert (x_[:7] == x[:7] + 360).all() + + # FIXME Need evolution in wrap_longitude + # x %= 360 + # x_, _ = wrap_longitude(x, y, ref=-10, cut=True) + # assert x.size == x_.size From c7fbbd7636650fcc1dc57077c8b9e988a34e9f69 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Thu, 13 Oct 2022 10:48:25 +0200 Subject: [PATCH 212/249] Add hybrid method and speed up union method --- src/py_eddy_tracker/poly.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index 6adb02c1..deabd3ea 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -431,7 +431,7 @@ def merge(x, y): return concatenate(x), concatenate(y) -def vertice_overlap(x0, y0, x1, y1, minimal_area=False, p1_area=False): +def vertice_overlap(x0, y0, x1, y1, minimal_area=False, p1_area=False, hybrid_area=False, min_overlap=0): r""" Return percent of overlap for each item. @@ -441,6 +441,9 @@ def vertice_overlap(x0, y0, x1, y1, minimal_area=False, p1_area=False): :param array y1: y for polygon list 1 :param bool minimal_area: If True, function will compute intersection/little polygon, else intersection/union :param bool p1_area: If True, function will compute intersection/p1 polygon, else intersection/union + :param bool hybrid_area: If True, function will compute like union, + but if cost is under min_overlap, obs is kept in case of fully included + :param float min_overlap: under this value cost is set to zero :return: Result of cost function :rtype: array @@ -466,14 +469,25 @@ def vertice_overlap(x0, y0, x1, y1, minimal_area=False, p1_area=False): # Area of intersection intersection = (p0 & p1).area() # we divide intersection with the little one result from 0 to 1 + if intersection == 0: + cost[i] = 0 + continue + p0_area_, p1_area_ = p0.area(), p1.area() if minimal_area: - cost[i] = intersection / min(p0.area(), p1.area()) + cost_ = intersection / min(p0_area_, p1_area_) # we divide intersection with p1 elif p1_area: - cost[i] = intersection / p1.area() + cost_ = intersection / p1_area_ # we divide intersection with polygon merging result from 0 to 1 else: - cost[i] = intersection / (p0 + p1).area() + cost_ = intersection / (p0_area_ + p1_area_ - intersection) + if cost_ >= min_overlap: + cost[i] = cost_ + else: + if hybrid_area and cost_ != 0 and (intersection / min(p0_area_, p1_area_)) > .99: + cost[i] = cost_ + else: + cost[i] = 0 return cost From 66f9905f2894b191a1bb9e05e3071c1adc508db3 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Thu, 13 Oct 2022 10:51:43 +0200 Subject: [PATCH 213/249] Remove reference to obs or observation to be easily replace by store later --- src/py_eddy_tracker/observations/groups.py | 11 +++---- .../observations/observation.py | 31 +++++++++---------- src/py_eddy_tracker/observations/tracking.py | 18 +++++------ 3 files changed, 27 insertions(+), 33 deletions(-) diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index b0bb7bbf..54ae013c 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -292,15 +292,14 @@ def filled_by_interpolation(self, mask): nb_obs = len(self) index = arange(nb_obs) - for field in self.obs.dtype.descr: - var = field[0] + for field in self.fields: if ( - var in ["n", "virtual", "track", "cost_association"] - or var in self.array_variables + field in ["n", "virtual", "track", "cost_association"] + or field in self.array_variables ): continue - self.obs[var][mask] = interp( - index[mask], index[~mask], self.obs[var][~mask] + self.obs[field][mask] = interp( + index[mask], index[~mask], self.obs[field][~mask] ) def insert_virtual(self): diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index ae95315e..29fcf434 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -264,7 +264,7 @@ def get_infos(self): bins_lat=(-90, -60, -15, 15, 60, 90), bins_amplitude=array((0, 1, 2, 3, 4, 5, 10, 500)), bins_radius=array((0, 15, 30, 45, 60, 75, 100, 200, 2000)), - nb_obs=self.observations.shape[0], + nb_obs=len(self), ) t0, t1 = self.period infos["t0"], infos["t1"] = t0, t1 @@ -341,7 +341,7 @@ def __repr__(self): bins_lat = (-90, -60, -15, 15, 60, 90) bins_amplitude = array((0, 1, 2, 3, 4, 5, 10, 500)) bins_radius = array((0, 15, 30, 45, 60, 75, 100, 200, 2000)) - nb_obs = self.observations.shape[0] + nb_obs = len(self) return f""" | {nb_obs} observations from {t0} to {t1} ({period} days, ~{nb_obs / period:.0f} obs/day) | Speed area : {self.speed_area.sum() / period / 1e12:.2f} Mkm²/day @@ -416,7 +416,7 @@ def remove_fields(self, *fields): """ Copy with fields listed remove """ - nb_obs = self.obs.shape[0] + nb_obs = len(self) fields = set(fields) only_variables = set(self.fields) - fields track_extra_variables = set(self.track_extra_variables) - fields @@ -439,7 +439,7 @@ def add_fields(self, fields=list(), array_fields=list()): """ Add a new field. """ - nb_obs = self.obs.shape[0] + nb_obs = len(self) new = self.__class__( size=nb_obs, track_extra_variables=list( @@ -547,9 +547,9 @@ def merge(self, other): nb_obs_self = len(self) nb_obs = nb_obs_self + len(other) eddies = self.new_like(self, nb_obs) - other_keys = other.obs.dtype.fields.keys() - self_keys = self.obs.dtype.fields.keys() - for key in eddies.obs.dtype.fields.keys(): + other_keys = other.fields + self_keys = self.fields + for key in eddies.fields: eddies.obs[key][:nb_obs_self] = self.obs[key][:] if key in other_keys: eddies.obs[key][nb_obs_self:] = other.obs[key][:] @@ -657,8 +657,8 @@ def insert_observations(self, other, index): """Insert other obs in self at the given index.""" if not self.coherence(other): raise Exception("Observations with no coherence") - insert_size = len(other.obs) - self_size = len(self.obs) + insert_size = len(other) + self_size = len(self) new_size = self_size + insert_size if self_size == 0: self.observations = other.obs @@ -1542,8 +1542,7 @@ def to_zarr(self, handler, **kwargs): handler.attrs["track_array_variables"] = self.track_array_variables handler.attrs["array_variables"] = ",".join(self.array_variables) # Iter on variables to create: - fields = [field[0] for field in self.observations.dtype.descr] - for ori_name in fields: + for ori_name in self.fields: # Patch for a transition name = ori_name # @@ -1588,12 +1587,11 @@ def to_netcdf(self, handler, **kwargs): handler.track_array_variables = self.track_array_variables handler.array_variables = ",".join(self.array_variables) # Iter on variables to create: - fields = [field[0] for field in self.observations.dtype.descr] fields_ = array( - [VAR_DESCR[field[0]]["nc_name"] for field in self.observations.dtype.descr] + [VAR_DESCR[field]["nc_name"] for field in self.fields] ) i = fields_.argsort() - for ori_name in array(fields)[i]: + for ori_name in array(self.fields)[i]: # Patch for a transition name = ori_name # @@ -1865,10 +1863,9 @@ def extract_with_mask(self, mask): if nb_obs == 0: logger.warning("Empty dataset will be created") else: - for field in self.obs.dtype.descr: + for field in self.fields: logger.debug("Copy of field %s ...", field) - var = field[0] - new.obs[var] = self.obs[var][mask] + new.obs[field] = self.obs[field][mask] return new def scatter(self, ax, name=None, ref=None, factor=1, **kwargs): diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index f1d2399b..4e0f9bcd 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -118,7 +118,7 @@ def __repr__(self): t0, t1 = self.period period = t1 - t0 + 1 nb = self.nb_obs_by_track - nb_obs = self.observations.shape[0] + nb_obs = len(self) m = self.virtual.astype("bool") nb_m = m.sum() bins_t = (1, 30, 90, 180, 270, 365, 1000, 10000) @@ -147,7 +147,7 @@ def __repr__(self): def add_distance(self): """Add a field of distance (m) between two consecutive observations, 0 for the last observation of each track""" - if "distance_next" in self.observations.dtype.descr: + if "distance_next" in self.fields: return self new = self.add_fields(("distance_next",)) new["distance_next"][:1] = self.distance_to_next() @@ -205,10 +205,9 @@ def extract_longer_eddies(self, nb_min, nb_obs, compress_id=True): logger.info("Selection of %d observations", nb_obs_select) eddies = self.__class__.new_like(self, nb_obs_select) eddies.sign_type = self.sign_type - for field in self.obs.dtype.descr: + for field in self.fields: logger.debug("Copy of field %s ...", field) - var = field[0] - eddies.obs[var] = self.obs[var][mask] + eddies.obs[field] = self.obs[field][mask] if compress_id: list_id = unique(eddies.obs.track) list_id.sort() @@ -387,13 +386,13 @@ def extract_toward_direction(self, west=True, delta_lon=None): def extract_first_obs_in_box(self, res): data = empty( - self.obs.shape, dtype=[("lon", "f4"), ("lat", "f4"), ("track", "i4")] + len(self), dtype=[("lon", "f4"), ("lat", "f4"), ("track", "i4")] ) data["lon"] = self.longitude - self.longitude % res data["lat"] = self.latitude - self.latitude % res data["track"] = self.track _, indexs = unique(data, return_index=True) - mask = zeros(self.obs.shape, dtype="bool") + mask = zeros(len(self), dtype="bool") mask[indexs] = True return self.extract_with_mask(mask) @@ -508,10 +507,9 @@ def extract_with_mask( if nb_obs == 0: logger.info("Empty dataset will be created") else: - for field in self.obs.dtype.descr: + for field in self.fields: logger.debug("Copy of field %s ...", field) - var = field[0] - new.obs[var] = self.obs[var][mask] + new.obs[field] = self.obs[field][mask] if compress_id: list_id = unique(new.track) list_id.sort() From 3e73e63adc6c71e3f040bfbb3d9f4e7e234eb05e Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Thu, 13 Oct 2022 10:56:18 +0200 Subject: [PATCH 214/249] Add hybrid method in appli --- src/py_eddy_tracker/appli/network.py | 13 +++++++++++- src/py_eddy_tracker/observations/network.py | 21 +++++++------------- src/py_eddy_tracker/observations/tracking.py | 12 ++++------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index 03c5eb35..f488168e 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -36,6 +36,11 @@ def build_network(): action="store_true", help="If True, use intersection/little polygon, else intersection/union", ) + parser.add_argument( + "--hybrid-area", + action="store_true", + help="If True, use minimal-area method if overlap is under min overlap, else intersection/union", + ) parser.contour_intern_arg() @@ -49,7 +54,7 @@ def build_network(): memory=args.memory, ) group = n.group_observations( - min_overlap=args.min_overlap, minimal_area=args.minimal_area + min_overlap=args.min_overlap, minimal_area=args.minimal_area, hybrid_area=args.hybrid_area ) n.build_dataset(group).write_file(filename=args.out) @@ -74,6 +79,11 @@ def divide_network(): action="store_true", help="If True, use intersection/little polygon, else intersection/union", ) + parser.add_argument( + "--hybrid-area", + action="store_true", + help="If True, use minimal-area method if overlap is under min overlap, else intersection/union", + ) args = parser.parse_args() contour_name = TrackEddiesObservations.intern(args.intern, public_label=True) e = TrackEddiesObservations.load_file( @@ -87,6 +97,7 @@ def divide_network(): window=args.window, min_overlap=args.min_overlap, minimal_area=args.minimal_area, + hybrid_area=args.hybrid_area ), ) n.write_file(filename=args.out) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 604035e4..c395bd8d 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -1913,21 +1913,14 @@ def group_translator(nb, duos): apply_replace(translate, gr_i, gr_j) return translate - def group_observations(self, min_overlap=0.2, minimal_area=False): + def group_observations(self, min_overlap=0.2, minimal_area=False, **kwargs): """Store every interaction between identifications - Parameters - ---------- - minimal_area : bool, optional - If True, function will compute intersection/little polygon, else intersection/union, by default False + :param bool minimal_area: If True, function will compute intersection/little polygon, else intersection/union, by default False + :param float min_overlap: minimum overlap area to associate observations, by default 0.2 - min_overlap : float, optional - minimum overlap area to associate observations, by default 0.2 - - Returns - ------- - TrackEddiesObservations - netcdf with interactions + :return: + :rtype: TrackEddiesObservations """ results, nb_obs = list(), list() @@ -1945,9 +1938,9 @@ def group_observations(self, min_overlap=0.2, minimal_area=False): ii, ij = bbox_intersection(xi, yi, xj, yj) m = ( vertice_overlap( - xi[ii], yi[ii], xj[ij], yj[ij], minimal_area=minimal_area + xi[ii], yi[ii], xj[ij], yj[ij], minimal_area=minimal_area, min_overlap=min_overlap, **kwargs ) - > min_overlap + != 0 ) results.append((i, j, ii[m], ij[m])) if display_iteration: diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index 4e0f9bcd..4d155605 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -720,7 +720,7 @@ def get_previous_obs( time_ref, window, min_overlap=0.2, - minimal_area=False, + **kwargs, ): """Backward association of observations to the segments""" time_cur = int_(ids["time"][i_current]) @@ -737,10 +737,8 @@ def get_previous_obs( continue c = zeros(len(xj)) c[ij] = vertice_overlap( - xi[ii], yi[ii], xj[ij], yj[ij], minimal_area=minimal_area + xi[ii], yi[ii], xj[ij], yj[ij], min_overlap=min_overlap, **kwargs ) - # We remove low overlap - c[c < min_overlap] = 0 # We get index of maximal overlap i = c.argmax() c_i = c[i] @@ -762,7 +760,7 @@ def get_next_obs( time_ref, window, min_overlap=0.2, - minimal_area=False, + **kwargs ): """Forward association of observations to the segments""" time_max = time_e.shape[0] - 1 @@ -782,10 +780,8 @@ def get_next_obs( continue c = zeros(len(xj)) c[ij] = vertice_overlap( - xi[ii], yi[ii], xj[ij], yj[ij], minimal_area=minimal_area + xi[ii], yi[ii], xj[ij], yj[ij], min_overlap=min_overlap, **kwargs ) - # We remove low overlap - c[c < min_overlap] = 0 # We get index of maximal overlap i = c.argmax() c_i = c[i] From 943bbf3730b6192a3aa3c3f9106e5c94adc94269 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Thu, 13 Oct 2022 11:01:44 +0200 Subject: [PATCH 215/249] Rewrite method to extract event for speed up --- src/py_eddy_tracker/observations/network.py | 236 +++++++++++--------- 1 file changed, 133 insertions(+), 103 deletions(-) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index c395bd8d..65b9e636 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -113,6 +113,20 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.reset_index() + def __repr__(self): + m_event, s_event = self.merging_event(only_index=True, triplet=True)[0], self.splitting_event(only_index=True, triplet=True)[0] + period = (self.period[1] - self.period[0]) / 365.25 + nb_by_network = self.network_size() + big = 50_000 + infos = [ + f"Atlas with {self.nb_network} networks ({self.nb_network / period:0.0f} networks/year)," + f" {self.nb_segment} segments ({self.nb_segment / period:0.0f} segments/year), {len(self)} observations ({len(self) / period:0.0f} observations/year)", + f" {m_event.size} merging ({m_event.size / period:0.0f} merging/year), {s_event.size} splitting ({s_event.size / period:0.0f} splitting/year)", + f" with {(nb_by_network > big).sum()} network with more than {big} obs and the biggest have {nb_by_network.max()} observations ({nb_by_network[nb_by_network> big].sum()} observations cumulate)", + f" {nb_by_network[0]} observations in trash" + ] + return "\n".join(infos) + def reset_index(self): self._index_network = None self._index_segment_track = None @@ -313,13 +327,19 @@ def correct_close_events(self, nb_days_max=20): """ Transform event where segment A splits from segment B, then x days after segment B merges with A - to - segment A splits from segment B then x days after segment A merges with B (B will be longer) - These events have to last less than `nb_days_max` to be changed. + + ------------------- A + / / + B -------------------- + to + --A-- + / \ + B ----------------------------------- + :param float nb_days_max: maximum time to search for splitting-merging event """ @@ -342,7 +362,7 @@ def correct_close_events(self, nb_days_max=20): segments_connexion[seg] = [i, i_p, i_n] for seg in sorted(segments_connexion.keys()): - seg_slice, i_seg_p, i_seg_n = segments_connexion[seg] + seg_slice, _, i_seg_n = segments_connexion[seg] # the segment ID has to be corrected, because we may have changed it since seg_corrected = segment[seg_slice.stop - 1] @@ -370,8 +390,6 @@ def correct_close_events(self, nb_days_max=20): segments_connexion[seg_corrected][0] = my_slice - self.segment[:] = segment_copy - self.previous_obs[:] = previous_obs return self.sort() def sort(self, order=("track", "segment", "time")): @@ -495,8 +513,10 @@ def func_backward(seg, indice): return self.extract_with_mask(mask) def connexions(self, multi_network=False): - """ - Create dictionnary for each segment, gives the segments in interaction with + """Create dictionnary for each segment, gives the segments in interaction with + + :param bool multi_network: use segment_track_array instead of segment, defaults to False + :return dict: Return dict of set, for each seg id we get set of segment which have event with him """ if multi_network: segment = self.segment_track_array @@ -504,26 +524,27 @@ def connexions(self, multi_network=False): self.only_one_network() segment = self.segment segments_connexion = dict() - - def add_seg(father, child): - if father not in segments_connexion: - segments_connexion[father] = set() - segments_connexion[father].add(child) - - previous_obs, next_obs = self.previous_obs, self.next_obs - for i, seg, _ in self.iter_on(segment): - if i.start == i.stop: - continue - i_p, i_n = previous_obs[i.start], next_obs[i.stop - 1] - # segment in interaction - p_seg, n_seg = segment[i_p], segment[i_n] - # Where segment are called - if i_p != -1: - add_seg(p_seg, seg) - add_seg(seg, p_seg) - if i_n != -1: - add_seg(n_seg, seg) - add_seg(seg, n_seg) + def add_seg(s1, s2): + if s1 not in segments_connexion: + segments_connexion[s1] = set() + if s2 not in segments_connexion: + segments_connexion[s2] = set() + segments_connexion[s1].add(s2), segments_connexion[s2].add(s1) + # Get index for each segment + i0, i1, _ = self.index_segment_track + i1 = i1 - 1 + # Check if segment merge + i_next = self.next_obs[i1] + m_n = i_next != -1 + # Check if segment come from splitting + i_previous = self.previous_obs[i0] + m_p = i_previous != -1 + # For each split + for s1, s2 in zip(segment[i_previous[m_p]], segment[i0[m_p]]): + add_seg(s1, s2) + # For each merge + for s1, s2 in zip(segment[i_next[m_n]], segment[i1[m_n]]): + add_seg(s1, s2) return segments_connexion @classmethod @@ -1089,34 +1110,22 @@ def segment_track_array(self): return self._segment_track_array def birth_event(self): - """Extract birth events. - Advice : individual eddies (self.track == 0) should be removed before -> apply remove_trash.""" - # FIXME how to manage group 0 - indices = list() - previous_obs = self.previous_obs - for i, _, _ in self.iter_on(self.segment_track_array): - nb = i.stop - i.start - if nb == 0: - continue - i_p = previous_obs[i.start] - if i_p == -1: - indices.append(i.start) - return self.extract_event(list(set(indices))) + """Extract birth events.""" + i_start, _, _ = self.index_segment_track + indices = i_start[self.previous_obs[i_start] == -1] + if self.first_is_trash(): + indices = indices[1:] + return self.extract_event(indices) + generation_event = birth_event def death_event(self): - """Extract death events. - Advice : individual eddies (self.track == 0) should be removed before -> apply remove_trash.""" - # FIXME how to manage group 0 - indices = list() - next_obs = self.next_obs - for i, _, _ in self.iter_on(self.segment_track_array): - nb = i.stop - i.start - if nb == 0: - continue - i_n = next_obs[i.stop - 1] - if i_n == -1: - indices.append(i.stop - 1) - return self.extract_event(list(set(indices))) + """Extract death events.""" + _, i_stop, _ = self.index_segment_track + indices = i_stop[self.next_obs[i_stop - 1] == -1] - 1 + if self.first_is_trash(): + indices = indices[1:] + return self.extract_event(indices) + dissipation_event = death_event def merging_event(self, triplet=False, only_index=False): """Return observation after a merging event. @@ -1124,25 +1133,26 @@ def merging_event(self, triplet=False, only_index=False): If `triplet=True` return the eddy after a merging event, the eddy before the merging event, and the eddy stopped due to merging. """ - idx_m1 = list() + # Get start and stop for each segment, there is no empty segment + _, i1, _ = self.index_segment_track + # Get last index for each segment + i_stop = i1 - 1 + # Get target index + idx_m1 = self.next_obs[i_stop] + # Get mask and valid target + m = idx_m1 != -1 + idx_m1 = idx_m1[m] + # Sort by time event + i = self.time[idx_m1].argsort() + idx_m1 = idx_m1[i] if triplet: - idx_m0_stop = list() - idx_m0 = list() - next_obs, previous_obs = self.next_obs, self.previous_obs - for i, _, _ in self.iter_on(self.segment_track_array): - nb = i.stop - i.start - if nb == 0: - continue - i_n = next_obs[i.stop - 1] - if i_n != -1: - if triplet: - idx_m0_stop.append(i.stop - 1) - idx_m0.append(previous_obs[i_n]) - idx_m1.append(i_n) + # Get obs before target + idx_m0_stop = i_stop[m][i] + idx_m0 = self.previous_obs[idx_m1].copy() if triplet: if only_index: - return array(idx_m1), array(idx_m0), array(idx_m0_stop) + return idx_m1, idx_m0, idx_m0_stop else: return ( self.extract_event(idx_m1), @@ -1150,7 +1160,7 @@ def merging_event(self, triplet=False, only_index=False): self.extract_event(idx_m0_stop), ) else: - idx_m1 = list(set(idx_m1)) + idx_m1 = unique(idx_m1) if only_index: return idx_m1 else: @@ -1162,25 +1172,24 @@ def splitting_event(self, triplet=False, only_index=False): If `triplet=True` return the eddy before a splitting event, the eddy after the splitting event, and the eddy starting due to splitting. """ - idx_s0 = list() + # Get start and stop for each segment, there is no empty segment + i_start, _, _ = self.index_segment_track + # Get target index + idx_s0 = self.previous_obs[i_start] + # Get mask and valid target + m = idx_s0 != -1 + idx_s0 = idx_s0[m] + # Sort by time event + i = self.time[idx_s0].argsort() + idx_s0 = idx_s0[i] if triplet: - idx_s1_start = list() - idx_s1 = list() - next_obs, previous_obs = self.next_obs, self.previous_obs - for i, _, _ in self.iter_on(self.segment_track_array): - nb = i.stop - i.start - if nb == 0: - continue - i_p = previous_obs[i.start] - if i_p != -1: - if triplet: - idx_s1_start.append(i.start) - idx_s1.append(next_obs[i_p]) - idx_s0.append(i_p) + # Get obs after target + idx_s1_start = i_start[m][i] + idx_s1 = self.next_obs[idx_s0].copy() if triplet: if only_index: - return array(idx_s0), array(idx_s1), array(idx_s1_start) + return idx_s0, idx_s1, idx_s1_start else: return ( self.extract_event(idx_s0), @@ -1189,7 +1198,7 @@ def splitting_event(self, triplet=False, only_index=False): ) else: - idx_s0 = list(set(idx_s0)) + idx_s0 = unique(idx_s0) if only_index: return idx_s0 else: @@ -1199,7 +1208,7 @@ def dissociate_network(self): """ Dissociate networks with no known interaction (splitting/merging) """ - tags = self.tag_segment(multi_network=True) + tags = self.tag_segment() if self.track[0] == 0: tags -= 1 self.track[:] = tags[self.segment_track_array] @@ -1345,16 +1354,22 @@ def __tag_segment(cls, seg, tag, groups, connexions): # For each connexion we apply same function cls.__tag_segment(seg, tag, groups, connexions) - def tag_segment(self, multi_network=False): - if multi_network: - nb = self.segment_track_array[-1] + 1 - else: - nb = self.segment.max() + 1 + def tag_segment(self): + """For each segment, method give a new network id, and all segment are connected + + :return array: for each unique seg id, it return new network id + """ + nb = self.segment_track_array[-1] + 1 sub_group = zeros(nb, dtype="u4") - c = self.connexions(multi_network=multi_network) + c = self.connexions(multi_network=True) j = 1 # for each available id for i in range(nb): + # No connexions, no need to explore + if i not in c: + sub_group[i] = j + j+= 1 + continue # Skip if already set if sub_group[i] != 0: continue @@ -1363,15 +1378,31 @@ def tag_segment(self, multi_network=False): j += 1 return sub_group + def fully_connected(self): + """Suspicious + """ + raise Exception("Must be check") self.only_one_network() return self.tag_segment().shape[0] == 1 + def first_is_trash(self): + """Check if first network is Trash + + :return bool: True if first network is trash + """ + i_start, i_stop, _ = self.index_segment_track + sl = slice(i_start[0], i_stop[0]) + return (self.previous_obs[sl] == -1).all() and (self.next_obs[sl] == -1).all() + def remove_trash(self): """ Remove the lonely eddies (only 1 obs in segment, associated network number is 0) """ - return self.extract_with_mask(self.track != 0) + if self.first_is_trash(): + return self.extract_with_mask(self.track != 0) + else: + return self def plot(self, ax, ref=None, color_cycle=None, **kwargs): """ @@ -1551,12 +1582,11 @@ def extract_with_mask(self, mask): logger.debug( f"{nb_obs} observations will be extracted ({nb_obs / self.shape[0]:.3%})" ) - for field in self.obs.dtype.descr: + for field in self.fields: if field in ("next_obs", "previous_obs"): continue logger.debug("Copy of field %s ...", field) - var = field[0] - new.obs[var] = self.obs[var][mask] + new.obs[field] = self.obs[field][mask] # n & p must be re-index n, p = self.next_obs[mask], self.previous_obs[mask] # we add 2 for -1 index return index -1 @@ -1682,9 +1712,9 @@ def date2file(julian_day): return f"/tmp/dt_global_{date.strftime('%Y%m%d')}.nc" """ - - itb_final = -ones((self.obs.size, 2), dtype="i4") - ptb_final = zeros((self.obs.size, 2), dtype="i1") + shape = len(self), 2 + itb_final = -ones(shape, dtype="i4") + ptb_final = zeros(shape, dtype="i1") t_start, t_end = int(self.period[0]), int(self.period[1]) @@ -1760,9 +1790,9 @@ def date2file(julian_day): return f"/tmp/dt_global_{date.strftime('%Y%m%d')}.nc" """ - - itf_final = -ones((self.obs.size, 2), dtype="i4") - ptf_final = zeros((self.obs.size, 2), dtype="i1") + shape = len(self), 2 + itf_final = -ones(shape, dtype="i4") + ptf_final = zeros(shape, dtype="i1") t_start, t_end = int(self.period[0]), int(self.period[1]) From 3359edaf1b2df21ab61d16297560cd9e42406629 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Thu, 13 Oct 2022 11:02:25 +0200 Subject: [PATCH 216/249] Add ref in display_color --- src/py_eddy_tracker/generic.py | 10 ++++++---- src/py_eddy_tracker/observations/observation.py | 12 +++++++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/py_eddy_tracker/generic.py b/src/py_eddy_tracker/generic.py index 7dbbf3c3..fbc17d07 100644 --- a/src/py_eddy_tracker/generic.py +++ b/src/py_eddy_tracker/generic.py @@ -456,17 +456,18 @@ def wrap_longitude(x, y, ref, cut=False): if cut: indexs = list() nb = x.shape[0] - new_previous = (x[0] - ref) % 360 + + new_x_previous = (x[0] - ref) % 360 + ref x_previous = x[0] for i in range(1, nb): x_ = x[i] - new_x = (x_ - ref) % 360 + new_x = (x_ - ref) % 360 + ref if not isnan(x_) and not isnan(x_previous): - d_new = new_x - new_previous + d_new = new_x - new_x_previous d = x_ - x_previous if abs(d - d_new) > 1e-5: indexs.append(i) - x_previous, new_previous = x_, new_x + x_previous, new_x_previous = x_, new_x nb_indexs = len(indexs) new_size = nb + nb_indexs * 3 @@ -477,6 +478,7 @@ def wrap_longitude(x, y, ref, cut=False): for i in range(nb): if j < nb_indexs and i == indexs[j]: j += 1 + # FIXME need check cor = 360 if x[i - 1] > x[i] else -360 out_x[i + i_] = (x[i] - ref) % 360 + ref - cor out_y[i + i_] = y[i] diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 29fcf434..2e4abef3 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -2069,11 +2069,12 @@ def format_label(self, label): nb_obs=len(self), ) - def display_color(self, ax, field, intern=False, **kwargs): + def display_color(self, ax, field, ref=None, intern=False, **kwargs): """Plot colored contour of eddies :param matplotlib.axes.Axes ax: matplotlib axe used to draw :param str,array field: color field + :param float,None ref: if defined, all coordinates are wrapped with ref as western boundary :param bool intern: if True, draw the speed contour :param dict kwargs: look at :py:meth:`matplotlib.collections.LineCollection` @@ -2081,6 +2082,13 @@ def display_color(self, ax, field, intern=False, **kwargs): """ xname, yname = self.intern(intern) x, y = self[xname], self[yname] + + if ref is not None: + # TODO : maybe buggy with global display + shape_out = x.shape + x, y = wrap_longitude(x.reshape(-1), y.reshape(-1), ref) + x, y = x.reshape(shape_out), y.reshape(shape_out) + c = self.parse_varname(field) cmap = get_cmap(kwargs.pop("cmap", "Spectral_r")) cmin, cmax = kwargs.pop("vmin", c.min()), kwargs.pop("vmax", c.max()) @@ -2089,6 +2097,8 @@ def display_color(self, ax, field, intern=False, **kwargs): [create_vertice(i, j) for i, j in zip(x, y)], colors=colors, **kwargs ) ax.add_collection(lines) + lines.cmap = cmap + lines.norm = Normalize(vmin=cmin, vmax=cmax) return lines def display(self, ax, ref=None, extern_only=False, intern_only=False, **kwargs): From 9d408e55d5e44a874cff8774d8f26c2b98163664 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Fri, 14 Oct 2022 09:36:40 +0200 Subject: [PATCH 217/249] Add moving window in iter_on, prepare tag 3.6.1 --- CHANGELOG.rst | 13 +++ src/py_eddy_tracker/observations/network.py | 4 +- .../observations/observation.py | 79 +++++++++++-------- src/py_eddy_tracker/observations/tracking.py | 3 - 4 files changed, 60 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b8cad2f4..76ec911d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -11,12 +11,25 @@ and this project adheres to `Semantic Versioning Date: Tue, 18 Oct 2022 14:57:26 +0200 Subject: [PATCH 218/249] Modify remove dead end speed up extract_segment --- CHANGELOG.rst | 2 + src/py_eddy_tracker/observations/network.py | 123 ++++++++++++-------- 2 files changed, 76 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 76ec911d..f8eee72f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -11,6 +11,8 @@ and this project adheres to `Semantic Versioning big).sum()} network with more than {big} obs and the biggest have {nb_by_network.max()} observations ({nb_by_network[nb_by_network> big].sum()} observations cumulate)", - f" {nb_by_network[0]} observations in trash" + f" {nb_trash} observations in trash" ] return "\n".join(infos) @@ -369,26 +370,29 @@ def correct_close_events(self, nb_days_max=20): # we keep the real segment number seg_corrected_copy = segment_copy[seg_slice.stop - 1] + if i_seg_n == -1: + continue + # if segment is split n_seg = segment[i_seg_n] - # if segment is split - if i_seg_n != -1: - seg2_slice, i2_seg_p, i2_seg_n = segments_connexion[n_seg] - p2_seg = segment[i2_seg_p] - - # if it merges on the first in a certain time - if (p2_seg == seg_corrected) and ( - _time[i_seg_n] - _time[i2_seg_p] < nb_days_max - ): - my_slice = slice(i_seg_n, seg2_slice.stop) - # correct the factice segment - segment[my_slice] = seg_corrected - # correct the good segment - segment_copy[my_slice] = seg_corrected_copy - previous_obs[i_seg_n] = seg_slice.stop - 1 - - segments_connexion[seg_corrected][0] = my_slice + seg2_slice, i2_seg_p, _ = segments_connexion[n_seg] + if i2_seg_p == -1: + continue + p2_seg = segment[i2_seg_p] + + # if it merges on the first in a certain time + if (p2_seg == seg_corrected) and ( + _time[i_seg_n] - _time[i2_seg_p] < nb_days_max + ): + my_slice = slice(i_seg_n, seg2_slice.stop) + # correct the factice segment + segment[my_slice] = seg_corrected + # correct the good segment + segment_copy[my_slice] = seg_corrected_copy + previous_obs[i_seg_n] = seg_slice.stop - 1 + + segments_connexion[seg_corrected][0] = my_slice return self.sort() @@ -789,6 +793,8 @@ def display_timeline( colors_mode=colors_mode, ) ) + if field is not None: + field = self.parse_varname(field) for i, b0, b1 in self.iter_on("segment"): x = self.time[i] if x.shape[0] == 0: @@ -797,9 +803,9 @@ def display_timeline( y = b0 * ones(x.shape) else: if method == "all": - y = self[field][i] * factor + y = field[i] * factor else: - y = self[field][i].mean() * ones(x.shape) * factor + y = field[i].mean() * ones(x.shape) * factor if colors_mode == "roll": _color = self.get_color(j) @@ -825,7 +831,7 @@ def event_timeline(self, ax, field=None, method=None, factor=1, colors_mode="rol if field is not None and method != "all": for i, b0, _ in self.iter_on("segment"): - y = self[field][i] + y = self.parse_varname(field)[i] if y.shape[0] != 0: y_seg[b0] = y.mean() * factor mappables = dict() @@ -851,7 +857,7 @@ def event_timeline(self, ax, field=None, method=None, factor=1, colors_mode="rol y0 = b0 else: if method == "all": - y0 = self[field][i.stop - 1] * factor + y0 = self.parse_varname(field)[i.stop - 1] * factor else: y0 = y_seg[b0] if i_n != -1: @@ -860,7 +866,7 @@ def event_timeline(self, ax, field=None, method=None, factor=1, colors_mode="rol seg_next if field is None else ( - self[field][i_n] * factor + self.parse_varname(field)[i_n] * factor if method == "all" else y_seg[seg_next] ) @@ -876,7 +882,7 @@ def event_timeline(self, ax, field=None, method=None, factor=1, colors_mode="rol seg_previous if field is None else ( - self[field][i_p] * factor + self.parse_varname(field)[i_p] * factor if method == "all" else y_seg[seg_previous] ) @@ -1446,35 +1452,54 @@ def remove_dead_end(self, nobs=3, ndays=0, recursive=0, mask=None): .. warning:: It will remove short segment that splits from then merges with the same segment """ - segments_keep = list() connexions = self.connexions(multi_network=True) - t = self.time - for i, b0, _ in self.iter_on(self.segment_track_array): - if mask and mask[i].any(): - segments_keep.append(b0) - continue - nb = i.stop - i.start - dt = t[i.stop - 1] - t[i.start] - if (nb < nobs or dt < ndays) and len(connexions.get(b0, tuple())) < 2: - continue - segments_keep.append(b0) + i0, i1, _ = self.index_segment_track + dt = self.time[i1 -1] - self.time[i0] + 1 + nb = i1 - i0 + m = (dt >= ndays) * (nb >= nobs) + nb_connexions = array([len(connexions.get(i, tuple())) for i in where(~m)[0]]) + m[~m] = nb_connexions >= 2 + segments_keep = where(m)[0] + if mask is not None: + segments_keep = unique(concatenate((segments_keep, self.segment_track_array[mask]))) + # get mask for selected obs + m = ~self.segment_mask(segments_keep) + self.track[m] = 0 + self.segment[m] = 0 + self.previous_obs[m] = -1 + self.previous_cost[m] = 0 + self.next_obs[m] = -1 + self.next_cost[m] = 0 + + m_previous = m[self.previous_obs] + self.previous_obs[m_previous] = -1 + self.previous_cost[m_previous] = 0 + m_next = m[self.next_obs] + self.next_obs[m_next] = -1 + self.next_cost[m_next] = 0 + + self.sort() if recursive > 0: - return self.extract_segment(segments_keep, absolute=True).remove_dead_end( - nobs, ndays, recursive - 1 - ) - return self.extract_segment(segments_keep, absolute=True) + self.remove_dead_end(nobs, ndays, recursive - 1) def extract_segment(self, segments, absolute=False): - mask = ones(self.shape, dtype="bool") - segments = array(segments) - values = self.segment_track_array if absolute else "segment" - keep = ones(values.max() + 1, dtype="bool") - v = unique(values) - keep[v] = in1d(v, segments) - for i, b0, b1 in self.iter_on(values): - if not keep[b0]: - mask[i] = False - return self.extract_with_mask(mask) + """Extract given segments + + :param array,tuple,list segments: list of segment to extract + :param bool absolute: keep for compatibility, defaults to False + :return NetworkObservations: Return observations from selected segment + """ + if not absolute: + raise Exception("Not implemented") + return self.extract_with_mask(self.segment_mask(segments)) + + def segment_mask(self, segments): + """Get mask from list of segment + + :param list,array segments: absolute id of segment + """ + return generate_mask_from_ids(array(segments), len(self), *self.index_segment_track) + def get_mask_with_period(self, period): """ From c455bc6e68a73cb4745eac157481bcb77760b012 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Tue, 18 Oct 2022 15:04:34 +0200 Subject: [PATCH 219/249] black & isort --- doc/conf.py | 14 +-- examples/06_grid_manipulation/pet_advect.py | 11 ++- examples/06_grid_manipulation/pet_lavd.py | 4 +- examples/07_cube_manipulation/pet_fsle_med.py | 4 +- .../pet_particles_drift.py | 4 +- examples/16_network/pet_follow_particle.py | 8 +- src/py_eddy_tracker/appli/network.py | 6 +- src/py_eddy_tracker/dataset/grid.py | 12 ++- src/py_eddy_tracker/observations/groups.py | 62 ++++++++++--- src/py_eddy_tracker/observations/network.py | 93 +++++++++++++------ .../observations/observation.py | 16 ++-- src/py_eddy_tracker/observations/tracking.py | 6 +- src/py_eddy_tracker/poly.py | 10 +- tests/test_generic.py | 4 +- 14 files changed, 181 insertions(+), 73 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index ccf26e4e..0844d585 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -96,9 +96,9 @@ master_doc = "index" # General information about the project. -project = u"py-eddy-tracker" -copyright = u"2019, A. Delepoulle & E. Mason" -author = u"A. Delepoulle & E. Mason" +project = "py-eddy-tracker" +copyright = "2019, A. Delepoulle & E. Mason" +author = "A. Delepoulle & E. Mason" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -272,8 +272,8 @@ ( master_doc, "py-eddy-tracker.tex", - u"py-eddy-tracker Documentation", - u"A. Delepoulle \\& E. Mason", + "py-eddy-tracker Documentation", + "A. Delepoulle \\& E. Mason", "manual", ), ] @@ -304,7 +304,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - (master_doc, "py-eddy-tracker", u"py-eddy-tracker Documentation", [author], 1) + (master_doc, "py-eddy-tracker", "py-eddy-tracker Documentation", [author], 1) ] # If true, show URL addresses after external links. @@ -320,7 +320,7 @@ ( master_doc, "py-eddy-tracker", - u"py-eddy-tracker Documentation", + "py-eddy-tracker Documentation", author, "py-eddy-tracker", "One line description of project.", diff --git a/examples/06_grid_manipulation/pet_advect.py b/examples/06_grid_manipulation/pet_advect.py index ab2a0e14..d7cc67e9 100644 --- a/examples/06_grid_manipulation/pet_advect.py +++ b/examples/06_grid_manipulation/pet_advect.py @@ -139,7 +139,9 @@ def update(i_frame, t_step): ) for time_step in (10800, 21600, 43200, 86400): x, y = x0.copy(), y0.copy() - kw_advect = dict(nb_step=int(50 * 86400 / time_step), time_step=time_step, u_name="u", v_name="v") + kw_advect = dict( + nb_step=int(50 * 86400 / time_step), time_step=time_step, u_name="u", v_name="v" + ) g.advect(x, y, **kw_advect).__next__() g.advect(x, y, **kw_advect, backward=True).__next__() d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5 @@ -158,7 +160,12 @@ def update(i_frame, t_step): time_step = 10800 for duration in (5, 50, 100): x, y = x0.copy(), y0.copy() - kw_advect = dict(nb_step=int(duration * 86400 / time_step), time_step=time_step, u_name="u", v_name="v") + kw_advect = dict( + nb_step=int(duration * 86400 / time_step), + time_step=time_step, + u_name="u", + v_name="v", + ) g.advect(x, y, **kw_advect).__next__() g.advect(x, y, **kw_advect, backward=True).__next__() d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5 diff --git a/examples/06_grid_manipulation/pet_lavd.py b/examples/06_grid_manipulation/pet_lavd.py index 639db99e..a3ea846e 100644 --- a/examples/06_grid_manipulation/pet_lavd.py +++ b/examples/06_grid_manipulation/pet_lavd.py @@ -110,7 +110,9 @@ def save(self, *args, **kwargs): step_by_day = 3 # Compute step of advection every 4h nb_step = 2 -kw_p = dict(nb_step=nb_step, time_step=86400 / step_by_day / nb_step, u_name="u", v_name="v") +kw_p = dict( + nb_step=nb_step, time_step=86400 / step_by_day / nb_step, u_name="u", v_name="v" +) # Start a generator which at each iteration return new position at next time step particule = g.advect(x, y, **kw_p, rk4=True) diff --git a/examples/07_cube_manipulation/pet_fsle_med.py b/examples/07_cube_manipulation/pet_fsle_med.py index a949ec77..9d78ea02 100644 --- a/examples/07_cube_manipulation/pet_fsle_med.py +++ b/examples/07_cube_manipulation/pet_fsle_med.py @@ -142,7 +142,9 @@ def build_triplet(x, y, step=0.02): used = zeros(x.shape[0], dtype="bool") # advection generator -kw = dict(t_init=t0, nb_step=1, backward=backward, mask_particule=used, u_name="u", v_name="v") +kw = dict( + t_init=t0, nb_step=1, backward=backward, mask_particule=used, u_name="u", v_name="v" +) p = c.advect(x, y, time_step=86400 / time_step_by_days, **kw) # We check at each step of advection if particle distance is over `dist_max` diff --git a/examples/07_cube_manipulation/pet_particles_drift.py b/examples/07_cube_manipulation/pet_particles_drift.py index c61ced5b..3d7aa1a4 100644 --- a/examples/07_cube_manipulation/pet_particles_drift.py +++ b/examples/07_cube_manipulation/pet_particles_drift.py @@ -20,7 +20,7 @@ "longitude", "latitude", "time", - unset=True + unset=True, ) # %% @@ -43,4 +43,4 @@ ax.plot(x, y, lw=3) ax.set_title("10 days particle paths") ax.set_xlim(31, 35), ax.set_ylim(32, 34.5) -ax.grid() \ No newline at end of file +ax.grid() diff --git a/examples/16_network/pet_follow_particle.py b/examples/16_network/pet_follow_particle.py index 356c7da4..9f5458eb 100644 --- a/examples/16_network/pet_follow_particle.py +++ b/examples/16_network/pet_follow_particle.py @@ -95,7 +95,13 @@ def save(self, *args, **kwargs): a.txt.set_position((25, 31)) step = 0.25 -kw_p = dict(nb_step=2, time_step=86400 * step * 0.5, t_init=t_snapshot - 2 * step, u_name="u", v_name="v") +kw_p = dict( + nb_step=2, + time_step=86400 * step * 0.5, + t_init=t_snapshot - 2 * step, + u_name="u", + v_name="v", +) mappables = dict() particules = c.advect(x, y, **kw_p) diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index f488168e..33d50b2a 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -54,7 +54,9 @@ def build_network(): memory=args.memory, ) group = n.group_observations( - min_overlap=args.min_overlap, minimal_area=args.minimal_area, hybrid_area=args.hybrid_area + min_overlap=args.min_overlap, + minimal_area=args.minimal_area, + hybrid_area=args.hybrid_area, ) n.build_dataset(group).write_file(filename=args.out) @@ -97,7 +99,7 @@ def divide_network(): window=args.window, min_overlap=args.min_overlap, minimal_area=args.minimal_area, - hybrid_area=args.hybrid_area + hybrid_area=args.hybrid_area, ), ) n.write_file(filename=args.out) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index c73f99d9..9345bf45 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -1980,7 +1980,15 @@ def interp(self, grid_name, lons, lats, method="bilinear"): self.x_c, self.y_c, g, m, lons, lats, nearest=method == "nearest" ) - def uv_for_advection(self, u_name=None, v_name=None, time_step=600, h_name=None, backward=False, factor=1): + def uv_for_advection( + self, + u_name=None, + v_name=None, + time_step=600, + h_name=None, + backward=False, + factor=1, + ): """ Get U,V to be used in degrees with precomputed time step @@ -1990,7 +1998,7 @@ def uv_for_advection(self, u_name=None, v_name=None, time_step=600, h_name=None, :param int time_step: Number of second for each advection """ if h_name is not None: - u_name, v_name = 'u', 'v' + u_name, v_name = "u", "v" if u_name not in self.vars: self.add_uv(h_name) self.vars.pop(h_name, None) diff --git a/src/py_eddy_tracker/observations/groups.py b/src/py_eddy_tracker/observations/groups.py index 54ae013c..81929e1e 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -351,7 +351,15 @@ def keep_tracks_by_date(self, date, nb_days): return self.extract_with_mask(mask) def particle_candidate_atlas( - self, cube, space_step, dt, start_intern=False, end_intern=False, callback_coherence=None, finalize_coherence=None, **kwargs + self, + cube, + space_step, + dt, + start_intern=False, + end_intern=False, + callback_coherence=None, + finalize_coherence=None, + **kwargs ): """Select particles within eddies, advect them, return target observation and associated percentages @@ -383,7 +391,9 @@ def particle_candidate_atlas( kw_coherence = dict(space_step=space_step, dt=dt, c=cube) kw_coherence.update(kwargs) for t in times: - logger.info("Coherence for time step : %s in [%s:%s]", t, times[0], times[-1]) + logger.info( + "Coherence for time step : %s in [%s:%s]", t, times[0], times[-1] + ) # Get index for origin i = t - t_start indexs0 = i_sort[i_start[i] : i_end[i]] @@ -393,7 +403,19 @@ def particle_candidate_atlas( if indexs0.size == 0 or indexs1.size == 0: continue - results.append(callback_coherence(self, i_target, pct, indexs0, indexs1, start_intern, end_intern, t_start=t, **kw_coherence)) + results.append( + callback_coherence( + self, + i_target, + pct, + indexs0, + indexs1, + start_intern, + end_intern, + t_start=t, + **kw_coherence + ) + ) indexs[results[-1]] = indexs0, indexs1 if finalize_coherence is not None: @@ -401,7 +423,17 @@ def particle_candidate_atlas( return i_target, pct @classmethod - def fill_coherence(cls, network, i_targets, percents, i_origin, i_end, start_intern, end_intern, **kwargs): + def fill_coherence( + cls, + network, + i_targets, + percents, + i_origin, + i_end, + start_intern, + end_intern, + **kwargs + ): """_summary_ :param array i_targets: global target @@ -412,21 +444,29 @@ def fill_coherence(cls, network, i_targets, percents, i_origin, i_end, start_int :param bool end_intern: Use intern or extern contour at end of advection """ # Get contour data - contours_start = [network[label][i_origin] for label in cls.intern(start_intern)] + contours_start = [ + network[label][i_origin] for label in cls.intern(start_intern) + ] contours_end = [network[label][i_end] for label in cls.intern(end_intern)] # Compute local coherence - i_local_targets, local_percents = particle_candidate_step(contours_start=contours_start, contours_end=contours_end,**kwargs) + i_local_targets, local_percents = particle_candidate_step( + contours_start=contours_start, contours_end=contours_end, **kwargs + ) # Store - cls.merge_particle_result(i_targets, percents, i_local_targets, local_percents, i_origin, i_end) - + cls.merge_particle_result( + i_targets, percents, i_local_targets, local_percents, i_origin, i_end + ) + @staticmethod - def merge_particle_result(i_targets, percents, i_local_targets, local_percents, i_origin, i_end): + def merge_particle_result( + i_targets, percents, i_local_targets, local_percents, i_origin, i_end + ): """Copy local result in merged result with global indexation :param array i_targets: global target - :param array percents: + :param array percents: :param array i_local_targets: local index target - :param array local_percents: + :param array local_percents: :param array i_origin: indices of origins :param array i_end: indices of ends """ diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index f11a180b..6b3102ed 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -16,15 +16,14 @@ bool_, concatenate, empty, - in1d, + nan, ones, + percentile, uint16, uint32, unique, where, zeros, - percentile, - nan ) import zarr @@ -112,9 +111,12 @@ class NetworkObservations(GroupEddiesObservations): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.reset_index() - + def __repr__(self): - m_event, s_event = self.merging_event(only_index=True, triplet=True)[0], self.splitting_event(only_index=True, triplet=True)[0] + m_event, s_event = ( + self.merging_event(only_index=True, triplet=True)[0], + self.splitting_event(only_index=True, triplet=True)[0], + ) period = (self.period[1] - self.period[0]) / 365.25 nb_by_network = self.network_size() nb_trash = 0 if self.ref_index != 0 else nb_by_network[0] @@ -124,7 +126,7 @@ def __repr__(self): f" {self.nb_segment} segments ({self.nb_segment / period:0.0f} segments/year), {len(self)} observations ({len(self) / period:0.0f} observations/year)", f" {m_event.size} merging ({m_event.size / period:0.0f} merging/year), {s_event.size} splitting ({s_event.size / period:0.0f} splitting/year)", f" with {(nb_by_network > big).sum()} network with more than {big} obs and the biggest have {nb_by_network.max()} observations ({nb_by_network[nb_by_network> big].sum()} observations cumulate)", - f" {nb_trash} observations in trash" + f" {nb_trash} observations in trash", ] return "\n".join(infos) @@ -332,7 +334,7 @@ def correct_close_events(self, nb_days_max=20): segment A splits from segment B then x days after segment A merges with B (B will be longer) These events have to last less than `nb_days_max` to be changed. - + ------------------- A / / B -------------------- @@ -528,12 +530,14 @@ def connexions(self, multi_network=False): self.only_one_network() segment = self.segment segments_connexion = dict() + def add_seg(s1, s2): if s1 not in segments_connexion: segments_connexion[s1] = set() if s2 not in segments_connexion: segments_connexion[s2] = set() segments_connexion[s1].add(s2), segments_connexion[s2].add(s1) + # Get index for each segment i0, i1, _ = self.index_segment_track i1 = i1 - 1 @@ -1122,6 +1126,7 @@ def birth_event(self): if self.first_is_trash(): indices = indices[1:] return self.extract_event(indices) + generation_event = birth_event def death_event(self): @@ -1131,6 +1136,7 @@ def death_event(self): if self.first_is_trash(): indices = indices[1:] return self.extract_event(indices) + dissipation_event = death_event def merging_event(self, triplet=False, only_index=False): @@ -1374,7 +1380,7 @@ def tag_segment(self): # No connexions, no need to explore if i not in c: sub_group[i] = j - j+= 1 + j += 1 continue # Skip if already set if sub_group[i] != 0: @@ -1384,10 +1390,8 @@ def tag_segment(self): j += 1 return sub_group - def fully_connected(self): - """Suspicious - """ + """Suspicious""" raise Exception("Must be check") self.only_one_network() return self.tag_segment().shape[0] == 1 @@ -1454,14 +1458,16 @@ def remove_dead_end(self, nobs=3, ndays=0, recursive=0, mask=None): """ connexions = self.connexions(multi_network=True) i0, i1, _ = self.index_segment_track - dt = self.time[i1 -1] - self.time[i0] + 1 + dt = self.time[i1 - 1] - self.time[i0] + 1 nb = i1 - i0 m = (dt >= ndays) * (nb >= nobs) nb_connexions = array([len(connexions.get(i, tuple())) for i in where(~m)[0]]) m[~m] = nb_connexions >= 2 segments_keep = where(m)[0] if mask is not None: - segments_keep = unique(concatenate((segments_keep, self.segment_track_array[mask]))) + segments_keep = unique( + concatenate((segments_keep, self.segment_track_array[mask])) + ) # get mask for selected obs m = ~self.segment_mask(segments_keep) self.track[m] = 0 @@ -1470,14 +1476,14 @@ def remove_dead_end(self, nobs=3, ndays=0, recursive=0, mask=None): self.previous_cost[m] = 0 self.next_obs[m] = -1 self.next_cost[m] = 0 - + m_previous = m[self.previous_obs] self.previous_obs[m_previous] = -1 self.previous_cost[m_previous] = 0 m_next = m[self.next_obs] self.next_obs[m_next] = -1 self.next_cost[m_next] = 0 - + self.sort() if recursive > 0: self.remove_dead_end(nobs, ndays, recursive - 1) @@ -1498,8 +1504,9 @@ def segment_mask(self, segments): :param list,array segments: absolute id of segment """ - return generate_mask_from_ids(array(segments), len(self), *self.index_segment_track) - + return generate_mask_from_ids( + array(segments), len(self), *self.index_segment_track + ) def get_mask_with_period(self, period): """ @@ -1849,7 +1856,7 @@ def date2file(julian_day): n_days=n_days, contour_start=contour_start, contour_end=contour_end, - **kwargs + **kwargs, ) logger.info( ( @@ -1974,7 +1981,7 @@ def group_observations(self, min_overlap=0.2, minimal_area=False, **kwargs): :param bool minimal_area: If True, function will compute intersection/little polygon, else intersection/union, by default False :param float min_overlap: minimum overlap area to associate observations, by default 0.2 - :return: + :return: :rtype: TrackEddiesObservations """ @@ -1993,7 +2000,13 @@ def group_observations(self, min_overlap=0.2, minimal_area=False, **kwargs): ii, ij = bbox_intersection(xi, yi, xj, yj) m = ( vertice_overlap( - xi[ii], yi[ii], xj[ij], yj[ij], minimal_area=minimal_area, min_overlap=min_overlap, **kwargs + xi[ii], + yi[ii], + xj[ij], + yj[ij], + minimal_area=minimal_area, + min_overlap=min_overlap, + **kwargs, ) != 0 ) @@ -2038,9 +2051,12 @@ def build_dataset(self, group, raw_data=True): print() eddies.track[new_i] = group return eddies - + + @njit(cache=True) -def get_percentile_on_following_obs(i, indexs, percents, follow_obs, t, segment, i_target, window, q=50, nb_min=1): +def get_percentile_on_following_obs( + i, indexs, percents, follow_obs, t, segment, i_target, window, q=50, nb_min=1 +): """Get stat on a part of segment close of an event :param int i: index to follow @@ -2070,8 +2086,22 @@ def get_percentile_on_following_obs(i, indexs, percents, follow_obs, t, segment, return nan return percentile(percent_target[:j], q) + @njit(cache=True) -def get_percentile_around_event(i, i1, i2, ind, pct, follow_obs, t, segment, window=10, follow_parent=False, q=50, nb_min=1): +def get_percentile_around_event( + i, + i1, + i2, + ind, + pct, + follow_obs, + t, + segment, + window=10, + follow_parent=False, + q=50, + nb_min=1, +): """Get stat around event :param array[int] i: Indexs of target @@ -2094,14 +2124,23 @@ def get_percentile_around_event(i, i1, i2, ind, pct, follow_obs, t, segment, win for j, (i_, i1_, i2_) in enumerate(zip(i, i1, i2)): if follow_parent: # We follow parent - stat1[j] = get_percentile_on_following_obs(i_, ind, pct, follow_obs, t, segment, i1_, window, q, nb_min) - stat2[j] = get_percentile_on_following_obs(i_, ind, pct, follow_obs, t, segment, i2_, window, q, nb_min) + stat1[j] = get_percentile_on_following_obs( + i_, ind, pct, follow_obs, t, segment, i1_, window, q, nb_min + ) + stat2[j] = get_percentile_on_following_obs( + i_, ind, pct, follow_obs, t, segment, i2_, window, q, nb_min + ) else: # We follow child - stat1[j] = get_percentile_on_following_obs(i1_, ind, pct, follow_obs, t, segment, i_, window, q, nb_min) - stat2[j] = get_percentile_on_following_obs(i2_, ind, pct, follow_obs, t, segment, i_, window, q, nb_min) + stat1[j] = get_percentile_on_following_obs( + i1_, ind, pct, follow_obs, t, segment, i_, window, q, nb_min + ) + stat2[j] = get_percentile_on_following_obs( + i2_, ind, pct, follow_obs, t, segment, i_, window, q, nb_min + ) return stat1, stat2 + @njit(cache=True) def get_next_index(gr): """Return for each obs index the new position to join all groups""" diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index a7663345..df60474c 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -57,8 +57,8 @@ hist_numba, local_to_coordinates, reverse_index, - wrap_longitude, window_index, + wrap_longitude, ) from ..poly import ( bbox_intersection, @@ -448,9 +448,7 @@ def add_fields(self, fields=list(), array_fields=list()): ), track_array_variables=self.track_array_variables, array_variables=list(concatenate((self.array_variables, array_fields))), - only_variables=list( - concatenate((self.fields, fields, array_fields)) - ), + only_variables=list(concatenate((self.fields, fields, array_fields))), raw_data=self.raw_data, ) new.sign_type = self.sign_type @@ -591,7 +589,7 @@ def iter_on(self, xname, window=None, bins=None): x0 = arange(x.min(), x.max()) if bins is None else array(bins) i_ordered, first_index, last_index = window_index(x, x0, window) for x_, i0, i1 in zip(x0, first_index, last_index): - yield i_ordered[i0: i1], x_ - window, x_ + window + yield i_ordered[i0:i1], x_ - window, x_ + window else: d = x[1:] - x[:-1] if bins is None: @@ -1595,9 +1593,7 @@ def to_netcdf(self, handler, **kwargs): handler.track_array_variables = self.track_array_variables handler.array_variables = ",".join(self.array_variables) # Iter on variables to create: - fields_ = array( - [VAR_DESCR[field]["nc_name"] for field in self.fields] - ) + fields_ = array([VAR_DESCR[field]["nc_name"] for field in self.fields]) i = fields_.argsort() for ori_name in array(self.fields)[i]: # Patch for a transition @@ -1676,7 +1672,9 @@ def get_filters_zarr(name): content = VAR_DESCR.get(name) filters = list() store_dtype = content["output_type"] - scale_factor, add_offset = content.get("scale_factor", None), content.get("add_offset", None) + scale_factor, add_offset = content.get("scale_factor", None), content.get( + "add_offset", None + ) if scale_factor is not None or add_offset is not None: if add_offset is None: add_offset = 0 diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index 152239cf..164f9724 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -385,9 +385,7 @@ def extract_toward_direction(self, west=True, delta_lon=None): return self.extract_with_mask(m) def extract_first_obs_in_box(self, res): - data = empty( - len(self), dtype=[("lon", "f4"), ("lat", "f4"), ("track", "i4")] - ) + data = empty(len(self), dtype=[("lon", "f4"), ("lat", "f4"), ("track", "i4")]) data["lon"] = self.longitude - self.longitude % res data["lat"] = self.latitude - self.latitude % res data["track"] = self.track @@ -757,7 +755,7 @@ def get_next_obs( time_ref, window, min_overlap=0.2, - **kwargs + **kwargs, ): """Forward association of observations to the segments""" time_max = time_e.shape[0] - 1 diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index deabd3ea..99d701db 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -431,7 +431,9 @@ def merge(x, y): return concatenate(x), concatenate(y) -def vertice_overlap(x0, y0, x1, y1, minimal_area=False, p1_area=False, hybrid_area=False, min_overlap=0): +def vertice_overlap( + x0, y0, x1, y1, minimal_area=False, p1_area=False, hybrid_area=False, min_overlap=0 +): r""" Return percent of overlap for each item. @@ -484,7 +486,11 @@ def vertice_overlap(x0, y0, x1, y1, minimal_area=False, p1_area=False, hybrid_ar if cost_ >= min_overlap: cost[i] = cost_ else: - if hybrid_area and cost_ != 0 and (intersection / min(p0_area_, p1_area_)) > .99: + if ( + hybrid_area + and cost_ != 0 + and (intersection / min(p0_area_, p1_area_)) > 0.99 + ): cost[i] = cost_ else: cost[i] = 0 diff --git a/tests/test_generic.py b/tests/test_generic.py index 29cb64b7..ee2d7881 100644 --- a/tests/test_generic.py +++ b/tests/test_generic.py @@ -33,7 +33,7 @@ def test_cumsum_by_track(): def test_wrapping(): - y = x = arange(-5,5, dtype='f4') + y = x = arange(-5, 5, dtype="f4") x_, _ = wrap_longitude(x, y, ref=-10) assert (x_ == x).all() x_, _ = wrap_longitude(x, y, ref=1) @@ -42,7 +42,7 @@ def test_wrapping(): assert (x_[:6] == x[:6] + 360).all() x_, _ = wrap_longitude(x, y, ref=1, cut=True) assert x.size + 3 == x_.size - assert (x_[6 + 3:] == x[6:]).all() + assert (x_[6 + 3 :] == x[6:]).all() assert (x_[:7] == x[:7] + 360).all() # FIXME Need evolution in wrap_longitude From 7fc19dfb1c439bd5ff19a544c6cf1aa2f0a6548d Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle <36040805+AntSimi@users.noreply.github.com> Date: Wed, 18 Jan 2023 16:48:12 +0100 Subject: [PATCH 220/249] test python 3.10 binder (#186) Update setup.cfg --- environment.yml | 2 +- setup.cfg | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/environment.yml b/environment.yml index 4ea8f840..fcf7c4b2 100644 --- a/environment.yml +++ b/environment.yml @@ -3,7 +3,7 @@ channels: - conda-forge - defaults dependencies: - - python=3.8 + - python=3.10 - ffmpeg - pip: - -r requirements.txt diff --git a/setup.cfg b/setup.cfg index eb88b6f9..7e773ae8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -5,8 +5,8 @@ column_limit = 100 [flake8] max-line-length = 140 ignore = - E203, # whitespace before ':' - W503, # line break before binary operator + E203, + W503, exclude= build doc From 9085eacbbddb178025b456fe1e2137c64b1dacf0 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Wed, 8 Feb 2023 10:07:09 +0100 Subject: [PATCH 221/249] - Add period to cube - Add some methods for display - Speed up overlap --- README.md | 5 + src/py_eddy_tracker/appli/network.py | 5 + src/py_eddy_tracker/dataset/grid.py | 85 +++++--------- src/py_eddy_tracker/generic.py | 28 +---- src/py_eddy_tracker/observations/network.py | 58 +++++----- .../observations/observation.py | 107 +++++++----------- src/py_eddy_tracker/poly.py | 23 ++-- 7 files changed, 133 insertions(+), 178 deletions(-) diff --git a/README.md b/README.md index 98a16b62..0cc34894 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ [![PyPI version](https://badge.fury.io/py/pyEddyTracker.svg)](https://badge.fury.io/py/pyEddyTracker) +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6333988.svg)](https://doi.org/10.5281/zenodo.6333988) [![Documentation Status](https://readthedocs.org/projects/py-eddy-tracker/badge/?version=stable)](https://py-eddy-tracker.readthedocs.io/en/stable/?badge=stable) [![Gitter](https://badges.gitter.im/py-eddy-tracker/community.svg)](https://gitter.im/py-eddy-tracker/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/AntSimi/py-eddy-tracker/master?urlpath=lab/tree/notebooks/python_module/) @@ -6,6 +7,10 @@ # README # +### How to cite code? ### + +Zenodo provide DOI for each tagged version, [all DOI are available here](https://doi.org/10.5281/zenodo.6333988) + ### Method ### Method was described in : diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index 33d50b2a..b8c2da51 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -128,6 +128,9 @@ def subset_network(): action="store_true", help="Remove trash (network id == 0)", ) + parser.add_argument( + "-i", "--ids", nargs="+", type=int, help="List of network which will be extract" + ) parser.add_argument( "-p", "--period", @@ -138,6 +141,8 @@ def subset_network(): ) args = parser.parse_args() n = NetworkObservations.load_file(args.input, raw_data=True) + if args.ids is not None: + n = n.networks(args.ids) if args.length is not None: n = n.longer_than(*args.length) if args.remove_dead_end is not None: diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 9345bf45..043a5244 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -2,45 +2,20 @@ """ Class to load and manipulate RegularGrid and UnRegularGrid """ -from datetime import datetime import logging +from datetime import datetime from cv2 import filter2D from matplotlib.path import Path as BasePath from netCDF4 import Dataset -from numba import njit, prange, types as numba_types -from numpy import ( - arange, - array, - ceil, - concatenate, - cos, - deg2rad, - empty, - errstate, - exp, - float_, - floor, - histogram2d, - int_, - interp, - isnan, - linspace, - ma, - mean as np_mean, - meshgrid, - nan, - nanmean, - ones, - percentile, - pi, - radians, - round_, - sin, - sinc, - where, - zeros, -) +from numba import njit, prange +from numba import types as numba_types +from numpy import (arange, array, ceil, concatenate, cos, deg2rad, empty, + errstate, exp, float_, floor, histogram2d, int_, interp, + isnan, linspace, ma) +from numpy import mean as np_mean +from numpy import (meshgrid, nan, nanmean, ones, percentile, pi, radians, + round_, sin, sinc, where, zeros) from pint import UnitRegistry from scipy.interpolate import RectBivariateSpline, interp1d from scipy.ndimage import gaussian_filter @@ -49,26 +24,15 @@ from scipy.special import j1 from .. import VAR_DESCR +from ..data import get_demo_path from ..eddy_feature import Amplitude, Contours -from ..generic import ( - bbox_indice_regular, - coordinates_to_local, - distance, - interp2d_geo, - local_to_coordinates, - nearest_grd_indice, - uniform_resample, -) +from ..generic import (bbox_indice_regular, coordinates_to_local, distance, + interp2d_geo, local_to_coordinates, nearest_grd_indice, + uniform_resample) from ..observations.observation import EddiesObservations -from ..poly import ( - create_vertice, - fit_circle, - get_pixel_in_regular, - poly_area, - poly_contain_poly, - visvalingam, - winding_number_poly, -) +from ..poly import (create_vertice, fit_circle, get_pixel_in_regular, + poly_area, poly_contain_poly, visvalingam, + winding_number_poly) logger = logging.getLogger("pet") @@ -1318,9 +1282,13 @@ def compute_pixel_path(self, x0, y0, x1, y1): self.x_size, ) - def clean_land(self): + def clean_land(self, name): """Function to remove all land pixel""" - pass + mask_land = self.__class__(get_demo_path("mask_1_60.nc"), "lon", "lat") + x,y = meshgrid(self.x_c, self.y_c) + m = mask_land.interp('mask', x.reshape(-1), y.reshape(-1), 'nearest') + data = self.grid(name) + self.vars[name] = ma.array(data, mask=m.reshape(x.shape).T) def is_circular(self): """Check if the grid is circular""" @@ -2392,6 +2360,15 @@ def __iter__(self): for _, d in self.datasets: yield d + @property + def time(self): + return array([t for t, _ in self.datasets]) + + @property + def period(self): + t = self.time + return t.min(), t.max() + def __getitem__(self, item): for t, d in self.datasets: if t == item: diff --git a/src/py_eddy_tracker/generic.py b/src/py_eddy_tracker/generic.py index fbc17d07..29815acd 100644 --- a/src/py_eddy_tracker/generic.py +++ b/src/py_eddy_tracker/generic.py @@ -3,27 +3,11 @@ Tool method which use mostly numba """ -from numba import njit, prange, types as numba_types -from numpy import ( - absolute, - arcsin, - arctan2, - bool_, - cos, - empty, - floor, - histogram, - interp, - isnan, - linspace, - nan, - ones, - pi, - radians, - sin, - where, - zeros, -) +from numba import njit, prange +from numba import types as numba_types +from numpy import (absolute, arcsin, arctan2, bool_, cos, empty, floor, + histogram, interp, isnan, linspace, nan, ones, pi, radians, + sin, where, zeros) @njit(cache=True) @@ -426,7 +410,7 @@ def split_line(x, y, i): """ nb_jump = len(where(i[1:] - i[:-1] != 0)[0]) nb_value = x.shape[0] - final_size = (nb_jump - 1) + nb_value + final_size = nb_jump + nb_value new_x = empty(final_size, dtype=x.dtype) new_y = empty(final_size, dtype=y.dtype) new_j = 0 diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 6b3102ed..4ffed94c 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -2,37 +2,26 @@ """ Class to create network of observations """ -from glob import glob import logging import time +from glob import glob import netCDF4 -from numba import njit, types as nb_types -from numba.typed import List -from numpy import ( - arange, - array, - bincount, - bool_, - concatenate, - empty, - nan, - ones, - percentile, - uint16, - uint32, - unique, - where, - zeros, -) import zarr +from numba import njit +from numba import types as nb_types +from numba.typed import List +from numpy import (arange, array, bincount, bool_, concatenate, empty, nan, + ones, percentile, uint16, uint32, unique, where, zeros) from ..dataset.grid import GridCollection from ..generic import build_index, wrap_longitude from ..poly import bbox_intersection, vertice_overlap -from .groups import GroupEddiesObservations, get_missing_indices, particle_candidate +from .groups import (GroupEddiesObservations, get_missing_indices, + particle_candidate) from .observation import EddiesObservations -from .tracking import TrackEddiesObservations, track_loess_filter, track_median_filter +from .tracking import (TrackEddiesObservations, track_loess_filter, + track_median_filter) logger = logging.getLogger("pet") @@ -280,6 +269,15 @@ def longer_than(self, nb_day_min=-1, nb_day_max=-1): """ Select network on time duration + :param int nb_day_min: Minimal number of days covered by one network, if negative -> not used + :param int nb_day_max: Maximal number of days covered by one network, if negative -> not used + """ + return self.extract_with_mask(self.mask_longer_than(nb_day_min, nb_day_max)) + + def mask_longer_than(self, nb_day_min=-1, nb_day_max=-1): + """ + Select network on time duration + :param int nb_day_min: Minimal number of days covered by one network, if negative -> not used :param int nb_day_max: Maximal number of days covered by one network, if negative -> not used """ @@ -293,7 +291,7 @@ def longer_than(self, nb_day_min=-1, nb_day_max=-1): continue if nb_day_min <= (ptp(t[i]) + 1) <= nb_day_max: mask[i] = True - return self.extract_with_mask(mask) + return mask @classmethod def from_split_network(cls, group_dataset, indexs, **kwargs): @@ -800,7 +798,7 @@ def display_timeline( if field is not None: field = self.parse_varname(field) for i, b0, b1 in self.iter_on("segment"): - x = self.time[i] + x = self.time_datetime64[i] if x.shape[0] == 0: continue if field is None: @@ -831,7 +829,7 @@ def event_timeline(self, ax, field=None, method=None, factor=1, colors_mode="rol # TODO : fill mappables dict y_seg = dict() - _time = self.time + _time = self.time_datetime64 if field is not None and method != "all": for i, b0, _ in self.iter_on("segment"): @@ -1011,7 +1009,7 @@ def scatter_timeline( if "c" not in kwargs: v = self.parse_varname(name) kwargs["c"] = v * factor - mappables["scatter"] = ax.scatter(self.time, y, **kwargs) + mappables["scatter"] = ax.scatter(self.time_datetime64, y, **kwargs) return mappables def event_map(self, ax, **kwargs): @@ -1244,7 +1242,7 @@ def networks_mask(self, id_networks, segment=False): def networks(self, id_networks): return self.extract_with_mask( - generate_mask_from_ids(id_networks, self.track.size, *self.index_network) + generate_mask_from_ids(array(id_networks), self.track.size, *self.index_network) ) @property @@ -1423,10 +1421,10 @@ def plot(self, ax, ref=None, color_cycle=None, **kwargs): :param dict kwargs: keyword arguments for Axes.plot :return: a list of matplotlib mappables """ - nb_colors = 0 - if color_cycle is not None: - kwargs = kwargs.copy() - nb_colors = len(color_cycle) + kwargs = kwargs.copy() + if color_cycle is None: + color_cycle = self.COLORS + nb_colors = len(color_cycle) mappables = list() if "label" in kwargs: kwargs["label"] = self.format_label(kwargs["label"]) diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index df60474c..72031608 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -2,76 +2,38 @@ """ Base class to manage eddy observation """ +import logging from datetime import datetime from io import BufferedReader, BytesIO -import logging from tarfile import ExFileObject from tokenize import TokenError -from Polygon import Polygon +import packaging.version +import zarr from matplotlib.cm import get_cmap from matplotlib.collections import LineCollection, PolyCollection from matplotlib.colors import Normalize from netCDF4 import Dataset -from numba import njit, types as numba_types -from numpy import ( - absolute, - arange, - array, - array_equal, - ceil, - concatenate, - cos, - digitize, - empty, - errstate, - floor, - histogram, - histogram2d, - in1d, - isnan, - linspace, - ma, - nan, - ndarray, - ones, - percentile, - radians, - sin, - unique, - where, - zeros, -) -import packaging.version +from numba import njit +from numba import types as numba_types +from numpy import (absolute, arange, array, array_equal, ceil, concatenate, + cos, datetime64, digitize, empty, errstate, floor, + histogram, histogram2d, in1d, isnan, linspace, ma, nan, + ndarray, ones, percentile, radians, sin, unique, where, + zeros) from pint import UnitRegistry from pint.errors import UndefinedUnitError -import zarr +from Polygon import Polygon from .. import VAR_DESCR, VAR_DESCR_inv, __version__ -from ..generic import ( - bbox_indice_regular, - build_index, - distance, - distance_grid, - flatten_line_matrix, - hist_numba, - local_to_coordinates, - reverse_index, - window_index, - wrap_longitude, -) -from ..poly import ( - bbox_intersection, - close_center, - convexs, - create_meshed_particles, - create_vertice, - get_pixel_in_regular, - insidepoly, - poly_indexs, - reduce_size, - vertice_overlap, -) +from ..generic import (bbox_indice_regular, build_index, distance, + distance_grid, flatten_line_matrix, hist_numba, + local_to_coordinates, reverse_index, window_index, + wrap_longitude) +from ..poly import (bbox_intersection, close_center, convexs, + create_meshed_particles, create_vertice, + get_pixel_in_regular, insidepoly, poly_indexs, reduce_size, + vertice_overlap) logger = logging.getLogger("pet") @@ -1844,6 +1806,11 @@ def extract_with_area(self, area, **kwargs): mask *= (lon > lon0) * (lon < area["urcrnrlon"]) return self.extract_with_mask(mask, **kwargs) + @property + def time_datetime64(self): + dt = (datetime64('1970-01-01') - datetime64('1950-01-01')).astype('i8') + return (self.time - dt).astype('datetime64[D]') + def time_sub_sample(self, t0, time_step): """ Time sub sampling @@ -2351,7 +2318,7 @@ def grid_stat(self, bins, varname, data=None): return regular_grid def interp_grid( - self, grid_object, varname, method="center", dtype=None, intern=None + self, grid_object, varname, i=None, method="center", dtype=None, intern=None ): """ Interpolate a grid on a center or contour with mean, min or max method @@ -2359,6 +2326,8 @@ def interp_grid( :param grid_object: Handler of grid to interp :type grid_object: py_eddy_tracker.dataset.grid.RegularGridDataset :param str varname: Name of variable to use + :param array[bool,int],None i: + Index or mask to subset observations, it could avoid to build a specific dataset. :param str method: 'center', 'mean', 'max', 'min', 'nearest' :param str dtype: if None we use var dtype :param bool intern: Use extern or intern contour @@ -2366,19 +2335,25 @@ def interp_grid( .. minigallery:: py_eddy_tracker.EddiesObservations.interp_grid """ if method in ("center", "nearest"): - return grid_object.interp(varname, self.longitude, self.latitude, method) + x, y = self.longitude, self.latitude + if i is not None: + x, y = x[i], y[i] + return grid_object.interp(varname, x,y , method) elif method in ("min", "max", "mean", "count"): x0 = grid_object.x_bounds[0] x_name, y_name = self.intern(False if intern is None else intern) x_ref = ((self.longitude - x0) % 360 + x0 - 180).reshape(-1, 1) x, y = (self[x_name] - x_ref) % 360 + x_ref, self[y_name] + if i is not None: + x, y = x[i], y[i] grid = grid_object.grid(varname) - result = empty(self.shape, dtype=grid.dtype if dtype is None else dtype) + result = empty(x.shape[0], dtype=grid.dtype if dtype is None else dtype) min_method = method == "min" grid_stat( grid_object.x_c, grid_object.y_c, -grid if min_method else grid, + grid.mask, x, y, result, @@ -2545,13 +2520,14 @@ def grid_box_stat(x_c, y_c, grid, mask, x, y, value, circular=False, method=50): @njit(cache=True) -def grid_stat(x_c, y_c, grid, x, y, result, circular=False, method="mean"): +def grid_stat(x_c, y_c, grid, mask, x, y, result, circular=False, method="mean"): """ Compute the mean or the max of the grid for each contour :param array_like x_c: the grid longitude coordinates :param array_like y_c: the grid latitude coordinates :param array_like grid: grid value + :param array[bool] mask: mask for invalid value :param array_like x: longitude of contours :param array_like y: latitude of contours :param array_like result: return values @@ -2577,9 +2553,12 @@ def grid_stat(x_c, y_c, grid, x, y, result, circular=False, method="mean"): result[elt] = i.shape[0] elif mean_method: v_sum = 0 + nb_ = 0 for i_, j_ in zip(i, j): + if mask[i_, j_]: + continue v_sum += grid[i_, j_] - nb_ = i.shape[0] + nb_ += 1 # FIXME : how does it work on grid bound, if nb_ == 0: result[elt] = nan @@ -2588,7 +2567,9 @@ def grid_stat(x_c, y_c, grid, x, y, result, circular=False, method="mean"): elif max_method: v_max = -1e40 for i_, j_ in zip(i, j): - v_max = max(v_max, grid[i_, j_]) + values = grid[i_, j_] + # FIXME must use mask + v_max = max(v_max, values) result[elt] = v_max diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index 99d701db..217b1d18 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -5,10 +5,12 @@ import heapq -from Polygon import Polygon -from numba import njit, prange, types as numba_types -from numpy import arctan, array, concatenate, empty, nan, ones, pi, where, zeros +from numba import njit, prange +from numba import types as numba_types +from numpy import (arctan, array, concatenate, empty, nan, ones, pi, where, + zeros) from numpy.linalg import lstsq +from Polygon import Polygon from .generic import build_index @@ -278,7 +280,10 @@ def close_center(x0, y0, x1, y1, delta=0.1): for i0 in range(nb0): xi0, yi0 = x0[i0], y0[i0] for i1 in range(nb1): - if abs(x1[i1] - xi0) > delta: + d_x = x1[i1] - xi0 + if abs(d_x) > 180: + d_x = (d_x + 180) % 360 - 180 + if abs(d_x) > delta: continue if abs(y1[i1] - yi0) > delta: continue @@ -474,22 +479,22 @@ def vertice_overlap( if intersection == 0: cost[i] = 0 continue - p0_area_, p1_area_ = p0.area(), p1.area() + p0_area, p1_area = p0.area(), p1.area() if minimal_area: - cost_ = intersection / min(p0_area_, p1_area_) + cost_ = intersection / min(p0_area, p1_area) # we divide intersection with p1 elif p1_area: - cost_ = intersection / p1_area_ + cost_ = intersection / p1_area # we divide intersection with polygon merging result from 0 to 1 else: - cost_ = intersection / (p0_area_ + p1_area_ - intersection) + cost_ = intersection / (p0_area + p1_area - intersection) if cost_ >= min_overlap: cost[i] = cost_ else: if ( hybrid_area and cost_ != 0 - and (intersection / min(p0_area_, p1_area_)) > 0.99 + and (intersection / min(p0_area, p1_area)) > 0.99 ): cost[i] = cost_ else: From e7d138de2f2e6718c4cd4d461c31a58a5b169271 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Thu, 4 May 2023 10:52:06 +0200 Subject: [PATCH 222/249] change version for module --- doc/environment.yml | 1 + environment.yml | 1 + requirements.txt | 8 ++++---- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/environment.yml b/doc/environment.yml index 9d882911..89fcbe9c 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -4,6 +4,7 @@ channels: dependencies: - python=3.10 - ffmpeg + - pip - pip: - sphinx-gallery - sphinx_rtd_theme diff --git a/environment.yml b/environment.yml index fcf7c4b2..12ce70e7 100644 --- a/environment.yml +++ b/environment.yml @@ -4,6 +4,7 @@ channels: - defaults dependencies: - python=3.10 + - pip - ffmpeg - pip: - -r requirements.txt diff --git a/requirements.txt b/requirements.txt index 497344e6..4c8af099 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,11 @@ matplotlib opencv-python -pint==0.18 +pint polygon3 pyyaml requests scipy zarr -netCDF4<1.6 -numpy<1.23 -numba<0.56 \ No newline at end of file +netCDF4 +numpy +numba \ No newline at end of file From 17288159048ffbb599ca1287cb53bbc29f94f272 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Thu, 4 May 2023 11:10:51 +0200 Subject: [PATCH 223/249] minimal version of python : 3.10 --- .github/workflows/python-app.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index bbc0662c..00dbcc95 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -11,7 +11,7 @@ jobs: matrix: # os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, windows-latest] - python_version: [3.7, 3.8, 3.9, '3.10'] + python_version: ['3.10'] name: Run py eddy tracker build tests runs-on: ${{ matrix.os }} defaults: diff --git a/setup.py b/setup.py index 6b18bcbb..7b836763 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ setup( name="pyEddyTracker", - python_requires=">=3.7", + python_requires=">=3.10", version=versioneer.get_version(), cmdclass=versioneer.get_cmdclass(), description="Py-Eddy-Tracker libraries", From 1b9ab25576a5e96b9987374687dd5436f93b7ed9 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Thu, 4 May 2023 12:25:47 +0200 Subject: [PATCH 224/249] numba correction with masked array --- doc/spectrum.rst | 1 - examples/16_network/pet_atlas.py | 4 +- examples/16_network/pet_follow_particle.py | 3 +- examples/16_network/pet_relative.py | 8 +- .../16_network/pet_replay_segmentation.py | 1 - src/py_eddy_tracker/dataset/grid.py | 118 +++++++++++++----- .../old_tracker_reference.py | 1 - src/py_eddy_tracker/generic.py | 32 +++-- src/py_eddy_tracker/observations/network.py | 83 +++++++++--- .../observations/observation.py | 87 +++++++++---- src/py_eddy_tracker/poly.py | 8 +- src/py_eddy_tracker/tracking.py | 4 +- 12 files changed, 256 insertions(+), 94 deletions(-) diff --git a/doc/spectrum.rst b/doc/spectrum.rst index 5a42cbec..f96e30a0 100644 --- a/doc/spectrum.rst +++ b/doc/spectrum.rst @@ -28,7 +28,6 @@ Compute and display spectrum ax.set_title("Spectrum") ax.set_xlabel("km") for name_area, area in areas.items(): - lon_spec, lat_spec = raw.spectrum_lonlat("adt", area=area) mappable = ax.loglog(*lat_spec, label="lat %s raw" % name_area)[0] ax.loglog( diff --git a/examples/16_network/pet_atlas.py b/examples/16_network/pet_atlas.py index 6927f169..48b374e2 100644 --- a/examples/16_network/pet_atlas.py +++ b/examples/16_network/pet_atlas.py @@ -129,7 +129,9 @@ def update_axes(ax, mappable=None): # Merging in networks longer than 10 days, with dead end remove (shorter than 10 observations) # -------------------------------------------------------------------------------------------- ax = start_axes("") -merger = n10.remove_dead_end(nobs=10).merging_event() +n10_ = n10.copy() +n10_.remove_dead_end(nobs=10) +merger = n10_.merging_event() g_10_merging = merger.grid_count(bins) m = g_10_merging.display(ax, **kw_time, vmin=0, vmax=1) update_axes(ax, m).set_label("Pixel used in % of time") diff --git a/examples/16_network/pet_follow_particle.py b/examples/16_network/pet_follow_particle.py index 9f5458eb..6815fb6e 100644 --- a/examples/16_network/pet_follow_particle.py +++ b/examples/16_network/pet_follow_particle.py @@ -41,7 +41,8 @@ def save(self, *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.remove_dead_end(nobs=0, ndays=10) +n = n.remove_trash() n.numbering_segment() c = GridCollection.from_netcdf_cube( get_demo_path("dt_med_allsat_phy_l4_2005T2.nc"), diff --git a/examples/16_network/pet_relative.py b/examples/16_network/pet_relative.py index f5e8bc92..dd97b538 100644 --- a/examples/16_network/pet_relative.py +++ b/examples/16_network/pet_relative.py @@ -127,7 +127,9 @@ # Remove dead branch # ------------------ # Remove all tiny segments with less than N obs which didn't join two segments -n_clean = n.remove_dead_end(nobs=5, ndays=10) +n_clean = n.copy() +n_clean.remove_dead_end(nobs=5, ndays=10) +n_clean = n_clean.remove_trash() fig = plt.figure(figsize=(15, 12)) ax = fig.add_axes([0.04, 0.54, 0.90, 0.40]) ax.set_title(f"Original network ({n.infos()})") @@ -261,7 +263,9 @@ # -------------------- # Get a simplified network -n = n2.remove_dead_end(nobs=50, recursive=1) +n = n2.copy() +n.remove_dead_end(nobs=50, recursive=1) +n = n.remove_trash() n.numbering_segment() # %% # Only a map can be tricky to understand, with a timeline it's easier! diff --git a/examples/16_network/pet_replay_segmentation.py b/examples/16_network/pet_replay_segmentation.py index ecb0970d..d909af7f 100644 --- a/examples/16_network/pet_replay_segmentation.py +++ b/examples/16_network/pet_replay_segmentation.py @@ -163,7 +163,6 @@ def get_obs(dataset): for b0, b1 in [ (datetime(i, 1, 1), datetime(i, 12, 31)) for i in (2004, 2005, 2006, 2007, 2008) ]: - ref, delta = datetime(1950, 1, 1), 20 b0_, b1_ = (b0 - ref).days, (b1 - ref).days ax = timeline_axes() diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 043a5244..7e9a04be 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -2,20 +2,45 @@ """ Class to load and manipulate RegularGrid and UnRegularGrid """ -import logging from datetime import datetime +import logging from cv2 import filter2D from matplotlib.path import Path as BasePath from netCDF4 import Dataset -from numba import njit, prange -from numba import types as numba_types -from numpy import (arange, array, ceil, concatenate, cos, deg2rad, empty, - errstate, exp, float_, floor, histogram2d, int_, interp, - isnan, linspace, ma) -from numpy import mean as np_mean -from numpy import (meshgrid, nan, nanmean, ones, percentile, pi, radians, - round_, sin, sinc, where, zeros) +from numba import njit, prange, types as numba_types +from numpy import ( + arange, + array, + ceil, + concatenate, + cos, + deg2rad, + empty, + errstate, + exp, + float_, + floor, + histogram2d, + int_, + interp, + isnan, + linspace, + ma, + mean as np_mean, + meshgrid, + nan, + nanmean, + ones, + percentile, + pi, + radians, + round_, + sin, + sinc, + where, + zeros, +) from pint import UnitRegistry from scipy.interpolate import RectBivariateSpline, interp1d from scipy.ndimage import gaussian_filter @@ -26,13 +51,25 @@ from .. import VAR_DESCR from ..data import get_demo_path from ..eddy_feature import Amplitude, Contours -from ..generic import (bbox_indice_regular, coordinates_to_local, distance, - interp2d_geo, local_to_coordinates, nearest_grd_indice, - uniform_resample) +from ..generic import ( + bbox_indice_regular, + coordinates_to_local, + distance, + interp2d_geo, + local_to_coordinates, + nearest_grd_indice, + uniform_resample, +) from ..observations.observation import EddiesObservations -from ..poly import (create_vertice, fit_circle, get_pixel_in_regular, - poly_area, poly_contain_poly, visvalingam, - winding_number_poly) +from ..poly import ( + create_vertice, + fit_circle, + get_pixel_in_regular, + poly_area, + poly_contain_poly, + visvalingam, + winding_number_poly, +) logger = logging.getLogger("pet") @@ -86,7 +123,7 @@ def value_on_regular_contour(x_g, y_g, z_g, m_g, vertices, num_fac=2, fixed_size @njit(cache=True) def mean_on_regular_contour( - x_g, y_g, z_g, m_g, vertices, num_fac=2, fixed_size=None, nan_remove=False + x_g, y_g, z_g, m_g, vertices, num_fac=2, fixed_size=-1, nan_remove=False ): x_val, y_val = vertices[:, 0], vertices[:, 1] x_new, y_new = uniform_resample(x_val, y_val, num_fac, fixed_size) @@ -406,8 +443,8 @@ def setup_coordinates(self): x_name, y_name = self.coordinates if self.is_centered: # logger.info("Grid center") - self.x_c = self.vars[x_name].astype("float64") - self.y_c = self.vars[y_name].astype("float64") + self.x_c = array(self.vars[x_name].astype("float64")) + self.y_c = array(self.vars[y_name].astype("float64")) self.x_bounds = concatenate((self.x_c, (2 * self.x_c[-1] - self.x_c[-2],))) self.y_bounds = concatenate((self.y_c, (2 * self.y_c[-1] - self.y_c[-2],))) @@ -419,8 +456,8 @@ def setup_coordinates(self): self.y_bounds[-1] -= d_y[-1] / 2 else: - self.x_bounds = self.vars[x_name].astype("float64") - self.y_bounds = self.vars[y_name].astype("float64") + self.x_bounds = array(self.vars[x_name].astype("float64")) + self.y_bounds = array(self.vars[y_name].astype("float64")) if len(self.x_dim) == 1: self.x_c = self.x_bounds.copy() @@ -757,7 +794,7 @@ def eddy_identification( # Test of the rotating sense: cyclone or anticyclone if has_value( - data, i_x_in, i_y_in, cvalues, below=anticyclonic_search + data.data, i_x_in, i_y_in, cvalues, below=anticyclonic_search ): continue @@ -788,7 +825,6 @@ def eddy_identification( contour.reject = 4 continue if reset_centroid: - if self.is_circular(): centi = self.normalize_x_indice(reset_centroid[0]) else: @@ -1285,8 +1321,8 @@ def compute_pixel_path(self, x0, y0, x1, y1): def clean_land(self, name): """Function to remove all land pixel""" mask_land = self.__class__(get_demo_path("mask_1_60.nc"), "lon", "lat") - x,y = meshgrid(self.x_c, self.y_c) - m = mask_land.interp('mask', x.reshape(-1), y.reshape(-1), 'nearest') + x, y = meshgrid(self.x_c, self.y_c) + m = mask_land.interp("mask", x.reshape(-1), y.reshape(-1), "nearest") data = self.grid(name) self.vars[name] = ma.array(data, mask=m.reshape(x.shape).T) @@ -1310,7 +1346,7 @@ def get_step_in_km(self, lat, wave_length): min_wave_length = max(step_x_km, step_y_km) * 2 if wave_length < min_wave_length: logger.error( - "wave_length too short for resolution, must be > %d km", + "Wave_length too short for resolution, must be > %d km", ceil(min_wave_length), ) raise Exception() @@ -1361,6 +1397,24 @@ def kernel_lanczos(self, lat, wave_length, order=1): kernel[dist_norm > order] = 0 return self.finalize_kernel(kernel, order, half_x_pt, half_y_pt) + def kernel_loess(self, lat, wave_length, order=1): + """ + https://fr.wikipedia.org/wiki/R%C3%A9gression_locale + """ + order = self.check_order(order) + half_x_pt, half_y_pt, dist_norm = self.estimate_kernel_shape( + lat, wave_length, order + ) + + def inc_func(xdist): + f = zeros(xdist.size) + f[abs(xdist) < 1] = 1 + return f + + kernel = (1 - abs(dist_norm) ** 3) ** 3 + kernel[abs(dist_norm) > order] = 0 + return self.finalize_kernel(kernel, order, half_x_pt, half_y_pt) + def kernel_bessel(self, lat, wave_length, order=1): """wave_length in km order must be int @@ -1638,11 +1692,13 @@ def compute_finite_difference(self, data, schema=1, mode="reflect", vertical=Fal data1[-schema:] = nan data2[:schema] = nan - d = self.EARTH_RADIUS * 2 * pi / 360 * 2 * schema + # Distance for one degree + d = self.EARTH_RADIUS * 2 * pi / 360 + # Mulitply by 2 step if vertical: - d *= self.ystep + d *= self.ystep * 2 * schema else: - d *= self.xstep * cos(deg2rad(self.y_c)) + d *= self.xstep * cos(deg2rad(self.y_c)) * 2 * schema return (data1 - data2) / d def compute_stencil( @@ -1855,7 +1911,7 @@ def speed_coef_mean(self, contour): return mean_on_regular_contour( self.x_c, self.y_c, - self._speed_ev, + self._speed_ev.data, self._speed_ev.mask, contour.vertices, nan_remove=True, @@ -1945,7 +2001,7 @@ def interp(self, grid_name, lons, lats, method="bilinear"): g = self.grid(grid_name) m = self.get_mask(g) return interp2d_geo( - self.x_c, self.y_c, g, m, lons, lats, nearest=method == "nearest" + self.x_c, self.y_c, g.data, m, lons, lats, nearest=method == "nearest" ) def uv_for_advection( @@ -1981,7 +2037,7 @@ def uv_for_advection( u = -u v = -v m = u.mask + v.mask - return u, v, m + return u.data, v.data, m def advect(self, x, y, u_name, v_name, nb_step=10, rk4=True, **kw): """ diff --git a/src/py_eddy_tracker/featured_tracking/old_tracker_reference.py b/src/py_eddy_tracker/featured_tracking/old_tracker_reference.py index 41e02db9..b0d4abfa 100644 --- a/src/py_eddy_tracker/featured_tracking/old_tracker_reference.py +++ b/src/py_eddy_tracker/featured_tracking/old_tracker_reference.py @@ -8,7 +8,6 @@ class CheltonTracker(Model): - __slots__ = tuple() GROUND = RegularGridDataset( diff --git a/src/py_eddy_tracker/generic.py b/src/py_eddy_tracker/generic.py index 29815acd..612def68 100644 --- a/src/py_eddy_tracker/generic.py +++ b/src/py_eddy_tracker/generic.py @@ -3,11 +3,27 @@ Tool method which use mostly numba """ -from numba import njit, prange -from numba import types as numba_types -from numpy import (absolute, arcsin, arctan2, bool_, cos, empty, floor, - histogram, interp, isnan, linspace, nan, ones, pi, radians, - sin, where, zeros) +from numba import njit, prange, types as numba_types +from numpy import ( + absolute, + arcsin, + arctan2, + bool_, + cos, + empty, + floor, + histogram, + interp, + isnan, + linspace, + nan, + ones, + pi, + radians, + sin, + where, + zeros, +) @njit(cache=True) @@ -285,14 +301,14 @@ def interp2d_bilinear(x_g, y_g, z_g, m_g, x, y): @njit(cache=True, fastmath=True) -def uniform_resample(x_val, y_val, num_fac=2, fixed_size=None): +def uniform_resample(x_val, y_val, num_fac=2, fixed_size=-1): """ Resample contours to have (nearly) equal spacing. :param array_like x_val: input x contour coordinates :param array_like y_val: input y contour coordinates :param int num_fac: factor to increase lengths of output coordinates - :param int,None fixed_size: if defined, will be used to set sampling + :param int fixed_size: if > -1, will be used to set sampling """ nb = x_val.shape[0] # Get distances @@ -303,7 +319,7 @@ def uniform_resample(x_val, y_val, num_fac=2, fixed_size=None): dist[1:][dist[1:] < 1e-3] = 1e-3 dist = dist.cumsum() # Get uniform distances - if fixed_size is None: + if fixed_size == -1: fixed_size = dist.size * num_fac d_uniform = linspace(0, dist[-1], fixed_size) x_new = interp(d_uniform, dist, x_val) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 4ffed94c..a2e2daed 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -2,26 +2,37 @@ """ Class to create network of observations """ +from glob import glob import logging import time -from glob import glob import netCDF4 -import zarr -from numba import njit -from numba import types as nb_types +from numba import njit, types as nb_types from numba.typed import List -from numpy import (arange, array, bincount, bool_, concatenate, empty, nan, - ones, percentile, uint16, uint32, unique, where, zeros) +from numpy import ( + arange, + array, + bincount, + bool_, + concatenate, + empty, + nan, + ones, + percentile, + uint16, + uint32, + unique, + where, + zeros, +) +import zarr from ..dataset.grid import GridCollection from ..generic import build_index, wrap_longitude from ..poly import bbox_intersection, vertice_overlap -from .groups import (GroupEddiesObservations, get_missing_indices, - particle_candidate) +from .groups import GroupEddiesObservations, get_missing_indices, particle_candidate from .observation import EddiesObservations -from .tracking import (TrackEddiesObservations, track_loess_filter, - track_median_filter) +from .tracking import TrackEddiesObservations, track_loess_filter, track_median_filter logger = logging.getLogger("pet") @@ -93,7 +104,6 @@ def fix_next_previous_obs(next_obs, previous_obs, flag_virtual): class NetworkObservations(GroupEddiesObservations): - __slots__ = ("_index_network", "_index_segment_track", "_segment_track_array") NOGROUP = 0 @@ -465,7 +475,6 @@ def find_link(self, i_observations, forward=True, backward=False): segments_connexion[seg][0] = i_slice if i_p != -1: - if p_seg not in segments_connexion: segments_connexion[p_seg] = [None, [], []] @@ -614,7 +623,6 @@ def relatives(self, obs, order=2): segments_connexion[seg][0] = i_slice if i_p != -1: - if p_seg not in segments_connexion: segments_connexion[p_seg] = [None, []] @@ -1242,7 +1250,9 @@ def networks_mask(self, id_networks, segment=False): def networks(self, id_networks): return self.extract_with_mask( - generate_mask_from_ids(array(id_networks), self.track.size, *self.index_network) + generate_mask_from_ids( + array(id_networks), self.track.size, *self.index_network + ) ) @property @@ -1638,7 +1648,6 @@ def analysis_coherence( correct_close_events=0, remove_dead_end=0, ): - """Global function to analyse segments coherence, with network preprocessing. :param callable date_function: python function, takes as param `int` (julian day) and return data filename associated to the date @@ -1719,7 +1728,6 @@ def segment_coherence_backward( contour_start="speed", contour_end="speed", ): - """ Percentage of particules and their targets after backward advection from a specific eddy. @@ -1797,7 +1805,6 @@ def segment_coherence_forward( contour_end="speed", **kwargs, ): - """ Percentage of particules and their targets after forward advection from a specific eddy. @@ -1886,6 +1893,48 @@ def mask_obs_close_event(self, merging=True, spliting=True, dt=3): mask_follow_obs(m, self.previous_obs, self.time, i_target, dt) return m + def swap_track( + self, + length_main_max_after_event=2, + length_secondary_min_after_event=10, + delta_pct_max=-0.2, + ): + events = self.splitting_event(triplet=True, only_index=True) + count = 0 + for i_main, i1, i2 in zip(*events): + seg_main, _, seg2 = ( + self.segment_track_array[i_main], + self.segment_track_array[i1], + self.segment_track_array[i2], + ) + i_start, i_end, i0 = self.index_segment_track + # For splitting + last_index_main = i_end[seg_main - i0] - 1 + last_index_secondary = i_end[seg2 - i0] - 1 + last_main_next_obs = self.next_obs[last_index_main] + t_event, t_main_end, t_secondary_start, t_secondary_end = ( + self.time[i_main], + self.time[last_index_main], + self.time[i2], + self.time[last_index_secondary], + ) + dt_main, dt_secondary = ( + t_main_end - t_event, + t_secondary_end - t_secondary_start, + ) + delta_cost = self.previous_cost[i2] - self.previous_cost[i1] + if ( + dt_main <= length_main_max_after_event + and dt_secondary >= length_secondary_min_after_event + and last_main_next_obs == -1 + and delta_cost > delta_pct_max + ): + self.segment[i1 : last_index_main + 1] = self.segment[i2] + self.segment[i2 : last_index_secondary + 1] = self.segment[i_main] + count += 1 + logger.info("%d segmnent swap on %d", count, len(events[0])) + return self.sort() + class Network: __slots__ = ( diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 72031608..f710cf0a 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -2,38 +2,77 @@ """ Base class to manage eddy observation """ -import logging from datetime import datetime from io import BufferedReader, BytesIO +import logging from tarfile import ExFileObject from tokenize import TokenError -import packaging.version -import zarr +from Polygon import Polygon from matplotlib.cm import get_cmap from matplotlib.collections import LineCollection, PolyCollection from matplotlib.colors import Normalize from netCDF4 import Dataset -from numba import njit -from numba import types as numba_types -from numpy import (absolute, arange, array, array_equal, ceil, concatenate, - cos, datetime64, digitize, empty, errstate, floor, - histogram, histogram2d, in1d, isnan, linspace, ma, nan, - ndarray, ones, percentile, radians, sin, unique, where, - zeros) +from numba import njit, types as numba_types +from numpy import ( + absolute, + arange, + array, + array_equal, + ceil, + concatenate, + cos, + datetime64, + digitize, + empty, + errstate, + floor, + histogram, + histogram2d, + in1d, + isnan, + linspace, + ma, + nan, + ndarray, + ones, + percentile, + radians, + sin, + unique, + where, + zeros, +) +import packaging.version from pint import UnitRegistry from pint.errors import UndefinedUnitError -from Polygon import Polygon +import zarr from .. import VAR_DESCR, VAR_DESCR_inv, __version__ -from ..generic import (bbox_indice_regular, build_index, distance, - distance_grid, flatten_line_matrix, hist_numba, - local_to_coordinates, reverse_index, window_index, - wrap_longitude) -from ..poly import (bbox_intersection, close_center, convexs, - create_meshed_particles, create_vertice, - get_pixel_in_regular, insidepoly, poly_indexs, reduce_size, - vertice_overlap) +from ..generic import ( + bbox_indice_regular, + build_index, + distance, + distance_grid, + flatten_line_matrix, + hist_numba, + local_to_coordinates, + reverse_index, + window_index, + wrap_longitude, +) +from ..poly import ( + bbox_intersection, + close_center, + convexs, + create_meshed_particles, + create_vertice, + get_pixel_in_regular, + insidepoly, + poly_indexs, + reduce_size, + vertice_overlap, +) logger = logging.getLogger("pet") @@ -1808,8 +1847,8 @@ def extract_with_area(self, area, **kwargs): @property def time_datetime64(self): - dt = (datetime64('1970-01-01') - datetime64('1950-01-01')).astype('i8') - return (self.time - dt).astype('datetime64[D]') + dt = (datetime64("1970-01-01") - datetime64("1950-01-01")).astype("i8") + return (self.time - dt).astype("datetime64[D]") def time_sub_sample(self, t0, time_step): """ @@ -2215,7 +2254,7 @@ def grid_count(self, bins, intern=False, center=False, filter=slice(None)): x_ref = ((self.longitude[filter] - x0) % 360 + x0 - 180).reshape(-1, 1) x_contour, y_contour = self[x_name][filter], self[y_name][filter] grid_count_pixel_in( - grid, + grid.data, x_contour, y_contour, x_ref, @@ -2338,7 +2377,7 @@ def interp_grid( x, y = self.longitude, self.latitude if i is not None: x, y = x[i], y[i] - return grid_object.interp(varname, x,y , method) + return grid_object.interp(varname, x, y, method) elif method in ("min", "max", "mean", "count"): x0 = grid_object.x_bounds[0] x_name, y_name = self.intern(False if intern is None else intern) @@ -2352,7 +2391,7 @@ def interp_grid( grid_stat( grid_object.x_c, grid_object.y_c, - -grid if min_method else grid, + -grid.data if min_method else grid.data, grid.mask, x, y, diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index 217b1d18..491b0c3a 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -5,12 +5,10 @@ import heapq -from numba import njit, prange -from numba import types as numba_types -from numpy import (arctan, array, concatenate, empty, nan, ones, pi, where, - zeros) -from numpy.linalg import lstsq from Polygon import Polygon +from numba import njit, prange, types as numba_types +from numpy import arctan, array, concatenate, empty, nan, ones, pi, where, zeros +from numpy.linalg import lstsq from .generic import build_index diff --git a/src/py_eddy_tracker/tracking.py b/src/py_eddy_tracker/tracking.py index 16616d5a..9329e3bd 100644 --- a/src/py_eddy_tracker/tracking.py +++ b/src/py_eddy_tracker/tracking.py @@ -409,14 +409,14 @@ def to_netcdf(self, handler): logger.debug('Create Dimensions "Nstep" : %d', nb_step) handler.createDimension("Nstep", nb_step) var_file_in = handler.createVariable( - zlib=True, + zlib=False, complevel=1, varname="FileIn", datatype="S1024", dimensions="Nstep", ) var_file_out = handler.createVariable( - zlib=True, + zlib=False, complevel=1, varname="FileOut", datatype="S1024", From b93850af1331b5bd0428ccd8832b8c479f0d019f Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Thu, 4 May 2023 16:20:39 +0200 Subject: [PATCH 225/249] Add example with correspondance --- .../pet_how_to_use_correspondances.py | 94 +++++++++++ .../pet_how_to_use_correspondances.ipynb | 155 ++++++++++++++++++ .../observations/observation.py | 6 +- src/py_eddy_tracker/tracking.py | 7 +- 4 files changed, 258 insertions(+), 4 deletions(-) create mode 100644 examples/08_tracking_manipulation/pet_how_to_use_correspondances.py create mode 100644 notebooks/python_module/08_tracking_manipulation/pet_how_to_use_correspondances.ipynb diff --git a/examples/08_tracking_manipulation/pet_how_to_use_correspondances.py b/examples/08_tracking_manipulation/pet_how_to_use_correspondances.py new file mode 100644 index 00000000..8161ad81 --- /dev/null +++ b/examples/08_tracking_manipulation/pet_how_to_use_correspondances.py @@ -0,0 +1,94 @@ +""" +Correspondances +=============== + +Correspondances is a mechanism to intend to continue tracking with new detection + +""" + +import logging + +# %% +from matplotlib import pyplot as plt +from netCDF4 import Dataset + +from py_eddy_tracker import start_logger +from py_eddy_tracker.data import get_remote_demo_sample +from py_eddy_tracker.featured_tracking.area_tracker import AreaTracker + +# In order to hide some warning +import py_eddy_tracker.observations.observation +from py_eddy_tracker.tracking import Correspondances + +py_eddy_tracker.observations.observation._display_check_warning = False + + +# %% +def plot_eddy(ed): + fig = plt.figure(figsize=(10, 5)) + ax = fig.add_axes([0.05, 0.03, 0.90, 0.94]) + ed.plot(ax, ref=-10, marker="x") + lc = ed.display_color(ax, field=ed.time, ref=-10, intern=True) + plt.colorbar(lc).set_label("Time in Julian days (from 1950/01/01)") + ax.set_xlim(4.5, 8), ax.set_ylim(36.8, 38.3) + ax.set_aspect("equal") + ax.grid() + + +# %% +# Get remote data, we will keep only 20 first days, +# `get_remote_demo_sample` function is only to get demo dataset, in your own case give a list of identification filename +# and don't mix cyclonic and anticyclonic files. +file_objects = get_remote_demo_sample( + "eddies_med_adt_allsat_dt2018/Anticyclonic_2010_2011_2012" +)[:20] + +# %% +# We run a traking with a tracker which use contour overlap, on 10 first time step +c_first_run = Correspondances( + datasets=file_objects[:10], class_method=AreaTracker, virtual=4 +) +start_logger().setLevel("INFO") +c_first_run.track() +start_logger().setLevel("WARNING") +with Dataset("correspondances.nc", "w") as h: + c_first_run.to_netcdf(h) +# Next step are done only to build atlas and display it +c_first_run.prepare_merging() + +# We have now an eddy object +eddies_area_tracker = c_first_run.merge(raw_data=False) +eddies_area_tracker.virtual[:] = eddies_area_tracker.time == 0 +eddies_area_tracker.filled_by_interpolation(eddies_area_tracker.virtual == 1) + +# %% +# Plot from first ten days +plot_eddy(eddies_area_tracker) + +# %% +# Restart from previous run +# ------------------------- +# We give all filenames, the new one and filename from previous run +c_second_run = Correspondances( + datasets=file_objects[:20], + # This parameter must be identical in each run + class_method=AreaTracker, + virtual=4, + # Previous saved correspondancs + previous_correspondance="correspondances.nc", +) +start_logger().setLevel("INFO") +c_second_run.track() +start_logger().setLevel("WARNING") +c_second_run.prepare_merging() +# We have now another eddy object +eddies_area_tracker_extend = c_second_run.merge(raw_data=False) +eddies_area_tracker_extend.virtual[:] = eddies_area_tracker_extend.time == 0 +eddies_area_tracker_extend.filled_by_interpolation( + eddies_area_tracker_extend.virtual == 1 +) + + +# %% +# Plot with time extension +plot_eddy(eddies_area_tracker_extend) diff --git a/notebooks/python_module/08_tracking_manipulation/pet_how_to_use_correspondances.ipynb b/notebooks/python_module/08_tracking_manipulation/pet_how_to_use_correspondances.ipynb new file mode 100644 index 00000000..0681c0fc --- /dev/null +++ b/notebooks/python_module/08_tracking_manipulation/pet_how_to_use_correspondances.ipynb @@ -0,0 +1,155 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n# Correspondances\n\nCorrespondances is a mechanism to intend to continue tracking with new detection\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import logging" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from matplotlib import pyplot as plt\nfrom netCDF4 import Dataset\n\nfrom py_eddy_tracker import start_logger\nfrom py_eddy_tracker.data import get_remote_demo_sample\nfrom py_eddy_tracker.featured_tracking.area_tracker import AreaTracker\n\n# In order to hide some warning\nimport py_eddy_tracker.observations.observation\nfrom py_eddy_tracker.tracking import Correspondances\n\npy_eddy_tracker.observations.observation._display_check_warning = False" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def plot_eddy(ed):\n fig = plt.figure(figsize=(10, 5))\n ax = fig.add_axes([0.05, 0.03, 0.90, 0.94])\n ed.plot(ax, ref=-10, marker=\"x\")\n lc = ed.display_color(ax, field=ed.time, ref=-10, intern=True)\n plt.colorbar(lc).set_label(\"Time in Julian days (from 1950/01/01)\")\n ax.set_xlim(4.5, 8), ax.set_ylim(36.8, 38.3)\n ax.set_aspect(\"equal\")\n ax.grid()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get remote data, we will keep only 20 first days,\n`get_remote_demo_sample` function is only to get demo dataset, in your own case give a list of identification filename\nand don't mix cyclonic and anticyclonic files.\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "file_objects = get_remote_demo_sample(\n \"eddies_med_adt_allsat_dt2018/Anticyclonic_2010_2011_2012\"\n)[:20]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We run a traking with a tracker which use contour overlap, on 10 first time step\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "c_first_run = Correspondances(\n datasets=file_objects[:10], class_method=AreaTracker, virtual=4\n)\nstart_logger().setLevel(\"INFO\")\nc_first_run.track()\nstart_logger().setLevel(\"WARNING\")\nwith Dataset(\"correspondances.nc\", \"w\") as h:\n c_first_run.to_netcdf(h)\n# Next step are done only to build atlas and display it\nc_first_run.prepare_merging()\n\n# We have now an eddy object\neddies_area_tracker = c_first_run.merge(raw_data=False)\neddies_area_tracker.virtual[:] = eddies_area_tracker.time == 0\neddies_area_tracker.filled_by_interpolation(eddies_area_tracker.virtual == 1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Plot from first ten days\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "plot_eddy(eddies_area_tracker)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Restart from previous run\nWe give all filenames, the new one and filename from previous run\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "c_second_run = Correspondances(\n datasets=file_objects[:20],\n # This parameter must be identical in each run\n class_method=AreaTracker,\n virtual=4,\n # Previous saved correspondancs\n previous_correspondance=\"correspondances.nc\",\n)\nstart_logger().setLevel(\"INFO\")\nc_second_run.track()\nstart_logger().setLevel(\"WARNING\")\nc_second_run.prepare_merging()\n# We have now another eddy object\neddies_area_tracker_extend = c_second_run.merge(raw_data=False)\neddies_area_tracker_extend.virtual[:] = eddies_area_tracker_extend.time == 0\neddies_area_tracker_extend.filled_by_interpolation(\n eddies_area_tracker_extend.virtual == 1\n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Plot with time extension\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "plot_eddy(eddies_area_tracker_extend)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index f710cf0a..b39f7f83 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -80,6 +80,7 @@ _software_version_reduced = packaging.version.Version( "{v.major}.{v.minor}".format(v=packaging.version.parse(__version__)) ) +_display_check_warning = True def _check_versions(version): @@ -90,7 +91,8 @@ def _check_versions(version): :param version: string version of software used to create the file. If None, version was not provided :type version: str, None """ - + if not _display_check_warning: + return file_version = packaging.version.parse(version) if version is not None else None if file_version is None or file_version < _software_version_reduced: logger.warning( @@ -774,7 +776,7 @@ def load_file(cls, filename, **kwargs): zarr_file = filename_.endswith(end) else: zarr_file = False - logger.info(f"loading file '{filename}'") + logger.info(f"loading file '{filename_}'") if zarr_file: return cls.load_from_zarr(filename, **kwargs) else: diff --git a/src/py_eddy_tracker/tracking.py b/src/py_eddy_tracker/tracking.py index 9329e3bd..b64b6fcc 100644 --- a/src/py_eddy_tracker/tracking.py +++ b/src/py_eddy_tracker/tracking.py @@ -2,11 +2,11 @@ """ Class to store link between observations """ - from datetime import datetime, timedelta import json import logging import platform +from tarfile import ExFileObject from netCDF4 import Dataset, default_fillvals from numba import njit, types as numba_types @@ -375,7 +375,10 @@ def track(self): # We begin with second file, first one is in previous for file_name in self.datasets[first_dataset:]: self.swap_dataset(file_name, **kwargs) - logger.info("%s match with previous state", file_name) + filename_ = ( + file_name.filename if isinstance(file_name, ExFileObject) else file_name + ) + logger.info("%s match with previous state", filename_) logger.debug("%d obs to match", len(self.current_obs)) nb_real_obs = len(self.previous_obs) From 65971875c9aa530a4038bbc6b2b9321cc6c4374d Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Wed, 10 May 2023 16:53:13 +0200 Subject: [PATCH 226/249] Correction on vertice overlap which use same variable for two things ... --- src/py_eddy_tracker/poly.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/py_eddy_tracker/poly.py b/src/py_eddy_tracker/poly.py index 491b0c3a..b5849610 100644 --- a/src/py_eddy_tracker/poly.py +++ b/src/py_eddy_tracker/poly.py @@ -477,22 +477,22 @@ def vertice_overlap( if intersection == 0: cost[i] = 0 continue - p0_area, p1_area = p0.area(), p1.area() + p0_area_, p1_area_ = p0.area(), p1.area() if minimal_area: - cost_ = intersection / min(p0_area, p1_area) + cost_ = intersection / min(p0_area_, p1_area_) # we divide intersection with p1 elif p1_area: - cost_ = intersection / p1_area + cost_ = intersection / p1_area_ # we divide intersection with polygon merging result from 0 to 1 else: - cost_ = intersection / (p0_area + p1_area - intersection) + cost_ = intersection / (p0_area_ + p1_area_ - intersection) if cost_ >= min_overlap: cost[i] = cost_ else: if ( hybrid_area and cost_ != 0 - and (intersection / min(p0_area, p1_area)) > 0.99 + and (intersection / min(p0_area_, p1_area_)) > 0.99 ): cost[i] = cost_ else: From e659c503f62e02f511f4a151f122756b90e22522 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle <36040805+AntSimi@users.noreply.github.com> Date: Wed, 20 Sep 2023 09:50:59 +0200 Subject: [PATCH 227/249] Update pet_okubo_weiss.py change sign in formula --- examples/06_grid_manipulation/pet_okubo_weiss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/06_grid_manipulation/pet_okubo_weiss.py b/examples/06_grid_manipulation/pet_okubo_weiss.py index 818a6742..aa8a063e 100644 --- a/examples/06_grid_manipulation/pet_okubo_weiss.py +++ b/examples/06_grid_manipulation/pet_okubo_weiss.py @@ -2,7 +2,7 @@ Get Okubo Weis ============== -.. math:: OW = S_n^2 + S_s^2 + \omega^2 +.. math:: OW = S_n^2 + S_s^2 - \omega^2 with normal strain (:math:`S_n`), shear strain (:math:`S_s`) and vorticity (:math:`\omega`) From 73b017c9e4c7a60c33ad339eb82248bc3bda9237 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle <36040805+AntSimi@users.noreply.github.com> Date: Wed, 27 Sep 2023 15:34:01 +0200 Subject: [PATCH 228/249] issue #207 change speed compute formula to avoid mask shrinking --- src/py_eddy_tracker/dataset/grid.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index 7e9a04be..edb96bac 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -38,6 +38,7 @@ round_, sin, sinc, + sqrt, where, zeros, ) @@ -1919,7 +1920,8 @@ def speed_coef_mean(self, contour): def init_speed_coef(self, uname="u", vname="v"): """Draft""" - self._speed_ev = (self.grid(uname) ** 2 + self.grid(vname) ** 2) ** 0.5 + u, v = self.grid(uname), self.grid(vname) + self._speed_ev = sqrt(u * u + v * v) def display(self, ax, name, factor=1, ref=None, **kwargs): """ From c7430cef0f9f133296db0ef144ebd15a73d73300 Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle <36040805+AntSimi@users.noreply.github.com> Date: Thu, 21 Dec 2023 10:49:48 +0100 Subject: [PATCH 229/249] Update python-app.yml python version --- .github/workflows/python-app.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 00dbcc95..f2f4753e 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -11,7 +11,7 @@ jobs: matrix: # os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, windows-latest] - python_version: ['3.10'] + python_version: ['3.10', '3.11', '3.12'] name: Run py eddy tracker build tests runs-on: ${{ matrix.os }} defaults: From 62e283be6558e9abec374d153bfbbaa3ffb8415a Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Mon, 29 Jul 2024 14:50:11 +0200 Subject: [PATCH 230/249] specify ubuntu lts --- .github/workflows/python-app.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index f2f4753e..7c93faae 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -10,7 +10,7 @@ jobs: strategy: matrix: # os: [ubuntu-latest, macos-latest, windows-latest] - os: [ubuntu-latest, windows-latest] + os: [ubuntu-lts-latest, windows-latest] python_version: ['3.10', '3.11', '3.12'] name: Run py eddy tracker build tests runs-on: ${{ matrix.os }} From e6d4ada203bfe29b2a7231428948fcba7bbbcc74 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Mon, 29 Jul 2024 14:56:25 +0200 Subject: [PATCH 231/249] Specify os for readthedocs --- .readthedocs.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.readthedocs.yml b/.readthedocs.yml index 1299f38e..ec749526 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,6 +1,8 @@ version: 2 conda: environment: doc/environment.yml +build: + os: ubuntu-lts-latest python: install: - method: setuptools From 80f8e143adf5ae992286cbe42336730e88a06c9e Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Mon, 29 Jul 2024 14:58:56 +0200 Subject: [PATCH 232/249] Add python spec for readthedocs --- .readthedocs.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index ec749526..a04495b6 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -3,7 +3,9 @@ conda: environment: doc/environment.yml build: os: ubuntu-lts-latest + tools: + python: "3.10" python: - install: - - method: setuptools - path: . + install: + - method: setuptools + path: . From 27bafc6d7bb21b02e2ceada0d048a906b4616609 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Mon, 29 Jul 2024 15:08:35 +0200 Subject: [PATCH 233/249] update versionner --- src/py_eddy_tracker/__init__.py | 12 +- src/py_eddy_tracker/_version.py | 449 ++++++++++++++++++++------------ 2 files changed, 296 insertions(+), 165 deletions(-) diff --git a/src/py_eddy_tracker/__init__.py b/src/py_eddy_tracker/__init__.py index 0a98892d..7115bf67 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -32,13 +32,13 @@ del get_versions -def start_logger(): +def start_logger(color=True): FORMAT_LOG = "%(levelname)-8s %(asctime)s %(module)s.%(funcName)s :\n\t%(message)s" logger = logging.getLogger("pet") if len(logger.handlers) == 0: # set up logging to CONSOLE console = logging.StreamHandler() - console.setFormatter(ColoredFormatter(FORMAT_LOG)) + console.setFormatter(ColoredFormatter(FORMAT_LOG, color=color)) # add the handler to the root logger logger.addHandler(console) return logger @@ -53,13 +53,14 @@ class ColoredFormatter(logging.Formatter): DEBUG="\033[34m\t", ) - def __init__(self, message): + def __init__(self, message, color=True): super().__init__(message) + self.with_color = color def format(self, record): color = self.COLOR_LEVEL.get(record.levelname, "") color_reset = "\033[0m" - model = color + "%s" + color_reset + model = (color + "%s" + color_reset) if self.with_color else "%s" record.msg = model % record.msg record.funcName = model % record.funcName record.module = model % record.module @@ -696,3 +697,6 @@ def identify_time(str_date): VAR_DESCR_inv[VAR_DESCR[key]["nc_name"]] = key for key_old in VAR_DESCR[key].get("old_nc_name", list()): VAR_DESCR_inv[key_old] = key + +from . import _version +__version__ = _version.get_versions()['version'] diff --git a/src/py_eddy_tracker/_version.py b/src/py_eddy_tracker/_version.py index 44367e3a..589e706f 100644 --- a/src/py_eddy_tracker/_version.py +++ b/src/py_eddy_tracker/_version.py @@ -1,11 +1,13 @@ + # This file helps to compute a version number in source trees obtained from # git-archive tarball (such as those provided by githubs download-from-tag # feature). Distribution tarballs (built by setup.py sdist) and build # directories (produced by setup.py build) will contain a much shorter file # that just contains the computed version number. -# This file is released into the public domain. Generated by -# versioneer-0.18 (https://github.com/warner/python-versioneer) +# This file is released into the public domain. +# Generated by versioneer-0.29 +# https://github.com/python-versioneer/python-versioneer """Git implementation of _version.py.""" @@ -14,9 +16,11 @@ import re import subprocess import sys +from typing import Any, Callable, Dict, List, Optional, Tuple +import functools -def get_keywords(): +def get_keywords() -> Dict[str, str]: """Get the keywords needed to look up the version information.""" # these strings will be replaced by git during git-archive. # setup.py/versioneer.py will grep for the variable names, so they must @@ -32,8 +36,15 @@ def get_keywords(): class VersioneerConfig: """Container for Versioneer configuration parameters.""" + VCS: str + style: str + tag_prefix: str + parentdir_prefix: str + versionfile_source: str + verbose: bool + -def get_config(): +def get_config() -> VersioneerConfig: """Create, populate and return the VersioneerConfig() object.""" # these strings are filled in when 'setup.py versioneer' creates # _version.py @@ -51,41 +62,50 @@ class NotThisMethod(Exception): """Exception raised if a method is not valid for the current scenario.""" -LONG_VERSION_PY = {} -HANDLERS = {} - +LONG_VERSION_PY: Dict[str, str] = {} +HANDLERS: Dict[str, Dict[str, Callable]] = {} -def register_vcs_handler(vcs, method): # decorator - """Decorator to mark a method as the handler for a particular VCS.""" - def decorate(f): +def register_vcs_handler(vcs: str, method: str) -> Callable: # decorator + """Create decorator to mark a method as the handler of a VCS.""" + def decorate(f: Callable) -> Callable: """Store f in HANDLERS[vcs][method].""" if vcs not in HANDLERS: HANDLERS[vcs] = {} HANDLERS[vcs][method] = f return f - return decorate -def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=None): +def run_command( + commands: List[str], + args: List[str], + cwd: Optional[str] = None, + verbose: bool = False, + hide_stderr: bool = False, + env: Optional[Dict[str, str]] = None, +) -> Tuple[Optional[str], Optional[int]]: """Call the given command(s).""" assert isinstance(commands, list) - p = None - for c in commands: + process = None + + popen_kwargs: Dict[str, Any] = {} + if sys.platform == "win32": + # This hides the console window if pythonw.exe is used + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + popen_kwargs["startupinfo"] = startupinfo + + for command in commands: try: - dispcmd = str([c] + args) + dispcmd = str([command] + args) # remember shell=False, so use git.cmd on windows, not just git - p = subprocess.Popen( - [c] + args, - cwd=cwd, - env=env, - stdout=subprocess.PIPE, - stderr=(subprocess.PIPE if hide_stderr else None), - ) + process = subprocess.Popen([command] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None), **popen_kwargs) break - except EnvironmentError: - e = sys.exc_info()[1] + except OSError as e: if e.errno == errno.ENOENT: continue if verbose: @@ -96,18 +116,20 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env= if verbose: print("unable to find command, tried %s" % (commands,)) return None, None - stdout = p.communicate()[0].strip() - if sys.version_info[0] >= 3: - stdout = stdout.decode() - if p.returncode != 0: + stdout = process.communicate()[0].strip().decode() + if process.returncode != 0: if verbose: print("unable to run %s (error)" % dispcmd) print("stdout was %s" % stdout) - return None, p.returncode - return stdout, p.returncode + return None, process.returncode + return stdout, process.returncode -def versions_from_parentdir(parentdir_prefix, root, verbose): +def versions_from_parentdir( + parentdir_prefix: str, + root: str, + verbose: bool, +) -> Dict[str, Any]: """Try to determine the version from the parent directory name. Source tarballs conventionally unpack into a directory that includes both @@ -116,64 +138,64 @@ def versions_from_parentdir(parentdir_prefix, root, verbose): """ rootdirs = [] - for i in range(3): + for _ in range(3): dirname = os.path.basename(root) if dirname.startswith(parentdir_prefix): - return { - "version": dirname[len(parentdir_prefix) :], - "full-revisionid": None, - "dirty": False, - "error": None, - "date": None, - } - else: - rootdirs.append(root) - root = os.path.dirname(root) # up a level + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} + rootdirs.append(root) + root = os.path.dirname(root) # up a level if verbose: - print( - "Tried directories %s but none started with prefix %s" - % (str(rootdirs), parentdir_prefix) - ) + print("Tried directories %s but none started with prefix %s" % + (str(rootdirs), parentdir_prefix)) raise NotThisMethod("rootdir doesn't start with parentdir_prefix") @register_vcs_handler("git", "get_keywords") -def git_get_keywords(versionfile_abs): +def git_get_keywords(versionfile_abs: str) -> Dict[str, str]: """Extract version information from the given file.""" # the code embedded in _version.py can just fetch the value of these # keywords. When used from setup.py, we don't want to import _version.py, # so we do it with a regexp instead. This function is not used from # _version.py. - keywords = {} + keywords: Dict[str, str] = {} try: - f = open(versionfile_abs, "r") - for line in f.readlines(): - if line.strip().startswith("git_refnames ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["refnames"] = mo.group(1) - if line.strip().startswith("git_full ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["full"] = mo.group(1) - if line.strip().startswith("git_date ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["date"] = mo.group(1) - f.close() - except EnvironmentError: + with open(versionfile_abs, "r") as fobj: + for line in fobj: + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + except OSError: pass return keywords @register_vcs_handler("git", "keywords") -def git_versions_from_keywords(keywords, tag_prefix, verbose): +def git_versions_from_keywords( + keywords: Dict[str, str], + tag_prefix: str, + verbose: bool, +) -> Dict[str, Any]: """Get version information from git keywords.""" - if not keywords: - raise NotThisMethod("no keywords at all, weird") + if "refnames" not in keywords: + raise NotThisMethod("Short version file found") date = keywords.get("date") if date is not None: + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 # -like" string, which we must then edit to make compliant), because @@ -186,11 +208,11 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): if verbose: print("keywords are unexpanded, not using") raise NotThisMethod("unexpanded keywords, not a git-archive tarball") - refs = set([r.strip() for r in refnames.strip("()").split(",")]) + refs = {r.strip() for r in refnames.strip("()").split(",")} # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of # just "foo-1.0". If we see a "tag: " prefix, prefer those. TAG = "tag: " - tags = set([r[len(TAG) :] for r in refs if r.startswith(TAG)]) + tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} if not tags: # Either we're using git < 1.8.3, or there really are no tags. We use # a heuristic: assume all version tags have a digit. The old git %d @@ -199,7 +221,7 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): # between branches and tags. By ignoring refnames without digits, we # filter out many common branch names like "release" and # "stabilization", as well as "HEAD" and "master". - tags = set([r for r in refs if re.search(r"\d", r)]) + tags = {r for r in refs if re.search(r'\d', r)} if verbose: print("discarding '%s', no digits" % ",".join(refs - tags)) if verbose: @@ -207,30 +229,33 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): for ref in sorted(tags): # sorting will prefer e.g. "2.0" over "2.0rc1" if ref.startswith(tag_prefix): - r = ref[len(tag_prefix) :] + r = ref[len(tag_prefix):] + # Filter out refs that exactly match prefix or that don't start + # with a number once the prefix is stripped (mostly a concern + # when prefix is '') + if not re.match(r'\d', r): + continue if verbose: print("picking %s" % r) - return { - "version": r, - "full-revisionid": keywords["full"].strip(), - "dirty": False, - "error": None, - "date": date, - } + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} # no suitable tags, so version is "0+unknown", but full hex is still there if verbose: print("no suitable tags, using unknown + full revision id") - return { - "version": "0+unknown", - "full-revisionid": keywords["full"].strip(), - "dirty": False, - "error": "no suitable tags", - "date": None, - } + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} @register_vcs_handler("git", "pieces_from_vcs") -def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): +def git_pieces_from_vcs( + tag_prefix: str, + root: str, + verbose: bool, + runner: Callable = run_command +) -> Dict[str, Any]: """Get version from 'git describe' in the root of the source tree. This only gets called if the git-archive 'subst' keywords were *not* @@ -241,7 +266,15 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] - out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True) + # GIT_DIR can interfere with correct operation of Versioneer. + # It may be intended to be passed to the Versioneer-versioned project, + # but that should not change where we get our version from. + env = os.environ.copy() + env.pop("GIT_DIR", None) + runner = functools.partial(runner, env=env) + + _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=not verbose) if rc != 0: if verbose: print("Directory %s not under git control" % root) @@ -249,33 +282,57 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] # if there isn't one, this yields HEX[-dirty] (no NUM) - describe_out, rc = run_command( - GITS, - [ - "describe", - "--tags", - "--dirty", - "--always", - "--long", - "--match", - "%s*" % tag_prefix, - ], - cwd=root, - ) + describe_out, rc = runner(GITS, [ + "describe", "--tags", "--dirty", "--always", "--long", + "--match", f"{tag_prefix}[[:digit:]]*" + ], cwd=root) # --long was added in git-1.5.5 if describe_out is None: raise NotThisMethod("'git describe' failed") describe_out = describe_out.strip() - full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) + full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root) if full_out is None: raise NotThisMethod("'git rev-parse' failed") full_out = full_out.strip() - pieces = {} + pieces: Dict[str, Any] = {} pieces["long"] = full_out pieces["short"] = full_out[:7] # maybe improved later pieces["error"] = None + branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], + cwd=root) + # --abbrev-ref was added in git-1.6.3 + if rc != 0 or branch_name is None: + raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") + branch_name = branch_name.strip() + + if branch_name == "HEAD": + # If we aren't exactly on a branch, pick a branch which represents + # the current commit. If all else fails, we are on a branchless + # commit. + branches, rc = runner(GITS, ["branch", "--contains"], cwd=root) + # --contains was added in git-1.5.4 + if rc != 0 or branches is None: + raise NotThisMethod("'git branch --contains' returned error") + branches = branches.split("\n") + + # Remove the first line if we're running detached + if "(" in branches[0]: + branches.pop(0) + + # Strip off the leading "* " from the list of branches. + branches = [branch[2:] for branch in branches] + if "master" in branches: + branch_name = "master" + elif not branches: + branch_name = None + else: + # Pick the first branch that is returned. Good or bad. + branch_name = branches[0] + + pieces["branch"] = branch_name + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] # TAG might have hyphens. git_describe = describe_out @@ -284,16 +341,17 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): dirty = git_describe.endswith("-dirty") pieces["dirty"] = dirty if dirty: - git_describe = git_describe[: git_describe.rindex("-dirty")] + git_describe = git_describe[:git_describe.rindex("-dirty")] # now we have TAG-NUM-gHEX or HEX if "-" in git_describe: # TAG-NUM-gHEX - mo = re.search(r"^(.+)-(\d+)-g([0-9a-f]+)$", git_describe) + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) if not mo: - # unparseable. Maybe git-describe is misbehaving? - pieces["error"] = "unable to parse git-describe output: '%s'" % describe_out + # unparsable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%s'" + % describe_out) return pieces # tag @@ -302,12 +360,10 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): if verbose: fmt = "tag '%s' doesn't start with prefix '%s'" print(fmt % (full_tag, tag_prefix)) - pieces["error"] = "tag '%s' doesn't start with prefix '%s'" % ( - full_tag, - tag_prefix, - ) + pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" + % (full_tag, tag_prefix)) return pieces - pieces["closest-tag"] = full_tag[len(tag_prefix) :] + pieces["closest-tag"] = full_tag[len(tag_prefix):] # distance: number of commits since tag pieces["distance"] = int(mo.group(2)) @@ -318,26 +374,27 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): else: # HEX: no tags pieces["closest-tag"] = None - count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], cwd=root) - pieces["distance"] = int(count_out) # total number of commits + out, rc = runner(GITS, ["rev-list", "HEAD", "--left-right"], cwd=root) + pieces["distance"] = len(out.split()) # total number of commits # commit date: see ISO-8601 comment in git_versions_from_keywords() - date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[ - 0 - ].strip() + date = runner(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip() + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) return pieces -def plus_or_dot(pieces): +def plus_or_dot(pieces: Dict[str, Any]) -> str: """Return a + if we don't already have one, else return a .""" if "+" in pieces.get("closest-tag", ""): return "." return "+" -def render_pep440(pieces): +def render_pep440(pieces: Dict[str, Any]) -> str: """Build up version string, with post-release "local version identifier". Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you @@ -355,29 +412,78 @@ def render_pep440(pieces): rendered += ".dirty" else: # exception #1 - rendered = "0+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) + rendered = "0+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered -def render_pep440_pre(pieces): - """TAG[.post.devDISTANCE] -- No -dirty. +def render_pep440_branch(pieces: Dict[str, Any]) -> str: + """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] . + + The ".dev0" means not master branch. Note that .dev0 sorts backwards + (a feature branch will appear "older" than the master branch). Exceptions: - 1: no tags. 0.post.devDISTANCE + 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0" + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def pep440_split_post(ver: str) -> Tuple[str, Optional[int]]: + """Split pep440 version string at the post-release segment. + + Returns the release segments before the post-release and the + post-release version number (or -1 if no post-release segment is present). + """ + vc = str.split(ver, ".post") + return vc[0], int(vc[1] or 0) if len(vc) == 2 else None + + +def render_pep440_pre(pieces: Dict[str, Any]) -> str: + """TAG[.postN.devDISTANCE] -- No -dirty. + + Exceptions: + 1: no tags. 0.post0.devDISTANCE + """ + if pieces["closest-tag"]: if pieces["distance"]: - rendered += ".post.dev%d" % pieces["distance"] + # update the post release segment + tag_version, post_version = pep440_split_post(pieces["closest-tag"]) + rendered = tag_version + if post_version is not None: + rendered += ".post%d.dev%d" % (post_version + 1, pieces["distance"]) + else: + rendered += ".post0.dev%d" % (pieces["distance"]) + else: + # no commits, use the tag as the version + rendered = pieces["closest-tag"] else: # exception #1 - rendered = "0.post.dev%d" % pieces["distance"] + rendered = "0.post0.dev%d" % pieces["distance"] return rendered -def render_pep440_post(pieces): +def render_pep440_post(pieces: Dict[str, Any]) -> str: """TAG[.postDISTANCE[.dev0]+gHEX] . The ".dev0" means dirty. Note that .dev0 sorts backwards @@ -404,12 +510,41 @@ def render_pep440_post(pieces): return rendered -def render_pep440_old(pieces): +def render_pep440_post_branch(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] . + + The ".dev0" means not master branch. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_old(pieces: Dict[str, Any]) -> str: """TAG[.postDISTANCE[.dev0]] . The ".dev0" means dirty. - Eexceptions: + Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: @@ -426,7 +561,7 @@ def render_pep440_old(pieces): return rendered -def render_git_describe(pieces): +def render_git_describe(pieces: Dict[str, Any]) -> str: """TAG[-DISTANCE-gHEX][-dirty]. Like 'git describe --tags --dirty --always'. @@ -446,7 +581,7 @@ def render_git_describe(pieces): return rendered -def render_git_describe_long(pieces): +def render_git_describe_long(pieces: Dict[str, Any]) -> str: """TAG-DISTANCE-gHEX[-dirty]. Like 'git describe --tags --dirty --always -long'. @@ -466,26 +601,28 @@ def render_git_describe_long(pieces): return rendered -def render(pieces, style): +def render(pieces: Dict[str, Any], style: str) -> Dict[str, Any]: """Render the given version pieces into the requested style.""" if pieces["error"]: - return { - "version": "unknown", - "full-revisionid": pieces.get("long"), - "dirty": None, - "error": pieces["error"], - "date": None, - } + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} if not style or style == "default": style = "pep440" # the default if style == "pep440": rendered = render_pep440(pieces) + elif style == "pep440-branch": + rendered = render_pep440_branch(pieces) elif style == "pep440-pre": rendered = render_pep440_pre(pieces) elif style == "pep440-post": rendered = render_pep440_post(pieces) + elif style == "pep440-post-branch": + rendered = render_pep440_post_branch(pieces) elif style == "pep440-old": rendered = render_pep440_old(pieces) elif style == "git-describe": @@ -495,16 +632,12 @@ def render(pieces, style): else: raise ValueError("unknown style '%s'" % style) - return { - "version": rendered, - "full-revisionid": pieces["long"], - "dirty": pieces["dirty"], - "error": None, - "date": pieces.get("date"), - } + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} -def get_versions(): +def get_versions() -> Dict[str, Any]: """Get version information or return default if unable to do so.""" # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have # __file__, we can work backwards from there to the root. Some @@ -515,7 +648,8 @@ def get_versions(): verbose = cfg.verbose try: - return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, verbose) + return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, + verbose) except NotThisMethod: pass @@ -524,16 +658,13 @@ def get_versions(): # versionfile_source is the relative path from the top of the source # tree (where the .git directory might live) to this file. Invert # this to find the root from __file__. - for i in cfg.versionfile_source.split("/"): + for _ in cfg.versionfile_source.split('/'): root = os.path.dirname(root) except NameError: - return { - "version": "0+unknown", - "full-revisionid": None, - "dirty": None, - "error": "unable to find root of source tree", - "date": None, - } + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to find root of source tree", + "date": None} try: pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) @@ -547,10 +678,6 @@ def get_versions(): except NotThisMethod: pass - return { - "version": "0+unknown", - "full-revisionid": None, - "dirty": None, - "error": "unable to compute version", - "date": None, - } + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to compute version", "date": None} From 0cb3230e8a97731e25d8e8d65df1e405c1d6406c Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Mon, 29 Jul 2024 15:13:00 +0200 Subject: [PATCH 234/249] versionner file --- versioneer.py | 1354 +++++++++++++++++++++++++++++++------------------ 1 file changed, 873 insertions(+), 481 deletions(-) diff --git a/versioneer.py b/versioneer.py index 2b545405..1e3753e6 100644 --- a/versioneer.py +++ b/versioneer.py @@ -1,4 +1,5 @@ -# Version: 0.18 + +# Version: 0.29 """The Versioneer - like a rocketeer, but for versions. @@ -6,18 +7,14 @@ ============== * like a rocketeer, but for versions! -* https://github.com/warner/python-versioneer +* https://github.com/python-versioneer/python-versioneer * Brian Warner -* License: Public Domain -* Compatible With: python2.6, 2.7, 3.2, 3.3, 3.4, 3.5, 3.6, and pypy -* [![Latest Version] -(https://pypip.in/version/versioneer/badge.svg?style=flat) -](https://pypi.python.org/pypi/versioneer/) -* [![Build Status] -(https://travis-ci.org/warner/python-versioneer.png?branch=master) -](https://travis-ci.org/warner/python-versioneer) - -This is a tool for managing a recorded version number in distutils-based +* License: Public Domain (Unlicense) +* Compatible with: Python 3.7, 3.8, 3.9, 3.10, 3.11 and pypy3 +* [![Latest Version][pypi-image]][pypi-url] +* [![Build Status][travis-image]][travis-url] + +This is a tool for managing a recorded version number in setuptools-based python projects. The goal is to remove the tedious and error-prone "update the embedded version string" step from your release process. Making a new release should be as easy as recording a new tag in your version-control @@ -26,9 +23,38 @@ ## Quick Install -* `pip install versioneer` to somewhere to your $PATH -* add a `[versioneer]` section to your setup.cfg (see below) -* run `versioneer install` in your source tree, commit the results +Versioneer provides two installation modes. The "classic" vendored mode installs +a copy of versioneer into your repository. The experimental build-time dependency mode +is intended to allow you to skip this step and simplify the process of upgrading. + +### Vendored mode + +* `pip install versioneer` to somewhere in your $PATH + * A [conda-forge recipe](https://github.com/conda-forge/versioneer-feedstock) is + available, so you can also use `conda install -c conda-forge versioneer` +* add a `[tool.versioneer]` section to your `pyproject.toml` or a + `[versioneer]` section to your `setup.cfg` (see [Install](INSTALL.md)) + * Note that you will need to add `tomli; python_version < "3.11"` to your + build-time dependencies if you use `pyproject.toml` +* run `versioneer install --vendor` in your source tree, commit the results +* verify version information with `python setup.py version` + +### Build-time dependency mode + +* `pip install versioneer` to somewhere in your $PATH + * A [conda-forge recipe](https://github.com/conda-forge/versioneer-feedstock) is + available, so you can also use `conda install -c conda-forge versioneer` +* add a `[tool.versioneer]` section to your `pyproject.toml` or a + `[versioneer]` section to your `setup.cfg` (see [Install](INSTALL.md)) +* add `versioneer` (with `[toml]` extra, if configuring in `pyproject.toml`) + to the `requires` key of the `build-system` table in `pyproject.toml`: + ```toml + [build-system] + requires = ["setuptools", "versioneer[toml]"] + build-backend = "setuptools.build_meta" + ``` +* run `versioneer install --no-vendor` in your source tree, commit the results +* verify version information with `python setup.py version` ## Version Identifiers @@ -60,7 +86,7 @@ for example `git describe --tags --dirty --always` reports things like "0.7-1-g574ab98-dirty" to indicate that the checkout is one revision past the 0.7 tag, has a unique revision id of "574ab98", and is "dirty" (it has -uncommitted changes. +uncommitted changes). The version identifier is used for multiple purposes: @@ -165,7 +191,7 @@ Some situations are known to cause problems for Versioneer. This details the most significant ones. More can be found on Github -[issues page](https://github.com/warner/python-versioneer/issues). +[issues page](https://github.com/python-versioneer/python-versioneer/issues). ### Subprojects @@ -179,7 +205,7 @@ `setup.cfg`, and `tox.ini`. Projects like these produce multiple PyPI distributions (and upload multiple independently-installable tarballs). * Source trees whose main purpose is to contain a C library, but which also - provide bindings to Python (and perhaps other langauges) in subdirectories. + provide bindings to Python (and perhaps other languages) in subdirectories. Versioneer will look for `.git` in parent directories, and most operations should get the right version string. However `pip` and `setuptools` have bugs @@ -193,9 +219,9 @@ Pip-8.1.1 is known to have this problem, but hopefully it will get fixed in some later version. -[Bug #38](https://github.com/warner/python-versioneer/issues/38) is tracking +[Bug #38](https://github.com/python-versioneer/python-versioneer/issues/38) is tracking this issue. The discussion in -[PR #61](https://github.com/warner/python-versioneer/pull/61) describes the +[PR #61](https://github.com/python-versioneer/python-versioneer/pull/61) describes the issue from the Versioneer side in more detail. [pip PR#3176](https://github.com/pypa/pip/pull/3176) and [pip PR#3615](https://github.com/pypa/pip/pull/3615) contain work to improve @@ -223,31 +249,20 @@ cause egg_info to be rebuilt (including `sdist`, `wheel`, and installing into a different virtualenv), so this can be surprising. -[Bug #83](https://github.com/warner/python-versioneer/issues/83) describes +[Bug #83](https://github.com/python-versioneer/python-versioneer/issues/83) describes this one, but upgrading to a newer version of setuptools should probably resolve it. -### Unicode version strings - -While Versioneer works (and is continually tested) with both Python 2 and -Python 3, it is not entirely consistent with bytes-vs-unicode distinctions. -Newer releases probably generate unicode version strings on py2. It's not -clear that this is wrong, but it may be surprising for applications when then -write these strings to a network connection or include them in bytes-oriented -APIs like cryptographic checksums. - -[Bug #71](https://github.com/warner/python-versioneer/issues/71) investigates -this question. - ## Updating Versioneer To upgrade your project to a new release of Versioneer, do the following: * install the new Versioneer (`pip install -U versioneer` or equivalent) -* edit `setup.cfg`, if necessary, to include any new configuration settings - indicated by the release notes. See [UPGRADING](./UPGRADING.md) for details. -* re-run `versioneer install` in your source tree, to replace +* edit `setup.cfg` and `pyproject.toml`, if necessary, + to include any new configuration settings indicated by the release notes. + See [UPGRADING](./UPGRADING.md) for details. +* re-run `versioneer install --[no-]vendor` in your source tree, to replace `SRC/_version.py` * commit any changed files @@ -264,36 +279,70 @@ direction and include code from all supported VCS systems, reducing the number of intermediate scripts. +## Similar projects + +* [setuptools_scm](https://github.com/pypa/setuptools_scm/) - a non-vendored build-time + dependency +* [minver](https://github.com/jbweston/miniver) - a lightweight reimplementation of + versioneer +* [versioningit](https://github.com/jwodder/versioningit) - a PEP 518-based setuptools + plugin ## License To make Versioneer easier to embed, all its code is dedicated to the public domain. The `_version.py` that it creates is also in the public domain. -Specifically, both are released under the Creative Commons "Public Domain -Dedication" license (CC0-1.0), as described in -https://creativecommons.org/publicdomain/zero/1.0/ . +Specifically, both are released under the "Unlicense", as described in +https://unlicense.org/. -""" +[pypi-image]: https://img.shields.io/pypi/v/versioneer.svg +[pypi-url]: https://pypi.python.org/pypi/versioneer/ +[travis-image]: +https://img.shields.io/travis/com/python-versioneer/python-versioneer.svg +[travis-url]: https://travis-ci.com/github/python-versioneer/python-versioneer -from __future__ import print_function +""" +# pylint:disable=invalid-name,import-outside-toplevel,missing-function-docstring +# pylint:disable=missing-class-docstring,too-many-branches,too-many-statements +# pylint:disable=raise-missing-from,too-many-lines,too-many-locals,import-error +# pylint:disable=too-few-public-methods,redefined-outer-name,consider-using-with +# pylint:disable=attribute-defined-outside-init,too-many-arguments -try: - import configparser -except ImportError: - import ConfigParser as configparser +import configparser import errno import json import os import re import subprocess import sys +from pathlib import Path +from typing import Any, Callable, cast, Dict, List, Optional, Tuple, Union +from typing import NoReturn +import functools + +have_tomllib = True +if sys.version_info >= (3, 11): + import tomllib +else: + try: + import tomli as tomllib + except ImportError: + have_tomllib = False class VersioneerConfig: """Container for Versioneer configuration parameters.""" + VCS: str + style: str + tag_prefix: str + versionfile_source: str + versionfile_build: Optional[str] + parentdir_prefix: Optional[str] + verbose: Optional[bool] -def get_root(): + +def get_root() -> str: """Get the project root directory. We require that all commands are run from the project root, i.e. the @@ -301,20 +350,28 @@ def get_root(): """ root = os.path.realpath(os.path.abspath(os.getcwd())) setup_py = os.path.join(root, "setup.py") + pyproject_toml = os.path.join(root, "pyproject.toml") versioneer_py = os.path.join(root, "versioneer.py") - if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): + if not ( + os.path.exists(setup_py) + or os.path.exists(pyproject_toml) + or os.path.exists(versioneer_py) + ): # allow 'python path/to/setup.py COMMAND' root = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0]))) setup_py = os.path.join(root, "setup.py") + pyproject_toml = os.path.join(root, "pyproject.toml") versioneer_py = os.path.join(root, "versioneer.py") - if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): - err = ( - "Versioneer was unable to run the project root directory. " - "Versioneer requires setup.py to be executed from " - "its immediate directory (like 'python setup.py COMMAND'), " - "or in a way that lets it use sys.argv[0] to find the root " - "(like 'python path/to/setup.py COMMAND')." - ) + if not ( + os.path.exists(setup_py) + or os.path.exists(pyproject_toml) + or os.path.exists(versioneer_py) + ): + err = ("Versioneer was unable to run the project root directory. " + "Versioneer requires setup.py to be executed from " + "its immediate directory (like 'python setup.py COMMAND'), " + "or in a way that lets it use sys.argv[0] to find the root " + "(like 'python path/to/setup.py COMMAND').") raise VersioneerBadRootError(err) try: # Certain runtime workflows (setup.py install/develop in a setuptools @@ -323,46 +380,62 @@ def get_root(): # module-import table will cache the first one. So we can't use # os.path.dirname(__file__), as that will find whichever # versioneer.py was first imported, even in later projects. - me = os.path.realpath(os.path.abspath(__file__)) - me_dir = os.path.normcase(os.path.splitext(me)[0]) + my_path = os.path.realpath(os.path.abspath(__file__)) + me_dir = os.path.normcase(os.path.splitext(my_path)[0]) vsr_dir = os.path.normcase(os.path.splitext(versioneer_py)[0]) - if me_dir != vsr_dir: - print( - "Warning: build in %s is using versioneer.py from %s" - % (os.path.dirname(me), versioneer_py) - ) + if me_dir != vsr_dir and "VERSIONEER_PEP518" not in globals(): + print("Warning: build in %s is using versioneer.py from %s" + % (os.path.dirname(my_path), versioneer_py)) except NameError: pass return root -def get_config_from_root(root): +def get_config_from_root(root: str) -> VersioneerConfig: """Read the project setup.cfg file to determine Versioneer config.""" - # This might raise EnvironmentError (if setup.cfg is missing), or + # This might raise OSError (if setup.cfg is missing), or # configparser.NoSectionError (if it lacks a [versioneer] section), or # configparser.NoOptionError (if it lacks "VCS="). See the docstring at # the top of versioneer.py for instructions on writing your setup.cfg . - setup_cfg = os.path.join(root, "setup.cfg") - parser = configparser.SafeConfigParser() - with open(setup_cfg, "r") as f: - parser.readfp(f) - VCS = parser.get("versioneer", "VCS") # mandatory - - def get(parser, name): - if parser.has_option("versioneer", name): - return parser.get("versioneer", name) - return None + root_pth = Path(root) + pyproject_toml = root_pth / "pyproject.toml" + setup_cfg = root_pth / "setup.cfg" + section: Union[Dict[str, Any], configparser.SectionProxy, None] = None + if pyproject_toml.exists() and have_tomllib: + try: + with open(pyproject_toml, 'rb') as fobj: + pp = tomllib.load(fobj) + section = pp['tool']['versioneer'] + except (tomllib.TOMLDecodeError, KeyError) as e: + print(f"Failed to load config from {pyproject_toml}: {e}") + print("Try to load it from setup.cfg") + if not section: + parser = configparser.ConfigParser() + with open(setup_cfg) as cfg_file: + parser.read_file(cfg_file) + parser.get("versioneer", "VCS") # raise error if missing + + section = parser["versioneer"] + + # `cast`` really shouldn't be used, but its simplest for the + # common VersioneerConfig users at the moment. We verify against + # `None` values elsewhere where it matters cfg = VersioneerConfig() - cfg.VCS = VCS - cfg.style = get(parser, "style") or "" - cfg.versionfile_source = get(parser, "versionfile_source") - cfg.versionfile_build = get(parser, "versionfile_build") - cfg.tag_prefix = get(parser, "tag_prefix") - if cfg.tag_prefix in ("''", '""'): + cfg.VCS = section['VCS'] + cfg.style = section.get("style", "") + cfg.versionfile_source = cast(str, section.get("versionfile_source")) + cfg.versionfile_build = section.get("versionfile_build") + cfg.tag_prefix = cast(str, section.get("tag_prefix")) + if cfg.tag_prefix in ("''", '""', None): cfg.tag_prefix = "" - cfg.parentdir_prefix = get(parser, "parentdir_prefix") - cfg.verbose = get(parser, "verbose") + cfg.parentdir_prefix = section.get("parentdir_prefix") + if isinstance(section, configparser.SectionProxy): + # Make sure configparser translates to bool + cfg.verbose = section.getboolean("verbose") + else: + cfg.verbose = section.get("verbose") + return cfg @@ -371,41 +444,48 @@ class NotThisMethod(Exception): # these dictionaries contain VCS-specific tools -LONG_VERSION_PY = {} -HANDLERS = {} +LONG_VERSION_PY: Dict[str, str] = {} +HANDLERS: Dict[str, Dict[str, Callable]] = {} -def register_vcs_handler(vcs, method): # decorator - """Decorator to mark a method as the handler for a particular VCS.""" - - def decorate(f): +def register_vcs_handler(vcs: str, method: str) -> Callable: # decorator + """Create decorator to mark a method as the handler of a VCS.""" + def decorate(f: Callable) -> Callable: """Store f in HANDLERS[vcs][method].""" - if vcs not in HANDLERS: - HANDLERS[vcs] = {} - HANDLERS[vcs][method] = f + HANDLERS.setdefault(vcs, {})[method] = f return f - return decorate -def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=None): +def run_command( + commands: List[str], + args: List[str], + cwd: Optional[str] = None, + verbose: bool = False, + hide_stderr: bool = False, + env: Optional[Dict[str, str]] = None, +) -> Tuple[Optional[str], Optional[int]]: """Call the given command(s).""" assert isinstance(commands, list) - p = None - for c in commands: + process = None + + popen_kwargs: Dict[str, Any] = {} + if sys.platform == "win32": + # This hides the console window if pythonw.exe is used + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + popen_kwargs["startupinfo"] = startupinfo + + for command in commands: try: - dispcmd = str([c] + args) + dispcmd = str([command] + args) # remember shell=False, so use git.cmd on windows, not just git - p = subprocess.Popen( - [c] + args, - cwd=cwd, - env=env, - stdout=subprocess.PIPE, - stderr=(subprocess.PIPE if hide_stderr else None), - ) + process = subprocess.Popen([command] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None), **popen_kwargs) break - except EnvironmentError: - e = sys.exc_info()[1] + except OSError as e: if e.errno == errno.ENOENT: continue if verbose: @@ -416,28 +496,25 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env= if verbose: print("unable to find command, tried %s" % (commands,)) return None, None - stdout = p.communicate()[0].strip() - if sys.version_info[0] >= 3: - stdout = stdout.decode() - if p.returncode != 0: + stdout = process.communicate()[0].strip().decode() + if process.returncode != 0: if verbose: print("unable to run %s (error)" % dispcmd) print("stdout was %s" % stdout) - return None, p.returncode - return stdout, p.returncode + return None, process.returncode + return stdout, process.returncode -LONG_VERSION_PY[ - "git" -] = ''' +LONG_VERSION_PY['git'] = r''' # This file helps to compute a version number in source trees obtained from # git-archive tarball (such as those provided by githubs download-from-tag # feature). Distribution tarballs (built by setup.py sdist) and build # directories (produced by setup.py build) will contain a much shorter file # that just contains the computed version number. -# This file is released into the public domain. Generated by -# versioneer-0.18 (https://github.com/warner/python-versioneer) +# This file is released into the public domain. +# Generated by versioneer-0.29 +# https://github.com/python-versioneer/python-versioneer """Git implementation of _version.py.""" @@ -446,9 +523,11 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env= import re import subprocess import sys +from typing import Any, Callable, Dict, List, Optional, Tuple +import functools -def get_keywords(): +def get_keywords() -> Dict[str, str]: """Get the keywords needed to look up the version information.""" # these strings will be replaced by git during git-archive. # setup.py/versioneer.py will grep for the variable names, so they must @@ -464,8 +543,15 @@ def get_keywords(): class VersioneerConfig: """Container for Versioneer configuration parameters.""" + VCS: str + style: str + tag_prefix: str + parentdir_prefix: str + versionfile_source: str + verbose: bool + -def get_config(): +def get_config() -> VersioneerConfig: """Create, populate and return the VersioneerConfig() object.""" # these strings are filled in when 'setup.py versioneer' creates # _version.py @@ -483,13 +569,13 @@ class NotThisMethod(Exception): """Exception raised if a method is not valid for the current scenario.""" -LONG_VERSION_PY = {} -HANDLERS = {} +LONG_VERSION_PY: Dict[str, str] = {} +HANDLERS: Dict[str, Dict[str, Callable]] = {} -def register_vcs_handler(vcs, method): # decorator - """Decorator to mark a method as the handler for a particular VCS.""" - def decorate(f): +def register_vcs_handler(vcs: str, method: str) -> Callable: # decorator + """Create decorator to mark a method as the handler of a VCS.""" + def decorate(f: Callable) -> Callable: """Store f in HANDLERS[vcs][method].""" if vcs not in HANDLERS: HANDLERS[vcs] = {} @@ -498,22 +584,35 @@ def decorate(f): return decorate -def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, - env=None): +def run_command( + commands: List[str], + args: List[str], + cwd: Optional[str] = None, + verbose: bool = False, + hide_stderr: bool = False, + env: Optional[Dict[str, str]] = None, +) -> Tuple[Optional[str], Optional[int]]: """Call the given command(s).""" assert isinstance(commands, list) - p = None - for c in commands: + process = None + + popen_kwargs: Dict[str, Any] = {} + if sys.platform == "win32": + # This hides the console window if pythonw.exe is used + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + popen_kwargs["startupinfo"] = startupinfo + + for command in commands: try: - dispcmd = str([c] + args) + dispcmd = str([command] + args) # remember shell=False, so use git.cmd on windows, not just git - p = subprocess.Popen([c] + args, cwd=cwd, env=env, - stdout=subprocess.PIPE, - stderr=(subprocess.PIPE if hide_stderr - else None)) + process = subprocess.Popen([command] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None), **popen_kwargs) break - except EnvironmentError: - e = sys.exc_info()[1] + except OSError as e: if e.errno == errno.ENOENT: continue if verbose: @@ -524,18 +623,20 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, if verbose: print("unable to find command, tried %%s" %% (commands,)) return None, None - stdout = p.communicate()[0].strip() - if sys.version_info[0] >= 3: - stdout = stdout.decode() - if p.returncode != 0: + stdout = process.communicate()[0].strip().decode() + if process.returncode != 0: if verbose: print("unable to run %%s (error)" %% dispcmd) print("stdout was %%s" %% stdout) - return None, p.returncode - return stdout, p.returncode + return None, process.returncode + return stdout, process.returncode -def versions_from_parentdir(parentdir_prefix, root, verbose): +def versions_from_parentdir( + parentdir_prefix: str, + root: str, + verbose: bool, +) -> Dict[str, Any]: """Try to determine the version from the parent directory name. Source tarballs conventionally unpack into a directory that includes both @@ -544,15 +645,14 @@ def versions_from_parentdir(parentdir_prefix, root, verbose): """ rootdirs = [] - for i in range(3): + for _ in range(3): dirname = os.path.basename(root) if dirname.startswith(parentdir_prefix): return {"version": dirname[len(parentdir_prefix):], "full-revisionid": None, "dirty": False, "error": None, "date": None} - else: - rootdirs.append(root) - root = os.path.dirname(root) # up a level + rootdirs.append(root) + root = os.path.dirname(root) # up a level if verbose: print("Tried directories %%s but none started with prefix %%s" %% @@ -561,41 +661,48 @@ def versions_from_parentdir(parentdir_prefix, root, verbose): @register_vcs_handler("git", "get_keywords") -def git_get_keywords(versionfile_abs): +def git_get_keywords(versionfile_abs: str) -> Dict[str, str]: """Extract version information from the given file.""" # the code embedded in _version.py can just fetch the value of these # keywords. When used from setup.py, we don't want to import _version.py, # so we do it with a regexp instead. This function is not used from # _version.py. - keywords = {} + keywords: Dict[str, str] = {} try: - f = open(versionfile_abs, "r") - for line in f.readlines(): - if line.strip().startswith("git_refnames ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["refnames"] = mo.group(1) - if line.strip().startswith("git_full ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["full"] = mo.group(1) - if line.strip().startswith("git_date ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["date"] = mo.group(1) - f.close() - except EnvironmentError: + with open(versionfile_abs, "r") as fobj: + for line in fobj: + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + except OSError: pass return keywords @register_vcs_handler("git", "keywords") -def git_versions_from_keywords(keywords, tag_prefix, verbose): +def git_versions_from_keywords( + keywords: Dict[str, str], + tag_prefix: str, + verbose: bool, +) -> Dict[str, Any]: """Get version information from git keywords.""" - if not keywords: - raise NotThisMethod("no keywords at all, weird") + if "refnames" not in keywords: + raise NotThisMethod("Short version file found") date = keywords.get("date") if date is not None: + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + # git-2.2.0 added "%%cI", which expands to an ISO-8601 -compliant # datestamp. However we prefer "%%ci" (which expands to an "ISO-8601 # -like" string, which we must then edit to make compliant), because @@ -608,11 +715,11 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): if verbose: print("keywords are unexpanded, not using") raise NotThisMethod("unexpanded keywords, not a git-archive tarball") - refs = set([r.strip() for r in refnames.strip("()").split(",")]) + refs = {r.strip() for r in refnames.strip("()").split(",")} # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of # just "foo-1.0". If we see a "tag: " prefix, prefer those. TAG = "tag: " - tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)]) + tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} if not tags: # Either we're using git < 1.8.3, or there really are no tags. We use # a heuristic: assume all version tags have a digit. The old git %%d @@ -621,7 +728,7 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): # between branches and tags. By ignoring refnames without digits, we # filter out many common branch names like "release" and # "stabilization", as well as "HEAD" and "master". - tags = set([r for r in refs if re.search(r'\d', r)]) + tags = {r for r in refs if re.search(r'\d', r)} if verbose: print("discarding '%%s', no digits" %% ",".join(refs - tags)) if verbose: @@ -630,6 +737,11 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): # sorting will prefer e.g. "2.0" over "2.0rc1" if ref.startswith(tag_prefix): r = ref[len(tag_prefix):] + # Filter out refs that exactly match prefix or that don't start + # with a number once the prefix is stripped (mostly a concern + # when prefix is '') + if not re.match(r'\d', r): + continue if verbose: print("picking %%s" %% r) return {"version": r, @@ -645,7 +757,12 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): @register_vcs_handler("git", "pieces_from_vcs") -def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): +def git_pieces_from_vcs( + tag_prefix: str, + root: str, + verbose: bool, + runner: Callable = run_command +) -> Dict[str, Any]: """Get version from 'git describe' in the root of the source tree. This only gets called if the git-archive 'subst' keywords were *not* @@ -656,8 +773,15 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] - out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, - hide_stderr=True) + # GIT_DIR can interfere with correct operation of Versioneer. + # It may be intended to be passed to the Versioneer-versioned project, + # but that should not change where we get our version from. + env = os.environ.copy() + env.pop("GIT_DIR", None) + runner = functools.partial(runner, env=env) + + _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=not verbose) if rc != 0: if verbose: print("Directory %%s not under git control" %% root) @@ -665,24 +789,57 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] # if there isn't one, this yields HEX[-dirty] (no NUM) - describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty", - "--always", "--long", - "--match", "%%s*" %% tag_prefix], - cwd=root) + describe_out, rc = runner(GITS, [ + "describe", "--tags", "--dirty", "--always", "--long", + "--match", f"{tag_prefix}[[:digit:]]*" + ], cwd=root) # --long was added in git-1.5.5 if describe_out is None: raise NotThisMethod("'git describe' failed") describe_out = describe_out.strip() - full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) + full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root) if full_out is None: raise NotThisMethod("'git rev-parse' failed") full_out = full_out.strip() - pieces = {} + pieces: Dict[str, Any] = {} pieces["long"] = full_out pieces["short"] = full_out[:7] # maybe improved later pieces["error"] = None + branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], + cwd=root) + # --abbrev-ref was added in git-1.6.3 + if rc != 0 or branch_name is None: + raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") + branch_name = branch_name.strip() + + if branch_name == "HEAD": + # If we aren't exactly on a branch, pick a branch which represents + # the current commit. If all else fails, we are on a branchless + # commit. + branches, rc = runner(GITS, ["branch", "--contains"], cwd=root) + # --contains was added in git-1.5.4 + if rc != 0 or branches is None: + raise NotThisMethod("'git branch --contains' returned error") + branches = branches.split("\n") + + # Remove the first line if we're running detached + if "(" in branches[0]: + branches.pop(0) + + # Strip off the leading "* " from the list of branches. + branches = [branch[2:] for branch in branches] + if "master" in branches: + branch_name = "master" + elif not branches: + branch_name = None + else: + # Pick the first branch that is returned. Good or bad. + branch_name = branches[0] + + pieces["branch"] = branch_name + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] # TAG might have hyphens. git_describe = describe_out @@ -699,7 +856,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): # TAG-NUM-gHEX mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) if not mo: - # unparseable. Maybe git-describe is misbehaving? + # unparsable. Maybe git-describe is misbehaving? pieces["error"] = ("unable to parse git-describe output: '%%s'" %% describe_out) return pieces @@ -724,26 +881,27 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): else: # HEX: no tags pieces["closest-tag"] = None - count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], - cwd=root) - pieces["distance"] = int(count_out) # total number of commits + out, rc = runner(GITS, ["rev-list", "HEAD", "--left-right"], cwd=root) + pieces["distance"] = len(out.split()) # total number of commits # commit date: see ISO-8601 comment in git_versions_from_keywords() - date = run_command(GITS, ["show", "-s", "--format=%%ci", "HEAD"], - cwd=root)[0].strip() + date = runner(GITS, ["show", "-s", "--format=%%ci", "HEAD"], cwd=root)[0].strip() + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) return pieces -def plus_or_dot(pieces): +def plus_or_dot(pieces: Dict[str, Any]) -> str: """Return a + if we don't already have one, else return a .""" if "+" in pieces.get("closest-tag", ""): return "." return "+" -def render_pep440(pieces): +def render_pep440(pieces: Dict[str, Any]) -> str: """Build up version string, with post-release "local version identifier". Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you @@ -768,23 +926,71 @@ def render_pep440(pieces): return rendered -def render_pep440_pre(pieces): - """TAG[.post.devDISTANCE] -- No -dirty. +def render_pep440_branch(pieces: Dict[str, Any]) -> str: + """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] . + + The ".dev0" means not master branch. Note that .dev0 sorts backwards + (a feature branch will appear "older" than the master branch). Exceptions: - 1: no tags. 0.post.devDISTANCE + 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "%%d.g%%s" %% (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0" + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+untagged.%%d.g%%s" %% (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def pep440_split_post(ver: str) -> Tuple[str, Optional[int]]: + """Split pep440 version string at the post-release segment. + + Returns the release segments before the post-release and the + post-release version number (or -1 if no post-release segment is present). + """ + vc = str.split(ver, ".post") + return vc[0], int(vc[1] or 0) if len(vc) == 2 else None + + +def render_pep440_pre(pieces: Dict[str, Any]) -> str: + """TAG[.postN.devDISTANCE] -- No -dirty. + + Exceptions: + 1: no tags. 0.post0.devDISTANCE + """ + if pieces["closest-tag"]: if pieces["distance"]: - rendered += ".post.dev%%d" %% pieces["distance"] + # update the post release segment + tag_version, post_version = pep440_split_post(pieces["closest-tag"]) + rendered = tag_version + if post_version is not None: + rendered += ".post%%d.dev%%d" %% (post_version + 1, pieces["distance"]) + else: + rendered += ".post0.dev%%d" %% (pieces["distance"]) + else: + # no commits, use the tag as the version + rendered = pieces["closest-tag"] else: # exception #1 - rendered = "0.post.dev%%d" %% pieces["distance"] + rendered = "0.post0.dev%%d" %% pieces["distance"] return rendered -def render_pep440_post(pieces): +def render_pep440_post(pieces: Dict[str, Any]) -> str: """TAG[.postDISTANCE[.dev0]+gHEX] . The ".dev0" means dirty. Note that .dev0 sorts backwards @@ -811,12 +1017,41 @@ def render_pep440_post(pieces): return rendered -def render_pep440_old(pieces): +def render_pep440_post_branch(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] . + + The ".dev0" means not master branch. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%%d" %% pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%%s" %% pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0.post%%d" %% pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+g%%s" %% pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_old(pieces: Dict[str, Any]) -> str: """TAG[.postDISTANCE[.dev0]] . The ".dev0" means dirty. - Eexceptions: + Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: @@ -833,7 +1068,7 @@ def render_pep440_old(pieces): return rendered -def render_git_describe(pieces): +def render_git_describe(pieces: Dict[str, Any]) -> str: """TAG[-DISTANCE-gHEX][-dirty]. Like 'git describe --tags --dirty --always'. @@ -853,7 +1088,7 @@ def render_git_describe(pieces): return rendered -def render_git_describe_long(pieces): +def render_git_describe_long(pieces: Dict[str, Any]) -> str: """TAG-DISTANCE-gHEX[-dirty]. Like 'git describe --tags --dirty --always -long'. @@ -873,7 +1108,7 @@ def render_git_describe_long(pieces): return rendered -def render(pieces, style): +def render(pieces: Dict[str, Any], style: str) -> Dict[str, Any]: """Render the given version pieces into the requested style.""" if pieces["error"]: return {"version": "unknown", @@ -887,10 +1122,14 @@ def render(pieces, style): if style == "pep440": rendered = render_pep440(pieces) + elif style == "pep440-branch": + rendered = render_pep440_branch(pieces) elif style == "pep440-pre": rendered = render_pep440_pre(pieces) elif style == "pep440-post": rendered = render_pep440_post(pieces) + elif style == "pep440-post-branch": + rendered = render_pep440_post_branch(pieces) elif style == "pep440-old": rendered = render_pep440_old(pieces) elif style == "git-describe": @@ -905,7 +1144,7 @@ def render(pieces, style): "date": pieces.get("date")} -def get_versions(): +def get_versions() -> Dict[str, Any]: """Get version information or return default if unable to do so.""" # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have # __file__, we can work backwards from there to the root. Some @@ -926,7 +1165,7 @@ def get_versions(): # versionfile_source is the relative path from the top of the source # tree (where the .git directory might live) to this file. Invert # this to find the root from __file__. - for i in cfg.versionfile_source.split('/'): + for _ in cfg.versionfile_source.split('/'): root = os.path.dirname(root) except NameError: return {"version": "0+unknown", "full-revisionid": None, @@ -953,41 +1192,48 @@ def get_versions(): @register_vcs_handler("git", "get_keywords") -def git_get_keywords(versionfile_abs): +def git_get_keywords(versionfile_abs: str) -> Dict[str, str]: """Extract version information from the given file.""" # the code embedded in _version.py can just fetch the value of these # keywords. When used from setup.py, we don't want to import _version.py, # so we do it with a regexp instead. This function is not used from # _version.py. - keywords = {} + keywords: Dict[str, str] = {} try: - f = open(versionfile_abs, "r") - for line in f.readlines(): - if line.strip().startswith("git_refnames ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["refnames"] = mo.group(1) - if line.strip().startswith("git_full ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["full"] = mo.group(1) - if line.strip().startswith("git_date ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - keywords["date"] = mo.group(1) - f.close() - except EnvironmentError: + with open(versionfile_abs, "r") as fobj: + for line in fobj: + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + except OSError: pass return keywords @register_vcs_handler("git", "keywords") -def git_versions_from_keywords(keywords, tag_prefix, verbose): +def git_versions_from_keywords( + keywords: Dict[str, str], + tag_prefix: str, + verbose: bool, +) -> Dict[str, Any]: """Get version information from git keywords.""" - if not keywords: - raise NotThisMethod("no keywords at all, weird") + if "refnames" not in keywords: + raise NotThisMethod("Short version file found") date = keywords.get("date") if date is not None: + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 # -like" string, which we must then edit to make compliant), because @@ -1000,11 +1246,11 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): if verbose: print("keywords are unexpanded, not using") raise NotThisMethod("unexpanded keywords, not a git-archive tarball") - refs = set([r.strip() for r in refnames.strip("()").split(",")]) + refs = {r.strip() for r in refnames.strip("()").split(",")} # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of # just "foo-1.0". If we see a "tag: " prefix, prefer those. TAG = "tag: " - tags = set([r[len(TAG) :] for r in refs if r.startswith(TAG)]) + tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} if not tags: # Either we're using git < 1.8.3, or there really are no tags. We use # a heuristic: assume all version tags have a digit. The old git %d @@ -1013,7 +1259,7 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): # between branches and tags. By ignoring refnames without digits, we # filter out many common branch names like "release" and # "stabilization", as well as "HEAD" and "master". - tags = set([r for r in refs if re.search(r"\d", r)]) + tags = {r for r in refs if re.search(r'\d', r)} if verbose: print("discarding '%s', no digits" % ",".join(refs - tags)) if verbose: @@ -1021,30 +1267,33 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): for ref in sorted(tags): # sorting will prefer e.g. "2.0" over "2.0rc1" if ref.startswith(tag_prefix): - r = ref[len(tag_prefix) :] + r = ref[len(tag_prefix):] + # Filter out refs that exactly match prefix or that don't start + # with a number once the prefix is stripped (mostly a concern + # when prefix is '') + if not re.match(r'\d', r): + continue if verbose: print("picking %s" % r) - return { - "version": r, - "full-revisionid": keywords["full"].strip(), - "dirty": False, - "error": None, - "date": date, - } + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} # no suitable tags, so version is "0+unknown", but full hex is still there if verbose: print("no suitable tags, using unknown + full revision id") - return { - "version": "0+unknown", - "full-revisionid": keywords["full"].strip(), - "dirty": False, - "error": "no suitable tags", - "date": None, - } + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} @register_vcs_handler("git", "pieces_from_vcs") -def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): +def git_pieces_from_vcs( + tag_prefix: str, + root: str, + verbose: bool, + runner: Callable = run_command +) -> Dict[str, Any]: """Get version from 'git describe' in the root of the source tree. This only gets called if the git-archive 'subst' keywords were *not* @@ -1055,7 +1304,15 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] - out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True) + # GIT_DIR can interfere with correct operation of Versioneer. + # It may be intended to be passed to the Versioneer-versioned project, + # but that should not change where we get our version from. + env = os.environ.copy() + env.pop("GIT_DIR", None) + runner = functools.partial(runner, env=env) + + _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=not verbose) if rc != 0: if verbose: print("Directory %s not under git control" % root) @@ -1063,33 +1320,57 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] # if there isn't one, this yields HEX[-dirty] (no NUM) - describe_out, rc = run_command( - GITS, - [ - "describe", - "--tags", - "--dirty", - "--always", - "--long", - "--match", - "%s*" % tag_prefix, - ], - cwd=root, - ) + describe_out, rc = runner(GITS, [ + "describe", "--tags", "--dirty", "--always", "--long", + "--match", f"{tag_prefix}[[:digit:]]*" + ], cwd=root) # --long was added in git-1.5.5 if describe_out is None: raise NotThisMethod("'git describe' failed") describe_out = describe_out.strip() - full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) + full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root) if full_out is None: raise NotThisMethod("'git rev-parse' failed") full_out = full_out.strip() - pieces = {} + pieces: Dict[str, Any] = {} pieces["long"] = full_out pieces["short"] = full_out[:7] # maybe improved later pieces["error"] = None + branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], + cwd=root) + # --abbrev-ref was added in git-1.6.3 + if rc != 0 or branch_name is None: + raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") + branch_name = branch_name.strip() + + if branch_name == "HEAD": + # If we aren't exactly on a branch, pick a branch which represents + # the current commit. If all else fails, we are on a branchless + # commit. + branches, rc = runner(GITS, ["branch", "--contains"], cwd=root) + # --contains was added in git-1.5.4 + if rc != 0 or branches is None: + raise NotThisMethod("'git branch --contains' returned error") + branches = branches.split("\n") + + # Remove the first line if we're running detached + if "(" in branches[0]: + branches.pop(0) + + # Strip off the leading "* " from the list of branches. + branches = [branch[2:] for branch in branches] + if "master" in branches: + branch_name = "master" + elif not branches: + branch_name = None + else: + # Pick the first branch that is returned. Good or bad. + branch_name = branches[0] + + pieces["branch"] = branch_name + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] # TAG might have hyphens. git_describe = describe_out @@ -1098,16 +1379,17 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): dirty = git_describe.endswith("-dirty") pieces["dirty"] = dirty if dirty: - git_describe = git_describe[: git_describe.rindex("-dirty")] + git_describe = git_describe[:git_describe.rindex("-dirty")] # now we have TAG-NUM-gHEX or HEX if "-" in git_describe: # TAG-NUM-gHEX - mo = re.search(r"^(.+)-(\d+)-g([0-9a-f]+)$", git_describe) + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) if not mo: - # unparseable. Maybe git-describe is misbehaving? - pieces["error"] = "unable to parse git-describe output: '%s'" % describe_out + # unparsable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%s'" + % describe_out) return pieces # tag @@ -1116,12 +1398,10 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): if verbose: fmt = "tag '%s' doesn't start with prefix '%s'" print(fmt % (full_tag, tag_prefix)) - pieces["error"] = "tag '%s' doesn't start with prefix '%s'" % ( - full_tag, - tag_prefix, - ) + pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" + % (full_tag, tag_prefix)) return pieces - pieces["closest-tag"] = full_tag[len(tag_prefix) :] + pieces["closest-tag"] = full_tag[len(tag_prefix):] # distance: number of commits since tag pieces["distance"] = int(mo.group(2)) @@ -1132,19 +1412,20 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): else: # HEX: no tags pieces["closest-tag"] = None - count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], cwd=root) - pieces["distance"] = int(count_out) # total number of commits + out, rc = runner(GITS, ["rev-list", "HEAD", "--left-right"], cwd=root) + pieces["distance"] = len(out.split()) # total number of commits # commit date: see ISO-8601 comment in git_versions_from_keywords() - date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[ - 0 - ].strip() + date = runner(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip() + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) return pieces -def do_vcs_install(manifest_in, versionfile_source, ipy): +def do_vcs_install(versionfile_source: str, ipy: Optional[str]) -> None: """Git-specific installation logic for Versioneer. For Git, this means creating/changing .gitattributes to mark _version.py @@ -1153,36 +1434,40 @@ def do_vcs_install(manifest_in, versionfile_source, ipy): GITS = ["git"] if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] - files = [manifest_in, versionfile_source] + files = [versionfile_source] if ipy: files.append(ipy) - try: - me = __file__ - if me.endswith(".pyc") or me.endswith(".pyo"): - me = os.path.splitext(me)[0] + ".py" - versioneer_file = os.path.relpath(me) - except NameError: - versioneer_file = "versioneer.py" - files.append(versioneer_file) + if "VERSIONEER_PEP518" not in globals(): + try: + my_path = __file__ + if my_path.endswith((".pyc", ".pyo")): + my_path = os.path.splitext(my_path)[0] + ".py" + versioneer_file = os.path.relpath(my_path) + except NameError: + versioneer_file = "versioneer.py" + files.append(versioneer_file) present = False try: - f = open(".gitattributes", "r") - for line in f.readlines(): - if line.strip().startswith(versionfile_source): - if "export-subst" in line.strip().split()[1:]: - present = True - f.close() - except EnvironmentError: + with open(".gitattributes", "r") as fobj: + for line in fobj: + if line.strip().startswith(versionfile_source): + if "export-subst" in line.strip().split()[1:]: + present = True + break + except OSError: pass if not present: - f = open(".gitattributes", "a+") - f.write("%s export-subst\n" % versionfile_source) - f.close() + with open(".gitattributes", "a+") as fobj: + fobj.write(f"{versionfile_source} export-subst\n") files.append(".gitattributes") run_command(GITS, ["add", "--"] + files) -def versions_from_parentdir(parentdir_prefix, root, verbose): +def versions_from_parentdir( + parentdir_prefix: str, + root: str, + verbose: bool, +) -> Dict[str, Any]: """Try to determine the version from the parent directory name. Source tarballs conventionally unpack into a directory that includes both @@ -1191,30 +1476,23 @@ def versions_from_parentdir(parentdir_prefix, root, verbose): """ rootdirs = [] - for i in range(3): + for _ in range(3): dirname = os.path.basename(root) if dirname.startswith(parentdir_prefix): - return { - "version": dirname[len(parentdir_prefix) :], - "full-revisionid": None, - "dirty": False, - "error": None, - "date": None, - } - else: - rootdirs.append(root) - root = os.path.dirname(root) # up a level + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} + rootdirs.append(root) + root = os.path.dirname(root) # up a level if verbose: - print( - "Tried directories %s but none started with prefix %s" - % (str(rootdirs), parentdir_prefix) - ) + print("Tried directories %s but none started with prefix %s" % + (str(rootdirs), parentdir_prefix)) raise NotThisMethod("rootdir doesn't start with parentdir_prefix") SHORT_VERSION_PY = """ -# This file was generated by 'versioneer.py' (0.18) from +# This file was generated by 'versioneer.py' (0.29) from # revision-control system data, or from the parent directory name of an # unpacked source archive. Distribution tarballs contain a pre-generated copy # of this file. @@ -1231,43 +1509,41 @@ def get_versions(): """ -def versions_from_file(filename): +def versions_from_file(filename: str) -> Dict[str, Any]: """Try to determine the version from _version.py if present.""" try: with open(filename) as f: contents = f.read() - except EnvironmentError: + except OSError: raise NotThisMethod("unable to read _version.py") - mo = re.search( - r"version_json = '''\n(.*)''' # END VERSION_JSON", contents, re.M | re.S - ) + mo = re.search(r"version_json = '''\n(.*)''' # END VERSION_JSON", + contents, re.M | re.S) if not mo: - mo = re.search( - r"version_json = '''\r\n(.*)''' # END VERSION_JSON", contents, re.M | re.S - ) + mo = re.search(r"version_json = '''\r\n(.*)''' # END VERSION_JSON", + contents, re.M | re.S) if not mo: raise NotThisMethod("no version_json in _version.py") return json.loads(mo.group(1)) -def write_to_version_file(filename, versions): +def write_to_version_file(filename: str, versions: Dict[str, Any]) -> None: """Write the given version number to the given _version.py file.""" - os.unlink(filename) - contents = json.dumps(versions, sort_keys=True, indent=1, separators=(",", ": ")) + contents = json.dumps(versions, sort_keys=True, + indent=1, separators=(",", ": ")) with open(filename, "w") as f: f.write(SHORT_VERSION_PY % contents) print("set %s to '%s'" % (filename, versions["version"])) -def plus_or_dot(pieces): +def plus_or_dot(pieces: Dict[str, Any]) -> str: """Return a + if we don't already have one, else return a .""" if "+" in pieces.get("closest-tag", ""): return "." return "+" -def render_pep440(pieces): +def render_pep440(pieces: Dict[str, Any]) -> str: """Build up version string, with post-release "local version identifier". Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you @@ -1285,29 +1561,78 @@ def render_pep440(pieces): rendered += ".dirty" else: # exception #1 - rendered = "0+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) + rendered = "0+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered -def render_pep440_pre(pieces): - """TAG[.post.devDISTANCE] -- No -dirty. +def render_pep440_branch(pieces: Dict[str, Any]) -> str: + """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] . + + The ".dev0" means not master branch. Note that .dev0 sorts backwards + (a feature branch will appear "older" than the master branch). Exceptions: - 1: no tags. 0.post.devDISTANCE + 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0" + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def pep440_split_post(ver: str) -> Tuple[str, Optional[int]]: + """Split pep440 version string at the post-release segment. + + Returns the release segments before the post-release and the + post-release version number (or -1 if no post-release segment is present). + """ + vc = str.split(ver, ".post") + return vc[0], int(vc[1] or 0) if len(vc) == 2 else None + + +def render_pep440_pre(pieces: Dict[str, Any]) -> str: + """TAG[.postN.devDISTANCE] -- No -dirty. + + Exceptions: + 1: no tags. 0.post0.devDISTANCE + """ + if pieces["closest-tag"]: if pieces["distance"]: - rendered += ".post.dev%d" % pieces["distance"] + # update the post release segment + tag_version, post_version = pep440_split_post(pieces["closest-tag"]) + rendered = tag_version + if post_version is not None: + rendered += ".post%d.dev%d" % (post_version + 1, pieces["distance"]) + else: + rendered += ".post0.dev%d" % (pieces["distance"]) + else: + # no commits, use the tag as the version + rendered = pieces["closest-tag"] else: # exception #1 - rendered = "0.post.dev%d" % pieces["distance"] + rendered = "0.post0.dev%d" % pieces["distance"] return rendered -def render_pep440_post(pieces): +def render_pep440_post(pieces: Dict[str, Any]) -> str: """TAG[.postDISTANCE[.dev0]+gHEX] . The ".dev0" means dirty. Note that .dev0 sorts backwards @@ -1334,12 +1659,41 @@ def render_pep440_post(pieces): return rendered -def render_pep440_old(pieces): +def render_pep440_post_branch(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] . + + The ".dev0" means not master branch. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_old(pieces: Dict[str, Any]) -> str: """TAG[.postDISTANCE[.dev0]] . The ".dev0" means dirty. - Eexceptions: + Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: @@ -1356,7 +1710,7 @@ def render_pep440_old(pieces): return rendered -def render_git_describe(pieces): +def render_git_describe(pieces: Dict[str, Any]) -> str: """TAG[-DISTANCE-gHEX][-dirty]. Like 'git describe --tags --dirty --always'. @@ -1376,7 +1730,7 @@ def render_git_describe(pieces): return rendered -def render_git_describe_long(pieces): +def render_git_describe_long(pieces: Dict[str, Any]) -> str: """TAG-DISTANCE-gHEX[-dirty]. Like 'git describe --tags --dirty --always -long'. @@ -1396,26 +1750,28 @@ def render_git_describe_long(pieces): return rendered -def render(pieces, style): +def render(pieces: Dict[str, Any], style: str) -> Dict[str, Any]: """Render the given version pieces into the requested style.""" if pieces["error"]: - return { - "version": "unknown", - "full-revisionid": pieces.get("long"), - "dirty": None, - "error": pieces["error"], - "date": None, - } + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} if not style or style == "default": style = "pep440" # the default if style == "pep440": rendered = render_pep440(pieces) + elif style == "pep440-branch": + rendered = render_pep440_branch(pieces) elif style == "pep440-pre": rendered = render_pep440_pre(pieces) elif style == "pep440-post": rendered = render_pep440_post(pieces) + elif style == "pep440-post-branch": + rendered = render_pep440_post_branch(pieces) elif style == "pep440-old": rendered = render_pep440_old(pieces) elif style == "git-describe": @@ -1425,20 +1781,16 @@ def render(pieces, style): else: raise ValueError("unknown style '%s'" % style) - return { - "version": rendered, - "full-revisionid": pieces["long"], - "dirty": pieces["dirty"], - "error": None, - "date": pieces.get("date"), - } + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} class VersioneerBadRootError(Exception): """The project root directory is unknown or missing key files.""" -def get_versions(verbose=False): +def get_versions(verbose: bool = False) -> Dict[str, Any]: """Get the project version from whatever source is available. Returns dict with two keys: 'version' and 'full'. @@ -1453,10 +1805,9 @@ def get_versions(verbose=False): assert cfg.VCS is not None, "please set [versioneer]VCS= in setup.cfg" handlers = HANDLERS.get(cfg.VCS) assert handlers, "unrecognized VCS '%s'" % cfg.VCS - verbose = verbose or cfg.verbose - assert ( - cfg.versionfile_source is not None - ), "please set versioneer.versionfile_source" + verbose = verbose or bool(cfg.verbose) # `bool()` used to avoid `None` + assert cfg.versionfile_source is not None, \ + "please set versioneer.versionfile_source" assert cfg.tag_prefix is not None, "please set versioneer.tag_prefix" versionfile_abs = os.path.join(root, cfg.versionfile_source) @@ -1510,22 +1861,22 @@ def get_versions(verbose=False): if verbose: print("unable to compute version") - return { - "version": "0+unknown", - "full-revisionid": None, - "dirty": None, - "error": "unable to compute version", - "date": None, - } + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, "error": "unable to compute version", + "date": None} -def get_version(): +def get_version() -> str: """Get the short version string for this project.""" return get_versions()["version"] -def get_cmdclass(): - """Get the custom setuptools/distutils subclasses used by Versioneer.""" +def get_cmdclass(cmdclass: Optional[Dict[str, Any]] = None): + """Get the custom setuptools subclasses used by Versioneer. + + If the package uses a different cmdclass (e.g. one from numpy), it + should be provide as an argument. + """ if "versioneer" in sys.modules: del sys.modules["versioneer"] # this fixes the "python setup.py develop" case (also 'install' and @@ -1539,25 +1890,25 @@ def get_cmdclass(): # parent is protected against the child's "import versioneer". By # removing ourselves from sys.modules here, before the child build # happens, we protect the child from the parent's versioneer too. - # Also see https://github.com/warner/python-versioneer/issues/52 + # Also see https://github.com/python-versioneer/python-versioneer/issues/52 - cmds = {} + cmds = {} if cmdclass is None else cmdclass.copy() - # we add "version" to both distutils and setuptools - from distutils.core import Command + # we add "version" to setuptools + from setuptools import Command class cmd_version(Command): description = "report generated version string" - user_options = [] - boolean_options = [] + user_options: List[Tuple[str, str, str]] = [] + boolean_options: List[str] = [] - def initialize_options(self): + def initialize_options(self) -> None: pass - def finalize_options(self): + def finalize_options(self) -> None: pass - def run(self): + def run(self) -> None: vers = get_versions(verbose=True) print("Version: %s" % vers["version"]) print(" full-revisionid: %s" % vers.get("full-revisionid")) @@ -1565,10 +1916,9 @@ def run(self): print(" date: %s" % vers.get("date")) if vers["error"]: print(" error: %s" % vers["error"]) - cmds["version"] = cmd_version - # we override "build_py" in both distutils and setuptools + # we override "build_py" in setuptools # # most invocation pathways end up running build_py: # distutils/build -> build_py @@ -1583,30 +1933,68 @@ def run(self): # then does setup.py bdist_wheel, or sometimes setup.py install # setup.py egg_info -> ? + # pip install -e . and setuptool/editable_wheel will invoke build_py + # but the build_py command is not expected to copy any files. + # we override different "build_py" commands for both environments - if "setuptools" in sys.modules: - from setuptools.command.build_py import build_py as _build_py + if 'build_py' in cmds: + _build_py: Any = cmds['build_py'] else: - from distutils.command.build_py import build_py as _build_py + from setuptools.command.build_py import build_py as _build_py class cmd_build_py(_build_py): - def run(self): + def run(self) -> None: root = get_root() cfg = get_config_from_root(root) versions = get_versions() _build_py.run(self) + if getattr(self, "editable_mode", False): + # During editable installs `.py` and data files are + # not copied to build_lib + return # now locate _version.py in the new build/ directory and replace # it with an updated value if cfg.versionfile_build: - target_versionfile = os.path.join(self.build_lib, cfg.versionfile_build) + target_versionfile = os.path.join(self.build_lib, + cfg.versionfile_build) print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) - cmds["build_py"] = cmd_build_py - if "cx_Freeze" in sys.modules: # cx_freeze enabled? - from cx_Freeze.dist import build_exe as _build_exe + if 'build_ext' in cmds: + _build_ext: Any = cmds['build_ext'] + else: + from setuptools.command.build_ext import build_ext as _build_ext + + class cmd_build_ext(_build_ext): + def run(self) -> None: + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + _build_ext.run(self) + if self.inplace: + # build_ext --inplace will only build extensions in + # build/lib<..> dir with no _version.py to write to. + # As in place builds will already have a _version.py + # in the module dir, we do not need to write one. + return + # now locate _version.py in the new build/ directory and replace + # it with an updated value + if not cfg.versionfile_build: + return + target_versionfile = os.path.join(self.build_lib, + cfg.versionfile_build) + if not os.path.exists(target_versionfile): + print(f"Warning: {target_versionfile} does not exist, skipping " + "version update. This can happen if you are running build_ext " + "without first running build_py.") + return + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + cmds["build_ext"] = cmd_build_ext + if "cx_Freeze" in sys.modules: # cx_freeze enabled? + from cx_Freeze.dist import build_exe as _build_exe # type: ignore # nczeczulin reports that py2exe won't like the pep440-style string # as FILEVERSION, but it can be used for PRODUCTVERSION, e.g. # setup(console=[{ @@ -1615,7 +2003,7 @@ def run(self): # ... class cmd_build_exe(_build_exe): - def run(self): + def run(self) -> None: root = get_root() cfg = get_config_from_root(root) versions = get_versions() @@ -1627,28 +2015,24 @@ def run(self): os.unlink(target_versionfile) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] - f.write( - LONG - % { - "DOLLAR": "$", - "STYLE": cfg.style, - "TAG_PREFIX": cfg.tag_prefix, - "PARENTDIR_PREFIX": cfg.parentdir_prefix, - "VERSIONFILE_SOURCE": cfg.versionfile_source, - } - ) - + f.write(LONG % + {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) cmds["build_exe"] = cmd_build_exe del cmds["build_py"] - if "py2exe" in sys.modules: # py2exe enabled? + if 'py2exe' in sys.modules: # py2exe enabled? try: - from py2exe.distutils_buildexe import py2exe as _py2exe # py3 + from py2exe.setuptools_buildexe import py2exe as _py2exe # type: ignore except ImportError: - from py2exe.build_exe import py2exe as _py2exe # py2 + from py2exe.distutils_buildexe import py2exe as _py2exe # type: ignore class cmd_py2exe(_py2exe): - def run(self): + def run(self) -> None: root = get_root() cfg = get_config_from_root(root) versions = get_versions() @@ -1660,27 +2044,60 @@ def run(self): os.unlink(target_versionfile) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] - f.write( - LONG - % { - "DOLLAR": "$", - "STYLE": cfg.style, - "TAG_PREFIX": cfg.tag_prefix, - "PARENTDIR_PREFIX": cfg.parentdir_prefix, - "VERSIONFILE_SOURCE": cfg.versionfile_source, - } - ) - + f.write(LONG % + {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) cmds["py2exe"] = cmd_py2exe + # sdist farms its file list building out to egg_info + if 'egg_info' in cmds: + _egg_info: Any = cmds['egg_info'] + else: + from setuptools.command.egg_info import egg_info as _egg_info + + class cmd_egg_info(_egg_info): + def find_sources(self) -> None: + # egg_info.find_sources builds the manifest list and writes it + # in one shot + super().find_sources() + + # Modify the filelist and normalize it + root = get_root() + cfg = get_config_from_root(root) + self.filelist.append('versioneer.py') + if cfg.versionfile_source: + # There are rare cases where versionfile_source might not be + # included by default, so we must be explicit + self.filelist.append(cfg.versionfile_source) + self.filelist.sort() + self.filelist.remove_duplicates() + + # The write method is hidden in the manifest_maker instance that + # generated the filelist and was thrown away + # We will instead replicate their final normalization (to unicode, + # and POSIX-style paths) + from setuptools import unicode_utils + normalized = [unicode_utils.filesys_decode(f).replace(os.sep, '/') + for f in self.filelist.files] + + manifest_filename = os.path.join(self.egg_info, 'SOURCES.txt') + with open(manifest_filename, 'w') as fobj: + fobj.write('\n'.join(normalized)) + + cmds['egg_info'] = cmd_egg_info + # we override different "sdist" commands for both environments - if "setuptools" in sys.modules: - from setuptools.command.sdist import sdist as _sdist + if 'sdist' in cmds: + _sdist: Any = cmds['sdist'] else: - from distutils.command.sdist import sdist as _sdist + from setuptools.command.sdist import sdist as _sdist class cmd_sdist(_sdist): - def run(self): + def run(self) -> None: versions = get_versions() self._versioneer_generated_versions = versions # unless we update this, the command will keep using the old @@ -1688,7 +2105,7 @@ def run(self): self.distribution.metadata.version = versions["version"] return _sdist.run(self) - def make_release_tree(self, base_dir, files): + def make_release_tree(self, base_dir: str, files: List[str]) -> None: root = get_root() cfg = get_config_from_root(root) _sdist.make_release_tree(self, base_dir, files) @@ -1697,10 +2114,8 @@ def make_release_tree(self, base_dir, files): # updated value target_versionfile = os.path.join(base_dir, cfg.versionfile_source) print("UPDATING %s" % target_versionfile) - write_to_version_file( - target_versionfile, self._versioneer_generated_versions - ) - + write_to_version_file(target_versionfile, + self._versioneer_generated_versions) cmds["sdist"] = cmd_sdist return cmds @@ -1743,25 +2158,28 @@ def make_release_tree(self, base_dir, files): """ -INIT_PY_SNIPPET = """ +OLD_SNIPPET = """ from ._version import get_versions __version__ = get_versions()['version'] del get_versions """ +INIT_PY_SNIPPET = """ +from . import {0} +__version__ = {0}.get_versions()['version'] +""" + -def do_setup(): - """Main VCS-independent setup function for installing Versioneer.""" +def do_setup() -> int: + """Do main VCS-independent setup function for installing Versioneer.""" root = get_root() try: cfg = get_config_from_root(root) - except ( - EnvironmentError, - configparser.NoSectionError, - configparser.NoOptionError, - ) as e: - if isinstance(e, (EnvironmentError, configparser.NoSectionError)): - print("Adding sample versioneer config to setup.cfg", file=sys.stderr) + except (OSError, configparser.NoSectionError, + configparser.NoOptionError) as e: + if isinstance(e, (OSError, configparser.NoSectionError)): + print("Adding sample versioneer config to setup.cfg", + file=sys.stderr) with open(os.path.join(root, "setup.cfg"), "a") as f: f.write(SAMPLE_CONFIG) print(CONFIG_ERROR, file=sys.stderr) @@ -1770,76 +2188,46 @@ def do_setup(): print(" creating %s" % cfg.versionfile_source) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] - f.write( - LONG - % { - "DOLLAR": "$", - "STYLE": cfg.style, - "TAG_PREFIX": cfg.tag_prefix, - "PARENTDIR_PREFIX": cfg.parentdir_prefix, - "VERSIONFILE_SOURCE": cfg.versionfile_source, - } - ) - - ipy = os.path.join(os.path.dirname(cfg.versionfile_source), "__init__.py") + f.write(LONG % {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) + + ipy = os.path.join(os.path.dirname(cfg.versionfile_source), + "__init__.py") + maybe_ipy: Optional[str] = ipy if os.path.exists(ipy): try: with open(ipy, "r") as f: old = f.read() - except EnvironmentError: + except OSError: old = "" - if INIT_PY_SNIPPET not in old: + module = os.path.splitext(os.path.basename(cfg.versionfile_source))[0] + snippet = INIT_PY_SNIPPET.format(module) + if OLD_SNIPPET in old: + print(" replacing boilerplate in %s" % ipy) + with open(ipy, "w") as f: + f.write(old.replace(OLD_SNIPPET, snippet)) + elif snippet not in old: print(" appending to %s" % ipy) with open(ipy, "a") as f: - f.write(INIT_PY_SNIPPET) + f.write(snippet) else: print(" %s unmodified" % ipy) else: print(" %s doesn't exist, ok" % ipy) - ipy = None - - # Make sure both the top-level "versioneer.py" and versionfile_source - # (PKG/_version.py, used by runtime code) are in MANIFEST.in, so - # they'll be copied into source distributions. Pip won't be able to - # install the package without this. - manifest_in = os.path.join(root, "MANIFEST.in") - simple_includes = set() - try: - with open(manifest_in, "r") as f: - for line in f: - if line.startswith("include "): - for include in line.split()[1:]: - simple_includes.add(include) - except EnvironmentError: - pass - # That doesn't cover everything MANIFEST.in can do - # (http://docs.python.org/2/distutils/sourcedist.html#commands), so - # it might give some false negatives. Appending redundant 'include' - # lines is safe, though. - if "versioneer.py" not in simple_includes: - print(" appending 'versioneer.py' to MANIFEST.in") - with open(manifest_in, "a") as f: - f.write("include versioneer.py\n") - else: - print(" 'versioneer.py' already in MANIFEST.in") - if cfg.versionfile_source not in simple_includes: - print( - " appending versionfile_source ('%s') to MANIFEST.in" - % cfg.versionfile_source - ) - with open(manifest_in, "a") as f: - f.write("include %s\n" % cfg.versionfile_source) - else: - print(" versionfile_source already in MANIFEST.in") + maybe_ipy = None # Make VCS-specific changes. For git, this means creating/changing # .gitattributes to mark _version.py for export-subst keyword # substitution. - do_vcs_install(manifest_in, cfg.versionfile_source, ipy) + do_vcs_install(cfg.versionfile_source, maybe_ipy) return 0 -def scan_setup_py(): +def scan_setup_py() -> int: """Validate the contents of setup.py against Versioneer's expectations.""" found = set() setters = False @@ -1876,10 +2264,14 @@ def scan_setup_py(): return errors +def setup_command() -> NoReturn: + """Set up Versioneer and exit with appropriate error code.""" + errors = do_setup() + errors += scan_setup_py() + sys.exit(1 if errors else 0) + + if __name__ == "__main__": cmd = sys.argv[1] if cmd == "setup": - errors = do_setup() - errors += scan_setup_py() - if errors: - sys.exit(1) + setup_command() From 4afa5f14b082b5faebce21feb4abe7b246286fb0 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Mon, 29 Jul 2024 15:22:27 +0200 Subject: [PATCH 235/249] update for documentation --- .github/workflows/python-app.yml | 2 +- .readthedocs.yml | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 7c93faae..f2f4753e 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -10,7 +10,7 @@ jobs: strategy: matrix: # os: [ubuntu-latest, macos-latest, windows-latest] - os: [ubuntu-lts-latest, windows-latest] + os: [ubuntu-latest, windows-latest] python_version: ['3.10', '3.11', '3.12'] name: Run py eddy tracker build tests runs-on: ${{ matrix.os }} diff --git a/.readthedocs.yml b/.readthedocs.yml index a04495b6..4b698a62 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -4,8 +4,10 @@ conda: build: os: ubuntu-lts-latest tools: - python: "3.10" + python: "mambaforge-latest" python: install: - method: setuptools path: . +sphinx: + configuration: docs/conf.py \ No newline at end of file From 3a54bbb6e50ebc38dcb334539dcb5b456a408127 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Mon, 29 Jul 2024 15:24:56 +0200 Subject: [PATCH 236/249] again doc --- .readthedocs.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 4b698a62..ddfbb747 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -9,5 +9,3 @@ python: install: - method: setuptools path: . -sphinx: - configuration: docs/conf.py \ No newline at end of file From d5d3aed5f4ac51b361697638144fc19410f04093 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Tue, 12 Nov 2024 17:02:22 +0100 Subject: [PATCH 237/249] correction on lagerloef uv --- src/py_eddy_tracker/dataset/grid.py | 67 +++++++++++++---------------- 1 file changed, 29 insertions(+), 38 deletions(-) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index edb96bac..d8a48f69 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -1670,7 +1670,7 @@ def spectrum_lonlat(self, grid_name, area=None, ref=None, **kwargs): (lat_content[0], lat_content[1] / ref_lat_content[1]), ) - def compute_finite_difference(self, data, schema=1, mode="reflect", vertical=False): + def compute_finite_difference(self, data, schema=1, mode="reflect", vertical=False, second=False): if not isinstance(schema, int) and schema < 1: raise Exception("schema must be a positive int") @@ -1694,13 +1694,16 @@ def compute_finite_difference(self, data, schema=1, mode="reflect", vertical=Fal data2[:schema] = nan # Distance for one degree - d = self.EARTH_RADIUS * 2 * pi / 360 + d = self.EARTH_RADIUS * 2 * pi / 360 * 2 * schema # Mulitply by 2 step if vertical: - d *= self.ystep * 2 * schema + d *= self.ystep else: - d *= self.xstep * cos(deg2rad(self.y_c)) * 2 * schema - return (data1 - data2) / d + d *= self.xstep * cos(deg2rad(self.y_c)) + if second: + return (data1 + data2 - 2 * data) / (d ** 2 / 4) + else: + return (data1 - data2) / d def compute_stencil( self, data, stencil_halfwidth=4, mode="reflect", vertical=False @@ -1787,13 +1790,14 @@ def compute_stencil( ) return ma.array(g, mask=m) - def add_uv_lagerloef(self, grid_height, uname="u", vname="v", schema=15): - self.add_uv(grid_height, uname, vname) + def add_uv_lagerloef(self, grid_height, uname="u", vname="v", schema=15, **kwargs): + self.add_uv(grid_height, uname, vname, **kwargs) latmax = 5 - _, (i_start, i_end) = self.nearest_grd_indice((0, 0), (-latmax, latmax)) + _, i_start = self.nearest_grd_indice(0, -latmax) + _, i_end = self.nearest_grd_indice(0, latmax) sl = slice(i_start, i_end) # Divide by sideral day - lat = self.y_c[sl] + lat = self.y_c gob = ( cos(deg2rad(lat)) * ones((self.x_c.shape[0], 1)) @@ -1807,39 +1811,26 @@ def add_uv_lagerloef(self, grid_height, uname="u", vname="v", schema=15): mode = "wrap" if self.is_circular() else "reflect" # fill data to compute a finite difference on all point - data = self.convolve_filter_with_dynamic_kernel( - grid_height, - self.kernel_bessel, - lat_max=10, - wave_length=500, - order=1, - extend=0.1, - ) - data = self.convolve_filter_with_dynamic_kernel( - data, self.kernel_bessel, lat_max=10, wave_length=500, order=1, extend=0.1 - ) - data = self.convolve_filter_with_dynamic_kernel( - data, self.kernel_bessel, lat_max=10, wave_length=500, order=1, extend=0.1 - ) + kw_filter = dict(kernel_func=self.kernel_bessel, order=1, extend=.1) + data = self.convolve_filter_with_dynamic_kernel(grid_height, wave_length=500, **kw_filter, lat_max=6+5+2+3) v_lagerloef = ( self.compute_finite_difference( - self.compute_finite_difference(data, mode=mode, schema=schema), - mode=mode, - schema=schema, - )[:, sl] - * gob - ) - u_lagerloef = ( - -self.compute_finite_difference( - self.compute_finite_difference(data, vertical=True, schema=schema), - vertical=True, - schema=schema, - )[:, sl] + self.compute_finite_difference(data, mode=mode, schema=1), + vertical=True, schema=1 + ) * gob ) - w = 1 - exp(-((lat / 2.2) ** 2)) - self.vars[vname][:, sl] = self.vars[vname][:, sl] * w + v_lagerloef * (1 - w) - self.vars[uname][:, sl] = self.vars[uname][:, sl] * w + u_lagerloef * (1 - w) + u_lagerloef = -self.compute_finite_difference(data, vertical=True, schema=schema, second=True) * gob + + v_lagerloef = self.convolve_filter_with_dynamic_kernel(v_lagerloef, wave_length=195, **kw_filter, lat_max=6 + 5 +2) + v_lagerloef = self.convolve_filter_with_dynamic_kernel(v_lagerloef, wave_length=416, **kw_filter, lat_max=6 + 5) + v_lagerloef = self.convolve_filter_with_dynamic_kernel(v_lagerloef, wave_length=416, **kw_filter, lat_max=6) + u_lagerloef = self.convolve_filter_with_dynamic_kernel(u_lagerloef, wave_length=195, **kw_filter, lat_max=6 + 5 +2) + u_lagerloef = self.convolve_filter_with_dynamic_kernel(u_lagerloef, wave_length=416, **kw_filter, lat_max=6 + 5) + u_lagerloef = self.convolve_filter_with_dynamic_kernel(u_lagerloef, wave_length=416, **kw_filter, lat_max=6) + w = 1 - exp(-((lat[sl] / 2.2) ** 2)) + self.vars[vname][:, sl] = self.vars[vname][:, sl] * w + v_lagerloef[:, sl] * (1 - w) + self.vars[uname][:, sl] = self.vars[uname][:, sl] * w + u_lagerloef[:, sl] * (1 - w) def add_uv(self, grid_height, uname="u", vname="v", stencil_halfwidth=4): r"""Compute a u and v grid From f6ae4ee6d6d21e70dd75344e85617978b6306637 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Fri, 15 Nov 2024 16:14:20 +0100 Subject: [PATCH 238/249] fix matplotlib and zarr version --- environment.yml | 1 - requirements.txt | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/environment.yml b/environment.yml index 12ce70e7..e9a05ac0 100644 --- a/environment.yml +++ b/environment.yml @@ -1,7 +1,6 @@ name: binder-pyeddytracker channels: - conda-forge - - defaults dependencies: - python=3.10 - pip diff --git a/requirements.txt b/requirements.txt index 4c8af099..556cabbf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,11 @@ -matplotlib +matplotlib < 3.8 # need an update of contour management opencv-python pint polygon3 pyyaml requests scipy -zarr +zarr < 3.0 netCDF4 numpy numba \ No newline at end of file From 66f2f313187dd30920db8d80a0444aff04259443 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Fri, 15 Nov 2024 16:18:09 +0100 Subject: [PATCH 239/249] add requirement on environement doc --- doc/environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/environment.yml b/doc/environment.yml index 89fcbe9c..065c1027 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -1,11 +1,11 @@ channels: - conda-forge - - defaults dependencies: - python=3.10 - ffmpeg - pip - pip: + - -r ../requirements.txt - sphinx-gallery - sphinx_rtd_theme - sphinx>=3.1 From 449b7f87292adbcbd9fb4c2b71a4890176282066 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Tue, 19 Nov 2024 10:09:53 +0100 Subject: [PATCH 240/249] update python version condition --- doc/environment.yml | 2 +- environment.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/environment.yml b/doc/environment.yml index 065c1027..7cf02b76 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -1,7 +1,7 @@ channels: - conda-forge dependencies: - - python=3.10 + - python>=3.10 - ffmpeg - pip - pip: diff --git a/environment.yml b/environment.yml index e9a05ac0..819d28d7 100644 --- a/environment.yml +++ b/environment.yml @@ -2,7 +2,7 @@ name: binder-pyeddytracker channels: - conda-forge dependencies: - - python=3.10 + - python>=3.10 - pip - ffmpeg - pip: From 99a848fa0cd38693ee5d62ac6a2e6a2324996cdb Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle <36040805+AntSimi@users.noreply.github.com> Date: Wed, 20 Nov 2024 15:24:34 +0100 Subject: [PATCH 241/249] solve doc problem (#255) * reject python 3.13 * use pip instead of setuptools * add sample id to install --- .readthedocs.yml | 2 +- doc/environment.yml | 3 ++- environment.yml | 2 +- .../pet_eddy_detection_ACC.py | 3 ++- src/py_eddy_tracker/data/__init__.py | 19 +++++++++++++------ 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index ddfbb747..5ac02e12 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -7,5 +7,5 @@ build: python: "mambaforge-latest" python: install: - - method: setuptools + - method: pip path: . diff --git a/doc/environment.yml b/doc/environment.yml index 7cf02b76..063a60de 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -1,11 +1,12 @@ channels: - conda-forge dependencies: - - python>=3.10 + - python>=3.10, <3.13 - ffmpeg - pip - pip: - -r ../requirements.txt + - git+https://github.com/AntSimi/py-eddy-tracker-sample-id.git - sphinx-gallery - sphinx_rtd_theme - sphinx>=3.1 diff --git a/environment.yml b/environment.yml index 819d28d7..e94c7bc1 100644 --- a/environment.yml +++ b/environment.yml @@ -2,7 +2,7 @@ name: binder-pyeddytracker channels: - conda-forge dependencies: - - python>=3.10 + - python>=3.10, <3.13 - pip - ffmpeg - pip: diff --git a/examples/02_eddy_identification/pet_eddy_detection_ACC.py b/examples/02_eddy_identification/pet_eddy_detection_ACC.py index 3d3d4ac1..d12c62f3 100644 --- a/examples/02_eddy_identification/pet_eddy_detection_ACC.py +++ b/examples/02_eddy_identification/pet_eddy_detection_ACC.py @@ -7,6 +7,7 @@ Two detections are provided : with a filtered ADT and without filtering """ + from datetime import datetime from matplotlib import pyplot as plt, style @@ -80,7 +81,7 @@ def set_fancy_labels(fig, ticklabelsize=14, labelsize=14, labelweight="semibold" # Identification # ^^^^^^^^^^^^^^ # Run the identification step with slices of 2 mm -date = datetime(2016, 5, 15) +date = datetime(2019, 2, 23) kw_ident = dict( date=date, step=0.002, shape_error=70, sampling=30, uname="u", vname="v" ) diff --git a/src/py_eddy_tracker/data/__init__.py b/src/py_eddy_tracker/data/__init__.py index f14fee87..bf062983 100644 --- a/src/py_eddy_tracker/data/__init__.py +++ b/src/py_eddy_tracker/data/__init__.py @@ -8,6 +8,7 @@ 20160515 adt None None longitude latitude . \ --cut 800 --fil 1 """ + import io import lzma from os import path @@ -26,14 +27,20 @@ def get_remote_demo_sample(path): if path.endswith(".nc"): return io.BytesIO(content) else: - if path.endswith(".nc"): + try: + import py_eddy_tracker_sample_id + if path.endswith(".nc"): + return py_eddy_tracker_sample_id.get_remote_demo_sample(path) + content = open(py_eddy_tracker_sample_id.get_remote_demo_sample(f"{path}.tar.xz"), "rb").read() + except: + if path.endswith(".nc"): + content = requests.get( + f"https://github.com/AntSimi/py-eddy-tracker-sample-id/raw/master/{path}" + ).content + return io.BytesIO(content) content = requests.get( - f"https://github.com/AntSimi/py-eddy-tracker-sample-id/raw/master/{path}" + f"https://github.com/AntSimi/py-eddy-tracker-sample-id/raw/master/{path}.tar.xz" ).content - return io.BytesIO(content) - content = requests.get( - f"https://github.com/AntSimi/py-eddy-tracker-sample-id/raw/master/{path}.tar.xz" - ).content # Tar module could manage lzma tar, but it will apply uncompress for each extractfile tar = tarfile.open(mode="r", fileobj=io.BytesIO(lzma.decompress(content))) From 0a4ed708d87cc4073634beac8fb88a4b16747f0e Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:18:47 +0100 Subject: [PATCH 242/249] bug correction toward direction #252 --- src/py_eddy_tracker/appli/network.py | 2 +- src/py_eddy_tracker/dataset/grid.py | 13 ++++++------- src/py_eddy_tracker/observations/tracking.py | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/py_eddy_tracker/appli/network.py b/src/py_eddy_tracker/appli/network.py index b8c2da51..0a3d06ca 100644 --- a/src/py_eddy_tracker/appli/network.py +++ b/src/py_eddy_tracker/appli/network.py @@ -283,7 +283,7 @@ def previous_obs(d, i_seg): def display_compare(ref, others): def display(value, ref=None): if ref: - outs = [f"{v/ref[k] * 100:.1f}% ({v})" for k, v in value.items()] + outs = [f"{v / ref[k] * 100:.1f}% ({v})" for k, v in value.items()] else: outs = value return "".join([f"{v:^18}" for v in outs]) diff --git a/src/py_eddy_tracker/dataset/grid.py b/src/py_eddy_tracker/dataset/grid.py index d8a48f69..f15503b2 100644 --- a/src/py_eddy_tracker/dataset/grid.py +++ b/src/py_eddy_tracker/dataset/grid.py @@ -9,6 +9,7 @@ from matplotlib.path import Path as BasePath from netCDF4 import Dataset from numba import njit, prange, types as numba_types +import numpy as np from numpy import ( arange, array, @@ -35,7 +36,6 @@ percentile, pi, radians, - round_, sin, sinc, sqrt, @@ -2251,12 +2251,11 @@ def compute_pixel_path(x0, y0, x1, y1, x_ori, y_ori, x_step, y_step, nb_x): i_x1 = empty(nx, dtype=numba_types.int_) i_y0 = empty(nx, dtype=numba_types.int_) i_y1 = empty(nx, dtype=numba_types.int_) - # Because round_ is not accepted with array in numba for i in range(nx): - i_x0[i] = round_(((x0[i] - x_ori) % 360) / x_step) - i_x1[i] = round_(((x1[i] - x_ori) % 360) / x_step) - i_y0[i] = round_((y0[i] - y_ori) / y_step) - i_y1[i] = round_((y1[i] - y_ori) / y_step) + i_x0[i] = np.round(((x0[i] - x_ori) % 360) / x_step) + i_x1[i] = np.round(((x1[i] - x_ori) % 360) / x_step) + i_y0[i] = np.round((y0[i] - y_ori) / y_step) + i_y1[i] = np.round((y1[i] - y_ori) / y_step) # Delta index of x d_x = i_x1 - i_x0 d_x = (d_x + nb_x // 2) % nb_x - (nb_x // 2) @@ -2941,7 +2940,7 @@ def compute_stencil(x, y, h, m, earth_radius, vertical=False, stencil_halfwidth= h_3, h_2, h_1, h0 = h[-4, j], h[-3, j], h[-2, j], h[-1, j] m_3, m_2, m_1, m0 = m[-4, j], m[-3, j], m[-2, j], m[-1, j] else: - m_3, m_2, m_1, m0 = False, False, False, False + m_3, m_2, m_1, m0 = True, True, True, True h1, h2, h3, h4 = h[0, j], h[1, j], h[2, j], h[3, j] m1, m2, m3, m4 = m[0, j], m[1, j], m[2, j], m[3, j] for i in range(nb_x): diff --git a/src/py_eddy_tracker/observations/tracking.py b/src/py_eddy_tracker/observations/tracking.py index 164f9724..fa1c1f93 100644 --- a/src/py_eddy_tracker/observations/tracking.py +++ b/src/py_eddy_tracker/observations/tracking.py @@ -380,7 +380,7 @@ def extract_toward_direction(self, west=True, delta_lon=None): d_lon = lon[i1] - lon[i0] m = d_lon < 0 if west else d_lon > 0 if delta_lon is not None: - m *= delta_lon < d_lon + m *= delta_lon < abs(d_lon) m = m.repeat(nb) return self.extract_with_mask(m) From c069878e3f69cd908c8bef6906f05ca4f015ef0e Mon Sep 17 00:00:00 2001 From: Antoine Delepoulle <36040805+AntSimi@users.noreply.github.com> Date: Wed, 20 Nov 2024 15:24:34 +0100 Subject: [PATCH 243/249] Add method to get period information for each network --- src/py_eddy_tracker/observations/network.py | 34 +++++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index a2e2daed..87ef4a78 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -9,6 +9,7 @@ import netCDF4 from numba import njit, types as nb_types from numba.typed import List +import numpy as np from numpy import ( arange, array, @@ -124,7 +125,7 @@ def __repr__(self): f"Atlas with {self.nb_network} networks ({self.nb_network / period:0.0f} networks/year)," f" {self.nb_segment} segments ({self.nb_segment / period:0.0f} segments/year), {len(self)} observations ({len(self) / period:0.0f} observations/year)", f" {m_event.size} merging ({m_event.size / period:0.0f} merging/year), {s_event.size} splitting ({s_event.size / period:0.0f} splitting/year)", - f" with {(nb_by_network > big).sum()} network with more than {big} obs and the biggest have {nb_by_network.max()} observations ({nb_by_network[nb_by_network> big].sum()} observations cumulate)", + f" with {(nb_by_network > big).sum()} network with more than {big} obs and the biggest have {nb_by_network.max()} observations ({nb_by_network[nb_by_network > big].sum()} observations cumulate)", f" {nb_trash} observations in trash", ] return "\n".join(infos) @@ -225,6 +226,12 @@ def network_size(self, id_networks=None): i = id_networks - self.index_network[2] return self.index_network[1][i] - self.index_network[0][i] + def networks_period(self): + """ + Return period for each network + """ + return get_period_with_index(self.time, *self.index_network[:2]) + def unique_segment_to_id(self, id_unique): """Return id network and id segment for a unique id @@ -1788,8 +1795,8 @@ def date2file(julian_day): ) logger.info( ( - f"coherence {_t} / {range_end-1} ({(_t - range_start) / (range_end - range_start-1):.1%})" - f" : {time.time()-_timestamp:5.2f}s" + f"coherence {_t} / {range_end - 1} ({(_t - range_start) / (range_end - range_start - 1):.1%})" + f" : {time.time() - _timestamp:5.2f}s" ) ) @@ -1865,8 +1872,8 @@ def date2file(julian_day): ) logger.info( ( - f"coherence {_t} / {range_end-1} ({(_t - range_start) / (range_end - range_start-1):.1%})" - f" : {time.time()-_timestamp:5.2f}s" + f"coherence {_t} / {range_end - 1} ({(_t - range_start) / (range_end - range_start - 1):.1%})" + f" : {time.time() - _timestamp:5.2f}s" ) ) return itf_final, ptf_final @@ -2065,7 +2072,7 @@ def group_observations(self, min_overlap=0.2, minimal_area=False, **kwargs): nb_alone, nb_obs, nb_gr = (gr == self.NOGROUP).sum(), len(gr), len(unique(gr)) logger.info( f"{nb_alone} alone / {nb_obs} obs, {nb_gr} groups, " - f"{nb_alone *100./nb_obs:.2f} % alone, {(nb_obs - nb_alone) / (nb_gr - 1):.1f} obs/group" + f"{nb_alone * 100. / nb_obs:.2f} % alone, {(nb_obs - nb_alone) / (nb_gr - 1):.1f} obs/group" ) return gr @@ -2316,3 +2323,18 @@ def mask_follow_obs(m, next_obs, time, indexs, dt=3): m[i_next] = True i_next = next_obs[i_next] dt_ = abs(time[i_next] - t0) + + +@njit(cache=True) +def get_period_with_index(t, i0, i1): + """Return peek to peek cover by each slice define by i0 and i1 + + :param array t: array which contain values to estimate spread + :param array i0: index which determine start of slice + :param array i1: index which determine end of slice + :return array: Peek to peek of t + """ + periods = np.empty(i0.size, t.dtype) + for i in range(i0.size): + periods[i] = t[i0[i] : i1[i]].ptp() + return periods From 7ad635def9c26d02f2b00cf4f8c71ff4af449e98 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Fri, 10 Jan 2025 15:46:10 +0100 Subject: [PATCH 244/249] In cas of empty slice continue and set period to 0 --- src/py_eddy_tracker/observations/network.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 87ef4a78..393dae78 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -2336,5 +2336,8 @@ def get_period_with_index(t, i0, i1): """ periods = np.empty(i0.size, t.dtype) for i in range(i0.size): + if i1[i] == i0[i]: + periods[i] = 0 + continue periods[i] = t[i0[i] : i1[i]].ptp() return periods From 1c42ae3358e62055646c11df1d2916de8c3dd941 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Tue, 28 Jan 2025 15:52:09 +0100 Subject: [PATCH 245/249] add docs conf.py --- .readthedocs.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.readthedocs.yml b/.readthedocs.yml index 5ac02e12..ba36f8ea 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -9,3 +9,5 @@ python: install: - method: pip path: . +sphinx: + configuration: doc/conf.py \ No newline at end of file From a39435dd2a02b0f313765452bdaebe39203769cf Mon Sep 17 00:00:00 2001 From: "J. Gamot" Date: Thu, 16 Jan 2025 17:07:06 +0100 Subject: [PATCH 246/249] modifications network file --- src/py_eddy_tracker/appli/gui.py | 7 ++- src/py_eddy_tracker/observations/network.py | 63 ++++++++++++++++++--- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/py_eddy_tracker/appli/gui.py b/src/py_eddy_tracker/appli/gui.py index 4a8cdeb0..c3d7619b 100644 --- a/src/py_eddy_tracker/appli/gui.py +++ b/src/py_eddy_tracker/appli/gui.py @@ -11,7 +11,7 @@ from matplotlib.animation import FuncAnimation from matplotlib.axes import Axes from matplotlib.collections import LineCollection -from numpy import arange, where +from numpy import arange, where, nan from .. import EddyParser from ..gui import GUI @@ -58,7 +58,10 @@ def setup( self.kw_label["fontweight"] = kwargs.pop("fontweight", "demibold") # To text each visible eddy if field_txt: - self.field_txt = self.eddy[field_txt] + if isinstance(field_txt,str): + self.field_txt = self.eddy[field_txt] + else : + self.field_txt=field_txt if field_color: # To color each visible eddy self.field_color = self.eddy[field_color].astype("f4") diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index 393dae78..ef0b02b4 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -5,7 +5,8 @@ from glob import glob import logging import time - +from datetime import timedelta, datetime +import os import netCDF4 from numba import njit, types as nb_types from numba.typed import List @@ -16,6 +17,7 @@ bincount, bool_, concatenate, + empty, nan, ones, @@ -120,6 +122,7 @@ def __repr__(self): period = (self.period[1] - self.period[0]) / 365.25 nb_by_network = self.network_size() nb_trash = 0 if self.ref_index != 0 else nb_by_network[0] + lifetime=self.lifetime big = 50_000 infos = [ f"Atlas with {self.nb_network} networks ({self.nb_network / period:0.0f} networks/year)," @@ -127,6 +130,7 @@ def __repr__(self): f" {m_event.size} merging ({m_event.size / period:0.0f} merging/year), {s_event.size} splitting ({s_event.size / period:0.0f} splitting/year)", f" with {(nb_by_network > big).sum()} network with more than {big} obs and the biggest have {nb_by_network.max()} observations ({nb_by_network[nb_by_network > big].sum()} observations cumulate)", f" {nb_trash} observations in trash", + f" {lifetime.max()} days max of lifetime", ] return "\n".join(infos) @@ -201,6 +205,13 @@ def ref_segment_track_index(self): @property def ref_index(self): return self.index_network[2] + + @property + def lifetime(self): + """Return lifetime for each observation""" + lt=self.networks_period.astype("int") + nb_by_network=self.network_size() + return lt.repeat(nb_by_network) def network_segment_size(self, id_networks=None): """Get number of segment by network @@ -226,12 +237,15 @@ def network_size(self, id_networks=None): i = id_networks - self.index_network[2] return self.index_network[1][i] - self.index_network[0][i] + @property def networks_period(self): """ Return period for each network """ return get_period_with_index(self.time, *self.index_network[:2]) + + def unique_segment_to_id(self, id_unique): """Return id network and id segment for a unique id @@ -281,7 +295,7 @@ def astype(self, cls): new[k][:] = self[k][:] new.sign_type = self.sign_type return new - + def longer_than(self, nb_day_min=-1, nb_day_max=-1): """ Select network on time duration @@ -1132,23 +1146,29 @@ def segment_track_array(self): self._segment_track_array = build_unique_array(self.segment, self.track) return self._segment_track_array - def birth_event(self): + def birth_event(self, only_index=False): """Extract birth events.""" i_start, _, _ = self.index_segment_track indices = i_start[self.previous_obs[i_start] == -1] if self.first_is_trash(): indices = indices[1:] - return self.extract_event(indices) - + if only_index: + return indices + else : + return self.extract_event(indices) + generation_event = birth_event - def death_event(self): + def death_event(self, only_index=False): """Extract death events.""" _, i_stop, _ = self.index_segment_track indices = i_stop[self.next_obs[i_stop - 1] == -1] - 1 if self.first_is_trash(): indices = indices[1:] - return self.extract_event(indices) + if only_index: + return indices + else : + return self.extract_event(indices) dissipation_event = death_event @@ -1459,7 +1479,7 @@ def plot(self, ax, ref=None, color_cycle=None, **kwargs): j += 1 return mappables - def remove_dead_end(self, nobs=3, ndays=0, recursive=0, mask=None): + def remove_dead_end(self, nobs=3, ndays=0, recursive=0, mask=None, return_mask=False): """ Remove short segments that don't connect several segments @@ -1485,6 +1505,8 @@ def remove_dead_end(self, nobs=3, ndays=0, recursive=0, mask=None): ) # get mask for selected obs m = ~self.segment_mask(segments_keep) + if return_mask: + return ~m self.track[m] = 0 self.segment[m] = 0 self.previous_obs[m] = -1 @@ -1502,6 +1524,8 @@ def remove_dead_end(self, nobs=3, ndays=0, recursive=0, mask=None): self.sort() if recursive > 0: self.remove_dead_end(nobs, ndays, recursive - 1) + + def extract_segment(self, segments, absolute=False): """Extract given segments @@ -2042,6 +2066,29 @@ def group_observations(self, min_overlap=0.2, minimal_area=False, **kwargs): results, nb_obs = list(), list() # To display print only in INFO display_iteration = logger.getEffectiveLevel() == logging.INFO + + + # Trier les fichiers par date + def extract_date(file): + filename = os.path.basename(file) + date_str = filename.split('_')[-1].split('.')[0] # Extraire la partie date (ex : "20180101") + return datetime.strptime(date_str, "%Y%m%d") # Convertir en objet datetime + self.filenames = sorted(self.filenames, key=extract_date) + + # Detect missing date and print them to inform the user which files are missing + missing_dates = [] + dates_list = [extract_date(self.filenames[i]) for i in range(len(self.filenames))] + for i in range(len(dates_list) - 1): + expected_date = dates_list[i] + timedelta(days=1) + while expected_date < dates_list[i + 1]: + missing_dates.append(expected_date) + expected_date += timedelta(days=1) + if missing_dates: + missing_str = ', '.join(date.strftime("%Y-%m-%d") for date in missing_dates) + raise Exception(f"Following files missing : {missing_str}") + else: + print("No missing files") + for i, filename in enumerate(self.filenames): if display_iteration: print(f"{filename} compared to {self.window} next", end="\r") From f7f820d3746cc137f14ccb5853599c26dd80cf93 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Wed, 29 Jan 2025 16:17:44 +0100 Subject: [PATCH 247/249] Move out argsort from numba to speed up --- src/py_eddy_tracker/generic.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/py_eddy_tracker/generic.py b/src/py_eddy_tracker/generic.py index 612def68..2fdb737a 100644 --- a/src/py_eddy_tracker/generic.py +++ b/src/py_eddy_tracker/generic.py @@ -615,7 +615,6 @@ def build_circle(x0, y0, r): return x_norm * r + x0, y_norm * r + y0 -@njit(cache=True) def window_index(x, x0, half_window=1): """ Give for a fixed half_window each start and end index for each x0, in @@ -626,7 +625,12 @@ def window_index(x, x0, half_window=1): :param float half_window: half window """ # Sort array, bounds will be sort also - i_ordered = x.argsort() + i_ordered = x.argsort(kind="mergesort") + return window_index_(x, i_ordered, x0, half_window) + + +@njit(cache=True) +def window_index_(x, i_ordered, x0, half_window=1): nb_x, nb_pt = x.size, x0.size first_index = empty(nb_pt, dtype=i_ordered.dtype) last_index = empty(nb_pt, dtype=i_ordered.dtype) From 8fe5bf10e1bc973c83dd114b12e19c37b2f27edc Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Thu, 30 Jan 2025 11:59:41 +0100 Subject: [PATCH 248/249] Remove check on missing file, code was build with bad hypothesis --- src/py_eddy_tracker/observations/network.py | 22 --------------------- 1 file changed, 22 deletions(-) diff --git a/src/py_eddy_tracker/observations/network.py b/src/py_eddy_tracker/observations/network.py index ef0b02b4..f0b9d7cc 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -2067,28 +2067,6 @@ def group_observations(self, min_overlap=0.2, minimal_area=False, **kwargs): # To display print only in INFO display_iteration = logger.getEffectiveLevel() == logging.INFO - - # Trier les fichiers par date - def extract_date(file): - filename = os.path.basename(file) - date_str = filename.split('_')[-1].split('.')[0] # Extraire la partie date (ex : "20180101") - return datetime.strptime(date_str, "%Y%m%d") # Convertir en objet datetime - self.filenames = sorted(self.filenames, key=extract_date) - - # Detect missing date and print them to inform the user which files are missing - missing_dates = [] - dates_list = [extract_date(self.filenames[i]) for i in range(len(self.filenames))] - for i in range(len(dates_list) - 1): - expected_date = dates_list[i] + timedelta(days=1) - while expected_date < dates_list[i + 1]: - missing_dates.append(expected_date) - expected_date += timedelta(days=1) - if missing_dates: - missing_str = ', '.join(date.strftime("%Y-%m-%d") for date in missing_dates) - raise Exception(f"Following files missing : {missing_str}") - else: - print("No missing files") - for i, filename in enumerate(self.filenames): if display_iteration: print(f"{filename} compared to {self.window} next", end="\r") From 229543fdf7d0a8a3e1de6c40d769185cd85ca1b7 Mon Sep 17 00:00:00 2001 From: "A. Delepoulle" <36040805+AntSimi@users.noreply.github.com> Date: Fri, 6 Jun 2025 10:33:16 +0200 Subject: [PATCH 249/249] update changelog --- CHANGELOG.rst | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f8eee72f..6d6d6a30 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -11,14 +11,23 @@ and this project adheres to `Semantic Versioning

    +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�%f-q_Fh|rx`s{;VIHiEwW)6vknTrp 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