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