From e662ec87a67f873748b47f2674cbf5f69571da06 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 1/3] 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 +- src/py_eddy_tracker/observations/network.py | 1 - .../observations/observation.py | 2 + src/py_eddy_tracker/observations/tracking.py | 15 ++++--- src/py_eddy_tracker/tracking.py | 9 ++-- src/scripts/EddyTranslate | 9 ++-- 16 files changed, 86 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 80def41c..f9b78b99 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 46946e77..693b4ab4 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -108,12 +108,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 d5a727f9..b076c8ae 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 c0924cb3..9be49aad 100644 --- a/src/py_eddy_tracker/observations/groups.py +++ b/src/py_eddy_tracker/observations/groups.py @@ -187,7 +187,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) @@ -195,7 +196,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/network.py b/src/py_eddy_tracker/observations/network.py index 4f9af0b3..a3c1e06d 100644 --- a/src/py_eddy_tracker/observations/network.py +++ b/src/py_eddy_tracker/observations/network.py @@ -7,7 +7,6 @@ import zarr from numba import njit -from numba import types as nb_types from numpy import ( arange, array, diff --git a/src/py_eddy_tracker/observations/observation.py b/src/py_eddy_tracker/observations/observation.py index 557c0279..32ddae75 100644 --- a/src/py_eddy_tracker/observations/observation.py +++ b/src/py_eddy_tracker/observations/observation.py @@ -1330,6 +1330,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 b632270c..f89084e8 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 5114253fa6111160e98b96251df3daa92dce8531 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 2/3] 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 f9b78b99..30226e4d 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 0f8766b8..06741f59 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 693b4ab4..c7225d0a 100644 --- a/src/py_eddy_tracker/__init__.py +++ b/src/py_eddy_tracker/__init__.py @@ -258,7 +258,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 155c668ee92001a0a15d61eda8ee4226cdb26f91 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 3/3] manage time in network --- examples/16_network/pet_follow_particle.py | 4 ++-- examples/16_network/pet_segmentation_anim.py | 3 +-- .../16_network/pet_follow_particle.ipynb | 2 +- .../16_network/pet_segmentation_anim.ipynb | 14 +++++++------- src/py_eddy_tracker/observations/tracking.py | 18 ++++++++++++------ 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/examples/16_network/pet_follow_particle.py b/examples/16_network/pet_follow_particle.py index d7253a87..a2aa2217 100644 --- a/examples/16_network/pet_follow_particle.py +++ b/examples/16_network/pet_follow_particle.py @@ -140,12 +140,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(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): +for t in arange(t_start + dt, t_end): particle_candidate(x0, y0, c, n, t, i_target_b, pct_target_b, n_days=-dt) # %% 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/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 f89084e8..6bf74875 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, @@ -604,6 +605,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), @@ -617,7 +624,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 @@ -644,6 +651,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): @@ -655,8 +663,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 @@ -701,8 +708,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] @@ -732,7 +738,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