pyadps 0.3.3b0__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 +42 -0
- pyadps/__init__.py +8 -0
- pyadps/__main__.py +15 -0
- pyadps/pages/01_Read_File.py +458 -0
- pyadps/pages/02_View_Raw_Data.py +164 -0
- pyadps/pages/03_Download_Raw_File.py +298 -0
- pyadps/pages/04_Sensor_Health.py +905 -0
- pyadps/pages/05_QC_Test.py +476 -0
- pyadps/pages/06_Profile_Test.py +970 -0
- pyadps/pages/07_Velocity_Test.py +600 -0
- pyadps/pages/08_Write_File.py +574 -0
- pyadps/pages/09_Auto_process.py +62 -0
- pyadps/pages/__init__.py +0 -0
- pyadps/utils/__init__.py +12 -0
- pyadps/utils/autoprocess.py +530 -0
- pyadps/utils/metadata/config.ini +99 -0
- pyadps/utils/metadata/demo.000 +0 -0
- pyadps/utils/metadata/flmeta.json +422 -0
- pyadps/utils/metadata/vlmeta.json +567 -0
- pyadps/utils/plotgen.py +728 -0
- pyadps/utils/profile_test.py +556 -0
- pyadps/utils/pyreadrdi.py +969 -0
- pyadps/utils/readrdi.py +1610 -0
- pyadps/utils/script.py +201 -0
- pyadps/utils/sensor_health.py +120 -0
- pyadps/utils/signal_quality.py +455 -0
- pyadps/utils/velocity_test.py +200 -0
- pyadps/utils/writenc.py +339 -0
- pyadps-0.3.3b0.dist-info/LICENSE +8 -0
- pyadps-0.3.3b0.dist-info/METADATA +172 -0
- pyadps-0.3.3b0.dist-info/RECORD +33 -0
- pyadps-0.3.3b0.dist-info/WHEEL +4 -0
- pyadps-0.3.3b0.dist-info/entry_points.txt +5 -0
@@ -0,0 +1,574 @@
|
|
1
|
+
import configparser
|
2
|
+
import tempfile
|
3
|
+
|
4
|
+
import numpy as np
|
5
|
+
import pandas as pd
|
6
|
+
import plotly.graph_objects as go
|
7
|
+
import streamlit as st
|
8
|
+
import utils.writenc as wr
|
9
|
+
from plotly_resampler import FigureResampler
|
10
|
+
|
11
|
+
if "flead" not in st.session_state:
|
12
|
+
st.write(":red[Please Select Data!]")
|
13
|
+
st.stop()
|
14
|
+
|
15
|
+
if "fname" not in st.session_state:
|
16
|
+
st.session_state.fname = "No file selected"
|
17
|
+
|
18
|
+
if "rawfilename" not in st.session_state:
|
19
|
+
st.session_state.rawfilename = "rawfile.nc"
|
20
|
+
|
21
|
+
if "vleadfilename" not in st.session_state:
|
22
|
+
st.session_state.vleadfilename = "vlead.nc"
|
23
|
+
|
24
|
+
|
25
|
+
# Check if attributes exist in session state
|
26
|
+
if "attributes" not in st.session_state:
|
27
|
+
st.session_state.attributes = {}
|
28
|
+
st.session_state.isAttributes = False
|
29
|
+
|
30
|
+
if st.session_state.isVelocityTest:
|
31
|
+
st.session_state.final_mask = st.session_state.velocity_mask
|
32
|
+
|
33
|
+
if st.session_state.isVelocityModifiedMagnet:
|
34
|
+
st.session_state.final_velocity = st.session_state.velocity_magnet
|
35
|
+
if st.session_state.isRegridCheck_PT:
|
36
|
+
st.session_state.final_velocity = st.session_state.velocity_regrid
|
37
|
+
elif st.session_state.isVelocityModifiedSound_ST:
|
38
|
+
st.session_state.final_velocity = st.session_state.velocity_sensor
|
39
|
+
else:
|
40
|
+
st.session_state.final_velocity = st.session_state.velocity
|
41
|
+
|
42
|
+
if st.session_state.isRegridCheck_PT:
|
43
|
+
st.session_state.final_echo = st.session_state.echo_regrid
|
44
|
+
st.session_state.final_correlation = st.session_state.correlation_regrid
|
45
|
+
st.session_state.final_pgood = st.session_state.pgood_regrid
|
46
|
+
else:
|
47
|
+
st.session_state.final_echo = st.session_state.echo
|
48
|
+
st.session_state.final_correlation = st.session_state.correlation
|
49
|
+
st.session_state.final_pgood = st.session_state.pgood
|
50
|
+
else:
|
51
|
+
if st.session_state.isRegridCheck_PT:
|
52
|
+
st.session_state.final_mask = st.session_state.profile_mask_regrid
|
53
|
+
st.session_state.final_velocity = st.session_state.velocity_regrid
|
54
|
+
st.session_state.final_echo = st.session_state.echo_regrid
|
55
|
+
st.session_state.final_correlation = st.session_state.correlation_regrid
|
56
|
+
st.session_state.final_pgood = st.session_state.pgood_regrid
|
57
|
+
else:
|
58
|
+
if st.session_state.isProfileTest:
|
59
|
+
st.session_state.final_mask = st.session_state.profile_mask
|
60
|
+
elif st.session_state.isQCTest:
|
61
|
+
st.session_state.final_mask = st.session_state.qc_mask
|
62
|
+
elif st.session_state.isSensorTest:
|
63
|
+
st.session_state.final_mask = st.session_state.sensor_mask
|
64
|
+
else:
|
65
|
+
st.session_state.final_mask = st.session_state.orig_mask
|
66
|
+
st.session_state.final_velocity = st.session_state.velocity
|
67
|
+
st.session_state.final_echo = st.session_state.echo
|
68
|
+
st.session_state.final_correlation = st.session_state.correlation
|
69
|
+
st.session_state.final_pgood = st.session_state.pgood
|
70
|
+
|
71
|
+
|
72
|
+
if "depth_axis" not in st.session_state:
|
73
|
+
st.session_state.isRegridCheck_PT = False
|
74
|
+
|
75
|
+
|
76
|
+
@st.cache_data
|
77
|
+
def file_write(filename="processed_file.nc"):
|
78
|
+
tempdirname = tempfile.TemporaryDirectory(delete=False)
|
79
|
+
outfilepath = tempdirname.name + "/" + filename
|
80
|
+
return outfilepath
|
81
|
+
|
82
|
+
|
83
|
+
# If the data is not regrided based on pressure sensor. Use the mean depth
|
84
|
+
if not st.session_state.isRegridCheck_PT:
|
85
|
+
st.write(":red[WARNING!]")
|
86
|
+
st.write(
|
87
|
+
"Data not regrided. Using the mean transducer depth to calculate the depth axis."
|
88
|
+
)
|
89
|
+
# mean_depth = np.mean(st.session_state.vlead.vleader["Depth of Transducer"]) / 10
|
90
|
+
mean_depth = np.mean(st.session_state.depth) / 10
|
91
|
+
mean_depth = np.trunc(mean_depth)
|
92
|
+
st.write(f"Mean depth of the transducer is `{mean_depth}`")
|
93
|
+
cells = st.session_state.flead.field()["Cells"]
|
94
|
+
cell_size = st.session_state.flead.field()["Depth Cell Len"] / 100
|
95
|
+
bin1dist = st.session_state.flead.field()["Bin 1 Dist"] / 100
|
96
|
+
if st.session_state.beam_direction_QCT.lower() == "up":
|
97
|
+
sgn = -1
|
98
|
+
else:
|
99
|
+
sgn = 1
|
100
|
+
first_depth = mean_depth + sgn * bin1dist
|
101
|
+
last_depth = first_depth + sgn * cells * cell_size
|
102
|
+
z = np.arange(first_depth, last_depth, sgn * cell_size)
|
103
|
+
st.session_state.final_depth_axis = z
|
104
|
+
else:
|
105
|
+
st.session_state.final_depth_axis = st.session_state.depth_axis
|
106
|
+
|
107
|
+
|
108
|
+
# Functions for plotting
|
109
|
+
@st.cache_data
|
110
|
+
def fillplot_plotly(
|
111
|
+
x, y, data, maskdata, colorscale="balance", title="Data", mask=False
|
112
|
+
):
|
113
|
+
fig = FigureResampler(go.Figure())
|
114
|
+
if mask:
|
115
|
+
data1 = np.where(maskdata == 1, np.nan, data)
|
116
|
+
else:
|
117
|
+
data1 = np.where(data == -32768, np.nan, data)
|
118
|
+
|
119
|
+
fig.add_trace(
|
120
|
+
go.Heatmap(
|
121
|
+
z=data1[:, 0:-1],
|
122
|
+
x=x,
|
123
|
+
y=y,
|
124
|
+
colorscale=colorscale,
|
125
|
+
hoverongaps=False,
|
126
|
+
)
|
127
|
+
)
|
128
|
+
fig.update_layout(
|
129
|
+
xaxis=dict(showline=True, mirror=True),
|
130
|
+
yaxis=dict(showline=True, mirror=True),
|
131
|
+
title_text=title,
|
132
|
+
)
|
133
|
+
fig.update_yaxes(autorange="reversed")
|
134
|
+
st.plotly_chart(fig)
|
135
|
+
|
136
|
+
|
137
|
+
def call_plot(varname, beam, mask=False):
|
138
|
+
if varname == "Velocity":
|
139
|
+
fillplot_plotly(
|
140
|
+
st.session_state.date,
|
141
|
+
st.session_state.final_depth_axis,
|
142
|
+
st.session_state.final_velocity[beam - 1, :, :],
|
143
|
+
st.session_state.final_mask,
|
144
|
+
title=varname,
|
145
|
+
mask=mask,
|
146
|
+
)
|
147
|
+
elif varname == "Echo":
|
148
|
+
fillplot_plotly(
|
149
|
+
st.session_state.date,
|
150
|
+
st.session_state.final_depth_axis,
|
151
|
+
st.session_state.final_echo[beam - 1, :, :],
|
152
|
+
st.session_state.final_mask,
|
153
|
+
title=varname,
|
154
|
+
mask=mask,
|
155
|
+
)
|
156
|
+
elif varname == "Correlation":
|
157
|
+
fillplot_plotly(
|
158
|
+
st.session_state.date,
|
159
|
+
st.session_state.final_depth_axis,
|
160
|
+
st.session_state.final_correlation[beam - 1, :, :],
|
161
|
+
st.session_state.final_mask,
|
162
|
+
title=varname,
|
163
|
+
mask=mask,
|
164
|
+
)
|
165
|
+
elif varname == "Percent Good":
|
166
|
+
fillplot_plotly(
|
167
|
+
st.session_state.date,
|
168
|
+
st.session_state.final_depth_axis,
|
169
|
+
st.session_state.final_pgood[beam - 1, :, :],
|
170
|
+
st.session_state.final_mask,
|
171
|
+
title=varname,
|
172
|
+
mask=mask,
|
173
|
+
)
|
174
|
+
|
175
|
+
|
176
|
+
# Option to View Processed Data
|
177
|
+
st.header("View Processed Data", divider="blue")
|
178
|
+
var_option = st.selectbox(
|
179
|
+
"Select a data type", ("Velocity", "Echo", "Correlation", "Percent Good")
|
180
|
+
)
|
181
|
+
beam = st.radio("Select beam", (1, 2, 3, 4), horizontal=True)
|
182
|
+
|
183
|
+
mask_radio = st.radio("Apply Mask", ("Yes", "No"), horizontal=True)
|
184
|
+
plot_button = st.button("Plot Processed Data")
|
185
|
+
if plot_button:
|
186
|
+
if mask_radio == "Yes":
|
187
|
+
call_plot(var_option, beam, mask=True)
|
188
|
+
elif mask_radio == "No":
|
189
|
+
call_plot(var_option, beam, mask=False)
|
190
|
+
|
191
|
+
|
192
|
+
# Option to Write Processed Data
|
193
|
+
st.header("Write Data", divider="blue")
|
194
|
+
|
195
|
+
st.session_state.mask_data_WF = st.radio(
|
196
|
+
"Do you want to mask the final data?", ("Yes", "No")
|
197
|
+
)
|
198
|
+
|
199
|
+
if st.session_state.mask_data_WF == "Yes":
|
200
|
+
mask = st.session_state.final_mask
|
201
|
+
st.session_state.write_velocity = np.copy(st.session_state.final_velocity)
|
202
|
+
st.session_state.write_velocity[:, mask == 1] = -32768
|
203
|
+
else:
|
204
|
+
st.session_state.write_velocity = np.copy(st.session_state.final_velocity)
|
205
|
+
|
206
|
+
|
207
|
+
st.session_state.file_type_WF = st.radio(
|
208
|
+
"Select output file format:", ("NetCDF", "CSV")
|
209
|
+
)
|
210
|
+
|
211
|
+
if st.session_state.file_type_WF == "NetCDF":
|
212
|
+
add_attr_button = st.checkbox("Add attributes to NetCDF file")
|
213
|
+
|
214
|
+
if add_attr_button:
|
215
|
+
st.session_state.isAttributes = True
|
216
|
+
st.write("### Modify Attributes")
|
217
|
+
|
218
|
+
# Create two-column layout for attributes
|
219
|
+
col1, col2 = st.columns(2)
|
220
|
+
|
221
|
+
with col1:
|
222
|
+
# Display attributes in the first column
|
223
|
+
for key in [
|
224
|
+
"Cruise_No.",
|
225
|
+
"Ship_Name",
|
226
|
+
"Project_No.",
|
227
|
+
"Water_Depth_m",
|
228
|
+
"Deployment_Depth_m",
|
229
|
+
"Deployment_Date",
|
230
|
+
"Recovery_Date",
|
231
|
+
]:
|
232
|
+
if key in st.session_state.attributes:
|
233
|
+
st.session_state.attributes[key] = st.text_input(
|
234
|
+
key, value=st.session_state.attributes[key]
|
235
|
+
)
|
236
|
+
else:
|
237
|
+
st.session_state.attributes[key] = st.text_input(key)
|
238
|
+
|
239
|
+
with col2:
|
240
|
+
# Display attributes in the second column
|
241
|
+
for key in [
|
242
|
+
"Latitude",
|
243
|
+
"Longitude",
|
244
|
+
"Platform_Type",
|
245
|
+
"Participants",
|
246
|
+
"File_created_by",
|
247
|
+
"Contact",
|
248
|
+
"Comments",
|
249
|
+
]:
|
250
|
+
if key in st.session_state.attributes:
|
251
|
+
st.session_state.attributes[key] = st.text_input(
|
252
|
+
key, value=st.session_state.attributes[key]
|
253
|
+
)
|
254
|
+
else:
|
255
|
+
st.session_state.attributes[key] = st.text_input(key)
|
256
|
+
|
257
|
+
download_button = st.button("Generate Processed files")
|
258
|
+
|
259
|
+
if download_button:
|
260
|
+
st.session_state.processed_filename = file_write()
|
261
|
+
st.write(":grey[Processed file created. Click the download button.]")
|
262
|
+
# st.write(st.session_state.processed_filename)
|
263
|
+
depth_axis = np.trunc(st.session_state.final_depth_axis)
|
264
|
+
final_mask = st.session_state.final_mask
|
265
|
+
|
266
|
+
if st.session_state.file_type_WF == "NetCDF":
|
267
|
+
if add_attr_button and st.session_state.attributes:
|
268
|
+
# Generate file with attributes
|
269
|
+
wr.finalnc(
|
270
|
+
st.session_state.processed_filename,
|
271
|
+
depth_axis,
|
272
|
+
final_mask,
|
273
|
+
st.session_state.date,
|
274
|
+
st.session_state.write_velocity,
|
275
|
+
attributes=st.session_state.attributes, # Pass edited attributes
|
276
|
+
)
|
277
|
+
else:
|
278
|
+
# Generate file without attributes
|
279
|
+
wr.finalnc(
|
280
|
+
st.session_state.processed_filename,
|
281
|
+
depth_axis,
|
282
|
+
final_mask,
|
283
|
+
st.session_state.date,
|
284
|
+
st.session_state.write_velocity,
|
285
|
+
)
|
286
|
+
|
287
|
+
with open(st.session_state.processed_filename, "rb") as file:
|
288
|
+
st.download_button(
|
289
|
+
label="Download NetCDF File",
|
290
|
+
data=file,
|
291
|
+
file_name="processed_file.nc",
|
292
|
+
)
|
293
|
+
|
294
|
+
if st.session_state.file_type_WF == "CSV":
|
295
|
+
udf = pd.DataFrame(
|
296
|
+
st.session_state.write_velocity[0, :, :].T,
|
297
|
+
index=st.session_state.date,
|
298
|
+
columns=-1 * depth_axis,
|
299
|
+
)
|
300
|
+
vdf = pd.DataFrame(
|
301
|
+
st.session_state.write_velocity[1, :, :].T,
|
302
|
+
index=st.session_state.date,
|
303
|
+
columns=-1 * depth_axis,
|
304
|
+
)
|
305
|
+
wdf = pd.DataFrame(
|
306
|
+
st.session_state.write_velocity[2, :, :].T,
|
307
|
+
index=st.session_state.date,
|
308
|
+
columns=-1 * depth_axis,
|
309
|
+
)
|
310
|
+
ucsv = udf.to_csv().encode("utf-8")
|
311
|
+
vcsv = vdf.to_csv().encode("utf-8")
|
312
|
+
wcsv = wdf.to_csv().encode("utf-8")
|
313
|
+
csv_mask = pd.DataFrame(st.session_state.final_mask.T).to_csv().encode("utf-8")
|
314
|
+
st.download_button(
|
315
|
+
label="Download Zonal Velocity File (CSV)",
|
316
|
+
data=ucsv,
|
317
|
+
file_name="zonal_velocity.csv",
|
318
|
+
mime="text/csf",
|
319
|
+
)
|
320
|
+
st.download_button(
|
321
|
+
label="Download Meridional Velocity File (CSV)",
|
322
|
+
data=vcsv,
|
323
|
+
file_name="meridional_velocity.csv",
|
324
|
+
mime="text/csf",
|
325
|
+
)
|
326
|
+
st.download_button(
|
327
|
+
label="Download Vertical Velocity File (CSV)",
|
328
|
+
data=vcsv,
|
329
|
+
file_name="vertical_velocity.csv",
|
330
|
+
mime="text/csf",
|
331
|
+
)
|
332
|
+
|
333
|
+
st.download_button(
|
334
|
+
label="Download Final Mask (CSV)",
|
335
|
+
data=csv_mask,
|
336
|
+
file_name="final_mask.csv",
|
337
|
+
mime="text/csv",
|
338
|
+
)
|
339
|
+
|
340
|
+
|
341
|
+
# Option to Download Config file
|
342
|
+
# ------------------------------
|
343
|
+
|
344
|
+
# Header for the Config.ini File Generator
|
345
|
+
st.header("Config.ini File Generator", divider="blue")
|
346
|
+
|
347
|
+
# Radio button to decide whether to generate the config.ini file
|
348
|
+
generate_config_radio = st.radio(
|
349
|
+
"Do you want to generate a config.ini file?", ("No", "Yes")
|
350
|
+
)
|
351
|
+
|
352
|
+
|
353
|
+
if generate_config_radio == "Yes":
|
354
|
+
# Create a config parser object
|
355
|
+
config = configparser.ConfigParser()
|
356
|
+
|
357
|
+
# Main section
|
358
|
+
config["FileSettings"] = {}
|
359
|
+
config["DownloadOptions"] = {}
|
360
|
+
config["SensorTest"] = {"sensor_test": "False"}
|
361
|
+
config["QCTest"] = {"qc_test": "False"}
|
362
|
+
config["ProfileTest"] = {"profile_test": "False"}
|
363
|
+
config["VelocityTest"] = {"velocity_test": "False"}
|
364
|
+
config["Attributes"] = {}
|
365
|
+
|
366
|
+
# ------------------
|
367
|
+
# File Settings
|
368
|
+
# ------------------
|
369
|
+
config["FileSettings"]["input_file_path"] = ""
|
370
|
+
config["FileSettings"]["input_file_name"] = st.session_state.fname
|
371
|
+
config["FileSettings"]["output_file_path"] = ""
|
372
|
+
config["FileSettings"]["output_file_name_raw_netcdf"] = ""
|
373
|
+
config["FileSettings"]["output_file_name_vlead_netcdf"] = ""
|
374
|
+
config["FileSettings"]["output_file_name_raw_csv"] = ""
|
375
|
+
config["FileSettings"]["output_file_name_processed_netcdf"] = ""
|
376
|
+
config["FileSettings"]["output_file_name_processed_csv"] = ""
|
377
|
+
|
378
|
+
if st.session_state.file_type_WF.lower() == "netcdf":
|
379
|
+
st.session_state.isProcessedNetcdfDownload_WF = True
|
380
|
+
else:
|
381
|
+
st.session_state.isProcessedNetcdfDownload_WF = False
|
382
|
+
st.session_state.isProcessedCSVDownload_WF = True
|
383
|
+
# ------------------
|
384
|
+
# Download options
|
385
|
+
# ------------------
|
386
|
+
config["DownloadOptions"]["download_raw_netcdf"] = str(
|
387
|
+
st.session_state.rawnc_download_DRW
|
388
|
+
)
|
389
|
+
config["DownloadOptions"]["download_vlead_netcdf"] = str(
|
390
|
+
st.session_state.vleadnc_download_DRW
|
391
|
+
)
|
392
|
+
config["DownloadOptions"]["download_processed_netcdf"] = str(
|
393
|
+
st.session_state.isProcessedNetcdfDownload_WF
|
394
|
+
)
|
395
|
+
config["DownloadOptions"]["download_raw_csv"] = str(
|
396
|
+
st.session_state.rawcsv_download_DRW
|
397
|
+
)
|
398
|
+
config["DownloadOptions"]["download_processed_csv"] = str(
|
399
|
+
st.session_state.isProcessedCSVDownload_WF
|
400
|
+
)
|
401
|
+
config["DownloadOptions"]["add_attributes_raw"] = str(
|
402
|
+
st.session_state.add_attributes_DRW
|
403
|
+
)
|
404
|
+
config["DownloadOptions"]["add_attributes_processed"] = str(
|
405
|
+
st.session_state.isAttributes
|
406
|
+
)
|
407
|
+
config["DownloadOptions"]["axis_option"] = str(st.session_state.axis_option_DRW)
|
408
|
+
config["DownloadOptions"]["apply_mask"] = "True"
|
409
|
+
config["DownloadOptions"]["download_mask"] = "True"
|
410
|
+
|
411
|
+
# ------------------
|
412
|
+
# PAGE: Sensor Test
|
413
|
+
# ------------------
|
414
|
+
config["SensorTest"]["sensor_test"] = str(st.session_state.isSensorTest)
|
415
|
+
# Tab 1: Depth Sensor
|
416
|
+
config["SensorTest"]["is_depth_modified"] = str(st.session_state.isDepthModified_ST)
|
417
|
+
config["SensorTest"]["depth_input_option"] = str(st.session_state.depthoption_ST)
|
418
|
+
config["SensorTest"]["is_fixed_depth"] = str(st.session_state.isFixedDepth_ST)
|
419
|
+
config["SensorTest"]["fixed_depth"] = str(st.session_state.fixeddepth_ST)
|
420
|
+
config["SensorTest"]["is_upload_depth"] = str(st.session_state.isUploadDepth_ST)
|
421
|
+
config["SensorTest"]["depth_file_path"] = ""
|
422
|
+
|
423
|
+
# Tab 2: Salinity sensor
|
424
|
+
config["SensorTest"]["is_salinity_modified"] = str(
|
425
|
+
st.session_state.isSalinityModified_ST
|
426
|
+
)
|
427
|
+
config["SensorTest"]["salinity_input_option"] = str(
|
428
|
+
st.session_state.salinityoption_ST
|
429
|
+
)
|
430
|
+
config["SensorTest"]["is_fixed_salinity"] = str(st.session_state.isFixedSalinity_ST)
|
431
|
+
config["SensorTest"]["fixed_salinity"] = str(st.session_state.fixedsalinity_ST)
|
432
|
+
config["SensorTest"]["is_upload_salinity"] = str(
|
433
|
+
st.session_state.isUploadSalinity_ST
|
434
|
+
)
|
435
|
+
config["SensorTest"]["salinity_file_path"] = ""
|
436
|
+
|
437
|
+
# Tab 3: Temperature sensor
|
438
|
+
config["SensorTest"]["is_temperature_modified"] = str(
|
439
|
+
st.session_state.isTemperatureModified_ST
|
440
|
+
)
|
441
|
+
config["SensorTest"]["temperature_input_option"] = str(
|
442
|
+
st.session_state.temperatureoption_ST
|
443
|
+
)
|
444
|
+
config["SensorTest"]["is_fixed_temperature"] = str(
|
445
|
+
st.session_state.isFixedTemperature_ST
|
446
|
+
)
|
447
|
+
config["SensorTest"]["fixed_temperature"] = str(
|
448
|
+
st.session_state.fixedtemperature_ST
|
449
|
+
)
|
450
|
+
config["SensorTest"]["is_upload_temperature"] = str(
|
451
|
+
st.session_state.isUploadTemperature_ST
|
452
|
+
)
|
453
|
+
config["SensorTest"]["temperature_file_path"] = ""
|
454
|
+
|
455
|
+
# Tab 7:
|
456
|
+
|
457
|
+
config["SensorTest"]["roll_check"] = str(st.session_state.isRollCheck_ST)
|
458
|
+
config["SensorTest"]["roll_cutoff"] = str(st.session_state.roll_cutoff_ST)
|
459
|
+
config["SensorTest"]["pitch_check"] = str(st.session_state.isPitchCheck_ST)
|
460
|
+
config["SensorTest"]["pitch_cutoff"] = str(st.session_state.pitch_cutoff_ST)
|
461
|
+
|
462
|
+
config["SensorTest"]["velocity_modified"] = str(
|
463
|
+
st.session_state.isVelocityModifiedSound_ST
|
464
|
+
)
|
465
|
+
|
466
|
+
# ------------------
|
467
|
+
# PAGE: QC Test
|
468
|
+
# ------------------
|
469
|
+
# Tab 2
|
470
|
+
config["QCTest"]["qc_test"] = str(st.session_state.isQCTest)
|
471
|
+
config["QCTest"]["qc_check"] = str(st.session_state.isQCCheck_QCT)
|
472
|
+
config["QCTest"]["correlation"] = str(st.session_state.ct_QCT)
|
473
|
+
config["QCTest"]["echo_intensity"] = str(st.session_state.et_QCT)
|
474
|
+
config["QCTest"]["error_velocity"] = str(st.session_state.evt_QCT)
|
475
|
+
config["QCTest"]["false_target"] = str(st.session_state.ft_QCT)
|
476
|
+
config["QCTest"]["three_beam"] = str(st.session_state.is3beam_QCT)
|
477
|
+
config["QCTest"]["percent_good"] = str(st.session_state.pgt_QCT)
|
478
|
+
|
479
|
+
# Tab 4
|
480
|
+
config["QCTest"]["beam_modified"] = str(st.session_state.isBeamModified_QCT)
|
481
|
+
config["QCTest"]["orientation"] = str(st.session_state.beam_direction_QCT)
|
482
|
+
|
483
|
+
# ------------------
|
484
|
+
# PAGE: Profile Test
|
485
|
+
# ------------------
|
486
|
+
# Tab 1
|
487
|
+
config["ProfileTest"]["profile_test"] = str(st.session_state.isProfileTest)
|
488
|
+
config["ProfileTest"]["trim_ends_check"] = str(st.session_state.isTrimEndsCheck_PT)
|
489
|
+
config["ProfileTest"]["trim_start_ensemble"] = str(st.session_state.start_ens_PT)
|
490
|
+
config["ProfileTest"]["trim_end_ensemble"] = str(st.session_state.end_ens_PT)
|
491
|
+
|
492
|
+
# Tab 2
|
493
|
+
config["ProfileTest"]["cutbins_sidelobe_check"] = str(
|
494
|
+
st.session_state.isCutBinSideLobeCheck_PT
|
495
|
+
)
|
496
|
+
config["ProfileTest"]["extra_cells"] = str(st.session_state.extra_cells_PT)
|
497
|
+
config["ProfileTest"]["water_depth"] = str(st.session_state.water_depth_PT)
|
498
|
+
|
499
|
+
# Tab 3
|
500
|
+
# config["ProfileTest"]["manual_cutbins"] = str(
|
501
|
+
# st.session_state.isCutBinManualCheck_PT
|
502
|
+
# )
|
503
|
+
|
504
|
+
# Tab 4
|
505
|
+
config["ProfileTest"]["regrid"] = str(st.session_state.isRegridCheck_PT)
|
506
|
+
config["ProfileTest"]["end_cell_option"] = str(st.session_state.end_cell_option_PT)
|
507
|
+
config["ProfileTest"]["interpolate"] = str(st.session_state.interpolate_PT)
|
508
|
+
config["ProfileTest"]["boundary"] = str(st.session_state.manualdepth_PT)
|
509
|
+
|
510
|
+
# ------------------
|
511
|
+
# PAGE: Velocity Test
|
512
|
+
# ------------------
|
513
|
+
|
514
|
+
config["VelocityTest"]["velocity_test"] = str(st.session_state.isVelocityTest)
|
515
|
+
|
516
|
+
# Tab 1
|
517
|
+
config["VelocityTest"]["magnetic_declination"] = str(
|
518
|
+
st.session_state.isMagnetCheck_VT
|
519
|
+
)
|
520
|
+
config["VelocityTest"]["magnet_method"] = str(st.session_state.magnet_method_VT)
|
521
|
+
config["VelocityTest"]["magnet_latitude"] = str(st.session_state.magnet_lat_VT)
|
522
|
+
config["VelocityTest"]["magnet_longitude"] = str(st.session_state.magnet_lon_VT)
|
523
|
+
config["VelocityTest"]["magnet_depth"] = str(st.session_state.magnet_depth_VT)
|
524
|
+
config["VelocityTest"]["magnet_year"] = str(st.session_state.magnet_year_VT)
|
525
|
+
config["VelocityTest"]["magnet_user_input"] = str(
|
526
|
+
st.session_state.magnet_user_input_VT
|
527
|
+
)
|
528
|
+
|
529
|
+
# Tab 2
|
530
|
+
config["VelocityTest"]["cutoff"] = str(st.session_state.isCutoffCheck_VT)
|
531
|
+
config["VelocityTest"]["max_zonal_velocity"] = str(st.session_state.maxuvel_VT)
|
532
|
+
config["VelocityTest"]["max_meridional_velocity"] = str(st.session_state.maxvvel_VT)
|
533
|
+
config["VelocityTest"]["max_vertical_velocity"] = str(st.session_state.maxwvel_VT)
|
534
|
+
|
535
|
+
# Tab 3
|
536
|
+
config["VelocityTest"]["despike"] = str(st.session_state.isDespikeCheck_VT)
|
537
|
+
config["VelocityTest"]["despike_kernal_size"] = str(
|
538
|
+
st.session_state.despike_kernal_VT
|
539
|
+
)
|
540
|
+
config["VelocityTest"]["despike_cutoff"] = str(st.session_state.despike_cutoff_VT)
|
541
|
+
|
542
|
+
# Tab 4
|
543
|
+
config["VelocityTest"]["flatline"] = str(st.session_state.isFlatlineCheck_VT)
|
544
|
+
config["VelocityTest"]["flatline_kernal_size"] = str(
|
545
|
+
st.session_state.flatline_kernal_VT
|
546
|
+
)
|
547
|
+
config["VelocityTest"]["flatline_cutoff"] = str(st.session_state.flatline_cutoff_VT)
|
548
|
+
|
549
|
+
# Optional section (attributes)
|
550
|
+
|
551
|
+
for key, value in st.session_state.attributes.items():
|
552
|
+
config["Attributes"][key] = str(value) # Ensure all values are strings
|
553
|
+
|
554
|
+
# Write config.ini to a temporary file
|
555
|
+
# config_filepath = "config.ini"
|
556
|
+
# with open(config_filepath, "w") as configfile:
|
557
|
+
# config.write(configfile)
|
558
|
+
# Create a temporary file for the config.ini
|
559
|
+
with tempfile.NamedTemporaryFile("w+", delete=False, suffix=".ini") as temp_config:
|
560
|
+
config.write(temp_config)
|
561
|
+
temp_config_path = temp_config.name
|
562
|
+
# Allow the user to download the generated config.ini file
|
563
|
+
with open(temp_config_path, "rb") as file:
|
564
|
+
st.download_button(
|
565
|
+
label="Download config.ini File",
|
566
|
+
data=file,
|
567
|
+
file_name="config.ini",
|
568
|
+
)
|
569
|
+
|
570
|
+
display_config_radio = st.radio(
|
571
|
+
"Do you want to display config.ini file?", ("No", "Yes")
|
572
|
+
)
|
573
|
+
if display_config_radio == "Yes":
|
574
|
+
st.write({section: dict(config[section]) for section in config.sections()})
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import os
|
2
|
+
import tempfile
|
3
|
+
|
4
|
+
import configparser
|
5
|
+
import json
|
6
|
+
import streamlit as st
|
7
|
+
from utils.autoprocess import autoprocess
|
8
|
+
|
9
|
+
|
10
|
+
@st.cache_data
|
11
|
+
def file_access(uploaded_file):
|
12
|
+
"""
|
13
|
+
Function creates temporary directory to store the uploaded file.
|
14
|
+
The path of the file is returned
|
15
|
+
|
16
|
+
Args:
|
17
|
+
uploaded_file (string): Name of the uploaded file
|
18
|
+
|
19
|
+
Returns:
|
20
|
+
path (string): Path of the uploaded file
|
21
|
+
"""
|
22
|
+
temp_dir = tempfile.mkdtemp()
|
23
|
+
path = os.path.join(temp_dir, uploaded_file.name)
|
24
|
+
with open(path, "wb") as f:
|
25
|
+
f.write(uploaded_file.getvalue())
|
26
|
+
return path
|
27
|
+
|
28
|
+
|
29
|
+
def display_config_as_json(config_file):
|
30
|
+
config = configparser.ConfigParser()
|
31
|
+
config.read_string(config_file.getvalue().decode("utf-8"))
|
32
|
+
st.json({section: dict(config[section]) for section in config.sections()})
|
33
|
+
|
34
|
+
|
35
|
+
def main():
|
36
|
+
st.title("ADCP Data Auto Processing Tool")
|
37
|
+
st.write("Upload a binary input file and config.ini file for processing.")
|
38
|
+
|
39
|
+
# File Upload Section
|
40
|
+
uploaded_binary_file = st.file_uploader(
|
41
|
+
"Upload ADCP Binary File", type=["000", "bin"]
|
42
|
+
)
|
43
|
+
uploaded_config_file = st.file_uploader(
|
44
|
+
"Upload Config File (config.ini)", type=["ini"]
|
45
|
+
)
|
46
|
+
|
47
|
+
if uploaded_binary_file and uploaded_config_file:
|
48
|
+
st.success("Files uploaded successfully!")
|
49
|
+
|
50
|
+
# Display config.ini file content as JSON
|
51
|
+
display_config_as_json(uploaded_config_file)
|
52
|
+
|
53
|
+
fpath = file_access(uploaded_binary_file)
|
54
|
+
# Process files
|
55
|
+
with st.spinner("Processing files. Please wait..."):
|
56
|
+
autoprocess(uploaded_config_file, binary_file_path=fpath)
|
57
|
+
st.success("Processing completed successfully!")
|
58
|
+
st.write("Processed file written.")
|
59
|
+
|
60
|
+
|
61
|
+
if __name__ == "__main__":
|
62
|
+
main()
|
pyadps/pages/__init__.py
ADDED
File without changes
|
pyadps/utils/__init__.py
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# pyadps/utils/__init__.py
|
2
|
+
|
3
|
+
from pyadps.utils.plotgen import *
|
4
|
+
from pyadps.utils.profile_test import *
|
5
|
+
from pyadps.utils.pyreadrdi import *
|
6
|
+
from pyadps.utils.readrdi import *
|
7
|
+
from pyadps.utils.sensor_health import *
|
8
|
+
from pyadps.utils.signal_quality import *
|
9
|
+
from pyadps.utils.velocity_test import *
|
10
|
+
from pyadps.utils.writenc import *
|
11
|
+
from pyadps.utils.autoprocess import *
|
12
|
+
from pyadps.utils.script import *
|