Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optional parameter frequency_dimension across wave.resource #336

Merged
merged 6 commits into from
Aug 19, 2024
184 changes: 134 additions & 50 deletions mhkit/wave/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,11 +398,8 @@ def surface_elevation(
)

# wave elevation
# eta = xr.DataArray(columns=S.columns, index=time_index)
# for mcol in eta.columns:
C = np.cos(B + phase)
# C = xr.DataArray(data=C, index=time_index, columns=omega.index)
eta[var] = (C * A).sum(axis=1)
eta[var] = (C * A).sum(dim=frequency_dimension)

if to_pandas:
eta = eta.to_dataframe()
Expand Down Expand Up @@ -475,14 +472,19 @@ def frequency_moment(S, N, frequency_bins=None, frequency_dimension="", to_panda
return m


def significant_wave_height(S, frequency_bins=None, to_pandas=True):
def significant_wave_height(
S, frequency_dimension="", frequency_bins=None, to_pandas=True
):
"""
Calculates wave height from spectra

Parameters
------------
S: pandas DataFrame, pandas Series, xarray DataArray, or xarray Dataset
Spectral density [m^2/Hz] indexed by frequency [Hz]
frequency_dimension: string (optional)
Name of the xarray dimension corresponding to frequency. If not supplied,
defaults to the first dimension. Does not affect pandas input.
frequency_bins: numpy array or pandas Series (optional)
Bin widths for frequency of S. Required for unevenly sized bins
to_pandas: bool (optional)
Expand All @@ -498,9 +500,13 @@ def significant_wave_height(S, frequency_bins=None, to_pandas=True):
raise TypeError(f"to_pandas must be of type bool. Got: {type(to_pandas)}")

# Eq 12 in IEC 62600-101
m0 = frequency_moment(S, 0, frequency_bins=frequency_bins, to_pandas=False).rename(
{"m0": "Hm0"}
)
m0 = frequency_moment(
S,
0,
frequency_bins=frequency_bins,
frequency_dimension=frequency_dimension,
to_pandas=False,
).rename({"m0": "Hm0"})
Hm0 = 4 * np.sqrt(m0)

if to_pandas:
Expand All @@ -509,14 +515,19 @@ def significant_wave_height(S, frequency_bins=None, to_pandas=True):
return Hm0


def average_zero_crossing_period(S, frequency_bins=None, to_pandas=True):
def average_zero_crossing_period(
S, frequency_dimension="", frequency_bins=None, to_pandas=True
):
"""
Calculates wave average zero crossing period from spectra

Parameters
------------
S: pandas DataFrame, pandas Series, xarray DataArray, or xarray Dataset
Spectral density [m^2/Hz] indexed by frequency [Hz]
frequency_dimension: string (optional)
Name of the xarray dimension corresponding to frequency. If not supplied,
defaults to the first dimension. Does not affect pandas input.
frequency_bins: numpy array or pandas Series (optional)
Bin widths for frequency of S. Required for unevenly sized bins
to_pandas: bool (optional)
Expand All @@ -532,12 +543,20 @@ def average_zero_crossing_period(S, frequency_bins=None, to_pandas=True):
raise TypeError(f"to_pandas must be of type bool. Got: {type(to_pandas)}")

# Eq 15 in IEC 62600-101
m0 = frequency_moment(S, 0, frequency_bins=frequency_bins, to_pandas=False).rename(
{"m0": "Tz"}
)
m2 = frequency_moment(S, 2, frequency_bins=frequency_bins, to_pandas=False).rename(
{"m2": "Tz"}
)
m0 = frequency_moment(
S,
0,
frequency_bins=frequency_bins,
frequency_dimension=frequency_dimension,
to_pandas=False,
).rename({"m0": "Tz"})
m2 = frequency_moment(
S,
2,
frequency_bins=frequency_bins,
frequency_dimension=frequency_dimension,
to_pandas=False,
).rename({"m2": "Tz"})

Tz = np.sqrt(m0 / m2)

Expand All @@ -547,14 +566,19 @@ def average_zero_crossing_period(S, frequency_bins=None, to_pandas=True):
return Tz


def average_crest_period(S, frequency_bins=None, to_pandas=True):
def average_crest_period(
S, frequency_dimension="", frequency_bins=None, to_pandas=True
):
"""
Calculates wave average crest period from spectra

Parameters
------------
S: pandas DataFrame, pandas Series, xarray DataArray, or xarray Dataset
Spectral density [m^2/Hz] indexed by frequency [Hz]
frequency_dimension: string (optional)
Name of the xarray dimension corresponding to frequency. If not supplied,
defaults to the first dimension. Does not affect pandas input.
frequency_bins: numpy array or pandas Series (optional)
Bin widths for frequency of S. Required for unevenly sized bins
to_pandas: bool (optional)
Expand All @@ -570,12 +594,20 @@ def average_crest_period(S, frequency_bins=None, to_pandas=True):
if not isinstance(to_pandas, bool):
raise TypeError(f"to_pandas must be of type bool. Got: {type(to_pandas)}")

m2 = frequency_moment(S, 2, frequency_bins=frequency_bins, to_pandas=False).rename(
{"m2": "Tavg"}
)
m4 = frequency_moment(S, 4, frequency_bins=frequency_bins, to_pandas=False).rename(
{"m4": "Tavg"}
)
m2 = frequency_moment(
S,
2,
frequency_bins=frequency_bins,
frequency_dimension=frequency_dimension,
to_pandas=False,
).rename({"m2": "Tavg"})
m4 = frequency_moment(
S,
4,
frequency_bins=frequency_bins,
frequency_dimension=frequency_dimension,
to_pandas=False,
).rename({"m4": "Tavg"})

Tavg = np.sqrt(m2 / m4)

Expand All @@ -585,14 +617,17 @@ def average_crest_period(S, frequency_bins=None, to_pandas=True):
return Tavg


def average_wave_period(S, frequency_bins=None, to_pandas=True):
def average_wave_period(S, frequency_dimension="", frequency_bins=None, to_pandas=True):
"""
Calculates mean wave period from spectra

Parameters
------------
S: pandas DataFrame, pandas Series, xarray DataArray, or xarray Dataset
Spectral density [m^2/Hz] indexed by frequency [Hz]
frequency_dimension: string (optional)
Name of the xarray dimension corresponding to frequency. If not supplied,
defaults to the first dimension. Does not affect pandas input.
frequency_bins: numpy array or pandas Series (optional)
Bin widths for frequency of S. Required for unevenly sized bins
to_pandas: bool (optional)
Expand All @@ -607,12 +642,20 @@ def average_wave_period(S, frequency_bins=None, to_pandas=True):
if not isinstance(to_pandas, bool):
raise TypeError(f"to_pandas must be of type bool. Got: {type(to_pandas)}")

m0 = frequency_moment(S, 0, frequency_bins=frequency_bins, to_pandas=False).rename(
{"m0": "Tm"}
)
m1 = frequency_moment(S, 1, frequency_bins=frequency_bins, to_pandas=False).rename(
{"m1": "Tm"}
)
m0 = frequency_moment(
S,
0,
frequency_bins=frequency_bins,
frequency_dimension=frequency_dimension,
to_pandas=False,
).rename({"m0": "Tm"})
m1 = frequency_moment(
S,
1,
frequency_bins=frequency_bins,
frequency_dimension=frequency_dimension,
to_pandas=False,
).rename({"m1": "Tm"})

Tm = np.sqrt(m0 / m1)

Expand Down Expand Up @@ -664,14 +707,17 @@ def peak_period(S, frequency_dimension="", to_pandas=True):
return Tp


def energy_period(S, frequency_bins=None, to_pandas=True):
def energy_period(S, frequency_dimension="", frequency_bins=None, to_pandas=True):
"""
Calculates wave energy period from spectra

Parameters
------------
S: pandas DataFrame, pandas Series, xarray DataArray, or xarray Dataset
Spectral density [m^2/Hz] indexed by frequency [Hz]
frequency_dimension: string (optional)
Name of the xarray dimension corresponding to frequency. If not supplied,
defaults to the first dimension. Does not affect pandas input.
frequency_bins: numpy array or pandas Series (optional)
Bin widths for frequency of S. Required for unevenly sized bins
to_pandas: bool (optional)
Expand All @@ -687,11 +733,19 @@ def energy_period(S, frequency_bins=None, to_pandas=True):
raise TypeError(f"to_pandas must be of type bool. Got: {type(to_pandas)}")

mn1 = frequency_moment(
S, -1, frequency_bins=frequency_bins, to_pandas=False
S,
-1,
frequency_bins=frequency_bins,
frequency_dimension=frequency_dimension,
to_pandas=False,
).rename({"m-1": "Te"})
m0 = frequency_moment(S, 0, frequency_bins=frequency_bins, to_pandas=False).rename(
{"m0": "Te"}
)
m0 = frequency_moment(
S,
0,
frequency_bins=frequency_bins,
frequency_dimension=frequency_dimension,
to_pandas=False,
).rename({"m0": "Te"})

# Eq 13 in IEC 62600-101
Te = mn1 / m0
Expand All @@ -702,14 +756,17 @@ def energy_period(S, frequency_bins=None, to_pandas=True):
return Te


def spectral_bandwidth(S, frequency_bins=None, to_pandas=True):
def spectral_bandwidth(S, frequency_dimension="", frequency_bins=None, to_pandas=True):
"""
Calculates bandwidth from spectra

Parameters
------------
S: pandas DataFrame, pandas Series, xarray DataArray, or xarray Dataset
Spectral density [m^2/Hz] indexed by frequency [Hz]
frequency_dimension: string (optional)
Name of the xarray dimension corresponding to frequency. If not supplied,
defaults to the first dimension. Does not affect pandas input.
frequency_bins: numpy array or pandas Series (optional)
Bin widths for frequency of S. Required for unevenly sized bins
to_pandas: bool (optional)
Expand All @@ -724,15 +781,27 @@ def spectral_bandwidth(S, frequency_bins=None, to_pandas=True):
if not isinstance(to_pandas, bool):
raise TypeError(f"to_pandas must be of type bool. Got: {type(to_pandas)}")

m2 = frequency_moment(S, 2, frequency_bins=frequency_bins, to_pandas=False).rename(
{"m2": "e"}
)
m0 = frequency_moment(S, 0, frequency_bins=frequency_bins, to_pandas=False).rename(
{"m0": "e"}
)
m4 = frequency_moment(S, 4, frequency_bins=frequency_bins, to_pandas=False).rename(
{"m4": "e"}
)
m2 = frequency_moment(
S,
2,
frequency_bins=frequency_bins,
frequency_dimension=frequency_dimension,
to_pandas=False,
).rename({"m2": "e"})
m0 = frequency_moment(
S,
0,
frequency_bins=frequency_bins,
frequency_dimension=frequency_dimension,
to_pandas=False,
).rename({"m0": "e"})
m4 = frequency_moment(
S,
4,
frequency_bins=frequency_bins,
frequency_dimension=frequency_dimension,
to_pandas=False,
).rename({"m4": "e"})

e = np.sqrt(1 - (m2**2) / (m0 / m4))

Expand All @@ -742,14 +811,17 @@ def spectral_bandwidth(S, frequency_bins=None, to_pandas=True):
return e


def spectral_width(S, frequency_bins=None, to_pandas=True):
def spectral_width(S, frequency_dimension="", frequency_bins=None, to_pandas=True):
"""
Calculates wave spectral width from spectra

Parameters
------------
S: pandas DataFrame, pandas Series, xarray DataArray, or xarray Dataset
Spectral density [m^2/Hz] indexed by frequency [Hz]
frequency_dimension: string (optional)
Name of the xarray dimension corresponding to frequency. If not supplied,
defaults to the first dimension. Does not affect pandas input.
frequency_bins: numpy array or pandas Series (optional)
Bin widths for frequency of S. Required for unevenly sized bins
to_pandas: bool (optional)
Expand All @@ -765,13 +837,25 @@ def spectral_width(S, frequency_bins=None, to_pandas=True):
raise TypeError(f"to_pandas must be of type bool. Got: {type(to_pandas)}")

mn2 = frequency_moment(
S, -2, frequency_bins=frequency_bins, to_pandas=False
S,
-2,
frequency_bins=frequency_bins,
frequency_dimension=frequency_dimension,
to_pandas=False,
).rename({"m-2": "v"})
m0 = frequency_moment(S, 0, frequency_bins=frequency_bins, to_pandas=False).rename(
{"m0": "v"}
)
m0 = frequency_moment(
S,
0,
frequency_bins=frequency_bins,
frequency_dimension=frequency_dimension,
to_pandas=False,
).rename({"m0": "v"})
mn1 = frequency_moment(
S, -1, frequency_bins=frequency_bins, to_pandas=False
S,
-1,
frequency_bins=frequency_bins,
frequency_dimension=frequency_dimension,
to_pandas=False,
).rename({"m-1": "v"})

# Eq 16 in IEC 62600-101
Expand Down
Loading