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,530 @@
|
|
1
|
+
import configparser
|
2
|
+
import os
|
3
|
+
|
4
|
+
import numpy as np
|
5
|
+
import pandas as pd
|
6
|
+
import pyadps.utils.writenc as wr
|
7
|
+
from netCDF4 import date2num
|
8
|
+
from pyadps.utils import readrdi
|
9
|
+
from pyadps.utils.profile_test import side_lobe_beam_angle, manual_cut_bins
|
10
|
+
from pyadps.utils.profile_test import regrid2d, regrid3d
|
11
|
+
from pyadps.utils.signal_quality import (
|
12
|
+
default_mask,
|
13
|
+
ev_check,
|
14
|
+
false_target,
|
15
|
+
pg_check,
|
16
|
+
echo_check,
|
17
|
+
correlation_check,
|
18
|
+
)
|
19
|
+
from pyadps.utils.velocity_test import (
|
20
|
+
despike,
|
21
|
+
flatline,
|
22
|
+
velocity_cutoff,
|
23
|
+
magdec,
|
24
|
+
wmm2020api,
|
25
|
+
velocity_modifier,
|
26
|
+
)
|
27
|
+
from pyadps.utils.sensor_health import sound_speed_correction, tilt_sensor_check
|
28
|
+
|
29
|
+
|
30
|
+
def main():
|
31
|
+
# Get the config file
|
32
|
+
try:
|
33
|
+
filepath = input("Enter config file name: ")
|
34
|
+
if os.path.exists(filepath):
|
35
|
+
autoprocess(filepath)
|
36
|
+
else:
|
37
|
+
print("File not found!")
|
38
|
+
except Exception as e:
|
39
|
+
import traceback
|
40
|
+
|
41
|
+
print("Error: Unable to process the data.")
|
42
|
+
traceback.print_exc()
|
43
|
+
|
44
|
+
|
45
|
+
def autoprocess(config_file, binary_file_path=None):
|
46
|
+
# Load configuration
|
47
|
+
config = configparser.ConfigParser()
|
48
|
+
|
49
|
+
# Decode and parse the config file
|
50
|
+
# Check if config_file is a file-like object or a file path
|
51
|
+
if hasattr(config_file, "read"):
|
52
|
+
# If it's a file-like object, read its content
|
53
|
+
config_content = config_file.read().decode("utf-8")
|
54
|
+
else:
|
55
|
+
# If it's a file path, open the file and read its content
|
56
|
+
with open(config_file, "r", encoding="utf-8") as file:
|
57
|
+
config_content = file.read()
|
58
|
+
config.read_string(config_content)
|
59
|
+
|
60
|
+
if not binary_file_path:
|
61
|
+
input_file_name = config.get("FileSettings", "input_file_name")
|
62
|
+
input_file_path = config.get("FileSettings", "input_file_path")
|
63
|
+
full_input_file_path = os.path.join(input_file_path, input_file_name)
|
64
|
+
else:
|
65
|
+
full_input_file_path = binary_file_path
|
66
|
+
|
67
|
+
print("File reading started. Please wait for a few seconds ...")
|
68
|
+
ds = readrdi.ReadFile(full_input_file_path)
|
69
|
+
print("File reading complete.")
|
70
|
+
|
71
|
+
header = ds.fileheader
|
72
|
+
flobj = ds.fixedleader
|
73
|
+
vlobj = ds.variableleader
|
74
|
+
velocity = ds.velocity.data
|
75
|
+
echo = ds.echo.data
|
76
|
+
correlation = ds.correlation.data
|
77
|
+
pgood = ds.percentgood.data
|
78
|
+
roll = ds.variableleader.roll.data
|
79
|
+
pitch = ds.variableleader.pitch.data
|
80
|
+
sound = ds.variableleader.speed_of_sound.data
|
81
|
+
depth = ds.variableleader.depth_of_transducer.data
|
82
|
+
temperature = (
|
83
|
+
ds.variableleader.temperature.data * ds.variableleader.temperature.scale
|
84
|
+
)
|
85
|
+
salinity = ds.variableleader.salinity.data * ds.variableleader.salinity.scale
|
86
|
+
orientation = ds.fixedleader.system_configuration()["Beam Direction"]
|
87
|
+
ensembles = header.ensembles
|
88
|
+
cells = flobj.field()["Cells"]
|
89
|
+
beams = flobj.field()["Beams"]
|
90
|
+
cell_size = flobj.field()["Depth Cell Len"]
|
91
|
+
bin1dist = flobj.field()["Bin 1 Dist"]
|
92
|
+
beam_angle = int(flobj.system_configuration()["Beam Angle"])
|
93
|
+
fdata = flobj.fleader
|
94
|
+
vdata = vlobj.vleader
|
95
|
+
# depth = ds.variableleader.depth_of_transducer
|
96
|
+
|
97
|
+
# Initialize mask
|
98
|
+
mask = default_mask(ds)
|
99
|
+
|
100
|
+
# Debugging statement
|
101
|
+
x = np.arange(0, ensembles, 1)
|
102
|
+
y = np.arange(0, cells, 1)
|
103
|
+
|
104
|
+
axis_option = config.get("DownloadOptions", "axis_option")
|
105
|
+
|
106
|
+
# Sensor Test
|
107
|
+
isSensorTest = config.getboolean("SensorTest", "sensor_test")
|
108
|
+
if isSensorTest:
|
109
|
+
isDepthModified = config.getboolean("SensorTest", "is_depth_modified")
|
110
|
+
if isDepthModified:
|
111
|
+
depth_option = config.get("SensorTest", "depth_input_option")
|
112
|
+
if depth_option == "Fixed Value":
|
113
|
+
fixed_depth = config.getfloat("SensorTest", "fixed_depth")
|
114
|
+
depth = np.full(ensembles, fixed_depth)
|
115
|
+
depth *= 10
|
116
|
+
elif depth_option == "File Upload":
|
117
|
+
depth_file_path = config.get("SensorTest", "depth_file_path")
|
118
|
+
df = pd.read_csv(depth_file_path)
|
119
|
+
depth = np.squeeze(df)
|
120
|
+
if len(depth) != ensembles:
|
121
|
+
print("""
|
122
|
+
Error: Uploaded file ensembles and
|
123
|
+
actual ensembles mismatch
|
124
|
+
""")
|
125
|
+
else:
|
126
|
+
print("Depth file uploaded.")
|
127
|
+
|
128
|
+
isSalinityModified = config.getboolean("SensorTest", "is_salinity_modified")
|
129
|
+
if isSalinityModified:
|
130
|
+
salinity_option = config.get("SensorTest", "salinity_input_option")
|
131
|
+
if salinity_option == "Fixed Value":
|
132
|
+
fixed_salinity = config.getfloat("SensorTest", "fixed_salinity")
|
133
|
+
salinity = np.full(ensembles, fixed_salinity)
|
134
|
+
salinity *= 10
|
135
|
+
elif salinity_option == "File Upload":
|
136
|
+
salinity_file_path = config.get("SensorTest", "salinity_file_path")
|
137
|
+
df = pd.read_csv(salinity_file_path)
|
138
|
+
salinity = np.squeeze(df)
|
139
|
+
if len(salinity) != ensembles:
|
140
|
+
print("""
|
141
|
+
Error: Uploaded file ensembles and
|
142
|
+
actual ensembles mismatch
|
143
|
+
""")
|
144
|
+
else:
|
145
|
+
print("Salinity file uploaded.")
|
146
|
+
|
147
|
+
isTemperatureModified = config.getboolean(
|
148
|
+
"SensorTest", "is_temperature_modified"
|
149
|
+
)
|
150
|
+
if isTemperatureModified:
|
151
|
+
temperature_option = config.get("SensorTest", "temperature_input_option")
|
152
|
+
if temperature_option == "Fixed Value":
|
153
|
+
fixed_temperature = config.getfloat("SensorTest", "fixed_temperature")
|
154
|
+
temperature = np.full(ensembles, fixed_temperature)
|
155
|
+
temperature *= 10
|
156
|
+
elif temperature_option == "File Upload":
|
157
|
+
temperature_file_path = config.get(
|
158
|
+
"SensorTest", "temperature_file_path"
|
159
|
+
)
|
160
|
+
df = pd.read_csv(temperature_file_path)
|
161
|
+
temperature = np.squeeze(df)
|
162
|
+
if len(temperature) != ensembles:
|
163
|
+
print("""
|
164
|
+
Error: Uploaded file ensembles and
|
165
|
+
actual ensembles mismatch
|
166
|
+
""")
|
167
|
+
else:
|
168
|
+
print("Temperature file uploaded.")
|
169
|
+
|
170
|
+
isRollCheck = config.getboolean("SensorTest", "roll_check")
|
171
|
+
if isRollCheck:
|
172
|
+
roll_cutoff = config.getint("SensorTest", "roll_cutoff")
|
173
|
+
mask = tilt_sensor_check(roll, mask, cutoff=roll_cutoff)
|
174
|
+
|
175
|
+
isPitchCheck = config.getboolean("SensorTest", "pitch_check")
|
176
|
+
if isPitchCheck:
|
177
|
+
pitch_cutoff = config.getint("SensorTest", "pitch_cutoff")
|
178
|
+
mask = tilt_sensor_check(pitch, mask, cutoff=pitch_cutoff)
|
179
|
+
|
180
|
+
isVelocityModified = config.getboolean("SensorTest", "velocity_modified")
|
181
|
+
if isVelocityModified:
|
182
|
+
velocity = sound_speed_correction(
|
183
|
+
velocity, sound, temperature, salinity, depth
|
184
|
+
)
|
185
|
+
|
186
|
+
# QC Test
|
187
|
+
isQCTest = config.getboolean("QCTest", "qc_test")
|
188
|
+
if isQCTest:
|
189
|
+
isQCCheck = config.get("QCTest", "qc_check")
|
190
|
+
if isQCCheck:
|
191
|
+
ct = config.getint("QCTest", "correlation")
|
192
|
+
evt = config.getint("QCTest", "error_velocity")
|
193
|
+
et = config.getint("QCTest", "echo_intensity")
|
194
|
+
ft = config.getint("QCTest", "false_target")
|
195
|
+
is3Beam = config.getboolean("QCTest", "three_beam")
|
196
|
+
pgt = config.getint("QCTest", "percent_good")
|
197
|
+
orientation = config.get("QCTest", "orientation")
|
198
|
+
|
199
|
+
mask = pg_check(ds, mask, pgt, threebeam=is3Beam)
|
200
|
+
mask = correlation_check(ds, mask, ct)
|
201
|
+
mask = echo_check(ds, mask, et)
|
202
|
+
mask = ev_check(ds, mask, evt)
|
203
|
+
mask = false_target(ds, mask, ft, threebeam=True)
|
204
|
+
|
205
|
+
print("QC Check Complete.")
|
206
|
+
|
207
|
+
isBeamModified = config.getboolean("QCTest", "beam_modified")
|
208
|
+
if isBeamModified:
|
209
|
+
orientation = config.get("QCTest", "orientation")
|
210
|
+
print("Beam orientation changed.")
|
211
|
+
|
212
|
+
# Profile Test
|
213
|
+
endpoints = None
|
214
|
+
isProfileTest = config.getboolean("ProfileTest", "profile_test")
|
215
|
+
if isProfileTest:
|
216
|
+
isTrimEnds = config.getboolean("ProfileTest", "trim_ends_check")
|
217
|
+
if isTrimEnds:
|
218
|
+
start_index = config.getint("ProfileTest", "trim_start_ensemble")
|
219
|
+
end_index = config.getint("ProfileTest", "trim_end_ensemble")
|
220
|
+
if start_index > 0:
|
221
|
+
mask[:, :start_index] = 1
|
222
|
+
|
223
|
+
if end_index < x[-1]:
|
224
|
+
mask[:, end_index:] = 1
|
225
|
+
|
226
|
+
endpoints = np.array([start_index, end_index])
|
227
|
+
|
228
|
+
print("Trim Ends complete.")
|
229
|
+
|
230
|
+
isCutBins = config.getboolean("ProfileTest", "cutbins_sidelobe_check")
|
231
|
+
if isCutBins:
|
232
|
+
water_column_depth = config.getint("ProfileTest", "water_depth")
|
233
|
+
extra_cells = config.getint("ProfileTest", "extra_cells")
|
234
|
+
mask = side_lobe_beam_angle(
|
235
|
+
depth,
|
236
|
+
mask,
|
237
|
+
orientation=orientation,
|
238
|
+
water_column_depth=water_column_depth,
|
239
|
+
extra_cells=extra_cells,
|
240
|
+
cells=cells,
|
241
|
+
cell_size=cell_size,
|
242
|
+
bin1dist=bin1dist,
|
243
|
+
beam_angle=beam_angle,
|
244
|
+
)
|
245
|
+
print("Cutbins complete.")
|
246
|
+
|
247
|
+
# Manual Cut Bins
|
248
|
+
# isManual_cutbins = config.getboolean("ProfileTest", "manual_cutbins")
|
249
|
+
# if isManual_cutbins:
|
250
|
+
# raw_bins = config.get("ProfileTest", "manual_cut_bins")
|
251
|
+
# bin_groups = raw_bins.split("]")
|
252
|
+
#
|
253
|
+
# for group in bin_groups:
|
254
|
+
# if group.strip(): # Ignore empty parts
|
255
|
+
# # Clean and split the values
|
256
|
+
# clean_group = group.replace("[", "").strip()
|
257
|
+
# values = list(map(int, clean_group.split(",")))
|
258
|
+
# min_cell, max_cell, min_ensemble, max_ensemble = values
|
259
|
+
# mask = manual_cut_bins(
|
260
|
+
# mask, min_cell, max_cell, min_ensemble, max_ensemble
|
261
|
+
# )
|
262
|
+
#
|
263
|
+
# print("Manual cut bins applied.")
|
264
|
+
|
265
|
+
isRegrid = config.getboolean("ProfileTest", "regrid")
|
266
|
+
if isRegrid:
|
267
|
+
print("File regridding started. This will take a few seconds ...")
|
268
|
+
|
269
|
+
# regrid_option = config.get("ProfileTest", "regrid_option")
|
270
|
+
end_cell_option = config.get("ProfileTest", "end_cell_option")
|
271
|
+
interpolate = config.get("ProfileTest", "interpolate")
|
272
|
+
boundary = config.getint("ProfileTest", "boundary")
|
273
|
+
z, velocity = regrid3d(
|
274
|
+
depth,
|
275
|
+
velocity,
|
276
|
+
-32768,
|
277
|
+
trimends=endpoints,
|
278
|
+
orientation=orientation,
|
279
|
+
end_cell_option=end_cell_option,
|
280
|
+
method=interpolate,
|
281
|
+
boundary_limit=boundary,
|
282
|
+
cells=cells,
|
283
|
+
cell_size=cell_size,
|
284
|
+
bin1dist=bin1dist,
|
285
|
+
beams=beams,
|
286
|
+
)
|
287
|
+
z, echo = regrid3d(
|
288
|
+
depth,
|
289
|
+
echo,
|
290
|
+
-32768,
|
291
|
+
trimends=endpoints,
|
292
|
+
orientation=orientation,
|
293
|
+
method=interpolate,
|
294
|
+
boundary_limit=boundary,
|
295
|
+
cells=cells,
|
296
|
+
cell_size=cell_size,
|
297
|
+
bin1dist=bin1dist,
|
298
|
+
beams=beams,
|
299
|
+
)
|
300
|
+
z, correlation = regrid3d(
|
301
|
+
depth,
|
302
|
+
correlation,
|
303
|
+
-32768,
|
304
|
+
trimends=endpoints,
|
305
|
+
orientation=orientation,
|
306
|
+
method=interpolate,
|
307
|
+
boundary_limit=boundary,
|
308
|
+
cells=cells,
|
309
|
+
cell_size=cell_size,
|
310
|
+
bin1dist=bin1dist,
|
311
|
+
beams=beams,
|
312
|
+
)
|
313
|
+
z, pgood = regrid3d(
|
314
|
+
depth,
|
315
|
+
pgood,
|
316
|
+
-32768,
|
317
|
+
trimends=endpoints,
|
318
|
+
orientation=orientation,
|
319
|
+
method=interpolate,
|
320
|
+
boundary_limit=boundary,
|
321
|
+
cells=cells,
|
322
|
+
cell_size=cell_size,
|
323
|
+
bin1dist=bin1dist,
|
324
|
+
beams=beams,
|
325
|
+
)
|
326
|
+
z, mask = regrid2d(
|
327
|
+
depth,
|
328
|
+
mask,
|
329
|
+
1,
|
330
|
+
trimends=endpoints,
|
331
|
+
orientation=orientation,
|
332
|
+
method=interpolate,
|
333
|
+
boundary_limit=boundary,
|
334
|
+
cells=cells,
|
335
|
+
cell_size=cell_size,
|
336
|
+
bin1dist=bin1dist,
|
337
|
+
)
|
338
|
+
depth = z
|
339
|
+
|
340
|
+
print("Regrid Complete.")
|
341
|
+
|
342
|
+
print("Profile Test complete.")
|
343
|
+
|
344
|
+
isVelocityTest = config.getboolean("VelocityTest", "velocity_test")
|
345
|
+
if isVelocityTest:
|
346
|
+
isMagneticDeclination = config.getboolean(
|
347
|
+
"VelocityTest", "magnetic_declination"
|
348
|
+
)
|
349
|
+
if isMagneticDeclination:
|
350
|
+
magmethod = config.get("VelocityTest", "magnet_method")
|
351
|
+
maglat = config.getfloat("VelocityTest", "magnet_latitude")
|
352
|
+
maglon = config.getfloat("VelocityTest", "magnet_longitude")
|
353
|
+
magdep = config.getfloat("VelocityTest", "magnet_depth")
|
354
|
+
magyear = config.getfloat("VelocityTest", "magnet_year")
|
355
|
+
year = int(magyear)
|
356
|
+
# mag = config.getfloat("VelocityTest", "mag")
|
357
|
+
|
358
|
+
if magmethod == "pygeomag":
|
359
|
+
mag = magdec(maglat, maglon, magdep, magyear)
|
360
|
+
elif magmethod.lower() == "api":
|
361
|
+
mag = wmm2020api(maglat, maglon, year)
|
362
|
+
elif magmethod.lower() == "manual":
|
363
|
+
mag = config.getint("VelocityTest", "magnet_user_input")
|
364
|
+
else:
|
365
|
+
mag = 0
|
366
|
+
velocity = velocity_modifier(velocity, mag)
|
367
|
+
print(f"Magnetic Declination applied. The value is {mag[0]} degrees.")
|
368
|
+
|
369
|
+
isCutOff = config.getboolean("VelocityTest", "cutoff")
|
370
|
+
if isCutOff:
|
371
|
+
maxu = config.getint("VelocityTest", "max_zonal_velocity")
|
372
|
+
maxv = config.getint("VelocityTest", "max_meridional_velocity")
|
373
|
+
maxw = config.getint("VelocityTest", "max_vertical_velocity")
|
374
|
+
mask = velocity_cutoff(velocity[0, :, :], mask, cutoff=maxu)
|
375
|
+
mask = velocity_cutoff(velocity[1, :, :], mask, cutoff=maxv)
|
376
|
+
mask = velocity_cutoff(velocity[2, :, :], mask, cutoff=maxw)
|
377
|
+
print("Maximum velocity cutoff applied.")
|
378
|
+
|
379
|
+
isDespike = config.getboolean("VelocityTest", "despike")
|
380
|
+
if isDespike:
|
381
|
+
despike_kernal = config.getint("VelocityTest", "despike_kernal_size")
|
382
|
+
despike_cutoff = config.getint("VelocityTest", "despike_cutoff")
|
383
|
+
|
384
|
+
mask = despike(
|
385
|
+
velocity[0, :, :],
|
386
|
+
mask,
|
387
|
+
kernal_size=despike_kernal,
|
388
|
+
cutoff=despike_cutoff,
|
389
|
+
)
|
390
|
+
mask = despike(
|
391
|
+
velocity[1, :, :],
|
392
|
+
mask,
|
393
|
+
kernal_size=despike_kernal,
|
394
|
+
cutoff=despike_cutoff,
|
395
|
+
)
|
396
|
+
print("Velocity data despiked.")
|
397
|
+
|
398
|
+
isFlatline = config.getboolean("VelocityTest", "flatline")
|
399
|
+
if isFlatline:
|
400
|
+
despike_kernal = config.getint("VelocityTest", "flatline_kernal_size")
|
401
|
+
despike_cutoff = config.getint("VelocityTest", "flatline_deviation")
|
402
|
+
|
403
|
+
mask = flatline(
|
404
|
+
velocity[0, :, :],
|
405
|
+
mask,
|
406
|
+
kernal_size=despike_kernal,
|
407
|
+
cutoff=despike_cutoff,
|
408
|
+
)
|
409
|
+
mask = flatline(
|
410
|
+
velocity[1, :, :],
|
411
|
+
mask,
|
412
|
+
kernal_size=despike_kernal,
|
413
|
+
cutoff=despike_cutoff,
|
414
|
+
)
|
415
|
+
mask = flatline(
|
416
|
+
velocity[2, :, :],
|
417
|
+
mask,
|
418
|
+
kernal_size=despike_kernal,
|
419
|
+
cutoff=despike_cutoff,
|
420
|
+
)
|
421
|
+
|
422
|
+
print("Flatlines in velocity removed.")
|
423
|
+
|
424
|
+
print("Velocity Test complete.")
|
425
|
+
|
426
|
+
# Apply mask to velocity data
|
427
|
+
isApplyMask = config.get("DownloadOptions", "apply_mask")
|
428
|
+
if isApplyMask:
|
429
|
+
velocity[:, mask == 1] = -32768
|
430
|
+
print("Mask Applied.")
|
431
|
+
|
432
|
+
# Create Depth axis if regrid not applied
|
433
|
+
if depth is None:
|
434
|
+
mean_depth = np.mean(vlobj.vleader["Depth of Transducer"]) / 10
|
435
|
+
mean_depth = np.trunc(mean_depth)
|
436
|
+
cells = flobj.field()["Cells"]
|
437
|
+
cell_size = flobj.field()["Depth Cell Len"] / 100
|
438
|
+
bin1dist = flobj.field()["Bin 1 Dist"] / 100
|
439
|
+
max_depth = mean_depth - bin1dist
|
440
|
+
min_depth = max_depth - cells * cell_size
|
441
|
+
depth = np.arange(-1 * max_depth, -1 * min_depth, cell_size)
|
442
|
+
|
443
|
+
print("WARNING: File not regrided. Depth axis created based on mean depth.")
|
444
|
+
|
445
|
+
# Create Time axis
|
446
|
+
year = vlobj.vleader["RTC Year"]
|
447
|
+
month = vlobj.vleader["RTC Month"]
|
448
|
+
day = vlobj.vleader["RTC Day"]
|
449
|
+
hour = vlobj.vleader["RTC Hour"]
|
450
|
+
minute = vlobj.vleader["RTC Minute"]
|
451
|
+
second = vlobj.vleader["RTC Second"]
|
452
|
+
|
453
|
+
year = year + 2000
|
454
|
+
date_df = pd.DataFrame(
|
455
|
+
{
|
456
|
+
"year": year,
|
457
|
+
"month": month,
|
458
|
+
"day": day,
|
459
|
+
"hour": hour,
|
460
|
+
"minute": minute,
|
461
|
+
"second": second,
|
462
|
+
}
|
463
|
+
)
|
464
|
+
|
465
|
+
date_raw = pd.to_datetime(date_df)
|
466
|
+
date_vlead = pd.to_datetime(date_df)
|
467
|
+
date_final = pd.to_datetime(date_df)
|
468
|
+
|
469
|
+
print("Time axis created.")
|
470
|
+
|
471
|
+
isAttributes = config.getboolean("DownloadOptions", "add_attributes_processed")
|
472
|
+
if isAttributes:
|
473
|
+
attributes = [att for att in config["DownloadOptions"]]
|
474
|
+
attributes = dict(config["DownloadOptions"].items())
|
475
|
+
del attributes["add_attributes_processed"]
|
476
|
+
else:
|
477
|
+
attributes = None
|
478
|
+
|
479
|
+
isWriteRawNC = config.getboolean("DownloadOptions", "download_raw_netcdf")
|
480
|
+
isWriteVleadNC = config.getboolean("DownloadOptions", "download_vlead_netcdf")
|
481
|
+
isWriteProcNC = config.getboolean("DownloadOptions", "download_processed_netcdf")
|
482
|
+
filepath = config.get("FileSettings", "output_file_path")
|
483
|
+
|
484
|
+
print(isWriteRawNC)
|
485
|
+
if isWriteRawNC:
|
486
|
+
filename = config.get("FileSettings", "output_file_name_raw_netcdf")
|
487
|
+
output_file_path = os.path.join(filepath, filename)
|
488
|
+
print(date_raw.shape)
|
489
|
+
wr.rawnc(
|
490
|
+
full_input_file_path,
|
491
|
+
output_file_path,
|
492
|
+
date_raw,
|
493
|
+
axis_option=axis_option,
|
494
|
+
attributes=attributes,
|
495
|
+
)
|
496
|
+
|
497
|
+
print("Raw file written.")
|
498
|
+
|
499
|
+
if isWriteVleadNC:
|
500
|
+
filename = config.get("FileSettings", "output_file_name_vlead_netcdf")
|
501
|
+
output_file_path = os.path.join(filepath, filename)
|
502
|
+
wr.vlead_nc(
|
503
|
+
full_input_file_path,
|
504
|
+
output_file_path,
|
505
|
+
date_vlead,
|
506
|
+
axis_option=axis_option,
|
507
|
+
attributes=attributes,
|
508
|
+
)
|
509
|
+
|
510
|
+
print("Vlead file written.")
|
511
|
+
|
512
|
+
depth1 = depth
|
513
|
+
|
514
|
+
if isWriteProcNC:
|
515
|
+
filename = config.get("FileSettings", "output_file_name_processed_netcdf")
|
516
|
+
output_file_path = os.path.join(filepath, filename)
|
517
|
+
|
518
|
+
wr.finalnc(
|
519
|
+
output_file_path,
|
520
|
+
depth1,
|
521
|
+
mask,
|
522
|
+
date_final,
|
523
|
+
velocity,
|
524
|
+
attributes=attributes, # Pass edited attributes
|
525
|
+
)
|
526
|
+
print("Processed file written.")
|
527
|
+
|
528
|
+
|
529
|
+
if __name__ == "__main__":
|
530
|
+
main()
|
@@ -0,0 +1,99 @@
|
|
1
|
+
[FileSettings]
|
2
|
+
# Input file settings
|
3
|
+
input_file_path = /home/user/data/
|
4
|
+
input_file_name = adcp_raw.000
|
5
|
+
|
6
|
+
# Output file settings. Do not enter file extension.
|
7
|
+
output_file_path = /home/nio/Videos/output/
|
8
|
+
output_file_name_raw = adcp_raw.nc
|
9
|
+
output_file_name_vlead = adcp_vlead.nc
|
10
|
+
output_file_name_processed = adcp_proc.nc
|
11
|
+
|
12
|
+
# Choose between 'netcdf' or 'csv' for the raw output format
|
13
|
+
output_format_raw = netcdf
|
14
|
+
|
15
|
+
# Choose between 'netcdf' or 'csv' for the processed output format
|
16
|
+
output_format_processed = csv
|
17
|
+
|
18
|
+
[DownloadOptions]
|
19
|
+
# Options to download raw and/or processed output files
|
20
|
+
axis_option = ensemble
|
21
|
+
download_raw = True
|
22
|
+
download_vlead = True
|
23
|
+
download_processed = True
|
24
|
+
apply_mask = True
|
25
|
+
download_mask = True
|
26
|
+
|
27
|
+
[SensorTest]
|
28
|
+
sensor_test = True
|
29
|
+
transducer_depth = 200
|
30
|
+
|
31
|
+
|
32
|
+
[QCTest]
|
33
|
+
# Enable or Disable QC Test (True/False)
|
34
|
+
qc_test = True
|
35
|
+
correlation = 64
|
36
|
+
error_velocity = 2000
|
37
|
+
echo_intensity = 40
|
38
|
+
false_target = 50
|
39
|
+
three_beam = True
|
40
|
+
percentage_good = 50
|
41
|
+
orientation = up
|
42
|
+
|
43
|
+
|
44
|
+
[ProfileTest]
|
45
|
+
# Enable or Disable Profile Test (True/False)
|
46
|
+
profile_test = True
|
47
|
+
trim_ends = True
|
48
|
+
trim_ends_start_index = 2
|
49
|
+
trim_ends_end_index = 17086
|
50
|
+
cut_bins = True
|
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]
|
54
|
+
regrid = True
|
55
|
+
regrid_option = Cell
|
56
|
+
regrid_interpolation = nearest
|
57
|
+
transducer_depth = 200
|
58
|
+
water_column_depth = 200
|
59
|
+
|
60
|
+
[VelocityTest]
|
61
|
+
# Enable or Disable Velocity Test (True/False)
|
62
|
+
velocity_test = True
|
63
|
+
magnetic_declination = True
|
64
|
+
latitude = 0.0
|
65
|
+
longitude = 83.0
|
66
|
+
depth = 0
|
67
|
+
year = 2025
|
68
|
+
cutoff = True
|
69
|
+
max_zonal_velocity = 250
|
70
|
+
max_meridional_velocity = 250
|
71
|
+
max_vertical_velocity = 15
|
72
|
+
despike = True
|
73
|
+
despike_kernal_size = 5
|
74
|
+
despike_cutoff = 150
|
75
|
+
flatline = True
|
76
|
+
flatline_kernal_size = 13
|
77
|
+
flatline_deviation = 1
|
78
|
+
|
79
|
+
[Optional]
|
80
|
+
# Options to add attributes to netcdf file (True/False)
|
81
|
+
attributes = True
|
82
|
+
cruise_no. = Ship999
|
83
|
+
ship_name = RV Vessel Name
|
84
|
+
project_no. = GAP9999
|
85
|
+
water_depth_m = 1000
|
86
|
+
deployment_depth_m = 300
|
87
|
+
deployment_date = 12/10/2023
|
88
|
+
recovery_date = 8/10/2024
|
89
|
+
latitude = 15.0
|
90
|
+
longitude = 77.0
|
91
|
+
platform_type = Moored
|
92
|
+
participants = abcd, efgh, ijkl
|
93
|
+
file_created_by = xxxx
|
94
|
+
contact = abcd
|
95
|
+
comments = No comments
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
Binary file
|