pyadps 0.2.1b0__py3-none-any.whl → 0.3.1b0__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/pages/01_Read_File.py +92 -17
- pyadps/pages/02_View_Raw_Data.py +69 -33
- pyadps/pages/04_Sensor_Health.py +892 -0
- pyadps/pages/05_QC_Test.py +478 -0
- pyadps/pages/06_Profile_Test.py +958 -0
- pyadps/pages/07_Velocity_Test.py +599 -0
- pyadps/pages/{07_Write_File.py → 08_Write_File.py} +130 -52
- pyadps/pages/09_Auto_process.py +62 -0
- pyadps/utils/__init__.py +2 -3
- pyadps/utils/autoprocess.py +228 -46
- pyadps/utils/metadata/config.ini +22 -4
- pyadps/utils/metadata/demo.000 +0 -0
- pyadps/utils/plotgen.py +499 -0
- pyadps/utils/profile_test.py +491 -126
- pyadps/utils/pyreadrdi.py +13 -6
- pyadps/utils/readrdi.py +78 -6
- pyadps/utils/script.py +21 -23
- pyadps/utils/sensor_health.py +120 -0
- pyadps/utils/signal_quality.py +343 -23
- pyadps/utils/velocity_test.py +75 -27
- pyadps/utils/writenc.py +8 -1
- {pyadps-0.2.1b0.dist-info → pyadps-0.3.1b0.dist-info}/METADATA +3 -3
- pyadps-0.3.1b0.dist-info/RECORD +33 -0
- {pyadps-0.2.1b0.dist-info → pyadps-0.3.1b0.dist-info}/WHEEL +1 -1
- pyadps/pages/04_QC_Test.py +0 -334
- pyadps/pages/05_Profile_Test.py +0 -575
- pyadps/pages/06_Velocity_Test.py +0 -341
- pyadps/utils/cutbin.py +0 -413
- pyadps/utils/regrid.py +0 -279
- pyadps-0.2.1b0.dist-info/RECORD +0 -31
- {pyadps-0.2.1b0.dist-info → pyadps-0.3.1b0.dist-info}/LICENSE +0 -0
- {pyadps-0.2.1b0.dist-info → pyadps-0.3.1b0.dist-info}/entry_points.txt +0 -0
pyadps/utils/autoprocess.py
CHANGED
@@ -5,22 +5,25 @@ import numpy as np
|
|
5
5
|
import pandas as pd
|
6
6
|
import pyadps.utils.writenc as wr
|
7
7
|
from pyadps.utils import readrdi
|
8
|
-
from pyadps.utils.profile_test import side_lobe_beam_angle
|
9
|
-
from pyadps.utils.
|
8
|
+
from pyadps.utils.profile_test import side_lobe_beam_angle, manual_cut_bins
|
9
|
+
from pyadps.utils.profile_test import regrid2d, regrid3d
|
10
10
|
from pyadps.utils.signal_quality import (
|
11
11
|
default_mask,
|
12
12
|
ev_check,
|
13
13
|
false_target,
|
14
14
|
pg_check,
|
15
|
-
|
15
|
+
echo_check,
|
16
|
+
correlation_check,
|
16
17
|
)
|
17
18
|
from pyadps.utils.velocity_test import (
|
18
19
|
despike,
|
19
20
|
flatline,
|
20
|
-
magnetic_declination,
|
21
21
|
velocity_cutoff,
|
22
|
+
wmm2020api,
|
23
|
+
velocity_modifier,
|
22
24
|
)
|
23
25
|
|
26
|
+
|
24
27
|
def main():
|
25
28
|
# Get the config file
|
26
29
|
try:
|
@@ -29,16 +32,34 @@ def main():
|
|
29
32
|
autoprocess(filepath)
|
30
33
|
else:
|
31
34
|
print("File not found!")
|
32
|
-
except:
|
35
|
+
except Exception as e:
|
36
|
+
import traceback
|
37
|
+
|
33
38
|
print("Error: Unable to process the data.")
|
39
|
+
traceback.print_exc()
|
40
|
+
|
34
41
|
|
35
|
-
def autoprocess(
|
42
|
+
def autoprocess(config_file, binary_file_path=None):
|
43
|
+
# Load configuration
|
36
44
|
config = configparser.ConfigParser()
|
37
|
-
config.read(filepath)
|
38
|
-
input_file_name = config.get("FileSettings", "input_file_name")
|
39
|
-
input_file_path = config.get("FileSettings", "input_file_path")
|
40
45
|
|
41
|
-
|
46
|
+
# Decode and parse the config file
|
47
|
+
# Check if config_file is a file-like object or a file path
|
48
|
+
if hasattr(config_file, "read"):
|
49
|
+
# If it's a file-like object, read its content
|
50
|
+
config_content = config_file.read().decode("utf-8")
|
51
|
+
else:
|
52
|
+
# If it's a file path, open the file and read its content
|
53
|
+
with open(config_file, "r", encoding="utf-8") as file:
|
54
|
+
config_content = file.read()
|
55
|
+
config.read_string(config_content)
|
56
|
+
|
57
|
+
if not binary_file_path:
|
58
|
+
input_file_name = config.get("FileSettings", "input_file_name")
|
59
|
+
input_file_path = config.get("FileSettings", "input_file_path")
|
60
|
+
full_input_file_path = os.path.join(input_file_path, input_file_name)
|
61
|
+
else:
|
62
|
+
full_input_file_path = binary_file_path
|
42
63
|
|
43
64
|
print("File reading started. Please wait for a few seconds ...")
|
44
65
|
ds = readrdi.ReadFile(full_input_file_path)
|
@@ -55,13 +76,24 @@ def autoprocess(filepath):
|
|
55
76
|
cells = flobj.field()["Cells"]
|
56
77
|
fdata = flobj.fleader
|
57
78
|
vdata = vlobj.vleader
|
79
|
+
# depth = ds.variableleader.depth_of_transducer
|
58
80
|
|
59
|
-
|
60
|
-
|
81
|
+
# Initialize mask
|
82
|
+
mask = default_mask(ds)
|
83
|
+
|
84
|
+
# Debugging statement
|
61
85
|
x = np.arange(0, ensembles, 1)
|
62
86
|
y = np.arange(0, cells, 1)
|
63
87
|
depth = None
|
64
88
|
|
89
|
+
axis_option = config.get("DownloadOptions", "axis_option")
|
90
|
+
|
91
|
+
# Sensor Test
|
92
|
+
isSensorTest = config.getboolean("SensorTest", "sensor_test")
|
93
|
+
isRollTest = config.getboolean("RollTest", "roll_test")
|
94
|
+
# if isSensorTest:
|
95
|
+
# if isRollTest:
|
96
|
+
|
65
97
|
# QC Test
|
66
98
|
isQCTest = config.getboolean("QCTest", "qc_test")
|
67
99
|
|
@@ -72,14 +104,15 @@ def autoprocess(filepath):
|
|
72
104
|
ft = config.getint("QCTest", "false_target")
|
73
105
|
is3Beam = config.getboolean("QCTest", "three_beam")
|
74
106
|
pgt = config.getint("QCTest", "percentage_good")
|
107
|
+
orientation = config.get("QCTest", "orientation")
|
75
108
|
|
76
|
-
mask = pg_check(
|
77
|
-
mask =
|
78
|
-
mask =
|
79
|
-
mask = ev_check(
|
80
|
-
mask = false_target(
|
81
|
-
print("QC Test complete.")
|
109
|
+
mask = pg_check(ds, mask, pgt, threebeam=is3Beam)
|
110
|
+
mask = correlation_check(ds, mask, ct)
|
111
|
+
mask = echo_check(ds, mask, et)
|
112
|
+
mask = ev_check(ds, mask, evt)
|
113
|
+
mask = false_target(ds, mask, ft, threebeam=True)
|
82
114
|
|
115
|
+
# Profile Test
|
83
116
|
endpoints = None
|
84
117
|
isProfileTest = config.getboolean("ProfileTest", "profile_test")
|
85
118
|
if isProfileTest:
|
@@ -87,8 +120,6 @@ def autoprocess(filepath):
|
|
87
120
|
if isTrimEnds:
|
88
121
|
start_index = config.getint("ProfileTest", "trim_ends_start_index")
|
89
122
|
end_index = config.getint("ProfileTest", "trim_ends_end_index")
|
90
|
-
# if start_index < 0 or start_index > ensembles:
|
91
|
-
|
92
123
|
if start_index > 0:
|
93
124
|
mask[:, :start_index] = 1
|
94
125
|
|
@@ -101,29 +132,150 @@ def autoprocess(filepath):
|
|
101
132
|
|
102
133
|
isCutBins = config.getboolean("ProfileTest", "cut_bins")
|
103
134
|
if isCutBins:
|
135
|
+
water_column_depth = 0
|
104
136
|
add_cells = config.getint("ProfileTest", "cut_bins_add_cells")
|
105
|
-
|
137
|
+
if orientation == "down":
|
138
|
+
water_column_depth = config.get("ProfileTest", "water_column_depth")
|
139
|
+
water_column_depth = int(water_column_depth)
|
140
|
+
mask = side_lobe_beam_angle(
|
141
|
+
ds,
|
142
|
+
mask,
|
143
|
+
orientation=orientation,
|
144
|
+
water_column_depth=water_column_depth,
|
145
|
+
extra_cells=add_cells,
|
146
|
+
)
|
147
|
+
else:
|
148
|
+
mask = side_lobe_beam_angle(
|
149
|
+
ds,
|
150
|
+
mask,
|
151
|
+
orientation=orientation,
|
152
|
+
water_column_depth=water_column_depth,
|
153
|
+
extra_cells=add_cells,
|
154
|
+
)
|
106
155
|
|
107
156
|
print("Cutbins complete.")
|
108
157
|
|
158
|
+
# Manual Cut Bins
|
159
|
+
isManual_cutbins = config.getboolean("ProfileTest", "manual_cutbins")
|
160
|
+
if isManual_cutbins:
|
161
|
+
raw_bins = config.get("ProfileTest", "manual_cut_bins")
|
162
|
+
bin_groups = raw_bins.split("]")
|
163
|
+
|
164
|
+
for group in bin_groups:
|
165
|
+
if group.strip(): # Ignore empty parts
|
166
|
+
# Clean and split the values
|
167
|
+
clean_group = group.replace("[", "").strip()
|
168
|
+
values = list(map(int, clean_group.split(",")))
|
169
|
+
min_cell, max_cell, min_ensemble, max_ensemble = values
|
170
|
+
mask = manual_cut_bins(
|
171
|
+
mask, min_cell, max_cell, min_ensemble, max_ensemble
|
172
|
+
)
|
173
|
+
|
174
|
+
print("Manual cut bins applied.")
|
175
|
+
|
109
176
|
isRegrid = config.getboolean("ProfileTest", "regrid")
|
110
177
|
if isRegrid:
|
111
178
|
print("File regridding started. This will take a few seconds ...")
|
179
|
+
|
112
180
|
regrid_option = config.get("ProfileTest", "regrid_option")
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
181
|
+
interpolate = config.get("ProfileTest", "regrid_interpolation")
|
182
|
+
boundary = 0
|
183
|
+
if regrid_option == "Manual":
|
184
|
+
boundary = config.get("ProfileTest", "transducer_depth")
|
185
|
+
z, velocity = regrid3d(
|
186
|
+
ds,
|
187
|
+
velocity,
|
188
|
+
-32768,
|
189
|
+
trimends=endpoints,
|
190
|
+
orientation=orientation,
|
191
|
+
method=interpolate,
|
192
|
+
boundary_limit=boundary,
|
193
|
+
)
|
194
|
+
z, echo = regrid3d(
|
195
|
+
ds,
|
196
|
+
echo,
|
197
|
+
-32768,
|
198
|
+
trimends=endpoints,
|
199
|
+
orientation=orientation,
|
200
|
+
method=interpolate,
|
201
|
+
boundary_limit=boundary,
|
202
|
+
)
|
203
|
+
z, correlation = regrid3d(
|
204
|
+
ds,
|
205
|
+
correlation,
|
206
|
+
-32768,
|
207
|
+
trimends=endpoints,
|
208
|
+
orientation=orientation,
|
209
|
+
method=interpolate,
|
210
|
+
boundary_limit=boundary,
|
211
|
+
)
|
212
|
+
z, pgood = regrid3d(
|
213
|
+
ds,
|
214
|
+
pgood,
|
215
|
+
-32768,
|
216
|
+
trimends=endpoints,
|
217
|
+
orientation=orientation,
|
218
|
+
method=interpolate,
|
219
|
+
boundary_limit=boundary,
|
220
|
+
)
|
221
|
+
z, mask = regrid2d(
|
222
|
+
ds,
|
223
|
+
mask,
|
224
|
+
1,
|
225
|
+
trimends=endpoints,
|
226
|
+
orientation=orientation,
|
227
|
+
method=interpolate,
|
228
|
+
boundary_limit=boundary,
|
229
|
+
)
|
230
|
+
depth = z
|
231
|
+
else:
|
232
|
+
z, velocity = regrid3d(
|
233
|
+
ds,
|
234
|
+
velocity,
|
235
|
+
-32768,
|
236
|
+
trimends=endpoints,
|
237
|
+
orientation=orientation,
|
238
|
+
method=interpolate,
|
239
|
+
boundary_limit=boundary,
|
240
|
+
)
|
241
|
+
z, echo = regrid3d(
|
242
|
+
ds,
|
243
|
+
echo,
|
244
|
+
-32768,
|
245
|
+
trimends=endpoints,
|
246
|
+
orientation=orientation,
|
247
|
+
method=interpolate,
|
248
|
+
boundary_limit=boundary,
|
249
|
+
)
|
250
|
+
z, correlation = regrid3d(
|
251
|
+
ds,
|
252
|
+
correlation,
|
253
|
+
-32768,
|
254
|
+
trimends=endpoints,
|
255
|
+
orientation=orientation,
|
256
|
+
method=interpolate,
|
257
|
+
boundary_limit=boundary,
|
258
|
+
)
|
259
|
+
z, pgood = regrid3d(
|
260
|
+
ds,
|
261
|
+
pgood,
|
262
|
+
-32768,
|
263
|
+
trimends=endpoints,
|
264
|
+
orientation=orientation,
|
265
|
+
method=interpolate,
|
266
|
+
boundary_limit=boundary,
|
267
|
+
)
|
268
|
+
z, mask = regrid2d(
|
269
|
+
ds,
|
270
|
+
mask,
|
271
|
+
1,
|
272
|
+
trimends=endpoints,
|
273
|
+
orientation=orientation,
|
274
|
+
method=interpolate,
|
275
|
+
boundary_limit=boundary,
|
276
|
+
)
|
277
|
+
depth = z
|
278
|
+
|
127
279
|
print("Regrid Complete.")
|
128
280
|
|
129
281
|
print("Profile Test complete.")
|
@@ -138,12 +290,12 @@ def autoprocess(filepath):
|
|
138
290
|
maglon = config.getfloat("VelocityTest", "longitude")
|
139
291
|
magdep = config.getfloat("VelocityTest", "depth")
|
140
292
|
magyear = config.getfloat("VelocityTest", "year")
|
293
|
+
year = int(magyear)
|
294
|
+
# mag = config.getfloat("VelocityTest", "mag")
|
141
295
|
|
142
|
-
|
143
|
-
|
144
|
-
)
|
296
|
+
mag = wmm2020api(maglat, maglon, year)
|
297
|
+
velocity = velocity_modifier(velocity, mag)
|
145
298
|
print(f"Magnetic Declination applied. The value is {mag[0]} degrees.")
|
146
|
-
|
147
299
|
isCutOff = config.getboolean("VelocityTest", "cutoff")
|
148
300
|
if isCutOff:
|
149
301
|
maxu = config.getint("VelocityTest", "max_zonal_velocity")
|
@@ -196,6 +348,7 @@ def autoprocess(filepath):
|
|
196
348
|
kernal_size=despike_kernal,
|
197
349
|
cutoff=despike_cutoff,
|
198
350
|
)
|
351
|
+
|
199
352
|
print("Flatlines in velocity removed.")
|
200
353
|
|
201
354
|
print("Velocity Test complete.")
|
@@ -239,14 +392,13 @@ def autoprocess(filepath):
|
|
239
392
|
}
|
240
393
|
)
|
241
394
|
|
242
|
-
|
395
|
+
date_raw = pd.to_datetime(date_df)
|
396
|
+
date_vlead = pd.to_datetime(date_df)
|
397
|
+
date_final = pd.to_datetime(date_df)
|
243
398
|
|
244
399
|
print("Time axis created.")
|
245
400
|
|
246
|
-
isWriteRawNC = config.get("DownloadOptions", "download_raw")
|
247
|
-
isWriteProcNC = config.get("DownloadOptions", "download_processed")
|
248
401
|
isAttributes = config.get("Optional", "attributes")
|
249
|
-
|
250
402
|
if isAttributes:
|
251
403
|
attributes = [att for att in config["Optional"]]
|
252
404
|
attributes = dict(config["Optional"].items())
|
@@ -254,15 +406,44 @@ def autoprocess(filepath):
|
|
254
406
|
else:
|
255
407
|
attributes = None
|
256
408
|
|
409
|
+
isWriteRawNC = config.get("DownloadOptions", "download_raw")
|
410
|
+
isWriteVleadNC = config.get("DownloadOptions", "download_vlead")
|
411
|
+
isWriteProcNC = config.get("DownloadOptions", "download_processed")
|
412
|
+
|
257
413
|
if isWriteRawNC:
|
258
414
|
filepath = config.get("FileSettings", "output_file_path")
|
259
415
|
filename = config.get("FileSettings", "output_file_name_raw")
|
260
416
|
output_file_path = os.path.join(filepath, filename)
|
261
417
|
if isAttributes:
|
262
|
-
wr.rawnc(
|
418
|
+
wr.rawnc(
|
419
|
+
full_input_file_path,
|
420
|
+
output_file_path,
|
421
|
+
date_raw,
|
422
|
+
axis_option,
|
423
|
+
attributes,
|
424
|
+
isAttributes,
|
425
|
+
)
|
263
426
|
|
264
427
|
print("Raw file written.")
|
265
428
|
|
429
|
+
if isWriteVleadNC:
|
430
|
+
filepath = config.get("FileSettings", "output_file_path")
|
431
|
+
filename = config.get("FileSettings", "output_file_name_vlead")
|
432
|
+
output_file_path = os.path.join(filepath, filename)
|
433
|
+
if isAttributes:
|
434
|
+
wr.vlead_nc(
|
435
|
+
full_input_file_path,
|
436
|
+
output_file_path,
|
437
|
+
date_vlead,
|
438
|
+
axis_option,
|
439
|
+
attributes,
|
440
|
+
isAttributes,
|
441
|
+
)
|
442
|
+
|
443
|
+
print("Vlead file written.")
|
444
|
+
|
445
|
+
depth1 = depth
|
446
|
+
|
266
447
|
if isWriteProcNC:
|
267
448
|
filepath = config.get("FileSettings", "output_file_path")
|
268
449
|
filename = config.get("FileSettings", "output_file_name_processed")
|
@@ -270,8 +451,9 @@ def autoprocess(filepath):
|
|
270
451
|
|
271
452
|
wr.finalnc(
|
272
453
|
full_file_path,
|
273
|
-
|
274
|
-
|
454
|
+
depth1,
|
455
|
+
mask,
|
456
|
+
date_final,
|
275
457
|
velocity,
|
276
458
|
attributes=attributes, # Pass edited attributes
|
277
459
|
)
|
pyadps/utils/metadata/config.ini
CHANGED
@@ -4,8 +4,9 @@ input_file_path = /home/user/data/
|
|
4
4
|
input_file_name = adcp_raw.000
|
5
5
|
|
6
6
|
# Output file settings. Do not enter file extension.
|
7
|
-
output_file_path = /home/
|
7
|
+
output_file_path = /home/nio/Videos/output/
|
8
8
|
output_file_name_raw = adcp_raw.nc
|
9
|
+
output_file_name_vlead = adcp_vlead.nc
|
9
10
|
output_file_name_processed = adcp_proc.nc
|
10
11
|
|
11
12
|
# Choose between 'netcdf' or 'csv' for the raw output format
|
@@ -16,11 +17,18 @@ output_format_processed = csv
|
|
16
17
|
|
17
18
|
[DownloadOptions]
|
18
19
|
# Options to download raw and/or processed output files
|
20
|
+
axis_option = ensemble
|
19
21
|
download_raw = True
|
22
|
+
download_vlead = True
|
20
23
|
download_processed = True
|
21
24
|
apply_mask = True
|
22
25
|
download_mask = True
|
23
26
|
|
27
|
+
[SensorTest]
|
28
|
+
sensor_test = True
|
29
|
+
transducer_depth = 200
|
30
|
+
|
31
|
+
|
24
32
|
[QCTest]
|
25
33
|
# Enable or Disable QC Test (True/False)
|
26
34
|
qc_test = True
|
@@ -30,6 +38,8 @@ echo_intensity = 40
|
|
30
38
|
false_target = 50
|
31
39
|
three_beam = True
|
32
40
|
percentage_good = 50
|
41
|
+
orientation = up
|
42
|
+
|
33
43
|
|
34
44
|
[ProfileTest]
|
35
45
|
# Enable or Disable Profile Test (True/False)
|
@@ -39,17 +49,22 @@ trim_ends_start_index = 2
|
|
39
49
|
trim_ends_end_index = 17086
|
40
50
|
cut_bins = True
|
41
51
|
cut_bins_add_cells = 2
|
52
|
+
manual_cutbins = True
|
53
|
+
manual_cut_bins = [2,10,0,8000] [40,42,0,8000] [12,14,0,8000]
|
42
54
|
regrid = True
|
43
|
-
regrid_option =
|
55
|
+
regrid_option = Cell
|
56
|
+
regrid_interpolation = nearest
|
57
|
+
transducer_depth = 200
|
58
|
+
water_column_depth = 200
|
44
59
|
|
45
60
|
[VelocityTest]
|
46
61
|
# Enable or Disable Velocity Test (True/False)
|
47
62
|
velocity_test = True
|
48
63
|
magnetic_declination = True
|
49
64
|
latitude = 0.0
|
50
|
-
longitude = 0
|
65
|
+
longitude = 83.0
|
51
66
|
depth = 0
|
52
|
-
year =
|
67
|
+
year = 2025
|
53
68
|
cutoff = True
|
54
69
|
max_zonal_velocity = 250
|
55
70
|
max_meridional_velocity = 250
|
@@ -79,3 +94,6 @@ file_created_by = xxxx
|
|
79
94
|
contact = abcd
|
80
95
|
comments = No comments
|
81
96
|
|
97
|
+
|
98
|
+
|
99
|
+
|
Binary file
|