Source code for wavespectra.core.xrstats
"""Peak based wave stats ufuncs."""
import numpy as np
import xarray as xr
from wavespectra.core.attributes import attrs
from wavespectra.core import npstats
[docs]
def peak_wave_direction(dset):
"""Peak wave direction Dp.
Args:
- dset (xr.DataArray, xr.Dataset): Spectra array or dataset in wavespectra convention.
Returns:
- dp (xr.DataArray): Peak wave direction data array.
"""
# Ensure DataArray
if isinstance(dset, xr.Dataset):
dset = dset[attrs.SPECNAME]
# Dimensions checking
if attrs.DIRNAME not in dset.dims:
raise ValueError("Cannot calculate dp from frequency spectra.")
if attrs.FREQNAME in dset.dims:
dset = dset.sum(attrs.FREQNAME)
# Ensure single chunk along input core dimensions
dset = dset.chunk({attrs.DIRNAME: None})
# Peak
ipeak = dset.argmax(dim=attrs.DIRNAME)
# Apply function over the full dataset
darr = xr.apply_ufunc(
npstats.dp_gufunc,
ipeak.astype("int64"),
dset[attrs.DIRNAME].astype("float32"),
input_core_dims=[[], [attrs.DIRNAME]],
dask="parallelized",
output_dtypes=["float32"],
)
# Finalise
darr.name = "dp"
darr.attrs = {
"standard_name": attrs.ATTRS.dp.standard_name,
"units": attrs.ATTRS.dp.units
}
return darr
[docs]
def mean_direction_at_peak_wave_period(dset):
"""Mean direction at the peak wave period Dpm.
Args:
- dset (xr.DataArray, xr.Dataset): Spectra array or dataset in wavespectra convention.
Returns:
- dpm (xr.DataArray): Mean direction at the peak wave period data array.
Note from WW3 Manual:
- Peak wave direction, defined like the mean direction, using the freq/wavenum
bin containing of the spectrum F(k) that contains the peak frequency only.
"""
# Ensure DataArray
if isinstance(dset, xr.Dataset):
dset = dset[attrs.SPECNAME]
# Dimensions checking
if attrs.DIRNAME not in dset.dims:
raise ValueError("Cannot calculate dp from frequency spectra.")
# Ensure single chunk along input core dimensions
dset = dset.chunk({attrs.FREQNAME: None})
# Directional moments and peaks
msin, mcos = dset.spec.momd(1)
ipeak = dset.spec._peak(dset.spec.oned())
# Apply function over the full dataset
darr = xr.apply_ufunc(
npstats.dpm_gufunc,
ipeak.astype("int64"),
msin.astype("float64"),
mcos.astype("float64"),
input_core_dims=[[], [attrs.FREQNAME], [attrs.FREQNAME]],
dask="parallelized",
output_dtypes=["float32"],
)
# Finalise
darr.name = "dpm"
darr.attrs = {
"standard_name": attrs.ATTRS.dpm.standard_name,
"units": attrs.ATTRS.dpm.units
}
return darr #.where((darr >= 0) & (darr <= 360))
[docs]
def peak_wave_period(dset, smooth=True):
"""Smooth Peak wave period Tp.
Args:
- dset (xr.DataArray, xr.Dataset): Spectra array or dataset in wavespectra convention.
- smooth (bool): Choose between the smooth (tps) or the raw (tp) peak wave period type.
Returns:
- tp (xr.DataArray): Peak wave period data array.
"""
# Ensure DataArray
if isinstance(dset, xr.Dataset):
dset = dset[attrs.SPECNAME]
# Choose peak period function
if smooth:
func = npstats.tps_gufunc
else:
func = npstats.tp_gufunc
# Integrate over directions
if attrs.DIRNAME in dset.dims:
dset = dset.sum(dim=attrs.DIRNAME)
# Ensure single chunk along input core dimensions
dset = dset.chunk({attrs.FREQNAME: None})
# Frequency Peaks
ipeak = dset.spec._peak(dset)
# Apply function over the full dataset
darr = xr.apply_ufunc(
func,
ipeak.astype("int64"),
dset.astype("float64"),
dset[attrs.FREQNAME].astype("float32"),
input_core_dims=[[], [attrs.FREQNAME], [attrs.FREQNAME]],
dask="parallelized",
output_dtypes=["float32"],
)
# Finalise
darr.name = "tp"
darr.attrs = {
"standard_name": attrs.ATTRS.tp.standard_name,
"units": attrs.ATTRS.tp.units
}
return darr