pyadps 0.2.0b0__py3-none-any.whl → 0.3.0b0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyadps/pages/01_Read_File.py +96 -17
- pyadps/pages/02_View_Raw_Data.py +69 -33
- pyadps/pages/03_Download_Raw_File.py +4 -4
- pyadps/pages/04_Sensor_Health.py +892 -0
- pyadps/pages/05_QC_Test.py +478 -0
- pyadps/pages/06_Profile_Test.py +959 -0
- pyadps/pages/07_Velocity_Test.py +599 -0
- pyadps/pages/{07_Write_File.py → 08_Write_File.py} +127 -52
- pyadps/pages/09_Auto_process.py +62 -0
- pyadps/utils/__init__.py +2 -3
- pyadps/utils/autoprocess.py +129 -46
- pyadps/utils/metadata/config.ini +22 -4
- pyadps/utils/metadata/demo.000 +0 -0
- pyadps/utils/plotgen.py +499 -0
- pyadps/utils/profile_test.py +491 -126
- pyadps/utils/pyreadrdi.py +13 -6
- pyadps/utils/readrdi.py +78 -6
- pyadps/utils/script.py +21 -23
- pyadps/utils/sensor_health.py +120 -0
- pyadps/utils/signal_quality.py +343 -23
- pyadps/utils/velocity_test.py +75 -27
- pyadps/utils/writenc.py +8 -1
- {pyadps-0.2.0b0.dist-info → pyadps-0.3.0b0.dist-info}/METADATA +53 -22
- pyadps-0.3.0b0.dist-info/RECORD +33 -0
- {pyadps-0.2.0b0.dist-info → pyadps-0.3.0b0.dist-info}/WHEEL +1 -1
- pyadps/pages/04_QC_Test.py +0 -334
- pyadps/pages/05_Profile_Test.py +0 -575
- pyadps/pages/06_Velocity_Test.py +0 -341
- pyadps/utils/cutbin.py +0 -413
- pyadps/utils/regrid.py +0 -279
- pyadps-0.2.0b0.dist-info/RECORD +0 -31
- {pyadps-0.2.0b0.dist-info → pyadps-0.3.0b0.dist-info}/LICENSE +0 -0
- {pyadps-0.2.0b0.dist-info → pyadps-0.3.0b0.dist-info}/entry_points.txt +0 -0
pyadps/utils/cutbin.py
DELETED
@@ -1,413 +0,0 @@
|
|
1
|
-
import matplotlib as mpl
|
2
|
-
import matplotlib.pyplot as plt
|
3
|
-
import numpy as np
|
4
|
-
from matplotlib.widgets import Button, RadioButtons, RectangleSelector, Slider
|
5
|
-
|
6
|
-
from pyadps.utils import readrdi as rd
|
7
|
-
|
8
|
-
|
9
|
-
class CutBins:
|
10
|
-
def __init__(
|
11
|
-
self, data, mask, newmask=False, t1=0, t2=200, tinc=500, z1=0, z2=-1, zinc=0
|
12
|
-
):
|
13
|
-
# DATA SETUP
|
14
|
-
self.orig_data = data
|
15
|
-
self.orig_shape = np.shape(self.orig_data)
|
16
|
-
self.fill = 999
|
17
|
-
self.maskarray = mask
|
18
|
-
if not newmask:
|
19
|
-
self.orig_data[self.maskarray == 1] = self.fill
|
20
|
-
|
21
|
-
self.t1, self.t2, self.tinc = t1, t2, tinc
|
22
|
-
self.z1, self.z2, self.zinc = z1, z2, zinc
|
23
|
-
if z2 == -1:
|
24
|
-
self.z2 = self.orig_shape[0]
|
25
|
-
|
26
|
-
self.data = self.orig_data[self.z1 : self.z2, self.t1 : self.t2]
|
27
|
-
self.orig_subset = self.orig_data[self.z1 : self.z2, self.t1 : self.t2]
|
28
|
-
self.datacopy = np.copy(self.orig_data)
|
29
|
-
self.datamin = np.min(self.orig_data)
|
30
|
-
self.datamax = np.max(self.orig_data)
|
31
|
-
self.shape = np.shape(self.data)
|
32
|
-
|
33
|
-
# PLOT SETUP
|
34
|
-
self.t = np.arange(self.t1, self.t2)
|
35
|
-
self.z = np.arange(self.z1, self.z2)
|
36
|
-
self.tickinterval = int((self.t2 - self.t1) / 5)
|
37
|
-
self.xticks = np.arange(self.t1, self.t2, self.tickinterval)
|
38
|
-
self.X, self.Y = np.meshgrid(self.t, self.z)
|
39
|
-
self.fig, self.axs = plt.subplot_mosaic(
|
40
|
-
[["a", "b"], ["c", "b"]],
|
41
|
-
figsize=(12, 10),
|
42
|
-
width_ratios=[2, 1],
|
43
|
-
height_ratios=[1.75, 1],
|
44
|
-
)
|
45
|
-
self.fig.set_facecolor("darkgrey")
|
46
|
-
plt.subplots_adjust(top=0.82, right=0.95)
|
47
|
-
|
48
|
-
# ADDING WIDGET AXES
|
49
|
-
self.ax_clear_button = self.fig.add_axes(rect=(0.125, 0.90, 0.08, 0.025))
|
50
|
-
self.ax_delete_button = self.fig.add_axes(rect=(0.225, 0.90, 0.08, 0.025))
|
51
|
-
self.ax_refill_button = self.fig.add_axes(rect=(0.325, 0.90, 0.08, 0.025))
|
52
|
-
self.ax_next_button = self.fig.add_axes(rect=(0.630, 0.65, 0.02, 0.050))
|
53
|
-
self.ax_previous_button = self.fig.add_axes(rect=(0.075, 0.65, 0.02, 0.050))
|
54
|
-
self.ax_radio_button = self.fig.add_axes(rect=(0.725, 0.87, 0.10, 0.10))
|
55
|
-
self.ax_exit_button = self.fig.add_axes(rect=(0.825, 0.025, 0.08, 0.035))
|
56
|
-
self.ax_hslider = self.fig.add_axes(rect=(0.125, 0.85, 0.50, 0.03))
|
57
|
-
self.ax_vslider = self.fig.add_axes(rect=(0.04, 0.25, 0.03, 0.50))
|
58
|
-
|
59
|
-
self.ax_delete_button.set_visible(False)
|
60
|
-
self.ax_refill_button.set_visible(False)
|
61
|
-
|
62
|
-
# --- Slider settings ---
|
63
|
-
# Initial slider settings
|
64
|
-
self.hevent = 0
|
65
|
-
self.vevent = 0
|
66
|
-
|
67
|
-
# Slider options
|
68
|
-
self.hslider = Slider(
|
69
|
-
ax=self.ax_hslider,
|
70
|
-
label="Ensemble",
|
71
|
-
valmin=self.t1,
|
72
|
-
valmax=self.t2,
|
73
|
-
valinit=self.hevent,
|
74
|
-
valfmt="%i",
|
75
|
-
valstep=1,
|
76
|
-
)
|
77
|
-
|
78
|
-
self.vslider = Slider(
|
79
|
-
ax=self.ax_vslider,
|
80
|
-
label="Bins",
|
81
|
-
valmin=self.z1,
|
82
|
-
valmax=self.z2,
|
83
|
-
valinit=self.vevent,
|
84
|
-
valfmt="%i",
|
85
|
-
valstep=1,
|
86
|
-
orientation="vertical",
|
87
|
-
)
|
88
|
-
|
89
|
-
# Button Labels
|
90
|
-
self.clear_button = Button(self.ax_clear_button, "Clear")
|
91
|
-
self.delete_button = Button(self.ax_delete_button, "Delete")
|
92
|
-
self.refill_button = Button(self.ax_refill_button, "Refill")
|
93
|
-
self.previous_button = Button(self.ax_previous_button, "<")
|
94
|
-
self.next_button = Button(self.ax_next_button, ">")
|
95
|
-
self.exit_button = Button(self.ax_exit_button, "Save & Exit")
|
96
|
-
# self.cell_button = Button(self.ax_cell_button, "Cell")
|
97
|
-
# self.ensemble_button = Button(self.ax_ensemble_button, "Ensemble")
|
98
|
-
self.radio_button = RadioButtons(
|
99
|
-
self.ax_radio_button, ("Bin", "Ensemble", "Cell", "Region")
|
100
|
-
)
|
101
|
-
|
102
|
-
# --------------PLOTS---------------------
|
103
|
-
|
104
|
-
# Settings colorbar extreme to black
|
105
|
-
cmap = mpl.cm.turbo.with_extremes(over="k")
|
106
|
-
# FILL PLOT
|
107
|
-
self.mesh = self.axs["a"].pcolormesh(
|
108
|
-
self.X, self.Y, self.data, cmap=cmap, picker=True, vmin=0, vmax=255
|
109
|
-
)
|
110
|
-
plt.colorbar(self.mesh, orientation="horizontal")
|
111
|
-
self.axs["a"].set_xlim([self.t1, self.t2])
|
112
|
-
self.axs["a"].set_ylim([self.z1, self.z2])
|
113
|
-
# Draw vertical and horizontal lines
|
114
|
-
(self.vline,) = self.axs["a"].plot(
|
115
|
-
[self.t1, self.t1], [self.z1, self.z2], color="r", linewidth=2.5
|
116
|
-
)
|
117
|
-
(self.hline,) = self.axs["a"].plot(
|
118
|
-
[self.t1, self.t2], [self.z1, self.z1], color="r", linewidth=2.5
|
119
|
-
)
|
120
|
-
|
121
|
-
# PROFILE
|
122
|
-
(self.profile,) = self.axs["b"].plot(
|
123
|
-
self.data[self.z1 : self.z2, self.t1 + self.hevent], range(self.z1, self.z2)
|
124
|
-
)
|
125
|
-
|
126
|
-
self.axs["b"].set_xlim([self.datamin, self.datamax])
|
127
|
-
self.profile_text = self.axs["b"].text(
|
128
|
-
0.95,
|
129
|
-
0.95,
|
130
|
-
f"Ensemble No.: {self.t1 + self.hevent}",
|
131
|
-
verticalalignment="bottom",
|
132
|
-
horizontalalignment="right",
|
133
|
-
transform=self.axs["b"].transAxes,
|
134
|
-
color="k",
|
135
|
-
fontsize=12,
|
136
|
-
)
|
137
|
-
|
138
|
-
# TIME SERIES
|
139
|
-
(self.tseries,) = self.axs["c"].plot(
|
140
|
-
range(self.t1, self.t2), self.data[self.z1 + self.vevent, self.t1 : self.t2]
|
141
|
-
)
|
142
|
-
self.axs["c"].set_ylim([self.datamin, self.datamax])
|
143
|
-
self.tseries_text = self.axs["c"].text(
|
144
|
-
0.90,
|
145
|
-
0.90,
|
146
|
-
f"Bin No.: {self.z1 + self.vevent}",
|
147
|
-
verticalalignment="bottom",
|
148
|
-
horizontalalignment="right",
|
149
|
-
transform=self.axs["c"].transAxes,
|
150
|
-
color="k",
|
151
|
-
fontsize=12,
|
152
|
-
)
|
153
|
-
# --------------END PLOTS---------------------
|
154
|
-
|
155
|
-
# EVENTS
|
156
|
-
self.onclick = self.onclick_bin
|
157
|
-
self.hslider.on_changed(self.hupdate)
|
158
|
-
self.vslider.on_changed(self.vupdate)
|
159
|
-
self.clear_button.on_clicked(self.clear)
|
160
|
-
self.radio_button.on_clicked(self.radio)
|
161
|
-
self.cid = self.fig.canvas.mpl_connect("pick_event", self.onclick)
|
162
|
-
|
163
|
-
self.delete_button.on_clicked(self.boxdelete)
|
164
|
-
self.refill_button.on_clicked(self.boxrefill)
|
165
|
-
self.next_button.on_clicked(self.next)
|
166
|
-
self.previous_button.on_clicked(self.previous)
|
167
|
-
self.exit_button.on_clicked(self.exit)
|
168
|
-
|
169
|
-
def next(self, event):
|
170
|
-
if self.t2 <= self.orig_shape[1]:
|
171
|
-
# Next works till the last subset. The if statement checks for last subset.
|
172
|
-
self.t1 = self.t1 + self.tinc
|
173
|
-
self.t2 = self.t2 + self.tinc
|
174
|
-
if self.t2 > (self.orig_shape[1]):
|
175
|
-
# If in last subset create a dummy data set with missing value.
|
176
|
-
self.data = self.datacopy[
|
177
|
-
self.z1 : self.z2, self.t1 : self.orig_shape[1]
|
178
|
-
]
|
179
|
-
self.orig_subset = self.orig_data[
|
180
|
-
self.z1 : self.z2, self.t1 : self.orig_shape[1]
|
181
|
-
]
|
182
|
-
self.missing = (
|
183
|
-
np.ones((self.z2 - self.z1, self.t2 - self.orig_shape[1]))
|
184
|
-
* self.fill
|
185
|
-
)
|
186
|
-
# self.data consist of data along with flagged value
|
187
|
-
self.data = np.append(self.data, self.missing, axis=1)
|
188
|
-
# self.orig_subset contains only the subset of the original data
|
189
|
-
# Useful for plotting time series and profiles
|
190
|
-
self.orig_subset = np.append(self.orig_subset, self.missing, axis=1)
|
191
|
-
else:
|
192
|
-
self.data = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
|
193
|
-
self.orig_subset = self.orig_data[self.z1 : self.z2, self.t1 : self.t2]
|
194
|
-
|
195
|
-
self.mesh.set_array(self.data)
|
196
|
-
self.tick = np.arange(self.t1, self.t2, self.tickinterval)
|
197
|
-
self.axs["a"].set_xticks(self.xticks, self.tick)
|
198
|
-
|
199
|
-
self.profile.set_xdata(self.orig_subset[:, self.hevent])
|
200
|
-
self.profile_text.set_text(f"Ensemble No.: {self.t1 + self.hevent}")
|
201
|
-
self.vline.set_xdata([self.hevent, self.hevent])
|
202
|
-
|
203
|
-
self.tseries.set_ydata(self.orig_subset[self.vevent, :])
|
204
|
-
self.tseries_text.set_text(f"Bin No.: {self.z1 + self.vevent}")
|
205
|
-
self.hline.set_ydata([self.vevent, self.vevent])
|
206
|
-
|
207
|
-
self.fig.canvas.draw()
|
208
|
-
|
209
|
-
def previous(self, event):
|
210
|
-
if self.t1 >= self.tinc:
|
211
|
-
self.t1 = self.t1 - self.tinc
|
212
|
-
self.t2 = self.t2 - self.tinc
|
213
|
-
self.tick = np.arange(self.t1, self.t2, self.tickinterval)
|
214
|
-
self.data = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
|
215
|
-
self.axs["a"].set_xticks(self.xticks, self.tick)
|
216
|
-
self.mesh.set_array(self.data)
|
217
|
-
|
218
|
-
# Reset sliders
|
219
|
-
self.profile.set_xdata(self.orig_data[self.z1 : self.z2, self.hevent])
|
220
|
-
self.profile_text.set_text(f"Ensemble No.: {self.hevent}")
|
221
|
-
self.vline.set_xdata([self.hevent, self.hevent])
|
222
|
-
|
223
|
-
self.tseries.set_ydata(self.orig_data[self.vevent, self.t1 : self.t2])
|
224
|
-
self.tseries_text.set_text(f"Bin No.: {self.z1 + self.vevent}")
|
225
|
-
self.hline.set_ydata([self.vevent, self.vevent])
|
226
|
-
|
227
|
-
self.fig.canvas.draw()
|
228
|
-
|
229
|
-
def radio(self, event):
|
230
|
-
self.fig.canvas.mpl_disconnect(self.cid)
|
231
|
-
if event == "Bin":
|
232
|
-
self.cid = self.fig.canvas.mpl_connect("pick_event", self.onclick_bin)
|
233
|
-
elif event == "Ensemble":
|
234
|
-
self.cid = self.fig.canvas.mpl_connect("pick_event", self.onclick_ens)
|
235
|
-
elif event == "Cell":
|
236
|
-
self.cid = self.fig.canvas.mpl_connect("pick_event", self.onclick_cell)
|
237
|
-
else:
|
238
|
-
self.rid = RectangleSelector(
|
239
|
-
self.axs["a"],
|
240
|
-
self.onclick_box,
|
241
|
-
useblit=True,
|
242
|
-
minspanx=2,
|
243
|
-
minspany=2,
|
244
|
-
interactive=True,
|
245
|
-
)
|
246
|
-
|
247
|
-
def clear(self, event):
|
248
|
-
if event.button == 1:
|
249
|
-
self.datacopy = np.copy(self.orig_data)
|
250
|
-
if self.t2 >= (self.orig_shape[1]):
|
251
|
-
test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
|
252
|
-
test = np.append(test, self.missing, axis=1)
|
253
|
-
else:
|
254
|
-
test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
|
255
|
-
|
256
|
-
# self.mesh.set_array(self.datacopy[self.z1 : self.z2, self.t1 : self.t2])
|
257
|
-
self.mesh.set_array(test)
|
258
|
-
self.fig.canvas.draw()
|
259
|
-
|
260
|
-
def hupdate(self, event):
|
261
|
-
self.hevent = event
|
262
|
-
self.profile.set_xdata(self.orig_subset[:, self.hevent])
|
263
|
-
self.profile_text.set_text(f"Ensemble No.: {self.t1 + self.hevent}")
|
264
|
-
self.vline.set_xdata([self.hevent, self.hevent])
|
265
|
-
|
266
|
-
def vupdate(self, event):
|
267
|
-
self.vevent = event
|
268
|
-
self.tseries.set_ydata(self.orig_subset[self.vevent, :])
|
269
|
-
self.tseries_text.set_text(f"Bin No.: {self.z1 + self.vevent}")
|
270
|
-
self.hline.set_ydata([self.vevent, self.vevent])
|
271
|
-
|
272
|
-
def onclick_bin(self, event):
|
273
|
-
ind = event.ind
|
274
|
-
x = ind // (self.t[-1] + 1)
|
275
|
-
# y = ind % (self.t[-1] + 1)
|
276
|
-
xx = self.z1 + x
|
277
|
-
# yy = self.t1 + y
|
278
|
-
if np.all(self.datacopy[xx, :] == self.fill):
|
279
|
-
self.datacopy[xx, :] = np.copy(self.orig_data[xx, :])
|
280
|
-
|
281
|
-
else:
|
282
|
-
self.datacopy[xx, :] = self.fill
|
283
|
-
|
284
|
-
if self.t2 >= (self.orig_shape[1]):
|
285
|
-
test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
|
286
|
-
test = np.append(test, self.missing, axis=1)
|
287
|
-
else:
|
288
|
-
test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
|
289
|
-
|
290
|
-
# self.mesh.set_array(self.datacopy[self.z1 : self.z2, self.t1 : self.t2])
|
291
|
-
self.mesh.set_array(test)
|
292
|
-
self.hline.set_ydata([x, x])
|
293
|
-
self.vslider.set_val(x[0])
|
294
|
-
self.fig.canvas.draw()
|
295
|
-
|
296
|
-
def onclick_ens(self, event):
|
297
|
-
ind = event.ind
|
298
|
-
if np.size(ind) != 1:
|
299
|
-
return
|
300
|
-
# x = ind // (self.t[-1] + 1)
|
301
|
-
y = ind % (self.t[-1] + 1)
|
302
|
-
yy = self.t1 + y
|
303
|
-
|
304
|
-
if yy < self.orig_shape[1]:
|
305
|
-
if np.all(self.datacopy[:, yy] == self.fill):
|
306
|
-
self.datacopy[:, yy] = np.copy(self.orig_data[:, yy])
|
307
|
-
else:
|
308
|
-
self.datacopy[:, yy] = self.fill
|
309
|
-
|
310
|
-
if self.t2 >= (self.orig_shape[1]):
|
311
|
-
test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
|
312
|
-
test = np.append(test, self.missing, axis=1)
|
313
|
-
else:
|
314
|
-
test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
|
315
|
-
# self.mesh.set_array(self.datacopy[self.z1 : self.z2, self.t1 : self.t2])
|
316
|
-
self.mesh.set_array(test)
|
317
|
-
self.hline.set_xdata([y, y])
|
318
|
-
self.hslider.set_val(y[0])
|
319
|
-
self.fig.canvas.draw()
|
320
|
-
|
321
|
-
def onclick_cell(self, event):
|
322
|
-
ind = event.ind
|
323
|
-
if np.size(ind) != 1:
|
324
|
-
return
|
325
|
-
x = ind // (self.t[-1] + 1)
|
326
|
-
y = ind % (self.t[-1] + 1)
|
327
|
-
xx = self.z1 + x
|
328
|
-
yy = self.t1 + y
|
329
|
-
|
330
|
-
if yy < self.orig_shape[1]:
|
331
|
-
if self.datacopy[xx, yy] == self.fill:
|
332
|
-
self.datacopy[xx, yy] = np.copy(self.orig_data[x, y])
|
333
|
-
else:
|
334
|
-
self.datacopy[xx, yy] = self.fill
|
335
|
-
|
336
|
-
if self.t2 > (self.orig_shape[1]):
|
337
|
-
test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
|
338
|
-
test = np.append(test, self.missing, axis=1)
|
339
|
-
else:
|
340
|
-
test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
|
341
|
-
|
342
|
-
# self.mesh.set_array(self.datacopy[self.z1 : self.z2, self.t1 : self.t2])
|
343
|
-
self.mesh.set_array(test)
|
344
|
-
self.vline.set_xdata([y, y])
|
345
|
-
self.hline.set_ydata([x, x])
|
346
|
-
self.hslider.set_val(y[0])
|
347
|
-
self.vslider.set_val(x[0])
|
348
|
-
self.fig.canvas.draw()
|
349
|
-
|
350
|
-
def onclick_box(self, eclick, erelease):
|
351
|
-
self.ax_delete_button.set_visible(True)
|
352
|
-
self.ax_refill_button.set_visible(True)
|
353
|
-
plt.gcf().canvas.draw()
|
354
|
-
self.x11, self.y11 = int(eclick.xdata), int(eclick.ydata)
|
355
|
-
self.x22, self.y22 = int(erelease.xdata) + 1, int(erelease.ydata) + 1
|
356
|
-
|
357
|
-
print(
|
358
|
-
f"({self.x11:3.2f}, {self.y11:3.2f}) --> ({self.x22:3.2f}, {self.y22:3.2f})"
|
359
|
-
)
|
360
|
-
print(f" The buttons you used were: {eclick.button} {erelease.button}")
|
361
|
-
|
362
|
-
def boxdelete(self, event):
|
363
|
-
z1 = self.z1 + self.y11 + 1
|
364
|
-
z2 = self.z1 + self.y22
|
365
|
-
t1 = self.t1 + self.x11 + 1
|
366
|
-
t2 = self.t1 + self.x22
|
367
|
-
self.datacopy[z1:z2, t1:t2] = self.fill
|
368
|
-
|
369
|
-
if self.t2 > (self.orig_shape[1]):
|
370
|
-
test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
|
371
|
-
test = np.append(test, self.missing, axis=1)
|
372
|
-
else:
|
373
|
-
test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
|
374
|
-
|
375
|
-
# self.mesh.set_array(self.datacopy[self.z1 : self.z2, self.t1 : self.t2])
|
376
|
-
self.mesh.set_array(test)
|
377
|
-
self.fig.canvas.draw()
|
378
|
-
|
379
|
-
def boxrefill(self, event):
|
380
|
-
z1 = self.z1 + self.y11 + 1
|
381
|
-
z2 = self.z1 + self.y22
|
382
|
-
t1 = self.t1 + self.x11 + 1
|
383
|
-
t2 = self.t1 + self.x22
|
384
|
-
self.datacopy[z1:z2, t1:t2] = self.orig_data[z1:z2, t1:t2]
|
385
|
-
|
386
|
-
if self.t2 > (self.orig_shape[1]):
|
387
|
-
test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
|
388
|
-
test = np.append(test, self.missing, axis=1)
|
389
|
-
else:
|
390
|
-
test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
|
391
|
-
# self.mesh.set_array(self.datacopy[self.z1 : self.z2, self.t1 : self.t2])
|
392
|
-
self.mesh.set_array(test)
|
393
|
-
self.fig.canvas.draw()
|
394
|
-
|
395
|
-
def exit(self, event):
|
396
|
-
plt.close()
|
397
|
-
|
398
|
-
def mask(self):
|
399
|
-
self.maskarray[self.datacopy == self.fill] = 1
|
400
|
-
return self.maskarray
|
401
|
-
|
402
|
-
|
403
|
-
# filename = "BGS11000.000"
|
404
|
-
# ds = rd.echo(filename, run="fortran")
|
405
|
-
# echo = ds[0, :, :]
|
406
|
-
# shape = echo.shape
|
407
|
-
# mask = np.zeros(shape)
|
408
|
-
|
409
|
-
# manual = CutBins(echo, mask)
|
410
|
-
# plt.show()
|
411
|
-
# mask = manual.mask()
|
412
|
-
# plt.pcolormesh(mask)
|
413
|
-
# plt.show()
|
pyadps/utils/regrid.py
DELETED
@@ -1,279 +0,0 @@
|
|
1
|
-
import numpy as np
|
2
|
-
import scipy as sp
|
3
|
-
|
4
|
-
# import readrdi as rd
|
5
|
-
|
6
|
-
|
7
|
-
def regrid2d(
|
8
|
-
flobj,
|
9
|
-
vlobj,
|
10
|
-
data,
|
11
|
-
fill_value,
|
12
|
-
end_bin_option="cell",
|
13
|
-
trimends=None,
|
14
|
-
method="nearest",
|
15
|
-
orientation="default",
|
16
|
-
boundary_limit=0,
|
17
|
-
):
|
18
|
-
"""
|
19
|
-
Regrids 2D data onto a new grid based on specified parameters.
|
20
|
-
|
21
|
-
Parameters:
|
22
|
-
-----------
|
23
|
-
flobj : object
|
24
|
-
The fixed leader object that contains information
|
25
|
-
about the fixed leader data.
|
26
|
-
|
27
|
-
vlobj : object
|
28
|
-
The variable leader object that contains information
|
29
|
-
about the variable leader data.
|
30
|
-
|
31
|
-
data : array-like
|
32
|
-
The 2D data array to be regridded.
|
33
|
-
|
34
|
-
fill_value : scalar
|
35
|
-
The value used to fill missing or undefined grid points.
|
36
|
-
|
37
|
-
end_bin_option : str or float, optional, default="cell"
|
38
|
-
The depth of the last bin or boundary for the grid.
|
39
|
-
Options include:
|
40
|
-
- "cell" : Calculates the depth of the default last bin for the grid.
|
41
|
-
Truncates to surface for upward ADCP.
|
42
|
-
- "surface": The data is gridded till the surface
|
43
|
-
- "manual": User-defined depth for the grid.
|
44
|
-
Use boundary_limit option to provide the value.
|
45
|
-
otherwise, a specific numerical depth value can be provided.
|
46
|
-
|
47
|
-
trimends : tuple of floats, optional, default=None
|
48
|
-
If provided, defines the ensemble range (start, end) for
|
49
|
-
calculating the maximum/minimum transducer depth.
|
50
|
-
Helps avoiding the deployment or retrieval data.
|
51
|
-
E.g. (10, 3000)
|
52
|
-
|
53
|
-
method : str, optional, default="nearest"
|
54
|
-
The interpolation method to use for regridding based
|
55
|
-
on scipy.interpolate.interp1d.
|
56
|
-
Options include:
|
57
|
-
- "nearest" : Nearest neighbor interpolation.
|
58
|
-
- "linear" : Linear interpolation.
|
59
|
-
- "cubic" : Cubic interpolation.
|
60
|
-
|
61
|
-
orientation : str, optional, default="up"
|
62
|
-
Defines the direction of the regridding for an upward/downward looking ADCP. Options include:
|
63
|
-
- "up" : Regrid upwards (for upward-looking ADCP).
|
64
|
-
- "down" : Regrid downwards (for downward-looking ADCP).
|
65
|
-
|
66
|
-
boundary_limit : float, optional, default=0
|
67
|
-
The limit for the boundary depth. This restricts the grid regridding to depths beyond the specified limit.
|
68
|
-
|
69
|
-
Returns:
|
70
|
-
--------
|
71
|
-
z: regridded depth
|
72
|
-
regridded_data : array-like
|
73
|
-
The regridded 2D data array, based on the specified method,
|
74
|
-
orientation, and other parameters.
|
75
|
-
|
76
|
-
Notes:
|
77
|
-
------
|
78
|
-
- If `end_bin_option == boundary`, then `boundary_limit` is used to regrid the data.
|
79
|
-
- This function allows for flexible regridding of 2D data to fit a new grid, supporting different interpolation methods.
|
80
|
-
- The `boundary_limit` parameter helps restrict regridding to depths above or below a certain threshold.
|
81
|
-
"""
|
82
|
-
|
83
|
-
# Get values and convert to 'm'
|
84
|
-
bin1dist = flobj.field()["Bin 1 Dist"] / 100
|
85
|
-
transdepth = vlobj.vleader["Depth of Transducer"] / 10
|
86
|
-
depth_interval = flobj.field()["Depth Cell Len"] / 100
|
87
|
-
bins = flobj.field()["Cells"]
|
88
|
-
ensembles = flobj.ensembles
|
89
|
-
|
90
|
-
if orientation.lower() == "default":
|
91
|
-
orientation = flobj.system_configuration()['Beam Direction']
|
92
|
-
|
93
|
-
if orientation.lower() == "up":
|
94
|
-
sgn = -1
|
95
|
-
else:
|
96
|
-
sgn = 1
|
97
|
-
|
98
|
-
# Create a regular grid
|
99
|
-
|
100
|
-
# Find depth of first cell
|
101
|
-
depth = transdepth + sgn*bin1dist
|
102
|
-
|
103
|
-
# Find the maximum and minimum depth for first cell for upward
|
104
|
-
# looking ADCP (minimum and maximum for downward looking)
|
105
|
-
if trimends is not None:
|
106
|
-
max_depth = abs(np.min(sgn*depth[trimends[0] : trimends[1]]))
|
107
|
-
min_depth = abs(np.max(sgn*depth[trimends[0] : trimends[1]]))
|
108
|
-
else:
|
109
|
-
max_depth = abs(np.min(sgn*depth))
|
110
|
-
min_depth = abs(np.max(sgn*depth))
|
111
|
-
|
112
|
-
# FIRST CELL
|
113
|
-
# Convert the first cell depth to the first regular grid depth
|
114
|
-
depthfirstcell = max_depth - max_depth % depth_interval
|
115
|
-
|
116
|
-
# LAST CELL
|
117
|
-
# Convert the last cell depth to last regular grid depth
|
118
|
-
if end_bin_option.lower() == "surface":
|
119
|
-
# Added one additional negative cell to accomodate 0 m.
|
120
|
-
depthlastcell = sgn * depth_interval
|
121
|
-
elif end_bin_option.lower() == "cell":
|
122
|
-
min_depth_regrid = min_depth - sgn*min_depth % depth_interval
|
123
|
-
depthlastcell = min_depth_regrid + sgn* (bins+1) * depth_interval
|
124
|
-
# Check if this is required. Use 'surface' option
|
125
|
-
if depthlastcell < 0:
|
126
|
-
depthlastcell = sgn*depth_interval
|
127
|
-
elif end_bin_option.lower() == "manual":
|
128
|
-
if sgn < 0 and boundary_limit > depthfirstcell:
|
129
|
-
print("ERROR: For upward looking ADCP, boundary limit should be less than transducer depth")
|
130
|
-
return
|
131
|
-
if sgn > 0 and boundary_limit < depthfirstcell:
|
132
|
-
print("ERROR: For downward looking ADCP, boundary limit should be greater than transducer depth")
|
133
|
-
return
|
134
|
-
# Set the last grid cell depth
|
135
|
-
depthlastcell = boundary_limit
|
136
|
-
else:
|
137
|
-
print("ERROR: `end_bin_option` not recognized.")
|
138
|
-
return
|
139
|
-
|
140
|
-
# Negative used for upward and positive for downward.
|
141
|
-
z = np.arange(sgn * depthfirstcell, sgn * depthlastcell, depth_interval)
|
142
|
-
regbins = len(z)
|
143
|
-
|
144
|
-
regridded_data = np.zeros((regbins, ensembles))
|
145
|
-
|
146
|
-
# Create original depth array
|
147
|
-
for i, d in enumerate(depth):
|
148
|
-
n = d + sgn*depth_interval * bins
|
149
|
-
# np.arange may include unexpected elements due to floating-point
|
150
|
-
# precision issues at the stopping point. Changed to np.linspace.
|
151
|
-
#
|
152
|
-
# depth_bins = np.arange(sgn*d, sgn*n, depth_interval)
|
153
|
-
depth_bins = np.linspace(sgn*d, sgn*n, bins)
|
154
|
-
f = sp.interpolate.interp1d(
|
155
|
-
depth_bins,
|
156
|
-
data[:, i],
|
157
|
-
kind=method,
|
158
|
-
fill_value=fill_value,
|
159
|
-
bounds_error=False,
|
160
|
-
)
|
161
|
-
gridz = f(z)
|
162
|
-
|
163
|
-
regridded_data[:, i] = gridz
|
164
|
-
|
165
|
-
return abs(z), regridded_data
|
166
|
-
|
167
|
-
|
168
|
-
def regrid3d(
|
169
|
-
flobj,
|
170
|
-
vlobj,
|
171
|
-
data,
|
172
|
-
fill_value,
|
173
|
-
end_bin_option="cell",
|
174
|
-
trimends=None,
|
175
|
-
method="nearest",
|
176
|
-
orientation="up",
|
177
|
-
boundary_limit=0,
|
178
|
-
):
|
179
|
-
"""
|
180
|
-
Regrids 3D data onto a new grid based on specified parameters.
|
181
|
-
|
182
|
-
Parameters:
|
183
|
-
-----------
|
184
|
-
flobj : object
|
185
|
-
The fixed leader object that contains information
|
186
|
-
about the fixed leader data.
|
187
|
-
|
188
|
-
vlobj : object
|
189
|
-
The variable leader object that contains information
|
190
|
-
about the variable leader data.
|
191
|
-
|
192
|
-
data : array-like
|
193
|
-
The 3D data array to be regridded, with dimensions
|
194
|
-
typically representing time, depth, and another axis (e.g., ensembles).
|
195
|
-
|
196
|
-
fill_value : scalar
|
197
|
-
The value used to fill missing or undefined grid points.
|
198
|
-
|
199
|
-
end_bin_option : str or float, optional, default="cell"
|
200
|
-
The depth of the last bin or boundary for the grid.
|
201
|
-
Options include:
|
202
|
-
- "cell" : Calculates the depth of the default last bin for the grid.
|
203
|
-
Truncates to surface for upward ADCP.
|
204
|
-
- "surface" : The data is gridded till the surface.
|
205
|
-
- "manual" : User-defined depth for the grid.
|
206
|
-
Use boundary_limit option to provide the value.
|
207
|
-
Otherwise, a specific numerical depth value can be provided.
|
208
|
-
|
209
|
-
trimends : tuple of floats, optional, default=None
|
210
|
-
If provided, defines the ensemble range (start, end) for
|
211
|
-
calculating the maximum/minimum transducer depth.
|
212
|
-
Helps avoiding the deployment or retrieval data.
|
213
|
-
E.g., (10, 3000)
|
214
|
-
|
215
|
-
method : str, optional, default="nearest"
|
216
|
-
The interpolation method to use for regridding based
|
217
|
-
on scipy.interpolate.interp1d.
|
218
|
-
Options include:
|
219
|
-
- "nearest" : Nearest neighbor interpolation.
|
220
|
-
- "linear" : Linear interpolation.
|
221
|
-
- "cubic" : Cubic interpolation.
|
222
|
-
|
223
|
-
orientation : str, optional, default="up"
|
224
|
-
Defines the direction of the regridding for an upward/downward looking ADCP. Options include:
|
225
|
-
- "up" : Regrid upwards (for upward-looking ADCP).
|
226
|
-
- "down" : Regrid downwards (for downward-looking ADCP).
|
227
|
-
|
228
|
-
boundary_limit : float, optional, default=0
|
229
|
-
The limit for the boundary depth. This restricts the grid regridding to depths beyond the specified limit.
|
230
|
-
|
231
|
-
Returns:
|
232
|
-
--------
|
233
|
-
z : array-like
|
234
|
-
The regridded depth array.
|
235
|
-
regridded_data : array-like
|
236
|
-
The regridded 3D data array, based on the specified method,
|
237
|
-
orientation, and other parameters.
|
238
|
-
|
239
|
-
Notes:
|
240
|
-
------
|
241
|
-
- If `end_bin_option == boundary`, then `boundary_limit` is used to regrid the data.
|
242
|
-
- This function allows for flexible regridding of 3D data to fit a new grid, supporting different interpolation methods.
|
243
|
-
- The `boundary_limit` parameter helps restrict regridding to depths above or below a certain threshold.
|
244
|
-
- This function is an extension of 2D regridding to handle the time dimension or other additional axes in the data.
|
245
|
-
"""
|
246
|
-
|
247
|
-
beams = flobj.field()["Beams"]
|
248
|
-
z, data_dummy = regrid2d(
|
249
|
-
flobj,
|
250
|
-
vlobj,
|
251
|
-
data[0, :, :],
|
252
|
-
fill_value,
|
253
|
-
end_bin_option=end_bin_option,
|
254
|
-
trimends=trimends,
|
255
|
-
method=method,
|
256
|
-
orientation=orientation,
|
257
|
-
boundary_limit=boundary_limit,
|
258
|
-
)
|
259
|
-
|
260
|
-
newshape = np.shape(data_dummy)
|
261
|
-
regridded_data = np.zeros((beams, newshape[0], newshape[1]))
|
262
|
-
regridded_data[0, :, :] = data_dummy
|
263
|
-
|
264
|
-
for i in range(beams - 1):
|
265
|
-
z, data_dummy = regrid2d(
|
266
|
-
flobj,
|
267
|
-
vlobj,
|
268
|
-
data[i + 1, :, :],
|
269
|
-
fill_value,
|
270
|
-
end_bin_option=end_bin_option,
|
271
|
-
trimends=trimends,
|
272
|
-
method=method,
|
273
|
-
orientation=orientation,
|
274
|
-
boundary_limit=boundary_limit,
|
275
|
-
)
|
276
|
-
regridded_data[i + 1, :, :] = data_dummy
|
277
|
-
|
278
|
-
return z, regridded_data
|
279
|
-
|