pyadps 0.1.0b0__py3-none-any.whl → 0.1.2__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/Home_Page.py +11 -5
- pyadps/pages/01_Read_File.py +194 -18
- pyadps/pages/02_View_Raw_Data.py +69 -33
- pyadps/pages/03_Download_Raw_File.py +214 -66
- pyadps/pages/04_Sensor_Health.py +905 -0
- pyadps/pages/05_QC_Test.py +476 -0
- pyadps/pages/06_Profile_Test.py +971 -0
- pyadps/pages/07_Velocity_Test.py +600 -0
- pyadps/pages/08_Write_File.py +606 -0
- pyadps/pages/09_Auto_process.py +64 -0
- pyadps/utils/__init__.py +3 -3
- pyadps/utils/autoprocess.py +548 -0
- pyadps/utils/metadata/config.ini +99 -0
- pyadps/utils/metadata/demo.000 +0 -0
- pyadps/utils/plotgen.py +505 -3
- pyadps/utils/profile_test.py +752 -145
- pyadps/utils/pyreadrdi.py +27 -17
- pyadps/utils/readrdi.py +167 -20
- pyadps/utils/script.py +197 -147
- pyadps/utils/sensor_health.py +120 -0
- pyadps/utils/signal_quality.py +344 -24
- pyadps/utils/velocity_test.py +103 -20
- pyadps/utils/writenc.py +223 -27
- {pyadps-0.1.0b0.dist-info → pyadps-0.1.2.dist-info}/METADATA +56 -24
- pyadps-0.1.2.dist-info/RECORD +33 -0
- {pyadps-0.1.0b0.dist-info → pyadps-0.1.2.dist-info}/WHEEL +1 -1
- pyadps-0.1.2.dist-info/entry_points.txt +5 -0
- pyadps/pages/04_QC_Test.py +0 -283
- pyadps/pages/05_Profile_Test.py +0 -389
- pyadps/pages/06_Velocity_Test.py +0 -293
- pyadps/pages/07_Write_File.py +0 -367
- pyadps/utils/cutbin.py +0 -413
- pyadps/utils/regrid.py +0 -122
- pyadps-0.1.0b0.dist-info/RECORD +0 -29
- pyadps-0.1.0b0.dist-info/entry_points.txt +0 -3
- {pyadps-0.1.0b0.dist-info → pyadps-0.1.2.dist-info}/LICENSE +0 -0
pyadps/pages/04_QC_Test.py
DELETED
@@ -1,283 +0,0 @@
|
|
1
|
-
import numpy as np
|
2
|
-
import pandas as pd
|
3
|
-
import plotly.express as px
|
4
|
-
import plotly.graph_objects as go
|
5
|
-
import streamlit as st
|
6
|
-
from plotly.subplots import make_subplots
|
7
|
-
from plotly_resampler import FigureResampler
|
8
|
-
from utils.signal_quality import ev_check, false_target, pg_check, qc_check
|
9
|
-
|
10
|
-
if "flead" not in st.session_state:
|
11
|
-
st.write(":red[Please Select Data!]")
|
12
|
-
st.stop()
|
13
|
-
|
14
|
-
# `mask` holds the temporary changes in the page
|
15
|
-
# `qcmask` holds the final changes in the page
|
16
|
-
if "mask" not in st.session_state:
|
17
|
-
st.session_state.mask = np.copy(st.session_state.orig_mask)
|
18
|
-
|
19
|
-
if not st.session_state.isQCMask:
|
20
|
-
st.write(":grey[Creating a new mask file ...]")
|
21
|
-
st.session_state.qc_mask = np.copy(st.session_state.orig_mask)
|
22
|
-
st.session_state.isSubmit = False
|
23
|
-
else:
|
24
|
-
st.write(":grey[Working on a saved mask file ...]")
|
25
|
-
st.write(":orange[WARNING! QC test already completed. Reset to change settings.]")
|
26
|
-
reset_button1 = st.button("Reset Mask Data")
|
27
|
-
if reset_button1:
|
28
|
-
st.session_state.mask = np.copy(st.session_state.orig_mask)
|
29
|
-
st.session_state.qc_mask = np.copy(st.session_state.orig_mask)
|
30
|
-
st.write(":green[Mask data is reset to default]")
|
31
|
-
|
32
|
-
if "isThresh" not in st.session_state:
|
33
|
-
st.session_state.isThresh = False
|
34
|
-
|
35
|
-
# Load data
|
36
|
-
flobj = st.session_state.flead
|
37
|
-
vlobj = st.session_state.vlead
|
38
|
-
velocity = st.session_state.velocity
|
39
|
-
echo = st.session_state.echo
|
40
|
-
correlation = st.session_state.correlation
|
41
|
-
pgood = st.session_state.pgood
|
42
|
-
ensembles = st.session_state.head.ensembles
|
43
|
-
cells = flobj.field()["Cells"]
|
44
|
-
fdata = flobj.fleader
|
45
|
-
vdata = vlobj.vleader
|
46
|
-
x = np.arange(0, ensembles, 1)
|
47
|
-
y = np.arange(0, cells, 1)
|
48
|
-
|
49
|
-
|
50
|
-
@st.cache_data
|
51
|
-
def fillplot_plotly(data, colorscale="balance"):
|
52
|
-
fig = FigureResampler(go.Figure())
|
53
|
-
data1 = np.where(data == -32768, np.nan, data)
|
54
|
-
fig.add_trace(
|
55
|
-
go.Heatmap(z=data1[:, 0:-1], x=x, y=y, colorscale=colorscale, hoverongaps=False)
|
56
|
-
)
|
57
|
-
st.plotly_chart(fig)
|
58
|
-
|
59
|
-
|
60
|
-
@st.cache_data
|
61
|
-
def plot_noise(dep=0, rec=-1):
|
62
|
-
n = dep
|
63
|
-
m = rec
|
64
|
-
colorleft = [
|
65
|
-
"rgb(240, 255, 255)",
|
66
|
-
"rgb(115, 147, 179)",
|
67
|
-
"rgb(100, 149, 237)",
|
68
|
-
"rgb(15, 82, 186)",
|
69
|
-
]
|
70
|
-
colorright = [
|
71
|
-
"rgb(250, 200, 152)",
|
72
|
-
"rgb(255, 165, 0)",
|
73
|
-
"rgb(255, 95, 31)",
|
74
|
-
"rgb(139, 64, 0)",
|
75
|
-
]
|
76
|
-
fig = make_subplots(
|
77
|
-
rows=1,
|
78
|
-
cols=2,
|
79
|
-
subplot_titles=[
|
80
|
-
f"Deployment Ensemble ({x[n]+1})",
|
81
|
-
f"Recovery Ensemble ({x[m]+1})",
|
82
|
-
],
|
83
|
-
)
|
84
|
-
for i in range(4):
|
85
|
-
fig.add_trace(
|
86
|
-
go.Scatter(
|
87
|
-
x=echo[i, :, n],
|
88
|
-
y=y,
|
89
|
-
name=f"Beam (D) {i+1}",
|
90
|
-
line=dict(color=colorleft[i]),
|
91
|
-
),
|
92
|
-
row=1,
|
93
|
-
col=1,
|
94
|
-
)
|
95
|
-
for i in range(4):
|
96
|
-
fig.add_trace(
|
97
|
-
go.Scatter(
|
98
|
-
x=echo[i, :, m],
|
99
|
-
y=y,
|
100
|
-
name=f"Beam (R) {i+1}",
|
101
|
-
line=dict(color=colorright[i]),
|
102
|
-
),
|
103
|
-
row=1,
|
104
|
-
col=2,
|
105
|
-
)
|
106
|
-
|
107
|
-
fig.update_layout(height=600, width=800, title_text="Echo Intensity")
|
108
|
-
fig.update_xaxes(title="Echo (count)")
|
109
|
-
fig.update_yaxes(title="Cells")
|
110
|
-
st.plotly_chart(fig)
|
111
|
-
|
112
|
-
######### NOISE FLOOR IDENTIFICATION ##############
|
113
|
-
dn = rn = 1
|
114
|
-
st.header("Noise Floor Identification", divider="blue")
|
115
|
-
st.write(
|
116
|
-
"""
|
117
|
-
If the ADCP has collected data from the air either
|
118
|
-
before deployment or after recovery, this data can
|
119
|
-
be used to estimate the echo intensity threshold.
|
120
|
-
The plots below show the echo intensity from the first
|
121
|
-
and last ensembles. The noise level is typically around
|
122
|
-
30-40 counts throughout the entire profile.
|
123
|
-
"""
|
124
|
-
)
|
125
|
-
dn = st.number_input("Deployment Ensemble", x[0] + 1, x[-1] + 1, x[0] + 1)
|
126
|
-
# r = st.number_input("Recovery Ensemble", -1 * (x[-1] + 1), -1 * (x[0] + 1), -1)
|
127
|
-
rn = st.number_input("Recovery Ensemble", x[0] + 1, x[-1] + 1, x[-1] + 1)
|
128
|
-
dn = dn - 1
|
129
|
-
rn = rn - 1
|
130
|
-
|
131
|
-
plot_noise(dep=dn, rec=rn)
|
132
|
-
|
133
|
-
|
134
|
-
################## QC Test ###################
|
135
|
-
|
136
|
-
st.header("Quality Control Tests", divider="blue")
|
137
|
-
|
138
|
-
left, right = st.columns([1, 1])
|
139
|
-
with left:
|
140
|
-
st.write("Thresholds used during deployment")
|
141
|
-
fdata = st.session_state.flead.field()
|
142
|
-
thresh = pd.DataFrame(
|
143
|
-
[
|
144
|
-
["Correlation", fdata["Correlation Thresh"]],
|
145
|
-
["Error Velocity", fdata["Error Velocity Thresh"]],
|
146
|
-
["Echo Intensity", 0],
|
147
|
-
["False Target", fdata["False Target Thresh"]],
|
148
|
-
["Percentage Good", fdata["Percent Good Min"]],
|
149
|
-
],
|
150
|
-
columns=["Threshold", "Values"],
|
151
|
-
)
|
152
|
-
|
153
|
-
st.write(thresh)
|
154
|
-
|
155
|
-
with right:
|
156
|
-
with st.form(key="my_form"):
|
157
|
-
st.write("Would you like to apply new threshold?")
|
158
|
-
|
159
|
-
ct = st.number_input(
|
160
|
-
"Select Correlation Threshold",
|
161
|
-
0,
|
162
|
-
255,
|
163
|
-
fdata["Correlation Thresh"],
|
164
|
-
)
|
165
|
-
|
166
|
-
evt = st.number_input(
|
167
|
-
"Select Error Velocity Threshold",
|
168
|
-
0,
|
169
|
-
9999,
|
170
|
-
fdata["Error Velocity Thresh"],
|
171
|
-
)
|
172
|
-
|
173
|
-
et = st.number_input(
|
174
|
-
"Select Echo Intensity Threshold",
|
175
|
-
0,
|
176
|
-
255,
|
177
|
-
0,
|
178
|
-
)
|
179
|
-
|
180
|
-
ft = st.number_input(
|
181
|
-
"Select False Target Threshold",
|
182
|
-
0,
|
183
|
-
255,
|
184
|
-
fdata["False Target Thresh"],
|
185
|
-
)
|
186
|
-
|
187
|
-
option = st.selectbox(
|
188
|
-
"Would you like to use a three-beam solution?", (True, False)
|
189
|
-
)
|
190
|
-
|
191
|
-
pgt = st.number_input(
|
192
|
-
"Select Percent Good Threshold",
|
193
|
-
0,
|
194
|
-
100,
|
195
|
-
fdata["Percent Good Min"],
|
196
|
-
)
|
197
|
-
submit_button = st.form_submit_button(label="Submit")
|
198
|
-
|
199
|
-
|
200
|
-
mask = st.session_state.mask
|
201
|
-
with left:
|
202
|
-
if submit_button:
|
203
|
-
st.session_state.newthresh = pd.DataFrame(
|
204
|
-
[
|
205
|
-
["Correlation", str(ct)],
|
206
|
-
["Error Velocity", str(evt)],
|
207
|
-
["Echo Intensity", str(et)],
|
208
|
-
["False Target", str(ft)],
|
209
|
-
["Three Beam", str(option)],
|
210
|
-
["Percentage Good", str(pgt)],
|
211
|
-
],
|
212
|
-
columns=["Threshold", "Values"],
|
213
|
-
)
|
214
|
-
st.session_state.isThresh = True
|
215
|
-
# st.write(st.session_state.newthresh)
|
216
|
-
|
217
|
-
mask = pg_check(pgood, mask, pgt, threebeam=option)
|
218
|
-
mask = qc_check(correlation, mask, ct)
|
219
|
-
mask = qc_check(echo, mask, et)
|
220
|
-
mask = ev_check(velocity[3, :, :], mask, evt)
|
221
|
-
mask = false_target(echo, mask, ft, threebeam=True)
|
222
|
-
st.session_state.mask = mask
|
223
|
-
|
224
|
-
if st.session_state.isThresh:
|
225
|
-
st.write("Current Thresholds")
|
226
|
-
st.write(st.session_state.newthresh)
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
st.header("Mask File", divider="blue")
|
231
|
-
st.write(
|
232
|
-
"""
|
233
|
-
Displayed the mask file.
|
234
|
-
Ensure to save any necessary changes or apply additional thresholds if needed.
|
235
|
-
"""
|
236
|
-
)
|
237
|
-
|
238
|
-
|
239
|
-
if st.button("Display mask file"):
|
240
|
-
st.header("Default Mask File", divider="blue")
|
241
|
-
st.write(
|
242
|
-
"""
|
243
|
-
ADCP assigns missing values based on thresholds set before deployment.
|
244
|
-
These values cannot be recovered and the default
|
245
|
-
"""
|
246
|
-
)
|
247
|
-
fillplot_plotly(st.session_state.orig_mask, colorscale="greys")
|
248
|
-
|
249
|
-
|
250
|
-
st.header("Update Mask File", divider="blue")
|
251
|
-
st.write(
|
252
|
-
"""
|
253
|
-
Update, display and save the updated mask file after applying threshold.
|
254
|
-
If thresholds are not saved, default mask file is used.
|
255
|
-
"""
|
256
|
-
)
|
257
|
-
# values, counts = np.unique(mask, return_counts=True)
|
258
|
-
fillplot_plotly(st.session_state.mask, colorscale="greys")
|
259
|
-
|
260
|
-
col1, col2 = st.columns([1, 1])
|
261
|
-
|
262
|
-
with col1:
|
263
|
-
save_mask_button = st.button(label="Save Mask Data")
|
264
|
-
|
265
|
-
if save_mask_button:
|
266
|
-
# st.session_state.mask = mask
|
267
|
-
st.session_state.qc_mask = np.copy(st.session_state.mask)
|
268
|
-
st.session_state.isQCMask = True
|
269
|
-
st.session_state.isProfileMask = False
|
270
|
-
st.session_state.isGridSave = False
|
271
|
-
st.session_state.isVelocityMask = False
|
272
|
-
st.write(":green[Mask file saved]")
|
273
|
-
else:
|
274
|
-
st.write(":red[Mask data not saved]")
|
275
|
-
with col2:
|
276
|
-
reset_mask_button = st.button("Reset mask Data")
|
277
|
-
if reset_mask_button:
|
278
|
-
st.session_state.mask = np.copy(st.session_state.orig_mask)
|
279
|
-
st.session_state.isQCMask = False
|
280
|
-
st.session_state.isGrid = False
|
281
|
-
st.session_state.isProfileMask = False
|
282
|
-
st.session_state.isVelocityMask = False
|
283
|
-
st.write(":green[Mask data is reset to default]")
|
pyadps/pages/05_Profile_Test.py
DELETED
@@ -1,389 +0,0 @@
|
|
1
|
-
import numpy as np
|
2
|
-
# import pandas as pd
|
3
|
-
# import plotly.express as px
|
4
|
-
import plotly.graph_objects as go
|
5
|
-
import streamlit as st
|
6
|
-
from plotly.subplots import make_subplots
|
7
|
-
from plotly_resampler import FigureResampler
|
8
|
-
from utils.profile_test import side_lobe_beam_angle
|
9
|
-
from utils.regrid import regrid2d, regrid3d
|
10
|
-
from utils.signal_quality import default_mask
|
11
|
-
|
12
|
-
if "flead" not in st.session_state:
|
13
|
-
st.write(":red[Please Select Data!]")
|
14
|
-
st.stop()
|
15
|
-
|
16
|
-
# `maskp` holds the temporary changes in the page
|
17
|
-
# `profile_mask`
|
18
|
-
if "maskp" not in st.session_state:
|
19
|
-
if "qc_mask" not in st.session_state:
|
20
|
-
st.session_state.maskp = np.copy(st.session_state.orig_mask)
|
21
|
-
else:
|
22
|
-
st.session_state.maskp = np.copy(st.session_state.qc_mask)
|
23
|
-
|
24
|
-
|
25
|
-
if st.session_state.isQCMask:
|
26
|
-
st.write(":grey[Working on a saved mask file ...]")
|
27
|
-
if st.session_state.isProfileMask:
|
28
|
-
st.write(
|
29
|
-
":orange[Warning: Profile test already completed. Reset to change settings.]"
|
30
|
-
)
|
31
|
-
reset_selectbox = st.selectbox(
|
32
|
-
"Choose reset option",
|
33
|
-
("QC Test", "Default"),
|
34
|
-
index=None,
|
35
|
-
placeholder="Reset mask to ...",
|
36
|
-
)
|
37
|
-
if reset_selectbox == "Default":
|
38
|
-
st.write("Default mask file selected")
|
39
|
-
st.session_state.maskp = st.session_state.orig_mask
|
40
|
-
elif reset_selectbox == "QC Test":
|
41
|
-
st.write("QC Test mask file selected")
|
42
|
-
st.session_state.maskp = st.session_state.qc_mask
|
43
|
-
else:
|
44
|
-
st.session_state.maskp = st.session_state.profile_mask
|
45
|
-
else:
|
46
|
-
st.session_state.maskp = st.session_state.qc_mask
|
47
|
-
else:
|
48
|
-
st.write(":orange[Creating a new mask file ...]")
|
49
|
-
|
50
|
-
mask = st.session_state.maskp
|
51
|
-
|
52
|
-
# Load data
|
53
|
-
flobj = st.session_state.flead
|
54
|
-
vlobj = st.session_state.vlead
|
55
|
-
velocity = st.session_state.velocity
|
56
|
-
echo = st.session_state.echo
|
57
|
-
correlation = st.session_state.correlation
|
58
|
-
pgood = st.session_state.pgood
|
59
|
-
fdata = flobj.fleader
|
60
|
-
vdata = vlobj.vleader
|
61
|
-
|
62
|
-
|
63
|
-
ensembles = st.session_state.head.ensembles
|
64
|
-
cells = flobj.field()["Cells"]
|
65
|
-
x = np.arange(0, ensembles, 1)
|
66
|
-
y = np.arange(0, cells, 1)
|
67
|
-
|
68
|
-
# Regrided data
|
69
|
-
if "velocity_regrid" not in st.session_state:
|
70
|
-
st.session_state.echo_regrid = np.copy(echo)
|
71
|
-
st.session_state.velocity_regrid = np.copy(velocity)
|
72
|
-
st.session_state.correlation_regrid = np.copy(correlation)
|
73
|
-
st.session_state.pgood_regrid = np.copy(pgood)
|
74
|
-
st.session_state.mask_regrid = np.copy(mask)
|
75
|
-
|
76
|
-
|
77
|
-
# @st.cache_data
|
78
|
-
def fillplot_plotly(
|
79
|
-
data, title="data", maskdata=None, missing=-32768, colorscale="balance"
|
80
|
-
):
|
81
|
-
fig = FigureResampler(go.Figure())
|
82
|
-
data1 = np.where(data == missing, np.nan, data)
|
83
|
-
fig.add_trace(
|
84
|
-
go.Heatmap(
|
85
|
-
z=data1,
|
86
|
-
x=x,
|
87
|
-
y=y,
|
88
|
-
colorscale=colorscale,
|
89
|
-
hoverongaps=False,
|
90
|
-
)
|
91
|
-
)
|
92
|
-
if mask is not None:
|
93
|
-
fig.add_trace(
|
94
|
-
go.Heatmap(
|
95
|
-
z=maskdata,
|
96
|
-
x=x,
|
97
|
-
y=y,
|
98
|
-
colorscale="gray",
|
99
|
-
hoverongaps=False,
|
100
|
-
showscale=False,
|
101
|
-
opacity=0.5,
|
102
|
-
)
|
103
|
-
)
|
104
|
-
fig.update_layout(
|
105
|
-
xaxis=dict(showline=True, mirror=True),
|
106
|
-
yaxis=dict(showline=True, mirror=True),
|
107
|
-
title_text=title,
|
108
|
-
)
|
109
|
-
fig.update_xaxes(title="Ensembles")
|
110
|
-
fig.update_yaxes(title="Depth Cells")
|
111
|
-
st.plotly_chart(fig)
|
112
|
-
|
113
|
-
|
114
|
-
def fillselect_plotly(data, title="data", colorscale="balance"):
|
115
|
-
fig = FigureResampler(go.Figure())
|
116
|
-
data1 = np.where(data == -32768, None, data)
|
117
|
-
fig.add_trace(
|
118
|
-
go.Heatmap(
|
119
|
-
z=data1,
|
120
|
-
x=x,
|
121
|
-
y=y,
|
122
|
-
colorscale=colorscale,
|
123
|
-
hoverongaps=False,
|
124
|
-
)
|
125
|
-
)
|
126
|
-
# fig.add_trace(
|
127
|
-
# go.Scatter(x=X, y=Y, marker=dict(color="black", size=16), mode="lines+markers")
|
128
|
-
# )
|
129
|
-
fig.update_layout(
|
130
|
-
xaxis=dict(showline=True, mirror=True),
|
131
|
-
yaxis=dict(showline=True, mirror=True),
|
132
|
-
title_text=title,
|
133
|
-
)
|
134
|
-
fig.update_xaxes(title="Ensembles")
|
135
|
-
fig.update_yaxes(title="Depth Cells")
|
136
|
-
fig.update_layout(clickmode="event+select")
|
137
|
-
event = st.plotly_chart(fig, key="1", on_select="rerun", selection_mode="box")
|
138
|
-
|
139
|
-
return event
|
140
|
-
|
141
|
-
|
142
|
-
@st.cache_data
|
143
|
-
def trim_ends(start_ens=0, end_ens=0, ens_range=20):
|
144
|
-
depth = vdata["Depth of Transducer"] / 10
|
145
|
-
fig = make_subplots(
|
146
|
-
rows=1,
|
147
|
-
cols=2,
|
148
|
-
subplot_titles=[
|
149
|
-
"Deployment Ensemble",
|
150
|
-
"Recovery Ensemble",
|
151
|
-
],
|
152
|
-
)
|
153
|
-
fig.add_trace(
|
154
|
-
go.Scatter(
|
155
|
-
x=x[0:ens_range],
|
156
|
-
y=depth[0:ens_range],
|
157
|
-
name="Deployment",
|
158
|
-
mode="markers",
|
159
|
-
marker=dict(color="#1f77b4"),
|
160
|
-
),
|
161
|
-
row=1,
|
162
|
-
col=1,
|
163
|
-
)
|
164
|
-
|
165
|
-
fig.add_trace(
|
166
|
-
go.Scatter(
|
167
|
-
x=x[-1 * ens_range :],
|
168
|
-
y=depth[-1 * ens_range :],
|
169
|
-
name="Recovery",
|
170
|
-
mode="markers",
|
171
|
-
marker=dict(color="#17becf"),
|
172
|
-
),
|
173
|
-
row=1,
|
174
|
-
col=2,
|
175
|
-
)
|
176
|
-
|
177
|
-
if start_ens > x[0]:
|
178
|
-
fig.add_trace(
|
179
|
-
go.Scatter(
|
180
|
-
x=x[0:start_ens],
|
181
|
-
y=depth[0:start_ens],
|
182
|
-
name="Selected Points (D)",
|
183
|
-
mode="markers",
|
184
|
-
marker=dict(color="red"),
|
185
|
-
),
|
186
|
-
row=1,
|
187
|
-
col=1,
|
188
|
-
)
|
189
|
-
|
190
|
-
if end_ens < x[-1] + 1:
|
191
|
-
fig.add_trace(
|
192
|
-
go.Scatter(
|
193
|
-
x=x[end_ens : x[-1] + 1],
|
194
|
-
y=depth[end_ens : x[-1] + 1],
|
195
|
-
name="Selected Points (R)",
|
196
|
-
mode="markers",
|
197
|
-
marker=dict(color="orange"),
|
198
|
-
),
|
199
|
-
row=1,
|
200
|
-
col=2,
|
201
|
-
)
|
202
|
-
|
203
|
-
fig.update_layout(height=600, width=800, title_text="Transducer depth")
|
204
|
-
fig.update_xaxes(title="Ensembles")
|
205
|
-
fig.update_yaxes(title="Depth (m)")
|
206
|
-
st.plotly_chart(fig)
|
207
|
-
|
208
|
-
|
209
|
-
st.header("Profile Test")
|
210
|
-
|
211
|
-
############## TRIM ENDS #################
|
212
|
-
st.header("Trim Ends", divider="blue")
|
213
|
-
n = 20
|
214
|
-
m = 20
|
215
|
-
if "update_mask" not in st.session_state:
|
216
|
-
st.session_state.update_mask = False
|
217
|
-
st.session_state.endpoints = None
|
218
|
-
if "update_mask_cutbin" not in st.session_state:
|
219
|
-
st.session_state.update_mask_cutbin = False
|
220
|
-
|
221
|
-
ens_range = st.number_input("Change range", x[0], x[-1], 20)
|
222
|
-
start_ens = st.slider("Deployment Ensembles", 0, ens_range, 0)
|
223
|
-
end_ens = st.slider("Recovery Ensembles", x[-1] - ens_range, x[-1] + 1, x[-1] + 1)
|
224
|
-
|
225
|
-
n = int(ens_range)
|
226
|
-
|
227
|
-
if start_ens or end_ens:
|
228
|
-
trim_ends(start_ens=start_ens, end_ens=end_ens, ens_range=n)
|
229
|
-
st.session_state.update_mask = False
|
230
|
-
|
231
|
-
update_mask = st.button("Update mask data")
|
232
|
-
if update_mask:
|
233
|
-
if start_ens > 0:
|
234
|
-
mask[:, :start_ens] = 1
|
235
|
-
|
236
|
-
if end_ens < x[-1]:
|
237
|
-
mask[:, end_ens:] = 1
|
238
|
-
|
239
|
-
st.session_state.ens_range = ens_range
|
240
|
-
st.session_state.start_ens = start_ens
|
241
|
-
st.session_state.end_ens = end_ens
|
242
|
-
st.session_state.maskp = mask
|
243
|
-
st.write(":green[mask data updated]")
|
244
|
-
st.session_state.endpoints = np.array(
|
245
|
-
[st.session_state.start_ens, st.session_state.end_ens]
|
246
|
-
)
|
247
|
-
st.write(st.session_state.endpoints)
|
248
|
-
st.session_state.update_mask = True
|
249
|
-
|
250
|
-
if not st.session_state.update_mask:
|
251
|
-
st.write(":red[mask data not updated]")
|
252
|
-
|
253
|
-
|
254
|
-
############ CUT BINS (SIDE LOBE) ############################
|
255
|
-
st.header("Cut Bins: Side Lobe Contamination", divider="blue")
|
256
|
-
st.write(
|
257
|
-
"""
|
258
|
-
The side lobe echos from hard surface such as sea surface or bottom of the ocean can contaminate
|
259
|
-
data closer to this region. The data closer to the surface or bottom can be removed using
|
260
|
-
the relation between beam angle and the thickness of the contaminated layer.
|
261
|
-
"""
|
262
|
-
)
|
263
|
-
|
264
|
-
# Reset mask
|
265
|
-
mask = st.session_state.maskp
|
266
|
-
beam = st.radio("Select beam", (1, 2, 3, 4), horizontal=True)
|
267
|
-
beam = beam - 1
|
268
|
-
st.session_state.beam = beam
|
269
|
-
fillplot_plotly(echo[beam, :, :], title="Echo Intensity")
|
270
|
-
|
271
|
-
with st.form(key="cutbin_form"):
|
272
|
-
extra_cells = st.number_input("Additional Cells to Delete", 0, 10, 0)
|
273
|
-
cut_bins_mask = st.form_submit_button(label="Cut bins")
|
274
|
-
|
275
|
-
if cut_bins_mask:
|
276
|
-
st.session_state.extra_cells = extra_cells
|
277
|
-
mask = side_lobe_beam_angle(flobj, vlobj, mask, extra_cells=extra_cells)
|
278
|
-
fillplot_plotly(
|
279
|
-
echo[beam, :, :],
|
280
|
-
title="Echo Intensity (Masked)",
|
281
|
-
maskdata=mask,
|
282
|
-
)
|
283
|
-
fillplot_plotly(mask, colorscale="greys", title="Mask Data")
|
284
|
-
|
285
|
-
update_mask_cutbin = st.button("Update mask file after cutbin")
|
286
|
-
if update_mask_cutbin:
|
287
|
-
st.session_state.maskp = mask
|
288
|
-
st.write(":green[mask file updated]")
|
289
|
-
st.session_state.update_mask_cutbin = True
|
290
|
-
|
291
|
-
if not st.session_state.update_mask_cutbin:
|
292
|
-
st.write(":red[mask file not updated]")
|
293
|
-
|
294
|
-
|
295
|
-
############ CUT BINS: Manual #################
|
296
|
-
st.header("Cut Bins: Manual", divider="blue")
|
297
|
-
|
298
|
-
|
299
|
-
############ REGRID ###########################################
|
300
|
-
st.header("Regrid Depth Cells", divider="blue")
|
301
|
-
|
302
|
-
st.write(
|
303
|
-
"""
|
304
|
-
When the ADCP buoy has vertical oscillations (greater than depth cell size),
|
305
|
-
the depth bins has to be regridded based on the pressure sensor data. The data
|
306
|
-
can be regrided either till the surface or till the last bin.
|
307
|
-
If the `bin` option is selected, ensure that the end data are trimmed.
|
308
|
-
"""
|
309
|
-
)
|
310
|
-
|
311
|
-
last_cell = st.radio(
|
312
|
-
"Select the depth of last bin for regridding", ("Bin", "Surface"), horizontal=True
|
313
|
-
)
|
314
|
-
st.session_state.last_cell = last_cell
|
315
|
-
st.write(last_cell)
|
316
|
-
regrid_button = st.button(label="Regrid Data")
|
317
|
-
|
318
|
-
|
319
|
-
if regrid_button:
|
320
|
-
st.write(st.session_state.endpoints)
|
321
|
-
z, st.session_state.velocity_regrid = regrid3d(
|
322
|
-
flobj, vlobj, velocity, -32768, trimends=st.session_state.endpoints
|
323
|
-
)
|
324
|
-
st.write(":grey[Regrided velocity ...]")
|
325
|
-
z, st.session_state.echo_regrid = regrid3d(
|
326
|
-
flobj, vlobj, echo, -32768, trimends=st.session_state.endpoints
|
327
|
-
)
|
328
|
-
st.write(":grey[Regrided echo intensity ...]")
|
329
|
-
z, st.session_state.correlation_regrid = regrid3d(
|
330
|
-
flobj, vlobj, correlation, -32768, trimends=st.session_state.endpoints
|
331
|
-
)
|
332
|
-
st.write(":grey[Regrided correlation...]")
|
333
|
-
z, st.session_state.pgood_regrid = regrid3d(
|
334
|
-
flobj, vlobj, pgood, -32768, trimends=st.session_state.endpoints
|
335
|
-
)
|
336
|
-
st.write(":grey[Regrided percent good...]")
|
337
|
-
z, st.session_state.mask_regrid = regrid2d(
|
338
|
-
flobj, vlobj, mask, 1, trimends=st.session_state.endpoints
|
339
|
-
)
|
340
|
-
|
341
|
-
st.session_state.depth = z
|
342
|
-
|
343
|
-
st.write(":grey[Regrided mask...]")
|
344
|
-
st.write(":green[All data regrided!]")
|
345
|
-
|
346
|
-
st.write("No. of grid depth bins before regridding: ", np.shape(velocity)[1])
|
347
|
-
st.write(
|
348
|
-
"No. of grid depth bins after regridding: ",
|
349
|
-
np.shape(st.session_state.velocity_regrid)[1],
|
350
|
-
)
|
351
|
-
fillplot_plotly(
|
352
|
-
st.session_state.velocity_regrid[0, :, :], title="Regridded Velocity File"
|
353
|
-
)
|
354
|
-
fillplot_plotly(velocity[0, :, :], title="Original File")
|
355
|
-
fillplot_plotly(
|
356
|
-
st.session_state.mask_regrid, colorscale="greys", title="Regridded Mask File"
|
357
|
-
)
|
358
|
-
|
359
|
-
st.session_state.isGrid = True
|
360
|
-
st.session_state.isGridSave = False
|
361
|
-
|
362
|
-
|
363
|
-
########### Save and Reset Mask ##############
|
364
|
-
st.header("Save & Reset Mask Data", divider="blue")
|
365
|
-
|
366
|
-
col1, col2 = st.columns([1, 1])
|
367
|
-
with col1:
|
368
|
-
save_mask_button = st.button(label="Save Mask Data")
|
369
|
-
if save_mask_button:
|
370
|
-
if st.session_state.isGrid:
|
371
|
-
st.session_state.profile_mask = st.session_state.mask_regrid
|
372
|
-
st.session_state.isGridSave = True
|
373
|
-
else:
|
374
|
-
st.session_state.profile_mask = st.session_state.maskp
|
375
|
-
st.session_state.isProfileMask = True
|
376
|
-
st.session_state.isVelocityMask = False
|
377
|
-
st.write(":green[Mask data saved]")
|
378
|
-
else:
|
379
|
-
st.write(":red[Mask data not saved]")
|
380
|
-
with col2:
|
381
|
-
reset_mask_button = st.button("Reset mask data")
|
382
|
-
if reset_mask_button:
|
383
|
-
st.session_state.maskp = np.copy(st.session_state.orig_mask)
|
384
|
-
st.write(":green[Mask data is reset to default]")
|
385
|
-
st.session_state.isQCMask = False
|
386
|
-
st.session_state.isProfileMask = False
|
387
|
-
st.session_state.isGrid = False
|
388
|
-
st.session_state.isGridSave = False
|
389
|
-
st.session_state.isVelocityMask = False
|