Source code for wavespectra.input.funwave

"""Read Funwave 2D Wave Maker files"""
import numpy as np
import xarray as xr

from wavespectra import SpecArray
from wavespectra.input import read_ascii_or_binary
from wavespectra.core.attributes import attrs, set_spec_attributes


[docs] def read_funwave(filename_or_obj): """Read Spectra in Funwave format. Args: - filename_or_obj (str, filelike): Funwave file to read. Returns: - dset (SpecDataset): spectra dataset object read from funwave file. Note: - Format description: https://fengyanshi.github.io/build/html/wavemaker_para.html. - Both 2D E(f,d) and 1d E(f) spectra are supported. - Directions converted from Cartesian (0E, CCW, to) to wavespectra (0N, CW, from). - Phases are ignored if present. """ data = read_ascii_or_binary(filename_or_obj, mode="r") # Remove any empty rows data = [row for row in data if row != "\n"] # Shape nf, nd = [int(val) for val in data.pop(0).split()[:2]] # Tp tp = float(data.pop(0).split()[0]) # Spectral coordinates (convert dir from cartesian to wavespectra convention) freq = np.array([float(data.pop(0).split()[0]) for count in range(nf)]) dir = np.array([float(data.pop(0).split()[0]) for count in range(nd)]) dir = (270 - dir) % 360 # Turn zero dir into 360 for continuity i0 = np.where(dir==0)[0] if i0.size > 0: dir[i0] = 360.0 # Amplitude spectrum if nd == 1: amp = np.genfromtxt(data) coords = {attrs.FREQNAME: freq} dims = (attrs.FREQNAME) else: amp = np.genfromtxt(data[:nd]) coords = {attrs.FREQNAME: freq, attrs.DIRNAME: dir} dims = (attrs.FREQNAME, attrs.DIRNAME) darr = xr.DataArray(data=amp.transpose(), coords=coords, dims=dims) # Energy density spectrum darr = darr ** 2 / (darr.spec.dfarr * darr.spec.dd * 2) # Define output dataset dset = darr.to_dataset(name=attrs.SPECNAME) if nd > 1: dset = dset.sortby(attrs.DIRNAME) dset["tp"] = tp set_spec_attributes(dset) return dset