pyadps 0.1.0b0__tar.gz → 0.2.0b0__tar.gz
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-0.1.0b0 → pyadps-0.2.0b0}/PKG-INFO +2 -1
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/pyproject.toml +2 -1
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/pages/01_Read_File.py +2 -0
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/pages/03_Download_Raw_File.py +22 -9
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/pages/04_QC_Test.py +56 -5
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/pages/05_Profile_Test.py +203 -17
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/pages/06_Velocity_Test.py +67 -19
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/pages/07_Write_File.py +138 -53
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/utils/__init__.py +1 -1
- pyadps-0.2.0b0/src/pyadps/utils/autoprocess.py +282 -0
- pyadps-0.2.0b0/src/pyadps/utils/metadata/config.ini +81 -0
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/utils/profile_test.py +36 -24
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/utils/readrdi.py +3 -2
- pyadps-0.2.0b0/src/pyadps/utils/regrid.py +279 -0
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/utils/velocity_test.py +50 -15
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/utils/writenc.py +82 -20
- pyadps-0.1.0b0/src/pyadps/utils/regrid.py +0 -122
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/LICENSE +0 -0
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/README.md +0 -0
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/Home_Page.py +0 -0
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/__init__.py +0 -0
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/__main__.py +0 -0
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/pages/02_View_Raw_Data.py +0 -0
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/pages/__init__.py +0 -0
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/utils/cutbin.py +0 -0
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/utils/metadata/flmeta.json +0 -0
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/utils/metadata/vlmeta.json +0 -0
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/utils/plotgen.py +0 -0
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/utils/pyreadrdi.py +0 -0
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/utils/script.py +0 -0
- {pyadps-0.1.0b0 → pyadps-0.2.0b0}/src/pyadps/utils/signal_quality.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: pyadps
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.2.0b0
|
4
4
|
Summary: A Python package for ADCP data processing
|
5
5
|
Home-page: https://example.com
|
6
6
|
License: MIT
|
@@ -12,6 +12,7 @@ Classifier: License :: OSI Approved :: MIT License
|
|
12
12
|
Classifier: Operating System :: OS Independent
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
15
16
|
Provides-Extra: tests
|
16
17
|
Requires-Dist: cmake (>=3.30.2)
|
17
18
|
Requires-Dist: matplotlib (>=3.8.4)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "pyadps"
|
3
|
-
version = "0.
|
3
|
+
version = "0.2.0-beta"
|
4
4
|
description = "A Python package for ADCP data processing"
|
5
5
|
authors = ["P. Amol <prakashamol@gmail.com>"]
|
6
6
|
readme = "README.md"
|
@@ -36,6 +36,7 @@ tests = ["pytest"]
|
|
36
36
|
|
37
37
|
[tool.poetry.scripts]
|
38
38
|
run-pyadps = "pyadps.__main__:main"
|
39
|
+
run-auto = "pyadps.utils.autoprocess:main"
|
39
40
|
|
40
41
|
[build-system]
|
41
42
|
requires = ["poetry-core>=1.0.0"]
|
@@ -110,6 +110,7 @@ if uploaded_file is not None:
|
|
110
110
|
correlation = ds.correlation.data
|
111
111
|
echo = ds.echo.data
|
112
112
|
pgood = ds.percentgood.data
|
113
|
+
beamdir = ds.fixedleader.system_configuration()['Beam Direction']
|
113
114
|
|
114
115
|
st.session_state.fname = uploaded_file.name
|
115
116
|
st.session_state.head = ds.fileheader
|
@@ -119,6 +120,7 @@ if uploaded_file is not None:
|
|
119
120
|
st.session_state.echo = ds.echo.data
|
120
121
|
st.session_state.correlation = ds.correlation.data
|
121
122
|
st.session_state.pgood = ds.percentgood.data
|
123
|
+
st.session_state.beam_direction = beamdir
|
122
124
|
|
123
125
|
# st.session_state.flead = flead
|
124
126
|
# st.session_state.vlead = vlead
|
@@ -46,24 +46,27 @@ def read_file(filepath):
|
|
46
46
|
st.session_state.ds = ds
|
47
47
|
|
48
48
|
@st.cache_data
|
49
|
-
def file_write(path, add_attributes=True):
|
49
|
+
def file_write(path, axis_option, add_attributes=True):
|
50
50
|
tempdirname = tempfile.TemporaryDirectory(delete=False)
|
51
51
|
st.session_state.rawfilename = tempdirname.name + "/rawfile.nc"
|
52
52
|
|
53
53
|
if add_attributes:
|
54
|
-
wr.
|
54
|
+
wr.rawnc(path, st.session_state.rawfilename, st.session_state.date, axis_option, attributes=st.session_state.attributes)
|
55
55
|
else:
|
56
|
-
wr.
|
56
|
+
wr.rawnc(path, st.session_state.rawfilename, st.session_state.date,axis_option)
|
57
57
|
|
58
58
|
@st.cache_data
|
59
|
-
def file_write_vlead(path, add_attributes=True):
|
59
|
+
def file_write_vlead(path, axis_option, add_attributes=True):
|
60
60
|
tempvardirname = tempfile.TemporaryDirectory(delete=False)
|
61
61
|
st.session_state.vleadfilename = tempvardirname.name + "/vlead.nc"
|
62
62
|
|
63
63
|
if add_attributes:
|
64
|
-
wr.vlead_nc(path, st.session_state.vleadfilename, attributes=st.session_state.attributes)
|
64
|
+
wr.vlead_nc(path, st.session_state.vleadfilename, st.session_state.date, axis_option, attributes=st.session_state.attributes)
|
65
65
|
else:
|
66
|
-
wr.vlead_nc(path, st.session_state.vleadfilename)
|
66
|
+
wr.vlead_nc(path, st.session_state.vleadfilename, st.session_state.date, axis_option)
|
67
|
+
|
68
|
+
if "axis_option" not in st.session_state:
|
69
|
+
st.session_state.axis_option = "ensemble" # Default value
|
67
70
|
|
68
71
|
# UI for attribute selection
|
69
72
|
st.header("NetCDF File", divider="blue")
|
@@ -97,13 +100,23 @@ if add_attributes == "Yes":
|
|
97
100
|
st.session_state.attributes['Comments'] = st.text_area("Comments")
|
98
101
|
|
99
102
|
st.write("Attributes will be added to the NetCDF file once you submit.")
|
100
|
-
|
103
|
+
|
104
|
+
# Dropdown for axis_option
|
105
|
+
axis_option = st.selectbox(
|
106
|
+
"Select x-axis option:",
|
107
|
+
options=["ensemble", "time"],
|
108
|
+
index=0 # Default to "ensemble"
|
109
|
+
)
|
110
|
+
|
111
|
+
# Ensure it is passed correctly
|
112
|
+
st.session_state.axis_option = axis_option
|
113
|
+
|
101
114
|
# Buttons to generate files
|
102
115
|
download_button = st.button("Generate Raw NetCDF File")
|
103
116
|
download_var_button = st.button("Generate Raw Variable Leader NetCDF File")
|
104
117
|
|
105
118
|
if download_button:
|
106
|
-
file_write(st.session_state.fpath, add_attributes == "Yes")
|
119
|
+
file_write(st.session_state.fpath, st.session_state.axis_option , add_attributes == "Yes")
|
107
120
|
st.write(st.session_state.rawfilename)
|
108
121
|
with open(st.session_state.rawfilename, "rb") as file:
|
109
122
|
st.download_button(
|
@@ -113,7 +126,7 @@ if download_button:
|
|
113
126
|
)
|
114
127
|
|
115
128
|
if download_var_button:
|
116
|
-
file_write_vlead(st.session_state.fpath, add_attributes == "Yes")
|
129
|
+
file_write_vlead(st.session_state.fpath, st.session_state.axis_option, add_attributes == "Yes")
|
117
130
|
st.write(st.session_state.vleadfilename)
|
118
131
|
with open(st.session_state.vleadfilename, "rb") as file:
|
119
132
|
st.download_button(
|
@@ -5,6 +5,7 @@ import plotly.graph_objects as go
|
|
5
5
|
import streamlit as st
|
6
6
|
from plotly.subplots import make_subplots
|
7
7
|
from plotly_resampler import FigureResampler
|
8
|
+
from streamlit.runtime.state import session_state
|
8
9
|
from utils.signal_quality import ev_check, false_target, pg_check, qc_check
|
9
10
|
|
10
11
|
if "flead" not in st.session_state:
|
@@ -134,11 +135,25 @@ plot_noise(dep=dn, rec=rn)
|
|
134
135
|
################## QC Test ###################
|
135
136
|
|
136
137
|
st.header("Quality Control Tests", divider="blue")
|
138
|
+
st.write("")
|
137
139
|
|
138
140
|
left, right = st.columns([1, 1])
|
139
141
|
with left:
|
140
|
-
st.write("
|
142
|
+
st.write(""" Teledyne RDI recommends these quality control tests,
|
143
|
+
some of which can be configured before deployment.
|
144
|
+
The pre-deployment values configured for the ADCP are listed
|
145
|
+
in the table below. The noise-floor identification graph above
|
146
|
+
can assist in determining the echo intensity threshold.
|
147
|
+
For more information about these tests,
|
148
|
+
refer to *Acoustic Doppler Current Profiler Principles of
|
149
|
+
Operation: A Practical Primer* by Teledyne RDI.""")
|
141
150
|
fdata = st.session_state.flead.field()
|
151
|
+
st.divider()
|
152
|
+
st.write(":blue-background[Additional Information:]")
|
153
|
+
st.write(f"Number of Pings per Ensemble: `{fdata["Pings"]}`")
|
154
|
+
st.write(f"Number of Beams: `{fdata["Beams"]}`")
|
155
|
+
st.divider()
|
156
|
+
st.write(":red-background[Thresholds used during deployment:]")
|
142
157
|
thresh = pd.DataFrame(
|
143
158
|
[
|
144
159
|
["Correlation", fdata["Correlation Thresh"]],
|
@@ -222,7 +237,7 @@ with left:
|
|
222
237
|
st.session_state.mask = mask
|
223
238
|
|
224
239
|
if st.session_state.isThresh:
|
225
|
-
st.write("Current Thresholds")
|
240
|
+
st.write(":green-background[Current Thresholds]")
|
226
241
|
st.write(st.session_state.newthresh)
|
227
242
|
|
228
243
|
|
@@ -237,7 +252,7 @@ Ensure to save any necessary changes or apply additional thresholds if needed.
|
|
237
252
|
|
238
253
|
|
239
254
|
if st.button("Display mask file"):
|
240
|
-
st.
|
255
|
+
st.subheader("Default Mask File")
|
241
256
|
st.write(
|
242
257
|
"""
|
243
258
|
ADCP assigns missing values based on thresholds set before deployment.
|
@@ -247,7 +262,7 @@ These values cannot be recovered and the default
|
|
247
262
|
fillplot_plotly(st.session_state.orig_mask, colorscale="greys")
|
248
263
|
|
249
264
|
|
250
|
-
st.
|
265
|
+
st.subheader("Update Mask File")
|
251
266
|
st.write(
|
252
267
|
"""
|
253
268
|
Update, display and save the updated mask file after applying threshold.
|
@@ -257,8 +272,36 @@ If thresholds are not saved, default mask file is used.
|
|
257
272
|
# values, counts = np.unique(mask, return_counts=True)
|
258
273
|
fillplot_plotly(st.session_state.mask, colorscale="greys")
|
259
274
|
|
260
|
-
|
275
|
+
############## SENSOR HEALTH ######################
|
276
|
+
st.header("Sensor Health", divider="blue")
|
277
|
+
st.write("The following details can be used to determine whether the additional sensors are functioning properly.")
|
278
|
+
# ################## Pressure Sensor Check ###################
|
279
|
+
# st.subheader("Pressure Sensor Check", divider="orange")
|
280
|
+
#
|
281
|
+
# st.subheader("Temperature Sensor Check", divider="orange")
|
282
|
+
#
|
283
|
+
# st.subheader("Tilt Sensor Check", divider="orange")
|
284
|
+
################## Fix Orientation ###################
|
285
|
+
st.subheader("Fix Orientation", divider="orange")
|
286
|
+
|
287
|
+
|
288
|
+
if st.session_state.beam_direction == 'Up':
|
289
|
+
beamalt = 'Down'
|
290
|
+
else:
|
291
|
+
beamalt = 'Up'
|
292
|
+
st.write(f"The current orientation of ADCP is `{st.session_state.beam_direction}`. Use the below option to correct the orientation.")
|
293
|
+
|
294
|
+
beamdir_select = st.radio(f'Change orientation to {beamalt}', ['No', 'Yes'])
|
295
|
+
if beamdir_select == 'Yes':
|
296
|
+
st.session_state.beam_direction = beamalt
|
297
|
+
st.write(f"The orientation changed to `{st.session_state.beam_direction}`")
|
298
|
+
|
261
299
|
|
300
|
+
|
301
|
+
|
302
|
+
################## Save Button #############
|
303
|
+
st.header("Save Data", divider="blue")
|
304
|
+
col1, col2 = st.columns([1, 1])
|
262
305
|
with col1:
|
263
306
|
save_mask_button = st.button(label="Save Mask Data")
|
264
307
|
|
@@ -281,3 +324,11 @@ with col2:
|
|
281
324
|
st.session_state.isProfileMask = False
|
282
325
|
st.session_state.isVelocityMask = False
|
283
326
|
st.write(":green[Mask data is reset to default]")
|
327
|
+
|
328
|
+
|
329
|
+
|
330
|
+
|
331
|
+
|
332
|
+
|
333
|
+
|
334
|
+
|
@@ -5,7 +5,7 @@ import plotly.graph_objects as go
|
|
5
5
|
import streamlit as st
|
6
6
|
from plotly.subplots import make_subplots
|
7
7
|
from plotly_resampler import FigureResampler
|
8
|
-
from utils.profile_test import side_lobe_beam_angle
|
8
|
+
from utils.profile_test import side_lobe_beam_angle, manual_cut_bins
|
9
9
|
from utils.regrid import regrid2d, regrid3d
|
10
10
|
from utils.signal_quality import default_mask
|
11
11
|
|
@@ -79,6 +79,7 @@ def fillplot_plotly(
|
|
79
79
|
data, title="data", maskdata=None, missing=-32768, colorscale="balance"
|
80
80
|
):
|
81
81
|
fig = FigureResampler(go.Figure())
|
82
|
+
data = np.int32(data)
|
82
83
|
data1 = np.where(data == missing, np.nan, data)
|
83
84
|
fig.add_trace(
|
84
85
|
go.Heatmap(
|
@@ -98,7 +99,7 @@ def fillplot_plotly(
|
|
98
99
|
colorscale="gray",
|
99
100
|
hoverongaps=False,
|
100
101
|
showscale=False,
|
101
|
-
opacity=0.
|
102
|
+
opacity=0.7,
|
102
103
|
)
|
103
104
|
)
|
104
105
|
fig.update_layout(
|
@@ -113,6 +114,7 @@ def fillplot_plotly(
|
|
113
114
|
|
114
115
|
def fillselect_plotly(data, title="data", colorscale="balance"):
|
115
116
|
fig = FigureResampler(go.Figure())
|
117
|
+
data = np.int32(data)
|
116
118
|
data1 = np.where(data == -32768, None, data)
|
117
119
|
fig.add_trace(
|
118
120
|
go.Heatmap(
|
@@ -215,8 +217,10 @@ m = 20
|
|
215
217
|
if "update_mask" not in st.session_state:
|
216
218
|
st.session_state.update_mask = False
|
217
219
|
st.session_state.endpoints = None
|
220
|
+
st.session_state.isTrimEnds = False
|
218
221
|
if "update_mask_cutbin" not in st.session_state:
|
219
222
|
st.session_state.update_mask_cutbin = False
|
223
|
+
st.session_state.isCutBins = False
|
220
224
|
|
221
225
|
ens_range = st.number_input("Change range", x[0], x[-1], 20)
|
222
226
|
start_ens = st.slider("Deployment Ensembles", 0, ens_range, 0)
|
@@ -226,7 +230,7 @@ n = int(ens_range)
|
|
226
230
|
|
227
231
|
if start_ens or end_ens:
|
228
232
|
trim_ends(start_ens=start_ens, end_ens=end_ens, ens_range=n)
|
229
|
-
st.session_state.update_mask = False
|
233
|
+
# st.session_state.update_mask = False
|
230
234
|
|
231
235
|
update_mask = st.button("Update mask data")
|
232
236
|
if update_mask:
|
@@ -246,6 +250,7 @@ if update_mask:
|
|
246
250
|
)
|
247
251
|
st.write(st.session_state.endpoints)
|
248
252
|
st.session_state.update_mask = True
|
253
|
+
st.session_state.isTrimEnds = True
|
249
254
|
|
250
255
|
if not st.session_state.update_mask:
|
251
256
|
st.write(":red[mask data not updated]")
|
@@ -268,13 +273,22 @@ beam = beam - 1
|
|
268
273
|
st.session_state.beam = beam
|
269
274
|
fillplot_plotly(echo[beam, :, :], title="Echo Intensity")
|
270
275
|
|
276
|
+
orientation = st.session_state.beam_direction
|
277
|
+
st.write(f"The orientation is `{orientation}`.")
|
278
|
+
water_column_depth = 0
|
271
279
|
with st.form(key="cutbin_form"):
|
272
280
|
extra_cells = st.number_input("Additional Cells to Delete", 0, 10, 0)
|
281
|
+
if orientation.lower() == 'down':
|
282
|
+
water_column_depth = st.number_input("Enter water column depth (m): ", 0, 15000, 0)
|
283
|
+
|
273
284
|
cut_bins_mask = st.form_submit_button(label="Cut bins")
|
274
285
|
|
275
286
|
if cut_bins_mask:
|
276
287
|
st.session_state.extra_cells = extra_cells
|
277
|
-
mask = side_lobe_beam_angle(flobj, vlobj, mask,
|
288
|
+
mask = side_lobe_beam_angle(flobj, vlobj, mask,
|
289
|
+
orientation=orientation,
|
290
|
+
water_column_depth=water_column_depth,
|
291
|
+
extra_cells=extra_cells)
|
278
292
|
fillplot_plotly(
|
279
293
|
echo[beam, :, :],
|
280
294
|
title="Echo Intensity (Masked)",
|
@@ -287,14 +301,140 @@ if update_mask_cutbin:
|
|
287
301
|
st.session_state.maskp = mask
|
288
302
|
st.write(":green[mask file updated]")
|
289
303
|
st.session_state.update_mask_cutbin = True
|
304
|
+
st.session_state.isCutBins = True
|
290
305
|
|
291
306
|
if not st.session_state.update_mask_cutbin:
|
292
307
|
st.write(":red[mask file not updated]")
|
293
308
|
|
294
309
|
|
295
|
-
|
310
|
+
########### CUT BINS: Manual #################
|
296
311
|
st.header("Cut Bins: Manual", divider="blue")
|
312
|
+
# Reset mask
|
313
|
+
# Selection of variable (Velocity, Echo Intensity, etc.)
|
314
|
+
variable = st.selectbox(
|
315
|
+
"Select Variable to Display",
|
316
|
+
("Velocity", "Echo Intensity", "Correlation", "Percentage Good")
|
317
|
+
)
|
318
|
+
|
319
|
+
# Map variable selection to corresponding data
|
320
|
+
data_dict = {
|
321
|
+
"Velocity": velocity,
|
322
|
+
"Echo Intensity": echo,
|
323
|
+
"Correlation": correlation,
|
324
|
+
"Percentage Good": pgood,
|
325
|
+
}
|
326
|
+
|
327
|
+
# User selects beam (1-4)
|
328
|
+
beam = st.radio("Select beam", (1, 2, 3, 4), horizontal=True, key="beam_selection")
|
329
|
+
beam_index = beam - 1
|
330
|
+
|
331
|
+
# Display the selected variable and beam
|
332
|
+
selected_data = data_dict[variable][beam_index, :, :]
|
333
|
+
fillplot_plotly(selected_data, title=f"{variable}")
|
334
|
+
|
335
|
+
|
336
|
+
st.subheader("Mask Selected Regions")
|
337
|
+
with st.form(key="manual_cutbin_form"):
|
338
|
+
st.write("Select the specific range of cells and ensembles to delete")
|
339
|
+
|
340
|
+
# Input for selecting minimum and maximum cells
|
341
|
+
min_cell = st.number_input("Min Cell", 0, int(flobj.field()["Cells"]), 0)
|
342
|
+
max_cell = st.number_input("Max Cell", 0, int(flobj.field()["Cells"]), 10)
|
343
|
+
|
344
|
+
# Input for selecting minimum and maximum ensembles
|
345
|
+
min_ensemble = st.number_input("Min Ensemble", 0, int(flobj.ensembles), 0)
|
346
|
+
max_ensemble = st.number_input("Max Ensemble", 0, int(flobj.ensembles), int(flobj.ensembles))
|
347
|
+
|
348
|
+
# Submit button to apply the mask
|
349
|
+
cut_bins_mask_manual = st.form_submit_button(label="Apply Manual Cut Bins")
|
297
350
|
|
351
|
+
if cut_bins_mask_manual:
|
352
|
+
mask = manual_cut_bins(mask, min_cell, max_cell, min_ensemble, max_ensemble)
|
353
|
+
st.session_state.maskp = mask
|
354
|
+
fillplot_plotly(
|
355
|
+
echo[beam, :, :],
|
356
|
+
title="Echo Intensity (Masked Manually)",
|
357
|
+
maskdata=mask,
|
358
|
+
)
|
359
|
+
fillplot_plotly(mask, colorscale="greys", title="Mask Data")
|
360
|
+
|
361
|
+
# Adding the new feature: Delete Single Cell or Ensemble
|
362
|
+
st.subheader("Delete Specific Cell or Ensemble")
|
363
|
+
|
364
|
+
# Step 1: User chooses between deleting a cell or an ensemble
|
365
|
+
delete_option = st.radio("Select option to delete", ("Cell", "Ensemble"), horizontal=True)
|
366
|
+
|
367
|
+
# Step 2: Display options based on user's choice
|
368
|
+
if delete_option == "Cell":
|
369
|
+
# Option to delete a specific cell across all ensembles
|
370
|
+
with st.form(key="delete_cell_form"):
|
371
|
+
st.write("Select a specific cell to delete across all ensembles")
|
372
|
+
|
373
|
+
# Input for selecting a single cell
|
374
|
+
cell = st.number_input("Cell", 0, int(flobj.field()["Cells"]), 0, key="single_cell")
|
375
|
+
|
376
|
+
# Submit button to apply the mask for cell deletion
|
377
|
+
delete_cell = st.form_submit_button(label="Delete Cell")
|
378
|
+
|
379
|
+
if delete_cell:
|
380
|
+
mask[cell, :] = 1 # Mask the entire row for the selected cell
|
381
|
+
st.session_state.maskp = mask
|
382
|
+
fillplot_plotly(
|
383
|
+
echo[beam, :, :],
|
384
|
+
title=f"Echo Intensity (Cell {cell} Deleted Across Ensembles)",
|
385
|
+
maskdata=mask,
|
386
|
+
)
|
387
|
+
fillplot_plotly(mask, colorscale="greys", title="Mask Data")
|
388
|
+
|
389
|
+
elif delete_option == "Ensemble":
|
390
|
+
# Option to delete a specific ensemble across all cells
|
391
|
+
with st.form(key="delete_ensemble_form"):
|
392
|
+
st.write("Select a specific ensemble to delete across all cells")
|
393
|
+
|
394
|
+
# Input for selecting a specific ensemble
|
395
|
+
ensemble = st.number_input("Ensemble", 0, int(flobj.ensembles), 0, key="single_ensemble")
|
396
|
+
|
397
|
+
# Submit button to apply the mask for ensemble deletion
|
398
|
+
delete_ensemble = st.form_submit_button(label="Delete Ensemble")
|
399
|
+
|
400
|
+
if delete_ensemble:
|
401
|
+
mask[:, ensemble-1] = 1 # Mask the entire column for the selected ensemble
|
402
|
+
st.session_state.maskp = mask
|
403
|
+
fillplot_plotly(
|
404
|
+
echo[beam, :, :],
|
405
|
+
title=f"Echo Intensity (Ensemble {ensemble} Deleted Across Cells)",
|
406
|
+
maskdata=mask,
|
407
|
+
)
|
408
|
+
fillplot_plotly(mask, colorscale="greys", title="Mask Data")
|
409
|
+
|
410
|
+
|
411
|
+
# Layout with two columns
|
412
|
+
col1, col2 = st.columns([2, 1])
|
413
|
+
|
414
|
+
with col1:
|
415
|
+
|
416
|
+
# Button to save mask data after manual cut bins, with unique key
|
417
|
+
update_mask_cutbin = st.button("Update mask file after cutbin Manual", key="update_cutbin_button")
|
418
|
+
if update_mask_cutbin:
|
419
|
+
st.session_state.maskp = mask
|
420
|
+
st.write(":green[mask file updated]")
|
421
|
+
st.session_state.update_mask_cutbin = True
|
422
|
+
st.session_state.isCutBins = True
|
423
|
+
|
424
|
+
if not st.session_state.update_mask_cutbin:
|
425
|
+
st.write(":red[mask file not updated]")
|
426
|
+
|
427
|
+
with col2:
|
428
|
+
# Button to reset the mask data, with unique key
|
429
|
+
reset_mask_button = st.button("Reset mask data", key="reset_mask_button")
|
430
|
+
if reset_mask_button:
|
431
|
+
st.session_state.maskp = np.copy(st.session_state.orig_mask)
|
432
|
+
st.write(":green[Mask data is reset to default]")
|
433
|
+
st.session_state.isQCMask = False
|
434
|
+
st.session_state.isProfileMask = False
|
435
|
+
st.session_state.isGrid = False
|
436
|
+
st.session_state.isGridSave = False
|
437
|
+
st.session_state.isVelocityMask = False
|
298
438
|
|
299
439
|
############ REGRID ###########################################
|
300
440
|
st.header("Regrid Depth Cells", divider="blue")
|
@@ -304,38 +444,84 @@ st.write(
|
|
304
444
|
When the ADCP buoy has vertical oscillations (greater than depth cell size),
|
305
445
|
the depth bins has to be regridded based on the pressure sensor data. The data
|
306
446
|
can be regrided either till the surface or till the last bin.
|
307
|
-
If the `
|
447
|
+
If the `Cell` option is selected, ensure that the end data are trimmed.
|
448
|
+
Manual option permits choosing the end cell depth.
|
308
449
|
"""
|
309
450
|
)
|
310
451
|
|
311
|
-
|
312
|
-
|
313
|
-
)
|
314
|
-
|
315
|
-
|
316
|
-
|
452
|
+
if st.session_state.beam_direction.lower() == "up":
|
453
|
+
end_bin_option = st.radio(
|
454
|
+
"Select the depth of last bin for regridding", ("Cell", "Surface", "Manual"), horizontal=True
|
455
|
+
)
|
456
|
+
else:
|
457
|
+
end_bin_option = st.radio(
|
458
|
+
"Select the depth of last bin for regridding", ("Cell", "Manual"), horizontal=True
|
459
|
+
)
|
460
|
+
|
461
|
+
st.session_state.end_bin_option = end_bin_option
|
462
|
+
st.write(f"You have selected: `{end_bin_option}`")
|
463
|
+
|
464
|
+
if end_bin_option == "Manual":
|
465
|
+
mean_depth = np.mean(st.session_state.vlead.vleader["Depth of Transducer"]) / 10
|
466
|
+
mean_depth = round(mean_depth, 2)
|
317
467
|
|
468
|
+
st.write(f"The transducer depth is {mean_depth} m. The value should not exceed the transducer depth")
|
469
|
+
if st.session_state.beam_direction.lower() == "up":
|
470
|
+
boundary = st.number_input("Enter the depth (m):", max_value=int(mean_depth), min_value=0)
|
471
|
+
else:
|
472
|
+
boundary = st.number_input("Enter the depth (m):", min_value=int(mean_depth))
|
473
|
+
else:
|
474
|
+
boundary = 0
|
475
|
+
|
476
|
+
interpolate = st.radio("Choose interpolation method:", ("nearest", "linear", "cubic"))
|
477
|
+
|
478
|
+
regrid_button = st.button(label="Regrid Data")
|
318
479
|
|
319
480
|
if regrid_button:
|
320
481
|
st.write(st.session_state.endpoints)
|
321
482
|
z, st.session_state.velocity_regrid = regrid3d(
|
322
|
-
flobj, vlobj, velocity, -32768,
|
483
|
+
flobj, vlobj, velocity, -32768,
|
484
|
+
trimends=st.session_state.endpoints,
|
485
|
+
end_bin_option=st.session_state.end_bin_option,
|
486
|
+
orientation=st.session_state.beam_direction,
|
487
|
+
method=interpolate,
|
488
|
+
boundary_limit=boundary
|
323
489
|
)
|
324
490
|
st.write(":grey[Regrided velocity ...]")
|
325
491
|
z, st.session_state.echo_regrid = regrid3d(
|
326
|
-
flobj, vlobj, echo, -32768,
|
492
|
+
flobj, vlobj, echo, -32768,
|
493
|
+
trimends=st.session_state.endpoints,
|
494
|
+
end_bin_option=st.session_state.end_bin_option,
|
495
|
+
orientation=st.session_state.beam_direction,
|
496
|
+
method=interpolate,
|
497
|
+
boundary_limit=boundary
|
327
498
|
)
|
328
499
|
st.write(":grey[Regrided echo intensity ...]")
|
329
500
|
z, st.session_state.correlation_regrid = regrid3d(
|
330
|
-
flobj, vlobj, correlation, -32768,
|
501
|
+
flobj, vlobj, correlation, -32768,
|
502
|
+
trimends=st.session_state.endpoints,
|
503
|
+
end_bin_option=st.session_state.end_bin_option,
|
504
|
+
orientation=st.session_state.beam_direction,
|
505
|
+
method=interpolate,
|
506
|
+
boundary_limit=boundary
|
331
507
|
)
|
332
508
|
st.write(":grey[Regrided correlation...]")
|
333
509
|
z, st.session_state.pgood_regrid = regrid3d(
|
334
|
-
flobj, vlobj, pgood, -32768,
|
510
|
+
flobj, vlobj, pgood, -32768,
|
511
|
+
trimends=st.session_state.endpoints,
|
512
|
+
end_bin_option=st.session_state.end_bin_option,
|
513
|
+
orientation=st.session_state.beam_direction,
|
514
|
+
method=interpolate,
|
515
|
+
boundary_limit=boundary
|
335
516
|
)
|
336
517
|
st.write(":grey[Regrided percent good...]")
|
337
518
|
z, st.session_state.mask_regrid = regrid2d(
|
338
|
-
flobj, vlobj, mask, 1,
|
519
|
+
flobj, vlobj, mask, 1,
|
520
|
+
trimends=st.session_state.endpoints,
|
521
|
+
end_bin_option=st.session_state.end_bin_option,
|
522
|
+
orientation=st.session_state.beam_direction,
|
523
|
+
method="nearest",
|
524
|
+
boundary_limit=boundary
|
339
525
|
)
|
340
526
|
|
341
527
|
st.session_state.depth = z
|