pyadps 0.2.1b0__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.
@@ -1,334 +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 streamlit.runtime.state import session_state
9
- from utils.signal_quality import ev_check, false_target, pg_check, qc_check
10
-
11
- if "flead" not in st.session_state:
12
- st.write(":red[Please Select Data!]")
13
- st.stop()
14
-
15
- # `mask` holds the temporary changes in the page
16
- # `qcmask` holds the final changes in the page
17
- if "mask" not in st.session_state:
18
- st.session_state.mask = np.copy(st.session_state.orig_mask)
19
-
20
- if not st.session_state.isQCMask:
21
- st.write(":grey[Creating a new mask file ...]")
22
- st.session_state.qc_mask = np.copy(st.session_state.orig_mask)
23
- st.session_state.isSubmit = False
24
- else:
25
- st.write(":grey[Working on a saved mask file ...]")
26
- st.write(":orange[WARNING! QC test already completed. Reset to change settings.]")
27
- reset_button1 = st.button("Reset Mask Data")
28
- if reset_button1:
29
- st.session_state.mask = np.copy(st.session_state.orig_mask)
30
- st.session_state.qc_mask = np.copy(st.session_state.orig_mask)
31
- st.write(":green[Mask data is reset to default]")
32
-
33
- if "isThresh" not in st.session_state:
34
- st.session_state.isThresh = False
35
-
36
- # Load data
37
- flobj = st.session_state.flead
38
- vlobj = st.session_state.vlead
39
- velocity = st.session_state.velocity
40
- echo = st.session_state.echo
41
- correlation = st.session_state.correlation
42
- pgood = st.session_state.pgood
43
- ensembles = st.session_state.head.ensembles
44
- cells = flobj.field()["Cells"]
45
- fdata = flobj.fleader
46
- vdata = vlobj.vleader
47
- x = np.arange(0, ensembles, 1)
48
- y = np.arange(0, cells, 1)
49
-
50
-
51
- @st.cache_data
52
- def fillplot_plotly(data, colorscale="balance"):
53
- fig = FigureResampler(go.Figure())
54
- data1 = np.where(data == -32768, np.nan, data)
55
- fig.add_trace(
56
- go.Heatmap(z=data1[:, 0:-1], x=x, y=y, colorscale=colorscale, hoverongaps=False)
57
- )
58
- st.plotly_chart(fig)
59
-
60
-
61
- @st.cache_data
62
- def plot_noise(dep=0, rec=-1):
63
- n = dep
64
- m = rec
65
- colorleft = [
66
- "rgb(240, 255, 255)",
67
- "rgb(115, 147, 179)",
68
- "rgb(100, 149, 237)",
69
- "rgb(15, 82, 186)",
70
- ]
71
- colorright = [
72
- "rgb(250, 200, 152)",
73
- "rgb(255, 165, 0)",
74
- "rgb(255, 95, 31)",
75
- "rgb(139, 64, 0)",
76
- ]
77
- fig = make_subplots(
78
- rows=1,
79
- cols=2,
80
- subplot_titles=[
81
- f"Deployment Ensemble ({x[n]+1})",
82
- f"Recovery Ensemble ({x[m]+1})",
83
- ],
84
- )
85
- for i in range(4):
86
- fig.add_trace(
87
- go.Scatter(
88
- x=echo[i, :, n],
89
- y=y,
90
- name=f"Beam (D) {i+1}",
91
- line=dict(color=colorleft[i]),
92
- ),
93
- row=1,
94
- col=1,
95
- )
96
- for i in range(4):
97
- fig.add_trace(
98
- go.Scatter(
99
- x=echo[i, :, m],
100
- y=y,
101
- name=f"Beam (R) {i+1}",
102
- line=dict(color=colorright[i]),
103
- ),
104
- row=1,
105
- col=2,
106
- )
107
-
108
- fig.update_layout(height=600, width=800, title_text="Echo Intensity")
109
- fig.update_xaxes(title="Echo (count)")
110
- fig.update_yaxes(title="Cells")
111
- st.plotly_chart(fig)
112
-
113
- ######### NOISE FLOOR IDENTIFICATION ##############
114
- dn = rn = 1
115
- st.header("Noise Floor Identification", divider="blue")
116
- st.write(
117
- """
118
- If the ADCP has collected data from the air either
119
- before deployment or after recovery, this data can
120
- be used to estimate the echo intensity threshold.
121
- The plots below show the echo intensity from the first
122
- and last ensembles. The noise level is typically around
123
- 30-40 counts throughout the entire profile.
124
- """
125
- )
126
- dn = st.number_input("Deployment Ensemble", x[0] + 1, x[-1] + 1, x[0] + 1)
127
- # r = st.number_input("Recovery Ensemble", -1 * (x[-1] + 1), -1 * (x[0] + 1), -1)
128
- rn = st.number_input("Recovery Ensemble", x[0] + 1, x[-1] + 1, x[-1] + 1)
129
- dn = dn - 1
130
- rn = rn - 1
131
-
132
- plot_noise(dep=dn, rec=rn)
133
-
134
-
135
- ################## QC Test ###################
136
-
137
- st.header("Quality Control Tests", divider="blue")
138
- st.write("")
139
-
140
- left, right = st.columns([1, 1])
141
- with left:
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.""")
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:]")
157
- thresh = pd.DataFrame(
158
- [
159
- ["Correlation", fdata["Correlation Thresh"]],
160
- ["Error Velocity", fdata["Error Velocity Thresh"]],
161
- ["Echo Intensity", 0],
162
- ["False Target", fdata["False Target Thresh"]],
163
- ["Percentage Good", fdata["Percent Good Min"]],
164
- ],
165
- columns=["Threshold", "Values"],
166
- )
167
-
168
- st.write(thresh)
169
-
170
- with right:
171
- with st.form(key="my_form"):
172
- st.write("Would you like to apply new threshold?")
173
-
174
- ct = st.number_input(
175
- "Select Correlation Threshold",
176
- 0,
177
- 255,
178
- fdata["Correlation Thresh"],
179
- )
180
-
181
- evt = st.number_input(
182
- "Select Error Velocity Threshold",
183
- 0,
184
- 9999,
185
- fdata["Error Velocity Thresh"],
186
- )
187
-
188
- et = st.number_input(
189
- "Select Echo Intensity Threshold",
190
- 0,
191
- 255,
192
- 0,
193
- )
194
-
195
- ft = st.number_input(
196
- "Select False Target Threshold",
197
- 0,
198
- 255,
199
- fdata["False Target Thresh"],
200
- )
201
-
202
- option = st.selectbox(
203
- "Would you like to use a three-beam solution?", (True, False)
204
- )
205
-
206
- pgt = st.number_input(
207
- "Select Percent Good Threshold",
208
- 0,
209
- 100,
210
- fdata["Percent Good Min"],
211
- )
212
- submit_button = st.form_submit_button(label="Submit")
213
-
214
-
215
- mask = st.session_state.mask
216
- with left:
217
- if submit_button:
218
- st.session_state.newthresh = pd.DataFrame(
219
- [
220
- ["Correlation", str(ct)],
221
- ["Error Velocity", str(evt)],
222
- ["Echo Intensity", str(et)],
223
- ["False Target", str(ft)],
224
- ["Three Beam", str(option)],
225
- ["Percentage Good", str(pgt)],
226
- ],
227
- columns=["Threshold", "Values"],
228
- )
229
- st.session_state.isThresh = True
230
- # st.write(st.session_state.newthresh)
231
-
232
- mask = pg_check(pgood, mask, pgt, threebeam=option)
233
- mask = qc_check(correlation, mask, ct)
234
- mask = qc_check(echo, mask, et)
235
- mask = ev_check(velocity[3, :, :], mask, evt)
236
- mask = false_target(echo, mask, ft, threebeam=True)
237
- st.session_state.mask = mask
238
-
239
- if st.session_state.isThresh:
240
- st.write(":green-background[Current Thresholds]")
241
- st.write(st.session_state.newthresh)
242
-
243
-
244
-
245
- st.header("Mask File", divider="blue")
246
- st.write(
247
- """
248
- Displayed the mask file.
249
- Ensure to save any necessary changes or apply additional thresholds if needed.
250
- """
251
- )
252
-
253
-
254
- if st.button("Display mask file"):
255
- st.subheader("Default Mask File")
256
- st.write(
257
- """
258
- ADCP assigns missing values based on thresholds set before deployment.
259
- These values cannot be recovered and the default
260
- """
261
- )
262
- fillplot_plotly(st.session_state.orig_mask, colorscale="greys")
263
-
264
-
265
- st.subheader("Update Mask File")
266
- st.write(
267
- """
268
- Update, display and save the updated mask file after applying threshold.
269
- If thresholds are not saved, default mask file is used.
270
- """
271
- )
272
- # values, counts = np.unique(mask, return_counts=True)
273
- fillplot_plotly(st.session_state.mask, colorscale="greys")
274
-
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
-
299
-
300
-
301
-
302
- ################## Save Button #############
303
- st.header("Save Data", divider="blue")
304
- col1, col2 = st.columns([1, 1])
305
- with col1:
306
- save_mask_button = st.button(label="Save Mask Data")
307
-
308
- if save_mask_button:
309
- # st.session_state.mask = mask
310
- st.session_state.qc_mask = np.copy(st.session_state.mask)
311
- st.session_state.isQCMask = True
312
- st.session_state.isProfileMask = False
313
- st.session_state.isGridSave = False
314
- st.session_state.isVelocityMask = False
315
- st.write(":green[Mask file saved]")
316
- else:
317
- st.write(":red[Mask data not saved]")
318
- with col2:
319
- reset_mask_button = st.button("Reset mask Data")
320
- if reset_mask_button:
321
- st.session_state.mask = np.copy(st.session_state.orig_mask)
322
- st.session_state.isQCMask = False
323
- st.session_state.isGrid = False
324
- st.session_state.isProfileMask = False
325
- st.session_state.isVelocityMask = False
326
- st.write(":green[Mask data is reset to default]")
327
-
328
-
329
-
330
-
331
-
332
-
333
-
334
-