Skip to content

Commit 54da94a

Browse files
committed
Correct comments, guestimate HR cell size and blank coefficients
1 parent 868985c commit 54da94a

3 files changed

Lines changed: 40 additions & 34 deletions

File tree

mhkit/dolfyn/io/nortek.py

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,6 @@ def sample_spacing(self):
509509
"""
510510
Find the spacing, in bytes, between each set of samples.
511511
"""
512-
513512
id_count = {}
514513
id_size = {}
515514
while True:
@@ -522,28 +521,23 @@ def sample_spacing(self):
522521
# now read the next byte, which is the size of the data block
523522
sz = 2 * unpack(self.endian + "H", self.read(2))[0]
524523
shift = sz - 4
525-
526524
if nowid not in id_count:
527525
id_count[nowid] = 1
528526
else:
529527
id_count[nowid] += 1
530-
531528
if nowid not in id_size:
532529
id_size[nowid] = [sz]
533530
else:
534531
id_size[nowid].append(sz)
535-
536532
self.f.seek(shift, 1)
537533
# If we get stuck in a while loop
538534
if self.pos == pos:
539535
self.f.seek(2, 1)
540536
except EOFError:
541537
break
542-
543538
# Take median size of each ID data block
544539
for id in id_size:
545540
id_size[id] = int(np.median(id_size[id]))
546-
547541
# Return size of most common data block found
548542
if len(id_count) >= 1:
549543
return id_size[max(id_count, key=id_count.get)]
@@ -585,7 +579,7 @@ def read_user_cfg(self):
585579
cfg_u["waves"] = {}
586580

587581
cfg_u["transmit_pulse_length_m"] = tmp[0] # counts
588-
cfg_u["blank_dist"] = tmp[1] # overridden below
582+
cfg_u["blank_dist"] = tmp[1] # counts
589583
cfg_u["receive_length_m"] = tmp[2] # counts
590584
cfg_u["time_between_pings"] = tmp[3] # counts
591585
cfg_u["time_between_bursts"] = tmp[4] # counts
@@ -889,8 +883,8 @@ def read_vec_sys(self):
889883
]:
890884
self.burst_start[c] = True
891885
if "time" not in dat["coords"]:
892-
self._init_data(defs.vec_sysdata)
893-
self._dtypes += ["vec_sysdata"]
886+
self._init_data(defs.vec_sys)
887+
self._dtypes += ["vec_sys"]
894888
byts = self.read(24)
895889
# The first two are size (skip them).
896890
dat["coords"]["time"][c] = lib.rd_time(byts[2:8])
@@ -1022,6 +1016,7 @@ def read_aqd_profile_hr(self):
10221016
if "temp" not in dat["data_vars"]:
10231017
self._init_data(defs.aqd_hr_profile)
10241018
self._dtypes += ["awac_profile"]
1019+
self.data["attrs"]["hr_profile"] = 1
10251020

10261021
byts = self.read(52)
10271022
c = self.c
@@ -1166,17 +1161,17 @@ def read_awac_stage(self):
11661161
byts = self.read(30)
11671162
dv = dat["data_vars"]
11681163
(
1169-
dv["amp"][0, c], # amplitude beam 1 (counts)
1170-
dv["amp"][1, c], # amplitude beam 2 (counts)
1171-
dv["amp"][2, c], # amplitude beam 3 (counts)
1164+
dv["amp_alt"][0, c], # amplitude beam 1 (counts)
1165+
dv["amp_alt"][1, c], # amplitude beam 2 (counts)
1166+
dv["amp_alt"][2, c], # amplitude beam 3 (counts)
11721167
dv["pressure"][c], # (0.001 dbar)
11731168
dv["ast_dist1"][c], # altimeter range estimate (1 mm) using AST
11741169
dv["ast_quality"][c], # alimeter quality for AST algorithm
11751170
dv["c_sound"][c], # speed of sound (0.1 m/s)
11761171
dv["ast_dist2"][c], # altimeter range estimate (1 mm) using AST
1177-
dv["vel"][0, c], # velocity beam 1 (mm/s) East for SUV
1178-
dv["vel"][1, c], # North for SUV
1179-
dv["vel"][2, c], # Up for SUV
1172+
dv["vel_alt"][0, c], # velocity beam 1 (mm/s) East for SUV
1173+
dv["vel_alt"][1, c], # North for SUV
1174+
dv["vel_alt"][2, c], # Up for SUV
11801175
) = unpack(self.endian + "4x3B2x2hH2h2x3h3x", byts)
11811176
alt_bytes = self.read(nbeams * nbins)
11821177
tmp = unpack(
@@ -1382,15 +1377,15 @@ def _convert_data(self, vardict):
13821377
if retval is not None:
13831378
dat[nm] = retval
13841379

1385-
def convert_vec_sysdata(self):
1380+
def convert_vec_sys(self):
13861381
"""Convert raw Vector system data into physical quantities."""
13871382
dat = self.data
13881383
fs = dat["attrs"]["fs"]
1389-
self._convert_data(defs.vec_sysdata)
1384+
self._convert_data(defs.vec_sys)
13901385
t = dat["coords"]["time"]
13911386
dv = dat["data_vars"]
13921387
dat["sys"]["_sysi"] = ~np.isnan(t)
1393-
# These are the indices in the sysdata variables
1388+
# These are the indices in the system variables
13941389
# that are not interpolated.
13951390
nburst = self.config["adv"]["n_burst"]
13961391
if nburst == 0:
@@ -1443,20 +1438,28 @@ def convert_vec_data(self):
14431438
def convert_awac_profile(self):
14441439
"""Convert raw AWAC profile measurements to physical quantities."""
14451440
self._convert_data(defs.awac_profile)
1446-
# Calculate the ranges.
1447-
cs_coefs = {2000: 0.0239, 1000: 0.0478, 600: 0.0797, 400: 0.1195}
1448-
h_ang = 25 * (np.pi / 180) # Head angle is 25 degrees for all awacs.
1441+
# Calculate the ranges. (Manually calculated)
1442+
if "hr_profile" in self.data["attrs"]:
1443+
cs_coefs = {2000: 0.00675, 1000: 0.01350}
1444+
bd_coef = 0.00662
1445+
n_digits = 3
1446+
else:
1447+
cs_coefs = {2000: 0.0239, 1000: 0.0478, 600: 0.0797, 400: 0.1195}
1448+
bd_coef = 0.02289
1449+
n_digits = 2
1450+
# Head angle is 25 degrees for all awacs.
1451+
h_ang = 25 * (np.pi / 180)
14491452
# Cell size
14501453
cs = round(
1451-
float(self.config["bin_length"])
1452-
/ 256.0
1454+
self.config["bin_length"]
1455+
/ 256
14531456
* cs_coefs[self.config["hdr"]["carrier_freq_kHz"]]
14541457
* np.cos(h_ang),
1455-
ndigits=2,
1458+
n_digits,
14561459
)
14571460
# Blanking distance
1458-
bd = round(self.config["blank_dist"] * 0.0229 * np.cos(h_ang) - cs, ndigits=2)
1459-
1461+
bd = round(self.config["blank_dist"] * bd_coef * np.cos(h_ang) - cs, n_digits)
1462+
# Profile range
14601463
r = (np.float32(np.arange(self.config["usr"]["n_bins"])) + 1) * cs + bd
14611464
self.data["coords"]["range"] = r
14621465
self.data["attrs"]["cell_size"] = float(cs)

mhkit/dolfyn/io/nortek_defs.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ def scale(self, data):
170170
),
171171
}
172172

173-
vec_sysdata = {
173+
vec_sys = {
174174
"time": _VarAtts(
175175
dims=[],
176176
dtype=np.float64,
@@ -445,7 +445,7 @@ def scale(self, data):
445445
}
446446

447447
stage_data = {
448-
"amp": _VarAtts(
448+
"amp_alt": _VarAtts(
449449
dims=[4],
450450
dtype=np.uint8,
451451
group="data_vars",
@@ -502,7 +502,7 @@ def scale(self, data):
502502
long_name="Altimeter Range Acoustic Surface Tracking 2",
503503
standard_name="altimeter_range",
504504
),
505-
"vel": _VarAtts(
505+
"vel_alt": _VarAtts(
506506
dims=[4],
507507
dtype=np.float32,
508508
group="data_vars",

mhkit/dolfyn/rotate/vector.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -252,12 +252,19 @@ def _calc_omat(time, hh, pp, rr, orientation_down=None):
252252
Roll Euler angle in degrees.
253253
254254
orientation_down: array-like or bool, optional
255-
Set to true if non-cabled ADV is facing downwards
255+
Set to true if non-cabled ADV is facing upwards.
256+
Leave as None for all other Nortek instruments.
256257
257258
Returns
258259
-------
259260
omat: array-like
260261
The calculated orientation matrix.
262+
263+
Notes
264+
-----
265+
For non-cabled Nortek Vector ADVs: 'down' configuration means the
266+
probe was pointing 'up', where the 'up' orientation corresponds
267+
to the communication cable being up.
261268
"""
262269

263270
rr = rr.data.copy()
@@ -270,10 +277,6 @@ def _calc_omat(time, hh, pp, rr, orientation_down=None):
270277
pp[lastgd:] = pp[lastgd]
271278
hh[lastgd:] = hh[lastgd]
272279
if orientation_down is not None:
273-
# For non-cabled Nortek Vector ADVs: 'down' configuration means th
274-
# probe was pointing 'up', where the 'up' orientation corresponds
275-
# to the communication cable being up. Check the Nortek coordinate
276-
# transform matlab script for more info.
277280
rr += 180
278281

279282
return _euler2orient(time, hh, pp, rr)

0 commit comments

Comments
 (0)