Skip to content

Wave from empirical data is tricky #316

Closed
@rgcoe

Description

@rgcoe

I was trying to use wot.waves.long_crested_wave to create a wave based on an empirical spectrum. In the docstring for wot.waves.long_crested_wave it says you should pass an Omnidirection wave spectrum in units of m^2/Hz, in the format used by :py:class:wavespectra.SpecArray.

def long_crested_wave(
efth: DataArray,
nrealizations: int,
direction: Optional[float] = 0.0,
seed: Optional[float] = None,
) -> DataArray:
"""Create a complex frequency-domain wave elevation from an
omnidirectional spectrum.
The omnidirectional spectrum is in the
:py:class:`wavespectra.SpecArray` format.
.. note:: The frequencies must be evenly-spaced with spacing equal
to the first frequency. This is not always the case when
e.g. reading from buoy data. Use interpolation as
:python:`da.interp(freq=[...])`.
Parameters
----------
efth
Omnidirection wave spectrum in units of m^2/Hz, in the format
used by :py:class:`wavespectra.SpecArray`.
nrealizations
Number of wave phase realizations to be created for the
long-crested wave.
direction
Direction (in degrees) of the long-crested wave.
seed
Seed for random number generator. Used for reproducibility.
Generally should not be used except for testing.
"""

So I did something like the following:

import numpy as np
import xarray as xr
import wavespectra
import wecopttool as wot

efth = np.array([0.00000000e+00, 0.00000000e+00, 1.09429785e-03, 5.89094920e-02,
                 2.07249055e-01, 2.02675843e-01, 1.68867998e-01, 1.19803351e-01,
                 7.78674098e-02, 4.96642804e-02, 3.23615943e-02, 2.09029418e-02,
                 1.36226413e-02, 8.86459619e-03, 5.62541522e-03, 3.37224324e-03,
                 2.02762403e-03, 1.13507449e-03, 4.59939791e-04, 2.04417576e-04,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00])
freq = np.array([0.025, 0.05, 0.075, 0.1, 0.125, 0.15, 0.175, 0.2, 0.225,
                 0.25, 0.275, 0.3, 0.325, 0.35, 0.375, 0.4, 0.425, 0.45,
                 0.475, 0.5, 0.525, 0.55, 0.575, 0.6, 0.625, 0.65, 0.675,
                 0.7, 0.725, 0.75, 0.775, 0.8, 0.825, 0.85, 0.875, 0.9,
                 0.925, 0.95, 0.975, 1., 1.025, 1.05, 1.075, 1.1, 1.125,
                 1.15, 1.175, 1.2, 1.225, 1.25, 1.275, 1.3, 1.325, 1.35,
                 1.375, 1.4, 1.425, 1.45, 1.475, 1.5, 1.525, 1.55, 1.575,
                 1.6, 1.625, 1.65, 1.675, 1.7, 1.725, 1.75, 1.775, 1.8,
                 1.825, 1.85, 1.875])
da = xr.DataArray(data=np.transpose(np.atleast_2d(efth)),
             dims=[
                 "freq",
                 "dir"
                 ],
             coords=dict(
                 freq=freq,
                 dir=[0],
                 ),
             )
ws = wavespectra.SpecArray(da)
wot.waves.long_crested_wave(efth=ws)

This produces an error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[20], [line 41](vscode-notebook-cell:?execution_count=20&line=41)
     [29](vscode-notebook-cell:?execution_count=20&line=29) da = xr.DataArray(data=np.transpose(np.atleast_2d(efth)),
     [30](vscode-notebook-cell:?execution_count=20&line=30)              dims=[
     [31](vscode-notebook-cell:?execution_count=20&line=31)                  "freq",
   (...)
     [37](vscode-notebook-cell:?execution_count=20&line=37)                  ),
     [38](vscode-notebook-cell:?execution_count=20&line=38)              )
     [39](vscode-notebook-cell:?execution_count=20&line=39) ws = wavespectra.SpecArray(da)
---> [41](vscode-notebook-cell:?execution_count=20&line=41) wot.waves.long_crested_wave(efth=ws)
     [42](vscode-notebook-cell:?execution_count=20&line=42) ws

File [~/mambaforge/envs/wot_release/lib/python3.11/site-packages/wecopttool/waves.py:215](https://file+.vscode-resource.vscode-cdn.net/Users/rcoe/Downloads/~/mambaforge/envs/wot_release/lib/python3.11/site-packages/wecopttool/waves.py:215), in long_crested_wave(efth, direction, seed)
    [212](https://file+.vscode-resource.vscode-cdn.net/Users/rcoe/Downloads/~/mambaforge/envs/wot_release/lib/python3.11/site-packages/wecopttool/waves.py:212) f1, nfreq = frequency_parameters(efth.freq.values, False)
    [213](https://file+.vscode-resource.vscode-cdn.net/Users/rcoe/Downloads/~/mambaforge/envs/wot_release/lib/python3.11/site-packages/wecopttool/waves.py:213) df = f1
--> [215](https://file+.vscode-resource.vscode-cdn.net/Users/rcoe/Downloads/~/mambaforge/envs/wot_release/lib/python3.11/site-packages/wecopttool/waves.py:215) values = efth.values
    [216](https://file+.vscode-resource.vscode-cdn.net/Users/rcoe/Downloads/~/mambaforge/envs/wot_release/lib/python3.11/site-packages/wecopttool/waves.py:216) values[values<0] = np.nan
    [217](https://file+.vscode-resource.vscode-cdn.net/Users/rcoe/Downloads/~/mambaforge/envs/wot_release/lib/python3.11/site-packages/wecopttool/waves.py:217) amplitudes = np.sqrt(2 * values * df)

AttributeError: 'SpecArray' object has no attribute 'values'

I was able to resolve the problem by doing just passing my raw xr.DataArray (not the wavespectra.SpecArray):

# continuing from above
wot.waves.long_crested_wave(da)

This is OK I guess, but if so our docstring is misleading.

Suggested options:

  1. Update the docstring for wot.waves.long_crested_wave to make it clear that you should pass a xr.DataArray with a specific structure (don't love this one)
  2. Update the source for wot.waves.long_crested_wave to use a wavespectra.SpecArray as the input argument (preferred)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions