forked from AntSimi/py-eddy-tracker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpet_replay_segmentation.py
More file actions
177 lines (149 loc) · 5.1 KB
/
pet_replay_segmentation.py
File metadata and controls
177 lines (149 loc) · 5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
"""
Replay segmentation
===================
Case from figure 10 from https://doi.org/10.1002/2017JC013158
Again with the Ierapetra Eddy
"""
from datetime import datetime, timedelta
from matplotlib import pyplot as plt
from matplotlib.ticker import FuncFormatter
from numpy import where
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
@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=GUI_AXES)
ax.set_xlim(19, 29), ax.set_ylim(31, 35.5)
ax.set_aspect("equal")
ax.set_title(title, weight="bold")
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 instead of the maximum overlap ratio
"""
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_]:
i_next_ = -1
else:
ids["previous_obs"][i_next_] = i_next
i_next = i_next_
def get_obs(dataset):
"Function to isolate a specific obs"
return where(
(dataset.lat > 33)
* (dataset.lat < 34)
* (dataset.lon > 22)
* (dataset.lon < 23)
* (dataset.time > 20630)
* (dataset.time < 20650)
)[0][0]
# %%
# Get original network, we will isolate only relative at order *2*
n = NetworkObservations.load_file(get_demo_path("network_med.nc")).network(651)
n_ = n.relative(get_obs(n), order=2)
# %%
# Display the default segmentation
ax = start_axes(n_.infos())
n_.plot(ax, color_cycle=n.COLORS)
update_axes(ax)
fig = plt.figure(figsize=(15, 5))
ax = fig.add_axes([0.04, 0.05, 0.92, 0.92])
ax.xaxis.set_major_formatter(formatter), ax.grid()
_ = n_.display_timeline(ax)
# %%
# Run a new segmentation
# ----------------------
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 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)
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)
# %%
# Parameters 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)