pyadps 0.1.0__py3-none-any.whl → 0.1.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.
@@ -25,10 +25,9 @@ if "vleadfilename" not in st.session_state:
25
25
 
26
26
  if "attributes" not in st.session_state:
27
27
  st.session_state.attributes = {}
28
-
29
- if "add_attributes_DRW" not in st.session_state:
30
- st.session_state.add_attributes_DRW = "No" # Default value
31
-
28
+
29
+ if "add_attributes" not in st.session_state:
30
+ st.session_state.add_attributes = "No" # Default value
32
31
 
33
32
  ################ Functions #######################
34
33
  @st.cache_data()
@@ -39,7 +38,6 @@ def file_access(uploaded_file):
39
38
  f.write(uploaded_file.getvalue())
40
39
  return path
41
40
 
42
-
43
41
  @st.cache_data
44
42
  def read_file(filepath):
45
43
  ds = rd.ReadFile(st.session_state.fpath)
@@ -47,110 +45,65 @@ def read_file(filepath):
47
45
  ds.fixensemble()
48
46
  st.session_state.ds = ds
49
47
 
50
-
51
48
  @st.cache_data
52
- def file_write(path, axis_option, add_attributes=True):
49
+ def file_write(path, add_attributes=True):
53
50
  tempdirname = tempfile.TemporaryDirectory(delete=False)
54
51
  st.session_state.rawfilename = tempdirname.name + "/rawfile.nc"
55
-
52
+
56
53
  if add_attributes:
57
- wr.rawnc(
58
- path,
59
- st.session_state.rawfilename,
60
- st.session_state.date1,
61
- axis_option,
62
- attributes=st.session_state.attributes,
63
- )
54
+ wr.main(path, st.session_state.rawfilename, attributes=st.session_state.attributes)
64
55
  else:
65
- wr.rawnc(
66
- path, st.session_state.rawfilename, st.session_state.date1, axis_option
67
- )
68
-
56
+ wr.main(path, st.session_state.rawfilename)
69
57
 
70
58
  @st.cache_data
71
- def file_write_vlead(path, axis_option, add_attributes=True):
59
+ def file_write_vlead(path, add_attributes=True):
72
60
  tempvardirname = tempfile.TemporaryDirectory(delete=False)
73
61
  st.session_state.vleadfilename = tempvardirname.name + "/vlead.nc"
74
-
62
+
75
63
  if add_attributes:
76
- wr.vlead_nc(
77
- path,
78
- st.session_state.vleadfilename,
79
- st.session_state.date2,
80
- axis_option,
81
- attributes=st.session_state.attributes,
82
- )
64
+ wr.vlead_nc(path, st.session_state.vleadfilename, attributes=st.session_state.attributes)
83
65
  else:
84
- wr.vlead_nc(
85
- path, st.session_state.vleadfilename, st.session_state.date2, axis_option
86
- )
87
-
88
-
89
- if "axis_option" not in st.session_state:
90
- st.session_state.axis_option = "ensemble" # Default value
66
+ wr.vlead_nc(path, st.session_state.vleadfilename)
91
67
 
92
68
  # UI for attribute selection
93
69
  st.header("NetCDF File", divider="blue")
94
70
 
95
71
  # Option to add attributes
96
- st.session_state.add_attributes_DRW = st.radio(
97
- "Do you want to add attributes to the NetCDF file?", ["No", "Yes"], horizontal=True
98
- )
72
+ add_attributes = st.radio("Do you want to add attributes to the NetCDF file?", ["No", "Yes"], horizontal=True)
99
73
 
100
- if st.session_state.add_attributes_DRW == "Yes":
74
+ if add_attributes == "Yes":
101
75
  st.write("### Please fill in the attributes:")
102
-
76
+
103
77
  # Two-column layout
104
78
  col1, col2 = st.columns(2)
105
-
79
+
106
80
  with col1:
107
- st.session_state.attributes["Cruise_No."] = st.text_input("Cruise No.")
108
- st.session_state.attributes["Ship_Name"] = st.text_input("Ship Name")
109
- st.session_state.attributes["Project_No."] = st.text_input("Project No.")
110
- st.session_state.attributes["Water_Depth_m"] = st.text_input("Water Depth (m)")
111
- st.session_state.attributes["Deployment_Depth_m"] = st.text_input(
112
- "Deployment Depth (m)"
113
- )
114
- st.session_state.attributes["Deployment_Date"] = st.date_input(
115
- "Deployment Date"
116
- )
117
- st.session_state.attributes["Recovery_Date"] = st.date_input("Recovery Date")
81
+ st.session_state.attributes['Cruise_No.'] = st.text_input("Cruise No.")
82
+ st.session_state.attributes['Ship_Name'] = st.text_input("Ship Name")
83
+ st.session_state.attributes['Project_No.'] = st.text_input("Project No.")
84
+ st.session_state.attributes['Water_Depth_m'] = st.text_input("Water Depth (m)")
85
+ st.session_state.attributes['Deployment_Depth_m'] = st.text_input("Deployment Depth (m)")
86
+ st.session_state.attributes['Deployment_Date'] = st.date_input("Deployment Date")
87
+ st.session_state.attributes['Recovery_Date'] = st.date_input("Recovery Date")
88
+
118
89
 
119
90
  with col2:
120
- st.session_state.attributes["Latitude"] = st.text_input("Latitude")
121
- st.session_state.attributes["Longitude"] = st.text_input("Longitude")
122
- st.session_state.attributes["Platform_Type"] = st.text_input("Platform Type")
123
- st.session_state.attributes["Participants"] = st.text_area("Participants")
124
- st.session_state.attributes["File_created_by"] = st.text_input(
125
- "File created by"
126
- )
127
- st.session_state.attributes["Contact"] = st.text_input("Contact")
128
- st.session_state.attributes["Comments"] = st.text_area("Comments")
91
+ st.session_state.attributes['Latitude'] = st.text_input("Latitude")
92
+ st.session_state.attributes['Longitude'] = st.text_input("Longitude")
93
+ st.session_state.attributes['Platform_Type'] = st.text_input("Platform Type")
94
+ st.session_state.attributes['Participants'] = st.text_area("Participants")
95
+ st.session_state.attributes['File_created_by'] = st.text_input("File created by")
96
+ st.session_state.attributes['Contact'] = st.text_input("Contact")
97
+ st.session_state.attributes['Comments'] = st.text_area("Comments")
129
98
 
130
99
  st.write("Attributes will be added to the NetCDF file once you submit.")
131
-
132
- # Dropdown for axis_option
133
- st.session_state.axis_option_DRW = st.selectbox(
134
- "Select x-axis option:",
135
- options=["time", "ensemble"],
136
- index=0, # Default to "time"
137
- )
138
-
139
- # Ensure it is passed correctly
140
- # st.session_state.axis_option = axis_option
141
-
100
+
142
101
  # Buttons to generate files
143
- st.session_state.rawnc_download_DRW = st.button("Generate Raw NetCDF File")
144
- st.session_state.vleadnc_download_DRW = st.button(
145
- "Generate Raw Variable Leader NetCDF File"
146
- )
102
+ download_button = st.button("Generate Raw NetCDF File")
103
+ download_var_button = st.button("Generate Raw Variable Leader NetCDF File")
147
104
 
148
- if st.session_state.rawnc_download_DRW:
149
- file_write(
150
- st.session_state.fpath,
151
- st.session_state.axis_option_DRW,
152
- st.session_state.add_attributes_DRW == "Yes",
153
- )
105
+ if download_button:
106
+ file_write(st.session_state.fpath, add_attributes == "Yes")
154
107
  st.write(st.session_state.rawfilename)
155
108
  with open(st.session_state.rawfilename, "rb") as file:
156
109
  st.download_button(
@@ -159,12 +112,8 @@ if st.session_state.rawnc_download_DRW:
159
112
  file_name="rawfile.nc",
160
113
  )
161
114
 
162
- if st.session_state.vleadnc_download_DRW:
163
- file_write_vlead(
164
- st.session_state.fpath,
165
- st.session_state.axis_option,
166
- st.session_state.add_attributes_DRW == "Yes",
167
- )
115
+ if download_var_button:
116
+ file_write_vlead(st.session_state.fpath, add_attributes == "Yes")
168
117
  st.write(st.session_state.vleadfilename)
169
118
  with open(st.session_state.vleadfilename, "rb") as file:
170
119
  st.download_button(
@@ -173,7 +122,6 @@ if st.session_state.vleadnc_download_DRW:
173
122
  file_name="vlead.nc",
174
123
  )
175
124
 
176
-
177
125
  def download_csv_with_ensemble(data, filename):
178
126
  # Create ensemble numbers from 1 to the number of rows in the data
179
127
  ensembles = np.arange(1, len(next(iter(data.values()))) + 1)
@@ -183,62 +131,60 @@ def download_csv_with_ensemble(data, filename):
183
131
  df.insert(0, "RDI_Ensemble", ensembles) # Add ensemble numbers as the first column
184
132
 
185
133
  # Export the DataFrame as a CSV
186
- csv = df.to_csv(index=False).encode("utf-8")
134
+ csv = df.to_csv(index=False).encode('utf-8')
187
135
  return st.download_button(
188
136
  label=f"Download {filename} as CSV",
189
137
  data=csv,
190
138
  file_name=f"{filename}.csv",
191
- mime="text/csv",
139
+ mime='text/csv',
192
140
  )
193
-
194
-
141
+
195
142
  def download_csv(data, filename):
196
143
  # Convert data to DataFrame if it's not already one
197
144
  if isinstance(data, dict):
198
145
  df = pd.DataFrame.from_dict(data, orient="index").T
199
146
  else:
200
147
  df = pd.DataFrame(data)
201
-
148
+
202
149
  # Export the DataFrame as a CSV
203
- csv = df.to_csv(index=False).encode("utf-8")
150
+ csv = df.to_csv(index=False).encode('utf-8')
204
151
  return st.download_button(
205
152
  label=f"Download {filename} as CSV",
206
153
  data=csv,
207
154
  file_name=f"{filename}.csv",
208
- mime="text/csv",
155
+ mime='text/csv',
209
156
  )
210
-
211
-
157
+
158
+
212
159
  def download_csv1(data, filename):
213
160
  # Convert data to DataFrame if it's not already one
214
161
  if isinstance(data, dict):
215
162
  df = pd.DataFrame.from_dict(data, orient="index").T
216
163
  else:
217
164
  df = pd.DataFrame(data)
218
-
165
+
219
166
  # Create ensemble and depth arrays
220
167
  ensembles = np.arange(1, df.shape[0] + 1)
221
168
  depths = np.arange(1, df.shape[1] + 1)
222
-
169
+
223
170
  # Add ensemble numbers as the first column
224
- df.insert(0, "Ensemble", ensembles)
225
-
171
+ df.insert(0, 'Ensemble', ensembles)
172
+
226
173
  # Transpose the DataFrame to switch rows and columns
227
174
  df = df.T
228
-
175
+
229
176
  # Add depth values as the first row
230
- df.insert(0, "Depth", [""] + list(depths))
231
-
177
+ df.insert(0, 'Depth', [''] + list(depths))
178
+
232
179
  # Export the DataFrame as a CSV
233
- csv = df.to_csv(index=False, header=False).encode("utf-8")
180
+ csv = df.to_csv(index=False, header=False).encode('utf-8')
234
181
  return st.download_button(
235
182
  label=f"Download {filename} as CSV",
236
183
  data=csv,
237
184
  file_name=f"{filename}.csv",
238
- mime="text/csv",
185
+ mime='text/csv',
239
186
  )
240
187
 
241
-
242
188
  # Load data
243
189
  fdata = st.session_state.flead.fleader
244
190
  vdata = st.session_state.vlead.vleader
@@ -256,36 +202,25 @@ X, Y = np.meshgrid(x, y)
256
202
  st.header("Download Raw Data CSV File", divider="blue")
257
203
 
258
204
  # Selection for the data category
259
- st.session_state.rawcsv_option_DRW = st.selectbox(
205
+ data_type = st.selectbox(
260
206
  "Select data type to download:",
261
- [
262
- "Velocity",
263
- "Echo Intensity",
264
- "Correlation",
265
- "Percent Good",
266
- "Variable Leader",
267
- "Fixed Leader",
268
- ],
207
+ ["Fixed Leader", "Variable Leader", "Velocity", "Echo Intensity", "Correlation", "Percent Good"]
269
208
  )
270
209
 
271
210
  # Show corresponding variable options based on selection
272
- if st.session_state.rawcsv_option_DRW == "Fixed Leader":
211
+ if data_type == "Fixed Leader":
273
212
  # Combine all variables of Fixed Leader into one DataFrame
274
213
  f_combined_data = {var: fdata[var] for var in fdata.keys()}
275
214
  download_csv_with_ensemble(f_combined_data, "Fixed_Leader_All_Variables")
276
215
 
277
- elif st.session_state.rawcsv_option_DRW == "Variable Leader":
216
+ elif data_type == "Variable Leader":
278
217
  # Combine all variables of Variable Leader into one DataFrame
279
218
  v_combined_data = {var: vdata[var] for var in vdata.keys()}
280
219
  download_csv(v_combined_data, "Variable_Leader_All_Variables")
281
220
 
282
221
  else:
283
- st.session_state.rawcsv_beam_DRW = st.radio(
284
- "Select beam to download", (1, 2, 3, 4), horizontal=True
285
- )
222
+ beam_download = st.radio("Select beam to download", (1, 2, 3, 4), horizontal=True)
286
223
 
287
- data_type = st.session_state.rawcsv_option_DRW
288
- beam_download = st.session_state.rawcsv_beam_DRW
289
224
  if data_type == "Velocity":
290
225
  download_data = velocity[beam_download - 1, :, :]
291
226
  elif data_type == "Echo Intensity":
@@ -296,3 +231,4 @@ else:
296
231
  download_data = pgood[beam_download - 1, :, :]
297
232
 
298
233
  download_csv1(download_data, f"{data_type}_Beam_{beam_download}")
234
+
@@ -0,0 +1,283 @@
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]")