Skip to content

Commit 9884dc6

Browse files
committed
Make sure surface removal functions work for averaged datasets
1 parent 42d5a86 commit 9884dc6

1 file changed

Lines changed: 63 additions & 45 deletions

File tree

mhkit/dolfyn/adp/clean.py

Lines changed: 63 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ def water_depth_from_amplitude(ds, thresh=10, nfilt=None) -> None:
205205
else:
206206
long_name = "Instrument Depth"
207207

208-
ds["depth"] = xr.DataArray(
208+
ds["depth" + tag[0]] = xr.DataArray(
209209
d.astype("float32"),
210210
dims=["time" + tag[0]],
211211
attrs={"units": "m", "long_name": long_name, "standard_name": "depth"},
@@ -307,7 +307,13 @@ def water_depth_from_pressure(ds, salinity=35) -> None:
307307
else:
308308
long_name = "Instrument Depth"
309309

310-
ds["water_density"] = xr.DataArray(
310+
# Use correct coordinate tag
311+
if "_" in pressure[0]:
312+
tag = "_" + pressure[0].split("_")[-1]
313+
else:
314+
tag = ""
315+
316+
ds["water_density" + tag] = xr.DataArray(
311317
rho.astype("float32"),
312318
dims=[ds[pressure[0]].dims[0]],
313319
attrs={
@@ -317,7 +323,7 @@ def water_depth_from_pressure(ds, salinity=35) -> None:
317323
"description": "Water density from linear approximation of sea water equation of state",
318324
},
319325
)
320-
ds["depth"] = xr.DataArray(
326+
ds["depth" + tag] = xr.DataArray(
321327
d.astype("float32"),
322328
dims=[ds[pressure[0]].dims[0]],
323329
attrs={"units": "m", "long_name": long_name, "standard_name": "depth"},
@@ -368,7 +374,7 @@ def remove_surface_interference(
368374
`distance > range * cos(beam angle) - cell size`
369375
"""
370376

371-
if "depth" not in ds.data_vars:
377+
if ("depth" not in ds.data_vars) and ("depth_avg" not in ds.data_vars):
372378
raise KeyError(
373379
"Depth variable 'depth' does not exist in input dataset."
374380
"Please calculate 'depth' using the function 'water_depth_from_pressure'"
@@ -388,27 +394,23 @@ def remove_surface_interference(
388394
beam_angle = np.deg2rad(beam_angle)
389395

390396
if cell_size is None:
391-
# Fetch cell size
392-
cell_sizes = [
393-
a
394-
for a in ds.attrs
395-
if (
396-
("cell_size" in a)
397-
and ("_bt" not in a)
398-
and ("_alt" not in a)
399-
and ("wave" not in a)
400-
)
401-
]
402-
if cell_sizes:
403-
cs = cell_sizes[0]
404-
else:
397+
# Fetch cell size (usually 'cell_size' or 'cell_size_avg')
398+
cell_sizes = []
399+
if hasattr(ds, "cell_size"):
400+
cell_sizes.append("cell_size")
401+
if hasattr(ds, "cell_size_avg"):
402+
cell_sizes.append("cell_size_avg")
403+
if not cell_sizes:
405404
raise KeyError(
406405
"'cell_size` not found in dataset attributes. "
407406
"Please supply the ADCP's cell size."
408407
)
409408
else:
410409
cs = [cell_size]
411410

411+
# Depth variable(s)
412+
depths = [cs.replace("cell_size", "depth") for cs in cell_sizes]
413+
412414
if not inplace:
413415
ds = ds.copy(deep=True)
414416

@@ -417,34 +419,50 @@ def remove_surface_interference(
417419

418420
# Apply range_offset if available
419421
range_offset = __check_for_range_offset(ds)
420-
if range_offset:
421-
range_limit = (
422-
(ds["depth"] - range_offset) * np.cos(beam_angle) - ds.attrs[cs]
423-
) + range_offset
424-
else:
425-
range_limit = ds["depth"] * np.cos(beam_angle) - ds.attrs[cs]
426-
427-
# Echosounder data needs only be trimmed at water surface
428-
if "echo" in profile_vars:
429-
mask_echo = ds["range_echo"] > ds["depth"]
430-
ds["echo"].values[..., mask_echo] = val
431-
profile_vars.remove("echo")
432-
433-
# Correct profile measurements for surface interference
434-
for var in profile_vars:
435-
# Use correct coordinate tag
436-
if "_" in var and ("gd" not in var):
437-
tag = "_" + "_".join(var.split("_")[1:])
422+
for depth, cs in zip(depths, cell_sizes):
423+
if range_offset:
424+
range_limit = (
425+
(ds[depth] - range_offset) * np.cos(beam_angle) - ds.attrs[cs]
426+
) + range_offset
427+
else:
428+
range_limit = ds[depth] * np.cos(beam_angle) - ds.attrs[cs]
429+
430+
# No good way to do this
431+
if "_avg" not in depth:
432+
# Echosounder data needs only be trimmed at water surface
433+
if "echo" in profile_vars:
434+
mask_echo = ds["range_echo"] > ds["depth"]
435+
ds["echo"].values[..., mask_echo] = val
436+
profile_vars.remove("echo")
437+
438+
# Correct profile measurements for surface interference
439+
for var in profile_vars:
440+
if "avg" in var:
441+
continue
442+
# Use correct coordinate tag
443+
if "_" in var and ("gd" not in var):
444+
tag = "_" + "_".join(var.split("_")[1:])
445+
else:
446+
tag = ""
447+
mask = ds["range" + tag] > range_limit
448+
# Remove values
449+
a = ds[var].values
450+
try: # float dtype
451+
a[..., mask] = val
452+
except: # int dtype
453+
a[..., mask] = 0
454+
ds[var].values = a
438455
else:
439-
tag = ""
440-
mask = ds["range" + tag] > range_limit
441-
# Remove values
442-
a = ds[var].values
443-
try: # float dtype
444-
a[..., mask] = val
445-
except: # int dtype
446-
a[..., mask] = 0
447-
ds[var].values = a
456+
for var in profile_vars:
457+
if "avg" in var:
458+
mask = ds["range_avg"] > range_limit
459+
# Remove values
460+
a = ds[var].values
461+
try: # float dtype
462+
a[..., mask] = val
463+
except: # int dtype
464+
a[..., mask] = 0
465+
ds[var].values = a
448466

449467
if not inplace:
450468
return ds

0 commit comments

Comments
 (0)